diff --git a/game.cpp b/game.cpp new file mode 100644 index 0000000..7d927dd --- /dev/null +++ b/game.cpp @@ -0,0 +1,1144 @@ +// --------- HEADERS ---------- +#include +#include +#include +#include +#include +using namespace std; + +// ------- COLORS --------- +#define RESET "\033[0m" +#define RED "\033[31m" +#define GREEN "\033[32m" +#define CYAN "\033[36m" +#define BLUE "\033[34m" +#define YELLOW "\033[33m" +#define MAGENTA "\033[35m" +#define WHITE "\033[37m" + +// ----------------- Function Declarations ----------------- +void WaitForAnyKey(); +string Solid_HollowCircle(char Board[8][8], string player1, string player2); // counts the number of Circles +void SaveHistory(); +void ShowHistory(); +bool IsEnd(char board[8][8]); // checks if its end of game of not +void SaveGame(); // saves previous uncompleted game +bool LoadGame(); // loads previous uncompleted game +void StartGame(bool isLoaded); // the main strategy +void DrawBoard(); +void ChangeAll(int x,int y,char p); // returns any legal circle +bool ValidMove(int x,int y,char p); // check if there is any legal move for current player +int numofCircles (char board[8][8], char player); +string CurrentDateTime(); +void DrawMenu(int choice); +void DrawNewGameMenu(int choice); +void ModeType(int mode); +bool HasAnyMove(char p); +bool IsEndGame(); +void WaitForKeyRelease(); +void ClearInputBuffer(); + +// ----------------- Global Variables ----------------- +char board[8][8]; +bool locked[8][8]; +string menu[5]; +string mod[3]; +char currentPlayer = '1'; +bool movedThisTurn = false; +string player1, player2; +bool placedThisTurn = false; +bool lastTurnWasPass = false; +bool savedthisgame = false; +int moveCount = 0; +int botLevel = 0; +bool showPassMessage = false; +string passPlayerName = ""; + +// ----------------- structs ------------------ +struct Move { + int x, y; + int score; +}; + +Move moves[64]; + +COORD cursor = {0, 0}; + +// ------------ bot ----------- +void DrawBotMod(int level) { + system("cls"); + + string options[4] = { "Easy", "Hard", "Expert", "back" }; + cout << GREEN << " ╔═════════ " << RESET << RED << "BOT MODE" << RESET << GREEN << " ═════════╗\n" << RESET; + cout << GREEN << " ║ ║\n" << RESET; + for (int i = 0; i < 4; i++) { + + if (i == level) { + + if (i == 0) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << endl; + + if (i == 1) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << endl; + + if (i == 2) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << endl; + + if (i == 3) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << endl; + } + + else { + + if (i == 0) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + + if (i == 1) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + + if (i == 2) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + + if (i == 3) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + } + } + + cout << GREEN << " ║ ║\n" << RESET; + cout << GREEN << " ╚════════════════════════════╝\n" << RESET; + +} + +bool SelectBotLevel() { + int choice = 0; + while (true) { + DrawBotMod(choice); + char input = _getch(); + + if (input == 'w' || input == 'W') { + choice--; + if (choice < 0) choice = 3; + } + else if (input == 's' || input == 'S') { + choice++; + if (choice > 3) choice = 0; + } + else if (input == '\r') { // ENTER + // ---- BACK ---- + if (choice == 3) { + ClearInputBuffer(); + + return false; + } + + // ---- BOT LEVEL ---- + botLevel = choice + 1; + + ClearInputBuffer(); + return true; + } + } +} + +int CountFlips(int x,int y,char p){ + char backup[8][8]; + memcpy(backup, board, sizeof(board)); + + ChangeAll(x,y,p); + + int before = numofCircles(backup, p); + int after = numofCircles(board, p); + + memcpy(board, backup, sizeof(board)); + return after - before; +} + + + +void CollectValidMoves(char p){ + moveCount = 0; + for(int y=0;y<8;y++){ + for(int x=0;x<8;x++){ + if(ValidMove(x,y,p)){ + moves[moveCount].x = x; + moves[moveCount].y = y; + moves[moveCount].score = CountFlips(x,y,p); + moveCount++; + } + } + } +} + +bool IsCorner(int x,int y){ + return (x==0||x==7) && (y==0||y==7); +} + +bool IsEdge(int x,int y){ + return x==0||x==7||y==0||y==7; +} + +void BotMove(int level) { + + CollectValidMoves('2'); + + // ---------- BOT PASS ---------- +if (moveCount == 0) { + + showPassMessage = true; + passPlayerName = player2; + + DrawBoard(); + Sleep(800); + + showPassMessage = false; + + if (lastTurnWasPass) { + return; + } + + lastTurnWasPass = true; + currentPlayer = '1'; + return; +} + + // ---------- BOT HAS MOVE ---------- + + int idx = 0; + + // LEVEL 1: + if (level == 1) { + idx = rand() % moveCount; + } + + // LEVEL 2: + else if (level == 2) { + int maxScore = -1; + for (int i = 0; i < moveCount; i++) + if (moves[i].score > maxScore) + maxScore = moves[i].score; + + int best[64], bestCount = 0; + for (int i = 0; i < moveCount; i++) + if (moves[i].score == maxScore) + best[bestCount++] = i; + + idx = best[rand() % bestCount]; + } + + // LEVEL 3: + else if (level == 3) { + + int corners[64], cCount = 0; + int edges[64], eCount = 0; + int best[64], bCount = 0; + + int maxScore = -1; + for (int i = 0; i < moveCount; i++) + if (moves[i].score > maxScore) + maxScore = moves[i].score; + + for (int i = 0; i < moveCount; i++) { + if (IsCorner(moves[i].x, moves[i].y)) + corners[cCount++] = i; + else if (IsEdge(moves[i].x, moves[i].y)) + edges[eCount++] = i; + else if (moves[i].score == maxScore) + best[bCount++] = i; + } + + if (cCount > 0) idx = corners[rand() % cCount]; + else if (eCount > 0) idx = edges[rand() % eCount]; + else idx = best[rand() % bCount]; + } + + // ---------- EXECUTE MOVE ---------- + int x = moves[idx].x; + int y = moves[idx].y; + + board[y][x] = '2'; + locked[y][x] = true; + ChangeAll(x, y, '2'); + + currentPlayer = '1'; + +} + +// ----------------- Functions ----------------- + +void ClearInputBuffer() { + while (_kbhit())_getch(); +} +bool HasAnyMove(char p){ + for(int y=0;y<8;y++) + for(int x=0;x<8;x++) + if(ValidMove(x,y,p)) + return true; + return false; +} + +bool IsEndGame(){ + return !HasAnyMove('1') && !HasAnyMove('2'); +} + + +void DrawMenu(int choice) { + + system("cls"); + string options[5] = { "New Game", "Load Game", "Help", "Game History", "Exit" }; + cout << GREEN << " ╔══════════ " << RESET << RED << "GAME MENU" << RESET << GREEN << " ══════════╗\n" << RESET; + cout << GREEN << " ║ ║\n" << RESET; + for (int i = 0; i < 5; i++) { + + if (i == choice) { + if (i == 0) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + + if (i == 1) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + + if (i == 2) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + + if (i == 3) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + + if (i == 4) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + } + else { + + if (i == 0) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + + if (i == 1) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + + if (i == 2) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + + if (i == 3) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + + if (i == 4) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << RESET << endl; + } + } + cout << GREEN << " ║ ║\n" << RESET; + cout << GREEN << " ╚═══════════════════════════════╝\n" << RESET; + + +} + +void DrawNewGameMenu(int choice) { + system("cls"); + + string options[3] = { "Single Player", "Two Player", "Back to Menu" }; + cout << GREEN << " ╔════════ " << RESET << RED << "NEW GAME" << RESET << GREEN << " ════════╗\n" << RESET; + cout << GREEN << " ║ ║\n" << RESET; + + for (int i = 0 ; i < 3 ; i++) { + if (i == choice){ + + if (i == 0) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + + + if (i == 1) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + + if (i == 2) cout << GREEN << " ╠" << RESET << MAGENTA << " > " << options[i] << " <" << RESET << GREEN << " ╣" << RESET << endl; + + } + else { + + if (i == 0) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << endl; + + if (i == 1) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << endl; + + if (i == 2) cout << GREEN << " ║" << RESET << " " << options[i] << GREEN << " ║" << endl; + + } + + } + + cout << GREEN << " ║ ║\n" << RESET; + cout << GREEN << " ╚══════════════════════════╝\n" << RESET; + +} + +// -------------------- Game place -------------------- +void ModeType(int mode) { + system("cls"); + + if (mode == 1) { + cout << "Enter your name: "; + cin >> player1; + + player2 = "Bot"; + + bool levelSelected = false; + while (!levelSelected) { + levelSelected = SelectBotLevel(); + if (!levelSelected) return; + } + } + else if (mode == 2) { + cout << "Enter Player1 Name: "; + cin >> player1; + cout << "Enter Player2 Name: "; + cin >> player2; + + } + + savedthisgame = false; + StartGame(false); +} + + +void DrawBoard() { + system("cls"); + + cout << GREEN << " ┌─────────────────────────────────┐\n" << RESET; + +for (int y = 0; y < 8; y++) { + + cout << GREEN << " │ " << RESET; + + for (int x = 0; x < 8; x++) { + + string display; + if (cursor.X == x && cursor.Y == y) { + + if (board[y][x] == '_') { + cout << RED << "[" << RESET << "_" << RED << "]" << RESET ; + } + else if (ValidMove(x, y, currentPlayer)) { + cout << RED << "[*]" << RESET; + } + else { + + cout << RED << "[" << RESET; + cout << (board[y][x] == '1' ? "●" : "○"); + cout << RED << "]" << RESET; + } + } + else { + + if (board[y][x] == '1') + display = "●"; + else if (board[y][x] == '2') + display = "○"; + else if (ValidMove(x, y, currentPlayer)) + display = string(BLUE) + "*" + RESET; + else + display = "_"; + + cout << " " << display << " "; + } + + cout << " "; + } + cout << GREEN << "│\n" << RESET; +} + cout << GREEN << " └─────────────────────────────────┘\n" << RESET; + + cout << GREEN << " ╔════════╗\n" << RESET; + cout << GREEN << " ║ ║\n" << RESET; + + cout << " ● : " << numofCircles(board, '1') << endl; + cout << " ○ : " << numofCircles(board, '2') << endl; + cout << GREEN << " ║ ║\n" << RESET; + cout << GREEN << " ╚════════╝\n" << RESET; + cout << "\n Current Player: " << (currentPlayer == '1' ? player1 : player2) << endl; + + +} + + + + +void StartGame(bool isLoaded = false) { + if (!isLoaded) { + + movedThisTurn = false; + currentPlayer = '1'; + cursor = {0, 0}; + for (int y = 0; y < 8; y++) + for (int x = 0; x < 8; x++) { + board[y][x] = '_'; + locked[y][x] = false; + } + board[3][3] = board[4][4] = '2'; + board[3][4] = board[4][3] = '1'; + locked[3][3] = locked[4][4] = locked[3][4] = locked[4][3] = true; + } + + DrawBoard(); + + WaitForKeyRelease(); + ClearInputBuffer(); + + bool wPressed=false, aPressed=false, sPressed=false, dPressed=false, enterPressed=false; + bool spacePressed=false; + + while(true) { + bool needRedraw = false; + + + // ---------- BOT TURN ---------- + if (player2 == "Bot" && currentPlayer == '2') { + + Sleep(400); + BotMove(botLevel); + + lastTurnWasPass = false; + placedThisTurn = false; + + DrawBoard(); + WaitForKeyRelease(); + ClearInputBuffer(); + continue; + + } + + + // Move Cursor + if ((GetAsyncKeyState('W') & 0x8000) && !wPressed && cursor.Y>0) { cursor.Y--; wPressed=true; needRedraw=true; } + else if (!(GetAsyncKeyState('W') & 0x8000)) wPressed=false; + if ((GetAsyncKeyState('S') & 0x8000) && !sPressed && cursor.Y<7) { cursor.Y++; sPressed=true; needRedraw=true; } + else if (!(GetAsyncKeyState('S') & 0x8000)) sPressed=false; + if ((GetAsyncKeyState('A') & 0x8000) && !aPressed && cursor.X>0) { cursor.X--; aPressed=true; needRedraw=true; } + else if (!(GetAsyncKeyState('A') & 0x8000)) aPressed=false; + if ((GetAsyncKeyState('D') & 0x8000) && !dPressed && cursor.X<7) { cursor.X++; dPressed=true; needRedraw=true; } + else if (!(GetAsyncKeyState('D') & 0x8000)) dPressed=false; + + + // ENTER + if ((GetAsyncKeyState(VK_RETURN) & 0x8000) && !enterPressed) { + + if (!placedThisTurn) { + + if (!HasAnyMove(currentPlayer)) { + + DrawBoard(); + Sleep(1000); + } + + if (lastTurnWasPass) { + + // remove("SaveGame.txt"); + // SaveGame(); + + // WaitForKeyRelease(); + // ClearInputBuffer(); + // break; + } + + + lastTurnWasPass = true; + } + else { + + locked[cursor.Y][cursor.X] = true; + ChangeAll(cursor.X, cursor.Y, currentPlayer); + + lastTurnWasPass = false; + placedThisTurn = false; + + currentPlayer = (currentPlayer=='1')?'2':'1'; + SaveGame(); + } + + needRedraw = true; + enterPressed = true; + } + else if (!(GetAsyncKeyState(VK_RETURN) & 0x8000)) enterPressed = false; + + + // SPACE + if ((GetAsyncKeyState(VK_SPACE) & 0x8000) && !spacePressed) { + + if (!locked[cursor.Y][cursor.X]) { + + if (ValidMove(cursor.X, cursor.Y, currentPlayer)) { + char &cell = board[cursor.Y][cursor.X]; + + if (cell == '_') { + cell = currentPlayer; + placedThisTurn = true; + } + else if (cell == currentPlayer) { + cell = '_'; + placedThisTurn = false; + } + needRedraw = true; + + } + else { + cout << "\nInvalid move! You must place on a legal cell.\n"; + Sleep(800); + } + + } + else { + cout << "\nInvalid move! You must place on a legal cell.\n"; + Sleep(800); + } + + spacePressed = true; + } + else if (!(GetAsyncKeyState(VK_SPACE) & 0x8000)) spacePressed = false; + + + // ESC + if ((GetAsyncKeyState(VK_ESCAPE) & 0x8000)) { + + remove("SaveGame.txt"); + SaveGame(); + WaitForKeyRelease(); + ClearInputBuffer(); + break; + } + + + if (needRedraw) + DrawBoard(); + + bool movesLeft = false; + for(int y=0;y<8;y++) + for(int x=0;x<8;x++) + if(ValidMove(x,y,currentPlayer)) movesLeft=true; + + if (!movesLeft) { + cout << " --------passed------"; + Sleep(500); + currentPlayer = (currentPlayer=='1')?'2':'1'; + } + + + if (IsEndGame()) { // end of the game + + if (!savedthisgame) { + + + SaveHistory(); + system("cls"); + + cout << " << --- " << RED << "GAME IS OVER" << RESET << " --- >>\n"; + + if (numofCircles(board, '1') > numofCircles(board, '2')){ + cout << " PLAYER < " << CYAN << player1 << RESET << " > won!"; + } + else if (numofCircles(board, '1') < numofCircles(board, '2')){ + cout << " PLAYER < " << CYAN << player2 << RESET << " > won!"; + } + else if (numofCircles(board, '1') == numofCircles(board, '2')){ + system("cls"); + cout << GREEN << " Equal!" << RESET; + } + + cout << RED << "\n PRESS ANY KET TO RETURN TO MENU . . ." << RESET ; + + WaitForAnyKey(); + + WaitForKeyRelease(); + ClearInputBuffer(); + break; + + } + } + + Sleep(80); + + } +} + +// ----------------- Remaining Functions ----------------- +void WaitForKeyRelease() { + while ((GetAsyncKeyState(VK_RETURN) & 0x8000) || (GetAsyncKeyState(VK_SPACE) & 0x8000) ||(GetAsyncKeyState(VK_ESCAPE) & 0x8000)) { + Sleep(50); + } +} + +void WaitForAnyKey(){ + while(true){ + for(int k=8;k<=190;k++) + if(GetAsyncKeyState(k)&0x8000) { + return; + } + Sleep(50); + } +} + +string Solid_HollowCircle(char Board[8][8], string player1, string player2) { + int solid = 0, hollow = 0; + for (int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++) { + if (Board[i][j] == '1') solid++; + else if (Board[i][j] == '2') hollow++; + } + + string res; + if (solid > hollow) + res = player1 + " won\n"; + else if (hollow > solid) + res = player2 + " won\n"; + else + res = "Equal\n"; + + res += "Solid Circles (●) : " + to_string(solid) + "\n"; + res += "Hollow Circles (○) : " + to_string(hollow) + "\n"; + + return res; +} + +string CurrentDateTime() { + + time_t t = time(0); + tm now = *localtime(&t); + + string Date, Times, res; + + Date = to_string(now.tm_year + 1900) + "-" + to_string(now.tm_mon + 1) + "-" + to_string(now.tm_mday) + " "; + + Times = to_string(now.tm_hour) + ":" + to_string(now.tm_min) + ":" + to_string(now.tm_sec); + + res = Date + Times; + return res; +} + + +void SaveHistory() { + + int p1 = numofCircles(board, '1'); + int p2 = numofCircles(board, '2'); + + string winner; + if (p1 > p2) winner = player1; + else if (p2 > p1) winner = player2; + else winner = "Equal"; + + ofstream file("HistoryGame.txt", ios::app); + if (!file) return; + + file << "------------------\n"; + file << "Date: " << CurrentDateTime() << "\n"; + file << "Player 1: " << player1 << "\n"; + file << "Player 2: " << player2 << "\n"; + file << "Score: " << player1 << " (" << p1 << ") - " + << player2 << " (" << p2 << ")\n"; + file << "Winner: " << winner << "\n"; + file << "------------------\n"; + + file.close(); +} + +void ShowHistory() { + + ifstream file("HistoryGame.txt"); + if (!file) { + cout << "No game history found!\n"; + return; + } + + string lines[2000]; + int count = 0; + + while (getline(file, lines[count]) && count < 2000) + count++; + + file.close(); + + for (int i = count - 1; i >= 0; i--) { + cout << lines[i] << endl; + } + + cout << "\n<<---" << RED << " -- PRESS ANY KEY TO RETURN TO MENU -- " << RESET << "--->>"; + WaitForAnyKey(); +} + +bool IsEnd(char board[8][8]){ + for(int i=0;i<8;i++) + for(int j=0;j<8;j++) + if(board[i][j]=='_') + return false; + return true; +} + +void SaveGame(){ + ofstream file("SaveGame.txt"); + if(!file) return; + file<> currentPlayer; + file.ignore(); + + getline(file, player1); + getline(file, player2); + + for(int i=0;i<8;i++) + for(int j=0;j<8;j++) + file >> board[i][j]; + + for(int i=0;i<8;i++) + for(int j=0;j<8;j++) + file >> locked[i][j]; + + file.close(); + return true; +} + + +int numofCircles (char board[8][8], char player) { + + int number = 0; + for (int i = 0 ; i < 8 ; i++) + for (int j = 0 ; j < 8 ; j++) + if (board[i][j] == player) + number++; + + return number; +} + +// ---------- Opponent ---------- +char Opponent(char p){ + return (p=='1')?'2':'1'; +} + +// ---------- Change Functions ---------- +void ChangeRight(int x,int y,char p){ + + char op=Opponent(p); + int i=x+1; + + while(i<8&&board[y][i]==op)i++; + + if(i<8&&board[y][i]==p) + for(int j=x+1;j=0&&board[y][i]==op)i--; + + if(i>=0&&board[y][i]==p) + for(int j=x-1;j>i;j--) + board[y][j]=p; +} + + +void ChangeDown(int x,int y,char p){ + + char op=Opponent(p); + int i=y+1; + + while(i<8&&board[i][x]==op)i++; + + if(i<8&&board[i][x]==p) + for(int j=y+1;j=0&&board[i][x]==op)i--; + + if(i>=0&&board[i][x]==p) + for(int j=y-1;j>i;j--) + board[j][x]=p; +} + + +void ChangeUpRight(int x,int y,char p){ + + char op=Opponent(p); + int i=x+1,j=y-1; + + while(i<8&&j>=0&&board[j][i]==op){i++;j--;} + + if(i<8&&j>=0&&board[j][i]==p){ + int a=x+1,b=y-1;while(aj){board[b][a]=p;a++;b--;} + } +} + + +void ChangeUpLeft(int x,int y,char p){ + + char op=Opponent(p); + int i=x-1,j=y-1; + + while(i>=0&&j>=0&&board[j][i]==op){i--;j--;} + + if(i>=0&&j>=0&&board[j][i]==p){ + int a=x-1,b=y-1; + while(a>i&&b>j){ + board[b][a]=p; + a--; + b--; + } + } +} + + +void ChangeDownRight(int x,int y,char p){ + + char op=Opponent(p); + int i=x+1,j=y+1; + + while(i<8&&j<8&&board[j][i]==op){i++;j++;} + + if(i<8&&j<8&&board[j][i]==p){ + int a=x+1,b=y+1; + while(a=0&&j<8&&board[j][i]==op){i--;j++;} + + if(i>=0&&j<8&&board[j][i]==p){ + int a=x-1,b=y+1; + while(a>i&&b=8||board[y][i]!=op) return false; + + while(i<8&&board[y][i]==op)i++; + return (i<8&&board[y][i]==p); +} + + +bool CheckLeft(int x,int y,char p){ + + char op=Opponent(p); + int i=x-1; + + if(i<0||board[y][i]!=op) return false; + + while(i>=0&&board[y][i]==op)i--; + + return (i>=0 && board[y][i]==p); +} + + +bool CheckDown(int x,int y,char p){ + + char op=Opponent(p); + int i=y+1; + + if(i>=8||board[i][x]!=op) return false; + + while(i<8&&board[i][x]==op)i++; + + return (i<8&&board[i][x]==p); +} + + +bool CheckUp(int x,int y,char p){ + + char op=Opponent(p); + int i=y-1; + + if(i<0||board[i][x]!=op) return false; + + while(i>=0&&board[i][x]==op)i--; + + return (i>=0&&board[i][x]==p); +} + + +bool CheckUpRight(int x,int y,char p){ + + char op=Opponent(p); + int i=x+1,j=y-1; + + if(i>=8||j<0||board[j][i]!=op) return false; + + while(i<8&&j>=0&&board[j][i]==op){i++;j--;} + + return (i<8&&j>=0&&board[j][i]==p); + +} + + +bool CheckUpLeft(int x,int y,char p){ + + char op=Opponent(p); + int i=x-1,j=y-1; + + if(i<0||j<0||board[j][i]!=op) return false; + + while(i>=0&&j>=0&&board[j][i]==op){i--;j--;} + + return (i>=0&&j>=0&&board[j][i]==p); + +} + + +bool CheckDownRight(int x,int y,char p){ + + char op=Opponent(p); + int i=x+1,j=y+1; + + if(i>=8||j>=8||board[j][i]!=op) return false; + + while(i<8&&j<8&&board[j][i]==op){i++;j++;} + + return (i<8&&j<8&&board[j][i]==p); + +} + + +bool CheckDownLeft(int x,int y,char p){ + + char op=Opponent(p); + int i=x-1,j=y+1; + + if(i<0||j>=8||board[j][i]!=op) return false; + + while(i>=0&&j<8&&board[j][i]==op){i--;j++;} + + return (i>=0&&j<8&&board[j][i]==p); + +} + + +bool ValidMove(int x,int y,char p){ + if(board[y][x]!='_') return false; + return CheckRight(x,y,p) || CheckLeft(x,y,p) || CheckUp(x,y,p) || CheckDown(x,y,p) || + CheckUpRight(x,y,p) || CheckUpLeft(x,y,p) || CheckDownRight(x,y,p) || CheckDownLeft(x,y,p); +} + +void EnableANSI() { + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwMode = 0; + GetConsoleMode(hOut, &dwMode); + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(hOut, dwMode); +} + + +// ----- main------- +int main() { + + + + EnableANSI(); + SetConsoleOutputCP(CP_UTF8); + SetConsoleCP(CP_UTF8); + + int choice = 0; + while (true) { + + DrawMenu(choice); + char input = _getch(); // Get key without enter + + if (input == 'w' || input == 'W') { + choice--; + if (choice < 0) choice = 4; + } + else if (input == 's' || input == 'S') { + choice++; + if (choice > 4) choice = 0; + } else if (input == '\r') { // Enter key + if (choice == 0) { // New Game + int newChoice = 0; + while (true) { + DrawNewGameMenu(newChoice); + + char newInput = _getch(); + + if (newInput == 'w' || newInput == 'W') { + newChoice--; + if (newChoice < 0) newChoice = 2; + } else if (newInput == 's' || newInput == 'S') { + newChoice++; + if (newChoice > 2) newChoice = 0; + } else if (newInput == '\r') { + if (newChoice == 0) { + ModeType(1); + break; + } + else if (newChoice == 1) { + ModeType(2); + break; + } + else if (newChoice == 2) + break; // Back to main menu + } + } + } + else if (choice == 1) { + + Sleep(800); + if(!LoadGame()){ + cout << "No unfinished game found!"; + Sleep(1500); + continue; + } + + cursor = {0,0}; + StartGame(true); + } + else if (choice == 2) { + system("cls"); + Sleep(800); + cout<< " W : up \n S : down \n A : left \n D : right\n" + << " SPACE : place the circles\n" + << " ENTER : fix the cell && change the turn \n" + << " ESC : Close The Game \n" + << " <<---" << RED << " -- PRESS ANY KEY TO RETURN TO MENU -- " << RESET << "--->>"; + + WaitForAnyKey(); + } + else if (choice == 3) { + + system("cls"); + WaitForKeyRelease(); + ClearInputBuffer(); + + ShowHistory(); + + } + else if (choice == 4) { + + break; + } + } + } + return 0; +}