home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OS9_6X09 / GAMES / Reversi.lzh / board.c next >
Text File  |  1991-05-22  |  9KB  |  414 lines

  1. /* SCC$board.c#mwc0.01/26Apr1991 */
  2. /* game board for reversi.c
  3. *  by Joel Matthew Rees, Dec '89
  4. *  Modified for MS-DOS/TURBO-C March 1991
  5. *  eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991
  6. *  new OS-9/CoCo version Apr/May 1991
  7. *  This program is assigned by the author to the public domain.
  8. */
  9.  
  10.  
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include <sgstat.h>
  14. #include <common.h>
  15.  
  16.  
  17. #include "rev_img.h"
  18. #define BOARD
  19. #include "board.h"
  20.  
  21.  
  22. #define MAXUSER 16 /* assume no more than this */
  23.  
  24.  
  25. #define CELL 22 /* even for border and center */
  26. #define bdHOME 0
  27. #define bdHOMEpx 2
  28. #define bdFAR 23 /* ((CELL + 1) * WIDTH) / 8 */
  29.  
  30. /* p * 22 */
  31. static uint off(p)
  32. uint p;
  33. {
  34. #asm
  35.  clra
  36.  ldb 5,s
  37.  lslb
  38.  lslb   *4
  39.  addb 5,s   *5
  40.  lslb   *10
  41.  addb 5,s   *11
  42.  lslb   *22
  43.  addb #2 bdHOMEpx
  44. #endasm
  45. }
  46.  
  47.  
  48. #define PIECEoff 2 /* (CELL - piecex + 1) / 2 */
  49. #define CURSORoff 7 /* (CELL - cursx + 1) / 2 */
  50.  
  51.  
  52. /* buffer numbers: */
  53. /* BLACK is 1, WHITE is -1 (= 255) */
  54. /* ILLEGAL is 2, XHAIR is 3 */
  55. #define FONT 4
  56.  
  57.  
  58. /* window types */
  59. #define WT40X24 1
  60. #define WT80X24 2
  61. #define WGHI2CO 5
  62. #define WGMD4CO 6
  63. #define WGHI4CO 7
  64. #define WGMD16CO 8
  65. /* colors (depend on put logic, also on palette settings) */
  66. #define cWHITE 0
  67. #define cBLUE 1
  68. #define cBLACK 2
  69. #define cGREEN 3
  70. /* image put logic */
  71. #define lNONE 0
  72. #define lAND 1
  73. #define lOR 2
  74. #define lXOR 3
  75. /* overlay window save select */
  76. #define oSAVE 1
  77. #define oNOSAVE 0
  78.  
  79.  
  80. int path;
  81.  
  82. static struct sgbuf wstat;
  83. int group;
  84.  
  85. /* set up a window as a graphics window to run the game in
  86. *  return -1 if unable to set window up properly
  87. */
  88. int gograph()
  89. {
  90.   if ((path = open("/w", _READ | _WRITE))  < 0) {
  91.     fprintf(stderr, "error opening graphics window\n");
  92.     exit (-1);
  93.   }
  94.   if (getstat(0, path, &wstat) < 0) {
  95.     fprintf(stderr, "error accessing window modes\n");
  96.     exit (-1);
  97.   }
  98.   wstat.sg_case = wstat.sg_echo = wstat.sg_alf = wstat.sg_pause = 0;
  99.   if (setstat(0, path, &wstat) < 0) {
  100.     fprintf(stderr, "error changing window modes\n");
  101.     exit (-1);
  102.   }
  103.   DWSet(path, WGMD4CO, 0, 0, 40, 24, cBLUE, cGREEN, cBLUE);
  104.   ScaleSw(path, FALSE);
  105.   Select(path);
  106.   group = getuid();
  107.   CurOff(path);
  108.   if (group == 0)
  109.     group = MAXUSER; /* group 0 reserved */
  110.   GPLoad(path, group, FONT, gcfontty, gcfontx, gcfontx, gcfontln, gcfont);
  111. /*  write(path, gcfont, gcfontln); GPLoad actually takes care of this,
  112. *   contrary to the what the MultiVue docs */
  113.   Font(path, group, FONT);
  114.   GPLoad(path, group, BLACK, piecety, piecex, piecex, blackln, black);
  115.   GPLoad(path, group, WHITE, piecety, piecex, piecex, whiteln, white);
  116.   GPLoad(path, group, ILLEGAL, cursty, cursx, cursx, illln, illegal);
  117.   GPLoad(path, group, XHAIR, cursty, cursx, cursx, arcxhaln, arcxhair);
  118.   LSet(path, lNONE);
  119.   return (path);
  120. }
  121.  
  122.  
  123. endgraph()
  124. {
  125.   KilBuf(path, group, FONT);
  126.   KilBuf(path, group, BLACK);
  127.   KilBuf(path, group, WHITE);
  128.   KilBuf(path, group, ILLEGAL);
  129.   KilBuf(path, group, XHAIR);
  130.   DWEnd(path);
  131.   close(path);
  132.   putchar(0x1b); putchar(0x21); /* reselect start window */
  133. }
  134.  
  135.  
  136. /* draw a line from (x0, y0) to (x, y)
  137. *  leaves draw pointer at (x0, y0)
  138. */
  139. static line(x0, y0, x, y)
  140. int x0, y0, x, y;
  141. {
  142.   SetDPtr(path, x0, y0);
  143.   Line(path, x, y);
  144. }
  145.  
  146.  
  147. /* set up the playing board on the screen, without pieces
  148. */
  149. static grid(home, sq_sz, sq_ct)
  150. uint home; uint sq_sz; uint sq_ct;
  151. {
  152.   uint i;
  153.   uint term = sq_ct * sq_sz + home;
  154.  
  155.   for (i=home; i<=term; i+=sq_sz)
  156.   {
  157.     line(home, i, term, i);
  158.     line(i, home, i, term);
  159.   }
  160. }
  161.  
  162.  
  163. /* put board on screen
  164. */
  165. putboard()
  166. {
  167.   OWSet(path, oNOSAVE, bdHOME, bdHOME, bdFAR, bdFAR, cBLUE, cGREEN);
  168.   Clear(path);
  169.   grid(bdHOMEpx, CELL, WIDTH); /* skip edge */
  170.   OWEnd(path);
  171.   OWSet(path, oNOSAVE, bdFAR, bdHOME, 40 - bdFAR, 24, cBLUE, cBLUE);
  172.   Clear(path);
  173.   OWEnd(path);
  174.   OWSet(path, oNOSAVE, bdHOME, bdFAR, 40, 24 - bdFAR, cBLUE, cBLUE);
  175.   Clear(path);
  176.   OWEnd(path);
  177. }
  178.  
  179.  
  180. /* put a player's piece on the board at position (x, y)
  181. */
  182. putpiece(player, x, y)
  183. SQUARE player; uint x; uint y;
  184. {
  185.   PutBlk(path, group, player, off(x) + PIECEoff, off(y) + PIECEoff);
  186. }
  187.  
  188.  
  189. /* convert up to two digits of count into a decimal string in buffer
  190. *  (buffer should be at least 3 bytes)
  191. *  return address of buffer passed in
  192. */
  193. static char *convert(buffer, count)
  194. char *buffer; int count;
  195. {
  196.   register char *at = buffer;
  197.   int dig1 = count / 10;
  198.  
  199.   if (dig1 != 0)
  200.     *at++ = dig1 + '0';
  201.   *at++ = (count % 10) + '0';
  202.   *at = NUL;
  203.   return (buffer);
  204. }
  205.  
  206.  
  207. #define gxHOME bdFAR
  208. #define gxGL 24
  209. #define gWID 32
  210. #define gxGR 80
  211. #define gxFAR 17
  212. #define gyHOME 0
  213. #define gyTURN 12
  214. #define gySCORE 9
  215. #define gyGAUGE 68 /* 9 * 8 - 4 */
  216. #define gyFAR 15
  217.  
  218.  
  219. static char buffer[4];
  220.  
  221. /* put a bar on the screen, with variable fill
  222. *   puts bars upside up
  223. *   alters the draw pointer
  224. */
  225. static gauge(xhome, height, player)
  226. uint xhome; uint height; int player;
  227. {
  228.   FColor(path, (player == WHITE) ? cWHITE : cBLACK);
  229.   CurXY(path, (xhome >> 3) + 1, gySCORE);
  230.   write(path, convert(buffer, height), 2);
  231.   SetDPtr(path, xhome, gyGAUGE);
  232.   Bar(path, xhome + gWID, gyGAUGE - height);
  233. }
  234.  
  235.  
  236. /* show count graphically and numerically,
  237. *   using turn to determine gauge to put on left
  238. */
  239. static gauges(bpts, wpts, turn)
  240. uint bpts; uint wpts; SQUARE turn;
  241. {
  242.   int left = turn;
  243.  
  244.   OWSet(path, oNOSAVE, gxHOME, gyHOME, gxFAR, gyFAR, cGREEN, cBLUE);
  245.   Clear(path);
  246.   CurXY(path, 0, gyTURN);
  247.   if (turn == NONE) {
  248.     left = (wpts > bpts) ? WHITE : BLACK;
  249.     if (bpts == wpts)
  250.       write(path, "TIE!", 4);
  251.     else {
  252.       FColor(path, (left == WHITE) ? cWHITE : cBLACK);
  253.       write(path, "WINNER:", 7);
  254.       putpiece(left, 3, 4);
  255.     }
  256.   }
  257.   else {
  258.     FColor(path, (turn == WHITE) ? cWHITE : cBLACK);
  259.     write(path, "TURN:", 5);
  260.     putpiece(turn, 3, 4);
  261.   }
  262.   gauge(gxGL, (left == WHITE) ? wpts : bpts, left);
  263.   gauge(gxGR, (left == WHITE) ? bpts : wpts, -left);
  264.   OWEnd(path);
  265. }
  266.  
  267.  
  268. #define PROMPTLN bdFAR
  269. #define vWIDE 40
  270.  
  271.  
  272. /* clear a prompt line window and write in it
  273. *  x and y are start, in absolute characters
  274. *  if length is zero, uses length of string
  275. *  clips if x + length > vWIDE - 1
  276.    right justifies on bottom line
  277. */
  278. static writelw(x, y, turn, s, len)
  279. uint x; uint y; int turn; char *s; uint len;
  280. {
  281.   int color = (turn == WHITE) ? cWHITE : cBLACK;
  282.   uint slen = strlen(s);
  283.  
  284.   if (x > vWIDE - 2)
  285.     return;
  286.   if (len == 0)
  287.     len = slen;
  288.   if (x + len > vWIDE - 1) /* avoid wrap */
  289.     len = vWIDE - 1 - x;
  290.   if (slen > len)
  291.     slen = len;
  292.   OWSet(path, oNOSAVE, x, y, len + 1, 1, color, cBLUE);
  293.   Clear(path);
  294.   if ((y == PROMPTLN) && (slen < len))
  295.     CurXY(path, len - slen, 0);
  296.   write(path, s, slen);
  297.   OWEnd(path);
  298. }
  299.  
  300.  
  301. #define L1 16 /* gyFAR + 1 */
  302. #define L2 17 /* gyFAR + 2 */
  303. #define L3 18 /* gyFAR + 3 */
  304.  
  305. /* clear a prompt
  306. */
  307. unprompt(words)
  308. int words;
  309. {
  310.   switch(words) {
  311.   case USER :
  312.     writelw(25, L1, NONE, "", 12);
  313.     writelw(25, L2, NONE, "", 10);
  314.     writelw(25, L3, NONE, "", 6);
  315.     break;
  316.   case COMPUTER :
  317.     writelw(25, L1, NONE, "", 6);
  318.     break;
  319.   }
  320.   writelw(0, PROMPTLN, NONE, "", 40);
  321. }
  322.  
  323.  
  324. /* prompt player(s)
  325. */
  326. prompt(words, turn)
  327. int words; SQUARE turn;
  328. {
  329.   switch(words) {
  330.   case USER :
  331.     writelw(25, L1, turn, "move: <\xd2\xd4\xd1\xd3>", 12);
  332.     writelw(25, L2, turn, "<C>omputer", 10);
  333.     writelw(25, L3, turn, "<Q>uit", 6);
  334.   case WILLPLAY :
  335.     writelw(0, PROMPTLN, turn, "<ENTER> to play", 40);
  336.     break;
  337.   case COMPUTER :
  338.     writelw(25, L1, turn, "<Q>uit", 6);
  339.     writelw(0, PROMPTLN, turn, "... thinking ...", 40);
  340.     break;
  341.   case QUIT :
  342.     writelw(0, PROMPTLN, turn, "> Press any key to end", 40);
  343.     break;
  344.   case REALLY :
  345.     writelw(0, PROMPTLN, turn, "> Confirm quit? <Y/N>", 40);
  346.     break;
  347.   case NOGOOD :
  348.     writelw(0, PROMPTLN, turn, "** Can't play here!", 40);
  349.     break;
  350.   case CONTINUE :
  351.     writelw(0, PROMPTLN, turn, ">> Press any key to continue", 40);
  352.     break;
  353.   case NOPLAY :
  354.     writelw(0, PROMPTLN, turn, "** No square playable! **", 40);
  355.     break;
  356.   }
  357. }
  358.  
  359.  
  360. /* put the pieces out, show counts and turn
  361. *  if turn is 0, show winner
  362. */
  363. display(tbd, turn)
  364. LN *tbd; SQUARE turn;
  365. {
  366.   register SQUARE *bd = (SQUARE *) tbd;
  367. /* MWC apparently sees tbd as char **! */
  368.   uint i, j;
  369.   SQUARE pc;
  370.   int bct = 0;
  371.   int wct = 0;
  372.  
  373.   OWSet(path, oNOSAVE, bdHOME, bdHOME, bdFAR, bdFAR, cBLUE, cGREEN);
  374.   for (i = 0; i < WIDTH; i++)
  375.     for (j = 0; j < WIDTH; j++) {
  376.       pc = *bd++;
  377.       if ((pc == BLACK) || (pc == WHITE)) {
  378.         putpiece(pc, j, i);
  379.         if (pc == BLACK)
  380.           bct++;
  381.         else
  382.           wct++;
  383.       }
  384.     }
  385.   gauges(bct, wct, turn);
  386.   OWEnd(path);
  387. }
  388.  
  389.  
  390. /* OS-9 does this for us:
  391. static uint px = bdHOMEpx;
  392. static uint py = bdHOMEpx;
  393. */
  394.  
  395. /* put a cursor on the screen, remembering position
  396. * The OS-9 cursor is independent of the active window.
  397. * Translation of window to board is handled in off()
  398. */
  399. showcursor(x, y, valid)
  400. uint x; uint y; int valid;
  401. {
  402.   PutGC(path, off(x) + CURSORoff, off(y) + CURSORoff);
  403.   SetGC(path, group, valid ? XHAIR : ILLEGAL);
  404. }
  405.  
  406.  
  407. /* remove cursor from remembered position
  408. */
  409. clrcursor()
  410. {
  411.   SetGC(path, 0, ILLEGAL);
  412. }
  413.  
  414.