How to increase total positions considered for a chess engine - java

I'm writing a chess engine in Java and using bitboards to represent the board (12 64-bit numbers). The size of an instance of this class(its retained size) is 152Bytes according to IntelliJ debugger.
When trying to see a few moves a head, for each move I consider I create a new instance to represent the new Board state. Below is what the Board class looks like approximately.
public long WP=0L, WN=0L, WB=0L, WR=0L, WQ=0L, WK=0L, BP=0L, BN=0L, BB=0L, BR=0L, BQ=0L, BK=0L;
long NOT_WHITE_PIECES;
long WHITE_PIECES;
long BLACK_PIECES;
long OCCUPIED;
long EMPTY;
public void updateBitboards() {}
public void updateMailbox() {}
public void movePiece(Move move) {}
public void drawBitboard() {}
Other fields and methods are static so I don't think they affect the size of an instance.
The problem is, even if I want to consider only the first 4 moves in chess, there's ~8,000,000 possible combination of moves. So I'm going to end up storing a total of 8,000,000*152B = 1,216,000,000B... which is 1.2GB.
I feel like I'm missing something here. How can I increase the number of positions I consider at a time?

First, you don't want to create a new instance of the board state each move. If you are using e.g. Minimax then you make the move, make recursive call, then unmake the move. This way you always just have one board state which it considers.
Then to minimize the number of moves you need to consider you want to make enhancements to the algorithm. The most common to start with is alpha-beta pruning which you can read more about here: https://www.chessprogramming.org/Alpha-Beta. Alpha beta pruning will always yield the same result as a minimax, but you consider less positions since you don't search the hopeless ones.
Then there are tons of other pruning techniques that you can do to reduce the search tree. Most of these will not yield the same result since you "manually" choose to cut off certain positions that you "think" is going to be bad. This could be things like the assumption that there is always better to do something than nothing (null move pruning).
Other easy things you can do to speed up algorithm is to look at move ordering. To make Minimax most efficient you always want to look at the best move first in each position. That way you will get more cutoffs and not search as many moves. Everything you need to know about chess programming you can find at https://www.chessprogramming.org/.

Related

Searching a matrix for a chain of sums

I'm still trying to improve on my coding skills, and this question has got me spinning in my tracks a little bit, so any help is greatly appreciated. I know how to create the random array very easily, no problem with that. However, the logic of finding the chain is proving very difficult for me. I believe the proper approach is some sort of depth first searching algorithm, but I'm not entirely sure of how to implement that in this scenario, or whether that is even correct.
My basic question is, should I be using depth first search, and if so, should I be doing it recursively? Any tips or hints on implementation are also welcome!
Make a program that creates a 3x3 grid of random
positive numbers where 0 <= n <= 9. The program should
find all possible combinations of numbers that add up to the area of
the grid, or 9, using these rules (similar to Boggle):
a. The numbers must be "chained" in sequentially adjacent cells, where
"adjacent" cells are those horizontally, vertically, and diagonally
neighboring
b. The chain does not have to be in a line. For example, it could go
horizontally once, then vertically once, and finally diagonally once
c. At least the “grid width - 1” cells must be used in the chain (a
3x3 grid means that at least two cells must be used)
d. A chain cannot repeat a grid cell that it has already used
e. Chains that use the exact same cells as a previous chain are
considered repeats and should not be counted
I know that for each element, when you are searching through each adjacent element, you must check and keep track of whether it's been visited before, so you don't repeat numbers.
public class GridSolver {
int[][] workingGrid;
public GridSolver(int[][] workingGrid){
this.workingGrid = workingGrid;
}
public String solve(){
int length = this.workingGrid.length;
boolean[][] visited = new boolean[length][length];
for(int rows=0; rows<length; rows++){
for(int columns=0; columns<length; columns++){
if(visited[rows][columns] == false){
dfs(workingGrid[rows][columns]);
}
}
}
return null;
}
public HashSet<ArrayList<Integer>> dfs(int element){
HashSet<ArrayList<Integer>> chains = new HashSet<>();
checkLeft();
checkTopLeft();
checkTopMiddle();
checkTopRight();
checkRight();
checkBottomRight();
checkBottomMiddle();
checkBottomLeft();
return null;
}}
This is what I have so far and I realize that it is pretty sloppy and not the best thought out scheme, but that's why I'm here I guess :P.
Also just to explain some of my thinking in the code, the dfs()method has a return type of HashSet because I know that you can't have duplicate chains, and it is a set of a list of the chains. Also the "check" methods are not implemented, I just wrote them down because I know that you will need to process each of these adjacent blocks for each number.
Once again, any help is greatly appreciated, and thank you for humoring me as a beginner here!

