#include #include #include #include #include #include #include #include #include #include #include using namespace std; struct Player { string name; char color; // 'B' or 'W' int discs; }; void initialBoard(); void drawBoard(int cursorRow, int cursorCol, bool blackTurn, bool invalidMove, const string& message); bool cursor(int& cursorRow, int& cursorCol, bool blackTurn, bool invalidMove, const string& message, bool viewOnly); bool possibleMoveB(int row, int col); bool possibleMoveW(int row, int col); bool hasAnyMoveB(); bool hasAnyMoveW(); void placeB(int row, int col); void placeW(int row, int col); void flipB(int row, int col); void flipW(int row, int col); int blackCount(); int whiteCount(); void singlePlayerB(string& s); bool aiMoveWhite(); void gameOverB(string& s); void singlePlayerW(string& s); bool aiMoveBlack(); void gameOverW(string& s); void multiPlayer(string& s, string& t); void gameOverM(string& s, string& t); void saveHistory(const string& mode, const Player& black, const Player& white, const string& result); void showHistory(); void help(); void newGame(); void menu(); char B='B'; //○ char W='W'; //● bool blackTurn=true; const int BOARD_SIZE = 8; string board[BOARD_SIZE][BOARD_SIZE]; // Arrow key codes const int KEY_UP = 72; const int KEY_DOWN = 80; const int KEY_LEFT = 75; const int KEY_RIGHT = 77; const int ENTER = 13; const int ESC = 27; void initialBoard() { for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { board[i][j] = " "; } } board[3][3] = "●"; board[3][4] = "○"; board[4][3] = "○"; board[4][4] = "●"; } void drawBoard(int cursorRow, int cursorCol, bool blackTurn, bool invalidMove, const string& message="") { SetConsoleOutputCP(CP_UTF8); system("cls"); cout << "┏"; for (int i = 0; i < BOARD_SIZE; i++) { cout << "━━━"; if (i < BOARD_SIZE - 1) {cout << "┳";} } cout << "┓\n"; for (int i = 0; i < BOARD_SIZE; i++) { cout << "┃"; for (int j = 0; j < BOARD_SIZE; j++) { bool valid; if (blackTurn) {valid = possibleMoveB(i, j);} else {valid = possibleMoveW(i, j);} if (i == cursorRow && j == cursorCol) { if (valid) {cout << "[*]";} else {cout << "[" << board[i][j] << "]";} } else { if (valid) {cout << " * ";} else {cout << " " << board[i][j] << " ";} } cout << "┃"; } cout << "\n"; if (i < BOARD_SIZE - 1) { cout << "┣"; for (int j = 0; j < BOARD_SIZE; j++) { cout << "━━━"; if (j < BOARD_SIZE - 1) {cout << "╋";} } cout << "┫\n"; } } cout << "┗"; for (int i = 0; i < BOARD_SIZE; i++) { cout << "━━━"; if (i < BOARD_SIZE - 1) {cout << "┻";} } cout << "┛\n"; //cout << "\n"; cout <<" Black(○): " << blackCount()<< " White(●): " << whiteCount() << "\n"; cout << " Turn: "; if (blackTurn) {cout << "Black(○)\n";} else {cout << "White(●)\n";} cout<<"\n"; if (!message.empty()) {cout << " " << message << "\n\n";} else if (invalidMove) {cout << " Invalid Move!\n\n";} else {cout << "\n\n";} cout << " Press ESC To Return To The Menu "<<"\n"; } bool cursor(int& cursorRow, int& cursorCol, bool blackTurn, bool invalidMove = false, const string& message = "", bool viewOnly = false) { while (true) { drawBoard(cursorRow, cursorCol, blackTurn, invalidMove, message); int ch = _getch(); if (ch == 0 || ch == 224) { ch = _getch(); switch (ch) { case KEY_UP: if (cursorRow > 0) cursorRow--; break; case KEY_DOWN: if (cursorRow < BOARD_SIZE - 1) cursorRow++; break; case KEY_LEFT: if (cursorCol > 0) cursorCol--; break; case KEY_RIGHT: if (cursorCol < BOARD_SIZE - 1) cursorCol++; break; } } else if (ch == ENTER) { if (!viewOnly) { return true; } } else if (ch == ESC) { return false; } } } bool possibleMoveB(int row, int col) { int r, c; if (board[row][col]==" ") { r=row+1; if (r=0 && board[r][col]=="●") { while (r>=0 && board[r][col]=="●") {r--;} if (r>=0 && board[r][col]=="○") {return true;}} c=col+1; if (c=0 && board[row][c]=="●") { while (c>=0 && board[row][c]=="●") {c--;} if (c>=0 && board[row][c]=="○") {return true;}} r=row+1; c=col+1; if (r=0 && board[r][c]=="●") { while (r=0 && board[r][c]=="●") {r++; c--;} if (r=0 && board[r][c]=="○") {return true;}} r=row-1; c=col+1; if (r>=0 && c=0 && c=0 && c=0 && c>=0 && board[r][c]=="●") { while (r>=0 && c>=0 && board[r][c]=="●") {r--; c--;} if (r>=0 && c>=0 && board[r][c]=="○") {return true;}} } return false; } bool possibleMoveW(int row, int col) { int r, c; if (board[row][col]==" ") { r=row+1; if (r=0 && board[r][col]=="○") { while (r>=0 && board[r][col]=="○") {r--;} if (r>=0 && board[r][col]=="●") {return true;}} c=col+1; if (c=0 && board[row][c]=="○") { while (c>=0 && board[row][c]=="○") {c--;} if (c>=0 && board[row][c]=="●") {return true;}} r=row+1; c=col+1; if (r=0 && board[r][c]=="○") { while (r=0 && board[r][c]=="○") {r++; c--;} if (r=0 && board[r][c]=="●") {return true;}} r=row-1; c=col+1; if (r>=0 && c=0 && c=0 && c=0 && c>=0 && board[r][c]=="○") { while (r>=0 && c>=0 && board[r][c]=="○") {r--; c--;} if (r>=0 && c>=0 && board[r][c]=="●") {return true;}} } return false; } bool hasAnyMoveB() { for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (possibleMoveB(i, j)) {return true;} } } return false; } bool hasAnyMoveW() { for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (possibleMoveW(i, j)) {return true;} } } return false; } void placeB(int row, int col) { board[row][col]="○"; } void placeW(int row, int col) { board[row][col]="●"; } void flipB(int row, int col) { int r, c, count, k; r=row+1; count=0; while (r0 && r=0 && board[r][col]=="●") {count++; r--;} if (count>0 && r>=0 && board[r][col]=="○") { for (k=1; k<=count; k++) { board[row-k][col]="○"; } } c=col+1; count=0; while (c0 && c=0 && board[row][c]=="●") {count++; c--;} if (count>0 && c>=0 && board[row][c]=="○") { for (k=1; k<=count; k++) { board[row][col-k]="○"; } } r=row+1; c=col+1; count=0; while (r0 && r=0 && board[r][c]=="●") {count++; r++; c--;} if (count>0 && r=0 && board[r][c]=="○") { for (k=1; k<=count; k++) { board[row+k][col-k]="○"; } } r=row-1; c=col+1; count=0; while (r>=0 && c0 && r>=0 && c=0 && c>=0 && board[r][c]=="●") {count++; r--; c--;} if (count>0 && r>=0 && c>=0 && board[r][c]=="○") { for (k=1; k<=count; k++) { board[row-k][col-k]="○"; } } } void flipW(int row, int col) { int r, c, count, k; r=row+1; count=0; while (r0 && r=0 && board[r][col]=="○") {count++; r--;} if (count>0 && r>=0 && board[r][col]=="●") { for (k=1; k<=count; k++) { board[row-k][col]="●"; } } c=col+1; count=0; while (c0 && c=0 && board[row][c]=="○") {count++; c--;} if (count>0 && c>=0 && board[row][c]=="●") { for (k=1; k<=count; k++) { board[row][col-k]="●"; } } r=row+1; c=col+1; count=0; while (r0 && r=0 && board[r][c]=="○") {count++; r++; c--;} if (count>0 && r=0 && board[r][c]=="●") { for (k=1; k<=count; k++) { board[row+k][col-k]="●"; } } r=row-1; c=col+1; count=0; while (r>=0 && c0 && r>=0 && c=0 && c>=0 && board[r][c]=="○") {count++; r--; c--;} if (count>0 && r>=0 && c>=0 && board[r][c]=="●") { for (k=1; k<=count; k++) { board[row-k][col-k]="●"; } } } int blackCount() { int count=0; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (board[i][j]=="○") {count++;} } } return count; } int whiteCount() { int count=0; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (board[i][j]=="●") {count++;} } } return count; } void singlePlayerB(string& s) { initialBoard(); int cursorRow = 0, cursorCol = 0; bool blackTurn = true; bool invalidMove = false; string currentMessage = ""; while (true) { if (!hasAnyMoveB() && !hasAnyMoveW()) { gameOverB(s); return; } if (blackTurn && !hasAnyMoveB()) { currentMessage = "Black(○) has no valid moves. Skipping Turn..."; drawBoard(cursorRow, cursorCol, blackTurn, false, currentMessage); Sleep(2000); currentMessage = ""; blackTurn=false; continue; } if (!blackTurn && !hasAnyMoveW()) { currentMessage = "White(●) has no valid moves. Skipping Turn..."; drawBoard(cursorRow, cursorCol, blackTurn, false, currentMessage); Sleep(2000); currentMessage = ""; blackTurn=true; continue; } drawBoard(cursorRow, cursorCol, blackTurn, invalidMove, currentMessage); if (blackTurn) { bool pressedEnter = cursor(cursorRow, cursorCol, blackTurn, invalidMove, currentMessage); if (!pressedEnter) {return;} if (possibleMoveB(cursorRow, cursorCol)) { placeB(cursorRow, cursorCol); flipB(cursorRow, cursorCol); blackTurn = false; invalidMove = false; } else { invalidMove = true; } } else { Sleep(800); aiMoveWhite(); blackTurn = true; } } } bool aiMoveWhite() { int rows[64]; int cols[64]; int count = 0; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (possibleMoveW(i, j)) { rows[count] = i; cols[count] = j; count++; } } } if (count == 0) return false; int r = rand() % count; int row = rows[r]; int col = cols[r]; placeW(row, col); flipW(row, col); return true; } void gameOverB(string& s) { int cursorRow = 0; int cursorCol = 0; Player blackPlayer; Player whitePlayer; blackPlayer.name = s; blackPlayer.color = 'B'; blackPlayer.discs = blackCount(); whitePlayer.name = "Bot"; whitePlayer.color = 'W'; whitePlayer.discs = whiteCount(); string winnerMessage; string result; if (blackPlayer.discs > whitePlayer.discs) { winnerMessage = "Congrats " + blackPlayer.name + "! You Won!"; result = blackPlayer.name + " Won";} else if (whitePlayer.discs > blackPlayer.discs) { winnerMessage = "You Lost " + blackPlayer.name + ". Better Luck Next Time!"; result = whitePlayer.name + " Won";} else { winnerMessage = "It's a DRAW!"; result = "Draw";} saveHistory("Single Player", blackPlayer, whitePlayer, result); cursor(cursorRow, cursorCol, true, false, winnerMessage, true); } void singlePlayerW(string& s) { initialBoard(); int cursorRow = 0, cursorCol = 0; bool blackTurn = true; bool invalidMove = false; string currentMessage = ""; while (true) { if (!hasAnyMoveB() && !hasAnyMoveW()) { gameOverW(s); return; } if (blackTurn && !hasAnyMoveB()) { currentMessage = "Black(○) has no valid moves. Skipping Turn..."; drawBoard(cursorRow, cursorCol, blackTurn, false, currentMessage); Sleep(2000); currentMessage = ""; blackTurn=false; continue; } if (!blackTurn && !hasAnyMoveW()) { currentMessage = "White(●) has no valid moves. Skipping Turn..."; drawBoard(cursorRow, cursorCol, blackTurn, false, currentMessage); Sleep(2000); currentMessage = ""; blackTurn=true; continue; } drawBoard(cursorRow, cursorCol, blackTurn, invalidMove, currentMessage); if (!blackTurn) { bool pressedEnter = cursor(cursorRow, cursorCol, blackTurn, invalidMove, currentMessage); if (!pressedEnter) {return;} if (possibleMoveW(cursorRow, cursorCol)) { placeW(cursorRow, cursorCol); flipW(cursorRow, cursorCol); blackTurn = true; invalidMove = false; } else { invalidMove = true; } } else { Sleep(800); aiMoveBlack(); blackTurn = false; } } } bool aiMoveBlack() { int rows[64]; int cols[64]; int count=0; for (int i = 0; i blackPlayer.discs) { winnerMessage = "Congrats " + whitePlayer.name + "! You Won!"; result = whitePlayer.name + " Won";} else if (blackPlayer.discs > whitePlayer.discs) { winnerMessage = "You Lost " + whitePlayer.name + ". Better Luck Next Time!"; result = blackPlayer.name + " Won";} else { winnerMessage = "It's a DRAW!"; result = "Draw";} saveHistory("Single Player", blackPlayer, whitePlayer, result); cursor(cursorRow, cursorCol, true, false, winnerMessage, true); } void multiPlayer(string& s, string& t) { initialBoard(); int cursorRow = 0, cursorCol = 0; bool blackTurn = true; bool invalidMove = false; string currentMessage = ""; while (true) { if (!hasAnyMoveB() && !hasAnyMoveW()) { gameOverM(s, t); return; } if (blackTurn && !hasAnyMoveB()) { currentMessage = "Black(○) has no valid moves. Skipping Turn..."; drawBoard(cursorRow, cursorCol, blackTurn, false, currentMessage); Sleep(2000); currentMessage = ""; blackTurn=false; continue; } if (!blackTurn && !hasAnyMoveW()) { currentMessage = "White(●) has no valid moves. Skipping Turn..."; drawBoard(cursorRow, cursorCol, blackTurn, false, currentMessage); Sleep(2000); currentMessage = ""; blackTurn=true; continue; } drawBoard(cursorRow, cursorCol, blackTurn, invalidMove, currentMessage); bool pressedEnter = cursor(cursorRow, cursorCol, blackTurn, invalidMove, currentMessage); if (!pressedEnter) {return;} invalidMove = false; currentMessage = ""; bool valid; if (blackTurn) {valid = possibleMoveB(cursorRow, cursorCol);} else {valid = possibleMoveW(cursorRow, cursorCol);} if (valid) { if (blackTurn) { placeB(cursorRow, cursorCol); flipB(cursorRow, cursorCol); } else { placeW(cursorRow, cursorCol); flipW(cursorRow, cursorCol); } blackTurn = !blackTurn; } else { invalidMove = true; } } } void gameOverM(string& s, string& t) { int cursorRow = 0; int cursorCol = 0; Player blackPlayer; Player whitePlayer; blackPlayer.name = s; blackPlayer.color = 'B'; blackPlayer.discs = blackCount(); whitePlayer.name = t; whitePlayer.color = 'W'; whitePlayer.discs = whiteCount(); string winnerMessage; string result; if (blackPlayer.discs > whitePlayer.discs) { winnerMessage = "Congrats " + blackPlayer.name + "! You Won!"; result = blackPlayer.name + " Won";} else if (blackPlayer.discs < whitePlayer.discs) { winnerMessage = "Congrats " + whitePlayer.name + "! You Won!"; result = whitePlayer.name + " Won";} else { winnerMessage = "It's a DRAW!"; result = "Draw";} saveHistory("Multiplayer", blackPlayer, whitePlayer, result); cursor(cursorRow, cursorCol, true, false, winnerMessage, true); } void saveHistory(const string& mode, const Player& black, const Player& white, const string& result) { ifstream inFile("History.txt"); string oldContent; string line; while (getline(inFile, line)) { oldContent += line+"\n"; } inFile.close(); ofstream outFile("History.txt"); if (!outFile) { cout<<"Error: Could not open History.txt for writing.\n"; return; } outFile<>n; if (n==1) { cout<<"Enter Your Name: "; cin>>s; cout<<"Choose Your Color (B/W): "; cin>>a; if (a=='B') { singlePlayerB(s);} if (a=='W') { singlePlayerW(s);} } if (n==2) { cout<<"Enter Your Name (P1 as Black): "; cin>>s; cout<<"Enter Your Name (P2 as White): "; cin>>t; multiPlayer(s, t); } } void menu() { system("cls"); cout<<" Welcome To Othello!"<>choice; if (choice==1) {newGame();} else if (choice==2) {help();} else if (choice == 3) {showHistory();} else if (choice==4) {return 0;} } }