2 Incheckningar 894e79daa4 ... 84aeae7154

Upphovsman SHA1 Meddelande Datum
  jpenguin 84aeae7154 Changed gameOver to use an external function to check if three in a row are X or 0 2 år sedan
  jpenguin 3bad3ce8c4 Cleaned up, spit functions, can now randomize when against AI, fewer global variables 2 år sedan
2 ändrade filer med 178 tillägg och 161 borttagningar
  1. 1 1
      CMakeLists.txt
  2. 177 160
      main.cpp

+ 1 - 1
CMakeLists.txt

@@ -3,7 +3,7 @@ project(TicTacToe)
 
 set(CMAKE_CXX_STANDARD 14)
 
-include_directories(extern/cpackets)
+include_directories(extern)
 include_directories(.)
 
 add_executable(TicTacToe

+ 177 - 160
main.cpp

@@ -6,206 +6,223 @@
 #include <string>
 #include <algorithm>
 #include <cstdlib>
-#include "conio.h"
+#include "cpackets/conio.h"
 
 using namespace std;
 
-void drawBoard(string playerNames[2]);
+void newGame(string playerNames[2]);
+void nextTurn(string playerNames[2]);
+void drawBoard();
 void inputCoordinates(string playerNames[2]);
-void randomAI(string playerNames[2]);
+void randomAI();
 void clearBoard();
-bool checkWin(string playerNames[2]);
-void newGame(string playerNames[2]);
+bool gameOver();
 void clearScreen();
 
-char grid[3][3], numPayers;
+char grid[3][3];
 
 short turns;
 
-bool won;
+template<typename T, typename U>
+bool allEqual(const T &t, const U &u)
+{
+    return t == u;
+}
+
+template<typename T, typename U, typename... Others>
+bool allEqual(const T &t, const U &u, Others const &...args)
+{
+    return (t == u) && allEqual(u, args...);
+}
 
 int main()
 {
-	string playerNames[2];
-	int n = sizeof(playerNames) / sizeof(playerNames[0]);
-	cout << "\nOne or two players? (1/2) ";
-	do {
-		numPayers = getche();
-		cout << endl;
-		switch (numPayers) {
-			case '1': cout << "\nPlayer one, enter you name: ";
-				getline(cin, playerNames[0]);
-				playerNames[1] = "The Computer";
-				break;
-			case '2': cout << "\nPlayer one, enter you name: ";
-				getline(cin, playerNames[0]);
-				cout << "\nPlayer two, enter you name: ";
-				getline(cin, playerNames[1]);
-				cout << "Randomize who goes first? (y/n)";
-				if (getch() == 'y' || getch() == 'Y')
-					shuffle(playerNames, playerNames + n, mt19937(random_device()()));
-				//else
-				//	cout << "no";
-				break;
-			default: numPayers = 'E';
-				//cout << "default";
-				break;
-		}
-	}
-	while (numPayers == 'E');
-	cout << endl;
-	newGame(playerNames);
-	return 0;
+    string playerNames[2];
+    char numPlayers;
+    int n = sizeof(playerNames) / sizeof(playerNames[0]);
+    cout << "\nOne or two players? (1/2) ";
+    do {
+        numPlayers = getche();
+        cout << endl;
+        switch (numPlayers) {
+        case '1':
+            cout << "\nPlayer one, enter you name: ";
+            getline(cin, playerNames[0]);
+            playerNames[1] = "The Computer";
+            break;
+        case '2':
+            cout << "\nPlayer one, enter you name: ";
+            getline(cin, playerNames[0]);
+            cout << "\nPlayer two, enter you name: ";
+            getline(cin, playerNames[1]);
+            // else
+            //	cout << "no";
+            break;
+        default:
+            numPlayers = '0';
+            // cout << "default";
+            break;
+        }
+    } while (numPlayers == '0');
+    cout << "Randomize who goes first? (y/n)";
+    if (getch() == 'y' || getch() == 'Y')
+        shuffle(playerNames, playerNames + n, mt19937(random_device()()));
+
+    cout << endl;
+    newGame(playerNames);
+    return 0;
 }
 
 void newGame(string playerNames[2])
 {
-	clrscr();
-	won = false;
-	turns = 0;
-        clearBoard();
-	drawBoard(playerNames);
+    clearScreen();
+    turns = 0;
+    clearBoard();
+    nextTurn(playerNames);
 }
-void drawBoard(string playerNames[2])
+void nextTurn(string playerNames[2])
+{
+    drawBoard();
+
+    if (playerNames[turns % 2].compare("The Computer") == 0)
+        randomAI();
+    else
+        inputCoordinates(playerNames); // player goes first
+
+    if (gameOver()) {
+        drawBoard();
+        if (turns == 8) {
+            nextTurn(playerNames);
+            cout << "Draw\nPlay again (y/n):  ";
+            cin.ignore();
+            if (getch() == 'y' || getch() == 'Y')
+                main();
+            else {
+                cout << endl;
+                exit(0);
+            }
+        } else {
+            cout << playerNames[turns % 2] << " has won\n\nPlay again (y/n):  ";
+            cin.ignore(100, '\n');
+            if (getch() == 'y' || getch() == 'Y')
+                main();
+            else {
+                cout << endl;
+                exit(0);
+            }
+        }
+    }
+    turns++;
+    nextTurn(playerNames);
+}
+
+void drawBoard()
 {
     clearScreen();
 
-	cout << "---+---+---+---|\n";
-	cout << "2  |" << setw(3) << grid[2][0] << "|" << setw(3) << grid[2][1]
-		 << "|" << setw(3) << grid[2][2] << "|\n";
-	cout << "---+---+---+---|\n";
-	cout << "1  |" << setw(3) << grid[1][0] << "|" << setw(3) << grid[1][1]
-		 << "|" << setw(3) << grid[1][2] << "|\n";
-	cout << "---+---+---+---|\n";
-	cout << "0  |" << setw(3) << grid[0][0] << "|" << setw(3) << grid[0][1]
-		 << "|" << setw(3) << grid[0][2] << "|\n";
-	cout << "---+---+---+---|\n";
-	cout << "   | 0 | 1 | 2 |\n";
-
-	if (!won)
-		inputCoordinates(playerNames); // player goes first
+    cout << "---+---+---+---|\n";
+    cout << "2  |" << setw(3) << grid[2][0] << "|" << setw(3) << grid[2][1] << "|" << setw(3)
+         << grid[2][2] << "|\n";
+    cout << "---+---+---+---|\n";
+    cout << "1  |" << setw(3) << grid[1][0] << "|" << setw(3) << grid[1][1] << "|" << setw(3)
+         << grid[1][2] << "|\n";
+    cout << "---+---+---+---|\n";
+    cout << "0  |" << setw(3) << grid[0][0] << "|" << setw(3) << grid[0][1] << "|" << setw(3)
+         << grid[0][2] << "|\n";
+    cout << "---+---+---+---|\n";
+    cout << "   | 0 | 1 | 2 |\n";
 }
 
 void clearBoard()
 {
-	// for (int a = 0; a < 3; a++) {
-	for (auto &a: grid) {
-		for (char &b: a) {
-			b = ' ';
-		}
-	}
+    // for (int a = 0; a < 3; a++) {
+    for (auto &a : grid) {
+        for (char &b : a) {
+            b = ' ';
+        }
+    }
 }
 
-bool checkWin(string playerNames[2])
+bool gameOver()
 {
-	char playAgain;
-	// rows
-	if ((grid[0][0] == grid[0][1]) && (grid[0][1] == grid[0][2])
-		&& (grid[0][1]) != ' ')
-		won = true;
-	else if ((grid[1][0] == grid[1][1]) && (grid[1][1] == grid[1][2])
-		&& (grid[1][1]) != ' ')
-		won = true;
-	else if ((grid[2][0] == grid[2][1]) && (grid[2][1] == grid[2][2])
-		&& (grid[2][1]) != ' ')
-		won = true;
-		// columns
-	else if ((grid[0][0] == grid[1][0]) && (grid[1][0] == grid[2][0])
-		&& (grid[2][0]) != ' ')
-		won = true;
-	else if ((grid[0][1] == grid[1][1]) && (grid[1][1] == grid[2][1])
-		&& (grid[2][1]) != ' ')
-		won = true;
-	else if ((grid[0][2] == grid[1][2]) && (grid[1][2] == grid[2][2])
-		&& (grid[2][2]) != ' ')
-		won = true;
-		// diagonal
-	else if ((grid[0][0] == grid[1][1]) && (grid[1][1] == grid[2][2])
-		&& (grid[2][2]) != ' ')
-		won = true;
-	else if ((grid[2][0] == grid[1][1]) && (grid[1][1] == grid[0][2])
-		&& (grid[0][2]) != ' ')
-		won = true;
-	else if (turns == 8) {
-		won = true;
-		drawBoard(playerNames);
-		cout << "Draw\nPlay again (y/n):  ";
-		cin.ignore();
-                playAgain = getch();
-		if (playAgain == 'y' || playAgain == 'Y')
-			main();
-		else {
-			cout << endl;
-			exit(0);
-		}
-	}
-	else
-		return false;
-
-	if (won) {
-		drawBoard(playerNames);
-
-		cout << playerNames[turns % 2] << " has won\n\nPlay again (y/n):  ";
-		cin.ignore();
-                playAgain = getch();
-		if (playAgain == 'y' || playAgain == 'Y')
-			main();
-		else {
-			cout << endl;
-			exit(0);
-		}
-	}
+    // rows
+    if (allEqual(grid[0][0], grid[0][1], grid[0][2], 'X')
+        || allEqual(grid[0][0], grid[0][1], grid[0][2], 'O'))
+        return true;
+    else if (allEqual(grid[1][0], grid[1][1], grid[1][2], 'X')
+             || allEqual(grid[1][0], grid[1][1], grid[1][2], 'O'))
+        return true;
+    else if (allEqual(grid[2][0], grid[2][1], grid[2][2], 'X')
+             || allEqual(grid[2][0], grid[2][1], grid[2][2], 'O'))
+        return true;
+    /*if ((grid[0][0] == grid[0][1]) && (grid[0][1] == grid[0][2]) && (grid[0][1]) != ' ') {
+        return true;
+    } else if ((grid[1][0] == grid[1][1]) && (grid[1][1] == grid[1][2]) && (grid[1][1]) != ' ') {
+        return true;
+    } else if ((grid[2][0] == grid[2][1]) && (grid[2][1] == grid[2][2]) && (grid[2][1]) != ' ') {
+        return true;
+    }*/
+    // columns
+    else if ((grid[0][0] == grid[1][0]) && (grid[1][0] == grid[2][0]) && (grid[2][0]) != ' ') {
+        return true;
+    } else if ((grid[0][1] == grid[1][1]) && (grid[1][1] == grid[2][1]) && (grid[2][1]) != ' ') {
+        return true;
+    } else if ((grid[0][2] == grid[1][2]) && (grid[1][2] == grid[2][2]) && (grid[2][2]) != ' ') {
+        return true;
+    }
+    // diagonal
+    else if (allEqual(grid[0][0], grid[1][1], grid[2][2], 'X')
+             || allEqual(grid[0][0], grid[1][1], grid[2][2], 'O'))
+        return true;
+    else if (allEqual(grid[2][0], grid[1][1], grid[0][2], 'X')
+             || allEqual(grid[2][0], grid[1][1], grid[0][2], 'O'))
+        return true;
+    /*else if ((grid[0][0] == grid[1][1]) && (grid[1][1] == grid[2][2]) && (grid[2][2]) != ' ')
+        return true;
+    else if ((grid[2][0] == grid[1][1]) && (grid[1][1] == grid[0][2]) && (grid[0][2]) != ' ')
+        return true;*/
+    else if (turns > 7)
+        return true;
+
+    return false;
 }
 
 void inputCoordinates(string playerNames[2])
 {
-	int x, y;
-	do {
-		cout << playerNames[turns % 2] << ", what square would you like (x y):  ";
-		cin >> y >> x;
-	}
-	while (grid[x][y] != ' ');
-	if (turns % 2)
-		grid[x][y] = 'O';
-	else
-		grid[x][y] = 'X';
-
-	checkWin(playerNames);
-	turns++;
-	if (numPayers == '1')
-            randomAI(playerNames); // random randomAI
-	else
-		drawBoard(playerNames);
+    int x, y;
+    do {
+        cout << playerNames[turns % 2] << ", what square would you like (x y):  ";
+        cin >> y >> x;
+    } while (grid[x][y] != ' ');
+    if (turns % 2)
+        grid[x][y] = 'O';
+    else
+        grid[x][y] = 'X';
 }
 
-void randomAI(string playerNames[2])
+void randomAI()
 {
-	unsigned x, y;
-
-	//if (grid[0][0] == ' ')
-	//	grid[0][0] = 'O';
-	//else {
-	do {
-		random_device dev;
-		mt19937 rng(dev());
-		uniform_int_distribution<mt19937::result_type> mark(0, 2);
-		x = mark(rng);
-		y = mark(rng);
-	}
-	while (grid[x][y] != ' ');
-	grid[x][y] = 'O';
-	//}
-
-	(checkWin(playerNames));
-	turns++;
-	drawBoard(playerNames); // Draw board before players next turn
+    unsigned x, y;
+
+    do {
+        random_device dev;
+        mt19937 rng(dev());
+        uniform_int_distribution<mt19937::result_type> mark(0, 2);
+        x = mark(rng);
+        y = mark(rng);
+    } while (grid[x][y] != ' '); // Repeat until blank square is found
+
+    if (turns % 2)
+        grid[x][y] = 'O';
+    else
+        grid[x][y] = 'X';
 }
 
 void clearScreen()
 {
 #ifdef _WIN32
-	system("cls");
+    system("cls");
 #else
-	system("clear");
+    system("clear");
 #endif
 }