src/game.c

changeset 8
52d742aee695
parent 7
41468077b5bb
child 9
4e4f156bba58
equal deleted inserted replaced
7:41468077b5bb 8:52d742aee695
32 #include <ncurses.h> 32 #include <ncurses.h>
33 #include <string.h> 33 #include <string.h>
34 34
35 static const uint8_t boardx = 10, boardy = 10; 35 static const uint8_t boardx = 10, boardy = 10;
36 36
37 static void draw_board(Board board) { 37 static void draw_board(Board board, uint8_t mycolor) {
38 38
39 for (uint8_t y = 0 ; y < 8 ; y++) { 39 for (uint8_t y = 0 ; y < 8 ; y++) {
40 for (uint8_t x = 0 ; x < 8 ; x++) { 40 for (uint8_t x = 0 ; x < 8 ; x++) {
41 uint8_t col = board[y][x] & COLOR_MASK; 41 uint8_t col = board[y][x] & COLOR_MASK;
42 uint8_t piece = board[y][x] & PIECE_MASK; 42 uint8_t piece = board[y][x] & PIECE_MASK;
51 } 51 }
52 52
53 attrset((col == WHITE ? A_BOLD : A_DIM) | 53 attrset((col == WHITE ? A_BOLD : A_DIM) |
54 COLOR_PAIR((y&1)==(x&1) ? COL_WB : COL_BW)); 54 COLOR_PAIR((y&1)==(x&1) ? COL_WB : COL_BW));
55 55
56 mvaddch(boardy-y, boardx+x*3, ' '); 56 int cy = mycolor == WHITE ? boardy-y : boardy-7+y;
57 mvaddch(boardy-y, boardx+x*3+1, piecec); 57 int cx = mycolor == WHITE ? boardx+x*3 : boardx+21-x*3;
58 mvaddch(boardy-y, boardx+x*3+2, ' '); 58 mvaddch(cy, cx, ' ');
59 mvaddch(cy, cx+1, piecec);
60 mvaddch(cy, cx+2, ' ');
59 } 61 }
60 } 62 }
61 63
62 attrset(A_NORMAL); 64 attrset(A_NORMAL);
63 for (uint8_t i = 0 ; i < 8 ; i++) { 65 for (uint8_t i = 0 ; i < 8 ; i++) {
64 mvaddch(boardy+1, boardx+i*3+1, 'a'+i); 66 int x = mycolor == WHITE ? boardx+i*3+1 : boardx+22-i*3;
65 mvaddch(boardy-i, boardx-2, '1'+i); 67 int y = mycolor == WHITE ? boardy-i : boardy-7+i;
66 } 68 mvaddch(boardy+1, x, 'a'+i);
67 } 69 mvaddch(y, boardx-2, '1'+i);
68 70 }
69 static int sendmove(int opponent) { 71 }
72
73 static void apply_move(Board board, Move *move) {
74 board[move->fromrow][move->fromfile] = 0;
75 // TODO: care for en passant capture
76 board[move->torow][move->tofile] = move->piece;
77 }
78
79 static _Bool validate_move(Board board, uint8_t mycolor, Move *move) {
80 _Bool result = TRUE;
81
82 /* does piece exist */
83 result &= board[move->fromrow][move->fromfile] == move->piece;
84
85 /* is move rule conform */
86 // TODO: make it so
87
88 /* is piece blocked */
89 // TODO: make it so
90
91 /* is piece pinned */
92 // TODO: make it so
93
94 return result;
95 }
96
97 static _Bool eval_move(Board board, uint8_t mycolor, char *movestr, Move *move) {
98 memset(move, 0, sizeof(Move));
99
100 size_t len = strlen(movestr);
101
102 /* remove check */
103 if (movestr[len-1] == '+') {
104 len--; movestr[len] = '\0';
105 move->check = TRUE;
106 }
107
108 if (len == 2) {
109 /* pawn move (e.g. "e4") */
110 if (isfile(movestr[0]) && isrow(movestr[1])) {
111 move->piece = PAWN;
112 move->fromfile = move->tofile = fileidx(movestr[0]);
113 move->torow = rowidx(movestr[1]);
114 move->fromrow = rowidx(movestr[1]) + (mycolor == WHITE ? -1 : 1);
115 if (move->fromrow > 6) {
116 move->piece = 0;
117 } else {
118 /* advanced first move */
119 if (move->fromrow == (mycolor == WHITE ? 2 : 5) &&
120 board[move->fromrow][move->fromfile] != (mycolor|PAWN)) {
121
122 move->fromrow += (mycolor == WHITE ? -1 : 1);
123 if (move->fromrow > 6) {
124 move->piece = 0;
125 }
126 }
127 }
128 }
129 } else if (len == 3) {
130 if (strcmp(movestr, "0-0") == 0) {
131 /* king side castling */
132 move->piece = KING;
133 move->fromfile = fileidx('e');
134 move->fromfile = fileidx('g');
135 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
136 } else {
137 /* unambiguous move (e.g. "Nf3") */
138 }
139
140 } else if (len == 4) {
141 /* ambiguous move (e.g. "Ndf3") */
142
143 /* unambiguous capture (e.g. "Nxf3", "dxe5") */
144
145 } else if (len == 5) {
146 /* queen side castling "O-O-O" */
147
148 /* ambiguous capture (e.g. "Ndxf3") */
149
150 /* long notation move (e.g. "Nc5a4") */
151
152 /* long notation capture (e.g. "e5xf6") */
153 } else if (len == 6) {
154 /* long notation capture (e.g. "Nc5xf3") */
155 }
156
157 if (move->piece) {
158 move->piece |= mycolor;
159 return TRUE;
160 } else {
161 return FALSE;
162 }
163 }
164
165 static int sendmove(Board board, uint8_t mycolor, int opponent) {
70 const size_t buflen = 8; 166 const size_t buflen = 8;
71 char move[buflen]; 167 char movestr[buflen];
72 _Bool remisrejected = FALSE; 168 _Bool remisrejected = FALSE;
73 169
74 while (1) { 170 while (1) {
75 move(boardy+3, 0); 171 move(boardy+3, 0);
76 if (remisrejected) { 172 if (remisrejected) {
84 "Or type 'surr' to surrender or 'remis' to offer remis.\n\n" 180 "Or type 'surr' to surrender or 'remis' to offer remis.\n\n"
85 "Type your move: "); 181 "Type your move: ");
86 } 182 }
87 clrtoeol(); 183 clrtoeol();
88 refresh(); 184 refresh();
89 getnstr(move, buflen); 185 getnstr(movestr, buflen);
90 186
91 if (strncmp(move, "surr", buflen) == 0) { 187 if (strncmp(movestr, "surr", buflen) == 0) {
92 printw("You surrendered!"); 188 printw("You surrendered!");
189 refresh();
93 net_send_code(opponent, NETCODE_SURRENDER); 190 net_send_code(opponent, NETCODE_SURRENDER);
94 return 1; 191 return 1;
95 } else if (strncmp(move, "remis", buflen) == 0) { 192 } else if (strncmp(movestr, "remis", buflen) == 0) {
96 if (!remisrejected) { 193 if (!remisrejected) {
97 net_send_code(opponent, NETCODE_REMIS); 194 net_send_code(opponent, NETCODE_REMIS);
98 printw("Remis offer sent - waiting for acceptance..."); 195 printw("Remis offer sent - waiting for acceptance...");
99 refresh(); 196 refresh();
100 if (net_recieve_code(opponent) == NETCODE_ACCEPT) { 197 if (net_recieve_code(opponent) == NETCODE_ACCEPT) {
101 printw("\rRemis accepted!"); 198 printw("\rRemis accepted!");
102 clrtoeol(); 199 clrtoeol();
200 refresh();
103 return 1; 201 return 1;
104 } else { 202 } else {
105 remisrejected = TRUE; 203 remisrejected = TRUE;
106 } 204 }
107 } 205 }
108 } else { 206 } else {
109 // TODO: validate move syntactically 207 Move move;
110 // TODO: send move and await acceptance 208 if (eval_move(board, mycolor, movestr, &move)) {
111 } 209 net_send_code(opponent, NETCODE_MOVE);
112 } 210 net_send_data(opponent, &move, sizeof(Move));
113 } 211 if (net_recieve_code(opponent) == NETCODE_ACCEPT) {
114 212 apply_move(board, &move);
115 static int recvmove(int opponent) { 213 return 0;
214 } else {
215 printw("Invalid move.");
216 clrtoeol();
217 }
218 } else {
219 printw("Can't interpret move - please use algebraic notation.");
220 }
221 }
222 }
223 }
224
225 static int recvmove(Board board, uint8_t mycolor, int opponent) {
116 226
117 while (1) { 227 while (1) {
118 move(boardy+3, 0); 228 move(boardy+3, 0);
119 printw("Awaiting opponent move..."); 229 printw("Awaiting opponent move...");
120 clrtoeol(); 230 clrtoeol();
121 refresh(); 231 refresh();
122 232
123 // TODO: nonblocking 233 // TODO: nonblocking
124 uint32_t code = net_recieve_code(opponent); 234 uint32_t code = net_recieve_code(opponent);
235
236 Move move;
125 switch (code) { 237 switch (code) {
126 case NETCODE_SURRENDER: 238 case NETCODE_SURRENDER:
127 printw("\rYour opponent surrendered!"); 239 printw("\rYour opponent surrendered!");
128 clrtoeol(); 240 clrtoeol();
129 return 1; 241 return 1;
137 } else { 249 } else {
138 net_send_code(opponent, NETCODE_DECLINE); 250 net_send_code(opponent, NETCODE_DECLINE);
139 } 251 }
140 break; 252 break;
141 case NETCODE_MOVE: 253 case NETCODE_MOVE:
142 // TODO: receive move 254 net_recieve_data(opponent, &move, sizeof(Move));
143 // TODO: validate move and accept/reject 255 if (validate_move(board, mycolor, &move)) {
144 return 0; 256 apply_move(board, &move);
257 net_send_code(opponent, NETCODE_ACCEPT);
258 return 0;
259 } else {
260 net_send_code(opponent, NETCODE_DECLINE);
261 }
145 } 262 }
146 } 263 }
147 } 264 }
148 265
149 void game_start(Settings *settings, int opponent) { 266 void game_start(Settings *settings, int opponent) {
150 _Bool myturn = is_server(settings) == 267 _Bool myturn = is_server(settings) ==
151 (settings->gameinfo.servercolor == WHITE); 268 (settings->gameinfo.servercolor == WHITE);
269 uint8_t mycolor = myturn ? WHITE:BLACK;
270
152 _Bool running; 271 _Bool running;
153 272
154 Board board = { 273 Board board = {
155 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, 274 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
156 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, 275 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN},
162 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK} 281 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
163 }; 282 };
164 283
165 do { 284 do {
166 clear(); 285 clear();
167 draw_board(board); 286 draw_board(board, mycolor);
168 if (myturn) { 287 if (myturn) {
169 running = !sendmove(opponent); 288 running = !sendmove(board, mycolor, opponent);
170 } else { 289 } else {
171 running = !recvmove(opponent); 290 running = !recvmove(board, mycolor, opponent);
172 flushinp(); // flush any input the user hacked in while waiting 291 flushinp(); // flush any input the user hacked in while waiting
173 } 292 }
174 myturn ^= 1; 293 myturn ^= 1;
175 } while (running); 294 } while (running);
176 295

mercurial