1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <X11/Xlib.h>
5 #include <X11/Xutil.h>
6 #include <math.h>
7 #include "struct.h"
8 
9 Display *dpy,*odpy,*currdpy;
10 Window win,owin,currwin;
11 GC gc,ogc,currgc;
12 int xsize,ysize,obstacle_color;
13 extern int botmode;
14 extern int oldw, oldb;
15 int scr, oscr, currscr;
16 extern Cursor upc, downc, oupc, odownc;
17 Pixmap bamp, obamp, currbamp;
18 int xwin,ywin, curr_player;
19 extern Bool flumping;
20 extern int botlevel;
21 
22 
print_board()23 print_board()
24 {
25   int x,y,*board;
26   int i,j;
27 
28   x = return_x_size();
29   y = return_y_size();
30 
31   board = (int *) return_board();
32 
33   for (i=0;i!=y;i++) {
34     for (j=0;j!=x;j++)
35       printf("%d ",board[j*y+i]);
36     printf("\n");
37   }
38 }
39 
initialize_display(name)40 initialize_display(name)
41      char *name;
42 {
43   int scn;
44   XSetWindowAttributes attr;
45   XGCValues gcvalues;
46   XSizeHints hints;
47   XClassHint classhint;
48   XWMHints wmhint;
49 
50   xsize = return_x_size();
51   ysize = return_y_size();
52   xwin = xsize*X_PIECE_SIZE;
53   ywin = ysize*Y_PIECE_SIZE+TEXT_SIZE;
54   hints.min_width = xwin;
55   hints.max_width = xwin;
56   hints.min_height = ywin;
57   hints.max_height = ywin;
58   hints.flags = PMinSize | PMaxSize;
59   classhint.res_name = "xataxx";
60   classhint.res_class = "xataxx";
61   wmhint.input = True;
62   wmhint.flags = InputHint;
63 
64   if (xwin < 120) xwin = 120;
65   if (!(dpy = XOpenDisplay(NULL))) {
66     fprintf(stderr,"Could not open local display.  Bummer, drag.\n");
67     exit(1);
68   }
69   if (botmode) {
70     if (!(odpy = XOpenDisplay(name))) {
71       fprintf(stderr,"Could not open display %s.  Bummer, drag.\n",name);
72       exit(1);
73     }
74   }
75 #ifdef DEBUG
76 	printf("Display(s) open.\n");
77 #endif
78   scn = DefaultScreen(dpy);
79   scr = scn;
80   win = XCreateWindow(dpy,DefaultRootWindow(dpy),100,100,xwin,ywin,
81                             1,DefaultDepth(dpy,scr),InputOutput,CopyFromParent,0,0);
82   attr.backing_store = Always;
83   attr.event_mask = ButtonPressMask | KeyPressMask | ButtonReleaseMask
84     | ExposureMask | MotionNotify;
85   attr.background_pixel = BlackPixel(dpy,scr);
86   XChangeWindowAttributes(dpy,win,CWEventMask|CWBackingStore|CWBackPixel,&attr);
87   XSetWMHints(dpy, win, &wmhint);
88   XSetClassHint(dpy, win, &classhint);
89   XSetIconName(dpy,win,"XAtaxx: White");
90   XStoreName(dpy,win,"XAtaxx: White");
91   XSetNormalHints(dpy, win, &hints);
92   XMapWindow(dpy,win);
93   gcvalues.foreground = WhitePixel(dpy,scn);
94   gcvalues.background = BlackPixel(dpy,scn);
95   gc = XCreateGC(dpy,win,GCForeground|GCBackground,&gcvalues);
96   XSetFunction(dpy,gc,GXcopy);
97   bamp = XCreatePixmap(dpy, win, xwin, ywin, DefaultDepth(dpy,scr));
98   if (botmode) {
99     scn = DefaultScreen(odpy);
100     oscr = scn;
101     attr.background_pixel = BlackPixel(odpy,oscr);
102     owin = XCreateWindow(odpy,DefaultRootWindow(odpy),
103 			     100,100,xwin,ywin,
104 			     1,1,InputOutput,CopyFromParent,0,0);
105     XChangeWindowAttributes(odpy,owin,CWEventMask|CWBackingStore|CWBackPixel,&attr);
106     XSetWMHints(odpy, owin, &wmhint);
107     XSetClassHint(odpy, owin, &classhint);
108     XSetIconName(odpy,owin,"XAtaxx: Black");
109     XStoreName(odpy,owin,"XAtaxx: Black");
110     XSetNormalHints(odpy, owin, &hints);
111     XMapWindow(odpy,owin);
112     gcvalues.foreground = WhitePixel(odpy,scn);
113     gcvalues.background = BlackPixel(odpy,scn);
114     ogc = XCreateGC(odpy,owin,GCForeground,&gcvalues);
115     XSetFunction(odpy,ogc,GXcopy);
116     obamp = XCreatePixmap(odpy, owin, xwin, ywin, DefaultDepth(dpy,scr));
117   }
118 
119 #ifdef DEBUG
120 	printf("Opt window dealt with.\n");
121 #endif
122 
123   XFlush(dpy);
124   if (botmode) {
125     XFlush(odpy);
126   }
127 }
128 
wipemap(cdpy,cbamp,cgc,cscr,cwin)129 wipemap(cdpy, cbamp, cgc, cscr, cwin)
130 Display *cdpy;
131 Pixmap cbamp;
132 int cscr;
133 GC cgc;
134 Window cwin;
135 {
136   GC ccgc;
137 
138   ccgc = XCreateGC(cdpy, cwin, 0, 0);
139   XSetForeground(cdpy, ccgc, BlackPixel(cdpy,cscr));
140   XFillRectangle(cdpy, cbamp, ccgc, 0, 0, xwin, ywin);
141   XFlush(cdpy);
142 }
143 
draw_board(board)144 draw_board(board)
145      int *board;
146 {
147   int occ,x,y;
148 
149   if (currdpy != dpy && !botmode)
150     return(0);
151   wipemap(currdpy, currbamp, currgc, currscr, currwin);
152   for (y=0;y!=ysize;y++)
153     for (x=0;x!=xsize;x++)
154       if ((occ=board[x*ysize+y])!=EMPTY) {
155 	if (occ==WHITE)
156 	  draw_circle(x,y,WHITE);
157 	else  {
158 	  if (occ==BLACK)
159 	    draw_circle(x,y,BLACK);
160 	  else
161 	    draw_obstacle(x,y);
162 	}
163       }
164   show_scores(currdpy, currbamp, currgc, oldw, oldb);
165   XFlush(currdpy);
166 }
167 
show_scores(sdpy,swin,sgc,ws,bs)168 show_scores(sdpy, swin, sgc, ws, bs)
169 Display *sdpy;
170 Window swin;
171 GC sgc;
172 int ws, bs;
173 {
174   char mess[100];
175 
176   sprintf(mess,"White: %d",ws);
177   XDrawString(sdpy,swin,sgc,5,ysize*Y_PIECE_SIZE+20,mess,strlen(mess));
178   sprintf(mess,"Black: %d",bs);
179   XDrawString(sdpy,swin,sgc,xsize*X_PIECE_SIZE-55,ysize*Y_PIECE_SIZE+20,mess,strlen(mess));
180   XFlush(sdpy);
181 }
182 
popupbutton(button,x,y)183 popupbutton(button, x, y)
184 unsigned int button;
185 int *x, *y;
186 {
187   XEvent evt;
188   Bool qqx = True;
189 
190   if (currdpy == dpy)
191 	XDefineCursor(dpy,win,downc);
192   else
193 	XDefineCursor(odpy,owin,odownc);
194   while(qqx) {
195 	while(!XCheckTypedWindowEvent(currdpy, currwin, (ButtonPress|ButtonRelease), &evt));
196 	  if (evt.type == ButtonRelease)
197 	    if(evt.xbutton.button == button)
198 	      qqx = False;
199   }
200   *x = evt.xbutton.x;
201   *y = evt.xbutton.y;
202   if (currdpy == dpy)
203 	XDefineCursor(dpy,win,upc);
204   else
205 	XDefineCursor(odpy,owin,oupc);
206 }
207 
208 #define SELWID 5
209 
piece_sel(x,y,display,win,cgc)210 piece_sel(x, y, display, win, cgc)
211 int x,y;
212 Display *display;
213 Window *win;
214 GC cgc;
215 {
216   int qx1, qx2, qy1, qy2;
217   int qq;
218   GC pgc;
219   XGCValues gcvalues;
220 
221   gcvalues.function = GXcopy; /*GXinvert*/
222   pgc = XCreateGC(display,win,GCFunction,&gcvalues);
223   XCopyGC(display,cgc,GCForeground|GCBackground,pgc);
224   qx1 = x*X_PIECE_SIZE;
225   qy1 = y*Y_PIECE_SIZE;
226   qx2 = qx1 + X_PIECE_SIZE;
227   qy2 = qy1 + Y_PIECE_SIZE;
228 
229   XDrawLine(display, win, pgc, qx1, qy1, qx1+SELWID, qy1);
230   XDrawLine(display, win, pgc, qx1, qy1, qx1, qy1+SELWID);
231   XDrawLine(display, win, pgc, qx2, qy1, qx2, qy1+SELWID);
232   XDrawLine(display, win, pgc, qx1, qy2, qx1+SELWID, qy2);
233   XDrawLine(display, win, pgc, qx1, qy2, qx1, qy2-SELWID);
234   XDrawLine(display, win, pgc, qx2, qy1, qx2-SELWID, qy1);
235   XDrawLine(display, win, pgc, qx2, qy2, qx2, qy2-SELWID);
236   XDrawLine(display, win, pgc, qx2, qy2, qx2-SELWID, qy2);
237   XFlush(display);
238 }
239 
inboard(bx,by)240 inboard(bx, by) /* true if x,y is in the board */
241 int bx, by;
242 {
243   if (bx >= return_x_size() || by >= return_y_size())
244 	return(0);
245   else
246     return(1);
247 }
248 
play_loop()249 play_loop()
250 {
251   XEvent event;
252   int currx,curry,cx1,cy1,cx2,cy2,cx3,cy3,down=0,readfds,white,black,x,y;
253   char mess[100],c;
254 
255   curr_player = WHITE;
256   srandom(time(NULL));
257   x = return_x_size();
258   y = return_y_size();
259   place_piece(0,0,WHITE);
260   place_piece(x-1,y-1,WHITE);
261   place_piece(0,y-1,BLACK);
262   place_piece(x-1,0,BLACK);
263   obstacle_color = curr_player;
264   XNextEvent(dpy,&event);
265   redraw_all(curr_player);
266   if (botmode) {
267     XNextEvent(odpy,&event);
268     redraw_all(curr_player);
269   }
270 
271   while (1) {
272     while(!end_game()) {
273       select_player(curr_player);
274       if (!down) {
275         cx1= -1; cy1= -1; cx2= -1; cy2= -1;
276       }
277       XNextEvent(currdpy,&event);
278       switch(event.type) {
279       case ButtonPress:
280 	currx = event.xbutton.x/X_PIECE_SIZE;
281 	curry = event.xbutton.y/Y_PIECE_SIZE;
282 	if (event.xbutton.button == 1)
283 		popupbutton(event.xbutton.button, &cx3, &cy3);
284 	else
285 		break;
286 	cx3 = cx3/X_PIECE_SIZE;
287 	cy3 = cy3/Y_PIECE_SIZE;
288 	if (cx3 == currx && cy3 == curry && inboard(cx3,cy3)) {
289 	  if (cx1 >= 0) {
290             if(!b_peek(cx3, cy3)) {
291 	      cx2 = cx3;
292               cy2 = cy3;
293 	      if(!move_piece(cx1,cy1,cx2,cy2,curr_player)) {
294   	        if (botmode) {
295 	          curr_player = (curr_player==WHITE) ? BLACK : WHITE;
296 	          if (!valid_move(curr_player))
297 		    curr_player = (curr_player==WHITE) ? BLACK : WHITE;
298 	        }
299 	        else {
300 		  if (valid_move(BLACK))
301 	            obstacle_color = BLACK;
302 		  redraw_all(WHITE);
303 	          redraw_win(currdpy, currwin, currbamp, currgc);
304                   if (valid_move(BLACK) && botlevel < 2)
305 		    msec_wait(557567);
306 		  robot_move(BLACK);
307                   flumping = False;
308 	            while(!valid_move(WHITE)&&valid_move(BLACK)) {
309 		      redraw_all(WHITE);
310 		      orobot_move(BLACK);
311 	            }
312 		  flumping = True;
313 	        }
314               } /* matches if(!move_piece(cx1,cy1,cx2,cy2,curr_player))  */
315 	      obstacle_color = curr_player;
316 	      down = 0;
317 	      redraw_all(curr_player);
318             }
319 	    else {
320 	      if (b_peek(cx3,cy3) == curr_player && inboard(cx3,cy3)) {
321 		if(cx3 == cx1 && cy3 == cy1) {
322 		  redraw_all(curr_player);
323 		  cx1 = -1; cy1 = -1;
324 		  down=0;
325 		}
326 		else {
327 		  if (inboard(cx3,cy3)) {
328 		    piece_sel(cx1,cy1, currdpy, currwin, currgc);
329 		    cx1 = cx3; cy1 = cy3;
330 			redraw_all(curr_player);
331 		    piece_sel(cx1,cy1, currdpy, currwin, currgc);
332                   }
333 		}
334 	      }
335             }
336           } /* matches if (cx1 >= 0)  */
337 	  else {
338 	    if(b_peek(currx, curry) == curr_player) {
339 		cx1 = cx3;
340 		cy1 = cy3;
341 		piece_sel(cx1,cy1, currdpy, currwin, currgc);
342 		down = 1;
343 	    }
344 	  }
345 	}
346         flumping = False;
347 	while((!count_board(BLACK)) && valid_move(WHITE)) {
348 	  orobot_move(WHITE);
349 	  redraw_all(WHITE);
350 	}
351 	while((!count_board(WHITE)) && valid_move(BLACK)) {
352 	  orobot_move(BLACK);
353 	  redraw_all(BLACK);
354 	}
355         flumping = True;
356 	break;
357       case Expose:
358 	redraw_win(currdpy, currwin, currbamp, currgc);
359 	break;
360       case KeyPress:
361 	XLookupString(&event, &c, 1, NULL, NULL);
362 	if (c == 'q')
363 		quit();
364 	break;
365       default:
366 	break;
367       } /* matches switch(event.type) { */
368     } /* matches while(!end_game()) { */
369     white = count_board(WHITE);
370     black = count_board(BLACK);
371     oldw = white;
372     oldb = black;
373     if (white > black)
374       sprintf(mess,"White is the winner.");
375     else {
376       if (black > white)
377 	sprintf(mess,"Black is the winner.");
378       else
379 	sprintf(mess,"The game is a tie.");
380     }
381 
382     select_player(WHITE);
383     XDrawString(currdpy,currwin,currgc,5,ysize*Y_PIECE_SIZE+35,mess,strlen(mess));
384     XFlush(currdpy);
385     if (botmode) {
386       select_player(BLACK);
387       XDrawString(currdpy,currwin,currgc,5,ysize*Y_PIECE_SIZE+35,mess,strlen(mess));
388       XFlush(currdpy);
389     }
390     XNextEvent(dpy,&event);
391     return(0);
392   }
393 }
394 
init_pieces()395 init_pieces()
396 {
397   int curr_player=WHITE,x,y;
398 
399   /* Place initial pieces */
400   x = return_x_size();
401   y = return_y_size();
402   clean_board();
403   place_piece(0,0,WHITE);
404   place_piece(x-1,y-1,WHITE);
405   place_piece(0,y-1,BLACK);
406   place_piece(x-1,0,BLACK);
407   curr_player = WHITE;
408   obstacle_color = curr_player;
409   redraw_all(curr_player);
410 }
411 
redraw_all(curr_player)412 redraw_all(curr_player)
413 {
414   select_player(WHITE);
415   oldw = count_board(WHITE);
416   oldb = count_board(BLACK);
417   draw_board(return_board());
418   redraw_win(currdpy, currwin, currbamp, currgc);
419   if (botmode) {
420     select_player(BLACK);
421     draw_board(return_board());
422     redraw_win(currdpy, currwin, currbamp, currgc);
423   }
424   select_player(curr_player);
425 }
426 
select_player(curr_player)427 select_player(curr_player)
428      int curr_player;
429 {
430   if (curr_player==WHITE) {
431     currdpy = dpy;
432     currwin = win;
433     currgc = gc;
434     currbamp = bamp;
435     currscr = scr;
436   }
437   else {
438     currdpy = odpy;
439     currwin = owin;
440     currgc = ogc;
441     currbamp = obamp;
442     currscr = oscr;
443   }
444 }
445 
446 
447 
448 
449