blob: ce61d7a3830530db2442dc18505f87bd7f4e3189 [file] [log] [blame]
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 Pierre Delore
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "plugin.h"
22
23#ifdef HAVE_LCD_CHARCELLS
24
Jens Arnolda36b1d42006-01-15 18:20:18 +000025/* NIM game for the player
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000026
27Rules of nim game
28-----------------
29There are 21 matches.
30Two players (you and the cpu) alternately pick a certain number of matches and the one,
31who takes the last match, loses.
32
33
34History:
35-------
36V1.0 : 2003-07-22
37 First release of the game
38V1.1 : 2003-07-22
39 I Change the patterns definition in order to have a clean code
40V1.2 : 2003-07-30
41 Patch from JB that change:
42 . the win and lose message
43 . the BUTTON_STOP code
44 . Add a test
45 I suppress the exit variable
46 I suppress or translates the comments which were in French
47 I put min=1 at the of the main loop ( When there are 21 matches you can decide not to
48 take a match. Later you are obliged to take at least one.)
49*/
50
Jens Arnolda36b1d42006-01-15 18:20:18 +000051PLUGIN_HEADER
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000052
53/*Pattern for the game*/
54static unsigned char smile[]={0x00, 0x11, 0x04, 0x04, 0x00, 0x11, 0x0E}; /* :-) */
55static unsigned char cry[] ={0x00, 0x11, 0x04, 0x04, 0x00, 0x0E, 0x11}; /* :-( */
56static unsigned char pattern3[]={0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15}; /*3 parts*/
57static unsigned char pattern2[]={0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14}; /*2 parts*/
58static unsigned char pattern1[]={0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}; /*1 part*/
59
60static unsigned char str[12]; /*String use to display the first line*/
Jens Arnoldad4e3d62007-03-26 07:52:13 +000061static unsigned long hsmile,hcry,h1,h2; /*Handle for the new pattern*/
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000062
63static bool end; /*If true game is finished*/
Steve Bavin65265772008-05-13 09:57:56 +000064static const struct plugin_api* rb;
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000065
66
67/*Display that the action it's impossible*/
68static void impossible(void)
69{
70 rb->lcd_puts(0,1,"Impossible!");
Jens Arnoldf9b90e92007-04-06 22:55:00 +000071 rb->lcd_update();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000072 rb->sleep(HZ);
73 return;
74}
75
76/*Display that the CPU lose :) */
77static void lose(void)
78{
79 rb->lcd_define_pattern(hsmile,smile);
Jens Arnoldad4e3d62007-03-26 07:52:13 +000080 rb->lcd_puts(0,1,"You Win!!");
81 rb->lcd_putc(8,1,hsmile);
Jens Arnoldf9b90e92007-04-06 22:55:00 +000082 rb->lcd_update();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000083 end=true;
84 rb->sleep(HZ*2);
85 return;
86}
87
88
89/* Display that the CPU win :( */
90static void win(void)
91{
92 rb->lcd_define_pattern(hcry,cry);
Jens Arnoldad4e3d62007-03-26 07:52:13 +000093 rb->lcd_puts(0,1,"You Lose!!");
94 rb->lcd_putc(9,1,hcry);
Jens Arnoldf9b90e92007-04-06 22:55:00 +000095 rb->lcd_update();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +000096 end=true;
97 rb->sleep(HZ*2);
98 return;
99}
100
101
102/*Display the first line*/
103static void display_first_line(int x)
104{
105 int i;
106
107 rb->snprintf(str,sizeof(str)," =%d",x);
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000108 rb->lcd_puts(0,0,str);
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000109
110 rb->lcd_define_pattern(h1,pattern3);
Jens Arnoldf9b90e92007-04-06 22:55:00 +0000111 for (i=0;i<x/3;i++)
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000112 rb->lcd_putc(i,0,h1);
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000113
114 if (x%3==2)
115 {
116 rb->lcd_define_pattern(h2,pattern2);
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000117 rb->lcd_putc(i,0,h2);
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000118 }
119 if (x%3==1)
120 {
121 rb->lcd_define_pattern(h2,pattern1);
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000122 rb->lcd_putc(i,0,h2);
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000123 }
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000124}
125
126/* Call when the program end */
Jens Arnold2afdf952004-10-22 00:22:07 +0000127static void nim_exit(void *parameter)
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000128{
Jens Arnold2afdf952004-10-22 00:22:07 +0000129 (void)parameter;
130
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000131 /*Restore the old pattern*/
132 rb->lcd_unlock_pattern(h1);
133 rb->lcd_unlock_pattern(h2);
134 rb->lcd_unlock_pattern(hsmile);
135 rb->lcd_unlock_pattern(hcry);
136
137 /*Clear the screen*/
138 rb->lcd_clear_display();
Jens Arnoldf9b90e92007-04-06 22:55:00 +0000139 rb->lcd_update();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000140}
141
142/* this is the plugin entry point */
Steve Bavin65265772008-05-13 09:57:56 +0000143enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000144{
145 int y,z,button;
146 int x,v,min;
147 bool ok;
148 bool go;
149
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000150 /* if you don't use the parameter, you can do like
151 this to avoid the compiler warning about it */
152 (void)parameter;
153
154 /* if you are using a global api pointer, don't forget to copy it!
155 otherwise you will get lovely "I04: IllInstr" errors... :-) */
156 rb = api;
157
158 /*Get the pattern handle*/
159 h1=rb->lcd_get_locked_pattern();
160 h2=rb->lcd_get_locked_pattern();
161 hcry=rb->lcd_get_locked_pattern();
162 hsmile=rb->lcd_get_locked_pattern();
163
164
Jens Arnold4d6374c2007-03-16 21:56:08 +0000165 rb->splash(HZ, "NIM V1.2");
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000166 rb->lcd_clear_display();
167
168 /* Main loop */
169 while (1)
170 {
171 /* Init */
172 x=21;
173 v=1;
174 y=1;
175 end=false;
176 min=0;
177
178 /*Empty the event queue*/
Jens Arnold3c348df2005-01-26 22:48:25 +0000179 rb->button_clear_queue();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000180
181 /* Game loop */
182 while(end!=true)
183 {
184 do
185 {
186 ok=1;
187 y=1;
188 display_first_line(x);
189
190 rb->snprintf(str,sizeof(str),"[%d..%d]?=%d",min,v,y);
191 rb->lcd_puts(0,1,str);
Jens Arnoldf9b90e92007-04-06 22:55:00 +0000192 rb->lcd_update();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000193
194 go=false;
195 while (!go)
196 {
197 button = rb->button_get(true);
198 switch ( button )
199 {
200 case BUTTON_STOP|BUTTON_REL:
201 go = true;
Jens Arnold2afdf952004-10-22 00:22:07 +0000202 nim_exit(NULL);
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000203 return PLUGIN_OK;
204 break;
205
206 case BUTTON_PLAY|BUTTON_REL:
207 go=true;
208 break;
209
210 case BUTTON_LEFT|BUTTON_REL:
211 go=false;
212 if (y>min)
213 y--;
214 break;
215
216 case BUTTON_RIGHT|BUTTON_REL:
217 go=false;
218 if (y<v)
219 y++;
220 break;
221
Jens Arnold2afdf952004-10-22 00:22:07 +0000222 default:
223 if (rb->default_event_handler_ex(button, nim_exit,
224 NULL) == SYS_USB_CONNECTED)
225 return PLUGIN_USB_CONNECTED;
226 break;
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000227 }
228 display_first_line(x);
229 rb->snprintf(str,sizeof(str),"[%d..%d]?=%d",min,v,y);
230 rb->lcd_puts(0,1,str);
Jens Arnoldf9b90e92007-04-06 22:55:00 +0000231 rb->lcd_update();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000232 }
233
234 if ( (y==0) && (x<21))
235 {
236 impossible();
237 ok=false;
238 }
239 else
240 {
241 if (y!=0) /*If y=0 and x=21 jump to CPU code */
242 {
243 if ((y>v) || (y>x))
244 {
245 impossible();
246 ok=false;
247 }
248 if (y-x==0)
249 win();
250 else
251 {
252 v=y*2;
253 x-=y;
254 }
255 }
256 }
257 }
258 while (ok==false);
259
260 display_first_line(x);
261
262 /*CPU*/
263 if (x==1)
264 lose();
265 else
266 if (x==2)
267 win();
268 y=0;
269 if (end==false)
270 {
271 for (z=v;z>=1;z--)
272 {
273 if (x-z==1)
274 y=z;
275 }
276 if (y<=0)
277 {
278 for(z=v;z>=1;z--)
279 {
280 if(x-(z*3)==2)
281 y=z;
282 }
283 if ((y==0) && (x>14))
284 y=v;
285 if (y==0)
286 y=1;
287 }
288 v=y*2;
289 x-=y;
290 rb->snprintf(str,sizeof(str),"I take=%d",y);
291 rb->lcd_puts(0,1,str);
Jens Arnoldf9b90e92007-04-06 22:55:00 +0000292 rb->lcd_update();
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000293 rb->sleep(HZ);
294 }
295 if ((x==1)&&(!end))
296 win();
297 min=1;
298 }
299 }
Jens Arnold2afdf952004-10-22 00:22:07 +0000300 nim_exit(NULL);
Linus Nielsen Feltzingc70a7502003-11-04 00:30:49 +0000301 return PLUGIN_OK;
302}
303#endif