• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Source code written in the old pre-ANSI Microware C, Libre license. Not sure the current source compiles, nor that the objects survived the journey.


Commit MetaInfo

Revision7ebede1fd227cdd6a280478b291daeaa08f0da88 (tree)
Zeit2020-10-08 22:10:51
AutorJoel Matthew Rees <joel.rees@gmai...>
CommiterJoel Matthew Rees

Log Message

Licensing where public domain not recognized clarified.

Ändern Zusammenfassung

Diff

--- a/board.c
+++ b/board.c
@@ -1 +1 @@
1-/* SCC$board.c#mwc0.01/26Apr1991 */ /* game board for reversi.c * by Joel Matthew Rees, Dec '89 * Modified for MS-DOS/TURBO-C March 1991 * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * new OS-9/CoCo version Apr/May 1991 * This program is assigned by the author to the public domain. */ #include <string.h> #include <stdio.h> #include <sgstat.h> #include <common.h> #include "rev_img.h" #define BOARD #include "board.h" #define MAXUSER 16 /* assume no more than this */ #define CELL 22 /* even for border and center */ #define bdHOME 0 #define bdHOMEpx 2 #define bdFAR 23 /* ((CELL + 1) * WIDTH) / 8 */ /* p * 22 * Marginally faster than using a multiply instruction on 6809 */ static uint off(p) uint p; { #asm clra ldb 5,s lslb lslb *4 addb 5,s *5 lslb *10 addb 5,s *11 lslb *22 addb #2 bdHOMEpx #endasm } #define PIECEoff 2 /* (CELL - piecex + 1) / 2 */ #define CURSORoff 7 /* (CELL - cursx + 1) / 2 */ /* buffer numbers: */ /* BLACK is 1, WHITE is -1 (= 255) */ /* ILLEGAL is 2, XHAIR is 3 */ #define FONT 4 /* window types */ #define WT40X24 1 #define WT80X24 2 #define WGHI2CO 5 #define WGMD4CO 6 #define WGHI4CO 7 #define WGMD16CO 8 /* colors (depend on put logic, also on palette settings) */ #define cWHITE 0 #define cBLUE 1 #define cBLACK 2 #define cGREEN 3 /* image put logic */ #define lNONE 0 #define lAND 1 #define lOR 2 #define lXOR 3 /* overlay window save select */ #define oSAVE 1 #define oNOSAVE 0 int path; static struct sgbuf wstat; int group; /* set up a window as a graphics window to run the game in * return -1 if unable to set window up properly */ int gograph() { if ((path = open("/w", _READ | _WRITE)) < 0) { fprintf(stderr, "error opening graphics window\n"); exit (-1); } if (getstat(0, path, &wstat) < 0) { fprintf(stderr, "error accessing window modes\n"); exit (-1); } wstat.sg_case = wstat.sg_echo = wstat.sg_alf = wstat.sg_pause = 0; if (setstat(0, path, &wstat) < 0) { fprintf(stderr, "error changing window modes\n"); exit (-1); } DWSet(path, WGMD4CO, 0, 0, 40, 24, cBLUE, cGREEN, cBLUE); ScaleSw(path, FALSE); Select(path); group = getuid(); CurOff(path); if (group == 0) group = MAXUSER; /* group 0 reserved */ GPLoad(path, group, FONT, gcfontty, gcfontx, gcfontx, gcfontln, gcfont); /* write(path, gcfont, gcfontln); GPLoad actually takes care of this, * contrary to the what the MultiVue docs */ Font(path, group, FONT); GPLoad(path, group, BLACK, piecety, piecex, piecex, blackln, black); GPLoad(path, group, WHITE, piecety, piecex, piecex, whiteln, white); GPLoad(path, group, ILLEGAL, cursty, cursx, cursx, illln, illegal); GPLoad(path, group, XHAIR, cursty, cursx, cursx, arcxhaln, arcxhair); LSet(path, lNONE); return (path); } endgraph() { KilBuf(path, group, FONT); KilBuf(path, group, BLACK); KilBuf(path, group, WHITE); KilBuf(path, group, ILLEGAL); KilBuf(path, group, XHAIR); DWEnd(path); close(path); putchar(0x1b); putchar(0x21); /* reselect start window */ } /* draw a line from (x0, y0) to (x, y) * leaves draw pointer at (x0, y0) */ static line(x0, y0, x, y) int x0, y0, x, y; { SetDPtr(path, x0, y0); Line(path, x, y); } /* set up the playing board on the screen, without pieces */ static grid(home, sq_sz, sq_ct) uint home; uint sq_sz; uint sq_ct; { uint i; uint term = sq_ct * sq_sz + home; for (i=home; i<=term; i+=sq_sz) { line(home, i, term, i); line(i, home, i, term); } } /* put board on screen */ putboard() { OWSet(path, oNOSAVE, bdHOME, bdHOME, bdFAR, bdFAR, cBLUE, cGREEN); Clear(path); grid(bdHOMEpx, CELL, WIDTH); /* skip edge */ OWEnd(path); OWSet(path, oNOSAVE, bdFAR, bdHOME, 40 - bdFAR, 24, cBLUE, cBLUE); Clear(path); OWEnd(path); OWSet(path, oNOSAVE, bdHOME, bdFAR, 40, 24 - bdFAR, cBLUE, cBLUE); Clear(path); OWEnd(path); } /* put a player's piece on the board at position (x, y) */ putpiece(player, x, y) SQUARE player; uint x; uint y; { PutBlk(path, group, player, off(x) + PIECEoff, off(y) + PIECEoff); } /* convert up to two digits of count into a decimal string in buffer * (buffer should be at least 3 bytes) * return address of buffer passed in */ static char *convert(buffer, count) char *buffer; int count; { register char *at = buffer; int dig1 = count / 10; if (dig1 != 0) *at++ = dig1 + '0'; *at++ = (count % 10) + '0'; *at = NUL; return (buffer); } #define gxHOME bdFAR #define gxGL 24 #define gWID 32 #define gxGR 80 #define gxFAR 17 #define gyHOME 0 #define gyTURN 12 #define gySCORE 9 #define gyGAUGE 68 /* 9 * 8 - 4 */ #define gyFAR 15 static char buffer[4]; /* put a bar on the screen, with variable fill * puts bars upside up * alters the draw pointer */ static gauge(xhome, height, player) uint xhome; uint height; int player; { FColor(path, (player == WHITE) ? cWHITE : cBLACK); CurXY(path, (xhome >> 3) + 1, gySCORE); write(path, convert(buffer, height), 2); SetDPtr(path, xhome, gyGAUGE); Bar(path, xhome + gWID, gyGAUGE - height); } /* show count graphically and numerically, * using turn to determine gauge to put on left */ static gauges(bpts, wpts, turn) uint bpts; uint wpts; SQUARE turn; { int left = turn; OWSet(path, oNOSAVE, gxHOME, gyHOME, gxFAR, gyFAR, cGREEN, cBLUE); Clear(path); CurXY(path, 0, gyTURN); if (turn == NONE) { left = (wpts > bpts) ? WHITE : BLACK; if (bpts == wpts) write(path, "TIE!", 4); else { FColor(path, (left == WHITE) ? cWHITE : cBLACK); write(path, "WINNER:", 7); putpiece(left, 3, 4); } } else { FColor(path, (turn == WHITE) ? cWHITE : cBLACK); write(path, "TURN:", 5); putpiece(turn, 3, 4); } gauge(gxGL, (left == WHITE) ? wpts : bpts, left); gauge(gxGR, (left == WHITE) ? bpts : wpts, -left); OWEnd(path); } #define PROMPTLN bdFAR #define vWIDE 40 /* clear a prompt line window and write in it * x and y are start, in absolute characters * if length is zero, uses length of string * clips if x + length > vWIDE - 1 right justifies on bottom line */ static writelw(x, y, turn, s, len) uint x; uint y; int turn; char *s; uint len; { int color = (turn == WHITE) ? cWHITE : cBLACK; uint slen = strlen(s); if (x > vWIDE - 2) return; if (len == 0) len = slen; if (x + len > vWIDE - 1) /* avoid wrap */ len = vWIDE - 1 - x; if (slen > len) slen = len; OWSet(path, oNOSAVE, x, y, len + 1, 1, color, cBLUE); Clear(path); if ((y == PROMPTLN) && (slen < len)) CurXY(path, len - slen, 0); write(path, s, slen); OWEnd(path); } #define L1 16 /* gyFAR + 1 */ #define L2 17 /* gyFAR + 2 */ #define L3 18 /* gyFAR + 3 */ /* clear a prompt */ unprompt(words) int words; { switch(words) { case USER : writelw(25, L1, NONE, "", 12); writelw(25, L2, NONE, "", 10); writelw(25, L3, NONE, "", 6); break; case COMPUTER : writelw(25, L1, NONE, "", 6); break; } writelw(0, PROMPTLN, NONE, "", 40); } /* prompt player(s) */ prompt(words, turn) int words; SQUARE turn; { switch(words) { case USER : writelw(25, L1, turn, "move: <\xd2\xd4\xd1\xd3>", 12); writelw(25, L2, turn, "<C>omputer", 10); writelw(25, L3, turn, "<Q>uit", 6); case WILLPLAY : writelw(0, PROMPTLN, turn, "<ENTER> to play", 40); break; case COMPUTER : writelw(25, L1, turn, "<Q>uit", 6); writelw(0, PROMPTLN, turn, "... thinking ...", 40); break; case QUIT : writelw(0, PROMPTLN, turn, "> Press any key to end", 40); break; case REALLY : writelw(0, PROMPTLN, turn, "> Confirm quit? <Y/N>", 40); break; case NOGOOD : writelw(0, PROMPTLN, turn, "** Can't play here!", 40); break; case CONTINUE : writelw(0, PROMPTLN, turn, ">> Press any key to continue", 40); break; case NOPLAY : writelw(0, PROMPTLN, turn, "** No square playable! **", 40); break; } } /* put the pieces out, show counts and turn * if turn is 0, show winner */ display(tbd, turn) LN *tbd; SQUARE turn; { register SQUARE *bd = (SQUARE *) tbd; /* MWC apparently sees tbd as char **! */ uint i, j; SQUARE pc; int bct = 0; int wct = 0; OWSet(path, oNOSAVE, bdHOME, bdHOME, bdFAR, bdFAR, cBLUE, cGREEN); for (i = 0; i < WIDTH; i++) for (j = 0; j < WIDTH; j++) { pc = *bd++; if ((pc == BLACK) || (pc == WHITE)) { putpiece(pc, j, i); if (pc == BLACK) bct++; else wct++; } } gauges(bct, wct, turn); OWEnd(path); } /* OS-9 does this for us: static uint px = bdHOMEpx; static uint py = bdHOMEpx; */ /* put a cursor on the screen, remembering position * The OS-9 cursor is independent of the active window. * Translation of window to board is handled in off() */ showcursor(x, y, valid) uint x; uint y; int valid; { PutGC(path, off(x) + CURSORoff, off(y) + CURSORoff); SetGC(path, group, valid ? XHAIR : ILLEGAL); } /* remove cursor from remembered position */ clrcursor() { SetGC(path, 0, ILLEGAL); }
\ No newline at end of file
1+/* SCC$board.c#mwc0.01/26Apr1991 */ /* game board for reversi.c * by Joel Matthew Rees, Dec '89 * Modified for MS-DOS/TURBO-C March 1991 * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * new OS-9/CoCo version Apr/May 1991 * This program is assigned by the author to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ #include <string.h> #include <stdio.h> #include <sgstat.h> #include <common.h> #include "rev_img.h" #define BOARD #include "board.h" #define MAXUSER 16 /* assume no more than this */ #define CELL 22 /* even for border and center */ #define bdHOME 0 #define bdHOMEpx 2 #define bdFAR 23 /* ((CELL + 1) * WIDTH) / 8 */ /* p * 22 * Marginally faster than using a multiply instruction on 6809 */ static uint off(p) uint p; { #asm clra ldb 5,s lslb lslb *4 addb 5,s *5 lslb *10 addb 5,s *11 lslb *22 addb #2 bdHOMEpx #endasm } #define PIECEoff 2 /* (CELL - piecex + 1) / 2 */ #define CURSORoff 7 /* (CELL - cursx + 1) / 2 */ /* buffer numbers: */ /* BLACK is 1, WHITE is -1 (= 255) */ /* ILLEGAL is 2, XHAIR is 3 */ #define FONT 4 /* window types */ #define WT40X24 1 #define WT80X24 2 #define WGHI2CO 5 #define WGMD4CO 6 #define WGHI4CO 7 #define WGMD16CO 8 /* colors (depend on put logic, also on palette settings) */ #define cWHITE 0 #define cBLUE 1 #define cBLACK 2 #define cGREEN 3 /* image put logic */ #define lNONE 0 #define lAND 1 #define lOR 2 #define lXOR 3 /* overlay window save select */ #define oSAVE 1 #define oNOSAVE 0 int path; static struct sgbuf wstat; int group; /* set up a window as a graphics window to run the game in * return -1 if unable to set window up properly */ int gograph() { if ((path = open("/w", _READ | _WRITE)) < 0) { fprintf(stderr, "error opening graphics window\n"); exit (-1); } if (getstat(0, path, &wstat) < 0) { fprintf(stderr, "error accessing window modes\n"); exit (-1); } wstat.sg_case = wstat.sg_echo = wstat.sg_alf = wstat.sg_pause = 0; if (setstat(0, path, &wstat) < 0) { fprintf(stderr, "error changing window modes\n"); exit (-1); } DWSet(path, WGMD4CO, 0, 0, 40, 24, cBLUE, cGREEN, cBLUE); ScaleSw(path, FALSE); Select(path); group = getuid(); CurOff(path); if (group == 0) group = MAXUSER; /* group 0 reserved */ GPLoad(path, group, FONT, gcfontty, gcfontx, gcfontx, gcfontln, gcfont); /* write(path, gcfont, gcfontln); GPLoad actually takes care of this, * contrary to the what the MultiVue docs */ Font(path, group, FONT); GPLoad(path, group, BLACK, piecety, piecex, piecex, blackln, black); GPLoad(path, group, WHITE, piecety, piecex, piecex, whiteln, white); GPLoad(path, group, ILLEGAL, cursty, cursx, cursx, illln, illegal); GPLoad(path, group, XHAIR, cursty, cursx, cursx, arcxhaln, arcxhair); LSet(path, lNONE); return (path); } endgraph() { KilBuf(path, group, FONT); KilBuf(path, group, BLACK); KilBuf(path, group, WHITE); KilBuf(path, group, ILLEGAL); KilBuf(path, group, XHAIR); DWEnd(path); close(path); putchar(0x1b); putchar(0x21); /* reselect start window */ } /* draw a line from (x0, y0) to (x, y) * leaves draw pointer at (x0, y0) */ static line(x0, y0, x, y) int x0, y0, x, y; { SetDPtr(path, x0, y0); Line(path, x, y); } /* set up the playing board on the screen, without pieces */ static grid(home, sq_sz, sq_ct) uint home; uint sq_sz; uint sq_ct; { uint i; uint term = sq_ct * sq_sz + home; for (i=home; i<=term; i+=sq_sz) { line(home, i, term, i); line(i, home, i, term); } } /* put board on screen */ putboard() { OWSet(path, oNOSAVE, bdHOME, bdHOME, bdFAR, bdFAR, cBLUE, cGREEN); Clear(path); grid(bdHOMEpx, CELL, WIDTH); /* skip edge */ OWEnd(path); OWSet(path, oNOSAVE, bdFAR, bdHOME, 40 - bdFAR, 24, cBLUE, cBLUE); Clear(path); OWEnd(path); OWSet(path, oNOSAVE, bdHOME, bdFAR, 40, 24 - bdFAR, cBLUE, cBLUE); Clear(path); OWEnd(path); } /* put a player's piece on the board at position (x, y) */ putpiece(player, x, y) SQUARE player; uint x; uint y; { PutBlk(path, group, player, off(x) + PIECEoff, off(y) + PIECEoff); } /* convert up to two digits of count into a decimal string in buffer * (buffer should be at least 3 bytes) * return address of buffer passed in */ static char *convert(buffer, count) char *buffer; int count; { register char *at = buffer; int dig1 = count / 10; if (dig1 != 0) *at++ = dig1 + '0'; *at++ = (count % 10) + '0'; *at = NUL; return (buffer); } #define gxHOME bdFAR #define gxGL 24 #define gWID 32 #define gxGR 80 #define gxFAR 17 #define gyHOME 0 #define gyTURN 12 #define gySCORE 9 #define gyGAUGE 68 /* 9 * 8 - 4 */ #define gyFAR 15 static char buffer[4]; /* put a bar on the screen, with variable fill * puts bars upside up * alters the draw pointer */ static gauge(xhome, height, player) uint xhome; uint height; int player; { FColor(path, (player == WHITE) ? cWHITE : cBLACK); CurXY(path, (xhome >> 3) + 1, gySCORE); write(path, convert(buffer, height), 2); SetDPtr(path, xhome, gyGAUGE); Bar(path, xhome + gWID, gyGAUGE - height); } /* show count graphically and numerically, * using turn to determine gauge to put on left */ static gauges(bpts, wpts, turn) uint bpts; uint wpts; SQUARE turn; { int left = turn; OWSet(path, oNOSAVE, gxHOME, gyHOME, gxFAR, gyFAR, cGREEN, cBLUE); Clear(path); CurXY(path, 0, gyTURN); if (turn == NONE) { left = (wpts > bpts) ? WHITE : BLACK; if (bpts == wpts) write(path, "TIE!", 4); else { FColor(path, (left == WHITE) ? cWHITE : cBLACK); write(path, "WINNER:", 7); putpiece(left, 3, 4); } } else { FColor(path, (turn == WHITE) ? cWHITE : cBLACK); write(path, "TURN:", 5); putpiece(turn, 3, 4); } gauge(gxGL, (left == WHITE) ? wpts : bpts, left); gauge(gxGR, (left == WHITE) ? bpts : wpts, -left); OWEnd(path); } #define PROMPTLN bdFAR #define vWIDE 40 /* clear a prompt line window and write in it * x and y are start, in absolute characters * if length is zero, uses length of string * clips if x + length > vWIDE - 1 right justifies on bottom line */ static writelw(x, y, turn, s, len) uint x; uint y; int turn; char *s; uint len; { int color = (turn == WHITE) ? cWHITE : cBLACK; uint slen = strlen(s); if (x > vWIDE - 2) return; if (len == 0) len = slen; if (x + len > vWIDE - 1) /* avoid wrap */ len = vWIDE - 1 - x; if (slen > len) slen = len; OWSet(path, oNOSAVE, x, y, len + 1, 1, color, cBLUE); Clear(path); if ((y == PROMPTLN) && (slen < len)) CurXY(path, len - slen, 0); write(path, s, slen); OWEnd(path); } #define L1 16 /* gyFAR + 1 */ #define L2 17 /* gyFAR + 2 */ #define L3 18 /* gyFAR + 3 */ /* clear a prompt */ unprompt(words) int words; { switch(words) { case USER : writelw(25, L1, NONE, "", 12); writelw(25, L2, NONE, "", 10); writelw(25, L3, NONE, "", 6); break; case COMPUTER : writelw(25, L1, NONE, "", 6); break; } writelw(0, PROMPTLN, NONE, "", 40); } /* prompt player(s) */ prompt(words, turn) int words; SQUARE turn; { switch(words) { case USER : writelw(25, L1, turn, "move: <\xd2\xd4\xd1\xd3>", 12); writelw(25, L2, turn, "<C>omputer", 10); writelw(25, L3, turn, "<Q>uit", 6); case WILLPLAY : writelw(0, PROMPTLN, turn, "<ENTER> to play", 40); break; case COMPUTER : writelw(25, L1, turn, "<Q>uit", 6); writelw(0, PROMPTLN, turn, "... thinking ...", 40); break; case QUIT : writelw(0, PROMPTLN, turn, "> Press any key to end", 40); break; case REALLY : writelw(0, PROMPTLN, turn, "> Confirm quit? <Y/N>", 40); break; case NOGOOD : writelw(0, PROMPTLN, turn, "** Can't play here!", 40); break; case CONTINUE : writelw(0, PROMPTLN, turn, ">> Press any key to continue", 40); break; case NOPLAY : writelw(0, PROMPTLN, turn, "** No square playable! **", 40); break; } } /* put the pieces out, show counts and turn * if turn is 0, show winner */ display(tbd, turn) LN *tbd; SQUARE turn; { register SQUARE *bd = (SQUARE *) tbd; /* MWC apparently sees tbd as char **! */ uint i, j; SQUARE pc; int bct = 0; int wct = 0; OWSet(path, oNOSAVE, bdHOME, bdHOME, bdFAR, bdFAR, cBLUE, cGREEN); for (i = 0; i < WIDTH; i++) for (j = 0; j < WIDTH; j++) { pc = *bd++; if ((pc == BLACK) || (pc == WHITE)) { putpiece(pc, j, i); if (pc == BLACK) bct++; else wct++; } } gauges(bct, wct, turn); OWEnd(path); } /* OS-9 does this for us: static uint px = bdHOMEpx; static uint py = bdHOMEpx; */ /* put a cursor on the screen, remembering position * The OS-9 cursor is independent of the active window. * Translation of window to board is handled in off() */ showcursor(x, y, valid) uint x; uint y; int valid; { PutGC(path, off(x) + CURSORoff, off(y) + CURSORoff); SetGC(path, group, valid ? XHAIR : ILLEGAL); } /* remove cursor from remembered position */ clrcursor() { SetGC(path, 0, ILLEGAL); }
\ No newline at end of file
--- a/board.h
+++ b/board.h
@@ -1 +1 @@
1-/* SCC$board.h#mwc0.01/26Apr1991 */ /* include file for board.c * by Joel Matthew Rees, Dec '89, * Modified for MS-DOS/TURBO-C March 1991 * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * new OS-9/CoCo version Apr 1991 * This file is assigned by the author to the public domain. */ #define BLACK 1 #define NONE 0 #define WHITE -BLACK #define WIDTH 8 #define WM 7 typedef char SQUARE; typedef SQUARE BD[WIDTH][WIDTH]; typedef SQUARE LN[WIDTH]; extern int path; extern int group; /* set up a hardware graphics window to run the game in * load the font and image buffers * return the path to the window, EOF on error */ extern int gograph(); /* close and deallocate the window, font and image buffers */ extern endgraph(); /* put board on screen */ extern putboard(); /* put a player's piece on the board at position (x, y) * home square is (0,0) */ extern putpiece( /* SQUARE player, uint x, uint y */ ); #define USER 1 #define COMPUTER 0 #define QUIT -1 #define REALLY -2 #define NOPLAY -3 #define CONTINUE -4 #define NOGOOD -5 #define WILLPLAY -6 /* prompt the player */ extern unprompt( /* message */ ); extern prompt( /* int message, SQUARE turn */ ); /* put the pieces out, show counts and turn * if turn is 0, show winner */ extern display( /* LN *bd, SQUARE turn */ ); #define ILLEGAL 2 #define XHAIR 3 /* put a cursor on the screen, remembering position * home square is (0,0) */ extern showcursor( /* uint x, uint y, int valid */ ); /* remove cursor from remembered position */ extern clrcursor();
\ No newline at end of file
1+/* SCC$board.h#mwc0.01/26Apr1991 */ /* include file for board.c * by Joel Matthew Rees, Dec '89, * Modified for MS-DOS/TURBO-C March 1991 * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * new OS-9/CoCo version Apr 1991 * This file is assigned by the author to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ #define BLACK 1 #define NONE 0 #define WHITE -BLACK #define WIDTH 8 #define WM 7 typedef char SQUARE; typedef SQUARE BD[WIDTH][WIDTH]; typedef SQUARE LN[WIDTH]; extern int path; extern int group; /* set up a hardware graphics window to run the game in * load the font and image buffers * return the path to the window, EOF on error */ extern int gograph(); /* close and deallocate the window, font and image buffers */ extern endgraph(); /* put board on screen */ extern putboard(); /* put a player's piece on the board at position (x, y) * home square is (0,0) */ extern putpiece( /* SQUARE player, uint x, uint y */ ); #define USER 1 #define COMPUTER 0 #define QUIT -1 #define REALLY -2 #define NOPLAY -3 #define CONTINUE -4 #define NOGOOD -5 #define WILLPLAY -6 /* prompt the player */ extern unprompt( /* message */ ); extern prompt( /* int message, SQUARE turn */ ); /* put the pieces out, show counts and turn * if turn is 0, show winner */ extern display( /* LN *bd, SQUARE turn */ ); #define ILLEGAL 2 #define XHAIR 3 /* put a cursor on the screen, remembering position * home square is (0,0) */ extern showcursor( /* uint x, uint y, int valid */ ); /* remove cursor from remembered position */ extern clrcursor();
\ No newline at end of file
--- a/common.h
+++ b/common.h
@@ -1 +1 @@
1-/* common definitions for reversi, by Joel Rees, 1989 -- 1991 * Microware C for OS-9/6809 ceased to be actively developed before the * ANSI standard began to take shape, and followed pre-ANSI rules. * This header is therefore mostly cosmetic and documentational. * Copyright for this file assigned by the author to the public domain. */ typedef unsigned int uint; /* not supported! typedef unsigned char uchar; */ #define TRUE 1 #define FALSE 0 #define ERROR -1 #define NUL 0 #define MININT 0x8000 /* 6809 */ #define MAXINT 0x7fff #asm asld macro rept \1 aslb rola endr endm asrd macro rept \1 asra rorb endr endm #endasm
\ No newline at end of file
1+/* common definitions for reversi, by Joel Rees, 1989 -- 1991 * Microware C for OS-9/6809 ceased to be actively developed before the * ANSI standard began to take shape, and followed pre-ANSI rules. * This header is therefore mostly cosmetic and documentational. * Copyright for this file assigned by the author to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ typedef unsigned int uint; /* not supported! typedef unsigned char uchar; */ #define TRUE 1 #define FALSE 0 #define ERROR -1 #define NUL 0 #define MININT 0x8000 /* 6809 */ #define MAXINT 0x7fff #asm asld macro rept \1 aslb rola endr endm asrd macro rept \1 asra rorb endr endm #endasm
\ No newline at end of file
--- a/keybd.h
+++ b/keybd.h
@@ -1 +1 @@
1-/* keycode definitions for the CoCo 3 * by Joel Rees, 1989 -- 1999, all rights to this file assigned to the public domain. */ #define BREAK 5 #define shBREAK 3 #define clBREAK 0x1b #define ENTER 0x0d #define SPACE 0x20 #define LEFT 8 #define shLEFT 0x18 #define clLEFT 0x10 #define RIGHT 9 #define shRIGHT 19 #define clRIGHT 11 #define DOWN 0x0a #define shDOWN 0x1a #define clDOWN 0x12 #define UP 0x0c #define shUP 0x1c #define clUP 0x13 #define F1 0xb1 #define shF1 0xb3 #define clF1 0xb5 #define F2 0xb2 #define shF2 0xb4 #define clF2 0xb6
\ No newline at end of file
1+/* keycode definitions for the CoCo 3 * by Joel Rees, 1989 -- 1999, all rights to this file assigned to the public domain. * This program is assigned by the author to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ #define BREAK 5 #define shBREAK 3 #define clBREAK 0x1b #define ENTER 0x0d #define SPACE 0x20 #define LEFT 8 #define shLEFT 0x18 #define clLEFT 0x10 #define RIGHT 9 #define shRIGHT 19 #define clRIGHT 11 #define DOWN 0x0a #define shDOWN 0x1a #define clDOWN 0x12 #define UP 0x0c #define shUP 0x1c #define clUP 0x13 #define F1 0xb1 #define shF1 0xb3 #define clF1 0xb5 #define F2 0xb2 #define shF2 0xb4 #define clF2 0xb6
\ No newline at end of file
--- a/process.h
+++ b/process.h
@@ -1 +1 @@
1-/* process.h -- stuff for process control * -- Joel Rees, March 1991 * Microware C for OS-9/6809 ceased to be actively developed before the * ANSI standard began to take shape, and followed pre-ANSI rules. * This header is therefore mostly cosmetic and documentational. * Copyright would be meaningless. */ /* void exit(int status); */ exit(); /* void _exit(int status); */ _exit();
\ No newline at end of file
1+/* process.h -- stuff for process control * -- Joel Rees, March 1991 * Microware C for OS-9/6809 ceased to be actively developed before the * ANSI standard began to take shape, and followed pre-ANSI rules. * This header is therefore mostly cosmetic and documentational. * Copyright would be meaningless. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ /* void exit(int status); */ exit(); /* void _exit(int status); */ _exit();
\ No newline at end of file
--- a/rand.c
+++ b/rand.c
@@ -1 +1 @@
1-/* SCC$rand.c#mwc0.01/26Apr1991 */ /* sort of random number generators by Joel Matthew Rees primarily for games * Copyright for this file assigned by the author to the public domain. * (Not that I consider the algorithm very well-crafted.) * Modified for MS-DOS/TURBO-C March 1991 * new OS-9/CoCo version Apr 1991 */ #include <time.h> #include <common.h> #define RAND #include "rand.h" static uint rand = 0; trandize() { struct sgtbuf diff; uint t, r; getime(&diff); /* calculate seconds */ #asm * t = ((((uint) diff.t_hour << 4) - diff.t_hour) << 2) + diff.t_minute; clra ldb 7,s aslb aslb aslb asld 1 subb 7,s sbca #0 asld 2 addb 8,s adca #0 std ,s * r = (t & 0x0800) == 0x0800; anda #8 sta 2,s * t = (((t << 4) - t) << 2) + diff.t_second; lda ,s asld 4 subd ,s asld 2 addb 9,s adca #0 std ,s * /* fold it in */ * rand ^= t ^ ((uint) diff.t_seconds << 11) ^ ((uint) diff.t_seconds << 5); lda 9,s asla asla asla pshs a lda 10,s clrb asrd 3 eora ,s+ eora ,s eorb 1,s eora rand,y eorb rand+1,y std rand,y * /* approximate days and add it in */ * t = (((diff.t_year << 1) + diff.t_year) << 2) + diff.t_month; clra ldb 4,s asld 1 addb 4,s adca #0 asld 2 addb 5,s adca #0 std 0,s * rand += ((t << 5) - t - (t >> 1)) + diff.t_day + r; asld 5 subd ,s asr ,s ror 1,s subd ,s addb 6,s adca #0 tst 2,s beq trizp0 addd #1 trizp0 addd rand,y std rand,y #endasm } /* produce an arbitrary number, and re-seed */ uint trand(limit) uint limit; { uint val; uint bit; val = rand % limit; #asm * bit = (limit | rand) & 0xf; clr 0,s ldb rand+1,y orb 9,s andb #$f stb 1,s * rand += (limit >> 8) | (limit << 8); ldb 8,s lda 9,s addd rand,y std rand,y #endasm rand = (rand << bit) | (rand >> (16 - bit)); return(val); }
\ No newline at end of file
1+/* SCC$rand.c#mwc0.01/26Apr1991 */ /* sort of random number generators by Joel Matthew Rees primarily for games * Copyright for this file assigned by the author to the public domain. * (Not that I consider the algorithm very well-crafted.) * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. * Modified for MS-DOS/TURBO-C March 1991 * new OS-9/CoCo version Apr 1991 */ #include <time.h> #include <common.h> #define RAND #include "rand.h" static uint rand = 0; trandize() { struct sgtbuf diff; uint t, r; getime(&diff); /* calculate seconds */ #asm * t = ((((uint) diff.t_hour << 4) - diff.t_hour) << 2) + diff.t_minute; clra ldb 7,s aslb aslb aslb asld 1 subb 7,s sbca #0 asld 2 addb 8,s adca #0 std ,s * r = (t & 0x0800) == 0x0800; anda #8 sta 2,s * t = (((t << 4) - t) << 2) + diff.t_second; lda ,s asld 4 subd ,s asld 2 addb 9,s adca #0 std ,s * /* fold it in */ * rand ^= t ^ ((uint) diff.t_seconds << 11) ^ ((uint) diff.t_seconds << 5); lda 9,s asla asla asla pshs a lda 10,s clrb asrd 3 eora ,s+ eora ,s eorb 1,s eora rand,y eorb rand+1,y std rand,y * /* approximate days and add it in */ * t = (((diff.t_year << 1) + diff.t_year) << 2) + diff.t_month; clra ldb 4,s asld 1 addb 4,s adca #0 asld 2 addb 5,s adca #0 std 0,s * rand += ((t << 5) - t - (t >> 1)) + diff.t_day + r; asld 5 subd ,s asr ,s ror 1,s subd ,s addb 6,s adca #0 tst 2,s beq trizp0 addd #1 trizp0 addd rand,y std rand,y #endasm } /* produce an arbitrary number, and re-seed */ uint trand(limit) uint limit; { uint val; uint bit; val = rand % limit; #asm * bit = (limit | rand) & 0xf; clr 0,s ldb rand+1,y orb 9,s andb #$f stb 1,s * rand += (limit >> 8) | (limit << 8); ldb 8,s lda 9,s addd rand,y std rand,y #endasm rand = (rand << bit) | (rand >> (16 - bit)); return(val); }
\ No newline at end of file
--- a/rand.h
+++ b/rand.h
@@ -1 +1 @@
1-/* SCC$rand.h#mwc0.01/26Apr1991 */ /* include file for rand.c by Joel Matthew Rees -- Jan 1990 * Copyright for this file assigned by the author to the public domain. * Modified for MS-DOS/TURBO-C March 1991 * new OS-9/CoCo version Apr 1991 */ #ifndef TRUE #include <common.h> #endif #ifdef RAND #define EXTERN #else #define EXTERN extern #endif EXTERN trandize(); EXTERN uint trand( /* uint limit */ ); #undef EXTERN
\ No newline at end of file
1+/* SCC$rand.h#mwc0.01/26Apr1991 */ /* include file for rand.c by Joel Matthew Rees -- Jan 1990 * Copyright for this file assigned by the author to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. * Modified for MS-DOS/TURBO-C March 1991 * new OS-9/CoCo version Apr 1991 */ #ifndef TRUE #include <common.h> #endif #ifdef RAND #define EXTERN #else #define EXTERN extern #endif EXTERN trandize(); EXTERN uint trand( /* uint limit */ ); #undef EXTERN
\ No newline at end of file
--- a/rev_img.a
+++ b/rev_img.a
@@ -1 +1 @@
1- psect rev_img_a,0,0,0,0,0 * The reversi image file * Copyright May 1991 -- Joel Matthew Rees * Copyright for this file assigned to the public domain. * * The easiest way (in my budget) to generate these images on OS-9/6809 * was to calculate them on graph paper (and/or in my head) * and use the assembler's binary constants to assemble them. * * Includes * a crude italics font with some graphics characters, * playing pieces, and the cursor * * These images do not contain imbedded buffer loads and * may therefore be loaded in any group/buffer * * The screen types, image x dimensions, and buffer lengths are made available in int variables. * The image y dimension is the same as the x dimension. * no pc relative (const) data for MWC vsect * char # in font/pseudo-ASCII code gcfontx: fdb 8 gcfontty: fdb 5 gcfont: fcb %00010000 $00/$C1 fcb %00010000 fcb %00010000 fcb %11110000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $01/$C2 fcb %00010000 fcb %00010000 fcb %00011111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $02/$C3 fcb %00010000 fcb %00010000 fcb %11111111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $03/$C4 fcb %00000000 fcb %00000000 fcb %11111111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $04/$C5 fcb %00010000 fcb %00010000 fcb %11111111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $05/$C6 fcb %00010000 fcb %00001000 fcb %00000111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00010000 $06/$C7 fcb %00010000 fcb %00100000 fcb %11000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $07/$C8 fcb %00000000 fcb %00000000 fcb %11000000 fcb %00100000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 $08/$C9 fcb %00000000 fcb %00000000 fcb %00000111 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $09/$CA fcb %00010000 fcb %00100000 fcb %11000111 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $0A/$CB fcb %00010000 fcb %00001000 fcb %11000111 fcb %00100000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $0B/$CC fcb %00010000 fcb %00001000 fcb %00000111 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $0C/$CD fcb %00010000 fcb %00100000 fcb %11000000 fcb %00100000 fcb %00010000 fcb %00010000 fcb %00010000 * graphics font extension fcb %00000000 $0D/$CE fcb %00000000 fcb %00011000 fcb %00111100 fcb %00111100 fcb %00011000 fcb %00000000 fcb %00000000 fcb %00000000 $0E/$CF fcb %10101010 fcb %11000110 fcb %11111110 fcb %11000110 fcb %10101010 fcb %00000000 fcb %00000000 fcb %01111100 $0F/$D0 fcb %00111000 fcb %01010100 fcb %00010000 fcb %01010100 fcb %00111000 fcb %01111100 fcb %00000000 fcb %00010000 $10/$D1 fcb %00111000 fcb %01010100 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 fcb %00000000 $11/$D2 fcb %00100000 fcb %01000000 fcb %11111110 fcb %01000000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00000000 $12/$D3 fcb %00001000 fcb %00000100 fcb %11111110 fcb %00000100 fcb %00001000 fcb %00000000 fcb %00000000 fcb %00010000 $13/$D4 fcb %00010000 fcb %00010000 fcb %00010000 fcb %01010100 fcb %00111000 fcb %00010000 fcb %00000000 fcb %01111100 $14/$D5 fcb %00010000 fcb %00111000 fcb %01010100 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 fcb %00000000 $15/$D6 fcb %10010000 fcb %10100000 fcb %11111110 fcb %10100000 fcb %10010000 fcb %00000000 fcb %00000000 fcb %00000000 $16/$D7 fcb %00010010 fcb %00001010 fcb %11111110 fcb %00001010 fcb %00010010 fcb %00000000 fcb %00000000 fcb %00010000 $17/$D8 fcb %00010000 fcb %00010000 fcb %01010100 fcb %00111000 fcb %00010000 fcb %01111100 fcb %00000000 fcb %00000000 $18/$D9 fcb %00101000 fcb %01000100 fcb %11111110 fcb %01000100 fcb %00101000 fcb %00000000 fcb %00000000 fcb %00010000 $19/$DA fcb %00111000 fcb %01010100 fcb %00010000 fcb %01010100 fcb %00111000 fcb %00010000 fcb %00000000 fcb %00010000 $1A/$AA fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 $1B/$AB fcb %00000000 fcb %00000000 fcb %11111111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00010000 $1C/$AC fcb %00010000 fcb %00010000 fcb %00011111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00010000 $1D/$AD fcb %00010000 fcb %00010000 fcb %11110000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $1E/$AE fcb %00000000 fcb %00000000 fcb %11110000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 $1F/$AF fcb %00000000 fcb %00000000 fcb %00011111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 * start italics * ASCII code fcb %00000000 $20 SP fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00001000 $21 ! fcb %00010000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %00000000 fcb %01000000 fcb %00000000 fcb %00100100 $22 " fcb %01001000 fcb %10010000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00001010 $23 # fcb %00010100 fcb %01110110 fcb %00101000 fcb %11011100 fcb %01010000 fcb %10100000 fcb %00000000 fcb %00000100 $24 $ fcb %00011100 fcb %00101010 fcb %00111000 fcb %10101000 fcb %01110000 fcb %01000000 fcb %00000000 fcb %01100010 $25 % fcb %01100100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01001100 fcb %10001100 fcb %00000000 fcb %00001100 $26 & fcb %00010100 fcb %00011000 fcb %01101010 fcb %10001100 fcb %10001000 fcb %01110100 fcb %00000000 fcb %00011000 $27 ' fcb %00010000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000100 $28 ( fcb %00001000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %00100000 fcb %00010000 fcb %00001000 fcb %00010000 $29 ) fcb %00001000 fcb %00000100 fcb %00000100 fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %00000000 $2A * fcb %00010010 fcb %00010100 fcb %01111110 fcb %00101000 fcb %01001000 fcb %00000000 fcb %00000000 fcb %00000000 $2B + fcb %00001000 fcb %00010000 fcb %01111100 fcb %00010000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00000000 $2C , fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00110000 fcb %00100000 fcb %01000000 fcb %00000000 $2D - fcb %00000000 fcb %00000000 fcb %01111100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $2E . fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %01100000 fcb %01100000 fcb %00000000 fcb %00000010 $2F / fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %10000000 fcb %00000000 fcb %00011100 $30 0 fcb %00100010 fcb %01010010 fcb %10010010 fcb %10010100 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00000100 $31 1 fcb %00001100 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01110000 fcb %00000000 fcb %00011100 $32 2 fcb %00100010 fcb %00000100 fcb %00001000 fcb %00110000 fcb %01000100 fcb %11111000 fcb %00000000 fcb %00011100 $33 3 fcb %00100010 fcb %00000100 fcb %00011000 fcb %00001000 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00000100 $34 4 fcb %00010100 fcb %00100100 fcb %01001000 fcb %11111100 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00011110 $35 5 fcb %00100000 fcb %01011100 fcb %01100010 fcb %00000010 fcb %10000100 fcb %01111000 fcb %00000000 fcb %00001110 $36 6 fcb %00010000 fcb %00100000 fcb %01111000 fcb %10000100 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00111110 $37 7 fcb %01000010 fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00001110 $38 8 fcb %00010010 fcb %00011100 fcb %00100010 fcb %01000010 fcb %10000100 fcb %11111000 fcb %00000000 fcb %00001110 $39 9 fcb %00010010 fcb %00011110 fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %00000000 fcb %00000000 $3A : fcb %00000000 fcb %00011000 fcb %00000000 fcb %00000000 fcb %00110000 fcb %00000000 fcb %00000000 fcb %00000000 $3B ; fcb %00000000 fcb %00011000 fcb %00000000 fcb %00000000 fcb %00110000 fcb %00100000 fcb %01000000 fcb %00000000 $3C < fcb %00000100 fcb %00010000 fcb %01000000 fcb %00100000 fcb %00010000 fcb %00000000 fcb %00000000 fcb %00000000 $3D = fcb %00000000 fcb %01111110 fcb %00000000 fcb %11111100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $3E > fcb %00001000 fcb %00000100 fcb %00000010 fcb %00001000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00011110 $3F ? fcb %00100010 fcb %00000010 fcb %00001100 fcb %00010000 fcb %00000000 fcb %00100000 fcb %00100000 fcb %00011110 $40 @ fcb %00100010 fcb %01001110 fcb %01010100 fcb %10011100 fcb %10000000 fcb %11111000 fcb %00000000 fcb %00001100 $41 A fcb %00010010 fcb %00100010 fcb %01111110 fcb %01000010 fcb %10000010 fcb %10000100 fcb %00000000 fcb %00111100 $42 B fcb %00010010 fcb %00100010 fcb %00111100 fcb %01000010 fcb %10000100 fcb %11111000 fcb %00000000 fcb %00011100 $43 C fcb %00100010 fcb %01000000 fcb %10000000 fcb %10000000 fcb %10000100 fcb %01111000 fcb %00000000 fcb %01111100 $44 D fcb %00100010 fcb %00100010 fcb %01000010 fcb %01000010 fcb %10000100 fcb %11111000 fcb %00000000 fcb %00111110 $45 E fcb %00100000 fcb %01000000 fcb %01111000 fcb %10000000 fcb %10000000 fcb %11111100 fcb %00000000 fcb %00111110 $46 F fcb %00100000 fcb %01000000 fcb %01111000 fcb %10000000 fcb %10000000 fcb %10000000 fcb %00000000 fcb %00011110 $47 G fcb %00100000 fcb %01000000 fcb %10001110 fcb %10000010 fcb %10000100 fcb %01111100 fcb %00000000 fcb %00100010 $48 H fcb %00100010 fcb %01000100 fcb %01111100 fcb %01000100 fcb %10001000 fcb %10001000 fcb %00000000 fcb %00011100 $49 I fcb %00001000 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01110000 fcb %00000000 fcb %00001110 $4A J fcb %00000100 fcb %00000100 fcb %00001000 fcb %00001000 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00010010 $4B K fcb %00100100 fcb %00111000 fcb %01010000 fcb %01001000 fcb %10001000 fcb %10001000 fcb %00001000 fcb %00010000 $4C L fcb %00100000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %10000000 fcb %11111100 fcb %00000000 fcb %00010010 $4D M fcb %00110110 fcb %00101010 fcb %01000100 fcb %01000100 fcb %10001000 fcb %10001000 fcb %00000000 fcb %00010010 $4E N fcb %00110010 fcb %00110100 fcb %01010100 fcb %01011000 fcb %10011000 fcb %10010000 fcb %00000000 fcb %00011100 $4F O fcb %00100010 fcb %01000010 fcb %01000010 fcb %10000100 fcb %10000100 fcb %01111000 fcb %00000000 fcb %00011100 $50 P fcb %00100010 fcb %00100100 fcb %00111000 fcb %01000000 fcb %01000000 fcb %10000000 fcb %00000000 fcb %00011100 $51 Q fcb %00100010 fcb %01000010 fcb %10000010 fcb %10010100 fcb %10001100 fcb %01111000 fcb %00001000 fcb %00011100 $52 R fcb %00100010 fcb %00100100 fcb %00111000 fcb %01010000 fcb %01001000 fcb %10001000 fcb %00001000 fcb %00001110 $53 S fcb %00010010 fcb %00010000 fcb %00001000 fcb %00000100 fcb %10001000 fcb %01110000 fcb %00000000 fcb %01111111 $54 T fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %00000000 fcb %00100010 $55 U fcb %00100010 fcb %01000100 fcb %01000100 fcb %10001000 fcb %10001000 fcb %01111000 fcb %00000000 fcb %01000010 $56 V fcb %01000010 fcb %01000100 fcb %01001000 fcb %01010000 fcb %01100000 fcb %01000000 fcb %00000000 fcb %01000010 $57 W fcb %01000010 fcb %01000100 fcb %10000100 fcb %10101000 fcb %11010000 fcb %10010000 fcb %00000000 fcb %00100010 $58 X fcb %00100100 fcb %00011000 fcb %00010000 fcb %00101000 fcb %01001000 fcb %10001000 fcb %00000000 fcb %00100010 $59 Y fcb %00100100 fcb %00101000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00111110 $5A Z fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %11111000 fcb %00000000 fcb %00011110 $5B [ fcb %00100000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %10000000 fcb %11110000 fcb %00000000 fcb %00100000 $5C \ fcb %00100000 fcb %00010000 fcb %00010000 fcb %00001000 fcb %00001000 fcb %00000100 fcb %00000100 fcb %00011110 $5D ] fcb %00000100 fcb %00000100 fcb %00001000 fcb %00001000 fcb %00010000 fcb %11110000 fcb %00000000 fcb %00001000 $5E ^ fcb %00100100 fcb %10000010 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $5F _ fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %11111111 fcb %00000000 fcb %00010000 $60 ` fcb %00001000 fcb %00000100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $61 a fcb %00000000 fcb %00001110 fcb %00000010 fcb %00111110 fcb %01000100 fcb %01111000 fcb %00000000 fcb %00000000 $62 b fcb %00001000 fcb %00010000 fcb %00010000 fcb %00111100 fcb %00100010 fcb %01111100 fcb %00000000 fcb %00000000 $63 c fcb %00000000 fcb %00000000 fcb %00011110 fcb %00100000 fcb %01000000 fcb %01111100 fcb %00000000 fcb %00000000 $64 d fcb %00000010 fcb %00000010 fcb %00000100 fcb %01111100 fcb %10001000 fcb %11110000 fcb %00000000 fcb %00000000 $65 e fcb %00000000 fcb %00011110 fcb %00100010 fcb %01111100 fcb %01000000 fcb %01111000 fcb %00000000 fcb %00000000 $66 f fcb %00001100 fcb %00010010 fcb %00100000 fcb %01110000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %00000000 $67 g fcb %00000000 fcb %00000000 fcb %00011110 fcb %00100010 fcb %00111100 fcb %10001000 fcb %01110000 fcb %00000000 $68 h fcb %00001000 fcb %00010000 fcb %00010000 fcb %00111100 fcb %00100010 fcb %01000100 fcb %00000000 fcb %00000000 $69 i fcb %00000100 fcb %00000000 fcb %00011000 fcb %00010000 fcb %00100000 fcb %01100000 fcb %00000000 fcb %00000000 $6A j fcb %00000010 fcb %00000000 fcb %00000110 fcb %00000100 fcb %00001000 fcb %01001000 fcb %00110000 fcb %00000000 $6B k fcb %00001000 fcb %00010010 fcb %00010100 fcb %00111000 fcb %00100100 fcb %01000100 fcb %00000000 fcb %00000000 $6C l fcb %00001100 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01110000 fcb %00000000 fcb %00000000 $6D m fcb %00000000 fcb %00000000 fcb %01110100 fcb %01011010 fcb %10000010 fcb %10000100 fcb %00000000 fcb %00000000 $6E n fcb %00000000 fcb %00000000 fcb %00111100 fcb %00100010 fcb %01000100 fcb %01000100 fcb %00000000 fcb %00000000 $6F o fcb %00000000 fcb %00000000 fcb %00011100 fcb %00100010 fcb %01000100 fcb %00111000 fcb %00000000 fcb %00000000 $70 p fcb %00000000 fcb %00011100 fcb %00100010 fcb %00111100 fcb %01000000 fcb %01000000 fcb %10000000 fcb %00000000 $71 q fcb %00000000 fcb %00000000 fcb %00111100 fcb %01000100 fcb %01111000 fcb %00010010 fcb %00111100 fcb %00000000 $72 r fcb %00000000 fcb %00000000 fcb %00011110 fcb %00100010 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00000000 $73 s fcb %00000000 fcb %00011100 fcb %00100010 fcb %00111000 fcb %10000100 fcb %01111000 fcb %00000000 fcb %00000000 $74 t fcb %00000000 fcb %00001000 fcb %00111100 fcb %00010000 fcb %00100000 fcb %00110000 fcb %00000000 fcb %00000000 $75 u fcb %00000000 fcb %00000000 fcb %00100010 fcb %01000100 fcb %01000100 fcb %01110100 fcb %00000000 fcb %00000000 $76 v fcb %00000000 fcb %00000000 fcb %01000100 fcb %01001000 fcb %01010000 fcb %01100000 fcb %00000000 fcb %00000000 $77 w fcb %00000000 fcb %00000000 fcb %00100010 fcb %01000010 fcb %01010100 fcb %00101000 fcb %00000000 fcb %00000000 $78 x fcb %00000000 fcb %00100100 fcb %00101000 fcb %00010000 fcb %00101000 fcb %01001000 fcb %00000000 fcb %00000000 $79 y fcb %00000000 fcb %00000000 fcb %00100010 fcb %00100100 fcb %00011000 fcb %00010000 fcb %01100000 fcb %00000000 $7A z fcb %00000000 fcb %00111100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01111000 fcb %00000000 fcb %00000110 $7B { fcb %00001000 fcb %00001000 fcb %00011000 fcb %00010000 fcb %00100000 fcb %00011000 fcb %00000000 fcb %00000100 $7C | fcb %00000100 fcb %00001000 fcb %00000000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %00000000 fcb %00110000 $7D { fcb %00001000 fcb %00010000 fcb %00110000 fcb %00100000 fcb %00100000 fcb %11000000 fcb %00000000 fcb %00000000 $7E ~ fcb %00000000 fcb %01110000 fcb %10010010 fcb %00011100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %01010101 $7F DEL fcb %10101010 fcb %01010101 fcb %10101010 fcb %01010101 fcb %10101010 fcb %01010101 fcb %10101010 gcfontln: fdb gcfontln-gcfont * the playing pieces * discs in 19 pixel fields, * colors for putting on green background without logic * piecex: fdb 19 piecety: fdb 6 black: fcb %11111111, %11111110, %10101010, %11111111, %11111100 fcb %11111111, %11101010, %10101010, %10101111, %11111100 fcb %11111110, %10101010, %10101010, %10101010, %11111100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11111110, %10101010, %10101010, %10101010, %11111100 fcb %11111111, %11101010, %10101010, %10101111, %11111100 fcb %11111111, %11111110, %10101010, %11111111, %11111100 blackln: fdb blackln-black white: fcb %11111111, %11111100, %00000000, %11111111, %11111100 fcb %11111111, %11000000, %00000000, %00001111, %11111100 fcb %11111100, %00000000, %00000000, %00000000, %11111100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11111100, %00000000, %00000000, %00000000, %11111100 fcb %11111111, %11000000, %00000000, %00001111, %11111100 fcb %11111111, %11111100, %00000000, %11111111, %11111100 whiteln: fdb whiteln-white * illegal cursor: * this pattern is illegal indicator in a 9 pixel diameter circle cursx: fdb 9 cursty: fdb 6 illegal: fcb %00000011, %11110000, %00000000 fcb %00111100, %00001111, %00000000 fcb %00111100, %00000011, %00000000 fcb %11000011, %00000000, %11000000 fcb %11000000, %11000000, %11000000 fcb %11000000, %00110000, %11000000 fcb %00110000, %00001111, %00000000 fcb %00111100, %00001111, %00000000 fcb %00000011, %11110000, %00000000 illln: fdb illln-illegal * this pattern is crosshairs in four interstitial arcs in a 9 pixel field arcxhair: fcb %00110000, %11000011, %00000000 fcb %11000000, %11000000, %11000000 fcb %00000000, %11000000, %00000000 fcb %00000000, %11000000, %00000000 fcb %11111111, %11111111, %11000000 fcb %00000000, %11000000, %00000000 fcb %00000000, %11000000, %00000000 fcb %11000000, %11000000, %11000000 fcb %00110000, %11000011, %00000000 arcxhaln: fdb arcxhaln-arcxhair endsect endsect end
\ No newline at end of file
1+ psect rev_img_a,0,0,0,0,0 * The reversi image file * Copyright May 1991 -- Joel Matthew Rees * Copyright for this file assigned to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. * * The easiest way (in my budget) to generate these images on OS-9/6809 * was to calculate them on graph paper (and/or in my head) * and use the assembler's binary constants to assemble them. * * Includes * a crude italics font with some graphics characters, * playing pieces, and the cursor * * These images do not contain imbedded buffer loads and * may therefore be loaded in any group/buffer * * The screen types, image x dimensions, and buffer lengths are made available in int variables. * The image y dimension is the same as the x dimension. * no pc relative (const) data for MWC vsect * char # in font/pseudo-ASCII code gcfontx: fdb 8 gcfontty: fdb 5 gcfont: fcb %00010000 $00/$C1 fcb %00010000 fcb %00010000 fcb %11110000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $01/$C2 fcb %00010000 fcb %00010000 fcb %00011111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $02/$C3 fcb %00010000 fcb %00010000 fcb %11111111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $03/$C4 fcb %00000000 fcb %00000000 fcb %11111111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $04/$C5 fcb %00010000 fcb %00010000 fcb %11111111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $05/$C6 fcb %00010000 fcb %00001000 fcb %00000111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00010000 $06/$C7 fcb %00010000 fcb %00100000 fcb %11000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $07/$C8 fcb %00000000 fcb %00000000 fcb %11000000 fcb %00100000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 $08/$C9 fcb %00000000 fcb %00000000 fcb %00000111 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $09/$CA fcb %00010000 fcb %00100000 fcb %11000111 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $0A/$CB fcb %00010000 fcb %00001000 fcb %11000111 fcb %00100000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $0B/$CC fcb %00010000 fcb %00001000 fcb %00000111 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 $0C/$CD fcb %00010000 fcb %00100000 fcb %11000000 fcb %00100000 fcb %00010000 fcb %00010000 fcb %00010000 * graphics font extension fcb %00000000 $0D/$CE fcb %00000000 fcb %00011000 fcb %00111100 fcb %00111100 fcb %00011000 fcb %00000000 fcb %00000000 fcb %00000000 $0E/$CF fcb %10101010 fcb %11000110 fcb %11111110 fcb %11000110 fcb %10101010 fcb %00000000 fcb %00000000 fcb %01111100 $0F/$D0 fcb %00111000 fcb %01010100 fcb %00010000 fcb %01010100 fcb %00111000 fcb %01111100 fcb %00000000 fcb %00010000 $10/$D1 fcb %00111000 fcb %01010100 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 fcb %00000000 $11/$D2 fcb %00100000 fcb %01000000 fcb %11111110 fcb %01000000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00000000 $12/$D3 fcb %00001000 fcb %00000100 fcb %11111110 fcb %00000100 fcb %00001000 fcb %00000000 fcb %00000000 fcb %00010000 $13/$D4 fcb %00010000 fcb %00010000 fcb %00010000 fcb %01010100 fcb %00111000 fcb %00010000 fcb %00000000 fcb %01111100 $14/$D5 fcb %00010000 fcb %00111000 fcb %01010100 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 fcb %00000000 $15/$D6 fcb %10010000 fcb %10100000 fcb %11111110 fcb %10100000 fcb %10010000 fcb %00000000 fcb %00000000 fcb %00000000 $16/$D7 fcb %00010010 fcb %00001010 fcb %11111110 fcb %00001010 fcb %00010010 fcb %00000000 fcb %00000000 fcb %00010000 $17/$D8 fcb %00010000 fcb %00010000 fcb %01010100 fcb %00111000 fcb %00010000 fcb %01111100 fcb %00000000 fcb %00000000 $18/$D9 fcb %00101000 fcb %01000100 fcb %11111110 fcb %01000100 fcb %00101000 fcb %00000000 fcb %00000000 fcb %00010000 $19/$DA fcb %00111000 fcb %01010100 fcb %00010000 fcb %01010100 fcb %00111000 fcb %00010000 fcb %00000000 fcb %00010000 $1A/$AA fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 $1B/$AB fcb %00000000 fcb %00000000 fcb %11111111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00010000 $1C/$AC fcb %00010000 fcb %00010000 fcb %00011111 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00010000 $1D/$AD fcb %00010000 fcb %00010000 fcb %11110000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $1E/$AE fcb %00000000 fcb %00000000 fcb %11110000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00000000 $1F/$AF fcb %00000000 fcb %00000000 fcb %00011111 fcb %00010000 fcb %00010000 fcb %00010000 fcb %00010000 * start italics * ASCII code fcb %00000000 $20 SP fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00001000 $21 ! fcb %00010000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %00000000 fcb %01000000 fcb %00000000 fcb %00100100 $22 " fcb %01001000 fcb %10010000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00001010 $23 # fcb %00010100 fcb %01110110 fcb %00101000 fcb %11011100 fcb %01010000 fcb %10100000 fcb %00000000 fcb %00000100 $24 $ fcb %00011100 fcb %00101010 fcb %00111000 fcb %10101000 fcb %01110000 fcb %01000000 fcb %00000000 fcb %01100010 $25 % fcb %01100100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01001100 fcb %10001100 fcb %00000000 fcb %00001100 $26 & fcb %00010100 fcb %00011000 fcb %01101010 fcb %10001100 fcb %10001000 fcb %01110100 fcb %00000000 fcb %00011000 $27 ' fcb %00010000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000100 $28 ( fcb %00001000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %00100000 fcb %00010000 fcb %00001000 fcb %00010000 $29 ) fcb %00001000 fcb %00000100 fcb %00000100 fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %00000000 $2A * fcb %00010010 fcb %00010100 fcb %01111110 fcb %00101000 fcb %01001000 fcb %00000000 fcb %00000000 fcb %00000000 $2B + fcb %00001000 fcb %00010000 fcb %01111100 fcb %00010000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00000000 $2C , fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00110000 fcb %00100000 fcb %01000000 fcb %00000000 $2D - fcb %00000000 fcb %00000000 fcb %01111100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $2E . fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %01100000 fcb %01100000 fcb %00000000 fcb %00000010 $2F / fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %10000000 fcb %00000000 fcb %00011100 $30 0 fcb %00100010 fcb %01010010 fcb %10010010 fcb %10010100 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00000100 $31 1 fcb %00001100 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01110000 fcb %00000000 fcb %00011100 $32 2 fcb %00100010 fcb %00000100 fcb %00001000 fcb %00110000 fcb %01000100 fcb %11111000 fcb %00000000 fcb %00011100 $33 3 fcb %00100010 fcb %00000100 fcb %00011000 fcb %00001000 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00000100 $34 4 fcb %00010100 fcb %00100100 fcb %01001000 fcb %11111100 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00011110 $35 5 fcb %00100000 fcb %01011100 fcb %01100010 fcb %00000010 fcb %10000100 fcb %01111000 fcb %00000000 fcb %00001110 $36 6 fcb %00010000 fcb %00100000 fcb %01111000 fcb %10000100 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00111110 $37 7 fcb %01000010 fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00001110 $38 8 fcb %00010010 fcb %00011100 fcb %00100010 fcb %01000010 fcb %10000100 fcb %11111000 fcb %00000000 fcb %00001110 $39 9 fcb %00010010 fcb %00011110 fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %00000000 fcb %00000000 $3A : fcb %00000000 fcb %00011000 fcb %00000000 fcb %00000000 fcb %00110000 fcb %00000000 fcb %00000000 fcb %00000000 $3B ; fcb %00000000 fcb %00011000 fcb %00000000 fcb %00000000 fcb %00110000 fcb %00100000 fcb %01000000 fcb %00000000 $3C < fcb %00000100 fcb %00010000 fcb %01000000 fcb %00100000 fcb %00010000 fcb %00000000 fcb %00000000 fcb %00000000 $3D = fcb %00000000 fcb %01111110 fcb %00000000 fcb %11111100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $3E > fcb %00001000 fcb %00000100 fcb %00000010 fcb %00001000 fcb %00100000 fcb %00000000 fcb %00000000 fcb %00011110 $3F ? fcb %00100010 fcb %00000010 fcb %00001100 fcb %00010000 fcb %00000000 fcb %00100000 fcb %00100000 fcb %00011110 $40 @ fcb %00100010 fcb %01001110 fcb %01010100 fcb %10011100 fcb %10000000 fcb %11111000 fcb %00000000 fcb %00001100 $41 A fcb %00010010 fcb %00100010 fcb %01111110 fcb %01000010 fcb %10000010 fcb %10000100 fcb %00000000 fcb %00111100 $42 B fcb %00010010 fcb %00100010 fcb %00111100 fcb %01000010 fcb %10000100 fcb %11111000 fcb %00000000 fcb %00011100 $43 C fcb %00100010 fcb %01000000 fcb %10000000 fcb %10000000 fcb %10000100 fcb %01111000 fcb %00000000 fcb %01111100 $44 D fcb %00100010 fcb %00100010 fcb %01000010 fcb %01000010 fcb %10000100 fcb %11111000 fcb %00000000 fcb %00111110 $45 E fcb %00100000 fcb %01000000 fcb %01111000 fcb %10000000 fcb %10000000 fcb %11111100 fcb %00000000 fcb %00111110 $46 F fcb %00100000 fcb %01000000 fcb %01111000 fcb %10000000 fcb %10000000 fcb %10000000 fcb %00000000 fcb %00011110 $47 G fcb %00100000 fcb %01000000 fcb %10001110 fcb %10000010 fcb %10000100 fcb %01111100 fcb %00000000 fcb %00100010 $48 H fcb %00100010 fcb %01000100 fcb %01111100 fcb %01000100 fcb %10001000 fcb %10001000 fcb %00000000 fcb %00011100 $49 I fcb %00001000 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01110000 fcb %00000000 fcb %00001110 $4A J fcb %00000100 fcb %00000100 fcb %00001000 fcb %00001000 fcb %10001000 fcb %01110000 fcb %00000000 fcb %00010010 $4B K fcb %00100100 fcb %00111000 fcb %01010000 fcb %01001000 fcb %10001000 fcb %10001000 fcb %00001000 fcb %00010000 $4C L fcb %00100000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %10000000 fcb %11111100 fcb %00000000 fcb %00010010 $4D M fcb %00110110 fcb %00101010 fcb %01000100 fcb %01000100 fcb %10001000 fcb %10001000 fcb %00000000 fcb %00010010 $4E N fcb %00110010 fcb %00110100 fcb %01010100 fcb %01011000 fcb %10011000 fcb %10010000 fcb %00000000 fcb %00011100 $4F O fcb %00100010 fcb %01000010 fcb %01000010 fcb %10000100 fcb %10000100 fcb %01111000 fcb %00000000 fcb %00011100 $50 P fcb %00100010 fcb %00100100 fcb %00111000 fcb %01000000 fcb %01000000 fcb %10000000 fcb %00000000 fcb %00011100 $51 Q fcb %00100010 fcb %01000010 fcb %10000010 fcb %10010100 fcb %10001100 fcb %01111000 fcb %00001000 fcb %00011100 $52 R fcb %00100010 fcb %00100100 fcb %00111000 fcb %01010000 fcb %01001000 fcb %10001000 fcb %00001000 fcb %00001110 $53 S fcb %00010010 fcb %00010000 fcb %00001000 fcb %00000100 fcb %10001000 fcb %01110000 fcb %00000000 fcb %01111111 $54 T fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %00000000 fcb %00100010 $55 U fcb %00100010 fcb %01000100 fcb %01000100 fcb %10001000 fcb %10001000 fcb %01111000 fcb %00000000 fcb %01000010 $56 V fcb %01000010 fcb %01000100 fcb %01001000 fcb %01010000 fcb %01100000 fcb %01000000 fcb %00000000 fcb %01000010 $57 W fcb %01000010 fcb %01000100 fcb %10000100 fcb %10101000 fcb %11010000 fcb %10010000 fcb %00000000 fcb %00100010 $58 X fcb %00100100 fcb %00011000 fcb %00010000 fcb %00101000 fcb %01001000 fcb %10001000 fcb %00000000 fcb %00100010 $59 Y fcb %00100100 fcb %00101000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00111110 $5A Z fcb %00000100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01000000 fcb %11111000 fcb %00000000 fcb %00011110 $5B [ fcb %00100000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %10000000 fcb %11110000 fcb %00000000 fcb %00100000 $5C \ fcb %00100000 fcb %00010000 fcb %00010000 fcb %00001000 fcb %00001000 fcb %00000100 fcb %00000100 fcb %00011110 $5D ] fcb %00000100 fcb %00000100 fcb %00001000 fcb %00001000 fcb %00010000 fcb %11110000 fcb %00000000 fcb %00001000 $5E ^ fcb %00100100 fcb %10000010 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $5F _ fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %11111111 fcb %00000000 fcb %00010000 $60 ` fcb %00001000 fcb %00000100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 fcb %00000000 $61 a fcb %00000000 fcb %00001110 fcb %00000010 fcb %00111110 fcb %01000100 fcb %01111000 fcb %00000000 fcb %00000000 $62 b fcb %00001000 fcb %00010000 fcb %00010000 fcb %00111100 fcb %00100010 fcb %01111100 fcb %00000000 fcb %00000000 $63 c fcb %00000000 fcb %00000000 fcb %00011110 fcb %00100000 fcb %01000000 fcb %01111100 fcb %00000000 fcb %00000000 $64 d fcb %00000010 fcb %00000010 fcb %00000100 fcb %01111100 fcb %10001000 fcb %11110000 fcb %00000000 fcb %00000000 $65 e fcb %00000000 fcb %00011110 fcb %00100010 fcb %01111100 fcb %01000000 fcb %01111000 fcb %00000000 fcb %00000000 $66 f fcb %00001100 fcb %00010010 fcb %00100000 fcb %01110000 fcb %00100000 fcb %01000000 fcb %01000000 fcb %00000000 $67 g fcb %00000000 fcb %00000000 fcb %00011110 fcb %00100010 fcb %00111100 fcb %10001000 fcb %01110000 fcb %00000000 $68 h fcb %00001000 fcb %00010000 fcb %00010000 fcb %00111100 fcb %00100010 fcb %01000100 fcb %00000000 fcb %00000000 $69 i fcb %00000100 fcb %00000000 fcb %00011000 fcb %00010000 fcb %00100000 fcb %01100000 fcb %00000000 fcb %00000000 $6A j fcb %00000010 fcb %00000000 fcb %00000110 fcb %00000100 fcb %00001000 fcb %01001000 fcb %00110000 fcb %00000000 $6B k fcb %00001000 fcb %00010010 fcb %00010100 fcb %00111000 fcb %00100100 fcb %01000100 fcb %00000000 fcb %00000000 $6C l fcb %00001100 fcb %00001000 fcb %00010000 fcb %00010000 fcb %00100000 fcb %01110000 fcb %00000000 fcb %00000000 $6D m fcb %00000000 fcb %00000000 fcb %01110100 fcb %01011010 fcb %10000010 fcb %10000100 fcb %00000000 fcb %00000000 $6E n fcb %00000000 fcb %00000000 fcb %00111100 fcb %00100010 fcb %01000100 fcb %01000100 fcb %00000000 fcb %00000000 $6F o fcb %00000000 fcb %00000000 fcb %00011100 fcb %00100010 fcb %01000100 fcb %00111000 fcb %00000000 fcb %00000000 $70 p fcb %00000000 fcb %00011100 fcb %00100010 fcb %00111100 fcb %01000000 fcb %01000000 fcb %10000000 fcb %00000000 $71 q fcb %00000000 fcb %00000000 fcb %00111100 fcb %01000100 fcb %01111000 fcb %00010010 fcb %00111100 fcb %00000000 $72 r fcb %00000000 fcb %00000000 fcb %00011110 fcb %00100010 fcb %00100000 fcb %01000000 fcb %00000000 fcb %00000000 $73 s fcb %00000000 fcb %00011100 fcb %00100010 fcb %00111000 fcb %10000100 fcb %01111000 fcb %00000000 fcb %00000000 $74 t fcb %00000000 fcb %00001000 fcb %00111100 fcb %00010000 fcb %00100000 fcb %00110000 fcb %00000000 fcb %00000000 $75 u fcb %00000000 fcb %00000000 fcb %00100010 fcb %01000100 fcb %01000100 fcb %01110100 fcb %00000000 fcb %00000000 $76 v fcb %00000000 fcb %00000000 fcb %01000100 fcb %01001000 fcb %01010000 fcb %01100000 fcb %00000000 fcb %00000000 $77 w fcb %00000000 fcb %00000000 fcb %00100010 fcb %01000010 fcb %01010100 fcb %00101000 fcb %00000000 fcb %00000000 $78 x fcb %00000000 fcb %00100100 fcb %00101000 fcb %00010000 fcb %00101000 fcb %01001000 fcb %00000000 fcb %00000000 $79 y fcb %00000000 fcb %00000000 fcb %00100010 fcb %00100100 fcb %00011000 fcb %00010000 fcb %01100000 fcb %00000000 $7A z fcb %00000000 fcb %00111100 fcb %00001000 fcb %00010000 fcb %00100000 fcb %01111000 fcb %00000000 fcb %00000110 $7B { fcb %00001000 fcb %00001000 fcb %00011000 fcb %00010000 fcb %00100000 fcb %00011000 fcb %00000000 fcb %00000100 $7C | fcb %00000100 fcb %00001000 fcb %00000000 fcb %00010000 fcb %00100000 fcb %00100000 fcb %00000000 fcb %00110000 $7D { fcb %00001000 fcb %00010000 fcb %00110000 fcb %00100000 fcb %00100000 fcb %11000000 fcb %00000000 fcb %00000000 $7E ~ fcb %00000000 fcb %01110000 fcb %10010010 fcb %00011100 fcb %00000000 fcb %00000000 fcb %00000000 fcb %01010101 $7F DEL fcb %10101010 fcb %01010101 fcb %10101010 fcb %01010101 fcb %10101010 fcb %01010101 fcb %10101010 gcfontln: fdb gcfontln-gcfont * the playing pieces * discs in 19 pixel fields, * colors for putting on green background without logic * piecex: fdb 19 piecety: fdb 6 black: fcb %11111111, %11111110, %10101010, %11111111, %11111100 fcb %11111111, %11101010, %10101010, %10101111, %11111100 fcb %11111110, %10101010, %10101010, %10101010, %11111100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %10101010, %10101010, %10101010, %10101010, %10101000 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %11101010, %10101010, %10101010, %10101010, %10101100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11111010, %10101010, %10101010, %10101010, %10111100 fcb %11111110, %10101010, %10101010, %10101010, %11111100 fcb %11111111, %11101010, %10101010, %10101111, %11111100 fcb %11111111, %11111110, %10101010, %11111111, %11111100 blackln: fdb blackln-black white: fcb %11111111, %11111100, %00000000, %11111111, %11111100 fcb %11111111, %11000000, %00000000, %00001111, %11111100 fcb %11111100, %00000000, %00000000, %00000000, %11111100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %00000000, %00000000, %00000000, %00000000, %00000000 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %11000000, %00000000, %00000000, %00000000, %00001100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11110000, %00000000, %00000000, %00000000, %00111100 fcb %11111100, %00000000, %00000000, %00000000, %11111100 fcb %11111111, %11000000, %00000000, %00001111, %11111100 fcb %11111111, %11111100, %00000000, %11111111, %11111100 whiteln: fdb whiteln-white * illegal cursor: * this pattern is illegal indicator in a 9 pixel diameter circle cursx: fdb 9 cursty: fdb 6 illegal: fcb %00000011, %11110000, %00000000 fcb %00111100, %00001111, %00000000 fcb %00111100, %00000011, %00000000 fcb %11000011, %00000000, %11000000 fcb %11000000, %11000000, %11000000 fcb %11000000, %00110000, %11000000 fcb %00110000, %00001111, %00000000 fcb %00111100, %00001111, %00000000 fcb %00000011, %11110000, %00000000 illln: fdb illln-illegal * this pattern is crosshairs in four interstitial arcs in a 9 pixel field arcxhair: fcb %00110000, %11000011, %00000000 fcb %11000000, %11000000, %11000000 fcb %00000000, %11000000, %00000000 fcb %00000000, %11000000, %00000000 fcb %11111111, %11111111, %11000000 fcb %00000000, %11000000, %00000000 fcb %00000000, %11000000, %00000000 fcb %11000000, %11000000, %11000000 fcb %00110000, %11000011, %00000000 arcxhaln: fdb arcxhaln-arcxhair endsect endsect end
\ No newline at end of file
--- a/rev_img.h
+++ b/rev_img.h
@@ -1 +1 @@
1-/* include file for the reversi image file * Pre-ANSI C, mostly cosmetic and documentational. * May 1991 -- Joel Matthew Rees * Copyright for this file assigned to the public domain. * * The y dimension is the same as the x dimension for all images in this file. */ /* the font, with x dimension, screen type, and buffer length */ extern char gcfont[]; extern int gcfontx, gcfontty, gcfontln; /* the playing pieces, with x dimension, screen type, and buffer length */ extern int piecex, piecety; extern char black[], white[]; extern int blackln, whiteln; /* the cursors, with x dimension, screen type, and buffer length */ extern int cursx, cursty; extern char illegal[], arcxhair[]; extern int illln, arcxhaln;
\ No newline at end of file
1+/* include file for the reversi image file * Pre-ANSI C, mostly cosmetic and documentational. * May 1991 -- Joel Matthew Rees * Copyright for this file assigned to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. * * The y dimension is the same as the x dimension for all images in this file. */ /* the font, with x dimension, screen type, and buffer length */ extern char gcfont[]; extern int gcfontx, gcfontty, gcfontln; /* the playing pieces, with x dimension, screen type, and buffer length */ extern int piecex, piecety; extern char black[], white[]; extern int blackln, whiteln; /* the cursors, with x dimension, screen type, and buffer length */ extern int cursx, cursty; extern char illegal[], arcxhair[]; extern int illln, arcxhaln;
\ No newline at end of file
--- a/reversa.c
+++ b/reversa.c
@@ -1 +1 @@
1-/* SCC$reversi.c#mwc0.01/26Apr1991 */ /* reversi: a game like Othello * An OS-9 version in C, by Joel Matthew Rees, Dec '89 * Drastically modified for MS-DOS/TURBO-C March 1991 -- jmr * new OS-9/CoCo version Apr/May 1991 * This version uses assembler in the radar routine, * to see if there is any speed improvement. * Copyright 1991 Joel Matthew Rees * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * Copyright for this program and all object code generated from it * and its excerpts are assigned by the author to the public domain. */ /* problems with (LN *) casting in Microware C for OS-9/6809! */ #include <stdio.h> #include <process.h> #include <ctype.h> #include <common.h> #include <keybd.h> #include "rand.h" #include "board.h" static char gbuf[4]; /* this probably ought have been defined in board.c! * getc for a path rather than a file pointer */ int getch(path) int path; { read(path, gbuf, 1); return(gbuf[0]); } #define KBRDY 1 /* this might also ought have been defined in board.c! * check for input available */ int kbhit(p) int p; { return (getstat(KBRDY, path) != EOF); } /* eat NUL prebytes and force upper case * caveats: punctuation (0x20 -- 0x3f) gets forced to control characters */ int getarrow() { int temp; while ((temp = getch(path)) == NUL) ; return (temp & ~0x20); } /* strategic values of board positions */ BD vals = { { 8, -4, 4, 2, 2, 4, -4, 8 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 8, -4, 4, 2, 2, 4, -4, 8 } }; SQUARE *valp = (SQUARE *) vals; #define DEPTH 7 /* must be one less than a power of two */ BD board[DEPTH + 1]; static int top = 0; /* top of the various stacks */ static int level; /* level of look-ahead */ /* for a fast offset and a cast that doesn't work in MWC should be LN *boardof(x) */ SQUARE *boardof(x) int x; /* LSByte only */ { #asm lda 5,s clrb asra rorb asra rorb leax board,y leax d,x tfr x,d #endasm } /* translate an arrow key to cursor motion * Permute graphics mapping in this function * Perform bounding ELSEWHERE!!! */ SQUARE *cursmove(cursor, key) SQUARE *cursor; uint key; { int k_d; switch (key) { case LEFT: k_d = -1; break; case RIGHT: k_d = 1; break; case DOWN: k_d = WIDTH; break; case UP: k_d = -WIDTH; break; case 'C': cursor = NULL; /* fall through */ default: k_d = 0; } if (k_d != 0) { cursor += k_d; } return (cursor); } /* convert pointers to indices * 8 byte wide board is faster than to / and % * #asm code assumes sizeof(board) < 128 */ xy(bd, pos, ax, ay) LN *bd; SQUARE *pos; int *ax; int *ay; { #asm * int dif = (pos - (SQUARE *) bd); ldd 6,s subd 4,s pshs b (0 <= d < 128) * *ay = (dif >> 3); asrb asrb asrb std [11,s] * *ax = (dif & 7); puls b andb #7 std [8,s] #endasm } /* erase board and fill in borders */ init(tboard) LN *tboard; { register SQUARE *bd = (SQUARE *) tboard; SQUARE *lim = ((SQUARE *) tboard) + WIDTH * WIDTH; while (bd < lim) *bd++ = NONE; } #define RANK7 (WIDTH * (WIDTH - 1)) /* check all directions for a scoring line * quits as soon as a scoring line is found * returns !FALSE if scoring line found * This might be done in a loop, but it should be faster unrolled */ int radar(bd, player, pos) LN *bd; SQUARE player; SQUARE *pos; { #asm * register SQUARE *base = (SQUARE *) bd; ldx 4,s * int ipos = pos - base; ( 1,s ) * int beam = ipos; ( b ) ldd 8,s subd 4,s cmpd #64 bhs radno ipos set 9 stb ipos,s reuse pos LSB * SQUARE other = -player; ( ,s ) player set 7 lda player,s nega other set 6 sta other,s use player MSB * if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { lda b,x beq radck radno clra clrb puls u,pc radck * if (beam < WIDTH * (WIDTH - 2)) { /* up the array */ cmpb #48 bhs rad3 * if (base[beam += WIDTH] == other) addb #8 lda b,x cmpa other,s bne rad1 * while (beam < RANK7) rad0l cmpb #56 RANK7 bhs rad1 * if (base[beam += WIDTH] != other) addb #8 lda b,x cmpa other,s beq rad0l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad1 * beam = ipos; ldb ipos,s * if ((beam & WM) < 6) /* up & right */ lda ipos,s anda #7 WM cmpa #6 bhs rad2 * if (base[beam += WIDTH + 1] == other) addb #9 lda b,x cmpa other,s bne rad2 * while (((beam & WM) < 7) && (beam < RANK7 - 1)) rad1l cmpb #55 (RANK7 - 1) bhs rad2 tfr b,a anda #7 cmpa #7 bhs rad2 * if (base[beam += WIDTH + 1] != other) addb #9 lda b,x cmpa other,s beq rad1l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad2 * beam = ipos; ldb ipos,s * if ((beam & WM) > 1) /* up & left */ lda ipos,s anda #7 WM cmpa #1 bls rad3 * if (base[beam += WIDTH - 1] == other) addb #7 lda b,x cmpa other,s bne rad3 * while (((beam & WM) > 0) && (beam < RANK7 - 1)) rad2l cmpb #55 (RANK7 - 1) bhs rad3 tfr b,a anda #7 beq rad3 * if (base[beam += WIDTH - 1] != other) addb #7 lda b,x cmpa other,s beq rad2l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; * } rad3 * beam = ipos; ldb ipos,s * if (beam >= WIDTH * 2) { /* down the array */ cmpb #16 blo rad6 * if (base[beam -= WIDTH] == other) subb #8 lda b,x cmpa other,s bne rad4 * while (beam >= WIDTH) rad3l cmpb #8 WIDTH blo rad4 * if (base[beam -= WIDTH] != other) subb #8 lda b,x cmpa other,s beq rad3l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad4 * beam = ipos; ldb ipos,s * if ((beam & WM) < 6) /* down & right */ lda ipos,s anda #7 cmpa #6 bhs rad5 * if (base[beam -= WIDTH - 1] == other) subb #7 lda b,x cmpa other,s bne rad5 * while (((beam & WM) < 7) && (beam > WIDTH)) rad4l cmpb #8 WIDTH bls rad5 tfr b,a anda #7 cmpa #7 bhs rad5 * if (base[beam -= WIDTH - 1] != other) subb #7 lda b,x cmpa other,s beq rad4l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad5 * beam = ipos; ldb ipos,s * if ((beam & WM) > 1) /* down & left */ lda ipos,s anda #7 cmpa #1 bls rad6 * if (base[beam -= WIDTH + 1] == other) subb #9 lda b,x cmpa other,s bne rad6 * while (((beam & WM) > 0) && (beam > WIDTH)) rad5l cmpb #8 WIDTH bls rad6 tfr b,a anda #7 beq rad6 * if (base[beam -= WIDTH + 1] != other) subb #9 lda b,x cmpa other,s beq rad5l * if (base[beam] == player) cmpa player,s * goto ping; beq ping * else * break; * } rad6 * beam = ipos; ldb ipos,s * if ((beam & WM) < 6) /* right */ lda ipos,s anda #7 cmpa #6 bhs rad7 * if (base[++beam] == other) incb lda b,x cmpa other,s bne rad7 * while ((beam & WM) < 7) rad6l tfr b,a anda #7 cmpa #7 bhs rad7 * if (base[++beam] != other) incb lda b,x cmpa other,s beq rad6l * if (base[beam] == player) cmpa player,s * goto ping; beq ping * else * break; rad7 * beam = ipos; ldb ipos,s * if ((beam & WM) > 1) /* left */ lda ipos,s anda #7 cmpa #1 lbls radno * if (base[--beam] == other) decb lda b,x cmpa other,s lbne radno * while ((beam & WM) > 0) rad7l tfr b,a anda #7 lbeq radno * if (base[--beam] != other) decb lda b,x cmpa other,s beq rad7l * if (base[beam] == player) cmpa player,s * goto ping; beq ping * else * break; * } * return(FALSE); lbra radno ping * return(TRUE); ldd #1 #endasm } /* put a piece down and capture lines * returns count captured, does not count piece played */ int play(bd, pos, player) LN *bd; SQUARE *pos; SQUARE player; { register SQUARE *base = (SQUARE *) bd; int ipos = pos - base; int beam = ipos; int pcs = 0; SQUARE other = -player; if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { while (beam < RANK7) /* up the array */ if (base[beam += WIDTH] != other) break; if (base[beam] == player) while (base[beam -= WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while (beam >= WIDTH) /* down the array */ if (base[beam -= WIDTH] != other) break; if (base[beam] == player) while (base[beam += WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) < 7) /* right */ if (base[++beam] != other) break; if (base[beam] == player) while (base[--beam] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) > 0) /* left */ if (base[--beam] != other) break; if (base[beam] == player) while (base[++beam] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & right */ while (((beam & WM) < 7) && (beam < RANK7)) if (base[beam += WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH + 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & left */ while (((beam & WM) > 0) && (beam < RANK7)) if (base[beam += WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & right */ while (((beam & WM) < 7) && (beam >= WIDTH)) if (base[beam -= WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & left */ while (((beam & WM) > 0) && (beam >= WIDTH)) if (base[beam -= WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH + 1] == other) { base[beam] = player; pcs++; } if (pcs > 0) { *pos = player; if (top == level + 1) pcs += valp[pos - (SQUARE *) bd]; } } return(pcs); } /* seek a playable position, from pos, in increasing order * restores pos to board boundaries before seeking * before or after board will start at bd[0][0] * tests (restored) pos first * return NULL if no position playable after returning to pos */ SQUARE *seek(bd, pos, turn) LN *bd; SQUARE *pos; SQUARE turn; { register SQUARE *hunt; SQUARE *bhome = (SQUARE *) bd; SQUARE *bend = (SQUARE *) bd + WIDTH * WIDTH - 1; if ((pos < bhome) || (pos > bend)) pos = bhome; hunt = pos; do { if (*hunt == NONE) if (radar(bd, turn, hunt)) { pos = NULL; /* force hunt != pos */ break; } if (++hunt > bend) hunt = bhome; } while (hunt != pos); return (hunt == pos ? NULL : hunt); } /* wrap pos around center */ SQUARE *wrapsq(bd, pos, lo, hi) LN *bd; SQUARE *pos; int lo; int hi; { int i, j; xy(bd, pos, &j, &i); if (i < lo) i = hi; else if (i > hi) i = lo; if (j < lo) j = hi; else if (j > hi) j = lo; return ((SQUARE *) bd + (i << 3) + j); } /* drop out unceremoniously * (have to provide some orderly emergency exit!) */ quit(turn) SQUARE turn; { int resp; Bell(path); prompt(REALLY, turn); resp = tolower(getch(path)); if ((resp == 'y') || (resp == 'q')) { endgraph(); printf("So glad you could join us!\n"); exit(0); } unprompt(REALLY); } /* copy top level to test level, * initializes and cancels operations on test level, */ revert() { #asm * register SQUARE *scan = (SQUARE *) board + (top << 6); ldd top,y pshs d lbsr boardof tfr d,x * SQUARE *last = scan + WIDTH * WIDTH; leau 64,x stu ,s * while (scan < last) { bra revt revlup * scan[0] = scan[-(WIDTH * WIDTH)]; ldd -64,x two at a time std ,x++ * scan++; * } revt cmpx ,s blo revlup leas 2,s #endasm } /* find best play, recursive to level * return a value for the play * uses *pos to seed seek() * also uses *pos to flag noplay for next level of recursion * displays the cursor when evaluating level 0 * also checks for keyboard quit when evaluating level 0 */ int eval(turn, pos) SQUARE turn; SQUARE **pos; { SQUARE *test; /* should be (LN *) */ register SQUARE *check = (*pos) + WIDTH * WIDTH; SQUARE *oldc = NULL; SQUARE *best = NULL; int val; int oldv = MININT; int x, y; SQUARE *other = NULL; test = boardof(++top); revert(); check = seek(test, check - WIDTH - 1, turn); /* seek neighboring */ oldc = check; /* flag end */ other = check; /* flag noplay for deeper levels */ do { if (check != NULL) { if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); xy(test, check, &x, &y); showcursor(x, y, TRUE); } val = play(test, check, turn); } else { val = 0; if ((check == NULL) && (*pos == NULL)) break; /* no play left */ } if (top < level) val -= eval(-turn, &other); if (val > oldv) { oldv = val; best = check; } else if ((val == oldv) && (trand(1001 + top) & 32)) best = check; revert(); check++; if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); clrcursor(); } } while ((check = seek(test, check, turn)) != oldc); --top; *pos = (best == NULL) ? NULL : boardof(top) + (best - (SQUARE *) test); return(oldv); } /* get a play from a user * return NULL if computer selected or no play */ SQUARE *getuplay(turn, pos) SQUARE turn; SQUARE *pos; { SQUARE *cursor = seek(board, pos - WIDTH - 1, turn); /* neighbor */ uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 0, 7); else break; if (radar(board, turn, cursor)) { Bell(path); prompt(WILLPLAY, turn); } else { key = NUL; prompt(NOGOOD, turn); } } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } static int turnf[BLACK - WHITE + 1]; /* set by getprefs */ static int *uturn = turnf + 1; /* for accessing turn by player */ /* get a position to play a turn * returns the position to play */ SQUARE *getplay(turn) SQUARE turn; { static SQUARE *mem = (SQUARE *) board; SQUARE *mtemp; if (uturn[turn]) { prompt(USER, turn); mtemp = getuplay(turn, mem); unprompt(USER); } if (!uturn[turn] || (mtemp == NULL)) { prompt(COMPUTER, turn); eval(turn, &mem); unprompt(COMPUTER); } else mem = mtemp; return(mem); } /* find an empty position in the center four * forces pos to "nearest" center position if out of bounds * returns pos found or NULL */ SQUARE *seekctr(pos) register SQUARE *pos; { SQUARE *pos33 = (SQUARE *) board + 3 * WIDTH + 3; SQUARE *pos43 = pos33 + WIDTH; SQUARE *old = NULL; if (pos < pos33) pos = pos33; while (TRUE) { if ((pos > pos33 + 1) && (pos < pos43)) pos = pos43; else if (pos > pos43 + 1) pos = pos33; if ((*pos == NONE) || (pos == old)) break; if (old == NULL) old = pos; pos++; } return (*pos == NONE ? pos : NULL); } /* let user select one of first four moves * returns position selected * if no position available, returns NULL */ SQUARE *getuctr(turn) SQUARE turn; { SQUARE *cursor = seekctr((SQUARE *) board); uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 3, 4); else break; if (*cursor != NONE) { prompt(NOGOOD, turn); key = NUL; } else prompt(WILLPLAY, turn); } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } /* have computer find one of the first four moves * return position found or NULL */ SQUARE *getcctr() { SQUARE *pos = (SQUARE *) board + WIDTH * 3 + 3; if (trand(129) & 8) pos++; if (trand(511) & 4) pos += WIDTH; return (seekctr(pos)); } /* set by getprefs * flag diagonal first four plays */ static int diag; firstplay() { SQUARE turn = BLACK; SQUARE *pos = NULL; SQUARE *pos43 = (SQUARE *) board + 4 * WIDTH + 3; int off; while (TRUE) { display((SQUARE *) board, turn); prompt(uturn[turn], turn); if (uturn[turn]) pos = getuctr(turn); if (!uturn[turn] || (pos == NULL)) pos = getcctr(); unprompt(uturn[turn]); if (pos == NULL) break; *pos = turn; if (diag) { off = pos43 - pos + 1; *((off & 1) ? pos + 1 : pos - 1) = -turn; pos += (pos >= pos43) ? -WIDTH : WIDTH; *pos = -turn; *((off & 1) ? pos + 1 : pos - 1) = turn; break; } turn = -turn; } } /* read a char and flush to EOL */ int getc2cr() { int ch = getchar(); while (getchar() != '\n') ; return (ch); } getprefs() { trandize(); printf("A game of Reversi\n\n"); printf("Copyright 1991, Joel Matthew Rees\n"); printf(" 565 E. Mansfield Ave,\n South Salt Lake City, Utah 84106\n\n"); printf("Enter skill level <0 .. %d>\n", DEPTH); level = (DEPTH & getc2cr()); printf("\nWill the computer play black? <y/n>\n"); uturn[BLACK] = !(tolower(getc2cr()) == 'y'); printf("\nWill the computer play white? <y/n>\n"); uturn[WHITE] = !(tolower(getc2cr()) == 'y'); printf("\nWill the first four plays be\n diagonal <y/n>\n"); diag = tolower(getc2cr()) == 'y'; printf("\nInstructions:\n"); printf("Use cursor keys\n and press <ENTER> to select play.\n"); printf("Press <C>\n to have the computer play for you.\n"); printf("Press any key to start the game.\n"); getchar(); trandize(); } main() { int noplay = FALSE; SQUARE turn = BLACK; SQUARE *pos; getprefs(); gograph(); init(board); putboard(); firstplay(); do { display(board, turn); prompt(CONTINUE, turn); getch(path); if ((pos = getplay(turn)) == NULL) { noplay++; prompt(NOPLAY, turn); } else { noplay = FALSE; play(board, pos, turn); } turn = -turn; } while (noplay < 2); display(board, 0); prompt(QUIT, turn); getch(path); endgraph(); printf("Thank you.\n Come again.\n"); return(0); }
\ No newline at end of file
1+/* SCC$reversi.c#mwc0.01/26Apr1991 */ /* reversi: a game like Othello * An OS-9 version in C, by Joel Matthew Rees, Dec '89 * Drastically modified for MS-DOS/TURBO-C March 1991 -- jmr * new OS-9/CoCo version Apr/May 1991 * This version uses assembler in the radar routine, * to see if there is any speed improvement. * Copyright 1991 Joel Matthew Rees * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * Copyright for this program and all object code generated from it * and its excerpts are assigned by the author to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ /* problems with (LN *) casting in Microware C for OS-9/6809! */ #include <stdio.h> #include <process.h> #include <ctype.h> #include <common.h> #include <keybd.h> #include "rand.h" #include "board.h" static char gbuf[4]; /* this probably ought have been defined in board.c! * getc for a path rather than a file pointer */ int getch(path) int path; { read(path, gbuf, 1); return(gbuf[0]); } #define KBRDY 1 /* this might also ought have been defined in board.c! * check for input available */ int kbhit(p) int p; { return (getstat(KBRDY, path) != EOF); } /* eat NUL prebytes and force upper case * caveats: punctuation (0x20 -- 0x3f) gets forced to control characters */ int getarrow() { int temp; while ((temp = getch(path)) == NUL) ; return (temp & ~0x20); } /* strategic values of board positions */ BD vals = { { 8, -4, 4, 2, 2, 4, -4, 8 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 8, -4, 4, 2, 2, 4, -4, 8 } }; SQUARE *valp = (SQUARE *) vals; #define DEPTH 7 /* must be one less than a power of two */ BD board[DEPTH + 1]; static int top = 0; /* top of the various stacks */ static int level; /* level of look-ahead */ /* for a fast offset and a cast that doesn't work in MWC should be LN *boardof(x) */ SQUARE *boardof(x) int x; /* LSByte only */ { #asm lda 5,s clrb asra rorb asra rorb leax board,y leax d,x tfr x,d #endasm } /* translate an arrow key to cursor motion * Permute graphics mapping in this function * Perform bounding ELSEWHERE!!! */ SQUARE *cursmove(cursor, key) SQUARE *cursor; uint key; { int k_d; switch (key) { case LEFT: k_d = -1; break; case RIGHT: k_d = 1; break; case DOWN: k_d = WIDTH; break; case UP: k_d = -WIDTH; break; case 'C': cursor = NULL; /* fall through */ default: k_d = 0; } if (k_d != 0) { cursor += k_d; } return (cursor); } /* convert pointers to indices * 8 byte wide board is faster than to / and % * #asm code assumes sizeof(board) < 128 */ xy(bd, pos, ax, ay) LN *bd; SQUARE *pos; int *ax; int *ay; { #asm * int dif = (pos - (SQUARE *) bd); ldd 6,s subd 4,s pshs b (0 <= d < 128) * *ay = (dif >> 3); asrb asrb asrb std [11,s] * *ax = (dif & 7); puls b andb #7 std [8,s] #endasm } /* erase board and fill in borders */ init(tboard) LN *tboard; { register SQUARE *bd = (SQUARE *) tboard; SQUARE *lim = ((SQUARE *) tboard) + WIDTH * WIDTH; while (bd < lim) *bd++ = NONE; } #define RANK7 (WIDTH * (WIDTH - 1)) /* check all directions for a scoring line * quits as soon as a scoring line is found * returns !FALSE if scoring line found * This might be done in a loop, but it should be faster unrolled */ int radar(bd, player, pos) LN *bd; SQUARE player; SQUARE *pos; { #asm * register SQUARE *base = (SQUARE *) bd; ldx 4,s * int ipos = pos - base; ( 1,s ) * int beam = ipos; ( b ) ldd 8,s subd 4,s cmpd #64 bhs radno ipos set 9 stb ipos,s reuse pos LSB * SQUARE other = -player; ( ,s ) player set 7 lda player,s nega other set 6 sta other,s use player MSB * if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { lda b,x beq radck radno clra clrb puls u,pc radck * if (beam < WIDTH * (WIDTH - 2)) { /* up the array */ cmpb #48 bhs rad3 * if (base[beam += WIDTH] == other) addb #8 lda b,x cmpa other,s bne rad1 * while (beam < RANK7) rad0l cmpb #56 RANK7 bhs rad1 * if (base[beam += WIDTH] != other) addb #8 lda b,x cmpa other,s beq rad0l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad1 * beam = ipos; ldb ipos,s * if ((beam & WM) < 6) /* up & right */ lda ipos,s anda #7 WM cmpa #6 bhs rad2 * if (base[beam += WIDTH + 1] == other) addb #9 lda b,x cmpa other,s bne rad2 * while (((beam & WM) < 7) && (beam < RANK7 - 1)) rad1l cmpb #55 (RANK7 - 1) bhs rad2 tfr b,a anda #7 cmpa #7 bhs rad2 * if (base[beam += WIDTH + 1] != other) addb #9 lda b,x cmpa other,s beq rad1l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad2 * beam = ipos; ldb ipos,s * if ((beam & WM) > 1) /* up & left */ lda ipos,s anda #7 WM cmpa #1 bls rad3 * if (base[beam += WIDTH - 1] == other) addb #7 lda b,x cmpa other,s bne rad3 * while (((beam & WM) > 0) && (beam < RANK7 - 1)) rad2l cmpb #55 (RANK7 - 1) bhs rad3 tfr b,a anda #7 beq rad3 * if (base[beam += WIDTH - 1] != other) addb #7 lda b,x cmpa other,s beq rad2l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; * } rad3 * beam = ipos; ldb ipos,s * if (beam >= WIDTH * 2) { /* down the array */ cmpb #16 blo rad6 * if (base[beam -= WIDTH] == other) subb #8 lda b,x cmpa other,s bne rad4 * while (beam >= WIDTH) rad3l cmpb #8 WIDTH blo rad4 * if (base[beam -= WIDTH] != other) subb #8 lda b,x cmpa other,s beq rad3l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad4 * beam = ipos; ldb ipos,s * if ((beam & WM) < 6) /* down & right */ lda ipos,s anda #7 cmpa #6 bhs rad5 * if (base[beam -= WIDTH - 1] == other) subb #7 lda b,x cmpa other,s bne rad5 * while (((beam & WM) < 7) && (beam > WIDTH)) rad4l cmpb #8 WIDTH bls rad5 tfr b,a anda #7 cmpa #7 bhs rad5 * if (base[beam -= WIDTH - 1] != other) subb #7 lda b,x cmpa other,s beq rad4l * if (base[beam] == player) cmpa player,s * goto ping; lbeq ping * else * break; rad5 * beam = ipos; ldb ipos,s * if ((beam & WM) > 1) /* down & left */ lda ipos,s anda #7 cmpa #1 bls rad6 * if (base[beam -= WIDTH + 1] == other) subb #9 lda b,x cmpa other,s bne rad6 * while (((beam & WM) > 0) && (beam > WIDTH)) rad5l cmpb #8 WIDTH bls rad6 tfr b,a anda #7 beq rad6 * if (base[beam -= WIDTH + 1] != other) subb #9 lda b,x cmpa other,s beq rad5l * if (base[beam] == player) cmpa player,s * goto ping; beq ping * else * break; * } rad6 * beam = ipos; ldb ipos,s * if ((beam & WM) < 6) /* right */ lda ipos,s anda #7 cmpa #6 bhs rad7 * if (base[++beam] == other) incb lda b,x cmpa other,s bne rad7 * while ((beam & WM) < 7) rad6l tfr b,a anda #7 cmpa #7 bhs rad7 * if (base[++beam] != other) incb lda b,x cmpa other,s beq rad6l * if (base[beam] == player) cmpa player,s * goto ping; beq ping * else * break; rad7 * beam = ipos; ldb ipos,s * if ((beam & WM) > 1) /* left */ lda ipos,s anda #7 cmpa #1 lbls radno * if (base[--beam] == other) decb lda b,x cmpa other,s lbne radno * while ((beam & WM) > 0) rad7l tfr b,a anda #7 lbeq radno * if (base[--beam] != other) decb lda b,x cmpa other,s beq rad7l * if (base[beam] == player) cmpa player,s * goto ping; beq ping * else * break; * } * return(FALSE); lbra radno ping * return(TRUE); ldd #1 #endasm } /* put a piece down and capture lines * returns count captured, does not count piece played */ int play(bd, pos, player) LN *bd; SQUARE *pos; SQUARE player; { register SQUARE *base = (SQUARE *) bd; int ipos = pos - base; int beam = ipos; int pcs = 0; SQUARE other = -player; if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { while (beam < RANK7) /* up the array */ if (base[beam += WIDTH] != other) break; if (base[beam] == player) while (base[beam -= WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while (beam >= WIDTH) /* down the array */ if (base[beam -= WIDTH] != other) break; if (base[beam] == player) while (base[beam += WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) < 7) /* right */ if (base[++beam] != other) break; if (base[beam] == player) while (base[--beam] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) > 0) /* left */ if (base[--beam] != other) break; if (base[beam] == player) while (base[++beam] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & right */ while (((beam & WM) < 7) && (beam < RANK7)) if (base[beam += WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH + 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & left */ while (((beam & WM) > 0) && (beam < RANK7)) if (base[beam += WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & right */ while (((beam & WM) < 7) && (beam >= WIDTH)) if (base[beam -= WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & left */ while (((beam & WM) > 0) && (beam >= WIDTH)) if (base[beam -= WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH + 1] == other) { base[beam] = player; pcs++; } if (pcs > 0) { *pos = player; if (top == level + 1) pcs += valp[pos - (SQUARE *) bd]; } } return(pcs); } /* seek a playable position, from pos, in increasing order * restores pos to board boundaries before seeking * before or after board will start at bd[0][0] * tests (restored) pos first * return NULL if no position playable after returning to pos */ SQUARE *seek(bd, pos, turn) LN *bd; SQUARE *pos; SQUARE turn; { register SQUARE *hunt; SQUARE *bhome = (SQUARE *) bd; SQUARE *bend = (SQUARE *) bd + WIDTH * WIDTH - 1; if ((pos < bhome) || (pos > bend)) pos = bhome; hunt = pos; do { if (*hunt == NONE) if (radar(bd, turn, hunt)) { pos = NULL; /* force hunt != pos */ break; } if (++hunt > bend) hunt = bhome; } while (hunt != pos); return (hunt == pos ? NULL : hunt); } /* wrap pos around center */ SQUARE *wrapsq(bd, pos, lo, hi) LN *bd; SQUARE *pos; int lo; int hi; { int i, j; xy(bd, pos, &j, &i); if (i < lo) i = hi; else if (i > hi) i = lo; if (j < lo) j = hi; else if (j > hi) j = lo; return ((SQUARE *) bd + (i << 3) + j); } /* drop out unceremoniously * (have to provide some orderly emergency exit!) */ quit(turn) SQUARE turn; { int resp; Bell(path); prompt(REALLY, turn); resp = tolower(getch(path)); if ((resp == 'y') || (resp == 'q')) { endgraph(); printf("So glad you could join us!\n"); exit(0); } unprompt(REALLY); } /* copy top level to test level, * initializes and cancels operations on test level, */ revert() { #asm * register SQUARE *scan = (SQUARE *) board + (top << 6); ldd top,y pshs d lbsr boardof tfr d,x * SQUARE *last = scan + WIDTH * WIDTH; leau 64,x stu ,s * while (scan < last) { bra revt revlup * scan[0] = scan[-(WIDTH * WIDTH)]; ldd -64,x two at a time std ,x++ * scan++; * } revt cmpx ,s blo revlup leas 2,s #endasm } /* find best play, recursive to level * return a value for the play * uses *pos to seed seek() * also uses *pos to flag noplay for next level of recursion * displays the cursor when evaluating level 0 * also checks for keyboard quit when evaluating level 0 */ int eval(turn, pos) SQUARE turn; SQUARE **pos; { SQUARE *test; /* should be (LN *) */ register SQUARE *check = (*pos) + WIDTH * WIDTH; SQUARE *oldc = NULL; SQUARE *best = NULL; int val; int oldv = MININT; int x, y; SQUARE *other = NULL; test = boardof(++top); revert(); check = seek(test, check - WIDTH - 1, turn); /* seek neighboring */ oldc = check; /* flag end */ other = check; /* flag noplay for deeper levels */ do { if (check != NULL) { if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); xy(test, check, &x, &y); showcursor(x, y, TRUE); } val = play(test, check, turn); } else { val = 0; if ((check == NULL) && (*pos == NULL)) break; /* no play left */ } if (top < level) val -= eval(-turn, &other); if (val > oldv) { oldv = val; best = check; } else if ((val == oldv) && (trand(1001 + top) & 32)) best = check; revert(); check++; if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); clrcursor(); } } while ((check = seek(test, check, turn)) != oldc); --top; *pos = (best == NULL) ? NULL : boardof(top) + (best - (SQUARE *) test); return(oldv); } /* get a play from a user * return NULL if computer selected or no play */ SQUARE *getuplay(turn, pos) SQUARE turn; SQUARE *pos; { SQUARE *cursor = seek(board, pos - WIDTH - 1, turn); /* neighbor */ uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 0, 7); else break; if (radar(board, turn, cursor)) { Bell(path); prompt(WILLPLAY, turn); } else { key = NUL; prompt(NOGOOD, turn); } } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } static int turnf[BLACK - WHITE + 1]; /* set by getprefs */ static int *uturn = turnf + 1; /* for accessing turn by player */ /* get a position to play a turn * returns the position to play */ SQUARE *getplay(turn) SQUARE turn; { static SQUARE *mem = (SQUARE *) board; SQUARE *mtemp; if (uturn[turn]) { prompt(USER, turn); mtemp = getuplay(turn, mem); unprompt(USER); } if (!uturn[turn] || (mtemp == NULL)) { prompt(COMPUTER, turn); eval(turn, &mem); unprompt(COMPUTER); } else mem = mtemp; return(mem); } /* find an empty position in the center four * forces pos to "nearest" center position if out of bounds * returns pos found or NULL */ SQUARE *seekctr(pos) register SQUARE *pos; { SQUARE *pos33 = (SQUARE *) board + 3 * WIDTH + 3; SQUARE *pos43 = pos33 + WIDTH; SQUARE *old = NULL; if (pos < pos33) pos = pos33; while (TRUE) { if ((pos > pos33 + 1) && (pos < pos43)) pos = pos43; else if (pos > pos43 + 1) pos = pos33; if ((*pos == NONE) || (pos == old)) break; if (old == NULL) old = pos; pos++; } return (*pos == NONE ? pos : NULL); } /* let user select one of first four moves * returns position selected * if no position available, returns NULL */ SQUARE *getuctr(turn) SQUARE turn; { SQUARE *cursor = seekctr((SQUARE *) board); uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 3, 4); else break; if (*cursor != NONE) { prompt(NOGOOD, turn); key = NUL; } else prompt(WILLPLAY, turn); } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } /* have computer find one of the first four moves * return position found or NULL */ SQUARE *getcctr() { SQUARE *pos = (SQUARE *) board + WIDTH * 3 + 3; if (trand(129) & 8) pos++; if (trand(511) & 4) pos += WIDTH; return (seekctr(pos)); } /* set by getprefs * flag diagonal first four plays */ static int diag; firstplay() { SQUARE turn = BLACK; SQUARE *pos = NULL; SQUARE *pos43 = (SQUARE *) board + 4 * WIDTH + 3; int off; while (TRUE) { display((SQUARE *) board, turn); prompt(uturn[turn], turn); if (uturn[turn]) pos = getuctr(turn); if (!uturn[turn] || (pos == NULL)) pos = getcctr(); unprompt(uturn[turn]); if (pos == NULL) break; *pos = turn; if (diag) { off = pos43 - pos + 1; *((off & 1) ? pos + 1 : pos - 1) = -turn; pos += (pos >= pos43) ? -WIDTH : WIDTH; *pos = -turn; *((off & 1) ? pos + 1 : pos - 1) = turn; break; } turn = -turn; } } /* read a char and flush to EOL */ int getc2cr() { int ch = getchar(); while (getchar() != '\n') ; return (ch); } getprefs() { trandize(); printf("A game of Reversi\n\n"); printf("Copyright 1991, Joel Matthew Rees\n"); printf(" 565 E. Mansfield Ave,\n South Salt Lake City, Utah 84106\n\n"); printf("Enter skill level <0 .. %d>\n", DEPTH); level = (DEPTH & getc2cr()); printf("\nWill the computer play black? <y/n>\n"); uturn[BLACK] = !(tolower(getc2cr()) == 'y'); printf("\nWill the computer play white? <y/n>\n"); uturn[WHITE] = !(tolower(getc2cr()) == 'y'); printf("\nWill the first four plays be\n diagonal <y/n>\n"); diag = tolower(getc2cr()) == 'y'; printf("\nInstructions:\n"); printf("Use cursor keys\n and press <ENTER> to select play.\n"); printf("Press <C>\n to have the computer play for you.\n"); printf("Press any key to start the game.\n"); getchar(); trandize(); } main() { int noplay = FALSE; SQUARE turn = BLACK; SQUARE *pos; getprefs(); gograph(); init(board); putboard(); firstplay(); do { display(board, turn); prompt(CONTINUE, turn); getch(path); if ((pos = getplay(turn)) == NULL) { noplay++; prompt(NOPLAY, turn); } else { noplay = FALSE; play(board, pos, turn); } turn = -turn; } while (noplay < 2); display(board, 0); prompt(QUIT, turn); getch(path); endgraph(); printf("Thank you.\n Come again.\n"); return(0); }
\ No newline at end of file
--- a/reversi.c
+++ b/reversi.c
@@ -1 +1 @@
1-/* SCC$reversi.c#mwc0.01/26Apr1991 */ /* reversi: a game like Othello * An OS-9 version in C, by Joel Matthew Rees, Dec '89 * Drastically modified for MS-DOS/TURBO-C March 1991 -- jmr * new OS-9/CoCo version Apr/May 1991 * This version does not assembler in the radar routine. * Copyright 1991 Joel Matthew Rees * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * Copyright for this program and all object code generated from it * and its excerpts are assigned by the author to the public domain. */ /* problems with (LN *) casting in Microware C for OS-9/6809! */ #include <stdio.h> #include <process.h> #include <ctype.h> #include <common.h> #include <keybd.h> #include "rand.h" #include "board.h" static char gbuf[4]; /* this probably ought have been defined in board.c! * getc for a path rather than a file pointer */ int getch(path) int path; { read(path, gbuf, 1); return(gbuf[0]); } #define KBRDY 1 /* this might also ought have been defined in board.c! * check for input available */ int kbhit(p) int p; { return (getstat(KBRDY, path) != EOF); } /* eat NUL prebytes and force upper case * caveats: punctuation (0x20 -- 0x3f) gets forced to control characters */ int getarrow() { int temp; while ((temp = getch(path)) == NUL) ; return (temp & ~0x20); } /* strategic values of board positions */ BD vals = { { 8, -4, 4, 2, 2, 4, -4, 8 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 8, -4, 4, 2, 2, 4, -4, 8 } }; SQUARE *valp = (SQUARE *) vals; #define DEPTH 7 /* must be one less than a power of two */ BD board[DEPTH + 1]; static int top = 0; /* top of the various stacks */ static int level; /* level of look-ahead */ /* for a fast offset and a cast that doesn't work in MWC should be LN *boardof(x) */ SQUARE *boardof(x) int x; /* LSByte only */ { #asm lda 5,s clrb asra rorb asra rorb leax board,y leax d,x tfr x,d #endasm } /* translate an arrow key to cursor motion * Permute graphics mapping in this function * Perform bounding ELSEWHERE!!! */ SQUARE *cursmove(cursor, key) SQUARE *cursor; uint key; { int k_d; switch (key) { case LEFT: k_d = -1; break; case RIGHT: k_d = 1; break; case DOWN: k_d = WIDTH; break; case UP: k_d = -WIDTH; break; case 'C': cursor = NULL; /* fall through */ default: k_d = 0; } if (k_d != 0) { cursor += k_d; } return (cursor); } /* convert pointers to indices * 8 byte wide board is faster than to / and % * #asm code assumes sizeof(board) < 128 */ xy(bd, pos, ax, ay) LN *bd; SQUARE *pos; int *ax; int *ay; { #asm * int dif = (pos - (SQUARE *) bd); ldd 6,s subd 4,s pshs b (0 <= d < 128) * *ay = (dif >> 3); asrb asrb asrb std [11,s] * *ax = (dif & 7); puls b andb #7 std [8,s] #endasm } /* erase board and fill in borders */ init(tboard) LN *tboard; { register SQUARE *bd = (SQUARE *) tboard; SQUARE *lim = ((SQUARE *) tboard) + WIDTH * WIDTH; while (bd < lim) *bd++ = NONE; } #define RANK7 (WIDTH * (WIDTH - 1)) /* check all directions for a scoring line * quits as soon as a scoring line is found * returns TRUE if scoring line found * This might be done in a loop, but it should be faster unrolled */ int radar(bd, player, pos) LN *bd; SQUARE player; SQUARE *pos; { register SQUARE *base = (SQUARE *) bd; int ipos = pos - base; int beam = ipos; SQUARE other = -player; if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { if (beam < WIDTH * (WIDTH - 2)) { /* up the array */ if (base[beam += WIDTH] == other) while (beam < RANK7) if (base[beam += WIDTH] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) < 6) /* up & right */ if (base[beam += WIDTH + 1] == other) while (((beam & WM) < 7) && (beam < RANK7)) if (base[beam += WIDTH + 1] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) > 1) /* up & left */ if (base[beam += WIDTH - 1] == other) while (((beam & WM) > 0) && (beam < RANK7)) if (base[beam += WIDTH - 1] != other) if (base[beam] == player) goto ping; else break; } beam = ipos; if (beam >= WIDTH * 2) { /* down the array */ if (base[beam -= WIDTH] == other) while (beam >= WIDTH) if (base[beam -= WIDTH] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) < 6) /* down & right */ if (base[beam -= WIDTH - 1] == other) while (((beam & WM) < 7) && (beam > WIDTH)) if (base[beam -= WIDTH - 1] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) > 1) /* down & left */ if (base[beam -= WIDTH + 1] == other) while (((beam & WM) > 0) && (beam > WIDTH)) if (base[beam -= WIDTH + 1] != other) if (base[beam] == player) goto ping; else break; } beam = ipos; if ((beam & WM) < 6) /* right */ if (base[++beam] == other) while ((beam & WM) < 7) if (base[++beam] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) > 1) /* left */ if (base[--beam] == other) while ((beam & WM) > 0) if (base[--beam] != other) if (base[beam] == player) goto ping; else break; } return(FALSE); ping: return(TRUE); } /* put a piece down and capture lines * returns count captured, does not count piece played */ int play(bd, pos, player) LN *bd; SQUARE *pos; SQUARE player; { register SQUARE *base = (SQUARE *) bd; int ipos = pos - base; int beam = ipos; int pcs = 0; SQUARE other = -player; if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { while (beam < RANK7) /* up the array */ if (base[beam += WIDTH] != other) break; if (base[beam] == player) while (base[beam -= WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while (beam >= WIDTH) /* down the array */ if (base[beam -= WIDTH] != other) break; if (base[beam] == player) while (base[beam += WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) < 7) /* right */ if (base[++beam] != other) break; if (base[beam] == player) while (base[--beam] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) > 0) /* left */ if (base[--beam] != other) break; if (base[beam] == player) while (base[++beam] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & right */ while (((beam & WM) < 7) && (beam < RANK7)) if (base[beam += WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH + 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & left */ while (((beam & WM) > 0) && (beam < RANK7)) if (base[beam += WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & right */ while (((beam & WM) < 7) && (beam >= WIDTH)) if (base[beam -= WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & left */ while (((beam & WM) > 0) && (beam >= WIDTH)) if (base[beam -= WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH + 1] == other) { base[beam] = player; pcs++; } if (pcs > 0) { *pos = player; if (top == level + 1) pcs += valp[pos - (SQUARE *) bd]; } } return(pcs); } /* seek a playable position, from pos, in increasing order * restores pos to board boundaries before seeking * before or after board will start at bd[0][0] * tests (restored) pos first * return NULL if no position playable after returning to pos */ SQUARE *seek(bd, pos, turn) LN *bd; SQUARE *pos; SQUARE turn; { register SQUARE *hunt; SQUARE *bhome = (SQUARE *) bd; SQUARE *bend = (SQUARE *) bd + WIDTH * WIDTH - 1; if ((pos < bhome) || (pos > bend)) pos = bhome; hunt = pos; do { if (*hunt == NONE) if (radar(bd, turn, hunt)) { pos = NULL; /* force hunt != pos */ break; } if (++hunt > bend) hunt = bhome; } while (hunt != pos); return (hunt == pos ? NULL : hunt); } /* wrap pos around center */ SQUARE *wrapsq(bd, pos, lo, hi) LN *bd; SQUARE *pos; int lo; int hi; { int i, j; xy(bd, pos, &j, &i); if (i < lo) i = hi; else if (i > hi) i = lo; if (j < lo) j = hi; else if (j > hi) j = lo; return ((SQUARE *) bd + (i << 3) + j); } /* drop out unceremoniously * (have to provide some orderly emergency exit!) */ quit(turn) SQUARE turn; { int resp; Bell(path); prompt(REALLY, turn); resp = tolower(getch(path)); if ((resp == 'y') || (resp == 'q')) { endgraph(); printf("So glad you could join us!\n"); exit(0); } unprompt(REALLY); } /* copy top level to test level, * initializes and cancels operations on test level, */ revert() { #asm * register SQUARE *scan = (SQUARE *) board + (top << 6); ldd top,y pshs d lbsr boardof tfr d,x * SQUARE *last = scan + WIDTH * WIDTH; leau 64,x stu ,s * while (scan < last) { bra revt revlup * scan[0] = scan[-(WIDTH * WIDTH)]; ldd -64,x two at a time std ,x++ * scan++; * } revt cmpx ,s blo revlup leas 2,s #endasm } /* find best play, recursive to level * return a value for the play * uses *pos to seed seek() * also uses *pos to flag noplay for next level of recursion * displays the cursor when evaluating level 0 * also checks for keyboard quit when evaluating level 0 */ int eval(turn, pos) SQUARE turn; SQUARE **pos; { SQUARE *test; /* should be (LN *) */ register SQUARE *check = (*pos) + WIDTH * WIDTH; SQUARE *oldc = NULL; SQUARE *best = NULL; int val; int oldv = MININT; int x, y; SQUARE *other = NULL; test = boardof(++top); revert(); check = seek(test, check - WIDTH - 1, turn); /* seek neighboring */ oldc = check; /* flag end */ other = check; /* flag noplay for deeper levels */ do { if (check != NULL) { if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); xy(test, check, &x, &y); showcursor(x, y, TRUE); } val = play(test, check, turn); } else { val = 0; if ((check == NULL) && (*pos == NULL)) break; /* no play left */ } if (top < level) val -= eval(-turn, &other); if (val > oldv) { oldv = val; best = check; } else if ((val == oldv) && (trand(1001 + top) & 32)) best = check; revert(); check++; if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); clrcursor(); } } while ((check = seek(test, check, turn)) != oldc); --top; *pos = (best == NULL) ? NULL : boardof(top) + (best - (SQUARE *) test); return(oldv); } /* get a play from a user * return NULL if computer selected or no play */ SQUARE *getuplay(turn, pos) SQUARE turn; SQUARE *pos; { SQUARE *cursor = seek(board, pos - WIDTH - 1, turn); /* neighbor */ uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 0, 7); else break; if (radar(board, turn, cursor)) { Bell(path); prompt(WILLPLAY, turn); } else { key = NUL; prompt(NOGOOD, turn); } } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } static int turnf[BLACK - WHITE + 1]; /* set by getprefs */ static int *uturn = turnf + 1; /* for accessing turn by player */ /* get a position to play a turn * returns the position to play */ SQUARE *getplay(turn) SQUARE turn; { static SQUARE *mem = (SQUARE *) board; SQUARE *mtemp; if (uturn[turn]) { prompt(USER, turn); mtemp = getuplay(turn, mem); unprompt(USER); } if (!uturn[turn] || (mtemp == NULL)) { prompt(COMPUTER, turn); eval(turn, &mem); unprompt(COMPUTER); } else mem = mtemp; return(mem); } /* find an empty position in the center four * forces pos to "nearest" center position if out of bounds * returns pos found or NULL */ SQUARE *seekctr(pos) register SQUARE *pos; { SQUARE *pos33 = (SQUARE *) board + 3 * WIDTH + 3; SQUARE *pos43 = pos33 + WIDTH; SQUARE *old = NULL; if (pos < pos33) pos = pos33; while (TRUE) { if ((pos > pos33 + 1) && (pos < pos43)) pos = pos43; else if (pos > pos43 + 1) pos = pos33; if ((*pos == NONE) || (pos == old)) break; if (old == NULL) old = pos; pos++; } return (*pos == NONE ? pos : NULL); } /* let user select one of first four moves * returns position selected * if no position available, returns NULL */ SQUARE *getuctr(turn) SQUARE turn; { SQUARE *cursor = seekctr((SQUARE *) board); uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 3, 4); else break; if (*cursor != NONE) { prompt(NOGOOD, turn); key = NUL; } else prompt(WILLPLAY, turn); } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } /* have computer find one of the first four moves * return position found or NULL */ SQUARE *getcctr() { SQUARE *pos = (SQUARE *) board + WIDTH * 3 + 3; if (trand(129) & 8) pos++; if (trand(511) & 4) pos += WIDTH; return (seekctr(pos)); } /* set by getprefs * flag diagonal first four plays */ static int diag; firstplay() { SQUARE turn = BLACK; SQUARE *pos = NULL; SQUARE *pos43 = (SQUARE *) board + 4 * WIDTH + 3; int off; while (TRUE) { display((SQUARE *) board, turn); prompt(uturn[turn], turn); if (uturn[turn]) pos = getuctr(turn); if (!uturn[turn] || (pos == NULL)) pos = getcctr(); unprompt(uturn[turn]); if (pos == NULL) break; *pos = turn; if (diag) { off = pos43 - pos + 1; *((off & 1) ? pos + 1 : pos - 1) = -turn; pos += (pos >= pos43) ? -WIDTH : WIDTH; *pos = -turn; *((off & 1) ? pos + 1 : pos - 1) = turn; break; } turn = -turn; } } /* read a char and flush to EOL */ int getc2cr() { int ch = getchar(); while (getchar() != '\n') ; return (ch); } getprefs() { trandize(); printf("A game of Reversi\n\n"); printf("Copyright 1991, Joel Matthew Rees\n"); printf(" 565 E. Mansfield Ave,\n South Salt Lake City, Utah 84106\n\n"); printf("Enter skill level <0 .. %d>\n", DEPTH); level = (DEPTH & getc2cr()); printf("\nWill the computer play black? <y/n>\n"); uturn[BLACK] = !(tolower(getc2cr()) == 'y'); printf("\nWill the computer play white? <y/n>\n"); uturn[WHITE] = !(tolower(getc2cr()) == 'y'); printf("\nWill the first four plays be\n diagonal <y/n>\n"); diag = tolower(getc2cr()) == 'y'; printf("\nInstructions:\n"); printf("Use cursor keys\n and press <ENTER> to select play.\n"); printf("Press <C>\n to have the computer play for you.\n"); printf("Press any key to start the game.\n"); getchar(); trandize(); } main() { int noplay = FALSE; SQUARE turn = BLACK; SQUARE *pos; getprefs(); gograph(); init(board); putboard(); firstplay(); do { display(board, turn); prompt(CONTINUE, turn); getch(path); if ((pos = getplay(turn)) == NULL) { noplay++; prompt(NOPLAY, turn); } else { noplay = FALSE; play(board, pos, turn); } turn = -turn; } while (noplay < 2); display(board, 0); prompt(QUIT, turn); getch(path); endgraph(); printf("Thank you.\n Come again.\n"); return(0); }
\ No newline at end of file
1+/* SCC$reversi.c#mwc0.01/26Apr1991 */ /* reversi: a game like Othello * An OS-9 version in C, by Joel Matthew Rees, Dec '89 * Drastically modified for MS-DOS/TURBO-C March 1991 -- jmr * new OS-9/CoCo version Apr/May 1991 * This version does not assembler in the radar routine. * Copyright 1991 Joel Matthew Rees * eliminated BORDER, pWIDTH for speed -- JMR 13Apr1991 * Copyright for this program and all object code generated from it * and its excerpts are assigned by the author to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ /* problems with (LN *) casting in Microware C for OS-9/6809! */ #include <stdio.h> #include <process.h> #include <ctype.h> #include <common.h> #include <keybd.h> #include "rand.h" #include "board.h" static char gbuf[4]; /* this probably ought have been defined in board.c! * getc for a path rather than a file pointer */ int getch(path) int path; { read(path, gbuf, 1); return(gbuf[0]); } #define KBRDY 1 /* this might also ought have been defined in board.c! * check for input available */ int kbhit(p) int p; { return (getstat(KBRDY, path) != EOF); } /* eat NUL prebytes and force upper case * caveats: punctuation (0x20 -- 0x3f) gets forced to control characters */ int getarrow() { int temp; while ((temp = getch(path)) == NUL) ; return (temp & ~0x20); } /* strategic values of board positions */ BD vals = { { 8, -4, 4, 2, 2, 4, -4, 8 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 2, -1, 0, 0, 0, 0, -1, 2 }, { 4, -2, 1, 0, 0, 1, -2, 4 }, { -4, -7, -2, -1, -1, -2, -7, -4 }, { 8, -4, 4, 2, 2, 4, -4, 8 } }; SQUARE *valp = (SQUARE *) vals; #define DEPTH 7 /* must be one less than a power of two */ BD board[DEPTH + 1]; static int top = 0; /* top of the various stacks */ static int level; /* level of look-ahead */ /* for a fast offset and a cast that doesn't work in MWC should be LN *boardof(x) */ SQUARE *boardof(x) int x; /* LSByte only */ { #asm lda 5,s clrb asra rorb asra rorb leax board,y leax d,x tfr x,d #endasm } /* translate an arrow key to cursor motion * Permute graphics mapping in this function * Perform bounding ELSEWHERE!!! */ SQUARE *cursmove(cursor, key) SQUARE *cursor; uint key; { int k_d; switch (key) { case LEFT: k_d = -1; break; case RIGHT: k_d = 1; break; case DOWN: k_d = WIDTH; break; case UP: k_d = -WIDTH; break; case 'C': cursor = NULL; /* fall through */ default: k_d = 0; } if (k_d != 0) { cursor += k_d; } return (cursor); } /* convert pointers to indices * 8 byte wide board is faster than to / and % * #asm code assumes sizeof(board) < 128 */ xy(bd, pos, ax, ay) LN *bd; SQUARE *pos; int *ax; int *ay; { #asm * int dif = (pos - (SQUARE *) bd); ldd 6,s subd 4,s pshs b (0 <= d < 128) * *ay = (dif >> 3); asrb asrb asrb std [11,s] * *ax = (dif & 7); puls b andb #7 std [8,s] #endasm } /* erase board and fill in borders */ init(tboard) LN *tboard; { register SQUARE *bd = (SQUARE *) tboard; SQUARE *lim = ((SQUARE *) tboard) + WIDTH * WIDTH; while (bd < lim) *bd++ = NONE; } #define RANK7 (WIDTH * (WIDTH - 1)) /* check all directions for a scoring line * quits as soon as a scoring line is found * returns TRUE if scoring line found * This might be done in a loop, but it should be faster unrolled */ int radar(bd, player, pos) LN *bd; SQUARE player; SQUARE *pos; { register SQUARE *base = (SQUARE *) bd; int ipos = pos - base; int beam = ipos; SQUARE other = -player; if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { if (beam < WIDTH * (WIDTH - 2)) { /* up the array */ if (base[beam += WIDTH] == other) while (beam < RANK7) if (base[beam += WIDTH] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) < 6) /* up & right */ if (base[beam += WIDTH + 1] == other) while (((beam & WM) < 7) && (beam < RANK7)) if (base[beam += WIDTH + 1] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) > 1) /* up & left */ if (base[beam += WIDTH - 1] == other) while (((beam & WM) > 0) && (beam < RANK7)) if (base[beam += WIDTH - 1] != other) if (base[beam] == player) goto ping; else break; } beam = ipos; if (beam >= WIDTH * 2) { /* down the array */ if (base[beam -= WIDTH] == other) while (beam >= WIDTH) if (base[beam -= WIDTH] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) < 6) /* down & right */ if (base[beam -= WIDTH - 1] == other) while (((beam & WM) < 7) && (beam > WIDTH)) if (base[beam -= WIDTH - 1] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) > 1) /* down & left */ if (base[beam -= WIDTH + 1] == other) while (((beam & WM) > 0) && (beam > WIDTH)) if (base[beam -= WIDTH + 1] != other) if (base[beam] == player) goto ping; else break; } beam = ipos; if ((beam & WM) < 6) /* right */ if (base[++beam] == other) while ((beam & WM) < 7) if (base[++beam] != other) if (base[beam] == player) goto ping; else break; beam = ipos; if ((beam & WM) > 1) /* left */ if (base[--beam] == other) while ((beam & WM) > 0) if (base[--beam] != other) if (base[beam] == player) goto ping; else break; } return(FALSE); ping: return(TRUE); } /* put a piece down and capture lines * returns count captured, does not count piece played */ int play(bd, pos, player) LN *bd; SQUARE *pos; SQUARE player; { register SQUARE *base = (SQUARE *) bd; int ipos = pos - base; int beam = ipos; int pcs = 0; SQUARE other = -player; if ((*pos == NONE) && (((unsigned) beam) < WIDTH * WIDTH)) { while (beam < RANK7) /* up the array */ if (base[beam += WIDTH] != other) break; if (base[beam] == player) while (base[beam -= WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while (beam >= WIDTH) /* down the array */ if (base[beam -= WIDTH] != other) break; if (base[beam] == player) while (base[beam += WIDTH] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) < 7) /* right */ if (base[++beam] != other) break; if (base[beam] == player) while (base[--beam] == other) { base[beam] = player; pcs++; } beam = ipos; while ((beam & WM) > 0) /* left */ if (base[--beam] != other) break; if (base[beam] == player) while (base[++beam] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & right */ while (((beam & WM) < 7) && (beam < RANK7)) if (base[beam += WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH + 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* up & left */ while (((beam & WM) > 0) && (beam < RANK7)) if (base[beam += WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam -= WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & right */ while (((beam & WM) < 7) && (beam >= WIDTH)) if (base[beam -= WIDTH - 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH - 1] == other) { base[beam] = player; pcs++; } beam = ipos; /* down & left */ while (((beam & WM) > 0) && (beam >= WIDTH)) if (base[beam -= WIDTH + 1] != other) break; if (base[beam] == player) while (base[beam += WIDTH + 1] == other) { base[beam] = player; pcs++; } if (pcs > 0) { *pos = player; if (top == level + 1) pcs += valp[pos - (SQUARE *) bd]; } } return(pcs); } /* seek a playable position, from pos, in increasing order * restores pos to board boundaries before seeking * before or after board will start at bd[0][0] * tests (restored) pos first * return NULL if no position playable after returning to pos */ SQUARE *seek(bd, pos, turn) LN *bd; SQUARE *pos; SQUARE turn; { register SQUARE *hunt; SQUARE *bhome = (SQUARE *) bd; SQUARE *bend = (SQUARE *) bd + WIDTH * WIDTH - 1; if ((pos < bhome) || (pos > bend)) pos = bhome; hunt = pos; do { if (*hunt == NONE) if (radar(bd, turn, hunt)) { pos = NULL; /* force hunt != pos */ break; } if (++hunt > bend) hunt = bhome; } while (hunt != pos); return (hunt == pos ? NULL : hunt); } /* wrap pos around center */ SQUARE *wrapsq(bd, pos, lo, hi) LN *bd; SQUARE *pos; int lo; int hi; { int i, j; xy(bd, pos, &j, &i); if (i < lo) i = hi; else if (i > hi) i = lo; if (j < lo) j = hi; else if (j > hi) j = lo; return ((SQUARE *) bd + (i << 3) + j); } /* drop out unceremoniously * (have to provide some orderly emergency exit!) */ quit(turn) SQUARE turn; { int resp; Bell(path); prompt(REALLY, turn); resp = tolower(getch(path)); if ((resp == 'y') || (resp == 'q')) { endgraph(); printf("So glad you could join us!\n"); exit(0); } unprompt(REALLY); } /* copy top level to test level, * initializes and cancels operations on test level, */ revert() { #asm * register SQUARE *scan = (SQUARE *) board + (top << 6); ldd top,y pshs d lbsr boardof tfr d,x * SQUARE *last = scan + WIDTH * WIDTH; leau 64,x stu ,s * while (scan < last) { bra revt revlup * scan[0] = scan[-(WIDTH * WIDTH)]; ldd -64,x two at a time std ,x++ * scan++; * } revt cmpx ,s blo revlup leas 2,s #endasm } /* find best play, recursive to level * return a value for the play * uses *pos to seed seek() * also uses *pos to flag noplay for next level of recursion * displays the cursor when evaluating level 0 * also checks for keyboard quit when evaluating level 0 */ int eval(turn, pos) SQUARE turn; SQUARE **pos; { SQUARE *test; /* should be (LN *) */ register SQUARE *check = (*pos) + WIDTH * WIDTH; SQUARE *oldc = NULL; SQUARE *best = NULL; int val; int oldv = MININT; int x, y; SQUARE *other = NULL; test = boardof(++top); revert(); check = seek(test, check - WIDTH - 1, turn); /* seek neighboring */ oldc = check; /* flag end */ other = check; /* flag noplay for deeper levels */ do { if (check != NULL) { if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); xy(test, check, &x, &y); showcursor(x, y, TRUE); } val = play(test, check, turn); } else { val = 0; if ((check == NULL) && (*pos == NULL)) break; /* no play left */ } if (top < level) val -= eval(-turn, &other); if (val > oldv) { oldv = val; best = check; } else if ((val == oldv) && (trand(1001 + top) & 32)) best = check; revert(); check++; if (top == 1) { if (kbhit(path)) if ((getch(path) | 0x20) == 'q') quit(turn); clrcursor(); } } while ((check = seek(test, check, turn)) != oldc); --top; *pos = (best == NULL) ? NULL : boardof(top) + (best - (SQUARE *) test); return(oldv); } /* get a play from a user * return NULL if computer selected or no play */ SQUARE *getuplay(turn, pos) SQUARE turn; SQUARE *pos; { SQUARE *cursor = seek(board, pos - WIDTH - 1, turn); /* neighbor */ uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 0, 7); else break; if (radar(board, turn, cursor)) { Bell(path); prompt(WILLPLAY, turn); } else { key = NUL; prompt(NOGOOD, turn); } } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } static int turnf[BLACK - WHITE + 1]; /* set by getprefs */ static int *uturn = turnf + 1; /* for accessing turn by player */ /* get a position to play a turn * returns the position to play */ SQUARE *getplay(turn) SQUARE turn; { static SQUARE *mem = (SQUARE *) board; SQUARE *mtemp; if (uturn[turn]) { prompt(USER, turn); mtemp = getuplay(turn, mem); unprompt(USER); } if (!uturn[turn] || (mtemp == NULL)) { prompt(COMPUTER, turn); eval(turn, &mem); unprompt(COMPUTER); } else mem = mtemp; return(mem); } /* find an empty position in the center four * forces pos to "nearest" center position if out of bounds * returns pos found or NULL */ SQUARE *seekctr(pos) register SQUARE *pos; { SQUARE *pos33 = (SQUARE *) board + 3 * WIDTH + 3; SQUARE *pos43 = pos33 + WIDTH; SQUARE *old = NULL; if (pos < pos33) pos = pos33; while (TRUE) { if ((pos > pos33 + 1) && (pos < pos43)) pos = pos43; else if (pos > pos43 + 1) pos = pos33; if ((*pos == NONE) || (pos == old)) break; if (old == NULL) old = pos; pos++; } return (*pos == NONE ? pos : NULL); } /* let user select one of first four moves * returns position selected * if no position available, returns NULL */ SQUARE *getuctr(turn) SQUARE turn; { SQUARE *cursor = seekctr((SQUARE *) board); uint key; int x, y; if (cursor != NULL) { Bell(path); prompt(WILLPLAY, turn); key = 1; /* not NUL, no action */ do { xy(board, cursor, &x, &y); showcursor(x, y, (key != NUL)); cursor = cursmove(cursor, key = getarrow()); if (key == 'Q') quit(turn); clrcursor(); if (cursor != NULL) cursor = wrapsq(board, cursor, 3, 4); else break; if (*cursor != NONE) { prompt(NOGOOD, turn); key = NUL; } else prompt(WILLPLAY, turn); } while(key != '\r'); } unprompt(WILLPLAY); return(cursor); } /* have computer find one of the first four moves * return position found or NULL */ SQUARE *getcctr() { SQUARE *pos = (SQUARE *) board + WIDTH * 3 + 3; if (trand(129) & 8) pos++; if (trand(511) & 4) pos += WIDTH; return (seekctr(pos)); } /* set by getprefs * flag diagonal first four plays */ static int diag; firstplay() { SQUARE turn = BLACK; SQUARE *pos = NULL; SQUARE *pos43 = (SQUARE *) board + 4 * WIDTH + 3; int off; while (TRUE) { display((SQUARE *) board, turn); prompt(uturn[turn], turn); if (uturn[turn]) pos = getuctr(turn); if (!uturn[turn] || (pos == NULL)) pos = getcctr(); unprompt(uturn[turn]); if (pos == NULL) break; *pos = turn; if (diag) { off = pos43 - pos + 1; *((off & 1) ? pos + 1 : pos - 1) = -turn; pos += (pos >= pos43) ? -WIDTH : WIDTH; *pos = -turn; *((off & 1) ? pos + 1 : pos - 1) = turn; break; } turn = -turn; } } /* read a char and flush to EOL */ int getc2cr() { int ch = getchar(); while (getchar() != '\n') ; return (ch); } getprefs() { trandize(); printf("A game of Reversi\n\n"); printf("Copyright 1991, Joel Matthew Rees\n"); printf(" 565 E. Mansfield Ave,\n South Salt Lake City, Utah 84106\n\n"); printf("Enter skill level <0 .. %d>\n", DEPTH); level = (DEPTH & getc2cr()); printf("\nWill the computer play black? <y/n>\n"); uturn[BLACK] = !(tolower(getc2cr()) == 'y'); printf("\nWill the computer play white? <y/n>\n"); uturn[WHITE] = !(tolower(getc2cr()) == 'y'); printf("\nWill the first four plays be\n diagonal <y/n>\n"); diag = tolower(getc2cr()) == 'y'; printf("\nInstructions:\n"); printf("Use cursor keys\n and press <ENTER> to select play.\n"); printf("Press <C>\n to have the computer play for you.\n"); printf("Press any key to start the game.\n"); getchar(); trandize(); } main() { int noplay = FALSE; SQUARE turn = BLACK; SQUARE *pos; getprefs(); gograph(); init(board); putboard(); firstplay(); do { display(board, turn); prompt(CONTINUE, turn); getch(path); if ((pos = getplay(turn)) == NULL) { noplay++; prompt(NOPLAY, turn); } else { noplay = FALSE; play(board, pos, turn); } turn = -turn; } while (noplay < 2); display(board, 0); prompt(QUIT, turn); getch(path); endgraph(); printf("Thank you.\n Come again.\n"); return(0); }
\ No newline at end of file
--- a/reversi.ps
+++ b/reversi.ps
@@ -1 +1 @@
1-The reversi game algorithm in pseudo-code. Analysis and expression by Joel Rees, Salt Lake City, sometime in the late 1980s, or early 1990s. The algorithm and strategy are common, I have never seen them copyrighted, I assume they are in the public domain. I assign any rights I might have to the following to the public domain. (February 2000.) (The game Othello is copyrighted. Reversi is dangerously close to Othello, but Roman Checkers and other versions of this game pre- date both, so I assume the copyright on Othello does not effect reversi.) reversi: set up board set up players play first four turns play until no plays left announce points --------------------------------------- set up board: clear board array query for opposing first turns set up players: clear no play/pass flag get player's names set turn variable randomize computer strategy play first four turns: if opposing first turns if computer not first player prompt for first play until play among center four else pick random square among center four place first player opposite place second player on both neighbors else while center four squares not filled if player is not computer prompt for play until play among center four if player is computer pick random play from squares remaining among center four display board play until no plays left: do if valid play available clear no play/pass flag get play for player make play else if pass flag set set no play flag change turns display board while no play flag not set announce points: count points for each player print scores --------------------------------------- test for valid play available: clear valid play available flag for each empty space on board and while valid play flag clear for each direction and while valid play flag clear if neighbor is other player probe player this direction if this player probed set valid play flag return valid play flag get play for player: if player is not computer prompt for play until valid play if player is computer or player consults computer look ahead depth plays for player probe player this direction: while neighbor is on board and neighbor is other player move to neighbor in this direction return neighbor owner --------------------------------------- look ahead depth plays for player: clear memory for each playable square on board play square calculate value of play this level if value is greater than memory or (value is equal to memory and crystal ball says yes) clear memory remember play --------------------------------------- calculate value of play at level: if level is zero calculate value by static function else look ahead depth-1 for other player value is - value for other player add value to count gained --------------------------------------- crystal ball: binary random function static value function: +32 -16 +4 -2 -16 -24 -2 +2 +4 -2 +8 +2 -2 +2 +2 0 (reflecting on both axes) --------------------------------------- New static evaluation algorithm (A): count own score store score as temp count opponent's score subtract opponent's score from temp find opponent's best move subtract opponent's best from temp if self owns any corner count unloseable territory store unloseable as perm if opponent owns any corner count ungainable territory subtract ungainable from perm value is perm + temp Problems with (A): Does not provide much guard against yeilding a corner early
\ No newline at end of file
1+The reversi game algorithm in pseudo-code. Analysis and expression by Joel Rees, Salt Lake City, sometime in the late 1980s, or early 1990s. The algorithm and strategy are common, I have never seen them copyrighted, I assume they are in the public domain. I assign any rights I might have to the following to the public domain. (February 2000.) (The game Othello is copyrighted. Reversi is dangerously close to Othello, but Roman Checkers and other versions of this game pre- date both, so I assume the copyright on Othello does not effect reversi.) * The author assigns his rights to this algorithm to the public domain. * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. reversi: set up board set up players play first four turns play until no plays left announce points --------------------------------------- set up board: clear board array query for opposing first turns set up players: clear no play/pass flag get player's names set turn variable randomize computer strategy play first four turns: if opposing first turns if computer not first player prompt for first play until play among center four else pick random square among center four place first player opposite place second player on both neighbors else while center four squares not filled if player is not computer prompt for play until play among center four if player is computer pick random play from squares remaining among center four display board play until no plays left: do if valid play available clear no play/pass flag get play for player make play else if pass flag set set no play flag change turns display board while no play flag not set announce points: count points for each player print scores --------------------------------------- test for valid play available: clear valid play available flag for each empty space on board and while valid play flag clear for each direction and while valid play flag clear if neighbor is other player probe player this direction if this player probed set valid play flag return valid play flag get play for player: if player is not computer prompt for play until valid play if player is computer or player consults computer look ahead depth plays for player probe player this direction: while neighbor is on board and neighbor is other player move to neighbor in this direction return neighbor owner --------------------------------------- look ahead depth plays for player: clear memory for each playable square on board play square calculate value of play this level if value is greater than memory or (value is equal to memory and crystal ball says yes) clear memory remember play --------------------------------------- calculate value of play at level: if level is zero calculate value by static function else look ahead depth-1 for other player value is - value for other player add value to count gained --------------------------------------- crystal ball: binary random function static value function: +32 -16 +4 -2 -16 -24 -2 +2 +4 -2 +8 +2 -2 +2 +2 0 (reflecting on both axes) --------------------------------------- New static evaluation algorithm (A): count own score store score as temp count opponent's score subtract opponent's score from temp find opponent's best move subtract opponent's best from temp if self owns any corner count unloseable territory store unloseable as perm if opponent owns any corner count ungainable territory subtract ungainable from perm value is perm + temp Problems with (A): Does not provide much guard against yeilding a corner early
\ No newline at end of file
--- a/string.h
+++ b/string.h
@@ -1 +1 @@
1-/* string.h -- function prototypes and stuff for string handling * Microware C for OS-9/6809 ceased to be actively developed before the * ANSI standard began to take shape, and followed pre-ANSI rules. * This header is therefore mostly cosmetic and documentational. * Copyright would be meaningless. * Joel Rees, June 1990 */ /* char *strcat(char *dst, char *src); */ char *strcat(); /* char *strncat(char *dst, char *src, int n); */ char *strncat(); /* int strcmp(char *dst, char *src); */ int strcmp(); /* int strncmp(char *dst, char *src, int n); */ int strncmp(); /* char *strcpy(char *dst, char *src); */ char *strcpy(); /* char *strncpy(char *dst, char *src, int n); */ char *strncpy(); /* char *strhcpy(char *dst, char *src); b7 set in terminator (OS-9) */ char *strhcpy(); /* char *strlen(char *str); */ int strlen(); /* char *index(char *str, int ch); */ char *index(); #define strchr index /* portability */ /* char *rindex(char *str, int ch); */ char *rindex(); #define strrchr rindex /* portability */
\ No newline at end of file
1+/* string.h -- function prototypes and stuff for string handling * Microware C for OS-9/6809 ceased to be actively developed before the * ANSI standard began to take shape, and followed pre-ANSI rules. * This header is therefore mostly cosmetic and documentational. * Copyright would be meaningless. * Joel Rees, June 1990 * If your jurisdiction does not allow public domain assignment, * you may use the following terms (MIT template): ** [Author(s)] ** Joel Rees, from November 2007 (JMR) ** All copyrights claimed and retained by the author(s). ** [License] ** This source may be used under the following conditions: ** * This source must be provided in some reasonable manner ** with any object distribution or publication. ** * This license notice may not be removed or modified. ** * Any modifications made to this file and published ** shall receive the same license. ** * The author(s) make no legal representations whatsoever ** concerning this source and the abstractions and/or ** implementations contained therein: ** * Each user assumes all liability and responsibility ** concerning such use. ** * USE AT YOUR OWN RISK. ** * The author(s) assert and concur that algorithms and ** other abstractions are fundamentally not patentable. ** * No other conditions are asserted. ** End of copyright and license notice. */ /* char *strcat(char *dst, char *src); */ char *strcat(); /* char *strncat(char *dst, char *src, int n); */ char *strncat(); /* int strcmp(char *dst, char *src); */ int strcmp(); /* int strncmp(char *dst, char *src, int n); */ int strncmp(); /* char *strcpy(char *dst, char *src); */ char *strcpy(); /* char *strncpy(char *dst, char *src, int n); */ char *strncpy(); /* char *strhcpy(char *dst, char *src); b7 set in terminator (OS-9) */ char *strhcpy(); /* char *strlen(char *str); */ int strlen(); /* char *index(char *str, int ch); */ char *index(); #define strchr index /* portability */ /* char *rindex(char *str, int ch); */ char *rindex(); #define strrchr rindex /* portability */
\ No newline at end of file