Java - Most efficient random-access multi-threaded list

Chosen List Structure:
Synchronised LinkedList.
Scenario:
My program requires rendering some (rather computational) generated images in a grid. These images must update whenever some data value changes (on another thread), hence, I have a rendering queue to manage this.
The rendering queue is a synchronised LinkedList, where on a low-priority thread, it is constantly being iterated over to check if some render work needs doing. Since the images are based on all kinds of data, each of which could change independently, I needed some form of queue to combine changes.
Data tends to change in chunks, and so when a large batch comes through I see an imaginary line run down the area where it's re-rendering the tiles. To pretty this up a bit, I decided rather than rendering in standard order, I'd render them in a random order (to give a 'dissolve in/out' effect).
It looks lovely, but the only problem is, there is a notable different in the amount of time it takes to complete with this effect running.
Problem:
I've theorised a couple of reasons accessing this list randomly instead of iteratively would cause such a notable delay. Firstly, the Random number generator's nextInt method might take up a significant enough amount of time. Secondly, since it's a LinkedList, getting the nth item might also be significant when the size of the list is in the 4000s range.
Is there any other reason for this delay that I might have overlooked? Rather than using a random number generator, or even a linked list, how else might I efficiently achieve a random access & remove from a list? If you've read the scenario, perhaps you can think of another way I could go about this entirely?
Requirements:
Multi-threaded addition to & modification of list.
Random access & removal of items from list.
Efficient operation, with large data sets & number of runs
You can use an ArrayList along with a couple of simple operations to implement this very efficiently.
To insert, always insert new work at the end of the list (an amortized constant time operation).
To extract a random piece of work, pick a random number i, swap the element at i with the element at the end of the list, and then extract and return that new last element.
Here's code (untested, uncompiled):
class RandomizedQueue<T> {
private final List<T> workItems = new ArrayList<>();
private final Random random;
RandomizedQueue(Random random) {
this.random = random;
}
public synchronized void insert(T item) {
workItems.add(item);
}
public synchronized T extract() {
if (workItems.isEmpty()) {
return null; // or throw an exception
}
int pos = random.nextInt(workItems.size());
int lastPos = workItems.size() - 1;
T item = workItems.get(pos);
workItems.set(pos, workItems.get(lastPos));
return workItems.remove(lastPos);
}
}
You could perhaps use a PriorityQueue, and when adding things to this queue give each item a random priority. The rendering can just always take the top element on the queue since it is randomized already. Inserting at a "random" position in a PriorityQueue (or better put, with a random priority) is really fast.

Check if a position is clicked using HashMap

I'm writing a simple program and want to know if an approximate position is clicked. I've got a hashmap with the position as key value and want to display a currently invisible object if the user clicks close enough to the position of the object - not just right at it. The position class just holds an x and a y value.
HashMap<Position, Place> places = new HashMap<>(); //Assume this is populated
#Override
class WhatIsHere extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
Place place = places.get(new Position(me.getX(), me.getY()));
if (place != null) {
place.setVisible(true);
} else {
System.out.println("Nothing there");
}
}
}
This bit of code finds the place if you click right on it though I don't know how to look for, say, me.getX()+-10 and find objects in that range.
Do I need to set four ints holding x-10 and x+10 etc. and just loop through all the positions inbetween? It seems awfully dumb to do it that way.
I dislike exercises that require use of a particular collection, regardless of whether it is the best choice. One of the most important things to learn about the collections, and more generally about data structures, is picking which to use for a given job.
However, I understand you have to use HashMap. Here is one way to do it.
Divide the space up into small squares. Identify each square by e.g. the Point at the minimum x and minimum y. Create a HashMap that maps the square that are near at least one of your objects to the list of nearby objects.
To look up a point, calculate the Point identifying the square containing it. Look up that Point in the map. If it is not present, your point is not near any object. If it is present, check your point against each object in the list according to your nearness rules.
For some configurations of your objects, you may be able to ensure that each square is near at most one object. If so, you can replace the list with the object.
You might want to use TreeMap and you would be able to get a sub map which seems to be what you are looking for.

