/// <summary> /// This is the main body of the program always running. It is the core for the game. The game will be played out until someone wins. /// The user will have the option to chose from playing vs AI or a friend. both the player and the enemy will be assigned player numbers. /// </summary> /// <param name="args"></param> static void Main(string[] args) { //Initiate Objects. Queue <int[, ]> replay = new Queue <int[, ]>(); Stack <int[, ]> undo = new Stack <int[, ]>(); Stack <int[, ]> redo = new Stack <int[, ]>(); winCondition winner = new winCondition(); BoardArray nBoard = new BoardArray(); BoardDraw draw = new BoardDraw(); Movement move = new Movement(); kingMe king = new kingMe(); Random RNG = new Random(); AI ai = new AI(); //Initiate Variables. int playerTurn = RNG.Next(1, 3); //Generates a number 1 or 2 randomly for which player starts the game. int[,] board = new int[8, 8]; bool gameOver = false; int humanPlayer = 0; int gameMode = 0; //Create a new board. nBoard.BoardCreate(board); Console.WriteLine("Hello welcome to CheckersCLI.\n\nIn this game you can either play against a friend localy, play against our AI\nor watch our AI battle it out!\n\n" + "To undo mistakes type 'Undo', this can only be done at the start of your turn.\nSimilarly you can also 'Redo' at the start of your turn.\n" + "\nIf you choose the wrong piece to move type 'Back' to change your selection.\n\nAt the of of every game the game will replay for you to watch.\n\nPress any button to continue..."); Console.ReadKey(); Console.Clear(); //Ask the human to choose gamemode. while (gameMode < 1 || gameMode > 3) { Console.WriteLine("Will you play against a friend 1, AI 2 or will you watch two AI battle 3? Type 1, 2 or 3 below to answer."); int.TryParse(Console.ReadLine(), out gameMode); Console.Clear(); } //If playing against AI ask the human which player they wish to be. if (gameMode == 2) { while (humanPlayer < 1 || humanPlayer > 2) { Console.WriteLine("Will you be player 1 or player 2? Type 1 or 2 below to answer."); int.TryParse(Console.ReadLine(), out humanPlayer); Console.Clear(); } } //Game loop, runs until the win condition is met. //Game switches between players at the end of of their turns. while (!gameOver) { if (playerTurn == 1) { //Draws the board and adds the instance to the undo stack and replay queue. draw.UpdateBoard(board); replay.Enqueue(board.Clone() as int[, ]); if (undo.Count == 0) { undo.Push(board.Clone() as int[, ]); } Console.WriteLine("Player 1 turn"); //If the human player chose vs AI gamemode and player 2 then the ai is player 1. //Calls object to take the moves and update the board. if (humanPlayer == 2 || gameMode == 3) { board = ai.takeMove(board, playerTurn, replay, undo, redo); } else { board = move.firstPoint(board, playerTurn, replay, undo, redo, humanPlayer); } //Check for posible kings on the board. king.kinged(board); Console.Clear(); if (redo.Count > 0) { redo.Clear(); } //Win condition. if (winner.wonYet(board) == 1) { draw.UpdateBoard(board); replay.Enqueue(board.Clone() as int[, ]); Console.WriteLine("PLAYER 1 WINS! This game took " + replay.Count + " moves!"); Console.Read(); Console.Clear(); Console.WriteLine("Now displaying replay."); //Show replay of game. foreach (int[,] q in replay) { draw.UpdateBoard(q); System.Threading.Thread.Sleep(2000); Console.Clear(); } Console.ReadLine(); gameOver = true; } Console.Clear(); playerTurn = 2; } else { //Draws the board and adds the instance to the undo stack and replay queue. draw.UpdateBoard(board); replay.Enqueue(board.Clone() as int[, ]); if (undo.Count == 0) { undo.Push(board.Clone() as int[, ]); } Console.WriteLine("Player 2 turn"); //If the human player chose vs AI gamemode and player 1 then the ai is player 2. //Calls object to take the moves and update the board. if (humanPlayer == 1 || gameMode == 3) { board = ai.takeMove(board, playerTurn, replay, undo, redo); } else { board = move.firstPoint(board, playerTurn, replay, undo, redo, humanPlayer); } //Check for posible kings on the board. king.kinged(board); Console.Clear(); if (redo.Count > 0) { redo.Clear(); } //Win condition. if (winner.wonYet(board) == 2) { draw.UpdateBoard(board); replay.Enqueue(board.Clone() as int[, ]); Console.WriteLine("PLAYER 2 WINS! This game took " + replay.Count + " moves!"); Console.Read(); Console.Clear(); Console.WriteLine("Now displaying replay.\n"); //Show replay of game. foreach (int[,] q in replay) { draw.UpdateBoard(q); System.Threading.Thread.Sleep(2000); Console.Clear(); } Console.ReadLine(); gameOver = true; } Console.Clear(); playerTurn = 1; } } }
/// <summary> /// Recieves the users coordinates on which piece they would like to move. /// </summary> /// <param name="coord"></param> /// <param name="player"></param> /// <param name="replay"></param> /// <param name="undo"></param> /// <param name="redo"></param> /// <returns> The updated instance of the board after moving. </returns> public int[,] firstPoint(int[,] coord, int player, Queue <int[, ]> replay, Stack <int[, ]> undo, Stack <int[, ]> redo, int ai) { //Initiate objects. ProxyChecker proxy = new ProxyChecker(); BoardDraw draw = new BoardDraw(); Exception e = new Exception(); //Initiate variables int enemy = 0; bool passed = false; bool needToJump = false; int robot = 0; //Set enemy of player if (player == 1) { enemy = 2; } else { enemy = 1; } //Runs until the user has input a valid set of coordinates. while (!passed) { //Get users input of two numbers split by ','. Console.WriteLine("Which piece would you like to move?"); string[] line = Console.ReadLine().Split(','); try { //Allows the user to undo. if (line[0] == "undo" || line[0] == "Undo") { if (undo.Count < 2) { Console.WriteLine("You cannot undo any further."); throw e; } else if (undo.Count < 3 & ai != 0) { Console.WriteLine("You cannot undo any further."); throw e; } redo.Push(undo.Pop()); //Undoes twice in order to undo the AI's turn as well. if (ai != 0) { redo.Push(undo.Pop()); Console.Clear(); coord = undo.Peek().Clone() as int[, ]; draw.UpdateBoard(coord); Console.WriteLine("Player " + player + " turn"); firstPoint(coord, player, replay, undo, redo, ai); } coord = undo.Peek().Clone() as int[, ]; return(coord); } //Allows the user to redo. else if (line[0] == "redo" || line[0] == "Redo") { if (redo.Count < 1) { Console.WriteLine("You cannot redo any further."); throw e; } else if (redo.Count < 2 & ai != 0) { Console.WriteLine("You cannot redo any further."); throw e; } undo.Push(redo.Pop()); //Redo redoes twice in order to redo the AI's turn as well. if (ai != 0) { undo.Push(redo.Pop()); Console.Clear(); coord = undo.Peek().Clone() as int[, ]; draw.UpdateBoard(coord); firstPoint(coord, player, replay, undo, redo, ai); } coord = undo.Peek().Clone() as int[, ]; return(coord); } int[] startCoords = Array.ConvertAll(line, int.Parse); //Checks to see if the user can take a piece and if they have selected that piece. if (proxy.EnemyChecker(coord, player, enemy, startCoords, robot) == 2) { Console.WriteLine("You have a piece that can take an enemy piece, please use that piece."); throw e; } else if (proxy.EnemyChecker(coord, player, enemy, startCoords, robot) == 1) { needToJump = true; } int i = startCoords[1]; int j = startCoords[0]; //If the user puts more than 2 numbers in or selects a piece that isn't theirs. if (startCoords.Length < 2 || (coord[i, j] != player & coord[i, j] != player + 7)) { throw e; } //Call method to move the piece. secondPoint(coord, player, i, j, needToJump, enemy, replay, undo, redo, ai); passed = true; } catch { Console.WriteLine("That is an invalid co-ordinate."); } } undo.Push(coord.Clone() as int[, ]); return(coord); }
public int[,] secondPoint(int[,] coord, int player, int x, int y, bool needToJump, int enemy, Queue <int[, ]> replay, Stack <int[, ]> undo, Stack <int[, ]> redo, int ai) { //Initiate objects. BoardArray uBoard = new BoardArray(); ProxyChecker proxy = new ProxyChecker(); BoardDraw draw = new BoardDraw(); Exception e = new Exception(); //Initiate variables. bool tooFar = false; bool passed = false; int robot = 0; //Runs until the user has input a valid set of coordinates. while (!passed) { //Get users input of two numbers split by ','. Console.WriteLine("Where will you move this piece to?"); string[] line = Console.ReadLine().Split(','); //Lets the user go back and change their first coordinate. if (line[0] == "back" || line[0] == "Back") { firstPoint(coord, player, replay, undo, redo, ai); if (undo.Count > 0) { undo.Pop(); } return(coord); } try { int[] moveCoords = Array.ConvertAll(line, int.Parse); int i = moveCoords[1]; int j = moveCoords[0]; //Checks to see if the distance of the move is more than one tile. if (Math.Abs(x - i) > 1 || Math.Abs(y - j) > 1) { tooFar = true; } //If the user has to take a piece and they have not selected a distance greater than one tile. if (needToJump == true & tooFar != true) { throw e; } //If user must take a piece. if (needToJump) { //Validation for direction of jump and piece to take. if (player == 1 || coord[x, y] == 8 || coord[x, y] == 9) { if (i > 1 & j < 6) { //Up to the right on the board. if ((coord[i - 1, j + 1] == enemy || coord[i - 1, j + 1] == enemy + 7) & coord[i - 2, j + 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x + 1, y - 1] = 0; coord[x, y] = 0; passed = true; //If the user can take another piece this turn. if (proxy.EnemyChecker(coord, player, enemy, moveCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); Console.WriteLine("You can jump another piece this turn."); secondPoint(coord, player, i, j, needToJump, enemy, replay, undo, redo, ai); } return(coord); } } if (i > 1 & j > 1) { //Up to the left on the board. if ((coord[i - 1, j - 1] == enemy || coord[i - 1, j - 1] == enemy + 7) & coord[i - 2, j - 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x + 1, y + 1] = 0; coord[x, y] = 0; passed = true; //If the user can take another piece this turn. if (proxy.EnemyChecker(coord, player, enemy, moveCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); Console.WriteLine("You can jump another piece this turn."); secondPoint(coord, player, i, j, needToJump, enemy, replay, undo, redo, ai); } return(coord); } } } if (player == 2 || coord[x, y] == 8 || coord[x, y] == 9) { if (i < 6 & j > 1) { //Down to the left on the board. if ((coord[i + 1, j - 1] == enemy || coord[i + 1, j - 1] == enemy + 7) & coord[i + 2, j - 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x - 1, y + 1] = 0; coord[x, y] = 0; passed = true; //If the user can take another piece this turn. if (proxy.EnemyChecker(coord, player, enemy, moveCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); Console.WriteLine("You can jump another piece this turn."); secondPoint(coord, player, i, j, needToJump, enemy, replay, undo, redo, ai); } return(coord); } } if (i < 6 & j < 6) { //Down to the right on the board. if ((coord[i + 1, j + 1] == enemy || coord[i + 1, j + 1] == enemy + 7) & coord[i + 2, j + 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x - 1, y - 1] = 0; coord[x, y] = 0; passed = true; //If the user can take another piece this turn. if (proxy.EnemyChecker(coord, player, enemy, moveCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); Console.WriteLine("You can jump another piece this turn."); secondPoint(coord, player, i, j, needToJump, enemy, replay, undo, redo, ai); } return(coord); } } } } //If the user is not jumping a piece and only moving one tile. else { //Makes sure the jump is no longer than one tile, the tile is equal to zero and the user input only two values in. if (moveCoords.Length < 2 || coord[i, j] != 0 || tooFar) { throw e; } //Validation for which direction to move. if (player == 1 || coord[x, y] == player + 7) { if (x < 7 & y > 0) { //Down to the left on the board. if (i == x + 1 & j == y - 1) { coord[i, j] = coord[x, y]; coord[x, y] = 0; return(coord); } } if (x < 7 & y < 7) { //Down to the right on the board. if (i == x + 1 & j == y + 1) { coord[i, j] = coord[x, y]; coord[x, y] = 0; return(coord); } } } if (player == 2 || coord[i, j] == player + 7) { if (x > 0 & y < 7) { //Up to the right on the board. if (i == x - 1 & j == y + 1) { coord[i, j] = coord[x, y]; coord[x, y] = 0; return(coord); } } if (x > 0 & y > 0) { //Up to the left on the board. if (i == x - 1 & j == y - 1) { coord[i, j] = coord[x, y]; coord[x, y] = 0; return(coord); } } } } } catch { Console.WriteLine("That is an invalid co-ordinate"); } } return(coord); }
/// <summary> /// The AI used to play against the player. /// This AI uses the most simple for of linear search, moving the first piece it can. /// </summary> /// <param name="coord"></param> /// <param name="player"></param> /// <param name="replay"></param> /// <param name="undo"></param> /// <param name="redo"></param> /// <returns> The updated instance of the board after moving. </returns> public int[,] takeMove(int[,] coord, int player, Queue <int[, ]> replay, Stack <int[, ]> undo, Stack <int[, ]> redo) { //Initiate Objects. BoardArray uBoard = new BoardArray(); ProxyChecker proxy = new ProxyChecker(); BoardDraw draw = new BoardDraw(); Exception e = new Exception(); //Initiate Variables. int robot = player; int enemy; //Set enemy of the AI. if (player == 1) { enemy = 2; } else { enemy = 1; } int[] startCoords = new int[2]; //Checks to see if the AI can jump a piece. If not the enter if statement. if (proxy.EnemyChecker(coord, player, enemy, startCoords, robot) == 0) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { //Validation for which direction the piece can move. if (coord[i, j] == player || coord[i, j] == player + 7) { if (player == 1 || coord[i, j] == player + 7) { if (i < 7 & j > 0) { if (coord[i + 1, j - 1] == 0) { coord[i + 1, j - 1] = coord[i, j]; coord[i, j] = 0; undo.Push(coord.Clone() as int[, ]); return(coord); } } if (i < 7 & j < 7) { if (coord[i + 1, j + 1] == 0) { coord[i + 1, j + 1] = coord[i, j]; coord[i, j] = 0; undo.Push(coord.Clone() as int[, ]); return(coord); } } } if (player == 2 || coord[i, j] == player + 7) { if (i > 0 & j < 7) { if (coord[i - 1, j + 1] == 0) { coord[i - 1, j + 1] = coord[i, j]; coord[i, j] = 0; undo.Push(coord.Clone() as int[, ]); return(coord); } } if (i > 0 & j > 0) { if (coord[i - 1, j - 1] == 0) { coord[i - 1, j - 1] = coord[i, j]; coord[i, j] = 0; undo.Push(coord.Clone() as int[, ]); return(coord); } } } } } } } //If the AI can jump an enemy piece. else { //Validation for which piece can jump and in which direction. if (player == 1 || coord[startCoords[0], startCoords[1]] == 8 || coord[startCoords[0], startCoords[1]] == 9) { if (startCoords[0] < 6 & startCoords[1] > 1) { if ((coord[startCoords[0] + 1, startCoords[1] - 1] == enemy || coord[startCoords[0] + 1, startCoords[1] - 1] == enemy + 7) & coord[startCoords[0] + 2, startCoords[1] - 2] == 0) { coord[startCoords[0] + 2, startCoords[1] - 2] = coord[startCoords[0], startCoords[1]]; coord[startCoords[0] + 1, startCoords[1] - 1] = 0; coord[startCoords[0], startCoords[1]] = 0; startCoords[0] += 2; startCoords[1] -= 2; //Checks to see if the same piece can jump again. if (proxy.EnemyChecker(coord, player, enemy, startCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); takeMove(coord, player, replay, undo, redo); } undo.Push(coord.Clone() as int[, ]); return(coord); } } if (startCoords[0] < 6 & startCoords[1] < 6) { if ((coord[startCoords[0] + 1, startCoords[1] + 1] == enemy || coord[startCoords[0] + 1, startCoords[1] + 1] == enemy + 7) & coord[startCoords[0] + 2, startCoords[1] + 2] == 0) { coord[startCoords[0] + 2, startCoords[1] + 2] = coord[startCoords[0], startCoords[1]]; coord[startCoords[0] + 1, startCoords[1] + 1] = 0; coord[startCoords[0], startCoords[1]] = 0; startCoords[0] += 2; startCoords[1] += 2; //Checks to see if the same piece can jump again. if (proxy.EnemyChecker(coord, player, enemy, startCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); takeMove(coord, player, replay, undo, redo); } undo.Push(coord.Clone() as int[, ]); return(coord); } } } if (player == 2 || coord[startCoords[0], startCoords[1]] == 8 || coord[startCoords[0], startCoords[1]] == 9) { if (startCoords[0] > 1 & startCoords[1] < 6) { if ((coord[startCoords[0] - 1, startCoords[1] + 1] == enemy || coord[startCoords[0] - 1, startCoords[1] + 1] == enemy + 7) & coord[startCoords[0] - 2, startCoords[1] + 2] == 0) { coord[startCoords[0] - 2, startCoords[1] + 2] = coord[startCoords[0], startCoords[1]]; coord[startCoords[0] - 1, startCoords[1] + 1] = 0; coord[startCoords[0], startCoords[1]] = 0; startCoords[0] -= 2; startCoords[1] += 2; //Checks to see if the same piece can jump again. if (proxy.EnemyChecker(coord, player, enemy, startCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); takeMove(coord, player, replay, undo, redo); } undo.Push(coord.Clone() as int[, ]); return(coord); } } if (startCoords[0] > 1 & startCoords[1] > 1) { if ((coord[startCoords[0] - 1, startCoords[1] - 1] == enemy || coord[startCoords[0] - 1, startCoords[1] - 1] == enemy + 7) & coord[startCoords[0] - 2, startCoords[1] - 2] == 0) { coord[startCoords[0] - 2, startCoords[1] - 2] = coord[startCoords[0], startCoords[1]]; coord[startCoords[0] - 1, startCoords[1] - 1] = 0; coord[startCoords[0], startCoords[1]] = 0; startCoords[0] -= 2; startCoords[1] -= 2; //Checks to see if the same piece can jump again. if (proxy.EnemyChecker(coord, player, enemy, startCoords, robot) == 1) { Console.Clear(); draw.UpdateBoard(coord); replay.Enqueue(coord.Clone() as int[, ]); takeMove(coord, player, replay, undo, redo); } undo.Push(coord.Clone() as int[, ]); return(coord); } } } } return(coord); }
static void Main(string[] args) { //Initiate Objects winCondition winner = new winCondition(); BoardArray nBoard = new BoardArray(); BoardDraw draw = new BoardDraw(); Movement move = new Movement(); kingMe king = new kingMe(); Random RNG = new Random(); //Initiate Variables int playerTurn = RNG.Next(1, 2); //Change 2 to 3 int[,] board = new int[8, 8]; bool gameOver = false; int humanPlayer = 0; //Create a new board nBoard.BoardCreate(board); // while (humanPlayer < 1 || humanPlayer > 2) { Console.WriteLine("Will you be player 1 or player 2? Type 1 or 2 below to answer."); int.TryParse(Console.ReadLine(), out humanPlayer); Console.Clear(); } while (!gameOver) { if (playerTurn == 1) { draw.UpdateBoard(board); Console.WriteLine("Player 1 turn"); move.firstPoint(board, playerTurn); king.kinged(board); if (winner.wonYet(board) == 1) { for (int i = 0; i < 20; i++) { Console.WriteLine("PLAYER 1 WINS!"); } Console.Read(); gameOver = true; } Console.Clear(); playerTurn = 2; } else { draw.UpdateBoard(board); Console.WriteLine("Player 2 turn"); move.firstPoint(board, playerTurn); king.kinged(board); if (winner.wonYet(board) == 2) { for (int i = 0; i < 20; i++) { Console.WriteLine("PLAYER 2 WINS!"); } Console.Read(); gameOver = true; } Console.Clear(); playerTurn = 1; } } }
public int[,] secondPoint(int[,] coord, int player, int x, int y, bool needToJump, int enemy) { BoardArray uBoard = new BoardArray(); ProxyChecker proxy = new ProxyChecker(); BoardDraw draw = new BoardDraw(); Exception e = new Exception(); bool passed = false; while (!passed) { Console.WriteLine("Where will you move this piece to?"); string[] line = Console.ReadLine().Split(','); bool tooFar = false; try { int[] moveCoords = Array.ConvertAll(line, int.Parse); int i = moveCoords[1]; int j = moveCoords[0]; if (Math.Abs(x - i) > 1 || Math.Abs(y - j) > 1) { tooFar = true; } if (needToJump == true & tooFar != true) { throw e; } if (player == 1 || coord[x, y] == 8 || coord[x, y] == 9) { if (i > 1 & j < 6) { if ((coord[i - 1, j + 1] == enemy || coord[i - 1, j + 1] == enemy + 7) & coord[i - 2, j + 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x + 1, y - 1] = 0; coord[x, y] = 0; passed = true; if (proxy.EnemyChecker(coord, player, enemy, moveCoords) == 1) { Console.WriteLine("You can jump another piece this turn."); draw.UpdateBoard(coord); secondPoint(coord, player, i, j, needToJump, enemy); } return(coord); } } if (i > 1 & j > 1) { if ((coord[i - 1, j - 1] == enemy || coord[i - 1, j - 1] == enemy + 7) & coord[i - 2, j - 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x + 1, y + 1] = 0; coord[x, y] = 0; passed = true; if (proxy.EnemyChecker(coord, player, enemy, moveCoords) == 1) { Console.WriteLine("You can jump another piece this turn."); firstPoint(coord, player); secondPoint(coord, player, i, j, needToJump, enemy); } return(coord); } } } else if (player == 2 || coord[x, y] == 8 || coord[x, y] == 9) { if (i < 6 & j > 1) { if ((coord[i + 1, j - 1] == enemy || coord[i + 1, j - 1] == enemy + 7) & coord[i + 2, j - 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x - 1, y + 1] = 0; coord[x, y] = 0; passed = true; if (proxy.EnemyChecker(coord, player, enemy, moveCoords) == 1) { Console.WriteLine("You can jump another piece this turn."); firstPoint(coord, player); secondPoint(coord, player, i, j, needToJump, enemy); } return(coord); } } if (i < 6 & j < 6) { if ((coord[i + 1, j + 1] == enemy || coord[i + 1, j + 1] == enemy + 7) & coord[i + 2, j + 2] == coord[x, y]) { coord[i, j] = coord[x, y]; coord[x - 1, y - 1] = 0; coord[x, y] = 0; passed = true; if (proxy.EnemyChecker(coord, player, enemy, moveCoords) == 1) { Console.WriteLine("You can jump another piece this turn."); firstPoint(coord, player); secondPoint(coord, player, i, j, needToJump, enemy); } return(coord); } } } if (moveCoords.Length < 2 || coord[i, j] != 0 || tooFar) { throw e; } coord[i, j] = coord[x, y]; coord[x, y] = 0; passed = true; } catch { Console.WriteLine("That is an invalid co-ordinate"); } } return(coord); }