private static void InitSingleplayer(OthelloGame game, Queue <string> moveSequence, Queue <char[, ]> boardStates) { char playerColor = '\0', aiColor = '\0'; string userInput; bool validInput = false; OthelloAI ai = null; // loop until user gives a valid color selection while (!validInput) { Console.Clear(); Console.Write("Pick the human player color (B/W): "); userInput = Console.ReadLine(); // if users input matches one of the selection options, assign colors if (userInput.Length == 1 && Regex.IsMatch(userInput, "[BbWw]")) { // if human chose black, assign human black color and ai white color if (Regex.IsMatch(userInput, "[Bb]")) { // initialize colors playerColor = '@'; aiColor = 'O'; // initialize AI ai = new OthelloAI(game, false); moveSequence.Enqueue("Human Player: Black\nAI: White"); } else // if human chose white, do the reverse { // initialize colors playerColor = 'O'; aiColor = '@'; // initialize AI ai = new OthelloAI(game, true); moveSequence.Enqueue("Human Player: White\nAI: Black"); } validInput = true; } else { Console.WriteLine("Entered color selection was invalid, please try again.\nPress enter to continue..."); Console.ReadLine(); } } Console.WriteLine("Player pieces are: " + playerColor + "\nAI pieces are: " + aiColor + "\nPress enter to begin..."); Console.ReadLine(); bool playerIsBlack = playerColor == '@'; PlaySingleplayer(game, ai, moveSequence, boardStates, playerIsBlack); }
private static void PlaySingleplayer(OthelloGame game, OthelloAI ai, Queue <string> moveSequence, Queue <char[, ]> boardStates, bool playerIsBlack) { string userInput; // begin gameplay game.ResetBoard(); // bool tracks whether player entered move or a command such as toggling alpha-beta bool validMoveEntered; // game loops until neither black nor white have remaining moves bool blackHasMoves; // cache result of game.HasLegalMoves('B') to avoid recomputation while ((blackHasMoves = game.HasLegalMoves('@')) && game.HasLegalMoves('O')) { // execution instructions for when player is black if (playerIsBlack) { if (blackHasMoves) { // loop until black player enters a legal move do { game.PrintBoard(); Console.WriteLine("Enter move as ColRow, -1 to toggle Alpha-Beta Pruning, or -2 to toggle debug mode"); Console.Write("\nBlack, enter your selection: "); userInput = Console.ReadLine(); switch (userInput) { case "-1": ai.ToggleAlphaBeta(); validMoveEntered = false; Console.WriteLine($"Alpha-Beta Active is now {ai.AlphaBetaActive}\nPress enter to continue..."); Console.ReadLine(); break; case "-2": DEBUG_MODE = !DEBUG_MODE; validMoveEntered = false; Console.WriteLine($"Debug mode is now {DEBUG_MODE}\nPress enter to continue..."); Console.ReadLine(); break; default: validMoveEntered = game.PlayMove(userInput); break; } } while (!validMoveEntered); moveSequence.Enqueue("Black: " + userInput.ToUpper()); boardStates.Enqueue((char[, ])game.BoardState.Clone()); } else { Console.WriteLine("Black has no moves. Press enter to pass..."); Console.ReadLine(); game.PassMove(); } // wait for user to let ai move game.PrintBoard(); Console.WriteLine("White's turn"); if (game.HasLegalMoves('O')) { int[] aiMove = ai.ChooseMove(); game.PlayMove(aiMove); string aiMoveFormatted = FormatAIMove(aiMove); moveSequence.Enqueue("White: " + aiMoveFormatted); boardStates.Enqueue((char[, ])game.BoardState.Clone()); } else { Console.WriteLine("White has no moves. Press enter to pass..."); Console.ReadLine(); game.PassMove(); } } else // execution instructions for when player is white { // wait for user to let ai move game.PrintBoard(); Console.WriteLine("Black's turn"); if (blackHasMoves) { int[] aiMove = ai.ChooseMove(); game.PlayMove(aiMove); string aiMoveFormatted = FormatAIMove(aiMove); moveSequence.Enqueue("Black: " + aiMoveFormatted); boardStates.Enqueue((char[, ])game.BoardState.Clone()); } else { Console.WriteLine("Black has no moves. Press enter to pass..."); Console.ReadLine(); game.PassMove(); } if (game.HasLegalMoves('O')) { // loop until white player enters a legal move do { game.PrintBoard(); Console.WriteLine("Enter move as ColRow, -1 to toggle Alpha-Beta Pruning, or -2 to toggle debug mode"); Console.Write("\nWhite, enter your move/selection: "); userInput = Console.ReadLine(); switch (userInput) { case "-1": ai.ToggleAlphaBeta(); validMoveEntered = false; Console.WriteLine($"Alpha-Beta Active is now {ai.AlphaBetaActive}\nPress enter to continue..."); Console.ReadLine(); break; case "-2": DEBUG_MODE = !DEBUG_MODE; validMoveEntered = false; Console.WriteLine($"Debug mode is now {DEBUG_MODE}\nPress enter to continue..."); Console.ReadLine(); break; default: validMoveEntered = game.PlayMove(userInput); break; } } while (!validMoveEntered); moveSequence.Enqueue("White: " + userInput.ToUpper()); boardStates.Enqueue((char[, ])game.BoardState.Clone()); } else { Console.WriteLine("White has no moves. Press enter to pass..."); Console.ReadLine(); game.PassMove(); } } } Console.WriteLine("There are no more legal moves. Press enter to continue..."); Console.ReadLine(); // score game int blackScore = 0, whiteScore = 0; foreach (char piece in game.BoardState) { if (piece == '@') { blackScore++; } else if (piece == 'O') { whiteScore++; } } // declare winner if (blackScore > whiteScore) { Console.WriteLine("Black Wins!"); } else if (whiteScore > blackScore) { Console.WriteLine("White Wins!"); } else { Console.WriteLine("Game Tied!"); } Console.WriteLine($"Black Score: {blackScore}\nWhite Score: {whiteScore}"); moveSequence.Enqueue($"Final Score:\nBlack Score: {blackScore}\nWhite Score: {whiteScore}"); Console.WriteLine("Press enter to continue..."); Console.ReadLine(); }
public OthelloComputer(int color, int depth) : base(color) { ai = new OthelloAI(depth, color); }