/* This handles initializing and showing the game board in the game Trippin. */ #include #include #include "trip.h" /* a little substitute cause we don't need to know the contents: */ struct Image { long image; }; #define SQWID (SQIZE << 1) #define BOWID (SQIZE << 4) #define ARIZE ((SQIZE >> 1) - 2) #define RADZ (SQIZE / 3L) #define ANY 0xFF import struct Image olabel, blabel; import ubyte board[8][8]; import bool lace, won; import short sqite, thite; import struct RastPort *r; import piece bb, oo, *turn; private ubyte combos[58] = { /* all possible three-bits-true bytes */ 0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x15, 0x16, 0x19, 0x1A, 0x1C, 0x23, 0x25, 0x26, 0x29, 0x2A, 0x2C, 0x31, 0x32, 0x34, 0x38, 0x43, 0x45, 0x46, 0x49, 0x4A, 0x4C, 0x51, 0x52, 0x54, 0x58, 0x61, 0x62, 0x64, 0x68, 0x70, 0x83, 0x85, 0x86, 0x89, 0x8A, 0x8C, 0x91, 0x92, 0x94, 0x98, 0xA1, 0xA2, 0xA4, 0xA8, 0xB0, 0xC1, 0xC2, 0xC4, 0xC8, 0xD0, 0xE0, ANY, ANY }; void Shuffle() { ubyte deck[58]; register short x, y; int rand(), i = 0; movmem(combos, deck, 58); /* for (i = 0; i < 2; i++) /* some extra randomness */ for (x = 0; x < 58; x++) for (y = 0; y < 58; y++) if (rand() & 1) { register ubyte t = deck[x]; deck[x] = deck[y]; deck[y] = t; } for (x = 0; x < 8; x++) for (y = 0; y < 8; y++) if ((x == 1 || x == 6) && (y == 1 || y == 6)) board[x][y] = ANY; else if (y == 7 && (x == 4 || x == 3)) board[x][y] = ANY; else board[x][y] = deck[i++]; } private void DrawArrows(xc, yc, bits) short xc, yc, bits; { short sx = xc + (SQWID >> 1) + 1, sy = yc + (sqite >> 1); short dx, dy, len, i; RectFill(r, sx - 3L, sy - (1L << lace), sx + 2L, sy + (2L << lace) - 1); for (i = 0; i < 8; i++) if (bits & (1 << i)) { short yo = lace && i >= 2 && i <= 6; dx = sx; dy = sy; len = i & 1 ? ARIZE - (ARIZE >> 2) : ARIZE; if (i >= 1 && i <= 3) dx += len << 1; else if (i >= 5) dx -= (len << 1); if (i >= 3 && i <= 5) dy += len << lace; else if (i <= 1 || i == 7) dy -= len << lace; if (lace && sx != dx) { /* thicken lace non-verticals */ Move(r, (long) sx - (i >= 5), sy + 1L - yo); Draw(r, (long) dx - (i >= 5), dy + 1L - yo); } dy += yo; sy += yo; Move(r, (long) sx, (long) sy); Draw(r, (long) dx - (i == 6), (long) dy); if (sy != dy) { /* thicken non-horizontals */ Move(r, sx - 1L, (long) sy); Draw(r, dx - 1L, (long) dy); } sy -= yo; if (i & 1) { /* diagonal line arrowheads */ long ye = dy + ((i == 3 || i == 5 ? -3L : 3L) << lace); Move(r, (long) dx, (long) dy); Draw(r, (long) dx, ye); Move(r, dx - 1L, (long) dy); Draw(r, dx - 1L, ye); Move(r, (long) dx, (long) dy); Draw(r, dx + (i >= 5 ? 6L - lace : -7L + lace), (long) dy); if (lace) { if (yo) dy--; else dy++; Move(r, (long) dx, (long) dy); Draw(r, dx + (i >= 5 ? 6L - lace : -7L + lace), (long) dy); } } else { long pull; if (sx == dx) { /* vertical lines */ pull = (i == 4 ? -2 : 2) << lace; Move(r, (long) dx, (long) dy); Draw(r, dx + 4L, dy + pull); Move(r, dx - 1L, (long) dy); Draw(r, dx - 5L, dy + pull); if (lace) { if (i) dy--; else dy++; Move(r, (long) dx, (long) dy); Draw(r, dx + 4L, dy + pull); Move(r, dx - 1L, (long) dy); Draw(r, dx - 5L, dy + pull); } } else { /* horizontal lines */ pull = i == 2 ? -4 : 4; if (i == 6) dx--; if (lace) { Move(r, (long) dx, (long) dy); Draw(r, dx + pull, dy + (2L << lace)); Move(r, (long) dx, (long) dy - yo); Draw(r, dx + pull, dy - yo - (2L << lace)); } dx += (short) pull >> 2; Move(r, (long) dx, (long) dy); Draw(r, dx + pull, dy + (2L << lace)); Move(r, (long) dx, (long) dy - yo); Draw(r, dx + pull, dy - yo - (2L << lace)); } } } } void DrawSquare(x, y) short x, y; { long xc = 1 + x * SQWID, yc = thite + 2 + y * sqite, hafite = sqite >> 1; SetAPen(r, WHITE); RectFill(r, xc + 2, yc + 1 + lace, xc + SQWID - 1, yc + sqite - 1); SetAPen(r, BLACK); if ((x == 1 || x == 6) && (y == 1 || y == 6)) { DrawEllipse(r, xc + (SQWID >> 1) + 1, yc + hafite, RADZ << 1, RADZ << lace); DrawEllipse(r, xc + (SQWID >> 1), yc + hafite, RADZ << 1, RADZ << lace); if (lace) { DrawEllipse(r, xc + (SQWID >> 1) + 1, yc + hafite + 1, RADZ << 1, RADZ << lace); DrawEllipse(r, xc + (SQWID >> 1), yc + hafite + 1, RADZ << 1, RADZ << lace); } } else if (y == 7 && (x == 3 || x == 4)) { RectFill(r, xc + 8, yc + (4 << lace), xc + SQWID - 7, yc + sqite - (4 << lace) + lace); SetAPen(r, WHITE); RectFill(r, xc + 14, yc + (7 << lace), xc + SQWID - 13, yc + sqite - (7 << lace) + lace); } else if (board[x][y] != ANY) DrawArrows((short) xc, (short) yc, board[x][y]); SetAPen(r, BLACK); Move(r, xc + SQWID, yc); Draw(r, xc, yc); Draw(r, xc, yc + sqite); Move(r, xc + 1, yc + sqite); Draw(r, xc + 1, yc + 1); if (lace) Draw(r, xc + SQWID, yc + 1); } private void CenterText(say, y) str say; long y; { long sl = strlen(say); short tl = TextLength(r, say, sl); Move(r, BOWID + (MARGINWID >> 1) - (tl >> 1) + 1L, y + ((r->TxBaseline + 1) >> 1)); Text(r, say, sl); } private long yoff(y) short y; { return (long) (thite + 2 + ((y) << lace)); } void TellTurn() { short xc, yc; long a; struct Image *label; str say; bool blueturn = turn == &bb; static bool lastwon = true; SetAPen(r, WHITE); RectFill(r, BOWID + 5L, yoff(2), BOWID + MARGINWID - 2L, yoff(21) - 1); SetAPen(r, BLACK); SetBPen(r, WHITE); CenterText("To move: ", yoff(11)); label = blueturn ? &blabel : &olabel; DrawImage(r, label, BOWID - (IMWID >> 1) + 130L, yoff(11 - (IMHITE >> 1))); SetAPen(r, blueturn ? BLUE : ORANGE); RectFill(r, BOWID + 15L, yoff(32), BOWID + MARGINWID - 12L, yoff(56)); SetAPen(r, blueturn ? WHITE : BLACK); SetBPen(r, blueturn ? BLUE : ORANGE); if (won) say = "Game Over."; else if (!turn->allowed) say = "CAN'T MOVE!"; else if (turn->machine) say = "thinking..."; else say = "MAKE A MOVE"; CenterText(say, yoff(44)); SetAPen(r, WHITE); SetBPen(r, BLACK); CenterText("Legal Moves:", yoff(74)); xc = BOWID + ((MARGINWID) >> 1) - SQIZE; yc = yoff(82); RectFill(r, xc + 2L, yc + lace + 1L, xc + SQWID - 1L, yc + sqite - 1L); SetAPen(r, BLACK); DrawArrows(xc, yc, won ? 0 : turn->allowed); if (!turn->allowed) won = true; if (won == lastwon) return; lastwon = won; if (won) { SetAPen(r, ORANGE); RectFill(r, BOWID + 7L, yoff(112), BOWID + MARGINWID - 4L, yoff(174)); SetAPen(r, WHITE); RectFill(r, BOWID + 17L, yoff(117), BOWID + MARGINWID - 14L, yoff(169)); label = blueturn ? &olabel : &blabel; a = yoff(120); DrawImage(r, label, BOWID + 23L, a); DrawImage(r, label, BOWID + MARGINWID - IMWID - 20L, a); SetAPen(r, BLACK); SetBPen(r, WHITE); a = yoff(143) - ((thite + 1) >> 1); CenterText("WE HAVE", a); CenterText("A WINNER!", a + thite + 1); a = yoff(167 - IMHITE); DrawImage(r, label, BOWID + 23L, a); DrawImage(r, label, BOWID + MARGINWID - IMWID - 20L, a); } else { SetAPen(r, BLACK); RectFill(r, BOWID + 7L, yoff(112), BOWID + MARGINWID - 4L, yoff(174)); SetAPen(r, ORANGE); SetBPen(r, BLACK); CenterText("Try to reach", yoff(135) - thite); CenterText("the blinking", yoff(136)); CenterText(" X of your ", yoff(137) + thite); CenterText("piece's color", yoff(138) + (thite << 1)); } } void ShowBoard() { short x, y, i, bwid; long bot = 2 + thite + (sqite << 3); SetDrMd(r, JAM2); SetAPen(r, BLACK); RectFill(r, 3L + BOWID, thite + 2L, 2L + MARGINWID + BOWID, 2L + thite + (sqite << 3) + lace); for (x = 0; x < 8; x++) for (y = 0; y < 8; y++) DrawSquare(x, y); Move(r, BOWID + 2L, 2L + thite); Draw(r, BOWID + 2L, bot); Draw(r, 1L, bot); Move(r, BOWID + 1L, 2L + thite); Draw(r, BOWID + 1L, bot); if (lace) { Move(r, BOWID + 2L, bot + 1); Draw(r, 1L, bot + 1); } LiftBob(&oo); /* paint tokens in start position */ DropBob(&oo); LiftBob(&bb); DropBob(&bb); TellTurn(); }