Interview question: Create an object oriented design for Sudoku

I answered that I will have have a 2d Array.
And then I will have 3 functions
one to check the horizontal condition.
another function to check vertical condition
and another one the check the 3*3 block condition.
But he is not satisfied, can any one give a good answer for this question?
I found this stack overflow link related to my question.
Programming Design Help - How to Structure a Sudoku Solver program?.
But I want a proper object oriented design (like what should be the classes, inheritance and other details) which are the same things interviewer expected from me.
To me, your design starts with a "region" class. You can then extend this to be a "horizontal region" "vertical region" and "square region" as the three types of regions. Edit: upon further consideration you don't really need to make this distinction unless it's for display purposes... algorithmically it will be the same.
Then you can make your 2d array of "elements" and add the elements appropriately to your regions, which provides a network for your calculations. Your elements have a list of potential values, and your regions are responsible for removing those potential values. When you have a value found, it triggers the regions it is a member of to remove the potential values from those too.
For base classes of a solver, I see a good start with Cell, ValidationRegion, Board, and Pattern as your main classes.
Cell: Has the current value of the cell, the remaining possible values of the cell, and if the cell is fixed or not.
ValidationRegion: Has references to the appropriate 9 Cells on the Board. This class doesn't really need to know if it is representing horizontal, vertical, or a square regions, because the rules are the same. This class has a validate() method to verify that the current state of the region is possible.
Board: Has the entire layout of Cells, and initializes the fixed ValidationRegions appropriately by passing the appropriate Cells by reference. It also has a solve method that applies Patterns in a pre-defined order until a solution is reached or it is determined that no solution is possible (brute-force pattern must therefore be the last ditch effort).
Pattern: Abstract class that has an apply(Board) method that applies the given pattern to the specified board object (removes possibilities from Cells and sets them when it knows there is only one possibility left). From Sudoku Dragon - Sudoku Strategy, you'll likely implement patterns like OneChoicePattern, SinglePossibilityPattern, OnlySquareRule, etc.
If the question was just "What's an object-oriented design for Sudoku" and you went off and started telling him stuff, he may have been disappointed that you didn't ask for actual requirements. "Sudoku" is pretty broad. Just a data representation? A solver? A means to play? A validator? A puzzle creator?
Until you know what he wanted you to build, you can't really design a solution.
For an Object-Oriented approach to Sudoku I'd do something like this (just using simple names):
A NumberSpace is a single square on the Sudoku board and capable of holding a number from 1-9.
A Block is a grouping of 9 NumberSpaces in a 3x3 pattern, Which would probably just be represented in the class as a multidimensional array of NumberSpace objects. Methods on this could include (bool)validate which would test to make sure no number is repeated per block.
Finally, a Board would represent the entire gaming area where which would be another array (3x3) of Blocks. Methods for this class would include means for verifying the validity of columns/rows.
Two outstanding classes raise from this problem, the main game board and a cell holding a value.
In C#, this would be:
// Main game board
public class BoardGame{
List<List<Cell> cells = new List<List<Cell>>();
public BoardGame(int dimention){
// Initialize and add cells to the cells attribute
}
public bool HorizLineContainsValue(int lineNumber, value){
// return true if any cell in horiz. line number contains value
}
public bool VertLineContainsValue(int lineNumber, value){
// return true if any cell in vertic. line number contains value
}
}
public class Cell {
// X index on the game board
public int X{get; set;}
// Y index on the game board
public int Y{get; set;}
// Value of this cell
public int Value{get; set;}
// Set game board
public GameBoard GameBoard{set;}
public boolean AcceptValue(int value){
// Ask the game board if cells on horizontal line X have this value
// Ask the game board if cells on vertical line Y have this value
// And return true or false accordingly
}
}
If you wish to consider the 3*3 block then you might go for the composite design pattern which will fit this problem very well.
Here is a link to a very interesting and pragmatic book resolving a complex game using OOAD and design patterns
I am not sure about this, but I have a feeling that the interviewer probably wanted something like MVC pattern etc, a high level design/architecture. Then, within this context, you will have three modules/components: model, view and controller. Each of which is then made up of one or more classes. For most interactive applications, this pattern or some variation/related pattern is applicable.
I would say this would have been enough. Since, in an interview you don't have enough time to come up with details of classes, neither it is necessary to do so (at least in typical cases).

