/[projet1]/public/oric/games/Awele/MiniGameAwale.c
Defence Force logotype

Contents of /public/oric/games/Awele/MiniGameAwale.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 491 - (show annotations)
Sun May 22 11:33:41 2011 UTC (8 years, 10 months ago) by dbug
File MIME type: text/plain
File size: 9956 byte(s)
Added an Oric version of the game Awele made by a coworker eons ago :)
1 #include "MiniGameAwale.h"
2 #include <stdio.h>
3
4 //#include <assert.h> // no assert on oric!
5 #define assert(test)
6
7 #define DEPTH_SEARCH1 (3)
8 #define DEPTH_SEARCH2 (4)
9
10 #define FALSE (0)
11 #define TRUE (!FALSE)
12
13 #define DISPLAY
14
15 #ifndef NULL
16 #define NULL (0)
17 #endif //NULL
18
19
20
21 static long holdrand = 1L;
22
23 int rand()
24 {
25 return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
26 }
27
28
29 void StateAwale_Reset(StateAwale* state)
30 {
31 // clear map
32 int i, j;
33 for(j=0; j<LENGTH; ++j)
34 {
35 for(i=0; i<WIDTH; ++i)
36 {
37 state->m_map[j][i] = 4;
38 }
39 }
40
41 // reset garbages
42 state->m_garbage[0] = state->m_garbage[1] = 0;
43
44 // clear first player
45 state->m_player = rand()&1;
46 }
47
48
49 int StateAwale_PlacesToPlay(const StateAwale *state, ShotAwale* shotArray)
50 {
51 int i, nbShot = 0;
52 ShotAwale shot;
53
54 for(i=0; i<WIDTH; ++i)
55 {
56 if(state->m_map[state->m_player][i]!=0)
57 {
58 shot = i;
59 if(StateAwale_CanPlay(state, shot))
60 {
61 if(NULL != shotArray)
62 {
63 shotArray[nbShot] = shot;
64 }
65 nbShot++;
66 }
67 }
68 }
69 return nbShot;
70 }
71
72
73 int StateAwale_HasPlaceToPlay(const StateAwale* state)
74 {
75 int hasPlaceToPlay = FALSE;
76 int i;
77 for(i=0; i<WIDTH; ++i)
78 {
79 if(state->m_map[state->m_player][i]!=0)
80 {
81 ShotAwale shot;
82 shot = i;
83 if(StateAwale_CanPlay(state, shot))
84 {
85 hasPlaceToPlay = TRUE;
86 break;
87 }
88 }
89 }
90
91 return hasPlaceToPlay;
92 }
93
94
95 int StateAwale_CanPlay(const StateAwale *state, ShotAwale play)
96 {
97 int ret = FALSE;
98 if(play>=0 && play<WIDTH)
99 {
100 switch(state->m_player)
101 {
102 case 0:
103 {
104 if(state->m_map[0][play] > play)
105 ret = TRUE;
106 }
107 break;
108 case 1:
109 {
110 if(state->m_map[1][play] >= (WIDTH - play))
111 ret = TRUE;
112 }
113 break;
114 }
115 }
116 return ret;
117 }
118
119
120 void StateAwale_PlayShot(StateAwale* state, ShotAwale play)
121 {
122 int seeds;
123 int column;
124 int line;
125 int step;
126
127 seeds = 0;
128 column = play;
129 line = state->m_player;
130 step = 0;
131 assert(StateAwale_CanPlay(state, play));
132
133 // 1°) take the seeds
134 seeds = state->m_map[state->m_player][column];
135 state->m_map[state->m_player][column] = 0;
136
137 // 2°) drop the seeds on the map
138 step = (0==state->m_player) ? -1 : 1;
139 while(seeds>0)
140 {
141 // faire le test avant, de toute façon il faut faire le test,
142 // on évite ainsi de faire un incrément plus une correction
143 // revoir l'ordre de stockage des troous afin d'avoir un tableau
144 // linéaire et de ne pas faire de test pour step
145 column += step;
146 if(column<0)
147 {
148 step = step > 0 ? -1 : 1;
149 column = 0;
150 line = 1 - line;
151 }
152 else if(column>=WIDTH)
153 {
154 step = step > 0 ? -1 : 1;
155 column = WIDTH - 1;
156 line = 1 - line;
157 }
158
159 state->m_map[line][column]++;
160 seeds--;
161 };
162
163 // 3°) does we get seeds ?
164 if( line == (1-state->m_player))
165 {
166 step = step > 0 ? -1 : 1;
167 while(state->m_map[line][column] == 2 ||
168 state->m_map[line][column] == 3)
169 {
170 state->m_garbage[state->m_player] += state->m_map[line][column];
171 state->m_map[line][column] = 0;
172 if(column>0 && column<WIDTH-1)
173 {
174 column += step;
175 }
176 }
177 }
178
179 // 4°) change the player
180 StateAwale_SetPlayer(state, 1-StateAwale_GetPlayer(state));
181 }
182
183
184 //=========================================================
185 // IA Part
186 //=========================================================
187 int StateAwale_AlphaBeta(const StateAwale* state, int player, int alpha, int beta, int depth)
188 {
189 int m, i, t, nbSon;
190 int end;
191 ShotAwale shotAvailable[WIDTH];
192 StateAwale son;
193
194 // must we stop search ?
195 if(0 == depth || !StateAwale_HasPlaceToPlay(state))
196 return StateAwale_Eval(state, player);
197
198
199 nbSon = StateAwale_PlacesToPlay(state, shotAvailable);
200 if( StateAwale_GetPlayer(state) == player ) // on maximise
201 {
202 m = alpha;
203 end = FALSE;
204 for(i=0; !end && i<nbSon; i++)
205 {
206 son = *state;
207 StateAwale_PlayShot(&son, shotAvailable[i]);
208 t = StateAwale_AlphaBeta(&son, player, m, beta, depth-1);
209 if(t>m)
210 m = t; // mise a jour du max
211 if(t>beta)
212 end = TRUE; // elagage de l'arbre
213 }
214 }
215 else // on minimise
216 {
217 m = beta;
218 end = FALSE;
219 for(i=0; !end && i<nbSon; i++)
220 {
221 son = *state;
222 StateAwale_PlayShot(&son, shotAvailable[i]);
223 t = StateAwale_AlphaBeta(&son, player, alpha, m, depth-1);
224 if(t<m)
225 m = t; // mise à jour du min
226 if(t<alpha)
227 end = TRUE;
228 }
229 }
230
231 return m;
232 }
233
234
235 int StateAwale_BestShot_AlphaBeta(const StateAwale* state, const ShotAwale* shotArray, int shotArraySize, int depth)
236 {
237 int ret = -1;
238 int score, bestScore, bestShot;
239 int nbGoodShot = 0;
240 int goodShots[WIDTH];
241 int i;
242 StateAwale son;
243
244 bestScore = -1000;
245 assert(depth>=0);
246 for(i=0; i<shotArraySize; i++)
247 {
248 son = *state;
249 StateAwale_PlayShot(&son, shotArray[i]);
250 score = StateAwale_AlphaBeta(&son, StateAwale_GetPlayer(state), -1000, +1000, depth-1); // start with minimize, invert
251 if(score>=bestScore)
252 {
253 // store every shots with the same score as the best one
254 if(score>bestScore)
255 nbGoodShot = 0; // reset best shots array
256
257 goodShots[nbGoodShot] = i; // store shot
258 nbGoodShot++;
259
260 // store the best shot
261 bestScore = score;
262 bestShot = i;
263 }
264 }
265
266 // return one of the best shot
267 bestShot = rand()%nbGoodShot;
268 return goodShots[bestShot];
269 // return the best shot
270 //return bestShot;
271 }
272
273
274 void StateAwale_Display(const StateAwale* state)
275 {
276 int i, j;
277 puts("+-+-----------------+\n");
278 puts("| | 0| 1| 2| 3| 4| 5|\n");
279 puts("+-+-----------------+\n");
280
281 for(j=0; j<LENGTH; ++j)
282 {
283 char player = (StateAwale_GetPlayer(state)==j) ? '*' : ' ';
284 printf("|%d|", player);
285 for(i=0; i<WIDTH; ++i)
286 {
287 if(state->m_map[j][i]<10)
288 putchar(' ');
289 printf("%d|", state->m_map[j][i]);
290 }
291 putchar('\n');
292 puts("+-+-----------------+\n");
293 }
294
295 printf("line 0: %d line 1: %d\n", state->m_garbage[0], state->m_garbage[1]);
296 get();
297 }
298
299
300 ShotAwale GameAwale_GetShot_Human(/*const*/ GameAwale *game )
301 {
302 int place;
303 int canPlayShot;
304 ShotAwale shot;
305
306 canPlayShot = FALSE;
307 while(!canPlayShot)
308 {
309 puts("Select a shot\n");
310 //cin >> place;
311 //scanf("%d", &place);
312 place = getchar();
313 if (place>='0' && place<='9')
314 {
315 shot = place - '0';
316 if(StateAwale_CanPlay(&game->m_currentState, shot))
317 {
318 canPlayShot = TRUE;
319 }
320 }
321
322 if(canPlayShot != TRUE)
323 {
324 puts("invalid shot\n");
325 }
326 }
327
328 return shot;
329 }
330
331
332 ShotAwale GameAwale_GetShot_Cpu0(/*const*/ GameAwale *game )
333 {
334 ShotAwale shotAvailable[WIDTH];
335 int nbShot, randShot;
336 ShotAwale shot;
337
338 nbShot = StateAwale_PlacesToPlay(&game->m_currentState, shotAvailable);
339 randShot = rand()/(RAND_MAX%nbShot);
340 shot = shotAvailable[randShot];
341 assert(StateAwale_CanPlay(&game->m_currentState, shot));
342 #ifdef DISPLAY
343 //cout << "Shot Selected : " << ret.m_column << endl;
344 printf("Shot selected: %d\n", shot);
345 #endif
346
347 return shot;
348 }
349
350
351 ShotAwale GameAwale_GetShot_Cpu1(/*const*/ GameAwale* game )
352 {
353 ShotAwale shotAvailable[WIDTH];
354 int nbShot, abShot;
355 ShotAwale shot;
356
357 nbShot = StateAwale_PlacesToPlay(&game->m_currentState, shotAvailable);
358 abShot = StateAwale_BestShot_AlphaBeta(&game->m_currentState, shotAvailable, nbShot, DEPTH_SEARCH1);
359 shot = shotAvailable[abShot];
360 assert(StateAwale_CanPlay(&game->m_currentState, shot));
361 #ifdef DISPLAY
362 //cout << "Shot Selected : " << ret.m_column << endl;
363 printf("Shot Selected : %d\n", shot );
364 #endif
365
366 return shot;
367 }
368
369
370 ShotAwale GameAwale_GetShot_Cpu2(/*const*/ GameAwale* game )
371 {
372 ShotAwale shotAvailable[WIDTH];
373 int nbShot, abShot;
374 ShotAwale shot;
375
376 nbShot = StateAwale_PlacesToPlay(&game->m_currentState, shotAvailable);
377 abShot = StateAwale_BestShot_AlphaBeta(&game->m_currentState, shotAvailable, nbShot, DEPTH_SEARCH2);
378 shot = shotAvailable[abShot];
379 assert(StateAwale_CanPlay(&game->m_currentState, shot));
380 #ifdef DISPLAY
381 //cout << "Shot Selected : " << ret.m_column << endl;
382 printf("Shot Selected : %d\n", shot );
383 #endif
384 return shot;
385 }
386
387
388 void GameAwale_GameInit(GameAwale* game)
389 {
390 // Clear Map
391 StateAwale_Reset(&game->m_currentState);
392
393 // Give Player Name
394 game->m_player[0] = 'A';
395 game->m_player[1] = 'B';
396
397 // Init ShotFunc Ptr (Human or computer)
398 //m_shotFunc[0] = GetShot_Human;
399 //m_shotFunc[0] = GetShot_Cpu0;
400 game->m_shotFunc[0] = GameAwale_GetShot_Cpu1;
401
402 //m_shotFunc[1] = GetShot_Human;
403 //m_shotFunc[1] = GetShot_Cpu0;
404 //m_shotFunc[1] = GetShot_Cpu1;
405 game->m_shotFunc[1] = GameAwale_GetShot_Cpu2;
406
407 }
408
409
410 void GameAwale_GameLoop(GameAwale* game)
411 {
412 ShotAwale shot;
413 for(;;)
414 {
415 // 1°) display current state
416 #ifdef DISPLAY
417 //cout << m_currentState << endl;
418 StateAwale_Display(&game->m_currentState);
419 #endif
420 // 2°) test if finished
421 if( !StateAwale_HasPlaceToPlay(&game->m_currentState))
422 break;
423 // 3°) ask the player to play
424 //ShotAwale shot = GetShot_Human();
425 #ifdef DISPLAY
426 //cout << "Player: " << (char)(game->m_player[StateAwale_GetPlayer(game->m_currentState.)].m_id) << endl;
427 printf("Player: %d\n", (char)(game->m_player[StateAwale_GetPlayer(&game->m_currentState)]));
428 #endif
429 // get player shot
430 shot = (game->m_shotFunc[StateAwale_GetPlayer(&game->m_currentState)])(game);
431 // and play it
432 StateAwale_PlayShot(&game->m_currentState, shot);
433 }
434 }
435
436
437 int GameAwale_GameTerm(GameAwale* game)
438 {
439 // 5°) display the winner or draw game
440 int eval;
441 eval = StateAwale_Eval(&game->m_currentState, 0);
442 #ifdef DISPLAY
443 if( 0==eval )
444 {
445 //cout << "Draw Game" << endl;
446 puts("Draw game\n");
447 }
448 else
449 {
450 //cout << "The Winner is: " << (char)((eval>0) ? game->m_player[0].m_id : game->m_player[1].m_id) << endl;
451 printf("The Winner is: %c\n", (char)((eval>0) ? game->m_player[0] : game->m_player[1]));
452 }
453 #endif
454
455 return (eval==0)?0:(eval>0)?1:2;
456 }
457
458
459
460
461
462
463
464

  ViewVC Help
Powered by ViewVC 1.1.26