Chessboard demo for the Gameduino

Dependencies:   Gameduino mbed

Committer:
TheChrisyd
Date:
Fri Dec 21 13:48:51 2012 +0000
Revision:
1:1c7889325d09
Parent:
0:abda8c4b7cfd
updated Gameduino library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TheChrisyd 0:abda8c4b7cfd 1 #include "mbed.h"
TheChrisyd 0:abda8c4b7cfd 2 #include "GD.h"
TheChrisyd 0:abda8c4b7cfd 3 #include "shield.h"
TheChrisyd 0:abda8c4b7cfd 4
TheChrisyd 0:abda8c4b7cfd 5 #include "Wood32.h"
TheChrisyd 0:abda8c4b7cfd 6 #include "staunton.h" // Chess pieces from eboard's Staunton set: http://www.bergo.eng.br
TheChrisyd 0:abda8c4b7cfd 7
TheChrisyd 0:abda8c4b7cfd 8 #define digits (sizeof(staunton_img) / 256)
TheChrisyd 0:abda8c4b7cfd 9 #include "digits.h"
TheChrisyd 0:abda8c4b7cfd 10
TheChrisyd 0:abda8c4b7cfd 11 GDClass GD(ARD_MOSI, ARD_MISO, ARD_SCK, ARD_D9, USBTX, USBRX) ;
TheChrisyd 0:abda8c4b7cfd 12 int atxy(int x, int y)
TheChrisyd 0:abda8c4b7cfd 13 {
TheChrisyd 0:abda8c4b7cfd 14 return (y << 6) + x;
TheChrisyd 0:abda8c4b7cfd 15 }
TheChrisyd 0:abda8c4b7cfd 16
TheChrisyd 0:abda8c4b7cfd 17 static void square(byte x, byte y, byte light)
TheChrisyd 0:abda8c4b7cfd 18 {
TheChrisyd 0:abda8c4b7cfd 19 PROGMEM prog_uchar *src = Wood32_pic + (16 * light);
TheChrisyd 0:abda8c4b7cfd 20 int addr = atxy(x, y);
TheChrisyd 0:abda8c4b7cfd 21 GD.copy(addr + 0 * 64, src, 4);
TheChrisyd 0:abda8c4b7cfd 22 GD.copy(addr + 1 * 64, src + 4, 4);
TheChrisyd 0:abda8c4b7cfd 23 GD.copy(addr + 2 * 64, src + 8, 4);
TheChrisyd 0:abda8c4b7cfd 24 GD.copy(addr + 3 * 64, src + 12, 4);
TheChrisyd 0:abda8c4b7cfd 25 }
TheChrisyd 0:abda8c4b7cfd 26
TheChrisyd 0:abda8c4b7cfd 27 #define QROOK 0
TheChrisyd 0:abda8c4b7cfd 28 #define QKNIGHT 1
TheChrisyd 0:abda8c4b7cfd 29 #define QBISHOP 2
TheChrisyd 0:abda8c4b7cfd 30 #define QUEEN 3
TheChrisyd 0:abda8c4b7cfd 31 #define KING 4
TheChrisyd 0:abda8c4b7cfd 32 #define KBISHOP 5
TheChrisyd 0:abda8c4b7cfd 33 #define KKNIGHT 6
TheChrisyd 0:abda8c4b7cfd 34 #define KROOK 7
TheChrisyd 0:abda8c4b7cfd 35 #define PAWN 8
TheChrisyd 0:abda8c4b7cfd 36 #define WHITE 0x00
TheChrisyd 0:abda8c4b7cfd 37 #define BLACK 0x10
TheChrisyd 0:abda8c4b7cfd 38
TheChrisyd 0:abda8c4b7cfd 39 static signed char board[32];
TheChrisyd 0:abda8c4b7cfd 40
TheChrisyd 0:abda8c4b7cfd 41 static void startboard()
TheChrisyd 0:abda8c4b7cfd 42 {
TheChrisyd 0:abda8c4b7cfd 43 byte i;
TheChrisyd 0:abda8c4b7cfd 44
TheChrisyd 0:abda8c4b7cfd 45 for (i = 0; i < 8; i++) {
TheChrisyd 0:abda8c4b7cfd 46 board[i] = 56 + i;
TheChrisyd 0:abda8c4b7cfd 47 board[8+i] = 48 + i;
TheChrisyd 0:abda8c4b7cfd 48 board[16+i] = i;
TheChrisyd 0:abda8c4b7cfd 49 board[24+i] = 8 + i;
TheChrisyd 0:abda8c4b7cfd 50 }
TheChrisyd 0:abda8c4b7cfd 51 }
TheChrisyd 0:abda8c4b7cfd 52
TheChrisyd 0:abda8c4b7cfd 53 // Return the piece at pos, or -1 if pos is empty
TheChrisyd 0:abda8c4b7cfd 54 static signed char find(byte pos)
TheChrisyd 0:abda8c4b7cfd 55 {
TheChrisyd 0:abda8c4b7cfd 56 byte slot;
TheChrisyd 0:abda8c4b7cfd 57 for (slot = 0; slot < 32; slot++)
TheChrisyd 0:abda8c4b7cfd 58 if (board[slot] == pos)
TheChrisyd 0:abda8c4b7cfd 59 return slot;
TheChrisyd 0:abda8c4b7cfd 60 return -1;
TheChrisyd 0:abda8c4b7cfd 61 }
TheChrisyd 0:abda8c4b7cfd 62
TheChrisyd 0:abda8c4b7cfd 63 byte images[16] = { 0, 1, 2, 3, 4, 2, 1, 0, 5, 5, 5, 5, 5, 5, 5, 5 };
TheChrisyd 0:abda8c4b7cfd 64
TheChrisyd 0:abda8c4b7cfd 65 static void piece(byte slot, int x, int y)
TheChrisyd 0:abda8c4b7cfd 66 {
TheChrisyd 0:abda8c4b7cfd 67 byte i = (4 * slot);
TheChrisyd 0:abda8c4b7cfd 68 byte j = images[slot & 0xf] * 2;
TheChrisyd 0:abda8c4b7cfd 69 byte bw = (slot >> 4) & 1;
TheChrisyd 0:abda8c4b7cfd 70 GD.sprite(i, x, y, j, bw, 0);
TheChrisyd 0:abda8c4b7cfd 71 GD.sprite(i + 1, x + 16, y, j + 1, bw, 0);
TheChrisyd 0:abda8c4b7cfd 72 GD.sprite(i + 2, x, y + 16, j + 12, bw, 0);
TheChrisyd 0:abda8c4b7cfd 73 GD.sprite(i + 3, x + 16, y + 16, j + 13, bw, 0);
TheChrisyd 0:abda8c4b7cfd 74 }
TheChrisyd 0:abda8c4b7cfd 75
TheChrisyd 0:abda8c4b7cfd 76 #define BOARDX(pos) (8 + (((pos) & 7) << 5))
TheChrisyd 0:abda8c4b7cfd 77 #define BOARDY(pos) (24 + ((((pos) >> 3) & 7) << 5))
TheChrisyd 0:abda8c4b7cfd 78
TheChrisyd 0:abda8c4b7cfd 79 static void drawboard()
TheChrisyd 0:abda8c4b7cfd 80 {
TheChrisyd 0:abda8c4b7cfd 81 byte slot;
TheChrisyd 0:abda8c4b7cfd 82
TheChrisyd 0:abda8c4b7cfd 83 for (slot = 0; slot < 32; slot++) {
TheChrisyd 0:abda8c4b7cfd 84 signed char pos = board[slot];
TheChrisyd 0:abda8c4b7cfd 85 if (pos < 0)
TheChrisyd 0:abda8c4b7cfd 86 piece(slot, 400, 400);
TheChrisyd 0:abda8c4b7cfd 87 else {
TheChrisyd 0:abda8c4b7cfd 88 piece(slot, BOARDX(pos), BOARDY(pos));
TheChrisyd 0:abda8c4b7cfd 89 }
TheChrisyd 0:abda8c4b7cfd 90 }
TheChrisyd 0:abda8c4b7cfd 91 }
TheChrisyd 0:abda8c4b7cfd 92
TheChrisyd 0:abda8c4b7cfd 93 static float smoothstep(float x)
TheChrisyd 0:abda8c4b7cfd 94 {
TheChrisyd 0:abda8c4b7cfd 95 return x*x*(3-2*x);
TheChrisyd 0:abda8c4b7cfd 96 }
TheChrisyd 0:abda8c4b7cfd 97
TheChrisyd 0:abda8c4b7cfd 98
TheChrisyd 0:abda8c4b7cfd 99 // move piece 'slot' to position 'pos'.
TheChrisyd 0:abda8c4b7cfd 100 // return true if a piece was taken.
TheChrisyd 0:abda8c4b7cfd 101 static byte movepiece(byte slot, byte pos)
TheChrisyd 0:abda8c4b7cfd 102 {
TheChrisyd 0:abda8c4b7cfd 103 long double x0 = BOARDX(board[slot]);
TheChrisyd 0:abda8c4b7cfd 104 long double y0 = BOARDY(board[slot]);
TheChrisyd 0:abda8c4b7cfd 105 long double x1 = BOARDX(pos);
TheChrisyd 0:abda8c4b7cfd 106 long double y1 = BOARDY(pos);
TheChrisyd 0:abda8c4b7cfd 107 // move at 1.5 pix/frame
TheChrisyd 0:abda8c4b7cfd 108 int d = int(sqrt(((x0 - x1)*(x0 - x1)) + ((y0 - y1)*(y0 - y1))) / 2);
TheChrisyd 0:abda8c4b7cfd 109 int it;
TheChrisyd 0:abda8c4b7cfd 110 for (it = 0; it < d; it++) {
TheChrisyd 0:abda8c4b7cfd 111 float t = smoothstep(float(it) / d);
TheChrisyd 0:abda8c4b7cfd 112 GD.waitvblank();
TheChrisyd 0:abda8c4b7cfd 113 GD.waitvblank();
TheChrisyd 0:abda8c4b7cfd 114 piece(slot, int(x0 + t * (x1 - x0)), int(y0 + t * (y1 - y0)));
TheChrisyd 0:abda8c4b7cfd 115 }
TheChrisyd 0:abda8c4b7cfd 116 byte taken = find(pos) != -1;
TheChrisyd 0:abda8c4b7cfd 117 if (taken)
TheChrisyd 0:abda8c4b7cfd 118 board[find(pos)] = -1;
TheChrisyd 0:abda8c4b7cfd 119 board[slot] = pos;
TheChrisyd 0:abda8c4b7cfd 120 drawboard();
TheChrisyd 0:abda8c4b7cfd 121 return taken;
TheChrisyd 0:abda8c4b7cfd 122 }
TheChrisyd 0:abda8c4b7cfd 123
TheChrisyd 0:abda8c4b7cfd 124 void setup()
TheChrisyd 0:abda8c4b7cfd 125 {
TheChrisyd 0:abda8c4b7cfd 126 int i, j;
TheChrisyd 0:abda8c4b7cfd 127
TheChrisyd 0:abda8c4b7cfd 128 GD.begin();
TheChrisyd 0:abda8c4b7cfd 129 GD.ascii();
TheChrisyd 0:abda8c4b7cfd 130 GD.putstr(0, 0, "Chess board");
TheChrisyd 0:abda8c4b7cfd 131
TheChrisyd 0:abda8c4b7cfd 132 GD.copy(RAM_CHR, Wood32_chr, sizeof(Wood32_chr));
TheChrisyd 0:abda8c4b7cfd 133 GD.copy(RAM_PAL, Wood32_pal, sizeof(Wood32_pal));
TheChrisyd 0:abda8c4b7cfd 134 GD.copy(RAM_SPRIMG, staunton_img, sizeof(staunton_img));
TheChrisyd 0:abda8c4b7cfd 135 GD.copy(RAM_SPRPAL, staunton_white, sizeof(staunton_white));
TheChrisyd 0:abda8c4b7cfd 136 GD.copy(RAM_SPRPAL + 512, staunton_black, sizeof(staunton_black));
TheChrisyd 0:abda8c4b7cfd 137
TheChrisyd 0:abda8c4b7cfd 138 GD.copy(RAM_SPRIMG + (digits << 8), digits_img, sizeof(digits_img));
TheChrisyd 0:abda8c4b7cfd 139 GD.copy(RAM_SPRPAL + 2 * 512, digits_pal, sizeof(digits_pal));
TheChrisyd 0:abda8c4b7cfd 140 for (i = 0; i < 256; i++) {
TheChrisyd 0:abda8c4b7cfd 141 unsigned int b = GD.rd16(RAM_SPRPAL + 2 * 512 + 2 * i);
TheChrisyd 0:abda8c4b7cfd 142 GD.wr16(RAM_SPRPAL + 3 * 512 + 2 * i, b ^ 0x7fff);
TheChrisyd 0:abda8c4b7cfd 143 }
TheChrisyd 0:abda8c4b7cfd 144
TheChrisyd 0:abda8c4b7cfd 145 // Draw the 64 squares of the board
TheChrisyd 0:abda8c4b7cfd 146 for (i = 0; i < 8; i++)
TheChrisyd 0:abda8c4b7cfd 147 for (j = 0; j < 8; j++)
TheChrisyd 0:abda8c4b7cfd 148 square(1 + (i << 2), 3 + (j << 2), (i ^ j) & 1);
TheChrisyd 0:abda8c4b7cfd 149
TheChrisyd 0:abda8c4b7cfd 150 // Draw the rank and file markers 1-8 a-h
TheChrisyd 0:abda8c4b7cfd 151 for (i = 0; i < 8; i++) {
TheChrisyd 0:abda8c4b7cfd 152 GD.wr(atxy(3 + (i << 2), 2), 'a' + i);
TheChrisyd 0:abda8c4b7cfd 153 GD.wr(atxy(3 + (i << 2), 35), 'a' + i);
TheChrisyd 0:abda8c4b7cfd 154 GD.wr(atxy(0, 5 + (i << 2)), '8' - i);
TheChrisyd 0:abda8c4b7cfd 155 GD.wr(atxy(33, 5 + (i << 2)), '8' - i);
TheChrisyd 0:abda8c4b7cfd 156 }
TheChrisyd 0:abda8c4b7cfd 157
TheChrisyd 0:abda8c4b7cfd 158 startboard();
TheChrisyd 0:abda8c4b7cfd 159 drawboard();
TheChrisyd 0:abda8c4b7cfd 160 }
TheChrisyd 0:abda8c4b7cfd 161
TheChrisyd 0:abda8c4b7cfd 162 static int clocktimer[2];
TheChrisyd 0:abda8c4b7cfd 163
TheChrisyd 0:abda8c4b7cfd 164 // draw digit d in sprite slots spr,spr+1 at (x,y)
TheChrisyd 0:abda8c4b7cfd 165 static void digit(byte spr, byte d, byte bw, int x, int y)
TheChrisyd 0:abda8c4b7cfd 166 {
TheChrisyd 0:abda8c4b7cfd 167 GD.sprite(spr, x, y, digits + d, 2 + bw, 0);
TheChrisyd 0:abda8c4b7cfd 168 GD.sprite(spr + 1, x, y + 16, digits + d + 11, 2 + bw, 0);
TheChrisyd 0:abda8c4b7cfd 169 }
TheChrisyd 0:abda8c4b7cfd 170
TheChrisyd 0:abda8c4b7cfd 171 static void showclock(byte bw)
TheChrisyd 0:abda8c4b7cfd 172 {
TheChrisyd 0:abda8c4b7cfd 173 int t = clocktimer[bw];
TheChrisyd 0:abda8c4b7cfd 174 byte spr = 128 + (bw * 16);
TheChrisyd 0:abda8c4b7cfd 175 byte s = t % 60;
TheChrisyd 0:abda8c4b7cfd 176 int y = (bw ? 31 : 3) * 8;
TheChrisyd 0:abda8c4b7cfd 177 byte d0 = s % 10; s /= 10;
TheChrisyd 0:abda8c4b7cfd 178 digit(spr, d0, bw, 400 - 1 * 16, y);
TheChrisyd 0:abda8c4b7cfd 179 digit(spr + 2, s, bw, 400 - 2 * 16, y);
TheChrisyd 0:abda8c4b7cfd 180
TheChrisyd 0:abda8c4b7cfd 181 digit(spr + 4, 10, bw, 400 - 3 * 16, y); // colon
TheChrisyd 0:abda8c4b7cfd 182 spr += 6;
TheChrisyd 0:abda8c4b7cfd 183 int x = 400 - 4 * 16;
TheChrisyd 0:abda8c4b7cfd 184
TheChrisyd 0:abda8c4b7cfd 185 byte m = t / 60;
TheChrisyd 0:abda8c4b7cfd 186 do {
TheChrisyd 0:abda8c4b7cfd 187 d0 = m % 10; m /= 10;
TheChrisyd 0:abda8c4b7cfd 188 digit(spr, d0, bw, x, y);
TheChrisyd 0:abda8c4b7cfd 189 spr += 2;
TheChrisyd 0:abda8c4b7cfd 190 x -= 16;
TheChrisyd 0:abda8c4b7cfd 191 } while (m);
TheChrisyd 0:abda8c4b7cfd 192 }
TheChrisyd 0:abda8c4b7cfd 193
TheChrisyd 0:abda8c4b7cfd 194 static int turn;
TheChrisyd 0:abda8c4b7cfd 195
TheChrisyd 0:abda8c4b7cfd 196 #define ALG(r,f) ((r - 'a') + ((8 - f) * 8))
TheChrisyd 0:abda8c4b7cfd 197 #define CASTLE 255,255
TheChrisyd 0:abda8c4b7cfd 198
TheChrisyd 0:abda8c4b7cfd 199 static byte game[] = {
TheChrisyd 0:abda8c4b7cfd 200 ALG('e', 2),ALG('e', 4), ALG('e', 7),ALG('e', 5),
TheChrisyd 0:abda8c4b7cfd 201 ALG('g', 1),ALG('f', 3), ALG('b', 8),ALG('c', 6),
TheChrisyd 0:abda8c4b7cfd 202 ALG('f', 1),ALG('b', 5), ALG('a', 7),ALG('a', 6),
TheChrisyd 0:abda8c4b7cfd 203 ALG('b', 5),ALG('a', 4), ALG('g', 8),ALG('f', 6),
TheChrisyd 0:abda8c4b7cfd 204 ALG('d', 1),ALG('e', 2), ALG('b', 7),ALG('b', 5),
TheChrisyd 0:abda8c4b7cfd 205 ALG('a', 4),ALG('b', 3), ALG('f', 8),ALG('e', 7),
TheChrisyd 0:abda8c4b7cfd 206 ALG('c', 2),ALG('c', 3), CASTLE,
TheChrisyd 0:abda8c4b7cfd 207 CASTLE, ALG('d', 7),ALG('d', 5),
TheChrisyd 0:abda8c4b7cfd 208 ALG('e', 4),ALG('d', 5), ALG('f', 6),ALG('d', 5),
TheChrisyd 0:abda8c4b7cfd 209 ALG('f', 3),ALG('e', 5), ALG('d', 5),ALG('f', 4),
TheChrisyd 0:abda8c4b7cfd 210 ALG('e', 2),ALG('e', 4), ALG('c', 6),ALG('e', 5),
TheChrisyd 0:abda8c4b7cfd 211 ALG('e', 4),ALG('a', 8), ALG('d', 8),ALG('d', 3),
TheChrisyd 0:abda8c4b7cfd 212 ALG('b', 3),ALG('d', 1), ALG('c', 8),ALG('h', 3),
TheChrisyd 0:abda8c4b7cfd 213 ALG('a', 8),ALG('a', 6), ALG('h', 3),ALG('g', 2),
TheChrisyd 0:abda8c4b7cfd 214 ALG('f', 1),ALG('e', 1), ALG('d', 3),ALG('f', 3),
TheChrisyd 0:abda8c4b7cfd 215 };
TheChrisyd 0:abda8c4b7cfd 216
TheChrisyd 0:abda8c4b7cfd 217 static void putalg(byte x, byte y, byte a)
TheChrisyd 0:abda8c4b7cfd 218 {
TheChrisyd 0:abda8c4b7cfd 219 GD.wr(atxy(x, y), 'a' + (a & 7));
TheChrisyd 0:abda8c4b7cfd 220 GD.wr(atxy(x+1, y), '8' - ((a >> 3) & 7));
TheChrisyd 0:abda8c4b7cfd 221 }
TheChrisyd 0:abda8c4b7cfd 222
TheChrisyd 0:abda8c4b7cfd 223 int main()
TheChrisyd 0:abda8c4b7cfd 224 {
TheChrisyd 0:abda8c4b7cfd 225 setup();
TheChrisyd 0:abda8c4b7cfd 226 while(1){
TheChrisyd 0:abda8c4b7cfd 227 byte i;
TheChrisyd 0:abda8c4b7cfd 228 for (i = rand()%25; i; i--) {
TheChrisyd 0:abda8c4b7cfd 229 clocktimer[(1 & turn) ^ 1]++;
TheChrisyd 0:abda8c4b7cfd 230 GD.waitvblank();
TheChrisyd 0:abda8c4b7cfd 231 showclock(0);
TheChrisyd 0:abda8c4b7cfd 232 showclock(1);
TheChrisyd 0:abda8c4b7cfd 233 wait_ms(20);
TheChrisyd 0:abda8c4b7cfd 234 }
TheChrisyd 0:abda8c4b7cfd 235 if (turn < (sizeof(game) / 2)) {
TheChrisyd 0:abda8c4b7cfd 236 byte yy = 8 + (turn >> 1);
TheChrisyd 0:abda8c4b7cfd 237 byte xx = (turn & 1) ? 44 : 38;
TheChrisyd 0:abda8c4b7cfd 238 byte i = 1 + (turn >> 1);
TheChrisyd 0:abda8c4b7cfd 239 if (i >= 10)
TheChrisyd 0:abda8c4b7cfd 240 GD.wr(atxy(35, yy), '0' + i / 10);
TheChrisyd 0:abda8c4b7cfd 241 GD.wr(atxy(36, yy), '0' + i % 10);
TheChrisyd 0:abda8c4b7cfd 242 GD.wr(atxy(37, yy), '.');
TheChrisyd 0:abda8c4b7cfd 243
TheChrisyd 0:abda8c4b7cfd 244 byte from = game[2 * turn];
TheChrisyd 0:abda8c4b7cfd 245 byte to = game[2 * turn + 1];
TheChrisyd 0:abda8c4b7cfd 246 if (from != 255) {
TheChrisyd 0:abda8c4b7cfd 247 putalg(xx, yy, from);
TheChrisyd 0:abda8c4b7cfd 248 GD.wr(atxy(xx + 2, yy), movepiece(find(from), to) ? 'x' : '-');
TheChrisyd 0:abda8c4b7cfd 249 putalg(xx + 3, yy, to);
TheChrisyd 0:abda8c4b7cfd 250 } else {
TheChrisyd 0:abda8c4b7cfd 251 byte rank = (turn & 1) ? 8 : 1;
TheChrisyd 0:abda8c4b7cfd 252 movepiece(find(ALG('e', rank)), ALG('g', rank));
TheChrisyd 0:abda8c4b7cfd 253 movepiece(find(ALG('h', rank)), ALG('f', rank));
TheChrisyd 0:abda8c4b7cfd 254 GD.putstr(xx, yy, "O-O");
TheChrisyd 0:abda8c4b7cfd 255 }
TheChrisyd 0:abda8c4b7cfd 256 turn++;
TheChrisyd 0:abda8c4b7cfd 257 } else {
TheChrisyd 0:abda8c4b7cfd 258 wait_ms(4000);
TheChrisyd 0:abda8c4b7cfd 259 setup();
TheChrisyd 0:abda8c4b7cfd 260 turn = 0;
TheChrisyd 0:abda8c4b7cfd 261 clocktimer[0] = 0;
TheChrisyd 0:abda8c4b7cfd 262 clocktimer[1] = 0;
TheChrisyd 0:abda8c4b7cfd 263 }
TheChrisyd 0:abda8c4b7cfd 264 }}