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