// finds the value of a specific move in a column // deep is how many moves ahead the alg is looking public float FindMoveValue(Board GameBoard, int col, int deep) { // create temporary Board, make the best move and check for next best //Board newBoard = GameBoard.Copy(); // check if the move will win the game //WinState? win = newBoard.CheckWinState(); WinState? win = GameBoard.CheckWinState(); // if the game is going to end with the move if (win != null) { // check if it will end with draw if (win == WinState.TIE) return 0f; // return 1 (best) for win, and -1 (worst) for lose //else if (win == WinState.BLACKWIN && Game1.AIColor == BoardState.BLACK) else if (win == WinState.BLACKWIN)// && GameBoard.CurrentPlayer == TypeToken.TOKEN_BLACK) return -1f; //else if (win == WinState.REDWIN && Game1.AIColor == BoardState.RED) else if (win == WinState.REDWIN)// && GameBoard.CurrentPlayer == TypeToken.TOKEN_RED) return 1f; else return -1f; } // if we have looked forward the maximum amount // return the value of the move if (deep == DEEPNESS) { // MCScore //int newStrength = Convert.ToInt32(Strength / ((double)Math.Pow(7, DEEPNESS))); //alg.SetStrength(newStrength); alg.SetStrength(5); return alg.FindDeepValue(GameBoard, col); } //newBoard.MakeMove(col); GameBoard.MakeMove(col); // Get the possible moves for the newBoard (the next move would be players) List<int> possibleMoves = GameBoard.GetPossibleMoves(); //newBoard.GetPossibleMoves(); // start looking into deeper moves float value = float.MinValue; foreach (int col2 in possibleMoves) value = Math.Max(value, -1f * FindMoveValue(GameBoard, col2, deep + 1)); // remove the last move made so it doesnt stay permanent GameBoard.Unmove(col); return value; }
int Strength = 100; // 20;//30000; #endregion Fields #region Constructors public OrdenadorIA(List<SquareViewModel> squares, int numRows, int numColumns) { //Strength = 40000; alg.SetStrength(Strength); board = new Board(squares, numRows, numColumns); List<int> possibleMoves = board.GetPossibleMoves(); // represents the best move value (start at obsurdly low) float best = float.MinValue; // the column that the AI will play int bestColumn = -1; // loop through each column and check the value of the move foreach (int col in possibleMoves) { float value = FindMoveValue(board, col, 0); // if the column has a better value for the AI than the current best move // use that column as the best if (value > best) { best = value; bestColumn = col; } } // return the best column fo the AI to play selectedColumn = bestColumn; }
public float FindDeepValue(Board GameBoard, int col) { int value = 0; for (int i = 0; i < Strength; i++) { Board newBoard = GameBoard.Copy(); newBoard.MakeMove(col); WinState? winner = CheckNextMoves(newBoard); // if the AI would win, increase the value of the move // if ai would lose, or tie, decrese the value //if (winner = WinState.BLACKWIN && Game1.AIColor == BoardState.BLACK) if (winner == WinState.BLACKWIN)// && GameBoard.CurrentPlayer == TypeToken.TOKEN_BLACK) value--; //else if (winner = WinState.REDWIN && Game1.AIColor == BoardState.RED) else if (winner == WinState.REDWIN)// && GameBoard.CurrentPlayer ==TypeToken.TOKEN_RED) value++; else if (winner == WinState.TIE) value--; else value--; } // make the return value either -1 or 1 return (value / (float)Strength); }
/* Checks all the next possible moves given a Board. */ WinState? CheckNextMoves(Board GameBoard) { // will be randomized from all possible moves int nextMove; // play a single move, then keep playing checking // every move to find the best ones while (!GameBoard.CheckForWinner()) { List<int> possibleMoves = GameBoard.GetPossibleMoves(); // choose a random move from the possible moves nextMove = rnd.Next(0, possibleMoves.Count); GameBoard.MakeMove(possibleMoves[nextMove]); } // return who would win the game return GameBoard.Winner; }
public Board Copy() { Board b = new Board(); b.numColumns = this.numColumns; b.NumRows = this.NumRows; b.currentPlayer = this.currentPlayer; b.opponentPlayer = this.opponentPlayer; b.squares = new List<Square>(); foreach (Square s in this.squares) b.squares.Add(new Square() { Token = s.Token }); b.isGameOver = this.isGameOver; b.Winner = this.Winner; return b; }