public void MakeBestMove(out int X, out int Y, Board board) { this.originalBoard = board; AlphaBeta(-50000, 50000, 0, 7, originalBoard.currentPlayer, board); //PVS(-50000, 50000, 0, 6, originalBoard.currentPlayer, board); X = this.bestMoveX; Y = this.bestMoveY; }
protected int AlphaBeta(int alpha, int beta, int pass, int depth, int player, Board previousBoard) { int subBestX = -1; int subBestY = -1; int bestValue = MIN_VALUE; if (depth <= 0) return Evaluation(previousBoard,player); //Try every possible position for( int i=0; i<8; i++ ) { for (int j = 0; j < 8; j++) { Board nextBoard = previousBoard.CloneBoard().FlipPiece(i, j, false, player); if (nextBoard != null) { int value = -AlphaBeta(-beta, -alpha, 0, depth - 1, -player, nextBoard); if (value > beta) return value; if (value > bestValue) { bestValue = value; subBestX = i; subBestY = j; if(value > alpha) alpha = value; } } } } if (bestValue <= MIN_VALUE) { if (pass == 0) { //here may be needed to be modified //since the game is over, the player can win then the weight should be //very large to assure he can win return previousBoard.ComputeScore(player) * 100; } //DoPassMove(); bestValue = -AlphaBeta(-beta, -alpha, 1, depth,-player,previousBoard); //UnDoPassMove(); } bestMoveX = subBestX; bestMoveY = subBestY; return bestValue; }
public Board CloneBoard() { Board resultBoard = new Board(); resultBoard.currentPlayer = this.currentPlayer; resultBoard.noOfPieces = this.noOfPieces; resultBoard.gameMode = this.gameMode; resultBoard.startPlayer = this.startPlayer; for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) { resultBoard.positions[i, j].color = this.positions[i, j].color; resultBoard.positions[i, j].weight = this.positions[i, j].weight; } return resultBoard; }
/// <summary> /// Place a piece on (direcX, direcY). (-2, -2) indicates initial play by AI /// </summary> /// <param name="X"></param> /// <param name="Y"></param> /// <returns>0: Successfully placed; 1: Game Ended; 2: No possible Move for current player; 3: Error in AI</returns> public int Play(int direcX, int direcY, out string result, bool isAI) { if (direcX != -2 || direcY != -2) { if (positions[direcX, direcY].color == 0) { Board previous = this.CloneBoard(); if (FlipPiece(direcX, direcY, false, currentPlayer) != null) { lastPlayX = direcX; lastPlayY = direcY; if (noOfPieces == 64) { result = EndGame(); return 1; } if (!isAI) this.previousBoard = previous; } else if (isAI) { result = "Error: AI try to put in invalid place " + direcX.ToString() + "/" + direcY.ToString(); return 3; } else { result = ""; return -1; } } else if (!isAI) { result = ""; return -1; } } int statusCode = -1; int noPossibleMoves = GetNoPossibleMoves(currentPlayer); if (noPossibleMoves == 0) { currentPlayer = -currentPlayer; noPossibleMoves = GetNoPossibleMoves(currentPlayer); if (noPossibleMoves == 0) { result = EndGame(); return 1; } result = currentPlayer == 1 ? "No possible move for black player. White player plays again" : "No possible move for white player. Black player plays again"; statusCode = 2; } else { result = currentPlayer == 1 ? "White player playing..." : "Black player playing..."; statusCode = 0; } if (IsCurrentPlayerAI() && gameMode == 1 && (statusCode == 0 || statusCode == 2) && isAI) { statusCode = AIPlay(out result); if (statusCode == -1) { result = "Error: AI failed to move"; statusCode = 3; } //else //{ // result = currentPlayer == 1 ? "White player playing..." : "Black player playing..."; // statusCode = 0; //} } return statusCode; }
protected int ComputeWeight(Board board,int player) { int result = 0; foreach (Position pos in board.positions) { result += (pos.color * pos.weight); } return player == 1 ? result : -result; }
protected int Evaluation(Board board,int player) { //int num = 0; //for (int i = 0; i < 8; i++) //{ // for (int j = 0; j < 8; j++) // { // if (board.positions[i, j].color != 0) // num++; // } //} //if(num > 10) //{ //W_MOBILITY = 1; // W_WEIGTH = 3; //} return W_WEIGTH * ComputeWeight(board, player) + W_SELF_MOBILITY * Mobility(player);// -W_OPP_MOBILITY * Mobility(-player); }