Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Runtime.InteropServices;
- namespace TicTacToeFP;
- public partial class TicTacToe
- {
- /*
- ************************************************************
- C# CONSOLE APPLICATION
- THIS PROJECT IS ABOUT A
- TIC TAC TOE GAME
- FOR THIS PROJECT IS USED FUNCTIONAL PROGRAMMING (FP)
- ************************************************************
- */
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /*
- ************************************************************
- START OF THE PROJECT
- ************************************************************
- */
- /*
- ************************************************************
- THIS PART OF THE CODE IS TO MAKE
- THE CONSOLE WINDOW IN FULL SCREEN AUTOMATICALLY,
- WHEN CALLED
- ************************************************************
- */
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- [LibraryImport("kernel32.dll")]
- private static partial IntPtr GetConsoleWindow();
- private static readonly IntPtr ThisCon = GetConsoleWindow();
- [LibraryImport("user32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static partial bool ShowWindow(IntPtr hWnd, int nCmdShow);
- private const int MAXIMIZE = 3;
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /*
- ************************************************************
- THIS PART OF THE CODE IS TO HELP
- THE "WriteCentered" METHOD TO CENTER THE TEXT
- IN THE MIDDLE OF THE CONSOLE
- ************************************************************
- */
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- [LibraryImport("kernel32.dll")]
- private static partial IntPtr GetStdHandle(int nStdHandle);
- [StructLayout(LayoutKind.Sequential)]
- struct COORD
- {
- public short X;
- public short Y;
- }
- [LibraryImport("kernel32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static partial bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
- [StructLayout(LayoutKind.Sequential)]
- struct CONSOLE_SCREEN_BUFFER_INFO
- {
- public COORD dwSize;
- public COORD dwCursorPosition;
- public ushort wAttributes;
- public SMALL_RECT srWindow;
- public COORD dwMaximumWindowSize;
- }
- [StructLayout(LayoutKind.Sequential)]
- struct SMALL_RECT
- {
- public short Left;
- public short Top;
- public short Right;
- public short Bottom;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- static void Main(string[] args)
- {
- ShowWindow(ThisCon, MAXIMIZE); // FULL SCREEN
- Console.CursorVisible = false; // TURN THE VISIBILITY OF THE CURSOR TO OFF
- MainMenu();
- }
- /*
- ************************************************************
- CREATING A METHOD,
- WHICH DOESN'T TAKE ANY PARAMETERS
- AND TAKES METHODS AS ELEMENTS,
- WHICH DON'T RETURN ANYTHING
- ************************************************************
- */
- delegate void menuOption();
- /*
- ************************************************************
- USING THE CREATED METHOD TO CREATE AN ARRAY
- ************************************************************
- */
- static menuOption[] mainMenuOptions = { GameStart, ExitGame };
- /*
- ************************************************************
- METHOD TO DISPLAY THE MAIN MENU
- ************************************************************
- */
- static void MainMenu()
- {
- string[] mainMenu = { "Start Game", "Exit" };
- int pointer = 0;
- bool arrowVisible = true;
- while (true)
- {
- Console.Clear();
- Console.ForegroundColor = ConsoleColor.Red;
- for (int i = 0; i < 16; i++)
- {
- Console.WriteLine();
- }
- WriteCentered("Tic Tac Toe");
- for (int i = 0; i < 3; i++)
- {
- Console.WriteLine();
- }
- WriteCentered("Main Menu");
- for (int i = 0; i < 3; i++)
- {
- Console.WriteLine();
- }
- for (int i = 0; i < mainMenu.Length; i++)
- {
- if (i == pointer)
- {
- Console.ForegroundColor = ConsoleColor.Green;
- if (arrowVisible)
- {
- WriteCentered("-> " + mainMenu[i]);
- Console.WriteLine();
- arrowVisible = false;
- }
- else
- {
- WriteCentered(" ");
- Console.WriteLine();
- arrowVisible = true;
- }
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.Red;
- WriteCentered(mainMenu[i]);
- Console.WriteLine();
- }
- }
- if (Console.KeyAvailable)
- {
- ConsoleKeyInfo inputKey = Console.ReadKey(true);
- bool upKeyState = inputKey.Key == ConsoleKey.UpArrow;
- if (upKeyState)
- {
- pointer--;
- if (pointer == -1)
- {
- pointer = mainMenu.Length - 1;
- }
- continue;
- }
- bool downKeyState = inputKey.Key == ConsoleKey.DownArrow;
- if (downKeyState)
- {
- pointer++;
- if (pointer == mainMenu.Length)
- {
- pointer = 0;
- }
- continue;
- }
- bool returnKeyState = inputKey.Key == ConsoleKey.Enter;
- if (returnKeyState)
- {
- mainMenuOptions[pointer]();
- }
- }
- Thread.Sleep(200);
- }
- }
- /*
- ************************************************************
- METHOD TO CALL THE NEEDED METHODS,
- SO THE PLAYER / PLAYERS CAN PLAY
- ************************************************************
- */
- static void GameStart()
- {
- string[] names = new string [2];
- string choice = ChoiceMenu();
- if (choice == "yes")
- {
- char[] marks = { 'X', 'O' };
- Console.Clear();
- for (int i = 0; i < 20; i++)
- {
- Console.WriteLine();
- }
- for (int i = 0; i < names.Length; i++)
- {
- Console.WriteLine();
- WriteCentered("Enter a name for Player " + (i + 1).ToString() + ", who will be with the symbol '" + marks[i] + "': ");
- names[i] = EnterName();
- }
- }
- else if (choice == "no")
- {
- Console.ForegroundColor = ConsoleColor.Red;
- names[0] = "Player 1";
- names[1] = "Player 2";
- }
- GamePlay(names);
- }
- /*
- ************************************************************
- METHOD TO EXIT THE GAME
- ************************************************************
- */
- static void ExitGame()
- {
- Console.Clear();
- Console.ForegroundColor = ConsoleColor.Red;
- Environment.Exit(0);
- }
- /*
- ************************************************************
- CREATING A METHOD,
- WHICH DOESN'T TAKE ANY PARAMETERS
- AND TAKES METHODS AS ELEMENTS,
- WHICH RETURN A STRING
- ************************************************************
- */
- delegate string ChoiceOption();
- /*
- ************************************************************
- USING THE CREATED METHOD TO CREATE AN ARRAY
- ************************************************************
- */
- static ChoiceOption[] choiceMenuOptions = { ChoiceIsYes, ChoiceIsNo };
- /*
- ************************************************************
- METHOD TO DISPLAY THE CHOICE MENU
- ************************************************************
- */
- static string ChoiceMenu()
- {
- string[] choiceMenu = { "Yes", "No" };
- int pointer = 0;
- bool arrowVisible = true;
- while (true)
- {
- Console.Clear();
- Console.ForegroundColor = ConsoleColor.Red;
- for (int i = 0; i < 20; i++)
- {
- Console.WriteLine();
- }
- WriteCentered("Do you want to change the names from \"Player 1\" and \"Player 2\" to something different?");
- for (int i = 0; i < 3; i++)
- {
- Console.WriteLine();
- }
- for (int i = 0; i < choiceMenu.Length; i++)
- {
- if (i == pointer)
- {
- Console.ForegroundColor = ConsoleColor.Green;
- if (arrowVisible)
- {
- WriteCentered("-> " + choiceMenu[i]);
- Console.WriteLine();
- arrowVisible = false;
- }
- else
- {
- WriteCentered(" ");
- Console.WriteLine();
- arrowVisible = true;
- }
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.Red;
- WriteCentered(choiceMenu[i]);
- Console.WriteLine();
- }
- }
- if (Console.KeyAvailable)
- {
- ConsoleKeyInfo inputKey = Console.ReadKey(true);
- bool upKeyState = inputKey.Key == ConsoleKey.UpArrow;
- if (upKeyState)
- {
- pointer--;
- if (pointer == -1)
- {
- pointer = choiceMenu.Length - 1;
- }
- continue;
- }
- bool downKeyState = inputKey.Key == ConsoleKey.DownArrow;
- if (downKeyState)
- {
- pointer++;
- if (pointer == choiceMenu.Length)
- {
- pointer = 0;
- }
- continue;
- }
- bool returnKeyState = inputKey.Key == ConsoleKey.Enter;
- if (returnKeyState)
- {
- return choiceMenuOptions[pointer]();
- }
- BackToMainMenu(inputKey);
- }
- Thread.Sleep(200);
- }
- }
- /*
- ************************************************************
- METHOD TO RETURN "yes",
- SO THE USER CAN INPUT DIFFERENT NAMES
- ************************************************************
- */
- static string ChoiceIsYes()
- {
- return "yes";
- }
- /*
- ************************************************************
- METHOD TO RETURN "no",
- SO THE NAMES WON'T BE CHANGED
- ************************************************************
- */
- static string ChoiceIsNo()
- {
- return "no";
- }
- /*
- ************************************************************
- METHOD TO INPUT A NAME
- ************************************************************
- */
- static string EnterName()
- {
- string name = Console.ReadLine();
- return name;
- }
- /*
- ************************************************************
- METHOD TO ALLOW THE PLAYER / PLAYERS TO PLAY
- ************************************************************
- */
- static void GamePlay(string[] names)
- {
- string[] square = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
- int sizeOfTheArray = square.Length;
- int player = 1, gameState = -1;
- char mark;
- while ( (gameState == -1) && (player != 6) )
- {
- player = (player % 2 == 1) ? 1 : 2;
- mark = (player == 1) ? 'X' : 'O';
- Board(square, names, sizeOfTheArray);
- WriteCentered("It's " + names[player - 1] + "'s turn.");
- player = ActionChoice(square, player, mark, sizeOfTheArray);
- gameState = GameState(square);
- }
- if ( (gameState == 0) || (gameState == 1) )
- {
- Board(square, names, sizeOfTheArray);
- if (gameState == 1)
- {
- int index = (--player == 1) ? 0 : 1;
- WriteCentered("==> " + names[index] + " won! <==");
- }
- else if (gameState == 0)
- {
- WriteCentered("==> Game draw <==");
- }
- for (int i = 0; i < 2; i++)
- {
- Console.WriteLine();
- }
- PressEnterToContinue();
- }
- }
- /*
- ************************************************************
- METHOD TO DRAW THE TIC TAC TOE BOARD
- WITH THE PLAYERS MARK
- ************************************************************
- */
- static void Board(string[] square, string[] names, int size)
- {
- Console.Clear();
- for (int i = 0; i < 14; i++)
- {
- Console.WriteLine();
- }
- WriteCentered("Tic Tac Toe");
- for (int i = 0; i < 4; i++)
- {
- Console.WriteLine();
- }
- WriteCentered(names[0] + " (X) - " + names[1] + " (O)");
- for (int i = 0; i < 4; i++)
- {
- Console.WriteLine();
- }
- WriteCentered(" | | ");
- Console.WriteLine();
- for (int i = 0; i < size - 2; i += 3)
- {
- WriteCentered(square[i] + " | " + square[i + 1] + " | " + square[i + 2]);
- Console.WriteLine();
- if (i != 6)
- {
- WriteCentered("_____|_____|_____");
- Console.WriteLine();
- WriteCentered(" | | ");
- Console.WriteLine();
- }
- }
- WriteCentered(" | | ");
- for (int i = 0; i < 4; i++)
- {
- Console.WriteLine();
- }
- }
- /*
- ************************************************************
- METHOD TO ALLOW THE PLAYERS TO PRESS
- A NUMBER 1 TO 9 AND CHANGE IT TO EITHER 'X' OR 'O'
- "R" / "r" TO RESTART THE GAME
- "Q" / "q" TO GO BACK TO THE MAIN MENU
- ************************************************************
- */
- static int ActionChoice(string[] square, int player, char mark, int size)
- {
- while (true)
- {
- ConsoleKeyInfo inputKey = Console.ReadKey(true);
- int key = inputKey.KeyChar - '0';
- if ( ( (key > 0) && (key < 10) ) && (square[key - 1] == key.ToString()))
- {
- CheckActionChoice(square, mark, key, size);
- player++;
- break;
- }
- else if ( (inputKey.KeyChar == 'R') || (inputKey.KeyChar == 'r') ) // Check for 'R' or 'r' key press
- {
- for (int i = 0; i < size; i++)
- {
- if ( (square[i] == "X") || (square[i] == "O") )
- {
- square[i] = (i + 1).ToString();
- }
- }
- player = 1;
- break;
- }
- else if ( (inputKey.KeyChar == 'Q') || (inputKey.KeyChar == 'q') ) // Check for 'Q' or 'q' key press
- {
- player = 6; // It takes this value, so in the loop in the GamePlay function can break and go back to the Main Menu
- break;
- }
- else
- {
- Console.Clear();
- for (int i = 0; i < 20; i++)
- {
- Console.WriteLine();
- }
- WriteCentered("Invalid move!");
- for (int i = 0; i < 4; i++)
- {
- Console.WriteLine();
- }
- PressEnterToContinue();
- break;
- }
- }
- return player;
- }
- /*
- ************************************************************
- METHOD TO CHECK THE PRESSED NUMBER,
- IF IT CAN BE CHANGED TO EITHER
- 'X' OT 'O'
- ************************************************************
- */
- static void CheckActionChoice(string[] square, char mark, int key, int size)
- {
- for (int i = 0; i < size; i++)
- {
- if (key.ToString() == square[i])
- {
- square[i] = mark.ToString();
- break;
- }
- }
- }
- /*
- ************************************************************
- METHOD TO RETURN THE GAME STATUS:
- 1 ==> GAME IS OVER WITH A RESULT
- -1 ==> GAME IS IN PROGRESS
- O ==> GAME IS OVER AND NO RESULT
- ************************************************************
- */
- static int GameState(string[] square)
- {
- if ( (square[0] == square[1]) && (square[1] == square[2]) )
- {
- return 1;
- }
- else if ( (square[3] == square[4]) && (square[4] == square[5]) )
- {
- return 1;
- }
- else if ( (square[6] == square[7]) && (square[7] == square[8]) )
- {
- return 1;
- }
- else if ( (square[0] == square[3]) && (square[3] == square[6]) )
- {
- return 1;
- }
- else if ( (square[1] == square[4]) && (square[4] == square[7]) )
- {
- return 1;
- }
- else if ( (square[2] == square[5]) && (square[5] == square[8]) )
- {
- return 1;
- }
- else if ( (square[0] == square[4]) && (square[4] == square[8]) )
- {
- return 1;
- }
- else if ( (square[2] == square[4]) && (square[4] == square[6]) )
- {
- return 1;
- }
- else if ( (square[0] != "1") && (square[1] != "2") && (square[2] != "3") &&
- (square[3] != "4") && (square[4] != "5") && (square[5] != "6") &&
- (square[6] != "7") && (square[7] != "8") && (square[8] != "9") )
- {
- return 0;
- }
- return -1;
- }
- /*
- ************************************************************
- METHOD TO ALLOW THE USER
- TO GO BACK TO THE MAIN MENU,
- IF THE "ESCAPE" BUTTON IS PRESSED
- ************************************************************
- */
- static void BackToMainMenu(ConsoleKeyInfo inputKey)
- {
- if (inputKey.Key == ConsoleKey.Escape)
- {
- MainMenu();
- }
- }
- /*
- ************************************************************
- METHOD TO ALLOW THE USER TO INPUT AGAIN,
- IF THE "ENTER" BUTTON IS PRESSED
- ************************************************************
- */
- static void PressEnterToContinue()
- {
- WriteCentered("Press \"ENTER\" to continue!");
- while (Console.ReadKey(true).Key != ConsoleKey.Enter);
- }
- /*
- ************************************************************
- METHOD TO CENTER THE TEXT
- IN THE MIDDLE OF THE CONSOLE
- ************************************************************
- */
- static void WriteCentered(string text)
- {
- int consoleWidth = Console.WindowWidth;
- int textWidth = text.Length;
- int leftMargin = (consoleWidth - textWidth) / 2;
- string centeredText = new string(' ', leftMargin) + text;
- Console.Write(centeredText);
- }
- /*
- ************************************************************
- END OF THE PROJECT
- ************************************************************
- */
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement