I am programming an AI for a chess-like game, based on two types of pieces on a 8 x 8 grid.
I want to build a kind of minmax tree, which represents each possible move in a game, played by white players in first, and by black players in second.
I have this generate() method which is call recursively. I need to be able to display about 8 levels of possible moves. Without optimization, this three has 8^8 leafs.
I implemented a simple system which determinate if a grid has actually ever been calculated and if its the case, system just points a child to the ever-calculated child reference.
I don’t know if my explanations are clear, I will join a part of code that you should be able to understand.
The problem is that actually, I am able to generate about 3 or 4 levels of all possibilities. I am far of 8.
I would like to be able to calculate it in less than 5 seconds..
So guys, do you see a solution for optimize my algorithm ?
This is the generate function: leftDiagonalMove(), rightDiagonalMove() and frontMove() return false if a move is illegal or move the piece in the grid and return true, if the move is legal.
clone() creates a new instance with the same properties of it’s “parent” and backMove() just step back to last Move.
public void generate(Node root, boolean white, int index) { Grid grid = root.getGrid(); Stack<Piece> whitePieces = grid.getPiecesByColor(WHITE); Stack<Piece> blackPieces = grid.getPiecesByColor(BLACK); Node node; String serial = ""; // white loop for (int i = 0; i < whitePieces.size() && white; i++) { Piece wPiece = whitePieces.get(i); if (grid.leftDiagonalMove(wPiece)) { serial = grid.getSerial(); if(!allGrids.containsKey(serial)){ node = new Node(grid.clone()); node.setMove(grid.getLastMove()); root.addChild(node); // add modified grid allGrids.put(serial, node); //actualGrid.display(); if (index < 5 && grid.getPosition(wPiece).x > 0) generate(node, !white, index + 1); actualGrid.backMove(); // back step to initial grid } else{ root.addChild(allGrids.get(serial)); } } if (grid.frontMove(wPiece)) { // same code as leftMove } if (grid.rightDiagonalMove(wPiece)) { // same code as leftMove } } // black loop for (int i = 0; i < blackPieces.size() && !white; i++) { Piece bPiece = blackPieces.get(i); if (grid.leftDiagonalMove(bPiece)) { // same code as white loop and replacing wPiece by bPiece } if (grid.frontMove(bPiece)) { // same code as white loop and replacing wPiece by bPiece } if (grid.rightDiagonalMove(bPiece)) { // same code as white loop and replacing wPiece by bPiece } } }
Advertisement
Answer
You need to use something called AlphaBeta pruning on your generated MinMax trees of moves. More on this here:
http://en.wikipedia.org/wiki/Alpha-beta_pruning
http://www.progtools.org/games/tutorials/ai_contest/minmax_contest.pdf
Basically you do one level of branches and then using pruning you eliminate bad branches early. Then from the non eliminated branches you calculate (for each) another level. You prune again until you reach a desired depth.
Here are a few more links for you to read up on minmax:
1. http://en.wikipedia.org/wiki/Minimax
2. MinMax trees – when Min can win in two steps
This one is on optimizing pruning for chess games:
1. http://en.wikipedia.org/wiki/Alpha-beta_pruning#Heuristic_improvements
2. http://en.wikipedia.org/wiki/Refutation_table#Related_techniques