aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2018-02-07 21:16:03 +0100
committertomsmeding <tom.smeding@gmail.com>2018-02-07 21:16:03 +0100
commite1c5955c23f7be7cb7c6ab6fc3d2a0046c1c36a6 (patch)
treec4e38c1058588697dd88cde068c1aec7d7aa610a
parentce5b7dba1050fdfbe10ca247db9e4d75148bb665 (diff)
Improvements
-rw-r--r--Makefile5
-rw-r--r--README.md3
-rw-r--r--main.c109
m---------termio0
4 files changed, 74 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index 1899fcf..4db1f12 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,9 @@
+.PHONY: all clean
+
all: tetris
+clean:
+ rm -f tetris
+
tetris: $(wildcard *.c *.h)
gcc -Wall -Wextra -std=c11 -O2 -fwrapv -o $@ $(filter %.c,$^) -Itermio termio/libtermio.a
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0f99230
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+Clone using `git clone --recurse-submodules`.
+
+Arrow keys or WASD to move; Q to quit.
diff --git a/main.c b/main.c
index d1c5138..d9f7984 100644
--- a/main.c
+++ b/main.c
@@ -12,6 +12,8 @@
#define WID 10
#define HEI 22
+#define USE_UNICODE
+
int delay_msec=700;
@@ -36,19 +38,26 @@ static int rotateR(int bl){
return dest;
}
-static int rotateL(int bl){
- return rotateR(rotateR(rotateR(bl)));
-}
-
struct board {
int lines[HEI];
int stone,stx,sty;
};
+static bool boardvalid(const struct board *bd){
+ for(int y=0;y<4;y++){
+ for(int x=0;x<4;x++){
+ if((bd->stone&(1<<(4*y+x)))){
+ if(bd->sty+y>=HEI)return false;
+ if(bd->stx+x<0||bd->stx+x>=WID)return false;
+ }
+ if(bd->lines[bd->sty+y]&((!!(bd->stone&(1<<(4*y+x))))<<(bd->stx+x)))return false;
+ }
+ }
+ return true;
+}
+
static void persist(struct board *bd){
- // fprintf(stderr,"persist: stone=%d\n",bd->stone);
- // usleep(1000000);
for(int y=0;y<4;y++){
for(int x=0;x<4;x++){
bd->lines[bd->sty+y]|=(!!(bd->stone&(1<<(4*y+x))))<<(bd->stx+x);
@@ -56,72 +65,83 @@ static void persist(struct board *bd){
}
}
-static void spawn(struct board *bd){
+// returns false iff game over
+static bool spawn(struct board *bd){
int idx=rand()%7;
- // fprintf(stderr,"%d\n",idx);
- // usleep(1000000);
bd->stone=stones[idx];
bd->stx=WID/2-1;
bd->sty=0;
+ return boardvalid(bd);
}
static void show(const struct board *bd){
struct board bd2;
memcpy(&bd2,bd,sizeof bd2);
persist(&bd2);
- printf("\x1B[H\x1B[2J");
+ clearscreen();
for(int y=0;y<HEI;y++){
- putchar('|');
+ moveto(0,y);
+ tputc('|');
for(int x=0;x<WID;x++){
- if(bd2.lines[y]&(1<<x))printf("█");
- else putchar(' ');
+#ifdef USE_UNICODE
+ if(x%2==1){
+ if(bd2.lines[y]&(1<<(x-1))){
+ if(bd2.lines[y]&(1<<x))tprintf("█");
+ else tprintf("▌");
+ } else {
+ if(bd2.lines[y]&(1<<x))tprintf("▐");
+ else tputc(' ');
+ }
+ }
+ if(bd2.lines[y]&(1<<x))tprintf("█");
+ else tputc(' ');
+#else
+ if(bd2.lines[y]&(1<<x))tputc('#');
+ else tputc(' ');
+#endif
}
- putchar('|');
- putchar('\n');
+ tputc('|');
}
- putchar('+');
- for(int x=0;x<WID;x++){
- putchar('-');
- }
- putchar('+');
- putchar('\n');
- fflush(stdout);
+ moveto(0,HEI);
+ tputc('+');
+#ifdef USE_UNICODE
+ assert(WID%2==0);
+ for(int x=0;x<WID*3/2;x++)tputc('-');
+#else
+ for(int x=0;x<WID;x++)tputc('-');
+#endif
+ tputc('+');
+ redraw();
}
-static bool boardvalid(const struct board *bd){
- for(int y=0;y<4;y++){
- for(int x=0;x<4;x++){
- if((bd->stone&(1<<(4*y+x)))){
- if(bd->sty+y>=HEI)return false;
- if(bd->stx+x<0||bd->stx+x>=WID)return false;
- }
- if(bd->lines[bd->sty+y]&((!!(bd->stone&(1<<(4*y+x))))<<(bd->stx+x)))return false;
+static void checklines(struct board *bd){
+ for(int y=HEI-1;y>=0;y--){
+ if(bd->lines[y]==(1<<WID)-1){
+ memmove(bd->lines+1,bd->lines,y*sizeof(int));
+ bd->lines[0]=0;
+ y++;
}
}
- return true;
}
-static void advance(struct board *bd){
- fprintf(stderr,"advance: stone=%d\n",bd->stone);
+// returns false iff game over
+static bool advance(struct board *bd){
if(bd->stone==0){
- spawn(bd);
- return;
+ return spawn(bd);
}
bd->sty++;
if(!boardvalid(bd)){
bd->sty--;
persist(bd);
- spawn(bd);
- return;
+ checklines(bd);
+ return spawn(bd);
}
+ return true;
}
static void move(struct board *bd,int dir){
bd->stx+=dir;
- if(!boardvalid(bd)){
- bd->stx-=dir;
- return;
- }
+ if(!boardvalid(bd))bd->stx-=dir;
}
static void rotR(struct board *bd){
@@ -136,6 +156,9 @@ int main(void){
initkeyboard(false);
atexit(endkeyboard);
+ initscreen();
+ atexit(endscreen);
+ installCLhandler(true);
struct board bd;
memset(&bd,0,sizeof bd);
@@ -164,7 +187,7 @@ int main(void){
gettimeofday(&end,NULL);
if(ret==0){
- advance(&bd);
+ if(!advance(&bd))break;
timeleft.tv_sec=delay_msec/1000;
timeleft.tv_usec=delay_msec%1000*1000;
continue;
@@ -192,7 +215,7 @@ int main(void){
int key=tgetkey();
if(key=='Q'||key=='q')break;
else if(key=='S'||key=='s'||key==KEY_DOWN){
- advance(&bd);
+ if(!advance(&bd))break;
timeleft.tv_sec=delay_msec/1000;
timeleft.tv_usec=delay_msec%1000*1000;
} else if(key=='A'||key=='a'||key==KEY_LEFT)move(&bd,-1);
diff --git a/termio b/termio
-Subproject 27b2fed1846cebde87565abb65c0bde207d15d6
+Subproject e3cb19cb87aaf5172d1090b2c6379e56429d932