Compare commits
3 Commits
6442bf6b6d
...
claude-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef4f2d2cbf | ||
|
|
c057c9f3c1 | ||
|
|
cfbf7e9974 |
160
main.cpp
160
main.cpp
@@ -1,6 +1,5 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -8,11 +7,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
string spielfeld[3][3] = {
|
const int N = 3;
|
||||||
{" ", " ", " "},
|
|
||||||
{" ", " ", " "},
|
|
||||||
{" ", " ", " "}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct userInput {
|
struct userInput {
|
||||||
bool ok;
|
bool ok;
|
||||||
@@ -22,109 +17,120 @@ struct userInput {
|
|||||||
|
|
||||||
struct gameState {
|
struct gameState {
|
||||||
bool running = true;
|
bool running = true;
|
||||||
string winner;
|
char winner = ' ';
|
||||||
|
char board[N][N];
|
||||||
int filledCells = 0;
|
int filledCells = 0;
|
||||||
|
// Per-player (0=X, 1=O) counters for rows, cols, and both diagonals.
|
||||||
|
// Win-check is O(1): increment on each move, compare to N.
|
||||||
|
int rowCount[2][N] = {};
|
||||||
|
int colCount[2][N] = {};
|
||||||
|
int diagCount[2] = {};
|
||||||
|
int antiDiagCount[2] = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
void render() {
|
void render(const gameState &state) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
system("cls");
|
system("cls");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef linux
|
||||||
#ifdef linux
|
|
||||||
system("clear");
|
system("clear");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cout << " | 1 | 2 | 3 |" << endl;
|
cout << " | ";
|
||||||
cout << "---------------" << endl;
|
for (int j = 0; j < N; j++) cout << j + 1 << " | ";
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
cout << i+1 << " | ";
|
|
||||||
for (int j = 0; j < 3; j++) {
|
|
||||||
cout << spielfeld[i][j] << " | ";
|
|
||||||
}
|
|
||||||
cout << endl;
|
|
||||||
cout << "---------------" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
userInput getUserInput() {
|
|
||||||
int inputSpalte, inputZeile;
|
|
||||||
cout << "Zeile: ";
|
|
||||||
cin >> inputZeile;
|
|
||||||
cout << "Spalte: ";
|
|
||||||
cin >> inputSpalte;
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
if (spielfeld[inputZeile-1][inputSpalte-1] == " ") {
|
for (int i = 0; i < N * 4 + 3; i++) cout << "-";
|
||||||
return {true, inputZeile-1, inputSpalte-1};
|
cout << endl;
|
||||||
} else {
|
for (int i = 0; i < N; i++) {
|
||||||
cout << endl << "Input konnte nicht gelesen werden" << endl;
|
cout << i + 1 << " | ";
|
||||||
return getUserInput();
|
for (int j = 0; j < N; j++) cout << state.board[i][j] << " | ";
|
||||||
|
cout << endl;
|
||||||
|
for (int k = 0; k < N * 4 + 3; k++) cout << "-";
|
||||||
|
cout << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkforWin(gameState &state) {
|
userInput getUserInput(const gameState &state) {
|
||||||
// TODO: implement a proper efficent check that doesnt end when every tile is filled
|
while (true) {
|
||||||
// simplest way would be to check all 8 different solutions. 3 from top to bottom, 3 from left to right and 2 diagonals
|
int inputZeile, inputSpalte;
|
||||||
for (int i = 0; i < 3; i++) {
|
cout << "Zeile: ";
|
||||||
// left to right
|
cin >> inputZeile;
|
||||||
if (spielfeld[i][0] == spielfeld[i][1] && spielfeld[i][2] == spielfeld[i][1] && spielfeld[i][2] != " ") {
|
cout << "Spalte: ";
|
||||||
state.running = false;
|
cin >> inputSpalte;
|
||||||
state.winner = spielfeld[i][1];
|
cout << endl;
|
||||||
return;
|
|
||||||
|
if (!cin) {
|
||||||
|
cin.clear();
|
||||||
|
cin.ignore(1000, '\n');
|
||||||
|
cout << "Ungueltige Eingabe, bitte nochmal." << endl;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
// top to bottom
|
|
||||||
if (spielfeld[0][i] == spielfeld[1][i] && spielfeld[1][i] == spielfeld[2][i] && spielfeld[1][i] != " ") {
|
if (inputZeile >= 1 && inputZeile <= N &&
|
||||||
state.running = false;
|
inputSpalte >= 1 && inputSpalte <= N &&
|
||||||
state.winner = spielfeld[1][i];
|
state.board[inputZeile - 1][inputSpalte - 1] == ' ') {
|
||||||
return;
|
return {true, inputZeile - 1, inputSpalte - 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cout << "Feld bereits belegt oder ausserhalb des Spielfelds." << endl;
|
||||||
}
|
}
|
||||||
// top left to bottom right
|
}
|
||||||
if (spielfeld[0][0] == spielfeld[1][1] && spielfeld[1][1] == spielfeld[2][2] && spielfeld[2][2] != " ") {
|
|
||||||
|
void checkforWin(gameState &state, int zeile, int spalte, char player) {
|
||||||
|
int p = (player == 'X') ? 0 : 1;
|
||||||
|
|
||||||
|
state.rowCount[p][zeile]++;
|
||||||
|
state.colCount[p][spalte]++;
|
||||||
|
if (zeile == spalte) state.diagCount[p]++;
|
||||||
|
if (zeile + spalte == N - 1) state.antiDiagCount[p]++;
|
||||||
|
|
||||||
|
if (state.rowCount[p][zeile] == N ||
|
||||||
|
state.colCount[p][spalte] == N ||
|
||||||
|
state.diagCount[p] == N ||
|
||||||
|
state.antiDiagCount[p] == N) {
|
||||||
state.running = false;
|
state.running = false;
|
||||||
state.winner = spielfeld[2][2];
|
state.winner = player;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// top right to bottom left
|
if (state.filledCells >= N * N) {
|
||||||
if (spielfeld[0][2] == spielfeld[1][1] && spielfeld[1][1] == spielfeld[2][0] && spielfeld[2][0] != " ") {
|
|
||||||
state.running = false;
|
state.running = false;
|
||||||
state.winner = spielfeld[2][0];
|
state.winner = '-';
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw
|
|
||||||
if (state.filledCells >= 9) {
|
|
||||||
state.running = false;
|
|
||||||
state.winner = "-";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
SetConsoleOutputCP(CP_UTF8);
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
#endif
|
#endif
|
||||||
cout << fixed << setprecision(2);
|
|
||||||
|
|
||||||
gameState state;
|
gameState state;
|
||||||
|
for (int i = 0; i < N; i++)
|
||||||
|
for (int j = 0; j < N; j++)
|
||||||
|
state.board[i][j] = ' ';
|
||||||
|
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
while (state.running) {
|
while (state.running) {
|
||||||
render();
|
render(state);
|
||||||
string current_player = counter++ % 2 == 1 ? "X" : "O";
|
char current_player = counter++ % 2 == 1 ? 'X' : 'O';
|
||||||
cout << endl << "Am Zug ist Spieler: " << current_player << endl;
|
cout << endl << "Am Zug ist Spieler: " << current_player << endl;
|
||||||
if (auto [ok, zeile, spalte] = getUserInput(); ok) {
|
auto [ok, zeile, spalte] = getUserInput(state);
|
||||||
spielfeld[zeile][spalte] = current_player;
|
if (ok) {
|
||||||
state.filledCells += 1;
|
state.board[zeile][spalte] = current_player;
|
||||||
|
state.filledCells++;
|
||||||
|
checkforWin(state, zeile, spalte, current_player);
|
||||||
}
|
}
|
||||||
checkforWin(state);
|
|
||||||
}
|
}
|
||||||
render();
|
|
||||||
cout << endl << "Der gewinner ist: " << state.winner << endl;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
render(state);
|
||||||
|
if (state.winner == '-') {
|
||||||
|
cout << endl << "Unentschieden!" << endl;
|
||||||
|
} else {
|
||||||
|
cout << endl << "Der Gewinner ist: " << state.winner << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
system("pause");
|
system("pause");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user