#include #include #include #include #define N 5 #define EMPTY 0 #define BLACK 1 #define WHITE 2 /* Spielfeld */ int field[N][N]; /* Welcher Kreuzungspunkt gehoert zu welcher Gruppe. Ein Kreuzungspunkt * zeigt auf einen anderen und der wieder auf einen anderen etc. indem * group[i][j] = N*i2+j2 gesetzt wird, wobei dann i/j auf i2/j2 zeigt. * Zeigt ein Kreuzungspunkt auf sich selbst, so ist er der Repraesentant * seiner Gruppe. */ int group[N][N]; int pts[3]; int other (int col) { switch (col) { case BLACK: return WHITE; case WHITE: return BLACK; } assert (0); /* NOT REACHED */ return EMPTY; } void groups (void); void freedoms (void); int root (int si, int sj); /* Spielfeld zeichnen. */ void draw (void) { int i, j; char ch = 0; printf (" +"); for (i=0; i<2*N+1; ++i) { printf ("-"); } printf ("+\n"); for (i=N-1; i>=0; --i) { printf ("%2d | ", i+1); for (j=0; j= N) return; if (j >= N) return; if (field[i][j] == EMPTY) return; freedom[root (i,j)] = 1; } /* Testen, ob die Gruppe an i/j eine Freiheit hat. */ int has_freedom (int i, int j) { if (i < 0) return -1; if (j < 0) return -1; if (i >= N) return -1; if (j >= N) return -1; if (field[i][j] == EMPTY) return -1; return freedom[root (i, j)]; } /* Gruppen mit und ohne Freiheiten bestimmen. Dazu gehen wir alle * leeren Kreuzungspunkte durch und rufen fuer die benachbarten Gruppen * set_freedom auf. */ void freedoms (void) { int i, j; groups (); for (i=0; i= N) || (j >= N)) return 0; if (field[i][j] != EMPTY) return 0; if ((col != BLACK) && (col != WHITE)) return 0; field[i][j] = col; freedoms (); if ((has_freedom (i-1, j) == 0) && (field[i-1][j] != col)) removegroup (i-1, j); if ((has_freedom (i+1, j) == 0) && (field[i+1][j] != col)) removegroup (i+1, j); if ((has_freedom (i, j-1) == 0) && (field[i][j-1] != col)) removegroup (i, j-1); if ((has_freedom (i, j+1) == 0) && (field[i][j+1] != col)) removegroup (i, j+1); /* Freiheiten neu berechnen falls Gruppen geloescht wurden. */ freedoms (); if (has_freedom (i,j) != 1) { field[i][j] = EMPTY; return 0; } return 1; } int main () { int i, j, col = BLACK; char sign[3] = " #O"; char buf[100]; for (i=0; i 0) { pts[col]--; } else { break; } col = other (col); continue; } if (sscanf (buf, "%c%d", &tmp, &i) != 2) { printf ("Illegal move\n"); continue; } i--; j = tmp - 'A'; if (domove (i, j, col)) { col = other (col); } else { printf ("Illegal move\n"); } } draw (); if (col == WHITE) { printf ("BLACK(#) WINS\n"); } else { assert (col == BLACK); printf ("WHITE(O) WINS\n"); } return 0; }