pax_global_header00006660000000000000000000000064151740633650014524gustar00rootroot0000000000000052 comment=fcc25f4b0e5436389646919e2fd1f41f9fccbbc2 nbsdgames-6.0.1/000077500000000000000000000000001517406336500134735ustar00rootroot00000000000000nbsdgames-6.0.1/LICENSE000066400000000000000000000006301517406336500144770ustar00rootroot00000000000000Authored by abakh 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 . nbsdgames-6.0.1/Makefile000066400000000000000000000040031517406336500151300ustar00rootroot00000000000000# -*- Makefile -*- #-O3 --std=c99 -lcurses -DNO_MOUSE for NetBSD curses #adding --std=c99 makes warnings in GNU, and the blame is upon glibc feature test macros. my code is correct. GAMES_DIR?=$(PREFIX)/usr/bin SCORES_DIR?=$(PREFIX)/var/games MAN_DIR?=$(PREFIX)/usr/share/man/man6 CFLAGS+= -Wno-unused-result -DSCORES_DIR=\"$(SCORES_DIR)\" 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 revenge trsr sjump scissor SCORE_FILES= pipes_scores jewels_scores miketron_scores muncher_scores fisher_scores darrt_scores tugow_scores revenge_scores sjump_scores redsquare_scores scissor_scores SRC!=echo *.c *.h all: $(ALL) scorefiles: for sf in $(SCORE_FILES); do touch $(DESTDIR)$(SCORES_DIR)/$$sf ; chmod 664 $(DESTDIR)$(SCORES_DIR)/$$sf; chown :games $(DESTDIR)$(SCORES_DIR)/$$sf ; done; for game in $(ALL); do chown :games $(DESTDIR)$(GAMES_DIR)/$$game; chmod g $(DESTDIR)$(GAMES_DIR)/$$game ; done; manpages: cp man/* $(DESTDIR)$(MAN_DIR) $(ALL): $(SRC) config.h common.h $(CC) $(CFLAGS) $@.c $(LDFLAGS) $(LIBS) -o $@ menu: cp nbsdgames.desktop $(DESTIDR)$(PREFIX)/usr/share/applications cp nbsdgames.svg $(DESTDIR)$(PREFIX)/usr/share/pixmaps clean: for game in $(ALL); do rm $$game; done; uninstall: for game in $(ALL); do rm $(GAMES_DIR)/$$game; rm $(MAN_DIR)/$$game.6.gz ;done; install: $(ALL) cp $(ALL) $(DESTDIR)/$(GAMES_DIR) test: for game in $(ALL); do ./$$game ;done; #######for namespacing ####### nb: CFLAGS="$$CFLAGS -D NB=\\\"nb\\\"" $(MAKE) for game in $(ALL); do cp $$game nb$$game ;done; for manpage in $(ls man); do cp man/$$manpage man/nb$$manpage ;done; nbinstall: nb for game in $(ALL); do cp nb$$game $(DESTDIR)/$(GAMES_DIR) ;done; cp nbsdgames $(DESTDIR)/$(GAMES_DIR) rm $(DESTDIR)/$(GAMES_DIR)/nbnbsdgames nbmanpages: nb cp man/nb* $(DESTDIR)/$(MAN_DIR) nbclean: clean for game in $(ALL); do rm nb$$game ;done; nbsdgames-6.0.1/README.md000066400000000000000000000123741517406336500147610ustar00rootroot00000000000000# New BSD Games *You have a computing machine from 1980's and you wonder how you can use it?
You are a bored sysadmin with no work, and need to kill time looking busy with terminal?
You have Plan9 dual-booted with OpenBSD and have kept the OpenBSD just for gaming?
You have to make a Reversi AI for your homework and you don't know where to copy it from?
Your port of Linux to a fancy platform has no GUI, but you still want nice screenshots?
You have been so excited about the bsdgames, but have grown tired of playing tetris, snake and robots for billions of times?
Are you feeling that betrayed you by bundling stuff like phantasia in a package you expected to contain GAMES?
Did you come here thinking it is bsdgames?*
**Don't worry** anymore as you've got nbsdgames now! The games include: * Jewels (A game with a gameplay kinda similiar to that of Tetris, NOT my invention) * Sudoku * Mines (Minesweeper) * Reversi * Checkers * Battleship * SOS * Rabbithole (A maze-exploring game where you have to gather items from all around the maze rather than reaching an end, the idea maybe mine) * Pipes (Same as the famous Pipe Mania) * Fifteen * Memoblocks (or Memory blocks. A similar game was included in Windows 7) * Fisher * Muncher * Miketron * Redsquare (Conway's Game of Life made playable!) * Darrt (with original gameplay!) * Snakeduel * Tugow (Numpad practice game) * Trsr (Two-player minesweeper) * Scissor (Rock-paper-scissor made into an original and unique gameplay. A genre of its own) * Revenge The difficulty and/or dimensions are adjustable through simple command line options, you can play a minesweeper game that take hours to complete, or exprience hexadecimal sudoku and 8x8 fifteen-like puzzles! *Or just enter "nbsdgames" at your terminal to get a fancy menu and play all sorts of games from there.* Play on xterm for best experience. ## Packages It's on almost every repo by now: Debian (and other DEBs), OpenSUSE (and other RPMs), AUR, Alpine, FreeBSD, NetBSD, DragonflyBSD, Minix, Homebrew (MacOSX) and more https://repology.org/project/nbsdgames/versions Thanks to Elias Riedel Gårding, Zinjanthropus, Gürkan Myczko, Robert Clausecker, Sam James, and so many other nice people for packaging. They also gave back code and useful feedback. ## How to compile Have * git (optional) * POSIX make (optional) * A C compiler with C99 enabled * The standard library * ncurses (libncurses5-dev if you are on debian-based distros) To install them all on debian-base : ``` sh sudo apt install git make gcc libncurses5-dev ``` 1) Download the files 2) Go to the sources directory 3) Install Like this: ``` sh git clone https://github.com/abakh/nbsdgames cd ./nbsdgames make sudo make install # or use the binaries already compiled ``` ## Packages It's on almost every repo by now: Debian (and other DEBs), OpenSUSE (and other RPMs), AUR, Alpine, FreeBSD, NetBSD, DragonflyBSD, Minix, Homebrew (MacOSX) and more https://repology.org/project/nbsdgames/versions Thanks to Elias Riedel Gårding, Zinjanthropus, Gürkan Myczko, Robert Clausecker, Sam James, and so many other nice people for packaging. They also gave back code and useful feedback. ## Other Platforms They are known to work on Windows as well (using PDCurses, thanks to Laura Michaels for providing advice). They have been ported to Plan9 thanks to Jens Staal! Thanks to PDCurses they even work on DOS and every platform with SDL. They should theoretically work on OS/2 as well but I have not verified that yet. ## Dependencies * git (optional) * POSIX make (optional) * A C compiler with C99 enabled * The standard library * ncurses (libncurses5-dev if you are on debian-based distros) To install them all on debian-base : ``` sh sudo apt install git make gcc libncurses5-dev ``` ## How to build 1) Download the files 2) Go to the sources directory 3) Install Like this: ``` sh git clone https://github.com/abakh/nbsdgames cd ./nbsdgames make sudo make install # or use the binaries already compiled ``` ## How do these look like Linux+xterm+tmux ![Screenshot from 4 games in tmux](https://raw.githubusercontent.com/abakh/junk/master/screenshot.png) Plan9 ![Screenshot from the games in Plan9](https://raw.githubusercontent.com/abakh/junk/master/screenshot_plan9.png) Windows ![Screenshot from the games in Windows 7](https://raw.githubusercontent.com/abakh/junk/master/screenshot_windows.jpg) ## How to contribute * Share these with your friends and others (including making YouTube videos of yourself playing, and telling every relevant youtuber and blogger to do the same) * Your stars make the repo more findable in Github :star: * Tell me your feature requests, bug reports, etc. * Tell me the games you want to be added (but in the same genre, I can't port Angry Birds to curses! :) * Make a package for your distro (or put it on repos if the package is not there) * Tell distro developers to consider adding these as *default games*, read and send them the **mail.md** text. * Compile these with ASAN, play and find C-ish bugs. Also thanks to all the people who helped in the previous versions, all what I requested was done! I didn't expect such an amount of assistance on this project :heart: nbsdgames-6.0.1/battleship.c000066400000000000000000000336441517406336500160100ustar00rootroot00000000000000/* _ |_) |_)ATTLESHIP Authored by abakh 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 . */ #include "common.h" #define MISS -2 #define SEA -1 #define HIT 0 #define NOTHING -1 #define ALL 0x7c #define RED 3 #define CYAN 2 #define ENGLISH_LETTERS 26 typedef unsigned char bitbox; bool multiplayer; byte py,px;//cursor chtype colors[4]={0}; byte game[2][10][10];//main board bool computer[2] = {0}; byte score[2] = {0};//set by header() bitbox sunk[2]={0}; byte just_sunk[2]={0};//to be displayed for human players byte firstinrowy , firstinrowx ; byte lastinrowy ,lastinrowx; byte goindirection; byte shotinvain; void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } void mouseinput(bool ingame){ #ifndef NO_MOUSE MEVENT minput; #ifdef PDCURSES nc_getmouse(&minput); #else getmouse(&minput); #endif if(minput.bstate & (BUTTON1_CLICKED|BUTTON1_RELEASED)){ if( minput.y-4 < 10){ if( (ingame && minput.x-23<20 && minput.x-23>=0 ) || (!ingame && minput.x-1<20) ){//it most be on the trackboard if ingame is true py=minput.y-4; px=(minput.x-1-(ingame*2)) /2; } } else return; } if(minput.bstate & (BUTTON1_CLICKED|BUTTON1_RELEASED)) ungetch('\n'); if(minput.bstate & (BUTTON2_CLICKED|BUTTON2_RELEASED|BUTTON3_CLICKED|BUTTON3_RELEASED) ) ungetch('r'); #endif } void rectangle(byte sy,byte sx){ for(byte y=0;y<=10+1;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+10*2,ACS_VLINE); } for(byte x=0;x<=10*2;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+10+1,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+10+1,sx,ACS_LLCORNER); mvaddch(sy,sx+10*2,ACS_URCORNER); mvaddch(sy+10+1,sx+10*2,ACS_LRCORNER); } void print_type(byte type){ switch(type){ case(2): addstr("patrol boat"); break; case(3): addstr("destroyer"); break; case(4): addstr("battleship"); break; case(5): addstr("carrier"); break; case(6): addstr("submarine"); break; } } void MID(byte *y , byte *x, byte direction){ switch(direction){ case(0): *x=*x-1; break; case(1): *y=*y-1; break; case(2): *x=*x+1; break; case(3): *y=*y+1; break; } } void genocide(bool side , byte type){ byte y,x; for(y=0;y<10;++y){ for(x=0;x<10;++x){ if(game[side][y][x] == type) game[side][y][x] = SEA; } } } void header(bool side){ score[0]=score[1]=0; byte y,x; for(y=0;y<10;++y){ for(x=0;x<10;++x){ if(game[!side][y][x] == HIT) score[side]++; if(game[side][y][x] == HIT) score[!side]++; } } mvaddch(0,1, '_'); mvprintw(1,0,"|_) %2d:%2d",score[side],score[!side]); mvprintw(2,0,"|_)ATTLESHIP "); if(multiplayer){ attron(colors[side]); if(side) printw("Yellow's turn"); else printw("Green's turn"); attroff(colors[side]); } } void draw(bool side,byte sy,byte sx,bool regular){//the game's board rectangle(sy,sx); chtype ch ; byte y,x; for(y=0;y<10;++y){ for(x=0;x<10;++x){ ch =A_NORMAL; if(y==py && x==px) ch |= A_STANDOUT; if(game[side][y][x] == HIT) ch |= 'X'|colors[RED]; else if(game[side][y][x] > 0 && !(multiplayer&®ular) ) ch |= ACS_BLOCK|colors[side]; else if(game[side][y][x]== MISS) ch |= 'O'|colors[CYAN]; else if(!(multiplayer&®ular)) ch |= '~'|colors[CYAN]; else ch |=' '; mvaddch(sy+1+y,sx+x*2+1,ch); } } } void draw_trackboard(bool side,byte sy,byte sx){ rectangle(sy,sx); chtype ch ; byte y,x; for(y=0;y<10;++y){ for(x=0;x<10;++x){ ch =A_NORMAL; if(y==py && x==px-10) ch |= A_STANDOUT; if(game[!side][y][x] == HIT) ch |= '*'|colors[RED]; else if(game[!side][y][x]== MISS) ch |= '~'|colors[CYAN]; else ch |= '.'; mvaddch(sy+1+y,sx+x*2+1,ch); } } refresh(); } void autoset(bool side){ byte y=0,x=0,direction=0, invain=0; byte realy,realx; byte l; for(byte type=2;type<7;++type){ SetLocation: realy=rand()%10; realx=rand()%10; invain=0; SetDirection: y=realy; x=realx; direction=rand()%4; for(l=0;(type != 6 && l=10 || x>=10 || game[side][y][x] != SEA ){ genocide(side,type); ++invain; direction= (direction+1)%4; if(invain<4) goto SetDirection; else goto SetLocation;//endless loop } else{ game[side][y][x]=type; MID(&y,&x,direction); } } } } void set_the_board(bool side){ if( computer[side] ){ autoset(side); return; } erase(); mvaddch(0,1, '_'); mvaddstr(1,0,"|_) Set your board"); mvaddstr(2,0,"|_)ATTLESHIP"); mvaddstr(16,0,"Press RETURN to specify the location and press R to rotate the ship."); int input; byte y=0,x=0,direction=0, invain=0; byte realy,realx; byte l; py=px=0; for(byte type=2;type<7;++type){ mvaddstr(15,0,"Put your "); print_type(type); addstr(" in its position: "); SetLocation: while(1){ draw(side,3,0,false); refresh(); input = getch(); if( input == KEY_MOUSE ) mouseinput(0); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py<9) ++py; if( (input=='h' || (input==KEY_LEFT||input=='a')) && px>0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px<9) ++px; if( input=='\n'||input==KEY_ENTER ) break; if( (input=='q'||input==27) ) sigint_handler(EXIT_SUCCESS); } realy=y=py; realx=x=px; invain=0; SetDirection: y=realy; x=realx; for(l=0;(type != 6 && l=10 || x>=10 || game[side][y][x] != SEA ){ genocide(side,type); ++invain; direction= (direction+1)%4; if(invain<4) goto SetDirection; else goto SetLocation;//endless loop } else{ game[side][y][x]=type; MID(&y,&x,direction); } } while(1){ invain=0; draw(side,3,0,false); input=getch(); if( input== 'r' || input == 'R' ){ genocide(side,type); direction= (direction+1)%4; goto SetDirection; } else if(input == KEY_MOUSE) mouseinput(0); else break; } } } void turn_shift(void){ if(!multiplayer) return; char key = 'a'+(rand()%ENGLISH_LETTERS); int input1,input2,input3; input1=input2=input3=0; erase(); beep(); mvaddch(0,1, '_'); mvaddstr(1,0,"|_) Anti-cheater"); mvaddstr(2,0,"|_)ATTLESHIP"); mvaddstr(4,0,"********************"); mvprintw(5,0," Type '%c' 3 times ",key); mvaddstr(6,0," before "); mvaddstr(7,0," proceeding "); mvaddstr(8,0," to the game "); mvaddstr(10,0,"********************"); refresh(); while(1){ input3=input2; input2=input1; input1=getch(); if( (input1==input2) && (input2==input3) && (input3==key) ) break; } erase(); } byte shoot(bool turn, byte y , byte x){ if( y<0 || x<0 || y>9 || x>9 ){ //didn't shoot at all return NOTHING; } byte s = game[!turn][y][x]; if(s==HIT || s==MISS) return NOTHING; if(s>0){ game[!turn][y][x]=HIT; return 1; } else{ game[!turn][y][x]=MISS; return 0; } } void sink_announce(bool side){ byte type,y,x; for(type=2;type<7;++type){ for(y=0;y<10;++y){ for(x=0;x<10;++x){ if( game[!side][y][x] == type ) goto Next; } } //there is no instance of 'type' in the opponent's board if( ( (1 << type) | sunk[!side] ) != sunk[!side] ){//if it is not yet announced as sunk sunk[!side] |= (1 << type); if(computer[side]){ lastinrowy=lastinrowx=firstinrowy=firstinrowx=-1; shotinvain=0; } else{ just_sunk[!side]=type;//leave to be displayed by you_sunk } return; } Next: continue; } } void you_sunk(bool side){ if( just_sunk[!side] == 3) mvaddstr(15,0,"You have destroyed my destroyer!!"); else if( just_sunk[!side]){ mvaddstr(15,0,"You have sunk my "); print_type(just_sunk[!side]); addstr("!!"); } just_sunk[!side]=0; } void cheat(bool side){ /* its actually an anti-cheat, the player can place all their ships adjacent to one another and in the same direction, and the algorithm will often play in a way that it will be left with one or two isolated tiles being unshot (with their respective ships being shot before). in a such a situation a human will *very easily* find the tiles with logical thinking, but the computer shoots randomly and it will take such a long time for it that it will often lose the winning game. this function still doesn't make a win,it's randomly executed. if i implemented the logical thinking thing, it would become a difficult, unenjoyable game.*/ byte y,x; for(y=0;y<10;++y){ for(x=0;x<10;++x){ if(game[!side][y][x]>0){ shoot(side,y,x); firstinrowy=y; firstinrowx=x; return; } } } } void decide(bool side){// sink_announce is responsible for unsetting the global variables involved byte y,x,r; Again: if( firstinrowy == NOTHING ){ if( score[side] > 14 && score[side]9 || x>9) && r==NOTHING){ goto Again; } } r= shoot(side,y,x);//(y,x) may be MISS, but its impossible for it to be empty water, as executing this means it has tested every direction before if(r==1){ lastinrowy=y;//continue from the imaginary firstinrow lastinrowx=x; } if(r==NOTHING) goto Again; } } else{ lastinrowy= y; lastinrowx= x; } if( r != NOTHING ) return; } } else{ y=lastinrowy; x=lastinrowx; MID(&y,&x,goindirection); r=shoot(side,y,x); if( r == 1 ){ lastinrowy=y; lastinrowx=x; } else{ lastinrowy=lastinrowx=NOTHING; goindirection=(goindirection+2)%4; } if( r != NOTHING ) return; else{ goto Again; } } } void gameplay(bool side){//side is only there to feed header() erase(); header(side); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("Guess the location of your opponent's\n"); printw("ships and sink them! The player\n"); printw("who sinks all the opponent's ships wins."); getch(); erase(); } void help(bool side){//side is only there to feed header() erase(); header(side); attron(A_BOLD); mvprintw(3,0," **** THE CONTROLS ****"); mvprintw(9,0,"YOU CAN ALSO USE THE MOUSE!"); attroff(A_BOLD); mvprintw(4,0,"RETURN/ENTER : Shoot"); mvprintw(5,0,"R : Rotate"); mvprintw(6,0,"hjkl/ARROW KEYS : Move cursor"); mvprintw(7,0,"q : Quit"); mvprintw(8,0,"F1 & F2 : Help on controls & gameplay"); mvprintw(11,0,"Press a key to continue"); getch(); erase(); gameplay(side); } int main(int argc,char** argv){ if(argc>1){ printf("This game doesn't take arguments"); } initscr(); #ifndef NO_MOUSE mousemask(ALL_MOUSE_EVENTS,NULL); #endif curs_set(0); noecho(); cbreak(); keypad(stdscr,1); if( has_colors() ){ start_color(); use_default_colors(); init_pair(1,COLOR_GREEN,-1); init_pair(2,COLOR_YELLOW,-1); init_pair(3,COLOR_CYAN,-1); init_pair(4,COLOR_RED,-1); for(byte b=0;b<4;++b) colors[b]=COLOR_PAIR(b+1); } int input; printw("Choose type of the game:\n"); printw("1 : Single Player*\n"); printw("2 : Multi Player\n"); refresh(); input=getch(); if(input == '2'){ multiplayer=1; computer[1]=computer[0]=0; } else{ multiplayer=0; computer[1]=1; computer[0]=0; } Start: firstinrowy=firstinrowx=lastinrowy=lastinrowx=goindirection=NOTHING; shotinvain=0; sunk[0]=sunk[1]=0; memset(game,SEA,200); srand(time(NULL)%UINT_MAX); erase(); set_the_board(0); turn_shift(); set_the_board(1); bool won; bool turn=1; Turn: px=10; py=0; sink_announce(turn); if( sunk[0]==ALL ){ won=1; goto End; } else if( sunk[1]==ALL ){ won=0; goto End; } //the turn starts HERE turn=!turn; //turn_shift(); if( computer[turn] ){ decide(turn); goto Turn; } else{ erase(); you_sunk(turn); while(1){ header(turn); draw(turn,3,0,true); draw_trackboard(turn,3,22); refresh(); input=getch(); if(input == KEY_F(1) || input=='?' ) help(turn); if((input==KEY_F(2)||input=='!') ) gameplay(turn); if(input == KEY_MOUSE) mouseinput(1); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py<9) ++py; if( (input=='h' || (input==KEY_LEFT||input=='a')) && px>10) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px<19) ++px; if( (input=='q'||input==27)) sigint_handler(EXIT_SUCCESS); if( input=='\n' || input==KEY_ENTER){ byte r=shoot(turn,py,px-10); if(r != NOTHING){ goto Turn; } } } } End: erase(); header(won); draw(won,3,0,false); draw_trackboard(won,3,22); if( computer[won] ) mvaddstr(15,0,"Hahaha! I won! "); else mvprintw(15,0,"Player %d won the game.",won+1); addstr(" Wanna play again? (y/n)"); refresh(); curs_set(1); input=getch(); if( input!='n' && input !='N' && input!='q' ){ curs_set(0); goto Start; } endwin(); return 0; } nbsdgames-6.0.1/checkers.c000066400000000000000000000416141517406336500154340ustar00rootroot00000000000000/* .-. | ' '._.HECKERS Authored by abakh 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 . */ #include "common.h" #define LIGHT -1 #define DARK 1 #define KING 2 #define DOESNT_MATTER 1 #define IMAGINARY 0 #define NORMAL 1 #define ALT_IMG 2 #define ALT_NRM 3 #define WIN 100000 byte py,px;//cursor byte cy,cx;//selected(choosen) piece byte game[8][8]; byte computer[2]={0,0}; char side[2]={'h','h'}; byte score[2];//set by header() bool endgame=false; byte jumpagainy , jumpagainx; bool kinged;//if a piece jumps over multiple others and becomes a king it cannot continue jumping bool in(byte A[4],byte B[4],byte a,byte b){ for(byte c=0;c<4;++c) if(A[c]==a && B[c]==b) return true; return false; } void rectangle(byte sy,byte sx){ byte y,x; for(y=0;y<=8+1;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+8*2,ACS_VLINE); } for(x=0;x<=8*2;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+8+1,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+8+1,sx,ACS_LLCORNER); mvaddch(sy,sx+8*2,ACS_URCORNER); mvaddch(sy+8+1,sx+8*2,ACS_LRCORNER); } void header(void){ score[0]=score[1]=0; byte y,x; for(y=0;y<8;++y){ for(x=0;x<8;++x){ if(game[y][x]){ if(game[y][x]<0) score[0]++; else score[1]++; } } } mvprintw(0,0," .-."); mvprintw(1,0,"| ' %2d:%2d",score[0],score[1]); mvprintw(2,0,"'._,HECKERS "); } void draw(byte sy,byte sx){//the game's board rectangle(sy,sx); chtype ch ; byte y,x; for(y=0;y<8;++y){ for(x=0;x<8;++x){ ch=A_NORMAL; if(y==py && x==px) ch |= A_STANDOUT; if(y==cy && x==cx) ch |= A_BOLD; if(game[y][x]){ if(game[y][x]<0){ if(has_colors()) ch|=COLOR_PAIR(1); else ch |= A_UNDERLINE; } if(abs(game[y][x])<2) ch |='O'; else ch |='K'; } else if( (y%2) != (x%2) ) ch|='.'; else ch|=' '; mvaddch(sy+1+y,sx+x*2+1,ch); } } } //place the pieces on the board void fill(void){ byte y,x; for(y=0;y<8;++y){ for(x=0;x<8;++x){ game[y][x]=0; if( (y%2) != (x%2)){ if(y<3) game[y][x]=1; if(y>4) game[y][x]=-1; } } } } //fill mvy/x with possible moves bool moves(byte ty,byte tx,byte mvy[4],byte mvx[4]){ bool ret=0; byte ndx=0; byte t= game[ty][tx]; move(15,0); byte dy,dx; for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ if( !dy || !dx || (!ty && dy<0) || (!tx && dx<0) || (dy==-t) || (ty+dy>=8) || (tx+dx>=8) ) ; else if(!game[ty+dy][tx+dx]){ ret=1; mvy[ndx]=ty+dy; mvx[ndx]=tx+dx; ++ndx; } else ++ndx; } } return ret; } //would be much faster than applying moves() on every tile bool can_move(byte side){ byte y , x ,t, dy , dx; for(y=0;y<8;++y){ for(x=0;x<8;++x){ if( (t=game[y][x])*side > 0 ){ for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ if( !dy || !dx || (!y && dy<0) || (!x && dx<0) || (dy==-t) || (y+dy>=8) || (x+dx>=8) ) ; else if( !game[y+dy][x+dx] ) return 1; } } } } } return 0; } //fill mvy/x with possible jumping moves bool jumps(byte ty,byte tx,byte mvy[4],byte mvx[4]){ bool ret=0; byte ndx=0; byte ey,ex; byte t= game[ty][tx]; byte dy,dx; for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ ey = dy*2; ex = dx*2; if(!dy || !dx ||(dy==-t)|| (ty+ey<0) || (tx+ex<0) || (ty+ey>=8) || (tx+ex>=8) ) ; else if(!game[ty+ey][tx+ex] && game[ty+dy][tx+dx]*t<0){ ret=1; mvy[ndx]=ty+ey; mvx[ndx]=tx+ex; ++ndx; } else ++ndx; } } return ret; } //same as can_move for jumps byte can_jump(byte ty,byte tx){ byte dy,dx,t=game[ty][tx]; byte ey,ex; byte ret=0; for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ ey=dy*2; ex=dx*2; if((dy==-t)||(ty+ey<0)||(tx+ex<0)||(ty+ey>=8)||(tx+ex>=8) ) ; else if(!game[ty+dy*2][tx+dx*2]&&game[ty+dy][tx+dx]*t<0){ ++ret; if(ret>1) return ret; } } } return ret; } //see if the side is forced to do a jump byte forced_jump(byte side){ byte y,x; byte foo,ret; foo=ret=0; for(y=0;y<8;++y){ for(x=0;x<8;++x){ if(game[y][x]*side>0 && (foo=can_jump(y,x)) ) ret+=foo; if(ret>1) return ret; } } return ret; } byte cmove(byte fy,byte fx,byte sy,byte sx){//really move/jump , 'move' is a curses function byte a = game[fy][fx]; byte ret=0; game[fy][fx]=0; game[sy][sx]=a; if(abs(fy-sy) == 2){ ret =game[(fy+sy)/2][(fx+sx)/2]; game[(fy+sy)/2][(fx+sx)/2]=0; } return ret; } //make the pawn a king bool king(byte y,byte x){ byte t= (4-y)*game[y][x]; if( (y==7 || !y) && t<0 && t>-5 ){ game[y][x]*=2; return 1; } return 0; } double advantage(byte side){ unsigned char own,opp; own=opp=0; byte foo; byte y,x; for(y=0;y<8;++y){ for(x=0;x<8;++x){ foo=game[y][x]*side; if(foo>0){ ++own;//so it wont sacrfice two pawns for a king ( 2 kings == 3 pawns) own+=foo; } else if(foo<0){ ++opp; opp-=foo; } } } if(!own) return 0; else if(!opp) return WIN; else return (double)own/opp; } double posadvantage(byte side){ double adv=0; double oppadv=0; byte foo; byte y,x; byte goal= (side>0)*7 , oppgoal=(side<0)*7; /*This encourages the AI to king its pawns and concentrate its kings in the center. The idea is : With forces concentrated in the center, movements to all of the board would be in the game tree's horizon of sight(given enough depth); and with forces being focused , its takes less movements to make an attack. */ for(y=0;y<8;++y){ for(x=0;x<8;++x){ foo=game[y][x]*side; if(foo>0){ adv+=foo; ++adv; if(foo==1) adv+= 1/( abs(y-goal) );//adding positional value else if(foo==2) adv+= 1/( fabs(y-3.5)+ fabs(x-3.5) ); } else if( foo<0 ){ oppadv-=foo; ++oppadv; if(foo==-1) adv+=1/( abs(y-oppgoal) ); else if(foo==-2) adv+= 1/( fabs(y-3.5)+ fabs(x-3.5) ); } } } if(!adv) return 0; else if( !oppadv ) return WIN; else return adv/oppadv; return adv; } //the AI algorithm double decide(byte side,byte depth,byte movetype){ byte fj=forced_jump(side);//only one legal jump if returns 1 byte nextturn; byte mvy[4],mvx[4]; byte n; bool didking; byte captured; double adv=0; byte toy,tox; byte y,x; double wrstadv=WIN+1; double bestadv=0; byte besttoy,besttox; byte besty,bestx; bestx=besty=besttox=besttoy=-100; bool canmove=0; byte nexts ; if(movetype == IMAGINARY || movetype == NORMAL ){ nexts=IMAGINARY; }else{ nexts=ALT_IMG; } for(y=0;y<8;++y){ for(x=0;x<8;++x){ if(fj && (movetype==NORMAL || movetype==ALT_NRM) && jumpagainy>=0 && (jumpagainy!=y || jumpagainx!=x) ) continue; if(game[y][x]*side>0){ canmove=0; memset(mvy,-1,4); memset(mvx,-1,4); if(fj) canmove=jumps(y,x,mvy,mvx); else canmove=moves(y,x,mvy,mvx); if(canmove){ for(n=0;n<4;++n){ if(mvy[n] != -1){//a real move toy=mvy[n]; tox=mvx[n]; captured=cmove(y,x,toy,tox);//do the imaginary move if(fj && can_jump(toy,tox) ) //its a double jump nextturn=side; else nextturn=-side; didking=king(toy,tox); //see the advantage you get if(fj==1 && (movetype==ALT_NRM || movetype==NORMAL) ) adv= DOESNT_MATTER;//you have to do the move anyway else if(depth==0){ if(movetype==IMAGINARY || movetype==NORMAL){//calculating advantage only based on numerical superiority adv=advantage(side); } else{ adv=posadvantage(side);//taking to account the position of the pieces } } else if(depth<0){ adv= rand()%100;//random move } else{ if(nextturn==side) adv=decide(nextturn,depth,nexts); else{ //best move is the one that gives least advantage to the opponent adv=decide(nextturn,depth-!fj,nexts); if(adv==WIN) adv=0; else if(adv) adv=1/adv; else adv=WIN; } } //undo the imaginary move if(didking) game[toy][tox]/=2; game[y][x]=game[toy][tox]; game[toy][tox]=0; if(fj){ game[(toy+y)/2][(tox+x)/2]=captured; } if(besty<0 || (adv>bestadv|| (adv==bestadv && ( rand()%2 )))) { besty=y; bestx=x; besttoy=toy; besttox=tox; bestadv=adv; } if(adv= 0 ){ if(endgame && fj!=1 && movetype==NORMAL && bestadv==wrstadv ){//the algorithm is not given enough depth to determine which move is better if(wrstadv == WIN){//the randomization in the algorithm may cause an illusion of an inevitable win in several moves, if not for this if(depth > 1) decide(side,depth-1,NORMAL); else goto Move; } else{ decide(side,depth,ALT_NRM);//change your opinion about what advantage means } } else{ Move: cmove(besty,bestx,besttoy,besttox); kinged=king(besttoy,besttox); if(!kinged && can_jump(besttoy,besttox) ){ jumpagainy = besttoy;//so the next player (itself) can only continue the chain of jumps from there jumpagainx = besttox; } else jumpagainy=jumpagainx=-1; } } return bestadv; } //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 <8 && minput.x-1<16){ py=minput.y-4; px=(minput.x-1)/2; } else return; if(minput.bstate & (BUTTON1_CLICKED|BUTTON1_PRESSED|BUTTON1_RELEASED) ) ungetch('\n'); #endif } void gameplay(void){ erase(); header(); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("1) The game starts with each player having 12 men;\n"); printw(" men can only diagonally move forwards \n"); printw(" (toward the opponent's side).\n\n"); printw("2) Men can become kings by reaching the opponent's \n"); printw(" first rank; kings can diagonally move both forwards\n"); printw(" and backwards.\n\n"); printw("3) Pieces can capture opponent's pieces by jumping over them\n"); printw(" also they can capture several pieces at once by doing a\n"); printw(" chain of jumps.\n\n"); printw("4) You have to do a jump if you can.\n\n"); printw("5) A player wins when the opponent can't do a move e. g. \n"); printw(" all of their pieces are captured.\n\n"); refresh(); getch(); erase(); curs_set(0); } void help(void){ erase(); header(); 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 : Select or move the piece"); 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(); gameplay(); } int main(int argc,char** argv){ int depth=-3;//start as stupid (actively try to lose). so noobs could play too. int opt; bool sides_chosen=0,no_replay=0,fixed_starting_depth=0; int auto_stupid_counter=0; while( (opt= getopt(argc,argv,"hnp:1:2:"))!= -1 ){ switch(opt){ case '1': case '2': if(!strcmp("c",optarg) || !strcmp("h",optarg)){ side[opt-'1']=optarg[0]; sides_chosen=1; } else{ puts("That should be either h or c\n"); return EXIT_FAILURE; } break; case 'p': if(sscanf(optarg,"%d",&depth) && depth<128 && depth>0){ fixed_starting_depth=1; } else{ puts("That should be a number from 1 to 127."); return EXIT_FAILURE; } break; case 'n': no_replay=1; break; case 'h': default: printf("Usage: %s [options]\n -p ai power\n -1 type of player 1\n -2 type of player 2\n -h help\n -n dont ask for replay\n",argv[0]); return EXIT_SUCCESS; break; } } initscr(); #ifndef NO_MOUSE mousemask(ALL_MOUSE_EVENTS,NULL); #endif noecho(); cbreak(); keypad(stdscr,1); int input ; if(!sides_chosen){ printw("Black plays first.\nChoose type of the black player(H/c)\n" ); refresh(); input=getch(); if(input=='c'){ computer[0]=depth; side[0]='c'; printw("Computer.\n"); } else{ computer[0]=0; side[0]='h'; printw("Human.\n"); } printw("Choose type of the white player(h/C)\n"); refresh(); input=getch(); if(input=='h'){ computer[1]=0; side[1]='h'; printw("Human.\n"); } else{ computer[1]=depth; side[1]='c'; printw("Computer.\n"); } } if(has_colors()){ start_color(); use_default_colors(); init_pair(1,COLOR_RED,-1); } signal(SIGINT,sigint_handler); Start: srand(time(NULL)%UINT_MAX); fill(); cy=cx=-1; py=px=0; byte mvy[4],mvx[4]; memset(mvy,-1,4); memset(mvx,-1,4); byte turn=1; bool t=1; bool fj; byte result; byte todraw=0; double adv = 1;//used to determine when the game is a draw double previousadv =1; Turn: curs_set(0); jumpagainy=jumpagainx=-1; kinged=0; turn =-turn; t=!t;//t == turn<0 that's turn in binary/array index format fj = forced_jump(turn); erase(); flushinp(); header(); draw(3,0); if(t){ previousadv=adv; adv= advantage(1) + (score[0]*score[1]);//just taking the dry scores to account too,nothing special if(previousadv==adv) ++todraw; else todraw=0; } if(score[0]==score[1] && !can_move(1) && !can_move(-1) && !forced_jump(1) && !forced_jump(-1)){ result=0; goto End; } else if(!score[0] || (turn==-1 && !fj && !can_move(-1))){ result=1; goto End; } else if(!score[1] || (turn==1 && !fj && !can_move(1))){ result=-1; goto End; } else if(todraw==50){ // 50 turns without any kind of gain for either side result=0; goto End; } endgame= score[t]<=5 || score[!t]<=5; draw(3,0); refresh(); while(side[t]=='c'){ mvprintw(13,0,"Thinking..."); refresh(); decide(turn,depth+(score[t]=0 && !kinged )){ goto Turn; } } while(1){ erase(); draw(3,0); header(); if(!(computer[0]||computer[1])){ if(t) addstr(" White's turn"); else{ attron(COLOR_PAIR(1)); addstr(" Black's turn"); attroff(COLOR_PAIR(1)); } } 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) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py<7) ++py; if( (input=='h' || (input==KEY_LEFT||input=='a')) && px>0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px<7) ++px; if( (input=='q'||input==27)){ result=2; goto End; } if(input=='\n' || input==KEY_ENTER){ if(game[py][px]*turn>0){ cy=py; cx=px; memset(mvy,-1,4); memset(mvx,-1,4); if(!fj) moves(py,px,mvy,mvx); jumps(py,px,mvy,mvx); } if( in(mvy,mvx,py,px) && !(jumpagainy>=0 && (cy !=jumpagainy || cx != jumpagainx) ) ){ memset(mvy,-1,4); memset(mvx,-1,4); cmove(cy,cx,py,px); kinged=king(py,px); cy=-1; cx=-1; if( !(fj && can_jump(py,px) && !kinged ) ){ goto Turn; } else{ jumpagainy=py; jumpagainx=px; } } } } End: move(13,0); switch(result){ case -1: printw("Black side has won the game."); break; case 0: printw("Draw."); break; case 1: printw("White side has won the game."); break; case 2: printw("You resigned."); } /* The idea is: Anyone should be likely to win the first time (so they don't lose interest) should be likely to lose the second time (so they don't think the AI is stupid) after that, the AI tries to play on par with the player by discovering his level of skill.*/ if(!fixed_starting_depth && result!=2 && result!=0 && (side[0]=='c'||side[1]=='c') && (side[0]=='h'||side[1]=='h')){ if( (side[0]=='c' && score[0]>score[1]) || (side[1]=='c' && score[1]>score[0])){//if computer won if(depth>-1){ --depth; } if(auto_stupid_counter==1){ depth=0; } } else{ if(depth<5){ ++depth; printw(" I'd play better next time. "); } else{ printw(" Are you human? "); } if(!fixed_starting_depth && auto_stupid_counter==0){ depth=4; auto_stupid_counter+=1; } } } if(!no_replay){ printw(" Wanna rematch?(y/n)"); refresh(); curs_set(1); input=getch(); if(result==2){ if (input=='Y' || input=='y') goto Start; } else if(input!='n' && input!='N' && input!= 'q'){ /*byte b=computer[0]; //switch sides, i don't know if it's necessary computer[0]=computer[1]; computer[1]=b;*/ goto Start; } } else{ printw("Press any key on your keyboard to continue."); getch(); } endwin(); return EXIT_SUCCESS; } nbsdgames-6.0.1/common.h000066400000000000000000000064731517406336500151460ustar00rootroot00000000000000/* Authored by abakh 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #define FOPEN_FAIL -10 #define ENV_VAR_OR_USERNAME (getenv("NB_PLAYER")?getenv("NB_PLAYER"):getenv("USER")) #define MAXPATHSIZE 1000 FILE* score_file; byte score_write(const char* path, long wscore, byte save_to_num){// only saves the top 10, returns the place in the chart score_file=fopen(path,"r"); if(!score_file){ score_file=fopen(path,"w"); if(!score_file){ return FOPEN_FAIL; } } #ifdef NO_VLA #define save_to_num_ 10 #else //such a dirty cpp hack byte save_to_num_=save_to_num; #endif char name_buff[save_to_num_][60]; long score_buff[save_to_num_]; char tmp_path[MAXPATHSIZE + 8] = {0}; strcpy(tmp_path, path); strcat(tmp_path, ".XXXXXX"); memset(name_buff,0,save_to_num_*60*sizeof(char) ); memset(score_buff,0,save_to_num_*sizeof(long) ); long scanned_score =0; char scanned_name[60]={0}; byte location=0; while( fscanf(score_file,"%59s : %ld\n",scanned_name,&scanned_score) == 2 && location=scores_count || wscore>=score_buff[i]) ){ fprintf(tmp_score_file,"%s : %ld\n",ENV_VAR_OR_USERNAME,wscore); ret=i; wrote_it=1; } if(i #include #ifdef __unix__ #define rand() random() #define srand(x) srandom(x) //At the time of writing, NetBSD's rand() is damn stupid. //rand()%4 constantly gives 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3. #endif // It seems usleep is obsoleted in favor of nanosleep, // and some POSIX implementations lack it. but i refuse // to end using it! what the hell, filling a struct for // something as trivial as sleeping 0.1 seconds?? // the function is written by Jens Staal for Plan9 #ifdef Plan9 int microsleep(long usec){ int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #define usleep(x) microsleep(x) #endif typedef signed char byte; #ifndef M_PI //i don't know why tf, but it happens #define M_PI 3.1415 #endif #endif //CONFIG_H nbsdgames-6.0.1/darrt.c000066400000000000000000000220601517406336500147530ustar00rootroot00000000000000/* _ | '. | : |.' ARRT Authored by abakh 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 . */ #include "common.h" #define SAVE_TO_NUM 11 #define LEN 24 #define HLEN LEN/2 #define WID 80 #define HWID WID/2 #define SHOTS_WHEN_STARTING 10 #define randint(a,b) ((a)+(rand()%((b+1)-(a)))) #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif // 12 lines of water // 80 columns chtype colors[3]={0}; long score=0; FILE* scorefile; chtype background[LEN][WID]; int input; typedef struct aim{ char sign; float y,x; float angle; float v; float vy,vx; byte brake; bool visible; }aim; aim aims[26]; aim landed_aims[SHOTS_WHEN_STARTING];//so an aim couldn't pass below one that has already landed, doesn't make sense visually. byte shots,aims_to_stop; char msg[150]={0}; byte msg_show=0; void filled_rect(byte sy,byte sx,byte ey,byte ex){ byte y,x; for(y=sy;yy,(byte)a->x); long points; if(distance>HLEN){ points=-2*pow(2,distance-HLEN); } else if((byte) a->y == HLEN && (byte) a->x == HWID){ points=1000000; } else{ points=pow(2,HLEN-distance); } return points; } void aim_lands(aim *a){ landed_aims[SHOTS_WHEN_STARTING-aims_to_stop]=*a; --aims_to_stop; score+=calculate_points(a); a->visible=0; float distance= center_distance((byte)a->y,(byte)a->x); if((byte)a->y==HLEN && (byte)a->x==HWID){ strcpy(msg,"Bravo!"); } else if(distance<2){ strcpy(msg,"Very close..."); } else{ goto NoMessage; } msg_show=30; NoMessage: return; } void move_aim(aim *a){ if(a->brake==1){ return; } else if(a->brake>0){ --a->brake; } bool bounce=0; //bounce when hitting the borders, and don't get stuck there if(a->x<0 || (int)a->x>=WID-1 || ((int)a->x==13 && a->y<=7 ) ){ a->angle =M_PI- a->angle; bounce=1; } if(a->y <0 || (int)a->y >= LEN-1 || (a->x<=13 && (int)a->y==7)){ a->angle =0- a->angle; bounce=1; } if(a->x<0)//these are for getting unstuck a->x=1; if(a->y<0) a->y=1; if(a->x>=WID) a->x=WID-1; if(a->y>=LEN) a->y=LEN-1; if((int)a->x==13 && a->y<7) a->x=14; if(a->x<=13 && (int)a->y==7) a->y=8; while(a->angle<0){//preventing overflow a->angle +=M_PI*2; } if(bounce){ a->vy=sin(a->angle)*a->v; a->vx=cos(a->angle)*a->v; } //move a->y+=a->vy; a->x+=a->vx; if(bounce && a->x>=WID-1)//getting unstuck a->x=WID-1; if(bounce && a->y>=LEN-1) a->y=LEN-1; if(bounce){//bounce in a slightly different direction than it should be a->angle +=randint(-1,1)*0.1; a->vy=sin(a->angle)*a->v; a->vx=cos(a->angle)*a->v; } if(a->x<13 && a->y<7){// don't go into the logo area if(13 - a->x < 7 - a->y){ a->y=8; } else{ a->x=14; } } if(a->brake==1){//the aim has just been stopped aim_lands(a); } } void star_line(byte y){ for(byte x=1;x0){ byte a = (LEN-9)/2; star_line(1); star_line(LEN-2); mvaddstr(1,WID/2-8,"CONGRATULATIONS!!"); mvprintw(a+1,HWID-10," _____You beat the"); mvprintw(a+2,HWID-10," .' | previous"); mvprintw(a+3,HWID-10," .' | record"); mvprintw(a+4,HWID-10," | .| | of"); mvprintw(a+5,HWID-10," |.' | |%11ld",formerscore); mvprintw(a+6,HWID-10," | | held by"); mvprintw(a+7,HWID-10," ___| |___%7s!",formername); mvprintw(a+8,HWID-10," | |"); mvprintw(a+9,HWID-10," |____________|"); mvprintw(LEN-3,HWID-11,"Press a key to continue"); refresh(); do{ input=getch(); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); filled_rect(0,0,LEN,WID); red_border(); } } //scorefile is still open with w+ char pname[60] = {0}; long pscore=0; byte rank=0; rewind(score_file); mvaddstr(1,WID/2-4,"HIGH SCORES"); while( rank>>"); printw("%s",pname); mvprintw(2+2*rank,WID-1-digit_count(pscore),"%ld",pscore); ++rank; } refresh(); } void help(void){ nocbreak(); cbreak(); filled_rect(0,0,LEN,WID); red_border(); mvprintw(1,HWID-4,"GAME PLAY"); mvprintw(3,1,"If you hit a letter on keyboard, the letter on the"); mvprintw(4,1,"screen will soon stop. You have to aim for the"); mvprintw(5,1,"center of the target using the moving letters."); refresh(); getch(); halfdelay(1); } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } int main(int argc,char** argv){ if(argc>1){ printf("This game doesn't take arguments"); } signal(SIGINT,sigint_handler); initscr(); noecho(); cbreak(); keypad(stdscr,1); srand(time(NULL)%UINT_MAX); if(has_colors()){ start_color(); init_pair(1,COLOR_RED,COLOR_BLACK); init_pair(2,COLOR_YELLOW,COLOR_BLACK); init_pair(3,COLOR_GREEN,COLOR_BLACK); for(byte b=0;b<3;++b) colors[b]=COLOR_PAIR(b+1); } make_background(); byte really_quit=0; Start: really_quit=0; erase(); halfdelay(1); curs_set(0); score=0; msg_show=0; aims_to_stop=shots=SHOTS_WHEN_STARTING; fill_aims(); while(1){ draw(); refresh(); input=getch(); if(input=='?' || input==KEY_F(1)) help(); if(input>='a' && input<='z'){ input=input-'a'+'A'; } if(input>='A' && input<='Z' && shots){ if(!aims[input-'A'].brake){ aims[input-'A'].brake=15; --shots; } } if(input=='Q'){ if(really_quit==0){ strcpy(msg,"ESC or Ctrl-C to quit."); msg_show=50; really_quit=1; } else{ break; } } if(input==27){ break; } if(input!=ERR){ usleep(100000); flushinp(); } if(!aims_to_stop){ break; } for(int i=0;i<26;++i){ move_aim(aims+i); } } flushinp(); nocbreak(); cbreak(); curs_set(1); end_scene(); show_scores(save_score()); attron(colors[0]|A_STANDOUT); mvprintw(LEN-1,HWID-11,"Wanna play again? (y/n)"); attroff(colors[0]|A_STANDOUT); do{ input=getch(); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); if(input!='q' && input!='n' && input!='N') goto Start; endwin(); return 0; } nbsdgames-6.0.1/fifteen.c000066400000000000000000000136661517406336500152730ustar00rootroot00000000000000/* .-- |__ | IFTEEN Authored by abakh 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 . */ #include "common.h" /* The Plan9 compiler can not handle VLAs */ #ifdef NO_VLA #define size 4 #else byte size=4; #endif byte py,px; byte ey,ex; //the empty tile chtype green=A_BOLD; //bold when there is no color 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, ".--"); mvaddstr(sy+1,sx,"|__"); mvaddstr(sy+2,sx,"| IFTEEN"); } //convert integer to representing sign char int2sgn(byte num){ if(!num) return ' '; else if(0< num && num <= 9) return num+'0'; else if(10<=num && num <=35) return num-10+'a'; else if(36<=num && num <=51) return num-36+'A'; return 0; } /*bool isinorder(byte board[size][size],byte y,byte x){ using check[][] is much cheaper return (board[y][x] == y*size+x+1); } */ //display void draw(byte sy,byte sx,char board[size][size],char check[size][size]){ rectangle(sy,sx); chtype prnt; byte y,x; for(y=0;y=0 && y=0 && x0)? 1:-1; if(ex!=x) dx=(x-ex >0)? 1:-1; while(ex!=x || ey!=y){ slide_one(board,ey+dy,ex+dx);//ey/x comes forth itself } ey=y; ex=x; } } bool issolved(char board[size][size],char check[size][size]){ byte y,x; for(y=0;y7){ fprintf(stderr,"3<=size<=7"); } break; #endif //NO_VLA case 'n': no_replay=1; break; case 'h': default: printf("Usage:%s [options]\n -s size\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_GREEN,-1); green=COLOR_PAIR(1); } char board[size][size]; char check[size][size]; fill(check); int input; Start: py=px=0; ey=ex=size-1; curs_set(0); fill(board); shuffle(board); while(1){ erase(); logo(0,0); draw(3,0,board,check); refresh(); if(issolved(board,check)) break; 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) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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 . */ #include "common.h" #define SAVE_TO_NUM 11 #define HOOKS 10 #define LEN 24 #define HLEN LEN/2 #define WID 80 #define HWID WID/2 #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif // 12 lines of water // 80 columns chtype colors[4]={A_NORMAL,A_STANDOUT}; byte fish[10]={0};//positions byte caught=-1; bool stop[10]={0}; unsigned int count[10]={0}; unsigned long score=0; const char sym[]="~:=!@+><;&"; byte hook=0, hooknum=0; byte clb,clbtime=0; int input; void filled_rect(byte sy,byte sx,byte ey,byte ex){ byte y,x; for(y=sy;y0){ byte a = (LEN-9)/2; star_line(1); star_line(LEN-2); mvaddstr(1,WID/2-8,"CONGRATULATIONS!!"); mvprintw(a+1,HWID-10," _____You beat the"); mvprintw(a+2,HWID-10," .' | previous"); mvprintw(a+3,HWID-10," .' | record"); mvprintw(a+4,HWID-10," | .| | of"); mvprintw(a+5,HWID-10," |.' | |%11ld",formerscore); mvprintw(a+6,HWID-10," | | held by"); mvprintw(a+7,HWID-10," ___| |___%7s!",formername); mvprintw(a+8,HWID-10," | |"); mvprintw(a+9,HWID-10," |____________|"); mvprintw(LEN-3,HWID-11,"Press a key to continue"); refresh(); do{ input=getch(); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); filled_rect(0,0,LEN,WID); green_border(); } } //scorefile is still open with w+ char pname[60] = {0}; long pscore=0; byte rank=0; rewind(score_file); mvaddstr(1,WID/2-4,"HIGH SCORES"); attron(colors[3]); while( rank>>"); printw("%s",pname); mvprintw(2+2*rank,WID-1-digit_count(pscore),"%ld",pscore); ++rank; } attroff(colors[3]); refresh(); } void help(void){ nocbreak(); cbreak(); attron(colors[3]); filled_rect(0,0,LEN,WID); green_border(); mvprintw(1,HWID-4,"GAME PLAY"); mvprintw(3,1,"Catch a fish and reel it in for points"); mvprintw(4,1,"The deeper the fish, the more points it is worth."); mvprintw(5,1,"If a fish hits your line, you lose a hook."); mvprintw(6,1,"When you run out of hooks, the game is over!"); mvprintw(8,HWID-4,"CONTROLS"); mvprintw(10,1,"UP & DOWN: Control the hook"); mvprintw(11,1,"q: Quit"); mvprintw(13,1,"This is a port of \"Deep Sea Fisher\", a MikeOS game."); attroff(colors[3]); refresh(); getch(); halfdelay(1); } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } int main(int argc,char** argv){ if(argc>1){ printf("This game doesn't take arguments"); } signal(SIGINT,sigint_handler); initscr(); noecho(); cbreak(); keypad(stdscr,1); srand(time(NULL)%UINT_MAX); for(byte n=0;n<10;++n) fish[n]=rand()%80; if(has_colors()){ start_color(); init_pair(1,COLOR_BLACK,COLOR_CYAN); init_pair(2,COLOR_BLACK,COLOR_BLUE); init_pair(3,COLOR_WHITE,COLOR_GREEN); init_pair(4,COLOR_BLACK,COLOR_WHITE); for(byte b=0;b<4;++b) colors[b]=COLOR_PAIR(b+1); } byte n; Start: halfdelay(1); curs_set(0); clbtime=0; hook=0; hooknum=HOOKS; score=0; memset(count,0,10*sizeof(unsigned int) ); while(1){ draw(); refresh(); input=getch(); for(n=0;n<10;++n){ if(stop[n]){ if(rand()%(n+15)==0)//this is to make the fish move stop[n]=0; continue; } if(n%2) fish[n]--; else fish[n]++; if(fish[n]<0) fish[n]=79; if(fish[n]>79) fish[n]=0;//appear on the other end if(fish[n]==40){ if(hook>n+1){ caught= -1; hook=0; --hooknum; } if(hook==n+1 && caught==-1){ caught=n; if(n%2) fish[n]=79; else fish[n]=0; } } if(rand()%(14-n)==0)//this is to make it stop stop[n]=1; } if((input==KEY_UP||input=='w')){ if(hook>0) --hook; if(hook==0 && caught!=-1){ count[caught]++; score+=(caught+1)*(caught+1); clb=caught; clbtime=10;//celebrate catching the fish caught=-1; } } if((input==KEY_DOWN||input=='s')){ if(hook<11) ++hook; if(fish[hook-1]==40 && caught==-1){ caught=hook-1; if(n%2) fish[hook-1]=0; else fish[hook-1]=79; } } if(input=='?' || input==KEY_F(1)) help(); if((input=='q'||input==27)) break; if(!hooknum) break; if(input!=ERR){ usleep(100000); flushinp(); } } flushinp(); nocbreak(); cbreak(); curs_set(1); show_scores(save_score()); attron(colors[2]); mvprintw(LEN-1,HWID-11,"Wanna play again? (y/n)"); attroff(colors[2]); do{ input=getch(); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); if(input!='q' && input!='n' && input!='N') goto Start; endwin(); return 0; } nbsdgames-6.0.1/futureideas.txt000066400000000000000000000011371517406336500165560ustar00rootroot00000000000000games to make: bomberman centipede xonix blastball chase sortwars guerre scissor orbit artillery obwalt redistribution frog pong jumpwars skrimish ufohunt riverraid keepball hitandrun boas things to do: support compilation as a single binary add mouse support to games that don't have it fix revenge's bugs start AI games as super stupid make fisher work in smaller screens, change the color scheme imporve redsquare gameplay (adding complicated score, not going to next level when you lose) reorder the games in the menu so that the funner games come first, and noobs don't get lost trying to win sudoku nbsdgames-6.0.1/jewels.c000066400000000000000000000207251517406336500151360ustar00rootroot00000000000000/* Jewels Authored by abakh 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 . 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. TODO make it like puyo puyo instead of the remake of what i poorly remembered*/ #include "common.h" #define LEN 17 #define WID 19 #define DELAY 2 #define SAVE_TO_NUM 10 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"; byte save_score(void){ return fallback_to_home("jewels_scores",score,SAVE_TO_NUM); } void show_scores(byte playerrank){ if(playerrank==FOPEN_FAIL){ printf("Could not open scorefile."); abort(); } if(playerrank == 0){ char formername[60]={0}; long formerscore=0; rewind(score_file); fscanf(score_file,"%*s : %*d\n"); if ( fscanf(score_file,"%s : %ld\n",formername,&formerscore)==2){ printf("\n*****CONGRATULATIONS!****\n"); printf(" _____ You beat the\n"); printf(" .' | previous\n"); printf(" .' | record\n"); printf(" | .| | of\n"); printf(" |.' | |%14ld\n",formerscore); printf(" | | held by\n"); printf(" ___| |___%11s\n",formername); printf(" | |\n"); printf(" |____________|\n"); printf("*************************\n"); } } //scorefile is still open with w+ char pname[60] = {0}; long pscore=0; byte rank=0; rewind(score_file); printf("\n>*>*>Top %d<*<*<\n",SAVE_TO_NUM); while( rank>>"); printf("%d) %s : %ld\n",rank+1,pname,pscore); ++rank; } putchar('\n'); fclose(score_file); } //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:%ld",score); mvaddstr(1,0,"Next:"); addch(next1); addch(next2); for(byte y=0;y1){ printf("This game doesn't take arguments"); } initscr(); cbreak(); halfdelay(DELAY); noecho(); curs_set(0); wnoutrefresh(stdscr); keypad(stdscr,1); int input; bool falls; byte stop=0 , combo; char jwstr[] = "*^~\"$V"; if(has_colors()){ start_color(); use_default_colors(); init_pair(1,COLOR_RED,-1); init_pair(2,COLOR_GREEN,-1); init_pair(3,COLOR_MAGENTA,-1); init_pair(4,COLOR_BLUE,-1);//array this thing init_pair(5,COLOR_YELLOW,-1); init_pair(6,COLOR_CYAN,-1); for(byte n=0;n<6;++n){ colors[n] = COLOR_PAIR(n+1); } } srand(time(NULL)%UINT_MAX); byte ran1= rand()%6; byte ran2= rand()%6; next1= colors[ran1]|jwstr[ran1]; next2= colors[ran2]|jwstr[ran2]; while(1){ chtype a,b; a=board[0][WID/2]; b=board[0][WID/2-1]; if(a || b ){ goto Lose; } jy=ky=0; jx=WID/2; kx=-1; board[jy][jx]=next2; board[jy+ky][jx+kx]=next1; ran1= rand()%6; ran2= rand()%6; next1=colors[ran1]|jwstr[ran1]; next2=colors[ran2]|jwstr[ran2]; falls = 1; while(falls){ input = getch(); if(input != ERR) stop+=1; if( stop >= 10){ falls=fall(); stop=0; } else if(input=='l' || (input==KEY_RIGHT||input=='d')) jmove(0,+1); else if(input=='j' || (input==KEY_LEFT||input=='a') ) jmove(0,-1); else if(input=='k' || (input==KEY_UP||input=='w')) 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'||input==27)) 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); show_scores(save_score()); return EXIT_SUCCESS; } nbsdgames-6.0.1/mail.md000066400000000000000000000122321517406336500147370ustar00rootroot00000000000000First of all, thanks for reading and sorry if this email reaches you multiple times, your distro's fans might agree too much with the points made below. This 2-minutes read is about the zero-cost but influential and significantly beneficial decision to include the 93.7 kB package of nbsdgames (which are 21 games with a lot of variety, creativity, endless gameplay and a menu icon) as default games on your distro (maybe alongside or instead of the other games you include, if you already do). Here are some reasons for doing so (arguably it is more important than the important calculator app you probably already include) along with answers to common questions that might arise: * The way any user would feel about any product including your OS, is very dependent on the first impression it makes. Technical problems and learning curves are also very common. If you include games in your OS, their first impression would be "dozens of cool stuff, followed by one or two problems" however if you don't include games the first impression would be almost entirely made of the problems and difficulties they would face and they would not like and talk positively about your OS (similar to the way many people feel about vim because they couldn't manage to exit it the first time) * It is something exotic that Windows doesn't have and your users can show their not-techy-yet friends to evoke their interest. * Its cost is a fraction of a megabyte, less than a wallpaper, its benefit is many hours of positive user experience for many people who try your distro. * I have seen a lot of users (including programmers) avoid Linux because they fear the command-line, and they don't learn the command-line because they don't begin to use it. Terminal games make them begin to use the Terminal and make the impression that the Terminal is cool, easy and usable. * A lot of users try OSes on VMs. A lot of people dual-boot OSes with Windows. I have seen that default games give them motivation to boot the OS more than once, play the games and also see and try other things there. * These can motivate non-techy people to install Linux on their old PCs so children could play and tinker with them (it did happen back when Windows included games) few years later those children could be benefiting you and others because it made them try Linux more. * As I said, technical problems are common. A lot of them are significant annoyances (network problems, dual-boot difficulties) that last many hours for the users and could make them give up. Games are good mental rests that make it go easy. People in NetBSD made a good choice when they put a tetris game in their /rescue directory. * Minimal programs like this are good at propagating the Unix philosophy, "KISS", and the important reality that one small program might do a job better than many much bigger inefficient programs. If I were to show how Free Software managed to perform better than commercial products, I would begin with introducing such concepts. FAQ: + Why Windows and phone vendors stopped shipping games? - The games on old phones and old Windows versions were popular however since their "new looking" games started becoming too heavy they stopped being justifiable (the latest minesweeper is like 100 MB, not to mention other games). They also make money from their spyware social media apps and other stuff that compete with games over the user's boredom and attention. They also needed to pay their game developers, unlike the free and open source nbsdgames. + Not many people asked us for games. - Supply often precedes demand. Nobody asks an empty store to give them the stuff they need. Most inventions were probably not asked for. Same applies here. + People can install games themselves. - Default applications (like your default browser, default office suite, bluetooth wizard and other stuff) exist because the user can't predict and prepare exactly everything they would need later on, and they wouldn't have the time and energy to search and compare every possible choice at the second they need something. Good defaults are a significant help everywhere. + We already have games. - The cute little nbsdgames could be a good friend for them. It also has much less size and far more varied gameplay and more colorful looks than the default games I have seen. It is also important to note that games are there to entertain people, and some packages aren't good at the purpose they should serve. For example they include very few games with very repetitive gameplay that are not interesting for more than minutes, not being "easy to learn and hard to master". For instance I like sgt-puzzles because the package is open-source however it is too gray and entirely slow-paced and I couldn't figure out how to play most of them back when I was bored enough to try them out. However nbsdgames has fast-paced games, slow-paced games, easy games, hard games, puzzle games, focus games, so on. When you get tired of one game you can play all the others. I hope you realize that I make this points because it is a good package not because it is my package (same applies to the person who sent you this email). I did it because I thought it is a good thing to do and it seems that it is so. nbsdgames-6.0.1/man/000077500000000000000000000000001517406336500142465ustar00rootroot00000000000000nbsdgames-6.0.1/man/battleship.6000066400000000000000000000007271517406336500165020ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "BATTLESHIP" "" "May 2021" "" "" .SH "NAME" \fBbattleship, nbbattleship\fR .SH "CONTROLS" RETURN/ENTER : Shoot .TP R : Rotate .TP hjkl/ARROW KEYS : Move cursor .TP q : Quit .TP F1 & F2 : Help on controls & gameplay .TP YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" Guess the location of your opponent\'s .TP ships and sink them! The player .TP who sinks all the opponent\'s ships wins\. nbsdgames-6.0.1/man/checkers.6000066400000000000000000000015611517406336500161270ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "CHECKERS" "" "May 2021" "" "" .SH "NAME" \fBcheckers, nbcheckers\fR .SH "CONTROLS" RETURN/ENTER : Select or move the piece .P hjkl/ARROW KEYS : Move cursor .P q : quit .P F1 & F2 : Help on controls & gameplay .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" 1) The game starts with each player having 12 men; .P men can only diagonally move forwards .P (toward the opponet\'s side)\. .P 2) Men can become kings by reaching the opponet\'s .P first rank; kings can diagonally move both forwards .P and backwards\. .P 3) Pieces can capture opponet\'s pieces by jumping over them .P also they can capture several pieces at once by doing a .P chain of jumps\. .P 4) You have to do a jump if you can\. .P 5) A player wins when the opponet can\'t do a move e\. g\. .P all of their pieces are captured\. nbsdgames-6.0.1/man/darrt.6000066400000000000000000000004731517406336500154550ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "DARRT" "" "May 2021" "" "" .SH "NAME" \fBdarrt, nbdarrt\fR .SH "GAMEPLAY" If you hit a letter on keyboard, the letter on the .P screen will soon stop\. You have to aim for the .P center of the target using the moving letters\. nbsdgames-6.0.1/man/fifteen.6000066400000000000000000000006161517406336500157600ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "FIFTEEN" "" "May 2021" "" "" .SH "NAME" \fBfifteen, nbfifteen\fR .SH "CONTROLS" RETURN/ENTER : Slide .P hjkl/ARROW KEYS : Move cursor .P q : Quit .P F1 & F2 : Help on controls & gameplay .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" Slide the tiles until the numbers and characters are .P in the right order\. nbsdgames-6.0.1/man/fisher.6000066400000000000000000000010071517406336500156130ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "FISHER" "" "May 2021" "" "" .SH "NAME" \fBfisher, nbfisher\fR .SH "CONTROLS" UP & DOWN: Control the hook .P q: Quit .P This is a port of "Deep Sea Fisher", a MikeOS game\. .SH "GAMEPLAY" Catch a fish and reel it in for points .P The deeper the fish, the more points it is worth\. .P If a fish hits your line, you lose a hook\. .P When you run out of hooks, the game is over! .P This is a port of "Deep Sea Fisher", a MikeOS game\. nbsdgames-6.0.1/man/jewels.6000066400000000000000000000002761517406336500156330ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "JEWELS" "" "May 2021" "" "" .SH "NAME" \fBjewels, nbjewels\fR .P j,l\-Move k\-Rotate p\-Pause q\-Quit nbsdgames-6.0.1/man/memoblocks.6000066400000000000000000000010701517406336500164660ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "MEMOBLOCKS" "" "May 2021" "" "" .SH "NAME" \fBmemoblocks, nbmemoblocks\fR .SH "CONTROLS" RETURN/ENTER : Reveal .P hjkl/ARROW KEYS : Move cursor .P q : Quit .P F1 & F2 : Help on controls & gameplay .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" Click on a tile to see the glyph it contains, .P then try to find a matching glyph the same way\. .P They form a pair only when you click a tile .P directly after the match\. The game ends when .P you have found all the matching pairs\. nbsdgames-6.0.1/man/miketron.6000066400000000000000000000007121517406336500161650ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "MIKETRON" "" "May 2021" "" "" .SH "NAME" \fBmiketron, nbmiketron\fR .SH "CONTROLS" hjkl/ARROW KEYS : Change direction .P q : Quit .P F1 & F2: Help on controls & gameplay .SH "GAMEPLAY" You are controlling a strange vechile which can .P survive explosions but cannot cross the trail it has .P left behind\. Keep it running as much as you can\. .P Plagiarized from MikeOS nbsdgames-6.0.1/man/mines.6000066400000000000000000000012711517406336500154510ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "MINES" "" "May 2021" "" "" .SH "NAME" \fBmines, nbmines\fR .SH "CONTROLS" RETURN/ENTER : Examine for bombs .P SPACE : Flag/Unflag .P hjkl/ARROW KEYS : Move cursor .P q : Quit .P F1 & F2 : Help on controls & gameplay .P PgDn,PgUp,\fI,\fR : Scroll .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" Try to find the landmines in the field .P with logical reasoning: When you click .P on a tile ( a \'\.\' here), numbers may show .P up that indicate the number of landmines .P in adjacent tiles; you should find and .P avoid the landmines based on them; and .P clicking on a landmine would make you .P lose the game\. nbsdgames-6.0.1/man/muncher.6000066400000000000000000000004611517406336500157770ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "MUNCHER" "" "May 2021" "" "" .SH "NAME" \fBmuncher, nbmuncher\fR .SH "CONTROLS" hjkl/ARROW KEYS : Change direction .P q : Quit .P F1 & F2: Help on controls & gameplay .SH "GAMEPLAY" Eat the food and avoid the traps\. nbsdgames-6.0.1/man/pipes.6000066400000000000000000000006611517406336500154600ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "PIPES" "" "May 2021" "" "" .SH "NAME" \fBpipes, nbpipes\fR .SH "CONTROLS" RETURN/ENTER : Place/Replace a pipe .P hjkl/ARROW KEYS : Move cursor .P p : Pause .P q : Quit .P f : Toggle fast flow .P F1 & F2 : Help on controls & gameplay .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" Keep maintaining the pipeline and .P don\'t let the sewage leak\. nbsdgames-6.0.1/man/rabbithole.6000066400000000000000000000007701517406336500164540ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "RABBITHOLE" "" "May 2021" "" "" .SH "NAME" \fBrabbithole, nbrabbithole\fR .SH "CONTROLS" hjkl/ARROW KEYS : Move cursor .P q : Quit .P F1 & F2: Help on controls & gameplay (viewing these pages doesn\'t pause the timer!) .P PgDn,PgUp,\fI,\fR : Scroll .SH "GAMEPLAY" Try to gather all the carrots in the maze .P in the given time\. The determining factors .P are your choice of paths and the speed of .P your fingers\. nbsdgames-6.0.1/man/redsquare.6000066400000000000000000000006321517406336500163310ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "REDSQUARE" "" "May 2021" "" "" .SH "NAME" \fBredsquare, nbredsquare\fR .SH "CONTROLS" hjkl/ARROW KEYS : Move square .P q : Quit .P F1 & F2 : Help on controls & gameplay .SH "GAMEPLAY" Move the square and catch the X or outnumber the .P white cells with those of your own, .P in the environment of Conway\'s game of life\. nbsdgames-6.0.1/man/reversi.6000066400000000000000000000014111517406336500160110ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "REVERSI" "" "May 2021" "" "" .SH "NAME" \fBreversi, nbreversi\fR .SH "CONTROLS" RETURN/ENTER : Put the piece .P hjkl/ARROW KEYS : Move cursor .P q : Quit .P F1 & F2 : Help on controls & gameplay .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" Players take turns placing disks on the board: .P 1) Any pieces of the opponet\'s color that is bounded .P in a straight line between the piece just placed and .P another piece of the current player\'s color would turn .P to the current player\'s color\. .P 2) You can only put pieces if at least one of your .P opponet\'s pieces turns into your color\. .P 3) The game ends when neither side can do a move and .P the player with more pieces wins\. nbsdgames-6.0.1/man/snakeduel.6000066400000000000000000000004051517406336500163070ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "SNAKEDUEL" "" "May 2021" "" "" .SH "NAME" \fBsnakeduel, nbsnakeduel\fR .SH "CONTROLS" hjkl/ARROW KEYS : Change direction .P q : Quit .P F1 & F2: Help on controls & gameplay nbsdgames-6.0.1/man/sos.6000066400000000000000000000010421517406336500151360ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "SOS" "" "May 2021" "" "" .SH "NAME" \fBsos, nbsos\fR .SH "CONTROLS" hjkl/ARROW KEYS : Move cursor .P S & O : Write S or O .P q : Quit .P F1 & F2: Help on controls & gameplay .P PgDn,PgUp,\fI,\fR : Scroll .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" The game is similar to Tic Tac Toe: .P The players write S and O in the squares .P and making the straight connected sequence .P S\-O\-S makes you a score; obviously, the .P player with a higher score wins\. nbsdgames-6.0.1/man/sudoku.6000066400000000000000000000013251517406336500156500ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.8.0 .\" http://github.com/apjanke/ronn-ng/tree/0.8.0 .TH "SUDOKU" "" "May 2021" "" "" .SH "NAME" \fBsudoku, nbsudoku\fR .SH "CONTROLS" 1 \- g : Enter number/character .P SPACE : Clear tile .P ARROW KEYS : Move cursor .P q : Quit .P n : New board .P r : Restart .P ? : Hint (not like in other games) .P F1 & F2: Help on controls & gameplay .P PgDn,PgUp,\fI,\fR : Scroll .P YOU CAN ALSO USE THE MOUSE! .SH "GAMEPLAY" Fill the table with digits (and characters) .P so that all the rows, columns and smaller subregions .P contain all of the digits from 1 to 9 and all .P the alphabet letters from \'a\' to \'g\'\. .SH "BUGS" Doesn\'t guarantee a unique solution\. Attempts to fix that are welcome\. nbsdgames-6.0.1/memoblocks.c000066400000000000000000000133331517406336500157750ustar00rootroot00000000000000/* . . _ |\/| |_) | |EMORY|_)LOCKS Authored by abakh 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 . */ #include "common.h" typedef unsigned char ubyte; #define size 8 #define size2 16 byte py,px; byte fy,fx; //the first 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+size2+1,ACS_VLINE); } for(byte x=0;x<=size2+1;++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+size2+1,ACS_URCORNER); mvaddch(sy+size+1,sx+size2+1,ACS_LRCORNER); } void logo(byte sy,byte sx){ mvaddstr(sy,sx, ". . _"); mvaddstr(sy+1,sx,"|\\/| |_)"); mvaddstr(sy+2,sx,"| |EMORY|_)LOCKS"); } //convert integer to representing sign char int2sgn(byte num){ if(0< num && num <= 9) return num+'0'; else if(10<=num && num <=35) return num-10+'a'; else if(36<=num && num <=51) return num-36+'A'; else if(52<=num && num<=64) return num-52+'!'; return 0; } //display void draw(byte sy,byte sx,chtype board[size][size2],bool show[size][size2]){ rectangle(sy,sx); byte y,x; chtype prnt; for(y=0;y1){ printf("This game doesn't take arguments"); } 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(); if( has_colors() ){ start_color(); use_default_colors(); init_pair(1,COLOR_YELLOW,-1); init_pair(2,COLOR_GREEN,-1); init_pair(3,COLOR_BLUE,-1); init_pair(4,COLOR_CYAN,-1); init_pair(5,COLOR_MAGENTA,-1); init_pair(6,COLOR_RED,-1); for(byte b=0;b<6;++b){ colors[b]=COLOR_PAIR(b+1); } } } chtype board[size][size2]; bool show[size][size2]; int input; time_t tstart,now; Start: tstart=time(NULL); py=px=0; fy=fx=-1; curs_set(0); memset(show,0,size*size2); fill(board); shuffle(board); while(1){ erase(); logo(0,0); draw(3,0,board,show); refresh(); if(issolved(show)) break; 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) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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 . */ #include "common.h" #define SAVE_TO_NUM 10 #define MINLEN 10 #define MAXLEN 24 #define MINWID 40 #define MAXWID 80 #define FLIGHT_TIME 16 #define NOTRAIL_TIME 30 #define BOMB_RANGE 8 enum {UP=1,RIGHT,DOWN,LEFT,FLIGHT,NOTRAIL,BOMB,SPAWN,STOP,SUPERFOOD,TRAIL}; /* The Plan9 compiler can not handle VLAs and usleep is a POSIX function */ #ifdef NO_VLA #define len 10 #define wid 40 #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif #else int len=MINLEN,wid=MINWID; #endif//NO_VLA int py,px; int immunity,flight,notrail; byte direction; long score; chtype colors[6]={0}; byte pse_msg=100; //no need to a epilepsy variable like in muncher as zeroing the colors suffices FILE *scorefile; void move_tron(void){ switch(direction){ case UP: --py; break; case DOWN: ++py; break; case LEFT: --px; break; case RIGHT: ++px; break; } if(py==-1) py=len-1; else if(py==len) py=0; if(px==-1) px=wid-1; else if(py==len) py=0; } void logo(void){ mvaddstr(1,0,"|\\/|"); mvaddstr(2,0,"| |IKETRON"); } byte save_score(void){ return fallback_to_home("miketron_scores",score,SAVE_TO_NUM); } void show_scores(byte playerrank){ erase(); logo(); if(playerrank==FOPEN_FAIL){ mvaddstr(3,0,"Couldn't open scorefile."); 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); attron(colors[b]); 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," |____________|"); attroff(colors[b]); b=(b+1)%6; if(getch()==ERR) goto Effect; nocbreak(); cbreak(); erase(); logo(); } } //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>>"); printw("%d) %s : %ld\n",rank+1,pname,pscore); ++rank; } addch('\n'); refresh(); } void put_stuff(byte board[len][wid],byte num){ byte y,x; for(byte n=0;npy-5 && ypx-10 && x0){ mvprintw(len+5,0,"Suffering PSE? Press e."); --pse_msg; } effect=(effect+1)%6; } void explode(byte board[len][wid],int by,int bx){ board[by][bx]=0;//prevent endless recursion int sy=by-BOMB_RANGE/2; int sx=bx-BOMB_RANGE; int ey=by+BOMB_RANGE/2; int ex=bx+BOMB_RANGE; if(ey>=len) ey-=len; if(ex>=wid) ex-=wid; if(sy<0) sy+=len; if(sx<0) sx+=wid; int y=sy; int x=sx; while(y!=ey){ while(x!=ex){ ++x; if(x==wid) x=0; if(board[y][x]==BOMB) explode(board,y,x); board[y][x]=-10; } x=sx; ++y; if(y==len) y=0; } } void gameplay(void){ nocbreak(); cbreak(); erase(); logo(); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("You are controlling a strange vehicle which can \n"); printw("survive explosions but cannot cross the trail it has\n"); printw("left behind. Keep it running as much as you can."); refresh(); getch(); erase(); halfdelay(1); } void help(void){ nocbreak(); cbreak(); erase(); logo(); attron(A_BOLD); mvprintw(3,0," **** THE CONTROLS ****"); attroff(A_BOLD); mvprintw(4,0,"hjkl/ARROW KEYS : Change direction"); mvprintw(5,0,"q : Quit"); mvprintw(6,0,"F1 & F2: Help on controls & gameplay"); mvprintw(8,0,"Press a key to continue"); refresh(); getch(); erase(); halfdelay(1); gameplay(); } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } int main(int argc,char** argv){ if(argc>1){ printf("This game doesn't take arguments"); } #ifndef NO_VLA signal(SIGINT,sigint_handler); #endif initscr(); #ifndef NO_VLA len=LINES-7; if(lenMAXLEN){ len=MAXLEN; } wid=COLS-5; if(widMAXWID){ wid=MAXWID; } #endif srand(time(NULL)%UINT_MAX); byte board[len][wid]; bool halfspeed=0; initscr(); 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_CYAN,-1); init_pair(5,COLOR_MAGENTA,-1); init_pair(6,COLOR_RED,-1); for(byte b= 0;b<6;++b){ colors[b]=COLOR_PAIR(b+1); } } Start: immunity=flight=notrail=0; curs_set(0); halfdelay(1); score=0; direction=LEFT; py=len/2; px=wid/2; memset(board,0,len*wid); put_stuff(board,20); int preinput=0,input=0; while(1){ erase(); logo(); mvprintw(1,12,"Score:%ld",score); if(immunity){ mvprintw(2,12,"Immunity:%d",immunity); } else if(flight){ mvprintw(2,12,"Flight:%d",flight); } else if(notrail){ mvprintw(2,12,"NoTrail:%d",notrail); } draw(board); refresh(); preinput=input; input = getch(); if(input!=ERR)//hide message when a key is entered pse_msg=0; if(board[py][px]==SPAWN){ put_stuff(board,5); } else if(board[py][px]==BOMB){ explode(board,py,px); for(byte b=0;b<10;++b){ draw(board); refresh(); usleep(100000); } } else if(board[py][px]==STOP){ mvaddch(4+py,px+1,ACS_PLUS|A_STANDOUT); refresh(); nocbreak(); cbreak(); preinput=input; input=getch(); halfdelay(1); } else if(board[py][px]==SUPERFOOD){ immunity+=len+wid; } else if(board[py][px]==FLIGHT){ flight+=FLIGHT_TIME; } else if(board[py][px]==NOTRAIL){ notrail+=NOTRAIL_TIME; } else{ goto NoFeatures; } board[py][px]=0;//if one of conditions is true, it executes! keep nagging about goto being redundant! NoFeatures: if(board[py][px]==TRAIL){ if(immunity) board[py][px]=0; else if(!flight) break; } if( input == KEY_F(1) || input=='?' ) help(); if( (input==KEY_F(2)||input=='!') ) gameplay(); halfspeed=!halfspeed; if( (input=='k' || (input==KEY_UP||input=='w')) ){ direction=UP; halfspeed=1; } else if( (input=='j' || (input==KEY_DOWN||input=='s')) ){ direction=DOWN; halfspeed=1; } else if( (input=='h' || (input==KEY_LEFT||input=='a')) ) direction=LEFT; else if( (input=='l' || (input==KEY_RIGHT||input=='d')) ) direction=RIGHT; if( (input=='q'||input==27)) sigint_handler(0); if(input=='e'){ for(int b=0;b<6;++b){ colors[b]=0; } pse_msg=0; } if(input!=ERR){ if(preinput==input){//if it wasn't there, hitting two keys in less than 0.1 sec would not work usleep(100000); flushinp(); } } if( !((direction==UP||direction==DOWN)&&!halfspeed) && !immunity && !flight && !notrail) board[py][px]=TRAIL; if(direction==UP && halfspeed){ --py; if(py==-1) py=len-1; halfspeed=1; } else if(direction==DOWN && halfspeed){ ++py; if(py==len) py=0; } else if(direction==LEFT){ --px; if(px==-1) px=wid-1; } else if(direction==RIGHT){ ++px; if(px==wid) px=0; } ++score; if(!(score%100)){ put_stuff(board,5); put_trail(board,20); } if(immunity) --immunity; else if(flight) --flight; else if(notrail) --notrail; } nocbreak(); cbreak(); draw(board); refresh(); mvprintw(len+5,0,"Game over! Press a key to see the high scores:"); getch(); show_scores(save_score()); printw("Game over! Wanna play again?(y/n)"); curs_set(1); input=getch(); if( input!= 'N' && input!= 'n' && input!='q') goto Start; endwin(); return EXIT_SUCCESS; } nbsdgames-6.0.1/mines.c000066400000000000000000000215761517406336500147650ustar00rootroot00000000000000/* |\/| | |INES Authored by abakh 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 . compile with -lncurses */ #include "common.h" #define FLAG 9 #define UNCLEAR 10 #define MINLEN 8 #define MINWID 8 #define MAXLEN 1000 #define MAXWID 1000 #define EMPTY_LINES 7 #ifdef NO_VLA //The Plan9 compiler can not handle VLAs #define len 8 #define wid 8 #else int len=8,wid=8; #endif int py,px,flags; int untouched; int mscount; chtype colors[6]={0}; int beginy,view_len; void setup_scroll(){ beginy=0; if(0len){ beginy-=beginy+view_len-len; } } void rectangle(int sy,int sx){ setup_scroll(); for(int y=0;y<=view_len;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+wid*2,ACS_VLINE); } for(int x=0;x<=wid*2;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+view_len+1,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+view_len+1,sx,ACS_LLCORNER); mvaddch(sy,sx+wid*2,ACS_URCORNER); mvaddch(sy+view_len+1,sx+wid*2,ACS_LRCORNER); } byte get_cell(byte board[len][wid],int y,int x){ return board[(y+len)%len][(x+wid)%wid]; } //display void draw(int sy,int sx,byte board[len][wid]){ rectangle(sy,sx); chtype attr ; char prnt; int y,x; setup_scroll(); for(y=beginy;y9){ prnt='?'; } mvaddch(sy+1+(y-beginy),sx+x*2+1,attr|prnt); } } } //show the mines void drawmines(int sy,int sx,byte board[len][wid],byte mines[len][wid]){ int y,x; setup_scroll(); for(y=beginy;y=0 && board[ty][tx] <9)//it has been click()ed before return 0; else{//untouched if(board[ty][tx]==FLAG) --flags; board[ty][tx]=0; --untouched; } int y,x; for(y=ty-1;y=len) break; for (x=tx-1;x=wid) break; if(mines[y][x]) board[ty][tx]++; } } if(!board[ty][tx]){//there are no mines in the adjacent tiles for(y=ty-1;y=len) break; for(x=tx-1;x=wid) break; click(board,mines,y,x); } } } return 0; } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } void mouseinput(int sy, int sx){ #ifndef NO_MOUSE MEVENT minput; #ifdef PDCURSES nc_getmouse(&minput); #else getmouse(&minput); #endif if( minput.y-4-sy : Scroll"); mvprintw(12,0,"Press a key to continue"); refresh(); getch(); erase(); gameplay(); } int main(int argc, char** argv){ signal(SIGINT,sigint_handler); #ifndef NO_VLA int opt; while( (opt=getopt(argc,argv,"hnm:l:w:"))!=-1){ switch(opt){ case 'm': mscount=atoi(optarg); if(mscount<0 || mscount>len*wid){ fprintf(stderr,"Too few/many mines.\n"); } break; case 'l': len=atoi(optarg); if(lenMAXLEN){ fprintf(stderr,"Length too high or low.\n"); } break; case 'w': wid=atoi(optarg); if(widMAXWID){ fprintf(stderr,"Width too high or low.\n"); } break; case 'h': default: printf("Usage:%s [options]\n -l length\n -w width\n -m number of mines\n -h help\n",argv[0]); return EXIT_FAILURE; break; } } if(!mscount){ mscount=len*wid/6; } #else mscount=len*wid/6; #endif 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[len][wid]; byte mines[len][wid]; char result[70]; int input; int sy,sx; bool first_click; Start: first_click=1; sy=sx=0; py=px=0; untouched=len*wid; flags=0; curs_set(0); for(int y=0;y0){ sy=0; } } if( input==KEY_NPAGE && LINES< len+3){ sy-=10; if(sy< -(len+3) ){ sy=-(len+3); } } if( input=='<' && COLS< wid*2+1){ sx+=10; if(sx>0){ sx=0; } } if( input=='>' && COLS< wid*2+1){ sx-=10; if(sx< -(wid*2+1)){ sx=-(wid*2+1); } } if( input==KEY_F(1) || input=='?' ) help(); if( (input==KEY_F(2)||input=='!') ) gameplay(); if( input==KEY_MOUSE ) mouseinput(sy,sx); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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 . */ #include "common.h" #define SAVE_TO_NUM 10 #define MINLEN 10 #define MAXLEN 24 #define MINWID 40 #define MAXWID 80 enum {UP=1,RIGHT,DOWN,LEFT,FOOD,SUPERFOOD,TRAP}; /* The Plan9 compiler can not handle VLAs */ #ifdef NO_VLA #define len 36 #define wid 80 #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif #else int len,wid; #endif//NO_VLA int py,px;//pointer byte pse_msg=20;//flashing animations might hurt some people bool epilepsy=0; char alt_animation[4]={'-','\\','|','/'}; int immunity; byte direction; long score; chtype colors[6]={0}; FILE* scorefile; void logo(void){ mvaddstr(1,0,"|\\/|"); mvaddstr(2,0,"| |UNCHER"); } byte save_score(void){ return fallback_to_home("muncher_scores",score,SAVE_TO_NUM); } void show_scores(byte playerrank){ erase(); logo(); 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); attron(colors[b]); 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," |____________|"); attroff(colors[b]); b=(b+1)%6; if(getch()==ERR) goto Effect; nocbreak(); cbreak(); erase(); logo(); } } //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>>"); printw("%d) %s : %ld\n",rank+1,pname,pscore); ++rank; } addch('\n'); refresh(); } void rectangle(void){ for(int y=0;y<=len;++y){ mvaddch(3+y,0,ACS_VLINE); mvaddch(4+y,1+wid,ACS_VLINE); } for(int x=0;x<=wid;++x){ mvaddch(3,x,ACS_HLINE); mvaddch(4+len,x,ACS_HLINE); } mvaddch(3,0,ACS_ULCORNER); mvaddch(4+len,0,ACS_LLCORNER); mvaddch(3,1+wid,ACS_URCORNER); mvaddch(4+len,1+wid,ACS_LRCORNER); } void place_food(byte board[len][wid]){ int y,x; do{ y=rand()%len; x=rand()%wid; }while(y==py && x==px); board[y][x]=FOOD; byte num; if(score<300) num=rand()%2; else if(score<500) num=1+rand()%2; else if(score<1000) num=2+rand()%4; else if(score<2000) num=5+rand()%6; else num=10+rand()%11; while(num){ Again: y=rand()%len; x=rand()%wid; if(abs(y-py)<4 && abs(x-px)<7) goto Again; if(board[y][x]==FOOD) goto Again; board[y][x]=TRAP; --num; } if(score>2000 && !(rand()%5)){ do{ y=rand()%len; x=rand()%wid; }while(y==py && x==px && board[y][x]!=FOOD); board[y][x]=SUPERFOOD; } } void draw(byte board[len][wid]){ int y,x; static byte effect=0; chtype prnt; rectangle(); for(y=0;yMAXLEN) len=MAXLEN; wid=COLS-5; if(widMAXWID) wid=MAXWID; #endif srand(time(NULL)%UINT_MAX); byte board[len][wid]; bool halfspeed=0; int constant=150*(80*24)/(len*wid); initscr(); 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_CYAN,-1); init_pair(5,COLOR_MAGENTA,-1); init_pair(6,COLOR_RED,-1); for(byte b= 0;b<6;++b){ colors[b]=COLOR_PAIR(b+1); } } Start: curs_set(0); halfdelay(1); score=direction=immunity=0; py=len/2; px=wid/2; memset(board,0,len*wid); place_food(board); int preinput,input=0; while(1){ erase(); logo(); mvprintw(1,11,"Score:%ld",score); if(immunity) mvprintw(2,11,"Immunity:%d",immunity); draw(board); refresh(); if( board[py][px]==FOOD ){ score+= constant; board[py][px]=0; if(!epilepsy){ for(byte b=0;b<6;++b){ mvaddch(4+py,px+1,'r'|colors[b]|A_STANDOUT); refresh(); usleep(100000/5); } } place_food(board); } if( board[py][px]==SUPERFOOD ){ immunity+=(len+wid)/2; board[py][px]=0; } if(board[py][px]==TRAP){ if(immunity) board[py][px]=0; else break; } if(px<0 || px>=wid) break; halfspeed=!halfspeed; preinput=input; input = getch(); if( input == KEY_F(1) || input=='?' ) help(); if( (input==KEY_F(2)||input=='!') ) gameplay(); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0 ){ direction=UP; halfspeed=1; } if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0 ) direction=LEFT; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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 . */ #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "common.h" #define LEN 24 #define HLEN LEN/2 #define WID 100 #define HWID WID/2 #ifndef NB #define NB #endif #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif // 12 lines of water // 80 columns chtype colors[4]={A_NORMAL,A_STANDOUT}; char main_menu[]={ "See High Scores\n" NB"fisher\n" NB"darrt\n" NB"miketron\n" NB"muncher\n" NB"scissor\n" NB"reversi\n" NB"battleship\n" NB"jewels\n" NB"sudoku\n" NB"mines\n" NB"pipes\n" NB"checkers\n" NB"rabbithole\n" NB"snakeduel\n" NB"sos\n" NB"fifteen\n" NB"memoblocks\n" NB"tugow\n" NB"trsr\n" NB"revenge\n" NB"redsquare\n" }; char ascii_art[]={ " ###### ###### " " #################################### " " ###################################### " " ########################################" " ########################################" " ###################################### " " ###################################### " " ######## #### #### ######## " " ######### #########" " ######## ########" " ###### ######" }; char scores_menu[]={ "pipes_scores\n" "jewels_scores\n" "miketron_scores\n" "muncher_scores\n" "fisher_scores\n" "darrt_scores\n" "tugow_scores\n" "revenge_scores\n" "sjump_scores\n" }; char choice_str[100]={0}; char name[100]={0}; void fancy_background(){ int y,x; int lines=LINES,cols=COLS; for(y=0;y first_entry+(lines-3)){ first_entry=chosen-(lines-3); } if(chosen=1){ name[index-1]='\0'; --index; } } if(('a'<=input && input<='z') || ('0'<=input && input<='9')){ if(index<25){ name[index]=input; index++; } } } setenv("NB_PLAYER",name,1); } void scores(){ int choice; char address[1000]={0}; FILE* score_file; while(1){ switch(choice=menu(scores_menu,"High Scores")){ case -1: erase(); return; break; default: get_entry(scores_menu,choice,choice_str); snprintf(address,999,"%s/%s",SCORES_DIR,choice_str); if((score_file=fopen(address,"r"))){ show_scores(score_file); } snprintf(address,999,"%s/.%s",getenv("HOME"),choice_str); if((score_file=fopen(address,"r"))){ show_scores(score_file); } break; } } } int main(int argc,char** argv){ printf("\x1b]2;%s\x07","NBSDGAMES!");//change the title printf("\x1b]0;%s\x07","NBSDGAMES!"); if(argc>1){ printf("This game doesn't take arguments"); } signal(SIGINT,sigint_handler); initscr(); noecho(); cbreak(); keypad(stdscr,1); char path[104]; srand(time(NULL)%UINT_MAX); if(has_colors()){ start_color(); init_pair(1,COLOR_RED,COLOR_BLACK); init_pair(2,COLOR_MAGENTA,COLOR_BLACK); init_pair(3,COLOR_YELLOW,COLOR_BLACK); init_pair(4,COLOR_GREEN,COLOR_BLACK); for(int b=0;b<4;++b){ colors[b]=COLOR_PAIR(b+1); } } int n; Start: curs_set(0); enter_name(); int choice; while(1){ switch(choice=menu(main_menu,"Main Menu")){ case -1: sigint_handler(EXIT_SUCCESS); break; case 0: scores(); break; default: def_prog_mode(); endwin(); get_entry(main_menu,choice,choice_str); if(system(choice_str) == 32512){ snprintf(path,103,"./%s",choice_str); system(path); } reset_prog_mode(); break; } } curs_set(1); endwin(); return 0; } nbsdgames-6.0.1/nbsdgames.desktop000066400000000000000000000003401517406336500170260ustar00rootroot00000000000000[Desktop Entry] Type=Application Encoding=UTF-8 Name=NBSDGAMES! Comment=Games! Games! Games! Icon=nbsdgames Exec=nbsdgames Terminal=true Categories=Game;ArcadeGame; Keywords=konsole;console;terminal;command;line;game;bored; nbsdgames-6.0.1/nbsdgames.svg000066400000000000000000000133511517406336500161620ustar00rootroot00000000000000 image/svg+xml nbsdgames-6.0.1/pipes.c000066400000000000000000000246141517406336500147660ustar00rootroot00000000000000/* _ |_) | IPES Authored by abakh 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 . */ #include "common.h" #define UP 1 #define RIGHT 2 #define DOWN 4 #define LEFT 8 #define CROSSOVER 15 #define FILLED 16 #define FLOWDELAY 5 #define DELAY 3 #define SAVE_TO_NUM 10 #define SY 0 #define SX 7 typedef unsigned char bitbox; /* The Plan9 compiler can not handle VLAs */ //#ifdef NO_VLA who uses that len wid arguments for this one? removed them #define wid 20 #define len 14 //#else //int len,wid; //#endif int py,px,fy,fx;//p: pointer f: fluid bitbox tocome[5]={0};//the row of pipes in the left side chtype green=A_BOLD;//will use bold font instead of green if colors are not available long score; void logo(void){ mvprintw(0,0," _ "); mvprintw(1,0,"|_)"); mvprintw(2,0,"| IPES"); } byte save_score(void){ return fallback_to_home("pipes_scores",score,SAVE_TO_NUM); } void show_scores(byte playerrank){ erase(); logo(); if(playerrank==FOPEN_FAIL){ mvaddstr(SY,SX,"Couldn't open scorefile"); mvprintw(SY+1,SX,"However, 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"); if ( fscanf(score_file,"%s : %ld",formername,&formerscore)==2 && formerscore>0){ byte a = (len-9)/2; attron(A_BOLD); mvprintw(SY,SX, "**** ***"); mvprintw(SY+len+1,SX,"***********************"); attroff(A_BOLD); attron(green); mvprintw(SY,SX+4,"CONGRATULATIONS!"); attroff(green); mvprintw(SY+a+1,SX," _____You beat the"); mvprintw(SY+a+2,SX," .' | previous"); mvprintw(SY+a+3,SX," .' | record"); mvprintw(SY+a+4,SX," | .| | of"); mvprintw(SY+a+5,SX," |.' | |%11ld",formerscore); mvprintw(SY+a+6,SX," | | held by"); mvprintw(SY+a+7,SX," ___| |___%7s!",formername); mvprintw(SY+a+8,SX," | |"); mvprintw(SY+a+9,SX," |____________|"); mvprintw(len+2,0,"Game over! Press a key to proceed:"); refresh(); getch(); erase(); logo(); } } attron(A_BOLD); mvprintw(3,0," HIGH"); mvprintw(4,0,"SCORES"); attroff(A_BOLD); //scorefile is still open with w+ char pname[60] = {0}; long pscore=0; byte rank=0; rewind(score_file); while( rank>>"); printw("%d",rank+1); attroff(green); printw(") %s : %ld",pname,pscore); ++rank; } fclose(score_file); refresh(); } //move in direction void MID(bitbox direction){ switch(direction){ case UP: --fy; break; case DOWN: ++fy; break; case LEFT: --fx; break; case RIGHT: ++fx; break; } } bitbox opposite(bitbox direction){ switch(direction){ case UP: return DOWN; case DOWN: return UP; case LEFT: return RIGHT; case RIGHT: return LEFT; } return 0; } void rectangle(void){ for(int y=0;y<=len;++y){ mvaddch(SY+y,SX,ACS_VLINE); mvaddch(SY+y,SX+wid+1,ACS_VLINE); } for(int x=0;x<=wid;++x){ mvaddch(SY,SX+x,ACS_HLINE); mvaddch(SY+len+1,SX+x,ACS_HLINE); } mvaddch(SY,SX,ACS_ULCORNER); mvaddch(SY+len+1,SX,ACS_LLCORNER); mvaddch(SY,SX+wid+1,ACS_URCORNER); mvaddch(SY+len+1,SX+wid+1,ACS_LRCORNER); } //this generates the pipes... bitbox pipegen(void){ if(rand()%17){//17 so all forms have the same chance byte a=rand()%4; byte b; do{ b=rand()%4; }while(b==a); return (1 << a) | ( 1 << b); } else return CROSSOVER;//could not be generated like that } //.. and this is only for display void addpipe(int y,int x,bitbox pipe , bool highlight){ bitbox p= pipe & ~FILLED; chtype foo ; switch(p){ case UP|RIGHT : foo= ACS_LLCORNER; break; case UP|DOWN : foo=ACS_VLINE; break; case UP|LEFT : foo=ACS_LRCORNER; break; case DOWN|RIGHT : foo =ACS_ULCORNER; break; case DOWN|LEFT : foo=ACS_URCORNER; break; case LEFT|RIGHT: foo=ACS_HLINE; break; case RIGHT: foo = '>'; break; case LEFT: foo = '<'; break; case UP: foo = '^'; break; case DOWN: foo = 'v'; break; case CROSSOVER: //all foo = ACS_PLUS; break; default: foo = ' '; break; } if( pipe & FILLED ) foo |= green; mvaddch(y,x, foo|(highlight*A_REVERSE) ); } //display void draw(bitbox board[len][wid]){ int y,x; for(y=0;y= now-tstart){ mvprintw(4,0,"Time:%ld",giventime-(now-tstart)); mvprintw(5,0,"Score:"); mvprintw(6,0,"%ld",score); } else{ mvprintw(4,0,"Score:"); mvprintw(5,0,"%ld",score); } for(foo=0;foo<5;++foo) addpipe(11-foo,4,tocome[foo],0); draw(board); refresh(); if(now-tstart == giventime){ flow=1; } if(flow && (fast || ( !(now%FLOWDELAY)&& now!=lasttime ) )){ lasttime = now; MID(direction); if(fy=0&& fx>=0 && ( board[fy][fx]&opposite(direction) ) ){ if(board[fy][fx] != CROSSOVER && board[fy][fx] != (CROSSOVER|FILLED) ) direction = board[fy][fx] & ~opposite(direction); ++score; if(fast) ++score; } else goto End; board[fy][fx]|=FILLED; } input = getch(); if( input == KEY_F(1) || input=='?' ){ help(); if(!flow) tstart += time(NULL)-now; } if( (input==KEY_F(2)||input=='!') ){ gameplay(); if(!flow) tstart += time(NULL)-now; } if( input == KEY_MOUSE ) mouseinput(); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0 ) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0 ) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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 . compile with -lncurses */ #include "common.h" #define UP 1 #define RIGHT 2 #define DOWN 4 #define LEFT 8 #define VISITED 16 #define CARROT 32 typedef unsigned char bitbox; /* The Plan9 compiler can not handle VLAs */ #ifdef NO_VLA #define len 10 #define wid 20 #else int len,wid; #endif int py,px; chtype colors[6]={0}; typedef struct point{ int y; int x; } point; point MID(int y,int x,bitbox direction){//move in direction point pt = {y,x}; switch(direction){ case UP: --pt.y; return pt; case DOWN: ++pt.y; return pt; case LEFT: --pt.x; return pt; case RIGHT: ++pt.x; return pt; } return pt; } void rectangle(int sy,int sx){ for(int y=0;y<=len*2;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+wid*2,ACS_VLINE); } for(int x=0;x<=wid*2;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+len*2,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+len*2,sx,ACS_LLCORNER); mvaddch(sy,sx+wid*2,ACS_URCORNER); mvaddch(sy+len*2,sx+wid*2,ACS_LRCORNER); } void draw(int sy,int sx,bitbox board[len][wid]){ int y,x; bitbox d; chtype prnt; point pt; for(y=0;y : Scroll"); mvprintw(9,0,"Press a key to continue"); refresh(); while ( getch()==ERR ); erase(); gameplay(); } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } int main(int argc,char** argv){ if(argc>1){ printf("This game doesn't take arguments"); } signal(SIGINT,sigint_handler); initscr(); #ifndef NO_VLA if((LINES-7)/2 < 5){ len=5; } else{ len=(LINES-7)/2; } if((COLS-5)/2 < 20){ wid=20; } else{ wid=(COLS-5)/2; } #endif int carrot_count= (len*wid)/50; int carrots_found; time_t tstart , now, giventime=len*wid/5; srand(time(NULL)%UINT_MAX); point start={0,0}; bitbox board[len][wid]; int sy,sx; Start: tstart = time(NULL); carrots_found=0; initscr(); curs_set(0); noecho(); cbreak(); halfdelay(3); 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); } } sy=sx=0; py=px=0; memset(board,0,len*wid); make_maze(board,start); carrotify(board,carrot_count); int input; while(1){ board[py][px] |= VISITED; if( board[py][px] & CARROT ){ ++carrots_found; board[py][px] &= ~CARROT; } now=time(NULL); erase(); mvprintw(sy+0,sx+0," _ "); mvprintw(sy+1,sx+0,"|_) Time left :%ld",giventime-(now-tstart)); mvprintw(sy+2,sx+0,"| \\ABBITHOLE Carrots left :%d",carrot_count-carrots_found); draw(sy+3,sx+0,board); refresh(); if(carrots_found==carrot_count || now-tstart == giventime){ flushinp(); break; } input = getch(); if( input==KEY_PPAGE && LINES< len+3){//the board starts in 3 sy+=10; if(sy>0) sy=0; } if( input==KEY_NPAGE && LINES< len+3){ sy-=10; if(sy< -(len+3) ) sy=-(len+3); } if( input=='<' && COLS< wid*2+1){ sx+=10; if(sx>0) sx=0; } if( input=='>' && COLS< wid*2+1){ sx-=10; if(sx< -(wid*2+1)) sx=-(wid*2+1); } if( (input==KEY_F(2)||input=='!') ) gameplay(); if( input == KEY_F(1) || input=='?' ) help(); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0 && (board[py][px]&UP) ) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0 && (board[py][px]&LEFT) ) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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 . */ #include "common.h" #define LEN 35 #define WID 50 #define STALE_LIMIT 20 #define RLEN LEN //real #define RWID WID #define DEAD 0 #define ALIVE 1 #define RED 2 #define EMPTY_LINES 7 #define SUBTITLEY (EMPTY_LINES+view_len-2) #define SAVE_TO_NUM 10 int level; byte py,px; byte cy,cx;//cross bool coherent;//square's coherence int anum,rnum;//reds and otherwise alive cell counts int stale_cells,stale_for,incoherent_for;//throw new cells if it is stale for a long time long score; char msg[1000]={0}; char msg_show=0; chtype colors[6]={0}; void cp(byte a[RLEN][RWID],byte b[RLEN][RWID]){ byte y,x; for(y=0;y*>*>Top %d<*<*<\n",SAVE_TO_NUM); while( rank>>"); printw("%d) %s : %ld\n",rank+1,pname,pscore); ++rank; } addch('\n'); refresh(); avoid_accidental_pass(); avoid_accidental_pass(); halfdelay(1); } int beginy,view_len; void setup_scroll(){ beginy=0; if(0LEN){ beginy-=beginy+view_len-LEN; } } void rectangle(int sy,int sx){ setup_scroll(); for(int y=0;y<=view_len;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+WID+1,ACS_VLINE); } for(int x=0;x<=WID;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+view_len+1,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+view_len+1,sx,ACS_LLCORNER); mvaddch(sy,sx+WID+1,ACS_URCORNER); mvaddch(sy+view_len+1,sx+WID+1,ACS_LRCORNER); } void count(byte board[LEN][WID]){ byte y,x; anum=rnum=0; for(y=0;yalives) board[y][x]=RED; else if(alives>reds) board[y][x]=ALIVE; } else{ board[y][x]=DEAD; } } else if(alives+reds==3){ if(alives>reds) board[y][x]=ALIVE; else board[y][x]=RED; } } } } void add_line(byte board[LEN][WID],byte line,const char* str){ for(byte x=0;str[x]!='\0';++x){ if(str[x]=='#') board[line][x]=ALIVE; /*else board[line][x]=0;*/ } } void new_level(byte board[LEN][WID],int level){ memset(board,0,RLEN*RWID); switch(level){ case 0: cy=12; cx=12; add_line(board,11," # # # # "); add_line(board,12," # # # # #/# # # "); add_line(board,13," # # # # # # # # "); add_line(board,14," # # # # "); add_line(board,15," "); add_line(board,16," "); add_line(board,17," "); add_line(board,18," ## ## ## ## ## ## ## "); add_line(board,19," ## ## ## ## ## ## ## "); add_line(board,20," "); add_line(board,21," # ## ## ## "); add_line(board,22," # ## ## ## "); add_line(board,23," # "); break; case 1: cy=12; cx=RWID/2; add_line(board,5, " #### #"); add_line(board,6, " #### #"); add_line(board,7, " # # "); add_line(board,8, " # ## # ## # ##"); add_line(board,9, " # # # ## # ## #"); add_line(board,10," # # # # # # # #"); add_line(board,11," ### ## # # # #"); add_line(board,15," #### "); add_line(board,16," # # "); add_line(board,17," # ## # ## # # ## # #"); add_line(board,18," # # # ## # # # # # # # #"); add_line(board,19," # # # # # # # # # # # # #"); add_line(board,20," #### ## # # # # ## # ###"); add_line(board,21," #"); add_line(board,22," # #"); add_line(board,23," ##"); break; case 2: cy=12; cx=RWID/2; add_line(board,5, " # # # #"); add_line(board,6, " # # ## # "); add_line(board,7, " # # # ## ### # # ## ## # # ##"); add_line(board,8, " # # # # # # # # ## # # # ##"); add_line(board,9, " # # # # # # # # # # # # #"); add_line(board,10," # # ## # ## # # # # # # #"); add_line(board,15," #### # "); add_line(board,16," # # # "); add_line(board,17," # # # ## # # # ## # ## # #"); add_line(board,18," ##### ## # # # # # # # # # #"); add_line(board,19," # # # # # # # # # # # #"); add_line(board,20," # # # # ## # # ## #"); break; case 3: cy= 12; cx= 10; add_line(board,3, " ## # #"); add_line(board,4, " ## # # "); add_line(board,5, " # # "); add_line(board,6, " # # # # "); add_line(board,7, " ### ### "); add_line(board,17," ## ## "); add_line(board,18," # # # #"); add_line(board,19," # # # # "); add_line(board,20," # # "); add_line(board,21," ### ### "); add_line(board,22," ### ### "); add_line(board,23," ## ## "); add_line(board,24," ## ## "); add_line(board,25," # ## ## # "); add_line(board,26," ### ###"); add_line(board,27," # #"); add_line(board,30," ##"); add_line(board,31," ##"); break; case 4: cy=RLEN/2; cx=RWID/2; add_line(board,0, " "); add_line(board,1, " # # "); add_line(board,2, " # # "); add_line(board,3, " ### ### "); add_line(board,4, " # # "); add_line(board,5, " # # "); add_line(board,6, " ### ### "); add_line(board,7, " # # "); add_line(board,8, " # # "); add_line(board,9, " ### ### "); add_line(board,10," # # "); add_line(board,11," # # "); add_line(board,12," ### ### "); add_line(board,13," # # "); add_line(board,14," # #"); add_line(board,15," ### ###"); add_line(board,17," "); add_line(board,18," # "); add_line(board,19," # "); add_line(board,20," ### "); add_line(board,21," # "); add_line(board,22," # "); add_line(board,23," ### "); add_line(board,24," # "); add_line(board,25," # "); add_line(board,26," ### "); add_line(board,27," # "); add_line(board,28," # "); add_line(board,29," ### "); add_line(board,30," # "); add_line(board,31," # "); add_line(board,32," ### "); break; case 5: cy=rand()%(RLEN/2); cx=rand()%(RWID/2); add_line(board,0, " "); add_line(board,1, " "); add_line(board,2, " "); add_line(board,3, " "); add_line(board,4, " "); add_line(board,5, " "); add_line(board,6, " "); add_line(board,0, " # # # # "); add_line(board,1, " # | | # # # "); add_line(board,2, " # # | | # # # # # # "); add_line(board,3 ," #### | | #### #### #### "); add_line(board,11," "); add_line(board,12," "); add_line(board,13," "); add_line(board,8 ," # # # # "); add_line(board,9 ," # # # # "); add_line(board,10," # # # # # # # # "); add_line(board,11," #### #### #### #### "); add_line(board,19," "); add_line(board,20," "); add_line(board,16," # # # # "); add_line(board,17," #| | # # # "); add_line(board,18," # #| | # # # # # # "); add_line(board,19," ####| | #### #### #### "); add_line(board,25," "); add_line(board,26," "); add_line(board,27," "); add_line(board,28," "); add_line(board,25," # # "); add_line(board,26," # # "); add_line(board,27," # # # # "); add_line(board,28," #### #### "); break; case 6: add_line(board,5," #"); add_line(board,6," ##"); add_line(board,7," ##"); break; default: srand(level); cy=rand()%(RLEN/2); cx=rand()%(RWID/2); rand_level(board); } } void rm_square(byte board[LEN][WID],byte prey,byte prex){ byte dy,dx,ry,rx; for(dy=0;dy<2;++dy){ for(dx=0;dx<2;++dx){ ry=prey+dy; if(ry==-1) ry=LEN-1; else if(ry==LEN) ry=0; rx=prex+dx; if(rx==-1) rx=WID-1; else if(rx==WID) rx=0; board[ry][rx]=DEAD; } } } void mk_square(byte board[LEN][WID]){ byte dy,dx,ry,rx; for(dy=0;dy<2;++dy){ for(dx=0;dx<2;++dx){ ry=py+dy; if(ry==-1) ry=LEN-1; else if(ry==LEN) ry=0; rx=px+dx; if(rx==-1) rx=WID-1; else if(rx==WID) rx=0; board[ry][rx]=RED; } } } byte nothing_around(byte board[LEN][WID],byte fy, byte fx){ byte count_reds=0; byte sy=fy-1,sx=fx-1;//s:start byte dy,dx;//d:delta for(dy=0;dy<4;dy++){ for(dx=0;dx<4;dx++){ if(get_cell(board,sy+dy,sx+dx)){ count_reds++; } } } return (count_reds==4); } byte no_square(byte board[LEN][WID]){ return !(get_cell(board,py,px) && get_cell(board,py+1,px) && get_cell(board,py,px+1) && get_cell(board,py+1,px+1) && nothing_around(board,py,px) ); } void find_square(byte board[LEN][WID],byte fy, byte fx){//f:found byte dy,dx,ry,rx; for(dy=0;dy<2;++dy){ for(dx=0;dx<2;++dx){ ry=fy+dy; rx=fx+dx; if(get_cell(board,ry,rx)!=RED){ //the square can be divided at both sides of the border, this prevents failing //it goes to look from the upper-left corner of the square as it would for other squares return; } } } if(nothing_around(board,fy,fx)){ py=fy; px=fx; coherent=1; } } //detect if there is a square and enable the player to move void reemerge(byte board[LEN][WID]){ byte y,x,dy,dx,ry,rx; for(y=0;y1){ printf("This game doesn't take arguments"); } signal(SIGINT,sigint_handler); srand(time(NULL)%UINT_MAX); initscr(); 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[RLEN][RWID]; memset(board,0,RLEN*RWID); int input=0; int prey,prex; int cinred; Start: incoherent_for=0; score=0; level=0; stale_cells=0; stale_for=0; msg_show=0; curs_set(0); halfdelay(9); cinred=0; py=LEN*3/4; px=WID/2; curs_set(0); new_level(board,level); mk_square(board); while(1){ switch(rand()%5){//move the X case 0: ++cx; if(cx==WID) cx=0; break; case 1: --cy; if(cy==-1) cy=LEN-1; break; case 2: --cx; if(cx==-1) cx=WID-1; break; case 3: ++cy; if(cy==LEN) cy=0; break; case 4: ;//stay there } if(coherent && (cy==py||cy==(py+LEN+1)%LEN)&& (cx==px||cx==(px+WID+1)%WID)){ ++cinred; } else{ cinred=0; } count(board); if(no_square(board)){ coherent=0; } if(!coherent && rnum>=4){ reemerge(board); } erase(); logo(); mvaddstr(2,16,"Score:"); if(rnum>anum){ attron(colors[3]); } printw("%ld",score); if(rnum>anum){ attroff(colors[3]); } draw(board); if(msg_show){ move(SUBTITLEY,0); addstr(msg); --msg_show; } refresh(); if(!coherent){ ++incoherent_for; } else{ incoherent_for=0; } if(coherent || abs(stale_cells-(rnum+anum))>stale_cells/10){//if there is too much variation it is not stale stale_cells=rnum+anum; stale_for=0; } else{ stale_for+=1; } if(stale_for>STALE_LIMIT || incoherent_for>STALE_LIMIT*5){ for(int i=0;i<10;++i){ board[rand()%LEN][rand()%WID]=RED; } for(int i=0;i<10;++i){ board[rand()%LEN][rand()%WID]=ALIVE; } stale_for=0; incoherent_for=0; } if((rnum>anum && anum==0)||cinred==2){ move(SUBTITLEY,0); if(rnum>anum && anum==0){ if(rnum>100){ printw("HEAVY WIN +1000 "); score+=1000; } else{ printw("Total win! +100 "); score+=100; } } if(cinred==2){ printw("Win by capture! +20 "); } printw("Well done! Press a key to continue: "); curs_set(1); avoid_accidental_pass(); curs_set(0); ++level; new_level(board,level); py=LEN*3/4; px=WID/2; msg_show=0; mk_square(board); continue; } else if(!rnum){ /*move(SUBTITLEY,0); printw("You have lost The Game "); if(rand()%5==0) printw("(and RedSquare) "); printw(". ");*/ break; } halfdelay(9); input = getch(); live(board); count(board); if(no_square(board)){//the square has participated in life reactions if so coherent=0; } if(!coherent){ //camera_on_reds(board); reemerge(board);//there might be another square somewhere if(coherent){ sprintf(msg,"Reemergence! +30 "); msg_show=20; score+=30; } } if( input==KEY_F(1) || input=='?' ) help(); if( (input==KEY_F(2)||input=='!') ) gameplay(); prey=py; prex=px; if(input=='k' || (input==KEY_UP||input=='w')){ --py; if(py==-1) py=LEN-1; } else if(input=='j' || (input==KEY_DOWN||input=='s')){ ++py; if(py==LEN) py=0; } else if(input=='h' || (input==KEY_LEFT||input=='a')){ --px; if(px==-1) px=WID-1; } else if(input=='l' || (input==KEY_RIGHT||input=='d')){ ++px; if(px==WID) px=0; } else goto DidntMove; if(coherent){ rm_square(board,prey,prex); mk_square(board); } DidntMove: if( (input=='q'||input==27)){ sigint_handler(0); } if( input=='p'){ nocbreak(); cbreak(); erase(); logo(); attron(A_BOLD); addstr("\n PAUSED"); attroff(A_BOLD); refresh(); getch(); halfdelay(9); } if( input=='?' || input==KEY_F(1)){ help(); } if( input=='!' || (input==KEY_F(2)||input=='!')){ gameplay(); } } nocbreak(); cbreak(); draw(board); refresh(); move(SUBTITLEY,0); printw("You have lost The Game"); if(rand()%5==0) printw(" (and RedSquare)"); printw(". "); printw("Press a key to continue:"); avoid_accidental_pass(); show_scores(save_score()); printw("Game over! Wanna play again?(y/n)"); curs_set(1); input=avoid_accidental_pass(); if(input != 'N' && input != 'n' && input != 'q') goto Start; endwin(); return EXIT_SUCCESS; } nbsdgames-6.0.1/revenge.c000066400000000000000000000233021517406336500152720ustar00rootroot00000000000000/* .-. |_.' | \EVENGE Authored by abakh 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 . */ #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>>"); 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;y3 && 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=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;yy){ 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=0 && x>=0 && y0){ tile_push(board,-1,0); } if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0){ tile_push(board,0,-1); } if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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; } nbsdgames-6.0.1/reversi.c000066400000000000000000000252461517406336500153270ustar00rootroot00000000000000/* _ |_) | \EVERSI Authored by abakh 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 . */ #include "common.h" byte py,px;//cursor const char piece[2] = {'O','X'}; char game[8][8];//main board char side[2]={'h','h'}; byte score[2];//set by header() void rectangle(byte sy,byte sx){ for(byte y=0;y<=8+1;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+8*2,ACS_VLINE); } for(byte x=0;x<=8*2;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+8+1,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+8+1,sx,ACS_LLCORNER); mvaddch(sy,sx+8*2,ACS_URCORNER); mvaddch(sy+8+1,sx+8*2,ACS_LRCORNER); } void header(void){//abuse, used to count the pieces on each side too score[0]=score[1]=0; for(byte y=0;y<8;++y){ for(byte x=0;x<8;++x){ if(game[y][x]){ if(game[y][x]==piece[0]) score[0]++; else score[1]++; } } } mvaddch(0,1, '_'); mvprintw(1,0,"|_) %2d:%2d",score[1],score[0]); mvprintw(2,0,"| \\EVERSI "); } void draw(byte sy,byte sx){//the game's board rectangle(sy,sx); chtype attr ; for(byte y=0;y<8;++y){ for(byte x=0;x<8;++x){ attr=A_NORMAL; if(y==py && x==px) attr |= A_STANDOUT; if(game[y][x]) mvaddch(sy+1+y,sx+x*2+1,attr|game[y][x]); else mvaddch(sy+1+y,sx+x*2+1,attr|'.'); } } } bool can_reverse(byte ty , byte tx,char board[8][8],char piece){//can place a piece there? byte y,x,count; if(board[ty][tx]) return false; for(byte dy=-1;dy<2;++dy){ //changes the direction for(byte dx=-1;dx<2;++dx){ if(dx==0&&dy==0)//it would be itself dx=1; count=0; y=ty+dy; x=tx+dx; while(1){ if(y<0 || y>=8 ||x<0 || x>=8){//reaches edges of the board count=0; break; } if(!board[y][x]){//gap count=0; break; } if(board[y][x]!=piece){ ++count; y+=dy; x+=dx; } else break;//same color } if(count) return true; } } return false; } void reverse(byte ty,byte tx,char board[8][8],char piece){//place a piece there board[ty][tx]=piece; byte y,x; for(byte dy=-1;dy<2;++dy){//changes the direction for(byte dx=-1;dx<2;++dx){ if(dy==0 && dx==0) dx=1; y=ty+dy; x=tx+dx; while(1){ if(y<0 || y>=8 || x<0 || x>=8) break; if(!board[y][x]) break; if(board[y][x]!=piece){ y+=dy; x+=dx; } else{ //of same kind while(y!=ty || x!=tx){ //reverse the disks board[y][x]=piece; y-=dy; x-=dx; } break; } } } } } bool can_move(char board[8][8],char piece){//can move at all? for(byte y=0;y<8;++y) for(byte x=0;x<8;++x) if(can_reverse(y,x,board,piece)) return true; return false; } double advantage(char board[8][8],char piece){ double own=0; double opp=0; for(byte y=0;y<8;++y){ for(byte x=0;x<8;++x){ if(board[y][x]){ if(board[y][x]==piece){ ++own; if( ((y==7 || y==0)&&(x!=7 && x!=0)) || ((x==7 || x==0)&&(y!=7 && y!=0)) ){//edges own+=100; } if( (y==7 || y==0)&&(x==7 || x==0) ){//corners own+=10000; } } else{ ++opp; if( ((y==7 || y==0)&&(x!=7 && x!=0)) || ((x==7 || x==0)&&(y!=7 && y!=0)) ) opp+=100; if( (y==7 || y==0)&&(x==7 || x==0) ) opp+=10000; } } } } return own/opp; } void cp(char A[8][8],char B[8][8]){//copy the board A to B for(byte y=0;y<8;++y) for(byte x=0;x<8;++x) B[y][x]=A[y][x]; } double win_or_lose(char board[8][8],char piece,char opponent){ byte own_score=0; for(byte y=0;y<8;++y){ for(byte x=0;x<8;++x){ if(board[y][x]==piece){ ++own_score; } if(board[y][x]==opponent){ --own_score; } } } if(own_score>0){ return 1000000; } else{ return 1/1000000; } } double decide(char board[8][8],char piece,char opponent,byte depth){//AI algorithm if(!can_move(board,piece)) return 0; char plan[8][8]; double adv,bestadv; adv=bestadv=0; byte besty,bestx; for(byte y=0;y<8;++y){ for(byte x=0;x<8;++x){ if(can_reverse(y,x,board,piece) ){ cp(board,plan);//backtrack reverse(y,x,plan,piece); if(depth<0){ adv=rand(); } else if(depth){ adv= decide(plan,opponent,piece,depth-1);//least benefit for the opponent if(adv){ //the opponent can make a move adv = 1/adv; } else{ if(!can_move(board,piece)){//if neither AI nor the opponent can make a move, this is a conclusion to the game adv=win_or_lose(board,piece,opponent); } else{ adv=advantage(plan,piece); } } } else{ adv=advantage(plan,piece); } if(adv>bestadv){ bestadv=adv; besty=y; bestx=x; } } } } reverse(besty,bestx,board,piece);//do the move return bestadv; } //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 <8 && minput.x-1<16){ py=minput.y-4; px=(minput.x-1)/2; } else return; if(minput.bstate & BUTTON1_CLICKED) ungetch('\n'); #endif } void gameplay(void){ erase(); header(); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("Players take turns placing disks on the board:\n\n"); printw("1) Any pieces of the opponent's color that is bounded\n"); printw(" in a straight line between the piece just placed and\n"); printw(" another piece of the current player's color would turn\n"); printw(" to the current player's color.\n\n"); printw("2) You can only put pieces if at least one of your \n"); printw(" opponent's pieces turns into your color.\n\n"); printw("3) The game ends when neither side can do a move and\n"); printw(" the player with more pieces wins.\n"); getch(); } void help(void){ erase(); header(); 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 : Put the piece"); 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"); getch(); gameplay(); } int main(int argc , char** argv){ int depth=-1; int auto_stupid_counter=0; int opt; bool sides_chosen=0,no_replay=0,fixed_starting_depth=0; while( (opt= getopt(argc,argv,"hnp:1:2:"))!= -1 ){ switch(opt){ case '1': case '2': if(!strcmp("c",optarg) || !strcmp("h",optarg)){ side[opt-'1']=optarg[0]; sides_chosen=1; } else{ puts("That should be either h or c\n"); return EXIT_FAILURE; } break; case 'p': if(sscanf(optarg,"%d",&depth) && depth<128 && depth>0) fixed_starting_depth=1; else{ puts("That should be a number from 1 to 127."); return EXIT_FAILURE; } break; case 'n': no_replay=1; break; case 'h': default: printf("Usage: %s [options]\n -p ai power\n -1 type of player 1\n -2 type of player 2\n -h help\n -n dont ask for replay\n",argv[0]); return EXIT_SUCCESS; break; } } signal(SIGINT,sigint_handler); initscr(); #ifndef NO_MOUSE mousemask(ALL_MOUSE_EVENTS,NULL); #endif noecho(); cbreak(); keypad(stdscr,1); int input; if(!sides_chosen){ printw("Black plays first:\n"); printw("Choose type of the white player (H/c)\n"); refresh(); input=getch(); if(input == 'h'){ side[0]='h'; printw("Human.\n"); } else{ side[0]='c'; printw("Computer.\n"); } refresh(); printw("Choose type of the black player(h/C)\n"); refresh(); input=getch(); if(input == 'c'){ side[1]='c'; printw("Computer.\n"); } else{ side[1]='h'; printw("Human.\n"); } } Start: curs_set(0); py=px=0; memset(game,0,64); bool turn=0; bool resign=0; byte cantmove=0; game[3][3]=piece[0]; game[4][4]=piece[0]; game[3][4]=piece[1]; game[4][3]=piece[1]; Turn: if(side[0]=='c' &&side[1]=='c'){//make AI vs AI games more variable and interesting fixed_starting_depth=1; depth=4+(rand()%2); py=px=9;//visual nuisance removed } srand(time(NULL)%UINT_MAX); erase(); flushinp(); draw(3,0); header(); refresh(); if(cantmove >=2)//both sides cant move, the game ends goto End; turn = !turn; if(side[turn]=='c'){ if(can_move(game,piece[turn])){ mvprintw(13,0,"Thinking..."); refresh(); decide(game,piece[turn],piece[!turn],depth); cantmove=0; } else ++cantmove; goto Turn; } if(!can_move(game,piece[turn])){ ++cantmove; goto Turn; } else{ cantmove=0; while(1){ //human control erase(); draw(3,0); header(); if(side[0]=='h' && side[1] =='h'){ mvprintw(2,10,"%c's turn",piece[turn]); } 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) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py<7) ++py; if( (input=='h' || (input==KEY_LEFT||input=='a')) && px>0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px<7) ++px; if( (input=='q'||input==27)){ resign=1; goto End; } if(input=='\n' || input==KEY_ENTER){ if(can_reverse(py,px,game,piece[turn])){ reverse(py,px,game,piece[turn]); goto Turn; } } } } End: if(resign) mvprintw(13,0,"You resigned."); else if(score[0]==score[1]) mvprintw(13,0,"Draw!!"); else if(score[0] > score[1]) mvprintw(13,0,"'%c' won.",piece[0]); else mvprintw(13,0,"'%c' won.",piece[1]); if(!fixed_starting_depth && !resign && score[0]!=score[1] && (side[0]=='c'||side[1]=='c') && (side[0]=='h'||side[1]=='h')){ if( (side[0]=='c' && score[0]>score[1]) || (side[1]=='c' && score[1]>score[0])){//if computer won if(depth>-3){ --depth; } if(auto_stupid_counter==1){ depth=0; } } else{ if(depth<7){ ++depth; printw(" I'd play better next time. "); } else{ printw(" Are you human? "); } if(!fixed_starting_depth && auto_stupid_counter==0){ depth=4; auto_stupid_counter+=1; } } } if(!no_replay){ printw(" Wanna play again?(y/n)"); curs_set(1); input=getch(); if(resign){ if (input=='Y' || input=='y') goto Start; } else if(input != 'N' && input != 'n' && input != 'q') goto Start; } else{ printw(" Press any key on your keyboard to continue:"); getch(); } endwin(); return EXIT_SUCCESS; } nbsdgames-6.0.1/scissor.c000066400000000000000000000257331517406336500153360ustar00rootroot00000000000000/* _ (_ _)CISSOR Authored by abakh 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 . */ #include "common.h" #define SAVE_TO_NUM 11 #define LEN 24 #define WID 80 #define HLEN (LEN/2) #define HWID (WID/2) #define ITEMS_COUNT 26 #define randint(a,b) ((a)+(rand()%((b+1)-(a)))) #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif // 12 lines of water // 80 columns enum {ROCK=0,PAPER,SCISSOR,MAGIC}; chtype colors[3]={0}; long score=0; FILE* scorefile; int input; typedef struct item{ byte type; float y,x; float angle; float vy,vx; bool player; struct item *last_collision;//so they don't stick together }item; item items[ITEMS_COUNT]; char msg[150]={0}; byte msg_show=0; void filled_rect(byte sy,byte sx,byte ey,byte ex){ byte y,x; for(y=sy;yangle+=((rand()%200)-100)*0.01; a->vy=sin(a->angle)/2; a->vx=cos(a->angle); } void fill_items(){ item *a=NULL; for(byte i=0;iy=(float)(LEN*i/ITEMS_COUNT); a->x=(float)(WID*i/ITEMS_COUNT);*/ a->y=rand()%LEN; a->x=rand()%WID; a->angle=(rand()%4)*(6.28/4); a->vy=sin(a->angle); a->vx=cos(a->angle); a->type=i%3; if(i<1){ a->type=MAGIC; } a->player=0; a->last_collision=NULL; } } void move_item(item *a){ bool bounce; bounce=0; //bounce when hitting the borders, and don't get stuck there if( a->x<0 || (int)a->x>=WID-1 || ((int)a->x==13 && a->y<=7 ) ){ a->angle =M_PI- a->angle; a->vy=sin(a->angle); a->vx=cos(a->angle); bounce=1; } if( a->y <0 || (int)a->y >= LEN-1 || (a->x<=13 && (int)a->y==7)){ a->angle =0- a->angle; a->vy=sin(a->angle); a->vx=cos(a->angle); bounce=1; } if(a->x<0){//these are for getting unstuck a->x=1; } if(a->y<0){ a->y=1; } if(a->x>=WID){ a->x=WID-1; } if(a->y>=LEN){ a->y=LEN-1; } if((int)a->x==13 && a->y<7){ a->x=14; } if(a->x<=13 && (int)a->y==7){ a->y=8; } while(a->angle<0){//preventing overflow a->angle +=M_PI*2; } //move a->x+=a->vx; a->y+=a->vy; if(bounce && a->x>=WID-1)//getting unstuck a->x=WID-1; if(bounce && a->y>=LEN-1) a->y=LEN-1; if(bounce){//bounce in a slightly different direction than it should be a->angle +=randint(-1,1)*0.1; } if(a->x<13 && a->y<7){// don't go into the logo area if(13 - a->x < 7 - a->y){ a->y=8; } else{ a->x=14; } } } void swap_items(item *a, item *b){ item s= *a; *a=*b; *b=s; } void sort_items(){ byte pos=0;//sort for y while(pos items[pos-1].y || ((int) items[pos].y == (int) items[pos-1].y) && (items[pos].x > items[pos-1].x)){ pos+=1; } else{ swap_items(&items[pos],&items[pos-1]); } } } void guide_item(item *a, int input){ if( (input=='k' || (input==KEY_UP||input=='w'))){ a->vy=-1; a->vx=0; } if( (input=='j' || (input==KEY_DOWN||input=='s'))){ a->vy=1; a->vx=0; } if( (input=='h' || (input==KEY_LEFT||input=='a'))){ a->vy=0; a->vx=-1; } if( (input=='l' || (input==KEY_RIGHT||input=='d'))){ a->vy=0; a->vx=1; } if( input=='y'){//intended behavior, moves faster diagonally. legit "cheating" a->vy=-1; a->vx=-1; } if( input=='u'){ a->vy=-1; a->vx=1; } if(input=='b'){ a->vy=1; a->vx=-1; } if(input=='n'){ a->vy=1; a->vx=1; } } void collide(item *a, item *b){ if(a==b){ printf("RIIIIDII"); } if(a->last_collision==b){ return; } if(a->player || b->player){ if(a->type!=b->type){ score+=47; } } float svy=a->vy; float svx=a->vx; float sangle=a->angle; a->vy=b->vy; a->vx=b->vx; a->angle=b->angle; b->vy=svy; b->vx=svx; b->angle=sangle; add_random_angle(a); add_random_angle(b); a->last_collision=b; b->last_collision=a; if(a->type==MAGIC){ if(b->type==SCISSOR){ b->type=PAPER; b->player=0; } else if(b->type==ROCK){ b->type=SCISSOR; } else if(b->type==PAPER){ b->type=ROCK; } } else if(a->type==ROCK){ if(b->type==SCISSOR){ b->type=ROCK; b->player=0; } else if(b->type==PAPER){ a->type=PAPER; } } else if(a->type==PAPER){ if(b->type==ROCK){ b->type=PAPER; } else if(b->type==SCISSOR){ a->type=SCISSOR; } } else if(a->type==SCISSOR){ if(b->type==PAPER){ b->type=SCISSOR; } else if(b->type==ROCK){ a->type=ROCK; a->player=0; } } } void collisions(){ item *a,*b; for(byte i=0;ilast_collision; /*if(b && fabs(a->y-b->y)<3 && fabs(a->x-b->x)<3){ a->last_collision=NULL; }*/ for(byte j=i+1;jy-b->y)<1.5 && fabs(a->x-b->x)<1.5){ collide(a,b); } } } } void mechanics(){ collisions(); static byte slow_motion=0; slow_motion=(slow_motion+1)%1; for(byte i=0;itype==SCISSOR){ make_player=a; } if(a->player){ return; } } if(make_player){ make_player->player=1; } } void logo(){ mvaddstr(0,0," "); mvaddstr(1,0," _ "); mvaddstr(2,0,"(_' "); mvaddstr(3,0,"._)CISSOR"); } void draw(){ logo(); mvprintw(5,0,"Score: %ld",score); for(byte i=0;i0){ byte a = (LEN-9)/2; star_line(1); star_line(LEN-2); mvaddstr(1,WID/2-8,"CONGRATULATIONS!!"); mvprintw(a+1,HWID-10," _____You beat the"); mvprintw(a+2,HWID-10," .' | previous"); mvprintw(a+3,HWID-10," .' | record"); mvprintw(a+4,HWID-10," | .| | of"); mvprintw(a+5,HWID-10," |.' | |%11ld",formerscore); mvprintw(a+6,HWID-10," | | held by"); mvprintw(a+7,HWID-10," ___| |___%7s!",formername); mvprintw(a+8,HWID-10," | |"); mvprintw(a+9,HWID-10," |____________|"); mvprintw(LEN-3,HWID-11,"Press a key to continue"); refresh(); do{ input=getch(); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); filled_rect(0,0,LEN,WID); magenta_border(); } } //scorefile is still open with w+ char pname[60] = {0}; long pscore=0; byte rank=0; rewind(score_file); mvaddstr(1,WID/2-4,"HIGH SCORES"); while( rank>>"); printw("%s",pname); mvprintw(2+2*rank,WID-1-digit_count(pscore),"%ld",pscore); ++rank; } refresh(); } void help(void){ nocbreak(); cbreak(); filled_rect(0,0,LEN,WID); magenta_border(); mvaddstr(1,WID/2-4,"GAMEPLAY"); mvprintw(3,1,"This is rock-paper-scissor game evolved to a"); mvprintw(4,1,"super-hyper-great live action strategy game."); mvprintw(5,1,"You have extra lives as long as there are scissors"); mvprintw(6,1,"on screen. Hit and dodge rocks and papers and manage"); mvprintw(7,1,"their populations. The more you hit, the more you win."); mvprintw(8,1,"Patience and vigilance could lead to very high scores."); refresh(); getch(); halfdelay(1); } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } int avoid_accidental_pass(){ int input; Again: input=getch(); if( input==ERR){ goto Again; } if( (input=='k' || (input==KEY_UP||input=='w'))){ goto Again; } else if( (input=='j' || (input==KEY_DOWN||input=='s')) ){ goto Again; } else if( (input=='h' || (input==KEY_LEFT||input=='a'))){ goto Again; } else if( (input=='l' || (input==KEY_RIGHT||input=='d'))){ goto Again; } return input; } int main(int argc,char** argv){ if(argc>1){ printf("This game doesn't take arguments"); } signal(SIGINT,sigint_handler); initscr(); noecho(); cbreak(); keypad(stdscr,1); srand(time(NULL)%UINT_MAX); if(has_colors()){ start_color(); init_pair(1,COLOR_RED,COLOR_BLACK); init_pair(2,COLOR_YELLOW,COLOR_BLACK); init_pair(3,COLOR_MAGENTA,COLOR_BLACK); for(byte b=0;b<3;++b) colors[b]=COLOR_PAIR(b+1); } Start: erase(); halfdelay(1); curs_set(0); score=0; msg_show=0; fill_items(); byte found_player=0; while(1){ erase(); draw(); refresh(); input=getch(); if(input=='?' || input==KEY_F(1)) help(); if(input=='p'){ nocbreak(); cbreak(); erase(); logo(); attron(A_BOLD); addstr("\n PAUSED"); attroff(A_BOLD); refresh(); getch(); halfdelay(1); } if(input=='q'){ break; } find_scissor(); found_player=0; for(int i=0;itype==SCISSOR && !(rand()%2)){ guide_item(items+i,input); } if((items+i)->player){ guide_item((items+i),input); found_player=1; break; } } if(!found_player){ break; } if(input==27){ break; } if(input!=ERR){ usleep(100000); flushinp(); } mechanics(); } flushinp(); nocbreak(); cbreak(); draw(); refresh(); move(LEN-1,0); printw("You have lost The Game. Press a key to contintue."); refresh(); avoid_accidental_pass(); curs_set(1); show_scores(save_score()); attron(colors[2]|A_STANDOUT); mvprintw(LEN-1,HWID-11,"Wanna play again? (y/n)"); attroff(colors[2]|A_STANDOUT); input=avoid_accidental_pass(); if(input!='q' && input!='n' && input!='N') goto Start; endwin(); return 0; } nbsdgames-6.0.1/sjump.c000077500000000000000000000203621517406336500150030ustar00rootroot00000000000000/* _ ___ (_' | ._)QUARE (_:UMP Authored by abakh 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 . */ #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "common.h" #define SAVE_TO_NUM 10 #define LEN 24 #define HLEN LEN/2 #define WID 80 #define HWID WID/2 #define SIZE 12 #define SHOTS_WHEN_STARTING 10 #define DELAY 50000 #define byte int #define randint(a,b) ((a)+(rand()%((b+1)-(a)))) #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif // 12 lines of water // 80 columns enum {LOSE,WIN}; chtype colors[5]={0}; long score=0,jumps=0; FILE* scorefile; chtype background[LEN][WID]; int input; char msg[150]={0}; byte msg_show=0; bool timed[3]; byte squarex[3]; byte squarey[3]; byte loops_left=0; int oy=0; int ox=0; float rotation_angle=0; int combo=1; void filled_rect(byte sy,byte sx,byte ey,byte ex){ byte y,x; for(y=sy;y*>*>Top %d<*<*<\n",SAVE_TO_NUM); while( rank>>"); printw("%d) %s : %ld\n",rank+1,pname,pscore); ++rank; } addch('\n'); refresh(); } void draw_square(byte sy,byte sx){ for(byte y=0;y--- //| | //^ V //| | //----<--- } void draw_angle(byte sy,byte sx){ int y=sy+oy; int x=sx+ox; attron(colors[0]); mvaddch(y,x,'O'); attroff(colors[0]); } void draw(int sy,int sx){ for(byte i=0;i<3;++i){ draw_square(sy+squarey[i],sx+squarex[i]); } logo(); } byte shooting_scene(){ float dy=(oy-(SIZE/2))/(float)SIZE; float dx=(ox-(SIZE))/(float)(SIZE*2); dy/=2;//it was too hard :( float y=squarey[0]+oy; float x=squarex[0]+ox; float offsetx=0; float offsety=0; float doffsety=0; float doffsetx=-dx*2; byte reached_o=0; while(1){ erase(); draw(offsety,offsetx); if(round(x)<=-round(offsetx)+1){//slow the animation reached_o=1; } attron(colors[0]); mvaddch(round(y)+round(offsety),round(x)+round(offsetx),'O'); attroff(colors[0]); for(byte i=0;i<1;i++){ y+=dy; x+=dx; offsety+=doffsety; if(reached_o){ offsetx=-x; } else{ offsetx+=doffsetx; } if( y>=LEN-1 || y<=1|| x> squarex[1]+SIZE*3 || x<-SIZE){ combo=1; return LOSE; } if(y>=squarey[1] && x>=squarex[1] && y<=squarey[1]+SIZE && round(x)<=squarex[1]+SIZE*2){ if(round(y)==squarey[1] || round(y)==squarey[1]+SIZE){ score+=combo*101; } else{ score+=combo; } combo++; jumps++; oy=round(y)-squarey[1]; ox=round(x)-squarex[1]; for(byte i=0;i<3;++i){ squarey[i]+=offsety; squarex[i]+=offsetx; } squarey[0]=squarey[1]; squarex[0]=squarex[1]; squarey[1]=squarey[2]; squarex[1]=squarex[2]; squarex[2]=squarex[1]+WID-SIZE; squarey[2]=5+ (rand()%(LEN-(5+SIZE))); //since square 0 always ends up at the center after the animation, //square 2 should be choosen in a way that it would still remain //in the screen after the animation in which it becomes square 1. return WIN; } } refresh(); if(reached_o){ usleep(DELAY/6); } else{ usleep(DELAY/3); } } } void help(void){ nocbreak(); cbreak(); erase(); filled_rect(0,0,LEN,WID); red_border(); mvprintw(1,HWID-4,"GAME PLAY"); mvprintw(3,1,"Jump from square to square using enter key."); refresh(); flushinp(); getch(); usleep(5000000); halfdelay(1); } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } int main(void){ signal(SIGINT,sigint_handler); initscr(); noecho(); cbreak(); keypad(stdscr,1); srand(time(NULL)%UINT_MAX); if(has_colors()){ start_color(); use_default_colors(); init_pair(1,COLOR_RED,-1); init_pair(2,COLOR_YELLOW,-1); init_pair(3,COLOR_GREEN,-1); init_pair(4,COLOR_MAGENTA,-1); init_pair(5,COLOR_BLUE,-1); for(byte b=0;b<5;++b) colors[b]=COLOR_PAIR(b+1); } Start: oy=ox=0; squarey[0]=5; squarex[0]=0; squarey[1]=5; squarex[1]=squarex[0]+WID-SIZE; squarey[2]=5; squarex[2]=squarex[1]+WID-SIZE; erase(); nodelay(stdscr,1); curs_set(0); score=0; msg_show=0; while(1){ erase(); draw(0,0); draw_angle(squarey[0],squarex[0]); refresh(); input=getch(); move_o(); if(input=='?' || input==KEY_F(1)) help(); if(input=='q'){ break; } if(input=='\n'||input==KEY_ENTER){ if(shooting_scene()==LOSE){ break; } } usleep(DELAY); if(input!=ERR){ flushinp(); } } nodelay(stdscr,0); flushinp(); nocbreak(); cbreak(); curs_set(1); mvprintw(LEN,0,"Press a key to see the high scores:"); refresh(); getch(); show_scores(save_score()); printw("\n\nWanna play again? (y/n)"); do{ input=getch(); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); if(input!='q' && input!='n' && input!='N') goto Start; endwin(); return 0; } nbsdgames-6.0.1/snakeduel.c000066400000000000000000000366231517406336500156240ustar00rootroot00000000000000/* _ _ (_ | : _)NAKE |.'UEL Authored by abakh 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 . */ #include "common.h" #define SAVE_TO_NUM 10 #define MINLEN 10 #define MAXLEN 127 #define MINWID 40 #define MAXWID 127 #define LOSE -(MAXWID*MAXLEN) #define WIN_LIMIT 5 //#define REPORT 0 #ifdef REPORT #define reportif(x) if(x){fprintf(lol,#x" is true\n");fflush(lol);} #define reportd(x) if(REPORT){fprintf(lol, #x": %ld\n",(long)x);fflush(lol);} #define reports(x) if(REPORT){fprintf(lol, "line %d: %s\n",__LINE__,x);fflush(lol);} #else #define reportif(x) #define reportd(x) #define reports(x) #endif enum {UP=0,RIGHT,DOWN,LEFT}; enum {BLOCK=0,SURVIVAL,MIRROR,IMITATE}; /* The Plan9 compiler can not handle VLAs */ #ifdef NO_VLA #define len 36 #define wid 80 #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif #else int len=MINLEN,wid=MINWID; #endif//NO_VLA typedef struct snake{ int y; int x; byte direction; byte fp; byte strategy; byte score; chtype color; } snake; snake p;//player snake c;//computer byte pscore; byte cscore; chtype colors[6]={0}; byte constant_change={0}; bool must_win=0; FILE* lol; void logo(void){ mvaddstr(0,0," _ _"); mvaddstr(1,0,"(_ | : "); mvaddstr(2,0," _)NAKE |.'UEL"); } void rectangle(void){ for(int y=0;y<=len;++y){ mvaddch(3+y,0,ACS_VLINE); mvaddch(4+y,1+wid,ACS_VLINE); } for(int x=0;x<=wid;++x){ mvaddch(3,x,ACS_HLINE); mvaddch(4+len,x,ACS_HLINE); } mvaddch(3,0,ACS_ULCORNER); mvaddch(4+len,0,ACS_LLCORNER); mvaddch(3,1+wid,ACS_URCORNER); mvaddch(4+len,1+wid,ACS_LRCORNER); } void swap(byte* a,byte* b){ byte s= *a; *a=*b; *b=s; } void swap_long(long* a,long* b){ long s= *a; *a=*b; *b=s; } byte opposite(byte direction){ switch(direction){ case UP: return DOWN; case DOWN: return UP; case LEFT: return RIGHT; case RIGHT: return LEFT; default: abort(); } } snake fake_move(snake s){ switch(s.direction){ case UP: s.y=s.y-1; break; case DOWN: s.y=s.y+1; break; case LEFT: s.x=s.x-1; break; case RIGHT: s.x=s.x+1; break; } return s; } bool blocked(byte board[len][wid],snake s){ s=fake_move(s); return ( s.y<0 || s.y >=len || s.x<0 || s.x>=wid || board[s.y][s.x] ); } bool better_change_way(byte board[len][wid],snake s){ if(blocked(board,s)){ return 1; } s=fake_move(s); if(blocked(board,s)){ return 1; } return 0; } void putfp(byte board[len][wid],snake s){ if(s.x>=0 && s.y>=0 && s.xy_dist){ swap(&directions[0],&directions[1]); } if(x_dist==y_dist && x_dist<3 && directions[0]==me.direction){ swap(&directions[0],&directions[1]); } } void avoid(snake me,int y, int x, byte directions[4]){ purs(me,y,x,directions); for(byte i=0;i<4;++i){ directions[i]=opposite(directions[i]); } } void shuffle(byte directions[4]){ byte a=rand()%4; byte b=rand()%4; swap(&directions[a],&directions[b]); } void enemy_avoid(snake me,snake enemy,byte directions[4]){ avoid(me,enemy.y,enemy.x,directions); } void enemy_pursue(snake me,snake enemy,byte directions[4]){ purs(me,enemy.y,enemy.x,directions); } void enemy_block(byte board[len][wid],snake me, snake enemy,byte directions[4]){ snake ahead=enemy; switch(enemy.direction){ case UP: if(me.y>enemy.y)//me is to the down of the enemy, so cannot plan to block it's way in advance goto JustPursue; break; case DOWN: if(me.yenemy.x) goto JustPursue; break; default: abort(); } for(byte i=0;i<10;++i){ if(blocked(board,ahead)||ahead.y==me.y||ahead.x==me.x){ purs(me,ahead.y,ahead.x,directions); return; } ahead=fake_move(ahead); } JustPursue: purs(me,ahead.y,ahead.x,directions); } void enemy_mirror(snake me,snake enemy,byte directions[4]){ int y,x; y=len-1-enemy.y; x=wid-1-enemy.x; purs(me,y,x,directions); } void enemy_block_mirror(snake me,snake enemy,byte directions[4]){ int y_dist=abs(me.y-enemy.y); int x_dist=abs(me.x-enemy.x); if(y_dist>x_dist){ purs(me,len-1-enemy.y,enemy.x,directions); } else{ purs(me,enemy.y,wid-1-enemy.x,directions); } } void move_to_top(byte array[4],byte index){ byte newtop=array[index]; for(byte i=index;i>0;--i){ array[i]=array[i-1]; } array[0]=newtop; } void leave_escapes(byte board[len][wid],snake me,byte directions[4]){ byte s=3; for(byte i=0;i<4;i++){ me.direction=directions[s]; if(!better_change_way(board,me)){ move_to_top(directions,s); } else{ --s; } } } long go_deep(byte board[len][wid],snake me,bool randomize){ reports("****go deep***"); if(randomize){ reports("randomize"); } long m=0; byte bumps=0; static byte inc=1; if(randomize){ inc=-inc; } while(!blocked(board,me)){ me=fake_move(me); ++m; if(m>len+wid){ return m; } if(blocked(board,me)||(randomize&&!(rand()%10))){ snake f=me; byte i; if(randomize){ f.direction=rand()%4; } for(i=0;i<4;++i){ if(f.direction!=opposite(me.direction) || blocked(board,f)){ me=f; break; } else{ f.direction+=4+inc; f.direction%=4; } } reports("***BUMP!***"); reportd(bumps); reportd(m); if(bumps==4){ return m; } else{ ++bumps; } } } return m; } long mnvrblty(byte board[len][wid],snake me,byte depth){ long m=0; long max=0,n,max_n; while(m<=4 && !blocked(board,me)){ me=fake_move(me); ++m; if(depth){ snake f=me; max_n=0; for(byte i=0;i<4;++i){ n=0; if(i==opposite(me.direction)){ continue; } f.direction=i; for(byte j=0;j<10;++j){ n=go_deep(board,f,j%2); if(max_nlen+wid){ return max_n; } } reports("Then the maximum became:"); reportd(max_n); } if(maxdirection); int y_dist=(abs(me->y-enemy->y)); int x_dist=(abs(me->x-enemy->x)); int dist=(y_dist+x_dist); long g=go_deep(board,*me,1); reportd(g); byte directions[4]={0,1,2,3}; long advantages[4]={0}; if(me->strategy==IMITATE ){ if(abs(me->y-(len-1-enemy->y))+abs(me->x-(wid-1-enemy->x))>3){ me->strategy=SURVIVAL; } else{ me->strategy=IMITATE; } } else if(g<20){ me->strategy=SURVIVAL; } else if( dist<20){ me->strategy=BLOCK; } else{ me->strategy=MIRROR; } bool change_path=0; if(better_change_way(board,*me)){ change_path=1; } else if(me->strategy==IMITATE){ change_path=1; } else if(me->strategy==SURVIVAL){ reports("SURVIVAL!@#"); change_path=1; } else if(me->strategy==MIRROR){ change_path=better_change_way(board,*me) || ((me->x%2)&&(me->y%3==2)) || ((me->x%2==0)&&(me->y%3==0)); if(better_change_way(board,*me) && !change_path){ reports("fuck you"); } } else if(me->strategy==BLOCK){ reports("BLOCK!@#"); change_path= !(rand()%(dist+1)) || !(rand()%(x_dist+1)) || !(rand()%(y_dist+1));//this one wants to leave escapes if(!change_path && dist<40 && !(rand()%(dist/2+1))){//this one wants to kill change_path=1; } } if(change_path){ if(me->strategy==IMITATE){ enemy_mirror(*me,*enemy,directions); } if(me->strategy==MIRROR){ enemy_mirror(*me,*enemy,directions); //shuffle(directions); leave_escapes(board,*me,directions); reports("did the leave escapes shit"); reports("MIRROR"); } else if(me->strategy==BLOCK){ if(dist<7){ enemy_pursue(*me,*enemy,directions); } /*else if(dist<20){ enemy_block(board,*me,*enemy,directions); }*/ else{ enemy_block(board,*me,*enemy,directions); } leave_escapes(board,*me,directions); reports("BLOCK"); } else if(me->strategy==SURVIVAL){ rank_for_survival(board,*me,advantages,directions); reports("SURVIVAL and I am acting upon it"); } for(byte i=0;i<4;++i){//if one way is blocked, go for others reportd(directions[i]); f.direction=directions[i]; if(!blocked(board,f)){ if(better_change_way(board,f)){ reports("YET THIS MOTHER FUCKER CHOSE:"); reportd(i); } *me=f; move_snake(board,me); return 1; } else{ reports("this fucker didn't choose:"); reportd(directions[i]); reports("because that way was supposedly blocked."); } } return LOSE; } reports("went on"); move_snake(board,me); return 1; } void init_game(byte board[len][wid]){ if(p.score>c.score+2 && rand()%2){ must_win=1; } if(must_win && p.score>c.score){ c.strategy=IMITATE; } else{ c.strategy=MIRROR; } c.direction=0; c.y=len/2; c.x=wid*9/20; c.fp=4; c.color=colors[rand()%6]; p.direction=0; p.y=len/2; p.x=wid*11/20; p.fp=8; do{ p.color=colors[rand()%6]; }while(p.color==c.color); for(byte y=0;yMAXLEN){ fprintf(stderr,"Length too high or low.\n"); } autoset=0; break; case 'w': wid=atoi(optarg); if(widMAXWID){ fprintf(stderr,"Width too high or low.\n"); } autoset=0; break; case 'h': default: printf("Usage:%s [options]\n -l length\n -w width\n -h help\n",argv[0]); return EXIT_FAILURE; break; } } #endif initscr(); #ifndef NO_VLA if(autoset){ len=LINES-7; if(lenMAXLEN) len=MAXLEN; wid=COLS-5; if(widMAXWID) wid=MAXWID; } #endif srand(time(NULL)%UINT_MAX); byte board[len][wid]; byte win_limit=WIN_LIMIT; reportd(len); reportd(wid); noecho(); cbreak(); keypad(stdscr,1); if(has_colors()){ start_color(); use_default_colors(); init_pair(1,COLOR_RED,-1); init_pair(2,COLOR_YELLOW,-1); init_pair(3,COLOR_GREEN,-1); init_pair(4,COLOR_CYAN,-1); init_pair(5,COLOR_MAGENTA,-1); init_pair(6,COLOR_BLUE,-1); for(byte b= 0;b<6;++b){ colors[b]=COLOR_PAIR(b+1); } colors[1]|=A_BOLD; } Start: if(c.score==win_limit || p.score==win_limit){ win_limit=WIN_LIMIT; c.score=p.score=0; must_win=0; } if(c.score==p.score && p.score==win_limit-1){ ++win_limit; } curs_set(0); halfdelay(1); init_game(board); erase(); int preinput=0,input=0; while(1){ logo(); draw(board); refresh(); preinput=input; input = getch(); if( input == KEY_F(1) || input=='?' ) help(); if( (input==KEY_F(2)||input=='!') ) gameplay(); if( (input=='k' || (input==KEY_UP||input=='w')) && p.y>0 && p.direction != DOWN ){ p.direction=UP; } if( (input=='j' || (input==KEY_DOWN||input=='s')) && p.y0 && p.direction != RIGHT){ p.direction=LEFT; } if( (input=='l' || (input==KEY_RIGHT||input=='d')) && p.x 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 . */ #include "common.h" #define NOTHING 123 #ifdef NO_VLA #define len 5 #define wid 6 #else int len=5,wid=6; #endif int py,px; chtype colors[6]={A_BOLD}; int score[2] ={0}; int side[2]={'h','h'}; char so[2] = {'S','O'}; char rd(char board[len][wid],int y, int x){ if(y<0 || x<0 || y>= len || x>=wid) return NOTHING; else return board[y][x]; } void color(byte colored[len][wid],int y,int x,bool side){ if(colored[y][x] == !side || colored[y][x]==2) colored[y][x]=2; else colored[y][x]=side; } void rectangle(int sy,int sx){ for(int y=0;y<=len+1;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+wid*2,ACS_VLINE); } for(int x=0;x<=wid*2;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+len+1,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+len+1,sx,ACS_LLCORNER); mvaddch(sy,sx+wid*2,ACS_URCORNER); mvaddch(sy+len+1,sx+wid*2,ACS_LRCORNER); } void draw(int sy,int sx,char board[len][wid],byte colored[len][wid]){ rectangle(sy,sx); chtype attr ; char prnt; int y,x; for(y=0;y=0) attr |= colors[colored[y][x]]; if( board[y][x] ) prnt = board[y][x]; else prnt = '.'; mvaddch(sy+1+y,sx+x*2+1,attr|prnt); } } } byte did_sos(char board[len][wid], int y , int x ){ byte dy,dx; byte soses=0; if(board[y][x]== 'S'){ for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ if(rd(board,y+dy,x+dx)=='O' && rd(board,y+2*dy,x+2*dx) == 'S' ) ++soses; } } return soses; } else if(board[y][x]== 'O'){ for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ if(rd(board,y+dy,x+dx)=='S' && rd(board,y-dy,x-dx) =='S') ++soses; } } return soses/2; } return 0; } void color_sos(char board[len][wid],byte colored[len][wid], int y , int x ,bool side){ byte dy,dx; if(board[y][x]== 'S'){ for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ if(rd(board,y+dy,x+dx)=='O' && rd(board,y+2*dy,x+2*dx) == 'S' ){ color(colored,y,x,side); color(colored,y+dy,x+dx,side); color(colored,y+2*dy,x+2*dx,side); } } } } else if(board[y][x]== 'O'){ for(dy=-1;dy<2;++dy){ for(dx=-1;dx<2;++dx){ if(rd(board,y+dy,x+dx)=='S' && rd(board,y-dy,x-dx) =='S'){ color(colored,y,x,side); color(colored,y+dy,x+dx,side); color(colored,y-dy,x-dx,side); } } } } } void randmove(int* y,int* x,byte* c){ *y=rand()%len; *x=rand()%wid; *c=rand()%2; } int decide ( char board[len][wid],byte colored[len][wid], byte depth , byte side ){ //the move is imaginary if side is negative int adv,bestadv; int oppadv; int besty,bestx; char bestchar; byte c; oppadv=adv=bestadv=INT_MIN; besty=bestx=-1; int y,x; int ry,rx; byte rc; randmove(&ry,&rx,&rc);//provides efficient randomization for(y=0;y0){ oppadv= decide(board,NULL,depth-1,-1); } if(depth>0 && oppadv != INT_MIN)//this has no meanings if the opponet cannot move adv-=1*oppadv; if(besty<0 ||adv>bestadv || (adv==bestadv && y==ry && x==rx && c==rc /*c==0*/) ){ bestadv=adv; besty=y; bestx=x; bestchar=so[c]; } board[y][x]=0;//undoing the move } } } } if(besty>=0 && side >= 0 ){ board[besty][bestx]=bestchar; score[side]+= did_sos(board,besty,bestx); color_sos(board,colored,besty,bestx,side); } return bestadv; } bool isfilled(char board[len][wid]){ int y,x; for(y=0;y : Scroll"); mvprintw(11,0,"Press a key to continue"); refresh(); getch(); erase(); gameplay(); } int main(int argc, char** argv){ int dpt=-1; signal(SIGINT,sigint_handler); int opt; int auto_stupid_counter=0; bool sides_chosen=0,no_replay=0,fixed_starting_depth=0; while( (opt= getopt(argc,argv,"hnp:1:2:"))!= -1 ){ switch(opt){ case '1': case '2': if(!strcmp("c",optarg) || !strcmp("h",optarg)){ side[opt-'1']=optarg[0]; sides_chosen=1; } else{ puts("That should be either h or c\n"); return EXIT_FAILURE; } break; case 'p': if(sscanf(optarg,"%d",&dpt) && dpt<128 && dpt>0){ fixed_starting_depth=1; } else{ puts("That should be a number from 1 to 127."); return EXIT_FAILURE; } break; #ifndef NO_VLA case 'l': len=atoi(optarg); if(len<0 || len>1000){ fprintf(stderr,"Length too high or low.\n"); } break; case 'w': wid=atoi(optarg); if(wid<0 || wid>1000){ fprintf(stderr,"Width too high or low.\n"); } break; #endif //NO_VLA case 'n': no_replay=1; break; case 'h': default: printf("Usage: %s [options]\n -p ai power\n -1 type of player 1\n -2 type of player 2\n -h help\n -n dont ask for replay\n",argv[0]); return EXIT_SUCCESS; break; } } srand(time(NULL)%UINT_MAX); int input; initscr(); #ifndef NO_MOUSE mousemask(ALL_MOUSE_EVENTS,NULL); #endif curs_set(0); noecho(); cbreak(); keypad(stdscr,1); if(!sides_chosen){ printw("Blue plays first.\n Choose the type of the blue player(H/c)\n" ); refresh(); input=getch(); if(input=='c'){ side[0]='c'; printw("Computer.\n"); } else{ side[0]='h'; printw("Human.\n"); } refresh(); printw("Choose the type of the yellow player(h/C)\n"); refresh(); input=getch(); if(input=='h'){ side[1]='h'; printw("Human.\n"); } else{ side[1]='c'; printw("Computer.\n"); } } if(has_colors()){ start_color(); use_default_colors(); init_pair(1,COLOR_BLUE,-1); init_pair(2,COLOR_YELLOW,-1); init_pair(3,COLOR_GREEN,-1); for(byte b= 0;b<6;++b){ colors[b]=COLOR_PAIR(b+1); } } int sy,sx; Start: sy=sx=0;//for scrolling py=px=0; char board[len][wid]; byte colored[len][wid]; bool t=1; score[0]=score[1]=0; memset(board,0,len*wid); memset(colored,-1,len*wid); Turn: erase(); mvprintw(sy+0,sx+0," _ _ _"); mvprintw(sy+1,sx+0,"(_'| |(_' %d:%d \n",score[0],score[1]); mvprintw(sy+2,sx+0,"._):_:._) \n"); draw(sy+3,sx+0,board,colored); if( isfilled(board) ) goto End; refresh(); t=!t; if(side[t]=='c'){ mvprintw(sy+len+5,sx+0,"Thinking..."); refresh(); decide(board,colored,dpt,t); goto Turn; } //else while(1){ erase(); mvprintw(sy+0,sx+0," _ _ _"); mvprintw(sy+1,sx+0,"(_'| |(_' %d:%d \n",score[0],score[1]); mvprintw(sy+2,sx+0,"._):_:._) \n"); draw(sy+3,sx+0,board,colored); refresh(); input = getch(); if( input==KEY_PPAGE && LINES< len+3){//the board starts in 3 sy+=10; if(sy>0) sy=0; } if( input==KEY_NPAGE && LINES< len+3){ sy-=10; if(sy< -(len+3) ) sy=-(len+3); } if( input=='<' && COLS< wid*2+1){ sx+=10; if(sx>0) sx=0; } if( input=='>' && COLS< wid*2+1){ sx-=10; if(sx< -(wid*2+1)) sx=-(wid*2+1); } if( input==KEY_F(1) || input=='?') help(); if( (input==KEY_F(2)||input=='!') ) gameplay(); if( input==KEY_MOUSE ) mouseinput(sy,sx); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0) --py; if( (input=='j' || (input==KEY_DOWN)) && py0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && pxscore[0]) +1); } if(!fixed_starting_depth && score[1] != score[0] && (side[0]=='c'||side[1]=='c') && (side[0]=='h'||side[1]=='h')){ if( (side[0]=='c' && score[0]>score[1]) || (side[1]=='c' && score[1]>score[0])){//if computer won if(dpt>-3){ --dpt; } if(auto_stupid_counter==1){ dpt=0; } } else{ if(dpt<7){ ++dpt; printw(" I'd play better next time. "); } else{ printw(" Are you human? "); } if(!fixed_starting_depth && auto_stupid_counter==0){ dpt=3; auto_stupid_counter+=1; } } } if(!no_replay){ printw(" Wanna play again?(y/n)"); curs_set(1); flushinp(); input=getch(); curs_set(0); if(input != 'N' && input != 'n' && input!='q') goto Start; } else{ printw("Please press a key on your computer's keyboard to continue."); getch(); } endwin(); return EXIT_SUCCESS; } nbsdgames-6.0.1/sudoku.c000066400000000000000000000305241517406336500151550ustar00rootroot00000000000000/* _ (_ _)UDOKU Authored by abakh 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 . NOTE: This program is only made for entertainment porpuses. The puzzles are generated by randomly clearing tiles on the table and are guaranteed to have a solution , but are not guaranteed to have only one unique solution. */ #include "common.h" byte _wait=0, waitcycles=0;//apparently 'wait' conflicts with a variable in a library macOS includes by default byte py,px; unsigned int filled; chtype colors[6]={0}; #ifdef NO_VLA//the Plan9 compiler can not handle VLAs #define size 3 #define s 9 #ifdef Plan9 // I hope this is approximately right int round(float x) { int y; if(x > 0) y = (int)(x + 0.5); //int will round down, so if the decimal of x is .5 or higher this will round up. else if(x < 0) y = (int)(x - 0.5); // the same but opposite return y; } #endif #else byte size=3,s=9;//s=size*size #endif void cross(byte sy,byte sx,chtype start,chtype middle,chtype end){ //to simplify drawing tables. doesn't draw a cross (why did I choose that name?) mvaddch(sy,sx,start); byte f = 2*size; for(char n=1;ns) return 1; for(byte y=0;ys) board[y][x]=int2sgn(k=1); } ++k; if(k>s) k=1; } } for(byte n=0;n3) printw(" (and characters) \n"); else addch('\n'); printw("so that all the rows, columns and smaller subregions \n"); printw("contain all of the digits from 1 to "); if(size<=3){ addch(int2sgn(s)); addch('.'); } if(size>3){ addch('9'); printw(" and all\nthe alphabet letters from 'a' to '%c'.",int2sgn(s)); } printw("\n\nPress a key to continue."); refresh(); getch(); erase(); } void help(void){ erase(); header(0,0); attron(A_BOLD); mvprintw(3,0," **** THE CONTROLS ****"); mvprintw(13,0,"YOU CAN ALSO USE THE MOUSE!"); attroff(A_BOLD); mvprintw(4,0,"1 - %c : Enter number/character",int2sgn(s)); mvprintw(5,0,"SPACE : Clear tile"); mvprintw(6,0,"ARROW KEYS : Move cursor"); mvprintw(7,0,"q : Quit"); mvprintw(8,0,"n : New board"); mvprintw(9,0,"r : Restart"); if(size>4) printw(" (some of these alphabet controls maybe overridden in certain sizes)"); mvprintw(10,0,"F1 & F2: Help on controls & gameplay"); mvprintw(11,0,"PgDn,PgUp,<,> : Scroll"); mvprintw(14,0,"Press a key to continue"); refresh(); getch(); erase(); gameplay(); } int main(int argc,char** argv){ signal(SIGINT,sigint_handler); bool fastgen=0; int opt; while( (opt=getopt(argc,argv,"hfs:d:"))!=-1){ switch(opt){ #ifndef NO_VLA case 's': size=atoi(optarg); if(size>7 || size<2){ printf("2 <= size <= 7\n"); return EXIT_FAILURE; } break; #endif //NO_VLA case 'f': fastgen=1; break; case 'h': default: printf("Usage:%s [options]\n -s size\n -h help\n -f fast (flawed) generation\n",argv[0]); return EXIT_FAILURE; break; } } fastgen= (size>4) || fastgen || !(!getenv("SUDOKU_FASTGEN")); initscr(); #ifndef NO_MOUSE mousemask(ALL_MOUSE_EVENTS,NULL); #endif //NO_MOUSE noecho(); cbreak(); keypad(stdscr,1); srand(time(NULL)%UINT_MAX); if( has_colors() ){ start_color(); use_default_colors(); init_pair(1,COLOR_YELLOW,-1); init_pair(2,COLOR_GREEN,-1); init_pair(3,COLOR_BLUE,-1); init_pair(4,COLOR_CYAN,-1); init_pair(5,COLOR_MAGENTA,-1); init_pair(6,COLOR_RED,-1); for(byte b=0;b<6;++b){ colors[b]=COLOR_PAIR(b+1); } } #ifndef NO_VLA s= size*size; #endif char board[s][s]; char empty[s][s]; char game[s][s]; int input=0; int sy,sx; Start: sy=sx=0; erase(); curs_set(0); filled =0; memset(board,0,s*s); memset(empty,0,s*s); memset(game,0,s*s); if(fastgen) just_fill(board); else fill(board); mk_puzzle(board,empty,game); py=px=0; while(1){ erase(); draw(sy+3,sx+0,empty,game); header(sy+0,sx+0); refresh(); if(filled == s*s) break; input = getch(); if( input==KEY_PPAGE && LINES< s+size+3){//the board starts in 3 sy+=10; if(sy>0) sy=0; } if( input==KEY_NPAGE && LINES< s+size+3){ sy-=10; if(sy< -(s+size+3) ) sy=-(s+size+3); } if( input=='<' && COLS< s*2){ sx+=10; if(sx>0) sx=0; } if( input=='>' && COLS< s*2){ sx-=10; if(sx< -(s*2)) sx=-(s*2); } if(input == KEY_F(1)||input=='?'){ help(); } if((input==KEY_F(2)||input=='!')){ gameplay(); } if(input == '\n' || input == KEY_ENTER){ if(empty[py][px]==0){ game[py][px]=int2sgn((sgn2int(game[py][px])+1)%(s+1)); } } if(input == KEY_MOUSE) mouseinput(sy,sx); if(input == KEY_UP && py) --py; if((input==KEY_DOWN||input=='s') && py 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 . compile with -lncurses */ #include "common.h" #define FOUND 9 #define UNTOUCHED -1 #define MINLEN 8 #define MINWID 8 #define MAXLEN 1000 #define MAXWID 1000 #define EMPTY_LINES 7 #define MAX_REPEATS 5 #ifdef NO_VLA //The Plan9 compiler can not handle VLAs #define len 8 #define wid 8 #else int len=8,wid=8; #endif int py,px,flags; int mscount; long scores[2]; char sides[2]={'h','h'}; chtype colors[6]={0}; int beginy,view_len; int turn=0; void setup_scroll(){ beginy=0; if(0len){ beginy-=beginy+view_len-len; } } void rectangle(int sy,int sx){ setup_scroll(); for(int y=0;y<=view_len;++y){ mvaddch(sy+y,sx,ACS_VLINE); mvaddch(sy+y,sx+wid*2,ACS_VLINE); } for(int x=0;x<=wid*2;++x){ mvaddch(sy,sx+x,ACS_HLINE); mvaddch(sy+view_len+1,sx+x,ACS_HLINE); } mvaddch(sy,sx,ACS_ULCORNER); mvaddch(sy+view_len+1,sx,ACS_LLCORNER); mvaddch(sy,sx+wid*2,ACS_URCORNER); mvaddch(sy+view_len+1,sx+wid*2,ACS_LRCORNER); } byte get_cell(byte board[len][wid],int y,int x){ return board[(y+len)%len][(x+wid)%wid]; } void logo(int sy, int sx){ mvprintw(sy,sx, "_____"); mvprintw(sy+1,sx+0, " | "); mvprintw(sy+2,sx, " |REASURE %ld:%ld",scores[0],scores[1]); if(turn==0){ attron(colors[1]); mvprintw(sy+1,sx+11,"Percent's Turn"); attroff(colors[1]); } if(turn==1){ attron(colors[2]); mvprintw(sy+1,sx+11,"Square's Turn"); attroff(colors[2]); } } //display void draw(int sy,int sx,byte board[len][wid]){ rectangle(sy,sx); chtype attr ; char prnt; int y,x; setup_scroll(); for(y=beginy;y=0 && board[ty][tx] <9)//it has been click()ed before return 0; else{ board[ty][tx]=0; } int y,x; for(y=ty-1;y=len) break; for (x=tx-1;x=wid) break; if(mines[y][x]) board[ty][tx]++; } } if(!board[ty][tx]){//there are no mines in the adjacent tiles for(y=ty-1;y=len) break; for(x=tx-1;x=wid) break; click(board,mines,y,x); } } } return 0; } //count discovered mines around the number being inspected float hit_probablity(byte board [len][wid],byte mines[len][wid],int ny,int nx){//n:number int y,x; float empty=0; float bombs=0; for(y=ny-1;y=len || x<0 || x>=wid){ continue; } if(board[y][x]==UNTOUCHED){ ++empty; if(mines[y][x]==1){ ++bombs; } } } } if(empty==0){ return 0; } return bombs/empty; } //AI algorithm byte decide(byte board[len][wid],byte mines[len][wid]){ float maxp=0; float p=0; int targety=-1, targetx=-1; int hity,hitx; int y,x; for(y=0;ymaxp){ targety=y; targetx=x; } if(p==1.0){ goto Skip; } } } } Skip: if(-1==targety){ do{ hity=rand()%len; hitx=rand()%wid; }while(board[hity][hitx]!=-1); } else{ do{ hity=targety-1+(rand()%3); hitx=targetx-1+(rand()%3); }while(board[hity][hitx]!=UNTOUCHED ||hitx<0 || hitx>=wid || hity<0 || hity>=len); } return click(board,mines,hity,hitx); } //place mines void mine(byte mines[len][wid]){ int y=rand()%len; int x=rand()%wid; for(int n=0;n : Scroll"); mvprintw(11,0,"Press a key to continue"); refresh(); getch(); erase(); gameplay(); } int main(int argc, char** argv){ signal(SIGINT,sigint_handler); #ifndef NO_VLA int opt; int input; int sides_chosen=0,size_chosen=0; while( (opt=getopt(argc,argv,"hnm:l:w:"))!=-1){ switch(opt){ case '1': case '2': if(!strcmp("c",optarg) || !strcmp("h",optarg)){ sides[opt-'1']=optarg[0]; sides_chosen=1; } else{ puts("That should be either h or c\n"); return EXIT_FAILURE; } break; case 'm': mscount=atoi(optarg); if(mscount<0 || mscount>len*wid){ fprintf(stderr,"Too few/many mines.\n"); } break; case 'l': size_chosen=1; len=atoi(optarg); if(lenMAXLEN){ fprintf(stderr,"Length too high or low.\n"); } break; case 'w': size_chosen=1; wid=atoi(optarg); if(widMAXWID){ fprintf(stderr,"Width too high or low.\n"); } break; case 'h': default: printf("Usage:%s [options]\n -l length\n -w width\n -m number of mines\n -h help\n",argv[0]); return EXIT_FAILURE; break; } } #endif 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); } } #ifndef NO_VLA if(!size_chosen){ if((LINES-7) < 5){ len=5; } else{ len=15; } if((COLS-5)/2 < 20){ wid=20; } else{ wid=15; } } if(!mscount){ mscount=len*wid/8; } if(mscount%2==0){ mscount+=1;//there should not be a draw } #else mscount=len*wid/8; #endif if(!sides_chosen){ printw("Choose type of the # player(H/c)\n" ); refresh(); input=getch(); if(input=='c'){ sides[0]='c'; printw("Computer.\n"); } else{ sides[0]='h'; printw("Human.\n"); } printw("Choose type of the %% player(h/C)\n"); refresh(); input=getch(); if(input=='h'){ sides[1]='h'; printw("Human.\n"); } else{ sides[1]='c'; printw("Computer.\n"); } } byte board[len][wid]; byte mines[len][wid]; int sy,sx; byte repeats; bool first_click; byte won; Start: won=-1; scores[0]=scores[1]=0; sy=sx=0; py=px=0; flags=0; curs_set(0); for(int y=0;ymscount/2){ won=0; goto End; } if(scores[1]>mscount/2){ won=1; goto End; } repeats=0; turn=!turn; if(sides[turn]=='c'){ bool first_time=1; do{ ++repeats; erase(); logo(sy,sx); draw(sy+3,sx+0,board); refresh(); if(!first_time){ usleep(500000);//it is demoralising to see it find 5 mines in a split second } else{ first_time=0; } if(scores[0]>mscount/2 || scores[1]>mscount/2){ goto Turn; } }while(decide(board,mines) && repeatsmscount/2 || scores[1]>mscount/2){ goto Turn; } ++repeats; if(repeats>=MAX_REPEATS){ goto Turn; } while(1){ erase(); logo(sy,sx); draw(sy+3,sx+0,board); refresh(); input = getch(); if( input==KEY_PPAGE && LINES< len+3){//the board starts in 3 sy+=10; if(sy>0){ sy=0; } } if( input==KEY_NPAGE && LINES< len+3){ sy-=10; if(sy< -(len+3) ){ sy=-(len+3); } } if( input=='<' && COLS< wid*2+1){ sx+=10; if(sx>0){ sx=0; } } if( input=='>' && COLS< wid*2+1){ sx-=10; if(sx< -(wid*2+1)){ sx=-(wid*2+1); } } if( input==KEY_F(1) || input=='?' ) help(); if( (input==KEY_F(2)||input=='!') ) gameplay(); if( input==KEY_MOUSE ) mouseinput(sy,sx); if( (input=='k' || (input==KEY_UP||input=='w')) && py>0) --py; if( (input=='j' || (input==KEY_DOWN||input=='s')) && py0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && px 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 . */ #include "common.h" #define SAVE_TO_NUM 11 #define HOOKS 10 #define LEN 24 #define WID 80 #define HWID 40 #define DUDES_WID 32 #ifdef Plan9 int usleep(long usec) { int second = usec/1000000; long nano = usec*1000 - second*1000000; struct timespec sleepy = {0}; sleepy.tv_sec = second; sleepy.tv_nsec = nano; nanosleep(&sleepy, (struct timespec *) NULL); return 0; } #endif // 12 lines of water // 80 columns char dudes[]= " O O \n" "/|\\ /|\\\n" "\\--\\-----------------------/--/\n" "/ \\ / \\\n" "\\ \\ / /\n" "\f" " O\n" " O /| \\\n" "/|\\ / | /\n" "\\--\\----------------------/---/ \n" "/ \\ / \\\n" "\\ \\ / \\\n" " / /\n" "\f" " O\n" " /|\\\n" " O / | \\\n" "/|\\ / | /\n" "\\--\\----------------------/----/\n" "/ \\ / \\\n" "\\ \\ / \\\n" " / /\n" " / /\n" "\f" " O\n" " /| \\\n" " / | \\\n" " O / | /\n" "/|\\ / | /\n" "\\--\\--------------------/-----/\n" "/ \\ / \\\n" "\\ \\ / \\\n" " / \\\n" " / /\n" " / / \n" ; char logo[]= "_____ _ \n" " | .' '. : : \n" " | : : : . : \n" " |UG '._.'F '.'.'AR\n" ; char choose_from[]="7894561230"; char home_row[]= "asdfghjkl;'"; char type_str[10]={0}; byte offset=0; byte level=0; chtype colors[4]={A_NORMAL,A_STANDOUT}; unsigned long score=0; int input; void filled_rect(byte sy,byte sx,byte ey,byte ex){ byte y,x; for(y=sy;y0){ byte a = (LEN-9)/2; star_line(1); star_line(LEN-2); mvaddstr(1,WID/2-8,"CONGRATULATIONS!!"); mvprintw(a+1,HWID-10," _____You beat the"); mvprintw(a+2,HWID-10," .' | previous"); mvprintw(a+3,HWID-10," .' | record"); mvprintw(a+4,HWID-10," | .| | of"); mvprintw(a+5,HWID-10," |.' | |%11ld",formerscore); mvprintw(a+6,HWID-10," | | held by"); mvprintw(a+7,HWID-10," ___| |___%7s!",formername); mvprintw(a+8,HWID-10," | |"); mvprintw(a+9,HWID-10," |____________|"); mvprintw(LEN-3,HWID-11,"Press a key to continue"); refresh(); do{ input=getch(); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); filled_rect(0,0,LEN,WID); blue_border(); } } //scorefile is still open with w+ char pname[60] = {0}; long pscore=0; byte rank=0; rewind(score_file); mvaddstr(1,WID/2-4,"HIGH SCORES"); attron(colors[3]); while( rank>>"); printw("%s",pname); mvprintw(2+2*rank,WID-1-digit_count(pscore),"%ld",pscore); ++rank; } attroff(colors[3]); refresh(); } void help(void){ nocbreak(); cbreak(); attron(colors[3]); filled_rect(0,0,LEN,WID); blue_border(); mvprintw(1,HWID-4,"GAME PLAY"); mvprintw(3,1,"Type those things and beat the other guy"); mvprintw(4,1,"Press h to use home-row mode."); attroff(colors[3]); refresh(); getch(); halfdelay(1); } void sigint_handler(int x){ endwin(); puts("Quit."); exit(x); } int main(int argc,char** argv){ if(argc>1){ printf("This game doesn't take arguments"); } signal(SIGINT,sigint_handler); initscr(); noecho(); cbreak(); keypad(stdscr,1); srand(time(NULL)%UINT_MAX); if(has_colors()){ start_color(); use_default_colors(); init_pair(1,COLOR_BLACK,COLOR_CYAN); init_pair(2,COLOR_BLACK,COLOR_BLUE); init_pair(3,COLOR_WHITE,COLOR_BLUE); init_pair(4,COLOR_BLUE,COLOR_WHITE); for(byte b=0;b<4;++b) colors[b]=COLOR_PAIR(b+1); } byte home_row_mode=0; byte t; byte threshold; for(byte i=0;ithreshold){ t=0; ++offset; } if(offset>HWID-3){ break; } if(offset