using System.Collections.Generic;
using System.Threading.Tasks;
public static void Main(string[] args)
public static void MainMenu() {
string[,] xOGrid = new string[,] { { " ", " ", " " }, { " ", " ", " " }, { " ", " ", " " } };
string[,] fourGrid = new string[,] { { " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " " } };
string[,] playerOneShipGrid = new string[10, 10];
string[,] playerTwoShipGrid = new string[10, 10];
string[,] playerOneMarkGrid = new string[10, 10];
string[,] playerTwoMarkGrid = new string[10, 10];
Console.Write("Welcome to The Games Pack! We have naughts and crosses, connect 4, and battleship.\nType XO or Naughts and Crosses, 4 or Connect 4, S or Battleship to play the respective game.\nYou can also type H or Help and E or Exit to get help and exit, respectively.\nWhat game do you want to play?: ");
game = Console.ReadLine().ToLower();
if (game == "xo" || game == "naughts and crosses") {
XOFourMarkChoose(xOGrid, player, "X");
} else if (game == "4" || game == "connect 4") {
XOFourMarkChoose(fourGrid, player, "Y");
} else if (game == "s" || game == "battleship") {
playerOneShipGrid = ShipFillBoard(playerOneShipGrid);
playerTwoShipGrid = ShipFillBoard(playerTwoShipGrid);
playerOneMarkGrid = ShipFillBoard(playerOneMarkGrid);
playerTwoMarkGrid = ShipFillBoard(playerTwoMarkGrid);
ShipPlacementControl(playerOneShipGrid, playerTwoShipGrid, playerOneMarkGrid, playerTwoMarkGrid, player);
} else if (game == "h" || game == "help") {
} else if (game == "e" || game == "exit") {
} else if (game == "black" || game == "white") {
public static int ColourChange(string colour) {
Console.ForegroundColor = ConsoleColor.Black;
Console.BackgroundColor = ConsoleColor.White;
} else if (colour == "black") {
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.Black;
public static void Help() {
Console.WriteLine("When asked what game you want to play, the following are valid inputs:\nXO, Naughts and Crosses Will let you play naughts and crosses (also known as tic-tac-toe). How to play on page 2.\n4, Connect 4 Will let you play connect 4. How to play on page 3.\nS, Battleship Will let you play battleship. How to play on page 4.\nH, Help Opens the help menu. You are reading this now.\nE, Exit Exits the program. The close button in the top right still works normally.\nBlack Changes console colours to white on black.\nWhite Changes console colours to black on white.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nPage 1/4\nPress Enter to continue.");
Console.WriteLine("Playing naughts and crosses:\nNaughts and crosses is played on a 3x3 grid, as seen below.\n | | \n-+-+-\n | | \n-+-+-\n | | \nThe aim of the game is to have 3 of your mark lined up in a row, column, or diagonally.\nThis is done by taking turns placing your mark (X or O) on an empty space on the grid.\nTo place your mark, when it is your turn, type a coordinate in the following format: x,y\nFor example, typing 3,2 would place the X and 1,3 would place the O as shown below:\n | | \n-+-+-\n | |X\n-+-+-\nO| | \nYou can also have spaces in your coordinate, for example, typing 3 , 2 would still put a mark where the X is.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nPage 2/4\nPress Enter to continue.");
Console.WriteLine("Playing connect 4:\nConnect 4 is played on a 7x6 grid, as seen in the placement example.\nThe aim of the game is to have 4 of your colour lined up in a row, column, or diagonally.\nThis is done by taking turns placing your coloured counter (yellow (Y) or red (R)) into an column that isn't full.\nTo place your counter, when it is your turn, type a column number in the following format: x\nYour counter will then fall down into the lowest empty slot in the column.\nFor example, if yellow is placed in column 1, then red in 1, then yellow in 3, then the grid would look like the one below:\n| | | | | | | |\n+-+-+-+-+-+-+-+\n| | | | | | | |\n+-+-+-+-+-+-+-+\n| | | | | | | |\n+-+-+-+-+-+-+-+\n| | | | | | | |\n+-+-+-+-+-+-+-+\n|R| | | | | | |\n+-+-+-+-+-+-+-+\n|Y| |Y| | | | |\n+-+-+-+-+-+-+-+\n\n\n\n\n\n\n\n\n\n\n\n\n\nPage 3/4\nPress Enter to continue.");
Console.WriteLine("Playing battleship:\nBattleship is played on a 10x10 grid, as seen below.\nThe aim of the game to to sink all your opponent's ships.\nThis is done by taking turns typing in a coordinate, which will fire a 'shot' at your opponent's grid.\nThis will then record a hit or a miss on your marking grid and your opponent's ship grid.\nYou will then be give 5 seconds to swap over, while the ships you have sunk and your most recent shot's hit/miss are displayed.\nWhen firing a shot/placing ships, the coordinate format is *letter**number*. Capitalization doesn't matter.\nWhen placing ships, the coordinate is the top/leftmost point on the ship.\nA grid with a carrier placed vertically at B3 pictured below:\n 1 2 3 4 5 6 7 8 9 10\n +-+-+-+-+-+-+-+-+-+-+\nA| | | | | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nB| | |C| | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nC| | |C| | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nD| | |C| | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nE| | |C| | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nF| | |C| | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nG| | | | | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nH| | | | | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nI| | | | | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\nJ| | | | | | | | | | |\n +-+-+-+-+-+-+-+-+-+-+\n\nPage 4/4\nPress Enter to continue.");
public static void XOControl(string[,] xOGrid, int player, int playerIsMain) {
string[] coordinate = new string[2];
int[] coordinateNumeric = new int[2];
player = AllPlayerChange(player);
if (player == playerIsMain) {
Console.WriteLine("{0}|{1}|{2}\n-+-+-\n{3}|{4}|{5}\n-+-+-\n{6}|{7}|{8}\nPlayer {9}, place your mark: ", xOGrid[0,0], xOGrid[0,1], xOGrid[0,2], xOGrid[1, 0], xOGrid[1, 1], xOGrid[1, 2], xOGrid[2, 0], xOGrid[2, 1], xOGrid[2, 2], player);
coordinate = Console.ReadLine().Trim().Split(',');
coordinateNumeric[0] = Convert.ToInt32(coordinate[1]) - 1;
coordinateNumeric[1] = Convert.ToInt32(coordinate[0]) - 1;
if (coordinateNumeric[0] < 0 || coordinateNumeric[0] > 2 || coordinateNumeric[1] < 0 || coordinateNumeric[1] > 2 || xOGrid[coordinateNumeric[0], coordinateNumeric[1]] != " ") {
XOControl(xOGrid, player, playerIsMain);
xOGrid[coordinateNumeric[0], coordinateNumeric[1]] = playerMark;
XOWinCheck(xOGrid, player, playerIsMain, coordinateNumeric);
public static void XOWinCheck(string[,] xOGrid, int player, int playerIsMain, int[] coordinateNumeric) {
if (xOGrid[0, 0] != " " && xOGrid[0, 1] != " " && xOGrid[0, 2] != " " && xOGrid[1, 0] != " " && xOGrid[1, 1] != " " && xOGrid[1, 2] != " " && xOGrid[2, 0] != " " && xOGrid[2, 1] != " " && xOGrid[2, 2] != " ") {
if (xOGrid[coordinateNumeric[0], 0] == xOGrid[coordinateNumeric[0], 1] && xOGrid[coordinateNumeric[0], 1] == xOGrid[coordinateNumeric[0], 2]) {
} else if (xOGrid[0, coordinateNumeric[1]] == xOGrid[1, coordinateNumeric[1]] && xOGrid[1, coordinateNumeric[1]] == xOGrid[2, coordinateNumeric[1]]) {
} else if (xOGrid[0, 0] == xOGrid[1, 1] && xOGrid[1, 1] == xOGrid[2, 2] && xOGrid[1, 1] != " ") {
} else if (xOGrid[0, 2] == xOGrid[1, 1] && xOGrid[1, 1] == xOGrid[2, 0] && xOGrid[1, 1] != " ") {
XOControl(xOGrid, player, playerIsMain);
} else if (gameState == 1) {
Console.WriteLine("{0}|{1}|{2}\n-+-+-\n{3}|{4}|{5}\n-+-+-\n{6}|{7}|{8}\nPlayer {9} wins! Press Enter to return to the menu.", xOGrid[0, 0], xOGrid[0, 1], xOGrid[0, 2], xOGrid[1, 0], xOGrid[1, 1], xOGrid[1, 2], xOGrid[2, 0], xOGrid[2, 1], xOGrid[2, 2], player);
Console.WriteLine("{0}|{1}|{2}\n-+-+-\n{3}|{4}|{5}\n-+-+-\n{6}|{7}|{8}\nThe game is tied! Press Enter to return to the menu.", xOGrid[0, 0], xOGrid[0, 1], xOGrid[0, 2], xOGrid[1, 0], xOGrid[1, 1], xOGrid[1, 2], xOGrid[2, 0], xOGrid[2, 1], xOGrid[2, 2]);
public static void FourControl(string[,] fourGrid, int player, int playerIsMain) {
int coordinate, gravity = 0;
int[] coordinateNumeric = new int[2];
player = AllPlayerChange(player);
if (player == playerIsMain) {
FourBoardWrite(fourGrid);
Console.WriteLine("Player {0}, place your counter: ", player);
coordinate = Convert.ToInt32(Console.ReadLine()) - 1;
if (coordinate < 0 || coordinate > 6 || fourGrid[coordinate, 0] != " ") {
FourControl(fourGrid, player, playerIsMain);
for (int i = 0; gravity == 0; i++) {
if (i == 5 && fourGrid[coordinate, i] == " ") {
fourGrid[coordinate, i] = playerMark;
} else if (fourGrid[coordinate, i] != " " || i == 5) {
fourGrid[coordinate, i - 1] = playerMark;
FourWinCheckControl(fourGrid, player, playerIsMain, coordinateNumeric);
public static void FourWinCheckControl(string[,] fourGrid, int player, int playerIsMain, int[] coordinateNumeric) {
int filledSpaces = 0, gameState = 0;
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 6; j++) {
if (fourGrid[i, j] != " ") {
if (filledSpaces == 42) {
gameState = FourWinChecker(fourGrid, gameState, 4, 6, -1, 1, 0);
gameState = FourWinChecker(fourGrid, gameState, 7, 3, -1, 0, 1);
gameState = FourWinChecker(fourGrid, gameState, 4, 3, -1, 1, 1);
gameState = FourWinChecker(fourGrid, gameState, 7, 3, 2, -1, 1);
FourControl(fourGrid, player, playerIsMain);
} else if (gameState == 1) {
FourBoardWrite(fourGrid);
Console.WriteLine("Player {0} wins! Press Enter to return to the menu.", player);
FourBoardWrite(fourGrid);
Console.WriteLine("The game is tied! Press Enter to return to the menu.");
public static int FourWinChecker(string[,] fourGrid, int gameState, int xLimit, int yLimit, int backLimit, int xMod, int yMod) {
for (int i = 0; i < xLimit; i++) {
for (int j = 0; j < yLimit; j++) {
if (fourGrid[i, j] != " " && fourGrid[xMod + i, yMod + j] == fourGrid[i, j] && fourGrid[i, j] == fourGrid[2 * xMod + i, 2 * yMod + j] && fourGrid[i, j] == fourGrid[3 * xMod + i, 3 * yMod + j]) {
public static int FourBoardWrite(string[,] fourGrid) {
for (int i = 0; i < 6; i++)
for (int j = 0; j < 7; j++)
if (fourGrid[j, i] == "Y") {
Console.ForegroundColor = ConsoleColor.DarkYellow;
} else if (fourGrid[j, i] == "R") {
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(fourGrid[j, i]);
if (Console.BackgroundColor == ConsoleColor.Black) {
Console.ForegroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Black;
Console.WriteLine("|\n+-+-+-+-+-+-+-+");
public static void XOFourMarkChoose(string[,] xOFourGrid, int player, string mainMark) {
Console.Write("Which player is {0}? (Type 1 or 2): ", mainMark);
playerIsMain = Convert.ToInt32(Console.ReadLine());
XOControl(xOFourGrid, player, playerIsMain);
FourControl(xOFourGrid, player, playerIsMain);
public static void ShipPlacementControl(string[,] playerOneShipGrid, string[,] playerTwoShipGrid, string[,] playerOneMarkGrid, string[,] playerTwoMarkGrid, int player) {
for (int i = 5; i != 0; i--) {
Console.WriteLine("Player 1 will be placing their ships in {0} seconds, player 2, look away!", i);
playerOneShipGrid = ShipPlacerAdjust(playerOneShipGrid, player);
for (int i = 5; i != 0; i--) {
Console.WriteLine("Player 2 will be placing their ships in {0} seconds, player 1, look away!", i);
playerTwoShipGrid = ShipPlacerAdjust(playerTwoShipGrid, player);
for (int i = 5; i != 0; i--) {
Console.WriteLine("The game will start with player one in {0} seconds, player 2, look away!", i);
player = AllPlayerChange(player);
ShipBoardControlAdjust(playerOneShipGrid, playerTwoShipGrid, playerOneMarkGrid, playerTwoMarkGrid, player);
public static string[,] ShipPlacerAdjust(string[,] shipGrid, int player) {
shipGrid = ShipPlacer(shipGrid, "carrier", 5, "C");
shipGrid = ShipPlacer(shipGrid, "battleship", 4, "B");
shipGrid = ShipPlacer(shipGrid, "destroyer", 3, "D");
shipGrid = ShipPlacer(shipGrid, "submarine", 3, "S");
shipGrid = ShipPlacer(shipGrid, "patrol boat", 2, "P");
public static string[,] ShipPlacer(string[,] shipGrid, string ship, int shipLength, string shipShort)
string coordinateStorage, direction;
int[] coordinate = new int[2];
int emptyCheck = 0, successfulPlacement = 0, xPlaceCap, xPlaceMod, yPlaceCap, yPlaceMod;
ShipBoardWrite(shipGrid);
Console.Write("Do you want to place the {0} ({1} spaces) horizontally or vertically? (Type H or V): ", ship, shipLength);
direction = Console.ReadLine().ToLower();
Console.Write("Where do you want to place the {0} ({1} spaces)? (Type coordinate): ", ship, shipLength);
coordinateStorage = Console.ReadLine().ToLower();
coordinate[0] = ShipLetterToNumber(coordinateStorage.Remove(1));
coordinate[1] = Convert.ToInt32(coordinateStorage.Remove(0, 1)) - 1;
yPlaceCap = 11 - shipLength;
xPlaceCap = 11 - shipLength;
if (coordinate[1] > -1 && coordinate[1] < xPlaceCap && coordinate[0] > -1 && coordinate[0] < yPlaceCap) {
for (int i = 0; i < shipLength; i++) {
if (shipGrid[i * xPlaceMod + coordinate[1], i * yPlaceMod + coordinate[0]] == " ") {
if (emptyCheck == shipLength) {
for (int i = 0; i < shipLength; i++) {
shipGrid[i * xPlaceMod + coordinate[1], i * yPlaceMod + coordinate[0]] = shipShort;
} while (successfulPlacement == 0);
public static void ShipBoardControlAdjust(string[,] playerOneShipGrid, string[,] playerTwoShipGrid, string[,] playerOneMarkGrid, string[,] playerTwoMarkGrid, int player) {
player = AllPlayerChange(player);
ShipBoardControl(playerOneShipGrid, playerTwoShipGrid, playerOneMarkGrid, playerTwoMarkGrid, player, playerOneShipGrid, playerOneMarkGrid, playerTwoShipGrid);
ShipBoardControl(playerOneShipGrid, playerTwoShipGrid, playerOneMarkGrid, playerTwoMarkGrid, player, playerTwoShipGrid, playerTwoMarkGrid, playerOneShipGrid);
public static void ShipBoardControl(string[,] playerOneShipGrid, string[,] playerTwoShipGrid, string[,] playerOneMarkGrid, string[,] playerTwoMarkGrid, int player, string[,] activeShipGrid, string[,] activeMarkGrid, string[,] secondaryShipGrid)
string coordinateStorage, hitMessage = "";
int[] coordinate = new int[2];
int carrierSpaces = 0, battleSpaces = 0, destroySpaces = 0, subSpaces = 0, patrolSpaces = 0;
ShipBoardWrite(activeMarkGrid);
Console.WriteLine("Tracking grid ^");
ShipBoardWrite(activeShipGrid);
Console.WriteLine("Ship grid ^\nWhat coordinate do you want to fire your shot at?: ");
coordinateStorage = Console.ReadLine().ToLower();
coordinate[0] = ShipLetterToNumber(coordinateStorage.Remove(1));
coordinate[1] = Convert.ToInt32(coordinateStorage.Remove(0, 1)) - 1;
if (coordinate[1] > -1 && coordinate[1] < 10 && coordinate[0] > -1 && coordinate[0] < 10 && activeMarkGrid[coordinate[1], coordinate[0]] == " ") {
if (secondaryShipGrid[coordinate[1], coordinate[0]] != " ") {
activeMarkGrid[coordinate[1], coordinate[0]] = "*";
secondaryShipGrid[coordinate[1], coordinate[0]] = "*";
activeMarkGrid[coordinate[1], coordinate[0]] = "~";
secondaryShipGrid[coordinate[1], coordinate[0]] = "~";
ShipBoardControl(playerOneShipGrid, playerTwoShipGrid, playerOneMarkGrid, playerTwoMarkGrid, player, activeShipGrid, activeMarkGrid, secondaryShipGrid);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (secondaryShipGrid[j, i] == "C") {
} else if (secondaryShipGrid[j, i] == "B") {
} else if (secondaryShipGrid[j, i] == "D") {
} else if (secondaryShipGrid[j, i] == "S") {
} else if (secondaryShipGrid[j, i] == "P") {
if (carrierSpaces == 0 && battleSpaces == 0 && destroySpaces == 0 && subSpaces == 0 && patrolSpaces == 0) {
ShipWinMessage(activeShipGrid, secondaryShipGrid, player);
ShipWinMessage(secondaryShipGrid, activeShipGrid, player);
for (int i = 5; i != 0; i--) {
Console.WriteLine("It's about to be player {0}'s turn in {1} secs, swap over.\nPlayer {2} {3} at {4}", AllPlayerChange(player), i, player, hitMessage, coordinateStorage.ToUpper());
if (carrierSpaces == 0) {
Console.WriteLine("Player {0} has sunk player {1}'s carrier.", player, AllPlayerChange(player));
Console.WriteLine("Player {0} has sunk player {1}'s battleship.", player, AllPlayerChange(player));
if (destroySpaces == 0) {
Console.WriteLine("Player {0} has sunk player {1}'s destroyer.", player, AllPlayerChange(player));
Console.WriteLine("Player {0} has sunk player {1}'s submarine.", player, AllPlayerChange(player));
Console.WriteLine("Player {0} has sunk player {1}'s patrol boat.", player, AllPlayerChange(player));
ShipBoardControlAdjust(activeShipGrid, secondaryShipGrid, activeMarkGrid, playerTwoMarkGrid, player);
ShipBoardControlAdjust(secondaryShipGrid, activeShipGrid, playerOneMarkGrid, activeMarkGrid, player);
public static void ShipWinMessage(string[,] playerOneShipGrid, string[,] playerTwoShipGrid, int player)
ShipBoardWrite(playerOneShipGrid);
Console.WriteLine("Player 1's grid ^");
ShipBoardWrite(playerTwoShipGrid);
Console.WriteLine("Player 2's grid ^\nPlayer {0} wins! Press enter to return to the menu.", player);
public static int ShipBoardWrite(string[,] allGrid) {
string[] convertArray = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
Console.WriteLine(" 1 2 3 4 5 6 7 8 9 10\n +-+-+-+-+-+-+-+-+-+-+");
for (int i = 0; i < 10; i++) {
Console.Write("{0}|", convertArray[i]);
for (int j = 0; j < 10; j++) {
if (allGrid[j, i] == "*") {
Console.ForegroundColor = ConsoleColor.Red;
} else if (allGrid[j, i] == "~") {
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write(allGrid[j, i]);
if (Console.BackgroundColor == ConsoleColor.Black) {
Console.ForegroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Black;
Console.WriteLine("\n +-+-+-+-+-+-+-+-+-+-+");
public static string[,] ShipFillBoard(string[,] grid) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
public static int ShipLetterToNumber(string letter)
string[] convertArray = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
for (int i = 0; i < 10; i++) {
if (convertArray[i] == letter) {
number = Convert.ToInt32(convertArray[i + 10]);
public static int AllPlayerChange(int player)