Last active
December 18, 2016 21:11
-
-
Save spitty/8f62e84276f0f320e53b66a7631dc2a5 to your computer and use it in GitHub Desktop.
Revisions
-
spitty revised this gist
Dec 18, 2016 . 1 changed file with 0 additions and 327 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,327 +0,0 @@ -
spitty revised this gist
Dec 18, 2016 . 1 changed file with 327 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,327 @@ /* This Arduino sketch shows QR-code with word 'AMAZING' and a heart in the right side of GLCD-display. Used parts: - Library openGLCD https://bitbucket.org/bperrybap/openglcd/wiki/Home - example life.pde "John Conway's Game of Life for openGLCD" Author: Maxim Logunov [email protected] Date: 2016-12-17 */ #include <openGLCD.h> /********* user configurable defines ************/ #define CELL_SIZE 4 // the height and width of each cell #define DELAY 50 // number of milliseconds delay between the display of each generation /******* end of user configurable defines ********/ #define ROWS (DISPLAY_HEIGHT / CELL_SIZE) #define COLUMNS (DISPLAY_WIDTH / 2 / CELL_SIZE) // Modification: // ^ use only half of display // #define BYTES_PER_COLUMN ((COLUMNS + 7)/ 8) //this is the number of bytes needed to hold a column #define MAX_ITERATIONS 500 // iterations are terminated if this number is exceeded #define STABLE_GENERATIONS 4 // must be at least 2, this is the number of back generations checked for stability #define MIN_OBJECTS 2 // minmum number of objects to be seeded by the random generater #define MAX_OBJECTS 4 // maximum number of objects for random seed generator #define MARGIN 4 // minimum distance from screen edge for randomly seeded objects #define BITVAL(_pos) (1<< (7-(_pos % 8))) // macro to get a bitfield value #define ALIVE true #define DEAD false /* ======== Life Objects ======== * these objects can be displayed on the Arduino life screen * to add an object, create and initialise a structure following the examples here * add a reference to your structure to the object table, name your object by adding to the enum list */ // structure template for life objects typedef struct { byte height ; byte width ; byte bitfield[]; } object_t, *object_ptr_t; // definitions and initialisations for all defined objects here struct { byte height ; byte width ; byte bitfield[2]; } static table = {2,4, { 0b10010000 , // * * 0b11110000 } }; // **** struct { byte height ; byte width ; byte bitfield[3]; } static glider = {3,3, { 0b00100000 , // * 0b10100000 , // * * 0b01100000 }}; // ** #ifdef NOTUSED struct { byte height ; byte width ; byte bitfield[3]; } static glider2 = {3,3, { 0b10100000 , // * * 0b11000000 , // ** 0b11110000 }}; // **** #endif struct { byte height ; byte width ; byte bitfield[4]; } static loaf = {4,4, { 0b01100000 , // ** 0b10010000 , // * * 0b01010000 , // * * 0b00100000 }}; // * struct { byte height ; byte width ; byte bitfield[3]; } static ship = {3,3, { 0b11000000 , // ** 0b10100000 , // * * 0b01100000 }}; // ** struct { byte height ; byte width ; byte bitfield[4]; } static behive = {4,3, { 0b01000000 , // * 0b10100000 , // * * 0b10100000 , // * * 0b01000000}}; // * struct { byte height ; byte width ; byte bitfield[1]; } static blinker = {1,3, { 0b11100000 }}; // *** struct { byte height ; byte width ; byte bitfield[2]; } static block = {2,2, { 0b11000000 , // ** 0b11000000}}; // ** // place all the objects in the object table object_ptr_t objectTable[] = { (object_ptr_t)&table, (object_ptr_t)&glider, (object_ptr_t)&loaf, (object_ptr_t)&ship, (object_ptr_t)&behive, (object_ptr_t)&blinker, (object_ptr_t)&block }; #define OBJECT_COUNT (sizeof( objectTable/ sizeof(object_ptr_t))) // enumerate all the objects, add any new objects to the end of this enum (note case difference ) // the life program references all objects using the names in this list enum {Table,Glider,Loaf,Ship,Behive,Blinker,Block}; byte generations[STABLE_GENERATIONS][ROWS][BYTES_PER_COLUMN]; // array used to calculate, draw and check if iterations are changing // This part descripbes QR-code #define RECTSIZE 21 #define PXSIZE 2 const int bits[RECTSIZE][RECTSIZE] = {{0,0,0,0,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,0,0}, {0,1,1,1,1,1,0,1,1,0,1,1,0,1,0,1,1,1,1,1,0}, {0,1,0,0,0,1,0,1,1,0,1,1,1,1,0,1,0,0,0,1,0}, {0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0}, {0,1,0,0,0,1,0,1,1,1,1,0,1,1,0,1,0,0,0,1,0}, {0,1,1,1,1,1,0,1,1,0,1,0,0,1,0,1,1,1,1,1,0}, {0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,0,1,0,0,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0}, {1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,1,0,1}, {0,1,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,1}, {1,0,1,1,1,0,1,1,0,0,0,0,0,1,1,1,1,1,0,1,1}, {0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,1,0,1,0,0,1}, {1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,0,0,1,1}, {0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1}, {0,1,1,1,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,0}, {0,1,0,0,0,1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,0}, {0,1,0,0,0,1,0,1,1,1,0,0,1,1,0,0,1,0,1,0,1}, {0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0}, {0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,0,1,1,1,0,0}, {0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,1,0,0,0,1,0}}; void setup(){ GLCD.Init(); // initialise the library, non inverted writes pixels onto a clear screen GLCD.SelectFont(System5x7); GLCD.DrawString("Life", gTextfmt_center, gTextfmt_center); delay(1000); // ^ delay decreased seed(3); } void loop (void){ GLCD.ClearScreen(); // Draw QR-code for (int i = 0; i < RECTSIZE; i++) { for (int j = 0; j < RECTSIZE; j++) { uint8_t color = (bits[i][j] == 0 ? PIXEL_ON : PIXEL_OFF); GLCD.FillRect(75 + j * PXSIZE, 11 + i * PXSIZE, 2, 2, color); } } unsigned int i = generate(); GLCD.CursorTo(0,0); GLCD.print(i); GLCD.print(" iterations"); delay(2000); seed(1); // use random seed } unsigned int generate(){ unsigned int iteration = 0; byte thisGeneration,nextGeneration; thisGeneration = nextGeneration = 0; //display the initial array for(int row = 0; row < ROWS; row++) { for(int column = 0; column < COLUMNS; column++) { if(isAlive(thisGeneration,row,column)) GLCD.DrawRoundRect(column * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE, CELL_SIZE/2, BLACK) ; else GLCD.DrawRoundRect(column * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE, CELL_SIZE/2, WHITE) ; } } delay(1500); // show the seeded condition a little longer do{ thisGeneration = iteration % STABLE_GENERATIONS; nextGeneration = (thisGeneration+1) % STABLE_GENERATIONS; delay(DELAY); memset(generations[nextGeneration],0,sizeof(generations[0])); // clear the array for the next generation //see who lives and who dies for(int row = 0; row < ROWS; row++){ for(int column = 0; column < COLUMNS; column++){ boolean cell = isAlive(thisGeneration,row,column); byte n = getNeighborCount(thisGeneration,row,column); if(cell == DEAD){ if(n==3) { setLife(nextGeneration,row,column,ALIVE); // birth GLCD.DrawRoundRect(column * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE, CELL_SIZE/2, BLACK) ; } } else{ if(n==2 || n==3) { setLife(nextGeneration,row,column,ALIVE); //survival // No need to draw cell as it is already there. } else { setLife(nextGeneration,row,column,DEAD); //death GLCD.DrawRoundRect(column * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE, CELL_SIZE/2, WHITE) ; } } } } } while(isStable(thisGeneration) == false && ++iteration < MAX_ITERATIONS ) ; return iteration; } void seed(int seedValue){ // a hard coded seed is used if seedvalue is zero, otherwise a random seed is used memset(generations,0,sizeof(generations)); // clear all generation arrays if(seedValue == 0){ // load default objects, arguments are offsets from the center of the screen loadObject(Table,2,-9); // put a table object 2 down from the center and 9 columns left or center loadObject(Glider, -5,-9); // put a glider 5 rows above the center and 9 columns left of center } else{ // load some random objects and place at random positions byte nbrObjects = random(MIN_OBJECTS,MAX_OBJECTS+1); // make a random number of objects for(byte i=0; i < nbrObjects;i++){ byte obj = random(7); // OBJECT_COUNT); int column = random(MARGIN - (COLUMNS/2), (COLUMNS/2) - MARGIN); int row = random(MARGIN - (ROWS/2) , (ROWS/2) - MARGIN); loadObject(obj,row,column); } } } void loadObject(void * object, char y, char x){ // object_ptr is the object to be loaded // y and x are offsets from the center of the display object_ptr_t object_ptr = (object_ptr_t)object; byte row = (ROWS/2) + y; byte column = (COLUMNS/2) + x; for(byte ys = 0; ys < object_ptr->height; ys++ ){ for(byte xs=0; xs < object_ptr->width; xs++ ){ if( (row +ys < ROWS) && (column +xs < COLUMNS)){ // this code only works on widths up to 8 bits boolean value = object_ptr->bitfield[ys] & BITVAL(xs) ; setLife(0, row+ys, column+xs, value) ; // objects always loaded into the first array } } } } void loadObject(int object, char y, char x){ loadObject(objectTable[object], y, x ); } boolean isStable(byte thisGeneration){ // returns true if any two captured generations are the same for(byte i=0; i < STABLE_GENERATIONS; i++) if(i != thisGeneration) if(memcmp(generations[thisGeneration], generations[i], sizeof(generations[0])) == 0) return true; return false; } boolean isAlive( byte generation, byte row, byte column){ byte b = generations[generation][row][column /8]; return b & BITVAL(column) ; } void setLife( byte generation, byte row, byte column, boolean state){ byte elem = column /8; byte b = generations[generation][row][elem]; if(state != DEAD){ b = b | BITVAL(column); } else{ b &= ~(BITVAL(column)) ; } generations[generation][row][elem] = b; } byte getNeighborCount( byte generation, byte row, byte column){ byte count = 0; for(byte d = 0;d < 8; d++) if(isNeighborAlive(generation,row,column,d) != 0) count++; return count; } boolean isNeighborAlive( byte generation , byte row, byte column, byte dir){ byte nrow=row; byte ncol=column; if(dir == 7 || dir == 0 || dir == 1) nrow--; if(dir == 3 || dir == 4 || dir == 5) nrow++; if(dir == 5 || dir == 6 || dir == 7) ncol--; if(dir == 1 || dir == 2 || dir == 3) ncol++; if(ncol==255) ncol = COLUMNS - 1; if(ncol==COLUMNS) ncol = 0; if(nrow==255) nrow = ROWS - 1; if(nrow==ROWS) nrow = 0; return isAlive(generation,nrow,ncol); } -
spitty created this gist
Dec 18, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,53 @@ /* This Arduino sketch shows QR-code with word 'AMAZING' and a heart in the right side of GLCD-display. Library openGLCD https://bitbucket.org/bperrybap/openglcd/wiki/Home is used. Author: Maxim Logunov [email protected] Date: 2016-12-17 */ #include <openGLCD.h> #define RECTSIZE 21 #define PXSIZE 2 const int bits[RECTSIZE][RECTSIZE] = {{0,0,0,0,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,0,0}, {0,1,1,1,1,1,0,1,1,0,1,1,0,1,0,1,1,1,1,1,0}, {0,1,0,0,0,1,0,1,1,0,1,1,1,1,0,1,0,0,0,1,0}, {0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0}, {0,1,0,0,0,1,0,1,1,1,1,0,1,1,0,1,0,0,0,1,0}, {0,1,1,1,1,1,0,1,1,0,1,0,0,1,0,1,1,1,1,1,0}, {0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,0,1,0,0,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0}, {1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,1,0,1}, {0,1,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,1}, {1,0,1,1,1,0,1,1,0,0,0,0,0,1,1,1,1,1,0,1,1}, {0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,1,0,1,0,0,1}, {1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,0,0,1,1}, {0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1}, {0,1,1,1,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,0}, {0,1,0,0,0,1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,0}, {0,1,0,0,0,1,0,1,1,1,0,0,1,1,0,0,1,0,1,0,1}, {0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0}, {0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,0,1,1,1,0,0}, {0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,1,0,0,0,1,0}}; void setup() { GLCD.Init(); GLCD.ClearScreen(); } void loop() { for (int i = 0; i < RECTSIZE; i++) { for (int j = 0; j < RECTSIZE; j++) { uint8_t color = (bits[i][j] == 0 ? PIXEL_ON : PIXEL_OFF); // padding-top : 11 = (64 - RECTSIZE * PXSIZE) / 2 // padding-left : 75 = WIDTH / 2 + (64 - RECTSIZE * PXSIZE) / 2 GLCD.FillRect(75 + j * PXSIZE, 11 + i * PXSIZE, 2, 2, color); } } delay(1000); }