Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <functional>
- #include <iostream>
- #include <vector>
- #include <string>
- #include <windows.h>
- void VP_ClearScreen() {
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- HANDLE hStdOut;
- DWORD count;
- DWORD cellCount;
- COORD homeCoords = { 0, 0 };
- hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
- if (hStdOut == INVALID_HANDLE_VALUE) return;
- // Get the number of cells in the current buffer
- if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return;
- cellCount = csbi.dwSize.X *csbi.dwSize.Y;
- // Fill the entire buffer with spaces
- if (!FillConsoleOutputCharacter(hStdOut,(TCHAR) ' ', cellCount, homeCoords, &count))
- return;
- // Fill the entire buffer with the current colors and attributes
- if (!FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, cellCount, homeCoords, &count))
- return;
- // Move the cursor home
- SetConsoleCursorPosition( hStdOut, homeCoords );
- /* Windows */
- }
- void VP_SetConsoleCursor(bool bCursor) {
- CONSOLE_CURSOR_INFO curCursorInfo;
- curCursorInfo.bVisible = bCursor;
- curCursorInfo.dwSize = 1;
- SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &curCursorInfo);
- }
- void VP_GoToXY(int x, int y) {
- COORD CursorPosition = {static_cast<short>(x), static_cast<short>(y)};
- SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), CursorPosition);
- }
- int VP_GetCh () {
- HANDLE hConsole;
- INPUT_RECORD inrec;
- DWORD count, mode;
- hConsole = GetStdHandle(STD_INPUT_HANDLE);
- if (hConsole == INVALID_HANDLE_VALUE || !GetConsoleMode(hConsole, &mode)|| !SetConsoleMode(hConsole, 0))
- return 0;
- FlushConsoleInputBuffer(hConsole);
- do {
- ReadConsoleInput(hConsole, &inrec, 1, &count);
- } while ((inrec.EventType != KEY_EVENT) || inrec.Event.KeyEvent.bKeyDown);
- SetConsoleMode(hConsole, mode);
- return inrec.Event.KeyEvent.wVirtualKeyCode;
- }
- // Enum for positions
- enum position {LEFT, CENTER, RIGHT, TOP, BOTTOM};
- class Menu {
- public:
- // Define Empty Menu with a Title and set Left and Right Selectors
- Menu (std::string title = "",
- std::string leftSelector = "",
- std::string rightSelector = "",
- position verticalPosition = TOP,
- position horizontalPosition = LEFT) :
- strMenuTitle(title),
- strLeftSelector(leftSelector),
- strRightSelector(rightSelector),
- posVPosition(verticalPosition),
- posHPosition(horizontalPosition),
- vMenuOptions(),
- vMenuFunctions(),
- iLastSelection(1),
- bWrapAround(true) {}
- // Set Title for the Menu
- void SetTitle (std::string title) {
- strMenuTitle = title;
- }
- // Set Left and Right Selectors
- void SetSelectors (std::string leftSelector, std::string rightSelector) {
- strLeftSelector = leftSelector;
- strRightSelector = rightSelector;
- }
- // Set Menu Location
- void SetLocation (position verticalPosition = TOP, position horizontalPosition = LEFT) {
- posVPosition = verticalPosition;
- posHPosition = horizontalPosition;
- }
- // Allow Option Selection to return from bottom/top to top/bottom
- void Wrap (bool wrapAround = true) {
- bWrapAround = wrapAround;
- }
- // Add new Option
- void AddOption (std::string option) {
- vMenuOptions.push_back (option);
- vMenuFunctions.resize (vMenuOptions.size());
- }
- // Add new Option with a function
- void AddOption (std::string option, std::function<void ()> func) {
- vMenuOptions.push_back (option);
- vMenuFunctions.push_back (func);
- }
- // Set Option x to "text"
- void SetOption (unsigned int number, std::string option);
- // Set Option x to "text" with a function
- void SetOption (unsigned int number, std::string option, std::function<void ()> func);
- // Allow Option Selection to return from bottom/top to top/bottom
- unsigned int LastSelection() {
- return iLastSelection;
- }
- // Allow Option Selection to return from bottom/top to top/bottom
- int Size() {
- return vMenuOptions.size();
- }
- // Display menu with an option already highlighted
- void Play ();
- private:
- // Private function to Draw the menu
- void Draw();
- // Define a string to hold the left selector
- std::string strMenuTitle;
- // Define a string to hold the left selector
- std::string strLeftSelector;
- // Define a string to hold the right selector
- std::string strRightSelector;
- // Define a position to hold the vertical position
- position posVPosition;
- // Define a position to hold the horizontal position
- position posHPosition;
- // Define a vactor for storing the option strings
- std::vector<std::string> vMenuOptions;
- // Define a vector for storing the option functions
- std::vector<std::function <void ()>> vMenuFunctions;
- // Define an unsigned int to hold the last selected option
- unsigned int iLastSelection;
- // Define wrap around option
- bool bWrapAround;
- };
- void Menu::SetOption (unsigned int number, std::string option) {
- // Resize vMenuOptions to allow option at position
- if (vMenuOptions.size() < number) {
- vMenuOptions.resize (number, "");
- vMenuFunctions.resize (number);
- }
- // Assign the new option
- vMenuOptions[ (number - 1)] = option;
- }
- void Menu::SetOption (unsigned int number, std::string option, std::function<void ()> func) {
- // Resize vMenuOptions to allow option at position
- if (vMenuOptions.size() < number) {
- vMenuOptions.resize (number, "");
- vMenuFunctions.resize (number);
- }
- // Assign the new option
- vMenuOptions[ (number - 1)] = option;
- // Assign the new function
- vMenuFunctions[(number - 1)] = func;
- }
- void Menu::Draw () {
- // Clear the screen
- VP_ClearScreen();
- // Draw Title
- if (!strMenuTitle.empty() ) {
- // Print Title
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() - strMenuTitle.length() ) :
- (posHPosition == CENTER) ? ( (79 - strMenuTitle.length() ) / 2) :
- /*(posHPosition == LEFT) ?*/ strLeftSelector.length() ),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) );
- std::cout << strMenuTitle;
- // Print Seperator
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() - strMenuTitle.length() ) :
- (posHPosition == CENTER) ? ( (79 - strMenuTitle.length() ) / 2) :
- /*(posHPosition == LEFT) ?*/ strLeftSelector.length() ),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + 1);
- for (unsigned int i = 0; i < strMenuTitle.length(); i ++)
- std::cout << "-";
- }
- // Draw Options
- for (unsigned int i = 0; i < vMenuOptions.size(); i ++) {
- // Output Menu Option
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[i].length() ) :
- (posHPosition == CENTER) ? ( (79 - vMenuOptions[i].length() ) / 2) :
- /*(posHPosition == LEFT) ?*/ strLeftSelector.length() ),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + ( (strMenuTitle.empty() ) ? i : (i + 2) ) );
- std::cout << vMenuOptions[i];
- }
- }
- void Menu::Play () {
- // Draw the menu
- Draw();
- // Define Variables
- int iKeyPress;
- // Handle User Input until ENTER is Pressed
- do {
- // Draw Left Selector
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[ (iLastSelection - 1)].length() - strLeftSelector.length() ) :
- (posHPosition == CENTER) ? ( (79 - vMenuOptions[ (iLastSelection - 1)].length() ) / 2 - strLeftSelector.length() ) :
- /*(posHPosition == LEFT) ?*/ 0),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + ( (strMenuTitle.empty() ) ? (iLastSelection - 1) : (iLastSelection + 1) ) );
- std::cout << strLeftSelector;
- // Draw Right Selector
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() ) :
- (posHPosition == CENTER) ? ( (79 + vMenuOptions[ (iLastSelection - 1)].length() ) / 2) :
- /*(posHPosition == LEFT) ?*/ strLeftSelector.length() + vMenuOptions[ (iLastSelection - 1)].length() ),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + ( (strMenuTitle.empty() ) ? (iLastSelection - 1) : (iLastSelection + 1) ) );
- std::cout << strRightSelector;
- iKeyPress = VP_GetCh();
- // Handle User Input
- switch (iKeyPress) {
- // User Pressed Up
- case VK_UP:
- // Clear Left Selector
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[ (iLastSelection - 1)].length() - strLeftSelector.length() ) :
- (posHPosition == CENTER) ? ( (79 - vMenuOptions[ (iLastSelection - 1)].length() ) / 2 - strLeftSelector.length() ) :
- /*(posHPosition == LEFT) ?*/ 0),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + ( (strMenuTitle.empty() ) ? (iLastSelection - 1) : (iLastSelection + 1) ) );
- for (unsigned int i = 0; i < strLeftSelector.length(); i ++)
- std::cout << " ";
- // Clear Right Selector
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() ) :
- (posHPosition == CENTER) ? ( (79 + vMenuOptions[ (iLastSelection - 1)].length() ) / 2) :
- /*(posHPosition == LEFT) ?*/ strLeftSelector.length() + vMenuOptions[ (iLastSelection - 1)].length() ),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + ( (strMenuTitle.empty() ) ? (iLastSelection - 1) : (iLastSelection + 1) ) );
- for (unsigned int i = 0; i < strRightSelector.length(); i ++)
- std::cout << " ";
- // Set iLastSelection and allow for loop around
- iLastSelection = ( (iLastSelection == 1) ? ( (bWrapAround) ? vMenuOptions.size() : 1) : (iLastSelection - 1) );
- break;
- // User Pressed Down
- case VK_DOWN:
- // Clear Left Selector
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[ (iLastSelection - 1)].length() - strLeftSelector.length() ) :
- (posHPosition == CENTER) ? ( (79 - vMenuOptions[ (iLastSelection - 1)].length() ) / 2 - strLeftSelector.length() ) :
- /*(posHPosition == LEFT) ?*/ 0),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + ( (strMenuTitle.empty() ) ? (iLastSelection - 1) : (iLastSelection + 1) ) );
- for (unsigned int i = 0; i < strLeftSelector.length(); i ++)
- std::cout << " ";
- // Clear Right Selector
- VP_GoToXY ( ( (posHPosition == RIGHT) ? (79 - strRightSelector.length() ) :
- (posHPosition == CENTER) ? ( (79 + vMenuOptions[ (iLastSelection - 1)].length() ) / 2) :
- /*(posHPosition == LEFT) ?*/ strLeftSelector.length() + vMenuOptions[ (iLastSelection - 1)].length() ),
- ( (posVPosition == BOTTOM) ? (25 - Size() - 2) :
- (posVPosition == CENTER) ? ( (25 - Size() - 2) / 2) :
- /*(posVPosition == TOP) ?*/ 0) + ( (strMenuTitle.empty() ) ? (iLastSelection - 1) : (iLastSelection + 1) ) );
- for (unsigned int i = 0; i < strRightSelector.length(); i ++)
- std::cout << " ";
- // Set iLastSelection and allow for loop around
- iLastSelection = ( (iLastSelection == vMenuOptions.size() ) ? ( (bWrapAround) ? 1 : vMenuOptions.size() ) : (iLastSelection + 1) );
- break;
- // User Pressed Enter
- case VK_RETURN:
- if(vMenuFunctions[(iLastSelection - 1)]) {
- VP_ClearScreen();
- vMenuFunctions[(iLastSelection - 1)]();
- }
- Draw();
- }
- } while (vMenuFunctions[(iLastSelection - 1)] || (iKeyPress != VK_RETURN));
- }
- void DrawBoard(int board[], std::string players[]) {
- for (int i = 0; i < 9; i ++) {
- VP_GoToXY(37 + ((i % 3) * 2), 11 + ((i / 3) * 2));
- std::cout << ((board[i]) ? ((board[i] == 1) ? "X" : "O") : " ");
- if (i % 3 == 2) {
- if (i / 3 != 2) {
- VP_GoToXY(37, 12 + ((i / 3) * 2));
- std::cout << static_cast<char> (196)
- << static_cast<char> (197)
- << static_cast<char> (196)
- << static_cast<char> (197)
- << static_cast<char> (196);
- }
- }
- else
- std::cout << static_cast<char> (179);
- }
- VP_GoToXY(0, 12);
- std::cout << " " << players[0];
- VP_GoToXY(78 - players[1].length(), 12);
- std::cout << players[1];
- }
- void Move(int board[], std::string players[], int &player) {
- DrawBoard(board, players);
- VP_GoToXY(((player == 1) ? 0 : 78 - players[1].length()), 12);
- std::cout << "<" << players[player - 1] << ">";
- int position = 1;
- while (board[(position - 1)])
- position ++;
- int keyPress;
- do {
- VP_GoToXY(37 + (((position - 1) % 3) * 2), 11 + (((position - 1) / 3) * 2));
- std::cout << ((player == 1) ? "X" : "O");
- keyPress = VP_GetCh();
- VP_GoToXY(37 + (((position - 1) % 3) * 2), 11 + (((position - 1) / 3) * 2));
- std::cout << " ";
- do {
- if (keyPress == VK_RIGHT)
- position = ((position < 9) ? (position + 1) : 1);
- if (keyPress == VK_LEFT)
- position = ((position > 1) ? (position - 1) : 9);
- if (keyPress == VK_DOWN) {
- position = ((position < 9) ? (position + 3) : 1);
- if (position > 9)
- position = position - 9 + 1;
- }
- if (keyPress == VK_UP) {
- position = ((position > 1) ? (position - 3) : 9);
- if (position < 1)
- position = position + 9 - 1;
- }
- } while (board[(position - 1)]);
- } while (keyPress != VK_RETURN);
- board[(position - 1)] = player;
- VP_GoToXY(((player == 1) ? 0 : 78 - players[1].length()), 12);
- std::cout << " " << players[player - 1] << " ";
- player = ((player == 1) ? 2 : 1);
- }
- int Winner(int board[]) {
- for(int i = 0; i < 3; i ++)
- // Horizontal Victory
- if (board[(i * 3) + 0] == board[(i * 3) + 1]
- && board[(i * 3) + 1] == board[(i * 3) + 2])
- return board[(i * 3) + 0];
- // Vertical Victory
- else if (board[(0 * 3) + i] == board[(1 * 3) + i]
- && board[(1 * 3) + i] == board[(2 * 3) + i])
- return board[(0 * 3) + i];
- // Diagonal Victory
- if (board[0] == board[4] && board[4] == board[8])
- return board[0];
- if (board[2] == board[4] && board[4] == board[6])
- return board[2];
- // Draw
- int moves = 0;
- for (int i = 0; i < 9; i ++)
- if (board[i])
- moves ++;
- if (moves == 9)
- return 3;
- return 0;
- }
- void TicTacToe() {
- // Create game board
- int tttBoard[] = {
- 0,0,0,
- 0,0,0,
- 0,0,0
- };
- // Create player
- int player = 1;
- // Create winner
- int winner;
- // Create player names
- std::string players[] = {
- "Becky",
- "Zach"
- };
- DrawBoard(tttBoard, players);
- do {
- Move(tttBoard, players, player);
- } while (!(winner = Winner(tttBoard)));
- VP_ClearScreen();
- DrawBoard(tttBoard, players);
- VP_GoToXY(26, 17);
- // Player won
- if (winner != 3)
- std::cout << players[(winner - 1)] << " won! Great Job!";
- // Draw
- else
- std::cout << "No one won! Game ended in a Draw!";
- std::cout << "\nPress any key to continue...";
- VP_GetCh();
- }
- int main() {
- VP_SetConsoleCursor(false);
- // Define Settings Menu
- //Menu SettingsMenu("Settings", "-> ", " <-", CENTER, CENTER);
- // Define Main Menu
- Menu MainMenu("Tic-Tac-Toe", "-> ", " <-", CENTER, CENTER);
- MainMenu.AddOption("Play Tic-Tac-Toe", TicTacToe);
- //MainMenu.AddOption("Settings", std::bind(&Menu::Play, std::ref(SettingsMenu)));
- MainMenu.AddOption("Exit");
- MainMenu.Play();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement