1
0
mirror of https://github.com/abakh/nbsdgames.git synced 2024-11-02 16:27:18 -04:00

add revenge

This commit is contained in:
me 2022-08-18 03:54:10 +04:30
parent 04e8559947
commit 680effbd68
3 changed files with 485 additions and 2 deletions

View File

@ -10,8 +10,8 @@ LIBS_PKG_CONFIG!=pkg-config --libs --cflags ncurses
LIBS=$(LIBS_PKG_CONFIG) -lm
ALL= nbsdgames jewels sudoku mines reversi checkers battleship rabbithole sos pipes fifteen memoblocks fisher muncher miketron redsquare darrt snakeduel tugow
SCORE_FILES= pipes_scores jewels_scores miketron_scores muncher_scores fisher_scores darrt_scores tugow_scores
ALL= nbsdgames jewels sudoku mines reversi checkers battleship rabbithole sos pipes fifteen memoblocks fisher muncher miketron redsquare darrt snakeduel tugow revenge
SCORE_FILES= pipes_scores jewels_scores miketron_scores muncher_scores fisher_scores darrt_scores tugow_scores revenge_scores
SRC!=echo *.c *.h
all: $(ALL)

View File

@ -62,6 +62,7 @@ char main_menu[]={
NB"darrt\n"
NB"snakeduel\n"
NB"tugow\n"
NB"revenge\n"
};
char ascii_art[]={
" ###### ###### "

482
revenge.c Normal file
View File

@ -0,0 +1,482 @@
/*
.-.
|_.'
| \EVENGE
Authored by abakh <abakh!tuta,io>
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "common.h"
enum {EMPTY=0,BLOCK,CAT_OLD,CAT,CAT_NEW,CAT_TRAPPED,CHEESE};
/* The Plan9 compiler can not handle VLAs */
#ifdef NO_VLA
#define size 20
#else
byte size=20;
#endif
#define SAVE_TO_NUM 10
long score=0;
byte py,px;
byte ey,ex; //the empty tile
chtype colors[6]={0};
void rectangle(byte sy,byte sx){
for(byte y=0;y<=size+1;++y){
mvaddch(sy+y,sx,ACS_VLINE);
mvaddch(sy+y,sx+size*2,ACS_VLINE);
}
for(byte x=0;x<=size*2;++x){
mvaddch(sy,sx+x,ACS_HLINE);
mvaddch(sy+size+1,sx+x,ACS_HLINE);
}
mvaddch(sy,sx,ACS_ULCORNER);
mvaddch(sy+size+1,sx,ACS_LLCORNER);
mvaddch(sy,sx+size*2,ACS_URCORNER);
mvaddch(sy+size+1,sx+size*2,ACS_LRCORNER);
}
void logo(byte sy,byte sx){
mvaddstr(sy,sx, ".-.");
mvprintw(sy+1,sx,"|_.'");
mvaddstr(sy+2,sx,"| \\EVENGE ");
}
byte save_score(void){
return fallback_to_home("revenge_scores",score,SAVE_TO_NUM);
}
void show_scores(byte playerrank){
erase();
logo(0,0);
if(playerrank==FOPEN_FAIL){
mvaddstr(3,0,"Could not open score file");
printw("\nHowever, your score is %ld.",score);
refresh();
return;
}
if(playerrank == 0){
char formername[60]={0};
long formerscore=0;
rewind(score_file);
fscanf(score_file,"%*s : %*d\n");
move(3,0);
byte b=0;
if ( fscanf(score_file,"%s : %ld\n",formername,&formerscore)==2){
halfdelay(1);
printw("*****CONGRATULATIONS!****\n");
printw(" You beat the\n");
printw(" previous\n");
printw(" record\n");
printw(" of\n");
printw(" %14ld\n",formerscore);
printw(" held by\n");
printw(" %11s\n",formername);
printw(" \n");
printw(" \n");
printw("*************************\n");
printw("Press a key to proceed:");
Effect:
move(4,0);
mvprintw(4,0, " _____ ");
mvprintw(5,0, " .' |");
mvprintw(6,0, " .' |");
mvprintw(7,0, " | .| |");
mvprintw(8,0, " |.' | |");
mvprintw(9,0, " | |");
mvprintw(10,0," ___| |___");
mvprintw(11,0," | |");
mvprintw(12,0," |____________|");
b=(b+1)%6;
if(getch()==ERR)
goto Effect;
nocbreak();
cbreak();
erase();
logo(0,0);
}
}
//scorefile is still open with w+
move(3,0);
char pname[60] = {0};
long pscore=0;
byte rank=0;
rewind(score_file);
printw(">*>*>Top %d<*<*<\n",SAVE_TO_NUM);
while( rank<SAVE_TO_NUM && fscanf(score_file,"%s : %ld\n",pname,&pscore) == 2){
if(rank == playerrank)
printw(">>>");
printw("%d) %s : %ld\n",rank+1,pname,pscore);
++rank;
}
addch('\n');
refresh();
}
//display
void draw(byte sy,byte sx,byte board[size][size]){
rectangle(sy,sx);
mvprintw(1,sx+12,"Score: %ld",score);
chtype prnt;
byte y,x;
for(y=0;y<size;++y){
for(x=0;x<size;++x){
switch(board[y][x]){
case EMPTY:
prnt=' ';
break;
case BLOCK:
prnt='#'|colors[1];
break;
case CAT:
case CAT_OLD:
case CAT_TRAPPED:
prnt='f'|colors[2];
break;
case CHEESE:
prnt='%'|colors[2]|A_BOLD;
break;
}
if(y==py && x==px && board[y][x]==EMPTY){
prnt = 'r'|A_STANDOUT;
}
mvaddch(sy+1+y,sx+x*2+1,prnt);
}
}
}
void fill(byte board[size][size]){
byte y,x;
for(y=0;y<size;++y){
for(x=0;x<size;++x){
if(y>3 && y<17 && x>3 && x<17){
board[y][x]= BLOCK;
}
else{
board[y][x]= EMPTY;
}
}
}
py=size/2;
px=size/2;
board[py][px]=EMPTY;
}
void put_cats(byte board[size][size], byte number){
byte y,x;
for(byte i=0;i<number;++i){
do{
y=rand()%size;
x=rand()%size;
}while(board[y][x]!=EMPTY || abs(y-py)<4 || abs(x-px)<4);
board[y][x]=CAT;
}
}
void turn_to_cheese(byte board[size][size]){
byte y,x;
for(y=0;y<size;++y){
for(x=0;x<size;++x){
if(board[y][x]==CAT_OLD){
board[y][x]=CHEESE;
score+=75;
}
}
}
}
#define MOVE_CAT if(!(y+dy<0 || x+dx<0 || y+dy>=size || x+dx>=size)&&(board[y+dy][x+dx]==EMPTY)){\
board[y][x]=EMPTY;\
board[y+dy][x+dx]=CAT_NEW;\
goto Next;\
}
byte cat_life(byte board[size][size]){
byte y,x,dy,dx,predy,predx;
byte only_old=1;
for(y=0;y<size;++y){
for(x=0;x<size;++x){
if(board[y][x]==CAT_OLD){
for(dy=-1;dy<2;++dy){
for(dx=-1;dx<2;++dx){
MOVE_CAT;
}
}
}
if(board[y][x]==CAT){
only_old=0;
board[y][x]=CAT_OLD;
dy=dx=0;
if(py<y){
dy=-1;
}
if(px<x){
dx=-1;
}
if(py>y){
dy=1;
}
if(px>x){
dx=1;
}
MOVE_CAT;
predy=dy;
predx=dx;
dy=0;
dx=predx;
MOVE_CAT;
dy=predy;
dx=0;
MOVE_CAT;
dx=-1+(rand()%3);
MOVE_CAT;
dy=-1+(rand()%3);
MOVE_CAT;
for(dy=-1;dy<2;++dy){
for(dx=-1;dx<2;++dx){
MOVE_CAT;
}
}
}
Next: continue;
}
}
for(y=0;y<size;++y){
for(x=0;x<size;++x){
if(board[y][x]==CAT_NEW){
board[y][x]=CAT;
}
}
}
if(only_old){
turn_to_cheese(board);
return 0;
}
return 1;
}
void tile_push(byte board[size][size],byte dy, byte dx){
byte y=py,x=px;
y+=dy;
x+=dx;
byte first_tile=1;
while(y>=0 && x>=0 && y<size && x<size){
if(first_tile && board[y][x]==CHEESE){
score+= 100;
}
if(board[y][x]==EMPTY || board[y][x]==CHEESE){
board[y][x]=BLOCK;
board[py+dy][px+dx]=EMPTY;
py+=dy;
px+=dx;
break;
}
else if(board[y][x]!=BLOCK){
break;
}
y+=dy;
x+=dx;
}
}
//peacefully close when ^C is pressed
void sigint_handler(int x){
endwin();
puts("Quit.");
exit(x);
}
void mouseinput(void){
#ifndef NO_MOUSE
MEVENT minput;
#ifdef PDCURSES
nc_getmouse(&minput);
#else
getmouse(&minput);
#endif
if( minput.y-4<size && minput.x-1<size*2){
py=minput.y-4;
px=(minput.x-1)/2;
}
else
return;
if(minput.bstate & BUTTON1_CLICKED)
ungetch('\n');
#endif
}
void help(void){
erase();
logo(0,0);
attron(A_BOLD);
mvprintw(3,0," **** THE CONTROLS ****");
mvprintw(8,0,"YOU CAN ALSO USE THE MOUSE!");
attroff(A_BOLD);
mvprintw(4,0,"RETURN/ENTER : Slide");
mvprintw(5,0,"hjkl/ARROW KEYS : Move cursor");
mvprintw(6,0,"q : Quit");
mvprintw(7,0,"F1 & F2 : Help on controls & gameplay");
mvprintw(10,0,"Press a key to continue");
refresh();
getch();
erase();
}
void gameplay(void){
erase();
logo(0,0);
attron(A_BOLD);
mvprintw(3,0," **** THE GAMEPLAY ****");
attroff(A_BOLD);
mvprintw(4,0,"Trap cats and don't be eaten by them.\n");
refresh();
getch();
erase();
}
int main(int argc, char** argv){
int opt;
bool no_replay=0;
while( (opt=getopt(argc,argv,"hns:"))!=-1){
switch(opt){
case 'n':
no_replay=1;
break;
case 'h':
default:
printf("Usage:%s [options]\n -h help\n -n don't ask for replay\n",argv[0]);
break;
}
}
signal(SIGINT,sigint_handler);
srand(time(NULL)%UINT_MAX);
initscr();
#ifndef NO_MOUSE
mousemask(ALL_MOUSE_EVENTS,NULL);
#endif
noecho();
cbreak();
keypad(stdscr,1);
if(has_colors()){
start_color();
use_default_colors();
init_pair(1,COLOR_BLUE,-1);
init_pair(2,COLOR_GREEN,-1);
init_pair(3,COLOR_YELLOW,-1);
init_pair(4,COLOR_RED,-1);
init_pair(5,COLOR_RED,COLOR_YELLOW);
init_pair(6,COLOR_RED,COLOR_MAGENTA);
for(byte b= 0;b<6;++b){
colors[b]=COLOR_PAIR(b+1);
}
}
byte board[size][size];
int input;
time_t last_wave,last_move;
byte waves_count;
Start:
waves_count=0;
halfdelay(1);
score=0;
last_wave=last_move=time(0);
py=px=0;
ey=ex=size-1;
curs_set(0);
fill(board);
put_cats(board,1);
while(1){
erase();
logo(0,0);
draw(3,0,board);
refresh();
input = getch();
if( input==KEY_F(1) || input=='?' )
help();
if( (input==KEY_F(2)||input=='!') )
gameplay();
if( input==KEY_MOUSE )
mouseinput();
if( (input=='k' || (input==KEY_UP||input=='w')) && py>0){
tile_push(board,-1,0);
}
if( (input=='j' || (input==KEY_DOWN||input=='s')) && py<size-1){
tile_push(board,1,0);
}
if( (input=='h' || (input==KEY_LEFT||input=='a')) && px>0){
tile_push(board,0,-1);
}
if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px<size-1){
tile_push(board,0,1);
}
if( input=='y'){
tile_push(board,-1,-1);
}
if( input=='u'){
tile_push(board,-1,1);
}
if(input=='b'){
tile_push(board,1,-1);
}
if(input=='n'){
tile_push(board,1,1);
}
if( input=='p'){
nocbreak();
cbreak();
erase();
logo(0,0);
attron(A_BOLD);
mvaddstr(2,12,"PAUSED");
attroff(A_BOLD);
getch();
halfdelay(1);
}
if( (input=='q'||input==27)){
sigint_handler(0);
}
if( last_move < time(0)){
byte no_cat_life=!cat_life(board);
if( no_cat_life || (time(0)> last_wave+300 && waves_count<5)){
put_cats(board,2+(rand()%7));
last_wave=time(0);
waves_count++;
}
if(no_cat_life){
waves_count=0;
}
last_move=time(0);
}
if(board[py][px]==CAT){
break;
}
}
flushinp();
nocbreak();
cbreak();
logo(0,0);
draw(3,0,board);
refresh();
move(25,0);
printw("You lost The Game. Press a key to see high scores:");
getch();
show_scores(save_score());
if(!no_replay){
printw("You lost The Game. Wanna play again?(y/n)");
refresh();
curs_set(1);
input=getch();
while(input!='n'&&input!='N'&&input!='q'&&input!='Q'&&input!='y'&&input!='\n'){
input=getch();
}
if(input != 'N' && input != 'n' && input != 'q')
goto Start;
}
else{
printw(" Press any key on this computer's keyboard if you want to continue.");
getch();
}
endwin();
return EXIT_SUCCESS;
}