public override ushort Move(TicTacToeBoard currentBoard) { ushort chosenMove = 0; do { // call the method used to determine the move chosenMove = this.moveMethod(currentBoard, this.Token); } while (currentBoard.At(chosenMove)); return(chosenMove); }
public static ushort MinMaxMove(TicTacToeBoard board, Piece.PieceValue token) { // computer always plays the center square if it is available if (!board.At(4)) { return(4); } // computer's 2nd move should be a corner if computer went first // computer's 1st move should be a corner if the center is taken // really not the best strategy if ((board.Moves == 1 && board.At(4)) || board.Moves == 2) { return((TicTacToeBoard.Corners)[Computer.randNum.Next(0, TicTacToeBoard.Corners.Length - 1)]); } // start with recommended move ushort aMove = 4; // use MinMax strategy to find the next move MoveStrategy strategy = Computer.LookAhead(new Piece(token), new TicTacToeBoard(board), ref aMove); return(aMove); }
public override ushort Move(TicTacToeBoard currentBoard) { // computer's algorithm will modify the board so create a copy to work on // TicTacToeBoard tempBoard = new TicTacToeBoard(currentBoard); // call the method used to determine the move ushort chosenMove = this.moveMethod(currentBoard, this.Token); while (currentBoard.At(chosenMove)) { chosenMove = this.moveMethod(currentBoard, this.Token); } return(chosenMove); }
/// <summary>Draws the current board for a command line interface.</summary> private void DrawBoard() { byte i = 0; // iterator // iterate through the board for (i = 0; i < theBoard.Length; ++i) { if (theBoard.At(i)) { switch (theBoard.GetAt(i).Value) { case Piece.PieceValue.X: Console.Write("X "); break; case Piece.PieceValue.O: Console.Write("O "); break; default: // some kind of error has occured throw new System.Exception(); } // end switch } else { Console.Write("{0} ", i); } // start a new line after mDim squares if (i % theBoard.Dimension == theBoard.Dimension - 1) { Console.WriteLine(); } } // end for loop }
protected static MoveStrategy LookAhead(Piece inPiece, TicTacToeBoard inBoard, ref ushort bestMove) { // unused dummy value to seend the algorithm ushort aDummy = 0; // temporary strategy MoveStrategy aResponse; // the strategy to return MoveStrategy outValue = (inPiece.Value == Piece.PieceValue.X) ? MoveStrategy.OWin - 1 : MoveStrategy.XWin + 1; // first check to see if the game is a draw if (inBoard.Full()) { outValue = MoveStrategy.Draw; } // return any move that results in an immediate win else if (Computer.ImmediateWin(inPiece, inBoard, ref bestMove)) { outValue = (inPiece.Value == Piece.PieceValue.X) ? MoveStrategy.XWin : MoveStrategy.OWin; } // return any move that will result in blocking the other player from an immediate win on his next turn else if (Computer.ImmediateBlock(inPiece, inBoard, ref bestMove)) { outValue = (inPiece.Value == Piece.PieceValue.X) ? MoveStrategy.XBlock : MoveStrategy.OBlock; } // no immediate wins so look for a promising move else { for (ushort i = 0; i < inBoard.Length; ++i) { if (!inBoard.At(i)) { inBoard.Place(inPiece, i); // swap pieces and go down a move Piece aPiece = (inPiece.Value == Piece.PieceValue.X) ? new Piece(Piece.PieceValue.O) : new Piece(Piece.PieceValue.X); // call look ahead recursively with a copy of the board each time aResponse = LookAhead(aPiece, new TicTacToeBoard(inBoard), ref aDummy); // determine the best move switch (inPiece.Value) { case Piece.PieceValue.X: if (aResponse > outValue) { outValue = aResponse; bestMove = i; } break; case Piece.PieceValue.O: if (aResponse < outValue) { outValue = aResponse; bestMove = i; } break; default: break; } // end switch } // end if } // end for loop } // end else // return the best move strategy return(outValue); }