使用negamax算法实现合理的Checkers启发式

时间:2018-10-01 07:03:38

标签: java artificial-intelligence

因此,我一直在尝试创建一个能够赢得很多Checkers游戏的AI,问题在于我现在所做的实现似乎会导致内存效率低下,并且我会收到诸如:

线程“ main”中的异常java.lang.OutOfMemoryError:Java堆空间

该游戏是为我预先制作的,通过使用GameState.findPossibleMoves(lNextStates)函数,我可以计算出可能发生的所有动作。我目前正在做的是:

import java.util.*;

public class Player {
    static int myPlayer = 0;
    static int opponentPlayer = 0;

    public GameState play(final GameState pState, final Deadline pDue) {
        /*
         * introducing neccessary constants
         */
        myPlayer = pState.getNextPlayer();
        double alpha = Double.NEGATIVE_INFINITY;
        double beta = Double.POSITIVE_INFINITY;
        Node root = new Node(Double.NEGATIVE_INFINITY, pState);
        int depth = 0;
        double v = -10;
        Calculator calculator = new Calculator(opponentPlayer, myPlayer);
        Vector<GameState> nextStates = new Vector<GameState>();
        pState.findPossibleMoves(nextStates);
        /*
         * creating a node with pState as state
         */
        Node nodeToStoreFirstState = new Node(v, pState);
        Node interestingNode = null;
        if(myPlayer == Constants.CELL_RED) {
            opponentPlayer = Constants.CELL_WHITE;
        }
        else {
            opponentPlayer = Constants.CELL_RED;
        }


        if (nextStates.size() == 0) {
            // Must play "pass" move if there are no other moves possible.
            return new GameState(pState, new Move());
        }
        else {
            negaMax(nodeToStoreFirstState, depth, alpha, beta, myPlayer, root, calculator);
            interestingNode = root.findingHighestValue();
            return interestingNode.getState();

        }
    }



    public static Vector<Node> calculationFirstMove(GameState pState, int myPlayer, int opponentPlayer) {
        /*
         * heuristics for first moves,
         * check right and left moves, rewarding them with different v
         */ 
        // sätt Constants.CELL_RED till myPlayer och Constnats.CELL_WHITE till opponentPLayer
        Vector<GameState> lNextStates = new Vector<GameState>();
        pState.findPossibleMoves(lNextStates);
        Vector<Node> nodesStored = new Vector<Node>();
        for(GameState state : lNextStates) {
            double v = 0;
            Node storingValue = new Node(v, state);
            for(int row = 0; row < GameState.NUMBER_OF_SQUARES; row++) {
                for(int col = 0; col < GameState.NUMBER_OF_SQUARES; col++) {
                    if(pState.get(row, col) == myPlayer) {
                        if(pState.get(row+1, col+1) == opponentPlayer) {
                            if(pState.get(row + 2, col + 2 ) == Constants.CELL_EMPTY) {
                                v = v + 30;
                                if(pState.get(row + 3, col + 3) == opponentPlayer) {
                                    if(pState.get(row + 4, col + 4) == Constants.CELL_EMPTY){
                                        v = v + 100;
                                    }
                                }
                            }
                        }

                    }
                    // sätt Constants.CELL_RED till myPlayer och Constnats.CELL_WHITE till opponentPLayer
                    if(pState.get(row, col) == myPlayer) {
                        if(pState.get(row+1, col-1) == opponentPlayer) {
                            if(pState.get(row + 2, col -2) == Constants.CELL_EMPTY) {
                                v = 30;
                                if(pState.get(row + 3, col - 3) == opponentPlayer) {
                                    if(pState.get(row + 4, col - 4) == Constants.CELL_EMPTY){
                                        v = 100;
                                    }
                                }
                            }
                        }

                    }
                }
            }
            storingValue.setValue(v);
            nodesStored.add(storingValue);
        }
        return nodesStored;
        }

    public static Vector<Node> setNodesInOrder(GameState pState) {
        Vector<Node> nodesStored = calculationFirstMove(pState, myPlayer, opponentPlayer);
        Node currentLargestNode = nodesStored.get(0);
        for(int child = 1; child < nodesStored.size(); child ++) {
            Node comparingNode = nodesStored.get(child);
            Node largestNode = currentLargestNode.compareTo(comparingNode);
            nodesStored.add(largestNode);
        }
        return nodesStored;
    }


    public double negaMax(Node node, int depth, double alpha, double beta, int currentPlayer, Node root, Calculator calculator) {
        double v = 0;
        Vector<Node> nodesInOrder = Player.setNodesInOrder(node.getState());
        if(depth == 0 || nodesInOrder.size() == 0) {
            //v = calculator.totsum  // implementera heuristik som vanligt
            //v = calculator.heuristics(node.getState());
            v = nodesInOrder.elementAt(0).getValue();
            Node state = new Node(v, node.getState());
            state.setParent(root);
        }

        else if(currentPlayer == myPlayer) {
            v = Double.NEGATIVE_INFINITY;
            for(Node child : nodesInOrder) {
                Node newNode = new Node(v, child.getState());
                root.setChild(newNode);
                newNode.setParent(root);
                v = Math.max(v, negaMax(child, depth -1, alpha, beta, opponentPlayer, root, calculator));
                newNode.setValue(v);
                alpha = Math.max(alpha, v);
                if(beta <= alpha) {
                    break;
                }
            }
        }
        else {
            v = Double.POSITIVE_INFINITY;
            for(Node child : nodesInOrder) {
                Node newNode = new Node(v, child.getState());
                root.setChild(newNode);
                newNode.setParent(root);
                v = Math.min(v, negaMax(child, depth-1, alpha, beta, myPlayer, root, calculator));
                newNode.setValue(v);
                beta = Math.min(beta, v);
                if(beta <= alpha) {
                    break;
                }
            }
        }
        return v;   
    }
}

这是一堆代码,我知道,这也是为什么我也发布问题的主要原因,我希望我的calculationFirstMove方法效率很低,我认为我处于需要一些位置的位置从这一点出发的帮助。预先感谢!

0 个答案:

没有答案