1 #include <stdlib.h>
2 #include <X11/Xlib.h>
3 #include "struct.h"
4
5 extern Display *dpy, *odpy, *currdpy;
6 extern Window win, owin, currwin;
7 extern GC gc, ogc, currgc;
8 extern int xsize, ysize, obstacle_color, scr, oscr, currscr, curr_player;
9 extern int botmode;
10 extern Pixmap mapw, mapb, omapw, omapb, wblock, bblock, owblock, obblock, bamp, obamp, currbamp;
11
12 #define abs(num) ((num) < 0) ? -(num) : (num);
13 #define b_look(x,y) board[x*y_board_size+y]
14
15 int *board, *bl2;
16 int x_board_size,y_board_size;
17 Bool flumping, wflump, fflump, jflump;
18
19 /* Allocate game board */
allocate_board(xsize,ysize)20 allocate_board(xsize,ysize)
21 int xsize,ysize;
22 {
23 int x,y;
24
25 if ((xsize<MIN_BOARD_SIZE)||(xsize>MAX_BOARD_SIZE))
26 return(1);
27 if ((ysize<MIN_BOARD_SIZE)||(ysize>MAX_BOARD_SIZE))
28 return(1);
29
30 x_board_size = xsize;
31 y_board_size = ysize;
32
33 board = (int *) malloc(sizeof(int)*x_board_size*y_board_size);
34 bl2 = (int *) malloc(sizeof(int)*x_board_size*y_board_size);
35 for (x=0;x!=x_board_size;x++)
36 for (y=0;y!=y_board_size;y++)
37 board[x*y_board_size+y] = EMPTY;
38
39 return(0);
40 }
41
42 #ifdef NEWBOT
43
44 /* Copy one board array onto another for look-ahead */
copy_board(bs,bd)45 copy_board(bs, bd)
46 int *bs, *bd;
47 {
48 int x,y;
49
50 for(x=0;x!=xsize;x++)
51 for(y=0;y!=ysize;y++)
52 bd[x*ysize+y] = bs[x*ysize+y];
53
54 return(0);
55 }
56
57 #endif
58
59 /* Add obstruction to current board */
add_obstruction(xpos,ypos)60 add_obstruction(xpos,ypos)
61 int xpos,ypos;
62 {
63 if (!board)
64 return(1);
65
66 if ((xpos>x_board_size)||(xpos < 0))
67 return(1);
68 if ((ypos>y_board_size)||(ypos < 0))
69 return(1);
70
71 b_look(xpos,ypos) = OBSTACLE;
72
73 return(0);
74 }
75
76 /* Initialize the player pieces */
place_piece(xpos,ypos,player)77 place_piece(xpos,ypos,player)
78 int xpos,ypos,player;
79 {
80 if ((xpos>x_board_size)||(xpos < 0))
81 return(1);
82 if ((ypos>y_board_size)||(ypos < 0))
83 return(1);
84
85 b_look(xpos,ypos) = player;
86 if ((player!=WHITE)&&(player!=BLACK))
87 return(1);
88
89 return(1);
90 }
91
update_square(x,y,xnew,ynew,player)92 update_square(x,y,xnew,ynew,player)
93 int x,y,xnew,ynew,player;
94 {
95 Pixmap smap;
96
97 if ((x>=0)&&(x<x_board_size)&&(y>=0)&&(y<y_board_size))
98 if ((b_look(x,y)!=EMPTY)&&(b_look(x,y)!=OBSTACLE)&&b_look(x,y)!=player) {
99 b_look(x,y) = player;
100 if (flumping && jflump) {
101 if (player == WHITE)
102 smap = mapw;
103 else
104 smap = mapb;
105 blat(xnew, ynew, x, y, smap, dpy, scr, gc, win, bamp);
106 if (botmode) {
107 if (player == WHITE)
108 smap = omapw;
109 else
110 smap = omapb;
111 blat(xnew, ynew, x, y, smap, odpy, oscr, ogc, owin, obamp);
112 }
113 }
114 }
115 }
116
117 /* Move a piece.
118 Return 1 if the piece cannot be moved.
119 */
move_piece(xcurr,ycurr,xnew,ynew,player)120 move_piece(xcurr,ycurr,xnew,ynew,player)
121 int xcurr,ycurr,xnew,ynew,player;
122 {
123 int xdiff,ydiff,other_player,p;
124 Pixmap smap;
125
126 /* Player must own current position */
127 if (b_look(xcurr,ycurr) != player)
128 return(1);
129
130 /* The new position must be empty */
131 if (b_look(xnew,ynew) != EMPTY)
132 return(1);
133
134 /* Check the validity of moving to the new position */
135 xdiff = abs(xcurr-xnew);
136 ydiff = abs(ycurr-ynew);
137
138 /* Simple one square slurp */
139 if ((xdiff <= 1)&&(ydiff <=1))
140 b_look(xnew,ynew) = player;
141 else {
142 if ((xdiff <= 2)&&(ydiff <=2)) {
143 b_look(xcurr,ycurr) = EMPTY;
144 b_look(xnew,ynew) = player;
145 redraw_win(dpy, win, bamp, gc);
146 if (botmode)
147 redraw_win(odpy, owin, obamp, ogc);
148 }
149 else
150 return(1);
151 }
152 if(flumping) {
153 if (player == WHITE)
154 smap = mapw;
155 else
156 smap = mapb;
157 blat(xcurr, ycurr, xnew, ynew, smap, dpy, scr, gc, win, bamp);
158 if (botmode) {
159 if (player == WHITE)
160 smap = omapw;
161 else
162 smap = omapb;
163 blat(xcurr, ycurr, xnew, ynew, smap, odpy, oscr, ogc, owin, obamp);
164 }
165 }
166 /* Update the squares around the new one */
167 update_square((xnew-1),(ynew-1),xnew,ynew,player);
168 update_square((xnew),(ynew-1),xnew,ynew,player);
169 update_square((xnew+1),(ynew-1),xnew,ynew,player);
170 update_square((xnew+1),(ynew),xnew,ynew,player);
171 update_square((xnew+1),(ynew+1),xnew,ynew,player);
172 update_square((xnew),(ynew+1),xnew,ynew,player);
173 update_square((xnew-1),(ynew+1),xnew,ynew,player);
174 update_square((xnew-1),(ynew),xnew,ynew,player);
175
176 return(0);
177 }
178
179 #ifdef NEWBOT
180
sample_move(xcurr,ycurr,xnew,ynew,player)181 sample_move(xcurr,ycurr,xnew,ynew,player)
182 int xcurr,ycurr,xnew,ynew,player;
183 {
184 int xdiff,ydiff,other_player,p;
185
186 /* Player must own current position */
187 if (b_look(xcurr,ycurr) != player)
188 return(1);
189
190 /* The new position must be empty */
191 if (b_look(xnew,ynew) != EMPTY)
192 return(1);
193
194 /* Check the validity of moving to the new position */
195 xdiff = abs(xcurr-xnew);
196 ydiff = abs(ycurr-ynew);
197
198 /* Simple one square slurp */
199 if ((xdiff <= 1)&&(ydiff <=1))
200 b_look(xnew,ynew) = player;
201 else {
202 if ((xdiff <= 2)&&(ydiff <=2)) {
203 b_look(xcurr,ycurr) = EMPTY;
204 b_look(xnew,ynew) = player;
205 }
206 else
207 return(1);
208 }
209 /* Update the squares around the new one */
210 update_square((xnew-1),(ynew-1),xnew,ynew,player);
211 update_square((xnew),(ynew-1),xnew,ynew,player);
212 update_square((xnew+1),(ynew-1),xnew,ynew,player);
213 update_square((xnew+1),(ynew),xnew,ynew,player);
214 update_square((xnew+1),(ynew+1),xnew,ynew,player);
215 update_square((xnew),(ynew+1),xnew,ynew,player);
216 update_square((xnew-1),(ynew+1),xnew,ynew,player);
217 update_square((xnew-1),(ynew),xnew,ynew,player);
218
219 return(0);
220 }
221
222 #endif
223
b_peek(x,y)224 int b_peek(x,y)
225 int x,y;
226 {
227 return(board[x*y_board_size+y]);
228 }
229
230 /* Return an array of integers specifying the board */
return_board()231 int *return_board()
232 {
233 return(board);
234 }
235
return_x_size()236 return_x_size()
237 {
238 return(x_board_size);
239 }
240
return_y_size()241 return_y_size()
242 {
243 return(y_board_size);
244 }
245
246 /* Return 1 if the game is at an end. */
end_game()247 end_game()
248 {
249 int x,y;
250
251 for (x=0;x!=x_board_size;x++)
252 for (y=0;y!=y_board_size;y++)
253 if (b_look(x,y)==EMPTY)
254 return(0);
255
256 return(1);
257 }
258
259 /* Clean the board */
clean_board()260 clean_board()
261 {
262 int x,y;
263
264 for (x=0;x!=x_board_size;x++)
265 for (y=0;y!=y_board_size;y++)
266 if (b_look(x,y)!=OBSTACLE)
267 b_look(x,y) = EMPTY;
268 }
269
270 /* Return the number of pieces belonging to player. */
count_board(player)271 count_board(player)
272 int player;
273 {
274 int x,y,count=0;
275
276 for (x=0;x!=x_board_size;x++)
277 for (y=0;y!=y_board_size;y++)
278 if (b_look(x,y)==player)
279 count++;
280
281 return(count);
282 }
283
284 #define do_check(x,y,player) \
285 if (((x)>=0)&&((x)<x_board_size)&&((y)>=0)&&((y)<y_board_size)) \
286 if (b_look((x),(y))==EMPTY) \
287 return(1);
288
289 /* Return 1 if player has a valid move at x,y. */
check_move(x,y,player)290 check_move(x,y,player)
291 int x,y,player;
292 {
293 do_check(x-1,y-1,player);
294 do_check(x,y-1,player);
295 do_check(x+1,y-1,player);
296 do_check(x+1,y,player);
297 do_check(x+1,y+1,player);
298 do_check(x,y+1,player);
299 do_check(x-1,y+1,player);
300 do_check(x-1,y,player);
301
302 do_check(x-2,y-2,player);
303 do_check(x-1,y-2,player);
304 do_check(x,y-2,player);
305 do_check(x+1,y-2,player);
306 do_check(x+2,y-2,player);
307 do_check(x+2,y-1,player);
308 do_check(x+2,y,player);
309 do_check(x+2,y+1,player);
310 do_check(x+2,y+2,player);
311 do_check(x+1,y+2,player);
312 do_check(x,y+2,player);
313 do_check(x-1,y+2,player);
314 do_check(x-2,y+2,player);
315 do_check(x-2,y+1,player);
316 do_check(x-2,y,player);
317 do_check(x-2,y-1,player);
318 return(0);
319 }
320
321 /* Return 1 if player has a valid move. */
valid_move(player)322 valid_move(player)
323 {
324 int x,y;
325
326 for (x=0;x!=x_board_size;x++)
327 for (y=0;y!=y_board_size;y++)
328 if (b_look(x,y)==player)
329 if (check_move(x,y,player))
330 return(1);
331
332 return(0);
333 }
334
335 typedef struct {
336 int ox,oy;
337 int nx,ny;
338 } thing;
339
b_look2(x,y)340 b_look2(x,y)
341 int x,y;
342 {
343 if ((x>=0)&&(x<x_board_size)&&(y>=0)&&(y<y_board_size))
344 return(b_look(x,y));
345 else
346 return(OBSTACLE);
347 }
348
349 thing best;
350 int best_count,oplayer,curr_count;
351
evaluate(oldx,oldy,newx,newy,oplayer)352 evaluate(oldx,oldy,newx,newy,oplayer)
353 {
354 if ((newx>=0)&&(newx<x_board_size)&&(newy>=0)&&(newy<y_board_size)) {
355 if (b_look2(newx,newy)==EMPTY) {
356 if (b_look2((newx-1),(newy-1))==oplayer)
357 curr_count++;
358 if (b_look2(newx,(newy-1))==oplayer)
359 curr_count++;
360 if (b_look2((newx+1),(newy-1))==oplayer)
361 curr_count++;
362 if (b_look2((newx+1),newy)==oplayer)
363 curr_count++;
364 if (b_look2((newx+1),(newy+1))==oplayer)
365 curr_count++;
366 if (b_look2(newx,(newy+1))==oplayer)
367 curr_count++;
368 if (b_look2((newx-1),(newy+1))==oplayer)
369 curr_count++;
370 if (b_look2((newx-1),newy)==oplayer)
371 curr_count++;
372 if (curr_count > best_count) {
373 if ((best_count==-1)||(random()&1)) {
374 best.ox = oldx;
375 best.oy = oldy;
376 best.nx = newx;
377 best.ny = newy;
378 best_count = curr_count;
379 }
380 }
381 }
382 }
383 }
384
385 #ifdef NEWBOT
386
smart_robot(player)387 smart_robot(player)
388 int player;
389 {
390 int botp, enemp, oppon, bgross, egross, bnet, enet, nx, ny;
391 thing b1, b2;
392
393 oppon = (player==WHITE) ? BLACK : WHITE;
394 botp = count_board(player);
395 enemp = count_board(oppon);
396 copy_board(board, bl2);
397 best_count = -500;
398
399 for (x=0;x!=x_board_size;x++) {
400 for (y=0;y!=y_board_size;y++) {
401 if (b_look(x,y)==player) {
402 bgross = count_board(player);
403 egross = count_board(oppon); /* must get values for nx, ny & loop */
404 if ((nx>=0) && (nx<x_board_size) && (ny>=0) && (ny<y_board_size)) {
405 sample_move(x, y, nx, ny, player);
406 robot_move(oppon);
407 bnet = bgross - botp;
408 enet = egross - enemp;
409 if ((bnet-enet) > best_count) {
410 b1.ox = x;
411 b1.oy = y;
412 b1.nx = nx;
413 b1.ny = ny;
414 best_count = (bnet-enet);
415 }
416 }
417 }
418 }
419 }
420 }
421
422 #endif
423
424 /* Make a move for player. */
orobot_move(player)425 orobot_move(player)
426 int player;
427 {
428 int x,y;
429
430 best_count = -1;
431 best.ox = -1;
432 oplayer = (player==WHITE) ? BLACK : WHITE;
433
434 for (x=0;x!=x_board_size;x++)
435 for (y=0;y!=y_board_size;y++) {
436 if (b_look(x,y)==player) {
437 curr_count=1; evaluate(x,y,(x-1),(y-1),oplayer);
438 curr_count=1; evaluate(x,y,(x),(y-1),oplayer);
439 curr_count=1; evaluate(x,y,(x+1),(y-1),oplayer);
440 curr_count=1; evaluate(x,y,(x+1),(y),oplayer);
441 curr_count=1; evaluate(x,y,(x+1),(y+1),oplayer);
442 curr_count=1; evaluate(x,y,(x),(y+1),oplayer);
443 curr_count=1; evaluate(x,y,(x-1),(y+1),oplayer);
444 curr_count=1; evaluate(x,y,(x-1),(y),oplayer);
445
446 curr_count= 0; evaluate(x,y,(x-2),(y-2),oplayer);
447 curr_count= 0; evaluate(x,y,(x-1),(y-2),oplayer);
448 curr_count= 0; evaluate(x,y,(x),(y-2),oplayer);
449 curr_count= 0; evaluate(x,y,(x+1),(y-2),oplayer);
450 curr_count= 0; evaluate(x,y,(x+2),(y-2),oplayer);
451 curr_count= 0; evaluate(x,y,(x+2),(y-1),oplayer);
452 curr_count= 0; evaluate(x,y,(x+2),(y),oplayer);
453 curr_count= 0; evaluate(x,y,(x+2),(y+1),oplayer);
454 curr_count= 0; evaluate(x,y,(x+2),(y+2),oplayer);
455 curr_count= 0; evaluate(x,y,(x+1),(y+2),oplayer);
456 curr_count= 0; evaluate(x,y,(x),(y+2),oplayer);
457 curr_count= 0; evaluate(x,y,(x-1),(y+2),oplayer);
458 curr_count= 0; evaluate(x,y,(x-2),(y+2),oplayer);
459 curr_count= 0; evaluate(x,y,(x-2),(y+1),oplayer);
460 curr_count= 0; evaluate(x,y,(x-2),(y),oplayer);
461 curr_count= 0; evaluate(x,y,(x-2),(y-1),oplayer);
462 }
463 }
464 if (best_count==-1)
465 return(0);
466 move_piece(best.ox,best.oy,best.nx,best.ny,player);
467 }
468
469
470
471
472
473
474
475
476