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