// // clobberopgave3.cc // C++ programma dat meerpersoons Clobber speelt // compileren: g++ -Wall -O2 -o clobber clobberopgave3.cc // aanroep: ./clobber [hoogte] [breedte] [playouts] [seed] [spellen] // [slimme-speler 0/1/...] [slimme-speler 0/1/...] // [printen 0/1] [spelers] // [parameter 1] [parameter 2] // bij 0: 0 speelt "slim", 1 idem, etc. // de member-variabele laatstezet bevat de laatste speler die echt zette // Walter Kosters, 23 maart 2017; versie 2.1 // #include #include using namespace std; const int MAX = 20; const int GROOT = 100000; int m, n; // hoogte en breedte van het bord, <= MAX int playouts; // aantal playouts bij Monte Carlo (MC) bool printen; // printen we de spelletjes? int spelers; // aantal spelers, <= MAX int param1; // parameter voor eerste slimme speler int param2; // parameter voor tweede slimme speler class clobber { private: short bord[MAX][MAX]; int beurt; short passen; short laatstezet; public: clobber ( ); void init ( ); void print ( ); int aantalzetten ( ); void doezet (int k); short randomspel ( ); short slimspel (short speler1, short speler2); void doenulzet ( ); void slimmezet1 (int param); void slimmezet2 (int param); };//clobber //constructor clobber::clobber ( ) { //init ( ); }//clobber::clobber //beginstand opzetten; waarde "spelers" betekent leeg void clobber::init ( ) { int i, j; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) bord[i][j] = rand ( ) % spelers; beurt = 0; passen = 0; laatstezet = spelers + 1; }//clobber::init //hoeveel zetten zijn er mogelijk voor de speler die nu aan de beurt is? int clobber::aantalzetten ( ) { int teller = 0, i, j; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) if ( bord[i][j] == beurt % spelers ) { if ( i > 0 && bord[i-1][j] != bord[i][j] && bord[i-1][j] != spelers ) teller++; if ( j > 0 && bord[i][j-1] != bord[i][j] && bord[i][j-1] != spelers ) teller++; if ( j < n-1 && bord[i][j+1] != bord[i][j] && bord[i][j+1] != spelers ) teller++; if ( i < m-1 && bord[i+1][j] != bord[i][j] && bord[i+1][j] != spelers ) teller++; }//if return teller; }//clobber::aantalzetten //doe k-de mogelijke zet void clobber::doezet (int k) { int teller = 0, i, j; passen = 0; laatstezet = beurt % spelers; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) if ( bord[i][j] == beurt % spelers ) { if ( i > 0 && bord[i-1][j] != bord[i][j] && bord[i-1][j] != spelers ) { if ( teller == k ) { bord[i][j] = spelers; bord[i-1][j] = beurt % spelers; beurt++; return; }//if teller++; }//if if ( j > 0 && bord[i][j-1] != bord[i][j] && bord[i][j-1] != spelers ) { if ( teller == k ) { bord[i][j] = spelers; bord[i][j-1] = beurt % spelers;; beurt++; return; }//if teller++; }//if if ( j < n-1 && bord[i][j+1] != bord[i][j] && bord[i][j+1] != spelers ) { if ( teller == k ) { bord[i][j] = spelers; bord[i][j+1] = beurt % spelers; beurt++; return; }//if teller++; }//if if ( i < m-1 && bord[i+1][j] != bord[i][j] && bord[i+1][j] != spelers ) { if ( teller == k ) { bord[i][j] = spelers; bord[i+1][j] = beurt % spelers; beurt++; return; }//if teller++; }//if }//if }//clobber::doezet //print spelbord void clobber::print ( ) { int i, j; cout << "Toestand " << beurt << endl << " "; for ( j = 0; j < n; j++ ) cout << " " << j % 10; cout << endl; for ( i = 0; i < m; i++ ) { cout << i << " "; for ( j = 0; j < n; j++ ) if ( bord[i][j] == spelers ) cout << " ."; else if ( bord[i][j] < 10 ) cout << " " << bord[i][j]; else cout << " " << bord[i][j]; cout << endl; }//for cout << "Speler " << beurt % spelers << " is aan de beurt" << endl << endl; }//clobber::clobber //passen void clobber::doenulzet ( ) { beurt++; passen++; }//clobber::doenulzet //speel random potje short clobber::randomspel ( ) { int aantal = aantalzetten ( ); short winnaar = 100; if ( printen ) print ( ); while ( passen < spelers ) { if ( aantal > 0 ) { winnaar = beurt % spelers; doezet (rand ( ) % aantal); }//if else doenulzet ( ); if ( printen ) print ( ); aantal = aantalzetten ( ); }//while return winnaar; }//clobber::randomspel //doe een slim spel, waarbij speler1 en speler2 slim spelen //en de rest random, mits param1 ongelijk 0, idem param2 short clobber::slimspel (short speler1, short speler2) { int aantal = aantalzetten ( ); short winnaar = 100; bool oldprinten = printen; if ( printen ) print ( ); while ( passen < spelers ) { if ( aantal > 0 ) { winnaar = beurt % spelers; if ( winnaar == speler1 && param1 != 0 ) { printen = false; slimmezet1 (param1); printen = oldprinten; }//if else if ( winnaar == speler2 && param2 != 0 ) { printen = false; slimmezet2 (param2); printen = oldprinten; }//if else { doezet (rand( ) % aantal); }//else }//if else doenulzet ( ); if ( printen ) print ( ); aantal = aantalzetten ( ); }//while // cout << winnaar << " heeft gewonnen." << endl; return winnaar; }//clobber::slimspel //bepaal slimme = minimax/alpha-beta zet voor de huidige speler, //die > 0 zetten heeft, met versie param void clobber::slimmezet1 (int param) { int bestezet = 0; //TODO doezet (bestezet); }//clobber::slimmezet1 //bepaal nog een slimme = minimax/alpha-beta zet voor de huidige speler, //die > 0 zetten heeft, met versie param void clobber::slimmezet2 (int param) { int bestezet = 0; //TODO doezet (bestezet); }//clobber::slimmezet2 int main (int argc, char* argv[ ]) { int gewonnen[MAX] = {0}; int i; if ( argc != 12 ) { cout << "Aanroepen met: " << endl << argv[0] << " [hoogte] [breedte] [playouts] [seed] [spellen] " << "[slimme speler 1] [slimme speler 2] [printen 0/1] [spelers] " << "[param1] [param2]" << endl; return 1; }//if m = atoi (argv[1]); n = atoi (argv[2]); if ( m > MAX || n > MAX ) { cout << "Bord te groot!" << endl; return 1; }//if playouts = atoi (argv[3]); srand (atoi (argv[4])); int spellen = atoi (argv[5]); short speler1 = atoi (argv[6]); short speler2 = atoi (argv[7]); short result; printen = ( argv[8][0] == '1' ); spelers = atoi (argv[9]); if ( spelers > MAX ) { cout << "Teveel spelers!" << endl; return 1; }//if param1 = atoi (argv[10]); param2 = atoi (argv[11]); clobber clob; for ( i = 0; i < spellen; i++ ) { clob.init ( ); result = clob.slimspel (speler1,speler2); if ( result == 100 ) cout << "REMISE" << endl; else gewonnen[result]++; }//for cout << "Einduitslag: ["; for ( i = 0; i < spelers - 1; i++ ) cout << gewonnen[i] << ","; cout << gewonnen[spelers-1] << "] / " << spellen << " (totaal)" << endl; return 0; }//main