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