summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2004-06-08 11:14:37 +0000
committerBjörn Stenberg <bjorn@haxx.se>2004-06-08 11:14:37 +0000
commit00f67d61ce7ca02188ea8934f4accd53f51235c3 (patch)
tree48d225a48aaddaf5b65b971bcf42b8c8fa0d3f86 /apps
parent3405d1302073ab7fa1ae7913d9e27c64133b7d78 (diff)
downloadrockbox-00f67d61ce7ca02188ea8934f4accd53f51235c3.tar.gz
rockbox-00f67d61ce7ca02188ea8934f4accd53f51235c3.zip
Othelo removed due to legal issues.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4722 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/othelo.c1545
-rw-r--r--apps/plugins/othelo.txt122
2 files changed, 0 insertions, 1667 deletions
diff --git a/apps/plugins/othelo.c b/apps/plugins/othelo.c
deleted file mode 100644
index 7f0502794b..0000000000
--- a/apps/plugins/othelo.c
+++ /dev/null
@@ -1,1545 +0,0 @@
1/*
2 Designed, Written, AI Bots, the lot ...BlueChip =8ªD#
3
4 Thanks espcially to
5 DevZer0, LinusN, Zagor, scott666
6 for their help with understanding Rockbox & the SDK
7
8 Please note that the code formatting is not that which was
9 produced originally, but has been updated by whoever
10 ported it to the plugin system.
11 I am sure it was done with good reason, so I have not
12 redone it!
13*/
14
15/*
16 * Version Date Who Comment
17 * -------- -------- ---- ------------------------------------------------
18 * 1.4 20030729 BC Ensure game terminates even if dreamer disabled
19 * 1.3 20030729 BC Fixed display bug introduced by port to plugin
20 * Updated documentation
21 * 1.2 2003 Ported to new plugin system
22 * 1.1 20030625 BC Flash board when invalid move to used aquare
23 * Fixed "pause computer" for real harware!
24 * Added USB_CONNECTED support
25 * Ensure correct fonts on the way in and out
26 * 1.0 20030622 BC Release
27 *
28 *
29 * Todo:
30 * # More AI :)
31 * # Reintroduce suspend feature under plugin system
32 */
33
34/* Plugin header */
35#include "plugin.h"
36
37#ifdef HAVE_LCD_BITMAP
38
39static struct plugin_api* rb;
40
41/***************************************************************************/
42/***************************************************************************/
43/* OTHFONT.H */
44/***************************************************************************/
45/***************************************************************************/
46
47/* Don't reorder this array - you have been warned! */
48enum othfontc {
49 of_plx,
50 of_plo,
51 of_poss,
52 of_choice,
53 of_sp,
54 of_h,
55 of_c,
56 of_0,
57 of_1,
58 of_2,
59 of_3,
60 of_4,
61 of_5,
62 of_6,
63 of_7,
64 of_8,
65 of_9,
66 of_colon,
67 of_dash,
68 of_ptr,
69 of_p,
70 of_l,
71 of_a,
72 of_y,
73 of_q,
74 of_u,
75 of_i,
76 of_t,
77 of_eos
78};
79
80static unsigned char othfont[of_eos][6] = {
81 /* +------+
82 * | ## |
83 * | #### |
84 * |######|
85 * |######|
86 * | #### |
87 * | ## |
88 * +------+
89 */
90 {0x0C, 0x1E, 0x3F, 0x3F, 0x1E, 0x0C},
91 /* +------+
92 * | ## |
93 * | #### |
94 * |## ##|
95 * |## ##|
96 * | #### |
97 * | ## |
98 * +------+
99 */
100 {0x0C, 0x1E, 0x33, 0x33, 0x1E, 0x0C},
101 /* +------+
102 * | |
103 * | |
104 * | ## |
105 * | ## |
106 * | |
107 * | |
108 * +------+
109 */
110 {0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00},
111 /* +------+
112 * | |
113 * | # # |
114 * | ## |
115 * | ## |
116 * | # # |
117 * | |
118 * +------+
119 */
120 {0x00, 0x12, 0x0C, 0x0C, 0x12, 0x00},
121 /* +------+
122 * | |
123 * | |
124 * | |
125 * | |
126 * | |
127 * | |
128 * +------+
129 */
130 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
131 /* +------+
132 * | # # | 0001 0010 12
133 * | # # | 0001 0010 12
134 * | #### | 0001 1110 1E
135 * | # # | 0001 0010 12
136 * | # # | 0001 0010 12
137 * | # # | 0001 0010 12
138 * +------+
139 */
140 {0x12,0x12,0x1E,0x12,0x12,0x12},
141 /* +------+
142 * | ## | 0000 1100 0C
143 * | # # | 0001 0010 12
144 * |# | 0010 0000 20
145 * |# | 0010 0000 20
146 * | # # | 0001 0010 12
147 * | ## | 0000 1100 0C
148 * +------+
149 */
150 {0x0C,0x12,0x20,0x20,0x12,0x0C},
151 /* +------+
152 * | ## | 0000 1100 0C
153 * | # # | 0001 0010 12
154 * | # ## | 0001 0110 16
155 * | ## # | 0001 1010 1A
156 * | # # | 0001 0010 12
157 * | ## | 0000 1100 0C
158 * +------+
159 */
160 {0x0C,0x12,0x16,0x1A,0x12,0x0C},
161 /* +------+
162 * | # | 0000 0100 04
163 * | ## | 0000 1100 0C
164 * | # | 0000 0100 04
165 * | # | 0000 0100 04
166 * | # | 0000 0100 04
167 * | ### | 0000 1110 0E
168 * +------+
169 */
170 {0x04,0x0C,0x04,0x04,0x04,0x0E},
171 /* +------+
172 * | ## | 0000 1100 0C
173 * | # # | 0001 0010 12
174 * | # | 0000 0010 02
175 * | ## | 0000 1100 0C
176 * | # | 0001 0000 10
177 * | #### | 0001 1110 1E
178 * +------+
179 */
180 {0x0C,0x12,0x02,0x0C,0x10,0x1E},
181 /* +------+
182 * | ### | 0001 1100 1C
183 * | # | 0000 0010 02
184 * | ## | 0000 1100 0C
185 * | # | 0000 0010 02
186 * | # | 0000 0010 02
187 * | ### | 0001 1100 1C
188 * +------+
189 */
190 {0x1C,0x02,0x0C,0x02,0x02,0x1C},
191 /* +------+
192 * | # | 0001 0000 10
193 * | # | 0001 0000 10
194 * | # # | 0001 0100 14
195 * | # # | 0001 0100 14
196 * | #### | 0001 1110 1E
197 * | # | 0000 0100 04
198 * +------+
199 */
200 {0x10,0x10,0x14,0x14,0x1E,0x04},
201 /* +------+
202 * | #### | 0001 1110 1E
203 * | # | 0001 0000 10
204 * | ### | 0001 1100 1C
205 * | # | 0000 0010 02
206 * | # # | 0001 0010 12
207 * | ## | 0000 1100 0C
208 * +------+
209 */
210 {0x1E,0x10,0x1C,0x02,0x12,0x0C},
211 /* +------+
212 * | ### | 0000 1110 0E
213 * | # | 0001 0000 10
214 * | ### | 0001 1100 1C
215 * | # # | 0001 0010 12
216 * | # # | 0001 0010 12
217 * | ## | 0000 1100 0C
218 * +------+
219 */
220 {0x0E,0x10,0x1C,0x12,0x12,0x0C},
221 /* +------+
222 * | #### | 0001 1110 1E
223 * | # | 0000 0010 02
224 * | # | 0000 0100 04
225 * | # | 0000 0100 04
226 * | # | 0000 1000 08
227 * | # | 0000 1000 08
228 * +------+
229 */
230 {0x1E,0x02,0x04,0x04,0x08,0x08},
231 /* +------+
232 * | ## | 0000 1100 0C
233 * | # # | 0001 0010 12
234 * | ## | 0000 1100 0C
235 * | # # | 0001 0010 12
236 * | # # | 0001 0010 12
237 * | ## | 0000 1100 0C
238 * +------+
239 */
240 {0x0C,0x12,0x0C,0x12,0x12,0x0C},
241 /* +------+
242 * | ## | 0000 1100 0C
243 * | # # | 0001 0010 12
244 * | # # | 0001 0010 12
245 * | ### | 0000 1110 0E
246 * | # | 0000 0010 02
247 * | ## | 0000 1100 0C
248 * +------+
249 */
250 {0x0C,0x12,0x12,0x0E,0x02,0x0C},
251 /* +------+
252 * | | 0000 0000 00
253 * | ## | 0000 1100 0C
254 * | ## | 0000 1100 0C
255 * | | 0000 0000 00
256 * | ## | 0000 1100 0C
257 * | ## | 0000 1100 0C
258 * +------+
259 */
260 {0x00,0x0C,0x0C,0x00,0x0C,0x0C},
261 /* +------+
262 * | | 0000 0000 00
263 * | | 0000 0000 00
264 * | #### | 0001 1110 1E
265 * | #### | 0001 1110 1E
266 * | | 0000 0000 00
267 * | | 0000 0000 00
268 * +------+
269 */
270 {0x00,0x00,0x1E,0x1E,0x00,0x00},
271 /* +------+
272 * | | 0000 0000 00
273 * | # | 0000 0100 04
274 * | ## | 0000 0110 06
275 * |######| 0011 1111 3F
276 * | ## | 0000 0110 06
277 * | # | 0000 0100 04
278 * +------+
279 */
280 {0x00,0x04,0x06,0x3F,0x06,0x04},
281 /*
282 * ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄ¿
283 * ³.###..³.³#.....³.³.###..³.³#...#.³ xx01 1100 | xx10 0000 | xx01 1100 | xx10 0010 | 1C 20 1C 22
284 * ³#...#.³.³#.....³.³#...#.³.³#...#.³ xx10 0010 | xx10 0000 | xx10 0010 | xx10 0010 | 22 20 22 22
285 * ³#...#.³.³#.....³.³#...#.³.³.###..³ xx10 0010 | xx10 0000 | xx10 0010 | xx01 1100 | 22 20 22 1C
286 * ³####..³.³#.....³.³#####.³.³..#...³ xx11 1100 | xx10 0000 | xx11 1110 | xx00 1000 | 3C 20 3E 08
287 * ³#.....³.³#...#.³.³#...#.³.³..#...³ xx10 0000 | xx10 0010 | xx10 0010 | xx00 1000 | 20 22 22 08
288 * ³#.....³.³.###..³.³#...#.³.³..#...³ xx10 0000 | xx01 1100 | xx10 0010 | xx00 1000 | 20 1C 22 08
289 * ÀÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÙ
290 */
291 {0x1C,0x22,0x22,0x3C,0x20,0x20},
292 {0x20,0x20,0x20,0x20,0x22,0x1C},
293 {0x1C,0x22,0x22,0x3E,0x22,0x22},
294 {0x22,0x22,0x1C,0x08,0x08,0x08},
295 /* ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄ¿
296 * ³.###..³.³#...#.³.³#####.³.³#####.³ xx01 1100 | xx10 0010 | xx11 1110 | xx11 1110 | 1C 22 3E 3E
297 * ³#...#.³.³#...#.³.³..#...³.³..#...³ xx10 0010 | xx10 0010 | xx00 1000 | xx00 1000 | 22 22 08 08
298 * ³#...#.³.³#...#.³.³..#...³.³..#...³ xx10 0010 | xx10 0010 | xx00 1000 | xx00 1000 | 22 22 08 08
299 * ³#...#.³.³#...#.³.³..#...³.³..#...³ xx10 0010 | xx10 0010 | xx00 1000 | xx00 1000 | 22 22 08 08
300 * ³#..##.³.³#...#.³.³..#...³.³..#...³ xx10 0110 | xx10 0010 | xx00 1000 | xx00 1000 | 22 22 08 08
301 * ³.#####³.³.###..³.³#####.³.³..#...³ xx01 1111 | xx01 1100 | xx11 1110 | xx00 1000 | 1F 1C 3E 08
302 * ÀÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÙ
303 */
304 {0x1C,0x22,0x22,0x22,0x22,0x1F},
305 {0x22,0x22,0x22,0x22,0x22,0x1C},
306 {0x3E,0x08,0x08,0x08,0x08,0x3E},
307 {0x3E,0x08,0x08,0x08,0x08,0x08}
308
309};
310
311
312/***************************************************************************/
313/***************************************************************************/
314/* OTHLOGO.H */
315/***************************************************************************/
316/***************************************************************************/
317
318/*
319
320######### # # ### ## ## ###
321#### # # # # # # # # # #
322## # ### ### # # # # #
323## # # # # # ### # ##
324## # # # # # # # # #
325# # ### ## # # ###
326#
327# ### # # ### ##### ### # # ###
328# # # # # # # # # # #
329# ## ### ## # ### # # # ##
330# # # # # # # # # #
331# # # # # # # # # #
332#### ### # ### # ### # # ###
333
334
335
336 #####################################
337 #####################################
338
339
340 ## ##### # # #### # ##
341 #### # # # # # ####
342 ###### # #### ### # ## ##
343 ###### # # # # # ## ##
344 #### # # # # # ####
345 ## # # # #### #### ##
346
347
348 #####################################
349 #####################################
350
351 X=42, Y=30
352####|####|# # | # |### | ##| #|# |### | | | FF A2 E3 18 E0 00
353####| |# # | # |# #| # |# # | # #| | | | F0 A2 94 A5 00 00
354## | |# #|## |### | # |# # | # #| | | | C0 9C E4 A5 00 00
355## | | |# |# #| # |# ##|# #| ##| | | C0 08 94 B9 30 00
356## | | |# |# #| # |# # |# #| #| | | C0 08 94 A9 10 00
357# | | |# |### | ##| # | # |### | | | 80 08 E3 24 E0 00
358# | | | | | | | | | | | 80 00 00 00 00 00
359# | ##|# # | # | ###| ###|## |### | # #| #|## | 83 A2 77 CE 51 C0
360# | # | # | # |# | #| #| |# # |# # | | 84 22 81 10 AA 00
361# | ##| #|## | ## | #| #|## |# # |# #|# | 83 1C 61 1C A9 80
362# | |# |# | #| #| #| |# # |# | # | 80 88 11 10 A8 40
363# #| |# |# | #| #| #| |# |# | # | 90 88 11 10 88 40
364####| ###| |# |### | #| |### |# |# ##|# | F7 08 E1 0E 8B 80
365 | | | | | | | | | | | 00 00 00 00 00 00
366 | | | | | | | | | | | 00 00 00 00 00 00
367 | | | | | | | | | | | 00 00 00 00 00 00
368 ##|####|####|####|####|####|####|####|####|### | | 3F FF FF FF FE 00
369 ##|####|####|####|####|####|####|####|####|### | | 3F FF FF FF FE 00
370 | | | | | | | | | | | 00 00 00 00 00 00
371 | | | | | | | | | | | 00 00 00 00 00 00
372 | ##| #|####| # |# ##|## #| | ## | | | 03 1F 4B D0 60 00
373 | ###|# | # | # |# # | #| |####| | | 07 84 4A 10 F0 00
374 |####|## | # | ###|# ##|# #| #|# #|# | | 0F C4 7B 91 98 00
375 |####|## | # | # |# # | #| #|# #|# | | 0F C4 4A 11 98 00
376 | ###|# | # | # |# # | #| |####| | | 07 84 4A 10 F0 00
377 | ##| | # | # |# ##|## #|### | ## | | | 03 04 4B DE 60 00
378 | | | | | | | | | | | 00 00 00 00 00 00
379 | | | | | | | | | | | 00 00 00 00 00 00
380 ##|####|####|####|####|####|####|####|####|### | | 3F FF FF FF FE 00
381 ##|####|####|####|####|####|####|####|####|### | | 3F FF FF FF FE 00
382*/
383
384/*
385 * bpl = BYTES per line
386 * ppl = PIXELS per line
387 * l = total lines
388 */
389#define logo_bpl 6
390#define logo_ppl 42
391#define logo_l 32
392
393static unsigned char logo[] = {
394 0xFF,0xA2,0xE3,0x18,0xE0,0x00,
395 0xF0,0xA2,0x94,0xA5,0x00,0x00,
396 0xC0,0x9C,0xE4,0xA5,0x00,0x00,
397 0xC0,0x08,0x94,0xB9,0x30,0x00,
398 0xC0,0x08,0x94,0xA9,0x10,0x00,
399 0x80,0x08,0xE3,0x24,0xE0,0x00,
400 0x80,0x00,0x00,0x00,0x00,0x00,
401 0x83,0xA2,0x77,0xCE,0x51,0xC0,
402 0x84,0x22,0x81,0x10,0xAA,0x00,
403 0x83,0x1C,0x61,0x1C,0xA9,0x80,
404 0x80,0x88,0x11,0x10,0xA8,0x40,
405 0x90,0x88,0x11,0x10,0x88,0x40,
406 0xF7,0x08,0xE1,0x0E,0x8B,0x80,
407 0x00,0x00,0x00,0x00,0x00,0x00,
408 0x00,0x00,0x00,0x00,0x00,0x00,
409 0x00,0x00,0x00,0x00,0x00,0x00,
410 0x00,0x00,0x00,0x00,0x00,0x00,
411 0x3F,0xFF,0xFF,0xFF,0xFE,0x00,
412 0x3F,0xFF,0xFF,0xFF,0xFE,0x00,
413 0x00,0x00,0x00,0x00,0x00,0x00,
414 0x00,0x00,0x00,0x00,0x00,0x00,
415 0x00,0x00,0x00,0x00,0x00,0x00,
416 0x03,0x1F,0x4B,0xD0,0x60,0x00,
417 0x07,0x84,0x4A,0x10,0xF0,0x00,
418 0x0F,0xC4,0x7B,0x91,0x98,0x00,
419 0x0F,0xC4,0x4A,0x11,0x98,0x00,
420 0x07,0x84,0x4A,0x10,0xF0,0x00,
421 0x03,0x04,0x4B,0xDE,0x60,0x00,
422 0x00,0x00,0x00,0x00,0x00,0x00,
423 0x00,0x00,0x00,0x00,0x00,0x00,
424 0x3F,0xFF,0xFF,0xFF,0xFE,0x00,
425 0x3F,0xFF,0xFF,0xFF,0xFE,0x00
426};
427
428static void showlogo(int x, int y, bool on)
429{
430 int px,py; /* pixel x & y */
431
432 if (on)
433 {
434 for (py=0; py<logo_l; py++)
435 for (px=0; px<logo_ppl; px++)
436 if ( ((logo[(py*logo_bpl)+(px/8)] >>(7-(px%8))) &1) )
437 rb->lcd_drawpixel(x+px, y+py);
438 else
439 rb->lcd_clearpixel(x+px, y+py);
440 rb->lcd_update_rect(x,y, logo_ppl, logo_l);
441 }
442 else
443 rb->lcd_clearrect(x,y, logo_ppl, logo_l);
444
445 return;
446
447}
448
449
450/***************************************************************************/
451/***************************************************************************/
452/* OTHELO.H */
453/***************************************************************************/
454/***************************************************************************/
455
456
457/* the following #define had to be taken from Button.c
458 'cos it is not defined in the header!! */
459/* how long until repeat kicks in */
460#define REPEAT_START 6
461
462/* player types */
463#define HUMAN false
464#define AIBOT true
465
466/* for domove() */
467#define CHECK false
468#define MAKE true
469
470/* screen coords - top left x&y */
471 /* game over */
472#define go_tlx 71
473#define go_tly 17
474 /* WiNS */
475#define win_tlx 63
476#define win_tly 1
477 /* DRaW */
478#define draw_tlx 59
479#define draw_tly 1
480 /* scores */
481#define sc_tlx 65
482#define sc_tly 39
483 /* logo */
484#define logo_tlx 65
485#define logo_tly 2
486
487/* board sqaures -
488 * there are a number of routines that expect these values asis
489 * do not try to play with these, you will likely kill the program
490 */
491#define PLAYERX 0
492#define PLAYERO 1
493#define POSS 2
494#define CHOICE 3
495#define EMPTY 4
496#define BORDER 5
497
498/* Who gets first turn */
499#define FIRST PLAYERX
500#define DF_PLX HUMAN
501#define DF_AIX NONE
502#define DF_PLO AIBOT
503#define DF_AIO WEAK
504
505/* Oponent skill level / help level
506 * -------- ---------------------------------------------------
507 * NONE no ai / no help
508 * WEAK random valid move / show all possible
509 * AVERAGE most pieces (random) / all + most pieces
510 * SMART most pieces (weighted/random) / all + weighted
511 * EXPERT
512 * GURU
513 */
514#define NONE 0
515#define WEAK 1
516#define AVERAGE 2
517#define SMART 3
518#define EXPERT 4
519#define GURU 5
520#define BEST 3 /* the best ai alogrithm currently available */
521
522/* these are for code clarity, do not change them! */
523#define LEFT 0x08
524#define RIGHT 0x04
525#define UP 0x02
526#define DOWN 0x01
527
528/* This represents the maximum number of possible moves
529 * I have no idea what the real maximum is, buts tests
530 * suggest about 10
531 */
532#define MAXPOSS 20
533
534struct move
535{
536 int x;
537 int y;
538 int taken;
539 int rank;
540 bool player;
541};
542
543
544/*===================================================================
545 * local global variables
546 * THIS IS THE DATA THAT NEEDS TO BE SAVED TO ALLOW THE GAME
547 * TO CONTINUE ...THE CONTINUE FEATURE DOES NOT WORK UNDER THE
548 * NEW PLUGIN SYSTEM!
549 *==================================================================*/
550
551/* score */
552static struct
553 {
554 int x;
555 int o;
556 } score;
557
558/* 8x8 with borders */
559static unsigned char board[10][10];
560
561/* player=HUMAN|AIBOT */
562static bool player[2] = {DF_PLX, DF_PLO};
563
564/* AI = WEAK|AVERAGE|SMART|EXPERT|GURU
565 Help=NONE|WEAK|AVERAGE|SMART|EXPERT|GURU */
566static unsigned char ai_help[2] = {DF_AIX, DF_AIO};
567
568/* is a game under way */
569static bool playing = false;
570
571/* who's turn is it? */
572static bool turn = FIRST;
573
574/********************************************************************
575 * strlen ofr use with othello print system
576 ********************************************************************/
577static int othstrlen(char* s)
578{
579 int i;
580
581 for(i=0; s[i]!=of_eos; i++);
582
583 return(i);
584
585}
586
587/********************************************************************
588 * print othello char upd=true will issue update_lcd()
589 ********************************************************************/
590static void othprint(unsigned char x, unsigned char y, char ch, bool upd)
591{
592 int px,py; /* pixel coords 1..6 */
593
594 for (py=0; py<6; py++)
595 for (px=0; px<6; px++)
596 if ((othfont[(unsigned char)ch][py] >>(5-px)) &1)
597 rb->lcd_drawpixel(x+px, y+py);
598 else
599 rb->lcd_clearpixel(x+px, y+py);
600
601 if (upd)
602 rb->lcd_update_rect(x,y, 6,6);
603
604 return;
605
606}
607
608
609/********************************************************************
610 * print othello string upd=true will issue update_lcd()
611 ********************************************************************/
612static void othprints(unsigned char x, unsigned char y, char* s, bool upd)
613{
614 int i;
615 int l; /* length of string */
616
617 l = othstrlen(s);
618
619 for (i=0; i<l; i++)
620 othprint(x+i*6,y, s[i], false);
621
622 if (upd)
623 rb->lcd_update_rect(x,y, l*6,6);
624
625 return;
626
627}
628
629
630/********************************************************************
631 * display game over visuals
632 ********************************************************************/
633static void show_endgame(unsigned char scx, unsigned char sco)
634{
635 /* end of game messages */
636 showlogo(logo_tlx,logo_tly, false);
637
638 /* game over */
639 rb->lcd_putsxy(go_tlx+1,go_tly+1, "Game");
640 rb->lcd_putsxy(go_tlx+1,go_tly+11, "oveR");
641 rb->lcd_invertrect(go_tlx,go_tly, 27,20);
642
643 if (scx==sco)
644 {
645 /* draw */
646 rb->lcd_putsxy(draw_tlx+13,draw_tly+4, "DraW");
647 othprint(draw_tlx+5,draw_tly+5, of_plx, true);
648 othprint(draw_tlx+40,draw_tly+5, of_plo, true);
649 rb->lcd_drawrect(draw_tlx+2,draw_tly+2, 47,11);
650 rb->lcd_drawrect(draw_tlx,draw_tly, 51,15);
651 }
652 else
653 {
654 /* win */
655 rb->lcd_putsxy(win_tlx+14,win_tly+4, "WiNS");
656 if (sco>scx)
657 othprint(win_tlx+5,win_tly+5, of_plo, true);
658 else
659 othprint(win_tlx+5,win_tly+5, of_plx, true);
660 rb->lcd_drawrect(win_tlx+2,win_tly+2, 39,11);
661 rb->lcd_drawrect(win_tlx,win_tly, 43,15);
662 }
663
664 rb->lcd_update();
665
666 return;
667
668}
669
670
671/********************************************************************
672 * display othello grid
673 * currenly hard coded to the top left corner of the screen
674 ********************************************************************/
675static void show_grid(void)
676{
677 int x,y;
678
679 rb->lcd_clearrect(0,0, (8*7)+1,(8*7)+1);
680 rb->lcd_drawrect(0,0, (8*7)+1,(8*7)+1);
681 for (x=7; x<((7*7)+1); x+=7)
682 {
683 rb->lcd_drawline(1,x, 2,x);
684 rb->lcd_drawline(x,1, x,2);
685 rb->lcd_drawline(x,(8*7)-1, x,(8*7)-2);
686 rb->lcd_drawline((8*7)-1,x, (8*7)-2,x);
687 for (y=7; y<((7*7)+1); y+=7)
688 {
689 rb->lcd_drawline(x-2,y, x+2,y);
690 rb->lcd_drawline(x,y-2, x,y+2);
691 }
692 }
693 rb->lcd_update_rect(0,0, (8*7)+1,(8*7)+1);
694
695 return;
696
697}
698
699
700/********************************************************************
701 * flash the board - used for invalid move!
702 ********************************************************************/
703static void flashboard(void)
704{
705 rb->lcd_invertrect(0,0, (8*7)+1,(8*7)+1);
706 rb->lcd_update_rect(0,0, (8*7)+1,(8*7)+1);
707 rb->sleep(HZ/10);
708 rb->lcd_invertrect(0,0, (8*7)+1,(8*7)+1);
709 rb->lcd_update_rect(0,0, (8*7)+1,(8*7)+1);
710
711 return;
712
713}
714
715
716/********************************************************************
717 * show player skill levels
718 ********************************************************************/
719static void show_players(void)
720{
721 static char scs[] = {
722 of_plx, of_colon, of_h, of_dash, of_0, of_eos, /* 0 */
723 of_plo, of_colon, of_h, of_dash, of_0, of_eos /* 6 */
724 };
725
726 if (player[PLAYERX]==AIBOT)
727 scs[2] = of_c;
728 else
729 scs[2] = of_h;
730 scs[4] = ai_help[PLAYERX] +of_0;
731
732 if (player[PLAYERO]==AIBOT)
733 scs[8] = of_c;
734 else
735 scs[8] = of_h;
736 scs[10] = ai_help[PLAYERO] +of_0;
737
738 othprints( 2,58, &scs[0], true);
739 othprints(40,58, &scs[6], true);
740
741 return;
742
743}
744
745
746/********************************************************************
747 * show f3 function
748 ********************************************************************/
749static void show_f3(bool playing)
750{
751 static char scs[10] = {of_p, of_l, of_a, of_y, of_eos,
752 of_q, of_u, of_i, of_t, of_eos };
753
754 if (playing)
755 othprints(80,58, &scs[5], true);
756 else
757 othprints(80,58, &scs[0], true);
758
759 return;
760
761}
762
763
764/********************************************************************
765 * update board tiles
766 ********************************************************************/
767static void show_board(void)
768{
769 unsigned char x,y;
770
771 for (y=1; y<=8; y++)
772 for (x=1; x<=8; x++)
773 othprint(((x-1)*7)+1, ((y-1)*7)+1, board[y][x], false);
774 rb->lcd_update_rect(0,0, (8*7)+1,(8*7)+1);
775
776 return;
777
778}
779
780
781/********************************************************************
782 * display scores player "turn" will get the arrow
783 ********************************************************************/
784static void show_score(bool turn)
785{
786 static char scs[] = {of_ptr, of_eos, /* 0 */
787 of_sp, of_eos, /* 2 */
788 of_plx, of_colon, of_eos, /* 4 */
789 of_plo, of_colon, of_eos, /* 7 */
790 of_sp, of_sp, of_eos, /* 10 score.x */
791 of_sp, of_sp, of_eos, /* 13 score.o */
792 };
793
794 rb->snprintf(&scs[10], 3, "%d", score.x);
795 scs[10] = scs[10] -'0' +of_0;
796 if (scs[11]=='\0')
797 scs[11] = of_sp;
798 else
799 scs[11] = scs[11] -'0' +of_0;
800 scs[12] = of_eos;
801
802 rb->snprintf(&scs[13], 3, "%d", score.o);
803 scs[13] = scs[13] -'0' +of_0;
804 if (scs[14]=='\0')
805 scs[14] = of_sp;
806 else
807 scs[14] = scs[14] -'0' +of_0;
808 scs[15] = of_eos;
809
810 /* turn arrow */
811 if (turn==PLAYERX)
812 {
813 othprints(sc_tlx,sc_tly, &scs[0], false);
814 othprints(sc_tlx,sc_tly+8, &scs[2], false);
815 }
816 else
817 {
818 othprints(sc_tlx,sc_tly, &scs[2], false);
819 othprints(sc_tlx,sc_tly+8, &scs[0], false);
820 }
821
822 /* names */
823 othprints(sc_tlx+10,sc_tly, &scs[4], false);
824 othprints(sc_tlx+10,sc_tly+8, &scs[7], false);
825
826 /* scores */
827 othprints(sc_tlx+26,sc_tly, &scs[10], false);
828 othprints(sc_tlx+26,sc_tly+8, &scs[13], false);
829
830 rb->lcd_update_rect(sc_tlx,sc_tly, 40,14);
831
832 return;
833}
834
835
836/********************************************************************
837 * cls()
838 ********************************************************************/
839static void initscreen(void)
840{
841 rb->lcd_setfont(FONT_SYSFIXED);
842 rb->lcd_clear_display();
843 rb->lcd_update();
844
845 return;
846}
847
848
849/********************************************************************
850 * Check is the specified move is valid
851 * if type=MOVE - the board will be updated.
852 * this is the recursive bit - it is called by domove()
853 * checkmove only checks the move in ONE direction
854 ********************************************************************/
855static int checkmove(unsigned char x, unsigned char y, bool pl,
856 unsigned char dir, bool type)
857{
858 int i;
859 unsigned char t;
860
861 x -= ( ((dir&LEFT )==LEFT ) ?1:0);
862 x += ( ((dir&RIGHT)==RIGHT) ?1:0);
863 y -= ( ((dir&UP )==UP ) ?1:0);
864 y += ( ((dir&DOWN )==DOWN ) ?1:0);
865
866 t = board[y][x];
867
868 /* found your piece */
869 if ( t == ((pl==PLAYERX)?PLAYERX:PLAYERO) )
870 return(1);
871
872 /* found an empty sqaure or board edge */
873 if (t>PLAYERO)
874 return(0);
875
876 /* must have found opponent piece */
877 if ((i = checkmove(x,y, pl, dir, type)))
878 {
879 if (type==MAKE)
880 board[y][x] = pl;
881 return(i+1);
882 }
883 else
884 return(0);
885}
886
887
888/********************************************************************
889 * this is the control loop for checkmove()
890 * checkmove()it is called with all eight possible directoins
891 * the move.taken is defined before it returns
892 * 0 taken is an invalid move
893 ********************************************************************/
894static void domove(struct move* move, bool type)
895{
896 int i;
897 unsigned char dir;
898
899 move->taken = 0;
900 for (dir=DOWN; dir<=(LEFT|UP); dir++)
901 {
902 if ( (dir&(UP|DOWN)) ==(UP|DOWN) )
903 continue;
904 if ((i = checkmove(move->x, move->y, move->player, dir, type)))
905 move->taken += i-1;
906 }
907
908 return;
909}
910
911
912/********************************************************************
913 * initialise a new game board and draw it on the screen
914 ********************************************************************/
915static void initboard(void)
916{
917 unsigned char x,y;
918
919 for (y=0; y<10; y++)
920 for (x=0; x<10; x++)
921 if ( (y%9)==0 || (x%9)==0)
922 board[y][x] = BORDER;
923 else
924 board[y][x] = EMPTY;
925
926 board[4][4] = PLAYERX;
927 board[5][5] = PLAYERX;
928 board[4][5] = PLAYERO;
929 board[5][4] = PLAYERO;
930
931 score.x = 2;
932 score.o = 2;
933
934 show_grid();
935 show_board();
936 show_score(FIRST);
937
938 return;
939}
940
941
942/********************************************************************
943 * remove "possible" markers from the board
944 ********************************************************************/
945static void clearposs(void)
946{
947 int x, y;
948
949 for (y=1; y<=8; y++)
950 for (x=1; x<=8; x++)
951 if (board[y][x]>=POSS)
952 board[y][x]=EMPTY;
953
954 return;
955}
956
957
958/********************************************************************
959 * build a list of all possible moves
960 ********************************************************************/
961static int getplist(struct move* plist, unsigned char pl)
962{
963 int x, y;
964 unsigned char pcnt = 0;
965
966 /* this significantly reduces the amount of pointer maths */
967 struct move pmove;
968
969 /* clear previous possibilities */
970 clearposs();
971
972 for (y=1; y<=8; y++)
973 for (x=1; x<=8; x++)
974 {
975 /* only empty sqaures */
976 if (board[y][x]!=EMPTY)
977 continue;
978 /* try move */
979 pmove.x = x;
980 pmove.y = y;
981 pmove.player = pl;
982 domove(&pmove, CHECK);
983 /* if valid - add to list */
984 if (pmove.taken)
985 rb->memcpy(&plist[pcnt++], &pmove, sizeof(struct move));
986 }
987
988 return(pcnt);
989
990}
991
992
993/********************************************************************
994 * qsort
995 ********************************************************************/
996static int plist_bytaken(const void* m1, const void* m2)
997{
998 /* highest is best */
999 return( ((struct move*)m2)->taken - ((struct move*)m1)->taken );
1000}
1001
1002
1003/********************************************************************
1004 * qsort
1005 ********************************************************************/
1006static int plist_byrank(const void* m1, const void* m2)
1007{
1008 /* lowest is best */
1009 return( ((struct move*)m1)->rank - ((struct move*)m2)->rank );
1010}
1011
1012
1013/********************************************************************
1014 *
1015CORNERS (1)
1016x......x 1,1(01) 1,8(08)
1017........
1018........
1019........
1020........
1021........
1022........
1023x......x 8,1(08) 8,8(64)
1024
1025
1026BLUFF (2)
1027..x..x.. 1,3(03) 1,6(06)
1028........
1029x.x..x.x 3,1(03) 3,3(09) 3,6(18) 3,8(24)
1030........
1031........
1032x.x..x.x 6,1(06) 6,3(18) 6,6(36) 6,8(48)
1033........
1034..x..x.. 8,3(24) 8,6(48) 8,8(64)
1035
1036
1037EDGE (3)
1038...xx... 1,4(00) 1,5(00)
1039........
1040........
1041x......x 4,1(00) 4,8(00)
1042x......x 5,1(00) 5,8(00)
1043........
1044........
1045...xx... 8,4(00) 8,5(00)
1046
1047
1048BAD (5) - some of these are edge pieces
1049.x....x. 1,2(02) 1,7(07)
1050xx....xx 2,1(02) 2,2(04) 2,7(14) 2,8(16)
1051........
1052........
1053........
1054........
1055xx....xx 7,1(07) 7,2(14) 7,7(49) 7,8(56)
1056.x....x. 8,2(16) 8,7(56)
1057
1058
1059OTHER (4)
1060
1061 * this is called my reduceplist, if the "smart" AIBOT is playing
1062 * board sqaures are weighted as above
1063 *
1064 ********************************************************************/
1065static void smartranking(struct move* plist, unsigned char pcnt)
1066{
1067
1068#define corner \
1069 ( ((y==1)||(y==8)) && ((x==1)||(x==8)) )
1070
1071#define bluff \
1072 ( ((y==1)||(y==3)||(y==6)||(y==8)) && \
1073 ((x==1)||(x==3)||(x==6)||(x==8)) )
1074
1075#define edge \
1076 ( ( ((y==1)||(y==8)) && ((x==4)||(x==5)) ) || \
1077 ( ((y==4)||(y==5)) && ((x==1)||(x==8)) ) )
1078
1079 int i;
1080 register unsigned char mul;
1081 register unsigned char x, y;
1082
1083 for (i=0; i<pcnt; i++)
1084 {
1085 x = plist[i].x;
1086 y = plist[i].y;
1087 mul = x *y;
1088
1089 /* preferred squares */
1090 if (corner) { plist[i].rank = 1; continue; }
1091 else if (bluff) { plist[i].rank = 2; continue; }
1092 else if (edge) { plist[i].rank = 3; continue; }
1093
1094 /* uninteresting square */
1095 plist[i].rank = 4;
1096
1097 /* avoid "bad" sqaures */
1098 if ( (mul==02)||(mul==04)||
1099 (mul==07)||(mul==14)||(mul==16)||
1100 (mul==49)||(mul==56) )
1101 plist[i].rank = 5;
1102 }
1103
1104 return;
1105
1106#undef corner
1107#undef bluff
1108#undef edge
1109
1110}
1111
1112
1113/********************************************************************
1114 * called by pressing f1 or f2 to change player modes
1115 ********************************************************************/
1116static void changeplayer(bool pl)
1117{
1118 ai_help[pl]++;
1119 if (ai_help[pl]>BEST)
1120 {
1121 player[pl] = (player[pl]==HUMAN)?AIBOT:HUMAN;
1122 if (player[pl]==HUMAN)
1123 ai_help[pl] = NONE;
1124 else
1125 ai_help[pl] = WEAK;
1126 }
1127 show_players();
1128
1129 return;
1130}
1131
1132
1133/********************************************************************
1134 * this proc reduces the list of possible moves to a short list of
1135 * preferred moves, dependand on the player AI
1136 ********************************************************************/
1137static unsigned char reduceplist(struct move* plist, unsigned char pcnt, unsigned char ai_help)
1138{
1139
1140 int i;
1141
1142 switch(ai_help)
1143 {
1144 /* ------------------------------------------------- */
1145 /* weak does not modify the possible's list */
1146 /*
1147 case WEAK:
1148 break;
1149 */
1150 /* ------------------------------------------------- */
1151 case GURU:
1152 break;
1153 /* ------------------------------------------------- */
1154 case EXPERT:
1155 break;
1156 /* ------------------------------------------------- */
1157 /* this player will favour certain known moves */
1158 case SMART:
1159 if (pcnt>1)
1160 {
1161 smartranking(plist, pcnt);
1162 rb->qsort(plist, pcnt, sizeof(struct move), plist_byrank);
1163 for (i=1; i<pcnt; i++)
1164 if (plist[i].rank!=plist[i-1].rank)
1165 break;
1166 pcnt = i;
1167 }
1168 /* FALL THROUGH */
1169 /* ------------------------------------------------- */
1170 /* reduce possibilites to "most pieces taken" */
1171 case AVERAGE:
1172 if (pcnt>1)
1173 {
1174 rb->qsort(plist, pcnt, sizeof(struct move), plist_bytaken);
1175 for (i=1; i<pcnt; i++)
1176 if (plist[i].taken!=plist[i-1].taken)
1177 break;
1178 pcnt = i;
1179 }
1180 break;
1181 /* ------------------------------------------------- */
1182 default:
1183 // you should never get here!
1184 break;
1185 }
1186
1187 return(pcnt);
1188
1189}
1190
1191
1192/********************************************************************
1193 * calc all moves with wieghting and report back to the user/aibot
1194 ********************************************************************/
1195static bool calcposs(struct move* plist, unsigned char* pcnt, bool turn)
1196{
1197 int i;
1198
1199 /* get list of all possible moves */
1200 (*pcnt) = getplist(plist, turn);
1201
1202 /* no moves? trigger Game Over */
1203 if (!(*pcnt))
1204 return(true);
1205
1206 /* only evaluate moves for AIBOTs or HUMAN+HELP */
1207 if ( (player[turn]==AIBOT) || (ai_help[turn]) )
1208 {
1209 /* mark all possible moves on board */
1210 for (i=0; i<(*pcnt); i++)
1211 board[plist[i].y][plist[i].x] = POSS;
1212
1213 /* use ai to reduce list */
1214 (*pcnt) = reduceplist(plist, (*pcnt), ai_help[turn]);
1215
1216 /* higlight preferred moves */
1217 if (ai_help[turn]>WEAK)
1218 for (i=0; i<(*pcnt); i++)
1219 board[plist[i].y][plist[i].x] = CHOICE;
1220 }
1221 else /* no ai/help required */
1222 {
1223 /* create dummy plist entry for default cursor position */
1224 plist[0].x = 4;
1225 plist[0].y = 4;
1226 }
1227
1228 return(false); /* do not cause Game Over */
1229}
1230
1231
1232/********************************************************************
1233 * cursor highlight
1234 ********************************************************************/
1235static void hilite(struct move* move, bool on)
1236{
1237 int x = (move->x-1)*7;
1238 int y = (move->y-1)*7;
1239
1240 rb->lcd_invertrect(x+1,y+1, 6,6);
1241 if (on)
1242 rb->lcd_drawrect(x,y, 8,8);
1243 else
1244 {
1245 if (x)
1246 rb->lcd_clearline(x,y+3, x,y+4);
1247 if (y)
1248 rb->lcd_clearline(x+3,y, x+4,y);
1249 if (x!=7*7)
1250 rb->lcd_clearline(x+7,y+3, x+7,y+4);
1251 if (y!=7*7)
1252 rb->lcd_clearline(x+3,y+7, x+4,y+7);
1253 }
1254 rb->lcd_update_rect(x,y, 8,8);
1255}
1256
1257
1258/********************************************************************
1259 * main othelo keyboard handler
1260 * returns the key that it terminated with
1261 ********************************************************************/
1262static int getmove(struct move* move, struct move* plist, unsigned char* pcnt, bool turn)
1263{
1264 int key;
1265 bool waiting = true;
1266
1267 /* get next move */
1268 do
1269 {
1270 hilite(move, true);
1271 key = rb->button_get(true);
1272 hilite(move, false);
1273
1274 switch(key)
1275 {
1276 case BUTTON_ON:
1277 case BUTTON_OFF:
1278 case BUTTON_F3:
1279 waiting = false;
1280 break;
1281 case BUTTON_UP:
1282 case BUTTON_UP | BUTTON_REPEAT:
1283 if (move->y>1) move->y--;
1284 break;
1285 case BUTTON_DOWN:
1286 case BUTTON_DOWN | BUTTON_REPEAT:
1287 if (move->y<8) move->y++;
1288 break;
1289 case BUTTON_LEFT:
1290 case BUTTON_LEFT | BUTTON_REPEAT:
1291 if (move->x>1) move->x--;
1292 break;
1293 case BUTTON_RIGHT:
1294 case BUTTON_RIGHT | BUTTON_REPEAT:
1295 if (move->x<8) move->x++;
1296 break;
1297 case BUTTON_PLAY:
1298 if (board[move->y][move->x]>=POSS)
1299 waiting = false;
1300 else
1301 flashboard();
1302 break;
1303 case BUTTON_F1:
1304 case BUTTON_F2:
1305 {
1306 bool pl;
1307
1308 pl = (key==BUTTON_F1)?PLAYERX:PLAYERO;
1309
1310 changeplayer(pl);
1311 /* update board if *current* player options changed */
1312 if (move->player==pl)
1313 {
1314 clearposs();
1315 calcposs(plist, pcnt, turn);
1316 show_board();
1317 }
1318 break;
1319 }
1320 default:
1321 break;
1322 }
1323 } while (waiting);
1324
1325 return(key);
1326}
1327
1328
1329/********************************************************************
1330 * main control loop
1331 ********************************************************************/
1332enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1333{
1334#define STILL_PLAYING (!gameover && !quit)
1335
1336#define default_players \
1337 player[PLAYERX] = DF_PLX; \
1338 ai_help[PLAYERX] = DF_AIX; \
1339 player[PLAYERO] = DF_PLO; \
1340 ai_help[PLAYERO] = DF_AIO;
1341
1342 int key;
1343
1344 unsigned char pcnt;
1345 struct move plist[MAXPOSS];
1346
1347 bool gameover;
1348 bool quit;
1349
1350 struct move move;
1351
1352 TEST_PLUGIN_API(api);
1353 (void)parameter;
1354 rb = api;
1355
1356 quit = false;
1357
1358 do /* while !quit */
1359 {
1360 initscreen();
1361 showlogo(logo_tlx,logo_tly, true);
1362 show_players();
1363 show_f3(true);
1364
1365 if (!playing)
1366 {
1367 initboard();
1368 playing = true;
1369 turn = FIRST;
1370 }
1371 else
1372 {
1373 show_grid();
1374 show_board();
1375 show_score(turn);
1376 }
1377
1378 gameover = false;
1379
1380 do /* while !gameover && !quit */
1381 {
1382 /* who's move is it? */
1383 move.player = turn;
1384
1385 /* perform ai/help routine */
1386 if ((gameover = calcposs(plist, &pcnt, turn))) continue;
1387
1388 /* player now gets to take a turn */
1389 if (player[turn]==AIBOT)
1390 {
1391 int timeout;
1392 bool held = false;
1393
1394 unsigned char t;
1395 /* select a random move from the possibles list */
1396 /* this block of code corrupts pcnt */
1397 if (pcnt>1)
1398 t = rb->rand() % pcnt;
1399 else
1400 t = 0;
1401 move.x = plist[t].x;
1402 move.y = plist[t].y;
1403 /* move selected will always be valid! */
1404 domove(&move, CHECK);
1405
1406 /* bots run faster when no humans are playing */
1407 if ((player[PLAYERX]==AIBOT) && (player[PLAYERO]==AIBOT))
1408 timeout = *rb->current_tick +((HZ*6)/10);
1409 else
1410 timeout = *rb->current_tick +((HZ*(REPEAT_START+1))/10);
1411 while (TIME_BEFORE(*rb->current_tick, timeout))
1412 {
1413 key = rb->button_get(false);
1414 switch (key)
1415 {
1416 case SYS_USB_CONNECTED:
1417 rb->usb_screen();
1418 return PLUGIN_USB_CONNECTED;
1419 /* hold play to freeze board */
1420 case BUTTON_PLAY:
1421 case BUTTON_PLAY|BUTTON_REPEAT:
1422 timeout = *rb->current_tick +HZ;
1423 held = true;
1424 break;
1425 case BUTTON_PLAY|BUTTON_REL:
1426 if (held)
1427 timeout = *rb->current_tick-1;
1428 continue;
1429 case BUTTON_F3:
1430 gameover = true;
1431 break;
1432 case BUTTON_OFF:
1433 default_players;
1434 playing = false;
1435 /* Fall through to BUTTON_ON */
1436 case BUTTON_ON:
1437 return PLUGIN_OK;
1438 default:
1439 break;
1440 }
1441 } /*endwhile*/;
1442 }
1443 else /* player is human */
1444 {
1445 /* only display poss on screen if help is enabled */
1446 if (ai_help[turn]) show_board();
1447 move.x = plist[0].x;
1448 move.y = plist[0].y;
1449 while(true)
1450 {
1451 key = getmove(&move, plist, &pcnt, turn);
1452 switch(key)
1453 {
1454 case SYS_USB_CONNECTED:
1455 rb->usb_screen();
1456 return PLUGIN_USB_CONNECTED;
1457 case BUTTON_OFF:
1458 playing = false;
1459 default_players;
1460 case BUTTON_ON:
1461 rb->lcd_setfont(FONT_UI);
1462 return PLUGIN_OK;
1463 case BUTTON_F3:
1464 gameover = true;
1465 default:
1466 break;
1467 }
1468 if (key==BUTTON_F3)
1469 break;
1470
1471 /* check move is valid & retrieve "pieces taken" */
1472 domove(&move, CHECK);
1473 if (move.taken==0)
1474 flashboard();
1475 else
1476 break;
1477 }
1478 }
1479
1480 /* player may have hit restart instead of moving */
1481 if (STILL_PLAYING)
1482 {
1483 /* MAKE MOVE */
1484 /* add new piece */
1485 board[move.y][move.x] = move.player;
1486 /* flip opponent pieces */
1487 domove(&move, MAKE);
1488 /* update board */
1489 clearposs();
1490 show_board();
1491 /* update score */
1492 if (turn==PLAYERX)
1493 {
1494 score.x += move.taken+1;
1495 score.o -= move.taken;
1496 }
1497 if (turn==PLAYERO)
1498 {
1499 score.o += move.taken+1;
1500 score.x -= move.taken;
1501 }
1502 /* next player please */
1503 turn = (turn==PLAYERX)?PLAYERO:PLAYERX;
1504 show_score(turn);
1505 }
1506
1507 } while(STILL_PLAYING);
1508
1509 clearposs();
1510 show_board();
1511 show_f3(false);
1512 show_endgame(score.x, score.o);
1513 playing = false;
1514
1515 do
1516 {
1517 if ((key = rb->button_get(true)) ==BUTTON_F3)
1518 break;
1519 switch(key)
1520 {
1521 case SYS_USB_CONNECTED:
1522 rb->usb_screen();
1523 return PLUGIN_USB_CONNECTED;
1524 case BUTTON_OFF:
1525 default_players;
1526 case BUTTON_ON:
1527 quit = true;
1528 break;
1529 case BUTTON_F1:
1530 changeplayer(PLAYERX);
1531 break;
1532 case BUTTON_F2:
1533 changeplayer(PLAYERO);
1534 break;
1535 default:
1536 break;
1537 }
1538 } while(!quit);
1539
1540 }while(!quit);
1541
1542 return PLUGIN_OK;
1543
1544}
1545#endif
diff --git a/apps/plugins/othelo.txt b/apps/plugins/othelo.txt
deleted file mode 100644
index 169203f32e..0000000000
--- a/apps/plugins/othelo.txt
+++ /dev/null
@@ -1,122 +0,0 @@
1Introduction to Othelo
2======================
3
4Othelo is based on a popular board game. This is by no means the first computer port of this game - the most famous port I can name was "Reversi".
5
6The objective is to 'capture' more squares of the board than your opponent.
7
8Each turn you claim a single, previously unclaimed, square of the board. But EVERY move MUST result in the taking of at least one of your opponents squares.
9
10An opponents square is captured by placing your pieces either side of it. Either vertically, horizontally or diagonally.
11
12The rules are mind-numbingly simple ...but, like Chess, the strategy for regular success is far from obvious.
13
14Further guidance on playing can be found at:
15http://home.nc.rr.com/othello/strategy/midgame/
16...although I would like to add that all of the AI Bots (Computer opponents) (currently three thereof) were written by yours truly without reference to these type of guides :-)
17
18
19Controls
20========
21
22Othelo can be found under games->othelo from the Rockbox main menu.
23
24At any time during play:
25F1 will change the player and dreamer for the BLACK opponent
26F2 will change the player and dreamer for the WHITE opponent
27F3 will terminate the current game
28OFF will switch off the Othelo game. When Othelo is restarted from the menu,
29 play will start with a new board.
30ON will suspend the current Othelo game. When Othelo is restarted from the
31 menu, play will continue from where it left off.
32
33Either player may be a Human or Computer, and this may be changed at any time during play with F1 and F2. The current choice is indicated by an H or C above the respective F1 and F2 buttons on the Jukebox.
34
35NOTE: The "suspend" function relied on an 'undocumented' feature which is no longer prevelant under the new "plugin" system. Therefore it needs to be re-implemented as "save progress to file." There are a number of reasons why this has not been implemented - if there is any demand for it, it will be added.
36
37
38Computer Advice
39===============
40
41When a Human is playing, he may select any of the AI Bots to offer advice (it is described as the Computer "dreaming" for you).
42
43The default advice/help level is 0 (zero) ...no advice
44Bot 1 help will simply highlight all possible valid moves
45Bot 2 will advise you which moves would steal the most pieces per turn
46Bot 3 will offer even deeper insights about strategic positioning
47Bot 4 hasn't been written yet ...watch this space
48
49In each case a 'valid' move is displayed as a dot in the centre of the square and a 'choice' move is highlighted with a cross.
50
51
52AI Opponents
53============
54
55There are currently three AI opponents C-1, C-2 and C-3 respectively. Each has it's own style of play. Losing against one of the opponents does not necessarily mean that you will lose against another.
56
57It can be interesting to set both opponents to Computer mode and watch them play against each other.
58
59
60Navigation
61==========
62
63During the turn of a Human, the up, down, left and right cursor keys navigate the board highlight in a suspiciously expected manner to the chosen square. When the cursor is highlighting the square you wish to play in, press PLAY. If you have chosen an invalid move, the board will flash and you will be expected to try again.
64
65Button repeat _is_ enabled for navigation.
66
67The AI opponents will pause slightly before making their move, to allow you to see the result of your move. If you wish to force the Computer opponent to wait longer before playing, you may keep PLAY depressed ("keep your finger on the piece you just played") and the Computer will make his move immediately you remove your finger from the keypad.
68
69
70Display
71=======
72
73The main board is that great big grid thing taking up most of the screen.
74
75Above F1 and F2, on the bottom line of the screen, is the identity of each player. Such as:
76"O:C-1" ...this means that, the player represented by the "O" graphic is a
77 [C]omputer and is controlled by AI Bot #1
78"O:H-2" ...this means that, the player represented by the "O" graphic is a
79 [H]uman player, and has AI Bot #2 dreaming for him
80etc.
81
82The scores are shown toward the bottom right of the screen and the current player has a small arrow (->) next to his name, indicating that he should hurry up and actually make a move, today preferably ...although if the music does run out, you can always use the ON button to suspend the game while you go and queue up some more :) ...or not if you are using the current plugin version :(
83
84During play the rest of the screen (the big lump on the right at the top) will show a pointless graphic to make the screen look pretty. When the game is quit or finished naturally, this area will display the identity of the winner, and a secret "end of play" message.
85
86
87Source Code
88===========
89
90The source code is scruffy, but well documented. For the plugin system all headers files were included into the main source code and erased to conform to the new coding standard.
91
92
93Future Development
94==================
95
96Better AI Bots. A perfect AI Bot is easy and you can add tolerances to it from there (to dumb it down a bit) ...the dilemma is the vast quantity of RAM required to run it. So the Bots really need to be strategy and not logic based.
97
98Remote control support. Save wear and tear on your Jukebox keys - that really weren't designed with games players in mind.
99
100
101Coding standards, bugs'n'stuff
102==============================
103
104Remember, if you don't like the code ...throw it away and never look at it again! ...Please do not tell me, I don't care. Any complaint requiring a response should be written on the back of notes valued at five thousand shiny new pennies of the British realm. ;)
105
106On the other hand, I love getting compliments, I am pleased to hear about bugs I can fix - although they don't tend to happen too often in my code ...go on then, find one! If you can think of any clever short cuts I have missed or fancy your hand at writing the next AI Bot - gimme a shout and I will explain all there is to know about possibility lists, and perhaps even answer such questions as "why is there only one equals sign in this IF statement" and "why are there lines of code with question marks in them"
107
108
109Greetz
110======
111
112mk, pajaco, DevZer0, jzoss, LinusN, Zagor, Cyborg, Lord Grumble
113
114
115Author
116======
117
118BlueChip
119Yep, the lot - and right chuffed with miself too :)
120
121
122-- othelo.txt - EOF \ No newline at end of file