mirror of
https://github.com/abakh/nbsdgames.git
synced 2024-12-04 14:46:22 -05:00
add revenge
This commit is contained in:
parent
04e8559947
commit
680effbd68
4
Makefile
4
Makefile
@ -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)
|
||||
|
||||
|
@ -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
482
revenge.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user