source: liacs/pm/nim-v3/nimSpel.cc@ 2

Last change on this file since 2 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.