#include #include #define SIZE_X 8 #define SIZE_Y 8 using namespace std; #include "Reversi_KI.h" void spielfeld_anzeigen(int spielfeld[SIZE_X][SIZE_Y]) { cout << " "; for (int j = 65; j < 65 + SIZE_Y; j++) { cout << ((char) j) << " "; } cout << endl; for (int i = 0; i < SIZE_X; i++) { cout << i + 1; for (int j = 0; j < SIZE_Y; j++) { switch (spielfeld[j][i]) { case 0: cout << " "; break; case 1: cout << " X"; break; case 2: cout << " O"; break; default: cout << "Inconsistent data in field! (spielfeld_anzeigen)" << endl; cout << "Aborting .... " << endl; exit(0); break; } }; // for j cout << endl; } // for i } int gewinner(int spielfeld[SIZE_X][SIZE_Y]) { int count_p1 = 0; int count_p2 = 0; for (int i = 0; i < SIZE_X; i++) { for (int j = 0; j < SIZE_Y; j++) { // loop through all fields + counting of X (1) and O (2) switch (spielfeld[j][i]) { case 0: /* empty field */ break; case 1: count_p1++; break; case 2: count_p2++; break; default: cout << "Inconsistent data in field! (gewinner)" << endl; cout << "Aborting .... " << endl; exit(0); break; } } } if (count_p1 == count_p2) { return 0; } if (count_p2 > count_p1) { return 2; } else { return 1; } } bool zug_gueltig(int spielfeld[SIZE_X][SIZE_Y], int spieler, int pos_x, int pos_y) { int gegner = 3 - spieler; /* toggle player */ if (spielfeld[pos_x][pos_y] != 0) // check if field is currently empty { return false; } for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { int p = 1; while (pos_x+p*i >= 0 && pos_x+p*i < SIZE_X && pos_y+p*j >= 0 && pos_y+p*j < SIZE_Y) { if (spielfeld[pos_x+i*p][pos_y+j*p] == gegner) /* a opponents stone * continue to look for own stone */ { p++; continue; } else if (spielfeld[pos_x+i*p][pos_y+j*p] == spieler && p > 1) /* oh, thats our stone! * and w've already seen a stone from out opponent (p > 0) * move is valid */ { return true; } else /* no stone or inconsistent playfield * move is invalid, continue with next opponent */ { break; } } } } return false; } bool zug_ausfuehren(int spielfeld[SIZE_X][SIZE_Y], int spieler, int pos_x, int pos_y) { int gegner = 3 - spieler; /* toggle player */ for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { int p = 1; while (pos_x+p*i >= 0 && pos_x+p*i < SIZE_X && pos_y+p*j >= 0 && pos_y+p*j < SIZE_Y) { if (spielfeld[pos_x+i*p][pos_y+j*p] == gegner) /* a opponents stone * continue to look for own stone */ { p++; continue; } else if (spielfeld[pos_x+i*p][pos_y+j*p] == spieler && p > 1) /* oh, thats our stone! * and w've already seen a stone from out opponent (p > 0) * move is valid */ { for (int q = 1; q <= p; q++) { /* turn stones */ spielfeld[pos_x+q*i][pos_y+q*j] = spieler; } break; } else /* no stone or inconsistent playfield * move is invalid, continue with next opponent */ { break; } } } } spielfeld[pos_x][pos_y] = spieler; return true; } int moegliche_zuege(int spielfeld[SIZE_X][SIZE_Y], int spieler) { int zuege = 0; for (int i = 0; i < SIZE_X; i++) { for (int j = 0; j < SIZE_Y; j++) { if (zug_gueltig(spielfeld, spieler, i, j)) { zuege++; } } } return zuege; } bool mensch_zug(int spielfeld[SIZE_X][SIZE_Y], int spieler) { if (moegliche_zuege(spielfeld, spieler) == 0) { return false; } int px; int py; bool repeat = false; do { if (repeat) { cout << "Invalid input !" << endl; } string eingabe; eingabe.reserve(50); cout << endl << "Player " << spieler << ": Your move (e.g. A1): "; eingabe.erase(eingabe.begin(), eingabe.end()); cin >> eingabe; px = ((int) eingabe.at(0)) - 65; py = ((int) eingabe.at(1)) - 49; } while ((repeat = !zug_gueltig(spielfeld, spieler, px, py))); zug_ausfuehren(spielfeld, spieler, px, py); return true; } void spiel(int spielertyp[2]) { int spielfeld[SIZE_X][SIZE_Y] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 1, 2, 0, 0, 0 }, { 0, 0, 0, 2, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } }; int aktueller_spieler = 1; spielfeld_anzeigen(spielfeld); // let each player make its moves until no further moves are possible while (moegliche_zuege(spielfeld, aktueller_spieler) > 0) { switch (spielertyp[aktueller_spieler-1]) { case 1: mensch_zug(spielfeld, aktueller_spieler); break; case 2: computer_zug(spielfeld, aktueller_spieler); break; default: cout << "Inconsistent data in field! (spiel)" << endl; cout << "Aborting .... " << endl; exit(0); break; } cout << endl; spielfeld_anzeigen(spielfeld); if (moegliche_zuege(spielfeld, 3 - aktueller_spieler)) { aktueller_spieler = 3 - aktueller_spieler; } } int winner = gewinner(spielfeld); switch (winner) { case 0: cout << "Das Spiel ist unentschieden ausgegangen!" << endl; break; case 1: case 2: cout << "Spieler " << winner << " hat gewonnen" << endl; break; } } int main(void) { int typ[2] = { 1, 2 }; spiel(typ); /* start game */ return 0; }