diff --git a/README.md b/README.md index 4ac66d3..dcffc01 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ See this repository: https://git.imzadi.de/acn/backgammon-vt100 * [Quatris](Quatris/) * [Worm](Worm/) * [Cpmtris](cpmtris/) +* [Sokoban](Sokoban/) ## More Games on the Interwebs diff --git a/Sokoban/HitechC/z80v309.lbr b/Sokoban/HitechC/z80v309.lbr new file mode 100644 index 0000000..b642e3a Binary files /dev/null and b/Sokoban/HitechC/z80v309.lbr differ diff --git a/Sokoban/README.md b/Sokoban/README.md new file mode 100644 index 0000000..26dc650 --- /dev/null +++ b/Sokoban/README.md @@ -0,0 +1,54 @@ +# Sokoban + +CP/M port of a Unix curses clone of sokoban + +I found it as part of the ZCN repository: https://github.com/jamesots/zcn + +The C source has been modified for VT100 compatibility, and some unused variables have been removed :) + +``sokoban.com`` is the compiled binary. + +To run it, the files ``sokoban.com`` and ``soklevls.dat`` are needed +The help file, ``sokoban.hlp``, is not used in this version. +You find the contents below. + +See the ``readme.*`` files for more information. + +## Commands + +| Key | Action | Key | Action | Key | Action | +| --- | ------------------- | --- | -------------- | --- | ------------------- | +| h | move/push left | H | run/push left | ^H | run left to object | +| l | move/push right | L | run/push right | ^L | run right to object | +| j | move/push down | J | run/push down | ^J | run down to object | +| k | move/push up | K | run/push up | ^K | run up to object | +| u | undo last move/push | U | undo all | | | +| c | temporary save | ^U | reset to temporary save | | | +| ^R | Refresh screen | ? | this help | | | +| q | quit | s | save the game | | | + +## The game + +Characters on screen are: + +| @@ | player | ++ | player on saving position | +| .. | saving position for packet | $$ | packets | +| ** | saved packet | ## | wall | + +Your goal is to move all packets to the saving position by pushing them. + +As you could see you can make a temporary save. This is useful if you think +that all the moves/pushes you have made are correct, but you don't know how +to go on. In this case you can temporary save (using the c command). If you +then get stucked you need not undo all (using U), you can reset to you +temporary save. + +If you have restored a saved game, a temporary save is automatically made +at the start. + +## Compiling + +HiTech C has been used to compile it, it is placed in the directory ``HitechC``. + +To compile Sokoban, I used the command ``c -O sokoban.c`` in CP/M. + diff --git a/Sokoban/readme.1st b/Sokoban/readme.1st new file mode 100644 index 0000000..1bc727d --- /dev/null +++ b/Sokoban/readme.1st @@ -0,0 +1,19 @@ +This is a CP/M port of a Unix curses clone of sokoban, along with an +executable patched to run in emulated 80x24 on ZCN. + +To run it on ZCN, you need to copy both sokoban.com and soklevls.dat. + +To run on any other CP/M, you'll probably need to hack the clear() and +move() routines in sokzcn.c and recompile it (with Hitech C); see +sokzcn.c for more. + +The various other README files aren't too relevant any more, but +they're the READMEs supplied by the author(s) of the version I ported. +FYI, and all that. :-) + +I combined all the level files into one 'soklevls.dat' file. The format +is that of the old screen.?? files, but with a ^L separating each level. +This should make it easy to add your own levels; in VDE you can insert a +^L by doing ^P ^L. The hard bit is designing the levels. :-) + +-Rus. diff --git a/Sokoban/readme.lnx b/Sokoban/readme.lnx new file mode 100644 index 0000000..9592f0d --- /dev/null +++ b/Sokoban/readme.lnx @@ -0,0 +1,34 @@ +This packages was originally a port of sokoban to minix. but with a +few hacks it works fine with linux too. + + +I have done some hacking in source-code to +obtain the following: + +1. It is now possible to use the arrow-keys + to move the player, you can also use the + numerical-keypad. + +2. The objects now contains of two diffrent + characters so you can make packages thats + looks like '[]', earlier you just had one + character that where repeated twice. + +3. The getch function in curses dont behave well + in combination with tcsh (6.01) so i 'borrowed' + from tt (the Tetris clone) the method to use + read instead. + +The Executable is compiled with gcc2.1 and shared libs, but it should +be no problems to re-compile it with gcc 1.40 + +The compiled version looks for screenfiles in /usr/games/sokob, it also +puts its highscore file there. + +Dont forget to make a highscore file first, sokoban want work if you don't. + + +Bengt Andersson. +Student at KTH (The Royal Tecnical High School) Sweden. +email: da1-ban@nada.kth.se + \ No newline at end of file diff --git a/Sokoban/readme.org b/Sokoban/readme.org new file mode 100644 index 0000000..bfb6c37 --- /dev/null +++ b/Sokoban/readme.org @@ -0,0 +1,39 @@ +This is SOKOBAN. + +I saw this game first on a PC running MSDOS. I found the idea of the game so +clever, that I made up my mind to make it run with an ascii terminal using +curses so that we can play it on our MicroVAX/ULTRIX. + +Along with this package there are alot of screen files describing the various +play levels. So what you need to do to install it on your own machine is: + +- Edit the header file sokoban.h to alter the given defines + +You have to note the following restrictions + +- The screen files must be readable for everyone who should be able to play + his game +- The score file should have read/write permission only for the owner + of the executable program. Because of that sokoban must run with setuid. + +You can now compile it (just type 'make'). +If compilation is succesful you must initialize the score file (just type +'sokoban -c') + +There is no manual page. All you have to know when you first play the game is +the command '?'. This gives you one screenful of information. + +After you have solved all the given screens (this will take a while) you will +find the game boring (sure you will). I hope there will be a lot of players who +will think out some new screens. +To test your own screens copy them to the screen directory (with a new level +number ) and type sokoban -. + +PLEASE DO SO AND POST NEW SCREENS TO THE NET. +OTHERWISE IT GETS BORING !!!!!!!!!!!!!!!!!!!! + +Comments are welcome. + +>From Canada or the US reply to ...!pyramid!tub!astbe!ber + (otherwise it would be expensive) +from elsewhere reply to ber@astbe diff --git a/Sokoban/readme.v2 b/Sokoban/readme.v2 new file mode 100644 index 0000000..5c0f6fb --- /dev/null +++ b/Sokoban/readme.v2 @@ -0,0 +1,27 @@ +This is my second version of SOKOBAN. + +The first thing I have to say is that I don't have the sources for SOKOBAN +under MS-DOS. I believe that this program is copyrighted. I took only the +idea and the screens of the PC-version. +I think that porting my version of SOKOBAN to the PC will not be very difficult +if you use the PC-Curses version which was on the net some months ago. + +I had a short mail talk with Norman Ramsey (...!allegra!princeton!nr) who wants +to do the porting. He said that he will post his version if the work is done. + +Some people asked me whether it is possible to make a better looking screen. +I added some extra definitions to the header file sokoban.h so that it is +possible to alter the the characters that are used for the representation of +the objects on the screen. You can also define wheter the object is displayed +in standout mode (invers) or not. + +There is no helpfile anymore (sokoban.help in the first version). I +included the help file in showscreen.c and made a better help facility. + +The score files from both versions are compatible so that you can go on with +the game. + +At last I added some new screens. I hope you enjoy them. + +If you have already designed some new screens mail them to me. My netadress is +given in README. diff --git a/Sokoban/soklevls.dat b/Sokoban/soklevls.dat new file mode 100644 index 0000000..6046379 --- /dev/null +++ b/Sokoban/soklevls.dat @@ -0,0 +1,761 @@ + ##### + # # + #$ # + ### $## + # $ $ # +### # ## # ###### +# # ## ##### ..# +# $ $ ..# +##### ### #@## ..# + # ######### + ####### + +############ +#.. # ### +#.. # $ $ # +#.. #$#### # +#.. @ ## # +#.. # # $ ## +###### ##$ $ # + # $ $ $ $ # + # # # + ############ + + ######## + # @# + # $#$ ## + # $ $# + ##$ $ # +######### $ # ### +#.... ## $ $ # +##... $ $ # +#.... ########## +######## + + ######## + # ....# +############ ....# +# # $ $ ....# +# $$$#$ $ # ....# +# $ $ # ....# +# $$ #$ $ $######## +# $ # # +## ######### +# # ## +# $ ## +# $$#$$ @# +# # ## +########### + + ##### + # ##### + # #$## # + # $ # +######### ### # +#.... ## $ $### +#.... $ $$ ## +#.... ##$ $ @# +######### $ ## + # $ $ # + ### ## # + # # + ###### + +###### ### +#.. # ##@## +#.. ### # +#.. $$ # +#.. # # $ # +#..### # $ # +#### $ #$ # + # $# $ # + # $ $ # + # ## # + ######### + + ##### + ####### ## +## # @## $$ # +# $ # +# $ ### # +### #####$### +# $ ### ..# +# $ $ $ ...# +# ###...# +# $$ # #...# +# ### ##### +#### + + #### + # ########### + # $ $ $ # + # $# $ # $ # + # $ $ # # +### $# # #### # +#@#$ $ $ ## # +# $ #$# # # +# $ $ $ $ # +##### ######### + # # + # # + #......# + #......# + #......# + ######## + + ####### + # ...# + ##### ...# + # . .# + # ## ...# + ## ## ...# + ### ######## + # $$$ ## + ##### $ $ ##### +## #$ $ # # +#@ $ $ $ $ # +###### $$ $ ##### + # # + ######## + + ### ############# +##@#### # # +# $$ $$ $ $ ...# +# $$$# $ #...# +# $ # $$ $$ #...# +### # $ #...# +# # $ $ $ #...# +# ###### ###...# +## # # $ $ #...# +# ## # $$ $ $##..# +# ..# # $ #.# +# ..# # $$$ $$$ #.# +##### # # #.# + # ######### #.# + # #.# + ############### + + #### + #### # # + ### @###$ # + ## $ # + ## $ $$## ## + # #$## # + # # $ $$ # ### + # $ # # $ ##### +#### # $$ # # +#### ## $ # +#. ### ######## +#.. ..# #### +#...#.# +#.....# +####### + +################ +# # +# # ###### # +# # $ $ $ $# # +# # $@$ ## ## +# # $ $ $###...# +# # $ $ ##...# +# ###$$$ $ ##...# +# # ## ##...# +##### ## ##...# + ##### ### + # # + ####### + + ######### + ## ## ##### +### # # ### +# $ #$ # # ... # +# # $#@$## # #.#. # +# # #$ # . . # +# $ $ # # #.#. # +# ## ##$ $ . . # +# $ # # #$#.#. # +## $ $ $ $... # + #$ ###### ## # + # # ########## + #### + + ####### + ####### # + # # $@$ # + #$$ # ######### + # ###......## # + # $......## # # + # ###...... # +## #### ### #$## +# #$ # $ # # +# $ $$$ # $## # +# $ $ ###$$ # # +##### $ # # + ### ### # # + # # # + ######## # + #### + + ######## + # # # + # $ # + ### #$ #### + # $ ##$ # + # # @ $ # $# + # # $ #### + ## ####$## # + # $#.....# # # + # $..**. $# ### +## #.....# # +# ### ####### +# $$ # # +# # # +###### # + ##### + +##### +# ## +# # #### +# $ #### # +# $$ $ $# +###@ #$ ## + # ## $ $ ## + # $ ## ## .# + # #$##$ #.# + ### $..##.# + # #.*...# + # $$ #.....# + # ######### + # # + #### + + ########## + #.. # # + #.. # + #.. # #### + ####### # ## + # # + # # ## # # +#### ## #### ## +# $ ##### # # +# # $ $ # $ # +# @$ $ # ## +#### ## ####### + # # + ###### + + ########### + # . # # + # #. @ # + ##### ##..# #### +## # ..### ### +# $ #... $ # $ # +# .. ## ## ## # +####$##$# $ # # # + ## # #$ $$ # # + # $ # # # $## # + # # + # ########### # + #### #### + + ###### + # @#### +##### $ # +# ## #### +# $ # ## # +# $ # ##### # +## $ $ # # +## $ $ ### # # +## # $ # # # +## # #$# # # +## ### # # ###### +# $ #### # #....# +# $ $ ..#.# +####$ $# $ ....# +# # ## ....# +################### + + ########## +##### #### +# # $ #@ # +# #######$#### ### +# # ## # #$ ..# +# # $ # # #.# +# # $ # #$ ..# +# # ### ## #.# +# ### # # #$ ..# +# # # #### #.# +# #$ $ $ #$ ..# +# $ # $ $ # #.# +#### $### #$ ..# + # $$ ###....# + # ## ###### + ######## + +######### +# # +# #### +## #### # # +## #@## # +# $$$ $ $$# +# # ## $ # +# # ## $ #### +#### $$$ $# # + # ## ....# + # # # #.. .# + # # # ##...# + ##### $ #...# + ## ##### + ##### + +###### #### +# ####### ##### +# $# # $ # # +# $ $ $ # $ $ # +##$ $ # @# $ # +# $ ########### ## +# # #.......# $# +# ## # ......# # +# # $........$ # +# # $ #.... ..# # +# $ $####$#### $# +# $ ### $ $ ## +# $ $ $ $ # +## ###### $ ##### # +# # # +################### + + ####### + # # #### +##### $#$ # ## +#.. # # # # +#.. # $#$ # $#### +#. # #$ # # +#.. $# # $ # +#..@# #$ #$ # # +#.. # $# $# # +#.. # #$$#$ # ## +#.. # $# # $#$ # +#.. # # # # # +##. #### ##### # + #### #### ##### + +############### +#.......... .#### +#..........$$.# # +###########$ # ## +# $ $ $ # +## #### # $ # # +# # ## # ## +# $# # ## ### ## +# $ #$### ### ## +### $ # # ### ## +### $ ## # # ## + # $ # $ $ $ # + # $ $#$$$ # # + # # $ ##### + # @## # # # + ############## + +#### +# ############## +# # ..#......# +# # # ##### ...# +##$# ........# +# ##$###### #### +# $ # ######@ # +##$ # $ ###### # +# $ #$$$## # +# # #$#$### +# #### #$$$$$ # +# # $ # # +# # ## ### +# ######$###### $ # +# # # # +########## ##### + + ####### + # # ##### +## # #...### +# $# #... # +# $ #$$ ... # +# $# #... .# +# # $######## +##$ $ $ # +## # $$ # # + ###### ##$$@# + # ## + ######## + + ################# + #... # # ## +##..... $## # #$ # +#......# $ # # +#......# # # # # +######### $ $ $ # + # #$##$ ##$## + ## $ # $ # + # ## ### # ##$ # + # $ $$ $ $ # + # $ $##$ ###### + ####### @ ## + ###### + + ##### + ##### # + ## $ $ #### +##### $ $ $ ##.# +# $$ ##..# +# ###### ###.. # +## # # #... # +# $ # #... # +#@ #$ ## ####...# +#### $ $$ ##..# + ## $ $ $...# + # $$ $ # .# + # $ $ #### + ###### # + ##### + +##### +# ## +# $ ######### +## # # ###### +## # $#$#@ # # +# # $ # $ # +# ### ######### ## +# ## ..*..... # ## +## ## *.*..*.* # ## +# $########## ##$ # +# $ $ $ $ # +# # # # # # +################### + + ########### + # # # +##### # $ $ # +# ##### $## # ## +# $ ## # ## $ # +# $ @$$ # ##$$$ # +## ### # ## # +## # ### #####$# +## # $ #....# +# ### ## $ #....## +# $ $ # #..$. # +# ## $ # ##.... # +##### ######...## + ##### ##### + + #### + # ######### + ## ## # # + # $# $@$ #### + #$ $ # $ $# ## +## $## #$ $ # +# # # # $$$ # +# $ $ $## #### +# $ $ #$# # # +## ### ###$ # + # #.... # + ####......#### + #....#### + #...## + #...# + ##### + + #### + ##### # + ## $# +## $ ## ### +#@$ $ # $ # +#### ## $# + #....#$ $ # + #....# $# + #.... $$ ## + #... # $ # + ######$ $ # + # ### + #$ ### + # # + #### + +############ +## ## # +## $ $ # +#### ## $$ # +# $ # # +# $$$ # #### +# # # $ ## +# # # $ # +# $# $# # +# ..# #### +####.. $ #@# +#.....# $# # +##....# $ # +###..## # +############ + + ######### + #.... ## + #.#.# $ ## +##....# # @## +# ....# # ## +# #$ ##$ # +## ### $ # + #$ $ $ $# # + # # $ $ ## # + # ### ## # + # ## ## ## + # $ # $ # + ###$ $ ### + # ##### + #### + +############ ###### +# # # ###....# +# $$# @ .....# +# # ### # ....# +## ## ### # ....# + # $ $ # # #### + # $ $## # # +#### # #### # ## # +# # #$ ## # # +# $ $ # ## # ## +# # $ $ # # # +# $ ## ## # ##### +# $$ $$ # +## ## ### $ # + # # # # + ###### ###### + + ##### +##### ###### # +# #### $ $ $ # +# $ ## ## ## ## +# $ $ $ $ # +### $ ## ## ## + # ##### #####$$ # + ##$##### @## # + # $ ###$### $ ## + # $ # ### ### + # $$ $ # $$ # + # # ## # + #######.. .### + #.........# + #.........# + ########### + +########### +#...... ######### +#...... # ## # +#..### $ $ # +#... $ $ # ## # +#...#$##### # # +### # #$ #$ # + # $$ $ $ $## # + # $ #$#$ ##$ # + ### ## # ## # + # $ $ ## ###### + # $ $ # + ## # # # + #####@##### + ### + + #### +####### @# +# $ # +# $## $# +##$#...# # + # $... # + # #. .# ## + # # #$ # + #$ $ # + # ####### + #### + + ###### + #############....# +## ## ##....# +# $$## $ @##....# +# $$ $# ....# +# $ ## $$ # # ...# +# $ ## $ # ....# +## ##### ### ##.### +## $ $ ## . # +# $### # ##### ### +# $ # # +# $ #$ $ $### # +# $$$# $ # #### +# # $$ # +###### ### + ##### + + ############ + # ## + # # #$$ $ # + #$ #$# ## @# + ## ## # $ # ## + # $ #$ # # + # # $ # # + ## $ $ ## # + # # ## $ # + # ## $$# # +######$$ # # +#....# ######## +#.#... ## +#.... # +#.... # +######### + + ##### + ## ## + ## # + ## $$ # + ## $$ $ # + # $ $ # +#### # $$ ##### +# ######## ## # +#. $$$@# +#.# ####### ## ## +#.# #######. #$ $## +#........... # # +############## $ # + ## ## + #### + + ######## + #### ###### + # ## $ $ @# + # ## ##$#$ $ $## +### ......# $$ ## +# ......# # # +# # ......#$ $ # +# #$...... $$# $ # +# ### ###$ $ ## +### $ $ $ $ # + # $ $ $ $ # + ###### ###### + ##### + + ####### + ##### # #### + # # $ # + #### #$$ ## ## # +## # # ## ### +# ### $#$ $ $ # +#... # ## # # +#...# @ # ### ## +#...# ### $ $ # +######## ## # # + ######### + + ##### + # # + # # ####### + # $@###### + # $ ##$ ### # + # #### $ $ # + # ##### # #$ #### +## #### ##$ # +# $# $ # ## ## # +# # #...# # +###### ### ... # + #### # #...# # + # ### # # + # # + ######### + +##### #### +#...# # #### +#...### $ # +#....## $ $### +##....## $ # +###... ## $ $ # +# ## # $ # +# ## # ### #### +# $ # #$ $ # +# $ @ $ $ # +# # $ $$ $ ### +# ###### ### +# ## #### +### + +########## +# #### +# ###### # ## +# # $ $ $ $ # +# #$ # +###$ $$# ### + # ## # $## + ##$# $ @# + # $ $ ### + # # $ # + # ## # # + ## ##### # + # # + #.......### + #.......# + ######### + + #### + ######### ## +## $ $ ##### +# ## ## ##...# +# #$$ $ $$#$##...# +# # @ # ...# +# $# ###$$ ...# +# $ $$ $ ##....# +###$ ####### + # ####### + #### + + ######### + #*.*#*.*# + #.*.*.*.# + #*.*.*.*# + #.*.*.*.# + #*.*.*.*# + ### ### + # # +###### ###### +# # +# $ $ $ $ $ # +## $ $ $ $ ## + #$ $ $ $ $# + # $@$ # + # ##### # + #### #### + + #### + # ## + # ## + # $$ ## + ###$ $ ## + #### $ # +### # ##### # +# # #....$ # +# # $ ....# # +# $ # #.*..# # +### #### ### # + #### @$ ##$## + ### $ # + # ## # + ######### + + ############ + ##.. # # + ##..* $ $ # + ##..*.# # # $## + #..*.# # # $ # +####...# # # # +# ## # # +# @$ $ ### # ## +# $ $ # # # +###$$ # # # # # + # $ # # ##### + # $# ##### # + #$ # # # # + # ### ## # + # # # ## + #### ###### + diff --git a/Sokoban/sokoban.c b/Sokoban/sokoban.c new file mode 100644 index 0000000..fe9685b --- /dev/null +++ b/Sokoban/sokoban.c @@ -0,0 +1,594 @@ +/* A fairly hacked-up version of sokoban, for CP/M. + * ported 95/7/28 by Russell Marks + * + * It compiles ok (with the usual warnings :-)) under Hitech C. + * All the source files were basically cat'ted together to make compliation + * less awkward. + * + * You'll need to patch the 'clear' and 'move' routines with your + * machine/terminal's clear screen and cursor move codes. (They're currently + * set for ZCN.) For very simple terminals, you may even be able to patch + * the binary directly and not bother recompiling. + * + * This version is for VT100 compatible terminals, patched by + * Anna Christina Nass + */ + +#include +#include +#include +#include + +#define refresh() +#define printw printf + + +void clear() +{ +printf("%c[2J%c[H",27,27); +} + + +void move(int y,int x) +{ +printf("%c[%d;%dH",27,y+1,x+1); +} + +short readscreen(); + + +/**/ +/* OBJECT: this typedef is used for internal and external representation */ +/* of objects */ +/**/ +typedef struct { + char obj_intern; /* internal representation of the object */ + char obj_display1; /* first display char for the object */ + char obj_display2; /* second display char for the object */ + short invers; /* if set to 1 the object will be shown invers */ +} OBJECT; + +/**/ +/* You can now alter the definitions below. +/* Attention: Do not alter `obj_intern'. This would cause an error */ +/* when reading the screenfiles */ +/**/ +static OBJECT + player = { '@', '*', '*', 0 }, + playerstore = { '+', '*', '*', 1 }, + store = { '.', '.', '.', 0 }, + packet = { '$', '[', ']', 0 }, + save = { '*', '<', '>', 1 }, + ground = { ' ', ' ', ' ', 0 }, + wall = { '#', '#', '#', 1 }; + +/************************************************************************* +********************** DO NOT CHANGE BELOW THIS LINE ********************* +*************************************************************************/ +#define MAXROW 20 +#define MAXCOL 40 + +typedef struct { + short x, y; +} POS; + +#define E_FOPENSCREEN 1 +#define E_PLAYPOS1 2 +#define E_ILLCHAR 3 +#define E_PLAYPOS2 4 +#define E_TOMUCHROWS 5 +#define E_TOMUCHCOLS 6 +#define E_ENDGAME 7 +#define E_NOUSER 9 +#define E_FOPENSAVE 10 +#define E_WRITESAVE 11 +#define E_STATSAVE 12 +#define E_READSAVE 13 +#define E_ALTERSAVE 14 +#define E_SAVED 15 +#define E_TOMUCHSE 16 +#define E_FOPENSCORE 17 +#define E_READSCORE 18 +#define E_WRITESCORE 19 +#define E_USAGE 20 +#define E_ILLPASSWORD 21 +#define E_LEVELTOOHIGH 22 +#define E_NOSUPER 23 +#define E_NOSAVEFILE 24 + +/* defining the types of move */ +#define MOVE 1 +#define PUSH 2 +#define SAVE 3 +#define UNSAVE 4 +#define STOREMOVE 5 +#define STOREPUSH 6 + +/* defines for control characters */ +#define CNTL_L '\014' +#define CNTL_K '\013' +#define CNTL_H '\010' +#define CNTL_J '\012' +#define CNTL_R '\022' +#define CNTL_U '\025' + +static POS tpos1, /* testpos1: 1 pos. over/under/left/right */ + tpos2, /* testpos2: 2 pos. " */ + lastppos, /* the last player position (for undo) */ + last_p1, last_p2; /* last test positions (for undo) */ +static char lppc, ltp1c, ltp2c; /* the char for the above pos. (for undo) */ +static char action, lastaction; + +/** For the temporary save **/ +static char tmp_map[MAXROW+1][MAXCOL+1]; +static short tmp_pushes, tmp_moves, tmp_savepack; +static POS tmp_ppos; + +short scoring = 1; +short level, packets, savepack, moves, pushes, rows, cols; +short scorelevel, scoremoves, scorepushes; +char map[MAXROW+1][MAXCOL+1]; +POS ppos; +char username[]="Player", *prgname; + + +short play() { + + short c; + short ret; + short undolock = 1; /* locked for undo */ + + showscreen(); + tmpsave(); + ret = 0; + while( ret == 0) { + c=getch(); + switch(c) { case '8': c = 'k'; break; + case '2': c = 'j'; break; + case '4': c = 'h'; break; + case '6': c = 'l'; break; + case '5': c = 'u'; break; + case 'E'&0x3f: c='k'; break; + case 'S'&0x3f: c='h'; break; + case 'D'&0x3f: c='l'; break; + case 'X'&0x3f: c='j'; break; + + default: break; }; + + switch(c) { + case 'q': /* quit the game */ + ret = E_ENDGAME; + break; + case CNTL_R: /* refresh the screen */ + clear(); + showscreen(); + break; + case 'c': /* temporary save */ + case 's': + tmpsave(); + break; + case CNTL_U: /* reset to temporary save */ + case 'r': + tmpreset(); + undolock = 1; + showscreen(); + break; + case 'U': /* undo this level */ + moves = pushes = 0; + if( (ret = readscreen()) == 0) { + showscreen(); + undolock = 1; + } + break; + case 'u': /* undo last move */ + if( ! undolock) { + undomove(); + undolock = 1; + } + break; + + case 'k': /* up */ + case 'K': /* run up */ + case CNTL_K: /* run up, stop before object */ + case 'j': /* down */ + case 'J': /* run down */ + case CNTL_J: /* run down, stop before object */ + case 'l': /* right */ + case 'L': /* run right */ + case CNTL_L: /* run right, stop before object */ + case 'h': /* left */ + case 'H': /* run left */ + case CNTL_H: /* run left, stop before object */ + do { + if( (action = testmove( c)) != 0) { + lastaction = action; + lastppos.x = ppos.x; lastppos.y = ppos.y; + lppc = map[ppos.x][ppos.y]; + last_p1.x = tpos1.x; last_p1.y = tpos1.y; + ltp1c = map[tpos1.x][tpos1.y]; + last_p2.x = tpos2.x; last_p2.y = tpos2.y; + ltp2c = map[tpos2.x][tpos2.y]; + domove( lastaction); + undolock = 0; + } + } while( (action != 0) && (! islower( c)) + && (packets != savepack)); + break; + default: helpmessage(); break; + } + if( (ret == 0) && (packets == savepack)) { + scorelevel = level; + scoremoves = moves; + scorepushes = pushes; + break; + } + } + return( ret); +} + +testmove( action) +register short action; +{ + register short ret; + register char tc; + register short stop_at_object; + + if( (stop_at_object = iscntrl( action))) action = action + 'A' - 1; + action = (isupper( action)) ? tolower( action) : action; + if( (action == 'k') || (action == 'j')) { + tpos1.x = (action == 'k') ? ppos.x-1 : ppos.x+1; + tpos2.x = (action == 'k') ? ppos.x-2 : ppos.x+2; + tpos1.y = tpos2.y = ppos.y; + } + else { + tpos1.y = (action == 'h') ? ppos.y-1 : ppos.y+1; + tpos2.y = (action == 'h') ? ppos.y-2 : ppos.y+2; + tpos1.x = tpos2.x = ppos.x; + } + tc = map[tpos1.x][tpos1.y]; + if( (tc == packet.obj_intern) || (tc == save.obj_intern)) { + if( ! stop_at_object) { + if( map[tpos2.x][tpos2.y] == ground.obj_intern) + ret = (tc == save.obj_intern) ? UNSAVE : PUSH; + else if( map[tpos2.x][tpos2.y] == store.obj_intern) + ret = (tc == save.obj_intern) ? STOREPUSH : SAVE; + else ret = 0; + } + else ret = 0; + } + else if( tc == ground.obj_intern) + ret = MOVE; + else if( tc == store.obj_intern) + ret = STOREMOVE; + else ret = 0; + return( ret); +} + +domove( moveaction) +register short moveaction; +{ + map[ppos.x][ppos.y] = (map[ppos.x][ppos.y] == player.obj_intern) + ? ground.obj_intern + : store.obj_intern; + switch( moveaction) { + case MOVE: map[tpos1.x][tpos1.y] = player.obj_intern; break; + case STOREMOVE: map[tpos1.x][tpos1.y] = playerstore.obj_intern; break; + case PUSH: map[tpos2.x][tpos2.y] = map[tpos1.x][tpos1.y]; + map[tpos1.x][tpos1.y] = player.obj_intern; + pushes++; break; + case UNSAVE: map[tpos2.x][tpos2.y] = packet.obj_intern; + map[tpos1.x][tpos1.y] = playerstore.obj_intern; + pushes++; savepack--; break; + case SAVE: map[tpos2.x][tpos2.y] = save.obj_intern; + map[tpos1.x][tpos1.y] = player.obj_intern; + savepack++; pushes++; break; + case STOREPUSH: map[tpos2.x][tpos2.y] = save.obj_intern; + map[tpos1.x][tpos1.y] = playerstore.obj_intern; + pushes++; break; + } + moves++; + dispmoves(); disppushes(); dispsave(); + mapchar( map[ppos.x][ppos.y], ppos.x, ppos.y); + mapchar( map[tpos1.x][tpos1.y], tpos1.x, tpos1.y); + mapchar( map[tpos2.x][tpos2.y], tpos2.x, tpos2.y); + move( MAXROW+1, 0); + refresh(); + ppos.x = tpos1.x; ppos.y = tpos1.y; +} + +undomove() { + + map[lastppos.x][lastppos.y] = lppc; + map[last_p1.x][last_p1.y] = ltp1c; + map[last_p2.x][last_p2.y] = ltp2c; + ppos.x = lastppos.x; ppos.y = lastppos.y; + switch( lastaction) { + case MOVE: moves--; break; + case STOREMOVE: moves--; break; + case PUSH: moves--; pushes--; break; + case UNSAVE: moves--; pushes--; savepack++; break; + case SAVE: moves--; pushes--; savepack--; break; + case STOREPUSH: moves--; pushes--; break; + } + dispmoves(); disppushes(); dispsave(); + mapchar( map[ppos.x][ppos.y], ppos.x, ppos.y); + mapchar( map[last_p1.x][last_p1.y], last_p1.x, last_p1.y); + mapchar( map[last_p2.x][last_p2.y], last_p2.x, last_p2.y); + move( MAXROW+1, 0); + refresh(); +} + +tmpsave() { + + register short i, j; + + for( i = 0; i < rows; i++) for( j = 0; j < cols; j++) + tmp_map[i][j] = map[i][j]; + tmp_pushes = pushes; + tmp_moves = moves; + tmp_savepack = savepack; + tmp_ppos.x = ppos.x; tmp_ppos.y = ppos.y; +} + +tmpreset() { + + register short i, j; + + for( i = 0; i < rows; i++) for( j = 0; j < cols; j++) + map[i][j] = tmp_map[i][j]; + pushes = tmp_pushes; + moves = tmp_moves; + savepack = tmp_savepack; + ppos.x = tmp_ppos.x; ppos.y = tmp_ppos.y; +} + +short readscreen() { + + FILE *screen; + short j, c, f, ret = 0; + + if( (screen = fopen( "soklevls.dat", "r")) == NULL) + ret = E_FOPENSCREEN; + else { + if(level>1) { + for(f=1;f MAXROW) + ret = E_TOMUCHROWS; + else { + if( j > cols) cols = j; + j = 0; + } + } + else if( (c == player.obj_intern) || (c == playerstore.obj_intern)) { + if( ppos.x != -1) + ret = E_PLAYPOS1; + else { + ppos.x = rows; ppos.y = j; + map[rows][j++] = c; + if( j > MAXCOL) ret = E_TOMUCHCOLS; + } + } + else if( (c == save.obj_intern) || (c == packet.obj_intern) || + (c == wall.obj_intern) || (c == store.obj_intern) || + (c == ground.obj_intern)) { + if( c == save.obj_intern) { savepack++; packets++; } + if( c == packet.obj_intern) packets++; + map[rows][j++] = c; + if( j > MAXCOL) ret = E_TOMUCHCOLS; + } + else ret = E_ILLCHAR; + } + fclose( screen); + if( (ret == 0) && (ppos.x == -1)) ret = E_PLAYPOS2; + } + return( ret); +} + +showscreen() { + + register short i, j; + + clear(); + for( i = 0; i < rows; i++) + for( j = 0; map[i][j] != '\0'; j++) + mapchar( map[i][j], i, j); + move( MAXROW, 0); + printw( "Level: Packets: Saved: Moves: Pushes:"); + displevel(); + disppackets(); + dispsave(); + dispmoves(); + disppushes(); + move( MAXROW+2,0); + refresh(); +} + +mapchar( c, i, j) +register char c; +register short i, j; +{ + OBJECT *obj, *get_obj_adr(); + register short offset_row = 0; /*(MAXROW - rows) / 2;*/ + register short offset_col = MAXCOL - cols; + + obj = get_obj_adr( c); + +/* if( obj->invers) standout();*/ + move( i + offset_row, 2*j + offset_col); + printw( "%c%c", obj ->obj_display1, obj ->obj_display2); +/* if( obj->invers) standend();*/ +} + +OBJECT *get_obj_adr( c) +register char c; +{ + register OBJECT *ret; + + if( c == player.obj_intern) ret = &player; + else if( c == playerstore.obj_intern) ret = &playerstore; + else if( c == store.obj_intern) ret = &store; + else if( c == save.obj_intern) ret = &save; + else if( c == packet.obj_intern) ret = &packet; + else if( c == wall.obj_intern) ret = &wall; + else if( c == ground.obj_intern) ret = &ground; + else ret = &ground; + + return( ret); +} + + +displevel() { + move( MAXROW, 7); printw( "%3d", level); +} + +disppackets() { + move( MAXROW, 21); printw( "%3d", packets); +} + +dispsave() { + move( MAXROW, 33); printw( "%3d", savepack); +} + +dispmoves() { + move( MAXROW, 45); printw( "%5d", moves); +} + +disppushes() { + move( MAXROW, 59); printw( "%5d", pushes); +} + +static short optrestore = 0, + optlevel = 1; + +helpmessage() { +#if 0 + move( MAXROW+2, 0); + printw( "Press ? for help."); + refresh(); + sleep( 1); + move( MAXROW+2, 0); deleteln(); + refresh(); +#endif +} + +showhelp() { +} + + +main( argc, argv) +short argc; +char *argv[]; +{ + short ret; + + scorelevel = 0; + moves = pushes = packets = savepack = 0; + if( (prgname = strrchr( argv[0], '/')) == NULL) + prgname = argv[0]; + else prgname++; + + { + if( (ret = checkcmdline( argc, argv)) == 0) { + level=optlevel; + } + } + ret = gameloop(); + errmess( ret); +} + +checkcmdline( argc, argv) +short argc; +char *argv[]; +{ + short ret = 0; + + if(argc==2) { + if( (optlevel = atoi(argv[1])) == 0) + ret = E_USAGE; + } + return( ret); +} + +gameloop() { + + short ret = 0; + +/* initscr(); cbreak(); noecho();*/ + if( ! optrestore) ret = readscreen(); + while( ret == 0) { + if( (ret = play()) == 0) { + level++; + moves = pushes = packets = savepack = 0; + ret = readscreen(); + } + } + clear(); refresh(); +/* nocbreak(); echo(); endwin();*/ + return( ret); +} + +char *message[] = { + "illegal error number", + "cannot open screen file", + "more than one player position in screen file", + "illegal char in screen file", + "no player position in screenfile", + "too much rows in screen file", + "too much columns in screenfile", + "quit the game", + NULL, /* errmessage deleted */ + "cannot get your username", + "cannot open savefile", + "error writing to savefile", + "cannot stat savefile", + "error reading savefile", + "cannot restore, your savefile has been altered", + "game saved", + "too much users in score table", + "cannot open score file", + "error reading scorefile", + "error writing scorefile", + "illegal command line syntax", + "illegal password", + "level number too big in command line", + "only superuser is allowed to make a new score table", + "cannot find file to restore" +}; + +errmess( ret) +register short ret; +{ + if( ret != E_ENDGAME) { + fprintf( stderr, "%s: ", prgname); + switch( ret) { + case E_FOPENSCREEN: case E_PLAYPOS1: case E_ILLCHAR: + case E_PLAYPOS2: case E_TOMUCHROWS: case E_TOMUCHCOLS: + case E_ENDGAME: case E_NOUSER: + case E_FOPENSAVE: case E_WRITESAVE: case E_STATSAVE: + case E_READSAVE: case E_ALTERSAVE: case E_SAVED: + case E_TOMUCHSE: case E_FOPENSCORE: case E_READSCORE: + case E_WRITESCORE: case E_USAGE: case E_ILLPASSWORD: + case E_LEVELTOOHIGH: case E_NOSUPER: case E_NOSAVEFILE: + fprintf( stderr, "%s\n", message[ret]); + break; + default: fprintf( stderr, "%s\n", message[0]); + break; + } + if( ret == E_USAGE) usage(); + } +} + +usage() { + fprintf( stderr, "Usage: %s [start_level]", prgname); +} + diff --git a/Sokoban/sokoban.com b/Sokoban/sokoban.com new file mode 100644 index 0000000..3ed8486 Binary files /dev/null and b/Sokoban/sokoban.com differ diff --git a/Sokoban/sokoban.hlp b/Sokoban/sokoban.hlp new file mode 100644 index 0000000..d71efa6 --- /dev/null +++ b/Sokoban/sokoban.hlp @@ -0,0 +1,39 @@ + + S O K O B A N + + The problem is to push packets to saving positions by moving around + and pushing only one packet at a time if possible. + + + Available Commands are: + + h: move/push left H: run/push left ^H: run left to object + l: move/push right L: run/push right ^L: run right to object + j: move/push down J: run/push down ^J: run down to object + k: move/push up K: run/push up ^K: run up to object + + u: undo last move/push U: undo all + + c: temporary save ^U: reset to temporary save + + ^R: Refresh screen + + q: quit s: save the game ?: this help screen ++= (DO NOT CHANGE OR DELETE THIS LINE) + + Characters on screen are: + + @@ player ++ player on saving position + .. saving position for packet $$ packets + ** saved packet ## wall + + + As you could see you can make a temporary save. This is useful if you think + that all the moves/pushes you have made are correct, but you don't know how + to go on. In this case you can temporary save (using the c command). If you + then get stucked you need not undo all (using U), you can reset to you + temporary save. + + If you have restored a saved game, a temporary save is automatically made + at the start. +== (DO NOT CHANGE THIS LINE)