#include #include #include #include #include #include "config.h" #define LEN 17 #define WID 19 #define DELAY 2 #define SAVE_TO_NUM 10 /* Jewels copyright Hossein Bakhtiarifar 2018 (c) No rights are reserved and this software comes with no warranties of any kind to the extent permitted by law. compile with -lnucrses A pair of jewels appear on top of the window, And you can move and rotate them while they are falling down. If you make a vertical or horizontal row of 4 jewels they will explode and add up to your score. Like Tetris,You will lose the game when the center of the uppermost row is filled. */ typedef signed char byte; chtype board[LEN][WID]; chtype colors[6]={0}; chtype next1,next2; byte jx,jy; //first jewel's position byte kx,ky;//second jewel's position in relation to that of j long score=0; char* controls = "j,l-Move k-Rotate p-Pause q-Quit"; FILE* scorefile; byte scorewrite(long score){// only saves the top 10 bool deforno; if( !getenv("JW_SCORES") && (scorefile= fopen(JW_SCORES,"r")) ){ deforno=1; } else{ deforno=0; if( !(scorefile = fopen(getenv("JW_SCORES"),"r")) ){ fprintf(stderr,"\nNo accessible score files found. You can make an empty text file in %s or set JW_SCORES to such a file to solve this. \n",JW_SCORES); exit(EXIT_SUCCESS); } } char namebuff[SAVE_TO_NUM][60]; long scorebuff[SAVE_TO_NUM]; memset(namebuff,0,SAVE_TO_NUM*60*sizeof(char) ); memset(scorebuff,0,SAVE_TO_NUM*sizeof(long) ); long fuckingscore =0; char fuckingname[60]={0}; byte location=0; while( fscanf(scorefile,"%59s : %ld\n",fuckingname,&fuckingscore) == 2 && location=itreached || score>=scorebuff[location]) ){ fprintf(scorefile,"%s : %ld\n",getenv("USER"),score); ret=location; wroteit=1; } if(location*>*>Top %d<*<*<\n",SAVE_TO_NUM); while( rank>>"); printf("%d) %s : %ld\n",rank+1,pname,pscore); rank++; } putchar('\n'); } //apply gravity bool fall(void){ bool jfall,kfall,ret; jfall=kfall=ret=0; for(int y=LEN-1;y>0;y--){ chtype c,d; for(int x=WID-1;x>=0;x--){ c=board[y][x]; d=board[y-1][x]; if(!c && d){ board[y-1][x]=0; board[y][x]=d; if(y-1==jy && x==jx) jfall=1; if((y-1==jy+ky) && (x==jx+kx)) kfall=1; ret=1; } } } if(jfall&&kfall) jy++; else jy = LEN+1; return ret; } // rotate 90d clockwise in ky/x format void clockwise(byte* y,byte* x){ /* o x x xo o ox*/ chtype fx,fy; if(*y) fy=0; fx=-*y; if(*x) fx=0; fy=*x; *y=fy; *x=fx; } //rtt jwls bool rotate(void){//f:future if(jy>LEN) return 0; byte fy,fx; fy=ky;fx=kx; clockwise(&fy,&fx); if( jy+fy<0 || jy+fy>=LEN || jx+fx<0 || jx+fx>=WID ) return 0; if(board[jy+fy][jx+fx]) return 0; chtype a = board[jy+ky][jx+kx]; board[jy+ky][jx+kx]=0; ky=fy; kx=fx; board[jy+ky][jx+kx]=a; return 1; } //mv jwls bool jmove(byte dy,byte dx){ if(jy>LEN) return 0; if(jx+dx>=WID || jx+dx<0 || jx+kx+dx>=WID ||jx+kx+dx<0 || jy+dx<0 ||jx+dx+kx<0) return 0; if( board[jy+ky+dy][jx+kx+dx] ) if( !(jy+ky+dy == jy && jx+kx+dx==jx) ) return 0; if( board[jy+dy][jx+dx]) if(!(dx==kx && dy==ky)) return 0; //still alive? chtype a = board[jy][jx]; chtype b = board[jy+ky][jx+kx]; board[jy][jx]=0; board[jy+ky][jx+kx]=0; board[jy+dy][jx+dx]=a; board[jy+ky+dy][jx+kx+dx]=b; jy+=dy;jx+=dx; return 1; } //scoring algorithm bool explode(byte combo){ bool ret =0; chtype c,uc; byte n; byte y,x; for(y=0;y=3 && x==WID-1){//the chain ends because the row ends x++; goto HrExplsn; } } else if(n>=3){ HrExplsn: score+=n*10*(n-2)*combo; ret=1; for(;n>=0;n--) board[y][x-1-n]=0; n=0; } else n=0; } } for(x=0;x=3 && y==LEN-1){ y++; goto VrExplsn; } } else if(n>=3){ VrExplsn: score+=n*10*(n-2)*combo; ret=1; for(;n>=0;n--) board[y-1-n][x]=0; n=0; } else n=0; } } return ret; } //display void draw(void){ erase(); int middle = (COLS/2-1)-(WID/2); chtype a=A_STANDOUT|' '; mvhline(LEN,middle-2,a,WID+4); mvvline(0,middle-1,a,LEN); mvvline(0,middle-2,a,LEN); mvvline(0,middle+WID,a,LEN); mvvline(0,middle+WID+1,a,LEN); mvprintw(0,0,"Score:%d",score); mvaddstr(1,0,"Next:"); addch(next1); addch(next2); for(byte y=0;y= 10){ falls=fall(); stop=0; } else if(input=='l' || input==KEY_RIGHT) jmove(0,+1); else if(input=='j' || input==KEY_LEFT ) jmove(0,-1); else if(input=='k' || input==KEY_UP) rotate(); else if(input=='p'){ mvaddstr(LINES-2,COLS/2-15,"Paused - Press a key to continue "); refresh(); nocbreak(); cbreak(); getch(); halfdelay(DELAY); } else if(input=='q') goto Lose; else if(input==' ') while( (falls=fall()) ) stop=0; else{ falls=fall(); stop=0; } draw(); } combo=1; while(explode(combo)){ // explode, fall, explode, fall until nothing is left combo++; while(fall()); draw(); } } Lose: nocbreak(); endwin(); printf("%s _Jewels_ %s\n",jwstr,jwstr); printf("You have scored %ld points.\n",score); showscores(scorewrite(score)); return EXIT_SUCCESS; }