因此,我一直在尝试创建一个能够赢得很多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方法效率很低,我认为我处于需要一些位置的位置从这一点出发的帮助。预先感谢!