Use cbitset for game of life to reduce data size - making it run on r0ket

This commit is contained in:
bernd 2011-07-20 08:08:09 +02:00
parent eabf38452f
commit 71d7bb28b1
1 changed files with 71 additions and 79 deletions

View File

@ -2,9 +2,17 @@
#include "basic/basic.h" #include "basic/basic.h"
#include "lcd/render.h" //#include "lcd/render.h"
#include "lcd/display.h" #include "lcd/display.h"
#include "lcd/allfonts.h" //#include "lcd/allfonts.h"
#define BITSET_X (RESX+2)
#define BITSET_Y (RESY+2)
#define BITSET_SIZE (BITSET_X*BITSET_Y)
#include "cbitset.h"
typedef uint8_t uchar;
unsigned char rnd1(); unsigned char rnd1();
@ -28,78 +36,63 @@ void fill_rect(char x0, char y0, char x1, char y1) {
} }
#define STARTVALUE 10 #define STARTVALUE 10
typedef unsigned char uchar;
typedef uchar row_t[RESY+2]; struct bitset _buf1,*buf1=&_buf1;
uchar buf1[RESX+2][RESY+2]; struct bitset _buf2,*buf2=&_buf2;
uchar buf2[RESX+2][RESY+2];
row_t *life =buf1; struct bitset *life =&_buf1;
row_t *new =buf2; struct bitset *new =&_buf2;
void swap_areas() { void swap_areas() {
row_t *tmp=life; struct bitset *tmp=life;
life=new; life=new;
new=tmp; new=tmp;
} }
void fill_area(uchar area[RESX+2][RESY+2], uchar x0, uchar y0, uchar x1, uchar y1,uchar value) { void fill_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value) {
for(uchar x=x0; x<=x1; ++x) { for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) { for(uchar y=y0; y<=y1; ++y) {
area[x][y]=value; bitset_set2(area,x,y,value);
} }
} }
} }
bool find_area(uchar area[RESX+2][RESY+2], uchar x0, uchar y0, uchar x1, uchar y1,uchar value) { bool find_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value) {
for(uchar x=x0; x<=x1; ++x) { for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) { for(uchar y=y0; y<=y1; ++y) {
if(area[x][y]==value) return true; if(bitset_get2(area,x,y)==value) return true;
} }
} }
return false; return false;
} }
uint32_t sum_area(uchar area[RESX+2][RESY+2], uchar x0, uchar y0, uchar x1, uchar y1) { uint32_t sum_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1) {
uint32_t sum=0; uint32_t sum=0;
for(uchar x=x0; x<=x1; ++x) { for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) { for(uchar y=y0; y<=y1; ++y) {
sum+=area[x][y]; sum+=bitset_get2(area,x,y);
} }
} }
return sum; return sum;
} }
void draw_area() { void draw_area() {
for(uchar x=1; x<=RESX; ++x) { for(uchar x=0; x<RESX; ++x) {
for(uchar y=1; y<=RESY; ++y) { for(uchar y=0; y<RESY; ++y) {
lcdSetPixel(x,y,life[x+1][y+1]&1); lcdSetPixel(x,y,bitset_get2(life,x+1,y+1));
} }
} }
} }
void calc_waldbrand() {
fprintf(stderr,"calc area...\n");
// swap_areas();
// return;
for(uchar x=1; x<=RESX; ++x) {
for(uchar y=1; y<=RESY; ++y) {
if(life[x][y]==0) {
new[x][y]=rnd1()<20?0:(find_area(life,x-1,y-1,x+1,y+1,STARTVALUE)?STARTVALUE:0);
} else {
new[x][y]=life[x][y]-1;
}
// new[x][y]=sum_area(life,x-1,y-1,x+1,y+1)%2;
}
}
swap_areas();
}
void calc_area() { void calc_area() {
#ifdef SIMULATOR
static unsigned long iter=0; static unsigned long iter=0;
fprintf(stderr,"Iteration %d \n",++iter); fprintf(stderr,"Iteration %d \n",++iter);
#endif
for(uchar x=1; x<=RESX; ++x) { for(uchar x=1; x<=RESX; ++x) {
for(uchar y=1; y<=RESY; ++y) { for(uchar y=1; y<=RESY; ++y) {
uchar sum=sum_area(life,x-1,y-1,x+1,y+1)-life[x][y]; uchar sum=sum_area(life,x-1,y-1,x+1,y+1)-bitset_get2(life,x,y);
new[x][y]=sum==3||(sum==2&&life[x][y]); bitset_set2(new,x,y,sum==3||(sum==2&&bitset_get2(life,x,y)));
} }
} }
swap_areas(); swap_areas();
@ -110,47 +103,69 @@ int pattern=0;
void reset_area() { void reset_area() {
fill_area(life,0,0,RESX+1,RESY+1,0); fill_area(life,0,0,RESX+1,RESY+1,0);
fill_area(new,0,0,RESX+1,RESY+1,0);
switch(pattern) { switch(pattern) {
case 0: case 0:
for(uchar x=STARTVALUE; x>0; --x) { bitset_set2(life,41,40,1);
for(uchar y=1; y<RESY/2; ++y) { bitset_set2(life,42,40,1);
life[RESX/2+x][y]=x; bitset_set2(life,41,41,1);
} bitset_set2(life,40,41,1);
} bitset_set2(life,41,42,1);
life[7][7]=1;
life[17][7]=1;
life[7][17]=1;
new[55][15]=1;
new[45][25]=1;
new[35][35]=1;
new[25][45]=1;
new[15][55]=1;
break; break;
case 1: case 1:
for(int i=0; i<RESX/3; ++i) life[i][0]=1; for(int i=0; i<RESX/2; ++i) bitset_set2(life,i,0,1);
bitset_set2(life,40,40,1);
bitset_set2(life,41,40,1);
bitset_set2(life,41,41,1);
break; break;
case 2: case 2:
life[RESX/2][RESY/2]=1; bitset_set2(life,40,40,1);
bitset_set2(life,41,40,1);
bitset_set2(life,42,40,1);
bitset_set2(life,42,41,1);
bitset_set2(life,42,42,1);
bitset_set2(life,40,41,1);
bitset_set2(life,40,42,1);
break; break;
} }
} }
void random_area(uchar area[RESX+2][RESY+2], uchar x0, uchar y0, uchar x1, uchar y1,uchar value) { void random_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value) {
for(uchar x=x0; x<=x1; ++x) { for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) { for(uchar y=y0; y<=y1; ++y) {
area[x][y]=rnd1()<value; bitset_set2(area,x,y,rnd1()<value);
} }
} }
} }
#define LEDINTERVAL 1
uint8_t ledcycle=3;
void nextledcycle() {
ledcycle=(ledcycle+1)%(8*LEDINTERVAL);
uint8_t a=ledcycle/LEDINTERVAL;
switch(a) {
case 0: gpioSetValue (RB_LED0, CFG_LED_ON); break;
case 4: gpioSetValue (RB_LED0, CFG_LED_OFF); break;
case 1: gpioSetValue (RB_LED1, CFG_LED_ON); break;
case 5: gpioSetValue (RB_LED1, CFG_LED_OFF); break;
case 2: gpioSetValue (RB_LED2, CFG_LED_ON); break;
case 6: gpioSetValue (RB_LED2, CFG_LED_OFF); break;
case 3: gpioSetValue (RB_LED3, CFG_LED_ON); break;
case 7: gpioSetValue (RB_LED3, CFG_LED_OFF); break;
}
}
uchar stepmode=0; uchar stepmode=0;
uchar randdensity=0; uchar randdensity=0;
void main_life(void) { void main_life(void) {
gpioSetValue (RB_LED1, CFG_LED_OFF);
backlightInit(); backlightInit();
reset_area(); reset_area();
gpioSetValue (RB_LED0, CFG_LED_ON);
gpioSetValue (RB_LED1, CFG_LED_ON);
gpioSetValue (RB_LED2, CFG_LED_ON);
gpioSetValue (RB_LED3, CFG_LED_ON);
while (1) { while (1) {
// checkISP(); // checkISP();
lcdFill(0); lcdFill(0);
@ -159,6 +174,7 @@ void main_life(void) {
switch(button) { switch(button) {
case BTN_DOWN: case BTN_DOWN:
stepmode=1; stepmode=1;
nextledcycle();
break; break;
case BTN_RIGHT: case BTN_RIGHT:
stepmode=0; stepmode=0;
@ -184,27 +200,3 @@ void main_life(void) {
} }
return; return;
} }
// random code from ecc
static int xrandm=100000000;
static int xrandm1=10000;
static int xrandb1=51723621;
int xmult(int p,int q)
{
int p1,p0,q1,q0;
p1=p/xrandm1; p0=p%xrandm1;
q1=q/xrandm1; q0=q%xrandm1;
return (((p0*q1+p1*q0)%xrandm1)*xrandm1+p0*q0)%xrandm;
}
unsigned char rnd1()
{
static int a=123456789;
a = (xmult(a,xrandb1)+1)%xrandm;
return a & 0xff;
}