source: liacs/pm/backup/nim.cc@ 7

Last change on this file since 7 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: 8.8 KB
RevLine 
[2]1//Rick van der Zwet
2//Pascal de Vos
3//Programeeropgave 4, Nim Spel
4
5#include <iostream>
6#include <ctime>
7#include <cstdlib>
8
9using namespace std;
10
11//constanten
12const int MaxStapels = 4; //Maximale Aantal Stapels
13const int MaxAantal = 4; //Maximale Aantal Lucifers
14
15
16
17//creeer random getal met behulp van de random functie;
18int RandomGetal(int Min, int Max){
19 return ( Min + int( double(Max + 1 - Min) * rand()/(RAND_MAX+1.0)) );
20} //RandomGetal
21
22
23
24//Zorgt dat de gebruiker enkel getallen <= Max in kan voeren
25int VoerInGetal(int Min, int Max){
26 int x = 0;
27 do {
28 if(!(cin >> x)) {
29 cout << "Enkel Cijfers aub" << endl;
30 cin.clear();
31 cin.ignore(10000,'\n');
32 }
33 else if (x > Max) {
34 cout << "Te groot getal" << endl;
35 }
36 else if (x < Min) {
37 cout << "Te klein getal" << endl;
38 }// end if
39 } // end do
40 while((x < Min) or (x > Max));
41 return x;
42} //end VoerInGetal
43
44
45
46//Class die gebruikt wordt om terugzetten te realiseren
47class NimData{
48 public:
49 NimData( ); //creator
50 ~NimData( ) { };
51 int StapelNummer; //Nummer van de stapel waar het
52 int AantalEraf; //AantalEraf af is gegaan
53 NimData * VorigeZet_pt; //Pointer naar de zet ervoor, maakt stapelen mogelijk
54};// end NimData
55
56NimData::NimData( ){
57 StapelNummer = 0;
58 AantalEraf = 0;
59 VorigeZet_pt = NULL;
60}// end NimData::NimData
61
62
63
64class NimSpel{
65 public:
66 NimSpel( ); //creator
67 ~NimSpel( ) { }; //destructor
68 void NimSpelen( ); //Main programma
69 private:
70 NimData * LaatsteZet_pt; //Pointer naar gegevens laatste zet
71 int AantalZetten; //aantal zetten dat gedaan is
72 int Stapels[MaxStapels]; //aantal luicifers per stapel
73 int SpelerAanBeurt; //speler die aan de beurt is
74 //2 spelers, nummer 1 is de speler, nummer 2 is computer
75 double WinstArray[MaxAantal + 1][3]; //slim berekende winst array voor computer 'ai'
76 //[0] = totaal aantal mogelijkheden, [1] = aantal winnen, [2] = aantal verliezen
77
78 void PakWeg(int Groep, int Aantal); //Haal Aantal uit Stapels[Groep]
79 void ZetTerug(int AantalStappen); //Ga AantalStappen terug
80 void SpelerKiest ( ); //Invoerscherm voor gebruiker
81 void ComputerNiveauSlim(int * StapelNummer, int * Aantal); //Computer berekening
82 void ComputerKiest (int Niveau); //ComputerHandelingen
83 void DrukAf( ); //Druk Spel af
84 bool SpelAfgelopen( ); // Kijken af alles afgelopen is
85}; //end NimSpel
86
87
88
89//init van de groepen array
90NimSpel::NimSpel( ){
91 LaatsteZet_pt = NULL;
92 AantalZetten = 0;
93 SpelerAanBeurt = 1;
94
95 for(int i = 0; i < MaxStapels; i++) {
96 Stapels[i] = MaxAantal;
97 } //end for
98
99 //Bedacht en getest algoritme
100 WinstArray[0][0] = 1;
101 WinstArray[0][1] = 0;
102 WinstArray[0][2] = 1;
103 WinstArray[1][0] = 1;
104 WinstArray[1][1] = 1;
105 WinstArray[1][2] = 0;
106 WinstArray[2][0] = 1;
107 WinstArray[2][1] = 1;
108 WinstArray[2][2] = 0;
109 for(int i = 3; i < MaxAantal + 1; i++){
110 WinstArray[i][0] = WinstArray[i-1][0] + WinstArray[i-2][0];
111 WinstArray[i][1] = WinstArray[i-1][2] + WinstArray[i-2][2];
112 WinstArray[i][2] = WinstArray[i][0] - WinstArray[i][1];
113 }
114} //end NimSpel::NimSpel
115
116
117
118void NimSpel::PakWeg(int StapelNummer, int Aantal){
119 NimData * temp_pt; //
120 temp_pt = new NimData; //
121 temp_pt->VorigeZet_pt = LaatsteZet_pt; //Zetten onthouden
122 LaatsteZet_pt = temp_pt; //
123 LaatsteZet_pt->StapelNummer = StapelNummer; //
124 LaatsteZet_pt->AantalEraf = Aantal; //
125
126 AantalZetten++; //Max Zetten bijhouden
127
128 Stapels[StapelNummer] = Stapels[StapelNummer] - Aantal;
129} //end NimSpel::NimSpel
130
131
132
133void NimSpel::ZetTerug(int AantalStappen) {
134 NimData * temp_pt;
135 for(int i = 0; i < AantalStappen; i++) {
136 temp_pt = LaatsteZet_pt;
137 Stapels[temp_pt->StapelNummer] = Stapels[temp_pt->StapelNummer] + temp_pt->AantalEraf;
138 AantalZetten--;
139 LaatsteZet_pt = temp_pt->VorigeZet_pt;
140 delete temp_pt;
141 } //end for
142} //end NimSpel::ZetTerug
143
144
145
146void NimSpel::SpelerKiest( ){
147 int StapelNummer, Aantal, AantalStappen = 0;
148
149 cout << "Maximaal terug te zetten zetten: " << AantalZetten << endl
150 << "'0' om niet terug te zetten" << endl
151 << "Aantal zetten: ";
152 AantalStappen = VoerInGetal(0, AantalZetten);
153
154 if (AantalStappen == 0) {
155 do{
156 cout << "Speler aan de beurt" << endl;
157 cout << "Welke stapel [0-" << (MaxStapels - 1) << "] : ";
158 StapelNummer = VoerInGetal(0, MaxStapels - 1);
159 cout << "Hoeveel [1-2] : ";
160 Aantal = VoerInGetal(1, 2);
161 if (Stapels[StapelNummer] - Aantal < 0){
162 cout << Stapels[StapelNummer] << endl;
163 cout << "Geen Geldige Combinatie, probeer opnieuw";
164 } //end if
165 } //end do
166 while(Stapels[StapelNummer] - Aantal < 0);
167 PakWeg(StapelNummer, Aantal);
168 }
169 else { //Ga AantalStappen terug zetten
170 ZetTerug(AantalStappen);
171 SpelerAanBeurt = SpelerAanBeurt - 1 + (AantalStappen%2); //ivm met onevenaantal terug zetten
172 }// end if
173} //end NimSpel::SpelerKiest
174
175
176
177void NimSpel::ComputerNiveauSlim(int * StapelNummer, int * Aantal) {
178 double KansMax, KansMet1, KansMet2 = 0; //tempvariablen, voor het bepalen van de max
179 for(int i = 0; i < MaxStapels; i++) {
180 if (Stapels[i] > 0) {
181 KansMet1 = WinstArray[Stapels[i]-1][2] / WinstArray[Stapels[i]-2][0];
182 }
183 else {
184 KansMet1 = 0;
185 }//end if
186
187 if (Stapels[i] > 1) {
188 KansMet2 = WinstArray[Stapels[i]-2][2] / WinstArray[Stapels[i]-2][0];
189 }
190 else {
191 KansMet2 = 0;
192 }//end if
193
194 if(KansMet1 > KansMax) {
195 *Aantal = 1;
196 *StapelNummer = i;
197 KansMax = KansMet1;
198 }//end if
199
200 if(KansMet2 > KansMax) {
201 *Aantal = 2;
202 *StapelNummer = i;
203 KansMax = KansMet2;
204 }//end if
205 }//end for
206}// end NimSpel::ComputerNiveauSlim
207
208
209
210void NimSpel::ComputerKiest(int Niveau) {
211 int StapelNummer = 0; //Voor het geval alles op verliezen staat ;-)
212 int Aantal = 1; //
213 char wait; //loze char ivm met Wachten om ENTER invoer.
214
215 cout << "Computer Kiest..." << endl;
216 switch (Niveau) {
217 case 1: //random keuze
218 do {
219 StapelNummer = RandomGetal(0, (MaxStapels-1));
220 Aantal = RandomGetal(1, 2);
221 } //end do
222 while(Stapels[StapelNummer] - Aantal < 0);
223 break;
224 case 2: //slimme keuze
225 ComputerNiveauSlim(&StapelNummer, &Aantal);
226 break;
227 default: //dedug keuze
228 StapelNummer = 0;
229 Aantal = 2;
230 break;
231 } //end switch
232
233 cout << "Stapel: " << StapelNummer << endl;
234 cout << "Aantal: " << Aantal << endl;
235 cout << "Druk op ENTER...";
236 cin.clear();
237 cin.ignore(10000,'\n');
238 cin.get(wait);
239 PakWeg(StapelNummer, Aantal);
240} //end NimSpel::Computerkiest
241
242
243
244void NimSpel::DrukAf( ){
245 system("clear"); //OS Dependent Line, for windows use 'system("cls");' instead.
246 cout << endl << " : ";
247 for(int i = 0; i < MaxStapels; i++) {
248 if (i < 10) {cout << " " << i << " | ";} else { cout << i << " | ";}
249 }//end for
250 for(int i = 1; i <= MaxAantal; i++) {
251 cout << endl;
252 if (i < 10) {cout << " " << i << " : ";} else { cout << i << " : ";}
253 for(int j = 0; j < MaxStapels; j++) {
254 if (i <= Stapels[j]) { cout << "XX | ";} else { cout << " | ";}
255 }//end for
256 }//end for
257 cout << endl << endl;
258}//end NimSpelDrukAf
259
260
261
262bool NimSpel::SpelAfgelopen( ){
263 for(int i = 0; i < MaxStapels; i++) {
264 if (Stapels[i] > 0) { //als er nog ergens waardes aanwezig zijn
265 return (false);
266 }//end if
267 }//end if
268 return (true);
269}//end NimSpelAfgelopen
270
271
272
273void NimSpel::NimSpelen( ){
274 int Niveau = 0; //
275 cout << endl //
276 << "Geef het niveau aan" << endl //
277 << "1) Random " << endl //Niveau bepalen
278 << "2) Winnend Spelen " << endl;//
279 Niveau =VoerInGetal(1,2); //
280
281 while (not(SpelAfgelopen( ))) { //Zolang spel niet afgelopen
282 DrukAf( ); //Druk bord af
283 if (SpelerAanBeurt == 1) { //a1) Speler 1 aan de beurt
284 SpelerKiest( ); //a2) Speler Doorwerken, keuzes enz.
285 SpelerAanBeurt++; //a3) Computer aan de beurt
286 }
287 else if (SpelerAanBeurt == 2) { //b1) Computer aan de Beurt
288 ComputerKiest(Niveau); //b2) Computer op Niveau laten spelen
289 SpelerAanBeurt = 1; //b3) Speler aan de beurt
290 } //end if
291 } //end while
292 if (SpelerAanBeurt == 2) { //ivm met regels a3,b3
293 cout << "Voila uw heeft GEWONNEN" << endl;
294 }
295 else {
296 cout << "DE COMPUTER IS DE BESTE !!!" <<endl;
297 }//end if
298} //end NimSpel::NimSpelen
299
300
301
302int main( ){
303 srand(time(0)); //elke keer andere random begin waarde
304 NimSpel Spel1; //nieuw spel
305 Spel1.NimSpelen(); //spelen
306}// end main
307
308
Note: See TracBrowser for help on using the repository browser.