Rev 3924 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3924 | Rev 5098 | ||
---|---|---|---|
1 | // |
1 | // |
2 | // KReversi.java |
2 | // KReversi.java |
3 | // The Othello Game, based on the algorithm of Muffy Barkocy |
3 | // The Othello Game, based on the algorithm of Muffy Barkocy |
4 | // (muffy@fish.com). |
4 | // (muffy@fish.com). |
5 | // |
5 | // |
6 | // The strategy is very very simple. The best move for the computer |
6 | // The strategy is very very simple. The best move for the computer |
7 | // is the move that flip more pieces (preferring boards line and |
7 | // is the move that flip more pieces (preferring boards line and |
8 | // corners) and give less pieces to move to the opponent. |
8 | // corners) and give less pieces to move to the opponent. |
9 | // |
9 | // |
10 | // Author: Alex "Kazuma" Garbagnati (kazuma@energy.it) |
10 | // Author: Alex "Kazuma" Garbagnati (kazuma@energy.it) |
11 | // Date: 20 Jan 96 |
11 | // Date: 20 Jan 96 |
12 | // L.R.: 26 Jan 96 |
12 | // L.R.: 26 Jan 96 |
13 | // Note: |
13 | // Note: |
14 | // |
14 | // |
15 | 15 | ||
16 | 16 | ||
17 | 17 | ||
18 | #include |
18 | #include |
19 | #include |
19 | #include |
20 | #include |
20 | #include |
21 | #include |
21 | #include |
22 | #include |
22 | #include |
23 | #include |
23 | #include |
24 | 24 | ||
25 | typedef unsigned int u32; |
25 | typedef unsigned int u32; |
26 | 26 | ||
27 | int YSHIFT= 33; |
27 | int YSHIFT= 33; |
28 | 28 | ||
29 | int ENGLISH = 0; // |
29 | int ENGLISH = 0; // |
30 | int ITALIAN = 1; // Languages |
30 | int ITALIAN = 1; // Languages |
31 | int EXTERNAL = 2; // |
31 | int EXTERNAL = 2; // |
32 | 32 | ||
33 | #define BLACK 0x000000; // |
33 | #define BLACK 0x000000; // |
34 | #define BLACK_S 0x333333; // |
34 | #define BLACK_S 0x333333; // |
35 | #define WHITE 0xffffff; // Colors |
35 | #define WHITE 0xffffff; // Colors |
36 | #define WHITE_S 0xaaaaaa; // |
36 | #define WHITE_S 0xaaaaaa; // |
37 | 37 | ||
38 | 38 | ||
39 | int NOMOVE = 0; // |
39 | int NOMOVE = 0; // |
40 | int REALMOVE = 1; // Type of move |
40 | int REALMOVE = 1; // Type of move |
41 | int PSEUDOMOVE = 2; // |
41 | int PSEUDOMOVE = 2; // |
42 | 42 | ||
43 | int Empty = 0; // |
43 | int Empty = 0; // |
44 | int User = 1; // Board's owners |
44 | int User = 1; // Board's owners |
45 | int Computer = 2; // |
45 | int Computer = 2; // |
46 | 46 | ||
47 | #define true 1 |
47 | #define true 1 |
48 | #define false 0 |
48 | #define false 0 |
49 | 49 | ||
50 | int UserMove = true; |
50 | int UserMove = true; |
51 | int GameOver = false; |
51 | int GameOver = false; |
52 | int CopyWinOn = false; |
52 | int CopyWinOn = false; |
53 | int StillInitiated = false; // This solve a little |
53 | int StillInitiated = false; // This solve a little |
54 | // problem on reinit. |
54 | // problem on reinit. |
55 | 55 | ||
56 | int TheBoard[8][8]; // Board |
56 | int TheBoard[8][8]; // Board |
57 | int Score[8][8]; |
57 | int Score[8][8]; |
58 | int OpponentScore[8][8]; |
58 | int OpponentScore[8][8]; |
59 | 59 | ||
60 | 60 | ||
61 | 61 | ||
62 | // |
62 | // |
63 | // DrawBoard |
63 | // DrawBoard |
64 | // (paint the Othello Board, a 8X8 green square table) |
64 | // (paint the Othello Board, a 8X8 green square table) |
65 | // |
65 | // |
66 | // Input: graphic (Graphics) |
66 | // Input: graphic (Graphics) |
67 | // Output: none |
67 | // Output: none |
68 | // Notes: |
68 | // Notes: |
69 | // |
69 | // |
70 | void DrawBoard() { |
70 | void DrawBoard() { |
71 | 71 | ||
72 | int i; |
72 | int i; |
73 | for(i=0;i<=8;i++) |
73 | for(i=0;i<=8;i++) |
74 | { |
74 | { |
75 | __asm__ __volatile__("int $0x40"::"a"(38),"b"(320),"c"(YSHIFT+(YSHIFT+(40*i))*65536+40*i),"d"(0x555555)); |
75 | __asm__ __volatile__("int $0x40"::"a"(38),"b"(320),"c"(YSHIFT+(YSHIFT+(40*i))*65536+40*i),"d"(0x555555)); |
76 | __menuet__line((40*i),YSHIFT,(40*i),353,0x555555); // horizontal |
76 | __menuet__line((40*i),YSHIFT,(40*i),353,0x555555); // horizontal |
77 | 77 | ||
78 | } |
78 | } |
79 | 79 | ||
80 | } |
80 | } |
81 | // End of DrawBoard |
81 | // End of DrawBoard |
82 | 82 | ||
83 | 83 | ||
84 | // |
84 | // |
85 | // DrawPiece |
85 | // DrawPiece |
86 | // (paint a piece, black or white, I'm using an 8x8 array, so |
86 | // (paint a piece, black or white, I'm using an 8x8 array, so |
87 | // from the input values for rows and cols must be |
87 | // from the input values for rows and cols must be |
88 | // subtracted 1) |
88 | // subtracted 1) |
89 | // |
89 | // |
90 | // Input: who (int), |
90 | // Input: who (int), |
91 | // column (int), |
91 | // column (int), |
92 | // row (int) |
92 | // row (int) |
93 | // Output: none |
93 | // Output: none |
94 | // Notes: |
94 | // Notes: |
95 | // |
95 | // |
96 | void DrawPiece(int Who, int Col, int Row) { |
96 | void DrawPiece(int Who, int Col, int Row) { |
97 | int pCol = (40*(Col-1)+1); |
97 | int pCol = (40*(Col-1)+1); |
98 | int pRow = YSHIFT+(40*(Row-1)+1); |
98 | int pRow = YSHIFT+(40*(Row-1)+1); |
99 | u32 pColor,pShadow; |
99 | u32 pColor,pShadow; |
100 | 100 | ||
101 | if (Who == User) { |
101 | if (Who == User) { |
102 | pColor = BLACK; |
102 | pColor = BLACK; |
103 | pShadow = BLACK_S; |
103 | pShadow = BLACK_S; |
104 | } else { |
104 | } else { |
105 | pColor = WHITE; |
105 | pColor = WHITE; |
106 | pShadow = WHITE_S; |
106 | pShadow = WHITE_S; |
107 | } |
107 | } |
108 | TheBoard[Col-1][Row-1] = Who; |
108 | TheBoard[Col-1][Row-1] = Who; |
109 | 109 | ||
110 | __menuet__bar(pCol+9,pRow+9,19,19,pColor); |
110 | __menuet__bar(pCol+9,pRow+9,19,19,pColor); |
111 | } |
111 | } |
112 | // End of DrawPiece |
112 | // End of DrawPiece |
113 | 113 | ||
114 | 114 | ||
115 | // |
115 | // |
116 | // MsgWhoMove |
116 | // MsgWhoMove |
117 | // (paint the message informing who's move) |
117 | // (paint the message informing who's move) |
118 | // |
118 | // |
119 | // Input: is user ? (int) |
119 | // Input: is user ? (int) |
120 | // Output: none |
120 | // Output: none |
121 | // Notes: |
121 | // Notes: |
122 | // |
122 | // |
123 | void MsgWhoMove(int UM) { |
123 | void MsgWhoMove(int UM) { |
124 | } |
124 | } |
125 | // End of MsgWhoMove |
125 | // End of MsgWhoMove |
126 | 126 | ||
127 | 127 | ||
128 | // |
128 | // |
129 | // FlipRow |
129 | // FlipRow |
130 | // (calculate number of pieces are flipped by a move |
130 | // (calculate number of pieces are flipped by a move |
131 | // and return it. Eventually do the complete or pseudo |
131 | // and return it. Eventually do the complete or pseudo |
132 | // move) |
132 | // move) |
133 | // |
133 | // |
134 | // Input: who (int) |
134 | // Input: who (int) |
135 | // which board (int[][]) |
135 | // which board (int[][]) |
136 | // position col, row (int) |
136 | // position col, row (int) |
137 | // direction col, row (int) |
137 | // direction col, row (int) |
138 | // make move ? (int) |
138 | // make move ? (int) |
139 | // |
139 | // |
140 | int FlipRow(int Who, int WhichBoard[8][8] , int C, int R, |
140 | int FlipRow(int Who, int WhichBoard[8][8] , int C, int R, |
141 | int CInc, int RInc, int MakeMove) { |
141 | int CInc, int RInc, int MakeMove) { |
142 | int NewCol; |
142 | int NewCol; |
143 | int NewRow; |
143 | int NewRow; |
144 | int Opponent = User + Computer - Who; |
144 | int Opponent = User + Computer - Who; |
145 | int CNT = 0; |
145 | int CNT = 0; |
146 | 146 | ||
147 | NewCol = C - 1; |
147 | NewCol = C - 1; |
148 | NewRow = R - 1; |
148 | NewRow = R - 1; |
149 | while (true) { |
149 | while (true) { |
150 | if (((NewCol+CInc) < 0) || ((NewCol+CInc) > 7) || |
150 | if (((NewCol+CInc) < 0) || ((NewCol+CInc) > 7) || |
151 | ((NewRow+RInc) < 0) || ((NewRow+RInc) > 7)) { |
151 | ((NewRow+RInc) < 0) || ((NewRow+RInc) > 7)) { |
152 | return 0; |
152 | return 0; |
153 | } |
153 | } |
154 | if (WhichBoard[NewCol+CInc][NewRow+RInc] == Opponent) { |
154 | if (WhichBoard[NewCol+CInc][NewRow+RInc] == Opponent) { |
155 | CNT++; |
155 | CNT++; |
156 | NewCol += CInc; |
156 | NewCol += CInc; |
157 | NewRow += RInc; |
157 | NewRow += RInc; |
158 | } else if (WhichBoard[NewCol+CInc][NewRow+RInc] == Empty) { |
158 | } else if (WhichBoard[NewCol+CInc][NewRow+RInc] == Empty) { |
159 | return 0; |
159 | return 0; |
160 | } else { |
160 | } else { |
161 | break; |
161 | break; |
162 | } |
162 | } |
163 | } |
163 | } |
164 | if (MakeMove != NOMOVE) { |
164 | if (MakeMove != NOMOVE) { |
165 | C--; |
165 | C--; |
166 | R--; |
166 | R--; |
167 | int v; |
167 | int v; |
168 | for(v=0; v<=CNT; v++) { |
168 | for(v=0; v<=CNT; v++) { |
169 | if (MakeMove == REALMOVE) { |
169 | if (MakeMove == REALMOVE) { |
170 | DrawPiece(Who, C+1, R+1); |
170 | DrawPiece(Who, C+1, R+1); |
171 | } else { |
171 | } else { |
172 | WhichBoard[C][R] = Who; |
172 | WhichBoard[C][R] = Who; |
173 | } |
173 | } |
174 | C += CInc; |
174 | C += CInc; |
175 | R += RInc; |
175 | R += RInc; |
176 | } |
176 | } |
177 | } |
177 | } |
178 | return CNT; |
178 | return CNT; |
179 | } |
179 | } |
180 | // End of FlipRow |
180 | // End of FlipRow |
181 | 181 | ||
182 | 182 | ||
183 | // |
183 | // |
184 | // IsLegalMove |
184 | // IsLegalMove |
185 | // (verify that the move is legal) |
185 | // (verify that the move is legal) |
186 | // |
186 | // |
187 | // Input: who (int) |
187 | // Input: who (int) |
188 | // board (int[][]) |
188 | // board (int[][]) |
189 | // position col, row (int) |
189 | // position col, row (int) |
190 | // Output: is legal ? (int) |
190 | // Output: is legal ? (int) |
191 | // Notes: |
191 | // Notes: |
192 | // |
192 | // |
193 | int IsLegalMove(int Who, int WhichBoard[8][8] , int C, int R) { |
193 | int IsLegalMove(int Who, int WhichBoard[8][8] , int C, int R) { |
194 | if (WhichBoard[C-1][R-1] != Empty) { |
194 | if (WhichBoard[C-1][R-1] != Empty) { |
195 | return false; |
195 | return false; |
196 | } |
196 | } |
197 | int CInc,RInc; |
197 | int CInc,RInc; |
198 | for (CInc=-1; CInc<2; CInc++) { |
198 | for (CInc=-1; CInc<2; CInc++) { |
199 | for (RInc=-1; RInc<2; RInc++) { |
199 | for (RInc=-1; RInc<2; RInc++) { |
200 | if (FlipRow(Who, WhichBoard, C, R, CInc, RInc, NOMOVE) > 0) { |
200 | if (FlipRow(Who, WhichBoard, C, R, CInc, RInc, NOMOVE) > 0) { |
201 | return true; |
201 | return true; |
202 | } |
202 | } |
203 | } |
203 | } |
204 | } |
204 | } |
205 | return false; |
205 | return false; |
206 | } |
206 | } |
207 | // End of IsLegalMove |
207 | // End of IsLegalMove |
208 | 208 | ||
209 | 209 | ||
210 | // |
210 | // |
211 | // MakeMove |
211 | // MakeMove |
212 | // (make the move) |
212 | // (make the move) |
213 | // |
213 | // |
214 | // Input: who (int) |
214 | // Input: who (int) |
215 | // position col, row (int) |
215 | // position col, row (int) |
216 | // Output: false=EndGame, true=next player (int) |
216 | // Output: false=EndGame, true=next player (int) |
217 | // Notes: |
217 | // Notes: |
218 | // |
218 | // |
219 | int MakeMove(int Who, int C, int R) { |
219 | int MakeMove(int Who, int C, int R) { |
220 | int CInc,RInc; |
220 | int CInc,RInc; |
221 | for (CInc=-1; CInc<2; CInc++) { |
221 | for (CInc=-1; CInc<2; CInc++) { |
222 | for (RInc=-1; RInc<2; RInc++) { |
222 | for (RInc=-1; RInc<2; RInc++) { |
223 | FlipRow(Who, TheBoard, C, R, CInc, RInc, REALMOVE); |
223 | FlipRow(Who, TheBoard, C, R, CInc, RInc, REALMOVE); |
224 | } |
224 | } |
225 | } |
225 | } |
226 | if (IsBoardComplete() || |
226 | if (IsBoardComplete() || |
227 | ((!ThereAreMoves(Computer, TheBoard)) && (!ThereAreMoves(User, TheBoard)))) { |
227 | ((!ThereAreMoves(Computer, TheBoard)) && (!ThereAreMoves(User, TheBoard)))) { |
228 | return false; |
228 | return false; |
229 | } |
229 | } |
230 | int Opponent = (User + Computer) - Who; |
230 | int Opponent = (User + Computer) - Who; |
231 | if (ThereAreMoves(Opponent, TheBoard)) { |
231 | if (ThereAreMoves(Opponent, TheBoard)) { |
232 | UserMove = !UserMove; |
232 | UserMove = !UserMove; |
233 | } |
233 | } |
234 | return true; |
234 | return true; |
235 | } |
235 | } |
236 | // End of MakeMove |
236 | // End of MakeMove |
237 | 237 | ||
238 | 238 | ||
239 | // |
239 | // |
240 | // EndGame |
240 | // EndGame |
241 | // (shows the winning message) |
241 | // (shows the winning message) |
242 | // |
242 | // |
243 | // Input: none |
243 | // Input: none |
244 | // Output: none |
244 | // Output: none |
245 | // Notes: |
245 | // Notes: |
246 | // |
246 | // |
247 | void EndGame() { |
247 | void EndGame() { |
248 | int CompPieces = 0; |
248 | int CompPieces = 0; |
249 | int UserPieces = 0; |
249 | int UserPieces = 0; |
250 | char *WinMsg_W = "Computer Won"; |
250 | char *WinMsg_W = "Computer Won"; |
251 | char *WinMsg_L = "User Won"; |
251 | char *WinMsg_L = "User Won"; |
252 | char *WinMsg_T = "???"; |
252 | char *WinMsg_T = "???"; |
253 | char *TheMsg; |
253 | char *TheMsg; |
254 | 254 | ||
255 | int StrWidth; |
255 | int StrWidth; |
256 | 256 | ||
257 | int c,r; |
257 | int c,r; |
258 | for (c=0; c<8; c++) { |
258 | for (c=0; c<8; c++) { |
259 | for (r=0; r<8; r++) { |
259 | for (r=0; r<8; r++) { |
260 | if (TheBoard[c][r] == Computer) { |
260 | if (TheBoard[c][r] == Computer) { |
261 | CompPieces++; |
261 | CompPieces++; |
262 | } else { |
262 | } else { |
263 | UserPieces++; |
263 | UserPieces++; |
264 | } |
264 | } |
265 | } |
265 | } |
266 | } |
266 | } |
267 | if (CompPieces > UserPieces) { |
267 | if (CompPieces > UserPieces) { |
268 | TheMsg = WinMsg_W; |
268 | TheMsg = WinMsg_W; |
269 | } else if (UserPieces > CompPieces) { |
269 | } else if (UserPieces > CompPieces) { |
270 | TheMsg = WinMsg_L; |
270 | TheMsg = WinMsg_L; |
271 | } else { |
271 | } else { |
272 | TheMsg = WinMsg_T; |
272 | TheMsg = WinMsg_T; |
273 | } |
273 | } |
274 | 274 | ||
275 | __menuet__write_text(100,8,0xff0000,TheMsg,strlen(TheMsg)); |
275 | __menuet__write_text(100,8,0xff0000,TheMsg,strlen(TheMsg)); |
276 | 276 | ||
277 | } |
277 | } |
278 | // End of EndGame |
278 | // End of EndGame |
279 | 279 | ||
280 | 280 | ||
281 | // |
281 | // |
282 | // IsBoardComplete |
282 | // IsBoardComplete |
283 | // (checks if the board is complete) |
283 | // (checks if the board is complete) |
284 | // |
284 | // |
285 | // Input: none |
285 | // Input: none |
286 | // Output: the board is complete ? (int) |
286 | // Output: the board is complete ? (int) |
287 | // Notes: |
287 | // Notes: |
288 | // |
288 | // |
289 | int IsBoardComplete() { |
289 | int IsBoardComplete() { |
290 | int i,j; |
290 | int i,j; |
291 | for (i=0; i<8; i++) { |
291 | for (i=0; i<8; i++) { |
292 | for (j=0; j<8; j++) { |
292 | for (j=0; j<8; j++) { |
293 | if (TheBoard[i][j] == Empty) { |
293 | if (TheBoard[i][j] == Empty) { |
294 | return false; |
294 | return false; |
295 | } |
295 | } |
296 | } |
296 | } |
297 | } |
297 | } |
298 | return true; |
298 | return true; |
299 | } |
299 | } |
300 | // End of IsBoardComplete |
300 | // End of IsBoardComplete |
301 | 301 | ||
302 | 302 | ||
303 | // |
303 | // |
304 | // ThereAreMoves |
304 | // ThereAreMoves |
305 | // (checks if there are more valid moves for the |
305 | // (checks if there are more valid moves for the |
306 | // player) |
306 | // player) |
307 | // |
307 | // |
308 | // Input: player (int) |
308 | // Input: player (int) |
309 | // board (int[][]) |
309 | // board (int[][]) |
310 | // Output: there are moves ? (int) |
310 | // Output: there are moves ? (int) |
311 | // Notes: |
311 | // Notes: |
312 | // |
312 | // |
313 | int ThereAreMoves(int Who, int WhichBoard[8][8] ) { |
313 | int ThereAreMoves(int Who, int WhichBoard[8][8] ) { |
314 | int i,j; |
314 | int i,j; |
315 | for (i=1; i<=8; i++) { |
315 | for (i=1; i<=8; i++) { |
316 | for (j=1; j<=8; j++) { |
316 | for (j=1; j<=8; j++) { |
317 | if (IsLegalMove(Who, WhichBoard, i, j)) { |
317 | if (IsLegalMove(Who, WhichBoard, i, j)) { |
318 | return true; |
318 | return true; |
319 | } |
319 | } |
320 | } |
320 | } |
321 | } |
321 | } |
322 | return false; |
322 | return false; |
323 | } |
323 | } |
324 | // End of ThereAreMoves |
324 | // End of ThereAreMoves |
325 | 325 | ||
326 | 326 | ||
327 | // |
327 | // |
328 | // CalcOpponentScore |
328 | // CalcOpponentScore |
329 | // (calculate the totalScore of opponent after |
329 | // (calculate the totalScore of opponent after |
330 | // a move) |
330 | // a move) |
331 | // |
331 | // |
332 | // Input: position x, y (int) |
332 | // Input: position x, y (int) |
333 | // Output: score (int) |
333 | // Output: score (int) |
334 | // Notes: |
334 | // Notes: |
335 | // |
335 | // |
336 | int CalcOpponentScore(int CP, int RP) { |
336 | int CalcOpponentScore(int CP, int RP) { |
337 | int OpScore = 0; |
337 | int OpScore = 0; |
338 | int tempBoard[8][8]; // = new int[8][8]; |
338 | int tempBoard[8][8]; // = new int[8][8]; |
339 | int c,r; |
339 | int c,r; |
340 | for (c=0; c<8; c++) { |
340 | for (c=0; c<8; c++) { |
341 | for (r=0; r<8; r++) { |
341 | for (r=0; r<8; r++) { |
342 | tempBoard[c][r] = TheBoard[c][r]; |
342 | tempBoard[c][r] = TheBoard[c][r]; |
343 | } |
343 | } |
344 | } |
344 | } |
345 | int CInc,RInc; |
345 | int CInc,RInc; |
346 | for (CInc=-1; CInc<2; CInc++) { |
346 | for (CInc=-1; CInc<2; CInc++) { |
347 | for (RInc=-1; RInc<2; RInc++) { |
347 | for (RInc=-1; RInc<2; RInc++) { |
348 | FlipRow(Computer, tempBoard, CP+1, RP+1, CInc, RInc, PSEUDOMOVE); |
348 | FlipRow(Computer, tempBoard, CP+1, RP+1, CInc, RInc, PSEUDOMOVE); |
349 | } |
349 | } |
350 | } |
350 | } |
351 | if (ThereAreMoves(User, tempBoard)) { |
351 | if (ThereAreMoves(User, tempBoard)) { |
352 | int C,R; |
352 | int C,R; |
353 | for (C=0; C<8; C++) { |
353 | for (C=0; C<8; C++) { |
354 | for (R=0; R<8; R++) { |
354 | for (R=0; R<8; R++) { |
355 | OpScore += RankMove(User, tempBoard, C, R); |
355 | OpScore += RankMove(User, tempBoard, C, R); |
356 | } |
356 | } |
357 | } |
357 | } |
358 | } |
358 | } |
359 | return OpScore; |
359 | return OpScore; |
360 | } |
360 | } |
361 | // End of CalcOpponentScore() |
361 | // End of CalcOpponentScore() |
362 | 362 | ||
363 | 363 | ||
364 | // |
364 | // |
365 | // RankMoves |
365 | // RankMoves |
366 | // (rank all moves for the computer) |
366 | // (rank all moves for the computer) |
367 | // |
367 | // |
368 | // Input: none |
368 | // Input: none |
369 | // Output: none |
369 | // Output: none |
370 | // Notes: |
370 | // Notes: |
371 | // |
371 | // |
372 | void RankMoves() { |
372 | void RankMoves() { |
373 | int C,R; |
373 | int C,R; |
374 | for (C=0; C<8; C++) { |
374 | for (C=0; C<8; C++) { |
375 | for (R=0; R<8; R++) { |
375 | for (R=0; R<8; R++) { |
376 | Score[C][R] = RankMove(Computer, TheBoard, C, R); |
376 | Score[C][R] = RankMove(Computer, TheBoard, C, R); |
377 | if (Score[C][R] != 0) { |
377 | if (Score[C][R] != 0) { |
378 | OpponentScore[C][R] = CalcOpponentScore(C, R); |
378 | OpponentScore[C][R] = CalcOpponentScore(C, R); |
379 | } else { |
379 | } else { |
380 | OpponentScore[C][R] = 0; |
380 | OpponentScore[C][R] = 0; |
381 | } |
381 | } |
382 | } |
382 | } |
383 | } |
383 | } |
384 | } |
384 | } |
385 | // End of RankMoves |
385 | // End of RankMoves |
386 | 386 | ||
387 | 387 | ||
388 | // |
388 | // |
389 | // RankMove |
389 | // RankMove |
390 | // (rank a move for a player on a board) |
390 | // (rank a move for a player on a board) |
391 | // |
391 | // |
392 | // Input: who moves (int) |
392 | // Input: who moves (int) |
393 | // on which board (int[][]) |
393 | // on which board (int[][]) |
394 | // position col, row (int) |
394 | // position col, row (int) |
395 | // Output: flipped pieces (int) |
395 | // Output: flipped pieces (int) |
396 | // Notes: best are corner, then border lines, |
396 | // Notes: best are corner, then border lines, |
397 | // worst are line near to border lines |
397 | // worst are line near to border lines |
398 | // |
398 | // |
399 | int RankMove(int Who, int WhichBoard[8][8], int Col, int Row) { |
399 | int RankMove(int Who, int WhichBoard[8][8], int Col, int Row) { |
400 | int CNT = 0; |
400 | int CNT = 0; |
401 | int MV = 0; |
401 | int MV = 0; |
402 | 402 | ||
403 | if (WhichBoard[Col][Row] != Empty) { |
403 | if (WhichBoard[Col][Row] != Empty) { |
404 | return 0; |
404 | return 0; |
405 | } |
405 | } |
406 | int CInc,RInc; |
406 | int CInc,RInc; |
407 | for (CInc=-1; CInc<2; CInc++) { |
407 | for (CInc=-1; CInc<2; CInc++) { |
408 | for (RInc=-1; RInc<2; RInc++) { |
408 | for (RInc=-1; RInc<2; RInc++) { |
409 | MV = FlipRow(Who, WhichBoard, Col+1, Row+1, CInc, RInc, NOMOVE); |
409 | MV = FlipRow(Who, WhichBoard, Col+1, Row+1, CInc, RInc, NOMOVE); |
410 | CNT += MV; |
410 | CNT += MV; |
411 | } |
411 | } |
412 | } |
412 | } |
413 | if (CNT > 0) { |
413 | if (CNT > 0) { |
414 | if (((Col == 0) || (Col == 7)) || |
414 | if (((Col == 0) || (Col == 7)) || |
415 | ((Row == 0) || (Row == 7))) { |
415 | ((Row == 0) || (Row == 7))) { |
416 | CNT = 63; |
416 | CNT = 63; |
417 | } |
417 | } |
418 | if (((Col == 0) || (Col == 7)) && |
418 | if (((Col == 0) || (Col == 7)) && |
419 | ((Row == 0) || (Row == 7))) { |
419 | ((Row == 0) || (Row == 7))) { |
420 | CNT = 64; |
420 | CNT = 64; |
421 | } |
421 | } |
422 | if ((((Col == 0) || (Col == 7)) && (Row == 1) || (Row == 6)) && |
422 | if ((((Col == 0) || (Col == 7)) && (Row == 1) || (Row == 6)) && |
423 | (((Col == 1) || (Col == 6)) && (Row == 0) || (Row == 7)) && |
423 | (((Col == 1) || (Col == 6)) && (Row == 0) || (Row == 7)) && |
424 | (((Col == 1) || (Col == 6)) && (Row == 1) || (Row == 6))) { |
424 | (((Col == 1) || (Col == 6)) && (Row == 1) || (Row == 6))) { |
425 | CNT = 1; |
425 | CNT = 1; |
426 | } |
426 | } |
427 | } |
427 | } |
428 | return CNT; |
428 | return CNT; |
429 | } |
429 | } |
430 | // End of RankMove |
430 | // End of RankMove |
431 | 431 | ||
432 | 432 | ||
433 | // |
433 | // |
434 | // BestMove |
434 | // BestMove |
435 | // (calculate and execute the best move) |
435 | // (calculate and execute the best move) |
436 | // |
436 | // |
437 | // Input: none |
437 | // Input: none |
438 | // Output: value, col & row (int[3]) |
438 | // Output: value, col & row (int[3]) |
439 | // Notes: |
439 | // Notes: |
440 | // |
440 | // |
441 | void BestMove (int retval[3]) { |
441 | void BestMove (int retval[3]) { |
442 | 442 | ||
443 | retval[0] = -998; // move value; |
443 | retval[0] = -998; // move value; |
444 | retval[1] = 0; // column |
444 | retval[1] = 0; // column |
445 | retval[2] = 0; // row |
445 | retval[2] = 0; // row |
446 | 446 | ||
447 | RankMoves(); |
447 | RankMoves(); |
448 | int C,R; |
448 | int C,R; |
449 | for (C=0; C<8; C++) { |
449 | for (C=0; C<8; C++) { |
450 | for (R=0; R<8; R++) { |
450 | for (R=0; R<8; R++) { |
451 | if ((Score[C][R] == 0) && (OpponentScore[C][R] == 0)) { |
451 | if ((Score[C][R] == 0) && (OpponentScore[C][R] == 0)) { |
452 | Score[C][R] = -999; |
452 | Score[C][R] = -999; |
453 | } else if (Score[C][R] != 64) { |
453 | } else if (Score[C][R] != 64) { |
454 | Score[C][R] = Score[C][R] - OpponentScore[C][R]; |
454 | Score[C][R] = Score[C][R] - OpponentScore[C][R]; |
455 | } |
455 | } |
456 | } |
456 | } |
457 | } |
457 | } |
458 | for (C=0; C<8; C++) { |
458 | for (C=0; C<8; C++) { |
459 | for (R=0; R<8; R++) { |
459 | for (R=0; R<8; R++) { |
460 | if (Score[C][R] > retval[0]) { |
460 | if (Score[C][R] > retval[0]) { |
461 | retval[1] = C; |
461 | retval[1] = C; |
462 | retval[2] = R; |
462 | retval[2] = R; |
463 | retval[0] = Score[C][R]; |
463 | retval[0] = Score[C][R]; |
464 | } |
464 | } |
465 | } |
465 | } |
466 | } |
466 | } |
467 | retval[1]++; |
467 | retval[1]++; |
468 | retval[2]++; |
468 | retval[2]++; |
469 | // return retval; |
469 | // return retval; |
470 | } |
470 | } |
471 | // End of BestMove |
471 | // End of BestMove |
472 | 472 | ||
473 | 473 | ||
474 | 474 | ||
475 | 475 | ||
476 | // |
476 | // |
477 | // paint |
477 | // paint |
478 | // |
478 | // |
479 | void paint() { |
479 | void paint() { |
480 | // MsgWhoMove(UserMove); |
480 | // MsgWhoMove(UserMove); |
481 | if (!CopyWinOn) { |
481 | if (!CopyWinOn) { |
482 | int i,j; |
482 | int i,j; |
483 | for (i=0; i<8; i++) { |
483 | for (i=0; i<8; i++) { |
484 | for (j=0; j<8; j++) { |
484 | for (j=0; j<8; j++) { |
485 | if (TheBoard[i][j] != Empty) { |
485 | if (TheBoard[i][j] != Empty) { |
486 | DrawPiece(TheBoard[i][j], i+1, j+1); |
486 | DrawPiece(TheBoard[i][j], i+1, j+1); |
487 | } |
487 | } |
488 | } |
488 | } |
489 | } |
489 | } |
490 | // } else { |
490 | // } else { |
491 | // ShowAbout(); |
491 | // ShowAbout(); |
492 | } |
492 | } |
493 | 493 | ||
494 | int _user = 0; |
494 | int _user = 0; |
495 | int _computer = 0; |
495 | int _computer = 0; |
496 | int c, r; |
496 | int c, r; |
497 | 497 | ||
498 | for (c=0; c<8; c++) |
498 | for (c=0; c<8; c++) |
499 | for (r=0; r<8; r++) { |
499 | for (r=0; r<8; r++) { |
500 | if (TheBoard[c][r] == User) |
500 | if (TheBoard[c][r] == User) |
501 | _user++; |
501 | _user++; |
502 | if (TheBoard[c][r] == Computer) |
502 | if (TheBoard[c][r] == Computer) |
503 | _computer++; |
503 | _computer++; |
504 | } |
504 | } |
505 | 505 | ||
506 | // do not use sprintf function here please! ( sprintf(score, "User: %d - Computer: %d", _user, _computer); ) |
506 | // do not use sprintf function here please! ( sprintf(score, "User: %d - Computer: %d", _user, _computer); ) |
507 | char score[64]; |
507 | char score[64]; |
508 | char tmp[8]; |
508 | char tmp[8]; |
509 | strcpy(score, "User (black): "); |
509 | strcpy(score, "User (black): "); |
510 | itoa(_user++, tmp, 10); |
510 | itoa(_user++, tmp, 10); |
511 | strcat(score, tmp); |
511 | strcat(score, tmp); |
512 | strcat(score, " - Computer (white): "); |
512 | strcat(score, " - Computer (white): "); |
513 | itoa(_computer++, tmp, 10); |
513 | itoa(_computer++, tmp, 10); |
514 | strcat(score, tmp); |
514 | strcat(score, tmp); |
515 | 515 | ||
516 | __menuet__bar(58, 8, 250, 16, 0x777777); |
516 | __menuet__bar(58, 8, 250, 16, 0x777777); |
517 | __menuet__write_text(58,8,0x333333,score, strlen(score)); |
517 | __menuet__write_text(58,8,0x333333,score, strlen(score)); |
518 | 518 | ||
519 | 519 | ||
520 | } |
520 | } |
521 | // End of paint |
521 | // End of paint |
522 | 522 | ||
523 | 523 | ||
524 | // |
524 | // |
525 | // init |
525 | // init |
526 | // |
526 | // |
527 | void init() { |
527 | void init() { |
528 | // This is the right size of the applet 321x387 |
528 | // This is the right size of the applet 321x387 |
529 | // resize(321,387); |
529 | // resize(321,387); |
530 | // I set twice the language. That's because if anybody |
530 | // I set twice the language. That's because if anybody |
531 | // forget a string in an external language file, are |
531 | // forget a string in an external language file, are |
532 | // used english strings. |
532 | // used english strings. |
533 | if (!StillInitiated) { |
533 | if (!StillInitiated) { |
534 | StillInitiated = true; |
534 | StillInitiated = true; |
535 | } |
535 | } |
536 | int i,j; |
536 | int i,j; |
537 | for (i=0; i<8; i++) { |
537 | for (i=0; i<8; i++) { |
538 | for (j=0; j<8; j++) { |
538 | for (j=0; j<8; j++) { |
539 | TheBoard[i][j] = 0; |
539 | TheBoard[i][j] = 0; |
540 | } |
540 | } |
541 | } |
541 | } |
542 | TheBoard[3][3] = User; |
542 | TheBoard[3][3] = User; |
543 | TheBoard[3][4] = Computer; |
543 | TheBoard[3][4] = Computer; |
544 | TheBoard[4][3] = Computer; |
544 | TheBoard[4][3] = Computer; |
545 | TheBoard[4][4] = User; |
545 | TheBoard[4][4] = User; |
546 | UserMove = true; |
546 | UserMove = true; |
547 | // MsgWhoMove(true); |
547 | // MsgWhoMove(true); |
548 | // repaint(); |
548 | // repaint(); |
549 | } |
549 | } |
550 | // End of init |
550 | // End of init |
551 | 551 | ||
552 | 552 | ||
553 | 553 | ||
554 | 554 | ||
555 | 555 | ||
556 | void paint_win(void) |
556 | void paint_win(void) |
557 | { |
557 | { |
558 | __menuet__window_redraw(1); |
558 | __menuet__window_redraw(1); |
559 | __menuet__define_window(100,100,330,400,0x33777777,0,"Reversi"); |
559 | __menuet__define_window(100,100,330,400,0x33777777,0,"Reversi"); |
560 | __menuet__make_button(4,4,40,20,3,0xe0e0e0); |
560 | __menuet__make_button(4,4,40,20,3,0xe0e0e0); |
561 | __menuet__write_text(8,8,0x333333,"New",3); |
561 | __menuet__write_text(8,8,0x333333,"New",3); |
562 | __menuet__window_redraw(2); |
562 | __menuet__window_redraw(2); |
563 | } |
563 | } |
564 | 564 | ||
565 | void main(void) |
565 | void main(void) |
566 | { |
566 | { |
567 | int i; |
567 | int i; |
568 | u32 mouse_coord; |
568 | u32 mouse_coord; |
569 | u32 mouse_butn; |
569 | u32 mouse_butn; |
570 | int X,Y; |
570 | int X,Y; |
571 | 571 | ||
572 | int TheCol, TheRow; |
572 | int TheCol, TheRow; |
573 | int BMove[3]; |
573 | int BMove[3]; |
574 | int BX, BY; |
574 | int BX, BY; |
575 | int retval = false; |
575 | int retval = false; |
576 | 576 | ||
577 | 577 | ||
578 | __menuet__set_bitfield_for_wanted_events(EVENT_REDRAW + EVENT_KEY + EVENT_BUTTON + EVENT_MOUSE_CHANGE); |
578 | __menuet__set_bitfield_for_wanted_events(EVENT_REDRAW + EVENT_KEY + EVENT_BUTTON + EVENT_MOUSE_CHANGE); |
579 | paint_win(); |
579 | paint_win(); |
580 | DrawBoard(); |
580 | DrawBoard(); |
581 | init(); |
581 | init(); |
582 | paint(); |
582 | paint(); |
583 | 583 | ||
584 | for(;;) |
584 | for(;;) |
585 | { |
585 | { |
586 | i=__menuet__wait_for_event(); |
586 | i=__menuet__wait_for_event(); |
587 | switch(i) |
587 | switch(i) |
588 | { |
588 | { |
589 | case 1: |
589 | case 1: |
590 | paint_win(); |
590 | paint_win(); |
591 | DrawBoard(); |
591 | DrawBoard(); |
592 | paint(); |
592 | paint(); |
593 | continue; |
593 | continue; |
594 | case 2: |
594 | case 2: |
595 | __menuet__getkey(); |
595 | __menuet__getkey(); |
596 | continue; |
596 | continue; |
597 | case 3: |
597 | case 3: |
598 | if(__menuet__get_button_id()==1) { |
598 | if(__menuet__get_button_id()==1) { |
599 | __menuet__sys_exit();} |
599 | __menuet__sys_exit();} |
600 | else |
600 | else |
601 | paint_win(); |
601 | paint_win(); |
602 | init(); |
602 | init(); |
603 | DrawBoard(); |
603 | DrawBoard(); |
604 | paint(); |
604 | paint(); |
605 | continue; |
605 | continue; |
606 | case 4: |
606 | case 4: |
607 | continue; |
607 | continue; |
608 | case 5: |
608 | case 5: |
609 | continue; |
609 | continue; |
610 | case 6: |
610 | case 6: |
611 | __asm__ __volatile__("int $0x40":"=a"(mouse_butn):"0"(37),"b"(2)); |
611 | __asm__ __volatile__("int $0x40":"=a"(mouse_butn):"0"(37),"b"(2)); |
612 | __asm__ __volatile__("int $0x40":"=a"(mouse_coord):"0"(37),"b"(1)); |
612 | __asm__ __volatile__("int $0x40":"=a"(mouse_coord):"0"(37),"b"(1)); |
613 | X = mouse_coord >> 16; |
613 | X = mouse_coord >> 16; |
614 | Y = mouse_coord & 0xffff; |
614 | Y = mouse_coord & 0xffff; |
615 | 615 | ||
616 | // Process a normal click in the board |
616 | // Process a normal click in the board |
617 | BX = X; |
617 | BX = X; |
618 | BY = Y - YSHIFT; |
618 | BY = Y - YSHIFT; |
619 | 619 | ||
620 | 620 | ||
621 | if ((BY >= 0) && (BY <= 321) && |
621 | if ((BY >= 0) && (BY <= 321) && |
622 | (mouse_butn !=0) && (UserMove)) { |
622 | (mouse_butn !=0) && (UserMove)) { |
623 | TheCol = (int)((BX/40)+1); |
623 | TheCol = (int)((BX/40)+1); |
624 | TheRow = (int)((BY/40)+1); |
624 | TheRow = (int)((BY/40)+1); |
625 | 625 | ||
626 | if (IsLegalMove(User, TheBoard, TheCol, TheRow)) { |
626 | if (IsLegalMove(User, TheBoard, TheCol, TheRow)) { |
627 | retval = MakeMove(User, TheCol, TheRow); |
627 | retval = MakeMove(User, TheCol, TheRow); |
628 | while (retval && (!UserMove)) { |
628 | while (retval && (!UserMove)) { |
629 | //MsgWhoMove(UserMove); |
629 | //MsgWhoMove(UserMove); |
630 | BestMove(BMove); |
630 | BestMove(BMove); |
631 | 631 | ||
632 | retval = MakeMove(Computer, BMove[1], BMove[2]); |
632 | retval = MakeMove(Computer, BMove[1], BMove[2]); |
633 | //MsgWhoMove(UserMove); |
633 | //MsgWhoMove(UserMove); |
634 | } |
634 | } |
635 | if (!retval) { |
635 | if (!retval) { |
636 | EndGame(); |
636 | EndGame(); |
637 | } |
637 | } |
638 | } |
638 | } |
639 | paint(); |
639 | paint(); |
640 | } |
640 | } |
641 | continue; |
641 | continue; |
642 | 642 | ||
643 | 643 | ||
644 | } |
644 | } |
645 | } |
645 | } |
646 | }=>8;>8;>8;>8;>8;>8;>8;>8;>8;>8;>2;>2;>8;>8;>8;>8;>2;>2;>8;>8;>=8;>=8;>8;>8;>8;>8;>2;>2;>2;>2;>=CNT;>>>=8;i++)> |
646 | } |
- | 647 | ||
- | 648 | /* We use LIBC only for strcpy/itoa, so we don't need CRT startup code */ |
|
- | 649 | int __bss_count; |
|
- | 650 | void __crt1_startup() { main(); }=>8;>8;>8;>8;>8;>8;>8;>8;>8;>8;>2;>2;>8;>8;>8;>8;>2;>2;>8;>8;>=8;>=8;>8;>8;>8;>8;>2;>2;>2;>2;>=CNT;>>>=8;i++)> |