source: liacs/pm/nim_full.cc@ 92

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