pax_global_header00006660000000000000000000000064141764755610014532gustar00rootroot0000000000000052 comment=2199c6efd36e84b90086600ff5c10b7ba9f58fee nbsdgames-5/000077500000000000000000000000001417647556100132035ustar00rootroot00000000000000nbsdgames-5/LICENSE000066400000000000000000000006301417647556100142070ustar00rootroot00000000000000Authored 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-5/Makefile000066400000000000000000000060141417647556100146440ustar00rootroot00000000000000# -*- 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?=/usr/games SCORES_DIR?=/var/games MAN_DIR?=/usr/share/man/man6 CFLAGS+= -Wno-unused-result -D SCORES_DIR=\"$(SCORES_DIR)\" LDFLAGS+= -lncurses -lm ALL= nbsdgames jewels sudoku mines reversi checkers battleship rabbithole sos pipes fifteen memoblocks fisher muncher miketron redsquare darrt snakeduel tugow SCORE_FILES= pipes_scores jewels_scores miketron_scores muncher_scores fisher_scores darrt_scores tugow_scores all: $(ALL) scorefiles: for sf in $(SCORE_FILES); do touch $(SCORES_DIR)/$$sf ; chmod 664 $(SCORES_DIR)/$$sf; chown :games $(SCORES_DIR)/$$sf ; done; for game in $(ALL); do chown :games $(GAMES_DIR)/$$game; chmod g $(GAMES_DIR)/$$game ; done; manpages: cp man/* $(MAN_DIR) jewels: jewels.c config.h common.h $(CC) jewels.c $(LDFLAGS) $(CFLAGS) -o ./jewels sudoku: sudoku.c config.h $(CC) sudoku.c $(LDFLAGS) $(CFLAGS) -o ./sudoku mines: mines.c config.h $(CC) mines.c $(LDFLAGS) $(CFLAGS) -o ./mines reversi: reversi.c config.h $(CC) reversi.c $(LDFLAGS) $(CFLAGS) -o ./reversi checkers: checkers.c config.h $(CC) checkers.c $(LDFLAGS) $(CFLAGS) -o ./checkers battleship: battleship.c config.h $(CC) battleship.c $(LDFLAGS) $(CFLAGS) -o ./battleship rabbithole: rabbithole.c config.h $(CC) rabbithole.c $(LDFLAGS) $(CFLAGS) -o ./rabbithole sos: sos.c config.h $(CC) sos.c $(LDFLAGS) $(CFLAGS) -o ./sos pipes: pipes.c config.h common.h $(CC) pipes.c $(LDFLAGS) $(CFLAGS) -o ./pipes fifteen: fifteen.c config.h $(CC) fifteen.c $(LDFLAGS) $(CFLAGS) -o ./fifteen memoblocks: memoblocks.c $(CC) memoblocks.c $(LDFLAGS) $(CFLAGS) -o ./memoblocks fisher: fisher.c config.h common.h $(CC) fisher.c $(LDFLAGS) $(CFLAGS) -o ./fisher muncher: muncher.c config.h common.h $(CC) muncher.c $(LDFLAGS) $(CFLAGS) -o ./muncher miketron: miketron.c config.h common.h $(CC) miketron.c $(LDFLAGS) $(CFLAGS) -o ./miketron redsquare: redsquare.c config.h $(CC) redsquare.c $(LDFLAGS) $(CFLAGS) -o ./redsquare darrt: darrt.c config.h common.h $(CC) darrt.c $(LDFLAGS) $(CFLAGS) -o ./darrt nbsdgames: nbsdgames.c $(CC) nbsdgames.c $(LDFLAGS) $(CFLAGS) -o ./nbsdgames snakeduel: snakeduel.c config.h $(CC) snakeduel.c $(LDFLAGS) $(CFLAGS) -o ./snakeduel tugow: tugow.c common.h $(CC) tugow.c $(LDFLAGS) $(CFLAGS) -o ./tugow menu: cp nbsdgames.desktop /usr/share/applications cp nbsdgames.svg /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) $(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 cp nb* $(GAMES_DIR) nbmanpages: nb cp man/nb* $(MAN_DIR) nbclean: for game in $(ALL); do rm nb$$game; done; nbsdgames-5/README.md000066400000000000000000000107371417647556100144720ustar00rootroot00000000000000# New BSD Games *You have a computing machine from 1980's and you wonder how you can use it?
Do you have Plan9 dual-booted with OpenBSD and keep the OpenBSD just for gaming?
Are you the DSL developer and have cancelled the project because you lacked games?
You are a bored sysadmin with no work, and need to kill time looking busy with terminal?
You have to make a Reversi AI for your homework and you don't know where to copy it from?
Your port of a Unix-like system 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?*
**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, unplayable on the environments that don't support the line characters) * 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 (Numlock practice game) 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. ## Prerequisites * 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 run 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 ``` ## Platforms They natively run on Linux, BSD, MacOS and 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. ## Packages It is now on Debian unstable and soon on your Debian-derived distros, just install the deb from here until it gets to your repo. Thanks to Gürkan Myczko for packaging. It's available on Arch (AUR) thanks to Elias Riedel Gårding: https://aur.archlinux.org/packages/nbsdgames-git/ (The commands start with nb to avoid name conflict) It's been made available for rpm distros thanks to Zinjanthropus: https://build.opensuse.org/package/show/home:Zinjanthropus/nbsdgames It's available on pkgsrc (default on NetBSD, Minix, supports everything else) thanks to nia: https://pkgsrc.se/games/nbsdgames It's available on homebrew (package manager for Linux people using Mac OSX, and Linux people using OSX using Linux) thanks to kind strangers: https://formulae.brew.sh/formula/nbsdgames It's available on FreeBSD thanks to Robert Clausecker https://www.freshports.org/games/nbsdgames/ ## 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 * 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) * Getting it to Redhat and SUSE repos would be nice. Also thank 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-5/battleship.c000066400000000000000000000340351417647556100155130ustar00rootroot00000000000000/* _ |_) |_)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 #include #include #include #include #include #include #include "config.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 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(); } 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(); } 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-5/checkers.c000066400000000000000000000376771417647556100151620ustar00rootroot00000000000000/* .-. | ' '._.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 #include #include #include #include #include #include #include #include #include #include "config.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 int dpt; byte game[8][8]; byte computer[2]={0,0}; char sides[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 s){//s is the type of move, it doesn't stand for anything 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(s == IMAGINARY || s == NORMAL ) nexts=IMAGINARY; else nexts=ALT_IMG; for(y=0;y<8;++y){ for(x=0;x<8;++x){ if(fj && (s==NORMAL || s==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 && (s==ALT_NRM || s==NORMAL) ) adv= DOESNT_MATTER;//you have to do the move anyway else if(!depth){ if(s==IMAGINARY || s==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(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 && s==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(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 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(); } 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(); } int main(int argc,char** argv){ dpt=4; int opt; bool sides_chosen=0,no_replay=0; while( (opt= getopt(argc,argv,"hnp:1:2:"))!= -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 'p': if(sscanf(optarg,"%d",&dpt) && dpt<128 && dpt>0) ; 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]=dpt; sides[0]='c'; printw("Computer.\n"); } else{ computer[0]=0; sides[0]='h'; printw("Human.\n"); } printw("Choose type of the white player(h/C)\n"); refresh(); input=getch(); if(input=='h'){ computer[1]=0; sides[1]='h'; printw("Human.\n"); } else{ computer[1]=dpt; sides[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 gain for either side result=0; goto End; } endgame= score[t]<=5 || score[!t]<=5; draw(3,0); refresh(); while(sides[t]=='c'){ mvprintw(13,0,"Thinking..."); refresh(); decide(turn,dpt+(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."); } 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-5/circlejump.c000077500000000000000000000152131417647556100155110ustar00rootroot00000000000000/* _ | '. | : |.' 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 #include #include #include #include #include #include #include #include #include #include "config.h" #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; char msg[150]={0}; byte msg_show=0; bool timed[3]; byte circlex[3]; byte circley[3]; byte loops_left=0; float shooting_angle=0; float rotation_angle=0; byte digit_count(int num){ byte ret=0; do{ ++ret; num/=10; }while(num); return ret; } 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 bet 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==KEY_DOWN); 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"); attron(colors[3]); while( rank>>"); printw("%s",pname); mvprintw(2+2*rank,WID-1-digit_count(pscore),"%d",pscore); ++rank; } refresh(); } void help(void){ nocbreak(); cbreak(); attron(colors[3]); 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."); attroff(colors[3]); refresh(); getch(); 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(); 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(); Start: 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=='Q'){ strcpy(msg,"Ctrl-C to quit."); msg_show=50; } 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==KEY_DOWN); if(input!='q' && input!='n' && input!='N') goto Start; endwin(); return 0; } nbsdgames-5/common.h000066400000000000000000000055461417647556100146560ustar00rootroot00000000000000/* 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 "config.h" #define FOPEN_FAIL -10 #define ENV_VAR_OR_USERNAME (getenv("NB_PLAYER")?getenv("NB_PLAYER"):getenv("USER")) 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_]; 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(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-5/darrt.c000066400000000000000000000220311417647556100144610ustar00rootroot00000000000000/* _ | '. | : |.' 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 #include #include #include #include #include #include #include #include #include #include "config.h" #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; 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; 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; } //move a->x+=cos(a->angle)*a->v; a->y+=sin(a->angle)*a->v; 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; } } 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"); attron(colors[3]); while( rank>>"); printw("%s",pname); mvprintw(2+2*rank,WID-1-digit_count(pscore),"%d",pscore); ++rank; } attroff(colors[3]); refresh(); } void help(void){ nocbreak(); cbreak(); attron(colors[3]); 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."); 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(); 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(); Start: 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'){ strcpy(msg,"Ctrl-C to quit."); msg_show=50; } 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-5/fifteen.c000066400000000000000000000140361417647556100147730ustar00rootroot00000000000000/* .-- |__ | 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 #include #include #include #include #include #include "config.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 #include #include #include #include #include #include #include #include #include "config.h" #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),"%d",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-5/jewels.c000066400000000000000000000211321417647556100146370ustar00rootroot00000000000000/* 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 #include #include #include #include #include "config.h" #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:%d",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-5/man/000077500000000000000000000000001417647556100137565ustar00rootroot00000000000000nbsdgames-5/man/battleship.6000066400000000000000000000007271417647556100162120ustar00rootroot00000000000000.\" 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-5/man/checkers.6000066400000000000000000000015611417647556100156370ustar00rootroot00000000000000.\" 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-5/man/darrt.6000066400000000000000000000004731417647556100151650ustar00rootroot00000000000000.\" 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-5/man/fifteen.6000066400000000000000000000006161417647556100154700ustar00rootroot00000000000000.\" 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-5/man/fisher.6000066400000000000000000000010071417647556100153230ustar00rootroot00000000000000.\" 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-5/man/jewels.6000066400000000000000000000002761417647556100153430ustar00rootroot00000000000000.\" 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-5/man/memoblocks.6000066400000000000000000000010701417647556100161760ustar00rootroot00000000000000.\" 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-5/man/miketron.6000066400000000000000000000007121417647556100156750ustar00rootroot00000000000000.\" 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-5/man/mines.6000066400000000000000000000012711417647556100151610ustar00rootroot00000000000000.\" 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-5/man/muncher.6000066400000000000000000000004611417647556100155070ustar00rootroot00000000000000.\" 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-5/man/pipes.6000066400000000000000000000006611417647556100151700ustar00rootroot00000000000000.\" 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-5/man/rabbithole.6000066400000000000000000000007701417647556100161640ustar00rootroot00000000000000.\" 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-5/man/redsquare.6000066400000000000000000000006321417647556100160410ustar00rootroot00000000000000.\" 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-5/man/reversi.6000066400000000000000000000014111417647556100155210ustar00rootroot00000000000000.\" 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-5/man/snakeduel.6000066400000000000000000000004051417647556100160170ustar00rootroot00000000000000.\" 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-5/man/sos.6000066400000000000000000000010421417647556100146460ustar00rootroot00000000000000.\" 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-5/man/sudoku.6000066400000000000000000000013251417647556100153600ustar00rootroot00000000000000.\" 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-5/memoblocks.c000066400000000000000000000134771417647556100155160ustar00rootroot00000000000000/* . . _ |\/| |_) | |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 #include #include #include #include #include #include "config.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 #include #include #include #include #include #include #include #include #include "config.h" #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 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); } 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 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:%ld",immunity); else if(flight) mvprintw(2,12,"Flight:%ld",flight); else if(notrail) mvprintw(2,12,"NoTrail:%ld",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-5/mines.c000066400000000000000000000217721417647556100144730ustar00rootroot00000000000000/* |\/| | |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 #include #include #include #include #include #include #include "config.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; byte 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(); } void gameplay(void){ erase(); mvprintw(1,0,"|\\/|"); mvprintw(2,0,"| |INES"); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); mvprintw(4,0,"Try to find the landmines in the field\n"); printw("with logical reasoning: When you click\n"); printw("on a tile ( a '.' here), numbers may show\n"); printw("up that indicate the number of landmines\n"); printw("in adjacent tiles; you should find and \n"); printw("avoid the landmines based on them; and\n"); printw("clicking on a landmine would make you\n"); printw("lose the game."); refresh(); getch(); erase(); } 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 #include #include #include #include #include #include #include #include "config.h" #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"jewels\n" NB"sudoku\n" NB"mines\n" NB"reversi\n" NB"checkers\n" NB"battleship\n" NB"rabbithole\n" NB"sos\n" NB"pipes\n" NB"fifteen\n" NB"memoblocks\n" NB"fisher\n" NB"muncher\n" NB"miketron\n" NB"redsquare\n" NB"darrt\n" NB"snakeduel\n" NB"tugow\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" }; char choice_str[100]={0}; void fancy_background(){ int y,x; int lines=LINES,cols=COLS; #define ABS(x) (((x)<0)?-(x):(x)) 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){ 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_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); system(choice_str); reset_prog_mode(); break; } } curs_set(1); //show_scores(save_score()); endwin(); return 0; } nbsdgames-5/nbsdgames.desktop000066400000000000000000000003401417647556100165360ustar00rootroot00000000000000[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-5/nbsdgames.svg000066400000000000000000000133511417647556100156720ustar00rootroot00000000000000 image/svg+xml nbsdgames-5/pipes.c000066400000000000000000000241121417647556100144670ustar00rootroot00000000000000/* _ |_) | 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 #include #include #include #include #include #include "config.h" #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 #include #include #include #include #include #include "config.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(); } void gameplay(void){ erase(); mvprintw(0,0," _ "); mvprintw(1,0,"|_)"); mvprintw(2,0,"| \\ABBITHOLE"); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("Try to gather all the carrots in the maze\n"); printw("in the given time. The determining factors\n"); printw("are your choice of paths and the speed of\n "); printw("your fingers.\n"); refresh(); while ( getch()==ERR ); erase(); } 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 #include #include #include #include #include #include "config.h" #define LEN 35 #define WID 50 #define RLEN LEN //real #define RWID WID #define DEAD 0 #define ALIVE 1 #define RED 2 #define EMPTY_LINES 7 int level; byte py,px; byte cy,cx;//cross bool coherent;//square's coherence int anum,rnum;//reds and otherwise alive cell counts chtype colors[6]={0}; void cp(byte a[RLEN][RWID],byte b[RLEN][RWID]){ byte y,x; for(y=0;yLEN){ 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{ if(coherent && board[y][x]==RED) coherent=0; 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]){ ++level; memset(board,0,RLEN*RWID); switch(level){ case 0: 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 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,15," #### # "); add_line(board,16," # # # "); add_line(board,17," # # # ## # # # ## # ## # #"); add_line(board,18," ##### ## # # # # # # # # # #"); add_line(board,19," # # # # # # # # # # # #"); add_line(board,20," # # # # ## # # ## #"); break; case 2: 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 3: 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 4: 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," #### #### "); //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; } } } //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: curs_set(0); halfdelay(9); cinred=0; py=LEN*3/4; px=WID/2; curs_set(0); level=-1; new_level(board); mk_square(board); while(1){ switch(rand()%5){//move the cross 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(board[cy][cx]==RED) ++cinred; else cinred=0; count(board); if(rnum!=4) coherent=0; if(!coherent && rnum==4) reemerge(board); erase(); logo(); draw(board); refresh(); if(rnum>anum||cinred==2){ mvprintw(LEN+5,0,"Well done! Press a key to continue:"); curs_set(1); getch(); curs_set(0); new_level(board); py=LEN*3/4; px=WID/2; mk_square(board); continue; } else if(!rnum){ move(LEN+5,0); printw("You have lost The Game"); if(rand()%5==0) printw(" (and RedSquare)"); printw(". "); break; } halfdelay(9); input = getch(); live(board); count(board);//apparently this should come at both sides of live+draw. resulting from trial and error. if(rnum!=4)//the square has participated in life reactions if so coherent=0; if(!coherent && rnum==4)//there can be a square reemerge(board); 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(); } } move(EMPTY_LINES+view_len,0); printw("Wanna play again?(y/n)"); nocbreak(); cbreak(); curs_set(1); flushinp(); input=getch(); if(input != 'N' && input != 'n' && input != 'q') goto Start; endwin(); return EXIT_SUCCESS; } nbsdgames-5/reversi.c000066400000000000000000000225721417647556100150360ustar00rootroot00000000000000/* _ |_) | \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 #include #include #include #include #include "config.h" byte py,px;//cursor const char piece[2] = {'O','X'}; char game[8][8];//main board char sides[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[0],score[1]); 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 decide(char board[8][8],char piece,char opponet,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){ adv= decide(plan,opponet,piece,depth-1);//least benefit for the opponet if(adv) //the opponet can make a move adv = 1/adv; 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 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"); curs_set(1); getch(); } 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 opponet'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(); } int main(int argc , char** argv){ int depth=2; int opt; bool sides_chosen=0,no_replay=0; while( (opt= getopt(argc,argv,"hnp:1:2:"))!= -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 'p': if(sscanf(optarg,"%d",&depth) && depth<128 && depth>0) ; 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 == 'c'){ sides[0]='c'; printw("Computer.\n"); } else{ sides[0]='h'; printw("Human.\n"); } refresh(); printw("Choose type of the black player(h/C)\n"); refresh(); input=getch(); if(input == 'h'){ sides[1]='h'; printw("Human.\n"); } else{ sides[1]='c'; printw("Computer.\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: erase(); flushinp(); draw(3,0); header(); refresh(); if(cantmove >=2)//both sides cant move, the game ends goto End; turn = !turn; if(sides[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(sides[0]=='h' && sides[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(!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-5/snakeduel.c000066400000000000000000000370701417647556100153310ustar00rootroot00000000000000/* _ _ (_ | : _)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 #include #include #include #include #include #include #include #include #include "config.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 #include #include #include #include #include #include "config.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 sides[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; } } } } 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(); } void gameplay(void){ erase(); mvprintw(0,0," _ _ _"); mvprintw(1,0,"(_'| |(_' "); mvprintw(2,0,"._):_:._) "); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("The game is similar to Tic Tac Toe:\n"); printw("The players write S and O in the squares\n"); printw("and making the straight connected sequence\n"); printw("S-O-S makes you a score; obviously, the\n"); printw("player with a higher score wins."); refresh(); getch(); erase(); } int main(int argc, char** argv){ int dpt=1; signal(SIGINT,sigint_handler); int opt; bool sides_chosen=0,no_replay=0; while( (opt= getopt(argc,argv,"hnp:1:2:"))!= -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 'p': if(sscanf(optarg,"%d",&dpt) && dpt<128 && dpt>0) ; 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'){ sides[0]='c'; printw("Computer.\n"); } else{ sides[0]='h'; printw("Human.\n"); } refresh(); printw("Choose the type of the yellow player(h/C)\n"); refresh(); input=getch(); if(input=='h'){ sides[1]=0; printw("Human.\n"); } else{ sides[1]=dpt; 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 vs %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(sides[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 vs %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||input=='s')) && py0) --px; if( (input=='l' || (input==KEY_RIGHT||input=='d')) && pxscore[0]) +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-5/sudoku.c000066400000000000000000000305641417647556100146710ustar00rootroot00000000000000/* _ (_ _)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 #include #include #include //to seed random #include #include #include #include "config.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;n4) printw(" (some of these alphabet controls maybe overridden in certain sizes)"); mvprintw(10,0,"? : Hint (not like in other games)"); mvprintw(11,0,"F1 & F2: Help on controls & gameplay"); mvprintw(12,0,"PgDn,PgUp,<,> : Scroll"); mvprintw(15,0,"Press a key to continue"); refresh(); getch(); erase(); } void gameplay(void){ erase(); header(0,0); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("Fill the table with digits"); if(size>3) 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(); } 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)) help(); if((input==KEY_F(2)||input=='!')) gameplay(); 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 . */ #include #include #include #include #include #include #include #include #include #include #include "config.h" #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 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),"%d",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"); 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 t; byte threshold; for(byte i=0;ithreshold){ t=0; ++offset; } if(offset>HWID-3){ break; } if(offset