/* 4 Gewinnt mit Computerspieler 2001 Stefan Reiss www.reisz.de*/ #include using namespace std; #define ZEILEN 6 #define SPALTEN 7 #define MAXZEILE (ZEILEN-1) #define forint(i,a,b) for(int i=a;i!=b;++i) #define forr(r) forint(r,0,ZEILEN) #define fors(s) forint(s,0,SPALTEN) #define LEER 0 #define ROT 1 #define GELB 2 typedef int feld_t[ZEILEN][SPALTEN]; // als parametertyp um ein feld zu uebergeben feld_t feld; // das Feld int * stack_f [50]; int sp = 0; // fuer undo #define erlaubt(feld,s) (!(feld[MAXZEILE][s])) //ist zug erlaubt const char plchar[] = ".#O"; // fuer Ausdrucken inline void setze(feld_t feld, int s , int farbe) { forr(r) if(!feld[r][s]) { feld[r][s]=farbe; break; }} inline void setze_hin (feld_t feld, int s , int farbe) { forr(r) if(!feld[r][s]) { *(stack_f[sp++]=&feld[r][s]) = farbe; break; }} inline void setze_zurueck() {*stack_f[--sp] = LEER; } void clear(){ memset (feld,0,sizeof(feld)); sp=0; } void drucke(feld_t feld) { forr(r) { fors(s) cout << plchar[feld[MAXZEILE-r][s]] << ' '; cout << "\n"; } } // 'gewichte : punkte fuer reihen mit 1,2,3,4 gleichen ohne fremde const int weight [] = { 0,1,10,100,10000 }; #define forsum4(xp) { for(sum=0,i=0;i<4;++i)\ if((xp)==f) ++sum; else if((xp)) {sum=0; break;} val+=weight[sum]; } // Wert einer Stellung fuer Farbe f int wertf(feld_t feld, int f) { int i,sum,val = 0; // (4 dreifache schleifen) { fors(s) forint(r,0,ZEILEN -3) forsum4(feld[r+i][s]); } { forr(r) forint(s,0,SPALTEN-3) forsum4(feld[r][s+i]); } { forint(s,0,SPALTEN -3) forint(r,0,ZEILEN -3) forsum4(feld[r+i][s+i]); } { forint(s,3,SPALTEN ) forint(r,0,ZEILEN -3) forsum4(feld[r+i][s-i]); } return val; } //wert fuer aktuelle Farbe #define wertx(feld,dran) (wertf(feld,dran) - wertf(feld,(dran)^3)) // liefert den wert nach vorausberechnung von n zuegen // aus Sicht des spielers 'dran'; bester zug int 'bz' int wert_n (feld_t feld ,int dran , int depth, int & bz) { int w = wertx(feld,dran); if (depth == 0 || abs(w)>5000) { bz=-1; return w;} //schon zuende int bestwert = -100000, bestzug = -1; fors(s) // teste alle moeglichen zuege { if (erlaubt(feld,s)) { setze_hin(feld,s,dran); // mache zug int w = -wert_n(feld,dran^3,depth -1,bz); // berechne wert if (w > bestwert) { bestwert = w; bestzug = s; } setze_zurueck(); if (bestwert > 5000) break; // gewinnt schon } } bz = bestzug; return bestwert; } void main() { char line[5]; int dran = ROT, bz, depth = 4; for(;;) { drucke(feld); cout << plchar[dran] << "\n"; if (abs(wertx(feld,dran)) > 5000) { cout << "fertig\n"; } cin >> line; if (line[0] == 's') { dran^=3; } if (line[0] == 'w') { cout << wert_n (feld,dran,depth,bz) << "\n"; } if (line[0] == 'm') { wert_n(feld,dran,depth,bz); cout << "->" << bz << "\n"; if(bz!=-1) { setze_hin(feld,bz,dran); dran ^= 3;}} if (line[0] == 'x') break; if (line[0] == 'c') { clear(); dran = ROT; } if (line[0] == 'z') { setze_zurueck(); dran^=3; } if (line[0] == 'd') { depth = atoi(line+1); } if (isdigit(line[0])) { int s = atoi(line); if (erlaubt(feld,s)) { setze_hin(feld,s,dran); dran ^= 3; } else cout << "verboten\n"; } } }