Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Linq;
- namespace XOX
- {
- internal class Program
- {
- private static void Main()
- {
- new Game().Init();
- Console.WriteLine("\n\nPress any key to quit.");
- Console.ReadKey();
- }
- }
- internal class Game
- {
- public void Init()
- {
- var controller = new Controller();
- controller.InitEmptyGameField();
- controller.GameLoop();
- }
- }
- internal class Model
- {
- public static GameFieldStatus[] GameField = new GameFieldStatus[9];
- public static GameStatusEnum GameStatus = GameStatusEnum.Playing;
- public enum GameFieldStatus
- {
- Empty = 0,
- X,
- O
- }
- public enum GameStatusEnum
- {
- Playing,
- XWon,
- OWon,
- Tie
- }
- }
- internal class View
- {
- public static void PrintGameField()
- {
- for (var i = 1; i <= Model.GameField.Length; i++)
- {
- Console.Write($"| {ParseGameFieldStatus(Model.GameField[i - 1], i)} |");
- if (i != 0 && i % 3 == 0)
- Console.Write("\n");
- }
- }
- public static void PrintErrorNotANumber()
- {
- Console.Clear();
- Console.WriteLine("\nError: This was not a number. Please try again. \n");
- }
- public static void PrintErrorFieldTaken()
- {
- Console.Clear();
- Console.WriteLine("\nError: This field is already taken. Please try again. \n");
- }
- public static void PrintErrorWrongNumber()
- {
- Console.Clear();
- Console.WriteLine("Please enter a valid number. \n");
- }
- public static void PrintWaitForInput()
- {
- Console.WriteLine("Please enter the fieldnumber you want to mark with X: ");
- }
- public static void ClearConsole()
- {
- Console.Clear();
- }
- public static void PrintGameStatus()
- {
- switch (Model.GameStatus)
- {
- case Model.GameStatusEnum.Playing:
- break;
- case Model.GameStatusEnum.XWon:
- Console.WriteLine("Player won the game! :)\n\n");
- break;
- case Model.GameStatusEnum.OWon:
- Console.WriteLine("PC won the game! :(\n\n");
- break;
- case Model.GameStatusEnum.Tie:
- Console.WriteLine("Nobody won, tie. :|\n\n");
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
- private static string ParseGameFieldStatus(Model.GameFieldStatus status, int position = 0)
- {
- switch (status)
- {
- case Model.GameFieldStatus.Empty:
- return $" {position} ";
- case Model.GameFieldStatus.X:
- return " X ";
- case Model.GameFieldStatus.O:
- return " O ";
- default:
- throw new ArgumentOutOfRangeException(nameof(status), status, null);
- }
- }
- }
- internal class Controller
- {
- private static bool _wrongPlayerMove;
- public void GameLoop()
- {
- for (;;)
- {
- View.PrintGameField();
- View.PrintWaitForInput();
- ParsePlayerInput(Console.ReadKey());
- CheckForWinCondition();
- if (ParseWinCondition())
- break;
- if(!_wrongPlayerMove) // only move when player has entered a sane and vaild input
- MakeEnemyMove();
- CheckForWinCondition();
- if (ParseWinCondition())
- break;
- }
- View.PrintGameField(); // print the game one more time to celebrate wins visually ;)
- }
- public void InitEmptyGameField()
- {
- for (var i = 0; i < Model.GameField.Length; i++)
- {
- Model.GameField[i] = Model.GameFieldStatus.Empty;
- }
- }
- private static void ParsePlayerInput(ConsoleKeyInfo input)
- {
- if (int.TryParse(input.KeyChar.ToString(), out var intResult))
- {
- _wrongPlayerMove = false; // reset dirty flag
- if (intResult < 1)
- {
- _wrongPlayerMove = true;
- View.PrintErrorWrongNumber();
- return;
- }
- if (Model.GameField[intResult - 1] == Model.GameFieldStatus.Empty)
- Model.GameField[intResult - 1] = Model.GameFieldStatus.X;
- else
- {
- View.PrintErrorFieldTaken();
- _wrongPlayerMove = true;
- return;
- }
- View.ClearConsole();
- }
- else
- {
- _wrongPlayerMove = true;
- View.PrintErrorNotANumber();
- }
- }
- private static bool ParseWinCondition()
- {
- if (Model.GameStatus == Model.GameStatusEnum.Playing) return false;
- View.PrintGameStatus();
- return true;
- }
- private static void MakeEnemyMove()
- {
- // get available fields array positions, read: an array of array positions, where GameFieldStatus is empty
- var emptyFieldsArrayPosition = Model.GameField.Select((s, i) => new {i, s})
- .Where(t => t.s == Model.GameFieldStatus.Empty)
- .Select(t => t.i)
- .ToArray();
- // TODO: Make enemy smarter
- // chose one array position of the earlier created array
- var randomEmptyArrayPosition = new Random().Next(0, emptyFieldsArrayPosition.Length-1);
- var chosenField = emptyFieldsArrayPosition[randomEmptyArrayPosition];
- Model.GameField[chosenField] = Model.GameFieldStatus.O;
- }
- private static void CheckForWinCondition()
- {
- if (CheckHorizontal(Model.GameFieldStatus.X) || CheckVertical(Model.GameFieldStatus.X) ||
- CheckDiagonal(Model.GameFieldStatus.X))
- {
- Model.GameStatus = Model.GameStatusEnum.XWon;
- return;
- }
- if (CheckHorizontal(Model.GameFieldStatus.O) || CheckVertical(Model.GameFieldStatus.O) ||
- CheckDiagonal(Model.GameFieldStatus.O))
- {
- Model.GameStatus = Model.GameStatusEnum.OWon;
- return;
- }
- if (Model.GameField.Any(x => x == (int) Model.GameStatusEnum.Playing)) return; // not all fields filled yet, early out
- Model.GameStatus = Model.GameStatusEnum.Tie; // all fields filled, no winner -> tie
- }
- private static bool CheckHorizontal(Model.GameFieldStatus checkForThisPlayer)
- {
- for (var i = 0; i < Model.GameField.Length; i += 3)
- {
- if (Model.GameField[i] == checkForThisPlayer && Model.GameField[i + 1] == checkForThisPlayer &&
- Model.GameField[i + 2] == checkForThisPlayer)
- return true;
- }
- return false;
- }
- private static bool CheckVertical(Model.GameFieldStatus checkForThisPlayer)
- {
- for (var i = 0; i < 3; i++)
- {
- if (Model.GameField[i] == checkForThisPlayer && Model.GameField[i + 3] == checkForThisPlayer &&
- Model.GameField[i + 6] == checkForThisPlayer)
- return true;
- }
- return false;
- }
- private static bool CheckDiagonal(Model.GameFieldStatus checkForThisPlayer)
- {
- if (Model.GameField[0] == checkForThisPlayer && Model.GameField[4] == checkForThisPlayer &&
- Model.GameField[8] == checkForThisPlayer)
- return true;
- if (Model.GameField[2] == checkForThisPlayer && Model.GameField[4] == checkForThisPlayer &&
- Model.GameField[6] == checkForThisPlayer)
- return true;
- return false;
- }
- }
- }
Add Comment
Please, Sign In to add comment