#include #include #include #include #include #include #include "config.h" #define UP 1 #define RIGHT 2 #define DOWN 4 #define LEFT 8 #define CROSSOVER 15 #define FILLED 16 #define SPILL 13 #define FLOWDELAY 5 #define DELAY 3 #define SAVE_TO_NUM 10 #define SY 0 #define SX 7 /* _ |_) | IPES Authored by Hossein Bakhtiarifar No rights are reserved and this software comes with no warranties of any kind to the extent permitted by law. compile with -lncurses */ typedef signed char byte; typedef unsigned char bitbox; int len,wid,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; FILE* scorefile; char error [150]={0}; void logo(void){ mvprintw(0,0," _ "); mvprintw(1,0,"|_)"); mvprintw(2,0,"| IPES"); } byte scorewrite(void){// only saves the top 10, returns the place in the chart bool deforno; if( !getenv("PP_SCORES") && (scorefile= fopen(PP_SCORES,"r")) ){ deforno=1; } else{ deforno=0; if( !(scorefile = fopen(getenv("PP_SCORES"),"r")) ){ sprintf(error,"No accessible score files found. You can make an empty text file in %s or set PP_SCORES to such a file to solve this.",PP_SCORES); return -1; } } char namebuff[SAVE_TO_NUM][60]; long scorebuff[SAVE_TO_NUM]; memset(namebuff,0,SAVE_TO_NUM*60*sizeof(char) ); memset(scorebuff,0,SAVE_TO_NUM*sizeof(long) ); long fuckingscore =0; char fuckingname[60]={0}; byte location=0; while( fscanf(scorefile,"%59s : %ld\n",fuckingname,&fuckingscore) == 2 && location=itreached || score>=scorebuff[location]) ){ fprintf(scorefile,"%s : %ld\n",getenv("USER"),score); ret=location; wroteit=1; } if(location0){ 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 bet 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(scorefile); while( rank>>"); printw("%d",rank+1); attroff(green); printw(") %s : %ld",pname,pscore); rank++; } 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(random()%17){//17 so all forms have the same chance byte a=random()%4; byte b; do{ b=random()%4; }while(b==a); return (1 << a) | ( 1 << b); } else return CROSSOVER;//sum of all directions, the crossover } //.. 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;y3 || (argc==2 && !strcmp("help",argv[1])) ){ printf("Usage: %s [len wid]\n",argv[0]); return EXIT_FAILURE; } if(argc==2){ puts("Give both dimensions."); return EXIT_FAILURE; } if(argc==3){ bool lool = sscanf(argv[1],"%d",&len) && sscanf(argv[2],"%d",&wid); if(!lool){ puts("Invalid input."); return EXIT_FAILURE; } if(len<5 || wid<5 || len>1000 || wid>1000){ puts("At least one of your given dimensions is too small or too big."); return EXIT_FAILURE; } } else{ wid=20; len=14; } initscr(); mousemask(ALL_MOUSE_EVENTS,NULL); time_t tstart , now, lasttime, giventime=len*wid/4; srandom(time(NULL)%UINT_MAX); bitbox direction,board[len][wid]; int input; byte foo; bool flow,fast; Start: //TODO in all the games, some things have to be moved behind the start . definize sy and sx flow=0; fast=0; score=0; memset(error,0,150); memset(board,0,len*wid); fy=1+(random()%(len-2) ); fx=1+(random()%(wid-2) ); board[fy][fx]= 1 << (random()%4); direction= board[fy][fx]; board[fy][fx]|=FILLED; for(foo=0;foo<5;foo++) tocome[foo]=pipegen(); tstart = time(NULL); lasttime=0; initscr(); curs_set(0); noecho(); cbreak(); halfdelay(DELAY); keypad(stdscr,1); if(has_colors()){ start_color(); use_default_colors(); init_pair(2,COLOR_GREEN,-1); green=COLOR_PAIR(2); } py=px=0; while(1){ now=time(NULL); erase(); logo(); if(fast){ attron(A_BOLD); mvprintw(3,0," FAST"); attroff(A_BOLD); } if(!flow && giventime >= 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) ){ gameplay(); if(!flow) tstart += time(NULL)-now; } if( input == KEY_MOUSE ) mouseinput(); if( (input=='k' || input==KEY_UP) && py>0 ) py--; if( (input=='j' || input==KEY_DOWN) && py0 ) px--; if( (input=='l' || input==KEY_RIGHT) && px