Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- internal enum GameStatus
- {
- OnGoing,
- Tied,
- XWin,
- OWin
- }
- internal static class Program
- {
- private static void Main()
- {
- Console.WriteLine("---------------------");
- Console.WriteLine("Welcome to TicTacToe:");
- Console.WriteLine("---------------------");
- Console.WriteLine();
- Console.WriteLine("The rules are as follows: ");
- Console.WriteLine(
- "1. To make a move Type \"T\" for TOP, \"B\" for BOTTOM, \"M\" for MIDDLE, \"L\" for LEFT and \"R\" for RIGHT");
- Console.WriteLine("2. Combine the letters to reach the corners: TR (top right), BL (bottom left)");
- Console.WriteLine("3. The rest of the game will play out as a normal TicTacToe game, but the ai is random :P");
- Console.WriteLine();
- bool playAgain;
- do
- {
- PlayGame();
- Console.WriteLine("Do you want to continue playing? (Y/N)");
- var answer = Console.ReadLine()?.ToUpper() ?? "N";
- playAgain = answer == "Y";
- } while (playAgain);
- }
- private static void PlayGame()
- {
- char[,] playingField =
- {
- { ' ', ' ', ' ' },
- { ' ', ' ', ' ' },
- { ' ', ' ', ' ' },
- };
- while (true)
- {
- PrintPlayingField(playingField);
- MakeHumanMove(playingField);
- var gameStatus = GetGameStatus(playingField);
- if (gameStatus is not GameStatus.OnGoing)
- {
- ReportGameStatus(gameStatus);
- return;
- }
- MakeComputerMove(playingField);
- gameStatus = GetGameStatus(playingField);
- if (gameStatus is not GameStatus.OnGoing)
- {
- ReportGameStatus(gameStatus);
- return;
- }
- Console.WriteLine();
- }
- void ReportGameStatus(GameStatus gameStatus)
- {
- Console.WriteLine(gameStatus switch
- {
- GameStatus.Tied => "GAME IS TIED!",
- GameStatus.XWin => "YOU WIN!",
- GameStatus.OWin => "YOU LOSE!",
- _ => throw new ArgumentOutOfRangeException()
- });
- }
- }
- private static void MakeComputerMove(char[,] playingField)
- {
- var bestScore = int.MinValue;
- var bestMove = (-1, -1);
- for (var row = 0; row < playingField.GetLength(0); row++)
- {
- for (var col = 0; col < playingField.GetLength(1); col++)
- {
- if (playingField[row, col] is ' ')
- {
- playingField[row, col] = 'O';
- var score = Minimax(false, playingField);
- playingField[row, col] = ' ';
- if (score > bestScore)
- {
- bestScore = score;
- bestMove = (row, col);
- }
- }
- }
- }
- playingField[bestMove.Item1, bestMove.Item2] = 'O';
- }
- private static int Minimax(bool isMaximizing, char[,] playingField)
- {
- var gameStatus = GetGameStatus(playingField);
- if (gameStatus is GameStatus.Tied) return 0;
- if (gameStatus is not GameStatus.OnGoing) return isMaximizing ? -1 : 1;
- if (isMaximizing)
- {
- var bestScore = int.MinValue;
- for (var row = 0; row < playingField.GetLength(0); row++)
- {
- for (var col = 0; col < playingField.GetLength(1); col++)
- {
- if (playingField[row, col] is ' ')
- {
- playingField[row, col] = 'O';
- var score = Minimax(false, playingField);
- playingField[row, col] = ' ';
- bestScore = Math.Max(bestScore, score);
- }
- }
- }
- return bestScore;
- }
- else
- {
- var bestScore = int.MaxValue;
- for (var row = 0; row < playingField.GetLength(0); row++)
- {
- for (var col = 0; col < playingField.GetLength(1); col++)
- {
- if (playingField[row, col] is ' ')
- {
- playingField[row, col] = 'X';
- var score = Minimax(true, playingField);
- playingField[row, col] = ' ';
- bestScore = Math.Min(bestScore, score);
- }
- }
- }
- return bestScore;
- }
- }
- private static void MakeHumanMove(char[,] playingField)
- {
- Console.WriteLine();
- while (true)
- {
- Console.Write("Make a move!: ");
- var playerMove = Console.ReadLine()?.Trim().ToUpper() ?? string.Empty;
- if (playerMove.Length is 1) playerMove += " ";
- var (row, col) = playerMove switch
- {
- "TL" => (0, 0),
- "T " => (0, 1),
- "TR" => (0, 2),
- "L " => (1, 0),
- "M " => (1, 1),
- "R " => (1, 2),
- "BL" => (2, 0),
- "B " => (2, 1),
- "BR" => (2, 2),
- _ => (-1, -1)
- };
- if (row is -1 || playingField[row, col] is not ' ')
- {
- Console.WriteLine("You blew that one, meathead!");
- continue;
- }
- playingField[row, col] = 'X';
- return;
- }
- }
- private static GameStatus GetGameStatus(char[,] playingField)
- {
- if (IsSame((0, 0), (0, 1), (0, 2))) return GetWinStatus(playingField[0, 0]);
- if (IsSame((1, 0), (1, 1), (1, 2))) return GetWinStatus(playingField[1, 0]);
- if (IsSame((2, 0), (2, 1), (2, 2))) return GetWinStatus(playingField[2, 0]);
- if (IsSame((0, 0), (1, 0), (2, 0))) return GetWinStatus(playingField[0, 0]);
- if (IsSame((0, 1), (1, 1), (2, 1))) return GetWinStatus(playingField[0, 1]);
- if (IsSame((0, 2), (1, 2), (2, 2))) return GetWinStatus(playingField[0, 2]);
- if (IsSame((0, 0), (1, 1), (2, 2))) return GetWinStatus(playingField[0, 0]);
- if (IsSame((0, 2), (1, 1), (2, 0))) return GetWinStatus(playingField[0, 2]);
- return AnyEmptySquares() ? GameStatus.OnGoing : GameStatus.Tied;
- bool IsSame((int row, int col) a, (int row, int col) b, (int row, int col) c) =>
- playingField[a.row, a.col] is not ' '
- && playingField[a.row, a.col] == playingField[b.row, b.col]
- && playingField[b.row, b.col] == playingField[c.row, c.col];
- GameStatus GetWinStatus(char player) => player is 'X' ? GameStatus.XWin : GameStatus.OWin;
- bool AnyEmptySquares()
- {
- for (var row = 0; row < playingField.GetLength(0); row++)
- {
- for (var col = 0; col < playingField.GetLength(1); col++)
- {
- if (playingField[row, col] is ' ') return true;
- }
- }
- return false;
- }
- }
- private static void PrintPlayingField(char[,] playingField)
- {
- for (var row = 0; row < playingField.GetLength(0); row++)
- {
- for (var col = 0; col < playingField.GetLength(1); col++)
- {
- Console.Write(GetDisplay(playingField[row, col], row, col));
- Console.Write(' ');
- }
- Console.WriteLine();
- }
- string GetDisplay(char ch, int row, int col)
- {
- return ch switch
- {
- 'X' => "*X",
- 'O' => "*O",
- _ => (row, col) switch
- {
- (0, 0) => "TL",
- (0, 1) => "T ",
- (0, 2) => "TR",
- (1, 0) => "L ",
- (1, 1) => "M ",
- (1, 2) => "R ",
- (2, 0) => "BL",
- (2, 1) => "B ",
- (2, 2) => "BR",
- _ => throw new ArgumentOutOfRangeException()
- }
- };
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement