source: liacs/pm/nim-v2/nimSpel.cc@ 377

Last change on this file since 377 was 2, checked in by Rick van der Zwet, 15 years ago

Initial import of data of old repository ('data') worth keeping (e.g. tracking
means of URL access statistics)

  • Property svn:executable set to *
File size: 6.9 KB
Line 
1/*programeeropdracht 4 The Nim Game
2 *Pascal de Vos (ID = 0446916)
3 *Rick van der Zwet (ID = 0433373)
4 *file: nimSpel.cc
5 *de is het rekengedeelte van mainForm.cc, hierin kan makkelijk en snel
6 *gegevens worden verwerkt en oplossingen worden doorgerekend
7 */
8#include "nimSpel.h"
9#include "const.h"
10#include <cstdlib>
11
12using namespace std;
13NimSpel::NimSpel( ){ //constructor
14 laatsteZet_pt = NULL;
15 aantalZetten = 0;
16} //end NimSpel::NimSpel
17
18
19
20//aantal beurten terug geven
21int NimSpel::aantalBeurten( ){
22 return( aantalZetten/2 );
23} //end NimSpel::aantalBeurten
24
25
26
27//aantal op stapel teruggeven
28int NimSpel::aantalOpStapel( const int nummer ){
29 return( stapels[nummer] );
30} //end NimSpel::aantalOpStapel
31
32
33
34//aantal actieve stapels teruggeven
35int NimSpel::actieveStapels( ){
36 return( aantalStapels );
37} //end NimSpel::actieveStapels
38
39bool NimSpel::afgelopen( ){ //kijken of spel afgelopen is
40 for( int i = 0; i < MAX_STAPELS; i++ ) {
41 if( stapels[i] > 0 ) { //als er nog ergens waardes aanwezig zijn
42 return( false );
43 }//end if
44 }//end if
45 return( true );
46}//end NimSpel::afgelopen
47
48
49
50//zet de beginwaarden van de stapel
51void NimSpel::beginWaarden( const int stapelAantal, const int aantal) {
52 zetTerug(aantalZetten/2); //terugzetten om oude pointer naar NULL te
53 //helpen en alles netjes de destructen
54 for( int i = 0; i < stapelAantal; i++ ) {
55 stapels[i] = aantal;
56 aantalStapels = stapelAantal;
57 } //end for
58} //end NimSpel::beginWaarden
59
60
61
62//creer een nieuwe zet voor de computer
63void NimSpel::computerZet( const bool niveauComputer, int & stapelNummer,
64 int & aantal) {
65 int tmpStapelNummer = -1;
66 int tmpAantal = -1;
67
68 if( niveauComputer ) { //winnend spelen als dat verwacht wordt
69 winnend( tmpStapelNummer, tmpAantal );
70 } //end if
71
72 if( tmpAantal == -1 ) {
73 //hij zal in deze if komen als er geen winnnende keuzes zijn
74 randomZet( tmpStapelNummer, tmpAantal );
75 } //end if
76
77 stapelNummer = tmpStapelNummer;
78 aantal = tmpAantal;
79} //end NimSpel::computerZet
80
81
82
83//doe een random zet, die wel in de range van een stapel aantal ligt
84void NimSpel::randomZet( int & stapelNummer, int & aantal ) {
85 do {
86 stapelNummer = int( double(aantalStapels) * rand()/(RAND_MAX+1.0) );
87 aantal = 1 + int( double(2) * rand()/(RAND_MAX+1.0) );
88 } //end do
89 while( stapels[stapelNummer] - aantal < 0 );
90}//end NimSpel::randomZet
91
92
93
94//verwerk een zet
95void NimSpel::pakWeg( const int stapelNummer, const int aantal ){
96 NimStapel * temp_pt; //
97 temp_pt = new NimStapel; //
98 temp_pt->vorigeZet_pt = laatsteZet_pt; //Zetten onthouden
99 laatsteZet_pt = temp_pt; //
100 laatsteZet_pt->stapelNummer = stapelNummer; //
101 laatsteZet_pt->aantalEraf = aantal; //
102 aantalZetten++; //Max Zetten bijhouden
103 stapels[stapelNummer] = stapels[stapelNummer] - aantal;
104} //end NimSpel::pakweg
105
106
107
108//zoek recursief het aantal winnende sporen en het aantal
109//verliezende sporter
110void NimSpel::recur( const int aantal, const bool aanBeurt,
111 int & aantalWinst, int & aantalVerlies ) {
112 if( aantal < 3 ) { //aantal lager dan 3
113 if( aanBeurt ) { //als je aan beurt bent dan een winstpunt
114 aantalWinst++;
115 }
116 else { //en anders een verliespunt
117 aantalVerlies++;
118 }
119 }
120 else { //3 en hoger zorgt ervoor dat we de functie weer
121 //aan moeten roepen en wel met 1 en 2 minder
122 recur( aantal-1, !(aanBeurt), aantalWinst, aantalVerlies);
123 recur( aantal-2, !(aanBeurt), aantalWinst, aantalVerlies);
124 }
125} //end NimSpel::recur;
126
127
128
129//zoek de keuze op met de meeste winkans
130//als er niet gewonnen kan worden return voor keuze '-1'
131void NimSpel::recurKeuze( const int aantal, int & keuze, double & winstKans ) {
132 int min1Winst = 0; //winst paden voor aantal-1
133 int min1Verlies = 0; //verlies paden voor aantal-1
134 int min2Winst = 0; //winst paden voor aantal-2
135 int min2Verlies = 0; //verlies paden voor aantal-2
136 double win1Kans = 0; //kans op winst met 1
137 double win2Kans = 0; //kans op winst met 2
138
139 if( aantal < 1 ) { //aantal is 0 of minder, kans op -2 zetten,
140 keuze = aantal; //want hij is afgelopen
141 winstKans = -2;
142 }
143 else if( aantal < 3 ) { //als er minder als 3 worden opgegeven hebben
144 keuze = aantal; //we altijd een winst situatie en gaan we niet
145 winstKans = 10;
146 }
147 else { //recursief rekenen
148 recur( aantal-1, false, min1Winst, min1Verlies ); //reken
149 recur( aantal-2, false, min2Winst, min2Verlies ); //kansen uit
150
151 //aangezien door 0 delen niet mag, zullen we de verliesKans met 1
152 //ophogen om zo toch eerlijkt te kunnen rekenen
153 min1Verlies++;
154 min2Verlies++;
155 win1Kans = double(min1Winst)/double(min1Verlies);
156 win2Kans = double(min2Winst)/double(min2Verlies);
157
158 //Als beiden kanten (-1 en -2) geen winst ergens oplevert is het
159 //hopenloos verloren en zullen we dit ook aangeven
160 //anders de kans met de meeste winst teruggeven
161 if( (min1Winst == 0) and (min2Winst == 0) ) {
162 keuze = -1;
163 winstKans = -1;
164 }
165 else if( win1Kans > win2Kans ) {
166 keuze = 1;
167 winstKans = win1Kans;
168 }
169 else {
170 keuze = 2;
171 winstKans = win2Kans;
172 }//end if
173
174 } //end if
175
176} //end NimSpel::recurKeuze
177
178
179
180//zoek de winnende zet uit (met hulp van een recursieve formule)
181void NimSpel::winnend( int & stapelNummer, int & aantal ) {
182 int tmpStapelNummer = -1; //-1 om ervoor te zorgen dat de winnende zet -1
183 int tmpAantal = -1; //wordt als er geen winnende zetten zijn
184 int tmpKeuze = 0; //(uit recurKeuze functie)
185 double tmpKans = 0; //tijdelijke Kans en Keuze
186 double kansMax = 0; //tijdelijk Variable voor geldende maximale kans
187
188 for( int i = 0; i <( MAX_STAPELS - 1); i++ ) {
189 //ga alle stapels af en van de stapel met de meeste kans pak je de
190 //winnnende stokjes vanaf
191 recurKeuze( stapels[i], tmpKeuze, tmpKans ); //bereken waardes
192
193 if( tmpKans > kansMax ) {
194 tmpStapelNummer = i;
195 tmpAantal = tmpKeuze;
196 kansMax = tmpKans;
197 } //end if
198
199 }//end for
200 stapelNummer = tmpStapelNummer;
201 aantal = tmpAantal;
202}// end NimSpel::winnnend
203
204
205//zet beurten terug
206void NimSpel::zetTerug( const int aantalBeurten ) {
207 int aantalStappen = aantalBeurten * 2;
208 NimStapel * temp_pt;
209 for( int i = 0; i < aantalStappen; i++ ) {
210 temp_pt = laatsteZet_pt;
211 stapels[temp_pt->stapelNummer] =
212 ( stapels[temp_pt->stapelNummer] + temp_pt->aantalEraf );
213 aantalZetten--;
214 laatsteZet_pt = temp_pt->vorigeZet_pt;
215 delete temp_pt;
216 } //end for
217} //end NimSpel::ZetTerug
218
219
220
221//kijk of je niet meer stokjes van een stapel afpakt als dat er liggen
222bool NimSpel::zetMogelijk( const int stapelNummer,
223 const int aantalPakken ) {
224 if( (stapels[stapelNummer] - aantalPakken) < 0 ) {
225 return false;
226 }
227 else {
228 return true;
229 } //end if
230} //end NimSpel::zetMogelijk
231
232
233
Note: See TracBrowser for help on using the repository browser.