Итак, я пытался создать ИИ, способный выигрывать во многих играх в шашки, проблема в том, что реализация, которую я сделал сейчас, кажется неэффективной для памяти, и я получаю такие предупреждения, как:
Исключение в потоке "main" java.lang.OutOfMemoryError: Куча Javaв состоянии рассчитать каждый возможный ход может быть.В настоящее время я сделал следующее:
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 будет оченьнеэффективно, я думаю, что я нахожусь в положении, когда мне нужна помощь, чтобы пойти с этой точки.Заранее спасибо!