/*programeeropdracht 4 The Nim Game *Pascal de Vos (ID = 0446916) *Rick van der Zwet (ID = 0433373) *file: nimSpel.cc *de is het rekengedeelte van mainForm.cc, hierin kan makkelijk en snel *gegevens worden verwerkt en oplossingen worden doorgerekend */ #include "nimSpel.h" #include "const.h" #include using namespace std; NimSpel::NimSpel( ){ //constructor laatsteZet_pt = NULL; aantalZetten = 0; } //end NimSpel::NimSpel //aantal beurten terug geven int NimSpel::aantalBeurten( ){ return( aantalZetten/2 ); } //end NimSpel::aantalBeurten //aantal op stapel teruggeven int NimSpel::aantalOpStapel( const int nummer ){ return( stapel[nummer] ); } //end NimSpel::aantalOpStapel //aantal actieve stapels teruggeven int NimSpel::actieveStapels( ){ return( aantalStapels ); } //end NimSpel::actieveStapels bool NimSpel::afgelopen( ){ //kijken of spel afgelopen is for( int i = 0; i < MAX_STAPELS; i++ ) { if( stapel[i] > 0 ) { //als er nog ergens waardes aanwezig zijn return( false ); }//end if }//end if return( true ); }//end NimSpel::afgelopen //zet de beginwaarden van de stapel void NimSpel::beginWaarden( const int stapelAantal, const int aantal) { zetTerug(aantalZetten/2); //terugzetten om oude pointer naar NULL te //helpen en alles netjes de destructen for( int i = 0; i < stapelAantal; i++ ) { stapel[i] = aantal; aantalStapels = stapelAantal; } //end for } //end NimSpel::beginWaarden //creer een nieuwe zet voor de computer void NimSpel::computerZet( const bool niveauComputer, int & stapelNummer, int & aantal) { int tmpStapelNummer = -1; int tmpAantal = -1; if( niveauComputer ) { //winnend spelen als dat verwacht wordt winnend( tmpStapelNummer, tmpAantal ); } //end if if( tmpAantal == -1 ) { //hij zal in deze if komen als er geen winnnende keuzes zijn randomZet( tmpStapelNummer, tmpAantal ); } //end if stapelNummer = tmpStapelNummer; aantal = tmpAantal; } //end NimSpel::computerZet //doe een random zet, die wel in de range van een stapel aantal ligt void NimSpel::randomZet( int & stapelNummer, int & aantal ) { do { stapelNummer = int( double(aantalStapels) * rand()/(RAND_MAX+1.0) ); aantal = 1 + int( double(2) * rand()/(RAND_MAX+1.0) ); } //end do while( stapel[stapelNummer] - aantal < 0 ); }//end NimSpel::randomZet //verwerk een zet void NimSpel::pakWeg( const int stapelNummer, const int aantal ){ NimStapel * temp_pt; // temp_pt = new NimStapel; // temp_pt->vorigeZet_pt = laatsteZet_pt; //Zetten onthouden laatsteZet_pt = temp_pt; // laatsteZet_pt->stapelNummer = stapelNummer; // laatsteZet_pt->aantalEraf = aantal; // aantalZetten++; //Max Zetten bijhouden stapel[stapelNummer] = stapel[stapelNummer] - aantal; } //end NimSpel::pakweg //Controleer of er precies 1 stapel is met een waarde lager dan 2 //Begin standaard met true en controleer op foute waardes bool NimSpel::winstAfgelopen() { bool einde = true; int stapelsMetWaarde = 0; int totaalWaarde = 0; for( int ctr=0; ctr < aantalStapels; ctr++ ) { if( stapel[ctr] > 0 ) { totaalWaarde = totaalWaarde + stapel[ctr]; stapelsMetWaarde++; if( (totaalWaarde > 2) or (stapelsMetWaarde > 1) ) { einde = false; break; } //end if } //end if not 0 } //end loop return(einde); } //end NimSpel::winstAfgelopen //Controleer of een pad zeker winnend is bool NimSpel::winstRecur( bool aanBeurt ) { bool winst1 = false; bool winst2 = false; aanBeurt = not(aanBeurt); if( winstAfgelopen() ) { if( aanBeurt ) { return(true); } else { return(false); } } else { for( int ctr=0; ctr < aantalStapels; ctr++ ) { if( stapel[ctr] > 0 ) { if( stapel[ctr] > 1 ) { stapel[ctr] = stapel[ctr] - 2; winst2 = winstRecur( aanBeurt ); stapel[ctr] = stapel[ctr] + 2; } //end if (test met 2) stapel[ctr] = stapel[ctr] - 1; winst1 = winstRecur( aanBeurt ); stapel[ctr] = stapel[ctr] + 1; } //end if (groter dan 0) if( winst1 & winst2 ) { return(true); } //end if (winst test) } //end for loop return(false); } } //end NimSpel::winstRecur //Deze functie creert alle mogelijk vervolg zetten, en test deze op //winnend void NimSpel::winnend( int & stapelNummer, int & aantal ) { bool winst; if( winnendEnable() ) { for( int ctr=0; ctr < aantalStapels; ctr++ ) { if( stapel[ctr] > 0 ) { if( stapel[ctr] > 1) { stapel[ctr] = stapel[ctr] - 2; winst = winstRecur( "false" ); stapel[ctr] = stapel[ctr] + 2; if( winst ) { stapelNummer = ctr; aantal = 2; return; } //winst 2 } stapel[ctr] = stapel[ctr] - 1; winst = winstRecur( "false" ); stapel[ctr] = stapel[ctr] + 1; if( winst ) { stapelNummer = ctr; aantal = 1; return; } //winst 1 } //not null } //loop for stapelNummer = -1; aantal = -1; } else { randomZet( stapelNummer, aantal ); } } //end NimSpel::winnnend bool NimSpel::winnendEnable() { int aantal = 0; for( int ctr=0; ctr < aantalStapels; ctr++ ) { aantal = aantal + stapel[ctr]; if( aantal > START_WINNEND ) { return(false); } //end if } //end for return(true); } //end NimSpel::winnendEnable //zet beurten terug void NimSpel::zetTerug( const int aantalBeurten ) { int aantalStappen = aantalBeurten * 2; NimStapel * temp_pt; for( int i = 0; i < aantalStappen; i++ ) { temp_pt = laatsteZet_pt; stapel[temp_pt->stapelNummer] = ( stapel[temp_pt->stapelNummer] + temp_pt->aantalEraf ); aantalZetten--; laatsteZet_pt = temp_pt->vorigeZet_pt; delete temp_pt; } //end for } //end NimSpel::ZetTerug //kijk of je niet meer stokjes van een stapel afpakt als dat er liggen bool NimSpel::zetMogelijk( const int stapelNummer, const int aantalPakken ) { if( (stapel[stapelNummer] - aantalPakken) < 0 ) { return false; } else { return true; } //end if } //end NimSpel::zetMogelijk