26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 * |
27 * |
28 */ |
28 */ |
29 |
29 |
30 #include "game.h" |
30 #include "game.h" |
|
31 #include "input.h" |
|
32 #include <ncurses.h> |
|
33 #include <string.h> |
|
34 |
|
35 static const uint8_t boardx = 10, boardy = 10; |
|
36 |
|
37 static void draw_board(Board board) { |
|
38 |
|
39 for (uint8_t y = 0 ; y < 8 ; y++) { |
|
40 for (uint8_t x = 0 ; x < 8 ; x++) { |
|
41 uint8_t col = board[y][x] & COLOR_MASK; |
|
42 uint8_t piece = board[y][x] & PIECE_MASK; |
|
43 char piecec = ' '; |
|
44 switch (piece) { |
|
45 case PAWN: piecec = 'P'; break; |
|
46 case ROOK: piecec = 'R'; break; |
|
47 case KNIGHT: piecec = 'N'; break; |
|
48 case BISHOP: piecec = 'B'; break; |
|
49 case QUEEN: piecec = 'Q'; break; |
|
50 case KING: piecec = 'K'; break; |
|
51 } |
|
52 |
|
53 attrset((col == WHITE ? A_BOLD : A_DIM) | |
|
54 COLOR_PAIR((y&1)==(x&1) ? COL_WB : COL_BW)); |
|
55 |
|
56 mvaddch(boardy-y, boardx+x*3, ' '); |
|
57 mvaddch(boardy-y, boardx+x*3+1, piecec); |
|
58 mvaddch(boardy-y, boardx+x*3+2, ' '); |
|
59 } |
|
60 } |
|
61 |
|
62 attrset(A_NORMAL); |
|
63 for (uint8_t i = 0 ; i < 8 ; i++) { |
|
64 mvaddch(boardy+1, boardx+i*3+1, 'a'+i); |
|
65 mvaddch(boardy-i, boardx-2, '1'+i); |
|
66 } |
|
67 } |
|
68 |
|
69 static int sendmove(int opponent) { |
|
70 const size_t buflen = 8; |
|
71 char move[buflen]; |
|
72 _Bool remisrejected = FALSE; |
|
73 |
|
74 while (1) { |
|
75 move(boardy+3, 0); |
|
76 if (remisrejected) { |
|
77 printw( |
|
78 "Use chess notation to enter your move.\n" |
|
79 "Remis offer rejected - type 'surr' to surrender. \n\n" |
|
80 "Type your move: "); |
|
81 } else { |
|
82 printw( |
|
83 "Use chess notation to enter your move.\n" |
|
84 "Or type 'surr' to surrender or 'remis' to offer remis.\n\n" |
|
85 "Type your move: "); |
|
86 } |
|
87 clrtoeol(); |
|
88 refresh(); |
|
89 getnstr(move, buflen); |
|
90 |
|
91 if (strncmp(move, "surr", buflen) == 0) { |
|
92 printw("You surrendered!"); |
|
93 net_send_code(opponent, NETCODE_SURRENDER); |
|
94 return 1; |
|
95 } else if (strncmp(move, "remis", buflen) == 0) { |
|
96 if (!remisrejected) { |
|
97 net_send_code(opponent, NETCODE_REMIS); |
|
98 printw("Remis offer sent - waiting for acceptance..."); |
|
99 refresh(); |
|
100 if (net_recieve_code(opponent) == NETCODE_ACCEPT) { |
|
101 printw("\rRemis accepted!"); |
|
102 clrtoeol(); |
|
103 return 1; |
|
104 } else { |
|
105 remisrejected = TRUE; |
|
106 } |
|
107 } |
|
108 } else { |
|
109 // TODO: validate move syntactically |
|
110 // TODO: send move and await acceptance |
|
111 } |
|
112 } |
|
113 } |
|
114 |
|
115 static int recvmove(int opponent) { |
|
116 |
|
117 while (1) { |
|
118 move(boardy+3, 0); |
|
119 printw("Awaiting opponent move..."); |
|
120 clrtoeol(); |
|
121 refresh(); |
|
122 |
|
123 // TODO: nonblocking |
|
124 uint32_t code = net_recieve_code(opponent); |
|
125 switch (code) { |
|
126 case NETCODE_SURRENDER: |
|
127 printw("\rYour opponent surrendered!"); |
|
128 clrtoeol(); |
|
129 return 1; |
|
130 case NETCODE_REMIS: |
|
131 if (prompt_yesno( |
|
132 "\rYour opponent offers remis - do you accept")) { |
|
133 printw("\rRemis accepted!"); |
|
134 clrtoeol(); |
|
135 net_send_code(opponent, NETCODE_ACCEPT); |
|
136 return 1; |
|
137 } else { |
|
138 net_send_code(opponent, NETCODE_DECLINE); |
|
139 } |
|
140 break; |
|
141 case NETCODE_MOVE: |
|
142 // TODO: receive move |
|
143 // TODO: validate move and accept/reject |
|
144 return 0; |
|
145 } |
|
146 } |
|
147 } |
31 |
148 |
32 void game_start(Settings *settings, int opponent) { |
149 void game_start(Settings *settings, int opponent) { |
|
150 _Bool myturn = is_server(settings) == |
|
151 (settings->gameinfo.servercolor == WHITE); |
|
152 _Bool running; |
33 |
153 |
|
154 Board board = { |
|
155 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, |
|
156 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, |
|
157 {0, 0, 0, 0, 0, 0, 0, 0}, |
|
158 {0, 0, 0, 0, 0, 0, 0, 0}, |
|
159 {0, 0, 0, 0, 0, 0, 0, 0}, |
|
160 {0, 0, 0, 0, 0, 0, 0, 0}, |
|
161 {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN}, |
|
162 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK} |
|
163 }; |
|
164 |
|
165 do { |
|
166 clear(); |
|
167 draw_board(board); |
|
168 if (myturn) { |
|
169 running = !sendmove(opponent); |
|
170 } else { |
|
171 running = !recvmove(opponent); |
|
172 flushinp(); // flush any input the user hacked in while waiting |
|
173 } |
|
174 myturn ^= 1; |
|
175 } while (running); |
|
176 |
|
177 mvaddstr(getmaxy(tchess_window)-1, 0, |
|
178 "Game has ended. Press any key to leave..."); |
|
179 getch(); |
34 } |
180 } |