Add missing keymaps for the c200, h100, and h300 to the manual. Long-record to enter...
[Rockbox.git] / apps / plugins / nim.c
blobae3297d458761ab5dbcd4124da48b4afcf4f1fa4
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2003 Pierre Delore
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "plugin.h"
21 #ifdef HAVE_LCD_CHARCELLS
23 /* NIM game for the player
25 Rules of nim game
26 -----------------
27 There are 21 matches.
28 Two players (you and the cpu) alternately pick a certain number of matches and the one,
29 who takes the last match, loses.
32 History:
33 -------
34 V1.0 : 2003-07-22
35 First release of the game
36 V1.1 : 2003-07-22
37 I Change the patterns definition in order to have a clean code
38 V1.2 : 2003-07-30
39 Patch from JB that change:
40 . the win and lose message
41 . the BUTTON_STOP code
42 . Add a test
43 I suppress the exit variable
44 I suppress or translates the comments which were in French
45 I put min=1 at the of the main loop ( When there are 21 matches you can decide not to
46 take a match. Later you are obliged to take at least one.)
49 PLUGIN_HEADER
51 /*Pattern for the game*/
52 static unsigned char smile[]={0x00, 0x11, 0x04, 0x04, 0x00, 0x11, 0x0E}; /* :-) */
53 static unsigned char cry[] ={0x00, 0x11, 0x04, 0x04, 0x00, 0x0E, 0x11}; /* :-( */
54 static unsigned char pattern3[]={0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15}; /*3 parts*/
55 static unsigned char pattern2[]={0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14}; /*2 parts*/
56 static unsigned char pattern1[]={0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}; /*1 part*/
58 static unsigned char str[12]; /*String use to display the first line*/
59 static unsigned long hsmile,hcry,h1,h2; /*Handle for the new pattern*/
61 static bool end; /*If true game is finished*/
62 static const struct plugin_api* rb;
65 /*Display that the action it's impossible*/
66 static void impossible(void)
68 rb->lcd_puts(0,1,"Impossible!");
69 rb->lcd_update();
70 rb->sleep(HZ);
71 return;
74 /*Display that the CPU lose :) */
75 static void lose(void)
77 rb->lcd_define_pattern(hsmile,smile);
78 rb->lcd_puts(0,1,"You Win!!");
79 rb->lcd_putc(8,1,hsmile);
80 rb->lcd_update();
81 end=true;
82 rb->sleep(HZ*2);
83 return;
87 /* Display that the CPU win :( */
88 static void win(void)
90 rb->lcd_define_pattern(hcry,cry);
91 rb->lcd_puts(0,1,"You Lose!!");
92 rb->lcd_putc(9,1,hcry);
93 rb->lcd_update();
94 end=true;
95 rb->sleep(HZ*2);
96 return;
100 /*Display the first line*/
101 static void display_first_line(int x)
103 int i;
105 rb->snprintf(str,sizeof(str)," =%d",x);
106 rb->lcd_puts(0,0,str);
108 rb->lcd_define_pattern(h1,pattern3);
109 for (i=0;i<x/3;i++)
110 rb->lcd_putc(i,0,h1);
112 if (x%3==2)
114 rb->lcd_define_pattern(h2,pattern2);
115 rb->lcd_putc(i,0,h2);
117 if (x%3==1)
119 rb->lcd_define_pattern(h2,pattern1);
120 rb->lcd_putc(i,0,h2);
124 /* Call when the program end */
125 static void nim_exit(void *parameter)
127 (void)parameter;
129 /*Restore the old pattern*/
130 rb->lcd_unlock_pattern(h1);
131 rb->lcd_unlock_pattern(h2);
132 rb->lcd_unlock_pattern(hsmile);
133 rb->lcd_unlock_pattern(hcry);
135 /*Clear the screen*/
136 rb->lcd_clear_display();
137 rb->lcd_update();
140 /* this is the plugin entry point */
141 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
143 int y,z,button;
144 int x,v,min;
145 bool ok;
146 bool go;
148 /* if you don't use the parameter, you can do like
149 this to avoid the compiler warning about it */
150 (void)parameter;
152 /* if you are using a global api pointer, don't forget to copy it!
153 otherwise you will get lovely "I04: IllInstr" errors... :-) */
154 rb = api;
156 /*Get the pattern handle*/
157 h1=rb->lcd_get_locked_pattern();
158 h2=rb->lcd_get_locked_pattern();
159 hcry=rb->lcd_get_locked_pattern();
160 hsmile=rb->lcd_get_locked_pattern();
163 rb->splash(HZ, "NIM V1.2");
164 rb->lcd_clear_display();
166 /* Main loop */
167 while (1)
169 /* Init */
170 x=21;
171 v=1;
172 y=1;
173 end=false;
174 min=0;
176 /*Empty the event queue*/
177 rb->button_clear_queue();
179 /* Game loop */
180 while(end!=true)
184 ok=1;
185 y=1;
186 display_first_line(x);
188 rb->snprintf(str,sizeof(str),"[%d..%d]?=%d",min,v,y);
189 rb->lcd_puts(0,1,str);
190 rb->lcd_update();
192 go=false;
193 while (!go)
195 button = rb->button_get(true);
196 switch ( button )
198 case BUTTON_STOP|BUTTON_REL:
199 go = true;
200 nim_exit(NULL);
201 return PLUGIN_OK;
202 break;
204 case BUTTON_PLAY|BUTTON_REL:
205 go=true;
206 break;
208 case BUTTON_LEFT|BUTTON_REL:
209 go=false;
210 if (y>min)
211 y--;
212 break;
214 case BUTTON_RIGHT|BUTTON_REL:
215 go=false;
216 if (y<v)
217 y++;
218 break;
220 default:
221 if (rb->default_event_handler_ex(button, nim_exit,
222 NULL) == SYS_USB_CONNECTED)
223 return PLUGIN_USB_CONNECTED;
224 break;
226 display_first_line(x);
227 rb->snprintf(str,sizeof(str),"[%d..%d]?=%d",min,v,y);
228 rb->lcd_puts(0,1,str);
229 rb->lcd_update();
232 if ( (y==0) && (x<21))
234 impossible();
235 ok=false;
237 else
239 if (y!=0) /*If y=0 and x=21 jump to CPU code */
241 if ((y>v) || (y>x))
243 impossible();
244 ok=false;
246 if (y-x==0)
247 win();
248 else
250 v=y*2;
251 x-=y;
256 while (ok==false);
258 display_first_line(x);
260 /*CPU*/
261 if (x==1)
262 lose();
263 else
264 if (x==2)
265 win();
266 y=0;
267 if (end==false)
269 for (z=v;z>=1;z--)
271 if (x-z==1)
272 y=z;
274 if (y<=0)
276 for(z=v;z>=1;z--)
278 if(x-(z*3)==2)
279 y=z;
281 if ((y==0) && (x>14))
282 y=v;
283 if (y==0)
284 y=1;
286 v=y*2;
287 x-=y;
288 rb->snprintf(str,sizeof(str),"I take=%d",y);
289 rb->lcd_puts(0,1,str);
290 rb->lcd_update();
291 rb->sleep(HZ);
293 if ((x==1)&&(!end))
294 win();
295 min=1;
298 nim_exit(NULL);
299 return PLUGIN_OK;
301 #endif