source: buchla-68k/orig/GEMDOS/REVERSI2.C@ 9519422

Last change on this file since 9519422 was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 8 years ago

Imported original source code.

  • Property mode set to 100755
File size: 17.1 KB
Line 
1/*
2 =============================================================================
3 reversi2.c -- REVERSI-II Desk Accessory.
4 Version 6 -- 1988-09-21 -- Mods by D.N. Lynx Crowe
5
6 Written by Christophe Bonnet. 5/08/86
7
8 Define TWIDDLE to slow down the computer...
9 =============================================================================
10*/
11
12#include "stddefs.h"
13#include "gemdefs.h"
14
15#define HIDE_MOUSE graf_mouse(M_OFF,0x0L);
16#define SHOW_MOUSE graf_mouse(M_ON,0x0L);
17#define WI_KIND (MOVER|NAME|CLOSER|INFO)
18#define NO_WINDOW (-1)
19
20#define TRUE 1
21#define FALSE 0
22#define WHITE 0
23#define BLACK 1
24#define RED 2
25#define MEDIUM 1
26#define LOW 0
27#define HIGH 2
28
29#define Getrez() (int)xbios(4) /* define these two links here so you */
30#define Random() xbios(17) /* don't have to include OSBIND.H */
31
32extern long xbios();
33extern int gl_apid;
34
35/*
36
37*/
38
39/* Global variables : For use in Gem aes and vdi calls *********************/
40/* Note: A great part of these variables are the same as in ACCSKEL.C */
41
42int menu_id, phys_handle, handle, wi_handle, top_window;
43int xdesk, ydesk, hdesk, wdesk, hchar, wchar;
44int hbox, wbox, xold, yold, hold, wold;
45int xwork, ywork, hwork, wwork, hidden, fulled, handed, screen_rez;
46int msgbuff[8], keycode, mx, my, butdown, pstatus, ret, ret1, ret2, ret3, ret4;
47int contrl[12], intin[128], ptsin[128], intout[128], ptsout[128];
48int work_in[11], work_out[57], pxyarray[10];
49
50typedef struct grect { /* this structure for clipping and rectangle */
51 /* drawings. Must be defined here because we */
52 int g_x; /* don't include OBDEFS.H library file to save */
53 int g_y; /* memory and compilation time ... */
54 int g_w;
55 int g_h;
56
57} GRECT;
58
59/* These are used in the main part of the program: game variables ***********/
60
61int b_grid[10][10], c_grid[10][10];
62
63int b_init[10][10]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 16, -4, 5, 1, 1, 5, -4, 16, 0,
65 0, -4,-12, -2, -2, -2, -2,-12, -4, 0,
66 0, 5, -2, 4, 2, 2, 4, -2, 5, 0,
67 0, 1, -2, 2, 1, 1, 2, -2, 1, 0,
68 0, 1, -2, 2, 1, 1, 2, -2, 1, 0,
69 0, 5, -2, 4, 2, 2, 4, -2, 5, 0,
70 0, -4,-12, -2, -2, -2, -2,-12, -4, 0,
71 0, 16, -4, 5, 1, 1, 5, -4, 16, 0,
72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
73
74int score[4], phase, adv, pass, v, w, valide, value, end=FALSE;
75int x_offset, y_offset;
76int c_wstart, c_hstart, c_width, c_heigth, w_width, w_heigth, x_rad, y_rad;
77int x_border, y_border, dial_a, dial_b, score_a, score_b, size, tab;
78int pgames, mgames;
79
80/*
81
82*/
83
84/* open a virtual screen workstation ***** from ACCSKEL.C *****************/
85
86open_vwork()
87{
88 int i;
89
90 for(i = 0; i < 10; work_in[i++] = 1) ;
91
92 work_in[10] = 2; /* Raster Coordinates */
93 handle = phys_handle;
94 v_opnvwk(work_in, &handle, work_out);
95}
96
97/* open a Gem window ******************************************************/
98
99open_window()
100{
101 wi_handle=wind_create(WI_KIND, xdesk, ydesk, wdesk, hdesk);
102
103 wind_set(wi_handle, WF_NAME, " REVERSI-II ", 0, 0);
104 wind_set(wi_handle, WF_INFO, " ", 0, 0);
105
106 wind_open(wi_handle, xdesk+wdesk/2 -(w_width/2),
107 ydesk+hdesk/2 -(w_heigth/2),
108 w_width, w_heigth);
109
110 wind_get(wi_handle, WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
111}
112
113/*
114
115*/
116
117/* entry point of this program **********************************************/
118
119main()
120{
121 appl_init();
122
123 phys_handle = graf_handle(&ret1, &ret2, &ret3, &ret4);
124 menu_id = menu_register(gl_apid, " Reversi-II");
125
126 wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
127
128 wi_handle = NO_WINDOW;
129
130 top_window = TRUE;
131 butdown = TRUE;
132
133 hidden = FALSE;
134 handed = FALSE;
135 fulled = FALSE;
136
137 mgames = 0;
138 pgames = 0;
139
140 screen(); /* draw the game board */
141 init(); /* initialize the variables */
142 multi();
143}
144
145/*
146
147*/
148
149/* accessory tasks dispatched by the MULTI function ***********************/
150
151multi()
152{
153 int event;
154
155 while (TRUE) {
156
157 event=evnt_multi(MU_MESAG |MU_BUTTON |MU_KEYBD |MU_M1 |MU_M2 ,
158 1,1,1,
159 0,xwork,ywork,wwork,hwork,
160 1,xwork,ywork,wwork,hwork,
161 msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
162
163 wind_update(TRUE);
164 wind_get(wi_handle,WF_TOP,&top_window,&ret,&ret,&ret);
165
166 if (event & MU_MESAG)
167 switch (msgbuff[0]) {
168
169 case WM_NEWTOP:
170 case WM_TOPPED:
171
172 if(msgbuff[3] == wi_handle)
173 wind_set(wi_handle,WF_TOP,0,0,0,0);
174 break;
175
176 case AC_CLOSE:
177
178 if((msgbuff[3] == menu_id) &&
179 (wi_handle != NO_WINDOW)){
180
181 v_clsvwk(handle);
182 wi_handle=NO_WINDOW;
183 }
184
185 break;
186/*
187
188*/
189 case WM_CLOSED:
190
191 if(msgbuff[3] == wi_handle){
192
193 wind_close(wi_handle);
194
195 graf_shrinkbox(xwork+wwork/2,ywork+hwork/2,0,0,
196 xwork,ywork,wwork,hwork);
197
198 wind_delete(wi_handle);
199 v_clsvwk(handle);
200 wi_handle=NO_WINDOW;
201 }
202
203 break;
204
205 case AC_OPEN:
206
207 if(msgbuff[4] == menu_id) {
208
209 if(wi_handle == NO_WINDOW){
210
211 open_vwork();
212 open_window();
213 event=0;
214
215 } else
216 wind_set(wi_handle,WF_TOP,0,0,0,0);
217 }
218
219 break;
220
221 case WM_REDRAW:
222
223 if(msgbuff[3] == wi_handle)
224 do_redraw(msgbuff[4],msgbuff[5],
225 msgbuff[6],msgbuff[7]);
226
227 break;
228/*
229
230*/
231 case WM_SIZED:
232 case WM_MOVED:
233
234 if(msgbuff[3] == wi_handle){
235
236 wind_set(wi_handle,WF_CURRXYWH,msgbuff[4],
237 msgbuff[5],msgbuff[6],msgbuff[7]);
238
239 wind_get(wi_handle,WF_WORKXYWH,
240 &xwork,&ywork,&wwork,&hwork);
241 }
242
243 break;
244
245 } /* switch msgbuff[0] */
246
247 if((event & MU_BUTTON) && (
248 top_window == wi_handle) && (handed)) {
249
250 pass=0;
251 turn();
252 }
253
254 if((event & MU_M1) && (top_window == wi_handle)) {
255
256 if(!handed) {
257
258 graf_mouse(POINT_HAND,0x0L);
259 handed=TRUE;
260 }
261 }
262
263 if(event & MU_M2) {
264
265 if(handed) {
266
267 graf_mouse(ARROW,0x0L);
268 handed=FALSE;
269 }
270 }
271
272 if((event & MU_KEYBD) && (top_window == wi_handle)) {
273
274 pass=1; /* if the player pressed a key */
275 turn(); /* then go to ATARI game turn */
276 }
277
278 wind_update(FALSE);
279 }
280}
281
282/*
283
284*/
285
286/* drawing of game board and counters ************************************/
287
288board()
289{
290 register int i,j,temp[4];
291
292 vswr_mode(handle,1);
293
294 rectangle(xwork, ywork, wwork, hwork, BLACK);
295
296 HIDE_MOUSE;
297
298 if(screen_rez == HIGH)
299 vsf_style(handle,4);
300 else
301 vsf_color(handle,RED);
302
303 temp[0]=x_border+xwork;
304 temp[1]=y_border+ywork;
305 temp[2]=xwork+x_border+(c_width * 8);
306 temp[3]=ywork+y_border+(c_heigth * 8);
307
308 v_bar(handle,temp);
309
310 vsf_color(handle,BLACK);
311
312 for(i=1;i<10;i++) {
313
314 temp[0]=xwork+(i * c_width) - c_wstart;
315 temp[1]=ywork+y_border;
316 temp[2]=xwork+(i * c_width) - c_wstart;
317 temp[3]=ywork+y_border+(c_heigth * 8);
318
319 v_pline(handle,2,temp);
320
321 temp[0]=xwork+x_border;
322 temp[1]=ywork+(i * c_heigth) - c_hstart;
323 temp[2]=xwork+x_border+(c_width * 8);
324 temp[3]=ywork+(i * c_heigth) - c_hstart;
325
326 v_pline(handle,2,temp);
327 }
328/*
329
330*/
331 for(i = 1; i < 9; i++) {
332
333 for(j = 1; j < 9; j++) {
334
335 if(c_grid[i][j] > 1) {
336
337 vsf_interior(handle,2);
338 vsf_style(handle,8);
339 vsf_color(handle,1);
340
341 if(c_grid[i][j] == 3)
342 vsf_color(handle,0);
343
344 v_ellipse(handle,
345 xwork+(i * c_width)-x_border+x_offset,
346 ywork+(j * c_heigth)-y_border+y_offset,
347 x_rad, y_rad);
348 }
349 }
350 }
351
352/*
353
354*/
355 vsf_color(handle,WHITE);
356
357 v_ellipse(handle, xwork+wwork-x_rad-3, ywork+dial_a, x_rad+3, y_rad+3);
358 v_ellipse(handle, xwork+wwork-x_rad-3, ywork+dial_b, x_rad+3, y_rad+3);
359
360 vsf_color(handle, BLACK);
361 v_ellipse(handle, xwork+wwork-x_rad-3, ywork+dial_a, x_rad, y_rad);
362
363 display();
364
365 wind_set(wi_handle, WF_INFO, "Your move...", 0, 0);
366
367 SHOW_MOUSE;
368}
369
370/*
371
372*/
373
374/* clipping rectangles coordinates ******* from ACCSKEL.C *****************/
375
376set_clip(x, y, w, h)
377int x, y, w, h;
378{
379 int clip[4];
380
381 clip[0] = x;
382 clip[1] = y;
383 clip[2] = x + w;
384 clip[3] = y + h;
385
386 vs_clip(handle, 1, clip);
387}
388
389/*
390
391*/
392
393/* find and redraw all clipping rectangles ***** from ACCSKEL.C ************/
394
395do_redraw(xc, yc, wc, hc)
396int xc, yc, hc, wc;
397{
398 GRECT t1,t2;
399
400 HIDE_MOUSE;
401
402 wind_update(TRUE);
403
404 t2.g_x=xc;
405 t2.g_y=yc;
406 t2.g_w=wc;
407 t2.g_h=hc;
408
409 wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
410
411 while(t1.g_w && t1.g_h) {
412
413 if (rc_intersect(&t2, &t1)) {
414
415 set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
416 board();
417 }
418
419 wind_get(wi_handle, WF_NEXTXYWH,
420 &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
421
422 }
423
424 wind_update(FALSE);
425
426 SHOW_MOUSE;
427}
428
429/*
430
431*/
432
433/* game turn of the human player (you!) ************************************/
434
435player()
436{
437 int i,j,vj,wj,temp[4];
438
439 /* transform mouse coordinates into grid coordinates */
440
441 v=(mx + c_wstart - xwork) / c_width;
442 w=(my + c_hstart - ywork) / c_heigth;
443
444 if (v > 0 && v < 9 && w > 0 && w < 9)
445 sub_1();
446}
447
448/*
449
450*/
451
452/* game turn of the computer ***********************************************/
453
454atari()
455{
456 int verify(), i, j, point = (-99), flip;
457
458 value = (-99);
459
460 for(i = 1; i < 9; i++) {
461
462 for(j = 1; j < 9; j++) {
463
464 if(c_grid[i][j] == 1) {
465
466 flip = verify(i,j);
467
468 if(flip > 0) {
469
470 if(score[2]+score[3] < 34)
471 flip = (-flip);
472
473 if(score[2]+score[3] > 56)
474 flip = flip * 6;
475
476 value = (b_grid[i][j] * 3) + flip;
477
478 if(value > point) {
479
480 point = value;
481 v = i;
482 w = j;
483 }
484
485 if((value == point) &&
486 ((Random() & 10) < 5)) {
487
488 point = value;
489 v = i;
490 w = j;
491 }
492 }
493 }
494 }
495 }
496
497 if(point == (-99))
498 pass++;
499 else
500 change(v,w);
501}
502
503/*
504
505*/
506
507/* display the score of both players ***************************************/
508
509display()
510{
511 int units,tens;
512 char string[10];
513
514 HIDE_MOUSE;
515
516 vst_color(handle,BLACK);
517 vst_height(handle,size,&wchar,&hchar,&wbox,&hbox);
518
519 rectangle(xwork+wwork-tab,ywork+score_a-hchar,wbox * 2,hbox,BLACK);
520 rectangle(xwork+wwork-tab,ywork+score_b-hchar,wbox * 2,hbox,BLACK);
521
522 vswr_mode(handle,3);
523
524 tens=score[2]/10; /* convert an integer in */
525 units=( score[2]-( tens * 10)); /* a string of char... */
526 string[0]=tens + 48;
527 string[1]=units + 48;
528 string[2]='\0';
529
530 v_gtext(handle,xwork+wwork-tab,ywork+score_a,string);
531
532 tens=score[3]/10;
533 units=( score[3]-( tens * 10));
534 string[0]=tens + 48;
535 string[1]=units + 48;
536
537 v_gtext(handle,xwork+wwork-tab,ywork+score_b,string);
538
539 vswr_mode(handle,1);
540
541 SHOW_MOUSE;
542}
543
544/*
545
546*/
547
548/* game turn : PLAYER ---> ATARI, and return to MULTI function *************/
549
550turn()
551{
552 if(end == TRUE) {
553
554 end=FALSE;
555 pass=0;
556 init();
557 set_clip(xwork,ywork,wwork,hwork);
558 board();
559
560 } else {
561
562 valide=FALSE;
563 phase=2;
564 adv=3;
565
566 if(pass == 0)
567 player();
568 else
569 valide=TRUE;
570
571 display();
572
573 if(valide == TRUE) {
574#ifdef TWIDDLE
575 wait();
576#endif
577 if(score[2]+score[3] == 64)
578 end=TRUE;
579
580 phase=3;
581 adv=2;
582 atari();
583 display();
584
585 if(pass == 2 || score[2] + score[3] == 64)
586 end=TRUE;
587 }
588
589 HIDE_MOUSE;
590 wind_update(TRUE);
591
592 if(end == FALSE)
593 wind_set(wi_handle, WF_INFO, "Your move...", 0, 0);
594 else
595 stop();
596
597 wind_update(FALSE);
598 SHOW_MOUSE;
599 }
600}
601
602/*
603
604*/
605
606/* sub-routine 1 of player loop ********************************************/
607
608sub_1()
609{
610 if(c_grid[v][w] == 1)
611 sub_2();
612}
613
614/* sub-routine 2 of player loop ********************************************/
615
616sub_2()
617{
618 int verify(),flip;
619
620 flip=verify(v,w);
621
622 if(flip > 0) {
623
624 change(v,w);
625 valide = TRUE;
626 }
627}
628
629/*
630
631*/
632
633/* verify if the phasing player could return at least 1 opposing counter ***/
634
635int verify(a,b)
636int a,b;
637{
638 int flop,i,j,dx,dy,flap,flag;
639
640 flop=0;
641
642 for(i = (-1);i<2;i++) {
643
644 for(j = (-1);j<2;j++) {
645
646 if(i != 0 || j != 0) {
647
648 flap=0;
649 flag=0;
650 dx=a+i;
651 dy=b+j;
652
653 while((c_grid[dx][dy] > 1) && (flag == 0)) {
654
655 if(c_grid[dx][dy] == phase) {
656
657 flag=1;
658 flop+=flap;
659 }
660
661 flap++;
662 dx+=i;
663 dy+=j;
664 }
665 }
666 }
667 }
668
669 return(flop);
670}
671
672/*
673
674*/
675
676/* return counters on screen and as variables ******************************/
677
678change(a,b)
679int a,b;
680{
681 int i,j,dx,dy,flag1,flag2,flop;
682
683 wind_update(TRUE);
684 set_clip(xwork,ywork,wwork,hwork);
685 vswr_mode(handle,1);
686 vsf_interior(handle,2);
687 vsf_style(handle,8);
688 vsf_color(handle,1);
689
690 if(phase == 3)
691 vsf_color(handle,0);
692
693 HIDE_MOUSE;
694
695 v_ellipse(handle, xwork+(a * c_width)-x_border+x_offset,
696 ywork+(b * c_heigth)-y_border+y_offset, x_rad,y_rad);
697
698 c_grid[a][b]=phase;
699 score[phase]++;
700
701 modify(a,b);
702
703 for(i = (-1);i<2;i++) {
704
705 for(j = (-1);j<2;j++) {
706
707 if((i != 0) || (j != 0)) {
708
709 dx=a;
710 dy=b;
711 flag1=0;
712 flop=0;
713/*
714
715*/
716 do {
717
718 dx+=i;
719 dy+=j;
720
721 if(c_grid[dx][dy] < 2)
722 flag1=1;
723
724 if(c_grid[dx][dy] == adv)
725 flop+=1;
726
727 if(c_grid[dx][dy] == phase) {
728
729 flag1=1;
730
731 if(flop >0) {
732
733 flag2=0;
734
735 do {
736
737 dx-=i;
738 dy-=j;
739
740 if((dx == a) && (dy == b))
741 flag2=1;
742 else {
743
744 c_grid[dx][dy]=phase;
745
746 v_ellipse(handle,
747 xwork+(dx * c_width)-x_border+x_offset,
748 ywork+(dy * c_heigth)-y_border+y_offset,
749 x_rad,y_rad);
750
751 score[phase]++;
752 score[adv]--;
753 }
754
755 } while(flag2 == 0);
756 }
757 }
758
759 } while(flag1 == 0);
760 }
761 }
762 }
763
764 SHOW_MOUSE;
765 wind_update(FALSE);
766}
767
768/*
769
770*/
771
772/* modify values of some cases following a move ****************************/
773
774modify(a,b)
775int a,b;
776{
777 int i,j;
778
779 if(b_grid[a][b] == 16) {
780
781 for(i=a + (-2);i<a+3;i++) {
782
783 if(i > 0 && i < 9) {
784
785 for(j=b + (-2);j<b+3;j++) {
786
787 if(j > 0 && j < 9) {
788
789 if(b_grid[i][j] < (-3))
790 b_grid[i][j]=0;
791 }
792 }
793 }
794 }
795
796 } else if(b_grid[a][b] == 5) {
797
798 for(i=a + (-1);i<a+2;i++) {
799
800 for(j=b + (-1);j<b+2;j++) {
801
802 if(b_grid[i][j] == 1)
803 b_grid[i][j]=3;
804
805 if(b_grid[i][j] == (-2))
806 b_grid[i][j]=1;
807 }
808 }
809 }
810}
811
812/*
813
814*/
815
816/* end of the game *********************************************************/
817
818stop()
819{
820 int tens, units;
821 char buffer[32];
822 char string[10];
823
824 if(score[2] EQ score[3]) {
825
826 ++pgames;
827 ++mgames;
828 strcpy(buffer, "Null game ");
829
830 } else if(score[2] > score[3]) {
831
832 ++pgames;
833 strcpy(buffer, "You WIN ");
834
835 } else {
836
837 ++mgames;
838 strcpy(buffer, "You LOSE ");
839 }
840
841 tens = pgames / 10;
842 units = pgames - (tens * 10);
843 string[0] = tens + 48;
844 string[1] = units + 48;
845 string[2] = ':';
846
847 tens = mgames / 10;
848 units = mgames - (tens * 10);
849 string[3] = tens + 48;
850 string[4] = units + 48;
851 string[5] = '\0';
852
853 strcat(buffer, string);
854
855 wind_set(wi_handle, WF_INFO, buffer, 0, 0);
856}
857
858/*
859
860*/
861
862/* variable initialisation ************************************************/
863
864init()
865{
866 int i,j;
867
868 for(i=0;i<10;i++)
869 for(j=0;j<10;j++)
870 b_grid[i][j]=b_init[i][j];
871
872 for(i=0;i<10;i++) {
873
874 for(j=0;j<10;j++) {
875
876 if((i == 0) || (j == 0) || (i == 9) || (j == 9))
877 c_grid[i][j]=0;
878 else
879 c_grid[i][j]=1;
880 }
881 }
882
883 c_grid[4][4]=2;
884 c_grid[5][5]=2;
885
886 c_grid[4][5]=3;
887 c_grid[5][4]=3;
888
889 score[2]=2;
890 score[3]=2;
891}
892
893/*
894
895*/
896
897/* draw a filled rectangle of specified size and color *********************/
898
899rectangle(x,y,w,h,color)
900int x,y,w,h,color;
901{
902 int temp[4];
903
904 HIDE_MOUSE;
905
906 vsf_interior(handle,2);
907 vsf_style(handle,8);
908 vsf_color(handle,color);
909
910 temp[0]= x;
911 temp[1]= y;
912 temp[2]= x + w - 1;
913 temp[3]= y + h - 1;
914
915 v_bar(handle,temp);
916
917 SHOW_MOUSE;
918}
919
920/*
921
922*/
923
924#ifdef TWIDDLE
925
926/* delay loop during computer's turn ***************************************/
927
928wait()
929{
930 int i,j;
931
932 wind_set(wi_handle,WF_INFO,"...... \0",0,0);
933
934 for(i=0; i<6; i++)
935 for(j=0;j<32000;j++)
936 ;
937}
938
939#endif
940
941/*
942
943*/
944
945/* allocate values to drawing variables, depending on screen resolution ****/
946
947screen()
948{
949 x_border = 6; y_border = 6;
950 x_rad = 9; y_rad = 9;
951 x_offset = 2; y_offset = 2;
952 c_wstart = 14; c_hstart = 14;
953 c_width = 20; c_heigth = 20;
954 w_width = 200; w_heigth = 210;
955 dial_a = 40; dial_b = 100;
956 score_a = 60; score_b = 120;
957 tab = 20; size = 6;
958
959 screen_rez = Getrez(); /* get screen resolution */
960
961 switch(screen_rez) {
962
963 case LOW:
964
965 x_border = 3;
966 x_rad = 4;
967 x_offset = 1;
968 c_wstart = 7;
969 c_width = 10;
970 w_width = 100;
971 tab = 12; size = 4;
972
973 case MEDIUM:
974
975 y_border = 3;
976 y_rad = 4;
977 y_offset = 1;
978 c_hstart = 7;
979 c_heigth = 10;
980 w_heigth = 110;
981 score_a = 37; score_b = 67;
982 dial_a = 20; dial_b = 50;
983 }
984}
Note: See TracBrowser for help on using the repository browser.