-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X if( obj->invers) standout(); X move( i + offset_row, 2*j + offset_col);`20 X printw( "%c%c", obj -> obj_display, obj -> obj_display); X if( obj->invers) standend(); X`7D X XOBJECT *get_obj_adr( c) Xregister char c; X`7B X register OBJECT *ret; X X if( c == player.obj_intern)`09`09ret = &player; X else if( c == playerstore.obj_intern)`09ret = &playerstore; X else if( c == store.obj_intern)`09`09ret = &store; X else if( c == save.obj_intern)`09`09ret = &save; X else if( c == packet.obj_intern)`09`09ret = &packet; X else if( c == wall.obj_intern)`09`09ret = &wall; X else if( c == ground.obj_intern)`09`09ret = &ground; X else ret = &ground; X X return( ret); X`7D X X Xdisplevel() `7B`20 X move( MAXROW, 7); printw( "%3d", level);`20 X`7D X `20 Xdisppackets() `7B`20 X move( MAXROW, 21); printw( "%3d", packets);`20 X`7D X `20 Xdispsave() `7B`20 X move( MAXROW, 33); printw( "%3d", savepack);`20 X`7D X `20 Xdispmoves() `7B`20 X move( MAXROW, 45); printw( "%5d", moves);`20 X`7D X `20 Xdisppushes() `7B`20 X move( MAXROW, 59); printw( "%5d", pushes);`20 X`7D X Xhelpmessage() `7B X X move( MAXROW+2, 0);`20 X printw( "Press ? for help.%c", '\007'); X refresh(); X raw();`09`09`09/* no input allowed while sleeping */ X sleep( 1); X move( MAXROW+2, 0); deleteln(); X refresh(); X noraw();`09`09`09`09/* end raw mode */ X`7D X Xstatic char *helppages`5B`5D = `7B /* be sure that there are max 9 lines per V page */ X "The problem is to push packets to", X "saving positions by moving around", X "and pushing only one packet at a", X " time if possible. ", X " ", X " ", X " ", X " ", X " ", X NULL,`09`09`09`09`09/* end of page */ X "Moving: You can move by using ", X " the keys ijkl. ", X " ", X " left right up down ", X " Move/Push j l i k ", X " Run/Push J L I K ", X " Run only `5EJ `5EL `5EI `5EK ", X " ", X " ", X NULL,`09`09`09`09`09/* end of page */ X "Other commands: ", X " c: temporary save ", X " q: quit ", X " `5ER: refresh the screen ", X " s: save the game ", X " u: undo last move/push ", X " U: undo all ", X " `5EU: reset to temp save ", X " `5EZ: fast quit - abort screen ", X NULL,`09`09`09`09`09/* end of page */ X "Characters on screen are: ", X " ", X " %@ player ", X " %+ player on saving position ", X " %. saving position for packet ", X " %$ packet ", X " %* saved packet ", X " %# wall ", X " ", X NULL,`09`09`09`09/* end of page */ X "If you set a temporary save, you", X "need not undo all when you get", X "stucked. Just reset to this save.", X " ", X "A temporary save is automatically", X "made at the start.", X " ", X " ", X " ", X NULL,`09`09`09`09`09/* end of page */ X NULL`09`09`09`09`09`09/* total end */ X`7D; X Xstatic char *title`5B`5D = `7B X " S O K O B A N ", X "---------------------------------" X`7D; X Xstatic char *helphelp`5B`5D = `7B X " (Press 'e' to exit help, ", X " any other key to continue) " X`7D; X X#define HELPROWS`0916 X#define HELPCOLS`0937 X Xshowhelp() `7B X X register short line, i; X short goon = 1; X WINDOW *win, *makehelpwin(); X X win = makehelpwin(); X for( i = 0, line = 2; goon; i++, line++) `7B X if( helppages`5Bi`5D != NULL) `7B X`09 wmove( win, line+1, 2); X`09 printhelpline( win, helppages`5Bi`5D); X `7D X else `7B X`09 wmove( win, HELPROWS-1, 0); X`09 wrefresh( win); X`09 if( (goon = (wgetch( win) != 'e'))) `7B X`09 line = 1; X`09 if( helppages`5Bi+1`5D == NULL) i = -1; X`09 `7D X `7D X `7D X werase( win); X wrefresh( win); X delwin( win); X`7D X XWINDOW *makehelpwin() `7B X X WINDOW *win, *newwin(); X X win = newwin( HELPROWS, HELPCOLS, 2, 0); X box( win, '`7C', '-'); X wmove( win, 1, 2); X wprintw( win, "%s", title`5B0`5D); X wmove( win, 2, 2); X wprintw( win, "%s", title`5B1`5D); X wmove( win, HELPROWS-3, 2); X wprintw( win, "%s", helphelp`5B0`5D); X wmove( win, HELPROWS-2, 2); X wprintw( win, "%s", helphelp`5B1`5D); X X return( win); X`7D X Xprinthelpline( win, line) XWINDOW *win; Xchar *line; X`7B X OBJECT *obj, *get_obj_adr(); X X for( ; *line != '\0'; line++) `7B X if( *line == '%') `7B X`09 ++line; X`09 obj = get_obj_adr( *line); X if( obj -> invers) wstandout( win); X waddch( win, obj -> obj_display); waddch( win, obj -> obj_display); X if( obj -> invers) wstandend( win); X `7D X else waddch( win, *line); X `7D X`7D $ CALL UNPACK SHOWSCREEN.C;1 1198649219 $ create 'f' X#include X#include unixlib X#include stdlib X#include libdef X#include jpidef X#include descrip X#include "sokoban.h" X X#define location(chr,target) ((unsigned int)strchr(target,chr)-(unsigned int V)target) X Xextern char *strrchr(); Xextern short readscreen(), play(), outputscore(), X`09 makenewscore(), restoregame(), score(); X Xextern short level, packets, savepack, moves, pushes, rows, columns; Xshort scoring = 1; Xshort scorelevel, scoremoves, scorepushes; Xchar map`5BMAXROW+1`5D`5BMAXCOL+1`5D; XPOS ppos; Xchar *prgname; X Xstatic short optshowscore = 0,`20 X`09 optmakescore = 0,`20 X optrestore = 1, /* Auto restore if savefile is present */ X`09`09`09 /* don't get level from score file --ADV--*/ X`09 optlevel = 0;`20 Xstatic short superduperuser = 0; X Xstatic short userlevel; X Xmain( argc, argv)`20 Xshort argc;`20 Xchar *argv`5B`5D; X`7B X short ret, ret2; X$DESCRIPTOR(usernamedesc,username); X X scorelevel = 0; X moves = pushes = packets = savepack = 0; X if( (prgname = strrchr( argv`5B0`5D, '/')) == NULL) X prgname = argv`5B0`5D; X else prgname++; X lib$getjpi(&JPI$_USERNAME,0,0,0,&usernamedesc); X if (strchr(username,' ')!=0) X username`5Blocation(' ',username)`5D = 0; X if( username == NULL) X ret = E_NOUSER; X else `7B X if (strcmp( username, SUPERUSER) == 0) superduperuser = 1; X if( (ret = checkcmdline( argc, argv)) == 0) `7B X`09 if( optrestore) /* Always restore game if file is present */ X`09 ret = restoregame(); X if( optshowscore) X`09 ret = outputscore(); X else if( optmakescore) `7B X`09 if( superduperuser) `7B X`09 ret = makenewscore(); X`09 `7D X`09 else ret = E_NOSUPER; X`09 `7D X else if( optlevel > 0) `7B X`09 if( superduperuser) `7B X`09 level = optlevel; X`09`09 optrestore = 0; X`09`09 scoring = 0; /* Ahh! No cheating now! */ X`09 `7D X`09 else `7B X`09`09/* Note: if user desires to play lower level, he can do so */ X`09 /* and still be scored. */ X`09`09 if ( optlevel <= level) `7B X level = optlevel; X`09`09`09optrestore = 0; X`09 `7D X`09`09 else ret = E_LEVHIGHMAX; /* Level higher than maxlevel */ X`09 `7D X`09 `7D X `7D X `7D X if( ret == 0) X ret = gameloop(); X else if (ret == 1) `7B X level = 1; X`09 optrestore = 0; X`09 ret = gameloop(); X`09`7D X errmess( ret); X if( scorelevel && scoring) `7B X ret2 = score(); X errmess( ret2); X `7D X exit( 0); /* End of main */ X`7D X Xcheckcmdline( argc, argv)`20 Xshort argc; Xchar *argv`5B`5D; X`7B X short ret = 0; X X if( argc > 1) X if( (argc == 2) && (argv`5B1`5D`5B0`5D == '-')) `7B X`09 if( (argv`5B1`5D`5B1`5D == 's') && (argv`5B1`5D`5B2`5D == '\0')) X`09 optshowscore = 1; X`09 else if( (argv`5B1`5D`5B1`5D == 'c') && (argv`5B1`5D`5B2`5D == '\0')) X`09 optmakescore = 1; X`09 else if( (argv`5B1`5D`5B1`5D == 'r') && (argv`5B1`5D`5B2`5D == '\0')) X`09 optrestore = 1; X`09 else if( (optlevel = atoi( &(argv`5B1`5D`5B1`5D))) == 0) X`09 ret = E_USAGE; X `7D X else ret = E_USAGE;`20 X return( ret); X`7D X Xgameloop() `7B X X short ret = 0; X X initscr(); crmode(); noecho(); X if( ! optrestore) ret = readscreen(); X while( ret == 0) `7B X if( (ret = play()) == 0) `7B X level++; X moves = pushes = packets = savepack = 0; X ret = readscreen(); X `7D X `7D X clear(); refresh();`20 X nocrmode(); echo(); endwin(); X return( ret); X`7D X Xgetpassword() `7B Xint E_ILLPASSWORD = 30; /* Not used */ X X char passwd`5B20`5D; X scanf("Password: %s",passwd); X return( (strcmp(passwd, PASSWORD) == 0) ? 0 : E_ILLPASSWORD); X`7D X Xchar *message`5B`5D = `7B X "illegal error number", X "cannot open screen file", X "more than one player position in screen file", X "illegal char in screen file", X "no player position in screenfile", X "too much rows in screen file", X "too much columns in screenfile", X "level aborted", X NULL,`09`09`09/* errmessage deleted */ X "cannot get your username", X "cannot open savefile", X "error writing to savefile", X "cannot stat savefile", X "error reading savefile", X "cannot restore, your savefile has been altered", X "game saved", X "too many users in score table", X "cannot open score file", X "error reading scorefile", X "error writing scorefile", X "illegal command line syntax", X "level number higher than current maxlevel", X "level number too big in command line", X "only superuser is allowed to make a new score table", X "cannot find file to restore" X`7D; X Xerrmess( ret)`20 Xregister short ret; X`7B X if ( ret != E_ENDGAME) `7B X fprintf( stderr, "Sokoban: "); X switch( ret) `7B X case E_FOPENSCREEN: case E_PLAYPOS1: case E_ILLCHAR:`20 X`09 case E_PLAYPOS2: case E_TOMUCHROWS: case E_TOMUCHCOLS:`20 X`09 case E_ENDGAME: case E_NOUSER: `20 X`09 case E_FOPENSAVE: case E_WRITESAVE: case E_STATSAVE: `20 X`09 case E_READSAVE: case E_ALTERSAVE: case E_SAVED: `20 X`09 case E_TOMUCHSE: case E_FOPENSCORE: case E_READSCORE:`20 X`09 case E_WRITESCORE: case E_USAGE:`09case E_LEVHIGHMAX: X`09 case E_LEVELTOOHIGH: case E_NOSUPER:`09case E_NOSAVEFILE: X`09`09`09 fprintf( stderr, "%s\n", message`5Bret`5D); X break; X default: fprintf( stderr, "%s\n", message`5B0`5D); X break; X `7D X `7D X if( ret == E_USAGE) usage(); X`7D X Xusage() `7B X printf("Usage: sokoban `5B-`7Bs`7Cc`7Cr`7C`7D`5D\n\n"); X printf(" -c: create new score table (superuser only)\n"); X printf(" -r: restore saved game\n"); X printf(" -s: show score table\n"); X printf(" -: play this level ( must be greater than 0)\n V"); X`7D $ CALL UNPACK SOK.C;1 459219461 $ create 'f' X 0 MASMUMMY 50 1230 444 `20 X 1 V086QKEN 50 1238 458 `20 X 2 MASDAN 50 1267 460 `20 X 3 V141NPG4 44 606 199 `20 X 4 V050QR5K 42 1052 330 `20 X 5 MASBULL 32 452 149 `20 X 6 ACSSJON 29 749 184 `20 X 7 V095PX49 29 1053 272 `20 X 8 V111Q2YG 28 881 316 `20 X 9 MASANDY 28 1091 324 `20 X 10 V051LPQA 24 1604 596 `20 X 11 V115P8D6 18 750 142 `20 X 12 V059NRRZ 18 869 241 `20 X 13 V132KYNQ 18 922 158 `20 X 14 V119MATC 17 303 87 `20 X 15 V106LR4H 17 574 217 `20 X 16 V114JCMW 15 655 166 `20 X 17 V062LLAZ 15 677 156 `20 X 18 V129RAAQ 15 688 154 `20 X 19 V054P8YX 15 803 190 `20 X 20 V622AG66 1 256 97 `20 $ CALL UNPACK SOK.SCORE;1 943015566 $ create 'f' X/*********************************************************************** X You may wish to alter the following directory paths X***********************************************************************/ X/**/ X/* SCREENPATH: the name of the directioy where the screen file are held */ X/**/ X#define SCREENPATH `09"$1$dua12:`5Btemp.masmummy`5D" X X/**/ X/* SAVEPATH: the name of the path where save files are held */ X/* Attention: Be sure that there are no other files with */ X/* the name .sav */ X/**/ X/* Note: Since there will be only one save file per user (unless he X/* somehow deletes the file), I changed the format of X/* "path:username.sav" to simply "homedirectory:savefile" X/* --ADV-- */ X#define sfname `09"sys$login:sokoban.sav" X X/**/ X/* LOCKPATH: temporary file which is created to ensure that no users */ X/* work with the scorefile at the same time */ X/**/ X/* I took this out since locking the file was screwing up the VMS`20 X/* conversion --ADV-- X/* X/* #define LOCKFILE`09"$1$dua22:`5Btemp.masandy`5Dsok.lock"*/ X X/**/ X/* SCOREFILE: the full pathname of the score file */ X/**/ +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-