Conway's game of life applied to the mbed and an RA8875 LCD.
Dependencies: LifeRules mbed RA8875
main.cpp
00001 // game of life implementation inspired by this forum thread 00002 // http://mbed.org/forum/helloworld/topic/4822/ 00003 // 00004 #include "mbed.h" // v122 00005 #include "RA8875.h" // v126 00006 #include "LifeRules.h" // v3 00007 00008 // These two defines can be enabled, or commented out 00009 #define BIG_SCREEN 00010 #define CAP_TOUCH 00011 #define LCD_C 16 // color - bits per pixel 00012 00013 #ifdef CAP_TOUCH 00014 RA8875 lcd(p5,p6,p7,p12,NC, p9,p10,p13, "tft"); // MOSI,MISO,SCK,/ChipSelect,/reset, SDA,SCL,/IRQ, name 00015 #else 00016 RA8875 lcd(p5,p6,p7,p12,NC, "tft"); //MOSI, MISO, SCK, /ChipSelect, /reset, name 00017 LocalFileSystem local("local"); // access to calibration file for resistive touch. 00018 #endif 00019 00020 #ifdef BIG_SCREEN 00021 #define LCD_W 800 00022 #define LCD_H 480 00023 #else 00024 #define LCD_W 480 00025 #define LCD_H 272 00026 #endif 00027 00028 00029 // Define the life-map size 00030 #define LIFE_W 150 00031 #define LIFE_H 100 00032 #define LIFE_C 2 /* 1 = monochrome, 2 = color */ 00033 #define LIFE_Z 2 /* Zoom factor */ 00034 00035 // Try to check if there is enough memory (for LPC1768) 00036 #if LIFE_W * LIFE_H * LIFE_C * 2 / 8 > 0x8000 00037 #error "Sorry, but there isn't this much memory on an LPC1768" 00038 #endif 00039 00040 extern "C" void mbed_reset(); 00041 00042 //#define DEBUG "main" 00043 // ... 00044 // INFO("Stuff to show %d", var); // new-line is automatically appended 00045 // 00046 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00047 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00048 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00049 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00050 #else 00051 #define INFO(x, ...) 00052 #define WARN(x, ...) 00053 #define ERR(x, ...) 00054 #endif 00055 00056 00057 #if LIFE_C == 2 00058 #define LIFE_CLR Life::color 00059 #else 00060 #define LIFE_CLR Life::monochrome 00061 #endif 00062 00063 Life life(LIFE_W, LIFE_H, LIFE_CLR); 00064 00065 // Where on screen do we locate it? 00066 #if LIFE_W * LIFE_Z < LCD_W 00067 #define H_OFFSET -1 00068 #else 00069 #define H_OFFSET 0 00070 #endif 00071 00072 #if LIFE_H * LIFE_Z < LCD_H 00073 #define V_OFFSET -1 00074 #else 00075 #define V_OFFSET 0 00076 #endif 00077 00078 #define LIFE_OFFSET_X (LCD_W - (LIFE_W * LIFE_Z) + H_OFFSET) 00079 #define LIFE_OFFSET_Y (LCD_H - (LIFE_H * LIFE_Z) + V_OFFSET) 00080 00081 unsigned char imgbuffer[3*LIFE_W]; // from forum thread... 00082 FILE *img; 00083 00084 Serial pc(USBTX,USBRX); // for debugging 00085 00086 int msDelay = 1000; //delay between frames 00087 00088 void CheckForUserInteraction(void); 00089 void genrand(); //random start 00090 void genglidergun(); //glider gun 00091 void genglider(); //glider 00092 void genship1(); //light weight ship 00093 void genBMP(); //from image 00094 void gentest(); 00095 void genBlinker(); 00096 00097 void ScreenUpdate() 00098 { 00099 lcd.SetWindow(LIFE_OFFSET_X, LIFE_OFFSET_Y, LIFE_W * LIFE_Z, LIFE_H * LIFE_Z); 00100 lcd.SetGraphicsCursor(LIFE_OFFSET_X+1, LIFE_OFFSET_Y+1); 00101 pc.printf("window(%d,%d, %d,%d)\r\n", LIFE_OFFSET_X, LIFE_OFFSET_Y, LIFE_W * LIFE_Z, LIFE_H * LIFE_Z); 00102 lcd._StartGraphicsStream(); 00103 for (int j = 0; j < LIFE_H; j++) { 00104 for (int Zx = 0; Zx < LIFE_Z; Zx++) { 00105 for (int i = 0; i < LIFE_W; i++) { 00106 Life::ValueOfLife lifeState = life.getbit(i,j); 00107 color_t p; 00108 switch (lifeState) { 00109 case Life::dead: 00110 p = RGB(0,0,0); 00111 break; 00112 case Life::dying: 00113 p = RGB(192,0,0); 00114 break; 00115 case Life::living: 00116 p = RGB(64,255,64); 00117 break; 00118 case Life::birthing: 00119 p = RGB(0,0,192); 00120 break; 00121 default: 00122 p = RGB(192,192,0); // Should never see this one... 00123 ERR(" lifeState = %d\r\n", lifeState); 00124 break; 00125 } 00126 for (int Zy = 0; Zy < LIFE_Z; Zy++) { 00127 lcd._putp(p); 00128 } 00129 } 00130 } 00131 } 00132 lcd._EndGraphicsStream(); 00133 lcd.SetWindow(); 00134 } 00135 00136 int GetScreenCapture(void) 00137 { 00138 char fqfn[50]; 00139 int i = 0; 00140 00141 pc.printf("Screen Capture... "); 00142 for (i=1; i< 100; i++) { 00143 snprintf(fqfn, sizeof(fqfn), "/local/Screen%02d.bmp", i); 00144 FILE * fh = fopen(fqfn, "rb"); 00145 if (!fh) { 00146 lcd.PrintScreen(0,0,LCD_W,LCD_H,fqfn); 00147 pc.printf(" as /local/Screen%02d.bmp\r\n", i); 00148 return i; 00149 } else { 00150 fclose(fh); // close this and try the next 00151 } 00152 } 00153 return 0; 00154 } 00155 00156 00157 int main() 00158 { 00159 pc.baud(460800); // I like a snappy terminal, so crank it up! 00160 pc.printf("\r\nConway's Game of Life - Build " __DATE__ " " __TIME__ "\r\n"); 00161 00162 lcd.init(LCD_W, LCD_H, LCD_C); 00163 lcd.Backlight(0.5f); 00164 00165 //lcd.frequency(5000000); 00166 lcd.puts("Welcome to Conway's Game of Life\r\n\r\n"); 00167 INFO("Destroy all life"); 00168 life.DestroyAllLife(); 00169 INFO("Life destroyed"); 00170 00171 lcd.foreground(RGB(255,255,255)); 00172 00173 //pc.printf("choice value = %d\n\r",choice); //for debugging 00174 lcd.puts("Please Select Starting Configuration:\r\n"); 00175 lcd.puts(" 0 = Glider 1 = Random\r\n" 00176 " 2 = Ship 3 = Glider Gun\r\n" 00177 " 4 = BMP image 5 = Blinker\r\n" 00178 " t = test \r\n" 00179 " r = reset\r\n" 00180 ); 00181 00182 // Frame the life map 00183 lcd.rect(LIFE_OFFSET_X-1,LIFE_OFFSET_Y-1,LIFE_OFFSET_X+LIFE_W*LIFE_Z,LIFE_OFFSET_Y+LIFE_H*LIFE_Z,Red); 00184 lcd.foreground(Blue); 00185 int choice = pc.getc(); 00186 00187 switch ( choice ) { 00188 case '0': 00189 lcd.puts(">Glider!\r\n"); 00190 genglider(); 00191 break; 00192 case '1': 00193 lcd.puts(">Random!\r\n"); 00194 genrand(); 00195 break; 00196 case '2': 00197 lcd.puts(">Ship!\r\n"); 00198 genship1(); 00199 break; 00200 case '3': 00201 lcd.puts(">Glider Gun!\r\n"); 00202 genglidergun(); 00203 break; 00204 case '4': 00205 lcd.puts(">BMP image!\r\n"); 00206 genBMP(); 00207 break; 00208 case '5': 00209 lcd.puts(">Blinker!\r\n"); 00210 genBlinker(); 00211 break; 00212 case 't': 00213 lcd.puts(">test!\r\n"); 00214 gentest(); 00215 break; 00216 } 00217 lcd.puts("\r\nRuntime Menu:\r\n" 00218 " p = PrintScreen\r\n" 00219 " + = faster\r\n" 00220 " - = slower\r\n" 00221 " 0-9 = updates/sec\r\n" 00222 ); 00223 00224 ScreenUpdate(); 00225 wait(1); 00226 00227 while(1) { 00228 CheckForUserInteraction(); 00229 if (msDelay >= 0) { 00230 static uint16_t toggle = 0; 00231 00232 if ((++toggle & 1) == 0) { 00233 life.GenerationStep(); 00234 } else { 00235 life.UpdateLifeCycle(); 00236 } 00237 ScreenUpdate(); 00238 wait_ms(msDelay); 00239 } 00240 } 00241 } 00242 00243 void CheckForUserInteraction(void) 00244 { 00245 while (pc.readable()) { 00246 int c = pc.getc(); 00247 if (c == '+' && msDelay >= 0) 00248 msDelay -= 10; 00249 else if (c == '-' && msDelay < 1000) 00250 msDelay += 10; 00251 else if (c >= '0' && c <= '9') { 00252 if (c == '0') 00253 msDelay = -1; 00254 else 00255 msDelay = 10 * ((1000 / (c - '0'))/10); 00256 } else if (c == 'r') 00257 mbed_reset(); 00258 else if (c == 'p') 00259 GetScreenCapture(); 00260 lcd.locate(49, 0); 00261 if (msDelay < 0) { 00262 msDelay = -10; 00263 lcd.printf("Paused "); 00264 } else { 00265 lcd.printf("Delay %4d", msDelay); 00266 } 00267 } 00268 } 00269 00270 00271 void genBlinker() 00272 { 00273 life.setbit(1,1, Life::living); 00274 life.setbit(1,2, Life::living); 00275 life.setbit(1,3, Life::living); 00276 } 00277 00278 void gentest() 00279 { 00280 // Point 00281 life.setbit(6,3, Life::living); 00282 // Block 00283 life.setbit(1,1, Life::living); 00284 life.setbit(1,2, Life::living); 00285 life.setbit(2,1, Life::living); 00286 life.setbit(2,2, Life::living); 00287 // Beehive 00288 life.setbit(6,1, Life::living); 00289 life.setbit(7,1, Life::living); 00290 life.setbit(5,2, Life::living); 00291 life.setbit(8,2, Life::living); 00292 life.setbit(6,3, Life::living); 00293 life.setbit(7,3, Life::living); 00294 // Blinker 00295 life.setbit(11,2, Life::living); 00296 life.setbit(12,2, Life::living); 00297 life.setbit(13,2, Life::living); 00298 // Glider 00299 // x 00300 // x 00301 // xxx 00302 life.setbit(2,10, Life::living); 00303 life.setbit(3,11, Life::living); 00304 life.setbit(1,12, Life::living); 00305 life.setbit(2,12, Life::living); 00306 life.setbit(3,12, Life::living); 00307 } 00308 00309 00310 void genrand() 00311 { 00312 for (int i = 0; i < LIFE_W; i++) { //loop through each cell 00313 for (int j = 0; j < LIFE_H; j++) { 00314 if (rand() & 1) { //50% chance 00315 life.setbit(i,j, Life::living); 00316 } 00317 } 00318 } 00319 } 00320 00321 void genBMP() 00322 { 00323 for (int i = 0; i < LIFE_W; i++) { 00324 img = fopen("/local/TESTIM~1.BMP", "rb"); 00325 fseek (img , 54 + (LIFE_W*i*3) , SEEK_SET); 00326 fread(imgbuffer, (LIFE_W*3), 1, img); 00327 fclose(img); 00328 for (int j = 0; j < LIFE_H; j++) { 00329 int red = imgbuffer[j*3]; 00330 if (red == 0) { 00331 life.setbit(j, LIFE_H - 1 - i, Life::living); 00332 } 00333 } 00334 } 00335 } 00336 00337 00338 void genglider() //set certain pixels 00339 { 00340 life.setbit(0,0, Life::living); 00341 life.setbit(1,1, Life::living); 00342 life.setbit(1,2, Life::living); 00343 life.setbit(2,0, Life::living); 00344 life.setbit(2,1, Life::living); 00345 } 00346 00347 void genglidergun() //set certain pixels 00348 { 00349 life.setbit(0,7, Life::living); //gun 00350 life.setbit(0,8, Life::living); 00351 life.setbit(1,7, Life::living); 00352 life.setbit(1,8, Life::living); 00353 life.setbit(8,8, Life::living); 00354 life.setbit(8,9, Life::living); 00355 life.setbit(9,7, Life::living); 00356 life.setbit(9,9, Life::living); 00357 life.setbit(10,7, Life::living); 00358 life.setbit(10,8, Life::living); 00359 life.setbit(16,9, Life::living); 00360 life.setbit(16,10, Life::living); 00361 life.setbit(16,11, Life::living); 00362 life.setbit(17,9, Life::living); 00363 life.setbit(18,10, Life::living); 00364 life.setbit(22,6, Life::living); 00365 life.setbit(22,7, Life::living); 00366 life.setbit(23,5, Life::living); 00367 life.setbit(23,7, Life::living); 00368 life.setbit(24,5, Life::living); 00369 life.setbit(24,6, Life::living); 00370 life.setbit(24,17, Life::living); 00371 life.setbit(24,18, Life::living); 00372 life.setbit(25,17, Life::living); 00373 life.setbit(25,19, Life::living); 00374 life.setbit(26,17, Life::living); 00375 life.setbit(34,5, Life::living); 00376 life.setbit(34,6, Life::living); 00377 life.setbit(35,5, Life::living); 00378 life.setbit(35,6, Life::living); 00379 life.setbit(35,12, Life::living); 00380 life.setbit(35,13, Life::living); 00381 life.setbit(35,14, Life::living); 00382 life.setbit(36,12, Life::living); 00383 life.setbit(37,13, Life::living); 00384 00385 life.setbit(50,38, Life::living); //eater 00386 life.setbit(51,38, Life::living); 00387 life.setbit(50,39, Life::living); 00388 life.setbit(52,39, Life::living); 00389 life.setbit(52,40, Life::living); 00390 life.setbit(52,41, Life::living); 00391 life.setbit(53,41, Life::living); 00392 } 00393 00394 void genship1() //set certain pixels 00395 { 00396 life.setbit(10,10, Life::living); 00397 life.setbit(13,10, Life::living); 00398 life.setbit(14,11, Life::living); 00399 life.setbit(10,12, Life::living); 00400 life.setbit(14,12, Life::living); 00401 life.setbit(11,13, Life::living); 00402 life.setbit(12,13, Life::living); 00403 life.setbit(13,13, Life::living); 00404 life.setbit(14,13, Life::living); 00405 } 00406 00407 00408
Generated on Tue Jul 12 2022 20:05:01 by 1.7.2