Designing a hand history class for Texas Hold'em in Java

I am trying to come up with a Java hand history class for Texas Hold'em and wanted to bounce an idea off here.
Requirements are that every action is stored and there is an efficient way to traverse each HandHistory object (which would represent a single played hand) to match common 'lines' like the standard continuation bet (i.e. the preflop raiser who was in late position preflop and probably is in position postflop is checked to and then makes a 75%ish pot bet).
Ignore for the moment that the definitions for each of the lines is fuzzy at best. As a first stab, I was thinking of organizing it like so:
public class HandHistory {
private Integer handnumber;
//in case we saw things at showdown, put them here
private HashMap<Player,String> playerHands;
private String flopCards;
private String turnCard;
private String riverCard;
private HashMap<BetRound,LinkedHashMap<Integer,ArrayList<PlayerAction>>> actions;
}
So, for each betround we store a linked hashmap whose keys are integers that are the offsets from first position to act for that betround, so preflop UTG is 0.
We generate the actions in position order already, so use a linked hashmap so we can iterate nicely later and skip over positions that are sitting out,etc.
Each arraylist will contain the actions that that position had in that betround. Most of the time this array will have one element, but in cases like, limps and then calls, it will have two.
Can anyone see a better data structure to use for this?
small change, since holdem has a fixed number of betting rounds, maybe
private HashMap<BetRound,LinkedHashMap<Integer,ArrayList<PlayerAction>>> actions;
could just be:
private LinkedHashMap<Integer,ArrayList<PlayerAction>>[] actions= new ... ;
also, here's a couple of books that may be of interest:
http://www.amazon.com/Poker-strategy-Winning-game-theory/dp/0399506691
http://www.amazon.com/Mathematics-Poker-Bill-Chen/dp/1886070253
class Card {
// ??? probably just an int (0 to 51), but certainly not a String.
// Instead of using class Card below, directly using an int woulb be OK.
}
class Hand {
Set<Card> hand; // size 2
}
class Draw { // not sure of the exact poker name for the 5 cards
Set<Card> flop; // size 3
Card turn;
Card river;
}
class Bet {
Player player;
// or maybe "Double" instead; then amount == null means player dropping out.
// or use 0.0 to mean dropped out.
double amount;
}
class BettingRound {
// Includes initial "entry" and all subsequent calls.
// Should include players dropping out also.
List<Bet> bets;
}
class Game {
Draw draw;
Map<Player, Hand> hands;
// rounds 0 and 1 are special since turn and river are not shown
List<BettingRound> rounds;
}
You should also know how much money each player has, I guess. You could keep track of that with a third field (total cash before the bet) in class Bet.
After thinking about it for a bit more, I think I have answered my own question. I've decided not to try to both store every action in a tabular way and try to get quick lookup of frequency counts for betting lines in the same data structure.
Instead, I am going to use my class above as the database-like storage to disk and use a DAG for the betting lines where the edges are tuples of {action, position, players ahead} and the vertices are frequency counts. I think a DAG is correct over a trie here since I do want multiple edges coming into a vertex since lines with common suffix are considered close.

Categories