protected static bool ImmediateBlock(Piece inPiece, TicTacToeBoard inBoard, ref ushort bestMove) { Piece p = (inPiece.Value == Piece.PieceValue.X) ? new Piece(Piece.PieceValue.X) : new Piece(Piece.PieceValue.O); for (ushort i = 0; i < inBoard.Length; ++i) { // create a clone of the current board TicTacToeBoard tempBoard = new TicTacToeBoard(inBoard); tempBoard.Place(p, i); if (tempBoard.Win(p.Value)) { bestMove = i; return(true); } } return(false); }
protected static bool ImmediateWin(Piece inPiece, TicTacToeBoard inBoard, ref ushort bestMove) { for (ushort i = 0; i < inBoard.Length; ++i) { // create a clone of the current board TicTacToeBoard tempBoard = new TicTacToeBoard(inBoard); // place a piece on each sqaure in the new board tempBoard.Place(inPiece, i); // and see if it results in an immediate win if (tempBoard.Win(inPiece.Value)) { bestMove = i; return(true); } } return(false); }
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); }