From e1c5955c23f7be7cb7c6ab6fc3d2a0046c1c36a6 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Wed, 7 Feb 2018 21:16:03 +0100 Subject: Improvements --- Makefile | 5 +++ README.md | 3 ++ main.c | 109 +++++++++++++++++++++++++++++++++++++------------------------- termio | 2 +- 4 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 README.md 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;ystone&(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<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 index 27b2fed..e3cb19c 160000 --- a/termio +++ b/termio @@ -1 +1 @@ -Subproject commit 27b2fed1846cebde87565abb65c0bde207d15d6b +Subproject commit e3cb19cb87aaf5172d1090b2c6379e56429d932f -- cgit v1.2.3-54-g00ecf