summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
committercgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
commit77e3814f0c0e3dea4d0032e25666f77e6f83bfff (patch)
tree7eddfcbf3dd12089e71dc3fafb0a106c5c5766c7
parente81d63576b2e46ab90da7d75fa155ea57ee4d32e (diff)
downloadbsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.gz
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.zst
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.zip
initial import of 386bsd-0.1 sources
-rw-r--r--Makefile10
-rw-r--r--Makefile.inc9
-rw-r--r--arithmetic/Makefile7
-rw-r--r--arithmetic/arithmetic.6103
-rw-r--r--arithmetic/arithmetic.c375
-rw-r--r--atc/BUGS4
-rw-r--r--atc/Makefile18
-rw-r--r--atc/atc.6598
-rw-r--r--atc/def.h80
-rw-r--r--atc/extern.c75
-rw-r--r--atc/extern.h62
-rw-r--r--atc/games/ATC_scores5
-rw-r--r--atc/games/Game_List5
-rw-r--r--atc/games/Killer21
-rw-r--r--atc/games/crossover14
-rw-r--r--atc/games/default21
-rw-r--r--atc/games/easy15
-rw-r--r--atc/games/game_222
-rw-r--r--atc/grammar.y389
-rw-r--r--atc/graphics.c418
-rw-r--r--atc/include.h86
-rw-r--r--atc/input.c663
-rw-r--r--atc/lex.l69
-rw-r--r--atc/list.c115
-rw-r--r--atc/log.c247
-rw-r--r--atc/main.c326
-rw-r--r--atc/pathnames.h39
-rw-r--r--atc/struct.h111
-rw-r--r--atc/tunable.c56
-rw-r--r--atc/tunable.h48
-rw-r--r--atc/update.c410
-rw-r--r--backgammon/Makefile5
-rw-r--r--backgammon/backgammon/Makefile14
-rw-r--r--backgammon/backgammon/backgammon.6205
-rw-r--r--backgammon/backgammon/extra.c253
-rw-r--r--backgammon/backgammon/main.c591
-rw-r--r--backgammon/backgammon/move.c551
-rw-r--r--backgammon/backgammon/text.c132
-rw-r--r--backgammon/backgammon/version.c41
-rw-r--r--backgammon/common_source/allow.c109
-rw-r--r--backgammon/common_source/back.h127
-rw-r--r--backgammon/common_source/backgammon.c751
-rw-r--r--backgammon/common_source/board.c176
-rw-r--r--backgammon/common_source/check.c158
-rw-r--r--backgammon/common_source/fancy.c748
-rw-r--r--backgammon/common_source/init.c65
-rw-r--r--backgammon/common_source/odds.c113
-rw-r--r--backgammon/common_source/one.c169
-rw-r--r--backgammon/common_source/save.c180
-rw-r--r--backgammon/common_source/subs.c477
-rw-r--r--backgammon/common_source/table.c308
-rw-r--r--backgammon/teachgammon/Makefile15
-rw-r--r--backgammon/teachgammon/data.c315
-rw-r--r--backgammon/teachgammon/teach.c166
-rw-r--r--backgammon/teachgammon/ttext1.c184
-rw-r--r--backgammon/teachgammon/ttext2.c193
-rw-r--r--backgammon/teachgammon/tutor.c155
-rw-r--r--backgammon/teachgammon/tutor.h45
-rw-r--r--battlestar/Makefile12
-rw-r--r--battlestar/battlestar.6164
-rw-r--r--battlestar/battlestar.c91
-rw-r--r--battlestar/com1.c250
-rw-r--r--battlestar/com2.c296
-rw-r--r--battlestar/com3.c312
-rw-r--r--battlestar/com4.c379
-rw-r--r--battlestar/com5.c324
-rw-r--r--battlestar/com6.c213
-rw-r--r--battlestar/com7.c268
-rw-r--r--battlestar/cypher.c430
-rw-r--r--battlestar/dayfile.c1205
-rw-r--r--battlestar/dayobjs.c138
-rw-r--r--battlestar/externs.h297
-rw-r--r--battlestar/fly.c284
-rw-r--r--battlestar/getcom.c99
-rw-r--r--battlestar/globals.c219
-rw-r--r--battlestar/init.c130
-rw-r--r--battlestar/misc.c62
-rw-r--r--battlestar/nightfile.c1177
-rw-r--r--battlestar/nightobjs.c100
-rw-r--r--battlestar/parse.c101
-rw-r--r--battlestar/pathnames.h36
-rw-r--r--battlestar/room.c226
-rw-r--r--battlestar/save.c145
-rw-r--r--battlestar/words.c206
-rw-r--r--bcd/Makefile9
-rw-r--r--bcd/bcd.651
-rw-r--r--bcd/bcd.c199
-rw-r--r--caesar/Makefile9
-rw-r--r--caesar/caesar.671
-rw-r--r--caesar/caesar.c154
-rw-r--r--canfield/Makefile5
-rw-r--r--canfield/canfield/Makefile11
-rw-r--r--canfield/canfield/canfield.6118
-rw-r--r--canfield/canfield/canfield.c1705
-rw-r--r--canfield/canfield/pathnames.h37
-rw-r--r--canfield/cfscores/Makefile9
-rw-r--r--canfield/cfscores/cfscores.c148
-rw-r--r--cribbage/Makefile14
-rw-r--r--cribbage/cards.c161
-rw-r--r--cribbage/crib.c610
-rw-r--r--cribbage/cribbage.6129
-rw-r--r--cribbage/cribbage.h61
-rw-r--r--cribbage/cribbage.n226
-rw-r--r--cribbage/cribcur.h57
-rw-r--r--cribbage/deck.h85
-rw-r--r--cribbage/extern.c67
-rw-r--r--cribbage/instr.c81
-rw-r--r--cribbage/io.c615
-rw-r--r--cribbage/pathnames.h38
-rw-r--r--cribbage/score.c364
-rw-r--r--cribbage/support.c357
-rw-r--r--dm/Makefile12
-rw-r--r--dm/dm.066
-rw-r--r--dm/dm.8109
-rw-r--r--dm/dm.c327
-rw-r--r--dm/dm.conf.066
-rw-r--r--dm/dm.conf.599
-rw-r--r--dm/pathnames.h39
-rw-r--r--factor/Makefile10
-rw-r--r--factor/factor.6116
-rw-r--r--factor/factor.c346
-rw-r--r--fish/Makefile10
-rw-r--r--fish/fish.684
-rw-r--r--fish/fish.c429
-rw-r--r--fish/fish.instr29
-rw-r--r--fish/pathnames.h37
-rw-r--r--fortune/Makefile15
-rw-r--r--fortune/Notes175
-rw-r--r--fortune/README7
-rw-r--r--fortune/datfiles/Makefile20
-rw-r--r--fortune/datfiles/fortunes16304
-rw-r--r--fortune/datfiles/fortunes-o.fake.rot132
-rw-r--r--fortune/datfiles/fortunes-o.real2018
-rw-r--r--fortune/datfiles/fortunes-o.real.rot132018
-rw-r--r--fortune/datfiles/fortunes-o.sp.ok299
-rw-r--r--fortune/datfiles/fortunes.sp.ok1978
-rw-r--r--fortune/datfiles/startrek756
-rw-r--r--fortune/datfiles/startrek.sp.ok86
-rw-r--r--fortune/datfiles/zippy1333
-rw-r--r--fortune/datfiles/zippy.sp.ok210
-rw-r--r--fortune/fortune/Makefile10
-rw-r--r--fortune/fortune/fortune.6173
-rw-r--r--fortune/fortune/fortune.c1340
-rw-r--r--fortune/fortune/pathnames.h36
-rw-r--r--fortune/strfile/Makefile6
-rw-r--r--fortune/strfile/strfile.8147
-rw-r--r--fortune/strfile/strfile.c456
-rw-r--r--fortune/strfile/strfile.h54
-rw-r--r--fortune/tools/Do_spell10
-rw-r--r--fortune/tools/Do_troff10
-rw-r--r--fortune/tools/Troff.mac26
-rw-r--r--fortune/tools/Troff.sed13
-rw-r--r--fortune/unstr/Makefile7
-rw-r--r--fortune/unstr/unstr.c144
-rw-r--r--hack/COPYRIGHT6
-rw-r--r--hack/Makefile35
-rw-r--r--hack/Makequest196
-rw-r--r--hack/OWNER2
-rw-r--r--hack/Original_READ_ME61
-rw-r--r--hack/READ_ME92
-rw-r--r--hack/alloc.c47
-rw-r--r--hack/config.h139
-rw-r--r--hack/data232
-rw-r--r--hack/date.h2
-rw-r--r--hack/def.edog.h12
-rw-r--r--hack/def.eshk.h24
-rw-r--r--hack/def.flag.h42
-rw-r--r--hack/def.func_tab.h16
-rw-r--r--hack/def.gen.h15
-rw-r--r--hack/def.gold.h12
-rw-r--r--hack/def.mkroom.h26
-rw-r--r--hack/def.monst.h60
-rw-r--r--hack/def.obj.h48
-rw-r--r--hack/def.objclass.h60
-rw-r--r--hack/def.objects.h289
-rw-r--r--hack/def.permonst.h25
-rw-r--r--hack/def.rm.h52
-rw-r--r--hack/def.trap.h27
-rw-r--r--hack/def.wseg.h13
-rw-r--r--hack/hack.6155
-rw-r--r--hack/hack.Decl.c43
-rw-r--r--hack/hack.apply.c437
-rw-r--r--hack/hack.bones.c95
-rw-r--r--hack/hack.c798
-rw-r--r--hack/hack.cmd.c302
-rw-r--r--hack/hack.do.c488
-rw-r--r--hack/hack.do_name.c289
-rw-r--r--hack/hack.do_wear.c336
-rw-r--r--hack/hack.dog.c413
-rw-r--r--hack/hack.eat.c459
-rw-r--r--hack/hack.end.c642
-rw-r--r--hack/hack.engrave.c306
-rw-r--r--hack/hack.fight.c358
-rw-r--r--hack/hack.fix113
-rw-r--r--hack/hack.h160
-rw-r--r--hack/hack.invent.c863
-rw-r--r--hack/hack.ioctl.c53
-rw-r--r--hack/hack.lev.c285
-rw-r--r--hack/hack.main.c499
-rw-r--r--hack/hack.makemon.c198
-rw-r--r--hack/hack.mfndpos.h12
-rw-r--r--hack/hack.mhitu.c363
-rw-r--r--hack/hack.mklev.c741
-rw-r--r--hack/hack.mkmaze.c136
-rw-r--r--hack/hack.mkobj.c148
-rw-r--r--hack/hack.mkshop.c274
-rw-r--r--hack/hack.mon.c853
-rw-r--r--hack/hack.monst.c79
-rw-r--r--hack/hack.o_init.c160
-rw-r--r--hack/hack.objnam.c547
-rw-r--r--hack/hack.onames.h227
-rw-r--r--hack/hack.options.c203
-rw-r--r--hack/hack.pager.c406
-rw-r--r--hack/hack.potion.c386
-rw-r--r--hack/hack.pri.c660
-rw-r--r--hack/hack.read.c539
-rw-r--r--hack/hack.rip.c81
-rw-r--r--hack/hack.rumors.c63
-rw-r--r--hack/hack.save.c238
-rw-r--r--hack/hack.search.c133
-rw-r--r--hack/hack.sh14
-rw-r--r--hack/hack.shk.c987
-rw-r--r--hack/hack.shknam.c140
-rw-r--r--hack/hack.steal.c203
-rw-r--r--hack/hack.termcap.c276
-rw-r--r--hack/hack.timeout.c62
-rw-r--r--hack/hack.topl.c192
-rw-r--r--hack/hack.track.c38
-rw-r--r--hack/hack.trap.c447
-rw-r--r--hack/hack.tty.c338
-rw-r--r--hack/hack.u_init.c357
-rw-r--r--hack/hack.unix.c430
-rw-r--r--hack/hack.vault.c259
-rw-r--r--hack/hack.version.c16
-rw-r--r--hack/hack.wield.c99
-rw-r--r--hack/hack.wizard.c189
-rw-r--r--hack/hack.worm.c183
-rw-r--r--hack/hack.worn.c65
-rw-r--r--hack/hack.zap.c642
-rw-r--r--hack/help132
-rw-r--r--hack/hh55
-rw-r--r--hack/makedefs.c224
-rw-r--r--hack/pathnames.h39
-rw-r--r--hack/rnd.c30
-rw-r--r--hack/rumors505
-rw-r--r--hangman/Makefile13
-rw-r--r--hangman/endgame.c73
-rw-r--r--hangman/extern.c74
-rw-r--r--hangman/getguess.c107
-rw-r--r--hangman/getword.c92
-rw-r--r--hangman/hangman.650
-rw-r--r--hangman/hangman.h81
-rw-r--r--hangman/main.c75
-rw-r--r--hangman/pathnames.h36
-rw-r--r--hangman/playgame.c60
-rw-r--r--hangman/prdata.c58
-rw-r--r--hangman/prman.c55
-rw-r--r--hangman/prword.c49
-rw-r--r--hangman/setup.c72
-rw-r--r--larn/COPYRIGHT6
-rw-r--r--larn/Fixed.Bugs216
-rw-r--r--larn/Makefile69
-rw-r--r--larn/OWNER3
-rw-r--r--larn/README148
-rw-r--r--larn/bill.c132
-rw-r--r--larn/config.c47
-rw-r--r--larn/create.c463
-rw-r--r--larn/data.c648
-rw-r--r--larn/datfiles/larn.help140
-rw-r--r--larn/datfiles/larnmaze288
-rw-r--r--larn/datfiles/larnopts12
-rw-r--r--larn/datfiles/lfortune34
-rw-r--r--larn/diag.c314
-rw-r--r--larn/display.c434
-rw-r--r--larn/fortune.c63
-rw-r--r--larn/global.c621
-rw-r--r--larn/header.h434
-rw-r--r--larn/help.c87
-rw-r--r--larn/io.c915
-rw-r--r--larn/larn.6158
-rw-r--r--larn/main.c878
-rw-r--r--larn/monster.c1387
-rw-r--r--larn/moreobj.c372
-rw-r--r--larn/movem.c312
-rw-r--r--larn/nap.c116
-rw-r--r--larn/object.c807
-rw-r--r--larn/pathnames.h41
-rw-r--r--larn/regen.c92
-rw-r--r--larn/savelev.c47
-rw-r--r--larn/scores.c652
-rw-r--r--larn/signal.c148
-rw-r--r--larn/store.c691
-rw-r--r--larn/tok.c218
-rw-r--r--mille/Makefile12
-rw-r--r--mille/comp.c486
-rw-r--r--mille/end.c148
-rw-r--r--mille/extern.c172
-rw-r--r--mille/init.c251
-rw-r--r--mille/mille.6378
-rw-r--r--mille/mille.c170
-rw-r--r--mille/mille.h228
-rw-r--r--mille/misc.c261
-rw-r--r--mille/move.c562
-rw-r--r--mille/print.c169
-rw-r--r--mille/roll.c57
-rw-r--r--mille/save.c172
-rw-r--r--mille/table.c64
-rw-r--r--mille/types.c75
-rw-r--r--mille/unctrl.h42
-rw-r--r--mille/varpush.c92
-rw-r--r--monop/Makefile24
-rw-r--r--monop/brd.dat78
-rw-r--r--monop/cards.c208
-rw-r--r--monop/cards.inp122
-rw-r--r--monop/deck.h48
-rw-r--r--monop/execute.c262
-rw-r--r--monop/getinp.c116
-rw-r--r--monop/houses.c269
-rw-r--r--monop/initdeck.c184
-rw-r--r--monop/jail.c127
-rw-r--r--monop/misc.c359
-rw-r--r--monop/mon.dat44
-rw-r--r--monop/monop.6191
-rw-r--r--monop/monop.c162
-rw-r--r--monop/monop.def124
-rw-r--r--monop/monop.ext57
-rw-r--r--monop/monop.h137
-rw-r--r--monop/morg.c210
-rw-r--r--monop/pathnames.h36
-rw-r--r--monop/print.c192
-rw-r--r--monop/prop.c211
-rw-r--r--monop/prop.dat58
-rw-r--r--monop/rent.c92
-rw-r--r--monop/roll.c74
-rw-r--r--monop/spec.c86
-rw-r--r--monop/trade.c306
-rw-r--r--morse/Makefile8
-rw-r--r--morse/morse.c145
-rw-r--r--number/Makefile6
-rw-r--r--number/number.652
-rw-r--r--number/number.c243
-rw-r--r--pom/Makefile8
-rw-r--r--pom/pom.645
-rw-r--r--pom/pom.c178
-rw-r--r--ppt/Makefile8
-rw-r--r--ppt/ppt.c83
-rw-r--r--primes/Makefile9
-rw-r--r--primes/pattern.c440
-rw-r--r--primes/pr_tbl.c546
-rw-r--r--primes/primes.c410
-rw-r--r--primes/primes.h56
-rw-r--r--rain/Makefile8
-rw-r--r--rain/rain.654
-rw-r--r--rain/rain.c245
-rw-r--r--robots/Makefile16
-rw-r--r--robots/extern.c75
-rw-r--r--robots/flush_in.c51
-rw-r--r--robots/init_field.c117
-rw-r--r--robots/main.c196
-rw-r--r--robots/make_level.c89
-rw-r--r--robots/move.c299
-rw-r--r--robots/move_robs.c152
-rw-r--r--robots/pathnames.h36
-rw-r--r--robots/play_level.c115
-rw-r--r--robots/query.c60
-rw-r--r--robots/rnd_pos.c68
-rw-r--r--robots/robots.6141
-rw-r--r--robots/robots.h110
-rw-r--r--robots/score.c184
-rw-r--r--rogue/CHANGES53
-rw-r--r--rogue/Makefile13
-rw-r--r--rogue/curses.c694
-rw-r--r--rogue/hit.c456
-rw-r--r--rogue/init.c338
-rw-r--r--rogue/inventory.c774
-rw-r--r--rogue/level.c881
-rw-r--r--rogue/machdep.c681
-rw-r--r--rogue/main.c85
-rw-r--r--rogue/message.c379
-rw-r--r--rogue/monster.c867
-rw-r--r--rogue/move.c647
-rw-r--r--rogue/object.c783
-rw-r--r--rogue/pack.c570
-rw-r--r--rogue/pathnames.h38
-rw-r--r--rogue/play.c298
-rw-r--r--rogue/random.c140
-rw-r--r--rogue/ring.c336
-rw-r--r--rogue/rogue.6113
-rw-r--r--rogue/rogue.h490
-rw-r--r--rogue/room.c649
-rw-r--r--rogue/save.c426
-rw-r--r--rogue/score.c581
-rw-r--r--rogue/spec_hit.c534
-rw-r--r--rogue/throw.c322
-rw-r--r--rogue/trap.c283
-rw-r--r--rogue/use.c618
-rw-r--r--rogue/zap.c405
-rw-r--r--sail/:file10
-rw-r--r--sail/:scene3
-rw-r--r--sail/:ship4
-rw-r--r--sail/:specs3
-rw-r--r--sail/Makefile12
-rw-r--r--sail/assorted.c274
-rw-r--r--sail/dr_1.c461
-rw-r--r--sail/dr_2.c275
-rw-r--r--sail/dr_3.c346
-rw-r--r--sail/dr_4.c65
-rw-r--r--sail/dr_5.c93
-rw-r--r--sail/dr_main.c108
-rw-r--r--sail/driver.h38
-rw-r--r--sail/externs.h310
-rw-r--r--sail/game.c87
-rw-r--r--sail/globals.c507
-rw-r--r--sail/lo_main.c91
-rw-r--r--sail/machdep.h46
-rw-r--r--sail/main.c108
-rw-r--r--sail/misc.c233
-rw-r--r--sail/parties.c76
-rw-r--r--sail/pathnames.h36
-rw-r--r--sail/pl_1.c135
-rw-r--r--sail/pl_2.c154
-rw-r--r--sail/pl_3.c272
-rw-r--r--sail/pl_4.c129
-rw-r--r--sail/pl_5.c254
-rw-r--r--sail/pl_6.c196
-rw-r--r--sail/pl_7.c481
-rw-r--r--sail/pl_main.c244
-rw-r--r--sail/player.h122
-rw-r--r--sail/sail.6896
-rw-r--r--sail/sync.c421
-rw-r--r--sail/version.c38
-rw-r--r--snake/Makefile5
-rw-r--r--snake/snake/Makefile11
-rw-r--r--snake/snake/move.c660
-rw-r--r--snake/snake/pathnames.h37
-rw-r--r--snake/snake/snake.6113
-rw-r--r--snake/snake/snake.c890
-rw-r--r--snake/snake/snake.h79
-rw-r--r--snake/snscore/Makefile9
-rw-r--r--snake/snscore/snscore.c117
-rw-r--r--trek/DOC/read_me.nr251
-rw-r--r--trek/DOC/things10
-rw-r--r--trek/DOC/trekmanual.nr895
-rw-r--r--trek/Makefile17
-rw-r--r--trek/abandon.c157
-rw-r--r--trek/attack.c188
-rw-r--r--trek/autover.c77
-rw-r--r--trek/board.x59
-rw-r--r--trek/capture.c128
-rw-r--r--trek/cgetc.c44
-rw-r--r--trek/check_out.c70
-rw-r--r--trek/checkcond.c104
-rw-r--r--trek/compkl.c112
-rw-r--r--trek/computer.c343
-rw-r--r--trek/damage.c91
-rw-r--r--trek/damaged.c67
-rw-r--r--trek/dcrept.c99
-rw-r--r--trek/destruct.c110
-rw-r--r--trek/dock.c144
-rw-r--r--trek/dumpgame.c161
-rw-r--r--trek/dumpme.c88
-rw-r--r--trek/dumpssradio.c85
-rw-r--r--trek/events.c463
-rw-r--r--trek/externs.c98
-rw-r--r--trek/getcodi.c68
-rw-r--r--trek/getpar.c297
-rw-r--r--trek/getpar.h45
-rw-r--r--trek/help.c157
-rw-r--r--trek/impulse.c80
-rw-r--r--trek/initquad.c152
-rw-r--r--trek/kill.c227
-rw-r--r--trek/klmove.c182
-rw-r--r--trek/lose.c85
-rw-r--r--trek/lrscan.c107
-rw-r--r--trek/main.c235
-rw-r--r--trek/move.c230
-rw-r--r--trek/nova.c141
-rw-r--r--trek/out.c56
-rw-r--r--trek/phaser.c369
-rw-r--r--trek/play.c110
-rw-r--r--trek/ram.c101
-rw-r--r--trek/ranf.c57
-rw-r--r--trek/rest.c80
-rw-r--r--trek/schedule.c173
-rw-r--r--trek/score.c104
-rw-r--r--trek/setup.c303
-rw-r--r--trek/setwarp.c64
-rw-r--r--trek/shield.c143
-rw-r--r--trek/snova.c158
-rw-r--r--trek/srscan.c190
-rw-r--r--trek/systemname.c67
-rw-r--r--trek/torped.c247
-rw-r--r--trek/trek.690
-rw-r--r--trek/trek.h380
-rw-r--r--trek/utility.c150
-rw-r--r--trek/visual.c101
-rw-r--r--trek/warp.c182
-rw-r--r--trek/win.c89
-rw-r--r--wargames/Makefile10
-rw-r--r--wargames/wargames.sh45
-rw-r--r--worm/Makefile9
-rw-r--r--worm/worm.666
-rw-r--r--worm/worm.c301
-rw-r--r--worms/Makefile8
-rw-r--r--worms/worms.671
-rw-r--r--worms/worms.c444
-rw-r--r--wump/Makefile11
-rw-r--r--wump/pathnames.h37
-rw-r--r--wump/wump.6110
-rw-r--r--wump/wump.c778
-rw-r--r--wump/wump.info41
511 files changed, 128822 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..4de91bbf
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 5.15.1.2 (Berkeley) 5/8/91
+
+Missing: adventure boggle ching dungeon hunt phantasia quiz warp
+
+SUBDIR= arithmetic atc backgammon battlestar bcd caesar canfield \
+ chess cribbage dm factor fish fortune hack hangman larn \
+ mille monop morse number pom ppt primes rain robots rogue \
+ sail snake trek wargames worm worms wump
+
+.include <bsd.subdir.mk>
diff --git a/Makefile.inc b/Makefile.inc
new file mode 100644
index 00000000..b66e2f74
--- /dev/null
+++ b/Makefile.inc
@@ -0,0 +1,9 @@
+# @(#)Makefile.inc 5.1 (Berkeley) 5/11/90
+
+BINOWN?= games
+.if defined(HIDEGAME)
+BINDIR?= /usr/games/hide
+BINMODE?= 4700
+.else
+BINDIR?= /usr/games
+.endif
diff --git a/arithmetic/Makefile b/arithmetic/Makefile
new file mode 100644
index 00000000..2ff01223
--- /dev/null
+++ b/arithmetic/Makefile
@@ -0,0 +1,7 @@
+# @(#)Makefile 5.2 (Berkeley) 5/11/90
+
+PROG= arithmetic
+MAN6= arithmetic.0
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
diff --git a/arithmetic/arithmetic.6 b/arithmetic/arithmetic.6
new file mode 100644
index 00000000..1ac71da6
--- /dev/null
+++ b/arithmetic/arithmetic.6
@@ -0,0 +1,103 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Eamonn McManus of Trinity College Dublin.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)arithmetic.6 6.6 (Berkeley) 6/23/90
+.\"
+.TH ARITHMETIC 6 "June 23, 1990"
+.UC 4
+.SH NAME
+arithmetic \- quiz on simple arithmetic
+.SH SYNOPSIS
+.B arithmetic
+.B [
+\-o +\-x/
+.B ]
+.B [
+\-r range
+.B ]
+.SH DESCRIPTION
+.I Arithmetic
+asks you to solve problems in simple arithmetic.
+Each question must be answered correctly before going on to the next.
+After every 20 problems, it prints the score so far and the time taken.
+You can quit at any time by typing the interrupt or end-of-file character.
+.PP
+The options are as follows:
+.TP
+\-o
+By default,
+.I arithmetic
+asks questions on addition of numbers from 0 to 10, and corresponding
+subtraction.
+By supplying one or more of the characters
+.BR +\-x/ ,
+you can ask for problems in addition, subtraction, multiplication, and
+division, respectively.
+If you give one of these characters more than once, that kind of problem
+will be asked correspondingly more often.
+.TP
+\-r
+If a
+.I range
+is supplied,
+.I arithmetic
+selects the numbers in its problems in the following way.
+For addition and multiplication, the numbers to be added or multiplied
+are between 0 and
+.IR range ,
+inclusive.
+For subtraction and division, both the required result and the number to
+divide by or subtract will be between 0 and
+.IR range .
+(Of course,
+.I arithmetic
+will not ask you to divide by 0.) The default
+.I range
+is 10.
+.PP
+When you get a problem wrong,
+.I arithmetic
+will remember the numbers involved, and will tend to select those numbers
+more often than others, in problems of the same sort.
+Eventually it will forgive and forget.
+.PP
+.I Arithmetic
+cannot be persuaded to tell you the right answer.
+You must work it out for yourself.
+.SH DIAGNOSTICS
+``What?'' if you get a question wrong.
+``Right!'' if you get it right.
+``Please type a number.'' if arithmetic doesn't understand what you typed.
+.SH "SEE ALSO"
+bc(1), dc(1)
diff --git a/arithmetic/arithmetic.c b/arithmetic/arithmetic.c
new file mode 100644
index 00000000..4fd8bf96
--- /dev/null
+++ b/arithmetic/arithmetic.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Eamonn McManus of Trinity College Dublin.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)arithmetic.c 5.5 (Berkeley) 2/27/91";
+#endif /* not lint */
+
+/*
+ * By Eamonn McManus, Trinity College Dublin <emcmanus@cs.tcd.ie>.
+ *
+ * The operation of this program mimics that of the standard Unix game
+ * `arithmetic'. I've made it as close as I could manage without examining
+ * the source code. The principal differences are:
+ *
+ * The method of biasing towards numbers that had wrong answers in the past
+ * is different; original `arithmetic' seems to retain the bias forever,
+ * whereas this program lets the bias gradually decay as it is used.
+ *
+ * Original `arithmetic' delays for some period (3 seconds?) after printing
+ * the score. I saw no reason for this delay, so I scrapped it.
+ *
+ * There is no longer a limitation on the maximum range that can be supplied
+ * to the program. The original program required it to be less than 100.
+ * Anomalous results may occur with this program if ranges big enough to
+ * allow overflow are given.
+ *
+ * I have obviously not attempted to duplicate bugs in the original. It
+ * would go into an infinite loop if invoked as `arithmetic / 0'. It also
+ * did not recognise an EOF in its input, and would continue trying to read
+ * after it. It did not check that the input was a valid number, treating any
+ * garbage as 0. Finally, it did not flush stdout after printing its prompt,
+ * so in the unlikely event that stdout was not a terminal, it would not work
+ * properly.
+ */
+
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+char keylist[] = "+-x/";
+char defaultkeys[] = "+-";
+char *keys = defaultkeys;
+int nkeys = sizeof(defaultkeys) - 1;
+int rangemax = 10;
+int nright, nwrong;
+time_t qtime;
+#define NQUESTS 20
+
+/*
+ * Select keys from +-x/ to be asked addition, subtraction, multiplication,
+ * and division problems. More than one key may be given. The default is
+ * +-. Specify a range to confine the operands to 0 - range. Default upper
+ * bound is 10. After every NQUESTS questions, statistics on the performance
+ * so far are printed.
+ */
+void
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern char *optarg;
+ extern int optind;
+ int ch, cnt;
+ time_t time();
+ void intr();
+
+ while ((ch = getopt(argc, argv, "r:o:")) != EOF)
+ switch(ch) {
+ case 'o': {
+ register char *p;
+
+ for (p = keys = optarg; *p; ++p)
+ if (!index(keylist, *p)) {
+ (void)fprintf(stderr,
+ "arithmetic: unknown key.\n");
+ exit(1);
+ }
+ nkeys = p - optarg;
+ break;
+ }
+ case 'r':
+ if ((rangemax = atoi(optarg)) <= 0) {
+ (void)fprintf(stderr,
+ "arithmetic: invalid range.\n");
+ exit(1);
+ }
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ if (argc -= optind)
+ usage();
+
+ /* Seed the random-number generator. */
+ srandom((int)time((time_t *)NULL));
+
+ (void)signal(SIGINT, intr);
+
+ /* Now ask the questions. */
+ for (;;) {
+ for (cnt = NQUESTS; cnt--;)
+ if (problem() == EOF)
+ exit(0);
+ showstats();
+ }
+ /* NOTREACHED */
+}
+
+/* Handle interrupt character. Print score and exit. */
+void
+intr()
+{
+ showstats();
+ exit(0);
+}
+
+/* Print score. Original `arithmetic' had a delay after printing it. */
+showstats()
+{
+ if (nright + nwrong > 0) {
+ (void)printf("\n\nRights %d; Wrongs %d; Score %d%%",
+ nright, nwrong, (int)(100L * nright / (nright + nwrong)));
+ if (nright > 0)
+ (void)printf("\nTotal time %ld seconds; %.1f seconds per problem\n\n",
+ (long)qtime, (float)qtime / nright);
+ }
+ (void)printf("\n");
+}
+
+/*
+ * Pick a problem and ask it. Keeps asking the same problem until supplied
+ * with the correct answer, or until EOF or interrupt is typed. Problems are
+ * selected such that the right operand and either the left operand (for +, x)
+ * or the correct result (for -, /) are in the range 0 to rangemax. Each wrong
+ * answer causes the numbers in the problem to be penalised, so that they are
+ * more likely to appear in subsequent problems.
+ */
+problem()
+{
+ register char *p;
+ time_t start, finish;
+ int left, op, right, result;
+ char line[80];
+
+ op = keys[random() % nkeys];
+ if (op != '/')
+ right = getrandom(rangemax + 1, op, 1);
+retry:
+ /* Get the operands. */
+ switch (op) {
+ case '+':
+ left = getrandom(rangemax + 1, op, 0);
+ result = left + right;
+ break;
+ case '-':
+ result = getrandom(rangemax + 1, op, 0);
+ left = right + result;
+ break;
+ case 'x':
+ left = getrandom(rangemax + 1, op, 0);
+ result = left * right;
+ break;
+ case '/':
+ right = getrandom(rangemax, op, 1) + 1;
+ result = getrandom(rangemax + 1, op, 0);
+ left = right * result + random() % right;
+ break;
+ }
+
+ /*
+ * A very big maxrange could cause negative values to pop
+ * up, owing to overflow.
+ */
+ if (result < 0 || left < 0)
+ goto retry;
+
+ (void)printf("%d %c %d = ", left, op, right);
+ (void)fflush(stdout);
+ (void)time(&start);
+
+ /*
+ * Keep looping until the correct answer is given, or until EOF or
+ * interrupt is typed.
+ */
+ for (;;) {
+ if (!fgets(line, sizeof(line), stdin)) {
+ (void)printf("\n");
+ return(EOF);
+ }
+ for (p = line; *p && isspace(*p); ++p);
+ if (!isdigit(*p)) {
+ (void)printf("Please type a number.\n");
+ continue;
+ }
+ if (atoi(p) == result) {
+ (void)printf("Right!\n");
+ ++nright;
+ break;
+ }
+ /* Wrong answer; penalise and ask again. */
+ (void)printf("What?\n");
+ ++nwrong;
+ penalise(right, op, 1);
+ if (op == 'x' || op == '+')
+ penalise(left, op, 0);
+ else
+ penalise(result, op, 0);
+ }
+
+ /*
+ * Accumulate the time taken. Obviously rounding errors happen here;
+ * however they should cancel out, because some of the time you are
+ * charged for a partially elapsed second at the start, and some of
+ * the time you are not charged for a partially elapsed second at the
+ * end.
+ */
+ (void)time(&finish);
+ qtime += finish - start;
+ return(0);
+}
+
+/*
+ * Here is the code for accumulating penalties against the numbers for which
+ * a wrong answer was given. The right operand and either the left operand
+ * (for +, x) or the result (for -, /) are stored in a list for the particular
+ * operation, and each becomes more likely to appear again in that operation.
+ * Initially, each number is charged a penalty of WRONGPENALTY, giving it that
+ * many extra chances of appearing. Each time it is selected because of this,
+ * its penalty is decreased by one; it is removed when it reaches 0.
+ *
+ * The penalty[] array gives the sum of all penalties in the list for
+ * each operation and each operand. The penlist[] array has the lists of
+ * penalties themselves.
+ */
+
+int penalty[sizeof(keylist) - 1][2];
+struct penalty {
+ int value, penalty; /* Penalised value and its penalty. */
+ struct penalty *next;
+} *penlist[sizeof(keylist) - 1][2];
+
+#define WRONGPENALTY 5 /* Perhaps this should depend on maxrange. */
+
+/*
+ * Add a penalty for the number `value' to the list for operation `op',
+ * operand number `operand' (0 or 1). If we run out of memory, we just
+ * forget about the penalty (how likely is this, anyway?).
+ */
+penalise(value, op, operand)
+ int value, op, operand;
+{
+ struct penalty *p;
+ char *malloc();
+
+ op = opnum(op);
+ if ((p = (struct penalty *)malloc((u_int)sizeof(*p))) == NULL)
+ return;
+ p->next = penlist[op][operand];
+ penlist[op][operand] = p;
+ penalty[op][operand] += p->penalty = WRONGPENALTY;
+ p->value = value;
+}
+
+/*
+ * Select a random value from 0 to maxval - 1 for operand `operand' (0 or 1)
+ * of operation `op'. The random number we generate is either used directly
+ * as a value, or represents a position in the penalty list. If the latter,
+ * we find the corresponding value and return that, decreasing its penalty.
+ */
+getrandom(maxval, op, operand)
+ int maxval, op, operand;
+{
+ int value;
+ register struct penalty **pp, *p;
+
+ op = opnum(op);
+ value = random() % (maxval + penalty[op][operand]);
+
+ /*
+ * 0 to maxval - 1 is a number to be used directly; bigger values
+ * are positions to be located in the penalty list.
+ */
+ if (value < maxval)
+ return(value);
+ value -= maxval;
+
+ /*
+ * Find the penalty at position `value'; decrement its penalty and
+ * delete it if it reaches 0; return the corresponding value.
+ */
+ for (pp = &penlist[op][operand]; (p = *pp) != NULL; pp = &p->next) {
+ if (p->penalty > value) {
+ value = p->value;
+ penalty[op][operand]--;
+ if (--(p->penalty) <= 0) {
+ p = p->next;
+ (void)free((char *)*pp);
+ *pp = p;
+ }
+ return(value);
+ }
+ value -= p->penalty;
+ }
+ /*
+ * We can only get here if the value from the penalty[] array doesn't
+ * correspond to the actual sum of penalties in the list. Provide an
+ * obscure message.
+ */
+ (void)fprintf(stderr, "arithmetic: bug: inconsistent penalties\n");
+ exit(1);
+ /* NOTREACHED */
+}
+
+/* Return an index for the character op, which is one of [+-x/]. */
+opnum(op)
+ int op;
+{
+ char *p;
+
+ if (op == 0 || (p = index(keylist, op)) == NULL) {
+ (void)fprintf(stderr,
+ "arithmetic: bug: op %c not in keylist %s\n", op, keylist);
+ exit(1);
+ }
+ return(p - keylist);
+}
+
+/* Print usage message and quit. */
+usage()
+{
+ (void)fprintf(stderr, "usage: arithmetic [-o +-x/] [-r range]\n");
+ exit(1);
+}
diff --git a/atc/BUGS b/atc/BUGS
new file mode 100644
index 00000000..7d2af294
--- /dev/null
+++ b/atc/BUGS
@@ -0,0 +1,4 @@
+log restarts if interrupted
+Still refreshes after exit
+Should ^Z be disabled?
+does not exit after hup
diff --git a/atc/Makefile b/atc/Makefile
new file mode 100644
index 00000000..df37f741
--- /dev/null
+++ b/atc/Makefile
@@ -0,0 +1,18 @@
+# @(#)Makefile 5.7 (Berkeley) 6/27/90
+
+PROG= atc
+CFLAGS+=-DBSD -I${.CURDIR} -I.
+SRCS= extern.c grammar.c graphics.c input.c lex.c list.c log.c \
+ main.c tunable.c update.c
+MAN6= atc.0
+DPADD= ${usr/lib/libl.a ${LIBM} ${LIBTERM} ${LIBCURSES} ${LIBCOMPAT}
+LDADD= -ll -lm -lcurses -ltermcap -lcompat
+GAMES= ATC_scores Game_List Killer crossover default easy game_2
+CLEANFILES=grammar.c y.tab.h lex.c
+HIDEGAME=hidegame
+
+beforeinstall:
+ (cd ${.CURDIR}/games; install -c -o ${BINOWN} -g ${BINGRP} -m 400 \
+ ${GAMES} ${DESTDIR}/usr/share/games/atc)
+
+.include <bsd.prog.mk>
diff --git a/atc/atc.6 b/atc/atc.6
new file mode 100644
index 00000000..09a14f26
--- /dev/null
+++ b/atc/atc.6
@@ -0,0 +1,598 @@
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Ed James.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atc.6 5.4 (Berkeley) 6/23/90
+.\"
+. \" XP - exdented paragraph
+.de XP
+.RT
+.if \\n(1T .sp \\n(PDu
+.ne 1.1
+.if !\\n(IP .nr IP +1
+.in +\\n(I\\n(IRu
+.ti -\\n(I\\n(IRu
+..
+.\" Copyright (c) 1986 Ed James. All rights reserved.
+.\"
+.TH ATC 6 "June 23, 1990"
+.UC
+.SH NAME
+atc \- Air Traffic Controller Game
+.SH SYNOPSIS
+.B atc
+-[u?lstp] [-[gf] game_name] [-r random seed]
+.SH DESCRIPTION
+.LP
+.I Atc
+lets you try your hand at the nerve wracking duties of the air traffic
+controller without endangering the lives of millions of
+travelers each year.
+Your responsibilities require you to direct the flight of jets
+and prop planes into and out of the flight arena and airports.
+The speed (update time) and frequency of the planes depend on the
+difficulty of the chosen arena.
+.SH OPTIONS
+.LP
+.TP 8
+.B \-u
+Print the usage line and exit.
+.TP
+.B \-?
+Same as
+.B \-u.
+.TP
+.B \-l
+Print a list of available games and exit.
+The first game name printed is the default game.
+.TP
+.B \-s
+Print the score list (formerly the Top Ten list).
+.TP
+.B \-t
+Same as
+.B \-s.
+.TP
+.B \-p
+Print the path to the special directory where
+.I atc
+expects to find its private files. This is used during the
+installation of the program.
+.TP
+.B "\-g game"
+Play the named game. If the game listed is not one of the
+ones printed from the
+.B \-l
+option, the default game is played.
+.TP
+.B "\-f game"
+Same as
+.B \-g.
+.TP
+.B "\-r seed"
+Set the random seed. The purpose of this flag is questionable.
+.SH GOALS
+.LP
+Your goal in
+.I atc
+is to keep the game going as long as possible.
+There is no winning state, except to beat the times of other players.
+You will need to: launch planes at airports (by instructing them to
+increase their altitude); land planes at airports (by instructing them to
+go to altitude zero when exactly over the airport); and maneuver planes
+out of exit points.
+.LP
+Several things will cause the end of the game.
+Each plane has a destination (see information area), and
+sending a plane to the wrong destination is an error.
+Planes can run out of fuel, or can collide. Collision is defined as
+adjacency in any of the three dimensions. A plane leaving the arena
+in any other way than through its destination exit is an error as well.
+.LP
+Scores are sorted in order of the number of planes safe. The other
+statistics are provided merely for fun. There is no penalty for
+taking longer than another player (except in the case of ties).
+.LP
+Suspending a game is not permitted. If you get a talk message, tough.
+When was the last time an Air Traffic Controller got called away to
+the phone?
+.SH "THE DISPLAY"
+.LP
+Depending on the terminal you run
+.I atc
+on, the screen will be divided into 4 areas.
+It should be stressed that the terminal driver portion of the
+game was designed to be reconfigurable, so the display format can vary
+depending the version you are playing. The descriptions here are based
+on the ascii version
+of the game. The game rules and input format, however,
+should remain consistent.
+Control-L redraws the screen, should it become muddled.
+.SS RADAR
+.IP
+The first screen area is the radar display, showing the relative locations
+of the planes, airports, standard entry/exit points, radar
+beacons, and "lines" which simply serve to aid you in guiding
+the planes.
+.IP
+Planes are shown as a single letter with an altitude. If
+the numerical altitude is a single digit, then it represents
+thousands of feet.
+Some distinction is made between the prop
+planes and the jets. On ascii terminals, prop planes are
+represented by a upper case letter, jets by a lower case letter.
+.IP
+Airports are shown as a number and some indication of the direction
+planes must be going to land at the airport.
+On ascii terminals, this is one of '^', '>', '<', and 'v', to indicate
+north (0 degrees), east (90), west (270) and south (180), respectively.
+The planes will also
+take off in this direction.
+.IP
+Beacons are represented as circles or asterisks and a number.
+Their purpose is to offer a place of easy reference to the plane pilots.
+See 'the delay command' under the input section of this manual.
+.IP
+Entry/exit points are displayed as numbers along the border of the
+radar screen. Planes will enter the arena from these points without
+warning. These points have a direction associated with them, and
+planes will always enter the arena from this direction. On the
+ascii version of
+.I atc,
+this direction is not displayed. It will become apparent
+what this direction is as the game progresses.
+.IP
+Incoming planes will always enter at the same altitude: 7000 feet.
+For a plane to successfully depart through an entry/exit point,
+it must be flying at 9000 feet.
+It is not necessary for the planes to be flying in any particular
+direction when they leave the arena (yet).
+.SS "INFORMATION AREA"
+.IP
+The second area of the display is the information area, which lists
+the time (number of updates since start), and the number of planes you
+have directed safely out of the arena.
+Below this is a list of planes currently in the air, followed by a
+blank line, and then a list of planes on the ground (at airports).
+Each line lists the plane name and its current altitude,
+an optional asterisk indicating low fuel, the plane's destination,
+and the plane's current command. Changing altitude is not considered
+to be a command and is therefore not displayed. The following are
+some possible information lines:
+.IP
+ B4*A0: Circle @ b1
+.br
+ g7 E4: 225
+.IP
+The first example shows a prop plane named 'B' that is flying at 4000
+feet. It is low on fuel (note the '*'). It's destination is
+Airport #0.
+The next command it expects
+to do is circle when it reaches Beacon #1.
+The second example shows a jet named 'g' at 7000 feet, destined for
+Exit #4. It is just now executing a turn to 225 degrees (South-West).
+.SS "INPUT AREA"
+.IP
+The third area of the display is the input area. It is here that
+your input is reflected. See the INPUT heading of this manual
+for more details.
+.SS "AUTHOR AREA"
+.IP
+This area is used simply to give credit where credit is due. :-)
+.SH INPUT
+.LP
+A command completion interface is built into
+the game. At any time, typing '?' will list possible input characters.
+Typing a backspace (your erase character) backs up, erasing the last part
+of the command. When a command is complete, a return enters it, and
+any semantic checking is done at that time. If no errors are detected,
+the command is sent to the appropriate plane. If an error is discovered
+during the check, the offending statement will be underscored and a
+(hopefully) descriptive message will be printed under it.
+.LP
+The command syntax is broken into two parts:
+.I "Immediate Only"
+and
+.I Delayable
+commands.
+.I "Immediate Only"
+commands happen on the next
+update.
+.I Delayable
+commands also happen on the next update unless they
+are followed by an optional predicate called the
+.I Delay
+command.
+.LP
+In the following tables, the syntax
+.B [0\-9]
+means any single digit, and
+.B <dir>
+refers to the keys around the 's' key, namely ``wedcxzaq''.
+In absolute references, 'q' refers to North-West or 315 degrees, and 'w'
+refers to North, or 0 degrees.
+In relative references, 'q' refers to -45 degrees or 45 degrees left, and 'w'
+refers to 0 degrees, or no change in direction.
+.LP
+All commands start with a plane letter. This indicates the recipient
+of the command. Case is ignored.
+.SS "IMMEDIATE ONLY COMMANDS"
+.RS
+.B "\- a Altitude:"
+.RS
+Affect a plane's altitude (and take off).
+.RE
+.RS
+.B "\- [0\-9] Number:"
+.RS
+Go to the given altitude (thousands of feet).
+.RE
+.B "\- c/+ Climb:"
+.RS
+Relative altitude change.
+.RE
+.RS
+.B "\- [0\-9] Number:"
+.RS
+Difference in thousands of feet.
+.RE
+.RE
+.B "\- d/\- Descend:"
+.RS
+Relative altitude change.
+.RE
+.RS
+.B "\- [0\-9] Number:"
+.RS
+Difference in thousands of feet.
+.RE
+.RE
+.RE
+.B "\- m Mark:"
+.RS
+Display in highlighted mode. Command is displayed normally.
+.RE
+.B "\- i Ignore:"
+.RS
+Do not display highlighted. Command is displayed as a
+line of dashes if there is no command.
+.RE
+.B "\- u Unmark:"
+.RS
+Same as ignore, but if a delayed command is processed,
+the plane will become marked. This is useful if you want
+to forget about a plane during part, but not all, of its
+journey.
+.RE
+.RE
+.SS "DELAYABLE COMMANDS"
+.RS
+.B "\- c Circle:"
+.RS
+Have the plane circle (clockwise by default).
+.RE
+.RS
+.B "\- l Left:"
+.RS
+Circle counterclockwise.
+.RE
+.B "\- r Right:"
+.RS
+Circle clockwise.
+.RE
+.RE
+.B "\- t Turn:"
+.RS
+Change direction.
+.RE
+.RS
+.B "\- l Left:"
+.RS
+Turn counterclockwise (45 degrees by default).
+.RE
+.RS
+.B "\- <dir> Direction:"
+.RS
+Turn ccw the given number of degrees.
+Zero degrees is no turn. A ccw turn
+of -45 degrees is 45 cw.
+.RE
+.RE
+.B "\- r Right:"
+.RS
+Turn clockwise (45 degrees by default).
+.RE
+.RS
+.B "\- <dir> Direction:"
+.RS
+Same as turn left <dir>.
+.RE
+.RE
+.B "\- L Left 90:"
+.RS
+Turn counterclockwise 90 degrees.
+.RE
+.B "\- R Right 90:"
+.RS
+Turn clockwise 90 degrees.
+.RE
+.B "\- <dir> Direction:"
+.RS
+Turn to the absolute compass heading given.
+The shortest turn will be taken.
+.RE
+.B "\- t Towards:"
+.RS
+Turn towards a beacon, airport or exit. The turn is
+just an estimate.
+.RE
+.RS
+.B "\- b/* Beacon:"
+.RS
+Turn towards the beacon.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The beacon number.
+.RE
+.RE
+.B "\- e Exit:"
+.RS
+Turn towards the exit.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The exit number.
+.RE
+.RE
+.B "\- a Airport:"
+.RS
+Turn towards the airport.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The airport number.
+.RE
+.RE
+.RE
+.RE
+.RE
+.SS THE DELAY COMMAND
+.LP
+The
+.B Delay
+(a/@)
+command may be appended to any
+.B Delayable
+command. It allows the controller to instruct a plane to do an action
+when the plane reaches a particular beacon (or other objects in future
+versions).
+.sp
+.RS
+.B "\- a/@ At:"
+.RS
+Do the given delayable command when the plane reaches the given beacon.
+.RE
+.RS
+.B "\- b/* Beacon:"
+.RS
+This is redundant to allow for expansion.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The beacon number.
+.RE
+.RE
+.RE
+.RE
+.SS "MARKING, UNMARKING AND IGNORING"
+.LP
+Planes are
+.B marked
+when they enter the arena. This means they are displayed in highlighted
+mode on the radar display. A plane may also be either
+.B unmarked
+or
+.B ignored.
+An
+.B unmarked
+plane is drawn in unhighlighted mode, and a line of dashes is displayed in
+the command field of the information area. The plane will remain this
+way until a mark command has been issued. Any other command will be issued,
+but the command line will return to a line of dashes when the command
+is completed.
+.LP
+An
+.B ignored
+plane is treated the same as an unmarked plane, except that it will
+automatically switch to
+.B marked
+status when a delayed command has been processed. This is useful if
+you want to forget about a plane for a while, but its flight path has
+not yet been completely set.
+.LP
+As with all of the commands, marking, unmarking and ignoring will take effect
+at the beginning of the next update. Do not be surprised if the plane does
+not immediately switch to unhighlighted mode.
+.SS EXAMPLES
+.RS
+.TP 16
+atlab1
+a: turn left at beacon #1
+.TP 16
+cc
+C: circle
+.TP 16
+gtte4ab2
+g: turn towards exit #4 at beacon #2
+.TP 16
+ma+2
+m: altitude: climb 2000 feet
+.TP 16
+stq
+S: turn to 315
+.TP 16
+xi
+x: ignore
+.RE
+.SH "OTHER INFORMATION"
+.LP
+Jets move every update; prop planes move every other update.
+.LP
+All planes turn a most 90 degrees per movement.
+.LP
+Planes enter at 7000 feet and leave at 9000 feet.
+.LP
+Planes flying at an altitude of 0 crash if they are not over an airport.
+.LP
+Planes waiting at airports can only be told to take off (climb in altitude).
+.SH "NEW GAMES"
+.LP
+The
+.B Game_List
+file lists the currently available play fields. New field description
+file names must be placed in this file to be 'playable'. If a player
+specifies a game not in this file, his score will not be logged.
+.LP
+The game field description files are broken into two parts. The first
+part is the definition section. Here, the four tunable game parameters
+must be set. These variables are set with the syntax:
+.IP
+variable = number;
+.LP
+Variable may be one of:
+.B update,
+indicating the number of seconds between forced updates;
+.B newplane,
+indicating (about) the number of updates between new plane entries;
+.B width,
+indicating the width of the play field; and
+.B height,
+indicating the height of the play field.
+.LP
+The second part of the field description files describes the locations
+of the exits, the beacons, the airports and the lines.
+The syntax is as follows:
+.IP
+beacon: (x y) ... ;
+.br
+airport: (x y direction) ... ;
+.br
+exit: (x y direction) ... ;
+.br
+line: [ (x1 y1) (x2 y2) ] ... ;
+.LP
+For beacons, a simple x, y coordinate pair is used (enclosed in parenthesis).
+Airports and exits require a third value, a direction, which is one
+of
+.B wedcxzaq.
+For airports, this is the direction that planes must be going to take
+off and land, and for exits, this is the direction that planes will going
+when they
+.B enter
+the arena. This may not seem intuitive, but as there is no restriction on
+direction of exit, this is appropriate.
+Lines are slightly different, since they need two coordinate pairs to
+specify the line endpoints. These endpoints must be enclosed in
+square brackets.
+.LP
+All statements are semi-colon (;) terminated. Multiple item statements
+accumulate. Each definition must occur exactly once, before any
+item statements. Comments begin with a hash (#) symbol
+and terminate with a newline.
+The coordinates are between zero and width-1 and height-1
+inclusive. All of the exit coordinates must lie on the borders, and
+all of the beacons and airports must lie inside of the borders.
+Line endpoints may be anywhere within the field, so long as
+the lines are horizontal, vertical or
+.B "exactly diagonal."
+.SS "FIELD FILE EXAMPLE"
+.RS
+.sp
+.nf
+.TA 1i 1i
+.ta 1i 1i
+# This is the default game.
+
+update = 5;
+newplane = 5;
+width = 30;
+height = 21;
+
+exit: ( 12 0 x ) ( 29 0 z ) ( 29 7 a ) ( 29 17 a )
+ ( 9 20 e ) ( 0 13 d ) ( 0 7 d ) ( 0 0 c ) ;
+
+beacon: ( 12 7 ) ( 12 17 ) ;
+
+airport: ( 20 15 w ) ( 20 18 d ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 12 1 ) ( 12 6 ) ]
+ [ ( 13 7 ) ( 28 7 ) ]
+ [ ( 28 1 ) ( 13 16 ) ]
+ [ ( 1 13 ) ( 11 13 ) ]
+ [ ( 12 8 ) ( 12 16 ) ]
+ [ ( 11 18 ) ( 10 19 ) ]
+ [ ( 13 17 ) ( 28 17 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
+.fi
+.RE
+.SH FILES
+.LP
+Files are kept in a special directory. See the OPTIONS for a way to
+print this path out.
+.TP 16
+.B ATC_score
+Where the scores are kept.
+.TP 16
+.B Game_List
+The list of playable games.
+.SH AUTHOR
+.LP
+Ed James, UC Berkeley: edjames@ucbvax.berkeley.edu, ucbvax!edjames
+.LP
+This game is based on someone's description of the overall flavor
+of a game written for some unknown PC many years ago, maybe.
+.SH BUGS
+.LP
+The screen sometimes refreshes after you have quit.
+.LP
+Yet Another Curses Bug was discovered during the development of this game.
+If your curses library clrtobot.o is version 5.1 or earlier,
+you will have erase problems with the backspace operator in the input
+window.
+
diff --git a/atc/def.h b/atc/def.h
new file mode 100644
index 00000000..257cdb41
--- /dev/null
+++ b/atc/def.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)def.h 5.2 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#define AUTHOR_STR "ATC - by Ed James"
+
+#define PI 3.14159654
+
+#define LOWFUEL 15
+
+#define REALLOC 10
+
+#define SGN(x) ((x < 0) ? -1 : ((x > 0) ? 1 : 0))
+#define ABS(x) ((x < 0) ? -(x) : (x))
+#define DIR_FROM_DXDY(dx,dy) ((int) (atan2((double)(dy), (double)(dx)) \
+ * MAXDIR / (2 * PI) + 2.5 + MAXDIR) % MAXDIR)
+
+#define MAXDIR 8
+
+#define D_LEFT 1
+#define D_RIGHT 2
+#define D_UP 3
+#define D_DOWN 4
+
+#define T_NODEST 0
+#define T_BEACON 1
+#define T_EXIT 2
+#define T_AIRPORT 3
+
+#define S_NONE 0
+#define S_GONE 1
+#define S_MARKED 2
+#define S_UNMARKED 3
+#define S_IGNORED 4
+
+#define INPUT_LINES 3
+#define PLANE_COLS 20
diff --git a/atc/extern.c b/atc/extern.c
new file mode 100644
index 00000000..a69252f3
--- /dev/null
+++ b/atc/extern.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)extern.c 5.4 (Berkeley) 10/30/90";
+#endif /* not lint */
+
+#include "include.h"
+
+char GAMES[] = "Game_List";
+
+int clck, safe_planes, start_time, test_mode;
+
+char *file;
+
+FILE *filein, *fileout;
+
+C_SCREEN screen, *sp = &screen;
+
+LIST air, ground;
+
+struct sgttyb tty_start, tty_new;
+
+DISPLACEMENT displacement[MAXDIR] = {
+ { 0, -1 },
+ { 1, -1 },
+ { 1, 0 },
+ { 1, 1 },
+ { 0, 1 },
+ { -1, 1 },
+ { -1, 0 },
+ { -1, -1 }
+};
diff --git a/atc/extern.h b/atc/extern.h
new file mode 100644
index 00000000..950dbb40
--- /dev/null
+++ b/atc/extern.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 5.4 (Berkeley) 10/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+extern char GAMES[], *file;
+
+extern int clck, safe_planes, start_time, test_mode;
+
+extern FILE *filein, *fileout;
+
+extern C_SCREEN screen, *sp;
+
+extern LIST air, ground;
+
+extern struct sgttyb tty_start, tty_new;
+
+extern DISPLACEMENT displacement[MAXDIR];
+
+extern PLANE *findplane(), *newplane();
diff --git a/atc/games/ATC_scores b/atc/games/ATC_scores
new file mode 100644
index 00000000..bbffeb25
--- /dev/null
+++ b/atc/games/ATC_scores
@@ -0,0 +1,5 @@
+schumann puff game_2 171 1414 195
+schumann puff default 18 220 59
+schumann puff easy 13 182 146
+schumann puff crossover 11 74 448
+schumann puff Killer 0 38 27
diff --git a/atc/games/Game_List b/atc/games/Game_List
new file mode 100644
index 00000000..0117385b
--- /dev/null
+++ b/atc/games/Game_List
@@ -0,0 +1,5 @@
+default
+easy
+crossover
+Killer
+game_2
diff --git a/atc/games/Killer b/atc/games/Killer
new file mode 100644
index 00000000..f15d0602
--- /dev/null
+++ b/atc/games/Killer
@@ -0,0 +1,21 @@
+update = 1;
+newplane = 4;
+width = 30;
+height = 21;
+
+exit: ( 29 7 a ) ( 29 17 a )
+ ( 0 7 d ) ( 0 0 c ) ;
+
+beacon: ( 12 7 ) ( 12 17 ) ( 14 10 ) ( 20 15 ) ;
+
+airport: ( 20 18 d ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 12 1 ) ( 12 6 ) ]
+ [ ( 13 7 ) ( 28 7 ) ]
+ [ ( 28 1 ) ( 13 16 ) ]
+ [ ( 1 13 ) ( 11 13 ) ]
+ [ ( 12 8 ) ( 12 16 ) ]
+ [ ( 11 18 ) ( 10 19 ) ]
+ [ ( 13 17 ) ( 28 17 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
diff --git a/atc/games/crossover b/atc/games/crossover
new file mode 100644
index 00000000..d2689ffd
--- /dev/null
+++ b/atc/games/crossover
@@ -0,0 +1,14 @@
+update = 5;
+newplane = 5;
+width = 29;
+height = 21;
+
+exit: ( 0 0 c ) ( 8 0 c ) ( 20 0 z ) ( 28 0 z )
+ ( 28 20 q ) ( 20 20 q ) ( 8 20 e ) ( 0 20 e );
+
+beacon: ( 14 6 ) ( 18 10 ) ( 14 14 ) ( 10 10 );
+
+line: [ ( 0 0 ) ( 20 20 ) ]
+ [ ( 8 0 ) ( 28 20 ) ]
+ [ ( 20 0 ) ( 0 20 ) ]
+ [ ( 28 0 ) ( 8 20 ) ];
diff --git a/atc/games/default b/atc/games/default
new file mode 100644
index 00000000..e19ef9d2
--- /dev/null
+++ b/atc/games/default
@@ -0,0 +1,21 @@
+update = 5;
+newplane = 10;
+width = 30;
+height = 21;
+
+exit: ( 12 0 x ) ( 29 0 z ) ( 29 7 a ) ( 29 17 a )
+ ( 9 20 e ) ( 0 13 d ) ( 0 7 d ) ( 0 0 c ) ;
+
+beacon: ( 12 7 ) ( 12 17 ) ;
+
+airport: ( 20 15 w ) ( 20 18 d ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 12 1 ) ( 12 6 ) ]
+ [ ( 13 7 ) ( 28 7 ) ]
+ [ ( 28 1 ) ( 13 16 ) ]
+ [ ( 1 13 ) ( 11 13 ) ]
+ [ ( 12 8 ) ( 12 16 ) ]
+ [ ( 11 18 ) ( 10 19 ) ]
+ [ ( 13 17 ) ( 28 17 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
diff --git a/atc/games/easy b/atc/games/easy
new file mode 100644
index 00000000..4ab8eac0
--- /dev/null
+++ b/atc/games/easy
@@ -0,0 +1,15 @@
+update = 7;
+newplane = 12;
+width = 15;
+height = 15;
+
+exit: ( 7 0 x ) ( 14 0 z ) ( 12 14 q ) ( 0 14 e ) ;
+
+beacon: ( 12 7 ) ;
+
+airport: ( 7 8 w ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 7 9 ) ( 12 14 ) ]
+ [ ( 7 0 ) ( 7 14 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
diff --git a/atc/games/game_2 b/atc/games/game_2
new file mode 100644
index 00000000..5788c8a2
--- /dev/null
+++ b/atc/games/game_2
@@ -0,0 +1,22 @@
+update = 5;
+newplane = 8;
+width = 30;
+height = 21;
+
+exit: ( 12 0 x ) ( 29 0 z ) ( 29 6 a ) ( 29 13 a )
+ ( 9 20 e ) ( 0 13 d ) ( 0 6 d ) ( 0 0 c ) ;
+
+beacon: ( 12 17 ) ( 23 6 ) ( 23 13 ) ( 25 17 )
+ ( 12 6 ) ( 12 13 ) ( 6 6 ) ;
+
+airport: ( 18 17 d ) ;
+
+line: [ ( 1 1 ) ( 16 16 ) ]
+ [ ( 1 6 ) ( 28 6 ) ]
+ [ ( 12 1 ) ( 12 17 ) ]
+ [ ( 10 19 ) ( 28 1 ) ]
+ [ ( 13 17 ) ( 17 17 ) ]
+ [ ( 1 13 ) ( 28 13 ) ]
+ [ ( 19 17 ) ( 24 17 ) ]
+ [ ( 19 17 ) ( 22 14 ) ]
+ [ ( 26 16 ) ( 28 14 ) ] ;
diff --git a/atc/grammar.y b/atc/grammar.y
new file mode 100644
index 00000000..a59a3820
--- /dev/null
+++ b/atc/grammar.y
@@ -0,0 +1,389 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+%token <ival> HeightOp
+%token <ival> WidthOp
+%token <ival> UpdateOp
+%token <ival> NewplaneOp
+%token <cval> DirOp
+%token <ival> ConstOp
+%token <ival> LineOp
+%token <ival> AirportOp
+%token <ival> BeaconOp
+%token <ival> ExitOp
+%union {
+ int ival;
+ char cval;
+}
+
+%{
+#include "include.h"
+
+#ifndef lint
+static char sccsid[] = "@(#)grammar.y 5.2 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+int errors = 0;
+int line = 1;
+%}
+
+%%
+file:
+ bunch_of_defs { if (checkdefs() < 0) return (errors); } bunch_of_lines
+ {
+ if (sp->num_exits + sp->num_airports < 2)
+ yyerror("Need at least 2 airports and/or exits.");
+ return (errors);
+ }
+ ;
+
+bunch_of_defs:
+ def bunch_of_defs
+ | def
+ ;
+
+def:
+ udef
+ | ndef
+ | wdef
+ | hdef
+ ;
+
+udef:
+ UpdateOp '=' ConstOp ';'
+ {
+ if (sp->update_secs != 0)
+ return (yyerror("Redefinition of 'update'."));
+ else if ($3 < 1)
+ return (yyerror("'update' is too small."));
+ else
+ sp->update_secs = $3;
+ }
+ ;
+
+ndef:
+ NewplaneOp '=' ConstOp ';'
+ {
+ if (sp->newplane_time != 0)
+ return (yyerror("Redefinition of 'newplane'."));
+ else if ($3 < 1)
+ return (yyerror("'newplane' is too small."));
+ else
+ sp->newplane_time = $3;
+ }
+ ;
+
+hdef:
+ HeightOp '=' ConstOp ';'
+ {
+ if (sp->height != 0)
+ return (yyerror("Redefinition of 'height'."));
+ else if ($3 < 3)
+ return (yyerror("'height' is too small."));
+ else
+ sp->height = $3;
+ }
+ ;
+
+wdef:
+ WidthOp '=' ConstOp ';'
+ {
+ if (sp->height != 0)
+ return (yyerror("Redefinition of 'width'."));
+ else if ($3 < 3)
+ return (yyerror("'width' is too small."));
+ else
+ sp->width = $3;
+ }
+ ;
+
+bunch_of_lines:
+ line bunch_of_lines
+ {}
+ | line
+ {}
+ ;
+
+line:
+ BeaconOp ':' Bpoint_list ';'
+ {}
+ | ExitOp ':' Epoint_list ';'
+ {}
+ | LineOp ':' Lline_list ';'
+ {}
+ | AirportOp ':' Apoint_list ';'
+ {}
+ ;
+
+Bpoint_list:
+ Bpoint Bpoint_list
+ {}
+ | Bpoint
+ {}
+ ;
+
+Bpoint:
+ '(' ConstOp ConstOp ')'
+ {
+ if (sp->num_beacons % REALLOC == 0) {
+ if (sp->beacon == NULL)
+ sp->beacon = (BEACON *) malloc((sp->num_beacons
+ + REALLOC) * sizeof (BEACON));
+ else
+ sp->beacon = (BEACON *) realloc(sp->beacon,
+ (sp->num_beacons + REALLOC) *
+ sizeof (BEACON));
+ if (sp->beacon == NULL)
+ return (yyerror("No memory available."));
+ }
+ sp->beacon[sp->num_beacons].x = $2;
+ sp->beacon[sp->num_beacons].y = $3;
+ check_point($2, $3);
+ sp->num_beacons++;
+ }
+ ;
+
+Epoint_list:
+ Epoint Epoint_list
+ {}
+ | Epoint
+ {}
+ ;
+
+Epoint:
+ '(' ConstOp ConstOp DirOp ')'
+ {
+ int dir;
+
+ if (sp->num_exits % REALLOC == 0) {
+ if (sp->exit == NULL)
+ sp->exit = (EXIT *) malloc((sp->num_exits +
+ REALLOC) * sizeof (EXIT));
+ else
+ sp->exit = (EXIT *) realloc(sp->exit,
+ (sp->num_exits + REALLOC) *
+ sizeof (EXIT));
+ if (sp->exit == NULL)
+ return (yyerror("No memory available."));
+ }
+ dir = dir_no($4);
+ sp->exit[sp->num_exits].x = $2;
+ sp->exit[sp->num_exits].y = $3;
+ sp->exit[sp->num_exits].dir = dir;
+ check_edge($2, $3);
+ check_edir($2, $3, dir);
+ sp->num_exits++;
+ }
+ ;
+
+Apoint_list:
+ Apoint Apoint_list
+ {}
+ | Apoint
+ {}
+ ;
+
+Apoint:
+ '(' ConstOp ConstOp DirOp ')'
+ {
+ int dir;
+
+ if (sp->num_airports % REALLOC == 0) {
+ if (sp->airport == NULL)
+ sp->airport=(AIRPORT *)malloc((sp->num_airports
+ + REALLOC) * sizeof(AIRPORT));
+ else
+ sp->airport = (AIRPORT *) realloc(sp->airport,
+ (sp->num_airports + REALLOC) *
+ sizeof(AIRPORT));
+ if (sp->airport == NULL)
+ return (yyerror("No memory available."));
+ }
+ dir = dir_no($4);
+ sp->airport[sp->num_airports].x = $2;
+ sp->airport[sp->num_airports].y = $3;
+ sp->airport[sp->num_airports].dir = dir;
+ check_point($2, $3);
+ check_adir($2, $3, dir);
+ sp->num_airports++;
+ }
+ ;
+
+Lline_list:
+ Lline Lline_list
+ {}
+ | Lline
+ {}
+ ;
+
+Lline:
+ '[' '(' ConstOp ConstOp ')' '(' ConstOp ConstOp ')' ']'
+ {
+ if (sp->num_lines % REALLOC == 0) {
+ if (sp->line == NULL)
+ sp->line = (LINE *) malloc((sp->num_lines +
+ REALLOC) * sizeof (LINE));
+ else
+ sp->line = (LINE *) realloc(sp->line,
+ (sp->num_lines + REALLOC) *
+ sizeof (LINE));
+ if (sp->line == NULL)
+ return (yyerror("No memory available."));
+ }
+ sp->line[sp->num_lines].p1.x = $3;
+ sp->line[sp->num_lines].p1.y = $4;
+ sp->line[sp->num_lines].p2.x = $7;
+ sp->line[sp->num_lines].p2.y = $8;
+ check_line($3, $4, $7, $8);
+ sp->num_lines++;
+ }
+ ;
+%%
+
+check_edge(x, y)
+{
+ if (!(x == 0) && !(x == sp->width - 1) &&
+ !(y == 0) && !(y == sp->height - 1))
+ yyerror("edge value not on edge.");
+}
+
+check_point(x, y)
+{
+ if (x < 1 || x >= sp->width - 1)
+ yyerror("X value out of range.");
+ if (y < 1 || y >= sp->height - 1)
+ yyerror("Y value out of range.");
+}
+
+check_linepoint(x, y)
+{
+ if (x < 0 || x >= sp->width)
+ yyerror("X value out of range.");
+ if (y < 0 || y >= sp->height)
+ yyerror("Y value out of range.");
+}
+
+check_line(x1, y1, x2, y2)
+{
+ int d1, d2;
+
+ check_linepoint(x1, y1);
+ check_linepoint(x2, y2);
+
+ d1 = ABS(x2 - x1);
+ d2 = ABS(y2 - y1);
+
+ if (!(d1 == d2) && !(d1 == 0) && !(d2 == 0))
+ yyerror("Bad line endpoints.");
+}
+
+yyerror(s)
+{
+ fprintf(stderr, "\"%s\": line %d: %s\n", file, line, s);
+ errors++;
+
+ return (errors);
+}
+
+check_edir(x, y, dir)
+{
+ int bad = 0;
+
+ if (x == sp->width - 1)
+ x = 2;
+ else if (x != 0)
+ x = 1;
+ if (y == sp->height - 1)
+ y = 2;
+ else if (y != 0)
+ y = 1;
+
+ switch (x * 10 + y) {
+ case 00: if (dir != 3) bad++; break;
+ case 01: if (dir < 1 || dir > 3) bad++; break;
+ case 02: if (dir != 1) bad++; break;
+ case 10: if (dir < 3 || dir > 5) bad++; break;
+ case 11: break;
+ case 12: if (dir > 1 && dir < 7) bad++; break;
+ case 20: if (dir != 5) bad++; break;
+ case 21: if (dir < 5) bad++; break;
+ case 22: if (dir != 7) bad++; break;
+ default:
+ yyerror("Unknown value in checkdir! Get help!");
+ break;
+ }
+ if (bad)
+ yyerror("Bad direction for entrance at exit.");
+}
+
+check_adir(x, y, dir)
+{
+}
+
+checkdefs()
+{
+ int err = 0;
+
+ if (sp->width == 0) {
+ yyerror("'width' undefined.");
+ err++;
+ }
+ if (sp->height == 0) {
+ yyerror("'height' undefined.");
+ err++;
+ }
+ if (sp->update_secs == 0) {
+ yyerror("'update' undefined.");
+ err++;
+ }
+ if (sp->newplane_time == 0) {
+ yyerror("'newplane' undefined.");
+ err++;
+ }
+ if (err)
+ return (-1);
+ else
+ return (0);
+}
diff --git a/atc/graphics.c b/atc/graphics.c
new file mode 100644
index 00000000..1d7d39d8
--- /dev/null
+++ b/atc/graphics.c
@@ -0,0 +1,418 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)graphics.c 5.3 (Berkeley) 10/30/90";
+#endif /* not lint */
+
+#include "include.h"
+#ifdef SYSV
+#include <errno.h>
+#endif
+
+#define C_TOPBOTTOM '-'
+#define C_LEFTRIGHT '|'
+#define C_AIRPORT '='
+#define C_LINE '+'
+#define C_BACKROUND '.'
+#define C_BEACON '*'
+#define C_CREDIT '*'
+
+WINDOW *radar, *cleanradar, *credit, *input, *planes;
+
+getAChar()
+{
+#ifdef BSD
+ return (getchar());
+#endif
+#ifdef SYSV
+ int c;
+
+ while ((c = getchar()) == -1 && errno == EINTR) ;
+ return(c);
+#endif
+}
+
+erase_all()
+{
+ PLANE *pp;
+
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ wmove(cleanradar, pp->ypos, pp->xpos * 2);
+ wmove(radar, pp->ypos, pp->xpos * 2);
+ waddch(radar, winch(cleanradar));
+ wmove(cleanradar, pp->ypos, pp->xpos * 2 + 1);
+ wmove(radar, pp->ypos, pp->xpos * 2 + 1);
+ waddch(radar, winch(cleanradar));
+ }
+}
+
+draw_all()
+{
+ PLANE *pp;
+
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ if (pp->status == S_MARKED)
+ wstandout(radar);
+ wmove(radar, pp->ypos, pp->xpos * 2);
+ waddch(radar, name(pp));
+ waddch(radar, '0' + pp->altitude);
+ if (pp->status == S_MARKED)
+ wstandend(radar);
+ }
+ wrefresh(radar);
+ planewin();
+ wrefresh(input); /* return cursor */
+ fflush(stdout);
+}
+
+init_gr()
+{
+ static char buffer[BUFSIZ];
+
+ initscr();
+ setbuf(stdout, buffer);
+ input = newwin(INPUT_LINES, COLS - PLANE_COLS, LINES - INPUT_LINES, 0);
+ credit = newwin(INPUT_LINES, PLANE_COLS, LINES - INPUT_LINES,
+ COLS - PLANE_COLS);
+ planes = newwin(LINES - INPUT_LINES, PLANE_COLS, 0, COLS - PLANE_COLS);
+}
+
+setup_screen(scp)
+ C_SCREEN *scp;
+{
+ register int i, j;
+ char str[3], *airstr;
+
+ str[2] = '\0';
+
+ if (radar != NULL)
+ delwin(radar);
+ radar = newwin(scp->height, scp->width * 2, 0, 0);
+
+ if (cleanradar != NULL)
+ delwin(cleanradar);
+ cleanradar = newwin(scp->height, scp->width * 2, 0, 0);
+
+ /* minus one here to prevent a scroll */
+ for (i = 0; i < PLANE_COLS - 1; i++) {
+ wmove(credit, 0, i);
+ waddch(credit, C_CREDIT);
+ wmove(credit, INPUT_LINES - 1, i);
+ waddch(credit, C_CREDIT);
+ }
+ wmove(credit, INPUT_LINES / 2, 1);
+ waddstr(credit, AUTHOR_STR);
+
+ for (i = 1; i < scp->height - 1; i++) {
+ for (j = 1; j < scp->width - 1; j++) {
+ wmove(radar, i, j * 2);
+ waddch(radar, C_BACKROUND);
+ }
+ }
+
+ /*
+ * Draw the lines first, since people like to draw lines
+ * through beacons and exit points.
+ */
+ str[0] = C_LINE;
+ for (i = 0; i < scp->num_lines; i++) {
+ str[1] = ' ';
+ draw_line(radar, scp->line[i].p1.x, scp->line[i].p1.y,
+ scp->line[i].p2.x, scp->line[i].p2.y, str);
+ }
+
+ str[0] = C_TOPBOTTOM;
+ str[1] = C_TOPBOTTOM;
+ wmove(radar, 0, 0);
+ for (i = 0; i < scp->width - 1; i++)
+ waddstr(radar, str);
+ waddch(radar, C_TOPBOTTOM);
+
+ str[0] = C_TOPBOTTOM;
+ str[1] = C_TOPBOTTOM;
+ wmove(radar, scp->height - 1, 0);
+ for (i = 0; i < scp->width - 1; i++)
+ waddstr(radar, str);
+ waddch(radar, C_TOPBOTTOM);
+
+ for (i = 1; i < scp->height - 1; i++) {
+ wmove(radar, i, 0);
+ waddch(radar, C_LEFTRIGHT);
+ wmove(radar, i, (scp->width - 1) * 2);
+ waddch(radar, C_LEFTRIGHT);
+ }
+
+ str[0] = C_BEACON;
+ for (i = 0; i < scp->num_beacons; i++) {
+ str[1] = '0' + i;
+ wmove(radar, scp->beacon[i].y, scp->beacon[i].x * 2);
+ waddstr(radar, str);
+ }
+
+ for (i = 0; i < scp->num_exits; i++) {
+ wmove(radar, scp->exit[i].y, scp->exit[i].x * 2);
+ waddch(radar, '0' + i);
+ }
+
+ airstr = "^?>?v?<?";
+ for (i = 0; i < scp->num_airports; i++) {
+ str[0] = airstr[scp->airport[i].dir];
+ str[1] = '0' + i;
+ wmove(radar, scp->airport[i].y, scp->airport[i].x * 2);
+ waddstr(radar, str);
+ }
+
+ overwrite(radar, cleanradar);
+ wrefresh(radar);
+ wrefresh(credit);
+ fflush(stdout);
+}
+
+draw_line(w, x, y, lx, ly, s)
+ WINDOW *w;
+ char *s;
+{
+ int dx, dy;
+
+ dx = SGN(lx - x);
+ dy = SGN(ly - y);
+ for (;;) {
+ wmove(w, y, x * 2);
+ waddstr(w, s);
+ if (x == lx && y == ly)
+ break;
+ x += dx;
+ y += dy;
+ }
+}
+
+ioclrtoeol(pos)
+{
+ wmove(input, 0, pos);
+ wclrtoeol(input);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+iomove(pos)
+{
+ wmove(input, 0, pos);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+ioaddstr(pos, str)
+ char *str;
+{
+ wmove(input, 0, pos);
+ waddstr(input, str);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+ioclrtobot()
+{
+ wclrtobot(input);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+ioerror(pos, len, str)
+ char *str;
+{
+ int i;
+
+ wmove(input, 1, pos);
+ for (i = 0; i < len; i++)
+ waddch(input, '^');
+ wmove(input, 2, 0);
+ waddstr(input, str);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+quit()
+{
+ int c, y, x;
+#ifdef BSD
+ struct itimerval itv;
+#endif
+
+ getyx(input, y, x);
+ wmove(input, 2, 0);
+ waddstr(input, "Really quit? (y/n) ");
+ wclrtobot(input);
+ wrefresh(input);
+ fflush(stdout);
+
+ c = getchar();
+ if (c == EOF || c == 'y') {
+ /* disable timer */
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(0);
+#endif
+ fflush(stdout);
+ clear();
+ refresh();
+ endwin();
+ log_score(0);
+ exit(0);
+ }
+ wmove(input, 2, 0);
+ wclrtobot(input);
+ wmove(input, y, x);
+ wrefresh(input);
+ fflush(stdout);
+ return;
+}
+
+planewin()
+{
+ PLANE *pp;
+ char *command();
+ int warning = 0;
+
+#ifdef BSD
+ wclear(planes);
+#endif
+
+ wmove(planes, 0,0);
+
+#ifdef SYSV
+ wclrtobot(planes);
+#endif
+ wprintw(planes, "Time: %-4d Safe: %d", clck, safe_planes);
+ wmove(planes, 2, 0);
+
+ waddstr(planes, "pl dt comm");
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ if (waddch(planes, '\n') == ERR) {
+ warning++;
+ break;
+ }
+ waddstr(planes, command(pp));
+ }
+ waddch(planes, '\n');
+ for (pp = ground.head; pp != NULL; pp = pp->next) {
+ if (waddch(planes, '\n') == ERR) {
+ warning++;
+ break;
+ }
+ waddstr(planes, command(pp));
+ }
+ if (warning) {
+ wmove(planes, LINES - INPUT_LINES - 1, 0);
+ waddstr(planes, "---- more ----");
+ wclrtoeol(planes);
+ }
+ wrefresh(planes);
+ fflush(stdout);
+}
+
+loser(p, s)
+ PLANE *p;
+ char *s;
+{
+ int c;
+#ifdef BSD
+ struct itimerval itv;
+#endif
+
+ /* disable timer */
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(0);
+#endif
+
+ wmove(input, 0, 0);
+ wclrtobot(input);
+ wprintw(input, "Plane '%c' %s\n\nHit space for top players list...",
+ name(p), s);
+ wrefresh(input);
+ fflush(stdout);
+ while ((c = getchar()) != EOF && c != ' ')
+ ;
+ clear(); /* move to top of screen */
+ refresh();
+ endwin();
+ log_score(0);
+ exit(0);
+}
+
+redraw()
+{
+ clear();
+ refresh();
+
+ touchwin(radar);
+ wrefresh(radar);
+ touchwin(planes);
+ wrefresh(planes);
+ touchwin(credit);
+ wrefresh(credit);
+
+ /* refresh input last to get cursor in right place */
+ touchwin(input);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+
+done_screen()
+{
+ clear();
+ refresh();
+ endwin(); /* clean up curses */
+}
diff --git a/atc/include.h b/atc/include.h
new file mode 100644
index 00000000..aa77562f
--- /dev/null
+++ b/atc/include.h
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)include.h 5.3 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+
+#ifdef BSD
+#include <sgtty.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#endif
+
+#ifdef SYSV
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/utsname.h>
+#endif
+
+#include <signal.h>
+#include <math.h>
+
+#include <curses.h>
+
+#ifdef SYSV
+#define index strchr
+#define rindex strrchr
+#define bcopy(a,b,c) memcpy((b), (a), (c))
+#define bzero(a,b) memset((a), '\0', (b))
+#define srandom srand
+#define random rand
+#define sgttyb termio
+#define sg_erase c_cc[2]
+#define sg_kill c_cc[3]
+#endif
+
+#include "def.h"
+#include "struct.h"
+#include "extern.h"
+#include "tunable.h"
diff --git a/atc/input.c b/atc/input.c
new file mode 100644
index 00000000..693a7a3a
--- /dev/null
+++ b/atc/input.c
@@ -0,0 +1,663 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 4/30/90";
+#endif not lint
+
+#include "include.h"
+#include "pathnames.h"
+
+#define MAXRULES 6
+#define MAXDEPTH 15
+
+#define RETTOKEN '\n'
+#ifdef SYSV
+#define CRTOKEN '\r'
+#endif
+#define REDRAWTOKEN '\014' /* CTRL(L) */
+#define SHELLTOKEN '!'
+#define HELPTOKEN '?'
+#define ALPHATOKEN 256
+#define NUMTOKEN 257
+
+typedef struct {
+ int token;
+ int to_state;
+ char *str;
+ char *(*func)();
+} RULE;
+
+typedef struct {
+ int num_rules;
+ RULE *rule;
+} STATE;
+
+typedef struct {
+ char str[20];
+ int state;
+ int rule;
+ int ch;
+ int pos;
+} STACK;
+
+#define T_RULE stack[level].rule
+#define T_STATE stack[level].state
+#define T_STR stack[level].str
+#define T_POS stack[level].pos
+#define T_CH stack[level].ch
+
+#define NUMELS(a) (sizeof (a) / sizeof (*(a)))
+
+#define NUMSTATES NUMELS(st)
+
+char *setplane(), *circle(), *left(), *right(), *Left(), *Right(),
+ *beacon(), *ex_it(), *climb(), *descend(), *setalt(), *setrelalt(),
+ *benum(), *to_dir(), *rel_dir(), *delayb(), *mark(), *unmark(),
+ *airport(), *turn(), *ignore();
+
+RULE state0[] = { { ALPHATOKEN, 1, "%c:", setplane},
+ { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " [a-z]<ret>", NULL }},
+ state1[] = { { 't', 2, " turn", turn },
+ { 'a', 3, " altitude:", NULL },
+ { 'c', 4, " circle", circle },
+ { 'm', 7, " mark", mark },
+ { 'u', 7, " unmark", unmark },
+ { 'i', 7, " ignore", ignore },
+ { HELPTOKEN, 12, " tacmui", NULL }},
+ state2[] = { { 'l', 6, " left", left },
+ { 'r', 6, " right", right },
+ { 'L', 4, " left 90", Left },
+ { 'R', 4, " right 90", Right },
+ { 't', 11, " towards", NULL },
+ { 'w', 4, " to 0", to_dir },
+ { 'e', 4, " to 45", to_dir },
+ { 'd', 4, " to 90", to_dir },
+ { 'c', 4, " to 135", to_dir },
+ { 'x', 4, " to 180", to_dir },
+ { 'z', 4, " to 225", to_dir },
+ { 'a', 4, " to 270", to_dir },
+ { 'q', 4, " to 315", to_dir },
+ { HELPTOKEN, 12, " lrLRt<dir>", NULL }},
+ state3[] = { { '+', 10, " climb", climb },
+ { 'c', 10, " climb", climb },
+ { '-', 10, " descend", descend },
+ { 'd', 10, " descend", descend },
+ { NUMTOKEN, 7, " %c000 feet", setalt },
+ { HELPTOKEN, 12, " +-cd[0-9]", NULL }},
+ state4[] = { { '@', 9, " at", NULL },
+ { 'a', 9, " at", NULL },
+ { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " @a<ret>", NULL }},
+ state5[] = { { NUMTOKEN, 7, "%c", delayb },
+ { HELPTOKEN, 12, " [0-9]", NULL }},
+ state6[] = { { '@', 9, " at", NULL },
+ { 'a', 9, " at", NULL },
+ { 'w', 4, " 0", rel_dir },
+ { 'e', 4, " 45", rel_dir },
+ { 'd', 4, " 90", rel_dir },
+ { 'c', 4, " 135", rel_dir },
+ { 'x', 4, " 180", rel_dir },
+ { 'z', 4, " 225", rel_dir },
+ { 'a', 4, " 270", rel_dir },
+ { 'q', 4, " 315", rel_dir },
+ { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " @a<dir><ret>",NULL }},
+ state7[] = { { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " <ret>", NULL }},
+ state8[] = { { NUMTOKEN, 4, "%c", benum },
+ { HELPTOKEN, 12, " [0-9]", NULL }},
+ state9[] = { { 'b', 5, " beacon #", NULL },
+ { '*', 5, " beacon #", NULL },
+ { HELPTOKEN, 12, " b*", NULL }},
+ state10[] = { { NUMTOKEN, 7, " %c000 ft", setrelalt},
+ { HELPTOKEN, 12, " [0-9]", NULL }},
+ state11[] = { { 'b', 8, " beacon #", beacon },
+ { '*', 8, " beacon #", beacon },
+ { 'e', 8, " exit #", ex_it },
+ { 'a', 8, " airport #", airport },
+ { HELPTOKEN, 12, " b*ea", NULL }},
+ state12[] = { { -1, -1, "", NULL }};
+
+#define DEF_STATE(s) { NUMELS(s), (s) }
+
+STATE st[] = {
+ DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2),
+ DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5),
+ DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8),
+ DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11),
+ DEF_STATE(state12)
+};
+
+PLANE p;
+STACK stack[MAXDEPTH];
+int level;
+int tval;
+int dest_type, dest_no, dir;
+
+pop()
+{
+ if (level == 0)
+ return (-1);
+ level--;
+
+ ioclrtoeol(T_POS);
+
+ strcpy(T_STR, "");
+ T_RULE = -1;
+ T_CH = -1;
+ return (0);
+}
+
+rezero()
+{
+ iomove(0);
+
+ level = 0;
+ T_STATE = 0;
+ T_RULE = -1;
+ T_CH = -1;
+ T_POS = 0;
+ strcpy(T_STR, "");
+}
+
+push(ruleno, ch)
+{
+ int newstate, newpos;
+
+ (void)sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval);
+ T_RULE = ruleno;
+ T_CH = ch;
+ newstate = st[T_STATE].rule[ruleno].to_state;
+ newpos = T_POS + strlen(T_STR);
+
+ ioaddstr(T_POS, T_STR);
+
+ if (level == 0)
+ ioclrtobot();
+ level++;
+ T_STATE = newstate;
+ T_POS = newpos;
+ T_RULE = -1;
+ strcpy(T_STR, "");
+}
+
+getcommand()
+{
+ int c, i, done;
+ char *s, *(*func)();
+ PLANE *pp;
+
+ rezero();
+
+ do {
+ c = gettoken();
+ if (c == tty_new.sg_erase) {
+ if (pop() < 0)
+ noise();
+ } else if (c == tty_new.sg_kill) {
+ while (pop() >= 0)
+ ;
+ } else {
+ done = 0;
+ for (i = 0; i < st[T_STATE].num_rules; i++) {
+ if (st[T_STATE].rule[i].token == c ||
+ st[T_STATE].rule[i].token == tval) {
+ push(i, (c >= ALPHATOKEN) ? tval : c);
+ done = 1;
+ break;
+ }
+ }
+ if (!done)
+ noise();
+ }
+ } while (T_STATE != -1);
+
+ if (level == 1)
+ return (1); /* forced update */
+
+ dest_type = T_NODEST;
+
+ for (i = 0; i < level; i++) {
+ func = st[stack[i].state].rule[stack[i].rule].func;
+ if (func != NULL)
+ if ((s = (*func)(stack[i].ch)) != NULL) {
+ ioerror(stack[i].pos, strlen(stack[i].str), s);
+ return (-1);
+ }
+ }
+
+ pp = findplane(p.plane_no);
+ if (pp->new_altitude != p.new_altitude)
+ pp->new_altitude = p.new_altitude;
+ else if (pp->status != p.status)
+ pp->status = p.status;
+ else {
+ pp->new_dir = p.new_dir;
+ pp->delayd = p.delayd;
+ pp->delayd_no = p.delayd_no;
+ }
+ return (0);
+}
+
+noise()
+{
+ putchar('\07');
+ fflush(stdout);
+}
+
+gettoken()
+{
+ while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN)
+ {
+ if (tval == SHELLTOKEN)
+ {
+#ifdef BSD
+ struct itimerval itv;
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ int aval;
+ aval = alarm(0);
+#endif
+ if (fork() == 0) /* child */
+ {
+ char *shell, *base, *getenv(), *strrchr();
+
+ setuid(getuid()); /* turn off setuid bit */
+ done_screen();
+
+ /* run user's favorite shell */
+ if ((shell = getenv("SHELL")) != NULL)
+ {
+ base = strrchr(shell, '/');
+ if (base == NULL)
+ base = shell;
+ else
+ base++;
+ execl(shell, base, 0);
+ }
+ else
+ execl(_PATH_BSHELL, "sh", 0);
+
+ exit(0); /* oops */
+ }
+
+ wait(0);
+#ifdef BSD
+ ioctl(fileno(stdin), TIOCSETP, &tty_new);
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 1;
+ itv.it_interval.tv_sec = sp->update_secs;
+ itv.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ ioctl(fileno(stdin), TCSETAW, &tty_new);
+ alarm(aval);
+#endif
+ }
+ redraw();
+ }
+
+ if (isdigit(tval))
+ return (NUMTOKEN);
+ else if (isalpha(tval))
+ return (ALPHATOKEN);
+ else
+ return (tval);
+}
+
+char *
+setplane(c)
+{
+ PLANE *pp;
+
+ pp = findplane(number(c));
+ if (pp == NULL)
+ return ("Unknown Plane");
+ bcopy(pp, &p, sizeof (p));
+ p.delayd = 0;
+ return (NULL);
+}
+
+char *
+turn(c)
+{
+ if (p.altitude == 0)
+ return ("Planes at airports may not change direction");
+ return (NULL);
+}
+
+char *
+circle(c)
+{
+ if (p.altitude == 0)
+ return ("Planes cannot circle on the ground");
+ p.new_dir = MAXDIR;
+ return (NULL);
+}
+
+char *
+left(c)
+{
+ dir = D_LEFT;
+ p.new_dir = p.dir - 1;
+ if (p.new_dir < 0)
+ p.new_dir += MAXDIR;
+ return (NULL);
+}
+
+char *
+right(c)
+{
+ dir = D_RIGHT;
+ p.new_dir = p.dir + 1;
+ if (p.new_dir > MAXDIR)
+ p.new_dir -= MAXDIR;
+ return (NULL);
+}
+
+char *
+Left(c)
+{
+ p.new_dir = p.dir - 2;
+ if (p.new_dir < 0)
+ p.new_dir += MAXDIR;
+ return (NULL);
+}
+
+char *
+Right(c)
+{
+ p.new_dir = p.dir + 2;
+ if (p.new_dir > MAXDIR)
+ p.new_dir -= MAXDIR;
+ return (NULL);
+}
+
+char *
+delayb(c)
+{
+ int xdiff, ydiff;
+
+ c -= '0';
+
+ if (c >= sp->num_beacons)
+ return ("Unknown beacon");
+ xdiff = sp->beacon[c].x - p.xpos;
+ xdiff = SGN(xdiff);
+ ydiff = sp->beacon[c].y - p.ypos;
+ ydiff = SGN(ydiff);
+ if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy)
+ return ("Beacon is not in flight path");
+ p.delayd = 1;
+ p.delayd_no = c;
+
+ if (dest_type != T_NODEST) {
+ switch (dest_type) {
+ case T_BEACON:
+ xdiff = sp->beacon[dest_no].x - sp->beacon[c].x;
+ ydiff = sp->beacon[dest_no].y - sp->beacon[c].y;
+ break;
+ case T_EXIT:
+ xdiff = sp->exit[dest_no].x - sp->beacon[c].x;
+ ydiff = sp->exit[dest_no].y - sp->beacon[c].y;
+ break;
+ case T_AIRPORT:
+ xdiff = sp->airport[dest_no].x - sp->beacon[c].x;
+ ydiff = sp->airport[dest_no].y - sp->beacon[c].y;
+ break;
+ default:
+ return ("Bad case in delayb! Get help!");
+ break;
+ }
+ if (xdiff == 0 && ydiff == 0)
+ return ("Would already be there");
+ p.new_dir = DIR_FROM_DXDY(xdiff, ydiff);
+ if (p.new_dir == p.dir)
+ return ("Already going in that direction");
+ }
+ return (NULL);
+}
+
+char *
+beacon(c)
+{
+ dest_type = T_BEACON;
+ return (NULL);
+}
+
+char *
+ex_it(c)
+{
+ dest_type = T_EXIT;
+ return (NULL);
+}
+
+char *
+airport(c)
+{
+ dest_type = T_AIRPORT;
+ return (NULL);
+}
+
+char *
+climb(c)
+{
+ dir = D_UP;
+ return (NULL);
+}
+
+char *
+descend(c)
+{
+ dir = D_DOWN;
+ return (NULL);
+}
+
+char *
+setalt(c)
+{
+ if ((p.altitude == c - '0') && (p.new_altitude == p.altitude))
+ return ("Already at that altitude");
+ p.new_altitude = c - '0';
+ return (NULL);
+}
+
+char *
+setrelalt(c)
+{
+ if (c == 0)
+ return ("altitude not changed");
+
+ switch (dir) {
+ case D_UP:
+ p.new_altitude = p.altitude + c - '0';
+ break;
+ case D_DOWN:
+ p.new_altitude = p.altitude - (c - '0');
+ break;
+ default:
+ return ("Unknown case in setrelalt! Get help!");
+ break;
+ }
+ if (p.new_altitude < 0)
+ return ("Altitude would be too low");
+ else if (p.new_altitude > 9)
+ return ("Altitude would be too high");
+ return (NULL);
+}
+
+char *
+benum(c)
+{
+ dest_no = c -= '0';
+
+ switch (dest_type) {
+ case T_BEACON:
+ if (c >= sp->num_beacons)
+ return ("Unknown beacon");
+ p.new_dir = DIR_FROM_DXDY(sp->beacon[c].x - p.xpos,
+ sp->beacon[c].y - p.ypos);
+ break;
+ case T_EXIT:
+ if (c >= sp->num_exits)
+ return ("Unknown exit");
+ p.new_dir = DIR_FROM_DXDY(sp->exit[c].x - p.xpos,
+ sp->exit[c].y - p.ypos);
+ break;
+ case T_AIRPORT:
+ if (c >= sp->num_airports)
+ return ("Unknown airport");
+ p.new_dir = DIR_FROM_DXDY(sp->airport[c].x - p.xpos,
+ sp->airport[c].y - p.ypos);
+ break;
+ default:
+ return ("Unknown case in benum! Get help!");
+ break;
+ }
+ return (NULL);
+}
+
+char *
+to_dir(c)
+{
+ p.new_dir = dir_no(c);
+ return (NULL);
+}
+
+char *
+rel_dir(c)
+{
+ int angle;
+
+ angle = dir_no(c);
+ switch (dir) {
+ case D_LEFT:
+ p.new_dir = p.dir - angle;
+ if (p.new_dir < 0)
+ p.new_dir += MAXDIR;
+ break;
+ case D_RIGHT:
+ p.new_dir = p.dir + angle;
+ if (p.new_dir >= MAXDIR)
+ p.new_dir -= MAXDIR;
+ break;
+ default:
+ return ("Bizarre direction in rel_dir! Get help!");
+ break;
+ }
+ return (NULL);
+}
+
+char *
+mark(c)
+{
+ if (p.altitude == 0)
+ return ("Cannot mark planes on the ground");
+ if (p.status == S_MARKED)
+ return ("Already marked");
+ p.status = S_MARKED;
+ return (NULL);
+}
+
+char *
+unmark(c)
+{
+ if (p.altitude == 0)
+ return ("Cannot unmark planes on the ground");
+ if (p.status == S_UNMARKED)
+ return ("Already unmarked");
+ p.status = S_UNMARKED;
+ return (NULL);
+}
+
+char *
+ignore(c)
+{
+ if (p.altitude == 0)
+ return ("Cannot ignore planes on the ground");
+ if (p.status == S_IGNORED)
+ return ("Already ignored");
+ p.status = S_IGNORED;
+ return (NULL);
+}
+
+dir_no(ch)
+ char ch;
+{
+ int dir;
+
+ switch (ch) {
+ case 'w': dir = 0; break;
+ case 'e': dir = 1; break;
+ case 'd': dir = 2; break;
+ case 'c': dir = 3; break;
+ case 'x': dir = 4; break;
+ case 'z': dir = 5; break;
+ case 'a': dir = 6; break;
+ case 'q': dir = 7; break;
+ default:
+ fprintf(stderr, "bad character in dir_no\n");
+ break;
+ }
+ return (dir);
+}
diff --git a/atc/lex.l b/atc/lex.l
new file mode 100644
index 00000000..65e0ad54
--- /dev/null
+++ b/atc/lex.l
@@ -0,0 +1,69 @@
+%{
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lex.l 5.2 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+#include "y.tab.h"
+extern int line;
+
+%}
+%%
+[0-9]+ { yylval.ival = atoi(yytext); return(ConstOp); }
+height { return(HeightOp); }
+width { return(WidthOp); }
+newplane { return(NewplaneOp); }
+update { return(UpdateOp); }
+airport { return(AirportOp); }
+line { return(LineOp); }
+exit { return(ExitOp); }
+beacon { return(BeaconOp); }
+[wedcxzaq] { yylval.cval = *yytext; return (DirOp); }
+[ \t]+ { }
+#[^\n]*\n { line++; }
+\n { line++; }
+. { return *yytext; }
diff --git a/atc/list.c b/atc/list.c
new file mode 100644
index 00000000..8da9da2f
--- /dev/null
+++ b/atc/list.c
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)list.c 5.2 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+#include "include.h"
+
+PLANE *
+newplane()
+{
+ return ((PLANE *) calloc(1, sizeof (PLANE)));
+}
+
+append(l, p)
+ LIST *l;
+ PLANE *p;
+{
+ PLANE *q = NULL, *r = NULL;
+
+ if (l->head == NULL) {
+ p->next = p->prev = NULL;
+ l->head = l->tail = p;
+ } else {
+ q = l -> head;
+
+ while (q != NULL && q->plane_no < p->plane_no) {
+ r = q;
+ q = q -> next;
+ }
+
+ if (q) {
+ if (r) {
+ p->prev = r;
+ r->next = p;
+ p->next = q;
+ q->prev = p;
+ } else {
+ p->next = q;
+ p->prev = NULL;
+ q->prev = p;
+ l->head = p;
+ }
+ } else {
+ l->tail->next = p;
+ p->next = NULL;
+ p->prev = l->tail;
+ l->tail = p;
+ }
+ }
+}
+
+delete(l, p)
+ LIST *l;
+ PLANE *p;
+{
+ if (l->head == NULL)
+ loser(p, "deleted a non-existant plane! Get help!");
+
+ if (l->head == p && l->tail == p)
+ l->head = l->tail = NULL;
+ else if (l->head == p) {
+ l->head = p->next;
+ l->head->prev = NULL;
+ } else if (l->tail == p) {
+ l->tail = p->prev;
+ l->tail->next = NULL;
+ } else {
+ p->prev->next = p->next;
+ p->next->prev = p->prev;
+ }
+}
diff --git a/atc/log.c b/atc/log.c
new file mode 100644
index 00000000..5872583f
--- /dev/null
+++ b/atc/log.c
@@ -0,0 +1,247 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log.c 5.7 (Berkeley) 10/30/90";
+#endif not lint
+
+#include "include.h"
+#include "pathnames.h"
+
+compar(a, b)
+ SCORE *a, *b;
+{
+ if (b->planes == a->planes)
+ return (b->time - a->time);
+ else
+ return (b->planes - a->planes);
+}
+
+#define SECAMIN 60
+#define MINAHOUR 60
+#define HOURADAY 24
+#define SECAHOUR (SECAMIN * MINAHOUR)
+#define SECADAY (SECAHOUR * HOURADAY)
+#define DAY(t) ((t) / SECADAY)
+#define HOUR(t) (((t) % SECADAY) / SECAHOUR)
+#define MIN(t) (((t) % SECAHOUR) / SECAMIN)
+#define SEC(t) ((t) % SECAMIN)
+
+char *
+timestr(t)
+{
+ static char s[80];
+
+ if (DAY(t) > 0)
+ (void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t));
+ else if (HOUR(t) > 0)
+ (void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t));
+ else if (MIN(t) > 0)
+ (void)sprintf(s, "%d:%02d", MIN(t), SEC(t));
+ else if (SEC(t) > 0)
+ (void)sprintf(s, ":%02d", SEC(t));
+ else
+ *s = '\0';
+
+ return (s);
+}
+
+log_score(list_em)
+{
+ register int i, fd, num_scores = 0, good, changed = 0, found = 0;
+ struct passwd *pw;
+ FILE *fp;
+ char *cp, *index(), *rindex();
+ SCORE score[100], thisscore;
+#ifdef SYSV
+ struct utsname name;
+#endif
+
+ umask(0);
+ fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0644);
+ if (fd < 0) {
+ perror(_PATH_SCORE);
+ return (-1);
+ }
+ /*
+ * This is done to take advantage of stdio, while still
+ * allowing a O_CREAT during the open(2) of the log file.
+ */
+ fp = fdopen(fd, "r+");
+ if (fp == NULL) {
+ perror(_PATH_SCORE);
+ return (-1);
+ }
+#ifdef BSD
+ if (flock(fileno(fp), LOCK_EX) < 0)
+#endif
+#ifdef SYSV
+ while (lockf(fileno(fp), F_LOCK, 1) < 0)
+#endif
+ {
+ perror("flock");
+ return (-1);
+ }
+ for (;;) {
+ good = fscanf(fp, "%s %s %s %d %d %d",
+ score[num_scores].name,
+ score[num_scores].host,
+ score[num_scores].game,
+ &score[num_scores].planes,
+ &score[num_scores].time,
+ &score[num_scores].real_time);
+ if (good != 6 || ++num_scores >= NUM_SCORES)
+ break;
+ }
+ if (!test_mode && !list_em) {
+ if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) {
+ fprintf(stderr,
+ "getpwuid failed for uid %d. Who are you?\n",
+ getuid());
+ return (-1);
+ }
+ strcpy(thisscore.name, pw->pw_name);
+#ifdef BSD
+ if (gethostname(thisscore.host, sizeof (thisscore.host)) < 0) {
+ perror("gethostname");
+ return (-1);
+ }
+#endif
+#ifdef SYSV
+ uname(&name);
+ strcpy(thisscore.host, name.sysname);
+#endif
+
+ cp = rindex(file, '/');
+ if (cp == NULL) {
+ fprintf(stderr, "log: where's the '/' in %s?\n", file);
+ return (-1);
+ }
+ cp++;
+ strcpy(thisscore.game, cp);
+
+ thisscore.time = clck;
+ thisscore.planes = safe_planes;
+ thisscore.real_time = time(0) - start_time;
+
+ for (i = 0; i < num_scores; i++) {
+ if (strcmp(thisscore.name, score[i].name) == 0 &&
+ strcmp(thisscore.host, score[i].host) == 0 &&
+ strcmp(thisscore.game, score[i].game) == 0) {
+ if (thisscore.time > score[i].time) {
+ score[i].time = thisscore.time;
+ score[i].planes = thisscore.planes;
+ score[i].real_time =
+ thisscore.real_time;
+ changed++;
+ }
+ found++;
+ break;
+ }
+ }
+ if (!found) {
+ for (i = 0; i < num_scores; i++) {
+ if (thisscore.time > score[i].time) {
+ if (num_scores < NUM_SCORES)
+ num_scores++;
+ bcopy(&score[i],
+ &score[num_scores - 1],
+ sizeof (score[i]));
+ bcopy(&thisscore, &score[i],
+ sizeof (score[i]));
+ changed++;
+ break;
+ }
+ }
+ }
+ if (!found && !changed && num_scores < NUM_SCORES) {
+ bcopy(&thisscore, &score[num_scores],
+ sizeof (score[num_scores]));
+ num_scores++;
+ changed++;
+ }
+
+ if (changed) {
+ if (found)
+ puts("You beat your previous score!");
+ else
+ puts("You made the top players list!");
+ qsort(score, num_scores, sizeof (*score), compar);
+ rewind(fp);
+ for (i = 0; i < num_scores; i++)
+ fprintf(fp, "%s %s %s %d %d %d\n",
+ score[i].name, score[i].host,
+ score[i].game, score[i].planes,
+ score[i].time, score[i].real_time);
+ } else {
+ if (found)
+ puts("You didn't beat your previous score.");
+ else
+ puts("You didn't make the top players list.");
+ }
+ putchar('\n');
+ }
+#ifdef BSD
+ flock(fileno(fp), LOCK_UN);
+#endif
+#ifdef SYSV
+ /* lock will evaporate upon close */
+#endif
+ fclose(fp);
+ printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name", "host",
+ "game", "time", "real time", "planes safe");
+ puts("-------------------------------------------------------------------------------");
+ for (i = 0; i < num_scores; i++) {
+ cp = index(score[i].host, '.');
+ if (cp != NULL)
+ *cp = '\0';
+ printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1,
+ score[i].name, score[i].host, score[i].game,
+ score[i].time, timestr(score[i].real_time),
+ score[i].planes);
+ }
+ putchar('\n');
+ return (0);
+}
diff --git a/atc/main.c b/atc/main.c
new file mode 100644
index 00000000..e4ce3d0f
--- /dev/null
+++ b/atc/main.c
@@ -0,0 +1,326 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 3/5/91";
+#endif /* not lint */
+
+#include "include.h"
+#include "pathnames.h"
+
+main(ac, av)
+ char *av[];
+{
+ int seed;
+ int f_usage = 0, f_list = 0, f_showscore = 0;
+ int f_printpath = 0;
+ char *file = NULL;
+ char *name, *ptr;
+#ifdef BSD
+ struct itimerval itv;
+#endif
+ extern char *default_game(), *okay_game();
+ extern void log_score(), quit(), update();
+
+ start_time = seed = time(0);
+
+ name = *av++;
+ while (*av) {
+#ifndef SAVEDASH
+ if (**av == '-')
+ *++*av;
+ else
+ break;
+#endif
+ ptr = *av++;
+ while (*ptr) {
+ switch (*ptr) {
+ case '?':
+ case 'u':
+ f_usage++;
+ break;
+ case 'l':
+ f_list++;
+ break;
+ case 's':
+ case 't':
+ f_showscore++;
+ break;
+ case 'p':
+ f_printpath++;
+ break;
+ case 'r':
+ seed = atoi(*av);
+ av++;
+ break;
+ case 'f':
+ case 'g':
+ file = *av;
+ av++;
+ break;
+ default:
+ fprintf(stderr, "Unknown option '%c'\n", *ptr,
+ name);
+ f_usage++;
+ break;
+ }
+ ptr++;
+ }
+ }
+ srandom(seed);
+
+ if (f_usage)
+ fprintf(stderr,
+ "Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
+ name);
+ if (f_showscore)
+ log_score(1);
+ if (f_list)
+ list_games();
+ if (f_printpath) {
+ char buf[100];
+
+ strcpy(buf, _PATH_GAMES);
+ buf[strlen(buf) - 1] = '\0';
+ puts(buf);
+ }
+
+ if (f_usage || f_showscore || f_list || f_printpath)
+ exit(0);
+
+ if (file == NULL)
+ file = default_game();
+ else
+ file = okay_game(file);
+
+ if (file == NULL || read_file(file) < 0)
+ exit(1);
+
+ init_gr();
+ setup_screen(sp);
+
+ addplane();
+
+ signal(SIGINT, quit);
+ signal(SIGQUIT, quit);
+#ifdef BSD
+ signal(SIGTSTP, SIG_IGN);
+ signal(SIGSTOP, SIG_IGN);
+#endif
+ signal(SIGHUP, log_score);
+ signal(SIGTERM, log_score);
+
+#ifdef BSD
+ ioctl(fileno(stdin), TIOCGETP, &tty_start);
+ bcopy(&tty_start, &tty_new, sizeof(tty_new));
+ tty_new.sg_flags |= CBREAK;
+ tty_new.sg_flags &= ~ECHO;
+ ioctl(fileno(stdin), TIOCSETP, &tty_new);
+#endif
+
+#ifdef SYSV
+ ioctl(fileno(stdin), TCGETA, &tty_start);
+ bcopy(&tty_start, &tty_new, sizeof(tty_new));
+ tty_new.c_lflag &= ~ICANON;
+ tty_new.c_lflag &= ~ECHO;
+ tty_new.c_cc[VMIN] = 1;
+ tty_new.c_cc[VTIME] = 0;
+ ioctl(fileno(stdin), TCSETAW, &tty_new);
+#endif
+
+ signal(SIGALRM, update);
+
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 1;
+ itv.it_interval.tv_sec = sp->update_secs;
+ itv.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(sp->update_secs);
+#endif
+
+ for (;;) {
+ if (getcommand() != 1)
+ planewin();
+ else {
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(0);
+#endif
+
+ update();
+
+#ifdef BSD
+ itv.it_value.tv_sec = sp->update_secs;
+ itv.it_value.tv_usec = 0;
+ itv.it_interval.tv_sec = sp->update_secs;
+ itv.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(sp->update_secs);
+#endif
+ }
+ }
+}
+
+read_file(s)
+ char *s;
+{
+ extern FILE *yyin;
+ int retval;
+
+ file = s;
+ yyin = fopen(s, "r");
+ if (yyin == NULL) {
+ perror(s);
+ return (-1);
+ }
+ retval = yyparse();
+ fclose(yyin);
+
+ if (retval != 0)
+ return (-1);
+ else
+ return (0);
+}
+
+char *
+default_game()
+{
+ FILE *fp;
+ static char file[256];
+ char line[256], games[256];
+
+ strcpy(games, _PATH_GAMES);
+ strcat(games, GAMES);
+
+ if ((fp = fopen(games, "r")) == NULL) {
+ perror(games);
+ return (NULL);
+ }
+ if (fgets(line, sizeof(line), fp) == NULL) {
+ fprintf(stderr, "%s: no default game available\n", games);
+ return (NULL);
+ }
+ fclose(fp);
+ line[strlen(line) - 1] = '\0';
+ strcpy(file, _PATH_GAMES);
+ strcat(file, line);
+ return (file);
+}
+
+char *
+okay_game(s)
+ char *s;
+{
+ FILE *fp;
+ static char file[256];
+ char *ret = NULL, line[256], games[256];
+
+ strcpy(games, _PATH_GAMES);
+ strcat(games, GAMES);
+
+ if ((fp = fopen(games, "r")) == NULL) {
+ perror(games);
+ return (NULL);
+ }
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ line[strlen(line) - 1] = '\0';
+ if (strcmp(s, line) == 0) {
+ strcpy(file, _PATH_GAMES);
+ strcat(file, line);
+ ret = file;
+ break;
+ }
+ }
+ fclose(fp);
+ if (ret == NULL) {
+ test_mode = 1;
+ ret = s;
+ fprintf(stderr, "%s: %s: game not found\n", games, s);
+ fprintf(stderr, "Your score will not be logged.\n");
+ sleep(2); /* give the guy time to read it */
+ }
+ return (ret);
+}
+
+list_games()
+{
+ FILE *fp;
+ char line[256], games[256];
+ int num_games = 0;
+
+ strcpy(games, _PATH_GAMES);
+ strcat(games, GAMES);
+
+ if ((fp = fopen(games, "r")) == NULL) {
+ perror(games);
+ return (-1);
+ }
+ puts("available games:");
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ printf(" %s", line);
+ num_games++;
+ }
+ fclose(fp);
+ if (num_games == 0) {
+ fprintf(stderr, "%s: no games available\n", games);
+ return (-1);
+ }
+ return (0);
+}
diff --git a/atc/pathnames.h b/atc/pathnames.h
new file mode 100644
index 00000000..72aae534
--- /dev/null
+++ b/atc/pathnames.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.4 (Berkeley) 4/30/90
+ */
+
+#include <paths.h>
+
+#define _PATH_GAMES "/usr/share/games/atc/"
+#define _PATH_SCORE "/var/games/atc_score"
diff --git a/atc/struct.h b/atc/struct.h
new file mode 100644
index 00000000..3a5ab490
--- /dev/null
+++ b/atc/struct.h
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)struct.h 5.2 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+typedef struct {
+ int x, y;
+ int dir; /* used only sometimes */
+} SCREEN_POS;
+
+typedef struct {
+ SCREEN_POS p1, p2;
+} LINE;
+
+typedef SCREEN_POS EXIT;
+typedef SCREEN_POS BEACON;
+typedef SCREEN_POS AIRPORT;
+
+typedef struct {
+ int width, height;
+ int update_secs;
+ int newplane_time;
+ int num_exits;
+ int num_lines;
+ int num_beacons;
+ int num_airports;
+ EXIT *exit;
+ LINE *line;
+ BEACON *beacon;
+ AIRPORT *airport;
+} C_SCREEN;
+
+typedef struct plane {
+ struct plane *next, *prev;
+ int status;
+ int plane_no;
+ int plane_type;
+ int orig_no;
+ int orig_type;
+ int dest_no;
+ int dest_type;
+ int altitude;
+ int new_altitude;
+ int dir;
+ int new_dir;
+ int fuel;
+ int xpos;
+ int ypos;
+ int delayd;
+ int delayd_no;
+} PLANE;
+
+typedef struct {
+ PLANE *head, *tail;
+} LIST;
+
+typedef struct {
+ char name[10];
+ char host[256];
+ char game[256];
+ int planes;
+ int time;
+ int real_time;
+} SCORE;
+
+typedef struct displacement {
+ int dx;
+ int dy;
+} DISPLACEMENT;
diff --git a/atc/tunable.c b/atc/tunable.c
new file mode 100644
index 00000000..b6eb4559
--- /dev/null
+++ b/atc/tunable.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tunable.c 5.4 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+/*
+ * NUM_SCORES - Number of scores that are kept track of.
+ * Keep this greater than 0, but less than 100.
+ * 4 lines are printed above the score, one below + your prompt, so
+ * to prevent scrolling: 6 + NUM_SCORES <= 24 (lines on an average terminal).
+ */
+int NUM_SCORES = 18;
diff --git a/atc/tunable.h b/atc/tunable.h
new file mode 100644
index 00000000..8ae00b02
--- /dev/null
+++ b/atc/tunable.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tunable.h 5.3 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+extern int NUM_SCORES;
diff --git a/atc/update.c b/atc/update.c
new file mode 100644
index 00000000..4e8a4edb
--- /dev/null
+++ b/atc/update.c
@@ -0,0 +1,410 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)update.c 5.5 (Berkeley) 10/30/90";
+#endif not lint
+
+#include "include.h"
+
+update()
+{
+ int i, dir_diff, mask, unclean;
+ PLANE *pp, *p1, *p2, *p;
+
+#ifdef BSD
+ mask = sigblock(sigmask(SIGINT));
+#endif
+#ifdef SYSV
+ alarm(0);
+ signal(SIGALRM, update);
+#endif
+
+ clck++;
+
+ erase_all();
+
+ /* put some planes in the air */
+ do {
+ unclean = 0;
+ for (pp = ground.head; pp != NULL; pp = pp->next) {
+ if (pp->new_altitude > 0) {
+ delete(&ground, pp);
+ append(&air, pp);
+ unclean = 1;
+ break;
+ }
+ }
+ } while (unclean);
+
+ /* do altitude change and basic movement */
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ /* type 0 only move every other turn */
+ if (pp->plane_type == 0 && clck & 1)
+ continue;
+
+ pp->fuel--;
+ if (pp->fuel < 0)
+ loser(pp, "ran out of fuel.");
+
+ pp->altitude += SGN(pp->new_altitude - pp->altitude);
+
+ if (!pp->delayd) {
+ dir_diff = pp->new_dir - pp->dir;
+ /*
+ * Allow for circle commands
+ */
+ if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) {
+ if (dir_diff > MAXDIR/2)
+ dir_diff -= MAXDIR;
+ else if (dir_diff < -(MAXDIR/2))
+ dir_diff += MAXDIR;
+ }
+ if (dir_diff > 2)
+ dir_diff = 2;
+ else if (dir_diff < -2)
+ dir_diff = -2;
+ pp->dir += dir_diff;
+ if (pp->dir >= MAXDIR)
+ pp->dir -= MAXDIR;
+ else if (pp->dir < 0)
+ pp->dir += MAXDIR;
+ }
+ pp->xpos += displacement[pp->dir].dx;
+ pp->ypos += displacement[pp->dir].dy;
+
+ if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x &&
+ pp->ypos == sp->beacon[pp->delayd_no].y) {
+ pp->delayd = 0;
+ if (pp->status == S_UNMARKED)
+ pp->status = S_MARKED;
+ }
+
+ switch (pp->dest_type) {
+ case T_AIRPORT:
+ if (pp->xpos == sp->airport[pp->dest_no].x &&
+ pp->ypos == sp->airport[pp->dest_no].y &&
+ pp->altitude == 0) {
+ if (pp->dir != sp->airport[pp->dest_no].dir)
+ loser(pp, "landed in the wrong direction.");
+ else {
+ pp->status = S_GONE;
+ continue;
+ }
+ }
+ break;
+ case T_EXIT:
+ if (pp->xpos == sp->exit[pp->dest_no].x &&
+ pp->ypos == sp->exit[pp->dest_no].y) {
+ if (pp->altitude != 9)
+ loser(pp, "exited at the wrong altitude.");
+ else {
+ pp->status = S_GONE;
+ continue;
+ }
+ }
+ break;
+ default:
+ loser(pp, "has a bizarre destination, get help!");
+ }
+ if (pp->altitude > 9)
+ /* "this is impossible" */
+ loser(pp, "exceded flight ceiling.");
+ if (pp->altitude <= 0) {
+ for (i = 0; i < sp->num_airports; i++)
+ if (pp->xpos == sp->airport[i].x &&
+ pp->ypos == sp->airport[i].y) {
+ if (pp->dest_type == T_AIRPORT)
+ loser(pp,
+ "landed at the wrong airport.");
+ else
+ loser(pp,
+ "landed instead of exited.");
+ }
+ loser(pp, "crashed on the ground.");
+ }
+ if (pp->xpos < 1 || pp->xpos >= sp->width - 1 ||
+ pp->ypos < 1 || pp->ypos >= sp->height - 1) {
+ for (i = 0; i < sp->num_exits; i++)
+ if (pp->xpos == sp->exit[i].x &&
+ pp->ypos == sp->exit[i].y) {
+ if (pp->dest_type == T_EXIT)
+ loser(pp,
+ "exited via the wrong exit.");
+ else
+ loser(pp,
+ "exited instead of landed.");
+ }
+ loser(pp, "illegally left the flight arena.");
+ }
+ }
+
+ /*
+ * Traverse the list once, deleting the planes that are gone.
+ */
+ for (pp = air.head; pp != NULL; pp = p2) {
+ p2 = pp->next;
+ if (pp->status == S_GONE) {
+ safe_planes++;
+ delete(&air, pp);
+ }
+ }
+
+ draw_all();
+
+ for (p1 = air.head; p1 != NULL; p1 = p1->next)
+ for (p2 = p1->next; p2 != NULL; p2 = p2->next)
+ if (too_close(p1, p2, 1)) {
+ static char buf[80];
+
+ (void)sprintf(buf, "collided with plane '%c'.",
+ name(p2));
+ loser(p1, buf);
+ }
+ /*
+ * Check every other update. Actually, only add on even updates.
+ * Otherwise, prop jobs show up *on* entrance. Remember that
+ * we don't update props on odd updates.
+ */
+ if ((rand() % sp->newplane_time) == 0)
+ addplane();
+
+#ifdef BSD
+ sigsetmask(mask);
+#endif
+#ifdef SYSV
+ alarm(sp->update_secs);
+#endif
+}
+
+char *
+command(pp)
+ PLANE *pp;
+{
+ static char buf[50], *bp, *comm_start;
+ char *index();
+
+ buf[0] = '\0';
+ bp = buf;
+ (void)sprintf(bp, "%c%d%c%c%d: ", name(pp), pp->altitude,
+ (pp->fuel < LOWFUEL) ? '*' : ' ',
+ (pp->dest_type == T_AIRPORT) ? 'A' : 'E', pp->dest_no);
+
+ comm_start = bp = index(buf, '\0');
+ if (pp->altitude == 0)
+ (void)sprintf(bp, "Holding @ A%d", pp->orig_no);
+ else if (pp->new_dir >= MAXDIR || pp->new_dir < 0)
+ strcpy(bp, "Circle");
+ else if (pp->new_dir != pp->dir)
+ (void)sprintf(bp, "%d", dir_deg(pp->new_dir));
+
+ bp = index(buf, '\0');
+ if (pp->delayd)
+ (void)sprintf(bp, " @ B%d", pp->delayd_no);
+
+ bp = index(buf, '\0');
+ if (*comm_start == '\0' &&
+ (pp->status == S_UNMARKED || pp->status == S_IGNORED))
+ strcpy(bp, "---------");
+ return (buf);
+}
+
+/* char */
+name(p)
+ PLANE *p;
+{
+ if (p->plane_type == 0)
+ return ('A' + p->plane_no);
+ else
+ return ('a' + p->plane_no);
+}
+
+number(l)
+{
+ if (l < 'a' && l > 'z' && l < 'A' && l > 'Z')
+ return (-1);
+ else if (l >= 'a' && l <= 'z')
+ return (l - 'a');
+ else
+ return (l - 'A');
+}
+
+next_plane()
+{
+ static int last_plane = -1;
+ PLANE *pp;
+ int found, start_plane = last_plane;
+
+ do {
+ found = 0;
+ last_plane++;
+ if (last_plane >= 26)
+ last_plane = 0;
+ for (pp = air.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == last_plane) {
+ found++;
+ break;
+ }
+ if (!found)
+ for (pp = ground.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == last_plane) {
+ found++;
+ break;
+ }
+ } while (found && last_plane != start_plane);
+ if (last_plane == start_plane)
+ return (-1);
+ return (last_plane);
+}
+
+addplane()
+{
+ PLANE p, *pp, *p1;
+ int i, num_starts, close, rnd, rnd2, pnum;
+
+ bzero(&p, sizeof (p));
+
+ p.status = S_MARKED;
+ p.plane_type = random() % 2;
+
+ num_starts = sp->num_exits + sp->num_airports;
+ rnd = random() % num_starts;
+
+ if (rnd < sp->num_exits) {
+ p.dest_type = T_EXIT;
+ p.dest_no = rnd;
+ } else {
+ p.dest_type = T_AIRPORT;
+ p.dest_no = rnd - sp->num_exits;
+ }
+
+ /* loop until we get a plane not near another */
+ for (i = 0; i < num_starts; i++) {
+ /* loop till we get a different start point */
+ while ((rnd2 = random() % num_starts) == rnd)
+ ;
+ if (rnd2 < sp->num_exits) {
+ p.orig_type = T_EXIT;
+ p.orig_no = rnd2;
+ p.xpos = sp->exit[rnd2].x;
+ p.ypos = sp->exit[rnd2].y;
+ p.new_dir = p.dir = sp->exit[rnd2].dir;
+ p.altitude = p.new_altitude = 7;
+ close = 0;
+ for (p1 = air.head; p1 != NULL; p1 = p1->next)
+ if (too_close(p1, &p, 4)) {
+ close++;
+ break;
+ }
+ if (close)
+ continue;
+ } else {
+ p.orig_type = T_AIRPORT;
+ p.orig_no = rnd2 - sp->num_exits;
+ p.xpos = sp->airport[p.orig_no].x;
+ p.ypos = sp->airport[p.orig_no].y;
+ p.new_dir = p.dir = sp->airport[p.orig_no].dir;
+ p.altitude = p.new_altitude = 0;
+ }
+ p.fuel = sp->width + sp->height;
+ break;
+ }
+ if (i >= num_starts)
+ return (-1);
+ pnum = next_plane();
+ if (pnum < 0)
+ return (-1);
+ p.plane_no = pnum;
+
+ pp = newplane();
+ bcopy(&p, pp, sizeof (p));
+
+ if (pp->orig_type == T_AIRPORT)
+ append(&ground, pp);
+ else
+ append(&air, pp);
+
+ return (pp->dest_type);
+}
+
+PLANE *
+findplane(n)
+{
+ PLANE *pp;
+
+ for (pp = air.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == n)
+ return (pp);
+ for (pp = ground.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == n)
+ return (pp);
+ return (NULL);
+}
+
+too_close(p1, p2, dist)
+ PLANE *p1, *p2;
+{
+ if (ABS(p1->altitude - p2->altitude) <= dist &&
+ ABS(p1->xpos - p2->xpos) <= dist && ABS(p1->ypos - p2->ypos) <= dist)
+ return (1);
+ else
+ return (0);
+}
+
+dir_deg(d)
+{
+ switch (d) {
+ case 0: return (0);
+ case 1: return (45);
+ case 2: return (90);
+ case 3: return (135);
+ case 4: return (180);
+ case 5: return (225);
+ case 6: return (270);
+ case 7: return (315);
+ default:
+ return (-1);
+ }
+}
diff --git a/backgammon/Makefile b/backgammon/Makefile
new file mode 100644
index 00000000..01b2160a
--- /dev/null
+++ b/backgammon/Makefile
@@ -0,0 +1,5 @@
+# @(#)Makefile 5.1 (Berkeley) 6/17/90
+
+SUBDIR= backgammon teachgammon
+
+.include <bsd.subdir.mk>
diff --git a/backgammon/backgammon/Makefile b/backgammon/backgammon/Makefile
new file mode 100644
index 00000000..99f49252
--- /dev/null
+++ b/backgammon/backgammon/Makefile
@@ -0,0 +1,14 @@
+# @(#)Makefile 5.16 (Berkeley) 5/11/90
+
+PROG= backgammon
+CFLAGS+=-DV7 -I${.CURDIR}/../common_source
+SRCS= allow.c board.c check.c extra.c fancy.c init.c main.c move.c \
+ odds.c one.c save.c subs.c table.c text.c version.c
+MAN6= backgammon.0
+DPADD= ${LIBTERM} ${LIBCOMPAT}
+LDADD= -ltermcap -lcompat
+.PATH: ${.CURDIR}/../common_source
+HIDEGAME=hidegame
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/backgammon/backgammon/backgammon.6 b/backgammon/backgammon/backgammon.6
new file mode 100644
index 00000000..3718acb6
--- /dev/null
+++ b/backgammon/backgammon/backgammon.6
@@ -0,0 +1,205 @@
+.\" Copyright (c) 1980 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)backgammon.6 6.6 (Berkeley) 8/3/91
+.\"
+.TH BACKGAMMON 6 "August 3, 1991"
+.UC 5
+.SH NAME
+backgammon \- the game of backgammon
+.SH SYNOPSIS
+.B backgammon
+[ - ] [ n r w b pr pw pb t\c
+.I term
+s\c
+.I file
+]
+.SH DESCRIPTION
+This program lets you play backgammon against the computer
+or against a "friend".
+All commands only are one letter,
+so you don't need to type a carriage return,
+except at the end of a move.
+The program is mostly self documenting,
+so that a question mark (?) will usually get some help.
+If you answer `y' when the program asks if you want the rules,
+you will get text explaining the rules of the game,
+some hints on strategy,
+instruction on how to use the program,
+and a tutorial consisting of a practice game against the computer.
+A description of how to use the program can be
+obtained by answering `y' when it asks if you want instructions.
+.PP
+The possible arguments for backgammon
+(most are unnecessary but some are very convenient)
+consist of:
+.ne 11
+.PP
+.na
+.TP 8
+.B n
+don't ask for rules or instructions
+.TP 8
+.B r
+player is red (implies n)
+.TP 8
+.B w
+player is white (implies n)
+.TP 8
+.B b
+two players, red and white (implies n)
+.TP 8
+.B pr
+print the board before red's turn
+.TP 8
+.B pw
+print the board before white's turn
+.TP 8
+.B pb
+print the board before both player's turn
+.TP 8
+.B t\fIterm
+terminal is type
+.IR term ,
+uses /etc/termcap
+.TP 8
+.B s\fIfile
+recover previously saved game from
+.IR file .
+(This can also be done by executing the saved file,
+i.e., typing its name in as a command)
+.ad
+.PP
+Arguments may be optionally preceded by a `-'.
+Several arguments may be concatenated together,
+but not after `s' or `t' arguments,
+since they can be followed by an arbitrary string.
+Any unrecognized arguments are ignored.
+An argument of a lone `-' gets a description of possible arguments.
+.PP
+If
+.IR term
+has capabilities for direct cursor movement (see
+.IR termcap (5))
+.IR backgammon
+``fixes'' the board after each move,
+so the board does not need to be reprinted,
+unless the screen suffers some horrendous malady.
+Also, any `p' option will be ignored.
+(The `t' option is not necessary unless the terminal type does not match
+the entry in the /etc/termcap data base.)
+.SH QUICK\ REFERENCE
+When the program prompts by typing only your color,
+type a space or carriage return to roll, or
+.ne 5
+.PP
+.na
+.TP 8
+.B d
+to double
+.TP 8
+.B p
+to print the board
+.TP 8
+.B q
+to quit
+.TP 8
+.B s
+to save the game for later
+.PP
+.i0
+.ad
+When the program prompts with 'Move:', type
+.ne 4
+.PP
+.na
+.TP 8
+.B p
+to print the board
+.TP 8
+.B q
+to quit
+.TP 8
+.B s
+to save the game
+.ad
+.i0
+.PP
+or a
+.IR move ,
+which is a sequence of
+.ne 4
+.PP
+.na
+.TP 8
+.B s-f
+move from
+.BR s
+to
+.BR f
+.TP 8
+.B s/r
+move one man on
+.BR s
+the roll
+.BR r
+.ad
+.PP
+separated by commas or spaces and ending with a newline.
+Available abbreviations are
+.ne 4
+.PP
+.na
+.TP 10
+.B s-f1-f2
+means
+.BR s-f1,f1-f2
+.TP 10
+.B s/r1r2
+means
+.BR s/r1,s/r2
+.ad
+.PP
+Use `b' for bar and `h' for home,
+or 0 or 25 as appropriate.
+.SH AUTHOR
+Alan Char
+.SH FILES
+.TP 25
+/usr/games/teachgammon
+\- rules and tutorial
+.br
+.TP 25
+/etc/termcap
+\- terminal capabilities
+.SH BUGS
+.PP
+The program's strategy needs much work.
diff --git a/backgammon/backgammon/extra.c b/backgammon/backgammon/extra.c
new file mode 100644
index 00000000..36ca1dd5
--- /dev/null
+++ b/backgammon/backgammon/extra.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)extra.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+FILE *trace;
+#endif
+
+/*
+ * dble()
+ * Have the current player double and ask opponent to accept.
+ */
+
+dble () {
+ register int resp; /* response to y/n */
+
+ for (;;) {
+ writel (" doubles."); /* indicate double */
+
+ if (cturn == -pnum) { /* see if computer accepts */
+ if (dblgood()) { /* guess not */
+ writel (" Declined.\n");
+ nexturn();
+ cturn *= -2; /* indicate loss */
+ return;
+ } else { /* computer accepts */
+ writel (" Accepted.\n");
+ gvalue *= 2; /* double game value */
+ dlast = cturn;
+ if (tflag)
+ gwrite();
+ return;
+ }
+ }
+
+ /* ask if player accepts */
+ writel (" Does ");
+ writel (cturn == 1? color[2]: color[3]);
+ writel (" accept?");
+
+ /* get response from yorn,
+ * a "2" means he said "p"
+ * for print board. */
+ if ((resp = yorn ('R')) == 2) {
+ writel (" Reprint.\n");
+ buflush();
+ wrboard();
+ writel (*Colorptr);
+ continue;
+ }
+
+ /* check response */
+ if (resp) {
+ /* accepted */
+ gvalue *= 2;
+ dlast = cturn;
+ if (tflag)
+ gwrite();
+ return;
+ }
+
+ nexturn (); /* declined */
+ cturn *= -2;
+ return;
+ }
+}
+
+/*
+ * dblgood ()
+ * Returns 1 if the computer would double in this position. This
+ * is not an exact science. The computer will decline a double that he
+ * would have made. Accumulated judgments are kept in the variable n,
+ * which is in "pips", i.e., the position of each man summed over all
+ * men, with opponent's totals negative. Thus, n should have a positive
+ * value of 7 for each move ahead, or a negative value of 7 for each one
+ * behind.
+ */
+
+dblgood () {
+ register int n; /* accumulated judgment */
+ register int OFFC = *offptr; /* no. of computer's men off */
+ register int OFFO = *offopp; /* no. of player's men off */
+
+#ifdef DEBUG
+ register int i;
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+#endif
+
+ /* get real pip value */
+ n = eval()*cturn;
+#ifdef DEBUG
+ fputs ("\nDoubles:\nBoard: ",trace);
+ for (i = 0; i < 26; i++)
+ fprintf (trace," %d",board[i]);
+ fprintf (trace,"\n\tpip = %d, ",n);
+#endif
+
+ /* below adjusts pip value
+ * according to position
+ * judgments */
+
+ /* check men moving off
+ * board */
+ if (OFFC > -15 || OFFO > -15) {
+ if (OFFC < 0 && OFFO < 0) {
+ OFFC += 15;
+ OFFO += 15;
+ n +=((OFFC-OFFO)*7)/2;
+ } else if (OFFC < 0) {
+ OFFC += 15;
+ n -= OFFO*7/2;
+ } else if (OFFO < 0) {
+ OFFO += 15;
+ n += OFFC*7/2;
+ }
+ if (OFFC < 8 && OFFO > 8)
+ n -= 7;
+ if (OFFC < 10 && OFFO > 10)
+ n -= 7;
+ if (OFFC < 12 && OFFO > 12)
+ n -= 7;
+ if (OFFO < 8 && OFFC > 8)
+ n += 7;
+ if (OFFO < 10 && OFFC > 10)
+ n += 7;
+ if (OFFO < 12 && OFFC > 12)
+ n += 7;
+ n += ((OFFC-OFFO)*7)/2;
+ }
+
+#ifdef DEBUG
+ fprintf (trace,"off = %d, ",n);
+#endif
+
+ /* see if men are trapped */
+ n -= freemen(bar);
+ n += freemen(home);
+ n += trapped(home,-cturn);
+ n -= trapped(bar,cturn);
+
+#ifdef DEBUG
+ fprintf (trace,"free = %d\n",n);
+ fprintf (trace,"\tOFFC = %d, OFFO = %d\n",OFFC,OFFO);
+ fflush (trace);
+#endif
+
+ /* double if 2-3 moves ahead */
+ if (n > 10+rnum(7))
+ return(1);
+ return (0);
+}
+
+freemen (b)
+int b;
+
+{
+ register int i, inc, lim;
+
+ odds(0,0,0);
+ if (board[b] == 0)
+ return (0);
+ inc = (b == 0? 1: -1);
+ lim = (b == 0? 7: 18);
+ for (i = b+inc; i != lim; i += inc)
+ if (board[i]*inc < -1)
+ odds(abs(b-i),0,abs(board[b]));
+ if (abs(board[b]) == 1)
+ return ((36-count())/5);
+ return (count()/5);
+}
+
+trapped (n,inc)
+int n, inc;
+
+{
+ register int i, j, k;
+ int c, l, ct;
+
+ ct = 0;
+ l = n+7*inc;
+ for (i = n+inc; i != l; i += inc) {
+ odds (0,0,0);
+ c = abs(i-l);
+ if (board[i]*inc > 0) {
+ for (j = c; j < 13; j++)
+ if (board[i+inc*j]*inc < -1) {
+ if (j < 7)
+ odds (j,0,1);
+ for (k = 1; k < 7 && k < j; k++)
+ if (j-k < 7)
+ odds (k,j-k,1);
+ }
+ ct += abs(board[i])*(36-count());
+ }
+ }
+ return (ct/5);
+}
+
+eval () {
+
+ register int i, j;
+
+ for (j = i = 0; i < 26; i++)
+ j += (board[i] >= 0 ? i*board[i] : (25-i)*board[i]);
+
+ if (off[1] >= 0)
+ j += 25*off[1];
+ else
+ j += 25*(off[1]+15);
+
+ if (off[0] >= 0)
+ j -= 25*off[0];
+ else
+ j -= 25*(off[0]+15);
+ return (j);
+}
diff --git a/backgammon/backgammon/main.c b/backgammon/backgammon/main.c
new file mode 100644
index 00000000..82d496a1
--- /dev/null
+++ b/backgammon/backgammon/main.c
@@ -0,0 +1,591 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "back.h"
+
+#define MVPAUSE 5 /* time to sleep when stuck */
+#define MAXUSERS 35 /* maximum number of users */
+
+char *instr[]; /* text of instructions */
+char *message[]; /* update message */
+char ospeed; /* tty output speed */
+
+char *helpm[] = { /* help message */
+ "Enter a space or newline to roll, or",
+ " R to reprint the board\tD to double",
+ " S to save the game\tQ to quit",
+ 0
+};
+
+char *contin[] = { /* pause message */
+ "(Type a newline to continue.)",
+ "",
+ 0
+};
+
+static char user1a[] =
+ "Sorry, you cannot play backgammon when there are more than ";
+static char user1b[] =
+ " users\non the system.";
+static char user2a[] =
+ "\nThere are now more than ";
+static char user2b[] =
+ " users on the system, so you cannot play\nanother game. ";
+static char rules[] = "\nDo you want the rules of the game?";
+static char noteach[] = "Teachgammon not available!\n\007";
+static char need[] = "Do you need instructions for this program?";
+static char askcol[] =
+ "Enter 'r' to play red, 'w' to play white, 'b' to play both:";
+static char rollr[] = "Red rolls a ";
+static char rollw[] = ". White rolls a ";
+static char rstart[] = ". Red starts.\n";
+static char wstart[] = ". White starts.\n";
+static char toobad1[] = "Too bad, ";
+static char unable[] = " is unable to use that roll.\n";
+static char toobad2[] = ". Too bad, ";
+static char cantmv[] = " can't move.\n";
+static char bgammon[] = "Backgammon! ";
+static char gammon[] = "Gammon! ";
+static char again[] = ".\nWould you like to play again?";
+static char svpromt[] = "Would you like to save this game?";
+
+static char password[] = "losfurng";
+static char pbuf[10];
+
+main (argc,argv)
+int argc;
+char **argv;
+
+{
+ register int i; /* non-descript index */
+ register int l; /* non-descript index */
+ register char c; /* non-descript character storage */
+ long t; /* time for random num generator */
+
+ /* initialization */
+ bflag = 2; /* default no board */
+ signal (2,getout); /* trap interrupts */
+ if (gtty (0,&tty) == -1) /* get old tty mode */
+ errexit ("backgammon(gtty)");
+ old = tty.sg_flags;
+#ifdef V7
+ raw = ((noech = old & ~ECHO) | CBREAK); /* set up modes */
+#else
+ raw = ((noech = old & ~ECHO) | RAW); /* set up modes */
+#endif
+ ospeed = tty.sg_ospeed; /* for termlib */
+
+ /* check user count */
+# ifdef CORY
+ if (ucount() > MAXUSERS) {
+ writel (user1a);
+ wrint (MAXUSERS);
+ writel (user1b);
+ getout();
+ }
+# endif
+
+ /* get terminal
+ * capabilities, and
+ * decide if it can
+ * cursor address */
+ tflag = getcaps (getenv ("TERM"));
+ /* use whole screen
+ * for text */
+ if (tflag)
+ begscr = 0;
+ t = time(0);
+ srandom(t); /* 'random' seed */
+
+#ifdef V7
+ while (*++argv != 0) /* process arguments */
+#else
+ while (*++argv != -1) /* process arguments */
+#endif
+ getarg (&argv);
+ args[acnt] = '\0';
+ if (tflag) { /* clear screen */
+ noech &= ~(CRMOD|XTABS);
+ raw &= ~(CRMOD|XTABS);
+ clear();
+ }
+ fixtty (raw); /* go into raw mode */
+
+ /* check if restored
+ * game and save flag
+ * for later */
+ if (rfl = rflag) {
+ text (message); /* print message */
+ text (contin);
+ wrboard(); /* print board */
+ /* if new game, pretend
+ * to be a non-restored
+ * game */
+ if (cturn == 0)
+ rflag = 0;
+ } else {
+ rscore = wscore = 0; /* zero score */
+ text (message); /* update message
+ * without pausing */
+
+ if (aflag) { /* print rules */
+ writel (rules);
+ if (yorn(0)) {
+
+ fixtty (old); /* restore tty */
+ execl (TEACH,"teachgammon",args,0);
+
+ tflag = 0; /* error! */
+ writel (noteach);
+ exit();
+ } else { /* if not rules, then
+ * instructions */
+ writel (need);
+ if (yorn(0)) { /* print instructions */
+ clear();
+ text (instr);
+ }
+ }
+ }
+
+ init(); /* initialize board */
+
+ if (pnum == 2) { /* ask for color(s) */
+ writec ('\n');
+ writel (askcol);
+ while (pnum == 2) {
+ c = readc();
+ switch (c) {
+
+ case 'R': /* red */
+ pnum = -1;
+ break;
+
+ case 'W': /* white */
+ pnum = 1;
+ break;
+
+ case 'B': /* both */
+ pnum = 0;
+ break;
+
+ case 'P':
+ if (iroll)
+ break;
+ if (tflag)
+ curmove (curr,0);
+ else
+ writec ('\n');
+ writel ("Password:");
+ signal (14,getout);
+ cflag = 1;
+ alarm (10);
+ for (i = 0; i < 10; i++) {
+ pbuf[i] = readc();
+ if (pbuf[i] == '\n')
+ break;
+ }
+ if (i == 10)
+ while (readc() != '\n');
+ alarm (0);
+ cflag = 0;
+ if (i < 10)
+ pbuf[i] = '\0';
+ for (i = 0; i < 9; i++)
+ if (pbuf[i] != password[i])
+ getout();
+ iroll = 1;
+ if (tflag)
+ curmove (curr,0);
+ else
+ writec ('\n');
+ writel (askcol);
+ break;
+
+ default: /* error */
+ writec ('\007');
+ }
+ }
+ } else if (!aflag)
+ /* pause to read
+ * message */
+ text (contin);
+
+ wrboard(); /* print board */
+
+ if (tflag)
+ curmove (18,0);
+ else
+ writec ('\n');
+ }
+ /* limit text to bottom
+ * of screen */
+ if (tflag)
+ begscr = 17;
+
+ for (;;) { /* begin game! */
+ /* initial roll if
+ * needed */
+ if ((! rflag) || raflag)
+ roll();
+
+ /* perform ritual of
+ * first roll */
+ if (! rflag) {
+ if (tflag)
+ curmove (17,0);
+ while (D0 == D1) /* no doubles */
+ roll();
+
+ /* print rolls */
+ writel (rollr);
+ writec (D0+'0');
+ writel (rollw);
+ writec (D1+'0');
+
+ /* winner goes first */
+ if (D0 > D1) {
+ writel (rstart);
+ cturn = 1;
+ } else {
+ writel (wstart);
+ cturn = -1;
+ }
+ }
+
+ /* initalize variables
+ * according to whose
+ * turn it is */
+
+ if (cturn == 1) { /* red */
+ home = 25;
+ bar = 0;
+ inptr = &in[1];
+ inopp = &in[0];
+ offptr = &off[1];
+ offopp = &off[0];
+ Colorptr = &color[1];
+ colorptr = &color[3];
+ colen = 3;
+ } else { /* white */
+ home = 0;
+ bar = 25;
+ inptr = &in[0];
+ inopp = &in[1];
+ offptr = &off[0];
+ offopp = &off[1];
+ Colorptr = &color[0];
+ colorptr = &color[2];
+ colen = 5;
+ }
+
+ /* do first move
+ * (special case) */
+ if (! (rflag && raflag)) {
+ if (cturn == pnum) /* computer's move */
+ move (0);
+ else { /* player's move */
+ mvlim = movallow();
+ /* reprint roll */
+ if (tflag)
+ curmove (cturn == -1? 18: 19,0);
+ proll();
+ getmove(); /* get player's move */
+ }
+ }
+ if (tflag) {
+ curmove (17,0);
+ cline();
+ begscr = 18;
+ }
+
+ /* no longer any diff-
+ * erence between normal
+ * game and recovered
+ * game. */
+ rflag = 0;
+
+ /* move as long as it's
+ * someone's turn */
+ while (cturn == 1 || cturn == -1) {
+
+ /* board maintainence */
+ if (tflag)
+ refresh(); /* fix board */
+ else
+ /* redo board if -p */
+ if (cturn == bflag || bflag == 0)
+ wrboard();
+
+ /* do computer's move */
+ if (cturn == pnum) {
+ move (1);
+
+ /* see if double
+ * refused */
+ if (cturn == -2 || cturn == 2)
+ break;
+
+ /* check for winning
+ * move */
+ if (*offopp == 15) {
+ cturn *= -2;
+ break;
+ }
+ continue;
+
+ }
+
+ /* (player's move) */
+
+ /* clean screen if
+ * safe */
+ if (tflag && hflag) {
+ curmove (20,0);
+ clend ();
+ hflag = 1;
+ }
+
+ /* if allowed, give him
+ * a chance to double */
+ if (dlast != cturn && gvalue < 64) {
+ if (tflag)
+ curmove (cturn == -1? 18: 19,0);
+ writel (*Colorptr);
+ c = readc();
+
+ /* character cases */
+ switch (c) {
+
+ /* reprint board */
+ case 'R':
+ wrboard();
+ break;
+
+ /* save game */
+ case 'S':
+ raflag = 1;
+ save (1);
+ break;
+
+ /* quit */
+ case 'Q':
+ quit();
+ break;
+
+ /* double */
+ case 'D':
+ dble();
+ break;
+
+ /* roll */
+ case ' ':
+ case '\n':
+ roll();
+ writel (" rolls ");
+ writec (D0+'0');
+ writec (' ');
+ writec (D1+'0');
+ writel (". ");
+
+ /* see if he can move */
+ if ( (mvlim = movallow()) == 0) {
+
+ /* can't move */
+ writel (toobad1);
+ writel (*colorptr);
+ writel (unable);
+ if (tflag) {
+ if (pnum) {
+ buflush();
+ sleep (MVPAUSE);
+ }
+ }
+ nexturn();
+ break;
+ }
+
+ /* get move */
+ getmove();
+
+ /* okay to clean
+ * screen */
+ hflag = 1;
+ break;
+
+ /* invalid character */
+ default:
+
+ /* print help message */
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ text (helpm);
+ if (tflag)
+ curmove (cturn == -1? 18: 19,0);
+ else
+ writec ('\n');
+
+ /* don't erase */
+ hflag = 0;
+ }
+ } else { /* couldn't double */
+
+ /* print roll */
+ roll();
+ if (tflag)
+ curmove (cturn == -1? 18: 19,0);
+ proll ();
+
+ /* can he move? */
+ if ((mvlim = movallow()) == 0) {
+
+ /* he can't */
+ writel (toobad2);
+ writel (*colorptr);
+ writel (cantmv);
+ buflush();
+ sleep (MVPAUSE);
+ nexturn();
+ continue;
+ }
+
+ /* get move */
+ getmove();
+ }
+ }
+
+ /* don't worry about who
+ * won if quit */
+ if (cturn == 0)
+ break;
+
+ /* fix cturn = winner */
+ cturn /= -2;
+
+ /* final board pos. */
+ if (tflag)
+ refresh();
+
+ /* backgammon? */
+ mflag = 0;
+ l = bar+7*cturn;
+ for (i = bar; i != l; i += cturn)
+ if (board[i]*cturn) mflag++;
+
+ /* compute game value */
+ if (tflag)
+ curmove (20,0);
+ if (*offopp == 15) {
+ if (mflag) {
+ writel (bgammon);
+ gvalue *= 3;
+ }
+ else if (*offptr <= 0) {
+ writel (gammon);
+ gvalue *= 2;
+ }
+ }
+
+ /* report situation */
+ if (cturn == -1) {
+ writel ("Red wins ");
+ rscore += gvalue;
+ } else {
+ writel ("White wins ");
+ wscore += gvalue;
+ }
+ wrint (gvalue);
+ writel (" point");
+ if (gvalue > 1)
+ writec ('s');
+ writel (".\n");
+
+ /* write score */
+ wrscore();
+
+ /* check user count */
+# ifdef CORY
+ if (ucount() > MAXUSERS) {
+ writel (user2a);
+ wrint (MAXUSERS);
+ writel (user2b);
+ rfl = 1;
+ break;
+ }
+# endif
+
+ /* see if he wants
+ * another game */
+ writel (again);
+ if ((i = yorn ('S')) == 0)
+ break;
+
+ init();
+ if (i == 2) {
+ writel (" Save.\n");
+ cturn = 0;
+ save (0);
+ }
+
+ /* yes, reset game */
+ wrboard();
+ }
+
+ /* give him a chance to save if game was recovered */
+ if (rfl && cturn) {
+ writel (svpromt);
+ if (yorn (0)) {
+ /* re-initialize for
+ * recovery */
+ init();
+ cturn = 0;
+ save(0);
+ }
+ }
+
+ /* leave peacefully */
+ getout ();
+}
diff --git a/backgammon/backgammon/move.c b/backgammon/backgammon/move.c
new file mode 100644
index 00000000..17a5dfde
--- /dev/null
+++ b/backgammon/backgammon/move.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)move.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+FILE *trace;
+static char tests[20];
+#endif
+
+struct BOARD { /* structure of game position */
+ int b_board[26]; /* board position */
+ int b_in[2]; /* men in */
+ int b_off[2]; /* men off */
+ int b_st[4], b_fn[4]; /* moves */
+
+ struct BOARD *b_next; /* forward queue pointer */
+};
+
+struct BOARD *freeq = 0;
+struct BOARD *checkq = 0;
+struct BOARD *bsave();
+struct BOARD *nextfree();
+
+ /* these variables are values for the
+ * candidate move */
+static int ch; /* chance of being hit */
+static int op; /* computer's open men */
+static int pt; /* comp's protected points */
+static int em; /* farthest man back */
+static int frc; /* chance to free comp's men */
+static int frp; /* chance to free pl's men */
+
+ /* these values are the values for the
+ * move chosen (so far) */
+static int chance; /* chance of being hit */
+static int openmen; /* computer's open men */
+static int points; /* comp's protected points */
+static int endman; /* farthest man back */
+static int barmen; /* men on bar */
+static int menin; /* men in inner table */
+static int menoff; /* men off board */
+static int oldfrc; /* chance to free comp's men */
+static int oldfrp; /* chance to free pl's men */
+
+static int cp[5]; /* candidate start position */
+static int cg[5]; /* candidate finish position */
+
+static int race; /* game reduced to a race */
+
+move (okay)
+int okay; /* zero if first move */
+{
+ register int i; /* index */
+ register int l; /* last man */
+
+ if (okay) {
+ /* see if comp should double */
+ if (gvalue < 64 && dlast != cturn && dblgood()) {
+ writel (*Colorptr);
+ dble(); /* double */
+ /* return if declined */
+ if (cturn != 1 && cturn != -1)
+ return;
+ }
+ roll();
+ }
+
+ race = 0;
+ for (i = 0; i < 26; i++) {
+ if (board[i] < 0)
+ l = i;
+ }
+ for (i = 0; i < l; i++) {
+ if (board[i] > 0)
+ break;
+ }
+ if (i == l)
+ race = 1;
+
+ /* print roll */
+ if (tflag)
+ curmove (cturn == -1? 18: 19,0);
+ writel (*Colorptr);
+ writel (" rolls ");
+ writec (D0+'0');
+ writec (' ');
+ writec (D1+'0');
+ /* make tty interruptable
+ * while thinking */
+ if (tflag)
+ cline();
+ fixtty (noech);
+
+ /* find out how many moves */
+ mvlim = movallow();
+ if (mvlim == 0) {
+ writel (" but cannot use it.\n");
+ nexturn();
+ fixtty (raw);
+ return;
+ }
+
+ /* initialize */
+ for (i = 0; i < 4; i++)
+ cp[i] = cg[i] = 0;
+
+ /* strategize */
+ trymove (0,0);
+ pickmove();
+
+ /* print move */
+ writel (" and moves ");
+ for (i = 0; i < mvlim; i++) {
+ if (i > 0)
+ writec (',');
+ wrint (p[i] = cp[i]);
+ writec ('-');
+ wrint (g[i] = cg[i]);
+ makmove (i);
+ }
+ writec ('.');
+
+ /* print blots hit */
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ for (i = 0; i < mvlim; i++)
+ if (h[i])
+ wrhit(g[i]);
+ /* get ready for next move */
+ nexturn();
+ if (!okay) {
+ buflush();
+ sleep (3);
+ }
+ fixtty (raw); /* no more tty interrupt */
+}
+
+trymove (mvnum,swapped)
+register int mvnum; /* number of move (rel zero) */
+int swapped; /* see if swapped also tested */
+
+{
+ register int pos; /* position on board */
+ register int rval; /* value of roll */
+
+ /* if recursed through all dice
+ * values, compare move */
+ if (mvnum == mvlim) {
+ binsert (bsave());
+ return;
+ }
+
+ /* make sure dice in always
+ * same order */
+ if (d0 == swapped)
+ swap;
+ /* choose value for this move */
+ rval = dice[mvnum != 0];
+
+ /* find all legitimate moves */
+ for (pos = bar; pos != home; pos += cturn) {
+ /* fix order of dice */
+ if (d0 == swapped)
+ swap;
+ /* break if stuck on bar */
+ if (board[bar] != 0 && pos != bar)
+ break;
+ /* on to next if not occupied */
+ if (board[pos]*cturn <= 0)
+ continue;
+ /* set up arrays for move */
+ p[mvnum] = pos;
+ g[mvnum] = pos+rval*cturn;
+ if (g[mvnum]*cturn >= home) {
+ if (*offptr < 0)
+ break;
+ g[mvnum] = home;
+ }
+ /* try to move */
+ if (makmove (mvnum))
+ continue;
+ else
+ trymove (mvnum+1,2);
+ /* undo move to try another */
+ backone (mvnum);
+ }
+
+ /* swap dice and try again */
+ if ((!swapped) && D0 != D1)
+ trymove (0,1);
+}
+
+struct BOARD *
+bsave () {
+ register int i; /* index */
+ struct BOARD *now; /* current position */
+
+ now = nextfree (); /* get free BOARD */
+
+ /* store position */
+ for (i = 0; i < 26; i++)
+ now->b_board[i] = board[i];
+ now->b_in[0] = in[0];
+ now->b_in[1] = in[1];
+ now->b_off[0] = off[0];
+ now->b_off[1] = off[1];
+ for (i = 0; i < mvlim; i++) {
+ now->b_st[i] = p[i];
+ now->b_fn[i] = g[i];
+ }
+ return (now);
+}
+
+binsert (new)
+struct BOARD *new; /* item to insert */
+{
+ register struct BOARD *p = checkq; /* queue pointer */
+ register int result; /* comparison result */
+
+ if (p == 0) { /* check if queue empty */
+ checkq = p = new;
+ p->b_next = 0;
+ return;
+ }
+
+ result = bcomp (new,p); /* compare to first element */
+ if (result < 0) { /* insert in front */
+ new->b_next = p;
+ checkq = new;
+ return;
+ }
+ if (result == 0) { /* duplicate entry */
+ mvcheck (p,new);
+ makefree (new);
+ return;
+ }
+
+ while (p->b_next != 0) { /* traverse queue */
+ result = bcomp (new,p->b_next);
+ if (result < 0) { /* found place */
+ new->b_next = p->b_next;
+ p->b_next = new;
+ return;
+ }
+ if (result == 0) { /* duplicate entry */
+ mvcheck (p->b_next,new);
+ makefree (new);
+ return;
+ }
+ p = p->b_next;
+ }
+ /* place at end of queue */
+ p->b_next = new;
+ new->b_next = 0;
+}
+
+bcomp (a,b)
+struct BOARD *a;
+struct BOARD *b;
+{
+ register int *aloc = a->b_board; /* pointer to board a */
+ register int *bloc = b->b_board; /* pointer to board b */
+ register int i; /* index */
+ int result; /* comparison result */
+
+ for (i = 0; i < 26; i++) { /* compare boards */
+ result = cturn*(aloc[i]-bloc[i]);
+ if (result)
+ return (result); /* found inequality */
+ }
+ return (0); /* same position */
+}
+
+mvcheck (incumbent,candidate)
+register struct BOARD *incumbent;
+register struct BOARD *candidate;
+{
+ register int i;
+ register int result;
+
+ for (i = 0; i < mvlim; i++) {
+ result = cturn*(candidate->b_st[i]-incumbent->b_st[i]);
+ if (result > 0)
+ return;
+ if (result < 0)
+ break;
+ }
+ if (i == mvlim)
+ return;
+ for (i = 0; i < mvlim; i++) {
+ incumbent->b_st[i] = candidate->b_st[i];
+ incumbent->b_fn[i] = candidate->b_fn[i];
+ }
+}
+
+makefree (dead)
+struct BOARD *dead; /* dead position */
+{
+ dead->b_next = freeq; /* add to freeq */
+ freeq = dead;
+}
+
+struct BOARD *
+nextfree () {
+ struct BOARD *new;
+
+ if (freeq == 0) {
+ new = (struct BOARD *)calloc (1,sizeof (struct BOARD));
+ if (new == 0) {
+ writel ("\nOut of memory\n");
+ getout();
+ }
+ new->b_next = 0;
+ return (new);
+ }
+
+ new = freeq;
+ freeq = freeq->b_next;
+}
+
+pickmove () {
+ /* current game position */
+ register struct BOARD *now = bsave();
+ register struct BOARD *next; /* next move */
+
+#ifdef DEBUG
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+ fprintf (trace,"\nRoll: %d %d%s\n",D0,D1,race? " (race)": "");
+ fflush (trace);
+#endif
+ do { /* compare moves */
+ boardcopy (checkq);
+ next = checkq->b_next;
+ makefree (checkq);
+ checkq = next;
+ movcmp();
+ } while (checkq != 0);
+
+ boardcopy (now);
+}
+
+boardcopy (s)
+register struct BOARD *s; /* game situation */
+{
+ register int i; /* index */
+
+ for (i = 0; i < 26; i++)
+ board[i] = s->b_board[i];
+ for (i = 0; i < 2; i++) {
+ in[i] = s->b_in[i];
+ off[i] = s->b_off[i];
+ }
+ for (i = 0; i < mvlim; i++) {
+ p[i] = s->b_st[i];
+ g[i] = s->b_fn[i];
+ }
+}
+
+movcmp () {
+ register int i;
+ register int c;
+
+#ifdef DEBUG
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+#endif
+
+ odds (0,0,0);
+ if (!race) {
+ ch = op = pt = 0;
+ for (i = 1; i < 25; i++) {
+ if (board[i] == cturn)
+ ch = canhit (i,1);
+ op += abs (bar-i);
+ }
+ for (i = bar+cturn; i != home; i += cturn)
+ if (board[i]*cturn > 1)
+ pt += abs(bar-i);
+ frc = freemen (bar)+trapped (bar,cturn);
+ frp = freemen (home)+trapped (home,-cturn);
+ }
+ for (em = bar; em != home; em += cturn)
+ if (board[em]*cturn > 0)
+ break;
+ em = abs(home-em);
+#ifdef DEBUG
+ fputs ("Board: ",trace);
+ for (i = 0; i < 26; i++)
+ fprintf (trace, " %d",board[i]);
+ if (race)
+ fprintf (trace,"\n\tem = %d\n",em);
+ else
+ fprintf (trace,
+ "\n\tch = %d, pt = %d, em = %d, frc = %d, frp = %d\n",
+ ch,pt,em,frc,frp);
+ fputs ("\tMove: ",trace);
+ for (i = 0; i < mvlim; i++)
+ fprintf (trace," %d-%d",p[i],g[i]);
+ fputs ("\n",trace);
+ fflush (trace);
+ strcpy (tests,"");
+#endif
+ if ((cp[0] == 0 && cg[0] == 0) || movegood()) {
+#ifdef DEBUG
+ fprintf (trace,"\t[%s] ... wins.\n",tests);
+ fflush (trace);
+#endif
+ for (i = 0; i < mvlim; i++) {
+ cp[i] = p[i];
+ cg[i] = g[i];
+ }
+ if (!race) {
+ chance = ch;
+ openmen = op;
+ points = pt;
+ endman = em;
+ barmen = abs(board[home]);
+ oldfrc = frc;
+ oldfrp = frp;
+ }
+ menin = *inptr;
+ menoff = *offptr;
+ }
+#ifdef DEBUG
+ else {
+ fprintf (trace,"\t[%s] ... loses.\n",tests);
+ fflush (trace);
+ }
+#endif
+}
+
+movegood () {
+ register int n;
+
+ if (*offptr == 15)
+ return (1);
+ if (menoff == 15)
+ return (0);
+ if (race) {
+#ifdef DEBUG
+ strcat (tests,"o");
+#endif
+ if (*offptr-menoff)
+ return (*offptr > menoff);
+#ifdef DEBUG
+ strcat (tests,"e");
+#endif
+ if (endman-em)
+ return (endman > em);
+#ifdef DEBUG
+ strcat (tests,"i");
+#endif
+ if (menin == 15)
+ return (0);
+ if (*inptr == 15)
+ return (1);
+#ifdef DEBUG
+ strcat (tests,"i");
+#endif
+ if (*inptr-menin)
+ return (*inptr > menin);
+ return (rnum(2));
+ } else {
+ n = barmen-abs(board[home]);
+#ifdef DEBUG
+ strcat (tests,"c");
+#endif
+ if (abs(chance-ch)+25*n > rnum(150))
+ return (n? (n < 0): (ch < chance));
+#ifdef DEBUG
+ strcat (tests,"o");
+#endif
+ if (*offptr-menoff)
+ return (*offptr > menoff);
+#ifdef DEBUG
+ strcat (tests,"o");
+#endif
+ if (abs(openmen-op) > 7+rnum(12))
+ return (openmen > op);
+#ifdef DEBUG
+ strcat (tests,"b");
+#endif
+ if (n)
+ return (n < 0);
+#ifdef DEBUG
+ strcat (tests,"e");
+#endif
+ if (abs(endman-em) > rnum(2))
+ return (endman > em);
+#ifdef DEBUG
+ strcat (tests,"f");
+#endif
+ if (abs(frc-oldfrc) > rnum(2))
+ return (frc < oldfrc);
+#ifdef DEBUG
+ strcat (tests,"p");
+#endif
+ if (abs(n = pt-points) > rnum(4))
+ return (n > 0);
+#ifdef DEBUG
+ strcat (tests,"i");
+#endif
+ if (*inptr-menin)
+ return (*inptr > menin);
+#ifdef DEBUG
+ strcat (tests,"f");
+#endif
+ if (abs(frp-oldfrp) > rnum(2))
+ return (frp > oldfrp);
+ return (rnum(2));
+ }
+}
diff --git a/backgammon/backgammon/text.c b/backgammon/backgammon/text.c
new file mode 100644
index 00000000..1a390867
--- /dev/null
+++ b/backgammon/backgammon/text.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)text.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *instr[] = {
+ " If you did not notice by now, this program reacts to things as",
+ "soon as you type them, without waiting for a newline. This means that",
+ "the special characters RUBOUT, ESC, and CONTROL-D, will not perform",
+ "their special functions during most of this program. The program",
+ "should usually stop when a RUBOUT is typed, but occasionally it will",
+ "ignore RUBOUTs until it is waiting for input.\n",
+ " These instructions are presented in small chunks designed not to",
+ "roll off the top of your screen. When the characters '-->' are print-",
+ "ed, no more data will be printed until a space or newline is typed.",
+ "In this way, you can finish one section before continuing to another.",
+ "Like this:",
+ "",
+ " The two sides are colored 'red' and 'white.' The computer may play",
+ "one side, or if there are two players, the computer can merely act as",
+ "a gamekeeper, letting the players make the moves. Once you tell the",
+ "computer what color(s) you want to play, the decision remains in ef-",
+ "fect until you quit the program, even if you play more than one game,",
+ "since the program keeps a running score.\n",
+ " The program will prompt for a move in one of two ways. If the",
+ "player has the opportunity to double, then merely his color will be",
+ "typed out. The player can now do one of several things. He can dou-",
+ "ble by typing a 'd', he can roll by typing a space (' ') or newline,",
+ "or if he is not sure, he can reprint the board by typing a 'r'.\n",
+ " If the player cannot double, his roll will be thrust in front of",
+ "him, followed by the request 'Move:', asking for a move but not giving",
+ "him the chance to double. He can still ask for the board by typing",
+ "'r'. In either of these two states, the player can quit by typing 'q'",
+ "or save the game by typing 's'. In either case, the player will be",
+ "asked to verify, in case there was some error. The program then ends",
+ "immediately, after first saving the file if so requested.",
+ "",
+ " A player can move one of his men using two forms of input. The",
+ "first form is <s>-<f>, where <s> is the starting position, and <f> is",
+ "the finishing position of the player's man. For example, if white",
+ "wanted to move a piece from position 13 to position 8, his move could",
+ "be entered as 13-8. The second form is <s>/<r> where <s> is the",
+ "starting position, an <r> is the roll actually made. Hence, white",
+ "could have entered as 13/5 instead of 13-8.\n",
+ " A player must move each roll of the dice separately. For example,",
+ "if a player rolled 4 3, and wanted to move from 13 to 6, he could",
+ "enter it as 13/4,9/3 or 13/3,10/4 or 13-10,10-6 or 13-9,9-6, but not",
+ "13-6. The last two entries can be shortened to 13-10-6 and 13-9-6.",
+ "If you want to move more than one piece from the same position, such",
+ "as 13-10,13-9, you can abbreviate this using the <s>/<r> format as by",
+ "entering more than one <r>, or 13/34. A player can use both forms for",
+ "the same roll, e.g. 13/3,13-9, and separates individual moves by ei-",
+ "ther a comma or a space. The letter 'b' represents the bar, and the",
+ "letter 'h' represents a player's home. You could also enter the",
+ "number that would be in the position of the bar, 25 or 0 as appropri-",
+ "ate. Use a newline at the end of your moves for a turn.",
+ "",
+ " As you type in your move, if a character does not make sense under",
+ "the above constrictions, a bell will sound instead of the character,",
+ "and it will be ignored. You may kill lines and erase characters as",
+ "you would normally, but don't be surprised if they look different than",
+ "usual. Also, if you have entered one or more of your rolls, and you",
+ "wish to see what the move looks like so far, type a 'r' to see what it",
+ "looks like. This cannot be done in the middle of a move (e.g., after",
+ "a '-' or '/'). After the printing board, the program will go back to",
+ "inputting your move and you can backspace or kill just as if you had",
+ "just typed in your input.\n",
+ " Now you should be ready to begin the game. Good luck!",
+ "",
+ 0};
+
+
+text (t)
+char **t;
+
+{
+ register int i;
+ register char *s, *a;
+
+ fixtty (noech);
+ while (*t != 0) {
+ s = a = *t;
+ for (i = 0; *a != '\0'; i--)
+ a++;
+ if (i) {
+ writel (s);
+ writec ('\n');
+ } else {
+ writel ("-->");
+ fixtty (raw);
+ while ((i = readc()) != ' ' && i != '\n');
+ fixtty (noech);
+ clear();
+ }
+ t++;
+ }
+ fixtty (raw);
+}
diff --git a/backgammon/backgammon/version.c b/backgammon/backgammon/version.c
new file mode 100644
index 00000000..a6e9db27
--- /dev/null
+++ b/backgammon/backgammon/version.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1980, 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)version.c 1.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+char *message[] = {
+ "Last updated on Saturday, January 11, 1986.",
+ 0
+};
diff --git a/backgammon/common_source/allow.c b/backgammon/common_source/allow.c
new file mode 100644
index 00000000..2a7c9e0d
--- /dev/null
+++ b/backgammon/common_source/allow.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)allow.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+movallow () {
+
+ register int i, m, iold;
+ int r;
+
+ if (d0)
+ swap;
+ m = (D0 == D1? 4: 2);
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = iold = 0;
+ while (i < m) {
+ if (*offptr == 15)
+ break;
+ h[i] = 0;
+ if (board[bar]) {
+ if (i == 1 || m == 4)
+ g[i] = bar+cturn*D1;
+ else
+ g[i] = bar+cturn*D0;
+ if (r = makmove(i)) {
+ if (d0 || m == 4)
+ break;
+ swap;
+ movback (i);
+ if (i > iold)
+ iold = i;
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = 0;
+ } else
+ i++;
+ continue;
+ }
+ if ((p[i] += cturn) == home) {
+ if (i > iold)
+ iold = i;
+ if (m == 2 && i) {
+ movback(i);
+ p[i--] = bar;
+ if (p[i] != bar)
+ continue;
+ else
+ break;
+ }
+ if (d0 || m == 4)
+ break;
+ swap;
+ movback (i);
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = 0;
+ continue;
+ }
+ if (i == 1 || m == 4)
+ g[i] = p[i]+cturn*D1;
+ else
+ g[i] = p[i]+cturn*D0;
+ if (g[i]*cturn > home) {
+ if (*offptr >= 0)
+ g[i] = home;
+ else
+ continue;
+ }
+ if (board[p[i]]*cturn > 0 && (r = makmove(i)) == 0)
+ i++;
+ }
+ movback (i);
+ return (iold > i? iold: i);
+}
diff --git a/backgammon/common_source/back.h b/backgammon/common_source/back.h
new file mode 100644
index 00000000..5bab6e55
--- /dev/null
+++ b/backgammon/common_source/back.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)back.h 5.4 (Berkeley) 6/1/90
+ */
+
+#include <sgtty.h>
+
+#define rnum(r) (random()%r)
+#define D0 dice[0]
+#define D1 dice[1]
+#define swap {D0 ^= D1; D1 ^= D0; D0 ^= D1; d0 = 1-d0;}
+
+/*
+ *
+ * Some numerical conventions:
+ *
+ * Arrays have white's value in [0], red in [1].
+ * Numeric values which are one color or the other use
+ * -1 for white, 1 for red.
+ * Hence, white will be negative values, red positive one.
+ * This makes a lot of sense since white is going in decending
+ * order around the board, and red is ascending.
+ *
+ */
+
+char EXEC[]; /* object for main program */
+char TEACH[]; /* object for tutorial program */
+
+int pnum; /* color of player:
+ -1 = white
+ 1 = red
+ 0 = both
+ 2 = not yet init'ed */
+char args[100]; /* args passed to teachgammon and back */
+int acnt; /* length of args */
+int aflag; /* flag to ask for rules or instructions */
+int bflag; /* flag for automatic board printing */
+int cflag; /* case conversion flag */
+int hflag; /* flag for cleaning screen */
+int mflag; /* backgammon flag */
+int raflag; /* 'roll again' flag for recovered game */
+int rflag; /* recovered game flag */
+int tflag; /* cursor addressing flag */
+int rfl; /* saved value of rflag */
+int iroll; /* special flag for inputting rolls */
+int board[26]; /* board: negative values are white,
+ positive are red */
+int dice[2]; /* value of dice */
+int mvlim; /* 'move limit': max. number of moves */
+int mvl; /* working copy of mvlim */
+int p[5]; /* starting position of moves */
+int g[5]; /* ending position of moves (goals) */
+int h[4]; /* flag for each move if a man was hit */
+int cturn; /* whose turn it currently is:
+ -1 = white
+ 1 = red
+ 0 = just quitted
+ -2 = white just lost
+ 2 = red just lost */
+int d0; /* flag if dice have been reversed from
+ original position */
+int table[6][6]; /* odds table for possible rolls */
+int rscore; /* red's score */
+int wscore; /* white's score */
+int gvalue; /* value of game (64 max.) */
+int dlast; /* who doubled last (0 = neither) */
+int bar; /* position of bar for current player */
+int home; /* position of home for current player */
+int off[2]; /* number of men off board */
+int *offptr; /* pointer to off for current player */
+int *offopp; /* pointer to off for opponent */
+int in[2]; /* number of men in inner table */
+int *inptr; /* pointer to in for current player */
+int *inopp; /* pointer to in for opponent */
+
+int ncin; /* number of characters in cin */
+char cin[100]; /* input line of current move
+ (used for reconstructing input after
+ a backspace) */
+
+char *color[];
+ /* colors as strings */
+char **colorptr; /* color of current player */
+char **Colorptr; /* color of current player, capitalized */
+int colen; /* length of color of current player */
+
+struct sgttyb tty; /* tty information buffer */
+int old; /* original tty status */
+int noech; /* original tty status without echo */
+int raw; /* raw tty status, no echo */
+
+int curr; /* row position of cursor */
+int curc; /* column position of cursor */
+int begscr; /* 'beginning' of screen
+ (not including board) */
+
+int getout(); /* function to exit backgammon cleanly */
diff --git a/backgammon/common_source/backgammon.c b/backgammon/common_source/backgammon.c
new file mode 100644
index 00000000..036301f4
--- /dev/null
+++ b/backgammon/common_source/backgammon.c
@@ -0,0 +1,751 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)backgammon.c 5.1 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+/*
+** The game of Backgammon
+*/
+
+#include <stdio.h>
+
+#define WHITE 0
+#define BROWN 1
+#define NIL (-1)
+#define MAXGMOV 10
+#define MAXIMOVES 1000
+#define RULES "/usr/games/lib/backrules"
+
+char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
+
+int die1;
+int die2;
+int i;
+int j;
+int l;
+int m;
+int pflg = 1;
+int nobroll = 0;
+int count;
+int imoves;
+int goodmoves[MAXGMOV];
+int probmoves[MAXGMOV];
+
+int brown[] = { /* brown position table */
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+int white[] = { /* white position table */
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+int probability[] = {
+ 0, 11, 12, 13, 14, 15, 16,
+ 06, 05, 04, 03, 02, 01
+};
+
+struct {
+ int pos[4];
+ int mov[4];
+} moves[MAXIMOVES];
+
+main()
+{
+ int go[5], tvec[2];
+ int k, n, pid, ret, rpid, t;
+ char s[100];
+
+ srand(time(0));
+ go[5] = NIL;
+ fprintf(stdout, "Instructions? ");
+ gets(s);
+ if(*s == 'y')
+ instructions();
+ putchar('\n');
+ fprintf(stdout, "Opponent's level: b - beginner,\n");
+ fprintf(stdout, "i - intermediate, e - expert? ");
+ level='e';
+ gets(s);
+ if(*s == 'b')
+ level = 'b';
+ else if(*s == 'i')
+ level = 'i';
+ putchar('\n');
+ fprintf(stdout, "You will play brown.\n\n");
+ fprintf(stdout, "Would you like to roll your own dice? ");
+ gets(s);
+ putchar('\n');
+ if(*s == 'y')
+ nobroll = 1;
+ fprintf(stdout, "Would you like to go first? ");
+ gets(s);
+ putchar('\n');
+ if(*s == 'y')
+ goto nowhmove;
+whitesmv:
+ roll(WHITE);
+ fprintf(stdout, "white rolls %d, %d\n", die1, die2);
+ fprintf(stdout, "white's move is:");
+ if(nextmove(white, brown) == NIL)
+ goto nowhmove;
+ if(piececount(white, 0, 24) == 0){
+ fprintf(stdout, "White wins");
+ if(piececount(brown, 0, 6) != 0)
+ fprintf(stdout, " with a Backgammon!\n");
+ else if (piececount(brown, 0, 24) == 24)
+ fprintf(stdout, " with a Gammon.\n");
+ else
+ fprintf(stdout, ".\n");
+ exit(0);
+ }
+nowhmove:
+ if(pflg)
+ prtbrd();
+ roll(BROWN);
+retry:
+ fprintf(stdout, "\nYour roll is %d %d\n", die1, die2);
+ fprintf(stdout, "Move? ");
+ gets(s);
+ switch(*s) {
+ case '\0': /* empty line */
+ fprintf(stdout, "Brown's move skipped.\n");
+ goto whitesmv;
+
+ case 'b': /* how many beared off? */
+ fprintf(stdout, "Brown: %d\n", piececount(brown, 0, 24) - 15);
+ fprintf(stdout, "White: %d\n", piececount(white, 0, 24) - 15);
+ goto retry;
+
+ case 'p': /* print board */
+ prtbrd();
+ goto retry;
+
+ case 's': /* stop auto printing of board */
+ pflg = 0;
+ goto retry;
+
+ case 'r': /* resume auto printing */
+ pflg = 1;
+ goto retry;
+
+ case 'm': /* print possible moves */
+ pmoves();
+ goto retry;
+
+ case 'q': /* i give up */
+ exit(0);
+
+ case '!': /* escape to Shell */
+ if(s[1] != '\0')
+ system(s+1);
+ else if((pid = fork()) == 0) {
+ execl("/bin/sh", "sh", "-", 0);
+ fprintf(stderr, "back: cannot exec /bin/sh!\n");
+ exit(2);
+ }
+ while((rpid = wait(&ret)) != pid && rpid != -1)
+ ;
+ goto retry;
+
+ case '?': /* well, what can i do? */
+ fprintf(stdout, "<newline> skip this move\n");
+ fprintf(stdout, "b number beared off\n");
+ fprintf(stdout, "p print board\n");
+ fprintf(stdout, "q quit\n");
+ fprintf(stdout, "r resume auto print of board\n");
+ fprintf(stdout, "s stop auto print of board\n");
+ fprintf(stdout, "! escape to Shell\n");
+ goto retry;
+ }
+ n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
+ if((die1 != die2 && n > 2) || n > 4){
+ fprintf(stdout, "Too many moves.\n");
+ goto retry;
+ }
+ go[n] = NIL;
+ if(*s=='-'){
+ go[0]= -go[0];
+ t=die1;
+ die1=die2;
+ die2=t;
+ }
+ for(k = 0; k < n; k++){
+ if(0 <= go[k] && go[k] <= 24)
+ continue;
+ else{
+ fprintf(stdout, "Move %d illegal.\n", go[k]);
+ goto retry;
+ }
+ }
+ if(play(brown, white, go))
+ goto retry;
+ if(piececount(brown, 0, 24) == 0){
+ fprintf(stdout, "Brown wins");
+ if(piececount(white, 0, 6) != 0)
+ fprintf(stdout, " with a Backgammon.\n");
+ else if(piececount(white, 0, 24) == 24)
+ fprintf(stdout, " with a gammon.\n");
+ else
+ fprintf(stdout, ".\n");
+ exit(0);
+ }
+ goto whitesmv;
+}
+
+play(player,playee,pos)
+int *player,*playee,pos[];
+{
+ int k, n, die, ipos;
+
+ for(k=0; k < player[0]; k++){ /*blots on player[0] must be moved first*/
+ if(pos[k] == NIL)
+ break;
+ if(pos[k] != 0){
+ fprintf(stdout, "Stone on bar must be moved first.\n");
+ return(NIL);
+ }
+ }
+ for(k = 0; (ipos=pos[k]) != NIL; k++){
+ die = k?die2:die1;
+ n = 25-ipos-die;
+ if(player[ipos] == 0)
+ goto badmove;
+ if(n > 0 && playee[n] >= 2)
+ goto badmove;
+ if(n <= 0){
+ if(piececount(player,0,18) != 0)
+ goto badmove;
+ if((ipos+die) != 25 && piececount(player,19,24-die)!=0)
+ goto badmove;
+ }
+ player[ipos]--;
+ player[ipos+die]++;
+ }
+ for(k = 0; pos[k] != NIL; k++){
+ die = k?die2:die1;
+ n = 25-pos[k]-die;
+ if(n>0 && playee[n]==1){
+ playee[n]=0;
+ playee[0]++;
+ }
+ }
+ return(0);
+
+badmove:
+ fprintf(stdout, "Move %d illegal.\n", ipos);
+ while(k--){
+ die=k?die2:die1;
+ player[pos[k]]++;
+ player[pos[k]+die]--;
+ }
+ return(NIL);
+}
+nextmove(player,playee)
+int *player,*playee;
+{
+ int k;
+
+ imoves=0;
+ movegen(player,playee);
+ if(die1!=die2){
+ k=die1;
+ die1=die2;
+ die2=k;
+ movegen(player,playee);
+ }
+ if(imoves==0){
+ fprintf(stdout, "no move possible.\n");
+ return(NIL);
+ }
+ k=strategy(player,playee); /*select kth possible move*/
+ prtmov(k);
+ update(player,playee,k);
+ return(0);
+}
+prtmov(k)
+int k;
+{
+ int n;
+
+ if(k == NIL)
+ fprintf(stdout, "No move possible\n");
+ else for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ fprintf(stdout, " %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
+ }
+ fprintf(stdout, "\n");
+}
+update(player,playee,k)
+int *player,*playee,k;
+{
+ int n,t;
+
+ for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ player[moves[k].pos[n]]--;
+ player[moves[k].pos[n]+moves[k].mov[n]]++;
+ t=25-moves[k].pos[n]-moves[k].mov[n];
+ if(t>0 && playee[t]==1){
+ playee[0]++;
+ playee[t]--;
+ }
+ }
+}
+piececount(player,startrow,endrow)
+int *player,startrow,endrow;
+{
+ int sum;
+
+ sum=0;
+ while(startrow <= endrow)
+ sum += player[startrow++];
+ return(sum);
+}
+pmoves()
+{
+ int i1, i2;
+
+ fprintf(stdout, "Possible moves are:\n");
+ for(i1 = 0; i1 < imoves; i1++){
+ fprintf(stdout, "\n%d",i1);
+ for (i2 = 0; i2<4; i2++){
+ if(moves[i1].pos[i2] == NIL)
+ break;
+ fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
+ }
+ }
+ fprintf(stdout, "\n");
+}
+
+roll(who)
+{
+ register n;
+ char s[10];
+
+ if(who == BROWN && nobroll) {
+ fprintf(stdout, "Roll? ");
+ gets(s);
+ n = sscanf(s, "%d%d", &die1, &die2);
+ if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6)
+ fprintf(stdout, "Illegal - I'll do it!\n");
+ else
+ return;
+ }
+ die1 = ((rand()>>8) % 6) + 1;
+ die2 = ((rand()>>8) % 6) + 1;
+}
+
+movegen(mover,movee)
+int *mover,*movee;
+{
+ int k;
+
+ for(i = 0; i <= 24; i++){
+ count = 0;
+ if(mover[i] == 0)
+ continue;
+ if((k=25-i-die1) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover, 0, 18) != 0)
+ break;
+ if((i+die1) != 25 && piececount(mover,19,i-1) != 0)
+ break;
+ }
+ mover[i]--;
+ mover[i+die1]++;
+ count = 1;
+ for(j = 0; j <= 24; j++){
+ if(mover[j]==0)
+ continue;
+ if((k=25-j-die2) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover,0,18) != 0)
+ break;
+ if((j+die2) != 25 && piececount(mover,19,j-1) != 0)
+ break;
+ }
+ mover[j]--;
+ mover[j+die2]++;
+ count = 2;
+ if(die1 != die2){
+ moverecord(mover);
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ }
+ for(l = 0; l <= 24; l++){
+ if(mover[l] == 0)
+ continue;
+ if((k=25-l-die1) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover, 0, 18) != 0)
+ break;
+ if((l+die2) != 25 && piececount(mover,19,l-1) != 0)
+ break;
+ }
+ mover[l]--;
+ mover[l+die1]++;
+ count=3;
+ for(m=0;m<=24;m++){
+ if(mover[m]==0)
+ continue;
+ if((k=25-m-die1) >= 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover,0,18) != 0)
+ break;
+ if((m+die2) != 25 && piececount(mover,19,m-1) != 0)
+ break;
+ }
+ count=4;
+ moverecord(mover);
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 3)
+ moverecord(mover);
+ else{
+ mover[l]++;
+ mover[l+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 2)
+ moverecord(mover);
+ else{
+ mover[j]++;
+ mover[j+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 1)
+ moverecord(mover);
+ else{
+ mover[i]++;
+ mover[i+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+}
+moverecord(mover)
+int *mover;
+{
+ int t;
+
+ if(imoves < MAXIMOVES) {
+ for(t = 0; t <= 3; t++)
+ moves[imoves].pos[t] = NIL;
+ switch(count) {
+ case 4:
+ moves[imoves].pos[3]=m;
+ moves[imoves].mov[3]=die1;
+
+ case 3:
+ moves[imoves].pos[2]=l;
+ moves[imoves].mov[2]=die1;
+
+ case 2:
+ moves[imoves].pos[1]=j;
+ moves[imoves].mov[1]=die2;
+
+ case 1:
+ moves[imoves].pos[0]=i;
+ moves[imoves].mov[0]=die1;
+ imoves++;
+ }
+ }
+ switch(count) {
+ case 4:
+ break;
+
+ case 3:
+ mover[l]++;
+ mover[l+die1]--;
+ break;
+
+ case 2:
+ mover[j]++;
+ mover[j+die2]--;
+ break;
+
+ case 1:
+ mover[i]++;
+ mover[i+die1]--;
+ }
+}
+
+strategy(player,playee)
+int *player,*playee;
+{
+ int k, n, nn, bestval, moveval, prob;
+
+ n = 0;
+ if(imoves == 0)
+ return(NIL);
+ goodmoves[0] = NIL;
+ bestval = -32000;
+ for(k = 0; k < imoves; k++){
+ if((moveval=eval(player,playee,k,&prob)) < bestval)
+ continue;
+ if(moveval > bestval){
+ bestval = moveval;
+ n = 0;
+ }
+ if(n<MAXGMOV){
+ goodmoves[n]=k;
+ probmoves[n++]=prob;
+ }
+ }
+ if(level=='e' && n>1){
+ nn=n;
+ n=0;
+ prob=32000;
+ for(k = 0; k < nn; k++){
+ if((moveval=probmoves[k]) > prob)
+ continue;
+ if(moveval<prob){
+ prob=moveval;
+ n=0;
+ }
+ goodmoves[n]=goodmoves[k];
+ probmoves[n++]=probmoves[k];
+ }
+ }
+ return(goodmoves[(rand()>>4)%n]);
+}
+
+eval(player,playee,k,prob)
+int *player,*playee,k,*prob;
+{
+ int newtry[31], newother[31], *r, *q, *p, n, sum, first;
+ int ii, lastwhite, lastbrown;
+
+ *prob = sum = 0;
+ r = player+25;
+ p = newtry;
+ q = newother;
+ while(player<r){
+ *p++= *player++;
+ *q++= *playee++;
+ }
+ q=newtry+31;
+ for(p = newtry+25; p < q; p++) /* zero out spaces for hit pieces */
+ *p = 0;
+ for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ newtry[moves[k].pos[n]]--;
+ newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
+ if(ii<25 && newother[25-ii]==1){
+ newother[25-ii]=0;
+ newother[0]++;
+ if(ii<=15 && level=='e') /* hit if near other's home */
+ sum++;
+ }
+ }
+ for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++);
+ ;
+ for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++)
+ ;
+ lastwhite = 25-lastwhite;
+ if(lastwhite<=6 && lastwhite<lastbrown)
+ sum=1000;
+ /* experts running game. */
+ /* first priority is to */
+ /* get all pieces into */
+ /* white's home */
+ if(lastwhite<lastbrown && level=='e' && lastwhite>6) {
+ for(sum = 1000; lastwhite > 6; lastwhite--)
+ sum = sum-lastwhite*newtry[25-lastwhite];
+ }
+ for(first = 0; first < 25; first++)
+ if(newother[first] != 0) /*find other's first piece*/
+ break;
+ q = newtry+25;
+ for(p = newtry+1; p < q;) /* blocked points are good */
+ if(*p++ > 1)
+ sum++;
+ if(first > 5) { /* only stress removing pieces if */
+ /* homeboard cannot be hit */
+ q = newtry+31;
+ p=newtry+25;
+ for(n = 6; p < q; n--)
+ sum += *p++ * n; /*remove pieces, but just barely*/
+ }
+ if(level != 'b'){
+ r = newtry+25-first; /*singles past this point can't be hit*/
+ for(p = newtry+7; p < r; )
+ if(*p++ == 1) /*singles are bad after 1st 6 points if they can be hit*/
+ sum--;
+ q = newtry+3;
+ for(p = newtry; p < q; ) /*bad to be on 1st three points*/
+ sum -= *p++;
+ }
+
+ for(n = 1; n <= 4; n++)
+ *prob += n*getprob(newtry,newother,6*n-5,6*n);
+ return(sum);
+}
+instructions()
+{
+ register fd, r;
+ char buf[BUFSIZ];
+
+ if((fd = open(RULES, 0)) < 0) {
+ fprintf(stderr, "back: cannot open %s\n", RULES);
+ return;
+ }
+ while(r = read(fd, buf, BUFSIZ))
+ write(1, buf, r);
+}
+
+getprob(player,playee,start,finish)
+int *player,*playee,start,finish;
+{ /*returns the probability (times 102) that any
+ pieces belonging to 'player' and lying between
+ his points 'start' and 'finish' will be hit
+ by a piece belonging to playee
+ */
+ int k, n, sum;
+
+ sum = 0;
+ for(; start <= finish; start++){
+ if(player[start] == 1){
+ for(k = 1; k <= 12; k++){
+ if((n=25-start-k) < 0)
+ break;
+ if(playee[n] != 0)
+ sum += probability[k];
+ }
+ }
+ }
+ return(sum);
+}
+prtbrd()
+{
+ int k;
+ static char undersc[]="______________________________________________________";
+
+ fprintf(stdout, "White's Home\n%s\r",undersc);
+ for(k = 1; k <= 6; k++)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, " ");
+ for(k = 7; k <= 12; k++)
+ fprintf(stdout, "%4d",k);
+ putchar('\n');
+ numline(brown, white, 1, 6);
+ fprintf(stdout, " ");
+ numline(brown, white, 7, 12);
+ putchar('\n');
+ colorline(brown, 'B', white, 'W', 1, 6);
+ fprintf(stdout, " ");
+ colorline(brown, 'B', white, 'W', 7, 12);
+ putchar('\n');
+ if(white[0] != 0)
+ fprintf(stdout, "%28dW\n",white[0]);
+ else
+ putchar('\n');
+ if(brown[0] != 0)
+ fprintf(stdout, "%28dB\n", brown[0]);
+ else
+ putchar('\n');
+ colorline(white, 'W', brown, 'B', 1, 6);
+ fprintf(stdout, " ");
+ colorline(white, 'W', brown, 'B', 7, 12);
+ fprintf(stdout, "\n%s\r",undersc);
+ numline(white, brown, 1, 6);
+ fprintf(stdout, " ");
+ numline(white, brown, 7, 12);
+ putchar('\n');
+ for(k = 24; k >= 19; k--)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, " ");
+ for(k = 18; k >= 13; k--)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, "\nBrown's Home\n\n\n\n\n");
+}
+numline(upcol,downcol,start,fin)
+int *upcol,*downcol,start,fin;
+{
+ int k, n;
+
+ for(k = start; k <= fin; k++){
+ if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0)
+ fprintf(stdout, "%4d", n);
+ else
+ fprintf(stdout, " ");
+ }
+}
+colorline(upcol,c1,downcol,c2,start,fin)
+int *upcol,*downcol,start,fin;
+char c1,c2;
+{
+ int k;
+ char c;
+
+ for(k = start; k <= fin; k++){
+ c = ' ';
+ if(upcol[k] != 0)
+ c = c1;
+ if(downcol[25-k] != 0)
+ c = c2;
+ fprintf(stdout, " %c",c);
+ }
+}
diff --git a/backgammon/common_source/board.c b/backgammon/common_source/board.c
new file mode 100644
index 00000000..d21d36a9
--- /dev/null
+++ b/backgammon/common_source/board.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)board.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+static int i, j, k;
+static char ln[60];
+
+wrboard () {
+ register int l;
+ static char bl[] =
+ "| | | |\n";
+ static char sv[] =
+ "| | | | \n";
+
+ fixtty (noech);
+ clear();
+
+ if (tflag) {
+ fboard();
+ goto lastline;
+ }
+
+ writel ("_____________________________________________________\n");
+ writel (bl);
+ strcpy (ln,bl);
+ for (j = 1; j < 50; j += 4) {
+ k = j/4+(j > 24? 12: 13);
+ ln[j+1] = k%10+'0';
+ ln[j] = k/10+'0';
+ if (j == 21)
+ j += 4;
+ }
+ writel (ln);
+ for (i = 0; i < 5; i++) {
+ strcpy (ln,sv);
+ for (j = 1; j < 50; j += 4) {
+ k = j/4+(j > 24? 12: 13);
+ wrbsub ();
+ if (j == 21)
+ j += 4;
+ }
+ if (-board[25] > i)
+ ln[26] = 'w';
+ if (-board[25] > i+5)
+ ln[25] = 'w';
+ if (-board[25] > i+10)
+ ln[27] = 'w';
+ l = 53;
+ if (off[1] > i || (off[1] < 0 && off[1]+15 > i)) {
+ ln[54] = 'r';
+ l = 55;
+ }
+ if (off[1] > i+5 || (off[1] < 0 && off[1]+15 > i+5)) {
+ ln[55] = 'r';
+ l = 56;
+ }
+ if (off[1] > i+10 || (off[1] < 0 && off[1]+15 > i+10)) {
+ ln[56] = 'r';
+ l = 57;
+ }
+ ln[l++] = '\n';
+ ln[l] = '\0';
+ writel (ln);
+ }
+ strcpy (ln,bl);
+ ln[25] = 'B';
+ ln[26] = 'A';
+ ln[27] = 'R';
+ writel (ln);
+ strcpy (ln,sv);
+ for (i = 4; i > -1; i--) {
+ for (j = 1; j < 50; j += 4) {
+ k = ((j > 24? 53: 49)-j)/4;
+ wrbsub();
+ if (j == 21)
+ j += 4;
+ }
+ if (board[0] > i)
+ ln[26] = 'r';
+ if (board[0] > i+5)
+ ln[25] = 'r';
+ if (board[0] > i+10)
+ ln[27] = 'r';
+ l = 53;
+ if (off[0] > i || (off[0] < 0 && off[0]+15 > i)) {
+ ln[54] = 'w';
+ l = 55;
+ }
+ if (off[0] > i+5 || (off[0] < 0 && off[0]+15 > i+5)) {
+ ln[55] = 'w';
+ l = 56;
+ }
+ if (off[0] > i+10 || (off[0] < 0 && off[0]+15 > i+10)) {
+ ln[56] = 'w';
+ l = 57;
+ }
+ ln[l++] = '\n';
+ ln[l] = '\0';
+ writel (ln);
+ }
+ strcpy (ln,bl);
+ for (j = 1; j < 50; j += 4) {
+ k = ((j > 24? 53: 49)-j)/4;
+ ln[j+1] = k%10+'0';
+ if (k > 9)
+ ln[j] = k/10+'0';
+ if (j == 21)
+ j += 4;
+ }
+ writel (ln);
+ writel ("|_______________________|___|_______________________|\n");
+
+lastline:
+ gwrite ();
+ if (tflag)
+ curmove (18,0);
+ else {
+ writec ('\n');
+ writec ('\n');
+ }
+ fixtty(raw);
+}
+
+wrbsub () {
+ register int m;
+ register char d;
+
+ if (board[k] > 0) {
+ m = board[k];
+ d = 'r';
+ } else {
+ m = -board[k];
+ d = 'w';
+ }
+ if (m>i)
+ ln[j+1] = d;
+ if (m>i+5)
+ ln[j] = d;
+ if (m>i+10)
+ ln[j+2] = d;
+}
diff --git a/backgammon/common_source/check.c b/backgammon/common_source/check.c
new file mode 100644
index 00000000..5ef2eb2b
--- /dev/null
+++ b/backgammon/common_source/check.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)check.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+getmove () {
+ register int i, c;
+
+ c = 0;
+ for (;;) {
+ i = checkmove(c);
+
+ switch (i) {
+ case -1:
+ if (movokay(mvlim)) {
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ for (i = 0; i < mvlim; i++)
+ if (h[i])
+ wrhit(g[i]);
+ nexturn();
+ if (*offopp == 15)
+ cturn *= -2;
+ if (tflag && pnum)
+ bflag = pnum;
+ return;
+ }
+
+ case -4:
+ case 0:
+ if (tflag)
+ refresh();
+ if (i != 0 && i != -4)
+ break;
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ writel (*Colorptr);
+ if (i == -4)
+ writel (" must make ");
+ else
+ writel (" can only make ");
+ writec (mvlim+'0');
+ writel (" move");
+ if (mvlim > 1)
+ writec ('s');
+ writec ('.');
+ writec ('\n');
+ break;
+
+ case -3:
+ if (quit())
+ return;
+ }
+
+ if (! tflag)
+ proll ();
+ else {
+ curmove (cturn == -1? 18: 19,39);
+ cline ();
+ c = -1;
+ }
+ }
+}
+
+movokay (mv)
+register int mv;
+
+{
+ register int i, m;
+
+ if (d0)
+ swap;
+
+ for (i = 0; i < mv; i++) {
+
+ if (p[i] == g[i]) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Attempt to move to same location.\n");
+ return (0);
+ }
+
+ if (cturn*(g[i]-p[i]) < 0) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Backwards move.\n");
+ return (0);
+ }
+
+ if (abs(board[bar]) && p[i] != bar) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Men still on bar.\n");
+ return (0);
+ }
+
+ if ( (m = makmove(i)) ) {
+ moverr (i);
+ switch (m) {
+
+ case 1:
+ writel ("Move not rolled.\n");
+ break;
+
+ case 2:
+ writel ("Bad starting position.\n");
+ break;
+
+ case 3:
+ writel ("Destination occupied.\n");
+ break;
+
+ case 4:
+ writel ("Can't remove men yet.\n");
+ }
+ return (0);
+ }
+ }
+ return (1);
+}
diff --git a/backgammon/common_source/fancy.c b/backgammon/common_source/fancy.c
new file mode 100644
index 00000000..6afaa367
--- /dev/null
+++ b/backgammon/common_source/fancy.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)fancy.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char PC; /* padding character */
+char *BC; /* backspace sequence */
+char *CD; /* clear to end of screen sequence */
+char *CE; /* clear to end of line sequence */
+char *CL; /* clear screen sequence */
+char *CM; /* cursor movement instructions */
+char *HO; /* home cursor sequence */
+char *MC; /* column cursor movement map */
+char *ML; /* row cursor movement map */
+char *ND; /* forward cursor sequence */
+char *UP; /* up cursor sequence */
+
+int lHO; /* length of HO */
+int lBC; /* length of BC */
+int lND; /* length of ND */
+int lUP; /* length of UP */
+int CO; /* number of columns */
+int LI; /* number of lines */
+int *linect; /* array of lengths of lines on screen
+ (the actual screen is not stored) */
+
+ /* two letter codes */
+char tcap[] = "bccdceclcmhomcmlndup";
+ /* corresponding strings */
+char **tstr[] = { &BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP };
+
+int buffnum; /* pointer to output buffer */
+
+char tbuf[1024]; /* buffer for decoded termcap entries */
+
+int oldb[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+int oldr;
+int oldw;
+ /* "real" cursor positions, so
+ * it knows when to reposition.
+ * These are -1 if curr and curc
+ * are accurate */
+int realr;
+int realc;
+
+void addbuf();
+
+fboard () {
+ register int i, j, l;
+
+ curmove (0,0); /* do top line */
+ for (i = 0; i < 53; i++)
+ fancyc ('_');
+
+ curmove (15,0); /* do botttom line */
+ for (i = 0; i < 53; i++)
+ fancyc ('_');
+
+ l = 1; /* do vertical lines */
+ for (i = 52; i > -1; i -= 28) {
+ curmove ( (l == 1? 1: 15) ,i);
+ fancyc ('|');
+ for (j = 0; j < 14; j++) {
+ curmove (curr+l,curc-1);
+ fancyc ('|');
+ }
+ if (i == 24)
+ i += 32;
+ l = -l; /* alternate directions */
+ }
+
+ curmove (2,1); /* label positions 13-18 */
+ for (i = 13; i < 18; i++) {
+ fancyc ('1');
+ fancyc ((i % 10)+'0');
+ curmove (curr,curc+2);
+ }
+ fancyc ('1');
+ fancyc ('8');
+
+ curmove (2,29); /* label positions 19-24 */
+ fancyc ('1');
+ fancyc ('9');
+ for (i = 20; i < 25; i++) {
+ curmove (curr,curc+2);
+ fancyc ('2');
+ fancyc ((i % 10)+'0');
+ }
+
+ curmove (14,1); /* label positions 12-7 */
+ fancyc ('1');
+ fancyc ('2');
+ for (i = 11; i > 6; i--) {
+ curmove (curr,curc+2);
+ fancyc (i > 9? '1': ' ');
+ fancyc ((i % 10)+'0');
+ }
+
+ curmove (14,30); /* label positions 6-1 */
+ fancyc ('6');
+ for (i = 5; i > 0; i--) {
+ curmove (curr,curc+3);
+ fancyc (i+'0');
+ }
+
+ for (i = 12; i > 6; i--) /* print positions 12-7 */
+ if (board[i])
+ bsect (board[i],13,1+4*(12-i),-1);
+
+ if (board[0]) /* print red men on bar */
+ bsect (board[0],13,25,-1);
+
+ for (i = 6; i > 0; i--) /* print positions 6-1 */
+ if (board[i])
+ bsect (board[i],13,29+4*(6-i),-1);
+
+ l = (off[1] < 0? off[1]+15: off[1]); /* print white's home */
+ bsect (l,3,54,1);
+
+ curmove (8,25); /* print the word BAR */
+ fancyc ('B');
+ fancyc ('A');
+ fancyc ('R');
+
+ for (i = 13; i < 19; i++) /* print positions 13-18 */
+ if (board[i])
+ bsect (board[i],3,1+4*(i-13),1);
+
+ if (board[25]) /* print white's men on bar */
+ bsect (board[25],3,25,1);
+
+ for (i = 19; i < 25; i++) /* print positions 19-24 */
+ if (board[i])
+ bsect (board[i],3,29+4*(i-19),1);
+
+ l = (off[0] < 0? off[0]+15: off[0]); /* print red's home */
+ bsect (-l,13,54,-1);
+
+ for (i = 0; i < 26; i++) /* save board position
+ * for refresh later */
+ oldb[i] = board[i];
+ oldr = (off[1] < 0? off[1]+15: off[1]);
+ oldw = -(off[0] < 0? off[0]+15: off[0]);
+}
+
+/*
+ * bsect (b,rpos,cpos,cnext)
+ * Print the contents of a board position. "b" has the value of the
+ * position, "rpos" is the row to start printing, "cpos" is the column to
+ * start printing, and "cnext" is positive if the position starts at the top
+ * and negative if it starts at the bottom. The value of "cpos" is checked
+ * to see if the position is a player's home, since those are printed
+ * differently.
+ */
+
+bsect (b,rpos,cpos,cnext)
+int b; /* contents of position */
+int rpos; /* row of position */
+int cpos; /* column of position */
+int cnext; /* direction of position */
+
+{
+ register int j; /* index */
+ register int n; /* number of men on position */
+ register int bct; /* counter */
+ int k; /* index */
+ char pc; /* color of men on position */
+
+ n = abs(b); /* initialize n and pc */
+ pc = (b > 0? 'r': 'w');
+
+ if (n < 6 && cpos < 54) /* position cursor at start */
+ curmove (rpos,cpos+1);
+ else
+ curmove (rpos,cpos);
+
+ for (j = 0; j < 5; j++) { /* print position row by row */
+
+ for (k = 0; k < 15; k += 5) /* print men */
+ if (n > j+k)
+ fancyc (pc);
+
+ if (j < 4) { /* figure how far to
+ * back up for next
+ * row */
+ if (n < 6) { /* stop if none left */
+ if (j+1 == n)
+ break;
+ bct = 1; /* single column */
+ } else {
+ if (n < 11) { /* two columns */
+ if (cpos == 54) { /* home pos */
+ if (j+5 >= n)
+ bct = 1;
+ else
+ bct = 2;
+ }
+ if (cpos < 54) { /* not home */
+ if (j+6 >= n)
+ bct = 1;
+ else
+ bct = 2;
+ }
+ } else { /* three columns */
+ if (j+10 >= n)
+ bct = 2;
+ else
+ bct = 3;
+ }
+ }
+ curmove (curr+cnext,curc-bct); /* reposition cursor */
+ }
+ }
+}
+
+refresh() {
+ register int i, r, c;
+
+ r = curr; /* save current position */
+ c = curc;
+
+ for (i = 12; i > 6; i--) /* fix positions 12-7 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],13,1+(12-i)*4,-1);
+ oldb[i] = board[i];
+ }
+
+ if (board[0] != oldb[0]) { /* fix red men on bar */
+ fixpos (oldb[0],board[0],13,25,-1);
+ oldb[0] = board[0];
+ }
+
+ for (i = 6; i > 0; i--) /* fix positions 6-1 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],13,29+(6-i)*4,-1);
+ oldb[i] = board[i];
+ }
+
+ i = -(off[0] < 0? off[0]+15: off[0]); /* fix white's home */
+ if (oldw != i) {
+ fixpos (oldw,i,13,54,-1);
+ oldw = i;
+ }
+
+ for (i = 13; i < 19; i++) /* fix positions 13-18 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],3,1+(i-13)*4,1);
+ oldb[i] = board[i];
+ }
+
+ if (board[25] != oldb[25]) { /* fix white men on bar */
+ fixpos (oldb[25],board[25],3,25,1);
+ oldb[25] = board[25];
+ }
+
+ for (i = 19; i < 25; i++) /* fix positions 19-24 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],3,29+(i-19)*4,1);
+ oldb[i] = board[i];
+ }
+
+ i = (off[1] < 0? off[1]+15: off[1]); /* fix red's home */
+ if (oldr != i) {
+ fixpos (oldr,i,3,54,1);
+ oldr = i;
+ }
+
+ curmove (r,c); /* return to saved position */
+ newpos();
+ buflush();
+}
+
+fixpos (old,new,r,c,inc)
+int old, new, r, c, inc;
+
+{
+ register int o, n, nv;
+ int ov, nc;
+ char col;
+
+ if (old*new >= 0) {
+ ov = abs(old);
+ nv = abs(new);
+ col = (old+new > 0? 'r': 'w');
+ o = (ov-1)/5;
+ n = (nv-1)/5;
+ if (o == n) {
+ if (o == 2)
+ nc = c+2;
+ if (o == 1)
+ nc = c < 54? c: c+1;
+ if (o == 0)
+ nc = c < 54? c+1: c;
+ if (ov > nv)
+ fixcol (r+inc*(nv-n*5),nc,abs(ov-nv),' ',inc);
+ else
+ fixcol (r+inc*(ov-o*5),nc,abs(ov-nv),col,inc);
+ return;
+ } else {
+ if (c < 54) {
+ if (o+n == 1) {
+ if (n) {
+ fixcol (r,c,abs(nv-5),col,inc);
+ if (ov != 5)
+ fixcol (r+inc*ov,c+1,abs(ov-5),col,inc);
+ } else {
+ fixcol (r,c,abs(ov-5),' ',inc);
+ if (nv != 5)
+ fixcol (r+inc*nv,c+1,abs(nv-5),' ',inc);
+ }
+ return;
+ }
+ if (n == 2) {
+ if (ov != 10)
+ fixcol (r+inc*(ov-5),c,abs(ov-10),col,inc);
+ fixcol (r,c+2,abs(nv-10),col,inc);
+ } else {
+ if (nv != 10)
+ fixcol (r+inc*(nv-5),c,abs(nv-10),' ',inc);
+ fixcol (r,c+2,abs(ov-10),' ',inc);
+ }
+ return;
+ }
+ if (n > o) {
+ fixcol (r+inc*(ov%5),c+o,abs(5*n-ov),col,inc);
+ if (nv != 5*n)
+ fixcol (r,c+n,abs(5*n-nv),col,inc);
+ } else {
+ fixcol (r+inc*(nv%5),c+n,abs(5*n-nv),' ',inc);
+ if (ov != 5*o)
+ fixcol (r,c+o,abs(5*o-ov),' ',inc);
+ }
+ return;
+ }
+ }
+ nv = abs(new);
+ fixcol (r,c+1,nv,new > 0? 'r': 'w',inc);
+ if (abs(old) <= abs(new))
+ return;
+ fixcol (r+inc*new,c+1,abs(old+new),' ',inc);
+}
+
+fixcol (r,c,l,ch,inc)
+register int l, ch;
+int r, c, inc;
+
+{
+ register int i;
+
+ curmove (r,c);
+ fancyc (ch);
+ for (i = 1; i < l; i++) {
+ curmove (curr+inc,curc-1);
+ fancyc (ch);
+ }
+}
+
+curmove (r,c)
+register int r, c;
+
+{
+ if (curr == r && curc == c)
+ return;
+ if (realr == -1) {
+ realr = curr;
+ realc = curc;
+ }
+ curr = r;
+ curc = c;
+}
+
+newpos () {
+ register int r; /* destination row */
+ register int c; /* destination column */
+ register int mode = -1; /* mode of movement */
+
+ int count = 1000; /* character count */
+ int i; /* index */
+ int j; /* index */
+ int n; /* temporary variable */
+ char *m; /* string containing CM movement */
+
+
+ if (realr == -1) /* see if already there */
+ return;
+
+ r = curr; /* set current and dest. positions */
+ c = curc;
+ curr = realr;
+ curc = realc;
+
+ /* double check position */
+ if (curr == r && curc == c) {
+ realr = realc = -1;
+ return;
+ }
+
+ if (CM) { /* try CM to get there */
+ mode = 0;
+ m = (char *)tgoto (CM,c,r);
+ count = strlen (m);
+ }
+
+ /* try HO and local movement */
+ if (HO && (n = r+c*lND+lHO) < count) {
+ mode = 1;
+ count = n;
+ }
+
+ /* try various LF combinations */
+ if (r >= curr) {
+ /* CR, LF, and ND */
+ if ((n = (r-curr)+c*lND+1) < count) {
+ mode = 2;
+ count = n;
+ }
+ /* LF, ND */
+ if (c >= curc && (n = (r-curr)+(c-curc)*lND) < count) {
+ mode = 3;
+ count = n;
+ }
+ /* LF, BS */
+ if (c < curc && (n = (r-curr)+(curc-c)*lBC) < count) {
+ mode = 4;
+ count = n;
+ }
+ }
+
+ /* try corresponding UP combinations */
+ if (r < curr) {
+ /* CR, UP, and ND */
+ if ((n = (curr-r)*lUP+c*lND+1) < count) {
+ mode = 5;
+ count = n;
+ }
+ /* UP and ND */
+ if (c >= curc && (n = (curr-r)*lUP+(c-curc)*lND) < count) {
+ mode = 6;
+ count = n;
+ }
+ /* UP and BS */
+ if (c < curc && (n = (curr-r)*lUP+(curc-c)*lBC) < count) {
+ mode = 7;
+ count = n;
+ }
+ }
+
+ /* space over */
+ if (curr == r && c > curc && linect[r] < curc && c-curc < count)
+ mode = 8;
+
+ switch (mode) {
+
+ case -1: /* error! */
+ write (2,"\r\nInternal cursor error.\r\n",26);
+ getout();
+
+ /* direct cursor motion */
+ case 0:
+ tputs (m,abs(curr-r),addbuf);
+ break;
+
+ /* relative to "home" */
+ case 1:
+ tputs (HO,r,addbuf);
+ for (i = 0; i < r; i++)
+ addbuf ('\012');
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* CR and down and over */
+ case 2:
+ addbuf ('\015');
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* down and over */
+ case 3:
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < c-curc; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* down and back */
+ case 4:
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < curc-c; i++)
+ addbuf ('\010');
+ break;
+
+ /* CR and up and over */
+ case 5:
+ addbuf ('\015');
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* up and over */
+ case 6:
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < c-curc; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* up and back */
+ case 7:
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < curc-c; i++) {
+ if (BC)
+ tputs (BC,1,addbuf);
+ else
+ addbuf ('\010');
+ }
+ break;
+
+ /* safe space */
+ case 8:
+ for (i = 0; i < c-curc; i++)
+ addbuf (' ');
+ }
+
+ /* fix positions */
+ curr = r;
+ curc = c;
+ realr = -1;
+ realc = -1;
+}
+
+clear () {
+ register int i;
+
+ /* double space if can't clear */
+ if (CL == 0) {
+ writel ("\n\n");
+ return;
+ }
+
+ curr = curc = 0; /* fix position markers */
+ realr = realc = -1;
+ for (i = 0; i < 24; i++) /* clear line counts */
+ linect[i] = -1;
+ buffnum = -1; /* ignore leftover buffer contents */
+ tputs (CL,CO,addbuf); /* put CL in buffer */
+}
+
+tos () { /* home cursor */
+ curmove (0,0);
+}
+
+fancyc (c)
+register char c; /* character to output */
+{
+ register int sp; /* counts spaces in a tab */
+
+ if (c == '\007') { /* bells go in blindly */
+ addbuf (c);
+ return;
+ }
+
+ /* process tabs, use spaces if the
+ * the tab should be erasing things,
+ * otherwise use cursor movement
+ * routines. Note this does not use
+ * hardware tabs at all. */
+ if (c == '\t') {
+ sp = (curc+8) & (~ 7); /* compute spaces */
+ /* check line length */
+ if (linect[curr] >= curc || sp < 4) {
+ for (; sp > curc; sp--)
+ addbuf (' ');
+ curc = sp; /* fix curc */
+ } else
+ curmove (curr,sp);
+ return;
+ }
+
+ /* do newline be calling newline */
+ if (c == '\n') {
+ newline();
+ return;
+ }
+
+ /* ignore any other control chars */
+ if (c < ' ')
+ return;
+
+ /* if an erasing space or non-space,
+ * just add it to buffer. Otherwise
+ * use cursor movement routine, so that
+ * multiple spaces will be grouped
+ * together */
+ if (c > ' ' || linect[curr] >= curc) {
+ newpos (); /* make sure position correct */
+ addbuf (c); /* add character to buffer */
+ /* fix line length */
+ if (c == ' ' && linect[curr] == curc)
+ linect[curr]--;
+ else if (linect[curr] < curc)
+ linect[curr] = curc;
+ curc++; /* fix curc */
+ } else
+ /* use cursor movement routine */
+ curmove (curr,curc+1);
+}
+
+clend() {
+ register int i;
+ register char *s;
+
+
+ if (CD) {
+ tputs (CD,CO-curr,addbuf);
+ for (i = curr; i < LI; i++)
+ linect[i] = -1;
+ return;
+ }
+
+ curmove (i = curr,0);
+ cline();
+ while (curr < LI-1) {
+ curmove (curr+1,0);
+ if (linect[curr] > -1)
+ cline ();
+ }
+ curmove (i,0);
+}
+
+cline () {
+ register int i;
+ register int c;
+ register char *s;
+
+ if (curc > linect[curr])
+ return;
+ newpos ();
+ if (CE) {
+ tputs (CE,1,addbuf);
+ linect[curr] = curc-1;
+ } else {
+ c = curc-1;
+ while (linect[curr] > c) {
+ addbuf (' ');
+ curc++;
+ linect[curr]--;
+ }
+ curmove (curr,c+1);
+ }
+}
+
+newline () {
+ cline();
+ if (curr == LI-1)
+ curmove (begscr,0);
+ else
+ curmove (curr+1,0);
+}
+
+getcaps (s)
+register char *s;
+
+{
+ register char *code; /* two letter code */
+ register char ***cap; /* pointer to cap string */
+ char *bufp; /* pointer to cap buffer */
+ char tentry[1024]; /* temporary uncoded caps buffer */
+
+ tgetent (tentry,s); /* get uncoded termcap entry */
+
+ LI = tgetnum ("li"); /* get number of lines */
+ if (LI == -1)
+ LI = 12;
+ CO = tgetnum ("co"); /* get number of columns */
+ if (CO == -1)
+ CO = 65;
+
+ bufp = tbuf; /* get padding character */
+ tgetstr ("pc",&bufp);
+ if (bufp != tbuf)
+ PC = *tbuf;
+ else
+ PC = 0;
+
+ bufp = tbuf; /* get string entries */
+ cap = tstr;
+ for (code = tcap; *code; code += 2)
+ **cap++ = (char *)tgetstr (code,&bufp);
+
+ /* get pertinent lengths */
+ if (HO)
+ lHO = strlen (HO);
+ if (BC)
+ lBC = strlen (BC);
+ else
+ lBC = 1;
+ if (UP)
+ lUP = strlen (UP);
+ if (ND)
+ lND = strlen (ND);
+ if (LI < 24 || CO < 72 || !(CL && UP && ND))
+ return (0);
+ linect = (int *)calloc (LI+1,sizeof(int));
+ return (1);
+}
diff --git a/backgammon/common_source/init.c b/backgammon/common_source/init.c
new file mode 100644
index 00000000..9d3fce3b
--- /dev/null
+++ b/backgammon/common_source/init.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <sgtty.h>
+
+/*
+ * variable initialization.
+ */
+
+ /* name of executable object programs */
+char EXEC[] = "/usr/games/backgammon";
+char TEACH[] = "/usr/games/teachgammon";
+
+int pnum = 2; /* color of player:
+ -1 = white
+ 1 = red
+ 0 = both
+ 2 = not yet init'ed */
+int acnt = 0; /* length of args */
+int aflag = 1; /* flag to ask for rules or instructions */
+int bflag = 0; /* flag for automatic board printing */
+int cflag = 0; /* case conversion flag */
+int hflag = 1; /* flag for cleaning screen */
+int mflag = 0; /* backgammon flag */
+int raflag = 0; /* 'roll again' flag for recovered game */
+int rflag = 0; /* recovered game flag */
+int tflag = 0; /* cursor addressing flag */
+int iroll = 0; /* special flag for inputting rolls */
+int rfl = 0;
+
+char *color[] = {"White","Red","white","red"};
diff --git a/backgammon/common_source/odds.c b/backgammon/common_source/odds.c
new file mode 100644
index 00000000..dc780497
--- /dev/null
+++ b/backgammon/common_source/odds.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)odds.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+odds (r1,r2,val)
+register int r1;
+int r2, val;
+{
+ register int i, j;
+
+ if (r1 == 0) {
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 6; j++)
+ table[i][j] = 0;
+ return;
+ } else {
+ r1--;
+ if (r2-- == 0)
+ for (i = 0; i < 6; i++) {
+ table[i][r1] += val;
+ table[r1][i] += val;
+ }
+ else {
+ table[r2][r1] += val;
+ table[r1][r2] += val;
+ }
+ }
+}
+
+count () {
+ register int i;
+ register int j;
+ register int total;
+
+ total = 0;
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 6; j++)
+ total += table[i][j];
+ return (total);
+}
+
+canhit (i,c)
+int i, c;
+
+{
+ register int j, k, b;
+ int a, d, diff, place, addon, menstuck;
+
+ if (c == 0)
+ odds (0,0,0);
+ if (board[i] > 0) {
+ a = -1;
+ b = 25;
+ } else {
+ a = 1;
+ b = 0;
+ }
+ place = abs (25-b-i);
+ menstuck = abs (board[b]);
+ for (j = b; j != i; j += a) {
+ if (board[j]*a > 0) {
+ diff = abs(j-i);
+ addon = place+((board[j]*a > 2 || j == b)? 5: 0);
+ if ((j == b && menstuck == 1) &&
+ (j != b && menstuck == 0))
+ for (k = 1; k < diff; k++)
+ if (k < 7 && diff-k < 7 &&
+ (board[i+a*k]*a >= 0 ||
+ board[i+a*(diff-k)] >= 0))
+ odds (k,diff-k,addon);
+ if ((j == b || menstuck < 2) && diff < 7)
+ odds (diff,0,addon);
+ }
+ if (j == b && menstuck > 1)
+ break;
+ }
+ return (count());
+}
diff --git a/backgammon/common_source/one.c b/backgammon/common_source/one.c
new file mode 100644
index 00000000..c00f4ca1
--- /dev/null
+++ b/backgammon/common_source/one.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)one.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+makmove (i)
+register int i;
+
+{
+ register int n, d;
+ int max;
+
+ d = d0;
+ n = abs(g[i]-p[i]);
+ max = (*offptr < 0? 7: last());
+ if (board[p[i]]*cturn <= 0)
+ return (checkd(d)+2);
+ if (g[i] != home && board[g[i]]*cturn < -1)
+ return (checkd(d)+3);
+ if (i || D0 == D1) {
+ if (n == max? D1 < n: D1 != n)
+ return (checkd(d)+1);
+ } else {
+ if (n == max? D0 < n && D1 < n: D0 != n && D1 != n)
+ return (checkd(d)+1);
+ if (n == max? D0 < n: D0 != n) {
+ if (d0)
+ return (checkd(d)+1);
+ swap;
+ }
+ }
+ if (g[i] == home && *offptr < 0)
+ return (checkd(d)+4);
+ h[i] = 0;
+ board[p[i]] -= cturn;
+ if (g[i] != home) {
+ if (board[g[i]] == -cturn) {
+ board[home] -= cturn;
+ board[g[i]] = 0;
+ h[i] = 1;
+ if (abs(bar-g[i]) < 7) {
+ (*inopp)--;
+ if (*offopp >= 0)
+ *offopp -= 15;
+ }
+ }
+ board[g[i]] += cturn;
+ if (abs(home-g[i]) < 7 && abs(home-p[i]) > 6) {
+ (*inptr)++;
+ if (*inptr+*offptr == 0)
+ *offptr += 15;
+ }
+ } else {
+ (*offptr)++;
+ (*inptr)--;
+ }
+ return (0);
+}
+
+moverr (i)
+register int i;
+
+{
+ register int j;
+
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ writel ("Error: ");
+ for (j = 0; j <= i; j++) {
+ wrint (p[j]);
+ writec ('-');
+ wrint (g[j]);
+ if (j < i)
+ writec (',');
+ }
+ writel ("... ");
+ movback (i);
+}
+
+
+checkd (d)
+register int d;
+
+{
+ if (d0 != d)
+ swap;
+ return (0);
+}
+
+last () {
+ register int i;
+
+ for (i = home-6*cturn; i != home; i += cturn)
+ if (board[i]*cturn > 0)
+ return (abs(home-i));
+}
+
+movback (i)
+register int i;
+
+{
+ register int j;
+
+ for (j = i-1; j >= 0; j--)
+ backone(j);
+}
+
+backone (i)
+register int i;
+
+{
+ board[p[i]] += cturn;
+ if (g[i] != home) {
+ board[g[i]] -= cturn;
+ if (abs(g[i]-home) < 7 && abs(p[i]-home) > 6) {
+ (*inptr)--;
+ if (*inptr+*offptr < 15 && *offptr >= 0)
+ *offptr -= 15;
+ }
+ } else {
+ (*offptr)--;
+ (*inptr)++;
+ }
+ if (h[i]) {
+ board[home] += cturn;
+ board[g[i]] = -cturn;
+ if (abs(bar-g[i]) < 7) {
+ (*inopp)++;
+ if (*inopp+*offopp == 0)
+ *offopp += 15;
+ }
+ }
+}
diff --git a/backgammon/common_source/save.c b/backgammon/common_source/save.c
new file mode 100644
index 00000000..b91d3ec3
--- /dev/null
+++ b/backgammon/common_source/save.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)save.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+extern int errno;
+
+static char confirm[] = "Are you sure you want to leave now?";
+static char prompt[] = "Enter a file name: ";
+static char exist1[] = "The file '";
+static char exist2[] =
+ "' already exists.\nAre you sure you want to use this file?";
+static char cantuse[] = "\nCan't use ";
+static char saved[] = "This game has been saved on the file '";
+static char type[] = "'.\nType \"backgammon ";
+static char rec[] = "\" to recover your game.\n\n";
+static char cantrec[] = "Can't recover file: ";
+
+save (n)
+register int n;
+
+{
+ register int fdesc;
+ register char *fs;
+ char fname[50];
+
+ if (n) {
+ if (tflag) {
+ curmove (20,0);
+ clend();
+ } else
+ writec ('\n');
+ writel (confirm);
+ if (! yorn(0))
+ return;
+ }
+ cflag = 1;
+ for (;;) {
+ writel (prompt);
+ fs = fname;
+ while ((*fs = readc()) != '\n') {
+ if (*fs == tty.sg_erase) {
+ if (fs > fname) {
+ fs--;
+ if (tflag)
+ curmove (curr,curc-1);
+ else
+ writec (*fs);
+ } else
+ writec ('\007');
+ continue;
+ }
+ writec (*fs++);
+ }
+ *fs = '\0';
+ if ((fdesc = open(fname,2)) == -1 && errno == 2) {
+ if ((fdesc = creat (fname,0700)) != -1)
+ break;
+ }
+ if (fdesc != -1) {
+ if (tflag) {
+ curmove (18,0);
+ clend();
+ } else
+ writec ('\n');
+ writel (exist1);
+ writel (fname);
+ writel (exist2);
+ cflag = 0;
+ close (fdesc);
+ if (yorn (0)) {
+ unlink (fname);
+ fdesc = creat (fname,0700);
+ break;
+ } else {
+ cflag = 1;
+ continue;
+ }
+ }
+ writel (cantuse);
+ writel (fname);
+ writel (".\n");
+ close (fdesc);
+ cflag = 1;
+ }
+ write (fdesc,board,sizeof board);
+ write (fdesc,off,sizeof off);
+ write (fdesc,in,sizeof in);
+ write (fdesc,dice,sizeof dice);
+ write (fdesc,&cturn,sizeof cturn);
+ write (fdesc,&dlast,sizeof dlast);
+ write (fdesc,&pnum,sizeof pnum);
+ write (fdesc,&rscore,sizeof rscore);
+ write (fdesc,&wscore,sizeof wscore);
+ write (fdesc,&gvalue,sizeof gvalue);
+ write (fdesc,&raflag,sizeof raflag);
+ close (fdesc);
+ if (tflag)
+ curmove (18,0);
+ writel (saved);
+ writel (fname);
+ writel (type);
+ writel (fname);
+ writel (rec);
+ if (tflag)
+ clend();
+ getout ();
+}
+
+recover (s)
+char *s;
+
+{
+ register int i;
+ int fdesc;
+
+ if ((fdesc = open (s,0)) == -1)
+ norec (s);
+ read (fdesc,board,sizeof board);
+ read (fdesc,off,sizeof off);
+ read (fdesc,in,sizeof in);
+ read (fdesc,dice,sizeof dice);
+ read (fdesc,&cturn,sizeof cturn);
+ read (fdesc,&dlast,sizeof dlast);
+ read (fdesc,&pnum,sizeof pnum);
+ read (fdesc,&rscore,sizeof rscore);
+ read (fdesc,&wscore,sizeof wscore);
+ read (fdesc,&gvalue,sizeof gvalue);
+ read (fdesc,&raflag,sizeof raflag);
+ close (fdesc);
+ rflag = 1;
+}
+
+norec (s)
+register char *s;
+
+{
+ register char *c;
+
+ tflag = 0;
+ writel (cantrec);
+ c = s;
+ while (*c != '\0')
+ writec (*c++);
+ getout ();
+}
diff --git a/backgammon/common_source/subs.c b/backgammon/common_source/subs.c
new file mode 100644
index 00000000..7917124f
--- /dev/null
+++ b/backgammon/common_source/subs.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)subs.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "back.h"
+
+int buffnum;
+char outbuff[BUFSIZ];
+
+static char plred[] = "Player is red, computer is white.";
+static char plwhite[] = "Player is white, computer is red.";
+static char nocomp[] = "(No computer play.)";
+
+char *descr[] = {
+ "Usage: backgammon [-] [n r w b pr pw pb t3a]\n",
+ "\t-\tgets this list\n\tn\tdon't ask for rules or instructions",
+ "\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)",
+ "\tb\ttwo players, red and white (implies n)",
+ "\tpr\tprint the board before red's turn",
+ "\tpw\tprint the board before white's turn",
+ "\tpb\tprint the board before both player's turn",
+ "\tterm\tterminal is a term",
+ "\tsfile\trecover saved game from file",
+ 0
+};
+
+errexit (s)
+register char *s;
+{
+ write (2,"\n",1);
+ perror (s);
+ getout();
+}
+
+strset (s1,s2)
+register char *s1, *s2;
+{
+ while ( (*s1++ = *s2++) != '\0');
+}
+
+addbuf (c)
+register char c;
+
+{
+ buffnum++;
+ if (buffnum == BUFSIZ) {
+ if (write(1,outbuff,BUFSIZ) != BUFSIZ)
+ errexit ("addbuf (write):");
+ buffnum = 0;
+ }
+ outbuff[buffnum] = c;
+}
+
+buflush () {
+ if (buffnum < 0)
+ return;
+ buffnum++;
+ if (write (1,outbuff,buffnum) != buffnum)
+ errexit ("buflush (write):");
+ buffnum = -1;
+}
+
+readc () {
+ char c;
+
+ if (tflag) {
+ cline();
+ newpos();
+ }
+ buflush();
+ if (read(0,&c,1) != 1)
+ errexit ("readc");
+#ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
+ if (c == '\177')
+ getout();
+#endif
+ if (c == '\033' || c == '\015')
+ return ('\n');
+ if (cflag)
+ return (c);
+ if (c == '\014')
+ return ('R');
+ if (c >= 'a' && c <= 'z')
+ return (c & 0137);
+ return (c);
+}
+
+writec (c)
+char c;
+{
+ if (tflag)
+ fancyc (c);
+ else
+ addbuf (c);
+}
+
+writel (l)
+register char *l;
+{
+#ifdef DEBUG
+ register char *s;
+
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+
+ fprintf (trace,"writel: \"");
+ for (s = l; *s; s++) {
+ if (*s < ' ' || *s == '\177')
+ fprintf (trace,"^%c",(*s)^0100);
+ else
+ putc (*s,trace);
+ }
+ fprintf (trace,"\"\n");
+ fflush (trace);
+#endif
+
+ while (*l)
+ writec (*l++);
+}
+
+proll () {
+ if (d0)
+ swap;
+ if (cturn == 1)
+ writel ("Red's roll: ");
+ else
+ writel ("White's roll: ");
+ writec (D0+'0');
+ writec ('\040');
+ writec (D1+'0');
+ if (tflag)
+ cline();
+}
+
+wrint (n)
+int n;
+{
+ register int i, j, t;
+
+ for (i = 4; i > 0; i--) {
+ t = 1;
+ for (j = 0; j<i; j++)
+ t *= 10;
+ if (n > t-1)
+ writec ((n/t)%10+'0');
+ }
+ writec (n%10+'0');
+}
+
+gwrite() {
+ register int r, c;
+
+ if (tflag) {
+ r = curr;
+ c = curc;
+ curmove (16,0);
+ }
+
+ if (gvalue > 1) {
+ writel ("Game value: ");
+ wrint (gvalue);
+ writel (". ");
+ if (dlast == -1)
+ writel (color[0]);
+ else
+ writel (color[1]);
+ writel (" doubled last.");
+ } else {
+ switch (pnum) {
+ case -1: /* player is red */
+ writel (plred);
+ break;
+ case 0: /* player is both colors */
+ writel (nocomp);
+ break;
+ case 1: /* player is white */
+ writel (plwhite);
+ }
+ }
+
+ if (rscore || wscore) {
+ writel (" ");
+ wrscore();
+ }
+
+ if (tflag) {
+ cline();
+ curmove (r,c);
+ }
+}
+
+quit () {
+ register int i;
+
+ if (tflag) {
+ curmove (20,0);
+ clend();
+ } else
+ writec ('\n');
+ writel ("Are you sure you want to quit?");
+ if (yorn (0)) {
+ if (rfl) {
+ writel ("Would you like to save this game?");
+ if (yorn(0))
+ save(0);
+ }
+ cturn = 0;
+ return (1);
+ }
+ return (0);
+}
+
+yorn (special)
+register char special; /* special response */
+{
+ register char c;
+ register int i;
+
+ i = 1;
+ while ( (c = readc()) != 'Y' && c != 'N') {
+ if (special && c == special)
+ return (2);
+ if (i) {
+ if (special) {
+ writel (" (Y, N, or ");
+ writec (special);
+ writec (')');
+ } else
+ writel (" (Y or N)");
+ i = 0;
+ } else
+ writec ('\007');
+ }
+ if (c == 'Y')
+ writel (" Yes.\n");
+ else
+ writel (" No.\n");
+ if (tflag)
+ buflush();
+ return (c == 'Y');
+}
+
+wrhit (i)
+register int i;
+{
+ writel ("Blot hit on ");
+ wrint (i);
+ writec ('.');
+ writec ('\n');
+}
+
+nexturn () {
+ register int c;
+
+ cturn = -cturn;
+ c = cturn/abs(cturn);
+ home = bar;
+ bar = 25-bar;
+ offptr += c;
+ offopp -= c;
+ inptr += c;
+ inopp -= c;
+ Colorptr += c;
+ colorptr += c;
+}
+
+getarg (arg)
+register char ***arg;
+
+{
+ register char **s;
+
+ /* process arguments here. dashes are ignored, nbrw are ignored
+ if the game is being recovered */
+
+ s = *arg;
+ while (s[0][0] == '-') {
+ switch (s[0][1]) {
+
+ /* don't ask if rules or instructions needed */
+ case 'n':
+ if (rflag)
+ break;
+ aflag = 0;
+ args[acnt++] = 'n';
+ break;
+
+ /* player is both read and white */
+ case 'b':
+ if (rflag)
+ break;
+ pnum = 0;
+ aflag = 0;
+ args[acnt++] = 'b';
+ break;
+
+ /* player is red */
+ case 'r':
+ if (rflag)
+ break;
+ pnum = -1;
+ aflag = 0;
+ args[acnt++] = 'r';
+ break;
+
+ /* player is white */
+ case 'w':
+ if (rflag)
+ break;
+ pnum = 1;
+ aflag = 0;
+ args[acnt++] = 'w';
+ break;
+
+ /* print board after move according to following character */
+ case 'p':
+ if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
+ break;
+ args[acnt++] = 'p';
+ args[acnt++] = s[0][2];
+ if (s[0][2] == 'r')
+ bflag = 1;
+ if (s[0][2] == 'w')
+ bflag = -1;
+ if (s[0][2] == 'b')
+ bflag = 0;
+ break;
+
+ case 't':
+ if (s[0][2] == '\0') { /* get terminal caps */
+ s++;
+ tflag = getcaps (*s);
+ } else
+ tflag = getcaps (&s[0][2]);
+ break;
+
+ case 's':
+ s++;
+ /* recover file */
+ recover (s[0]);
+ break;
+ }
+ s++;
+ }
+ if (s[0] != 0)
+ recover(s[0]);
+}
+
+init () {
+ register int i;
+ for (i = 0; i < 26;)
+ board[i++] = 0;
+ board[1] = 2;
+ board[6] = board[13] = -5;
+ board[8] = -3;
+ board[12] = board[19] = 5;
+ board[17] = 3;
+ board[24] = -2;
+ off[0] = off[1] = -15;
+ in[0] = in[1] = 5;
+ gvalue = 1;
+ dlast = 0;
+}
+
+wrscore () {
+ writel ("Score: ");
+ writel (color[1]);
+ writec (' ');
+ wrint (rscore);
+ writel (", ");
+ writel (color[0]);
+ writec (' ');
+ wrint (wscore);
+}
+
+fixtty (mode)
+int mode;
+{
+ if (tflag)
+ newpos();
+ buflush();
+ tty.sg_flags = mode;
+ if (stty (0,&tty) < 0)
+ errexit("fixtty");
+}
+
+getout () {
+ /* go to bottom of screen */
+ if (tflag) {
+ curmove (23,0);
+ cline();
+ } else
+ writec ('\n');
+
+ /* fix terminal status */
+ fixtty (old);
+ exit();
+}
+roll () {
+ register char c;
+ register int row;
+ register int col;
+
+ if (iroll) {
+ if (tflag) {
+ row = curr;
+ col = curc;
+ curmove (17,0);
+ } else
+ writec ('\n');
+ writel ("ROLL: ");
+ c = readc();
+ if (c != '\n') {
+ while (c < '1' || c > '6')
+ c = readc();
+ D0 = c-'0';
+ writec (' ');
+ writec (c);
+ c = readc();
+ while (c < '1' || c > '6')
+ c = readc();
+ D1 = c-'0';
+ writec (' ');
+ writec (c);
+ if (tflag) {
+ curmove (17,0);
+ cline();
+ curmove (row,col);
+ } else
+ writec ('\n');
+ return;
+ }
+ if (tflag) {
+ curmove (17,0);
+ cline();
+ curmove (row,col);
+ } else
+ writec ('\n');
+ }
+ D0 = rnum(6)+1;
+ D1 = rnum(6)+1;
+ d0 = 0;
+}
diff --git a/backgammon/common_source/table.c b/backgammon/common_source/table.c
new file mode 100644
index 00000000..9555e8dd
--- /dev/null
+++ b/backgammon/common_source/table.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)table.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *help2[] = {
+ " Enter moves as <s>-<f> or <s>/<r> where <s> is the starting",
+ "position, <f> is the finishing position, and <r> is the roll.",
+ "Remember, each die roll must be moved separately.",
+ 0
+};
+
+struct state {
+ char ch;
+ int fcode;
+ int newst;
+};
+
+struct state atmata[] = {
+
+ 'R', 1, 0, '?', 7, 0, 'Q', 0, -3, 'B', 8, 25,
+ '9', 2, 25, '8', 2, 25, '7', 2, 25, '6', 2, 25,
+ '5', 2, 25, '4', 2, 25, '3', 2, 25, '2', 2, 19,
+ '1', 2, 15, '0', 2, 25, '.', 0, 0, '9', 2, 25,
+ '8', 2, 25, '7', 2, 25, '6', 2, 25, '5', 2, 25,
+
+ '4', 2, 25, '3', 2, 25, '2', 2, 25, '1', 2, 25,
+ '0', 2, 25, '/', 0, 32, '-', 0, 39, '.', 0, 0,
+ '/', 5, 32, ' ', 6, 3, ',', 6, 3, '\n', 0, -1,
+ '6', 3, 28, '5', 3, 28, '4', 3, 28, '3', 3, 28,
+ '2', 3, 28, '1', 3, 28, '.', 0, 0, 'H', 9, 61,
+
+ '9', 4, 61, '8', 4, 61, '7', 4, 61, '6', 4, 61,
+ '5', 4, 61, '4', 4, 61, '3', 4, 61, '2', 4, 53,
+ '1', 4, 51, '0', 4, 61, '.', 0, 0, '9', 4, 61,
+ '8', 4, 61, '7', 4, 61, '6', 4, 61, '5', 4, 61,
+ '4', 4, 61, '3', 4, 61, '2', 4, 61, '1', 4, 61,
+
+ '0', 4, 61, ' ', 6, 3, ',', 6, 3, '-', 5, 39,
+ '\n', 0, -1, '.', 0, 0
+};
+
+checkmove (ist)
+
+int ist;
+
+{
+ register int j, n;
+ register char c;
+ char a;
+
+domove:
+ if (ist == 0) {
+ if (tflag)
+ curmove (curr,32);
+ else
+ writel ("\t\t");
+ writel ("Move: ");
+ }
+ ist = mvl = ncin = 0;
+ for (j = 0; j < 5; j++)
+ p[j] = g[j] = -1;
+
+dochar:
+ c = readc();
+
+ if (c == 'S') {
+ raflag = 0;
+ save (1);
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,39);
+ ist = -1;
+ goto domove;
+ } else {
+ proll ();
+ ist = 0;
+ goto domove;
+ }
+ }
+
+ if (c == tty.sg_erase && ncin > 0) {
+ if (tflag)
+ curmove (curr,curc-1);
+ else {
+ if (tty.sg_erase == '\010')
+ writel ("\010 \010");
+ else
+ writec (cin[ncin-1]);
+ }
+ ncin--;
+ n = rsetbrd();
+ if (n == 0) {
+ n = -1;
+ if (tflag)
+ refresh();
+ }
+ if ((ist = n) > 0)
+ goto dochar;
+ goto domove;
+ }
+
+ if (c == tty.sg_kill && ncin > 0) {
+ if (tflag) {
+ refresh();
+ curmove (curr,39);
+ ist = -1;
+ goto domove;
+ } else if (tty.sg_erase == '\010') {
+ for (j = 0; j < ncin; j++)
+ writel ("\010 \010");
+ ist = -1;
+ goto domove;
+ } else {
+ writec ('\\');
+ writec ('\n');
+ proll ();
+ ist = 0;
+ goto domove;
+ }
+ }
+
+ n = dotable(c,ist);
+ if (n >= 0) {
+ cin[ncin++] = c;
+ if (n > 2)
+ if ((! tflag) || c != '\n')
+ writec (c);
+ ist = n;
+ if (n)
+ goto dochar;
+ else
+ goto domove;
+ }
+
+ if (n == -1 && mvl >= mvlim)
+ return(0);
+ if (n == -1 && mvl < mvlim-1)
+ return(-4);
+
+ if (n == -6) {
+ if (! tflag) {
+ if (movokay(mvl+1)) {
+ wrboard();
+ movback (mvl+1);
+ }
+ proll ();
+ writel ("\t\tMove: ");
+ for (j = 0; j < ncin;)
+ writec (cin[j++]);
+ } else {
+ if (movokay(mvl+1)) {
+ refresh();
+ movback (mvl+1);
+ } else
+ curmove (cturn == -1? 18:19,ncin+39);
+ }
+ ist = n = rsetbrd();
+ goto dochar;
+ }
+
+ if (n != -5)
+ return(n);
+ writec ('\007');
+ goto dochar;
+}
+
+dotable (c,i)
+char c;
+register int i;
+
+{
+ register int a, j;
+ int test;
+
+ test = (c == 'R');
+
+ while ( (a = atmata[i].ch) != '.') {
+ if (a == c || (test && a == '\n')) {
+ switch (atmata[i].fcode) {
+
+ case 1:
+ wrboard();
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,0);
+ proll ();
+ writel ("\t\t");
+ } else
+ proll ();
+ break;
+
+ case 2:
+ if (p[mvl] == -1)
+ p[mvl] = c-'0';
+ else
+ p[mvl] = p[mvl]*10+c-'0';
+ break;
+
+ case 3:
+ if (g[mvl] != -1) {
+ if (mvl < mvlim)
+ mvl++;
+ p[mvl] = p[mvl-1];
+ }
+ g[mvl] = p[mvl]+cturn*(c-'0');
+ if (g[mvl] < 0)
+ g[mvl] = 0;
+ if (g[mvl] > 25)
+ g[mvl] = 25;
+ break;
+
+ case 4:
+ if (g[mvl] == -1)
+ g[mvl] = c-'0';
+ else
+ g[mvl] = g[mvl]*10+c-'0';
+ break;
+
+ case 5:
+ if (mvl < mvlim)
+ mvl++;
+ p[mvl] = g[mvl-1];
+ break;
+
+ case 6:
+ if (mvl < mvlim)
+ mvl++;
+ break;
+
+ case 7:
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ text (help2);
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,39);
+ } else {
+ writec ('\n');
+ proll();
+ writel ("\t\tMove: ");
+ }
+ break;
+
+ case 8:
+ p[mvl] = bar;
+ break;
+
+ case 9:
+ g[mvl] = home;
+ }
+
+ if (! test || a != '\n')
+ return (atmata[i].newst);
+ else
+ return (-6);
+ }
+
+ i++;
+ }
+
+ return (-5);
+}
+
+rsetbrd () {
+ register int i, j, n;
+
+ n = 0;
+ mvl = 0;
+ for (i = 0; i < 4; i++)
+ p[i] = g[i] = -1;
+ for (j = 0; j < ncin; j++)
+ n = dotable (cin[j],n);
+ return (n);
+}
diff --git a/backgammon/teachgammon/Makefile b/backgammon/teachgammon/Makefile
new file mode 100644
index 00000000..b57ab045
--- /dev/null
+++ b/backgammon/teachgammon/Makefile
@@ -0,0 +1,15 @@
+# @(#)Makefile 5.1 (Berkeley) 5/11/90
+
+PROG= teachgammon
+CFLAGS+=-DV7 -I${.CURDIR}/../common_source
+SRCS= allow.c board.c check.c data.c fancy.c init.c odds.c one.c save.c \
+ subs.c table.c teach.c ttext1.c ttext2.c tutor.c
+DPADD= ${LIBTERM} ${LIBCOMPAT}
+LDADD= -ltermcap -lcompat
+HIDEGAME=hidegame
+NOMAN= noman
+
+.PATH: ${.CURDIR}/../common_source
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/backgammon/teachgammon/data.c b/backgammon/teachgammon/data.c
new file mode 100644
index 00000000..2f7b292a
--- /dev/null
+++ b/backgammon/teachgammon/data.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)data.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "tutor.h"
+
+int maxmoves = 23;
+
+char *text0[] = {
+ "To start the game, I roll a 3, and you roll a 1. This means",
+ "that I get to start first. I move 8-5,6-5 since this makes a",
+ "new point and helps to trap your back men on 1. You should be",
+ "able to do a similar move with your roll.",
+ 0
+};
+
+char *text1[] = {
+ "Now you shall see a move using doubles. I just rolled double",
+ "5's. I will move two men from position 13 to position 3. The",
+ "notation for this is 13-8,13-8,8-3,8-3. You will also roll dou-",
+ "bles, but you will be able to make a much stronger move.",
+ 0
+};
+
+char *text2[] = {
+ "Excellent! As you can see, you are beginning to develop a wall",
+ "which is trapping my men on position 24. Also, moving your back",
+ "men forward not only improves your board position safely, but it",
+ "thwarts my effort to make a wall.",
+ "",
+ "My roll now is 5 6. Normally, I would use that roll to move from",
+ "position 24 to position 13 (24-18-13), but your new point prevents",
+ "that. Instead, I am forced to move from 13 to 2, where my man is",
+ "open but cannot be hit.",
+ 0
+};
+
+char *text3[] = {
+ "As you can see, although you left a man open, it is a rela-",
+ "tively safe move to an advantageous position, which might help",
+ "you make a point later. Only two rolls (4 5 or 5 4) will allow",
+ "me to hit you. With an unprecedented amount of luck, I happen",
+ "to roll a 4 5 and hit you as just mentioned.",
+ 0
+};
+
+char *text4[] = {
+ "You're pretty lucky yourself, you know. I follow by rolling 2 3",
+ "and moving 25-22,24-22, forming a new point.",
+ 0
+};
+
+char *text5[] = {
+ "Not a spectacular move, but a safe one. I follow by rolling 6 1.",
+ "I decide to use this roll to move 22-16,16-17. It leaves me with",
+ "one man still open, but the blot is farther back on the board, and",
+ "would suffer less of a loss by being hit.",
+ 0
+};
+
+char *text6[] = {
+ "By moving your two men from 17 to 20, you lessen my chance of",
+ "getting my man off the board. In fact, the odds are 5 to 4",
+ "against me getting off. I roll with the odds and helplessly",
+ "receive a 3 5.",
+ 0
+};
+
+char *text7[] = {
+ "Note that the blot on 7 cannot be hit unless I get off the bar",
+ "and have a 1 or a 6 left over, and doing so will leave two of",
+ "my men open. Also, the blot on 16 cannot be hit at all! With",
+ "a sigh of frustration, I roll double 6's and remain immobile.",
+ 0
+};
+
+char *text8[] = {
+ "See, you did not get hit and, you got to 'cover up' your open men.",
+ "Quite an accomplishment. Finally, I get off the bar by rolling",
+ "6 2 and moving 25-23,23-17.",
+ 0
+};
+
+char *text9[] = {
+ "My venture off the bar did not last long. However, I got lucky",
+ "and rolled double 1's, allowing me to move 0-1,1-2,15-14,15-14.",
+ 0
+};
+
+char *text10[] = {
+ "You are improving your position greatly and safely, and are well",
+ "on the way to winning the game. I roll a 6 2 and squeak past",
+ "your back man. Now the game becomes a race to the finish.",
+ 0
+};
+
+char *text11[] = {
+ "Now that it is merely a race, you are trying to get as many men",
+ "as possible into the inner table, so you can start removing them.",
+ "I roll a 3 4 and move my two men farthest back to position 11",
+ "(15-11,14-11).",
+ 0
+};
+
+char *text12[] = {
+ "The race is still on, and you have seem to be doing all right.",
+ "I roll 6 1 and move 14-8,13-12.",
+ 0
+};
+
+char *text13[] = {
+ "Notice that you get to remove men the instant you have all of",
+ "them at your inner table, even if it is the middle of a turn.",
+ "I roll 1 2 and move 13-11,12-11.",
+ 0
+};
+
+char *text14[] = {
+ "Although you could have removed a man, this move illustrates two",
+ "points: 1) You never have to remove men, and 2) You should try",
+ "to spread out your men on your inner table. Since you have one",
+ "man on each position, you should be able to remove at least two",
+ "men next turn. I roll 2 5 and move 8-6,11-6.",
+ 0
+};
+
+char *text15[] = {
+ "This time you were able to remove men. I roll 3 4 and move",
+ "11-7,11-8. The race continues.",
+ 0
+};
+
+char *text16[] = {
+ "More holes are opening up in your inner table, but you are",
+ "still very much ahead. If we were doubling, you would have",
+ "doubled long ago. I roll 2 6 and move 8-6,11-5.",
+ 0
+};
+
+char *text17[] = {
+ "It pays to spread out your men. I roll 3 5 and move 7-4,8-3.",
+ 0
+};
+
+char *text18[] = {
+ "You can only remove some men, but you spread out more and",
+ "more, in order to be able to remove men more efficiently.",
+ "I roll double 3's, which help, but not that much. I move",
+ "8-5,3-0,3-0,3-0.",
+ 0
+};
+
+char *text19[] = {
+ "I roll 1 4 and move 5-4,4-0.",
+ 0
+};
+
+char *text20[] = {
+ "You are now nicely spread out to win a game. I roll 5 6 and",
+ "move 5-0,6-0.",
+ 0
+};
+
+char *text21[] = {
+ "Any minute now. Just a few short steps from victory. I roll",
+ "2 4 and move 6-4,4-0.",
+ 0
+};
+
+char *text22[] = {
+ "It looks pretty hopeless for me, but I play on, rolling 1 3 and",
+ "moving 4-3,3-0.",
+ 0
+};
+
+char *text23[] = {
+ "Congratulations! You just won a game of backgammon against the",
+ "computer! You will now be able to play a game, but remember,",
+ "when you start playing, that doubling will be enabled, which",
+ "will add another factor to the game... Good luck!!",
+ "",
+ 0
+};
+
+struct situatn test[] = {
+ {
+ {0,2,0,0,0,0,-5,0,-3,0,0,0,5,-5,0,0,0,3,0,5,0,0,0,0,-2,0},
+ 3, 1, {8,6,0,0}, {5,5,0,0}, 4, 2, text0
+ },
+ {
+ {0,2,0,0,0,-2,-4,0,-2,0,0,0,5,-5,0,0,0,2,0,4,0,2,0,0,-2,0},
+ 5, 5, {13,13,8,8}, {8,8,3,3}, 6, 6, text1
+ },
+ {
+ {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-3,0,0,0,2,2,4,0,2,0,0,-2,0},
+ 6, 5, {13,8,0,0}, {8,2,0,0}, 1, 2, text2
+ },
+ {
+ {0,0,-1,-2,0,-2,-4,2,-2,0,0,0,2,-2,0,1,0,2,2,4,0,2,0,0,-2,0},
+ 4, 5, {24,20,0,0}, {20,15,0,0}, 2, 5, text3
+ },
+ {
+ {0,0,0,-2,0,-2,-4,3,-2,0,0,0,2,-2,0,-1,0,2,2,4,0,2,0,0,-1,-1},
+ 2, 3, {25,24,0,0}, {22,22,0,0}, 4, 1, text4
+ },
+ {
+ {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-2,0,-1,0,2,2,4,0,2,-2,0,0,0},
+ 6, 1, {22,16,0,0}, {16,15,0,0}, 3, 3, text5
+ },
+ {
+ {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-2,0,-2,0,0,2,2,2,2,2,0,0,-1},
+ 3, 5, {0,0,0,0}, {0,0,0,0}, 5, 4, text6
+ },
+ {
+ {0,0,0,-2,0,-2,-4,1,-2,0,0,0,3,-2,0,-2,1,0,2,2,2,2,2,0,0,-1},
+ 6, 6, {0,0,0,0}, {0,0,0,0}, 3, 6, text7
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,3,-2,0,-2,2,0,2,2,2,2,2,0,0,-1},
+ 2, 6, {25,23,0,0}, {23,17,0,0}, 5, 1, text8
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,2,-2,0,-2,2,0,3,2,2,2,2,0,0,-1},
+ 1, 1, {25,24,15,15}, {24,23,14,14}, 4, 6, text9
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,0,-2,-2,0,3,0,4,2,2,2,2,-1,0,0},
+ 6, 2, {23,17,0,0}, {17,15,0,0}, 1, 3, text10
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,0,-2,-2,-1,2,0,3,4,2,2,2,0,0,0},
+ 4, 3, {15,14,0,0}, {11,11,0,0}, 5, 3, text11
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,-2,0,-2,-1,0,0,0,3,5,2,3,2,0,0,0},
+ 6, 1, {14,13,0,0}, {8,12,0,0}, 4, 4, text12
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-3,0,0,-2,-1,-1,0,0,0,0,0,5,2,2,5,0,0,0},
+ 2, 1, {13,12,0,0}, {11,11,0,0}, 2, 1, text13
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-3,0,0,-4,0,0,0,0,0,0,0,5,2,2,3,1,1,0},
+ 2, 5, {8,11,0,0}, {6,6,0,0}, 6, 3, text14
+ },
+ {
+ {0,0,0,-2,0,-2,-6,0,-2,0,0,-3,0,0,0,0,0,0,0,4,2,2,2,1,1,0},
+ 4, 3, {11,11,0,0}, {7,8,0,0}, 2, 5, text15
+ },
+ {
+ {0,0,0,-2,0,-2,-6,-1,-3,0,0,-1,0,0,0,0,0,0,0,4,1,2,2,0,1,0},
+ 2, 6, {8,11,0,0}, {6,5,0,0}, 6, 1, text16
+ },
+ {
+ {0,0,0,-2,0,-3,-7,-1,-2,0,0,0,0,0,0,0,0,0,0,3,1,2,2,0,0,0},
+ 5, 3, {8,7,0,0}, {3,4,0,0}, 5, 2, text17
+ },
+ {
+ {0,0,0,-3,-1,-3,-7,0,-1,0,0,0,0,0,0,0,0,0,0,3,0,1,2,1,0,0},
+ 3, 3, {8,3,3,3}, {5,0,0,0}, 1, 6, text18
+ },
+ {
+ {0,0,0,0,-1,-4,-7,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,1,0,0},
+ 1, 4, {4,5,0,0}, {0,4,0,0}, 2, 3, text19
+ },
+ {
+ {0,0,0,0,-1,-3,-7,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0},
+ 5, 6, {6,5,0,0}, {0,0,0,0}, 1, 4, text20
+ },
+ {
+ {0,0,0,0,-1,-2,-6,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0},
+ 2, 4, {4,6,0,0}, {0,4,0,0}, 6, 2, text21
+ },
+ {
+ {0,0,0,0,-1,-2,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0},
+ 3, 1, {4,3,0,0}, {3,0,0,0}, 4, 3, text22
+ },
+ {
+ {0,0,0,0,0,-2,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ 0, 0, {0,0,0,0}, {0,0,0,0}, 0, 0, text23
+ }
+};
diff --git a/backgammon/teachgammon/teach.c b/backgammon/teachgammon/teach.c
new file mode 100644
index 00000000..18528d05
--- /dev/null
+++ b/backgammon/teachgammon/teach.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)teach.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *hello[];
+char *list[];
+char *intro1[];
+char *intro2[];
+char *moves[];
+char *remove[];
+char *hits[];
+char *endgame[];
+char *doubl[];
+char *stragy[];
+char *prog[];
+char *lastch[];
+
+extern char ospeed; /* tty output speed for termlib */
+
+char *helpm[] = {
+ "\nEnter a space or newline to roll, or",
+ " b to display the board",
+ " d to double",
+ " q to quit\n",
+ 0
+};
+
+char *contin[] = {
+ "",
+ 0
+};
+
+main (argc,argv)
+int argc;
+char **argv;
+
+{
+ register int i;
+
+ signal (2,getout);
+ if (gtty (0,&tty) == -1) /* get old tty mode */
+ errexit ("teachgammon(gtty)");
+ old = tty.sg_flags;
+#ifdef V7
+ raw = ((noech = old & ~ECHO) | CBREAK); /* set up modes */
+#else
+ raw = ((noech = old & ~ECHO) | RAW); /* set up modes */
+#endif
+ ospeed = tty.sg_ospeed; /* for termlib */
+ tflag = getcaps (getenv ("TERM"));
+#ifdef V7
+ while (*++argv != 0)
+#else
+ while (*++argv != -1)
+#endif
+ getarg (&argv);
+ if (tflag) {
+ noech &= ~(CRMOD|XTABS);
+ raw &= ~(CRMOD|XTABS);
+ clear();
+ }
+ text (hello);
+ text (list);
+ i = text (contin);
+ if (i == 0)
+ i = 2;
+ init();
+ while (i)
+ switch (i) {
+
+ case 1:
+ leave();
+
+ case 2:
+ if (i = text(intro1))
+ break;
+ wrboard();
+ if (i = text(intro2))
+ break;
+
+ case 3:
+ if (i = text(moves))
+ break;
+
+ case 4:
+ if (i = text(remove))
+ break;
+
+ case 5:
+ if (i = text(hits))
+ break;
+
+ case 6:
+ if (i = text(endgame))
+ break;
+
+ case 7:
+ if (i = text(doubl))
+ break;
+
+ case 8:
+ if (i = text(stragy))
+ break;
+
+ case 9:
+ if (i = text(prog))
+ break;
+
+ case 10:
+ if (i = text(lastch))
+ break;
+ }
+ tutor();
+}
+
+leave() {
+ if (tflag)
+ clear();
+ else
+ writec ('\n');
+ fixtty(old);
+ execl (EXEC,"backgammon",args,"n",0);
+ writel ("Help! Backgammon program is missing\007!!\n");
+ exit (-1);
+}
diff --git a/backgammon/teachgammon/ttext1.c b/backgammon/teachgammon/ttext1.c
new file mode 100644
index 00000000..adf4cc1a
--- /dev/null
+++ b/backgammon/teachgammon/ttext1.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ttext1.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *opts = " QIMRHEDSPT";
+char *prompt = "-->";
+
+char *list[] = {
+ "\n\n\tI\tIntroduction to Backgammon",
+ "\tM\tMoves and Points",
+ "\tR\tRemoving Men from the Board",
+ "\tH\tHitting Blots",
+ "\tE\tEnding the Game and Scoring",
+ "\tD\tDoubling",
+ "\tS\tStrategy",
+ "\tP\tThe Program and How to Use It",
+ "\nalso, you can type:",
+ "\t?\tto get this list",
+ "\tQ\tto go start playing",
+ "\tT\tto go straight to the tutorial",
+ 0
+};
+
+char *hello[] = {
+ "\n\032 These rules consist of text describing how to play Backgammon",
+ "followed by a tutorial session where you play a practice game",
+ "against the computer. When using this program, think carefuly",
+ "before typing, since it reacts as soon as you type something. In",
+ "addition, the program presents text output, such as these rules,",
+ "in small blocks that will not roll off the top of the screen.",
+ "Frequently, you will see the characters '-->' indicating that the",
+ "program is waiting for you to finish reading, and will continue",
+ "printing when you type a space or newline. Also, the rules are",
+ "divided into sections, and although you should read them in or-",
+ "der, you can go directly to any of them by typing one of the fol-",
+ "lowing letters:",
+ "(Remember to hit a space or a newline to continue.)",
+ "",
+ 0
+};
+
+char *intro1[] = {
+ "\nIntroduction:",
+ "\n Backgammon is a game involving the skill of two players and",
+ "the luck of two dice. There are two players, red and white, and",
+ "each player gets fifteen men. The object of the game is to re-",
+ "move all your men from the board before the opponent does. The",
+ "board consists of twenty-four positions, a 'bar' and a 'home' for",
+ "each player. It looks like this:",
+ "",
+ 0};
+
+char *intro2[] = {
+ "",
+ "\n Although not indicated on the board, the players' homes are",
+ "located just to the right of the board. A player's men are placed",
+ "there when they are removed from the board. The board you just",
+ "saw was in it's initial position. All games start with the board",
+ "looking like this. Notice that red's pieces are represented by the",
+ "letter 'r' and white's pieces are represented by the letter 'w'.",
+ "Also, a position may have zero or more pieces on it, e.g. posi-",
+ "tion 12 has five red pieces on it, while position 11 does not",
+ "have any pieces of either color.",
+ "",
+ 0};
+
+char *moves[] = {
+ "\nMoves and Points:",
+ "\n Moves are made along the positions on the board according to",
+ "their numbers. Red moves in the positive direction (clockwise",
+ "from 1 to 24), and white moves in the negative direction (coun-",
+ "terclockwise from 24 to 1).",
+ "\n A turn consists of rolling the dice, and moving the number of",
+ "positions indicated on each die. The two numbers can be used to",
+ "move one man the sum of the two rolls, or two men the number on",
+ "each individual die. For example, if red rolled 6 3 at the start",
+ "of the game, he might move a man from 1 to 7 to 10, using both",
+ "dice for one man, or he might move two men from position 12, one",
+ "to 15 and one to 18. (Red did not have to choose two men start-",
+ "ing from the same position.) In addition, doubles are treated",
+ "specially in backgammon. When a player rolls doubles, he gets to",
+ "move as if he had four dice instead of two. For instance, if you",
+ "rolled double 2's, you could move one man eight positions, four",
+ "men two positions each, or any permutation in between.",
+ "",
+ "\n However, there are certain limitations, called 'points.' A",
+ "player has a point when he has two or more men on the same posi-",
+ "tion. This gives him custody of that position, and his opponent",
+ "cannot place his men there, even if passing through on the way to",
+ "another position. When a player has six points in a row, it is",
+ "called a 'wall,' since any of his opponent's men behind the wall",
+ "cannot pass it and are trapped, at least for the moment. Notice",
+ "that this could mean that a player could not use part or all of",
+ "his roll. However, he must use as much of his roll as possible.",
+ "",
+ 0};
+
+char *remove[] = {
+ "\nRemoving Men from the Board:",
+ "\n The most important part of the game is removing men, since",
+ "that is how you win the game. Once a man is removed, he stays",
+ "off the board for the duration of the game. However, a player",
+ "cannot remove men until all his men are on his 'inner table,' or",
+ "the last six positions of the board (19-24 for red, 6-1 for",
+ "white).",
+ "\n To get off the board, a player must roll the exact number to",
+ "get his man one position past the last position on the board, or",
+ "his 'home.' Hence, if red wanted to remove a man from position",
+ "23, he would have to roll a 2, anything else would be used for",
+ "another man, or for another purpose. However, there is one ex-",
+ "ception. If the player rolling has no men far enough to move the",
+ "roll made, he may move his farthest man off the board. For exam-",
+ "ple, if red's farthest man back was on position 21, he could re-",
+ "move men from that position if he rolled a 5 or a 6, as well as a",
+ "4. Since he does not have men on 20 (where he could use a 5) or",
+ "on 19 (where he could use a 6), he can use these rolls for posi-",
+ "tion 21. A player never has to remove men, but he must make as",
+ "many moves as possible.",
+ "",
+ 0};
+
+char *hits[] = {
+ "\nHitting Blots:",
+ "\n Although two men on a position form an impenetrable point, a",
+ "lone man is not so secure. Such a man is called a 'blot' and has",
+ "the potential of getting hit by an opposing man. When a player's",
+ "blot is hit, he is placed on the bar, and the first thing that",
+ "player must do is move the man off the bar. Such moves are",
+ "counted as if the bar is one position behind the first position",
+ "on the board. Thus if red has a man on the bar and rolls 2 3, he",
+ "must move the man on the bar to position 2 or 3 before moving any",
+ "other man. If white had points on positions 2 and 3, then red",
+ "would forfeit his turn. Being on the bar is a very bad position,",
+ "for often a player can lose many turns trying to move off the",
+ "bar, as well as being set back the full distance of the board.",
+ "",
+ 0};
+
+char *endgame[] = {
+ "\nEnding the Game and Scoring:",
+ "\n Winning a game usually wins one point, the normal value of a",
+ "game. However, if the losing player has not removed any men yet,",
+ "then the winning player wins double the game value, called a",
+ "'gammon.' If the losing player has a player on the bar or on the",
+ "winner's inner table, then the winner gets triple the game value,",
+ "which is called a 'backgammon.' (So that's where the name comes",
+ "from!)",
+ "",
+ 0};
diff --git a/backgammon/teachgammon/ttext2.c b/backgammon/teachgammon/ttext2.c
new file mode 100644
index 00000000..a1279b12
--- /dev/null
+++ b/backgammon/teachgammon/ttext2.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ttext2.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *prompt, *list, *opts;
+
+char *doubl[] = {
+ "\nDoubling:",
+ "\n If a player thinks he is in a good position, he may double the",
+ "value of the game. However, his opponent may not accept the pro-",
+ "posal and forfeit the game before the price gets too high. A",
+ "player must double before he rolls, and once his double has been",
+ "accepted, he cannot double again, until his opponent has doubled.",
+ "Thus, unless the game swings back and forth in advantage between",
+ "the two players a great deal, the value of the game should be",
+ "low. At any rate, the value of the game will never go above 64,",
+ "or six doubles. However, if a player wins a backgammon at 64",
+ "points, he wins 192 points!",
+ "",
+ 0};
+
+char *stragy[] = {
+ "\nStrategy:",
+ "\n Some general hints when playing: Try not to leave men open",
+ "unless absolutely necessary. Also, it is good to make as many",
+ "points as possible. Often, two men from different positions can",
+ "be brought together to form a new point. Although walls (six",
+ "points in a row) are difficult to form, many points nestled close-",
+ "ly together produce a formidable barrier. Also, while it is good",
+ "to move back men forward, doing so lessens the opportunity for you",
+ "to hit men. Finally, remember that once the two player's have",
+ "passed each other on the board, there is no chance of either team",
+ "being hit, so the game reduces to a race off the board. Addi-",
+ "tional hints on strategy are presented in the practice game.",
+ "",
+ 0};
+
+char *prog[] = {
+ "\nThe Program and How It Works:",
+ "\n A general rule of thumb is when you don't know what to do,",
+ "type a question mark, and you should get some help. When it is",
+ "your turn, only your color will be printed out, with nothing",
+ "after it. You may double by typing a 'd', but if you type a",
+ "space or newline, you will get your roll. (Remember, you must",
+ "double before you roll.) Also, typing a 'r' will reprint the",
+ "board, and a 'q' will quit the game. The program will type",
+ "'Move:' when it wants your move, and you may indicate each die's",
+ "move with <s>-<f>, where <s> is the starting position and <f> is",
+ "the finishing position, or <s>/<r> where <r> is the roll made.",
+ "<s>-<f1>-<f2> is short for <s>-<f1>,<f1>-<f2> and <s>/<r1><r2> is",
+ "short for <s>/<r1>,<s>/<r2>. Moves may be separated by a comma",
+ "or a space.",
+ "",
+ "\n While typing, any input which does not make sense will not be",
+ "echoed, and a bell will sound instead. Also, backspacing and",
+ "killing lines will echo differently than normal. You may examine",
+ "the board by typing a 'r' if you have made a partial move, or be-",
+ "fore you type a newline, to see what the board looks like. You",
+ "must end your move with a newline. If you cannot double, your",
+ "roll will always be printed, and you will not be given the oppor-",
+ "tunity to double. Home and bar are represented by the appropri-",
+ "ate number, 0 or 25 as the case may be, or by the letters 'h' or",
+ "'b' as appropriate. You may also type 'r' or 'q' when the program",
+ "types 'Move:', which has the same effect as above. Finally, you",
+ "will get to decide if you want to play red or white (or both if you",
+ "want to play a friend) at the beginning of the session, and you",
+ "will not get to change your mind later, since the computer keeps",
+ "score.",
+ "",
+ 0};
+
+char *lastch[] = {
+ "\nTutorial (Practice Game):",
+ "\n This tutorial, for simplicity's sake, will let you play one",
+ "predetermined game. All the rolls have been pre-arranged, and",
+ "only one response will let you advance to the next move.",
+ "Although a given roll will may have several legal moves, the tu-",
+ "torial will only accept one (not including the same moves in a",
+ "different order), claiming that that move is 'best.' Obviously,",
+ "a subjective statement. At any rate, be patient with it and have",
+ "fun learning about backgammon. Also, to speed things up a lit-",
+ "tle, doubling will not take place in the tutorial, so you will",
+ "never get that opportunity, and quitting only leaves the tutori-",
+ "al, not the game. You will still be able to play backgammon",
+ "after quitting.",
+ "\n This is your last chance to look over the rules before the tu-",
+ "torial starts.",
+ "",
+ 0};
+
+text (txt)
+char **txt;
+
+{
+ char **begin;
+ char *a;
+ char b;
+ char *c;
+ int i;
+
+ fixtty (noech);
+ begin = txt;
+ while (*txt) {
+ a = *(txt++);
+ if (*a != '\0') {
+ c = a;
+ for (i = 0; *(c++) != '\0'; i--);
+ writel (a);
+ writec ('\n');
+ } else {
+ fixtty (raw);
+ writel (prompt);
+ for (;;) {
+ if ((b = readc()) == '?') {
+ if (tflag) {
+ if (begscr) {
+ curmove (18,0);
+ clend();
+ } else
+ clear();
+ } else
+ writec ('\n');
+ text (list);
+ writel (prompt);
+ continue;
+ }
+ i = 0;
+ if (b == '\n')
+ break;
+ while (i < 11) {
+ if (b == opts[i])
+ break;
+ i++;
+ }
+ if (i == 11)
+ writec ('\007');
+ else
+ break;
+ }
+ if (tflag) {
+ if (begscr) {
+ curmove (18,0);
+ clend();
+ } else
+ clear();
+ } else
+ writec ('\n');
+ if (i)
+ return(i);
+ fixtty (noech);
+ if (tflag)
+ curmove (curr,0);
+ begin = txt;
+ }
+ }
+ fixtty (raw);
+ return (0);
+}
diff --git a/backgammon/teachgammon/tutor.c b/backgammon/teachgammon/tutor.c
new file mode 100644
index 00000000..2c96308c
--- /dev/null
+++ b/backgammon/teachgammon/tutor.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tutor.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+#include "tutor.h"
+
+extern int maxmoves;
+extern char *finis[];
+
+extern struct situatn test[];
+
+static char better[] = "That is a legal move, but there is a better one.\n";
+
+tutor () {
+ register int i, j;
+
+ i = 0;
+ begscr = 18;
+ cturn = -1;
+ home = 0;
+ bar = 25;
+ inptr = &in[0];
+ inopp = &in[1];
+ offptr = &off[0];
+ offopp = &off[1];
+ Colorptr = &color[0];
+ colorptr = &color[2];
+ colen = 5;
+ wrboard();
+
+ while (1) {
+ if (! brdeq(test[i].brd,board)) {
+ if (tflag && curr == 23)
+ curmove (18,0);
+ writel (better);
+ nexturn();
+ movback (mvlim);
+ if (tflag) {
+ refresh();
+ clrest ();
+ }
+ if ((! tflag) || curr == 19) {
+ proll();
+ writec ('\t');
+ }
+ else
+ curmove (curr > 19? curr-2: curr+4,25);
+ getmove();
+ if (cturn == 0)
+ leave();
+ continue;
+ }
+ if (tflag)
+ curmove (18,0);
+ text (*test[i].com);
+ if (! tflag)
+ writec ('\n');
+ if (i == maxmoves)
+ break;
+ D0 = test[i].roll1;
+ D1 = test[i].roll2;
+ d0 = 0;
+ mvlim = 0;
+ for (j = 0; j < 4; j++) {
+ if (test[i].mp[j] == test[i].mg[j])
+ break;
+ p[j] = test[i].mp[j];
+ g[j] = test[i].mg[j];
+ mvlim++;
+ }
+ if (mvlim)
+ for (j = 0; j < mvlim; j++)
+ if (makmove(j))
+ writel ("AARGH!!!\n");
+ if (tflag)
+ refresh();
+ nexturn();
+ D0 = test[i].new1;
+ D1 = test[i].new2;
+ d0 = 0;
+ i++;
+ mvlim = movallow();
+ if (mvlim) {
+ if (tflag)
+ clrest();
+ proll();
+ writec('\t');
+ getmove();
+ if (tflag)
+ refresh();
+ if (cturn == 0)
+ leave();
+ }
+ }
+ leave();
+}
+
+clrest () {
+ register int r, c, j;
+
+ r = curr;
+ c = curc;
+ for (j = r+1; j < 24; j++) {
+ curmove (j,0);
+ cline();
+ }
+ curmove (r,c);
+}
+
+brdeq (b1,b2)
+register int *b1, *b2;
+
+{
+ register int *e;
+
+ e = b1+26;
+ while (b1 < e)
+ if (*b1++ != *b2++)
+ return(0);
+ return(1);
+}
diff --git a/backgammon/teachgammon/tutor.h b/backgammon/teachgammon/tutor.h
new file mode 100644
index 00000000..6bd1cf87
--- /dev/null
+++ b/backgammon/teachgammon/tutor.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tutor.h 5.4 (Berkeley) 6/1/90
+ */
+
+struct situatn {
+ int brd[26];
+ int roll1;
+ int roll2;
+ int mp[4];
+ int mg[4];
+ int new1;
+ int new2;
+ char *(*com[8]);
+};
diff --git a/battlestar/Makefile b/battlestar/Makefile
new file mode 100644
index 00000000..0f65e58a
--- /dev/null
+++ b/battlestar/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 5.5 (Berkeley) 5/11/90
+
+PROG= battlestar
+SRCS= battlestar.c com1.c com2.c com3.c com4.c com5.c com6.c com7.c \
+ init.c cypher.c getcom.c parse.c room.c save.c fly.c misc.c \
+ globals.c dayfile.c nightfile.c dayobjs.c nightobjs.c words.c
+MAN6= battlestar.0
+DPADD= ${LIBCURSES} ${LIBTERMCAP} ${LIBCOMPAT}
+LDADD= -lcurses -ltermlib -lcompat
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
diff --git a/battlestar/battlestar.6 b/battlestar/battlestar.6
new file mode 100644
index 00000000..24fabf34
--- /dev/null
+++ b/battlestar/battlestar.6
@@ -0,0 +1,164 @@
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)battlestar.6 1.4 (Berkeley) 6/23/90
+.\"
+.TH BATTLESTAR 6 "June 23, 1990
+.UC 6
+.SH NAME
+battlestar \- a tropical adventure game
+.SH SYNOPSIS
+.B battlestar
+[
+.B -r (recover a saved game)
+]
+.br
+.fi
+.SH DESCRIPTION
+.I Battlestar
+is an adventure game in the classic style. However, It's slightly less
+of a
+puzzle and more a game of exploration. There are a few magical words
+in the game, but on the whole, simple English
+should suffice to make one's desires understandable to the parser.
+.SH "THE SETTING"
+In the days before the darkness came, when battlestars ruled the
+heavens...
+.br
+.nf
+
+ Three He made and gave them to His daughters,
+ Beautiful nymphs, the goddesses of the waters.
+ One to bring good luck and simple feats of wonder,
+ Two to wash the lands and churn the waves asunder,
+ Three to rule the world and purge the skies with thunder.
+
+.fi
+.PP
+In those times great wizards were known and their powers were beyond
+belief. They could take any object from thin air, and, uttering the
+word `su' could disappear.
+.PP
+In those times men were known for their lust of gold and desire to
+wear fine weapons. Swords and coats of mail were fashioned that could
+withstand a laser blast.
+.PP
+But when the darkness fell, the rightful reigns were toppled. Swords
+and helms and heads of state went rolling across the grass. The entire
+fleet of battlestars was reduced to a single ship.
+.SH "SAMPLE COMMANDS"
+.nf
+
+ take --- take an object
+ drop --- drop an object
+
+ wear --- wear an object you are holding
+ draw --- carry an object you are wearing
+
+ puton --- take an object and wear it
+ take off -- draw an object and drop it
+
+ throw <object> <direction>
+
+ ! <shell esc>
+
+.fi
+.SH "IMPLIED OBJECTS"
+.nf
+
+ >-: take watermelon
+ watermelon:
+ Taken.
+ >-: eat
+ watermelon:
+ Eaten.
+ >-: take knife and sword and apple, drop all
+ knife:
+ Taken.
+ broadsword:
+ Taken.
+ apple:
+ Taken.
+ knife:
+ Dropped.
+ broadsword:
+ Dropped.
+ apple:
+ Dropped.
+ >-: get
+ knife:
+ Taken.
+
+.fi
+.PP
+Notice that the "shadow" of the next word stays around if you
+want to take advantage of it. That is, saying "take knife" and then
+"drop"
+will drop the knife you just took.
+.SH "SCORE & INVEN"
+The two commands "score" and "inven" will print out your current status
+in
+the game.
+.SH "SAVING A GAME"
+The command "save" will save your game in a file called "Bstar." You
+can
+recover a saved game by using the "-r" option when you start up the
+game.
+.SH DIRECTIONS
+The compass directions N, S, E, and W can be used if you have a compass.
+If you don't have a compass, you'll have to say R, L, A, or B, which
+stand for
+Right, Left, Ahead, and Back. Directions printed in room descriptions
+are
+always printed in R, L, A, & B relative directions.
+.SH HISTORY
+I wrote Battlestar in 1979 in order to experiment with the niceties of
+the C Language.
+Most interesting things that happen in the game are hardwired into the
+code, so don't
+send me any hate mail about it! Instead, enjoy art for art's sake!
+.SH AUTHOR
+David Riggle
+.SH "INSPIRATION & ASSISTANCE"
+Chris Guthrie
+.br
+Peter Da Silva
+.br
+Kevin Brown
+.br
+Edward Wang
+.br
+Ken Arnold & Company
+.SH BUGS
+Countless.
+.SH "FAN MAIL"
+Send to edward%ucbarpa@Berkeley.arpa, chris%ucbcory@berkeley.arpa,
+riggle.pa@xerox.arpa.
diff --git a/battlestar/battlestar.c b/battlestar/battlestar.c
new file mode 100644
index 00000000..ea373e89
--- /dev/null
+++ b/battlestar/battlestar.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)battlestar.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * Battlestar - a stellar-tropical adventure game
+ *
+ * Originally written by His Lordship, Admiral David W. Horatio Riggle,
+ * on the Cory PDP-11/70, University of California, Berkeley.
+ */
+
+#include "externs.h"
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+ char mainbuf[LINELENGTH];
+ char *next;
+
+ initialize(argc < 2 || strcmp(argv[1], "-r"));
+start:
+ news();
+ beenthere[position]++;
+ if (notes[LAUNCHED])
+ crash(); /* decrements fuel & crash */
+ if (matchlight) {
+ puts("Your match splutters out.");
+ matchlight = 0;
+ }
+ if (!notes[CANTSEE] || testbit(inven,LAMPON) ||
+ testbit(location[position].objects, LAMPON)) {
+ writedes();
+ printobjs();
+ } else
+ puts("It's too dark to see anything in here!");
+ whichway(location[position]);
+run:
+ next = getcom(mainbuf, sizeof mainbuf, ">-: ",
+ "Please type in something.");
+ for (wordcount = 0; next && wordcount < 20; wordcount++)
+ next = getword(next, words[wordcount], -1);
+ parse();
+ switch (cypher()) {
+ case -1:
+ goto run;
+ case 0:
+ goto start;
+ default:
+ exit();
+ }
+}
diff --git a/battlestar/com1.c b/battlestar/com1.c
new file mode 100644
index 00000000..5b08526f
--- /dev/null
+++ b/battlestar/com1.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)com1.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+move(thataway, token)
+int thataway, token;
+{
+ wordnumber++;
+ if ((!notes[CANTMOVE] && !notes[LAUNCHED]) || testbit(location[position].objects, LAND) || fuel > 0 && notes[LAUNCHED])
+ if (thataway) {
+ position = thataway;
+ newway(token);
+ time++;
+ }
+ else {
+ puts("You can't go this way.");
+ newway(token);
+ whichway(location[position]);
+ return(0);
+ }
+ else if (notes[CANTMOVE] && !notes[LAUNCHED])
+ puts("You aren't able to move; you better drop something.");
+ else
+ puts("You are out of fuel; now you will rot in space forever!");
+ return(1);
+}
+
+convert(tothis) /* Converts day to night and vice versa. */
+int tothis; /* Day objects are permanent. Night objects are added*/
+{ /* at dusk, and subtracted at dawn. */
+ register struct objs *p;
+ register i, j;
+
+ if (tothis == TONIGHT) {
+ for (i = 1; i <= NUMOFROOMS; i++)
+ for (j = 0; j < NUMOFWORDS; j++)
+ nightfile[i].objects[j] = dayfile[i].objects[j];
+ for (p = nightobjs; p->room != 0; p++)
+ setbit(nightfile[p->room].objects, p->obj);
+ location = nightfile;
+ } else {
+ for (i = 1; i <= NUMOFROOMS; i++)
+ for (j = 0; j < NUMOFWORDS; j++)
+ dayfile[i].objects[j] = nightfile[i].objects[j];
+ for (p = nightobjs; p->room != 0; p++)
+ clearbit(dayfile[p->room].objects, p->obj);
+ location = dayfile;
+ }
+}
+
+news()
+{
+ register int n;
+ int hurt;
+
+ if (time > 30 && position < 32){
+ puts("An explosion of shuddering magnitude splinters bulkheads and");
+ puts("ruptures the battlestar's hull. You are sucked out into the");
+ puts("frozen void of space and killed.");
+ die();
+ }
+ if (time > 20 && position < 32)
+ puts("Explosions rock the battlestar.");
+ if (time > snooze){
+ puts("You drop from exhaustion...");
+ zzz();
+ }
+ if (time > snooze - 5)
+ puts("You're getting tired.");
+ if (time > (rythmn + CYCLE)) {
+ if (location == nightfile) {
+ convert(TODAY);
+ if (OUTSIDE && time - rythmn - CYCLE < 10) {
+ puts("Dew lit sunbeams stretch out from a watery sunrise and herald the dawn.");
+ puts("You awake from a misty dream-world into stark reality.");
+ puts("It is day.");
+ }
+ } else {
+ convert(TONIGHT);
+ clearbit(location[POOLS].objects, BATHGOD);
+ if (OUTSIDE && time - rythmn - CYCLE < 10) {
+ puts("The dying sun sinks into the ocean, leaving a blood stained sunset.");
+ puts("The sky slowly fades from orange to violet to black. A few stars");
+ puts("flicker on, and it is night.");
+ puts("The world seems completly different at night.");
+ }
+ }
+ rythmn = time - time % CYCLE;
+ }
+ if (!wiz && !tempwiz)
+ if ((testbit(inven,TALISMAN) || testbit(wear,TALISMAN)) && (testbit(inven,MEDALION) || testbit(wear,MEDALION)) && (testbit(inven,AMULET) || testbit(wear,AMULET))){
+ tempwiz = 1;
+ puts("The three amulets glow and reenforce each other in power.\nYou are now a wizard.");
+ }
+ if (testbit(location[position].objects,ELF)){
+ printf("%s\n",objdes[ELF]);
+ fight(ELF,rnd(30));
+ }
+ if (testbit(location[position].objects,DARK)){
+ printf("%s\n",objdes[DARK]);
+ fight(DARK,100);
+ }
+ if (testbit(location[position].objects,WOODSMAN)){
+ printf("%s\n",objdes[WOODSMAN]);
+ fight(WOODSMAN,50);
+ }
+ switch(position){
+
+ case 267:
+ case 257: /* entering a cave */
+ case 274:
+ case 246:
+ notes[CANTSEE] = 1;
+ break;
+ case 160:
+ case 216: /* leaving a cave */
+ case 230:
+ case 231:
+ case 232:
+ notes[CANTSEE] = 0;
+ break;
+ }
+ if (testbit(location[position].objects, GIRL))
+ meetgirl = 1;
+ if (meetgirl && CYCLE * 1.5 - time < 10){
+ setbit(location[GARDEN].objects,GIRLTALK);
+ setbit(location[GARDEN].objects,LAMPON);
+ setbit(location[GARDEN].objects,ROPE);
+ }
+ if (position == DOCK && (beenthere[position] || time > CYCLE)){
+ clearbit(location[DOCK].objects, GIRL);
+ clearbit(location[DOCK].objects,MAN);
+ }
+ if (meetgirl && time - CYCLE * 1.5 > 10){
+ clearbit(location[GARDEN].objects,GIRLTALK);
+ clearbit(location[GARDEN].objects,LAMPON);
+ clearbit(location[GARDEN].objects,ROPE);
+ meetgirl = 0;
+ }
+ if (testbit(location[position].objects,CYLON)){
+ puts("Oh my God, you're being shot at by an alien spacecraft!");
+ printf("The targeting computer says we have %d seconds to attack!\n",clock);
+ fflush(stdout);
+ sleep(1);
+ if (!visual()){
+ hurt = rnd(NUMOFINJURIES);
+ injuries[hurt] = 1;
+ puts("Laser blasts sear the cockpit, and the alien veers off in a victory roll.");
+ puts("The viper shudders under a terrible explosion.");
+ printf("I'm afraid you have suffered %s.\n", ouch[hurt]);
+ }
+ else
+ clearbit(location[position].objects,CYLON);
+ }
+ if (injuries[SKULL] && injuries[INCISE] && injuries[NECK]){
+ puts("I'm afraid you have suffered fatal injuries.");
+ die();
+ }
+ for (n=0; n < NUMOFINJURIES; n++)
+ if (injuries[n] == 1){
+ injuries[n] = 2;
+ if (WEIGHT > 5)
+ WEIGHT -= 5;
+ else
+ WEIGHT = 0;
+ }
+ if (injuries[ARM] == 2){
+ CUMBER -= 5;
+ injuries[ARM]++;
+ }
+ if (injuries[RIBS] == 2){
+ CUMBER -= 2;
+ injuries[RIBS]++;
+ }
+ if (injuries[SPINE] == 2){
+ WEIGHT = 0;
+ injuries[SPINE]++;
+ }
+ if (carrying > WEIGHT || encumber > CUMBER)
+ notes[CANTMOVE] = 1;
+ else
+ notes[CANTMOVE] = 0;
+}
+
+crash()
+{
+ int hurt1,hurt2;
+
+ fuel--;
+ if (!location[position].flyhere || (testbit(location[position].objects,LAND) && fuel <= 0)){
+ if (!location[position].flyhere)
+ puts("You're flying too low. We're going to crash!");
+ else{
+ puts("You're out of fuel. We'll have to crash land!");
+ if (!location[position].down){
+ puts("Your viper strikes the ground and explodes into firey fragments.");
+ puts("Thick black smoke billows up from the wreckage.");
+ die();
+ }
+ position = location[position].down;
+ }
+ notes[LAUNCHED] = 0;
+ setbit(location[position].objects,CRASH);
+ time += rnd(CYCLE/4);
+ puts("The viper explodes into the ground and you lose consciousness...");
+ zzz();
+ hurt1 = rnd(NUMOFINJURIES - 2) + 2;
+ hurt2 = rnd(NUMOFINJURIES - 2) + 2;
+ injuries[hurt1] = 1;
+ injuries[hurt2] = 1;
+ injuries[0] = 1; /* abrasions */
+ injuries[1] = 1; /* lacerations */
+ printf("I'm afraid you have suffered %s and %s.\n",ouch[hurt1],ouch[hurt2]);
+ }
+}
diff --git a/battlestar/com2.c b/battlestar/com2.c
new file mode 100644
index 00000000..5c8352cf
--- /dev/null
+++ b/battlestar/com2.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)com2.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+wearit() /* synonyms = {sheathe, sheath} */
+{
+ register int n;
+ int firstnumber, value;
+
+ firstnumber = wordnumber;
+ while(wordtype[++wordnumber] == ADJS);
+ while(wordnumber <= wordcount){
+ value = wordvalue[wordnumber];
+ for (n=0; objsht[value][n]; n++);
+ switch(value){
+
+ case -1:
+ puts("Wear what?");
+ return(firstnumber);
+
+ default:
+ printf("You can't wear%s%s!\n",(objsht[value][n-1] == 's' ? " " : " a "),objsht[value]);
+ return(firstnumber);
+
+ case KNIFE:
+ /* case SHIRT: */
+ case ROBE:
+ case LEVIS: /* wearable things */
+ case SWORD:
+ case MAIL:
+ case HELM:
+ case SHOES:
+ case PAJAMAS:
+ case COMPASS:
+ case LASER:
+ case AMULET:
+ case TALISMAN:
+ case MEDALION:
+ case ROPE:
+ case RING:
+ case BRACELET:
+ case GRENADE:
+
+ if (testbit(inven,value)){
+ clearbit(inven,value);
+ setbit(wear,value);
+ carrying -= objwt[value];
+ encumber -= objcumber[value];
+ time++;
+ printf("You are now wearing %s %s.\n",(objsht[value][n-1] == 's' ? "the" : "a"), objsht[value]);
+ }
+ else if (testbit(wear,value))
+ printf("You are already wearing the %s.\n", objsht[value]);
+ else
+ printf("You aren't holding the %s.\n", objsht[value]);
+ if (wordnumber < wordcount - 1 && wordvalue[++wordnumber] == AND)
+ wordnumber++;
+ else
+ return(firstnumber);
+ } /* end switch */
+ } /* end while */
+ puts("Don't be ridiculous.");
+ return(firstnumber);
+}
+
+put() /* synonyms = {buckle, strap, tie} */
+{
+ if (wordvalue[wordnumber + 1] == ON){
+ wordvalue[++wordnumber] = PUTON;
+ return(cypher());
+ }
+ if (wordvalue[wordnumber + 1] == DOWN){
+ wordvalue[++wordnumber] = DROP;
+ return(cypher());
+ }
+ puts("I don't understand what you want to put.");
+ return(-1);
+
+}
+
+draw() /* synonyms = {pull, carry} */
+{
+ return(take(wear));
+}
+
+use()
+{
+ while (wordtype[++wordnumber] == ADJS && wordnumber < wordcount);
+ if (wordvalue[wordnumber] == AMULET && testbit(inven,AMULET) && position != FINAL){
+ puts("The amulet begins to glow.");
+ if (testbit(inven,MEDALION)){
+ puts("The medallion comes to life too.");
+ if (position == 114){
+ location[position].down = 160;
+ whichway(location[position]);
+ puts("The waves subside and it is possible to descend to the sea cave now.");
+ time++;
+ return(-1);
+ }
+ }
+ puts("A light mist falls over your eyes and the sound of purling water trickles in");
+ puts("your ears. When the mist lifts you are standing beside a cool stream.");
+ if (position == 229)
+ position = 224;
+ else
+ position = 229;
+ time++;
+ return(0);
+ }
+ else if (position == FINAL)
+ puts("The amulet won't work in here.");
+ else if (wordvalue[wordnumber] == COMPASS && testbit(inven,COMPASS))
+ printf("Your compass points %s.\n",truedirec(NORTH,'-'));
+ else if (wordvalue[wordnumber] == COMPASS)
+ puts("You aren't holding the compass.");
+ else if (wordvalue[wordnumber] == AMULET)
+ puts("You aren't holding the amulet.");
+ else
+ puts("There is no apparent use.");
+ return(-1);
+}
+
+murder()
+{
+ register int n;
+
+ for (n=0; !((n == SWORD || n == KNIFE || n == TWO_HANDED || n == MACE || n == CLEAVER || n == BROAD || n == CHAIN || n == SHOVEL || n == HALBERD) && testbit(inven,n)) && n < NUMOFOBJECTS; n++);
+ if (n == NUMOFOBJECTS)
+ puts("You don't have suitable weapons to kill.");
+ else {
+ printf("Your %s should do the trick.\n",objsht[n]);
+ while (wordtype[++wordnumber] == ADJS);
+ switch(wordvalue[wordnumber]){
+
+ case NORMGOD:
+ if (testbit(location[position].objects,BATHGOD)){
+ puts("The goddess's head slices off. Her corpse floats in the water.");
+ clearbit(location[position].objects,BATHGOD);
+ setbit(location[position].objects,DEADGOD);
+ power += 5;
+ notes[JINXED]++;
+ } else if (testbit(location[position].objects,NORMGOD)){
+ puts("The goddess pleads but you strike her mercilessly. Her broken body lies in a\npool of blood.");
+ clearbit(location[position].objects,NORMGOD);
+ setbit(location[position].objects,DEADGOD);
+ power += 5;
+ notes[JINXED]++;
+ if (wintime)
+ live();
+ } else puts("I dont see her anywhere.");
+ break;
+ case TIMER:
+ if (testbit(location[position].objects,TIMER)){
+ puts("The old man offers no resistance.");
+ clearbit(location[position].objects,TIMER);
+ setbit(location[position].objects,DEADTIME);
+ power++;
+ notes[JINXED]++;
+ } else puts("Who?");
+ break;
+ case NATIVE:
+ if (testbit(location[position].objects,NATIVE)){
+ puts("The girl screams as you cut her body to shreds. She is dead.");
+ clearbit(location[position].objects,NATIVE);
+ setbit(location[position].objects,DEADNATIVE);
+ power += 5;
+ notes[JINXED]++;
+ } else puts("What girl?");
+ break;
+ case MAN:
+ if (testbit(location[position].objects,MAN)){
+ puts("You strike him to the ground, and he coughs up blood.");
+ puts("Your fantasy is over.");
+ die();
+ }
+ case -1:
+ puts("Kill what?");
+ break;
+
+ default:
+ if (wordtype[wordnumber] != NOUNS)
+ puts("Kill what?");
+ else
+ printf("You can't kill the %s!\n",objsht[wordvalue[wordnumber]]);
+ }
+ }
+}
+
+ravage()
+{
+ while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount);
+ if (wordtype[wordnumber] == NOUNS && testbit(location[position].objects,wordvalue[wordnumber])){
+ time++;
+ switch(wordvalue[wordnumber]){
+ case NORMGOD:
+ puts("You attack the goddess, and she screams as you beat her. She falls down");
+ puts("crying and tries to hold her torn and bloodied dress around her.");
+ power += 5;
+ pleasure += 8;
+ ego -= 10;
+ wordnumber--;
+ godready = -30000;
+ murder();
+ win = -30000;
+ break;
+ case NATIVE:
+ puts("The girl tries to run, but you catch her and throw her down. Her face is");
+ puts("bleeding, and she screams as you tear off her clothes.");
+ power += 3;
+ pleasure += 5;
+ ego -= 10;
+ wordnumber--;
+ murder();
+ if (rnd(100) < 50){
+ puts("Her screams have attracted attention. I think we are surrounded.");
+ setbit(location[ahead].objects,WOODSMAN);
+ setbit(location[ahead].objects,DEADWOOD);
+ setbit(location[ahead].objects,MALLET);
+ setbit(location[back].objects,WOODSMAN);
+ setbit(location[back].objects,DEADWOOD);
+ setbit(location[back].objects,MALLET);
+ setbit(location[left].objects,WOODSMAN);
+ setbit(location[left].objects,DEADWOOD);
+ setbit(location[left].objects,MALLET);
+ setbit(location[right].objects,WOODSMAN);
+ setbit(location[right].objects,DEADWOOD);
+ setbit(location[right].objects,MALLET);
+ }
+ break;
+ default:
+ puts("You are perverted.");
+ }
+ }
+ else
+ puts("Who?");
+}
+
+follow()
+{
+ if (followfight == time){
+ puts("The Dark Lord leaps away and runs down secret tunnels and corridoors.");
+ puts("You chase him through the darkness and splash in pools of water.");
+ puts("You have cornered him. His laser sword extends as he steps forward.");
+ position = FINAL;
+ fight(DARK,75);
+ setbit(location[position].objects,TALISMAN);
+ setbit(location[position].objects,AMULET);
+ return(0);
+ }
+ else if (followgod == time){
+ puts("The goddess leads you down a steamy tunnel and into a high, wide chamber.");
+ puts("She sits down on a throne.");
+ position = 268;
+ setbit(location[position].objects,NORMGOD);
+ notes[CANTSEE] = 1;
+ return(0);
+ }
+ else
+ puts("There is no one to follow.");
+ return(-1);
+}
diff --git a/battlestar/com3.c b/battlestar/com3.c
new file mode 100644
index 00000000..82be058e
--- /dev/null
+++ b/battlestar/com3.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)com3.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+dig()
+{
+ if (testbit(inven,SHOVEL)){
+ puts("OK");
+ time++;
+ switch(position){
+ case 144: /* copse near beach */
+ if (!notes[DUG]){
+ setbit(location[position].objects,DEADWOOD);
+ setbit(location[position].objects,COMPASS);
+ setbit(location[position].objects,KNIFE);
+ setbit(location[position].objects,MACE);
+ notes[DUG] = 1;
+ }
+ break;
+
+ default:
+ puts("Nothing happens.");
+ }
+ }
+ else
+ puts("You don't have a shovel.");
+}
+
+jump()
+{
+ register int n;
+
+ switch(position){
+ default:
+ puts("Nothing happens.");
+ return(-1);
+
+ case 242:
+ position = 133;
+ break;
+ case 214:
+ case 215:
+ case 162:
+ case 159:
+ position = 145;
+ break;
+ case 232:
+ position = 275;
+ break;
+ case 3:
+ position = 1;
+ break;
+ case 172:
+ position = 201;
+ }
+ puts("Ahhhhhhh...");
+ injuries[12] = injuries[8] = injuries[7] = injuries[6] = 1;
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(inven,n)){
+ clearbit(inven,n);
+ setbit(location[position].objects,n);
+ }
+ carrying = 0;
+ encumber = 0;
+ return(0);
+}
+
+bury()
+{
+ int value;
+
+ if (testbit(inven,SHOVEL)){
+ while(wordtype[++wordnumber] != OBJECT && wordtype[wordnumber] != NOUNS && wordnumber < wordcount);
+ value = wordvalue[wordnumber];
+ if (wordtype[wordnumber] == NOUNS && (testbit(location[position].objects,value) || value == BODY))
+ switch(value){
+ case BODY:
+ wordtype[wordnumber] = OBJECT;
+ if (testbit(inven,MAID) || testbit(location[position].objects,MAID))
+ value = MAID;
+ if (testbit(inven,DEADWOOD) || testbit(location[position].objects,DEADWOOD))
+ value = DEADWOOD;
+ if (testbit(inven,DEADGOD) || testbit(location[position].objects,DEADGOD))
+ value = DEADGOD;
+ if (testbit(inven,DEADTIME) || testbit(location[position].objects,DEADTIME))
+ value = DEADTIME;
+ if (testbit(inven,DEADNATIVE) || testbit(location[position].objects,DEADNATIVE))
+ value = DEADNATIVE;
+ break;
+
+ case NATIVE:
+ case NORMGOD:
+ puts("She screams as you wrestle her into the hole.");
+ case TIMER:
+ power += 7;
+ ego -= 10;
+ case AMULET:
+ case MEDALION:
+ case TALISMAN:
+ wordtype[wordnumber] = OBJECT;
+ break;
+
+ default:
+ puts("Wha..?");
+ }
+ if (wordtype[wordnumber] == OBJECT && position > 88 && (testbit(inven,value) || testbit(location[position].objects,value))){
+ puts("Buried.");
+ if (testbit(inven,value)){
+ clearbit(inven,value);
+ carrying -= objwt[value];
+ encumber -= objcumber[value];
+ }
+ clearbit(location[position].objects,value);
+ switch(value){
+ case MAID:
+ case DEADWOOD:
+ case DEADNATIVE:
+ case DEADTIME:
+ case DEADGOD:
+ ego += 2;
+ printf("The %s should rest easier now.\n",objsht[value]);
+ }
+ }
+ else
+ puts("It doesn't seem to work.");
+ }
+ else
+ puts("You aren't holding a shovel.");
+}
+
+drink()
+{
+ register int n;
+
+ if (testbit(inven,POTION)){
+ puts("The cool liquid runs down your throat but turns to fire and you choke.");
+ puts("The heat reaches your limbs and tingles your spirit. You feel like falling");
+ puts("asleep.");
+ clearbit(inven, POTION);
+ WEIGHT = MAXWEIGHT;
+ CUMBER = MAXCUMBER;
+ for (n=0; n < NUMOFINJURIES; n++)
+ injuries[n] = 0;
+ time++;
+ zzz();
+ }
+ else
+ puts("I'm not thirsty.");
+}
+
+shoot()
+{
+ int firstnumber, value;
+ register int n;
+
+ if (!testbit(inven,LASER))
+ puts("You aren't holding a blaster.");
+ else {
+ firstnumber = wordnumber;
+ while(wordtype[++wordnumber] == ADJS);
+ while(wordnumber<=wordcount && wordtype[wordnumber] == OBJECT){
+ value = wordvalue[wordnumber];
+ printf("%s:\n", objsht[value]);
+ for (n=0; objsht[value][n]; n++);
+ if (testbit(location[position].objects,value)){
+ clearbit(location[position].objects,value);
+ time++;
+ printf("The %s explode%s\n",objsht[value],(objsht[value][n-1]=='s' ? (objsht[value][n-2]=='s' ? "s." : ".") : "s."));
+ if (value == BOMB)
+ die();
+ }
+ else
+ printf("I dont see any %s around here.\n", objsht[value]);
+ if (wordnumber < wordcount - 1 && wordvalue[++wordnumber] == AND)
+ wordnumber++;
+ else
+ return(firstnumber);
+ }
+ /* special cases with their own return()'s */
+
+ if (wordnumber <= wordcount && wordtype[wordnumber] == NOUNS){
+ time++;
+ switch(wordvalue[wordnumber]){
+
+ case DOOR:
+ switch(position){
+ case 189:
+ case 231:
+ puts("The door is unhinged.");
+ location[189].north = 231;
+ location[231].south = 189;
+ whichway(location[position]);
+ break;
+ case 30:
+ puts("The wooden door splinters.");
+ location[30].west = 25;
+ whichway(location[position]);
+ break;
+ case 31:
+ puts("The laser blast has no effect on the door.");
+ break;
+ case 20:
+ puts("The blast hits the door and it explodes into flame. The magnesium burns");
+ puts("so rapidly that we have no chance to escape.");
+ die();
+ default:
+ puts("Nothing happens.");
+ }
+ break;
+
+ case NORMGOD:
+ if (testbit(location[position].objects,BATHGOD)){
+ puts("The goddess is hit in the chest and splashes back against the rocks.");
+ puts("Dark blood oozes from the charred blast hole. Her naked body floats in the");
+ puts("pools and then off downstream.");
+ clearbit(location[position].objects,BATHGOD);
+ setbit(location[180].objects,DEADGOD);
+ power += 5;
+ ego -= 10;
+ notes[JINXED]++;
+ } else if (testbit(location[position].objects,NORMGOD)){
+ puts("The blast catches the goddess in the stomach, knocking her to the ground.");
+ puts("She writhes in the dirt as the agony of death taunts her.");
+ puts("She has stopped moving.");
+ clearbit(location[position].objects,NORMGOD);
+ setbit(location[position].objects,DEADGOD);
+ power += 5;
+ ego -= 10;
+ notes[JINXED]++;
+ if (wintime)
+ live();
+ break;
+ } else
+ puts("I don't see any goddess around here.");
+ break;
+
+ case TIMER:
+ if (testbit(location[position].objects,TIMER)){
+ puts("The old man slumps over the bar.");
+ power++;
+ ego -= 2;
+ notes[JINXED]++;
+ clearbit(location[position].objects,TIMER);
+ setbit(location[position].objects,DEADTIME);
+ }
+ else puts("What old timer?");
+ break;
+ case MAN:
+ if (testbit(location[position].objects,MAN)){
+ puts("The man falls to the ground with blood pouring all over his white suit.");
+ puts("Your fantasy is over.");
+ die();
+ }
+ else puts("What man?");
+ break;
+ case NATIVE:
+ if (testbit(location[position].objects,NATIVE)){
+ puts("The girl is blown backwards several feet and lies in a pool of blood.");
+ clearbit(location[position].objects,NATIVE);
+ setbit(location[position].objects,DEADNATIVE);
+ power += 5;
+ ego -= 2;
+ notes[JINXED]++;
+ } else puts("There is no girl here.");
+ break;
+ case -1:
+ puts("Shoot what?");
+ break;
+
+ default:
+ printf("You can't shoot the %s.\n",objsht[wordvalue[wordnumber]]);
+ }
+ }
+ else puts("You must be a looney.");
+ }
+ return(firstnumber);
+}
diff --git a/battlestar/com4.c b/battlestar/com4.c
new file mode 100644
index 00000000..d1ba925e
--- /dev/null
+++ b/battlestar/com4.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)com4.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+take(from)
+unsigned int from[];
+{
+ int firstnumber, heavy, bulky, value;
+ register int n;
+
+ firstnumber = wordnumber;
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == OFF){
+ wordnumber++;
+ wordvalue[wordnumber] = TAKEOFF;
+ return(cypher());
+ }
+ else {
+ while(wordtype[++wordnumber] == ADJS);
+ while(wordnumber<=wordcount && wordtype[wordnumber] == OBJECT){
+ value = wordvalue[wordnumber];
+ printf("%s:\n", objsht[value]);
+ for (n=0; objsht[value][n]; n++);
+ heavy = (carrying + objwt[value]) <= WEIGHT;
+ bulky = (encumber + objcumber[value]) <= CUMBER;
+ if ((testbit(from,value) || wiz || tempwiz) && heavy && bulky && !testbit(inven,value)){
+ setbit(inven,value);
+ carrying += objwt[value];
+ encumber += objcumber[value];
+ time++;
+ if (testbit(from,value))
+ printf("Taken.\n");
+ else
+ printf("Zap! Taken from thin air.\n");
+ clearbit(from,value);
+ if (value == MEDALION)
+ win--;
+ }
+ else if (testbit(inven,value))
+ printf("You're already holding%s%s.\n", (objsht[value][n-1] == 's' ? " " : " a "),objsht[value]);
+ else if (!heavy)
+ printf("The %s %s too heavy.\n", objsht[value],(objsht[value][n-1] == 's' ? "are" : "is"));
+ else if (!bulky)
+ printf("The %s %s too cumbersome to hold.\n", objsht[value],(objsht[value][n-1] == 's' ? "are" : "is"));
+ else
+ printf("I dont see any %s around here.\n", objsht[value]);
+ if (wordnumber < wordcount -1 && wordvalue[++wordnumber] == AND)
+ wordnumber++;
+ else
+ return(firstnumber);
+ }
+ }
+ /* special cases with their own return()'s */
+
+ if (wordnumber <= wordcount && wordtype[wordnumber] == NOUNS)
+ switch(wordvalue[wordnumber]){
+
+ case SWORD:
+ if (testbit(from, SWORD)){
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+ }
+ if (testbit(from, TWO_HANDED)){
+ wordvalue[wordnumber] = TWO_HANDED;
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+ }
+ wordvalue[wordnumber] = BROAD;
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+
+ case BODY:
+ if (testbit(from,MAID)){
+ wordvalue[wordnumber] = MAID;
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+ }
+ else if (testbit(from,DEADWOOD)){
+ wordvalue[wordnumber] = DEADWOOD;
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+ }
+ else if (testbit(from,DEADNATIVE)){
+ wordvalue[wordnumber] = DEADNATIVE;
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+ }
+ else if (testbit(from,DEADGOD)){
+ wordvalue[wordnumber] = DEADGOD;
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+ }
+ else {
+ wordvalue[wordnumber] = DEADTIME;
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+ }
+ break;
+
+ case AMULET:
+ if (testbit(location[position].objects,AMULET)){
+ puts("The amulet is warm to the touch, and its beauty catches your breath.");
+ puts("A mist falls over your eyes, but then it is gone. Sounds seem clearer");
+ puts("and sharper but far away as if in a dream. The sound of purling water reaches");
+ puts("you from afar. The mist falls again, and your heart leaps in horror. The gold");
+ puts("freezes your hands and fathomless darkness engulfs your soul.");
+ }
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+
+ case MEDALION:
+ if (testbit(location[position].objects, MEDALION)){
+ puts("The medallion is warm, and it rekindles your spirit with the warmth of life.");
+ puts("Your amulet begins to glow as the medallion is brought near to it, and together\nthey radiate.");
+ }
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+
+ case TALISMAN:
+ if (testbit(location[position].objects,TALISMAN)){
+ puts("The talisman is cold to the touch, and it sends a chill down your spine.");
+ }
+ wordtype[wordnumber--] = OBJECT;
+ return(take(from));
+
+ case NORMGOD:
+ if (testbit(location[position].objects,BATHGOD) && (testbit(wear,AMULET) || testbit(inven,AMULET))){
+ puts("She offers a delicate hand, and you help her out of the sparkling springs.");
+ puts("Water droplets like liquid silver bedew her golden skin, but when they part");
+ puts("from her, they fall as teardrops. She wraps a single cloth around her and");
+ puts("ties it at the waist. Around her neck hangs a golden amulet.");
+ puts("She bids you to follow her.");
+ pleasure++;
+ followgod = time;
+ clearbit(location[position].objects,BATHGOD);
+ } else if (!testbit(location[position].objects,BATHGOD))
+ puts("You're in no position to take her.");
+ else
+ puts("She moves away from you.");
+ break;
+
+ default:
+ puts("It doesn't seem to work.");
+ }
+ else
+ puts("You've got to be kidding.");
+ return(firstnumber);
+}
+
+throw(name)
+ char *name;
+{
+ int n;
+ int deposit = 0;
+ int first, value;
+
+ first = wordnumber;
+ if (drop(name) != -1){
+ switch(wordvalue[wordnumber]){
+
+ case AHEAD:
+ deposit = ahead;
+ break;
+
+ case BACK:
+ deposit = back;
+ break;
+
+ case LEFT:
+ deposit = left;
+ break;
+
+ case RIGHT:
+ deposit = right;
+ break;
+
+ case UP:
+ deposit = location[position].up * (location[position].access || position == FINAL);
+ break;
+
+ case DOWN:
+ deposit = location[position].down;
+ break;
+ }
+ wordnumber = first;
+ while (wordtype[++wordnumber] == ADJS);
+ while (wordnumber <= wordcount){
+ value = wordvalue[wordnumber];
+ if (deposit && testbit(location[position].objects,value)){
+ clearbit(location[position].objects,value);
+ if (value != GRENADE)
+ setbit(location[deposit].objects,value);
+ else{
+ puts("A thundering explosion nearby sends up a cloud of smoke and shrapnel.");
+ for (n = 0; n < NUMOFWORDS; n ++)
+ location[deposit].objects[n] = 0;
+ setbit(location[deposit].objects,CHAR);
+ }
+ if (value == ROPE && position == FINAL)
+ location[position].access = 1;
+ switch(deposit){
+ case 189:
+ case 231:
+ puts("The stone door is unhinged.");
+ location[189].north = 231;
+ location[231].south = 189;
+ break;
+ case 30:
+ puts("The wooden door is blown open.");
+ location[30].west = 25;
+ break;
+ case 31:
+ puts("The door is not damaged.");
+ }
+ }
+ else if (value == GRENADE && testbit(location[position].objects,value)){
+ puts("You are blown into shreds when your grenade explodes.");
+ die();
+ }
+ if (wordnumber < wordcount - 1 && wordvalue[++wordnumber] == AND)
+ wordnumber++;
+ else
+ return(first);
+ }
+ return(first);
+ }
+ return(first);
+}
+
+drop(name)
+char *name;
+{
+
+ int firstnumber, value;
+
+ firstnumber = wordnumber;
+ while (wordtype[++wordnumber] == ADJS)
+ ;
+ while (wordnumber<=wordcount && (wordtype[wordnumber] == OBJECT || wordtype[wordnumber] == NOUNS)) {
+ value = wordvalue[wordnumber];
+ printf("%s:\n", objsht[value]);
+ if (testbit(inven,value)){
+ clearbit(inven,value);
+ carrying -= objwt[value];
+ encumber -= objcumber[value];
+ if (value == BOMB){
+ puts("The bomb explodes. A blinding white light and immense concussion obliterate us.");
+ die();
+ }
+ if (value != AMULET && value != MEDALION && value != TALISMAN)
+ setbit(location[position].objects,value);
+ else
+ tempwiz = 0;
+ time++;
+ if (*name == 'K')
+ puts("Drop kicked.");
+ else
+ printf("%s.\n", name);
+ }
+ else {
+ if (*name != 'K') {
+ printf("You aren't holding the %s.\n", objsht[value]);
+ if (testbit(location[position].objects,value)) {
+ if (*name == 'T')
+ puts("Kicked instead.");
+ else if (*name == 'G')
+ puts("Given anyway.");
+ }
+ } else
+ puts("Kicked.");
+ }
+ if (wordnumber < wordcount - 1 && wordvalue[++wordnumber] == AND)
+ wordnumber++;
+ else
+ return(firstnumber);
+ }
+ puts("Do what?");
+ return(-1);
+}
+
+takeoff()
+{
+ wordnumber = take(wear);
+ return(drop("Dropped"));
+}
+
+puton()
+{
+ wordnumber = take(location[position].objects);
+ return(wearit());
+}
+
+eat()
+{
+ int firstnumber, value;
+
+ firstnumber = wordnumber;
+ while(wordtype[++wordnumber] == ADJS);
+ while(wordnumber <= wordcount){
+ value = wordvalue[wordnumber];
+ switch(value){
+
+ case -1:
+ puts("Eat what?");
+ return(firstnumber);
+
+ default:
+ printf("You can't eat%s%s!\n",
+ wordtype[wordnumber] == OBJECT &&
+ objsht[value]
+ [strlen(objsht[value]) - 1] == 's' ?
+ " " : " a ",
+ words[wordnumber]);
+ return(firstnumber);
+
+ case PAPAYAS:
+ case PINEAPPLE:
+ case KIWI:
+ case COCONUTS: /* eatable things */
+ case MANGO:
+
+ printf("%s:\n",objsht[value]);
+ if (testbit(inven,value) && time > ate - CYCLE && testbit(inven,KNIFE)){
+ clearbit(inven,value);
+ carrying -= objwt[value];
+ encumber -= objcumber[value];
+ ate = max(time,ate) + CYCLE/3;
+ snooze += CYCLE/10;
+ time++;
+ puts("Eaten. You can explore a little longer now.");
+ }
+ else if (time < ate - CYCLE)
+ puts("You're stuffed.");
+ else if (!testbit(inven,KNIFE))
+ puts("You need a knife.");
+ else
+ printf("You aren't holding the %s.\n", objsht[value]);
+ if (wordnumber < wordcount - 1 && wordvalue[++wordnumber] == AND)
+ wordnumber++;
+ else
+ return(firstnumber);
+ } /* end switch */
+ } /* end while */
+ return(firstnumber);
+}
diff --git a/battlestar/com5.c b/battlestar/com5.c
new file mode 100644
index 00000000..dc7c589e
--- /dev/null
+++ b/battlestar/com5.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)com5.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+kiss()
+{
+ while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount);
+ if (wordtype[wordnumber] == NOUNS && testbit(location[position].objects,wordvalue[wordnumber])){
+ pleasure++;
+ printf("Kissed.\n");
+ switch (wordvalue[wordnumber]){
+ case NORMGOD:
+ switch(godready++){
+ case 0:
+ puts("She squirms and avoids your advances.");
+ break;
+ case 1:
+ puts("She is coming around; she didn't fight it as much.");
+ break;
+ case 2:
+ puts("She's begining to like it.");
+ break;
+ default:
+ puts("She's gone limp.");
+
+ }
+ break;
+ case NATIVE:
+ puts("The lips are warm and her body robust. She pulls you down to the ground.");
+ break;
+ case TIMER:
+ puts("The old man blushes.");
+ break;
+ case MAN:
+ puts("The dwarf punches you in the kneecap.");
+ break;
+ default:
+ pleasure--;
+ }
+ }
+ else puts("I'd prefer not to.");
+}
+
+love()
+{
+ register int n;
+
+ while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount);
+ if (wordtype[wordnumber] == NOUNS && testbit(location[position].objects,wordvalue[wordnumber])){
+ if (wordvalue[wordnumber] == NORMGOD && !loved)
+ if (godready >= 2){
+ puts("She cuddles up to you, and her mouth starts to work:\n'That was my sister's amulet. The lovely goddess, Purl, was she. The Empire\ncaptured her just after the Darkness came. My other sister, Vert, was killed\nby the Dark Lord himself. He took her amulet and warped its power.\nYour quest was foretold by my father before he died, but to get the Dark Lord's\namulet you must use cunning and skill. I will leave you my amulet.");
+ puts("which you may use as you wish. As for me, I am the last goddess of the\nwaters. My father was the Island King, and the rule is rightfully mine.'\n\nShe pulls the throne out into a large bed.");
+ power++;
+ pleasure += 15;
+ ego++;
+ if (card(injuries, NUMOFINJURIES)){
+ puts("Her kisses revive you; your wounds are healed.\n");
+ for (n=0; n < NUMOFINJURIES; n++)
+ injuries[n] = 0;
+ WEIGHT = MAXWEIGHT;
+ CUMBER = MAXCUMBER;
+ }
+ printf("Goddess:\n");
+ if (!loved)
+ setbit(location[position].objects,MEDALION);
+ loved = 1;
+ time += 10;
+ zzz();
+ }
+ else {
+ puts("You wish!");
+ return;
+ }
+ if (wordvalue[wordnumber] == NATIVE){
+ puts("The girl is easy prey. She peals off her sarong and indulges you.");
+ power++;
+ pleasure += 5;
+ printf("Girl:\n");
+ time += 10;
+ zzz();
+ }
+ printf("Loved.\n");
+ }
+ else puts("I't doesn't seem to work.");
+}
+
+zzz()
+{
+ int oldtime;
+ register int n;
+
+ oldtime = time;
+ if ((snooze - time) < (0.75 * CYCLE)){
+ time += 0.75 * CYCLE - (snooze - time);
+ printf("<zzz>");
+ for (n = 0; n < time - oldtime; n++)
+ printf(".");
+ printf("\n");
+ snooze += 3 * (time - oldtime);
+ if (notes[LAUNCHED]){
+ fuel -= (time - oldtime);
+ if (location[position].down){
+ position = location[position].down;
+ crash();
+ }
+ else
+ notes[LAUNCHED] = 0;
+ }
+ if (OUTSIDE && rnd(100) < 50){
+ puts("You are awakened abruptly by the sound of someone nearby.");
+ switch(rnd(4)){
+ case 0:
+ if (ucard(inven)){
+ n = rnd(NUMOFOBJECTS);
+ while(!testbit(inven,n))
+ n = rnd(NUMOFOBJECTS);
+ clearbit(inven,n);
+ if (n != AMULET && n != MEDALION && n != TALISMAN)
+ setbit(location[position].objects,n);
+ carrying -= objwt[n];
+ encumber -= objcumber[n];
+ }
+ puts("A fiendish little Elf is stealing your treasures!");
+ fight(ELF,10);
+ break;
+ case 1:
+ setbit(location[position].objects,DEADWOOD);
+ break;
+ case 2:
+ setbit(location[position].objects,HALBERD);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ return(0);
+ return(1);
+}
+
+chime()
+{
+ if ((time / CYCLE + 1) % 2 && OUTSIDE)
+ switch((time % CYCLE)/(CYCLE / 7)){
+ case 0:
+ puts("It is just after sunrise.");
+ break;
+ case 1:
+ puts("It is early morning.");
+ break;
+ case 2:
+ puts("It is late morning.");
+ break;
+ case 3:
+ puts("It is near noon.");
+ break;
+ case 4:
+ puts("It is early afternoon.");
+ break;
+ case 5:
+ puts("It is late afternoon.");
+ break;
+ case 6:
+ puts("It is near sunset.");
+ break;
+ }
+ else if (OUTSIDE)
+ switch((time % CYCLE)/(CYCLE / 7)){
+ case 0:
+ puts("It is just after sunset.");
+ break;
+ case 1:
+ puts("It is early evening.");
+ break;
+ case 2:
+ puts("The evening is getting old.");
+ break;
+ case 3:
+ puts("It is near midnight.");
+ break;
+ case 4:
+ puts("These are the wee hours of the morning.");
+ break;
+ case 5:
+ puts("The night is waning.");
+ break;
+ case 6:
+ puts("It is almost morning.");
+ break;
+ }
+ else
+ puts("I can't tell the time in here.");
+}
+
+give()
+{
+ int obj = -1, result = -1, person = 0, firstnumber, last1, last2;
+
+ firstnumber = wordnumber;
+ while (wordtype[++wordnumber] != OBJECT && wordvalue[wordnumber] != AMULET && wordvalue[wordnumber] != MEDALION && wordvalue[wordnumber] != TALISMAN && wordnumber <= wordcount);
+ if (wordnumber <= wordcount){
+ obj = wordvalue[wordnumber];
+ if (obj == EVERYTHING)
+ wordtype[wordnumber] = -1;
+ last1 = wordnumber;
+ }
+ wordnumber = firstnumber;
+ while ((wordtype[++wordnumber] != NOUNS || wordvalue[wordnumber] == obj) && wordnumber <= wordcount);
+ if (wordtype[wordnumber] == NOUNS){
+ person = wordvalue[wordnumber];
+ last2 = wordnumber;
+ }
+ wordnumber = last1 - 1;
+ if (person && testbit(location[position].objects,person))
+ if (person == NORMGOD && godready < 2 && !(obj == RING || obj == BRACELET))
+ puts("The goddess won't look at you.");
+ else
+ result = drop("Given");
+ else {
+ puts("I don't think that is possible.");
+ return(0);
+ }
+ if (result != -1 && (testbit(location[position].objects,obj) || obj == AMULET || obj == MEDALION || obj == TALISMAN)){
+ clearbit(location[position].objects,obj);
+ time++;
+ ego++;
+ switch(person){
+ case NATIVE:
+ puts("She accepts it shyly.");
+ ego += 2;
+ break;
+ case NORMGOD:
+ if (obj == RING || obj == BRACELET){
+ puts("She takes the charm and puts it on. A little kiss on the cheek is");
+ puts("your reward.");
+ ego += 5;
+ godready += 3;
+ }
+ if (obj == AMULET || obj == MEDALION || obj == TALISMAN){
+ win++;
+ ego += 5;
+ power -= 5;
+ if (win >= 3){
+ puts("The powers of the earth are now legitimate. You have destroyed the Darkness");
+ puts("and restored the goddess to her thrown. The entire island celebrates with");
+ puts("dancing and spring feasts. As a measure of her gratitude, the goddess weds you");
+ puts("in the late summer and crowns you Prince Liverwort, Lord of Fungus.");
+ puts("\nBut, as the year wears on and autumn comes along, you become restless and");
+ puts("yearn for adventure. The goddess, too, realizes that the marriage can't last.");
+ puts("She becomes bored and takes several more natives as husbands. One evening,");
+ puts("after having been out drinking with the girls, she kicks the throne particulary");
+ puts("hard and wakes you up. (If you want to win this game, you're going to have to\nshoot her!)");
+ clearbit(location[position].objects,MEDALION);
+ wintime = time;
+ }
+ }
+ break;
+ case TIMER:
+ if (obj == COINS){
+ puts("He fingers the coins for a moment and then looks up agape. `Kind you are and");
+ puts("I mean to repay you as best I can.' Grabbing a pencil and cocktail napkin...\n");
+ printf( "+-----------------------------------------------------------------------------+\n");
+ printf( "| xxxxxxxx\\ |\n");
+ printf( "| xxxxx\\ CLIFFS |\n");
+ printf( "| FOREST xxx\\ |\n");
+ printf( "| \\\\ x\\ OCEAN |\n");
+ printf( "| || x\\ |\n");
+ printf( "| || ROAD x\\ |\n");
+ printf( "| || x\\ |\n");
+ printf( "| SECRET || ......... |\n");
+ printf( "| - + - || ........ |\n");
+ printf( "| ENTRANCE || ... BEACH |\n");
+ printf( "| || ... E |\n");
+ printf( "| || ... | |\n");
+ printf( "| // ... N <-- + --- S |\n");
+ printf( "| PALM GROVE // ... | |\n");
+ printf( "| // ... W |\n");
+ printf( "+-----------------------------------------------------------------------------+\n");
+ puts("\n`This map shows a secret entrance to the catacombs.");
+ puts("You will know when you arrive because I left an old pair of shoes there.'");
+ }
+ break;
+ }
+ }
+ wordnumber = max(last1,last2);
+ return(firstnumber);
+}
diff --git a/battlestar/com6.c b/battlestar/com6.c
new file mode 100644
index 00000000..a9bd774a
--- /dev/null
+++ b/battlestar/com6.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)com6.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+#include "pathnames.h"
+
+launch()
+{
+ if (testbit(location[position].objects,VIPER) && !notes[CANTLAUNCH]){
+ if (fuel > 4){
+ clearbit(location[position].objects,VIPER);
+ position = location[position].up;
+ notes[LAUNCHED] = 1;
+ time++;
+ fuel -= 4;
+ puts("You climb into the viper and prepare for launch.");
+ puts("With a touch of your thumb the turbo engines ignite, thrusting you back into\nyour seat.");
+ return(1);
+ }
+ else
+ puts("Not enough fuel to launch.");
+ }
+ else
+ puts("Can't launch.");
+ return(0);
+}
+
+land()
+{
+ if (notes[LAUNCHED] && testbit(location[position].objects,LAND) && location[position].down){
+ notes[LAUNCHED] = 0;
+ position = location[position].down;
+ setbit(location[position].objects,VIPER);
+ fuel -= 2;
+ time++;
+ puts("You are down.");
+ return(1);
+ }
+ else
+ puts("You can't land here.");
+ return(0);
+}
+
+die() /* endgame */
+{
+ printf("bye.\nYour rating was %s.\n", rate());
+ post(' ');
+ exit(0);
+}
+
+live()
+{
+ puts("\nYou win!");
+ post('!');
+ exit(0);
+}
+
+/*
+ * sigh -- this program thinks "time" is an int. It's easier to not load
+ * <time.h> than try and fix it.
+ */
+#define KERNEL
+#include <sys/time.h>
+#undef KERNEL
+
+post(ch)
+char ch;
+{
+ FILE *fp;
+ struct timeval tv;
+ char *date, *ctime();
+ int s = sigblock(sigmask(SIGINT));
+
+ gettimeofday(&tv, (struct timezone *)0); /* can't call time */
+ date = ctime(&tv.tv_sec);
+ date[24] = '\0';
+ if (fp = fopen(_PATH_SCORE,"a")) {
+ fprintf(fp, "%s %8s %c%20s", date, uname, ch, rate());
+ if (wiz)
+ fprintf(fp, " wizard\n");
+ else if (tempwiz)
+ fprintf(fp, " WIZARD!\n");
+ else
+ fprintf(fp, "\n");
+ } else
+ perror(_PATH_SCORE);
+ sigsetmask(s);
+}
+
+char *
+rate()
+{
+ int score;
+
+ score = max(max(pleasure,power),ego);
+ if (score == pleasure){
+ if (score < 5)
+ return("novice");
+ else if (score < 20)
+ return("junior voyeur");
+ else if (score < 35)
+ return("Don Juan");
+ else return("Marquis De Sade");
+ }
+ else if (score == power){
+ if (score < 5)
+ return("serf");
+ else if (score < 8)
+ return("Samurai");
+ else if (score < 13)
+ return("Klingon");
+ else if (score < 22)
+ return("Darth Vader");
+ else return("Sauron the Great");
+ }
+ else{
+ if (score < 5)
+ return("Polyanna");
+ else if (score < 10)
+ return("philanthropist");
+ else if (score < 20)
+ return("Tattoo");
+ else return("Mr. Roarke");
+ }
+}
+
+drive()
+{
+ if (testbit(location[position].objects,CAR)){
+ puts("You hop in the car and turn the key. There is a perceptible grating noise,");
+ puts("and an explosion knocks you unconscious...");
+ clearbit(location[position].objects,CAR);
+ setbit(location[position].objects,CRASH);
+ injuries[5] = injuries[6] = injuries[7] = injuries[8] = 1;
+ time += 15;
+ zzz();
+ return(0);
+ }
+ else
+ puts("There is nothing to drive here.");
+ return(-1);
+}
+
+ride()
+{
+ if (testbit(location[position].objects,HORSE)){
+ puts("You climb onto the stallion and kick it in the guts. The stupid steed launches");
+ puts("forward through bush and fern. You are thrown and the horse gallups off.");
+ clearbit(location[position].objects,HORSE);
+ while (!(position = rnd(NUMOFROOMS+1)) || !OUTSIDE || !beenthere[position] || location[position].flyhere);
+ setbit(location[position].objects,HORSE);
+ if (location[position].north)
+ position = location[position].north;
+ else if (location[position].south)
+ position = location[position].south;
+ else if (location[position].east)
+ position = location[position].east;
+ else
+ position = location[position].west;
+ return(0);
+ }
+ else puts("There is no horse here.");
+ return(-1);
+}
+
+light() /* synonyms = {strike, smoke} */
+{ /* for matches, cigars */
+ if (testbit(inven,MATCHES) && matchcount){
+ puts("Your match splutters to life.");
+ time++;
+ matchlight = 1;
+ matchcount--;
+ if (position == 217){
+ puts("The whole bungalow explodes with an intense blast.");
+ die();
+ }
+ }
+ else puts("You're out of matches.");
+}
diff --git a/battlestar/com7.c b/battlestar/com7.c
new file mode 100644
index 00000000..9f1cde27
--- /dev/null
+++ b/battlestar/com7.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)com7.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+fight(enemy,strength)
+int enemy,strength;
+{
+ int lifeline = 0;
+ int hurt;
+ char auxbuf[LINELENGTH];
+ char *next;
+ int i;
+ int exhaustion;
+
+fighton:
+ time++;
+ snooze -= 5;
+ if (snooze > time)
+ exhaustion = CYCLE/(snooze - time);
+ else {
+ puts("You collapse exhausted, and he pulverizes your skull.");
+ die();
+ }
+ if (snooze - time < 20)
+ puts("You look tired! I hope you're able to fight.");
+ next = getcom(auxbuf, LINELENGTH, "<fight!>-: ", 0);
+ for (i=0; next && i < 10; i++)
+ next = getword(next, words[i], -1);
+ parse();
+ switch(wordvalue[wordnumber]){
+
+ case KILL:
+ case SMITE:
+ if (testbit(inven,TWO_HANDED))
+ hurt = rnd(70) - 2 * card(injuries,NUMOFINJURIES) - ucard(wear) - exhaustion;
+ else if (testbit(inven,SWORD) || testbit(inven, BROAD))
+ hurt = rnd(50)%(WEIGHT-carrying)-card(injuries,NUMOFINJURIES)-encumber - exhaustion;
+ else if (testbit(inven,KNIFE) || testbit(inven,MALLET) || testbit(inven,CHAIN) || testbit(inven,MACE) || testbit(inven,HALBERD))
+ hurt = rnd(15) - card(injuries,NUMOFINJURIES) - exhaustion;
+ else
+ hurt = rnd(7) - encumber;
+ if (hurt < 5)
+ switch(rnd(3)){
+
+ case 0:
+ puts("You swung wide and missed.");
+ break;
+ case 1:
+ puts("He checked your blow. CLASH! CLANG!");
+ break;
+ case 2:
+ puts("His filthy tunic hangs by one less thread.");
+ break;
+ }
+ else if (hurt < 10){
+ switch(rnd(3)){
+ case 0:
+ puts("He's bleeding.");
+ break;
+ case 1:
+ puts("A trickle of blood runs down his face.");
+ break;
+ case 2:
+ puts("A huge purple bruise is forming on the side of his face.");
+ break;
+ }
+ lifeline++;
+ }
+ else if (hurt < 20){
+ switch(rnd(3)){
+ case 0:
+ puts("He staggers back quavering.");
+ break;
+ case 1:
+ puts("He jumps back with his hand over the wound.");
+ break;
+ case 2:
+ puts("His shirt falls open with a swath across the chest.");
+ break;
+ }
+ lifeline += 5;
+ }
+ else if (hurt < 30){
+ switch(rnd(3)){
+ case 0:
+ printf("A bloody gash opens up on his %s side.\n",(rnd(2) ? "left" : "right"));
+ break;
+ case 1:
+ puts("The steel bites home and scrapes along his ribs.");
+ break;
+ case 2:
+ puts("You pierce him, and his breath hisses through clenched teeth.");
+ break;
+ }
+ lifeline += 10;
+ }
+ else if (hurt < 40){
+ switch(rnd(3)){
+ case 0:
+ puts("You smite him to the ground.");
+ if (strength - lifeline > 20)
+ puts("But in a flurry of steel he regains his feet!");
+ break;
+ case 1:
+ puts("The force of your blow sends him to his knees.");
+ puts("His arm swings lifeless at his side.");
+ break;
+ case 2:
+ puts("Clutching his blood drenched shirt, he collapses stunned.");
+ break;
+ }
+ lifeline += 20;
+ }
+ else {
+ switch(rnd(3)){
+ case 0:
+ puts("His ribs crack under your powerful swing, flooding his lungs with blood.");
+ break;
+ case 1:
+ puts("You shatter his upheld arm in a spray of blood. The blade continues deep");
+ puts("into his back, severing the spinal cord.");
+ lifeline += 25;
+ break;
+ case 2:
+ puts("With a mighty lunge the steel slides in, and gasping, he falls to the ground.");
+ lifeline += 25;
+ break;
+ }
+ lifeline += 30;
+ }
+ break;
+
+ case BACK:
+ if (enemy == DARK && lifeline > strength * 0.33){
+ puts("He throws you back against the rock and pummels your face.");
+ if (testbit(inven,AMULET) || testbit(wear,AMULET)){
+ printf("Lifting the amulet from you, ");
+ if (testbit(inven,MEDALION) || testbit(wear,MEDALION)){
+ puts("his power grows and the walls of\nthe earth tremble.");
+ puts("When he touches the medallion, your chest explodes and the foundations of the\nearth collapse.");
+ puts("The planet is consumed by darkness.");
+ die();
+ }
+ if (testbit(inven,AMULET)){
+ clearbit(inven,AMULET);
+ carrying -= objwt[AMULET];
+ encumber -= objcumber[AMULET];
+ }
+ else
+ clearbit(wear,AMULET);
+ puts("he flees down the dark caverns.");
+ clearbit(location[position].objects,DARK);
+ injuries[SKULL] = 1;
+ followfight = time;
+ return (0);
+ }
+ else{
+ puts("I'm afraid you have been killed.");
+ die();
+ }
+ }
+ else{
+ puts("You escape stunned and disoriented from the fight.");
+ puts("A victorious bellow echoes from the battlescene.");
+ if (back && position != back)
+ move(back,BACK);
+ else if (ahead &&position != ahead)
+ move(ahead,AHEAD);
+ else if (left && position != left)
+ move(left,LEFT);
+ else if (right && position != right)
+ move(right,RIGHT);
+ else
+ move(location[position].down,AHEAD);
+ return(0);
+ }
+
+ case SHOOT:
+ if (testbit(inven,LASER)){
+ if (strength - lifeline <= 50){
+ printf("The %s took a direct hit!\n",objsht[enemy]);
+ lifeline += 50;
+ }
+ else {
+ puts("With his bare hand he deflects the laser blast and whips the pistol from you!");
+ clearbit(inven,LASER);
+ setbit(location[position].objects,LASER);
+ carrying -= objwt[LASER];
+ encumber -= objcumber[LASER];
+ }
+ }
+ else
+ puts("Unfortunately, you don't have a blaster handy.");
+ break;
+
+ case DROP:
+ case DRAW:
+ cypher();
+ time--;
+ break;
+
+ default:
+ puts("You don't have a chance, he is too quick.");
+ break;
+
+ }
+ if (lifeline >= strength){
+ printf("You have killed the %s.\n", objsht[enemy]);
+ if (enemy == ELF || enemy == DARK)
+ puts("A watery black smoke consumes his body and then vanishes with a peal of thunder!");
+ clearbit(location[position].objects,enemy);
+ power += 2;
+ notes[JINXED]++;
+ return(0);
+ }
+ puts("He attacks...");
+ /* some embellisments */
+ hurt = rnd(NUMOFINJURIES) - (testbit(inven,SHIELD) != 0) - (testbit(wear,MAIL) != 0) - (testbit(wear,HELM) != 0);
+ hurt += (testbit(wear,AMULET) != 0) + (testbit(wear,MEDALION) != 0) + (testbit(wear,TALISMAN) != 0);
+ hurt = hurt < 0 ? 0 : hurt;
+ hurt = hurt >= NUMOFINJURIES ? NUMOFINJURIES -1 : hurt;
+ if (!injuries[hurt]){
+ injuries[hurt] = 1;
+ printf("I'm afraid you have suffered %s.\n", ouch[hurt]);
+ }
+ else
+ puts("You emerge unscathed.");
+ if (injuries[SKULL] && injuries[INCISE] && injuries[NECK]){
+ puts("I'm afraid you have suffered fatal injuries.");
+ die();
+ }
+ goto fighton;
+}
diff --git a/battlestar/cypher.c b/battlestar/cypher.c
new file mode 100644
index 00000000..3ab3fcbe
--- /dev/null
+++ b/battlestar/cypher.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cypher.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+cypher()
+{
+ register int n;
+ int junk;
+ int lflag = -1;
+ char buffer[10];
+
+ while (wordtype[wordnumber] == ADJS)
+ wordnumber++;
+ while (wordnumber <= wordcount) {
+ switch(wordvalue[wordnumber]) {
+
+ case UP:
+ if (location[position].access || wiz || tempwiz) {
+ if (!location[position].access)
+ puts("Zap! A gust of wind lifts you up.");
+ if (!move(location[position].up, AHEAD))
+ return(-1);
+ } else {
+ puts("There is no way up");
+ return(-1);
+ }
+ lflag = 0;
+ break;
+
+ case DOWN:
+ if (!move(location[position].down, AHEAD))
+ return(-1);
+ lflag = 0;
+ break;
+
+ case LEFT:
+ if (!move(left, LEFT))
+ return(-1);
+ lflag = 0;
+ break;
+
+ case RIGHT:
+ if (!move(right, RIGHT))
+ return(-1);
+ lflag = 0;
+ break;
+
+ case AHEAD:
+ if (!move(ahead, AHEAD))
+ return(-1);
+ lflag = 0;
+ break;
+
+ case BACK:
+ if (!move(back, BACK))
+ return(-1);
+ lflag = 0;
+ break;
+
+ case SHOOT:
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(location[position].objects,n) && *objsht[n]){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = shoot();
+ }
+ wordnumber++;
+ wordnumber++;
+ }
+ else
+ shoot();
+ break;
+
+ case TAKE:
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(location[position].objects,n) && *objsht[n]){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = take(location[position].objects);
+ }
+ wordnumber++;
+ wordnumber++;
+ }
+ else
+ take(location[position].objects);
+ break;
+
+ case DROP:
+
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(inven,n)){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = drop("Dropped");
+ }
+ wordnumber++;
+ wordnumber++;
+ }
+ else
+ drop("Dropped");
+ break;
+
+
+ case KICK:
+ case THROW:
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(inven,n) ||
+ testbit(location[position].objects, n) && *objsht[n]){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
+ }
+ wordnumber += 2;
+ } else
+ throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
+ break;
+
+ case TAKEOFF:
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(wear,n)){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = takeoff();
+ }
+ wordnumber += 2;
+ }
+ else
+ takeoff();
+ break;
+
+
+ case DRAW:
+
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(wear,n)){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = draw();
+ }
+ wordnumber += 2;
+ }
+ else
+ draw();
+ break;
+
+
+ case PUTON:
+
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(location[position].objects,n) && *objsht[n]){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = puton();
+ }
+ wordnumber += 2;
+ }
+ else
+ puton();
+ break;
+
+ case WEARIT:
+
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(inven,n)){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = wearit();
+ }
+ wordnumber += 2;
+ }
+ else
+ wearit();
+ break;
+
+
+ case EAT:
+
+ if (wordnumber < wordcount && wordvalue[wordnumber+1] == EVERYTHING){
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(inven,n)){
+ wordvalue[wordnumber+1] = n;
+ wordnumber = eat();
+ }
+ wordnumber += 2;
+ }
+ else
+ eat();
+ break;
+
+
+ case PUT:
+ put();
+ break;
+
+
+ case INVEN:
+ if (ucard(inven)){
+ puts("You are holding:\n");
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(inven,n))
+ printf("\t%s\n", objsht[n]);
+ printf("\n= %d kilogram%s (%d%%)\n", carrying, (carrying == 1 ? "." : "s."),(WEIGHT ? carrying*100/WEIGHT : -1));
+ printf("Your arms are %d%% full.\n",encumber*100/CUMBER);
+ }
+ else
+ puts("You aren't carrying anything.");
+
+ if (ucard(wear)){
+ puts("\nYou are wearing:\n");
+ for (n=0; n < NUMOFOBJECTS; n++)
+ if (testbit(wear,n))
+ printf("\t%s\n", objsht[n]);
+ }
+ else
+ puts("\nYou are stark naked.");
+ if (card(injuries,NUMOFINJURIES)){
+ puts("\nYou have suffered:\n");
+ for (n=0; n < NUMOFINJURIES; n++)
+ if (injuries[n])
+ printf("\t%s\n",ouch[n]);
+ printf("\nYou can still carry up to %d kilogram%s\n",WEIGHT,(WEIGHT == 1 ? "." : "s."));
+ }
+ else
+ puts("\nYou are in perfect health.");
+ break;
+
+ case USE:
+ lflag = use();
+ break;
+
+ case LOOK:
+ if (!notes[CANTSEE] || testbit(inven,LAMPON) || testbit(location[position].objects,LAMPON) || matchlight){
+ beenthere[position] = 2;
+ writedes();
+ printobjs();
+ if (matchlight){
+ puts("\nYour match splutters out.");
+ matchlight = 0;
+ }
+ } else
+ puts("I can't see anything.");
+ return(-1);
+ break;
+
+ case SU:
+ if (wiz || tempwiz){
+ printf("\nRoom (was %d) = ", position);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n')
+ sscanf(buffer,"%d", &position);
+ printf("Time (was %d) = ",time);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n')
+ sscanf(buffer,"%d", &time);
+ printf("Fuel (was %d) = ",fuel);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n')
+ sscanf(buffer,"%d", &fuel);
+ printf("Torps (was %d) = ",torps);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n')
+ sscanf(buffer,"%d", &torps);
+ printf("CUMBER (was %d) = ",CUMBER);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n')
+ sscanf(buffer,"%d", &CUMBER);
+ printf("WEIGHT (was %d) = ",WEIGHT);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n')
+ sscanf(buffer,"%d",&WEIGHT);
+ printf("Clock (was %d) = ",clock);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n')
+ sscanf(buffer,"%d",&clock);
+ printf("Wizard (was %d, %d) = ",wiz, tempwiz);
+ fgets(buffer,10,stdin);
+ if (*buffer != '\n'){
+ sscanf(buffer,"%d",&junk);
+ if (!junk)
+ tempwiz = wiz = 0;
+ }
+ printf("\nDONE.\n");
+ return(0);
+ }
+ else
+ puts("You aren't a wizard.");
+ break;
+
+ case SCORE:
+ printf("\tPLEASURE\tPOWER\t\tEGO\n");
+ printf("\t%3d\t\t%3d\t\t%3d\n\n",pleasure,power,ego);
+ printf("This gives you the rating of %s in %d turns.\n",rate(),time);
+ printf("You have visited %d out of %d rooms this run (%d%%).\n",card(beenthere,NUMOFROOMS),NUMOFROOMS,card(beenthere,NUMOFROOMS)*100/NUMOFROOMS);
+ break;
+
+ case KNIFE:
+ case KILL:
+ murder();
+ break;
+
+ case UNDRESS:
+ case RAVAGE:
+ ravage();
+ break;
+
+ case SAVE:
+ save();
+ break;
+
+ case FOLLOW:
+ lflag = follow();
+ break;
+
+ case GIVE:
+ give();
+ break;
+
+ case KISS:
+ kiss();
+ break;
+
+ case LOVE:
+ love();
+ break;
+
+ case RIDE:
+ lflag = ride();
+ break;
+
+ case DRIVE:
+ lflag = drive();
+ break;
+
+ case LIGHT:
+ light();
+ break;
+
+ case LAUNCH:
+ if (!launch())
+ return(-1);
+ else
+ lflag = 0;
+ break;
+
+ case LANDIT:
+ if (!land())
+ return(-1);
+ else
+ lflag = 0;
+ break;
+
+ case TIME:
+ chime();
+ break;
+
+ case SLEEP:
+ zzz();
+ break;
+
+ case DIG:
+ dig();
+ break;
+
+ case JUMP:
+ lflag = jump();
+ break;
+
+ case BURY:
+ bury();
+ break;
+
+ case SWIM:
+ puts("Surf's up!");
+ break;
+
+ case DRINK:
+ drink();
+ break;
+
+ case QUIT:
+ die();
+
+ default:
+ puts("How's that?");
+ return(-1);
+ break;
+
+
+ }
+ if (wordnumber < wordcount && *words[wordnumber++] == ',')
+ continue;
+ else return(lflag);
+ }
+ return(lflag);
+}
diff --git a/battlestar/dayfile.c b/battlestar/dayfile.c
new file mode 100644
index 00000000..3e2fc1a2
--- /dev/null
+++ b/battlestar/dayfile.c
@@ -0,0 +1,1205 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dayfile.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+struct room dayfile[] = {
+ { 0 },
+ { "You are in the main hangar.",
+ 5, 2, 9, 3, 3, 1, 0, 0,
+"This is a huge bay where many fighters and cargo craft lie. Alarms are \n\
+sounding and fighter pilots are running to their ships. Above is a gallery\n\
+overlooking the bay. The scream of turbo engines is coming from +. The rest\n\
+of the hangar is +. There is an exit +.*\n" },
+ { "This is the landing bay.",
+ 1, 0, 10, 0, 0, 0, 0, 0,
+"Ships are landing here, some heavily damaged. Enemy fighters continually\n\
+strafe this vulnerable port. The main hangar is +, *\n\
+There is an exit +.*\n" },
+ { "You are in the gallery.",
+ 4, 0, 0, 0, 0, 0, 1, 0,
+"From here a view of the entire landing bay reveals that our battlestar\n\
+is near destruction. Fires are spreading out of control and laser blasts\n\
+lick at the shadows. The control room is +. ***\n" },
+ { "You are in the control room.",
+ 0, 3, 0, 0, 0, 0, 5, 0,
+"Several frantic technicians are flipping switches wildly but otherwise\n\
+this room seems fairly deserted. A weapons locker has been left open.\n\
+A staircase leads down. * There is a way -. ** \n" },
+ { "This is the launch room.",
+ 6, 1, 7, 0, 4, 1, 0, 0,
+"From the launch tubes here fighters blast off into space. Only one is left,\n\
+and it is guarded by two fierce men. A staircase leads up from here.\n\
+There is a cluttered workbench +. From the main hangar come sounds of great\n\
+explosions. The main hangar is +. The viper launch tubes are to the -.*\n" },
+ { "You are at the workbench.",
+ 0, 5, 7, 0, 0, 0, 0, 0,
+"Strange and unwieldy tools are arranged here including a lunch box \n\
+and pneumatic wrenches and turbo sprocket rockets.*\n\
+The launch room is +. The remaining viper is +.*\n" },
+ { "You are in the viper launch tube.",
+ 0, 5, 0, 5, 32, 0, 0, 0,
+"The two guards are eyeing you warily! ****\n" },
+ { "This is a walk in closet.",
+ 22, 0, 0, 0, 0, 0, 0, 0,
+"A wardrobe of immense magnitude greets the eye. Furs and robes of kings\n\
+hang on rack after rack. Silken gowns, capes woven with spun gold, and \n\
+delicate synthetic fabrics are stowed here. The bedroom is +.***\n" },
+ { "You are in a wide hallway leading to the main hangar.",
+ 0, 0, 11, 1, 0, 0, 0, 0,
+"The walls and ceiling here have been blasted through in several places.\n\
+It looks as if quite a battle has been fought for possession of the landing bay\n\
+Gaping corpses litter the floor.** The hallway continues +.\n\
+The main hangar is +.\n" },
+ { "You are in a wide hallway leading to the landing bay.",
+ 0, 0, 12, 2, 0, 0, 0, 0,
+"Most of the men and supplies needed in the main hangar come through this\n\
+corridor, but the wounded are forced to use it too. It very dank and\n\
+crowded here, and the floor is slippery with blood.**\n\
+The hallway continues -. The landing bay is +.\n" },
+ { "The hallway is very congested with rubble here.",
+ 0, 0, 0, 9, 13, 1, 0, 0,
+"It is too choked with broken steel girders and other debris to continue\n\
+on much farther. Above, the ceiling has caved in and it is possible to \n\
+climb up. There is not much chance to go -, -, or -.\n\
+But the hallway seems clearer +.\n" },
+ { "A wide hallway and a more narrow walkway meet here.",
+ 14, 15, 0, 10, 0, 0, 0, 0,
+"The intersection is crowded with the many wounded who have come up\n\
+the wide hallway and continued +. The walkway is less crowded +.\n\
+The wide hallway goes *-.\n" },
+ { "You are in what was once an elegant stateroom.",
+ 16, 0, 0, 0, 0, 0, 11, 0,
+"Whoever lived in this stateroom, he and his female companion\n\
+were mercilessly slain in their sleep. Clothes, trinkets and personal\n\
+belongings are scattered all across the floor. Through a hole in the\n\
+collapsed floor I can see a hallway below. A door is +.***\n" },
+ { "You're at the entrance to the sick bay.",
+ 17, 12, 18, 0, 0, 0, 0, 0,
+"The wounded are entering the sick bay in loudly moaning files.\n\
+The walkway continues - and +. A doctor is motioning for you to \n\
+come to the -. *\n" },
+ { "You're in the walkway.",
+ 12, 19, 0, 0, 0, 0, 0, 0,
+"Most of the men and supplies were coming from the armory. The walkway\n\
+continues -. The armory is +.**\n" },
+ { "These are the executive suites of the battlestar.",
+ 20, 13, 21, 22, 23, 1, 24, 0,
+"Luxurious staterooms carpeted with crushed velvet and adorned with beaten\n\
+gold open onto this parlor. A wide staircase with ivory banisters leads\n\
+up or down. This parlor leads into a hallway +. The bridal suite is +.\n\
+Other rooms lie - and +.\n" },
+ { "You're in a long dimly lit hallway.",
+ 0, 14, 25, 0, 0, 0, 0, 0,
+"This part of the walkway is deserted. There is a dead end +. The\n\
+entrance to the sickbay is +. The walkway turns sharply -.*\n" },
+ { "This is the sick bay.",
+ 0, 0, 0, 14, 0, 0, 0, 0,
+"Sinister nurses with long needles and pitiful aim probe the depths of suffering\n\
+here. Only the mortally wounded receive medical attention on a battlestar,\n\
+but afterwards they are thrown into the incinerators along with the rest.**\n\
+Nothing but death and suffering +. The walkway is +.\n" },
+ { "You're in the armory.",
+ 15, 26, 0, 0, 0, 0, 0, 0,
+"An armed guard is stationed here 365 sectars a yarn to protect the magazine.\n\
+The walkway is +. The magazine is +.**\n" },
+ { "The hallway ends here at the presidential suite.",
+ 27, 16, 0, 0, 0, 0, 0, 0,
+"The door to this suite is made from solid magnesium, and the entryway is\n\
+inlaid with diamonds and fire opals. The door is ajar +. The hallway\n\
+goes -.**\n" },
+ { "This is the maid's utility room.",
+ 0, 0, 0, 16, 0, 0, 0, 0,
+"What a gruesome sight! The maid has been brutally drowned in a bucket of\n\
+Pine Sol and repeatedly stabbed in the back with a knife.***\n\
+The hallway is +.\n" },
+ { "This is a luxurious stateroom.",
+ 0, 8, 16, 0, 0, 0, 0, 0,
+"The floor is carpeted with a soft animal fur and the great wooden furniture\n\
+is inlaid with strips of platinum and gold. Electronic equipment built\n\
+into the walls and ceiling is flashing wildly. The floor shudders and\n\
+the sounds of dull explosions rumble though the room. From a window in\n\
+the wall + comes a view of darkest space. There is a small adjoining\n\
+room +, and a doorway +.*\n" },
+ { "You are at the entrance to the dining hall.",
+ 0, 0, 28, 0, 0, 0, 16, 0,
+"A wide staircase with ebony banisters leads down here.**\n\
+The dining hall is to the -.*\n" },
+ { "This was once the first class lounge.",
+ 0, 0, 29, 0, 16, 1, 0, 0,
+"There is much rubble and destruction here that was not apparent elsewhere.\n\
+The walls and ceilings have broken in in some places. A staircase with\n\
+red coral banisters leads up. It is impossible to go - or -.\n\
+It seems a little clearer +.*\n" },
+ { "You are in a narrow stairwell.",
+ 0, 17, 0, 0, 30, 1, 0, 0,
+"These dusty and decrepit stairs lead up. There is no way -. The\n\
+hallway turns sharply -.**\n" },
+ { "You are in the magazine.",
+ 19, 0, 0, 0, 0, 0, 0, 0,
+"Rows and rows of neatly stacked ammunition for laser pistols and grenade\n\
+launchers are here. The armory is +.***\n" },
+ { "You're in the presidential suite.",
+ 0, 20, 0, 0, 0, 0, 0, 0,
+"Apparently the president has been assassinated. A scorched figure lies\n\
+face downward on the carpet clutching his chest.*\n\
+The hallway leads -.**\n" },
+ { "You are in the dining hall.",
+ 0, 30, 31, 23, 0, 0, 0, 0,
+"This was the seen of a mass suicide. Hundreds of ambassadors and assorted\n\
+dignitaries sit slumped over their breakfast cereal. I suppose the news\n\
+of the cylon attack killed them. There is a strange chill in this room. I\n\
+would not linger here. * The kitchen is +. Entrances + and +.\n" },
+ { "The debris is very thick here.",
+ 0, 11, 0, 24, 0, 0, 0, 0,
+"Broken furniture, fallen girders, and other rubble block the way.\n\
+There is not much chance to continue -, -, or -.\n\
+It would be best to go -.\n" },
+ { "You are in the kitchen.",
+ 28, 0, 0, 0, 0, 0, 0, 0,
+"This room is full of shining stainless steel and burnished bronze cookware. An \n\
+assortment of tropical fruits and vegetables as well as fine meats and cheeses \n\
+lies on a sterling platter. The chef, unfortunately, has been skewered like a \n\
+side of beef. The dining room is +. ** There is a locked door +.\n" },
+ { "You are in an arched entry leading to the dining room.",
+ 0, 0, 0, 28, 0, 0, 0, 0,
+"The door leading out is bolted shut from the outside and is very strong.***\n\
+The dining room is +.\n" },
+ { "You are in space.",
+ 33, 34, 35, 36, 37, 1, 33, 1,
+"****\n" },
+ { "You are in space.",
+ 38, 32, 39, 40, 41, 1, 42, 1,
+"****\n" },
+ { "You are in space.",
+ 32, 44, 45, 46, 47, 1, 48, 1,
+"****\n" },
+ { "You are in space.",
+ 40, 45, 49, 32, 50, 1, 51, 1,
+"****\n" },
+ { "You are in space.",
+ 41, 46, 32, 52, 53, 1, 54, 1,
+"****\n" },
+ { "You are in space.",
+ 42, 47, 50, 53, 55, 1, 32, 1,
+"****\n" },
+ { "You are in space.",
+ 43, 48, 51, 54, 32, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 57, 33, 40, 41, 42, 1, 43, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 35, 57, 33, 58, 1, 59, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 36, 33, 59, 60, 1, 61, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 37, 58, 60, 62, 1, 33, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 38, 59, 61, 33, 1, 63, 1,
+"****\n" },
+ { "You are in space.",
+ 34, 64, 45, 46, 47, 1, 48, 1,
+"****\n" },
+ { "You are in space.",
+ 35, 44, 49, 34, 50, 1, 51, 1,
+"****\n" },
+ { "You are in space.",
+ 36, 44, 34, 52, 53, 1, 54, 1,
+"****\n" },
+ { "You are in space.",
+ 37, 44, 50, 53, 55, 1, 34, 1,
+"****\n" },
+ { "You are in space.",
+ 38, 44, 51, 54, 34, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 49, 49, 52, 35, 49, 1, 49, 1,
+"****\n" },
+ { "You are in space.",
+ 58, 47, 49, 37, 55, 1, 35, 1,
+"****\n" },
+ { "You are in space.",
+ 59, 48, 49, 38, 35, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 52, 52, 36, 49, 52, 1, 52, 1,
+"****\n" },
+ { "You are in space.",
+ 60, 46, 37, 52, 55, 1, 36, 1,
+"****\n" },
+ { "You are in space.",
+ 61, 48, 38, 52, 36, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 62, 55, 55, 55, 56, 1, 37, 1,
+"****\n" },
+ { "You are in space.",
+ 56, 56, 56, 56, 38, 1, 55, 1,
+"****\n" },
+ { "You are in space.",
+ 65, 39, 57, 57, 57, 1, 57, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 50, 49, 42, 62, 1, 40, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 51, 49, 43, 40, 1, 63, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 53, 43, 59, 62, 1, 41, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 54, 43, 59, 41, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 55, 62, 62, 56, 1, 42, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 56, 35, 36, 43, 1, 55, 1,
+"****\n" },
+ { "You are in space.",
+ 44, 66, 66, 66, 66, 1, 66, 1,
+"****\n" },
+ { "You are in space.",
+ 67, 57, 67, 67, 67, 1, 67, 1,
+"****\n" },
+ { "You are in space.",
+ 64, 68, 68, 68, 68, 1, 68, 1,
+"****\n" },
+ { "You are orbiting a small blue planet.",
+ 67, 67, 67, 67, 65, 1, 69, 1,
+"****\n" },
+ { "You are orbiting a tropical planet.",
+ 68, 68, 68, 68, 66, 1, 70, 1,
+"****\n" },
+ { "You are flying through a dense fog.",
+ 69, 69, 69, 69, 69, 1, 69, 1,
+"A cold grey sea of mist is swirling around the windshield and water droplets\n\
+are spewing from the wingtips. Ominous shadows loom in the darkness and it\n\
+feels as if a trap is closing around us. I have lost all sense of direction.\n\
+****\n" },
+ { "You are approaching an island.",
+ 71, 72, 73, 74, 68, 1, 0, 1,
+"Coconut palms, sword ferns, orchids, and other lush vegetation drape this\n\
+jagged island carved seemingly from pure emerald and set in a turquoise\n\
+sea. The land rises sharply +. There is a nice beach* +.*\n" },
+ { "You are flying over a mountainous region.",
+ 75, 73, 76, 77, 68, 1, 0, 1,
+"Below is a magnificent canyon with deep gorges, high pinnacles and\n\
+waterfalls plummeting hundreds of feet into mist. Everything in sight\n\
+is carpeted with a tropical green.* The ocean is +.**\n" },
+ { "You are flying over the ocean.",
+ 74, 78, 78, 78, 68, 1, 0, 1,
+"You bank over the water and your wingtips dip low to the green waves. The\n\
+sea is very shallow here and the white coral beds beneath us teem with \n\
+colorful fish.****\n" },
+ { "You are flying over the beach.",
+ 71, 72, 79, 74, 68, 1, 80, 1,
+"A warm gentle surf caresses the white coral beach here. The land rises\n\
+sharply +.* The beach is lost in low cliffs and rocks +.*\n" },
+ { "You are flying over a large lagoon.",
+ 81, 72, 73, 82, 68, 1, 0, 1,
+"Encircled by a coral reef, the palms and ferns in this sheltered spot\n\
+have grown down to the water's very brink which winds tortuously inland.\n\
+There looks like a small village +.***\n" },
+ { "You are flying over a gently sloping plane.",
+ 83, 71, 84, 85, 68, 1, 0, 1,
+"This is where several alluvial fans and ancient lava flows have run\n\
+together forming a fertile plane choked with vegetation. It would be\n\
+impossible to land safely here.* The terrain is more rugged +.**\n" },
+ { "You are flying through a gorge.",
+ 0, 0, 86, 71, 68, 1, 102, 1,
+"This narrow, steep sided canyon is lined with waving ferns. The floor is of\n\
+light gravel with many freshets pouring from the walls and running along it.\n\
+The gorge leads to the sea** +, and to a tumultuous origin +.\n" },
+ { "You are flying over a plantation.",
+ 85, 81, 71, 88, 68, 1, 89, 1,
+"Rows of palms, papayas, mangoes, kiwi, as well as smaller fields of sugar\n\
+cane and pineapple are growing here. It might be possible to land here, but\n\
+I wouldn't advise it.* There looks like two small settlements + \n\
+and *+.\n" },
+ { "You are over the ocean.",
+ 72, 78, 79, 74, 68, 1, 0, 1,
+"The deep green swells foam and roll into the shore **+*.\n" },
+ { "You are flying along the coast.",
+ 86, 72, 90, 73, 68, 1, 91, 1,
+"The coastline here is very rocky with little or no sand. The surf in some\n\
+places is violent and explodes in a shower of sparkling spray.\n\
+There is a winding road below which closely follows the shore. ****\n" },
+ { "This is a beautiful coral beach.",
+ 106, 0, 107, 108, 73, 0, 0, 0,
+"Fine silver sand kissed lightly by warm tropical waters stretches at least\n\
+30 meters here from the ocean to under gently swaying palms +.***\n" },
+ { "You are flying over a small fishing village.",
+ 77, 74, 71, 82, 68, 1, 92, 1,
+"A few thatched huts a short distance from the water and row of more modern\n\
+bungalows on either side of a dirt road are all that is here. The road\n\
+continues on ***+.\n" },
+ { "You are flying over a clearing.",
+ 88, 72, 74, 87, 68, 1, 93, 1,
+"There is a dock here (big enough for a seaplane) leading to a grassy\n\
+meadow and a road. Some people are having a party down there. Below is\n\
+a good landing site. ****\n" },
+ { "You are flying over the shore.",
+ 94, 75, 95, 96, 68, 1, 0, 1,
+"Rocky lava flows or coarse sandy beaches are all that is here except for\n\
+sparse herbs and weeds.****\n" },
+ { "You are flying in a wide valley.",
+ 95, 97, 86, 75, 68, 1, 98, 1,
+"This is a shallow valley yet the floor is obscured by a thick mist.\n\
+The valley opens to the sea +. The mist grows thicker +.**\n" },
+ { "You are flying near the shore.",
+ 96, 77, 75, 99, 68, 1, 0, 1,
+"Very tall palm trees growing in neatly planted rows march off from the \n\
+water here towards the hills and down to the flat lands *+.*\n\
+There is a nice beach +.\n" },
+ { "You are flying around the very tip of the island.",
+ 95, 79, 90, 84, 68, 1, 0, 1,
+"There is no beach here for sheer cliffs rise several hundred feet\n\
+to a tree covered summit. Far below, the blue sea gnaws voraciously at\n\
+the roots of these cliffs. The island bends around +** and +.\n" },
+ { "You are flying along the coastline.",
+ 99, 82, 88, 100, 68, 1, 101, 1,
+"There is a narrow strip of sand here lined with ferns and shrubs, but very\n\
+few trees. The beach is barley wide enough to land on. The beach continues\n\
+on -.* There are some buildings +.*\n" },
+ { "You are flying over several cottages and buildings",
+ 99, 82, 77, 87, 68, 1, 103, 1,
+"The grounds here are landscaped with palm trees, ferns, orchids, and beds of\n\
+flowering plumeria and antheriums. Directly below is a small ornate white\n\
+house with a belltower, a lush green lawn, and a spurting fountain.\n\
+Small dirt roads go + and +.**\n" },
+ { "You are in a field of sugar cane.",
+ 109, 110, 111, 112, 77, 0, 0, 0,
+"These strong, thick canes give little shelter but many cuts and scrapes.\n\
+There are some large trees ***+.\n" },
+ { "You are flying over the ocean.",
+ 95, 78, 90, 86, 68, 1, 0, 1,
+"The water is a placid turquoise and so clear that fish and sharks\n\
+many fathoms below are clearly visible.****\n" },
+ { "You are on the coast road.",
+ 113, 114, 115, 116, 79, 0, 0, 0,
+"The road winds close to the shore here and the sound of crashing surf is\n\
+deafening.* The water is +. The road continues - and -.\n" },
+ { "You are on the main street of the village.",
+ 117, 118, 119, 120, 81, 0, 0, 0,
+"Thatched roofs and outrigger canoes, palm trees and vacation bungalows, and\n\
+comely natives in a tropical paradise all make this a fantasy come true.\n\
+There is an open bungalow +.* The road continues - and -.\n" },
+ { "You are at the sea plane dock.",
+ 121, 122, 123, 124, 82, 0, 0, 0,
+"Native girls with skin of gold, clad only in fragrant leis and lavalavas,\n\
+line the dockside to greet you. A couple of ukulele plucking islanders and a\n\
+keyboard player are adding appropriate music. A road crosses the clearing \n\
++*. There are some tables set up +.*\n" },
+ { "You are flying over the ocean.",
+ 94, 83, 95, 96, 68, 1, 0, 1,
+"Sea weeds and kelp surge in the waves off shore here. The ocean becomes \n\
+much deeper +.***\n" },
+ { "You are flying along the coast.",
+ 94, 84, 86, 83, 68, 1, 0, 1,
+"The land is very low here with a river running into the sea +. There\n\
+is a wide valley opening up +. The very tip of the island is +.*\n" },
+ { "You are flying along the coast.",
+ 94, 85, 83, 99, 68, 1, 0, 1,
+"There are some secluded sandy stretches of beach here, but too many rocky\n\
+outcroppings of lava to land. There is a nicer beach ***+.\n" },
+ { "You are lost in a sea of fog.",
+ 97, 104, 97, 97, 97, 1, 0, 1,
+"What have you gotten us into?\n\
+I cant see a thing! ****\n" },
+ { "You are on a gravel wash.",
+ 125, 126, 127, 128, 84, 0, 0, 0,
+"The sound of cascading water is the background for a diluted chorus of \n\
+gurgling, splashing, and enchantingly delicate singing. Great billows\n\
+of steam are rising *+.**\n" },
+ { "You are flying over a wide beach.",
+ 96, 88, 85, 87, 68, 1, 105, 1,
+"Unlike the leeward beaches, few coconut palms grow here but a well groomed\n\
+lawn and garden with traipsing stone walks leads down to the sand.*\n\
+There are some buildings +. Some trees are growing +.*\n" },
+ { "You are flying over the ocean.",
+ 100, 100, 87, 100, 68, 1, 0, 1,
+"The sea is a perfectly clear blue with a white sandy bottom. No coral\n\
+grows underwater here, but the force of the waves is broken by the steep\n\
+incline.****\n" },
+ { "You are on a narrow strip of sand.",
+ 129, 130, 131, 0, 87, 0, 0, 0,
+"Rather coarse sand makes this beach very steep and only a few meters wide.\n\
+A fresh ocean breeze is rustling the ferns **+.*\n" },
+ { "This is Fern Canyon.",
+ 0, 0, 132, 133, 76, 0, 0, 0,
+"Delicate waving ferns flourish here, suckled by warm water dripping from \n\
+every fissure and crevice in the solid rock walls.\n\
+The canyon winds **-, and -.\n" },
+ { "This is the front lawn.",
+ 134, 135, 136, 137, 88, 0, 0, 0,
+"There is a small fountain here where the driveway meets the lawn.\n\
+Across the driveway, +, is an ornate white house with and elegant \n\
+woodworking. The bargeboards are carved with fylfots, the ancient \n\
+symbols of luck. Even a bell tower has been built here.* There is a \n\
+road + which turns into the driveway.*\n" },
+ { "You have just crossed the crest of a mountain.",
+ 97, 79, 86, 71, 68, 1, 0, 1,
+"The fog vanished mysteriously as we flew over the crest.*\n\
+Far + I can see the ocean.**\n" },
+ { "You are on a sandy beach.",
+ 138, 139, 140, 0, 99, 0, 0, 0,
+"This is the only good beach on the weather side of the island. Fine coral\n\
+sand, a fresh sea breeze, and dramatic surf add to its appeal.**\n\
+Stone steps lead to the gardens +.*\n" },
+ { "You are among palm trees near the shore.",
+ 141, 80, 142, 143, 73, 0, 0, 0,
+"Arching coconut palms laden with fruit provide a canopy for the glistening\n\
+white sand and sparse grasses growing here. The forest grows denser +.\n\
+The ocean is +.**\n" },
+ { "You are walking along the beach.",
+ 144, 0, 145, 80, 73, 0, 0, 0,
+"The warm tropical waters nuzzle your ankles as you walk. Above is a fiercely\n\
+blue sky. The slope of the sand is so gentle that two hundred meters\n\
+offshore the water is only knee deep.** There are some rocks +.*\n" },
+ { "You are walking along the beach.",
+ 146, 0, 80, 147, 73, 0, 0, 0,
+"Many beautiful shells have been washed up here including bright yellow \n\
+cowries, chocolate colored murex, orange conchs, striped tritons and the\n\
+deadly cone shells.****\n" },
+ { "You are in a papaya grove.",
+ 148, 89, 149, 150, 77, 0, 0, 0,
+"Green slender trees no taller than three meters bulge with their\n\
+orange succulent fruit. There are some tall trees +.***\n" },
+ { "You are in a field of pineapple.",
+ 89, 151, 152, 153, 77, 0, 0, 0,
+"The sharp dagger like pineapple leaves can pierce the flesh and hold fast\n\
+a skewered victim with tiny barbs.* The field ends +.**\n" },
+ { "You are in a field of kiwi plants.",
+ 149, 154, 155, 89, 77, 0, 0, 0,
+"Round hairy fruit hang from staked vines here. There are some trees +\n\
+and +. The field ends in a dirt road +.*\n" },
+ { "You are in a large grove of coconuts.",
+ 150, 153, 89, 156, 77, 0, 0, 0,
+"These trees are much taller than any growing near the shore plus the fat,\n\
+juicy coconuts have been selectively cultivated. The grove continues\n\
++, +, *and +.\n" },
+ { "You are in the woods.",
+ 157, 91, 158, 116, 79, 0, 0, 0,
+"Tropical undergrowth makes the going rough here. Sword ferns give no strong\n\
+foot hold and the dangling vines would gladly throttle one. Strange cackling\n\
+noises are coming from somewhere +.***\n" },
+ { "You are at the shore.",
+ 91, 0, 159, 145, 79, 0, 0, 0,
+"Explosions of surf jetting out of underwater tunnels here make it\n\
+impossible to climb down to a small cave entrance below. Only at rare\n\
+minus tides would it be possible to enter.*** The beach is better +.\n" },
+ { "You are on the coast road.",
+ 158, 161, 162, 91, 79, 0, 0, 0,
+"The road is beginning to turn inland.* I can here the surf +. The road\n\
+continues +.*\n" },
+ { "The road winds deeper into the trees.",
+ 163, 142, 91, 164, 79, 0, 0, 0,
+"Only narrow sunbeams filter through the foliage above. The moist rich earth\n\
+has nurtured a myriad of trees, shrubs, and flowers to grow here. The\n\
+road continues - and *- from here.*\n" },
+ { "This is the front porch of the bungalow.",
+ 165, 92, 0, 0, 81, 0, 0, 0,
+"These wooden steps and porch are very bucolic. A little woven mat on the \n\
+doorstep reads \"Don't Tread on Me\". The open front door is +.\n\
+A stone walk leads to the main street +.**\n" },
+ { "You are on a path leading to the lagoon.",
+ 92, 166, 167, 168, 81, 0, 0, 0,
+"This path trampled fern, grass, sapling, and anything else that got in its\n\
+way.* The water is +.**\n" },
+ { "This is a dirt road.",
+ 169, 118, 170, 92, 81, 0, 0, 0,
+"**The road continues on - here for some distance. A village is +.\n" },
+ { "You are on a dirt road.",
+ 171, 118, 92, 172, 81, 0, 0, 0,
+"**There is a small village +. The road continues +.\n" },
+ { "You are on a dirt road.",
+ 173, 93, 174, 175, 82, 0, 0, 0,
+"The light tan soil of the road contrasts artistically with the lush green\n\
+vegetation and seering blue sky.* There is a clearing and many people +.\n\
+The road continues - and -.\n" },
+ { "You are at the seaplane dock.",
+ 93, 0, 176, 177, 82, 0, 0, 0,
+"Several muscular, bronze skinned men greet you warmly as you pass under\n\
+a thatched shelter above the dock here. Polynesian hospitality.\n\
+There is a clearing +.* A trail runs around the lagoon + and +.\n" },
+ { "There are some tables on the lawn here.",
+ 121, 122, 123, 93, 82, 0, 0, 0,
+"Hors d'oeuvres, canapes, mixed drinks, and various narcotic drugs along with\n\
+cartons of Di Gel fill the tables to overflowing. Several other guests are\n\
+conversing and talking excitedly****.\n" },
+ { "You are nosing around in the bushes.",
+ 124, 124, 93, 124, 82, 0, 0, 0,
+"There is little here but some old beer cans. You are making fools out of\n\
+us in front of the other guests.** It would be best to go -.*\n" },
+ { "You are walking in a dry stream bed.",
+ 178, 98, 179, 0, 84, 0, 0, 0,
+"The large cobblestones are difficult to walk on. No sunlight reaches\n\
+below a white canopy of fog seemingly generated from *+. A dirt path \n\
+along the wash is +. A high bank is impossible to climb +.\n" },
+ { "You are at the thermal pools.",
+ 98, 0, 180, 181, 84, 0, 0, 0,
+"Several steaming fumaroles and spluttering geysers drenched by icy mountain\n\
+waters from a nearby waterfall heat half a dozen natural pools to a\n\
+delicious 42 degrees. Enchantingly beautiful singing seems to flow from the\n\
+water itself as it tumbles down the falls.*** There is a mossy entrance\n\
+to a cave +.\n" },
+ { "You are in the woods.",
+ 127, 180, 182, 98, 84, 0, 0, 0,
+"Coniferous trees girded by wild huckleberries, elderberries, salmonberries\n\
+and thimbleberries enjoy a less tropical climate here in the high mountains.\n\
+*The sound of rushing water is coming from +.**\n" },
+ { "You are on a dirt trail.",
+ 179, 181, 98, 0, 84, 0, 0, 0,
+"The trail seems to start here and head -.** High cliffs border the \n\
+trail +.\n" },
+ { "You are walking along the beach.",
+ 183, 101, 184, 0, 87, 0, 0, 0,
+"A rather unnerving surf explodes onto the beach here and dashes itself into\n\
+spray on the steep incline. The beach continues + and +.**\n" },
+ { "You are walking along the beach.",
+ 101, 185, 186, 0, 87, 0, 0, 0,
+"This is not a very nice beach. The coarse sand hurts my feet.****\n" },
+ { "You are walking through some ferns.",
+ 184, 186, 187, 101, 87, 0, 0, 0,
+"This is a wide field growing only ferns and small shrubs.** The \n\
+ocean is *+.\n" },
+ { "You are in a narrow canyon.",
+ 0, 0, 188, 102, 76, 0, 0, 0,
+"The steep sides here squeeze a little freshet through a gauntlet like\n\
+series of riffles and pools.****\n" },
+ { "The canyon is much wider here.",
+ 0, 0, 102, 189, 76, 0, 0, 0,
+"The sheer rock walls rise 10 meters to the forest above. A slender \n\
+waterfall careens away from the face of the rock high above and showers\n\
+the gravel floor with sparkling raindrops.** The canyon continues -\n\
+and -.\n" },
+ { "You are on the front porch of the cottage.",
+ 190, 103, 0, 0, 0, 0, 0, 0,
+"Several giggling native girls came running down the steps as you approached\n\
+and headed on down the road. On the fern rimmed porch is a small table with\n\
+matching white wrought iron chairs cushioned with red velvet. The front\n\
+door leads -. The lawn and fountain are +.**\n" },
+ { "You are in a palm grove.",
+ 103, 191, 192, 105, 88, 0, 0, 0,
+"****\n" },
+ { "You are on a dirt road.",
+ 193, 192, 245, 103, 88, 0, 0, 0,
+"There is a large village +. The road cleaves a coconut plantation +.\n\
+A small dirt road goes -, and a drive way peals off +.\n" },
+ { "You are in a field of small shrubs.",
+ 184, 186, 103, 187, 88, 0, 0, 0,
+"**Pine and other coniferous saplings have been planted here. The rich brown\n\
+soil is well tilled and watered. Across a large lawn, there is a small\n\
+cottage +. I can feel a delicious sea breeze blowing from +.\n" },
+ { "The beach is pretty rocky here.",
+ 194, 105, 195, 0, 96, 0, 0, 0,
+"Dangerous surf and lava outcroppings make this a treacherous strand.\n\
+The beach is nicer* +.**\n" },
+ { "The beach is almost 10 meters wide here.",
+ 105, 183, 196, 0, 99, 0, 0, 0,
+"The sand has become more coarse and the beach steeper.* It gets \n\
+worse +.**\n" },
+ { "You are in the gardens.",
+ 195, 196, 197, 105, 99, 0, 0, 0,
+"Lush green lawns studded with palms and benches stretch as far as the eye\n\
+can see.** A path leads -. Stone steps lead down to the beach +.\n" },
+ { "You are on the coast road.",
+ 198, 106, 163, 199, 73, 0, 0, 0,
+"The forest is dense on either side and conceals the road from anyone\n\
+approaching it.** The road continues - and -.\n" },
+ { "You are in the forest.",
+ 116, 107, 91, 106, 73, 0, 0, 0,
+"There are trees and ferns all around.****\n" },
+ { "You are in the forest.",
+ 199, 108, 106, 146, 73, 0, 0, 0,
+"There are trees and ferns all around.****\n" },
+ { "You are in a copse.",
+ 142, 107, 145, 80, 0, 0, 0, 0,
+"This is a secret hidden thicket only noticeable from the beach. Someone\n\
+has been digging here recently.****\n" },
+ { "You are at the tide pools.",
+ 91, 0, 114, 107, 79, 0, 0, 0,
+"These rocks and pools are the home for many sea anemones and crustaceans.\n\
+**The surf is very rough +. There is a nice beach +.\n" },
+ { "You are in the forest.",
+ 199, 108, 143, 0, 73, 0, 0, 0,
+"This is a shallow depression sheltered from the wind by a thick growth of \n\
+thorny shrubs. It looks like someone has camped here. There is a fire pit\n\
+with some dry sticks and grass nearby.* The beach is +.* The thorny\n\
+shrubs block the way -.\n" },
+ { "You are at the mouth of the lagoon.",
+ 200, 0, 108, 201, 74, 0, 0, 0,
+"The beach ends here where the coral reef rises to form a wide lagoon\n\
+bending inland. A path winds around the lagoon to the -.*\n\
+The beach continues on -. Only water lies +.\n" },
+ { "You are in a breadfruit grove.",
+ 202, 109, 203, 204, 77, 0, 0, 0,
+"The tall trees bend leisurely in the breeze, holding many round breadfruits\n\
+close to their large serrated leaves. There are coconut palms +,\n\
+*+, and +.\n" },
+ { "You are in a grove of mango trees.",
+ 203, 111, 205, 109, 77, 0, 0, 0,
+"The juicy yellow red fruits are nearly ripe on the trees here. There are\n\
+some coconut palms +. There are some vines +. There is a road +.*\n" },
+ { "You are in a grove of coconut palms.",
+ 204, 112, 109, 206, 77, 0, 0, 0,
+"All I can see around us are palm trees.****\n" },
+ { "You are in a coconut grove.",
+ 110, 207, 208, 209, 77, 0, 0, 0,
+"There are countless trees here.****\n" },
+ { "You are in a field of pineapple.",
+ 154, 208, 210, 110, 77, 0, 0, 0,
+"The sharp leaves are cutting me to ribbons. There is a road **+.\n\
+More pineapple +.\n" },
+ { "You are in a coconut grove.",
+ 112, 209, 110, 211, 77, 0, 0, 0,
+"There is a field of pineapple **+.*\n" },
+ { "You are on the edge of a kiwi and pineapple field.",
+ 111, 152, 155, 110, 77, 0, 0, 0,
+"An irrigation ditch separates the two fields here. There is a road **+.*\n" },
+ { "This is a dirt road.",
+ 205, 210, 212, 111, 77, 0, 0, 0,
+"The road runs - and - here.**\n" },
+ { "You are in a palm grove.",
+ 206, 211, 112, 213, 77, 0, 0, 0,
+"There are palm trees all around us.****\n" },
+ { "You are on the edge of a small clearing.",
+ 157, 113, 157, 157, 79, 0, 0, 0,
+"The ground is rather marshy here and darting in and out of the many tussocks\n\
+is a flock of wild chicken like fowl.****\n" },
+ { "You are in the woods.",
+ 158, 115, 215, 113, 79, 0, 0, 0,
+"You have walked a long way and found only trees. ****\n" },
+ { "You are walking along the shore.",
+ 115, 0, 214, 114, 86, 0, 0, 0,
+"You are now about 10 meters above the surf on a gently rising cliffside.**\n\
+The land rises +. There is a beach far +.\n" },
+ { "You are just inside the entrance to the sea cave.",
+ 246, 114, 0, 0, 114, 1, 0, 0,
+"The sound of water dripping in darkness and the roar of the ocean just outside\n\
+create a very unwelcoming atmosphere inside this cave. Only on rare occasions\n\
+such as this is it possible to enter the forbidden catacombs... The cave\n\
+continues -.***\n" },
+ { "You are in a secret nook beside the road.",
+ 115, 159, 162, 91, 79, 0, 0, 0,
+"Hidden from all but the most stalwart snoopers are some old clothes, empty\n\
+beer cans and a trash baggie full of used Huggies and ordure. Lets get\n\
+back to the road +.***\n" },
+ { "You are on the coast road.",
+ 215, 214, 0, 115, 86, 0, 0, 0,
+"The road turns abruptly - here, avoiding the cliffs near the shore\n\
++ and +.*\n" },
+ { "You are on a dirt road.",
+ 216, 116, 113, 141, 79, 0, 0, 0,
+"The roadside is choked with broad leaved plants fighting for every breath of\n\
+sunshine. The palm trees are taller than at the shore yet bend over the road \n\
+forming a canopy. The road continues *- and *-.\n" },
+ { "You have discovered a hidden thicket near the road.",
+ 163, 142, 116, 106, 73, 0, 0, 0,
+"Stuffed into a little bundle here is a bloody silken robe and many beer cans.\n\
+*Some droplets of blood and a major spill sparkle farther +.\n\
+The road is +.*\n" },
+ { "You are in the living room.",
+ 0, 117, 217, 218, 0, 0, 0, 0,
+"A decorative entry with fresh flowers and wall to wall carpeting leads into\n\
+the living room here where a couch and two chairs converse with an end table.\n\
+*The exit is +.* The bedroom is +.\n" },
+ { "You are at the lagoon.",
+ 118, 0, 167, 168, 81, 0, 0, 0,
+"There are several outrigger canoes pulled up on a small beach here and a\n\
+catch of colorful fish is drying in the sun. There are paths leading \n\
+off -*, -, and -.\n" },
+ { "You are at the lagoon.",
+ 118, 0, 170, 166, 81, 0, 0, 0,
+"This is a grassy little spot near the water. A sightly native girl is frolicing\n\
+in the water close to shore here.** The path continues - and -. \n" },
+ { "You are at the lagoon.",
+ 118, 0, 166, 172, 81, 0, 0, 0,
+"The path meanders through tussocks of grass, ferns, and thorny bushes here\n\
+and continues on **- and -.\n" },
+ { "You are in the woods.",
+ 219, 119, 220, 92, 81, 0, 0, 0,
+"There are plenty of ferns and thorny bushes here! ****\n" },
+ { "You are on a dirt road.",
+ 220, 167, 199, 119, 74, 0, 0, 0,
+"The road winds rather close to a large lagoon here and many sedges and tall\n\
+grasses line the shoulder *+. The road continues - and -.\n" },
+ { "You are in the woods beside the road.",
+ 221, 120, 92, 222, 81, 0, 0, 0,
+"The forest grows darker +. The road is +.**\n" },
+ { "The road crosses the lagoon here.",
+ 222, 0, 120, 174, 81, 0, 0, 0,
+"Coursing through the trees, the road at this point bridges a watery finger\n\
+of the lagoon.* The water is +. The road continues - and -.\n" },
+ { "You are in a coconut palm grove.",
+ 223, 121, 224, 225, 82, 0, 0, 0,
+"The tall palms are planted about 30 feet apart with a hardy deep green grass\n\
+filling the spaces in between. There are tire tracks through the grass. The\n\
+grove continues -. There is a road +.**\n" },
+ { "You are walking along a dirt road.",
+ 224, 176, 172, 121, 82, 0, 0, 0,
+"You are nearing the lagoon.** The road continues - and -.\n" },
+ { "You are on a dirt road.",
+ 225, 177, 121, 226, 82, 0, 0, 0,
+"The road turns abruptly - here, entering a grove of palm trees.* The road\n\
+also continues - toward the lagoon.*\n" },
+ { "You are on a trail running around the lagoon.",
+ 172, 0, 0, 122, 82, 0, 0, 0,
+"The dark waters brush the trail here and the path crosses a bridge +.\n\
+There is deep water + and +. The trail continues -.\n" },
+ { "This is the mouth of the lagoon.",
+ 175, 0, 122, 227, 82, 0, 0, 0,
+"The coral reef wraps around a natural bay here to create a wide lagoon which\n\
+winds tortuously inland.** A trail goes around the lagoon +. The beach\n\
+is +.\n" },
+ { "You are in a dry stream bed.",
+ 0, 125, 0, 0, 84, 0, 0, 0,
+"The dry wash drains over a tall precipice here into a turbid morass below. The\n\
+most noisome stench imaginable is wafting up to defile our nostrils. Above,\n\
+the lurid sun glows brown through a strange mist.* The only direction \n\
+I'm going is -.**\n" },
+ { "You are on a dirt path along the wash.",
+ 0, 128, 125, 228, 84, 0, 0, 0,
+"This path looks more like a deer trail. It scampers away ***+.\n" },
+ { "The thermal pools flow into a stream here.",
+ 127, 0, 229, 126, 84, 0, 0, 0,
+"The gurgling hot waters pour over boulders into a swiftly flowing\n\
+stream **+. The pools are +.\n" },
+ { "You are at the entrance to a cave.",
+ 128, 230, 126, 0, 84, 0, 0, 0,
+"A tall narrow fissure in the rock cliffs here has become a well traveled\n\
+passage way. A hoof beaten dirt path leads directly into it. A curl of\n\
+steam is trailing from a corner of the fissure's gaping mouth. The path\n\
+leads - and -. The pools are +.*\n" },
+ { "You are in the woods.",
+ 182, 229, 182, 127, 84, 0, 0, 0,
+"Wild berry bushes plump with fruit and thorns tangle your every effort to\n\
+proceed.* The sound of rushing water is +.**\n" },
+ { "You are walking along the beach.",
+ 139, 129, 184, 0, 99, 0, 0, 0,
+"Some dunes here progress inland and make it impossible to get very far in that\n\
+direction. The beach continues - and -.* The ocean is +.\n" },
+ { "You are in the dunes.",
+ 183, 101, 184, 129, 87, 0, 0, 0,
+"The endless rolling and pitching sand dunes are enough to make one very queasy!\n\
+The only way I'm going is ***+.\n" },
+ { "This is a lousy beach.",
+ 130, 0, 0, 0, 87, 0, 0, 0,
+"Volcanic and viciously sharp bitted grains of sand here bite like cold steel\n\
+into my tender feet. I refuse to continue on. Let's get out of here. The\n\
+beach is better +.***\n" },
+ { "You are in a field of sparse ferns.",
+ 131, 185, 187, 130, 87, 0, 0, 0,
+"The lava rock outcroppings here will support few plants. There is more \n\
+vegetation +. There is a nice beach +.* The ocean is +.\n" },
+ { "You are in the woods.",
+ 131, 131, 137, 131, 87, 0, 0, 0,
+"Young trees and tall shrubs grow densely together at this distance from the \n\
+shore.** The trees grow thicker +.*\n" },
+ { "The canyon is no wider than a foot here.",
+ 0, 0, 0, 132, 0, 0, 0, 0,
+"The freshet is gushing through the narrow trough, but the canyon has grown\n\
+too narrow to follow it any farther.*** I guess we'll have to go -.\n" },
+ { "You are in a narrow part of the canyon.",
+ 0, 0, 133, 232, 76, 0, 0, 0,
+"The two sheer sides are no more than a few meters apart here. There is a stone\n\
+door in the wall +. The gravelly floor runs with tiny rivulets seeping \n\
+from the ground itself.* The canyon continues - and -.\n" },
+ { "You are in the drawing room.",
+ 0, 134, 0, 0, 0, 0, 0, 0,
+"Exquisitely decorated with plants and antique furniture of superb\n\
+craftsmanship, the parlor reflects its owners impeccable taste. The tropical\n\
+sun is streaming in through open shutters *+. There doesn't seem \n\
+to be anybody around. A large immaculate oaken desk is visible in the\n\
+study and it even has a old fashioned telephone to complete the decor.**\n" },
+ { "You are in a palm grove.",
+ 135, 191, 233, 191, 88, 0, 0, 0,
+"Grassy rows of palms stretch as far as I can see.** There is a road +.*\n" },
+ { "You are on a dirt road.",
+ 136, 233, 234, 135, 88, 0, 0, 0,
+"The road winds through a coconut palm grove here. It continues on - \n\
+and -.**\n" },
+ { "The road leads to several large buildings here.",
+ 235, 136, 236, 237, 88, 0, 0, 0,
+"There is a clubhouse +,* a large barn and stable +, and a garage of \n\
+similar construct to the barn +.\n" },
+ { "This part of the beach is impassable.",
+ 0, 138, 0, 0, 96, 0, 0, 0,
+"The huge rocks and thunderous surf here would pound our frail bodies to pulp\n\
+in an instant.* The only direction I'm going is -.**\n" },
+ { "You are in the gardens.",
+ 195, 140, 197, 138, 96, 0, 0, 0,
+"So much green grass is a pleasure to the eyes.****\n" },
+ { "You are in the gardens.",
+ 140, 183, 197, 139, 99, 0, 0, 0,
+"Beautiful flowers and shrubs surround a little goldfish pond.****\n" },
+ { "You are on a stone walk in the garden.",
+ 195, 196, 238, 140, 99, 0, 0, 0,
+"The walk leads to a road **+.*\n" },
+ { "You are in the forest near the road.",
+ 198, 141, 216, 198, 73, 0, 0, 0,
+"There are many thorny bushes here!****\n" },
+ { "You are at a fork in the road.",
+ 239, 146, 141, 170, 73, 0, 0, 0,
+"Two roads come together in the forest here. One runs -,* the other \n\
+runs - and -.\n" },
+ { "You are on a dirt path around the lagoon.",
+ 170, 147, 146, 0, 74, 0, 0, 0,
+"The still waters reflect bending palms and a cloudless sky. It looks like\n\
+the path runs into a clearing +. The path continues -.**\n" },
+ { "You are drowning in the lagoon.",
+ 201, 201, 147, 201, 74, 0, 0, 0,
+"I suggest you get out before you become waterlogged.****\n" },
+ { "You are in a coconut palm grove.",
+ 202, 148, 203, 204, 77, 0, 0, 0,
+"****\n" },
+ { "You are in a palm grove.",
+ 202, 149, 205, 148, 77, 0, 0, 0,
+"****\n" },
+ { "You are in a palm grove.",
+ 202, 150, 148, 206, 77, 0, 0, 0,
+"****\n" },
+ { "You are on a dirt road.",
+ 203, 155, 212, 149, 77, 0, 0, 0,
+"*This road ends here at a palm grove but continues on - for quite\n\
+some way.**\n" },
+ { "You are in a coconut palm grove.",
+ 204, 156, 150, 213, 77, 0, 0, 0,
+"****\n" },
+ { "You are in a coconut grove.",
+ 151, 219, 208, 209, 77, 0, 0, 0,
+"*The grove ends +.**\n" },
+ { "You are in a coconut grove.",
+ 152, 207, 239, 151, 77, 0, 0, 0,
+"**There is a dirt road +.*\n" },
+ { "You are in a coconut grove.",
+ 153, 207, 151, 211, 77, 0, 0, 0,
+"****\n" },
+ { "This is a dirt road.",
+ 205, 239, 212, 154, 77, 0, 0, 0,
+"The road continues - and -.**\n" },
+ { "You are in a coconut grove.",
+ 153, 209, 153, 213, 77, 0, 0, 0,
+"****\n" },
+ { "You are in the woods near the road.",
+ 205, 210, 212, 155, 77, 0, 0, 0,
+"There are many thorny bushes here!****\n" },
+ { "You are in a coconut grove.",
+ 213, 213, 156, 234, 88, 0, 0, 0,
+"***The grove ends in a clearing +.\n" },
+ { "You are walking along some high cliffs.",
+ 162, 0, 0, 159, 86, 0, 0, 0,
+"The island bends sharply + here with high cliffs -\n\
+and -. The cliffs are lower +.\n" },
+ { "You are at the coast road turn around.",
+ 0, 162, 0, 158, 90, 0, 0, 0,
+"The coast road ends here in a lookout with a view of 100 kilometers of blue\n\
+sea and 100 meters of rugged cliff. Far below the waves crash against rocks.\n\
+****\n" },
+ { "You are in the woods near the road.",
+ 216, 163, 216, 198, 79, 0, 257, 0,
+"These thorny bushes are killing me.****\n" },
+ { "You are in the kitchen.",
+ 0, 0, 0, 165, 0, 0, 0, 0,
+"A small gas stove and a refrigerator are all the only appliances here. The\n\
+gas oven has been left on and the whole room is reeking with natural gas.\n\
+One spark from a match and.... The door out is ***+.\n" },
+ { "You are in the bedroom.",
+ 0, 0, 165, 0, 0, 0, 0, 0,
+"A soft feather comforter on top of layers of Answer blankets make this a very\n\
+luxurious place to sleep indeed. There are also some end tables and a dresser\n\
+here.** The living room is +.*\n" },
+ { "You are in the woods.",
+ 207, 169, 220, 221, 81, 0, 0, 0,
+"There seems to be a clearing +.***\n" },
+ { "You are in the woods near the road.",
+ 219, 170, 239, 169, 81, 0, 0, 0,
+"*As far as I can tell, there are two roads + and +.*\n" },
+ { "You are in the woods.",
+ 207, 171, 219, 222, 81, 0, 0, 0,
+"The forest is clearer +.***\n" },
+ { "You are on the lagoon's inland finger.",
+ 0, 172, 171, 172, 81, 0, 0, 0,
+"It is impossible to follow the lagoon any farther inland because of sharp\n\
+and very painful sedges.* The road is +.**\n" },
+ { "You are in a grassy coconut grove.",
+ 240, 173, 224, 241, 82, 0, 0, 0,
+"The tall palms provide a perfect canopy for the lush green grass.***\n\
+There is a road +.\n" },
+ { "You are near the lagoon's inland finger.",
+ 0, 174, 0, 173, 82, 0, 0, 0,
+"Very sharp sedges make it impossible to follow the lagoon any farther inland.\n\
+*There is a road +.**\n" },
+ { "You are on a dirt road.",
+ 241, 175, 173, 226, 82, 0, 0, 0,
+"The road winds through a coconut grove here and continues - and -.**\n" },
+ { "You are in the woods near the road.",
+ 226, 226, 175, 226, 82, 0, 0, 0,
+"**The road is +.*\n" },
+ { "This is a beach?",
+ 227, 227, 177, 0, 82, 0, 0, 0,
+"Hard jagged rocks that pierce with every footstep hardly comprise a beach.**\n\
+Let's go -.*\n" },
+ { "The trail is lost in the woods here.",
+ 241, 241, 179, 241, 84, 0, 0, 0,
+"I suppose the animals that use this trail all depart in different directions\n\
+when they get this far into the woods.** The trail goes -.*\n" },
+ { "You are on the bank of a stream.",
+ 182, 0, 242, 180, 84, 0, 0, 0,
+"The stream falls over several small boulders here and continues on **-.*\n" },
+ { "You are just inside the cave.",
+ 181, 267, 0, 0, 0, 0, 0, 0,
+"A steamy hot breath is belching from the depths of the earth within.* The\n\
+cave continues -.**\n" },
+ { "You are just inside the cave entrance.",
+ 274, 0, 0, 0, 0, 0, 0, 0,
+"The air is hot and sticky inside. The cave continues -. There is a \n\
+stone door in the wall +. A wooden sign in the dust reads in old elven\n\
+runes, \"GSRF KDIRE NLVEMP!\".**\n" },
+ { "You are at the edge of a huge chasm.",
+ 0, 0, 189, 0, 76, 0, 0, 0,
+"Several hundred feet down I can see the glimmer of placid water. The\n\
+rivulets drain over the edge and trickle down into the depths. It is \n\
+impossible to climb down without a rope.** The canyon continues -.*\n" },
+ { "You are on a dirt road.",
+ 192, 241, 240, 191, 88, 0, 0, 0,
+"The road winds through a coconut grove here. The road continues on -\n\
+and -.**\n" },
+ { "You are in a coconut palm grove near the road.",
+ 193, 233, 213, 192, 88, 0, 0, 0,
+"***The road is +.\n" },
+ { "You are at the clubhouse.",
+ 0, 193, 0, 0, 0, 0, 0, 0,
+"The clubhouse is built over the most inland part of the lagoon. Tropical\n\
+bananas and fragrant frangipani grow along the grassy shore. Walking across\n\
+the short wooden bridge, we enter. Along one wall is a bar with only a few\n\
+people seated at it. The restaurant and dance floor are closed off with\n\
+a 2 inch nylon rope. ****\n" },
+ { "You are in the stables.",
+ 0, 0, 0, 193, 0, 0, 0, 0,
+"Neighing horses snacking on hay and oats fill the stalls on both sides of\n\
+the barn. It is rather warm in here but that is not the most offensive\n\
+part. The old boards of the barn part just enough to let in dust laden\n\
+shafts of light. Flies swarm overhead and strafe the ground for dung.\n\
+My nose is beginning to itch. ****\n" },
+ { "You are in the old garage.",
+ 0, 0, 193, 0, 0, 0, 0, 0,
+"This is an old wooden building of the same vintage as the stables. Beneath\n\
+a sagging roof stand gardening tools and greasy rags. Parked in the center\n\
+is an underpowered Plymouth Volare' with a red and white striped golf cart\n\
+roof. ****\n" },
+ { "You are on a dirt road.",
+ 197, 197, 243, 197, 85, 0, 0, 0,
+"The road leads to a beautiful formal garden laced with stone walks and tropical\n\
+flowers and trees.** The road continues -. A walk leads -.\n" },
+ { "You are on a dirt road.",
+ 210, 199, 198, 220, 73, 0, 0, 0,
+"The road runs - and -.**\n" },
+ { "You are in a coconut grove near the road.",
+ 234, 223, 234, 233, 88, 0, 0, 0,
+"***The road is +.\n" },
+ { "You are on a dirt road.",
+ 233, 225, 223, 226, 82, 0, 0, 0,
+"The road continues - and -.**\n" },
+ { "The stream plummets over a cliff here.",
+ 182, 0, 0, 229, 84, 0, 0, 0,
+"Falling 10 agonizing meters into spray, only droplets of the stream are\n\
+left to dance off the floor below. I thought I saw a sparkle of gold\n\
+at the bottom of the falls, but now it is gone. There is no way down,\n\
+even with a strong rope. ****\n" },
+ { "You are on a dirt road.",
+ 0, 0, 244, 238, 85, 0, 0, 0,
+"**The road continues - and -.\n" },
+ { "You are on a dirt road.",
+ 0, 245, 0, 243, 88, 0, 0, 0,
+"*The road continues -* and -.\n" },
+ { "You are on a dirt road.",
+ 244, 234, 213, 136, 88, 0, 0, 0,
+"The road goes -* and *-.\n" },
+ { "You are in a low passage.",
+ 247, 160, 0, 0, 0, 0, 0, 0,
+"The passage is partially flooded here and it may be hazardous to proceed.\n\
+Water is surging from the tunnel and heading out to sea. Strange moaning\n\
+noises rise above the rushing of the water. They are as thin as a whispering\n\
+wind yet penetrate to my very soul. I think we have come too far...\n\
+The passage continues -.***\n" },
+ { "The walls are very close together here.",
+ 248, 0, 0, 0, 0, 0, 0, 0,
+"I can barely squeeze through the jagged opening. Slimy sea weeds provide\n\
+no footing at all. This tunnel seems to be an ancient lava tube. There is\n\
+a large room -.***\n" },
+ { "You are in the cathedral room.",
+ 249, 251, 249, 251, 0, 0, 0, 0,
+"Your light casts ghostly shadows on the walls but cannot pierce the \n\
+engulfing darkness overhead. The sound of water dripping echoes in the void.\n\
+*I can see no passages leading out of this room. We have definitely\n\
+come too far.*** \n" },
+ { "You are walking through a very round tunnel.",
+ 252, 0, 0, 0, 252, 1, 0, 0,
+"The round walls of this tunnel are amazingly smooth to the touch. A little\n\
+trickle of water flows down the center. The tunnel climbs steadily +.\n\
+The cave is beginning to flood again! Let's get out of here! ***\n" },
+ { "You are in the cathedral anteroom.",
+ 0, 0, 0, 248, 253, 1, 0, 0,
+"This small chamber with a flat stone floor is to one side of the cathedral \n\
+room. We appear to be at the bottom of a tall narrow shaft. There are many \n\
+puddles of water here. A staircase hewn from solid rock and black lava \n\
+leads up.*** The cathedral room is +.\n" },
+ { "You are in a wide chamber.",
+ 0, 0, 248, 254, 0, 0, 0, 0,
+"Water is sprinkling from the ceiling here. A shallow pool populated by a \n\
+myriad of blind white creatures sparkles in your light. Tiny shrimp and\n\
+crabs scurry away, frightened by the blinding rays.** The cave \n\
+continues - and -.\n" },
+ { "You are at the top of a sloping passage.",
+ 0, 0, 255, 256, 257, 1, 0, 0,
+"There is much algae growing here, both green and brown specimens. \n\
+Water from an underground sea surges and splashes against the slope of\n\
+the rock. The walls glisten with shiny minerals. High above, light\n\
+filters in through a narrow shaft.** A hallway here runs -\n\
+and -.\n" },
+ { "You are in an elaborately tiled room.",
+ 0, 0, 258, 0, 0, 0, 250, 0,
+"Large colorful tiles plate the floor and walls. The ceiling is a mosaic\n\
+of gems set in gold. Hopefully it is only our footsteps that are echoing in\n\
+this hollow chamber.** The room continues -. A stone staircase\n\
+leads down.*\n" },
+ { "You are at a dead end.",
+ 0, 0, 251, 0, 0, 0, 0, 0,
+"The walls here are alive with dark mussels. They click their shells menacingly\n\
+if we disturb them. ** The only exit is +.*\n" },
+ { "The tunnel is very low here.",
+ 0, 0, 259, 252, 0, 0, 0, 0,
+"I practically have to crawl on my knees to pass through this opening. The\n\
+air is stiflingly damp, but I can't hear any sounds of water dripping.**\n\
+The crawlspace continues -. The tunnel seems wider +.\n" },
+ { "This is the supply room.",
+ 0, 0, 252, 0, 0, 0, 0, 0,
+"Picks and shovels line the walls here, as well as hard hats, boxes of\n\
+dynamite, and a cartload of very high grade gold and silver ore.** \n\
+A tunnel leads off +.*\n" },
+ { "You have found a secret entrance to the catacombs.",
+ 0, 0, 0, 0, 216, 1, 252, 0,
+"I have a sickening feeling that we should not have entered the catacombs.\n\
+Below is a wet, seaweed covered floor. Above is a way out. ****\n" },
+ { "You are in the catacombs.",
+ 0, 0, 260, 253, 0, 0, 0, 0,
+"Ornate tombs and piles of treasure line the walls. Long spears with many\n\
+blades, fine swords and coats of mail, heaps of coins, jewelry, pottery, \n\
+and golden statues are tribute of past kings and queens.** The catacombs\n\
+continue - and -.\n" },
+ { "You are crawling on your stomach.",
+ 0, 0, 261, 255, 0, 0, 0, 0,
+"The passage is quite narrow and jagged, but the rock is no longer lava.\n\
+It appears to be a form of granite.** The crawlspace continues -, \n\
+but I would just as soon go -.\n" },
+ { "You are in the Sepulcher.",
+ 0, 0, 0, 258, 0, 0, 0, 0,
+"A single tomb is here. Encrusted with diamonds and opals, and secured with \n\
+straps of a very hard, untarnished silver, this tomb must be of a great king.\n\
+Vases overflowing with gold coins stand nearby. A line of verse on the wall\n\
+reads, \"Three he made and gave them to his daughters.\"****\n" },
+ { "The passage is wider here.",
+ 0, 0, 0, 259, 0, 0, 0, 0,
+"You are at the top of a flooded shaft. About a meter below the edge,\n\
+dark water rises and falls to the rhythm of the sea. A ladder goes\n\
+down into water here.*** A small crawlspace goes -.\n" },
+ { "You are at the bottom of a ladder.",
+ 0, 0, 0, 0, 261, 1, 263, 0,
+"This is a narrow platform to rest on before we continue either up or down this\n\
+rickety wooden ladder.****\n" },
+ { "You are standing in several inches of water.",
+ 264, 0, 265, 266, 262, 1, 0, 0,
+"This seems to be a working mine. Many different tunnels wander off following\n\
+glowing veins of precious metal. The floor is flooded here since we must\n\
+be nearly at sea level. A ladder leads up. ****\n" },
+ { "The tunnel here is blocked by broken rocks.",
+ 0, 263, 0, 0, 0, 0, 0, 0,
+"The way is blocked, but if you had some dynamite, we might be able to blast our\n\
+way through.* The passage goes -.**\n" },
+ { "The tunnel is too flooded to proceed.",
+ 0, 0, 0, 263, 0, 0, 0, 0,
+"Hidden shafts could swallow us if we tried to continue on down this tunnel.\n\
+The flooding is already up to my waist. Large crystals overhead shimmer\n\
+rainbows of reflected light.*** Let's go -.\n" },
+ { "The mine is less flooded here.",
+ 0, 0, 263, 0, 0, 0, 0, 0,
+"A meandering gold laden vein of quartz and blooming crystals of diamonds\n\
+and topaz burst from the walls of the cave. A passage goes -.***\n" },
+ { "You are inside the cave.",
+ 230, 268, 0, 0, 0, 0, 0, 0,
+"A hot steam swirls around our heads, and the walls are warm to the touch.\n\
+The trail winds + and +.**\n" },
+ { "You are in a rather large chamber.",
+ 267, 0, 0, 269, 0, 0, 269, 0,
+"Beds of ferns and palm leaves make several cozy nests along the walls. In the\n\
+center of the room is a throne of gold and silver which pulls out into a bed\n\
+of enormous size.*** A passageway leads down to the -.\n" },
+ { "You are walking along the edge of a huge abyss.",
+ 0, 0, 268, 0, 268, 1, 270, 0,
+"Steam is rising in great clouds from the immeasurable depths. A very narrow\n\
+trail winds down.** There is a tunnel +.*\n" },
+ { "You are on the edge of a huge abyss.",
+ 0, 0, 0, 0, 269, 1, 271, 0,
+"The trail winds farther down.****\n" },
+ { "You are winding your way along the abyss.",
+ 0, 0, 0, 0, 270, 1, 272, 0,
+"The trail continues up and down.****\n" },
+ { "You are on a wide shelf near the steamy abyss.",
+ 0, 273, 0, 0, 271, 1, 0, 0,
+"The stifling hot cave seems even hotter to me, staring down into this misty \n\
+abyss. A trail winds up.* A passageway leads -.**\n" },
+ { "You are in a wide tunnel leading to a fuming abyss.",
+ 272, 274, 0, 0, 0, 0, 0, 0,
+"The passageway winds through many beautiful formations of crystals and\n\
+sparkling minerals. The tunnel continues - and -.**\n" },
+ { "You are in a tunnel.",
+ 273, 231, 0, 0, 0, 0, 0, 0,
+"It is very warm in here. The smell of steam and hot rocks permeates the place.\n\
+The cave continues - and -.**\n" },
+ { "You are at the bottom of a pit.",
+ 0, 0, 0, 0, 232, 0, 0, 0,
+"I can see daylight far up at the mouth of the pit. A cool draft wafts down.\n\
+There doesn't seem to be any way out, and I don't remember how we came in.\n\
+If you had a rope it might be possible to climb out. ****\n" },
+};
diff --git a/battlestar/dayobjs.c b/battlestar/dayobjs.c
new file mode 100644
index 00000000..9e6617b4
--- /dev/null
+++ b/battlestar/dayobjs.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dayobjs.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+struct objs dayobjs[] = {
+ { 236, HORSE },
+ { 237, CAR },
+ { 275, POT },
+ { 275, BAR },
+ { 275, BLOCK },
+ { 260, COINS },
+ { 266, DARK },
+ { 235, TIMER },
+ { 51, 51 },
+ { 59, 51 },
+ { 48, 51 },
+ { 66, 52 },
+ { 65, 52 },
+ { 19, BOMB },
+ { 167, NATIVE },
+ { 21, KNIFE },
+ { 30, KNIFE },
+ { 30, CLEAVER },
+ { 260, SWORD },
+ { 70, LAND },
+ { 71, LAND },
+ { 72, LAND },
+ { 73, LAND },
+ { 74, LAND },
+ { 75, LAND },
+ { 76, LAND },
+ { 77, LAND },
+ { 78, LAND },
+ { 79, LAND },
+ { 81, LAND },
+ { 82, LAND },
+ { 83, LAND },
+ { 84, LAND },
+ { 85, LAND },
+ { 86, LAND },
+ { 87, LAND },
+ { 88, LAND },
+ { 90, LAND },
+ { 95, LAND },
+ { 96, LAND },
+ { 97, LAND },
+ { 99, LAND },
+ { 100, LAND },
+ { 104, LAND },
+ { 172, WOODSMAN },
+ { 172, DEADWOOD },
+ { 172, MALLET },
+ { 146, ELF },
+ { 146, HALBERD },
+ { 146, SHIELD },
+ { 190, TWO_HANDED },
+ { 190, POTION },
+ { 142, BROAD },
+ { 258, MAIL },
+ { 258, HELM },
+ { 21, MAID },
+ { 7, VIPER },
+ { 216, SHOES },
+ { 64, CYLON },
+ { 36, CYLON },
+ { 49, CYLON },
+ { 8, ROBE },
+ { 13, AMULET },
+ { 20, LASER },
+ { 126, BATHGOD },
+ { 26, GRENADE },
+ { 256, GRENADE },
+ { 237, CHAIN },
+ { 237, COMPASS },
+ { 218, LEVIS },
+ { 164, MACE },
+ { 137, SHOVEL },
+ { 11, COINS },
+ { 24, MATCHES },
+ { 235, MATCHES },
+ { 93, MAN },
+ { 109, PAPAYAS },
+ { 110, PINEAPPLE },
+ { 152, PINEAPPLE },
+ { 154, PINEAPPLE },
+ { 111, KIWI },
+ { 149, MANGO },
+ { 112, COCONUTS },
+ { 150, COCONUTS },
+ { 151, COCONUTS },
+ { 153, COCONUTS },
+ { 192, COCONUTS },
+ { 204, COCONUTS },
+ { 207, COCONUTS },
+ { 209, COCONUTS },
+ { 213, COCONUTS },
+ { 240, COCONUTS },
+ { 218, RING },
+ { 130, BRACELET },
+ { 93, GIRL },
+ { 268, LAMPON },
+ 0
+};
diff --git a/battlestar/externs.h b/battlestar/externs.h
new file mode 100644
index 00000000..d097901b
--- /dev/null
+++ b/battlestar/externs.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)externs.h 5.4 (Berkeley) 6/1/90
+ */
+
+#include <sys/signal.h>
+#include <stdio.h>
+
+#define BITS (8 * sizeof (int))
+
+#define OUTSIDE (position > 68 && position < 246 && position != 218)
+#define rnd(x) (rand() % (x))
+#define max(a,b) ((a) < (b) ? (b) : (a))
+#define testbit(array, index) (array[index/BITS] & (1 << (index % BITS)))
+#define setbit(array, index) (array[index/BITS] |= (1 << (index % BITS)))
+#define clearbit(array, index) (array[index/BITS] &= ~(1 << (index % BITS)))
+
+ /* well known rooms */
+#define FINAL 275
+#define GARDEN 197
+#define POOLS 126
+#define DOCK 93
+
+ /* word types */
+#define VERB 0
+#define OBJECT 1
+#define NOUNS 2
+#define PREPS 3
+#define ADJS 4
+#define CONJ 5
+
+ /* words numbers */
+#define KNIFE 0
+#define SWORD 1
+#define LAND 2
+#define WOODSMAN 3
+#define TWO_HANDED 4
+#define CLEAVER 5
+#define BROAD 6
+#define MAIL 7
+#define HELM 8
+#define SHIELD 9
+#define MAID 10
+#define BODY 10
+#define VIPER 11
+#define LAMPON 12
+#define SHOES 13
+#define CYLON 14
+#define PAJAMAS 15
+#define ROBE 16
+#define AMULET 17
+#define MEDALION 18
+#define TALISMAN 19
+#define DEADWOOD 20
+#define MALLET 21
+#define LASER 22
+#define BATHGOD 23
+#define NORMGOD 24
+#define GRENADE 25
+#define CHAIN 26
+#define ROPE 27
+#define LEVIS 28
+#define MACE 29
+#define SHOVEL 30
+#define HALBERD 31
+#define COMPASS 32
+#define CRASH 33
+#define ELF 34
+#define FOOT 35
+#define COINS 36
+#define MATCHES 37
+#define MAN 38
+#define PAPAYAS 39
+#define PINEAPPLE 40
+#define KIWI 41
+#define COCONUTS 42
+#define MANGO 43
+#define RING 44
+#define POTION 45
+#define BRACELET 46
+#define GIRL 47
+#define GIRLTALK 48
+#define DARK 49
+#define TIMER 50
+#define CHAR 53
+#define BOMB 54
+#define DEADGOD 55
+#define DEADTIME 56
+#define DEADNATIVE 57
+#define NATIVE 58
+#define HORSE 59
+#define CAR 60
+#define POT 61
+#define BAR 62
+#define BLOCK 63
+#define NUMOFOBJECTS 64
+ /* non-objects below */
+#define UP 1000
+#define DOWN 1001
+#define AHEAD 1002
+#define BACK 1003
+#define RIGHT 1004
+#define LEFT 1005
+#define TAKE 1006
+#define USE 1007
+#define LOOK 1008
+#define QUIT 1009
+#define NORTH 1010
+#define SOUTH 1011
+#define EAST 1012
+#define WEST 1013
+#define SU 1014
+#define DROP 1015
+#define TAKEOFF 1016
+#define DRAW 1017
+#define PUTON 1018
+#define WEARIT 1019
+#define PUT 1020
+#define INVEN 1021
+#define EVERYTHING 1022
+#define AND 1023
+#define KILL 1024
+#define RAVAGE 1025
+#define UNDRESS 1026
+#define THROW 1027
+#define LAUNCH 1028
+#define LANDIT 1029
+#define LIGHT 1030
+#define FOLLOW 1031
+#define KISS 1032
+#define LOVE 1033
+#define GIVE 1034
+#define SMITE 1035
+#define SHOOT 1036
+#define ON 1037
+#define OFF 1038
+#define TIME 1039
+#define SLEEP 1040
+#define DIG 1041
+#define EAT 1042
+#define SWIM 1043
+#define DRINK 1044
+#define DOOR 1045
+#define SAVE 1046
+#define RIDE 1047
+#define DRIVE 1048
+#define SCORE 1049
+#define BURY 1050
+#define JUMP 1051
+#define KICK 1052
+
+ /* injuries */
+#define ARM 6 /* broken arm */
+#define RIBS 7 /* broken ribs */
+#define SPINE 9 /* broken back */
+#define SKULL 11 /* fractured skull */
+#define INCISE 10 /* deep incisions */
+#define NECK 12 /* broken NECK */
+#define NUMOFINJURIES 13
+
+ /* notes */
+#define CANTLAUNCH 0
+#define LAUNCHED 1
+#define CANTSEE 2
+#define CANTMOVE 3
+#define JINXED 4
+#define DUG 5
+#define NUMOFNOTES 6
+
+ /* fundamental constants */
+#define NUMOFROOMS 275
+#define NUMOFWORDS ((NUMOFOBJECTS + BITS - 1) / BITS)
+#define LINELENGTH 81
+
+#define TODAY 0
+#define TONIGHT 1
+#define CYCLE 100
+
+ /* initial variable values */
+#define TANKFULL 250
+#define TORPEDOES 10
+#define MAXWEIGHT 60
+#define MAXCUMBER 10
+
+struct room {
+ char *name;
+ int link[8];
+#define north link[0]
+#define south link[1]
+#define east link[2]
+#define west link[3]
+#define up link[4]
+#define access link[5]
+#define down link[6]
+#define flyhere link[7]
+ char *desc;
+ unsigned int objects[NUMOFWORDS];
+};
+struct room dayfile[];
+struct room nightfile[];
+struct room *location;
+
+ /* object characteristics */
+char *objdes[NUMOFOBJECTS];
+char *objsht[NUMOFOBJECTS];
+char *ouch[NUMOFINJURIES];
+int objwt[NUMOFOBJECTS];
+int objcumber[NUMOFOBJECTS];
+
+ /* current input line */
+#define NWORD 20 /* words per line */
+char words[NWORD][15];
+int wordvalue[NWORD];
+int wordtype[NWORD];
+int wordcount, wordnumber;
+
+char *truedirec(), *rate();
+char *getcom(), *getword();
+
+ /* state of the game */
+int time;
+int position;
+int direction;
+int left, right, ahead, back;
+int clock, fuel, torps;
+int carrying, encumber;
+int rythmn;
+int followfight;
+int ate;
+int snooze;
+int meetgirl;
+int followgod;
+int godready;
+int win;
+int wintime;
+int wiz;
+int tempwiz;
+int matchlight, matchcount;
+int loved;
+int pleasure, power, ego;
+int WEIGHT;
+int CUMBER;
+int notes[NUMOFNOTES];
+unsigned int inven[NUMOFWORDS];
+unsigned int wear[NUMOFWORDS];
+char beenthere[NUMOFROOMS+1];
+char injuries[NUMOFINJURIES];
+
+char uname[9];
+
+struct wlist {
+ char *string;
+ int value, article;
+ struct wlist *next;
+};
+#define HASHSIZE 256
+#define HASHMUL 81
+#define HASHMASK (HASHSIZE - 1)
+struct wlist *hashtab[HASHSIZE];
+struct wlist wlist[];
+
+struct objs {
+ short room;
+ short obj;
+};
+struct objs dayobjs[];
+struct objs nightobjs[];
diff --git a/battlestar/fly.c b/battlestar/fly.c
new file mode 100644
index 00000000..e9b2db20
--- /dev/null
+++ b/battlestar/fly.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)fly.c 5.6 (Berkeley) 3/4/91";
+#endif /* not lint */
+
+#include "externs.h"
+#undef UP
+#include <curses.h>
+
+#define abs(a) ((a) < 0 ? -(a) : (a))
+#define MIDR (LINES/2 - 1)
+#define MIDC (COLS/2 - 1)
+
+int row, column;
+int dr = 0, dc = 0;
+char destroyed;
+int clock = 120; /* time for all the flights in the game */
+char cross = 0;
+sig_t oldsig;
+
+void
+succumb()
+{
+ if (oldsig == SIG_DFL) {
+ endfly();
+ exit(1);
+ }
+ if (oldsig != SIG_IGN) {
+ endfly();
+ (*oldsig)(SIGINT);
+ }
+}
+
+visual()
+{
+ void moveenemy();
+
+ destroyed = 0;
+ savetty();
+ if(initscr() == ERR){
+ puts("Whoops! No more memory...");
+ return(0);
+ }
+ oldsig = signal(SIGINT, succumb);
+ crmode();
+ noecho();
+ screen();
+ row = rnd(LINES-3) + 1;
+ column = rnd(COLS-2) + 1;
+ moveenemy();
+ for (;;) {
+ switch(getchar()){
+
+ case 'h':
+ case 'r':
+ dc = -1;
+ fuel--;
+ break;
+
+ case 'H':
+ case 'R':
+ dc = -5;
+ fuel -= 10;
+ break;
+
+ case 'l':
+ dc = 1;
+ fuel--;
+ break;
+
+ case 'L':
+ dc = 5;
+ fuel -= 10;
+ break;
+
+ case 'j':
+ case 'u':
+ dr = 1;
+ fuel--;
+ break;
+
+ case 'J':
+ case 'U':
+ dr = 5;
+ fuel -= 10;
+ break;
+
+ case 'k':
+ case 'd':
+ dr = -1;
+ fuel--;
+ break;
+
+ case 'K':
+ case 'D':
+ dr = -5;
+ fuel -= 10;
+ break;
+
+ case '+':
+ if (cross){
+ cross = 0;
+ notarget();
+ }
+ else
+ cross = 1;
+ break;
+
+ case ' ':
+ case 'f':
+ if (torps){
+ torps -= 2;
+ blast();
+ if (row == MIDR && column - MIDC < 2 && MIDC - column < 2){
+ destroyed = 1;
+ alarm(0);
+ }
+ }
+ else
+ mvaddstr(0,0,"*** Out of torpedoes. ***");
+ break;
+
+ case 'q':
+ endfly();
+ return(0);
+
+ default:
+ mvaddstr(0,26,"Commands = r,R,l,L,u,U,d,D,f,+,q");
+ continue;
+
+ case EOF:
+ break;
+ }
+ if (destroyed){
+ endfly();
+ return(1);
+ }
+ if (clock <= 0){
+ endfly();
+ die();
+ }
+ }
+}
+
+screen()
+{
+ register int r,c,n;
+ int i;
+
+ clear();
+ i = rnd(100);
+ for (n=0; n < i; n++){
+ r = rnd(LINES-3) + 1;
+ c = rnd(COLS);
+ mvaddch(r, c, '.');
+ }
+ mvaddstr(LINES-1-1,21,"TORPEDOES FUEL TIME");
+ refresh();
+}
+
+target()
+{
+ register int n;
+
+ move(MIDR,MIDC-10);
+ addstr("------- + -------");
+ for (n = MIDR-4; n < MIDR-1; n++){
+ mvaddch(n,MIDC,'|');
+ mvaddch(n+6,MIDC,'|');
+ }
+}
+
+notarget()
+{
+ register int n;
+
+ move(MIDR,MIDC-10);
+ addstr(" ");
+ for (n = MIDR-4; n < MIDR-1; n++){
+ mvaddch(n,MIDC,' ');
+ mvaddch(n+6,MIDC,' ');
+ }
+}
+
+blast()
+{
+ register int n;
+
+ alarm(0);
+ move(LINES-1, 24);
+ printw("%3d", torps);
+ for(n = LINES-1-2; n >= MIDR + 1; n--){
+ mvaddch(n, MIDC+MIDR-n, '/');
+ mvaddch(n, MIDC-MIDR+n, '\\');
+ refresh();
+ }
+ mvaddch(MIDR,MIDC,'*');
+ for(n = LINES-1-2; n >= MIDR + 1; n--){
+ mvaddch(n, MIDC+MIDR-n, ' ');
+ mvaddch(n, MIDC-MIDR+n, ' ');
+ refresh();
+ }
+ alarm(1);
+}
+
+void
+moveenemy()
+{
+ double d;
+ int oldr, oldc;
+
+ oldr = row;
+ oldc = column;
+ if (fuel > 0){
+ if (row + dr <= LINES-3 && row + dr > 0)
+ row += dr;
+ if (column + dc < COLS-1 && column + dc > 0)
+ column += dc;
+ } else if (fuel < 0){
+ fuel = 0;
+ mvaddstr(0,60,"*** Out of fuel ***");
+ }
+ d = (double) ((row - MIDR)*(row - MIDR) + (column - MIDC)*(column - MIDC));
+ if (d < 16){
+ row += (rnd(9) - 4) % (4 - abs(row - MIDR));
+ column += (rnd(9) - 4) % (4 - abs(column - MIDC));
+ }
+ clock--;
+ mvaddstr(oldr, oldc - 1, " ");
+ if (cross)
+ target();
+ mvaddstr(row, column - 1, "/-\\");
+ move(LINES-1, 24);
+ printw("%3d", torps);
+ move(LINES-1, 42);
+ printw("%3d", fuel);
+ move(LINES-1, 57);
+ printw("%3d", clock);
+ refresh();
+ signal(SIGALRM, moveenemy);
+ alarm(1);
+}
+
+endfly()
+{
+ alarm(0);
+ signal(SIGALRM, SIG_DFL);
+ mvcur(0,COLS-1,LINES-1,0);
+ endwin();
+ signal(SIGTSTP, SIG_DFL);
+ signal(SIGINT, oldsig);
+}
diff --git a/battlestar/getcom.c b/battlestar/getcom.c
new file mode 100644
index 00000000..dafec417
--- /dev/null
+++ b/battlestar/getcom.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getcom.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <ctype.h>
+
+char *
+getcom(buf, size, prompt, error)
+ char *buf;
+ int size;
+ char *prompt, *error;
+{
+ for (;;) {
+ fputs(prompt, stdout);
+ if (fgets(buf, size, stdin) == 0) {
+ clearerr(stdin);
+ continue;
+ }
+ while (isspace(*buf))
+ buf++;
+ if (*buf)
+ break;
+ if (error)
+ puts(error);
+ }
+ return (buf);
+}
+
+
+/*
+ * shifts to UPPERCASE if flag > 0, lowercase if flag < 0,
+ * and leaves it unchanged if flag = 0
+ */
+char *
+getword(buf1, buf2, flag)
+ register char *buf1, *buf2;
+ register flag;
+{
+ while (isspace(*buf1))
+ buf1++;
+ if (*buf1 != ',') {
+ if (!*buf1) {
+ *buf2 = 0;
+ return (0);
+ }
+ while (*buf1 && !isspace(*buf1) && *buf1 != ',')
+ if (flag < 0)
+ if (isupper(*buf1))
+ *buf2++ = tolower(*buf1++);
+ else
+ *buf2++ = *buf1++;
+ else if (flag > 0)
+ if (islower(*buf1))
+ *buf2++ = toupper(*buf1++);
+ else
+ *buf2++ = *buf1++;
+ else
+ *buf2++ = *buf1++;
+ } else
+ *buf2++ = *buf1++;
+ *buf2 = 0;
+ while (isspace(*buf1))
+ buf1++;
+ return (*buf1 ? buf1 : 0);
+}
diff --git a/battlestar/globals.c b/battlestar/globals.c
new file mode 100644
index 00000000..2bf1119f
--- /dev/null
+++ b/battlestar/globals.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)globals.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+int WEIGHT = MAXWEIGHT;
+int CUMBER = MAXCUMBER;
+
+char *objdes[NUMOFOBJECTS] = {
+ "There is a knife here",
+ "There is an exquisitely crafted sword and scabbard here.",
+ 0, /* can land from here */
+ "There is a fierce woodsman here brandishing a heavy mallet.",
+ "There is an unweildly two-handed sword here.",
+ "There is a bloody meat cleaver here.",
+ "A rusty broadsword is lying here.",
+ "There is an ancient coat of finely woven mail here.",
+ "There is a old dented helmet with an ostrich plume here.",
+ "There is a shield of some native tribe here.",
+ "The maid's body is lying here. She was murdered!",
+ "There is a Viper ready for launch here.",
+ "A kerosene lantern is burning luridly here.",
+ "An old pair of shoes has been discarded here.",
+ 0, /* cylon */
+ "There is a pair of pajamas here.",
+ "A kingly robe of royal purple and spun gold is draped here.",
+ "There is a strange golden amulet on the floor here.",
+ "A medallion of solid gold shimmers on the ground nearby.",
+ "A talisman of gold is lying here.",
+ "A dead woodsman has fallen here. He was savagely murdered.",
+ "A heavy wooden mallet lies nearby.",
+ "There is a laser pistol here.",
+ "A flower-like young goddess is bathing in the hot mineral pools. She is \nwatching you, but continues to steep and sing softly.",
+ "The goddess is reclining on a bed of ferns and studying you intently.",
+ "There is a grenade here",
+ "There is a length of heavy chain here.",
+ "There is a stout rope here.",
+ "There is a pair of Levi's here.",
+ "A bloody mace is lying on the ground here.",
+ "There is a shovel here.",
+ "A long, sharp halberd is propped up here.",
+ "There is a compass here",
+ "Wreckage and smoldering debris from a crash litter the ground here.",
+ "A woodland Elf armed with a shield and deadly halberd lunges toward you!",
+ "I think I hear footsteps behind us.",
+ "There are a few coins here.",
+ "There are some matches here.",
+ "An unctuous man in a white suit and a dwarf are standing here.",
+ "There are some ripe papayas here.",
+ "There is a ripe pineapple here.",
+ "There are some kiwi fruit here.",
+ "There are some coconuts here.",
+ "There is a ripe mango here.",
+ "There is a sparkling diamond ring here.",
+ "There is a colorful pink potion in a small crystal vial here.",
+ "A gold bracelet is on the ground here.",
+ "A swarthy woman with stern features pulls you aside from the crowd,\n'I must talk to you -- but not here. Meet me at midnight in the gardens.'",
+ "The swarthy woman has been awaiting you anxiousy. 'I must warn you that the\nIsland has anticipated your Quest. You will not be welcomed. The Darkness is\nstrong where you must search. Seek not the shadows save only at night, for\nthen are they the weakest. In the mountains far from here a canyon winds\nwith ferns and streams and forgotten vines. There you must go. Take this\nrope.'",
+ "Out from the shadows a figure leaps! His black cape swirls around, and he\nholds a laser sword at your chest. 'So, you have come to fulfill the Quest.\nHa! Your weapons are no match for me!'",
+ "An old timer with one eye missing and no money for a drink sits at the bar.",
+ "You are flying through an asteroid field!",
+ "A planet is nearby.",
+ "The ground is charred here.",
+ "There is a thermonuclear warhead here.",
+ "The fragile, beautiful young goddess lies here. You murdered her horribly.",
+ "The old timer is lying here. He is dead.",
+ "The native girl's body is lying here.",
+ "A native girl is sitting here.",
+ "A gorgeous white stallion is standing here.",
+ "The keys are in the ignition.",
+ "A pot of pearls and jewels is sitting here.",
+ "A bar of solid gold is here.",
+ "There is a 10 kilogram diamond block here."
+
+};
+
+char *objsht[NUMOFOBJECTS] = {
+ "knife",
+ "fine sword",
+ 0,
+ "Woodsman",
+ "two-handed sword",
+ "meat cleaver",
+ "broadsword",
+ "coat of mail",
+ "plumed helmet",
+ "shield",
+ "maid's body",
+ "viper",
+ "lantern",
+ "shoes",
+ 0,
+ "pajamas",
+ "robe",
+ "amulet",
+ "medallion",
+ "talisman",
+ "woodsman's body",
+ "wooden mallet",
+ "laser",
+ 0,
+ 0,
+ "grenade",
+ "chain",
+ "rope",
+ "levis",
+ "mace",
+ "shovel",
+ "halberd",
+ "compass",
+ 0,
+ "Elf",
+ 0,
+ "coins",
+ "match book",
+ 0,
+ "papayas",
+ "pineapple",
+ "kiwi",
+ "coconuts",
+ "mango",
+ "ring",
+ "potion",
+ "bracelet",
+ 0,
+ 0,
+ "Dark Lord",
+ 0,
+ 0,
+ 0,
+ 0,
+ "warhead",
+ "goddess's body",
+ "old timer's body",
+ "girl's body",
+ 0,
+ "stallion",
+ "car",
+ "pot of jewels",
+ "bar of gold",
+ "diamond block"
+};
+
+char *ouch[NUMOFINJURIES] = {
+ "some minor abrasions",
+ "some minor lacerations",
+ "a minor puncture wound",
+ "a minor amputation",
+ "a sprained wrist",
+ "a fractured ankle and shattered kneecap",
+ "a broken arm and dislocated shoulder",
+ "a few broken ribs",
+ "a broken leg and torn ligaments",
+ "a broken back and ruptured spleen",
+ "some deep incisions and a loss of blood",
+ "a fractured skull and mashed face",
+ "a broken neck"
+};
+
+int objwt[NUMOFOBJECTS] = {
+ 1, 5, 0, 10, 15, 2, 10, 10,
+ 3, 5, 50, 2500, 2, 1, 100, 1,
+ 2, 1, 1, 1, 60, 10, 5, 0,
+ 50, 5, 15, 5, 1, 20, 10, 10,
+ 0, 0, 0, 0, 1, 0, 0, 1,
+ 1, 1, 2, 1, 0, 0, 0, 0,
+ 0, 0, 100, 0, 0, 0, 55, 47,
+ 50, 45, 45, 100, 2000, 30, 20, 10
+};
+
+int objcumber[NUMOFOBJECTS] = {
+ 1, 5, 0, 150, 10, 1, 5, 2,
+ 2, 1, 5, 10, 1, 1, 10, 1,
+ 1, 1, 1, 1, 7, 5, 4, 0,
+ 0, 1, 1, 1, 1, 5, 4, 4,
+ 1, 0, 0, 0, 1, 0, 0, 1,
+ 1, 1, 3, 1, 0, 0, 1, 0,
+ 0, 0, 10, 0, 0, 0, 7, 8,
+ 10, 8, 8, 10, 10, 3, 1, 2
+};
+
+int win = 1;
+int matchcount = 20;
+int followgod = -1;
+int followfight = -1;
diff --git a/battlestar/init.c b/battlestar/init.c
new file mode 100644
index 00000000..47806cc9
--- /dev/null
+++ b/battlestar/init.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init.c 5.5 (Berkeley) 2/27/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include "externs.h"
+#include <pwd.h>
+
+initialize(startup)
+ char startup;
+{
+ register struct objs *p;
+ void die();
+
+ puts("Version 4.2, fall 1984.");
+ puts("First Adventure game written by His Lordship, the honorable");
+ puts("Admiral D.W. Riggle\n");
+ srand(getpid());
+ getutmp(uname);
+ wiz = wizard(uname);
+ wordinit();
+ if (startup) {
+ location = dayfile;
+ direction = NORTH;
+ time = 0;
+ snooze = CYCLE * 1.5;
+ position = 22;
+ setbit(wear, PAJAMAS);
+ fuel = TANKFULL;
+ torps = TORPEDOES;
+ for (p = dayobjs; p->room != 0; p++)
+ setbit(location[p->room].objects, p->obj);
+ } else
+ restore();
+ signal(SIGINT, die);
+}
+
+getutmp(uname)
+ char *uname;
+{
+ struct passwd *ptr;
+
+ ptr = getpwuid(getuid());
+ strcpy(uname, ptr ? ptr->pw_name : "");
+}
+
+char *list[] = { /* hereditary wizards */
+ "riggle",
+ "chris",
+ "edward",
+ "comay",
+ "yee",
+ "dmr",
+ "ken",
+ 0
+};
+
+char *badguys[] = {
+ "wnj",
+ "root",
+ "ted",
+ 0
+};
+
+wizard(uname)
+ char *uname;
+{
+ char flag;
+
+ if (flag = checkout(uname))
+ printf("You are the Great wizard %s.\n", uname);
+ return flag;
+}
+
+checkout(uname)
+ register char *uname;
+{
+ register char **ptr;
+
+ for (ptr = list; *ptr; ptr++)
+ if (strcmp(*ptr, uname) == 0)
+ return 1;
+ for (ptr = badguys; *ptr; ptr++)
+ if (strcmp(*ptr, uname) == 0) {
+ printf("You are the Poor anti-wizard %s. Good Luck!\n",
+ uname);
+ CUMBER = 3;
+ WEIGHT = 9; /* that'll get him! */
+ clock = 10;
+ setbit(location[7].objects, WOODSMAN); /* viper room */
+ setbit(location[20].objects, WOODSMAN); /* laser " */
+ setbit(location[13].objects, DARK); /* amulet " */
+ setbit(location[8].objects, ELF); /* closet */
+ return 0; /* anything else, Chris? */
+ }
+ return 0;
+}
diff --git a/battlestar/misc.c b/battlestar/misc.c
new file mode 100644
index 00000000..800eb2fb
--- /dev/null
+++ b/battlestar/misc.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)misc.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+card(array, size) /* for beenthere, injuries */
+ register char *array;
+ int size;
+{
+ register char *end = array + size;
+ register int i = 0;
+
+ while (array < end)
+ if (*array++)
+ i++;
+ return (i);
+}
+
+ucard(array)
+ register unsigned *array;
+{
+ register int j = 0, n;
+
+ for (n = 0; n < NUMOFOBJECTS; n++)
+ if (testbit(array, n))
+ j++;
+ return (j);
+}
diff --git a/battlestar/nightfile.c b/battlestar/nightfile.c
new file mode 100644
index 00000000..8e0b6c25
--- /dev/null
+++ b/battlestar/nightfile.c
@@ -0,0 +1,1177 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)nightfile.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+struct room nightfile[] = {
+ { 0 },
+ { "You are in the main hangar.",
+ 5, 2, 9, 3, 3, 1, 0, 0,
+"This is a huge bay where many fighters and cargo craft lie. Alarms are \n\
+sounding and fighter pilots are running to their ships. Above is a gallery\n\
+overlooking the bay. The scream of turbo engines is coming from +. The rest\n\
+of the hangar is +. There is an exit +.*\n" },
+ { "This is the landing bay.",
+ 1, 0, 10, 0, 0, 0, 0, 0,
+"Ships are landing here, some heavily damaged. Enemy fighters continually\n\
+strafe this vulnerable port. The main hangar is +, *\n\
+There is an exit +.*\n" },
+ { "You are in the gallery.",
+ 4, 0, 0, 0, 0, 0, 1, 0,
+"From here a view of the entire landing bay reveals that our battlestar\n\
+is near destruction. Fires are spreading out of control and laser blasts\n\
+lick at the shadows. The control room is +. ***\n" },
+ { "You are in the control room.",
+ 0, 3, 0, 0, 0, 0, 5, 0,
+"Several frantic technicians are flipping switches wildly but otherwise\n\
+this room seems fairly deserted. A weapons locker has been left open.\n\
+A staircase leads down. * There is a way -. ** \n" },
+ { "This is the launch room.",
+ 6, 1, 7, 0, 4, 1, 0, 0,
+"From the launch tubes here fighters blast off into space. Only one is left,\n\
+and it is guarded by two fierce men. A staircase leads up from here.\n\
+There is a cluttered workbench +. From the main hangar come sounds of great\n\
+explosions. The main hangar is +. The viper launch tubes are to the -.*\n" },
+ { "You are at the workbench.",
+ 0, 5, 7, 0, 0, 0, 0, 0,
+"Strange and unwieldy tools are arranged here including a lunch box \n\
+and pneumatic wrenches and turbo sprocket rockets.*\n\
+The launch room is +. The remaining viper is +.*\n" },
+ { "You are in the viper launch tube.",
+ 0, 5, 0, 5, 32, 0, 0, 0,
+"The two guards are eyeing you warily! ****\n" },
+ { "This is a walk in closet.",
+ 22, 0, 0, 0, 0, 0, 0, 0,
+"A wardrobe of immense magnitude greets the eye. Furs and robes of kings\n\
+hang on rack after rack. Silken gowns, capes woven with spun gold, and \n\
+delicate synthetic fabrics are stowed here. The bedroom is +.***\n" },
+ { "You are in a wide hallway leading to the main hangar.",
+ 0, 0, 11, 1, 0, 0, 0, 0,
+"The walls and ceiling here have been blasted through in several places.\n\
+It looks as if quite a battle has been fought for possession of the landing bay\n\
+Gaping corpses litter the floor.** The hallway continues +.\n\
+The main hangar is +.\n" },
+ { "You are in a wide hallway leading to the landing bay.",
+ 0, 0, 12, 2, 0, 0, 0, 0,
+"Most of the men and supplies needed in the main hangar come through this\n\
+corridor, but the wounded are forced to use it too. It very dank and\n\
+crowded here, and the floor is slippery with blood.**\n\
+The hallway continues -. The landing bay is +.\n" },
+ { "The hallway is very congested with rubble here.",
+ 0, 0, 0, 9, 13, 1, 0, 0,
+"It is too choked with broken steel girders and other debris to continue\n\
+on much farther. Above, the ceiling has caved in and it is possible to \n\
+climb up. There is not much chance to go -, -, or -.\n\
+But the hallway seems clearer +.\n" },
+ { "A wide hallway and a more narrow walkway meet here.",
+ 14, 15, 0, 10, 0, 0, 0, 0,
+"The intersection is crowded with the many wounded who have come up\n\
+the wide hallway and continued +. The walkway is less crowded +.\n\
+The wide hallway goes *-.\n" },
+ { "You are in what was once an elegant stateroom.",
+ 16, 0, 0, 0, 0, 0, 11, 0,
+"Whoever lived in this stateroom, he and his female companion\n\
+were mercilessly slain in their sleep. Clothes, trinkets and personal\n\
+belongings are scattered all across the floor. Through a hole in the\n\
+collapsed floor I can see a hallway below. A door is +.***\n" },
+ { "You're at the entrance to the sick bay.",
+ 17, 12, 18, 0, 0, 0, 0, 0,
+"The wounded are entering the sick bay in loudly moaning files.\n\
+The walkway continues - and +. A doctor is motioning for you to \n\
+come to the -. *\n" },
+ { "You're in the walkway.",
+ 12, 19, 0, 0, 0, 0, 0, 0,
+"Most of the men and supplies were coming from the armory. The walkway\n\
+continues -. The armory is +.**\n" },
+ { "These are the executive suites of the battlestar.",
+ 20, 13, 21, 22, 23, 1, 24, 0,
+"Luxurious staterooms carpeted with crushed velvet and adorned with beaten\n\
+gold open onto this parlor. A wide staircase with ivory banisters leads\n\
+up or down. This parlor leads into a hallway +. The bridal suite is +.\n\
+Other rooms lie - and +.\n" },
+ { "You're in a long dimly lit hallway.",
+ 0, 14, 25, 0, 0, 0, 0, 0,
+"This part of the walkway is deserted. There is a dead end +. The\n\
+entrance to the sickbay is +. The walkway turns sharply -.*\n" },
+ { "This is the sick bay.",
+ 0, 0, 0, 14, 0, 0, 0, 0,
+"Sinister nurses with long needles and pitiful aim probe the depths of suffering\n\
+here. Only the mortally wounded receive medical attention on a battlestar,\n\
+but afterwards they are thrown into the incinerators along with the rest.**\n\
+Nothing but death and suffering +. The walkway is +.\n" },
+ { "You're in the armory.",
+ 15, 26, 0, 0, 0, 0, 0, 0,
+"An armed guard is stationed here 365 sectars a yarn to protect the magazine.\n\
+The walkway is +. The magazine is +.**\n" },
+ { "The hallway ends here at the presidential suite.",
+ 27, 16, 0, 0, 0, 0, 0, 0,
+"The door to this suite is made from solid magnesium, and the entryway is\n\
+inlaid with diamonds and fire opals. The door is ajar +. The hallway\n\
+goes -.**\n" },
+ { "This is the maid's utility room.",
+ 0, 0, 0, 16, 0, 0, 0, 0,
+"What a gruesome sight! The maid has been brutally drowned in a bucket of\n\
+Pine Sol and repeatedly stabbed in the back with a knife.***\n\
+The hallway is +.\n" },
+ { "This is a luxurious stateroom.",
+ 0, 8, 16, 0, 0, 0, 0, 0,
+"The floor is carpeted with a soft animal fur and the great wooden furniture\n\
+is inlaid with strips of platinum and gold. Electronic equipment built\n\
+into the walls and ceiling is flashing wildly. The floor shudders and\n\
+the sounds of dull explosions rumble though the room. From a window in\n\
+the wall + comes a view of darkest space. There is a small adjoining\n\
+room +, and a doorway +.*\n" },
+ { "You are at the entrance to the dining hall.",
+ 0, 0, 28, 0, 0, 0, 16, 0,
+"A wide staircase with ebony banisters leads down here.**\n\
+The dining hall is to the -.*\n" },
+ { "This was once the first class lounge.",
+ 0, 0, 29, 0, 16, 1, 0, 0,
+"There is much rubble and destruction here that was not apparent elsewhere.\n\
+The walls and ceilings have broken in in some places. A staircase with\n\
+red coral banisters leads up. It is impossible to go - or -.\n\
+It seems a little clearer +.*\n" },
+ { "You are in a narrow stairwell.",
+ 0, 17, 0, 0, 30, 1, 0, 0,
+"These dusty and decrepit stairs lead up. There is no way -. The\n\
+hallway turns sharply -.**\n" },
+ { "You are in the magazine.",
+ 19, 0, 0, 0, 0, 0, 0, 0,
+"Rows and rows of neatly stacked ammunition for laser pistols and grenade\n\
+launchers are here. The armory is +.***\n" },
+ { "You're in the presidential suite.",
+ 0, 20, 0, 0, 0, 0, 0, 0,
+"Apparently the president has been assassinated. A scorched figure lies\n\
+face downward on the carpet clutching his chest.*\n\
+The hallway leads -.**\n" },
+ { "You are in the dining hall.",
+ 0, 30, 31, 23, 0, 0, 0, 0,
+"This was the seen of a mass suicide. Hundreds of ambassadors and assorted\n\
+dignitaries sit slumped over their breakfast cereal. I suppose the news\n\
+of the cylon attack killed them. There is a strange chill in this room. I\n\
+would not linger here. * The kitchen is +. Entrances + and +.\n" },
+ { "The debris is very thick here.",
+ 0, 11, 0, 24, 0, 0, 0, 0,
+"Broken furniture, fallen girders, and other rubble block the way.\n\
+There is not much chance to continue -, -, or -.\n\
+It would be best to go -.\n" },
+ { "You are in the kitchen.",
+ 28, 0, 0, 0, 0, 0, 0, 0,
+"This room is full of shining stainless steel and burnished bronze cookware. An \n\
+assortment of tropical fruits and vegetables as well as fine meats and cheeses \n\
+lies on a sterling platter. The chef, unfortunately, has been skewered like a \n\
+side of beef. The dining room is +. ** There is a locked door +.\n" },
+ { "You are in an arched entry leading to the dining room.",
+ 0, 0, 0, 28, 0, 0, 0, 0,
+"The door leading out is bolted shut from the outside and is very strong.***\n\
+The dining room is +.\n" },
+ { "You are in space.",
+ 33, 34, 35, 36, 37, 1, 33, 1,
+"****\n" },
+ { "You are in space.",
+ 38, 32, 39, 40, 41, 1, 42, 1,
+"****\n" },
+ { "You are in space.",
+ 32, 44, 45, 46, 47, 1, 48, 1,
+"****\n" },
+ { "You are in space.",
+ 40, 45, 49, 32, 50, 1, 51, 1,
+"****\n" },
+ { "You are in space.",
+ 41, 46, 32, 52, 53, 1, 54, 1,
+"****\n" },
+ { "You are in space.",
+ 42, 47, 50, 53, 55, 1, 32, 1,
+"****\n" },
+ { "You are in space.",
+ 43, 48, 51, 54, 32, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 57, 33, 40, 41, 42, 1, 43, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 35, 57, 33, 58, 1, 59, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 36, 33, 59, 60, 1, 61, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 37, 58, 60, 62, 1, 33, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 38, 59, 61, 33, 1, 63, 1,
+"****\n" },
+ { "You are in space.",
+ 34, 64, 45, 46, 47, 1, 48, 1,
+"****\n" },
+ { "You are in space.",
+ 35, 44, 49, 34, 50, 1, 51, 1,
+"****\n" },
+ { "You are in space.",
+ 36, 44, 34, 52, 53, 1, 54, 1,
+"****\n" },
+ { "You are in space.",
+ 37, 44, 50, 53, 55, 1, 34, 1,
+"****\n" },
+ { "You are in space.",
+ 38, 44, 51, 54, 34, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 49, 49, 52, 35, 49, 1, 49, 1,
+"****\n" },
+ { "You are in space.",
+ 58, 47, 49, 37, 55, 1, 35, 1,
+"****\n" },
+ { "You are in space.",
+ 59, 48, 49, 38, 35, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 52, 52, 36, 49, 52, 1, 52, 1,
+"****\n" },
+ { "You are in space.",
+ 60, 46, 37, 52, 55, 1, 36, 1,
+"****\n" },
+ { "You are in space.",
+ 61, 48, 38, 52, 36, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 62, 55, 55, 55, 56, 1, 37, 1,
+"****\n" },
+ { "You are in space.",
+ 56, 56, 56, 56, 38, 1, 55, 1,
+"****\n" },
+ { "You are in space.",
+ 65, 39, 57, 57, 57, 1, 57, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 50, 49, 42, 62, 1, 40, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 51, 49, 43, 40, 1, 63, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 53, 43, 59, 62, 1, 41, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 54, 43, 59, 41, 1, 56, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 55, 62, 62, 56, 1, 42, 1,
+"****\n" },
+ { "You are in space.",
+ 39, 56, 35, 36, 43, 1, 55, 1,
+"****\n" },
+ { "You are in space.",
+ 44, 66, 66, 66, 66, 1, 66, 1,
+"****\n" },
+ { "You are in space.",
+ 67, 57, 67, 67, 67, 1, 67, 1,
+"****\n" },
+ { "You are in space.",
+ 64, 68, 68, 68, 68, 1, 68, 1,
+"****\n" },
+ { "You are orbiting a small blue planet.",
+ 67, 67, 67, 67, 65, 1, 69, 1,
+"****\n" },
+ { "You are orbiting a tropical planet.",
+ 68, 68, 68, 68, 66, 1, 70, 1,
+"****\n" },
+ { "You are flying through a dense fog.",
+ 69, 69, 69, 69, 69, 1, 69, 1,
+"A cold grey sea of mist is swirling around the windshield and water droplets\n\
+are spewing from the wingtips. Ominous shadows loom in the darkness and it\n\
+feels as if a trap is closing around us. I have lost all sense of direction.\n\
+****\n" },
+ { "You are approaching an island.",
+ 71, 72, 73, 74, 68, 1, 0, 1,
+"Feather palms outlined by mellow moonlight and a silvery black ocean line\n\
+the perimeter of the island. Mighty mountains of emerald and amethyst rise\n\
+like jagged teeth from black gums. The land rises sharply +. The shore\n\
+line stretches on *+.*\n" },
+ { "You are flying over a mountainous region.",
+ 75, 73, 76, 77, 68, 1, 0, 1,
+"Below is a shadow filled canyon with luminous waterfalls plummeting down beyond sight and looming spires and pinnacles. **The ocean is +.*\n" },
+ { "You are flying over the ocean.",
+ 74, 78, 78, 78, 68, 1, 0, 1,
+"You bank over the water and your wingtips dip low to the green waves. The\n\
+sea is very shallow here and the white coral beds beneath us teem with \n\
+shadowy fish.****\n" },
+ { "You are flying over the beach.",
+ 71, 72, 79, 74, 68, 1, 80, 1,
+"A warm gentle surf caresses the beach here. The land rises\n\
+sharply +.* The beach is lost in low cliffs +.*\n" },
+ { "You are flying over a large lagoon.",
+ 81, 72, 73, 82, 68, 1, 0, 1,
+"The water's brink winds tortuously inland. There are some lights +.***\n" },
+ { "You are flying over a gently sloping plane.",
+ 83, 71, 84, 85, 68, 1, 0, 1,
+"The ground appears to be choked with vegetation.* The terrain is more\n\
+rugged +.**\n" },
+ { "You are flying through a gorge.",
+ 0, 0, 86, 71, 68, 1, 102, 1,
+"This is a narrow, steep sided canyon lined with plants. The stars above\n\
+glisten through the over hanging trees. The gorge leads to the\n\
+sea** +, and to a tumultuous origin +.\n" },
+ { "You are flying over a plantation.",
+ 85, 81, 71, 88, 68, 1, 89, 1,
+"It might be possible to land here, but not in the dark.* There are some lights\n\
++ and *+.\n" },
+ { "You are over the ocean.",
+ 72, 78, 79, 74, 68, 1, 0, 1,
+"The deep green swells foam and roll into the shore **+*.\n" },
+ { "You are flying along the coast.",
+ 86, 72, 90, 73, 68, 1, 91, 1,
+"The coastline here is very rocky. The surf in some places is violent\n\
+and explodes in a shower of sparkling, moonlit spray. ****\n" },
+ { "This is a beautiful coral beach.",
+ 106, 0, 107, 108, 73, 0, 0, 0,
+"Fine silver sand kissed lightly by warm tropical waters and illuminated\n\
+by a huge tropical moon stretches at least 30 meters inland.\n\
+Gently swaying palm trees are +.***\n" },
+ { "You are flying over a small fishing village.",
+ 77, 74, 71, 82, 68, 1, 92, 1,
+"A few thatched huts lit with torches and bonfires line a road below.\n\
+The road continues on ***+.\n" },
+ { "You are flying over a clearing.",
+ 88, 72, 74, 87, 68, 1, 93, 1,
+"There is a dock here (big enough for a seaplane) leading to a clearing.\n\
+The still waters of the lagoon reflects our orange turbo thrusters.****\n" },
+ { "You are flying over the shore.",
+ 94, 75, 95, 96, 68, 1, 0, 1,
+"Rocky lava flows have overtaken the beach here.****\n" },
+ { "You are flying in a wide valley.",
+ 95, 97, 86, 75, 68, 1, 98, 1,
+"This is a shallow valley yet the floor is obscured by a thick mist.\n\
+The valley opens into blackness +. The mist grows thicker +.**\n" },
+ { "You are flying near the shore.",
+ 96, 77, 75, 99, 68, 1, 0, 1,
+"Very tall trees growing in neatly planted rows march off from the \n\
+water here towards the hills and down to the flat lands *+.**\n" },
+ { "You are flying around the very tip of the island.",
+ 95, 79, 90, 84, 68, 1, 0, 1,
+"Sheer cliffs rise several hundred feet to a tree covered summit. Far below,\n\
+the grey sea gnaws voraciously at the roots of these cliffs. The island bends\n\
+around +** and +.\n" },
+ { "You are flying along the coastline.",
+ 99, 82, 88, 100, 68, 1, 101, 1,
+"This is a narrow strip of sand lined with very few trees. The stars above\n\
+flicker through wisps of clouds. The beach continues on -.* There\n\
+are some lights +.*\n" },
+ { "You are flying over several cottages and buildings",
+ 99, 82, 77, 87, 68, 1, 103, 1,
+"Directly below is small ornate house lit up with spot lights and decorative\n\
+bulbs. A bell tower and a spurting fountain are nearby. Small dirt roads go\n\
++ and +.**\n" },
+ { "You are in a field of sugar cane.",
+ 109, 110, 111, 112, 77, 0, 0, 0,
+"These strong, thick canes give little shelter but many cuts and scrapes.\n\
+There are some large trees ***+.\n" },
+ { "You are flying over the ocean.",
+ 95, 78, 90, 86, 68, 1, 0, 1,
+"The water is a placid ebony.****\n" },
+ { "You are on the coast road.",
+ 113, 114, 115, 116, 79, 0, 0, 0,
+"The road winds close to the shore here. The trees on either side press close\n\
+in the darkness and seem to be watching us.** The road continues -\n\
+and -.\n" },
+ { "You are on the main street of the village.",
+ 117, 118, 119, 120, 81, 0, 0, 0,
+"The natives are having a festive luau here. Beautiful dancers gyrate in the\n\
+torchlight to the rhythm of wooden drums. A suckling pig is sizzling in a\n\
+bed of coals and ti leaves are spread with poi and tropical fruits. Several\n\
+natives have come over to you and want you to join in the festivities.\n\
+There is a light burning in a bungalow +.***\n" },
+ { "You are at the sea plane dock.",
+ 121, 122, 123, 124, 82, 0, 0, 0,
+"The clearing is deserted. The grass is wet with the evening dew +.*\n\
+There is something set up +.*\n" },
+ { "You are flying over the ocean.",
+ 94, 83, 95, 96, 68, 1, 0, 1,
+"The black waves surge off shore here. The ocean becomes much calmer +.***\n" },
+ { "You are flying along the coast.",
+ 94, 84, 86, 83, 68, 1, 0, 1,
+"The land is very low here with a river running into the sea +. There\n\
+is a wide valley opening up +, but a strange mist is flowing out of it.\n\
+The very tip of the island is +.*\n" },
+ { "You are flying along the coast.",
+ 94, 85, 83, 99, 68, 1, 0, 1,
+"The coast here is cluttered with rocky outcroppings.****\n" },
+ { "You are lost in a sea of fog.",
+ 97, 104, 97, 97, 97, 1, 0, 1,
+"What have you gotten us into?\n\
+I cant see a thing! ****\n" },
+ { "You are on a gravel wash.",
+ 125, 126, 127, 128, 84, 0, 0, 0,
+"It is very dark here. A cool breeze is blowing from +. No moonlight can\n\
+reach below a thick canopy of fog above. The sound of cascading water is\n\
+coming from +.**\n" },
+ { "You are flying over a wide beach.",
+ 96, 88, 85, 87, 68, 1, 105, 1,
+"There are some lighted buildings *+. Some trees are growing +.*\n" },
+ { "You are flying over the ocean.",
+ 100, 100, 87, 100, 68, 1, 0, 1,
+"The black waves surge and splash against the rocky shore.****\n" },
+ { "You are on a narrow strip of sand.",
+ 129, 130, 131, 0, 87, 0, 0, 0,
+"Rather coarse sand makes this beach very steep and only a few meters wide.\n\
+A fresh ocean breeze is rustling the ferns **+.*\n" },
+ { "This is Fern Canyon.",
+ 0, 0, 132, 133, 76, 0, 0, 0,
+"Delicate waving ferns flourish here, suckled by warm water dripping from \n\
+every fissure and crevice in the solid rock walls. The stars above sparkle\n\
+through a thin mist. The canyon winds **-, and -.\n" },
+ { "This is the front lawn.",
+ 134, 135, 136, 137, 88, 0, 0, 0,
+"There is a small fountain lighted with green and yellow bulbs here where\n\
+the driveway meets the lawn. Across the driveway, +, is an ornate white\n\
+house lit with gas lamps. A bell tower here is awash in pale blue.* There\n\
+is a road + which turns into the driveway.*\n" },
+ { "You have just crossed the crest of a mountain.",
+ 97, 79, 86, 71, 68, 1, 0, 1,
+"The fog vanished mysteriously as we flew over the crest.*\n\
+Far + I can see the ocean sparkling in the moonlight.**\n" },
+ { "You are on a sandy beach.",
+ 138, 139, 140, 0, 99, 0, 0, 0,
+"Fine coral sand, a fresh sea breeze, and dramatic surf add to this beach's\n\
+appeal.** Stone steps lead to a lighted path in the gardens +.*\n" },
+ { "You are among palm trees near the shore.",
+ 141, 80, 142, 143, 73, 0, 0, 0,
+"Arching coconut palms laden with fruit provide a canopy for the glistening\n\
+white sand and sparse, dew covered grasses growing here. The forest grows\n\
+denser +. Crickets are chirping loudly here. The ocean is +.**\n" },
+ { "You are walking along the beach.",
+ 144, 0, 145, 80, 73, 0, 0, 0,
+"The warm tropical waters nuzzle your ankles as you walk. Above is a gorgeous\n\
+starscape. The battlestar must be up there somewhere. The slope of the sand\n\
+is so gentle that the surf only slides up the sand.** There are some rocks\n\
++.*\n" },
+ { "You are walking along the beach.",
+ 146, 0, 80, 147, 73, 0, 0, 0,
+"The tide is out very far tonight, and it is possible to explore hidden rocks\n\
+and caves not ordinarily accessible. Rich beds of seaweed have been exposed\n\
+to the cool night air.****\n" },
+ { "You are in a papaya grove.",
+ 148, 89, 149, 150, 77, 0, 0, 0,
+"Slender trees with their large seven lobed leaves bulge with succulent fruit.\n\
+There are some tall trees +.***\n" },
+ { "You are in a field of pineapple.",
+ 89, 151, 152, 153, 77, 0, 0, 0,
+"The sharp dagger like pineapple leaves can pierce the flesh and hold fast\n\
+a skewered victim with tiny barbs.* The field ends +.**\n" },
+ { "You are in a field of kiwi plants.",
+ 149, 154, 155, 89, 77, 0, 0, 0,
+"Round hairy fruit hang from staked vines here. There are some trees +\n\
+and +. The field ends in a road +.*\n" },
+ { "You are in a large grove of coconuts.",
+ 150, 153, 89, 156, 77, 0, 0, 0,
+"These trees are much taller than any growing near the shore and the shadows\n\
+are also deeper. It's hard to keep my sense of direction.****\n" },
+ { "You are in the woods.",
+ 157, 91, 158, 116, 79, 0, 0, 0,
+"Tropical undergrowth makes the going rough here. Sword ferns give no strong\n\
+foot hold and the dangling vines would gladly throttle one. The darkness is\n\
+so intense here that we stand in utter blackness.****\n" },
+ { "You are at the shore.",
+ 91, 0, 159, 145, 79, 0, 160, 0,
+"The low minus tide tonight might make it possible to climb down to a\n\
+small cave entrance below. Large rocks would usually churn the waves\n\
+asunder.*** The beach goes -.\n" },
+ { "You are on the coast road.",
+ 158, 161, 162, 91, 79, 0, 0, 0,
+"The road is beginning to turn slightly -. I can here the surf +. The road\n\
+continues into the dark forest +.*\n" },
+ { "The road winds deeper into the trees.",
+ 163, 142, 91, 164, 79, 0, 0, 0,
+"Only narrow moonbeams filter through the dense foliage above. The moist rich\n\
+earth has nurtured a myriad of slugs, snakes, and spiders to grow here. The\n\
+road continues - and *- into the shadows.*\n" },
+ { "This is the front porch of the bungalow.",
+ 165, 92, 0, 0, 81, 0, 0, 0,
+"The veranda is lit by a small yellow bug light. The door leads -.\n\
+The stone walk down to the luau is lined with burning torches +. That\n\
+roast pig smells good.**\n" },
+ { "You are on a path leading to the lagoon.",
+ 92, 166, 167, 168, 81, 0, 0, 0,
+"This path winds through the underbrush and towards the lagoon *+. The\n\
+broad faced moon peeps though the branches above. The sound of drums echos\n\
+in the woods.**\n" },
+ { "This is a dirt road.",
+ 169, 118, 170, 92, 81, 0, 0, 0,
+"**The road continues on - here for some distance. A bonfire and party light\n\
+up the night sky +.\n" },
+ { "You are on a dirt road.",
+ 171, 118, 92, 172, 81, 0, 0, 0,
+"**There is a village +. A huge bonfire licks at the trees, and a celebration\n\
+of some sort is going on there. The smell of luscious cooking is tantalizing\n\
+my flared nostrils. The road continues +.\n" },
+ { "You are on a dirt road.",
+ 173, 93, 174, 175, 82, 0, 0, 0,
+"This is a wide grassy clearing bedewed with droplets of evening mist. The\n\
+trees alongside the road moan and whisper as we pass. They seem annoyed at\n\
+our presence. **The road continues - and -.\n" },
+ { "You are at the seaplane dock.",
+ 93, 0, 176, 177, 82, 0, 0, 0,
+"Not a living thing stirs the calm surface of the lagoon. The wooden planks\n\
+creak unnaturally as we tread on them. The dock reaches a clearing +.\n\
+A dark trail leads around the lagoon **+.\n" },
+ { "There are some tables on the lawn here.",
+ 121, 122, 123, 93, 82, 0, 0, 0,
+"Some tables are strewn on the wet lawn.****\n" },
+ { "You are nosing around in the bushes.",
+ 124, 124, 93, 124, 82, 0, 0, 0,
+"There is little here but some old beer cans. It is damp and dirty in here.\n\
+I think I stepped in something unpleasant. It would be best to go **-.*\n" },
+ { "You are walking in a dry stream bed.",
+ 178, 98, 179, 0, 84, 0, 0, 0,
+"The large cobblestones are difficult to walk on. No starlight reaches\n\
+below a black canopy of fog seemingly engulfing the whole island. A dirt\n\
+path along the wash is **+. The high bank is impossible to climb +.\n" },
+ { "You are at the thermal pools.",
+ 98, 0, 180, 181, 84, 0, 0, 0,
+"Odd spluttering and belching water splashes up around the rocks here.\n\
+A spectacular waterfall nearby tumbles down as a river of effervescent\n\
+bubbles. The air is quite warm and a cave entrance ***+ spews steam.\n" },
+ { "You are in the woods.",
+ 127, 180, 182, 98, 84, 0, 0, 0,
+"It is pitch black in the forest here and my pant leg is caught on something.\n\
+There may be poison oak here. What was that? A lantern just flickered by in\n\
+the dark! The sound of rushing water is coming from *+.**\n" },
+ { "You are on a dirt trail.",
+ 179, 181, 98, 0, 84, 0, 0, 0,
+"The trail seems to start here and head towards the forest +.** High, dark\n\
+cliffs border the trail +. Some crickets are chirping noisily.\n" },
+ { "You are walking along the beach.",
+ 183, 101, 184, 0, 87, 0, 0, 0,
+"The surf is rather tame tonight. The beach continues + and +.**\n" },
+ { "You are walking along the beach.",
+ 101, 185, 186, 0, 87, 0, 0, 0,
+"This is not a very nice beach. The coarse sand hurts my feet.****\n" },
+ { "You are walking through some ferns.",
+ 184, 186, 187, 101, 87, 0, 0, 0,
+"This is a wide field growing only ferns and small shrubs.** In the dark\n\
+it would be all to easy to stumble into a venomous snake. The ocean is\n\
+*+.\n" },
+ { "You are in a narrow canyon.",
+ 0, 0, 188, 102, 76, 0, 0, 0,
+"The steep sides here squeeze a little freshet through a gauntlet like\n\
+series of riffles and pools. The cool mountain air is refreshing.****\n" },
+ { "The canyon is much wider here.",
+ 0, 0, 102, 189, 76, 0, 0, 0,
+"The sheer rock walls rise 10 meters into darkness. A slender waterfall\n\
+careens away from the face of the rock high above and showers the gravel\n\
+floor with sparkling raindrops.** The canyon continues -\n\
+and -.\n" },
+ { "You are on the front porch of the cottage.",
+ 190, 103, 0, 0, 0, 0, 0, 0,
+"The veranda is deserted. A table and chair are the only things on the porch.\n\
+Inside the house is a parlor lighted with an elegant chandelier. The door\n\
+leads -. The lawn and fountain are +.**\n" },
+ { "You are in a palm grove.",
+ 103, 191, 192, 105, 88, 0, 0, 0,
+"Crickets are chirping in the cool night air.****\n" },
+ { "You are on a dirt road.",
+ 193, 192, 245, 103, 88, 0, 0, 0,
+"There are many bright lights +. The road cleaves the darkness +.\n\
+A small dirt road goes -, and a drive way peals off +.\n" },
+ { "You are in a field of small shrubs.",
+ 184, 186, 103, 187, 88, 0, 0, 0,
+"**Pine and other coniferous saplings are growing here. The rich brown\n\
+soil is well watered. Across a large lawn +, there is a small cottage lighted\n\
+with spot lights and gas lamps. A cool land breeze is blowing.*\n" },
+ { "The beach is pretty rocky here.",
+ 194, 105, 195, 0, 96, 0, 0, 0,
+"The tide is very low tonight. The beach is nicer *+.**\n" },
+ { "The beach is almost 10 meters wide here.",
+ 105, 183, 196, 0, 99, 0, 0, 0,
+"The sand has become more coarse and the beach steeper.****\n" },
+ { "You are in the gardens.",
+ 195, 196, 197, 105, 99, 0, 0, 0,
+"Shadowy expanses of lawn and leaf have been groomed and manicured here.\n\
+The night sky is glowing with a full moon.** A lighted path leads -.\n\
+Stone steps lead down to the beach +.\n" },
+ { "You are on the coast road.",
+ 198, 106, 163, 199, 73, 0, 0, 0,
+"The forest is dense on either side. The trees seem to be actually squeezing\n\
+together to keep us from passing. A feeling of emnity is in the air.**\n\
+The road continues - and -.\n" },
+ { "You are in the forest.",
+ 116, 107, 91, 106, 73, 0, 0, 0,
+"I suppose there are trees and ferns all around, but it is too dark to see.****\n" },
+ { "You are in the forest.",
+ 199, 108, 106, 146, 73, 0, 0, 0,
+"There are shadowy trees and ferns all around.****\n" },
+ { "You are in a copse.",
+ 142, 107, 145, 80, 0, 0, 0, 0,
+"This is a secret hidden thicket only noticeable from the beach. In the\n\
+moonlight, I can tell that someone has been digging here recently.****\n" },
+ { "You are at the tide pools.",
+ 91, 0, 114, 107, 79, 0, 0, 0,
+"These rocks and pools are the home for many sea anemones and crustaceans.\n\
+They are exposed because of the low tide. There is a beach ***+.\n" },
+ { "You are in the forest.",
+ 199, 108, 143, 0, 73, 0, 0, 0,
+"This is a shallow depression sheltered from the wind by a thick growth of \n\
+thorny shrubs. It looks like someone is camping here. There is a fire pit\n\
+with warm, crackling flames and coals here.* The beach is +.* The thorny\n\
+shrubs block the way -.\n" },
+ { "You are at the mouth of the lagoon.",
+ 200, 0, 108, 201, 74, 0, 0, 0,
+"The beach ends here where the coral reef rises to form a wide lagoon.\n\
+A path winds around the lagoon to the -.* The beach continues\n\
+on -. Only water lies +.\n" },
+ { "You are in a breadfruit grove.",
+ 202, 109, 203, 204, 77, 0, 0, 0,
+"The tall trees bend leisurely in the breeze, holding many round breadfruits\n\
+close to their large serrated leaves. There are coconut palms +,\n\
+*+, and +.\n" },
+ { "You are in a grove of mango trees.",
+ 203, 111, 205, 109, 77, 0, 0, 0,
+"The trees are not tall enough to obscure the view and the bright moonlight\n\
+makes it fairly easy to see.****\n" },
+ { "You are in a grove of coconut palms.",
+ 204, 112, 109, 206, 77, 0, 0, 0,
+"All I can see around us are trees and ominous shapes darting in and out of the\n\
+shadows.****\n" },
+ { "You are in a coconut grove.",
+ 110, 207, 208, 209, 77, 0, 0, 0,
+"There are countless trees here.****\n" },
+ { "You are in a field of pineapple.",
+ 154, 208, 210, 110, 77, 0, 0, 0,
+"The sharp leaves are cutting me to ribbons. There is a road **+.*\n" },
+ { "You are in a coconut grove.",
+ 112, 209, 110, 211, 77, 0, 0, 0,
+"There is a field of something **+.*\n" },
+ { "You are on the edge of a kiwi and pineapple field.",
+ 111, 152, 155, 110, 77, 0, 0, 0,
+"An irrigation ditch separates the two fields here. There is a road **+.*\n" },
+ { "This is a dirt road.",
+ 205, 210, 212, 111, 77, 0, 0, 0,
+"The road runs - and - here. It is very dark in the forest.**\n" },
+ { "You are in a palm grove.",
+ 206, 211, 112, 213, 77, 0, 0, 0,
+"There are trees all around us.****\n" },
+ { "You are on the edge of a small clearing.",
+ 157, 113, 157, 157, 79, 0, 0, 0,
+"The ground is rather marshy here and the darkness is intense. A swarm of\n\
+ravenous mosquitoes has descended upon you and has sent you quaking to your\n\
+knees.****\n" },
+ { "You are in the woods.",
+ 158, 115, 215, 113, 79, 0, 0, 0,
+"You have walked a long way and found only spider webs. ****\n" },
+ { "You are walking along the shore.",
+ 115, 0, 214, 114, 86, 0, 0, 0,
+"You are now about 10 meters above the surf on a gently rising cliffside.**\n\
+The land rises +. There is a beach far +.\n" },
+ { "You are just inside the entrance to the sea cave.",
+ 246, 114, 0, 0, 114, 1, 0, 0,
+"The sound of water dripping in darkness and the roar of the ocean just outside\n\
+create a very unwelcoming atmosphere inside this cave. Only on rare occasions\n\
+such as this is it possible to enter the forbidden catacombs... The cave\n\
+continues -.***\n" },
+ { "You are in a secret nook beside the road.",
+ 115, 159, 162, 91, 79, 0, 0, 0,
+"This little thicket is hidden from the road in the shadows of the forest.\n\
+From here we have a clear view of any traffic along the road. A great hollow\n\
+tree stuffed with something is nearby. The road is +.***\n" },
+ { "You are on the coast road.",
+ 215, 214, 0, 115, 86, 0, 0, 0,
+"The road turns abruptly - here, wandering deeper into the black forest.***\n" },
+ { "You are on a dirt road.",
+ 216, 116, 113, 141, 79, 0, 0, 0,
+"We are walking through a tunnel of unfriendly trees and shrubs. The tall\n\
+ones bend over the roadway and reach down with their branches to grab us.\n\
+Broad leafed plants at the roadside whisper in the darkness. Something\n\
+just darted across the road and into the bushes *+. Let's go *-.\n" },
+ { "You have discovered a hidden thicket near the road.",
+ 163, 142, 116, 106, 73, 0, 0, 0,
+"I would think it best to stay n the road. The forest seems very unfriendly\n\
+at night. The road is **+.*\n" },
+ { "You are in the living room.",
+ 0, 117, 217, 218, 0, 0, 0, 0,
+"A decorative entry with fresh flowers and wall to wall carpeting leads into\n\
+the living room here where a couch and two chairs converse with an end table.\n\
+*The exit is +.* The bedroom is +.\n" },
+ { "You are at the lagoon.",
+ 118, 0, 167, 168, 81, 0, 0, 0,
+"A small beach here is deserted except for some fishing nets. It is very\n\
+peaceful at the lagoon at night. The sound of native drums is carried on\n\
+the night breeze. There are paths leading off into darkness +,\n\
+*+, and +.\n" },
+ { "You are at the lagoon.",
+ 118, 0, 170, 166, 81, 0, 0, 0,
+"The grass near the water is moist with the refreshing evening dew. Far away,\n\
+drums reverberate in the forest.** The path continues + and +.\n" },
+ { "You are at the lagoon.",
+ 118, 0, 166, 172, 81, 0, 0, 0,
+"The path meanders through shadows of tussocks of grass, ferns, and thorny\n\
+bushes here and continues on **- and -.\n" },
+ { "You are in the woods.",
+ 219, 119, 220, 92, 81, 0, 0, 0,
+"There are plenty of ferns and thorny bushes here! Spider webs and probing\n\
+branches snare us as we stumble along in the pitch black night.****\n" },
+ { "You are on a dirt road.",
+ 220, 167, 199, 119, 74, 0, 0, 0,
+"The road winds rather close to a large lagoon here and many sedges and tall\n\
+loom in the darkness *+. The road continues - and -.\n" },
+ { "You are in the woods beside the road.",
+ 221, 120, 92, 222, 81, 0, 0, 0,
+"The forest grows darker +. The road is +.**\n" },
+ { "The road crosses the lagoon here.",
+ 222, 0, 120, 174, 81, 0, 0, 0,
+"Strange mists rising from the water engulf a rickety old enclosed bridge here.\n\
+Spider webs catch our hair as we pass through its rotting timbers. I felt\n\
+something drop on my neck. The road delves into the accursed forest\n\
+**+ and +.\n" },
+ { "You are in a coconut palm grove.",
+ 223, 121, 224, 225, 82, 0, 0, 0,
+"The tall palms are planted about 30 feet apart and the stary sky is clearly\n\
+visible above. A low growing grass carpets the ground all around. The grove\n\
+continues +.***\n" },
+ { "You are walking along a dirt road.",
+ 224, 176, 172, 121, 82, 0, 0, 0,
+"You are near misty patch of the roadway **+. The road continues -.\n" },
+ { "You are on a dirt road.",
+ 225, 177, 121, 226, 82, 0, 0, 0,
+"The road turns abruptly - here, splitting a grove of palm trees.* In the\n\
+starlight I can also discern that the road continues - toward the lagoon.*\n" },
+ { "You are on a trail running around the lagoon.",
+ 172, 0, 0, 122, 82, 0, 0, 0,
+"The dark waters brush the trail here and the path crosses an old bridge\n\
++. There is deep water + and +. The trail continues -.\n" },
+ { "This is the mouth of the lagoon.",
+ 175, 0, 122, 227, 82, 0, 0, 0,
+"The coral reef wraps around a natural bay here to create a wide lagoon which\n\
+winds tortuously inland.** A trail goes around the lagoon +.\n\
+The beach is -.\n" },
+ { "You are in a dry stream bed.",
+ 0, 125, 0, 0, 84, 0, 0, 0,
+"The dry wash drains over a tall precipice here into a turbid morass below. The\n\
+most noisome stench imaginable is wafting up to defile our nostrils. Above,\n\
+the blackness is intense and a strange mist engulfs the island.* Let's go\n\
+-.**\n" },
+ { "You are on a dirt path along the wash.",
+ 0, 128, 125, 228, 84, 0, 0, 0,
+"The trail winds along the gravel wash and delves into the forest ***+.\n" },
+ { "The thermal pools flow into a stream here.",
+ 127, 0, 229, 126, 84, 0, 0, 0,
+"The gurgling hot waters pour over boulders into a swiftly flowing\n\
+stream **+. The pools are +.\n" },
+ { "You are at the entrance to a cave.",
+ 128, 230, 126, 0, 84, 0, 0, 0,
+"A torch lights the entrance to the cave. Deep inside I can see shadows moving.\n\
+A path goes + from here. The entrance is +.**\n" },
+ { "You are in the woods.",
+ 182, 229, 182, 127, 84, 0, 0, 0,
+"Thorns tangle your every effort to proceed.* The sound of rushing water is\n\
++.**\n" },
+ { "You are walking along the beach.",
+ 139, 129, 184, 0, 99, 0, 0, 0,
+"Some dunes here progress inland and make it impossible to get very far in that\n\
+direction. The beach continues - and -.* The ocean is +.\n" },
+ { "You are in the dunes.",
+ 183, 101, 184, 129, 87, 0, 0, 0,
+"The endless rolling and pitching sand dunes are enough to make one very queasy!\n\
+The sand is cool and the stars are bright at the ocean. The only way I'm going\n\
+is ***+.\n" },
+ { "This is a lousy beach.",
+ 130, 0, 0, 0, 87, 0, 0, 0,
+"Volcanic and viciously sharp bitted grains of sand here bite like cold steel\n\
+into my tender feet. I refuse to continue on. Let's get out of here. The\n\
+beach is better +.***\n" },
+ { "You are in a field of sparse ferns.",
+ 131, 185, 187, 130, 87, 0, 0, 0,
+"The lava rock outcroppings here will support few plants. There is more \n\
+vegetation +.** The ocean is +.\n" },
+ { "You are in the woods.",
+ 131, 131, 137, 131, 87, 0, 0, 0,
+"Young trees and tall shrubs grow densely together here.\n\
+They grow thicker **+.*\n" },
+ { "The canyon is no wider than a foot here.",
+ 0, 0, 0, 132, 0, 0, 0, 0,
+"The freshet is gushing through the narrow trough, but the canyon has grown\n\
+too narrow to follow it any farther.*** I guess we'll have to go -.\n" },
+ { "You are in a narrow part of the canyon.",
+ 0, 0, 133, 232, 76, 0, 0, 0,
+"The two sheer sides are no more than a few meters apart here. There is a stone\n\
+door in the wall +. The gravelly floor runs with tiny rivulets seeping \n\
+from the ground itself.* The canyon continues - and -.\n" },
+ { "You are in the drawing room.",
+ 0, 134, 0, 0, 0, 0, 0, 0,
+"Exquisitely decorated with plants and antique furniture of superb\n\
+craftsmanship, the parlor reflects its owners impeccable taste. The tropical\n\
+night air pours in through open shutters *+. There doesn't seem \n\
+to be anybody around. A large immaculate oaken desk is visible in the\n\
+study and it even has a old fashioned telephone to complete the decor.**\n" },
+ { "You are in a palm grove.",
+ 135, 191, 233, 191, 88, 0, 0, 0,
+"Grassy rows of dew covered palms stretch as far as I can see.**\n\
+There is a road +.*\n" },
+ { "You are on a dirt road.",
+ 136, 233, 234, 135, 88, 0, 0, 0,
+"The road winds through a coconut palm grove here. It continues on - \n\
+and -.**\n" },
+ { "The road leads to several large buildings here.",
+ 235, 136, 236, 237, 88, 0, 0, 0,
+"There is a lighted clubhouse +,* a large barn and stable +, and a\n\
+garage of similar construct to the barn +.\n" },
+ { "This part of the beach is impassable.",
+ 0, 138, 0, 0, 96, 0, 0, 0,
+"The see is calm tonight. The beach goes *-.**\n" },
+ { "You are in the gardens.",
+ 195, 140, 197, 138, 96, 0, 0, 0,
+"Dew beaded grass sparkles in the moonlight. Tiny lamps beside the path light\n\
+the way to the ocean ***+.\n" },
+ { "You are in the gardens.",
+ 140, 183, 197, 139, 99, 0, 0, 0,
+"Beautiful flowers and shrubs surround a lighted goldfish pond.****\n" },
+ { "You are on a stone walk in the garden.",
+ 195, 196, 238, 140, 99, 0, 0, 0,
+"The walk leads to a road **+.*\n" },
+ { "You are in the forest near the road.",
+ 198, 141, 216, 198, 73, 0, 0, 0,
+"There are many thorny bushes here!****\n" },
+ { "You are at a fork in the road.",
+ 239, 146, 141, 170, 73, 0, 0, 0,
+"Two roads come together in the darkness here. One runs -,* the other \n\
+runs - and -.\n" },
+ { "You are on a dirt path around the lagoon.",
+ 170, 147, 146, 0, 74, 0, 0, 0,
+"The still waters reflect bending palms and a stary sky. It looks like\n\
+the path runs into a clearing +. The path continues -.**\n" },
+ { "You are drowning in the lagoon.",
+ 201, 201, 147, 201, 74, 0, 0, 0,
+"I suggest you get out before you become waterlogged.****\n" },
+ { "You are in a coconut palm grove.",
+ 202, 148, 203, 204, 77, 0, 0, 0,
+"****\n" },
+ { "You are in a palm grove.",
+ 202, 149, 205, 148, 77, 0, 0, 0,
+"****\n" },
+ { "You are in a palm grove.",
+ 202, 150, 148, 206, 77, 0, 0, 0,
+"****\n" },
+ { "You are on a dirt road.",
+ 203, 155, 212, 149, 77, 0, 0, 0,
+"*This road ends here at a palm grove but continues on - for quite\n\
+some way.**\n" },
+ { "You are in a coconut palm grove.",
+ 204, 156, 150, 213, 77, 0, 0, 0,
+"****\n" },
+ { "You are in a coconut grove.",
+ 151, 219, 208, 209, 77, 0, 0, 0,
+"*The grove ends +.**\n" },
+ { "You are in a coconut grove.",
+ 152, 207, 239, 151, 77, 0, 0, 0,
+"**There is a dirt road +.*\n" },
+ { "You are in a coconut grove.",
+ 153, 207, 151, 211, 77, 0, 0, 0,
+"****\n" },
+ { "This is a dirt road.",
+ 205, 239, 212, 154, 77, 0, 0, 0,
+"The road continues - and -.**\n" },
+ { "You are in a coconut grove.",
+ 153, 209, 153, 213, 77, 0, 0, 0,
+"****\n" },
+ { "You are in the woods near the road.",
+ 205, 210, 212, 155, 77, 0, 0, 0,
+"There are many thorny bushes here!****\n" },
+ { "You are in a coconut grove.",
+ 213, 213, 156, 234, 88, 0, 0, 0,
+"***The grove ends in a clearing +.\n" },
+ { "You are walking along some high cliffs.",
+ 162, 0, 0, 159, 86, 0, 0, 0,
+"The island bends sharply + here with high cliffs -\n\
+and -. The cliffs are lower +.\n" },
+ { "You are at the coast road turn around.",
+ 0, 162, 0, 158, 90, 0, 0, 0,
+"The coast road ends here in a lookout with a view of the ocean.\n\
+Far below, the waves crash against the rocks.\n\
+****\n" },
+ { "You are in the woods near the road.",
+ 216, 163, 216, 198, 79, 0, 257, 0,
+"These thorny bushes are killing me.****\n" },
+ { "You are in the kitchen.",
+ 0, 0, 0, 165, 0, 0, 0, 0,
+"A small gas stove and a refrigerator are all the only appliances here. The\n\
+gas oven has been left on and the whole room is reeking with natural gas.\n\
+One spark from a match and.... The door out is ***+.\n" },
+ { "You are in the bedroom.",
+ 0, 0, 165, 0, 0, 0, 0, 0,
+"A soft feather comforter on top of layers of Answer blankets make this a very\n\
+luxurious place to sleep indeed. There are also some end tables and a dresser\n\
+here.** The living room is +.*\n" },
+ { "You are in the woods.",
+ 207, 169, 220, 221, 81, 0, 0, 0,
+"The darkness is intense, but there seems to be a clearing +.***\n" },
+ { "You are in the woods near the road.",
+ 219, 170, 239, 169, 81, 0, 0, 0,
+"*As far as I can tell, there are two roads + and +.*\n" },
+ { "You are in the woods.",
+ 207, 171, 219, 222, 81, 0, 0, 0,
+"The spider webs thin out and the forest is clearer +.***\n" },
+ { "You are on the lagoon's inland finger.",
+ 0, 172, 171, 172, 81, 0, 0, 0,
+"It is impossible to follow the lagoon any farther inland because of sharp\n\
+and very painful sedges.* The road is +.**\n" },
+ { "You are in a grassy coconut grove.",
+ 240, 173, 224, 241, 82, 0, 0, 0,
+"The tall palms provide a ghostly canopy for the sandy ground covering.****\n" },
+ { "You are near the lagoon's inland finger.",
+ 0, 174, 0, 173, 82, 0, 0, 0,
+"Very sharp sedges make it impossible to follow the lagoon any farther inland.\n\
+*There is a road +.**\n" },
+ { "You are on a dirt road.",
+ 241, 175, 173, 226, 82, 0, 0, 0,
+"The road winds through a coconut grove here and continues - and -.**\n" },
+ { "You are in the woods near the road.",
+ 226, 226, 175, 226, 82, 0, 0, 0,
+"**The road is +.*\n" },
+ { "This is a beach?",
+ 227, 227, 177, 0, 82, 0, 0, 0,
+"Hard jagged rocks that pierce with every footstep hardly comprise a beach.**\n\
+Let's go -.*\n" },
+ { "The trail is lost in the woods here.",
+ 241, 241, 179, 241, 84, 0, 0, 0,
+"The trail goes **-.*\n" },
+ { "You are on the bank of a stream.",
+ 182, 0, 242, 180, 84, 0, 0, 0,
+"The stream falls over several small boulders here and continues on **-.*\n" },
+ { "You are just inside the cave.",
+ 181, 267, 0, 0, 0, 0, 0, 0,
+"A steamy hot breath is belching from the depths of the earth within.* The\n\
+cave continues -.**\n" },
+ { "You are just inside the cave entrance.",
+ 274, 0, 0, 0, 0, 0, 0, 0,
+"The air is hot and sticky inside. The cave continues -. There is a \n\
+stone door in the wall +. A wooden sign in the dust warns in old elven\n\
+runes, \"GSRF KDIRE NLVEMP!\".**\n" },
+ { "You are at the edge of a huge chasm.",
+ 0, 0, 189, 0, 76, 0, 0, 0,
+"Several hundred feet down I can see the glimmer of placid water. The\n\
+rivulets drain over the edge and trickle down into the depths. It is \n\
+impossible to climb down.** The canyon continues -.*\n" },
+ { "You are on a dirt road.",
+ 192, 241, 240, 191, 88, 0, 0, 0,
+"The road winds through a coconut grove here. The road continues on into the\n\
+shadows - and -.**\n" },
+ { "You are in a coconut palm grove near the road.",
+ 193, 233, 213, 192, 88, 0, 0, 0,
+"***The road is +.\n" },
+ { "You are at the clubhouse.",
+ 0, 193, 0, 0, 0, 0, 0, 0,
+"The clubhouse is built over the most inland part of the lagoon. Tropical\n\
+bananas and fragrant frangipani grow along the grassy shore. Walking across\n\
+the short wooden bridge, we enter. Along one wall is a bar crowded with people.\n\
+The restaurant and disco dance floor are filled to capacity. A rock group\n\
+electrocutes itself to the satisfaction of the audience.****\n" },
+ { "You are in the stables.",
+ 0, 0, 0, 193, 0, 0, 0, 0,
+"Neighing horses snacking on hay and oats fill the stalls on both sides of\n\
+the barn. It is rather warm in here but that is not the most offensive\n\
+part.****\n" },
+ { "You are in the old garage.",
+ 0, 0, 193, 0, 0, 0, 0, 0,
+"This is an old wooden building of the same vintage as the stables. Beneath\n\
+a sagging roof stand gardening tools and greasy rags. Parked in the center\n\
+is an underpowered Plymouth Volare' with a red and white striped golf cart\n\
+roof. ****\n" },
+ { "You are on a dirt road.",
+ 197, 197, 243, 197, 85, 0, 0, 0,
+"The road leads to a formal garden laced with lighted stone walks and tropical\n\
+flowers and trees.** The road continues -. A walk leads -.\n" },
+ { "You are on a dirt road.",
+ 210, 199, 198, 220, 73, 0, 0, 0,
+"The road runs - and -.**\n" },
+ { "You are in a coconut grove near the road.",
+ 234, 223, 234, 233, 88, 0, 0, 0,
+"***The road is +.\n" },
+ { "You are on a dirt road.",
+ 233, 225, 223, 226, 82, 0, 0, 0,
+"The road continues - and -.**\n" },
+ { "The stream plummets over a cliff here.",
+ 182, 0, 0, 229, 84, 0, 0, 0,
+"Falling 10 agonizing meters into darkness, only droplets of the stream must\n\
+be left to dance off the floor below. There is no way down, even with a\n\
+strong rope. ****\n" },
+ { "You are on a dirt road.",
+ 0, 0, 244, 238, 85, 0, 0, 0,
+"**The road continues - and -.\n" },
+ { "You are on a dirt road.",
+ 0, 245, 0, 243, 88, 0, 0, 0,
+"*The road continues -* and -.\n" },
+ { "You are on a dirt road.",
+ 244, 234, 213, 136, 88, 0, 0, 0,
+"The road goes -* and *-.\n" },
+ { "You are in a low passage.",
+ 247, 160, 0, 0, 0, 0, 0, 0,
+"The ceiling here sparkles with iridiscent gems and minerals. Colorful starfish\n\
+and sea anemones cling to the slippery walls and floor. The passage continues\n\
++.***\n" },
+ { "The walls are very close together here.",
+ 248, 246, 0, 0, 0, 0, 0, 0,
+"I can barely squeeze through the jagged opening. Slimy sea weeds provide\n\
+no footing at all. This tunnel seems to be an ancient lava tube. There is\n\
+a large room +.***\n" },
+ { "You are in the cathedral room.",
+ 249, 247, 250, 251, 0, 0, 0, 0,
+"Your light casts ghostly shadows on the walls but cannot pierce the \n\
+engulfing darkness overhead. The sound of water dripping echoes in the void.\n\
+*I can see no passages leading out of this room.*** \n" },
+ { "You are walking through a very round tunnel.",
+ 252, 248, 0, 0, 252, 1, 0, 0,
+"The round walls of this tunnel are amazingly smooth to the touch. A little\n\
+trickle of water flows down the center. The tunnel climbs steadily +.\n\
+There is a large room +.**\n" },
+ { "You are in the cathedral anteroom.",
+ 0, 0, 0, 248, 253, 1, 0, 0,
+"This small chamber with a flat stone floor is to one side of the cathedral \n\
+room. We appear to be at the bottom of a tall narrow shaft. There are many \n\
+puddles of water here. A staircase hewn from solid rock and black lava \n\
+leads up.*** The cathedral room is -.\n" },
+ { "You are in a wide chamber.",
+ 0, 0, 248, 254, 0, 0, 0, 0,
+"Water is sprinkling from the ceiling here. A shallow pool populated by a \n\
+myriad of blind white creatures sparkles in your light. Tiny shrimp and\n\
+crabs scurry away, frightened by the blinding rays.** The cave \n\
+continues + and +.\n" },
+ { "You are at the top of a sloping passage.",
+ 0, 249, 255, 256, 257, 1, 249, 0,
+"There is much algae growing here, both green and brown specimens. I suspect\n\
+that we are near the high tide zone, but no light can get in here. The walls\n\
+glisten with shiny minerals.** A hallway here runs + and -.\n" },
+ { "You are in an elaborately tiled room.",
+ 0, 0, 258, 0, 0, 0, 250, 0,
+"Large colorful tiles plate the floor and walls. The ceiling is a mosaic\n\
+of gems set in gold. Hopefully it is only our footsteps that are echoing in\n\
+this hollow chamber.** The room continues -. A stone staircase leads\n\
+down.*\n" },
+ { "You are at a dead end.",
+ 0, 0, 251, 0, 0, 0, 0, 0,
+"The walls here are alive with dark mussels. They click their shells menacingly\n\
+if we disturb them.** The only exit is +.*\n" },
+ { "The tunnel is very low here.",
+ 0, 0, 259, 252, 0, 0, 0, 0,
+"You practically have to crawl on your knees to pass through this opening. The\n\
+air is stiflingly damp, but you can't hear any sounds of water dripping.**\n\
+The crawlspace continues -. The tunnel seems wider +.\n" },
+ { "This is the supply room.",
+ 0, 0, 252, 0, 0, 0, 0, 0,
+"Picks and shovels line the walls here, as well as hard hats, boxes of\n\
+dynamite, and a cartload of very high grade gold and silver ore.** \n\
+A tunnel leads off +.*\n" },
+ { "You have found a secret entrance to the catacombs",
+ 0, 0, 0, 0, 216, 1, 252, 0,
+"Below is a wet, seaweed covered floor. Above is a way out.****\n" },
+ { "You are in the catacombs.",
+ 0, 0, 260, 253, 0, 0, 0, 0,
+"Ornate tombs and piles of treasure line the walls. Long spears with many\n\
+blades, fine swords and coats of mail, heaps of coins, jewelry, pottery, \n\
+and golden statues are tribute past kings and queens.** The catacombs\n\
+continue - and -.\n" },
+ { "You are crawling on your stomach.",
+ 0, 0, 261, 255, 0, 0, 0, 0,
+"The passage is quite narrow and jagged, but the rock is no longer lava.\n\
+It appears to be a form of granite.** The crawlspace continues -, \n\
+but I would just as soon go -.\n" },
+ { "You are in the Sepulcher.",
+ 0, 0, 0, 258, 0, 0, 0, 0,
+"A single tomb is here. Encrusted with diamonds and opals, and secured with \n\
+straps of a very hard, untarnished silver, this tomb must be of a great king.\n\
+Vases overflowing with gold coins stand nearby. A line of verse on the wall\n\
+reads, \"Three he made and gave them to his daughters.\"****\n" },
+ { "The passage is wider here.",
+ 0, 0, 0, 259, 0, 0, 262, 0,
+"A ladder goes down into darkness here.*** A small crawlspace goes -.\n" },
+ { "You are at the bottom of a ladder.",
+ 0, 0, 0, 0, 261, 1, 263, 0,
+"This is a narrow platform to rest on before we continue either up or down this\n\
+rickety wooden ladder.****\n" },
+ { "You are standing in several inches of water.",
+ 264, 0, 265, 266, 262, 1, 0, 0,
+"This seems to be a working mine. Many different tunnels wander off following\n\
+glowing veins of precious metal. The floor is flooded here since we must\n\
+be nearly at sea level. A ladder leads up.****\n" },
+ { "The tunnel here is blocked by broken rocks.",
+ 0, 263, 0, 0, 0, 0, 0, 0,
+"The way is blocked, but if you had some dynamite, we might be able to blast our\n\
+way through.* The passage goes -.**\n" },
+ { "The tunnel is too flooded to proceed.",
+ 0, 0, 0, 263, 0, 0, 0, 0,
+"Hidden shafts could swallow us if we tried to continue on down this tunnel.\n\
+The flooding is already up to my waist. Large crystals overhead shimmer\n\
+rainbows of reflected light.*** Let's go -.\n" },
+ { "The mine is less flooded here.",
+ 0, 0, 263, 0, 0, 0, 0, 0,
+"A meandering gold laden vein of quartz and blooming crystals of diamonds\n\
+and topaz burst from the walls of the cave. A passage goes -.***\n" },
+ { "You are inside the cave.",
+ 230, 268, 0, 0, 0, 0, 0, 0,
+"A hot steam swirls around our heads, and the walls are warm to the touch.\n\
+The trail winds - and -.**\n" },
+ { "You are in a rather large chamber.",
+ 267, 0, 0, 269, 0, 0, 269, 0,
+"Beds of ferns and palm leaves make several cozy nests along the walls. In the\n\
+center of the room is a throne of gold and silver.*** A passageway leads\n\
+down and +.\n" },
+ { "You are walking along the edge of a huge abyss.",
+ 0, 0, 268, 0, 268, 1, 270, 0,
+"Steam is rising in great clouds from the immeasurable depths. A very narrow\n\
+trail winds down.** There is a tunnel -.*\n" },
+ { "You are on the edge of a huge abyss.",
+ 0, 0, 0, 0, 269, 1, 271, 0,
+"The trail winds farther down.****\n" },
+ { "You are winding your way along the abyss.",
+ 0, 0, 0, 0, 270, 1, 272, 0,
+"The trail continues up and down.****\n" },
+ { "You are on a wide shelf near the steamy abyss.",
+ 0, 273, 0, 0, 271, 1, 0, 0,
+"The stifling hot cave seems even hotter to me, staring down into this misty \n\
+abyss. A trail winds up.* A passageway leads -.**\n" },
+ { "You are in a wide tunnel leading to a fuming abyss.",
+ 272, 274, 0, 0, 0, 0, 0, 0,
+"The passageway winds through many beautiful formations of crystals and\n\
+sparkling minerals. The tunnel continues - and -.**\n" },
+ { "You are in a tunnel.",
+ 273, 231, 0, 0, 0, 0, 0, 0,
+"It is very warm in here. The smell of steam and hot rocks permeates the place.\n\
+The cave continues - and -.**\n" },
+ { "You are at the bottom of a pit.",
+ 0, 0, 0, 0, 232, 0, 0, 0,
+"At the top of the pit, a single star can be seen in the night sky. There\n\
+doesn't appear to be any way to get out without a rope. I don't remember\n\
+how we got here.****\n" },
+};
diff --git a/battlestar/nightobjs.c b/battlestar/nightobjs.c
new file mode 100644
index 00000000..43de722f
--- /dev/null
+++ b/battlestar/nightobjs.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)nightobjs.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+struct objs nightobjs[] = {
+ { 218, PAJAMAS },
+ { 235, NATIVE },
+ { 92, PAPAYAS },
+ { 92, PINEAPPLE },
+ { 92, KIWI },
+ { 92, MANGO },
+ { 92, NATIVE },
+ { 92, MAN },
+ { 181, LAMPON },
+ { 236, LAMPON },
+ { 92, LAMPON },
+ { 216, WOODSMAN },
+ { 216, DEADWOOD },
+ { 216, MALLET },
+ { 168, WOODSMAN },
+ { 168, DEADWOOD },
+ { 168, MALLET },
+ { 170, WOODSMAN },
+ { 170, DEADWOOD },
+ { 170, MALLET },
+ { 124, SHIELD },
+ { 124, HALBERD },
+ { 124, ELF },
+ { 144, SHIELD },
+ { 144, HALBERD },
+ { 144, ELF },
+ { 113, SHIELD },
+ { 113, HALBERD },
+ { 113, ELF },
+ { 161, SHIELD },
+ { 161, HALBERD },
+ { 161, ELF },
+ { 169, SHIELD },
+ { 169, HALBERD },
+ { 169, ELF },
+ { 182, SHIELD },
+ { 182, HALBERD },
+ { 182, ELF },
+ { 198, SHIELD },
+ { 198, HALBERD },
+ { 198, ELF },
+ { 212, SHIELD },
+ { 212, HALBERD },
+ { 212, ELF },
+ { 216, SHIELD },
+ { 216, HALBERD },
+ { 216, ELF },
+ { 226, SHIELD },
+ { 226, HALBERD },
+ { 226, ELF },
+ { 228, SHIELD },
+ { 228, HALBERD },
+ { 228, ELF },
+ { 68, CYLON },
+ { 144, SHOVEL },
+ { 249, FOOT },
+ { 250, FOOT },
+ { 93, PAPAYAS },
+ 0
+};
diff --git a/battlestar/parse.c b/battlestar/parse.c
new file mode 100644
index 00000000..d4101e65
--- /dev/null
+++ b/battlestar/parse.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)parse.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+wordinit()
+{
+ register struct wlist *w;
+
+ for (w = wlist; w->string; w++)
+ install(w);
+}
+
+hash(s)
+ register char *s;
+{
+ register hashval = 0;
+
+ while (*s) {
+ hashval += *s++;
+ hashval *= HASHMUL;
+ hashval &= HASHMASK;
+ }
+ return hashval;
+}
+
+struct wlist *
+lookup(s)
+ char *s;
+{
+ register struct wlist *wp;
+
+ for (wp = hashtab[hash(s)]; wp != NULL; wp = wp->next)
+ if (*s == *wp->string && strcmp(s, wp->string) == 0)
+ return wp;
+ return NULL;
+}
+
+install(wp)
+ register struct wlist *wp;
+{
+ int hashval;
+
+ if (lookup(wp->string) == NULL) {
+ hashval = hash(wp->string);
+ wp->next = hashtab[hashval];
+ hashtab[hashval] = wp;
+ } else
+ printf("Multiply defined %s.\n", wp->string);
+}
+
+parse()
+{
+ register struct wlist *wp;
+ register n;
+
+ wordnumber = 0; /* for cypher */
+ for (n = 0; n <= wordcount; n++) {
+ if ((wp = lookup(words[n])) == NULL) {
+ wordvalue[n] = -1;
+ wordtype[n] = -1;
+ } else {
+ wordvalue[n] = wp -> value;
+ wordtype[n] = wp -> article;
+ }
+ }
+}
diff --git a/battlestar/pathnames.h b/battlestar/pathnames.h
new file mode 100644
index 00000000..f38c354f
--- /dev/null
+++ b/battlestar/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 6/1/90
+ */
+
+#define _PATH_SCORE "/var/games/battlestar.log"
diff --git a/battlestar/room.c b/battlestar/room.c
new file mode 100644
index 00000000..f6c9418d
--- /dev/null
+++ b/battlestar/room.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)room.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+writedes()
+{
+ int compass;
+ register char *p;
+ register c;
+
+ printf("\n\t%s\n", location[position].name);
+ if (beenthere[position] < 3) {
+ compass = NORTH;
+ for (p = location[position].desc; c = *p++;)
+ if (c != '-' && c != '*' && c != '+')
+ putchar(c);
+ else {
+ if (c != '*')
+ printf(truedirec(compass, c));
+ compass++;
+ }
+ }
+}
+
+printobjs()
+{
+ register unsigned int *p = location[position].objects;
+ register n;
+
+ printf("\n");
+ for (n = 0; n < NUMOFOBJECTS; n++)
+ if (testbit(p, n) && objdes[n])
+ puts(objdes[n]);
+}
+
+whichway(here)
+struct room here;
+{
+ switch(direction) {
+
+ case NORTH:
+ left = here.west;
+ right = here.east;
+ ahead = here.north;
+ back = here.south;
+ break;
+
+ case SOUTH:
+ left = here.east;
+ right = here.west;
+ ahead = here.south;
+ back = here.north;
+ break;
+
+ case EAST:
+ left = here.north;
+ right = here.south;
+ ahead = here.east;
+ back = here.west;
+ break;
+
+ case WEST:
+ left = here.south;
+ right = here.north;
+ ahead = here.west;
+ back = here.east;
+ break;
+
+ }
+}
+
+char *
+truedirec(way, option)
+int way;
+char option;
+{
+ switch(way) {
+
+ case NORTH:
+ switch(direction) {
+ case NORTH:
+ return("ahead");
+ case SOUTH:
+ return(option == '+' ? "behind you" : "back");
+ case EAST:
+ return("left");
+ case WEST:
+ return("right");
+ }
+
+ case SOUTH:
+ switch(direction) {
+ case NORTH:
+ return(option == '+' ? "behind you" : "back");
+ case SOUTH:
+ return("ahead");
+ case EAST:
+ return("right");
+ case WEST:
+ return("left");
+ }
+
+ case EAST:
+ switch(direction) {
+ case NORTH:
+ return("right");
+ case SOUTH:
+ return("left");
+ case EAST:
+ return("ahead");
+ case WEST:
+ return(option == '+' ? "behind you" : "back");
+ }
+
+ case WEST:
+ switch(direction) {
+ case NORTH:
+ return("left");
+ case SOUTH:
+ return("right");
+ case EAST:
+ return(option == '+' ? "behind you" : "back");
+ case WEST:
+ return("ahead");
+ }
+
+ default:
+ printf("Error: room %d. More than four directions wanted.", position);
+ return("!!");
+ }
+}
+
+newway(thisway)
+int thisway;
+{
+ switch(direction){
+
+ case NORTH:
+ switch(thisway){
+ case LEFT:
+ direction = WEST;
+ break;
+ case RIGHT:
+ direction = EAST;
+ break;
+ case BACK:
+ direction = SOUTH;
+ break;
+ }
+ break;
+ case SOUTH:
+ switch(thisway){
+ case LEFT:
+ direction = EAST;
+ break;
+ case RIGHT:
+ direction = WEST;
+ break;
+ case BACK:
+ direction = NORTH;
+ break;
+ }
+ break;
+ case EAST:
+ switch(thisway){
+ case LEFT:
+ direction = NORTH;
+ break;
+ case RIGHT:
+ direction = SOUTH;
+ break;
+ case BACK:
+ direction = WEST;
+ break;
+ }
+ break;
+ case WEST:
+ switch(thisway){
+ case LEFT:
+ direction = SOUTH;
+ break;
+ case RIGHT:
+ direction = NORTH;
+ break;
+ case BACK:
+ direction = EAST;
+ break;
+ }
+ break;
+ }
+}
diff --git a/battlestar/save.c b/battlestar/save.c
new file mode 100644
index 00000000..4c049ae2
--- /dev/null
+++ b/battlestar/save.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)save.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+restore()
+{
+ char *getenv();
+ char *home;
+ char home1[100];
+ register int n;
+ int tmp;
+ register FILE *fp;
+
+ home = getenv("HOME");
+ strcpy(home1, home);
+ strcat(home1, "/Bstar");
+ if ((fp = fopen(home1, "r")) == 0) {
+ perror(home1);
+ return;
+ }
+ fread(&WEIGHT, sizeof WEIGHT, 1, fp);
+ fread(&CUMBER, sizeof CUMBER, 1, fp);
+ fread(&clock, sizeof clock, 1, fp);
+ fread(&tmp, sizeof tmp, 1, fp);
+ location = tmp ? dayfile : nightfile;
+ for (n = 1; n <= NUMOFROOMS; n++) {
+ fread(location[n].link, sizeof location[n].link, 1, fp);
+ fread(location[n].objects, sizeof location[n].objects, 1, fp);
+ }
+ fread(inven, sizeof inven, 1, fp);
+ fread(wear, sizeof wear, 1, fp);
+ fread(injuries, sizeof injuries, 1, fp);
+ fread(notes, sizeof notes, 1, fp);
+ fread(&direction, sizeof direction, 1, fp);
+ fread(&position, sizeof position, 1, fp);
+ fread(&time, sizeof time, 1, fp);
+ fread(&fuel, sizeof fuel, 1, fp);
+ fread(&torps, sizeof torps, 1, fp);
+ fread(&carrying, sizeof carrying, 1, fp);
+ fread(&encumber, sizeof encumber, 1, fp);
+ fread(&rythmn, sizeof rythmn, 1, fp);
+ fread(&followfight, sizeof followfight, 1, fp);
+ fread(&ate, sizeof ate, 1, fp);
+ fread(&snooze, sizeof snooze, 1, fp);
+ fread(&meetgirl, sizeof meetgirl, 1, fp);
+ fread(&followgod, sizeof followgod, 1, fp);
+ fread(&godready, sizeof godready, 1, fp);
+ fread(&win, sizeof win, 1, fp);
+ fread(&wintime, sizeof wintime, 1, fp);
+ fread(&matchlight, sizeof matchlight, 1, fp);
+ fread(&matchcount, sizeof matchcount, 1, fp);
+ fread(&loved, sizeof loved, 1, fp);
+ fread(&pleasure, sizeof pleasure, 1, fp);
+ fread(&power, sizeof power, 1, fp);
+ fread(&ego, sizeof ego, 1, fp);
+}
+
+save()
+{
+ char *getenv();
+ char *home;
+ char home1[100];
+ register int n;
+ int tmp;
+ FILE *fp;
+
+ home = getenv("HOME");
+ strcpy(home1, home);
+ strcat(home1, "/Bstar");
+ if ((fp = fopen(home1, "w")) == 0) {
+ perror(home1);
+ return;
+ }
+ printf("Saved in %s.\n", home1);
+ fwrite(&WEIGHT, sizeof WEIGHT, 1, fp);
+ fwrite(&CUMBER, sizeof CUMBER, 1, fp);
+ fwrite(&clock, sizeof clock, 1, fp);
+ tmp = location == dayfile;
+ fwrite(&tmp, sizeof tmp, 1, fp);
+ for (n = 1; n <= NUMOFROOMS; n++) {
+ fwrite(location[n].link, sizeof location[n].link, 1, fp);
+ fwrite(location[n].objects, sizeof location[n].objects, 1, fp);
+ }
+ fwrite(inven, sizeof inven, 1, fp);
+ fwrite(wear, sizeof wear, 1, fp);
+ fwrite(injuries, sizeof injuries, 1, fp);
+ fwrite(notes, sizeof notes, 1, fp);
+ fwrite(&direction, sizeof direction, 1, fp);
+ fwrite(&position, sizeof position, 1, fp);
+ fwrite(&time, sizeof time, 1, fp);
+ fwrite(&fuel, sizeof fuel, 1, fp);
+ fwrite(&torps, sizeof torps, 1, fp);
+ fwrite(&carrying, sizeof carrying, 1, fp);
+ fwrite(&encumber, sizeof encumber, 1, fp);
+ fwrite(&rythmn, sizeof rythmn, 1, fp);
+ fwrite(&followfight, sizeof followfight, 1, fp);
+ fwrite(&ate, sizeof ate, 1, fp);
+ fwrite(&snooze, sizeof snooze, 1, fp);
+ fwrite(&meetgirl, sizeof meetgirl, 1, fp);
+ fwrite(&followgod, sizeof followgod, 1, fp);
+ fwrite(&godready, sizeof godready, 1, fp);
+ fwrite(&win, sizeof win, 1, fp);
+ fwrite(&wintime, sizeof wintime, 1, fp);
+ fwrite(&matchlight, sizeof matchlight, 1, fp);
+ fwrite(&matchcount, sizeof matchcount, 1, fp);
+ fwrite(&loved, sizeof loved, 1, fp);
+ fwrite(&pleasure, sizeof pleasure, 1, fp);
+ fwrite(&power, sizeof power, 1, fp);
+ fwrite(&ego, sizeof ego, 1, fp);
+}
diff --git a/battlestar/words.c b/battlestar/words.c
new file mode 100644
index 00000000..94eb3adb
--- /dev/null
+++ b/battlestar/words.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)words.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+struct wlist wlist[] = {
+ { "knife", KNIFE, OBJECT },
+ { "sword", SWORD, NOUNS },
+ { "scabbard", SWORD, OBJECT },
+ { "fine", SWORD, OBJECT },
+ { "two-handed", TWO_HANDED, OBJECT },
+ { "cleaver", CLEAVER, OBJECT },
+ { "broadsword", BROAD, OBJECT },
+ { "mail", MAIL, OBJECT },
+ { "coat", MAIL, OBJECT },
+ { "helmet", HELM, OBJECT },
+ { "shield", SHIELD, OBJECT },
+ { "maid", MAID, OBJECT },
+ { "maid's", MAID, OBJECT },
+ { "body", BODY, NOUNS },
+ { "viper", VIPER, OBJECT },
+ { "lamp", LAMPON, OBJECT },
+ { "lantern", LAMPON, OBJECT },
+ { "shoes", SHOES, OBJECT },
+ { "pajamas", PAJAMAS, OBJECT },
+ { "robe", ROBE, OBJECT },
+ { "amulet", AMULET, NOUNS },
+ { "medallion", MEDALION, NOUNS },
+ { "talisman", TALISMAN, NOUNS },
+ { "woodsman", DEADWOOD, OBJECT },
+ { "woodsman's", DEADWOOD, OBJECT },
+ { "mallet", MALLET, OBJECT },
+ { "laser", LASER, OBJECT },
+ { "pistol", LASER, OBJECT },
+ { "blaster", LASER, OBJECT },
+ { "gun", LASER, OBJECT },
+ { "goddess", NORMGOD, NOUNS },
+ { "grenade", GRENADE, OBJECT },
+ { "chain", CHAIN, OBJECT },
+ { "rope", ROPE, OBJECT },
+ { "levis", LEVIS, OBJECT },
+ { "pants", LEVIS, OBJECT },
+ { "mace", MACE, OBJECT },
+ { "shovel", SHOVEL, OBJECT },
+ { "halberd", HALBERD, OBJECT },
+ { "compass", COMPASS, OBJECT },
+ { "elf", ELF, OBJECT },
+ { "coins", COINS, OBJECT },
+ { "matches", MATCHES, OBJECT },
+ { "match", MATCHES, OBJECT },
+ { "book", MATCHES, OBJECT },
+ { "man", MAN, NOUNS },
+ { "papayas", PAPAYAS, OBJECT },
+ { "pineapple", PINEAPPLE, OBJECT },
+ { "kiwi", KIWI, OBJECT },
+ { "coconuts", COCONUTS, OBJECT },
+ { "mango", MANGO, OBJECT },
+ { "ring", RING, OBJECT },
+ { "potion", POTION, OBJECT },
+ { "bracelet", BRACELET, OBJECT },
+ { "timer", TIMER, NOUNS },
+ { "bomb", BOMB, OBJECT },
+ { "warhead", BOMB, OBJECT },
+ { "girl", NATIVE, NOUNS },
+ { "native", NATIVE, NOUNS },
+ { "horse", HORSE, OBJECT },
+ { "stallion", HORSE, OBJECT },
+ { "car", CAR, OBJECT },
+ { "volare", CAR, OBJECT },
+ { "pot", POT, OBJECT },
+ { "jewels", POT, OBJECT },
+ { "bar", BAR, OBJECT },
+ { "diamond", BLOCK, OBJECT },
+ { "block", BLOCK, OBJECT },
+ { "up", UP, VERB },
+ { "u", UP, VERB },
+ { "down", DOWN, VERB },
+ { "d", DOWN, VERB },
+ { "ahead", AHEAD, VERB },
+ { "a", AHEAD, VERB },
+ { "back", BACK, VERB },
+ { "b", BACK, VERB },
+ { "right", RIGHT, VERB },
+ { "r", RIGHT, VERB },
+ { "left", LEFT, VERB },
+ { "l", LEFT, VERB },
+ { "take", TAKE, VERB },
+ { "get", TAKE, VERB },
+ { "use", USE, VERB },
+ { "look", LOOK, VERB },
+ { "lo", LOOK, VERB },
+ { "quit", QUIT, VERB },
+ { "q", QUIT, VERB },
+ { "su", SU, VERB },
+ { "drop", DROP, VERB },
+ { "draw", DRAW, VERB },
+ { "pull", DRAW, VERB },
+ { "carry", DRAW, VERB },
+ { "wear", WEARIT, VERB },
+ { "sheathe", WEARIT, VERB },
+ { "put", PUT, VERB },
+ { "buckle", PUT, VERB },
+ { "strap", PUT, VERB },
+ { "tie", PUT, VERB },
+ { "inven", INVEN, VERB },
+ { "i", INVEN, VERB },
+ { "everything", EVERYTHING, OBJECT },
+ { "all", EVERYTHING, OBJECT },
+ { "and", AND, CONJ },
+ { "kill", KILL, VERB },
+ { "fight", KILL, VERB },
+ { "ravage", RAVAGE, VERB },
+ { "rape", RAVAGE, VERB },
+ { "undress", UNDRESS, VERB },
+ { "throw", THROW, VERB },
+ { "launch", LAUNCH, VERB },
+ { "land", LANDIT, VERB },
+ { "light", LIGHT, VERB },
+ { "strike", LIGHT, VERB },
+ { "follow", FOLLOW, VERB },
+ { "chase", FOLLOW, VERB },
+ { "kiss", KISS, VERB },
+ { "love", LOVE, VERB },
+ { "fuck", LOVE, VERB },
+ { "give", GIVE, VERB },
+ { "smite", SMITE, VERB },
+ { "attack", SMITE, VERB },
+ { "swing", SMITE, VERB },
+ { "stab", SMITE, VERB },
+ { "slice", SMITE, VERB },
+ { "cut", SMITE, VERB },
+ { "hack", SMITE, VERB },
+ { "shoot", SHOOT, VERB },
+ { "blast", SHOOT, VERB },
+ { "on", ON, PREPS },
+ { "off", OFF, PREPS },
+ { "time", TIME, VERB },
+ { "sleep", SLEEP, VERB },
+ { "dig", DIG, VERB },
+ { "eat", EAT, VERB },
+ { "swim", SWIM, VERB },
+ { "drink", DRINK, VERB },
+ { "door", DOOR, NOUNS },
+ { "save", SAVE, VERB },
+ { "ride", RIDE, VERB },
+ { "mount", RIDE, VERB },
+ { "drive", DRIVE, VERB },
+ { "start", DRIVE, VERB },
+ { "score", SCORE, VERB },
+ { "points", SCORE, VERB },
+ { "bury", BURY, VERB },
+ { "jump", JUMP, VERB },
+ { "kick", KICK, VERB },
+ { "kerosene", 0, ADJS },
+ { "plumed", 0, ADJS },
+ { "ancient", 0, ADJS },
+ { "golden", 0, ADJS },
+ { "gold", 0, ADJS },
+ { "ostrich", 0, ADJS },
+ { "rusty", 0, ADJS },
+ { "old", 0, ADJS },
+ { "dented", 0, ADJS },
+ { "blue", 0, ADJS },
+ { "purple", 0, ADJS },
+ { "kingly", 0, ADJS },
+ { "the", 0, ADJS },
+ { "climb", 0, ADJS },
+ { "move", 0, ADJS },
+ { "make", 0, ADJS },
+ { "to", 0, ADJS },
+ 0
+};
diff --git a/bcd/Makefile b/bcd/Makefile
new file mode 100644
index 00000000..fef64ac8
--- /dev/null
+++ b/bcd/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 5.3 (Berkeley) 5/11/90
+
+PROG= bcd
+MAN6= bcd.0
+MLINKS= bcd.6 morse.6 bcd.6 ppt.6
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
+
diff --git a/bcd/bcd.6 b/bcd/bcd.6
new file mode 100644
index 00000000..9af59871
--- /dev/null
+++ b/bcd/bcd.6
@@ -0,0 +1,51 @@
+.\" Copyright (c) 1988 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bcd.6 6.7 (Berkeley) 6/23/90
+.\"
+.TH "BCD" 6 "June 23, 1990"
+.UC 7
+.SH NAME
+bcd \- format input as punch cards
+.br
+ppt \- format input as paper tape
+.br
+morse \- format input as morse code
+.SH SYNOPSIS
+\fBbcd\fP [string ...]
+.br
+\fBppt\fP [string ...]
+.br
+\fBmorse\fP [-s] [string ...]
+.SH DESCRIPTION
+\fIBcd\fP, \fIppt\fP and \fImorse\fP convert command line arguments, if
+provided, or standard input into a form familiar to old-timers. The
+\fI-s\fP option for morse produces dots and dashes rather than words.
diff --git a/bcd/bcd.c b/bcd/bcd.c
new file mode 100644
index 00000000..8fbee8ca
--- /dev/null
+++ b/bcd/bcd.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Steve Hayman of the Indiana University Computer Science Dept..
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)bcd.c 4.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * bcd --
+ *
+ * Read one line of standard input and produce something that looks like a
+ * punch card. An attempt to reimplement /usr/games/bcd. All I looked at
+ * was the man page.
+ *
+ * I couldn't find a BCD table handy so I wrote a shell script to deduce what
+ * the patterns were that the old bcd was using for each possible 8-bit
+ * character. These are the results -- the low order 12 bits represent the
+ * holes. (A 1 bit is a hole.) These may be wrong, but they match the old
+ * program!
+ *
+ * Steve Hayman
+ * sahayman@iuvax.cs.indiana.edu
+ * 1989 11 30
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <ctype.h>
+
+u_short holes[256] = {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406,
+ 0x812, 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300,
+ 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004,
+ 0x002, 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006,
+ 0x022, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804,
+ 0x802, 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408,
+ 0x404, 0x402, 0x402, 0x280, 0x240, 0x220, 0x210, 0x208,
+ 0x204, 0x202, 0x201, 0x082, 0x822, 0x600, 0x282, 0x30f,
+ 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802,
+ 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
+ 0x402, 0x402, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
+ 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406, 0x812,
+ 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300, 0x200,
+ 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002,
+ 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006, 0x022,
+ 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802,
+ 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
+ 0x402, 0x402, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
+ 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x30f,
+ 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802,
+ 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
+ 0x402, 0x402, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
+ 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0
+};
+
+/*
+ * i'th bit of w.
+ */
+#define bit(w,i) ((w)&(1<<(i)))
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char cardline[80];
+
+ /*
+ * The original bcd prompts with a "%" when reading from stdin,
+ * but this seems kind of silly. So this one doesn't.
+ */
+
+ if (argc > 1) {
+ while (--argc)
+ printcard(*++argv);
+ } else
+ while (fgets(cardline, sizeof(cardline), stdin))
+ printcard(cardline);
+ exit(0);
+}
+
+#define COLUMNS 48
+
+printcard(str)
+ register char *str;
+{
+ static char rowchars[] = " 123456789";
+ register int i, row;
+ register char *p;
+ char *index();
+
+ /* ruthlessly remove newlines and truncate at 48 characters. */
+ if ((p = index(str, '\n')))
+ *p = '\0';
+
+ if (strlen(str) > COLUMNS)
+ str[COLUMNS] = '\0';
+
+ /* make string upper case. */
+ for (p = str; *p; ++p)
+ if (isascii(*p) && islower(*p))
+ *p = toupper(*p);
+
+ /* top of card */
+ putchar(' ');
+ for (i = 1; i <= COLUMNS; ++i)
+ putchar('_');
+ putchar('\n');
+
+ /*
+ * line of text. Leave a blank if the character doesn't have
+ * a hole pattern.
+ */
+ p = str;
+ putchar('/');
+ for (i = 1; *p; i++, p++)
+ if (holes[*p])
+ putchar(*p);
+ else
+ putchar(' ');
+ while (i++ <= COLUMNS)
+ putchar(' ');
+ putchar('|');
+ putchar('\n');
+
+ /*
+ * 12 rows of potential holes; output a ']', which looks kind of
+ * like a hole, if the appropriate bit is set in the holes[] table.
+ * The original bcd output a '[', a backspace, five control A's,
+ * and then a ']'. This seems a little excessive.
+ */
+ for (row = 0; row <= 11; ++row) {
+ putchar('|');
+ for (i = 0, p = str; *p; i++, p++) {
+ if (bit(holes[*p], 11 - row))
+ putchar(']');
+ else
+ putchar(rowchars[row]);
+ }
+ while (i++ < COLUMNS)
+ putchar(rowchars[row]);
+ putchar('|');
+ putchar('\n');
+ }
+
+ /* bottom of card */
+ putchar('|');
+ for (i = 1; i <= COLUMNS; i++)
+ putchar('_');
+ putchar('|');
+ putchar('\n');
+}
diff --git a/caesar/Makefile b/caesar/Makefile
new file mode 100644
index 00000000..c35de8f4
--- /dev/null
+++ b/caesar/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 5.2 (Berkeley) 5/11/90
+
+PROG= caesar
+MAN6= caesar.0
+DPADD= ${LIBM}
+LDADD= -lm
+MLINKS= caesar.6 rot13.6
+
+.include <bsd.prog.mk>
diff --git a/caesar/caesar.6 b/caesar/caesar.6
new file mode 100644
index 00000000..c9d3b832
--- /dev/null
+++ b/caesar/caesar.6
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)caesar.6 5.3 (Berkeley) 11/11/90
+.\"
+.TH CAESAR 6 "November 11, 1990"
+.UC 7
+.SH NAME
+caesar \- decrypt caesar cyphers
+.SH SYNOPSIS
+.B caesar
+[
+.B rotation
+]
+.SH DESCRIPTION
+The
+.I caesar
+utility attempts to decrypt caesar cyphers using English letter frequency
+statistics.
+.I Caesar
+reads from the standard input and writes to the standard output.
+.PP
+The optional numerical argument
+.I rotation
+may be used to specify a specific rotation value.
+.PP
+The frequency (from most common to least) of English letters is as follows:
+.sp
+.RS
+ETAONRISHDLFCMUGPYWBVKXJQZ
+.RE
+.PP
+Their frequencies as a percentage are as follows:
+.sp
+.RS
+E(13), T(10.5), A(8.1), O(7.9), N(7.1), R(6.8), I(6.3), S(6.1), H(5.2),
+D(3.8), L(3.4), F(2.9), C(2.7), M(2.5), U(2.4), G(2), P(1.9), Y(1.9),
+W(1.5), B(1.4), V(.9), K(.4), X(.15), J(.13), Q(.11), Z(.07).
+.RE
+.PP
+Rotated postings to USENET and some of the databases used by the
+.IR fortune (6)
+program are rotated by 13 characters.
diff --git a/caesar/caesar.c b/caesar/caesar.c
new file mode 100644
index 00000000..2951a02c
--- /dev/null
+++ b/caesar/caesar.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Adams.
+ *
+ * Authors:
+ * Stan King, John Eldridge, based on algorithm suggested by
+ * Bob Morris
+ * 29-Sep-82
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)caesar.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <math.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#define LINELENGTH 2048
+#define ROTATE(ch, perm) \
+ isupper(ch) ? ('A' + (ch - 'A' + perm) % 26) : \
+ islower(ch) ? ('a' + (ch - 'a' + perm) % 26) : ch
+
+/*
+ * letter frequencies (taken from some unix(tm) documentation)
+ * (unix is a trademark of Bell Laboratories)
+ */
+double stdf[26] = {
+ 7.97, 1.35, 3.61, 4.78, 12.37, 2.01, 1.46, 4.49, 6.39, 0.04,
+ 0.42, 3.81, 2.69, 5.92, 6.96, 2.91, 0.08, 6.63, 8.77, 9.68,
+ 2.62, 0.81, 1.88, 0.23, 2.07, 0.06,
+};
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern int errno;
+ register int ch, dot, i, nread, winnerdot;
+ register char *inbuf;
+ int obs[26], try, winner;
+ char *malloc(), *strerror();
+
+ if (argc > 1)
+ printit(argv[1]);
+
+ if (!(inbuf = malloc(LINELENGTH))) {
+ (void)fprintf(stderr, "caesar: out of memory.\n");
+ exit(1);
+ }
+
+ /* adjust frequency table to weight low probs REAL low */
+ for (i = 0; i < 26; ++i)
+ stdf[i] = log(stdf[i]) + log(26.0 / 100.0);
+
+ /* zero out observation table */
+ bzero(obs, 26 * sizeof(int));
+
+ if ((nread = read(STDIN_FILENO, inbuf, LINELENGTH)) < 0) {
+ (void)fprintf(stderr, "caesar: %s\n", strerror(errno));
+ exit(1);
+ }
+ for (i = nread; i--;) {
+ ch = inbuf[i];
+ if (islower(ch))
+ ++obs[ch - 'a'];
+ else if (isupper(ch))
+ ++obs[ch - 'A'];
+ }
+
+ /*
+ * now "dot" the freqs with the observed letter freqs
+ * and keep track of best fit
+ */
+ for (try = winner = 0; try < 26; ++try) { /* += 13) { */
+ dot = 0;
+ for (i = 0; i < 26; i++)
+ dot += obs[i] * stdf[(i + try) % 26];
+ /* initialize winning score */
+ if (try == 0)
+ winnerdot = dot;
+ if (dot > winnerdot) {
+ /* got a new winner! */
+ winner = try;
+ winnerdot = dot;
+ }
+ }
+
+ for (;;) {
+ for (i = 0; i < nread; ++i) {
+ ch = inbuf[i];
+ putchar(ROTATE(ch, winner));
+ }
+ if (nread < LINELENGTH)
+ break;
+ if ((nread = read(STDIN_FILENO, inbuf, LINELENGTH)) < 0) {
+ (void)fprintf(stderr, "caesar: %s\n", strerror(errno));
+ exit(1);
+ }
+ }
+ exit(0);
+}
+
+printit(arg)
+ char *arg;
+{
+ register int ch, rot;
+
+ if ((rot = atoi(arg)) < 0) {
+ (void)fprintf(stderr, "caesar: bad rotation value.\n");
+ exit(1);
+ }
+ while ((ch = getchar()) != EOF)
+ putchar(ROTATE(ch, rot));
+ exit(0);
+}
diff --git a/canfield/Makefile b/canfield/Makefile
new file mode 100644
index 00000000..c077c47a
--- /dev/null
+++ b/canfield/Makefile
@@ -0,0 +1,5 @@
+# @(#)Makefile 5.1 (Berkeley) 4/8/91
+
+SUBDIR= canfield cfscores
+
+.include <bsd.subdir.mk>
diff --git a/canfield/canfield/Makefile b/canfield/canfield/Makefile
new file mode 100644
index 00000000..9992c41d
--- /dev/null
+++ b/canfield/canfield/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 5.7 (Berkeley) 4/8/91
+
+PROG= canfield
+MAN6= canfield.0
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermcap -lcompat
+HIDEGAME=hidegame
+
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/canfield/canfield/canfield.6 b/canfield/canfield/canfield.6
new file mode 100644
index 00000000..64c24d04
--- /dev/null
+++ b/canfield/canfield/canfield.6
@@ -0,0 +1,118 @@
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)canfield.6 6.5 (Berkeley) 6/23/90
+.\"
+.TH CANFIELD 6 "June 23, 1990"
+.UC 5
+.SH NAME
+canfield, cfscores \- the solitaire card game canfield
+.SH SYNOPSIS
+.B canfield
+.br
+.B cfscores
+.SH DESCRIPTION
+.PP
+If you have never played solitaire before, it is recommended
+that you consult a solitaire instruction book. In
+Canfield, tableau cards may be built on each other downward
+in alternate colors. An entire pile must be moved as a unit
+in building. Top cards of the piles are available
+to be played on foundations, but never into empty spaces.
+.PP
+Spaces must be filled from the stock. The top card of
+the stock also is available to be played on foundations or
+built on tableau piles. After the stock is exhausted,
+tableau spaces may be filled from the talon and the player may
+keep them open until he wishes to use them.
+.PP
+Cards are dealt from the hand to the talon by threes
+and this repeats until there are no more cards in the hand
+or the player quits. To have cards dealt onto the talon the
+player types 'ht' for his move. Foundation base cards are
+also automatically moved to the foundation when they become
+available.
+.PP
+The command 'c' causes
+.I canfield
+to maintain card counting statistics
+on the bottom of the screen.
+When properly used this can greatly increase one's chances of
+winning.
+.PP
+The rules for betting are somewhat less strict than
+those used in the official version of the game.
+The initial deal costs $13.
+You may quit at this point or inspect the game.
+Inspection costs $13 and allows you to make as many
+moves as possible without moving any cards from your hand
+to the talon.
+(The initial deal places three cards on the talon;
+if all these cards are used,
+three more are made available.)
+Finally, if the game seems interesting,
+you must pay the final installment of $26.
+At this point you are
+credited at the rate of $5 for each card on the foundation;
+as the game progresses you are credited with $5 for each
+card that is moved to the foundation.
+Each run through the hand after the first costs $5.
+The card counting feature
+costs $1 for each unknown card that is identified.
+If the information is toggled on,
+you are only charged for cards
+that became visible since it was last turned on.
+Thus the maximum cost of information is $34.
+Playing time is charged at a rate of $1 per minute.
+.PP
+With no arguments, the program
+.I cfscores
+prints out the current status of your canfield account.
+If a user name is specified,
+it prints out the status of their canfield account.
+If the
+.B \-a
+flag is specified,
+it prints out the canfield accounts for all users that have
+played the game since the database was set up.
+.SH FILES
+/usr/games/canfield the game itself
+.br
+/usr/games/cfscores the database printer
+.br
+/usr/games/lib/cfscores the database of scores
+.SH BUGS
+It is impossible to cheat.
+.SH AUTHORS
+Originally written: Steve Levine
+.br
+Further random hacking by: Steve Feldman, Kirk McKusick,
+Mikey Olson, and Eric Allman.
diff --git a/canfield/canfield/canfield.c b/canfield/canfield/canfield.c
new file mode 100644
index 00000000..e598fe86
--- /dev/null
+++ b/canfield/canfield/canfield.c
@@ -0,0 +1,1705 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)canfield.c 5.11 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * The canfield program
+ *
+ * Authors:
+ * Originally written: Steve Levine
+ * Converted to use curses and debugged: Steve Feldman
+ * Card counting: Kirk McKusick and Mikey Olson
+ * User interface cleanups: Eric Allman and Kirk McKusick
+ * Betting by Kirk McKusick
+ */
+
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <curses.h>
+#include <ctype.h>
+#include "pathnames.h"
+
+#define decksize 52
+#define originrow 0
+#define origincol 0
+#define basecol 1
+#define boxcol 42
+#define tboxrow 2
+#define bboxrow 17
+#define movecol 43
+#define moverow 16
+#define msgcol 43
+#define msgrow 15
+#define titlecol 30
+#define titlerow 0
+#define sidecol 1
+#define ottlrow 6
+#define foundcol 11
+#define foundrow 3
+#define stockcol 2
+#define stockrow 8
+#define fttlcol 10
+#define fttlrow 1
+#define taloncol 2
+#define talonrow 13
+#define tabrow 8
+#define ctoprow 21
+#define cbotrow 23
+#define cinitcol 14
+#define cheightcol 1
+#define cwidthcol 4
+#define handstatrow 21
+#define handstatcol 7
+#define talonstatrow 22
+#define talonstatcol 7
+#define stockstatrow 23
+#define stockstatcol 7
+#define Ace 1
+#define Jack 11
+#define Queen 12
+#define King 13
+#define atabcol 11
+#define btabcol 18
+#define ctabcol 25
+#define dtabcol 32
+
+#define spades 's'
+#define clubs 'c'
+#define hearts 'h'
+#define diamonds 'd'
+#define black 'b'
+#define red 'r'
+
+#define stk 1
+#define tal 2
+#define tab 3
+#define INCRHAND(row, col) {\
+ row -= cheightcol;\
+ if (row < ctoprow) {\
+ row = cbotrow;\
+ col += cwidthcol;\
+ }\
+}
+#define DECRHAND(row, col) {\
+ row += cheightcol;\
+ if (row > cbotrow) {\
+ row = ctoprow;\
+ col -= cwidthcol;\
+ }\
+}
+
+
+struct cardtype {
+ char suit;
+ char color;
+ bool visible;
+ bool paid;
+ int rank;
+ struct cardtype *next;
+};
+
+#define NIL ((struct cardtype *) -1)
+
+struct cardtype *deck[decksize];
+struct cardtype cards[decksize];
+struct cardtype *bottom[4], *found[4], *tableau[4];
+struct cardtype *talon, *hand, *stock, *basecard;
+int length[4];
+int cardsoff, base, cinhand, taloncnt, stockcnt, timesthru;
+char suitmap[4] = {spades, clubs, hearts, diamonds};
+char colormap[4] = {black, black, red, red};
+char pilemap[4] = {atabcol, btabcol, ctabcol, dtabcol};
+char srcpile, destpile;
+int mtforigin, tempbase;
+int coldcol, cnewcol, coldrow, cnewrow;
+bool errmsg, done;
+bool mtfdone, Cflag = FALSE;
+#define INSTRUCTIONBOX 1
+#define BETTINGBOX 2
+#define NOBOX 3
+int status = INSTRUCTIONBOX;
+int uid;
+
+/*
+ * Basic betting costs
+ */
+#define costofhand 13
+#define costofinspection 13
+#define costofgame 26
+#define costofrunthroughhand 5
+#define costofinformation 1
+#define secondsperdollar 60
+#define maxtimecharge 3
+#define valuepercardup 5
+/*
+ * Variables associated with betting
+ */
+struct betinfo {
+ long hand; /* cost of dealing hand */
+ long inspection; /* cost of inspecting hand */
+ long game; /* cost of buying game */
+ long runs; /* cost of running through hands */
+ long information; /* cost of information */
+ long thinktime; /* cost of thinking time */
+ long wins; /* total winnings */
+ long worth; /* net worth after costs */
+};
+struct betinfo this, game, total;
+bool startedgame = FALSE, infullgame = FALSE;
+time_t acctstart;
+int dbfd = -1;
+
+/*
+ * The following procedures print the board onto the screen using the
+ * addressible cursor. The end of these procedures will also be
+ * separated from the rest of the program.
+ *
+ * procedure to set the move command box
+ */
+movebox()
+{
+ switch (status) {
+ case BETTINGBOX:
+ printtopbettingbox();
+ break;
+ case NOBOX:
+ clearabovemovebox();
+ break;
+ case INSTRUCTIONBOX:
+ printtopinstructions();
+ break;
+ }
+ move(moverow, boxcol);
+ printw("| |");
+ move(msgrow, boxcol);
+ printw("| |");
+ switch (status) {
+ case BETTINGBOX:
+ printbottombettingbox();
+ break;
+ case NOBOX:
+ clearbelowmovebox();
+ break;
+ case INSTRUCTIONBOX:
+ printbottominstructions();
+ break;
+ }
+ refresh();
+}
+
+/*
+ * print directions above move box
+ */
+printtopinstructions()
+{
+ move(tboxrow, boxcol);
+ printw("*----------------------------------*");
+ move(tboxrow + 1, boxcol);
+ printw("| MOVES |");
+ move(tboxrow + 2, boxcol);
+ printw("|s# = stock to tableau |");
+ move(tboxrow + 3, boxcol);
+ printw("|sf = stock to foundation |");
+ move(tboxrow + 4, boxcol);
+ printw("|t# = talon to tableau |");
+ move(tboxrow + 5, boxcol);
+ printw("|tf = talon to foundation |");
+ move(tboxrow + 6, boxcol);
+ printw("|## = tableau to tableau |");
+ move(tboxrow + 7, boxcol);
+ printw("|#f = tableau to foundation |");
+ move(tboxrow + 8, boxcol);
+ printw("|ht = hand to talon |");
+ move(tboxrow + 9, boxcol);
+ printw("|c = toggle card counting |");
+ move(tboxrow + 10, boxcol);
+ printw("|b = present betting information |");
+ move(tboxrow + 11, boxcol);
+ printw("|q = quit to end the game |");
+ move(tboxrow + 12, boxcol);
+ printw("|==================================|");
+}
+
+/*
+ * Print the betting box.
+ */
+printtopbettingbox()
+{
+
+ move(tboxrow, boxcol);
+ printw("*----------------------------------*");
+ move(tboxrow + 1, boxcol);
+ printw("|Costs Hand Game Total |");
+ move(tboxrow + 2, boxcol);
+ printw("| Hands |");
+ move(tboxrow + 3, boxcol);
+ printw("| Inspections |");
+ move(tboxrow + 4, boxcol);
+ printw("| Games |");
+ move(tboxrow + 5, boxcol);
+ printw("| Runs |");
+ move(tboxrow + 6, boxcol);
+ printw("| Information |");
+ move(tboxrow + 7, boxcol);
+ printw("| Think time |");
+ move(tboxrow + 8, boxcol);
+ printw("|Total Costs |");
+ move(tboxrow + 9, boxcol);
+ printw("|Winnings |");
+ move(tboxrow + 10, boxcol);
+ printw("|Net Worth |");
+ move(tboxrow + 11, boxcol);
+ printw("|Return |");
+ move(tboxrow + 12, boxcol);
+ printw("|==================================|");
+}
+
+/*
+ * clear info above move box
+ */
+clearabovemovebox()
+{
+ int i;
+
+ for (i = 0; i <= 11; i++) {
+ move(tboxrow + i, boxcol);
+ printw(" ");
+ }
+ move(tboxrow + 12, boxcol);
+ printw("*----------------------------------*");
+}
+
+/*
+ * print instructions below move box
+ */
+printbottominstructions()
+{
+ move(bboxrow, boxcol);
+ printw("|Replace # with the number of the |");
+ move(bboxrow + 1, boxcol);
+ printw("|tableau you want. |");
+ move(bboxrow + 2, boxcol);
+ printw("*----------------------------------*");
+}
+
+/*
+ * print betting information below move box
+ */
+printbottombettingbox()
+{
+ move(bboxrow, boxcol);
+ printw("|x = toggle information box |");
+ move(bboxrow + 1, boxcol);
+ printw("|i = list playing instructions |");
+ move(bboxrow + 2, boxcol);
+ printw("*----------------------------------*");
+}
+
+/*
+ * clear info below move box
+ */
+clearbelowmovebox()
+{
+ int i;
+
+ move(bboxrow, boxcol);
+ printw("*----------------------------------*");
+ for (i = 1; i <= 2; i++) {
+ move(bboxrow + i, boxcol);
+ printw(" ");
+ }
+}
+
+/*
+ * procedure to put the board on the screen using addressable cursor
+ */
+makeboard()
+{
+ clear();
+ refresh();
+ move(titlerow, titlecol);
+ printw("=-> CANFIELD <-=");
+ move(fttlrow, fttlcol);
+ printw("foundation");
+ move(foundrow - 1, fttlcol);
+ printw("=---= =---= =---= =---=");
+ move(foundrow, fttlcol);
+ printw("| | | | | | | |");
+ move(foundrow + 1, fttlcol);
+ printw("=---= =---= =---= =---=");
+ move(ottlrow, sidecol);
+ printw("stock tableau");
+ move(stockrow - 1, sidecol);
+ printw("=---=");
+ move(stockrow, sidecol);
+ printw("| |");
+ move(stockrow + 1, sidecol);
+ printw("=---=");
+ move(talonrow - 2, sidecol);
+ printw("talon");
+ move(talonrow - 1, sidecol);
+ printw("=---=");
+ move(talonrow, sidecol);
+ printw("| |");
+ move(talonrow + 1, sidecol);
+ printw("=---=");
+ move(tabrow - 1, atabcol);
+ printw("-1- -2- -3- -4-");
+ movebox();
+}
+
+/*
+ * clean up the board for another game
+ */
+cleanupboard()
+{
+ int cnt, row, col;
+ struct cardtype *ptr;
+
+ if (Cflag) {
+ clearstat();
+ for(ptr = stock, row = stockrow;
+ ptr != NIL;
+ ptr = ptr->next, row++) {
+ move(row, sidecol);
+ printw(" ");
+ }
+ move(row, sidecol);
+ printw(" ");
+ move(stockrow + 1, sidecol);
+ printw("=---=");
+ move(talonrow - 2, sidecol);
+ printw("talon");
+ move(talonrow - 1, sidecol);
+ printw("=---=");
+ move(talonrow + 1, sidecol);
+ printw("=---=");
+ }
+ move(stockrow, sidecol);
+ printw("| |");
+ move(talonrow, sidecol);
+ printw("| |");
+ move(foundrow, fttlcol);
+ printw("| | | | | | | |");
+ for (cnt = 0; cnt < 4; cnt++) {
+ switch(cnt) {
+ case 0:
+ col = atabcol;
+ break;
+ case 1:
+ col = btabcol;
+ break;
+ case 2:
+ col = ctabcol;
+ break;
+ case 3:
+ col = dtabcol;
+ break;
+ }
+ for(ptr = tableau[cnt], row = tabrow;
+ ptr != NIL;
+ ptr = ptr->next, row++)
+ removecard(col, row);
+ }
+}
+
+/*
+ * procedure to create a deck of cards
+ */
+initdeck(deck)
+ struct cardtype *deck[];
+{
+ int i;
+ int scnt;
+ char s;
+ int r;
+
+ i = 0;
+ for (scnt=0; scnt<4; scnt++) {
+ s = suitmap[scnt];
+ for (r=Ace; r<=King; r++) {
+ deck[i] = &cards[i];
+ cards[i].rank = r;
+ cards[i].suit = s;
+ cards[i].color = colormap[scnt];
+ cards[i].next = NIL;
+ i++;
+ }
+ }
+}
+
+/*
+ * procedure to shuffle the deck
+ */
+shuffle(deck)
+ struct cardtype *deck[];
+{
+ int i,j;
+ struct cardtype *temp;
+
+ for (i=0; i<decksize; i++) {
+ deck[i]->visible = FALSE;
+ deck[i]->paid = FALSE;
+ }
+ for (i = decksize-1; i>=0; i--) {
+ j = random() % decksize;
+ if (i != j) {
+ temp = deck[i];
+ deck[i] = deck[j];
+ deck[j] = temp;
+ }
+ }
+}
+
+/*
+ * procedure to remove the card from the board
+ */
+removecard(a, b)
+{
+ move(b, a);
+ printw(" ");
+}
+
+/*
+ * procedure to print the cards on the board
+ */
+printrank(a, b, cp, inverse)
+ struct cardtype *cp;
+ bool inverse;
+{
+ move(b, a);
+ if (cp->rank != 10)
+ addch(' ');
+ if (inverse)
+ standout();
+ switch (cp->rank) {
+ case 2: case 3: case 4: case 5: case 6: case 7:
+ case 8: case 9: case 10:
+ printw("%d", cp->rank);
+ break;
+ case Ace:
+ addch('A');
+ break;
+ case Jack:
+ addch('J');
+ break;
+ case Queen:
+ addch('Q');
+ break;
+ case King:
+ addch('K');
+ }
+ if (inverse)
+ standend();
+}
+
+/*
+ * procedure to print out a card
+ */
+printcard(a, b, cp)
+ int a,b;
+ struct cardtype *cp;
+{
+ if (cp == NIL)
+ removecard(a, b);
+ else if (cp->visible == FALSE) {
+ move(b, a);
+ printw(" ? ");
+ } else {
+ bool inverse = (cp->suit == 'd' || cp->suit == 'h');
+
+ printrank(a, b, cp, inverse);
+ if (inverse)
+ standout();
+ addch(cp->suit);
+ if (inverse)
+ standend();
+ }
+}
+
+/*
+ * procedure to move the top card from one location to the top
+ * of another location. The pointers always point to the top
+ * of the piles.
+ */
+transit(source, dest)
+ struct cardtype **source, **dest;
+{
+ struct cardtype *temp;
+
+ temp = *source;
+ *source = (*source)->next;
+ temp->next = *dest;
+ *dest = temp;
+}
+
+/*
+ * Procedure to set the cards on the foundation base when available.
+ * Note that it is only called on a foundation pile at the beginning of
+ * the game, so the pile will have exactly one card in it.
+ */
+fndbase(cp, column, row)
+ struct cardtype **cp;
+{
+ bool nomore;
+
+ if (*cp != NIL)
+ do {
+ if ((*cp)->rank == basecard->rank) {
+ base++;
+ printcard(pilemap[base], foundrow, *cp);
+ if (*cp == tableau[0])
+ length[0] = length[0] - 1;
+ if (*cp == tableau[1])
+ length[1] = length[1] - 1;
+ if (*cp == tableau[2])
+ length[2] = length[2] - 1;
+ if (*cp == tableau[3])
+ length[3] = length[3] - 1;
+ transit(cp, &found[base]);
+ if (cp == &talon)
+ usedtalon();
+ if (cp == &stock)
+ usedstock();
+ if (*cp != NIL) {
+ printcard(column, row, *cp);
+ nomore = FALSE;
+ } else {
+ removecard(column, row);
+ nomore = TRUE;
+ }
+ cardsoff++;
+ if (infullgame) {
+ this.wins += valuepercardup;
+ game.wins += valuepercardup;
+ total.wins += valuepercardup;
+ }
+ } else
+ nomore = TRUE;
+ } while (nomore == FALSE);
+}
+
+/*
+ * procedure to initialize the things necessary for the game
+ */
+initgame()
+{
+ register i;
+
+ for (i=0; i<18; i++) {
+ deck[i]->visible = TRUE;
+ deck[i]->paid = TRUE;
+ }
+ stockcnt = 13;
+ stock = deck[12];
+ for (i=12; i>=1; i--)
+ deck[i]->next = deck[i - 1];
+ deck[0]->next = NIL;
+ found[0] = deck[13];
+ deck[13]->next = NIL;
+ for (i=1; i<4; i++)
+ found[i] = NIL;
+ basecard = found[0];
+ for (i=14; i<18; i++) {
+ tableau[i - 14] = deck[i];
+ deck[i]->next = NIL;
+ }
+ for (i=0; i<4; i++) {
+ bottom[i] = tableau[i];
+ length[i] = tabrow;
+ }
+ hand = deck[18];
+ for (i=18; i<decksize-1; i++)
+ deck[i]->next = deck[i + 1];
+ deck[decksize-1]->next = NIL;
+ talon = NIL;
+ base = 0;
+ cinhand = 34;
+ taloncnt = 0;
+ timesthru = 0;
+ cardsoff = 1;
+ coldrow = ctoprow;
+ coldcol = cinitcol;
+ cnewrow = ctoprow;
+ cnewcol = cinitcol + cwidthcol;
+}
+
+/*
+ * procedure to print the beginning cards and to start each game
+ */
+startgame()
+{
+ register int j;
+
+ shuffle(deck);
+ initgame();
+ this.hand = costofhand;
+ game.hand += costofhand;
+ total.hand += costofhand;
+ this.inspection = 0;
+ this.game = 0;
+ this.runs = 0;
+ this.information = 0;
+ this.wins = 0;
+ this.thinktime = 0;
+ infullgame = FALSE;
+ startedgame = FALSE;
+ printcard(foundcol, foundrow, found[0]);
+ printcard(stockcol, stockrow, stock);
+ printcard(atabcol, tabrow, tableau[0]);
+ printcard(btabcol, tabrow, tableau[1]);
+ printcard(ctabcol, tabrow, tableau[2]);
+ printcard(dtabcol, tabrow, tableau[3]);
+ printcard(taloncol, talonrow, talon);
+ move(foundrow - 2, basecol);
+ printw("Base");
+ move(foundrow - 1, basecol);
+ printw("Rank");
+ printrank(basecol, foundrow, found[0], 0);
+ for (j=0; j<=3; j++)
+ fndbase(&tableau[j], pilemap[j], tabrow);
+ fndbase(&stock, stockcol, stockrow);
+ showstat(); /* show card counting info to cheaters */
+ movetotalon();
+ updatebettinginfo();
+}
+
+/*
+ * procedure to clear the message printed from an error
+ */
+clearmsg()
+{
+ int i;
+
+ if (errmsg == TRUE) {
+ errmsg = FALSE;
+ move(msgrow, msgcol);
+ for (i=0; i<25; i++)
+ addch(' ');
+ refresh();
+ }
+}
+
+/*
+ * procedure to print an error message if the move is not listed
+ */
+dumberror()
+{
+ errmsg = TRUE;
+ move(msgrow, msgcol);
+ printw("Not a proper move ");
+}
+
+/*
+ * procedure to print an error message if the move is not possible
+ */
+destinerror()
+{
+ errmsg = TRUE;
+ move(msgrow, msgcol);
+ printw("Error: Can't move there");
+}
+
+/*
+ * function to see if the source has cards in it
+ */
+bool
+notempty(cp)
+struct cardtype *cp;
+{
+ if (cp == NIL) {
+ errmsg = TRUE;
+ move(msgrow, msgcol);
+ printw("Error: no cards to move");
+ return (FALSE);
+ } else
+ return (TRUE);
+}
+
+/*
+ * function to see if the rank of one card is less than another
+ */
+bool
+ranklower(cp1, cp2)
+ struct cardtype *cp1, *cp2;
+{
+ if (cp2->rank == Ace)
+ if (cp1->rank == King)
+ return (TRUE);
+ else
+ return (FALSE);
+ else if (cp1->rank + 1 == cp2->rank)
+ return (TRUE);
+ else
+ return (FALSE);
+}
+
+/*
+ * function to check the cardcolor for moving to a tableau
+ */
+bool
+diffcolor(cp1, cp2)
+ struct cardtype *cp1, *cp2;
+{
+ if (cp1->color == cp2->color)
+ return (FALSE);
+ else
+ return (TRUE);
+}
+
+/*
+ * function to see if the card can move to the tableau
+ */
+bool
+tabok(cp, des)
+ struct cardtype *cp;
+{
+ if ((cp == stock) && (tableau[des] == NIL))
+ return (TRUE);
+ else if (tableau[des] == NIL)
+ if (stock == NIL &&
+ cp != bottom[0] && cp != bottom[1] &&
+ cp != bottom[2] && cp != bottom[3])
+ return (TRUE);
+ else
+ return (FALSE);
+ else if (ranklower(cp, tableau[des]) && diffcolor(cp, tableau[des]))
+ return (TRUE);
+ else
+ return (FALSE);
+}
+
+/*
+ * procedure to turn the cards onto the talon from the deck
+ */
+movetotalon()
+{
+ int i, fin;
+
+ if (cinhand <= 3 && cinhand > 0) {
+ move(msgrow, msgcol);
+ printw("Hand is now empty ");
+ }
+ if (cinhand >= 3)
+ fin = 3;
+ else if (cinhand > 0)
+ fin = cinhand;
+ else if (talon != NIL) {
+ timesthru++;
+ errmsg = TRUE;
+ move(msgrow, msgcol);
+ if (timesthru != 4) {
+ printw("Talon is now the new hand");
+ this.runs += costofrunthroughhand;
+ game.runs += costofrunthroughhand;
+ total.runs += costofrunthroughhand;
+ while (talon != NIL) {
+ transit(&talon, &hand);
+ cinhand++;
+ }
+ if (cinhand >= 3)
+ fin = 3;
+ else
+ fin = cinhand;
+ taloncnt = 0;
+ coldrow = ctoprow;
+ coldcol = cinitcol;
+ cnewrow = ctoprow;
+ cnewcol = cinitcol + cwidthcol;
+ clearstat();
+ showstat();
+ } else {
+ fin = 0;
+ done = TRUE;
+ printw("I believe you have lost");
+ refresh();
+ sleep(5);
+ }
+ } else {
+ errmsg = TRUE;
+ move(msgrow, msgcol);
+ printw("Talon and hand are empty");
+ fin = 0;
+ }
+ for (i=0; i<fin; i++) {
+ transit(&hand, &talon);
+ INCRHAND(cnewrow, cnewcol);
+ INCRHAND(coldrow, coldcol);
+ removecard(cnewcol, cnewrow);
+ if (i == fin - 1)
+ talon->visible = TRUE;
+ if (Cflag) {
+ if (talon->paid == FALSE && talon->visible == TRUE) {
+ this.information += costofinformation;
+ game.information += costofinformation;
+ total.information += costofinformation;
+ talon->paid = TRUE;
+ }
+ printcard(coldcol, coldrow, talon);
+ }
+ }
+ if (fin != 0) {
+ printcard(taloncol, talonrow, talon);
+ cinhand -= fin;
+ taloncnt += fin;
+ if (Cflag) {
+ move(handstatrow, handstatcol);
+ printw("%3d", cinhand);
+ move(talonstatrow, talonstatcol);
+ printw("%3d", taloncnt);
+ }
+ fndbase(&talon, taloncol, talonrow);
+ }
+}
+
+
+/*
+ * procedure to print card counting info on screen
+ */
+showstat()
+{
+ int row, col;
+ register struct cardtype *ptr;
+
+ if (!Cflag)
+ return;
+ move(talonstatrow, talonstatcol - 7);
+ printw("Talon: %3d", taloncnt);
+ move(handstatrow, handstatcol - 7);
+ printw("Hand: %3d", cinhand);
+ move(stockstatrow, stockstatcol - 7);
+ printw("Stock: %3d", stockcnt);
+ for ( row = coldrow, col = coldcol, ptr = talon;
+ ptr != NIL;
+ ptr = ptr->next ) {
+ if (ptr->paid == FALSE && ptr->visible == TRUE) {
+ ptr->paid = TRUE;
+ this.information += costofinformation;
+ game.information += costofinformation;
+ total.information += costofinformation;
+ }
+ printcard(col, row, ptr);
+ DECRHAND(row, col);
+ }
+ for ( row = cnewrow, col = cnewcol, ptr = hand;
+ ptr != NIL;
+ ptr = ptr->next ) {
+ if (ptr->paid == FALSE && ptr->visible == TRUE) {
+ ptr->paid = TRUE;
+ this.information += costofinformation;
+ game.information += costofinformation;
+ total.information += costofinformation;
+ }
+ INCRHAND(row, col);
+ printcard(col, row, ptr);
+ }
+}
+
+/*
+ * procedure to clear card counting info from screen
+ */
+clearstat()
+{
+ int row;
+
+ move(talonstatrow, talonstatcol - 7);
+ printw(" ");
+ move(handstatrow, handstatcol - 7);
+ printw(" ");
+ move(stockstatrow, stockstatcol - 7);
+ printw(" ");
+ for ( row = ctoprow ; row <= cbotrow ; row++ ) {
+ move(row, cinitcol);
+ printw("%56s", " ");
+ }
+}
+
+/*
+ * procedure to update card counting base
+ */
+usedtalon()
+{
+ removecard(coldcol, coldrow);
+ DECRHAND(coldrow, coldcol);
+ if (talon != NIL && (talon->visible == FALSE)) {
+ talon->visible = TRUE;
+ if (Cflag) {
+ this.information += costofinformation;
+ game.information += costofinformation;
+ total.information += costofinformation;
+ talon->paid = TRUE;
+ printcard(coldcol, coldrow, talon);
+ }
+ }
+ taloncnt--;
+ if (Cflag) {
+ move(talonstatrow, talonstatcol);
+ printw("%3d", taloncnt);
+ }
+}
+
+/*
+ * procedure to update stock card counting base
+ */
+usedstock()
+{
+ stockcnt--;
+ if (Cflag) {
+ move(stockstatrow, stockstatcol);
+ printw("%3d", stockcnt);
+ }
+}
+
+/*
+ * let 'em know how they lost!
+ */
+showcards()
+{
+ register struct cardtype *ptr;
+ int row;
+
+ if (!Cflag || cardsoff == 52)
+ return;
+ for (ptr = talon; ptr != NIL; ptr = ptr->next) {
+ ptr->visible = TRUE;
+ ptr->paid = TRUE;
+ }
+ for (ptr = hand; ptr != NIL; ptr = ptr->next) {
+ ptr->visible = TRUE;
+ ptr->paid = TRUE;
+ }
+ showstat();
+ move(stockrow + 1, sidecol);
+ printw(" ");
+ move(talonrow - 2, sidecol);
+ printw(" ");
+ move(talonrow - 1, sidecol);
+ printw(" ");
+ move(talonrow, sidecol);
+ printw(" ");
+ move(talonrow + 1, sidecol);
+ printw(" ");
+ for (ptr = stock, row = stockrow; ptr != NIL; ptr = ptr->next, row++) {
+ move(row, stockcol - 1);
+ printw("| |");
+ printcard(stockcol, row, ptr);
+ }
+ if (stock == NIL) {
+ move(row, stockcol - 1);
+ printw("| |");
+ row++;
+ }
+ move(handstatrow, handstatcol - 7);
+ printw(" ");
+ move(row, stockcol - 1);
+ printw("=---=");
+ if ( cardsoff == 52 )
+ getcmd(moverow, movecol, "Hit return to exit");
+}
+
+/*
+ * procedure to update the betting values
+ */
+updatebettinginfo()
+{
+ long thiscosts, gamecosts, totalcosts;
+ double thisreturn, gamereturn, totalreturn;
+ time_t now;
+ register long dollars;
+
+ time(&now);
+ dollars = (now - acctstart) / secondsperdollar;
+ if (dollars > 0) {
+ acctstart += dollars * secondsperdollar;
+ if (dollars > maxtimecharge)
+ dollars = maxtimecharge;
+ this.thinktime += dollars;
+ game.thinktime += dollars;
+ total.thinktime += dollars;
+ }
+ thiscosts = this.hand + this.inspection + this.game +
+ this.runs + this.information + this.thinktime;
+ gamecosts = game.hand + game.inspection + game.game +
+ game.runs + game.information + game.thinktime;
+ totalcosts = total.hand + total.inspection + total.game +
+ total.runs + total.information + total.thinktime;
+ this.worth = this.wins - thiscosts;
+ game.worth = game.wins - gamecosts;
+ total.worth = total.wins - totalcosts;
+ thisreturn = ((double)this.wins / (double)thiscosts - 1.0) * 100.0;
+ gamereturn = ((double)game.wins / (double)gamecosts - 1.0) * 100.0;
+ totalreturn = ((double)total.wins / (double)totalcosts - 1.0) * 100.0;
+ if (status != BETTINGBOX)
+ return;
+ move(tboxrow + 2, boxcol + 13);
+ printw("%4d%8d%9d", this.hand, game.hand, total.hand);
+ move(tboxrow + 3, boxcol + 13);
+ printw("%4d%8d%9d", this.inspection, game.inspection, total.inspection);
+ move(tboxrow + 4, boxcol + 13);
+ printw("%4d%8d%9d", this.game, game.game, total.game);
+ move(tboxrow + 5, boxcol + 13);
+ printw("%4d%8d%9d", this.runs, game.runs, total.runs);
+ move(tboxrow + 6, boxcol + 13);
+ printw("%4d%8d%9d", this.information, game.information,
+ total.information);
+ move(tboxrow + 7, boxcol + 13);
+ printw("%4d%8d%9d", this.thinktime, game.thinktime, total.thinktime);
+ move(tboxrow + 8, boxcol + 13);
+ printw("%4d%8d%9d", thiscosts, gamecosts, totalcosts);
+ move(tboxrow + 9, boxcol + 13);
+ printw("%4d%8d%9d", this.wins, game.wins, total.wins);
+ move(tboxrow + 10, boxcol + 13);
+ printw("%4d%8d%9d", this.worth, game.worth, total.worth);
+ move(tboxrow + 11, boxcol + 13);
+ printw("%4.0f%%%7.1f%%%8.1f%%", thisreturn, gamereturn, totalreturn);
+}
+
+/*
+ * procedure to move a card from the stock or talon to the tableau
+ */
+simpletableau(cp, des)
+struct cardtype **cp;
+{
+ int origin;
+
+ if (notempty(*cp)) {
+ if (tabok(*cp, des)) {
+ if (*cp == stock)
+ origin = stk;
+ else
+ origin = tal;
+ if (tableau[des] == NIL)
+ bottom[des] = *cp;
+ transit(cp, &tableau[des]);
+ length[des]++;
+ printcard(pilemap[des], length[des], tableau[des]);
+ timesthru = 0;
+ if (origin == stk) {
+ usedstock();
+ printcard(stockcol, stockrow, stock);
+ } else {
+ usedtalon();
+ printcard(taloncol, talonrow, talon);
+ }
+ } else
+ destinerror();
+ }
+}
+
+/*
+ * print the tableau
+ */
+tabprint(sour, des)
+{
+ int dlength, slength, i;
+ struct cardtype *tempcard;
+
+ for (i=tabrow; i<=length[sour]; i++)
+ removecard(pilemap[sour], i);
+ dlength = length[des] + 1;
+ slength = length[sour];
+ if (slength == tabrow)
+ printcard(pilemap[des], dlength, tableau[sour]);
+ else
+ while (slength != tabrow - 1) {
+ tempcard = tableau[sour];
+ for (i=1; i<=slength-tabrow; i++)
+ tempcard = tempcard->next;
+ printcard(pilemap[des], dlength, tempcard);
+ slength--;
+ dlength++;
+ }
+}
+
+/*
+ * procedure to move from the tableau to the tableau
+ */
+tabtotab(sour, des)
+ register int sour, des;
+{
+ struct cardtype *temp;
+
+ if (notempty(tableau[sour])) {
+ if (tabok(bottom[sour], des)) {
+ tabprint(sour, des);
+ temp = bottom[sour];
+ bottom[sour] = NIL;
+ if (bottom[des] == NIL)
+ bottom[des] = temp;
+ temp->next = tableau[des];
+ tableau[des] = tableau[sour];
+ tableau[sour] = NIL;
+ length[des] = length[des] + (length[sour] - (tabrow - 1));
+ length[sour] = tabrow - 1;
+ timesthru = 0;
+ } else
+ destinerror();
+ }
+}
+
+/*
+ * functions to see if the card can go onto the foundation
+ */
+bool
+rankhigher(cp, let)
+ struct cardtype *cp;
+{
+ if (found[let]->rank == King)
+ if (cp->rank == Ace)
+ return(TRUE);
+ else
+ return(FALSE);
+ else if (cp->rank - 1 == found[let]->rank)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+
+/*
+ * function to determine if two cards are the same suit
+ */
+samesuit(cp, let)
+ struct cardtype *cp;
+{
+ if (cp->suit == found[let]->suit)
+ return (TRUE);
+ else
+ return (FALSE);
+}
+
+/*
+ * procedure to move a card to the correct foundation pile
+ */
+movetofound(cp, source)
+ struct cardtype **cp;
+{
+ tempbase = 0;
+ mtfdone = FALSE;
+ if (notempty(*cp)) {
+ do {
+ if (found[tempbase] != NIL)
+ if (rankhigher(*cp, tempbase)
+ && samesuit(*cp, tempbase)) {
+ if (*cp == stock)
+ mtforigin = stk;
+ else if (*cp == talon)
+ mtforigin = tal;
+ else
+ mtforigin = tab;
+ transit(cp, &found[tempbase]);
+ printcard(pilemap[tempbase],
+ foundrow, found[tempbase]);
+ timesthru = 0;
+ if (mtforigin == stk) {
+ usedstock();
+ printcard(stockcol, stockrow, stock);
+ } else if (mtforigin == tal) {
+ usedtalon();
+ printcard(taloncol, talonrow, talon);
+ } else {
+ removecard(pilemap[source], length[source]);
+ length[source]--;
+ }
+ cardsoff++;
+ if (infullgame) {
+ this.wins += valuepercardup;
+ game.wins += valuepercardup;
+ total.wins += valuepercardup;
+ }
+ mtfdone = TRUE;
+ } else
+ tempbase++;
+ else
+ tempbase++;
+ } while ((tempbase != 4) && !mtfdone);
+ if (!mtfdone)
+ destinerror();
+ }
+}
+
+/*
+ * procedure to get a command
+ */
+getcmd(row, col, cp)
+ int row, col;
+ char *cp;
+{
+ char cmd[2], ch;
+ int i;
+
+ i = 0;
+ move(row, col);
+ printw("%-24s", cp);
+ col += 1 + strlen(cp);
+ move(row, col);
+ refresh();
+ do {
+ ch = getch() & 0177;
+ if (ch >= 'A' && ch <= 'Z')
+ ch += ('a' - 'A');
+ if (ch == '\f') {
+ wrefresh(curscr);
+ refresh();
+ } else if (i >= 2 && ch != _tty.sg_erase && ch != _tty.sg_kill) {
+ if (ch != '\n' && ch != '\r' && ch != ' ')
+ write(1, "\007", 1);
+ } else if (ch == _tty.sg_erase && i > 0) {
+ printw("\b \b");
+ refresh();
+ i--;
+ } else if (ch == _tty.sg_kill && i > 0) {
+ while (i > 0) {
+ printw("\b \b");
+ i--;
+ }
+ refresh();
+ } else if (ch == '\032') { /* Control-Z */
+ suspend();
+ move(row, col + i);
+ refresh();
+ } else if (isprint(ch)) {
+ cmd[i++] = ch;
+ addch(ch);
+ refresh();
+ }
+ } while (ch != '\n' && ch != '\r' && ch != ' ');
+ srcpile = cmd[0];
+ destpile = cmd[1];
+}
+
+/*
+ * Suspend the game (shell escape if no process control on system)
+ */
+suspend()
+{
+#ifndef SIGTSTP
+ char *sh;
+#endif
+
+ updatebettinginfo();
+ move(21, 0);
+ refresh();
+ if (dbfd != -1) {
+ lseek(dbfd, uid * sizeof(struct betinfo), 0);
+ write(dbfd, (char *)&total, sizeof(total));
+ }
+ kill(getpid(), SIGTSTP);
+ raw();
+ noecho();
+}
+
+/*
+ * procedure to evaluate and make the specific moves
+ */
+movecard()
+{
+ int source, dest;
+ char osrcpile, odestpile;
+
+ done = FALSE;
+ errmsg = FALSE;
+ do {
+ if (talon == NIL && hand != NIL)
+ movetotalon();
+ if (cardsoff == 52) {
+ refresh();
+ srcpile = 'q';
+ } else if (!startedgame) {
+ move(msgrow, msgcol);
+ errmsg = TRUE;
+ switch (34 - taloncnt - cinhand) {
+ default:
+ errmsg = FALSE;
+ break;
+ case 1:
+ printw("One card used from talon ");
+ break;
+ case 2:
+ printw("Two cards used from talon ");
+ break;
+ case 3:
+ printw(">3< cards used from talon ");
+ break;
+ }
+ getcmd(moverow, movecol, "Move:");
+ } else
+ getcmd(moverow, movecol, "Move:");
+ clearmsg();
+ if (srcpile >= '1' && srcpile <= '4')
+ source = (int) (srcpile - '1');
+ if (destpile >= '1' && destpile <= '4')
+ dest = (int) (destpile - '1');
+ if (!startedgame &&
+ (srcpile == 't' || srcpile == 's' || srcpile == 'h' ||
+ srcpile == '1' || srcpile == '2' || srcpile == '3' ||
+ srcpile == '4')) {
+ startedgame = TRUE;
+ osrcpile = srcpile;
+ odestpile = destpile;
+ if (status != BETTINGBOX)
+ srcpile = 'y';
+ else do {
+ getcmd(moverow, movecol, "Inspect game?");
+ } while (srcpile != 'y' && srcpile != 'n');
+ if (srcpile == 'n') {
+ srcpile = 'q';
+ } else {
+ this.inspection += costofinspection;
+ game.inspection += costofinspection;
+ total.inspection += costofinspection;
+ srcpile = osrcpile;
+ destpile = odestpile;
+ }
+ }
+ switch (srcpile) {
+ case 't':
+ if (destpile == 'f' || destpile == 'F')
+ movetofound(&talon, source);
+ else if (destpile >= '1' && destpile <= '4')
+ simpletableau(&talon, dest);
+ else
+ dumberror();
+ break;
+ case 's':
+ if (destpile == 'f' || destpile == 'F')
+ movetofound(&stock, source);
+ else if (destpile >= '1' && destpile <= '4')
+ simpletableau(&stock, dest);
+ else dumberror();
+ break;
+ case 'h':
+ if (destpile != 't' && destpile != 'T') {
+ dumberror();
+ break;
+ }
+ if (infullgame) {
+ movetotalon();
+ break;
+ }
+ if (status == BETTINGBOX) {
+ do {
+ getcmd(moverow, movecol,
+ "Buy game?");
+ } while (srcpile != 'y' &&
+ srcpile != 'n');
+ if (srcpile == 'n') {
+ showcards();
+ done = TRUE;
+ break;
+ }
+ }
+ infullgame = TRUE;
+ this.wins += valuepercardup * cardsoff;
+ game.wins += valuepercardup * cardsoff;
+ total.wins += valuepercardup * cardsoff;
+ this.game += costofgame;
+ game.game += costofgame;
+ total.game += costofgame;
+ movetotalon();
+ break;
+ case 'q':
+ showcards();
+ done = TRUE;
+ break;
+ case 'b':
+ printtopbettingbox();
+ printbottombettingbox();
+ status = BETTINGBOX;
+ break;
+ case 'x':
+ clearabovemovebox();
+ clearbelowmovebox();
+ status = NOBOX;
+ break;
+ case 'i':
+ printtopinstructions();
+ printbottominstructions();
+ status = INSTRUCTIONBOX;
+ break;
+ case 'c':
+ Cflag = !Cflag;
+ if (Cflag)
+ showstat();
+ else
+ clearstat();
+ break;
+ case '1': case '2': case '3': case '4':
+ if (destpile == 'f' || destpile == 'F')
+ movetofound(&tableau[source], source);
+ else if (destpile >= '1' && destpile <= '4')
+ tabtotab(source, dest);
+ else dumberror();
+ break;
+ default:
+ dumberror();
+ }
+ fndbase(&stock, stockcol, stockrow);
+ fndbase(&talon, taloncol, talonrow);
+ updatebettinginfo();
+ } while (!done);
+}
+
+char *basicinstructions[] = {
+ "Here are brief instuctions to the game of Canfield:\n\n",
+ " If you have never played solitaire before, it is recom-\n",
+ "mended that you consult a solitaire instruction book. In\n",
+ "Canfield, tableau cards may be built on each other downward\n",
+ "in alternate colors. An entire pile must be moved as a unit\n",
+ "in building. Top cards of the piles are available to be able\n",
+ "to be played on foundations, but never into empty spaces.\n\n",
+ " Spaces must be filled from the stock. The top card of\n",
+ "the stock also is available to be played on foundations or\n",
+ "built on tableau piles. After the stock is exhausted, ta-\n",
+ "bleau spaces may be filled from the talon and the player may\n",
+ "keep them open until he wishes to use them.\n\n",
+ " Cards are dealt from the hand to the talon by threes\n",
+ "and this repeats until there are no more cards in the hand\n",
+ "or the player quits. To have cards dealt onto the talon the\n",
+ "player types 'ht' for his move. Foundation base cards are\n",
+ "also automatically moved to the foundation when they become\n",
+ "available.\n\n",
+ "push any key when you are finished: ",
+ 0 };
+
+char *bettinginstructions[] = {
+ " The rules for betting are somewhat less strict than\n",
+ "those used in the official version of the game. The initial\n",
+ "deal costs $13. You may quit at this point or inspect the\n",
+ "game. Inspection costs $13 and allows you to make as many\n",
+ "moves as is possible without moving any cards from your hand\n",
+ "to the talon. (the initial deal places three cards on the\n",
+ "talon; if all these cards are used, three more are made\n",
+ "available) Finally, if the game seems interesting, you must\n",
+ "pay the final installment of $26. At this point you are\n",
+ "credited at the rate of $5 for each card on the foundation;\n",
+ "as the game progresses you are credited with $5 for each\n",
+ "card that is moved to the foundation. Each run through the\n",
+ "hand after the first costs $5. The card counting feature\n",
+ "costs $1 for each unknown card that is identified. If the\n",
+ "information is toggled on, you are only charged for cards\n",
+ "that became visible since it was last turned on. Thus the\n",
+ "maximum cost of information is $34. Playing time is charged\n",
+ "at a rate of $1 per minute.\n\n",
+ "push any key when you are finished: ",
+ 0 };
+
+/*
+ * procedure to printout instructions
+ */
+instruct()
+{
+ register char **cp;
+
+ move(originrow, origincol);
+ printw("This is the game of solitaire called Canfield. Do\n");
+ printw("you want instructions for the game?");
+ do {
+ getcmd(originrow + 3, origincol, "y or n?");
+ } while (srcpile != 'y' && srcpile != 'n');
+ if (srcpile == 'n')
+ return;
+ clear();
+ for (cp = basicinstructions; *cp != 0; cp++)
+ printw(*cp);
+ refresh();
+ getch();
+ clear();
+ move(originrow, origincol);
+ printw("Do you want instructions for betting?");
+ do {
+ getcmd(originrow + 2, origincol, "y or n?");
+ } while (srcpile != 'y' && srcpile != 'n');
+ if (srcpile == 'n')
+ return;
+ clear();
+ for (cp = bettinginstructions; *cp != 0; cp++)
+ printw(*cp);
+ refresh();
+ getch();
+}
+
+/*
+ * procedure to initialize the game
+ */
+initall()
+{
+ int i;
+
+ srandom(getpid());
+ time(&acctstart);
+ initdeck(deck);
+ uid = getuid();
+ if (uid < 0)
+ uid = 0;
+ dbfd = open(_PATH_SCORE, 2);
+ if (dbfd < 0)
+ return;
+ i = lseek(dbfd, uid * sizeof(struct betinfo), 0);
+ if (i < 0) {
+ close(dbfd);
+ dbfd = -1;
+ return;
+ }
+ i = read(dbfd, (char *)&total, sizeof(total));
+ if (i < 0) {
+ close(dbfd);
+ dbfd = -1;
+ return;
+ }
+}
+
+/*
+ * procedure to end the game
+ */
+bool
+finish()
+{
+ int row, col;
+
+ if (cardsoff == 52) {
+ getcmd(moverow, movecol, "Hit return to exit");
+ clear();
+ refresh();
+ move(originrow, origincol);
+ printw("CONGRATULATIONS!\n");
+ printw("You won the game. That is a feat to be proud of.\n");
+ row = originrow + 5;
+ col = origincol;
+ } else {
+ move(msgrow, msgcol);
+ printw("You got %d card", cardsoff);
+ if (cardsoff > 1)
+ printw("s");
+ printw(" off ");
+ move(msgrow, msgcol);
+ row = moverow;
+ col = movecol;
+ }
+ do {
+ getcmd(row, col, "Play again (y or n)?");
+ } while (srcpile != 'y' && srcpile != 'n');
+ errmsg = TRUE;
+ clearmsg();
+ if (srcpile == 'y')
+ return (FALSE);
+ else
+ return (TRUE);
+}
+
+/*
+ * procedure to clean up and exit
+ */
+void
+cleanup()
+{
+
+ total.thinktime += 1;
+ status = NOBOX;
+ updatebettinginfo();
+ if (dbfd != -1) {
+ lseek(dbfd, uid * sizeof(struct betinfo), 0);
+ write(dbfd, (char *)&total, sizeof(total));
+ close(dbfd);
+ }
+ clear();
+ move(22,0);
+ refresh();
+ endwin();
+ exit(0);
+ /* NOTREACHED */
+}
+
+/*
+ * Field an interrupt.
+ */
+void
+askquit()
+{
+ move(msgrow, msgcol);
+ printw("Really wish to quit? ");
+ do {
+ getcmd(moverow, movecol, "y or n?");
+ } while (srcpile != 'y' && srcpile != 'n');
+ clearmsg();
+ if (srcpile == 'y')
+ cleanup();
+ signal(SIGINT, askquit);
+}
+
+/*
+ * Can you tell that this used to be a Pascal program?
+ */
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef MAXLOAD
+ double vec[3];
+
+ loadav(vec);
+ if (vec[2] >= MAXLOAD) {
+ puts("The system load is too high. Try again later.");
+ exit(0);
+ }
+#endif
+ signal(SIGINT, askquit);
+ signal(SIGHUP, cleanup);
+ signal(SIGTERM, cleanup);
+ initscr();
+ raw();
+ noecho();
+ initall();
+ instruct();
+ makeboard();
+ for (;;) {
+ startgame();
+ movecard();
+ if (finish())
+ break;
+ if (cardsoff == 52)
+ makeboard();
+ else
+ cleanupboard();
+ }
+ cleanup();
+ /* NOTREACHED */
+}
diff --git a/canfield/canfield/pathnames.h b/canfield/canfield/pathnames.h
new file mode 100644
index 00000000..f3442304
--- /dev/null
+++ b/canfield/canfield/pathnames.h
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 4/30/90
+ */
+
+#define _PATH_SCORE "/var/games/cfscores"
+
diff --git a/canfield/cfscores/Makefile b/canfield/cfscores/Makefile
new file mode 100644
index 00000000..c4479ad7
--- /dev/null
+++ b/canfield/cfscores/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 5.2 (Berkeley) 4/8/91
+
+PROG= cfscores
+CFLAGS+=-I${.CURDIR}/../canfield
+NOMAN= noman
+HIDEGAME=hidegame
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/canfield/cfscores/cfscores.c b/canfield/cfscores/cfscores.c
new file mode 100644
index 00000000..645da6f6
--- /dev/null
+++ b/canfield/cfscores/cfscores.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)cfscores.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <pwd.h>
+#include "pathnames.h"
+
+struct betinfo {
+ long hand; /* cost of dealing hand */
+ long inspection; /* cost of inspecting hand */
+ long game; /* cost of buying game */
+ long runs; /* cost of running through hands */
+ long information; /* cost of information */
+ long thinktime; /* cost of thinking time */
+ long wins; /* total winnings */
+ long worth; /* net worth after costs */
+};
+
+int dbfd;
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ register struct passwd *pw;
+ int uid;
+
+ if (argc > 2) {
+ printf("Usage: cfscores [user]\n");
+ exit(1);
+ }
+ dbfd = open(_PATH_SCORE, 0);
+ if (dbfd < 0) {
+ perror(_PATH_SCORE);
+ exit(2);
+ }
+ setpwent();
+ if (argc == 1) {
+ uid = getuid();
+ pw = getpwuid(uid);
+ if (pw == 0) {
+ printf("You are not listed in the password file?!?\n");
+ exit(2);
+ }
+ printuser(pw, 1);
+ exit(0);
+ }
+ if (strcmp(argv[1], "-a") == 0) {
+ while ((pw = getpwent()) != 0)
+ printuser(pw, 0);
+ exit(0);
+ }
+ pw = getpwnam(argv[1]);
+ if (pw == 0) {
+ printf("User %s unknown\n", argv[1]);
+ exit(3);
+ }
+ printuser(pw, 1);
+ exit(0);
+}
+
+/*
+ * print out info for specified password entry
+ */
+printuser(pw, printfail)
+ register struct passwd *pw;
+ int printfail;
+{
+ struct betinfo total;
+ int i;
+
+ if (pw->pw_uid < 0) {
+ printf("Bad uid %d\n", pw->pw_uid);
+ return;
+ }
+ i = lseek(dbfd, pw->pw_uid * sizeof(struct betinfo), 0);
+ if (i < 0) {
+ perror("lseek");
+ return;
+ }
+ i = read(dbfd, (char *)&total, sizeof(total));
+ if (i < 0) {
+ perror("read");
+ return;
+ }
+ if (i == 0 || total.hand == 0) {
+ if (printfail)
+ printf("%s has never played canfield.\n", pw->pw_name);
+ return;
+ }
+ printf("*----------------------*\n");
+ if (total.worth >= 0)
+ printf("* Winnings for %-8s*\n", pw->pw_name);
+ else
+ printf("* Losses for %-10s*\n", pw->pw_name);
+ printf("*======================*\n");
+ printf("|Costs Total |\n");
+ printf("| Hands %8d |\n", total.hand);
+ printf("| Inspections %8d |\n", total.inspection);
+ printf("| Games %8d |\n", total.game);
+ printf("| Runs %8d |\n", total.runs);
+ printf("| Information %8d |\n", total.information);
+ printf("| Think time %8d |\n", total.thinktime);
+ printf("|Total Costs %8d |\n", total.wins - total.worth);
+ printf("|Winnings %8d |\n", total.wins);
+ printf("|Net Worth %8d |\n", total.worth);
+ printf("*----------------------*\n\n");
+}
diff --git a/cribbage/Makefile b/cribbage/Makefile
new file mode 100644
index 00000000..81e39ae3
--- /dev/null
+++ b/cribbage/Makefile
@@ -0,0 +1,14 @@
+# @(#)Makefile 5.11 (Berkeley) 5/11/90
+
+PROG= cribbage
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermlib -lcompat
+SRCS= extern.c crib.c cards.c instr.c io.c score.c support.c
+MAN6= cribbage.0
+HIDEGAME=hidegame
+
+beforeinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/cribbage.n \
+ ${DESTDIR}/usr/share/games/cribbage.instr
+
+.include <bsd.prog.mk>
diff --git a/cribbage/cards.c b/cribbage/cards.c
new file mode 100644
index 00000000..c7314128
--- /dev/null
+++ b/cribbage/cards.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cards.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "deck.h"
+
+
+/*
+ * initialize a deck of cards to contain one of each type
+ */
+
+makedeck( d )
+
+ CARD d[];
+{
+ register int i, j, k;
+ long time();
+
+ i = time( (long *) 0 );
+ i = ( (i&0xff) << 8 ) | ( (i >> 8)&0xff ) | 1;
+ srand( i );
+ k = 0;
+ for( i = 0; i < RANKS; i++ ) {
+ for( j = 0; j < SUITS; j++ ) {
+ d[k].suit = j;
+ d[k++].rank = i;
+ }
+ }
+}
+
+
+
+/*
+ * given a deck of cards, shuffle it -- i.e. randomize it
+ * see Knuth, vol. 2, page 125
+ */
+
+shuffle( d )
+
+ CARD d[];
+{
+ register int j, k;
+ CARD c;
+
+ for( j = CARDS; j > 0; --j ) {
+ k = ( rand() >> 4 ) % j; /* random 0 <= k < j */
+ c = d[j - 1]; /* exchange (j - 1) and k */
+ d[j - 1] = d[k];
+ d[k] = c;
+ }
+}
+
+
+
+/*
+ * return true if the two cards are equal...
+ */
+
+eq( a, b )
+
+ CARD a, b;
+{
+ return( ( a.rank == b.rank ) && ( a.suit == b.suit ) );
+}
+
+
+
+/*
+ * isone returns TRUE if a is in the set of cards b
+ */
+
+isone( a, b, n )
+
+ CARD a, b[];
+ int n;
+{
+ register int i;
+
+ for( i = 0; i < n; i++ ) {
+ if( eq( a, b[i] ) ) return( TRUE );
+ }
+ return( FALSE );
+}
+
+
+
+/*
+ * remove the card a from the deck d of n cards
+ */
+
+cremove( a, d, n )
+
+ CARD a, d[];
+ int n;
+{
+ register int i, j;
+
+ j = 0;
+ for( i = 0; i < n; i++ ) {
+ if( !eq( a, d[i] ) ) d[j++] = d[i];
+ }
+ if( j < n ) d[j].suit = d[j].rank = EMPTY;
+}
+
+
+
+/*
+ * sorthand:
+ * Sort a hand of n cards
+ */
+sorthand(h, n)
+register CARD h[];
+int n;
+{
+ register CARD *cp, *endp;
+ CARD c;
+
+ for (endp = &h[n]; h < endp - 1; h++)
+ for (cp = h + 1; cp < endp; cp++)
+ if ((cp->rank < h->rank) ||
+ (cp->rank == h->rank && cp->suit < h->suit)) {
+ c = *h;
+ *h = *cp;
+ *cp = c;
+ }
+}
+
diff --git a/cribbage/crib.c b/cribbage/crib.c
new file mode 100644
index 00000000..d1d8bc74
--- /dev/null
+++ b/cribbage/crib.c
@@ -0,0 +1,610 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)crib.c 5.6 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include <sys/signal.h>
+# include <curses.h>
+# include "deck.h"
+# include "cribbage.h"
+# include "cribcur.h"
+# include "pathnames.h"
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ register char *p;
+ int ch;
+ BOOLEAN playing;
+ char *s; /* for reading arguments */
+ FILE *f;
+ FILE *fopen();
+ char *getline(), *getlogin();
+ void rint();
+
+ while ((ch = getopt(argc, argv, "eqr")) != EOF)
+ switch(ch) {
+ case 'e':
+ explain = TRUE;
+ break;
+ case 'q':
+ quiet = TRUE;
+ break;
+ case 'r':
+ rflag = TRUE;
+ break;
+ case '?':
+ default:
+ (void) fprintf(stderr, "usage: cribbage [-eqr]\n");
+ exit(1);
+ }
+
+ initscr();
+ signal(SIGINT, rint);
+ crmode();
+ noecho();
+ Playwin = subwin(stdscr, PLAY_Y, PLAY_X, 0, 0);
+ Tablewin = subwin(stdscr, TABLE_Y, TABLE_X, 0, PLAY_X);
+ Compwin = subwin(stdscr, COMP_Y, COMP_X, 0, TABLE_X + PLAY_X);
+ Msgwin = subwin(stdscr, MSG_Y, MSG_X, Y_MSG_START, SCORE_X + 1);
+ leaveok(Playwin, TRUE);
+ leaveok(Tablewin, TRUE);
+ leaveok(Compwin, TRUE);
+ clearok(stdscr, FALSE);
+
+ if (!quiet) {
+ msg("Do you need instructions for cribbage? ");
+ if (getuchar() == 'Y') {
+ endwin();
+ clear();
+ mvcur(0, COLS - 1, LINES - 1, 0);
+ fflush(stdout);
+ instructions();
+ crmode();
+ noecho();
+ clear();
+ refresh();
+ msg("For the rules of this program, do \"man cribbage\"");
+ }
+ }
+ playing = TRUE;
+ do {
+ wclrtobot(Msgwin);
+ msg(quiet ? "L or S? " : "Long (to 121) or Short (to 61)? ");
+ if (glimit == SGAME)
+ glimit = (getuchar() == 'L' ? LGAME : SGAME);
+ else
+ glimit = (getuchar() == 'S' ? SGAME : LGAME);
+ game();
+ msg("Another game? ");
+ playing = (getuchar() == 'Y');
+ } while (playing);
+
+ if (f = fopen(_PATH_LOG, "a")) {
+ (void)fprintf(f, "%s: won %5.5d, lost %5.5d\n",
+ getlogin(), cgames, pgames);
+ (void)fclose(f);
+ }
+ bye();
+ if (!f) {
+ (void)fprintf(stderr, "\ncribbage: can't open %s.\n",
+ _PATH_LOG);
+ exit(1);
+ }
+ exit(0);
+}
+
+/*
+ * makeboard:
+ * Print out the initial board on the screen
+ */
+makeboard()
+{
+ mvaddstr(SCORE_Y + 0, SCORE_X, "+---------------------------------------+");
+ mvaddstr(SCORE_Y + 1, SCORE_X, "| Score: 0 YOU |");
+ mvaddstr(SCORE_Y + 2, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
+ mvaddstr(SCORE_Y + 3, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
+ mvaddstr(SCORE_Y + 4, SCORE_X, "| |");
+ mvaddstr(SCORE_Y + 5, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
+ mvaddstr(SCORE_Y + 6, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
+ mvaddstr(SCORE_Y + 7, SCORE_X, "| Score: 0 ME |");
+ mvaddstr(SCORE_Y + 8, SCORE_X, "+---------------------------------------+");
+ gamescore();
+}
+
+/*
+ * gamescore:
+ * Print out the current game score
+ */
+gamescore()
+{
+ extern int Lastscore[];
+
+ if (pgames || cgames) {
+ mvprintw(SCORE_Y + 1, SCORE_X + 28, "Games: %3d", pgames);
+ mvprintw(SCORE_Y + 7, SCORE_X + 28, "Games: %3d", cgames);
+ }
+ Lastscore[0] = -1;
+ Lastscore[1] = -1;
+}
+
+/*
+ * game:
+ * Play one game up to glimit points. Actually, we only ASK the
+ * player what card to turn. We do a random one, anyway.
+ */
+game()
+{
+ register int i, j;
+ BOOLEAN flag;
+ BOOLEAN compcrib;
+
+ makeboard();
+ refresh();
+ makedeck(deck);
+ shuffle(deck);
+ if (gamecount == 0) {
+ flag = TRUE;
+ do {
+ if (!rflag) { /* player cuts deck */
+ msg(quiet ? "Cut for crib? " :
+ "Cut to see whose crib it is -- low card wins? ");
+ getline();
+ }
+ i = (rand() >> 4) % CARDS; /* random cut */
+ do { /* comp cuts deck */
+ j = (rand() >> 4) % CARDS;
+ } while (j == i);
+ addmsg(quiet ? "You cut " : "You cut the ");
+ msgcard(deck[i], FALSE);
+ endmsg();
+ addmsg(quiet ? "I cut " : "I cut the ");
+ msgcard(deck[j], FALSE);
+ endmsg();
+ flag = (deck[i].rank == deck[j].rank);
+ if (flag) {
+ msg(quiet ? "We tied..." :
+ "We tied and have to try again...");
+ shuffle(deck);
+ continue;
+ }
+ else
+ compcrib = (deck[i].rank > deck[j].rank);
+ } while (flag);
+ }
+ else {
+ werase(Tablewin);
+ wrefresh(Tablewin);
+ werase(Compwin);
+ wrefresh(Compwin);
+ msg("Loser (%s) gets first crib", (iwon ? "you" : "me"));
+ compcrib = !iwon;
+ }
+
+ pscore = cscore = 0;
+ flag = TRUE;
+ do {
+ shuffle(deck);
+ flag = !playhand(compcrib);
+ compcrib = !compcrib;
+ } while (flag);
+ ++gamecount;
+ if (cscore < pscore) {
+ if (glimit - cscore > 60) {
+ msg("YOU DOUBLE SKUNKED ME!");
+ pgames += 4;
+ }
+ else if (glimit - cscore > 30) {
+ msg("YOU SKUNKED ME!");
+ pgames += 2;
+ }
+ else {
+ msg("YOU WON!");
+ ++pgames;
+ }
+ iwon = FALSE;
+ }
+ else {
+ if (glimit - pscore > 60) {
+ msg("I DOUBLE SKUNKED YOU!");
+ cgames += 4;
+ }
+ else if (glimit - pscore > 30) {
+ msg("I SKUNKED YOU!");
+ cgames += 2;
+ }
+ else {
+ msg("I WON!");
+ ++cgames;
+ }
+ iwon = TRUE;
+ }
+ gamescore();
+}
+
+/*
+ * playhand:
+ * Do up one hand of the game
+ */
+playhand(mycrib)
+BOOLEAN mycrib;
+{
+ register int deckpos;
+ extern char Msgbuf[];
+
+ werase(Compwin);
+
+ knownum = 0;
+ deckpos = deal(mycrib);
+ sorthand(chand, FULLHAND);
+ sorthand(phand, FULLHAND);
+ makeknown(chand, FULLHAND);
+ prhand(phand, FULLHAND, Playwin, FALSE);
+ discard(mycrib);
+ if (cut(mycrib, deckpos))
+ return TRUE;
+ if (peg(mycrib))
+ return TRUE;
+ werase(Tablewin);
+ wrefresh(Tablewin);
+ if (score(mycrib))
+ return TRUE;
+ return FALSE;
+}
+
+
+
+/*
+ * deal cards to both players from deck
+ */
+
+deal( mycrib )
+{
+ register int i, j;
+
+ j = 0;
+ for( i = 0; i < FULLHAND; i++ ) {
+ if( mycrib ) {
+ phand[i] = deck[j++];
+ chand[i] = deck[j++];
+ }
+ else {
+ chand[i] = deck[j++];
+ phand[i] = deck[j++];
+ }
+ }
+ return( j );
+}
+
+/*
+ * discard:
+ * Handle players discarding into the crib...
+ * Note: we call cdiscard() after prining first message so player doesn't wait
+ */
+discard(mycrib)
+BOOLEAN mycrib;
+{
+ register char *prompt;
+ CARD crd;
+
+ prcrib(mycrib, TRUE);
+ prompt = (quiet ? "Discard --> " : "Discard a card --> ");
+ cdiscard(mycrib); /* puts best discard at end */
+ crd = phand[infrom(phand, FULLHAND, prompt)];
+ cremove(crd, phand, FULLHAND);
+ prhand(phand, FULLHAND, Playwin, FALSE);
+ crib[0] = crd;
+/* next four lines same as last four except for cdiscard() */
+ crd = phand[infrom(phand, FULLHAND - 1, prompt)];
+ cremove(crd, phand, FULLHAND - 1);
+ prhand(phand, FULLHAND, Playwin, FALSE);
+ crib[1] = crd;
+ crib[2] = chand[4];
+ crib[3] = chand[5];
+ chand[4].rank = chand[4].suit = chand[5].rank = chand[5].suit = EMPTY;
+}
+
+/*
+ * cut:
+ * Cut the deck and set turnover. Actually, we only ASK the
+ * player what card to turn. We do a random one, anyway.
+ */
+cut(mycrib, pos)
+BOOLEAN mycrib;
+int pos;
+{
+ register int i, cardx;
+ BOOLEAN win = FALSE;
+
+ if (mycrib) {
+ if (!rflag) { /* random cut */
+ msg(quiet ? "Cut the deck? " :
+ "How many cards down do you wish to cut the deck? ");
+ getline();
+ }
+ i = (rand() >> 4) % (CARDS - pos);
+ turnover = deck[i + pos];
+ addmsg(quiet ? "You cut " : "You cut the ");
+ msgcard(turnover, FALSE);
+ endmsg();
+ if (turnover.rank == JACK) {
+ msg("I get two for his heels");
+ win = chkscr(&cscore,2 );
+ }
+ }
+ else {
+ i = (rand() >> 4) % (CARDS - pos) + pos;
+ turnover = deck[i];
+ addmsg(quiet ? "I cut " : "I cut the ");
+ msgcard(turnover, FALSE);
+ endmsg();
+ if (turnover.rank == JACK) {
+ msg("You get two for his heels");
+ win = chkscr(&pscore, 2);
+ }
+ }
+ makeknown(&turnover, 1);
+ prcrib(mycrib, FALSE);
+ return win;
+}
+
+/*
+ * prcrib:
+ * Print out the turnover card with crib indicator
+ */
+prcrib(mycrib, blank)
+BOOLEAN mycrib, blank;
+{
+ register int y, cardx;
+
+ if (mycrib)
+ cardx = CRIB_X;
+ else
+ cardx = 0;
+
+ mvaddstr(CRIB_Y, cardx + 1, "CRIB");
+ prcard(stdscr, CRIB_Y + 1, cardx, turnover, blank);
+
+ if (mycrib)
+ cardx = 0;
+ else
+ cardx = CRIB_X;
+
+ for (y = CRIB_Y; y <= CRIB_Y + 5; y++)
+ mvaddstr(y, cardx, " ");
+}
+
+/*
+ * peg:
+ * Handle all the pegging...
+ */
+
+static CARD Table[14];
+
+static int Tcnt;
+
+peg(mycrib)
+BOOLEAN mycrib;
+{
+ static CARD ch[CINHAND], ph[CINHAND];
+ CARD crd;
+ register int i, j, k;
+ register int l;
+ register int cnum, pnum, sum;
+ register BOOLEAN myturn, mego, ugo, last, played;
+
+ cnum = pnum = CINHAND;
+ for (i = 0; i < CINHAND; i++) { /* make copies of hands */
+ ch[i] = chand[i];
+ ph[i] = phand[i];
+ }
+ Tcnt = 0; /* index to table of cards played */
+ sum = 0; /* sum of cards played */
+ mego = ugo = FALSE;
+ myturn = !mycrib;
+ for (;;) {
+ last = TRUE; /* enable last flag */
+ prhand(ph, pnum, Playwin, FALSE);
+ prhand(ch, cnum, Compwin, TRUE);
+ prtable(sum);
+ if (myturn) { /* my tyrn to play */
+ if (!anymove(ch, cnum, sum)) { /* if no card to play */
+ if (!mego && cnum) { /* go for comp? */
+ msg("GO");
+ mego = TRUE;
+ }
+ if (anymove(ph, pnum, sum)) /* can player move? */
+ myturn = !myturn;
+ else { /* give him his point */
+ msg(quiet ? "You get one" : "You get one point");
+ if (chkscr(&pscore, 1))
+ return TRUE;
+ sum = 0;
+ mego = ugo = FALSE;
+ Tcnt = 0;
+ }
+ }
+ else {
+ played = TRUE;
+ j = -1;
+ k = 0;
+ for (i = 0; i < cnum; i++) { /* maximize score */
+ l = pegscore(ch[i], Table, Tcnt, sum);
+ if (l > k) {
+ k = l;
+ j = i;
+ }
+ }
+ if (j < 0) /* if nothing scores */
+ j = cchose(ch, cnum, sum);
+ crd = ch[j];
+ cremove(crd, ch, cnum--);
+ sum += VAL(crd.rank);
+ Table[Tcnt++] = crd;
+ if (k > 0) {
+ addmsg(quiet ? "I get %d playing " :
+ "I get %d points playing ", k);
+ msgcard(crd, FALSE);
+ endmsg();
+ if (chkscr(&cscore, k))
+ return TRUE;
+ }
+ myturn = !myturn;
+ }
+ }
+ else {
+ if (!anymove(ph, pnum, sum)) { /* can player move? */
+ if (!ugo && pnum) { /* go for player */
+ msg("You have a GO");
+ ugo = TRUE;
+ }
+ if (anymove(ch, cnum, sum)) /* can computer play? */
+ myturn = !myturn;
+ else {
+ msg(quiet ? "I get one" : "I get one point");
+ do_wait();
+ if (chkscr(&cscore, 1))
+ return TRUE;
+ sum = 0;
+ mego = ugo = FALSE;
+ Tcnt = 0;
+ }
+ }
+ else { /* player plays */
+ played = FALSE;
+ if (pnum == 1) {
+ crd = ph[0];
+ msg("You play your last card");
+ }
+ else
+ for (;;) {
+ prhand(ph, pnum, Playwin, FALSE);
+ crd = ph[infrom(ph, pnum, "Your play: ")];
+ if (sum + VAL(crd.rank) <= 31)
+ break;
+ else
+ msg("Total > 31 -- try again");
+ }
+ makeknown(&crd, 1);
+ cremove(crd, ph, pnum--);
+ i = pegscore(crd, Table, Tcnt, sum);
+ sum += VAL(crd.rank);
+ Table[Tcnt++] = crd;
+ if (i > 0) {
+ msg(quiet ? "You got %d" : "You got %d points", i);
+ if (chkscr(&pscore, i))
+ return TRUE;
+ }
+ myturn = !myturn;
+ }
+ }
+ if (sum >= 31) {
+ if (!myturn)
+ do_wait();
+ sum = 0;
+ mego = ugo = FALSE;
+ Tcnt = 0;
+ last = FALSE; /* disable last flag */
+ }
+ if (!pnum && !cnum)
+ break; /* both done */
+ }
+ prhand(ph, pnum, Playwin, FALSE);
+ prhand(ch, cnum, Compwin, TRUE);
+ prtable(sum);
+ if (last)
+ if (played) {
+ msg(quiet ? "I get one for last" : "I get one point for last");
+ do_wait();
+ if (chkscr(&cscore, 1))
+ return TRUE;
+ }
+ else {
+ msg(quiet ? "You get one for last" :
+ "You get one point for last");
+ if (chkscr(&pscore, 1))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * prtable:
+ * Print out the table with the current score
+ */
+prtable(score)
+int score;
+{
+ prhand(Table, Tcnt, Tablewin, FALSE);
+ mvwprintw(Tablewin, (Tcnt + 2) * 2, Tcnt + 1, "%2d", score);
+ wrefresh(Tablewin);
+}
+
+/*
+ * score:
+ * Handle the scoring of the hands
+ */
+score(mycrib)
+BOOLEAN mycrib;
+{
+ sorthand(crib, CINHAND);
+ if (mycrib) {
+ if (plyrhand(phand, "hand"))
+ return TRUE;
+ if (comphand(chand, "hand"))
+ return TRUE;
+ do_wait();
+ if (comphand(crib, "crib"))
+ return TRUE;
+ }
+ else {
+ if (comphand(chand, "hand"))
+ return TRUE;
+ if (plyrhand(phand, "hand"))
+ return TRUE;
+ if (plyrhand(crib, "crib"))
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/cribbage/cribbage.6 b/cribbage/cribbage.6
new file mode 100644
index 00000000..59c6500d
--- /dev/null
+++ b/cribbage/cribbage.6
@@ -0,0 +1,129 @@
+.\" Copyright (c) 1980 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)cribbage.6 6.5 (Berkeley) 6/23/90
+.\"
+.TH CRIBBAGE 6 "June 23, 1990"
+.UC 4
+.SH NAME
+cribbage \- the card game cribbage
+.SH SYNOPSIS
+.B /usr/games/cribbage
+[
+.B \-req
+]
+.I name ...
+.SH DESCRIPTION
+.I Cribbage
+plays the card game cribbage, with the program playing one hand
+and the user the other. The program will initially ask the user if
+the rules of the game are needed \- if so, it will print out
+the appropriate section from
+.I According to Hoyle
+with
+.I more (I).
+.PP
+.I Cribbage
+options include:
+.TP
+.B \-e
+When the player makes a mistake scoring his hand or crib, provide an
+explanation of the correct score. (This is especially useful for
+beginning players.)
+.TP
+.B \-q
+Print a shorter form of all messages \- this is only recommended for
+users who have played the game without specifying this option.
+.TP
+.B \-r
+Instead of asking the player to cut the deck, the program will randomly
+cut the deck.
+.PP
+.I Cribbage
+first asks the player whether he wishes to play a short game
+(\*(lqonce around\*(rq, to 61) or a long game (\*(lqtwice around\*(rq, to 121). A
+response of `s' will result in a short game, any other response will
+play a long game.
+.PP
+At the start of the first game, the program
+asks the player to cut the deck to determine who gets the
+first crib. The user should respond with a number between 0 and
+51, indicating how many cards down the deck is to be cut. The player
+who cuts the lower ranked card gets the first crib.
+If more than one game is played, the
+loser of the previous game gets the first crib in the current game.
+.PP
+For each hand, the program first prints the player's hand,
+whose crib it is, and then asks the player
+to discard two cards into the crib. The cards are prompted for
+one per line, and are typed as explained below.
+.PP
+After discarding, the program cuts the deck (if it is the player's
+crib) or asks the player to cut the deck (if it's its crib); in the latter
+case, the appropriate response is a number from 0 to 39 indicating
+how far down the remaining 40 cards are to be cut.
+.PP
+After cutting the deck, play starts with the non-dealer (the person
+who doesn't have the crib) leading the first card.
+Play continues, as per cribbage, until all cards are exhausted. The
+program keeps track of the scoring of all points and the total of
+the cards on the table.
+.PP
+After play, the hands are scored. The program requests the player to
+score his hand (and the crib, if it is his) by printing out the
+appropriate cards (and the cut card enclosed in brackets).
+Play continues until one player reaches the game limit (61 or 121).
+.PP
+A carriage return when a numeric input is expected is equivalent
+to typing the lowest legal value; when cutting the deck this
+is equivalent to choosing the top card.
+.PP
+Cards are specified as rank followed by suit. The ranks may be specified
+as one of:
+`a', `2', `3', `4', `5', `6', `7', `8', `9', `t', `j', `q', and `k',
+or alternatively, one of: \*(lqace\*(rq, \*(lqtwo\*(rq, \*(lqthree\*(rq, \*(lqfour\*(rq, \*(lqfive\*(rq, \*(lqsix\*(rq,
+\*(lqseven\*(rq, \*(lqeight\*(rq, \*(lqnine\*(rq, \*(lqten\*(rq, \*(lqjack\*(rq, \*(lqqueen\*(rq, and \*(lqking\*(rq.
+Suits may be specified as: `s', `h', `d', and `c', or alternatively as:
+\*(lqspades\*(rq, \*(lqhearts\*(rq, \*(lqdiamonds\*(rq, and \*(lqclubs\*(rq.
+A card may be specified as: <rank> \*(lq \*(rq <suit>, or: <rank> \*(lq of \*(rq <suit>.
+If the single letter rank and suit designations are used, the space
+separating the suit and rank may be left out. Also, if only one card
+of the desired rank is playable, typing the rank is sufficient.
+For example, if your hand was \*(lq2H, 4D, 5C, 6H, JC, KD\*(rq and it was
+desired to discard the king of diamonds, any of the following could be typed:
+\*(lqk\*(rq, \*(lqking\*(rq, \*(lqkd\*(rq, \*(lqk d\*(rq, \*(lqk of d\*(rq, \*(lqking d\*(rq, \*(lqking of d\*(rq, \*(lqk diamonds\*(rq,
+\*(lqk of diamonds\*(rq, \*(lqking diamonds\*(rq, or \*(lqking of diamonds\*(rq.
+.SH FILES
+.ta 2i
+/usr/games/cribbage
+.SH AUTHORS
+Earl T. Cohen wrote the logic.
+Ken Arnold added the screen oriented interface.
diff --git a/cribbage/cribbage.h b/cribbage/cribbage.h
new file mode 100644
index 00000000..952d79b0
--- /dev/null
+++ b/cribbage/cribbage.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cribbage.h 5.4 (Berkeley) 6/1/90
+ */
+
+extern CARD deck[ CARDS ]; /* a deck */
+extern CARD phand[ FULLHAND ]; /* player's hand */
+extern CARD chand[ FULLHAND ]; /* computer's hand */
+extern CARD crib[ CINHAND ]; /* the crib */
+extern CARD turnover; /* the starter */
+
+extern CARD known[ CARDS ]; /* cards we have seen */
+extern int knownum; /* # of cards we know */
+
+extern int pscore; /* player's score */
+extern int cscore; /* comp's score */
+extern int glimit; /* points to win game */
+
+extern int pgames; /* player's games won */
+extern int cgames; /* comp's games won */
+extern int gamecount; /* # games played */
+extern int Lastscore[2]; /* previous score for each */
+
+extern BOOLEAN iwon; /* if comp won last */
+extern BOOLEAN explain; /* player mistakes explained */
+extern BOOLEAN rflag; /* if all cuts random */
+extern BOOLEAN quiet; /* if suppress random mess */
+extern BOOLEAN playing; /* currently playing game */
+
+extern char expl[]; /* string for explanation */
+
diff --git a/cribbage/cribbage.n b/cribbage/cribbage.n
new file mode 100644
index 00000000..084e0917
--- /dev/null
+++ b/cribbage/cribbage.n
@@ -0,0 +1,226 @@
+
+ CRIBBAGE
+ from
+ According to Hoyle
+
+Cribbage is believed to have been invented by Sir John Suckling (1609-1642).
+Probably it is an elaboration of an older game, Noddy. The original game
+was played with hands of five cards; the modern game gives each player
+six. That is virtually the only change from Suckling's directions.
+
+Players:
+
+ Two. There are variants for three and four players, described
+ later.
+
+Cards:
+
+ The pack of 52. The cards in each suit rank: K (high), Q, J, 10,
+9, 8, 7, 6, 5, 4, 3, 2, A. The counting values are: K, Q, J, 10, each 10
+(wherefore these are called tenth cards); ace, 1; each other card, its
+index value.
+
+Cribbage Board:
+
+ Indispensable to scoring (unless you have a computer!, ed.) is
+the device known as the cribbage board. This is a rectangular panel, long
+and narrow, in which are four rows of 30 holes each. (See illustration.)
+At one end, or in the center, are two or four additional holes, called
+game holes. The board is placed between the two players, and each keeps
+his own score on the two rows of holes nearest himself. Each is supplied
+with two pegs. Before the first hand, the pegs are placed in the game
+holes. On making his first score, the player advances one peg an
+appropriate number of holes (one per point) away from the game end of the
+board. The second score is recorded by placing the second peg an
+appropriate distance ahead of the first. For each subsequent score, the
+rear peg is jumped ahead of the other, the distance between the two pegs
+always showing the amount of this last score.
+
+ The traditional mode of scoring is down (away from the game end)
+the outer row, and up the inner row. "Once around" is a game of 61 points.
+"Twice around" is a game of 121 points.
+
+Preliminaries:
+
+ Cards are drawn; the lower deals first. If cards of equal rank
+are drawn, both players draw again. Dealer has the right to shuffle last.
+Nondealer cuts, and must leave at least four cards in each packet.
+
+Dealing:
+
+ Each player receives six cards, dealt one at a time face down,
+beginning with the nondealer. The turn to deal alternates. The dealer
+has an advantage.
+
+Laying Away:
+
+ After seeing his hand, each player lays away two cards face down.
+The four cards laid away, placed in one pile, form the crib. The crib
+counts for the dealer. Nondealer therefore tries to lay away balking
+cards -- cards that are least likely to create a score in the crib.
+
+The Starter:
+
+ After both hands have laid away, nondealer lifts off a packet from
+the top of the stock (the rest of the pack). Again, each packet must
+contain at least four cards. Dealer turns up the top card of the lower
+packer, which is then placed on top of the stock when the packets are
+reunited. The card thus turned up is called 1 the starter. If it is a
+jack, dealer immediately pegs 2, called 2 for his heels.
+
+The Play:
+
+ Nondealer begins the play by laying a card from his hand face up
+on the table, announcing its counting value. Dealer then shows a card,
+announcing the total count of the two cards. Play continues in the same
+way, by alternate exposure of cards, each player announcing the new total
+count. The total may be carried only to 31, no further. If a player adds
+a card that brings the total exactly to 31, he pegs 2. If a player is
+unable to play another card without exceeding 31, he must say "Go," and
+his opponent pegs 1, but before doing so, opponent must lay down any
+additional cards he can without exceeding 31. If such additional cards
+bring the total to exactly 31, he pegs 2 instead of 1.
+
+ Whenever a go occurs, the opponent of the player who played the
+last card must lead for a new count starting at zero. Playing the last
+card of all counts as a go. (Since nondealer makes the opening lead,
+dealer is bound to peg at least 1 in play.)
+
+ Besides pegging for 31 and go, the player may also peg for certain
+combinations made in play, as follows:
+
+ Fifteen:
+ Making the count total 15 pegs 2.
+ Pair:
+ Playing a card of same rank as that previously played pegs
+ 2. Playing a third card of the same rank makes pair royal
+ and pegs 6. Playing the fourth card of the same rank
+ makes double pair royal and pegs 12.
+
+ The tenth cards pair strictly by rank, a king with a king,
+ a queen with a queen, and so on. (King and jack do not
+ make a pair, although each has the counting value 10.)
+ Run:
+ Playing a card which, with the two or more played
+ immediately previously, makes a sequence of three or more
+ cards, pegs 1 for each card in the run. Runs depend on
+ rank alone; the suits do not matter. Nor does the score
+ for run depend upon playing the cards in strict sequence,
+ so long as the three or more last cards played can be
+ arranged in a run. Example: 7, 6, 8 played in that order
+ score 3 for run; 5, 2, 4, 3 played in that order score 4
+ for run.
+
+ Any of the foregoing combinations count, whether the cards
+ are played alternately or one player plays several times
+ in succession in consequence of a go. But a combination
+ does not score if it is interrupted by a go.
+
+ Showing:
+ After the play, the hands are shown (counted). Nondealer
+ shows first, then dealer's hand, then crib. The starter
+ is deemed to belong to each hand, so that each hand includes
+ five cards. Combinations of scoring value are as follows:
+
+ Fifteen:
+ Each combinations of two or more cards that total
+ fifteen scores 2.
+ Pair:
+ Each pair of cards of the same rank scores 2.
+
+ Run:
+ Each combination of three or more cards in sequence
+ scores 1 for each card in the run.
+ Flush:
+ Four cards of the same suit in hand score 4; four
+ cards in hand or crib of same suit as the starter
+ score 5. (No count for four-flush in crib.)
+ His Nobs:
+ Jack of same suit as the starter, in hand or crib,
+ scores 1.
+
+ It is important to note that every separate grouping of cards that
+makes a fifteen, pair, or run counts separately. Three of a kind, pair
+royal, counts 6 because three sets of pairs can be made; similarly, four
+of a kind, double pair royal, contain six pairs and count 12.
+
+ The highest possible hand is J, 5, 5, 5 with the starter the 5 of
+the same suit as the jack. There are four fifteens by combining the jack
+with a five, four more by combinations of three fives (a total of 16 for
+fifteens); the double pair royal adds 12 for a total of 28; and his nobs
+adds 1 for a maximum score of 29. (the score of 2 for his heels does not
+count in the total of the hand, since it is pegged before the play.)
+
+ A double run is a run with one card duplicated, as 4-3-3-2.
+Exclusive of fifteens, a double run of three cards counts 8; of four cards,
+10. A triple run is a run of three with one card triplicated, as K-K-K-Q-J.
+Exclusive of fifteens, it counts 15. A quadruple run is a run of three
+with two different cards duplicated, as the example 8-8-7-6-6 previously
+given. Exclusive of fifteens, it counts 16.
+
+ No hand can be constructed that counts 19, 25, 26 or 27. A
+time-honored way of showing a hand with not a single counting combination
+is to say "I have nineteen."
+
+ The customary order in showing is to count fifteens first, then
+runs, then pairs, but there is no compulsion of law. Example: A hand
+(with starter) of 9-6-5-4-4 will usually be counted "Fifteen 2, fifteen
+4, fifteen 6 and double run makes 14," or simply "Fifteen 6 and 8 is 14."
+
+Muggins:
+
+ The hands and crib are counted aloud, and if a player claims a
+greater total than is due him, his opponent may require correction. In
+some localities, if a player claims less than is due, his opponent may
+say "Muggins" and himself score the points overlooked.
+
+Scoring:
+
+ The usual game is 121, but it may be set at 61 by agreement.
+Since the player wins who first returns to the game hole by going "twice
+around," the scores must be pegged strictly in order: his heels, pegging
+in play, non-dealer's hand, dealer's hand, crib. Thus, if nondealer goes
+out on showing his hand, he wins, even though dealer might have gone out
+with a greater total if allowed to count his hand and crib.
+
+ When the game of 121 is played for a stake, a player wins a single
+game if the loser makes 61 points or more. If the loser fails to reach
+61, he is lurched, and the other wins a double game.
+
+Irregularities:
+
+ Misdeal. There must be a new deal by the same dealer if a card
+is found faced in the pack, if a card is exposed in dealing, or if the
+pack be found imperfect.
+
+ Wrong Number of Cards. If one hand (not crib) is found to have
+the wrong number of cards after laying away for the crib, the other hand
+and crib being correct, the opponent may either demand a new deal or may
+peg 2 and rectify the hand. If the crib is incorrect, both hands being
+correct, nondealer pegs 2 and the crib is corrected.
+
+Error in Pegging:
+
+ If a player places a peg short of the amount to which he is
+entitled, he may not correct his error after he has played the next card
+or after the cut for the next deal. If he pegs more than his announced
+score, the error must be corrected on demand at any time before the cut
+for the next deal and his opponent pegs 2.
+
+Strategy:
+
+ The best balking cards are kings and aces, because they have the
+least chance of producing sequences. Tenth cards are generally good,
+provided that the two cards laid away are not too near (likely to make a
+sequence). When nothing better offers, give two wide cards -- at least
+three apart in rank.
+
+ Proverbially the safest lead is a 4. The next card cannot make
+a 15. Lower cards are also safe from this point of view, but are better
+treasured for go and 31. The most dangerous leads are 7 and 8, but may
+be made to trap the opponent when they are backed with other close cards.
+Generally speaking, play on (toward a sequence) when you have close cards
+and off when you do not. However, the state of the score is a
+consideration. If far behind, play on when there is any chance of building
+a score for yourself; if well ahead, balk your opponent by playing off
+unless you will surely peg as much as he by playing on.
diff --git a/cribbage/cribcur.h b/cribbage/cribcur.h
new file mode 100644
index 00000000..31f9c51d
--- /dev/null
+++ b/cribbage/cribcur.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cribcur.h 5.4 (Berkeley) 6/1/90
+ */
+
+# define PLAY_Y 15 /* size of player's hand window */
+# define PLAY_X 12
+# define TABLE_Y 21 /* size of table window */
+# define TABLE_X 14
+# define COMP_Y 15 /* size of computer's hand window */
+# define COMP_X 12
+# define Y_SCORE_SZ 9 /* Y size of score board */
+# define X_SCORE_SZ 41 /* X size of score board */
+# define SCORE_Y 0 /* starting position of scoring board */
+# define SCORE_X (PLAY_X + TABLE_X + COMP_X)
+# define CRIB_Y 17 /* position of crib (cut card) */
+# define CRIB_X (PLAY_X + TABLE_X)
+# define MSG_Y (LINES - (Y_SCORE_SZ + 1))
+# define MSG_X (COLS - SCORE_X - 1)
+# define Y_MSG_START (Y_SCORE_SZ + 1)
+
+# define PEG '*' /* what a peg looks like on the board */
+
+extern WINDOW *Compwin; /* computer's hand window */
+extern WINDOW *Msgwin; /* message window */
+extern WINDOW *Playwin; /* player's hand window */
+extern WINDOW *Tablewin; /* table window */
diff --git a/cribbage/deck.h b/cribbage/deck.h
new file mode 100644
index 00000000..2a20e5af
--- /dev/null
+++ b/cribbage/deck.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)deck.h 5.4 (Berkeley) 6/1/90
+ */
+
+/*
+ * define structure of a deck of cards and other related things
+ */
+
+
+#define CARDS 52 /* number cards in deck */
+#define RANKS 13 /* number ranks in deck */
+#define SUITS 4 /* number suits in deck */
+
+#define CINHAND 4 /* # cards in cribbage hand */
+#define FULLHAND 6 /* # cards in dealt hand */
+
+#define LGAME 121 /* number points in a game */
+#define SGAME 61 /* # points in a short game */
+
+#define SPADES 0 /* value of each suit */
+#define HEARTS 1
+#define DIAMONDS 2
+#define CLUBS 3
+
+#define ACE 0 /* value of each rank */
+#define TWO 1
+#define THREE 2
+#define FOUR 3
+#define FIVE 4
+#define SIX 5
+#define SEVEN 6
+#define EIGHT 7
+#define NINE 8
+#define TEN 9
+#define JACK 10
+#define QUEEN 11
+#define KING 12
+#define EMPTY 13
+
+#define VAL(c) ( (c) < 9 ? (c)+1 : 10 ) /* val of rank */
+
+
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif
+
+typedef struct {
+ int rank;
+ int suit;
+ } CARD;
+
+typedef char BOOLEAN;
+
diff --git a/cribbage/extern.c b/cribbage/extern.c
new file mode 100644
index 00000000..3fa18ce6
--- /dev/null
+++ b/cribbage/extern.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)extern.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <curses.h>
+# include "deck.h"
+# include "cribbage.h"
+
+bool explain = FALSE; /* player mistakes explained */
+bool iwon = FALSE; /* if comp won last game */
+bool quiet = FALSE; /* if suppress random mess */
+bool rflag = FALSE; /* if all cuts random */
+
+char expl[128]; /* explanation */
+
+int cgames = 0; /* number games comp won */
+int cscore = 0; /* comp score in this game */
+int gamecount = 0; /* number games played */
+int glimit = LGAME; /* game playe to glimit */
+int knownum = 0; /* number of cards we know */
+int pgames = 0; /* number games player won */
+int pscore = 0; /* player score in this game */
+
+CARD chand[FULLHAND]; /* computer's hand */
+CARD crib[CINHAND]; /* the crib */
+CARD deck[CARDS]; /* a deck */
+CARD known[CARDS]; /* cards we have seen */
+CARD phand[FULLHAND]; /* player's hand */
+CARD turnover; /* the starter */
+
+WINDOW *Compwin; /* computer's hand window */
+WINDOW *Msgwin; /* messages for the player */
+WINDOW *Playwin; /* player's hand window */
+WINDOW *Tablewin; /* table window */
diff --git a/cribbage/instr.c b/cribbage/instr.c
new file mode 100644
index 00000000..d5ffdc0e
--- /dev/null
+++ b/cribbage/instr.c
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)instr.c 5.2 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pathnames.h"
+
+instructions()
+{
+ extern int errno;
+ struct stat sb;
+ union wait pstat;
+ pid_t pid;
+ char *pager, *path;
+
+ if (stat(_PATH_INSTR, &sb)) {
+ (void)fprintf(stderr, "cribbage: %s: %s.\n", _PATH_INSTR,
+ strerror(errno));
+ exit(1);
+ }
+ switch(pid = vfork()) {
+ case -1:
+ (void)fprintf(stderr, "cribbage: %s.\n", strerror(errno));
+ exit(1);
+ case 0:
+ if (!(path = getenv("PAGER")))
+ path = _PATH_MORE;
+ if (pager = rindex(path, '/'))
+ ++pager;
+ pager = path;
+ execlp(path, pager, _PATH_INSTR, (char *)NULL);
+ (void)fprintf(stderr, "cribbage: %s.\n", strerror(errno));
+ _exit(1);
+ default:
+ do {
+ pid = waitpid(pid, (int *)&pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+ if (pid == -1 || pstat.w_status)
+ exit(1);
+ }
+}
diff --git a/cribbage/io.c b/cribbage/io.c
new file mode 100644
index 00000000..ef99246b
--- /dev/null
+++ b/cribbage/io.c
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)io.c 5.8 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include <curses.h>
+# include <ctype.h>
+# include <signal.h>
+# include <stdarg.h>
+# include "deck.h"
+# include "cribbage.h"
+# include "cribcur.h"
+
+# define LINESIZE 128
+
+# ifdef CTRL
+# undef CTRL
+# endif
+# define CTRL(X) ('X' - 'A' + 1)
+
+# ifdef notdef /* defined in curses.h */
+# define erasechar() _tty.sg_erase
+# define killchar() _tty.sg_kill
+# endif
+
+char linebuf[ LINESIZE ];
+
+char *rankname[ RANKS ] = { "ACE", "TWO", "THREE", "FOUR",
+ "FIVE", "SIX", "SEVEN", "EIGHT",
+ "NINE", "TEN", "JACK", "QUEEN",
+ "KING" };
+
+char *rankchar[ RANKS ] = { "A", "2", "3", "4", "5", "6", "7",
+ "8", "9", "T", "J", "Q", "K" };
+
+char *suitname[ SUITS ] = { "SPADES", "HEARTS", "DIAMONDS",
+ "CLUBS" };
+
+char *suitchar[ SUITS ] = { "S", "H", "D", "C" };
+
+
+
+/*
+ * msgcard:
+ * Call msgcrd in one of two forms
+ */
+msgcard(c, brief)
+CARD c;
+BOOLEAN brief;
+{
+ if (brief)
+ return msgcrd(c, TRUE, (char *) NULL, TRUE);
+ else
+ return msgcrd(c, FALSE, " of ", FALSE);
+}
+
+
+
+/*
+ * msgcrd:
+ * Print the value of a card in ascii
+ */
+msgcrd(c, brfrank, mid, brfsuit)
+CARD c;
+char *mid;
+BOOLEAN brfrank, brfsuit;
+{
+ if (c.rank == EMPTY || c.suit == EMPTY)
+ return FALSE;
+ if (brfrank)
+ addmsg("%1.1s", rankchar[c.rank]);
+ else
+ addmsg(rankname[c.rank]);
+ if (mid != NULL)
+ addmsg(mid);
+ if (brfsuit)
+ addmsg("%1.1s", suitchar[c.suit]);
+ else
+ addmsg(suitname[c.suit]);
+ return TRUE;
+}
+
+/*
+ * printcard:
+ * Print out a card.
+ */
+printcard(win, cardno, c, blank)
+WINDOW *win;
+int cardno;
+CARD c;
+BOOLEAN blank;
+{
+ prcard(win, cardno * 2, cardno, c, blank);
+}
+
+/*
+ * prcard:
+ * Print out a card on the window at the specified location
+ */
+prcard(win, y, x, c, blank)
+WINDOW *win;
+int y, x;
+CARD c;
+BOOLEAN blank;
+{
+ if (c.rank == EMPTY)
+ return;
+ mvwaddstr(win, y + 0, x, "+-----+");
+ mvwaddstr(win, y + 1, x, "| |");
+ mvwaddstr(win, y + 2, x, "| |");
+ mvwaddstr(win, y + 3, x, "| |");
+ mvwaddstr(win, y + 4, x, "+-----+");
+ if (!blank) {
+ mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
+ waddch(win, suitchar[c.suit][0]);
+ mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
+ waddch(win, suitchar[c.suit][0]);
+ }
+}
+
+/*
+ * prhand:
+ * Print a hand of n cards
+ */
+prhand(h, n, win, blank)
+CARD h[];
+int n;
+WINDOW *win;
+BOOLEAN blank;
+{
+ register int i;
+
+ werase(win);
+ for (i = 0; i < n; i++)
+ printcard(win, i, *h++, blank);
+ wrefresh(win);
+}
+
+
+
+/*
+ * infrom:
+ * reads a card, supposedly in hand, accepting unambigous brief
+ * input, returns the index of the card found...
+ */
+infrom(hand, n, prompt)
+CARD hand[];
+int n;
+char *prompt;
+{
+ register int i, j;
+ CARD crd;
+
+ if (n < 1) {
+ printf("\nINFROM: %d = n < 1!!\n", n);
+ exit(74);
+ }
+ for (;;) {
+ msg(prompt);
+ if (incard(&crd)) { /* if card is full card */
+ if (!isone(crd, hand, n))
+ msg("That's not in your hand");
+ else {
+ for (i = 0; i < n; i++)
+ if (hand[i].rank == crd.rank &&
+ hand[i].suit == crd.suit)
+ break;
+ if (i >= n) {
+ printf("\nINFROM: isone or something messed up\n");
+ exit(77);
+ }
+ return i;
+ }
+ }
+ else /* if not full card... */
+ if (crd.rank != EMPTY) {
+ for (i = 0; i < n; i++)
+ if (hand[i].rank == crd.rank)
+ break;
+ if (i >= n)
+ msg("No such rank in your hand");
+ else {
+ for (j = i + 1; j < n; j++)
+ if (hand[j].rank == crd.rank)
+ break;
+ if (j < n)
+ msg("Ambiguous rank");
+ else
+ return i;
+ }
+ }
+ else
+ msg("Sorry, I missed that");
+ }
+ /* NOTREACHED */
+}
+
+
+
+/*
+ * incard:
+ * Inputs a card in any format. It reads a line ending with a CR
+ * and then parses it.
+ */
+incard(crd)
+CARD *crd;
+{
+ char *getline();
+ register int i;
+ int rnk, sut;
+ char *line, *p, *p1;
+ BOOLEAN retval;
+
+ retval = FALSE;
+ rnk = sut = EMPTY;
+ if (!(line = getline()))
+ goto gotit;
+ p = p1 = line;
+ while( *p1 != ' ' && *p1 != NULL ) ++p1;
+ *p1++ = NULL;
+ if( *p == NULL ) goto gotit;
+ /* IMPORTANT: no real card has 2 char first name */
+ if( strlen(p) == 2 ) { /* check for short form */
+ rnk = EMPTY;
+ for( i = 0; i < RANKS; i++ ) {
+ if( *p == *rankchar[i] ) {
+ rnk = i;
+ break;
+ }
+ }
+ if( rnk == EMPTY ) goto gotit; /* it's nothing... */
+ ++p; /* advance to next char */
+ sut = EMPTY;
+ for( i = 0; i < SUITS; i++ ) {
+ if( *p == *suitchar[i] ) {
+ sut = i;
+ break;
+ }
+ }
+ if( sut != EMPTY ) retval = TRUE;
+ goto gotit;
+ }
+ rnk = EMPTY;
+ for( i = 0; i < RANKS; i++ ) {
+ if( !strcmp( p, rankname[i] ) || !strcmp( p, rankchar[i] ) ) {
+ rnk = i;
+ break;
+ }
+ }
+ if( rnk == EMPTY ) goto gotit;
+ p = p1;
+ while( *p1 != ' ' && *p1 != NULL ) ++p1;
+ *p1++ = NULL;
+ if( *p == NULL ) goto gotit;
+ if( !strcmp( "OF", p ) ) {
+ p = p1;
+ while( *p1 != ' ' && *p1 != NULL ) ++p1;
+ *p1++ = NULL;
+ if( *p == NULL ) goto gotit;
+ }
+ sut = EMPTY;
+ for( i = 0; i < SUITS; i++ ) {
+ if( !strcmp( p, suitname[i] ) || !strcmp( p, suitchar[i] ) ) {
+ sut = i;
+ break;
+ }
+ }
+ if( sut != EMPTY ) retval = TRUE;
+gotit:
+ (*crd).rank = rnk;
+ (*crd).suit = sut;
+ return( retval );
+}
+
+
+
+/*
+ * getuchar:
+ * Reads and converts to upper case
+ */
+getuchar()
+{
+ register int c;
+
+ c = readchar();
+ if (islower(c))
+ c = toupper(c);
+ waddch(Msgwin, c);
+ return c;
+}
+
+/*
+ * number:
+ * Reads in a decimal number and makes sure it is between "lo" and
+ * "hi" inclusive.
+ */
+number(lo, hi, prompt)
+int lo, hi;
+char *prompt;
+{
+ char *getline();
+ register char *p;
+ register int sum;
+
+ sum = 0;
+ for (;;) {
+ msg(prompt);
+ if(!(p = getline()) || *p == NULL) {
+ msg(quiet ? "Not a number" : "That doesn't look like a number");
+ continue;
+ }
+ sum = 0;
+
+ if (!isdigit(*p))
+ sum = lo - 1;
+ else
+ while (isdigit(*p)) {
+ sum = 10 * sum + (*p - '0');
+ ++p;
+ }
+
+ if (*p != ' ' && *p != '\t' && *p != NULL)
+ sum = lo - 1;
+ if (sum >= lo && sum <= hi)
+ return sum;
+ if (sum == lo - 1)
+ msg("that doesn't look like a number, try again --> ");
+ else
+ msg("%d is not between %d and %d inclusive, try again --> ",
+ sum, lo, hi);
+ }
+}
+
+/*
+ * msg:
+ * Display a message at the top of the screen.
+ */
+char Msgbuf[BUFSIZ] = { '\0' };
+
+int Mpos = 0;
+
+static int Newpos = 0;
+
+/* VARARGS1 */
+msg(fmt)
+ char *fmt;
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)vsprintf(&Msgbuf[Newpos], fmt, ap);
+ va_end(ap);
+ endmsg();
+}
+
+/*
+ * addmsg:
+ * Add things to the current message
+ */
+/* VARARGS1 */
+addmsg(fmt)
+ char *fmt;
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)vsprintf(&Msgbuf[Newpos], fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * endmsg:
+ * Display a new msg.
+ */
+
+int Lineno = 0;
+
+endmsg()
+{
+ register int len;
+ register char *mp, *omp;
+ static int lastline = 0;
+
+ /*
+ * All messages should start with uppercase
+ */
+ mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
+ if (islower(Msgbuf[0]) && Msgbuf[1] != ')')
+ Msgbuf[0] = toupper(Msgbuf[0]);
+ mp = Msgbuf;
+ len = strlen(mp);
+ if (len / MSG_X + Lineno >= MSG_Y) {
+ while (Lineno < MSG_Y) {
+ wmove(Msgwin, Lineno++, 0);
+ wclrtoeol(Msgwin);
+ }
+ Lineno = 0;
+ }
+ mvaddch(Lineno + Y_MSG_START, SCORE_X, '*');
+ lastline = Lineno;
+ do {
+ mvwaddstr(Msgwin, Lineno, 0, mp);
+ if ((len = strlen(mp)) > MSG_X) {
+ omp = mp;
+ for (mp = &mp[MSG_X-1]; *mp != ' '; mp--)
+ continue;
+ while (*mp == ' ')
+ mp--;
+ mp++;
+ wmove(Msgwin, Lineno, mp - omp);
+ wclrtoeol(Msgwin);
+ }
+ if (++Lineno >= MSG_Y)
+ Lineno = 0;
+ } while (len > MSG_X);
+ wclrtoeol(Msgwin);
+ Mpos = len;
+ Newpos = 0;
+ wrefresh(Msgwin);
+ refresh();
+ wrefresh(Msgwin);
+}
+
+#ifdef notdef
+/*
+ * doadd:
+ * Perform an add onto the message buffer
+ */
+doadd(fmt, args)
+char *fmt;
+int *args;
+{
+ static FILE junk;
+
+ /*
+ * Do the printf into Msgbuf
+ */
+ junk._flag = _IOWRT + _IOSTRG;
+ junk._ptr = &Msgbuf[Newpos];
+ junk._cnt = 32767;
+ _doprnt(fmt, args, &junk);
+ putc('\0', &junk);
+ Newpos = strlen(Msgbuf);
+}
+#endif
+
+/*
+ * do_wait:
+ * Wait for the user to type ' ' before doing anything else
+ */
+do_wait()
+{
+ register int line;
+ static char prompt[] = { '-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0' };
+
+ if (Mpos + sizeof prompt < MSG_X)
+ wmove(Msgwin, Lineno > 0 ? Lineno - 1 : MSG_Y - 1, Mpos);
+ else {
+ mvwaddch(Msgwin, Lineno, 0, ' ');
+ wclrtoeol(Msgwin);
+ if (++Lineno >= MSG_Y)
+ Lineno = 0;
+ }
+ waddstr(Msgwin, prompt);
+ wrefresh(Msgwin);
+ wait_for(' ');
+}
+
+/*
+ * wait_for
+ * Sit around until the guy types the right key
+ */
+wait_for(ch)
+register char ch;
+{
+ register char c;
+
+ if (ch == '\n')
+ while ((c = readchar()) != '\n')
+ continue;
+ else
+ while (readchar() != ch)
+ continue;
+}
+
+/*
+ * readchar:
+ * Reads and returns a character, checking for gross input errors
+ */
+readchar()
+{
+ register int cnt, y, x;
+ auto char c;
+
+over:
+ cnt = 0;
+ while (read(0, &c, 1) <= 0)
+ if (cnt++ > 100) { /* if we are getting infinite EOFs */
+ bye(); /* quit the game */
+ exit(1);
+ }
+ if (c == CTRL(L)) {
+ wrefresh(curscr);
+ goto over;
+ }
+ if (c == '\r')
+ return '\n';
+ else
+ return c;
+}
+
+/*
+ * getline:
+ * Reads the next line up to '\n' or EOF. Multiple spaces are
+ * compressed to one space; a space is inserted before a ','
+ */
+char *
+getline()
+{
+ register char *sp;
+ register int c, oy, ox;
+ register WINDOW *oscr;
+
+ oscr = stdscr;
+ stdscr = Msgwin;
+ getyx(stdscr, oy, ox);
+ refresh();
+ /*
+ * loop reading in the string, and put it in a temporary buffer
+ */
+ for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
+ if (c == -1)
+ continue;
+ else if (c == erasechar()) { /* process erase character */
+ if (sp > linebuf) {
+ register int i;
+
+ sp--;
+ for (i = strlen(unctrl(*sp)); i; i--)
+ addch('\b');
+ }
+ continue;
+ }
+ else if (c == killchar()) { /* process kill character */
+ sp = linebuf;
+ move(oy, ox);
+ continue;
+ }
+ else if (sp == linebuf && c == ' ')
+ continue;
+ if (sp >= &linebuf[LINESIZE-1] || !(isprint(c) || c == ' '))
+ putchar(CTRL(G));
+ else {
+ if (islower(c))
+ c = toupper(c);
+ *sp++ = c;
+ addstr(unctrl(c));
+ Mpos++;
+ }
+ }
+ *sp = '\0';
+ stdscr = oscr;
+ return linebuf;
+}
+
+rint()
+{
+ bye();
+ exit(1);
+}
+
+/*
+ * bye:
+ * Leave the program, cleaning things up as we go.
+ */
+bye()
+{
+ signal(SIGINT, SIG_IGN);
+ mvcur(0, COLS - 1, LINES - 1, 0);
+ fflush(stdout);
+ endwin();
+ putchar('\n');
+}
diff --git a/cribbage/pathnames.h b/cribbage/pathnames.h
new file mode 100644
index 00000000..908b05cc
--- /dev/null
+++ b/cribbage/pathnames.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 5/1/90
+ */
+
+#define _PATH_LOG "/var/games/criblog"
+#define _PATH_MORE "/usr/bin/more"
+#define _PATH_INSTR "/usr/share/games/cribbage.instr"
diff --git a/cribbage/score.c b/cribbage/score.c
new file mode 100644
index 00000000..be3ca3fd
--- /dev/null
+++ b/cribbage/score.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)score.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "deck.h"
+#include "cribbage.h"
+
+
+/*
+ * the following arrays give the sum of the scores of the (50 2)*48 = 58800
+ * hands obtainable for the crib given the two cards whose ranks index the
+ * array. the two arrays are for the case where the suits are equal and
+ * not equal respectively
+ */
+
+long crbescr[ 169 ] = {
+ -10000, 271827, 278883, 332319, 347769, 261129, 250653, 253203, 248259,
+ 243435, 256275, 237435, 231051, -10000, -10000, 412815, 295707, 349497,
+ 267519, 262521, 259695, 254019, 250047, 262887, 244047, 237663, -10000,
+ -10000, -10000, 333987, 388629, 262017, 266787, 262971, 252729, 254475,
+ 267315, 248475, 242091, -10000, -10000, -10000, -10000, 422097, 302787,
+ 256437, 263751, 257883, 254271, 267111, 248271, 241887, -10000, -10000,
+ -10000, -10000, -10000, 427677, 387837, 349173, 347985, 423861, 436701,
+ 417861, 411477, -10000, -10000, -10000, -10000, -10000, -10000, 336387,
+ 298851, 338667, 236487, 249327, 230487, 224103, -10000, -10000, -10000,
+ -10000, -10000, -10000, -10000, 408483, 266691, 229803, 246195, 227355,
+ 220971, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+ 300675, 263787, 241695, 226407, 220023, -10000, -10000, -10000, -10000,
+ -10000, -10000, -10000, -10000, -10000, 295635, 273543, 219771, 216939,
+ -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+ -10000, 306519, 252747, 211431, -10000, -10000, -10000, -10000, -10000,
+ -10000, -10000, -10000, -10000, -10000, -10000, 304287, 262971, -10000,
+ -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+ -10000, -10000, 244131, -10000, -10000, -10000, -10000, -10000, -10000,
+ -10000, -10000, -10000, -10000, -10000, -10000, -10000 };
+
+long crbnescr[ 169 ] = {
+ 325272, 260772, 267828, 321264, 336714, 250074, 239598, 242148, 237204,
+ 232380, 246348, 226380, 219996, -10000, 342528, 401760, 284652, 338442,
+ 256464, 251466, 248640, 242964, 238992, 252960, 232992, 226608, -10000,
+ -10000, 362280, 322932, 377574, 250962, 255732, 251916, 241674, 243420,
+ 257388, 237420, 231036, -10000, -10000, -10000, 360768, 411042, 291732,
+ 245382, 252696, 246828, 243216, 257184, 237216, 230832, -10000, -10000,
+ -10000, -10000, 528768, 416622, 376782, 338118, 336930, 412806, 426774,
+ 406806, 400422, -10000, -10000, -10000, -10000, -10000, 369864, 325332,
+ 287796, 327612, 225432, 239400, 219432, 213048, -10000, -10000, -10000,
+ -10000, -10000, -10000, 359160, 397428, 255636, 218748, 236268, 216300,
+ 209916, -10000, -10000, -10000, -10000, -10000, -10000, -10000, 331320,
+ 289620, 252732, 231768, 215352, 208968, -10000, -10000, -10000, -10000,
+ -10000, -10000, -10000, -10000, 325152, 284580, 263616, 208716, 205884,
+ -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+ 321240, 296592, 241692, 200376, -10000, -10000, -10000, -10000, -10000,
+ -10000, -10000, -10000, -10000, -10000, 348600, 294360, 253044, -10000,
+ -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+ -10000, 308664, 233076, -10000, -10000, -10000, -10000, -10000, -10000,
+ -10000, -10000, -10000, -10000, -10000, -10000, 295896 };
+
+
+static int ichoose2[ 5 ] = { 0, 0, 2, 6, 12 };
+static int pairpoints, runpoints; /* globals from pairuns */
+
+
+/*
+ * scorehand:
+ * Score the given hand of n cards and the starter card.
+ * n must be <= 4
+ */
+scorehand(hand, starter, n, crb, do_explain)
+register CARD hand[];
+CARD starter;
+int n;
+BOOLEAN crb; /* true if scoring crib */
+BOOLEAN do_explain; /* true if must explain this hand */
+{
+ CARD h[(CINHAND + 1)];
+ register int i, k;
+ register int score;
+ register BOOLEAN flag;
+ char buf[32];
+
+ expl[0] = NULL; /* initialize explanation */
+ score = 0;
+ flag = TRUE;
+ k = hand[0].suit;
+ for (i = 0; i < n; i++) { /* check for flush */
+ flag = (flag && (hand[i].suit == k));
+ if (hand[i].rank == JACK) /* check for his nibs */
+ if (hand[i].suit == starter.suit) {
+ score++;
+ if (do_explain)
+ strcat(expl, "His Nobs");
+ }
+ h[i] = hand[i];
+ }
+
+ if (flag && n >= CINHAND) {
+ if (do_explain && expl[0] != NULL)
+ strcat(expl, ", ");
+ if (starter.suit == k) {
+ score += 5;
+ if (do_explain)
+ strcat(expl, "Five-flush");
+ }
+ else if (!crb) {
+ score += 4;
+ if (do_explain && expl[0] != NULL)
+ strcat(expl, ", Four-flush");
+ else
+ strcpy(expl, "Four-flush");
+ }
+ }
+
+ if (do_explain && expl[0] != NULL)
+ strcat(expl, ", ");
+ h[n] = starter;
+ sorthand(h, n + 1); /* sort by rank */
+ i = 2 * fifteens(h, n + 1);
+ score += i;
+ if (do_explain)
+ if (i > 0) {
+ (void)sprintf(buf, "%d points in fifteens", i);
+ strcat(expl, buf);
+ }
+ else
+ strcat(expl, "No fifteens");
+ i = pairuns(h, n + 1);
+ score += i;
+ if (do_explain)
+ if (i > 0) {
+ (void)sprintf(buf, ", %d points in pairs, %d in runs",
+ pairpoints, runpoints);
+ strcat(expl, buf);
+ }
+ else
+ strcat(expl, ", No pairs/runs");
+ return score;
+}
+
+/*
+ * fifteens:
+ * Return number of fifteens in hand of n cards
+ */
+fifteens(hand, n)
+register CARD hand[];
+int n;
+{
+ register int *sp, *np;
+ register int i;
+ register CARD *endp;
+ static int sums[15], nsums[15];
+
+ np = nsums;
+ sp = sums;
+ i = 16;
+ while (--i) {
+ *np++ = 0;
+ *sp++ = 0;
+ }
+ for (endp = &hand[n]; hand < endp; hand++) {
+ i = hand->rank + 1;
+ if (i > 10)
+ i = 10;
+ np = &nsums[i];
+ np[-1]++; /* one way to make this */
+ sp = sums;
+ while (i < 15) {
+ *np++ += *sp++;
+ i++;
+ }
+ sp = sums;
+ np = nsums;
+ i = 16;
+ while (--i)
+ *sp++ = *np++;
+ }
+ return sums[14];
+}
+
+
+
+/*
+ * pairuns returns the number of points in the n card sorted hand
+ * due to pairs and runs
+ * this routine only works if n is strictly less than 6
+ * sets the globals pairpoints and runpoints appropriately
+ */
+
+pairuns( h, n )
+
+ CARD h[];
+ int n;
+{
+ register int i;
+ int runlength, runmult, lastmult, curmult;
+ int mult1, mult2, pair1, pair2;
+ BOOLEAN run;
+
+ run = TRUE;
+ runlength = 1;
+ mult1 = 1;
+ pair1 = -1;
+ mult2 = 1;
+ pair2 = -1;
+ curmult = runmult = 1;
+ for( i = 1; i < n; i++ ) {
+ lastmult = curmult;
+ if( h[i].rank == h[i - 1].rank ) {
+ if( pair1 < 0 ) {
+ pair1 = h[i].rank;
+ mult1 = curmult = 2;
+ }
+ else {
+ if( h[i].rank == pair1 ) {
+ curmult = ++mult1;
+ }
+ else {
+ if( pair2 < 0 ) {
+ pair2 = h[i].rank;
+ mult2 = curmult = 2;
+ }
+ else {
+ curmult = ++mult2;
+ }
+ }
+ }
+ if( i == (n - 1) && run ) {
+ runmult *= curmult;
+ }
+ }
+ else {
+ curmult = 1;
+ if( h[i].rank == h[i - 1].rank + 1 ) {
+ if( run ) {
+ ++runlength;
+ }
+ else {
+ if( runlength < 3 ) { /* only if old short */
+ run = TRUE;
+ runlength = 2;
+ runmult = 1;
+ }
+ }
+ runmult *= lastmult;
+ }
+ else {
+ if( run ) runmult *= lastmult; /* if just ended */
+ run = FALSE;
+ }
+ }
+ }
+ pairpoints = ichoose2[ mult1 ] + ichoose2[ mult2 ];
+ runpoints = ( runlength >= 3 ? runlength*runmult : 0 );
+ return( pairpoints + runpoints );
+}
+
+
+
+/*
+ * pegscore tells how many points crd would get if played after
+ * the n cards in tbl during pegging
+ */
+
+pegscore( crd, tbl, n, sum )
+
+ CARD crd, tbl[];
+ int n;
+ int sum;
+{
+ BOOLEAN got[ RANKS ];
+ register int i, j, scr;
+ int k, lo, hi;
+
+ sum += VAL( crd.rank );
+ if( sum > 31 ) return( -1 );
+ if( sum == 31 || sum == 15 ) scr = 2;
+ else scr = 0;
+ if( !n ) return( scr );
+ j = 1;
+ while( ( crd.rank == tbl[n - j].rank ) && ( n - j >= 0 ) ) ++j;
+ if( j > 1 ) return( scr + ichoose2[j] );
+ if( n < 2 ) return( scr );
+ lo = hi = crd.rank;
+ for( i = 0; i < RANKS; i++ ) got[i] = FALSE;
+ got[ crd.rank ] = TRUE;
+ k = -1;
+ for( i = n - 1; i >= 0; --i ) {
+ if( got[ tbl[i].rank ] ) break;
+ got[ tbl[i].rank ] = TRUE;
+ if( tbl[i].rank < lo ) lo = tbl[i].rank;
+ if( tbl[i].rank > hi ) hi = tbl[i].rank;
+ for( j = lo; j <= hi; j++ ) if( !got[j] ) break;
+ if( j > hi ) k = hi - lo + 1;
+ }
+ if( k >= 3 ) return( scr + k );
+ else return( scr );
+}
+
+
+
+/*
+ * adjust takes a two card hand that will be put in the crib
+ * and returns an adjusted normalized score for the number of
+ * points such a crib will get.
+ */
+
+adjust( cb, tnv )
+
+ CARD cb[], tnv;
+{
+ int i, c0, c1;
+ long scr;
+
+ c0 = cb[0].rank;
+ c1 = cb[1].rank;
+ if( c0 > c1 ) {
+ i = c0;
+ c0 = c1;
+ c1 = i;
+ }
+ if( cb[0].suit != cb[1].suit ) scr = crbnescr[ RANKS*c0 + c1 ];
+ else scr = crbescr[ RANKS*c0 + c1 ];
+ if( scr <= 0 ) {
+ printf( "\nADJUST: internal error %d %d\n", c0, c1 );
+ exit( 93 );
+ }
+ return( (scr + 29400)/58800 );
+}
+
+
+
diff --git a/cribbage/support.c b/cribbage/support.c
new file mode 100644
index 00000000..b617296e
--- /dev/null
+++ b/cribbage/support.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)support.c 5.6 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include <curses.h>
+#include "deck.h"
+#include "cribbage.h"
+#include "cribcur.h"
+
+
+#define NTV 10 /* number scores to test */
+
+/* score to test reachability of, and order to test them in */
+int tv[ NTV ] = { 8, 7, 9, 6, 11, 12, 13, 14, 10, 5 };
+
+
+/*
+ * computer chooses what to play in pegging...
+ * only called if no playable card will score points
+ */
+
+cchose( h, n, s )
+
+ CARD h[];
+ int n;
+ int s;
+{
+ register int i, j, l;
+
+ if( n <= 1 ) return( 0 );
+ if( s < 4 ) { /* try for good value */
+ if( ( j = anysumto(h, n, s, 4) ) >= 0 ) return( j );
+ if( ( j = anysumto(h, n, s, 3) ) >= 0 && s == 0 )
+ return( j );
+ }
+ if( s > 0 && s < 20 ) {
+ for( i = 1; i <= 10; i++ ) { /* try for retaliation to 31 */
+ if( ( j = anysumto(h, n, s, 21-i) ) >= 0 ) {
+ if( ( l = numofval(h, n, i) ) > 0 ) {
+ if( l > 1 || VAL( h[j].rank ) != i ) return( j );
+ }
+ }
+ }
+ }
+ if( s < 15 ) {
+ for( i = 0; i < NTV; i++ ) { /* for retaliation after 15 */
+ if( ( j = anysumto(h, n, s, tv[i]) ) >= 0 ) {
+ if( ( l = numofval(h, n, 15-tv[i]) ) > 0 ) {
+ if( l > 1 || VAL( h[j].rank ) != 15-tv[i] ) return( j );
+ }
+ }
+ }
+ }
+ j = -1;
+ for( i = n - 1; i >= 0; --i ) { /* remember: h is sorted */
+ l = s + VAL( h[i].rank );
+ if( l > 31 ) continue;
+ if( l != 5 && l != 10 && l != 21 ) {
+ j = i;
+ break;
+ }
+ }
+ if( j >= 0 ) return( j );
+ for( i = n - 1; i >= 0; --i ) {
+ l = s + VAL( h[i].rank );
+ if( l > 31 ) continue;
+ if( j < 0 ) j = i;
+ if( l != 5 && l != 21 ) {
+ j = i;
+ break;
+ }
+ }
+ return( j );
+}
+
+
+
+/*
+ * plyrhand:
+ * Evaluate and score a player hand or crib
+ */
+plyrhand(hand, s)
+CARD hand[];
+char *s;
+{
+ register int i, j;
+ register BOOLEAN win;
+ static char prompt[BUFSIZ];
+
+ prhand(hand, CINHAND, Playwin, FALSE);
+ (void)sprintf(prompt, "Your %s scores ", s);
+ i = scorehand(hand, turnover, CINHAND, strcmp(s, "crib") == 0, explain);
+ if ((j = number(0, 29, prompt)) == 19)
+ j = 0;
+ if (i != j) {
+ if (i < j) {
+ win = chkscr(&pscore, i);
+ msg("It's really only %d points; I get %d", i, 2);
+ if (!win)
+ win = chkscr(&cscore, 2);
+ }
+ else {
+ win = chkscr(&pscore, j);
+ msg("You should have taken %d, not %d!", i, j);
+ }
+ if (explain)
+ msg("Explanation: %s", expl);
+ do_wait();
+ }
+ else
+ win = chkscr(&pscore, i);
+ return win;
+}
+
+/*
+ * comphand:
+ * Handle scoring and displaying the computers hand
+ */
+comphand(h, s)
+CARD h[];
+char *s;
+{
+ register int j;
+
+ j = scorehand(h, turnover, CINHAND, strcmp(s, "crib") == 0, FALSE);
+ prhand(h, CINHAND, Compwin, FALSE);
+ msg("My %s scores %d", s, (j == 0 ? 19 : j));
+ return chkscr(&cscore, j);
+}
+
+/*
+ * chkscr:
+ * Add inc to scr and test for > glimit, printing on the scoring
+ * board while we're at it.
+ */
+
+int Lastscore[2] = {-1, -1};
+
+chkscr(scr, inc)
+int *scr, inc;
+{
+ BOOLEAN myturn;
+
+ myturn = (scr == &cscore);
+ if (inc != 0) {
+ prpeg(Lastscore[myturn], '.', myturn);
+ Lastscore[myturn] = *scr;
+ *scr += inc;
+ prpeg(*scr, PEG, myturn);
+ refresh();
+ }
+ return (*scr >= glimit);
+}
+
+/*
+ * prpeg:
+ * Put out the peg character on the score board and put the
+ * score up on the board.
+ */
+prpeg(score, peg, myturn)
+register int score;
+char peg;
+BOOLEAN myturn;
+{
+ register int y, x;
+
+ if (!myturn)
+ y = SCORE_Y + 2;
+ else
+ y = SCORE_Y + 5;
+
+ if (score <= 0 || score >= glimit) {
+ if (peg == '.')
+ peg = ' ';
+ if (score == 0)
+ x = SCORE_X + 2;
+ else {
+ x = SCORE_X + 2;
+ y++;
+ }
+ }
+ else {
+ x = (score - 1) % 30;
+ if (score > 90 || (score > 30 && score <= 60)) {
+ y++;
+ x = 29 - x;
+ }
+ x += x / 5;
+ x += SCORE_X + 3;
+ }
+ mvaddch(y, x, peg);
+ mvprintw(SCORE_Y + (myturn ? 7 : 1), SCORE_X + 10, "%3d", score);
+}
+
+/*
+ * cdiscard -- the computer figures out what is the best discard for
+ * the crib and puts the best two cards at the end
+ */
+
+cdiscard( mycrib )
+
+ BOOLEAN mycrib;
+{
+ CARD d[ CARDS ], h[ FULLHAND ], cb[ 2 ];
+ register int i, j, k;
+ int nc, ns;
+ long sums[ 15 ];
+ static int undo1[15] = {0,0,0,0,0,1,1,1,1,2,2,2,3,3,4};
+ static int undo2[15] = {1,2,3,4,5,2,3,4,5,3,4,5,4,5,5};
+
+ makedeck( d );
+ nc = CARDS;
+ for( i = 0; i < knownum; i++ ) { /* get all other cards */
+ cremove( known[i], d, nc-- );
+ }
+ for( i = 0; i < 15; i++ ) sums[i] = 0L;
+ ns = 0;
+ for( i = 0; i < (FULLHAND - 1); i++ ) {
+ cb[0] = chand[i];
+ for( j = i + 1; j < FULLHAND; j++ ) {
+ cb[1] = chand[j];
+ for( k = 0; k < FULLHAND; k++ ) h[k] = chand[k];
+ cremove( chand[i], h, FULLHAND );
+ cremove( chand[j], h, FULLHAND - 1 );
+ for( k = 0; k < nc; k++ ) {
+ sums[ns] += scorehand( h, d[k], CINHAND, TRUE, FALSE );
+ if( mycrib ) sums[ns] += adjust( cb, d[k] );
+ else sums[ns] -= adjust( cb, d[k] );
+ }
+ ++ns;
+ }
+ }
+ j = 0;
+ for( i = 1; i < 15; i++ ) if( sums[i] > sums[j] ) j = i;
+ for( k = 0; k < FULLHAND; k++ ) h[k] = chand[k];
+ cremove( h[ undo1[j] ], chand, FULLHAND );
+ cremove( h[ undo2[j] ], chand, FULLHAND - 1 );
+ chand[4] = h[ undo1[j] ];
+ chand[5] = h[ undo2[j] ];
+}
+
+
+
+/*
+ * returns true if some card in hand can be played without exceeding 31
+ */
+
+anymove( hand, n, sum )
+
+ CARD hand[];
+ int n;
+ int sum;
+{
+ register int i, j;
+
+ if( n < 1 ) return( FALSE );
+ j = hand[0].rank;
+ for( i = 1; i < n; i++ ) {
+ if( hand[i].rank < j ) j = hand[i].rank;
+ }
+ return( sum + VAL( j ) <= 31 );
+}
+
+
+
+/*
+ * anysumto returns the index (0 <= i < n) of the card in hand that brings
+ * the s up to t, or -1 if there is none
+ */
+
+anysumto( hand, n, s, t )
+
+ CARD hand[];
+ int n;
+ int s, t;
+{
+ register int i;
+
+ for( i = 0; i < n; i++ ) {
+ if( s + VAL( hand[i].rank ) == t ) return( i );
+ }
+ return( -1 );
+}
+
+
+
+
+/*
+ * return the number of cards in h having the given rank value
+ */
+
+numofval( h, n, v )
+
+ CARD h[];
+ int n;
+ int v;
+{
+ register int i, j;
+
+ j = 0;
+ for( i = 0; i < n; i++ ) {
+ if( VAL( h[i].rank ) == v ) ++j;
+ }
+ return( j );
+}
+
+
+
+/*
+ * makeknown remembers all n cards in h for future recall
+ */
+
+makeknown( h, n )
+
+ CARD h[];
+ int n;
+{
+ register int i;
+
+ for( i = 0; i < n; i++ ) {
+ known[ knownum++ ] = h[i];
+ }
+}
+
diff --git a/dm/Makefile b/dm/Makefile
new file mode 100644
index 00000000..d0d552bd
--- /dev/null
+++ b/dm/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 5.7 (Berkeley) 9/30/90
+
+# -DLOG log games
+PROG= dm
+MAN8= dm.0
+MAN5= dm.conf.0
+BINGRP= kmem
+BINMODE=6555
+DPADD= ${LIBUTIL}
+LDADD= -lutil
+
+.include <bsd.prog.mk>
diff --git a/dm/dm.0 b/dm/dm.0
new file mode 100644
index 00000000..7afb5634
--- /dev/null
+++ b/dm/dm.0
@@ -0,0 +1,66 @@
+DM(8) 386BSD System Manager's Manual DM(8)
+
+NNAAMMEE
+ ddmm - dungeon master
+
+SSYYNNOOPPSSIISS
+ llnn --ss ddmm _g_a_m_e
+
+DDEESSCCRRIIPPTTIIOONN
+ DDmm is a program used to regulate game playing. DDmm expects to be invoked
+ with the name of a game that a user wishes to play. This is done by cre-
+ ating symbolic links to ddmm, in the directory /_u_s_r/_g_a_m_e_s for all of the
+ regulated games. The actual binaries for these games should be placed in
+ a ``hidden'' directory, /_u_s_r/_g_a_m_e_s/_h_i_d_e, that may only be accessed by the
+ ddmm program. DDmm determines if the requested game is available and, if so,
+ runs it. The file /_e_t_c/_d_m._c_o_n_f controls the conditions under which games
+ may be run.
+
+ The file /_e_t_c/_n_o_g_a_m_e_s may be used to ``turn off'' game playing. If the
+ file exists, no game playing is allowed; the contents of the file will be
+ displayed to any user requesting a game.
+
+FFIILLEESS
+ /etc/dm.conf configuration file
+ /etc/nogames turns off game playing
+ /usr/games/hide directory of ``real'' binaries
+ /var/log/games.log game logging file
+
+SSEEEE AALLSSOO
+ dm.conf(5)
+
+BBUUGGSS
+ Two problems result from ddmm running the games setuid ``games''. First,
+ all games that allow users to run UNIX commands should carefully set both
+ the real and effective user id's immediately before executing those com-
+ mands. Probably more important is that ddmm never be setuid anything but
+ ``games'' so that compromising a game will result only in the user's
+ ability to play games at will. Secondly, games which previously had no
+ reason to run setuid and which accessed user files may have to be modi-
+ fied.
+
+HHIISSTTOORRYY
+ The ddmm command appeared in 4.3BSD-Tahoe.
+
+BSD Experimental July 23, 1991 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dm/dm.8 b/dm/dm.8
new file mode 100644
index 00000000..4304600b
--- /dev/null
+++ b/dm/dm.8
@@ -0,0 +1,109 @@
+.\" Copyright (c) 1987, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)dm.8 5.11 (Berkeley) 7/23/91
+.\"
+.Dd July 23, 1991
+.Dt DM 8
+.Os
+.Sh NAME
+.Nm dm
+.Nd dungeon master
+.Sh SYNOPSIS
+.Nm ln
+.Fl s Cm dm Ar game
+.Sh DESCRIPTION
+.Nm Dm
+is a program used to regulate game playing.
+.Nm Dm
+expects to be invoked with the name of a game that a user wishes to play.
+This is done by creating symbolic links to
+.Nm dm ,
+in the directory
+.Pa /usr/games
+for all of the regulated games.
+The actual binaries for these games should be placed in a
+.Dq hidden
+directory,
+.Pa /usr/games/hide ,
+that may only be accessed by the
+.Nm dm
+program.
+.Nm Dm
+determines if the requested game is available and, if so, runs it.
+The file
+.Pa /etc/dm.conf
+controls the conditions under which games may
+be run.
+.Pp
+The file
+.Pa /etc/nogames
+may be used to
+.Dq turn off
+game playing.
+If the file exists, no game playing is allowed; the contents of the file
+will be displayed to any user requesting a game.
+.Sh FILES
+.Bl -tag -width /var/log/games.log -compact
+.It Pa /etc/dm.conf
+configuration file
+.It Pa /etc/nogames
+turns off game playing
+.It Pa /usr/games/hide
+directory of ``real'' binaries
+.It Pa /var/log/games.log
+game logging file
+.El
+.Sh SEE ALSO
+.Xr dm.conf 5
+.Sh BUGS
+Two problems result from
+.Nm dm
+running the games setuid
+.Dq games .
+First, all games that allow users to run
+.Tn UNIX
+commands should carefully
+set both the real and effective user id's immediately before executing
+those commands. Probably more important is that
+.Nm dm
+never be setuid
+anything but
+.Dq games
+so that compromising a game will result only in
+the user's ability to play games at will. Secondly, games which previously
+had no reason to run setuid and which accessed user files may have to
+be modified.
+.Sh HISTORY
+The
+.Nm dm
+command appeared in
+.Bx 4.3 tahoe .
diff --git a/dm/dm.c b/dm/dm.c
new file mode 100644
index 00000000..bf820688
--- /dev/null
+++ b/dm/dm.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1987 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)dm.c 5.16 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <pwd.h>
+#include <utmp.h>
+#include <nlist.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "pathnames.h"
+
+extern int errno;
+static time_t now; /* current time value */
+static int priority = 0; /* priority game runs at */
+static char *game, /* requested game */
+ *gametty; /* from tty? */
+
+/*ARGSUSED*/
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *cp, *rindex(), *ttyname();
+ time_t time();
+
+ nogamefile();
+ game = (cp = rindex(*argv, '/')) ? ++cp : *argv;
+
+ if (!strcmp(game, "dm"))
+ exit(0);
+
+ gametty = ttyname(0);
+ (void)time(&now);
+ read_config();
+#ifdef LOG
+ logfile();
+#endif
+ play(argv);
+ /*NOTREACHED*/
+}
+
+/*
+ * play --
+ * play the game
+ */
+play(args)
+ char **args;
+{
+ char pbuf[MAXPATHLEN], *strcpy(), *strerror();
+
+ (void)strcpy(pbuf, _PATH_HIDE);
+ (void)strcpy(pbuf + sizeof(_PATH_HIDE) - 1, game);
+ if (priority > 0) /* < 0 requires root */
+ (void)setpriority(PRIO_PROCESS, 0, priority);
+ setgid(getgid()); /* we run setgid kmem; lose it */
+ execv(pbuf, args);
+ (void)fprintf(stderr, "dm: %s: %s\n", pbuf, strerror(errno));
+ exit(1);
+}
+
+/*
+ * read_config --
+ * read through config file, looking for key words.
+ */
+read_config()
+{
+ FILE *cfp;
+ char lbuf[BUFSIZ], f1[40], f2[40], f3[40], f4[40], f5[40];
+
+ if (!(cfp = fopen(_PATH_CONFIG, "r")))
+ return;
+ while (fgets(lbuf, sizeof(lbuf), cfp))
+ switch(*lbuf) {
+ case 'b': /* badtty */
+ if (sscanf(lbuf, "%s%s", f1, f2) != 2 ||
+ strcasecmp(f1, "badtty"))
+ break;
+ c_tty(f2);
+ break;
+ case 'g': /* game */
+ if (sscanf(lbuf, "%s%s%s%s%s",
+ f1, f2, f3, f4, f5) != 5 || strcasecmp(f1, "game"))
+ break;
+ c_game(f2, f3, f4, f5);
+ break;
+ case 't': /* time */
+ if (sscanf(lbuf, "%s%s%s%s", f1, f2, f3, f4) != 4 ||
+ strcasecmp(f1, "time"))
+ break;
+ c_day(f2, f3, f4);
+ }
+ (void)fclose(cfp);
+}
+
+/*
+ * c_day --
+ * if day is today, see if okay to play
+ */
+c_day(s_day, s_start, s_stop)
+ char *s_day, *s_start, *s_stop;
+{
+ static char *days[] = {
+ "sunday", "monday", "tuesday", "wednesday",
+ "thursday", "friday", "saturday",
+ };
+ static struct tm *ct;
+ int start, stop;
+
+ if (!ct)
+ ct = localtime(&now);
+ if (strcasecmp(s_day, days[ct->tm_wday]))
+ return;
+ if (!isdigit(*s_start) || !isdigit(*s_stop))
+ return;
+ start = atoi(s_start);
+ stop = atoi(s_stop);
+ if (ct->tm_hour >= start && ct->tm_hour < stop) {
+ fputs("dm: Sorry, games are not available from ", stderr);
+ hour(start);
+ fputs(" to ", stderr);
+ hour(stop);
+ fputs(" today.\n", stderr);
+ exit(0);
+ }
+}
+
+/*
+ * c_tty --
+ * decide if this tty can be used for games.
+ */
+c_tty(tty)
+ char *tty;
+{
+ static int first = 1;
+ static char *p_tty;
+ char *rindex();
+
+ if (first) {
+ p_tty = rindex(gametty, '/');
+ first = 0;
+ }
+
+ if (!strcmp(gametty, tty) || p_tty && !strcmp(p_tty, tty)) {
+ fprintf(stderr, "dm: Sorry, you may not play games on %s.\n", gametty);
+ exit(0);
+ }
+}
+
+/*
+ * c_game --
+ * see if game can be played now.
+ */
+c_game(s_game, s_load, s_users, s_priority)
+ char *s_game, *s_load, *s_users, *s_priority;
+{
+ static int found;
+ double load();
+
+ if (found)
+ return;
+ if (strcmp(game, s_game) && strcasecmp("default", s_game))
+ return;
+ ++found;
+ if (isdigit(*s_load) && atoi(s_load) < load()) {
+ fputs("dm: Sorry, the load average is too high right now.\n", stderr);
+ exit(0);
+ }
+ if (isdigit(*s_users) && atoi(s_users) <= users()) {
+ fputs("dm: Sorry, there are too many users logged on right now.\n", stderr);
+ exit(0);
+ }
+ if (isdigit(*s_priority))
+ priority = atoi(s_priority);
+}
+
+/*
+ * load --
+ * return 15 minute load average
+ */
+double
+load()
+{
+ double avenrun[3];
+
+ if (getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0])) < 0) {
+ fputs("dm: getloadavg() failed.\n", stderr);
+ exit(1);
+ }
+ return(avenrun[2]);
+}
+
+/*
+ * users --
+ * return current number of users
+ * todo: check idle time; if idle more than X minutes, don't
+ * count them.
+ */
+users()
+{
+
+ register int nusers, utmp;
+ struct utmp buf;
+
+ if ((utmp = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
+ (void)fprintf(stderr, "dm: %s: %s\n",
+ _PATH_UTMP, strerror(errno));
+ exit(1);
+ }
+ for (nusers = 0; read(utmp, (char *)&buf, sizeof(struct utmp)) > 0;)
+ if (buf.ut_name[0] != '\0')
+ ++nusers;
+ return(nusers);
+}
+
+nogamefile()
+{
+ register int fd, n;
+ char buf[BUFSIZ];
+
+ if ((fd = open(_PATH_NOGAMES, O_RDONLY, 0)) >= 0) {
+#define MESG "Sorry, no games right now.\n\n"
+ (void)write(2, MESG, sizeof(MESG) - 1);
+ while ((n = read(fd, buf, sizeof(buf))) > 0)
+ (void)write(2, buf, n);
+ exit(1);
+ }
+}
+
+/*
+ * hour --
+ * print out the hour in human form
+ */
+hour(h)
+ int h;
+{
+ switch(h) {
+ case 0:
+ fputs("midnight", stderr);
+ break;
+ case 12:
+ fputs("noon", stderr);
+ break;
+ default:
+ if (h > 12)
+ fprintf(stderr, "%dpm", h - 12);
+ else
+ fprintf(stderr, "%dam", h);
+ }
+}
+
+#ifdef LOG
+/*
+ * logfile --
+ * log play of game
+ */
+logfile()
+{
+ struct passwd *pw, *getpwuid();
+ FILE *lp;
+ uid_t uid;
+ int lock_cnt;
+ char *ctime();
+
+ if (lp = fopen(_PATH_LOG, "a")) {
+ for (lock_cnt = 0;; ++lock_cnt) {
+ if (!flock(fileno(lp), LOCK_EX))
+ break;
+ if (lock_cnt == 4) {
+ perror("dm: log lock");
+ (void)fclose(lp);
+ return;
+ }
+ sleep((u_int)1);
+ }
+ if (pw = getpwuid(uid = getuid()))
+ fputs(pw->pw_name, lp);
+ else
+ fprintf(lp, "%u", uid);
+ fprintf(lp, "\t%s\t%s\t%s", game, gametty, ctime(&now));
+ (void)fclose(lp);
+ (void)flock(fileno(lp), LOCK_UN);
+ }
+}
+#endif /* LOG */
diff --git a/dm/dm.conf.0 b/dm/dm.conf.0
new file mode 100644
index 00000000..3a1e3648
--- /dev/null
+++ b/dm/dm.conf.0
@@ -0,0 +1,66 @@
+DM.CONF(5) 386BSD Programmer's Manual DM.CONF(5)
+
+NNAAMMEE
+ ddmm..ccoonnff - dm configuration file
+
+DDEESSCCRRIIPPTTIIOONN
+ The dm.conf file is the configuration file for the dm(8) program. It
+ consists of lines beginning with one of three keywords, ``badtty'',
+ ``game'', and ``time''. All other lines are ignored.
+
+ Any tty listed after the keyword ``badtty'' may not have games played on
+ it. Entries consist of two white-space separated fields: the string
+ ``badtty'' and the ttyname as returned by ttyname(3). For example, to
+ keep the uucp dialout, ``tty19'', from being used for games, the entry
+ would be:
+
+ badtty /dev/tty19
+
+ Any day/hour combination listed after the keyword ``time'' will disallow
+ games during those hours. Entries consist of four white-space separated
+ fields: the string ``time'', the unabbreviated day of the week and the
+ beginning and ending time of a period of the day when games may not be
+ played. The time fields are in a 0 based, 24-hour clock. For example,
+ the following entry allows games playing before 8AM and after 5PM on Mon-
+ days.
+
+ time Monday 8 17
+
+ Any game listed after the keyword ``game'' will set parameters for a spe-
+ cific game. Entries consist of five white-space separated fields: the
+ keyword ``game'', the name of a game, the highest system load average at
+ which the game may be played, the maximum users allowed if the game is to
+ be played, and the priority at which the game is to be run. Any of these
+ fields may start with a non-numeric character, resulting in no game limi-
+ tation or priority based on that field. The game "default" controls the
+ settings for any game not otherwise listed, and must be the last ``game''
+ entry in the file. Priorities may not be negative. For example, the
+ following entries limits the game ``hack'' to running only when the sys-
+ tem has 10 or less users and a load average of 5 or less; all other games
+ may be run any time the system has 15 or less users.
+
+ game hack 5 10 *
+ game default * 15 *
+
+FFIILLEESS
+ /etc/dm.conf The dm(8) configuration file.
+
+SSEEEE AALLSSOO
+ setpriority(2), ttyname(3), dm(8)
+
+4.2 Berkeley Distribution May 10, 1991 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dm/dm.conf.5 b/dm/dm.conf.5
new file mode 100644
index 00000000..e856385d
--- /dev/null
+++ b/dm/dm.conf.5
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1988, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)dm.conf.5 5.8 (Berkeley) 5/10/91
+.\"
+.Dd May 10, 1991
+.Dt DM.CONF 5
+.Os BSD 4.2
+.Sh NAME
+.Nm dm.conf
+.Nd \&dm configuration file
+.Sh DESCRIPTION
+The
+.Xr dm.conf
+file
+is the configuration file for the
+.Xr \&dm 8
+program.
+It consists of lines beginning with one of three keywords, ``badtty'',
+``game'', and ``time''. All other lines are ignored.
+.Pp
+Any tty listed after the keyword ``badtty'' may not have games played on
+it.
+Entries consist of two white-space separated fields: the string
+``badtty'' and the ttyname as returned by
+.Xr ttyname 3 .
+For example,
+to keep the uucp dialout, ``tty19'', from being used for games, the
+entry would be:
+.Bd -literal -offset indent
+badtty /dev/tty19
+.Ed
+.Pp
+Any day/hour combination listed after the keyword ``time'' will disallow
+games during those hours. Entries consist of four white-space separated
+fields: the string ``time'', the unabbreviated day of the week and the
+beginning and ending time of a period of the day when games may not be
+played. The time fields are in a 0 based, 24-hour clock. For example,
+the following entry allows games playing before 8AM and after 5PM on
+Mondays.
+.Bd -literal -offset indent
+time Monday 8 17
+.Ed
+.Pp
+Any game listed after the keyword ``game'' will set parameters for a specific
+game. Entries consist of five white-space separated fields: the keyword
+``game'', the name of a game, the highest system load average at which the
+game may be played, the maximum users allowed if the game is to be played,
+and the priority at which the game is to be run. Any of these fields may
+start with a non-numeric character, resulting in no game limitation or
+priority based on that field. The game "default" controls the settings for
+any game not otherwise listed, and must be the last ``game'' entry in the
+file. Priorities may not be negative. For example, the following entries
+limits the game ``hack'' to running only when the system has 10 or less
+users and a load average of 5 or less; all other games may be run any time
+the system has 15 or less users.
+.Bd -literal -offset indent
+game hack 5 10 *
+game default * 15 *
+.Ed
+.Sh FILES
+.Bl -tag -width /etc/dm.conf -compact
+.It Pa /etc/dm.conf
+The
+.Xr \&dm 8
+configuration file.
+.El
+.Sh SEE ALSO
+.Xr setpriority 2 ,
+.Xr ttyname 3 ,
+.Xr dm 8
diff --git a/dm/pathnames.h b/dm/pathnames.h
new file mode 100644
index 00000000..44d36b13
--- /dev/null
+++ b/dm/pathnames.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.3 (Berkeley) 6/26/90
+ */
+
+#define _PATH_CONFIG "/etc/dm.conf"
+#define _PATH_HIDE "/usr/games/hide/"
+#define _PATH_LOG "/var/log/games.log"
+#define _PATH_NOGAMES "/etc/nogames"
diff --git a/factor/Makefile b/factor/Makefile
new file mode 100644
index 00000000..846831b4
--- /dev/null
+++ b/factor/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 5.7 (Berkeley) 4/8/91
+
+PROG= factor
+SRCS= factor.c pr_tbl.c
+CFLAGS+=-I${.CURDIR}/../primes
+MAN6= factor.0
+MLINKS+=factor.6 primes.6
+.PATH: ${.CURDIR}/../primes
+
+.include <bsd.prog.mk>
diff --git a/factor/factor.6 b/factor/factor.6
new file mode 100644
index 00000000..fe83c689
--- /dev/null
+++ b/factor/factor.6
@@ -0,0 +1,116 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Landon Curt Noll.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)factor.6 5.3 (Berkeley) 6/23/90
+.\"
+.\"
+.\" By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
+.\"
+.\" chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+.\"
+.TH FACTOR 6 "June 23, 1990"
+.UC 7
+.SH NAME
+factor, primes \- factor a number, generate primes
+.SH SYNOPSIS
+.B factor
+[ number ] ...
+.PP
+.B primes
+[ start [ stop ]]
+.SH DESCRIPTION
+The
+.I factor
+utility will factor integers between -2147483648 and 2147483647 inclusive.
+When a number is factored, it is printed, followed by a ``:'',
+and the list of factors on a single line.
+Factors are listed in ascending order, and are preceded by a space.
+If a factor divides a value more than once, it will be printed
+more than once.
+.PP
+When
+.I factor
+is invoked with one or more arguments,
+each argument will be factored.
+.PP
+When
+.I factor
+is invoked with no arguments,
+.I factor
+reads numbers, one per line, from standard input, until end of file or error.
+Leading white-space and empty lines are ignored.
+Numbers may be preceded by a single - or +.
+Numbers are terminated by a non-digit character (such as a newline).
+After a number is read, it is factored.
+Input lines must not be longer than 255 characters.
+.PP
+The
+.I primes
+utility prints primes in ascending order, one per line, starting at or above
+.B start
+and continuing until, but not including
+.B stop.
+The
+.B start
+value must be at least 0 and not greater than
+.B stop.\&
+The
+.B stop
+value must not be greater than 4294967295.
+The default value of
+.B stop
+is 4294967295.
+.PP
+When the
+.I primes
+utility is invoked with no arguments,
+.B start
+is read from standard input.
+.B Stop
+is taken to be 4294967295.
+The
+.B start
+value may be preceded by a single +.
+The
+.B start
+value is terminated by a non-digit character (such as a newline).
+The input line must not be longer than 255 characters.
+.SH DIAGNOSTICS
+Out of range or invalid input results in `ouch' being
+written to standard error.
+.SH BUGS
+.I Factor
+cannot handle the ``10 most wanted'' factor list,
+.I primes
+won't get you a world record.
diff --git a/factor/factor.c b/factor/factor.c
new file mode 100644
index 00000000..df99aea1
--- /dev/null
+++ b/factor/factor.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Landon Curt Noll.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)factor.c 4.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * factor - factor a number into primes
+ *
+ * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
+ *
+ * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+ *
+ * usage:
+ * factor [number] ...
+ *
+ * The form of the output is:
+ *
+ * number: factor1 factor1 factor2 factor3 factor3 factor3 ...
+ *
+ * where factor1 < factor2 < factor3 < ...
+ *
+ * If no args are given, the list of numbers are read from stdin.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "primes.h"
+
+/*
+ * prime[i] is the (i-1)th prime.
+ *
+ * We are able to sieve 2^32-1 because this byte table yields all primes
+ * up to 65537 and 65537^2 > 2^32-1.
+ */
+extern ubig prime[];
+extern ubig *pr_limit; /* largest prime in the prime array */
+
+#define MAX_LINE 255 /* max line allowed on stdin */
+
+void pr_fact(); /* print factors of a value */
+long small_fact(); /* find smallest factor of a value */
+char *read_num_buf(); /* read a number buffer */
+char *program; /* name of this program */
+
+main(argc, argv)
+ int argc; /* arg count */
+ char *argv[]; /* the args */
+{
+ int arg; /* which arg to factor */
+ long val; /* the value to factor */
+ char buf[MAX_LINE+1]; /* input buffer */
+
+ /* parse args */
+ program = argv[0];
+ if (argc >= 2) {
+
+ /* factor each arg */
+ for (arg=1; arg < argc; ++arg) {
+
+ /* process the buffer */
+ if (read_num_buf(NULL, argv[arg]) == NULL) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+
+ /* factor the argument */
+ if (sscanf(argv[arg], "%ld", &val) == 1) {
+ pr_fact(val);
+ } else {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ }
+
+ /* no args supplied, read numbers from stdin */
+ } else {
+ /*
+ * read asciii numbers from input
+ */
+ while (read_num_buf(stdin, buf) != NULL) {
+
+ /* factor the argument */
+ if (sscanf(buf, "%ld", &val) == 1) {
+ pr_fact(val);
+ }
+ }
+ }
+ exit(0);
+}
+
+/*
+ * read_num_buf - read a number buffer from a stream
+ *
+ * Read a number on a line of the form:
+ *
+ * ^[ \t]*\([+-]?[0-9][0-9]\)*.*$
+ *
+ * where ? is a 1-or-0 operator and the number is within \( \).
+ *
+ * If does not match the above pattern, it is ignored and a new
+ * line is read. If the number is too large or small, we will
+ * print ouch and read a new line.
+ *
+ * We have to be very careful on how we check the magnitude of the
+ * input. We can not use numeric checks because of the need to
+ * check values against maximum numeric values.
+ *
+ * This routine will return a line containing a ascii number between
+ * NEG_SEMIBIG and SEMIBIG, or it will return NULL.
+ *
+ * If the stream is NULL then buf will be processed as if were
+ * a single line stream.
+ *
+ * returns:
+ * char * pointer to leading digit, + or -
+ * NULL EOF or error
+ */
+char *
+read_num_buf(input, buf)
+ FILE *input; /* input stream or NULL */
+ char *buf; /* input buffer */
+{
+ static char limit[MAX_LINE+1]; /* ascii value of SEMIBIG */
+ static int limit_len; /* digit count of limit */
+ static char neg_limit[MAX_LINE+1]; /* value of NEG_SEMIBIG */
+ static int neg_limit_len; /* digit count of neg_limit */
+ int len; /* digits in input (excluding +/-) */
+ char *s; /* line start marker */
+ char *d; /* first digit, skip +/- */
+ char *p; /* scan pointer */
+ char *z; /* zero scan pointer */
+
+ /* form the ascii value of SEMIBIG if needed */
+ if (!isascii(limit[0]) || !isdigit(limit[0])) {
+ sprintf(limit, "%ld", SEMIBIG);
+ limit_len = strlen(limit);
+ sprintf(neg_limit, "%ld", NEG_SEMIBIG);
+ neg_limit_len = strlen(neg_limit)-1; /* exclude - */
+ }
+
+ /*
+ * the search for a good line
+ */
+ if (input != NULL && fgets(buf, MAX_LINE, input) == NULL) {
+ /* error or EOF */
+ return NULL;
+ }
+ do {
+
+ /* ignore leading whitespace */
+ for (s=buf; *s && s < buf+MAX_LINE; ++s) {
+ if (!isascii(*s) || !isspace(*s)) {
+ break;
+ }
+ }
+
+ /* skip over any leading + or - */
+ if (*s == '+' || *s == '-') {
+ d = s+1;
+ } else {
+ d = s;
+ }
+
+ /* note leading zeros */
+ for (z=d; *z && z < buf+MAX_LINE; ++z) {
+ if (*z != '0') {
+ break;
+ }
+ }
+
+ /* scan for the first non-digit */
+ for (p=d; *p && p < buf+MAX_LINE; ++p) {
+ if (!isascii(*p) || !isdigit(*p)) {
+ break;
+ }
+ }
+
+ /* ignore empty lines */
+ if (p == d) {
+ continue;
+ }
+ *p = '\0';
+
+ /* object if too many digits */
+ len = strlen(z);
+ len = (len<=0) ? 1 : len;
+ if (*s == '-') {
+ /* accept if digit count is below limit */
+ if (len < neg_limit_len) {
+ /* we have good input */
+ return s;
+
+ /* reject very large numbers */
+ } else if (len > neg_limit_len) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+
+ /* carefully check against near limit numbers */
+ } else if (strcmp(z, neg_limit+1) > 0) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ /* number is near limit, but is under it */
+ return s;
+
+ } else {
+ /* accept if digit count is below limit */
+ if (len < limit_len) {
+ /* we have good input */
+ return s;
+
+ /* reject very large numbers */
+ } else if (len > limit_len) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+
+ /* carefully check against near limit numbers */
+ } else if (strcmp(z, limit) > 0) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ /* number is near limit, but is under it */
+ return s;
+ }
+ } while (input != NULL && fgets(buf, MAX_LINE, input) != NULL);
+
+ /* error or EOF */
+ return NULL;
+}
+
+
+/*
+ * pr_fact - print the factors of a number
+ *
+ * If the number is 0 or 1, then print the number and return.
+ * If the number is < 0, print -1, negate the number and continue
+ * processing.
+ *
+ * Print the factors of the number, from the lowest to the highest.
+ * A factor will be printed numtiple times if it divides the value
+ * multiple times.
+ *
+ * Factors are printed with leading tabs.
+ */
+void
+pr_fact(val)
+ long val; /* factor this value */
+{
+ ubig *fact; /* the factor found */
+
+ /* firewall - catch 0 and 1 */
+ switch (val) {
+ case -2147483648:
+ /* avoid negation problems */
+ puts("-2147483648: -1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n");
+ return;
+ case -1:
+ puts("-1: -1\n");
+ return;
+ case 0:
+ exit(0);
+ case 1:
+ puts("1: 1\n");
+ return;
+ default:
+ if (val < 0) {
+ val = -val;
+ printf("%ld: -1", val);
+ } else {
+ printf("%ld:", val);
+ }
+ fflush(stdout);
+ break;
+ }
+
+ /*
+ * factor value
+ */
+ fact = &prime[0];
+ while (val > 1) {
+
+ /* look for the smallest factor */
+ do {
+ if (val%(long)*fact == 0) {
+ break;
+ }
+ } while (++fact <= pr_limit);
+
+ /* watch for primes larger than the table */
+ if (fact > pr_limit) {
+ printf(" %ld\n", val);
+ return;
+ }
+
+ /* divide factor out until none are left */
+ do {
+ printf(" %ld", *fact);
+ val /= (long)*fact;
+ } while ((val % (long)*fact) == 0);
+ fflush(stdout);
+ ++fact;
+ }
+ putchar('\n');
+ return;
+}
diff --git a/fish/Makefile b/fish/Makefile
new file mode 100644
index 00000000..b1847b71
--- /dev/null
+++ b/fish/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 5.5 (Berkeley) 1/18/91
+
+PROG= fish
+MAN6= fish.0
+HIDEGAME=hidegame
+
+beforeinstall:
+ install -c -o bin -g bin -m 444 ${.CURDIR}/fish.instr /usr/share/games
+
+.include <bsd.prog.mk>
diff --git a/fish/fish.6 b/fish/fish.6
new file mode 100644
index 00000000..f565574a
--- /dev/null
+++ b/fish/fish.6
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fish.6 6.2 (Berkeley) 1/18/91
+.\"
+.TH FISH 6 "January 18, 1991"
+.UC 4
+.SH NAME
+fish \- play ``Go Fish''
+.SH SYNOPSIS
+.ft B
+fish [\-p]
+.ft R
+.SH DESCRIPTION
+.I Fish
+is the game
+.IR "Go Fish" ,
+a traditional children's card game.
+.PP
+The computer deals the player and itself seven cards, and places
+the rest of the deck face-down (figuratively).
+The object of the game is to collect ``books'', or all of the members
+of a single rank.
+For example, collecting four 2's would give the player a ``book of
+2's''.
+.PP
+The options are as follows:
+.TP
+\-p
+Professional mode.
+.PP
+The computer makes a random decision as to who gets to start the
+game, and then the computer and player take turns asking each other
+for cards of a specified rank.
+If the asked player has any cards of the requested rank, they give
+them up to the asking player.
+A player must have at least one of the cards of the rank they request
+in their hand.
+When a player asks for a rank of which the other player has no
+cards, the asker is told to ``Go Fish!''.
+Then, the asker draws a card from the non-dealt cards.
+If they draw the card they asked for, they continue their turn, asking
+for more ranks from the other player.
+Otherwise, the other player gets a turn.
+.PP
+When a player completes a book, either by getting cards from the
+other player or drawing from the deck, they set those cards aside and
+the rank is no longer in play.
+.PP
+The game ends when either player no longer has any cards in their hand.
+The player with the most books wins.
+.PP
+.I Fish
+provides instructions as to what input it accepts.
+.SH BUGS
+The computer cheats only rarely.
diff --git a/fish/fish.c b/fish/fish.c
new file mode 100644
index 00000000..0147ff22
--- /dev/null
+++ b/fish/fish.c
@@ -0,0 +1,429 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Muffy Barkocy.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)fish.c 5.4 (Berkeley) 1/18/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pathnames.h"
+
+#define RANKS 13
+#define HANDSIZE 7
+#define CARDS 4
+
+#define USER 1
+#define COMPUTER 0
+#define OTHER(a) (1 - (a))
+
+char *cards[] = {
+ "A", "2", "3", "4", "5", "6", "7",
+ "8", "9", "10", "J", "Q", "K", NULL,
+};
+#define PRC(card) (void)printf(" %s", cards[card])
+
+int promode;
+int asked[RANKS], comphand[RANKS], deck[RANKS];
+int userasked[RANKS], userhand[RANKS];
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int ch, move;
+
+ while ((ch = getopt(argc, argv, "p")) != EOF)
+ switch(ch) {
+ case 'p':
+ promode = 1;
+ break;
+ case '?':
+ default:
+ (void)fprintf(stderr, "usage: fish [-p]\n");
+ exit(1);
+ }
+
+ srandom(time((time_t *)NULL));
+ instructions();
+ init();
+
+ if (nrandom(2) == 1) {
+ printplayer(COMPUTER);
+ (void)printf("get to start.\n");
+ goto istart;
+ }
+ printplayer(USER);
+ (void)printf("get to start.\n");
+
+ for (;;) {
+ move = usermove();
+ if (!comphand[move]) {
+ if (gofish(move, USER, userhand))
+ continue;
+ } else {
+ goodmove(USER, move, userhand, comphand);
+ continue;
+ }
+
+istart: for (;;) {
+ move = compmove();
+ if (!userhand[move]) {
+ if (!gofish(move, COMPUTER, comphand))
+ break;
+ } else
+ goodmove(COMPUTER, move, comphand, userhand);
+ }
+ }
+ /* NOTREACHED */
+}
+
+usermove()
+{
+ register int n;
+ register char **p;
+ char buf[256];
+
+ (void)printf("\nYour hand is:");
+ printhand(userhand);
+
+ for (;;) {
+ (void)printf("You ask me for: ");
+ (void)fflush(stdout);
+ if (fgets(buf, BUFSIZ, stdin) == NULL)
+ exit(0);
+ if (buf[0] == '\0')
+ continue;
+ if (buf[0] == '\n') {
+ (void)printf("%d cards in my hand, %d in the pool.\n",
+ countcards(comphand), countcards(deck));
+ (void)printf("My books:");
+ (void)countbooks(comphand);
+ continue;
+ }
+ buf[strlen(buf) - 1] = '\0';
+ if (!strcasecmp(buf, "p") && !promode) {
+ promode = 1;
+ (void)printf("Entering pro mode.\n");
+ continue;
+ }
+ if (!strcasecmp(buf, "quit"))
+ exit(0);
+ for (p = cards; *p; ++p)
+ if (!strcasecmp(*p, buf))
+ break;
+ if (!*p) {
+ (void)printf("I don't understand!\n");
+ continue;
+ }
+ n = p - cards;
+ if (userhand[n]) {
+ userasked[n] = 1;
+ return(n);
+ }
+ if (nrandom(3) == 1)
+ (void)printf("You don't have any of those!\n");
+ else
+ (void)printf("You don't have any %s's!\n", cards[n]);
+ if (nrandom(4) == 1)
+ (void)printf("No cheating!\n");
+ (void)printf("Guess again.\n");
+ }
+ /* NOTREACHED */
+}
+
+compmove()
+{
+ static int lmove;
+
+ if (promode)
+ lmove = promove();
+ else {
+ do {
+ lmove = (lmove + 1) % RANKS;
+ } while (!comphand[lmove] || comphand[lmove] == CARDS);
+ }
+ asked[lmove] = 1;
+
+ (void)printf("I ask you for: %s.\n", cards[lmove]);
+ return(lmove);
+}
+
+promove()
+{
+ register int i, max;
+
+ for (i = 0; i < RANKS; ++i)
+ if (userasked[i] &&
+ comphand[i] > 0 && comphand[i] < CARDS) {
+ userasked[i] = 0;
+ return(i);
+ }
+ if (nrandom(3) == 1) {
+ for (i = 0;; ++i)
+ if (comphand[i] && comphand[i] != CARDS) {
+ max = i;
+ break;
+ }
+ while (++i < RANKS)
+ if (comphand[i] != CARDS &&
+ comphand[i] > comphand[max])
+ max = i;
+ return(max);
+ }
+ if (nrandom(1024) == 0723) {
+ for (i = 0; i < RANKS; ++i)
+ if (userhand[i] && comphand[i])
+ return(i);
+ }
+ for (;;) {
+ for (i = 0; i < RANKS; ++i)
+ if (comphand[i] && comphand[i] != CARDS &&
+ !asked[i])
+ return(i);
+ for (i = 0; i < RANKS; ++i)
+ asked[i] = 0;
+ }
+ /* NOTREACHED */
+}
+
+drawcard(player, hand)
+ int player;
+ int *hand;
+{
+ int card;
+
+ while (deck[card = nrandom(RANKS)] == 0);
+ ++hand[card];
+ --deck[card];
+ if (player == USER || hand[card] == CARDS) {
+ printplayer(player);
+ (void)printf("drew %s", cards[card]);
+ if (hand[card] == CARDS) {
+ (void)printf(" and made a book of %s's!\n",
+ cards[card]);
+ chkwinner(player, hand);
+ } else
+ (void)printf(".\n");
+ }
+ return(card);
+}
+
+gofish(askedfor, player, hand)
+ int askedfor, player;
+ int *hand;
+{
+ printplayer(OTHER(player));
+ (void)printf("say \"GO FISH!\"\n");
+ if (askedfor == drawcard(player, hand)) {
+ printplayer(player);
+ (void)printf("drew the guess!\n");
+ printplayer(player);
+ (void)printf("get to ask again!\n");
+ return(1);
+ }
+ return(0);
+}
+
+goodmove(player, move, hand, opphand)
+ int player, move;
+ int *hand, *opphand;
+{
+ printplayer(OTHER(player));
+ (void)printf("have %d %s%s.\n",
+ opphand[move], cards[move], opphand[move] == 1 ? "": "'s");
+
+ hand[move] += opphand[move];
+ opphand[move] = 0;
+
+ if (hand[move] == CARDS) {
+ printplayer(player);
+ (void)printf("made a book of %s's!\n", cards[move]);
+ chkwinner(player, hand);
+ }
+
+ chkwinner(OTHER(player), opphand);
+
+ printplayer(player);
+ (void)printf("get another guess!\n");
+}
+
+chkwinner(player, hand)
+ int player;
+ register int *hand;
+{
+ register int cb, i, ub;
+
+ for (i = 0; i < RANKS; ++i)
+ if (hand[i] > 0 && hand[i] < CARDS)
+ return;
+ printplayer(player);
+ (void)printf("don't have any more cards!\n");
+ (void)printf("My books:");
+ cb = countbooks(comphand);
+ (void)printf("Your books:");
+ ub = countbooks(userhand);
+ (void)printf("\nI have %d, you have %d.\n", cb, ub);
+ if (ub > cb) {
+ (void)printf("\nYou win!!!\n");
+ if (nrandom(1024) == 0723)
+ (void)printf("Cheater, cheater, pumpkin eater!\n");
+ } else if (cb > ub) {
+ (void)printf("\nI win!!!\n");
+ if (nrandom(1024) == 0723)
+ (void)printf("Hah! Stupid peasant!\n");
+ } else
+ (void)printf("\nTie!\n");
+ exit(0);
+}
+
+printplayer(player)
+ int player;
+{
+ switch (player) {
+ case COMPUTER:
+ (void)printf("I ");
+ break;
+ case USER:
+ (void)printf("You ");
+ break;
+ }
+}
+
+printhand(hand)
+ int *hand;
+{
+ register int book, i, j;
+
+ for (book = i = 0; i < RANKS; i++)
+ if (hand[i] < CARDS)
+ for (j = hand[i]; --j >= 0;)
+ PRC(i);
+ else
+ ++book;
+ if (book) {
+ (void)printf(" + Book%s of", book > 1 ? "s" : "");
+ for (i = 0; i < RANKS; i++)
+ if (hand[i] == CARDS)
+ PRC(i);
+ }
+ (void)putchar('\n');
+}
+
+countcards(hand)
+ register int *hand;
+{
+ register int i, count;
+
+ for (count = i = 0; i < RANKS; i++)
+ count += *hand++;
+ return(count);
+}
+
+countbooks(hand)
+ int *hand;
+{
+ int i, count;
+
+ for (count = i = 0; i < RANKS; i++)
+ if (hand[i] == CARDS) {
+ ++count;
+ PRC(i);
+ }
+ if (!count)
+ (void)printf(" none");
+ (void)putchar('\n');
+ return(count);
+}
+
+init()
+{
+ register int i, rank;
+
+ for (i = 0; i < RANKS; ++i)
+ deck[i] = CARDS;
+ for (i = 0; i < HANDSIZE; ++i) {
+ while (!deck[rank = nrandom(RANKS)]);
+ ++userhand[rank];
+ --deck[rank];
+ }
+ for (i = 0; i < HANDSIZE; ++i) {
+ while (!deck[rank = nrandom(RANKS)]);
+ ++comphand[rank];
+ --deck[rank];
+ }
+}
+
+nrandom(n)
+ int n;
+{
+ long random();
+
+ return((int)random() % n);
+}
+
+instructions()
+{
+ int input;
+ char buf[1024];
+
+ (void)printf("Would you like instructions (y or n)? ");
+ input = getchar();
+ while (getchar() != '\n');
+ if (input != 'y')
+ return;
+
+ (void)sprintf(buf, "%s %s", _PATH_MORE, _PATH_INSTR);
+ (void)system(buf);
+ (void)printf("Hit return to continue...\n");
+ while ((input = getchar()) != EOF && input != '\n');
+}
+
+usage()
+{
+ (void)fprintf(stderr, "usage: fish [-p]\n");
+ exit(1);
+}
diff --git a/fish/fish.instr b/fish/fish.instr
new file mode 100644
index 00000000..b7e87a0a
--- /dev/null
+++ b/fish/fish.instr
@@ -0,0 +1,29 @@
+This is the traditional children's card game "Go Fish". We each get seven
+cards, and the rest of the deck is kept to be drawn from later. The
+object of the game is to collect "books", or all of the cards of a single
+value. For example, getting four 2's would give you a "book of 2's".
+
+We take turns asking each other for cards, but you can't ask me for a card
+value if you don't have one of them in your hand! If I have any cards of
+the value you ask for, I have to give them to you. As long as I have one
+of the cards you ask for, you get to keep asking. If you ask me for a
+card of which I don't have any, then I'll tell you to "Go Fish!" This
+means that you draw a card from the deck. If you draw the card you asked
+me for, you get to keep asking me for cards. If not, it's my turn and I ask
+you for a card.
+
+Sometimes you get to ask first, sometimes I do. I'll tell you when it's
+your turn to move, I'll draw cards from the deck for you, and I'll tell
+you what you have in your hand. (Don't worry, I don't look at your hand
+when I'm trying to decide what card to ask for, honest!)
+
+Your input can be a card name ("A", "2", "3", "4", "5", "6", "7", "8",
+"9", "10", "J", "Q" or "K") or the letter "p", or "quit". The letter "p"
+makes my game much smarter, and the line "quit" stops the game. Just
+hitting the carriage return key displays how many cards I have in my hand,
+how many are left in the deck, and which books I've gotten.
+
+Normally, the game stops when one of us runs out of cards, and the winner
+is whoever has the most books!
+
+Good luck!
diff --git a/fish/pathnames.h b/fish/pathnames.h
new file mode 100644
index 00000000..bb4af192
--- /dev/null
+++ b/fish/pathnames.h
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 1/18/91
+ */
+
+#define _PATH_INSTR "/usr/share/games/fish.instr"
+#define _PATH_MORE "/usr/bin/more"
diff --git a/fortune/Makefile b/fortune/Makefile
new file mode 100644
index 00000000..f4b87ff8
--- /dev/null
+++ b/fortune/Makefile
@@ -0,0 +1,15 @@
+# @(#)Makefile 5.6 (Berkeley) 4/27/91
+
+SUBDIR= fortune
+
+.ifmake (clean) || (cleandir)
+SUBDIR+=datfiles
+.endif
+
+.ifmake !(install)
+SUBDIR+=strfile
+.else
+SUBDIR+=datfiles
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/fortune/Notes b/fortune/Notes
new file mode 100644
index 00000000..e5680c7c
--- /dev/null
+++ b/fortune/Notes
@@ -0,0 +1,175 @@
+Warning:
+ The fortunes contained in the fortune database have been collected
+ haphazardly from a cacophony of sources, in number so huge it
+ boggles the mind. It is impossible to do any meaningful quality
+ control on attributions, or lack thereof, or exactness of the quote.
+ Since this database is not used for profit, and since entire works
+ are not published, it falls under fair use, as we understand it.
+ However, if any half-assed idiot decides to make a profit off of
+ this, they will need to double check it all, and nobody not involved
+ of such an effort makes any warranty that anything in the database
+ bears any relation to the real world of literature, law, or other
+ bizzarrity.
+
+==> GENERAL INFORMATION
+ By default, fortune retrieves its fortune files from the directory
+/usr/share/games/fortune. A fortune file has two parts: the source file
+(which contains the fortunes themselves) and the data file which describes
+the fortunes. The data fil always has the same name as the fortune file
+with the string ".dat" concatenated, i.e. "fort" is the standard fortune
+database, and "fort.dat" is the data file which describes it. See
+strfile(8) for more information on creating the data files.
+ Fortunes are split into potentially offensive and not potentially
+offensive parts. The offensive version of a file has the same name as the
+non-offensive version with "-o" concatenated, i.e. "fort" is the standard
+fortune database, and "fort-o" is the standard offensive database. The
+fortune program automatically assumes that any file with a name ending in
+"-o" is potentially offensive, and should therefore only be displayed if
+explicitly requested, either with the -o option or by specifying a file name
+on the command line.
+ Potentially offensive fortune files should NEVER be maintained in
+clear text on the system. They are rotated (see caesar(6)) 13 positions.
+To create a new, potentially offensive database, use caesar to rotate it,
+and then create its data file with the -x option to strfile(8). The fortune
+program automatically decrypts the text when it prints entries from such
+databases.
+ Anything which would not make it onto network prime time programming
+(or which would only be broadcast if some discredited kind of guy said it)
+MUST be in the potentially offensive database. Fortunes containing any
+explicit language (see George Carlin's recent updated list) MUST be in the
+potentially offensive database. Political and religious opinions are often
+sequestered in the potentially offensive section as well. Anything which
+assumes as a world view blatantly racist, mysogynist (sexist), or homophobic
+ideas should not be in either, since they are not really funny unless *you*
+are racist, mysogynist, or homophobic.
+ The point of this is that people have should have a reasonable
+expectation that, should they just run "fortune", they will not be offended.
+We know that some people take offense at anything, but normal people do have
+opinions, too, and have a right not to have their sensibilities offended by
+a program which is supposed to be entertaining. People who run "fortune
+-o" or "fortune -a" are saying, in effect, that they are willing to have
+their sensibilities tweaked. However, they should not have their personal
+worth seriously (i.e., not in jest) assaulted. Jokes which depend for their
+humor on racist, mysogynist, or homophobic stereotypes *do* seriously
+assault individual personal worth, and in an general entertainment medium
+we should be able to get by without it.
+
+==> FORMATTING
+ This file describes the format for fortunes in the database. This
+is done in detail to make it easier to keep track of things. Any rule given
+here may be broken to make a better joke.
+
+[All examples are indented by one tab stop -- KCRCA]
+
+Numbers should be given in parentheses, e.g.,
+
+ (1) Everything depends.
+ (2) Nothing is always.
+ (3) Everything is sometimes.
+
+Attributions are two tab stops, followed by two hyphens, followed by a
+space, followed by the attribution, and are *not* preceded by blank
+lines. Book, journal, movie, and all other titles are in quotes, e.g.,
+
+ $100 invested at 7% interest for 100 years will become $100,000, at
+ which time it will be worth absolutely nothing.
+ -- Lazarus Long, "Time Enough for Love"
+
+Attributions which do not fit on one (72 char) line should be continued
+on a line which lines up below the first text of the attribution, e.g.,
+
+ -- A very long attribution which might not fit on one
+ line, "Ken Arnold's Stupid Sayings"
+
+Single paragraph fortunes are in left justified (non-indented) paragraphs
+unless they fall into another category listed below (see example above).
+Longer fortunes should also be in left justified paragraphs, but if this
+makes it too long, try indented paragraphs, with indentations of either one
+tab stop or 5 chars. Indentations of less than 5 are too hard to read.
+
+Laws have the title left justified and capitalized, followed by a colon,
+with all the text of the law itself indented one tab stop, initially
+capitalized, e.g.,
+
+ A Law of Computer Programming:
+ Make it possible for programmers to write in English and
+ you will find the programmers cannot write in English.
+
+Limericks are indented as follows, all lines capitalized:
+
+ A computer, to print out a fact,
+ Will divide, multiply, and subtract.
+ But this output can be
+ No more than debris,
+ If the input was short of exact.
+
+Accents precede the letter they are over, e.g., "`^He" for e with a grave
+accent. Underlining is done on a word-by-word basis, with the underlines
+preceding the word, e.g., "__^H^Hhi ____^H^H^H^Hthere".
+
+No fortune should run beyond 72 characters on a single line without good
+justification (er, no pun intended). And no right margin justification,
+either. Sorry. For BSD people, there is a program called "fmt" which can
+make this kind of formatting easier.
+
+Definitions are given with the word or phrase left justified, followed by
+the part of speech (if appropriate) and a colon. The definition starts
+indented by one tab stop, with subsequent lines left justified, e.g.,
+
+ Afternoon, n.:
+ That part of the day we spend worrying about how we wasted
+ the morning.
+
+Quotes are sometimes put around statements which are funnier or make more
+sense if they are understood as being spoken, rather than written,
+communication, e.g.,
+
+ "All my friends and I are crazy. That's the only thing that
+ keeps us sane."
+
+Ellipses are always surrounded by spaces, except when next to punctuation,
+and are three dots long.
+
+ "... all the modern inconveniences ..."
+ -- Mark Twain
+
+Human initials always have spaces after the periods, e.g, "P. T. Barnum",
+not "P.T. Barnum". However, "P.T.A.", not "P. T. A.".
+
+All fortunes should be attributed, but if and only if they are original with
+somebody. Many people have said things that are folk sayings (i.e., are
+common among the folk (i.e., us common slobs)). There is nothing wrong with
+this, of course, but such statements should not be attributed to individuals
+who did not invent them.
+
+Horoscopes should have the sign indented by one tab stop, followed by the
+dates of the sign, with the text left justified below it, e.g.,
+
+ AQUARIUS (Jan 20 - Feb 18)
+ You have an inventive mind and are inclined to be progressive. You
+ lie a great deal. On the other hand, you are inclined to be
+ careless and impractical, causing you to make the same mistakes over
+ and over again. People think you are stupid.
+
+Single quotes should not be used except as quotes within quotes. Not even
+single quotes masquerading as double quotes are to be used, e.g., don't say
+``hi there'' or `hi there' or 'hi there', but "hi there". However, you
+*can* say "I said, `hi there'".
+
+A long poem or song can be ordered as follows in order to make it fit on a
+screen (fortunes should be 19 lines or less if at all possible) (numbers
+here are stanza numbers):
+
+ 11111111111111111111
+ 11111111111111111111
+ 11111111111111111111 22222222222222222222
+ 11111111111111111111 22222222222222222222
+ 22222222222222222222
+ 33333333333333333333 22222222222222222222
+ 33333333333333333333
+ 33333333333333333333 44444444444444444444
+ 33333333333333333333 44444444444444444444
+ 44444444444444444444
+ 44444444444444444444
+
+
diff --git a/fortune/README b/fortune/README
new file mode 100644
index 00000000..ace0af6e
--- /dev/null
+++ b/fortune/README
@@ -0,0 +1,7 @@
+# @(#)README 5.1 (Berkeley) 6/26/90
+
+The potentially offensive fortunes are not installed by default on BSD
+systems. If you're absolutely, *positively*, without-a-shadow-of-a-doubt
+sure that your user community wants them installed, change the symbolic
+link "datfiles/fortunes-o" to point to "datfiles/fortunes-o.real.rot13",
+and do a make, followed by a make install.
diff --git a/fortune/datfiles/Makefile b/fortune/datfiles/Makefile
new file mode 100644
index 00000000..6af73c47
--- /dev/null
+++ b/fortune/datfiles/Makefile
@@ -0,0 +1,20 @@
+# @(#)Makefile 5.2 (Berkeley) 5/6/91
+
+DATFILES=fortunes.dat startrek.dat zippy.dat fortunes-o.dat
+CLEANFILES+=${DATFILES}
+
+install: ${DATFILES}
+ (cd ${.CURDIR} && install -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${DATFILES:R} ${DESTDIR}/usr/share/games/fortune)
+ install -o ${BINOWN} -g ${BINGRP} -m 444 ${DATFILES} \
+ ${DESTDIR}/usr/share/games/fortune
+
+fortunes-o.dat: ${.TARGET:R}
+ ${.CURDIR}/../strfile/obj/strfile -rsx \
+ ${.CURDIR}/${.TARGET:R} ${.TARGET}
+
+fortunes.dat startrek.dat zippy.dat: ${.TARGET:R}
+ ${.CURDIR}/../strfile/obj/strfile -rs \
+ ${.CURDIR}/${.TARGET:R} ${.TARGET}
+
+.include <bsd.prog.mk>
diff --git a/fortune/datfiles/fortunes b/fortune/datfiles/fortunes
new file mode 100644
index 00000000..f84326c8
--- /dev/null
+++ b/fortune/datfiles/fortunes
@@ -0,0 +1,16304 @@
+!07/11 PDP a ni deppart m'I !pleH
+%
+!07/11 PDP a ni deppart m'I !pleH
+%
+(1) Alexander the Great was a great general.
+(2) Great generals are forewarned.
+(3) Forewarned is forearmed.
+(4) Four is an even number.
+(5) Four is certainly an odd number of arms for a man to have.
+(6) The only number that is both even and odd is infinity.
+
+Therefore, Alexander the Great had an infinite number of arms.
+%
+(1) Everything depends.
+(2) Nothing is always.
+(3) Everything is sometimes.
+%
+1.79 x 10^12 furlongs per fortnight -- it's not just a good idea, it's
+the law!
+%
+10.0 times 0.1 is hardly ever 1.0.
+%
+100 buckets of bits on the bus
+100 buckets of bits
+Take one down, short it to ground
+FF buckets of bits on the bus
+
+FF buckets of bits on the bus
+FF buckets of bits
+Take one down, short it to ground
+FE buckets of bits on the bus
+
+ad infinitum...
+%
+$100 invested at 7% interest for 100 years will become $100,000, at
+which time it will be worth absolutely nothing.
+ -- Lazarus Long, "Time Enough for Love"
+%
+101 USES FOR A DEAD MICROPROCESSOR
+ (1) Scarecrow for centipedes
+ (2) Dead cat brush
+ (3) Hair barrettes
+ (4) Cleats
+ (5) Self-piercing earrings
+ (6) Fungus trellis
+ (7) False eyelashes
+ (8) Prosthetic dog claws
+ .
+ .
+ .
+ (99) Window garden harrow (pulled behind Tonka tractors)
+ (100) Killer velcro
+ (101) Currency
+%
+186,282 miles per second:
+
+It isn't just a good idea, it's the law!
+%
+2180, U.S. History question:
+ What 20th Century U.S. President was almost impeached and what
+office did he later hold?
+%
+$3,000,000
+%
+"355/113 -- Not the famous irrational number PI, but an incredible
+simulation!"
+%
+43rd Law of Computing:
+ Anything that can go wr
+fortune: Segmentation violation -- Core dumped
+%
+77. HO HUM -- The Redundant
+
+------- (7) This hexagram refers to a situation of extreme
+--- --- (8) boredom. Your programs always bomb off. Your wife
+------- (7) smells bad. Your children have hives. You are working
+---O--- (6) on an accounting system, when you want to develop the
+---X--- (9) GREAT AMERICAN COMPILER. You give up hot dates to
+--- --- (8) nurse sick computers. What you need now is sex.
+
+Nine in the second place means:
+ The yellow bird approaches the malt shop. Misfortune.
+
+Six in the third place means:
+ In former times men built altars to honor the Internal Revenue
+ Service. Great Dragons! Are you in trouble!
+%
+7:30, Channel 5: The Bionic Dog (Action/Adventure)
+ The Bionic Dog drinks too much and kicks over the National
+ Redwood Forest.
+%
+7:30, Channel 5: The Bionic Dog (Action/Adventure)
+ The Bionic Dog gets a hormonal short-circuit and violates the
+ Mann Act with an interstate Greyhound bus.
+%
+99 blocks of crud on the disk,
+99 blocks of crud!
+You patch a bug, and dump it again:
+100 blocks of crud on the disk!
+
+100 blocks of crud on the disk,
+100 blocks of crud!
+You patch a bug, and dump it again:
+101 blocks of crud on the disk! ...
+%
+A "No" uttered from deepest conviction is better and greater than a
+"Yes" merely uttered to please, or what is worse, to avoid trouble.
+ -- Mahatma Ghandi
+%
+A [golf] ball hitting a tree shall be deemed not to have hit the tree.
+Hitting a tree is simply bad luck and has no place in a scientific
+game. The player should estimate the distance the ball would have
+traveled if it had not hit the tree and play the ball from there,
+preferably atop a nice firm tuft of grass.
+ -- Donald A. Metz
+%
+A [golf] ball sliced or hooked into the rough shall be lifted and
+placed in the fairway at a point equal to the distance it carried or
+rolled into the rough. Such veering right or left frequently results
+from friction between the face of the club and the cover of the ball
+and the player should not be penalized for the erratic behavior of the
+ball resulting from such uncontrollable physical
+phenomena.
+ -- Donald A. Metz
+%
+A baby is an alimentary canal with a loud voice at one end and no
+responsibility at the other.
+%
+A baby is God's opinion that the world should go on.
+ -- Carl Sandburg
+%
+A bachelor is a selfish, undeserving guy who has cheated some woman out
+of a divorce.
+ -- Don Quinn
+%
+A banker is a fellow who lends you his umbrella when the sun is shining
+and wants it back the minute it begins to rain.
+ -- Mark Twain
+%
+A billion here, a couple of billion there -- first thing you know it
+adds up to be real money.
+ -- Senator Everett McKinley Dirksen
+%
+A bird in the bush usually has a friend in there with him.
+%
+A bird in the hand is worth what it will bring.
+%
+A bird in the hand makes it awfully hard to blow your nose.
+%
+... A booming voice says, "Wrong, cretin!", and you notice that you
+have turned into a pile of dust.
+%
+A bore is someone who persists in holding his own views after we have
+enlightened him with ours.
+%
+A budget is just a method of worrying before you spend money, as well
+as afterward.
+%
+A candidate is a person who gets money from the rich and votes from the
+poor to protect them from each other.
+%
+A celebrity is a person who is known for his well-knownness.
+%
+A child can go only so far in life without potty training. It is not
+mere coincidence that six of the last seven presidents were potty
+trained, not to mention nearly half of the nation's state legislators.
+ -- Dave Barry
+%
+A child of five could understand this! Fetch me a child of five.
+%
+A chubby man with a white beard and a red suit will approach you soon.
+Avoid him. He's a Commie.
+%
+A citizen of America will cross the ocean to fight for democracy, but
+won't cross the street to vote in a national election.
+ -- Bill Vaughan
+%
+A city is a large community where people are lonesome together
+ -- Herbert Prochnow
+%
+A classic is something that everybody wants to have read and nobody
+wants to read.
+ -- Mark Twain
+%
+A closed mouth gathers no foot.
+%
+A computer, to print out a fact,
+Will divide, multiply, and subtract.
+ But this output can be
+ No more than debris,
+If the input was short of exact.
+ -- Gigo
+%
+A conclusion is simply the place where someone got tired of thinking.
+%
+A CONS is an object which cares.
+ -- Bernie Greenberg.
+%
+A consultant is a person who borrows your watch, tells you what time it
+is, pockets the watch, and sends you a bill for it.
+%
+A continuing flow of paper is sufficient to continue the flow of paper.
+ -- Dyer
+%
+A copy of the universe is not what is required of art; one of the
+damned things is ample.
+ -- Rebecca West
+%
+A countryman between two lawyers is like a fish between two cats.
+ -- Ben Franklin
+%
+A crusader's wife slipped from the garrison
+And had an affair with a Saracen.
+ She was not oversexed,
+ Or jealous or vexed,
+She just wanted to make a comparison.
+%
+A cynic is a person searching for an honest man, with a stolen
+lantern.
+ -- Edgar A. Shoaff
+%
+A day for firm decisions!!!!! Or is it?
+%
+A day without sunshine is like night.
+%
+A diplomat is a man who can convince his wife she'd look stout in a fur
+coat.
+%
+A diplomat is someone who can tell you to go to hell in such a way that
+you will look forward to the trip.
+%
+ A disciple of another sect once came to Drescher as he was
+eating his morning meal. "I would like to give you this personality
+test", said the outsider, "because I want you to be happy."
+ Drescher took the paper that was offered him and put it into
+the toaster -- "I wish the toaster to be happy too".
+%
+A diva who specializes in risqu'e arias is an off-coloratura soprano ...
+%
+ A doctor, an architect, and a computer scientist were arguing
+about whose profession was the oldest. In the course of their
+arguments, they got all the way back to the Garden of Eden, whereupon
+the doctor said, "The medical profession is clearly the oldest, because
+Eve was made from Adam's rib, as the story goes, and that was a simply
+incredible surgical feat."
+ The architect did not agree. He said, "But if you look at the
+Garden itself, in the beginning there was chaos and void, and out of
+that, the Garden and the world were created. So God must have been an
+architect."
+ The computer scientist, who had listened to all of this said,
+"Yes, but where do you think the chaos came from?"
+%
+A door is what a dog is perpetually on the wrong side of.
+ -- Ogden Nash
+%
+A dozen, a gross, and a score,
+Plus three times the square root of four,
+ Divided by seven,
+ Plus five time eleven,
+Equals nine squared plus zero, no more.
+%
+A famous Lisp Hacker noticed an Undergraduate sitting in front of a
+Xerox 1108, trying to edit a complex Klone network via a browser.
+Wanting to help, the Hacker clicked one of the nodes in the network
+with the mouse, and asked "what do you see?" Very earnestly, the
+Undergraduate replied "I see a cursor." The Hacker then quickly
+pressed the boot toggle at the back of the keyboard, while
+simultaneously hitting the Undergraduate over the head with a thick
+Interlisp Manual. The Undergraduate was then Enlightened.
+%
+A fanatic is one who can't change his mind and won't change the
+subject.
+ -- Winston Churchill
+%
+A fool must now and then be right by chance.
+%
+A fool's brain digests philosophy into folly, science into
+superstition, and art into pedantry. Hence University education.
+ -- G. B. Shaw
+%
+A fool-proof method for sculpting an elephant: first, get a huge block
+of marble; then you chip away everything that doesn't look like an
+elephant.
+%
+A formal parsing algorithm should not always be used.
+ -- D. Gries
+%
+"A fractal is by definition a set for which the Hausdorff Besicovitch
+dimension strictly exceeds the topological dimension."
+ -- Mandelbrot, "The Fractal Geometry of Nature"
+%
+A free society is one where it is safe to be unpopular.
+ -- Adlai Stevenson
+%
+A Galileo could no more be elected president of the United States than
+he could be elected Pope of Rome. Both high posts are reserved for men
+favored by God with an extraordinary genius for swathing the bitter
+facts of life in bandages of self-illusion.
+ -- H. L. Mencken
+%
+A general leading the State Department resembles a dragon commanding
+ducks.
+ -- New York Times, Jan. 20, 1981
+%
+A girl and a boy bump into each other -- surely an accident.
+A girl and a boy bump and her handkerchief drops -- surely another accident.
+But when a girl gives a boy a dead squid -- *____that ___had __to ____mean _________something*.
+ -- S. Morganstern, "The Silent Gondoliers"
+%
+A gleekzorp without a tornpee is like a quop without a fertsneet (sort
+of).
+%
+A good question is never answered. It is not a bolt to be tightened
+into place but a seed to be planted and to bear more seed toward the
+hope of greening the landscape of idea.
+ -- John Ciardi
+%
+A great many people think they are thinking when they are merely
+rearranging their prejudices.
+ -- William James
+%
+A great nation is any mob of people which produces at least one honest
+man a century.
+%
+A hypothetical paradox:
+ What would happen in a battle between an Enterprise security
+team, who always get killed soon after appearing, and a squad of
+Imperial Stormtroopers, who can't hit the broad side of a planet?
+ -- Tom Galloway
+%
+A is for Amy who fell down the stairs, B is for Basil assaulted by bears.
+C is for Clair who wasted away, D is for Desmond thrown out of the sleigh.
+E is for Ernest who choked on a peach, F is for Fanny, sucked dry by a leech.
+G is for George, smothered under a rug, H is for Hector, done in by a thug.
+I is for Ida who drowned in the lake, J is for James who took lye, by mistake.
+K is for Kate who was struck with an axe, L is for Leo who swallowed some tacks.
+M is for Maud who was swept out to sea, N is for Nevil who died of enui.
+O is for Olive, run through with an awl, P is for Prue, trampled flat in a brawl
+Q is for Quinton who sank in a mire, R is for Rhoda, consumed by a fire.
+S is for Susan who parished of fits, T is for Titas who flew into bits.
+U is for Una who slipped down a drain, V is for Victor, squashed under a train.
+W is for Winie, embedded in ice, X is for Xercies, devoured by mice.
+Y is for Yoric whose head was bashed in, Z is for Zilla who drank too much gin.
+ -- Edward Gorey "The Gastly Crumb Tines"
+%
+A journey of a thousand miles begins with a cash advance.
+%
+A jury consists of 12 persons chosen to decide
+who has the better lawyer.
+ -- Robert Frost
+%
+A lack of leadership is no substitute for inaction.
+%
+A lack of leadership is no substitute for inaction.
+%
+A lack of leadership is no substitute for inaction.
+%
+A lady with one of her ears applied
+To an open keyhole heard, inside,
+Two female gossips in converse free --
+The subject engaging them was she.
+"I think", said one, "and my husband thinks
+That she's a prying, inquisitive minx!"
+As soon as no more of it she could hear
+The lady, indignant, removed her ear.
+"I will not stay," she said with a pout,
+"To hear my character lied about!"
+ -- Gopete Sherany
+%
+A language that doesn't affect the way you think about programming is
+not worth knowing.
+%
+A language that doesn't have everything is actually easier to program
+in than some that do.
+ -- Dennis M. Ritchie
+%
+A large number of installed systems work by fiat. That is, they work
+by being declared to work.
+ -- Anatol Holt
+%
+A Law of Computer Programming:
+ Make it possible for programmers to write in English and you
+will find the programmers cannot write in English.
+%
+A limerick packs laughs anatomical
+Into space that is quite economical.
+ But the good ones I've seen
+ So seldom are clean,
+And the clean ones so seldom are comical.
+%
+A LISP programmer knows the value of everything, but the cost of
+nothing.
+%
+A little inaccuracy sometimes saves tons of explanation.
+ -- H. H. Munroe
+%
+A long memory is the most subversive idea in America.
+%
+A long-forgotten loved one will appear soon. Buy the negatives at any
+price.
+%
+A Los Angeles judge ruled that "a citizen may snore with immunity in
+his own home, even though he may be in possession of unusual and
+exceptional ability in that particular field."
+%
+A lot of people are afraid of heights. Not me. I'm afraid of widths.
+ -- Steve Wright
+%
+A lot of people I know believe in positive thinking, and so do I. I
+believe everything positively stinks.
+ -- Lew Col
+%
+ A man goes to a tailor to try on a new custom-made suit. The
+first thing he notices is that the arms are too long.
+ "No problem," says the tailor. "Just bend them at the elbow
+and hold them out in front of you. See, now it's fine."
+ "But the collar is up around my ears!"
+ "It's nothing. Just hunch your back up a little ... no, a
+little more ... that's it."
+ "But I'm stepping on my cuffs!" the man cries in desperation.
+ "Nu, bend you knees a little to take up the slack. There you
+go. Look in the mirror -- the suit fits perfectly."
+ So, twisted like a pretzel, the man lurches out onto the
+street. Reba and Florence see him go by.
+ "Oh, look," says Reba, "that poor man!"
+ "Yes," says Florence, "but what a beautiful suit."
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+A man said to the Universe: "Sir, I exist!"
+
+"However," replied the Universe, "the fact has not created in me a
+sense of obligation."
+ -- Stephen Crane
+%
+A man wrapped up in himself makes a very small package.
+%
+ A master was explaining the nature of Tao to one of his
+novices. "The Tao is embodied in all software -- regardless of how
+insignificant," said the master.
+
+ "Is Tao in a hand-held calculator?" asked the novice.
+
+ "It is," came the reply.
+
+ "Is the Tao in a video game?" continued the novice.
+
+ "It is even in a video game," said the master.
+
+ "And is the Tao in the DOS for a personal computer?"
+
+ The master coughed and shifted his position slightly. "The
+lesson is over for today," he said.
+ -- "The Tao of Programming"
+%
+A mathematician is a machine for converting coffee into theorems.
+%
+A Mexican newspaper reports that bored Royal Air Force pilots stationed
+on the Falkland Islands have devised what they consider a marvelous new
+game. Noting that the local penguins are fascinated by airplanes, the
+pilots search out a beach where the birds are gathered and fly slowly
+along it at the water's edge. Perhaps ten thousand penguins turn their
+heads in unison watching the planes go by, and when the pilots turn
+around and fly back, the birds turn their heads in the opposite
+direction, like spectators at a slow-motion tennis match. Then, the
+paper reports, "The pilots fly out to sea and directly to the penguin
+colony and overfly it. Heads go up, up, up, and ten thousand penguins
+fall over gently onto their backs.
+ -- Audobon Society Magazine
+%
+ A musician of more ambition than talent composed an elegy at
+the death of composer Edward MacDowell. She played the elegy for the
+pianist Josef Hoffman, then asked his opinion. "Well, it's quite
+nice," he replied, but don't you think it would be better if ..."
+ "If what?" asked the composer.
+ "If ... if you had died and MacDowell had written the elegy?"
+%
+A neighbor came to Nasrudin, asking to borrow his donkey. "It is out
+on loan," the teacher replied. At that moment, the donkey brayed
+loudly inside the stable. "But I can hear it bray, over there." "Whom
+do you believe," asked Nasrudin, "me or a donkey?"
+%
+A new dramatist of the absurd
+Has a voice that will shortly be heard.
+ I learn from my spies
+ He's about to devise
+An unprintable three-letter word.
+%
+A new koan:
+
+ If you have some ice cream, I will give it to you.
+
+ If you have no ice cream, I will take it away from you.
+
+It is an ice cream koan.
+%
+A new supply of round tuits has arrived and are available from Mary.
+Anyone who has been putting off work until they got a round tuit now
+has no excuse for further procrastination.
+%
+A New York City judge ruled that if two women behind you at the movies
+insist on discussing the probable outcome of the film, you have the
+right to turn around and blow a Bronx cheer at them.
+%
+A New York City ordinance prohibits the shooting of rabbits from the
+rear of a Third Avenue street car -- if the car is in motion.
+%
+ A novel approach is to remove all power from the system, which
+removes most system overhead so that resources can be fully devoted to
+doing nothing. Benchmarks on this technique are promising; tremendous
+amounts of nothing can be produced in this manner. Certain hardware
+limitations can limit the speed of this method, especially in the
+larger systems which require a more involved & less efficient
+power-down sequence.
+ An alternate approach is to pull the main breaker for the
+building, which seems to provide even more nothing, but in truth has
+bugs in it, since it usually inhibits the systems which keep the beer
+cool.
+%
+A novice was trying to fix a broken Lisp machine by turning the power
+off and on. Knight, seeing what the student was doing spoke sternly:
+"You can not fix a machine by just power-cycling it with no
+understanding of what is going wrong." Knight turned the machine off
+and on. The machine worked.
+%
+A nuclear war can ruin your whole day.
+%
+A pedestal is as much a prison as any small, confined space.
+ -- Gloria Steinem
+%
+A penny saved is ridiculous.
+%
+A person is just about as big as the things that make them angry.
+%
+A physicist is an atom's way of knowing about atoms.
+ -- George Wald
+%
+A pig is a jolly companion,
+Boar, sow, barrow, or gilt --
+A pig is a pal, who'll boost your morale,
+Though mountains may topple and tilt.
+When they've blackballed, bamboozled, and burned you,
+When they've turned on you, Tory and Whig,
+Though you may be thrown over by Tabby and Rover,
+You'll never go wrong with a pig, a pig,
+You'll never go wrong with a pig!
+ -- Thomas Pynchon, "Gravity's Rainbow"
+%
+ A Plan for the Improvement of English Spelling
+ by Mark Twain
+
+ For example, in Year 1 that useless letter "c" would be dropped
+to be replased either by "k" or "s", and likewise "x" would no longer
+be part of the alphabet. The only kase in which "c" would be retained
+would be the "ch" formation, which will be dealt with later. Year 2
+might reform "w" spelling, so that "which" and "one" would take the
+same konsonant, wile Year 3 might well abolish "y" replasing it with
+"i" and Iear 4 might fiks the "g/j" anomali wonse and for all.
+ Jenerally, then, the improvement would kontinue iear bai iear
+with Iear 5 doing awai with useless double konsonants, and Iears 6-12
+or so modifaiing vowlz and the rimeining voist and unvoist konsonants.
+Bai Iear 15 or sou, it wud fainali bi posibl tu meik ius ov thi
+ridandant letez "c", "y" and "x" -- bai now jast a memori in the maindz
+ov ould doderez -- tu riplais "ch", "sh", and "th" rispektivli.
+ Fainali, xen, aafte sam 20 iers ov orxogrefkl riform, wi wud
+hev a lojikl, kohirnt speling in ius xrewawt xe Ingliy-spiking werld.
+%
+"A power so great, it can only be used for Good or Evil!"
+ -- Firesign Theatre, "The Giant Rat of Summatra"
+%
+A priest asked: What is Fate, Master?
+
+And he answered:
+
+It is that which gives a beast of burden its reason for existence.
+
+It is that which men in former times had to bear upon their backs.
+
+It is that which has caused nations to build byways from City to City
+upon which carts and coaches pass, and alongside which inns have come
+to be built to stave off Hunger, Thirst and Weariness.
+
+And that is Fate? said the priest.
+
+Fate ... I thought you said Freight, responded the Master.
+
+That's all right, said the priest. I wanted to know what Freight was
+too.
+ -- Kehlog Albran, "The Profit"
+%
+ A priest was walking along the cliffs at Dover when he came
+upon two locals pulling another man ashore on the end of a rope.
+"That's what I like to see", said the priest, "A man helping his fellow
+man".
+ As he was walking away, one local remarked to the other, "Well,
+he sure doesn't know the first thing about shark fishing."
+%
+A professor is one who talks in someone else's sleep.
+%
+"A programmer is a person who passes as an exacting expert on the basis
+of being able to turn out, after innumerable punching, an infinite
+series of incomprehensive answers calculated with micrometric
+precisions from vague assumptions based on debatable figures taken from
+inconclusive documents and carried out on instruments of problematical
+accuracy by persons of dubious reliability and questionable mentality
+for the avowed purpose of annoying and confounding a hopelessly
+defenseless department that was unfortunate enough to ask for the
+information in the first place."
+ -- IEEE Grid news magazine
+%
+A psychiatrist is a person who will give you expensive answers that
+your wife will give you for free.
+%
+A public debt is a kind of anchor in the storm; but if the anchor be
+too heavy for the vessel, she will be sunk by that very weight which
+was intended for her preservation.
+ -- Colton
+%
+A putt that stops close enough to the cup to inspire such comments as
+"you could blow it in" may be blown in. This rule does not apply if
+the ball is more than three inches from the hole, because no one wants
+to make a travesty of the game.
+ -- Donald A. Metz
+%
+"A raccoon tangled with a 23,000 volt line today. The results blacked
+out 1400 homes and, of course, one raccoon."
+ -- Steel City News
+%
+"A radioactive cat has eighteen half-lives."
+%
+A reading from the Book of Armaments, Chapter 4, Verses 16 to 20:
+
+Then did he raise on high the Holy Hand Grenade of Antioch, saying,
+"Bless this, O Lord, that with it thou mayst blow thine enemies to tiny
+bits, in thy mercy." And the people did rejoice and did feast upon the
+lambs and toads and tree-sloths and fruit-bats and orangutans and
+breakfast cereals ... Now did the Lord say, "First thou pullest the
+Holy Pin. Then thou must count to three. Three shall be the number of
+the counting and the number of the counting shall be three. Four shalt
+thou not count, neither shalt thou count two, excepting that thou then
+proceedeth to three. Five is right out. Once the number three, being
+the number of the counting, be reached, then lobbest thou the Holy Hand
+Grenade in the direction of thine foe, who, being naughty in my sight,
+shall snuff it."
+ -- Monty Python, "Monty Python and the Holy Grail"
+%
+A real patriot is the fellow who gets a parking ticket and rejoices
+that the system works.
+%
+A real person has two reasons for doing anything ... a good reason and
+the real reason.
+%
+A recent study has found that concentrating on difficult off-screen
+objects, such as the faces of loved ones, causes eye strain in computer
+scientists. Researchers into the phenomenon cite the added
+concentration needed to "make sense" of such unnatural three
+dimensional objects ...
+%
+A Riverside, California, health ordinance states that two persons may
+not kiss each other without first wiping their lips with carbolized
+rosewater.
+%
+A rock pile ceases to be a rock pile the moment a single man
+contemplates it, bearing within him the image of a cathedral.
+ -- Antoine de Saint-Exupery
+%
+A sense of humor keen enough to show a man his own absurdities will
+keep him from the commission of all sins, or nearly all, save those
+that are worth committing.
+ -- Samuel Butler
+%
+ A Severe Strain on the Credulity
+
+As a method of sending a missile to the higher, and even to the highest
+parts of the earth's atmospheric envelope, Professor Goddard's rocket
+is a practicable and therefore promising device. It is when one
+considers the multiple-charge rocket as a traveler to the moon that one
+begins to doubt ... for after the rocket quits our air and really
+starts on its journey, its flight would be neither accelerated nor
+maintained by the explosion of the charges it then might have left.
+Professor Goddard, with his "chair" in Clark College and countenancing
+of the Smithsonian Institution, does not know the relation of action to
+re-action, and of the need to have something better than a vacuum
+against which to react ... Of course he only seems to lack the
+knowledge ladled out daily in high schools.
+ -- New York Times Editorial, 1920
+%
+A sine curve goes off to infinity or at least the end of the blackboard
+ -- Prof. Steiner
+%
+... A solemn, unsmiling, sanctimonious old iceberg who looked like he
+was waiting for a vacancy in the Trinity.
+ -- Mark Twain
+%
+A straw vote only shows which way the hot air blows.
+ -- O'Henry
+%
+A strong conviction that something must be done is the parent of many
+bad measures.
+ -- Daniel Webster
+%
+A student who changes the course of history is probably taking an
+exam.
+%
+A student, in hopes of understanding the Lambda-nature, came to
+Greenblatt. As they spoke a Multics system hacker walked by. "Is it
+true," asked the student, "that PL-1 has many of the same data types as
+Lisp?" Almost before the student had finished his question, Greenblatt
+shouted, "FOO!", and hit the student with a stick.
+%
+A successful [software] tool is one that was used to do something
+undreamed of by its author.
+ -- S. C. Johnson
+%
+A tautology is a thing which is tautological.
+%
+A total abstainer is one who abstains from everything but abstention,
+and especially from inactivity in the affairs of others.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+A transistor protected by a fast-acting fuse will protect the fuse by
+blowing first.
+%
+A triangle which has an angle of 135 degrees is called an obscene
+triangle.
+%
+A truly wise man never plays leapfrog with a unicorn.
+%
+A university is what a college becomes when the faculty loses interest
+in students.
+ -- John Ciardi
+%
+"A University without students is like an ointment without a fly."
+ -- Ed Nather, professor of astronomy at UT Austin
+%
+A UNIX saleslady, Lenore,
+Enjoys work, but she likes the beach more.
+ She found a good way
+ To combine work and play:
+She sells C shells by the seashore.
+%
+A vacuum is a hell of a lot better than some of the stuff that nature
+replaces it with.
+ -- Tennessee Williams
+%
+A very intelligent turtle
+Found programming UNIX a hurdle
+ The system, you see,
+ Ran as slow as did he,
+And that's not saying much for the turtle.
+%
+A well adjusted person is one who makes the same mistake twice without
+getting nervous.
+%
+A witty saying proves nothing, but saying something pointless gets
+people's attention.
+%
+"A witty saying proves nothing."
+ -- Voltaire
+%
+"A wizard cannot do everything; a fact most magicians are reticent to
+admit, let alone discuss with prospective clients. Still, the fact
+remains that there are certain objects, and people, that are, for one
+reason or another, completely immune to any direct magical spell. It
+is for this group of beings that the magician learns the subtleties of
+using indirect spells. It also does no harm, in dealing with these
+matters, to carry a large club near your person at all times."
+ -- The Teachings of Ebenezum, Volume VIII
+%
+A year spent in artificial intelligence is enough to make one believe
+in God.
+%
+A.A.A.A.A.:
+ An organization for drunks who drive
+%
+AAAAAAAAAaaaaaaaaaaaaaaaccccccccckkkkkk!!!!!!!!!
+You brute! Knock before entering a ladies room!
+%
+Abandon the search for Truth; settle for a good fantasy.
+%
+"About the time we think we can make ends meet, somebody moves the
+ends."
+ -- Herbert Hoover
+%
+Absence makes the heart go wander.
+%
+Absent, adj.:
+ Exposed to the attacks of friends and acquaintances; defamed;
+slandered.
+%
+Absentee, n.:
+ A person with an income who has had the forethought to remove
+himself from the sphere of exaction.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Abstainer, n.:
+ A weak person who yields to the temptation of denying himself a
+pleasure.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Absurdity, n.:
+ A statement or belief manifestly inconsistent with one's own
+opinion.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Academic politics is the most vicious and bitter form of politics,
+because the stakes are so low.
+ -- Wallace Sayre
+%
+Accident, n.:
+ A condition in which presence of mind is good, but absence of
+body is better.
+%
+Accidents cause History.
+
+If Sigismund Unbuckle had taken a walk in 1426 and met Wat Tyler, the
+Peasant's Revolt would never have happened and the motor car would not
+have been invented until 2026, which would have meant that all the oil
+could have been used for lamps, thus saving the electric light bulb and
+the whale, and nobody would have caught Moby Dick or Billy Budd.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+According to Arkansas law, Section 4761, Pope's Digest: "No person
+shall be permitted under any pretext whatever, to come nearer than
+fifty feet of any door or window of any polling room, from the opening
+of the polls until the completion of the count and the certification of
+the returns."
+%
+According to Kentucky state law, every person must take a bath at least
+once a year.
+%
+According to my best recollection, I don't remember.
+ -- Vincent "Jimmy Blue Eyes" Alo
+%
+According to the latest official figures, 43% of all statistics are
+totally worthless.
+%
+According to the obituary notices, a mean and unimportant person never
+dies.
+%
+"According to the Rand McNally Places-Rated Almanac, the best place to
+live in America is the city of Pittsburgh. The city of New York came
+in twenty-fifth. Here in New York we really don't care too much.
+Because we know that we could beat up their city anytime."
+ -- David Letterman
+%
+Accordion, n.:
+ A bagpipe with pleats.
+%
+Accuracy, n.:
+ The vice of being right
+%
+ ACHTUNG!!!
+
+Das machine is nicht fur gefingerpoken und mittengrabben. Ist easy
+schnappen der springenwerk, blowenfusen und corkenpoppen mit
+spitzensparken. Ist nicht fur gewerken by das dummkopfen. Das
+rubbernecken sightseeren keepen hands in das pockets. Relaxen und
+vatch das blinkenlights!!!
+%
+Acid -- better living through chemistry.
+%
+Acid absorbs 47 times it's weight in excess Reality.
+%
+Acquaintance, n.:
+ A person whom we know well enough to borrow from, but not well
+enough to lend to.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+"Acting is an art which consists of keeping the audience from
+coughing."
+%
+Actor: "I'm a smash hit. Why, yesterday during the last act, I had
+ everyone glued in their seats!"
+Oliver Herford: "Wonderful! Wonderful! Clever of you to think of
+ it!"
+%
+Actor: So what do you do for a living?
+Doris: I work for a company that makes deceptively shallow serving
+ dishes for Chinese restaurants.
+ -- Woody Allen, "Without Feathers"
+%
+Actors will happen even in the best-regulated families.
+%
+ADA, n.:
+ Something you need only know the name of to be an Expert in
+Computing. Useful in sentences like, "We had better develop an ADA
+awareness."
+%
+Admiration, n.:
+ Our polite recognition of another's resemblance to ourselves.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Adolescence, n.:
+ The stage between puberty and adultery.
+%
+"Adopted kids are such a pain -- you have to teach them how to look
+like you ..."
+ -- Gilda Radner
+%
+Adore, v.:
+ To venerate expectantly.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Adult, n.:
+ One old enough to know better.
+%
+Advertising is a valuable economic factor because it is the cheapest
+way of selling goods, particularly if the goods are worthless.
+ -- Sinclair Lewis
+%
+Advice to young men: Be ascetic, and if you can't be ascetic,
+then at least be asceptic.
+%
+After [Benjamin] Franklin came a herd of Electrical Pioneers whose
+names have become part of our electrical terminology: Myron Volt, Mary
+Louise Amp, James Watt, Bob Transformer, etc. These pioneers conducted
+many important electrical experiments. For example, in 1780 Luigi
+Galvani discovered (this is the truth) that when he attached two
+different kinds of metal to the leg of a frog, an electrical current
+developed and the frog's leg kicked, even though it was no longer
+attached to the frog, which was dead anyway. Galvani's discovery led
+to enormous advances in the field of amphibian medicine. Today,
+skilled veterinary surgeons can take a frog that has been seriously
+injured or killed, implant pieces of metal in its muscles, and watch it
+hop back into the pond just like a normal frog, except for the fact
+that it sinks like a stone.
+ -- Dave Barry, "What is Electricity?"
+%
+After a few boring years, socially meaningful rock 'n' roll died out.
+It was replaced by disco, which offers no guidance to any form of life
+more advanced than the lichen family.
+ -- Dave Barry, "Kids Today: They Don't Know Dum Diddly
+ Do"
+%
+After a number of decimal places, nobody gives a damn.
+%
+"... After all, all he did was string together a lot of old, well-known
+quotations."
+ -- H. L. Mencken, on Shakespeare
+%
+After all, what is your hosts' purpose in having a party? Surely not
+for you to enjoy yourself; if that were their sole purpose, they'd have
+simply sent champagne and women over to your place by taxi.
+ -- P. J. O'Rourke
+%
+After an instrument has been assembled, extra components will be found
+on the bench.
+%
+ After his Ignoble Disgrace, Satan was being expelled from
+Heaven. As he passed through the Gates, he paused a moment in thought,
+and turned to God and said, "A new creature called Man, I hear, is soon
+to be created."
+ "This is true," He replied.
+ "He will need laws," said the Demon slyly.
+ "What! You, his appointed Enemy for all Time! You ask for the
+right to make his laws?"
+ "Oh, no!" Satan replied, "I ask only that he be allowed to
+make his own."
+ It was so granted.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+"After I asked him what he meant, he replied that freedom consisted of
+the unimpeded right to get rich, to use his ability, no matter what the
+cost to others, to win advancement."
+ -- Norman Thomas
+%
+After I run your program, let's make love like crazed weasels, OK?
+%
+After living in New York, you trust nobody, but you believe
+everything. Just in case.
+%
+After the last of 16 mounting screws has been removed from an access
+cover, it will be discovered that the wrong access cover has been
+removed.
+%
+Afternoon very favorable for romance. Try a single person for a
+change.
+%
+Afternoon, n.:
+ That part of the day we spend worrying about how we wasted the
+morning.
+%
+Age before beauty; and pearls before swine.
+ -- Dorothy Parker
+%
+Age, n.:
+ That period of life in which we compound for the vices that we
+still cherish by reviling those that we no longer have the enterprise
+to commit.
+ -- Ambrose Bierce
+%
+Ah say, son, you're about as sharp as a bowlin' ball.
+%
+Ah, but the choice of dreams to live,
+there's the rub.
+
+For all dreams are not equal,
+some exit to nightmare
+most end with the dreamer
+
+But at least one must be lived ... and died.
+%
+"Ah, you know the type. They like to blame it all on the Jews or the
+Blacks, 'cause if they couldn't, they'd have to wake up to the fact
+that life's one big, scary, glorious, complex and ultimately
+unfathomable crapshoot -- and the only reason THEY can't seem to keep
+up is they're a bunch of misfits and losers."
+ -- A analysis of Neo-Nazis, from "The Badger" comic
+%
+Air is water with holes in it
+%
+Alas, I am dying beyond my means.
+ -- Oscar Wilde, as he sipped champagne on his deathbed
+%
+Albert Einstein, when asked to describe radio, replied: "You see, wire
+telegraph is a kind of a very, very long cat. You pull his tail in New
+York and his head is meowing in Los Angeles. Do you understand this?
+And radio operates exactly the same way: you send signals here, they
+receive them there. The only difference is that there is no cat."
+%
+Alden's Laws:
+ (1) Giving away baby clothes and furniture is the major cause
+ of pregnancy.
+ (2) Always be backlit.
+ (3) Sit down whenever possible.
+%
+Aleph-null bottles of beer on the wall,
+Aleph-null bottles of beer,
+ You take one down, and pass it around,
+Aleph-null bottles of beer on the wall.
+%
+Alex Haley was adopted!
+%
+Alexander Graham Bell is alive and well in New York, and still waiting
+for a dial tone.
+%
+Alimony is a system by which, when two people make a mistake, one of
+them keeps paying for it.
+ -- Peggy Joyce
+%
+All [zoos] actually offer to the public in return for the taxes spent
+upon them is a form of idle and witless amusement, compared to which a
+visit to a penitentiary, or even to a State legislature in session, is
+informing, stimulating and ennobling.
+ -- H. L. Mencken
+%
+All bridge hands are equally likely, but some are more equally likely
+than others.
+ -- Alan Truscott
+%
+All extremists should be taken out and shot.
+%
+All Finagle Laws may be bypassed by learning the simple art of doing
+without thinking.
+%
+"All flesh is grass"
+ -- Isiah
+Smoke a friend today.
+%
+All I ask is a chance to prove that money can't make me happy.
+%
+All I ask of life is a constant and exaggerated sense of my own
+importance.
+%
+All I can think of is a platter of organic PRUNE CRISPS being trampled
+by an army of swarthy, Italian LOUNGE SINGERS ...
+%
+All I want is a warm bed and a kind word and unlimited power
+ -- Ashleigh Brilliant
+%
+All men are mortal. Socrates was mortal. Therefore, all men are
+Socrates.
+ -- Woody Allen
+%
+"All my friends and I are crazy. That's the only thing that keeps us
+sane."
+%
+"All my life I wanted to be someone; I guess I should have been more
+specific."
+ -- Jane Wagner
+%
+All of the true things I am about to tell you are shameless lies.
+ -- The Book of Bokonon / Kurt Vonnegut Jr.
+%
+All other things being equal, a bald man cannot be elected President of
+the United States.
+ -- Vic Gold
+%
+All power corrupts, but we need electricity.
+%
+All programmers are playwrights and all computers are lousy actors.
+%
+All progress is based upon a universal innate desire on the part of
+every organism to live beyond its income.
+ -- Samuel Butler
+%
+All science is either physics or stamp collecting.
+ -- E. Rutherford
+%
+"All snakes who wish to remain in Ireland will please raise their right
+hands."
+ -- Saint Patrick
+%
+All syllogisms have three parts, therefore this is not a syllogism.
+%
+All the big corporations depreciate their possessions, and you can,
+too, provided you use them for business purposes. For example, if you
+subscribe to the Wall Street Journal, a business-related newspaper, you
+can deduct the cost of your house, because, in the words of U.S.
+Supreme Court Chief Justice Warren Burger in a landmark 1979 tax
+decision: "Where else are you going to read the paper? Outside? What
+if it rains?"
+ -- Dave Barry, "Sweating Out Taxes"
+%
+"... all the modern inconveniences ..."
+ -- Mark Twain
+%
+All the passions make us commit faults; love makes us commit the most
+ridiculous ones.
+ -- La Rochefoucauld
+%
+All the taxes paid over a lifetime by the average American are spent by
+the government in less than a second.
+ -- Jim Fiebig
+%
+All the world's a stage and most of us are desperately unrehearsed.
+ -- Sean O'Casey
+%
+All the world's a VAX,
+And all the coders merely butchers;
+They have their exits and their entrails;
+And one int in his time plays many widths,
+His sizeof being _N bytes. At first the infant,
+Mewling and puking in the Regent's arms.
+And then the whining schoolboy, with his Sun,
+And shining morning face, creeping like slug
+Unwillingly to school.
+ -- A Very Annoyed PDP-11
+%
+All theoretical chemistry is really physics;
+and all theoretical chemists know it.
+ -- Richard P. Feynman
+%
+All things are possible, except skiing thru a revolving door.
+%
+All this wheeling and dealing around, why, it isn't for money, it's for
+fun. Money's just the way we keep score.
+%
+All true wisdom is found on T-shirts.
+%
+All wars are civil wars, because all men are brothers ... Each one owes
+infinitely more to the human race than to the particular country in
+which he was born.
+ -- Francois Fenelon
+%
+Alliance, n.:
+ In international politics, the union of two thieves who have
+their hands so deeply inserted in each other's pocket that they cannot
+separately plunder a third.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Alone, adj.:
+ In bad company.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Although golf was originally restricted to wealthy, overweight
+Protestants, today it's open to anybody who owns hideous clothing.
+ -- Dave Barry
+%
+Although the moon is smaller than the earth, it is farther away.
+%
+Although we modern persons tend to take our electric lights, radios,
+mixers, etc., for granted, hundreds of years ago people did not have
+any of these things, which is just as well because there was no place
+to plug them in. Then along came the first Electrical Pioneer,
+Benjamin Franklin, who flew a kite in a lighting storm and received a
+serious electrical shock. This proved that lighting was powered by the
+same force as carpets, but it also damaged Franklin's brain so severely
+that he started speaking only in incomprehensible maxims, such as "A
+penny saved is a penny earned." Eventually he had to be given a job
+running the post office.
+ -- Dave Barry, "What is Electricity?"
+%
+Although written many years ago, Lady Chatterley's Lover has just been
+reissued by the Grove Press, and this pictorial account of the
+day-to-day life of an English gamekeeper is full of considerable
+interest to outdoor minded readers, as it contains many passages on
+pheasant-raising, the apprehending of poachers, ways to control vermin,
+and other chores and duties of the professional gamekeeper.
+Unfortunately, one is obliged to wade through many pages of extraneous
+material in order to discover and savour those sidelights on the
+management of a midland shooting estate, and in this reviewer's opinion
+the book cannot take the place of J. R. Miller's "Practical
+Gamekeeping."
+ -- Ed Zern, "Field and Stream" (Nov. 1959)
+%
+Always borrow money from a pessimist; he doesn't expect to be paid
+back.
+%
+Always remember that you are unique. Just like everyone else.
+%
+"Always try to do things in chronological order; it's less confusing
+that way."
+%
+Am I ranting? I hope so. My ranting gets raves.
+%
+ AMAZING BUT TRUE ...
+
+If all the salmon caught in Canada in one year were laid end to end
+across the Sahara Desert, the smell would be absolutely awful.
+%
+ AMAZING BUT TRUE ...
+
+There is so much sand in Northern Africa that if it were spread out it
+would completely cover the Sahara Desert.
+%
+Ambidextrous, adj.:
+ Able to pick with equal skill a right-hand pocket or a left.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Ambition is a poor excuse for not having sense enough to be lazy.
+ -- Charlie McCarthy
+%
+America may be unique in being a country which has leapt from barbarism
+to decadence without touching civilization.
+ -- John O'Hara
+%
+America was discovered by Amerigo Vespucci and was named after him,
+until people got tired of living in a place called "Vespuccia" and
+changed its name to "America".
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+American business long ago gave up on demanding that prospective
+employees be honest and hardworking. It has even stopped hoping for
+employees who are educated enough that they can tell the difference
+between the men's room and the women's room without having little
+pictures on the doors.
+ -- Dave Barry, "Urine Trouble, Mister"
+%
+"Amnesia used to be my favorite word, but then I forgot it."
+%
+An age is called Dark not because the light fails to shine, but because
+people refuse to see it.
+ -- James Michener, "Space"
+%
+An American's a person who isn't afraid to criticize the President but
+is always polite to traffic cops.
+%
+"An anthropologist at Tulane has just come back from a field trip to
+New Guinea with reports of a tribe so primitive that they have Tide but
+not new Tide with lemon-fresh Borax."
+ -- David Letterman
+%
+An apple every eight hours will keep three doctors away.
+%
+ An architect's first work is apt to be spare and clean. He
+knows he doesn't know what he's doing, so he does it carefully and with
+great restraint.
+ As he designs the first work, frill after frill and
+embellishment after embellishment occur to him. These get stored away
+to be used "next time". Sooner or later the first system is finished,
+and the architect, with firm confidence and a demonstrated mastery of
+that class of systems, is ready to build a second system.
+ This second is the most dangerous system a man ever designs.
+When he does his third and later ones, his prior experiences will
+confirm each other as to the general characteristics of such systems,
+and their differences will identify those parts of his experience that
+are particular and not generalizable.
+ The general tendency is to over-design the second system, using
+all the ideas and frills that were cautiously sidetracked on the first
+one. The result, as Ovid says, is a "big pile".
+ -- Frederick Brooks, "The Mythical Man Month"
+%
+An artist should be fit for the best society and keep out of it.
+%
+An attorney was defending his client against a charge of first-degree
+murder. "Your Honor, my client is accused of stuffing his lover's
+mutilated body into a suitcase and heading for the Mexican border.
+Just north of Tijuana a cop spotted her hand sticking out of the
+suitcase. Now, I would like to stress that my client is *not* a
+murderer. A sloppy packer, maybe..."
+%
+An authority is a person who can tell you more about something than you
+really care to know.
+%
+An effective way to deal with predators is to taste terrible.
+%
+An elephant is a mouse with an operating system.
+%
+An English judge, growing weary of the barrister's long-winded
+summation, leaned over the bench and remarked, "I've heard your
+arguments, Sir Geoffrey, and I'm none the wiser!" Sir Geoffrey
+responded, "That may be, Milord, but at least you're better informed!"
+%
+An Englishman never enjoys himself, except for a noble purpose.
+ -- A. P. Herbert
+%
+An excellence-oriented '80s male does not wear a regular watch. He
+wears a Rolex watch, because it weighs nearly six pounds and is
+advertised only in excellence-oriented publications such as Fortune and
+Rich Protestant Golfer Magazine. The advertisements are written in
+incomplete sentences, which is how advertising copywriters denote
+excellence:
+
+"The Rolex Hyperion. An elegant new standard in quality excellence and
+discriminating handcraftsmanship. For the individual who is truly able
+to discriminate with regard to excellent quality standards of crafting
+things by hand. Fabricated of 100 percent 24-karat gold. No watch
+parts or anything. Just a great big chunk on your wrist. Truly a
+timeless statement. For the individual who is very secure. Who
+doesn't need to be reminded all the time that he is very successful.
+Much more successful than the people who laughed at him in high
+school. Because of his acne. People who are probably nowhere near as
+successful as he is now. Maybe he'll go to his 20th reunion, and
+they'll see his Rolex Hyperion. Hahahahahahahahaha."
+ -- Dave Barry, "In Search of Excellence"
+%
+An exotic journey in downtown Newark is in your future.
+%
+"... an experienced, industrious, ambitious, and often quite often
+picturesque liar."
+ -- Mark Twain
+%
+An idea is an eye given by God for the seeing of God. Some of these
+eyes we cannot bear to look out of, we blind them as quickly as
+possible.
+ -- Russell Hoban, "Pilgermann"
+%
+An idea is not responsible for the people who believe in it.
+%
+ An old Jewish man reads about Einstein's theory of relativity
+in the newspaper and asks his scientist grandson to explain it to him.
+ "Well, zayda, it's sort of like this. Einstein says that if
+you're having your teeth drilled without Novocain, a minute seems like
+an hour. But if you're sitting with a beautiful woman on your lap, an
+hour seems like a minute."
+ The old man considers this profound bit of thinking for a
+moment and says, "And from this he makes a living?"
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+"An ounce of prevention is worth a pound of purge."
+%
+Anarchy may not be the best form of government, but it's better than no
+government at all.
+%
+And as we stand on the edge of darkness
+Let our chant fill the void
+That others may know
+
+ In the land of the night
+ The ship of the sun
+ Is drawn by
+ The grateful dead.
+
+ -- Tibetan "Book of the Dead," ca. 4000 BC.
+%
+... and furthermore ... I don't like your trousers.
+%
+And I heard Jeff exclaim,
+As they strolled out of sight,
+"Merry Christmas to all --
+You take credit cards, right?"
+ -- "Outsiders" comic
+%
+... And malt does more than Milton can
+To justify God's ways to man
+ -- A. E. Housman
+%
+And on the seventh day, He exited from append mode.
+%
+"... And remember: if you don't like the news, go out and make some of
+your own."
+ -- "Scoop" Nisker, KFOG radio reporter
+ Preposterous Words
+%
+And so, men, we can see that human skin is an even more complex and
+fascinating organ than we thought it was, and if we want to keep it
+looking good, we have to care for it as though it were our own. One
+approach is to undergo a painful surgical procedure wherein your skin
+is turned inside-out, so the young cells are on the outside, but then
+of course you have the unpleasant side effect that your insides
+gradually fill up with dead old cells and you explode. So this
+procedure is pretty much limited to top Hollywood stars for whom
+youthful beauty is a career necessity, such as Elizabeth Taylor and
+Orson Welles.
+ -- Dave Barry, "Saving Face"
+%
+"...and the fully armed nuclear warheads, are, of course, merely a
+courtesy detail."
+%
+And this is a table ma'am. What in essence it consists of is a
+horizontal rectilinear plane surface maintained by four vertical
+columnar supports, which we call legs. The tables in this laboratory,
+ma'am, are as advanced in design as one will find anywhere in the
+world.
+ -- Michael Frayn, "The Tin Men"
+%
+ "And what will you do when you grow up to be as big as me?"
+asked the father of his little son.
+ "Diet."
+%
+And yet, seasons must be taken with a grain of salt, for they too have
+a sense of humor, as does history. Corn stalks comedy, comedy stalks
+tragedy, and this too is historic. And yet, still, when corn meets
+tragedy face to face, we have politics.
+ -- Dalglish, Larsen and Sutherland, "Root Crops and
+ Ground Cover"
+%
+Andrea: Unhappy the land that has no heroes.
+Galileo: No, unhappy the land that _____needs heroes.
+ -- Bertolt Brecht, "Life of Galileo"
+%
+Angels we have heard on High
+Tell us to go out and Buy.
+ -- Tom Lehrer
+%
+Ankh if you love Isis.
+%
+Anoint, v.:
+ To grease a king or other great functionary already
+sufficiently slippery.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+ Another Glitch in the Call
+ ------- ------ -- --- ----
+ (Sung to the tune of a recent Pink Floyd song.)
+
+We don't need no indirection
+We don't need no flow control
+No data typing or declarations
+Did you leave the lists alone?
+
+ Hey! Hacker! Leave those lists alone!
+
+Chorus:
+ All in all, it's just a pure-LISP function call.
+ All in all, it's just a pure-LISP function call.
+%
+Another good night not to sleep in a eucalyptus tree.
+%
+Another possible source of guidance for teenagers is television, but
+television's message has always been that the need for truth, wisdom
+and world peace pales by comparison with the need for a toothpaste that
+offers whiter teeth *___and* fresher breath.
+ -- Dave Barry, "Kids Today: They Don't Know Dum Diddly
+ Do"
+%
+ Answers to Last Fortune's Questions:
+
+(1) None. (Moses didn't have an ark).
+(2) Your mother, by the pigeonhole principle.
+(3) I don't know.
+(4) Who cares?
+(5) 6 (or maybe 4, or else 3). Mr. Alfred J. Duncan of Podunk,
+ Montana, submitted an interesting solution to Problem 5.
+(6) There is an interesting solution to this problem on page 1029 of my
+ book, which you can pick up for $23.95 at finer bookstores and
+ bathroom supply outlets (or 99 cents at the table in front of
+ Papyrus Books).
+%
+Anthony's Law of Force:
+ Don't force it; get a larger hammer.
+%
+Anthony's Law of the Workshop:
+ Any tool when dropped, will roll into the least accessible
+ corner of the workshop.
+
+Corollary:
+ On the way to the corner, any dropped tool will first strike
+ your toes.
+%
+Antonym, n.:
+ The opposite of the word you're trying to think of.
+%
+Any clod can have the facts, but having an opinion is an art.
+ -- Charles McCabe
+%
+Any clod can have the facts, but having opinions is an art.
+ -- Charles McCabe
+%
+Any dramatic series the producers want us to take seriously as a
+representation of contemporary reality cannot be taken seriously as a
+representation of anything -- except a show to be ignored by anyone
+capable of sitting upright in a chair and chewing gum simultaneously.
+ -- Richard Schickel
+%
+Any excuse will serve a tyrant.
+ -- Aesop
+%
+Any father who thinks he's all important should remind himself that
+this country honors fathers only one day a year while pickles get a
+whole week.
+%
+Any fool can paint a picture, but it takes a wise person to be able to
+sell it.
+%
+Any great truth can -- and eventually will -- be expressed as a cliche
+-- a cliche is a sure and certain way to dilute an idea. For instance,
+my grandmother used to say, "The black cat is always the last one off
+the fence." I have no idea what she meant, but at one time, it was
+undoubtedly true.
+ -- Solomon Short
+%
+Any philosophy that can be put in a nutshell belongs there.
+ -- Sydney J. Harris
+%
+Any small object that is accidentally dropped will hide under a larger
+object.
+%
+Any stone in your boot always migrates against the pressure gradient to
+exactly the point of most pressure.
+ -- Milt Barber
+%
+Any sufficiently advanced bug is indistinguishable from a feature.
+ -- Rich Kulawiec
+%
+Any sufficiently advanced technology is indistinguishable from a rigged
+demo.
+%
+Any sufficiently advanced technology is indistinguishable from magic.
+ -- Arthur C. Clarke
+%
+Any time things appear to be going better, you have overlooked
+something.
+%
+Any two philosophers can tell each other all they know in two hours.
+ -- Oliver Wendell Holmes, Jr.
+%
+Anybody can win, unless there happens to be a second entry.
+%
+Anybody who doesn't cut his speed at the sight of a police car is
+probably parked.
+%
+Anybody with money to burn will easily find someone to tend the fire.
+%
+Anyone can do any amount of work provided it isn't the work he is
+supposed to be doing at the moment.
+ -- Robert Benchley
+%
+Anyone can hold the helm when the sea is calm.
+ -- Publilius Syrus
+%
+Anyone can make an omelet with eggs. The trick is to make one with
+none.
+%
+Anyone who cannot cope with mathematics is not fully human. At best he
+is a tolerable subhuman who has learned to wear shoes, bathe and not
+make messes in the house.
+ -- Lazarus Long, "Time Enough for Love"
+%
+Anyone who goes to a psychiatrist ought to have his head examined.
+ -- Samuel Goldwyn
+%
+Anyone who hates Dogs and Kids Can't be All Bad.
+ -- W. C. Fields
+%
+Anyone who is capable of getting themselves made President should on no
+account be allowed to do the job.
+ -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
+%
+Anyone who uses the phrase "easy as taking candy from a baby" has never
+tried taking candy from a baby.
+ -- Robin Hood
+%
+Anything free is worth what you pay for it.
+%
+Anything is good and useful if it's made of chocolate.
+%
+Anything is good if it's made of chocolate.
+%
+Anything labeled "NEW" and/or "IMPROVED" isn't. The label means the
+price went up. The label "ALL NEW", "COMPLETELY NEW", or "GREAT NEW"
+means the price went way up.
+%
+Anything that is good and useful is made of chocolate.
+%
+Anything worth doing is worth overdoing
+%
+"Apathy is not the problem, it's the solution"
+%
+Aphorism, n.:
+ A concise, clever statement.
+Afterism, n.:
+ A concise, clever statement you don't think of until too late.
+ -- James Alexander Thom
+%
+APL is a mistake, carried through to perfection. It is the language of
+the future for the problems of the past: it creates a new generation of
+coding bums.
+%
+"APL is a write-only language. I can write programs in APL, but I
+can't read any of them."
+ -- Roy Keir
+%
+Aquadextrous, adj.:
+ Possessing the ability to turn the bathtub faucet on and off
+with your toes.
+ -- Rich Hall, "Sniglets"
+%
+AQUARIUS (Jan 20 - Feb 18)
+ You have an inventive mind and are inclined to be progressive.
+ You lie a great deal. On the other hand, you are inclined to
+ be careless and impractical, causing you to make the same
+ mistakes over and over again. People think you are stupid.
+%
+Arbitrary systems, pl.n.:
+ Systems about which nothing general can be said, save "nothing
+general can be said."
+%
+ARCHDUKE FERDINAND FOUND ALIVE --
+ FIRST WORLD WAR A MISTAKE
+%
+Are you a turtle?
+%
+Are you a turtle?
+%
+"Arguments with furniture are rarely productive."
+ -- Kehlog Albran, "The Profit"
+%
+ARIES (Mar 21 - Apr 19)
+ You are the pioneer type and hold most people in contempt. You
+ are quick tempered, impatient, and scornful of advice. You are
+ not very nice.
+%
+Arithmetic is being able to count up to twenty without taking off your
+shoes.
+ -- Mickey Mouse
+%
+Armadillo:
+ To provide weapons to a Spanish pickle
+%
+Arnold's Laws of Documentation:
+ (1) If it should exist, it doesn't.
+ (2) If it does exist, it's out of date.
+ (3) Only documentation for useless programs transcends the
+ first two laws.
+%
+Around computers it is difficult to find the correct unit of time to
+measure progress. Some cathedrals took a century to complete. Can you
+imagine the grandeur and scope of a program that would take as long?
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+Art is anything you can get away with.
+ -- Marshall McLuhan.
+%
+Art is either plagiarism or revolution.
+ -- Paul Gauguin
+%
+Arthur's Laws of Love:
+ (1) People to whom you are attracted invariably think you
+ remind them of someone else.
+ (2) The love letter you finally got the courage to send will be
+ delayed in the mail long enough for you to make a fool of
+ yourself in person.
+%
+Artistic ventures highlighted. Rob a museum.
+%
+As a professional humorist, I often get letters from readers who are
+interested in the basic nature of humor. "What kind of a sick
+perverted disgusting person are you," these letters typically ask,
+"that you make jokes about setting fire to a goat?" ...
+ -- Dave Barry, "Why Humor is Funny"
+%
+"As an adolescent I aspired to lasting fame, I craved factual
+certainty, and I thirsted for a meaningful vision of human life -- so I
+became a scientist. This is like becoming an archbishop so you can
+meet girls."
+ -- Matt Cartmill
+%
+As far as the laws of mathematics refer to reality, they are not
+certain, and as far as they are certain, they do not refer to reality.
+ -- Albert Einstein
+%
+As far as we know, our computer has never had an undetected error.
+ -- Weisert
+%
+As I was going up Punch Card Hill,
+ Feeling worse and worser,
+There I met a C.R.T.
+ And it drop't me a cursor.
+
+C.R.T., C.R.T.,
+ Phosphors light on you!
+If I had fifty hours a day
+ I'd spend them all at you.
+
+ -- Uncle Colonel's Cursory Rhymes
+%
+As I was passing Project MAC,
+I met a Quux with seven hacks.
+Every hack had seven bugs;
+Every bug had seven manifestations;
+Every manifestation had seven symptoms.
+Symptoms, manifestations, bugs, and hacks,
+How many losses at Project MAC?
+%
+As long as I am mayor of this city [Jersey City, New Jersey] the great
+industries are secure. We hear about constitutional rights, free
+speech and the free press. Every time I hear these words I say to
+myself, "That man is a Red, that man is a Communist". You never hear a
+real American talk like that.
+ -- Frank Hague (1896-1956)
+%
+As long as the answer is right, who cares if the question is wrong?
+%
+As long as war is regarded as wicked, it will always have its
+fascination. When it is looked upon as vulgar, it will cease to be
+popular.
+ -- Oscar Wilde
+%
+As of next week, passwords will be entered in Morse code.
+%
+"As part of the conversion, computer specialists rewrote 1,500
+programs; a process that traditionally requires some debugging."
+ -- USA Today, referring to the IRS switchover to a new
+ computer system.
+%
+As soon as we started programming, we found to our surprise that it
+wasn't as easy to get programs right as we had thought. Debugging had
+to be discovered. I can remember the exact instant when I realized
+that a large part of my life from then on was going to be spent in
+finding mistakes in my own programs.
+ -- Maurice Wilkes discovers debugging, 1949
+%
+As the poet said, "Only God can make a tree" -- probably because it's
+so hard to figure out how to get the bark on.
+ -- Woody Allen
+%
+As the trials of life continue to take their toll, remember that there
+is always a future in Computer Maintenance.
+ -- National Lampoon, "Deteriorata"
+%
+As Will Rogers would have said, "There is no such things as a free
+variable."
+%
+As with most fine things, chocolate has its season. There is a simple
+memory aid that you can use to determine whether it is the correct time
+to order chocolate dishes: any month whose name contains the letter A,
+E, or U is the proper time for chocolate.
+ -- Sandra Boynton, "Chocolate: The Consuming Passion"
+%
+As you know, birds do not have sexual organs because they would
+interfere with flight. [In fact, this was the big breakthrough for the
+Wright Brothers. They were watching birds one day, trying to figure
+out how to get their crude machine to fly, when suddenly it dawned on
+Wilbur. "Orville," he said, "all we have to do is remove the sexual
+organs!" You should have seen their original design.] As a result,
+birds are very, very difficult to arouse sexually. You almost never
+see an aroused bird. So when they want to reproduce, birds fly up and
+stand on telephone lines, where they monitor telephone conversations
+with their feet. When they find a conversation in which people are
+talking dirty, they grip the line very tightly until they are both
+highly aroused, at which point the female gets pregnant.
+ -- Dave Barry, "Sex and the Single Amoeba: What Every
+ Teen Should Know"
+%
+As you reach for the web, a venomous spider appears. Unable to pull
+your hand away in time, the spider promptly, but politely, bites you.
+The venom takes affect quickly causing your lips to turn plaid along
+with your complexion. You become dazed, and in your stupor you fall
+from the limbs of the tree. Snap! Your head falls off and rolls all
+over the ground. The instant before you croak, you hear the whoosh of
+a vacuum being filled by the air surrounding your head. Worse yet, the
+spider is suing you for damages.
+%
+As Zeus said to Narcissus, "Watch yourself."
+%
+ASHes to ASHes, DOS to DOS.
+%
+Ask five economists and you'll get five different explanations (six if
+one went to Harvard).
+ -- Edgar R. Fiedler
+%
+Ask not for whom the <CONTROL-G> tolls.
+%
+Ask Not for whom the Bell Tolls, and You will Pay only the
+Station-to-Station rate.
+%
+Ask not for whom the telephone bell tolls ... if thou art in the
+bathtub, it tolls for thee.
+%
+Ask your boss to reconsider -- it's so difficult to take "Go to hell"
+for an answer.
+%
+"Asked by reporters about his upcoming marriage to a forty-two-year-old
+woman, director Roman Polanski told reporters, `The way I look at it,
+she's the equivalent of three fourteen-year-olds.'"
+ -- David Letterman
+%
+Ass, n.:
+ The masculine of "lass".
+%
+Associate with well-mannered persons and your manners will improve.
+Run with decent folk and your own decent instincts will be
+strengthened. Keep the company of bums and you will become a bum.
+Hang around with rich people and you will end by picking up the check
+and dying broke.
+ -- Stanley Walker
+%
+"At a recent meeting in Snowmass, Colorado, a participant from Los
+Angeles fainted from hyperoxygenation, and we had to hold his head
+under the exhaust of a bus until he revived."
+%
+At any given moment, an arrow must be either where it is or where it is
+not. But obviously it cannot be where it is not. And if it is where
+it is, that is equivalent to saying that it is at rest.
+ -- Zeno's paradox of the moving (still?) arrow
+%
+At Group L, Stoffel oversees six first-rate programmers, a managerial
+challenge roughly comparable to herding cats.
+ -- The Washington Post Magazine, 9 June, 1985
+%
+At Group L, Stoffel oversees six first-rate programmers, a managerial
+challenge roughly comparable to herding cats.
+ -- The Washington Post Magazine, June 9, 1985
+%
+... at least I thought I was dancing, 'til somebody stepped on my hand.
+ -- J. B. White
+%
+"At least they're ___________EXPERIENCED incompetents"
+%
+At no time is freedom of speech more precious than when a man hits his
+thumb with a hammer.
+ -- Marshall Lumsden
+%
+At the source of every error which is blamed on the computer you will
+find at least two human errors, including the error of blaming it on
+the computer.
+%
+Atlanta makes it against the law to tie a giraffe to a telephone pole
+or street lamp.
+%
+Atlee is a very modest man. And with reason.
+ -- Winston Churchill
+%
+Authors (and perhaps columnists) eventually rise to the top of whatever
+depths they were once able to plumb.
+ -- Stanley Kaufman
+%
+Automobile, n.:
+ A four-wheeled vehicle that runs up hills and down
+pedestrians.
+%
+Avoid Quiet and Placid persons unless you are in Need of Sleep.
+ -- National Lampoon, "Deteriorata"
+%
+Avoid reality at all costs.
+%
+"Avoid revolution or expect to get shot. Mother and I will grieve, but
+we will gladly buy a dinner for the National Guardsman who shot you."
+ -- Dr. Paul Williamson, father of a Kent State student
+%
+Bacchus, n.:
+ A convenient deity invented by the ancients as an excuse for
+getting drunk.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Bagbiter:
+ 1. n.; Equipment or program that fails, usually
+intermittently. 2. adj.: Failing hardware or software. "This
+bagbiting system won't let me get out of spacewar." Usage: verges on
+obscenity. Grammatically separable; one may speak of "biting the
+bag". Synonyms: LOSER, LOSING, CRETINOUS, BLETCHEROUS, BARFUCIOUS,
+CHOMPER, CHOMPING.
+%
+Bagdikian's Observation:
+ Trying to be a first-rate reporter on the average American
+newspaper is like trying to play Bach's "St. Matthew Passion" on a
+ukelele.
+%
+Baker's First Law of Federal Geometry:
+ A block grant is a solid mass of money surrounded on all sides
+by governors.
+%
+Ban the bomb. Save the world for conventional warfare.
+%
+Banectomy, n.:
+ The removal of bruises on a banana.
+ -- Rich Hall, "Sniglets"
+%
+Bank error in your favor. Collect $200.
+%
+Barach's Rule:
+ An alcoholic is a person who drinks more than his own
+physician.
+%
+Bare feet magnetize sharp metal objects so they point upward from the
+floor -- especially in the dark.
+%
+Barometer, n.:
+ An ingenious instrument which indicates what kind of weather we
+are having.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Barth's Distinction:
+ There are two types of people: those who divide people into two
+types, and those who don't.
+%
+Baruch's Observation:
+ If all you have is a hammer, everything looks like a nail.
+%
+Baseball is a skilled game. It's America's game -- it, and high
+taxes.
+ -- Will Rogers
+%
+Basic is a high level languish.
+APL is a high level anguish.
+%
+"BASIC is the Computer Science equivalent of `Scientific Creationism'."
+%
+Basic, n.:
+ A programming language. Related to certain social diseases in
+that those who have it will not admit it in polite company.
+%
+Bathquake, n.:
+ The violent quake that rattles the entire house when the water
+faucet is turned on to a certain point.
+ -- Rich Hall, "Sniglets"
+%
+Be a better psychiatrist and the world will beat a psychopath to your
+door.
+%
+BE ALERT!!!! (The world needs more lerts ...)
+%
+Be assured that a walk through the ocean of most Souls would scarcely
+get your Feet wet. Fall not in Love, therefore: it will stick to your
+face.
+ -- National Lampoon, "Deteriorata"
+%
+Be braver -- you can't cross a chasm in two small jumps.
+%
+Be careful of reading health books, you might die of a misprint.
+ -- Mark Twain
+%
+Be different: conform.
+%
+Be free and open and breezy! Enjoy! Things won't get any better so
+get used to it.
+%
+Be security conscious -- National defense is at stake.
+%
+Be wary of strong drink. It can make you shoot at tax collectors and
+miss
+ -- Lazarus Long, "Time Enough for Love"
+%
+Bees are very busy souls
+They have no time for birth controls
+And that is why in times like these
+There are so many Sons of Bees.
+%
+ Before he became a hermit, Zarathud was a young Priest, and
+took great delight in making fools of his opponents in front of his
+followers.
+ One day Zarathud took his students to a pleasant pasture and
+there he confronted The Sacred Chao while She was contentedly grazing.
+ "Tell me, you dumb beast," demanded the Priest in his
+commanding voice, "why don't you do something worthwhile? What is your
+Purpose in Life, anyway?"
+ Munching the tasty grass, The Sacred Chao replied "MU". (The
+Chinese ideogram for NO-THING.)
+ Upon hearing this, absolutely nobody was enlightened.
+ Primarily because nobody understood Chinese.
+ -- Camden Benares, "Zen Without Zen Masters"
+%
+Before Xerox, five carbons were the maximum extension of anybody's
+ego.
+%
+Begathon, n.:
+ A multi-day event on public television, used to raise money so
+you won't have to watch commercials.
+%
+Behold the warranty ... the bold print giveth and the fine print taketh
+away.
+%
+Beifeld's Principle:
+ The probability of a young man meeting a desirable and
+receptive young female increases by pyramidal progression when he is
+already in the company of: (1) a date, (2) his wife, (3) a better
+looking and richer male friend.
+%
+"Being disintegrated makes me ve-ry an-gry!" <huff, huff>
+%
+"Being disintegrated makes me ve-ry an-gry!" <huff, huff>
+%
+Bell Labs Unix -- Reach out and grep someone.
+%
+Bennett's Laws of Horticulture:
+ (1) Houses are for people to live in.
+ (2) Gardens are for plants to live in.
+ (3) There is no such thing as a houseplant.
+%
+"Benson, you are so free of the ravages of intelligence"
+ -- Time Bandits
+%
+Besides the device, the box should contain:
+
+* Eight little rectangular snippets of paper that say "WARNING"
+
+* A plastic packet containing four 5/17 inch pilfer grommets and two
+ club-ended 6/93 inch boxcar prawns.
+
+YOU WILL NEED TO SUPPLY: a matrix wrench and 60,000 feet of tram
+cable.
+
+IF ANYTHING IS DAMAGED OR MISSING: You IMMEDIATELY should turn to your
+spouse and say: "Margaret, you know why this country can't make a car
+that can get all the way through the drive-through at Burger King
+without a major transmission overhaul? Because nobody cares, that's
+why."
+
+WARNING: This is assuming your spouse's name is Margaret.
+ -- Dave Barry, "Read This First!"
+%
+Best of all is never to have been born. Second best is to die soon.
+%
+better !pout !cry
+better watchout
+lpr why
+santa claus <north pole >town
+
+cat /etc/passwd >list
+ncheck list
+ncheck list
+cat list | grep naughty >nogiftlist
+cat list | grep nice >giftlist
+santa claus <north pole > town
+
+who | grep sleeping
+who | grep awake
+who | egrep 'bad|good'
+for (goodness sake) {
+ be good
+}
+%
+Better dead than mellow.
+%
+Between 1950 and 1952, a bored weatherman, stationed north of Hudson
+Bay, left a monument that neither government nor time can eradicate.
+Using a bulldozer abandoned by the Air Force, he spent two years and
+great effort pushing boulders into a single word.
+
+It can be seen from 10,000 feet, silhouetted against the snow.
+Government officials exchanged memos full of circumlocutions (no Latin
+equivalent exists) but failed to word an appropriation bill for the
+destruction of this cairn, that wouldn't alert the press and embarrass
+both Parliament and Party.
+
+It stands today, a monument to human spirit. If life exists on other
+planets, this may be the first message received from us.
+ -- The Realist, November, 1964.
+%
+"Beware of bugs in the above code; I have only proved it correct, not
+tried it."
+ -- Donald Knuth
+%
+Beware of computerized fortune-tellers!
+%
+Beware of low-flying butterflies.
+%
+Beware of Programmers who carry screwdrivers.
+ -- Leonard Brandwein
+%
+Beware of self-styled experts: an ex is a has-been, and a spurt is a
+drip under pressure.
+%
+"Beware of the man who works hard to learn something, learns it, and
+finds himself no wiser than before," Bokonon tells us. "He is full of
+murderous resentment of people who are ignorant without having come by
+their ignorance the hard way."
+ -- Kurt Vonnegut, "Cat's Cradle"
+%
+Beware of the Turing Tar-pit in which everything is possible but
+nothing of interest is easy.
+%
+Binary, adj.:
+ Possessing the ability to have friends of both sexes.
+%
+"Biology is the only science in which multiplication means the same
+thing as division."
+%
+Bipolar, adj.:
+ Refers to someone who has homes in Nome, Alaska, and Buffalo,
+New York
+%
+Birth, n.:
+ The first and direst of all disasters.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Bizarreness is the essence of the exotic
+%
+Bizoos, n.:
+ The millions of tiny individual bumps that make up a
+basketball.
+ -- Rich Hall, "Sniglets"
+%
+... bleakness ... desolation ... plastic forks ...
+%
+Blessed are the young for they shall inherit the national debt.
+%
+Blessed are they who Go Around in Circles, for they Shall be Known as
+Wheels.
+%
+BLISS is ignorance
+%
+Blood flows down one leg and up the other.
+%
+Blood is thicker than water, and much tastier.
+%
+Blore's Razor:
+ Given a choice between two theories, take the one which is
+funnier.
+%
+Board the windows, up your car insurance, and don't leave any booze in
+plain sight. It's St. Patrick's day in Chicago again. The legend has
+it that St. Patrick drove the snakes out of Ireland. In fact, he was
+arrested for drunk driving. The snakes left because people kept
+throwing up on them.
+%
+Boling's postulate:
+ If you're feeling good, don't worry. You'll get over it.
+%
+Bolub's Fourth Law of Computerdom:
+ Project teams detest weekly progress reporting because it so
+vividly manifests their lack of progress.
+%
+Bombeck's Rule of Medicine:
+ Never go to a doctor whose office plants have died.
+%
+BOO! We changed Coke again! BLEAH! BLEAH!
+%
+Boob's Law:
+ You always find something in the last place you look.
+%
+Bore, n.:
+ A guy who wraps up a two-minute idea in a two-hour vocabulary.
+ -- Walter Winchell
+%
+Bore, n.:
+ A person who talks when you wish him to listen.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Boren's Laws:
+ (1) When in charge, ponder.
+ (2) When in trouble, delegate.
+ (3) When in doubt, mumble.
+%
+Boss, n.:
+ According to the Oxford English Dictionary, in the Middle Ages
+the words "boss" and "botch" were largely synonymous, except that boss,
+in addition to meaning "a supervisor of workers" also meant "an
+ornamental stud."
+%
+Boston State House is the hub of the Solar System. You couldn't pry
+that out of a Boston man if you had the tire of all creation
+straightened out for a crowbar.
+ -- O. W. Holmes
+%
+Boston, n.:
+ Ludwig van Beethoven being jeered by 50,000 sports fans for
+finishing second in the Irish jig competition.
+%
+"Boy, life takes a long time to live
+ -- Steven Wright
+%
+Boy, n.:
+ A noise with dirt on it.
+%
+Boys are beyond the range of anybody's sure understanding, at least
+when they are between the ages of 18 months and 90 years.
+ -- James Thurber
+%
+Boys will be boys, and so will a lot of middle-aged men.
+ -- Kin Hubbard
+%
+Brace yourselves. We're about to try something that borders on the
+unique: an actually rather serious technical book which is not only
+(gasp) vehemently anti-Solemn, but also (shudder) takes sides. I tend
+to think of it as `Constructive Snottiness.'
+ -- Mike Padlipsky, Foreword to "Elements of Networking
+ Style"
+%
+Bradley's Bromide:
+ If computers get too powerful, we can organize them into a
+committee -- that will do them in.
+%
+Brady's First Law of Problem Solving:
+ When confronted by a difficult problem, you can solve it more
+easily by reducing it to the question, "How would the Lone Ranger have
+handled this?"
+%
+Brain fried -- Core dumped
+%
+Brain, n.:
+ The apparatus with which we think that we think.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Brain, v. [as in "to brain"]:
+ To rebuke bluntly, but not pointedly; to dispel a source of
+error in an opponent.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Breast Feeding should not be attempted by fathers with hairy chests,
+since they can make the baby sneeze and give it wind.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+Bride, n.:
+ A woman with a fine prospect of happiness behind her.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Bringing computers into the home won't change either one, but may
+revitalize the corner saloon.
+%
+British Israelites:
+ The British Israelites believe the white Anglo-Saxons of
+Britain to be descended from the ten lost tribes of Israel deported by
+Sargon of Assyria on the fall of Sumeria in 721 B.C. ... They further
+believe that the future can be foretold by the measurements of the
+Great Pyramid, which probably means it will be big and yellow and in
+the hand of the Arabs. They also believe that if you sleep with your
+head under the pillow a fairy will come and take all your teeth.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+Broad-mindedness, n.:
+ The result of flattening high-mindedness out.
+%
+Brontosaurus Principle:
+ Organizations can grow faster than their brains can manage them
+in relation to their environment and to their own physiology: when
+this occurs, they are an endangered species.
+ -- Thomas K. Connellan
+%
+Brook's Law:
+ Adding manpower to a late software project makes it later
+%
+Brooke's Law:
+ Whenever a system becomes completely defined, some damn fool
+discovers something which either abolishes the system or expands it
+beyond recognition.
+%
+Bubble Memory, n.:
+ A derogatory term, usually referring to a person's
+intelligence. See also "vacuum tube".
+%
+Bucy's Law:
+ Nothing is ever accomplished by a reasonable man.
+%
+Bug, n.:
+ An aspect of a computer program which exists because the
+programmer was thinking about Jumbo Jacks or stock options when s/he
+wrote the program.
+
+Fortunately, the second-to-last bug has just been fixed.
+ -- Ray Simard
+%
+Bugs, pl. n.:
+ Small living things that small living boys throw on small
+living girls.
+%
+BULLWINKLE: "You just leave that to my pal. He's the brains of the
+ outfit."
+GENERAL: "What does that make YOU?"
+BULLWINKLE: "What else? An executive..."
+ -- Jay Ward
+%
+Bumper sticker:
+
+"All the parts falling off this car are of the very finest British
+manufacture"
+%
+Bureaucrat, n.:
+ A person who cuts red tape sideways.
+ -- J. McCabe
+%
+Bureaucrat, n.:
+ A politician who has tenure.
+%
+Bureaucrats cut red tape -- lengthwise.
+%
+Burn's Hog Weighing Method:
+ (1) Get a perfectly symmetrical plank and balance it across a
+ sawhorse.
+ (2) Put the hog on one end of the plank.
+ (3) Pile rocks on the other end until the plank is again
+ perfectly balanced.
+ (4) Carefully guess the weight of the rocks.
+ -- Robert Burns
+%
+ ... But among the children of the Great Society there were
+those whose skins were black. And lo! Their portion was niggardly,
+and of the fatted calf they were sucking hind teat ...
+ Now it came to pass that a prophet rose up amongst them, and
+they called him King. And he went unto Pharaoh and said, "Let my
+people go to the front of the bus."
+ But Pharaoh answered: "In the fullness of time and with all
+deliberate speed shall this thing come to pass. When ye shall prove
+yourselves worthy, shall ye have your just portion -- yea, verily, like
+unto a snowball in Hell."
+ -- "The Begatting of a President"
+%
+... But as records of courts and justice are admissible, it can
+easily be proved that powerful and malevolent magicians once existed
+and were a scourge to mankind. The evidence (including confession)
+upon which certain women were convicted of witchcraft and executed was
+without a flaw; it is still unimpeachable. The judges' decisions based
+on it were sound in logic and in law. Nothing in any existing court
+was ever more thoroughly proved than the charges of witchcraft and
+sorcery for which so many suffered death. If there were no witches,
+human testimony and human reason are alike destitute of value.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+"But don't you worry, its for a cause -- feeding global corporations
+paws."
+%
+"But I don't like Spam!!!!"
+%
+... But if we laugh with derision, we will never understand. Human
+intellectual capacity has not altered for thousands of years so far as
+we can tell. If intelligent people invested intense energy in issues
+that now seem foolish to us, then the failure lies in our understanding
+of their world, not in their distorted perceptions. Even the standard
+example of ancient nonsense -- the debate about angels on pinheads --
+makes sense once you realize that theologians were not discussing
+whether five or eighteen would fit, but whether a pin could house a
+finite or an infinite number.
+ -- S. J. Gould, "Wide Hats and Narrow Minds"
+%
+But in our enthusiasm, we could not resist a radical overhaul of the
+system, in which all of its major weaknesses have been exposed,
+analyzed, and replaced with new weaknesses.
+ -- Bruce Leverett, "Register Allocation in Optimizing
+ Compilers"
+%
+"But officer, I was only trying to gain enough speed so I could coast
+to the nearest gas station."
+%
+But scientists, who ought to know
+Assure us that it must be so.
+Oh, let us never, never doubt
+What nobody is sure about.
+ -- Hilaire Belloc
+%
+But soft you, the fair Ophelia:
+Ope not thy ponderous and marble jaws,
+But get thee to a nunnery -- go!
+ -- Mark "The Bard" Twain
+%
+But the greatest Electrical Pioneer of them all was Thomas Edison, who
+was a brilliant inventor despite the fact that he had little formal
+education and lived in New Jersey. Edison's first major invention in
+1877, was the phonograph, which could soon be found in thousands of
+American homes, where it basically sat until 1923, when the record was
+invented. But Edison's greatest achievement came in 1879, when he
+invented the electric company. Edison's design was a brilliant
+adaptation of the simple electrical circuit: the electric company sends
+electricity through a wire to a customer, then immediately gets the
+electricity back through another wire, then (this is the brilliant
+part) sends it right back to the customer again.
+
+This means that an electric company can sell a customer the same batch
+of electricity thousands of times a day and never get caught, since
+very few customers take the time to examine their electricity closely.
+In fact the last year any new electricity was generated in the United
+States was 1937; the electric companies have been merely re-selling it
+ever since, which is why they have so much free time to apply for rate
+increases.
+ -- Dave Barry, "What is Electricity?"
+%
+"But this has taken us far afield from interface, which is not a bad
+place to be, since I particularly want to move ahead to the kludge.
+Why do people have so much trouble understanding the kludge? What is a
+kludge, after all, but not enough Ks, not enough ROMs, not enough RAMs,
+poor quality interface and too few bytes to go around? Have I
+explained yet about the bytes?"
+%
+... But we've only fondled the surface of that subject.
+ -- Virginia Masters
+%
+"But what we need to know is, do people want nasally-insertable
+computers?"
+%
+Buzz off, Banana Nose; Relieve mine eyes
+Of hateful soreness, purge mine ears of corn;
+Less dear than army ants in apple pies
+Art thou, old prune-face, with thy chestnuts worn,
+Dropt from thy peeling lips like lousy fruit;
+Like honeybees upon the perfum'd rose
+They suck, and like the double-breasted suit
+Are out of date; therefore, Banana Nose,
+Go fly a kite, thy welcome's overstayed;
+And stem the produce of thy waspish wits:
+Thy logick, like thy locks, is disarrayed;
+Thy cheer, like thy complexion, is the pits.
+Be off, I say; go bug somebody new,
+Scram, beat it, get thee hence, and nuts to you.
+%
+By doing just a little every day, you can gradually let the task
+completely overwhelm you.
+%
+"By necessity, by proclivity, and by delight, we all quote. In fact,
+it is as difficult to appropriate the thoughts of others as it is to
+invent. (R. Emerson)"
+ -- Quoted from a fortune cookie program
+ (whose author claims, "Actually, stealing IS easier.")
+ [to which I reply, "You think it's easy for me to
+ misconstrue all these misquotations?!?"]
+%
+"By the time they had diminished from 50 to 8, the other dwarves began
+to suspect 'Hungry' ..."
+ -- Gary Larson, "The Far Side"
+%
+By trying, we can easily learn to endure adversity -- another man's, I
+mean.
+ -- Mark Twain
+%
+Bypasses are devices that allow some people to dash from point A to
+point B very fast while other people dash from point B to point A very
+fast. People living at point C, being a point directly in between, are
+often given to wonder what's so great about point A that so many people
+from point B are so keen to get there and what's so great about point B
+that so many people from point A are so keen to get _____there. They often
+wish that people would just once and for all work out where the hell
+they wanted to be.
+ -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
+%
+C, n.:
+ A programming language that is sort of like Pascal except more
+like assembly except that it isn't very much like either one, or
+anything else. It is either the best language available to the art
+today, or it isn't.
+ -- Ray Simard
+%
+Cabbage, n.:
+ A familiar kitchen-garden vegetable about as large and wise as
+a man's head.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+"Cable is not a luxury, since many areas have poor TV reception."
+ -- The mayor of Tucson, Arizona, 1989
+%
+Cahn's Axiom:
+ When all else fails, read the instructions.
+%
+California is a fine place to live -- if you happen to be an orange.
+ -- Fred Allen
+%
+California, n.:
+ From Latin "calor", meaning "heat" (as in English "calorie" or
+Spanish "caliente"); and "fornia'" for "sexual intercourse" or
+"fornication." Hence: Tierra de California, "the land of hot sex."
+ -- Ed Moran
+%
+Call on God, but row away from the rocks.
+ -- Indian proverb
+%
+"Calling J-Man Kink. Calling J-Man Kink. Hash missile sighted, target
+Los Angeles. Disregard personal feelings about city and intercept."
+%
+"Calvin Coolidge looks as if he had been weaned on a pickle."
+ -- Alice Roosevelt Longworth
+%
+"Calvin Coolidge was the greatest man who ever came out of Plymouth
+Corner, Vermont."
+ -- Clarence Darrow
+%
+Campus sidewalks never exist as the straightest line between two
+points.
+ -- M. M. Johnston
+%
+Canada Bill Jone's Motto:
+ It's morally wrong to allow suckers to keep their money.
+
+Supplement:
+ A .44 magnum beats four aces.
+%
+Canada Post doesn't really charge 32 cents for a stamp. It's 2 cents
+for postage and 30 cents for storage.
+ -- Gerald Regan, Cabinet Minister, 12/31/83 Financial
+ Post
+%
+Cancel me not -- for what then shall remain?
+Abscissas, some mantissas, modules, modes,
+A root or two, a torus and a node:
+The inverse of my verse, a null domain.
+ -- Stanislaw Lem, "Cyberiad"
+%
+CANCER (June 21 - July 22)
+ You are sympathetic and understanding to other people's
+problems. They think you are a sucker. You are always putting things
+off. That's why you'll never make anything of yourself. Most welfare
+recipients are Cancer people.
+%
+Canonical, adj.:
+ The usual or standard state or manner of something. A true
+story: One Bob Sjoberg, new at the MIT AI Lab, expressed some
+annoyance at the use of jargon. Over his loud objections, we made a
+point of using jargon as much as possible in his presence, and
+eventually it began to sink in. Finally, in one conversation, he used
+the word "canonical" in jargon-like fashion without thinking.
+ Steele: "Aha! We've finally got you talking jargon too!"
+ Stallman: "What did he say?"
+ Steele: "He just used `canonical' in the canonical way."
+%
+CAPRICORN (Dec 23 - Jan 19)
+ You are conservative and afraid of taking risks. You don't do
+much of anything and are lazy. There has never been a Capricorn of any
+importance. Capricorns should avoid standing still for too long as
+they take root and become trees.
+%
+Captain Penny's Law:
+ You can fool all of the people some of the time, and some of
+the people all of the time, but you Can't Fool Mom.
+%
+Carelessly planned projects take three times longer to complete than
+expected. Carefully planned projects take four times longer to
+complete than expected, mostly because the planners expect their
+planning to reduce the time it takes.
+%
+Carmel, New York, has an ordinance forbidding men to wear coats and
+trousers that don't match.
+%
+Carperpetuation (kar' pur pet u a shun), n.:
+ The act, when vacuuming, of running over a string at least a
+dozen times, reaching over and picking it up, examining it, then
+putting it back down to give the vacuum one more chance.
+ -- Rich Hall, "Sniglets"
+%
+Cat, n.:
+ Lapwarmer with built-in buzzer.
+%
+Cauliflower is nothing but Cabbage with a College Education.
+ -- Mark Twain
+%
+Caution: breathing may be hazardous to your health.
+%
+CChheecckk yyoouurr dduupplleexx sswwiittcchh..
+%
+Cecil, you're my final hope
+Of finding out the true Straight Dope
+For I have been reading of Schrodinger's cat
+But none of my cats are at all like that.
+This unusual animal (so it is said)
+Is simultaneously alive and dead!
+What I don't understand is just why he
+Can't be one or the other, unquestionably.
+My future now hangs in between eigenstates.
+In one I'm enlightened, in the other I ain't.
+If *you* understand, Cecil, then show me the way
+And rescue my psyche from quantum decay.
+But if this queer thing has perplexed even you,
+Then I will *___and* I won't see you in Schrodinger's zoo.
+ -- Randy F., Chicago, "The Straight Dope, a compendium
+ of human knowledge" by Cecil Adams
+%
+Celebrate Hannibal Day this year. Take an elephant to lunch.
+%
+Celestial navigation is based on the premise that the Earth is the
+center of the universe. The premise is wrong, but the navigation
+works. An incorrect model can be a useful tool.
+ -- Kelvin Throop III
+%
+Census Taker to Housewife: Did you ever have the measles, and, if so,
+how many?
+%
+Cerebus: I'd love to lick apricot brandy out of your navel.
+Jaka: Look, Cerebus-- Jaka has to tell you ... something
+Cerebus: If Cerebus had a navel, would you lick apricot brandy
+ out of it?
+Jaka: Ugh!
+Cerebus: You don't like apricot brandy?
+ -- Cerebus #6, "The Secret"
+%
+Certain old men prefer to rise at dawn, taking a cold bath and a long
+walk with an empty stomach and otherwise mortifying the flesh. They
+then point with pride to these practices as the cause of their sturdy
+health and ripe years; the truth being that they are hearty and old,
+not because of their habits, but in spite of them. The reason we find
+only robust persons doing this thing is that it has killed all the
+others who have tried it.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Certainly there are things in life that money can't buy, but it's very funny--
+ Did you ever try buying them without money?
+ -- Ogden Nash
+%
+ Chapter 1
+
+The story so far:
+
+ In the beginning the Universe was created. This has made a lot
+of people very angry and been widely regarded as a bad move.
+%
+Character Density, n.:
+ The number of very weird people in the office.
+%
+Checkuary, n.:
+ The thirteenth month of the year. Begins New Year's Day and
+ends when a person stops absentmindedly writing the old year on his
+checks.
+%
+Chef, n.:
+ Any cook who swears in French.
+%
+Chemicals, n.:
+ Noxious substances from which modern foods are made.
+%
+Chemistry is applied theology.
+ -- Augustus Stanley Owsley III
+%
+Chicago law prohibits eating in a place that is on fire.
+%
+Chicago Transit Authority Rider's Rule #36:
+ Never ever ask the tough looking gentleman wearing El Rukn
+headgear where he got his "pyramid powered pizza warmer".
+ -- Chicago Reader 3/27/81
+%
+Chicago Transit Authority Rider's Rule #84:
+ The CTA has complimentary pop-up timers available on request
+for overheated passengers. When your timer pops up, the driver will
+cheerfully baste you.
+ -- Chicago Reader 5/28/82
+%
+Chicago, n.:
+ Where the dead still vote ... early and often!
+%
+Chicken Little only has to be right once.
+%
+Chicken Little was right.
+%
+Chicken Soup, n.:
+ An ancient miracle drug containing equal parts of aureomycin,
+cocaine, interferon, and TLC. The only ailment chicken soup can't cure
+is neurotic dependence on one's mother.
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+Children are natural mimic who act like their parents despite every
+effort to teach them good manners.
+%
+Children are unpredictable. You never know what inconsistency they're
+going to catch you in next.
+ -- Franklin P. Jones
+%
+Children aren't happy without something to ignore,
+And that's what parents were created for.
+ -- Ogden Nash
+%
+Children seldom misquote you. In fact, they usually repeat word for
+word what you shouldn't have said.
+%
+Chism's Law of Completion:
+ The amount of time required to complete a government project is
+precisely equal to the length of time already spent on it.
+%
+Chisolm's First Corollary to Murphy's Second Law:
+ When things just can't possibly get any worse, they will.
+%
+Chivalry, Schmivalry!
+ Roger the thief has a
+ method he uses for
+ sneaky attacks:
+Folks who are reading are
+ Characteristically
+ Always Forgetting to
+ Guard their own bac ...
+%
+Christ:
+ A man who was born at least 5,000 years ahead of his time.
+%
+Churchill's Commentary on Man:
+ Man will occasionally stumble over the truth, but most of the
+time he will pick himself up and continue on.
+%
+Cigarette, n.:
+ A fire at one end, a fool at the other, and a bit of tobacco in
+between.
+%
+Cinemuck, n.:
+ The combination of popcorn, soda, and melted chocolate which
+covers the floors of movie theaters.
+ -- Rich Hall, "Sniglets"
+%
+Clairvoyant, n.:
+ A person, commonly a woman, who has the power of seeing that
+which is invisible to her patron -- namely, that he is a blockhead.
+ -- Ambrose Bierce
+%
+Cleaning your house while your kids are still growing is like
+shoveling the walk before it stops snowing.
+ -- Phyllis Diller
+%
+Cleanliness is next to impossible.
+%
+Cleveland still lives. God ____must be dead.
+%
+"Cleveland? Yes, I spent a week there one day."
+%
+Cloning is the sincerest form of flattery.
+%
+Clothes make the man. Naked people have little or no influence on
+society.
+ -- Mark Twain
+%
+COBOL programs are an exercise in Artificial Inelegance.
+%
+Cocaine -- the thinking man's Dristan.
+%
+Cogito cogito ergo cogito sum --
+"I think that I think, therefore I think that I am."
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+"Cogito ergo I'm right and you're wrong."
+ -- Blair Houghton
+%
+Coincidence, n.:
+ You weren't paying attention to the other half of what was
+going on.
+%
+Coincidences are spiritual puns.
+ -- G. K. Chesterton
+%
+Cold, adj.:
+ When the local flashers are handing out written descriptions.
+%
+Cold, adj.:
+ When the politicians walk around with their hands in their own
+pockets.
+%
+Collaboration, n.:
+ A literary partnership based on the false assumption that the
+other fellow can spell.
+%
+College football is a game which would be much more interesting if the
+faculty played instead of the students, and even more interesting if
+the trustees played. There would be a great increase in broken arms,
+legs, and necks, and simultaneously an appreciable diminution in the
+loss to humanity.
+ -- H. L. Mencken
+%
+Colvard's Logical Premises:
+ All probabilities are 50%. Either a thing will happen or it
+ won't.
+
+Colvard's Unconscionable Commentary:
+ This is especially true when dealing with someone you're
+ attracted to.
+
+Grelb's Commentary
+ Likelihoods, however, are 90% against you.
+%
+Come, every frustum longs to be a cone,
+And every vector dreams of matrices.
+Hark to the gentle gradient of the breeze:
+It whispers of a more ergodic zone.
+ -- Stanislaw Lem, "Cyberiad"
+%
+Come, let us hasten to a higher plane,
+Where dyads tread the fairy fields of Venn,
+Their indices bedecked from one to _n,
+Commingled in an endless Markov chain!
+ -- Stanislaw Lem, "Cyberiad"
+%
+Command, n.:
+ Statement presented by a human and accepted by a computer in
+such a manner as to make the human feel as if he is in control.
+%
+ COMMENT
+
+Oh, life is a glorious cycle of song,
+A medley of extemporanea;
+And love is thing that can never go wrong;
+And I am Marie of Roumania.
+ -- Dorothy Parker
+%
+Commitment, n.:
+ Commitment can be illustrated by a breakfast of ham and eggs.
+The chicken was involved, the pig was committed.
+%
+Committee Rules:
+ (1) Never arrive on time, or you will be stamped a beginner.
+ (2) Don't say anything until the meeting is half over; this
+ stamps you as being wise.
+ (3) Be as vague as possible; this prevents irritating the
+ others.
+ (4) When in doubt, suggest that a subcommittee be appointed.
+ (5) Be the first to move for adjournment; this will make you
+ popular -- it's what everyone is waiting for.
+%
+Committee, n.:
+ A group of men who individually can do nothing but as a group
+decide that nothing can be done.
+ -- Fred Allen
+%
+Committees have become so important nowadays that subcommittees have to
+be appointed to do the work.
+%
+Common sense and a sense of humor are the same thing, moving at
+different speeds. A sense of humor is just common sense, dancing.
+ -- Clive James
+%
+Common sense is instinct, and enough of it is genius.
+ -- Josh Billings
+%
+Common sense is the collection of prejudices acquired by age eighteen.
+ -- Albert Einstein
+%
+Comparing information and knowledge is like asking whether the fatness
+of a pig is more or less green than the designated hitter rule."
+ -- David Guaspari
+%
+Computer programmers do it byte by byte
+%
+Computer Science is merely the post-Turing decline in formal systems
+theory.
+%
+Computers are not intelligent. They only think they are.
+%
+Computers are useless. They can only give you answers.
+ -- Pablo Picasso
+%
+Computers can figure out all kinds of problems, except the things in
+the world that just don't add up.
+%
+Computers will not be perfected until they can compute how much more
+than the estimate the job will cost.
+%
+Conceit causes more conversation than wit.
+ -- LaRouchefoucauld
+%
+Concept, n.:
+ Any "idea" for which an outside consultant billed you more than
+$25,000.
+%
+... [concerning quotation marks] even if we *___did* quote anybody in this
+business, it probably would be gibberish.
+ -- Thom McLeod
+%
+Condense soup, not books!
+%
+Confession is good for the soul only in the sense that a tweed coat is
+good for dandruff.
+ -- Peter de Vries
+%
+Confidence is the feeling you have before you understand the
+situation.
+%
+Congratulations! You have purchased an extremely fine device that
+would give you thousands of years of trouble-free service, except that
+you undoubtably will destroy it via some typical bonehead consumer
+maneuver. Which is why we ask you to PLEASE FOR GOD'S SAKE READ THIS
+OWNER'S MANUAL CAREFULLY BEFORE YOU UNPACK THE DEVICE. YOU ALREADY
+UNPACKED IT, DIDN'T YOU? YOU UNPACKED IT AND PLUGGED IT IN AND TURNED
+IT ON AND FIDDLED WITH THE KNOBS, AND NOW YOUR CHILD, THE SAME CHILD
+WHO ONCE SHOVED A POLISH SAUSAGE INTO YOUR VIDEOCASSETTE RECORDER AND
+SET IT ON "FAST FORWARD", THIS CHILD ALSO IS FIDDLING WITH THE KNOBS,
+RIGHT? AND YOU'RE JUST NOW STARTING TO READ THE INSTRUCTIONS,
+RIGHT??? WE MIGHT AS WELL JUST BREAK THESE DEVICES RIGHT AT THE
+FACTORY BEFORE WE SHIP THEM OUT, YOU KNOW THAT?
+ -- Dave Barry, "Read This First!"
+%
+Connector Conspiracy, n:
+ [probably came into prominence with the appearance of the
+KL-10, none of whose connectors match anything else] The tendency of
+manufacturers (or, by extension, programmers or purveyors of anything)
+to come up with new products which don't fit together with the old
+stuff, thereby making you buy either all new stuff or expensive
+interface devices.
+%
+Conscience is a mother-in-law whose visit never ends.
+ -- H. L. Mencken
+%
+Conscience is the inner voice that warns us somebody is looking
+ -- H. L. Mencken
+%
+Conscience is what hurts when everything else feels so good.
+%
+Conscious is when you are aware of something and conscience is when you
+wish you weren't.
+%
+"Consequences, Schmonsequences, as long as I'm rich."
+ -- "Ali Baba Bunny" [1957, Chuck Jones]
+%
+Consultants are mystical people who ask a company for a number and then
+give it back to them.
+%
+"Contrariwise," continued Tweedledee, "if it was so, it might be, and
+if it were so, it would be; but as it isn't, it ain't. That's logic!"
+ -- Lewis Carroll, "Through the Looking Glass"
+%
+"Contrary to popular belief, penguins are not the salvation of modern
+technology. Neither do they throw parties for the urban proletariat."
+%
+Conversation, n.:
+ A vocal competition in which the one who is catching his breath
+is called the listener.
+%
+Conway's Law:
+ In any organization there will always be one person who knows
+ what is going on.
+
+ This person must be fired.
+%
+Coronation, n.:
+ The ceremony of investing a sovereign with the outward and
+visible signs of his divine right to be blown skyhigh with a dynamite
+bomb.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Corrupt, adj.:
+ In politics, holding an office of trust or profit.
+%
+Corrupt, stupid grasping functionaries will make at least as big a
+muddle of socialism as stupid, selfish and acquisitive employers can
+make of capitalism.
+ -- Walter Lippmann
+%
+Corruption is not the #1 priority of the Police Commissioner. His job
+is to enforce the law and fight crime.
+ -- P.B.A. President E. J. Kiernan
+%
+Court, n.:
+ A place where they dispense with justice.
+ -- Arthur Train
+%
+Coward, n.:
+ One who in a perilous emergency thinks with his legs.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Crash programs fail because they are based on the theory that, with
+nine women pregnant, you can get a baby a month.
+ -- Wernher von Braun
+%
+Crime does not pay ... as well as politics.
+ -- A. E. Newman
+%
+Critic, n.:
+ A person who boasts himself hard to please because nobody tries
+to please him.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Croll's Query:
+ If tin whistles are made of tin, what are foghorns made of?
+%
+cursor address, n:
+ "Hello, cursor!"
+ -- Stan Kelly-Bootle, "The Devil's DP Dictionary"
+%
+"Cutting the space budget really restores my faith in humanity. It
+eliminates dreams, goals, and ideals and lets us get straight to the
+business of hate, debauchery, and self-annihilation."
+ -- Johnny Hart
+%
+"Cutting the space budget really restores my faith in humanity. It
+eliminates dreams, goals, and ideals and lets us get straight to the
+business of hate, debauchery, and self-annihilation."
+ -- Johnny Hart
+%
+Cynic, n.:
+ A blackguard whose faulty vision sees things as they are, not
+as they ought to be. Hence the custom among the Scythians of plucking
+out a cynic's eyes to improve his vision.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Cynic, n.:
+ One who looks through rose-colored glasses with a jaundiced
+eye.
+%
+Dare to be naive.
+ -- R. Buckminster Fuller
+%
+Darth Vader sleeps with a Teddywookie.
+%
+Dave Mack: "Your stupidity, Allen, is simply not up to par."
+Allen Gwinn: "Yours is."
+%
+Dawn, n.:
+ The time when men of reason go to bed.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Day of inquiry. You will be subpoenaed.
+%
+%DCL-MEM-BAD, bad memory
+VMS-F-PDGERS, pudding between the ears
+%
+Dealing with failure is easy: work hard to improve. Success is also
+easy to handle: you've solved the wrong problem. Work hard to
+improve.
+%
+Dear Lord:
+ I just want *___one* one-armed manager so I never have to hear "On
+the other hand", again.
+%
+Dear Miss Manners:
+ My home economics teacher says that one must never place one's
+elbows on the table. However, I have read that one elbow, in between
+courses, is all right. Which is correct?
+
+Gentle Reader:
+ For the purpose of answering examinations in your home
+economics class, your teacher is correct. Catching on to this
+principle of education may be of even greater importance to you now
+than learning correct current table manners, vital as Miss Manners
+believes that is.
+%
+Dear Miss Manners:
+ Please list some tactful ways of removing a man's saliva from
+your face.
+
+Gentle Reader:
+ Please list some decent ways of acquiring a man's saliva on
+your face ...
+%
+Dear Mister Language Person: I am curious about the expression, "Part
+of this complete breakfast". The way it comes up is, my 5-year-old
+will be watching TV cartoon shows in the morning, and they'll show a
+commercial for a children's compressed breakfast compound such as
+"Froot Loops" or "Lucky Charms", and they always show it sitting on a
+table next to some actual food such as eggs, and the announcer always
+says: "Part of this complete breakfast". Don't that really mean,
+"Adjacent to this complete breakfast", or "On the same table as this
+complete breakfast"? And couldn't they make essentially the same claim
+if, instead of Froot Loops, they put a can of shaving cream there, or a
+dead bat?
+
+Answer: Yes.
+ -- Dave Barry, "Tips for Writer's"
+%
+Dear Mister Language Person: What is the purpose of the apostrophe?
+
+Answer: The apostrophe is used mainly in hand-lettered small business
+signs to alert the reader than an "S" is coming up at the end of a
+word, as in: WE DO NOT EXCEPT PERSONAL CHECK'S, or: NOT RESPONSIBLE FOR
+ANY ITEM'S. Another important grammar concept to bear in mind when
+creating hand- lettered small-business signs is that you should put
+quotation marks around random words for decoration, as in "TRY" OUR HOT
+DOG'S, or even TRY "OUR" HOT DOG'S.
+ -- Dave Barry, "Tips for Writer's"
+%
+Death is God's way of telling you not to be such a wise guy.
+%
+Death is life's way of telling you you've been fired.
+ -- R. Geis
+%
+Death is Nature's way of recycling human beings.
+%
+"Death is nature's way of saying `Howdy'".
+%
+Death is nature's way of telling you to slow down
+%
+Death is only a state of mind.
+
+Only it doesn't leave you much time to think about anything else.
+%
+Death to all fanatics!
+%
+Decision maker, n.:
+ The person in your office who was unable to form a task force
+before the music stopped.
+%
+Decisions of the judges will be final unless shouted down by a really
+overwhelming majority of the crowd present. Abusive and obscene
+language may not be used by contestants when addressing members of the
+judging panel, or, conversely, by members of the judging panel when
+addressing contestants (unless struck by a boomerang).
+ -- Mudgeeraba Creek Emu-Riding and Boomerang-Throwing
+ Assoc.
+%
+ Deck Us All With Boston Charlie
+
+Deck us all with Boston Charlie,
+Walla Walla, Wash., an' Kalamazoo!
+Nora's freezin' on the trolley,
+Swaller dollar cauliflower, alleygaroo!
+
+Don't we know archaic barrel,
+Lullaby Lilla Boy, Louisville Lou.
+Trolley Molly don't love Harold,
+Boola boola Pensacoola hullabaloo!
+ -- Walt Kelly
+%
+"Deep" is a word like "theory" or "semantic" -- it implies all sorts of
+marvelous things. It's one thing to be able to say "I've got a
+theory", quite another to say "I've got a semantic theory", but, ah,
+those who can claim "I've got a deep semantic theory", they are truly
+blessed.
+ -- Randy Davis
+%
+default, n.:
+ [Possibly from Black English "De fault wid dis system is you,
+mon."] The vain attempt to avoid errors by inactivity. "Nothing will
+come of nothing: speak again." -- King Lear.
+ -- Stan Kelly-Bootle, "The Devil's DP Dictionary"
+%
+#define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)
+#define BX_(x) ((x) - (((x)>>1)&0x77777777) \
+ - (((x)>>2)&0x33333333) \
+ - (((x)>>3)&0x11111111))
+
+ -- really weird C code to count the number of bits in a word
+%
+ DELETE A FORTUNE!
+
+Don't some of these fortunes just drive you nuts?! Wouldn't you like
+to see some of them deleted from the system? You can! Just mail to
+"fortune" with the fortune you hate most, and we MIGHT make sure it
+gets expunged.
+%
+Deliberation, n.:
+ The act of examining one's bread to determine which side it is
+buttered on.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+"Deliver yesterday, code today, think tomorrow."
+%
+Demand the establishment of the government
+in its rightful home at Disneyland.
+%
+Democracy is a device that insures we shall be governed no better than
+we deserve.
+ -- George Bernard Shaw
+%
+Democracy is a form of government in which it is permitted to wonder
+aloud what the country could do under first-class management.
+ -- Senator Soaper
+%
+Democracy is a form of government that substitutes election by the
+incompetent many for appointment by the corrupt few.
+ -- G. B. Shaw
+%
+Democracy is a government where you can say what you think even if you
+don't think.
+%
+Democracy is also a form of worship. It is the worship of Jackals by
+Jackasses.
+ -- H. L. Mencken
+%
+Democracy is good. I say this because other systems are worse.
+ -- Jawaharlal Nehru
+%
+Democracy is the recurrent suspicion that more than half of the people
+are right more than half of the time.
+ -- E. B. White
+%
+Democracy, n.:
+ A government of the masses. Authority derived through mass
+meeting or any other form of direct expression. Results in mobocracy.
+Attitude toward property is communistic... negating property rights.
+Attitude toward law is that the will of the majority shall regulate,
+whether it is based upon deliberation or governed by passion,
+prejudice, and impulse, without restraint or regard to consequences.
+Result is demagogism, license, agitation, discontent, anarchy.
+ -- U. S. Army Training Manual No. 2000-25 (1928-1932),
+ since withdrawn.
+%
+Demographic polls show that you have lost credibility across the
+board. Especially with those 14 year-old Valley girls.
+%
+Dentist, n.:
+ A Prestidigitator who, putting metal in one's mouth, pulls
+coins out of one's pockets.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Despising machines to a man,
+The Luddites joined up with the Klan,
+ And ride out by night
+ In a sheeting of white
+To lynch all the robots they can.
+ -- C. M. and G. A. Maxson
+%
+Dessert is probably the most important stage of the meal, since it will
+be the last thing your guests remember before they pass out all over
+the table.
+ -- The Anarchist Cookbook
+%
+ DETERIORATA
+
+Go placidly amid the noise and waste,
+And remember what comfort there may be in owning a piece thereof.
+Avoid quiet and passive persons, unless you are in need of sleep.
+Rotate your tires.
+Speak glowingly of those greater than yourself,
+And heed well their advice -- even though they be turkeys.
+Know what to kiss -- and when.
+Remember that two wrongs never make a right,
+But that three do.
+Wherever possible, put people on "HOLD".
+Be comforted, that in the face of all aridity and disillusionment,
+And despite the changing fortunes of time,
+There is always a big future in computer maintenance.
+
+ You are a fluke of the universe ...
+ You have no right to be here.
+ Whether you can hear it or not, the universe
+ Is laughing behind your back.
+ -- National Lampoon
+%
+DeVries's Dilemma:
+ If you hit two keys on the typewriter, the one you don't want
+hits the paper.
+%
+Did I say 2? I lied.
+%
+Did you know ...
+
+That no-one ever reads these things?
+%
+Did you know that clones never use mirrors?
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Did you know that if you took all the economists in the world and lined
+them up end to end, they'd still point in the wrong direction?
+%
+Did you know that the voice tapes easily identify the Russian pilot
+that shot down the Korean jet? At one point he definitely states:
+
+ "Natasha! First we shoot jet, then we go after moose and
+ squirrel."
+
+ -- ihuxw!tommyo
+%
+Die, v.:
+ To stop sinning suddenly.
+ -- Elbert Hubbard
+%
+"Die? I should say not, dear fellow. No Barrymore would allow such a
+conventional thing to happen to him."
+ -- John Barrymore's dying words
+%
+Different all twisty a of in maze are you, passages little.
+%
+Dimensions will always be expressed in the least usable term.
+Velocity, for example, will be expressed in furlongs per fortnight.
+%
+Diplomacy is the art of saying "nice doggy" until you can find a rock.
+%
+Disc space -- the final frontier!
+%
+Disclaimer: "These opinions are my own, though for a small fee they be
+yours too."
+ -- Dave Haynie
+%
+Disclaimer: Any resemblance between the above views and those of my
+employer, my terminal, or the view out my window are purely
+coincidental. Any resemblance between the above and my own views is
+non-deterministic. The question of the existence of views in the
+absence of anyone to hold them is left as an exercise for the reader.
+The question of the existence of the reader is left as an exercise for
+the second god coefficient. (A discussion of non-orthogonal,
+non-integral polytheism is beyond the scope of this article.)
+%
+Disco is to music what Etch-A-Sketch is to art.
+%
+Distinctive, adj.:
+ A different color or shape than our competitors.
+%
+Distress, n.:
+ A disease incurred by exposure to the prosperity of a friend.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+District of Columbia pedestrians who leap over passing autos to escape
+injury, and then strike the car as they come down, are liable for any
+damage inflicted on the vehicle.
+%
+Do infants have as much fun in infancy as adults do in adultery?
+%
+Do molecular biologists wear designer genes?
+%
+Do not believe in miracles -- rely on them.
+%
+Do not drink coffee in early a.m. It will keep you awake until noon.
+%
+Do not meddle in the affairs of troff, for it is subtle and quick to
+anger.
+%
+"Do not meddle in the affairs of wizards, for you are crunchy and good
+with ketchup."
+%
+Do not read this fortune under penalty of law.
+Violators will be prosecuted.
+(Penal Code sec. 2.3.2 (II.a.))
+%
+Do not sleep in a eucalyptus tree tonight.
+%
+Do not try to solve all life's problems at once -- learn to dread each
+day as it comes.
+ -- Donald Kaul
+%
+Do something unusual today. Pay a bill.
+%
+Do what comes naturally now. Seethe and fume and throw a tantrum.
+%
+Do you have lysdexia?
+%
+Do you realize how many holes there could be if people would just take
+the time to take the dirt out of them?
+%
+"Do you think what we're doing is wrong?"
+"Of course it's wrong! It's illegal!"
+"I've never done anything illegal before."
+"I thought you said you were an accountant!"
+%
+Documentation is like sex: when it is good, it is very, very good; and
+when it is bad, it is better than nothing.
+ -- Dick Brandon
+%
+Documentation is the castor oil of programming. Managers know it must
+be good because the programmers hate it so much.
+%
+Does the name Pavlov ring a bell?
+%
+Don't abandon hope: your Tom Mix decoder ring arrives tomorrow.
+%
+Don't be humble ... you're not that great.
+ -- Golda Meir
+%
+Don't believe everything you hear or anything you say.
+%
+Don't change the reason, just change the excuses!
+ -- Joe Cointment
+%
+"Don't come back until you have him", the Tick-Tock Man said quietly,
+sincerely, extremely dangerously.
+
+They used dogs. They used probes. They used cardio plate crossoffs.
+They used teepers. They used bribery. They used stick tites. They
+used intimidation. They used torment. They used torture. They used
+finks. They used cops. They used search and seizure. They used
+fallaron. They used betterment incentives. They used finger prints.
+They used the bertillion system. They used cunning. They used guile.
+They used treachery. They used Raoul-Mitgong but he wasn't much help.
+They used applied physics. They used techniques of criminology. And
+what the hell, they caught him.
+
+ -- Harlan Ellison, "Repent, Harlequin, said the
+ Tick-Tock Man"
+%
+Don't cook tonight -- starve a rat today!
+%
+Don't feed the bats tonight.
+%
+Don't get even -- get odd!
+%
+Don't get suckered in by the comments -- they can be terribly
+misleading. Debug only code.
+ -- Dave Storer
+%
+"Don't go around saying the world owes you a living. The world owes
+you nothing. It was here first."
+ -- Mark Twain
+%
+Don't go surfing in South Dakota for a while.
+%
+Don't hate yourself in the morning -- sleep till noon.
+%
+Don't hit a man when he's down -- kick him; it's easier.
+%
+Don't kiss an elephant on the lips today.
+%
+Don't knock President Fillmore. He kept us out of Vietnam.
+%
+Don't let people drive you crazy when you know it's in walking
+distance.
+%
+Don't let your mind wander -- it's too little to be let out alone.
+%
+Don't look back, the lemmings are gaining on you.
+%
+Don't put off for tomorrow what you can do today, because if you enjoy
+it today you can do it again tomorrow.
+%
+"Don't say yes until I finish talking."
+ -- Darryl F. Zanuck
+%
+Don't steal; thou'lt never thus compete successfully in business.
+Cheat.
+ -- Ambrose Bierce
+%
+Don't suspect your friends -- turn them in!
+ -- "Brazil"
+%
+Don't take life so serious, son, it ain't nohow permanent.
+ -- Walt Kelly
+%
+Don't take life too seriously -- you'll never get out of it alive.
+%
+Don't tell any big lies today. Small ones can be just as effective.
+%
+"Don't tell me I'm burning the candle at both ends -- tell me where to
+get more wax!!"
+%
+Don't worry about avoiding temptation -- as you grow older, it starts
+avoiding you.
+ -- The Old Farmer's Almanac
+%
+"Don't worry about people stealing your ideas. If your ideas are any
+good, you'll have to ram them down people's throats."
+ -- Howard Aiken
+%
+Don't worry about the world coming to an end today. It's already
+tomorrow in Australia.
+ -- Charles Schultz
+%
+Don't worry over what other people are thinking about you. They're too
+busy worrying over what you are thinking about them.
+%
+Don't you feel more like you do now than you did when you came in?
+%
+Don: I didn't know you had a cousin Penelope, Bill! Was she
+ pretty?
+W. C.: Well, her face was so wrinkled it looked like seven miles of
+ bad road. She had so many gold teeth, Don, she use to have to
+ sleep with her head in a safe. She died in Bolivia.
+Don: Oh Bill, it must be hard to lose a relative.
+W. C.: It's almost impossible.
+ -- W. C. Fields, from "The Further Adventures of Larson
+ E. Whipsnade and other Tarradiddles"
+%
+ Double Bucky
+ (Sung to the tune of "Rubber Duckie")
+
+Double bucky, you're the one!
+You make my keyboard lots of fun
+ Double bucky, an additional bit or two:
+(Vo-vo-de-o!)
+Control and Meta side by side,
+Augmented ASCII, nine bits wide!
+ Double bucky, a half a thousand glyphs, plus a few!
+
+Double bucky, left and right
+OR'd together, outta sight!
+ Double bucky, I'd like a whole word of
+ Double bucky, I'm happy I heard of
+ Double bucky, I'd like a whole word of you!
+
+ -- (C) 1978 by Guy L. Steele, Jr.
+%
+Double-Blind Experiment, n.:
+ An experiment in which the chief researcher believes he is
+fooling both the subject and the lab assistant. Often accompanied by a
+belief in the tooth fairy.
+%
+Down with categorical imperative!
+%
+"Drawing on my fine command of language, I said nothing."
+%
+Drew's Law of Highway Biology:
+ The first bug to hit a clean windshield lands directly in front
+of your eyes.
+%
+Drink Canada Dry! You might not succeed, but it *__is* fun trying.
+%
+Drive defensively. Buy a tank.
+%
+Drugs may be the road to nowhere, but at least they're the scenic
+route!
+%
+Ducharme's Axiom:
+ If you view your problem closely enough you will recognize
+yourself as part of the problem.
+%
+Ducharme's Precept:
+ Opportunity always knocks at the least opportune moment.
+%
+Duct tape is like the force. It has a light side, and a dark side, and
+it holds the universe together ...
+ -- Carl Zwanzig
+%
+Due to a shortage of devoted followers, the production of great leaders
+has been discontinued.
+%
+Due to circumstances beyond your control, you are master of your fate
+and captain of your soul.
+%
+Due to lack of disk space, this fortune database has been
+discontinued.
+%
+ During a grouse hunt in North Carolina two intrepid sportsmen
+were blasting away at a clump of trees near a stone wall. Suddenly a
+red-faced country squire popped his head over the wall and shouted,
+"Hey, you almost hit my wife."
+ "Did I?" cried the hunter, aghast. "Terribly sorry. Have a
+shot at mine, over there."
+%
+During the next two hours, the system will be going up and down several
+times, often with lin~po_~{po ~poz~ppo\~{ o n~po_~{o[po ~y oodsou>#w4k**n~po_~{ol;lkld;f;g;dd;po\~{o
+%
+"Dying is a very dull, dreary affair. And my advice to you is to have
+nothing whatever to do with it."
+ -- W. Somerset Maugham
+%
+E Pluribus Unix
+%
+Eagleson's Law:
+ Any code of your own that you haven't looked at for six or more
+months, might as well have been written by someone else. (Eagleson is
+an optimist, the real number is more like three weeks.)
+%
+Earn cash in your spare time -- blackmail your friends
+%
+/earth is 98% full ... please delete anyone you can.
+%
+Earth is a beta site.
+%
+"Earth is a great, big funhouse without the fun."
+ -- Jeff Berner
+%
+Easiest Color to Solve on a Rubik's Cube:
+ Black. Simply remove all the little colored stickers on the
+cube, and each of side of the cube will now be the original color of
+the plastic underneath -- black. According to the instructions, this
+means the puzzle is solved.
+ -- Steve Rubenstein
+%
+ Eat drink and be merry, for tomorrow they may make it illegal.
+%
+"Eat, drink, and be merry, for tomorrow you may work."
+%
+Economics is extremely useful as a form of employment for economists.
+ -- John Kenneth Galbraith
+%
+Economics, n.:
+ Economics is the study of the value and meaning of J. K.
+Galbraith ...
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+Economists can certainly disappoint you. One said that the economy
+would turn up by the last quarter. Well, I'm down to mine and it
+hasn't.
+ -- Robert Orben
+%
+Economists state their GNP growth projections to the nearest tenth of a
+percentage point to prove they have a sense of humor.
+ -- Edgar R. Fiedler
+%
+Ed Sullivan will be around as long as someone else has talent.
+ -- Fred Allen
+%
+Education is the process of casting false pearls before real swine.
+ -- Irsin Edman
+%
+Eeny, Meeny, Jelly Beanie, the spirits are about to speak!
+ -- Bullwinkle Moose
+%
+Eggheads unite! You have nothing to lose but your yolks.
+ -- Adlai Stevenson
+%
+Eggnog is a traditional holiday drink invented by the English. Many
+people wonder where the word "eggnog" comes from. The first syllable
+comes from the English word "egg", meaning "egg". I don't know where
+the "nog" comes from.
+
+To make eggnog, you'll need rum, whiskey, wine gin and, if they are in
+season, eggs...
+%
+Egotism is the anesthetic given by a kindly nature to relieve the pain
+of being a damned fool.
+ -- Bellamy Brooks
+%
+Egotist, n.:
+ A person of low taste, more interested in himself than me.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Ehrman's Commentary:
+ (1) Things will get worse before they get better.
+ (2) Who said things would get better?
+%
+Eighty percent of air pollution comes from plants and trees.
+ -- Ronald Reagan, famous movie star
+%
+Eleanor Rigby
+ Sits at the keyboard
+ And waits for a line on the screen
+Lives in a dream
+Waits for a signal
+ Finding some code
+ That will make the machine do some more.
+What is it for?
+
+All the lonely users, where do they all come from?
+All the lonely users, why does it take so long?
+%
+Electrical Engineers do it with less resistance.
+%
+ Electricity is actually made up of extremely tiny particles,
+called electrons, that you cannot see with the naked eye unless you
+have been drinking. Electrons travel at the speed of light, which in
+most American homes is 110 volts per hour. This is very fast. In the
+time it has taken you to read this sentence so far, an electron could
+have traveled all the way from San Francisco to Hackensack, New Jersey,
+although God alone knows why it would want to.
+ The five main kinds of electricity are alternating current,
+direct current, lightning, static, and European. Most American homes
+have alternating current, which means that the electricity goes in one
+direction for a while, then goes in the other direction. This prevents
+harmful electron buildup in the wires.
+ -- Dave Barry, "The Taming of the Screw"
+%
+Electrocution, n.:
+ Burning at the stake with all the modern improvements.
+%
+Elevators smell different to midgets
+%
+Emersons' Law of Contrariness:
+ Our chief want in life is somebody who shall make us do what we
+can. Having found them, we shall then hate them for it.
+%
+Encyclopedia Salesmen:
+ Invite them all in. Nip out the back door. Phone the police
+and tell them your house is being burgled.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+Endless Loop: n., see Loop, Endless.
+Loop, Endless: n., see Endless Loop.
+ -- Random Shack Data Processing Dictionary
+%
+Entropy isn't what it used to be.
+%
+Enzymes are things invented by biologists that explain things which
+otherwise require harder thinking.
+ -- Jerome Lettvin
+%
+Epperson's law:
+ When a man says it's a silly, childish game, it's probably
+something his wife can beat him at.
+%
+Equal bytes for women.
+%
+Error in operator: add beer
+%
+Es brilig war. Die schlichte Toven
+ Wirrten und wimmelten in Waben;
+Und aller-m"umsige Burggoven
+ Dir mohmen R"ath ausgraben.
+ -- Lewis Carrol, "Through the Looking Glass"
+%
+Eternal nothingness is fine if you happen to be dressed for it.
+ -- Woody Allen
+%
+Etymology, n.:
+ Some early etymological scholars came up with derivations that
+were hard for the public to believe. The term "etymology" was formed
+from the Latin "etus" ("eaten"), the root "mal" ("bad"), and "logy"
+("study of"). It meant "the study of things that are hard to swallow."
+ -- Mike Kellen
+%
+Even if you do learn to speak correct English, whom are you going to
+speak it to?
+ -- Clarence Darrow
+%
+"Even if you're on the right track, you'll get run over if you just sit
+there."
+ -- Will Rogers
+%
+"Even the best of friends cannot attend each other's funeral."
+ -- Kehlog Albran, "The Profit"
+%
+Even though they raised the rate for first class mail in the United
+States we really shouldn't complain -- it's still only two cents a
+day.
+%
+Ever notice that even the busiest people are never too busy to tell you
+just how busy they are.
+%
+Ever since prehistoric times, wise men have tried to understand what,
+exactly, make people laugh. That's why they were called "wise men."
+All the other prehistoric people were out puncturing each other with
+spears, and the wise men were back in the cave saying: "How about:
+Would you please take my wife? No. How about: Here is my wife, please
+take her right now. No How about: Would you like to take something?
+My wife is available. No. How about ..."
+ -- Dave Barry, "Why Humor is Funny"
+%
+Every absurdity has a champion who will defend it.
+%
+Every creature has within him the wild, uncontrollable urge to punt.
+%
+Every four seconds a woman has a baby. Our problem is to find this
+woman and stop her.
+%
+"Every group has a couple of experts. And every group has at least one
+idiot. Thus are balance and harmony (and discord) maintained. It's
+sometimes hard to remember this in the bulk of the flamewars that all
+of the hassle and pain is generally caused by one or two
+highly-motivated, caustic twits."
+ -- Chuq Von Rospach, about Usenet
+%
+Every gun that is made, every warship launched, every rocket fired
+signifies in the final sense, a theft from those who hunger and are not
+fed, those who are cold and are not clothed. This world in arms is not
+spending money alone. It is spending the sweat of its laborers, the
+genius of its scientists, the hopes of its children. This is not a way
+of life at all in any true sense. Under the clouds of war, it is
+humanity hanging on a cross of iron.
+ -- Dwight Eisenhower, April 16, 1953
+%
+Every Horse has an Infinite Number of Legs (proof by intimidation):
+
+Horses have an even number of legs. Behind they have two legs, and in
+front they have fore-legs. This makes six legs, which is certainly an
+odd number of legs for a horse. But the only number that is both even
+and odd is infinity. Therefore, horses have an infinite number of
+legs. Now to show this for the general case, suppose that somewhere,
+there is a horse that has a finite number of legs. But that is a horse
+of another color, and by the [above] lemma ["All horses are the same
+color"], that does not exist.
+%
+Every improvement in communication makes the bore more terrible.
+ -- Frank Moore Colby
+%
+Every journalist has a novel in him, which is an excellent place for it.
+%
+Every little picofarad has a nanohenry all its own.
+ -- Don Vonada
+%
+"Every man has his price. Mine is $3.95."
+%
+Every man is as God made him, ay, and often worse.
+ -- Miguel de Cervantes
+%
+"Every morning, I get up and look through the 'Forbes' list of the
+richest people in America. If I'm not there, I go to work"
+ -- Robert Orben
+%
+Every nonzero finite dimensional inner product space has an orthonormal basis.
+
+It makes sense, when you don't think about it.
+%
+Every program has at least one bug and can be shortened by at least one
+instruction -- from which, by induction, one can deduce that every
+program can be reduced to one instruction which doesn't work.
+%
+Every program has two purposes -- one for which it was written and
+another for which it wasn't.
+%
+Every program is a part of some other program, and rarely fits.
+%
+Every solution breeds new problems.
+%
+Every successful person has had failures but repeated failure is no
+guarantee of eventual success.
+%
+"Every time I think I know where it's at, they move it."
+%
+Every word is like an unnecessary stain on silence and nothingness.
+ -- Beckett
+%
+Everybody is somebody else's weirdo.
+ -- Dykstra
+%
+Everybody wants to go to heaven, but nobody wants to die.
+%
+Everyone can be taught to sculpt: Michelangelo would have had to be
+taught how ___not to. So it is with the great programmers.
+%
+Everyone is a genius. It's just that some people are too stupid to
+realize it.
+%
+Everyone knows that dragons don't exist. But while this simplistic
+formulation may satisfy the layman, it does not suffice for the
+scientific mind. The School of Higher Neantical Nillity is in fact
+wholly unconcerned with what ____does exist. Indeed, the banality of
+existence has been so amply demonstrated, there is no need for us to
+discuss it any further here. The brilliant Cerebron, attacking the
+problem analytically, discovered three distinct kinds of dragon: the
+mythical, the chimerical, and the purely hypothetical. They were all,
+one might say, nonexistent, but each nonexisted in an entirely
+different way ...
+ -- Stanislaw Lem, "Cyberiad"
+%
+Everyone talks about apathy, but no one ____does anything about it.
+%
+Everything is controlled by a small evil group to which, unfortunately,
+no one we know belongs.
+%
+Everything is worth precisely as much as a belch, the difference being
+that a belch is more satisfying.
+ -- Ingmar Bergman
+%
+Everything should be built top-down, except the first time.
+%
+Everything you know is wrong!
+%
+Everything you've learned in school as "obvious" becomes less and less
+obvious as you begin to study the universe. For example, there are no
+solids in the universe. There's not even a suggestion of a solid.
+There are no absolute continuums. There are no surfaces. There are no
+straight lines.
+ -- R. Buckminster Fuller
+%
+ Excellence is THE trend of the '80s. Walk into any shopping
+mall bookstore, go to the rack where they keep the best-sellers such as
+"Garfield Gets Spayed", and you'll see a half-dozen books telling you
+how to be excellent: "In Search of Excellence", "Finding Excellence",
+"Grasping Hold of Excellence", "Where to Hide Your Excellence at Night
+So the Cleaning Personnel Don't Steal It", etc.
+ -- Dave Barry, "In Search of Excellence"
+%
+Excellent day for drinking heavily. Spike office water cooler.
+%
+Excellent day for putting Slinkies on an escalator.
+%
+Excellent day to have a rotten day.
+%
+Excellent time to become a missing person.
+%
+Excess on occasion is exhilarating. It prevents moderation from
+acquiring the deadening effect of a habit.
+ -- W. Somerset Maugham
+%
+Excessive login or logout messages are a sure sign of senility.
+%
+Executive ability is deciding quickly and getting somebody else to do
+the work.
+ -- John G. Pollard
+%
+Expect the worst, it's the least you can do.
+%
+Expense Accounts, n.:
+ Corporate food stamps.
+%
+Experience is something you don't get until just after you need it.
+ -- Olivier
+%
+Experience is that marvelous thing that enables you recognize a mistake
+when you make it again.
+ -- F. P. Jones
+%
+Experience is the worst teacher. It always gives the test first and
+the instruction afterward.
+%
+Experience is what causes a person to make new mistakes instead of old
+ones.
+%
+Experience is what you get when you were expecting something else.
+%
+Experience varies directly with equipment ruined.
+%
+Expert, n.:
+ Someone who comes from out of town and shows slides.
+%
+Extract from Official Sweepstakes Rules:
+
+ NO PURCHASE REQUIRED TO CLAIM YOUR PRIZE
+
+To claim your prize without purchase, do the following: (a) Carefully
+cut out your computer-printed name and address from upper right hand
+corner of the Prize Claim Form. (b) Affix computer-printed name and
+address -- with glue or cellophane tape (no staples or paper clips) --
+to a 3x5 inch index card. (c) Also cut out the "No" paragraph (lower
+left hand corner of Prize Claim Form) and affix it to the 3x5 card
+below your address label. (d) Then print on your 3x5 card, above your
+computer-printed name and address the words "CARTER & VAN PEEL
+SWEEPSTAKES" (Use all capital letters.) (e) Finally place 3x5 card
+(without bending) into a plain envelope [NOTE: do NOT use the the
+Official Prize Claim and CVP Perfume Reply Envelope or you may be
+disqualified], and mail to: CVP, Box 1320, Westbury, NY 11595. Print
+this address correctly. Comply with above instructions carefully and
+completely or you may be disqualified from receiving your prize.
+%
+F u cn rd ths u cnt spl wrth a dm!
+%
+f u cn rd ths, itn tyg h myxbl cd.
+%
+f u cn rd ths, u cn gt a gd jb n cmptr prgrmmng.
+%
+F: When into a room I plunge, I
+ Sometimes find some VIOLET FUNGI.
+ Then I linger, darkly brooding
+ On the poison they're exuding.
+ -- The Roguelet's ABC
+%
+Facts are stubborn, but statistics are more pliable.
+%
+Fairy Tale, n.:
+ A horror story to prepare children for the newspapers.
+%
+Faith is the quality that enables you to eat blackberry jam on a picnic
+without looking to see whether the seeds move.
+%
+Faith, n:
+ That quality which enables us to believe what we know to be
+untrue.
+%
+Fakir, n:
+ A psychologist whose charismatic data have inspired almost
+religious devotion in his followers, even though the sources seem to
+have shinnied up a rope and vanished.
+%
+Familiarity breeds attempt
+%
+Families, when a child is born
+Want it to be intelligent.
+I, through intelligence,
+Having wrecked my whole life,
+Only hope the baby will prove
+Ignorant and stupid.
+Then he will crown a tranquil life
+By becoming a Cabinet Minister
+ -- Su Tung-p'o
+%
+Famous last words:
+%
+Famous last words:
+ (1) "Don't worry, I can handle it."
+ (2) "You and what army?"
+ (3) "If you were as smart as you think you are, you wouldn't be
+ a cop."
+%
+Famous last words:
+ (1) Don't unplug it, it will just take a moment to fix.
+ (2) Let's take the shortcut, he can't see us from there.
+ (3) What happens if you touch these two wires tog--
+ (4) We won't need reservations.
+ (5) It's always sunny there this time of the year.
+ (6) Don't worry, it's not loaded.
+ (7) They'd never (be stupid enough to) make him a manager.
+%
+Famous, adj.:
+ Conspicuously miserable.
+ -- Ambrose Bierce
+%
+Far out in the uncharted backwaters of the unfashionable end of the
+Western Spiral arm of the Galaxy lies a small unregarded yellow sun.
+Orbiting this at a distance of roughly ninety-eight million miles is an
+utterly insignificant little blue-green planet whose ape-descended life
+forms are so amazingly primitive that they still think digital watches
+are a pretty neat idea ...
+ -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
+%
+Fashion is a form of ugliness so intolerable that we have to alter it
+every six months.
+ -- Oscar Wilde
+%
+Fats Loves Madelyn
+%
+Feel disillusioned? I've got some great new illusions ...
+%
+Fertility is hereditary. If your parents didn't have any children,
+neither will you.
+%
+ Festivity Level 1: Your guests are chatting amiably with each
+other, admiring your Christmas-tree ornaments, singing carols around
+the upright piano, sipping at their drinks and nibbling hors
+d'oeuvres.
+ Festivity Level 2: Your guests are talking loudly -- sometimes
+to each other, and sometimes to nobody at all, rearranging your
+Christmas-tree ornaments, singing "I Gotta Be Me" around the upright
+piano, gulping their drinks and wolfing down hors d'oeuvres.
+ Festivity Level 3: Your guests are arguing violently with
+inanimate objects, singing "I can't get no satisfaction," gulping down
+other peoples' drinks, wolfing down Christmas tree ornaments and
+placing hors d'oeuvres in the upright piano to see what happens when
+the little hammers strike.
+ Festivity Level 4: Your guests, hors d'oeuvres smeared all over
+their naked bodies are performing a ritual dance around the burning
+Christmas tree. The piano is missing.
+
+ You want to keep your party somewhere around level 3, unless
+you rent your home and own Firearms, in which case you can go to level
+4. The best way to get to level 3 is egg-nog.
+%
+Fifth Law of Applied Terror:
+ If you are given an open-book exam, you will forget your book.
+
+Corollary:
+ If you are given a take-home exam, you will forget where you
+live.
+%
+Fifth Law of Procrastination:
+ Procrastination avoids boredom; one never has the feeling that
+there is nothing important to do.
+%
+Fifty flippant frogs
+Walked by on flippered feet
+And with their slime they made the time
+Unnaturally fleet.
+%
+ FIGHTING WORDS
+
+Say my love is easy had,
+ Say I'm bitten raw with pride,
+Say I am too often sad --
+ Still behold me at your side.
+
+Say I'm neither brave nor young,
+ Say I woo and coddle care,
+Say the devil touched my tongue --
+ Still you have my heart to wear.
+
+But say my verses do not scan,
+ And I get me another man!
+ -- Dorothy Parker
+%
+Fights between cats and dogs are prohibited by statute in Barber, North
+Carolina.
+%
+Finagle's Creed:
+ Science is true. Don't be misled by facts.
+%
+Finagle's First Law:
+ If an experiment works, something has gone wrong.
+%
+Finagle's fourth Law:
+ Once a job is fouled up, anything done to improve it only makes
+it worse.
+%
+Finagle's Second Law:
+ No matter what the anticipated result, there will always be
+someone eager to (a) misinterpret it, (b) fake it, or (c) believe it
+happened according to his own pet theory.
+%
+Finagle's Third Law:
+ In any collection of data, the figure most obviously correct,
+ beyond all need of checking, is the mistake
+
+Corollaries:
+ (1) Nobody whom you ask for help will see it.
+ (2) The first person who stops by, whose advice you really
+ don't want to hear, will see it immediately.
+%
+Finding out what goes on in the C.I.A. is like performing acupuncture
+on a rock.
+ -- New York Times, Jan. 20, 1981
+%
+Fine day to throw a party. Throw him as far as you can.
+%
+Fine day to work off excess energy. Steal something heavy.
+%
+Fine's Corollary:
+ Functionality breeds Contempt.
+%
+Finish the sentence below in 25 words or less:
+
+ "Love is what you feel just before you give someone a good ..."
+
+Mail your answer along with the top half of your supervisor to:
+
+ P.O. Box 35
+ Baffled Greek, Michigan
+%
+First Corollary of Taber's Second Law:
+ Machines that piss people off get murdered.
+ -- Pat Taber
+%
+First Law of Bicycling:
+ No matter which way you ride, it's uphill and against the
+wind.
+%
+First Law of Procrastination:
+ Procrastination shortens the job and places the responsibility
+for its termination on someone else (i.e., the authority who imposed
+the deadline).
+%
+First Law of Socio-Genetics:
+ Celibacy is not hereditary.
+%
+First Rule of History:
+ History doesn't repeat itself -- historians merely repeat each
+other.
+%
+"First things first -- but not necessarily in that order"
+ -- The Doctor, "Doctor Who"
+%
+First, a few words about tools.
+
+Basically, a tool is an object that enables you to take advantage of
+the laws of physics and mechanics in such a way that you can seriously
+injure yourself. Today, people tend to take tools for granted. If
+you're ever walking down the street and you notice some people who look
+particularly smug, the odds are that they are taking tools for
+granted. If I were you, I'd walk right up and smack them in the face.
+ -- Dave Barry, "The Taming of the Screw"
+%
+Five is a sufficiently close approximation to infinity.
+ -- Robert Firth
+%
+Flappity, floppity, flip
+The mouse on the m"obius strip;
+ The strip revolved,
+ The mouse dissolved
+In a chronodimensional skip.
+%
+FLASH! Intelligence of mankind decreasing. Details at ... uh, when
+the little hand is on the ....
+%
+Flon's Law:
+ There is not now, and never will be, a language in which it is
+the least bit difficult to write bad programs.
+%
+Florence Flask was ... dressing for the opera when she turned to her
+husband and screamed, "Erlenmeyer! My joules! Someone has stolen my
+joules!"
+
+"Now, now, my dear," replied her husband, "keep your balance and reflux
+a moment. Perhaps they're mislead."
+
+"No, I know they're stolen," cried Florence. "I remember putting them
+in my burette ... We must call a copper."
+
+Erlenmeyer did so, and the flatfoot who turned up, one Sherlock Ohms,
+said the outrage looked like the work of an arch-criminal by the name
+of Lawrence Ium.
+
+"We must be careful -- he's a free radical, ultraviolet, and
+dangerous. His girlfriend is a chlorine at the Palladium. Maybe I can
+catch him there." With that, he jumped on his carbon cycle in an
+activated state and sped off along the reaction pathway ...
+ -- Daniel B. Murphy, "Precipitations"
+%
+flowchart, n. & v.:
+ [From flow "to ripple down in rich profusion, as hair" + chart
+"a cryptic hidden-treasure map designed to mislead the uninitiated."]
+1. n. The solution, if any, to a class of Mascheroni construction
+problems in which given algorithms require geometrical representation
+using only the 35 basic ideograms of the ANSI template. 2. n. Neronic
+doodling while the system burns. 3. n. A low-cost substitute for
+wallpaper. 4. n. The innumerate misleading the illiterate. "A
+thousand pictures is worth ten lines of code." -- The Programmer's
+Little Red Vade Mecum, Mao Tse T'umps. 5. v.intrans. To produce
+flowcharts with no particular object in mind. 6. v.trans. To obfuscate
+(a problem) with esoteric cartoons.
+ -- Stan Kelly-Bootle, "The Devil's DP Dictionary"
+%
+Flugg's Law:
+ When you need to knock on wood is when you realize that the
+world is composed of vinyl, naugahyde and aluminum.
+%
+Flying saucers on occasion
+ Show themselves to human eyes.
+Aliens fume, put off invasion
+ While they brand these tales as lies.
+%
+Fog Lamps, n.:
+ Excessively (often obnoxiously) bright lamps mounted on the
+fronts of automobiles; used on dry, clear nights to indicate that the
+driver's brain is in a fog.
+
+See also "Idiot Lights".
+%
+Food for thought is no substitute for the real thing.
+ -- Walt Kelly, "Putluck Pogo"
+%
+For 20 dollars, I'll give you a good fortune next time ...
+%
+For a good time, call (415) 642-9483
+%
+For a man to truly understand rejection, he must first be ignored by a
+cat.
+%
+"For an adequate time call 555-3321"
+%
+For an idea to be fashionable is ominous, since it must afterwards be
+always old-fashioned.
+%
+For every complex problem, there is a solution that is simple, neat,
+and wrong.
+ -- H. L. Mencken
+%
+For every credibility gap, there is a gullibility fill.
+ -- R. Clopton
+%
+ "For I perceive that behind this seemingly unrelated sequence
+of events, there lurks a singular, sinister attitude of mind."
+
+ "Whose?"
+
+ "MINE! HA-HA!"
+%
+For large values of one, one equals two, for small values of two.
+%
+For my son, Robert, this is proving to be the high-point of his entire
+life to date. He has had his pajamas on for two, maybe three days
+now. He has the sense of joyful independence a 5-year-old child gets
+when he suddenly realizes that he could be operating an acetylene torch
+in the coat closet and neither parent [because of the flu] would have
+the strength to object. He has been foraging for his own food, which
+means his diet consists entirely of "food" substances which are
+advertised only on Saturday-morning cartoon shows; substances that are
+the color of jukebox lights and that, for legal reasons, have their
+names spelled wrong, as in New Creemy Chok-'n'-Cheez Lumps o' Froot
+("part of this complete breakfast").
+ -- Dave Barry, "Molecular Homicide"
+%
+For perfect happiness, remember two things:
+ (1) Be content with what you've got.
+ (2) Be sure you've got plenty.
+%
+For some reason a glaze passes over people's faces when you say
+"Canada". Maybe we should invade South Dakota or something.
+ -- Sandra Gotlieb, wife of the Canadian ambassador to
+ the U.S.
+%
+For some reason, this fortune reminds everyone of Marvin Zelkowitz.
+%
+"For that matter, compare your pocket computer with the massive jobs of
+a thousand years ago. Why not, then, the last step of doing away with
+computers altogether?"
+ -- Jehan Shuman
+%
+For those who like this sort of thing, this is the sort of thing they
+like.
+ -- Abraham Lincoln
+%
+"For three days after death hair and fingernails continue to grow but
+phone calls taper off."
+ -- Johnny Carson
+%
+For years a secret shame destroyed my peace --
+I'd not read Eliot, Auden or MacNiece.
+But now I think a thought that brings me hope:
+Neither had Chaucer, Shakespeare, Milton, Pope.
+ -- Justin Richardson.
+%
+For your penance, say five Hail Marys and one loud BLAH!
+%
+Forgetfulness, n.:
+ A gift of God bestowed upon debtors in compensation for their
+destitution of conscience.
+%
+Forms follow function, and often obliterate it.
+%
+FORTUNE DISCUSSES THE OBSCURE FILMS! #6
+
+RAZORBACK: Paul Harbride, 1984, 2 hours 25 min.
+ One of the great Australian films of the early 1980's, and
+ arguably the best movie ever made about a large, man-eating
+ hog. Some violence. With Gregory Harrison.
+%
+fortune's Contribution of the Month to the Animal Rights Debate:
+
+ I'll stay out of animals' way if they'll stay out of mine.
+ "Hey you, get off my plate"
+ -- Roger Midnight
+%
+Fortune's Fictitious Country Song Title of the Week:
+ "How Can I Miss You if You Won't Go Away?"
+%
+Fortune's graffito of the week (or maybe even month):
+
+ Don't Write On Walls!
+
+ (and underneath)
+
+ You want I should type?
+%
+Fortune's Law of the Week (this week, from Kentucky):
+ No female shall appear in a bathing suit at any airport in this
+State unless she is escorted by two officers or unless she is armed
+with a club. The provisions of this statute shall not apply to females
+weighing less than 90 pounds nor exceeding 200 pounds, nor shall it
+apply to female horses.
+%
+Fortune's nomination for All-Time Champion and Protector of Youthful
+Morals goes to Representative Clare E. Hoffman of Michigan. During an
+impassioned House debate over a proposed bill to "expand oyster and
+clam research," a sharp-eared informant transcribed the following
+exchange between our hero and Rep. John D. Dingell, also of Michigan.
+
+DINGELL: There are places in the world at the present time where we are
+ having to artificially propagate oysters and clams.
+HOFFMAN: You mean the oysters I buy are not nature's oysters?
+DINGELL: They may or may not be natural. The simple fact of the matter
+ is that female oysters through their living habits cast out
+ large amounts of seed and the male oysters cast out large
+ amounts of fertilization ...
+HOFFMAN: Wait a minute! I do not want to go into that. There are many
+ teenagers who read The Congressional Record.
+%
+Fortune's Office Door Sign of the Week:
+
+ Incorrigible punster -- Do not incorrige.
+%
+FORTUNE'S PARTY TIPS #14
+
+Tired of finding that other people are helping themselves to your good
+liquor at BYOB parties? Take along a candle, which you insert and
+light after you've opened the bottle. No one ever expects anything
+drinkable to be in a bottle which has a candle stuck in its neck.
+%
+Fortune's Real-Life Courtroom Quote #18:
+
+Q: Are you married?
+A: No, I'm divorced.
+Q: And what did your husband do before you divorced him?
+A: A lot of things I didn't know about.
+%
+Fortune's Real-Life Courtroom Quote #19:
+
+Q: Doctor, how many autopsies have you performed on dead people?
+A: All my autopsies have been performed on dead people.
+%
+Fortune's Real-Life Courtroom Quote #29:
+
+THE JUDGE: Now, as we begin, I must ask you to banish all present
+ information and prejudice from your minds, if you have
+ any ...
+%
+Fortune's Real-Life Courtroom Quote #32:
+
+Q: Do you know how far pregnant you are right now?
+A: I will be three months November 8th.
+Q: Apparently then, the date of conception was August 8th?
+A: Yes.
+Q: What were you and your husband doing at that time?
+%
+Fortune's Real-Life Courtroom Quote #37:
+
+Q: Did he pick the dog up by the ears?
+A: No.
+Q: What was he doing with the dog's ears?
+A: Picking them up in the air.
+Q: Where was the dog at this time?
+A: Attached to the ears.
+%
+Fortune's Real-Life Courtroom Quote #3:
+
+Q: When he went, had you gone and had she, if she wanted to and were
+ able, for the time being excluding all the restraints on her not to
+ go, gone also, would he have brought you, meaning you and she, with
+ him to the station?
+MR. BROOKS: Objection. That question should be taken out and shot.
+%
+Fortune's Real-Life Courtroom Quote #41:
+
+Q: Now, Mrs. Johnson, how was your first marriage terminated?
+A: By death.
+Q: And by whose death was it terminated?
+%
+Fortune's Real-Life Courtroom Quote #52:
+
+Q: What is your name?
+A: Ernestine McDowell.
+Q: And what is your marital status?
+A: Fair.
+%
+Fortune's Real-Life Courtroom Quote #7:
+
+Q: What happened then?
+A: He told me, he says, "I have to kill you because you can identify
+ me."
+Q: Did he kill you?
+A: No.
+%
+fortune: cpu time/usefulness ratio too high -- core dumped.
+%
+Fortune: You will be attacked next Wednesday at 3:15 p.m. by six samuri
+sword wielding purple fish glued to Harley-Davidson motorcycles.
+
+Oh, and have a nice day!
+ -- Bryce Nesbitt '84
+%
+Fourth Law of Applied Terror:
+ The night before the English History mid-term, your Biology
+instructor will assign 200 pages on planaria.
+
+Corollary:
+ Every instructor assumes that you have nothing else to do
+except study for that instructor's course.
+%
+Fourth Law of Revision:
+ It is usually impractical to worry beforehand about
+interferences -- if you have none, someone will make one for you.
+%
+Fourth Law of Thermodynamics: If the probability of success is not
+almost one, it is damn near zero.
+ -- David Ellis
+%
+Frankfort, Kentucky, makes it against the law to shoot off a
+policeman's tie.
+%
+Fresco's Discovery:
+ If you knew what you were doing you'd probably be bored.
+%
+Friends, Romans, Hipsters,
+Let me clue you in;
+I come to put down Caesar, not to groove him.
+The square kicks some cats are on stay with them;
+The hip bits, like, go down under; so let it lay with Caesar. The cool Brutus
+Gave you the message: Caesar had big eyes;
+If that's the sound, someone's copping a plea,
+And, like, old Caesar really set them straight.
+Here, copacetic with Brutus and the studs, -- for Brutus is a real cool cat;
+So are they all, all cool cats, --
+Come I to make this gig at Caesar's laying down.
+%
+Frisbeetarianism, n.:
+ The belief that when you die, your soul goes up the on roof and
+gets stuck.
+%
+Frobnicate, v.:
+ To manipulate or adjust, to tweak. Derived from FROBNITZ.
+Usually abbreviated to FROB. Thus one has the saying "to frob a
+frob". See TWEAK and TWIDDLE. Usage: FROB, TWIDDLE, and TWEAK
+sometimes connote points along a continuum. FROB connotes aimless
+manipulation; TWIDDLE connotes gross manipulation, often a coarse
+search for a proper setting; TWEAK connotes fine-tuning. If someone is
+turning a knob on an oscilloscope, then if he's carefully adjusting it
+he is probably tweaking it; if he is just turning it but looking at the
+screen he is probably twiddling it; but if he's just doing it because
+turning a knob is fun, he's frobbing it.
+%
+Frobnitz, pl. Frobnitzem (frob'nitsm) n.:
+ An unspecified physical object, a widget. Also refers to
+electronic black boxes. This rare form is usually abbreviated to
+FROTZ, or more commonly to FROB. Also used are FROBNULE, FROBULE, and
+FROBNODULE. Starting perhaps in 1979, FROBBOZ (fruh-bahz'), pl.
+FROBBOTZIM, has also become very popular, largely due to its exposure
+via the Adventure spin-off called Zork (Dungeon). These can also be
+applied to non-physical objects, such as data structures.
+%
+[From an announcement of a congress of the International Ontopsychology
+Association, in Rome]:
+
+The Ontopsychological school, availing itself of new research criteria
+and of a new telematic epistemology, maintains that social modes do not
+spring from dialectics of territory or of class, or of consumer goods,
+or of means of power, but rather from dynamic latencies capillarized in
+millions of individuals in system functions which, once they have
+reached the event maturation, burst forth in catastrophic phenomenology
+engaging a suitable stereotype protagonist or duty marionette (general,
+president, political party, etc.) to consummate the act of social
+schizophrenia in mass genocide.
+%
+From the "Guiness Book of World Records", 1973:
+
+Certain passages in several laws have always defied interpretation and
+the most inexplicable must be a matter of opinion. A judge of the
+Court of Session of Scotland has sent the editors of this book his
+candidate which reads, "In the Nuts (unground), (other than ground
+nuts) Order, the expression nuts shall have reference to such nuts,
+other than ground nuts, as would but for this amending Order not
+qualify as nuts (unground)(other than ground nuts) by reason of their
+being nuts (unground)."
+%
+From the moment I picked your book up until I put it down I was
+convulsed with laughter. Some day I intend reading it.
+ -- Groucho Marx, from "The Book of Insults"
+%
+[From the operation manual for the CI-300 Dot Matrix Line Printer, made
+in Japan]:
+
+The excellent output machine of MODEL CI-300 as extraordinary DOT
+MATRIX LINE PRINTER, built in two MICRO-PROCESSORs as well as EAROM, is
+featured by permitting wonderful co-existence such as; "high quality
+against low cost", "diversified functions with compact design",
+"flexibility in accessibleness and durability of approx. 2000,000,00
+Dot/Head", "being sophisticated in mechanism but possibly agile
+operating under noises being extremely suppressed" etc.
+
+And as a matter of course, the final goal is just simply to help
+achieve "super shuttle diplomacy" between cool data, perhaps earned by
+HOST COMPUTER, and warm heart of human being.
+%
+From the Pro 350 Pocket Service Guide, p. 49, Step 5 of the
+instructions on removing an I/O board from the card cage, comes a new
+experience in sound:
+
+ 5. Turn the handle to the right 90 degrees. The pin-spreading
+ sound is normal for this type of connector.
+%
+From too much love of living,
+From hope and fear set free,
+We thank with brief thanksgiving,
+Whatever gods may be,
+That no life lives forever,
+That dead men rise up never,
+That even the weariest river winds somewhere safe to sea.
+ -- Swinburne
+%
+Fuch's Warning:
+ If you actually look like your passport photo, you aren't well
+enough to travel.
+%
+Fudd's First Law of Opposition:
+ Push something hard enough and it will fall over.
+%
+Furbling, v.:
+ Having to wander through a maze of ropes at an airport or bank
+even when you are the only person in line.
+ -- Rich Hall, "Sniglets"
+%
+Furious activity is no substitute for understanding.
+ -- H. H. Williams
+%
+Future looks spotty. You will spill soup in late evening.
+%
+G. B. Shaw to William Douglas Home: "Go on writing plays, my boy. One
+of these days a London producer will go into his office and say to his
+secretary, `Is there a play from Shaw this morning?' and when she says
+`No,' he will say, `Well, then we'll have to start on the rubbish.' And
+that's your chance, my boy."
+%
+Garbage In -- Gospel Out.
+%
+Garter, n.:
+ An elastic band intended to keep a woman from coming out of her
+stockings and desolating the country.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Gauls! We have nothing to fear; except perhaps that the sky may fall
+on our heads tomorrow. But as we all know, tomorrow never comes!!
+ -- Adventures of Asterix.
+%
+Gay shlafen: Yiddish for "go to sleep".
+
+ Now doesn't "gay shlafen" have a softer, more soothing sound
+than the harsh, staccato "go to sleep"? Listen to the difference:
+ "Go to sleep, you little wretch!" ... "Gay shlafen, darling."
+Obvious, isn't it?
+ Clearly the best thing you can do for you children is to start
+speaking Yiddish right now and never speak another word of English as
+long as you live. This will, of course, entail teaching Yiddish to all
+your friends, business associates, the people at the supermarket, and
+so on, but that's just the point. It has to start with committed
+individuals and then grow ...
+ Some minor adjustments will have to be made, of course: those
+signs written in what look like Yiddish letters won't be funny when
+everything is written in Yiddish. And we'll have to start driving on
+the left side of the road so we won't be reading the street signs
+backwards. But is that too high a price to pay for world peace? I
+think not, my friend, I think not.
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+ "Gee, Mudhead, everyone at More Science High has an
+extracurricular activity except you."
+ "Well, gee, doesn't Louise count?"
+ "Only to ten, Mudhead."
+
+ -- Firesign Theater
+%
+"Gee, Toto, I don't think we are in Kansas anymore."
+%
+GEMINI (May 21 - June 20)
+ You are a quick and intelligent thinker. People like you
+because you are bisexual. However, you are inclined to expect too much
+for too little. This means you are cheap. Geminis are known for
+committing incest.
+%
+GEMINI (May 21 to Jun. 20)
+ Good news and bad news highlighted. Enjoy the good news while
+you can; the bad news will make you forget it. You will enjoy praise
+and respect from those around you; everybody loves a sucker. A short
+trip is in the stars, possibly to the men's room.
+%
+Genderplex, n.:
+ The predicament of a person in a restaurant who is unable to
+determine his or her designated restroom (e.g., turtles and
+tortoises).
+ -- Rich Hall, "Sniglets"
+%
+Genetics explains why you look like your father, and if you don't, why
+you should.
+%
+Genius may have its limitations, but stupidity is not thus
+handicapped.
+ -- Elbert Hubbard
+%
+Genius, n.:
+ A chemist who discovers a laundry additive that rhymes with
+"bright".
+%
+George Orwell 1984. Northwestern 0.
+ -- Chicago Reader 10/15/82
+%
+George Orwell was an optimist.
+%
+George Washington was first in war, first in peace -- and the first to
+have his birthday juggled to make a long weekend.
+ -- Ashley Cooper
+%
+Gerrold's Laws of Infernal Dynamics:
+ (1) An object in motion will always be headed in the wrong
+ direction.
+ (2) An object at rest will always be in the wrong place.
+ (3) The energy required to change either one of these states
+ will always be more than you wish to expend, but never so
+ much as to make the task totally impossible.
+%
+Get forgiveness now -- tomorrow you may no longer feel guilty.
+%
+ Get GUMMed
+ --- ------
+The Gurus of Unix Meeting of Minds (GUMM) takes place Wednesday, April
+1, 2076 (check THAT in your perpetual calendar program), 14 feet above
+the ground directly in front of the Milpitas Gumps. Members will grep
+each other by the hand (after intro), yacc a lot, smoke filtered
+chroots in pipes, chown with forks, use the wc (unless uuclean), fseek
+nice zombie processes, strip, and sleep, but not, we hope, od. Three
+days will be devoted to discussion of the ramifications of whodo. Two
+seconds have been allotted for a complete rundown of all the user-
+friendly features of Unix. Seminars include "Everything You Know is
+Wrong", led by Tom Kempson, "Batman or Cat:man?" led by Richie Dennis
+"cc C? Si! Si!" led by Kerwin Bernighan, and "Document Unix, Are You
+Kidding?" led by Jan Yeats. No Reader Service No. is necessary because
+all GUGUs (Gurus of Unix Group of Users) already know everything we
+could tell them.
+ -- Dr. Dobb's Journal, June '84
+%
+Get Revenge! Live long enough to be a problem for your children!
+%
+ -- Gifts for Children --
+
+This is easy. You never have to figure out what to get for children,
+because they will tell you exactly what they want. They spend months
+and months researching these kinds of things by watching Saturday-
+morning cartoon-show advertisements. Make sure you get your children
+exactly what they ask for, even if you disapprove of their choices. If
+your child thinks he wants Murderous Bob, the Doll with the Face You
+Can Rip Right Off, you'd better get it. You may be worried that it
+might help to encourage your child's antisocial tendencies, but believe
+me, you have not seen antisocial tendencies until you've seen a child
+who is convinced that he or she did not get the right gift.
+ -- Dave Barry, "Christmas Shopping: A Survivor's Guide"
+%
+ -- Gifts for Men --
+
+Men are amused by almost any idiot thing -- that is why professional
+ice hockey is so popular -- so buying gifts for them is easy. But you
+should never buy them clothes. Men believe they already have all the
+clothes they will ever need, and new ones make them nervous. For
+example, your average man has 84 ties, but he wears, at most, only
+three of them. He has learned, through humiliating trial and error,
+that if he wears any of the other 81 ties, his wife will probably laugh
+at him ("You're not going to wear THAT tie with that suit, are you?").
+So he has narrowed it down to three safe ties, and has gone several
+years without being laughed at. If you give him a new tie, he will
+pretend to like it, but deep inside he will hate you.
+
+If you want to give a man something practical, consider tires. More
+than once, I would have gladly traded all the gifts I got for a new set
+of tires.
+ -- Dave Barry, "Christmas Shopping: A Survivor's Guide"
+%
+ Gimmie That Old Time Religion
+We will follow Zarathustra, We will worship like the Druids,
+Zarathustra like we use to, Dancing naked in the woods,
+I'm a Zarathustra booster, Drinking strange fermented fluids,
+And he's good enough for me! And it's good enough for me!
+ (chorus) (chorus)
+
+In the church of Aphrodite,
+The priestess wears a see-through nightie,
+She's a mighty righteous sightie,
+And she's good enough for me!
+ (chorus)
+
+CHORUS: Give me that old time religion,
+ Give me that old time religion,
+ Give me that old time religion,
+ 'Cause it's good enough for me!
+%
+Ginsberg's Theorem:
+ (1) You can't win.
+ (2) You can't break even.
+ (3) You can't even quit the game.
+
+Freeman's Commentary on Ginsberg's theorem:
+ Every major philosophy that attempts to make life seem
+ meaningful is based on the negation of one part of Ginsberg's
+ Theorem. To wit:
+
+ (1) Capitalism is based on the assumption that you can win.
+ (2) Socialism is based on the assumption that you can break
+ even.
+ (3) Mysticism is based on the assumption that you can quit the
+ game.
+%
+Give me a Plumber's friend the size of the Pittsburgh dome, and a place
+to stand, and I will drain the world.
+%
+"Give me enough medals, and I'll win any war."
+ -- Napolean
+%
+Give me the Luxuries, and the Hell with the Necessities!
+%
+Give thought to your reputation. Consider changing name and moving to
+a new town.
+%
+Give your child mental blocks for Christmas.
+%
+"Given the choice between accomplishing something and just lying
+around, I'd rather lie around. No contest."
+ -- Eric Clapton
+%
+Giving up on assembly language was the apple in our Garden of Eden:
+Languages whose use squanders machine cycles are sinful. The LISP
+machine now permits LISP programmers to abandon bra and fig-leaf.
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+Glib's Fourth Law of Unreliability:
+ Investment in reliability will increase until it exceeds the
+probable cost of errors, or until someone insists on getting some
+useful work done.
+%
+Gnagloot, n.:
+ A person who leaves all his ski passes on his jacket just to
+impress people.
+ -- Rich Hall, "Sniglets"
+%
+Go 'way! You're bothering me!
+%
+Go climb a gravity well!
+%
+Go placidly amid the noise and waste, and remember what value there may
+be in owning a piece thereof.
+ -- National Lampoon, "Deteriorata"
+%
+//GO.SYSIN DD *, DOODAH, DOODAH
+%
+God did not create the world in seven days; he screwed around for six
+days and then pulled an all-nighter.
+%
+God doesn't play dice.
+ -- Albert Einstein
+%
+"God gives burdens; also shoulders"
+
+Jimmy Carter cited this Jewish saying in his concession speech at the
+end of the 1980 election. At least he said it was a Jewish saying; I
+can't find it anywhere. I'm sure he's telling the truth though; why
+would he lie about a thing like that?
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+God has intended the great to be great and the little to be little ...
+The trade unions, under the European system, destroy liberty ... I do
+not mean to say that a dollar a day is enough to support a workingman
+... not enough to support a man and five children if he insists on
+smoking and drinking beer. But the man who cannot live on bread and
+water is not fit to live! A family may live on good bread and water in
+the morning, water and bread at midday, and good bread and water at
+night!
+ -- Rev. Henry Ward Beecher
+%
+God is a comic playing to an audience that's afraid to laugh
+%
+God is a polythiest
+%
+God is Dead
+ -- Nietzsche
+Nietzsche is Dead
+ -- God
+Nietzsche is God
+ -- The Dead
+%
+God is not dead! He's alive and autographing bibles at Cody's
+%
+God is real, unless declared integer.
+%
+God is really only another artist. He invented the giraffe, the
+elephant and the cat. He has no real style, He just goes on trying
+other things.
+ -- Pablo Picasso
+%
+God is the tangential point between zero and infinity.
+ -- Alfred Jarry
+%
+God isn't dead, he just couldn't find a parking place.
+%
+God made machine language; all the rest is the work of man.
+%
+God made the Idiot for practice, and then He made the School Board
+ -- Mark Twain
+%
+God made the integers; all else is the work of Man.
+ -- Kronecker
+%
+God made the world in six days, and was arrested on the seventh.
+%
+God may be subtle, but He isn't plain mean.
+ -- Albert Einstein
+%
+God must love the Common Man; He made so many of them.
+%
+God rest ye CS students now,
+Let nothing you dismay.
+The VAX is down and won't be up,
+Until the first of May.
+The program that was due this morn,
+Won't be postponed, they say.
+
+ Oh, tidings of comfort and joy,
+ Comfort and joy,
+ Oh, tidings of comfort and joy.
+
+The bearings on the drum are gone,
+The disk is wobbling, too.
+We've found a bug in Lisp, and Algol
+Can't tell false from true.
+And now we find that we can't get
+At Berkeley's 4.2.
+
+ (chorus)
+%
+Going to church does not make a person religious, nor does going to
+school make a person educated, any more than going to a garage makes a
+person a car.
+%
+Gold, n.:
+ A soft malleable metal relatively scarce in distribution. It
+is mined deep in the earth by poor men who then give it to rich men who
+immediately bury it back in the earth in great prisons, although gold
+hasn't done anything to them.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+Goldenstern's Rules:
+ (1) Always hire a rich attorney
+ (2) Never buy from a rich salesman.
+%
+Good advice is something a man gives when he is too old to set a bad
+example.
+ -- La Rouchefoucauld
+%
+Good day for a change of scene. Repaper the bedroom wall.
+%
+Good day for overcoming obstacles. Try a steeplechase.
+%
+Good day to avoid cops. Crawl to school.
+%
+Good day to let down old friends who need help.
+%
+Good leaders being scarce, following yourself is allowed.
+%
+Good news is just life's way of keeping you off balance.
+%
+Good news. Ten weeks from Friday will be a pretty good day.
+%
+Good night to spend with family, but avoid arguments with your mate's
+new lover.
+%
+"Good-bye. I am leaving because I am bored."
+ -- George Saunders' dying words
+%
+Gordon's first law:
+ If a research project is not worth doing, it is not worth doing
+well.
+%
+"Gosh that takes me back ... or forward. That's the trouble with time
+travel, you never can tell."
+ -- Dr. Who
+%
+Gosh that takes me back... or is it forward? That's the trouble with
+time travel, you never can tell."
+ -- Doctor Who "Androids of Tara"
+%
+Got Mole problems?
+Call Avogardo 6.02 x 10^23
+%
+Goto, n.:
+ A programming tool that exists to allow structured programmers
+to complain about unstructured programmers.
+ -- Ray Simard
+%
+Government [is] an illusion the governed should not encourage.
+ -- John Updike, "Couples"
+%
+Government lies, and newspapers lie, but in a democracy they are
+different lies.
+%
+Government spending? I don't know what it's all about. I don't know
+any more about this thing than an economist does, and, God knows, he
+doesn't know much.
+ -- Will Rogers
+%
+Grabel's Law:
+ 2 is not equal to 3 -- not even for large values of 2.
+%
+Graduate life -- it's not just a job, it's an indenture.
+%
+Graduate life: It's not just a job. It's an indenture.
+%
+Grandpa Charnock's Law:
+ You never really learn to swear until you learn to drive.
+%
+Gravity is a myth, the Earth sucks.
+%
+Gray's Law of Programming:
+ `_n+1' trivial tasks are expected to be accomplished in the same
+time as `_n' tasks.
+
+Logg's Rebuttal to Gray's Law:
+ `_n+1' trivial tasks take twice as long as `_n' trivial tasks.
+%
+Great minds run in great circles.
+%
+ GREAT MOMENTS IN AMERICAN HISTORY #21 -- July 30, 1917
+
+On this day, New York City hotel detectives burst in and caught then-
+Senator Warren G. Harding in bed with an underage girl. He bought them
+off with a $20 bribe, and later remarked thankfully, "I thought I
+wouldn't get out of that under $1000!" Always one to learn from his
+mistakes, in later years President Harding carried on his affairs in a
+tiny closet in the White House Cabinet Room while Secret Service men
+stood lookout.
+%
+Green light in a.m. for new projects. Red light in P.M. for traffic
+tickets.
+%
+Greener's Law:
+ Never argue with a man who buys ink by the barrel.
+%
+Grelb's Reminder:
+ Eighty percent of all people consider themselves to be above
+average drivers.
+%
+"Grub first, then ethics."
+ -- Bertolt Brecht
+%
+Gurmlish, n.:
+ The red warning flag at the top of a club sandwich which
+prevents the person from biting into it and puncturing the roof of his
+mouth.
+ -- Rich Hall & Friends, "Sniglets"
+%
+Gyroscope, n.:
+ A wheel or disk mounted to spin rapidly about an axis and also
+free to rotate about one or both of two axes perpendicular to each
+other and the axis of spin so that a rotation of one of the two
+mutually perpendicular axes results from application of torque to the
+other when the wheel is spinning and so that the entire apparatus
+offers considerable opposition depending on the angular momentum to any
+torque that would change the direction of the axis of spin.
+ -- Webster's Seventh New Collegiate Dictionary
+%
+H. L. Mencken suffers from the hallucination that he is H. L.
+Mencken -- there is no cure for a disease of that magnitude.
+ -- Maxwell Bodenheim
+%
+H. L. Mencken's Law:
+ Those who can -- do.
+ Those who can't -- teach.
+
+Martin's Extension:
+ Those who cannot teach -- administrate.
+%
+H: If a 'GOBLIN (HOB) waylays you,
+ Slice him up before he slays you.
+ Nothing makes you look a slob
+ Like running from a HOB'LIN (GOB).
+ -- The Roguelet's ABC
+%
+Hacker's Law:
+ The belief that enhanced understanding will necessarily stir a
+nation to action is one of mankind's oldest illusions.
+%
+Hacking's just another word for nothing left to kludge.
+%
+... Had this been an actual emergency, we would have fled in terror,
+and you would not have been informed.
+%
+Hail to the sun god
+He sure is a fun god
+Ra! Ra! Ra!
+%
+Hain't we got all the fools in town on our side? And hain't that a big
+enough majority in any town?
+ -- Mark Twain, "Huckleberry Finn"
+%
+Half Moon tonight. (At least it's better than no Moon at all.)
+%
+Half-done:
+ This is the best way to eat a kosher dill -- when it's still
+crunchy, light green, yet full of garlic flavor. The difference
+between this and the typical soggy dark green cucumber corpse is like
+the difference between life and death.
+ You may find it difficult to find a good half-done kosher dill
+there in Seattle, so what you should do is take a cab out to the
+airport, fly to New York, take the JFK Express to Jay Street-Borough
+Hall, transfer to an uptown F, get off at East Broadway, walk north on
+Essex (along the park), make your first left onto Hester Street, walk
+about fifteen steps, turn ninety degrees left, and stop. Say to the
+man, "Let me have a nice half-done."
+ Worth the trouble, wasn't it?
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+Hall's Laws of Politics:
+ (1) The voters want fewer taxes and more spending.
+ (2) Citizens want honest politicians until they want something
+ fixed.
+ (3) Constituency drives out consistency (i.e., liberals defend
+ military spending, and conservatives social spending in
+ their own districts).
+%
+Hand, n.:
+ A singular instrument worn at the end of a human arm and
+commonly thrust into somebody's pocket.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Hanlon's Razor:
+ Never attribute to malice that which is adequately explained by
+stupidity.
+%
+Hanson's Treatment of Time:
+ There are never enough hours in a day, but always too many days
+before Saturday.
+%
+Happiness is having a scratch for every itch.
+ -- Ogden Nash
+%
+Happiness isn't something you experience; it's something you remember.
+ -- Oscar Levant
+%
+Happiness, n.:
+ An agreeable sensation arising from contemplating the misery of
+another.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Hard work may not kill you, but why take chances?
+%
+Hardware, n.:
+ The parts of a computer system that can be kicked.
+%
+Hark ye, Clinker, you are a most notorious offender. You stand
+convicted of sickness, hunger, wretchedness, and want.
+ -- Tobias Smollet
+%
+Hark, Hark, the dogs do bark
+The Duke is fond of kittens
+He likes to take their insides out
+And use them for his mittens
+ From "The Thirteen Clocks"
+%
+Hark, the Herald Tribune sings,
+Advertising wondrous things.
+ -- Tom Lehrer
+%
+Harris's Lament:
+ All the good ones are taken.
+%
+Harrisberger's Fourth Law of the Lab:
+ Experience is directly proportional to the amount of equipment
+ruined.
+%
+Harry is heavily into camping, and every year in the late fall, he
+makes us all go to Assateague, which is an island on the Atlantic Ocean
+famous for its wild horses. I realize that the concept of wild horses
+probably stirs romantic notions in many of you, but this is because you
+have never met any wild horses in person. In person, they are like
+enormous hooved rats. They amble up to your camp site, and their
+attitude is: "We're wild horses. We're going to eat your food, knock
+down your tent and poop on your shoes. We're protected by federal law,
+just like Richard Nixon."
+ -- Dave Barry, "Tenting Grandpa Bob"
+%
+Hartley's First Law:
+ You can lead a horse to water, but if you can get him to float
+on his back, you've got something.
+%
+Hartley's Second Law:
+ Never sleep with anyone crazier than yourself.
+%
+Harvard Law:
+ Under the most rigorously controlled conditions of pressure,
+temperature, volume, humidity, and other variables, the organism will
+do as it damn well pleases.
+%
+"Has anyone had problems with the computer accounts?"
+"Yes, I don't have one."
+"Okay, you can send mail to one of the tutors ..."
+ -- E. D'Azevedo, Computer Science 372
+%
+Has everyone noticed that all the letters of the word "database" are
+typed with the left hand? Now the layout of the QWERTYUIOP typewriter
+keyboard was designed, among other things, to facilitate the even use
+of both hands. It follows, therefore, that writing about databases is
+not only unnatural, but a lot harder than it appears.
+%
+ Has your family tried 'em?
+
+ POWDERMILK BISCUITS
+
+ Heavens, they're tasty and expeditious!
+
+ They're made from whole wheat, to give shy persons the
+ strength to get up and do what needs to be done.
+
+ POWDERMILK BISCUITS
+
+ Buy them ready-made in the big blue box with the picture of the
+ biscuit on the front, or in the brown bag with the dark stains
+ that indicate freshness.
+%
+Hatred, n.:
+ A sentiment appropriate to the occasion of another's
+superiority.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Have an adequate day.
+%
+Have an adequate day.
+%
+Have people realized that the purpose of the fortune cookie program is
+to defuse project tensions? When did you ever see a cheerful cookie, a
+non-cynical, or even an informative cookie?
+
+Perhaps inadvertently, we have a channel for our aggressions. This
+still begs the question of whether the cookie releases the pressure or
+only serves to blunt the warning signs.
+
+ Long live the revolution!
+ Have a nice day.
+%
+Have you ever noticed that the people who are always trying to tell
+you, "There's a time for work and a time for play," never find the time
+for play?
+%
+Have you ever wondered what makes Californians so calm? Besides drugs,
+I mean. The answer is hot tubs. A hot tub is a redwood container
+filled with water that you sit in naked with members of the opposite
+sex, none of whom is necessarily your spouse. After a few hours in
+their hot tubs, Californians don't give a damn about earthquakes or
+mass murderers. They don't give a damn about anything , which is why
+they are able to produce "Laverne and Shirley" week after week.
+ -- Dave Barry, "The Taming of the Screw"
+%
+"Have you lived here all your life?"
+"Oh, twice that long."
+%
+Have you noticed that all you need to grow healthy, vigorous grass is a
+crack in your sidewalk?
+%
+Have you noticed the way people's intelligence capabilities decline
+sharply the minute they start waving guns around?
+ -- Dr. Who
+%
+Have you reconsidered a computer career?
+%
+"He did decide, though, that with more time and a great deal of mental
+effort, he could probably turn the activity into an acceptable
+perversion."
+ -- Mick Farren, "When Gravity Fails"
+%
+"He flung himself on his horse and rode madly off in all directions"
+%
+He had occasional flashes of silence that made his conversation
+perfectly delightful.
+ -- Sydney Smith
+%
+He had that rare weird electricity about him -- that extremely wild and
+heavy presence that you only see in a person who has abandoned all hope
+of ever behaving "normally."
+ -- Hunter S. Thompson, "Fear and Loathing '72"
+%
+He hadn't a single redeeming vice.
+ -- Oscar Wilde
+%
+"He is now rising from affluence to poverty."
+ -- Mark Twain
+%
+He looked at me as if I was a side dish he hadn't ordered.
+%
+He played the king as if afraid someone else would play the ace.
+ -- John Mason Brown, drama critic
+%
+He thought he saw an albatross
+That fluttered 'round the lamp.
+He looked again and saw it was
+A penny postage stamp.
+"You'd best be getting home," he said,
+"The nights are rather damp."
+%
+He was a fiddler, and consequently a rogue.
+ -- Jonathon Swift
+%
+"He was a modest, good-humored boy. It was Oxford that made him
+insufferable."
+%
+"He was so narrow minded he could see through a keyhole with both
+eyes ..."
+%
+He who attacks the fundamentals of the American broadcasting industry
+attacks democracy itself.
+ -- William S. Paley, chairman of CBS
+%
+He who Laughs, Lasts.
+%
+"He's just a politician trying to save both his faces ..."
+%
+He's the kind of guy, that, well, if you were ever in a jam he'd be
+there ... with two slices of bread and some chunky peanut butter.
+%
+"He's the kind of man for the times that need the kind of man he is ..."
+%
+HE: Let's end it all, bequeathin' our brains to science.
+SHE: What?!? Science got enough trouble with their ___OWN brains.
+ -- Walt Kelley
+%
+Health is merely the slowest possible rate at which one can die.
+%
+Health nuts are going to feel stupid someday, lying in hospitals dying
+of nothing.
+ -- Redd Foxx
+%
+Health nuts are going to feel stupid someday, lying in hospitals dying
+of nothing.
+ -- Redd Foxx
+%
+Heaven, n.:
+ A place where the wicked cease from troubling you with talk of
+their personal affairs, and the good listen with attention while you
+expound your own.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Heavy, adj.:
+ Seduced by the chocolate side of the force.
+%
+"Heisenberg may have slept here"
+%
+Hell hath no fury like a bureaucrat scorned.
+ -- Milton Friedman
+%
+Heller's Law:
+ The first myth of management is that it exists.
+
+Johnson's Corollary:
+ Nobody really knows what is going on anywhere within the
+organization.
+%
+"Hello," he lied.
+ -- Don Carpenter quoting a Hollywood agent
+%
+Help a swallow land at Capistrano.
+%
+Help fight continental drift.
+%
+Help me, I'm a prisoner in a Fortune cookie file!
+%
+Help stamp out and abolish redundancy.
+%
+Help! I'm trapped in a PDP 11/70!
+%
+HELP! MY TYPEWRITER IS BROKEN!
+ -- E. E. CUMMINGS
+%
+Her locks an ancient lady gave
+Her loving husband's life to save;
+And men -- they honored so the dame --
+Upon some stars bestowed her name.
+
+But to our modern married fair,
+Who'd give their lords to save their hair,
+No stellar recognition's given.
+There are not stars enough in heaven.
+%
+"Here at the Phone Company, we serve all kinds of people; from
+Presidents and Kings to the scum of the earth ..."
+%
+Here I sit, broken-hearted,
+All logged in, but work unstarted.
+First net.this and net.that,
+And a hot buttered bun for net.fat.
+
+The boss comes by, and I play the game,
+Then I turn back to net.flame.
+Is there a cure (I need your views),
+For someone trapped in net.news?
+
+I need your help, I say 'tween sobs,
+'Cause I'll soon be listed in net.jobs.
+%
+Here in my heart, I am Helen;
+ I'm Aspasia and Hero, at least.
+I'm Judith, and Jael, and Madame de Sta"el;
+ I'm Salome, moon of the East.
+
+Here in my soul I am Sappho;
+ Lady Hamilton am I, as well.
+In me R'ecamier vies with Kitty O'Shea,
+ With Dido, and Eve, and poor nell.
+
+I'm all of the glamorous ladies
+ At whose beckoning history shook.
+But you are a man, and see only my pan,
+ So I stay at home with a book.
+ -- Dorothy Parker
+%
+Here is a simple experiment that will teach you an important electrical
+lesson: On a cool, dry day, scuff your feet along a carpet, then reach
+your hand into a friend's mouth and touch one of his dental fillings.
+Did you notice how your friend twitched violently and cried out in
+pain? This teaches us that electricity can be a very powerful force,
+but we must never use it to hurt others unless we need to learn an
+important electrical lesson.
+
+It also teaches us how an electrical circuit works. When you scuffed
+your feet, you picked up batches of "electrons", which are very small
+objects that carpet manufacturers weave into carpets so they will
+attract dirt. The electrons travel through your bloodstream and
+collect in your finger, where they form a spark that leaps to your
+friend's filling, then travels down to his feet and back into the
+carpet, thus completing the circuit.
+
+Amazing Electronic Fact: If you scuffed your feet long enough without
+touching anything, you would build up so many electrons that your
+finger would explode! But this is nothing to worry about unless you
+have carpeting.
+ -- Dave Barry, "What is Electricity?"
+%
+ Here is the fact of the week, maybe even the fact of the
+month. According to probably reliable sources, the Coca-Cola people
+are experiencing severe marketing anxiety in China.
+ The words "Coca-Cola" translate into Chinese as either
+(depending on the inflection) "wax-fattened mare" or "bite the wax
+tadpole".
+ Bite the wax tadpole.
+ There is a sort of rough justice, is there not?
+ The trouble with this fact, as lovely as it is, is that it's
+hard to get a whole column out of it. I'd like to teach the world to
+bite a wax tadpole. Coke -- it's the real wax-fattened mare. Not bad,
+but broad satiric vistas do not open up.
+ -- John Carrol, San Francisco Chronicle
+%
+"Here's something to think about: How come you never see a headline like
+`Psychic Wins Lottery'?"
+ -- Jay Leno
+%
+Heuristics are bug ridden by definition. If they didn't have bugs,
+then they'd be algorithms.
+%
+"Hey! Who took the cork off my lunch??!"
+ -- W. C. Fields
+%
+Hi there! This is just a note from me, to you, to tell you, the person
+reading this note, that I can't think up any more famous quotes, jokes,
+nor bizarre stories, so you may as well go home.
+%
+"Hi, I'm Preston A. Mantis, president of Consumers Retail Law Outlet.
+As you can see by my suit and the fact that I have all these books of
+equal height on the shelves behind me, I am a trained legal attorney.
+Do you have a car or a job? Do you ever walk around? If so, you
+probably have the makings of an excellent legal case. Although of
+course every case is different, I would definitely say that based on my
+experience and training, there's no reason why you shouldn't come out
+of this thing with at least a cabin cruiser.
+
+"Remember, at the Preston A. Mantis Consumers Retail Law Outlet, our
+motto is: 'It is very difficult to disprove certain kinds of pain.'"
+ -- Dave Barry, "Pain and Suffering"
+%
+Hier liegt ein Mann ganz obnegleich;
+Im Leibe dick, an Suden reich.
+Wir haben ihn in das Grab gesteckt, Here lies a man with sundry flaws
+Weil es uns dunkt er sei verreckt. And numerous Sins upon his head;
+ We buried him today because
+ As far as we can tell, he's dead.
+ -- PDQ Bach's epitaph, as requested by his cousin Betty
+ Sue Bach and written by the local doggerel catcher;
+ "The Definitive Biography of PDQ Bach", Peter
+ Schickele
+%
+Higgeldy Piggeldy,
+Hamlet of Elsinore
+Ruffled the critics by
+Dropping this bomb:
+"Phooey on Freud and his
+Psychoanalysis --
+Oedipus, Shmoedipus,
+I just love Mom."
+%
+Hindsight is an exact science.
+%
+Hippogriff, n.:
+ An animal (now extinct) which was half horse and half griffin.
+The griffin was itself a compound creature, half lion and half eagle.
+The hippogriff was actually, therefore, only one quarter eagle, which
+is two dollars and fifty cents in gold. The study of zoology is full
+of surprises.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Hire the morally handicapped.
+%
+"His great aim was to escape from civilization, and, as soon as he had
+money, he went to Southern California."
+%
+"His mind is like a steel trap -- full of mice"
+ -- Foghorn Leghorn
+%
+"His super power is to turn into a scotch terrier."
+%
+History is curious stuff
+ You'd think by now we had enough
+Yet the fact remains I fear
+ They make more of it every year.
+%
+History repeats itself. That's one thing wrong with history.
+%
+History, n.:
+ Papa Hegel he say that all we learn from history is that we
+learn nothing from history. I know people who can't even learn from
+what happened this morning. Hegel must have been taking the long
+view.
+ -- Chad C. Mulligan, "The Hipcrime Vocab"
+%
+Hlade's Law:
+ If you have a difficult task, give it to a lazy person -- they
+will find an easier way to do it.
+%
+Hoare's Law of Large Problems:
+ Inside every large problem is a small problem struggling to get
+out.
+%
+Hofstadter's Law:
+ It always takes longer than you expect, even when you take
+Hofstadter's Law into account.
+%
+Hollywood is where if you don't have happiness you send out for it.
+ -- Rex Reed
+%
+ Home centers are designed for the do-it-yourselfer who's
+willing to pay higher prices for the convenience of being able to shop
+for lumber, hardware, and toasters all in one location. Notice I say
+"shop for", as opposed to "obtain". This is the major drawback of home
+centers: they are always out of everything except artificial Christmas
+trees. The home center employees have no time to reorder merchandise
+because they are too busy applying little price stickers to every
+object -- every board, washer, nail and screw -- in the entire store ...
+ Let's say a piece in your toilet tank breaks, so you remove the
+broken part, take it to the home center, and ask an employee if he has
+a replacement. The employee, who has never is his life even seen the
+inside of a toilet tank, will peer at the broken part in very much the
+same way that a member of a primitive Amazon jungle tribe would look at
+an electronic calculator, and then say, "We're expecting a shipment of
+these sometime around the middle of next week".
+ -- Dave Barry, "The Taming of the Screw"
+%
+Home of Doberman Propulsion Laboratories:
+The ultimate in watchdog weaponry.
+ -- Chris Shaw
+%
+"Honesty is the best policy, but insanity is a better defense"
+%
+Honesty pays, but it doesn't seem to pay enough to suit some people.
+ -- F. M. Hubbard
+%
+Honk if you hate bumper stickers that say "Honk if ..."
+%
+Honk if you love peace and quiet.
+%
+Honorable, adj.:
+ Afflicted with an impediment in one's reach. In legislative
+bodies, it is customary to mention all members as honorable; as, "the
+honorable gentleman is a scurvy cur."
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Horngren's Observation:
+ Among economists, the real world is often a special case.
+%
+Horse sense is the thing a horse has which keeps it from betting on
+people.
+ -- W. C. Fields
+%
+Horses are forbidden to eat fire hydrants in Marshalltown, Iowa.
+%
+"Houston, Tranquillity Base here. The Eagle has landed."
+ -- Neil Armstrong
+%
+How can you be in two places at once when you're not anywhere at all?
+%
+How come only your friends step on your new white sneakers?
+%
+How come wrong numbers are never busy?
+%
+"How do I love thee? My accumulator overflows."
+%
+How do you explain school to a higher intelligence?
+ -- Elliot, "E.T."
+%
+How doth the little crocodile
+ Improve his shining tail,
+And pour the waters of the Nile
+ On every golden scale!
+
+How cheerfully he seems to grin,
+ How neatly spreads his claws,
+And welcomes little fishes in,
+ With gently smiling jaws!
+ -- Lewis Carrol, "Alice in Wonderland"
+%
+How doth the VAX's C compiler
+Improve its object code.
+And even as we speak does it
+Increase the system load.
+
+How patiently it seems to run
+And spit out error flags,
+While users, with frustration, all
+Tear their clothes to rags.
+%
+How doth the VAX's C-compiler
+Improve its object code.
+And even as we speak does it
+Increase the system load.
+
+How patiently it seems to run
+And spit out error flags,
+While users, with frustration, all
+Tear all their clothes to rags.
+%
+How long a minute is depends on which side of the bathroom door you're
+on.
+%
+How many hardware engineers does it take to change a lightbulb?
+None: "We'll fix it in software."
+
+How many software engineers does it take to change a lightbulb?
+None: "We'll document it in the manual."
+
+How many tech writers does it take to change a lightbulb?
+None: "The user can work it out."
+%
+"How many hors d'oeuvres you are allowed to take off a tray being
+carried by a waiter at a nice party?"
+
+Two, but there are ways around it, depending on the style of the hors
+d'oeuvre. If they're those little pastry things where you can't tell
+what's inside, you take one, bite off about two-thirds of it, then
+say: "This is cheese! I hate cheese!" Then you put the rest of it
+back on the tray and bite another one and go, "Darn it! Another
+cheese!" and so on.
+ -- Dave Barry, "The Stuff of Etiquette"
+%
+ How many seconds are there in a year? If I tell you there are
+3.155 x 10^7, you won't even try to remember it. On the other hand,
+who could forget that, to within half a percent, pi seconds is a
+nanocentury.
+ -- Tom Duff, Bell Labs
+%
+How much does it cost to entice a dope-smoking UNIX system guru to
+Dayton?
+ -- Brian Boyle, UNIX/WORLD's First Annual Salary Survey
+%
+How wonderful opera would be if there were no singers.
+%
+How wonderful opera would be if there were no singers.
+%
+HOW YOU CAN TELL THAT IT'S GOING TO BE A ROTTEN DAY:
+ #1040 Your income tax refund cheque bounces.
+%
+HOW YOU CAN TELL THAT IT'S GOING TO BE A ROTTEN DAY:
+ #15 Your pet rock snaps at you.
+%
+HOW YOU CAN TELL THAT IT'S GOING TO BE A ROTTEN DAY:
+
+ #32: You call your answering service and they've never heard of
+ you.
+%
+Howe's Law:
+ Everyone has a scheme that will not work.
+%
+However, never daunted, I will cope with adversity in my traditional
+manner ... sulking and nausea.
+ -- Tom K. Ryan
+%
+HR 3128. Omnibus Budget Reconciliation, Fiscal 1986. Martin, R-Ill.,
+motion that the House recede from its disagreement to the Senate
+amendment making changes in the bill to reduce fiscal 1986 deficits.
+The Senate amendment was an amendment to the House amendment to the
+Senate amendment to the House amendment to the Senate amendment to the
+bill. The original Senate amendment was the conference agreement on
+the bill. Agreed to.
+ -- Albuquerque Journal
+%
+ Hug O' War
+
+I will not play at tug o' war.
+I'd rather play at hug o' war,
+Where everyone hugs
+Instead of tugs,
+Where everyone giggles
+And rolls on the rug,
+Where everyone kisses,
+And everyone grins,
+And everyone cuddles,
+And everyone wins.
+ -- Shel Silverstein
+%
+Human beings were created by water to transport it uphill.
+%
+Human cardiac catheterization was introduced by Werner Forssman in
+1929. Ignoring his department chief, and tying his assistant to an
+operating table to prevent his interference, he placed a uretheral
+catheter into a vein in his arm, advanced it to the right atrium [of
+his heart], and walked upstairs to the x-ray department where he took
+the confirmatory x-ray film. In 1956, Dr. Forssman was awarded the
+Nobel Prize.
+%
+Hummingbirds never remember the words to songs.
+%
+"Humor is a drug which it's the fashion to abuse."
+ -- William Gilbert
+%
+Hurewitz's Memory Principle:
+ The chance of forgetting something is directly proportional
+to ..... to ........ uh ..............
+%
+I also believe that academic freedom should protect the right of a
+professor or student to advocate Marxism, socialism, communism, or any
+other minority viewpoint -- no matter how distasteful to the majority.
+ -- Richard M. Nixon
+
+What are our schools for if not indoctrination against Communism?
+ -- Richard M. Nixon
+%
+"I am convinced that the manufacturers of carpet odor removing powder
+have included encapsulated time released cat urine in their products.
+This technology must be what prevented its distribution during my mom's
+reign. My carpet smells like piss, and I don't have a cat. Better go
+by some more."
+ -- timw@zeb.USWest.COM
+%
+I am more bored than you could ever possibly be. Go back to work.
+%
+"I am not an Economist. I am an honest man!"
+ -- Paul McCracken
+%
+"I am not now, and never have been, a girlfriend of Henry Kissinger."
+ -- Gloria Steinem
+%
+I am not now, nor have I ever been, a member of the demigodic party.
+ -- Dennis Ritchie
+%
+"I am not sure what this is, but an `F' would only dignify it."
+ -- English Professor
+%
+"I am ready to meet my Maker. Whether my Maker is prepared for the
+great ordeal of meeting me is another matter."
+ -- Winston Churchill
+%
+"I am returning this otherwise good typing paper to you because someone
+has printed gibberish all over it and put your name at the top."
+ -- English Professor, Ohio University
+%
+I am so optimistic about beef prices that I've just leased a pot roast
+with an option to buy.
+%
+"I am the mother of all things, and all things should wear a sweater."
+%
+"I am, in point of fact, a particularly haughty and exclusive person,
+of pre-Adamite ancestral descent. You will understand this when I tell
+you that I can trace my ancestry back to a protoplasmal primordial
+atomic globule. Consequently, my family pride is something
+inconceivable. I can't help it. I was born sneering."
+ -- Pooh-Bah, "The Mikado", Gilbert & Sullivan
+%
+"I appreciate the fact that this draft was done in haste, but some of
+the sentences that you are sending out in the world to do your work for
+you are loitering in taverns or asleep beside the highway."
+ -- Dr. Dwight Van de Vate, Professor of Philosophy,
+ University of Tennessee at Knoxville
+%
+"I argue very well. Ask any of my remaining friends. I can win an
+argument on any topic, against any opponent. People know this, and
+steer clear of me at parties. Often, as a sign of their great respect,
+they don't even invite me."
+ -- Dave Barry
+%
+'I believe in getting into hot water; it keeps you clean."
+ -- G. K. Chesterton
+%
+"I belong to no organized party. I am a Democrat."
+ -- Will Rogers
+%
+"I bet the human brain is a kludge."
+ -- Marvin Minsky
+%
+I brake for chezlogs!
+%
+I call them as I see them. If I can't see them, I make them up.
+ -- Biff Barf
+%
+I can feel for her because, although I have never been an Alaskan
+prostitute dancing on the bar in a spangled dress, I still get very
+bored with washing and ironing and dishwashing and cooking day after
+relentless day.
+ -- Betty MacDonald
+%
+I can read your mind, and you should be ashamed of yourself.
+%
+"I can remember when a good politician had to be 75 percent ability and
+25 percent actor, but I can well see the day when the reverse could be
+true."
+ -- Harry Truman
+%
+"I can resist anything but temptation."
+%
+"I can't complain, but sometimes I still do."
+ -- Joe Walsh
+%
+"I can't decide whether to commit suicide or go bowling."
+ -- Florence Henderson
+%
+I can't understand it. I can't even understand the people who can
+understand it.
+ -- Queen Juliana of the Netherlands.
+%
+I can't understand why a person will take a year or two to write a
+novel when he can easily buy one for a few dollars.
+ -- Fred Allen
+%
+"I cannot and will not cut my conscience to fit this year's fashions."
+ -- Lillian Hellman
+%
+I cannot conceive that anybody will require multiplications at the rate
+of 40,000 or even 4,000 per hour ...
+ -- F. H. Wales (1936)
+%
+I cannot overemphasize the importance of good grammar.
+
+What a crock. I could easily overemphasize the importance of good
+grammar. For example, I could say: "Bad grammar is the leading cause
+of slow, painful death in North America," or "Without good grammar, the
+United States would have lost World War II."
+ -- Dave Barry, "An Utterly Absurd Look at Grammar"
+%
+ "I cannot read the fiery letters," said Frodo in a quavering
+voice.
+ "No," Said Gandalf, "but I can. The letters are Elvish, of
+course, of an ancient mode, but the language is that of Mordor, which
+I will not utter here. They are lines of a verse long known in
+Elven-lore:
+
+ "This Ring, no other, is made by the elves,
+ Who'd pawn their own mother to grab it themselves.
+ Ruler of creeper, mortal, and scallop,
+ This is a sleeper that packs quite a wallop.
+ The Power almighty rests in this Lone Ring.
+ The Power, alrighty, for doing your Own Thing.
+ If broken or busted, it cannot be remade.
+ If found, send to Sorhed (with postage prepaid)."
+%
+" I changed my headlights the other day. I put in strobe lights
+instead! Now when I drive at night, it looks like everyone else is
+standing still ..."
+ -- Steven Wright
+%
+I could dance till the cows come home. On second thought, I'd rather
+dance with the cows till you come home.
+ -- Groucho Marx
+%
+"I couldn't remember when I had been so disappointed. Except perhaps
+the time I found out that M&Ms really *do* melt in your hand ..."
+ -- Peter Oakley
+%
+"I didn't know it was impossible when I did it."
+%
+I didn't like the play, but I saw it under adverse conditions. The
+curtain was up.
+%
+ I disapprove of the F-word, not because it's dirty, but because
+we use it as a substitute for thoughtful insults, and it frequently
+leads to violence. What we ought to do, when we anger each other, say,
+in traffic, is exchange phone numbers, so that later on, when we've had
+time to think of witty and learned insults or look them up in the
+library, we could call each other up:
+
+ You: Hello? Bob?
+ Bob: Yes?
+ You: This is Ed. Remember? The person whose parking space you
+ took last Thursday? Outside of Sears?
+ Bob: Oh yes! Sure! How are you, Ed?
+ You: Fine, thanks. Listen, Bob, the reason I'm calling is:
+ "Madam, you may be drunk, but I am ugly, and ..." No, wait.
+ I mean: "you may be ugly, but I am Winston Churchill
+ and ..." No, wait. (Sound of reference book thudding onto
+ the floor.) S-word. Excuse me. Look, Bob, I'm going to
+ have to get back to you.
+ Bob: Fine.
+ -- Dave Barry, "$#$%#^%!^%&@%@!"
+%
+I do hate sums. There is no greater mistake than to call arithmetic an
+exact science. There are permutations and aberrations discernible to
+minds entirely noble like mine; subtle variations which ordinary
+accountants fail to discover; hidden laws of number which it requires a
+mind like mine to perceive. For instance, if you add a sum from the
+bottom up, and then again from the top down, the result is always
+different.
+ -- Mrs. La Touche (19th cent.)
+%
+"I do not fear computers. I fear the lack of them."
+ -- Isaac Asimov
+%
+"I do not feel obliged to believe that the same God who has endowed us
+with sense, reason, and intellect has intended us to forego their use."
+ -- Galileo Galilei
+%
+"I do not know myself, and God forbid that I should."
+ -- Johann Wolfgang von Goethe
+%
+"I don't believe in astrology. But then I'm an Aquarius, and Aquarians
+don't believe in astrology."
+ -- James R. F. Quirk
+%
+I don't believe there really IS a GAS SHORTAGE.. I think it's all just
+a BIG HOAX on the part of the plastic sign salesmen -- to sell more
+numbers!!
+%
+I don't care for the Sugar Smacks commercial. I don't like the idea of
+a frog jumping on my Breakfast.
+ -- Lowell, Chicago Reader 10/15/82
+%
+"I don't care who does the electing as long as I get to do the
+nominating"
+ -- Boss Tweed
+%
+"I don't have any solution but I certainly admire the problem."
+ -- Ashleigh Brilliant
+%
+"I don't have to take this abuse from you -- I've got hundreds of
+people waiting to abuse me."
+ -- Bill Murray, "Ghostbusters"
+%
+I don't know anything about music. In my line you don't have to.
+ -- Elvis Presley
+%
+"I don't know anything about music. In my line you don't have to."
+ -- Elvis Presley
+%
+ "I don't know what you mean by `glory,'" Alice said
+ Humpty Dumpty smiled contemptuously. "Of course you don't --
+till I tell you. I meant `there's a nice knock-down argument for
+you!'"
+ "But glory doesn't mean `a nice knock-down argument,'" Alice
+objected.
+ "When I use a word," Humpty Dumpty said, in a rather scornful
+tone, "it means just what I choose it to mean -- neither more nor
+less."
+ "The question is," said Alice, "whether you can make words mean
+so many different things."
+ "The question is," said Humpty Dumpty, "which is to be master--
+that's all."
+ -- Lewis Carrol, "Through the Looking Glass"
+%
+"I don't like spinach, and I'm glad I don't, because if I liked it I'd
+eat it, and I just hate it."
+ -- Clarence Darrow
+%
+"I don't mind going nowhere as long as it's an interesting path."
+ -- Ronald Mabbitt
+%
+I don't mind what Congress does, as long as they don't do it in the
+streets and frighten the horses.
+ -- Victor Hugo
+%
+"I don't object to sex before marriage, but two minutes before?!?"
+%
+"I don't think so," said Ren'e Descartes. Just then, he vanished.
+%
+"I don't think they could put him in a mental hospital. On the other
+hand, if he were already in, I don't think they'd let him out."
+%
+I don't want to alarm anybody, but there is an excellent chance that
+the Earth will be destroyed in the next several days. Congress is
+thinking about eliminating a federal program under which scientists
+broadcast signals to alien beings. This would be a large mistake.
+Alien beings have nuclear blaster death cannons. You cannot cut off
+their federal programs as if they were merely poor people ...
+ -- Davy Barry, "THE ALIENS ARE COMING, THE ALIENS ARE
+ COMING!"
+%
+I doubt, therefore I might be.
+%
+"I dread success. To have succeeded is to have finished one's business
+on earth, like the male spider, who is killed by the female the moment
+he has succeeded in his courtship. I like a state of continual
+becoming, with a goal in front and not behind."
+ -- George Bernard Shaw
+%
+"I drink to make other people interesting."
+ -- George Jean Nathan
+%
+I fell asleep reading a dull book, and I dreamt that I was reading on,
+so I woke up from sheer boredom.
+%
+I for one cannot protest the recent M.T.A. fare hike and the
+accompanying promises that this would in no way improve service. For
+the transit system, as it now operates, has hidden advantages that
+can't be measured in monetary terms.
+
+Personally, I feel that it is well worth 75 cents or even $1 to have
+that unimpeachable excuse whenever I am late to anything: "I came by
+subway." Those four words have such magic in them that if Godot should
+someday show up and mumble them, any audience would instantly
+understand his long delay.
+%
+"I found out why my car was humming. It had forgotten the words."
+%
+"I gained nothing at all from Supreme Enlightenment, and for that very
+reason it is called Supreme Enlightenment."
+ -- Gotama Buddha
+%
+I gave up Smoking, Drinking and Sex. It was the most *__________horrifying* 20
+minutes of my life!
+%
+'I generally avoid temptation unless I can't resist it."
+ -- Mae West
+%
+I get up each morning, gather my wits.
+ Pick up the paper, read the obits.
+If I'm not there I know I'm not dead.
+ So I eat a good breakfast and go back to bed.
+%
+I get up each morning, gather my wits.
+Pick up the paper, read the obits.
+If I'm not there I know I'm not dead.
+So I eat a good breakfast and go back to bed.
+
+Oh, how do I know my youth is all spent?
+My get-up-and-go has got-up-and-went.
+But in spite of it all, I'm able to grin,
+And think of the places my get-up has been.
+ -- Pete Seeger
+%
+"I had to censor everything my sons watched ... even on the Mary Tyler
+Moore show I heard the word 'damn'!"
+ -- Mary Lou Bax
+%
+"I had to hit him -- he was starting to make sense."
+%
+"I hate it when my foot falls asleep during the day cause that means
+it's going to be up all night."
+ -- Steven Wright
+%
+"I hate quotations."
+ -- Ralph Waldo Emerson
+%
+I have a simple philosophy:
+
+ Fill what's empty.
+ Empty what's full.
+ Scratch where it itches.
+ -- A. R. Longworth
+%
+"I have a very firm grasp on reality! I can reach out and strangle it
+any time!"
+%
+"I have come up with a sure-fire concept for a hit television show,
+which would be called `A Live Celebrity Gets Eaten by a Shark'."
+ -- Dave Barry, "The Wonders of Sharks on TV"
+%
+I have discovered the art of deceiving diplomats. I tell them the truth
+and they never believe me.
+ -- Camillo Di Cavour
+%
+I have great faith in fools -- self confidence my friends call it.
+ -- Edgar Allan Poe
+%
+"I have just read your lousy review buried in the back pages. You
+sound like a frustrated old man who never made a success, an
+eight-ulcer man on a four-ulcer job, and all four ulcers working. I
+have never met you, but if I do you'll need a new nose and plenty of
+beefsteak and perhaps a supporter below. Westbrook Pegler, a
+guttersnipe, is a gentleman compared to you. You can take that as more
+of an insult than as a reflection on your ancestry."
+ -- President Harry S Truman
+%
+I have learned
+To spell hors d'oeuvres
+Which still grates on
+Some people's n'oeuvres.
+ -- Warren Knox
+%
+"I have made mistakes but I have never made the mistake of claiming
+that I have never made one."
+ -- James Gordon Bennett
+%
+"I have made this letter longer than usual because I lack the time to
+make it shorter."
+ -- Blaise Pascal
+%
+I have more humility in my little finger than you have in your whole
+____BODY!
+ -- from "Cerebus" #82
+%
+"I have seen the future and it is just like the present, only longer."
+ -- Kehlog Albran, "The Profit"
+%
+"I have the simplest tastes. I am always satisfied with the best."
+ -- Oscar Wilde
+%
+"I have the world's largest collection of seashells. I keep it
+scattered around the beaches of the world ... Perhaps you've seen it.
+ -- Steven Wright
+%
+"I have to convince you, or at least snow you ..."
+ -- Prof. Romas Aleliunas, CS 435
+%
+"I have two very rare photographs: one is a picture of Houdini locking
+his keys in his car; the other is a rare photograph of Norman Rockwell
+beating up a child."
+ -- Steven Wright
+%
+I have yet to see any problem, however complicated, which, when looked
+at in the right way, did not become still more complicated.
+ -- Poul Anderson
+%
+"I haven't lost my mind -- it's backed up on tape somewhere."
+%
+"I haven't lost my mind; I know exactly where I left it."
+%
+I just forgot my whole philosophy of life!!!
+%
+"I just need enough to tide me over until I need more."
+ -- Bill Hoest
+%
+I know it all. I just can't remember it all at once.
+%
+"I know not with what weapons World War III will be fought, but World
+War IV will be fought with sticks and stones."
+ -- Albert Einstein
+%
+"I know the answer! The answer lies within the heart of all mankind!
+The answer is twelve? I think I'm in the wrong building."
+ -- Charles Schulz
+%
+"I like being single. I'm always there when I need me."
+ -- Art Leo
+%
+I like to believe that people in the long run are going to do more to
+promote peace than our governments. Indeed, I think that people want
+peace so much that one of these days governments had better get out of
+the way and let them have it.
+ -- Dwight D. Eisenhower
+%
+"I like work ... I can sit and watch it for hours."
+%
+"I like your game but we have to change the rules."
+%
+"I love Saturday morning cartoons, what classic humour! This is what
+entertainment is all about ... Idiots, explosives and falling anvils."
+ -- Calvin and Hobbes, Bill Watterson
+%
+"I love to eat them Smurfies
+ Smurfies what I love to eat
+ Bite they ugly heads off,
+ Nibble on they bluish feet."
+%
+"I may appear to be just sitting here like a bucket of tapioca, but
+don't let appearances fool you. I'm approaching old age ... at the
+speed of light."
+ -- Prof. Cosmo Fishhawk
+%
+"I may not be totally perfect, but parts of me are excellent."
+ -- Ashleigh Brilliant
+%
+"I must have a prodigious quantity of mind; it takes me as much as a
+week sometimes to make it up."
+ -- Mark Twain, "The Innocents Abroad"
+%
+I must have slipped a disk -- my pack hurts
+%
+"I never fail to convince an audience that the best thing they could do
+was to go away."
+%
+"I never met a piece of chocolate I didn't like."
+%
+I often quote myself; it adds spice to my conversation.
+ -- G. B. Shaw
+%
+"I only touch base with reality on an as-needed basis!"
+ -- Royal Floyd Mengot (Klaus)
+%
+"I played lead guitar in a band called The Federal Duck, which is the
+kind of name that was popular in the '60s as a result of controlled
+substances being in widespread use. Back then, there were no
+restrictions, in terms of talent, on who could make an album, so we
+made one, and it sounds like a group of people who have been given
+powerful but unfamiliar instruments as a therapy for a degenerative
+nerve disease."
+ -- Dave Barry, "The Snake"
+%
+I predict that today will be remembered until tomorrow!
+%
+"I profoundly believe it takes a lot of practice to become a moral
+slob."
+ -- William F. Buckley
+%
+ "I quite agree with you," said the Duchess; "and the moral of
+that is -- `Be what you would seem to be' -- or, if you'd like it put
+more simply -- `Never imagine yourself not to be otherwise than what it
+might appear to others that what you were or might have been was not
+otherwise than what you had been would have appeared to them to be
+otherwise.'"
+ -- Lewis Carrol, "Alice in Wonderland"
+%
+I realize that the MX missile is none of our concern. I realize that
+the whole point of living in a democracy is that we pay professional
+congresspersons to concern themselves with things like the MX missile
+so we can be free to concern ourselves with getting hold of the
+plumber.
+
+But from time to time, I feel I must address major public issues such
+as this, because in a free and open society, where the very future of
+the world hinges on decisions made by our elected leaders, you never
+win large cash journalism awards if you stick to the topics I usually
+write about, such as nose-picking.
+ -- Dave Barry, "At Last, the Ultimate Deterrent Against
+ Political Fallout"
+%
+I really hate this damned machine
+I wish that they would sell it.
+It never does quite what I want
+But only what I tell it.
+%
+"I refuse to have a battle of wits with an unarmed person."
+%
+I see a good deal of talk from Washington about lowering taxes. I hope
+they do get 'em lowered enough so people can afford to pay 'em.
+ -- Will Rogers
+%
+I see the eigenvalue in thine eye,
+I hear the tender tensor in thy sigh.
+Bernoulli would have been content to die
+Had he but known such _a-squared cos 2(phi)!
+ -- Stanislaw Lem, "Cyberiad"
+%
+I sent a letter to the fish,
+I told them, "This is what I wish."
+The little fishes of the sea,
+They sent an answer back to me.
+The little fishes' answer was
+"We cannot do it, sir, because ..."
+I sent a letter back to say
+It would be better to obey.
+But someone came to me and said
+"The little fishes are in bed."
+I said to him, and I said it plain
+"Then you must wake them up again."
+I said it very loud and clear,
+I went and shouted in his ear.
+But he was very stiff and proud,
+He said "You needn't shout so loud."
+And he was very proud and stiff,
+He said "I'll go and wake them if ..."
+I took a kettle from the shelf,
+I went to wake them up myself.
+But when I found the door was locked
+I pulled and pushed and kicked and knocked,
+And when I found the door was shut,
+I tried to turn the handle, But ...
+
+ "Is that all?" asked Alice.
+ "That is all." said Humpty Dumpty. "Goodbye."
+ -- Lewis Carrol, "Through the Looking Glass"
+%
+"I shot an arrow into the air, and it stuck."
+ -- Graffito in Los Angeles
+%
+"... I should explain that I was wearing a black velvet cape that was
+supposed to make me look like the dashing, romantic Zorro but which
+actually made me look like a gigantic bat wearing glasses ..."
+ -- Dave Barry, "The Wet Zorro Suit and Other Turning
+ Points in l'Amour"
+%
+"I stayed up all night playing poker with tarot cards. I got a full
+house and four people died."
+ -- Steven Wright
+%
+"I stopped believing in Santa Claus when I was six. Mother took me to
+see him in a department store and he asked for my autograph."
+ -- Shirley Temple
+%
+I suggest you locate your hot tub outside your house, so it won't do
+too much damage if it catches fire or explodes. First you decide which
+direction your hot tub should face for maximum solar energy. After
+much trial and error, I have found that the best direction for a hot
+tub to face is up.
+ -- Dave Barry, "The Taming of the Screw"
+%
+"I think it is true for all _n. I was just playing it safe with _n >= 3
+because I couldn't remember the proof."
+ -- Baker, Pure Math 351a
+%
+"I think sex is better than logic, but I can't prove it."
+%
+I think that all good, right thinking people in this country are sick
+and tired of being told that all good, right thinking people in this
+country are fed up with being told that all good, right thinking people
+in this country are fed up with being sick and tired. I'm certainly
+not, and I'm sick and tired of being told that I am.
+ -- Monty Python
+%
+I think that I shall never see
+A billboard lovely as a tree.
+Perhaps, unless the billboards fall
+I'll never see a tree at all.
+ -- Ogden Nash
+%
+I think that I shall never see
+A thing as lovely as a tree.
+But as you see the trees have gone
+They went this morning with the dawn.
+A logging firm from out of town
+Came and chopped the trees all down.
+But I will trick those dirty skunks
+And write a brand new poem called 'Trunks'.
+%
+"I think the sky is blue because it's a shift from black through purple
+to blue, and it has to do with where the light is. You know, the
+farther we get into darkness, and there's a shifting of color of light
+into the blueness, and I think as you go farther and farther away from
+the reflected light we have from the sun or the light that's bouncing
+off this earth, uh, the darker it gets ... I think if you look at the
+color scale, you start at black, move it through purple, move it on
+out, it's the shifting of color. We mentioned before about the stars
+singing, and that's one of the effects of the shifting of colors."
+ -- Pat Robertson, The 700 Club
+%
+I think we can all agree that there is not enough common courtesy shown
+... HEY! PAY ATTENTION WHEN I'M TALKING TO YOU DAMMIT! I said I think
+we can all agree that there is not enough common courtesy shown today.
+When we take the time to be courteous to each other, we find that we
+are happier and less likely to engage in nuclear war. This point was
+driven home by the recent summit talks, where Nancy Reagan and Raisa
+Gorbachev, each of whose husband thinks the other's husband is vermin,
+were able to sit down at a high-level tea and engage in courteous
+conversation ...
+ -- Dave Barry, "The Stuff of Etiquette"
+%
+"I thought you were trying to get into shape."
+"I am. The shape I've selected is a triangle."
+%
+" ... I told my doctor I got all the exercise I needed being a
+pallbearer for all my friends who run and do exercises!"
+ -- Winston Churchill
+%
+I took a course in speed reading and was able to read War and Peace in
+twenty minutes. It's about Russia.
+ -- Woody Allen
+%
+I used to be an agnostic, but now I'm not so sure.
+%
+"I used to get high on life but lately I've built up a resistance."
+%
+"I used to think I was indecisive, but now I'm not so sure."
+%
+"I used to think that the brain was the most wonderful organ in my
+body. Then I realized who was telling me this."
+ -- Emo Phillips
+%
+I used to work in a fire hydrant factory. You couldn't park anywhere
+near the place.
+ -- Steven Wright
+%
+I value kindness to human beings first of all, and kindness to
+animals. I don't respect the law; I have a total irreverence for
+anything connected with society except that which makes the roads
+safer, the beer stronger, the food cheaper, and old men and women
+warmer in the winter, and happier in the summer.
+ -- Brendan Behan
+%
+"I want to buy a husband who, every week when I sit down to watch `St.
+Elsewhere', won't scream, `FORGET IT, BLANCHE ... IT'S TIME FOR "HEE
+HAW"!!'"
+ -- Berke Breathed, "Bloom County"
+%
+I was born because it was a habit in those days, people didn't know
+anything else ... I was not a Child Prodigy, because a Child Prodigy is
+a child who knows as much when it is a child as it does when it grows
+up.
+ -- Will Rogers
+%
+"I was drunk last night, crawled home across the lawn. By accident I
+put the car key in the door lock. The house started up. So I figured
+what the hell, and drove it around the block a few times. I thought I
+should go park it in the middle of the freeway and yell at everyone to
+get off my driveway."
+ -- Steven Wright
+%
+"I was gratified to be able to answer promptly, and I did. I said I
+didn't know."
+ -- Mark Twain
+%
+I was part of that strange race of people aptly described as spending
+their lives doing things they detest to make money they don't want to
+buy things they don't need to impress people they dislike.
+ -- Emile Henry Gauvreay
+%
+"I was playing poker the other night ... with Tarot cards. I got a full
+house and four people died."
+ -- Steven Wright
+%
+"I went into a general store, and they wouldn't sell me anything
+specific".
+ -- Steven Wright
+%
+I went on to test the program in every way I could devise. I strained
+it to expose its weaknesses. I ran it for high-mass stars and low-mass
+stars, for stars born exceedingly hot and those born relatively cold.
+I ran it assuming the superfluid currents beneath the crust to be
+absent -- not because I wanted to know the answer, but because I had
+developed an intuitive feel for the answer in this particular case.
+Finally I got a run in which the computer showed the pulsar's
+temperature to be less than absolute zero. I had found an error. I
+chased down the error and fixed it. Now I had improved the program to
+the point where it would not run at all.
+ -- George Greenstein, "Frozen Star: Of Pulsars, Black
+ Holes and the Fate of Stars"
+%
+"I went to a job interview the other day, the guy asked me if I had any
+questions , I said yes, just one, if you're in a car traveling at the
+speed of light and you turn your headlights on, does anything happen?
+
+He said he couldn't answer that, I told him sorry, but I couldn't work
+for him then.
+ -- Steven Wright
+%
+"I went to the hardware store and bought some used paint. It was in
+the shape of a house. I also bought some batteries, but they weren't
+included."
+ -- Steven Wright
+%
+"I went to the museum where they had all the heads and arms from the
+statues that are in all the other museums."
+ -- Steven Wright
+%
+I went to the race track once and bet on a horse that was so good that
+it took seven others to beat him!
+%
+"I wish there was a knob on the TV to turn up the intelligence.
+There's a knob called `brightness', but it doesn't work."
+ -- Gallagher
+%
+"I wouldn't recommend sex, drugs or insanity for everyone, but they've
+always worked for me."
+ -- Hunter S. Thompson
+%
+"I'd give my right arm to be ambidextrous."
+%
+"I'd love to go out with you, but I did my own thing and now I've got
+to undo it."
+%
+"I'd love to go out with you, but I have to floss my cat."
+%
+"I'd love to go out with you, but I have to stay home and see if I
+snore."
+%
+"I'd love to go out with you, but I never go out on days that end in
+`Y.'"
+%
+"I'd love to go out with you, but I want to spend more time with my
+blender."
+%
+"I'd love to go out with you, but I'm attending the opening of my
+garage door."
+%
+"I'd love to go out with you, but I'm converting my calendar watch from
+Julian to Gregorian."
+%
+"I'd love to go out with you, but I'm doing door-to-door collecting for
+static cling."
+%
+"I'd love to go out with you, but I'm having all my plants neutered."
+%
+"I'd love to go out with you, but I'm staying home to work on my
+cottage cheese sculpture."
+%
+"I'd love to go out with you, but I'm taking punk totem pole carving."
+%
+"I'd love to go out with you, but I've been scheduled for a karma
+transplant."
+%
+"I'd love to go out with you, but it's my parakeet's bowling night."
+%
+"I'd love to go out with you, but my favorite commercial is on TV."
+%
+"I'd love to go out with you, but the last time I went out, I never
+came back."
+%
+"I'd love to go out with you, but the man on television told me to say
+tuned."
+%
+"I'd love to go out with you, but there are important world issues that
+need worrying about."
+%
+"I'd rather have a bottle in front of me than a frontal lobotomy."
+%
+"I'll carry your books, I'll carry a tune, I'll carry on, carry over,
+carry forward, Cary Grant, cash & carry, Carry Me Back To Old Virginia,
+I'll even Hara Kari if you show me how, but I will *not* carry a gun."
+ -- Hawkeye, M*A*S*H
+%
+I'll defend to the death your right to say that, but I never said I'd
+listen to it!
+ -- Tom Galloway with apologies to Voltaire
+%
+I'll grant thee random access to my heart,
+Thoul't tell me all the constants of thy love;
+And so we two shall all love's lemmas prove
+And in our bound partition never part.
+ -- Stanislaw Lem, "Cyberiad"
+%
+"I'll rob that rich person and give it to some poor deserving slob.
+That will *prove* I'm Robin Hood."
+ -- Daffy Duck, "Robin Hood Daffy", [1958, Chuck Jones]
+%
+"I'm a creationist; I refuse to believe that I could have evolved from
+man."
+%
+I'm a Lisp variable -- bind me!
+%
+"I'm all for computer dating, but I wouldn't want one to marry my
+sister."
+%
+I'm changing my name to Chrysler
+I'm going down to Washington, D.C.
+I'll tell some power broker
+ What they did for Iacocca
+Will be perfectly acceptable to me!
+I'm changing my name to Chrysler,
+I'm heading for that great receiving line.
+When they hand a million grand out,
+ I'll be standing with my hand out,
+Yessir, I'll get mine!
+ -- Tom Paxton
+%
+I'm defending her honor, which is more than she ever did.
+%
+"I'm defending her honor, which is more than she ever did."
+%
+"I'm fed up to the ears with old men dreaming up wars for young men to
+die in."
+ -- George McGovern
+%
+I'm going to Boston to see my doctor. He's a very sick man.
+ -- Fred Allen
+%
+I'm going to live forever, or die trying!
+ -- Spider Robinson
+%
+... I'm IMAGINING a sensuous GIRAFFE, CAVORTING in the BACK ROOM of a
+KOSHER DELI!!
+%
+"I'm in Pittsburgh. Why am I here?"
+ -- Harold Urey, Nobel Laureate
+%
+i'm living so far beyond my income that we may almost be said to be
+living apart.
+ -- e. e. cummings
+%
+I'm N-ary the tree, I am,
+N-ary the tree, I am, I am.
+I'm getting traversed by the parser next door,
+She's traversed me seven times before.
+And ev'ry time it was an N-ary (N-ary!)
+Never wouldn't ever do a binary. (No sir!)
+I'm 'er eighth tree that was N-ary.
+N-ary the tree I am, I am,
+N-ary the tree I am.
+%
+"I'm not under the alkafluence of inkahol that some thinkle peep I am.
+It's just the drunker I sit here the longer I get."
+%
+"I'm prepared for all emergencies but totally unprepared for everyday
+life."
+%
+I'm proud to be paying taxes in the United States. The only thing is
+-- I could be just as proud for half the money.
+ -- Arthur Godfrey
+%
+I'm rated PG-34!!
+%
+"I'm really enjoying not talking to you ... Let's not talk again ____REAL
+soon ..."
+%
+"I'm returning this note to you, instead of your paper, because it
+(your paper) presently occupies the bottom of my bird cage."
+ -- English Professor, Providence College
+%
+I'm very good at integral and differential calculus,
+I know the scientific names of beings animalculous;
+In short, in matters vegetable, animal, and mineral,
+I am the very model of a modern Major-General.
+ -- Gilbert & Sullivan, "Pirates of Penzance"
+%
+"I'm willing to sacrifice anything for this cause, even other people's
+lives"
+%
+I've built a better model than the one at Data General
+For data bases vegetable, animal, and mineral
+My OS handles CPUs with multiplexed duality;
+My PL/1 compiler shows impressive functionality.
+My storage system's better than magnetic core polarity,
+You never have to bother checking out a bit for parity;
+There isn't any reason to install non-static floor matting;
+My disk drive has capacity for variable formatting.
+
+I feel compelled to mention what I know to be a gloating point:
+There's lots of room in memory for variables floating-point,
+Which shows for input vegetable, animal, and mineral
+I've built a better model than the one at Data General.
+
+ -- Steve Levine, "A Computer Song" (To the tune of
+ "Modern Major General", from "Pirates of Penzance",
+ by Gilbert & Sullivan)
+%
+I've enjoyed just about as much of this as I can stand.
+%
+I've found my niche. If you're wondering why I'm not there, there was
+this little hole in the bottom ...
+ -- John Croll
+%
+I've given up reading books; I find it takes my mind off myself.
+%
+I've had a perfectly wonderful evening. But this wasn't it.
+ -- Groucho Marx
+%
+I've known him as a man, as an adolescent and as a child -- sometimes
+on the same day.
+%
+"I've seen better heads on half a pint of beer."
+%
+"I've seen, I SAY, I've seen better heads on a mug of beer"
+ -- Senator Claghorn
+%
+I've touch'd the highest point of all my greatness;
+And from that full meridian of my glory
+I haste now to my setting. I shall fall,
+Like a bright exhalation in the evening
+And no man see me more.
+ -- Shakespeare
+%
+IBM had a PL/I,
+ Its syntax worse than JOSS;
+And everywhere this language went,
+ It was a total loss.
+%
+Idaho state law makes it illegal for a man to give his sweetheart a box
+of candy weighing less than fifty pounds.
+%
+Ideas don't stay in some minds very long because they don't like
+solitary confinement.
+%
+Idiot Box, n.:
+ The part of the envelope that tells a person where to place the
+stamp when they can't quite figure it out for themselves.
+ -- Rich Hall, "Sniglets"
+%
+Idiot, n.:
+ A member of a large and powerful tribe whose influence in human
+affairs has always been dominant and controlling.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+If a 6600 used paper tape instead of core memory, it would use up tape
+at about 30 miles/second.
+ -- Grishman, Assembly Language Programming
+%
+If A = B and B = C, then A = C, except where void or prohibited by law.
+ -- Roy Santoro
+%
+"If a camel flies, no one laughs if it doesn't get very far."
+ -- Paul White
+%
+If a camel is a horse designed by a committee, then a consensus
+forecast is a camel's behind.
+ -- Edgar R. Fiedler
+%
+If A equals success, then the formula is _A = _X + _Y + _Z. _X is work. _Y
+is play. _Z is keep your mouth shut.
+ -- Albert Einstein
+%
+If a group of _N persons implements a COBOL compiler, there will be _N-1
+passes. Someone in the group has to be the manager.
+ -- T. Cheatham
+%
+If a jury in a criminal trial stays out for more than twenty-four
+hours, it is certain to vote acquittal, save in those instances where
+it votes guilty.
+ -- Joseph C. Goulden
+%
+If a listener nods his head when you're explaining your program, wake
+him up.
+%
+If a President doesn't do it to his wife, he'll do it to his country.
+%
+If a putt passes over the hole without dropping, it is deemed to have
+dropped. The law of gravity holds that any object attempting to
+maintain a position in the atmosphere without something to support it
+must drop. The law of gravity supercedes the law of golf.
+ -- Donald A. Metz
+%
+"If a team is in a positive frame of mind, it will have a good
+attitude. If it has a good attitude, it will make a commitment to
+playing the game right. If it plays the game right, it will win --
+unless, of course, it doesn't have enough talent to win, and no manager
+can make goose-liver pate out of goose feathers, so why worry?"
+ -- Sparky Anderson
+%
+If all be true that I do think,
+There be Five Reasons why one should Drink;
+Good friends, good wine, or being dry,
+Or lest we should be by-and-by,
+Or any other reason why.
+%
+If all else fails, immortality can always be assured by spectacular
+error.
+ -- John Kenneth Galbraith
+%
+If all the Chinese simultaneously jumped into the Pacific off a 10 foot
+platform erected 10 feet off their coast, it would cause a tidal wave
+that would destroy everything in this country west of Nebraska.
+%
+If all the world's a stage, I want to operate the trap door.
+ -- Paul Beatty
+%
+If all the world's economists were laid end to end, we wouldn't reach a
+conclusion.
+ -- William Baumol
+%
+If an S and an I and an O and a U
+With an X at the end spell Su;
+And an E and a Y and an E spell I,
+Pray what is a speller to do?
+Then, if also an S and an I and a G
+And an HED spell side,
+There's nothing much left for a speller to do
+But to go commit siouxeyesighed.
+ -- Charles Follen Adams, "An Orthographic Lament"
+%
+If anything can go wrong, it will.
+%
+If at first you don't succeed, give up, no use being a damn fool.
+%
+If at first you don't succeed, redefine success.
+%
+If bankers can count, how come they have eight windows and only four
+tellers?
+%
+"If dolphins are so smart, why did Flipper work for television?"
+%
+If entropy is increasing, where is it coming from?
+%
+If everybody minded their own business, the world would go
+around a deal faster.
+ -- The Duchess, "Through the Looking Glass"
+%
+If everything is coming your way then you're in the wrong lane.
+%
+... If forced to travel on an airplane, try and get in the cabin with
+the Captain, so you can keep an eye on him and nudge him if he falls
+asleep or point out any mountains looming up ahead ...
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+If God didn't mean for us to juggle, tennis balls wouldn't come three
+to a can.
+%
+If God had intended Man to Smoke, He would have set him on Fire.
+%
+If God had intended Man to Walk, He would have given him Feet.
+%
+If God had intended Man to Watch TV, He would have given him Rabbit
+Ears.
+%
+If God had intended Men to Smoke, He would have put Chimneys in their
+Heads.
+%
+If God had meant for us to be in the Army, we would have been born with
+green, baggy skin.
+%
+If God had meant for us to be naked, we would have been born that way.
+%
+If God had not given us sticky tape, it would have been necessary to
+invent it.
+%
+If God had wanted you to go around nude, He would have given you bigger
+hands.
+%
+If God is dead, who will save the Queen?
+%
+If God is perfect, why did He create discontinuous functions?
+%
+"If God lived on Earth, people would knock out all His windows."
+ -- Yiddish saying
+%
+If God wanted us to be brave, why did he give us legs?
+ -- Marvin Kitman
+%
+"If I am elected, the concrete barriers around the WHITE HOUSE will be
+replaced by tasteful foam replicas of ANN MARGARET!"
+%
+If I could drop dead right now, I'd be the happiest man alive!
+ -- Samuel Goldwyn
+%
+If I don't drive around the park,
+I'm pretty sure to make my mark.
+If I'm in bed each night by ten,
+I may get back my looks again.
+If I abstain from fun and such,
+I'll probably amount to much;
+But I shall stay the way I am,
+Because I do not give a damn.
+ -- Dorothy Parker
+%
+If I don't see you in the future, I'll see you in the pasture.
+%
+If I had a plantation in Georgia and a home in Hell, I'd sell the
+plantation and go home.
+ -- Eugene P. Gallagher
+%
+If I had any humility I would be perfect.
+ -- Ted Turner
+%
+"If I had only known, I would have been a locksmith."
+ -- Albert Einstein
+%
+If I have seen farther than others, it is because I was standing on the
+shoulders of giants.
+ -- Isaac Newton
+
+In the sciences, we are now uniquely privileged to sit side by side
+with the giants on whose shoulders we stand.
+ -- Gerald Holton
+
+If I have not seen as far as others, it is because giants were standing
+on my shoulders.
+ -- Hal Abelson
+
+In computer science, we stand on each other's feet.
+ -- Brian K. Reid
+%
+If I kiss you, that is a psychological interaction.
+
+On the other hand, if I hit you over the head with a brick, that is
+also a psychological interaction.
+
+The difference is that one is friendly and the other is not so
+friendly.
+
+The crucial point is if you can tell which is which.
+ -- Dolph Sharp, "I'm O.K., You're Not So Hot"
+%
+If I traveled to the end of the rainbow
+As Dame Fortune did intend,
+Murphy would be there to tell me
+The pot's at the other end.
+ -- Bert Whitney
+%
+If ignorance is bliss, why aren't there more happy people?
+%
+If it's Tuesday, this must be someone else's fortune.
+%
+If Jesus Christ were to come today, people would not even crucify him.
+They would ask him to dinner, and hear what he had to say, and make fun
+of it.
+ -- Thomas Carlyle
+%
+"If just one piece of mail gets lost, well, they'll just think they
+forgot to send it. But if *two* pieces of mail get lost, hell, they'll
+just think the other guy hasn't gotten around to answering his mail.
+And if *fifty* pieces of mail get lost, can you imagine it, if *fifty*
+pieces of mail get lost, why they'll think someone *else* is broken!
+And if 1Gb of mail gets lost, they'll just *know* that Arpa is down and
+think it's a conspiracy to keep them from their God given right to
+receive Net Mail ..."
+ -- Leith (Casey) Leedom
+%
+If life is a stage, I want some better lighting.
+%
+If little else, the brain is an educational toy.
+ -- Tom Robbins
+%
+If little green men land in your back yard, hide any little green women
+you've got in the house.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+If mathematically you end up with the wrong answer, try multiplying by
+the page number.
+%
+If money can't buy happiness, I guess you'll just have to rent it.
+%
+"If once a man indulges himself in murder, very soon he comes to think
+little of robbing; and from robbing he next comes to drinking and
+Sabbath-breaking, and from that to incivility and procrastination."
+ -- Thomas De Quincey (1785 - 1859)
+%
+If one studies too zealously, one easily loses his pants.
+ -- A. Einstein.
+%
+If only God would give me some clear sign! Like making a large deposit
+in my name at a Swiss bank.
+ -- Woody Allen, "Without Feathers"
+%
+If only I could be respected without having to be respectable.
+%
+If only one could get that wonderful feeling of accomplishment without
+having to accomplish anything.
+%
+If Patrick Henry thought that taxation without representation was bad,
+he should see how bad it is with representation.
+%
+If scientific reasoning were limited to the logical processes of
+arithmetic, we should not get very far in our understanding of the
+physical world. One might as well attempt to grasp the game of poker
+entirely by the use of the mathematics of probability.
+ -- Vannevar Bush
+%
+If someone had told me I would be Pope one day, I would have studied
+harder.
+ -- Pope John Paul I
+%
+"If that makes any sense to you, you have a big problem."
+ -- C. Durance, Computer Science 234
+%
+If the aborigine drafted an IQ test, all of Western civilization would
+presumably flunk it.
+ -- Stanley Garn
+%
+If the code and the comments disagree, then both are probably wrong.
+ -- Norm Schryer
+%
+If the colleges were better, if they really had it, you would need to
+get the police at the gates to keep order in the inrushing multitude.
+See in college how we thwart the natural love of learning by leaving
+the natural method of teaching what each wishes to learn, and insisting
+that you shall learn what you have no taste or capacity for. The
+college, which should be a place of delightful labor, is made odious
+and unhealthy, and the young men are tempted to frivolous amusements to
+rally their jaded spirits. I would have the studies elective.
+Scholarship is to be created not by compulsion, but by awakening a pure
+interest in knowledge. The wise instructor accomplishes this by
+opening to his pupils precisely the attractions the study has for
+himself. The marking is a system for schools, not for the college; for
+boys, not for men; and it is an ungracious work to put on a professor.
+ -- Ralph Waldo Emerson
+%
+"If the King's English was good enough for Jesus, it's good enough for
+me!"
+ -- "Ma" Ferguson, Governor of Texas (circa 1920)
+%
+If the odds are a million to one against something occurring, chances
+are 50-50 it will.
+%
+If the weather is extremely bad, church attendance will be down. If
+the weather is extremely good, church attendance will be down. If the
+bulletin covers are in short supply, however, church attendance will
+exceed all expectations.
+ -- Reverend Chichester
+%
+If there are epigrams, there must be meta-epigrams.
+%
+If there is a possibility of several things going wrong, the one that
+will cause the most damage will be the one to go wrong.
+%
+If there is no God, who pops up the next Kleenex?
+ -- Art Hoppe
+%
+If they can make penicillin out of moldy bread, they can sure make
+something out of you.
+ -- Muhammad Ali
+%
+If this fortune didn't exist, somebody would have invented it.
+%
+If this is timesharing, give me my share right now.
+%
+If time heals all wounds, how come the belly button stays the same?
+%
+If today is the first day of the rest of your life, what the hell was
+yesterday?
+%
+If two men agree on everything, you may be sure that one of them is
+doing the thinking.
+ -- Lyndon Baines Johnson
+%
+If two wrongs don't make a right, try three.
+ -- Laurence J. Peter
+%
+"If value corrupts then absolute value corrupts absolutely"
+%
+"If we were meant to fly, we wouldn't keep losing our luggage."
+%
+If while you are in school, there is a shortage of qualified personnel
+in a particular field, then by the time you graduate with the necessary
+qualifications, that field's employment market is glutted.
+ -- Marguerite Emmons
+%
+If you are a fatalist, what can you do about it?
+ -- Ann Edwards-Duff
+%
+"If you can count your money, you don't have a billion dollars."
+ -- J. Paul Getty
+%
+If you can lead it to water and force it to drink, it isn't a horse.
+%
+If you can read this, you're too close.
+%
+If you can survive death, you can probably survive anything.
+%
+If you can't be good, be careful. If you can't be careful, give me a
+call.
+%
+If you can't learn to do it well, learn to enjoy doing it badly.
+%
+If you cannot convince them, confuse them.
+ -- Harry S Truman
+%
+If you didn't get caught, did you really do it?
+%
+If you don't care where you are, then you ain't lost.
+%
+If you don't go to other men's funerals they won't go to yours.
+ -- Clarence Day
+%
+If you don't have a nasty obituary you probably didn't matter.
+ -- Freeman Dyson
+%
+"If you don't want your dog to have bad breath, do what I do: Pour a little
+Lavoris in the toilet."
+ -- Jay Leno
+%
+If you eat a live frog in the morning, nothing worse will happen to
+either of you for the rest of the day.
+%
+"If you ever want to get anywhere in politics, my boy, you're going to
+have to get a toehold in the public eye."
+%
+If you explain so clearly that nobody can misunderstand, somebody
+will.
+%
+If you give Congress a chance to vote on both sides of an issue, it
+will always do it.
+ -- Les Aspin, D., Wisconsin
+%
+"If you go on with this nuclear arms race, all you are going to do is
+make the rubble bounce"
+ -- Winston Churchill
+%
+If you had any brains, you'd be dangerous.
+%
+If you have a procedure with 10 parameters, you probably missed some.
+%
+"If you have to hate, hate gently"
+%
+If you just try long enough and hard enough, you can always manage to
+boot yourself in the posterior.
+ -- A. J. Liebling
+%
+If you keep anything long enough, you can throw it away.
+%
+If you live in a country run by committee, be on the committee.
+ -- Graham Summer
+%
+If you live to the age of a hundred you have it made because very few
+people die past the age of a hundred.
+ -- George Burns
+%
+If you make people think they're thinking, they'll love you; but if you
+really make them think they'll hate you.
+%
+If you only have a hammer, you tend to see every problem as a nail.
+ -- Maslow
+%
+If you perceive that there are four possible ways in which a procedure
+can go wrong, and circumvent these, then a fifth way will promptly
+develop.
+%
+If you pick up a starving dog and make him prosperous, he will not bite
+you. This is the principal difference between a dog and a man.
+ -- Mark Twain
+%
+If you push the "extra ice" button on the soft drink vending machine,
+you won't get any ice. If you push the "no ice" button, you'll get
+ice, but no cup.
+%
+If you put garbage in a computer nothing comes out but garbage. But
+this garbage, having passed through a very expensive machine, is
+somehow enobled and none dare criticize it.
+%
+If you sit down at a poker game and don't see a sucker, get up. You're
+the sucker.
+%
+If you stand on your head, you will get footprints in your hair.
+%
+If you stick a stock of liquor in your locker,
+It is slick to stick a lock upon your stock.
+ Or some joker who is slicker,
+ Will trick you of your liquor,
+If you fail to lock your liquor with a lock.
+%
+If you think education is expensive, try ignorance.
+ -- Derek Bok, president of Harvard
+%
+If you think last Tuesday was a drag, wait till you see what happens
+tomorrow!
+%
+If you think nobody cares if you're alive, try missing a couple of car
+payments.
+ -- Earl Wilson
+%
+If you think the problem is bad now, just wait until we've solved it.
+ -- Arthur Kasspe
+%
+If you think the United States has stood still, who built the largest
+shopping center in the world?
+ -- Richard M. Nixon
+%
+If you think the United States has stood still, who built the largest
+shopping center in the world?
+ -- Richard Nixon
+%
+If you throw a New Year's Party, the worst thing that you can do would
+be to throw the kind of party where your guests wake up today, and call
+you to say they had a nice time. Now you'll be be expected to throw
+another party next year.
+
+What you should do is throw the kind of party where your guest wake up
+several days from now and call their lawyers to find out if they've
+been indicted for anything. You want your guests to be so anxious to
+avoid a recurrence of your party that they immediately start planning
+parties of their own, a year in advance, just to prevent you from
+having another one ...
+
+If your party is successful, the police will knock on your door, unless
+your party is very successful in which case they will lob tear gas
+through your living room window. As host, your job is to make sure
+that they don't arrest anybody. Or if they're dead set on arresting
+someone, your job is to make sure it isn't you ...
+%
+If you took all the students that felt asleep in class and laid them
+end to end, they'd be a lot more comfortable.
+ -- "Graffiti in the Big Ten"
+%
+"If you understand what you're doing, you're not learning anything."
+ -- A. L.
+%
+If you want divine justice, die.
+ -- Nick Seldon
+%
+If you want to know what god thinks of money, just look at the people
+he gave it to.
+ -- Dorthy Parker
+%
+If you want to understand your government, don't begin by reading the
+Constitution. It conveys precious little of the flavor of today's
+statecraft. Instead, read selected portions of the Washington
+telephone directory containing listings for all the organizations with
+titles beginning with the word "National".
+ -- George Will
+%
+If you want your spouse to listen and pay strict attention to every
+word you say, talk in your sleep.
+%
+"If you wants to get elected president, you'se got to think up some
+memoraboble homily so's school kids can be pestered into memorizin' it,
+even if they don't know what it means."
+ -- Walt Kelly, "The Pogo Party"
+%
+If you wish to live wisely, ignore sayings -- including this one.
+%
+If you're going to do something tonight that you'll be sorry for
+tomorrow morning, sleep late.
+ -- Henny Youngman
+%
+If you're happy, you're successful.
+%
+ If you're like most homeowners, you're afraid that many repairs
+around your home are too difficult to tackle. So, when your furnace
+explodes, you call in a so-called professional to fix it. The
+"professional" arrives in a truck with lettering on the sides and
+deposits a large quantity of tools and two assistants who spend the
+better part of the week in your basement whacking objects at random
+with heavy wrenches, after which the "professional" returns and gives
+you a bill for slightly more money than it would cost you to run a
+successful campaign for the U.S. Senate.
+ And that's why you've decided to start doing things yourself.
+You figure, "If those guys can fix my furnace, then so can I. How
+difficult can it be?"
+ Very difficult. In fact, most home projects are impossible,
+which is why you should do them yourself. There is no point in paying
+other people to screw things up when you can easily screw them up
+yourself for far less money. This article can help you.
+ -- Dave Barry, "The Taming of the Screw"
+%
+If you're not part of the solution, you're part of the precipitate.
+%
+If you're not very clever you should be conciliatory.
+ -- Benjamin Disraeli
+%
+If you're right 90% of the time, why quibble about the remaining 3%?
+%
+"If you've done six impossible things before breakfast, why not round
+it off with dinner at Milliway's, the restaurant at the end of the
+universe?"
+%
+If you've seen one redwood, you've seen them all.
+ -- Ronald Reagan
+%
+Ignisecond, n.:
+ The overlapping moment of time when the hand is locking the car
+door even as the brain is saying, "my keys are in there!"
+ -- Rich Hall, "Sniglets"
+%
+Il brilgue: les t^oves libricilleux
+ Se gyrent et frillant dans le guave,
+Enm^im'es sont les gougebosquex,
+ Et le m^omerade horgrave.
+ -- Lewis Carrol, "Through the Looking Glass"
+%
+Iles's Law:
+ There is always an easier way to do it. When looking directly
+at the easy way, especially for long periods, you will not see it.
+Neither will Iles.
+%
+Illinois isn't exactly the land that God forgot -- it's more like the
+land He's trying to ignore.
+%
+Imagination is the one weapon in the war against reality.
+ -- Jules de Gaultier
+%
+"Imagine if every Thursday your shoes exploded if you tied them the
+usual way. This happens to us all the time with computers, and nobody
+thinks of complaining."
+ -- Jeff Raskin, interviewed in Doctor Dobb's Journal
+%
+Imagine that Cray computer decides to make a personal computer. It has
+a 150 MHz processor, 200 megabytes of RAM, 1500 megabytes of disk
+storage, a screen resolution of 4096 x 4096 pixels, relies entirely on
+voice recognition for input, fits in your shirt pocket and costs $300.
+What's the first question that the computer community asks?
+
+"Is it PC compatible?"
+%
+Immigration is the sincerest form of flattery.
+ -- Jack Paar
+%
+Immortality -- a fate worse than death.
+ -- Edgar A. Shoaff
+%
+Impartial, adj.:
+ Unable to perceive any promise of personal advantage from
+espousing either side of a controversy or adopting either of two
+conflicting opinions.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Important letters which contain no errors will develop errors in the
+mail. Corresponding errors will show up in the duplicate while the
+Boss is reading it.
+%
+Impossible, adj.:
+ (1) I wouldn't like it and when it happens I won't approve;
+(2) I can't be bothered; (3) God can't be bothered. Meaning (3) may
+perhaps be valid but the others are 101% whaledreck.
+ -- Chad C. Mulligan, "The Hipcrime Vocab"
+%
+In 1750 Issac Newton became discouraged when he fell up a flight of
+stairs.
+%
+In 1869 the waffle iron was invented for people who had wrinkled
+waffles.
+%
+In 1880 the French captured Detroit but gave it back ... they couldn't
+get parts.
+%
+In 1914, the first crossword puzzle was printed in a newspaper. The
+creator received $4000 down ... and $3000 across.
+%
+In 1915 pancake make-up was invented but most people still preferred
+syrup.
+%
+In a five year period we can get one superb programming language. Only
+we can't control when the five year period will begin.
+%
+ In a forest a fox bumps into a little rabbit, and says, "Hi,
+junior, what are you up to?"
+ "I'm writing a dissertation on how rabbits eat foxes," said the
+rabbit.
+ "Come now, friend rabbit, you know that's impossible!"
+ "Well, follow me and I'll show you." They both go into the
+rabbit's dwelling and after a while the rabbit emerges with a satisfied
+expression on his face.
+ Comes along a wolf. "Hello, what are we doing these days?"
+ "I'm writing the second chapter of my thesis, on how rabbits
+devour wolves."
+ "Are you crazy? Where is your academic honesty?"
+ "Come with me and I'll show you." As before, the rabbit comes
+out with a satisfied look on his face and a diploma in his paw.
+Finally, the camera pans into the rabbit's cave and, as everybody
+should have guessed by now, we see a mean-looking, huge lion sitting
+next to some bloody and furry remnants of the wolf and the fox.
+
+The moral: It's not the contents of your thesis that are important --
+it's your PhD advisor that really counts.
+%
+In a medium in which a News Piece takes a minute and an "In-Depth"
+Piece takes two minutes, the Simple will drive out the Complex.
+ -- Frank Mankiewicz
+%
+In a museum in Havana, there are two skulls of Christopher Columbus,
+"one when he was a boy and one when he was a man."
+ -- Mark Twain
+%
+In Africa some of the native tribes have a custom of beating the ground
+with clubs and uttering spine chilling cries. Anthropologists call
+this a form of primitive self-expression. In America we call it golf.
+%
+In America today ... we have Woody Allen, whose humor has become so
+sophisticated that nobody gets it any more except Mia Farrow. All
+those who think Mia Farrow should go back to making movies where the
+devil gets her pregnant and Woody Allen should go back to dressing up
+as a human sperm, please raise your hands. Thank you.
+ -- Dave Barry, "Why Humor is Funny"
+%
+In America, any boy may become president and I suppose that's just one
+of the risks he takes.
+ -- Adlai Stevenson
+%
+In an organization, each person rises to the level of his own
+incompetency
+ -- The Peter Principle
+%
+In any formula, constants (especially those obtained from handbooks)
+are to be treated as variables.
+%
+"In any world menu, Canada must be considered the vichyssoise of
+nations -- it's cold, half-French, and difficult to stir."
+ -- Stuart Keate
+%
+In Blythe, California, a city ordinance declares that a person must own
+at least two cows before he can wear cowboy boots in public.
+%
+In Boston, it is illegal to hold frog-jumping contests in nightclubs.
+%
+In case of atomic attack, the federal ruling against prayer in schools
+will be temporarily canceled.
+%
+In case of injury notify your superior immediately. He'll kiss it and
+make it better.
+%
+In Columbia, Pennsylvania, it is against the law for a pilot to tickle
+a female flying student under her chin with a feather duster in order
+to get her attention.
+%
+In Corning, Iowa, it's a misdemeanor for a man to ask his wife to ride
+in any motor vehicle.
+%
+"In defeat, unbeatable; in victory, unbearable."
+ -- Winston Curchill, of Montgomery
+%
+In Denver it is unlawful to lend your vacuum cleaner to your next-door
+neighbor.
+%
+In Devon, Connecticut, it is unlawful to walk backwards after sunset.
+%
+In Dr. Johnson's famous dictionary patriotism is defined as the last
+resort of the scoundrel. With all due respect to an enlightened but
+inferior lexicographer I beg to submit that it is the first.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+In English, every word can be verbed. Would that it were so in our
+programming languages.
+%
+In Greene, New York, it is illegal to eat peanuts and walk backwards on
+the sidewalks when a concert is on.
+%
+In India, "cold weather" is merely a conventional phrase and has come
+into use through the necessity of having some way to distinguish
+between weather which will melt a brass door-knob and weather which
+will only make it mushy.
+ -- Mark Twain
+%
+In Lexington, Kentucky, it's illegal to carry an ice cream cone in your
+pocket.
+%
+In Lowes Crossroads, Delaware, it is a violation of local law for any
+pilot or passenger to carry an ice cream cone in their pocket while
+either flying or waiting to board a plane.
+%
+In Memphis, Tennessee, it is illegal for a woman to drive a car unless
+there is a man either running or walking in front of it waving a red
+flag to warn approaching motorists and pedestrians.
+%
+In Ohio, if you ignore an orator on Decoration day to such an extent as
+to publicly play croquet or pitch horseshoes within one mile of the
+speaker's stand, you can be fined $25.00.
+%
+"In order to make an apple pie from scratch, you must first create the
+universe."
+ -- Carl Sagan, Cosmos
+%
+In our civilization, and under our republican form of government,
+intelligence is so highly honored that it is rewarded by exemption from
+the cares of office.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+In Pocataligo, Georgia, it is a violation for a woman over 200 pounds
+and attired in shorts to pilot or ride in an airplane.
+%
+In Pocatello, Idaho, a law passed in 1912 provided that "The carrying
+of concealed weapons is forbidden, unless same are exhibited to public
+view."
+%
+In Riemann, Hilbert or in Banach space
+Let superscripts and subscripts go their ways.
+Our asymptotes no longer out of phase,
+We shall encounter, counting, face to face.
+ -- Stanislaw Lem, "Cyberiad"
+%
+In Seattle, Washington, it is illegal to carry a concealed weapon that
+is over six feet in length.
+%
+In seeking the unattainable, simplicity only gets in the way.
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+"In short, _N is Richardian if, and only if, _N is not Richardian."
+%
+In specifications, Murphy's Law supersedes Ohm's.
+%
+In Tennessee, it is illegal to shoot any game other than whales from a
+moving automobile.
+%
+[In the 60's] there was madness in any direction, at any hour ... You
+could strike sparks anywhere. There was a fantastic universal sense
+that whatever we were doing was `right', that we were winning ...
+
+And that, I think, was the handle -- the sense of inevitable victory
+over the forces of Old and Evil. Not in any mean or military sense; we
+didn't need that. Our energy would simply `prevail'. There was no
+point in fighting -- on our side or theirs. We had all the momentum;
+we were riding the crest of a high and beautiful wave ....
+
+So now, less than five years later, you can go up on a steep hill in
+Las Vegas and look West, and with the right kind of eyes you can almost
+___see the high-water mark -- the place where the wave finally broke and
+rolled back.
+ -- Hunter S. Thompson, "Fear and Loathing in Las Vegas"
+%
+In the beginning was the word.
+But by the time the second word was added to it,
+there was trouble.
+For with it came syntax ...
+ -- John Simon
+%
+In the days when Sussman was a novice Minsky once came to him as he sat
+hacking at the PDP-6. "What are you doing?", asked Minsky. "I am
+training a randomly wired neural net to play Tic-Tac-Toe." "Why is the
+net wired randomly?", asked Minsky. "I do not want it to have any
+preconceptions of how to play." Minsky shut his eyes. "Why do you
+close your eyes?", Sussman asked his teacher. "So the room will be
+empty." At that moment, Sussman was enlightened.
+%
+In the force if Yoda's so strong, construct a sentence with words in
+the proper order then why can't he?
+%
+In the land of the dark, the Ship of the Sun is driven by the Grateful
+Dead.
+ -- Egyptian Book of the Dead
+%
+In the long run, every program becomes rococo, and then rubble.
+ -- Alan Perlis
+%
+In the olden days in England, you could be hung for stealing a sheep or
+a loaf of bread. However, if a sheep stole a loaf of bread and gave it
+to you, you would only be tried for receiving, a crime punishable by
+forty lashes with the cat or the dog, whichever was handy. If you
+stole a dog and were caught, you were punished with twelve rabbit
+punches, although it was hard to find rabbits big enough or strong
+enough to punch you.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+In the space of one hundred and seventy-six years the Mississippi has
+shortened itself two hundred and forty-two miles. Therefore ... in the
+Old Silurian Period the Mississippi River was upward of one million
+three hundred thousand miles long ... seven hundred and forty-two years
+from now the Mississippi will be only a mile and three-quarters long.
+... There is something fascinating about science. One gets such
+wholesome returns of conjecture out of such a trifling investment of
+fact.
+ -- Mark Twain
+%
+In the Top 40, half the songs are secret messages to the teen world to
+drop out, turn on, and groove with the chemicals and light shows at
+discotheques.
+ -- Art Linkletter
+%
+In those days he was wiser than he is now -- he used to frequently take
+my advice.
+ -- Winston Churchill
+%
+In Tulsa, Oklahoma, it is against the law to open a soda bottle without
+the supervision of a licensed engineer.
+%
+In West Union, Ohio, No married man can go flying without his spouse
+along at any time, unless he has been married for more than 12 months.
+%
+Incumbent, n.:
+ Person of liveliest interest to the outcumbents.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+... indifference is a militant thing ... when it goes away it leaves
+smoking ruins, where lie citizens bayonetted through the throat. It is
+not a children's pastime like mere highway robbery.
+ -- Stephen Crane
+%
+Indifference will be the downfall of mankind, but who cares?
+%
+Individualists unite!
+%
+Infancy, n.:
+ The period of our lives when, according to Wordsworth, "Heaven
+lies about us." The world begins lying about us pretty soon
+afterward.
+ -- Ambrose Bierce
+%
+Information Center, n.:
+ A room staffed by professional computer people whose job it is
+to tell you why you cannot have the information you require.
+%
+Ingrate, n.:
+ A man who bites the hand that feeds him, and then complains of
+indigestion.
+%
+Injustice anywhere is a threat to justice everywhere.
+ -- Martin Luther King, Jr.
+%
+Ink, n.:
+ A villainous compound of tannogallate of iron, gum-arabic, and
+water, chiefly used to facilitate the infection of idiocy and promote
+intellectual crime.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Innovation is hard to schedule.
+ -- Dan Fylstra
+%
+Insanity is hereditary. You get it from your kids.
+%
+Insanity is the final defense ... It's hard to get a refund when the
+salesman is sniffing your crotch and baying at the moon.
+%
+Interpreter, n.:
+ One who enables two persons of different languages to
+understand each other by repeating to each what it would have been to
+the interpreter's advantage for the other to have said.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Intolerance is the last defense of the insecure.
+%
+ INVENTORY
+Four be the things I am wiser to know:
+Idleness, sorrow, a friend, and a foe.
+
+Four be the things I'd been better without:
+Love, curiosity, freckles, and doubt.
+
+Three be the things I shall never attain:
+Envy, content, and sufficient champagne.
+
+Three be the things I shall have till I die:
+Laughter and hope and a sock in the eye.
+%
+Iron Law of Distribution:
+ Them that has, gets.
+%
+"Irrationality is the square root of all evil"
+ -- Douglas Hofstadter
+%
+Is it possible that software is not like anything else, that it is
+meant to be discarded: that the whole point is to always see it as a
+soap bubble?
+%
+Is not marriage an open question, when it is alleged, from the
+beginning of the world, that such as are in the institution wish to get
+out, and such as are out wish to get in?
+ -- Ralph Emerson
+%
+Is your job running? You'd better go catch it!
+%
+Isn't it interesting that the same people who laugh at science fiction
+listen to weather forecasts and economists?
+ -- Kelvin Throop III
+%
+Isn't it strange that the same people that laugh at gypsy fortune
+tellers take economists seriously?
+%
+Issawi's Laws of Progress:
+
+ The Course of Progress:
+ Most things get steadily worse.
+
+ The Path of Progress:
+ A shortcut is the longest distance between two points.
+%
+It appears that after his death, Albert Einstein found himself working
+as the doorkeeper at the Pearly Gates. One slow day, he found that he
+had time to chat with the new entrants. To the first one he asked,
+"What's your IQ?" The new arrival replied, "190". They discussed
+Einstein's theory of relativity for hours. When the second new arrival
+came, Einstein once again inquired as to the newcomer's IQ. The answer
+this time came "120". To which Einstein replied, "Tell me, how did the
+Cubs do this year?" and they proceeded to talk for half an hour or so.
+To the final arrival, Einstein once again posed the question, "What's
+your IQ?". Upon receiving the answer "70", Einstein smiled and asked,
+"Got a minute to tell me about VMS 4.0?"
+%
+It happened that a fire broke out backstage in a theater. The clown
+came out to inform the public. They thought it was just a jest and
+applauded. He repeated his warning, they shouted even louder. So I
+think the world will come to an end amid general applause from all the
+wits, who believe that it is a joke.
+%
+It has been observed that one's nose is never so happy as when it is
+thrust into the affairs of another, from which some physiologists have
+drawn the inference that the nose is devoid of the sense of smell.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+It has been said [by Anatole France], "it is not by amusing oneself
+that one learns," and, in reply: "it is *____only* by amusing oneself that
+one can learn."
+ -- Edward Kasner and James R. Newman
+%
+It has been said that man is a rational animal. All my life I have
+been searching for evidence which could support this.
+ -- Bertrand Russell
+%
+It has just been discovered that research causes cancer in rats.
+%
+It is against the grain of modern education to teach children to
+program. What fun is there in making plans, acquiring discipline in
+organizing thoughts, devoting attention to detail, and learning to be
+self-critical?
+ -- Alan Perlis
+%
+It is against the law for a monster to enter the corporate limits of
+Urbana, Illinois.
+%
+It is always preferable to visit home with a friend. Your parents will
+not be pleased with this plan, because they want you all to themselves
+and because in the presence of your friend, they will have to act like
+mature human beings ...
+ -- Playboy, January 1983
+%
+It is amusing that a virtue is made of the vice of chastity; and it's a
+pretty odd sort of chastity at that, which leads men straight into the
+sin of Onan, and girls to the waning of their color.
+ -- Voltaire
+%
+It is an important and popular fact that things are not always what
+they seem. For instance, on the planet Earth, man had always assumed
+that he was more intelligent than dolphins because he had achieved so
+much -- the wheel, New York wars and so on -- whilst all the dolphins
+had ever done was muck about in the water having a good time. But
+conversely, the dolphins had always believed that they were far more
+intelligent than man -- for precisely the same reasons.
+
+Curiously enough, the dolphins had long known of the impending
+destruction of the of the planet Earth and had made many attempts to
+alert mankind to the danger; but most of their communications were
+misinterpreted ...
+ -- Douglas Admas "The Hitch-Hikers' Guide To The
+ Galaxy"
+%
+It is better for civilization to be going down the drain than to be
+coming up it.
+ -- Henry Allen
+%
+It is better never to have been born. But who among us has such luck?
+One in a million, perhaps.
+%
+It is better to kiss an avocado than to get in a fight with an aardvark
+%
+It is by the fortune of God that, in this country, we have three
+benefits: freedom of speech, freedom of thought, and the wisdom never
+to use either.
+ -- Mark Twain
+%
+It is difficult to produce a television documentary that is both
+incisive and probing when every twelve minutes one is interrupted by
+twelve dancing rabbits singing about toilet paper.
+ -- Rod Serling
+%
+"It is easier for a camel to pass through the eye of a needle if it is
+lightly greased."
+ -- Kehlog Albran, "The Profit"
+%
+It is easier to be a "humanitarian" than to render your own country its
+proper due; it is easier to be a "patriot" than to make your community
+a better place to live in; it is easier to be a "civic leader" than to
+treat your own family with loving understanding; for the smaller the
+focus of attention, the harder the task.
+ -- Sydney J. Harris
+%
+It is easier to change the specification to fit the program than vice
+versa.
+%
+It is easier to get forgiveness than permission.
+%
+It is easier to write an incorrect program than understand a correct
+one.
+%
+It is generally agreed that "Hello" is an appropriate greeting because
+if you entered a room and said "Goodbye," it could confuse a lot of
+people.
+ -- Dolph Sharp, "I'm O.K., You're Not So Hot"
+%
+It is illegal to drive more than two thousand sheep down Hollywood
+Boulevard at one time.
+%
+It is illegal to say "Oh, Boy" in Jonesboro, Georgia.
+%
+It is impossible to experience one's death objectively and still carry
+a tune.
+ -- Woody Allen
+%
+It is impossible to make anything foolproof because fools are so
+ingenious.
+%
+It is impossible to travel faster than light, and certainly not
+desirable, as one's hat keeps blowing off.
+ -- Woody Allen
+%
+It is Mr. Mellon's credo that $200,000,000 can do no wrong. Our
+offense consists in doubting it.
+ -- Justice Robert H. Jackson
+%
+It is much easier to suggest solutions when you know nothing about the
+problem.
+%
+It is necessary for the welfare of society that genius should be
+privileged to utter sedition, to blaspheme, to outrage good taste, to
+corrupt the youthful mind, and generally to scandalize one's uncles.
+ -- George Bernard Shaw
+%
+It is not enough to succeed. Others must fail.
+ -- Gore Vidal
+%
+It is not true that life is one damn thing after another -- it's one
+damn thing over and over.
+ -- Edna St. Vincent Millay
+%
+It is now 10 p.m. Do you know where Henry Kissinger is?
+ -- Elizabeth Carpenter
+%
+It is now pitch dark. If you proceed, you will likely fall into a
+pit.
+%
+It is one of the superstitions of the human mind to have imagined that
+virginity could be a virtue.
+ -- Voltaire
+%
+It is only people of small moral stature who have to stand on their
+dignity.
+%
+It is only the great men who are truly obscene. If they had not dared
+to be obscene, they could never have dared to be great.
+ -- Havelock Ellis
+%
+It is practically impossible to teach good programming style to
+students that have had prior exposure to BASIC: as potential
+programmers they are mentally mutilated beyond hope of
+regeneration.
+ -- Dijkstra
+%
+It is said that the lonely eagle flies to the mountain peaks while the
+lowly ant crawls the ground, but cannot the soul of the ant soar as
+high as the eagle?
+%
+It is something to be able to paint a particular picture, or to carve a
+statue, and so to make a few objects beautiful; but it is far more
+glorious to carve and paint the very atmosphere and medium through
+which we look, which morally we can do. To affect the quality of the
+day, that is the highest of arts.
+ -- Henry David Thoreau, "Where I Live"
+%
+It is Texas law that when two trains meet each other at a railroad
+crossing, each shall come to a full stop, and neither shall proceed
+until the other has gone.
+%
+It is the business of little minds to shrink.
+ -- Carl Sandburg
+%
+It is the business of the future to be dangerous.
+ -- Hawkwind
+%
+It is true that if your paperboy throws your paper into the bushes for
+five straight days it can be explained by Newton's Law of Gravity. But
+it takes Murphy's law to explain why it is happening to you.
+%
+It is very difficult to prophesy, especially when it pertains to the
+future.
+%
+It looks like blind screaming hedonism won out.
+%
+It may be bad manners to talk with your mouth full, but it isn't too
+good either if you speak when your head is empty.
+%
+It may be that your whole purpose in life is simply to serve as a
+warning to others.
+%
+"It runs like _x, where _x is something unsavory"
+ -- Prof. Romas Aleliunas, CS 435
+%
+It seems like the less a statesman amounts to, the more he loves the
+flag.
+%
+It shall be unlawful for any suspicious person to be within the
+municipality.
+ -- Local ordinance, Euclid Ohio
+%
+"It took me fifteen years to discover that I had no talent for writing,
+but I couldn't give up because by that time I was too famous."
+ -- Robert Benchly
+%
+It was a book to kill time for those who liked it better dead.
+%
+"It was a virgin forest, a place where the Hand of Man had never set
+foot."
+%
+It was one of those perfect summer days -- the sun was shining, a
+breeze was blowing, the birds were singing, and the lawn mower was
+broken ...
+ -- James Dent
+%
+"It was pleasant to me to get a letter from you the other day. Perhaps
+I should have found it pleasanter if I had been able to decipher it. I
+don't think that I mastered anything beyond the date (which I knew) and
+the signature (which I guessed at). There's a singular and a perpetual
+charm in a letter of yours; it never grows old, it never loses its
+novelty .... Other letters are read and thrown away and forgotten, but
+yours are kept forever -- unread. One of them will last a reasonable
+man a lifetime."
+ -- Thomas Aldrich
+%
+ It was the next morning that the armies of Twodor marched east
+laden with long lances, sharp swords, and death-dealing hangovers. The
+thousands were led by Arrowroot, who sat limply in his sidesaddle,
+nursing a whopper. Goodgulf, Gimlet, and the rest rode by him, praying
+for their fate to be quick, painless, and if possible, someone else's.
+ Many an hour the armies forged ahead, the war-merinos bleating
+under their heavy burdens and the soldiers bleating under their melting
+icepacks.
+ -- The Harvard Lampoon, "Bored of the Rings"
+%
+It wasn't that she had a rose in her teeth, exactly. It was more like
+the rose and the teeth were in the same glass.
+%
+It will be advantageous to cross the great stream ... the Dragon is on
+the wing in the Sky ... the Great Man rouses himself to his Work.
+%
+It will be generally found that those who sneer habitually at human
+nature and affect to despise it, are among its worst and least pleasant
+examples.
+ -- Charles Dickens
+%
+It would be nice if the Food and Drug Administration stopped issuing
+warnings about toxic substances and just gave me the names of one or
+two things still safe to eat.
+ -- Robert Fuoss
+%
+It's a damn poor mind that can only think of one way to spell a word.
+ -- Andrew Jackson
+%
+"It's a dog-eat-dog world out there, and I'm wearing Milkbone
+underwear."
+%
+It's a good thing we don't get all the government we pay for.
+%
+"It's a small world, but I wouldn't want to have to paint it."
+ -- Steven Wright
+%
+"It's a summons."
+"What's a summons?"
+"It means summon's in trouble."
+ -- Rocky and Bullwinkle
+%
+It's a very *__UN*lucky week in which to be took dead.
+ -- Churchy La Femme
+%
+It's always darkest just before it gets pitch black.
+%
+"It's bad luck to be superstitious."
+ -- Andrew W. Mathis
+%
+It's better to be wanted for murder that not to be wanted at all.
+ -- Marty Winch
+%
+"It's easier said than done."
+
+... and if you don't believe it, try proving that it's easier done than
+said, and you'll see that "it's easier said that `it's easier done than
+said' than it is done", which really proves that "it's easier said than
+done".
+%
+It's easier to fight for one's principles than to live up to them.
+%
+It's easier to get forgiveness for being wrong than forgiveness for
+being right.
+%
+"It's Fabulous! We haven't seen anything like it in the last half an
+hour!"
+ -- Macy's
+%
+It's illegal in Wilbur, Washington, to ride an ugly horse.
+%
+It's is not, it isn't ain't, and it's it's, not its, if you mean it
+is. If you don't, it's its. Then too, it's hers. It isn't her's. It
+isn't our's either. It's ours, and likewise yours and theirs.
+ -- Oxford University Press, Edpress News
+%
+It's just a jump to the left
+ And then a step to the right.
+Put your hands on your hips
+ And pull your knees in tight.
+It's the pelvic thrust
+ That really gets you insa-a-a-a-ane
+
+ LET'S DO THE TIME WARP AGAIN!
+
+ -- Rocky Horror Picture Show
+%
+"It's kind of fun to do the impossible."
+ -- Walt Disney
+%
+"It's Like This"
+
+Even the samurai
+have teddy bears,
+and even the teddy bears
+get drunk.
+%
+It's lucky you're going so slowly, because you're going in the wrong
+direction.
+%
+"It's men like him that give the Y chromosome a bad name."
+%
+It's more than magnificent -- it's mediocre.
+ -- Sam Goldwyn
+%
+It's no surprise that things are so screwed up: everyone that knows how
+to run a government is either driving taxicabs or cutting hair.
+ -- George Burns
+%
+It's not an optical illusion, it just looks like one.
+ -- Phil White
+%
+"It's not Camelot, but it's not Cleveland, either."
+ -- Kevin White, mayor of Boston
+%
+It's not enough to be Hungarian; you must have talent too.
+ -- Alexander Korda
+%
+"It's not just a computer -- it's your ass."
+ -- Cal Keegan
+%
+It's not reality or how you perceive things that's important -- it's
+what you're taking for it...
+%
+It's not so hard to lift yourself by your bootstraps once you're off
+the ground.
+ -- Daniel B. Luten
+%
+It's not that I'm afraid to die. I just don't want to be there when it
+happens.
+ -- Woody Allen
+%
+It's not the valleys in life I dread so much as the dips.
+ -- Garfield
+%
+It's odd, and a little unsettling, to reflect upon the fact that
+English is the only major language in which "I" is capitalized; in many
+other languages "You" is capitalized and the "i" is lower case.
+ -- Sydney J. Harris
+%
+It's raisins that make Post Raisin Bran so raisiny ...
+%
+It's really quite a simple choice: Life, Death, or Los Angeles.
+%
+It's so stupid of modern civilization to have given up believing in the
+Devil when he is the only explanation of it.
+%
+It's the opinion of some that crops could be grown on the moon. Which
+raises the fear that it may not be long before we're paying somebody
+not to.
+ -- Franklin P. Jones
+%
+It's the thought, if any, that counts!
+%
+ JACK AND THE BEANSTACK
+ by Mark Isaak
+
+ Long ago, in a finite state far away, there lived a JOVIAL
+character named Jack. Jack and his relations were poor. Often their
+hash table was bare. One day Jack's parent said to him, "Our matrices
+are sparse. You must go to the market to exchange our RAM for some
+BASICs." She compiled a linked list of items to retrieve and passed it
+to him.
+ So Jack set out. But as he was walking along a Hamilton path,
+he met the traveling salesman.
+ "Whither dost thy flow chart take thou?" prompted the salesman
+in high-level language.
+ "I'm going to the market to exchange this RAM for some chips
+and Apples," commented Jack.
+ "I have a much better algorithm. You needn't join a queue
+there; I will swap your RAM for these magic kernels now."
+ Jack made the trade, then backtracked to his house. But when
+he told his busy-waiting parent of the deal, she became so angry she
+started thrashing.
+ "Don't you even have any artificial intelligence? All these
+kernels together hardly make up one byte," and she popped them out the
+window ...
+%
+Jacquin's Postulate on Democratic Government:
+ No man's life, liberty, or property are safe while the
+legislature is in session.
+%
+James Joyce -- an essentially private man who wished his total
+indifference to public notice to be universally recognized.
+ -- Tom Stoppard
+%
+Jenkinson's Law:
+ It won't work.
+%
+Jesus Saves,
+Moses Invests,
+But only Buddha pays Dividends.
+%
+Job Placement, n.:
+ Telling your boss what he can do with your job.
+%
+Joe's sister puts spaghetti in her shoes!
+%
+Johnson's First Law:
+ When any mechanical contrivance fails, it will do so at the
+most inconvenient possible time.
+%
+Join in the new game that's sweeping the country. It's called
+"Bureaucracy". Everybody stands in a circle. The first person to do
+anything loses.
+%
+Join the march to save individuality!
+%
+Jone's Law:
+ The man who smiles when things go wrong has thought of someone
+to blame it on.
+%
+Jone's Motto:
+ Friends come and go, but enemies accumulate.
+%
+Jones's First Law:
+ Anyone who makes a significant contribution to any field of
+endeavor, and stays in that field long enough, becomes an obstruction
+to its progress -- in direct proportion to the importance of their
+original contribution.
+%
+Just about every computer on the market today runs Unix, except the Mac
+(and nobody cares about it).
+ -- Bill Joy 6/21/85
+%
+Just as most issues are seldom black or white, so are most good
+solutions seldom black or white. Beware of the solution that requires
+one side to be totally the loser and the other side to be totally the
+winner. The reason there are two sides to begin with usually is
+because neither side has all the facts. Therefore, when the wise
+mediator effects a compromise, he is not acting from political
+motivation. Rather, he is acting from a deep sense of respect for the
+whole truth.
+ -- Stephen R. Schwambach
+%
+Just because everything is different doesn't mean anything has
+changed.
+ -- Irene Peter
+%
+Just because you're paranoid doesn't mean they AREN'T after you.
+%
+Just because your doctor has a name for your condition doesn't mean he
+knows what it is.
+%
+Just go with the flow control, roll with the crunches, and, when you
+get a prompt, type like hell.
+%
+"Just once, I wish we would encounter an alien menace that wasn't
+immune to bullets"
+ -- The Brigader, "Dr. Who"
+%
+"Just out of curiosity does this actually mean something or have some
+of the few remaining bits of your brain just evaporated?"
+ -- Patricia O Tuama, rissa@killer.DALLAS.TX.US
+%
+Just remember: when you go to court, you are trusting your fate to
+twelve people that weren't smart enough to get out of jury duty!
+%
+`Just the place for a Snark!' the Bellman cried,
+ As he landed his crew with care;
+Supporting each man on the top of the tide
+ By a finger entwined in his hair.
+
+'Just the place for a Snark! I have said it twice:
+ That alone should encourage the crew.
+Just the place for a Snark! I have said it thrice:
+ What I tell you three times is true.'
+%
+Just when you thought you were winning the rat race, along comes a
+faster rat!!!
+%
+Justice always prevails ... three times out of seven!
+ -- Michael J. Wagner
+%
+Justice is incidental to law and order.
+ -- J. Edgar Hoover
+%
+Justice, n.:
+ A decision in your favor.
+%
+K: Cobalt's metal, hard and shining;
+ Cobol's wordy and confining;
+ KOBOLDS topple when you strike them;
+ Don't feel bad, it's hard to like them.
+ -- The Roguelet's ABC
+%
+Kansas state law requires pedestrians crossing the highways at night to
+wear tail lights.
+%
+Katz' Law:
+ Man and nations will act rationally when all other
+possibilities have been exhausted.
+%
+Keep America beautiful. Swallow your beer cans.
+%
+Keep Cool, but Don't Freeze
+ - Hellman's Mayonnaise
+%
+Keep emotionally active. Cater to your favorite neurosis.
+%
+Keep grandma off the streets -- legalize bingo.
+%
+Keep in mind always the two constant Laws of Frisbee:
+ (1) The most powerful force in the world is that of a disc
+ straining to land under a car, just out of reach (this
+ force is technically termed "car suck").
+ (2) Never precede any maneuver by a comment more predictive
+ than "Watch this!"
+%
+Keep you Eye on the Ball,
+Your Shoulder to the Wheel,
+Your Nose to the Grindstone,
+Your Feet on the Ground,
+Your Head on your Shoulders.
+Now ... try to get something DONE!
+%
+Ken Thompson has an automobile which he helped design. Unlike most
+automobiles, it has neither speedometer, nor gas gage, nor any of the
+numerous idiot lights which plague the modern driver. Rather, if the
+driver makes any mistake, a giant "?" lights up in the center of the
+dashboard. "The experienced driver", he says, "will usually know
+what's wrong."
+%
+Kerr's Three Rules for a Successful College:
+ Have plenty of football for the alumni, sex for the students,
+and parking for the faculty.
+%
+Kids have *_____never* taken guidance from their parents. If you could
+travel back in time and observe the original primate family in the
+original tree, you would see the primate parents yelling at the primate
+teenager for sitting around and sulking all day instead of hunting for
+grubs and berries like dad primate. Then you'd see the primate
+teenager stomp up to his branch and slam the leaves.
+ -- Dave Barry, "Kids Today: They Don't Know Dum Diddly
+ Do"
+%
+Kin, n.:
+ An affliction of the blood
+%
+Kinkler's First Law:
+ Responsibility always exceeds authority.
+
+Kinkler's Second Law:
+ All the easy problems have been solved.
+%
+"Kirk to Enterprise -- beam down yeoman Rand and a six-pack."
+%
+Kirkland, Illinois, law forbids bees to fly over the village or through
+any of its streets.
+%
+Kiss me twice. I'm schizophrenic.
+%
+Kiss your keyboard goodbye!
+%
+Klein bottle for rent -- inquire within.
+%
+Klein bottle for sale ... inquire within.
+%
+Kleptomaniac, n.:
+ A rich thief.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Know thyself. If you need help, call the C.I.A.
+%
+Know what I hate most? Rhetorical questions.
+ -- Henry N. Camp
+%
+Krogt, n. (chemical symbol: Kr):
+ The metallic silver coating found on fast-food game cards.
+ -- Rich Hall, "Sniglets"
+%
+Labor, n.:
+ One of the processes by which A acquires property for B.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Lackland's Laws:
+ (1) Never be first.
+ (2) Never be last.
+ (3) Never volunteer for anything
+%
+Lactomangulation, n.:
+ Manhandling the "open here" spout on a milk carton so badly
+that one has to resort to using the "illegal" side.
+ -- Rich Hall, "Sniglets"
+%
+Ladybug, ladybug,
+Look to your stern!
+Your house is on fire,
+Your children will burn!
+So jump ye and sing, for
+The very first time
+The four lines above
+Have been put into rhyme.
+ -- Walt Kelly
+%
+Laetrile is the pits
+%
+Langsam's Laws:
+ (1) Everything depends.
+ (2) Nothing is always.
+ (3) Everything is sometimes.
+%
+Larkinson's Law:
+ All laws are basically false.
+%
+Lassie looked brilliant, in part because the farm family she lived with
+was made up of idiots. Remember? One of them was always getting
+pinned under the tractor, and Lassie was always rushing back to the
+farmhouse to alert the other ones. She'd whimper and tug at their
+sleeves, and they'd always waste precious minutes saying things: "Do
+you think something's wrong? Do you think she wants us to follow her?
+What is it, girl?", etc., as if this had never happened before, instead
+of every week. What with all the time these people spent pinned under
+the tractor, I don't see how they managed to grow any crops
+whatsoever. They probably got by on federal crop supports, which
+Lassie filed the applications for.
+ -- Dave Barry
+%
+"Last night, I came home and realized that everything in my apartment
+had been stolen and replaced with an exact duplicate. I told this to
+my friend -- he said, `Do I know you?'"
+ -- Steven Wright
+%
+"Last week a cop stopped me in my car. He asked me if I had a police
+record. I said, no, but I have the new DEVO album. Cops have no sense
+of humor."
+%
+Last yeer I kudn't spel Engineer. Now I are won.
+%
+Laugh at your problems; everybody else does.
+%
+"Laughter is the closest distance between two people."
+ -- Victor Borge
+%
+Law of Communications:
+ The inevitable result of improved and enlarged communications
+between different levels in a hierarchy is a vastly increased area of
+misunderstanding.
+%
+Law of Probable Dispersal:
+ Whatever it is that hits the fan will not be evenly
+distributed.
+%
+Law of Selective Gravity:
+ An object will fall so as to do the most damage.
+
+Jenning's Corollary:
+ The chance of the bread falling with the buttered side down is
+directly proportional to the cost of the carpet.
+%
+Law of the Perversity of Nature:
+ You cannot successfully determine beforehand which side of the
+bread to butter.
+%
+Laws of Serendipity:
+
+ (1) In order to discover anything, you must be looking for
+ something.
+ (2) If you wish to make an improved product, you must already
+ be engaged in making an inferior one.
+%
+Lazlo's Chinese Relativity Axiom:
+ No matter how great your triumphs or how tragic your defeats --
+approximately one billion Chinese couldn't care less.
+%
+Learned men are the cisterns of knowledge, not the fountainheads.
+%
+Learning French is trivial: the word for horse is cheval, and
+everything else follows in the same way.
+ -- Alan J. Perlis
+%
+Left to themselves, things tend to go from bad to worse.
+%
+Legalize free-enterprise murder: why should governments have all the
+fun?
+%
+Legislation proposed in the Illinois State Legislature, May, 1907:
+ "Speed upon county roads will be limited to ten miles an hour
+unless the motorist sees a bailiff who does not appear to have had a
+drink in 30 days, when the driver will be permitted to make what he
+can."
+%
+Leibowitz's Rule:
+ When hammering a nail, you will never hit your finger if you
+hold the hammer with both hands.
+%
+LEO (July 23 - Aug 22)
+ You consider yourself a born leader. Others think you are
+ pushy. Most Leo people are bullies. You are vain and dislike
+ honest criticism. Your arrogance is disgusting. Leo people
+ are thieves.
+%
+LEO (July 23 - Aug 22)
+ Your determination and sense of humor will come to the fore.
+ Your ability to laugh at adversity will be a blessing because
+ you've got a day coming you wouldn't believe. As a matter of
+ fact, if you can laugh at what happens to you today, you've got
+ a sick sense of humor.
+%
+Let He who taketh the Plunge Remember to return it by Tuesday.
+%
+"Let me assure you that to us here at First National, you're not just a
+number. You're two numbers, a dash, three more numbers, another dash
+and another number."
+ -- James Estes
+%
+Let us live!!!
+Let us love!!!
+Let us share the deepest secrets of our souls!!!
+
+You first.
+%
+Let's just say that where a change was required, I adjusted. In every
+relationship that exists, people have to seek a way to survive. If you
+really care about the person, you do what's necessary, or that's the
+end. For the first time, I found that I really could change, and the
+qualities I most admired in myself I gave up. I stopped being loud and
+bossy ... Oh, all right. I was still loud and bossy, but only behind
+his back."
+ -- Kate Hepburn, on Tracy and Hepburn
+%
+Let's say your wedding ring falls into your toaster, and when you stick
+your hand in to retrieve it, you suffer Pain and Suffering as well as
+Mental Anguish. You would sue:
+
+* The toaster manufacturer, for failure to include, in the instructions
+ section that says you should never never never ever stick you hand
+ into the toaster, the statement "Not even if your wedding ring falls
+ in there".
+
+* The store where you bought the toaster, for selling it to an obvious
+ cretin like yourself.
+
+* Union Carbide Corporation, which is not directly responsible in this
+ case, but which is feeling so guilty that it would probably send you
+ a large cash settlement anyway.
+ -- Dave Barry
+%
+Let's talk about how to fill out your 1984 tax return. Here's an often
+overlooked accounting technique that can save you thousands of
+dollars: For several days before you put it in the mail, carry your
+tax return around under your armpit. No IRS agent is going to want to
+spend hours poring over a sweat-stained document. So even if you owe
+money, you can put in for an enormous refund and the agent will
+probably give it to you, just to avoid an audit. What does he care?
+It's not his money.
+ -- Dave Barry, "Sweating Out Taxes"
+%
+LETTERS TO THE EDITOR (The Times of London)
+
+Dear Sir,
+
+I am firmly opposed to the spread of microchips either to the home or
+to the office. We have more than enough of them foisted upon us in
+public places. They are a disgusting Americanism, and can only result
+in the farmers being forced to grow smaller potatoes, which in turn
+will cause massive unemployment in the already severely depressed
+agricultural industry.
+
+Yours faithfully,
+ Capt. Quinton D'Arcy, J. P.
+ Sevenoaks
+%
+Lewis's Law of Travel:
+ The first piece of luggage out of the chute doesn't belong to
+anyone, ever.
+%
+Liar, n.:
+ A lawyer with a roving commission.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Liberty is always dangerous, but it is the safest thing we have.
+ -- Harry Emerson Fosdick
+%
+LIBRA (Sep. 23 to Oct. 22)
+ Your desire for justice and truth will be overshadowed by your
+ desire for filthy lucre and a decent meal. Be gracious and
+ polite. Someone is watching you, so stop staring like that.
+%
+LIBRA (Sept 23 - Oct 22)
+ You are the artistic type and have a difficult time with
+ reality. If you are a man, you are more than likely gay.
+ Chances for employment and monetary gains are excellent. Most
+ Libra women are prostitutes. All Libra people die of venereal
+ disease.
+%
+Lie, n.:
+ A very poor substitute for the truth, but the only one
+discovered to date.
+%
+Lieberman's Law:
+ Everybody lies, but it doesn't matter since nobody listens.
+%
+Life is a whim of several billion cells to be you for a while.
+%
+Life is a yo-yo, and mankind ties knots in the string.
+%
+"Life is like a bowl of soup with hairs floating on it. You have to
+eat it nevertheless."
+ -- Flaubert
+%
+"Life is like a buffet; it's not good but there's plenty of it."
+%
+Life is like a simile.
+%
+Life is like an analogy
+%
+Life is like an onion: you peel off layer after layer, then you find
+there is nothing in it.
+%
+"Life is too important to take seriously."
+ -- Corky Siegel
+%
+"Life may have no meaning -- or even worse, it may have a meaning of
+which I disapprove."
+%
+"Life to you is a bold and dashing responsibility"
+ -- a Mary Chung's fortune cookie
+%
+"Life would be much simpler and things would get done much faster if it
+weren't for other people"
+ -- Blore
+%
+Life would be so much easier if we could just look at the source code.
+%
+"Life, loathe it or ignore it, you can't like it."
+ -- Marvin, "Hitchhiker's Guide to the Galaxy"
+%
+Like so many Americans, she was trying to construct a life that made
+sense from things she found in gift shops.
+ -- Kurt Vonnegut, Jr.
+%
+Like the ski resort of girls looking for husbands and husbands looking
+for girls, the situation is not as symmetrical as it might seem.
+ -- Alan McKay
+%
+Limericks are art forms complex,
+Their topics run chiefly to sex.
+ They usually have virgins,
+ And masculine urgin's,
+And other erotic effects.
+%
+Line Printer paper is strongest at the perforations.
+%
+Linus: I guess it's wrong always to be worrying about tomorrow. Maybe
+ we should think only about today.
+Charlie Brown:
+ No, that's giving up. I'm still hoping that yesterday will get
+ better.
+%
+Living in LA is like not having a date on Saturday night.
+ -- Candice Bergen
+%
+Living on Earth may be expensive, but it includes an annual free trip
+around the Sun.
+%
+Living your life is a task so difficult, it has never been attempted
+before.
+%
+Lizzie Borden took an axe,
+And plunged it deep into the VAX;
+Don't you envy people who
+Do all the things ___YOU want to do?
+%
+Loan-department manager: "There isn't any fine print. At these
+interest rates, we don't need it."
+%
+Lobster:
+ Everyone loves these delectable crustaceans, but many cooks are
+squeamish about placing them into boiling water alive, which is the
+only proper method of preparing them. Frankly, the easiest way to
+eliminate your guilt is to establish theirs by putting them on trial
+before they're cooked. The fact is, lobsters are among the most
+ferocious predators on the sea floor, and you're helping reduce crime
+in the reefs. Grasp the lobster behind the head, look it right in its
+unmistakably guilty eyestalks and say, "Where were you on the night of
+the 21st?", then flourish a picture of a scallop or a sole and shout,
+"Perhaps this will refresh that crude neural apparatus you call a
+memory!" The lobster will squirm noticeably. It may even take a swipe
+at you with one of its claws. Incorrigible. Pop it into the pot.
+Justice has been served, and shortly you and your friends will be,
+too.
+ -- "Cooking: The Art of Using Appliances and Utensils
+ into Excuses and Apologies"
+%
+Lockwood's Long Shot:
+ The chances of getting eaten up by a lion on Main Street aren't
+one in a million, but once would be enough.
+%
+Logic is a little bird, sitting in a tree; that smells *_____awful*.
+%
+... Logically incoherent, semantically incomprehensible, and
+legally ... impeccable!
+%
+Logicians have but ill defined
+As rational the human kind.
+Logic, they say, belongs to man,
+But let them prove it if they can.
+ -- Oliver Goldsmith
+%
+Look out! Behind you!
+%
+Look, we play the Star Spangled Banner before every game. You want us
+to pay income taxes, too?
+ -- Bill Veeck, Chicago White Sox
+%
+Loose bits sink chips.
+%
+Losing your drivers' license is just God's way of saying "BOOGA,
+BOOGA!"
+%
+Lost interest? It's so bad I've lost apathy.
+%
+Loud burping while walking around the airport is prohibited in
+Halstead, Kansas.
+%
+Love and scandal are the best sweeteners of tea.
+%
+Love and scandal are the best sweeteners of tea.
+%
+Love at first sight is one of the greatest labor-saving devices the
+world has ever seen.
+%
+Love cannot be much younger than the lust for murder.
+ -- Sigmund Freud
+%
+"Love is a snowmobile racing across the tundra and then suddenly it
+flips over, pinning you underneath. At night, the ice weasels come."
+ -- Matt Groening
+%
+Love is a word that is constantly heard,
+Hate is a word that is not.
+Love, I am told, is more precious than gold.
+Love, I have read, is hot.
+But hate is the verb that to me is superb,
+And Love but a drug on the mart.
+Any kiddie in school can love like a fool,
+But Hating, my boy, is an Art.
+ -- Ogden Nash
+%
+"Love is an ideal thing, marriage a real thing; a confusion of the real with
+the ideal never goes unpunished."
+ -- Goethe
+%
+Love is sentimental measles.
+%
+Love is the triumph of imagination over intelligence.
+ -- H. L. Mencken
+%
+Love means having to say you're sorry every five minutes.
+%
+Love thy neighbor as thyself, but choose your neighborhood.
+ -- Louise Beal
+%
+Love your enemies: they'll go crazy trying to figure out what you're up
+to.
+%
+ Love's Drug
+
+My love is like an iron wand
+ That conks me on the head,
+My love is like the valium
+ That I take before my bed,
+My love is like the pint of scotch
+ That I drink when I be dry;
+And I shall love thee still, my dear,
+ Until my wife is wise.
+%
+Lowery's Law:
+ If it jams -- force it. If it breaks, it needed replacing
+anyway.
+%
+LSD melts in your mind, not in your hand.
+%
+Lubarsky's Law of Cybernetic Entomology:
+ There's always one more bug.
+%
+Lunatic Asylum, n.:
+ The place where optimism most flourishes.
+%
+Lysistrata had a good idea.
+%
+"MacDonald has the gift on compressing the largest amount of words into
+the smallest amount of thoughts."
+ -- Winston Churchill
+%
+Machine-Independent, adj.:
+ Does not run on any existing machine.
+%
+Machines certainly can solve problems, store information, correlate,
+and play games -- but not with pleasure.
+ -- Leo Rosten
+%
+Mad, adj.:
+ Affected with a high degree of intellectual independence ...
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Madam, there's no such thing as a tough child -- if you parboil them
+first for seven hours, they always come out tender.
+ -- W. C. Fields
+%
+MAFIA, n:
+ [Acronym for Mechanized Applications in Forced Insurance
+Accounting.] An extensive network with many on-line and offshore
+subsystems running under OS, DOS, and IOS. MAFIA documentation is
+rather scanty, and the MAFIA sales office exhibits that testy
+reluctance to bona fide inquiries which is the hallmark of so many DP
+operations. From the little that has seeped out, it would appear that
+MAFIA operates under a non-standard protocol, OMERTA, a tight-lipped
+variant of SNA, in which extended handshakes also perform complex
+security functions. The known timesharing aspects of MAFIA point to a
+more than usually autocratic operating system. Screen prompts carry an
+imperative, nonrefusable weighting (most menus offer simple YES/YES
+options, defaulting to YES) that precludes indifference or delay.
+Uniquely, all editing under MAFIA is performed centrally, using a
+powerful rubout feature capable of erasing files, filors, filees, and
+entire nodal aggravations.
+ -- Stan Kelly-Bootle, "The Devil's DP Dictionary"
+%
+Magnet, n.: Something acted upon by magnetism
+
+Magnetism, n.: Something acting upon a magnet.
+
+The two definition immediately foregoing are condensed from the works
+of one thousand eminent scientists, who have illuminated the subject
+with a great white light, to the inexpressible advancement of human
+knowledge.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Magnocartic, adj.:
+ Any automobile that, when left unattended, attracts shopping
+carts.
+ -- Sniglets, "Rich Hall & Friends"
+%
+Magpie, n.:
+ A bird whose theivish disposition suggested to someone that it
+might be taught to talk.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Maier's Law:
+ If the facts don't conform to the theory, they must be disposed
+ of.
+
+Corollaries:
+ (1) The bigger the theory, the better.
+ (2) The experiment may be considered a success if no more than
+ 50% of the observed measurements must be discarded to
+ obtain a correspondence with the theory.
+%
+Main's Law:
+ For every action there is an equal and opposite government
+program.
+%
+Maintainer's Motto:
+ If we can't fix it, it ain't broke.
+%
+Major Premise: Sixty men can do a piece of work sixty times as quickly
+ as one man.
+
+Minor Premise: One man can dig a posthole in sixty seconds.
+
+Conclusion: Sixty men can dig a posthole in one second.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Majority, n.:
+ That quality that distinguishes a crime from a law.
+%
+Make it myself? But I'm a physical organic chemist!
+%
+Making files is easy under the UNIX operating system. Therefore, users
+tend to create numerous files using large amounts of file space. It
+has been said that the only standard thing about all UNIX systems is
+the message-of-the-day telling users to clean up their files.
+ -- System V.2 administrator's guide
+%
+Malek's Law:
+ Any simple idea will be worded in the most complicated way.
+%
+Man 1: Ask me the what the most important thing about telling a good
+ joke is.
+
+Man 2: OK, what is the most impo --
+
+Man 1: ______TIMING!
+%
+"Man invented language to satisfy his deep need to complain."
+ -- Lily Tomlin
+%
+Man is a rational animal who always loses his temper when he is called
+upon to act in accordance with the dictates of reason.
+ -- Oscar Wilde
+%
+Man is the best computer we can put aboard a spacecraft ... and the
+only one that can be mass produced with unskilled labor.
+ -- Wernher von Braun
+%
+Man is the only animal that blushes -- or needs to.
+ -- Mark Twain
+%
+Man is the only animal that can remain on friendly terms with the
+victims he intends to eat until he eats them.
+ -- Samuel Butler
+%
+Man is the only animal that can remain on friendly terms with the
+victims he intends to eat until he eats them.
+ -- Samuel Butler (1835-1902)
+%
+Man usually avoids attributing cleverness to somebody else -- unless it
+is an enemy.
+ -- Albert Einstein
+%
+Man, n.:
+ An animal so lost in rapturous contemplation of what he thinks
+e is as to overlook what he indubitably ought to be. His hief
+occupation is extermination of other animals and his own pecies, which,
+however, multiplies with such insistent apidity as to infest the whole
+habitable earth and Canada.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Mandrell: "You know what I think?"
+Doctor: "Ah, ah that's a catch question. With a brain your size you
+ don't think, right?"
+ -- Dr. Who
+%
+Mankind's yearning to engage in sports is older than recorded history,
+dating back to the time millions of years ago, when the first primitive
+man picked up a crude club and a round rock, tossed the rock into the
+air, and whomped the club into the sloping forehead of the first
+primitive umpire.
+
+What inner force drove this first athlete? Your guess is as good as
+mine. Better, probably, because you haven't had four beers.
+ -- Dave Barry, "Sports is a Drag"
+%
+Manual, n.:
+ A unit of documentation. There are always three or more on a
+given item. One is on the shelf; someone has the others. The
+information you need in in the others.
+ -- Ray Simard
+%
+Many years ago in a period commonly know as Next Friday Afternoon,
+there lived a King who was very Gloomy on Tuesday mornings because he
+was so Sad thinking about how Unhappy he had been on Monday and how
+completely Mournful he would be on Wednesday ...
+ -- Walt Kelly
+%
+Mark's Dental-Chair Discovery:
+ Dentists are incapable of asking questions that require a
+simple yes or no answer.
+%
+Marriage is the only adventure open to the cowardly.
+ -- Voltaire
+%
+Maryel brought her bat into Exit once and started whacking people on
+the dance floor. Now everyone's doing it. It's called grand slam
+dancing.
+ -- Ransford, Chicago Reader 10/7/83
+%
+Maternity pay? Now every Tom, Dick and Harry will get pregnant.
+ -- Malcolm Smith
+%
+Math is like love -- a simple idea but it can get complicated.
+ -- R. Drabek
+%
+Mathematicians are like Frenchmen: whatever you say to them they
+translate into their own language, and forthwith it is something
+entirely different.
+ -- Johann Wolfgang von Goethe
+%
+Mathematicians often resort to something called Hilbert space, which is
+described as being n-dimensional. Like modern sex, any number can
+play.
+ -- Dr. Thor Wald, in "Beep/The Quincunx of Time", by
+ James Blish
+%
+"Matrimony isn't a word, it's a sentence."
+%
+Matter cannot be created or destroyed, nor can it be returned without a
+receipt.
+%
+Maturity is only a short break in adolescence.
+ -- Jules Feiffer
+%
+May a Misguided Platypus lay its Eggs in your Jockey Shorts
+%
+May Euell Gibbons eat your only copy of the manual!
+%
+May the Fleas of a Thousand Camels infest one of your Erogenous Zones.
+%
+May your Tongue stick to the Roof of your Mouth with the Force of a
+Thousand Caramels.
+%
+Maybe Computer Science should be in the College of Theology.
+ -- R. S. Barton
+%
+Maybe you can't buy happiness, but these days you can certainly charge
+it.
+%
+McGowan's Madison Avenue Axiom:
+ If an item is advertised as "under $50", you can bet it's not
+$19.95.
+%
+Meader's Law:
+ Whatever happens to you, it will previously have happened to
+everyone you know, only more so.
+%
+Measure with a micrometer. Mark with chalk. Cut with an axe.
+%
+Meeting, n.:
+ An assembly of people coming together to decide what person or
+department not represented in the room must solve a problem.
+%
+Men were real men, women were real women, and small, furry creatures
+from Alpha Centauri were REAL small, furry creatures from Alpha
+Centauri. Spirits were brave, men boldly split infinitives that no man
+had split before. Thus was the Empire forged.
+ -- "The Hitchhiker's Guide to the Galaxy", Douglas Adams
+%
+Men's skin is different from women's skin. It is usually bigger, and
+it has more snakes tattooed on it. Also, if you examine a woman's skin
+very closely, inch by inch, starting at her shapely ankles, then gently
+tracing the slender curve of her calves, then moving up to her ...
+ [EDITOR'S NOTE: To make room for news articles about important
+ world events such as agriculture, we're going to delete the
+ next few square feet of the woman's skin. Thank you.]
+... until finally the two of you are lying there, spent, smoking your
+cigarettes, and suddenly it hits you: Human skin is actually made up of
+billions of tiny units of protoplasm, called "cells"! And what is even
+more interesting, the ones on the outside are all dying! This is a
+fact. Your skin is like an aggressive modern corporation, where the
+older veteran cells, who have finally worked their way to the top and
+obtained offices with nice views, are constantly being shoved out the
+window head first, without so much as a pension plan, by younger
+hotshot cells moving up from below.
+ -- Dave Barry, "Saving Face"
+%
+Mencken and Nathan's Fifteenth Law of The Average American:
+ The worst actress in the company is always the manager's wife.
+%
+Mencken and Nathan's Ninth Law of The Average American:
+ The quality of a champagne is judged by the amount of noise the
+cork makes when it is popped.
+%
+Mencken and Nathan's Second Law of The Average American:
+ All the postmasters in small towns read all the postcards.
+%
+Mencken and Nathan's Sixteenth Law of The Average American:
+ Milking a cow is an operation demanding a special talent that
+is possessed only by yokels, and no person born in a large city can
+never hope to acquire it.
+%
+Menu, n.:
+ A list of dishes which the restaurant has just run out of.
+%
+Meskimen's Law:
+ There's never time to do it right, but there's always time to
+do it over.
+%
+MESSAGE ACKNOWLEDGED -- The Pershing II missiles have been launched.
+%
+Message will arrive in the mail. Destroy, before the FBI sees it.
+%
+methionylglutaminylarginyltyrosylglutamylserylleucylphenylalanylalanylglutamin-
+ylleucyllysylglutamylarginyllysylglutamylglycylalanylphenylalanylvalylprolyl-
+phenylalanylvalylthreonylleucylglycylaspartylprolylglycylisoleucylglutamylglu-
+taminylserylleucyllysylisoleucylaspartylthreonylleucylisoleucylglutamylalanyl-
+glycylalanylaspartylalanylleucylglutamylleucylglycylisoleucylprolylphenylala-
+nylserylaspartylprolylleucylalanylaspartylglycylprolylthreonylisoleucylgluta-
+minylasparaginylalanylthreonylleucylarginylalanylphenylalanylalanylalanylgly-
+cylvalylthreonylprolylalanylglutaminylcysteinylphenylalanylglutamylmethionyl-
+leucylalanylleucylisoleucylarginylglutaminyllysylhistidylprolylthreonylisoleu-
+cylprolylisoleucylglycylleucylleucylmethionyltyrosylalanylasparaginylleucylva-
+lylphenylalanylasparaginyllysylglycylisoleucylaspartylglutamylphenylalanyltyro-
+sylalanylglutaminylcysteinylglutamyllysylvalylglycylvalylaspartylserylvalylleu-
+cylvalylalanylaspartylvalylprolylvalylglutaminylglutamylserylalanylprolylphe-
+nylalanylarginylglutaminylalanylalanylleucylarginylhistidylasparaginylvalylala-
+nylprolylisoleucylphenylalanylisoleucylcysteinylprolylprolylaspartylalanylas-
+partylaspartylaspartylleucylleucylarginylglutaminylisoleucylalanylseryltyrosyl-
+glycylarginylglycyltyrosylthreonyltyrosylleucylleucylserylarginylalanylglycyl-
+valylthreonylglycylalanylglutamylasparaginylarginylalanylalanylleucylprolylleu-
+cylasparaginylhistidylleucylvalylalanyllysylleucyllysylglutamyltyrosylasparagi-
+nylalanylalanylprolylprolylleucylglutaminylglycylphenylalanylglycylisoleucylse-
+rylalanylprolylaspartylglutaminylvalyllysylalanylalanylisoleucylaspartylalanyl-
+glycylalanylalanylglycylalanylisoleucylserylglycylserylalanylisoleucylvalylly-
+sylisoleucylisoleucylglutamylglutaminylhistidylasparaginylisoleucylglutamylpro-
+lylglutamyllysylmethionylleucylalanylalanylleucyllysylvalylphenylalanylvalyl-
+glutaminylprolylmethionyllysylalanylalanylthreonylarginylserine, n.:
+ The chemical name for tryptophan synthetase A protein, a
+ 1,913-letter enzyme with 267 amino acids.
+ -- Mrs. Bryne's Dictionary of Unusual, Obscure, and
+%
+Mickey Mouse wears a Spiro Agnew watch.
+%
+Micro Credo:
+ Never trust a computer bigger than you can lift.
+%
+"Microwave oven? Whaddya mean, it's a microwave oven? I've been
+watching Channel 4 on the thing for two weeks."
+%
+"Might as well be frank, monsieur. It would take a miracle to get you
+out of Casablanca and the Germans have outlawed miracles."
+%
+Mike: "The Fourth Dimension is a shambles?"
+Bernie: "Nobody ever empties the ashtrays. People are SO
+ inconsiderate."
+ -- Gary Trudeau, "Doonesbury"
+%
+Miksch's Law:
+ If a string has one end, then it has another end.
+%
+Military intelligence is a contradiction in terms.
+ -- Groucho Marx
+%
+Military justice is to justice what military music is to music.
+ -- Groucho Marx
+%
+Millihelen, adj:
+ The amount of beauty required to launch one ship.
+%
+Millions long for immortality who do not know what to do with
+themselves on a rainy Sunday afternoon.
+ -- Susan Ertz
+%
+Millions of sensible people are too high-minded to concede that
+politics is almost always the choice of the lesser evil. "Tweedledum
+and Tweedledee," they say, "I will not vote." Having abstained, they
+are presented with a President who appoints the people who are going to
+rummage around in their lives for the next four years. Consider all
+the people who sat home in a stew in 1968 rather than vote for Hubert
+Humphrey. They showed Humphrey. Those people who taught Hubert
+Humphrey a lesson will still be enjoying the Nixon Supreme Court when
+Tricia and Julie begin to find silver threads among the gold and the
+black.
+ -- Russel Baker, "Ford without Flummery"
+%
+Mind! I don't mean to say that I know, of my own knowledge, what there
+is particularly dead about a door-nail. I might have been inclined,
+myself, to regard a coffin-nail as the deadest piece of ironmongery in
+the trade. But the wisdom of our ancestors is in the simile; and my
+unhallowed hands shall not disturb it, or the Country's done for. You
+will therefore permit me to repeat, emphatically, that Marley was as
+dead as a door-nail.
+%
+Minnie Mouse is a slow maze learner.
+%
+Minors in Kansas City, Missouri, are not allowed to purchase cap
+pistols; they may buy shotguns freely, however.
+%
+Misery loves company, but company does not reciprocate.
+%
+Misery no longer loves company. Nowadays it insists on it.
+ -- Russell Baker
+%
+Misfortune, n.:
+ The kind of fortune that never misses.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Miss, n.:
+ A title with which we brand unmarried women to indicate that
+they are in the market.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Mistakes are often the stepping stones to utter failure.
+%
+Mitchell's Law of Committees:
+ Any simple problem can be made insoluble if enough meetings are
+held to discuss it.
+%
+MOCK APPLE PIE (No Apples Needed)
+
+ Pastry to two crust 9-inch pie 36 RITZ Crackers
+2 cups water 2 cups sugar
+2 teaspoons cream of tartar 2 tablespoons lemon juice
+ Grated rind of one lemon Butter or margarine
+ Cinnamon
+
+Roll out bottom crust of pastry and fit into 9-inch pie plate. Break
+RITZ Crackers coarsely into pastry-lined plate. Combine water, sugar
+and cream of tartar in saucepan, boil gently for 15 minutes. Add lemon
+juice and rind. Cool. Pour this syrup over Crackers, dot generously
+with butter or margarine and sprinkle with cinnamon. Cover with top
+crust. Trim and flute edges together. Cut slits in top crust to let
+steam escape. Bake in a hot oven (425 F) 30 to 35 minutes, until crust
+is crisp and golden. Serve warm. Cut into 6 to 8 slices.
+ -- Found lurking on a Ritz Crackers box
+%
+Modern man is the missing link between apes and human beings.
+%
+Mohandas K. Gandhi often changed his mind publicly. An aide once asked
+him how he could so freely contradict this week what he had said just
+last week. The great man replied that it was because this week he knew
+better.
+%
+Molecule, n.:
+ The ultimate, indivisible unit of matter. It is distinguished
+from the corpuscle, also the ultimate, indivisible unit of matter, by a
+closer resemblance to the atom, also the ultimate, indivisible unit of
+matter ... The ion differs from the molecule, the corpuscle and the
+atom in that it is an ion ...
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Mollison's Bureaucracy Hypothesis:
+ If an idea can survive a bureaucratic review and be implemented
+it wasn't worth doing.
+%
+Monday is an awful way to spend one seventh of your life.
+%
+Monday, n.:
+ In Christian countries, the day after the baseball game.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Money is better than poverty, if only for financial reasons.
+%
+Money is the root of all evil, and man needs roots
+%
+Money is the root of all wealth.
+%
+Moon, n.:
+ 1. A celestial object whose phase is very important to
+hackers. See PHASE OF THE MOON. 2. Dave Moon (MOON@MC).
+%
+Mophobia, n.:
+ Fear of being verbally abused by a Mississippian.
+%
+ MORE SPORTS RESULTS:
+The Beverly Hills Freudians tied the Chicago Rogerians 0-0 last
+Saturday night. The match started with a long period of silence while
+the Freudians waited for the Rogerians to free associate and the
+Rogerians waited for the Freudians to say something they could
+paraphrase. The stalemate was broken when the Freudians' best player
+took the offensive and interpreted the Rogerians' silence as reflecting
+their anal-retentive personalities. At this the Rogerians' star player
+said "I hear you saying you think we're full of ka-ka." This started a
+fight and the match was called by officials.
+%
+More than any time in history, mankind now faces a crossroads. One
+path leads to despair and utter hopelessness, the other to total
+extinction. Let us pray that we have the wisdom to choose correctly.
+ -- Woody Allen
+%
+Mosher's Law of Software Engineering:
+ Don't worry if it doesn't work right. If everything did, you'd
+be out of a job.
+%
+Most fish live underwater, which is a terrible place to have sex
+because virtually anywhere you lie down there will be stinging crabs
+and large quantities of little fish staring at you with buggy little
+eyes. So generally when two fish want to have sex, they swim around
+and around for hours, looking for someplace to go, until finally the
+female gets really tired and has a terrible headache, and she just
+dumps her eggs right on the sand and swims away. Then the male, driven
+by some timeless, noble instinct for survival, eats the eggs. So the
+truth is that fish don't reproduce at all, but there are so many of
+them that it doesn't make any difference.
+ -- Dave Barry, "Sex and the Single Amoeba: What Every
+ Teen Should Know"
+%
+Most people can't understand how others can blow their noses differently
+than they do.
+ -- Turgenev
+%
+Most people wouldn't know music if it came up and bit them on the ass.
+ -- Frank Zappa
+%
+Mother is far too clever to understand anything she does not like.
+ -- Arnold Bennett
+%
+Mother is the invention of necessity.
+%
+Mother told me to be good, but she's been wrong before.
+%
+Mr. Cole's Axiom:
+ The sum of the intelligence on the planet is a constant; the
+population is growing.
+%
+"Multiply in your head" (ordered the compassionate Dr. Adams)
+"365,365,365,365,365,365 by 365,365,365,365,365,365. He [ten-year-old
+Truman Henry Safford] flew around the room like a top, pulled his
+pantaloons over the tops of his boots, bit his hands, rolled his eyes
+in their sockets, sometimes smiling and talking, and then seeming to be
+in an agony, until, in not more than one minute, said he,
+133,491,850,208,566,925,016,658,299,941,583,255!" An electronic
+computer might do the job a little faster but it wouldn't be as much
+fun to watch.
+ -- James R. Newman (The World of Mathematics)
+%
+Murphy's Discovery:
+ Do you know Presidents talk to the country the way men talk to
+women? They say, "Trust me, go all the way with me, and everything
+will be all right." And what happens? Nine months later, you're in
+trouble!
+%
+Murphy's Law is recursive. Washing your car to make it rain doesn't
+work.
+%
+Murphy's Law of Research:
+ Enough research will tend to support your theory.
+%
+"Murphy's Law, that brash proletarian restatement of Godel's Theorem ..."
+ -- Thomas Pynchon, "Gravity's Rainbow"
+%
+ Murray and Esther, a middle-aged Jewish couple, are touring
+Chile. Murray just got a new camera and is constantly snapping
+pictures. One day, without knowing it, he photographs a top-secret
+military installation. In an instant, armed troops surround Murray and
+Esther and hustle them off to prison.
+ They can't prove who they are because they've left their
+passports in their hotel room. For three weeks they're tortured day
+and night to get them to name their contacts in the liberation
+movement.. Finally they're hauled in front of a military court,
+charged with espionage, and sentenced to death.
+ The next morning they're lined up in front of the wall where
+they'll be shot. The sergeant in charge of the firing squad asks them
+if they have any lasts requests. Esther wants to know if she can call
+her daughter in Chicago. The sergeant says he's sorry, that's not
+possible, and turns to Murray.
+ "This is crazy!" Murray shouts. "We're not spies!" And he
+spits in the sergeants face.
+ "Murray!" Esther cries. "Please! Don't make trouble."
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+Mustgo, n.:
+ Any item of food that has been sitting in the refrigerator so
+long it has become a science project.
+ -- Sniglets, "Rich Hall & Friends"
+%
+"My advice to you, my violent friend, is to seek out gold and sit on
+it."
+ -- "Grendel", by John Gardner
+%
+My band career ended late in my senior year when John Cooper and I
+threw my amplifier out the dormitory window. We did not act in haste.
+First we checked to make sure the amplifier would fit through the
+frame, using the belt from my bathrobe to measure, then we picked up
+the amplifier and backed up to my bedroom door. Then we rushed
+forward, shouting "The WHO! The WHO!" and we launched my amplifier
+perfectly, as though we had been doing it all our lives, clean through
+the window and down onto the sidewalk, where a small but appreciative
+crowd had gathered. I would like to be able to say that this was a
+symbolic act, an effort on my part to break cleanly away from one state
+in my life and move on to another, but the truth is, Cooper and I
+really just wanted to find out what it would sound like. It sounded
+OK.
+ -- Dave Barry, "The Snake"
+%
+"My doctor told me to stop having intimate dinners for four. Unless
+there are three other people."
+ -- Orson Welles
+%
+My God, I'm depressed! Here I am, a computer with a mind a thousand
+times as powerful as yours, doing nothing but cranking out fortunes and
+sending mail about softball games. And I've got this pain right
+through my ALU. I've asked for it to be replaced, but nobody ever
+listens. I think it would be better for us both if you were to just
+log out again.
+%
+"My life is a soap opera, but who has the rights?"
+ -- MadameX
+%
+My love runs by like a day in June,
+ And he makes no friends of sorrows.
+He'll tread his galloping rigadoon
+ In the pathway or the morrows.
+He'll live his days where the sunbeams start
+ Nor could storm or wind uproot him.
+My own dear love, he is all my heart --
+ And I wish somebody'd shoot him.
+ -- Dorothy Parker
+%
+My love, he's mad, and my love, he's fleet,
+ And a wild young wood-thing bore him!
+The ways are fair to his roaming feet,
+ And the skies are sunlit for him.
+As sharply sweet to my heart he seems
+ As the fragrance of acacia.
+My own dear love, he is all my dreams --
+ And I wish he were in Asia.
+ -- Dorothy Parker
+%
+My mother loved children -- she would have given anything if I had been
+one.
+ -- Groucho Marx
+%
+My opinions may have changed, but not the fact that I am right.
+%
+My own dear love, he is strong and bold
+ And he cares not what comes after.
+His words ring sweet as a chime of gold,
+ And his eyes are lit with laughter.
+He is jubilant as a flag unfurled --
+ Oh, a girl, she'd not forget him.
+My own dear love, he is all my world --
+ And I wish I'd never met him.
+ -- Dorothy Parker
+%
+... My pants just went on a wild rampage through a Long Island Bowling
+Alley!!
+%
+"My pants just went on a wild rampage through a Long Island Bowling
+Alley!!"
+ -- Zippy the Pinhead
+%
+My pen is at the bottom of a page,
+Which, being finished, here the story ends;
+'Tis to be wished it had been sooner done,
+But stories somehow lengthen when begun.
+ -- Byron
+%
+My theology, briefly, is that the universe was dictated but not
+signed.
+ -- Christopher Morley
+%
+"My weight is perfect for my height -- which varies"
+%
+Mythology, n.:
+ The body of a primitive people's beliefs concerning its
+origin, early history, heroes, deities and so forth, as distinguished
+from the true accounts which it invents later.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+ n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
+ n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
+ n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
+ n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
+ n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
+
+ -- C code which reverses the bits in a word.
+%
+Naeser's Law:
+ You can make it foolproof, but you can't make it
+damnfoolproof.
+%
+NAPOLEON: What shall we do with this soldier, Guiseppe? Everything he
+ says is wrong.
+GUISEPPE: Make him a general, Excellency, and then everything he says
+ will be right.
+ -- G. B. Shaw, "The Man of Destiny"
+%
+Nasrudin called at a large house to collect for charity. The servant
+said "My master is out." Nasrudin replied, "Tell your master that next
+time he goes out, he should not leave his face at the window. Someone
+might steal it."
+%
+Nasrudin returned to his village from the imperial capital, and the
+villagers gathered around to hear what had passed. "At this time,"
+said Nasrudin, "I only want to say that the King spoke to me." All the
+villagers but the stupidest ran off to spread the wonderful news. The
+remaining villager asked, "What did the King say to you?" "What he
+said -- and quite distinctly, for everyone to hear -- was 'Get out of
+my way!'" The simpleton was overjoyed; he had heard words actually
+spoken by the King, and seen the very man they were spoken to.
+%
+Nasrudin walked into a shop one day, and the owner came forward to
+serve him. Nasrudin said, "First things first. Did you see me walk
+into your shop?" "Of course." "Have you ever seen me before?"
+"Never." "Then how do you know it was me?"
+%
+Nasrudin walked into a teahouse and declaimed, "The moon is more useful
+than the sun." "Why?", he was asked. "Because at night we need the
+light more."
+%
+Nasrudin was carrying home a piece of liver and the recipe for liver
+pie. Suddenly a bird of prey swooped down and snatched the piece of
+meat from his hand. As the bird flew off, Nasrudin called after it,
+"Foolish bird! You have the liver, but what can you do with it without
+the recipe?"
+%
+Nature abhors a hero. For one thing, he violates the law of
+conservation of energy. For another, how can it be the survival of the
+fittest when the fittest keeps putting himself in situations where he
+is most likely to be creamed?
+ -- Solomon Short
+%
+Nature and nature's laws lay hid in night,
+God said, "Let Newton be," and all was light.
+
+It did not last; the devil howling "Ho!
+Let Einstein be!" restored the status quo.
+%
+Nature is by and large to be found out of doors, a location where, it
+cannot be argued, there are never enough comfortable chairs.
+ -- Fran Leibowitz
+%
+Nearly all men can stand adversity, but if you want to test a man's
+character, give him power.
+ -- Abraham Lincoln
+%
+Necessity is a mother.
+%
+Neckties strangle clear thinking.
+ -- Lin Yutang
+%
+Never be led astray onto the path of virtue.
+%
+Never call a man a fool. Borrow from him.
+%
+Never call a man a fool; borrow from him.
+%
+Never commit yourself! Let someone else commit you.
+%
+Never count your chickens before they rip your lips off
+%
+Never drink coke in a moving elevator. The elevator's motion coupled
+with the chemicals in coke produce hallucinations. People tend to
+change into lizards and attack without warning, and large bats usually
+fly in the window. Additionally, you begin to believe that elevators
+have windows.
+%
+Never eat more than you can lift.
+ -- Miss Piggy
+%
+Never hit a man with glasses. Hit him with a baseball bat.
+%
+Never let your schooling interfere with your education.
+%
+Never let your sense of morals prevent you from doing what is right.
+ -- Salvor Hardin, "Foundation"
+%
+Never make anything simple and efficient when a way can be found to
+make it complex and wonderful.
+%
+Never offend people with style when you can offend them with
+substance.
+ -- Sam Brown, "The Washington Post", January 26, 1977
+%
+Never put off till tomorrow what you can avoid all together.
+%
+Never put off until tomorrow what you can do today. There might be a
+law against it by that time.
+%
+Never settle with words what you can accomplish with a flame thrower.
+%
+Never tell a lie unless it is absolutely convenient.
+%
+Never try to outstubborn a cat.
+ -- Lazarus Long, "Time Enough for Love"
+%
+Never underestimate the bandwidth of a station wagon full of tapes.
+ -- Dr. Warren Jackson, Director, UTCS
+%
+"Never underestimate the power of a small tactical nuclear weapon."
+%
+Never worry about theory as long as the machinery does what it's
+supposed to do.
+ -- R. A. Heinlein
+%
+New crypt. See /usr/news/crypt.
+%
+New Hampshire law forbids you to tap your feet, nod your head, or in
+any way keep time to the music in a tavern, restaurant, or cafe.
+%
+New members are urgently needed in the Society for Prevention of
+Cruelty to Yourself. Apply within.
+%
+New members urgently required for SUICIDE CLUB, Watford area.
+ -- Monty Python's Big Red Book
+%
+New systems generate new problems.
+%
+New Year's Eve is the time of year when a man most feels his age, and
+his wife most often reminds him to act it.
+ -- Webster's Unafraid Dictionary
+%
+New York is real. The rest is done with mirrors.
+%
+New York's got the ways and means;
+Just won't let you be.
+ -- The Grateful Dead
+%
+Newlan's Truism:
+ An "acceptable" level of unemployment means that the government
+economist to whom it is acceptable still has a job.
+%
+NEWS FLASH!!
+ Today the East German pole-vault champion became the West
+ German pole-vault champion.
+%
+ *** NEWSFLASH ***
+Russian tanks steamrolling through New Jersey!!!! Details at eleven!
+%
+Newton's Fourth Law: Every action has an equal and opposite satisfaction.
+%
+Newton's Little-Known Seventh Law:
+ A bird in the hand is safer than one overhead.
+%
+Next Friday will not be your lucky day. As a matter of fact, you don't
+have a lucky day this year.
+%
+Next to being shot at and missed, nothing is really quite as satisfying
+as an income tax refund.
+ -- F. J. Raymond
+%
+"Nice boy, but about as sharp as a sack of wet mice."
+ -- Foghorn Leghorn
+%
+Nihilism should commence with oneself.
+%
+Niklaus Wirth has lamented that, whereas Europeans pronounce his name
+correctly (Ni-klows Virt), Americans invariably mangle it into
+(Nick-les Worth). Which is to say that Europeans call him by name, but
+Americans call him by value.
+%
+Nine megs for the secretaries fair,
+Seven megs for the hackers scarce,
+Five megs for the grads in smoky lairs,
+Three megs for system source;
+
+One disk to rule them all,
+One disk to bind them,
+One disk to hold the files
+And in the darkness grind 'em.
+%
+Nine-track tapes and seven-track tapes
+ And tapes without any tracks;
+Stretchy tapes and snarley tapes
+ And tapes mixed up on the racks --
+ Take hold of the tape
+ And pull off the strip,
+ And then you'll be sure
+ Your tape drive will skip.
+
+ -- Uncle Colonel's Cursory Rhymes
+%
+"Ninety percent of the time things turn out worse than you thought they
+would. The other ten percent of the time you had no right to expect
+that much."
+ -- Augustine
+%
+Ninety-Ninety Rule of Project Schedules:
+ The first ninety percent of the task takes ninety percent of
+the time, and the last ten percent takes the other ninety percent.
+%
+"Nirvana? Thats the place where the powers that be and their friends
+hang out.
+ -- Zonker Harris
+%
+No animal should ever jump on the dining room furniture unless
+absolutely certain he can hold his own in conversation.
+ -- Fran Lebowitz
+%
+No committee could ever come up with anything as revolutionary as a
+camel -- anything as practical and as perfectly designed to perform
+effectively under such difficult conditions.
+ -- Laurence J. Peter
+%
+No good deed goes unpunished.
+ -- Clare Boothe Luce
+%
+No man in the world has more courage than the man who can stop after
+eating one peanut.
+ -- Channing Pollock
+%
+No man is an island, but some of us are long peninsulas.
+%
+No matter how subtle the wizard, a knife in the shoulder blades will
+seriously cramp his style.
+%
+No matter what other nations may say about the United States,
+immigration is still the sincerest form of flattery.
+%
+No one can make you feel inferior without your consent.
+ -- Eleanor Roosevelt
+%
+"No one gets too old to learn a new way of being stupid."
+%
+No part of this message may reproduce, store itself in a retrieval
+system, or transmit disease, in any form, without the permissiveness of
+the author.
+ -- Chris Shaw
+%
+No plain fanfold paper could hold that fractal Puff --
+He grew so fast no plotting pack could shrink him far enough.
+Compiles and simulations grew so quickly tame
+And swapped out all their data space when Puff pushed his stack frame.
+CHORUS:
+ Puff the fractal dragon was written in C,
+ And frolicked while processes switched in mainframe memory.
+ Puff the fractal dragon was written in C,
+ And frolicked while processes switched in mainframe memory.
+Puff, he grew so quickly, while others moved like snails
+And mini-Puffs would perch themselves on his gigantic tail.
+All the student hackers loved that fractal Puff
+But DCS did not like Puff, and finally said, "Enough!"
+ (chorus)
+Puff used more resources than DCS could spare.
+The operator killed Puff's job -- he didn't seem to care.
+A gloom fell on the hackers; it seemed to be the end,
+But Puff trapped the exception, and grew from naught again!
+ (chorus)
+%
+No problem is so formidable that you can't just walk away from it.
+%
+No problem is so large it can't be fit in somewhere.
+%
+"No proper program contains an indication which as an operator-applied
+occurrence identifies an operator-defining occurrence which as an
+indication-applied occurrence identifies an indication-defining
+occurrence different from the one identified by the given indication as
+an indication-applied occurrence."
+ -- ALGOL 68 Report
+%
+"No self-respecting fish would want to be wrapped in that kind of
+paper."
+ -- Mike Royko on the Chicago Sun-Times after it was
+ taken over by Rupert Murdoch
+%
+ No violence, gentlemen -- no violence, I beg of you! Consider
+the furniture!
+ -- Sherlock Holmes
+%
+"No, `Eureka' is Greek for `This bath is too hot.'"
+ -- Dr. Who
+%
+Nobody can be exactly like me. Sometimes even I have trouble doing
+it.
+ -- Tallulah Bankhead
+%
+NOBODY EXPECTS THE SPANISH INQUISITION
+%
+Nobody said computers were going to be polite.
+%
+Nobody suffers the pain of birth or the anguish of loving a child in
+order for presidents to make wars, for governments to feed on the
+substance of their people, for insurance companies to cheat the young
+and rob the old.
+ -- Lewis Lapham
+%
+Nobody wants constructive criticism. It's all we can do to put up with
+constructive praise.
+%
+Non-Reciprocal Laws of Expectations:
+ Negative expectations yield negative results.
+ Positive expectations yield negative results.
+%
+Non-sequiturs make me eat lampshades.
+%
+Noncombatant, n.:
+ A dead Quaker.
+ -- Ambrose Bierce
+%
+Nondeterminism means never having to say you are wrong.
+%
+"Nondeterminism means never having to say you are wrong."
+%
+Nostalgia isn't what it used to be.
+%
+Not far from here, by a white sun, behind a green star, lived the
+Steelypips, illustrious, industrious, and they hadn't a care: no spats
+in their vats, no rules, no schools, no gloom, no evil influence of the
+moon, no trouble from matter or antimatter -- for they had a machine, a
+dream of a machine, with springs and gears and perfect in every
+respect. And they lived with it, and on it, and under it, and inside
+it, for it was all they had -- first they saved up all their atoms,
+then they put them all together, and if one didn't fit, why they
+chipped at it a bit, and everything was just fine ...
+ -- Stanislaw Lem, "Cyberiad"
+%
+"Not Hercules could have knock'd out his brains, for he had none."
+ -- Shakespeare
+%
+"Not only is this incomprehensible, but the ink is ugly and the paper
+is from the wrong kind of tree."
+ -- Professor W.
+%
+Notes for a ballet, "The Spell": ... Suddenly Sigmund hears the flutter
+of wings, and a group of wild swans flies across the moon ... Sigmund
+is astounded to see that their leader is part swan and part woman --
+unfortunately, divided lengthwise. She enchants Sigmund, who is
+careful not to make any poultry jokes ...
+ -- Woody Allen
+%
+Nothing astonishes men so much as common sense and plain dealing.
+%
+Nothing cures insomnia like the realization that it's time to get up.
+%
+Nothing is faster than the speed of light ...
+
+To prove this to yourself, try opening the refrigerator door before the
+light comes on.
+%
+Nothing is illegal if one hundred businessmen decide to do it.
+ -- Andrew Young
+%
+Nothing is more admirable than the fortitude with which millionaires
+tolerate the disadvantages of their wealth.
+ -- Nero Wolfe
+%
+Nothing makes one so vain as being told that one is a sinner.
+Conscience makes egotists of us all.
+ -- Oscar Wilde
+%
+Nothing recedes like success.
+ -- Walter Winchell
+%
+Nothing takes the taste out of peanut butter quite like unrequited
+love.
+ -- Charlie Brown
+%
+November, n.:
+ The eleventh twelfth of a weariness.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Now and then an innocent person is sent to the legislature.
+%
+Now I lay me down to sleep
+I pray the double lock will keep;
+May no brick through the window break,
+And, no one rob me till I awake.
+%
+"Now is the time for all good men to come to."
+ -- Walt Kelly
+%
+Now that you've read Fortune's diet truths, you'll be prepared the next
+time some housewife or boutique-owner-turned-diet-expert appears on TV
+to plug her latest book. And, if you still feel a twinge of guilt for
+eating coffee cake while listening to her exhortations, ask yourself
+the following questions:
+
+(1) Do I dare trust a person who actually considers alfalfa sprouts a
+ food?
+(2) Was the author's sole motive in writing this book to get rich
+ exploiting the forlorn hopes of chubby people like me?
+(3) Would a longer life be worthwhile if it had to be lived as
+ prescribed ... without French-fried onion rings, pizza with
+ double cheese, or the occasional Mai-Tai? (Remember, living
+ right doesn't really make you live longer, it just *seems* like
+ longer.)
+
+That, and another piece of coffee cake, should do the trick.
+%
+"Now the Lord God planted a garden East of Whittier in a place called
+Yorba Linda, and out of the ground he made to grow orange trees that
+were good for food and the fruits thereof he labeled SUNKIST ..."
+ -- "The Begatting of a President"
+%
+"Now this is a totally brain damaged algorithm. Gag me with a
+smurfette."
+ -- P. Buhr, Computer Science 354
+%
+... Now you're ready for the actual shopping. Your goal should be to
+get it over with as quickly as possible, because the longer you stay in
+the mall, the longer your children will have to listen to holiday songs
+on the mall public-address system, and many of these songs can damage
+children emotionally. For example: "Frosty the Snowman" is about a
+snowman who befriends some children, plays with them until they learn
+to love him, then melts. And "Rudolph the Red-Nosed Reindeer" is about
+a young reindeer who, because of a physical deformity, is treated as an
+outcast by the other reindeer. Then along comes good, old Santa. Does
+he ignore the deformity? Does he look past Rudolph's nose and respect
+Rudolph for the sensitive reindeer he is underneath? No. Santa asks
+Rudolph to guide his sleigh, as if Rudolph were nothing more than some
+kind of headlight with legs and a tail. So unless you want your
+children exposed to this kind of insensitivity, you should shop
+quickly.
+ -- Dave Barry, "Christmas Shopping: A Survivor's Guide"
+%
+ Now, you might ask, "How do I get one of those complete home
+tool sets for under $4?" An excellent question.
+ Go to one of those really cheap discount stores where they sell
+plastic furniture in colors visible from the planet Neptune and where
+they have a food section specializing in cardboard cartons full of
+Raisinets and malted milk balls manufactured during the Nixon
+administration. In either the hardware or housewares department,
+you'll find an item imported from an obscure Oriental country and
+described as "Nine Tools in One", consisting of a little handle with
+interchangeable ends representing inscrutable Oriental notions of tools
+that Americans might use around the home. Buy it.
+ This is the kind of tool set professionals use. Not only is it
+inexpensive, but it also has a great safety feature not found in the
+so-called quality tools sets: The handle will actually break right off
+if you accidentally hit yourself or anything else, or expose it to
+direct sunlight.
+ -- Dave Barry, "The Taming of the Screw"
+%
+"Nuclear war can ruin your whole compile."
+ -- Karl Lehenbauer
+%
+"Nuclear war would mean abolition of most comforts, and disruption of
+normal routines, for children and adults alike."
+ -- Willard F. Libby, "You *Can* Survive Atomic Attack"
+%
+"Nuclear war would really set back cable."
+ -- Ted Turner
+%
+[Nuclear war] ... may not be desirable.
+ -- Edwin Meese III
+%
+Nudists are people who wear one-button suits.
+%
+(null cookie; hope that's ok)
+%
+Numeric stability is probably not all that important when you're
+guessing.
+%
+O give me a home,
+Where the buffalo roam,
+Where the deer and the antelope play,
+Where seldom is heard
+A discouraging word,
+'Cause what can an antelope say?
+%
+O'Toole's Commentary on Murphy's Law:
+ Murphy was an optimist.
+%
+"Of ______course it's the murder weapon. Who would frame someone with a
+fake?"
+%
+Of all possible committee reactions to any given agenda item, the
+reaction that will occur is the one which will liberate the greatest
+amount of hot air.
+ -- Thomas L. Martin
+%
+Of all the animals, the boy is the most unmanageable.
+ -- Plato
+%
+Of all the words of witch's doom
+There's none so bad as which and whom.
+The man who kills both which and whom
+Will be enshrined in our Who's Whom.
+ -- Fletcher Knebel
+%
+"Of course power tools and alcohol don't mix. Everyone knows power
+tools aren't soluble in alcohol ..."
+ -- Crazy Nigel
+%
+Of course there's no reason for it, it's just our policy.
+%
+Of what you see in books, believe 75%. Of newspapers, believe 50%.
+And of TV news, believe 25% -- make that 5% if the anchorman wears a
+blazer.
+%
+Office Automation, n.:
+ The use of computers to improve efficiency by removing anyone
+you would want to talk with over coffee.
+%
+Ogden's Law:
+ The sooner you fall behind, the more time you have to catch
+up.
+%
+Oh Dad! We're ALL Devo!
+%
+Oh don't the days seem lank and long
+ When all goes right and none goes wrong,
+And isn't your life extremely flat
+ With nothing whatever to grumble at!
+%
+Oh, I am a C programmer and I'm okay
+ I muck with indices and structs all day
+And when it works, I shout hoo-ray
+ Oh, I am a C programmer and I'm okay
+%
+Oh, I don't blame Congress. If I had $600 billion at my disposal, I'd
+be irresponsible, too.
+ -- Lichty & Wagner
+%
+Oh, I have slipped the surly bonds of earth,
+And danced the skies on laughter silvered wings;
+Sunward I've climbed and joined the tumbling mirth
+Of sun-split clouds and done a hundred things
+You have not dreamed of --
+Wheeled and soared and swung
+High in the sunlit silence.
+Hovering there
+I've chased the shouting wind along and flung
+My eager craft through footless halls of air.
+Up, up along delirious, burning blue
+I've topped the wind-swept heights with easy grace,
+Where never lark, or even eagle flew;
+And, while with silent, lifting mind I've trod
+The high untrespassed sanctity of space,
+Put out my hand, and touched the face of God.
+ -- John Gillespie Magee Jr., "High Flight"
+%
+Oh, well, I guess this is just going to be one of those lifetimes.
+%
+Oh, when I was in love with you,
+ Then I was clean and brave,
+And miles around the wonder grew
+ How well did I behave.
+
+And now the fancy passes by,
+ And nothing will remain,
+And miles around they'll say that I
+ Am quite myself again.
+ -- A. E. Housman
+%
+Oh, wow! Look at the moon!
+%
+"OK, now let's look at four dimensions on the blackboard."
+ -- Dr. Joy
+%
+OK, so you're a Ph.D. Just don't touch anything.
+%
+Old age is the most unexpected of things that can happen to a man.
+ -- Trotsky
+%
+Old programmers never die. They just branch to a new address.
+%
+Old soldiers never die. Young ones do.
+%
+Oliver's Law:
+ Experience is something you don't get until just after you need
+it.
+%
+Omnibiblious, adj.:
+ Indifferent to type of drink. "Oh, you can get me anything.
+I'm omnibiblious."
+%
+OMNIVERSAL AWARENESS?? Oh, YEH!! First you need four GALLONS of
+JELL-O and a BIG WRENCH!! ... I think you drop th' WRENCH in the JELL-O
+as if it was a FLAVOR, or an INGREDIENT ... or ... I ... um ...
+WHERE'S the WASHING MACHINES?
+%
+On a paper submitted by a physicist colleague:
+
+"This isn't right. This isn't even wrong."
+ -- Wolfgang Pauli
+%
+On account of being a democracy and run by the people, we are the only
+nation in the world that has to keep a government four years, no matter
+what it does.
+ -- Will Rogers
+%
+ On his first day as a bus driver, Maxey Eckstein handed in
+receipts of $65. The next day his take was $67. The third day's
+income was $62. But on the fourth day, Eckstein emptied no less than
+$283 on the desk before the cashier.
+ "Eckstein!" exclaimed the cashier. "This is fantastic. That
+route never brought in money like this! What happened?"
+ "Well, after three days on that cockamamie route, I figured
+business would never improve, so I drove over to Fourteenth Street and
+worked there. I tell you, that street is a gold mine!"
+%
+On Monday mornings I am dedicated to the proposition that all men are
+created jerks.
+ -- Avery
+%
+On Monday mornings I am dedicated to the proposition that all men are
+created jerks.
+ -- H. Allen Smith, "Let the Crabgrass Grow"
+%
+On the road, ZIPPY is a pinhead without a purpose, but never without a
+POINT ...
+%
+On the subject of C program indentation:
+
+ "In My Egotistical Opinion, most people's C programs should be
+ indented six feet downward and covered with dirt."
+ -- Blair P. Houghton
+%
+"On two occasions I have been asked [by members of Parliament!], `Pray,
+Mr. Babbage, if you put into the machine wrong figures, will the right
+answers come out?' I am not able rightly to apprehend the kind of
+confusion of ideas that could provoke such a question."
+ -- Charles Babbage
+%
+On-line, adj.:
+ The idea that a human being should always be accessible to a
+computer.
+%
+Once ... in the wilds of Afghanistan, I lost my corkscrew, and we were
+forced to live on nothing but food and water for days.
+ -- W. C. Fields, "My Little Chickadee"
+%
+Once again, we come to the Holiday Season, a deeply religious time that
+each of us observes, in his own way, by going to the mall of his
+choice.
+
+In the old days, it was not called the Holiday Season; the Christians
+called it "Christmas" and went to church; the Jews called it "Hanukka"
+and went to synagogue; the atheists went to parties and drank. People
+passing each other on the street would say "Merry Christmas!" or "Happy
+Hanukka!" or (to the atheists) "Look out for the wall!"
+ -- Dave Barry, "Christmas Shopping: A Survivor's Guide"
+%
+Once at a social gathering, Gladstone said to Disraeli, "I predict,
+Sir, that you will die either by hanging or of some vile disease".
+Disraeli replied, "That all depends upon whether I embrace your
+principals or your mistress".
+%
+Once Law was sitting on the bench
+ And Mercy knelt a-weeping.
+"Clear out!" he cried, "disordered wench!
+ Nor come before me creeping.
+Upon you knees if you appear,
+'Tis plain you have no standing here."
+
+Then Justice came. His Honor cried:
+ "YOUR states? -- Devil seize you!"
+"Amica curiae," she replied --
+ "Friend of the court, so please you."
+"Begone!" he shouted -- "There's the door --
+I never saw your face before!"
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Once the realization is accepted that even between the closest human
+beings infinite distances continue to exist, a wonderful living side by
+side can grow up, if they succeed in loving the distance between them
+which makes it possible for each to see each other whole against the
+sky.
+ -- Rainer Rilke
+%
+ Once there lived a village of creatures along the bottom of a
+great crystal river. Each creature in its own manner clung tightly to
+the twigs and rocks of the river bottom, for clinging was their way of
+life, and resisting the current what each had learned from birth. But
+one creature said at last, "I trust that the current knows where it is
+going. I shall let go, and let it take me where it will. Clinging, I
+shall die of boredom."
+ The other creatures laughed and said, "Fool! Let go, and that
+current you worship will throw you tumbled and smashed across the
+rocks, and you will die quicker than boredom!"
+ But the one heeded them not, and taking a breath did let go,
+and at once was tumbled and smashed by the current across the rocks.
+Yet, in time, as the creature refused to cling again, the current
+lifted him free from the bottom, and he was bruised and hurt no more.
+ And the creatures downstream, to whom he was a stranger, cried,
+"See a miracle! A creature like ourselves, yet he flies! See the
+Messiah, come to save us all!" And the one carried in the current
+said, "I am no more Messiah than you. The river delight to lift us
+free, if only we dare let go. Our true work is this voyage, this
+adventure.
+ But they cried the more, "Saviour!" all the while clinging to
+the rocks, making legends of a Saviour.
+%
+Once upon a time, when I was training to be a mathematician, a group of
+us bright young students taking number theory discovered the names of
+the smaller prime numbers.
+
+2: The Odd Prime --
+ It's the only even prime, therefore is odd. QED.
+3: The True Prime --
+ Lewis Carroll: "If I tell you three times, it's true."
+31: The Arbitrary Prime --
+ Determined by unanimous unvote. We needed an arbitrary prime
+ in case the prof asked for one, and so had an election. 91
+ received the most votes (well, it *looks* prime) and 3+4i the
+ next most. However, 31 was the only candidate to receive none
+ at all.
+
+Since the composite numbers are formed from primes, their qualities are
+derived from those primes. So, for instance, the number 6 is "odd but
+true", while the powers of 2 are all extremely odd numbers.
+%
+... Once you're safely in the mall, you should tie your children to you
+with ropes so the other shoppers won't try to buy them. Holiday
+shoppers have been whipped into a frenzy by months of holiday
+advertisements, and they will buy anything small enough to stuff into a
+shopping bag. If your children object to being tied, threaten to take
+them to see Santa Claus; that ought to shut them up.
+ -- Dave Barry, "Christmas Shopping: A Survivor's Guide"
+%
+Once, adv.:
+ Enough.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+One advantage of talking to yourself is that you know at least
+somebody's listening.
+ -- Franklin P. Jones
+%
+"One basic notion underlying Usenet is that it is a cooperative."
+
+Having been on USENET for going on ten years, I disagree with this.
+The basic notion underlying USENET is the flame.
+ -- Chuq Von Rospach
+%
+One can't proceed from the informal to the formal by formal means.
+%
+One cannot make an omelette without breaking eggs -- but it is amazing
+how many eggs one can break without making a decent omelette.
+ -- Professor Charles P. Issawi
+%
+One day the King decided that he would force all his subjects to tell
+the truth. A gallows was erected in front of the city gates. A herald
+announced, "Whoever would enter the city must first answer the truth to
+a question which will be put to him." Nasrudin was first in line. The
+captain of the guard asked him, "Where are you going? Tell the truth
+-- the alternative is death by hanging." "I am going," said Nasrudin,
+"to be hanged on that gallows." "I don't believe you." "Very well, if
+I have told a lie, then hang me!" "But that would make it the truth!"
+"Exactly," said Nasrudin, "your truth."
+%
+One difference between a man and a machine is that a machine is quiet
+when well oiled.
+%
+One good reason why computers can do more work than people is that they
+never have to stop and answer the phone.
+%
+One is not superior merely because one sees the world as odious.
+ -- Chateaubriand (1768-1848)
+%
+One learns to itch where one can scratch.
+ -- Ernest Bramah
+%
+One man's brain plus one other will produce one half as many ideas as
+one man would have produced alone. These two plus two more will
+produce half again as many ideas. These four plus four more begin to
+represent a creative meeting, and the ratio changes to one quarter as
+many ...
+ -- Anthony Chevins
+%
+One man's theology is another man's belly laugh.
+%
+One monk said to the other, "The fish has flopped out of the net! How
+will it live?" The other said, "When you have gotten out of the net,
+I'll tell you."
+%
+One nice thing about egotists: they don't talk about other people.
+%
+One of my less pleasant chores when I was young was to read the Bible
+from one end to the other. Reading the Bible straight through is at
+least 70 percent discipline, like learning Latin. But the good parts
+are, of course, simply amazing. God is an extremely uneven writer, but
+when He's good, nobody can touch Him.
+ -- John Gardner, NYT Book Review, Jan 1983
+%
+One of the lessons of history is that nothing is often a good thing to
+do and always a clever thing to say.
+ -- Will Durant
+%
+"... one of the main causes of the fall of the Roman Empire was that,
+lacking zero, they had no way to indicate successful termination of
+their C programs."
+ -- Robert Firth
+%
+One of the oldest problems puzzled over in the Talmud is: "Why did God
+create goyim?" The generally accepted answer is "________somebody has to buy
+retail."
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+ One of the questions that comes up all the time is: How
+enthusiastic is our support for UNIX?
+ Unix was written on our machines and for our machines many
+years ago. Today, much of UNIX being done is done on our machines.
+Ten percent of our VAXs are going for UNIX use. UNIX is a simple
+language, easy to understand, easy to get started with. It's great for
+students, great for somewhat casual users, and it's great for
+interchanging programs between different machines. And so, because of
+its popularity in these markets, we support it. We have good UNIX on
+VAX and good UNIX on PDP-11s.
+ It is our belief, however, that serious professional users will
+run out of things they can do with UNIX. They'll want a real system and
+will end up doing VMS when they get to be serious about programming.
+ With UNIX, if you're looking for something, you can easily and
+quickly check that small manual and find out that it's not there. With
+VMS, no matter what you look for -- it's literally a five-foot shelf of
+documentation -- if you look long enough it's there. That's the
+difference -- the beauty of UNIX is it's simple; and the beauty of VMS
+is that it's all there.
+ -- Ken Olsen, President of DEC, 1984
+%
+One of the rules of Busmanship, New York style, is never surrender your
+seat to another passenger. This may seem callous, but it is the best
+way, really. If one passenger were to give a seat to someone who
+fainted in the aisle, say, the others on the bus would become
+disoriented and imagine they were in Topeka, Kansas.
+%
+The Seventh Commandments for Technicians
+ Work thou not on energized equipment, for if thou dost, thy
+fellow workers will surely buy beers for thy widow and console her in
+other ways.
+%
+The First Commandment for Technicians:
+ Beware the lightening that lurketh in the undischarged
+capacitor, lest it cause thee to bounce upon thy buttocks in a most
+untechnician-like manner.
+%
+One Page Principle:
+ A specification that will not fit on one page of 8.5x11 inch
+paper cannot be understood.
+ -- Mark Ardis
+%
+"One planet is all you get."
+%
+One promising concept that I came up with right away was that you could
+manufacture personal air bags, then get a law passed requiring that
+they be installed on congressmen to keep them from taking trips. Let's
+say your congressman was trying to travel to Paris to do a fact-finding
+study on how the French government handles diseases transmitted by
+sherbet. Just when he got to the plane, his mandatory air bag,
+strapped around his waist, would inflate -- FWWAAAAAAPPPP -- thus
+rendering him too large to fit through the plane door. It could also
+be rigged to inflate whenever the congressman proposed a law. ("Mr.
+Speaker, people ask me, why should October be designated as Cuticle
+Inspection Month? And I answer that FWWAAAAAAPPPP.") This would save
+millions of dollars, so I have no doubt that the public would violently
+support a law requiring airbags on congressmen. The problem is that
+your potential market is very small: there are only around 500 members
+of Congress, and some of them, such as House Speaker "Tip" O'Neil, are
+already too large to fit on normal aircraft.
+ -- Dave Barry, "'Mister Mediocre' Restaurants"
+%
+One reason why George Washington
+Is held in such veneration:
+He never blamed his problems
+On the former Administration.
+ -- George O. Ludcke
+%
+One seldom sees a monument to a committee.
+%
+One thing the inventors can't seem to get the bugs out of is fresh
+paint.
+%
+"One thing they don't tell you about doing experimental physics is that
+sometimes you must work under adverse conditions ... like a state of
+sheer terror."
+ -- W. K. Hartmann
+%
+One way to make your old car run better is to look up the price of a
+new model.
+%
+One way to stop a runaway horse is to bet on him.
+%
+One, with God, is always a majority, but many a martyr has been burned
+at the stake while the votes were being counted.
+ -- Thomas B. Reed
+%
+One-Shot Case Study, n.:
+ The scientific equivalent of the four-leaf clover, from which
+it is concluded all clovers possess four leaves and are sometimes
+green.
+%
+Only adults have difficulty with childproof caps.
+%
+Only God can make random selections.
+%
+Only presidents, editors, and people with tapeworms have the right to
+use the editorial "we."
+%
+Only through hard work and perseverance can one truly suffer.
+%
+Optimization hinders evolution.
+%
+Optimization hinders evolution.
+%
+Oregano, n.:
+ The ancient Italian art of pizza folding.
+%
+Oregon, n.:
+ Eighty billion gallons of water with no place to go on Saturday
+night.
+%
+Organic chemistry is the chemistry of carbon compounds. Biochemistry
+is the study of carbon compounds that crawl.
+ -- Mike Adams
+%
+Osborn's Law:
+ Variables won't; constants aren't.
+%
+Others will look to you for stability, so hide when you bite your
+nails.
+%
+Our country has plenty of good five-cent cigars, but the trouble is
+they charge fifteen cents for them.
+%
+Our documentation manager was showing her two year old son around the
+office. He was introduced to me, at which time he pointed out that we
+were both holding bags of popcorn. We were both holding bottles of
+juice. But only *__he* had a lollipop.
+
+He asked his mother, "Why doesn't HE have a lollipop?"
+
+Her reply:
+
+ "He can have a lollipop any time he wants to. That's what it
+ means to be a programmer."
+%
+Our OS who art in CPU, UNIX be thy name.
+ Thy programs run, thy syscalls done,
+ In kernel as it is in user!
+%
+Our policy is, when in doubt, do the right thing.
+ -- Roy L. Ash, ex-president Litton Industries
+%
+... Our second completely true news item was sent to me by Mr. H. Boyce
+Connell Jr. of Atlanta, Ga., where he is involved in a law firm. One
+thing I like about the South is, folks there care about tradition. If
+somebody gets handed a name like "H. Boyce," he hangs on to it, puts it
+on his legal stationery, even passes it to his son, rather than do what
+a lesser person would do, such as get it changed or kill himself.
+ -- Dave Barry, "This Column is Nothing but the Truth!"
+%
+"Our vision is to speed up time, eventually eliminating it."
+ -- Alex Schure
+%
+"Our vision is to speed up time, eventually eliminating it."
+ -- Alex Schure
+%
+Ours is a world of nuclear giants and ethical infants.
+ -- General Omar N. Bradley
+%
+ OUTCONERR
+Twas FORTRAN as the doloop goes
+ Did logzerneg the ifthen block
+All kludgy were the function flows
+ And subroutines adhoc.
+
+Beware the runtime-bug my friend
+ squrooneg, the false goto
+Beware the infiniteloop
+ And shun the inprectoo.
+%
+"Outside of a dog, a book is a man's best friend: and inside a dog,
+it's too dark to read."
+ -- Groucho Marx
+%
+Over the years, I've developed my sense of deja vu so acutely that now
+I can remember things that *have* happened before ...
+%
+Overdrawn? But I still have checks left!
+%
+Overflow on /dev/null, please empty the bit bucket.
+%
+Overload -- core meltdown sequence initiated.
+%
+Ozman's Laws:
+ (1) If someone says he will do something "without fail," he
+ won't.
+ (2) The more people talk on the phone, the less money they
+ make.
+ (3) People who go to conferences are the ones who shouldn't.
+ (4) Pizza always burns the roof of your mouth.
+%
+Painting, n.:
+ The art of protecting flat surfaces from the weather, and
+exposing them to the critic.
+ -- Ambrose Bierce
+%
+panic: can't find /
+%
+panic: kernel trap (ignored)
+%
+Paradise is exactly like where you are right now ... only much, much
+better.
+ -- Laurie Anderson
+%
+Parallel lines never meet, unless you bend one or both of them.
+%
+Paranoia is simply an optimistic outlook on life.
+%
+Paranoid schizophrenics outnumber their enemies at least two to one.
+%
+Paranoids are people, too; they have their own problems. It's easy to
+criticize, but if everybody hated you, you'd be paranoid too.
+ -- D. J. Hicks
+%
+Pardo's First Postulate:
+ Anything good in life is either illegal, immoral, or
+fattening.
+
+Arnold's Addendum:
+ Everything else causes cancer in rats.
+%
+Pardon this fortune. Database under reconstruction.
+%
+Parker's Law:
+ Beauty is only skin deep, but ugly goes clean to the bone.
+%
+Parkinson's Fifth Law:
+ If there is a way to delay in important decision, the good
+bureaucracy, public or private, will find it.
+%
+Parkinson's Fourth Law:
+ The number of people in any working group tends to increase
+regardless of the amount of work to be done.
+%
+Parsley
+ is gharsley.
+ -- Ogden Nash
+%
+Parts that positively cannot be assembled in improper order will be.
+%
+"Pascal is not a high-level language."
+ -- Steven Feiner
+%
+"Pascal is Pascal is Pascal is dog meat."
+ -- M. Devine and P. Larson, Computer Science 340
+%
+Pascal Users:
+ To show respect for the 313th anniversary (tomorrow) of the
+death of Blaise Pascal, your programs will be run at half speed.
+%
+Pascal, n.:
+ A programming language named after a man who would turn over in
+his grave if he knew about it.
+%
+Passionate hatred can give meaning and purpose to an empty life.
+ -- Eric Hoffer
+%
+Patageometry, n.:
+ The study of those mathematical properties that are invariant
+under brain transplants.
+%
+Paul Revere was a tattle-tale
+%
+Paul's Law:
+ In America, it's not how much an item costs, it's how much you
+save.
+%
+Paul's Law:
+ You can't fall off the floor.
+%
+Peace, n.:
+ In international affairs, a period of cheating between two
+periods of fighting.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Peanut Blossoms
+
+4 cups sugar 16 tbsp. milk
+4 cups brown sugar 4 tsp. vanilla
+4 cups shortening 14 cups flour
+8 eggs 4 tsp. soda
+4 cups peanut butter 4 tsp. salt
+
+Shape dough into balls. Roll in sugar and bake on ungreased cookie
+sheet at 375 F. for 10-12 minutes. Immediately top each cookie with a
+Hershey's kiss or star pressing down firmly to crack cookie. Makes a
+hell of a lot.
+%
+Pecor's Health-Food Principle:
+ Never eat rutabaga on any day of the week that has a "y" in
+it.
+%
+Pedaeration, n.:
+ The perfect body heat achieved by having one leg under the
+sheet and one hanging off the edge of the bed.
+ -- Rich Hall, "Sniglets"
+%
+Penguin Trivia #46:
+ Animals who are not penguins can only wish they were.
+ -- Chicago Reader 10/15/82
+%
+People need good lies. There are too many bad ones.
+ -- Bokonon, "Cat's Cradle" by Kurt Vonnegut, Jr.
+%
+People often find it easier to be a result of the past than a cause of
+the future.
+%
+"People think love is an emotion. Love is good sense."
+ -- Ken Kesey
+%
+People usually get what's coming to them ... unless it's been mailed.
+%
+People who are funny and smart and return phone calls get much better
+press than people who are just funny and smart.
+ -- Howard Simons, "The Washington Post"
+%
+People who claim they don't let little things bother them have never
+slept in a room with a single mosquito.
+%
+People who have what they want are very fond of telling people who
+haven't what they want that they don't want it.
+ -- Ogden Nash
+%
+People will accept your ideas much more readily if you tell them that
+Benjamin Franklin said it first.
+%
+People will buy anything that's one to a customer.
+%
+People will do tomorrow what they did today because that is what they
+did yesterday.
+%
+Pereant, inquit, qui ante nos nostra dixerunt.
+"Confound those who have said our remarks before us."
+ -- Aelius Donatus
+%
+Perfect day for scrubbing the floor and other exciting things.
+%
+Perfection is reached, not when there is no longer anything to add, but
+when there is no longer anything to take away.
+ -- Antoine de Saint-Exupery
+%
+Personifiers Unite! You have nothing to lose but Mr. Dignity!
+%
+Peter's Law of Substitution:
+ Look after the molehills, and the mountains will look after
+themselves.
+%
+Philadelphia is not dull -- it just seems so because it is next to
+exciting Camden, New Jersey.
+%
+Philogyny recapitulates erogeny; erogeny recapitulates philogyny.
+%
+Philosophy will clip an angel's wings.
+ -- John Keats
+%
+Pick another fortune cookie.
+%
+"Picture the sun as the origin of two intersecting 6-dimensional
+hyperplanes from which we can deduce a certain transformational
+sequence which gives us the terminal velocity of a rubber duck ..."
+%
+Pig, n.:
+ An animal (Porcus omnivorous) closely allied to the human race
+by the splendor and vivacity of its appetite, which, however, is
+inferior in scope, for it balks at pig.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+PISCES (Feb. 19 - Mar. 20)
+ You have a vivid imagination and often think you are being
+followed by the CIA or FBI. You have minor influence over your
+associates and people resent your flaunting of your power. You lack
+confidence and you are generally a coward. Pisces people do terrible
+things to small animals.
+%
+PISCES (Feb. 19 to Mar. 20)
+ Take the high road, look for the good things, carry the
+American Express card and a weapon. The world is yours today, as
+nobody else wants it. Your mortgage will be foreclosed. You will
+probably get run over by a bus.
+%
+ Pittsburgh Driver's Test
+
+(7) The car directly in front of you has a flashing right tail light
+ but a steady left tail light. This means
+
+ (a) one of the tail lights is broken; you should blow your horn
+ to call the problem to the driver's attention.
+ (b) the driver is signaling a right turn.
+ (c) the driver is signaling a left turn.
+ (d) the driver is from out of town.
+
+The correct answer is (d). Tail lights are used in some foreign
+countries to signal turns.
+%
+ Pittsburgh Driver's Test
+
+(8) Pedestrians are
+
+ (a) irrelevant.
+ (b) communists.
+ (c) a nuisance.
+ (d) difficult to clean off the front grille.
+
+The correct answer is (a). Pedestrians are not in cars, so they are
+totally irrelevant to driving; you should ignore them completely.
+%
+Pity the meek, for they shall inherit the earth.
+ -- Don Marquis
+%
+PL/1, "the fatal disease", belongs more to the problem set than to the
+solution set.
+ -- E. W. Dijkstra
+%
+"Plaese porrf raed."
+ -- Prof. Michael O'Longhlin, S.U.N.Y. Purchase
+%
+Plato, by the way, wanted to banish all poets from his proposed Utopia
+because they were liars. The truth was that Plato knew philosophers
+couldn't compete successfully with poets.
+ -- Kilgore Trout (Philip J. Farmer) "Venus on the Half
+ Shell"
+%
+Play Rogue, visit exotic locations, meet strange creatures and kill
+them.
+%
+Playing an unamplified electric guitar is like strumming on a picnic
+table.
+ -- Dave Barry, "The Snake"
+%
+Please ignore previous fortune.
+%
+Please take note:
+%
+Please try to limit the amount of "this room doesn't have any bazingas"
+until you are told that those rooms are "punched out". Once punched
+out, we have a right to complain about atrocities, missing bazingas,
+and such.
+ -- N. Meyrowitz
+%
+Please, won't somebody tell me what diddie-wa-diddie means?
+%
+ Plumbing is one of the easier of do-it-yourself activities,
+requiring only a few simple tools and a willingness to stick your arm
+into a clogged toilet. In fact, you can solve many home plumbing
+problems, such as annoying faucet drip, merely by turning up the
+radio. But before we get into specific techniques, let's look at how
+plumbing works.
+ A plumbing system is very much like your electrical system,
+except that instead of electricity, it has water, and instead of wires,
+it has pipes, and instead of radios and waffle irons, it has faucets
+and toilets. So the truth is that your plumbing systems is nothing at
+all like your electrical system, which is good, because electricity can
+kill you.
+ -- Dave Barry, "The Taming of the Screw"
+%
+PLUNDERER'S THEME
+(to Supercalifragilisticexpialidocius)
+
+Pillage, rape, and loot and burn, but all in moderation.
+If you do the things we say, then you'll soon rule the nation.
+Kill your foes and enemies and then kill your relations.
+Pillage, rape, and loot and burn, but all in moderation.
+%
+Pohl's law:
+ Nothing is so good that somebody, somewhere, will not hate it.
+%
+Police: Good evening, are you the host?
+Host: No.
+Police: We've been getting complaints about this party.
+Host: About the drugs?
+Police: No.
+Host: About the guns, then? Is somebody complaining about the guns?
+Police: No, the noise.
+Host: Oh, the noise. Well that makes sense because there are no guns
+ or drugs here. (An enormous explosion is heard in the
+ background.) Or fireworks. Who's complaining about the noise?
+ The neighbors?
+Police: No, the neighbors fled inland hours ago. Most of the recent
+ complaints have come from Pittsburgh. Do you think you could
+ ask the host to quiet things down?
+Host: No Problem. (At this point, a Volkswagon bug with primitive
+ religious symbols drawn on the doors emerges from the living
+ room and roars down the hall, past the police and onto the
+ lawn, where it smashes into a tree. Eight guests tumble out
+ onto the grass, moaning.) See? Things are starting to wind
+ down.
+%
+Political T.V. commercials prove one thing: some candidates can tell
+all their good points and qualifications in just 30 seconds.
+%
+Politician, n.:
+ An eel in the fundamental mud upon which the superstructure of
+organized society is reared. When he wriggles, he mistakes the
+agitation of his tail for the trembling of the edifice. As compared
+with the statesman, he suffers the disadvantage of being alive.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Politician, n.:
+ From the Greek "poly" ("many") and the French "tete" ("head" or
+"face," as in "tete-a-tete": head to head or face to face). Hence
+"polytetien", a person of two or more faces.
+ -- Martin Pitt
+%
+Politicians are the same all over. They promise to build a bridge even
+where there is no river.
+ -- Nikita Khrushchev
+%
+Politics is like coaching a football team. you have to be smart enough
+to understand the game but not smart enough to lose interest.
+%
+Polymer physicists are into chains.
+%
+Pope Goestheveezl was the shortest reigning pope in the history of the
+Church, reigning for two hours and six minutes on 1 April 1866. The
+white smoke had hardly faded into the blue of the Vatican skies before
+it dawned on the assembled multitudes in St. Peter's Square that his
+name had hilarious possibilities. The crowds fell about, helpless with
+laughter, singing
+ Half a pound of tuppenny rice
+ Half a pound of treacle
+ That's the way the chimney smokes
+ Pope Goestheveezl
+The square was finally cleared by armed carabineri with tears of
+laughter streaming down their faces. The event set a record for
+hilarious civic functions, smashing the previous record set when Baron
+Hans Neizant B"ompzidaize was elected Landburgher of K"oln in 1653.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+Portable, adj.:
+ Survives system reboot.
+%
+Positive, adj.:
+ Mistaken at the top of one's voice.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Pound for pound, the amoeba is the most vicious animal on earth.
+%
+"Power corrupts. Absolute power is kind of neat"
+ -- John Lehman, Secretary of the Navy 1981-1987
+%
+Power corrupts. And atomic power corrupts atomically.
+%
+Power, n:
+ The only narcotic regulated by the SEC instead of the FDA.
+%
+Practical people would be more practical if they would take a little
+more time for dreaming.
+ -- J. P. McEvoy
+%
+Predestination was doomed from the start.
+%
+President Reagan has noted that there are too many economic pundits and
+forecasters and has decided on an excess prophets tax.
+%
+President Thieu says he'll quit if he doesn't get more than 50% of the
+vote. In a democracy, that's not called quitting.
+ -- The Washington Post
+%
+Pretend to spank me -- I'm a pseudo-masochist!
+%
+Preudhomme's Law of Window Cleaning:
+ It's on the other side.
+%
+[Prime Minister Joseph] Chamberlain loves the working man -- he loves
+to see him work.
+ -- Winston Churchill
+%
+Pro is to con as progress is to Congress.
+%
+Probable-Possible, my black hen,
+She lays eggs in the Relative When.
+She doesn't lay eggs in the Positive Now
+Because she's unable to postulate how.
+ -- Frederick Winsor
+%
+Probably the question asked most often is: Do one-celled animals have
+orgasms? The answer is yes, they have orgasms almost constantly, which
+is why they don't mind living in pools of warm slime.
+ -- Dave Barry, "Sex and the Single Amoeba: What Every
+ Teen Should Know"
+%
+Prof: So the American government went to IBM to come up with a data
+ encryption standard and they came up with ...
+Student: EBCDIC!"
+%
+Professor Gorden Newell threw another shutout in last week's Chem.
+Eng. 130 midterm. Once again no student received a single point on
+his exam. Newell has now tossed five shutouts this quarter. Newell's
+earned exam average has now dropped to a phenomenal 30%
+%
+Proof techniques #1: Proof by Induction.
+
+This technique is used on equations with "_n" in them. Induction
+techniques are very popular, even the military used them.
+
+SAMPLE: Proof of induction without proof of induction.
+
+ We know it's true for _n equal to 1. Now assume that it's true
+for every natural number less than _n. _N is arbitrary, so we can take _n
+as large as we want. If _n is sufficiently large, the case of _n+1 is
+trivially equivalent, so the only important _n are _n less than _n. We
+can take _n = _n (from above), so it's true for _n+1 because it's just
+about _n.
+ QED. (QED translates from the Latin as "So what?")
+%
+Proof techniques #2: Proof by Oddity.
+ SAMPLE: To prove that horses have an infinite number of legs.
+(1) Horses have an even number of legs.
+(2) They have two legs in back and fore legs in front.
+(3) This makes a total of six legs, which certainly is an odd number of
+ legs for a horse.
+(4) But the only number that is both odd and even is infinity.
+(5) Therefore, horses must have an infinite number of legs.
+
+Topics is be covered in future issues include proof by:
+ Intimidation
+ Gesticulation (handwaving)
+ "Try it; it works"
+ Constipation (I was just sitting there and ...)
+ Blatant assertion
+ Changing all the 2's to _n's
+ Mutual consent
+ Lack of a counterexample, and
+ "It stands to reason"
+%
+Proposed Additions to the PDP-11 Instruction Set:
+
+BBW Branch Both Ways
+BEW Branch Either Way
+BBBF Branch on Bit Bucket Full
+BH Branch and Hang
+BMR Branch Multiple Registers
+BOB Branch On Bug
+BPO Branch on Power Off
+BST Backspace and Stretch Tape
+CDS Condense and Destroy System
+CLBR Clobber Register
+CLBRI Clobber Register Immediately
+CM Circulate Memory
+CMFRM Come From -- essential for truly structured programming
+CPPR Crumple Printer Paper and Rip
+CRN Convert to Roman Numerals
+%
+Proposed Additions to the PDP-11 Instruction Set:
+
+DC Divide and Conquer
+DMPK Destroy Memory Protect Key
+DO Divide and Overflow
+EMPC Emulate Pocket Calculator
+EPI Execute Programmer Immediately
+EROS Erase Read Only Storage
+EXCE Execute Customer Engineer
+HCF Halt and Catch Fire
+IBP Insert Bug and Proceed
+INSQSW Insert into queue somewhere (for FINO queues [First in never out])
+PBC Print and Break Chain
+PDSK Punch Disk
+%
+Proposed Additions to the PDP-11 Instruction Set:
+
+PI Punch Invalid
+POPI Punch Operator Immediately
+PVLC Punch Variable Length Card
+RASC Read And Shred Card
+RPM Read Programmers Mind
+RSSC reduce speed, step carefully (for improved accuracy)
+RTAB Rewind tape and break
+RWDSK rewind disk
+RWOC Read Writing On Card
+SCRBL scribble to disk - faster than a write
+SLC Search for Lost Chord
+SPSW Scramble Program Status Word
+SRSD Seek Record and Scar Disk
+STROM Store in Read Only Memory
+TDB Transfer and Drop Bit
+WBT Water Binary Tree
+%
+"Protozoa are small, and bacteria are small, but viruses are smaller
+than the both put together."
+%
+Psychiatrists say that one out of four people are mentally ill. Check
+three friends. If they're OK, you're it.
+%
+Psychotherapy is the theory that the patient will probably get well
+anyhow and is certainly a damn fool.
+ -- H. L. Mencken
+%
+Puns are little "plays on words" that a certain breed of person loves
+to spring on you and then look at you in a certain self-satisfied way
+to indicate that he thinks that you must think that he is by far the
+cleverest person on Earth now that Benjamin Franklin is dead, when in
+fact what you are thinking is that if this person ever ends up in a
+lifeboat, the other passengers will hurl him overboard by the end of
+the first day even if they have plenty of food and water.
+ -- Dave Barry, "Why Humor is Funny"
+%
+Pure drivel tends to drive ordinary drivel off of the TV screen.
+%
+Pure drivel tends to drive ordinary drivel off the TV screen.
+%
+Pushing 40 is exercise enough.
+%
+Put no trust in cryptic comments.
+%
+Put your Nose to the Grindstone!
+ -- Amalgamated Plastic Surgeons and Toolmakers, Ltd.
+%
+Putt's Law:
+ Technology is dominated by two types of people:
+ Those who understand what they do not manage.
+ Those who manage what they do not understand.
+%
+Q: Do you know what the death rate around here is?
+A: One per person.
+%
+Q: How did you get into artificial intelligence?
+A: Seemed logical -- I didn't have any real intelligence.
+%
+Q: How many DEC repairman does it take to fix a flat ?
+A: Five; four to hold the car up and one to swap tires.
+%
+Q: How many DEC repairman does it take to fix a flat?
+A: Five; four to hold the car up and one to swap tires.
+
+Q: How long does it take?
+A: It's indeterminate. It will depend upon how many flats they've
+ brought with them.
+
+Q: What happens if you've got TWO flats?
+A: They replace your generator.
+%
+Q: How many existentialists does it take to screw in a lightbulb?
+A: Two. One to screw it in and one to observe how the lightbulb
+ itself symbolizes a single incandescent beacon of subjective
+ reality in a netherworld of endless absurdity reaching out toward a
+ maudlin cosmos of nothingness.
+%
+Q: How many heterosexual males does it take to screw in a light bulb
+ in San Francisco?
+A: Both of them.
+%
+Q: How many IBM cpu's does it take to do a logical right shift?
+A: 33. 1 to hold the bits and 32 to push the register.
+%
+Q: How many IBM CPU's does it take to execute a job?
+A: Four; three to hold it down, and one to rip its head off.
+%
+Q: How many IBM types does it take to change a light bulb?
+A: 100. Ten to do it, and 90 to write document number GC7500439-0001,
+ Multitasking Incandescent Source System Facility, of which 10% of
+ the pages state only "This page intentionally left blank", and 20%
+ of the definitions are of the form "A ...... consists of sequences
+ of non-blank characters separated by blanks".
+%
+Q: How many journalists does it take to screw in a lightbulb?
+A: Three. One to report it as an inspired government program to bring
+ light to the people, one to report it as a diabolical government
+ plot to deprive the poor of darkness, and one to win a pulitzer
+ prize for reporting that Electric Company hired a lightbulb
+ assassin to break the bulb in the first place.
+%
+Q: How many Martians does it take to screw in a lightbulb?
+A: One and a half.
+%
+Q: How many mathematicians does it take to screw in a lightbulb?
+A: One. He gives it to six Californians, thereby reducing the problem
+ to the earlier joke.
+%
+Q: How many Oregonians does it take to screw in a light bulb?
+A: Three. One to screw in the lightbulb and two to fend off all those
+ Californians trying to share the experience.
+%
+Q: How many surrealists does it take to change a light bulb?
+A: Two. One to hold the giraffe and the other to fill the bathtub
+ with brightly colored machine tools.
+%
+Q: How many Zen masters does it take to screw in a light bulb?
+A: None. The Universe spins the bulb, and the Zen master stays out
+ of the way.
+%
+Q: What's a light-year?
+A: One-third less calories than a regular year.
+%
+Q: Why did the tachyon cross the road?
+A: Because it was on the other side.
+%
+Q: Why do ducks have flat feet?
+A: To stamp out forest fires.
+
+Q: Why do elephants have flat feet?
+A: To stamp out flaming ducks.
+%
+Q: Why do mountain climbers rope themselves together?
+A: To prevent the sensible ones from going home.
+%
+Q: Somebody just posted that Roman Polanski directed Star Wars. What
+ should I do?
+
+A: Post the correct answer at once! We can't have people go on
+ believing that! Very good of you to spot this. You'll probably be
+ the only one to make the correction, so post as soon as you can. No
+ time to lose, so certainly don't wait a day, or check to see if
+ somebody else has made the correction.
+
+ And it's not good enough to send the message by mail. Since you're
+ the only one who really knows that it was Francis Coppola, you have
+ to inform the whole net right away!
+
+ -- Brad Templeton, "Emily Postnews Answers Your Questions
+ on Netiquette"
+%
+Quality Control, n.:
+ The process of testing one out of every 1,000 units coming off
+a production line to make sure that at least one out of 100 works.
+%
+Question:
+Man Invented Alcohol,
+God Invented Grass.
+Who do you trust?
+%
+Quick!! Act as if nothing has happened!
+%
+Quick, sing me the BUDAPEST NATIONAL ANTHEM!!
+%
+Quidquid latine dictum sit, altum viditur.
+
+(Whatever is said in Latin sounds profound.)
+%
+Quigley's Law:
+ Whoever has any authority over you, no matter how small, will
+atttempt to use it.
+%
+QUOTE OF THE DAY:
+
+ `
+
+%
+"Qvid me anxivs svm?"
+%
+QWERT (kwirt), n. [MW < OW qwertyuiop, a thirteenth]:
+ 1. a unit of weight equal to 13 poiuyt avoirdupois (or 1.69
+kiloliks), commonly used in structural engineering; 2. [colloq.] one
+thirteenth the load that a fully grown sligo can carry; 3. [anat.] a
+painful irritation of the dermis in the region of the anus; 4. [slang]
+person who excites in others the symptoms of a qwert.
+ -- Webster's Middle World Dictionary, 4th ed.
+%
+Radioactive cats have 18 half-lives.
+%
+Rattling around the back of my head is a disturbing image of something
+I saw at the airport ... Now I'm remembering, those giant piles of
+computer magazines right next to "People" and "Time" in the airport
+store. Does it bother anyone else that half the world is being told
+all of our hard-won secrets of computer technology? Remember how all
+the lawyers cried foul when "How to Avoid Probate" was published? Are
+they taking no-fault insurance lying down? No way! But at the current
+rate it won't be long before there are stacks of the "Transactions on
+Information Theory" at the A&P checkout counters. Who's going to be
+impressed with us electrical engineers then? Are we, as the saying
+goes, giving away the store?
+ -- Robert W. Lucky, IEEE President
+%
+Ray's Rule of Precision:
+ Measure with a micrometer. Mark with chalk. Cut with an axe.
+%
+Razors pain you;
+Rivers are damp;
+Acids stain you;
+And drugs cause cramp.
+Guns aren't lawful;
+Nooses give;
+Gas smells awful;
+You might as well live.
+ -- Dorothy Parker
+%
+Re graphics: A picture is worth 10K words -- but only those to describe
+the picture. Hardly any sets of 10K words can be adequately described
+with pictures.
+%
+Reader, suppose you were an idiot. And suppose you were a member of
+Congress. But I repeat myself.
+ -- Mark Twain
+%
+Real computer scientists admire ADA for its overwhelming aesthetic
+value but they find it difficult to actually program in it, as it is
+much too large to implement. Most computer scientists don't notice
+this because they are still arguing over what else to add to ADA.
+%
+Real computer scientists despise the idea of actual hardware. Hardware
+has limitations, software doesn't. It's a real shame that Turing
+machines are so poor at I/O.
+%
+Real computer scientists don't comment their code. The identifiers are
+so long they can't afford the disk space.
+%
+Real computer scientists don't program in assembler. They don't write
+in anything less portable than a number two pencil.
+%
+Real computer scientists don't write code. They occasionally tinker
+with `programming systems', but those are so high level that they
+hardly count (and rarely count accurately; precision is for
+applications.)
+%
+Real computer scientists only write specs for languages that might run
+on future hardware. Nobody trusts them to write specs for anything homo
+sapiens will ever be able to fit on a single planet.
+%
+Real programmers disdain structured programming. Structured
+programming is for compulsive neurotics who were prematurely toilet-
+trained. They wear neckties and carefully line up pencils on otherwise
+clear desks.
+%
+Real programmers don't bring brown-bag lunches. If the vending machine
+doesn't sell it, they don't eat it. Vending machines don't sell
+quiche.
+%
+Real programmers don't comment their code. It was hard to write, it
+should be hard to understand.
+%
+Real programmers don't draw flowcharts. Flowcharts are, after all, the
+illiterate's form of documentation. Cavemen drew flowcharts; look how
+much good it did them.
+%
+Real Programmers don't play tennis, or any other sport that requires
+you to change clothes. Mountain climbing is OK, and real programmers
+wear their climbing boots to work in case a mountain should suddenly
+spring up in the middle of the machine room.
+%
+Real programmers don't write in BASIC. Actually, no programmers write
+in BASIC after reaching puberty.
+%
+Real programmers don't write in FORTRAN. FORTRAN is for pipe stress
+freaks and crystallography weenies. FORTRAN is for wimp engineers who
+wear white socks.
+%
+Real Programmers don't write in PL/I. PL/I is for programmers who
+can't decide whether to write in COBOL or FORTRAN.
+%
+Real Programmers think better when playing Adventure or Rogue.
+%
+Real Programs don't use shared text. Otherwise, how can they use
+functions for scratch space after they are finished calling them?
+%
+Real software engineers don't debug programs, they verify correctness.
+This process doesn't necessarily involve execution of anything on a
+computer, except perhaps a Correctness Verification Aid package.
+%
+Real software engineers don't like the idea of some inexplicable and
+greasy hardware several aisles away that may stop working at any
+moment. They have a great distrust of hardware people, and wish that
+systems could be virtual at *___all* levels. They would like personal
+computers (you know no one's going to trip over something and kill your
+DFA in mid-transit), except that they need 8 megabytes to run their
+Correctness Verification Aid packages.
+%
+Real software engineers work from 9 to 5, because that is the way the
+job is described in the formal spec. Working late would feel like
+using an undocumented external procedure.
+%
+Real Time, adj.:
+ Here and now, as opposed to fake time, which only occurs there
+and then.
+%
+Real Users are afraid they'll break the machine -- but they're never
+afraid to break your face.
+%
+Real Users find the one combination of bizarre input values that shuts
+down the system for days.
+%
+Real Users hate Real Programmers.
+%
+Real Users know your home telephone number.
+%
+Real Users never know what they want, but they always know when your
+program doesn't deliver it.
+%
+Real Users never use the Help key.
+%
+Real World, The n.:
+ 1. In programming, those institutions at which programming may
+be used in the same sentence as FORTRAN, COBOL, RPG, IBM, etc. 2. To
+programmers, the location of non-programmers and activities not related
+to programming. 3. A universe in which the standard dress is shirt and
+tie and in which a person's working hours are defined as 9 to 5. 4.
+The location of the status quo. 5. Anywhere outside a university.
+"Poor fellow, he's left MIT and gone into the real world." Used
+pejoratively by those not in residence there. In conversation, talking
+of someone who has entered the real world is not unlike talking about a
+deceased person.
+%
+Reality is a cop-out for people who can't handle drugs.
+%
+Reality is an obstacle to hallucination.
+%
+Reality is bad enough, why should I tell the truth?
+ -- Patrick Sky
+%
+Reality is for people who lack imagination.
+%
+Reality is for those who can't face Science Fiction.
+%
+Reality is just a convenient measure of complexity.
+ -- Alvy Ray Smith
+%
+"Reality is that which, when you stop believing in it, doesn't go
+away".
+ -- Philip K. Dick
+%
+"Really ?? What a coincidence, I'm shallow too!!"
+%
+Receiving a million dollars tax free will make you feel better than
+being flat broke and having a stomach ache.
+ -- Dolph Sharp, "I'm O.K., You're Not So Hot"
+%
+Recession is when your neighbor loses his job. Depression is when you
+lose your job. These economic downturns are very difficult to predict,
+but sophisticated econometric modeling houses like Data Resources and
+Chase Econometrics have successfully predicted 14 of the last 3
+recessions.
+%
+Reclaimer, spare that tree!
+Take not a single bit!
+It used to point to me,
+Now I'm protecting it.
+It was the reader's CONS
+That made it, paired by dot;
+Now, GC, for the nonce,
+Thou shalt reclaim it not.
+%
+ "Reflections on Ice-Breaking"
+Candy
+Is dandy
+But liquor
+Is quicker.
+ -- Ogden Nash
+%
+"Reintegration complete," ZORAC advised. "We're back in the universe
+again ..." An unusually long pause followed, "... but I don't know
+which part. We seem to have changed our position in space." A
+spherical display in the middle of the floor illuminated to show the
+starfield surrounding the ship.
+
+"Several large, artificial constructions are approaching us," ZORAC
+announced after a short pause. "The designs are not familiar, but they
+are obviously the products of intelligence. Implications: we have been
+intercepted deliberately by a means unknown, for a purpose unknown, and
+transferred to a place unknown by a form of intelligence unknown.
+Apart from the unknowns, everything is obvious."
+ -- James P. Hogan, "Giants Star"
+%
+Reisner's Rule of Conceptual Inertia:
+ If you think big enough, you'll never have to do it.
+%
+Religion has done love a great service by making it a sin.
+ -- Anatole France
+%
+"Rembrandt's first name was Beauregard, which is why he never used
+it."
+ -- Dave Barry
+%
+Remember that whatever misfortune may be your lot, it could only be
+worse in Cleveland.
+ -- National Lampoon, "Deteriorata"
+%
+Remember, drive defensively! And of course, the best defense is a good
+offense!
+%
+Remember, even if you win the rat race -- you're still a rat.
+%
+Remember, UNIX spelled backwards is XINU.
+%
+Remember: Silly is a state of Mind, Stupid is a way of Life.
+ -- Dave Butler
+%
+Renning's Maxim:
+ Man is the highest animal. Man does the classifying.
+%
+Reporter (to Mahatma Gandhi): Mr Gandhi, what do you think of Western
+ Civilization?
+Gandhi: I think it would be a good idea.
+%
+Reporter, n.:
+ A writer who guesses his way to the truth and dispels it with a
+tempest of words.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+REPORTER: Senator, are you for or against the MX missile system?
+
+SENATOR: Bob, the MX missile system reminds me of an old saying that
+the country folk in my state like to say. It goes like this: "You can
+carry a pig for six miles, but if you set it down it might run away."
+I have no idea why the country folk say this. Maybe there's some kind
+of chemical pollutant in their drinking water. That is why I pledge to
+do all that I can to protect the environment of this great nation of
+ours, and put prayer back in the schools, where it belongs. What we
+need is jobs, not empty promises. I realize I'm risking my political
+career be being so outspoken on a sensitive issue such as the MX, but
+that's just the kind of straight-talking honest person I am, and I
+can't help it.
+ -- Dave Barry, "On Presidential Politics"
+%
+Research is what I'm doing when I don't know what I'm doing.
+ -- Wernher von Braun
+%
+Resisting temptation is easier when you think you'll probably get
+another chance later on.
+%
+Review Questions
+
+(1) If Nerd on the planet Nutley starts out in his spaceship at 20 KPH,
+ and his speed doubles every 3.2 seconds, how long will it be before
+ he exceeds the speed of light? How long will it be before the
+ Galactic Patrol picks up the pieces of his spaceship?
+
+(2) If Roger Rowdy wrecks his car every week, and each week he breaks
+ twice as many bones as before, how long will it be before he breaks
+ every bone in his body? How long will it be before they cut off
+ his insurance? Where does he get a new car every week?
+
+(3) If Johnson drinks one beer the first hour (slow start), four beers
+ the next hour, nine beers the next, etc., and stacks the cans in a
+ pyramid, how soon will Johnson's pyramid be larger than King
+ Tut's? When will it fall on him? Will he notice?
+%
+Rhode's Law:
+ When any principle, law, tenet, probability, happening,
+circumstance, or result can in no way be directly, indirectly,
+empirically, or circuitously proven, derived, implied, inferred,
+induced, deducted, estimated, or scientifically guessed, it will always
+for the purpose of convenience, expediency, political advantage,
+material gain, or personal comfort, or any combination of the above, or
+none of the above, be unilaterally and unequivocally assumed,
+proclaimed, and adhered to as absolute truth to be undeniably,
+universally, immutably, and infinitely so, until such time as it
+becomes advantageous to assume otherwise, maybe.
+%
+"Right now I'm having amnesia and deja vu at the same time."
+ -- Steven Wright
+%
+Rocky's Lemma of Innovation Prevention
+ Unless the results are known in advance, funding agencies will
+ reject the proposal.
+%
+Romeo wasn't bilked in a day.
+ -- Walt Kelly, "Ten Ever-Lovin' Blue-Eyed Years With
+ Pogo"
+%
+ROMEO: Courage, man; the hurt cannot be much.
+MERCUTIO: No, 'tis not so deep as a well, nor so wide as a church-
+ door; but 'tis enough, 'twill serve.
+%
+Rudin's Law:
+ If there is a wrong way to do something, most people will do it
+every time.
+%
+Rule 46, Oxford Union Society, London:
+ Any member introducing a dog into the Society's premises shall
+be liable to a fine of one pound. Any animal leading a blind person
+shall be deemed to be a cat.
+%
+Rule of Creative Research:
+ (1) Never draw what you can copy.
+ (2) Never copy what you can trace.
+ (3) Never trace what you can cut out and paste down.
+%
+Rule of Defactualization:
+ Information deteriorates upward through bureaucracies.
+%
+Rule of Feline Frustration:
+ When your cat has fallen asleep on your lap and looks utterly
+content and adorable, you will suddenly have to go to the bathroom.
+%
+Rule of the Great:
+ When people you greatly admire appear to be thinking deep
+thoughts, they probably are thinking about lunch.
+%
+Rules for Academic Deans:
+ (1) HIDE!!!!
+ (2) If they find you, LIE!!!!
+ -- Father Damian C. Fandal
+%
+Rules for driving in New York:
+ (1) Anything done while honking your horn is legal.
+ (2) You may park anywhere if you turn your four-way flashers
+ on.
+ (3) A red light means the next six cars may go through the
+ intersection.
+%
+RULES OF EATING -- THE BRONX DIETER'S CREED
+ (1) Never eat on an empty stomach.
+ (2) Never leave the table hungry.
+ (3) When traveling, never leave a country hungry.
+ (4) Enjoy your food.
+ (5) Enjoy your companion's food.
+ (6) Really taste your food. It may take several portions to
+ accomplish this, especially if subtly seasoned.
+ (7) Really feel your food. Texture is important. Compare,
+ for example, the texture of a turnip to that of a
+ brownie. Which feels better against your cheeks?
+ (8) Never eat between snacks, unless it's a meal.
+ (9) Don't feel you must finish everything on your plate. You
+ can always eat it later.
+ (10) Avoid any wine with a childproof cap.
+ (11) Avoid blue food.
+ -- Richard Smit, "The Bronx Diet"
+%
+Rules:
+ (1) The boss is always right.
+ (2) When the boss is wrong, refer to rule 1.
+%
+ Safety Tips for the Post-Nuclear Existence
+ Tip #1: How to tell when you are dead.
+
+(1) Little things start bothering you: little things like worms, bugs,
+ ants.
+(2) Something is missing in your personal relationships.
+(3) Your dog becomes overly affectionate.
+(4) You have a hard time getting a waiter.
+(5) Exotic birds flock around you.
+(6) People ignore you at parties.
+(7) You have a hard time getting up in the morning.
+(8) You no longer get off on cocaine.
+%
+ Safety Tips for the Post-Nuclear Existence
+(1) Never use an elevator in a building that has been hit by a nuclear
+ bomb; use the stairs.
+(2) When you're flying through the air, remember to roll when you hit
+ the ground.
+(3) If you're on fire, avoid gasoline and other flammable materials.
+(4) Don't attempt communication with dead people; it will only lead to
+ psychological problems.
+(5) Food will be scarce; you will have to scavenge. Learn to
+ recognize foods that will be available after the bomb: mashed
+ potatoes, shredded wheat, tossed salad, ground beef, etc.
+(6) Put your hand over your mouth when you sneeze; internal organs
+ will be scarce in the post-nuclear age.
+(7) Try to be neat; fall only in designated piles.
+(8) Drive carefully in "Heavy Fallout" areas; people could be
+ staggering illegally.
+(9) Nutritionally, hundred dollar bills are equal to ones, but more
+ sanitary due to limited circulation.
+(10) Accumulate mannequins now; spare parts will be in short supply on
+ D-Day.
+%
+SAGITTARIUS (Nov 22 - Dec 21)
+ You are optimistic and enthusiastic. You have a reckless
+ tendency to rely on luck since you lack talent. The majority
+ of Sagittarians are drunks or dope fiends or both. People
+ laugh at you a great deal.
+%
+San Francisco isn't what it used to be, and it never was.
+ -- Herb Caen
+%
+San Francisco, n.:
+ Marcel Proust editing an issue of Penthouse.
+%
+Sanity is the trademark of a weak mind.
+ -- Mark Harrold
+%
+Santa Claus wears a Red Suit,
+ He must be a communist.
+And a beard and long hair,
+ Must be a pacifist.
+
+ What's in that pipe that he's smoking?
+ -- Arlo Guthrie
+%
+Satellite Safety Tip #14:
+ If you see a bright streak in the sky coming at you, duck.
+%
+Sattinger's Law:
+ It works better if you plug it in.
+%
+Saturday night in Toledo Ohio,
+ Is like being nowhere at all,
+All through the day how the hours rush by,
+ You sit in the park and you watch the grass die.
+ -- John Denver, "Saturday Night in Toledo Ohio"
+%
+Sauron is alive in Argentina!
+%
+Save energy: be apathetic.
+%
+Save the Whales -- Harpoon a Honda.
+%
+Save the whales. Collect the whole set.
+%
+"Saw a sign on a restaurant that said Breakfast, any time -- so I
+ordered French Toast in the Renaissance.
+ -- Steven Wright
+%
+SCCS, the source motel! Programs check in and never check out!
+ -- Ken Thompson
+%
+Schapiro's Explanation:
+ The grass is always greener on the other side -- but that's
+because they use more manure.
+%
+Schizophrenia beats being alone.
+%
+Schlattwhapper, n.:
+ The window shade that allows itself to be pulled down,
+hesitates for a second, then snaps up in your face.
+ -- Rich Hall, "Sniglets"
+%
+Schnuffel, n.:
+ A dog's practice of continuously nuzzling in your crotch in
+mixed company.
+ -- Rich Hall, "Sniglets"
+%
+Schwiggle, n.:
+ The amusing rotation of one's bottom while sharpening a
+pencil.
+ -- Rich Hall, "Sniglets"
+%
+Science is facts; just as houses are made of stones, so is science made
+of facts; but a pile of stones is not a house and a collection of facts
+is not necessarily science.
+ -- Henri Poincair'e
+%
+Science is what happens when preconception meets verification.
+%
+Scientists are people who build the Brooklyn Bridge and then buy it.
+ -- William Buckley
+
+%
+SCORPIO (Oct 23 - Nov 21)
+ You are shrewd in business and cannot be trusted. You will
+ achieve the pinnacle of success because of your total lack of
+ ethics. Most Scorpio people are murdered.
+%
+Scott's first Law:
+ No matter what goes wrong, it will probably look right.
+%
+Scott's second Law:
+ When an error has been detected and corrected, it will be found
+to have been wrong in the first place.
+
+Corollary:
+ After the correction has been found in error, it will be
+impossible to fit the original quantity back into the equation.
+%
+Scotty: Captain, we din' can reference it!
+Kirk: Analysis, Mr. Spock?
+Spock: Captain, it doesn't appear in the symbol table.
+Kirk: Then it's of external origin?
+Spock: Affirmative.
+Kirk: Mr. Sulu, go to pass two.
+Sulu: Aye aye, sir, going to pass two.
+%
+Screw up your courage! You've screwed up everything else.
+%
+Scrubbing floors and emptying bedpans has as much dignity as the
+Presidency.
+ -- Richard Nixon
+%
+Second Law of Business Meetings:
+ If there are two possible ways to spell a person's name, you
+will pick the wrong one.
+
+Corollary:
+ If there is only one way to spell a name, you will spell it
+wrong, anyway.
+%
+"Section 2.4.3.5 AWNS (Acceptor Wait for New Cycle State).
+ In AWNS the AH function indicates that it has received a
+multiline message byte.
+ In AWNS the RFD message must be sent false and the DAC message
+must be sent passive true.
+ The AH function must exit the AWNS and enter:
+ (1) The ANRS if DAV is false
+ (2) The AIDS if the ATN message is false and neither:
+ (a) The LADS is active
+ (b) Nor LACS is active"
+
+ -- from the IEEE Standard Digital Interface for
+ Programmable Instrumentation
+%
+Security check: INTRUDER ALERT!
+%
+Seduced, shaggy Samson snored.
+She scissored short. Sorely shorn,
+Soon shackled slave, Samson sighed,
+Silently scheming,
+Sightlessly seeking
+Some savage, spectacular suicide.
+ -- Stanislaw Lem, "Cyberiad"
+%
+"See - the thing is - I'm an absolutist. I mean, kind of ... in a way ..."
+%
+Seleznick's Theory of Holistic Medicine:
+ Ice Cream cures all ills.
+%
+Self Test for Paranoia:
+ You know you have it when you can't think of anything that's
+your own fault.
+%
+Seminars, n.:
+ From "semi" and "arse", hence, any half-assed discussion.
+%
+Sen. Danforth: "There is nothing on the face of the album which would
+ notify you if the record has pornographics material or
+ material glorifying violence?"
+Tipper Gore: "No, there is nothing that would suggest that to me."
+Frank Zappa: "I would say that a buzz saw blade between the guy's
+ legs on the album cover is good indication that it's
+ not for little Johnny."
+
+ -- The Senate Commerce Committee hearing on rock
+ lyrics, from The Village Voice, 6 Oct 1985
+%
+Senate, n.:
+ A body of elderly gentlemen charged with high duties and
+misdemeanors.
+ -- Ambrose Bierce
+%
+Serenity through viciousness.
+%
+Serocki's Stricture:
+ Marriage is always a bachelor's last option.
+%
+Serving coffee on aircraft causes turbulence.
+%
+ "Seven years and six months!" Humpty Dumpty repeated
+thoughtfully. "An uncomfortable sort of age. Now if you'd asked MY
+advice, I'd have said `Leave off at seven' -- but it's too late now."
+ "I never ask advice about growing," Alice said indignantly.
+ "Too proud?" the other enquired.
+ Alice felt even more indignant at this suggestion. "I mean,"
+she said, "that one can't help growing older."
+ "ONE can't, perhaps," said Humpty Dumpty; "but TWO can. With
+proper assistance, you might have left off at seven."
+ -- Lewis Carroll
+%
+Several years ago, some smart businessmen had an idea: Why not build a
+big store where a do-it-yourselfer could get everything he needed at
+reasonable prices? Then they decided, nah, the hell with that, let's
+build a home center. And before long home centers were springing up
+like crabgrass all over the United States.
+ -- Dave Barry, "The Taming of the Screw"
+%
+Sex is a natural bodily process, like a stroke.
+%
+Sex is not the answer. Sex is the question. "Yes" is the answer.
+ -- Swami X
+%
+Sex is the mathematics urge sublimated.
+ -- M. C. Reed.
+%
+Sex without love is an empty experience, but, as empty experiences go,
+it's one of the best.
+ -- Woody Allen
+%
+Shamus, n. [Yiddish]:
+ A shamus is a guy who takes care of handyman tasks around the
+temple, and makes sure everything is in working order.
+ A shamus is at the bottom of the pecking order of synagog
+functionaries, and there's a joke about that:
+ A rabbi, to show his humility before God, cries out in the
+middle of a service, "Oh, Lord, I am nobody!" The cantor, not to be
+bested, also cries out, "Oh, Lord, I am nobody!"
+ The shamus, deeply moved, follows suit and cries, "Oh, Lord, I
+am nobody!" The rabbi turns to the cantor and says, "Look who thinks
+he's nobody!"
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+Sharks are as tough as those football fans who take their shirts off
+during games in Chicago in January, only more intelligent.
+ -- Dave Barry, "Sex and the Single Amoeba: What Every
+ Teen Should Know"
+%
+Shaw's Principle:
+ Build a system that even a fool can use, and only a fool will
+want to use it.
+%
+"She is descended from a long line that her mother listened to."
+ -- Gypsy Rose Lee
+%
+She is not refined. She is not unrefined. She keeps a parrot.
+ -- Mark Twain
+%
+She liked him; he was a man of many qualities, even if most of them
+were bad.
+%
+She missed an invaluable opportunity to give him a look that you could
+have poured on a waffle ...
+%
+"She said, `I know you ... you cannot sing'. I said, `That's nothing,
+you should hear me play piano.'"
+ -- Morrisey
+%
+She's genuinely bogus.
+%
+"Sherry [Thomas Sheridan] is dull, naturally dull; but it must have
+taken him a great deal of pains to become what we now see him. Such an
+excess of stupidity, sir, is not in Nature."
+ -- Samuel Johnson
+%
+SHIFT TO THE LEFT! SHIFT TO THE RIGHT!
+POP UP, PUSH DOWN, BYTE, BYTE, BYTE!
+%
+Show me a man who is a good loser and I'll show you a man who is
+playing golf with his boss.
+%
+Show respect for age. Drink good Scotch for a change.
+%
+Signs of crime: screaming or cries for help.
+ -- from the Brown Security Crime Prevention Pamphlet
+%
+Silverman's Law:
+ If Murphy's Law can go wrong, it will.
+%
+Simon's Law:
+ Everything put together falls apart sooner or later.
+%
+Since I hurt my pendulum
+My life is all erratic.
+My parrot, who was cordial,
+Is now transmitting static.
+The carpet died, a palm collapsed,
+The cat keeps doing poo.
+The only thing that keeps me sane
+Is talking to my shoe.
+ -- My Shoe
+%
+Since we have to speak well of the dead, let's knock them while they're
+alive.
+ -- John Sloan
+%
+Since we're all here, we must not be all there.
+ -- Bob "Mountain" Beck
+%
+[Sir Stafford Cripps] has all the virtues I dislike and none of the
+vices I admire.
+ -- Winston Churchill
+%
+Sixtus V, Pope from 1585 to 1590 authorized a printing of the Vulgate
+Bible. Taking no chances, the pope issued a papal bull automatically
+excommunicating any printer who might make an alteration in the text.
+This he ordered printed at the beginning of the Bible. He personally
+examined every sheet as it came off the press. Yet the published
+Vulgate Bible contained so many errors that corrected scraps had to be
+printed and pasted over them in every copy. The result provoked wry
+comments on the rather patchy papal infallibility, and Pope Sixtus had
+no recourse but to order the return and destruction of every copy.
+%
+Skinner's Constant (or Flannagan's Finagling Factor):
+ That quantity which, when multiplied by, divided by, added to,
+or subtracted from the answer you get, gives you the answer you should
+have gotten.
+%
+Slang is language that takes off its coat, spits on its hands, and goes
+to work.
+%
+Slaves are generally expected to sing as well as to work ... I did not,
+when a slave, understand the deep meanings of those rude, and
+apparently incoherent songs. I was myself within the circle, so that I
+neither saw nor heard as those without might see and hear. They told a
+tale which was then altogether beyond my feeble comprehension: they
+were tones, loud, long and deep, breathing the prayer and complaint of
+souls boiling over with the bitterest anguish. Every tone was a
+testimony against slavery, and a prayer to God for deliverance from
+chains.
+ -- Frederick Douglass
+%
+Slick's Three Laws of the Universe:
+ (1) Nothing in the known universe travels faster than a bad
+ check.
+ (2) A quarter-ounce of chocolate = four pounds of fat.
+ (3) There are two types of dirt: the dark kind, which is
+ attracted to light objects, and the light kind, which is
+ attracted to dark objects.
+%
+Slowly and surely the unix crept up on the Nintendo user ...
+%
+Slurm, n.:
+ The slime that accumulates on the underside of a soap bar when
+it sits in the dish too long.
+ -- Rich Hall, "Sniglets"
+%
+Smoking is one of the leading causes of statistics.
+ -- Fletcher Knebel
+%
+Smoking is one of the leading causes of statistics.
+ -- Fletcher Knebel
+%
+Snacktrek, n.:
+ The peculiar habit, when searching for a snack, of constantly
+returning to the refrigerator in hopes that something new will have
+materialized.
+ -- Rich Hall, "Sniglets"
+%
+So as your consumer electronics adviser, I am advising you to donate
+your current VCR to a grate resident, who will laugh sardonically and
+hurl it into a dumpster. Then I want you to go out and purchase a vast
+array of 8-millimeter video equipment.
+
+... OK! Got everything? Well, *too bad, sucker*, because while you
+were gone the electronics industry came up with an even newer format
+that makes your 8-millimeter VCR look as technologically advanced as
+toenail dirt. This format is called "3.5 hectare" and it will not be
+made available until it is outmoded, sometime early next week, by a
+format called "Elroy", so *order yours now*.
+ -- Dave Barry, "No Surrender in the Electronics
+ Revolution"
+%
+So far as I can remember, there is not one word in the Gospels in
+praise of intelligence.
+ -- Bertrand Russell
+%
+... so long as the people do not care to exercise their freedom, those
+who wish to tyrranize will do so; for tyrants are active and ardent,
+and will devote themselves in the name of any number of gods, religious
+and otherwise, to put shackles upon sleeping men.
+ -- Voltarine de Cleyre
+%
+ So Richard and I decided to try to catch [the small shark].
+With a great deal of strategy and effort and shouting, we managed to
+maneuver the shark, over the course of about a half-hour, to a sort of
+corner of the lagoon, so that it had no way to escape other than to
+flop up onto the land and evolve. Richard and I were inching toward
+it, sort of crouched over, when all of a sudden it turned around and --
+I can still remember the sensation I felt at that moment, primarily in
+the armpit area -- headed right straight toward us.
+ Many people would have panicked at this point. But Richard and
+I were not "many people." We were experienced waders, and we kept our
+heads. We did exactly what the textbook says you should do when you're
+unarmed and a shark that is nearly two feet long turns on you in water
+up to your lower calves: We sprinted I would say 600 yards in the
+opposite direction, using a sprinting style such that the bottoms of
+our feet never once went below the surface of the water. We ran all
+the way to the far shore, and if we had been in a Warner Brothers
+cartoon we would have run right INTO the beach, and you would have seen
+these two mounds of sand racing across the island until they bonked
+into trees and coconuts fell onto their heads.
+ -- Dave Barry, "The Wonders of Sharks on TV"
+%
+"So she went into the garden to cut a cabbage leaf to make an apple
+pie; and at the same time a great she-bear, coming up the street pops
+its head into the shop. "What! no soap?" So he died, and she very
+imprudently married the barber; and there were present the Picninnies,
+and the Grand Panjandrum himself, with the little round button at top,
+and they all fell to playing the game of catch as catch can, till the
+gunpowder ran out at the heels of their boots."
+ -- Samuel Foote
+%
+... So the documentary-makers stick with sharks. Generally, their
+procedure is to scatter bleeding fish pieces around their boat, so as
+to infest the waters. I would estimate that the primary food source of
+sharks today is bleeding fish pieces scattered by people making
+documentaries. Once the sharks arrive, they are generally fairly
+listless. The general shark attitude seems to be: "Oh God, another
+documentary." So the divers have to somehow goad them into attacking,
+under the guise of Scientific Research. "We know very little about the
+effect of electricity on sharks," the narrator will say, in a deeply
+scientific voice. "That is why Todd is going to jab this Great White
+in the testicles with a cattle prod." The divers keep this kind of
+thing up until the shark finally gets irritated and snaps at them, and
+then they act as though this was a totally unexpected and very
+dangerous development, although clearly it is what they wanted all
+along.
+ -- Dave Barry, "The Wonders of Sharks on TV"
+%
+So, what's with this guy Gideon, anyway? And why can't he ever
+remember his Bible?
+%
+Sodd's Second Law:
+ Sooner or later, the worst possible set of circumstances is
+bound to occur.
+%
+Software, n.:
+ Formal evening attire for female computer analysts.
+%
+Some don't prefer the pursuit of happiness to the happiness of pursuit.
+%
+Some men are alive simply because it is against the law to kill them.
+ -- Ed Howe
+%
+Some of you ... may have decided that, this year, you're going to
+celebrate it the old-fashioned way, with your family sitting around
+stringing cranberries and exchanging humble, handmade gifts, like on
+"The Waltons". Well, you can forget it. If everybody pulled that kind
+of subversive stunt, the economy would collapse overnight. The
+government would have to intervene: it would form a cabinet-level
+Department of Holiday Gift-Giving, which would spend billions and
+billions of tax dollars to buy Barbie dolls and electronic games, which
+it would drop on the populace from Air Force jets, killing and maiming
+thousands. So, for the good of the nation, you should go along with
+the Holiday Program. This means you should get a large sum of money
+and go to a mall.
+ -- Dave Barry, "Christmas Shopping: A Survivor's Guide"
+%
+Some people are born mediocre, some people achieve mediocrity, and some
+people have mediocrity thrust upon them.
+ -- Joseph Heller, "Catch-22"
+%
+Some people have a way about them that seems to say: "If I have only
+one life to live, let me live it as a jerk."
+%
+Some people in this department wouldn't recognize subtlety if it hit
+them on the head.
+%
+Some people live life in the fast lane. You're in oncoming traffic.
+%
+Some performers on television appear to be horrible people, but when
+you finally get to know them in person, they turn out to be even
+worse.
+ -- Avery
+%
+Some points to remember [about animals]:
+
+(1) Don't go to sleep under big animals, e.g., elephants, rhinoceri,
+ hippopotamuses;
+(2) Don't put animals with sharp teeth or poisonous fangs down the
+ front of your clothes;
+(3) Don't pat certain animals, e.g., crocodiles and scorpions or dogs
+ you have just kicked.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+Some primal termite knocked on wood.
+And tasted it, and found it good.
+And that is why your Cousin May
+Fell through the parlor floor today.
+ -- Ogden Nash
+%
+Some programming languages manage to absorb change but withstand
+progress.
+%
+Some programming languages manage to absorb change, but withstand
+progress.
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+Somebody ought to cross ball point pens with coat hangers so that the
+pens will multiply instead of disappear.
+%
+Someone will try to honk your nose today.
+%
+"Sometimes I simply feel that the whole world is a cigarette and I'm
+the only ashtray."
+%
+Sometimes I worry about being a success in a mediocre world.
+ -- Lily Tomlin
+%
+"Somewhere", said Father Vittorini, "did Blake not speak of the
+Machineries of Joy? That is, did not God promote environments, then
+intimidate these Natures by provoking the existence of flesh, toy men
+and women, such as are we all? And thus happily sent forth, at our
+best, with good grace and fine wit, on calm noons, in fair climes, are
+we not God's Machineries of Joy?"
+
+"If Blake said that", said Father Brian, "he never lived in Dublin."
+ -- R. Bradbury, "The Machineries of Joy"
+%
+Somewhere, just out of sight, the unicorns are gathering.
+%
+Song Title of the Week:
+ "They're putting dimes in the hole in my head to see the change
+in me."
+%
+Sooner or later you must pay for your sins. (Those who have already
+paid may disregard this fortune).
+%
+Sorry, no fortune this time.
+%
+Sorry. I forget what I was going to say.
+%
+Space is big. You just won't believe how vastly, hugely, mind-
+bogglingly big it is. I mean, you may think it's a long way down the
+road to the drug store, but that's just peanuts to space.
+ -- "The Hitchhiker's Guide to the Galaxy"
+%
+"Spare no expense to save money on this one."
+ -- Samuel Goldwyn
+%
+Spark's Sixth Rule for Managers:
+ If a subordinate asks you a pertinent question, look at him as
+if he had lost his senses. When he looks down, paraphrase the question
+back at him.
+%
+Speak roughly to your little boy,
+ And beat him when he sneezes:
+He only does it to annoy
+ Because he knows it teases.
+
+ Wow! wow! wow!
+
+I speak severely to my boy,
+ And beat him when he sneezes:
+For he can thoroughly enjoy
+ The pepper when he pleases!
+
+ Wow! wow! wow!
+ -- Lewis Carrol, "Alice in Wonderland"
+%
+Speak roughly to your little VAX,
+ And boot it when it crashes;
+It knows that one cannot relax
+ Because the paging thrashes!
+
+ Wow! Wow! Wow!
+
+I speak severely to my VAX,
+ And boot it when it crashes;
+In spite of all my favorite hacks
+ My jobs it always thrashes!
+
+ Wow! Wow! Wow!
+%
+Speak softly and carry a +6 two-handed sword.
+%
+Speak softly and own a big, mean Doberman.
+ -- Dave Millman
+%
+Speaking as someone who has delved into the intricacies of PL/I, I am
+sure that only Real Men could have written such a machine-hogging,
+cycle-grabbing, all-encompassing monster. Allocate an array and free
+the middle third? Sure! Why not? Multiply a character string times a
+bit string and assign the result to a float decimal? Go ahead! Free a
+controlled variable procedure parameter and reallocate it before
+passing it back? Overlay three different types of variable on the same
+memory location? Anything you say! Write a recursive macro? Well,
+no, but Real Men use rescan. How could a language so obviously
+designed and written by Real Men not be intended for Real Man use?
+%
+Speaking of Godzilla and other things that convey horror:
+
+ With a purposeful grimace and a Mongo-like flair
+ He throws the spinning disk drives in the air!
+ And he picks up a Vax and he throws it back down
+ As he wades through the lab making terrible sounds!
+ Helpless users with projects due
+ Scream "My God!" as he stomps on the tape drives, too!
+
+ Oh, no! He says Unix runs too slow! Go, go, DECzilla!
+ Oh, yes! He's gonna bring up VMS! Go, go, DECzilla!"
+
+* VMS is a trademark of Digital Equipment Corporation
+* DECzilla is a trademark of Hollow Chocolate Bunnies of Death, Inc.
+ -- Curtis Jackson
+%
+Speaking of love, one problem that recurs more and more frequently
+these days, in books and plays and movies, is the inability of people
+to communicate with the people they love; Husbands and wives who can't
+communicate, children who can't communicate with their parents, and so
+on. And the characters in these books and plays and so on (and in real
+life, I might add) spend hours bemoaning the fact that they can't
+communicate. I feel that if a person can't communicate, the very _____least
+he can do is to Shut Up!
+ -- Tom Lehrer, "That Was the Year that Was"
+%
+"Speed is subsittute fo accurancy."
+%
+Speer's 1st Law of Proofreading:
+ The visibility of an error is inversely proportional to the
+number of times you have looked at it.
+%
+Spelling is a lossed art.
+%
+Spend extra time on hobby. Get plenty of rolling papers.
+%
+Spirtle, n.:
+ The fine stream from a grapefruit that always lands right in
+your eye.
+ -- Sniglets, "Rich Hall & Friends"
+%
+Spouse, n.:
+ Someone who'll stand by you through all the trouble you
+wouldn't have had if you'd stayed single.
+%
+"Star Wars is adolescent nonsense; Close Encounters is obscurantist
+drivel; Star Trek can turn your brains to pur'ee of bat guano; and the
+greatest science fiction series of all time is Doctor Who! And I'll
+take you all on, one-by-one or all in a bunch to back it up!"
+ -- Harlan Ellison
+%
+Stay away from flying saucers today.
+%
+Stay away from hurricanes for a while.
+%
+"Stealing a rhinoceros should not be attempted lightly."
+%
+Steele's Plagiarism of Somebody's Philosophy:
+ Everybody should believe in something -- I believe I'll have
+another drink.
+%
+Steinbach's Guideline for Systems Programming:
+ Never test for an error condition you don't know how to
+handle.
+%
+Stop searching. Happiness is right next to you.
+%
+Stop searching. Happiness is right next to you. Now, if they'd only
+take a bath ...
+%
+Stult's Report:
+ Our problems are mostly behind us. What we have to do now is
+fight the solutions.
+%
+Stupid, n.:
+ Losing $25 on the game and $25 on the instant replay.
+%
+Stupidity got us into this mess -- why can't it get us out?
+%
+Sturgeon's Law:
+ 90% of everything is crud.
+%
+Substitute "damn" every time you're inclined to write "very"; your
+editor will delete it and the writing will be just as it should be.
+ -- Mark Twain
+%
+Subtlety is the art of saying what you think and getting out of the way
+before it is understood.
+%
+Succumb to natural tendencies. Be hateful and boring.
+%
+Suddenly, Professor Liebowitz realizes he has come to the seminar
+without his duck ...
+%
+(Sung to the tune of "The Impossible Dream" from MAN OF LA MANCHA)
+
+ To code the impossible code,
+ To bring up a virgin machine,
+ To pop out of endless recursion,
+ To grok what appears on the screen,
+
+ To right the unrightable bug,
+ To endlessly twiddle and thrash,
+ To mount the unmountable magtape,
+ To stop the unstoppable crash!
+%
+Support bacteria -- it's the only culture some people have!
+%
+Support wildlife -- vote for an orgy.
+%
+Support your local police force -- steal!!
+%
+Support your local Search and Rescue unit -- get lost.
+%
+Sure he's sharp as a razor ... he's a two-dimensional pinhead!
+%
+Surprise due today. Also the rent.
+%
+Surprise your boss. Get to work on time.
+%
+Surprise! You are the lucky winner of random I.R.S. Audit! Just type
+in your name and social security number. Please remember that leaving
+the room is punishable under law:
+
+Name #
+%
+Swahili, n.:
+ The language used by the National Enquirer to print their
+retractions.
+ -- Johnny Hart
+%
+Sweater, n.:
+ A garment worn by a child when its mother feels chilly.
+%
+Swipple's Rule of Order:
+ He who shouts the loudest has the floor.
+%
+Syntactic sugar causes cancer of the semicolon.
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+System/3! System/3!
+See how it runs! See how it runs!
+ Its monitor loses so totally!
+ It runs all its programs in RPG!
+ It's made by our favorite monopoly!
+System/3!
+%
+Systems have sub-systems and sub-systems have sub-systems and so on ad
+infinitum -- which is why we're always starting over.
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+ _
+ _ / \ o
+ / \ | | o o o
+ | | | | _ o o o o
+ | \_| | / \ o o o
+ \__ | | | o o
+ | | | | ______ ~~~~ _____
+ | |__/ | / ___--\\ ~~~ __/_____\__
+ | ___/ / \--\\ \\ \ ___ <__ x x __\
+ | | / /\\ \\ )) \ ( " )
+ | | -------(---->>(@)--(@)-------\----------< >-----------
+ | | // | | //__________ / \ ____) (___ \\
+ | | // __|_| ( --------- ) //// ______ /////\ \\
+ // | ( \ ______ / <<<< <>-----<<<<< / \\
+ // ( ) / / \` \__ \\
+ //-------------------------------------------------------------\\
+
+Every now and then when your life gets complicated and the weasels
+start closing in, the only cure is to load up on heinous chemicals and
+then drive like a bastard from Hollywood to Las Vegas ... with the
+music at top volume and at least a pint of ether.
+ -- H.S. Thompson, "Fear and Loathing in Las Vegas"
+%
+T: One big monster, he called TROLL.
+ He don't rock, and he don't roll;
+ Drink no wine, and smoke no stogies.
+ He just Love To Eat Them Roguies.
+ -- The Roguelet's ABC
+%
+Tact is the ability to tell a man he has an open mind when he has a
+hole in his head.
+%
+Tact, n.:
+ The unsaid part of what you're thinking.
+%
+Take everything in stride. Trample anyone who gets in your way.
+%
+Take heart amid the deepening gloom that your dog is finally getting
+enough cheese
+ -- National Lampoon, "Deteriorata"
+%
+Take it easy, we're in a hurry.
+%
+Take my word for it, the silliest woman can manage a clever man, but it
+needs a very clever woman to manage a fool.
+ -- Kipling
+%
+Take the folks at Coca-Cola. For many years, they were content to sit
+back and make the same old carbonated beverage. It was a good
+beverage, no question about it; generations of people had grown up
+drinking it and doing the experiment in sixth grade where you put a
+nail into a glass of Coke and after a couple of days the nail dissolves
+and the teacher says: "Imagine what it does to your TEETH!" So
+Coca-Cola was solidly entrenched in the market, and the management saw
+no need to improve ...
+ -- Dave Barry, "In Search of Excellence"
+%
+Take your dying with some seriousness, however. Laughing on the way to
+your execution is not generally understood by less advanced life forms,
+and they'll call you crazy.
+ -- "Messiah's Handbook: Reminders for the Advanced Soul"
+%
+Talk sense to a fool and he calls you foolish.
+ -- Euripides
+%
+Talkers are no good doers.
+ -- William Shakespeare, "Henry VI"
+%
+Talking much about oneself can also be a means to conceal oneself.
+ -- Friedrich Nietzsche
+%
+TAURUS (Apr 20 - May 20)
+ You are practical and persistent. You have a dogged
+ determination and work like hell. Most people think you are
+ stubborn and bull headed. You are a Communist.
+%
+Tax reform means "Don't tax you, don't tax me, tax that fellow behind
+the tree."
+ -- Russell Long
+%
+Taxes are going up so fast, the government is likely to price itself
+out of the market.
+%
+Taxes, n.:
+ Of life's two certainties, the only one for which you can get
+an extension.
+%
+Teach children to be polite and courteous in the home, and, when he
+grows up, he will never be able to edge his car onto a freeway.
+%
+Teamwork is essential -- it allows you to blame someone else.
+%
+Technological progress has merely provided us with more efficient means
+for going backwards.
+ -- Aldous Huxley
+%
+Telephone, n.:
+ An invention of the devil which abrogates some of the
+advantages of making a disagreeable person keep his distance.
+ -- Ambrose Bierce
+%
+Tell me, O Octopus, I begs,
+Is those things arms, or is they legs?
+I marvel at thee, Octopus;
+If I were thou, I'd call me us.
+ -- Ogden Nash
+%
+Ten years of rejection slips is nature's way of telling you to stop
+writing.
+ -- R. Geis
+%
+"Terence, this is stupid stuff:
+You eat your victuals fast enough;
+There can't be much amiss, 'tis clear,
+To see the rate you drink your beer.
+But oh, good Lord, the verse you make,
+It gives a chap the belly-ache.
+The cow, the old cow, she is dead;
+It sleeps well the horned head:
+We poor lads, 'tis our turn now
+To hear such tunes as killed the cow.
+Pretty friendship 'tis to rhyme
+Your friends to death before their time.
+Moping, melancholy mad:
+Come, pipe a tune to dance to, lad."
+ -- A. E. Housman
+%
+"Termiter's argument that God is His own grandmother generated a
+surprising amount of controversy among Church leaders, who on the one
+hand considered the argument unsupported by scripture but on the other
+hand were unwilling to risk offending God's grandmother."
+ -- Len Cool, "American Pie"
+%
+Tertullian was born in Carthage somewhere about 160 A.D. He was a
+pagan, and he abandoned himself to the lascivious life of his city
+until about his 35th year, when he became a Christian .... To him is
+ascribed the sublime confession: Credo quia absurdum est (I believe
+because it is absurd). This does not altogether accord with historical
+fact, for he merely said:
+
+ "And the Son of God died, which is immediately credible because
+ it is absurd. And buried he rose again, which is certain
+ because it is impossible."
+
+Thanks to the acuteness of his mind, he saw through the poverty of
+philosophical and Gnostic knowledge, and contemptuously rejected it.
+ -- C. G. Jung, in Psychological Types
+
+(Teruillian was one of the founders of the Catholic Church).
+%
+Test-tube babies shouldn't throw stones.
+%
+Texas law forbids anyone to have a pair of pliers in his possession.
+%
+"Text processing has made it possible to right-justify any idea, even
+one which cannot be justified on any other grounds."
+ -- J. Finnegan, USC.
+%
+Thank goodness modern convenience is a thing of the remote future.
+ -- Pogo, by Walt Kelly
+%
+"That boy's about as sharp as a pound of wet liver"
+ -- Foghorn Leghorn
+%
+"That must be wonderful! I don't understand it at all."
+%
+That secret you've been guarding, isn't.
+%
+That woman speaks eight languages and can't say "no" in any of them.
+ -- Dorothy Parker
+%
+The 80's -- when you can't tell hairstyles from chemotherapy.
+%
+The [Ford Foundation] is a large body of money completely surrounded by
+people who want some.
+ -- Dwight MacDonald
+%
+The Abrams' Principle:
+ The shortest distance between two points is off the wall.
+%
+The advertisement is the most truthful part of a newspaper
+ -- Thomas Jefferson
+%
+The Advertising Agency Song:
+
+ When your client's hopping mad,
+ Put his picture in the ad.
+ If he still should prove refractory,
+ Add a picture of his factory.
+%
+"The algorithm to do that is extremely nasty. You might want to mug
+someone with it."
+ -- M. Devine, Computer Science 340
+%
+... The Anarchists' [national] anthem is an international anthem that
+consists of 365 raspberries blown in very quick succession to the tune
+of "Camptown Races". Nobody has to stand up for it, nobody has to
+listen to it, and, even better, nobody has to play it.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+The Arkansas legislature passed a law that states that the Arkansas
+River can rise no higher than to the Main Street bridge in Little
+Rock.
+%
+The Army has carried the American ... ideal to its logical conclusion.
+Not only do they prohibit discrimination on the grounds of race, creed
+and color, but also on ability.
+ -- T. Lehrer
+%
+The Army needs leaders the way a foot needs a big toe.
+ -- Bill Murray
+%
+The assertion that "all men are created equal" was of no practical use
+in effecting our separation from Great Britain and it was placed in the
+Declaration not for that, but for future use.
+ -- Abraham Lincoln
+%
+The average income of the modern teenager is about 2 a.m.
+%
+The average woman would rather have beauty than brains, because the
+average man can see better than he can think.
+%
+"The bad reputation UNIX has gotten is totally undeserved, laid on by
+people who don't understand, who have not gotten in there and tried
+anything."
+ -- Jim Joyce, owner of Jim Joyce's UNIX Bookstore
+%
+The basic idea behind malls is that they are more convenient than
+cities. Cities contain streets, which are dangerous and crowded and
+difficult to park in. Malls, on the other hand, have parking lots,
+which are also dangerous and crowded and difficult to park in, but --
+here is the big difference -- in mall parking lots, THERE ARE NO
+RULES. You're allowed to do anything. You can drive as fast as you
+want in any direction you want. I was once driving in a mall parking
+lot when my car was struck by a pickup truck being driven backward by a
+squat man with a tattoo that said "Charlie" on his forearm, who got out
+and explained to me, in great detail, why the accident was my fault,
+his reasoning being that he was violent and muscular, whereas I was
+neither. This kind of reasoning is legally valid in mall parking
+lots.
+ -- Dave Barry, "Christmas Shopping: A Survivor's Guide"
+%
+The basic menu item, in fact the ONLY menu item, would be a food unit
+called the "patty," consisting of -- this would be guaranteed in
+writing -- "100 percent animal matter of some kind." All patties would
+be heated up and then cooled back down in electronic devices
+immediately before serving. The Breakfast Patty would be a patty on a
+bun with lettuce, tomato, onion, egg, Ba-Ko-Bits, Cheez Whiz, a Special
+Sauce made by pouring ketchup out of a bottle and a little slip of
+paper stating: "Inspected by Number 12". The Lunch or Dinner Patty
+would be any Breakfast Patties that didn't get sold in the morning.
+The Seafood Lover's Patty would be any patties that were starting to
+emit a serious aroma. Patties that were too rank even to be Seafood
+Lover's Patties would be compressed into wads and sold as "Nuggets."
+ -- Dave Barry, "'Mister Mediocre' Restaurants"
+%
+The best book on programming for the layman is "Alice in Wonderland";
+but that's because it's the best book on anything for the layman.
+%
+The best cure for insomnia is to get a lot of sleep.
+ -- W. C. Fields
+%
+The best defense against logic is ignorance.
+%
+The best thing about growing older is that it takes such a long time.
+%
+"The best thing for being sad," replied Merlin, beginning to puff and
+blow, "is to learn something. That's the only thing that never fails.
+You may grow old and trembling in your anatomies, you may lie awake at
+night listening to the disorder of your veins, you may miss your only
+love, you may see the world about you devastated by evil lunatics, or
+know your honour trampled in the sewers of baser minds. There is only
+one thing for it then -- to learn. Learn why the world wags and what
+wags it. That is the only thing which the mind can never exhaust,
+never alienate, never be tortured by, never fear or distrust, and never
+dream of regretting. Learning is the only thing for you. Look what a
+lot of things there are to learn."
+ -- T.H. White, "The Once and Future King"
+%
+The best way to make a fire with two sticks is to make sure one of them
+is a match.
+ -- Will Rogers
+%
+The bigger the theory the better.
+%
+The biggest difference between time and space is that you can't reuse
+time.
+ -- Merrick Furst
+%
+The birds are singing, the flowers are budding, and it is time for Miss
+Manners to tell young lovers to stop necking in public.
+
+It's not that Miss Manners is immune to romance. Miss Manners has been
+known to squeeze a gentleman's arm while being helped over a curb, and,
+in her wild youth, even to press a dainty slipper against a foot or two
+under the dinner table. Miss Manners also believes that the sight of
+people strolling hand in hand or arm in arm or arm in hand dresses up a
+city considerably more than the more familiar sight of people shaking
+umbrellas at one another. What Miss Manners objects to is the kind of
+activity that frightens the horses on the street ...
+%
+"The bland leadeth the bland and they both shall fall into the kitsch."
+%
+The bogosity meter just pegged.
+%
+The brain is a wonderful organ; it starts working the moment you get up
+in the morning, and does not stop until you get to school.
+%
+The Briggs/Chase Law of Program Development:
+ To determine how long it will take to write and debug a
+program, take your best estimate, multiply that by two, add one, and
+convert to the next higher units.
+%
+The buffalo isn't as dangerous as everyone makes him out to be.
+Statistics prove that in the United States more Americans are killed in
+automobile accidents than are killed by buffalo.
+ -- Art Buchwald
+%
+The bureaucracy is expanding to meet the needs of an expanding
+bureaucracy.
+%
+"The C Programming Language -- A language which combines the
+flexibility of assembly language with the power of assembly language."
+%
+The camel has a single hump;
+The dromedary two;
+Or else the other way around.
+I'm never sure. Are you?
+ -- Ogden Nash
+%
+The capacity of human beings to bore one another seems to be vastly
+greater than that of any other animals. Some of their most esteemed
+inventions have no other apparent purpose, for example, the dinner
+party of more than two, the epic poem, and the science of metaphysics.
+ -- H. L. Mencken
+%
+"The chain which can be yanked is not the eternal chain."
+ -- G. Fitch
+%
+The chicken that clucks the loudest is the one most likely to show up
+at the steam fitters' picnic.
+%
+The chief cause of problems is solutions.
+%
+The chief danger in life is that you may take too may precautions.
+ -- Alfred Adler
+%
+The church is near but the road is icy; the bar is far away but I will
+walk carefully.
+ -- Russian Proverb
+%
+"The climate of Bombay is such that its inhabitants have to live
+elsewhere."
+%
+"The Computer made me do it."
+%
+The computing field is always in need of new cliches.
+ -- Alan Perlis
+%
+The confusion of a staff member is measured by the length of his
+memos.
+ -- New York Times, Jan. 20, 1981
+%
+The conservation movement is a breeding ground of Communists and other
+subversives. We intend to clean them out, even if it means rounding up
+every bird watcher in the country.
+ -- John Mitchell, Atty. General 1969-1972
+%
+The Consultant's Curse:
+ When the customer has beaten upon you long enough, give him
+what he asks for, instead of what he needs. This is very strong
+medicine, and is normally only required once.
+%
+The correct way to punctuate a sentence that starts: "Of course it is
+none of my business, but --" is to place a period after the word "but."
+Don't use excessive force in supplying such a moron with a period.
+Cutting his throat is only a momentary pleasure and is bound to get you
+talked about.
+ -- Lazarus Long, "Time Enough for Love"
+%
+The cost of living hasn't affected its popularity.
+%
+The cost of living is going up, and the chance of living is going
+down.
+%
+The cow is nothing but a machine with makes grass fit for us people to
+eat.
+ -- John McNulty
+%
+The Crown is full of it!
+ -- Nate Harris, 1775
+%
+The cry has been that when war is declared, all opposition should
+therefore be hushed. A sentiment more unworthy of a free country could
+hardly be propagated. If the doctrine be admitted, rulers have only to
+declare war and they are screened at once from scrutiny ... In war,
+then, as in peace, assert the freedom of speech and of the press.
+Cling to this as the bulwark of all our rights and privileges.
+ -- William Ellery Channing
+%
+The day after tomorrow is the third day of the rest of your life.
+%
+The day-to-day travails of the IBM programmer are so amusing to most of
+us who are fortunate enough never to have been one -- like watching
+Charlie Chaplin trying to cook a shoe.
+%
+The debate rages on: Is PL/I Bachtrian or Dromedary?
+%
+The devil finds work for idle circuits to do.
+%
+"The difference between a misfortune and a calamity? If Gladstone fell
+into the Thames, it would be a misfortune. But if someone dragged him
+out again, it would be a calamity."
+ -- Benjamin Disraeli
+%
+The difference between science and the fuzzy subjects is that science
+requires reasoning while those other subjects merely require
+scholarship.
+ -- Robert Heinlein
+%
+The distinction between Jewish and goyish can be quite subtle, as the
+following quote from Lenny Bruce illustrates:
+
+ "I'm Jewish. Count Basie's Jewish. Ray Charles is Jewish.
+Eddie Cantor's goyish. The B'nai Brith is goyish. The Hadassah is
+Jewish. Marine Corps -- heavy goyish, dangerous.
+ "Kool-Aid is goyish. All Drake's Cakes are goyish.
+Pumpernickel is Jewish and, as you know, white bread is very goyish.
+Instant potatoes -- goyish. Black cherry soda's very Jewish.
+Macaroons are ____very Jewish. Fruit salad is Jewish. Lime Jell-O is
+goyish. Lime soda is ____very goyish. Trailer parks are so goyish that
+Jews won't go near them ..."
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+The District of Columbia has a law forbidding you to exert pressure on
+a balloon and thereby cause a whistling sound on the streets.
+%
+The doctrine of human equality reposes on this: that there is no man
+really clever who has not found that he is stupid.
+ -- Gilbert K. Chesterson
+%
+The duck hunter trained his retriever to walk on water. Eager to show
+off this amazing accomplishment, he asked a friend to go along on his
+next hunting trip. Saying nothing, he fired his first shot and, as the
+duck fell, the dog walked on the surface of the water, retrieved the
+duck and returned it to his master.
+ "Notice anything?" the owner asked eagerly.
+ "Yes," said his friend, "I see that fool dog of yours can't
+swim."
+%
+The early bird who catches the worm works for someone who comes in late
+and owns the worm farm.
+ -- Travis McGee
+%
+The earth is like a tiny grain of sand, only much, much heavier.
+%
+The easiest way to figure the cost of living is to take your income and
+add ten percent.
+%
+The economy depends about as much on economists as the weather does on
+weather forecasters.
+ -- Jean-Paul Kauffmann
+%
+"The eleventh commandment was `Thou Shalt Compute' or `Thou Shalt Not
+Compute' -- I forget which."
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+The end of the human race will be that it will eventually die of
+civilization.
+ -- Ralph Waldo Emerson
+%
+The end of the world will occur at 3:00 p.m., this Friday, with
+symposium to follow.
+%
+The English have no respect for their language, and will not teach
+their children to speak it.
+ -- G. B. Shaw
+%
+The fact that boys are allowed to exist at all is evidence of a
+remarkable Christian forbearance among men.
+ -- Ambrose Bierce
+%
+The fact that it works is immaterial.
+ -- L. Ogborn
+%
+The faster we go, the rounder we get.
+ -- The Grateful Dead
+%
+The Fifth Rule:
+ You have taken yourself too seriously.
+%
+The first duty of a revolutionary is to get away with it.
+ -- Abbie Hoffman
+%
+The first Great Steward, Parrafin the Climber, was employed in King
+Chloroplast's kitchen as second scullery boy when the old King met a
+tragic death. He apparently fell backward by accident on a dozen salad
+forks. Simultaneously the true heir, his son Carotene, mysteriously
+fled the city, complaining of some sort of plot and a lot of
+threatening notes left on his breakfast tray. At the time, this looked
+suspicious what with his father's death, and Carotene was suspected of
+foul play. Then the rest of the King's relatives began to drop dead
+one after the other in an odd fashion. Some were found strangled with
+dishrags and some succumbed to food poisoning. A few were found
+drowned in the soup vats, and one was attacked by assailants unknown
+and beaten to death with a pot roast. At least three appear to have
+thrown themselves backward on salad forks, perhaps in a noble gesture
+of grief over the King's untimely end. Finally there was no one left
+in Minas Troney who was either eligible or willing to wear the accursed
+crown, and the rule of Twodor was up for grabs. The scullery slave
+Parrafin bravely accepted the Stewardship of Twodor until that day when
+a lineal descendant of Carotene's returns to reclaim his rightful
+throne, conquer Twodor's enemies, and revamp the postal system.
+ -- Harvard Lampoon, "Bored of the Rings"
+%
+The first myth of management is that it exists. The second myth of
+management is that success equals skill.
+ -- Robert Heller
+%
+The first riddle I ever heard, one familiar to almost every Jewish
+child, was propounded to me by my father:
+ "What is it that hangs on the wall, is green, wet -- and
+whistles?"
+ I knit my brow and thought and thought, and in final perplexity
+gave up.
+ "A herring," said my father.
+ "A herring," I echoed. "A herring doesn't hang on the wall!"
+ "So hang it there."
+ "But a herring isn't green!" I protested.
+ "Paint it."
+ "But a herring isn't wet."
+ "If its just painted its still wet."
+ "But -- " I sputtered, summoning all my outrage, "-- a herring
+doesn't whistle!!"
+ "Right, " smiled my father. "I just put that in to make it
+hard."
+ -- Leo Rosten, "The Joys of Yiddish"
+%
+"The first rule of magic is simple. Don't waste your time waving your
+hands and hoping when a rock or a club will do."
+ -- McCloctnik the Lucid
+%
+The First Rule of Program Optimization:
+ Don't do it.
+
+The Second Rule of Program Optimization (for experts only!):
+ Don't do it yet.
+ -- Michael Jackson
+%
+The first time, it's a KLUDGE!
+The second, a trick.
+Later, it's a well-established technique!
+ -- Mike Broido, Intermetrics
+%
+The following quote is from page 4-27 of the MSCP Basic Disk Functions
+Manual which is part of the UDA50 Programmers Doc Kit manuals:
+
+As stated above, the host area of a disk is structured as a vector of
+logical blocks. From a performance viewpoint, however, it is more
+appropriate to view the host area as a four dimensional hyper-cube, the
+four dimensions being cylinder, group, track, and sector.
+ . . .
+Referring to our hyper-cube analogy, the set of potentially accessible
+blocks form a line parallel to the track axis. This line moves
+parallel to the sector axis, wrapping around when it reaches the edge
+of the hyper-cube.
+%
+The fortune program is supported, in part, by user contributions and by
+a major grant from the National Endowment for the Inanities.
+%
+"The four building blocks of the universe are fire, water, gravel and
+vinyl."
+ -- Dave Barry
+%
+The full impact of parenthood doesn't hit you until you multiply the
+number of your kids by 32 teeth.
+%
+The generation of random numbers is too important to be left to
+chance.
+%
+The gentlemen looked one another over with microscopic carelessness.
+%
+The geographical center of Boston is in Roxbury. Due north of the
+center we find the South End. This is not to be confused with South
+Boston which lies directly east from the South End. North of the South
+End is East Boston and southwest of East Boston is the North End.
+%
+The giraffe you thought you offended last week is willing to be nuzzled
+today.
+%
+The goal of Computer Science is to build something that will last at
+least until we've finished building it.
+%
+The goal of science is to build better mousetraps. The goal of nature
+is to build better mice.
+%
+The gods gave man fire and he invented fire engines. They gave him
+love and he invented marriage.
+%
+THE GOLDEN RULE OF ARTS AND SCIENCES
+ The one who has the gold makes the rules.
+%
+"The good Christian should beware of mathematicians and all those who
+make empty prophecies. The danger already exists that mathematicians
+have made a covenant with the devil to darken the spirit and confine
+man in the bonds of Hell."
+ -- St. Augustine
+%
+The good die young -- because they see it's no use living if you've got
+to be good.
+%
+ "The Good Ship Enterprise" (to the tune of "The Good Ship Lollipop")
+
+On the good ship Enterprise
+Every week there's a new surprise
+Where the Romulans lurk
+And the Klingons often go berserk.
+
+Yes, the good ship Enterprise
+There's excitement anywhere it flies
+Where Tribbles play
+And Nurse Chapel never gets her way.
+
+ See Captain Kirk standing on the bridge,
+ Mr. Spock is at his side.
+ The weekly menace, ooh-ooh
+ It gets fried, scattered far and wide.
+
+It's the good ship Enterprise
+Heading out where danger lies
+And you live in dread
+If you're wearing a shirt that's red.
+ -- Doris Robin and Karen Trimble of The L.A. Filkharmonics
+%
+The government [is] extremely fond of amassing great quantities of
+statistics. These are raised to the _nth degree, the cube roots are
+extracted, and the results are arranged into elaborate and impressive
+displays. What must be kept ever in mind, however, is that in every
+case, the figures are first put down by a village watchman, and he puts
+down anything he damn well pleases.
+ -- Sir Josiah Stamp
+%
+The grand leap of the whale up the Fall of Niagara is esteemed, by all
+who have seen it, as one of the finest spectacles in nature.
+ -- Benjamin Franklin.
+%
+The Great Bald Swamp Hedgehog:
+ The Gerat Bald Swamp Hedgehog of Billericay displays, in
+courtship, his single prickle and does impressions of Holiday Inn desk
+clerks. Since this means him standing motionless for enormous periods
+of time he is often eaten in full display by The Great Bald Swamp
+Hedgehog Eater.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+The greatest dangers to liberty lurk in insidious encroachment by men
+of zeal, well-meaning but without understanding.
+ -- Justice Louis D. Brandeis
+%
+The hardest thing in the world to understand is the income tax.
+ -- Albert Einstein
+%
+The hearing ear is always found close to the speaking tongue, a custom
+whereof the memory of man runneth not howsomever to the contrary,
+nohow.
+%
+The Heineken Uncertainty Principle:
+ You can never be sure how many beers you had last night.
+%
+The herd instinct among economists makes sheep look like independent
+thinkers.
+%
+The hieroglyphics are all unreadable except for a notation on the back,
+which reads "Genuine authentic Egyptian papyrus. Guaranteed to be at
+least 5000 years old."
+%
+The human animal differs from the lesser primates in his passion for
+lists of "Ten Best".
+ -- H. Allen Smith
+%
+"The human brain is like an enormous fish -- it is flat and slimy and
+has gills through which it can see."
+ -- Monty Python
+%
+The human mind ordinarily operates at only ten percent of its capacity
+-- the rest is overhead for the operating system.
+%
+The human mind treats a new idea the way the body treats a strange
+protein -- it rejects it.
+ -- P. Medawar
+%
+The human race has been fascinated by sharks for as long as I can
+remember. Just like the bluebird feeding its young, or the spider
+struggling to weave its perfect web, or the buttercup blooming in
+spring, the shark reveals to us yet another of the infinite and
+wonderful facets of nature, namely the facet that it can bite your head
+off. This causes us humans to feel a certain degree of awe.
+ -- Dave Barry, "The Wonders of Sharks on TV"
+%
+The human race has one really effective weapon, and that is laughter.
+ -- Mark Twain
+%
+The human race is a race of cowards; and I am not only marching in that
+procession but carrying a banner.
+ -- Mark Twain
+%
+The idea is to die young as late as possible.
+ -- Ashley Montagu
+%
+The idea is to die young as late as possible.
+ -- Ashley Montague
+%
+The idea there was that consumers would bring their broken electronic
+devices, such as television sets and VCR's, to the destruction centers,
+where trained personnel would whack them (the devices) with
+sledgehammers. With their devices thus permanently destroyed,
+consumers would then be free to go out and buy new devices, rather than
+have to fritter away years of their lives trying to have the old ones
+repaired at so-called "factory service centers," which in fact consist
+of two men named Lester poking at the insides of broken electronic
+devices with cheap cigars and going, "Lookit all them WIRES in there!"
+ -- Dave Barry, "'Mister Mediocre' Restaurants"
+%
+"The identical is equal to itself, since it is different."
+ -- Franco Spisani
+%
+"The illegal we do immediately. The unconstitutional takes a bit
+longer."
+ -- Henry Kissinger
+%
+The income tax has made more liars out of the American people than golf
+has. Even when you make a tax form out on the level, you don't know
+when it's through if you are a crook or a martyr.
+ -- Will Rogers
+%
+The individual choice of garnishment of a burger can be an important
+point to the consumer in this day when individualism is an increasingly
+important thing to people.
+ -- Donald N. Smith, president of Burger King
+%
+The intelligence of any discussion diminishes with the square of the
+number of participants.
+ -- Adam Walinsky
+%
+The IQ of the group is the lowest IQ of a member of the group divided
+by the number of people in the group.
+%
+The IRS spends God knows how much of your tax money on these toll-free
+information hot lines staffed by IRS employees, whose idea of a
+dynamite tax tip is that you should print neatly. If you ask them a
+real tax question, such as how you can cheat, they're useless.
+
+So, for guidance, you want to look to big business. Big business never
+pays a nickel in taxes, according to Ralph Nader, who represents a big
+consumer organization that never pays a nickel in taxes...
+ -- Dave Barry, "Sweating Out Taxes"
+%
+The Kennedy Constant:
+ Don't get mad -- get even.
+%
+The Killer Ducks are coming!!!
+%
+The ladies men admire, I've heard,
+Would shudder at a wicked word.
+Their candle gives a single light;
+They'd rather stay at home at night.
+They do not keep awake till three,
+Nor read erotic poetry.
+They never sanction the impure,
+Nor recognize an overture.
+They shrink from powders and from paints ...
+So far, I've had no complaints.
+ -- Dorothy Parker
+%
+"The last time somebody said, `I find I can write much better with a
+word processor.', I replied, `They used to say the same thing about
+drugs.'
+ -- Roy Blount, Jr.
+%
+The law will never make men free; it is men who have got to make the
+law free.
+ -- Henry David Thoreau
+%
+The Law, in its majestic equality, forbids the rich, as well as the
+poor, to sleep under the bridges, to beg in the streets, and to steal
+bread.
+ -- Anatole France
+%
+"The lawgiver, of all beings, most owes the law allegiance. He of all
+men should behave as though the law compelled him. But it is the
+universal weakness of mankind that what we are given to administer we
+presently imagine we own."
+ -- H.G. Wells
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #10: SIMPLE
+
+SIMPLE is an acronym for Sheer Idiot's Monopurpose Programming Language
+Environment. This language, developed at the Hanover College for
+Technological Misfits, was designed to make it impossible to write code
+with errors in it. The statements are, therefore, confined to BEGIN,
+END and STOP. No matter how you arrange the statements, you can't make
+a syntax error. Programs written in SIMPLE do nothing useful. Thus
+they achieve the results of programs written in other languages without
+the tedious, frustrating process of testing and debugging.
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #12: LITHP
+
+This otherwise unremarkable language is distinguished by the absence of
+an "S" in its character set; users must substitute "TH". LITHP is said
+to be useful in protheththing lithtth.
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #13: SLOBOL
+
+SLOBOL is best known for the speed, or lack of it, of its compiler.
+Although many compilers allow you to take a coffee break while they
+compile, SLOBOL compilers allow you to travel to Bolivia to pick the
+coffee. Forty-three programmers are known to have died of boredom
+sitting at their terminals while waiting for a SLOBOL program to
+compile. Weary SLOBOL programmers often turn to a related (but
+infinitely faster) language, COCAINE.
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #17: SARTRE
+
+Named after the late existential philosopher, SARTRE is an extremely
+unstructured language. Statements in SARTRE have no purpose; they just
+are. Thus SARTRE programs are left to define their own functions.
+SARTRE programmers tend to be boring and depressed, and are no fun at
+parties.
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #18: C-
+
+This language was named for the grade received by its creator when he
+submitted it as a class project in a graduate programming class. C- is
+best described as a "low-level" programming language. In fact, the
+language generally requires more C- statements than machine-code
+statements to execute a given task. In this respect, it is very
+similar to COBOL.
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #18a: FIFTH
+
+FIFTH is a precision mathematical language in which the data types
+refer to quantity. The data types range from CC, OUNCE, SHOT, and
+JIGGER to FIFTH (hence the name of the language), LITER, MAGNUM and
+BLOTTO. Commands refer to ingredients such as CHABLIS, CHARDONNAY,
+CABERNET, GIN, VERMOUTH, VODKA, SCOTCH, and WHATEVERSAROUND.
+
+The many versions of the FIFTH language reflect the sophistication and
+financial status of its users. Commands in the ELITE dialect include
+VSOP and LAFITE, while commands in the GUTTER dialect include HOOTCH
+and RIPPLE. The latter is a favorite of frustrated FORTH programmers
+who end up using this language.
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #2: RENE
+
+Named after the famous French philosopher and mathematician Rene
+DesCartes, RENE is a language used for artificial intelligence. The
+language is being developed at the Chicago Center of Machine Politics
+and Programming under a grant from the Jane Byrne Victory Fund. A
+spokesman described the language as "Just as great as dis [sic] city of
+ours."
+
+The center is very pleased with progress to date. They say they have
+almost succeeded in getting a VAX to think. However, sources inside the
+organization say that each time the machine fails to think it ceases to
+exist.
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #5: VALGOL
+From its modest beginnings in Southern California's San Fernando Valley,
+VALGOL is enjoying a dramatic surge of popularity across the industry.
+
+Here is a sample program:
+ LIKE, Y*KNOW(I MEAN)START
+ IF PIZZA = LIKE BITCHEN AND GUY = LIKE TUBULAR AND
+ VALLEY GIRL = LIKE GRODY**MAX(FERSURE)**2 THEN
+ FOR I = LIKE 1 TO OH*MAYBE 100
+ DO*WAH - (DITTY**2)
+ BARF(I)=TOTALLY GROSS(OUT)
+ SURE
+ LIKE BAG THIS PROGRAM
+ REALLY
+ LIKE TOTALLY (Y*KNOW)
+ IM*SURE
+ GOTO THE MALL
+
+When the user makes a syntax error, the interpreter displays the message:
+
+ GAG ME WITH A SPOON!!
+%
+ THE LESSER-KNOWN PROGRAMMING LANGUAGES #8: LAIDBACK
+
+This language was developed at the Marin County Center for T'ai Chi,
+Mellowness and Computer Programming (now defunct), as an alternative to
+the more intense atmosphere in nearby Silicon Valley.
+
+The center was ideal for programmers who liked to soak in hot tubs
+while they worked. Unfortunately few programmers could survive there
+because the center outlawed Pizza and Coca-Cola in favor of Tofu and
+Perrier.
+
+Many mourn the demise of LAIDBACK because of its reputation as a gentle
+and non-threatening language since all error messages are in lower
+case. For example, LAIDBACK responded to syntax errors with the
+message:
+ "i hate to bother you, but i just can't relate to that. can
+ you find the time to try it again?"
+%
+The light at the end of the tunnel is the headlight of an approaching
+train.
+%
+The light at the end of the tunnel may be an oncoming dragon.
+%
+The lion and the calf shall lie down together but the calf won't get
+much sleep.
+ -- Woody Allen
+%
+The longer I am out of office, the more infallible I appear to myself.
+ -- Henry Kissinger
+%
+"The Lord gave us farmers two strong hands so we could grab as much as
+we could with both of them."
+ -- Joseph Heller, "Catch-22"
+%
+The makers may make
+and the users may use,
+but the fixers must fix
+with but minimal clues
+%
+The man who follows the crowd will usually get no further than the
+crowd. The man who walks alone is likely to find himself in places no
+one has ever been.
+ -- Alan Ashley-Pitt
+%
+The man who sets out to carry a cat by its tail learns something that
+will always be useful and which never will grow dim or doubtful.
+ -- Mark Twain.
+%
+The marvels of today's modern technology include the development of a
+soda can, when discarded will last forever ... and a $7,000 car which
+when properly cared for will rust out in two or three years.
+%
+"... the Mayo Clinic, named after its founder, Dr. Ted Clinic ..."
+ -- Dave Barry
+%
+The meek shall inherit the earth -- they are too weak to refuse.
+%
+ The men sat sipping their tea in silence. After a while the
+klutz said, "Life is like a bowl of sour cream."
+
+ "Like a bowl of sour cream?" asked the other. "Why?"
+
+ "How should I know? What am I, a philosopher?"
+%
+The meta-Turing test counts a thing as intelligent if it seeks to
+devise and apply Turing tests to objects of its own creation.
+ -- Lew Mammel, Jr.
+%
+The misnaming of fields of study is so common as to lead to what might
+be general systems laws. For example, Frank Harary once suggested the
+law that any field that had the word "science" in its name was
+guaranteed thereby not to be a science. He would cite as examples
+Military Science, Library Science, Political Science, Homemaking
+Science, Social Science, and Computer Science. Discuss the generality
+of this law, and possible reasons for its predictive
+power.
+ -- Gerald Weinberg, "An Introduction to General Systems
+ Thinking."
+%
+The modern child will answer you back before you've said anything.
+ -- Laurence J. Peter
+%
+The mome rath isn't born that could outgrabe me.
+ -- Nicol Williamson
+%
+The moon is a planet just like the Earth, only it is even deader.
+%
+The moon may be smaller than Earth, but it's further away.
+%
+"The more data I punch in this card, the lighter it becomes, and the
+lower the mailing cost."
+ -- Stan Kelly-Bootle, "The Devil's DP Dictionary"
+%
+The more laws and order are made prominent, the more thieves and
+robbers there will be.
+ -- Lao Tsu
+%
+The more things change, the more they stay insane.
+%
+The more we disagree, the more chance there is that at least one of us
+is right.
+%
+The mosquito is the state bird of New Jersey.
+ -- Andy Warhol
+%
+"The most difficult thing in the world is to know how to do a thing and
+to watch someone else do it wrong without comment."
+ -- Theodore H. White
+%
+The most exciting phrase to hear in science, the one that heralds new
+discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
+ -- Isaac Asimov
+%
+The moving cursor writes, and having written, blinks on.
+%
+... the MYSTERIANS are in here with my CORDUROY SOAP DISH!!
+%
+ "... The name of the song is called 'Haddocks' Eyes'!"
+ "Oh, that's the name of the song, is it?" Alice said, trying to
+feel interested.
+ "No, you don't understand," the Knight said, looking a little
+vexed. "That's what the name is called. The name really is, 'The Aged
+Aged Man.'"
+ "Then I ought to have said "That's what the song is called'?"
+Alice corrected herself.
+ "No, you oughtn't: that's quite another thing! The song is
+called 'Ways and Means': but that's only what it is called you know!"
+ "Well, what is the song then?" said Alice, who was by this time
+completely bewildered.
+ "I was coming to that," the Knight said. "The song really is
+"A-sitting on a Gate": and the tune's my own invention."
+ -- Lewis Carroll, "Through the Looking Glass"
+%
+"The National Association of Theater Concessionaires reported that in
+1986, 60% of all candy sold in movie theaters was sold to Roger Ebert."
+ -- D. Letterman
+%
+The National Short-Sleeved Shirt Association says:
+ Support your right to bare arms!
+%
+The net of law is spread so wide,
+No sinner from its sweep may hide.
+Its meshes are so fine and strong,
+They take in every child of wrong.
+O wondrous web of mystery!
+Big fish alone escape from thee!
+ -- James Jeffrey Roche
+%
+The new Congressmen say they're going to turn the government around. I
+hope I don't get run over again.
+%
+The New Testament offers the basis for modern computer coding theory,
+in the form of an affirmation of the binary number system.
+
+ But let your communication be Yea, yea; nay, nay: for
+ whatsoever is more than these cometh of evil.
+ -- Matthew 5:37
+%
+"The New York Times is read by the people who run the country. The
+Washington Post is read by the people who think they run the country.
+The National Enquirer is read by the people who think Elvis is alive
+and running the country ..."
+ -- Robert J Woodhead
+%
+The nice thing about standards is that there are so many of them to
+choose from.
+ -- Andrew S. Tanenbaum
+%
+The notion of a "record" is an obsolete remnant of the days of the
+80-column card.
+ -- Dennis M. Ritchie
+%
+The notion that the church, the press, and the universities should
+serve the state is essentially a Communist notion ... In a free society
+these institutions must be wholly free -- which is to say that their
+function is to serve as checks upon the state.
+ -- Alan Barth
+%
+The number of arguments is unimportant unless some of them are
+correct.
+ -- Ralph Hartley
+%
+The objective of all dedicated employees should be to thoroughly
+analyze all situations, anticipate all problems prior to their
+occurrence, have answers for these problems, and move swiftly to solve
+these problems when called upon.
+
+However, When you are up to your ass in alligators it is difficult to
+remind yourself your initial objective was to drain the swamp.
+%
+The Official MBA Handbook on business cards:
+ Avoid overly pretentious job titles such as "Lord of the Realm,
+Defender of the Faith, Emperor of India" or "Director of Corporate
+Planning."
+%
+The older a man gets, the farther he had to walk to school as a boy.
+%
+The older I grow the more I distrust the familiar doctrine that age
+brings wisdom.
+ -- H. L. Mencken
+%
+The older I grow, the less important the comma becomes. Let the reader
+catch his own breath.
+ -- Elizabeth Clarkson Zwart
+%
+The one good thing about repeating your mistakes is that you know when
+to cringe.
+%
+The only possible interpretation of any research whatever in the
+`social sciences' is: some do, some don't.
+ -- Ernest Rutherford
+%
+The only problem with being a man of leisure is that you can never stop
+and take a rest.
+%
+"The only real way to look younger is not to be born so soon."
+ -- Charles Schulz, "Things I've Had to Learn Over and
+ Over and Over"
+%
+The only really decent thing to do behind a person's back is pat it.
+%
+The only really good place to buy lumber is at a store where the lumber
+has already been cut and attached together in the form of furniture,
+finished, and put inside boxes.
+ -- Dave Barry, "The Taming of the Screw"
+%
+The only thing to do with good advice is pass it on. It is never any
+use to oneself.
+ -- Oscar Wilde
+%
+"The only thing we learn from history is that we learn nothing from
+history."
+ -- Hegel
+
+"I know guys can't learn from yesterday ... Hegel must be taking the
+long view."
+ -- John Brunner, "Stand on Zanzibar"
+%
+The only way to get rid of a temptation is to yield to it.
+ -- Oscar Wilde
+%
+The opossum is a very sophisticated animal. It doesn't even get up
+until 5 or 6 p.m.
+%
+The opposite of a profound truth may well be another profound truth.
+ -- Bohr
+%
+The optimum committee has no members.
+ -- Norman Augustine
+%
+The optimum committee has no members.
+ -- Norman Augustine
+%
+"The other day I put instant coffee in my microwave oven ... I almost
+went back in time."
+ -- Steven Wright
+%
+The past always looks better than it was. It's only pleasant because
+it isn't here.
+ -- Finley Peter Dunne (Mr. Dooley)
+%
+The penalty for laughing in a courtroom is six months in jail; if it
+were not for this penalty, the jury would never hear the evidence.
+ -- H. L. Mencken
+%
+ The people of Halifax invented the trampoline. During the
+Victorian period the tripe-dressers of Halifax stretched tripe across a
+large wooden frame and jumped up and down on it to `tender and dress'
+it. The tripoline, as they called it, degenerated into becoming the
+apparatus for a spectator sport.
+
+ The people of Halifax also invented the harmonium, a device for
+castrating pigs during Sunday service.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+The Pig, if I am not mistaken,
+Gives us ham and pork and Bacon.
+Let others think his heart is big,
+I think it stupid of the Pig.
+ -- Ogden Nash
+%
+The pitcher wound up and he flang the ball at the batter. The batter
+swang and missed. The pitcher flang the ball again and this time the
+batter connected. He hit a high fly right to the center fielder. The
+center fielder was all set to catch the ball, but at the last minute
+his eyes were blound by the sun and he dropped it.
+ -- Dizzy Dean
+%
+The plot was designed in a light vein that somehow became varicose.
+ -- David Lardner
+%
+The polite thing to do has always been to address people as they wish
+to be addressed, to treat them in a way they think dignified. But it
+is equally important to accept and tolerate different standards of
+courtesy, not expecting everyone else to adapt to one's own
+preferences. Only then can we hope to restore the insult to its proper
+social function of expressing true distaste.
+ -- Judith Martin, "Miss Manners' Guide to
+ Excruciatingly Correct Behavior"
+%
+"The porcupine with the sharpest quills gets stuck on a tree more
+often."
+%
+The Preacher, the Politician, the Teacher,
+ Were each of them once a kiddie.
+A child, indeed, is a wonderful creature.
+ Do I want one? God Forbiddie!
+ -- Ogden Nash
+%
+The President publicly apologized today to all those offended by his
+brother's remark, "There's more Arabs in this country than there is
+Jews!". Those offended include Arabs, Jews, and English teachers.
+ -- Baltimore, Channel 11 News, on Jimmy Carter
+%
+The price of seeking to force our beliefs on others is that someday
+they might force their beliefs on us.
+ -- Mario Cuomo
+%
+The primary cause of failure in electrical appliances is an expired
+warranty. Often, you can get an appliance running again simply by
+changing the warranty expiration date with a 15/64-inch felt-tipped
+marker.
+ -- Dave Barry, "The Taming of the Screw"
+%
+The primary purpose of the DATA statement is to give names to
+constants; instead of referring to pi as 3.141592653589793 at every
+appearance, the variable PI can be given that value with a DATA
+statement and used instead of the longer form of the constant. This
+also simplifies modifying the program, should the value of pi change.
+ -- FORTRAN manual for Xerox Computers
+%
+The primary requisite for any new tax law is for it to exempt enough
+voters to win the next election.
+%
+The primary theme of SoupCon is communication. The acronym "LEO"
+represents the secondary theme:
+
+ Law Enforcement Officials
+
+The overall theme of SoupCon shall be:
+
+ Avoiding Communication with Law Enforcement Officials
+%
+... the privileged being which we call human is distinguished from
+other animals only by certain double-edged manifestations which in
+charity we can only call "inhuman."
+ -- R. A. Lafferty
+%
+The probability of someone watching you is proportional to the
+stupidity of your action.
+%
+The problem ... is that we have run out of dinosaurs to form oil with.
+Scientists working for the Department of Energy have tried to form oil
+using other animals; they've piled thousands of tons of sand and Middle
+Eastern countries on top of cows, raccoons, haddock, laboratory rats,
+etc., but so far all they have managed to do is run up an enormous
+bulldozer-rental bill and anger a lot of Middle Eastern persons. None
+of the animals turned into oil, although most of the laboratory rats
+developed cancer.
+ -- Dave Barry, "Postpetroleum Guzzler"
+%
+The problem with any unwritten law is that you don't know where to go
+to erase it.
+ -- Glaser and Way
+%
+The problem with engineers is that they tend to cheat in order to get
+results.
+
+The problem with mathematicians is that they tend to work on toy
+problems in order to get results.
+
+The problem with program verifiers is that they tend to cheat at toy
+problems in order to get results.
+%
+The problem with people who have no vices is that generally you can be
+pretty sure they're going to have some pretty annoying virtues.
+ -- Elizabeth Taylor
+%
+The problem with the gene pool is that there is no lifeguard.
+%
+The Psblurtex is an 18-inch long anaconda that hides in the gentlemen's
+outfitting departments of Amazonian stores and is often bought by
+mistake since its colors are those of the London Reform Club. Once
+tied around its victim's neck, it strangles him gently and then claims
+the insurance before running off to Germany where it lives in hiding.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+"The pyramid is opening!"
+"Which one?"
+"The one with the ever-widening hole in it!"
+ -- Firesign Theater, "How Can You Be In Two Places At
+ Once When You're Not Anywhere At All"
+%
+The qotc (quote of the con) was Liz's:
+ "My brain is paged out to my liver"
+%
+The question is, why are politicians so eager to be president? What is
+it about the job that makes it worth revealing, on national television,
+that you have the ethical standards of a slime-coated piece of
+industrial waste?
+ -- Dave Barry, "On Presidential Politics"
+%
+The rain it raineth on the just
+ And also on the unjust fella,
+But chiefly on the just, because
+ The unjust steals the just's umbrella.
+%
+The reader this message encounters not failing to understand is
+cursed.
+%
+The reason computer chips are so small is computers don't eat much.
+%
+The reason it's called "Grape Nuts" is that it contains "dextrose",
+which is also sometimes called "grape sugar", and also because "Grape
+Nuts" is catchier, in terms of marketing, than "A Cross Between Gerbil
+Food and Gravel", which is what it tastes like.
+ -- Dave Barry, "Tips for Writer's"
+%
+The reasonable man adapts himself to the world; the unreasonable one
+persists in trying to adapt the world to himself. Therefore all
+progress depends on the unreasonable man.
+ -- George Bernard Shaw
+%
+The revolution will not be televised.
+%
+The reward of a thing well done is to have done it.
+ -- Emerson
+%
+The rhino is a homely beast,
+For human eyes he's not a feast.
+Farewell, farewell, you old rhinoceros,
+I'll stare at something less prepoceros.
+ -- Ogden Nash
+%
+The right half of the brain controls the left half of the body. This
+means that only left handed people are in their right mind.
+%
+"The Right Honorable Gentleman is indebted to his memory for his jests
+and to his imagination for his facts."
+ -- Sheridan
+%
+The right to revolt has sources deep in our history.
+ -- Supreme Court Justice William O. Douglas
+%
+"The rights you have are the rights given you by this Committee [the
+House Un-American Activities Committee]. We will determine what rights
+you have and what rights you have not got."
+ -- J. Parnell Thomas
+%
+The road to hell is paved with good intentions. And littered with
+sloppy analysis!
+%
+The Roman Rule
+ The one who says it cannot be done should never interrupt the
+ one who is doing it.
+%
+The Ruffed Pandanga of Borneo and Rotherham spreads out his feathers in
+his courtship dance and imitates Winston Churchill and Tommy Cooper on
+one leg. The padanga is dying out because the female padanga doesn't
+take it too seriously.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+The rule on staying alive as a forcaster is to give 'em a number or
+give 'em a date, but never give 'em both at once.
+ -- Jane Bryant Quinn
+%
+"The Schizophrenic: An Unauthorized Autobiography"
+%
+The Schwine-Kitzenger Institute study of 47 men over the age of 100
+showed that all had these things in common:
+
+ (1) They all had moderate appetites.
+ (2) They all came from middle class homes
+ (3) All but two of them were dead.
+%
+The scum also rises.
+ -- Dr. Hunter S. Thompson
+%
+The seven deadly sins ... Food, clothing, firing, rent, taxes,
+respectability and children. Nothing can lift those seven milestones
+from man's neck but money; and the spirit cannot soar until the
+milestones are lifted.
+ -- George Bernard Shaw
+%
+ The seven eyes of Ningauble the Wizard floated back to his hood
+as he reported to Fafhrd: "I have seen much, yet cannot explain all.
+The Gray Mouser is exactly twenty-five feet below the deepest cellar in
+the palace of Gilpkerio Kistomerces. Even though twenty-four parts in
+twenty-five of him are dead, he is alive.
+
+ "Now about Lankhmar. She's been invaded, her walls breached
+everywhere and desperate fighting is going on in the streets, by a
+fierce host which out-numbers Lankhmar's inhabitants by fifty to one --
+and equipped with all modern weapons. Yet you can save the city."
+
+ "How?" demanded Fafhrd.
+
+ Ningauble shrugged. "You're a hero. You should know."
+ -- Fritz Leiber, from "The Swords of Lankhmar"
+%
+The sheep that fly over your head are soon to land.
+%
+The shortest distance between two points is under construction.
+ -- Noelie Alito
+%
+The Sixth Commandment of Frisbee:
+ The greatest single aid to distance is for the disc to be going
+in a direction you did not want. (Goes the wrong way = Goes a long
+way.)
+ -- Dan Roddick
+%
+"The society which scorns excellence in plumbing as a humble activity
+and tolerates shoddiness in philosophy because it is an exalted
+activity will have neither good plumbing nor good philosophy ...
+neither its pipes nor its theories will hold water."
+%
+"The sooner all the animals are dead, the sooner we'll find their
+money."
+ -- Ed Bluestone, "The National Lampoon"
+%
+"The sooner you fall behind, the more time you'll have to catch up!"
+%
+The sooner you make your first 5000 mistakes, the sooner you will be
+able to correct them.
+ -- Nicolaides
+%
+The soul would have no rainbow had the eyes no tears.
+%
+The Soviet pre-eminence in chess can be traced to the average Russian's
+readiness to brood obsessively over anything, even the arrangement of
+some pieces of wood. Indeed, the Russians' predisposition for quiet
+reflection followed by sudden preventive action explains why they led
+the field for many years in both chess and ax murders. It is well
+known that as early as 1970, the U.S.S.R., aware of what a defeat at
+Reykjavik would do to national prestige, implemented a vigorous program
+of preparation and incentive. Every day for an entire year, a team of
+psychologists, chess analysts and coaches met with the top three
+Russian grand masters and threatened them with a pointy stick. That
+these tactics proved fruitless is now a part of chess history and a
+further testament to the American way, which provides that if you want
+something badly enough, you can always go to Iceland and get it from
+the Russians.
+ -- Marshall Brickman, Playboy, April, 1973
+%
+ The STAR WARS Song
+ Sung to the tune of "Lola", by the Kinks:
+
+I met him in a swamp down in Dagobah
+Where it bubbles all the time like a giant cabinet soda
+ S-O-D-A soda
+I saw the little runt sitting there on a log
+I asked him his name and in a raspy voice he said Yoda
+ Y-O-D-A Yoda, Yo-Yo-Yo-Yo Yoda
+
+Well I've been around but I ain't never seen
+A guy who looks like a Muppet but he's wrinkled and green
+ Oh my Yoda, Yo-Yo-Yo-Yo Yoda
+Well I'm not dumb but I can't understand
+How he can raise me in the air just by raising his hand
+ Oh my Yoda, Yo-Yo-Yo-Yo Yoda, Yo-Yo-Yo-Yo Yoda
+%
+The state law of Pennsylvania prohibits singing in the bathtub.
+%
+The steady state of disks is full.
+ -- Ken Thompson
+%
+ THE STORY OF CREATION
+ or
+ THE MYTH OF URK
+
+In the beginning there was data. The data was without form and null,
+and darkness was upon the face of the console; and the Spirit of IBM
+was moving over the face of the market. And DEC said, "Let there be
+registers"; and there were registers. And DEC saw that they carried;
+and DEC separated the data from the instructions. DEC called the data
+Stack, and the instructions they called Code. And there was evening
+and there was morning, one interrupt ...
+ -- Rico Tudor
+%
+The streets are safe in Philadelphia, it's only the people who make
+them unsafe.
+ -- Mayor Frank Rizzo
+%
+"The student in question is performing minimally for his peer group and
+is an emerging underachiever."
+%
+The study of non-linear physics is like the study of non-elephant
+biology.
+%
+"The subspace _W inherits the other 8 properties of _V. And there aren't
+even any property taxes."
+ -- J. MacKay, Mathematics 134b
+%
+The sum of the Universe is zero.
+%
+The sun was shining on the sea,
+Shining with all his might:
+He did his very best to make
+The billows smooth and bright --
+And this was very odd, because it was
+The middle of the night.
+ -- Lewis Carroll, "Through the Looking Glass"
+%
+The superfluous is very necessary.
+ -- Voltaire
+%
+The surest protection against temptation is cowardice.
+ -- Mark Twain
+%
+The temperature of Heaven can be rather accurately computed. Our
+authority is Isaiah 30:26, "Moreover, the light of the Moon shall be as
+the light of the Sun and the light of the Sun shall be sevenfold, as
+the light of seven days." Thus Heaven receives from the Moon as much
+radiation as we do from the Sun, and in addition 7*7 (49) times as much
+as the Earth does from the Sun, or 50 times in all. The light we
+receive from the Moon is one 1/10,000 of the light we receive from the
+Sun, so we can ignore that ... The radiation falling on Heaven will
+heat it to the point where the heat lost by radiation is just equal to
+the heat received by radiation, i.e., Heaven loses 50 times as much
+heat as the Earth by radiation. Using the Stefan-Boltzmann law for
+radiation, (_H/_E)^4 = 50, where _E is the absolute temperature of the
+earth (-300K), gives _H as 798K (525C). The exact temperature of Hell
+cannot be computed ... [However] Revelations 21:8 says "But the
+fearful, and unbelieving ... shall have their part in the lake which
+burneth with fire and brimstone." A lake of molten brimstone means
+that its temperature must be at or below the boiling point, 444.6C. We
+have, then, that Heaven, at 525C is hotter than Hell at 445C.
+ -- From "Applied Optics" vol. 11, A14, 1972
+%
+The Third Law of Photography:
+ If you did manage to get any good shots, they will be ruined
+when someone inadvertently opens the darkroom door and all of the dark
+leaks out.
+%
+The Three Laws of Thermodynamics:
+
+The First Law: You can't get anything without working for it.
+The Second Law: The most you can accomplish by working is to break
+ even.
+The Third Law: You can only break even at absolute zero.
+%
+ The Three Major Kind of Tools
+
+* Tools for hittings things to make them loose or to tighten them up or
+ jar their many complex, sophisticated electrical parts in such a
+ manner that they function perfectly. (These are your hammers, maces,
+ bludgeons, and truncheons.)
+
+* Tools that, if dropped properly, can penetrate your foot. (Awls)
+
+* Tools that nobody should ever use because the potential danger is far
+ greater than the value of any project that could possibly result.
+ (Power saws, power drills, power staplers, any kind of tool that uses
+ any kind of power more advanced than flashlight batteries.)
+ -- Dave Barry, "The Taming of the Screw"
+%
+The trouble with a kitten is that
+When it grows up, it's always a cat
+ -- Ogden Nash.
+%
+The trouble with being poor is that it takes up all your time.
+%
+The trouble with being punctual is that nobody's there to appreciate
+it.
+ -- Franklin P. Jones
+%
+The trouble with being punctual is that people think you have nothing
+more important to do.
+%
+The trouble with doing something right the first time is that nobody
+appreciates how difficult it was.
+%
+The trouble with superheros is what to do between phone booths.
+ -- Ken Kesey
+%
+The truth is what is; what should be is a dirty lie.
+ -- Lenny Bruce
+%
+The truth of a proposition has nothing to do with its credibility. And
+vice versa.
+%
+The turtle lives 'twixt plated decks
+Which practically conceal its sex.
+I think it clever of the turtle
+In such a fix to be so fertile.
+ -- Ogden Nash
+%
+"The two most common things in the universe are hydrogen and
+stupidity."
+%
+The typewriting machine, when played with expression, is no more
+annoying than the piano when played by a sister or near relation.
+ -- Oscar Wilde
+%
+The United States also has its native Fascists who say that they are
+"100 percent American"...
+ -- U. S. Army (1945)
+%
+The United States is like the guy at the party who gives cocaine to
+everybody and still nobody likes him.
+ -- Jim Samuels
+%
+The universe does not have laws -- it has habits, and habits can be
+broken.
+%
+The universe is like a safe to which there is a combination -- but the
+combination is locked up in the safe.
+ -- Peter DeVries
+%
+The University of California Bears announced the signing of Reggie
+Philbin to a letter of intent to attend Cal next Fall. Philbin is said
+to make up for no talent by cheating well. Says Philbin of his
+decision to attend Cal, "I'm in it for the free ride."
+%
+The USA is so enormous, and so numerous are its schools, colleges and
+religious seminaries, many devoted to special religious beliefs ranging
+from the unorthodox to the dotty, that we can hardly wonder at its
+yielding a more bounteous harvest of gobbledygook than the rest of the
+world put together.
+ -- Sir Peter Medawar
+%
+The use of COBOL cripples the mind; its teaching should, therefore, be
+regarded as a criminal offense.
+ -- E. W. Dijkstra
+%
+The verdict of a jury is the a priori opinion of that juror who smokes
+the worst cigars.
+ -- H. L. Mencken
+%
+The very ink with which all history is written is merely fluid
+prejudice.
+ -- Mark Twain
+%
+The very powerful and the very stupid have one thing in common.
+Instead of altering their views to fit the facts, they alter the facts
+to fit their views ... which can be very uncomfortable if you happen to
+be one of the facts that needs altering.
+ -- Doctor Who, "Face of Evil"
+%
+"The voters have spoken, the bastards ..."
+%
+"The wages of sin are death; but after they're done taking out taxes,
+it's just a tired feeling:"
+%
+The wages of sin are high but you get your money's worth.
+%
+"The warning message we sent the Russians was a calculated ambiguity
+that would be clearly understood."
+ -- Alexander Haig
+%
+"The way to make a small fortune in the commodities market is to start
+with a large fortune."
+%
+The wind doth taste so bitter sweet,
+ Like Jaspar wine and sugar,
+It must have blown through someone's feet,
+ Like those of Caspar Weinberger.
+ -- P. Opus
+%
+ THE WOMBAT
+
+The wombat lives across the seas,
+Among the far Antipodes.
+He may exist on nuts and berries,
+Or then again, on missionaries;
+His distant habitat precludes
+Conclusive knowledge of his moods.
+But I would not engage the wombat
+In any form of mortal combat.
+%
+The world is coming to an end ... SAVE YOUR BUFFERS!!!
+%
+The world is coming to an end! Repent and return those library books!
+%
+The world is coming to an end. Please log off.
+%
+The world's as ugly as sin,
+And almost as delightful
+ -- Frederick Locker-Lampson
+%
+The years of peak mental activity are undoubtedly between the ages of
+four and eighteen. At four we know all the questions, at eighteen all
+the answers.
+%
+Then a man said: Speak to us of Expectations.
+
+He then said: If a man does not see or hear the waters of the Jordan,
+then he should not taste the pomegranate or ply his wares in an open
+market.
+
+If a man would not labour in the salt and rock quarries then he should
+not accept of the Earth that which he refuses to give of himself.
+
+Such a man would expect a pear of a peach tree.
+Such a man would expect a stone to lay an egg.
+Such a man would expect Sears to assemble a lawnmower.
+ -- Kehlog Albran, "The Profit"
+%
+Then here's to the City of Boston,
+The town of the cries and the groans.
+Where the Cabots can't see the Kabotschniks,
+And the Lowells won't speak to the Cohns.
+ -- Franklin Pierce Adams
+%
+ THEORY
+Into love and out again,
+ Thus I went and thus I go.
+Spare your voice, and hold your pen:
+ Well and bitterly I know
+All the songs were ever sung,
+ All the words were ever said;
+Could it be, when I was young,
+ Someone dropped me on my head?
+ -- Dorothy Parker
+%
+There *__is* intelligent life on Earth, but I leave for Texas on Monday.
+%
+There are four kinds of homicide: felonious, excusable, justifiable,
+and praiseworthy ...
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+There are many intelligent species in the universe. They all own
+cats.
+%
+There are no data that cannot be plotted on a straight line if the axis
+are chosen correctly.
+%
+There are no games on this system.
+%
+There are no physicists in the hottest parts of hell, because the
+existence of a "hottest part" implies a temperature difference, and any
+marginally competent physicist would immediately use this to run a heat
+engine and make some other part of hell comfortably cool. This is
+obviously impossible.
+ -- Richard Davisson
+%
+There are people so addicted to exaggeration that they can't tell the
+truth without lying.
+%
+There are really not many jobs that actually require a penis or a
+vagina, and all other occupations should be open to everyone.
+ -- Gloria Steinem
+%
+ There are some goyisha names that just about guarantee that
+someone isn't Jewish. For example, you'll never meet a Jew named
+Johnson or Wright or Jones or Sinclair or Ricks or Stevenson or Reid or
+Larsen or Jenks. But some goyisha names just about guarantee that
+every other person you meet with that name will be Jewish. Why is
+this?
+ Who knows? Learned rabbis have pondered this question for
+centuries and have failed to come up with an answer, and you think ___you
+can find one? Get serious. You don't even understand why it's
+forbidden to eat crab -- fresh cold crab with mayonnaise -- or lobster
+-- soft tender morsels of lobster dipped in melted butter. You don't
+even understand a simple thing like that, and yet you hope to discover
+why there are more Jews named Miller than Katz? Fat Chance.
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+"There are some micro-organisms that exhibit characteristics of both
+plants and animals. When exposed to light they undergo photosynthesis;
+and when the lights go out, they turn into animals. But then again,
+don't we all?"
+%
+"There are those who claim that magic is like the tide; that it swells
+and fades over the surface of the earth, collecting in concentrated
+pools here and there, almost disappearing from other spots, leaving
+them parched for wonder. There are also those who believe that if you
+stick your fingers up your nose and blow, it will increase your
+intelligence."
+ -- The Teachings of Ebenezum, Volume VII
+%
+There are three kinds of lies: Lies, Damn Lies, and Statistics.
+ -- Disraeli
+%
+"There are three possibilities: Pioneer's solar panel has turned away
+from the sun; there's a large meteor blocking transmission; or someone
+loaded Star Trek 3.2 into our video processor."
+%
+There are three possible parts to a date, of which at least two must be
+offered: entertainment, food, and affection. It is customary to begin
+a series of dates with a great deal of entertainment, a moderate amount
+of food, and the merest suggestion of affection. As the amount of
+affection increases, the entertainment can be reduced proportionately.
+When the affection IS the entertainment, we no longer call it dating.
+Under no circumstances can the food be omitted.
+ -- Miss Manners' Guide to Excruciatingly Correct Behavior
+%
+"There are three principal ways to lose money: wine, women, and
+engineers. While the first two are more pleasant, the third is by far
+the more certain."
+ -- Baron Rothschild, ca. 1800
+%
+There are three schools of magic. One: State a tautology, then ring
+the changes on its corollaries; that's philosophy. Two: Record many
+facts. Try to find a pattern. Then make a wrong guess at the next
+fact; that's science. Three: Be aware that you live in a malevolent
+Universe controlled by Murphy's Law, sometimes offset by Brewster's
+Factor; that's engineering.
+%
+There are three things I always forget. Names, faces -- the third I
+can't remember.
+ -- Italo Svevo
+%
+There are three ways to get something done:
+ (1) Do it yourself.
+ (2) Hire someone to do it for you.
+ (3) Forbid your kids to do it.
+%
+There are three ways to get something done: do it yourself, hire
+someone, or forbid your kids to do it.
+%
+There are times when truth is stranger than fiction and lunch time is
+one of them.
+%
+There are two kinds of solar-heat systems: "passive" systems collect
+the sunlight that hits your home, and "active" systems collect the
+sunlight that hits your neighbors' homes, too.
+ -- Dave Barry, "Postpetroleum Guzzler"
+%
+There are two types of people in this world, good and bad. The good
+sleep better, but the bad seem to enjoy the waking hours much more.
+ -- Woody Allen
+%
+"There are two ways of constructing a software design: One way is to
+make is so simple that there are obviously no deficiencies, and the
+other way is to make it so complicated that there are no obvious
+deficiencies."
+ -- C. A. R. Hoare
+%
+"There are two ways of disliking poetry; one way is to dislike it, the
+other is to read Pope."
+ -- Oscar Wilde
+%
+There are two ways to write error-free programs. Only the third one
+works.
+%
+There are very few personal problems that cannot be solved through a
+suitable application of high explosives.
+%
+There can be no twisted thought without a twisted molecule.
+ -- R. W. Gerard
+%
+There cannot be a crisis next week. My schedule is already full.
+ -- Henry Kissinger
+%
+There exist tasks which cannot be done by more than 10 men or fewer
+than 100.
+ -- Steele's Law
+%
+There has been an alarming increase in the number of things you know
+nothing about.
+%
+There is a certain impertinence in allowing oneself to be burned for an
+opinion.
+ -- Anatole France
+%
+There is a great discovery still to be made in Literature: that of
+paying literary men by the quantity they do NOT write.
+%
+There is a green, multi-legged creature crawling on your shoulder.
+%
+There is a Massachusetts law requiring all dogs to have their hind legs
+tied during the month of April.
+%
+There is a natural hootchy-kootchy to a goldfish.
+ -- Walt Disney
+%
+"There is a road to freedom. Its milestones are Obedience, Endeavor,
+Honesty, Order, Cleanliness, Sobriety, Truthfulness, Sacrifice, and
+love of the Fatherland."
+ -- Adolf Hitler
+%
+There is a theory that states: "If anyone finds out what the universe
+is for it will disappear and be replaced by something more bazaarly
+inexplicable."
+
+There is another theory that states: "This has already happened ...."
+ -- Douglas Adams, "Hitch-Hikers Guide to the Galaxy"
+%
+There is a theory which states that if ever anyone discovers exactly
+what the Universe is for and why it is here, it will instantly
+disappear and be replaced by something even more bizarre and
+inexplicable. There is another theory which states that this has
+already happened.
+ -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
+%
+"There is hopeful symbolism in the fact that flags do not wave in a
+vacuum."
+ -- Arthur C. Clarke
+%
+There is no distinctly native American criminal class except Congress.
+ -- Mark Twain
+%
+There is no realizable power that man cannot, in time, fashion the
+tools to attain, nor any power so secure that the naked ape will not
+abuse it. So it is written in the genetic cards -- only physics and
+war hold him in check. And also the wife who wants him home by five,
+of course.
+ -- Encyclopedia Apocryphia, 1990 ed.
+%
+"There is no reason for any individual to have a computer in their
+home."
+ -- Ken Olson, President of DEC, World Future Society
+ Convention, 1977
+%
+There is no satisfaction in hanging a man who does not object to it
+ -- G. B. Shaw
+%
+There is no substitute for good manners, except, perhaps, fast
+reflexes.
+%
+There is no such thing as fortune. Try again.
+%
+There is no time like the pleasant.
+%
+There is no time like the present for postponing what you ought to be
+doing.
+%
+There is no TRUTH. There is no REALITY. There is no CONSISTENCY.
+There are no ABSOLUTE STATEMENTS I'm very probably wrong.
+%
+"There is nothing which cannot be answered by means of my doctrine,"
+said a monk, coming into a teahouse where Nasrudin sat. "And yet just
+a short time ago, I was challenged by a scholar with an unanswerable
+question," said Nasrudin. "I could have answered it if I had been
+there." "Very well. He asked, 'Why are you breaking into my house in
+the middle of the night?'"
+%
+There is nothing wrong with Southern California that a rise in the
+ocean level wouldn't cure.
+ -- Ross MacDonald
+%
+There is only one thing in the world worse than being talked about, and
+that is not being talked about.
+ -- Oscar Wilde
+%
+There is something fascinating about science. One gets such wholesale
+returns of conjecture out of such a trifling investment of fact.
+ -- Mark Twain
+%
+There once was a girl named Irene
+Who lived on distilled kerosene
+ But she started absorbin'
+ A new hydrocarbon
+And since then has never benzene.
+%
+There once was a member of Mensa
+Who was a most excellent fencer.
+ The sword that he used
+ Was his -- (line is refused,
+And has now been removed by the censor).
+%
+There once was an old man from Esser,
+Who's knowledge grew lesser and lesser.
+ It at last grew so small,
+ He knew nothing at all,
+And now he's a College Professor.
+%
+"There was a boy called Eustace Clarence Scrubb, and he almost deserved
+it."
+ -- C. S. Lewis, The Chronicles of Narnia
+%
+There was a plane crash over mid-ocean, and only three survivors were
+left in the life-raft: the Pope, the President, and Mayor Daley.
+Unfortunately, it was a one-man life-raft, and quickly sinking, so they
+started debating who should be allowed to stay.
+
+The Pope pointed out that he was the spiritual leader of millions all
+over the world, the President explained that if he died then America
+would be stuck with the Vice-President, and so forth. Then Mayor Daley
+said, "Look! We're not solving anything like this! The only fair
+thing to do is to vote on it." So they did, and Mayor Daley won by 97
+votes.
+%
+There was a young lady from Hyde
+Who ate a green apple and died.
+ While her lover lamented
+ The apple fermented
+And made cider inside her inside.
+%
+There was a young man who said "God,
+I find it exceedingly odd,
+ That the willow oak tree
+ Continues to be,
+When there's no one about in the Quad."
+
+"Dear Sir, your astonishment's odd,
+For I'm always about in the Quad;
+ And that's why the tree,
+ Continues to be,"
+Signed "Yours faithfully, God."
+%
+There was a young poet named Dan,
+Whose poetry never would scan.
+ When told this was so,
+ He said, "Yes, I know.
+%
+There was a young poet named Dan,
+Whose poetry never would scan.
+ When told this was so,
+ He said, "Yes, I know.
+It's because I try to put every possible syllable into that last line that I can."
+%
+"There was an interesting development in the CBS-Westmoreland trial:
+both sides agreed that after the trial, Andy Rooney would be allowed to
+talk to the jury for three minutes about little things that annoyed him
+during the trial."
+ -- David Letterman
+%
+There were in this country two very large monopolies. The larger of
+the two had the following record: the Vietnam War, Watergate, double-
+digit inflation, fuel and energy shortages, bankrupt airlines, and the
+8-cent postcard. The second was responsible for such things as the
+transistor, the solar cell, lasers, synthetic crystals, high fidelity
+stereo recording, sound motion pictures, radio astronomy, negative
+feedback, magnetic tape, magnetic "bubbles", electronic switching
+systems, microwave radio and TV relay systems, information theory, the
+first electrical digital computer, and the first communications
+satellite. Guess which one got to tell the other how to run the
+telephone business?
+%
+There's a fine line between courage and foolishness. Too bad it's not
+a fence.
+%
+There's an old proverb that says just about whatever you want it to.
+%
+There's little in taking or giving,
+ There's little in water or wine:
+This living, this living, this living,
+ Was never a project of mine.
+Oh, hard is the struggle, and sparse is
+ The gain of the one at the top,
+For art is a form of catharsis,
+ And love is a permanent flop,
+And work is the province of cattle,
+ And rest's for a clam in a shell,
+So I'm thinking of throwing the battle --
+ Would you kindly direct me to hell?
+ -- Dorothy Parker
+%
+There's no easy quick way out, we're gonna have to live through our
+whole lives, win, lose, or draw.
+ -- Walt Kelly
+%
+There's no future in time travel
+%
+There's no point in being grown up if you can't be childish sometimes.
+ -- Dr. Who
+%
+There's no real need to do housework -- after four years it doesn't get
+any worse.
+%
+There's no room in the drug world for amateurs.
+%
+There's no trick to being a humorist when you have the whole government
+working for you.
+ -- Will Rodgers
+%
+"There's nothing in the middle of the road but a yellow stripe and dead
+armadillos."
+ -- Jim Hightower, Texas Agricultural Commissioner
+%
+"There's nothing wrong with teenagers that reasoning with them won't
+aggravate."
+%
+There's only one way to have a happy marriage and as soon as I learn
+what it is I'll get married again.
+ -- Clint Eastwood
+%
+There's so much plastic in this culture that vinyl leopard skin is
+becoming an endangered synthetic.
+ -- Lily Tomlin
+%
+"These are DARK TIMES for all mankind's HIGHEST VALUES!"
+"These are DARK TIMES for FREEDOM and PROSPERITY!"
+"These are GREAT TIMES to put your money on BAD GUY to kick the CRAP
+out of MEGATON MAN!"
+%
+These days the necessities of life cost you about three times what they
+used to, and half the time they aren't even fit to drink.
+%
+They also surf who only stand on waves.
+%
+"They make a desert and call it peace."
+ -- Tacitus (55?-120?)
+%
+They spell it "da Vinci" and pronounce it "da Vinchy". Foreigners
+always spell better than they pronounce.
+ -- Mark Twain
+%
+"They that can give up essential liberty to obtain a little temporary
+safety deserve neither liberty nor safety."
+ -- Benjamin Franklin, 1759
+%
+"They told me I was gullible ... and I believed them!"
+%
+They told me you had proven it When they discovered our results
+ About a month before. Their hair began to curl
+The proof was valid, more or less Instead of understanding it
+ But rather less than more. We'd run the thing through PRL.
+
+He sent them word that we would try Don't tell a soul about all this
+ To pass where they had failed For it must ever be
+And after we were done, to them A secret, kept from all the rest
+ The new proof would be mailed. Between yourself and me.
+
+My notion was to start again
+ Ignoring all they'd done
+We quickly turned it into code
+ To see if it would run.
+%
+They're only trying to make me LOOK paranoid!
+%
+"They're unfriendly, which is fortunate, really. They'd be difficult
+to like."
+ -- Avon
+%
+Things are more like they used to be than they are now.
+%
+Things will be bright in P.M. A cop will shine a light in your face.
+%
+Think big. Pollute the Mississippi.
+%
+Think honk if you're a telepath.
+%
+Think of it! With VLSI we can pack 100 ENIACs in 1 sq. cm.!
+%
+Think of your family tonight. Try to crawl home after the computer
+crashes.
+%
+Think twice before speaking, but don't say "think think click click".
+%
+"Thirty days hath Septober,
+April, June, and no wonder.
+all the rest have peanut butter
+except my father who wears red suspenders."
+%
+This Fortue Examined By INSPECTOR NO. 2-14
+%
+This fortune cookie program out of order. For those in desperate need,
+please use the program "________randchar". This program generates random
+characters, and, given enough time, will undoubtedly come up with
+something profound. It will, however, take it no time at all to be
+more profound than THIS program has ever been.
+%
+This fortune intentionally not included.
+%
+This fortune is false.
+%
+This fortune is inoperative. Please try another.
+%
+"This is a country where people are free to practice their religion,
+regardless of race, creed, color, obesity, or number of dangling
+keys ..."
+%
+"This is a job for BOB VIOLENCE and SCUM, the INCREDIBLY STUPID MUTANT
+DOG."
+ -- Bob Violence
+%
+"This is a test of the Emergency Broadcast System. If this had been an
+actual emergency, do you really think we'd stick around to tell you?"
+%
+This is an especially good time for you vacationers who plan to fly,
+because the Reagan administration, as part of the same policy under
+which it recently sold Yellowstone National Park to Wayne Newton, has
+"deregulated" the airline industry. What this means for you, the
+consumer, is that the airlines are no longer required to follow any
+rules whatsoever. They can show snuff movies. They can charge for
+oxygen. They can hire pilots right out of Vending Machine Refill
+Person School. They can conserve fuel by ejecting husky passengers
+over water. They can ram competing planes in mid-air. These
+innovations have resulted in tremendous cost savings which have been
+passed along to you, the consumer, in the form of flights with
+amazingly low fares, such as $29. Of course, certain restrictions do
+apply, the main one being that all these flights take you to Newark,
+and you must pay thousands of dollars if you want to fly back out.
+ -- Dave Barry, "Iowa -- Land of Secure Vacations"
+%
+This is an unauthorized cybernetic announcement.
+%
+This is for all ill-treated fellows
+ Unborn and unbegot,
+For them to read when they're in trouble
+ And I am not.
+ -- A. E. Housman
+%
+"This is lemma 1.1. We start a new chapter so the numbers all go back
+to one."
+ -- Prof. Seager, C&O 351
+%
+This is National Non-Dairy Creamer Week.
+%
+THIS IS PLEDGE WEEK FOR THE FORTUNE PROGRAM
+
+If you like the fortune program, why not support it now with your
+contribution of a pithy fortune, clean or obscene? We cannot continue
+without your support. Less than 14% of all fortune users are
+contributors. That means that 86% of you are getting a free ride. We
+can't go on like this much longer. Federal cutbacks mean less money
+for fortunes, and unless user contributions increase to make up the
+difference, the fortune program will have to shut down between midnight
+and 8 a.m. Don't let this happen. Mail your fortunes right now to
+"fortune". Just type in your favorite pithy saying. Do it now before
+you forget. Our target is 300 new fortunes by the end of the week.
+Don't miss out. All fortunes will be acknowledged. If you contribute
+30 fortunes or more, you will receive a free subscription to "The
+Fortune Hunter", our monthly program guide. If you contribute 50 or
+more, you will receive a free "Fortune Hunter" coffee mug ....
+%
+This is the ____LAST time I take travel suggestions from Ray Bradbury!
+%
+This is the first numerical problem I ever did. It demonstrates the
+power of computers:
+
+Enter lots of data on calorie & nutritive content of foods. Instruct
+the thing to maximize a function describing nutritive content, with a
+minimum level of each component, for fixed caloric content. The
+results are that one should eat each day:
+
+ 1/2 chicken
+ 1 egg
+ 1 glass of skim milk
+ 27 heads of lettuce.
+ -- Rev. Adrian Melott
+%
+This is the story of the bee
+Whose sex is very hard to see
+
+You cannot tell the he from the she
+But she can tell, and so can he
+
+The little bee is never still
+She has no time to take the pill
+
+And that is why, in times like these
+There are so many sons of bees.
+%
+This is your fortune.
+%
+This land is full of trousers!
+this land is full of mausers!
+ And pussycats to eat them when the sun goes down!
+ -- Firesign Theater
+%
+This land is made of mountains,
+This land is made of mud,
+This land has lots of everything,
+For me and Elmer Fudd.
+
+This land has lots of trousers,
+This land has lots of mousers,
+And pussycats to eat them
+When the sun goes down.
+%
+This life is a test. It is only a test. Had this been an actual life,
+you would have received further instructions as to what to do and where
+to go.
+%
+This login session: $13.99, but for you $11.88
+%
+This novel is not to be tossed lightly aside, but to be hurled with
+great force.
+ -- Dorothy Parker
+%
+This planet has -- or rather had -- a problem, which was this: most of
+the people living on it were unhappy for pretty much of the time. Many
+solutions were suggested for this problem, but most of these were
+largely concerned with the movements of small green pieces of paper,
+which is odd because on the whole it wasn't the small green pieces of
+paper that were unhappy.
+ -- Douglas Adams
+%
+"This process can check if this value is zero, and if it is, it does
+something child-like."
+ -- Forbes Burkowski, Computer Science 454
+%
+This quote is taken from the Diamondback, the University of Maryland
+student newspaper, of Tuesday, 3/10/87.
+
+ One disadvantage of the Univac system is that it does not use
+ Unix, a recently developed program which translates from one
+ computer language to another and has a built-in editing system
+ which identifies errors in the original program.
+%
+This sentence contradicts itself -- no actually it doesn't.
+ -- Hofstadter
+%
+... This striving for excellence extends into people's personal lives
+as well. When '80s people buy something, they buy the best one, as
+determined by (1) price and (2) lack of availability. Eighties people
+buy imported dental floss. They buy gourmet baking soda. If an '80s
+couple goes to a restaurant where they have made a reservation three
+weeks in advance, and they are informed that their table is available,
+they stalk out immediately, because they know it is not an excellent
+restaurant. If it were, it would have an enormous crowd of
+excellence-oriented people like themselves waiting, their beepers going
+off like crickets in the night. An excellent restaurant wouldn't have
+a table ready immediately for anybody below the rank of Liza Minnelli.
+ -- Dave Barry, "In Search of Excellence"
+%
+This will be a memorable month -- no matter how hard you try to forget
+it.
+%
+ Thompson, if he is to be believed, has sampled the entire
+rainbow of legal and illegal drugs in heroic efforts to feel better
+than he does.
+ As for the truth about his health: I have asked around about
+it. I am told that he appears to be strong and rosy, and steadily
+sane. But we will be doing what he wants us to do, I think, if we
+consider his exterior a sort of Dorian Gray facade. Inwardly, he is
+being eaten alive by tinhorn politicians.
+ The disease is fatal. There is no known cure. The most we can
+do for the poor devil, it seems to me, is to name his disease in his
+honor. From this moment on, let all those who feel that Americans can
+be as easily led to beauty as to ugliness, to truth as to public
+relations, to joy as to bitterness, be said to be suffering from Hunter
+Thompson's disease. I don't have it this morning. It comes and goes.
+This morning I don't have Hunter Thompson's disease.
+ -- Kurt Vonnegut Jr. on Dr. Hunter S. Thompson: Excerpt
+ from "A Political Disease", Vonnegut's review of "Fear
+ and Loathing: On the Campaign Trail '72"
+%
+Those of you who think you know everything are very annoying to those
+of us who do.
+%
+Those who can't write, write manuals.
+%
+Those who can, do. Those who can't, simulate.
+%
+"Those who do not do politics will be done in by politics."
+ -- French Proverb
+%
+Those who do not understand Unix are condemned to reinvent it, poorly.
+ -- Henry Spencer
+%
+Those who educate children well are more to be honored than parents,
+for these only gave life, those the art of living well.
+ -- Aristotle
+%
+Those who express random thoughts to legislative committees are often
+surprised and appalled to find themselves the instigators of law.
+ -- Mark B. Cohen
+%
+Those who in quarrels interpose, must often wipe a bloody nose.
+%
+Those who make peaceful revolution impossible will make violent
+revolution inevitable.
+ -- John F. Kennedy
+%
+Those who profess to favor freedom, and yet deprecate agitation, are
+men who want rain without thunder and lightning. They want the ocean
+without the roar of its many waters.
+ -- Frederick Douglass
+%
+Three great scientific theories of the structure of the universe are
+the molecular, the corpuscular and the atomic. A fourth affirms, with
+Haeckel, the condensation or precipitation of matter from ether --
+whose existence is proved by the condensation or precipitation ... A
+fifth theory is held by idiots, but it is doubtful if they know any
+more about the matter than the others.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Time flies like an arrow
+Fruit flies like a banana
+%
+Time flies like an arrow, but fruit flies like a banana.
+%
+Time is an illusion; lunchtime, doubly so.
+ -- Ford Prefect
+%
+Time is nature's way of making sure that everything doesn't happen at
+once.
+%
+'Tis the dream of each programmer,
+Before his life is done,
+To write three lines of APL,
+And make the damn things run.
+%
+ (to "The Caissons Go Rolling Along")
+Scratch the disks, dump the core, Shut it down, pull the plug
+Roll the tapes across the floor, Give the core an extra tug
+And the system is going to crash. And the system is going to crash.
+Teletypes smashed to bits. Mem'ry cards, one and all,
+Give the scopes some nasty hits Toss out halfway down the hall
+And the system is going to crash. And the system is going to crash.
+And we've also found Just flip one switch
+When you turn the power down, And the lights will cease to twitch
+You turn the disk readers into trash. And the tape drives will crumble
+ in a flash.
+Oh, it's so much fun, When the CPU
+Now the CPU won't run Can print nothing out but "foo,"
+And the system is going to crash. The system is going to crash.
+%
+ To A Quick Young Fox:
+Why jog exquisite bulk, fond crazy vamp,
+Daft buxom jonquil, zephyr's gawky vice?
+Guy fed by work, quiz Jove's xanthic lamp --
+Zow! Qualms by deja vu gyp fox-kin thrice.
+ -- Lazy Dog
+%
+To be intoxicated is to feel sophisticated but not be able to say it.
+%
+To be is to do.
+ -- I. Kant
+To do is to be.
+ -- A. Sartre
+Yabba-Dabba-Doo!
+ -- F. Flinstone
+%
+"To be responsive at this time, though I will simply say, and therefore
+this is a repeat of what I said previously, that which I am unable to
+offer in response is based on information available to make no such
+statement."
+%
+To be sure of hitting the target, shoot first and, whatever you hit,
+call it the target.
+%
+To err is human, to forgive is Not Company Policy.
+%
+"To err is human, to forgive, beyond the scope of the Operating System"
+%
+To err is human, to moo bovine.
+%
+To every Ph.D. there is an equal and opposite Ph.D.
+ -- B. Duggan
+%
+To generalize is to be an idiot.
+ -- William Blake
+%
+To get something done, a committee should consist of no more than three
+men, two of them absent.
+%
+To invent, you need a good imagination and a pile of junk.
+ -- Thomas Edison
+%
+To iterate is human, to recurse, divine.
+%
+To the best of my recollection, Senator, I can't recall.
+%
+To the systems programmer, users and applications serve only to provide
+a test load.
+%
+To those accustomed to the precise, structured methods of conventional
+system development, exploratory development techniques may seem messy,
+inelegant, and unsatisfying. But it's a question of congruence:
+precision and flexibility may be just as disfunctional in novel,
+uncertain situations as sloppiness and vacillation are in familiar,
+well-defined ones. Those who admire the massive, rigid bone structures
+of dinosaurs should remember that jellyfish still enjoy their very
+secure ecological niche.
+ -- Beau Sheil, "Power Tools for Programmers"
+%
+To understand this important story, you have to understand how the
+telephone company works. Your telephone is connected to a local
+computer, which is in turn connected to a regional computer, which is
+in turn connected to a loudspeaker the size of a garbage truck on the
+lawn of Edna A. Bargewater of Lawrence, Kan.
+
+Whenever you talk on the phone, your local computer listens in. If it
+suspects you're going to discuss an intimate topic, it notifies the
+computer above it, which listens in and decides whether to alert the
+one above it, until finally, if you really humiliate yourself, maybe
+break down in tears and tell your closest friend about a sordid
+incident from your past involving a seedy motel, a neighbor's spouse,
+an entire religious order, a garden hose and six quarts of tapioca
+pudding, the top computer feeds your conversation into Edna's
+loudspeaker, and she and her friends come out on the porch to listen
+and drink gin and laugh themselves silly.
+ -- Dave Barry, "Won't It Be Just Great Owning Our Own
+ Phones?"
+%
+"To vacillate or not to vacillate, that is the question ... or is it?"
+%
+"To YOU I'm an atheist; to God, I'm the Loyal Opposition."
+ -- Woody Allen
+%
+Today is a good day to bribe a high-ranking public official.
+%
+Today is National Existential Ennui Awareness Day.
+%
+Today is the first day of the rest of the mess
+%
+Today is the first day of the rest of your lossage.
+%
+Today is the tomorrow you worried about yesterday
+%
+Today's scientific question is: What in the world is electricity?
+
+And where does it go after it leaves the toaster?
+ -- Dave Barry, "What is Electricity?"
+%
+"Today's thrilling story has been brought to you by Mushies, the great new
+cereal that gets soggy even without milk or cream. Join us soon for more
+spectacular adventure starring ... Tippy, the Wonder Dog."
+ -- Bob & Ray
+%
+"Today, of course, it is considered very poor taste to use the F-word
+except in major motion pictures."
+ -- Dave Barry, "$#$%#^%!^%&@%@!"
+%
+Toilet Toup'ee, n.:
+ Any shag carpet that causes the lid to become top-heavy, thus
+creating endless annoyance to male users.
+ -- Rich Hall, "Sniglets"
+%
+Tomorrow will be canceled due to lack of interest.
+%
+Tonight's the night: Sleep in a eucalyptus tree.
+%
+Too clever is dumb.
+ -- Ogden Nash
+%
+Too much of a good thing is WONDERFUL.
+ -- Mae West
+%
+Too much of everything is just enough.
+ -- Bob Wier
+%
+Too often I find that the volume of paper expands to fill the available
+briefcases.
+ -- Governor Jerry Brown
+%
+Top scientists agree that with the present rate of consumption, the
+earth's supply of gravity will be exhausted before the 24th century.
+As man struggles to discover cheaper alternatives, we need your help.
+Please...
+
+ CONSERVE GRAVITY
+
+Follow these simple suggestions:
+
+(1) Walk with a light step. Carry helium balloons if possible.
+(2) Use tape, magnets, or glue instead of paperweights.
+(3) Give up skiing and skydiving for more horizontal sports like
+ curling.
+(4) Avoid showers .. take baths instead.
+(5) Don't hang all your clothes in the closet ... Keep them in one big
+ pile.
+(6) Stop flipping pancakes
+%
+Travel important today; Internal Revenue men arrive tomorrow.
+%
+Troubled day for virgins over 16 who are beautiful and wealthy and live
+in eucalyptus trees.
+%
+Truly great madness can not be achieved without significant
+intelligence.
+ -- Henrik Tikkanen
+%
+Truth is the most valuable thing we have -- so let us economize it.
+ -- Mark Twain
+%
+Truth will be out this morning. (Which may really mess things up.)
+%
+Truthful, adj.:
+ Dumb and illiterate.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Try not to have a good time ... This is supposed to be educational.
+ -- Charles Schulz
+%
+Try to be the best of whatever you are, even if what you are is no
+good.
+%
+Try to find the real tense of the report you are reading: Was it done,
+is it being done, or is something to be done? Reports are now written
+in four tenses: past tense, present tense, future tense, and
+pretense. Watch for novel uses of CONGRAM (CONtractor GRAMmer),
+defined by the imperfect past, the insufficient present, and the
+absolutely perfect future.
+ -- Amrom Katz
+%
+Try to get all of your posthumous medals in advance.
+%
+Trying to be happy is like trying to build a machine for which the only
+specification is that it should run noiselessly.
+%
+Trying to define yourself is like trying to bite your own teeth.
+ -- Alan Watts
+%
+Trying to establish voice contact ... please ____yell into keyboard.
+%
+Turnaucka's Law:
+ The attention span of a computer is only as long as its
+electrical cord.
+%
+Tussman's Law:
+ Nothing is as inevitable as a mistake whose time has come.
+%
+TV is chewing gum for the eyes.
+ -- Frank Lloyd Wright
+%
+'Twas midnight, and the UNIX hacks
+Did gyre and gimble in their cave
+All mimsy was the CS-VAX
+And Cory raths outgrabe.
+
+"Beware the software rot, my son!
+The faults that bite, the jobs that thrash!
+Beware the broken pipe, and shun
+The frumious system crash!"
+%
+ 'Twas the Night before Crisis
+
+'Twas the night before crisis, and all through the house,
+ Not a program was working not even a browse.
+The programmers were wrung out too mindless to care,
+ Knowing chances of cutover hadn't a prayer.
+The users were nestled all snug in their beds,
+ While visions of inquiries danced in their heads.
+When out in the lobby there arose such a clatter,
+ I sprang from my tube to see what was the matter.
+And what to my wondering eyes should appear,
+ But a Super Programmer, oblivious to fear.
+More rapid than eagles, his programs they came,
+ And he whistled and shouted and called them by name;
+On Update! On Add! On Inquiry! On Delete!
+ On Batch Jobs! On Closing! On Functions Complete!
+His eyes were glazed over, his fingers were lean,
+ From Weekends and nights in front of a screen.
+A wink of his eye, and a twist of his head,
+ Soon gave me to know I had nothing to dread...
+%
+'Twas the nocturnal segment of the diurnal period
+ preceding the annual Yuletide celebration, And
+ throughout our place of residence,
+Kinetic activity was not in evidence among the
+ possessors of this potential, including that
+ species of domestic rodent known as Mus musculus.
+Hosiery was meticulously suspended from the forward
+ edge of the woodburning caloric apparatus,
+Pursuant to our anticipatory pleasure regarding an
+ imminent visitation from an eccentric
+ philanthropist among whose folkloric appelations
+ is the honorific title of St. Nicklaus ...
+%
+Twenty Percent of Zero is Better than Nothing.
+ -- Walt Kelly
+%
+Two can Live as Cheaply as One for Half as Long.
+ -- Howard Kandel
+%
+Two men came before Nasrudin when he was magistrate. The first man
+said, "This man has bitten my ear -- I demand compensation." The
+second man said, "He bit it himself." Nasrudin withdrew to his
+chambers, and spent an hour trying to bite his own ear. He succeeded
+only in falling over and bruising his forehead. Returning to the
+courtroom, Nasrudin pronounced, "Examine the man whose ear was bitten.
+If his forehead is bruised, he did it himself and the case is
+dismissed. If his forehead is not bruised, the other man did it and
+must pay three silver pieces."
+%
+Two percent of zero is almost nothing.
+%
+"Two sure ways to tell a sexy male; the first is, he has a bad memory.
+I forget the second."
+%
+Two wrongs don't make a right, but three lefts do.
+%
+U: There's a U -- a Unicorn!
+ Run right up and rub its horn.
+ Look at all those points you're losing!
+ UMBER HULKS are so confusing.
+ -- The Roguelet's ABC
+%
+"Ubi non accusator, ibi non judex."
+
+(Where there is no police, there is no speed limit.)
+ -- Roman Law, trans. Petr Beckmann (1971)
+%
+UFO's are for real: the Air Force doesn't exist.
+%
+"Uncle Cosmo ... why do they call this a word processor?"
+
+"It's simple, Skyler ... you've seen what food processors do to food,
+right?"
+ -- MacNelley, "Shoe"
+%
+Uncle Ed's Rule of Thumb:
+ Never use your thumb for a rule. You'll either hit it with a
+hammer or get a splinter in it.
+%
+Uncle Ed's Rule of Thumb:
+ Never use your thumb for a rule. You'll either hit it with a
+hammmer or get a splinter in it.
+%
+Under a government which imprisons any unjustly, the true place for a
+just man is also a prison.
+ -- Henry David Thoreau
+%
+Under a government which imprisons any unjustly, the true place for a
+just man is also in prison.
+ -- Henry David Thoreau
+%
+Under deadline pressure for the next week. If you want something, it
+can wait. Unless it's blind screaming paroxysmally hedonistic ...
+%
+Underlying Principle of Socio-Genetics:
+ Superiority is recessive.
+%
+Unfair animal names:
+
+-- tsetse fly -- bullhead
+-- booby -- duck-billed platypus
+-- sapsucker -- Clarence
+ -- Gary Larson
+%
+United Nations, New York, December 25. The peace and joy of the
+Christmas season was marred by a proclamation of a general strike of
+all the military forces of the world. Panic reigns in the hearts of
+all the patriots of every persuasion.
+
+Meanwhile, fears of universal disaster sank to an all-time low over the
+world.
+ -- Isaac Asimov
+%
+Universe, n.:
+ The problem.
+%
+University, n.:
+ Like a software house, except the software's free, and it's
+usable, and it works, and if it breaks they'll quickly tell you how to
+fix it, and ...
+%
+unix soit qui mal y pense
+%
+UNIX was half a billion (500000000) seconds old on
+Tue Nov 5 00:53:20 1985 GMT (measuring since the time(2) epoch).
+ -- Andy Tannenbaum
+%
+Unnamed Law:
+ If it happens, it must be possible.
+%
+Unquestionably, there is progress. The average American now pays out
+twice as much in taxes as he formerly got in wages.
+ -- H. L. Mencken
+%
+Usage: fortune -P [] -a [xsz] [Q: [file]] [rKe9] -v6[+] dataspec ... inputdir
+%
+User n.:
+ A programmer who will believe anything you tell him.
+%
+USER, n.:
+ The word computer professionals use when they mean "idiot."
+ -- Dave Barry, "Claw Your Way to the Top"
+%
+Using TSO is like kicking a dead whale down the beach.
+ -- S. C. Johnson
+%
+Utility is when you have one telephone, luxury is when you have two,
+opulence is when you have three -- and paradise is when you have none.
+ -- Doug Larson
+%
+Vail's Second Axiom:
+ The amount of work to be done increases in proportion to the
+amount of work already completed.
+%
+Valerie: Aww, Tom, you're going maudlin on me ...
+Tom: I reserve the right to wax maudlin as I wane eloquent ...
+ -- Tom Chapin
+%
+Van Roy's Law:
+ An unbreakable toy is useful for breaking other toys.
+%
+Vanilla, adj.:
+ Ordinary flavor, standard. See FLAVOR. When used of food,
+very often does not mean that the food is flavored with vanilla
+extract! For example, "vanilla-flavored won ton soup" (or simply
+"vanilla won ton soup") means ordinary won ton soup, as opposed to hot
+and sour won ton soup.
+%
+Velilind's Laws of Experimentation:
+ (1) If reproducibility may be a problem, conduct the test only
+ once.
+ (2) If a straight line fit is required, obtain only two data
+ points.
+%
+Veni, Vidi, Visa.
+%
+ "Verily and forsooth," replied Goodgulf darkly. "In the past
+year strange and fearful wonders I have seen. Fields sown with barley
+reap crabgrass and fungus, and even small gardens reject their
+artichoke hearts. There has been a hot day in December and a blue
+moon. Calendars are made with a month of Sundays and a blue-ribbon
+Holstein bore alive two insurance salesmen. The earth splits and the
+entrails of a goat were found tied in square knots. The face of the
+sun blackens and the skies have rained down soggy potato chips."
+
+ "But what do all these things mean?" gasped Frito.
+
+ "Beats me," said Goodgulf with a shrug, "but I thought it made
+good copy."
+ -- Harvard Lampoon, "Bored of the Rings"
+%
+Very few profundities can be expressed in less than 80 characters.
+%
+Vila: "I think I have just made the biggest mistake of my life."
+Orac: "It is unlikely. I would predict there are far greater mistakes
+ waiting to be made by someone with your obvious talent for it."
+%
+Violence is the last refuge of the incompetent.
+ -- Salvor Hardin
+%
+Virginia law forbids bathtubs in the house; tubs must be kept in the
+yard.
+%
+VIRGO (Aug 23 - Sept 22)
+ Learn something new today, like how to spell or how to count to
+ ten without using your fingers. Be careful dressing this
+ morning. You may be hit by a car later in the day and you
+ wouldn't want to be taken to the doctor's office in some of
+ that old underwear you own.
+%
+VIRGO (Aug 23 - Sept 22)
+ You are the logical type and hate disorder. This nitpicking is
+ sickening to your friends. You are cold and unemotional and
+ sometimes fall asleep while making love. Virgos make good bus
+ drivers.
+%
+"Virtual" means never knowing where your next byte is coming from.
+%
+Virtue is its own punishment.
+%
+Vital papers will demonstrate their vitality by spontaneously moving
+from where you left them to where you can't find them.
+%
+Vitamin C deficiency is apauling
+%
+VMS is like a nightmare about RXS-11M.
+%
+Vote anarchist
+%
+Vote for ME -- I'm well-tapered, half-cocked, ill-conceived and
+TAX-DEFERRED!
+%
+VYARZERZOMANIMORORSEZASSEZANSERAREORSES?
+%
+
+ *** System shutdown message from root ***
+
+System going down in 60 seconds
+
+
+%
+"Wagner's music is better than it sounds."
+ -- Mark Twain
+%
+Waiter: "Tea or coffee, gentlemen?"
+1st customer: "I'll have tea."
+2nd customer: "Me, too -- and be sure the glass is clean!"
+ (Waiter exits, returns)
+Waiter: "Two teas. Which one asked for the clean glass?"
+%
+Walk softly and carry a megawatt laser.
+%
+War hath no fury like a non-combatant.
+ -- Charles Edward Montague
+%
+War is peace. Freedom is slavery. Ketchup is a vegetable.
+%
+ WARNING TO ALL PERSONNEL:
+
+Firings will continue until morale improves.
+%
+ WARNING TO ALL PERSONNEL:
+
+Firings will continue until morale improves.
+%
+WARNING:
+ Reading this fortune can affect the dimensionality of your
+mind, change the curvature of your spine, cause the growth of hair on
+your palms, and make a difference in the outcome of your favorite war.
+%
+Warning: Listening to WXRT on April Fools' Day is not recommended for
+those who are slightly disoriented the first few hours after waking
+up.
+ -- Chicago Reader 4/22/83
+%
+Warp 7 -- It's a law we can live with.
+%
+Washington [D.C.] is a city of Southern efficiency and Northern charm.
+ -- John F. Kennedy
+%
+Waste not, get your budget cut next year.
+%
+Wasting time is an important part of living.
+%
+Watson's Law:
+ The reliability of machinery is inversely proportional to the
+number and significance of any persons watching it.
+%
+We are all agreed that your theory is crazy. The question which
+divides us is whether it is crazy enough to have a chance of being
+correct. My own feeling is that it is not crazy enough.
+ -- Niels Bohr
+%
+We are all in the gutter, but some of us are looking at the stars.
+ -- Oscar Wilde
+%
+We are all worms. But I do believe I am a glowworm.
+ -- Winston Churchill
+%
+We ARE as gods and might as well get good at it.
+ -- Whole Earth Catalog
+%
+We are confronted with insurmountable opportunities.
+ -- Walt Kelly, "Pogo"
+%
+We are going to give a little something, a few little years more, to
+socialism, because socialism is defunct. It dies all by itself. The
+bad thing is that socialism, being a victim of its ... Did I say
+socialism?
+ -- Fidel Castro
+%
+"We are on the verge: Today our program proved Fermat's next-to-last
+theorem."
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+"We are upping our standards ... so up yours."
+ -- Pat Paulsen for President, 1988.
+%
+We can defeat gravity. The problem is the paperwork involved.
+%
+We can predict everything, except the future.
+%
+We cannot put the face of a person on a stamp unless said person is
+deceased. My suggestion, therefore, is that you drop dead.
+ -- James E. Day, Postmaster General
+%
+"We demand rigidly defined areas of doubt and uncertainty!"
+ -- Vroomfondel
+%
+"We don't care. We don't have to. We're the Phone Company."
+%
+We don't know who discovered water, but we're certain it wasn't a
+fish.
+%
+We don't understand the software, and sometimes we don't understand the
+hardware, but we can *___see* the blinking lights!
+%
+We gave you an atomic bomb, what do you want, mermaids?
+ -- I. I. Rabi to the Atomic Energy Commission
+%
+"We had it tough ... I had to get up at 9 o'clock at night, half an
+hour before I went to bed, eat a lump of dry poison, work 29 hours down
+mill, and when we came home our Dad would kill us, and dance about on
+our grave singing Haleleuia ..."
+ -- Monty Python
+%
+We have met the enemy, and he is us.
+ -- Walt Kelly
+%
+We have only two things to worry about: That things will never get
+back to normal, and that they already have.
+%
+"We have reason to believe that man first walked upright to free his
+hands for masturbation."
+ -- Lily Tomlin
+%
+We have the flu. I don't know if this particular strain has an
+official name, but if it does, it must be something like "Martian Death
+Flu". You may have had it yourself. The main symptom is that you wish
+you had another setting on your electric blanket, up past "HIGH", that
+said "ELECTROCUTION".
+
+Another symptom is that you cease brushing your teeth, because (a) your
+teeth hurt, and (b) you lack the strength. Midway through the brushing
+process, you'd have to lie down in front of the sink to rest for a
+couple of hours, and rivulets of toothpaste foam would dribble sideways
+out of your mouth, eventually hardening into crusty little toothpaste
+stalagmites that would bond your head permanently to the bathroom
+floor, which is how the police would find you.
+
+You know the kind of flu I'm talking about.
+ -- Dave Barry, "Molecular Homicide"
+%
+We may hope that machines will eventually compete with men in all
+purely intellectual fields. But which are the best ones to start
+with? Many people think that a very abstract activity, like the
+playing of chess, would be best. It can also be maintained that it is
+best to provide the machine with the best sense organs that money can
+buy, and then teach it to understand and speak English.
+ -- Alan M. Turing
+%
+We may not return the affection of those who like us, but we always
+respect their good judgement.
+%
+We must remember the First Amendment which protects any shrill jackass
+no matter how self-seeking.
+ -- F. G. Withington
+%
+We ought to be very grateful that we have tools. Millions of years ago
+people did not have them, and home projects were extremely difficult.
+For example, when a primitive person wanted to put up paneling, he had
+to drive the little paneling nails into the cave wall with his bare
+fist, so generally the paneling wound up getting spattered with
+primitive blood, which isn't really all that bad when you consider how
+ugly paneling is to begin with.
+ -- Dave Barry, "The Taming of the Screw"
+%
+We really don't have any enemies. It's just that some of our best
+friends are trying to kill us.
+%
+ We were young and our happiness dazzled us with its strength.
+But there was also a terrible betrayal that lay within me like a Merle
+Haggard song at a French restaurant. ...
+ I could not tell the girl about the woman of the tollway, of
+her milk white BMW and her Jordache smile. There had been a fight. I
+had punched her boyfriend, who fought the mechanical bulls. Everyone
+told him, "You ride the bull, senor. You do not fight it." But he was
+lean and tough like a bad rib-eye and he fought the bull. And then he
+fought me. And when we finished there were no winners, just men doing
+what men must do. ...
+ "Stop the car," the girl said. There was a look of terrible
+sadness in her eyes. She knew about the woman of the tollway. I knew
+not how. I started to speak, but she raised an arm and spoke with a
+quiet and peace I will never forget.
+ "I do not ask for whom's the tollway belle," she said, "the
+tollway belle's for thee."
+ The next morning our youth was a memory, and our happiness was
+a lie. Life is like a bad margarita with good tequila, I thought as I
+poured whiskey onto my granola and faced a new day.
+ -- Peter Applebome, International Imitation Hemingway
+ Competition
+%
+We will have solar energy as soon as the utility companies solve one
+technical problem -- how to run a sunbeam through a meter.
+%
+we will invent new lullabies, new songs, new acts of love,
+we will cry over things we used to laugh &
+our new wisdom will bring tears to eyes of gentile
+creatures from other planets who were afraid of us till then &
+in the end a summer with wild winds &
+new friends will be.
+%
+We wish you a Hare Krishna
+We wish you a Hare Krishna
+We wish you a Hare Krishna
+And a Sun Myung Moon!
+ -- Maxwell Smart
+%
+"We'll cross out that bridge when we come back to it later."
+%
+We're deep into the holiday gift-giving season, as you can tell from
+the fact that everywhere you look, you see jolly old St. Nick urging
+you to purchase things, to the point where you want to slug him right
+in his bowl full of jelly.
+ -- Dave Barry, "Simple, Homespun Gifts"
+%
+We're only in it for the volume.
+ -- Black Sabbath
+%
+We've sent a man to the moon, and that's 29,000 miles away. The center
+of the Earth is only 4,000 miles away. You could drive that in a week,
+but for some reason nobody's ever done it.
+ -- Andy Rooney
+%
+Weiler's Law:
+ Nothing is impossible for the man who doesn't have to do it
+himself.
+%
+Weinberg's First Law:
+ Progress is made on alternate Fridays.
+%
+Weinberg's Principle:
+ An expert is a person who avoids the small errors while
+sweeping on to the grand fallacy.
+%
+Weinberg's Second Law:
+ If builders built buildings the way programmers wrote programs,
+then the first woodpecker that came along would destroy civilization.
+%
+Weiner's Law of Libraries:
+ There are no answers, only cross references.
+%
+Welcome thy neighbor into thy fallout shelter. He'll come in handy if
+you run out of food.
+ -- Dean McLaughlin.
+%
+Well, here it is, 1983, so it won't be long before you start reading a
+lot of boring stories about people like Vance Hartke. Hartke is a
+governor or mayor or something from one of the flatter states, and the
+reason you'll be reading about him is that he's one of the 50 top
+contenders for the 1984 Democratic presidential nomination. These men
+will spend the next 18 months going around the country engaging in the
+most degrading activities imaginable, such as wearing idiot hats and
+appearing on "Meet the Press". "Meet the Press" is one of those Sunday
+morning public interest shows that the public is not the least bit
+interested in. It features a panel of reporters who ask questions of a
+guest politician, who wins an Amana home freezer if he can get through
+the entire show without answering a single question ...
+ -- Dave Barry, "On Presidential Politics"
+%
+Well, I would -- if they realized that we -- again if -- if we led them
+back to that stalemate only because our retaliatory power, our seconds,
+or strike at them after our first strike, would be so destructive they
+they couldn't afford it, that would hold them off.
+ -- President Ronald Reagan, on the MX missile
+%
+"Well, if you can't believe what you read in a comic book, what *___can*
+you believe?!"
+ -- Bullwinkle J. Moose [Jay Ward]
+%
+Well, my terminal's locked up, and I ain't got any Mail,
+ And I can't recall the last time that my program didn't fail;
+I've got stacks in my structs, I've got arrays in my queues,
+ I've got the : Segmentation violation -- Core dumped blues.
+
+If you think that it's nice that you get what you C,
+ Then go : illogical statement with your whole family,
+'Cause the Supreme Court ain't the only place with : Bus error views.
+ I've got the : Segmentation violation -- Core dumped blues.
+
+On a PDP-11, life should be a breeze,
+ But with VAXen in the house even magnetic tapes would freeze.
+Now you might think that unlike VAXen I'd know who I abuse,
+ I've got the : Segmentation violation -- Core dumped blues.
+ -- Core Dumped Blues
+%
+"Well, that was a piece of cake, eh K-9?"
+
+"Piece of cake, Master? Radial slice of baked confection ...
+coefficient of relevance to Key of Time: zero."
+ -- Dr. Who
+%
+"Well," Brahma said, "even after ten thousand explanations, a fool is
+no wiser, but an intelligent man requires only two thousand five
+hundred."
+ -- The Mahabharata.
+%
+Westheimer's Discovery:
+ A couple of months in the laboratory can frequently save a
+couple of hours in the library.
+%
+Wethern's Law:
+ Assumption is the mother of all screw-ups.
+%
+"What are we going to do?"
+
+"Me, I'm examining the major Western religions. I'm looking for
+something that's soft on morality, generous with holidays, and has a
+short initiation period."
+%
+"What are you doing?"
+
+"Examining the world's major religions. I'm looking for something
+that's light on morals, has lots of holidays, and with a short
+initiation period."
+%
+What color is a chameleon on a mirror?
+%
+ "What do you give a man who has everything?" the pretty
+teenager asked her mother.
+ "Encouragement, dear," she replied.
+%
+What does "it" mean in the sentence "What time is it?"?
+%
+What does it mean if there is no fortune for you?
+%
+What garlic is to food, insanity is to art.
+%
+What garlic is to salad, insanity is to art.
+%
+"What George Washington did for us was to throw out the British, so
+that we wouldn't have a fat, insensitive government running our
+country. Nice try anyway, George."
+ -- D.J. on KSFO/KYA
+%
+What good is a ticket to the good life, if you can't find the
+entrance?
+%
+What good is having someone who can walk on water if you don't follow
+in his footsteps?
+%
+What I do, first thing [in the morning], is I hop into the shower
+stall. Then I hop right back out, because when I hopped in I landed
+barefoot right on top of See Threepio, a little plastic robot character
+from "Star Wars" whom my son, Robert, likes to pull the legs off of
+while he showers. Then I hop right back into the stall because our
+dog, Earnest, who has been alone in the basement all night building up
+powerful dog emotions, has come bounding and quivering into the
+bathroom and wants to greet me with 60 or 70 thousand playful nips, any
+one of which -- bear in mind that I am naked and, without my contact
+lenses, essentially blind -- could result in the kind of injury where
+you have to learn a whole new part if you want to sing the "Messiah",
+if you get my drift. Then I hop right back out, because Robert, with
+that uncanny sixth sense some children have -- you cannot teach it;
+they either have it or they don't -- has chosen exactly that moment to
+flush one of the toilets. Perhaps several of them.
+ -- Dave Barry, "Saving Face"
+%
+What I tell you three times is true.
+%
+"What I think is that the F-word is basically just a convenient nasty-
+sounding word that we tend to use when we would really like to come up
+with a terrifically witty insult, the kind Winston Churchill always
+came up with when enormous women asked him stupid questions at
+parties.
+ -- Dave Barry, "$#$%#^%!^%&@%@!"
+%
+What I want is all of the power and none of the responsibility.
+%
+"What I've done, of course, is total garbage."
+ -- R. Willard, Pure Math 430a
+%
+What if everything is an illusion and nothing exists? In that case, I
+definitely overpaid for my carpet.
+ -- Woody Allen, "Without Feathers"
+%
+What if nothing exists and we're all in somebody's dream? Or what's
+worse, what if only that fat guy in the third row exists?
+ -- Woody Allen, "Without Feathers"
+%
+What is a magician but a practising theorist?
+ -- Obi-Wan Kenobi
+%
+What is mind? No matter.
+What is matter? Never mind.
+ -- Thomas Hewitt Key, 1799-1875
+%
+What is the difference between a Turing machine and the modern
+computer? It's the same as that between Hillary's ascent of Everest
+and the establishment of a Hilton on its peak.
+%
+"What is the Nature of God?"
+
+ CLICK...CLICK...WHIRRR...CLICK...=BEEP!=
+ 1 QT. SOUR CREAM
+ 1 TSP. SAUERKRAUT
+ 1/2 CUT CHIVES.
+ STIR AND SPRINKLE WITH BACON BITS.
+
+"I've just GOT to start labeling my software..."
+ -- Bloom County
+%
+"What is the robbing of a bank compared to the FOUNDING of a bank?"
+ -- Bertold Brecht
+%
+"What is wanted is not the will to believe, but the will to find out,
+which is the exact opposite."
+ -- Bertrand Russell, "Skeptical_Essays", 1928
+%
+What is worth doing is worth the trouble of asking somebody to do.
+%
+What makes the universe so hard to comprehend is that there's nothing
+to compare it with.
+%
+What publishers are looking for these days isn't radical feminism.
+It's corporate feminism -- a brand of feminism designed to sell books
+and magazines, three-piece suits, airline tickets, Scotch, cigarettes
+and, most important, corporate America's message, which runs: "Yes,
+women were discriminated against in the past, but that unfortunate
+mistake has been remedied; now every woman can attain wealth, prestige
+and power by dint of individual rather than collective effort."
+ -- Susan Gordon
+%
+What sane person could live in this world and not be crazy?
+ -- Ursula K. LeGuin
+%
+What the hell, go ahead and put all your eggs in one basket.
+%
+What the large print giveth, the small print taketh away.
+%
+What the world *really* needs is a good Automatic Bicycle Sharpener.
+%
+What this country needs is a dime that will buy a good five-cent
+bagel.
+%
+What this country needs is a dime that will buy a good five-cent bagel.
+%
+What this country needs is a good five cent ANYTHING!
+%
+What this country needs is a good five cent microcomputer.
+%
+What this country needs is a good five cent nickel.
+%
+What this country needs is a good five dollar plasma weapon.
+%
+What this world needs is a good five-dollar plasma weapon.
+%
+What use is magic if it can't save a unicorn?
+ -- Peter S. Beagle, "The Last Unicorn"
+%
+What we need in this country, instead of Daylight Savings Time, which
+nobody really understands anyway, is a new concept called Weekday
+Morning Time, whereby at 7 a.m. every weekday we go into a space-
+launch-style "hold" for two to three hours, during which it just
+remains 7 a.m. This way we could all wake up via a civilized gradual
+process of stretching and belching and scratching, and it would still
+be only 7 a.m. when we were ready to actually emerge from bed.
+ -- Dave Barry, "$#$%#^%!^%&@%@!"
+%
+What you don't know can hurt you, only you won't know it.
+%
+"What's another word for Thesaurus?"
+ -- Steven Wright
+%
+ "What's that thing?"
+ "Well, it's a highly technical, sensitive instrument we use in
+computer repair. Being a layman, you probably can't grasp exactly what
+it does. We call it a two-by-four."
+ -- Jeff MacNelley, "Shoe"
+%
+"What's the use of a good quotation if you can't change it?"
+ -- Dr. Who
+%
+"What's the use of a good quotation if you can't change it?"
+ -- The Doctor
+%
+Whatever became of eternal truth?
+%
+Whatever became of Strange de Jim? Well, he found a substitute for
+cocaine: "You cover Q-tips with sandpaper and ram them up your nostrils
+as far as they will go. Then you sniff talcum powder while shredding
+hundred dollar bills."
+ -- Herb Caen
+%
+Whatever is not nailed down is mine. What I can pry loose is not
+nailed down.
+ -- Collis P. Huntingdon
+%
+"Whatever the missing mass of the universe is, I hope it's not
+cockroaches!"
+ -- Mom
+%
+When a Banker jumps out of a window, jump after him -- that's where the
+money is.
+ -- Robespierre
+%
+When a fellow says, "It ain't the money but the principle of the
+thing," it's the money.
+ -- Kim Hubbard
+%
+When a fly lands on the ceiling, does it do a half roll or a half
+loop?
+%
+When a place gets crowded enough to require ID's, social collapse is
+not far away. It is time to go elsewhere. The best thing about space
+travel is that it made it possible to go elsewhere.
+ -- Robert Heinlein
+%
+When a shepherd goes to kill a wolf, and takes his dog along to see the
+sport, he should take care to avoid mistakes. The dog has certain
+relationships to the wolf the shepherd may have forgotten.
+ -- Robert Pirsig, "Zen and the Art of Motorcycle
+ Maintenance"
+%
+When all other means of communication fail, try words.
+%
+"When are you BUTTHEADS gonna learn that you can't oppose Gestapo
+tactics *with* Gestapo tactics?"
+ -- Reuben Flagg
+%
+When asked by an anthropologist what the Indians called America before
+the white men came, an Indian said simply "Ours."
+ -- Vine Deloria, Jr.
+%
+When does summertime come to Minnesota, you ask? Well, last year, I
+think it was a Tuesday.
+%
+When God endowed human beings with brains, He did not intend to
+guarantee them.
+%
+"When I get real bored, I like to drive downtown and get a great
+parking spot, then sit in my car and count how many people ask me if
+I'm leaving."
+ -- Steven Wright
+%
+When I heated my home with oil, I used an average of 800 gallons a
+year. I have found that I can keep comfortably warm for an entire
+winter with slightly over half that quantity of beer.
+ -- Dave Barry, "Postpetroleum Guzzler"
+%
+When I said "we", officer, I was referring to myself, the four young
+ladies, and, of course, the goat.
+%
+When I was a boy I was told that anybody could become President. Now
+I'm beginning to believe it.
+ -- Clarence Darrow
+%
+When I was a kid I said to my father one afternoon, "Daddy, will you
+take me to the zoo?" He answered, "If the zoo wants you let them come
+and get you."
+ -- Jerry Lewis
+%
+"When I was crossing the border into Canada, they asked if I had any
+firearms with me. I said, `Well, what do you need?'"
+ -- Steven Wright
+%
+When I was in school, I cheated on my metaphysics exam: I looked into
+the soul of the boy sitting next to me.
+ -- Woody Allen
+%
+When I was seven years old, I was once reprimanded by my mother for an
+act of collective brutality in which I had been involved at school. A
+group of seven-year-olds had been teasing and tormenting a
+six-year-old. "It is always so," my mother said. "You do things
+together which not one of you would think of doing alone." ...
+Wherever one looks in the world of human organization, collective
+responsibility brings a lowering of moral standards. The military
+establishment is an extreme case, an organization which seems to have
+been expressly designed to make it possible for people to do things
+together which nobody in his right mind would do alone.
+ -- Freeman Dyson, "Weapons and Hope"
+%
+When I was younger, I could remember anything, whether it had happened
+or not; but my faculties are decaying now and soon I shall be so I
+cannot remember any but the things that never happened. It is sad to
+go to pieces like this but we all have to do it.
+ -- Mark Twain
+%
+When in doubt, do what the President does -- guess.
+%
+"When in doubt, tell the truth."
+ -- Mark Twain
+%
+When in doubt, use brute force.
+ -- Ken Thompson
+%
+When in panic, fear and doubt,
+Drink in barrels, eat, and shout.
+%
+When love is gone, there's always justice.
+And when justice is gone, there's always force.
+And when force is gone, there's always Mom.
+Hi, Mom!
+ -- Laurie Anderson
+%
+When Marriage is Outlawed,
+Only Outlaws will have Inlaws.
+%
+When more and more people are thrown out of work, unemployment
+results.
+ -- Calvin Coolidge
+%
+When one woman was asked how long she had been going to symphony
+concerts, she paused to calculate and replied, "Forty-seven years --
+and I find I mind it less and less."
+ -- Louise Andrews Kent
+%
+When properly administered, vacations do not diminish productivity:
+for every week you're away and get nothing done, there's another when
+your boss is away and you get twice as much done.
+ -- Daniel B. Luten
+%
+When someone says "I want a programming language in which I need only
+say what I wish done," give him a lollipop.
+%
+"When the going gets tough, the tough get empirical"
+ -- Jon Carroll
+%
+When the government bureau's remedies don't match your problem, you
+modify the problem, not the remedy.
+%
+When the Ngdanga tribe of West Africa hold their moon love ceremonies,
+the men of the tribe bang their heads on sacred trees until they get a
+nose bleed, which usually cures them of ____that.
+ -- Mike Harding, "The Armchair Anarchist's Almanac"
+%
+When the speaker and he to whom he is speaks do not understand, that is
+metaphysics.
+ -- Voltaire
+%
+When the Universe was not so out of whack as it is today, and all the
+stars were lined up in their proper places, you could easily count them
+from left to right, or top to bottom, and the larger and bluer ones
+were set apart, and the smaller yellowing types pushed off to the
+corners as bodies of a lower grade ...
+ -- Stanislaw Lem, "Cyberiad"
+%
+When the weight of the paperwork equals the weight of the plane, the
+plane will fly.
+ -- Donald Douglas
+%
+When two people are under the influence of the most violent, most
+insane, most delusive, and most transient of passions, they are
+required to swear that they will remain in that excited, abnormal, and
+exhausting condition continuously until death do them part.
+ -- George Bernard Shaw
+%
+When we are planning for posterity, we ought to remember that virtue is
+not hereditary.
+ -- Thomas Paine
+%
+When we understand knowledge-based systems, it will be as before --
+except our fingertips will have been singed.
+ -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
+%
+When you are about to do an objective and scientific piece of
+investigation of a topic, it is well to gave the answer firmly in hand,
+so that you can proceed forthrightly, without being deflected or
+swayed, directly to the goal.
+ -- Amrom Katz
+%
+"When you are in it up to your ears, keep your mouth shut."
+%
+When you don't know what you are doing, do it neatly.
+%
+When you have an efficient government, you have a dictatorship.
+ -- Harry Truman
+%
+ When you have shot and killed a man you have in some measure
+clarified your attitude toward him. You have given a definite answer
+to a definite problem. For better or worse you have acted decisively.
+ In a way, the next move is up to him.
+ -- R. A. Lafferty
+%
+"When you have to kill a man it costs nothing to be polite."
+ -- Winston Curchill, On formal declarations of war
+%
+When you know absolutely nothing about the topic, make your forecast by
+asking a carefully selected probability sample of 300 others who don't
+know the answer either.
+ -- Edgar R. Fiedler
+%
+When you make your mark in the world, watch out for guys with erasers.
+ -- The Wall Street Journal
+%
+When you try to make an impression, the chances are that is the
+impression you will make.
+%
+When you're away, I'm restless, lonely,
+Wretched, bored, dejected; only
+Here's the rub, my darling dear
+I feel the same when you are near.
+ -- Samuel Hoffenstein, "When You're Away"
+%
+When you're not looking at it, this fortune is written in FORTRAN.
+%
+Whenever anyone says, "theoretically", they really mean, "not really".
+ -- Dave Parnas
+%
+Whenever I hear anyone arguing for slavery, I feel a strong impulse to
+see it tried on him personally.
+ -- A. Lincoln
+%
+Whenever people agree with me I always feel I must be wrong.
+ -- Oscar Wilde
+%
+Whenever the literary German dives into a sentence, that is the last
+you are going to see of him until he emerges on the other side of his
+Atlantic with his verb in his mouth.
+ -- Mark Twain
+ "Connecticut Yankee in King Arthur's Court"
+%
+Whenever you find that you are on the side of the majority, it is time
+to reform.
+ -- Mark Twain
+%
+WHERE CAN THE MATTER BE
+
+ Oh, dear, where can the matter be
+ When it's converted to energy?
+ There is a slight loss of parity.
+ Johnny's so long at the fair.
+%
+Where humor is concerned there are no standards -- no one can say what
+is good or bad, although you can be sure that everyone will.
+ -- John Kenneth Galbraith
+%
+Where there's a will, there's an Inheritance Tax.
+%
+Whether you can hear it or not
+The Universe is laughing behind your back
+ -- National Lampoon, "Deteriorata"
+%
+Which is worse: ignorance or apathy? Who knows? Who cares?
+%
+While anyone can admit to themselves they were wrong, the true test is
+admission to someone else.
+%
+While Europe's eye is fix'd on mighty things,
+The fate of empires and the fall of kings;
+While quacks of State must each produce his plan,
+And even children lisp the Rights of Man;
+Amid this mighty fuss just let me mention,
+The Rights of Woman merit some attention.
+ -- Robert Burns, Address on "The Rights of Woman",
+ November 26, 1792
+%
+While having never invented a sin, I'm trying to perfect several.
+%
+While it may be true that a watched pot never boils, the one you don't
+keep an eye on can make an awful mess of your stove.
+ -- Edward Stevenson
+%
+While money can't buy happiness, it certainly lets you choose your own
+form of misery.
+%
+While money doesn't buy love, it puts you in a great bargaining
+position.
+%
+While most peoples' opinions change, the conviction of their
+correctness never does.
+%
+While you don't greatly need the outside world, it's still very
+reassuring to know that it's still there.
+%
+While your friend holds you affectionately by both your hands you are
+safe, for you can watch both of his.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Whistler's Law:
+ You never know who is right, but you always know who is in
+charge.
+%
+"Who cares if it doesn't do anything? It was made with our new
+Triple-Iso-Bifurcated-Krypton-Gate-MOS process ..."
+%
+Who made the world I cannot tell;
+'Tis made, and here am I in hell.
+My hand, though now my knuckles bleed,
+I never soiled with such a deed.
+ -- A. E. Housman
+%
+Who messed with my anti-paranoia shot?
+%
+Who needs friends when you can sit alone in your room and drink?
+%
+Who's on first?
+%
+"Whom are you?" said he, for he had been to night school.
+ -- George Ade
+%
+Whom computers would destroy, they must first drive mad.
+%
+Whom the gods wish to destroy they first call promising.
+%
+"Why are we importing all these highbrow plays like `Amadeus'? I could
+have told you Mozart was a jerk for nothing."
+ -- Ian Shoales
+%
+"Why be a man when you can be a success?"
+ -- Bertold Brecht
+%
+Why bother building any more nuclear warheads until we use the ones we
+have?
+%
+Why can't you be a non-conformist like everyone else?
+%
+Why did the Lord give us so much quickness of movement unless it was to
+avoid responsibility with?
+%
+Why did the Roman Empire collapse? What is the Latin for office
+automation?
+%
+Why do we have two eyes? To watch 3-D movies with.
+%
+Why does man kill? He kills for food. And not only food: frequently
+there must be a beverage.
+ -- Woody Allen, "Without Feathers"
+%
+Why does New Jersey have more toxic waste dumps and California have
+more lawyers?
+
+New Jersey had first choice.
+%
+Why don't elephants eat penguins ?
+
+Because they can't get the wrappers off ...
+%
+Why I Can't Go Out With You:
+
+I'd LOVE to, but ...
+ -- I have to floss my cat.
+ -- I've dedicated my life to linguini.
+ -- I need to spend more time with my blender.
+ -- it wouldn't be fair to the other Beautiful People.
+ -- it's my night to pet the dog/ferret/goldfish.
+ -- I'm going downtown to try on some gloves.
+ -- I have to check the freshness dates on my dairy products.
+ -- I'm going down to the bakery to watch the buns rise.
+ -- I have an appointment with a cuticle specialist.
+ -- I have some really hard words to look up.
+ -- I've got a Friends of the Lowly Rutabaga meeting.
+ -- I promised to help a friend fold road maps.
+%
+"Why is it that we rejoice at a birth and grieve at a funeral? It is
+because we are not the person involved"
+ -- Mark Twain
+%
+Why is the alphabet in that order? Is it because of that song?
+%
+"Why isn't there a special name for the tops of your feet?"
+ -- Lily Tomlin
+%
+"Why must you tell me all your secrets when it's hard enough to love
+you knowing nothing?"
+ -- Lloyd Cole and the Commotions
+%
+Why not have an old-fashioned Christmas for your family this year?
+Just picture the scene in your living room on Christmas morning as your
+children open their old-fashioned presents.
+
+Your 11-year-old son: "What the heck is this?"
+
+You: "A spinning top! You spin it around, and then eventually it
+ falls down. What fun! Ha, ha!"
+
+Son: "Is this a joke? Jason Thompson's parents got him a computer
+ with two disk drives and 128 kilobytes of random-access memory,
+ and I get this cretin TOP?"
+
+Your 8-year-old daughter: "You think that's bad? Look at this."
+
+You: "It's figgy pudding! What a treat!"
+
+Daughter: "It looks like goat barf."
+ -- Dave Barry, "Simple, Homespun Gifts"
+%
+"Why was I born with such contemporaries?"
+ -- Oscar Wilde
+%
+Why You Can't Run When There's Trouble in the Office:
+ No matter where you stand, no matter how far or fast you flee,
+when it hits the fan, as much as possible will be propelled in your
+direction, and almost none will be returned to the source.
+ -- John L. Shelton
+%
+Wiker's Law:
+ Government expands to absorb revenue and then some.
+%
+ William Safire's Rules for Writers:
+
+Remember to never split an infinitive. The passive voice should never
+be used. Do not put statements in the negative form. Verbs have to
+agree with their subjects. Proofread carefully to see if you words
+out. If you reread your work, you can find on rereading a great deal
+of repetition can be avoided by rereading and editing. A writer must
+not shift your point of view. And don't start a sentence with a
+conjunction. (Remember, too, a preposition is a terrible word to end a
+sentence with.) Don't overuse exclamation marks!! Place pronouns as
+close as possible, especially in long sentences, as of 10 or more
+words, to their antecedents. Writing carefully, dangling participles
+must be avoided. If any word is improper at the end of a sentence, a
+linking verb is. Take the bull by the hand and avoid mixing
+metaphors. Avoid trendy locutions that sound flaky. Everyone should
+be careful to use a singular pronoun with singular nouns in their
+writing. Always pick on the correct idiom. The adverb always follows
+the verb. Last but not least, avoid cliches like the plague; seek
+viable alternatives.
+%
+Williams and Holland's Law:
+ If enough data is collected, anything may be proven by
+statistical methods.
+%
+Winter is the season in which people try to keep the house as warm as
+it was in the summer, when they complained about the heat.
+%
+Wit, n.:
+ The salt with which the American Humorist spoils his cookery
+... by leaving it out.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+With a gentleman I try to be a gentleman and a half, and with a fraud I
+try to be a fraud and a half.
+ -- Otto von Bismark
+%
+With a rubber duck, one's never alone.
+ -- "The Hitchhiker's Guide to the Galaxy"
+%
+With all the fancy scientists in the world, why can't they just once
+build a nuclear balm?
+%
+With every passing hour our solar system comes forty-three thousand
+miles closer to globular cluster M13 in the constellation Hercules, and
+still there are some misfits who continue to insist that there is no
+such thing as progress.
+ -- Ransom K. Ferm
+%
+Without ice cream life and fame are meaningless.
+%
+Wombat's Laws of Computer Selection:
+ (1) If it doesn't run Unix, forget it.
+ (2) Any computer design over 10 years old is obsolete.
+ (3) Anything made by IBM is junk. (See number 2)
+ (4) The minimum acceptable CPU power for a single user is a
+ VAX/780 with a floating point accelerator.
+ (5) Any computer with a mouse is worthless.
+ -- Rich Kulawiec
+%
+Wood is highly ecological, since trees are a renewable resource. If
+you cut down a tree, another will grow in its place. And if you cut
+down the new tree, still another will grow. And if you cut down that
+tree, yet another will grow, only this one will be a mutation with
+long, poisonous tentacles and revenge in its heart, and it will sit
+there in the forest, cackling and making elaborate plans for when you
+come back.
+
+Wood heat is not new. It dates back to a day millions of years ago,
+when a group of cavemen were sitting around, watching dinosaurs rot.
+Suddenly, lightning struck a nearby log and set it on fire. One of the
+cavemen stared at the fire for a few minutes, then said: "Hey! Wood
+heat!" The other cavemen, who did not understand English, immediately
+beat him to death with stones. But the key discovery had been made,
+and from that day forward, the cavemen had all the heat they needed,
+although their insurance rates went way up.
+ -- Dave Barry, "Postpetroleum Guzzler"
+%
+Work Rule: Leave of Absence (for an Operation):
+ We are no longer allowing this practice. We wish to discourage
+any thoughts that you may not need all of whatever you have, and you
+should not consider having anything removed. We hired you as you are,
+and to have anything removed would certainly make you less than we
+bargained for.
+%
+Workers of the world, arise! You have nothing to lose but your
+chairs.
+%
+World War Three can be averted by adherence to a strictly enforced
+dress code!
+%
+Worst Month of 1981 for Downhill Skiing:
+ August. The lines are the shortest, though.
+ -- Steve Rubenstein
+%
+Worst Month of the Year:
+ February. February has only 28 days in it, which means that if
+you rent an apartment, you are paying for three full days you don't
+get. Try to avoid Februarys whenever possible.
+ -- Steve Rubenstein
+%
+Worst Response To A Crisis, 1985:
+ From a readers' Q and A column in TV GUIDE: "If we get involved
+in a nuclear war, would the electromagnetic pulses from exploding bombs
+damage my videotapes?"
+%
+Worst Vegetable of the Year:
+ The brussels sprout. This is also the worst vegetable of next
+year.
+ -- Steve Rubenstein
+%
+"Would you tell me, please, which way I ought to go from here?"
+
+"That depends a good deal on where you want to get to," said the Cat
+ -- Lewis Carrol
+%
+"Wouldn't the sentence 'I want to put a hyphen between the words Fish
+and And and And and Chips in my Fish-And-Chips sign' have been clearer
+if quotation marks had been placed before Fish, and between Fish and
+and, and and and And, and And and and, and and and And, and And and
+and, and and and Chips, as well as after Chips?"
+%
+Write-Protect Tab, n.:
+ A small sticker created to cover the unsightly notch carelessly
+left by disk manufacturers. The use of the tab creates an error
+message once in a while, but its aesthetic value far outweighs the
+momentary inconvenience.
+ -- Robb Russon
+%
+Writing about music is like dancing about architecture.
+ -- Frank Zappa
+%
+"Wrong," said Renner.
+
+"The tactful way," Rod said quietly, "the polite way to disagree with
+the Senator would be to say, `That turns out not to be the case.'"
+%
+X-rated movies are all alike ... the only thing they leave to the
+imagination is the plot.
+%
+Xerox does it again and again and again and ...
+%
+Xerox never comes up with anything original.
+%
+XIIdigitation, n.:
+ The practice of trying to determine the year a movie was made
+by deciphering the Roman numerals at the end of the credits.
+ -- Rich Hall, "Sniglets"
+%
+"Yacc" owes much to a most stimulating collection of users, who have
+goaded me beyond my inclination, and frequently beyond my ability in
+their endless search for "one more feature". Their irritating
+unwillingness to learn how to do things my way has usually led to my
+doing things their way; most of the time, they have been right.
+ -- S. C. Johnson, "Yacc guide acknowledgements"
+%
+Yea, though I walk through the valley of the shadow of APL, I shall
+fear no evil, for I can string six primitive monadic and dyadic
+operators together.
+ -- Steve Higgins
+%
+"Yeah, but you're taking the universe out of context."
+%
+Year, n.:
+ A period of three hundred and sixty-five disappointments.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Yes, but every time I try to see things your way, I get a headache.
+%
+Yes, but which self do you want to be?
+%
+Yesterday I was a dog. Today I'm a dog. Tomorrow I'll probably still
+be a dog. Sigh! There's so little hope for advancement.
+ -- Snoopy
+%
+Yesterday upon the stair
+I met a man who wasn't there.
+He wasn't there again today --
+I think he's from the CIA.
+%
+Yield to Temptation ... it may not pass your way again.
+ -- Lazarus Long, "Time Enough for Love"
+%
+Yinkel, n.:
+ A person who combs his hair over his bald spot, hoping no one
+will notice.
+ -- Rich Hall, "Sniglets"
+%
+You are a very redundant person, that's what kind of person you are.
+%
+You are here:
+ ***
+ ***
+ *********
+ *******
+ *****
+ ***
+ *
+
+ But you're not all there.
+%
+"You are old, Father William," the young man said,
+ "All your papers these days look the same;
+Those William's would be better unread --
+ Do these facts never fill you with shame?"
+
+"In my youth," Father William replied to his son,
+ "I wrote wonderful papers galore;
+But the great reputation I found that I'd won,
+ Made it pointless to think any more."
+%
+"You are old, father William," the young man said,
+ "And your hair has become very white;
+And yet you incessantly stand on your head --
+ Do you think, at your age, it is right?"
+
+"In my youth," father William replied to his son,
+ "I feared it might injure the brain;
+But, now that I'm perfectly sure I have none,
+ Why, I do it again and again."
+ -- Lewis Carrol
+%
+"You are old," said the youth, "and I'm told by my peers
+ That your lectures bore people to death.
+Yet you talk at one hundred conventions per year --
+ Don't you think that you should save your breath?"
+
+"I have answered three questions and that is enough,"
+ Said his father, "Don't give yourself airs!
+Do you think I can listen all day to such stuff?
+ Be off, or I'll kick you downstairs!"
+%
+"You are old," said the youth, "and your jaws are too weak
+ For anything tougher than suet;
+Yet you finished the goose, with the bones and the beak --
+ Pray, how did you manage to do it?"
+
+"In my youth," said his father, "I took to the law,
+ And argued each case with my wife;
+And the muscular strength which it gave to my jaw,
+ Has lasted the rest of my life."
+ -- Lewis Carrol
+%
+"You are old," said the youth, "and your programs don't run,
+ And there isn't one language you like;
+Yet of useful suggestions for help you have none --
+ Have you thought about taking a hike?"
+
+"Since I never write programs," his father replied,
+ "Every language looks equally bad;
+Yet the people keep paying to read all my books
+ And don't realize that they've been had."
+%
+"You are old," said the youth, "as I mentioned before,
+ And have grown most uncommonly fat;
+Yet you turned a back-somersault in at the door --
+ Pray what is the reason of that?"
+
+"In my youth," said the sage, as he shook his grey locks,
+ "I kept all my limbs very supple
+By the use of this ointment -- one shilling the box --
+ Allow me to sell you a couple?"
+ -- Lewis Carrol
+%
+"You are old," said the youth, "as I mentioned before,
+ And make errors few people could bear;
+You complain about everyone's English but yours --
+ Do you really think this is quite fair?"
+
+"I make lots of mistakes," Father William declared,
+ "But my stature these days is so great
+That no critic can hurt me -- I've got them all scared,
+ And to stop me it's now far too late."
+%
+"You are old," said the youth, "one would hardly suppose
+ That your eye was as steady as ever;
+Yet you balanced an eel on the end of your nose --
+ What made you so awfully clever?"
+
+"I have answered three questions, and that is enough,"
+ Said his father. "Don't give yourself airs!
+Do you think I can listen all day to such stuff?
+ Be off, or I'll kick you down stairs!"
+ -- Lewis Carrol
+%
+You are only young once, but you can stay immature indefinitely.
+%
+You are the only person to ever get this message.
+%
+You are wise, witty, and wonderful, but you spend too much time reading
+this sort of trash.
+%
+You buttered your bread, now lie in it.
+%
+You can always tell the Christmas season is here when you start getting
+incredibly dense, tinfoil-and-ribbon- wrapped lumps in the mail.
+Fruitcakes make ideal gifts because the Postal Service has been unable
+to find a way to damage them. They last forever, largely because
+nobody ever eats them. In fact, many smart people save the fruitcakes
+they receive and send them back to the original givers the next year;
+some fruitcakes have been passed back and forth for hundreds of years.
+
+The easiest way to make a fruitcake is to buy a darkish cake, then
+pound some old, hard fruit into it with a mallet. Be sure to wear
+safety glasses.
+ -- Dave Barry, "Simple, Homespun Gifts"
+%
+"You can bring any calculator you like to the midterm, as long as it
+doesn't dim the lights when you turn it on."
+ -- Hepler, Systems Design 182
+%
+You can create your own opportunities this week. Blackmail a senior
+executive.
+%
+"You can do this in a number of ways. IBM chose to do all of them.
+Why do you find that funny?"
+ -- D. Taylor, Computer Science 350
+%
+You can get more of what you want with a kind word and a gun than you
+can with just a kind word.
+ -- Bumper Sticker
+%
+You can learn many things from children. How much patience you have,
+for instance.
+ -- Franklin P. Jones
+%
+You can make it illegal, but you can't make it unpopular.
+%
+You can measure a programmer's perspective by noting his attitude on
+the continuing viability of FORTRAN.
+ -- Alan Perlis
+%
+You can only live once, but if you do it right, once is enough.
+%
+You can take all the impact that science considerations have on funding
+decisions at NASA, put them in the navel of a flea, and have room left
+over for a caraway seed and Tony Calio's heart.
+ -- F. Allen
+%
+You can tell how far we have to go, when FORTRAN is the language of
+supercomputers.
+ -- Steven Feiner
+%
+You can tune a piano, but you can't tuna fish.
+%
+"You can write a small letter to Grandma in the filename."
+ -- Forbes Burkowski, Computer Science 454
+%
+You can't carve your way to success without cutting remarks.
+%
+"You can't have everything. Where would you put it?"
+ -- Steven Wright
+%
+You can't hold a man down without staying down with him.
+ -- Booker T. Washington
+%
+You can't judge a book by the way it wears its hair.
+%
+"You can't make a program without broken egos."
+%
+You can't start worrying about what's going to happen. You get spastic
+enough worrying about what's happening now.
+ -- Lauren Bacall
+%
+"You can't survive by sucking the juice from a wet mitten."
+ -- Charles Schulz, "Things I've Had to Learn Over and
+ Over and Over"
+%
+"You can't teach people to be lazy - either they have it, or they
+don't."
+ -- Dagwood Bumstead
+%
+You cannot achieve the impossible without attempting the absurd.
+%
+You cannot kill time without injuring eternity.
+%
+You cannot propel yourself forward by patting yourself on the back.
+%
+You could get a new lease on life -- if only you didn't need the first
+and last month in advance.
+%
+You couldn't even prove the White House staff sane beyond a reasonable
+doubt.
+ -- Ed Meese, on the Hinckley verdict
+%
+You do not have mail.
+%
+You don't have to think too hard when you talk to teachers.
+ -- J. D. Salinger
+%
+You don't sew with a fork, so I see no reason to eat with knitting
+needles.
+ -- Miss Piggy, on eating Chinese Food
+%
+You first have to decide whether to use the short or the long form.
+The short form is what the Internal Revenue Service calls "simplified",
+which means it is designed for people who need the help of a Sears
+tax-preparation expert to distinguish between their first and last
+names. Here's the complete text:
+
+ "(1) How much did you make? (AMOUNT)
+ "(2) How much did we here at the government take out? (AMOUNT)
+ "(3) Hey! Sounds like we took too much! So we're going to
+ send an official government check for (ONE-FIFTEENTH OF
+ THE AMOUNT WE TOOK) directly to the (YOUR LAST NAME)
+ household at (YOUR ADDRESS), for you to spend in any way
+ you please! Which just goes to show you, (YOUR FIRST
+ NAME), that it pays to file the short form!"
+
+The IRS wants you to use this form because it gets to keep most of your
+money. So unless you have pond silt for brains, you want the long
+form.
+ -- Dave Barry, "Sweating Out Taxes"
+%
+You have a tendency to feel you are superior to most computers.
+%
+You have acquired a scroll entitled 'irk gleknow mizk'(n).--More--
+
+This is an IBM Manual scroll.--More--
+
+You are permanently confused.
+ -- Dave Decot
+%
+You have an unusual magnetic personality. Don't walk too close to
+metal objects which are not fastened down.
+%
+You have junk mail.
+%
+You have the body of a 19 year old. Please return it before it gets
+wrinkled.
+%
+You have the capacity to learn from mistakes. You'll learn a lot
+today.
+%
+You know it's going to be a bad day when you want to put on the clothes
+you wore home from the party and there aren't any.
+%
+You know the great thing about TV? If something important happens
+anywhere at all in the world, no matter what time of the day or night,
+you can always change the channel.
+ -- Jim Ignatowski
+%
+You know you have a small apartment when Rice Krispies echo.
+ -- S. Rickly Christian
+%
+You know you're a little fat if you have stretch marks on your car.
+ -- Cyrus, Chicago Reader 1/22/82
+%
+You know you've been spending too much time on the computer when your
+friend misdates a check, and you suggest adding a "++" to fix it.
+%
+You know you've landed gear-up when it takes full power to taxi.
+%
+ "You know, it's at times like this when I'm trapped in a Vogon
+airlock with a man from Betelgeuse and about to die of asphyxiation in
+deep space that I really wish I'd listened to what my mother told me
+when I was young!"
+ "Why, what did she tell you?"
+ "I don't know, I didn't listen!"
+ -- Douglas Adams, "Hitchhiker's Guide to the Galaxy"
+%
+You look like a million dollars. All green and wrinkled.
+%
+You may be recognized soon. Hide.
+%
+You may be sure that when a man begins to call himself a "realist," he
+is preparing to do something he is secretly ashamed of doing.
+ -- Sydney Harris
+%
+You may easily play a joke on a man who likes to argue -- agree with
+him.
+ -- Ed Howe
+%
+You may have heard that a dean is to faculty as a hydrant is to a dog.
+ -- Alfred Kahn
+%
+You men out there probably think you already know how to dress for
+success. You know, for example, that you should not wear leisure suits
+or white plastic belts and shoes, unless you are going to a costume
+party disguised as a pig farmer vacationing at Disney World.
+ -- Dave Barry, "How to Dress for Real Success"
+%
+You might have mail
+%
+"You must realize that the computer has it in for you. The irrefutable
+proof of this is that the computer always does what you tell it to do."
+%
+You need no longer worry about the future. This time tomorrow you'll
+be dead.
+%
+You need only reflect that one of the best ways to get yourself a
+reputation as a dangerous citizen these days is to go about repeating
+the very phrases which our founding fathers used in the struggle for
+independence.
+ -- Charles A. Beard
+%
+You never know how many friends you have until you rent a house on the
+beach.
+%
+You or I must yield up his life to Ahrimanes. I would rather it were
+you. I should have no hesitation in sacrificing my own life to spare
+yours, but we take stock next week, and it would not be fair on the
+company.
+ -- J. Wellington Wells
+%
+You possess a mind not merely twisted, but actually sprained.
+%
+You probably wouldn't worry about what people think of you if you could
+know how seldom they do.
+ -- Olin Miller.
+%
+You should emulate your heros, but don't carry it too far. Especially
+if they are dead.
+%
+You should never bet against anything in science at odds of more than
+about 10^12 to 1.
+ -- Ernest Rutherford
+%
+You should never wear your best trousers when you go out to fight for
+freedom and liberty.
+ -- Henrik Ibson
+%
+You should not use your fireplace, because scientists now believe that,
+contrary to popular opinion, fireplaces actually remove heat from
+houses. Really, that's what scientists believe. In fact many
+scientists actually use their fireplaces to cool their houses in the
+summer. If you visit a scientist's house on a sultry August day,
+you'll find a cheerful fire roaring on the hearth and the scientist
+sitting nearby, remarking on how cool he is and drinking heavily.
+ -- Dave Barry, "Postpetroleum Guzzler"
+%
+You should tip the waiter $10, minus $2 if he tells you his name,
+another $2 if he claims it will be His Pleasure to serve you and
+another $2 for each "special" he describes involving confusing terms
+such as "shallots," and $4 if the menu contains the word "fixin's." In
+many restaurants, this means the waiter will actually owe you money.
+If you are traveling with a child aged six months to three years, you
+should leave an additional amount equal to twice the bill to compensate
+for the fact that they will have to take the banquette out and burn it
+because the cracks are wedged solid with gobbets made of partially
+chewed former restaurant rolls saturated with baby spit.
+
+In New York, tip the taxicab driver $40 if he does not mention his
+hemorrhoids.
+ -- Dave Barry, "The Stuff of Etiquette"
+%
+"You should, without hesitation, pound your typewriter into a
+plowshare, your paper into fertilizer, and enter agriculture"
+ -- Business Professor, University of Georgia
+%
+You think Oedipus had a problem -- Adam was Eve's mother.
+%
+ YOU TOO CAN MAKE BIG MONEY IN THE EXCITING FIELD OF
+ PAPER SHUFFLING!
+
+Mr. TAA of Muddle, Mass. says: "Before I took this course I used to be
+a lowly bit twiddler. Now with what I learned at MIT Tech I feel
+really important and can obfuscate and confuse with the best."
+
+Mr. MARC had this to say: "Ten short days ago all I could look forward
+to was a dead-end job as a engineer. Now I have a promising future and
+make really big Zorkmids."
+
+MIT Tech can't promise these fantastic results to everyone, but when
+you earn your MDL degree from MIT Tech your future will be brighter.
+
+ SEND FOR OUR FREE BROCHURE TODAY!
+%
+You too can wear a nose mitten.
+%
+You will be a winner today. Pick a fight with a four-year-old.
+%
+You will be attacked by a beast who has the body of a wolf, the tail of
+a lion, and the face of Donald Duck.
+%
+You will be surprised by a loud noise.
+%
+You will be Told about it Tomorrow. Go Home and Prepare Thyself.
+%
+You will feel hungry again in another hour.
+%
+You will lose your present job and have to become a door to door
+mayonnaise salesman.
+%
+ You will remember, Watson, how the dreadful business of the
+Abernetty family was first brought to my notice by the depth which the
+parsley had sunk into the butter upon a hot day.
+ -- Sherlock Holmes
+%
+You will think of something funnier than this to add to the fortunes.
+%
+You worry too much about your job. Stop it. You're not paid enough to
+worry.
+%
+You'd better beat it. You can leave in a taxi. If you can't get a
+taxi, you can leave in a huff. If that's too soon, you can leave in a
+minute and a huff.
+ -- Groucho Marx
+%
+"You'll never be the man your mother was!"
+%
+You're at the end of the road again.
+%
+You're being followed. Cut out the hanky-panky for a few days.
+%
+You're never too old to become younger.
+ -- Mae West
+%
+You're not drunk if you can lie on the floor without holding on.
+ -- Dean Martin
+%
+You're not my type. For that matter, you're not even my species!!!
+%
+You've been leading a dog's life. Stay off the furniture.
+%
+"You've got to have a gimmick if your band sucks."
+ -- Gary Giddens
+%
+"You've got to think about tomorrow!"
+
+"TOMORROW! I haven't even prepared for *_________yesterday* yet!"
+%
+Your analyst has you mixed up with another patient. Don't believe a
+thing he tells you.
+%
+Your conscience never stops you from doing anything. It just stops you
+from enjoying it.
+%
+Your fault: core dumped
+%
+ Your home electrical system is basically a bunch of wires that
+bring electricity into your home and take if back out before it has a
+chance to kill you. This is called a "circuit". The most common home
+electrical problem is when the circuit is broken by a "circuit
+breaker"; this causes the electricity to back up in one of the wires
+until it bursts out of an outlet in the form of sparks, which can
+damage your carpet. The best way to avoid broken circuits is to change
+your fuses regularly.
+ Another common problem is that the lights flicker. This
+sometimes means that your electrical system is inadequate, but more
+often it means that your home is possessed by demons, in which case
+you'll need to get a caulking gun and some caulking. If you're not
+sure whether your house is possessed, see "The Amityville Horror", a
+fine documentary film based on an actual book. Or call in a licensed
+electrician, who is trained to spot the signs of demonic possession,
+such as blood coming down the stairs, enormous cats on the dinette
+table, etc.
+ -- Dave Barry, "The Taming of the Screw"
+%
+Your life would be very empty if you had nothing to regret.
+%
+Your lucky color has faded.
+%
+Your lucky number has been disconnected.
+%
+Your lucky number is 3552664958674928. Watch for it everywhere.
+%
+Your true value depends entirely on what you are compared with.
+%
+"Yow! Am I having fun yet?"
+ -- Zippy the Pinhead
+%
+YOW!! Everybody out of the GENETIC POOL!"
+%
+Zero Defects, n.:
+ The result of shutting down a production line.
+%
+Zounds! I was never so bethumped with words
+since I first called my brother's father dad.
+ -- William Shakespeare, "King John"
+%
+Zymurgy's Law of Volunteer Labor:
+ People are always available for work in the past tense.
diff --git a/fortune/datfiles/fortunes-o.fake.rot13 b/fortune/datfiles/fortunes-o.fake.rot13
new file mode 100644
index 00000000..bc7b70c3
--- /dev/null
+++ b/fortune/datfiles/fortunes-o.fake.rot13
@@ -0,0 +1,2 @@
+Gurer ner ab cbgragvnyyl bssrafvir sbegharf vafgnyyrq ba guvf
+flfgrz. Sbe shegure qrgnvyf, pbagnpg lbhe flfgrz nqzvavfgengbe.
diff --git a/fortune/datfiles/fortunes-o.real b/fortune/datfiles/fortunes-o.real
new file mode 100644
index 00000000..967766bf
--- /dev/null
+++ b/fortune/datfiles/fortunes-o.real
@@ -0,0 +1,2018 @@
+71:
+ 69 with two fingers up your ass.
+ -- George Carlin
+%
+A bather whose clothing was strewed
+By breezes that left her quite nude,
+ Saw a man come along
+ And, unless I'm quite wrong,
+You expected this line to be lewd.
+%
+A beat schizophrenic said, "Me?
+I am not I, I'm a tree."
+ But another, more sane,
+ Shouted, "I'm a Great Dane!"
+And covered his pants leg with pee.
+%
+A bureaucracy is like a septic tank -- all the really big shits float
+to the top.
+%
+A Christian is a man who feels repentance on Sunday for what he did on
+Saturday and is going to do on Monday.
+ -- Thomas Ybarra
+%
+A conservative is a man who believes that nothing should be done for
+the first time.
+ -- Alfred E. Wiggam
+%
+A conservative is a man with two perfectly good legs who has never
+learned to walk.
+ -- Franklin D. Roosevelt
+%
+A friend with weed is a friend indeed.
+%
+A hard man is good to find.
+%
+A man needs a mistress, just to break the monogamy.
+%
+A mathematician named Hall
+Has a hexahedronical ball,
+ And the cube of its weight
+ Times his pecker's, plus eight
+Is his phone number -- give him a call..
+%
+"A Mormon is a man that has the bad taste and the religion to do what a
+good many other people are restrained from doing by conscientious
+scruples and the police."
+ -- Mr. Dooley
+%
+A Nixon [is preferable to] a Dean Rusk -- who will be passionately
+wrong with a high sense of consistency.
+ -- J. K. Galbraith
+%
+A non-vegetarian anti-abortionist is a contradiction in terms.
+ -- Phyllis Schlafly
+%
+A nymph hits you and steals your virginity.
+%
+A person who has both feet planted firmly in the air can be safely
+called a liberal.
+%
+A pretty young lady named Vogel
+Once sat herself down on a molehill.
+ A curious mole
+ Nosed into her hole --
+Ms. Vogel's ok, but the mole's ill.
+%
+A pretty young maiden from France
+Decided she'd "just take a chance."
+ She let herself go
+ For an hour or so
+And now all her sisters are aunts.
+%
+A Puritan is someone who is deathly afraid that someone, somewhere, is
+having fun.
+%
+A reactionary is a man whose political opinions always manage to keep
+up with yesterday.
+%
+A remarkable race are the Persians;
+They have such peculiar diversions.
+ They make love the whole day
+ In the usual way
+And save up the nights for perversions.
+%
+A team playing baseball in Dallas
+Called the umpire blind out of malice.
+ While this worthy had fits
+ The team made eight hits
+And a girl in the bleachers named Alice.
+%
+A wanton young lady from Wimley
+Reproached for not acting quite primly
+ Said, "Heavens above!
+ I know sex isn't love,
+But it's such an entrancing facsimile."
+%
+A widow who fancied a man some
+Was diddled three times in a hansome.
+ When she clamored for more
+ Her young man became sore
+And exclaimed "My name's Simpson not Samson."
+%
+"A woman is like a dresser ... some man always goin' through her
+drawers."
+ -- Blind Lemon Pledge
+%
+A worried young man from Stamboul
+Founds lots of red spots on his tool.
+ Said the doctor, a cynic,
+ "Get out of my clinic;
+Just wipe off the lipstick, you fool!"
+%
+A.I. hackers do it with robots.
+%
+Absinthe makes the tart grow fonder.
+%
+"Acceptance without proof is the fundamental characteristic of Western
+religion, Rejection without proof is the fundamental characteristic of
+Western science."
+ -- Gary Zukav, "The Dancing Wu Li Masters"
+%
+Achilles' Biological Findings:
+ (1) If a child looks like his father, that's heredity. If he
+ looks like a neighbor, that's environment.
+ (2) A lot of time has been wasted arguing over what came first
+ -- the chicken or the egg. It was undoubtedly the
+ rooster.
+%
+Aide to Raygun: Sir, the poor are outside protesting your budget
+ cuts.
+Raygun himself: Tell them they'll have to help themselves.
+Aide to Raygun: Sir, the Pentagon wants another $30 billion.
+Raygun himself: Tell them to help themselves.
+%
+All a hacker needs is a tight PUSHJ, a loose pair of UUOs, and a warm
+place to shift.
+%
+All the waters of the earth are in the armpit of the Great Frog.
+ -- R. Crumb
+%
+All things dull and ugly, All creatures short and squat,
+ All things rude and nasty, The Lord God made the lot;
+Each little snake that poisons, Each little wasp that stings,
+ He made their brutish venom, He made their horrid wings.
+All things sick and cancerous, All evil great and small,
+ All things foul and dangerous, The Lord God made them all.
+Each nasty little hornet, Each beastly little squid.
+ Who made the spikey urchin? Who made the sharks? He did.
+All things scabbed and ulcerous, All pox both great and small.
+ Putrid, foul and gangrenous, The Lord God made them all.
+ -- Monty Python's Flying Circus
+%
+America is a large, friendly dog in a very small room. Every time it
+wags its tail, it knocks over a chair.
+ -- Arnold Joseph Toynbee
+%
+An architect fellow named Yoric
+Could, when feeling euphoric,
+ Display for selection
+ Three kinds of erection --
+Corinthian, ionic, and doric.
+%
+An Army travels on her stomach.
+%
+An egg has the shortest sex-life of all: if gets laid once; it gets
+eaten once. It also has to come in a box with 11 others, and the only
+person who will sit on its face is its mother.
+%
+"And Bezel saideth unto Sham: `Sham,' he saideth, `Thou shalt goest
+unto the town of Begorrah, and there thou shalt fetcheth unto thine
+bosom 35 talents, and also shalt thou fetcheth a like number of cubits,
+provideth that they are nice and fresh.'"
+ -- Dave Barry, "Getting Religion"
+%
+ And Jesus said unto them, "And whom do you say that I am?"
+ They replied, "You are the eschatological manifestation of the
+ground of our being, the ontological foundation of the context of our
+very selfhood revealed."
+ And Jesus replied, "What?"
+%
+... And then there's the guy who bought 20,000 bras, cut them in half,
+and sold 40,000 yamalchas with chin straps ...
+%
+Anxiety, n.:
+ The first time you can't do it a second time.
+
+Panic, n.:
+ The second time you can't do it the first time.
+%
+"Anything created must necessarily be inferior to the essence of the creator."
+ -- Claude Shouse
+
+"Einstein's mother must have been one heck of a physicist."
+ -- Joseph C. Wang
+%
+"Approximately 80% of our air pollution stems from hydrocarbons
+released by vegetation, so let's not go overboard in setting and
+enforcing tough emissions standards from man-made sources."
+ -- Ronald Reagan
+%
+Back in the good ole days in Texas, when stagecoaches and the like was
+popular, there were three people in a stagecoach one day: a true red-
+blooded born-and-raised Texas gentleman, a tenderfoot city-slicker from
+back East, and a beautiful and well-endowed Texas lady. The city-
+slicker kept eyeing the lady, and finally he leaned forward and said,
+"Lady, I'll give you $10 for a blow job." The Texas gentleman looked
+appalled, pulled out his pistol, and killed the city-slicker on the
+spot. The lady gasped and said, "Thank you, suh, for defendin' mah
+honor!" Whereupon the Texan holstered his gun and said, "Your honor,
+hell! No tenderfoot is gonna raise the price of women in Texas!"
+%
+Baltimore, n.:
+ Where the women wear turtleneck sweaters to hide their flea
+collars.
+%
+Bankers do it with interest (penalty for early withdrawal).
+%
+"Based on what you know about him in history books, what do you think
+Abraham Lincoln would be doing if he were alive today?
+
+ (1) Writing his memoirs of the Civil War.
+ (2) Advising the President.
+ (3) Desperately clawing at the inside of his coffin."
+ -- David Letterman
+%
+Be prepared... that's the Boy Scout's solemn creed.
+Be prepared... to be clean in word and deed.
+Don't solicit for your sister, that's not nice,
+Unless you get a good percentage of her price ...
+ -- Tom Lehrer
+%
+Behold the unborn fetus and
+ Weep salt tears crocodilian;
+All life is sacred (save, of course,
+ An enemy civilian).
+%
+Being stoned on marijuana isn't very different from being stoned on
+gin.
+ -- Ralph Nader
+%
+Beneath this stone a virgin lies,
+For her life held no terrors.
+A virgin born, a virgin died:
+No hits, no runs, no errors.
+%
+Beware of altruism. It is based on self-deception, the root of all
+evil.
+%
+Blessed are the meek for they shall inhibit the earth.
+%
+Booze is the answer. I don't remember the question.
+%
+Build a better mousetrap, the saying goes -- and with the brassiere,
+Yankee Ingenuity did exactly that. But their true stroke of genius was
+the new bait. The old fashioned mousetrap was loaded with cheese;
+nobody cares much about cheese, except mice. But when American
+Know-How reloaded the brassiere with tits, every heterosexual male in
+the country was hopelessly trapped.
+ -- Alan Sherman, "The Rape of the A*P*E*"
+%
+... But the reward of a successful collaboration is a thing that cannot
+be produced by either of the parties working alone. It is akin to the
+benefits of sex with a partner, as opposed to masturbation. The latter
+is fun, but you show me anyone who has gotten a baby from playing with
+him or herself, and I'll show you an ugly baby, with just a whole bunch
+of knuckles.
+ -- Harlan Ellison
+%
+"California is proud to be the home of the freeway."
+ -- Ronald Reagan
+%
+"Can you hammer a 6-inch spike into a wooden plank with your penis?"
+
+"Uh, not right now."
+
+"Tsk. A girl has to have some standards."
+ -- "Real Genius"
+%
+Captain Hook died of jock itch.
+%
+Champagne don't make me lazy.
+Cocaine don't drive me crazy.
+Ain't nobody's business but my own.
+ -- Taj Mahal
+%
+Chaste makes waste.
+%
+Chipmunks roasting on an open fire
+Jack Frost ripping up your nose
+Yuletide carolers being thrown in the fire
+And folks dressed up like buffaloes
+Everybody knows a turkey slaughtered in the snow
+Helps to make the season right
+Tiny tots with their eyes all gouged out
+Will find it hard to see tonight
+They know that Santa's on his way
+He's loaded lots of guns and bullets on his sleigh
+And every mother's child is sure to spy
+To see if reindeer really scream when they die
+And so I'm offering this simple phrase
+To kids from one to ninety two
+Although it's been said many times, many ways
+Merry Christmas, Merry Christmas, Merry Christmas, Fuck you!!
+%
+Christian, n.:
+ One who believes that the New Testament is a divinely inspired
+book admirably suited to the spiritual needs of his neighbor. One who
+follows the teachings of Christ in so far as they are not inconsistent
+with a life of sin.
+%
+Christianity has not been tried and found wanting; it has been found
+difficult and not tried.
+ -- G. K. Chesterton
+%
+Clarke's Third Law:
+ Any sufficiently advanced technology is indistinguishable from
+magic.
+
+G's Third Law:
+ In spite of all evidence to the contrary, the entire universe
+is composed of only two basic substances: magic and bullshit.
+
+H's Dictum:
+ There is no magic ...
+%
+Claude believed that only smart attractive people had the right to
+fuck, and it sincerely hurt him when he discovered evidence to the
+contrary.
+ -- Tom Robbins
+%
+CLONE OF MY OWN (to Home on the Range)
+
+Oh, give me a clone
+Of my own flesh and bone
+ With the Y chromosome changed to X.
+And when she is grown,
+My very own clone,
+ We'll be of the opposite sex.
+
+Chorus:
+ Clone, clone of my own,
+ With the Y chromosome changed to X.
+ And when we're alone,
+ Since her mind is my own,
+ She'll be thinking of nothing but sex.
+ -- Randall Garrett
+%
+Cocaine is nature's way of telling you you have too much money.
+%
+Coito ergo sum
+%
+College is like a woman -- you work so hard to get in, and nine months
+later you wish you'd never come.
+%
+Communists do it without class.
+%
+Condoms are like listening to a symphony with cotton in your ears.
+%
+Conservative, n.:
+ One who admires radicals centuries after they're dead.
+ -- Leo C. Rosten
+%
+Conserve energy -- make love more slowly.
+%
+Cunnilingus is next to godliness.
+%
+Dammit, how many times do I have to tell you? _____FIRST you rape, ____THEN you
+pillage!!
+%
+Dear Lord, observe this bended knee
+This visage meek and humble,
+And hear this confidential plea
+Voiced in reverent mumble:
+ Give me Shylock, give me Fagin
+ But O God spare me Ronald Reagan!
+ -- Ansel Adams
+%
+"Dear Mr. Seldes: I cannot remember the exact wording of the statement
+to which you allude; but what I meant was that ... a man who calls
+himself a 100% American and is proud of it, is generally 150% an idiot
+politically. But the designations may be good business for war
+veterans. Having bled for their country in 1861 and 1918, they have
+bled it all they could consequently. And why not?"
+ -- George Seldes, "The Great Quotations"
+%
+Democracy can learn some things from Communism: for example, when a
+Communist politician is through, he is through.
+%
+Democracy means simply the bludgeoning of the people by the people for
+the people.
+ -- Oscar Wilde
+%
+Did you hear about the new German microwave oven?
+
+ ... Seats 500.
+%
+Did you know that Spiro Agnew is an anagram of "Grow a Penis"
+%
+Did you know that there are 71.9 acres of nipple tissue in the U.S.?
+%
+[District Attorneys] learn in District Attorney School that there are
+two sure-fire ways to get a lot of favorable publicity:
+
+(1) Go down and raid all the lockers in the local high school and
+ confiscate 53 marijuana cigarettes and put them in a pile and hold
+ a press conference where you announce that they have a street value
+ of $850 million. These raids never fail, because ALL high schools,
+ including brand-new, never-used ones, have at least 53 marijuana
+ cigarettes in the lockers. As far as anyone can tell, the locker
+ factory puts them there.
+(2) Raid an "adult book store" and hold a press conference where you
+ announce you are charging the owner with 850 counts of being a
+ piece of human sleaze. This also never fails, because you always
+ get a conviction. A juror at a pornography trial is not about to
+ state for the record that he finds nothing obscene about a movie
+ where actors engage in sexual activities with live snakes and a
+ fire extinguisher. He is going to convict the bookstore owner, and
+ vote for the death penalty just to make sure nobody gets the wrong
+ impression.
+ -- Dave Barry, "Pornography"
+%
+Do something big -- fuck a giant
+%
+"Do you cheat on your wife?" asked the psychiatrist.
+"Who else?" answered the patient.
+%
+Doctors take two aspirin and do it in the morning.
+%
+"Don't let your mouth write no check that your tail can't cash."
+ -- Bo Diddley
+%
+Dope will get you through times of no money better that money will get
+you through times of no dope.
+ -- Gilbert Shelton
+%
+Draft beer, not people
+%
+Eat the rich -- the poor are tough and stringy.
+%
+Eisenhower was very nice,
+Nixon was his only vice.
+ -- C. Degen
+%
+Eleven reasons a cucumber is better than a man:
+ (1) Cucumbers can stay up all night, and you won't have to
+ sleep in the wet spot.
+ (2) Cucumbers don't play the guitar and try to find
+ themselves.
+ (3) You won't find out later that your cucumber (a) is
+ married, (b) is on penicillin, (c) likes you -- but loves
+ your brother!
+ (4) A cucumber won't care what time of the month it is.
+ (5) A cucumber never wants to get it on when your nails are
+ wet.
+ (6) Cucumbers don't say "Let's keep trying until we have a
+ boy".
+ (7) Cucumbers won't tell you size doesn't count.
+ (8) A cucumber won't leave you for a cheerleader or an ex-nun.
+ (9) Cucumbers don't fall asleep on your chest or drool on the
+ pillow.
+ (10) Cucumbers don't care if you make more money than they do.
+ (11) With a cucumber, the toilet seat is always the way you
+ left it.
+%
+Equality is not when a female Einstein gets promoted to assistant
+professor; equality is when a female schlemiel moves ahead as fast as a
+male schlemiel.
+ -- Ewald Nyquist
+%
+Evangelists do it with Him watching.
+%
+"Even nowadays a man can't step up and kill a woman without feeling
+just a bit unchivalrous ..."
+ -- Robert Benchley
+%
+Feminists say 60 percent of the country's wealth is in the hands of
+women. They're letting men hold the other 40 percent because their
+handbags are full.
+ -- Earl Wilson
+%
+Fie for shame, you lascivious, lewd, lecherous, libidinous, lustful,
+licentious, dirty bum!!
+%
+Floppy now, hard later.
+%
+For those of you how have been looking for evidence that a working
+version of "Star Wars" can be built, consider the following proof
+offered by Caspar Weinberger:
+
+ "If such a system is so unattainable, why have the Soviets been
+ working desperately to get it for over 17 years?"
+
+ -- USA Today, 24 June 1986
+%
+Fornication, n.:
+ Term used by people who don't have anybody to screw with.
+%
+Fortune's Real-Life Courtroom Quote #25:
+
+Q: You say you had three men punching at you, kicking you, raping you,
+ and you didn't scream?
+A: No ma'am.
+Q: Does that mean you consented?
+A: No, ma'am. That means I was unconscious.
+%
+George Washington not only chopped down his father's cherry tree, but
+he also admitted doing it. Now, do you know why his father didn't
+punish him? Because George still had the axe in his hand.
+%
+Getting an education at the University of California is like having
+$50.00 shoved up your ass, a nickel at a time.
+%
+"Go to Heaven for the climate, Hell for the company."
+ -- Mark Twain
+%
+ "God built a compelling sex drive into every creature, no
+matter what style of fucking it practiced. He made sex irresistibly
+pleasurable, wildly joyous, free from fears. He made it innocent
+merriment.
+ "Needless to say, fucking was an immediate smash hit. Everyone
+agreed, from aardvarks to zebras. All the jolly animals -- lions and
+lambs, rhinoceroses and gazelles, skylarks and lobsters, even insects,
+though most of them fuck only once in a lifetime -- fucked along
+innocently and merrily for hundreds of millions of years. Maybe they
+were dumb animals, but they knew a good thing when they had one."
+ -- Alan Sherman, "The Rape of the A*P*E*"
+%
+God gives us relatives; thank goodness we can chose our friends.
+%
+God is an atheist.
+%
+GOD is applied POWER
+ which is applied GOVERNMENT
+ which is applied POLITICS
+ which is applied ADVERTISING
+ which is applied SOCIOLOGY
+ which is applied PSYCHOLOGY
+ which is applied BIOLOGY
+ which is applied CHEMISTRY
+ which is applied PHYSICS
+ which is applied MATH
+ which is applied PHILOSOPHY
+ which is applied BULLSHIT
+%
+"God is as real as I am," the old man said. My faith was restored, for
+I new that Santa would never lie.
+%
+"God is big, so don't fuck with him."
+%
+God isn't dead -- he's been busted
+%
+God isn't dead, He's just trying to avoid the draft.
+%
+God must love assholes -- She made so many of them.
+%
+God wanted to have a holiday, so He asked St. Peter for suggestions on
+where to go.
+ "Why not go to Jupiter?" asked St. Peter.
+ "No, too much gravity, too much stomping around," said God.
+ "Well, how about Mercury?"
+ "No, it's too hot there."
+ "Okay," said St. Peter, "What about Earth?"
+ "No," said God, "They're such horrible gossips. When I was
+there 2000 years ago, I had an affair with a Jewish woman, and they're
+still talking about it."
+%
+Good day for water sports. Take a bath with a friend.
+%
+Grain grows best in shit
+ -- Ursula K. LeGuin
+%
+Gravity is an unforgiving motherfucker.
+%
+Great Lover, n.:
+ A man who can breathe through his ears.
+%
+Hackers do it with all sorts of characters.
+%
+Hackers do it with bugs.
+%
+Hackers do it with fewer instructions.
+%
+Hackers know all the right MOVs.
+%
+Haggis, n.:
+ Haggis is a kind of stuff black pudding eaten by the Scots and
+considered by them to be not only a delicacy but fit for human
+consumption. The minced heart, liver and lungs of a sheep, calf or
+other animal's inner organs are mixed with oatmeal, sealed and boiled
+in maw in the sheep's intestinal stomach-bag and ... Excuse me a minute ...
+%
+Hardly a pure science, history is closer to animal husbandry than it is
+to mathematics, in that it involves selective breeding. The principal
+difference between the husbandryman and the historian is that the
+former breeds sheep or cows or such, and the latter breeds (assumed)
+facts. The husbandryman uses his skills to enrich the future; the
+historian uses his to enrich the past. Both are usually up to their
+ankles in bullshit.
+ -- Tom Robbins
+%
+Having discovered the possibility that other creatures could be used
+for sexual intercourse, early man was likely to have made many such
+attempts ... though it is doubtful that he was so sexually carnivorous
+as the Christian and Jewish Adam, who, rabbinical interpreters of the
+Old Testament tell us, had intercourse with every creature before God
+finally hit upon the idea of woman and created Eve.
+ -- R. E. Masters
+%
+"He could be a poster child for retroactive birth control."
+%
+He hated to mend, so young Ned
+Called in a cute neighbor instead.
+ Her husband said, "Vi,
+ When you stitched up his torn fly,
+Did you have to bite off the thread?"
+%
+He wasn't much of an actor, he wasn't much of a Governor -- Hell, they
+_H_A_D to make him President of the United States. It's the only job he's
+qualified for!
+ -- Michael Cain
+%
+He who findeth sensuous pleasures in the bodies of lush, hot, pink
+damsels is not righteous, but he can have a lot more fun.
+%
+He who sneezes without a handkerchief takes matters into his own
+hands.
+%
+"He's not pining, he's passed on! This parrot won't squawk! He's
+ceased to be! He's expired, and gone to meet his maker! It's a
+stiff! No breath of life, he may rest in peace! If you hadn't nailed
+him to the perch, he'd be pushing up the daisies! He's off the twig!
+He's kicked the bucket! He's curled up his tooties! He's shuffled off
+this mortal world! He's run down the curtain, and joined the bleed'n
+Choir Invincible! HE'S FUCKING SNUFFED IT! Vis-a-vi his metabolic
+processes is head is lost. All statements concerning this parrot is no
+longer a going concern, after from now on, Inoperative...
+
+ THIS IS AN EX-PARROT!!
+%
+Her figure described a set of parabolas that could cause cardiac arrest
+in a yak.
+ -- Woody Allen
+%
+Her kisses left something to be desired -- the rest of her.
+%
+Here is the problem: for many years, the Supreme Court wrestled with
+the issue of pornography, until finally Associate Justice John Paul
+Stevens came up with the famous quotation about how he couldn't define
+pornography, but he knew it when he saw it. So for a while, the
+court's policy was to have all the suspected pornography trucked to
+Justice Stevens' house, where he would look it over. "Nope, this isn't
+it," he'd say. "Bring some more." This went on until one morning when
+his housekeeper found him trapped in the recreation room under an
+enormous mound of rubberized implements, and the court had to issue a
+ruling stating that it didn't know what the hell pornography was except
+that it was illegal and everybody should stop badgering the court about
+it because the court was going to take a nap.
+ -- Dave Barry, "Pornography"
+%
+"Here's the holiday schedule for Monday's observation of Martin Luther
+King Jr.'s birthday, when the following will be closed:
+
+ * Governmental offices
+ * Post offices
+ * Libraries
+ * Schools
+ * Banks
+ * Parts of Palm Beach
+
+and the mind of Senator Jesse Helms of North Carolina."
+ -- Dennis Miller, "Saturday Night Live"
+%
+History has the relation to truth that theology has to religion --
+i.e., none to speak of.
+ -- Lazarus Long
+%
+"How do you like the new America? We've cut the fat out of the
+government, and more recently the heart and brain (the backbone was
+gone some time ago). All we seem to have left now is muscle. We'll be
+lucky to escape with our skins!"
+%
+Howard Cosell's biggest protrusion is his asshole
+ -- John Valby
+%
+Hugh Hefner is a virgin.
+%
+I am an atheist, thank God!
+%
+I believe that Ronald Reagan will someday make this country what it
+once was ... an arctic wilderness
+ -- Steve Martin
+%
+I came; I saw; I fucked up
+%
+I have a funny daddy
+Who goes in and out with me
+And everything that baby does
+Daddy's sure to see,
+And everything that baby says,
+My daddy's sure to tell.
+You _m_u_s_t have read my daddy's verse.
+I hope he fries in Hell.
+ -- Ogden Nash
+%
+I love this fucking University, and this University loves fucking me.
+%
+I once met a lassie named Ruth
+In a long distance telephone booth.
+ Now I know the perfection
+ Of an ideal connection
+Even if somewhat uncouth.
+%
+"I own my own body, but I share"
+%
+I realize that today you have a number of top female athletes such as
+Martina Navratilova who can run like deer and bench-press Chevrolet
+trucks. But to be brutally frank, women as a group have a long way to
+go before they reach the level of intensity and dedication to sports
+that enables men to be such incredible jerks about it.
+ -- Dave Barry, "Sports is a Drag"
+%
+I regret to say that we of the F.B.I. are powerless to act in cases of
+oral-genital intimacy, unless it has in some way obstructed interstate
+commerce.
+ -- J. Edgar Hoover
+%
+I think every good Christian ought to kick Falwell right in the ass.
+ -- Barry Goldwater
+%
+I think pop music has done more for oral intercourse than anything else
+that has ever happened, and vice versa.
+ -- Frank Zappa
+%
+I walked on toward Ploughwright, thinking about feces. What a lot we
+had found out about the prehistoric past from the study of fossilized
+dung of long-vanished animals. A miraculous thing, really; a recovery
+from the past from what was carelessly rejected. And in the Middle
+Ages, how concerned people who lived close to the world of nature were
+with the feces of animals. And what a variety of names they had for
+them: the Crotels of a Hare, the Friants of a Boar, the Spraints of
+an Otter, the Werderobe of a Badger, the Waggying of a Fox, the Fumets
+of a Deer. Surely there might be some words for the material so near
+to the heart of Ozy Froats [an academic studying feces] than shit?
+What about the Problems of a President, the Backward Passes of a
+Footballer, the Deferrals of a Dean, the Odd Volumes of a Librarian,
+the Footnotes of a Ph.D., the Low Grades of a Freshman, the Anxieties
+of an Untenured Professor?
+ -- Robertson Davies, "The Rebel Angels"
+%
+I would like to suggest that you not use speed, and here's why: it is
+going to mess up your heart, mess up your liver, your kidneys, rot out
+your mind. In general this drug will make you just like your mother
+and father.
+ -- Frank Zappa
+%
+I wouldn't mind dying -- it's that business of having to stay dead that
+scares the shit out of me.
+ -- R. Geis
+%
+I'd like to meet the man who invented sex and see what he's working on
+now.
+%
+I'm for peace -- I've yet to see a man wake up in the morning and say
+"I've just had a good war."
+ -- Mae West
+%
+I'm going to Iowa for an award. Then I'm appearing at Carnegie Hall,
+it's sold out. Then I'm sailing to France to be honored by the French
+government -- I'd give it all up for one erection.
+ -- Groucho Marx
+%
+"I've had one child. My husband wants to have another. I'd like to
+watch him have another."
+%
+If a child annoys you, quiet him by brushing his hair. If this doesn't
+work, use the other side of the brush on the other end of the child.
+%
+If all these sweet young things were laid end-to-end, I wouldn't be a
+bit surprised.
+ -- Dorothy Parker
+%
+"If anyone wants to trade a couple of centrally located, well-cushioned
+showgirls for an eroded slope 90 minutes from Broadway, I'll be on this
+corner tomorrow at 11 with my tongue hanging out."
+ -- S. J. Perelman
+%
+If clear thinking created sparks, we could safely store dynamite in
+James Watt's office.
+ -- Wayne Shannon, KRON-TV
+%
+"If God had wanted us to use the metric system, Jesus would have had 10
+apostles."
+%
+If guns are outlawed, how will we shoot the liberals?
+%
+If Helen Keller is alone in a forest and falls, does she make a sound?
+%
+If men could get pregnant, abortion would be a sacrament.
+%
+If Reagan is the answer, it must have been a VERY silly question.
+%
+If someone were to ask me for a short cut to sensuality, I would
+suggest he go shopping for a used 427 Shelby-Cobra. But it is only
+fair to warn you that of the 300 guys who switched to them in 1966,
+only two went back to women.
+ -- Mort Sahl
+%
+If the American dream is for Americans only, it will remain our dream
+and never be our destiny.
+ -- Ren'e de Visme Williamson
+%
+If you can believe ten impossible things before breakfast, then you
+should join
+
+ THE CHURCH OF COUNTERFACTUAL BELIEF
+
+The Church of Counterfactual Belief has been set up to cater to all who
+don't allow demonstrable truth to get in the way of their beliefs. In
+addition to creation science and the flatness of the earth, the
+following beliefs have been certified by Pope Duane as Church dogma:
+
+ -- That there is a hole in the Earth at the North Pole from which
+ UFOs come.
+ -- That pi equals precisely 3.000.
+ -- That sex can be enjoyed only by blacks and homosexuals.
+ -- That Billy Joe Wilson (Hoopla, Miss.) has successfully squared
+ the circle.
+ -- That Harry Truman is still president, and doing a fine job.
+ -- That pi equals precisely 22/7.
+
+Several other important counterfactual beliefs are presently being
+studied, including Reaganomics, A.I., and that the moon landings were
+done in a Hollywood special effects studio. These will be the subject
+of a forthcoming Papal Bull ...
+%
+If you meet somebody who tells you that he loves you more than anybody
+in the whole wide world, don't trust him. It means he experiments.
+%
+If you think sex is a pain in the ass, try different position.
+%
+"If you're a real good kid, I'll give you a piggy-back ride on a
+buzz-saw."
+ -- W. C. Fields
+%
+Ignorance is the Mother of Devotion.
+ -- Robert Burton
+%
+"In Christianity neither morality nor religion come into contact with
+reality at any point."
+ -- Friedrich Nietzsche
+%
+ In the beginning was the DEMO Project. And the Project was
+without form. And darkness was upon the staff members thereof. So
+they spake unto their Division Head, saying, "It is a crock of shit,
+and it stinks."
+
+ And the Division Head spake unto his Department Head, saying,
+"It is a crock of excrement and none may abide the odor thereof." Now,
+the Department Head spake unto his Directorate Head, saying, "It is a
+container of excrement, and is very strong, such that none may abide
+before it." And it came to pass that the Directorate Head spake unto
+the Assistant Technical Director, saying, "It is a vessel of fertilizer
+and none may abide by its strength."
+
+ And the assistant Technical Director spake thus unto the
+Technical Director, saying, "It containeth that which aids growth and
+it is very strong." And, Lo, the Technical Director spake then unto
+the Captain, saying, "The powerful new Project will help promote the
+growth of the Laboratories."
+
+ And the Captain looked down upon the Project, and He saw that
+it was Good!
+%
+In the Garden of Eden sat Adam,
+Massaging the bust of his madam,
+ He chuckled with mirth,
+ For he knew that on earth,
+There were only two boobs and he had 'em.
+%
+Incest, n.:
+ Sibling revelry.
+%
+"Is it just me, or does anyone else read `bible humpers' every time
+someone writes `bible thumpers?'
+ -- Joel M. Snyder, jms@mis.arizona.edu
+%
+It is a sad commentary on today's society that this fortune has to be
+classified as "offensive" simply because it contains the word "fuck".
+%
+"It says he made us all to be just like him. So if we're dumb, then
+god is dumb, and maybe even a little ugly on the side."
+ -- Frank Zappa
+%
+"It was a Roman who said it was sweet to die for one's country. The
+Greeks never said it was sweet to die for anything. They had no vital
+lies."
+ -- Edith Hamilton, "The Greek Way"
+%
+Jesus died for your sins. Make it worth his time.
+%
+"Jesus saves...but Gretzky gets the rebound!"
+ -- Daniel Hinojosa
+%
+Jesus was killed by a Moral Majority.
+%
+John Birch Society -- that pathetic manifestation of organized
+apoplexy.
+ -- Edward P. Morgan
+%
+Kasha, n.:
+ Kasha is always defined as "buckwheat groats". There's only
+one problem with this definition: what the fuck are "buckwheat
+groats"? *_I* know what they are -- they're kasha. But that doesn't
+help *___you* much.
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
+%
+Kill a commie for Christ!
+%
+Laissez Faire Economics is the theory that if each acts like a vulture,
+all will end as doves.
+%
+Large cats can be dangerous, but a little pussy never hurt anyone.
+%
+LET Jesus be YOUR anchor!
+
+So when Satan rocks your boat, THROW Jesus overboard!
+%
+... Let me tell you who the actual "front-runners" are. On one side,
+you have George Bush, who is currently going through a sort of
+fraternity hazing wherein he has to perform a series of humiliating
+stunts to win the approval of the Republican Right. For example, they
+had him make a speech oozing praise all over William Loeb, deceased
+publisher of the Manchester (N.H.) Union Leader and Slime Journalist.
+Loeb had dumped viciously all over George in the 1980 New Hampshire
+primary. But when the Right held a big tribute for Loeb, George came
+back to the fold, like a man with a bungee cord wrapped around his
+neck.
+ -- Dave Barry, "The Twinkie and the Squid"
+%
+Life is like a penis: when it's soft you can't beat it, and when it's
+hard you get fucked.
+%
+Lisp hackers have to be bound (to-do 'it) ...
+%
+Living in Hollywood is like living in a bowl of granola. What ain't
+fruits and nuts is flakes.
+%
+Love does not make the world go around, just up and down a bit.
+%
+Mathematicians do it in theory.
+%
+Mathematicians take it to the limit.
+%
+May a diseased yak take a liking to your sister.
+%
+May the fairy god-camel leave a lump on your pillow!
+%
+Mayor Vincent J. `Buddy' Cianci on the ACLU's suit to have a city
+nativity scene removed:
+ "They're just jealous because they don't have three wise men
+and a virgin in the whole organization."
+%
+Megaton Man: "LOOK at them! Helpless, tender creatures, relying on
+ ME, waiting for ME to make my move!"
+
+(from below): "Move your ASS, Fat-head!"
+
+Megaton Man: "It is a MANDATE, and I am DUTY BOUND to OBEY!"
+%
+Missionary Position:
+ The missionary on top.
+%
+"Most legislators are so dumb that they couldn't pour piss out of a
+boot if the instructions were printed on the heel."
+%
+Motto of the Electrical Engineer:
+ Working computer hardware is a lot like an erect penis: it
+stays up as long as you don't fuck with it.
+%
+My brother-in-law has found a way to make ends meet. He goes around
+with his head stuck up his ass.
+%
+"My country, right or wrong," is a thing that no patriot would think of
+saying except in a desperate case. It is like saying, "My mother,
+drunk or sober."
+ -- G. K. Chesterton
+%
+My father was a creole, his father a Negro, and his father a monkey; my
+family, it seems, begins where yours left off.
+ -- Alexandre Dumas, pere
+%
+ My Favorite Drugs [Sung to My Favorite Things]
+Reefers and roach clips and papers and rollers
+Cocaine and procaine for twenty year molars
+Reds and peyote to work out your bugs
+These are a few of my favorite drugs.
+
+Uppers and downers and methedrine freakout
+Take some amphetamines, watch your brains leak out
+Acid and mescaline pull out your plugs
+These are a few of my favorite drugs.
+
+Backs that are perfect for carrying monkeys
+Users of heroin, often called junkies
+Methadone helps then to stop being thugs
+Takes them off one of my favorite drugs.
+
+ On a bad trip
+ When the cops come
+ When I lose my head
+ I simply take more of my favorite drugs
+ And then I'm not sad -- I'm dead!
+%
+ NEW ADDITION TO THE LIBRARY:
+"Sally", the department's new inflatable doll, is available on a
+short-term removal basis only -- please sign her out and return her
+promptly to avoid extended waits. (We are still awaiting shipment of
+our "Big John" doll.)
+%
+No woman can call herself free until she can choose consciously whether
+she will or will not be a mother.
+ -- Margaret H. Sanger
+%
+"Not only is God dead, but just try to find a plumber on weekends."
+ -- Woody Allen
+%
+Nothing is better than Sex.
+Masturbation is better than nothing.
+Therefore, Masturbation is better than Sex.
+%
+Nuke the gay, unborn, baby whales for Jesus.
+%
+O'Riordan's Theorem:
+ Brains x Beauty = Constant.
+
+Purmal's Corollary:
+ As the limit of (Brains x Beauty) goes to infinity,
+availability goes to zero.
+%
+Obscenity is the crutch of inarticulate motherfuckers.
+%
+Occident, n.:
+ The part of the world lying west (or east) of the Orient. It
+is largely inhabited by Christians, powerful sub-tribe of the
+Hypocrites, whose principal industries are murder and cheating, which
+they are pleased to call "war" and "commerce." These, also, are the
+principal industries of the Orient.
+ -- Ambrose Bierce, "The Devil's Dictionary"
+%
+Ocean, n.:
+ A body of water occupying about two-thirds of a world made for
+man -- who has no gills.
+%
+Once a young gay from Khartoum
+Took a lesbian up to his room.
+ They argued all night
+ Over who had the right
+To do what, and with which, and to whom.
+%
+Once upon a time, there was a non-conforming sparrow who decided not to
+fly south for the winter. However, soon after the weather turned cold,
+the sparrow changed his mind and reluctantly started to fly south.
+After a short time, ice began to form his on his wings and he fell to
+earth in a barnyard almost frozen. A cow passed by and crapped on this
+little bird and the sparrow thought it was the end, but the manure
+warmed him and defrosted his wings. Warm and happy the little sparrow
+began to sing. Just then, a large Tom cat came by and hearing the
+chirping investigated the sounds. As Old Tom cleared away the manure,
+he found the chirping bird and promptly ate him.
+
+There are three morals to this story:
+
+(1) Everyone who shits on you is not necessarily your enemy.
+(2) Everyone who gets you out of shit is not necessarily your friend.
+(3) If you are warm and happy in a pile of shit, keep your mouth shut.
+%
+One day President Reagan, Chairman Andropov, the Pope, and a boy scout
+were flying together in an airplane. Right out in the middle of
+nowhere the plane developed engine trouble and started to go down.
+Unfortunately, only three parachutes could be found for the four
+passengers! Andropov grabbed one of the parachutes and declared
+"Comrades, as leader of the socialist workers revolution, my life must
+be spared," and he jumped out of the plane. Then Reagan exclaimed "As
+leader of the greatest nation on earth, I must keep the world safe for
+democracy," and with that he too jumped to safety. Now if you are
+following all this (or counting on your fingers) you must see that
+there is only one parachute left for the two remaining passengers. The
+Pope looked kindly upon the boy scout and said "I have had a long and
+productive life, my son. You take the parachute and leave me in God's
+hands." "That's very kind of you," the observant scout replied, "but
+there is no need. Reagan just jumped out with my knapsack."
+%
+"One Saturday afternoon, during the campaign to decide whether or not
+there should be a Coastal Commission, I took a helicopter ride from Los
+Angeles to San Diego. We passed several state beaches, some crowded
+and some virtually empty. They had the same facilities, and in some
+cases the crowded and the empty beach were within a quarter mile of
+each other. Obviously many beach-goers prefer to be crowded together.
+Buying more beaches that people won't go to because they prefer to be
+crowded together on one beach is a ridiculous waste of our natural
+resources and our taxes."
+ -- Ronald Reagan
+%
+One thing I have no worry about is whether God exists. But it has
+occurred to me that God has Alzheimer's and has forgotten we exist.
+ -- Jane Wagner, "The Search for Signs of Intelligent
+ Life in the Universe"
+%
+Opinions are like assholes -- everyone's got one, but nobody wants to
+look at the other guy's.
+ -- Hal Hickman
+%
+Our [softball] team usually puts the other woman at second base, where
+the maximum possible number of males can get there on short notice to
+help out in case of emergency. As far as I can tell, our second
+basewoman is a pretty good baseball player, better than I am, anyway,
+but there's no way to know for sure because if the ball gets anywhere
+near her, a male comes barging over from, say, right field, to deal
+with it. She's been on the team for three seasons now, but the males
+still don't trust her. They know, deep in their souls, that if she had
+to choose between catching a fly ball and saving an infant's life, she
+probably would elect to save the infant's life, without ever
+considering whether there were men on base.
+ -- Dave Barry, "Sports is a Drag"
+%
+"Our government has kept us in a perpetual state of fear -- kept us in
+a continuous stampede of patriotic fervor -- with the cry of grave
+national emergency... Always there has been some terrible evil to
+gobble us up if we did not blindly rally behind it by furnishing the
+exorbitant sums demanded. Yet, in retrospect, these disasters seem
+never to have happened, seem never to have been quite real."
+ -- General Douglas MacArthur, 1957
+%
+ Overheard in a bar:
+Man: "Hey, Baby, I'd sure like to get in your pants!"
+Woman: "No, thanks, I've already got one ass-hole in there now."
+%
+People who develop the habit of thinking of themselves as world
+citizens are fulfilling the first requirement of sanity in our time.
+ -- Norman Cousins
+%
+Physicists do it with charm
+%
+Politicians do it to everyone.
+%
+Posterity will ne'er survey
+A nobler grave than this;
+Here lie the bones of Castlereagh;
+Stop, traveler, and piss.
+ -- Lord Byron, on Lord Castlereagh
+%
+Procrastinators do it tomorrow.
+%
+Prostitution is the only business where you can go into the hole and
+still come out ahead.
+%
+Q: How do you play religious roulette?
+A: You stand around in a circle and blaspheme and see who gets struck
+ by lightning first.
+%
+Q: How do you tell if an Elephant has been making love in your
+ backyard?
+A: If all your trashcan liners are missing ...
+%
+Q: How do you tell if you're making love to a nurse, a schoolteacher,
+ or an airline stewardess?
+A: A nurse says: "This won't hurt a bit." A schoolteacher says:
+ "We're going to have to do this over and over again until we get it
+ right." An airline stewardess says: "Just hold this over your
+ mouth and nose, and breath normally."
+%
+Q: How many right-to-lifers does it take to change a light bulb?
+A: Two. One to screw it in and one to say that light started when the
+ screwing began.
+%
+Q: How many supply-siders does it take to change a light bulb?
+A: None. The darkness will cause the light bulb to change by itself.
+%
+Q: How much money do you give to a 900 foot Jesus?
+A: As much as he wants.
+%
+Q: If Tarzan was Jewish, and Jane was a princess, what would Cheetah
+ be?
+A: A fur coat.
+%
+Q: What do you do with an elephant with three balls?
+A: Walk him and pitch to the rhino.
+%
+Q: What do you get when you cross James Dean with Ronald Reagan?
+A: A rebel without a clue.
+%
+Q: What is "SMOORPLAY"?
+A: It's what SMURFS do before they SMUCK, of course!
+%
+Q: What is the worst story Helen Keller ever read?
+A: A cheese grater
+%
+Q: What's Jewish foreplay?
+A: Two hours of begging.
+%
+Q: Where can you buy black lace crotchless panties for sheep?
+A: Fredrick's of Ithaca, New York.
+%
+Q: Where does virgin wool come from?
+A: Ugly sheep.
+%
+Q: Why does Helen Keller masturbate with one hand?
+A: So she can moan with the other!
+%
+"Queensboro president Donald Mannis, charged with receiving bribes in
+exchange for city contracts, resigned on Tuesday. Mannis feels he must
+devote more time to impending litigation, some of which might emanate
+from a recent statement he made comparing New York Mayor Ed Koch to
+Nazi Martin Bormann. A spokesman from the Bormann estate said they are
+weighing the odds of a slander suit. Mayor Koch could naturally be
+reached for comment, but we chose not to listen."
+ -- Dennis Miller, "Saturday Night Live"
+%
+Randel, n.:
+ A nonsensical poem recited by Irish schoolboys as an apology
+for farting at a friend.
+ -- Mrs. Byrne's Dictionary of Unusual, Obscure &
+ Preposterous Words
+%
+Reagan can't _a_c_t either
+%
+Remember when you were a kid and the boys didn't like the girls? Only
+sissies liked girls? What I'm trying to tell you is that nothing's
+changed. You think boys grow out of not liking girls, but we don't
+grow out of it. We just grow horny. That's the problem. We mix up
+liking pussy for liking girls. Believe me, one couldn't have less to
+do with the other.
+ -- Jules Feiffer
+%
+Republicans consume three-fourths of the rutabaga produced in this
+country. The remainder is thrown out.
+%
+Republicans raise dahlias, Dalmatians and eyebrows.
+Democrats raise Airedales, kids and taxes.
+
+Democrats eat the fish they catch.
+Republicans hang them on the wall.
+
+Republican boys date Democratic girls. They plan to marry Republican
+girls, but feel they're entitled to a little fun first.
+
+Democrats make up plans and then do something else.
+Republicans follow the plans their grandfathers made.
+
+Republicans consume three-fourths of the rutabaga produced in the USA.
+The remainder is thrown out.
+
+Republicans sleep in twin beds -- some even in separate rooms.
+That is why there are more Democrats.
+ -- The Official Rules, as compiled by Paul Dickson
+%
+Republicans tend to keep their shades drawn, although there is seldom
+any reason why they should. Democrats ought to, but don't.
+%
+Ronald Reagan -- America's favorite placebo
+%
+Said a horny young girl from Milpitas,
+"My favorite sport is coitus."
+ But a fullback from State
+ Made her period late,
+And now she has athlete's fetus
+%
+Said a swinging young chick named Lyth
+Whose virtue was largely a myth,
+ "Try as hard as I can,
+ I can't find a man
+That it's fun to be virtuous with."
+%
+Said Einstein, "I have an equation
+Which to some may seem rabelaisian:
+ Let _V be virginity
+ Approaching infinity;
+Let _P be a constant persuasion;
+
+"Let _V over _P be inverted
+With the square root of _M_u inserted
+ _N times into _V ...
+ The result, Q.E.D.,
+Is a relative!" Einstein asserted.
+%
+Save Soviet Jewry -- Win Valuable Prizes!!!!
+%
+Sex is like a bridge game -- If you have a good hand no partner is
+needed.
+%
+Sex is one of the nine reasons for reincarnation ... the other eight
+are unimportant.
+ -- Henry Miller
+%
+Sex is the poor man's opera.
+ -- G. B. Shaw
+%
+She asked me if I loved her still. "Yes," I replied. "I've never had
+you any other way."
+%
+She hates testicles, thus limiting the men she can admire to Democratic
+candidates for president.
+ -- John Greenway, "The American Tradition", on feminist
+ Elizabeth Gould Davis
+%
+... So this is a very confusing situation, and what makes it even worse
+is, our standards keep changing. Take Playboy magazine. Back in the
+1950s, when I started reading it strictly for the articles, Playboy was
+considered just about the raciest thing around, even though all it ever
+showed was women's breasts. Granted, any given one of these breasts
+would have provided adequate shelter for a family of four, but the
+overall effect was no more explicit than many publications we think
+nothing of today, such as Sports Illustrated's Annual Nipples Poking
+Through Swimsuits Issue.
+ -- Dave Barry, "Pornography"
+%
+Sooner or later, generals will own you.
+%
+Statisticians do it with 95% confidence.
+%
+Statisticians probably do it.
+%
+Subpoena, n.:
+ From the root "sub", below, and the Latin "poena" for male
+organ or penis. Therefore, "below the penis" or "by the balls."
+%
+Support the right of unborn males to bear arms!
+ -- A public service announcement from Phyllis Schlafly,
+ the Catholic Church, and the National Rifle
+ Association
+%
+Sure eating yogurt will improve your sex life. People know that if
+you'll eat that stuff, you'll eat anything.
+%
+Sure, Reagan has promised to take senility tests. But what if he
+forgets?
+%
+"Taxes should hurt. I just mailed my own tax return last night and I
+am prepared to say `ouch!' as loud as anyone."
+ -- Ronald Reagan
+%
+"The Army is a place where you get up early in the morning to be yelled
+at by people with short haircuts and tiny brains."
+ -- Dave Barry
+%
+ The big problem with pornography is defining it. You can't
+just say it's pictures of people naked. For example, you have these
+primitive African tribes that exist by chasing the wildebeest on foot,
+and they have to go around largely naked, because, as the old tribal
+saying goes: "N'wam k'honi soit qui mali," which means, "If you think
+you can catch a wildebeest in this climate and wear clothes at the same
+time, then I have some beach front property in the desert region of
+Northern Mali that you may be interested in."
+ So it's not considered pornographic when National Geographic
+publishes color photographs of these people hunting the wildebeest
+naked, or pounding one rock onto another rock for some primitive reason
+naked, or whatever. But if National Geographic were to publish an
+article entitled "The Girls of the California Junior College System
+Hunt the Wildebeest Naked," some people would call it pornography. But
+others would not. And still others, such as the Spectacularly Rev.
+Jerry Falwell, would get upset about seeing the wildebeest naked.
+ -- Dave Barry, "Pornography"
+%
+The computer is the ultimate polluter: its shit is indistinguishable
+from the food it produces.
+%
+ The defense attorney was hammering away at the plaintiff: "You
+claim," he jeered, "that my client came at you with a broken bottle in
+his hand. But is it not true, that you had something in YOUR hand?"
+
+ "Yes," he admitted, "his wife. Very charming, of course, but
+not much good in a fight."
+%
+The difference between this school and a cactus plant is that the
+cactus has the pricks on the outside.
+%
+... The Father, the Son and the Holy Ghost would never throw the Devil
+out of Heaven as long as they still need him as a fourth for bridge.
+ -- Letter in NEW LIBERTARIAN NOTES #19
+%
+ The Gray-haired Woman's Complaint
+
+My back aches, my pussy is sore;
+I simply can't fuck any more;
+ I'm covered with sweat,
+ And you haven't come yet,
+And my God, it's a quarter to four!
+%
+The man who said "A bird in the hand's worth two in the bush" has been
+putting his bird in the *WRONG* bushes.
+%
+THE MX IS GOOD FOR THE ECONOMY. One important reason we have a Defense
+Department is that when we give it money, it spends it, which creates
+jobs, whereas if we left the money in the hands of civilians, we don't
+know what they'd do with it. Probably put it in open trenches and set
+it on fire. The MX will create an especially large number of jobs
+because of the number of warheads it carries. It carries a total of 10
+warheads. This creates a great deal of employment, because you have
+your Warhead Makers, your Warhead Lifters, your Persons Who Tap the
+Warheads Gently with Rubber Mallets to Wedge Them All Snugly Into the
+Nose Cone, your Persons Who Just Walk Around Playing Soothing Cassettes
+by Recording Artists such as Perry Como So We Don't Have Any More
+Episodes Where a Worker Who is Experiencing Some Strain Sticks a
+Warhead in the Employee Cafeteria Microwave and Sets It On Roast, etc.
+We are talking about a lot of jobs.
+ -- Dave Barry, "At Last, the Ultimate Deterrent Against
+ Political Fallout"
+%
+The other night I was having sex, but the girl hung up on me.
+%
+The owner of a large furniture store in the mid-west arrived in France
+on a buying trip. As he was checking into a hotel he struck up an
+acquaintance with a beautiful young lady. However, she only spoke
+French and he only spoke English, so each couldn't understand a word
+the other spoke. He took out a pencil and a notebook and drew a
+picture of a taxi. She smiled, nodded her head and they went for a
+ride in the park. Later, he drew a picture of a table in a restaurant
+with a question mark and she nodded, so they went to dinner. After
+dinner he sketched two dancers and she was delighted. They went to
+several nightclubs, drank champagne, danced and had a glorious
+evening. It had gotten quite late when she motioned for the pencil and
+drew a picture of a four-poster bed. He was dumbfounded, and has never
+be able to understand how she knew he was in the furniture business.
+%
+The problem with being best man at a wedding is that you never get a
+chance to prove it.
+%
+The real problem with fucking a sheep is that you have to walk around
+in front every time you want to kiss her.
+%
+The reason we need the MX missile system is that the missiles we
+currently have in the ground are the Minuteman model, which is very
+old. The Defense Department can't even remember where half of them
+are. Insects have built nests in them. People have built houses
+directly over the silos. What this means, of course, is that if we
+ever needed them to help obliterate all human life on the planet, they
+could be a real embarrassment. I mean, maybe YOU'RE comfortable with
+the prospect of missiles that are supposed to represent you barging
+over the North Pole trailing shreds of polyester carpeting from some
+recreation room in South Dakota, but your strategic defense planners
+are not.
+ -- Dave Barry, "At Last, the Ultimate Deterrent Against
+ Political Fallout"
+%
+The sergeant walked into the shower and caught me giving myself a
+dishonorable discharge. Without missing a beat, I said, "It's my dick
+and I can wash it as fast as I want!"
+%
+ The Split-Atom Blues
+
+Gimme Twinkies, gimme wine,
+ Gimme jeans by Calvin Kline ...
+But if you split those atoms fine,
+ Mama keep 'em off those genes of mine!
+
+Gimme zits, take my dough,
+ Gimme arsenic in my jelly roll ...
+Call the devil and sell my soul,
+ But Mama keep dem atoms whole!
+ -- Milo Bloom, "Bloom County"
+%
+"The State of California has no business subsidizing intellectual
+curiosity."
+ -- Ronald Reagan
+%
+The superpowers often behave like two heavily armed blind men feeling
+their way around a room, each believing himself in mortal peril from
+the other, whom he assumes to have perfect vision. Each tends to
+ascribe to the other side a consistency, forsight and coherence that
+its own experience belies. Of course, even two blind men can do
+enormous damage to each other, not to speak of the room.
+ -- Henry Kissinger
+%
+The United States Army;
+194 years of proud service,
+unhampered by progress.
+%
+The United States is like the guy at the party who gives cocaine to
+everybody and still nobody likes him.
+ -- Jim Samuels
+%
+"The voters have spoken, the bastards ..."
+%
+"The whole world is about three drinks behind."
+ -- Humphrey Bogart
+%
+The word "spine" is, of course, an anagram of "penis". This is true in
+almost fifty percent of the languages of the Galaxy, and many people
+have attempted to explain why. Usually these explanations get bogged
+down in silly puns about "standing erect".
+ -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
+%
+The world is an 8000 mile in diameter spherical pile of shit.
+%
+ Them Toad Suckers
+
+How 'bout them toad suckers, ain't they clods?
+Sittin' there suckin' them green toady frogs!
+
+Suckin' them hop toads, suckin' them chunkers,
+Suckin' them a leapy type, suckin' them flunkers.
+
+Look at them toad suckers, ain't they snappy?
+Suckin' them bog frogs sure make's 'em happy!
+
+Them hugger mugger toad suckers, way down south,
+Stickin' them sucky toads in they mouth!
+
+How to be a toad sucker, no way to duck it,
+Get yourself a toad, rear back, and suck it!
+ -- Mason Williams
+%
+There are also a lot of nice buildings in Haiphong. What their
+contributions are to the war effort I don't know, but the desire to
+bomb a virgin building is terrific.
+ -- Commander Henry Urban Jr.
+%
+There are revolutions that are sweeping the world and we in America
+have been in a position of trying to stop them. With all the wealth of
+America, with all of the military strength of America, those
+revolutions are revolutions against a form of political and economic
+organization in the countries of Asia and the Middle East that are
+oppressive. They are revolutions against feudalism. [1952]
+ -- Supreme Court Justice William O. Douglas
+%
+There are two sides to every divorce: yours and the shithead's.
+%
+"There is a God, but He drinks"
+ -- Blore
+%
+There once was a couple named Kelley,
+Who lived their life belly to belly.
+ Because in their haste
+ They used Library Paste,
+Instead of Petroleum Jelly.
+%
+There once was a fiesty young terrier
+Who liked to bite girls on the derriere.
+ He'd yip and he'd yap,
+ Then leap up and snap;
+And the fairer the derriere the merrier.
+%
+There once was a freshman named Lin,
+Whose tool was as thin as a pin,
+ A virgin named Joan
+ From a bible belt home,
+Said "This won't be much of a sin."
+%
+There once was a hacker named Ken
+Who inherited truckloads of Yen
+ So he built him some chicks
+ Of silicon chips
+And hasn't been heard from since then.
+%
+There once was a lady from Exeter,
+So pretty that men craned their necks at her.
+ One was even so brave
+ As to take out and wave
+The distinguishing mark of his sex at her.
+%
+There once was a man named Eugene
+Who invented a screwing machine
+ Concave and convex
+ It served either sex
+And it played with itself in between.
+%
+There once was a plumber from Leigh,
+Who was plumbing his maid by the sea,
+ Said she, "Please stop plumbing,
+ I think someone's coming!"
+Said he, "Yes I know love, it's me."
+%
+There once was a queen of Bulgaria
+Whose bush had grown hairier and hairier,
+ Till a prince from Peru
+ Who came up for a screw
+Had to hunt for her cunt with a terrier.
+%
+There once was a Scot named McAmeter
+With a tool of prodigious diameter.
+ It was not the size
+ That cause such surprise;
+'Twas his rhythm -- iambic pentameter.
+%
+There was a bluestocking in Florence
+Wrote anti-sex pamphlets in torrents,
+ Till a Spanish grandee,
+ Got her off with his knee,
+And she burned all her works with abhorrence.
+%
+There was a gay countess of Bray,
+And you may think it odd when I say,
+ That in spite of high station,
+ Rank and education,
+She always spelled cunt with a "k".
+%
+There was a young fellow named Bliss
+Whose sex life was strangely amiss,
+ For even with Venus
+ His recalcitrant penis
+Would never do better than t
+ h
+ i
+ s
+ .
+%
+There was a young girl from Hong Kong
+Whose cervical cap was a gong.
+ She said with a yell,
+ As a shot rang her bell,
+"I'll give you a ding for a dong!"
+%
+There was a young girl named Sapphire
+Who succumbed to her lover's desire.
+ She said, "It's a sin,
+ But now that it's in,
+Could you shove it a few inches higher?"
+%
+There was a young girl of Angina
+Who stretched catgut across her vagina.
+ From the love-making frock
+ (With the proper sized cock)
+Came Tocata and Fugue in D minor.
+%
+There was a young girl of Darjeeling
+Who could dance with such exquisite feeling
+ There was never a sound
+ For miles around
+Save of fly-buttons hitting the ceiling.
+%
+There was a young lad name of Durcan
+Who was always jerkin' his gherkin.
+ His father said, "Durcan!
+ Stop jerkin' your gherkin!
+Your gherkin's for ferkin', not jerkin'.
+%
+There was a young lady from Maine
+Who claimed she had men on her brain.
+ But you knew from the view,
+ As her abdomen grew,
+It was not on her brain that he'd lain.
+%
+There was a young lady named Clair
+Who possessed a magnificent pair;
+ At least so I thought
+ Till I saw one get caught
+On a thorn, and begin losing air.
+%
+There was a young lady named Hall,
+Wore a newspaper dress to a ball.
+ The dress caught on fire
+ And burned her entire
+Front page, sporting section, and all.
+%
+There was a young lady named Twiss
+Who said she thought fucking a bliss,
+ For it tickled her bum
+ And caused her to come
+.siht ekil gniyl ylbatrofmoc elihW
+%
+There was a young lady of Norway
+Who hung by her toes in a doorway.
+ She said to her beau
+ "Just look at me Joe
+I think I've discovered one more way."
+%
+There was a young man from Bel-Aire
+Who was screwing his girl on the stair,
+ But the banister broke
+ So he doubled his stroke
+And finished her off in mid-air.
+%
+There was a young man named Crockett
+Whose balls got caught in a socket.
+ His wife was a bitch,
+ And she threw the switch,
+As Crockett went off like a rocket.
+%
+There was a young man of Cape Horn
+Who wished he had never been born,
+ And he wouldn't have been
+ If his father had seen
+That the end of the rubber was torn.
+%
+There was a young man of St. John's
+Who wanted to bugger the swans.
+ But the loyal hall porter
+ Said, "Pray take my daughter!
+Those birds are reserved for the dons."
+%
+There was a young whore from kaloo
+Who filled her vagina with glue.
+ She said with a grin,
+ "If they pay to get in,
+They can pay to get out again too!"
+%
+There was an old man of the port
+Whose prick was remarkably short.
+ When he got into bed,
+ The old woman said,
+"This isn't a prick; it's a wart!"
+%
+There was an old pirate named Bates
+Who was learning to rhumba on skates.
+ He fell on his cutlass
+ Which rendered him nutless
+And practically useless on dates.
+%
+There were the Scots
+Who kept the Sabbath
+And everything else they could lay their hands on.
+Then there were the Welsh
+Who prayed on their knees and their neighbors.
+Thirdly there were the Irish
+Who never knew what they wanted
+But were willing to fight for it anyway.
+Lastly there were the English
+Who considered themselves a self-made nation
+Thus relieving the Almighty of a dreadful responsibility.
+%
+There's been no top authority saying what marijuana does to you. I
+really don't know that much about it. I tried it once but it didn't do
+anything to me.
+ -- John Wayne
+%
+There's more than one way to skin a cat:
+ Way number 15 -- Krazy Glue and a toothbrush.
+%
+There's more than one way to skin a cat:
+ Way number 27 -- Use an electric sander.
+%
+There's more than one way to skin a cat:
+ Way number 32 -- Wrap it around a lonely frat man's pecker.
+%
+There's nothing better than good sex. But bad sex? A peanut butter
+and jelly sandwich is better than bad sex.
+ -- Billy Joel
+%
+There's nothing wrong with America that a good erection wouldn't cure.
+ -- David Mairowitz
+%
+This is a test of the emergency cunnilingus system. If this had been an
+actual emergency, you would have known it!
+%
+This is National Smokers-Are-Shits Week.
+%
+This limerick is **SO**FILTHY** that it would offend you. So I'll put
+"di-dah" for the filthy words:
+
+ Di-dah, di-dah, di-dah di-dah,
+ Di-dah di-dah di-dah, di-dah;
+ di-dah di-dah di-dah?
+ Di-dah di-dah di-dah.
+ Di-dah di-dah, di-dah di-fuck.
+%
+This test has been designed to evaluate reactions of management
+personal to various situations.
+
+You are making a sales presentation to a group of corporate executives
+in the plushest office you've ever seen. The enchillada casserole and
+egg salad sandwich you had for lunch react, creating severe pressure.
+Your sphincter loses control and you break wind, causing the glass
+bookcase doors to shatter and a secretary to pass out.
+
+YOU SHOULD:
+
+(a) Offer to come back next week when the smell has gone away.
+(b) Point to the Chief Executive and accuse him of the offense.
+(c) Challenge anyone in the room to do better.
+%
+Thou shalt not omit adultery.
+%
+To a Real Woman, every ejaculation is premature.
+%
+"Tom Hayden is the kind of politician who gives opportunism a bad
+name."
+ -- Gore Vidal
+%
+'Twas orgy, and the hip and mod And as in raffish thought he sprawled,
+Did groove and trip out at the pad: The Radcliffe girl, no idle flirt,
+All whimsy were the slamming chicks, Crept past the hippies getting balled
+And the Radcliffe undergrad. And doffed her miniskirt.
+
+"Beware the Radcliffe girl, my son! One, two! One, two! And through
+The looks that melt, the claws that and through
+ catch! The venerable staff went snicker-snack!
+Beware the Byrn Mawr deb, and shun He left her bred, sans maidenhead,
+The uppity Wellesleysnatch!" And went galumphing back.
+
+He took his venerable staff in hand: "And hast thou laid the Radcliffe girl?
+Long time the cool young stuff he Come to my arms, my horny boy!
+ sought -- O spaced-out day! Calooh! Callay!"
+So rested he among the spree He cackled in his joy.
+And paused to smoke some pot.
+ 'Twas orgy, and the hip and mod
+ Did groove and trip out at the pad:
+ All whimsy were the slamming chicks,
+ And the Radcliffe undergrad.
+%
+ Two little kids, aged six and eight, decide it's time to learn
+how to swear. So, the eight-year-old says to the six-year-old, "Okay,
+you say `ass' and I'll say `hell'".
+ All excited about their plan, they troop downstairs, where
+their mother asks them what they'd like for breakfast.
+ "Aw, hell," says the eight-year-old, "gimme some Cheerios."
+His mother backhands him off the stool, sending him bawling out of the
+room, and turns to the younger brother. "What'll you have?"
+ "I dunno," quavers the six-year-old, "but you can bet your ass
+it ain't gonna be Cheerios."
+%
+"Under capitalism, man exploits man. Under Communism, it's just the
+opposite."
+ -- John Kenneth Galbraith
+%
+Uppers are no longer stylish, methedrine is almost as rare as pure acid
+or DMT. "Consciousness Expansion" went out with LBJ and it is worth
+noting, historically, that downers came in with Nixon.
+ -- Dr. Hunter S. Thompson
+%
+Vegetarians for oral sex -- "The only meat that's fit to eat"
+%
+Vidi, vici, veni.
+(I saw, I conquered, I came.)
+%
+Virgin, n.:
+ An ugly third grader.
+%
+War is menstruation envy.
+%
+"Water? Never touch the stuff! Fish fuck in it."
+ -- W. C. Fields
+%
+We call our dog Egypt, because in every room he leaves a pyramid.
+%
+"We don't have to protect the environment -- the Second Coming is at
+hand."
+ -- James Watt
+%
+We have reason to believe that man first
+walked upright to free his hands for masturbation.
+ -- Lily Tomlin
+%
+"We should declare war on North Vietnam. We could pave the whole
+country and put parking strips on it, and still be home by Christmas."
+ -- Ronald Reagan
+%
+WE'RE GOING TO THROW THE MX AWAY AFTER WE BUILD IT. The MX is really
+[Don't tell anybody!] just a "bargaining chip" in the nuclear-arms-
+reduction talks with the Russians. See, we have a problem with the
+Russians. They look at our leaders and they see, for example, George
+Bush, who is really a fine and brave man but who happens to have this
+unfortunate physical characteristic whereby when he talks he sounds as
+though he just inhaled a helium party balloon. If he ever becomes
+President, the Russians will deliberately create nuclear crises just so
+they can gather around the Hot Line with refreshments and listen to
+George talk.
+ -- Dave Barry, "At Last, the Ultimate Deterrent Against
+ Political Fallout"
+%
+Well, see, Joyce, there we were, trapped in the elevator. Now, I had
+my tennis racquet and the goldfish; she was holding the Crisco. Surely
+you can imagine how one thing naturally led to another!
+%
+Well, there was this tiger, who woke up one morning, and just felt
+great (yes, just like Tony the Tiger: GREAAAAAAT). Anyway, he just
+felt so good, he went out and cornered a small monkey and roared at
+him: "WHO IS THE MIGHTIEST OF ALL THE JUNGLE ANIMALS?" And this poor
+quaking little monkey replied: "You are of course, no one is mightier
+than you." A little while later this tiger confronts a deer, and just
+bellows out: "WHO IS THE GREATEST AND STRONGEST OF ALL THE JUNGLE
+ANIMALS?" The deer is shaking so hard it can barely speak, but manages
+to stammer: "Oh great tiger, you are by far the mightiest animal in the
+jungle." The tiger, being on a roll, swaggered, up to an elephant that
+was quietly munching on some weeds, and roared at the top of his voice:
+"WHO IS THE MIGHTIEST OF ALL THE ANIMALS IN THE JUNGLE?" Well, this
+elephant grabs the tiger with his trunk, picks him up, slams him down;
+picks him up again, and shakes him until the tiger is just a blur of
+orange and black; and finally throws him violently into a nearby tree.
+The tiger staggers to his feet and looks at the elephant and says:
+"Man, just because you don't know the answer, you don't have to get so
+pissed."
+%
+What can you use used tampons for? Tea bags for vampires.
+%
+What did Mickey Mouse get for Christmas?
+A Dan Quayle watch.
+%
+What is the difficulty with writing a PDP-8 program to emulate Jerry
+Ford?
+
+Figuring out what to do with the other 3K.
+%
+ "What the hell are you getting so upset about? I thought you
+didn't believe in God."
+ "I don't," she sobbed, bursting violently into tears, "but the
+God I don't believe in is a good God, a just God, a merciful God. He's
+not the mean and stupid God you make Him out to be."
+ -- Joseph Heller, "Catch-22"
+%
+When God created man, She was only testing.
+%
+When God created two sexes, he may have been overdoing it.
+ -- Charles Merrill Smith
+%
+"When I grow up, I want to be an honest lawyer so things like that
+can't happen."
+ -- Richard Nixon as a boy (on the Teapot Dome scandal)
+%
+When it all boils down to the essence of truth one must live by a dog's
+rule of life: if you can't eat it or fuck it, piss on it!
+%
+ When the surgeon came to see her on the morning after her
+operation, the young woman asked her somewhat hesitantly how long it
+would be before she could resume her sex life. "I really haven't
+thought about it," gulped the stunned surgeon. "You're the first
+patient who's asked me that after a tonsillectomy!"
+%
+While I, with my usual enthusiasm,
+Was exploring in Ermintrude's busiasm,
+ She explained, "They are flat,
+ But think nothing of that --
+You will find that my sweet sister Susiasm."
+%
+"White House carpenters have reworked the master bedroom, remodeling it
+so that Ronnie can sleep with his head in the hall. That way, by the
+time he wakes up, somebody will have already shined his hair."
+%
+Why is it that there are so many more horses' asses than there are
+horses?
+ -- G. Gordon Liddy
+%
+Why marry a virgin? If she wasn't good enough for the rest of them
+then she isn't good enough for you.
+%
+Women Unite! Make *___him* sleep in the wet spot tonight!
+%
+Women who want to be equal to men lack imagination
+ -- Graffito in a women's restroom
+%
+Women's Libbers are OK. I just wouldn't want my sister to marry one.
+%
+Would you mind terribly much if I asked you to take your silly-assed
+problem down the hall?
+%
+"Yes, that was Richard Nixon. He used to be President. When he left
+the White House, the Secret Service would count the silverware."
+ -- Woody Allen, "Sleeper"
+%
+You always introduce the younger person to the older person, using the
+wording: "Miss Brown, I'd like to introduce you to an older person"
+(unless her name is not "Miss Brown"). If you do not know a person's
+age, ask for a driver's license and a major credit card. If you are
+introduced to a member of a minority group, use the "high-five" style
+handshake, followed by a remark designed to show you don't mind a bit,
+such as "I see you are a (name of a minority group)! Good!"
+ -- Dave Barry, "The Stuff of Etiquette"
+%
+"You and I as individuals can, by borrowing, live beyond our means, but
+only for a limited period of time. Why should we think that collectively,
+as a nation, we are not bound by that same limitation?"
+ -- Ronald Reagan
+%
+You are at a business lunch when you are suddenly overcome with an
+uncontrollable desire to pick your nose. Since this is definitely a
+no-no, you:
+
+(a) Pretend to wave to someone across the room and with one fluid
+ motion, bury your forefinger in your nostril right up to the 4th
+ joint.
+
+(b) Get everyone drunk and organize a nose picking contest with a prize
+ to the one who makes his nose bleed first.
+
+(c) Drop your napkin on the floor and when you bend over to pick it up,
+ blow your nose on your sock.
+%
+You better believe that marijuana can cause castration. Just suppose
+your girlfriend gets the munchies!
+%
+You can lead a whore to Vasser, but you can't make her think.
+ -- Frederick B. Artz
+%
+You can pick your friends, and you can pick your nose, but you can't
+pick your friend's nose.
+%
+You can't underestimate the power of fear.
+ -- Tricia Nixon
+%
+You come out of a woman and you spend the rest of your life trying to
+get back inside.
+ -- Heathcote Williams
+%
+You have just returned from a trip to Green Bay, Wisconsin in January
+and tell your boss that nobody but whores and football players live
+there. He mentions that his wife is from Green Bay. You:
+
+(a) Pretend you are suffering from amnesia and don't remember your
+ name.
+
+(b) Ask what position she played.
+
+(c) Ask if she is still working the streets.
+%
+You have prepared a proposal for your supervisor. The success of this
+proposal will mean increasing your salary 20%. In the middle of your
+proposal your supervisor leans over to look at your report and spits
+into your coffee. You:
+
+(a) Tell him you take your coffee black.
+
+(b) Ask him if he has any communicable diseases.
+
+(c) Show him who's in command; promptly take a leak in his "In"
+ basket.
+%
+"You have to regard everything I say with suspicion -- I may be trying
+to bullshit you, or I may just be bullshitting you inadvertently."
+ -- J. Wainwright, Mathematics 140b
diff --git a/fortune/datfiles/fortunes-o.real.rot13 b/fortune/datfiles/fortunes-o.real.rot13
new file mode 100644
index 00000000..ade8a606
--- /dev/null
+++ b/fortune/datfiles/fortunes-o.real.rot13
@@ -0,0 +1,2018 @@
+71:
+ 69 jvgu gjb svatref hc lbhe nff.
+ -- Trbetr Pneyva
+%
+N ongure jubfr pybguvat jnf fgerjrq
+Ol oerrmrf gung yrsg ure dhvgr ahqr,
+ Fnj n zna pbzr nybat
+ Naq, hayrff V'z dhvgr jebat,
+Lbh rkcrpgrq guvf yvar gb or yrjq.
+%
+N orng fpuvmbcueravp fnvq, "Zr?
+V nz abg V, V'z n gerr."
+ Ohg nabgure, zber fnar,
+ Fubhgrq, "V'z n Terng Qnar!"
+Naq pbirerq uvf cnagf yrt jvgu crr.
+%
+N ohernhpenpl vf yvxr n frcgvp gnax -- nyy gur ernyyl ovt fuvgf sybng
+gb gur gbc.
+%
+N Puevfgvna vf n zna jub srryf ercragnapr ba Fhaqnl sbe jung ur qvq ba
+Fngheqnl naq vf tbvat gb qb ba Zbaqnl.
+ -- Gubznf Loneen
+%
+N pbafreingvir vf n zna jub oryvrirf gung abguvat fubhyq or qbar sbe
+gur svefg gvzr.
+ -- Nyserq R. Jvttnz
+%
+N pbafreingvir vf n zna jvgu gjb cresrpgyl tbbq yrtf jub unf arire
+yrnearq gb jnyx.
+ -- Senaxyva Q. Ebbfriryg
+%
+N sevraq jvgu jrrq vf n sevraq vaqrrq.
+%
+N uneq zna vf tbbq gb svaq.
+%
+N zna arrqf n zvfgerff, whfg gb oernx gur zbabtnzl.
+%
+N zngurzngvpvna anzrq Unyy
+Unf n urknurqebavpny onyy,
+ Naq gur phor bs vgf jrvtug
+ Gvzrf uvf crpxre'f, cyhf rvtug
+Vf uvf cubar ahzore -- tvir uvz n pnyy..
+%
+"N Zbezba vf n zna gung unf gur onq gnfgr naq gur eryvtvba gb qb jung n
+tbbq znal bgure crbcyr ner erfgenvarq sebz qbvat ol pbafpvragvbhf
+fpehcyrf naq gur cbyvpr."
+ -- Ze. Qbbyrl
+%
+N Avkba [vf cersrenoyr gb] n Qrna Ehfx -- jub jvyy or cnffvbangryl
+jebat jvgu n uvtu frafr bs pbafvfgrapl.
+ -- W. X. Tnyoenvgu
+%
+N aba-irtrgnevna nagv-nobegvbavfg vf n pbagenqvpgvba va grezf.
+ -- Culyyvf Fpuynsyl
+%
+N alzcu uvgf lbh naq fgrnyf lbhe ivetvavgl.
+%
+N crefba jub unf obgu srrg cynagrq svezyl va gur nve pna or fnsryl
+pnyyrq n yvoreny.
+%
+N cerggl lbhat ynql anzrq Ibtry
+Bapr fng urefrys qbja ba n zbyruvyy.
+ N phevbhf zbyr
+ Abfrq vagb ure ubyr --
+Zf. Ibtry'f bx, ohg gur zbyr'f vyy.
+%
+N cerggl lbhat znvqra sebz Senapr
+Qrpvqrq fur'q "whfg gnxr n punapr."
+ Fur yrg urefrys tb
+ Sbe na ubhe be fb
+Naq abj nyy ure fvfgref ner nhagf.
+%
+N Chevgna vf fbzrbar jub vf qrnguyl nsenvq gung fbzrbar, fbzrjurer, vf
+univat sha.
+%
+N ernpgvbanel vf n zna jubfr cbyvgvpny bcvavbaf nyjnlf znantr gb xrrc
+hc jvgu lrfgreqnl.
+%
+N erznexnoyr enpr ner gur Crefvnaf;
+Gurl unir fhpu crphyvne qvirefvbaf.
+ Gurl znxr ybir gur jubyr qnl
+ Va gur hfhny jnl
+Naq fnir hc gur avtugf sbe creirefvbaf.
+%
+N grnz cynlvat onfronyy va Qnyynf
+Pnyyrq gur hzcver oyvaq bhg bs znyvpr.
+ Juvyr guvf jbegul unq svgf
+ Gur grnz znqr rvtug uvgf
+Naq n tvey va gur oyrnpuref anzrq Nyvpr.
+%
+N jnagba lbhat ynql sebz Jvzyrl
+Ercebnpurq sbe abg npgvat dhvgr cevzyl
+ Fnvq, "Urniraf nobir!
+ V xabj frk vfa'g ybir,
+Ohg vg'f fhpu na ragenapvat snpfvzvyr."
+%
+N jvqbj jub snapvrq n zna fbzr
+Jnf qvqqyrq guerr gvzrf va n unafbzr.
+ Jura fur pynzberq sbe zber
+ Ure lbhat zna orpnzr fber
+Naq rkpynvzrq "Zl anzr'f Fvzcfba abg Fnzfba."
+%
+"N jbzna vf yvxr n qerffre ... fbzr zna nyjnlf tbva' guebhtu ure
+qenjref."
+ -- Oyvaq Yrzba Cyrqtr
+%
+N jbeevrq lbhat zna sebz Fgnzobhy
+Sbhaqf ybgf bs erq fcbgf ba uvf gbby.
+ Fnvq gur qbpgbe, n plavp,
+ "Trg bhg bs zl pyvavp;
+Whfg jvcr bss gur yvcfgvpx, lbh sbby!"
+%
+N.V. unpxref qb vg jvgu ebobgf.
+%
+Nofvagur znxrf gur gneg tebj sbaqre.
+%
+"Npprcgnapr jvgubhg cebbs vf gur shaqnzragny punenpgrevfgvp bs Jrfgrea
+eryvtvba, Erwrpgvba jvgubhg cebbs vf gur shaqnzragny punenpgrevfgvp bs
+Jrfgrea fpvrapr."
+ -- Tnel Mhxni, "Gur Qnapvat Jh Yv Znfgref"
+%
+Npuvyyrf' Ovbybtvpny Svaqvatf:
+ (1) Vs n puvyq ybbxf yvxr uvf sngure, gung'f urerqvgl. Vs ur
+ ybbxf yvxr n arvtuobe, gung'f raivebazrag.
+ (2) N ybg bs gvzr unf orra jnfgrq nethvat bire jung pnzr svefg
+ -- gur puvpxra be gur rtt. Vg jnf haqbhogrqyl gur
+ ebbfgre.
+%
+Nvqr gb Enltha: Fve, gur cbbe ner bhgfvqr cebgrfgvat lbhe ohqtrg
+ phgf.
+Enltha uvzfrys: Gryy gurz gurl'yy unir gb uryc gurzfryirf.
+Nvqr gb Enltha: Fve, gur Cragntba jnagf nabgure $30 ovyyvba.
+Enltha uvzfrys: Gryy gurz gb uryc gurzfryirf.
+%
+Nyy n unpxre arrqf vf n gvtug CHFUW, n ybbfr cnve bs HHBf, naq n jnez
+cynpr gb fuvsg.
+%
+Nyy gur jngref bs gur rnegu ner va gur nezcvg bs gur Terng Sebt.
+ -- E. Pehzo
+%
+Nyy guvatf qhyy naq htyl, Nyy perngherf fubeg naq fdhng,
+ Nyy guvatf ehqr naq anfgl, Gur Ybeq Tbq znqr gur ybg;
+Rnpu yvggyr fanxr gung cbvfbaf, Rnpu yvggyr jnfc gung fgvatf,
+ Ur znqr gurve oehgvfu irabz, Ur znqr gurve ubeevq jvatf.
+Nyy guvatf fvpx naq pnaprebhf, Nyy rivy terng naq fznyy,
+ Nyy guvatf sbhy naq qnatrebhf, Gur Ybeq Tbq znqr gurz nyy.
+Rnpu anfgl yvggyr ubearg, Rnpu ornfgyl yvggyr fdhvq.
+ Jub znqr gur fcvxrl hepuva? Jub znqr gur funexf? Ur qvq.
+Nyy guvatf fpnoorq naq hyprebhf, Nyy cbk obgu terng naq fznyy.
+ Chgevq, sbhy naq tnaterabhf, Gur Ybeq Tbq znqr gurz nyy.
+ -- Zbagl Clguba'f Sylvat Pvephf
+%
+Nzrevpn vf n ynetr, sevraqyl qbt va n irel fznyy ebbz. Rirel gvzr vg
+jntf vgf gnvy, vg xabpxf bire n punve.
+ -- Neabyq Wbfrcu Gblaorr
+%
+Na nepuvgrpg sryybj anzrq Lbevp
+Pbhyq, jura srryvat rhcubevp,
+ Qvfcynl sbe fryrpgvba
+ Guerr xvaqf bs rerpgvba --
+Pbevaguvna, vbavp, naq qbevp.
+%
+Na Nezl geniryf ba ure fgbznpu.
+%
+Na rtt unf gur fubegrfg frk-yvsr bs nyy: vs trgf ynvq bapr; vg trgf
+rngra bapr. Vg nyfb unf gb pbzr va n obk jvgu 11 bguref, naq gur bayl
+crefba jub jvyy fvg ba vgf snpr vf vgf zbgure.
+%
+"Naq Ormry fnvqrgu hagb Funz: `Funz,' ur fnvqrgu, `Gubh funyg tbrfg
+hagb gur gbja bs Ortbeenu, naq gurer gubh funyg srgpurgu hagb guvar
+obfbz 35 gnyragf, naq nyfb funyg gubh srgpurgu n yvxr ahzore bs phovgf,
+cebivqrgu gung gurl ner avpr naq serfu.'"
+ -- Qnir Oneel, "Trggvat Eryvtvba"
+%
+ Naq Wrfhf fnvq hagb gurz, "Naq jubz qb lbh fnl gung V nz?"
+ Gurl ercyvrq, "Lbh ner gur rfpungbybtvpny znavsrfgngvba bs gur
+tebhaq bs bhe orvat, gur bagbybtvpny sbhaqngvba bs gur pbagrkg bs bhe
+irel frysubbq erirnyrq."
+ Naq Wrfhf ercyvrq, "Jung?"
+%
+... Naq gura gurer'f gur thl jub obhtug 20,000 oenf, phg gurz va unys,
+naq fbyq 40,000 lnznypunf jvgu puva fgencf ...
+%
+Nakvrgl, a.:
+ Gur svefg gvzr lbh pna'g qb vg n frpbaq gvzr.
+
+Cnavp, a.:
+ Gur frpbaq gvzr lbh pna'g qb vg gur svefg gvzr.
+%
+"Nalguvat perngrq zhfg arprffnevyl or vasrevbe gb gur rffrapr bs gur perngbe."
+ -- Pynhqr Fubhfr
+
+"Rvafgrva'f zbgure zhfg unir orra bar urpx bs n culfvpvfg."
+ -- Wbfrcu P. Jnat
+%
+"Nccebkvzngryl 80% bs bhe nve cbyyhgvba fgrzf sebz ulqebpneobaf
+eryrnfrq ol irtrgngvba, fb yrg'f abg tb bireobneq va frggvat naq
+rasbepvat gbhtu rzvffvbaf fgnaqneqf sebz zna-znqr fbheprf."
+ -- Ebanyq Erntna
+%
+Onpx va gur tbbq byr qnlf va Grknf, jura fgntrpbnpurf naq gur yvxr jnf
+cbchyne, gurer jrer guerr crbcyr va n fgntrpbnpu bar qnl: n gehr erq-
+oybbqrq obea-naq-envfrq Grknf tragyrzna, n graqresbbg pvgl-fyvpxre sebz
+onpx Rnfg, naq n ornhgvshy naq jryy-raqbjrq Grknf ynql. Gur pvgl-
+fyvpxre xrcg rlrvat gur ynql, naq svanyyl ur yrnarq sbejneq naq fnvq,
+"Ynql, V'yy tvir lbh $10 sbe n oybj wbo." Gur Grknf tragyrzna ybbxrq
+nccnyyrq, chyyrq bhg uvf cvfgby, naq xvyyrq gur pvgl-fyvpxre ba gur
+fcbg. Gur ynql tnfcrq naq fnvq, "Gunax lbh, fhu, sbe qrsraqva' znu
+ubabe!" Jurerhcba gur Grkna ubyfgrerq uvf tha naq fnvq, "Lbhe ubabe,
+uryy! Ab graqresbbg vf tbaan envfr gur cevpr bs jbzra va Grknf!"
+%
+Onygvzber, a.:
+ Jurer gur jbzra jrne ghegyrarpx fjrngref gb uvqr gurve syrn
+pbyynef.
+%
+Onaxref qb vg jvgu vagrerfg (cranygl sbe rneyl jvguqenjny).
+%
+"Onfrq ba jung lbh xabj nobhg uvz va uvfgbel obbxf, jung qb lbh guvax
+Noenunz Yvapbya jbhyq or qbvat vs ur jrer nyvir gbqnl?
+
+ (1) Jevgvat uvf zrzbvef bs gur Pvivy Jne.
+ (2) Nqivfvat gur Cerfvqrag.
+ (3) Qrfcrengryl pynjvat ng gur vafvqr bs uvf pbssva."
+ -- Qnivq Yrggrezna
+%
+Or cercnerq... gung'f gur Obl Fpbhg'f fbyrza perrq.
+Or cercnerq... gb or pyrna va jbeq naq qrrq.
+Qba'g fbyvpvg sbe lbhe fvfgre, gung'f abg avpr,
+Hayrff lbh trg n tbbq crepragntr bs ure cevpr ...
+ -- Gbz Yruere
+%
+Orubyq gur haobea srghf naq
+ Jrrc fnyg grnef pebpbqvyvna;
+Nyy yvsr vf fnperq (fnir, bs pbhefr,
+ Na rarzl pvivyvna).
+%
+Orvat fgbarq ba znevwhnan vfa'g irel qvssrerag sebz orvat fgbarq ba
+tva.
+ -- Enycu Anqre
+%
+Orarngu guvf fgbar n ivetva yvrf,
+Sbe ure yvsr uryq ab greebef.
+N ivetva obea, n ivetva qvrq:
+Ab uvgf, ab ehaf, ab reebef.
+%
+Orjner bs nygehvfz. Vg vf onfrq ba frys-qrprcgvba, gur ebbg bs nyy
+rivy.
+%
+Oyrffrq ner gur zrrx sbe gurl funyy vauvovg gur rnegu.
+%
+Obbmr vf gur nafjre. V qba'g erzrzore gur dhrfgvba.
+%
+Ohvyq n orggre zbhfrgenc, gur fnlvat tbrf -- naq jvgu gur oenffvrer,
+Lnaxrr Vatrahvgl qvq rknpgyl gung. Ohg gurve gehr fgebxr bs travhf jnf
+gur arj onvg. Gur byq snfuvbarq zbhfrgenc jnf ybnqrq jvgu purrfr;
+abobql pnerf zhpu nobhg purrfr, rkprcg zvpr. Ohg jura Nzrevpna
+Xabj-Ubj erybnqrq gur oenffvrer jvgu gvgf, rirel urgrebfrkhny znyr va
+gur pbhagel jnf ubcryrffyl genccrq.
+ -- Nyna Furezna, "Gur Encr bs gur N*C*R*"
+%
+... Ohg gur erjneq bs n fhpprffshy pbyynobengvba vf n guvat gung pnaabg
+or cebqhprq ol rvgure bs gur cnegvrf jbexvat nybar. Vg vf nxva gb gur
+orarsvgf bs frk jvgu n cnegare, nf bccbfrq gb znfgheongvba. Gur ynggre
+vf sha, ohg lbh fubj zr nalbar jub unf tbggra n onol sebz cynlvat jvgu
+uvz be urefrys, naq V'yy fubj lbh na htyl onol, jvgu whfg n jubyr ohapu
+bs xahpxyrf.
+ -- Uneyna Ryyvfba
+%
+"Pnyvsbeavn vf cebhq gb or gur ubzr bs gur serrjnl."
+ -- Ebanyq Erntna
+%
+"Pna lbh unzzre n 6-vapu fcvxr vagb n jbbqra cynax jvgu lbhe cravf?"
+
+"Hu, abg evtug abj."
+
+"Gfx. N tvey unf gb unir fbzr fgnaqneqf."
+ -- "Erny Travhf"
+%
+Pncgnva Ubbx qvrq bs wbpx vgpu.
+%
+Punzcntar qba'g znxr zr ynml.
+Pbpnvar qba'g qevir zr penml.
+Nva'g abobql'f ohfvarff ohg zl bja.
+ -- Gnw Znuny
+%
+Punfgr znxrf jnfgr.
+%
+Puvczhaxf ebnfgvat ba na bcra sver
+Wnpx Sebfg evccvat hc lbhe abfr
+Lhyrgvqr pnebyref orvat guebja va gur sver
+Naq sbyxf qerffrq hc yvxr ohssnybrf
+Rirelobql xabjf n ghexrl fynhtugrerq va gur fabj
+Urycf gb znxr gur frnfba evtug
+Gval gbgf jvgu gurve rlrf nyy tbhtrq bhg
+Jvyy svaq vg uneq gb frr gbavtug
+Gurl xabj gung Fnagn'f ba uvf jnl
+Ur'f ybnqrq ybgf bs thaf naq ohyyrgf ba uvf fyrvtu
+Naq rirel zbgure'f puvyq vf fher gb fcl
+Gb frr vs ervaqrre ernyyl fpernz jura gurl qvr
+Naq fb V'z bssrevat guvf fvzcyr cuenfr
+Gb xvqf sebz bar gb avargl gjb
+Nygubhtu vg'f orra fnvq znal gvzrf, znal jnlf
+Zreel Puevfgznf, Zreel Puevfgznf, Zreel Puevfgznf, Shpx lbh!!
+%
+Puevfgvna, a.:
+ Bar jub oryvrirf gung gur Arj Grfgnzrag vf n qvivaryl vafcverq
+obbx nqzvenoyl fhvgrq gb gur fcvevghny arrqf bs uvf arvtuobe. Bar jub
+sbyybjf gur grnpuvatf bs Puevfg va fb sne nf gurl ner abg vapbafvfgrag
+jvgu n yvsr bs fva.
+%
+Puevfgvnavgl unf abg orra gevrq naq sbhaq jnagvat; vg unf orra sbhaq
+qvssvphyg naq abg gevrq.
+ -- T. X. Purfgregba
+%
+Pynexr'f Guveq Ynj:
+ Nal fhssvpvragyl nqinaprq grpuabybtl vf vaqvfgvathvfunoyr sebz
+zntvp.
+
+T'f Guveq Ynj:
+ Va fcvgr bs nyy rivqrapr gb gur pbagenel, gur ragver havirefr
+vf pbzcbfrq bs bayl gjb onfvp fhofgnaprf: zntvp naq ohyyfuvg.
+
+U'f Qvpghz:
+ Gurer vf ab zntvp ...
+%
+Pynhqr oryvrirq gung bayl fzneg nggenpgvir crbcyr unq gur evtug gb
+shpx, naq vg fvapreryl uheg uvz jura ur qvfpbirerq rivqrapr gb gur
+pbagenel.
+ -- Gbz Eboovaf
+%
+PYBAR BS ZL BJA (gb Ubzr ba gur Enatr)
+
+Bu, tvir zr n pybar
+Bs zl bja syrfu naq obar
+ Jvgu gur L puebzbfbzr punatrq gb K.
+Naq jura fur vf tebja,
+Zl irel bja pybar,
+ Jr'yy or bs gur bccbfvgr frk.
+
+Pubehf:
+ Pybar, pybar bs zl bja,
+ Jvgu gur L puebzbfbzr punatrq gb K.
+ Naq jura jr'er nybar,
+ Fvapr ure zvaq vf zl bja,
+ Fur'yy or guvaxvat bs abguvat ohg frk.
+ -- Enaqnyy Tneergg
+%
+Pbpnvar vf angher'f jnl bs gryyvat lbh lbh unir gbb zhpu zbarl.
+%
+Pbvgb retb fhz
+%
+Pbyyrtr vf yvxr n jbzna -- lbh jbex fb uneq gb trg va, naq avar zbaguf
+yngre lbh jvfu lbh'q arire pbzr.
+%
+Pbzzhavfgf qb vg jvgubhg pynff.
+%
+Pbaqbzf ner yvxr yvfgravat gb n flzcubal jvgu pbggba va lbhe rnef.
+%
+Pbafreingvir, a.:
+ Bar jub nqzverf enqvpnyf praghevrf nsgre gurl'er qrnq.
+ -- Yrb P. Ebfgra
+%
+Pbafreir raretl -- znxr ybir zber fybjyl.
+%
+Phaavyvathf vf arkg gb tbqyvarff.
+%
+Qnzzvg, ubj znal gvzrf qb V unir gb gryy lbh? _____SVEFG lbh encr, ____GURA lbh
+cvyyntr!!
+%
+Qrne Ybeq, bofreir guvf oraqrq xarr
+Guvf ivfntr zrrx naq uhzoyr,
+Naq urne guvf pbasvqragvny cyrn
+Ibvprq va erirerag zhzoyr:
+ Tvir zr Fulybpx, tvir zr Sntva
+ Ohg B Tbq fcner zr Ebanyq Erntna!
+ -- Nafry Nqnzf
+%
+"Qrne Ze. Fryqrf: V pnaabg erzrzore gur rknpg jbeqvat bs gur fgngrzrag
+gb juvpu lbh nyyhqr; ohg jung V zrnag jnf gung ... n zna jub pnyyf
+uvzfrys n 100% Nzrevpna naq vf cebhq bs vg, vf trarenyyl 150% na vqvbg
+cbyvgvpnyyl. Ohg gur qrfvtangvbaf znl or tbbq ohfvarff sbe jne
+irgrenaf. Univat oyrq sbe gurve pbhagel va 1861 naq 1918, gurl unir
+oyrq vg nyy gurl pbhyq pbafrdhragyl. Naq jul abg?"
+ -- Trbetr Fryqrf, "Gur Terng Dhbgngvbaf"
+%
+Qrzbpenpl pna yrnea fbzr guvatf sebz Pbzzhavfz: sbe rknzcyr, jura n
+Pbzzhavfg cbyvgvpvna vf guebhtu, ur vf guebhtu.
+%
+Qrzbpenpl zrnaf fvzcyl gur oyhqtrbavat bs gur crbcyr ol gur crbcyr sbe
+gur crbcyr.
+ -- Bfpne Jvyqr
+%
+Qvq lbh urne nobhg gur arj Trezna zvpebjnir bira?
+
+ ... Frngf 500.
+%
+Qvq lbh xabj gung Fcveb Ntarj vf na nantenz bs "Tebj n Cravf"
+%
+Qvq lbh xabj gung gurer ner 71.9 nperf bs avccyr gvffhr va gur H.F.?
+%
+[Qvfgevpg Nggbearlf] yrnea va Qvfgevpg Nggbearl Fpubby gung gurer ner
+gjb fher-sver jnlf gb trg n ybg bs snibenoyr choyvpvgl:
+
+(1) Tb qbja naq envq nyy gur ybpxref va gur ybpny uvtu fpubby naq
+ pbasvfpngr 53 znevwhnan pvtnerggrf naq chg gurz va n cvyr naq ubyq
+ n cerff pbasrerapr jurer lbh naabhapr gung gurl unir n fgerrg inyhr
+ bs $850 zvyyvba. Gurfr envqf arire snvy, orpnhfr NYY uvtu fpubbyf,
+ vapyhqvat oenaq-arj, arire-hfrq barf, unir ng yrnfg 53 znevwhnan
+ pvtnerggrf va gur ybpxref. Nf sne nf nalbar pna gryy, gur ybpxre
+ snpgbel chgf gurz gurer.
+(2) Envq na "nqhyg obbx fgber" naq ubyq n cerff pbasrerapr jurer lbh
+ naabhapr lbh ner punetvat gur bjare jvgu 850 pbhagf bs orvat n
+ cvrpr bs uhzna fyrnmr. Guvf nyfb arire snvyf, orpnhfr lbh nyjnlf
+ trg n pbaivpgvba. N whebe ng n cbeabtencul gevny vf abg nobhg gb
+ fgngr sbe gur erpbeq gung ur svaqf abguvat bofprar nobhg n zbivr
+ jurer npgbef ratntr va frkhny npgvivgvrf jvgu yvir fanxrf naq n
+ sver rkgvathvfure. Ur vf tbvat gb pbaivpg gur obbxfgber bjare, naq
+ ibgr sbe gur qrngu cranygl whfg gb znxr fher abobql trgf gur jebat
+ vzcerffvba.
+ -- Qnir Oneel, "Cbeabtencul"
+%
+Qb fbzrguvat ovt -- shpx n tvnag
+%
+"Qb lbh purng ba lbhe jvsr?" nfxrq gur cflpuvngevfg.
+"Jub ryfr?" nafjrerq gur cngvrag.
+%
+Qbpgbef gnxr gjb nfcveva naq qb vg va gur zbeavat.
+%
+"Qba'g yrg lbhe zbhgu jevgr ab purpx gung lbhe gnvy pna'g pnfu."
+ -- Ob Qvqqyrl
+%
+Qbcr jvyy trg lbh guebhtu gvzrf bs ab zbarl orggre gung zbarl jvyy trg
+lbh guebhtu gvzrf bs ab qbcr.
+ -- Tvyoreg Furygba
+%
+Qensg orre, abg crbcyr
+%
+Rng gur evpu -- gur cbbe ner gbhtu naq fgevatl.
+%
+Rvfraubjre jnf irel avpr,
+Avkba jnf uvf bayl ivpr.
+ -- P. Qrtra
+%
+Ryrira ernfbaf n phphzore vf orggre guna n zna:
+ (1) Phphzoref pna fgnl hc nyy avtug, naq lbh jba'g unir gb
+ fyrrc va gur jrg fcbg.
+ (2) Phphzoref qba'g cynl gur thvgne naq gel gb svaq
+ gurzfryirf.
+ (3) Lbh jba'g svaq bhg yngre gung lbhe phphzore (n) vf
+ zneevrq, (o) vf ba cravpvyyva, (p) yvxrf lbh -- ohg ybirf
+ lbhe oebgure!
+ (4) N phphzore jba'g pner jung gvzr bs gur zbagu vg vf.
+ (5) N phphzore arire jnagf gb trg vg ba jura lbhe anvyf ner
+ jrg.
+ (6) Phphzoref qba'g fnl "Yrg'f xrrc gelvat hagvy jr unir n
+ obl".
+ (7) Phphzoref jba'g gryy lbh fvmr qbrfa'g pbhag.
+ (8) N phphzore jba'g yrnir lbh sbe n purreyrnqre be na rk-aha.
+ (9) Phphzoref qba'g snyy nfyrrc ba lbhe purfg be qebby ba gur
+ cvyybj.
+ (10) Phphzoref qba'g pner vs lbh znxr zber zbarl guna gurl qb.
+ (11) Jvgu n phphzore, gur gbvyrg frng vf nyjnlf gur jnl lbh
+ yrsg vg.
+%
+Rdhnyvgl vf abg jura n srznyr Rvafgrva trgf cebzbgrq gb nffvfgnag
+cebsrffbe; rdhnyvgl vf jura n srznyr fpuyrzvry zbirf nurnq nf snfg nf n
+znyr fpuyrzvry.
+ -- Rjnyq Aldhvfg
+%
+Rinatryvfgf qb vg jvgu Uvz jngpuvat.
+%
+"Rira abjnqnlf n zna pna'g fgrc hc naq xvyy n jbzna jvgubhg srryvat
+whfg n ovg hapuvinyebhf ..."
+ -- Eboreg Orapuyrl
+%
+Srzvavfgf fnl 60 creprag bs gur pbhagel'f jrnygu vf va gur unaqf bs
+jbzra. Gurl'er yrggvat zra ubyq gur bgure 40 creprag orpnhfr gurve
+unaqontf ner shyy.
+ -- Rney Jvyfba
+%
+Svr sbe funzr, lbh ynfpvivbhf, yrjq, yrpurebhf, yvovqvabhf, yhfgshy,
+yvpragvbhf, qvegl ohz!!
+%
+Sybccl abj, uneq yngre.
+%
+Sbe gubfr bs lbh ubj unir orra ybbxvat sbe rivqrapr gung n jbexvat
+irefvba bs "Fgne Jnef" pna or ohvyg, pbafvqre gur sbyybjvat cebbs
+bssrerq ol Pnfcne Jrvaoretre:
+
+ "Vs fhpu n flfgrz vf fb hanggnvanoyr, jul unir gur Fbivrgf orra
+ jbexvat qrfcrengryl gb trg vg sbe bire 17 lrnef?"
+
+ -- HFN Gbqnl, 24 Whar 1986
+%
+Sbeavpngvba, a.:
+ Grez hfrq ol crbcyr jub qba'g unir nalobql gb fperj jvgu.
+%
+Sbeghar'f Erny-Yvsr Pbhegebbz Dhbgr #25:
+
+D: Lbh fnl lbh unq guerr zra chapuvat ng lbh, xvpxvat lbh, encvat lbh,
+ naq lbh qvqa'g fpernz?
+N: Ab zn'nz.
+D: Qbrf gung zrna lbh pbafragrq?
+N: Ab, zn'nz. Gung zrnaf V jnf hapbafpvbhf.
+%
+Trbetr Jnfuvatgba abg bayl pubccrq qbja uvf sngure'f pureel gerr, ohg
+ur nyfb nqzvggrq qbvat vg. Abj, qb lbh xabj jul uvf sngure qvqa'g
+chavfu uvz? Orpnhfr Trbetr fgvyy unq gur nkr va uvf unaq.
+%
+Trggvat na rqhpngvba ng gur Havirefvgl bs Pnyvsbeavn vf yvxr univat
+$50.00 fubirq hc lbhe nff, n avpxry ng n gvzr.
+%
+"Tb gb Urnira sbe gur pyvzngr, Uryy sbe gur pbzcnal."
+ -- Znex Gjnva
+%
+ "Tbq ohvyg n pbzcryyvat frk qevir vagb rirel perngher, ab
+znggre jung fglyr bs shpxvat vg cenpgvprq. Ur znqr frk veerfvfgvoyl
+cyrnfhenoyr, jvyqyl wblbhf, serr sebz srnef. Ur znqr vg vaabprag
+zreevzrag.
+ "Arrqyrff gb fnl, shpxvat jnf na vzzrqvngr fznfu uvg. Rirelbar
+nterrq, sebz nneqinexf gb mroenf. Nyy gur wbyyl navznyf -- yvbaf naq
+ynzof, euvabprebfrf naq tnmryyrf, fxlynexf naq ybofgref, rira vafrpgf,
+gubhtu zbfg bs gurz shpx bayl bapr va n yvsrgvzr -- shpxrq nybat
+vaabpragyl naq zreevyl sbe uhaqerqf bs zvyyvbaf bs lrnef. Znlor gurl
+jrer qhzo navznyf, ohg gurl xarj n tbbq guvat jura gurl unq bar."
+ -- Nyna Furezna, "Gur Encr bs gur N*C*R*"
+%
+Tbq tvirf hf eryngvirf; gunax tbbqarff jr pna pubfr bhe sevraqf.
+%
+Tbq vf na ngurvfg.
+%
+TBQ vf nccyvrq CBJRE
+ juvpu vf nccyvrq TBIREAZRAG
+ juvpu vf nccyvrq CBYVGVPF
+ juvpu vf nccyvrq NQIREGVFVAT
+ juvpu vf nccyvrq FBPVBYBTL
+ juvpu vf nccyvrq CFLPUBYBTL
+ juvpu vf nccyvrq OVBYBTL
+ juvpu vf nccyvrq PURZVFGEL
+ juvpu vf nccyvrq CULFVPF
+ juvpu vf nccyvrq ZNGU
+ juvpu vf nccyvrq CUVYBFBCUL
+ juvpu vf nccyvrq OHYYFUVG
+%
+"Tbq vf nf erny nf V nz," gur byq zna fnvq. Zl snvgu jnf erfgberq, sbe
+V arj gung Fnagn jbhyq arire yvr.
+%
+"Tbq vf ovt, fb qba'g shpx jvgu uvz."
+%
+Tbq vfa'g qrnq -- ur'f orra ohfgrq
+%
+Tbq vfa'g qrnq, Ur'f whfg gelvat gb nibvq gur qensg.
+%
+Tbq zhfg ybir nffubyrf -- Fur znqr fb znal bs gurz.
+%
+Tbq jnagrq gb unir n ubyvqnl, fb Ur nfxrq Fg. Crgre sbe fhttrfgvbaf ba
+jurer gb tb.
+ "Jul abg tb gb Whcvgre?" nfxrq Fg. Crgre.
+ "Ab, gbb zhpu tenivgl, gbb zhpu fgbzcvat nebhaq," fnvq Tbq.
+ "Jryy, ubj nobhg Zrephel?"
+ "Ab, vg'f gbb ubg gurer."
+ "Bxnl," fnvq Fg. Crgre, "Jung nobhg Rnegu?"
+ "Ab," fnvq Tbq, "Gurl'er fhpu ubeevoyr tbffvcf. Jura V jnf
+gurer 2000 lrnef ntb, V unq na nssnve jvgu n Wrjvfu jbzna, naq gurl'er
+fgvyy gnyxvat nobhg vg."
+%
+Tbbq qnl sbe jngre fcbegf. Gnxr n ongu jvgu n sevraq.
+%
+Tenva tebjf orfg va fuvg
+ -- Hefhyn X. YrThva
+%
+Tenivgl vf na hasbetvivat zbgureshpxre.
+%
+Terng Ybire, a.:
+ N zna jub pna oerngur guebhtu uvf rnef.
+%
+Unpxref qb vg jvgu nyy fbegf bs punenpgref.
+%
+Unpxref qb vg jvgu ohtf.
+%
+Unpxref qb vg jvgu srjre vafgehpgvbaf.
+%
+Unpxref xabj nyy gur evtug ZBIf.
+%
+Unttvf, a.:
+ Unttvf vf n xvaq bs fghss oynpx chqqvat rngra ol gur Fpbgf naq
+pbafvqrerq ol gurz gb or abg bayl n qryvpnpl ohg svg sbe uhzna
+pbafhzcgvba. Gur zvaprq urneg, yvire naq yhatf bs n furrc, pnys be
+bgure navzny'f vaare betnaf ner zvkrq jvgu bngzrny, frnyrq naq obvyrq
+va znj va gur furrc'f vagrfgvany fgbznpu-ont naq ... Rkphfr zr n zvahgr ...
+%
+Uneqyl n cher fpvrapr, uvfgbel vf pybfre gb navzny uhfonaqel guna vg vf
+gb zngurzngvpf, va gung vg vaibyirf fryrpgvir oerrqvat. Gur cevapvcny
+qvssrerapr orgjrra gur uhfonaqelzna naq gur uvfgbevna vf gung gur
+sbezre oerrqf furrc be pbjf be fhpu, naq gur ynggre oerrqf (nffhzrq)
+snpgf. Gur uhfonaqelzna hfrf uvf fxvyyf gb raevpu gur shgher; gur
+uvfgbevna hfrf uvf gb raevpu gur cnfg. Obgu ner hfhnyyl hc gb gurve
+naxyrf va ohyyfuvg.
+ -- Gbz Eboovaf
+%
+Univat qvfpbirerq gur cbffvovyvgl gung bgure perngherf pbhyq or hfrq
+sbe frkhny vagrepbhefr, rneyl zna jnf yvxryl gb unir znqr znal fhpu
+nggrzcgf ... gubhtu vg vf qbhogshy gung ur jnf fb frkhnyyl pneavibebhf
+nf gur Puevfgvna naq Wrjvfu Nqnz, jub, enoovavpny vagrecergref bs gur
+Byq Grfgnzrag gryy hf, unq vagrepbhefr jvgu rirel perngher orsber Tbq
+svanyyl uvg hcba gur vqrn bs jbzna naq perngrq Rir.
+ -- E. R. Znfgref
+%
+"Ur pbhyq or n cbfgre puvyq sbe ergebnpgvir ovegu pbageby."
+%
+Ur ungrq gb zraq, fb lbhat Arq
+Pnyyrq va n phgr arvtuobe vafgrnq.
+ Ure uhfonaq fnvq, "Iv,
+ Jura lbh fgvgpurq hc uvf gbea syl,
+Qvq lbh unir gb ovgr bss gur guernq?"
+%
+Ur jnfa'g zhpu bs na npgbe, ur jnfa'g zhpu bs n Tbireabe -- Uryy, gurl
+_U_N_Q gb znxr uvz Cerfvqrag bs gur Havgrq Fgngrf. Vg'f gur bayl wbo ur'f
+dhnyvsvrq sbe!
+ -- Zvpunry Pnva
+%
+Ur jub svaqrgu frafhbhf cyrnfherf va gur obqvrf bs yhfu, ubg, cvax
+qnzfryf vf abg evtugrbhf, ohg ur pna unir n ybg zber sha.
+%
+Ur jub farrmrf jvgubhg n unaqxrepuvrs gnxrf znggref vagb uvf bja
+unaqf.
+%
+"Ur'f abg cvavat, ur'f cnffrq ba! Guvf cneebg jba'g fdhnjx! Ur'f
+prnfrq gb or! Ur'f rkcverq, naq tbar gb zrrg uvf znxre! Vg'f n
+fgvss! Ab oerngu bs yvsr, ur znl erfg va crnpr! Vs lbh unqa'g anvyrq
+uvz gb gur crepu, ur'q or chfuvat hc gur qnvfvrf! Ur'f bss gur gjvt!
+Ur'f xvpxrq gur ohpxrg! Ur'f pheyrq hc uvf gbbgvrf! Ur'f fuhssyrq bss
+guvf zbegny jbeyq! Ur'f eha qbja gur phegnva, naq wbvarq gur oyrrq'a
+Pubve Vaivapvoyr! UR'F SHPXVAT FAHSSRQ VG! Ivf-n-iv uvf zrgnobyvp
+cebprffrf vf urnq vf ybfg. Nyy fgngrzragf pbapreavat guvf cneebg vf ab
+ybatre n tbvat pbaprea, nsgre sebz abj ba, Vabcrengvir...
+
+ GUVF VF NA RK-CNEEBG!!
+%
+Ure svther qrfpevorq n frg bs cnenobynf gung pbhyq pnhfr pneqvnp neerfg
+va n lnx.
+ -- Jbbql Nyyra
+%
+Ure xvffrf yrsg fbzrguvat gb or qrfverq -- gur erfg bs ure.
+%
+Urer vf gur ceboyrz: sbe znal lrnef, gur Fhcerzr Pbheg jerfgyrq jvgu
+gur vffhr bs cbeabtencul, hagvy svanyyl Nffbpvngr Whfgvpr Wbua Cnhy
+Fgriraf pnzr hc jvgu gur snzbhf dhbgngvba nobhg ubj ur pbhyqa'g qrsvar
+cbeabtencul, ohg ur xarj vg jura ur fnj vg. Fb sbe n juvyr, gur
+pbheg'f cbyvpl jnf gb unir nyy gur fhfcrpgrq cbeabtencul gehpxrq gb
+Whfgvpr Fgriraf' ubhfr, jurer ur jbhyq ybbx vg bire. "Abcr, guvf vfa'g
+vg," ur'q fnl. "Oevat fbzr zber." Guvf jrag ba hagvy bar zbeavat jura
+uvf ubhfrxrrcre sbhaq uvz genccrq va gur erperngvba ebbz haqre na
+rabezbhf zbhaq bs ehoorevmrq vzcyrzragf, naq gur pbheg unq gb vffhr n
+ehyvat fgngvat gung vg qvqa'g xabj jung gur uryy cbeabtencul jnf rkprcg
+gung vg jnf vyyrtny naq rirelobql fubhyq fgbc onqtrevat gur pbheg nobhg
+vg orpnhfr gur pbheg jnf tbvat gb gnxr n anc.
+ -- Qnir Oneel, "Cbeabtencul"
+%
+"Urer'f gur ubyvqnl fpurqhyr sbe Zbaqnl'f bofreingvba bs Znegva Yhgure
+Xvat We.'f oveguqnl, jura gur sbyybjvat jvyy or pybfrq:
+
+ * Tbireazragny bssvprf
+ * Cbfg bssvprf
+ * Yvoenevrf
+ * Fpubbyf
+ * Onaxf
+ * Cnegf bs Cnyz Ornpu
+
+naq gur zvaq bs Frangbe Wrffr Uryzf bs Abegu Pnebyvan."
+ -- Qraavf Zvyyre, "Fngheqnl Avtug Yvir"
+%
+Uvfgbel unf gur eryngvba gb gehgu gung gurbybtl unf gb eryvtvba --
+v.r., abar gb fcrnx bs.
+ -- Ynmnehf Ybat
+%
+"Ubj qb lbh yvxr gur arj Nzrevpn? Jr'ir phg gur sng bhg bs gur
+tbireazrag, naq zber erpragyl gur urneg naq oenva (gur onpxobar jnf
+tbar fbzr gvzr ntb). Nyy jr frrz gb unir yrsg abj vf zhfpyr. Jr'yy or
+yhpxl gb rfpncr jvgu bhe fxvaf!"
+%
+Ubjneq Pbfryy'f ovttrfg cebgehfvba vf uvf nffubyr
+ -- Wbua Inyol
+%
+Uhtu Ursare vf n ivetva.
+%
+V nz na ngurvfg, gunax Tbq!
+%
+V oryvrir gung Ebanyq Erntna jvyy fbzrqnl znxr guvf pbhagel jung vg
+bapr jnf ... na nepgvp jvyqrearff
+ -- Fgrir Znegva
+%
+V pnzr; V fnj; V shpxrq hc
+%
+V unir n shaal qnqql
+Jub tbrf va naq bhg jvgu zr
+Naq rirelguvat gung onol qbrf
+Qnqql'f fher gb frr,
+Naq rirelguvat gung onol fnlf,
+Zl qnqql'f fher gb gryy.
+Lbh _z_h_f_g unir ernq zl qnqql'f irefr.
+V ubcr ur sevrf va Uryy.
+ -- Btqra Anfu
+%
+V ybir guvf shpxvat Havirefvgl, naq guvf Havirefvgl ybirf shpxvat zr.
+%
+V bapr zrg n ynffvr anzrq Ehgu
+Va n ybat qvfgnapr gryrcubar obbgu.
+ Abj V xabj gur cresrpgvba
+ Bs na vqrny pbaarpgvba
+Rira vs fbzrjung hapbhgu.
+%
+"V bja zl bja obql, ohg V funer"
+%
+V ernyvmr gung gbqnl lbh unir n ahzore bs gbc srznyr nguyrgrf fhpu nf
+Znegvan Aniengvybin jub pna eha yvxr qrre naq orapu-cerff Puriebyrg
+gehpxf. Ohg gb or oehgnyyl senax, jbzra nf n tebhc unir n ybat jnl gb
+tb orsber gurl ernpu gur yriry bs vagrafvgl naq qrqvpngvba gb fcbegf
+gung ranoyrf zra gb or fhpu vaperqvoyr wrexf nobhg vg.
+ -- Qnir Oneel, "Fcbegf vf n Qent"
+%
+V erterg gb fnl gung jr bs gur S.O.V. ner cbjreyrff gb npg va pnfrf bs
+beny-travgny vagvznpl, hayrff vg unf va fbzr jnl bofgehpgrq vagrefgngr
+pbzzrepr.
+ -- W. Rqtne Ubbire
+%
+V guvax rirel tbbq Puevfgvna bhtug gb xvpx Snyjryy evtug va gur nff.
+ -- Oneel Tbyqjngre
+%
+V guvax cbc zhfvp unf qbar zber sbe beny vagrepbhefr guna nalguvat ryfr
+gung unf rire unccrarq, naq ivpr irefn.
+ -- Senax Mnccn
+%
+V jnyxrq ba gbjneq Cybhtujevtug, guvaxvat nobhg srprf. Jung n ybg jr
+unq sbhaq bhg nobhg gur ceruvfgbevp cnfg sebz gur fghql bs sbffvyvmrq
+qhat bs ybat-inavfurq navznyf. N zvenphybhf guvat, ernyyl; n erpbirel
+sebz gur cnfg sebz jung jnf pneryrffyl erwrpgrq. Naq va gur Zvqqyr
+Ntrf, ubj pbaprearq crbcyr jub yvirq pybfr gb gur jbeyq bs angher jrer
+jvgu gur srprf bs navznyf. Naq jung n inevrgl bs anzrf gurl unq sbe
+gurz: gur Pebgryf bs n Uner, gur Sevnagf bs n Obne, gur Fcenvagf bs
+na Bggre, gur Jreqrebor bs n Onqtre, gur Jnttlvat bs n Sbk, gur Shzrgf
+bs n Qrre. Fheryl gurer zvtug or fbzr jbeqf sbe gur zngrevny fb arne
+gb gur urneg bs Bml Sebngf [na npnqrzvp fghqlvat srprf] guna fuvg?
+Jung nobhg gur Ceboyrzf bs n Cerfvqrag, gur Onpxjneq Cnffrf bs n
+Sbbgonyyre, gur Qrsreenyf bs n Qrna, gur Bqq Ibyhzrf bs n Yvoenevna,
+gur Sbbgabgrf bs n Cu.Q., gur Ybj Tenqrf bs n Serfuzna, gur Nakvrgvrf
+bs na Hagraherq Cebsrffbe?
+ -- Eboregfba Qnivrf, "Gur Erory Natryf"
+%
+V jbhyq yvxr gb fhttrfg gung lbh abg hfr fcrrq, naq urer'f jul: vg vf
+tbvat gb zrff hc lbhe urneg, zrff hc lbhe yvire, lbhe xvqarlf, ebg bhg
+lbhe zvaq. Va trareny guvf qeht jvyy znxr lbh whfg yvxr lbhe zbgure
+naq sngure.
+ -- Senax Mnccn
+%
+V jbhyqa'g zvaq qlvat -- vg'f gung ohfvarff bs univat gb fgnl qrnq gung
+fpnerf gur fuvg bhg bs zr.
+ -- E. Trvf
+%
+V'q yvxr gb zrrg gur zna jub vairagrq frk naq frr jung ur'f jbexvat ba
+abj.
+%
+V'z sbe crnpr -- V'ir lrg gb frr n zna jnxr hc va gur zbeavat naq fnl
+"V'ir whfg unq n tbbq jne."
+ -- Znr Jrfg
+%
+V'z tbvat gb Vbjn sbe na njneq. Gura V'z nccrnevat ng Pneartvr Unyy,
+vg'f fbyq bhg. Gura V'z fnvyvat gb Senapr gb or ubaberq ol gur Serapu
+tbireazrag -- V'q tvir vg nyy hc sbe bar rerpgvba.
+ -- Tebhpub Znek
+%
+"V'ir unq bar puvyq. Zl uhfonaq jnagf gb unir nabgure. V'q yvxr gb
+jngpu uvz unir nabgure."
+%
+Vs n puvyq naablf lbh, dhvrg uvz ol oehfuvat uvf unve. Vs guvf qbrfa'g
+jbex, hfr gur bgure fvqr bs gur oehfu ba gur bgure raq bs gur puvyq.
+%
+Vs nyy gurfr fjrrg lbhat guvatf jrer ynvq raq-gb-raq, V jbhyqa'g or n
+ovg fhecevfrq.
+ -- Qbebgul Cnexre
+%
+"Vs nalbar jnagf gb genqr n pbhcyr bs pragenyyl ybpngrq, jryy-phfuvbarq
+fubjtveyf sbe na rebqrq fybcr 90 zvahgrf sebz Oebnqjnl, V'yy or ba guvf
+pbeare gbzbeebj ng 11 jvgu zl gbathr unatvat bhg."
+ -- F. W. Creryzna
+%
+Vs pyrne guvaxvat perngrq fcnexf, jr pbhyq fnsryl fgber qlanzvgr va
+Wnzrf Jngg'f bssvpr.
+ -- Jnlar Funaaba, XEBA-GI
+%
+"Vs Tbq unq jnagrq hf gb hfr gur zrgevp flfgrz, Wrfhf jbhyq unir unq 10
+ncbfgyrf."
+%
+Vs thaf ner bhgynjrq, ubj jvyy jr fubbg gur yvorenyf?
+%
+Vs Uryra Xryyre vf nybar va n sberfg naq snyyf, qbrf fur znxr n fbhaq?
+%
+Vs zra pbhyq trg certanag, nobegvba jbhyq or n fnpenzrag.
+%
+Vs Erntna vf gur nafjre, vg zhfg unir orra n IREL fvyyl dhrfgvba.
+%
+Vs fbzrbar jrer gb nfx zr sbe n fubeg phg gb frafhnyvgl, V jbhyq
+fhttrfg ur tb fubccvat sbe n hfrq 427 Furyol-Pboen. Ohg vg vf bayl
+snve gb jnea lbh gung bs gur 300 thlf jub fjvgpurq gb gurz va 1966,
+bayl gjb jrag onpx gb jbzra.
+ -- Zbeg Fnuy
+%
+Vs gur Nzrevpna qernz vf sbe Nzrevpnaf bayl, vg jvyy erznva bhe qernz
+naq arire or bhe qrfgval.
+ -- Era'r qr Ivfzr Jvyyvnzfba
+%
+Vs lbh pna oryvrir gra vzcbffvoyr guvatf orsber oernxsnfg, gura lbh
+fubhyq wbva
+
+ GUR PUHEPU BS PBHAGRESNPGHNY ORYVRS
+
+Gur Puhepu bs Pbhagresnpghny Oryvrs unf orra frg hc gb pngre gb nyy jub
+qba'g nyybj qrzbafgenoyr gehgu gb trg va gur jnl bs gurve oryvrsf. Va
+nqqvgvba gb perngvba fpvrapr naq gur syngarff bs gur rnegu, gur
+sbyybjvat oryvrsf unir orra pregvsvrq ol Cbcr Qhnar nf Puhepu qbtzn:
+
+ -- Gung gurer vf n ubyr va gur Rnegu ng gur Abegu Cbyr sebz juvpu
+ HSBf pbzr.
+ -- Gung cv rdhnyf cerpvfryl 3.000.
+ -- Gung frk pna or rawblrq bayl ol oynpxf naq ubzbfrkhnyf.
+ -- Gung Ovyyl Wbr Jvyfba (Ubbcyn, Zvff.) unf fhpprffshyyl fdhnerq
+ gur pvepyr.
+ -- Gung Uneel Gehzna vf fgvyy cerfvqrag, naq qbvat n svar wbo.
+ -- Gung cv rdhnyf cerpvfryl 22/7.
+
+Frireny bgure vzcbegnag pbhagresnpghny oryvrsf ner cerfragyl orvat
+fghqvrq, vapyhqvat Erntnabzvpf, N.V., naq gung gur zbba ynaqvatf jrer
+qbar va n Ubyyljbbq fcrpvny rssrpgf fghqvb. Gurfr jvyy or gur fhowrpg
+bs n sbegupbzvat Cncny Ohyy ...
+%
+Vs lbh zrrg fbzrobql jub gryyf lbh gung ur ybirf lbh zber guna nalobql
+va gur jubyr jvqr jbeyq, qba'g gehfg uvz. Vg zrnaf ur rkcrevzragf.
+%
+Vs lbh guvax frk vf n cnva va gur nff, gel qvssrerag cbfvgvba.
+%
+"Vs lbh'er n erny tbbq xvq, V'yy tvir lbh n cvttl-onpx evqr ba n
+ohmm-fnj."
+ -- J. P. Svryqf
+%
+Vtabenapr vf gur Zbgure bs Qribgvba.
+ -- Eboreg Ohegba
+%
+"Va Puevfgvnavgl arvgure zbenyvgl abe eryvtvba pbzr vagb pbagnpg jvgu
+ernyvgl ng nal cbvag."
+ -- Sevrqevpu Avrgmfpur
+%
+ Va gur ortvaavat jnf gur QRZB Cebwrpg. Naq gur Cebwrpg jnf
+jvgubhg sbez. Naq qnexarff jnf hcba gur fgnss zrzoref gurerbs. Fb
+gurl fcnxr hagb gurve Qvivfvba Urnq, fnlvat, "Vg vf n pebpx bs fuvg,
+naq vg fgvaxf."
+
+ Naq gur Qvivfvba Urnq fcnxr hagb uvf Qrcnegzrag Urnq, fnlvat,
+"Vg vf n pebpx bs rkperzrag naq abar znl novqr gur bqbe gurerbs." Abj,
+gur Qrcnegzrag Urnq fcnxr hagb uvf Qverpgbengr Urnq, fnlvat, "Vg vf n
+pbagnvare bs rkperzrag, naq vf irel fgebat, fhpu gung abar znl novqr
+orsber vg." Naq vg pnzr gb cnff gung gur Qverpgbengr Urnq fcnxr hagb
+gur Nffvfgnag Grpuavpny Qverpgbe, fnlvat, "Vg vf n irffry bs sregvyvmre
+naq abar znl novqr ol vgf fgeratgu."
+
+ Naq gur nffvfgnag Grpuavpny Qverpgbe fcnxr guhf hagb gur
+Grpuavpny Qverpgbe, fnlvat, "Vg pbagnvargu gung juvpu nvqf tebjgu naq
+vg vf irel fgebat." Naq, Yb, gur Grpuavpny Qverpgbe fcnxr gura hagb
+gur Pncgnva, fnlvat, "Gur cbjreshy arj Cebwrpg jvyy uryc cebzbgr gur
+tebjgu bs gur Ynobengbevrf."
+
+ Naq gur Pncgnva ybbxrq qbja hcba gur Cebwrpg, naq Ur fnj gung
+vg jnf Tbbq!
+%
+Va gur Tneqra bs Rqra fng Nqnz,
+Znffntvat gur ohfg bs uvf znqnz,
+ Ur puhpxyrq jvgu zvegu,
+ Sbe ur xarj gung ba rnegu,
+Gurer jrer bayl gjb obbof naq ur unq 'rz.
+%
+Vaprfg, a.:
+ Fvoyvat eriryel.
+%
+"Vf vg whfg zr, be qbrf nalbar ryfr ernq `ovoyr uhzcref' rirel gvzr
+fbzrbar jevgrf `ovoyr guhzcref?'
+ -- Wbry Z. Falqre, wzf@zvf.nevmban.rqh
+%
+Vg vf n fnq pbzzragnel ba gbqnl'f fbpvrgl gung guvf sbeghar unf gb or
+pynffvsvrq nf "bssrafvir" fvzcyl orpnhfr vg pbagnvaf gur jbeq "shpx".
+%
+"Vg fnlf ur znqr hf nyy gb or whfg yvxr uvz. Fb vs jr'er qhzo, gura
+tbq vf qhzo, naq znlor rira n yvggyr htyl ba gur fvqr."
+ -- Senax Mnccn
+%
+"Vg jnf n Ebzna jub fnvq vg jnf fjrrg gb qvr sbe bar'f pbhagel. Gur
+Terrxf arire fnvq vg jnf fjrrg gb qvr sbe nalguvat. Gurl unq ab ivgny
+yvrf."
+ -- Rqvgu Unzvygba, "Gur Terrx Jnl"
+%
+Wrfhf qvrq sbe lbhe fvaf. Znxr vg jbegu uvf gvzr.
+%
+"Wrfhf fnirf...ohg Tergmxl trgf gur erobhaq!"
+ -- Qnavry Uvabwbfn
+%
+Wrfhf jnf xvyyrq ol n Zbeny Znwbevgl.
+%
+Wbua Ovepu Fbpvrgl -- gung cngurgvp znavsrfgngvba bs betnavmrq
+ncbcyrkl.
+ -- Rqjneq C. Zbetna
+%
+Xnfun, a.:
+ Xnfun vf nyjnlf qrsvarq nf "ohpxjurng tebngf". Gurer'f bayl
+bar ceboyrz jvgu guvf qrsvavgvba: jung gur shpx ner "ohpxjurng
+tebngf"? *_V* xabj jung gurl ner -- gurl'er xnfun. Ohg gung qbrfa'g
+uryc *___lbh* zhpu.
+ -- Neguhe Anvzna, "Rirel Tbl'f Thvqr gb Lvqqvfu"
+%
+Xvyy n pbzzvr sbe Puevfg!
+%
+Ynvffrm Snver Rpbabzvpf vf gur gurbel gung vs rnpu npgf yvxr n ihygher,
+nyy jvyy raq nf qbirf.
+%
+Ynetr pngf pna or qnatrebhf, ohg n yvggyr chffl arire uheg nalbar.
+%
+YRG Wrfhf or LBHE napube!
+
+Fb jura Fngna ebpxf lbhe obng, GUEBJ Wrfhf bireobneq!
+%
+... Yrg zr gryy lbh jub gur npghny "sebag-ehaaref" ner. Ba bar fvqr,
+lbh unir Trbetr Ohfu, jub vf pheeragyl tbvat guebhtu n fbeg bs
+sengreavgl unmvat jurerva ur unf gb cresbez n frevrf bs uhzvyvngvat
+fghagf gb jva gur nccebiny bs gur Erchoyvpna Evtug. Sbe rknzcyr, gurl
+unq uvz znxr n fcrrpu bbmvat cenvfr nyy bire Jvyyvnz Ybro, qrprnfrq
+choyvfure bs gur Znapurfgre (A.U.) Havba Yrnqre naq Fyvzr Wbheanyvfg.
+Ybro unq qhzcrq ivpvbhfyl nyy bire Trbetr va gur 1980 Arj Unzcfuver
+cevznel. Ohg jura gur Evtug uryq n ovt gevohgr sbe Ybro, Trbetr pnzr
+onpx gb gur sbyq, yvxr n zna jvgu n ohatrr pbeq jenccrq nebhaq uvf
+arpx.
+ -- Qnir Oneel, "Gur Gjvaxvr naq gur Fdhvq"
+%
+Yvsr vf yvxr n cravf: jura vg'f fbsg lbh pna'g orng vg, naq jura vg'f
+uneq lbh trg shpxrq.
+%
+Yvfc unpxref unir gb or obhaq (gb-qb 'vg) ...
+%
+Yvivat va Ubyyljbbq vf yvxr yvivat va n objy bs tenabyn. Jung nva'g
+sehvgf naq ahgf vf synxrf.
+%
+Ybir qbrf abg znxr gur jbeyq tb nebhaq, whfg hc naq qbja n ovg.
+%
+Zngurzngvpvnaf qb vg va gurbel.
+%
+Zngurzngvpvnaf gnxr vg gb gur yvzvg.
+%
+Znl n qvfrnfrq lnx gnxr n yvxvat gb lbhe fvfgre.
+%
+Znl gur snvel tbq-pnzry yrnir n yhzc ba lbhe cvyybj!
+%
+Znlbe Ivaprag W. `Ohqql' Pvnapv ba gur NPYH'f fhvg gb unir n pvgl
+angvivgl fprar erzbirq:
+ "Gurl'er whfg wrnybhf orpnhfr gurl qba'g unir guerr jvfr zra
+naq n ivetva va gur jubyr betnavmngvba."
+%
+Zrtngba Zna: "YBBX ng gurz! Urycyrff, graqre perngherf, erylvat ba
+ ZR, jnvgvat sbe ZR gb znxr zl zbir!"
+
+(sebz orybj): "Zbir lbhe NFF, Sng-urnq!"
+
+Zrtngba Zna: "Vg vf n ZNAQNGR, naq V nz QHGL OBHAQ gb BORL!"
+%
+Zvffvbanel Cbfvgvba:
+ Gur zvffvbanel ba gbc.
+%
+"Zbfg yrtvfyngbef ner fb qhzo gung gurl pbhyqa'g cbhe cvff bhg bs n
+obbg vs gur vafgehpgvbaf jrer cevagrq ba gur urry."
+%
+Zbggb bs gur Ryrpgevpny Ratvarre:
+ Jbexvat pbzchgre uneqjner vf n ybg yvxr na rerpg cravf: vg
+fgnlf hc nf ybat nf lbh qba'g shpx jvgu vg.
+%
+Zl oebgure-va-ynj unf sbhaq n jnl gb znxr raqf zrrg. Ur tbrf nebhaq
+jvgu uvf urnq fghpx hc uvf nff.
+%
+"Zl pbhagel, evtug be jebat," vf n guvat gung ab cngevbg jbhyq guvax bs
+fnlvat rkprcg va n qrfcrengr pnfr. Vg vf yvxr fnlvat, "Zl zbgure,
+qehax be fbore."
+ -- T. X. Purfgregba
+%
+Zl sngure jnf n perbyr, uvf sngure n Arteb, naq uvf sngure n zbaxrl; zl
+snzvyl, vg frrzf, ortvaf jurer lbhef yrsg bss.
+ -- Nyrknaqer Qhznf, crer
+%
+ Zl Snibevgr Qehtf [Fhat gb Zl Snibevgr Guvatf]
+Errsref naq ebnpu pyvcf naq cncref naq ebyyref
+Pbpnvar naq cebpnvar sbe gjragl lrne zbynef
+Erqf naq crlbgr gb jbex bhg lbhe ohtf
+Gurfr ner n srj bs zl snibevgr qehtf.
+
+Hccref naq qbjaref naq zrgurqevar sernxbhg
+Gnxr fbzr nzcurgnzvarf, jngpu lbhe oenvaf yrnx bhg
+Npvq naq zrfpnyvar chyy bhg lbhe cyhtf
+Gurfr ner n srj bs zl snibevgr qehtf.
+
+Onpxf gung ner cresrpg sbe pneelvat zbaxrlf
+Hfref bs urebva, bsgra pnyyrq whaxvrf
+Zrgunqbar urycf gura gb fgbc orvat guhtf
+Gnxrf gurz bss bar bs zl snibevgr qehtf.
+
+ Ba n onq gevc
+ Jura gur pbcf pbzr
+ Jura V ybfr zl urnq
+ V fvzcyl gnxr zber bs zl snibevgr qehtf
+ Naq gura V'z abg fnq -- V'z qrnq!
+%
+ ARJ NQQVGVBA GB GUR YVOENEL:
+"Fnyyl", gur qrcnegzrag'f arj vasyngnoyr qbyy, vf ninvynoyr ba n
+fubeg-grez erzbiny onfvf bayl -- cyrnfr fvta ure bhg naq erghea ure
+cebzcgyl gb nibvq rkgraqrq jnvgf. (Jr ner fgvyy njnvgvat fuvczrag bs
+bhe "Ovt Wbua" qbyy.)
+%
+Ab jbzna pna pnyy urefrys serr hagvy fur pna pubbfr pbafpvbhfyl jurgure
+fur jvyy be jvyy abg or n zbgure.
+ -- Znetnerg U. Fnatre
+%
+"Abg bayl vf Tbq qrnq, ohg whfg gel gb svaq n cyhzore ba jrrxraqf."
+ -- Jbbql Nyyra
+%
+Abguvat vf orggre guna Frk.
+Znfgheongvba vf orggre guna abguvat.
+Gurersber, Znfgheongvba vf orggre guna Frk.
+%
+Ahxr gur tnl, haobea, onol junyrf sbe Wrfhf.
+%
+B'Evbeqna'f Gurberz:
+ Oenvaf k Ornhgl = Pbafgnag.
+
+Chezny'f Pbebyynel:
+ Nf gur yvzvg bs (Oenvaf k Ornhgl) tbrf gb vasvavgl,
+ninvynovyvgl tbrf gb mreb.
+%
+Bofpravgl vf gur pehgpu bs vanegvphyngr zbgureshpxref.
+%
+Bppvqrag, a.:
+ Gur cneg bs gur jbeyq ylvat jrfg (be rnfg) bs gur Bevrag. Vg
+vf ynetryl vaunovgrq ol Puevfgvnaf, cbjreshy fho-gevor bs gur
+Ulcbpevgrf, jubfr cevapvcny vaqhfgevrf ner zheqre naq purngvat, juvpu
+gurl ner cyrnfrq gb pnyy "jne" naq "pbzzrepr." Gurfr, nyfb, ner gur
+cevapvcny vaqhfgevrf bs gur Bevrag.
+ -- Nzoebfr Ovrepr, "Gur Qrivy'f Qvpgvbanel"
+%
+Bprna, a.:
+ N obql bs jngre bpphclvat nobhg gjb-guveqf bs n jbeyq znqr sbe
+zna -- jub unf ab tvyyf.
+%
+Bapr n lbhat tnl sebz Xunegbhz
+Gbbx n yrfovna hc gb uvf ebbz.
+ Gurl nethrq nyy avtug
+ Bire jub unq gur evtug
+Gb qb jung, naq jvgu juvpu, naq gb jubz.
+%
+Bapr hcba n gvzr, gurer jnf n aba-pbasbezvat fcneebj jub qrpvqrq abg gb
+syl fbhgu sbe gur jvagre. Ubjrire, fbba nsgre gur jrngure ghearq pbyq,
+gur fcneebj punatrq uvf zvaq naq eryhpgnagyl fgnegrq gb syl fbhgu.
+Nsgre n fubeg gvzr, vpr ortna gb sbez uvf ba uvf jvatf naq ur sryy gb
+rnegu va n onealneq nyzbfg sebmra. N pbj cnffrq ol naq penccrq ba guvf
+yvggyr oveq naq gur fcneebj gubhtug vg jnf gur raq, ohg gur znaher
+jnezrq uvz naq qrsebfgrq uvf jvatf. Jnez naq unccl gur yvggyr fcneebj
+ortna gb fvat. Whfg gura, n ynetr Gbz png pnzr ol naq urnevat gur
+puvecvat vairfgvtngrq gur fbhaqf. Nf Byq Gbz pyrnerq njnl gur znaher,
+ur sbhaq gur puvecvat oveq naq cebzcgyl ngr uvz.
+
+Gurer ner guerr zbenyf gb guvf fgbel:
+
+(1) Rirelbar jub fuvgf ba lbh vf abg arprffnevyl lbhe rarzl.
+(2) Rirelbar jub trgf lbh bhg bs fuvg vf abg arprffnevyl lbhe sevraq.
+(3) Vs lbh ner jnez naq unccl va n cvyr bs fuvg, xrrc lbhe zbhgu fuhg.
+%
+Bar qnl Cerfvqrag Erntna, Punvezna Naqebcbi, gur Cbcr, naq n obl fpbhg
+jrer sylvat gbtrgure va na nvecynar. Evtug bhg va gur zvqqyr bs
+abjurer gur cynar qrirybcrq ratvar gebhoyr naq fgnegrq gb tb qbja.
+Hasbeghangryl, bayl guerr cnenpuhgrf pbhyq or sbhaq sbe gur sbhe
+cnffratref! Naqebcbi tenoorq bar bs gur cnenpuhgrf naq qrpynerq
+"Pbzenqrf, nf yrnqre bs gur fbpvnyvfg jbexref eribyhgvba, zl yvsr zhfg
+or fcnerq," naq ur whzcrq bhg bs gur cynar. Gura Erntna rkpynvzrq "Nf
+yrnqre bs gur terngrfg angvba ba rnegu, V zhfg xrrc gur jbeyq fnsr sbe
+qrzbpenpl," naq jvgu gung ur gbb whzcrq gb fnsrgl. Abj vs lbh ner
+sbyybjvat nyy guvf (be pbhagvat ba lbhe svatref) lbh zhfg frr gung
+gurer vf bayl bar cnenpuhgr yrsg sbe gur gjb erznvavat cnffratref. Gur
+Cbcr ybbxrq xvaqyl hcba gur obl fpbhg naq fnvq "V unir unq n ybat naq
+cebqhpgvir yvsr, zl fba. Lbh gnxr gur cnenpuhgr naq yrnir zr va Tbq'f
+unaqf." "Gung'f irel xvaq bs lbh," gur bofreinag fpbhg ercyvrq, "ohg
+gurer vf ab arrq. Erntna whfg whzcrq bhg jvgu zl xancfnpx."
+%
+"Bar Fngheqnl nsgreabba, qhevat gur pnzcnvta gb qrpvqr jurgure be abg
+gurer fubhyq or n Pbnfgny Pbzzvffvba, V gbbx n uryvpbcgre evqr sebz Ybf
+Natryrf gb Fna Qvrtb. Jr cnffrq frireny fgngr ornpurf, fbzr pebjqrq
+naq fbzr iveghnyyl rzcgl. Gurl unq gur fnzr snpvyvgvrf, naq va fbzr
+pnfrf gur pebjqrq naq gur rzcgl ornpu jrer jvguva n dhnegre zvyr bs
+rnpu bgure. Boivbhfyl znal ornpu-tbref cersre gb or pebjqrq gbtrgure.
+Ohlvat zber ornpurf gung crbcyr jba'g tb gb orpnhfr gurl cersre gb or
+pebjqrq gbtrgure ba bar ornpu vf n evqvphybhf jnfgr bs bhe angheny
+erfbheprf naq bhe gnkrf."
+ -- Ebanyq Erntna
+%
+Bar guvat V unir ab jbeel nobhg vf jurgure Tbq rkvfgf. Ohg vg unf
+bppheerq gb zr gung Tbq unf Nymurvzre'f naq unf sbetbggra jr rkvfg.
+ -- Wnar Jntare, "Gur Frnepu sbe Fvtaf bs Vagryyvtrag
+ Yvsr va gur Havirefr"
+%
+Bcvavbaf ner yvxr nffubyrf -- rirelbar'f tbg bar, ohg abobql jnagf gb
+ybbx ng gur bgure thl'f.
+ -- Uny Uvpxzna
+%
+Bhe [fbsgonyy] grnz hfhnyyl chgf gur bgure jbzna ng frpbaq onfr, jurer
+gur znkvzhz cbffvoyr ahzore bs znyrf pna trg gurer ba fubeg abgvpr gb
+uryc bhg va pnfr bs rzretrapl. Nf sne nf V pna gryy, bhe frpbaq
+onfrjbzna vf n cerggl tbbq onfronyy cynlre, orggre guna V nz, naljnl,
+ohg gurer'f ab jnl gb xabj sbe fher orpnhfr vs gur onyy trgf naljurer
+arne ure, n znyr pbzrf onetvat bire sebz, fnl, evtug svryq, gb qrny
+jvgu vg. Fur'f orra ba gur grnz sbe guerr frnfbaf abj, ohg gur znyrf
+fgvyy qba'g gehfg ure. Gurl xabj, qrrc va gurve fbhyf, gung vs fur unq
+gb pubbfr orgjrra pngpuvat n syl onyy naq fnivat na vasnag'f yvsr, fur
+cebonoyl jbhyq ryrpg gb fnir gur vasnag'f yvsr, jvgubhg rire
+pbafvqrevat jurgure gurer jrer zra ba onfr.
+ -- Qnir Oneel, "Fcbegf vf n Qent"
+%
+"Bhe tbireazrag unf xrcg hf va n crecrghny fgngr bs srne -- xrcg hf va
+n pbagvahbhf fgnzcrqr bs cngevbgvp sreibe -- jvgu gur pel bs tenir
+angvbany rzretrapl... Nyjnlf gurer unf orra fbzr greevoyr rivy gb
+tbooyr hf hc vs jr qvq abg oyvaqyl enyyl oruvaq vg ol sheavfuvat gur
+rkbeovgnag fhzf qrznaqrq. Lrg, va ergebfcrpg, gurfr qvfnfgref frrz
+arire gb unir unccrarq, frrz arire gb unir orra dhvgr erny."
+ -- Trareny Qbhtynf ZnpNeguhe, 1957
+%
+ Bireurneq va n one:
+Zna: "Url, Onol, V'q fher yvxr gb trg va lbhe cnagf!"
+Jbzna: "Ab, gunaxf, V'ir nyernql tbg bar nff-ubyr va gurer abj."
+%
+Crbcyr jub qrirybc gur unovg bs guvaxvat bs gurzfryirf nf jbeyq
+pvgvmraf ner shysvyyvat gur svefg erdhverzrag bs fnavgl va bhe gvzr.
+ -- Abezna Pbhfvaf
+%
+Culfvpvfgf qb vg jvgu punez
+%
+Cbyvgvpvnaf qb vg gb rirelbar.
+%
+Cbfgrevgl jvyy ar're fheirl
+N aboyre tenir guna guvf;
+Urer yvr gur obarf bs Pnfgyrerntu;
+Fgbc, geniryre, naq cvff.
+ -- Ybeq Oleba, ba Ybeq Pnfgyrerntu
+%
+Cebpenfgvangbef qb vg gbzbeebj.
+%
+Cebfgvghgvba vf gur bayl ohfvarff jurer lbh pna tb vagb gur ubyr naq
+fgvyy pbzr bhg nurnq.
+%
+D: Ubj qb lbh cynl eryvtvbhf ebhyrggr?
+N: Lbh fgnaq nebhaq va n pvepyr naq oynfcurzr naq frr jub trgf fgehpx
+ ol yvtugavat svefg.
+%
+D: Ubj qb lbh gryy vs na Ryrcunag unf orra znxvat ybir va lbhe
+ onpxlneq?
+N: Vs nyy lbhe genfupna yvaref ner zvffvat ...
+%
+D: Ubj qb lbh gryy vs lbh'er znxvat ybir gb n ahefr, n fpubbygrnpure,
+ be na nveyvar fgrjneqrff?
+N: N ahefr fnlf: "Guvf jba'g uheg n ovg." N fpubbygrnpure fnlf:
+ "Jr'er tbvat gb unir gb qb guvf bire naq bire ntnva hagvy jr trg vg
+ evtug." Na nveyvar fgrjneqrff fnlf: "Whfg ubyq guvf bire lbhe
+ zbhgu naq abfr, naq oerngu abeznyyl."
+%
+D: Ubj znal evtug-gb-yvsref qbrf vg gnxr gb punatr n yvtug ohyo?
+N: Gjb. Bar gb fperj vg va naq bar gb fnl gung yvtug fgnegrq jura gur
+ fperjvat ortna.
+%
+D: Ubj znal fhccyl-fvqref qbrf vg gnxr gb punatr n yvtug ohyo?
+N: Abar. Gur qnexarff jvyy pnhfr gur yvtug ohyo gb punatr ol vgfrys.
+%
+D: Ubj zhpu zbarl qb lbh tvir gb n 900 sbbg Wrfhf?
+N: Nf zhpu nf ur jnagf.
+%
+D: Vs Gnemna jnf Wrjvfu, naq Wnar jnf n cevaprff, jung jbhyq Purrgnu
+ or?
+N: N she pbng.
+%
+D: Jung qb lbh qb jvgu na ryrcunag jvgu guerr onyyf?
+N: Jnyx uvz naq cvgpu gb gur euvab.
+%
+D: Jung qb lbh trg jura lbh pebff Wnzrf Qrna jvgu Ebanyq Erntna?
+N: N erory jvgubhg n pyhr.
+%
+D: Jung vf "FZBBECYNL"?
+N: Vg'f jung FZHESF qb orsber gurl FZHPX, bs pbhefr!
+%
+D: Jung vf gur jbefg fgbel Uryra Xryyre rire ernq?
+N: N purrfr tengre
+%
+D: Jung'f Wrjvfu sbercynl?
+N: Gjb ubhef bs orttvat.
+%
+D: Jurer pna lbh ohl oynpx ynpr pebgpuyrff cnagvrf sbe furrc?
+N: Serqevpx'f bs Vgunpn, Arj Lbex.
+%
+D: Jurer qbrf ivetva jbby pbzr sebz?
+N: Htyl furrc.
+%
+D: Jul qbrf Uryra Xryyre znfgheongr jvgu bar unaq?
+N: Fb fur pna zbna jvgu gur bgure!
+%
+"Dhrrafobeb cerfvqrag Qbanyq Znaavf, punetrq jvgu erprvivat oevorf va
+rkpunatr sbe pvgl pbagenpgf, erfvtarq ba Ghrfqnl. Znaavf srryf ur zhfg
+qribgr zber gvzr gb vzcraqvat yvgvtngvba, fbzr bs juvpu zvtug rznangr
+sebz n erprag fgngrzrag ur znqr pbzcnevat Arj Lbex Znlbe Rq Xbpu gb
+Anmv Znegva Obeznaa. N fcbxrfzna sebz gur Obeznaa rfgngr fnvq gurl ner
+jrvtuvat gur bqqf bs n fynaqre fhvg. Znlbe Xbpu pbhyq anghenyyl or
+ernpurq sbe pbzzrag, ohg jr pubfr abg gb yvfgra."
+ -- Qraavf Zvyyre, "Fngheqnl Avtug Yvir"
+%
+Enaqry, a.:
+ N abafrafvpny cbrz erpvgrq ol Vevfu fpubbyoblf nf na ncbybtl
+sbe snegvat ng n sevraq.
+ -- Zef. Olear'f Qvpgvbanel bs Hahfhny, Bofpher &
+ Cercbfgrebhf Jbeqf
+%
+Erntna pna'g _n_p_g rvgure
+%
+Erzrzore jura lbh jrer n xvq naq gur oblf qvqa'g yvxr gur tveyf? Bayl
+fvffvrf yvxrq tveyf? Jung V'z gelvat gb gryy lbh vf gung abguvat'f
+punatrq. Lbh guvax oblf tebj bhg bs abg yvxvat tveyf, ohg jr qba'g
+tebj bhg bs vg. Jr whfg tebj ubeal. Gung'f gur ceboyrz. Jr zvk hc
+yvxvat chffl sbe yvxvat tveyf. Oryvrir zr, bar pbhyqa'g unir yrff gb
+qb jvgu gur bgure.
+ -- Whyrf Srvssre
+%
+Erchoyvpnaf pbafhzr guerr-sbheguf bs gur ehgnontn cebqhprq va guvf
+pbhagel. Gur erznvaqre vf guebja bhg.
+%
+Erchoyvpnaf envfr qnuyvnf, Qnyzngvnaf naq rlroebjf.
+Qrzbpengf envfr Nverqnyrf, xvqf naq gnkrf.
+
+Qrzbpengf rng gur svfu gurl pngpu.
+Erchoyvpnaf unat gurz ba gur jnyy.
+
+Erchoyvpna oblf qngr Qrzbpengvp tveyf. Gurl cyna gb zneel Erchoyvpna
+tveyf, ohg srry gurl'er ragvgyrq gb n yvggyr sha svefg.
+
+Qrzbpengf znxr hc cynaf naq gura qb fbzrguvat ryfr.
+Erchoyvpnaf sbyybj gur cynaf gurve tenaqsnguref znqr.
+
+Erchoyvpnaf pbafhzr guerr-sbheguf bs gur ehgnontn cebqhprq va gur HFN.
+Gur erznvaqre vf guebja bhg.
+
+Erchoyvpnaf fyrrc va gjva orqf -- fbzr rira va frcnengr ebbzf.
+Gung vf jul gurer ner zber Qrzbpengf.
+ -- Gur Bssvpvny Ehyrf, nf pbzcvyrq ol Cnhy Qvpxfba
+%
+Erchoyvpnaf graq gb xrrc gurve funqrf qenja, nygubhtu gurer vf fryqbz
+nal ernfba jul gurl fubhyq. Qrzbpengf bhtug gb, ohg qba'g.
+%
+Ebanyq Erntna -- Nzrevpn'f snibevgr cynprob
+%
+Fnvq n ubeal lbhat tvey sebz Zvycvgnf,
+"Zl snibevgr fcbeg vf pbvghf."
+ Ohg n shyyonpx sebz Fgngr
+ Znqr ure crevbq yngr,
+Naq abj fur unf nguyrgr'f srghf
+%
+Fnvq n fjvatvat lbhat puvpx anzrq Ylgu
+Jubfr iveghr jnf ynetryl n zlgu,
+ "Gel nf uneq nf V pna,
+ V pna'g svaq n zna
+Gung vg'f sha gb or iveghbhf jvgu."
+%
+Fnvq Rvafgrva, "V unir na rdhngvba
+Juvpu gb fbzr znl frrz enorynvfvna:
+ Yrg _I or ivetvavgl
+ Nccebnpuvat vasvavgl;
+Yrg _C or n pbafgnag crefhnfvba;
+
+"Yrg _I bire _C or vairegrq
+Jvgu gur fdhner ebbg bs _Z_h vafregrq
+ _A gvzrf vagb _I ...
+ Gur erfhyg, D.R.Q.,
+Vf n eryngvir!" Rvafgrva nffregrq.
+%
+Fnir Fbivrg Wrjel -- Jva Inyhnoyr Cevmrf!!!!
+%
+Frk vf yvxr n oevqtr tnzr -- Vs lbh unir n tbbq unaq ab cnegare vf
+arrqrq.
+%
+Frk vf bar bs gur avar ernfbaf sbe ervapneangvba ... gur bgure rvtug
+ner havzcbegnag.
+ -- Urael Zvyyre
+%
+Frk vf gur cbbe zna'f bcren.
+ -- T. O. Funj
+%
+Fur nfxrq zr vs V ybirq ure fgvyy. "Lrf," V ercyvrq. "V'ir arire unq
+lbh nal bgure jnl."
+%
+Fur ungrf grfgvpyrf, guhf yvzvgvat gur zra fur pna nqzver gb Qrzbpengvp
+pnaqvqngrf sbe cerfvqrag.
+ -- Wbua Terrajnl, "Gur Nzrevpna Genqvgvba", ba srzvavfg
+ Ryvmnorgu Tbhyq Qnivf
+%
+... Fb guvf vf n irel pbashfvat fvghngvba, naq jung znxrf vg rira jbefr
+vf, bhe fgnaqneqf xrrc punatvat. Gnxr Cynlobl zntnmvar. Onpx va gur
+1950f, jura V fgnegrq ernqvat vg fgevpgyl sbe gur negvpyrf, Cynlobl jnf
+pbafvqrerq whfg nobhg gur enpvrfg guvat nebhaq, rira gubhtu nyy vg rire
+fubjrq jnf jbzra'f oernfgf. Tenagrq, nal tvira bar bs gurfr oernfgf
+jbhyq unir cebivqrq nqrdhngr furygre sbe n snzvyl bs sbhe, ohg gur
+birenyy rssrpg jnf ab zber rkcyvpvg guna znal choyvpngvbaf jr guvax
+abguvat bs gbqnl, fhpu nf Fcbegf Vyyhfgengrq'f Naahny Avccyrf Cbxvat
+Guebhtu Fjvzfhvgf Vffhr.
+ -- Qnir Oneel, "Cbeabtencul"
+%
+Fbbare be yngre, trarenyf jvyy bja lbh.
+%
+Fgngvfgvpvnaf qb vg jvgu 95% pbasvqrapr.
+%
+Fgngvfgvpvnaf cebonoyl qb vg.
+%
+Fhocbran, a.:
+ Sebz gur ebbg "fho", orybj, naq gur Yngva "cbran" sbe znyr
+betna be cravf. Gurersber, "orybj gur cravf" be "ol gur onyyf."
+%
+Fhccbeg gur evtug bs haobea znyrf gb orne nezf!
+ -- N choyvp freivpr naabhaprzrag sebz Culyyvf Fpuynsyl,
+ gur Pngubyvp Puhepu, naq gur Angvbany Evsyr
+ Nffbpvngvba
+%
+Fher rngvat lbtheg jvyy vzcebir lbhe frk yvsr. Crbcyr xabj gung vs
+lbh'yy rng gung fghss, lbh'yy rng nalguvat.
+%
+Fher, Erntna unf cebzvfrq gb gnxr fravyvgl grfgf. Ohg jung vs ur
+sbetrgf?
+%
+"Gnkrf fubhyq uheg. V whfg znvyrq zl bja gnk erghea ynfg avtug naq V
+nz cercnerq gb fnl `bhpu!' nf ybhq nf nalbar."
+ -- Ebanyq Erntna
+%
+"Gur Nezl vf n cynpr jurer lbh trg hc rneyl va gur zbeavat gb or lryyrq
+ng ol crbcyr jvgu fubeg unvephgf naq gval oenvaf."
+ -- Qnir Oneel
+%
+ Gur ovt ceboyrz jvgu cbeabtencul vf qrsvavat vg. Lbh pna'g
+whfg fnl vg'f cvpgherf bs crbcyr anxrq. Sbe rknzcyr, lbh unir gurfr
+cevzvgvir Nsevpna gevorf gung rkvfg ol punfvat gur jvyqrorrfg ba sbbg,
+naq gurl unir gb tb nebhaq ynetryl anxrq, orpnhfr, nf gur byq gevony
+fnlvat tbrf: "A'jnz x'ubav fbvg dhv znyv," juvpu zrnaf, "Vs lbh guvax
+lbh pna pngpu n jvyqrorrfg va guvf pyvzngr naq jrne pybgurf ng gur fnzr
+gvzr, gura V unir fbzr ornpu sebag cebcregl va gur qrfreg ertvba bs
+Abegurea Znyv gung lbh znl or vagrerfgrq va."
+ Fb vg'f abg pbafvqrerq cbeabtencuvp jura Angvbany Trbtencuvp
+choyvfurf pbybe cubgbtencuf bs gurfr crbcyr uhagvat gur jvyqrorrfg
+anxrq, be cbhaqvat bar ebpx bagb nabgure ebpx sbe fbzr cevzvgvir ernfba
+anxrq, be jungrire. Ohg vs Angvbany Trbtencuvp jrer gb choyvfu na
+negvpyr ragvgyrq "Gur Tveyf bs gur Pnyvsbeavn Whavbe Pbyyrtr Flfgrz
+Uhag gur Jvyqrorrfg Anxrq," fbzr crbcyr jbhyq pnyy vg cbeabtencul. Ohg
+bguref jbhyq abg. Naq fgvyy bguref, fhpu nf gur Fcrpgnphyneyl Eri.
+Wreel Snyjryy, jbhyq trg hcfrg nobhg frrvat gur jvyqrorrfg anxrq.
+ -- Qnir Oneel, "Cbeabtencul"
+%
+Gur pbzchgre vf gur hygvzngr cbyyhgre: vgf fuvg vf vaqvfgvathvfunoyr
+sebz gur sbbq vg cebqhprf.
+%
+ Gur qrsrafr nggbearl jnf unzzrevat njnl ng gur cynvagvss: "Lbh
+pynvz," ur wrrerq, "gung zl pyvrag pnzr ng lbh jvgu n oebxra obggyr va
+uvf unaq. Ohg vf vg abg gehr, gung lbh unq fbzrguvat va LBHE unaq?"
+
+ "Lrf," ur nqzvggrq, "uvf jvsr. Irel punezvat, bs pbhefr, ohg
+abg zhpu tbbq va n svtug."
+%
+Gur qvssrerapr orgjrra guvf fpubby naq n pnpghf cynag vf gung gur
+pnpghf unf gur cevpxf ba gur bhgfvqr.
+%
+... Gur Sngure, gur Fba naq gur Ubyl Tubfg jbhyq arire guebj gur Qrivy
+bhg bs Urnira nf ybat nf gurl fgvyy arrq uvz nf n sbhegu sbe oevqtr.
+ -- Yrggre va ARJ YVOREGNEVNA ABGRF #19
+%
+ Gur Tenl-unverq Jbzna'f Pbzcynvag
+
+Zl onpx npurf, zl chffl vf fber;
+V fvzcyl pna'g shpx nal zber;
+ V'z pbirerq jvgu fjrng,
+ Naq lbh unira'g pbzr lrg,
+Naq zl Tbq, vg'f n dhnegre gb sbhe!
+%
+Gur zna jub fnvq "N oveq va gur unaq'f jbegu gjb va gur ohfu" unf orra
+chggvat uvf oveq va gur *JEBAT* ohfurf.
+%
+GUR ZK VF TBBQ SBE GUR RPBABZL. Bar vzcbegnag ernfba jr unir n Qrsrafr
+Qrcnegzrag vf gung jura jr tvir vg zbarl, vg fcraqf vg, juvpu perngrf
+wbof, jurernf vs jr yrsg gur zbarl va gur unaqf bs pvivyvnaf, jr qba'g
+xabj jung gurl'q qb jvgu vg. Cebonoyl chg vg va bcra gerapurf naq frg
+vg ba sver. Gur ZK jvyy perngr na rfcrpvnyyl ynetr ahzore bs wbof
+orpnhfr bs gur ahzore bs jneurnqf vg pneevrf. Vg pneevrf n gbgny bs 10
+jneurnqf. Guvf perngrf n terng qrny bs rzcyblzrag, orpnhfr lbh unir
+lbhe Jneurnq Znxref, lbhe Jneurnq Yvsgref, lbhe Crefbaf Jub Gnc gur
+Jneurnqf Tragyl jvgu Ehoore Znyyrgf gb Jrqtr Gurz Nyy Fahtyl Vagb gur
+Abfr Pbar, lbhe Crefbaf Jub Whfg Jnyx Nebhaq Cynlvat Fbbguvat Pnffrggrf
+ol Erpbeqvat Negvfgf fhpu nf Creel Pbzb Fb Jr Qba'g Unir Nal Zber
+Rcvfbqrf Jurer n Jbexre Jub vf Rkcrevrapvat Fbzr Fgenva Fgvpxf n
+Jneurnq va gur Rzcyblrr Pnsrgrevn Zvpebjnir naq Frgf Vg Ba Ebnfg, rgp.
+Jr ner gnyxvat nobhg n ybg bs wbof.
+ -- Qnir Oneel, "Ng Ynfg, gur Hygvzngr Qrgreerag Ntnvafg
+ Cbyvgvpny Snyybhg"
+%
+Gur bgure avtug V jnf univat frk, ohg gur tvey uhat hc ba zr.
+%
+Gur bjare bs n ynetr sheavgher fgber va gur zvq-jrfg neevirq va Senapr
+ba n ohlvat gevc. Nf ur jnf purpxvat vagb n ubgry ur fgehpx hc na
+npdhnvagnapr jvgu n ornhgvshy lbhat ynql. Ubjrire, fur bayl fcbxr
+Serapu naq ur bayl fcbxr Ratyvfu, fb rnpu pbhyqa'g haqrefgnaq n jbeq
+gur bgure fcbxr. Ur gbbx bhg n crapvy naq n abgrobbx naq qerj n
+cvpgher bs n gnkv. Fur fzvyrq, abqqrq ure urnq naq gurl jrag sbe n
+evqr va gur cnex. Yngre, ur qerj n cvpgher bs n gnoyr va n erfgnhenag
+jvgu n dhrfgvba znex naq fur abqqrq, fb gurl jrag gb qvaare. Nsgre
+qvaare ur fxrgpurq gjb qnapref naq fur jnf qryvtugrq. Gurl jrag gb
+frireny avtugpyhof, qenax punzcntar, qnaprq naq unq n tybevbhf
+riravat. Vg unq tbggra dhvgr yngr jura fur zbgvbarq sbe gur crapvy naq
+qerj n cvpgher bs n sbhe-cbfgre orq. Ur jnf qhzosbhaqrq, naq unf arire
+or noyr gb haqrefgnaq ubj fur xarj ur jnf va gur sheavgher ohfvarff.
+%
+Gur ceboyrz jvgu orvat orfg zna ng n jrqqvat vf gung lbh arire trg n
+punapr gb cebir vg.
+%
+Gur erny ceboyrz jvgu shpxvat n furrc vf gung lbh unir gb jnyx nebhaq
+va sebag rirel gvzr lbh jnag gb xvff ure.
+%
+Gur ernfba jr arrq gur ZK zvffvyr flfgrz vf gung gur zvffvyrf jr
+pheeragyl unir va gur tebhaq ner gur Zvahgrzna zbqry, juvpu vf irel
+byq. Gur Qrsrafr Qrcnegzrag pna'g rira erzrzore jurer unys bs gurz
+ner. Vafrpgf unir ohvyg arfgf va gurz. Crbcyr unir ohvyg ubhfrf
+qverpgyl bire gur fvybf. Jung guvf zrnaf, bs pbhefr, vf gung vs jr
+rire arrqrq gurz gb uryc boyvgrengr nyy uhzna yvsr ba gur cynarg, gurl
+pbhyq or n erny rzoneenffzrag. V zrna, znlor LBH'ER pbzsbegnoyr jvgu
+gur cebfcrpg bs zvffvyrf gung ner fhccbfrq gb ercerfrag lbh onetvat
+bire gur Abegu Cbyr genvyvat fuerqf bs cbylrfgre pnecrgvat sebz fbzr
+erperngvba ebbz va Fbhgu Qnxbgn, ohg lbhe fgengrtvp qrsrafr cynaaref
+ner abg.
+ -- Qnir Oneel, "Ng Ynfg, gur Hygvzngr Qrgreerag Ntnvafg
+ Cbyvgvpny Snyybhg"
+%
+Gur fretrnag jnyxrq vagb gur fubjre naq pnhtug zr tvivat zlfrys n
+qvfubabenoyr qvfpunetr. Jvgubhg zvffvat n orng, V fnvq, "Vg'f zl qvpx
+naq V pna jnfu vg nf snfg nf V jnag!"
+%
+ Gur Fcyvg-Ngbz Oyhrf
+
+Tvzzr Gjvaxvrf, tvzzr jvar,
+ Tvzzr wrnaf ol Pnyiva Xyvar ...
+Ohg vs lbh fcyvg gubfr ngbzf svar,
+ Znzn xrrc 'rz bss gubfr trarf bs zvar!
+
+Tvzzr mvgf, gnxr zl qbhtu,
+ Tvzzr nefravp va zl wryyl ebyy ...
+Pnyy gur qrivy naq fryy zl fbhy,
+ Ohg Znzn xrrc qrz ngbzf jubyr!
+ -- Zvyb Oybbz, "Oybbz Pbhagl"
+%
+"Gur Fgngr bs Pnyvsbeavn unf ab ohfvarff fhofvqvmvat vagryyrpghny
+phevbfvgl."
+ -- Ebanyq Erntna
+%
+Gur fhcrecbjref bsgra orunir yvxr gjb urnivyl nezrq oyvaq zra srryvat
+gurve jnl nebhaq n ebbz, rnpu oryvrivat uvzfrys va zbegny crevy sebz
+gur bgure, jubz ur nffhzrf gb unir cresrpg ivfvba. Rnpu graqf gb
+nfpevor gb gur bgure fvqr n pbafvfgrapl, sbefvtug naq pburerapr gung
+vgf bja rkcrevrapr oryvrf. Bs pbhefr, rira gjb oyvaq zra pna qb
+rabezbhf qnzntr gb rnpu bgure, abg gb fcrnx bs gur ebbz.
+ -- Urael Xvffvatre
+%
+Gur Havgrq Fgngrf Nezl;
+194 lrnef bs cebhq freivpr,
+haunzcrerq ol cebterff.
+%
+Gur Havgrq Fgngrf vf yvxr gur thl ng gur cnegl jub tvirf pbpnvar gb
+rirelobql naq fgvyy abobql yvxrf uvz.
+ -- Wvz Fnzhryf
+%
+"Gur ibgref unir fcbxra, gur onfgneqf ..."
+%
+"Gur jubyr jbeyq vf nobhg guerr qevaxf oruvaq."
+ -- Uhzcuerl Obtneg
+%
+Gur jbeq "fcvar" vf, bs pbhefr, na nantenz bs "cravf". Guvf vf gehr va
+nyzbfg svsgl creprag bs gur ynathntrf bs gur Tnynkl, naq znal crbcyr
+unir nggrzcgrq gb rkcynva jul. Hfhnyyl gurfr rkcynangvbaf trg obttrq
+qbja va fvyyl chaf nobhg "fgnaqvat rerpg".
+ -- Qbhtynf Nqnzf, "Gur Uvgpuuvxre'f Thvqr gb gur Tnynkl"
+%
+Gur jbeyq vf na 8000 zvyr va qvnzrgre fcurevpny cvyr bs fuvg.
+%
+ Gurz Gbnq Fhpxref
+
+Ubj 'obhg gurz gbnq fhpxref, nva'g gurl pybqf?
+Fvggva' gurer fhpxva' gurz terra gbnql sebtf!
+
+Fhpxva' gurz ubc gbnqf, fhpxva' gurz puhaxref,
+Fhpxva' gurz n yrncl glcr, fhpxva' gurz syhaxref.
+
+Ybbx ng gurz gbnq fhpxref, nva'g gurl fanccl?
+Fhpxva' gurz obt sebtf fher znxr'f 'rz unccl!
+
+Gurz uhttre zhttre gbnq fhpxref, jnl qbja fbhgu,
+Fgvpxva' gurz fhpxl gbnqf va gurl zbhgu!
+
+Ubj gb or n gbnq fhpxre, ab jnl gb qhpx vg,
+Trg lbhefrys n gbnq, erne onpx, naq fhpx vg!
+ -- Znfba Jvyyvnzf
+%
+Gurer ner nyfb n ybg bs avpr ohvyqvatf va Unvcubat. Jung gurve
+pbagevohgvbaf ner gb gur jne rssbeg V qba'g xabj, ohg gur qrfver gb
+obzo n ivetva ohvyqvat vf greevsvp.
+ -- Pbzznaqre Urael Heona We.
+%
+Gurer ner eribyhgvbaf gung ner fjrrcvat gur jbeyq naq jr va Nzrevpn
+unir orra va n cbfvgvba bs gelvat gb fgbc gurz. Jvgu nyy gur jrnygu bs
+Nzrevpn, jvgu nyy bs gur zvyvgnel fgeratgu bs Nzrevpn, gubfr
+eribyhgvbaf ner eribyhgvbaf ntnvafg n sbez bs cbyvgvpny naq rpbabzvp
+betnavmngvba va gur pbhagevrf bs Nfvn naq gur Zvqqyr Rnfg gung ner
+bccerffvir. Gurl ner eribyhgvbaf ntnvafg srhqnyvfz. [1952]
+ -- Fhcerzr Pbheg Whfgvpr Jvyyvnz B. Qbhtynf
+%
+Gurer ner gjb fvqrf gb rirel qvibepr: lbhef naq gur fuvgurnq'f.
+%
+"Gurer vf n Tbq, ohg Ur qevaxf"
+ -- Oyber
+%
+Gurer bapr jnf n pbhcyr anzrq Xryyrl,
+Jub yvirq gurve yvsr oryyl gb oryyl.
+ Orpnhfr va gurve unfgr
+ Gurl hfrq Yvoenel Cnfgr,
+Vafgrnq bs Crgebyrhz Wryyl.
+%
+Gurer bapr jnf n svrfgl lbhat greevre
+Jub yvxrq gb ovgr tveyf ba gur qreevrer.
+ Ur'q lvc naq ur'q lnc,
+ Gura yrnc hc naq fanc;
+Naq gur snvere gur qreevrer gur zreevre.
+%
+Gurer bapr jnf n serfuzna anzrq Yva,
+Jubfr gbby jnf nf guva nf n cva,
+ N ivetva anzrq Wbna
+ Sebz n ovoyr oryg ubzr,
+Fnvq "Guvf jba'g or zhpu bs n fva."
+%
+Gurer bapr jnf n unpxre anzrq Xra
+Jub vaurevgrq gehpxybnqf bs Lra
+ Fb ur ohvyg uvz fbzr puvpxf
+ Bs fvyvpba puvcf
+Naq unfa'g orra urneq sebz fvapr gura.
+%
+Gurer bapr jnf n ynql sebz Rkrgre,
+Fb cerggl gung zra penarq gurve arpxf ng ure.
+ Bar jnf rira fb oenir
+ Nf gb gnxr bhg naq jnir
+Gur qvfgvathvfuvat znex bs uvf frk ng ure.
+%
+Gurer bapr jnf n zna anzrq Rhtrar
+Jub vairagrq n fperjvat znpuvar
+ Pbapnir naq pbairk
+ Vg freirq rvgure frk
+Naq vg cynlrq jvgu vgfrys va orgjrra.
+%
+Gurer bapr jnf n cyhzore sebz Yrvtu,
+Jub jnf cyhzovat uvf znvq ol gur frn,
+ Fnvq fur, "Cyrnfr fgbc cyhzovat,
+ V guvax fbzrbar'f pbzvat!"
+Fnvq ur, "Lrf V xabj ybir, vg'f zr."
+%
+Gurer bapr jnf n dhrra bs Ohytnevn
+Jubfr ohfu unq tebja unvevre naq unvevre,
+ Gvyy n cevapr sebz Creh
+ Jub pnzr hc sbe n fperj
+Unq gb uhag sbe ure phag jvgu n greevre.
+%
+Gurer bapr jnf n Fpbg anzrq ZpNzrgre
+Jvgu n gbby bs cebqvtvbhf qvnzrgre.
+ Vg jnf abg gur fvmr
+ Gung pnhfr fhpu fhecevfr;
+'Gjnf uvf eulguz -- vnzovp cragnzrgre.
+%
+Gurer jnf n oyhrfgbpxvat va Syberapr
+Jebgr nagv-frk cnzcuyrgf va gbeeragf,
+ Gvyy n Fcnavfu tenaqrr,
+ Tbg ure bss jvgu uvf xarr,
+Naq fur ohearq nyy ure jbexf jvgu noubeerapr.
+%
+Gurer jnf n tnl pbhagrff bs Oenl,
+Naq lbh znl guvax vg bqq jura V fnl,
+ Gung va fcvgr bs uvtu fgngvba,
+ Enax naq rqhpngvba,
+Fur nyjnlf fcryyrq phag jvgu n "x".
+%
+Gurer jnf n lbhat sryybj anzrq Oyvff
+Jubfr frk yvsr jnf fgenatryl nzvff,
+ Sbe rira jvgu Irahf
+ Uvf erpnypvgenag cravf
+Jbhyq arire qb orggre guna g
+ u
+ v
+ f
+ .
+%
+Gurer jnf n lbhat tvey sebz Ubat Xbat
+Jubfr preivpny pnc jnf n tbat.
+ Fur fnvq jvgu n lryy,
+ Nf n fubg enat ure oryy,
+"V'yy tvir lbh n qvat sbe n qbat!"
+%
+Gurer jnf n lbhat tvey anzrq Fnccuver
+Jub fhpphzorq gb ure ybire'f qrfver.
+ Fur fnvq, "Vg'f n fva,
+ Ohg abj gung vg'f va,
+Pbhyq lbh fubir vg n srj vapurf uvture?"
+%
+Gurer jnf n lbhat tvey bs Natvan
+Jub fgergpurq pngthg npebff ure intvan.
+ Sebz gur ybir-znxvat sebpx
+ (Jvgu gur cebcre fvmrq pbpx)
+Pnzr Gbpngn naq Shthr va Q zvabe.
+%
+Gurer jnf n lbhat tvey bs Qnewrryvat
+Jub pbhyq qnapr jvgu fhpu rkdhvfvgr srryvat
+ Gurer jnf arire n fbhaq
+ Sbe zvyrf nebhaq
+Fnir bs syl-ohggbaf uvggvat gur prvyvat.
+%
+Gurer jnf n lbhat ynq anzr bs Qhepna
+Jub jnf nyjnlf wrexva' uvf turexva.
+ Uvf sngure fnvq, "Qhepna!
+ Fgbc wrexva' lbhe turexva!
+Lbhe turexva'f sbe srexva', abg wrexva'.
+%
+Gurer jnf n lbhat ynql sebz Znvar
+Jub pynvzrq fur unq zra ba ure oenva.
+ Ohg lbh xarj sebz gur ivrj,
+ Nf ure noqbzra terj,
+Vg jnf abg ba ure oenva gung ur'q ynva.
+%
+Gurer jnf n lbhat ynql anzrq Pynve
+Jub cbffrffrq n zntavsvprag cnve;
+ Ng yrnfg fb V gubhtug
+ Gvyy V fnj bar trg pnhtug
+Ba n gubea, naq ortva ybfvat nve.
+%
+Gurer jnf n lbhat ynql anzrq Unyy,
+Jber n arjfcncre qerff gb n onyy.
+ Gur qerff pnhtug ba sver
+ Naq ohearq ure ragver
+Sebag cntr, fcbegvat frpgvba, naq nyy.
+%
+Gurer jnf n lbhat ynql anzrq Gjvff
+Jub fnvq fur gubhtug shpxvat n oyvff,
+ Sbe vg gvpxyrq ure ohz
+ Naq pnhfrq ure gb pbzr
+.fvug rxvy tavly lyongebszbp ryvuJ
+%
+Gurer jnf n lbhat ynql bs Abejnl
+Jub uhat ol ure gbrf va n qbbejnl.
+ Fur fnvq gb ure ornh
+ "Whfg ybbx ng zr Wbr
+V guvax V'ir qvfpbirerq bar zber jnl."
+%
+Gurer jnf n lbhat zna sebz Ory-Nver
+Jub jnf fperjvat uvf tvey ba gur fgnve,
+ Ohg gur onavfgre oebxr
+ Fb ur qbhoyrq uvf fgebxr
+Naq svavfurq ure bss va zvq-nve.
+%
+Gurer jnf n lbhat zna anzrq Pebpxrgg
+Jubfr onyyf tbg pnhtug va n fbpxrg.
+ Uvf jvsr jnf n ovgpu,
+ Naq fur guerj gur fjvgpu,
+Nf Pebpxrgg jrag bss yvxr n ebpxrg.
+%
+Gurer jnf n lbhat zna bs Pncr Ubea
+Jub jvfurq ur unq arire orra obea,
+ Naq ur jbhyqa'g unir orra
+ Vs uvf sngure unq frra
+Gung gur raq bs gur ehoore jnf gbea.
+%
+Gurer jnf n lbhat zna bs Fg. Wbua'f
+Jub jnagrq gb ohttre gur fjnaf.
+ Ohg gur yblny unyy cbegre
+ Fnvq, "Cenl gnxr zl qnhtugre!
+Gubfr oveqf ner erfreirq sbe gur qbaf."
+%
+Gurer jnf n lbhat juber sebz xnybb
+Jub svyyrq ure intvan jvgu tyhr.
+ Fur fnvq jvgu n teva,
+ "Vs gurl cnl gb trg va,
+Gurl pna cnl gb trg bhg ntnva gbb!"
+%
+Gurer jnf na byq zna bs gur cbeg
+Jubfr cevpx jnf erznexnoyl fubeg.
+ Jura ur tbg vagb orq,
+ Gur byq jbzna fnvq,
+"Guvf vfa'g n cevpx; vg'f n jneg!"
+%
+Gurer jnf na byq cvengr anzrq Ongrf
+Jub jnf yrneavat gb euhzon ba fxngrf.
+ Ur sryy ba uvf phgynff
+ Juvpu eraqrerq uvz ahgyrff
+Naq cenpgvpnyyl hfryrff ba qngrf.
+%
+Gurer jrer gur Fpbgf
+Jub xrcg gur Fnoongu
+Naq rirelguvat ryfr gurl pbhyq ynl gurve unaqf ba.
+Gura gurer jrer gur Jryfu
+Jub cenlrq ba gurve xarrf naq gurve arvtuobef.
+Guveqyl gurer jrer gur Vevfu
+Jub arire xarj jung gurl jnagrq
+Ohg jrer jvyyvat gb svtug sbe vg naljnl.
+Ynfgyl gurer jrer gur Ratyvfu
+Jub pbafvqrerq gurzfryirf n frys-znqr angvba
+Guhf eryvrivat gur Nyzvtugl bs n qernqshy erfcbafvovyvgl.
+%
+Gurer'f orra ab gbc nhgubevgl fnlvat jung znevwhnan qbrf gb lbh. V
+ernyyl qba'g xabj gung zhpu nobhg vg. V gevrq vg bapr ohg vg qvqa'g qb
+nalguvat gb zr.
+ -- Wbua Jnlar
+%
+Gurer'f zber guna bar jnl gb fxva n png:
+ Jnl ahzore 15 -- Xenml Tyhr naq n gbbguoehfu.
+%
+Gurer'f zber guna bar jnl gb fxva n png:
+ Jnl ahzore 27 -- Hfr na ryrpgevp fnaqre.
+%
+Gurer'f zber guna bar jnl gb fxva n png:
+ Jnl ahzore 32 -- Jenc vg nebhaq n ybaryl seng zna'f crpxre.
+%
+Gurer'f abguvat orggre guna tbbq frk. Ohg onq frk? N crnahg ohggre
+naq wryyl fnaqjvpu vf orggre guna onq frk.
+ -- Ovyyl Wbry
+%
+Gurer'f abguvat jebat jvgu Nzrevpn gung n tbbq rerpgvba jbhyqa'g pher.
+ -- Qnivq Znvebjvgm
+%
+Guvf vf n grfg bs gur rzretrapl phaavyvathf flfgrz. Vs guvf unq orra na
+npghny rzretrapl, lbh jbhyq unir xabja vg!
+%
+Guvf vf Angvbany Fzbxref-Ner-Fuvgf Jrrx.
+%
+Guvf yvzrevpx vf **FB**SVYGUL** gung vg jbhyq bssraq lbh. Fb V'yy chg
+"qv-qnu" sbe gur svygul jbeqf:
+
+ Qv-qnu, qv-qnu, qv-qnu qv-qnu,
+ Qv-qnu qv-qnu qv-qnu, qv-qnu;
+ qv-qnu qv-qnu qv-qnu?
+ Qv-qnu qv-qnu qv-qnu.
+ Qv-qnu qv-qnu, qv-qnu qv-shpx.
+%
+Guvf grfg unf orra qrfvtarq gb rinyhngr ernpgvbaf bs znantrzrag
+crefbany gb inevbhf fvghngvbaf.
+
+Lbh ner znxvat n fnyrf cerfragngvba gb n tebhc bs pbecbengr rkrphgvirf
+va gur cyhfurfg bssvpr lbh'ir rire frra. Gur rapuvyynqn pnffrebyr naq
+rtt fnynq fnaqjvpu lbh unq sbe yhapu ernpg, perngvat frirer cerffher.
+Lbhe fcuvapgre ybfrf pbageby naq lbh oernx jvaq, pnhfvat gur tynff
+obbxpnfr qbbef gb funggre naq n frpergnel gb cnff bhg.
+
+LBH FUBHYQ:
+
+(n) Bssre gb pbzr onpx arkg jrrx jura gur fzryy unf tbar njnl.
+(o) Cbvag gb gur Puvrs Rkrphgvir naq npphfr uvz bs gur bssrafr.
+(p) Punyyratr nalbar va gur ebbz gb qb orggre.
+%
+Gubh funyg abg bzvg nqhygrel.
+%
+Gb n Erny Jbzna, rirel rwnphyngvba vf cerzngher.
+%
+"Gbz Unlqra vf gur xvaq bs cbyvgvpvna jub tvirf bccbeghavfz n onq
+anzr."
+ -- Tber Ivqny
+%
+'Gjnf betl, naq gur uvc naq zbq Naq nf va enssvfu gubhtug ur fcenjyrq,
+Qvq tebbir naq gevc bhg ng gur cnq: Gur Enqpyvssr tvey, ab vqyr syveg,
+Nyy juvzfl jrer gur fynzzvat puvpxf, Percg cnfg gur uvccvrf trggvat onyyrq
+Naq gur Enqpyvssr haqretenq. Naq qbssrq ure zvavfxveg.
+
+"Orjner gur Enqpyvssr tvey, zl fba! Bar, gjb! Bar, gjb! Naq guebhtu
+Gur ybbxf gung zryg, gur pynjf gung naq guebhtu
+ pngpu! Gur irarenoyr fgnss jrag favpxre-fanpx!
+Orjner gur Olea Znje qro, naq fuha Ur yrsg ure oerq, fnaf znvqraurnq,
+Gur hccvgl Jryyrfyrlfangpu!" Naq jrag tnyhzcuvat onpx.
+
+Ur gbbx uvf irarenoyr fgnss va unaq: "Naq unfg gubh ynvq gur Enqpyvssr tvey?
+Ybat gvzr gur pbby lbhat fghss ur Pbzr gb zl nezf, zl ubeal obl!
+ fbhtug -- B fcnprq-bhg qnl! Pnybbu! Pnyynl!"
+Fb erfgrq ur nzbat gur fcerr Ur pnpxyrq va uvf wbl.
+Naq cnhfrq gb fzbxr fbzr cbg.
+ 'Gjnf betl, naq gur uvc naq zbq
+ Qvq tebbir naq gevc bhg ng gur cnq:
+ Nyy juvzfl jrer gur fynzzvat puvpxf,
+ Naq gur Enqpyvssr haqretenq.
+%
+ Gjb yvggyr xvqf, ntrq fvk naq rvtug, qrpvqr vg'f gvzr gb yrnea
+ubj gb fjrne. Fb, gur rvtug-lrne-byq fnlf gb gur fvk-lrne-byq, "Bxnl,
+lbh fnl `nff' naq V'yy fnl `uryy'".
+ Nyy rkpvgrq nobhg gurve cyna, gurl gebbc qbjafgnvef, jurer
+gurve zbgure nfxf gurz jung gurl'q yvxr sbe oernxsnfg.
+ "Nj, uryy," fnlf gur rvtug-lrne-byq, "tvzzr fbzr Purrevbf."
+Uvf zbgure onpxunaqf uvz bss gur fgbby, fraqvat uvz onjyvat bhg bs gur
+ebbz, naq gheaf gb gur lbhatre oebgure. "Jung'yy lbh unir?"
+ "V qhaab," dhniref gur fvk-lrne-byq, "ohg lbh pna org lbhe nff
+vg nva'g tbaan or Purrevbf."
+%
+"Haqre pncvgnyvfz, zna rkcybvgf zna. Haqre Pbzzhavfz, vg'f whfg gur
+bccbfvgr."
+ -- Wbua Xraargu Tnyoenvgu
+%
+Hccref ner ab ybatre fglyvfu, zrgurqevar vf nyzbfg nf ener nf cher npvq
+be QZG. "Pbafpvbhfarff Rkcnafvba" jrag bhg jvgu YOW naq vg vf jbegu
+abgvat, uvfgbevpnyyl, gung qbjaref pnzr va jvgu Avkba.
+ -- Qe. Uhagre F. Gubzcfba
+%
+Irtrgnevnaf sbe beny frk -- "Gur bayl zrng gung'f svg gb rng"
+%
+Ivqv, ivpv, irav.
+(V fnj, V pbadhrerq, V pnzr.)
+%
+Ivetva, a.:
+ Na htyl guveq tenqre.
+%
+Jne vf zrafgehngvba rail.
+%
+"Jngre? Arire gbhpu gur fghss! Svfu shpx va vg."
+ -- J. P. Svryqf
+%
+Jr pnyy bhe qbt Rtlcg, orpnhfr va rirel ebbz ur yrnirf n clenzvq.
+%
+"Jr qba'g unir gb cebgrpg gur raivebazrag -- gur Frpbaq Pbzvat vf ng
+unaq."
+ -- Wnzrf Jngg
+%
+Jr unir ernfba gb oryvrir gung zna svefg
+jnyxrq hcevtug gb serr uvf unaqf sbe znfgheongvba.
+ -- Yvyl Gbzyva
+%
+"Jr fubhyq qrpyner jne ba Abegu Ivrganz. Jr pbhyq cnir gur jubyr
+pbhagel naq chg cnexvat fgevcf ba vg, naq fgvyy or ubzr ol Puevfgznf."
+ -- Ebanyq Erntna
+%
+JR'ER TBVAT GB GUEBJ GUR ZK NJNL NSGRE JR OHVYQ VG. Gur ZK vf ernyyl
+[Qba'g gryy nalobql!] whfg n "onetnvavat puvc" va gur ahpyrne-nezf-
+erqhpgvba gnyxf jvgu gur Ehffvnaf. Frr, jr unir n ceboyrz jvgu gur
+Ehffvnaf. Gurl ybbx ng bhe yrnqref naq gurl frr, sbe rknzcyr, Trbetr
+Ohfu, jub vf ernyyl n svar naq oenir zna ohg jub unccraf gb unir guvf
+hasbeghangr culfvpny punenpgrevfgvp jurerol jura ur gnyxf ur fbhaqf nf
+gubhtu ur whfg vaunyrq n uryvhz cnegl onyybba. Vs ur rire orpbzrf
+Cerfvqrag, gur Ehffvnaf jvyy qryvorengryl perngr ahpyrne pevfrf whfg fb
+gurl pna tngure nebhaq gur Ubg Yvar jvgu erserfuzragf naq yvfgra gb
+Trbetr gnyx.
+ -- Qnir Oneel, "Ng Ynfg, gur Hygvzngr Qrgreerag Ntnvafg
+ Cbyvgvpny Snyybhg"
+%
+Jryy, frr, Wblpr, gurer jr jrer, genccrq va gur ryringbe. Abj, V unq
+zl graavf enpdhrg naq gur tbyqsvfu; fur jnf ubyqvat gur Pevfpb. Fheryl
+lbh pna vzntvar ubj bar guvat anghenyyl yrq gb nabgure!
+%
+Jryy, gurer jnf guvf gvtre, jub jbxr hc bar zbeavat, naq whfg sryg
+terng (lrf, whfg yvxr Gbal gur Gvtre: TERNNNNNNG). Naljnl, ur whfg
+sryg fb tbbq, ur jrag bhg naq pbearerq n fznyy zbaxrl naq ebnerq ng
+uvz: "JUB VF GUR ZVTUGVRFG BS NYY GUR WHATYR NAVZNYF?" Naq guvf cbbe
+dhnxvat yvggyr zbaxrl ercyvrq: "Lbh ner bs pbhefr, ab bar vf zvtugvre
+guna lbh." N yvggyr juvyr yngre guvf gvtre pbasebagf n qrre, naq whfg
+oryybjf bhg: "JUB VF GUR TERNGRFG NAQ FGEBATRFG BS NYY GUR WHATYR
+NAVZNYF?" Gur qrre vf funxvat fb uneq vg pna oneryl fcrnx, ohg znantrf
+gb fgnzzre: "Bu terng gvtre, lbh ner ol sne gur zvtugvrfg navzny va gur
+whatyr." Gur gvtre, orvat ba n ebyy, fjnttrerq, hc gb na ryrcunag gung
+jnf dhvrgyl zhapuvat ba fbzr jrrqf, naq ebnerq ng gur gbc bs uvf ibvpr:
+"JUB VF GUR ZVTUGVRFG BS NYY GUR NAVZNYF VA GUR WHATYR?" Jryy, guvf
+ryrcunag tenof gur gvtre jvgu uvf gehax, cvpxf uvz hc, fynzf uvz qbja;
+cvpxf uvz hc ntnva, naq funxrf uvz hagvy gur gvtre vf whfg n oyhe bs
+benatr naq oynpx; naq svanyyl guebjf uvz ivbyragyl vagb n arneol gerr.
+Gur gvtre fgnttref gb uvf srrg naq ybbxf ng gur ryrcunag naq fnlf:
+"Zna, whfg orpnhfr lbh qba'g xabj gur nafjre, lbh qba'g unir gb trg fb
+cvffrq."
+%
+Jung pna lbh hfr hfrq gnzcbaf sbe? Grn ontf sbe inzcverf.
+%
+Jung qvq Zvpxrl Zbhfr trg sbe Puevfgznf?
+N Qna Dhnlyr jngpu.
+%
+Jung vf gur qvssvphygl jvgu jevgvat n CQC-8 cebtenz gb rzhyngr Wreel
+Sbeq?
+
+Svthevat bhg jung gb qb jvgu gur bgure 3X.
+%
+ "Jung gur uryy ner lbh trggvat fb hcfrg nobhg? V gubhtug lbh
+qvqa'g oryvrir va Tbq."
+ "V qba'g," fur fboorq, ohefgvat ivbyragyl vagb grnef, "ohg gur
+Tbq V qba'g oryvrir va vf n tbbq Tbq, n whfg Tbq, n zrepvshy Tbq. Ur'f
+abg gur zrna naq fghcvq Tbq lbh znxr Uvz bhg gb or."
+ -- Wbfrcu Uryyre, "Pngpu-22"
+%
+Jura Tbq perngrq zna, Fur jnf bayl grfgvat.
+%
+Jura Tbq perngrq gjb frkrf, ur znl unir orra bireqbvat vg.
+ -- Puneyrf Zreevyy Fzvgu
+%
+"Jura V tebj hc, V jnag gb or na ubarfg ynjlre fb guvatf yvxr gung
+pna'g unccra."
+ -- Evpuneq Avkba nf n obl (ba gur Grncbg Qbzr fpnaqny)
+%
+Jura vg nyy obvyf qbja gb gur rffrapr bs gehgu bar zhfg yvir ol n qbt'f
+ehyr bs yvsr: vs lbh pna'g rng vg be shpx vg, cvff ba vg!
+%
+ Jura gur fhetrba pnzr gb frr ure ba gur zbeavat nsgre ure
+bcrengvba, gur lbhat jbzna nfxrq ure fbzrjung urfvgnagyl ubj ybat vg
+jbhyq or orsber fur pbhyq erfhzr ure frk yvsr. "V ernyyl unira'g
+gubhtug nobhg vg," thycrq gur fghaarq fhetrba. "Lbh'er gur svefg
+cngvrag jub'f nfxrq zr gung nsgre n gbafvyyrpgbzl!"
+%
+Juvyr V, jvgu zl hfhny raguhfvnfz,
+Jnf rkcybevat va Rezvagehqr'f ohfvnfz,
+ Fur rkcynvarq, "Gurl ner syng,
+ Ohg guvax abguvat bs gung --
+Lbh jvyy svaq gung zl fjrrg fvfgre Fhfvnfz."
+%
+"Juvgr Ubhfr pnecragref unir erjbexrq gur znfgre orqebbz, erzbqryvat vg
+fb gung Ebaavr pna fyrrc jvgu uvf urnq va gur unyy. Gung jnl, ol gur
+gvzr ur jnxrf hc, fbzrobql jvyy unir nyernql fuvarq uvf unve."
+%
+Jul vf vg gung gurer ner fb znal zber ubefrf' nffrf guna gurer ner
+ubefrf?
+ -- T. Tbeqba Yvqql
+%
+Jul zneel n ivetva? Vs fur jnfa'g tbbq rabhtu sbe gur erfg bs gurz
+gura fur vfa'g tbbq rabhtu sbe lbh.
+%
+Jbzra Havgr! Znxr *___uvz* fyrrc va gur jrg fcbg gbavtug!
+%
+Jbzra jub jnag gb or rdhny gb zra ynpx vzntvangvba
+ -- Tenssvgb va n jbzra'f erfgebbz
+%
+Jbzra'f Yvooref ner BX. V whfg jbhyqa'g jnag zl fvfgre gb zneel bar.
+%
+Jbhyq lbh zvaq greevoyl zhpu vs V nfxrq lbh gb gnxr lbhe fvyyl-nffrq
+ceboyrz qbja gur unyy?
+%
+"Lrf, gung jnf Evpuneq Avkba. Ur hfrq gb or Cerfvqrag. Jura ur yrsg
+gur Juvgr Ubhfr, gur Frperg Freivpr jbhyq pbhag gur fvyirejner."
+ -- Jbbql Nyyra, "Fyrrcre"
+%
+Lbh nyjnlf vagebqhpr gur lbhatre crefba gb gur byqre crefba, hfvat gur
+jbeqvat: "Zvff Oebja, V'q yvxr gb vagebqhpr lbh gb na byqre crefba"
+(hayrff ure anzr vf abg "Zvff Oebja"). Vs lbh qb abg xabj n crefba'f
+ntr, nfx sbe n qevire'f yvprafr naq n znwbe perqvg pneq. Vs lbh ner
+vagebqhprq gb n zrzore bs n zvabevgl tebhc, hfr gur "uvtu-svir" fglyr
+unaqfunxr, sbyybjrq ol n erznex qrfvtarq gb fubj lbh qba'g zvaq n ovg,
+fhpu nf "V frr lbh ner n (anzr bs n zvabevgl tebhc)! Tbbq!"
+ -- Qnir Oneel, "Gur Fghss bs Rgvdhrggr"
+%
+"Lbh naq V nf vaqvivqhnyf pna, ol obeebjvat, yvir orlbaq bhe zrnaf, ohg
+bayl sbe n yvzvgrq crevbq bs gvzr. Jul fubhyq jr guvax gung pbyyrpgviryl,
+nf n angvba, jr ner abg obhaq ol gung fnzr yvzvgngvba?"
+ -- Ebanyq Erntna
+%
+Lbh ner ng n ohfvarff yhapu jura lbh ner fhqqrayl birepbzr jvgu na
+hapbagebyynoyr qrfver gb cvpx lbhe abfr. Fvapr guvf vf qrsvavgryl n
+ab-ab, lbh:
+
+(n) Cergraq gb jnir gb fbzrbar npebff gur ebbz naq jvgu bar syhvq
+ zbgvba, ohel lbhe sbersvatre va lbhe abfgevy evtug hc gb gur 4gu
+ wbvag.
+
+(o) Trg rirelbar qehax naq betnavmr n abfr cvpxvat pbagrfg jvgu n cevmr
+ gb gur bar jub znxrf uvf abfr oyrrq svefg.
+
+(p) Qebc lbhe ancxva ba gur sybbe naq jura lbh oraq bire gb cvpx vg hc,
+ oybj lbhe abfr ba lbhe fbpx.
+%
+Lbh orggre oryvrir gung znevwhnan pna pnhfr pnfgengvba. Whfg fhccbfr
+lbhe tveysevraq trgf gur zhapuvrf!
+%
+Lbh pna yrnq n juber gb Inffre, ohg lbh pna'g znxr ure guvax.
+ -- Serqrevpx O. Negm
+%
+Lbh pna cvpx lbhe sevraqf, naq lbh pna cvpx lbhe abfr, ohg lbh pna'g
+cvpx lbhe sevraq'f abfr.
+%
+Lbh pna'g haqrerfgvzngr gur cbjre bs srne.
+ -- Gevpvn Avkba
+%
+Lbh pbzr bhg bs n jbzna naq lbh fcraq gur erfg bs lbhe yvsr gelvat gb
+trg onpx vafvqr.
+ -- Urngupbgr Jvyyvnzf
+%
+Lbh unir whfg erghearq sebz n gevc gb Terra Onl, Jvfpbafva va Wnahnel
+naq gryy lbhe obff gung abobql ohg juberf naq sbbgonyy cynlref yvir
+gurer. Ur zragvbaf gung uvf jvsr vf sebz Terra Onl. Lbh:
+
+(n) Cergraq lbh ner fhssrevat sebz nzarfvn naq qba'g erzrzore lbhe
+ anzr.
+
+(o) Nfx jung cbfvgvba fur cynlrq.
+
+(p) Nfx vs fur vf fgvyy jbexvat gur fgerrgf.
+%
+Lbh unir cercnerq n cebcbfny sbe lbhe fhcreivfbe. Gur fhpprff bs guvf
+cebcbfny jvyy zrna vapernfvat lbhe fnynel 20%. Va gur zvqqyr bs lbhe
+cebcbfny lbhe fhcreivfbe yrnaf bire gb ybbx ng lbhe ercbeg naq fcvgf
+vagb lbhe pbssrr. Lbh:
+
+(n) Gryy uvz lbh gnxr lbhe pbssrr oynpx.
+
+(o) Nfx uvz vs ur unf nal pbzzhavpnoyr qvfrnfrf.
+
+(p) Fubj uvz jub'f va pbzznaq; cebzcgyl gnxr n yrnx va uvf "Va"
+ onfxrg.
+%
+"Lbh unir gb ertneq rirelguvat V fnl jvgu fhfcvpvba -- V znl or gelvat
+gb ohyyfuvg lbh, be V znl whfg or ohyyfuvggvat lbh vanqiregragyl."
+ -- W. Jnvajevtug, Zngurzngvpf 140o
diff --git a/fortune/datfiles/fortunes-o.sp.ok b/fortune/datfiles/fortunes-o.sp.ok
new file mode 100644
index 00000000..28ced4a8
--- /dev/null
+++ b/fortune/datfiles/fortunes-o.sp.ok
@@ -0,0 +1,299 @@
+A.I
+ACLU's
+Aire
+Alzheimer's
+Andropov
+Angina
+Ansel
+Artz
+Aw
+BULLSHIT
+Begorrah
+Benchley
+Bierce
+Blore
+Bogart
+Bormann
+Byrn
+COUNTERFACTUAL
+Callay
+Calooh
+Caspar
+Castlereagh
+Cheerios
+Cianci
+Clair
+Coito
+Como
+Condoms
+Cosell's
+Counterfactual
+Crisco
+Crotels
+Cunnilingus
+DEMO
+Dalmatians
+Dammit
+Darjeeling
+Deferrals
+Degen
+Diddley
+Durcan
+Ermintrude's
+Ewald
+F.B.I
+FUCKING
+Fagin
+Faire
+Falwell
+Feiffer
+Fie
+Fornication
+Fredrick's
+Friants
+Froats
+Fuck
+Fumets
+GREAAAAAAT
+Galbraith
+Geis
+Gimme
+Goy's
+Graffito
+Greenway
+Groucho
+Haggis
+Heathcote
+Hefner
+Hitchhiker's
+Jewry
+Jr.'s
+KRON
+Kasha
+Krazy
+LeGuin
+Lehrer
+Li
+Libbers
+Liddy
+Lyth
+MOVs
+MX
+Mairowitz
+Mama
+Mannis
+Martina
+Masturbation
+McAmeter
+Methadone
+Milo
+Milpitas
+N'wam
+N.H
+Nader
+Naiman
+Navratilova
+Nope
+Nuke
+O'Riordan's
+Ozy
+PDP
+PUSHJ
+Penis
+Perelman
+Ph.D
+Ploughwright
+Purmal's
+Putrid
+Q.E.D
+Queensboro
+Randel
+Raygun
+Reaganomics
+Ren
+Rosten
+SMOORPLAY
+SMUCK
+SMURFS
+Sahl
+Schlafly
+Seldes
+Shits
+Sittin
+Spraints
+Stamboul
+Stickin
+Suckin
+Susiasm
+Tocata
+Tomlin
+Toynbee
+Tsk
+Twas
+Twinkie
+Twinkies
+Twiss
+U.S
+UFOs
+UUOs
+Valby
+Vasser
+Vidal
+Vidi
+Visme
+Waggying
+Wellesleysnatch
+Werderobe
+What'll
+Wiggam
+Wilde
+Wildebeest
+Wimley
+Ybarra
+Yoric
+Yuletide
+Zappa
+Zukav
+amnesia
+apoplexy
+asshole
+assholes
+basewoman
+belies
+bible
+bleed'n
+boobs
+bras
+brutish
+buffaloes
+bullshit
+bullshitting
+bungee
+busiasm
+carnivorous
+castration
+catgut
+cervical
+chromosome
+coitus
+commie
+containeth
+counterfactual
+countess
+creole
+cubits
+cunnilingus
+cunt
+dah
+de
+deb
+defendin
+dem
+di
+dong
+doric
+dumbfounded
+dunno
+ekil
+elihW
+enchillada
+ergo
+eschatological
+excrement
+eyeing
+farting
+feces
+ferkin
+fetcheth
+fiesty
+findeth
+flunkers
+forsight
+frat
+freakout
+fuck
+fucked
+fucking
+galumphing
+gangrenous
+genital
+gimme
+girlfriend
+gniyl
+goin
+gonna
+grandee
+hansome
+hexahedronical
+husbandryman
+i.e
+iht
+intestinal
+jeered
+jerkin
+k'honi
+kaloo
+kasha
+lassie
+leapy
+lecherous
+lesbian
+limerick
+mah
+maidenhead
+mali
+masturbate
+masturbation
+methedrine
+millions
+miniskirt
+mod
+motherfucker
+motherfuckers
+mousetrap
+munchies
+ne'er
+ok
+ole
+penis
+pentameter
+pere
+peyote
+poena
+pox
+provideth
+qui
+rabbinical
+rabelaisian
+racquet
+rhumba
+saideth
+schlemiel
+shalt
+shit
+shithead's
+shits
+showgirls
+sissies
+sleaze
+soit
+spake
+sphincter
+spikey
+strewed
+suckin
+sucky
+suh
+tonsillectomy
+tooties
+trashcan
+truckloads
+ulcerous
+veni
+vici
+whimsy
+wildebeest
+yamalchas
+ylbatrofmoc
+yogurt
+zits
diff --git a/fortune/datfiles/fortunes.sp.ok b/fortune/datfiles/fortunes.sp.ok
new file mode 100644
index 00000000..e9fbace0
--- /dev/null
+++ b/fortune/datfiles/fortunes.sp.ok
@@ -0,0 +1,1978 @@
+A.A.A.A.A
+A.D
+AAAAAAAAAaaaaaaaaaaaaaaaccccccccckkkkkk
+ACHTUNG
+AI
+ALU
+ANRS
+ARCHDUKE
+ASHes
+ATN
+Abbie
+Adamite
+Ade
+Adlai
+Admas
+Adolf
+Aelius
+Aesop
+Aha
+Ahrimanes
+Albran
+Aldous
+Aleliunas
+Ali
+Alito
+Allan
+Alo
+Alvy
+Amana
+Amerigo
+Amica
+Amityville
+Amnesia
+Amp
+Amrom
+Anatol
+Androids
+Ankh
+Anoint
+Antonym
+Apocryphia
+Applebome
+Apr
+Aquadextrous
+Aquarians
+Ardis
+Arlo
+Arpa
+Ashleigh
+Asimov
+Aspasia
+Aspin
+Assateague
+Assoc
+Asterix
+Atlee
+Auden
+Audobon
+Avogardo
+Aww
+B'nai
+BARF
+BARFUCIOUS
+BASICs
+BBBF
+BBW
+BEANSTACK
+BEW
+BH
+BITCHEN
+BLAH
+BLEAH
+BLETCHEROUS
+BLOTTO
+BMR
+BOOGA
+BPO
+BST
+BULLWINKLE
+BUTTHEADS
+BYOB
+Ba
+Baba
+Bacall
+Bachtrian
+Bagbiter
+Bagdikian's
+Bai
+Baines
+Banach
+Banectomy
+Barach's
+Barbie
+Barf
+Bargewater
+Baruch's
+Basie's
+Bathquake
+Batman
+Baumol
+Bax
+Beagle
+Beal
+Beatty
+Beckett
+Beckmann
+Begathon
+Begatting
+Begone
+Behan
+Beifeld's
+Belloc
+Benares
+Benchley
+Berke
+Bernighan
+Bertold
+Bertolt
+Bierce
+Biff
+Billericay
+Bionic
+Bizoos
+Blaise
+Blish
+Blore
+Blore's
+Blount
+Bluestone
+Bodenheim
+Bok
+Bokonon
+Bolub's
+Bombeck's
+Boob's
+Boola
+Boothe
+Bootle
+Boren's
+Borge
+Boynton
+Brahma
+Bramah
+Brandwein
+Brecht
+Brickman
+Brith
+Broido
+Brontosaurus
+Brunner
+Brutus
+Bryne's
+Buckminster
+Bucky
+Bucy's
+Buhr
+Bullwinkle
+Bumstead
+Burggoven
+Burkowski
+Busmanship
+C&O
+C.I.A
+C.R.T
+CABERNET
+CChheecckk
+CDS
+CHARDONNAY
+CI
+CLBR
+CLBRI
+CLICK...CLICK...WHIRRR...CLICK
+CM
+CMFRM
+CONGRAM
+CONtractor
+CPPR
+CPU
+CPU's
+CPUs
+CRN
+CS
+CTA
+CVP
+Caen
+Cahn's
+Caissons
+Calio's
+Camillo
+Camptown
+Capt
+Carmel
+Carotene
+Carotene's
+Carperpetuation
+Carrol
+Cary
+Casablanca
+Caspar
+Cat:man
+Cavour
+Celibacy
+Centauri
+Cerebron
+Cerebus
+Channing
+Chapin
+Charnock's
+Chateaubriand
+Chatterley's
+Cheatham
+Checkuary
+Cheez
+Chem
+Chesterson
+Chevins
+Chichester
+Chism's
+Chisolm's
+Chloroplast's
+Chok
+Chung's
+Churchy
+Ciardi
+Cinemuck
+Claghorn
+Clair
+Clapton
+Clarkson
+Cleyre
+Clopton
+Cogito
+Cointment
+Collis
+Colton
+Colvard's
+Commie
+Computerdom
+Connell
+Connellan
+Constipation
+Contrariwise
+Corky
+Cory
+Cosmo
+Crabgrass
+Cray
+Creemy
+Cripps
+Croll
+Croll's
+Cuomo
+Curchill
+Cuticle
+Cyberiad
+Cybernetic
+D'Arcy
+D'Azevedo
+D.C
+DAC
+DAMMIT
+DAV
+DCL
+DCS
+DECzilla
+DELI
+DETERIORATA
+DEVO
+DFA
+DINGELL
+DMPK
+DOODAH
+DP
+Dabba
+Daft
+Dagobah
+Dagwood
+Dalglish
+Damian
+Danforth
+Darrow
+Darryl
+Darth
+Das
+Davisson
+DeVries
+DeVries's
+Decot
+Defactualization
+Deloria
+DesCartes
+Deteriorata
+Devine
+Devo
+Diamondback
+Diddly
+Dijkstra
+Dingell
+Dirksen
+Disco
+Disraeli
+Dobb's
+Doc
+Dolph
+Donatus
+Doo
+Doonesbury
+Drabek
+Drescher
+Dristan
+Dropt
+Ducharme's
+Duckie
+Dum
+Dunne
+Durance
+Durant
+Dykstra
+Dyson
+E.T
+EAROM
+EBCDIC
+ELECTROCUTION
+EMPC
+ENIACs
+EPI
+EXCE
+Eagleson
+Eagleson's
+Ebenezum
+Ebert
+Eckstein
+Edman
+Edpress
+Eggnog
+Ehrman's
+Elbert
+Electrocution
+Ellery
+Elliot
+Elroy
+Elven
+Elvis
+Elvish
+Emmons
+Emo
+Emu
+Enm
+Ennui
+Epperson's
+Erogenous
+Ertz
+Es
+Esser
+Euell
+Eustace
+Exupery
+FERSURE
+FF
+FINO
+FROB
+FROBBOTZIM
+FROBBOZ
+FROBNITZ
+FROBNODULE
+FROBNULE
+FROBULE
+FROTZ
+FWWAAAAAAPPPP
+Fafhrd
+Fainali
+Fakir
+Falkland
+Fandal
+Farrow
+Fatherland
+Feiffer
+Feiner
+Femme
+Fenelon
+Ferm
+Fidel
+Fiebig
+Fiedler
+Filkharmonics
+Fillmore
+Finagle
+Finagle's
+Finagling
+Firesign
+Firth
+Flagg
+Flannagan's
+Flaubert
+Flinstone
+Flon's
+Flugg's
+Flummery
+Foghorn
+Follen
+Forbiddie
+Forssman
+Fortue
+Fosdick
+Foxx
+Fran
+Francois
+Frayn
+Friedrich
+Frisbee
+Frisbeetarianism
+Frito
+Frobnicate
+Frobnitz
+Frobnitzem
+Frodo
+Froot
+Fruitcakes
+Fuch's
+Fudd
+Fudd's
+Fuoss
+Furbling
+Furst
+Fylstra
+GC
+GC7500439
+GO.SYSIN
+GOBLIN
+GOTO
+GRAMmer
+GRODY
+GUGUs
+GUISEPPE
+GUMM
+GUMMed
+Ga
+Galbraith
+Galilei
+Galileo
+Galvani
+Galvani's
+Gamekeeping
+Gandalf
+Gandhi
+Gastly
+Gaultier
+Gauvreay
+Geis
+Genderplex
+Gerat
+Gerrold's
+Ghandi
+Ghostbusters
+Giddens
+Gigo
+Gilda
+Gilpkerio
+Gimlet
+Gimmie
+Glaser
+Gnagloot
+Godel's
+Godot
+Godzilla
+Goestheveezl
+Golda
+Goldenstern's
+Goldwyn
+Gondoliers
+Goodbye
+Goodgulf
+Gopete
+Gorbachev
+Gorden
+Gorey
+Gotama
+Gotlieb
+Goto
+Gotta
+Goulden
+Goy's
+Grabel's
+Graffiti
+Graffito
+Greenstein
+Gregorian
+Grelb's
+Gries
+Grishman
+Groucho
+Guardsman
+Guiseppe
+Gumps
+Gurmlish
+H.S
+HCF
+HED
+HEE
+HOAX
+HOB'LIN
+HOOTCH
+HR
+Hackensack
+Hadassah
+Haeckel
+Hahahahahahahahaha
+Haig
+Hain't
+Haleleuia
+Hanukka
+Hara
+Harary
+Harbride
+Harlequin
+Harpoon
+Harrisberger's
+Harrold
+Hartke
+Havelock
+Hawkeye
+Hawkwind
+Haynie
+Hegel
+Heineken
+Heinlein
+Hellman
+Hellman's
+Henny
+Henrick
+Henrik
+Hepler
+Herford
+Higgeldy
+Hilaire
+Hillary's
+Hinckley
+Hipcrime
+Hippogriff
+Hitchhiker's
+Hlade's
+Hoare
+Hoare's
+Hoban
+Hoffenstein
+Hofstadter
+Hofstadter's
+Holton
+Homespun
+Hoppe
+Horngren's
+Housman
+Huntingdon
+Hurewitz's
+I.R.S
+IBP
+ID's
+II.a
+INSQSW
+Iacocca
+Ian
+Ibson
+Iear
+Iears
+Ignatowski
+Ignisecond
+Il
+Iles
+Iles's
+Ingliy
+Ingmar
+Inlaws
+Irsin
+Isaak
+Isiah
+Iso
+Issac
+Issawi
+Issawi's
+Ist
+Italo
+Ium
+JELL
+JFK
+Jackals
+Jacquin's
+Jael
+Jaka
+Jarry
+Jaspar
+Jawaharlal
+Jehan
+Jell
+Jenerally
+Jenkinson's
+Jenks
+Jenning's
+Jonathon
+Jone's
+Jonesboro
+Jordache
+Josh
+Juliana
+Jun
+Jung
+Justin
+KLUDGE
+KOBOLDS
+KPH
+Kabotschniks
+Kan
+Kandel
+Kari
+Kasner
+Kasspe
+Kauffmann
+Kaul
+Keate
+Kehlog
+Keir
+Kellen
+Kempson
+Kenobi
+Kerwin
+Kesey
+Kiernan
+Kinkler's
+Kistomerces
+Kitman
+Kitzenger
+Kleptomaniac
+Klingons
+Klone
+Knebel
+Knuth
+Ko
+Kool
+Korda
+Kr
+Krispies
+Krogt
+Ks
+Kulawiec
+L.A
+LAFITE
+LAIDBACK
+LIBRA
+LITHP
+LSD
+LaRouchefoucauld
+Lackland's
+Lactomangulation
+Ladybug
+Laetrile
+Lafferty
+Lampson
+Landburgher
+Langsam's
+Lankhmar
+Lankhmar's
+Lapham
+Lapwarmer
+Lardner
+Larkinson's
+Lassie
+Laverne
+Lazlo's
+LeGuin
+Lebowitz
+Leedom
+Lehrer
+Leibe
+Leiber
+Leibowitz
+Leibowitz's
+Leith
+Lem
+Lenore
+Les
+Lettvin
+Levant
+Leverett
+Libra
+Lichty
+Lieberman's
+Liebling
+Liebowitz
+Lilla
+Linkletter
+Lippmann
+Liza
+Logg's
+Logicians
+Longworth
+Lookit
+Lovin
+Lowery's
+Ltd
+Lubarsky's
+Luce
+Ludcke
+Luddites
+Luigi
+Lumsden
+Luten
+Lyndon
+Lysistrata
+M&Ms
+M.T.A
+MAFIA
+MANCHA
+MC
+MDL
+MERCUTIO
+MHz
+MOS
+MSCP
+MW
+MX
+MYSTERIANS
+Mabbitt
+MacDowell
+MacKay
+MacNelley
+MacNiece
+Macaroons
+Macy's
+Madelyn
+Magee
+Magnocartic
+Mahabharata
+Mahatma
+Mai
+Malek's
+Mammel
+Mandrell
+Manhandling
+Mankiewicz
+Marley
+Marshalltown
+Maryel
+Mascheroni
+Maslow
+Mathis
+Maud
+Maugham
+Maxey
+Maxson
+McCloctnik
+McEvoy
+McLuhan
+McNulty
+Medawar
+Meese
+Meir
+Melott
+Mem'ry
+Mencken
+Mencken's
+Mengot
+Mensa
+Merrick
+Meskimen's
+Meta
+Metz
+Mewling
+Meyrowitz
+Mia
+Michener
+Mikado
+Miksch's
+Milkbone
+Millay
+Millihelen
+Millions
+Millman
+Milpitas
+Minas
+Minnelli
+Mitgong
+Moby
+Mohandas
+Mollison's
+Mom
+Mongo
+Montagu
+Mophobia
+Moping
+Mordor
+Morganstern
+Morrisey
+Mosher's
+Mudgeeraba
+Mudhead
+Muhammad
+Muppet
+Murdoch
+Mustgo
+Myung
+NEWSFLASH
+NYT
+Nader
+Naeser's
+Naiman
+Napolean
+Narnia
+Nasrudin
+Natasha
+Nate
+Nather
+Neantical
+Neizant
+Neo
+Nerd
+Neronic
+Nesbitt
+Nevil
+Newlan's
+Ngdanga
+Ni
+Nicklaus
+Nicol
+Niels
+Nikita
+Niklaus
+Ningauble
+Noelie
+Nome
+Nora's
+Novocain
+Nutley
+O'Casey
+O'Hara
+O'Henry
+O'Longhlin
+O'Neil
+O'Rourke
+O'Toole's
+O.K
+OMERTA
+OMNIVERSAL
+OR'd
+OS
+OUTCONERR
+Obi
+Ogborn
+Olivier
+Omar
+Omnibiblious
+Onan
+Ontopsychological
+Ontopsychology
+Ope
+Ophelia
+Orac
+Orben
+Orson
+Ozman's
+P.B.A
+P.M
+P.O
+PBC
+PDGERS
+PDP
+PDQ
+PDSK
+PL
+POPI
+POWDERMILK
+PRL
+PROCESSORs
+PVLC
+Paar
+Padlipsky
+Paley
+Pandanga
+Pardo's
+Parnas
+Parnell
+Parrafin
+Patageometry
+Pecor's
+Pedaeration
+Pegler
+Pensacoola
+Penzance
+Pereant
+Perlis
+Petr
+Pharaoh
+Philbin
+Philogyny
+Phooey
+Picninnies
+Piggeldy
+Pilgermann
+Pirsig
+Plaese
+Platypus
+Pluribus
+Pocataligo
+Pocatello
+Podunk
+Pohl's
+Poincair
+Polanski
+Porcus
+Postpetroleum
+Poul
+Presley
+Preudhomme's
+Prochnow
+Prue
+Psblurtex
+Publilius
+Pumpernickel
+Putluck
+Pynchon
+QT
+QWERT
+QWERTYUIOP
+Quidquid
+Quigley's
+Quincey
+Quincunx
+Quinton
+Quux
+Qvid
+RAMs
+RASC
+RFD
+ROMs
+RPG
+RSSC
+RTAB
+RWDSK
+RWOC
+RXS
+Ra
+Radner
+Raisa
+Raisinets
+Ransford
+Raskin
+Reba
+Redd
+Regan
+Reggie
+Reisner's
+Relaxen
+Ren
+Renner
+Renning's
+Richardian
+Richie
+Rigby
+Rilke
+Robb
+Robespierre
+Roche
+Rochefoucauld
+Roddick
+Rogerians
+Roguelet's
+Roguies
+Rolex
+Romas
+Romulans
+Rooney
+Rosten
+Rotherham
+Rouchefoucauld
+Roumania
+Roxbury
+Royko
+Rubenstein
+Rubik's
+Rudin's
+Ruffed
+Rukn
+Rupert
+Russel
+Russon
+S.U.N.Y
+SARTRE
+SCCS
+SCRBL
+SIGPLAN
+SLC
+SLOBOL
+SNA
+SPSW
+SRSD
+Safford
+Safire's
+Sagan
+Sagittarians
+Salome
+Salvor
+Santoro
+Sappho
+Sargon
+Sartre
+Sauron
+Sayre
+Schapiro's
+Schickel
+Schickele
+Schlattwhapper
+Schmivalry
+Schmonsequences
+Schnuffel
+Schrodinger's
+Schryer
+Schure
+Schwambach
+Schwiggle
+Schwine
+Scrubb
+Se
+Seager
+Seeger
+Seldon
+Seleznick's
+Sep
+Septober
+Serendipity
+Serling
+Serocki's
+Sevenoaks
+Shalt
+Shamus
+Sheil
+Shel
+Sherany
+Shmoedipus
+Shoaff
+Shoales
+Shuman
+Si
+Sigismund
+Silurian
+Silverstein
+Simard
+Sixtus
+Sjoberg
+Skyler
+Slinkies
+Slurm
+Smit
+Smollet
+Smurfies
+Snacktrek
+Sniglets
+Snowman
+Snowmass
+Socio
+Sodd's
+Sorhed
+SoupCon
+Sox
+Spam
+Speer's
+Spirtle
+Spisani
+Spock
+Sta
+Stallman
+Stanislaw
+Steelypips
+Steinbach's
+Steinem
+Stoffel
+Stoppard
+Stormtroopers
+Stretchy
+Stult's
+Suden
+Sulu
+Sumeria
+Summatra
+Sunward
+Supercalifragilisticexpialidocius
+Svevo
+Swaller
+Swinburne
+Swipple's
+Syrus
+T'ai
+T'umps
+T.H
+TAA
+TDB
+TLC
+TSO
+TSP
+Tabby
+Taber
+Taber's
+Tai
+Tanenbaum
+Tannenbaum
+Tarradiddles
+Teddywookie
+Terence
+Tertullian
+Teruillian
+Thames
+Theatre
+Thieu
+Thom
+Thoul't
+Threepio
+Throop
+Thurber
+Thyself
+Tierra
+Tijuana
+Tikkanen
+Titas
+Tobias
+Tock
+Tomlin
+Tonka
+Toto
+Touche
+Toup
+Toven
+Tribbles
+Tricia
+Trimble
+Troney
+Trotsky
+Trudeau
+Truscott
+Tse
+Tsu
+Tue
+Turgenev
+Turnaucka's
+Tussman's
+Tut's
+Twas
+Tweedledee
+Tweedledum
+Twodor
+Twodor's
+U.S
+U.S.S.R
+UDA50
+UFO's
+URK
+UT
+UTCS
+Ubi
+Un
+Una
+Und
+Updike
+Urey
+VALGOL
+VAX
+VAX's
+VAXen
+VAXs
+VCR
+VCR's
+VIDEOCASSETTE
+VLSI
+VMS
+VODKA
+VSOP
+VYARZERZOMANIMORORSEZASSEZANSERAREORSES
+Vannevar
+Vate
+Vax
+Veeck
+Velilind's
+Veni
+Venn
+Vespucci
+Vespuccia
+Vic
+Vidal
+Vidi
+Vila
+Vinchy
+Vinci
+Virt
+Vittorini
+Vo
+Vocab
+Vogon
+Volkswagon
+Voltarine
+Vonada
+Vonnegut
+Vonnegut's
+Vries
+Vroomfondel
+Vulgate
+WBT
+WHATEVERSAROUND
+WOMBAT
+WORLD's
+WXRT
+Waben
+Wald
+Walinsky
+Walla
+Warhol
+Wat
+Watford
+Watterson
+Weil
+Weiler's
+Weiner's
+Weisert
+Wernher
+Westbrook
+Westbury
+Westheimer's
+Westmoreland
+Wethern's
+Whaddya
+Whipsnade
+Wiker's
+Wilde
+Winchell
+Winie
+Winsor
+Wir
+Wirrten
+Wirth
+Withington
+Wombat's
+XIIdigitation
+XINU
+Xercies
+YEH
+Yabba
+Yellowstone
+Yessir
+Yinkel
+Yo
+Yoda
+Yoda's
+Yorba
+Yoric
+Youngman
+Yuletide
+Yutang
+ZIPPY
+ZORAC
+Zanuck
+Zappa
+Zarathud
+Zarathustra
+Zelkowitz
+Zeno's
+Zern
+Zilla
+Zippy
+Zonker
+Zorkmids
+Zorro
+Zow
+Zwanzig
+Zwart
+Zymurgy's
+a.m
+aafte
+abhors
+absorbin
+absurdum
+acacia
+accurancy
+accursed
+accusator
+acne
+acupuncture
+adhoc
+adj
+adv
+airbags
+alimentary
+alkafluence
+alleygaroo
+alrighty
+altum
+amnesia
+anal
+anat
+anchorman
+ane
+animalculous
+anomali
+anxivs
+anymore
+anytime
+apauling
+appelations
+approx
+arabic
+arias
+arse
+ary
+asparaginylalanylthreonylleucylarginylalanylphenylalanylalanylalanylglycylva
+aspartylleucylleucylarginylglutaminylisoleucylalanylseryltyrosylglycylarginyl
+astrology
+ath
+atrium
+atttempt
+ause
+ausgraben
+avoirdupois
+awai
+ay
+bac
+backlit
+bagbiting
+bagel
+bahz
+bai
+bamboozled
+banquette
+barf
+bayonetted
+bazingas
+bedecked
+bedpans
+befriends
+bequeathin
+bertillion
+bethumped
+bi
+bibles
+bingo
+bisexual
+blackguard
+blinkenlights
+blockhead
+blound
+blowenfusen
+bogosity
+bonehead
+bonked
+boola
+bossy
+bounteous
+bowlin
+boyfriend
+bra
+brilgue
+brilig
+brussels
+bucky
+burgled
+burneth
+ca
+caliente
+calor
+capillarized
+carabineri
+carbolized
+cardio
+castrating
+ch
+chemotherapy
+cheque
+cheval
+chezlogs
+childproof
+chromosome
+chronodimensional
+chroots
+claus
+cm
+cmptr
+cn
+cnt
+cockamamie
+cogito
+colloq
+congresspersons
+conks
+copacetic
+corkenpoppen
+corpuscle
+cpu
+cpu's
+crabgrass
+crapshoot
+criminology
+croquet
+crossoffs
+crossword
+crowbar
+crunchy
+crustaceans
+crusty
+cummings
+curiae
+cuticle
+cybernetic
+da
+damnfoolproof
+dandruff
+dans
+darkish
+darkroom
+das
+dataspec
+dduupplleexx
+de
+defamed
+defuse
+demagogism
+demigodic
+demo
+deppart
+der
+dermis
+destitution
+dev
+dextrose
+diddie
+dinette
+dis
+disco
+discotheques
+dishes
+dishrags
+dishwashing
+dixerunt
+dm
+doderez
+doggerel
+doggy
+doloop
+dost
+doth
+dotty
+drivel
+drop't
+dummkopfen
+dumpster
+dunkt
+e.g
+ecamier
+ee
+eggnog
+ein
+enobled
+enui
+er
+ergo
+erogeny
+es
+est
+etus
+ev'ry
+exhalation
+extemporanea
+extracurricular
+eyestalks
+fainali
+fallaron
+fella
+fertsneet
+figgy
+fiks
+filees
+filename
+filors
+fix'd
+fixin's
+flang
+flatfoot
+floss
+fo
+foghorns
+folkloric
+foo
+forcaster
+fornia
+fornication
+forsooth
+fractal
+freezin
+frillant
+frob
+frob'nitsm
+frobbing
+frolicked
+fruh
+fruitcake
+fruitcakes
+frumious
+funhouse
+galore
+gamekeeper
+ganz
+garnishment
+gd
+gefingerpoken
+genocide
+gesteckt
+gewerken
+gharsley
+giftlist
+gimble
+gimmick
+girlfriend
+gleekzorp
+gleknow
+glowworm
+glycylalanylaspartylalanylleucylglutamylleucylglycylisoleucylprolyphenylalanyl
+glycyltyrosylthreonyltyrosylleucylleucylserylarginylalanylglycylvalylthreonyl
+gobbets
+gonna
+goodbye
+goto
+gougebosquex
+goyim
+goyish
+goyisha
+graffito
+grok
+grouse
+gry
+gt
+guave
+guttersnipe
+gylcylalanylglutamylasparaginylarginyalanylalanylleucylprolylleucylaspartagi
+gyre
+gyrent
+haben
+hain't
+hairstyles
+hammmer
+handcraftsmanship
+handwaving
+hanky
+harmonium
+headgear
+hectare
+heinous
+hermit
+hev
+hexagram
+highbrow
+hippogriff
+honorific
+honour
+hoo
+hooved
+horgrave
+hormonal
+hors
+hotshot
+houseplant
+housewares
+hullabaloo
+humour
+hyper
+i'm
+i.e
+ibi
+icepacks
+ideogram
+ideograms
+iear
+iers
+ifthen
+ihn
+ihuxw
+impo
+incivility
+incomprehensive
+incorrige
+infiniteloop
+inkahol
+innumerate
+inprectoo
+inputdir
+inquit
+inrushing
+insa
+interferon
+ironmongery
+itn
+ius
+jast
+jb
+jeered
+judex
+jukebox
+ka
+kar
+karat
+karma
+kase
+keepen
+kiloliks
+kitsch
+klows
+kludge
+kludgy
+klutz
+knock'd
+koan
+kohirnt
+konsonant
+konsonants
+kontinue
+kudn't
+kwirt
+l'Amour
+ladybug
+lampshades
+lank
+lanylglycylalanylisoleucylserylglycylserylalanylisoleucylvalyllysylisoleucyli
+latine
+lawnmower
+le
+lerts
+les
+letez
+leucylphenylalanylisoleucylcysteinylprolylprolylaspartylalanylaspartylaspartyl
+lexicographer
+libricilleux
+liegt
+lightbulb
+limerick
+lin
+linguini
+lithtth
+lobotomy
+locutions
+logick
+logout
+logy
+logzerneg
+lojikl
+lurketh
+lyaspartylglutaminylvalyllysylalanylalanylisoleucylaspartylalanylglycylalanyla
+lysdexia
+lythreonylprolyalanylglutaminylcysteinylphenylalanylglutamylmethionylleucyala
+m'I
+ma'am
+magtape
+maindz
+mainframe
+mal
+margarita
+masochist
+masturbation
+mausers
+megs
+meik
+meltdown
+memoraboble
+memori
+memorizin
+meowing
+merinos
+meta
+methionylglutaminylarginyltyrosylglutamylserylluecylphenyialanylalanylglutamin
+methionyllysylalanylalanylthreonylarginylserine
+midterm
+millions
+mimsy
+min
+minx
+mit
+mittengrabben
+mizk
+mobocracy
+modifaiing
+mohmen
+moldy
+mome
+mon
+mousetraps
+musculus
+myxbl
+n'oeuvres
+nah
+nanocentury
+nanohenry
+naugahyde
+nell
+net.fat
+net.flame
+net.jobs
+net.news
+net.that
+net.this
+ni
+nicht
+nightie
+nog
+nogiftlist
+nohow
+nonrefusable
+nostra
+nth
+nunnery
+nylasparaginyllysylglycylisoleucylaspartylglutamylphenylalanyltyrosylalanylglu
+nylaspartylvalylprolylvalylglutaminylglutamylserylalanylprolyphenylalanylargi
+nylglutaminylalanylalanylleucylarginylhistidylasparaginylvalylalanylprolyiso
+nylhistidylleucylvalylalanyllysylleucylysylglutamyltyrosylasparaginylalanylala
+nylleucylisoleucylarginylglutaminyllysylhistidylprolythreonylisoleucylprolyli
+nylprolylprolylleucylglutaminylglycylphenylalanylglycylisoleucylserylalanylpro
+obits
+obius
+obnegleich
+obscurantist
+okay
+ol;lkld;f;g;dd;po
+oln
+omelette
+omerade
+omnibiblious
+omnivorous
+ompzidaize
+oodsou
+ooh
+orxogrefkl
+ould
+outcumbents
+outgrabe
+outta
+ov
+oves
+p'o
+p.m
+padanga
+pallbearer
+panky
+pantaloons
+paperboy
+paroxysmally
+penis
+pense
+perfum'd
+phenylalanylyalylthreonylleucylglycylaspartylprolylglycylisoleucylglutamylglu
+philogyny
+pl
+pl.n
+planaria
+platypus
+pleH
+po
+pointy
+poiuyt
+poly
+polytetien
+polytheism
+poo
+popcorn
+porrf
+posibl
+posthole
+potty
+poz
+ppo
+prawns
+pre
+prepoceros
+pretzel
+prgrmmng
+priestess
+primordial
+proceedeth
+proletarian
+propounded
+protheththing
+protien
+protoplasmal
+pulitzer
+pur
+pushy
+qotc
+qui
+quia
+quiche
+quop
+qwert
+qwertyuiop
+rKe9
+raed
+raineth
+raisiny
+randchar
+rapturous
+raspy
+rath
+raths
+rd
+reich
+replased
+replasing
+rhinoceri
+ridandant
+riform
+rigadoon
+rimeining
+rind
+riplais
+rispektivli
+risqu
+rosewater
+rubbernecken
+rubout
+runtime
+ry
+sam
+samurai
+samuri
+santa
+savour
+sawhorse
+schlichte
+schnappen
+scullery
+seashells
+sei
+serylaspartylprolylleucylalanylaspartylglycylprolylthreonylisoleucylglutaminyl
+shalt
+shamus
+shinnied
+shlafen
+shorn
+sightie
+sightseeren
+siouxeyesighed
+sizeof
+skyhigh
+sligo
+smurfette
+snarley
+snowman
+soit
+soleucylglutamylglutaminylhistidylasparaginylisoleucylglutamylprolyglutamylly
+soleucylglyclleucylleucylmethionyltyrosylalanylasparaginylleucylvalylphenylala
+somebody'd
+sont
+spacewar
+spank
+spel
+speling
+spitzensparken
+spl
+springenwerk
+sq
+squrooneg
+sswwiittcchh
+stalagmites
+starfield
+statecraft
+steamrolling
+steeplechase
+stogies
+subsittute
+suet
+surly
+svm
+swang
+sweeteners
+switchover
+sylmethionylleucylalanylalanylleucyllysylvalylphenylalanylvalyglutaminylproly
+synagog
+synthetase
+syscalls
+tachyon
+taketh
+taminylcysteinylglutamyllysylvalylglycylvalylaspartylserylvalylleucylvalylala
+taminylserylleucyllysylisoleucylaspartylthreonylleucylisoleucylglutamylalanyl
+tannogallate
+tapioca
+tarot
+tbsp
+teddy
+teepers
+telematic
+telepath
+tequila
+theivish
+thi
+thinkle
+thou'lt
+thru
+ths
+thyself
+tinhorn
+tites
+toehold
+tollway
+tommyo
+tornpee
+touch'd
+trampoline
+trans
+treacle
+tripoline
+truncheons
+tryptophan
+tsetse
+tsp
+tu
+tuit
+tuits
+tuppenny
+tween
+twixt
+tyg
+tyrranize
+ukelele
+umsige
+unbegot
+und
+uns
+unvoist
+uretheral
+urgin's
+ust
+v.intrans
+v.trans
+valium
+varicose
+vatch
+ve
+velcro
+verreckt
+vichyssoise
+viditur
+vo
+voist
+vol
+vowlz
+vu
+w4k
+wa
+watchout
+weatherman
+weenies
+weirdo
+wench
+werld
+whaledreck
+whilst
+whodo
+whomped
+wi
+wid
+wimmelten
+wimp
+wombat
+wonse
+woodburning
+workingman
+wr
+wrth
+wrung
+wud
+xanthic
+xe
+xen
+xrewawt
+xsz
+ylleucyllysylglutamylarginyllysylglutamylglycylalanylphenylalanylvalylprolyl
+yo
+you'se
+yyoouurr
+zayda
+zephyr's
diff --git a/fortune/datfiles/startrek b/fortune/datfiles/startrek
new file mode 100644
index 00000000..a5155cb3
--- /dev/null
+++ b/fortune/datfiles/startrek
@@ -0,0 +1,756 @@
+A father doesn't destroy his children.
+ -- Lt. Carolyn Palamas, "Who Mourns for Adonais?",
+ stardate 3468.1.
+%
+A little suffering is good for the soul.
+ -- Kirk, "The Corbomite Maneuver", stardate 1514.0
+%
+A man either lives life as it happens to him, meets it head-on and
+licks it, or he turns his back on it and starts to wither away.
+ -- Dr. Boyce, "The Menagerie" ("The Cage"), stardate unknown
+%
+A princess should not be afraid -- not with a brave knight to protect
+her.
+ -- McCoy, "Shore Leave", stardate 3025.3
+%
+A star captain's most solemn oath is that he will give his life, even
+his entire crew, rather than violate the Prime Directive.
+ -- Kirk, "The Omega Glory", stardate unknown
+%
+A Vulcan can no sooner be disloyal than he can exist without
+breathing.
+ -- Kirk, "The Menagerie", stardate 3012.4
+%
+A woman should have compassion.
+ -- Kirk, "Catspaw", stardate 3018.2
+%
+Actual war is a very messy business. Very, very messy business.
+ -- Kirk, "A Taste of Armageddon", stardate 3193.0
+%
+After a time, you may find that "having" is not so pleasing a thing,
+after all, as "wanting." It is not logical, but it is often true.
+ -- Spock, "Amok Time", stardate 3372.7
+%
+All your people must learn before you can reach for the stars.
+ -- Kirk, "The Gamesters of Triskelion", stardate 3259.2
+%
+Another Armenia, Belgium ... the weak innocents who always seem to be
+located on a natural invasion route.
+ -- Kirk, "Errand of Mercy", stardate 3198.4
+%
+Another dream that failed. There's nothing sadder.
+ -- Kirk, "This side of Paradise", stardate 3417.3
+%
+Another war ... must it always be so? How many comrades have we lost
+in this way? ... Obedience. Duty. Death, and more death ...
+ -- Romulan Commander, "Balance of Terror", stardate 1709.2
+%
+... bacteriological warfare ... hard to believe we were once foolish
+enough to play around with that.
+ -- McCoy, "The Omega Glory", stardate unknown
+%
+"Beauty is transitory."
+"Beauty survives."
+ -- Spock and Kirk, "That Which Survives", stardate unknown
+%
+Behind every great man, there is a woman -- urging him on.
+ -- Harry Mudd, "I, Mudd", stardate 4513.3
+%
+Blast medicine anyway! We've learned to tie into every organ in the
+human body but one. The brain! The brain is what life is all about.
+ -- McCoy, "The Menagerie", stardate 3012.4
+%
+But it's real. And if it's real it can be affected ... we may not be
+able to break it, but, I'll bet you credits to Navy Beans we can put a
+dent in it.
+ -- deSalle, "Catspaw", stardate 3018.2
+%
+"Can you imagine how life could be improved if we could do away with
+jealousy, greed, hate ..."
+
+"It can also be improved by eliminating love, tenderness, sentiment --
+the other side of the coin"
+ -- Dr. Roger Corby and Kirk, "What are Little Girls Made Of?",
+ stardate 2712.4
+%
+Change is the essential process of all existence.
+ -- Spock, "Let That Be Your Last Battlefield", stardate 5730.2
+%
+Compassion -- that's the one things no machine ever had. Maybe it's
+the one thing that keeps men ahead of them.
+ -- McCoy, "The Ultimate Computer", stardate 4731.3
+%
+Computers make excellent and efficient servants, but I have no wish to
+serve under them. Captain, a starship also runs on loyalty to one
+man. And nothing can replace it or him.
+ -- Spock, "The Ultimate Computer", stardate 4729.4
+%
+Conquest is easy. Control is not.
+ -- Kirk, "Mirror, Mirror", stardate unknown
+%
+Death, when unnecessary, is a tragic thing.
+ -- Flint, "Requiem for Methuselah", stardate 5843.7
+%
+Death. Destruction. Disease. Horror. That's what war is all about.
+That's what makes it a thing to be avoided.
+ -- Kirk, "A Taste of Armageddon", stardate 3193.0
+%
+Do you know about being with somebody? Wanting to be? If I had the
+whole universe, I'd give it to you, Janice. When I see you, I feel
+like I'm hungry all over. Do you know how that feels?
+ -- Charlie Evans, "Charlie X", stardate 1535.8
+%
+Do you know the one -- "All I ask is a tall ship, and a star to steer
+her by ..." You could feel the wind at your back, about you ... the
+sounds of the sea beneath you. And even if you take away the wind and
+the water, it's still the same. The ship is yours ... you can feel her
+... and the stars are still there.
+ -- Kirk, "The Ultimate Computer", stardate 4729.4
+%
+[Doctors and Bartenders], We both get the same two kinds of customers
+-- the living and the dying.
+ -- Dr. Boyce, "The Menagerie" ("The Cage"), stardate unknown
+%
+Each kiss is as the first.
+ -- Miramanee, Kirk's wife, "The Paradise Syndrome",
+ stardate 4842.6
+%
+Earth -- mother of the most beautiful women in the universe.
+ -- Apollo, "Who Mourns for Adonais?" stardate 3468.1
+%
+Either one of us, by himself, is expendable. Both of us are not.
+ -- Kirk, "The Devil in the Dark", stardate 3196.1
+%
+Emotions are alien to me. I'm a scientist.
+ -- Spock, "This Side of Paradise", stardate 3417.3
+%
+Even historians fail to learn from history -- they repeat the same
+mistakes.
+ -- John Gill, "Patterns of Force", stardate 2534.7
+%
+Every living thing wants to survive.
+ -- Spock, "The Ultimate Computer", stardate 4731.3
+%
+"Evil does seek to maintain power by suppressing the truth."
+"Or by misleading the innocent."
+ -- Spock and McCoy, "And The Children Shall Lead",
+ stardate 5029.5.
+%
+Extreme feminine beauty is always disturbing.
+ -- Spock, "The Cloud Minders", stardate 5818.4
+%
+Fascinating is a word I use for the unexpected.
+ -- Spock, "The Squire of Gothos", stardate 2124.5
+%
+Fascinating, a totally parochial attitude.
+ -- Spock, "Metamorphosis", stardate 3219.8
+%
+First study the enemy. Seek weakness.
+ -- Romulan Commander, "Balance of Terror", stardate 1709.2
+%
+Four thousand throats may be cut in one night by a running man.
+ -- Klingon Soldier, "Day of the Dove", stardate unknown
+%
+"... freedom ... is a worship word..."
+"It is our worship word too."
+ -- Cloud William and Kirk, "The Omega Glory", stardate unknown
+%
+Genius doesn't work on an assembly line basis. You can't simply say,
+"Today I will be brilliant."
+ -- Kirk, "The Ultimate Computer", stardate 4731.3
+%
+"Get back to your stations!"
+"We're beaming down to the planet, sir."
+ -- Kirk and Mr. Leslie, "This Side of Paradise",
+ stardate 3417.3
+%
+He's dead, Jim
+ -- McCoy, "The Devil in the Dark", stardate 3196.1
+%
+History tends to exaggerate.
+ -- Col. Green, "The Savage Curtain", stardate 5906.4
+%
+Humans do claim a great deal for that particular emotion (love).
+ -- Spock, "The Lights of Zetar", stardate 5725.6
+%
+I am pleased to see that we have differences. May we together become
+greater than the sum of both of us.
+ -- Surak of Vulcan, "The Savage Curtain", stardate 5906.4
+%
+I have never understood the female capacity to avoid a direct answer to
+any question.
+ -- Spock, "This Side of Paradise", stardate 3417.3
+%
+I object to intellect without discipline; I object to power without
+constructive purpose.
+ -- Spock, "The Squire of Gothos", stardate 2124.5
+%
+I realize that command does have its fascination, even under
+circumstances such as these, but I neither enjoy the idea of command
+nor am I frightened of it. It simply exists, and I will do whatever
+logically needs to be done.
+ -- Spock, "The Galileo Seven", stardate 2812.7
+%
+"I think they're going to take all this money that we spend now on war
+and death --"
+"And make them spend it on life."
+ -- Edith Keeler and Kirk, "The City on the Edge of Forever",
+ stardate unknown.
+%
+I thought my people would grow tired of killing. But you were right,
+they see it is easier than trading. And it has its pleasures. I feel
+it myself. Like the hunt, but with richer rewards.
+ -- Apella, "A Private Little War", stardate 4211.8
+%
+I'm a soldier, not a diplomat. I can only tell the truth.
+ -- Kirk, "Errand of Mercy", stardate 3198.9
+%
+I'm frequently appalled by the low regard you Earthmen have for life.
+ -- Spock, "The Galileo Seven", stardate 2822.3
+%
+I've already got a female to worry about. Her name is the Enterprise.
+ -- Kirk, "The Corbomite Maneuver", stardate 1514.0
+%
+If a man had a child who'd gone anti-social, killed perhaps, he'd still
+tend to protect that child.
+ -- McCoy, "The Ultimate Computer", stardate 4731.3
+%
+If I can have honesty, it's easier to overlook mistakes.
+ -- Kirk, "Space Seed", stardate 3141.9
+%
+If some day we are defeated, well, war has its fortunes, good and bad.
+ -- Commander Kor, "Errand of Mercy", stardate 3201.7
+%
+If there are self-made purgatories, then we all have to live in them.
+ -- Spock, "This Side of Paradise", stardate 3417.7
+%
+Immortality consists largely of boredom.
+ -- Zefrem Cochrane, "Metamorphosis", stardate 3219.8
+%
+In the strict scientific sense we all feed on death -- even
+vegetarians.
+ -- Spock, "Wolf in the Fold", stardate 3615.4
+%
+Insufficient facts always invite danger.
+ -- Spock, "Space Seed", stardate 3141.9
+%
+Insults are effective only where emotion is present.
+ -- Spock, "Who Mourns for Adonais?" stardate 3468.1
+%
+Intuition, however illogical, is recognized as a command prerogative.
+ -- Kirk, "Obsession", stardate 3620.7
+%
+Is not that the nature of men and women -- that the pleasure is in the
+learning of each other?
+ -- Natira, the High Priestess of Yonada, "For the World is
+ Hollow and I Have Touched the Sky", stardate 5476.3.
+%
+Is truth not truth for all?
+ -- Natira, "For the World is Hollow and I have Touched
+ the Sky", stardate 5476.4.
+%
+It [being a Vulcan] means to adopt a philosophy, a way of life which is
+logical and beneficial. We cannot disregard that philosophy merely for
+personal gain, no matter how important that gain might be.
+ -- Spock, "Journey to Babel", stardate 3842.4
+%
+It is a human characteristic to love little animals, especially if
+they're attractive in some way.
+ -- McCoy, "The Trouble with Tribbles", stardate 4525.6
+%
+It is more rational to sacrifice one life than six.
+ -- Spock, "The Galileo Seven", stardate 2822.3
+%
+It is necessary to have purpose.
+ -- Alice #1, "I, Mudd", stardate 4513.3
+%
+It is undignified for a woman to play servant to a man who is not
+hers.
+ -- Spock, "Amok Time", stardate 3372.7
+%
+It would be illogical to assume that all conditions remain stable
+ -- Spock, "The Enterprise" Incident", stardate 5027.3
+%
+It would be illogical to kill without reason
+ -- Spock, "Journey to Babel", stardate 3842.4
+%
+It would seem that evil retreats when forcibly confronted
+ -- Yarnek of Excalbia, "The Savage Curtain", stardate 5906.5
+%
+"It's hard to believe that something which is neither seen nor felt can
+do so much harm."
+
+"That's true. But an idea can't be seen or felt. And that's what kept
+the Troglytes in the mines all these centuries. A mistaken idea."
+ -- Vanna and Kirk, "The Cloud Minders", stardate 5819.0
+%
+Killing is stupid; useless!
+ -- McCoy, "A Private Little War", stardate 4211.8
+%
+Killing is wrong.
+ -- Losira, "That Which Survives", stardate unknown
+%
+Knowledge, sir, should be free to all!
+ -- Harry Mudd, "I, Mudd", stardate 4513.3
+%
+Landru! Guide us!
+ -- A Beta 3-oid, "The Return of the Archons", stardate 3157.4
+%
+Leave bigotry in your quarters; there's no room for it on the bridge.
+ -- Kirk, "Balance of Terror", stardate 1709.2
+%
+"Life and death are seldom logical."
+"But attaining a desired goal always is."
+ -- McCoy and Spock, "The Galileo Seven", stardate 2821.7
+%
+Live long and prosper.
+ -- Spock, "Amok Time", stardate 3372.7
+%
+"Logic and practical information do not seem to apply here."
+"You admit that?"
+"To deny the facts would be illogical, Doctor"
+ -- Spock and McCoy, "A Piece of the Action", stardate unknown
+%
+Lots of people drink from the wrong bottle sometimes.
+ -- Edith Keeler, "The City on the Edge of Forever",
+ stardate unknown
+%
+Love sometimes expresses itself in sacrifice.
+ -- Kirk, "Metamorphosis", stardate 3220.3
+%
+Madness has no purpose. Or reason. But it may have a goal.
+ -- Spock, "The Alternative Factor", stardate 3088.7
+%
+Many Myths are based on truth
+ -- Spock, "The Way to Eden", stardate 5832.3
+%
+Men don't talk peace unless they're ready to back it up with war.
+ -- Col. Green, "The Savage Curtain", stardate 5906.4
+%
+Men of peace usually are [brave].
+ -- Spock, "The Savage Curtain", stardate 5906.5
+%
+Men will always be men -- no matter where they are.
+ -- Harry Mudd, "Mudd's Women", stardate 1329.8
+%
+Military secrets are the most fleeting of all.
+ -- Spock, "The Enterprise Incident", stardate 5027.4
+%
+Most legends have their basis in facts.
+ -- Kirk, "And The Children Shall Lead", stardate 5029.5
+%
+Murder is contrary to the laws of man and God.
+ -- M-5 Computer, "The Ultimate Computer", stardate 4731.3
+%
+No more blah, blah, blah!
+ -- Kirk, "Miri", stardate 2713.6
+%
+No one can guarantee the actions of another.
+ -- Spock, "Day of the Dove", stardate unknown
+%
+No one may kill a man. Not for any purpose. It cannot be condoned.
+ -- Kirk, "Spock's Brain", stardate 5431.6
+%
+"No one talks peace unless he's ready to back it up with war."
+"He talks of peace if it is the only way to live."
+ -- Colonel Green and Surak of Vulcan, "The Savage Curtain",
+ stardate 5906.5.
+%
+No one wants war.
+ -- Kirk, "Errand of Mercy", stardate 3201.7
+%
+No problem is insoluble.
+ -- Dr. Janet Wallace, "The Deadly Years", stardate 3479.4
+%
+Not one hundred percent efficient, of course ... but nothing ever is.
+ -- Kirk, "Metamorphosis", stardate 3219.8
+%
+Oblivion together does not frighten me, beloved.
+ -- Thalassa (in Anne Mulhall's body), "Return to Tomorrow",
+ stardate 4770.3.
+%
+Oh, that sound of male ego. You travel halfway across the galaxy and
+it's still the same song.
+ -- Eve McHuron, "Mudd's Women", stardate 1330.1
+%
+On my planet, to rest is to rest -- to cease using energy. To me, it
+is quite illogical to run up and down on green grass, using energy,
+instead of saving it.
+ -- Spock, "Shore Leave", stardate 3025.2
+%
+One does not thank logic.
+ -- Sarek, "Journey to Babel", stardate 3842.4
+%
+One of the advantages of being a captain is being able to ask for
+advice without necessarily having to take it.
+ -- Kirk, "Dagger of the Mind", stardate 2715.2
+%
+Only a fool fights in a burning house.
+ -- Kank the Klingon, "Day of the Dove", stardate unknown
+%
+Our missions are peaceful -- not for conquest. When we do battle, it
+is only because we have no choice.
+ -- Kirk, "The Squire of Gothos", stardate 2124.5
+%
+Our way is peace.
+ -- Septimus, the Son Worshiper, "Bread and Circuses",
+ stardate 4040.7.
+%
+Pain is a thing of the mind. The mind can be controlled.
+ -- Spock, "Operation -- Annihilate!" stardate 3287.2
+%
+Peace was the way.
+ -- Kirk, "The City on the Edge of Forever", stardate unknown
+%
+Power is danger.
+ -- The Centurion, "Balance of Terror", stardate 1709.2
+%
+Prepare for tomorrow -- get ready.
+ -- Edith Keeler, "The City On the Edge of Forever",
+ stardate unknown
+%
+Punishment becomes ineffective after a certain point. Men become
+insensitive.
+ -- Eneg, "Patterns of Force", stardate 2534.7
+%
+Respect is a rational process
+ -- McCoy, "The Galileo Seven", stardate 2822.3
+%
+Romulan women are not like Vulcan females. We are not dedicated to
+pure logic and the sterility of non-emotion.
+ -- Romulan Commander, "The Enterprise Incident",
+ stardate 5027.3
+%
+Schshschshchsch.
+ -- The Gorn, "Arena", stardate 3046.2
+%
+Sometimes a feeling is all we humans have to go on.
+ -- Kirk, "A Taste of Armageddon", stardate 3193.9
+%
+Sometimes a man will tell his bartender things he'll never tell his doctor.
+ -- Dr. Phillip Boyce, "The Menagerie" ("The Cage"),
+ stardate unknown.
+%
+Star Trek Lives!
+%
+Suffocating together ... would create heroic camaraderie.
+ -- Khan Noonian Singh, "Space Seed", stardate 3142.8
+%
+Superior ability breeds superior ambition.
+ -- Spock, "Space Seed", stardate 3141.9
+%
+"That unit is a woman."
+"A mass of conflicting impulses."
+ -- Spock and Nomad, "The Changeling", stardate 3541.9
+%
+"The combination of a number of things to make existence worthwhile."
+"Yes, the philosophy of 'none,' meaning 'all.'"
+ -- Spock and Lincoln, "The Savage Curtain", stardate 5906.4
+%
+The face of war has never changed. Surely it is more logical to heal
+than to kill.
+ -- Surak of Vulcan, "The Savage Curtain", stardate 5906.5
+%
+The games have always strengthened us. Death becomes a familiar
+pattern. We don't fear it as you do.
+ -- Proconsul Marcus Claudius, "Bread and Circuses",
+ stardate 4041.2
+%
+"The glory of creation is in its infinite diversity."
+"And in the way our differences combine to create meaning and beauty."
+ -- Dr. Miranda Jones and Spock, "Is There in Truth No Beauty?",
+ stardate 5630.8
+%
+The heart is not a logical organ.
+ -- Dr. Janet Wallace, "The Deadly Years", stardate 3479.4
+%
+The idea of male and female are universal constants.
+ -- Kirk, "Metamorphosis", stardate 3219.8
+%
+The joys of love made her human and the agonies of love destroyed her.
+ -- Spock, "Requiem for Methuselah", stardate 5842.8
+%
+The man on tops walks a lonely street; the "chain" of command is often
+a noose.
+%
+The more complex the mind, the greater the need for the simplicity of
+play.
+ -- Kirk, "Shore Leave", stardate 3025.8
+%
+The only solution is ... a balance of power. We arm our side with
+exactly that much more. A balance of power -- the trickiest, most
+difficult, dirtiest game of them all. But the only one that preserves
+both sides.
+ -- Kirk, "A Private Little War", stardate 4211.8
+%
+The people of Gideon have always believed that life is sacred. That
+the love of life is the greatest gift ... We are incapable of
+destroying or interfering with the creation of that which we love so
+deeply -- life in every form from fetus to developed being.
+ -- Hodin of Gideon, "The Mark of Gideon", stardate 5423.4
+%
+... The prejudices people feel about each other disappear when then get
+to know each other.
+ -- Kirk, "Elaan of Troyius", stardate 4372.5
+%
+"The release of emotion is what keeps us health. Emotionally healthy."
+
+"That may be, Doctor. However, I have noted that the healthy release
+of emotion is frequently unhealthy for those closest to you."
+ -- McCoy and Spock, "Plato's Stepchildren", stardate 5784.3
+%
+The sight of death frightens them [Earthers].
+ -- Kras the Klingon, "Friday's Child", stardate 3497.2
+%
+The sooner our happiness together begins, the longer it will last.
+ -- Miramanee, "The Paradise Syndrome", stardate 4842.6
+%
+... The things love can drive a man to -- the ecstasies, the
+the miseries, the broken rules, the desperate chances, the glorious
+failures and the glorious victories.
+ -- McCoy, "Requiem for Methuselah", stardate 5843.7
+%
+There are always alternatives.
+ -- Spock, "The Galileo Seven", stardate 2822.3
+%
+There are certain things men must do to remain men.
+ -- Kirk, "The Ultimate Computer", stardate 4929.4
+%
+There are some things worth dying for.
+ -- Kirk, "Errand of Mercy", stardate 3201.7
+%
+There comes to all races an ultimate crisis which you have yet to face
+.... One day our minds became so powerful we dared think of ourselves
+as gods.
+ -- Sargon, "Return to Tomorrow", stardate 4768.3
+%
+There is a multi-legged creature crawling on your shoulder.
+ -- Spock, "A Taste of Armageddon", stardate 3193.9
+%
+There is an old custom among my people. When a woman saves a man's
+life, he is grateful.
+ -- Nona, the Kanuto which woman, "A Private Little War",
+ stardate 4211.8.
+%
+There is an order of things in this universe.
+ -- Apollo, "Who Mourns for Adonais?" stardate 3468.1
+%
+There's a way out of any cage.
+ -- Captain Christopher Pike, "The Menagerie" ("The Cage"),
+ stardate unknown.
+%
+There's another way to survive. Mutual trust -- and help.
+ -- Kirk, "Day of the Dove", stardate unknown
+%
+There's no honorable way to kill, no gentle way to destroy. There is
+nothing good in war. Except its ending.
+ -- Abraham Lincoln, "The Savage Curtain", stardate 5906.5
+%
+There's nothing disgusting about it [the Companion]. It's just another
+life form, that's all. You get used to those things.
+ -- McCoy, "Metamorphosis", stardate 3219.8
+%
+"There's only one kind of woman ..."
+"Or man, for that matter. You either believe in yourself or you don't."
+ -- Kirk and Harry Mudd, "Mudd's Women", stardate 1330.1
+%
+This cultural mystique surrounding the biological function -- you
+realize humans are overly preoccupied with the subject.
+ -- Kelinda the Kelvan, "By Any Other Name", stardate 4658.9
+%
+Those who hate and fight must stop themselves -- otherwise it is not
+stopped.
+ -- Spock, "Day of the Dove", stardate unknown
+%
+Time is fluid ... like a river with currents, eddies, backwash.
+ -- Spock, "The City on the Edge of Forever", stardate 3134.0
+%
+To live is always desirable.
+ -- Eleen the Capellan, "Friday's Child", stardate 3498.9
+%
+Too much of anything, even love, isn't necessarily a good thing.
+ -- Kirk, "The Trouble with Tribbles", stardate 4525.6
+%
+Totally illogical, there was no chance.
+ -- Spock, "The Galileo Seven", stardate 2822.3
+%
+Uncontrolled power will turn even saints into savages. And we can all
+be counted on to live down to our lowest impulses.
+ -- Parmen, "Plato's Stepchildren", stardate 5784.3
+%
+Violence in reality is quite different from theory.
+ -- Spock, "The Cloud Minders", stardate 5818.4
+%
+Virtue is a relative term.
+ -- Spock, "Friday's Child", stardate 3499.1
+%
+Vulcans believe peace should not depend on force.
+ -- Amanda, "Journey to Babel", stardate 3842.3
+%
+Vulcans do not approve of violence.
+ -- Spock, "Journey to Babel", stardate 3842.4
+%
+Vulcans never bluff.
+ -- Spock, "The Doomsday Machine", stardate 4202.1
+%
+Vulcans worship peace above all.
+ -- McCoy, "Return to Tomorrow", stardate 4768.3
+%
+Wait! You have not been prepared!
+ -- Mr. Atoz, "Tomorrow is Yesterday", stardate 3113.2
+%
+War is never imperative.
+ -- McCoy, "Balance of Terror", stardate 1709.2
+%
+War isn't a good life, but it's life.
+ -- Kirk, "A Private Little War", stardate 4211.8
+%
+[War] is instinctive. But the instinct can be fought. We're human
+beings with the blood of a million savage years on our hands! But we
+can stop it. We can admit that we're killers ... but we're not going
+to kill today. That's all it takes! Knowing that we're not going to
+kill today!
+ -- Kirk, "A Taste of Armageddon", stardate 3193.0
+%
+We do not colonize. We conquer. We rule. There is no other way for
+us.
+ -- Rojan, "By Any Other Name", stardate 4657.5
+%
+We fight only when there is no other choice. We prefer the ways of
+peaceful contact.
+ -- Kirk, "Spectre of the Gun", stardate 4385.3
+%
+We have found all life forms in the galaxy are capable of superior
+development.
+ -- Kirk, "The Gamesters of Triskelion", stardate 3211.7
+%
+We have phasers, I vote we blast 'em!
+ -- Bailey, "The Corbomite Maneuver", stardate 1514.2
+%
+"We have the right to survive!"
+"Not be killing others."
+ -- Deela and Kirk, "Wink of An Eye", stardate 5710.5
+%
+We Klingons believe as you do -- the sick should die. Only the strong
+should live.
+ -- Kras, "Friday's Child", stardate 3497.2
+%
+We're all sorry for the other guy when he loses his job to a machine.
+But when it comes to your job -- that's different. And it always will
+be different.
+ -- McCoy, "The Ultimate Computer", stardate 4729.4
+%
+"What happened to the crewman?"
+
+"The M-5 computer needed a new power source, the crewman merely got in
+the way."
+ -- Kirk and Dr. Richard Daystrom, "The Ultimate Computer",
+ stardate 4731.3.
+%
+What kind of love is that? Not to be loved; never to have shown love.
+ -- Commissioner Nancy Hedford, "Metamorphosis",
+ stardate 3219.8
+%
+"What terrible way to die."
+"There are no good ways."
+ -- Sulu and Kirk, "That Which Survives", stardate unknown
+%
+When a child is taught ... its programmed with simple instructions --
+and at some point, if its mind develops properly, it exceeds the sum of
+what it was taught, thinks independently.
+ -- Dr. Richard Daystrom, "The Ultimate Computer",
+ stardate 4731.3.
+%
+When dreams become more important than reality, you give up travel,
+building, creating; you even forget how to repair the machines left
+behind by your ancestors. You just sit living and reliving other lives
+left behind in the thought records.
+ -- Vina, "The Menagerie" ("The Cage"), stardate unknown
+%
+Where there's no emotion, there's no motive for violence.
+ -- Spock, "Dagger of the Mind", stardate 2715.1
+%
+Witch! Witch! They'll burn ya!
+ -- Hag, "Tomorrow is Yesterday", stardate unknown
+%
+Without facts, the decision cannot be made logically. You must rely on
+your human intuition.
+ -- Spock, "Assignment: Earth", stardate unknown
+%
+Without followers, evil cannot spread.
+ -- Spock, "And The Children Shall Lead", stardate 5029.5
+%
+Without freedom of choice there is no creativity.
+ -- Kirk, "The return of the Archons", stardate 3157.4
+%
+Women are more easily and more deeply terrified ... generating more
+sheer horror than the male of the species.
+ -- Spock, "Wolf in the Fold", stardate 3615.4
+%
+Women professionals do tend to over-compensate.
+ -- Dr. Elizabeth Dehaver, "Where No Man Has Gone Before",
+ stardate 1312.9.
+%
+Worlds are conquered, galaxies destroyed -- but a woman is always a
+woman.
+ -- Kirk, "Conscience of the King", stardate unknown
+%
+Worlds may change, galaxies disintegrate, but a woman always remains a
+woman.
+ -- Kirk, "The Conscience of the King", stardate 2818.9
+%
+Yes, it is written. Good shall always destroy evil.
+ -- Sirah the Yang, "The Omega Glory", stardate unknown
+%
+You are an excellent tactician, Captain. You let your second in
+command attack while you sit and watch for weakness.
+ -- Khan Noonian Singh, "Space Seed", stardate 3141.9
+%
+You can't evaluate a man by logic alone.
+ -- McCoy, "I, Mudd", stardate 4513.3
+%
+You Earth people glorified organized violence for forty centuries. But
+you imprison those who employ it privately.
+ -- Spock, "Dagger of the Mind", stardate 2715.1
+%
+You go slow, be gentle. It's no one-way street -- you know how you
+feel and that's all. It's how the girl feels too. Don't press. If
+the girl feels anything for you at all, you'll know.
+ -- Kirk, "Charlie X", stardate 1535.8
+%
+You humans have that emotional need to express gratitude. "You're
+welcome," I believe, is the correct response.
+ -- Spock, "Bread and Circuses", stardate 4041.2
+%
+You say you are lying. But if everything you say is a lie, then you
+are telling the truth. You cannot tell the truth because everything
+you say is a lie. You lie, you tell the truth ... but you cannot, for
+you lie.
+ -- Norman the android, "I, Mudd", stardate 4513.3
+%
+You speak of courage. Obviously you do not know the difference between
+courage and foolhardiness. Always it is the brave ones who die, the
+soldiers.
+ -- Kor, the Klingon Commander, "Errand of Mercy",
+ stardate 3201.7
+%
+You! What PLANET is this!
+ -- McCoy, "The City on the Edge of Forever", stardate 3134.0
+%
+You'll learn something about men and women -- the way they're supposed
+to be. Caring for each other, being happy with each other, being good
+to each other. That's what we call love. You'll like that a lot.
+ -- Kirk, "The Apple", stardate 3715.6
+%
+You're dead, Jim.
+ -- McCoy, "Amok Time", stardate 3372.7
+%
+You're dead, Jim.
+ -- McCoy, "The Tholian Web", stardate unknown
+%
+You're too beautiful to ignore. Too much woman.
+ -- Kirk to Yeoman Rand, "The Enemy Within", stardate unknown
+%
+Youth doesn't excuse everything.
+ -- Dr. Janice Lester (in Kirk's body), "Turnabout Intruder",
+ stardate 5928.5.
diff --git a/fortune/datfiles/startrek.sp.ok b/fortune/datfiles/startrek.sp.ok
new file mode 100644
index 00000000..41ecbdfc
--- /dev/null
+++ b/fortune/datfiles/startrek.sp.ok
@@ -0,0 +1,86 @@
+Adonais
+Amanda
+Apella
+Archons
+Armenia
+Atoz
+Capellan
+Catspaw
+Centurion
+Changeling
+Claudius
+Corbomite
+Corby
+Daystrom
+Deela
+Dehaver
+Elaan
+Eleen
+Eneg
+Excalbia
+Galileo
+Gorn
+Gothos
+Hag
+Hedford
+Hodin
+Kank
+Kanuto
+Kelinda
+Kelvan
+Klingon
+Klingons
+Kor
+Kras
+Landru
+Losira
+Lt
+McHuron
+Miramanee
+Miri
+Mulhall's
+Natira
+Nomad
+Nona
+Noonian
+Palamas
+Parmen
+Phillip
+Priestess
+Proconsul
+Requiem
+Rojan
+Romulan
+Sarek
+Sargon
+Schshschshchsch
+Septimus
+Singh
+Sirah
+Spectre
+Spock
+Spock's
+Stepchildren
+Sulu
+Surak
+Thalassa
+Tholian
+Tribbles
+Triskelion
+Troglytes
+Troyius
+Vanna
+Vina
+Yarnek
+Yonada
+Zefrem
+Zetar
+android
+backwash
+bacteriological
+blah
+deSalle
+oid
+stardate
+tactician
+ya
diff --git a/fortune/datfiles/zippy b/fortune/datfiles/zippy
new file mode 100644
index 00000000..c9ed1061
--- /dev/null
+++ b/fortune/datfiles/zippy
@@ -0,0 +1,1333 @@
+A can of ASPARAGUS, 73 pigeons, some LIVE ammo, and a FROZEN DAQUIRI!!
+%
+A dwarf is passing out somewhere in Detroit!
+%
+A shapely CATHOLIC SCHOOLGIRL is FIDGETING inside my costume..
+%
+A wide-eyed, innocent UNICORN, poised delicately in a MEADOW filled
+with LILACS, LOLLIPOPS & small CHILDREN at the HUSH of twilight??
+%
+Actually, what I'd like is a little toy spaceship!!
+%
+All I can think of is a platter of organic PRUNE CRISPS being trampled
+by an army of swarthy, Italian LOUNGE SINGERS ...
+%
+All of a sudden, I want to THROW OVER my promising ACTING CAREER, grow
+a LONG BLACK BEARD and wear a BASEBALL HAT!! ... Although I don't know
+WHY!!
+%
+All of life is a blur of Republicans and meat!
+%
+All right, you degenerates! I want this place evacuated in 20 seconds!
+%
+All this time I've been VIEWING a RUSSIAN MIDGET SODOMIZE a HOUSECAT!
+%
+Alright, you!! Imitate a WOUNDED SEAL pleading for a PARKING SPACE!!
+%
+Am I accompanied by a PARENT or GUARDIAN?
+%
+Am I elected yet?
+%
+Am I in GRADUATE SCHOOL yet?
+%
+Am I SHOPLIFTING?
+%
+America!! I saw it all!! Vomiting! Waving! JERRY FALWELLING into
+your void tube of UHF oblivion!! SAFEWAY of the mind ...
+%
+An air of FRENCH FRIES permeates my nostrils!!
+%
+An INK-LING? Sure -- TAKE one!! Did you BUY any COMMUNIST UNIFORMS??
+%
+An Italian is COMBING his hair in suburban DES MOINES!
+%
+And furthermore, my bowling average is unimpeachable!!!
+%
+ANN JILLIAN'S HAIR makes LONI ANDERSON'S HAIR look like RICARDO
+MONTALBAN'S HAIR!
+%
+Are the STEWED PRUNES still in the HAIR DRYER?
+%
+Are we live or on tape?
+%
+Are we on STRIKE yet?
+%
+Are we THERE yet?
+%
+Are we THERE yet? My MIND is a SUBMARINE!!
+%
+Are you mentally here at Pizza Hut??
+%
+Are you selling NYLON OIL WELLS?? If so, we can use TWO DOZEN!!
+%
+Are you still an ALCOHOLIC?
+%
+As President I have to go vacuum my coin collection!
+%
+Awright, which one of you hid my PENIS ENVY?
+%
+BARBARA STANWYCK makes me nervous!!
+%
+Barbie says, Take quaaludes in gin and go to a disco right away!
+But Ken says, WOO-WOO!! No credit at "Mr. Liquor"!!
+%
+BARRY ... That was the most HEART-WARMING rendition of "I DID IT MY
+WAY" I've ever heard!!
+%
+Being a BALD HERO is almost as FESTIVE as a TATTOOED KNOCKWURST.
+%
+BELA LUGOSI is my co-pilot ...
+%
+BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-
+%
+... bleakness ... desolation ... plastic forks ...
+%
+Bo Derek ruined my life!
+%
+Boy, am I glad it's only 1971...
+%
+Boys, you have ALL been selected to LEAVE th' PLANET in 15 minutes!!
+%
+But they went to MARS around 1953!!
+%
+But was he mature enough last night at the lesbian masquerade?
+%
+Can I have an IMPULSE ITEM instead?
+%
+Can you MAIL a BEAN CAKE?
+%
+Catsup and Mustard all over the place! It's the Human Hamburger!
+%
+CHUBBY CHECKER just had a CHICKEN SANDWICH in downtown DULUTH!
+%
+Civilization is fun! Anyway, it keeps me busy!!
+%
+Clear the laundromat!! This whirl-o-matic just had a nuclear meltdown!!
+%
+Concentrate on th'cute, li'l CARTOON GUYS! Remember the SERIAL
+NUMBERS!! Follow the WHIPPLE AVE. EXIT!! Have a FREE PEPSI!! Turn
+LEFT at th'HOLIDAY INN!! JOIN the CREDIT WORLD!! MAKE me an OFFER!!!
+%
+CONGRATULATIONS! Now should I make thinly veiled comments about
+DIGNITY, self-esteem and finding TRUE FUN in your RIGHT VENTRICLE??
+%
+Content: 80% POLYESTER, 20% DACRONi ... The waitress's UNIFORM sheds
+TARTAR SAUCE like an 8" by 10" GLOSSY ...
+%
+Could I have a drug overdose?
+%
+Did an Italian CRANE OPERATOR just experience uninhibited sensations in
+a MALIBU HOT TUB?
+%
+Did I do an INCORRECT THING??
+%
+Did I say I was a sardine? Or a bus???
+%
+Did I SELL OUT yet??
+%
+Did YOU find a DIGITAL WATCH in YOUR box of VELVEETA?
+%
+Did you move a lot of KOREAN STEAK KNIVES this trip, Dingy?
+%
+DIDI ... is that a MARTIAN name, or, are we in ISRAEL?
+%
+Didn't I buy a 1951 Packard from you last March in Cairo?
+%
+Disco oil bussing will create a throbbing naugahide pipeline running
+straight to the tropics from the rug producing regions and devalue the
+dollar!
+%
+Do I have a lifestyle yet?
+%
+Do you guys know we just passed thru a BLACK HOLE in space?
+%
+Do you have exactly what I want in a plaid poindexter bar bat??
+%
+Do you like "TENDER VITTLES"?
+%
+Do you think the "Monkees" should get gas on odd or even days?
+%
+Does someone from PEORIA have a SHORTER ATTENTION span than me?
+%
+does your DRESSING ROOM have enough ASPARAGUS?
+%
+DON'T go!! I'm not HOWARD COSELL!! I know POLISH JOKES ... WAIT!!
+Don't go!! I AM Howard Cosell! ... And I DON'T know Polish jokes!!
+%
+Don't hit me!! I'm in the Twilight Zone!!!
+%
+Don't SANFORIZE me!!
+%
+Don't worry, nobody really LISTENS to lectures in MOSCOW, either! ...
+FRENCH, HISTORY, ADVANCED CALCULUS, COMPUTER PROGRAMMING, BLACK
+STUDIES, SOCIOBIOLOGY! ... Are there any QUESTIONS??
+%
+Edwin Meese made me wear CORDOVANS!!
+%
+Eisenhower!! Your mimeograph machine upsets my stomach!!
+%
+Either CONFESS now or we go to "PEOPLE'S COURT"!!
+%
+Everybody gets free BORSCHT!
+%
+Everybody is going somewhere!! It's probably a garage sale or a
+disaster Movie!!
+%
+Everywhere I look I see NEGATIVITY and ASPHALT ...
+%
+Excuse me, but didn't I tell you there's NO HOPE for the survival of
+OFFSET PRINTING?
+%
+FEELINGS are cascading over me!!!
+%
+Finally, Zippy drives his 1958 RAMBLER METROPOLITAN into the faculty
+dining room.
+%
+First, I'm going to give you all the ANSWERS to today's test ... So
+just plug in your SONY WALKMANS and relax!!
+%
+FOOLED you! Absorb EGO SHATTERING impulse rays, polyester poltroon!!
+%
+for ARTIFICIAL FLAVORING!!
+%
+Four thousand different MAGNATES, MOGULS & NABOBS are romping in my
+gothic solarium!!
+%
+FROZEN ENTREES may be flung by members of opposing SWANSON SECTS ...
+%
+FUN is never having to say you're SUSHI!!
+%
+Gee, I feel kind of LIGHT in the head now, knowing I can't make my
+satellite dish PAYMENTS!
+%
+Gibble, Gobble, we ACCEPT YOU ...
+%
+Give them RADAR-GUIDED SKEE-BALL LANES and VELVEETA BURRITOS!!
+%
+Go on, EMOTE! I was RAISED on thought balloons!!
+%
+GOOD-NIGHT, everybody ... Now I have to go administer FIRST-AID to my
+pet LEISURE SUIT!!
+%
+HAIR TONICS, please!!
+%
+Half a mind is a terrible thing to waste!
+%
+Hand me a pair of leather pants and a CASIO keyboard -- I'm living for
+today!
+%
+Has everybody got HALVAH spread all over their ANKLES??
+%
+Has everybody got HALVAH spread all over their ANKLES?? ... Now, it's
+time to "HAVE A NAGEELA"!!
+%
+... he dominates the DECADENT SUBWAY SCENE.
+%
+He is the MELBA-BEING ... the ANGEL CAKE ... XEROX him ... XEROX him --
+%
+He probably just wants to take over my CELLS and then EXPLODE inside me
+like a BARREL of runny CHOPPED LIVER! Or maybe he'd like to
+PSYCHOLIGICALLY TERRORISE ME until I have no objection to a RIGHT-WING
+MILITARY TAKEOVER of my apartment!! I guess I should call AL PACINO!
+%
+HELLO KITTY gang terrorizes town, family STICKERED to death!
+%
+HELLO, everybody, I'm a HUMAN!!
+%
+Hello, GORRY-O!! I'm a GENIUS from HARVARD!!
+%
+Hello. I know the divorce rate among unmarried Catholic Alaskan
+females!!
+%
+Hello. Just walk along and try NOT to think about your INTESTINES
+being almost FORTY YARDS LONG!!
+%
+Hello... IRON CURTAIN? Send over a SAUSAGE PIZZA! World War III? No
+thanks!
+%
+Hello? Enema Bondage? I'm calling because I want to be happy, I
+guess ...
+%
+Here I am at the flea market but nobody is buying my urine sample
+bottles ...
+%
+Here I am in 53 B.C. and all I want is a dill pickle!!
+%
+Here I am in the POSTERIOR OLFACTORY LOBULE but I don't see CARL SAGAN
+anywhere!!
+%
+Here we are in America ... when do we collect unemployment?
+%
+Hey, wait a minute!! I want a divorce!! ... you're not Clint Eastwood!!
+%
+Hey, waiter! I want a NEW SHIRT and a PONY TAIL with lemon sauce!
+%
+Hiccuping & trembling into the WASTE DUMPS of New Jersey like some
+drunken CABBAGE PATCH DOLL, coughing in line at FIORUCCI'S!!
+%
+Hmmm ... a CRIPPLED ACCOUNTANT with a FALAFEL sandwich is HIT by a
+TROLLEY-CAR ...
+%
+Hmmm ... A hash-singer and a cross-eyed guy were SLEEPING on a deserted
+island, when ...
+%
+Hmmm ... a PINHEAD, during an EARTHQUAKE, encounters an ALL-MIDGET
+FIDDLE ORCHESTRA ... ha ... ha ...
+%
+Hmmm ... an arrogant bouquet with a subtle suggestion of POLYVINYL
+CHLORIDE ...
+%
+Hold the MAYO & pass the COSMIC AWARENESS ...
+%
+HOORAY, Ronald!! Now YOU can marry LINDA RONSTADT too!!
+%
+How do I get HOME?
+%
+How do you explain Wayne Newton's POWER over millions? It's th'
+MOUSTACHE ... Have you ever noticed th' way it radiates SINCERITY,
+HONESTY & WARMTH? It's a MOUSTACHE you want to take HOME and introduce
+to NANCY SINATRA!
+%
+How many retured bricklayers from FLORIDA are out purchasing PENCIL
+SHARPENERS right NOW??
+%
+How's it going in those MODULAR LOVE UNITS??
+%
+How's the wife? Is she at home enjoying capitalism?
+%
+hubub, hubub, HUBUB, hubub, hubub, hubub, HUBUB, hubub, hubub, hubub.
+%
+HUGH BEAUMONT died in 1982!!
+%
+HUMAN REPLICAS are inserted into VATS of NUTRITIONAL YEAST ...
+%
+I always have fun because I'm out of my mind!!!
+%
+I am a jelly donut. I am a jelly donut.
+%
+I am a traffic light, and Alan Ginzberg kidnapped my laundry in 1927!
+%
+I am covered with pure vegetable oil and I am writing a best seller!
+%
+I am deeply CONCERNED and I want something GOOD for BREAKFAST!
+%
+I am having FUN... I wonder if it's NET FUN or GROSS FUN?
+%
+I am NOT a nut....
+%
+I appoint you ambassador to Fantasy Island!!!
+%
+I brought my BOWLING BALL -- and some DRUGS!!
+%
+I can't decide which WRONG TURN to make first!!
+%
+I can't decide which WRONG TURN to make first!! I wonder if BOB
+GUCCIONE has these problems!
+%
+I can't think about that. It doesn't go with HEDGES in the shape of
+LITTLE LULU -- or ROBOTS making BRICKS ...
+%
+I demand IMPUNITY!
+%
+I didn't order any WOO-WOO ... Maybe a YUBBA ... But no WOO-WOO!
+%
+I don't believe there really IS a GAS SHORTAGE ... I think it's all
+just a BIG HOAX on the part of the plastic sign salesmen -- to sell
+more numbers!!
+%
+... I don't know why but, suddenly, I want to discuss declining I.Q.
+LEVELS with a blue ribbon SENATE SUB-COMMITTEE!
+%
+I don't know WHY I said that ... I think it came from the FILLINGS in
+my read molars ...
+%
+... I don't like FRANK SINATRA or his CHILDREN.
+%
+I don't understand the HUMOUR of the THREE STOOGES!!
+%
+I feel ... JUGULAR ...
+%
+I feel better about world problems now!
+%
+I feel like a wet parking meter on Darvon!
+%
+I feel like I am sharing a ``CORN-DOG'' with NIKITA KHRUSCHEV ...
+%
+I feel like I'm in a Toilet Bowl with a thumbtack in my forehead!!
+%
+I feel partially hydrogenated!
+%
+I fill MY industrial waste containers with old copies of the
+"WATCHTOWER" and then add HAWAIIAN PUNCH to the top ... They look NICE
+in the yard ...
+%
+I guess it was all a DREAM ... or an episode of HAWAII FIVE-O ...
+%
+I guess you guys got BIG MUSCLES from doing too much STUDYING!
+%
+I had a lease on an OEDIPUS COMPLEX back in '81 ...
+%
+I had pancake makeup for brunch!
+%
+I have a TINY BOWL in my HEAD
+%
+I have a very good DENTAL PLAN. Thank you.
+%
+I have a VISION! It's a RANCID double-FISHWICH on an ENRICHED BUN!!
+%
+I have accepted Provolone into my life!
+%
+I have many CHARTS and DIAGRAMS..
+%
+... I have read the INSTRUCTIONS ...
+%
+-- I have seen the FUN --
+%
+I have seen these EGG EXTENDERS in my Supermarket ...
+%
+I have seen these EGG EXTENDERS in my Supermarket ... I have read the
+INSTRUCTIONS ...
+%
+I have the power to HALT PRODUCTION on all TEENAGE SEX COMEDIES!!
+%
+I HAVE to buy a new "DODGE MISER" and two dozen JORDACHE JEANS because
+my viewscreen is "USER-FRIENDLY"!!
+%
+I haven't been married in over six years, but we had sexual counseling
+every day from Oral Roberts!!
+%
+I hope I bought the right relish ... zzzzzzzzz ...
+%
+I hope something GOOD came in the mail today so I have a REASON to
+live!!
+%
+I hope the ``Eurythmics'' practice birth control ...
+%
+I hope you millionaires are having fun! I just invested half your life
+savings in yeast!!
+%
+I invented skydiving in 1989!
+%
+I joined scientology at a garage sale!!
+%
+I just forgot my whole philosophy of life!!!
+%
+I just got my PRINCE bumper sticker ... But now I can't remember WHO he
+is ...
+%
+I just had a NOSE JOB!!
+%
+I just had my entire INTESTINAL TRACT coated with TEFLON!
+%
+I just heard the SEVENTIES were over!! And I was just getting in touch
+with my LEISURE SUIT!!
+%
+I just remembered something about a TOAD!
+%
+I KAISER ROLL?! What good is a Kaiser Roll without a little COLE SLAW
+on the SIDE?
+%
+I Know A Joke
+%
+I know how to do SPECIAL EFFECTS!!
+%
+I know th'MAMBO!! I have a TWO-TONE CHEMISTRY SET!!
+%
+I know things about TROY DONAHUE that can't even be PRINTED!!
+%
+I left my WALLET in the BATHROOM!!
+%
+I like the way ONLY their mouths move ... They look like DYING OYSTERS
+%
+I like your SNOOPY POSTER!!
+%
+-- I love KATRINKA because she drives a PONTIAC. We're going away
+now. I fed the cat.
+%
+I love ROCK 'N ROLL! I memorized the all WORDS to "WIPE-OUT" in
+1965!!
+%
+I need to discuss BUY-BACK PROVISIONS with at least six studio
+SLEAZEBALLS!!
+%
+I once decorated my apartment entirely in ten foot salad forks!!
+%
+I own seven-eighths of all the artists in downtown Burbank!
+%
+I put aside my copy of "BOWLING WORLD" and think about GUN CONTROL
+legislation..
+%
+I represent a sardine!!
+%
+I request a weekend in Havana with Phil Silvers!
+%
+... I see TOILET SEATS ...
+%
+I selected E5 ... but I didn't hear "Sam the Sham and the Pharoahs"!
+%
+I smell a RANCID CORN DOG!
+%
+I smell like a wet reducing clinic on Columbus Day!
+%
+I think I am an overnight sensation right now!!
+%
+... I think I'd better go back to my DESK and toy with a few common
+MISAPPREHENSIONS ...
+%
+I think I'll KILL myself by leaping out of this 14th STORY WINDOW while
+reading ERICA JONG'S poetry!!
+%
+I think my career is ruined!
+%
+I used to be a FUNDAMENTALIST, but then I heard about the HIGH
+RADIATION LEVELS and bought an ENCYCLOPEDIA!!
+%
+... I want a COLOR T.V. and a VIBRATING BED!!!
+%
+I want a VEGETARIAN BURRITO to go ... with EXTRA MSG!!
+%
+I want a WESSON OIL lease!!
+%
+I want another RE-WRITE on my CEASAR SALAD!!
+%
+I want EARS! I want two ROUND BLACK EARS to make me feel warm 'n
+secure!!
+%
+... I want FORTY-TWO TRYNEL FLOATATION SYSTEMS installed within
+SIX AND A HALF HOURS!!!
+%
+I want the presidency so bad I can already taste the hors d'oeuvres.
+%
+I want to dress you up as TALLULAH BANKHEAD and cover you with VASELINE
+and WHEAT THINS ...
+%
+I want to kill everyone here with a cute colorful Hydrogen Bomb!!
+%
+I want to perform cranial activities with Tuesday Weld!!
+%
+... I want to perform cranial activities with Tuesday Weld!!
+%
+I want to read my new poem about pork brains and outer space ...
+%
+I want to so HAPPY, the VEINS in my neck STAND OUT!!
+%
+I want you to MEMORIZE the collected poems of EDNA ST VINCENT MILLAY
+... BACKWARDS!!
+%
+I want you to organize my PASTRY trays ... my TEA-TINS are gleaming in
+formation like a ROW of DRUM MAJORETTES -- please don't be FURIOUS with
+me --
+%
+I was born in a Hostess Cupcake factory before the sexual revolution!
+%
+I was making donuts and now I'm on a bus!
+%
+I wish I was a sex-starved manicurist found dead in the Bronx!!
+%
+I wish I was on a Cincinnati street corner holding a clean dog!
+%
+I wonder if BOB GUCCIONE has these problems!
+%
+I wonder if I could ever get started in the credit world?
+%
+I wonder if I ought to tell them about my PREVIOUS LIFE as a COMPLETE
+STRANGER?
+%
+I wonder if I should put myself in ESCROW!!
+%
+I wonder if there's anything GOOD on tonight?
+%
+I would like to urinate in an OVULAR, porcelain pool --
+%
+I'd like MY data-base JULIENNED and stir-fried!
+%
+I'd like some JUNK FOOD ... and then I want to be ALONE --
+%
+I'll eat ANYTHING that's BRIGHT BLUE!!
+%
+I'll show you MY telex number if you show me YOURS ...
+%
+I'm a fuschia bowling ball somewhere in Brittany
+%
+I'm a GENIUS! I want to dispute sentence structure with SUSAN
+SONTAG!!
+%
+I'm a nuclear submarine under the polar ice cap and I need a Kleenex!
+%
+I'm also against BODY-SURFING!!
+%
+I'm also pre-POURED pre-MEDITATED and pre-RAPHAELITE!!
+%
+I'm ANN LANDERS!! I can SHOPLIFT!!
+%
+I'm changing the CHANNEL ... But all I get is commercials for "RONCO
+MIRACLE BAMBOO STEAMERS"!
+%
+I'm continually AMAZED at th'breathtaking effects of WIND EROSION!!
+%
+I'm definitely not in Omaha!
+%
+I'm DESPONDENT ... I hope there's something DEEP-FRIED under this
+miniature DOMED STADIUM ...
+%
+I'm dressing up in an ill-fitting IVY-LEAGUE SUIT!! Too late...
+%
+I'm EMOTIONAL now because I have MERCHANDISING CLOUT!!
+%
+I'm encased in the lining of a pure pork sausage!!
+%
+I'm GLAD I remembered to XEROX all my UNDERSHIRTS!!
+%
+I'm gliding over a NUCLEAR WASTE DUMP near ATLANTA, Georgia!!
+%
+I'm having a BIG BANG THEORY!!
+%
+I'm having a MID-WEEK CRISIS!
+%
+I'm having a RELIGIOUS EXPERIENCE ... and I don't take any DRUGS
+%
+I'm having a tax-deductible experience! I need an energy crunch!!
+%
+I'm having an emotional outburst!!
+%
+I'm having an EMOTIONAL OUTBURST!! But, uh, WHY is there a WAFFLE in
+my PAJAMA POCKET??
+%
+I'm having BEAUTIFUL THOUGHTS about the INSIPID WIVES of smug and
+wealthy CORPORATE LAWYERS ...
+%
+I'm having fun HITCHHIKING to CINCINNATI or FAR ROCKAWAY!!
+%
+... I'm IMAGINING a sensuous GIRAFFE, CAVORTING in the BACK ROOM
+of a KOSHER DELI --
+%
+I'm in direct contact with many advanced fun CONCEPTS.
+%
+I'm into SOFTWARE!
+%
+I'm meditating on the FORMALDEHYDE and the ASBESTOS leaking into my
+PERSONAL SPACE!!
+%
+I'm mentally OVERDRAWN! What's that SIGNPOST up ahead? Where's ROD
+STERLING when you really need him?
+%
+I'm not an Iranian!! I voted for Dianne Feinstein!!
+%
+I'm not available for comment..
+%
+I'm pretending I'm pulling in a TROUT! Am I doing it correctly??
+%
+I'm pretending that we're all watching PHIL SILVERS instead of RICARDO
+MONTALBAN!
+%
+I'm QUIETLY reading the latest issue of "BOWLING WORLD" while my wife
+and two children stand QUIETLY BY ...
+%
+I'm rated PG-34!!
+%
+I'm receiving a coded message from EUBIE BLAKE!!
+%
+I'm RELIGIOUS!! I love a man with a HAIRPIECE!! Equip me with
+MISSILES!!
+%
+I'm reporting for duty as a modern person. I want to do the Latin
+Hustle now!
+%
+I'm shaving!! I'M SHAVING!!
+%
+I'm sitting on my SPEED QUEEN ... To me, it's ENJOYABLE ... I'm WARM
+... I'm VIBRATORY ...
+%
+I'm thinking about DIGITAL READ-OUT systems and computer-generated
+IMAGE FORMATIONS ...
+%
+I'm totally DESPONDENT over the LIBYAN situation and the price of
+CHICKEN ...
+%
+I'm using my X-RAY VISION to obtain a rare glimpse of the INNER
+WORKINGS of this POTATO!!
+%
+I'm wearing PAMPERS!!
+%
+I'm wet! I'm wild!
+%
+I'm young ... I'm HEALTHY ... I can HIKE THRU CAPT GROGAN'S LUMBAR
+REGIONS!
+%
+I'm ZIPPY the PINHEAD and I'm totally committed to the festive mode.
+%
+I've got a COUSIN who works in the GARMENT DISTRICT ...
+%
+I've got an IDEA!! Why don't I STARE at you so HARD, you forget your
+SOCIAL SECURITY NUMBER!!
+%
+I've read SEVEN MILLION books!!
+%
+... ich bin in einem dusenjet ins jahr 53 vor chr ... ich lande im
+antiken Rom ... einige gladiatoren spielen scrabble ... ich rieche
+PIZZA ...
+%
+If a person is FAMOUS in this country, they have to go on the ROAD for
+MONTHS at a time and have their name misspelled on the SIDE of a
+GREYHOUND SCENICRUISER!!
+%
+If elected, Zippy pledges to each and every American a 55-year-old
+houseboy ...
+%
+If I am elected no one will ever have to do their laundry again!
+%
+If I am elected, the concrete barriers around the WHITE HOUSE will be
+replaced by tasteful foam replicas of ANN MARGARET!
+%
+If I felt any more SOPHISTICATED I would DIE of EMBARRASSMENT!
+%
+If I had a Q-TIP, I could prevent th' collapse of NEGOTIATIONS!!
+%
+... If I had heart failure right now, I couldn't be a more fortunate
+man!!
+%
+If I pull this SWITCH I'll be RITA HAYWORTH!! Or a SCIENTOLOGIST!
+%
+if it GLISTENS, gobble it!!
+%
+If our behavior is strict, we do not need fun!
+%
+If Robert Di Niro assassinates Walter Slezak, will Jodie Foster marry
+Bonzo??
+%
+In 1962, you could buy a pair of SHARKSKIN SLACKS, with a "Continental
+Belt," for $10.99!!
+%
+In Newark the laundromats are open 24 hours a day!
+%
+INSIDE, I have the same personality disorder as LUCY RICARDO!!
+%
+Inside, I'm already SOBBING!
+%
+Is a tattoo real, like a curb or a battleship? Or are we suffering in
+Safeway?
+%
+Is he the MAGIC INCA carrying a FROG on his shoulders?? Is the FROG
+his GUIDELIGHT?? It is curious that a DOG runs already on the
+ESCALATOR ...
+%
+Is it 1974? What's for SUPPER? Can I spend my COLLEGE FUND in one
+wild afternoon??
+%
+Is it clean in other dimensions?
+%
+Is it NOUVELLE CUISINE when 3 olives are struggling with a scallop in a
+plate of SAUCE MORNAY?
+%
+Is something VIOLENT going to happen to a GARBAGE CAN?
+%
+Is this an out-take from the "BRADY BUNCH"?
+%
+Is this going to involve RAW human ecstasy?
+%
+Is this TERMINAL fun?
+%
+Is this the line for the latest whimsical YUGOSLAVIAN drama which also
+makes you want to CRY and reconsider the VIETNAM WAR?
+%
+Isn't this my STOP?!
+%
+It don't mean a THING if you ain't got that SWING!!
+%
+It was a JOKE!! Get it?? I was receiving messages from DAVID
+LETTERMAN!! YOW!!
+%
+It's a lot of fun being alive ... I wonder if my bed is made?!?
+%
+It's NO USE ... I've gone to "CLUB MED"!!
+%
+It's OBVIOUS ... The FURS never reached ISTANBUL ... You were an EXTRA
+in the REMAKE of "TOPKAPI" ... Go home to your WIFE ... She's making
+FRENCH TOAST!
+%
+It's OKAY -- I'm an INTELLECTUAL, too.
+%
+It's the RINSE CYCLE!! They've ALL IGNORED the RINSE CYCLE!!
+%
+JAPAN is a WONDERFUL planet -- I wonder if we'll ever reach their level
+of COMPARATIVE SHOPPING ...
+%
+Jesuit priests are DATING CAREER DIPLOMATS!!
+%
+Jesus is my POSTMASTER GENERAL ...
+%
+Kids, don't gross me off ... "Adventures with MENTAL HYGIENE" can be
+carried too FAR!
+%
+Kids, the seven basic food groups are GUM, PUFF PASTRY, PIZZA,
+PESTICIDES, ANTIBIOTICS, NUTRA-SWEET and MILK DUDS!!
+%
+Laundry is the fifth dimension!! ... um ... um ... th' washing machine
+is a black hole and the pink socks are bus drivers who just fell in!!
+%
+LBJ, LBJ, how many JOKES did you tell today??!
+%
+Leona, I want to CONFESS things to you ... I want to WRAP you in a
+SCARLET ROBE trimmed with POLYVINYL CHLORIDE ... I want to EMPTY your
+ASHTRAYS ...
+%
+Let me do my TRIBUTE to FISHNET STOCKINGS ...
+%
+Let's all show human CONCERN for REVERAND MOON's legal difficulties!!
+%
+Let's send the Russians defective lifestyle accessories!
+%
+Life is a POPULARITY CONTEST! I'm REFRESHINGLY CANDID!!
+%
+Like I always say -- nothing can beat the BRATWURST here in DUSSELDORF!!
+%
+Loni Anderson's hair should be LEGALIZED!!
+%
+Look DEEP into the OPENINGS!! Do you see any ELVES or EDSELS ... or a
+HIGHBALL?? ...
+%
+Look into my eyes and try to forget that you have a Macy's charge
+card!
+%
+Look! A ladder! Maybe it leads to heaven, or a sandwich!
+%
+LOOK!! Sullen American teens wearing MADRAS shorts and "Flock of
+Seagulls" HAIRCUTS!
+%
+Make me look like LINDA RONSTADT again!!
+%
+Mary Tyler Moore's SEVENTH HUSBAND is wearing my DACRON TANK TOP in a
+cheap hotel in HONOLULU!
+%
+Maybe we could paint GOLDIE HAWN a rich PRUSSIAN BLUE --
+%
+MERYL STREEP is my obstetrician!
+%
+MMM-MM!! So THIS is BIO-NEBULATION!
+%
+Mmmmmm-MMMMMM!! A plate of STEAMING PIECES of a PIG mixed with the
+shreds of SEVERAL CHICKENS!! ... Oh BOY!! I'm about to swallow a
+TORN-OFF section of a COW'S LEFT LEG soaked in COTTONSEED OIL and
+SUGAR!! ... Let's see ... Next, I'll have the GROUND-UP flesh of CUTE,
+BABY LAMBS fried in the MELTED, FATTY TISSUES from a warm-blooded
+animal someone once PETTED!! ... YUM!! That was GOOD!! For DESSERT,
+I'll have a TOFU BURGER with BEAN SPROUTS on a stone-ground, WHOLE
+WHEAT BUN!!
+%
+Mr and Mrs PED, can I borrow 26.7% of the RAYON TEXTILE production of
+the INDONESIAN archipelago?
+%
+My Aunt MAUREEN was a military advisor to IKE & TINA TURNER!!
+%
+My BIOLOGICAL ALARM CLOCK just went off ... It has noiseless DOZE
+FUNCTION and full kitchen!!
+%
+My CODE of ETHICS is vacationing at famed SCHROON LAKE in upstate New
+York!!
+%
+My EARS are GONE!!
+%
+My face is new, my license is expired, and I'm under a doctor's
+care!!!!
+%
+My haircut is totally traditional!
+%
+MY income is ALL disposable!
+%
+My LESLIE GORE record is BROKEN ...
+%
+My life is a patio of fun!
+%
+My mind is a potato field ...
+%
+My mind is making ashtrays in Dayton ...
+%
+My nose feels like a bad Ronald Reagan movie ...
+%
+my NOSE is NUMB!
+%
+... My pants just went on a wild rampage through a Long Island Bowling
+Alley!!
+%
+My pants just went to high school in the Carlsbad Caverns!!!
+%
+My polyvinyl cowboy wallet was made in Hong Kong by Montgomery Clift!
+%
+My uncle Murray conquered Egypt in 53 B.C. And I can prove it too!!
+%
+My vaseline is RUNNING...
+%
+NANCY!! Why is everything RED?!
+%
+NATHAN ... your PARENTS were in a CARCRASH!! They're VOIDED -- They
+COLLAPSED They had no CHAINSAWS ... They had no MONEY MACHINES ... They
+did PILLS in SKIMPY GRASS SKIRTS ... Nathan, I EMULATED them ... but
+they were OFF-KEY ...
+%
+NEWARK has been REZONED!! DES MOINES has been REZONED!!
+%
+Nipples, dimples, knuckles, NICKLES, wrinkles, pimples!!
+%
+Not SENSUOUS ... only "FROLICSOME" ... and in need of DENTAL WORK ...
+in PAIN!!!
+%
+Now I am depressed ...
+%
+Now I think I just reached the state of HYPERTENSION that comes JUST
+BEFORE you see the TOTAL at the SAFEWAY CHECKOUT COUNTER!
+%
+Now I understand the meaning of "THE MOD SQUAD"!
+%
+Now I'm being INVOLUNTARILY shuffled closer to the CLAM DIP with the
+BROKEN PLASTIC FORKS in it!!
+%
+Now I'm concentrating on a specific tank battle toward the end of World
+War II!
+%
+Now I'm having INSIPID THOUGHTS about the beatiful, round wives of
+HOLLYWOOD MOVIE MOGULS encased in PLEXIGLASS CARS and being approached
+by SMALL BOYS selling FRUIT ...
+%
+Now KEN and BARBIE are PERMANENTLY ADDICTED to MIND-ALTERING DRUGS ...
+%
+Now my EMOTIONAL RESOURCES are heavily committed to 23% of the SMELTING
+and REFINING industry of the state of NEVADA!!
+%
+Now that I have my "APPLE", I comprehend COST ACCOUNTING!!
+%
+... Now, it's time to "HAVE A NAGEELA"!!
+%
+Now, let's SEND OUT for QUICHE!!
+%
+Of course, you UNDERSTAND about the PLAIDS in the SPIN CYCLE --
+%
+Oh my GOD -- the SUN just fell into YANKEE STADIUM!!
+%
+Oh, I get it!! "The BEACH goes on", huh, SONNY??
+%
+Okay ... I'm going home to write the "I HATE RUBIK's CUBE HANDBOOK FOR
+DEAD CAT LOVERS" ...
+%
+OKAY!! Turn on the sound ONLY for TRYNEL CARPETING, FULLY-EQUIPPED
+R.V.'S and FLOATATION SYSTEMS!!
+%
+OMNIVERSAL AWARENESS?? Oh, YEH!! First you need 4 GALLONS of JELL-O
+and a BIG WRENCH!! ... I think you drop th'WRENCH in the JELL-O as if
+it was a FLAVOR, or an INGREDIENT ... ... or ... I ... um ... WHERE'S
+the WASHING MACHINES?
+%
+On SECOND thought, maybe I'll heat up some BAKED BEANS and watch REGIS
+PHILBIN ... It's GREAT to be ALIVE!!
+%
+On the other hand, life can be an endless parade of TRANSSEXUAL
+QUILTING BEES aboard a cruise ship to DISNEYWORLD if only we let it!!
+%
+On the road, ZIPPY is a pinhead without a purpose, but never without a
+POINT.
+%
+Once upon a time, four AMPHIBIOUS HOG CALLERS attacked a family of
+DEFENSELESS, SENSITIVE COIN COLLECTORS and brought DOWN their PROPERTY
+VALUES!!
+%
+Once, there was NO fun ... This was before MENU planning, FASHION
+statements or NAUTILUS equipment ... Then, in 1985 ... FUN was
+completely encoded in this tiny MICROCHIP ... It contain 14,768 vaguely
+amusing SIT-COM pilots!! We had to wait FOUR BILLION years but we
+finally got JERRY LEWIS, MTV and a large selection of creme-filled
+snack cakes!
+%
+One FISHWICH coming up!!
+%
+ONE: I will donate my entire "BABY HUEY" comic book collection to
+ the downtown PLASMA CENTER ...
+TWO: I won't START a BAND called "KHADAFY & THE HIT SQUAD" ...
+THREE: I won't ever TUMBLE DRY my FOX TERRIER again!!
+%
+... or were you driving the PONTIAC that HONKED at me in MIAMI last
+Tuesday?
+%
+Our father who art in heaven ... I sincerely pray that SOMEBODY at this
+table will PAY for my SHREDDED WHAT and ENGLISH MUFFIN ... and also
+leave a GENEROUS TIP ....
+%
+over in west Philadelphia a puppy is vomiting ...
+%
+OVER the underpass! UNDER the overpass! Around the FUTURE and BEYOND
+REPAIR!!
+%
+PARDON me, am I speaking ENGLISH?
+%
+Pardon me, but do you know what it means to be TRULY ONE with your
+BOOTH!
+%
+PEGGY FLEMMING is stealing BASKET BALLS to feed the babies in VERMONT.
+%
+PIZZA!!
+%
+Place me on a BUFFER counter while you BELITTLE several BELLHOPS in the
+Trianon Room!! Let me one of your SUBSIDIARIES!
+%
+Please come home with me ... I have Tylenol!!
+%
+Psychoanalysis?? I thought this was a nude rap session!!!
+%
+PUNK ROCK!! DISCO DUCK!! BIRTH CONTROL!!
+%
+Quick, sing me the BUDAPEST NATIONAL ANTHEM!!
+%
+RELATIVES!!
+%
+Remember, in 2039, MOUSSE & PASTA will be available ONLY by
+prescription!!
+%
+RHAPSODY in Glue!
+%
+SANTA CLAUS comes down a FIRE ESCAPE wearing bright blue LEG WARMERS
+... He scrubs the POPE with a mild soap or detergent for 15 minutes,
+starring JANE FONDA!!
+%
+Send your questions to ``ASK ZIPPY'', Box 40474, San Francisco, CA
+94140, USA
+%
+SHHHH!! I hear SIX TATTOOED TRUCK-DRIVERS tossing ENGINE BLOCKS into
+empty OIL DRUMS ...
+%
+Should I do my BOBBIE VINTON medley?
+%
+Should I get locked in the PRINCICAL'S OFFICE today -- or have a
+VASECTOMY??
+%
+Should I start with the time I SWITCHED personalities with a BEATNIK
+hair stylist or my failure to refer five TEENAGERS to a good OCULIST?
+%
+Sign my PETITION.
+%
+So this is what it feels like to be potato salad
+%
+So, if we convert SUPPLY-SIDE SOYABEAN FUTURES into HIGH-YIELD T-BILL
+INDICATORS, the PRE-INFLATIONARY risks will DWINDLE to a rate of 2
+SHOPPING SPREES per EGGPLANT!!
+%
+someone in DAYTON, Ohio is selling USED CARPETS to a SERBO-CROATIAN
+%
+Sometime in 1993 NANCY SINATRA will lead a BLOODLESS COUP on GUAM!!
+%
+Somewhere in DOWNTOWN BURBANK a prostitute is OVERCOOKING a LAMB
+CHOP!!
+%
+Somewhere in suburban Honolulu, an unemployed bellhop is whipping up a
+batch of illegal psilocybin chop suey!!
+%
+Somewhere in Tenafly, New Jersey, a chiropractor is viewing "Leave it
+to Beaver"!
+%
+Spreading peanut butter reminds me of opera!! I wonder why?
+%
+TAILFINS!! ... click ...
+%
+ Talking Pinhead Blues:
+Oh, I LOST my ``HELLO KITTY'' DOLL and I get BAD reception on channel
+ TWENTY-SIX!!
+
+Th'HOSTESS FACTORY is closin' down and I just heard ZASU PITTS has been
+ DEAD for YEARS.. (sniff)
+
+My PLATFORM SHOE collection was CHEWED up by th' dog, ALEXANDER HAIG
+ won't let me take a SHOWER 'til Easter ... (snurf)
+
+So I went to the kitchen, but WALNUT PANELING whup me upside mah HAID!!
+ (on no, no, no.. Heh, heh)
+%
+TAPPING? You POLITICIANS! Don't you realize that the END of the "Wash
+Cycle" is a TREASURED MOMENT for most people?!
+%
+Tex SEX! The HOME of WHEELS! The dripping of COFFEE!! Take me to
+Minnesota but don't EMBARRASS me!!
+%
+Th' MIND is the Pizza Palace of th' SOUL
+%
+Thank god!! ... It's HENNY YOUNGMAN!!
+%
+The appreciation of the average visual graphisticator alone is worth
+the whole suaveness and decadence which abounds!!
+%
+The entire CHINESE WOMEN'S VOLLEYBALL TEAM all share ONE personality --
+and have since BIRTH!!
+%
+The fact that 47 PEOPLE are yelling and sweat is cascading down my
+SPINAL COLUMN is fairly enjoyable!!
+%
+The FALAFEL SANDWICH lands on my HEAD and I become a VEGETARIAN ...
+%
+... the HIGHWAY is made out of LIME JELLO and my HONDA is a barbequeued
+OYSTER! Yum!
+%
+The Korean War must have been fun.
+%
+... the MYSTERIANS are in here with my CORDUROY SOAP DISH!!
+%
+The Osmonds! You are all Osmonds!! Throwing up on a freeway at
+dawn!!!
+%
+The PILLSBURY DOUGHBOY is CRYING for an END to BURT REYNOLDS movies!!
+%
+The PINK SOCKS were ORIGINALLY from 1952!! But they went to MARS
+around 1953!!
+%
+The SAME WAVE keeps coming in and COLLAPSING like a rayon MUU-MUU ...
+%
+There's a little picture of ED MCMAHON doing BAD THINGS to JOAN RIVERS
+in a $200,000 MALIBU BEACH HOUSE!!
+%
+There's enough money here to buy 5000 cans of Noodle-Roni!
+%
+These PRESERVES should be FORCE-FED to PENTAGON OFFICIALS!!
+%
+They collapsed ... like nuns in the street ... they had no teen
+appeal!
+%
+This ASEXUAL PIG really BOILS my BLOOD ... He's so ... so ... URGENT!!
+%
+This is a NO-FRILLS flight -- hold th' CANADIAN BACON!!
+%
+This MUST be a good party -- My RIB CAGE is being painfully pressed up
+against someone's MARTINI!!
+%
+... this must be what it's like to be a COLLEGE GRADUATE!!
+%
+This PIZZA symbolizes my COMPLETE EMOTIONAL RECOVERY!!
+%
+This PORCUPINE knows his ZIPCODE ... And he has "VISA"!!
+%
+This TOPS OFF my partygoing experience! Someone I DON'T LIKE is
+talking to me about a HEART-WARMING European film ...
+%
+Those aren't WINOS -- that's my JUGGLER, my AERIALIST, my SWORD
+SWALLOWER, and my LATEX NOVELTY SUPPLIER!!
+%
+Thousands of days of civilians ... have produced a ... feeling for the
+aesthetic modules --
+%
+Today, THREE WINOS from DETROIT sold me a framed photo of TAB HUNTER
+before his MAKEOVER!
+%
+Toes, knees, NIPPLES. Toes, knees, nipples, KNUCKLES ...
+Nipples, dimples, knuckles, NICKLES, wrinkles, pimples!!
+%
+TONY RANDALL! Is YOUR life a PATIO of FUN??
+%
+Uh-oh -- WHY am I suddenly thinking of a VENERABLE religious leader
+frolicking on a FORT LAUDERDALE weekend?
+%
+Uh-oh!! I forgot to submit to COMPULSORY URINALYSIS!
+%
+UH-OH!! I put on "GREAT HEAD-ON TRAIN COLLISIONS of the 50's" by
+mistake!!!
+%
+UH-OH!! I think KEN is OVER-DUE on his R.V. PAYMENTS and HE'S having a
+NERVOUS BREAKDOWN too!! Ha ha.
+%
+Uh-oh!! I'm having TOO MUCH FUN!!
+%
+UH-OH!! We're out of AUTOMOBILE PARTS and RUBBER GOODS!
+%
+Used staples are good with SOY SAUCE!
+%
+VICARIOUSLY experience some reason to LIVE!!
+%
+Vote for ME -- I'm well-tapered, half-cocked, ill-conceived and
+TAX-DEFERRED!
+%
+Wait ... is this a FUN THING or the END of LIFE in Petticoat
+Junction??
+%
+Was my SOY LOAF left out in th'RAIN? It tastes REAL GOOD!!
+%
+We are now enjoying total mutual interaction in an imaginary hot
+tub ...
+%
+We have DIFFERENT amounts of HAIR --
+%
+We just joined the civil hair patrol!
+%
+We place two copies of PEOPLE magazine in a DARK, HUMID mobile home.
+45 minutes later CYNDI LAUPER emerges wearing a BIRD CAGE on her head!
+%
+Well, here I am in AMERICA.. I LIKE it. I HATE it. I LIKE it. I
+HATE it. I LIKE it. I HATE it. I LIKE it. I HATE it. I LIKE ...
+EMOTIONS are SWEEPING over me!!
+%
+Well, I'm a classic ANAL RETENTIVE!! And I'm looking for a way to
+VICARIOUSLY experience some reason to LIVE!!
+%
+Well, I'm INVISIBLE AGAIN ... I might as well pay a visit to the LADIES
+ROOM ...
+%
+Well, O.K. I'll compromise with my principles because of EXISTENTIAL
+DESPAIR!
+%
+Were these parsnips CORRECTLY MARINATED in TACO SAUCE?
+%
+What a COINCIDENCE! I'm an authorized "SNOOTS OF THE STARS" dealer!!
+%
+What GOOD is a CARDBOARD suitcase ANYWAY?
+%
+What I need is a MATURE RELATIONSHIP with a FLOPPY DISK ...
+%
+What I want to find out is -- do parrots know much about Astro-Turf?
+%
+What PROGRAM are they watching?
+%
+What UNIVERSE is this, please??
+%
+What's the MATTER Sid? ... Is your BEVERAGE unsatisfactory?
+%
+When I met th'POPE back in '58, I scrubbed him with a MILD SOAP or
+DETERGENT for 15 minutes. He seemed to enjoy it ...
+%
+When this load is DONE I think I'll wash it AGAIN ...
+%
+When you get your PH.D. will you get able to work at BURGER KING?
+%
+When you said "HEAVILY FORESTED" it reminded me of an overdue CLEANING
+BILL ... Don't you SEE? O'Grogan SWALLOWED a VALUABLE COIN COLLECTION
+and HAD to murder the ONLY MAN who KNEW!!
+%
+Where do your SOCKS go when you lose them in th' WASHER?
+%
+Where does it go when you flush?
+%
+Where's SANDY DUNCAN?
+%
+Where's th' DAFFY DUCK EXHIBIT??
+%
+Where's the Coke machine? Tell me a joke!!
+%
+While my BRAINPAN is being refused service in BURGER KING, Jesuit
+priests are DATING CAREER DIPLOMATS!!
+%
+While you're chewing, think of STEVEN SPIELBERG'S bank account ... his
+will have the same effect as two "STARCH BLOCKERS"!
+%
+WHO sees a BEACH BUNNY sobbing on a SHAG RUG?!
+%
+WHOA!! Ken and Barbie are having TOO MUCH FUN!! It must be the
+NEGATIVE IONS!!
+%
+Why are these athletic shoe salesmen following me??
+%
+Why don't you ever enter and CONTESTS, Marvin?? Don't you know your
+own ZIPCODE?
+%
+Why is everything made of Lycra Spandex?
+%
+Why is it that when you DIE, you can't take your HOME ENTERTAINMENT
+CENTER with you??
+%
+Will it improve my CASH FLOW?
+%
+Will the third world war keep "Bosom Buddies" off the air?
+%
+Will this never-ending series of PLEASURABLE EVENTS never cease?
+%
+With YOU, I can be MYSELF ... We don't NEED Dan Rather ...
+%
+World War III? No thanks!
+%
+World War Three can be averted by adherence to a strictly enforced
+dress code!
+%
+Wow! Look!! A stray meatball!! Let's interview it!
+%
+Xerox your lunch and file it under "sex offenders"!
+%
+Yes, but will I see the EASTER BUNNY in skintight leather at an IRON
+MAIDEN concert?
+%
+You can't hurt me!! I have an ASSUMABLE MORTGAGE!!
+%
+You mean now I can SHOOT YOU in the back and further BLUR th'
+distinction between FANTASY and REALITY?
+%
+You mean you don't want to watch WRESTLING from ATLANTA?
+%
+YOU PICKED KARL MALDEN'S NOSE!!
+%
+You should all JUMP UP AND DOWN for TWO HOURS while I decide on a NEW
+CAREER!!
+%
+You were s'posed to laugh!
+%
+YOU!! Give me the CUTEST, PINKEST, most charming little VICTORIAN
+DOLLHOUSE you can find!! An make it SNAPPY!!
+%
+Your CHEEKS sit like twin NECTARINES above a MOUTH that knows no BOUNDS --
+%
+Youth of today! Join me in a mass rally for traditional mental
+attitudes!
+%
+Yow!
+%
+Yow! Am I having fun yet?
+%
+Yow! Am I in Milwaukee?
+%
+Yow! And then we could sit on the hoods of cars at stop lights!
+%
+Yow! Are we laid back yet?
+%
+Yow! Are we wet yet?
+%
+Yow! Are you the self-frying president?
+%
+Yow! Did something bad happen or am I in a drive-in movie??
+%
+Yow! I just went below the poverty line!
+%
+Yow! I threw up on my window!
+%
+Yow! I want my nose in lights!
+%
+Yow! I want to mail a bronzed artichoke to Nicaragua!
+%
+Yow! I'm having a quadrophonic sensation of two winos alone in a steel
+mill!
+%
+Yow! I'm imagining a surfer van filled with soy sauce!
+%
+Yow! Is my fallout shelter termite proof?
+%
+Yow! Is this sexual intercourse yet?? Is it, huh, is it??
+%
+Yow! It's a hole all the way to downtown Burbank!
+%
+Yow! It's some people inside the wall! This is better than mopping!
+%
+Yow! Maybe I should have asked for my Neutron Bomb in PAISLEY --
+%
+Yow! Now I get to think about all the BAD THINGS I did to a BOWLING
+BALL when I was in JUNIOR HIGH SCHOOL!
+%
+Yow! Now we can become alcoholics!
+%
+Yow! Those people look exactly like Donnie and Marie Osmond!!
+%
+Yow! We're going to a new disco!
+%
+YOW!! Everybody out of the GENETIC POOL!
+%
+YOW!! I'm in a very clever and adorable INSANE ASYLUM!!
+%
+YOW!! Now I understand advanced MICROBIOLOGY and th' new TAX REFORM
+laws!!
+%
+YOW!! The land of the rising SONY!!
+%
+YOW!! Up ahead! It's a DONUT HUT!!
+%
+YOW!! What should the entire human race DO?? Consume a fifth of
+CHIVAS REGAL, ski NUDE down MT. EVEREST, and have a wild SEX WEEKEND!
+%
+YOW!!! I am having fun!!!
+%
+Zippy's brain cells are straining to bridge synapses ...
diff --git a/fortune/datfiles/zippy.sp.ok b/fortune/datfiles/zippy.sp.ok
new file mode 100644
index 00000000..67c616bc
--- /dev/null
+++ b/fortune/datfiles/zippy.sp.ok
@@ -0,0 +1,210 @@
+ANAL
+ASEXUAL
+Astro
+B.C
+BANKHEAD
+BI
+BIO
+BORSCHT
+BRAINPAN
+BURRITO
+BURRITOS
+Barbie
+Bo
+Bonzo
+CARCRASH
+CASIO
+CHAINSAWS
+CHIVAS
+COM
+CORDOVANS
+COSELL
+CROATIAN
+Carlsbad
+Clift
+Cosell
+Cupcake
+DAQUIRI
+DELI
+DIDI
+DISCO
+DISNEYWORLD
+DONUT
+DOUGHBOY
+Darvon
+Di
+Disco
+Donnie
+EDSELS
+EMOTE
+EUBIE
+Enema
+FALAFEL
+FISHNET
+FISHWICH
+FLEMMING
+FLOATATION
+FROLICSOME
+Feinstein
+GOLDIE
+GORRY
+GUCCIONE
+GUIDELIGHT
+Gibble
+Ginzberg
+HAIRPIECE
+HAWN
+HAYWORTH
+HITCHHIKING
+HOAX
+HOUSECAT
+Hmmm
+I.Q
+INTESTINAL
+Iranian
+JELL
+JELLO
+JILLIAN'S
+JULIENNED
+Jodie
+KATRINKA
+KNOCKWURST
+LBJ
+LING
+LONI
+LUGOSI
+Loni
+Lycra
+MALIBU
+MCMAHON
+MELBA
+MERYL
+MMM
+MOGULS
+MONTALBAN'S
+MOUSSE
+MSG
+MT
+MTV
+MYSTERIANS
+Macy's
+Meese
+Monkees
+NABOBS
+NAGEELA
+NEBULATION
+NICKLES
+NUTRA
+Niro
+OLFACTORY
+OMNIVERSAL
+OVULAR
+Osmond
+Osmonds
+PAISLEY
+PASTA
+PG
+Pharoahs
+Provolone
+R.V.'S
+RAPHAELITE
+RICARDO
+RITA
+Rom
+Roni
+SAGAN
+SANFORIZE
+SCHROON
+SCIENTOLOGIST
+SERBO
+SHOPLIFT
+SINATRA
+SKEE
+SODOMIZE
+SONTAG
+STREEP
+Safeway
+Slezak
+Spandex
+T.V
+TACO
+TAILFINS
+TALLULAH
+TINA
+TRANSSEXUAL
+TRYNEL
+Tenafly
+Tex
+Th
+Tylenol
+Uh
+VASELINE
+VELVEETA
+WESSON
+YEH
+YUBBA
+Yum
+ZIPPY
+Zippy
+Zippy's
+barbequeued
+chr
+co
+cranial
+creme
+devalue
+disco
+donut
+donuts
+dusenjet
+einem
+einige
+frolicking
+fuschia
+gladiatoren
+gothic
+graphisticator
+hors
+houseboy
+ich
+im
+jahr
+kidnapped
+lande
+laundromat
+laundromats
+lesbian
+li'l
+manicurist
+matic
+meatball
+meltdown
+naugahide
+obstetrician
+poindexter
+pre
+psilocybin
+quaaludes
+quadrophonic
+rieche
+s'posed
+scientology
+skintight
+skydiving
+solarium
+spielen
+telex
+th
+th'HOLIDAY
+th'MAMBO
+th'RAIN
+th'WRENCH
+th'cute
+thru
+thumbtack
+uh
+um
+urinate
+vaseline
+vor
+zzzzzzzzz
diff --git a/fortune/fortune/Makefile b/fortune/fortune/Makefile
new file mode 100644
index 00000000..f800abb6
--- /dev/null
+++ b/fortune/fortune/Makefile
@@ -0,0 +1,10 @@
+# %W% (Berkeley) %G%
+
+PROG= fortune
+MAN6= fortune.0
+CFLAGS+=-I${.CURDIR}/../strfile
+DPADD= ${COMPAT}
+LDADD= -lcompat
+
+.include "${.CURDIR}/../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/fortune/fortune/fortune.6 b/fortune/fortune/fortune.6
new file mode 100644
index 00000000..c2469bc1
--- /dev/null
+++ b/fortune/fortune/fortune.6
@@ -0,0 +1,173 @@
+.\" Copyright (c) 1985 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Ken Arnold.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fortune.6 6.8 (Berkeley) 6/23/90
+.\"
+.TH FORTUNE 6 "June 23, 1990"
+.UC 4
+.SH NAME
+fortune \- print a random, hopefully interesting, adage
+.SH SYNOPSIS
+.B fortune
+[
+.B \-aefilosw
+]
+[
+.B \-m
+.I pattern
+]
+[ [
+.IR N%
+]
+.I file/dir/all
+]
+.SH DESCRIPTION
+When
+.I fortune
+is run with no arguments it prints out a random epigram.
+Epigrams are divided into several categories, where each category
+is subdivided into those which are potentially offensive and those
+which are not.
+The options are as follows:
+.TP
+.B \-a
+Choose from all lists of maxims, both offensive and not.
+.TP
+.B \-e
+Consider all fortune files to be of equal size (see discussion below
+on multiple files).
+.TP
+.B \-f
+Print out the list of files which would be searched, but don't
+print a fortune.
+.TP
+.B \-l
+Long dictums only.
+.TP
+.B \-m
+Print out all fortunes which match the regular expression
+.IR pattern .
+See
+.BR regex (3)
+for a description of patterns.
+.TP
+.B \-o
+Choose only from potentially offensive aphorisms.
+.ft B
+Please, please, please request a potentially offensive fortune if and
+only if you believe, deep down in your heart, that you are willing
+to be offended.
+(And that if you are, you'll just quit using -o rather than give us
+grief about it, okay?)
+.ft R
+.PP
+.in +5
+\&... let us keep in mind the basic governing philosophy
+of The Brotherhood, as handsomely summarized in these words:
+we believe in healthy, hearty laughter -- at the expense of
+the whole human race, if needs be.
+Needs be.
+.br
+.in +10
+-- H. Allen Smith, "Rude Jokes"
+.TP
+.B \-s
+Short apothegms only.
+.TP
+.B \-i
+Ignore case for
+.B \-m
+patterns.
+.TP
+.B \-w
+Wait before termination for an amount of time calculated from the
+number of characters in the message.
+This is useful if it is executed as part of the logout procedure
+to guarantee that the message can be read before the screen is cleared.
+.PP
+The user may specify alternate sayings.
+You can specify a specific file, a directory which contains one or
+more files, or the special word
+.B all
+which says to use all the standard databases.
+Any of these may be preceded by a percentage, which is a number
+.I N
+between 0 and 100 inclusive, followed by a
+.B % .
+If it is, there will be a
+.I N
+percent probability that an adage will be picked from that file
+or directory.
+If the percentages do not sum to 100, and there are specifications
+without percentages, the remaining percent will apply to those files
+and/or directories, in which case the probability of selecting from
+one of them will be based on their relative sizes.
+.PP
+As an example, given two databases
+.B funny
+and
+.B not-funny ,
+with
+.B funny
+twice as big, saying
+.RS
+fortune funny not-funny
+.RE
+will get you fortunes out of
+.B funny
+two-thirds of the time.
+The command
+.RS
+fortune 90% funny 10% not-funny
+.RE
+will pick out 90% of its fortunes from
+.B funny
+(the ``10% not-funny'' is unnecessary, since 10% is all that's left).
+The
+.B \-e
+option says to consider all files equal;
+thus
+.RS
+fortune \-e
+.RE
+is equivalent to
+.RS
+fortune 50% funny 50% not-funny
+.RE
+.SH FILES
+/usr/share/games/fortune
+.SH AUTHOR
+Ken Arnold
+.SH "SEE ALSO"
+regex(3), regcmp(3), strfile(8)
diff --git a/fortune/fortune/fortune.c b/fortune/fortune/fortune.c
new file mode 100644
index 00000000..c044139d
--- /dev/null
+++ b/fortune/fortune/fortune.c
@@ -0,0 +1,1340 @@
+/*-
+ * Copyright (c) 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ken Arnold.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1986 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)fortune.c 5.13 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+# include <machine/endian.h>
+# include <sys/param.h>
+# include <sys/stat.h>
+# include <sys/dir.h>
+# include <stdio.h>
+# include <assert.h>
+# include "strfile.h"
+# include "pathnames.h"
+
+#ifdef SYSV
+# include <dirent.h>
+
+# define NO_LOCK
+# define REGCMP
+# ifdef NO_REGEX
+# undef NO_REGEX
+# endif /* NO_REGEX */
+# define index strchr
+# define rindex strrchr
+#endif /* SYSV */
+
+#ifndef NO_REGEX
+# include <ctype.h>
+#endif /* NO_REGEX */
+
+# ifndef NO_LOCK
+# include <sys/file.h>
+# endif /* NO_LOCK */
+
+# ifndef F_OK
+/* codes for access() */
+# define F_OK 0 /* does file exist */
+# define X_OK 1 /* is it executable by caller */
+# define W_OK 2 /* writable by caller */
+# define R_OK 4 /* readable by caller */
+# endif /* F_OK */
+
+# define TRUE 1
+# define FALSE 0
+# define bool short
+
+# define MINW 6 /* minimum wait if desired */
+# define CPERS 20 /* # of chars for each sec */
+# define SLEN 160 /* # of chars in short fortune */
+
+# define POS_UNKNOWN ((unsigned long) -1) /* pos for file unknown */
+# define NO_PROB (-1) /* no prob specified for file */
+
+# ifdef DEBUG
+# define DPRINTF(l,x) if (Debug >= l) fprintf x; else
+# undef NDEBUG
+# else /* DEBUG */
+# define DPRINTF(l,x)
+# define NDEBUG 1
+# endif /* DEBUG */
+
+typedef struct fd {
+ int percent;
+ int fd, datfd;
+ unsigned long pos;
+ FILE *inf;
+ char *name;
+ char *path;
+ char *datfile, *posfile;
+ bool read_tbl;
+ bool was_pos_file;
+ STRFILE tbl;
+ int num_children;
+ struct fd *child, *parent;
+ struct fd *next, *prev;
+} FILEDESC;
+
+bool Found_one; /* did we find a match? */
+bool Find_files = FALSE; /* just find a list of proper fortune files */
+bool Wait = FALSE; /* wait desired after fortune */
+bool Short_only = FALSE; /* short fortune desired */
+bool Long_only = FALSE; /* long fortune desired */
+bool Offend = FALSE; /* offensive fortunes only */
+bool All_forts = FALSE; /* any fortune allowed */
+bool Equal_probs = FALSE; /* scatter un-allocted prob equally */
+#ifndef NO_REGEX
+bool Match = FALSE; /* dump fortunes matching a pattern */
+#endif
+#ifdef DEBUG
+bool Debug = FALSE; /* print debug messages */
+#endif
+
+char *Fortbuf = NULL; /* fortune buffer for -m */
+
+int Fort_len = 0;
+
+off_t Seekpts[2]; /* seek pointers to fortunes */
+
+FILEDESC *File_list = NULL, /* Head of file list */
+ *File_tail = NULL; /* Tail of file list */
+FILEDESC *Fortfile; /* Fortune file to use */
+
+STRFILE Noprob_tbl; /* sum of data for all no prob files */
+
+char *do_malloc(), *copy(), *off_name();
+
+FILEDESC *pick_child(), *new_fp();
+
+extern char *malloc(), *index(), *rindex(), *strcpy(), *strcat();
+
+extern time_t time();
+
+#ifndef NO_REGEX
+char *conv_pat();
+#endif
+
+#ifndef NO_REGEX
+#ifdef REGCMP
+# define RE_COMP(p) (Re_pat = regcmp(p, NULL))
+# define BAD_COMP(f) ((f) == NULL)
+# define RE_EXEC(p) regex(Re_pat, (p))
+
+char *Re_pat;
+
+char *regcmp(), *regex();
+#else
+# define RE_COMP(p) (p = re_comp(p))
+# define BAD_COMP(f) ((f) != NULL)
+# define RE_EXEC(p) re_exec(p)
+
+char *re_comp();
+#ifdef SYSV
+char *re_exec();
+#else
+int re_exec();
+#endif
+#endif
+#endif
+
+main(ac, av)
+int ac;
+char *av[];
+{
+#ifdef OK_TO_WRITE_DISK
+ int fd;
+#endif /* OK_TO_WRITE_DISK */
+
+ getargs(ac, av);
+
+#ifndef NO_REGEX
+ if (Match)
+ exit(find_matches() != 0);
+#endif
+
+ init_prob();
+ srandom((int)(time((time_t *) NULL) + getpid()));
+ do {
+ get_fort();
+ } while ((Short_only && fortlen() > SLEN) ||
+ (Long_only && fortlen() <= SLEN));
+
+ display(Fortfile);
+
+#ifdef OK_TO_WRITE_DISK
+ if ((fd = creat(Fortfile->posfile, 0666)) < 0) {
+ perror(Fortfile->posfile);
+ exit(1);
+ }
+#ifdef LOCK_EX
+ /*
+ * if we can, we exclusive lock, but since it isn't very
+ * important, we just punt if we don't have easy locking
+ * available.
+ */
+ (void) flock(fd, LOCK_EX);
+#endif /* LOCK_EX */
+ write(fd, (char *) &Fortfile->pos, sizeof Fortfile->pos);
+ if (!Fortfile->was_pos_file)
+ (void) chmod(Fortfile->path, 0666);
+#ifdef LOCK_EX
+ (void) flock(fd, LOCK_UN);
+#endif /* LOCK_EX */
+#endif /* OK_TO_WRITE_DISK */
+ if (Wait) {
+ if (Fort_len == 0)
+ (void) fortlen();
+ sleep((unsigned int) max(Fort_len / CPERS, MINW));
+ }
+ exit(0);
+ /* NOTREACHED */
+}
+
+display(fp)
+FILEDESC *fp;
+{
+ register char *p, ch;
+ char line[BUFSIZ];
+
+ open_fp(fp);
+ (void) fseek(fp->inf, Seekpts[0], 0);
+ for (Fort_len = 0; fgets(line, sizeof line, fp->inf) != NULL &&
+ !STR_ENDSTRING(line, fp->tbl); Fort_len++) {
+ if (fp->tbl.str_flags & STR_ROTATED)
+ for (p = line; ch = *p; ++p)
+ if (isupper(ch))
+ *p = 'A' + (ch - 'A' + 13) % 26;
+ else if (islower(ch))
+ *p = 'a' + (ch - 'a' + 13) % 26;
+ fputs(line, stdout);
+ }
+ (void) fflush(stdout);
+}
+
+/*
+ * fortlen:
+ * Return the length of the fortune.
+ */
+fortlen()
+{
+ register int nchar;
+ char line[BUFSIZ];
+
+ if (!(Fortfile->tbl.str_flags & (STR_RANDOM | STR_ORDERED)))
+ nchar = (Seekpts[1] - Seekpts[0] <= SLEN);
+ else {
+ open_fp(Fortfile);
+ (void) fseek(Fortfile->inf, Seekpts[0], 0);
+ nchar = 0;
+ while (fgets(line, sizeof line, Fortfile->inf) != NULL &&
+ !STR_ENDSTRING(line, Fortfile->tbl))
+ nchar += strlen(line);
+ }
+ Fort_len = nchar;
+ return nchar;
+}
+
+/*
+ * This routine evaluates the arguments on the command line
+ */
+getargs(argc, argv)
+register int argc;
+register char **argv;
+{
+ register int ignore_case;
+# ifndef NO_REGEX
+ register char *pat;
+# endif /* NO_REGEX */
+ extern char *optarg;
+ extern int optind;
+ int ch;
+
+ ignore_case = FALSE;
+ pat = NULL;
+
+# ifdef DEBUG
+ while ((ch = getopt(argc, argv, "aDefilm:osw")) != EOF)
+#else
+ while ((ch = getopt(argc, argv, "aefilm:osw")) != EOF)
+#endif /* DEBUG */
+ switch(ch) {
+ case 'a': /* any fortune */
+ All_forts++;
+ break;
+# ifdef DEBUG
+ case 'D':
+ Debug++;
+ break;
+# endif /* DEBUG */
+ case 'e':
+ Equal_probs++; /* scatter un-allocted prob equally */
+ break;
+ case 'f': /* find fortune files */
+ Find_files++;
+ break;
+ case 'l': /* long ones only */
+ Long_only++;
+ Short_only = FALSE;
+ break;
+ case 'o': /* offensive ones only */
+ Offend++;
+ break;
+ case 's': /* short ones only */
+ Short_only++;
+ Long_only = FALSE;
+ break;
+ case 'w': /* give time to read */
+ Wait++;
+ break;
+# ifdef NO_REGEX
+ case 'i': /* case-insensitive match */
+ case 'm': /* dump out the fortunes */
+ (void) fprintf(stderr,
+ "fortune: can't match fortunes on this system (Sorry)\n");
+ exit(0);
+# else /* NO_REGEX */
+ case 'm': /* dump out the fortunes */
+ Match++;
+ pat = optarg;
+ break;
+ case 'i': /* case-insensitive match */
+ ignore_case++;
+ break;
+# endif /* NO_REGEX */
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (!form_file_list(argv, argc))
+ exit(1); /* errors printed through form_file_list() */
+#ifdef DEBUG
+ if (Debug >= 1)
+ print_file_list();
+#endif /* DEBUG */
+ if (Find_files) {
+ print_file_list();
+ exit(0);
+ }
+
+# ifndef NO_REGEX
+ if (pat != NULL) {
+ if (ignore_case)
+ pat = conv_pat(pat);
+ if (BAD_COMP(RE_COMP(pat))) {
+#ifndef REGCMP
+ fprintf(stderr, "%s\n", pat);
+#else /* REGCMP */
+ fprintf(stderr, "bad pattern: %s\n", pat);
+#endif /* REGCMP */
+ }
+ }
+# endif /* NO_REGEX */
+}
+
+/*
+ * form_file_list:
+ * Form the file list from the file specifications.
+ */
+form_file_list(files, file_cnt)
+register char **files;
+register int file_cnt;
+{
+ register int i, percent;
+ register char *sp;
+
+ if (file_cnt == 0)
+ if (Find_files)
+ return add_file(NO_PROB, FORTDIR, NULL, &File_list,
+ &File_tail, NULL);
+ else
+ return add_file(NO_PROB, "fortunes", FORTDIR,
+ &File_list, &File_tail, NULL);
+ for (i = 0; i < file_cnt; i++) {
+ percent = NO_PROB;
+ if (!isdigit(files[i][0]))
+ sp = files[i];
+ else {
+ percent = 0;
+ for (sp = files[i]; isdigit(*sp); sp++)
+ percent = percent * 10 + *sp - '0';
+ if (percent > 100) {
+ fprintf(stderr, "percentages must be <= 100\n");
+ return FALSE;
+ }
+ if (*sp == '.') {
+ fprintf(stderr, "percentages must be integers\n");
+ return FALSE;
+ }
+ /*
+ * If the number isn't followed by a '%', then
+ * it was not a percentage, just the first part
+ * of a file name which starts with digits.
+ */
+ if (*sp != '%') {
+ percent = NO_PROB;
+ sp = files[i];
+ }
+ else if (*++sp == '\0') {
+ if (++i >= file_cnt) {
+ fprintf(stderr, "percentages must precede files\n");
+ return FALSE;
+ }
+ sp = files[i];
+ }
+ }
+ if (strcmp(sp, "all") == 0)
+ sp = FORTDIR;
+ if (!add_file(percent, sp, NULL, &File_list, &File_tail, NULL))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * add_file:
+ * Add a file to the file list.
+ */
+add_file(percent, file, dir, head, tail, parent)
+int percent;
+register char *file;
+char *dir;
+FILEDESC **head, **tail;
+FILEDESC *parent;
+{
+ register FILEDESC *fp;
+ register int fd;
+ register char *path, *offensive;
+ register bool was_malloc;
+ register bool isdir;
+
+ if (dir == NULL) {
+ path = file;
+ was_malloc = FALSE;
+ }
+ else {
+ path = do_malloc((unsigned int) (strlen(dir) + strlen(file) + 2));
+ (void) strcat(strcat(strcpy(path, dir), "/"), file);
+ was_malloc = TRUE;
+ }
+ if ((isdir = is_dir(path)) && parent != NULL) {
+ if (was_malloc)
+ free(path);
+ return FALSE; /* don't recurse */
+ }
+ offensive = NULL;
+ if (!isdir && parent == NULL && (All_forts || Offend) &&
+ !is_off_name(path)) {
+ offensive = off_name(path);
+ was_malloc = TRUE;
+ if (Offend) {
+ if (was_malloc)
+ free(path);
+ path = offensive;
+ file = off_name(file);
+ }
+ }
+
+ DPRINTF(1, (stderr, "adding file \"%s\"\n", path));
+over:
+ if ((fd = open(path, 0)) < 0) {
+ /*
+ * This is a sneak. If the user said -a, and if the
+ * file we're given isn't a file, we check to see if
+ * there is a -o version. If there is, we treat it as
+ * if *that* were the file given. We only do this for
+ * individual files -- if we're scanning a directory,
+ * we'll pick up the -o file anyway.
+ */
+ if (All_forts && offensive != NULL) {
+ path = offensive;
+ if (was_malloc)
+ free(path);
+ offensive = NULL;
+ was_malloc = TRUE;
+ DPRINTF(1, (stderr, "\ttrying \"%s\"\n", path));
+ file = off_name(file);
+ goto over;
+ }
+ if (dir == NULL && file[0] != '/')
+ return add_file(percent, file, FORTDIR, head, tail,
+ parent);
+ if (parent == NULL)
+ perror(path);
+ if (was_malloc)
+ free(path);
+ return FALSE;
+ }
+
+ DPRINTF(2, (stderr, "path = \"%s\"\n", path));
+
+ fp = new_fp();
+ fp->fd = fd;
+ fp->percent = percent;
+ fp->name = file;
+ fp->path = path;
+ fp->parent = parent;
+
+ if ((isdir && !add_dir(fp)) ||
+ (!isdir &&
+ !is_fortfile(path, &fp->datfile, &fp->posfile, (parent != NULL))))
+ {
+ if (parent == NULL)
+ fprintf(stderr,
+ "fortune:%s not a fortune file or directory\n",
+ path);
+ free((char *) fp);
+ if (was_malloc)
+ free(path);
+ do_free(fp->datfile);
+ do_free(fp->posfile);
+ do_free(offensive);
+ return FALSE;
+ }
+ /*
+ * If the user said -a, we need to make this node a pointer to
+ * both files, if there are two. We don't need to do this if
+ * we are scanning a directory, since the scan will pick up the
+ * -o file anyway.
+ */
+ if (All_forts && parent == NULL && !is_off_name(path))
+ all_forts(fp, offensive);
+ if (*head == NULL)
+ *head = *tail = fp;
+ else if (fp->percent == NO_PROB) {
+ (*tail)->next = fp;
+ fp->prev = *tail;
+ *tail = fp;
+ }
+ else {
+ (*head)->prev = fp;
+ fp->next = *head;
+ *head = fp;
+ }
+#ifdef OK_TO_WRITE_DISK
+ fp->was_pos_file = (access(fp->posfile, W_OK) >= 0);
+#endif /* OK_TO_WRITE_DISK */
+
+ return TRUE;
+}
+
+/*
+ * new_fp:
+ * Return a pointer to an initialized new FILEDESC.
+ */
+FILEDESC *
+new_fp()
+{
+ register FILEDESC *fp;
+
+ fp = (FILEDESC *) do_malloc(sizeof *fp);
+ fp->datfd = -1;
+ fp->pos = POS_UNKNOWN;
+ fp->inf = NULL;
+ fp->fd = -1;
+ fp->percent = NO_PROB;
+ fp->read_tbl = FALSE;
+ fp->next = NULL;
+ fp->prev = NULL;
+ fp->child = NULL;
+ fp->parent = NULL;
+ fp->datfile = NULL;
+ fp->posfile = NULL;
+ return fp;
+}
+
+/*
+ * off_name:
+ * Return a pointer to the offensive version of a file of this name.
+ */
+char *
+off_name(file)
+char *file;
+{
+ char *new;
+
+ new = copy(file, (unsigned int) (strlen(file) + 2));
+ return strcat(new, "-o");
+}
+
+/*
+ * is_off_name:
+ * Is the file an offensive-style name?
+ */
+is_off_name(file)
+char *file;
+{
+ int len;
+
+ len = strlen(file);
+ return (len >= 3 && file[len - 2] == '-' && file[len - 1] == 'o');
+}
+
+/*
+ * all_forts:
+ * Modify a FILEDESC element to be the parent of two children if
+ * there are two children to be a parent of.
+ */
+all_forts(fp, offensive)
+register FILEDESC *fp;
+char *offensive;
+{
+ register char *sp;
+ register FILEDESC *scene, *obscene;
+ register int fd;
+ auto char *datfile, *posfile;
+
+ if (fp->child != NULL) /* this is a directory, not a file */
+ return;
+ if (!is_fortfile(offensive, &datfile, &posfile, FALSE))
+ return;
+ if ((fd = open(offensive, 0)) < 0)
+ return;
+ DPRINTF(1, (stderr, "adding \"%s\" because of -a\n", offensive));
+ scene = new_fp();
+ obscene = new_fp();
+ *scene = *fp;
+
+ fp->num_children = 2;
+ fp->child = scene;
+ scene->next = obscene;
+ obscene->next = NULL;
+ scene->child = obscene->child = NULL;
+ scene->parent = obscene->parent = fp;
+
+ fp->fd = -1;
+ scene->percent = obscene->percent = NO_PROB;
+
+ obscene->fd = fd;
+ obscene->inf = NULL;
+ obscene->path = offensive;
+ if ((sp = rindex(offensive, '/')) == NULL)
+ obscene->name = offensive;
+ else
+ obscene->name = ++sp;
+ obscene->datfile = datfile;
+ obscene->posfile = posfile;
+ obscene->read_tbl = FALSE;
+#ifdef OK_TO_WRITE_DISK
+ obscene->was_pos_file = (access(obscene->posfile, W_OK) >= 0);
+#endif /* OK_TO_WRITE_DISK */
+}
+
+/*
+ * add_dir:
+ * Add the contents of an entire directory.
+ */
+add_dir(fp)
+register FILEDESC *fp;
+{
+ register DIR *dir;
+#ifdef SYSV
+ register struct dirent *dirent; /* NIH, of course! */
+#else
+ register struct direct *dirent;
+#endif
+ auto FILEDESC *tailp;
+ auto char *name;
+
+ (void) close(fp->fd);
+ fp->fd = -1;
+ if ((dir = opendir(fp->path)) == NULL) {
+ perror(fp->path);
+ return FALSE;
+ }
+ tailp = NULL;
+ DPRINTF(1, (stderr, "adding dir \"%s\"\n", fp->path));
+ fp->num_children = 0;
+ while ((dirent = readdir(dir)) != NULL) {
+ if (dirent->d_namlen == 0)
+ continue;
+ name = copy(dirent->d_name, dirent->d_namlen);
+ if (add_file(NO_PROB, name, fp->path, &fp->child, &tailp, fp))
+ fp->num_children++;
+ else
+ free(name);
+ }
+ if (fp->num_children == 0) {
+ (void) fprintf(stderr,
+ "fortune: %s: No fortune files in directory.\n", fp->path);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * is_dir:
+ * Return TRUE if the file is a directory, FALSE otherwise.
+ */
+is_dir(file)
+char *file;
+{
+ auto struct stat sbuf;
+
+ if (stat(file, &sbuf) < 0)
+ return FALSE;
+ return (sbuf.st_mode & S_IFDIR);
+}
+
+/*
+ * is_fortfile:
+ * Return TRUE if the file is a fortune database file. We try and
+ * exclude files without reading them if possible to avoid
+ * overhead. Files which start with ".", or which have "illegal"
+ * suffixes, as contained in suflist[], are ruled out.
+ */
+/* ARGSUSED */
+is_fortfile(file, datp, posp, check_for_offend)
+char *file;
+char **datp, **posp;
+int check_for_offend;
+{
+ register int i;
+ register char *sp;
+ register char *datfile;
+ static char *suflist[] = { /* list of "illegal" suffixes" */
+ "dat", "pos", "c", "h", "p", "i", "f",
+ "pas", "ftn", "ins.c", "ins,pas",
+ "ins.ftn", "sml",
+ NULL
+ };
+
+ DPRINTF(2, (stderr, "is_fortfile(%s) returns ", file));
+
+ /*
+ * Preclude any -o files for offendable people, and any non -o
+ * files for completely offensive people.
+ */
+ if (check_for_offend && !All_forts) {
+ i = strlen(file);
+ if (Offend ^ (file[i - 2] == '-' && file[i - 1] == 'o'))
+ return FALSE;
+ }
+
+ if ((sp = rindex(file, '/')) == NULL)
+ sp = file;
+ else
+ sp++;
+ if (*sp == '.') {
+ DPRINTF(2, (stderr, "FALSE (file starts with '.')\n"));
+ return FALSE;
+ }
+ if ((sp = rindex(sp, '.')) != NULL) {
+ sp++;
+ for (i = 0; suflist[i] != NULL; i++)
+ if (strcmp(sp, suflist[i]) == 0) {
+ DPRINTF(2, (stderr, "FALSE (file has suffix \".%s\")\n", sp));
+ return FALSE;
+ }
+ }
+
+ datfile = copy(file, (unsigned int) (strlen(file) + 4)); /* +4 for ".dat" */
+ strcat(datfile, ".dat");
+ if (access(datfile, R_OK) < 0) {
+ free(datfile);
+ DPRINTF(2, (stderr, "FALSE (no \".dat\" file)\n"));
+ return FALSE;
+ }
+ if (datp != NULL)
+ *datp = datfile;
+ else
+ free(datfile);
+#ifdef OK_TO_WRITE_DISK
+ if (posp != NULL) {
+ *posp = copy(file, (unsigned int) (strlen(file) + 4)); /* +4 for ".dat" */
+ (void) strcat(*posp, ".pos");
+ }
+#endif /* OK_TO_WRITE_DISK */
+ DPRINTF(2, (stderr, "TRUE\n"));
+ return TRUE;
+}
+
+/*
+ * copy:
+ * Return a malloc()'ed copy of the string
+ */
+char *
+copy(str, len)
+char *str;
+unsigned int len;
+{
+ char *new, *sp;
+
+ new = do_malloc(len + 1);
+ sp = new;
+ do {
+ *sp++ = *str;
+ } while (*str++);
+ return new;
+}
+
+/*
+ * do_malloc:
+ * Do a malloc, checking for NULL return.
+ */
+char *
+do_malloc(size)
+unsigned int size;
+{
+ char *new;
+
+ if ((new = malloc(size)) == NULL) {
+ (void) fprintf(stderr, "fortune: out of memory.\n");
+ exit(1);
+ }
+ return new;
+}
+
+/*
+ * do_free:
+ * Free malloc'ed space, if any.
+ */
+do_free(ptr)
+char *ptr;
+{
+ if (ptr != NULL)
+ free(ptr);
+}
+
+/*
+ * init_prob:
+ * Initialize the fortune probabilities.
+ */
+init_prob()
+{
+ register FILEDESC *fp, *last;
+ register int percent, num_noprob, frac;
+
+ /*
+ * Distribute the residual probability (if any) across all
+ * files with unspecified probability (i.e., probability of 0)
+ * (if any).
+ */
+
+ percent = 0;
+ num_noprob = 0;
+ for (fp = File_tail; fp != NULL; fp = fp->prev)
+ if (fp->percent == NO_PROB) {
+ num_noprob++;
+ if (Equal_probs)
+ last = fp;
+ }
+ else
+ percent += fp->percent;
+ DPRINTF(1, (stderr, "summing probabilities:%d%% with %d NO_PROB's",
+ percent, num_noprob));
+ if (percent > 100) {
+ (void) fprintf(stderr,
+ "fortune: probabilities sum to %d%%!\n", percent);
+ exit(1);
+ }
+ else if (percent < 100 && num_noprob == 0) {
+ (void) fprintf(stderr,
+ "fortune: no place to put residual probability (%d%%)\n",
+ percent);
+ exit(1);
+ }
+ else if (percent == 100 && num_noprob != 0) {
+ (void) fprintf(stderr,
+ "fortune: no probability left to put in residual files\n");
+ exit(1);
+ }
+ percent = 100 - percent;
+ if (Equal_probs)
+ if (num_noprob != 0) {
+ if (num_noprob > 1) {
+ frac = percent / num_noprob;
+ DPRINTF(1, (stderr, ", frac = %d%%", frac));
+ for (fp = File_list; fp != last; fp = fp->next)
+ if (fp->percent == NO_PROB) {
+ fp->percent = frac;
+ percent -= frac;
+ }
+ }
+ last->percent = percent;
+ DPRINTF(1, (stderr, ", residual = %d%%", percent));
+ }
+ else {
+ DPRINTF(1, (stderr,
+ ", %d%% distributed over remaining fortunes\n",
+ percent));
+ }
+ DPRINTF(1, (stderr, "\n"));
+
+#ifdef DEBUG
+ if (Debug >= 1)
+ print_file_list();
+#endif
+}
+
+/*
+ * get_fort:
+ * Get the fortune data file's seek pointer for the next fortune.
+ */
+get_fort()
+{
+ register FILEDESC *fp;
+ register int choice;
+ long random();
+
+ if (File_list->next == NULL || File_list->percent == NO_PROB)
+ fp = File_list;
+ else {
+ choice = random() % 100;
+ DPRINTF(1, (stderr, "choice = %d\n", choice));
+ for (fp = File_list; fp->percent != NO_PROB; fp = fp->next)
+ if (choice < fp->percent)
+ break;
+ else {
+ choice -= fp->percent;
+ DPRINTF(1, (stderr,
+ " skip \"%s\", %d%% (choice = %d)\n",
+ fp->name, fp->percent, choice));
+ }
+ DPRINTF(1, (stderr,
+ "using \"%s\", %d%% (choice = %d)\n",
+ fp->name, fp->percent, choice));
+ }
+ if (fp->percent != NO_PROB)
+ get_tbl(fp);
+ else {
+ if (fp->next != NULL) {
+ sum_noprobs(fp);
+ choice = random() % Noprob_tbl.str_numstr;
+ DPRINTF(1, (stderr, "choice = %d (of %d) \n", choice,
+ Noprob_tbl.str_numstr));
+ while (choice >= fp->tbl.str_numstr) {
+ choice -= fp->tbl.str_numstr;
+ fp = fp->next;
+ DPRINTF(1, (stderr,
+ " skip \"%s\", %d (choice = %d)\n",
+ fp->name, fp->tbl.str_numstr,
+ choice));
+ }
+ DPRINTF(1, (stderr, "using \"%s\", %d\n", fp->name,
+ fp->tbl.str_numstr));
+ }
+ get_tbl(fp);
+ }
+ if (fp->child != NULL) {
+ DPRINTF(1, (stderr, "picking child\n"));
+ fp = pick_child(fp);
+ }
+ Fortfile = fp;
+ get_pos(fp);
+ open_dat(fp);
+ (void) lseek(fp->datfd,
+ (off_t) (sizeof fp->tbl + fp->pos * sizeof Seekpts[0]), 0);
+ read(fp->datfd, Seekpts, sizeof Seekpts);
+ Seekpts[0] = ntohl(Seekpts[0]);
+ Seekpts[1] = ntohl(Seekpts[1]);
+}
+
+/*
+ * pick_child
+ * Pick a child from a chosen parent.
+ */
+FILEDESC *
+pick_child(parent)
+FILEDESC *parent;
+{
+ register FILEDESC *fp;
+ register int choice;
+
+ if (Equal_probs) {
+ choice = random() % parent->num_children;
+ DPRINTF(1, (stderr, " choice = %d (of %d)\n",
+ choice, parent->num_children));
+ for (fp = parent->child; choice--; fp = fp->next)
+ continue;
+ DPRINTF(1, (stderr, " using %s\n", fp->name));
+ return fp;
+ }
+ else {
+ get_tbl(parent);
+ choice = random() % parent->tbl.str_numstr;
+ DPRINTF(1, (stderr, " choice = %d (of %d)\n",
+ choice, parent->tbl.str_numstr));
+ for (fp = parent->child; choice >= fp->tbl.str_numstr;
+ fp = fp->next) {
+ choice -= fp->tbl.str_numstr;
+ DPRINTF(1, (stderr, "\tskip %s, %d (choice = %d)\n",
+ fp->name, fp->tbl.str_numstr, choice));
+ }
+ DPRINTF(1, (stderr, " using %s, %d\n", fp->name,
+ fp->tbl.str_numstr));
+ return fp;
+ }
+}
+
+/*
+ * sum_noprobs:
+ * Sum up all the noprob probabilities, starting with fp.
+ */
+sum_noprobs(fp)
+register FILEDESC *fp;
+{
+ static bool did_noprobs = FALSE;
+
+ if (did_noprobs)
+ return;
+ zero_tbl(&Noprob_tbl);
+ while (fp != NULL) {
+ get_tbl(fp);
+ sum_tbl(&Noprob_tbl, &fp->tbl);
+ fp = fp->next;
+ }
+ did_noprobs = TRUE;
+}
+
+max(i, j)
+register int i, j;
+{
+ return (i >= j ? i : j);
+}
+
+/*
+ * open_fp:
+ * Assocatiate a FILE * with the given FILEDESC.
+ */
+open_fp(fp)
+FILEDESC *fp;
+{
+ if (fp->inf == NULL && (fp->inf = fdopen(fp->fd, "r")) == NULL) {
+ perror(fp->path);
+ exit(1);
+ }
+}
+
+/*
+ * open_dat:
+ * Open up the dat file if we need to.
+ */
+open_dat(fp)
+FILEDESC *fp;
+{
+ if (fp->datfd < 0 && (fp->datfd = open(fp->datfile, 0)) < 0) {
+ perror(fp->datfile);
+ exit(1);
+ }
+}
+
+/*
+ * get_pos:
+ * Get the position from the pos file, if there is one. If not,
+ * return a random number.
+ */
+get_pos(fp)
+FILEDESC *fp;
+{
+#ifdef OK_TO_WRITE_DISK
+ int fd;
+#endif /* OK_TO_WRITE_DISK */
+
+ assert(fp->read_tbl);
+ if (fp->pos == POS_UNKNOWN) {
+#ifdef OK_TO_WRITE_DISK
+ if ((fd = open(fp->posfile, 0)) < 0 ||
+ read(fd, &fp->pos, sizeof fp->pos) != sizeof fp->pos)
+ fp->pos = random() % fp->tbl.str_numstr;
+ else if (fp->pos >= fp->tbl.str_numstr)
+ fp->pos %= fp->tbl.str_numstr;
+ if (fd >= 0)
+ (void) close(fd);
+#else
+ fp->pos = random() % fp->tbl.str_numstr;
+#endif /* OK_TO_WRITE_DISK */
+ }
+ if (++(fp->pos) >= fp->tbl.str_numstr)
+ fp->pos -= fp->tbl.str_numstr;
+ DPRINTF(1, (stderr, "pos for %s is %d\n", fp->name, fp->pos));
+}
+
+/*
+ * get_tbl:
+ * Get the tbl data file the datfile.
+ */
+get_tbl(fp)
+FILEDESC *fp;
+{
+ auto int fd;
+ register FILEDESC *child;
+
+ if (fp->read_tbl)
+ return;
+ if (fp->child == NULL) {
+ if ((fd = open(fp->datfile, 0)) < 0) {
+ perror(fp->datfile);
+ exit(1);
+ }
+ if (read(fd, (char *) &fp->tbl, sizeof fp->tbl) != sizeof fp->tbl) {
+ (void)fprintf(stderr,
+ "fortune: %s corrupted\n", fp->path);
+ exit(1);
+ }
+ /* fp->tbl.str_version = ntohl(fp->tbl.str_version); */
+ fp->tbl.str_numstr = ntohl(fp->tbl.str_numstr);
+ fp->tbl.str_longlen = ntohl(fp->tbl.str_longlen);
+ fp->tbl.str_shortlen = ntohl(fp->tbl.str_shortlen);
+ fp->tbl.str_flags = ntohl(fp->tbl.str_flags);
+ (void) close(fd);
+ }
+ else {
+ zero_tbl(&fp->tbl);
+ for (child = fp->child; child != NULL; child = child->next) {
+ get_tbl(child);
+ sum_tbl(&fp->tbl, &child->tbl);
+ }
+ }
+ fp->read_tbl = TRUE;
+}
+
+/*
+ * zero_tbl:
+ * Zero out the fields we care about in a tbl structure.
+ */
+zero_tbl(tp)
+register STRFILE *tp;
+{
+ tp->str_numstr = 0;
+ tp->str_longlen = 0;
+ tp->str_shortlen = -1;
+}
+
+/*
+ * sum_tbl:
+ * Merge the tbl data of t2 into t1.
+ */
+sum_tbl(t1, t2)
+register STRFILE *t1, *t2;
+{
+ t1->str_numstr += t2->str_numstr;
+ if (t1->str_longlen < t2->str_longlen)
+ t1->str_longlen = t2->str_longlen;
+ if (t1->str_shortlen > t2->str_shortlen)
+ t1->str_shortlen = t2->str_shortlen;
+}
+
+#define STR(str) ((str) == NULL ? "NULL" : (str))
+
+/*
+ * print_file_list:
+ * Print out the file list
+ */
+print_file_list()
+{
+ print_list(File_list, 0);
+}
+
+/*
+ * print_list:
+ * Print out the actual list, recursively.
+ */
+print_list(list, lev)
+register FILEDESC *list;
+int lev;
+{
+ while (list != NULL) {
+ fprintf(stderr, "%*s", lev * 4, "");
+ if (list->percent == NO_PROB)
+ fprintf(stderr, "___%%");
+ else
+ fprintf(stderr, "%3d%%", list->percent);
+ fprintf(stderr, " %s", STR(list->name));
+ DPRINTF(1, (stderr, " (%s, %s, %s)\n", STR(list->path),
+ STR(list->datfile), STR(list->posfile)));
+ putc('\n', stderr);
+ if (list->child != NULL)
+ print_list(list->child, lev + 1);
+ list = list->next;
+ }
+}
+
+#ifndef NO_REGEX
+/*
+ * conv_pat:
+ * Convert the pattern to an ignore-case equivalent.
+ */
+char *
+conv_pat(orig)
+register char *orig;
+{
+ register char *sp;
+ register unsigned int cnt;
+ register char *new;
+
+ cnt = 1; /* allow for '\0' */
+ for (sp = orig; *sp != '\0'; sp++)
+ if (isalpha(*sp))
+ cnt += 4;
+ else
+ cnt++;
+ if ((new = malloc(cnt)) == NULL) {
+ fprintf(stderr, "pattern too long for ignoring case\n");
+ exit(1);
+ }
+
+ for (sp = new; *orig != '\0'; orig++) {
+ if (islower(*orig)) {
+ *sp++ = '[';
+ *sp++ = *orig;
+ *sp++ = toupper(*orig);
+ *sp++ = ']';
+ }
+ else if (isupper(*orig)) {
+ *sp++ = '[';
+ *sp++ = *orig;
+ *sp++ = tolower(*orig);
+ *sp++ = ']';
+ }
+ else
+ *sp++ = *orig;
+ }
+ *sp = '\0';
+ return new;
+}
+
+/*
+ * find_matches:
+ * Find all the fortunes which match the pattern we've been given.
+ */
+find_matches()
+{
+ Fort_len = maxlen_in_list(File_list);
+ DPRINTF(2, (stderr, "Maximum length is %d\n", Fort_len));
+ /* extra length, "%\n" is appended */
+ Fortbuf = do_malloc((unsigned int) Fort_len + 10);
+
+ Found_one = FALSE;
+ matches_in_list(File_list);
+ return Found_one;
+ /* NOTREACHED */
+}
+
+/*
+ * maxlen_in_list
+ * Return the maximum fortune len in the file list.
+ */
+maxlen_in_list(list)
+FILEDESC *list;
+{
+ register FILEDESC *fp;
+ register int len, maxlen;
+
+ maxlen = 0;
+ for (fp = list; fp != NULL; fp = fp->next) {
+ if (fp->child != NULL) {
+ if ((len = maxlen_in_list(fp->child)) > maxlen)
+ maxlen = len;
+ }
+ else {
+ get_tbl(fp);
+ if (fp->tbl.str_longlen > maxlen)
+ maxlen = fp->tbl.str_longlen;
+ }
+ }
+ return maxlen;
+}
+
+/*
+ * matches_in_list
+ * Print out the matches from the files in the list.
+ */
+matches_in_list(list)
+FILEDESC *list;
+{
+ register char *sp;
+ register FILEDESC *fp;
+ int in_file;
+
+ for (fp = list; fp != NULL; fp = fp->next) {
+ if (fp->child != NULL) {
+ matches_in_list(fp->child);
+ continue;
+ }
+ DPRINTF(1, (stderr, "searching in %s\n", fp->path));
+ open_fp(fp);
+ sp = Fortbuf;
+ in_file = FALSE;
+ while (fgets(sp, Fort_len, fp->inf) != NULL)
+ if (!STR_ENDSTRING(sp, fp->tbl))
+ sp += strlen(sp);
+ else {
+ *sp = '\0';
+ if (RE_EXEC(Fortbuf)) {
+ printf("%c%c", fp->tbl.str_delim,
+ fp->tbl.str_delim);
+ if (!in_file) {
+ printf(" (%s)", fp->name);
+ Found_one = TRUE;
+ in_file = TRUE;
+ }
+ putchar('\n');
+ (void) fwrite(Fortbuf, 1, (sp - Fortbuf), stdout);
+ }
+ sp = Fortbuf;
+ }
+ }
+}
+# endif /* NO_REGEX */
+
+usage()
+{
+ (void) fprintf(stderr, "fortune [-a");
+#ifdef DEBUG
+ (void) fprintf(stderr, "D");
+#endif /* DEBUG */
+ (void) fprintf(stderr, "f");
+#ifndef NO_REGEX
+ (void) fprintf(stderr, "i");
+#endif /* NO_REGEX */
+ (void) fprintf(stderr, "losw]");
+#ifndef NO_REGEX
+ (void) fprintf(stderr, " [-m pattern]");
+#endif /* NO_REGEX */
+ (void) fprintf(stderr, "[ [#%%] file/directory/all]\n");
+ exit(1);
+}
diff --git a/fortune/fortune/pathnames.h b/fortune/fortune/pathnames.h
new file mode 100644
index 00000000..e64ac65d
--- /dev/null
+++ b/fortune/fortune/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.2 (Berkeley) 4/8/91
+ */
+
+#define FORTDIR "/usr/share/games/fortune"
diff --git a/fortune/strfile/Makefile b/fortune/strfile/Makefile
new file mode 100644
index 00000000..96ee7782
--- /dev/null
+++ b/fortune/strfile/Makefile
@@ -0,0 +1,6 @@
+# @(#)Makefile 5.1 (Berkeley) 4/27/91
+
+PROG= strfile
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/fortune/strfile/strfile.8 b/fortune/strfile/strfile.8
new file mode 100644
index 00000000..2bbabe1b
--- /dev/null
+++ b/fortune/strfile/strfile.8
@@ -0,0 +1,147 @@
+.\" Copyright (c) 1989, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Ken Arnold.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strfile.8 5.9 (Berkeley) 3/16/91
+.\"
+.Dd March 16, 1991
+.Dt STRFILE 8
+.Os BSD 4
+.Sh NAME
+.Nm strfile ,
+.Nm unstr
+.Nd "create a random access file for storing strings"
+.Sh SYNOPSIS
+.Nm strfile
+.Op Fl iorsx
+.Op Fl c Ar char
+.Ar source_file
+.Op Ar output_file
+.Nm unstr
+.Ar source_file
+.Sh DESCRIPTION
+.Nm Strfile
+reads a file containing groups of lines separated by a line containing
+a single percent
+.Ql \&%
+sign and creates a data file which contains
+a header structure and a table of file offsets for each group of lines.
+This allows random access of the strings.
+.Pp
+The output file, if not specified on the command line, is named
+.Ar source_file Ns Sy .out .
+.Pp
+The options are as follows:
+.Bl -tag -width "-c char"
+.It Fl c Ar char
+Change the delimiting character from the percent sign to
+.Ar char .
+.It Fl i
+Ignore case when ordering the strings.
+.It Fl o
+Order the strings in alphabetical order.
+The offset table will be sorted in the alphabetical order of the
+groups of lines referenced.
+Any initial non-alphanumeric characters are ignored.
+This option causes the
+.Dv STR_ORDERED
+bit in the header
+.Ar str_flags
+field to be set.
+.It Fl r
+Randomize access to the strings.
+Entries in the offset table will be randomly ordered.
+This option causes the
+.Dv STR_RANDOM
+bit in the header
+.Ar str_flags
+field to be set.
+.It Fl s
+Run silently; don't give a summary message when finished.
+.It Fl x
+Note that each alphabetic character in the groups of lines is rotated
+13 positions in a simple caesar cypher.
+This option causes the
+.Dv STR_ROTATED
+bit in the header
+.Ar str_flags
+field to be set.
+.El
+.Pp
+The format of the header is:
+.Bd -literal
+#define VERSION 1
+unsigned long str_version; /* version number */
+unsigned long str_numstr; /* # of strings in the file */
+unsigned long str_longlen; /* length of longest string */
+unsigned long str_shortlen; /* length of shortest string */
+#define STR_RANDOM 0x1 /* randomized pointers */
+#define STR_ORDERED 0x2 /* ordered pointers */
+#define STR_ROTATED 0x4 /* rot-13'd text */
+unsigned long str_flags; /* bit field for flags */
+char str_delim; /* delimiting character */
+.Ed
+.Pp
+All fields are written in network byte order.
+.Pp
+The purpose of
+.Nm unstr
+is to undo the work of
+.Nm strfile .
+It prints out the strings contained in the file
+.Ar source_file
+in the order that they are listed in
+the header file
+.Ar source_file Ns Pa .dat
+to standard output.
+It is possible to create sorted versions of input files by using
+.Fl o
+when
+.Nm strfile
+is run and then using
+.Nm unstr
+to dump them out in the table order.
+.Sh SEE ALSO
+.Xr byteorder 3 ,
+.Xr fortune 6
+.Sh FILES
+.Bl -tag -width strfile.out -compact
+.It Pa strfile.out
+default output file.
+.El
+.Sh HISTORY
+The
+.Nm
+command
+.Ud
diff --git a/fortune/strfile/strfile.c b/fortune/strfile/strfile.c
new file mode 100644
index 00000000..6271e68d
--- /dev/null
+++ b/fortune/strfile/strfile.c
@@ -0,0 +1,456 @@
+/*-
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ken Arnold.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)strfile.c 5.12 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+# include <machine/endian.h>
+# include <sys/param.h>
+# include <stdio.h>
+# include <ctype.h>
+# include "strfile.h"
+
+# ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+# endif /* MAXPATHLEN */
+
+/*
+ * This program takes a file composed of strings seperated by
+ * lines starting with two consecutive delimiting character (default
+ * character is '%') and creates another file which consists of a table
+ * describing the file (structure from "strfile.h"), a table of seek
+ * pointers to the start of the strings, and the strings, each terminated
+ * by a null byte. Usage:
+ *
+ * % strfile [-iorsx] [ -cC ] sourcefile [ datafile ]
+ *
+ * c - Change delimiting character from '%' to 'C'
+ * s - Silent. Give no summary of data processed at the end of
+ * the run.
+ * o - order the strings in alphabetic order
+ * i - if ordering, ignore case
+ * r - randomize the order of the strings
+ * x - set rotated bit
+ *
+ * Ken Arnold Sept. 7, 1978 --
+ *
+ * Added ordering options.
+ */
+
+# define TRUE 1
+# define FALSE 0
+
+# define STORING_PTRS (Oflag || Rflag)
+# define CHUNKSIZE 512
+
+#ifdef lint
+# define ALWAYS atoi("1")
+#else
+# define ALWAYS 1
+#endif
+# define ALLOC(ptr,sz) if (ALWAYS) { \
+ if (ptr == NULL) \
+ ptr = malloc((unsigned int) (CHUNKSIZE * sizeof *ptr)); \
+ else if (((sz) + 1) % CHUNKSIZE == 0) \
+ ptr = realloc((void *) ptr, ((unsigned int) ((sz) + CHUNKSIZE) * sizeof *ptr)); \
+ if (ptr == NULL) { \
+ fprintf(stderr, "out of space\n"); \
+ exit(1); \
+ } \
+ } else
+
+#ifdef NO_VOID
+# define void char
+#endif
+
+typedef struct {
+ char first;
+ off_t pos;
+} STR;
+
+char *Infile = NULL, /* input file name */
+ Outfile[MAXPATHLEN] = "", /* output file name */
+ Delimch = '%'; /* delimiting character */
+
+int Sflag = FALSE; /* silent run flag */
+int Oflag = FALSE; /* ordering flag */
+int Iflag = FALSE; /* ignore case flag */
+int Rflag = FALSE; /* randomize order flag */
+int Xflag = FALSE; /* set rotated bit */
+long Num_pts = 0; /* number of pointers/strings */
+
+off_t *Seekpts;
+
+FILE *Sort_1, *Sort_2; /* pointers for sorting */
+
+STRFILE Tbl; /* statistics table */
+
+STR *Firstch; /* first chars of each string */
+
+char *fgets(), *strcpy(), *strcat();
+
+void *malloc(), *realloc();
+
+/*
+ * main:
+ * Drive the sucker. There are two main modes -- either we store
+ * the seek pointers, if the table is to be sorted or randomized,
+ * or we write the pointer directly to the file, if we are to stay
+ * in file order. If the former, we allocate and re-allocate in
+ * CHUNKSIZE blocks; if the latter, we just write each pointer,
+ * and then seek back to the beginning to write in the table.
+ */
+main(ac, av)
+int ac;
+char **av;
+{
+ register char *sp, dc;
+ register FILE *inf, *outf;
+ register off_t last_off, length, pos, *p;
+ register int first, cnt;
+ register char *nsp;
+ register STR *fp;
+ static char string[257];
+
+ getargs(ac, av); /* evalute arguments */
+ dc = Delimch;
+ if ((inf = fopen(Infile, "r")) == NULL) {
+ perror(Infile);
+ exit(1);
+ }
+
+ if ((outf = fopen(Outfile, "w")) == NULL) {
+ perror(Outfile);
+ exit(1);
+ }
+ if (!STORING_PTRS)
+ (void) fseek(outf, sizeof Tbl, 0);
+
+ /*
+ * Write the strings onto the file
+ */
+
+ Tbl.str_longlen = 0;
+ Tbl.str_shortlen = (unsigned int) 0xffffffff;
+ Tbl.str_delim = dc;
+ Tbl.str_version = VERSION;
+ first = Oflag;
+ add_offset(outf, ftell(inf));
+ last_off = 0;
+ do {
+ sp = fgets(string, 256, inf);
+ if (sp == NULL || sp[0] == dc && sp[1] == '\n') {
+ pos = ftell(inf);
+ length = pos - last_off - (sp ? strlen(sp) : 0);
+ last_off = pos;
+ if (!length)
+ continue;
+ add_offset(outf, pos);
+ if (Tbl.str_longlen < length)
+ Tbl.str_longlen = length;
+ if (Tbl.str_shortlen > length)
+ Tbl.str_shortlen = length;
+ first = Oflag;
+ }
+ else if (first) {
+ for (nsp = sp; !isalnum(*nsp); nsp++)
+ continue;
+ ALLOC(Firstch, Num_pts);
+ fp = &Firstch[Num_pts - 1];
+ if (Iflag && isupper(*nsp))
+ fp->first = tolower(*nsp);
+ else
+ fp->first = *nsp;
+ fp->pos = Seekpts[Num_pts - 1];
+ first = FALSE;
+ }
+ } while (sp != NULL);
+
+ /*
+ * write the tables in
+ */
+
+ (void) fclose(inf);
+
+ if (Oflag)
+ do_order();
+ else if (Rflag)
+ randomize();
+
+ if (Xflag)
+ Tbl.str_flags |= STR_ROTATED;
+
+ if (!Sflag) {
+ printf("\"%s\" created\n", Outfile);
+ if (Num_pts == 2)
+ puts("There was 1 string");
+ else
+ printf("There were %d strings\n", Num_pts - 1);
+ printf("Longest string: %lu byte%s\n", Tbl.str_longlen,
+ Tbl.str_longlen == 1 ? "" : "s");
+ printf("Shortest string: %lu byte%s\n", Tbl.str_shortlen,
+ Tbl.str_shortlen == 1 ? "" : "s");
+ }
+
+ (void) fseek(outf, (off_t) 0, 0);
+ Tbl.str_version = htonl(Tbl.str_version);
+ Tbl.str_numstr = htonl(Num_pts - 1);
+ Tbl.str_longlen = htonl(Tbl.str_longlen);
+ Tbl.str_shortlen = htonl(Tbl.str_shortlen);
+ Tbl.str_flags = htonl(Tbl.str_flags);
+ (void) fwrite((char *) &Tbl, sizeof Tbl, 1, outf);
+ if (STORING_PTRS) {
+ for (p = Seekpts, cnt = Num_pts; cnt--; ++p)
+ *p = htonl(*p);
+ (void) fwrite((char *) Seekpts, sizeof *Seekpts, (int) Num_pts, outf);
+ }
+ (void) fclose(outf);
+ exit(0);
+}
+
+/*
+ * This routine evaluates arguments from the command line
+ */
+getargs(argc, argv)
+int argc;
+char **argv;
+{
+ extern char *optarg;
+ extern int optind;
+ int ch;
+
+ while ((ch = getopt(argc, argv, "c:iorsx")) != EOF)
+ switch(ch) {
+ case 'c': /* new delimiting char */
+ Delimch = *optarg;
+ if (!isascii(Delimch)) {
+ printf("bad delimiting character: '\\%o\n'",
+ Delimch);
+ }
+ break;
+ case 'i': /* ignore case in ordering */
+ Iflag++;
+ break;
+ case 'o': /* order strings */
+ Oflag++;
+ break;
+ case 'r': /* randomize pointers */
+ Rflag++;
+ break;
+ case 's': /* silent */
+ Sflag++;
+ break;
+ case 'x': /* set the rotated bit */
+ Xflag++;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argv += optind;
+
+ if (*argv) {
+ Infile = *argv;
+ if (*++argv)
+ (void) strcpy(Outfile, *argv);
+ }
+ if (!Infile) {
+ puts("No input file name");
+ usage();
+ }
+ if (*Outfile == '\0') {
+ (void) strcpy(Outfile, Infile);
+ (void) strcat(Outfile, ".dat");
+ }
+}
+
+usage()
+{
+ (void) fprintf(stderr,
+ "strfile [-iorsx] [-c char] sourcefile [datafile]\n");
+ exit(1);
+}
+
+/*
+ * add_offset:
+ * Add an offset to the list, or write it out, as appropriate.
+ */
+add_offset(fp, off)
+FILE *fp;
+off_t off;
+{
+ off_t net;
+
+ if (!STORING_PTRS) {
+ net = htonl(off);
+ fwrite(&net, 1, sizeof net, fp);
+ } else {
+ ALLOC(Seekpts, Num_pts + 1);
+ Seekpts[Num_pts] = off;
+ }
+ Num_pts++;
+}
+
+/*
+ * do_order:
+ * Order the strings alphabetically (possibly ignoring case).
+ */
+do_order()
+{
+ register int i;
+ register off_t *lp;
+ register STR *fp;
+ extern int cmp_str();
+
+ Sort_1 = fopen(Infile, "r");
+ Sort_2 = fopen(Infile, "r");
+ qsort((char *) Firstch, (int) Tbl.str_numstr, sizeof *Firstch, cmp_str);
+ i = Tbl.str_numstr;
+ lp = Seekpts;
+ fp = Firstch;
+ while (i--)
+ *lp++ = fp++->pos;
+ (void) fclose(Sort_1);
+ (void) fclose(Sort_2);
+ Tbl.str_flags |= STR_ORDERED;
+}
+
+/*
+ * cmp_str:
+ * Compare two strings in the file
+ */
+char *
+unctrl(c)
+char c;
+{
+ static char buf[3];
+
+ if (isprint(c)) {
+ buf[0] = c;
+ buf[1] = '\0';
+ }
+ else if (c == 0177) {
+ buf[0] = '^';
+ buf[1] = '?';
+ }
+ else {
+ buf[0] = '^';
+ buf[1] = c + 'A' - 1;
+ }
+ return buf;
+}
+
+cmp_str(p1, p2)
+STR *p1, *p2;
+{
+ register int c1, c2;
+ register int n1, n2;
+
+# define SET_N(nf,ch) (nf = (ch == '\n'))
+# define IS_END(ch,nf) (ch == Delimch && nf)
+
+ c1 = p1->first;
+ c2 = p2->first;
+ if (c1 != c2)
+ return c1 - c2;
+
+ (void) fseek(Sort_1, p1->pos, 0);
+ (void) fseek(Sort_2, p2->pos, 0);
+
+ n1 = FALSE;
+ n2 = FALSE;
+ while (!isalnum(c1 = getc(Sort_1)) && c1 != '\0')
+ SET_N(n1, c1);
+ while (!isalnum(c2 = getc(Sort_2)) && c2 != '\0')
+ SET_N(n2, c2);
+
+ while (!IS_END(c1, n1) && !IS_END(c2, n2)) {
+ if (Iflag) {
+ if (isupper(c1))
+ c1 = tolower(c1);
+ if (isupper(c2))
+ c2 = tolower(c2);
+ }
+ if (c1 != c2)
+ return c1 - c2;
+ SET_N(n1, c1);
+ SET_N(n2, c2);
+ c1 = getc(Sort_1);
+ c2 = getc(Sort_2);
+ }
+ if (IS_END(c1, n1))
+ c1 = 0;
+ if (IS_END(c2, n2))
+ c2 = 0;
+ return c1 - c2;
+}
+
+/*
+ * randomize:
+ * Randomize the order of the string table. We must be careful
+ * not to randomize across delimiter boundaries. All
+ * randomization is done within each block.
+ */
+randomize()
+{
+ register int cnt, i;
+ register off_t tmp;
+ register off_t *sp;
+ extern time_t time();
+
+ srandom((int)(time((time_t *) NULL) + getpid()));
+
+ Tbl.str_flags |= STR_RANDOM;
+ cnt = Tbl.str_numstr;
+
+ /*
+ * move things around randomly
+ */
+
+ for (sp = Seekpts; cnt > 0; cnt--, sp++) {
+ i = random() % cnt;
+ tmp = sp[0];
+ sp[0] = sp[i];
+ sp[i] = tmp;
+ }
+}
diff --git a/fortune/strfile/strfile.h b/fortune/strfile/strfile.h
new file mode 100644
index 00000000..0f93928b
--- /dev/null
+++ b/fortune/strfile/strfile.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ken Arnold.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)strfile.h 5.8 (Berkeley) 4/8/91
+ */
+
+#define STR_ENDSTRING(line,tbl) \
+ ((line)[0] == (tbl).str_delim && (line)[1] == '\n')
+
+typedef struct { /* information table */
+#define VERSION 1
+ unsigned long str_version; /* version number */
+ unsigned long str_numstr; /* # of strings in the file */
+ unsigned long str_longlen; /* length of longest string */
+ unsigned long str_shortlen; /* length of shortest string */
+#define STR_RANDOM 0x1 /* randomized pointers */
+#define STR_ORDERED 0x2 /* ordered pointers */
+#define STR_ROTATED 0x4 /* rot-13'd text */
+ unsigned long str_flags; /* bit field for flags */
+ unsigned char stuff[4]; /* long aligned space */
+#define str_delim stuff[0] /* delimiting character */
+} STRFILE;
diff --git a/fortune/tools/Do_spell b/fortune/tools/Do_spell
new file mode 100644
index 00000000..fdba4892
--- /dev/null
+++ b/fortune/tools/Do_spell
@@ -0,0 +1,10 @@
+#!/bin/sh -
+#
+# @(#)Do_spell 5.2 (Berkeley) 4/8/91
+#
+
+F=_spell.$$
+echo $1
+spell < $1 > $F
+sort $F $1.sp.ok | uniq -u | column
+rm -f $F
diff --git a/fortune/tools/Do_troff b/fortune/tools/Do_troff
new file mode 100644
index 00000000..dc2000e3
--- /dev/null
+++ b/fortune/tools/Do_troff
@@ -0,0 +1,10 @@
+#!/bin/csh -f
+#
+# @(#)Do_troff 5.4 (Berkeley) 4/8/91
+#
+
+set file=$1
+shift
+( echo ".ds Se $file" ; cat Troff.mac ; sed -f Troff.sed $file ) | \
+ $* -me >& $file.tr
+echo troff output in $file.tr
diff --git a/fortune/tools/Troff.mac b/fortune/tools/Troff.mac
new file mode 100644
index 00000000..c2b433e1
--- /dev/null
+++ b/fortune/tools/Troff.mac
@@ -0,0 +1,26 @@
+.nr tp 8
+.nr hm 3v
+.nr fm 2v
+.nr tm 5v
+.nr bm 4v
+.cs R
+.sc
+.sz 6
+.ll +10n
+.lt \n(.l
+.de $h
+.tl 'Fortune Database'\\*(Se'\*(td'
+..
+.de $f
+.tl ''- % -''
+..
+.2c
+.nf
+.ta
+.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n 80n
+.de %%
+.sp .3
+.ce
+\(sq\|\(sq\|\(sq\|\(sq\|\(sq\|\(sq\|\(sq\|\(sq\|\(sq
+.sp .2
+..
diff --git a/fortune/tools/Troff.sed b/fortune/tools/Troff.sed
new file mode 100644
index 00000000..32166812
--- /dev/null
+++ b/fortune/tools/Troff.sed
@@ -0,0 +1,13 @@
+/^['.]/s//\\\&&/
+/^%%/s//.&/
+/--/s//\\*-/g
+/_a-squared cos 2(phi)/s//\\fIa\\fP\\u2\\d cos 2\\(*f/
+/__**\([a-zA-Z]*\)/s//\\fI\1\\fP/g
+/"\(.\)/s//\1\\*:/g
+/`\(.\)/s//\1\\*`/g
+/'\(.\)/s//\1\\*'/g
+/~\(.\)/s//\1\\*~/g
+/\^\(.\)/s//\1\\*^/g
+/,\(.\)/s//\1\\*,/g
+/\(.\)\(.\)/s//\\o_\1\2_/g
+/*/s//\\(bs/g
diff --git a/fortune/unstr/Makefile b/fortune/unstr/Makefile
new file mode 100644
index 00000000..12ce2289
--- /dev/null
+++ b/fortune/unstr/Makefile
@@ -0,0 +1,7 @@
+# @(#)Makefile 5.1 (Berkeley) 4/27/91
+
+PROG= unstr
+NOMAN= noman
+CFLAGS+=-I${.CURDIR}/../strfile
+
+.include <bsd.prog.mk>
diff --git a/fortune/unstr/unstr.c b/fortune/unstr/unstr.c
new file mode 100644
index 00000000..249705c7
--- /dev/null
+++ b/fortune/unstr/unstr.c
@@ -0,0 +1,144 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ken Arnold.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)unstr.c 5.8 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+/*
+ * This program un-does what "strfile" makes, thereby obtaining the
+ * original file again. This can be invoked with the name of the output
+ * file, the input file, or both. If invoked with only a single argument
+ * ending in ".dat", it is pressumed to be the input file and the output
+ * file will be the same stripped of the ".dat". If the single argument
+ * doesn't end in ".dat", then it is presumed to be the output file, and
+ * the input file is that name prepended by a ".dat". If both are given
+ * they are treated literally as the input and output files.
+ *
+ * Ken Arnold Aug 13, 1978
+ */
+
+# include <machine/endian.h>
+# include <sys/param.h>
+# include "strfile.h"
+# include <stdio.h>
+# include <ctype.h>
+
+# ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+# endif /* MAXPATHLEN */
+
+char *Infile, /* name of input file */
+ Datafile[MAXPATHLEN], /* name of data file */
+ Delimch; /* delimiter character */
+
+FILE *Inf, *Dataf;
+
+char *strcat(), *strcpy();
+
+/* ARGSUSED */
+main(ac, av)
+int ac;
+char **av;
+{
+ static STRFILE tbl; /* description table */
+
+ getargs(av);
+ if ((Inf = fopen(Infile, "r")) == NULL) {
+ perror(Infile);
+ exit(1);
+ }
+ if ((Dataf = fopen(Datafile, "r")) == NULL) {
+ perror(Datafile);
+ exit(1);
+ }
+ (void) fread((char *) &tbl, sizeof tbl, 1, Dataf);
+ tbl.str_version = ntohl(tbl.str_version);
+ tbl.str_numstr = ntohl(tbl.str_numstr);
+ tbl.str_longlen = ntohl(tbl.str_longlen);
+ tbl.str_shortlen = ntohl(tbl.str_shortlen);
+ tbl.str_flags = ntohl(tbl.str_flags);
+ if (!(tbl.str_flags & (STR_ORDERED | STR_RANDOM))) {
+ fprintf(stderr, "nothing to do -- table in file order\n");
+ exit(1);
+ }
+ Delimch = tbl.str_delim;
+ order_unstr(&tbl);
+ (void) fclose(Inf);
+ (void) fclose(Dataf);
+ exit(0);
+}
+
+getargs(av)
+register char *av[];
+{
+ if (!*++av) {
+ (void) fprintf(stderr, "usage: unstr datafile\n");
+ exit(1);
+ }
+ Infile = *av;
+ (void) strcpy(Datafile, Infile);
+ (void) strcat(Datafile, ".dat");
+}
+
+order_unstr(tbl)
+register STRFILE *tbl;
+{
+ register int i;
+ register char *sp;
+ auto off_t pos;
+ char buf[BUFSIZ];
+
+ for (i = 0; i < tbl->str_numstr; i++) {
+ (void) fread((char *) &pos, 1, sizeof pos, Dataf);
+ (void) fseek(Inf, ntohl(pos), 0);
+ if (i != 0)
+ (void) printf("%c\n", Delimch);
+ for (;;) {
+ sp = fgets(buf, sizeof buf, Inf);
+ if (sp == NULL || STR_ENDSTRING(sp, *tbl))
+ break;
+ else
+ fputs(sp, stdout);
+ }
+ }
+}
diff --git a/hack/COPYRIGHT b/hack/COPYRIGHT
new file mode 100644
index 00000000..71a94494
--- /dev/null
+++ b/hack/COPYRIGHT
@@ -0,0 +1,6 @@
+This entire subtree is copyright the Stichting Mathematisch Centrum.
+The following copyright notice applies to all files found here. None of
+these files contain AT&T proprietary source code.
+_____________________________________________________________________________
+
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
diff --git a/hack/Makefile b/hack/Makefile
new file mode 100644
index 00000000..a037ad27
--- /dev/null
+++ b/hack/Makefile
@@ -0,0 +1,35 @@
+# @(#)Makefile 5.10 (Berkeley) 12/8/90
+
+PROG= hack
+SRCS= alloc.c hack.Decl.c hack.apply.c hack.bones.c hack.c hack.cmd.c \
+ hack.do.c hack.do_name.c hack.do_wear.c hack.dog.c hack.eat.c \
+ hack.end.c hack.engrave.c hack.fight.c hack.invent.c hack.ioctl.c \
+ hack.lev.c hack.main.c hack.makemon.c hack.mhitu.c hack.mklev.c \
+ hack.mkmaze.c hack.mkobj.c hack.mkshop.c hack.mon.c hack.monst.c \
+ hack.o_init.c hack.objnam.c hack.options.c hack.pager.c hack.potion.c \
+ hack.pri.c hack.read.c hack.rip.c hack.rumors.c hack.save.c \
+ hack.search.c hack.shk.c hack.shknam.c hack.steal.c hack.termcap.c \
+ hack.timeout.c hack.topl.c hack.track.c hack.trap.c hack.tty.c \
+ hack.u_init.c hack.unix.c hack.vault.c hack.version.c hack.wield.c \
+ hack.wizard.c hack.worm.c hack.worn.c hack.zap.c rnd.c
+MAN6= hack.0
+DPADD= ${LIBTERM} ${LIBCOMPAT}
+LDADD= -ltermcap -lcompat
+HIDEGAME=hidegame
+
+hack.onames.h: makedefs def.objects.h
+ makedefs ${.CURDIR}/def.objects.h > hack.onames.h
+
+makedefs: makedefs.c
+ ${CC} ${CFLAGS} -o ${.TARGET} ${.CURDIR}/${.PREFIX}.c
+
+beforeinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \
+ ${DESTDIR}/var/games/hackdir/perm
+ install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \
+ ${DESTDIR}/var/games/hackdir/record
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/help \
+ ${.CURDIR}/hh ${.CURDIR}/data ${DESTDIR}/var/games/hackdir
+ rm -f ${DESTDIR}/var/games/hackdir/bones*
+
+.include <bsd.prog.mk>
diff --git a/hack/Makequest b/hack/Makequest
new file mode 100644
index 00000000..9271c284
--- /dev/null
+++ b/hack/Makequest
@@ -0,0 +1,196 @@
+# Hack or Quest Makefile.
+
+# on some systems the termcap library is in -ltermcap
+TERMLIB = -ltermlib
+
+
+# make hack
+GAME = quest
+GAMEDIR = /usr/games/lib/questdir
+CFLAGS = -g -DQUEST
+HACKCSRC = hack.Decl.c\
+ hack.apply.c hack.bones.c hack.c hack.cmd.c hack.do.c\
+ hack.do_name.c hack.do_wear.c hack.dog.c hack.eat.c hack.end.c\
+ hack.engrave.c hack.fight.c hack.invent.c hack.ioctl.c\
+ hack.lev.c hack.main.c hack.makemon.c hack.mhitu.c\
+ hack.mklev.c hack.mkmaze.c hack.mkobj.c hack.mkshop.c\
+ hack.mon.c hack.monst.c hack.o_init.c hack.objnam.c\
+ hack.options.c hack.pager.c hack.potion.c hack.pri.c\
+ hack.read.c hack.rip.c hack.rumors.c hack.save.c\
+ hack.search.c hack.shk.c hack.shknam.c hack.steal.c\
+ hack.termcap.c hack.timeout.c hack.topl.c\
+ hack.track.c hack.trap.c hack.tty.c hack.unix.c\
+ hack.u_init.c hack.vault.c\
+ hack.wield.c hack.wizard.c hack.worm.c hack.worn.c hack.zap.c\
+ hack.version.c rnd.c alloc.c
+
+CSOURCES = $(HACKCSRC) makedefs.c
+
+HSOURCES = hack.h hack.mfndpos.h config.h\
+ def.edog.h def.eshk.h def.flag.h def.func_tab.h def.gold.h\
+ def.mkroom.h\
+ def.monst.h def.obj.h def.objclass.h def.objects.h\
+ def.permonst.h def.rm.h def.trap.h def.wseg.h
+
+SOURCES = $(CSOURCES) $(HSOURCES)
+
+AUX = data help hh rumors hack.6 hack.sh
+
+DISTR = $(SOURCES) $(AUX) READ_ME Makefile date.h hack.onames.h
+
+HOBJ = hack.Decl.o hack.apply.o hack.bones.o hack.o hack.cmd.o hack.do.o\
+ hack.do_name.o hack.do_wear.o hack.dog.o hack.eat.o hack.end.o\
+ hack.engrave.o hack.fight.o hack.invent.o hack.ioctl.o\
+ hack.lev.o hack.main.o hack.makemon.o hack.mhitu.o hack.mklev.o\
+ hack.mkmaze.o hack.mkobj.o hack.mkshop.o hack.mon.o\
+ hack.monst.o hack.o_init.o hack.objnam.o hack.options.o\
+ hack.pager.o hack.potion.o hack.pri.o\
+ hack.read.o hack.rip.o hack.rumors.o hack.save.o\
+ hack.search.o hack.shk.o hack.shknam.o hack.steal.o\
+ hack.termcap.o hack.timeout.o hack.topl.o\
+ hack.track.o hack.trap.o\
+ hack.tty.o hack.unix.o hack.u_init.o hack.vault.o hack.wield.o\
+ hack.wizard.o hack.worm.o hack.worn.o hack.zap.o\
+ hack.version.o rnd.o alloc.o
+
+$(GAME): $(HOBJ) Makefile
+ @echo "Loading ..."
+ @ld -X -o $(GAME) /lib/crt0.o $(HOBJ) $(TERMLIB) -lc
+
+all: $(GAME) lint
+ @echo "Done."
+
+makedefs: makedefs.c
+ cc -o makedefs makedefs.c
+
+
+hack.onames.h: makedefs def.objects.h
+ makedefs > hack.onames.h
+
+lint:
+# lint cannot have -p here because (i) capitals are meaningful:
+# [Ww]izard, (ii) identifiers may coincide in the first six places:
+# doweararm() versus dowearring().
+# _flsbuf comes from <stdio.h>, a bug in the system libraries.
+ @echo lint -axbh -DLINT ...
+ @lint -axbh -DLINT $(HACKCSRC) | sed '/_flsbuf/d'
+
+
+diff:
+ @- for i in $(SOURCES) $(AUX) ; do \
+ cmp -s $$i $D/$$i || \
+ ( echo diff $D/$$i $$i ; diff $D/$$i $$i ; echo ) ; done
+
+distribution: Makefile
+ @- for i in READ_ME $(SOURCES) $(AUX) Makefile date.h hack.onames.h\
+ ; do \
+ cmp -s $$i $D/$$i || \
+ ( echo cp $$i $D ; cp $$i $D ) ; done
+# the distribution directory also contains the empty files perm and record.
+
+
+install:
+ rm -f $(GAMEDIR)/$(GAME)
+ cp $(GAME) $(GAMEDIR)/$(GAME)
+ chmod 04511 $(GAMEDIR)/$(GAME)
+ rm -f $(GAMEDIR)/bones*
+# cp hack.6 /usr/man/man6
+
+clean:
+ rm -f *.o
+
+
+depend:
+# For the moment we are lazy and disregard /usr/include files because
+# the sources contain them conditionally. Perhaps we should use cpp.
+# ( /bin/grep '^#[ ]*include' $$i | sed -n \
+# -e 's,<\(.*\)>,"/usr/include/\1",' \
+#
+ for i in ${CSOURCES}; do \
+ ( /bin/grep '^#[ ]*include[ ]*"' $$i | sed -n \
+ -e 's/[^"]*"\([^"]*\)".*/\1/' \
+ -e H -e '$$g' -e '$$s/\n/ /g' \
+ -e '$$s/.*/'$$i': &/' -e '$$s/\.c:/.o:/p' \
+ >> makedep); done
+ for i in ${HSOURCES}; do \
+ ( /bin/grep '^#[ ]*include[ ]*"' $$i | sed -n \
+ -e 's/[^"]*"\([^"]*\)".*/\1/' \
+ -e H -e '$$g' -e '$$s/\n/ /g' \
+ -e '$$s/.*/'$$i': &\
+ touch '$$i/p \
+ >> makedep); done
+ @echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
+ @echo '$$r makedep' >>eddep
+ @echo 'w' >>eddep
+ @cp Makefile Makefile.bak
+ ed - Makefile < eddep
+ @rm -f eddep makedep
+ @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
+ @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
+ @echo '# see make depend above' >> Makefile
+ - diff Makefile Makefile.bak
+ @rm -f Makefile.bak
+
+# DO NOT DELETE THIS LINE
+
+hack.Decl.o: hack.h def.mkroom.h
+hack.apply.o: hack.h def.edog.h def.mkroom.h
+hack.bones.o: hack.h
+hack.o: hack.h
+hack.cmd.o: hack.h def.func_tab.h
+hack.do.o: hack.h
+hack.do_name.o: hack.h
+hack.do_wear.o: hack.h
+hack.dog.o: hack.h hack.mfndpos.h def.edog.h def.mkroom.h
+hack.eat.o: hack.h
+hack.end.o: hack.h
+hack.engrave.o: hack.h
+hack.fight.o: hack.h
+hack.invent.o: hack.h def.wseg.h
+hack.ioctl.o: config.h
+hack.lev.o: hack.h def.mkroom.h def.wseg.h
+hack.main.o: hack.h
+hack.makemon.o: hack.h
+hack.mhitu.o: hack.h
+hack.mklev.o: hack.h def.mkroom.h
+hack.mkmaze.o: hack.h def.mkroom.h
+hack.mkobj.o: hack.h
+hack.mkshop.o: hack.h def.mkroom.h def.eshk.h
+hack.mon.o: hack.h hack.mfndpos.h
+hack.monst.o: hack.h def.eshk.h
+hack.o_init.o: config.h def.objects.h hack.onames.h
+hack.objnam.o: hack.h
+hack.options.o: config.h hack.h
+hack.pager.o: hack.h
+hack.potion.o: hack.h
+hack.pri.o: hack.h def.wseg.h
+hack.read.o: hack.h
+hack.rip.o: hack.h
+hack.rumors.o: hack.h
+hack.save.o: hack.h
+hack.search.o: hack.h
+hack.shk.o: hack.h hack.mfndpos.h def.mkroom.h def.eshk.h
+hack.shknam.o: hack.h
+hack.steal.o: hack.h
+hack.termcap.o: config.h def.flag.h
+hack.timeout.o: hack.h
+hack.topl.o: hack.h
+hack.track.o: hack.h
+hack.trap.o: hack.h def.mkroom.h
+hack.tty.o: hack.h
+hack.unix.o: hack.h def.mkroom.h
+hack.u_init.o: hack.h
+hack.vault.o: hack.h def.mkroom.h
+hack.wield.o: hack.h
+hack.wizard.o: hack.h
+hack.worm.o: hack.h def.wseg.h
+hack.worn.o: hack.h
+hack.zap.o: hack.h
+hack.version.o: date.h
+hack.h: config.h def.objclass.h def.monst.h def.gold.h def.trap.h def.obj.h def.flag.h def.rm.h def.permonst.h hack.onames.h
+ touch hack.h
+def.objects.h: config.h def.objclass.h
+ touch def.objects.h
+# DEPENDENCIES MUST END AT END OF FILE
+# IF YOU PUT STUFF HERE IT WILL GO AWAY
+# see make depend above
diff --git a/hack/OWNER b/hack/OWNER
new file mode 100644
index 00000000..be2d1e53
--- /dev/null
+++ b/hack/OWNER
@@ -0,0 +1,2 @@
+Andries Brouwer
+mcvax!aeb
diff --git a/hack/Original_READ_ME b/hack/Original_READ_ME
new file mode 100644
index 00000000..9d2070be
--- /dev/null
+++ b/hack/Original_READ_ME
@@ -0,0 +1,61 @@
+This is export hack, my first semester programming project.
+
+To set it up for your system, you will have to do the following:
+ 1: create a hack uid, to own the top ten list, etc.
+ 2: create a hack directory "/usr/lib/game/hack" is the default.
+ 2.5: make the directory 700 mode. /* sav files go in there...*/
+ 3: modify hack.main.c to use the new directory.
+ 4: modify hack.main.c so it uses the new hack gid. Gid accounts can
+go into magic mode without the password, can get cores with ^G, etc.
+(make sure gid isn't checked anywhere else...)
+ 5: recompile hack.
+ 6: put it in games after making it set-uid hack.
+ 8: fix the bugs I undobtedly left in it.
+ 9: tell me what you think of it.
+
+ Hack uses the UCB file /etc/termcap to get your terminal escape codes.
+If you don't use it, you will have to make extensive changes to hack.pri.c
+
+If you find any bugs (That you think I don't know about), or have any
+awesome new changes (Like a better save (One that works!)), or have ANY
+questions, write me
+ Jay Fenlason
+ 29 East St.
+ Sudbury Mass.
+ 01776
+
+or call me at (617) 443-5036. Since I have both a modem and a teen-age
+sister, Good Luck.
+
+
+Hack is split (roughly) into several source files that do different things.
+I have tried to fit all the procedures having to do with a certain segment
+of the game into a single file, but the job is not the best in the world.
+The rough splits are:
+
+hack.c General random stuff and things I never got around to moving.
+hack.main.c main() and other random procedures, also the lock file stuff.
+hack.mon.c Monsters, moving, attacking, etc.
+hack.do.c drink, eat, read, wield, save, etc.
+hack.do1.c zap, wear, remove, etc...
+hack.pri.c stuff having to do with the screen, most of the terminal
+ independant stuff is in here.
+hack.lev.c temp files and calling of mklev.
+
+Because of the peculiar restraints on our system, I make mklev (create
+a level) a separate procedure execd by hack when needed. The source for
+mklev is (Naturaly) mklev.c. You may want to put mklev back into hack.
+Good luck.
+
+Most of hack was written by me, with help from
+ Kenny Woodland (KW) (general random things including
+ the original BUZZ())
+ Mike Thome (MT) (The original chamelian)
+ and Jon Payne (JP) (The original lock file kludge and
+ the massive CURS())
+
+This entire program would not have been possible without the SFSU Logo
+Workshop. I am eternally grateful to all of our students (Especially K.L.),
+without whom I would never have seen Rogue. I am especially grateful to
+Mike Clancy, without whose generous help I would never have gotten to play
+ROGUE.
diff --git a/hack/READ_ME b/hack/READ_ME
new file mode 100644
index 00000000..cfe6ca2f
--- /dev/null
+++ b/hack/READ_ME
@@ -0,0 +1,92 @@
+Hack is a display oriented dungeons & dragons - like game.
+Both display and command structure resemble rogue.
+(For a game with the same structure but entirely different display -
+a real cave instead of dull rectangles - try Quest)
+
+Hack was originally written by Jay Fenlason (at lincolnsudbury:
+ 29 East St., Sudbury Mass., 01776) with help from
+ Kenny Woodland, Mike Thome and Jon Payne.
+Basically it was an implementation of Rogue, however, with 52+ instead of 26
+ monster types.
+The current version is more than thrice as large (with such new features as
+ the dog, the long worms, the shops, etc.) and almost entirely rewritten
+ (only the display routines are the original ones - I must rewrite these
+ too one day; especially when you are blind strange things still happen).
+
+Files for hack:
+ hack The actual game
+ record Top 100 list (just start with an empty file)
+ news Tells about recent changes in hack, or bugs found ...
+ (Just start with no news file.)
+ data Auxiliary file used by hack to give you the names
+ and sometimes some more information on the
+ objects and monsters.
+ help Introductory information (no doubt outdated).
+ hh Compactified version of help.
+ perm An empty file used for locking purposes.
+ rumors Texts for fortune cookies.
+ (Some of these contain information on the game,
+ others are just plain stupid. Additional rumors
+ are appreciated.)
+ hack.sh A shell script.
+ (We have hack.sh in /usr/games/hack and
+ hack in /usr/games/lib/hackdir/hack and all the other
+ hack stuff in /usr/games/lib/hackdir - perhaps this
+ will make the script clear.
+ There is no need for you to use it.)
+ READ_ME This file.
+ Original_READ_ME Jay Fenlason's READ_ME
+
+System files used:
+ /etc/termcap Used in conjunction with the environment variable
+ $TERM.
+ /bin/cat
+ /usr/ucb/more
+ /bin/sh Used when $SHELL is undefined.
+
+How to install hack:
+0. Compile the sources. Perhaps you should first look at the file config.h
+ and define BSD if you are on a BSDtype system,
+ define STUPID if your C-compiler chokes on complicated expressions.
+ Make sure schar and uchar represent signed and unsigned types.
+ If your C compiler doesnt allow initialization of bit fields
+ change Bitfield. When config.h looks reasonable, say 'make'.
+ (Perhaps you have to change TERMLIB in the makefile.)
+1. If it didnt exist already, introduce a loginname `play' .
+2. The program hack resides in a directory so that it is executable
+ for everybody and is suid play:
+ ---s--s--x 1 play 206848 Apr 3 00:17 hack
+ Perhaps you wish to restrict playing to certain hours, or have games
+ running under nice; in that case you might write a program play.c
+ such that the program play is suid play and executable for everybody
+ while all the games in /usr/games are readable or executable for
+ play only; all the program play does is asking for the name of a game,
+ checking that time-of-day and system load do not forbid playing,
+ and then executing the game. Thus:
+ -r-sr-sr-x 1 play 13312 May 24 12:52 play
+ ---x------ 1 play 206848 Apr 3 00:17 hack
+ If you are worried about security you might let play do
+ chroot("/usr/games") so that no player can get access to the rest
+ of the system via shell escapes and the likes.
+ If you #define SECURE in config.h then hack will not setuid(getuid())
+ before executing a chdir(). Hack will always do setuid(getuid()) with
+ a fork. If you do not define UNIX then hack will not fork.
+3. The rest of the stuff belonging to hack sits in a subdirectory hackdir
+ (on our system /usr/games/lib/hackdir) with modes
+ drwx------ 3 play 1024 Aug 9 09:03 hackdir
+ Here all the temporary files will be created (with names like xlock.17
+ or user.5).
+4. If you are not really short on file space, creating a subdirectory
+ hackdir/save (modes again drwx------) will enable users to save their
+ unfinished games.
+
+The program hack is called
+$ hack [-d hackdir] [maxnrofplayers]
+(for playing) or
+$ hack [-d hackdir] -s [listofusers | limit | all]
+(for seeing part of the scorelist).
+The shell file hack (in this kit called hack.sh) takes care of
+calling hack with the right arguments.
+
+Send complaints, bug reports, suggestions for improvements to
+mcvax!aeb - in real life Andries Brouwer.
diff --git a/hack/alloc.c b/hack/alloc.c
new file mode 100644
index 00000000..d94bf8b9
--- /dev/null
+++ b/hack/alloc.c
@@ -0,0 +1,47 @@
+/* alloc.c - version 1.0.2 */
+#ifdef LINT
+
+/*
+ a ridiculous definition, suppressing
+ "possible pointer alignment problem" for (long *) malloc()
+ "enlarg defined but never used"
+ "ftell defined (in <stdio.h>) but never used"
+ from lint
+*/
+#include <stdio.h>
+long *
+alloc(n) unsigned n; {
+long dummy = ftell(stderr);
+ if(n) dummy = 0; /* make sure arg is used */
+ return(&dummy);
+}
+
+#else
+
+extern char *malloc();
+extern char *realloc();
+
+long *
+alloc(lth)
+register unsigned lth;
+{
+ register char *ptr;
+
+ if(!(ptr = malloc(lth)))
+ panic("Cannot get %d bytes", lth);
+ return((long *) ptr);
+}
+
+long *
+enlarge(ptr,lth)
+register char *ptr;
+register unsigned lth;
+{
+ register char *nptr;
+
+ if(!(nptr = realloc(ptr,lth)))
+ panic("Cannot reallocate %d bytes", lth);
+ return((long *) nptr);
+}
+
+#endif LINT
diff --git a/hack/config.h b/hack/config.h
new file mode 100644
index 00000000..f382937b
--- /dev/null
+++ b/hack/config.h
@@ -0,0 +1,139 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* config.h - version 1.0.3 */
+
+#include "pathnames.h"
+
+#ifndef CONFIG /* make sure the compiler doesnt see the typedefs twice */
+
+#define CONFIG
+#define UNIX /* delete if no fork(), exec() available */
+#define CHDIR /* delete if no chdir() available */
+
+/*
+ * Some include files are in a different place under SYSV
+ * BSD SYSV
+ * <sys/wait.h> <wait.h>
+ * <sys/time.h> <time.h>
+ * <sgtty.h> <termio.h>
+ * Some routines are called differently
+ * index strchr
+ * rindex strrchr
+ * Also, the code for suspend and various ioctls is only given for BSD4.2
+ * (I do not have access to a SYSV system.)
+ */
+#define BSD /* delete this line on System V */
+
+/* #define STUPID */ /* avoid some complicated expressions if
+ your C compiler chokes on them */
+/* #define PYRAMID_BUG */ /* avoid a bug on the Pyramid */
+/* #define NOWAITINCLUDE */ /* neither <wait.h> nor <sys/wait.h> exists */
+
+#define WIZARD "bruno" /* the person allowed to use the -D option */
+#define RECORD "record"/* the file containing the list of topscorers */
+#define NEWS "news" /* the file containing the latest hack news */
+#define HELP "help" /* the file containing a description of the commands */
+#define SHELP "hh" /* abbreviated form of the same */
+#define RUMORFILE "rumors" /* a file with fortune cookies */
+#define DATAFILE "data" /* a file giving the meaning of symbols used */
+#define FMASK 0660 /* file creation mask */
+#define HLOCK "perm" /* an empty file used for locking purposes */
+#define LLOCK "safelock" /* link to previous */
+
+#ifdef UNIX
+/*
+ * Define DEF_PAGER as your default pager, e.g. "/bin/cat" or "/usr/ucb/more"
+ * If defined, it can be overridden by the environment variable PAGER.
+ * Hack will use its internal pager if DEF_PAGER is not defined.
+ * (This might be preferable for security reasons.)
+ * #define DEF_PAGER ".../mydir/mypager"
+ */
+
+/*
+ * If you define MAIL, then the player will be notified of new mail
+ * when it arrives. If you also define DEF_MAILREADER then this will
+ * be the default mail reader, and can be overridden by the environment
+ * variable MAILREADER; otherwise an internal pager will be used.
+ * A stat system call is done on the mailbox every MAILCKFREQ moves.
+ */
+/* #define MAIL */
+#define DEF_MAILREADER _PATH_MAIL /* or e.g. /bin/mail */
+#define MAILCKFREQ 100
+
+
+#define SHELL /* do not delete the '!' command */
+
+#ifdef BSD
+#define SUSPEND /* let ^Z suspend the game */
+#endif BSD
+#endif UNIX
+
+#ifdef CHDIR
+/*
+ * If you define HACKDIR, then this will be the default playground;
+ * otherwise it will be the current directory.
+ */
+#ifdef QUEST
+#define HACKDIR _PATH_QUEST
+#else QUEST
+#define HACKDIR _PATH_HACK
+#endif QUEST
+
+/*
+ * Some system administrators are stupid enough to make Hack suid root
+ * or suid daemon, where daemon has other powers besides that of reading or
+ * writing Hack files. In such cases one should be careful with chdir's
+ * since the user might create files in a directory of his choice.
+ * Of course SECURE is meaningful only if HACKDIR is defined.
+ */
+#define SECURE /* do setuid(getuid()) after chdir() */
+
+/*
+ * If it is desirable to limit the number of people that can play Hack
+ * simultaneously, define HACKDIR, SECURE and MAX_NR_OF_PLAYERS.
+ * #define MAX_NR_OF_PLAYERS 100
+ */
+#endif CHDIR
+
+/* size of terminal screen is (at least) (ROWNO+2) by COLNO */
+#define COLNO 80
+#define ROWNO 22
+
+/*
+ * small signed integers (8 bits suffice)
+ * typedef char schar;
+ * will do when you have signed characters; otherwise use
+ * typedef short int schar;
+ */
+typedef char schar;
+
+/*
+ * small unsigned integers (8 bits suffice - but 7 bits do not)
+ * - these are usually object types; be careful with inequalities! -
+ * typedef unsigned char uchar;
+ * will be satisfactory if you have an "unsigned char" type; otherwise use
+ * typedef unsigned short int uchar;
+ */
+typedef unsigned char uchar;
+
+/*
+ * small integers in the range 0 - 127, usually coordinates
+ * although they are nonnegative they must not be declared unsigned
+ * since otherwise comparisons with signed quantities are done incorrectly
+ */
+typedef schar xchar;
+typedef xchar boolean; /* 0 or 1 */
+#define TRUE 1
+#define FALSE 0
+
+/*
+ * Declaration of bitfields in various structs; if your C compiler
+ * doesnt handle bitfields well, e.g., if it is unable to initialize
+ * structs containing bitfields, then you might use
+ * #define Bitfield(x,n) uchar x
+ * since the bitfields used never have more than 7 bits. (Most have 1 bit.)
+ */
+#define Bitfield(x,n) unsigned x:n
+
+#define SIZE(x) (int)(sizeof(x) / sizeof(x[0]))
+
+#endif CONFIG
diff --git a/hack/data b/hack/data
new file mode 100644
index 00000000..5d8d509b
--- /dev/null
+++ b/hack/data
@@ -0,0 +1,232 @@
+ Hack & Quest data file - version 1.0.3
+@ human (or you)
+- a wall
+| a wall
++ a door
+. the floor of a room
+ a dark part of a room
+# a corridor
+} water filled area
+< the staircase to the previous level
+> the staircase to the next level
+^ a trap
+$ a pile, pot or chest of gold
+%% a piece of food
+! a potion
+* a gem
+? a scroll
+= a ring
+/ a wand
+[ a suit of armor
+) a weapon
+( a useful item (camera, key, rope etc.)
+0 an iron ball
+_ an iron chain
+` an enormous rock
+" an amulet
+, a trapper
+: a chameleon
+; a giant eel
+' a lurker above
+& a demon
+A a giant ant
+B a giant bat
+C a centaur;
+ Of all the monsters put together by the Greek imagination
+ the Centaurs (Kentauroi) constituted a class in themselves.
+ Despite a strong streak of sensuality in their make-up,
+ their normal behaviour was moral, and they took a kindly
+ thought of man's welfare. The attempted outrage of Nessos on
+ Deianeira, and that of the whole tribe of Centaurs on the
+ Lapith women, are more than offset by the hospitality of
+ Pholos and by the wisdom of Cheiron, physician, prophet,
+ lyrist, and the instructor of Achilles. Further, the Cen-
+ taurs were peculiar in that their nature, which united the
+ body of a horse with the trunk and head of a man, involved
+ an unthinkable duplication of vital organs and important
+ members. So grotesque a combination seems almost un-Greek.
+ These strange creatures were said to live in the caves and
+ clefts of the mountains, myths associating them especially
+ with the hills of Thessaly and the range of Erymanthos.
+ [Mythology of all races, Vol. 1, pp. 270-271]
+D a dragon;
+ In the West the dragon was the natural enemy of man. Although
+ preferring to live in bleak and desolate regions, whenever it was
+ seen among men it left in its wake a trail of destruction and
+ disease. Yet any attempt to slay this beast was a perilous under-
+ taking. For the dragon's assailant had to contend not only with
+ clouds of sulphurous fumes pouring from its fire-breathing nos-
+ trils, but also with the thrashings of its tail, the most deadly
+ part of its serpent-like body.
+ [From: Mythical Beasts by Deirdre Headon (The Leprechaun Library)]
+E a floating eye
+F a freezing sphere
+G a gnome;
+ ... And then a gnome came by, carrying a bundle, an old fellow
+ three times as large as an imp and wearing clothes of a sort,
+ especially a hat. And he was clearly just as frightened as the
+ imps though he could not go so fast. Ramon Alonzo saw that there
+ must be some great trouble that was vexing magical things; and,
+ since gnomes speak the language of men, and will answer if spoken
+ to gently, he raised his hat, and asked of the gnome his name.
+ The gnome did not stop his hasty shuffle a moment as he answered
+ 'Alaraba' and grabbed the rim of his hat but forgot to doff it.
+ 'What is the trouble, Alaraba?' said Ramon Alonzo.
+ 'White magic. Run!' said the gnome ...
+ [From: The Charwoman's Shadow, by Lord Dunsany.]
+H a hobgoblin;
+ Hobgoblin. Used by the Puritans and in later times for
+ wicked goblin spirits, as in Bunyan's 'Hobgoblin nor foul
+ friend', but its more correct use is for the friendly spir-
+ its of the brownie type. In 'A midsummer night's dream' a
+ fairy says to Shakespeare's Puck:
+ Those that Hobgoblin call you, and sweet Puck,
+ You do their work, and they shall have good luck:
+ Are you not he?
+ and obviously Puck would not wish to be called a hobgoblin
+ if that was an ill-omened word.
+ Hobgoblins are on the whole, good-humoured and ready to be
+ helpful, but fond of practical joking, and like most of the
+ fairies rather nasty people to annoy. Boggarts hover on the
+ verge of hobgoblindom. Bogles are just over the edge.
+ One Hob mentioned by Henderson, was Hob Headless who haunted
+ the road between Hurworth and Neasham, but could not cross
+ the little river Kent, which flowed into the Tess. He was
+ exorcised and laid under a large stone by the roadside for
+ ninety-nine years and a day. If anyone was so unwary as to
+ sit on that stone, he would be unable to quit it for ever.
+ The ninety-nine years is nearly up, so trouble may soon be
+ heard of on the road between Hurworth and Neasham.
+ [Katharine Briggs, A dictionary of Fairies]
+I an invisible stalker
+J a jackal
+K a kobold
+L a leprechaun;
+ The Irish Leprechaun is the Faeries' shoemaker and is known
+ under various names in different parts of Ireland: Cluri-
+ caune in Cork, Lurican in Kerry, Lurikeen in Kildare and Lu-
+ rigadaun in Tipperary. Although he works for the Faeries,
+ the Leprechaun is not of the same species. He is small, has
+ dark skin and wears strange clothes. His nature has some-
+ thing of the manic-depressive about it: first he is quite
+ happy, whistling merrily as he nails a sole on to a shoe; a
+ few minutes later, he is sullen and morose, drunk on his
+ home-made heather ale. The Leprechaun's two great loves are
+ tobacco and whiskey, and he is a first-rate con-man, impos-
+ sible to out-fox. No one, no matter how clever, has ever
+ managed to cheat him out of his hidden pot of gold or his
+ magic shilling. At the last minute he always thinks of some
+ way to divert his captor's attention and vanishes in the
+ twinkling of an eye.
+ [From: A Field Guide to the Little People
+ by Nancy Arrowsmith & George Moorse. ]
+M a mimic
+N a nymph
+O an orc
+P a purple worm
+Q a quasit
+R a rust monster
+S a snake
+T a troll
+U an umber hulk
+V a vampire
+W a wraith
+X a xorn
+Y a yeti
+Z a zombie
+a an acid blob
+b a giant beetle
+c a cockatrice;
+ Once in a great while, when the positions of the stars are
+ just right, a seven-year-old rooster will lay an egg. Then,
+ along will come a snake, to coil around the egg, or a toad,
+ to squat upon the egg, keeping it warm and helping it to
+ hatch. When it hatches, out comes a creature called basil-
+ isk, or cockatrice, the most deadly of all creatures. A sin-
+ gle glance from its yellow, piercing toad's eyes will kill
+ both man and beast. Its power of destruction is said to be
+ so great that sometimes simply to hear its hiss can prove
+ fatal. Its breath is so venomenous that it causes all vege-
+ tation to wither.
+ There is, however, one creature which can withstand the
+ basilisk's deadly gaze, and this is the weasel. No one knows
+ why this is so, but although the fierce weasel can slay the
+ basilisk, it will itself be killed in the struggle. Perhaps
+ the weasel knows the basilisk's fatal weakness: if it ever
+ sees its own reflection in a mirror it will perish instant-
+ ly. But even a dead basilisk is dangerous, for it is said
+ that merely touching its lifeless body can cause a person to
+ sicken and die.
+ [From: Mythical Beasts by Deirdre Headon (The Leprechaun
+ Library) and other sources. ]
+d a dog
+e an ettin
+f a fog cloud
+g a gelatinous cube
+h a homunculus
+i an imp;
+ ... imps ... little creatures of two feet high that could
+ gambol and jump prodigiously; ...
+ [From: The Charwoman's Shadow, by Lord Dunsany.]
+
+ An 'imp' is an off-shoot or cutting. Thus an 'ymp tree' was
+ a grafted tree, or one grown from a cutting, not from seed.
+ 'Imp' properly means a small devil, an off-shoot of Satan,
+ but the distinction between goblins or bogles and imps from
+ hell is hard to make, and many in the Celtic countries as
+ well as the English Puritans regarded all fairies as devils.
+ The fairies of tradition often hover uneasily between the
+ ghostly and the diabolic state.
+ [Katharine Briggs, A dictionary of Fairies]
+j a jaguar
+k a killer bee
+l a leocrotta
+m a minotaur
+n a nurse
+o an owlbear
+p a piercer
+q a quivering blob
+r a giant rat
+s a scorpion
+t a tengu;
+ The tengu was the most troublesome creature of Japanese
+ legend. Part bird and part man, with red beak for a nose
+ and flashing eyes, the tengu was notorious for stirring up
+ feuds and prolonging enmity between families. Indeed, the
+ belligerent tengus were supposed to have been man's first
+ instructors in the use of arms.
+ [From: Mythical Beasts by Deirdre Headon
+ (The Leprechaun Library). ]
+u a unicorn;
+ Men have always sought the elusive unicorn, for the single
+ twisted horn which projected from its forehead was thought
+ to be a powerful talisman. It was said that the unicorn had
+ simply to dip the tip of its horn in a muddy pool for the
+ water to become pure. Men also believed that to drink from
+ this horn was a protection against all sickness, and that if
+ the horn was ground to a powder it would act as an antidote
+ to all poisons. Less than 200 years ago in France, the horn
+ of a unicorn was used in a ceremony to test the royal food
+ for poison.
+ Although only the size of a small horse, the unicorn is a
+ very fierce beast, capable of killing an elephant with a
+ single thrust from its horn. Its fleetness of foot also
+ makes this solitary creature difficult to capture. However,
+ it can be tamed and captured by a maiden. Made gentle by the
+ sight of a virgin, the unicorn can be lured to lay its head
+ in her lap, and in this docile mood, the maiden may secure
+ it with a golden rope.
+ [From: Mythical Beasts by Deirdre Headon
+ (The Leprechaun Library). ]
+v a violet fungi
+w a long worm;
+ From its teeth the crysknife can be manufactured.
+~ the tail of a long worm
+x a xan;
+ The xan were animals sent to prick the legs of the Lords of Xibalba.
+y a yellow light
+z a zruty;
+ The zruty are wild and gigantic beings, living in the wildernesses
+ of the Tatra mountains.
+1 The wizard of Yendor
+2 The mail daemon
diff --git a/hack/date.h b/hack/date.h
new file mode 100644
index 00000000..9a7ef768
--- /dev/null
+++ b/hack/date.h
@@ -0,0 +1,2 @@
+
+char datestring[] = "Tue Jul 23 1985";
diff --git a/hack/def.edog.h b/hack/def.edog.h
new file mode 100644
index 00000000..a5c2b461
--- /dev/null
+++ b/hack/def.edog.h
@@ -0,0 +1,12 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.edog.h - version 1.0.2 */
+
+struct edog {
+ long hungrytime; /* at this time dog gets hungry */
+ long eattime; /* dog is eating */
+ long droptime; /* moment dog dropped object */
+ unsigned dropdist; /* dist of drpped obj from @ */
+ unsigned apport; /* amount of training */
+ long whistletime; /* last time he whistled */
+};
+#define EDOG(mp) ((struct edog *)(&(mp->mextra[0])))
diff --git a/hack/def.eshk.h b/hack/def.eshk.h
new file mode 100644
index 00000000..2ebf2804
--- /dev/null
+++ b/hack/def.eshk.h
@@ -0,0 +1,24 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.eshk.h - version 1.0.2 : added 'following' */
+
+#define BILLSZ 200
+struct bill_x {
+ unsigned bo_id;
+ unsigned useup:1;
+ unsigned bquan:7;
+ unsigned price; /* price per unit */
+};
+
+struct eshk {
+ long int robbed; /* amount stolen by most recent customer */
+ boolean following; /* following customer since he owes us sth */
+ schar shoproom; /* index in rooms; set by inshop() */
+ coord shk; /* usual position shopkeeper */
+ coord shd; /* position shop door */
+ int shoplevel; /* level of his shop */
+ int billct;
+ struct bill_x bill[BILLSZ];
+ int visitct; /* nr of visits by most recent customer */
+ char customer[PL_NSIZ]; /* most recent customer */
+ char shknam[PL_NSIZ];
+};
diff --git a/hack/def.flag.h b/hack/def.flag.h
new file mode 100644
index 00000000..221f33dd
--- /dev/null
+++ b/hack/def.flag.h
@@ -0,0 +1,42 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.flag.h - version 1.0.3 */
+
+struct flag {
+ unsigned ident; /* social security number for each monster */
+ unsigned debug:1; /* in debugging mode */
+#define wizard flags.debug
+ unsigned toplin:2; /* a top line (message) has been printed */
+ /* 0: top line empty; 2: no --More-- reqd. */
+ unsigned cbreak:1; /* in cbreak mode, rogue format */
+ unsigned standout:1; /* use standout for --More-- */
+ unsigned nonull:1; /* avoid sending nulls to the terminal */
+ unsigned time:1; /* display elapsed 'time' */
+ unsigned nonews:1; /* suppress news printing */
+ unsigned notombstone:1;
+ unsigned end_top, end_around; /* describe desired score list */
+ unsigned end_own:1; /* idem (list all own scores) */
+ unsigned no_rest_on_space:1; /* spaces are ignored */
+ unsigned beginner:1;
+ unsigned female:1;
+ unsigned invlet_constant:1; /* let objects keep their
+ inventory symbol */
+ unsigned move:1;
+ unsigned mv:1;
+ unsigned run:3; /* 0: h (etc), 1: H (etc), 2: fh (etc) */
+ /* 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF- */
+ unsigned nopick:1; /* do not pickup objects */
+ unsigned echo:1; /* 1 to echo characters */
+ unsigned botl:1; /* partially redo status line */
+ unsigned botlx:1; /* print an entirely new bottom line */
+ unsigned nscrinh:1; /* inhibit nscr() in pline(); */
+ unsigned made_amulet:1;
+ unsigned no_of_wizards:2;/* 0, 1 or 2 (wizard and his shadow) */
+ /* reset from 2 to 1, but never to 0 */
+ unsigned moonphase:3;
+#define NEW_MOON 0
+#define FULL_MOON 4
+
+};
+
+extern struct flag flags;
+
diff --git a/hack/def.func_tab.h b/hack/def.func_tab.h
new file mode 100644
index 00000000..63f74d2e
--- /dev/null
+++ b/hack/def.func_tab.h
@@ -0,0 +1,16 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.func_tab.h - version 1.0.2 */
+
+struct func_tab {
+ char f_char;
+ int (*f_funct)();
+};
+
+extern struct func_tab cmdlist[];
+
+struct ext_func_tab {
+ char *ef_txt;
+ int (*ef_funct)();
+};
+
+extern struct ext_func_tab extcmdlist[];
diff --git a/hack/def.gen.h b/hack/def.gen.h
new file mode 100644
index 00000000..f1e44fc9
--- /dev/null
+++ b/hack/def.gen.h
@@ -0,0 +1,15 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.gen.h version 1.0.1: added ONCE flag */
+
+struct gen {
+ struct gen *ngen;
+ xchar gx,gy;
+ unsigned gflag; /* 037: trap type; 040: SEEN flag */
+ /* 0100: ONCE only */
+#define TRAPTYPE 037
+#define SEEN 040
+#define ONCE 0100
+};
+extern struct gen *fgold, *ftrap;
+struct gen *g_at();
+#define newgen() (struct gen *) alloc(sizeof(struct gen))
diff --git a/hack/def.gold.h b/hack/def.gold.h
new file mode 100644
index 00000000..80889088
--- /dev/null
+++ b/hack/def.gold.h
@@ -0,0 +1,12 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.gold.h - version 1.0.2 */
+
+struct gold {
+ struct gold *ngold;
+ xchar gx,gy;
+ long amount;
+};
+
+extern struct gold *fgold;
+struct gold *g_at();
+#define newgold() (struct gold *) alloc(sizeof(struct gold))
diff --git a/hack/def.mkroom.h b/hack/def.mkroom.h
new file mode 100644
index 00000000..ddbb62be
--- /dev/null
+++ b/hack/def.mkroom.h
@@ -0,0 +1,26 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.mkroom.h - version 1.0.3 */
+
+struct mkroom {
+ schar lx,hx,ly,hy; /* usually xchar, but hx may be -1 */
+ schar rtype,rlit,doorct,fdoor;
+};
+
+#define MAXNROFROOMS 15
+extern struct mkroom rooms[MAXNROFROOMS+1];
+
+#define DOORMAX 100
+extern coord doors[DOORMAX];
+
+/* various values of rtype */
+/* 0: ordinary room; 8-15: various shops */
+/* Note: some code assumes that >= 8 means shop, so be careful when adding
+ new roomtypes */
+#define SWAMP 3
+#define VAULT 4
+#define BEEHIVE 5
+#define MORGUE 6
+#define ZOO 7
+#define SHOPBASE 8
+#define WANDSHOP 9
+#define GENERAL 15
diff --git a/hack/def.monst.h b/hack/def.monst.h
new file mode 100644
index 00000000..88836af7
--- /dev/null
+++ b/hack/def.monst.h
@@ -0,0 +1,60 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.monst.h - version 1.0.2 */
+
+struct monst {
+ struct monst *nmon;
+ struct permonst *data;
+ unsigned m_id;
+ xchar mx,my;
+ xchar mdx,mdy; /* if mdispl then pos where last displayed */
+#define MTSZ 4
+ coord mtrack[MTSZ]; /* monster track */
+ schar mhp,mhpmax;
+ char mappearance; /* nonzero for undetected 'M's and for '1's */
+ Bitfield(mimic,1); /* undetected mimic */
+ Bitfield(mdispl,1); /* mdx,mdy valid */
+ Bitfield(minvis,1); /* invisible */
+ Bitfield(cham,1); /* shape-changer */
+ Bitfield(mhide,1); /* hides beneath objects */
+ Bitfield(mundetected,1); /* not seen in present hiding place */
+ Bitfield(mspeed,2);
+ Bitfield(msleep,1);
+ Bitfield(mfroz,1);
+ Bitfield(mconf,1);
+ Bitfield(mflee,1); /* fleeing */
+ Bitfield(mfleetim,7); /* timeout for mflee */
+ Bitfield(mcan,1); /* has been cancelled */
+ Bitfield(mtame,1); /* implies peaceful */
+ Bitfield(mpeaceful,1); /* does not attack unprovoked */
+ Bitfield(isshk,1); /* is shopkeeper */
+ Bitfield(isgd,1); /* is guard */
+ Bitfield(mcansee,1); /* cansee 1, temp.blinded 0, blind 0 */
+ Bitfield(mblinded,7); /* cansee 0, temp.blinded n, blind 0 */
+ Bitfield(mtrapped,1); /* trapped in a pit or bear trap */
+ Bitfield(mnamelth,6); /* length of name (following mxlth) */
+#ifndef NOWORM
+ Bitfield(wormno,5); /* at most 31 worms on any level */
+#endif NOWORM
+ unsigned mtrapseen; /* bitmap of traps we've been trapped in */
+ long mlstmv; /* prevent two moves at once */
+ struct obj *minvent;
+ long mgold;
+ unsigned mxlth; /* length of following data */
+ /* in order to prevent alignment problems mextra should
+ be (or follow) a long int */
+ long mextra[1]; /* monster dependent info */
+};
+
+#define newmonst(xl) (struct monst *) alloc((unsigned)(xl) + sizeof(struct monst))
+
+extern struct monst *fmon;
+extern struct monst *fallen_down;
+struct monst *m_at();
+
+/* these are in mspeed */
+#define MSLOW 1 /* slow monster */
+#define MFAST 2 /* speeded monster */
+
+#define NAME(mtmp) (((char *) mtmp->mextra) + mtmp->mxlth)
+#define MREGEN "TVi1"
+#define UNDEAD "ZVW "
diff --git a/hack/def.obj.h b/hack/def.obj.h
new file mode 100644
index 00000000..50b21df1
--- /dev/null
+++ b/hack/def.obj.h
@@ -0,0 +1,48 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.obj.h - version 1.0.3 */
+
+struct obj {
+ struct obj *nobj;
+ unsigned o_id;
+ unsigned o_cnt_id; /* id of container object is in */
+ xchar ox,oy;
+ xchar odx,ody;
+ uchar otyp;
+ uchar owt;
+ uchar quan; /* use oextra for tmp gold objects */
+ schar spe; /* quality of weapon, armor or ring (+ or -)
+ number of charges for wand ( >= -1 )
+ special for uball and amulet %% BAH */
+ char olet;
+ char invlet;
+ Bitfield(oinvis,1); /* not yet implemented */
+ Bitfield(odispl,1);
+ Bitfield(known,1); /* exact nature known */
+ Bitfield(dknown,1); /* color or text known */
+ Bitfield(cursed,1);
+ Bitfield(unpaid,1); /* on some bill */
+ Bitfield(rustfree,1);
+ Bitfield(onamelth,6);
+ long age; /* creation date */
+ long owornmask;
+#define W_ARM 01L
+#define W_ARM2 02L
+#define W_ARMH 04L
+#define W_ARMS 010L
+#define W_ARMG 020L
+#define W_ARMOR (W_ARM | W_ARM2 | W_ARMH | W_ARMS | W_ARMG)
+#define W_RINGL 010000L /* make W_RINGL = RING_LEFT (see uprop) */
+#define W_RINGR 020000L
+#define W_RING (W_RINGL | W_RINGR)
+#define W_WEP 01000L
+#define W_BALL 02000L
+#define W_CHAIN 04000L
+ long oextra[1]; /* used for name of ordinary objects - length
+ is flexible; amount for tmp gold objects */
+};
+
+extern struct obj *fobj;
+
+#define newobj(xl) (struct obj *) alloc((unsigned)(xl) + sizeof(struct obj))
+#define ONAME(otmp) ((char *) otmp->oextra)
+#define OGOLD(otmp) (otmp->oextra[0])
diff --git a/hack/def.objclass.h b/hack/def.objclass.h
new file mode 100644
index 00000000..9e17de23
--- /dev/null
+++ b/hack/def.objclass.h
@@ -0,0 +1,60 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.objclass.h - version 1.0.3 */
+
+/* definition of a class of objects */
+
+struct objclass {
+ char *oc_name; /* actual name */
+ char *oc_descr; /* description when name unknown */
+ char *oc_uname; /* called by user */
+ Bitfield(oc_name_known,1);
+ Bitfield(oc_merge,1); /* merge otherwise equal objects */
+ char oc_olet;
+ schar oc_prob; /* probability for mkobj() */
+ schar oc_delay; /* delay when using such an object */
+ uchar oc_weight;
+ schar oc_oc1, oc_oc2;
+ int oc_oi;
+#define nutrition oc_oi /* for foods */
+#define a_ac oc_oc1 /* for armors - only used in ARM_BONUS */
+#define ARM_BONUS(obj) ((10 - objects[obj->otyp].a_ac) + obj->spe)
+#define a_can oc_oc2 /* for armors */
+#define bits oc_oc1 /* for wands and rings */
+ /* wands */
+#define NODIR 1
+#define IMMEDIATE 2
+#define RAY 4
+ /* rings */
+#define SPEC 1 /* +n is meaningful */
+#define wldam oc_oc1 /* for weapons and PICK_AXE */
+#define wsdam oc_oc2 /* for weapons and PICK_AXE */
+#define g_val oc_oi /* for gems: value on exit */
+};
+
+extern struct objclass objects[];
+
+/* definitions of all object-symbols */
+
+#define ILLOBJ_SYM '\\'
+#define AMULET_SYM '"'
+#define FOOD_SYM '%'
+#define WEAPON_SYM ')'
+#define TOOL_SYM '('
+#define BALL_SYM '0'
+#define CHAIN_SYM '_'
+#define ROCK_SYM '`'
+#define ARMOR_SYM '['
+#define POTION_SYM '!'
+#define SCROLL_SYM '?'
+#define WAND_SYM '/'
+#define RING_SYM '='
+#define GEM_SYM '*'
+/* Other places with explicit knowledge of object symbols:
+ * ....shk.c: char shtypes[] = "=/)%?![";
+ * mklev.c: "=/)%?![<>"
+ * hack.mkobj.c: char mkobjstr[] = "))[[!!!!????%%%%/=**";
+ * hack.apply.c: otmp = getobj("0#%", "put in");
+ * hack.eat.c: otmp = getobj("%", "eat");
+ * hack.invent.c: if(index("!%?[)=*(0/\"", sym)){
+ * hack.invent.c: || index("%?!*",otmp->olet))){
+ */
diff --git a/hack/def.objects.h b/hack/def.objects.h
new file mode 100644
index 00000000..b4400fc4
--- /dev/null
+++ b/hack/def.objects.h
@@ -0,0 +1,289 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.objects.h - version 1.0.3 */
+
+/* objects have letter " % ) ( 0 _ ` [ ! ? / = * */
+#include "config.h"
+#include "def.objclass.h"
+#define NULL (char *)0
+
+struct objclass objects[] = {
+
+ { "strange object", NULL, NULL, 1, 0,
+ ILLOBJ_SYM, 0, 0, 0, 0, 0, 0 },
+ { "amulet of Yendor", NULL, NULL, 1, 0,
+ AMULET_SYM, 100, 0, 2, 0, 0, 0 },
+
+#define FOOD(name,prob,delay,weight,nutrition) { name, NULL, NULL, 1, 1,\
+ FOOD_SYM, prob, delay, weight, 0, 0, nutrition }
+
+/* dog eats foods 0-4 but prefers 1 above 0,2,3,4 */
+/* food 4 can be read */
+/* food 5 improves your vision */
+/* food 6 makes you stronger (like Popeye) */
+/* foods CORPSE up to CORPSE+52 are cadavers */
+
+ FOOD("food ration", 50, 5, 4, 800),
+ FOOD("tripe ration", 20, 1, 2, 200),
+ FOOD("pancake", 3, 1, 1, 200),
+ FOOD("dead lizard", 3, 0, 1, 40),
+ FOOD("fortune cookie", 7, 0, 1, 40),
+ FOOD("carrot", 2, 0, 1, 50),
+ FOOD("tin", 7, 0, 1, 0),
+ FOOD("orange", 1, 0, 1, 80),
+ FOOD("apple", 1, 0, 1, 50),
+ FOOD("pear", 1, 0, 1, 50),
+ FOOD("melon", 1, 0, 1, 100),
+ FOOD("banana", 1, 0, 1, 80),
+ FOOD("candy bar", 1, 0, 1, 100),
+ FOOD("egg", 1, 0, 1, 80),
+ FOOD("clove of garlic", 1, 0, 1, 40),
+ FOOD("lump of royal jelly", 0, 0, 1, 200),
+
+ FOOD("dead human", 0, 4, 40, 400),
+ FOOD("dead giant ant", 0, 1, 3, 30),
+ FOOD("dead giant bat", 0, 1, 3, 30),
+ FOOD("dead centaur", 0, 5, 50, 500),
+ FOOD("dead dragon", 0, 15, 150, 1500),
+ FOOD("dead floating eye", 0, 1, 1, 10),
+ FOOD("dead freezing sphere", 0, 1, 1, 10),
+ FOOD("dead gnome", 0, 1, 10, 100),
+ FOOD("dead hobgoblin", 0, 2, 20, 200),
+ FOOD("dead stalker", 0, 4, 40, 400),
+ FOOD("dead jackal", 0, 1, 10, 100),
+ FOOD("dead kobold", 0, 1, 10, 100),
+ FOOD("dead leprechaun", 0, 4, 40, 400),
+ FOOD("dead mimic", 0, 4, 40, 400),
+ FOOD("dead nymph", 0, 4, 40, 400),
+ FOOD("dead orc", 0, 2, 20, 200),
+ FOOD("dead purple worm", 0, 7, 70, 700),
+ FOOD("dead quasit", 0, 2, 20, 200),
+ FOOD("dead rust monster", 0, 5, 50, 500),
+ FOOD("dead snake", 0, 1, 10, 100),
+ FOOD("dead troll", 0, 4, 40, 400),
+ FOOD("dead umber hulk", 0, 5, 50, 500),
+ FOOD("dead vampire", 0, 4, 40, 400),
+ FOOD("dead wraith", 0, 1, 1, 10),
+ FOOD("dead xorn", 0, 7, 70, 700),
+ FOOD("dead yeti", 0, 7, 70, 700),
+ FOOD("dead zombie", 0, 1, 3, 30),
+ FOOD("dead acid blob", 0, 1, 3, 30),
+ FOOD("dead giant beetle", 0, 1, 1, 10),
+ FOOD("dead cockatrice", 0, 1, 3, 30),
+ FOOD("dead dog", 0, 2, 20, 200),
+ FOOD("dead ettin", 0, 1, 3, 30),
+ FOOD("dead fog cloud", 0, 1, 1, 10),
+ FOOD("dead gelatinous cube", 0, 1, 10, 100),
+ FOOD("dead homunculus", 0, 2, 20, 200),
+ FOOD("dead imp", 0, 1, 1, 10),
+ FOOD("dead jaguar", 0, 3, 30, 300),
+ FOOD("dead killer bee", 0, 1, 1, 10),
+ FOOD("dead leocrotta", 0, 5, 50, 500),
+ FOOD("dead minotaur", 0, 7, 70, 700),
+ FOOD("dead nurse", 0, 4, 40, 400),
+ FOOD("dead owlbear", 0, 7, 70, 700),
+ FOOD("dead piercer", 0, 2, 20, 200),
+ FOOD("dead quivering blob", 0, 1, 10, 100),
+ FOOD("dead giant rat", 0, 1, 3, 30),
+ FOOD("dead giant scorpion", 0, 1, 10, 100),
+ FOOD("dead tengu", 0, 3, 30, 300),
+ FOOD("dead unicorn", 0, 3, 30, 300),
+ FOOD("dead violet fungi", 0, 1, 10, 100),
+ FOOD("dead long worm", 0, 5, 50, 500),
+/* %% wt of long worm should be proportional to its length */
+ FOOD("dead xan", 0, 3, 30, 300),
+ FOOD("dead yellow light", 0, 1, 1, 10),
+ FOOD("dead zruty", 0, 6, 60, 600),
+
+/* weapons ... - ROCK come several at a time */
+/* weapons ... - (ROCK-1) are shot using idem+(BOW-ARROW) */
+/* weapons AXE, SWORD, THSWORD are good for worm-cutting */
+/* weapons (PICK-)AXE, DAGGER, CRYSKNIFE are good for tin-opening */
+#define WEAPON(name,prob,wt,ldam,sdam) { name, NULL, NULL, 1, 0 /*%%*/,\
+ WEAPON_SYM, prob, 0, wt, ldam, sdam, 0 }
+
+ WEAPON("arrow", 7, 0, 6, 6),
+ WEAPON("sling bullet", 7, 0, 4, 6),
+ WEAPON("crossbow bolt", 7, 0, 4, 6),
+ WEAPON("dart", 7, 0, 3, 2),
+ WEAPON("rock", 6, 1, 3, 3),
+ WEAPON("boomerang", 2, 3, 9, 9),
+ WEAPON("mace", 9, 3, 6, 7),
+ WEAPON("axe", 6, 3, 6, 4),
+ WEAPON("flail", 6, 3, 6, 5),
+ WEAPON("long sword", 8, 3, 8, 12),
+ WEAPON("two handed sword", 6, 4, 12, 6),
+ WEAPON("dagger", 6, 3, 4, 3),
+ WEAPON("worm tooth", 0, 4, 2, 2),
+ WEAPON("crysknife", 0, 3, 10, 10),
+ WEAPON("spear", 6, 3, 6, 8),
+ WEAPON("bow", 6, 3, 4, 6),
+ WEAPON("sling", 5, 3, 6, 6),
+ WEAPON("crossbow", 6, 3, 4, 6),
+
+ { "whistle", "whistle", NULL, 0, 0,
+ TOOL_SYM, 90, 0, 2, 0, 0, 0 },
+ { "magic whistle", "whistle", NULL, 0, 0,
+ TOOL_SYM, 10, 0, 2, 0, 0, 0 },
+ { "expensive camera", NULL, NULL, 1, 1,
+ TOOL_SYM, 0, 0, 3, 0, 0, 0 },
+ { "ice box", "large box", NULL, 0, 0,
+ TOOL_SYM, 0, 0, 40, 0, 0, 0 },
+ { "pick-axe", NULL, NULL, 1, 1,
+ TOOL_SYM, 0, 0, 5, 6, 3, 0 },
+ { "can opener", NULL, NULL, 1, 1,
+ TOOL_SYM, 0, 0, 1, 0, 0, 0 },
+ { "heavy iron ball", NULL, NULL, 1, 0,
+ BALL_SYM, 100, 0, 20, 0, 0, 0 },
+ { "iron chain", NULL, NULL, 1, 0,
+ CHAIN_SYM, 100, 0, 20, 0, 0, 0 },
+ { "enormous rock", NULL, NULL, 1, 0,
+ ROCK_SYM, 100, 0, 200 /* > MAX_CARR_CAP */, 0, 0, 0 },
+
+#define ARMOR(name,prob,delay,ac,can) { name, NULL, NULL, 1, 0,\
+ ARMOR_SYM, prob, delay, 8, ac, can, 0 }
+ ARMOR("helmet", 3, 1, 9, 0),
+ ARMOR("plate mail", 5, 5, 3, 2),
+ ARMOR("splint mail", 8, 5, 4, 1),
+ ARMOR("banded mail", 10, 5, 4, 0),
+ ARMOR("chain mail", 10, 5, 5, 1),
+ ARMOR("scale mail", 10, 5, 6, 0),
+ ARMOR("ring mail", 15, 5, 7, 0),
+ /* the armors below do not rust */
+ ARMOR("studded leather armor", 13, 3, 7, 1),
+ ARMOR("leather armor", 17, 3, 8, 0),
+ ARMOR("elven cloak", 5, 0, 9, 3),
+ ARMOR("shield", 3, 0, 9, 0),
+ ARMOR("pair of gloves", 1, 1, 9, 0),
+
+#define POTION(name,color) { name, color, NULL, 0, 1,\
+ POTION_SYM, 0, 0, 2, 0, 0, 0 }
+
+ POTION("restore strength", "orange"),
+ POTION("booze", "bubbly"),
+ POTION("invisibility", "glowing"),
+ POTION("fruit juice", "smoky"),
+ POTION("healing", "pink"),
+ POTION("paralysis", "puce"),
+ POTION("monster detection", "purple"),
+ POTION("object detection", "yellow"),
+ POTION("sickness", "white"),
+ POTION("confusion", "swirly"),
+ POTION("gain strength", "purple-red"),
+ POTION("speed", "ruby"),
+ POTION("blindness", "dark green"),
+ POTION("gain level", "emerald"),
+ POTION("extra healing", "sky blue"),
+ POTION("levitation", "brown"),
+ POTION(NULL, "brilliant blue"),
+ POTION(NULL, "clear"),
+ POTION(NULL, "magenta"),
+ POTION(NULL, "ebony"),
+
+#define SCROLL(name,text,prob) { name, text, NULL, 0, 1,\
+ SCROLL_SYM, prob, 0, 3, 0, 0, 0 }
+ SCROLL("mail", "KIRJE", 0),
+ SCROLL("enchant armor", "ZELGO MER", 6),
+ SCROLL("destroy armor", "JUYED AWK YACC", 5),
+ SCROLL("confuse monster", "NR 9", 5),
+ SCROLL("scare monster", "XIXAXA XOXAXA XUXAXA", 4),
+ SCROLL("blank paper", "READ ME", 3),
+ SCROLL("remove curse", "PRATYAVAYAH", 6),
+ SCROLL("enchant weapon", "DAIYEN FOOELS", 6),
+ SCROLL("damage weapon", "HACKEM MUCHE", 5),
+ SCROLL("create monster", "LEP GEX VEN ZEA", 5),
+ SCROLL("taming", "PRIRUTSENIE", 1),
+ SCROLL("genocide", "ELBIB YLOH",2),
+ SCROLL("light", "VERR YED HORRE", 10),
+ SCROLL("teleportation", "VENZAR BORGAVVE", 5),
+ SCROLL("gold detection", "THARR", 4),
+ SCROLL("food detection", "YUM YUM", 1),
+ SCROLL("identify", "KERNOD WEL", 18),
+ SCROLL("magic mapping", "ELAM EBOW", 5),
+ SCROLL("amnesia", "DUAM XNAHT", 3),
+ SCROLL("fire", "ANDOVA BEGARIN", 5),
+ SCROLL("punishment", "VE FORBRYDERNE", 1),
+ SCROLL(NULL, "VELOX NEB", 0),
+ SCROLL(NULL, "FOOBIE BLETCH", 0),
+ SCROLL(NULL, "TEMOV", 0),
+ SCROLL(NULL, "GARVEN DEH", 0),
+
+#define WAND(name,metal,prob,flags) { name, metal, NULL, 0, 0,\
+ WAND_SYM, prob, 0, 3, flags, 0, 0 }
+
+ WAND("light", "iridium", 10, NODIR),
+ WAND("secret door detection", "tin", 5, NODIR),
+ WAND("create monster", "platinum", 5, NODIR),
+ WAND("wishing", "glass", 1, NODIR),
+ WAND("striking", "zinc", 9, IMMEDIATE),
+ WAND("slow monster", "balsa", 5, IMMEDIATE),
+ WAND("speed monster", "copper", 5, IMMEDIATE),
+ WAND("undead turning", "silver", 5, IMMEDIATE),
+ WAND("polymorph", "brass", 5, IMMEDIATE),
+ WAND("cancellation", "maple", 5, IMMEDIATE),
+ WAND("teleportation", "pine", 5, IMMEDIATE),
+ WAND("make invisible", "marble", 9, IMMEDIATE),
+ WAND("digging", "iron", 5, RAY),
+ WAND("magic missile", "aluminium", 10, RAY),
+ WAND("fire", "steel", 5, RAY),
+ WAND("sleep", "curved", 5, RAY),
+ WAND("cold", "short", 5, RAY),
+ WAND("death", "long", 1, RAY),
+ WAND(NULL, "oak", 0, 0),
+ WAND(NULL, "ebony", 0, 0),
+ WAND(NULL, "runed", 0, 0),
+
+#define RING(name,stone,spec) { name, stone, NULL, 0, 0,\
+ RING_SYM, 0, 0, 1, spec, 0, 0 }
+
+ RING("adornment", "engagement", 0),
+ RING("teleportation", "wooden", 0),
+ RING("regeneration", "black onyx", 0),
+ RING("searching", "topaz", 0),
+ RING("see invisible", "pearl", 0),
+ RING("stealth", "sapphire", 0),
+ RING("levitation", "moonstone", 0),
+ RING("poison resistance", "agate", 0),
+ RING("aggravate monster", "tiger eye", 0),
+ RING("hunger", "shining", 0),
+ RING("fire resistance", "gold", 0),
+ RING("cold resistance", "copper", 0),
+ RING("protection from shape changers", "diamond", 0),
+ RING("conflict", "jade", 0),
+ RING("gain strength", "ruby", SPEC),
+ RING("increase damage", "silver", SPEC),
+ RING("protection", "granite", SPEC),
+ RING("warning", "wire", 0),
+ RING("teleport control", "iron", 0),
+ RING(NULL, "ivory", 0),
+ RING(NULL, "blackened", 0),
+
+/* gems ************************************************************/
+#define GEM(name,color,prob,gval) { name, color, NULL, 0, 1,\
+ GEM_SYM, prob, 0, 1, 0, 0, gval }
+ GEM("diamond", "blue", 1, 4000),
+ GEM("ruby", "red", 1, 3500),
+ GEM("sapphire", "blue", 1, 3000),
+ GEM("emerald", "green", 1, 2500),
+ GEM("turquoise", "green", 1, 2000),
+ GEM("aquamarine", "blue", 1, 1500),
+ GEM("tourmaline", "green", 1, 1000),
+ GEM("topaz", "yellow", 1, 900),
+ GEM("opal", "yellow", 1, 800),
+ GEM("garnet", "dark", 1, 700),
+ GEM("amethyst", "violet", 2, 650),
+ GEM("agate", "green", 2, 600),
+ GEM("onyx", "white", 2, 550),
+ GEM("jasper", "yellowish brown", 2, 500),
+ GEM("jade", "green", 2, 450),
+ GEM("worthless piece of blue glass", "blue", 20, 0),
+ GEM("worthless piece of red glass", "red", 20, 0),
+ GEM("worthless piece of yellow glass", "yellow", 20, 0),
+ GEM("worthless piece of green glass", "green", 20, 0),
+ { NULL, NULL, NULL, 0, 0, ILLOBJ_SYM, 0, 0, 0, 0, 0, 0 }
+};
+
+char obj_symbols[] = {
+ ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM,
+ BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM,
+ WAND_SYM, RING_SYM, GEM_SYM, 0 };
+int bases[sizeof(obj_symbols)];
diff --git a/hack/def.permonst.h b/hack/def.permonst.h
new file mode 100644
index 00000000..b19efc6a
--- /dev/null
+++ b/hack/def.permonst.h
@@ -0,0 +1,25 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.permonst.h - version 1.0.2 */
+
+struct permonst {
+ char *mname,mlet;
+ schar mlevel,mmove,ac,damn,damd;
+ unsigned pxlth;
+};
+
+extern struct permonst mons[];
+#define PM_ACID_BLOB &mons[7]
+#define PM_ZOMBIE &mons[13]
+#define PM_PIERCER &mons[17]
+#define PM_KILLER_BEE &mons[26]
+#define PM_WRAITH &mons[33]
+#define PM_MIMIC &mons[37]
+#define PM_VAMPIRE &mons[43]
+#define PM_CHAMELEON &mons[47]
+#define PM_DEMON &mons[54]
+#define PM_MINOTAUR &mons[55] /* last in mons array */
+#define PM_SHK &mons[56] /* very last */
+#define PM_GHOST &pm_ghost
+#define PM_EEL &pm_eel
+#define PM_WIZARD &pm_wizard
+#define CMNUM 55 /* number of common monsters */
diff --git a/hack/def.rm.h b/hack/def.rm.h
new file mode 100644
index 00000000..f84921ca
--- /dev/null
+++ b/hack/def.rm.h
@@ -0,0 +1,52 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.rm.h - version 1.0.2 */
+
+/* Level location types */
+#define HWALL 1
+#define VWALL 2
+#define SDOOR 3
+#define SCORR 4
+#define LDOOR 5
+#define POOL 6 /* not yet fully implemented */
+ /* this should in fact be a bit like lit */
+#define DOOR 7
+#define CORR 8
+#define ROOM 9
+#define STAIRS 10
+
+/*
+ * Avoid using the level types in inequalities:
+ * these types are subject to change.
+ * Instead, use one of the macros below.
+ */
+#define IS_WALL(typ) ((typ) <= VWALL)
+#define IS_ROCK(typ) ((typ) < POOL) /* absolutely nonaccessible */
+#define ACCESSIBLE(typ) ((typ) >= DOOR) /* good position */
+#define IS_ROOM(typ) ((typ) >= ROOM) /* ROOM or STAIRS */
+#define ZAP_POS(typ) ((typ) > DOOR)
+
+/*
+ * A few of the associated symbols are not hardwired.
+ */
+#ifdef QUEST
+#define CORR_SYM ':'
+#else
+#define CORR_SYM '#'
+#endif QUEST
+#define POOL_SYM '}'
+
+#define ERRCHAR '{'
+
+/*
+ * The structure describing a coordinate position.
+ * Before adding fields, remember that this will significantly affect
+ * the size of temporary files and save files.
+ */
+struct rm {
+ char scrsym;
+ unsigned typ:5;
+ unsigned new:1;
+ unsigned seen:1;
+ unsigned lit:1;
+};
+extern struct rm levl[COLNO][ROWNO];
diff --git a/hack/def.trap.h b/hack/def.trap.h
new file mode 100644
index 00000000..26946add
--- /dev/null
+++ b/hack/def.trap.h
@@ -0,0 +1,27 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.trap.h - version 1.0.2 */
+
+struct trap {
+ struct trap *ntrap;
+ xchar tx,ty;
+ unsigned ttyp:5;
+ unsigned tseen:1;
+ unsigned once:1;
+};
+
+extern struct trap *ftrap;
+struct trap *t_at();
+#define newtrap() (struct trap *) alloc(sizeof(struct trap))
+
+/* various kinds of traps */
+#define BEAR_TRAP 0
+#define ARROW_TRAP 1
+#define DART_TRAP 2
+#define TRAPDOOR 3
+#define TELEP_TRAP 4
+#define PIT 5
+#define SLP_GAS_TRAP 6
+#define PIERC 7
+#define MIMIC 8 /* used only in mklev.c */
+#define TRAPNUM 9 /* if not less than 32, change sizeof(ttyp) */
+ /* see also mtrapseen (bit map) */
diff --git a/hack/def.wseg.h b/hack/def.wseg.h
new file mode 100644
index 00000000..0a2af779
--- /dev/null
+++ b/hack/def.wseg.h
@@ -0,0 +1,13 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* def.wseg.h - version 1.0.2 */
+
+#ifndef NOWORM
+/* worm structure */
+struct wseg {
+ struct wseg *nseg;
+ xchar wx,wy;
+ unsigned wdispl:1;
+};
+
+#define newseg() (struct wseg *) alloc(sizeof(struct wseg))
+#endif NOWORM
diff --git a/hack/hack.6 b/hack/hack.6
new file mode 100644
index 00000000..c4c46c30
--- /dev/null
+++ b/hack/hack.6
@@ -0,0 +1,155 @@
+.TH HACK 6 "31 March 1985"
+.UC 4
+.SH NAME
+hack \- Exploring The Dungeons of Doom
+.SH SYNOPSIS
+.B /usr/games/hack
+[
+.B \-d
+.I directory
+]
+[
+.B \-n
+]
+[
+.B \-u
+.I playername
+]
+.br
+.B /usr/games/hack
+[
+.B \-d
+.I directory
+]
+.B \-s
+[
+.B \-X
+]
+[
+.I playernames
+]
+.SH DESCRIPTION
+.PP
+.I Hack
+is a display oriented dungeons & dragons - like game.
+Both display and command structure resemble rogue.
+(For a game with the same structure but entirely different display -
+a real cave instead of dull rectangles - try Quest.)
+.PP
+To get started you really only need to know two commands. The command
+.B ?
+will give you a list of the available commands and the command
+.B /
+will identify the things you see on the screen.
+.PP
+To win the game (as opposed to merely playing to beat other people high
+scores) you must locate the Amulet of Yendor which is somewhere below
+the 20th level of the dungeon and get it out. Nobody has achieved this
+yet and if somebody does, he will probably go down in history as a hero
+among heros.
+.PP
+When the game ends, either by your death, when you quit, or if you escape
+from the caves,
+.I hack
+will give you (a fragment of) the list of top scorers. The scoring
+is based on many aspects of your behaviour but a rough estimate is
+obtained by taking the amount of gold you've found in the cave plus four
+times your (real) experience. Precious stones may be worth a lot of gold
+when brought to the exit.
+There is a 10% penalty for getting yourself killed.
+.PP
+The administration of the game is kept in the directory specified with the
+.B \-d
+option, or, if no such option is given, in the directory specified by
+the environment variable HACKDIR, or, if no such variable exists, in
+the current directory. This same directory contains several auxiliary
+files such as lockfiles and the list of topscorers and a subdirectory
+.I save
+where games are saved.
+The game administrator may however choose to install hack with a fixed
+playing ground, usually /usr/games/lib/hackdir.
+.PP
+The
+.B \-n
+option suppresses printing of the news.
+.PP
+The
+.B \-u
+.I playername
+option supplies the answer to the question "Who are you?".
+When
+.I playername
+has as suffix one of
+.B \-T \-S \-K \-F \-C \-W
+then this supplies the answer to the question "What kind of character ... ?".
+.PP
+The
+.B \-s
+option will print out the list of your scores. It may be followed by arguments
+.B \-X
+where X is one of the letters C, F, K, S, T, W to print the scores of
+Cavemen, Fighters, Knights, Speleologists, Tourists or Wizards.
+It may also be followed by one or more player names to print the scores of the
+players mentioned.
+.SH AUTHORS
+Jay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the
+original hack, very much like rogue (but full of bugs).
+.br
+Andries Brouwer continuously deformed their sources into the current
+version - in fact an entirely different game.
+.SH FILES
+.DT
+.ta \w'data, rumors\ \ \ 'u
+hack The hack program.
+.br
+data, rumors Data files used by hack.
+.br
+help, hh Help data files.
+.br
+record The list of topscorers.
+.br
+save A subdirectory containing the saved
+.br
+ games.
+.br
+bones_dd Descriptions of the ghost and
+.br
+ belongings of a deceased adventurer.
+.br
+xlock.dd Description of a dungeon level.
+.br
+safelock Lock file for xlock.
+.br
+record_lock Lock file for record.
+.SH ENVIRONMENT
+.DT
+.ta \w'HACKPAGER, PAGER\ \ \ 'u
+USER or LOGNAME Your login name.
+.br
+HOME Your home directory.
+.br
+SHELL Your shell.
+.br
+TERM The type of your terminal.
+.br
+HACKPAGER, PAGER Pager used instead of default pager.
+.br
+MAIL Mailbox file.
+.br
+MAILREADER Reader used instead of default
+.br
+ (probably /bin/mail or /usr/ucb/mail).
+.br
+HACKDIR Playground.
+.br
+HACKOPTIONS String predefining several hack options
+.br
+ (see help file).
+.br
+
+Several other environment variables are used in debugging (wizard) mode,
+like GENOCIDED, INVENT, MAGIC and SHOPTYPE.
+.SH BUGS
+.PP
+Probably infinite.
+Mail complaints to mcvax!aeb .
diff --git a/hack/hack.Decl.c b/hack/hack.Decl.c
new file mode 100644
index 00000000..b2855ac9
--- /dev/null
+++ b/hack/hack.Decl.c
@@ -0,0 +1,43 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.Decl.c - version 1.0.3 */
+
+#include "hack.h"
+char nul[40]; /* contains zeros */
+char plname[PL_NSIZ]; /* player name */
+char lock[PL_NSIZ+4] = "1lock"; /* long enough for login name .99 */
+
+boolean in_mklev, restoring;
+
+struct rm levl[COLNO][ROWNO]; /* level map */
+#ifndef QUEST
+#include "def.mkroom.h"
+struct mkroom rooms[MAXNROFROOMS+1];
+coord doors[DOORMAX];
+#endif QUEST
+struct monst *fmon = 0;
+struct trap *ftrap = 0;
+struct gold *fgold = 0;
+struct obj *fobj = 0, *fcobj = 0, *invent = 0, *uwep = 0, *uarm = 0,
+ *uarm2 = 0, *uarmh = 0, *uarms = 0, *uarmg = 0, *uright = 0,
+ *uleft = 0, *uchain = 0, *uball = 0;
+struct flag flags;
+struct you u;
+struct monst youmonst; /* dummy; used as return value for boomhit */
+
+xchar dlevel = 1;
+xchar xupstair, yupstair, xdnstair, ydnstair;
+char *save_cm = 0, *killer, *nomovemsg;
+
+long moves = 1;
+long wailmsg = 0;
+
+int multi = 0;
+char genocided[60];
+char fut_geno[60];
+
+xchar curx,cury;
+xchar seelx, seehx, seely, seehy; /* corners of lit room */
+
+coord bhitpos;
+
+char quitchars[] = " \r\n\033";
diff --git a/hack/hack.apply.c b/hack/hack.apply.c
new file mode 100644
index 00000000..ebdf82ad
--- /dev/null
+++ b/hack/hack.apply.c
@@ -0,0 +1,437 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.apply.c - version 1.0.3 */
+
+#include "hack.h"
+#include "def.edog.h"
+#include "def.mkroom.h"
+extern struct monst *bchit();
+extern struct obj *addinv();
+extern struct trap *maketrap();
+extern int (*occupation)();
+extern char *occtxt;
+extern char quitchars[];
+extern char pl_character[];
+
+static void use_camera(), use_ice_box(), use_whistle(), use_magic_whistle();
+static int use_pick_axe();
+
+doapply() {
+ register struct obj *obj;
+ register int res = 1;
+
+ obj = getobj("(", "use or apply");
+ if(!obj) return(0);
+
+ switch(obj->otyp){
+ case EXPENSIVE_CAMERA:
+ use_camera(obj); break;
+ case ICE_BOX:
+ use_ice_box(obj); break;
+ case PICK_AXE:
+ res = use_pick_axe(obj);
+ break;
+
+ case MAGIC_WHISTLE:
+ if(pl_character[0] == 'W' || u.ulevel > 9) {
+ use_magic_whistle(obj);
+ break;
+ }
+ /* fall into next case */
+ case WHISTLE:
+ use_whistle(obj);
+ break;
+
+ case CAN_OPENER:
+ if(!carrying(TIN)) {
+ pline("You have no can to open.");
+ goto xit;
+ }
+ pline("You cannot open a tin without eating its contents.");
+ pline("In order to eat, use the 'e' command.");
+ if(obj != uwep)
+ pline("Opening the tin will be much easier if you wield the can-opener.");
+ goto xit;
+
+ default:
+ pline("Sorry, I don't know how to use that.");
+ xit:
+ nomul(0);
+ return(0);
+ }
+ nomul(0);
+ return(res);
+}
+
+/* ARGSUSED */
+static void
+use_camera(obj) /* register */ struct obj *obj; {
+register struct monst *mtmp;
+ if(!getdir(1)){ /* ask: in what direction? */
+ flags.move = multi = 0;
+ return;
+ }
+ if(u.uswallow) {
+ pline("You take a picture of %s's stomach.", monnam(u.ustuck));
+ return;
+ }
+ if(u.dz) {
+ pline("You take a picture of the %s.",
+ (u.dz > 0) ? "floor" : "ceiling");
+ return;
+ }
+ if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) {
+ if(mtmp->msleep){
+ mtmp->msleep = 0;
+ pline("The flash awakens %s.", monnam(mtmp)); /* a3 */
+ } else
+ if(mtmp->data->mlet != 'y')
+ if(mtmp->mcansee || mtmp->mblinded){
+ register int tmp = dist(mtmp->mx,mtmp->my);
+ register int tmp2;
+ if(cansee(mtmp->mx,mtmp->my))
+ pline("%s is blinded by the flash!", Monnam(mtmp));
+ setmangry(mtmp);
+ if(tmp < 9 && !mtmp->isshk && rn2(4)) {
+ mtmp->mflee = 1;
+ if(rn2(4)) mtmp->mfleetim = rnd(100);
+ }
+ if(tmp < 3) mtmp->mcansee = mtmp->mblinded = 0;
+ else {
+ tmp2 = mtmp->mblinded;
+ tmp2 += rnd(1 + 50/tmp);
+ if(tmp2 > 127) tmp2 = 127;
+ mtmp->mblinded = tmp2;
+ mtmp->mcansee = 0;
+ }
+ }
+ }
+}
+
+static
+struct obj *current_ice_box; /* a local variable of use_ice_box, to be
+ used by its local procedures in/ck_ice_box */
+static
+in_ice_box(obj) register struct obj *obj; {
+ if(obj == current_ice_box ||
+ (Punished && (obj == uball || obj == uchain))){
+ pline("You must be kidding.");
+ return(0);
+ }
+ if(obj->owornmask & (W_ARMOR | W_RING)) {
+ pline("You cannot refrigerate something you are wearing.");
+ return(0);
+ }
+ if(obj->owt + current_ice_box->owt > 70) {
+ pline("It won't fit.");
+ return(1); /* be careful! */
+ }
+ if(obj == uwep) {
+ if(uwep->cursed) {
+ pline("Your weapon is welded to your hand!");
+ return(0);
+ }
+ setuwep((struct obj *) 0);
+ }
+ current_ice_box->owt += obj->owt;
+ freeinv(obj);
+ obj->o_cnt_id = current_ice_box->o_id;
+ obj->nobj = fcobj;
+ fcobj = obj;
+ obj->age = moves - obj->age; /* actual age */
+ return(1);
+}
+
+static
+ck_ice_box(obj) register struct obj *obj; {
+ return(obj->o_cnt_id == current_ice_box->o_id);
+}
+
+static
+out_ice_box(obj) register struct obj *obj; {
+register struct obj *otmp;
+ if(obj == fcobj) fcobj = fcobj->nobj;
+ else {
+ for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj)
+ if(!otmp->nobj) panic("out_ice_box");
+ otmp->nobj = obj->nobj;
+ }
+ current_ice_box->owt -= obj->owt;
+ obj->age = moves - obj->age; /* simulated point of time */
+ (void) addinv(obj);
+}
+
+static void
+use_ice_box(obj) register struct obj *obj; {
+register int cnt = 0;
+register struct obj *otmp;
+ current_ice_box = obj; /* for use by in/out_ice_box */
+ for(otmp = fcobj; otmp; otmp = otmp->nobj)
+ if(otmp->o_cnt_id == obj->o_id)
+ cnt++;
+ if(!cnt) pline("Your ice-box is empty.");
+ else {
+ pline("Do you want to take something out of the ice-box? [yn] ");
+ if(readchar() == 'y')
+ if(askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0))
+ return;
+ pline("That was all. Do you wish to put something in? [yn] ");
+ if(readchar() != 'y') return;
+ }
+ /* call getobj: 0: allow cnt; #: allow all types; %: expect food */
+ otmp = getobj("0#%", "put in");
+ if(!otmp || !in_ice_box(otmp))
+ flags.move = multi = 0;
+}
+
+static
+struct monst *
+bchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; {
+ register struct monst *mtmp = (struct monst *) 0;
+ register int bchx = u.ux, bchy = u.uy;
+
+ if(sym) Tmp_at(-1, sym); /* open call */
+ while(range--) {
+ bchx += ddx;
+ bchy += ddy;
+ if(mtmp = m_at(bchx,bchy))
+ break;
+ if(!ZAP_POS(levl[bchx][bchy].typ)) {
+ bchx -= ddx;
+ bchy -= ddy;
+ break;
+ }
+ if(sym) Tmp_at(bchx, bchy);
+ }
+ if(sym) Tmp_at(-1, -1);
+ return(mtmp);
+}
+
+/* ARGSUSED */
+static void
+use_whistle(obj) struct obj *obj; {
+register struct monst *mtmp = fmon;
+ pline("You produce a high whistling sound.");
+ while(mtmp) {
+ if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
+ if(mtmp->msleep)
+ mtmp->msleep = 0;
+ if(mtmp->mtame)
+ EDOG(mtmp)->whistletime = moves;
+ }
+ mtmp = mtmp->nmon;
+ }
+}
+
+/* ARGSUSED */
+static void
+use_magic_whistle(obj) struct obj *obj; {
+register struct monst *mtmp = fmon;
+ pline("You produce a strange whistling sound.");
+ while(mtmp) {
+ if(mtmp->mtame) mnexto(mtmp);
+ mtmp = mtmp->nmon;
+ }
+}
+
+static int dig_effort; /* effort expended on current pos */
+static uchar dig_level;
+static coord dig_pos;
+static boolean dig_down;
+
+static
+dig() {
+ register struct rm *lev;
+ register dpx = dig_pos.x, dpy = dig_pos.y;
+
+ /* perhaps a nymph stole his pick-axe while he was busy digging */
+ /* or perhaps he teleported away */
+ if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
+ dig_level != dlevel ||
+ ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
+ (!dig_down && dist(dpx,dpy) > 2)))
+ return(0);
+
+ dig_effort += 10 + abon() + uwep->spe + rn2(5);
+ if(dig_down) {
+ if(!xdnstair) {
+ pline("The floor here seems too hard to dig in.");
+ return(0);
+ }
+ if(dig_effort > 250) {
+ dighole();
+ return(0); /* done with digging */
+ }
+ if(dig_effort > 50) {
+ register struct trap *ttmp = t_at(dpx,dpy);
+
+ if(!ttmp) {
+ ttmp = maketrap(dpx,dpy,PIT);
+ ttmp->tseen = 1;
+ pline("You have dug a pit.");
+ u.utrap = rn1(4,2);
+ u.utraptype = TT_PIT;
+ return(0);
+ }
+ }
+ } else
+ if(dig_effort > 100) {
+ register char *digtxt;
+ register struct obj *obj;
+
+ lev = &levl[dpx][dpy];
+ if(obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) {
+ fracture_rock(obj);
+ digtxt = "The rock falls apart.";
+ } else if(!lev->typ || lev->typ == SCORR) {
+ lev->typ = CORR;
+ digtxt = "You succeeded in cutting away some rock.";
+ } else if(lev->typ == HWALL || lev->typ == VWALL
+ || lev->typ == SDOOR) {
+ lev->typ = xdnstair ? DOOR : ROOM;
+ digtxt = "You just made an opening in the wall.";
+ } else
+ digtxt = "Now what exactly was it that you were digging in?";
+ mnewsym(dpx, dpy);
+ prl(dpx, dpy);
+ pline(digtxt); /* after mnewsym & prl */
+ return(0);
+ } else {
+ if(IS_WALL(levl[dpx][dpy].typ)) {
+ register int rno = inroom(dpx,dpy);
+
+ if(rno >= 0 && rooms[rno].rtype >= 8) {
+ pline("This wall seems too hard to dig into.");
+ return(0);
+ }
+ }
+ pline("You hit the rock with all your might.");
+ }
+ return(1);
+}
+
+/* When will hole be finished? Very rough indication used by shopkeeper. */
+holetime() {
+ return( (occupation == dig) ? (250 - dig_effort)/20 : -1);
+}
+
+dighole()
+{
+ register struct trap *ttmp = t_at(u.ux, u.uy);
+
+ if(!xdnstair) {
+ pline("The floor here seems too hard to dig in.");
+ } else {
+ if(ttmp)
+ ttmp->ttyp = TRAPDOOR;
+ else
+ ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
+ ttmp->tseen = 1;
+ pline("You've made a hole in the floor.");
+ if(!u.ustuck) {
+ if(inshop())
+ shopdig(1);
+ pline("You fall through ...");
+ if(u.utraptype == TT_PIT) {
+ u.utrap = 0;
+ u.utraptype = 0;
+ }
+ goto_level(dlevel+1, FALSE);
+ }
+ }
+}
+
+static
+use_pick_axe(obj)
+struct obj *obj;
+{
+ char dirsyms[12];
+ extern char sdir[];
+ register char *dsp = dirsyms, *sdp = sdir;
+ register struct monst *mtmp;
+ register struct rm *lev;
+ register int rx, ry, res = 0;
+
+ if(obj != uwep) {
+ if(uwep && uwep->cursed) {
+ /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
+ pline("Since your weapon is welded to your hand,");
+ pline("you cannot use that pick-axe.");
+ return(0);
+ }
+ pline("You now wield %s.", doname(obj));
+ setuwep(obj);
+ res = 1;
+ }
+ while(*sdp) {
+ (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */
+ rx = u.ux + u.dx;
+ ry = u.uy + u.dy;
+ if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
+ (IS_ROCK(levl[rx][ry].typ)
+ || sobj_at(ENORMOUS_ROCK, rx, ry))))
+ *dsp++ = *sdp;
+ sdp++;
+ }
+ *dsp = 0;
+ pline("In what direction do you want to dig? [%s] ", dirsyms);
+ if(!getdir(0)) /* no txt */
+ return(res);
+ if(u.uswallow && attack(u.ustuck)) /* return(1) */;
+ else
+ if(u.dz < 0)
+ pline("You cannot reach the ceiling.");
+ else
+ if(u.dz == 0) {
+ if(Confusion)
+ confdir();
+ rx = u.ux + u.dx;
+ ry = u.uy + u.dy;
+ if((mtmp = m_at(rx, ry)) && attack(mtmp))
+ return(1);
+ if(!isok(rx, ry)) {
+ pline("Clash!");
+ return(1);
+ }
+ lev = &levl[rx][ry];
+ if(lev->typ == DOOR)
+ pline("Your %s against the door.",
+ aobjnam(obj, "clang"));
+ else if(!IS_ROCK(lev->typ)
+ && !sobj_at(ENORMOUS_ROCK, rx, ry)) {
+ /* ACCESSIBLE or POOL */
+ pline("You swing your %s through thin air.",
+ aobjnam(obj, (char *) 0));
+ } else {
+ if(dig_pos.x != rx || dig_pos.y != ry
+ || dig_level != dlevel || dig_down) {
+ dig_down = FALSE;
+ dig_pos.x = rx;
+ dig_pos.y = ry;
+ dig_level = dlevel;
+ dig_effort = 0;
+ pline("You start digging.");
+ } else
+ pline("You continue digging.");
+ occupation = dig;
+ occtxt = "digging";
+ }
+ } else if(Levitation) {
+ pline("You cannot reach the floor.");
+ } else {
+ if(dig_pos.x != u.ux || dig_pos.y != u.uy
+ || dig_level != dlevel || !dig_down) {
+ dig_down = TRUE;
+ dig_pos.x = u.ux;
+ dig_pos.y = u.uy;
+ dig_level = dlevel;
+ dig_effort = 0;
+ pline("You start digging in the floor.");
+ if(inshop())
+ shopdig(0);
+ } else
+ pline("You continue digging in the floor.");
+ occupation = dig;
+ occtxt = "digging";
+ }
+ return(1);
+}
diff --git a/hack/hack.bones.c b/hack/hack.bones.c
new file mode 100644
index 00000000..d4a05b82
--- /dev/null
+++ b/hack/hack.bones.c
@@ -0,0 +1,95 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.bones.c - version 1.0.3 */
+
+#include "hack.h"
+extern char plname[PL_NSIZ];
+extern long somegold();
+extern struct monst *makemon();
+extern struct permonst pm_ghost;
+
+char bones[] = "bones_xx";
+
+/* save bones and possessions of a deceased adventurer */
+savebones(){
+register fd;
+register struct obj *otmp;
+register struct trap *ttmp;
+register struct monst *mtmp;
+ if(dlevel <= 0 || dlevel > MAXLEVEL) return;
+ if(!rn2(1 + dlevel/2)) return; /* not so many ghosts on low levels */
+ bones[6] = '0' + (dlevel/10);
+ bones[7] = '0' + (dlevel%10);
+ if((fd = open(bones,0)) >= 0){
+ (void) close(fd);
+ return;
+ }
+ /* drop everything; the corpse's possessions are usually cursed */
+ otmp = invent;
+ while(otmp){
+ otmp->ox = u.ux;
+ otmp->oy = u.uy;
+ otmp->age = 0; /* very long ago */
+ otmp->owornmask = 0;
+ if(rn2(5)) otmp->cursed = 1;
+ if(!otmp->nobj){
+ otmp->nobj = fobj;
+ fobj = invent;
+ invent = 0; /* superfluous */
+ break;
+ }
+ otmp = otmp->nobj;
+ }
+ if(!(mtmp = makemon(PM_GHOST, u.ux, u.uy))) return;
+ mtmp->mx = u.ux;
+ mtmp->my = u.uy;
+ mtmp->msleep = 1;
+ (void) strcpy((char *) mtmp->mextra, plname);
+ mkgold(somegold() + d(dlevel,30), u.ux, u.uy);
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
+ mtmp->m_id = 0;
+ if(mtmp->mtame) {
+ mtmp->mtame = 0;
+ mtmp->mpeaceful = 0;
+ }
+ mtmp->mlstmv = 0;
+ if(mtmp->mdispl) unpmon(mtmp);
+ }
+ for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
+ ttmp->tseen = 0;
+ for(otmp = fobj; otmp; otmp = otmp->nobj) {
+ otmp->o_id = 0;
+ /* otmp->o_cnt_id = 0; - superfluous */
+ otmp->onamelth = 0;
+ otmp->known = 0;
+ otmp->invlet = 0;
+ if(otmp->olet == AMULET_SYM && !otmp->spe) {
+ otmp->spe = -1; /* no longer the actual amulet */
+ otmp->cursed = 1; /* flag as gotten from a ghost */
+ }
+ }
+ if((fd = creat(bones, FMASK)) < 0) return;
+ savelev(fd,dlevel);
+ (void) close(fd);
+}
+
+getbones(){
+register fd,x,y,ok;
+ if(rn2(3)) return(0); /* only once in three times do we find bones */
+ bones[6] = '0' + dlevel/10;
+ bones[7] = '0' + dlevel%10;
+ if((fd = open(bones, 0)) < 0) return(0);
+ if((ok = uptodate(fd)) != 0){
+ getlev(fd, 0, dlevel);
+ for(x = 0; x < COLNO; x++) for(y = 0; y < ROWNO; y++)
+ levl[x][y].seen = levl[x][y].new = 0;
+ }
+ (void) close(fd);
+#ifdef WIZARD
+ if(!wizard) /* duvel!frans: don't remove bones while debugging */
+#endif WiZARD
+ if(unlink(bones) < 0){
+ pline("Cannot unlink %s .", bones);
+ return(0);
+ }
+ return(ok);
+}
diff --git a/hack/hack.c b/hack/hack.c
new file mode 100644
index 00000000..5c828814
--- /dev/null
+++ b/hack/hack.c
@@ -0,0 +1,798 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.c - version 1.0.3 */
+
+#include "hack.h"
+#include <stdio.h>
+
+extern char news0();
+extern char *nomovemsg;
+extern char *exclam();
+extern struct obj *addinv();
+extern boolean hmon();
+
+/* called on movement:
+ 1. when throwing ball+chain far away
+ 2. when teleporting
+ 3. when walking out of a lit room
+ */
+unsee() {
+ register x,y;
+ register struct rm *lev;
+
+/*
+ if(u.udispl){
+ u.udispl = 0;
+ newsym(u.udisx, u.udisy);
+ }
+*/
+#ifndef QUEST
+ if(seehx){
+ seehx = 0;
+ } else
+#endif QUEST
+ for(x = u.ux-1; x < u.ux+2; x++)
+ for(y = u.uy-1; y < u.uy+2; y++) {
+ if(!isok(x, y)) continue;
+ lev = &levl[x][y];
+ if(!lev->lit && lev->scrsym == '.') {
+ lev->scrsym =' ';
+ lev->new = 1;
+ on_scr(x,y);
+ }
+ }
+}
+
+/* called:
+ in hack.eat.c: seeoff(0) - blind after eating rotten food
+ in hack.mon.c: seeoff(0) - blinded by a yellow light
+ in hack.mon.c: seeoff(1) - swallowed
+ in hack.do.c: seeoff(0) - blind after drinking potion
+ in hack.do.c: seeoff(1) - go up or down the stairs
+ in hack.trap.c:seeoff(1) - fall through trapdoor
+ */
+seeoff(mode) /* 1 to redo @, 0 to leave them */
+{ /* 1 means misc movement, 0 means blindness */
+ register x,y;
+ register struct rm *lev;
+
+ if(u.udispl && mode){
+ u.udispl = 0;
+ levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy);
+ }
+#ifndef QUEST
+ if(seehx) {
+ seehx = 0;
+ } else
+#endif QUEST
+ if(!mode) {
+ for(x = u.ux-1; x < u.ux+2; x++)
+ for(y = u.uy-1; y < u.uy+2; y++) {
+ if(!isok(x, y)) continue;
+ lev = &levl[x][y];
+ if(!lev->lit && lev->scrsym == '.')
+ lev->seen = 0;
+ }
+ }
+}
+
+domove()
+{
+ xchar oldx,oldy;
+ register struct monst *mtmp;
+ register struct rm *tmpr,*ust;
+ struct trap *trap;
+ register struct obj *otmp;
+
+ u_wipe_engr(rnd(5));
+
+ if(inv_weight() > 0){
+ pline("You collapse under your load.");
+ nomul(0);
+ return;
+ }
+ if(u.uswallow) {
+ u.dx = u.dy = 0;
+ u.ux = u.ustuck->mx;
+ u.uy = u.ustuck->my;
+ } else {
+ if(Confusion) {
+ do {
+ confdir();
+ } while(!isok(u.ux+u.dx, u.uy+u.dy) ||
+ IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ));
+ }
+ if(!isok(u.ux+u.dx, u.uy+u.dy)){
+ nomul(0);
+ return;
+ }
+ }
+
+ ust = &levl[u.ux][u.uy];
+ oldx = u.ux;
+ oldy = u.uy;
+ if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen)
+ nomul(0);
+ if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx ||
+ u.uy+u.dy != u.ustuck->my)) {
+ if(dist(u.ustuck->mx, u.ustuck->my) > 2){
+ /* perhaps it fled (or was teleported or ... ) */
+ u.ustuck = 0;
+ } else {
+ if(Blind) pline("You cannot escape from it!");
+ else pline("You cannot escape from %s!",
+ monnam(u.ustuck));
+ nomul(0);
+ return;
+ }
+ }
+ if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) {
+ /* attack monster */
+
+ nomul(0);
+ gethungry();
+ if(multi < 0) return; /* we just fainted */
+
+ /* try to attack; note that it might evade */
+ if(attack(u.uswallow ? u.ustuck : mtmp))
+ return;
+ }
+ /* not attacking an animal, so we try to move */
+ if(u.utrap) {
+ if(u.utraptype == TT_PIT) {
+ pline("You are still in a pit.");
+ u.utrap--;
+ } else {
+ pline("You are caught in a beartrap.");
+ if((u.dx && u.dy) || !rn2(5)) u.utrap--;
+ }
+ return;
+ }
+ tmpr = &levl[u.ux+u.dx][u.uy+u.dy];
+ if(IS_ROCK(tmpr->typ) ||
+ (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){
+ flags.move = 0;
+ nomul(0);
+ return;
+ }
+ while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) {
+ register xchar rx = u.ux+2*u.dx, ry = u.uy+2*u.dy;
+ register struct trap *ttmp;
+ nomul(0);
+ if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
+ (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) &&
+ !sobj_at(ENORMOUS_ROCK, rx, ry)) {
+ if(m_at(rx,ry)) {
+ pline("You hear a monster behind the rock.");
+ pline("Perhaps that's why you cannot move it.");
+ goto cannot_push;
+ }
+ if(ttmp = t_at(rx,ry))
+ switch(ttmp->ttyp) {
+ case PIT:
+ pline("You push the rock into a pit!");
+ deltrap(ttmp);
+ delobj(otmp);
+ pline("It completely fills the pit!");
+ continue;
+ case TELEP_TRAP:
+ pline("You push the rock and suddenly it disappears!");
+ delobj(otmp);
+ continue;
+ }
+ if(levl[rx][ry].typ == POOL) {
+ levl[rx][ry].typ = ROOM;
+ mnewsym(rx,ry);
+ prl(rx,ry);
+ pline("You push the rock into the water.");
+ pline("Now you can cross the water!");
+ delobj(otmp);
+ continue;
+ }
+ otmp->ox = rx;
+ otmp->oy = ry;
+ /* pobj(otmp); */
+ if(cansee(rx,ry)) atl(rx,ry,otmp->olet);
+ if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy);
+
+ { static long lastmovetime;
+ /* note: this var contains garbage initially and
+ after a restore */
+ if(moves > lastmovetime+2 || moves < lastmovetime)
+ pline("With great effort you move the enormous rock.");
+ lastmovetime = moves;
+ }
+ } else {
+ pline("You try to move the enormous rock, but in vain.");
+ cannot_push:
+ if((!invent || inv_weight()+90 <= 0) &&
+ (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)
+ && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){
+ pline("However, you can squeeze yourself into a small opening.");
+ break;
+ } else
+ return;
+ }
+ }
+ if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) &&
+ IS_ROCK(levl[u.ux+u.dx][u.uy].typ) &&
+ invent && inv_weight()+40 > 0) {
+ pline("You are carrying too much to get through.");
+ nomul(0);
+ return;
+ }
+ if(Punished &&
+ DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){
+ if(carried(uball)) {
+ movobj(uchain, u.ux, u.uy);
+ goto nodrag;
+ }
+
+ if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){
+ /* leave ball, move chain under/over ball */
+ movobj(uchain, uball->ox, uball->oy);
+ goto nodrag;
+ }
+
+ if(inv_weight() + (int) uball->owt/2 > 0) {
+ pline("You cannot %sdrag the heavy iron ball.",
+ invent ? "carry all that and also " : "");
+ nomul(0);
+ return;
+ }
+
+ movobj(uball, uchain->ox, uchain->oy);
+ unpobj(uball); /* BAH %% */
+ uchain->ox = u.ux;
+ uchain->oy = u.uy;
+ nomul(-2);
+ nomovemsg = "";
+ nodrag: ;
+ }
+ u.ux += u.dx;
+ u.uy += u.dy;
+ if(flags.run) {
+ if(tmpr->typ == DOOR ||
+ (xupstair == u.ux && yupstair == u.uy) ||
+ (xdnstair == u.ux && ydnstair == u.uy))
+ nomul(0);
+ }
+
+ if(tmpr->typ == POOL && !Levitation)
+ drown(); /* not necessarily fatal */
+
+/*
+ if(u.udispl) {
+ u.udispl = 0;
+ newsym(oldx,oldy);
+ }
+*/
+ if(!Blind) {
+#ifdef QUEST
+ setsee();
+#else
+ if(ust->lit) {
+ if(tmpr->lit) {
+ if(tmpr->typ == DOOR)
+ prl1(u.ux+u.dx,u.uy+u.dy);
+ else if(ust->typ == DOOR)
+ nose1(oldx-u.dx,oldy-u.dy);
+ } else {
+ unsee();
+ prl1(u.ux+u.dx,u.uy+u.dy);
+ }
+ } else {
+ if(tmpr->lit) setsee();
+ else {
+ prl1(u.ux+u.dx,u.uy+u.dy);
+ if(tmpr->typ == DOOR) {
+ if(u.dy) {
+ prl(u.ux-1,u.uy);
+ prl(u.ux+1,u.uy);
+ } else {
+ prl(u.ux,u.uy-1);
+ prl(u.ux,u.uy+1);
+ }
+ }
+ }
+ nose1(oldx-u.dx,oldy-u.dy);
+ }
+#endif QUEST
+ } else {
+ pru();
+ }
+ if(!flags.nopick) pickup(1);
+ if(trap) dotrap(trap); /* fall into pit, arrow trap, etc. */
+ (void) inshop();
+ if(!Blind) read_engr_at(u.ux,u.uy);
+}
+
+movobj(obj, ox, oy)
+register struct obj *obj;
+register int ox, oy;
+{
+ /* Some dirty programming to get display right */
+ freeobj(obj);
+ unpobj(obj);
+ obj->nobj = fobj;
+ fobj = obj;
+ obj->ox = ox;
+ obj->oy = oy;
+}
+
+dopickup(){
+ if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) {
+ pline("There is nothing here to pick up.");
+ return(0);
+ }
+ if(Levitation) {
+ pline("You cannot reach the floor.");
+ return(1);
+ }
+ pickup(0);
+ return(1);
+}
+
+pickup(all)
+{
+ register struct gold *gold;
+ register struct obj *obj, *obj2;
+ register int wt;
+
+ if(Levitation) return;
+ while(gold = g_at(u.ux,u.uy)) {
+ pline("%ld gold piece%s.", gold->amount, plur(gold->amount));
+ u.ugold += gold->amount;
+ flags.botl = 1;
+ freegold(gold);
+ if(flags.run) nomul(0);
+ if(Invisible) newsym(u.ux,u.uy);
+ }
+
+ /* check for more than one object */
+ if(!all) {
+ register int ct = 0;
+
+ for(obj = fobj; obj; obj = obj->nobj)
+ if(obj->ox == u.ux && obj->oy == u.uy)
+ if(!Punished || obj != uchain)
+ ct++;
+ if(ct < 2)
+ all++;
+ else
+ pline("There are several objects here.");
+ }
+
+ for(obj = fobj; obj; obj = obj2) {
+ obj2 = obj->nobj; /* perhaps obj will be picked up */
+ if(obj->ox == u.ux && obj->oy == u.uy) {
+ if(flags.run) nomul(0);
+
+ /* do not pick up uchain */
+ if(Punished && obj == uchain)
+ continue;
+
+ if(!all) {
+ char c;
+
+ pline("Pick up %s ? [ynaq]", doname(obj));
+ while(!index("ynaq ", (c = readchar())))
+ bell();
+ if(c == 'q') return;
+ if(c == 'n') continue;
+ if(c == 'a') all = 1;
+ }
+
+ if(obj->otyp == DEAD_COCKATRICE && !uarmg){
+ pline("Touching the dead cockatrice is a fatal mistake.");
+ pline("You turn to stone.");
+ killer = "cockatrice cadaver";
+ done("died");
+ }
+
+ if(obj->otyp == SCR_SCARE_MONSTER){
+ if(!obj->spe) obj->spe = 1;
+ else {
+ /* Note: perhaps the 1st pickup failed: you cannot
+ carry anymore, and so we never dropped it -
+ let's assume that treading on it twice also
+ destroys the scroll */
+ pline("The scroll turns to dust as you pick it up.");
+ delobj(obj);
+ continue;
+ }
+ }
+
+ wt = inv_weight() + obj->owt;
+ if(wt > 0) {
+ if(obj->quan > 1) {
+ /* see how many we can lift */
+ extern struct obj *splitobj();
+ int savequan = obj->quan;
+ int iw = inv_weight();
+ int qq;
+ for(qq = 1; qq < savequan; qq++){
+ obj->quan = qq;
+ if(iw + weight(obj) > 0)
+ break;
+ }
+ obj->quan = savequan;
+ qq--;
+ /* we can carry qq of them */
+ if(!qq) goto too_heavy;
+ pline("You can only carry %s of the %s lying here.",
+ (qq == 1) ? "one" : "some",
+ doname(obj));
+ (void) splitobj(obj, qq);
+ /* note: obj2 is set already, so we'll never
+ * encounter the other half; if it should be
+ * otherwise then write
+ * obj2 = splitobj(obj,qq);
+ */
+ goto lift_some;
+ }
+ too_heavy:
+ pline("There %s %s here, but %s.",
+ (obj->quan == 1) ? "is" : "are",
+ doname(obj),
+ !invent ? "it is too heavy for you to lift"
+ : "you cannot carry anymore");
+ break;
+ }
+ lift_some:
+ if(inv_cnt() >= 52) {
+ pline("Your knapsack cannot accomodate anymore items.");
+ break;
+ }
+ if(wt > -5) pline("You have a little trouble lifting");
+ freeobj(obj);
+ if(Invisible) newsym(u.ux,u.uy);
+ addtobill(obj); /* sets obj->unpaid if necessary */
+ { int pickquan = obj->quan;
+ int mergquan;
+ if(!Blind) obj->dknown = 1; /* this is done by prinv(),
+ but addinv() needs it already for merging */
+ obj = addinv(obj); /* might merge it with other objects */
+ mergquan = obj->quan;
+ obj->quan = pickquan; /* to fool prinv() */
+ prinv(obj);
+ obj->quan = mergquan;
+ }
+ }
+ }
+}
+
+/* stop running if we see something interesting */
+/* turn around a corner if that is the only way we can proceed */
+/* do not turn left or right twice */
+lookaround(){
+register x,y,i,x0,y0,m0,i0 = 9;
+register int corrct = 0, noturn = 0;
+register struct monst *mtmp;
+#ifdef lint
+ /* suppress "used before set" message */
+ x0 = y0 = 0;
+#endif lint
+ if(Blind || flags.run == 0) return;
+ if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return;
+#ifdef QUEST
+ if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop;
+#endif QUEST
+ for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
+ if(x == u.ux && y == u.uy) continue;
+ if(!levl[x][y].typ) continue;
+ if((mtmp = m_at(x,y)) && !mtmp->mimic &&
+ (!mtmp->minvis || See_invisible)){
+ if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy))
+ goto stop;
+ } else mtmp = 0; /* invisible M cannot influence us */
+ if(x == u.ux-u.dx && y == u.uy-u.dy) continue;
+ switch(levl[x][y].scrsym){
+ case '|':
+ case '-':
+ case '.':
+ case ' ':
+ break;
+ case '+':
+ if(x != u.ux && y != u.uy) break;
+ if(flags.run != 1) goto stop;
+ /* fall into next case */
+ case CORR_SYM:
+ corr:
+ if(flags.run == 1 || flags.run == 3) {
+ i = DIST(x,y,u.ux+u.dx,u.uy+u.dy);
+ if(i > 2) break;
+ if(corrct == 1 && DIST(x,y,x0,y0) != 1)
+ noturn = 1;
+ if(i < i0) {
+ i0 = i;
+ x0 = x;
+ y0 = y;
+ m0 = mtmp ? 1 : 0;
+ }
+ }
+ corrct++;
+ break;
+ case '^':
+ if(flags.run == 1) goto corr; /* if you must */
+ if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
+ break;
+ default: /* e.g. objects or trap or stairs */
+ if(flags.run == 1) goto corr;
+ if(mtmp) break; /* d */
+ stop:
+ nomul(0);
+ return;
+ }
+ }
+#ifdef QUEST
+ if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop;
+#endif QUEST
+ if(corrct > 1 && flags.run == 2) goto stop;
+ if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
+ (corrct == 1 || (corrct == 2 && i0 == 1))) {
+ /* make sure that we do not turn too far */
+ if(i0 == 2) {
+ if(u.dx == y0-u.uy && u.dy == u.ux-x0)
+ i = 2; /* straight turn right */
+ else
+ i = -2; /* straight turn left */
+ } else if(u.dx && u.dy) {
+ if((u.dx == u.dy && y0 == u.uy) ||
+ (u.dx != u.dy && y0 != u.uy))
+ i = -1; /* half turn left */
+ else
+ i = 1; /* half turn right */
+ } else {
+ if((x0-u.ux == y0-u.uy && !u.dy) ||
+ (x0-u.ux != y0-u.uy && u.dy))
+ i = 1; /* half turn right */
+ else
+ i = -1; /* half turn left */
+ }
+ i += u.last_str_turn;
+ if(i <= 2 && i >= -2) {
+ u.last_str_turn = i;
+ u.dx = x0-u.ux, u.dy = y0-u.uy;
+ }
+ }
+}
+
+/* something like lookaround, but we are not running */
+/* react only to monsters that might hit us */
+monster_nearby() {
+register int x,y;
+register struct monst *mtmp;
+ if(!Blind)
+ for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
+ if(x == u.ux && y == u.uy) continue;
+ if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame &&
+ !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) &&
+ !mtmp->mfroz && !mtmp->msleep && /* aplvax!jcn */
+ (!mtmp->minvis || See_invisible))
+ return(1);
+ }
+ return(0);
+}
+
+#ifdef QUEST
+cansee(x,y) xchar x,y; {
+register int dx,dy,adx,ady,sdx,sdy,dmax,d;
+ if(Blind) return(0);
+ if(!isok(x,y)) return(0);
+ d = dist(x,y);
+ if(d < 3) return(1);
+ if(d > u.uhorizon*u.uhorizon) return(0);
+ if(!levl[x][y].lit)
+ return(0);
+ dx = x - u.ux; adx = abs(dx); sdx = sgn(dx);
+ dy = y - u.uy; ady = abs(dy); sdy = sgn(dy);
+ if(dx == 0 || dy == 0 || adx == ady){
+ dmax = (dx == 0) ? ady : adx;
+ for(d = 1; d <= dmax; d++)
+ if(!rroom(sdx*d,sdy*d))
+ return(0);
+ return(1);
+ } else if(ady > adx){
+ for(d = 1; d <= ady; d++){
+ if(!rroom(sdx*( (d*adx)/ady ), sdy*d) ||
+ !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d))
+ return(0);
+ }
+ return(1);
+ } else {
+ for(d = 1; d <= adx; d++){
+ if(!rroom(sdx*d, sdy*( (d*ady)/adx )) ||
+ !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 )))
+ return(0);
+ }
+ return(1);
+ }
+}
+
+rroom(x,y) register int x,y; {
+ return(IS_ROOM(levl[u.ux+x][u.uy+y].typ));
+}
+
+#else
+
+cansee(x,y) xchar x,y; {
+ if(Blind || u.uswallow) return(0);
+ if(dist(x,y) < 3) return(1);
+ if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y &&
+ y <= seehy) return(1);
+ return(0);
+}
+#endif QUEST
+
+sgn(a) register int a; {
+ return((a > 0) ? 1 : (a == 0) ? 0 : -1);
+}
+
+#ifdef QUEST
+setsee()
+{
+ register x,y;
+
+ if(Blind) {
+ pru();
+ return;
+ }
+ for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++)
+ for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) {
+ if(cansee(x,y))
+ prl(x,y);
+ }
+}
+
+#else
+
+setsee()
+{
+ register x,y;
+
+ if(Blind) {
+ pru();
+ return;
+ }
+ if(!levl[u.ux][u.uy].lit) {
+ seelx = u.ux-1;
+ seehx = u.ux+1;
+ seely = u.uy-1;
+ seehy = u.uy+1;
+ } else {
+ for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--);
+ for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++);
+ for(seely = u.uy; levl[u.ux][seely-1].lit; seely--);
+ for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++);
+ }
+ for(y = seely; y <= seehy; y++)
+ for(x = seelx; x <= seehx; x++) {
+ prl(x,y);
+ }
+ if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */
+ else {
+ if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1);
+ if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1);
+ if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y);
+ if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y);
+ }
+}
+#endif QUEST
+
+nomul(nval)
+register nval;
+{
+ if(multi < 0) return;
+ multi = nval;
+ flags.mv = flags.run = 0;
+}
+
+abon()
+{
+ if(u.ustr == 3) return(-3);
+ else if(u.ustr < 6) return(-2);
+ else if(u.ustr < 8) return(-1);
+ else if(u.ustr < 17) return(0);
+ else if(u.ustr < 69) return(1); /* up to 18/50 */
+ else if(u.ustr < 118) return(2);
+ else return(3);
+}
+
+dbon()
+{
+ if(u.ustr < 6) return(-1);
+ else if(u.ustr < 16) return(0);
+ else if(u.ustr < 18) return(1);
+ else if(u.ustr == 18) return(2); /* up to 18 */
+ else if(u.ustr < 94) return(3); /* up to 18/75 */
+ else if(u.ustr < 109) return(4); /* up to 18/90 */
+ else if(u.ustr < 118) return(5); /* up to 18/99 */
+ else return(6);
+}
+
+losestr(num) /* may kill you; cause may be poison or monster like 'A' */
+register num;
+{
+ u.ustr -= num;
+ while(u.ustr < 3) {
+ u.ustr++;
+ u.uhp -= 6;
+ u.uhpmax -= 6;
+ }
+ flags.botl = 1;
+}
+
+losehp(n,knam)
+register n;
+register char *knam;
+{
+ u.uhp -= n;
+ if(u.uhp > u.uhpmax)
+ u.uhpmax = u.uhp; /* perhaps n was negative */
+ flags.botl = 1;
+ if(u.uhp < 1) {
+ killer = knam; /* the thing that killed you */
+ done("died");
+ }
+}
+
+losehp_m(n,mtmp)
+register n;
+register struct monst *mtmp;
+{
+ u.uhp -= n;
+ flags.botl = 1;
+ if(u.uhp < 1)
+ done_in_by(mtmp);
+}
+
+losexp() /* hit by V or W */
+{
+ register num;
+ extern long newuexp();
+
+ if(u.ulevel > 1)
+ pline("Goodbye level %u.", u.ulevel--);
+ else
+ u.uhp = -1;
+ num = rnd(10);
+ u.uhp -= num;
+ u.uhpmax -= num;
+ u.uexp = newuexp();
+ flags.botl = 1;
+}
+
+inv_weight(){
+register struct obj *otmp = invent;
+register int wt = (u.ugold + 500)/1000;
+register int carrcap;
+ if(Levitation) /* pugh@cornell */
+ carrcap = MAX_CARR_CAP;
+ else {
+ carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel);
+ if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
+ if(Wounded_legs & LEFT_SIDE) carrcap -= 10;
+ if(Wounded_legs & RIGHT_SIDE) carrcap -= 10;
+ }
+ while(otmp){
+ wt += otmp->owt;
+ otmp = otmp->nobj;
+ }
+ return(wt - carrcap);
+}
+
+inv_cnt(){
+register struct obj *otmp = invent;
+register int ct = 0;
+ while(otmp){
+ ct++;
+ otmp = otmp->nobj;
+ }
+ return(ct);
+}
+
+long
+newuexp()
+{
+ return(10*(1L << (u.ulevel-1)));
+}
diff --git a/hack/hack.cmd.c b/hack/hack.cmd.c
new file mode 100644
index 00000000..e36cfcca
--- /dev/null
+++ b/hack/hack.cmd.c
@@ -0,0 +1,302 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.cmd.c - version 1.0.3 */
+
+#include "hack.h"
+#include "def.func_tab.h"
+
+int doredraw(),doredotopl(),dodrop(),dodrink(),doread(),dosearch(),dopickup(),
+doversion(),doweararm(),dowearring(),doremarm(),doremring(),dopay(),doapply(),
+dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(),doengrave(),dotele(),
+dohelp(),doeat(),doddrop(),do_mname(),doidtrap(),doprwep(),doprarm(),
+doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(),doset(),
+doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip(), dopray();
+#ifdef SHELL
+int dosh();
+#endif SHELL
+#ifdef SUSPEND
+int dosuspend();
+#endif SUSPEND
+
+struct func_tab cmdlist[]={
+ '\020', doredotopl,
+ '\022', doredraw,
+ '\024', dotele,
+#ifdef SUSPEND
+ '\032', dosuspend,
+#endif SUSPEND
+ 'a', doapply,
+/* 'A' : UNUSED */
+/* 'b', 'B' : go sw */
+ 'c', ddocall,
+ 'C', do_mname,
+ 'd', dodrop,
+ 'D', doddrop,
+ 'e', doeat,
+ 'E', doengrave,
+/* 'f', 'F' : multiple go (might become 'fight') */
+/* 'g', 'G' : UNUSED */
+/* 'h', 'H' : go west */
+ 'I', dotypeinv, /* Robert Viduya */
+ 'i', ddoinv,
+/* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
+/* 'o', doopen, */
+ 'O', doset,
+ 'p', dopay,
+ 'P', dowearring,
+ 'q', dodrink,
+ 'Q', done1,
+ 'r', doread,
+ 'R', doremring,
+ 's', dosearch,
+ 'S', dosave,
+ 't', dothrow,
+ 'T', doremarm,
+/* 'u', 'U' : go ne */
+ 'v', doversion,
+/* 'V' : UNUSED */
+ 'w', dowield,
+ 'W', doweararm,
+/* 'x', 'X' : UNUSED */
+/* 'y', 'Y' : go nw */
+ 'z', dozap,
+/* 'Z' : UNUSED */
+ '<', doup,
+ '>', dodown,
+ '/', dowhatis,
+ '?', dohelp,
+#ifdef SHELL
+ '!', dosh,
+#endif SHELL
+ '.', donull,
+ ' ', donull,
+ ',', dopickup,
+ ':', dolook,
+ '^', doidtrap,
+ '\\', dodiscovered, /* Robert Viduya */
+ WEAPON_SYM, doprwep,
+ ARMOR_SYM, doprarm,
+ RING_SYM, doprring,
+ '$', doprgold,
+ '#', doextcmd,
+ 0,0,0
+};
+
+struct ext_func_tab extcmdlist[] = {
+ "dip", dodip,
+ "pray", dopray,
+ (char *) 0, donull
+};
+
+extern char *parse(), lowc(), unctrl(), quitchars[];
+
+rhack(cmd)
+register char *cmd;
+{
+ register struct func_tab *tlist = cmdlist;
+ boolean firsttime = FALSE;
+ register res;
+
+ if(!cmd) {
+ firsttime = TRUE;
+ flags.nopick = 0;
+ cmd = parse();
+ }
+ if(!*cmd || (*cmd & 0377) == 0377 ||
+ (flags.no_rest_on_space && *cmd == ' ')){
+ bell();
+ flags.move = 0;
+ return; /* probably we just had an interrupt */
+ }
+ if(movecmd(*cmd)) {
+ walk:
+ if(multi) flags.mv = 1;
+ domove();
+ return;
+ }
+ if(movecmd(lowc(*cmd))) {
+ flags.run = 1;
+ rush:
+ if(firsttime){
+ if(!multi) multi = COLNO;
+ u.last_str_turn = 0;
+ }
+ flags.mv = 1;
+#ifdef QUEST
+ if(flags.run >= 4) finddir();
+ if(firsttime){
+ u.ux0 = u.ux + u.dx;
+ u.uy0 = u.uy + u.dy;
+ }
+#endif QUEST
+ domove();
+ return;
+ }
+ if((*cmd == 'f' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) {
+ flags.run = 2;
+ goto rush;
+ }
+ if(*cmd == 'F' && movecmd(lowc(cmd[1]))) {
+ flags.run = 3;
+ goto rush;
+ }
+ if(*cmd == 'm' && movecmd(cmd[1])) {
+ flags.run = 0;
+ flags.nopick = 1;
+ goto walk;
+ }
+ if(*cmd == 'M' && movecmd(lowc(cmd[1]))) {
+ flags.run = 1;
+ flags.nopick = 1;
+ goto rush;
+ }
+#ifdef QUEST
+ if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
+ flags.run = 4;
+ if(*cmd == 'F') flags.run += 2;
+ if(cmd[2] == '-') flags.run += 1;
+ goto rush;
+ }
+#endif QUEST
+ while(tlist->f_char) {
+ if(*cmd == tlist->f_char){
+ res = (*(tlist->f_funct))();
+ if(!res) {
+ flags.move = 0;
+ multi = 0;
+ }
+ return;
+ }
+ tlist++;
+ }
+ { char expcmd[10];
+ register char *cp = expcmd;
+ while(*cmd && cp-expcmd < sizeof(expcmd)-2) {
+ if(*cmd >= 040 && *cmd < 0177)
+ *cp++ = *cmd++;
+ else {
+ *cp++ = '^';
+ *cp++ = *cmd++ ^ 0100;
+ }
+ }
+ *cp++ = 0;
+ pline("Unknown command '%s'.", expcmd);
+ }
+ multi = flags.move = 0;
+}
+
+doextcmd() /* here after # - now read a full-word command */
+{
+ char buf[BUFSZ];
+ register struct ext_func_tab *efp = extcmdlist;
+
+ pline("# ");
+ getlin(buf);
+ clrlin();
+ if(buf[0] == '\033')
+ return(0);
+ while(efp->ef_txt) {
+ if(!strcmp(efp->ef_txt, buf))
+ return((*(efp->ef_funct))());
+ efp++;
+ }
+ pline("%s: unknown command.", buf);
+ return(0);
+}
+
+char
+lowc(sym)
+char sym;
+{
+ return( (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym );
+}
+
+char
+unctrl(sym)
+char sym;
+{
+ return( (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym );
+}
+
+/* 'rogue'-like direction commands */
+char sdir[] = "hykulnjb><";
+schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 };
+schar ydir[10] = { 0,-1,-1,-1, 0, 1, 1, 1, 0, 0 };
+schar zdir[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1,-1 };
+
+movecmd(sym) /* also sets u.dz, but returns false for <> */
+char sym;
+{
+ register char *dp;
+
+ u.dz = 0;
+ if(!(dp = index(sdir, sym))) return(0);
+ u.dx = xdir[dp-sdir];
+ u.dy = ydir[dp-sdir];
+ u.dz = zdir[dp-sdir];
+ return(!u.dz);
+}
+
+getdir(s)
+boolean s;
+{
+ char dirsym;
+
+ if(s) pline("In what direction?");
+ dirsym = readchar();
+ if(!movecmd(dirsym) && !u.dz) {
+ if(!index(quitchars, dirsym))
+ pline("What a strange direction!");
+ return(0);
+ }
+ if(Confusion && !u.dz)
+ confdir();
+ return(1);
+}
+
+confdir()
+{
+ register x = rn2(8);
+ u.dx = xdir[x];
+ u.dy = ydir[x];
+}
+
+#ifdef QUEST
+finddir(){
+register int i, ui = u.di;
+ for(i = 0; i <= 8; i++){
+ if(flags.run & 1) ui++; else ui += 7;
+ ui %= 8;
+ if(i == 8){
+ pline("Not near a wall.");
+ flags.move = multi = 0;
+ return(0);
+ }
+ if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
+ break;
+ }
+ for(i = 0; i <= 8; i++){
+ if(flags.run & 1) ui += 7; else ui++;
+ ui %= 8;
+ if(i == 8){
+ pline("Not near a room.");
+ flags.move = multi = 0;
+ return(0);
+ }
+ if(isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
+ break;
+ }
+ u.di = ui;
+ u.dx = xdir[ui];
+ u.dy = ydir[ui];
+}
+
+isroom(x,y) register x,y; { /* what about POOL? */
+ return(isok(x,y) && (levl[x][y].typ == ROOM ||
+ (levl[x][y].typ >= LDOOR && flags.run >= 6)));
+}
+#endif QUEST
+
+isok(x,y) register x,y; {
+ /* x corresponds to curx, so x==1 is the first column. Ach. %% */
+ return(x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1);
+}
diff --git a/hack/hack.do.c b/hack/hack.do.c
new file mode 100644
index 00000000..1227eb92
--- /dev/null
+++ b/hack/hack.do.c
@@ -0,0 +1,488 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.do.c - version 1.0.3 */
+
+/* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */
+
+#include "hack.h"
+
+extern struct obj *splitobj(), *addinv();
+extern boolean hmon();
+extern boolean level_exists[];
+extern struct monst youmonst;
+extern char *Doname();
+extern char *nomovemsg;
+
+static int drop();
+
+dodrop() {
+ return(drop(getobj("0$#", "drop")));
+}
+
+static int
+drop(obj) register struct obj *obj; {
+ if(!obj) return(0);
+ if(obj->olet == '$') { /* pseudo object */
+ register long amount = OGOLD(obj);
+
+ if(amount == 0)
+ pline("You didn't drop any gold pieces.");
+ else {
+ mkgold(amount, u.ux, u.uy);
+ pline("You dropped %ld gold piece%s.",
+ amount, plur(amount));
+ if(Invisible) newsym(u.ux, u.uy);
+ }
+ free((char *) obj);
+ return(1);
+ }
+ if(obj->owornmask & (W_ARMOR | W_RING)){
+ pline("You cannot drop something you are wearing.");
+ return(0);
+ }
+ if(obj == uwep) {
+ if(uwep->cursed) {
+ pline("Your weapon is welded to your hand!");
+ return(0);
+ }
+ setuwep((struct obj *) 0);
+ }
+ pline("You dropped %s.", doname(obj));
+ dropx(obj);
+ return(1);
+}
+
+/* Called in several places - should not produce texts */
+dropx(obj)
+register struct obj *obj;
+{
+ freeinv(obj);
+ dropy(obj);
+}
+
+dropy(obj)
+register struct obj *obj;
+{
+ if(obj->otyp == CRYSKNIFE)
+ obj->otyp = WORM_TOOTH;
+ obj->ox = u.ux;
+ obj->oy = u.uy;
+ obj->nobj = fobj;
+ fobj = obj;
+ if(Invisible) newsym(u.ux,u.uy);
+ subfrombill(obj);
+ stackobj(obj);
+}
+
+/* drop several things */
+doddrop() {
+ return(ggetobj("drop", drop, 0));
+}
+
+dodown()
+{
+ if(u.ux != xdnstair || u.uy != ydnstair) {
+ pline("You can't go down here.");
+ return(0);
+ }
+ if(u.ustuck) {
+ pline("You are being held, and cannot go down.");
+ return(1);
+ }
+ if(Levitation) {
+ pline("You're floating high above the stairs.");
+ return(0);
+ }
+
+ goto_level(dlevel+1, TRUE);
+ return(1);
+}
+
+doup()
+{
+ if(u.ux != xupstair || u.uy != yupstair) {
+ pline("You can't go up here.");
+ return(0);
+ }
+ if(u.ustuck) {
+ pline("You are being held, and cannot go up.");
+ return(1);
+ }
+ if(!Levitation && inv_weight() + 5 > 0) {
+ pline("Your load is too heavy to climb the stairs.");
+ return(1);
+ }
+
+ goto_level(dlevel-1, TRUE);
+ return(1);
+}
+
+goto_level(newlevel, at_stairs)
+register int newlevel;
+register boolean at_stairs;
+{
+ register fd;
+ register boolean up = (newlevel < dlevel);
+
+ if(newlevel <= 0) done("escaped"); /* in fact < 0 is impossible */
+ if(newlevel > MAXLEVEL) newlevel = MAXLEVEL; /* strange ... */
+ if(newlevel == dlevel) return; /* this can happen */
+
+ glo(dlevel);
+ fd = creat(lock, FMASK);
+ if(fd < 0) {
+ /*
+ * This is not quite impossible: e.g., we may have
+ * exceeded our quota. If that is the case then we
+ * cannot leave this level, and cannot save either.
+ * Another possibility is that the directory was not
+ * writable.
+ */
+ pline("A mysterious force prevents you from going %s.",
+ up ? "up" : "down");
+ return;
+ }
+
+ if(Punished) unplacebc();
+ u.utrap = 0; /* needed in level_tele */
+ u.ustuck = 0; /* idem */
+ keepdogs();
+ seeoff(1);
+ if(u.uswallow) /* idem */
+ u.uswldtim = u.uswallow = 0;
+ flags.nscrinh = 1;
+ u.ux = FAR; /* hack */
+ (void) inshop(); /* probably was a trapdoor */
+
+ savelev(fd,dlevel);
+ (void) close(fd);
+
+ dlevel = newlevel;
+ if(maxdlevel < dlevel)
+ maxdlevel = dlevel;
+ glo(dlevel);
+
+ if(!level_exists[dlevel])
+ mklev();
+ else {
+ extern int hackpid;
+
+ if((fd = open(lock,0)) < 0) {
+ pline("Cannot open %s .", lock);
+ pline("Probably someone removed it.");
+ done("tricked");
+ }
+ getlev(fd, hackpid, dlevel);
+ (void) close(fd);
+ }
+
+ if(at_stairs) {
+ if(up) {
+ u.ux = xdnstair;
+ u.uy = ydnstair;
+ if(!u.ux) { /* entering a maze from below? */
+ u.ux = xupstair; /* this will confuse the player! */
+ u.uy = yupstair;
+ }
+ if(Punished && !Levitation){
+ pline("With great effort you climb the stairs.");
+ placebc(1);
+ }
+ } else {
+ u.ux = xupstair;
+ u.uy = yupstair;
+ if(inv_weight() + 5 > 0 || Punished){
+ pline("You fall down the stairs."); /* %% */
+ losehp(rnd(3), "fall");
+ if(Punished) {
+ if(uwep != uball && rn2(3)){
+ pline("... and are hit by the iron ball.");
+ losehp(rnd(20), "iron ball");
+ }
+ placebc(1);
+ }
+ selftouch("Falling, you");
+ }
+ }
+ { register struct monst *mtmp = m_at(u.ux, u.uy);
+ if(mtmp)
+ mnexto(mtmp);
+ }
+ } else { /* trapdoor or level_tele */
+ do {
+ u.ux = rnd(COLNO-1);
+ u.uy = rn2(ROWNO);
+ } while(levl[u.ux][u.uy].typ != ROOM ||
+ m_at(u.ux,u.uy));
+ if(Punished){
+ if(uwep != uball && !up /* %% */ && rn2(5)){
+ pline("The iron ball falls on your head.");
+ losehp(rnd(25), "iron ball");
+ }
+ placebc(1);
+ }
+ selftouch("Falling, you");
+ }
+ (void) inshop();
+ initrack();
+
+ losedogs();
+ { register struct monst *mtmp;
+ if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */
+ }
+ flags.nscrinh = 0;
+ setsee();
+ seeobjs(); /* make old cadavers disappear - riv05!a3 */
+ docrt();
+ pickup(1);
+ read_engr_at(u.ux,u.uy);
+}
+
+donull() {
+ return(1); /* Do nothing, but let other things happen */
+}
+
+dopray() {
+ nomovemsg = "You finished your prayer.";
+ nomul(-3);
+ return(1);
+}
+
+struct monst *bhit(), *boomhit();
+dothrow()
+{
+ register struct obj *obj;
+ register struct monst *mon;
+ register tmp;
+
+ obj = getobj("#)", "throw"); /* it is also possible to throw food */
+ /* (or jewels, or iron balls ... ) */
+ if(!obj || !getdir(1)) /* ask "in what direction?" */
+ return(0);
+ if(obj->owornmask & (W_ARMOR | W_RING)){
+ pline("You can't throw something you are wearing.");
+ return(0);
+ }
+
+ u_wipe_engr(2);
+
+ if(obj == uwep){
+ if(obj->cursed){
+ pline("Your weapon is welded to your hand.");
+ return(1);
+ }
+ if(obj->quan > 1)
+ setuwep(splitobj(obj, 1));
+ else
+ setuwep((struct obj *) 0);
+ }
+ else if(obj->quan > 1)
+ (void) splitobj(obj, 1);
+ freeinv(obj);
+ if(u.uswallow) {
+ mon = u.ustuck;
+ bhitpos.x = mon->mx;
+ bhitpos.y = mon->my;
+ } else if(u.dz) {
+ if(u.dz < 0) {
+ pline("%s hits the ceiling, then falls back on top of your head.",
+ Doname(obj)); /* note: obj->quan == 1 */
+ if(obj->olet == POTION_SYM)
+ potionhit(&youmonst, obj);
+ else {
+ if(uarmh) pline("Fortunately, you are wearing a helmet!");
+ losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object");
+ dropy(obj);
+ }
+ } else {
+ pline("%s hits the floor.", Doname(obj));
+ if(obj->otyp == EXPENSIVE_CAMERA) {
+ pline("It is shattered in a thousand pieces!");
+ obfree(obj, Null(obj));
+ } else if(obj->otyp == EGG) {
+ pline("\"Splash!\"");
+ obfree(obj, Null(obj));
+ } else if(obj->olet == POTION_SYM) {
+ pline("The flask breaks, and you smell a peculiar odor ...");
+ potionbreathe(obj);
+ obfree(obj, Null(obj));
+ } else {
+ dropy(obj);
+ }
+ }
+ return(1);
+ } else if(obj->otyp == BOOMERANG) {
+ mon = boomhit(u.dx, u.dy);
+ if(mon == &youmonst) { /* the thing was caught */
+ (void) addinv(obj);
+ return(1);
+ }
+ } else {
+ if(obj->otyp == PICK_AXE && shkcatch(obj))
+ return(1);
+
+ mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 :
+ (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1,
+ obj->olet,
+ (int (*)()) 0, (int (*)()) 0, obj);
+ }
+ if(mon) {
+ /* awake monster if sleeping */
+ wakeup(mon);
+
+ if(obj->olet == WEAPON_SYM) {
+ tmp = -1+u.ulevel+mon->data->ac+abon();
+ if(obj->otyp < ROCK) {
+ if(!uwep ||
+ uwep->otyp != obj->otyp+(BOW-ARROW))
+ tmp -= 4;
+ else {
+ tmp += uwep->spe;
+ }
+ } else
+ if(obj->otyp == BOOMERANG) tmp += 4;
+ tmp += obj->spe;
+ if(u.uswallow || tmp >= rnd(20)) {
+ if(hmon(mon,obj,1) == TRUE){
+ /* mon still alive */
+#ifndef NOWORM
+ cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
+#endif NOWORM
+ } else mon = 0;
+ /* weapons thrown disappear sometimes */
+ if(obj->otyp < BOOMERANG && rn2(3)) {
+ /* check bill; free */
+ obfree(obj, (struct obj *) 0);
+ return(1);
+ }
+ } else miss(objects[obj->otyp].oc_name, mon);
+ } else if(obj->otyp == HEAVY_IRON_BALL) {
+ tmp = -1+u.ulevel+mon->data->ac+abon();
+ if(!Punished || obj != uball) tmp += 2;
+ if(u.utrap) tmp -= 2;
+ if(u.uswallow || tmp >= rnd(20)) {
+ if(hmon(mon,obj,1) == FALSE)
+ mon = 0; /* he died */
+ } else miss("iron ball", mon);
+ } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) {
+ potionhit(mon, obj);
+ return(1);
+ } else {
+ if(cansee(bhitpos.x,bhitpos.y))
+ pline("You miss %s.",monnam(mon));
+ else pline("You miss it.");
+ if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
+ if(tamedog(mon,obj)) return(1);
+ if(obj->olet == GEM_SYM && mon->data->mlet == 'u' &&
+ !mon->mtame){
+ if(obj->dknown && objects[obj->otyp].oc_name_known){
+ if(objects[obj->otyp].g_val > 0){
+ u.uluck += 5;
+ goto valuable;
+ } else {
+ pline("%s is not interested in your junk.",
+ Monnam(mon));
+ }
+ } else { /* value unknown to @ */
+ u.uluck++;
+ valuable:
+ if(u.uluck > LUCKMAX) /* dan@ut-ngp */
+ u.uluck = LUCKMAX;
+ pline("%s graciously accepts your gift.",
+ Monnam(mon));
+ mpickobj(mon, obj);
+ rloc(mon);
+ return(1);
+ }
+ }
+ }
+ }
+ /* the code following might become part of dropy() */
+ if(obj->otyp == CRYSKNIFE)
+ obj->otyp = WORM_TOOTH;
+ obj->ox = bhitpos.x;
+ obj->oy = bhitpos.y;
+ obj->nobj = fobj;
+ fobj = obj;
+ /* prevent him from throwing articles to the exit and escaping */
+ /* subfrombill(obj); */
+ stackobj(obj);
+ if(Punished && obj == uball &&
+ (bhitpos.x != u.ux || bhitpos.y != u.uy)){
+ freeobj(uchain);
+ unpobj(uchain);
+ if(u.utrap){
+ if(u.utraptype == TT_PIT)
+ pline("The ball pulls you out of the pit!");
+ else {
+ register long side =
+ rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
+ pline("The ball pulls you out of the bear trap.");
+ pline("Your %s leg is severely damaged.",
+ (side == LEFT_SIDE) ? "left" : "right");
+ set_wounded_legs(side, 500+rn2(1000));
+ losehp(2, "thrown ball");
+ }
+ u.utrap = 0;
+ }
+ unsee();
+ uchain->nobj = fobj;
+ fobj = uchain;
+ u.ux = uchain->ox = bhitpos.x - u.dx;
+ u.uy = uchain->oy = bhitpos.y - u.dy;
+ setsee();
+ (void) inshop();
+ }
+ if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
+ return(1);
+}
+
+/* split obj so that it gets size num */
+/* remainder is put in the object structure delivered by this call */
+struct obj *
+splitobj(obj, num) register struct obj *obj; register int num; {
+register struct obj *otmp;
+ otmp = newobj(0);
+ *otmp = *obj; /* copies whole structure */
+ otmp->o_id = flags.ident++;
+ otmp->onamelth = 0;
+ obj->quan = num;
+ obj->owt = weight(obj);
+ otmp->quan -= num;
+ otmp->owt = weight(otmp); /* -= obj->owt ? */
+ obj->nobj = otmp;
+ if(obj->unpaid) splitbill(obj,otmp);
+ return(otmp);
+}
+
+more_experienced(exp,rexp)
+register int exp, rexp;
+{
+ extern char pl_character[];
+
+ u.uexp += exp;
+ u.urexp += 4*exp + rexp;
+ if(exp) flags.botl = 1;
+ if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000))
+ flags.beginner = 0;
+}
+
+set_wounded_legs(side, timex)
+register long side;
+register int timex;
+{
+ if(!Wounded_legs || (Wounded_legs & TIMEOUT))
+ Wounded_legs |= side + timex;
+ else
+ Wounded_legs |= side;
+}
+
+heal_legs()
+{
+ if(Wounded_legs) {
+ if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
+ pline("Your legs feel somewhat better.");
+ else
+ pline("Your leg feels somewhat better.");
+ Wounded_legs = 0;
+ }
+}
diff --git a/hack/hack.do_name.c b/hack/hack.do_name.c
new file mode 100644
index 00000000..72ac62c8
--- /dev/null
+++ b/hack/hack.do_name.c
@@ -0,0 +1,289 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.do_name.c - version 1.0.3 */
+
+#include "hack.h"
+#include <stdio.h>
+extern char plname[];
+
+coord
+getpos(force,goal) int force; char *goal; {
+register cx,cy,i,c;
+extern char sdir[]; /* defined in hack.c */
+extern schar xdir[], ydir[]; /* idem */
+extern char *visctrl(); /* see below */
+coord cc;
+ pline("(For instructions type a ?)");
+ cx = u.ux;
+ cy = u.uy;
+ curs(cx,cy+2);
+ while((c = readchar()) != '.'){
+ for(i=0; i<8; i++) if(sdir[i] == c){
+ if(1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
+ cx += xdir[i];
+ if(0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO-1)
+ cy += ydir[i];
+ goto nxtc;
+ }
+ if(c == '?'){
+ pline("Use [hjkl] to move the cursor to %s.", goal);
+ pline("Type a . when you are at the right place.");
+ } else {
+ pline("Unknown direction: '%s' (%s).",
+ visctrl(c),
+ force ? "use hjkl or ." : "aborted");
+ if(force) goto nxtc;
+ cc.x = -1;
+ cc.y = 0;
+ return(cc);
+ }
+ nxtc: ;
+ curs(cx,cy+2);
+ }
+ cc.x = cx;
+ cc.y = cy;
+ return(cc);
+}
+
+do_mname(){
+char buf[BUFSZ];
+coord cc;
+register int cx,cy,lth,i;
+register struct monst *mtmp, *mtmp2;
+extern char *lmonnam();
+ cc = getpos(0, "the monster you want to name");
+ cx = cc.x;
+ cy = cc.y;
+ if(cx < 0) return(0);
+ mtmp = m_at(cx,cy);
+ if(!mtmp){
+ if(cx == u.ux && cy == u.uy)
+ pline("This ugly monster is called %s and cannot be renamed.",
+ plname);
+ else
+ pline("There is no monster there.");
+ return(1);
+ }
+ if(mtmp->mimic){
+ pline("I see no monster there.");
+ return(1);
+ }
+ if(!cansee(cx,cy)) {
+ pline("I cannot see a monster there.");
+ return(1);
+ }
+ pline("What do you want to call %s? ", lmonnam(mtmp));
+ getlin(buf);
+ clrlin();
+ if(!*buf || *buf == '\033')
+ return(1);
+ lth = strlen(buf)+1;
+ if(lth > 63){
+ buf[62] = 0;
+ lth = 63;
+ }
+ mtmp2 = newmonst(mtmp->mxlth + lth);
+ *mtmp2 = *mtmp;
+ for(i=0; i<mtmp->mxlth; i++)
+ ((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
+ mtmp2->mnamelth = lth;
+ (void) strcpy(NAME(mtmp2), buf);
+ replmon(mtmp,mtmp2);
+ return(1);
+}
+
+/*
+ * This routine changes the address of obj . Be careful not to call it
+ * when there might be pointers around in unknown places. For now: only
+ * when obj is in the inventory.
+ */
+do_oname(obj) register struct obj *obj; {
+register struct obj *otmp, *otmp2;
+register lth;
+char buf[BUFSZ];
+ pline("What do you want to name %s? ", doname(obj));
+ getlin(buf);
+ clrlin();
+ if(!*buf || *buf == '\033')
+ return;
+ lth = strlen(buf)+1;
+ if(lth > 63){
+ buf[62] = 0;
+ lth = 63;
+ }
+ otmp2 = newobj(lth);
+ *otmp2 = *obj;
+ otmp2->onamelth = lth;
+ (void) strcpy(ONAME(otmp2), buf);
+
+ setworn((struct obj *) 0, obj->owornmask);
+ setworn(otmp2, otmp2->owornmask);
+
+ /* do freeinv(obj); etc. by hand in order to preserve
+ the position of this object in the inventory */
+ if(obj == invent) invent = otmp2;
+ else for(otmp = invent; ; otmp = otmp->nobj){
+ if(!otmp)
+ panic("Do_oname: cannot find obj.");
+ if(otmp->nobj == obj){
+ otmp->nobj = otmp2;
+ break;
+ }
+ }
+ /* obfree(obj, otmp2); /* now unnecessary: no pointers on bill */
+ free((char *) obj); /* let us hope nobody else saved a pointer */
+}
+
+ddocall()
+{
+ register struct obj *obj;
+
+ pline("Do you want to name an individual object? [ny] ");
+ switch(readchar()) {
+ case '\033':
+ break;
+ case 'y':
+ obj = getobj("#", "name");
+ if(obj) do_oname(obj);
+ break;
+ default:
+ obj = getobj("?!=/", "call");
+ if(obj) docall(obj);
+ }
+ return(0);
+}
+
+docall(obj)
+register struct obj *obj;
+{
+ char buf[BUFSZ];
+ struct obj otemp;
+ register char **str1;
+ extern char *xname();
+ register char *str;
+
+ otemp = *obj;
+ otemp.quan = 1;
+ otemp.onamelth = 0;
+ str = xname(&otemp);
+ pline("Call %s %s: ", index(vowels,*str) ? "an" : "a", str);
+ getlin(buf);
+ clrlin();
+ if(!*buf || *buf == '\033')
+ return;
+ str = newstring(strlen(buf)+1);
+ (void) strcpy(str,buf);
+ str1 = &(objects[obj->otyp].oc_uname);
+ if(*str1) free(*str1);
+ *str1 = str;
+}
+
+char *ghostnames[] = { /* these names should have length < PL_NSIZ */
+ "adri", "andries", "andreas", "bert", "david", "dirk", "emile",
+ "frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
+ "kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
+ "tom", "wilmar"
+};
+
+char *
+xmonnam(mtmp, vb) register struct monst *mtmp; int vb; {
+static char buf[BUFSZ]; /* %% */
+extern char *shkname();
+ if(mtmp->mnamelth && !vb) {
+ (void) strcpy(buf, NAME(mtmp));
+ return(buf);
+ }
+ switch(mtmp->data->mlet) {
+ case ' ':
+ { register char *gn = (char *) mtmp->mextra;
+ if(!*gn) { /* might also look in scorefile */
+ gn = ghostnames[rn2(SIZE(ghostnames))];
+ if(!rn2(2)) (void)
+ strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn);
+ }
+ (void) sprintf(buf, "%s's ghost", gn);
+ }
+ break;
+ case '@':
+ if(mtmp->isshk) {
+ (void) strcpy(buf, shkname(mtmp));
+ break;
+ }
+ /* fall into next case */
+ default:
+ (void) sprintf(buf, "the %s%s",
+ mtmp->minvis ? "invisible " : "",
+ mtmp->data->mname);
+ }
+ if(vb && mtmp->mnamelth) {
+ (void) strcat(buf, " called ");
+ (void) strcat(buf, NAME(mtmp));
+ }
+ return(buf);
+}
+
+char *
+lmonnam(mtmp) register struct monst *mtmp; {
+ return(xmonnam(mtmp, 1));
+}
+
+char *
+monnam(mtmp) register struct monst *mtmp; {
+ return(xmonnam(mtmp, 0));
+}
+
+char *
+Monnam(mtmp) register struct monst *mtmp; {
+register char *bp = monnam(mtmp);
+ if('a' <= *bp && *bp <= 'z') *bp += ('A' - 'a');
+ return(bp);
+}
+
+char *
+amonnam(mtmp,adj)
+register struct monst *mtmp;
+register char *adj;
+{
+ register char *bp = monnam(mtmp);
+ static char buf[BUFSZ]; /* %% */
+
+ if(!strncmp(bp, "the ", 4)) bp += 4;
+ (void) sprintf(buf, "the %s %s", adj, bp);
+ return(buf);
+}
+
+char *
+Amonnam(mtmp, adj)
+register struct monst *mtmp;
+register char *adj;
+{
+ register char *bp = amonnam(mtmp,adj);
+
+ *bp = 'T';
+ return(bp);
+}
+
+char *
+Xmonnam(mtmp) register struct monst *mtmp; {
+register char *bp = Monnam(mtmp);
+ if(!strncmp(bp, "The ", 4)) {
+ bp += 2;
+ *bp = 'A';
+ }
+ return(bp);
+}
+
+char *
+visctrl(c)
+char c;
+{
+static char ccc[3];
+ if(c < 040) {
+ ccc[0] = '^';
+ ccc[1] = c + 0100;
+ ccc[2] = 0;
+ } else {
+ ccc[0] = c;
+ ccc[1] = 0;
+ }
+ return(ccc);
+}
diff --git a/hack/hack.do_wear.c b/hack/hack.do_wear.c
new file mode 100644
index 00000000..423955d2
--- /dev/null
+++ b/hack/hack.do_wear.c
@@ -0,0 +1,336 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.do_wear.c - version 1.0.3 */
+
+#include "hack.h"
+#include <stdio.h>
+extern char *nomovemsg;
+extern char quitchars[];
+extern char *Doname();
+
+off_msg(otmp) register struct obj *otmp; {
+ pline("You were wearing %s.", doname(otmp));
+}
+
+doremarm() {
+ register struct obj *otmp;
+ if(!uarm && !uarmh && !uarms && !uarmg) {
+ pline("Not wearing any armor.");
+ return(0);
+ }
+ otmp = (!uarmh && !uarms && !uarmg) ? uarm :
+ (!uarms && !uarm && !uarmg) ? uarmh :
+ (!uarmh && !uarm && !uarmg) ? uarms :
+ (!uarmh && !uarm && !uarms) ? uarmg :
+ getobj("[", "take off");
+ if(!otmp) return(0);
+ if(!(otmp->owornmask & (W_ARMOR - W_ARM2))) {
+ pline("You can't take that off.");
+ return(0);
+ }
+ if( otmp == uarmg && uwep && uwep->cursed ) { /* myers@uwmacc */
+ pline("You seem not able to take off the gloves while holding your weapon.");
+ return(0);
+ }
+ (void) armoroff(otmp);
+ return(1);
+}
+
+doremring() {
+ if(!uleft && !uright){
+ pline("Not wearing any ring.");
+ return(0);
+ }
+ if(!uleft)
+ return(dorr(uright));
+ if(!uright)
+ return(dorr(uleft));
+ if(uleft && uright) while(1) {
+ char answer;
+
+ pline("What ring, Right or Left? [ rl?]");
+ if(index(quitchars, (answer = readchar())))
+ return(0);
+ switch(answer) {
+ case 'l':
+ case 'L':
+ return(dorr(uleft));
+ case 'r':
+ case 'R':
+ return(dorr(uright));
+ case '?':
+ (void) doprring();
+ /* might look at morc here %% */
+ }
+ }
+ /* NOTREACHED */
+#ifdef lint
+ return(0);
+#endif lint
+}
+
+dorr(otmp) register struct obj *otmp; {
+ if(cursed(otmp)) return(0);
+ ringoff(otmp);
+ off_msg(otmp);
+ return(1);
+}
+
+cursed(otmp) register struct obj *otmp; {
+ if(otmp->cursed){
+ pline("You can't. It appears to be cursed.");
+ return(1);
+ }
+ return(0);
+}
+
+armoroff(otmp) register struct obj *otmp; {
+register int delay = -objects[otmp->otyp].oc_delay;
+ if(cursed(otmp)) return(0);
+ setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
+ if(delay) {
+ nomul(delay);
+ switch(otmp->otyp) {
+ case HELMET:
+ nomovemsg = "You finished taking off your helmet.";
+ break;
+ case PAIR_OF_GLOVES:
+ nomovemsg = "You finished taking off your gloves";
+ break;
+ default:
+ nomovemsg = "You finished taking off your suit.";
+ }
+ } else {
+ off_msg(otmp);
+ }
+ return(1);
+}
+
+doweararm() {
+ register struct obj *otmp;
+ register int delay;
+ register int err = 0;
+ long mask = 0;
+
+ otmp = getobj("[", "wear");
+ if(!otmp) return(0);
+ if(otmp->owornmask & W_ARMOR) {
+ pline("You are already wearing that!");
+ return(0);
+ }
+ if(otmp->otyp == HELMET){
+ if(uarmh) {
+ pline("You are already wearing a helmet.");
+ err++;
+ } else
+ mask = W_ARMH;
+ } else if(otmp->otyp == SHIELD){
+ if(uarms) pline("You are already wearing a shield."), err++;
+ if(uwep && uwep->otyp == TWO_HANDED_SWORD)
+ pline("You cannot wear a shield and wield a two-handed sword."), err++;
+ if(!err) mask = W_ARMS;
+ } else if(otmp->otyp == PAIR_OF_GLOVES) {
+ if(uarmg) {
+ pline("You are already wearing gloves.");
+ err++;
+ } else
+ if(uwep && uwep->cursed) {
+ pline("You cannot wear gloves over your weapon.");
+ err++;
+ } else
+ mask = W_ARMG;
+ } else {
+ if(uarm) {
+ if(otmp->otyp != ELVEN_CLOAK || uarm2) {
+ pline("You are already wearing some armor.");
+ err++;
+ }
+ }
+ if(!err) mask = W_ARM;
+ }
+ if(otmp == uwep && uwep->cursed) {
+ if(!err++)
+ pline("%s is welded to your hand.", Doname(uwep));
+ }
+ if(err) return(0);
+ setworn(otmp, mask);
+ if(otmp == uwep)
+ setuwep((struct obj *) 0);
+ delay = -objects[otmp->otyp].oc_delay;
+ if(delay){
+ nomul(delay);
+ nomovemsg = "You finished your dressing manoeuvre.";
+ }
+ otmp->known = 1;
+ return(1);
+}
+
+dowearring() {
+ register struct obj *otmp;
+ long mask = 0;
+ long oldprop;
+
+ if(uleft && uright){
+ pline("There are no more ring-fingers to fill.");
+ return(0);
+ }
+ otmp = getobj("=", "wear");
+ if(!otmp) return(0);
+ if(otmp->owornmask & W_RING) {
+ pline("You are already wearing that!");
+ return(0);
+ }
+ if(otmp == uleft || otmp == uright) {
+ pline("You are already wearing that.");
+ return(0);
+ }
+ if(otmp == uwep && uwep->cursed) {
+ pline("%s is welded to your hand.", Doname(uwep));
+ return(0);
+ }
+ if(uleft) mask = RIGHT_RING;
+ else if(uright) mask = LEFT_RING;
+ else do {
+ char answer;
+
+ pline("What ring-finger, Right or Left? ");
+ if(index(quitchars, (answer = readchar())))
+ return(0);
+ switch(answer){
+ case 'l':
+ case 'L':
+ mask = LEFT_RING;
+ break;
+ case 'r':
+ case 'R':
+ mask = RIGHT_RING;
+ break;
+ }
+ } while(!mask);
+ setworn(otmp, mask);
+ if(otmp == uwep)
+ setuwep((struct obj *) 0);
+ oldprop = u.uprops[PROP(otmp->otyp)].p_flgs;
+ u.uprops[PROP(otmp->otyp)].p_flgs |= mask;
+ switch(otmp->otyp){
+ case RIN_LEVITATION:
+ if(!oldprop) float_up();
+ break;
+ case RIN_PROTECTION_FROM_SHAPE_CHANGERS:
+ rescham();
+ break;
+ case RIN_GAIN_STRENGTH:
+ u.ustr += otmp->spe;
+ u.ustrmax += otmp->spe;
+ if(u.ustr > 118) u.ustr = 118;
+ if(u.ustrmax > 118) u.ustrmax = 118;
+ flags.botl = 1;
+ break;
+ case RIN_INCREASE_DAMAGE:
+ u.udaminc += otmp->spe;
+ break;
+ }
+ prinv(otmp);
+ return(1);
+}
+
+ringoff(obj)
+register struct obj *obj;
+{
+register long mask;
+ mask = obj->owornmask & W_RING;
+ setworn((struct obj *) 0, obj->owornmask);
+ if(!(u.uprops[PROP(obj->otyp)].p_flgs & mask))
+ impossible("Strange... I didnt know you had that ring.");
+ u.uprops[PROP(obj->otyp)].p_flgs &= ~mask;
+ switch(obj->otyp) {
+ case RIN_FIRE_RESISTANCE:
+ /* Bad luck if the player is in hell... --jgm */
+ if (!Fire_resistance && dlevel >= 30) {
+ pline("The flames of Hell burn you to a crisp.");
+ killer = "stupidity in hell";
+ done("burned");
+ }
+ break;
+ case RIN_LEVITATION:
+ if(!Levitation) { /* no longer floating */
+ float_down();
+ }
+ break;
+ case RIN_GAIN_STRENGTH:
+ u.ustr -= obj->spe;
+ u.ustrmax -= obj->spe;
+ if(u.ustr > 118) u.ustr = 118;
+ if(u.ustrmax > 118) u.ustrmax = 118;
+ flags.botl = 1;
+ break;
+ case RIN_INCREASE_DAMAGE:
+ u.udaminc -= obj->spe;
+ break;
+ }
+}
+
+find_ac(){
+register int uac = 10;
+ if(uarm) uac -= ARM_BONUS(uarm);
+ if(uarm2) uac -= ARM_BONUS(uarm2);
+ if(uarmh) uac -= ARM_BONUS(uarmh);
+ if(uarms) uac -= ARM_BONUS(uarms);
+ if(uarmg) uac -= ARM_BONUS(uarmg);
+ if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
+ if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
+ if(uac != u.uac){
+ u.uac = uac;
+ flags.botl = 1;
+ }
+}
+
+glibr(){
+register struct obj *otmp;
+int xfl = 0;
+ if(!uarmg) if(uleft || uright) {
+ /* Note: at present also cursed rings fall off */
+ pline("Your %s off your fingers.",
+ (uleft && uright) ? "rings slip" : "ring slips");
+ xfl++;
+ if((otmp = uleft) != Null(obj)){
+ ringoff(uleft);
+ dropx(otmp);
+ }
+ if((otmp = uright) != Null(obj)){
+ ringoff(uright);
+ dropx(otmp);
+ }
+ }
+ if((otmp = uwep) != Null(obj)){
+ /* Note: at present also cursed weapons fall */
+ setuwep((struct obj *) 0);
+ dropx(otmp);
+ pline("Your weapon %sslips from your hands.",
+ xfl ? "also " : "");
+ }
+}
+
+struct obj *
+some_armor(){
+register struct obj *otmph = uarm;
+ if(uarmh && (!otmph || !rn2(4))) otmph = uarmh;
+ if(uarmg && (!otmph || !rn2(4))) otmph = uarmg;
+ if(uarms && (!otmph || !rn2(4))) otmph = uarms;
+ return(otmph);
+}
+
+corrode_armor(){
+register struct obj *otmph = some_armor();
+ if(otmph){
+ if(otmph->rustfree ||
+ otmph->otyp == ELVEN_CLOAK ||
+ otmph->otyp == LEATHER_ARMOR ||
+ otmph->otyp == STUDDED_LEATHER_ARMOR) {
+ pline("Your %s not affected!",
+ aobjnam(otmph, "are"));
+ return;
+ }
+ pline("Your %s!", aobjnam(otmph, "corrode"));
+ otmph->spe--;
+ }
+}
diff --git a/hack/hack.dog.c b/hack/hack.dog.c
new file mode 100644
index 00000000..aa4387ab
--- /dev/null
+++ b/hack/hack.dog.c
@@ -0,0 +1,413 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.dog.c - version 1.0.3 */
+
+#include "hack.h"
+#include "hack.mfndpos.h"
+extern struct monst *makemon();
+#include "def.edog.h"
+#include "def.mkroom.h"
+
+struct permonst li_dog =
+ { "little dog", 'd',2,18,6,1,6,sizeof(struct edog) };
+struct permonst dog =
+ { "dog", 'd',4,16,5,1,6,sizeof(struct edog) };
+struct permonst la_dog =
+ { "large dog", 'd',6,15,4,2,4,sizeof(struct edog) };
+
+
+makedog(){
+register struct monst *mtmp = makemon(&li_dog,u.ux,u.uy);
+ if(!mtmp) return; /* dogs were genocided */
+ initedog(mtmp);
+}
+
+initedog(mtmp) register struct monst *mtmp; {
+ mtmp->mtame = mtmp->mpeaceful = 1;
+ EDOG(mtmp)->hungrytime = 1000 + moves;
+ EDOG(mtmp)->eattime = 0;
+ EDOG(mtmp)->droptime = 0;
+ EDOG(mtmp)->dropdist = 10000;
+ EDOG(mtmp)->apport = 10;
+ EDOG(mtmp)->whistletime = 0;
+}
+
+/* attach the monsters that went down (or up) together with @ */
+struct monst *mydogs = 0;
+struct monst *fallen_down = 0; /* monsters that fell through a trapdoor */
+ /* they will appear on the next level @ goes to, even if he goes up! */
+
+losedogs(){
+register struct monst *mtmp;
+ while(mtmp = mydogs){
+ mydogs = mtmp->nmon;
+ mtmp->nmon = fmon;
+ fmon = mtmp;
+ mnexto(mtmp);
+ }
+ while(mtmp = fallen_down){
+ fallen_down = mtmp->nmon;
+ mtmp->nmon = fmon;
+ fmon = mtmp;
+ rloc(mtmp);
+ }
+}
+
+keepdogs(){
+register struct monst *mtmp;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(dist(mtmp->mx,mtmp->my) < 3 && follower(mtmp)
+ && !mtmp->msleep && !mtmp->mfroz) {
+ relmon(mtmp);
+ mtmp->nmon = mydogs;
+ mydogs = mtmp;
+ unpmon(mtmp);
+ keepdogs(); /* we destroyed the link, so use recursion */
+ return; /* (admittedly somewhat primitive) */
+ }
+}
+
+fall_down(mtmp) register struct monst *mtmp; {
+ relmon(mtmp);
+ mtmp->nmon = fallen_down;
+ fallen_down = mtmp;
+ unpmon(mtmp);
+ mtmp->mtame = 0;
+}
+
+/* return quality of food; the lower the better */
+#define DOGFOOD 0
+#define CADAVER 1
+#define ACCFOOD 2
+#define MANFOOD 3
+#define APPORT 4
+#define POISON 5
+#define UNDEF 6
+dogfood(obj) register struct obj *obj; {
+ switch(obj->olet) {
+ case FOOD_SYM:
+ return(
+ (obj->otyp == TRIPE_RATION) ? DOGFOOD :
+ (obj->otyp < CARROT) ? ACCFOOD :
+ (obj->otyp < CORPSE) ? MANFOOD :
+ (poisonous(obj) || obj->age + 50 <= moves ||
+ obj->otyp == DEAD_COCKATRICE)
+ ? POISON : CADAVER
+ );
+ default:
+ if(!obj->cursed) return(APPORT);
+ /* fall into next case */
+ case BALL_SYM:
+ case CHAIN_SYM:
+ case ROCK_SYM:
+ return(UNDEF);
+ }
+}
+
+/* return 0 (no move), 1 (move) or 2 (dead) */
+dog_move(mtmp, after) register struct monst *mtmp; {
+register int nx,ny,omx,omy,appr,nearer,j;
+int udist,chi,i,whappr;
+register struct monst *mtmp2;
+register struct permonst *mdat = mtmp->data;
+register struct edog *edog = EDOG(mtmp);
+struct obj *obj;
+struct trap *trap;
+xchar cnt,chcnt,nix,niy;
+schar dogroom,uroom;
+xchar gx,gy,gtyp,otyp; /* current goal */
+coord poss[9];
+int info[9];
+#define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy))
+#define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy))
+
+ if(moves <= edog->eattime) return(0); /* dog is still eating */
+ omx = mtmp->mx;
+ omy = mtmp->my;
+ whappr = (moves - EDOG(mtmp)->whistletime < 5);
+ if(moves > edog->hungrytime + 500 && !mtmp->mconf){
+ mtmp->mconf = 1;
+ mtmp->mhpmax /= 3;
+ if(mtmp->mhp > mtmp->mhpmax)
+ mtmp->mhp = mtmp->mhpmax;
+ if(cansee(omx,omy))
+ pline("%s is confused from hunger.", Monnam(mtmp));
+ else pline("You feel worried about %s.", monnam(mtmp));
+ } else
+ if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){
+ if(cansee(omx,omy))
+ pline("%s dies from hunger.", Monnam(mtmp));
+ else
+ pline("You have a sad feeling for a moment, then it passes.");
+ mondied(mtmp);
+ return(2);
+ }
+ dogroom = inroom(omx,omy);
+ uroom = inroom(u.ux,u.uy);
+ udist = dist(omx,omy);
+
+ /* maybe we tamed him while being swallowed --jgm */
+ if(!udist) return(0);
+
+ /* if we are carrying sth then we drop it (perhaps near @) */
+ /* Note: if apport == 1 then our behaviour is independent of udist */
+ if(mtmp->minvent){
+ if(!rn2(udist) || !rn2((int) edog->apport))
+ if(rn2(10) < edog->apport){
+ relobj(mtmp, (int) mtmp->minvis);
+ if(edog->apport > 1) edog->apport--;
+ edog->dropdist = udist; /* hpscdi!jon */
+ edog->droptime = moves;
+ }
+ } else {
+ if(obj = o_at(omx,omy)) if(!index("0_", obj->olet)){
+ if((otyp = dogfood(obj)) <= CADAVER){
+ nix = omx;
+ niy = omy;
+ goto eatobj;
+ }
+ if(obj->owt < 10*mtmp->data->mlevel)
+ if(rn2(20) < edog->apport+3)
+ if(rn2(udist) || !rn2((int) edog->apport)){
+ freeobj(obj);
+ unpobj(obj);
+ /* if(levl[omx][omy].scrsym == obj->olet)
+ newsym(omx,omy); */
+ mpickobj(mtmp,obj);
+ }
+ }
+ }
+
+ /* first we look for food */
+ gtyp = UNDEF; /* no goal as yet */
+#ifdef LINT
+ gx = gy = 0; /* suppress 'used before set' message */
+#endif LINT
+ for(obj = fobj; obj; obj = obj->nobj) {
+ otyp = dogfood(obj);
+ if(otyp > gtyp || otyp == UNDEF) continue;
+ if(inroom(obj->ox,obj->oy) != dogroom) continue;
+ if(otyp < MANFOOD &&
+ (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) {
+ if(otyp < gtyp || (otyp == gtyp &&
+ DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){
+ gx = obj->ox;
+ gy = obj->oy;
+ gtyp = otyp;
+ }
+ } else
+ if(gtyp == UNDEF && dogroom >= 0 &&
+ uroom == dogroom &&
+ !mtmp->minvent && edog->apport > rn2(8)){
+ gx = obj->ox;
+ gy = obj->oy;
+ gtyp = APPORT;
+ }
+ }
+ if(gtyp == UNDEF ||
+ (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){
+ if(dogroom < 0 || dogroom == uroom){
+ gx = u.ux;
+ gy = u.uy;
+#ifndef QUEST
+ } else {
+ int tmp = rooms[dogroom].fdoor;
+ cnt = rooms[dogroom].doorct;
+
+ gx = gy = FAR; /* random, far away */
+ while(cnt--){
+ if(dist(gx,gy) >
+ dist(doors[tmp].x, doors[tmp].y)){
+ gx = doors[tmp].x;
+ gy = doors[tmp].y;
+ }
+ tmp++;
+ }
+ /* here gx == FAR e.g. when dog is in a vault */
+ if(gx == FAR || (gx == omx && gy == omy)){
+ gx = u.ux;
+ gy = u.uy;
+ }
+#endif QUEST
+ }
+ appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0;
+ if(after && udist <= 4 && gx == u.ux && gy == u.uy)
+ return(0);
+ if(udist > 1){
+ if(!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||
+ whappr ||
+ (mtmp->minvent && rn2((int) edog->apport)))
+ appr = 1;
+ }
+ /* if you have dog food he'll follow you more closely */
+ if(appr == 0){
+ obj = invent;
+ while(obj){
+ if(obj->otyp == TRIPE_RATION){
+ appr = 1;
+ break;
+ }
+ obj = obj->nobj;
+ }
+ }
+ } else appr = 1; /* gtyp != UNDEF */
+ if(mtmp->mconf) appr = 0;
+
+ if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)){
+ extern coord *gettrack();
+ register coord *cp;
+ cp = gettrack(omx,omy);
+ if(cp){
+ gx = cp->x;
+ gy = cp->y;
+ }
+ }
+
+ nix = omx;
+ niy = omy;
+ cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS);
+ chcnt = 0;
+ chi = -1;
+ for(i=0; i<cnt; i++){
+ nx = poss[i].x;
+ ny = poss[i].y;
+ if(info[i] & ALLOW_M){
+ mtmp2 = m_at(nx,ny);
+ if(mtmp2->data->mlevel >= mdat->mlevel+2 ||
+ mtmp2->data->mlet == 'c')
+ continue;
+ if(after) return(0); /* hit only once each move */
+
+ if(hitmm(mtmp, mtmp2) == 1 && rn2(4) &&
+ mtmp2->mlstmv != moves &&
+ hitmm(mtmp2,mtmp) == 2) return(2);
+ return(0);
+ }
+
+ /* dog avoids traps */
+ /* but perhaps we have to pass a trap in order to follow @ */
+ if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){
+ if(!trap->tseen && rn2(40)) continue;
+ if(rn2(10)) continue;
+ }
+
+ /* dog eschewes cursed objects */
+ /* but likes dog food */
+ obj = fobj;
+ while(obj){
+ if(obj->ox != nx || obj->oy != ny)
+ goto nextobj;
+ if(obj->cursed) goto nxti;
+ if(obj->olet == FOOD_SYM &&
+ (otyp = dogfood(obj)) < MANFOOD &&
+ (otyp < ACCFOOD || edog->hungrytime <= moves)){
+ /* Note: our dog likes the food so much that he
+ might eat it even when it conceals a cursed object */
+ nix = nx;
+ niy = ny;
+ chi = i;
+ eatobj:
+ edog->eattime =
+ moves + obj->quan * objects[obj->otyp].oc_delay;
+ if(edog->hungrytime < moves)
+ edog->hungrytime = moves;
+ edog->hungrytime +=
+ 5*obj->quan * objects[obj->otyp].nutrition;
+ mtmp->mconf = 0;
+ if(cansee(nix,niy))
+ pline("%s ate %s.", Monnam(mtmp), doname(obj));
+ /* perhaps this was a reward */
+ if(otyp != CADAVER)
+ edog->apport += 200/(edog->dropdist+moves-edog->droptime);
+ delobj(obj);
+ goto newdogpos;
+ }
+ nextobj:
+ obj = obj->nobj;
+ }
+
+ for(j=0; j<MTSZ && j<cnt-1; j++)
+ if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
+ if(rn2(4*(cnt-j))) goto nxti;
+
+/* Some stupid C compilers cannot compute the whole expression at once. */
+ nearer = GDIST(nx,ny);
+ nearer -= GDIST(nix,niy);
+ nearer *= appr;
+ if((nearer == 0 && !rn2(++chcnt)) || nearer<0 ||
+ (nearer > 0 && !whappr &&
+ ((omx == nix && omy == niy && !rn2(3))
+ || !rn2(12))
+ )){
+ nix = nx;
+ niy = ny;
+ if(nearer < 0) chcnt = 0;
+ chi = i;
+ }
+ nxti: ;
+ }
+newdogpos:
+ if(nix != omx || niy != omy){
+ if(info[chi] & ALLOW_U){
+ (void) hitu(mtmp, d(mdat->damn, mdat->damd)+1);
+ return(0);
+ }
+ mtmp->mx = nix;
+ mtmp->my = niy;
+ for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
+ mtmp->mtrack[0].x = omx;
+ mtmp->mtrack[0].y = omy;
+ }
+ if(mintrap(mtmp) == 2) /* he died */
+ return(2);
+ pmon(mtmp);
+ return(1);
+}
+
+/* return roomnumber or -1 */
+inroom(x,y) xchar x,y; {
+#ifndef QUEST
+ register struct mkroom *croom = &rooms[0];
+ while(croom->hx >= 0){
+ if(croom->hx >= x-1 && croom->lx <= x+1 &&
+ croom->hy >= y-1 && croom->ly <= y+1)
+ return(croom - rooms);
+ croom++;
+ }
+#endif QUEST
+ return(-1); /* not in room or on door */
+}
+
+tamedog(mtmp, obj)
+register struct monst *mtmp;
+register struct obj *obj;
+{
+ register struct monst *mtmp2;
+
+ if(flags.moonphase == FULL_MOON && night() && rn2(6))
+ return(0);
+
+ /* If we cannot tame him, at least he's no longer afraid. */
+ mtmp->mflee = 0;
+ mtmp->mfleetim = 0;
+ if(mtmp->mtame || mtmp->mfroz ||
+#ifndef NOWORM
+ mtmp->wormno ||
+#endif NOWORM
+ mtmp->isshk || mtmp->isgd || index(" &@12", mtmp->data->mlet))
+ return(0); /* no tame long worms? */
+ if(obj) {
+ if(dogfood(obj) >= MANFOOD) return(0);
+ if(cansee(mtmp->mx,mtmp->my)){
+ pline("%s devours the %s.", Monnam(mtmp),
+ objects[obj->otyp].oc_name);
+ }
+ obfree(obj, (struct obj *) 0);
+ }
+ mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
+ *mtmp2 = *mtmp;
+ mtmp2->mxlth = sizeof(struct edog);
+ if(mtmp->mnamelth) (void) strcpy(NAME(mtmp2), NAME(mtmp));
+ initedog(mtmp2);
+ replmon(mtmp,mtmp2);
+ return(1);
+}
diff --git a/hack/hack.eat.c b/hack/hack.eat.c
new file mode 100644
index 00000000..f1a76777
--- /dev/null
+++ b/hack/hack.eat.c
@@ -0,0 +1,459 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.eat.c - version 1.0.3 */
+
+#include "hack.h"
+char POISONOUS[] = "ADKSVabhks";
+extern char *nomovemsg;
+extern int (*afternmv)();
+extern int (*occupation)();
+extern char *occtxt;
+extern struct obj *splitobj(), *addinv();
+
+/* hunger texts used on bottom line (each 8 chars long) */
+#define SATIATED 0
+#define NOT_HUNGRY 1
+#define HUNGRY 2
+#define WEAK 3
+#define FAINTING 4
+#define FAINTED 5
+#define STARVED 6
+
+char *hu_stat[] = {
+ "Satiated",
+ " ",
+ "Hungry ",
+ "Weak ",
+ "Fainting",
+ "Fainted ",
+ "Starved "
+};
+
+init_uhunger(){
+ u.uhunger = 900;
+ u.uhs = NOT_HUNGRY;
+}
+
+#define TTSZ SIZE(tintxts)
+struct { char *txt; int nut; } tintxts[] = {
+ "It contains first quality peaches - what a surprise!", 40,
+ "It contains salmon - not bad!", 60,
+ "It contains apple juice - perhaps not what you hoped for.", 20,
+ "It contains some nondescript substance, tasting awfully.", 500,
+ "It contains rotten meat. You vomit.", -50,
+ "It turns out to be empty.", 0
+};
+
+static struct {
+ struct obj *tin;
+ int usedtime, reqtime;
+} tin;
+
+opentin(){
+ register int r;
+
+ if(!carried(tin.tin)) /* perhaps it was stolen? */
+ return(0); /* %% probably we should use tinoid */
+ if(tin.usedtime++ >= 50) {
+ pline("You give up your attempt to open the tin.");
+ return(0);
+ }
+ if(tin.usedtime < tin.reqtime)
+ return(1); /* still busy */
+
+ pline("You succeed in opening the tin.");
+ useup(tin.tin);
+ r = rn2(2*TTSZ);
+ if(r < TTSZ){
+ pline(tintxts[r].txt);
+ lesshungry(tintxts[r].nut);
+ if(r == 1) /* SALMON */ {
+ Glib = rnd(15);
+ pline("Eating salmon made your fingers very slippery.");
+ }
+ } else {
+ pline("It contains spinach - this makes you feel like Popeye!");
+ lesshungry(600);
+ if(u.ustr < 118)
+ u.ustr += rnd( ((u.ustr < 17) ? 19 : 118) - u.ustr);
+ if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
+ flags.botl = 1;
+ }
+ return(0);
+}
+
+Meatdone(){
+ u.usym = '@';
+ prme();
+}
+
+doeat(){
+ register struct obj *otmp;
+ register struct objclass *ftmp;
+ register tmp;
+
+ /* Is there some food (probably a heavy corpse) here on the ground? */
+ if(!Levitation)
+ for(otmp = fobj; otmp; otmp = otmp->nobj) {
+ if(otmp->ox == u.ux && otmp->oy == u.uy &&
+ otmp->olet == FOOD_SYM) {
+ pline("There %s %s here; eat %s? [ny] ",
+ (otmp->quan == 1) ? "is" : "are",
+ doname(otmp),
+ (otmp->quan == 1) ? "it" : "one");
+ if(readchar() == 'y') {
+ if(otmp->quan != 1)
+ (void) splitobj(otmp, 1);
+ freeobj(otmp);
+ otmp = addinv(otmp);
+ addtobill(otmp);
+ goto gotit;
+ }
+ }
+ }
+ otmp = getobj("%", "eat");
+ if(!otmp) return(0);
+gotit:
+ if(otmp->otyp == TIN){
+ if(uwep) {
+ switch(uwep->otyp) {
+ case CAN_OPENER:
+ tmp = 1;
+ break;
+ case DAGGER:
+ case CRYSKNIFE:
+ tmp = 3;
+ break;
+ case PICK_AXE:
+ case AXE:
+ tmp = 6;
+ break;
+ default:
+ goto no_opener;
+ }
+ pline("Using your %s you try to open the tin.",
+ aobjnam(uwep, (char *) 0));
+ } else {
+ no_opener:
+ pline("It is not so easy to open this tin.");
+ if(Glib) {
+ pline("The tin slips out of your hands.");
+ if(otmp->quan > 1) {
+ register struct obj *obj;
+ extern struct obj *splitobj();
+
+ obj = splitobj(otmp, 1);
+ if(otmp == uwep) setuwep(obj);
+ }
+ dropx(otmp);
+ return(1);
+ }
+ tmp = 10 + rn2(1 + 500/((int)(u.ulevel + u.ustr)));
+ }
+ tin.reqtime = tmp;
+ tin.usedtime = 0;
+ tin.tin = otmp;
+ occupation = opentin;
+ occtxt = "opening the tin";
+ return(1);
+ }
+ ftmp = &objects[otmp->otyp];
+ multi = -ftmp->oc_delay;
+ if(otmp->otyp >= CORPSE && eatcorpse(otmp)) goto eatx;
+ if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
+ pline("Blecch! Rotten food!");
+ if(!rn2(4)) {
+ pline("You feel rather light headed.");
+ Confusion += d(2,4);
+ } else if(!rn2(4)&& !Blind) {
+ pline("Everything suddenly goes dark.");
+ Blind = d(2,10);
+ seeoff(0);
+ } else if(!rn2(3)) {
+ if(Blind)
+ pline("The world spins and you slap against the floor.");
+ else
+ pline("The world spins and goes dark.");
+ nomul(-rnd(10));
+ nomovemsg = "You are conscious again.";
+ }
+ lesshungry(ftmp->nutrition / 4);
+ } else {
+ if(u.uhunger >= 1500) {
+ pline("You choke over your food.");
+ pline("You die...");
+ killer = ftmp->oc_name;
+ done("choked");
+ }
+ switch(otmp->otyp){
+ case FOOD_RATION:
+ if(u.uhunger <= 200)
+ pline("That food really hit the spot!");
+ else if(u.uhunger <= 700)
+ pline("That satiated your stomach!");
+ else {
+ pline("You're having a hard time getting all that food down.");
+ multi -= 2;
+ }
+ lesshungry(ftmp->nutrition);
+ if(multi < 0) nomovemsg = "You finished your meal.";
+ break;
+ case TRIPE_RATION:
+ pline("Yak - dog food!");
+ more_experienced(1,0);
+ flags.botl = 1;
+ if(rn2(2)){
+ pline("You vomit.");
+ morehungry(20);
+ if(Sick) {
+ Sick = 0; /* David Neves */
+ pline("What a relief!");
+ }
+ } else lesshungry(ftmp->nutrition);
+ break;
+ default:
+ if(otmp->otyp >= CORPSE)
+ pline("That %s tasted terrible!",ftmp->oc_name);
+ else
+ pline("That %s was delicious!",ftmp->oc_name);
+ lesshungry(ftmp->nutrition);
+ if(otmp->otyp == DEAD_LIZARD && (Confusion > 2))
+ Confusion = 2;
+ else
+#ifdef QUEST
+ if(otmp->otyp == CARROT && !Blind){
+ u.uhorizon++;
+ setsee();
+ pline("Your vision improves.");
+ } else
+#endif QUEST
+ if(otmp->otyp == FORTUNE_COOKIE) {
+ if(Blind) {
+ pline("This cookie has a scrap of paper inside!");
+ pline("What a pity, that you cannot read it!");
+ } else
+ outrumor();
+ } else
+ if(otmp->otyp == LUMP_OF_ROYAL_JELLY) {
+ /* This stuff seems to be VERY healthy! */
+ if(u.ustrmax < 118) u.ustrmax++;
+ if(u.ustr < u.ustrmax) u.ustr++;
+ u.uhp += rnd(20);
+ if(u.uhp > u.uhpmax) {
+ if(!rn2(17)) u.uhpmax++;
+ u.uhp = u.uhpmax;
+ }
+ heal_legs();
+ }
+ break;
+ }
+ }
+eatx:
+ if(multi<0 && !nomovemsg){
+ static char msgbuf[BUFSZ];
+ (void) sprintf(msgbuf, "You finished eating the %s.",
+ ftmp->oc_name);
+ nomovemsg = msgbuf;
+ }
+ useup(otmp);
+ return(1);
+}
+
+/* called in hack.main.c */
+gethungry(){
+ --u.uhunger;
+ if(moves % 2) {
+ if(Regeneration) u.uhunger--;
+ if(Hunger) u.uhunger--;
+ /* a3: if(Hunger & LEFT_RING) u.uhunger--;
+ if(Hunger & RIGHT_RING) u.uhunger--;
+ etc. */
+ }
+ if(moves % 20 == 0) { /* jimt@asgb */
+ if(uleft) u.uhunger--;
+ if(uright) u.uhunger--;
+ }
+ newuhs(TRUE);
+}
+
+/* called after vomiting and after performing feats of magic */
+morehungry(num) register num; {
+ u.uhunger -= num;
+ newuhs(TRUE);
+}
+
+/* called after eating something (and after drinking fruit juice) */
+lesshungry(num) register num; {
+ u.uhunger += num;
+ newuhs(FALSE);
+}
+
+unfaint(){
+ u.uhs = FAINTING;
+ flags.botl = 1;
+}
+
+newuhs(incr) boolean incr; {
+ register int newhs, h = u.uhunger;
+
+ newhs = (h > 1000) ? SATIATED :
+ (h > 150) ? NOT_HUNGRY :
+ (h > 50) ? HUNGRY :
+ (h > 0) ? WEAK : FAINTING;
+
+ if(newhs == FAINTING) {
+ if(u.uhs == FAINTED)
+ newhs = FAINTED;
+ if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
+ if(u.uhs != FAINTED && multi >= 0 /* %% */) {
+ pline("You faint from lack of food.");
+ nomul(-10+(u.uhunger/10));
+ nomovemsg = "You regain consciousness.";
+ afternmv = unfaint;
+ newhs = FAINTED;
+ }
+ } else
+ if(u.uhunger < -(int)(200 + 25*u.ulevel)) {
+ u.uhs = STARVED;
+ flags.botl = 1;
+ bot();
+ pline("You die from starvation.");
+ done("starved");
+ }
+ }
+
+ if(newhs != u.uhs) {
+ if(newhs >= WEAK && u.uhs < WEAK)
+ losestr(1); /* this may kill you -- see below */
+ else
+ if(newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax)
+ losestr(-1);
+ switch(newhs){
+ case HUNGRY:
+ pline((!incr) ? "You only feel hungry now." :
+ (u.uhunger < 145) ? "You feel hungry." :
+ "You are beginning to feel hungry.");
+ break;
+ case WEAK:
+ pline((!incr) ? "You feel weak now." :
+ (u.uhunger < 45) ? "You feel weak." :
+ "You are beginning to feel weak.");
+ break;
+ }
+ u.uhs = newhs;
+ flags.botl = 1;
+ if(u.uhp < 1) {
+ pline("You die from hunger and exhaustion.");
+ killer = "exhaustion";
+ done("starved");
+ }
+ }
+}
+
+#define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
+ ? 'a' + (otyp - DEAD_ACID_BLOB)\
+ : '@' + (otyp - DEAD_HUMAN))
+poisonous(otmp)
+register struct obj *otmp;
+{
+ return(index(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0);
+}
+
+/* returns 1 if some text was printed */
+eatcorpse(otmp) register struct obj *otmp; {
+register char let = CORPSE_I_TO_C(otmp->otyp);
+register tp = 0;
+ if(let != 'a' && moves > otmp->age + 50 + rn2(100)) {
+ tp++;
+ pline("Ulch -- that meat was tainted!");
+ pline("You get very sick.");
+ Sick = 10 + rn2(10);
+ u.usick_cause = objects[otmp->otyp].oc_name;
+ } else if(index(POISONOUS, let) && rn2(5)){
+ tp++;
+ pline("Ecch -- that must have been poisonous!");
+ if(!Poison_resistance){
+ losestr(rnd(4));
+ losehp(rnd(15), "poisonous corpse");
+ } else
+ pline("You don't seem affected by the poison.");
+ } else if(index("ELNOPQRUuxz", let) && rn2(5)){
+ tp++;
+ pline("You feel sick.");
+ losehp(rnd(8), "cadaver");
+ }
+ switch(let) {
+ case 'L':
+ case 'N':
+ case 't':
+ Teleportation |= INTRINSIC;
+ break;
+ case 'W':
+ pluslvl();
+ break;
+ case 'n':
+ u.uhp = u.uhpmax;
+ flags.botl = 1;
+ /* fall into next case */
+ case '@':
+ pline("You cannibal! You will be sorry for this!");
+ /* not tp++; */
+ /* fall into next case */
+ case 'd':
+ Aggravate_monster |= INTRINSIC;
+ break;
+ case 'I':
+ if(!Invis) {
+ Invis = 50+rn2(100);
+ if(!See_invisible)
+ newsym(u.ux, u.uy);
+ } else {
+ Invis |= INTRINSIC;
+ See_invisible |= INTRINSIC;
+ }
+ /* fall into next case */
+ case 'y':
+#ifdef QUEST
+ u.uhorizon++;
+#endif QUEST
+ /* fall into next case */
+ case 'B':
+ Confusion = 50;
+ break;
+ case 'D':
+ Fire_resistance |= INTRINSIC;
+ break;
+ case 'E':
+ Telepat |= INTRINSIC;
+ break;
+ case 'F':
+ case 'Y':
+ Cold_resistance |= INTRINSIC;
+ break;
+ case 'k':
+ case 's':
+ Poison_resistance |= INTRINSIC;
+ break;
+ case 'c':
+ pline("You turn to stone.");
+ killer = "dead cockatrice";
+ done("died");
+ /* NOTREACHED */
+ case 'a':
+ if(Stoned) {
+ pline("What a pity - you just destroyed a future piece of art!");
+ tp++;
+ Stoned = 0;
+ }
+ break;
+ case 'M':
+ pline("You cannot resist the temptation to mimic a treasure chest.");
+ tp++;
+ nomul(-30);
+ afternmv = Meatdone;
+ nomovemsg = "You now again prefer mimicking a human.";
+ u.usym = '$';
+ prme();
+ break;
+ }
+ return(tp);
+}
diff --git a/hack/hack.end.c b/hack/hack.end.c
new file mode 100644
index 00000000..0ddd2bd0
--- /dev/null
+++ b/hack/hack.end.c
@@ -0,0 +1,642 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.end.c - version 1.0.3 */
+
+#include "hack.h"
+#include <stdio.h>
+#include <signal.h>
+#define Sprintf (void) sprintf
+extern char plname[], pl_character[];
+extern char *itoa(), *ordin(), *eos();
+
+xchar maxdlevel = 1;
+
+void
+done1()
+{
+ (void) signal(SIGINT,SIG_IGN);
+ pline("Really quit?");
+ if(readchar() != 'y') {
+ (void) signal(SIGINT,done1);
+ clrlin();
+ (void) fflush(stdout);
+ if(multi > 0) nomul(0);
+ return;
+ }
+ done("quit");
+ /* NOTREACHED */
+}
+
+int done_stopprint;
+int done_hup;
+
+void
+done_intr(){
+ done_stopprint++;
+ (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGQUIT, SIG_IGN);
+}
+
+void
+done_hangup(){
+ done_hup++;
+ (void) signal(SIGHUP, SIG_IGN);
+ done_intr();
+}
+
+done_in_by(mtmp) register struct monst *mtmp; {
+static char buf[BUFSZ];
+ pline("You die ...");
+ if(mtmp->data->mlet == ' '){
+ Sprintf(buf, "the ghost of %s", (char *) mtmp->mextra);
+ killer = buf;
+ } else if(mtmp->mnamelth) {
+ Sprintf(buf, "%s called %s",
+ mtmp->data->mname, NAME(mtmp));
+ killer = buf;
+ } else if(mtmp->minvis) {
+ Sprintf(buf, "invisible %s", mtmp->data->mname);
+ killer = buf;
+ } else killer = mtmp->data->mname;
+ done("died");
+}
+
+/* called with arg "died", "drowned", "escaped", "quit", "choked", "panicked",
+ "burned", "starved" or "tricked" */
+/* Be careful not to call panic from here! */
+done(st1)
+register char *st1;
+{
+
+#ifdef WIZARD
+ if(wizard && *st1 == 'd'){
+ u.uswldtim = 0;
+ if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */
+ u.uhp = u.uhpmax;
+ pline("For some reason you are still alive.");
+ flags.move = 0;
+ if(multi > 0) multi = 0; else multi = -1;
+ flags.botl = 1;
+ return;
+ }
+#endif WIZARD
+ (void) signal(SIGINT, done_intr);
+ (void) signal(SIGQUIT, done_intr);
+ (void) signal(SIGHUP, done_hangup);
+ if(*st1 == 'q' && u.uhp < 1){
+ st1 = "died";
+ killer = "quit while already on Charon's boat";
+ }
+ if(*st1 == 's') killer = "starvation"; else
+ if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else
+ if(*st1 == 'p') killer = "panic"; else
+ if(*st1 == 't') killer = "trickery"; else
+ if(!index("bcd", *st1)) killer = st1;
+ paybill();
+ clearlocks();
+ if(flags.toplin == 1) more();
+ if(index("bcds", *st1)){
+#ifdef WIZARD
+ if(!wizard)
+#endif WIZARD
+ savebones();
+ if(!flags.notombstone)
+ outrip();
+ }
+ if(*st1 == 'c') killer = st1; /* after outrip() */
+ settty((char *) 0); /* does a clear_screen() */
+ if(!done_stopprint)
+ printf("Goodbye %s %s...\n\n", pl_character, plname);
+ { long int tmp;
+ tmp = u.ugold - u.ugold0;
+ if(tmp < 0)
+ tmp = 0;
+ if(*st1 == 'd' || *st1 == 'b')
+ tmp -= tmp/10;
+ u.urexp += tmp;
+ u.urexp += 50 * maxdlevel;
+ if(maxdlevel > 20)
+ u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20);
+ }
+ if(*st1 == 'e') {
+ extern struct monst *mydogs;
+ register struct monst *mtmp;
+ register struct obj *otmp;
+ register int i;
+ register unsigned worthlessct = 0;
+ boolean has_amulet = FALSE;
+
+ killer = st1;
+ keepdogs();
+ mtmp = mydogs;
+ if(mtmp) {
+ if(!done_stopprint) printf("You");
+ while(mtmp) {
+ if(!done_stopprint)
+ printf(" and %s", monnam(mtmp));
+ if(mtmp->mtame)
+ u.urexp += mtmp->mhp;
+ mtmp = mtmp->nmon;
+ }
+ if(!done_stopprint)
+ printf("\nescaped from the dungeon with %ld points,\n",
+ u.urexp);
+ } else
+ if(!done_stopprint)
+ printf("You escaped from the dungeon with %ld points,\n",
+ u.urexp);
+ for(otmp = invent; otmp; otmp = otmp->nobj) {
+ if(otmp->olet == GEM_SYM){
+ objects[otmp->otyp].oc_name_known = 1;
+ i = otmp->quan*objects[otmp->otyp].g_val;
+ if(i == 0) {
+ worthlessct += otmp->quan;
+ continue;
+ }
+ u.urexp += i;
+ if(!done_stopprint)
+ printf("\t%s (worth %d Zorkmids),\n",
+ doname(otmp), i);
+ } else if(otmp->olet == AMULET_SYM) {
+ otmp->known = 1;
+ i = (otmp->spe < 0) ? 2 : 5000;
+ u.urexp += i;
+ if(!done_stopprint)
+ printf("\t%s (worth %d Zorkmids),\n",
+ doname(otmp), i);
+ if(otmp->spe >= 0) {
+ has_amulet = TRUE;
+ killer = "escaped (with amulet)";
+ }
+ }
+ }
+ if(worthlessct) if(!done_stopprint)
+ printf("\t%u worthless piece%s of coloured glass,\n",
+ worthlessct, plur(worthlessct));
+ if(has_amulet) u.urexp *= 2;
+ } else
+ if(!done_stopprint)
+ printf("You %s on dungeon level %d with %ld points,\n",
+ st1, dlevel, u.urexp);
+ if(!done_stopprint)
+ printf("and %ld piece%s of gold, after %ld move%s.\n",
+ u.ugold, plur(u.ugold), moves, plur(moves));
+ if(!done_stopprint)
+ printf("You were level %u with a maximum of %d hit points when you %s.\n",
+ u.ulevel, u.uhpmax, st1);
+ if(*st1 == 'e' && !done_stopprint){
+ getret(); /* all those pieces of coloured glass ... */
+ cls();
+ }
+#ifdef WIZARD
+ if(!wizard)
+#endif WIZARD
+ topten();
+ if(done_stopprint) printf("\n\n");
+ exit(0);
+}
+
+#define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry))
+#define NAMSZ 8
+#define DTHSZ 40
+#define PERSMAX 1
+#define POINTSMIN 1 /* must be > 0 */
+#define ENTRYMAX 100 /* must be >= 10 */
+#define PERS_IS_UID /* delete for PERSMAX per name; now per uid */
+struct toptenentry {
+ struct toptenentry *tt_next;
+ long int points;
+ int level,maxlvl,hp,maxhp;
+ int uid;
+ char plchar;
+ char sex;
+ char name[NAMSZ+1];
+ char death[DTHSZ+1];
+ char date[7]; /* yymmdd */
+} *tt_head;
+
+topten(){
+ int uid = getuid();
+ int rank, rank0 = -1, rank1 = 0;
+ int occ_cnt = PERSMAX;
+ register struct toptenentry *t0, *t1, *tprev;
+ char *recfile = RECORD;
+ char *reclock = "record_lock";
+ int sleepct = 300;
+ FILE *rfile;
+ register flg = 0;
+ extern char *getdate();
+#define HUP if(!done_hup)
+ while(link(recfile, reclock) == -1) {
+ HUP perror(reclock);
+ if(!sleepct--) {
+ HUP puts("I give up. Sorry.");
+ HUP puts("Perhaps there is an old record_lock around?");
+ return;
+ }
+ HUP printf("Waiting for access to record file. (%d)\n",
+ sleepct);
+ HUP (void) fflush(stdout);
+ sleep(1);
+ }
+ if(!(rfile = fopen(recfile,"r"))){
+ HUP puts("Cannot open record file!");
+ goto unlock;
+ }
+ HUP (void) putchar('\n');
+
+ /* create a new 'topten' entry */
+ t0 = newttentry();
+ t0->level = dlevel;
+ t0->maxlvl = maxdlevel;
+ t0->hp = u.uhp;
+ t0->maxhp = u.uhpmax;
+ t0->points = u.urexp;
+ t0->plchar = pl_character[0];
+ t0->sex = (flags.female ? 'F' : 'M');
+ t0->uid = uid;
+ (void) strncpy(t0->name, plname, NAMSZ);
+ (t0->name)[NAMSZ] = 0;
+ (void) strncpy(t0->death, killer, DTHSZ);
+ (t0->death)[DTHSZ] = 0;
+ (void) strcpy(t0->date, getdate());
+
+ /* assure minimum number of points */
+ if(t0->points < POINTSMIN)
+ t0->points = 0;
+
+ t1 = tt_head = newttentry();
+ tprev = 0;
+ /* rank0: -1 undefined, 0 not_on_list, n n_th on list */
+ for(rank = 1; ; ) {
+ if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
+ t1->date, &t1->uid,
+ &t1->level, &t1->maxlvl,
+ &t1->hp, &t1->maxhp, &t1->points,
+ &t1->plchar, &t1->sex, t1->name, t1->death) != 11
+ || t1->points < POINTSMIN)
+ t1->points = 0;
+ if(rank0 < 0 && t1->points < t0->points) {
+ rank0 = rank++;
+ if(tprev == 0)
+ tt_head = t0;
+ else
+ tprev->tt_next = t0;
+ t0->tt_next = t1;
+ occ_cnt--;
+ flg++; /* ask for a rewrite */
+ } else
+ tprev = t1;
+ if(t1->points == 0) break;
+ if(
+#ifdef PERS_IS_UID
+ t1->uid == t0->uid &&
+#else
+ strncmp(t1->name, t0->name, NAMSZ) == 0 &&
+#endif PERS_IS_UID
+ t1->plchar == t0->plchar && --occ_cnt <= 0){
+ if(rank0 < 0){
+ rank0 = 0;
+ rank1 = rank;
+ HUP printf("You didn't beat your previous score of %ld points.\n\n",
+ t1->points);
+ }
+ if(occ_cnt < 0){
+ flg++;
+ continue;
+ }
+ }
+ if(rank <= ENTRYMAX){
+ t1 = t1->tt_next = newttentry();
+ rank++;
+ }
+ if(rank > ENTRYMAX){
+ t1->points = 0;
+ break;
+ }
+ }
+ if(flg) { /* rewrite record file */
+ (void) fclose(rfile);
+ if(!(rfile = fopen(recfile,"w"))){
+ HUP puts("Cannot write record file\n");
+ goto unlock;
+ }
+
+ if(!done_stopprint) if(rank0 > 0){
+ if(rank0 <= 10)
+ puts("You made the top ten list!\n");
+ else
+ printf("You reached the %d%s place on the top %d list.\n\n",
+ rank0, ordin(rank0), ENTRYMAX);
+ }
+ }
+ if(rank0 == 0) rank0 = rank1;
+ if(rank0 <= 0) rank0 = rank;
+ if(!done_stopprint) outheader();
+ t1 = tt_head;
+ for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
+ if(flg) fprintf(rfile,"%6s %d %d %d %d %d %ld %c%c %s,%s\n",
+ t1->date, t1->uid,
+ t1->level, t1->maxlvl,
+ t1->hp, t1->maxhp, t1->points,
+ t1->plchar, t1->sex, t1->name, t1->death);
+ if(done_stopprint) continue;
+ if(rank > flags.end_top &&
+ (rank < rank0-flags.end_around || rank > rank0+flags.end_around)
+ && (!flags.end_own ||
+#ifdef PERS_IS_UID
+ t1->uid != t0->uid ))
+#else
+ strncmp(t1->name, t0->name, NAMSZ)))
+#endif PERS_IS_UID
+ continue;
+ if(rank == rank0-flags.end_around &&
+ rank0 > flags.end_top+flags.end_around+1 &&
+ !flags.end_own)
+ (void) putchar('\n');
+ if(rank != rank0)
+ (void) outentry(rank, t1, 0);
+ else if(!rank1)
+ (void) outentry(rank, t1, 1);
+ else {
+ int t0lth = outentry(0, t0, -1);
+ int t1lth = outentry(rank, t1, t0lth);
+ if(t1lth > t0lth) t0lth = t1lth;
+ (void) outentry(0, t0, t0lth);
+ }
+ }
+ if(rank0 >= rank) if(!done_stopprint)
+ (void) outentry(0, t0, 1);
+ (void) fclose(rfile);
+unlock:
+ (void) unlink(reclock);
+}
+
+outheader() {
+char linebuf[BUFSZ];
+register char *bp;
+ (void) strcpy(linebuf, "Number Points Name");
+ bp = eos(linebuf);
+ while(bp < linebuf + COLNO - 9) *bp++ = ' ';
+ (void) strcpy(bp, "Hp [max]");
+ puts(linebuf);
+}
+
+/* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */
+int
+outentry(rank,t1,so) register struct toptenentry *t1; {
+boolean quit = FALSE, killed = FALSE, starv = FALSE;
+char linebuf[BUFSZ];
+ linebuf[0] = 0;
+ if(rank) Sprintf(eos(linebuf), "%3d", rank);
+ else Sprintf(eos(linebuf), " ");
+ Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->name);
+ if(t1->plchar == 'X') Sprintf(eos(linebuf), " ");
+ else Sprintf(eos(linebuf), "-%c ", t1->plchar);
+ if(!strncmp("escaped", t1->death, 7)) {
+ if(!strcmp(" (with amulet)", t1->death+7))
+ Sprintf(eos(linebuf), "escaped the dungeon with amulet");
+ else
+ Sprintf(eos(linebuf), "escaped the dungeon [max level %d]",
+ t1->maxlvl);
+ } else {
+ if(!strncmp(t1->death,"quit",4)) {
+ quit = TRUE;
+ if(t1->maxhp < 3*t1->hp && t1->maxlvl < 4)
+ Sprintf(eos(linebuf), "cravenly gave up");
+ else
+ Sprintf(eos(linebuf), "quit");
+ }
+ else if(!strcmp(t1->death,"choked"))
+ Sprintf(eos(linebuf), "choked on %s food",
+ (t1->sex == 'F') ? "her" : "his");
+ else if(!strncmp(t1->death,"starv",5))
+ Sprintf(eos(linebuf), "starved to death"), starv = TRUE;
+ else Sprintf(eos(linebuf), "was killed"), killed = TRUE;
+ Sprintf(eos(linebuf), " on%s level %d",
+ (killed || starv) ? "" : " dungeon", t1->level);
+ if(t1->maxlvl != t1->level)
+ Sprintf(eos(linebuf), " [max %d]", t1->maxlvl);
+ if(quit && t1->death[4]) Sprintf(eos(linebuf), t1->death + 4);
+ }
+ if(killed) Sprintf(eos(linebuf), " by %s%s",
+ (!strncmp(t1->death, "trick", 5) || !strncmp(t1->death, "the ", 4))
+ ? "" :
+ index(vowels,*t1->death) ? "an " : "a ",
+ t1->death);
+ Sprintf(eos(linebuf), ".");
+ if(t1->maxhp) {
+ register char *bp = eos(linebuf);
+ char hpbuf[10];
+ int hppos;
+ Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-");
+ hppos = COLNO - 7 - strlen(hpbuf);
+ if(bp <= linebuf + hppos) {
+ while(bp < linebuf + hppos) *bp++ = ' ';
+ (void) strcpy(bp, hpbuf);
+ Sprintf(eos(bp), " [%d]", t1->maxhp);
+ }
+ }
+ if(so == 0) puts(linebuf);
+ else if(so > 0) {
+ register char *bp = eos(linebuf);
+ if(so >= COLNO) so = COLNO-1;
+ while(bp < linebuf + so) *bp++ = ' ';
+ *bp = 0;
+ standoutbeg();
+ fputs(linebuf,stdout);
+ standoutend();
+ (void) putchar('\n');
+ }
+ return(strlen(linebuf));
+}
+
+char *
+itoa(a) int a; {
+static char buf[12];
+ Sprintf(buf,"%d",a);
+ return(buf);
+}
+
+char *
+ordin(n) int n; {
+register int d = n%10;
+ return((d==0 || d>3 || n/10==1) ? "th" : (d==1) ? "st" :
+ (d==2) ? "nd" : "rd");
+}
+
+clearlocks(){
+register x;
+ (void) signal(SIGHUP,SIG_IGN);
+ for(x = maxdlevel; x >= 0; x--) {
+ glo(x);
+ (void) unlink(lock); /* not all levels need be present */
+ }
+}
+
+#ifdef NOSAVEONHANGUP
+hangup()
+{
+ (void) signal(SIGINT, SIG_IGN);
+ clearlocks();
+ exit(1);
+}
+#endif NOSAVEONHANGUP
+
+char *
+eos(s)
+register char *s;
+{
+ while(*s) s++;
+ return(s);
+}
+
+/* it is the callers responsibility to check that there is room for c */
+charcat(s,c) register char *s, c; {
+ while(*s) s++;
+ *s++ = c;
+ *s = 0;
+}
+
+/*
+ * Called with args from main if argc >= 0. In this case, list scores as
+ * requested. Otherwise, find scores for the current player (and list them
+ * if argc == -1).
+ */
+prscore(argc,argv) int argc; char **argv; {
+ extern char *hname;
+ char **players;
+ int playerct;
+ int rank;
+ register struct toptenentry *t1, *t2;
+ char *recfile = RECORD;
+ FILE *rfile;
+ register flg = 0;
+ register int i;
+#ifdef nonsense
+ long total_score = 0L;
+ char totchars[10];
+ int totcharct = 0;
+#endif nonsense
+ int outflg = (argc >= -1);
+#ifdef PERS_IS_UID
+ int uid = -1;
+#else
+ char *player0;
+#endif PERS_IS_UID
+
+ if(!(rfile = fopen(recfile,"r"))){
+ puts("Cannot open record file!");
+ return;
+ }
+
+ if(argc > 1 && !strncmp(argv[1], "-s", 2)){
+ if(!argv[1][2]){
+ argc--;
+ argv++;
+ } else if(!argv[1][3] && index("CFKSTWX", argv[1][2])) {
+ argv[1]++;
+ argv[1][0] = '-';
+ } else argv[1] += 2;
+ }
+ if(argc <= 1){
+#ifdef PERS_IS_UID
+ uid = getuid();
+ playerct = 0;
+#else
+ player0 = plname;
+ if(!*player0)
+ player0 = "hackplayer";
+ playerct = 1;
+ players = &player0;
+#endif PERS_IS_UID
+ } else {
+ playerct = --argc;
+ players = ++argv;
+ }
+ if(outflg) putchar('\n');
+
+ t1 = tt_head = newttentry();
+ for(rank = 1; ; rank++) {
+ if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
+ t1->date, &t1->uid,
+ &t1->level, &t1->maxlvl,
+ &t1->hp, &t1->maxhp, &t1->points,
+ &t1->plchar, &t1->sex, t1->name, t1->death) != 11)
+ t1->points = 0;
+ if(t1->points == 0) break;
+#ifdef PERS_IS_UID
+ if(!playerct && t1->uid == uid)
+ flg++;
+ else
+#endif PERS_IS_UID
+ for(i = 0; i < playerct; i++){
+ if(strcmp(players[i], "all") == 0 ||
+ strncmp(t1->name, players[i], NAMSZ) == 0 ||
+ (players[i][0] == '-' &&
+ players[i][1] == t1->plchar &&
+ players[i][2] == 0) ||
+ (digit(players[i][0]) && rank <= atoi(players[i])))
+ flg++;
+ }
+ t1 = t1->tt_next = newttentry();
+ }
+ (void) fclose(rfile);
+ if(!flg) {
+ if(outflg) {
+ printf("Cannot find any entries for ");
+ if(playerct < 1) printf("you.\n");
+ else {
+ if(playerct > 1) printf("any of ");
+ for(i=0; i<playerct; i++)
+ printf("%s%s", players[i], (i<playerct-1)?", ":".\n");
+ printf("Call is: %s -s [playernames]\n", hname);
+ }
+ }
+ return;
+ }
+
+ if(outflg) outheader();
+ t1 = tt_head;
+ for(rank = 1; t1->points != 0; rank++, t1 = t2) {
+ t2 = t1->tt_next;
+#ifdef PERS_IS_UID
+ if(!playerct && t1->uid == uid)
+ goto outwithit;
+ else
+#endif PERS_IS_UID
+ for(i = 0; i < playerct; i++){
+ if(strcmp(players[i], "all") == 0 ||
+ strncmp(t1->name, players[i], NAMSZ) == 0 ||
+ (players[i][0] == '-' &&
+ players[i][1] == t1->plchar &&
+ players[i][2] == 0) ||
+ (digit(players[i][0]) && rank <= atoi(players[i]))){
+ outwithit:
+ if(outflg)
+ (void) outentry(rank, t1, 0);
+#ifdef nonsense
+ total_score += t1->points;
+ if(totcharct < sizeof(totchars)-1)
+ totchars[totcharct++] = t1->plchar;
+#endif nonsense
+ break;
+ }
+ }
+ free((char *) t1);
+ }
+#ifdef nonsense
+ totchars[totcharct] = 0;
+
+ /* We would like to determine whether he is experienced. However,
+ the information collected here only tells about the scores/roles
+ that got into the topten (top 100?). We should maintain a
+ .hacklog or something in his home directory. */
+ flags.beginner = (total_score < 6000);
+ for(i=0; i<6; i++)
+ if(!index(totchars, "CFKSTWX"[i])) {
+ flags.beginner = 1;
+ if(!pl_character[0]) pl_character[0] = "CFKSTWX"[i];
+ break;
+ }
+#endif nonsense
+}
diff --git a/hack/hack.engrave.c b/hack/hack.engrave.c
new file mode 100644
index 00000000..dc16c39f
--- /dev/null
+++ b/hack/hack.engrave.c
@@ -0,0 +1,306 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.engrave.c - version 1.0.3 */
+
+#include "hack.h"
+
+extern char *nomovemsg;
+extern char nul[];
+extern struct obj zeroobj;
+struct engr {
+ struct engr *nxt_engr;
+ char *engr_txt;
+ xchar engr_x, engr_y;
+ unsigned engr_lth; /* for save & restore; not length of text */
+ long engr_time; /* moment engraving was (will be) finished */
+ xchar engr_type;
+#define DUST 1
+#define ENGRAVE 2
+#define BURN 3
+} *head_engr;
+
+struct engr *
+engr_at(x,y) register xchar x,y; {
+register struct engr *ep = head_engr;
+ while(ep) {
+ if(x == ep->engr_x && y == ep->engr_y)
+ return(ep);
+ ep = ep->nxt_engr;
+ }
+ return((struct engr *) 0);
+}
+
+sengr_at(s,x,y) register char *s; register xchar x,y; {
+register struct engr *ep = engr_at(x,y);
+register char *t;
+register int n;
+ if(ep && ep->engr_time <= moves) {
+ t = ep->engr_txt;
+/*
+ if(!strcmp(s,t)) return(1);
+*/
+ n = strlen(s);
+ while(*t) {
+ if(!strncmp(s,t,n)) return(1);
+ t++;
+ }
+ }
+ return(0);
+}
+
+u_wipe_engr(cnt)
+register int cnt;
+{
+ if(!u.uswallow && !Levitation)
+ wipe_engr_at(u.ux, u.uy, cnt);
+}
+
+wipe_engr_at(x,y,cnt) register xchar x,y,cnt; {
+register struct engr *ep = engr_at(x,y);
+register int lth,pos;
+char ch;
+ if(ep){
+ if((ep->engr_type != DUST) || Levitation) {
+ cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1;
+ }
+ lth = strlen(ep->engr_txt);
+ if(lth && cnt > 0 ) {
+ while(cnt--) {
+ pos = rn2(lth);
+ if((ch = ep->engr_txt[pos]) == ' ')
+ continue;
+ ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
+ }
+ }
+ while(lth && ep->engr_txt[lth-1] == ' ')
+ ep->engr_txt[--lth] = 0;
+ while(ep->engr_txt[0] == ' ')
+ ep->engr_txt++;
+ if(!ep->engr_txt[0]) del_engr(ep);
+ }
+}
+
+read_engr_at(x,y) register int x,y; {
+register struct engr *ep = engr_at(x,y);
+ if(ep && ep->engr_txt[0]) {
+ switch(ep->engr_type) {
+ case DUST:
+ pline("Something is written here in the dust.");
+ break;
+ case ENGRAVE:
+ pline("Something is engraved here on the floor.");
+ break;
+ case BURN:
+ pline("Some text has been burned here in the floor.");
+ break;
+ default:
+ impossible("Something is written in a very strange way.");
+ }
+ pline("You read: \"%s\".", ep->engr_txt);
+ }
+}
+
+make_engr_at(x,y,s)
+register int x,y;
+register char *s;
+{
+ register struct engr *ep;
+
+ if(ep = engr_at(x,y))
+ del_engr(ep);
+ ep = (struct engr *)
+ alloc((unsigned)(sizeof(struct engr) + strlen(s) + 1));
+ ep->nxt_engr = head_engr;
+ head_engr = ep;
+ ep->engr_x = x;
+ ep->engr_y = y;
+ ep->engr_txt = (char *)(ep + 1);
+ (void) strcpy(ep->engr_txt, s);
+ ep->engr_time = 0;
+ ep->engr_type = DUST;
+ ep->engr_lth = strlen(s) + 1;
+}
+
+doengrave(){
+register int len;
+register char *sp;
+register struct engr *ep, *oep = engr_at(u.ux,u.uy);
+char buf[BUFSZ];
+xchar type;
+int spct; /* number of leading spaces */
+register struct obj *otmp;
+ multi = 0;
+
+ if(u.uswallow) {
+ pline("You're joking. Hahaha!"); /* riv05!a3 */
+ return(0);
+ }
+
+ /* one may write with finger, weapon or wand */
+ otmp = getobj("#-)/", "write with");
+ if(!otmp) return(0);
+
+ if(otmp == &zeroobj)
+ otmp = 0;
+ if(otmp && otmp->otyp == WAN_FIRE && otmp->spe) {
+ type = BURN;
+ otmp->spe--;
+ } else {
+ /* first wield otmp */
+ if(otmp != uwep) {
+ if(uwep && uwep->cursed) {
+ /* Andreas Bormann */
+ pline("Since your weapon is welded to your hand,");
+ pline("you use the %s.", aobjnam(uwep, (char *) 0));
+ otmp = uwep;
+ } else {
+ if(!otmp)
+ pline("You are now empty-handed.");
+ else if(otmp->cursed)
+ pline("The %s %s to your hand!",
+ aobjnam(otmp, "weld"),
+ (otmp->quan == 1) ? "itself" : "themselves");
+ else
+ pline("You now wield %s.", doname(otmp));
+ setuwep(otmp);
+ }
+ }
+
+ if(!otmp)
+ type = DUST;
+ else
+ if(otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
+ otmp->otyp == CRYSKNIFE ||
+ otmp->otyp == LONG_SWORD || otmp->otyp == AXE) {
+ type = ENGRAVE;
+ if((int)otmp->spe <= -3) {
+ type = DUST;
+ pline("Your %s too dull for engraving.",
+ aobjnam(otmp, "are"));
+ if(oep && oep->engr_type != DUST) return(1);
+ }
+ } else type = DUST;
+ }
+ if(Levitation && type != BURN){ /* riv05!a3 */
+ pline("You can't reach the floor!");
+ return(1);
+ }
+ if(oep && oep->engr_type == DUST){
+ pline("You wipe out the message that was written here.");
+ del_engr(oep);
+ oep = 0;
+ }
+ if(type == DUST && oep){
+ pline("You cannot wipe out the message that is %s in the rock.",
+ (oep->engr_type == BURN) ? "burned" : "engraved");
+ return(1);
+ }
+
+ pline("What do you want to %s on the floor here? ",
+ (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
+ getlin(buf);
+ clrlin();
+ spct = 0;
+ sp = buf;
+ while(*sp == ' ') spct++, sp++;
+ len = strlen(sp);
+ if(!len || *buf == '\033') {
+ if(type == BURN) otmp->spe++;
+ return(0);
+ }
+
+ switch(type) {
+ case DUST:
+ case BURN:
+ if(len > 15) {
+ multi = -(len/10);
+ nomovemsg = "You finished writing.";
+ }
+ break;
+ case ENGRAVE: /* here otmp != 0 */
+ { int len2 = (otmp->spe + 3) * 2 + 1;
+
+ pline("Your %s dull.", aobjnam(otmp, "get"));
+ if(len2 < len) {
+ len = len2;
+ sp[len] = 0;
+ otmp->spe = -3;
+ nomovemsg = "You cannot engrave more.";
+ } else {
+ otmp->spe -= len/2;
+ nomovemsg = "You finished engraving.";
+ }
+ multi = -len;
+ }
+ break;
+ }
+ if(oep) len += strlen(oep->engr_txt) + spct;
+ ep = (struct engr *) alloc((unsigned)(sizeof(struct engr) + len + 1));
+ ep->nxt_engr = head_engr;
+ head_engr = ep;
+ ep->engr_x = u.ux;
+ ep->engr_y = u.uy;
+ sp = (char *)(ep + 1); /* (char *)ep + sizeof(struct engr) */
+ ep->engr_txt = sp;
+ if(oep) {
+ (void) strcpy(sp, oep->engr_txt);
+ (void) strcat(sp, buf);
+ del_engr(oep);
+ } else
+ (void) strcpy(sp, buf);
+ ep->engr_lth = len+1;
+ ep->engr_type = type;
+ ep->engr_time = moves-multi;
+
+ /* kludge to protect pline against excessively long texts */
+ if(len > BUFSZ-20) sp[BUFSZ-20] = 0;
+
+ return(1);
+}
+
+save_engravings(fd) int fd; {
+register struct engr *ep = head_engr;
+ while(ep) {
+ if(!ep->engr_lth || !ep->engr_txt[0]){
+ ep = ep->nxt_engr;
+ continue;
+ }
+ bwrite(fd, (char *) & (ep->engr_lth), sizeof(ep->engr_lth));
+ bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
+ ep = ep->nxt_engr;
+ }
+ bwrite(fd, (char *) nul, sizeof(unsigned));
+ head_engr = 0;
+}
+
+rest_engravings(fd) int fd; {
+register struct engr *ep;
+unsigned lth;
+ head_engr = 0;
+ while(1) {
+ mread(fd, (char *) &lth, sizeof(unsigned));
+ if(lth == 0) return;
+ ep = (struct engr *) alloc(sizeof(struct engr) + lth);
+ mread(fd, (char *) ep, sizeof(struct engr) + lth);
+ ep->nxt_engr = head_engr;
+ ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
+ head_engr = ep;
+ }
+}
+
+del_engr(ep) register struct engr *ep; {
+register struct engr *ept;
+ if(ep == head_engr)
+ head_engr = ep->nxt_engr;
+ else {
+ for(ept = head_engr; ept; ept = ept->nxt_engr) {
+ if(ept->nxt_engr == ep) {
+ ept->nxt_engr = ep->nxt_engr;
+ goto fnd;
+ }
+ }
+ impossible("Error in del_engr?");
+ return;
+ fnd: ;
+ }
+ free((char *) ep);
+}
diff --git a/hack/hack.fight.c b/hack/hack.fight.c
new file mode 100644
index 00000000..ede886d1
--- /dev/null
+++ b/hack/hack.fight.c
@@ -0,0 +1,358 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.fight.c - version 1.0.3 */
+
+#include "hack.h"
+extern struct permonst li_dog, dog, la_dog;
+extern char *exclam(), *xname();
+extern struct obj *mkobj_at();
+
+static boolean far_noise;
+static long noisetime;
+
+/* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */
+hitmm(magr,mdef) register struct monst *magr,*mdef; {
+register struct permonst *pa = magr->data, *pd = mdef->data;
+int hit;
+schar tmp;
+boolean vis;
+ if(index("Eauy", pa->mlet)) return(0);
+ if(magr->mfroz) return(0); /* riv05!a3 */
+ tmp = pd->ac + pa->mlevel;
+ if(mdef->mconf || mdef->mfroz || mdef->msleep){
+ tmp += 4;
+ if(mdef->msleep) mdef->msleep = 0;
+ }
+ hit = (tmp > rnd(20));
+ if(hit) mdef->msleep = 0;
+ vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
+ if(vis){
+ char buf[BUFSZ];
+ if(mdef->mimic) seemimic(mdef);
+ if(magr->mimic) seemimic(magr);
+ (void) sprintf(buf,"%s %s", Monnam(magr),
+ hit ? "hits" : "misses");
+ pline("%s %s.", buf, monnam(mdef));
+ } else {
+ boolean far = (dist(magr->mx, magr->my) > 15);
+ if(far != far_noise || moves-noisetime > 10) {
+ far_noise = far;
+ noisetime = moves;
+ pline("You hear some noises%s.",
+ far ? " in the distance" : "");
+ }
+ }
+ if(hit){
+ if(magr->data->mlet == 'c' && !magr->cham) {
+ magr->mhpmax += 3;
+ if(vis) pline("%s is turned to stone!", Monnam(mdef));
+ else if(mdef->mtame)
+ pline("You have a peculiarly sad feeling for a moment, then it passes.");
+ monstone(mdef);
+ hit = 2;
+ } else
+ if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) {
+ magr->mhpmax += 1 + rn2(pd->mlevel+1);
+ if(magr->mtame && magr->mhpmax > 8*pa->mlevel){
+ if(pa == &li_dog) magr->data = pa = &dog;
+ else if(pa == &dog) magr->data = pa = &la_dog;
+ }
+ if(vis) pline("%s is killed!", Monnam(mdef));
+ else if(mdef->mtame)
+ pline("You have a sad feeling for a moment, then it passes.");
+ mondied(mdef);
+ hit = 2;
+ }
+ }
+ return(hit);
+}
+
+/* drop (perhaps) a cadaver and remove monster */
+mondied(mdef) register struct monst *mdef; {
+register struct permonst *pd = mdef->data;
+ if(letter(pd->mlet) && rn2(3)){
+ (void) mkobj_at(pd->mlet,mdef->mx,mdef->my);
+ if(cansee(mdef->mx,mdef->my)){
+ unpmon(mdef);
+ atl(mdef->mx,mdef->my,fobj->olet);
+ }
+ stackobj(fobj);
+ }
+ mondead(mdef);
+}
+
+/* drop a rock and remove monster */
+monstone(mdef) register struct monst *mdef; {
+ extern char mlarge[];
+ if(index(mlarge, mdef->data->mlet))
+ mksobj_at(ENORMOUS_ROCK, mdef->mx, mdef->my);
+ else
+ mksobj_at(ROCK, mdef->mx, mdef->my);
+ if(cansee(mdef->mx, mdef->my)){
+ unpmon(mdef);
+ atl(mdef->mx,mdef->my,fobj->olet);
+ }
+ mondead(mdef);
+}
+
+
+fightm(mtmp) register struct monst *mtmp; {
+register struct monst *mon;
+ for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) {
+ if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3)
+ if(rn2(4))
+ return(hitmm(mtmp,mon));
+ }
+ return(-1);
+}
+
+/* u is hit by sth, but not a monster */
+thitu(tlev,dam,name)
+register tlev,dam;
+register char *name;
+{
+char buf[BUFSZ];
+ setan(name,buf);
+ if(u.uac + tlev <= rnd(20)) {
+ if(Blind) pline("It misses.");
+ else pline("You are almost hit by %s!", buf);
+ return(0);
+ } else {
+ if(Blind) pline("You are hit!");
+ else pline("You are hit by %s!", buf);
+ losehp(dam,name);
+ return(1);
+ }
+}
+
+char mlarge[] = "bCDdegIlmnoPSsTUwY',&";
+
+boolean
+hmon(mon,obj,thrown) /* return TRUE if mon still alive */
+register struct monst *mon;
+register struct obj *obj;
+register thrown;
+{
+ register tmp;
+ boolean hittxt = FALSE;
+
+ if(!obj){
+ tmp = rnd(2); /* attack with bare hands */
+ if(mon->data->mlet == 'c' && !uarmg){
+ pline("You hit the cockatrice with your bare hands.");
+ pline("You turn to stone ...");
+ done_in_by(mon);
+ }
+ } else if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE) {
+ if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG))
+ tmp = rnd(2);
+ else {
+ if(index(mlarge, mon->data->mlet)) {
+ tmp = rnd(objects[obj->otyp].wldam);
+ if(obj->otyp == TWO_HANDED_SWORD) tmp += d(2,6);
+ else if(obj->otyp == FLAIL) tmp += rnd(4);
+ } else {
+ tmp = rnd(objects[obj->otyp].wsdam);
+ }
+ tmp += obj->spe;
+ if(!thrown && obj == uwep && obj->otyp == BOOMERANG
+ && !rn2(3)){
+ pline("As you hit %s, the boomerang breaks into splinters.",
+ monnam(mon));
+ freeinv(obj);
+ setworn((struct obj *) 0, obj->owornmask);
+ obfree(obj, (struct obj *) 0);
+ tmp++;
+ }
+ }
+ if(mon->data->mlet == 'O' && obj->otyp == TWO_HANDED_SWORD &&
+ !strcmp(ONAME(obj), "Orcrist"))
+ tmp += rnd(10);
+ } else switch(obj->otyp) {
+ case HEAVY_IRON_BALL:
+ tmp = rnd(25); break;
+ case EXPENSIVE_CAMERA:
+ pline("You succeed in destroying your camera. Congratulations!");
+ freeinv(obj);
+ if(obj->owornmask)
+ setworn((struct obj *) 0, obj->owornmask);
+ obfree(obj, (struct obj *) 0);
+ return(TRUE);
+ case DEAD_COCKATRICE:
+ pline("You hit %s with the cockatrice corpse.",
+ monnam(mon));
+ if(mon->data->mlet == 'c') {
+ tmp = 1;
+ hittxt = TRUE;
+ break;
+ }
+ pline("%s is turned to stone!", Monnam(mon));
+ killed(mon);
+ return(FALSE);
+ case CLOVE_OF_GARLIC: /* no effect against demons */
+ if(index(UNDEAD, mon->data->mlet))
+ mon->mflee = 1;
+ tmp = 1;
+ break;
+ default:
+ /* non-weapons can damage because of their weight */
+ /* (but not too much) */
+ tmp = obj->owt/10;
+ if(tmp < 1) tmp = 1;
+ else tmp = rnd(tmp);
+ if(tmp > 6) tmp = 6;
+ }
+
+ /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */
+
+ tmp += u.udaminc + dbon();
+ if(u.uswallow) {
+ if((tmp -= u.uswldtim) <= 0) {
+ pline("Your arms are no longer able to hit.");
+ return(TRUE);
+ }
+ }
+ if(tmp < 1) tmp = 1;
+ mon->mhp -= tmp;
+ if(mon->mhp < 1) {
+ killed(mon);
+ return(FALSE);
+ }
+ if(mon->mtame && (!mon->mflee || mon->mfleetim)) {
+ mon->mflee = 1; /* Rick Richardson */
+ mon->mfleetim += 10*rnd(tmp);
+ }
+
+ if(!hittxt) {
+ if(thrown)
+ /* this assumes that we cannot throw plural things */
+ hit( xname(obj) /* or: objects[obj->otyp].oc_name */,
+ mon, exclam(tmp) );
+ else if(Blind)
+ pline("You hit it.");
+ else
+ pline("You hit %s%s", monnam(mon), exclam(tmp));
+ }
+
+ if(u.umconf && !thrown) {
+ if(!Blind) {
+ pline("Your hands stop glowing blue.");
+ if(!mon->mfroz && !mon->msleep)
+ pline("%s appears confused.",Monnam(mon));
+ }
+ mon->mconf = 1;
+ u.umconf = 0;
+ }
+ return(TRUE); /* mon still alive */
+}
+
+/* try to attack; return FALSE if monster evaded */
+/* u.dx and u.dy must be set */
+attack(mtmp)
+register struct monst *mtmp;
+{
+ schar tmp;
+ boolean malive = TRUE;
+ register struct permonst *mdat;
+ mdat = mtmp->data;
+
+ u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */
+
+ if(mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep &&
+ !mtmp->mconf && mtmp->mcansee && !rn2(7) &&
+ (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */
+ mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy))
+ return(FALSE);
+
+ if(mtmp->mimic){
+ if(!u.ustuck && !mtmp->mflee) u.ustuck = mtmp;
+ switch(levl[u.ux+u.dx][u.uy+u.dy].scrsym){
+ case '+':
+ pline("The door actually was a Mimic.");
+ break;
+ case '$':
+ pline("The chest was a Mimic!");
+ break;
+ default:
+ pline("Wait! That's a Mimic!");
+ }
+ wakeup(mtmp); /* clears mtmp->mimic */
+ return(TRUE);
+ }
+
+ wakeup(mtmp);
+
+ if(mtmp->mhide && mtmp->mundetected){
+ register struct obj *obj;
+
+ mtmp->mundetected = 0;
+ if((obj = o_at(mtmp->mx,mtmp->my)) && !Blind)
+ pline("Wait! There's a %s hiding under %s!",
+ mdat->mname, doname(obj));
+ return(TRUE);
+ }
+
+ tmp = u.uluck + u.ulevel + mdat->ac + abon();
+ if(uwep) {
+ if(uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE)
+ tmp += uwep->spe;
+ if(uwep->otyp == TWO_HANDED_SWORD) tmp -= 1;
+ else if(uwep->otyp == DAGGER) tmp += 2;
+ else if(uwep->otyp == CRYSKNIFE) tmp += 3;
+ else if(uwep->otyp == SPEAR &&
+ index("XDne", mdat->mlet)) tmp += 2;
+ }
+ if(mtmp->msleep) {
+ mtmp->msleep = 0;
+ tmp += 2;
+ }
+ if(mtmp->mfroz) {
+ tmp += 4;
+ if(!rn2(10)) mtmp->mfroz = 0;
+ }
+ if(mtmp->mflee) tmp += 2;
+ if(u.utrap) tmp -= 3;
+
+ /* with a lot of luggage, your agility diminishes */
+ tmp -= (inv_weight() + 40)/20;
+
+ if(tmp <= rnd(20) && !u.uswallow){
+ if(Blind) pline("You miss it.");
+ else pline("You miss %s.",monnam(mtmp));
+ } else {
+ /* we hit the monster; be careful: it might die! */
+
+ if((malive = hmon(mtmp,uwep,0)) == TRUE) {
+ /* monster still alive */
+ if(!rn2(25) && mtmp->mhp < mtmp->mhpmax/2) {
+ mtmp->mflee = 1;
+ if(!rn2(3)) mtmp->mfleetim = rnd(100);
+ if(u.ustuck == mtmp && !u.uswallow)
+ u.ustuck = 0;
+ }
+#ifndef NOWORM
+ if(mtmp->wormno)
+ cutworm(mtmp, u.ux+u.dx, u.uy+u.dy,
+ uwep ? uwep->otyp : 0);
+#endif NOWORM
+ }
+ if(mdat->mlet == 'a') {
+ if(rn2(2)) {
+ pline("You are splashed by the blob's acid!");
+ losehp_m(rnd(6), mtmp);
+ if(!rn2(30)) corrode_armor();
+ }
+ if(!rn2(6)) corrode_weapon();
+ }
+ }
+ if(malive && mdat->mlet == 'E' && canseemon(mtmp)
+ && !mtmp->mcan && rn2(3)) {
+ if(mtmp->mcansee) {
+ pline("You are frozen by the floating eye's gaze!");
+ nomul((u.ulevel > 6 || rn2(4)) ? rn1(20,-21) : -200);
+ } else {
+ pline("The blinded floating eye cannot defend itself.");
+ if(!rn2(500)) if((int)u.uluck > LUCKMIN) u.uluck--;
+ }
+ }
+ return(TRUE);
+}
diff --git a/hack/hack.fix b/hack/hack.fix
new file mode 100644
index 00000000..01e64602
--- /dev/null
+++ b/hack/hack.fix
@@ -0,0 +1,113 @@
+/***** unido:net.games.hack / ab / 7:23 pm Sep 13, 1985*/
+
+Recently hack (1.0.3) crashed with core dumps during some good games.
+The crashes occured in the onbill-routine. After investigating the core
+dump I found that the shopkeeper's bill was still to be paid. Normaly
+if you leave a shop the bill will be cleared and onbill() would not
+check it. But under certain conditions you can leave a shop without
+clearing the bill. The conditions are:
+
+ 1. You have to rob a shop in order to make the shopkeeper
+ follow you.
+
+ 2. After leaving the shop being followed by the shopkeeper
+ you must return to the shop...
+
+ 3. ...and then leave the unguarded shop again.
+ - The shopkeeper mustn't be present!
+
+If you climb the stairs to the previous level, chances are that your
+bill now contains much more items than allowed. If so the next call to
+onbill() will dump the core.
+
+Following is a context diff to fix the bug. Actually just the last hunk
+does the fix [it deletes two lines which have been inserted in 1.0.3],
+but I think the other fix was intended by the now deleted lines.
+
+ Andreas
+
+--
+Andreas Bormann ab@unido.UUCP
+University of Dortmund N 51 29' 05" E 07 24' 42"
+West Germany
+
+------ the diff follows:
+
+*** hack.shk.c.orig Sun Aug 4 12:07:51 1985
+--- hack.shk.c Fri Sep 13 14:29:52 1985
+***************
+*** 133,139
+ /* Did we just leave a shop? */
+ if(u.uinshop &&
+ (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
+- u.uinshop = 0;
+ if(shopkeeper) {
+ if(ESHK(shopkeeper)->billct) {
+ pline("Somehow you escaped the shop without paying!");
+
+--- 133,138 -----
+ /* Did we just leave a shop? */
+ if(u.uinshop &&
+ (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
+ if(shopkeeper) {
+ if(ESHK(shopkeeper)->billct) {
+ if(inroom(shopkeeper->mx, shopkeeper->my)
+***************
+*** 136,142
+ u.uinshop = 0;
+ if(shopkeeper) {
+ if(ESHK(shopkeeper)->billct) {
+! pline("Somehow you escaped the shop without paying!");
+ addupbill();
+ pline("You stole for a total worth of %ld zorkmids.",
+ total);
+
+--- 135,143 -----
+ (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
+ if(shopkeeper) {
+ if(ESHK(shopkeeper)->billct) {
+! if(inroom(shopkeeper->mx, shopkeeper->my)
+! == u.uinshop - 1) /* ab@unido */
+! pline("Somehow you escaped the shop without paying!");
+ addupbill();
+ pline("You stole for a total worth of %ld zorkmids.",
+ total);
+***************
+*** 149,154
+ shopkeeper = 0;
+ shlevel = 0;
+ }
+ }
+
+ /* Did we just enter a zoo of some kind? */
+
+--- 150,156 -----
+ shopkeeper = 0;
+ shlevel = 0;
+ }
++ u.uinshop = 0;
+ }
+
+ /* Did we just enter a zoo of some kind? */
+***************
+*** 183,190
+ findshk(roomno);
+ if(!shopkeeper) {
+ rooms[roomno].rtype = 0;
+- u.uinshop = 0;
+- } else if(inroom(shopkeeper->mx, shopkeeper->my) != roomno) {
+ u.uinshop = 0;
+ } else if(!u.uinshop){
+ if(!ESHK(shopkeeper)->visitct ||
+
+--- 185,190 -----
+ findshk(roomno);
+ if(!shopkeeper) {
+ rooms[roomno].rtype = 0;
+ u.uinshop = 0;
+ } else if(!u.uinshop){
+ if(!ESHK(shopkeeper)->visitct ||
+/* ---------- */
+
+
+
diff --git a/hack/hack.h b/hack/hack.h
new file mode 100644
index 00000000..58c02837
--- /dev/null
+++ b/hack/hack.h
@@ -0,0 +1,160 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.h - version 1.0.3 */
+
+#include "config.h"
+#include <string.h>
+
+#ifndef BSD
+#define index strchr
+#define rindex strrchr
+#endif BSD
+
+#define Null(type) ((struct type *) 0)
+
+#include "def.objclass.h"
+
+typedef struct {
+ xchar x,y;
+} coord;
+
+#include "def.monst.h" /* uses coord */
+#include "def.gold.h"
+#include "def.trap.h"
+#include "def.obj.h"
+#include "def.flag.h"
+
+#define plur(x) (((x) == 1) ? "" : "s")
+
+#define BUFSZ 256 /* for getlin buffers */
+#define PL_NSIZ 32 /* name of player, ghost, shopkeeper */
+
+#include "def.rm.h"
+#include "def.permonst.h"
+
+extern long *alloc();
+
+extern xchar xdnstair, ydnstair, xupstair, yupstair; /* stairs up and down. */
+
+extern xchar dlevel;
+#define newstring(x) (char *) alloc((unsigned)(x))
+#include "hack.onames.h"
+
+#define ON 1
+#define OFF 0
+
+extern struct obj *invent, *uwep, *uarm, *uarm2, *uarmh, *uarms, *uarmg,
+ *uleft, *uright, *fcobj;
+extern struct obj *uchain; /* defined iff PUNISHED */
+extern struct obj *uball; /* defined if PUNISHED */
+struct obj *o_at(), *getobj(), *sobj_at();
+
+struct prop {
+#define TIMEOUT 007777 /* mask */
+#define LEFT_RING W_RINGL /* 010000L */
+#define RIGHT_RING W_RINGR /* 020000L */
+#define INTRINSIC 040000L
+#define LEFT_SIDE LEFT_RING
+#define RIGHT_SIDE RIGHT_RING
+#define BOTH_SIDES (LEFT_SIDE | RIGHT_SIDE)
+ long p_flgs;
+ int (*p_tofn)(); /* called after timeout */
+};
+
+struct you {
+ xchar ux, uy;
+ schar dx, dy, dz; /* direction of move (or zap or ... ) */
+#ifdef QUEST
+ schar di; /* direction of FF */
+ xchar ux0, uy0; /* initial position FF */
+#endif QUEST
+ xchar udisx, udisy; /* last display pos */
+ char usym; /* usually '@' */
+ schar uluck;
+#define LUCKMAX 10 /* on moonlit nights 11 */
+#define LUCKMIN (-10)
+ int last_str_turn:3; /* 0: none, 1: half turn, 2: full turn */
+ /* +: turn right, -: turn left */
+ unsigned udispl:1; /* @ on display */
+ unsigned ulevel:4; /* 1 - 14 */
+#ifdef QUEST
+ unsigned uhorizon:7;
+#endif QUEST
+ unsigned utrap:3; /* trap timeout */
+ unsigned utraptype:1; /* defined if utrap nonzero */
+#define TT_BEARTRAP 0
+#define TT_PIT 1
+ unsigned uinshop:6; /* used only in shk.c - (roomno+1) of shop */
+
+
+/* perhaps these #define's should also be generated by makedefs */
+#define TELEPAT LAST_RING /* not a ring */
+#define Telepat u.uprops[TELEPAT].p_flgs
+#define FAST (LAST_RING+1) /* not a ring */
+#define Fast u.uprops[FAST].p_flgs
+#define CONFUSION (LAST_RING+2) /* not a ring */
+#define Confusion u.uprops[CONFUSION].p_flgs
+#define INVIS (LAST_RING+3) /* not a ring */
+#define Invis u.uprops[INVIS].p_flgs
+#define Invisible (Invis && !See_invisible)
+#define GLIB (LAST_RING+4) /* not a ring */
+#define Glib u.uprops[GLIB].p_flgs
+#define PUNISHED (LAST_RING+5) /* not a ring */
+#define Punished u.uprops[PUNISHED].p_flgs
+#define SICK (LAST_RING+6) /* not a ring */
+#define Sick u.uprops[SICK].p_flgs
+#define BLIND (LAST_RING+7) /* not a ring */
+#define Blind u.uprops[BLIND].p_flgs
+#define WOUNDED_LEGS (LAST_RING+8) /* not a ring */
+#define Wounded_legs u.uprops[WOUNDED_LEGS].p_flgs
+#define STONED (LAST_RING+9) /* not a ring */
+#define Stoned u.uprops[STONED].p_flgs
+#define PROP(x) (x-RIN_ADORNMENT) /* convert ring to index in uprops */
+ unsigned umconf:1;
+ char *usick_cause;
+ struct prop uprops[LAST_RING+10];
+
+ unsigned uswallow:1; /* set if swallowed by a monster */
+ unsigned uswldtim:4; /* time you have been swallowed */
+ unsigned uhs:3; /* hunger state - see hack.eat.c */
+ schar ustr,ustrmax;
+ schar udaminc;
+ schar uac;
+ int uhp,uhpmax;
+ long int ugold,ugold0,uexp,urexp;
+ int uhunger; /* refd only in eat.c and shk.c */
+ int uinvault;
+ struct monst *ustuck;
+ int nr_killed[CMNUM+2]; /* used for experience bookkeeping */
+};
+
+extern struct you u;
+
+extern char *traps[];
+extern char *monnam(), *Monnam(), *amonnam(), *Amonnam(),
+ *doname(), *aobjnam();
+extern char readchar();
+extern char vowels[];
+
+extern xchar curx,cury; /* cursor location on screen */
+
+extern coord bhitpos; /* place where thrown weapon falls to the ground */
+
+extern xchar seehx,seelx,seehy,seely; /* where to see*/
+extern char *save_cm,*killer;
+
+extern xchar dlevel, maxdlevel; /* dungeon level */
+
+extern long moves;
+
+extern int multi;
+
+
+extern char lock[];
+
+
+#define DIST(x1,y1,x2,y2) (((x1)-(x2))*((x1)-(x2)) + ((y1)-(y2))*((y1)-(y2)))
+
+#define PL_CSIZ 20 /* sizeof pl_character */
+#define MAX_CARR_CAP 120 /* so that boulders can be heavier */
+#define MAXLEVEL 40
+#define FAR (COLNO+2) /* position outside screen */
diff --git a/hack/hack.invent.c b/hack/hack.invent.c
new file mode 100644
index 00000000..c4620ca1
--- /dev/null
+++ b/hack/hack.invent.c
@@ -0,0 +1,863 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.invent.c - version 1.0.3 */
+
+#include "hack.h"
+#include <stdio.h>
+extern struct obj *splitobj();
+extern struct obj zeroobj;
+extern char morc;
+extern char quitchars[];
+char *xprname();
+
+#ifndef NOWORM
+#include "def.wseg.h"
+extern struct wseg *wsegs[32];
+#endif NOWORM
+
+#define NOINVSYM '#'
+
+static int lastinvnr = 51; /* 0 ... 51 */
+static
+assigninvlet(otmp)
+register struct obj *otmp;
+{
+ boolean inuse[52];
+ register int i;
+ register struct obj *obj;
+
+ for(i = 0; i < 52; i++) inuse[i] = FALSE;
+ for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
+ i = obj->invlet;
+ if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
+ if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
+ if(i == otmp->invlet) otmp->invlet = 0;
+ }
+ if((i = otmp->invlet) &&
+ (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
+ return;
+ for(i = lastinvnr+1; i != lastinvnr; i++) {
+ if(i == 52) { i = -1; continue; }
+ if(!inuse[i]) break;
+ }
+ otmp->invlet = (inuse[i] ? NOINVSYM :
+ (i < 26) ? ('a'+i) : ('A'+i-26));
+ lastinvnr = i;
+}
+
+struct obj *
+addinv(obj)
+register struct obj *obj;
+{
+ register struct obj *otmp;
+
+ /* merge or attach to end of chain */
+ if(!invent) {
+ invent = obj;
+ otmp = 0;
+ } else
+ for(otmp = invent; /* otmp */; otmp = otmp->nobj) {
+ if(merged(otmp, obj, 0))
+ return(otmp);
+ if(!otmp->nobj) {
+ otmp->nobj = obj;
+ break;
+ }
+ }
+ obj->nobj = 0;
+
+ if(flags.invlet_constant) {
+ assigninvlet(obj);
+ /*
+ * The ordering of the chain is nowhere significant
+ * so in case you prefer some other order than the
+ * historical one, change the code below.
+ */
+ if(otmp) { /* find proper place in chain */
+ otmp->nobj = 0;
+ if((invent->invlet ^ 040) > (obj->invlet ^ 040)) {
+ obj->nobj = invent;
+ invent = obj;
+ } else
+ for(otmp = invent; ; otmp = otmp->nobj) {
+ if(!otmp->nobj ||
+ (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){
+ obj->nobj = otmp->nobj;
+ otmp->nobj = obj;
+ break;
+ }
+ }
+ }
+ }
+
+ return(obj);
+}
+
+useup(obj)
+register struct obj *obj;
+{
+ if(obj->quan > 1){
+ obj->quan--;
+ obj->owt = weight(obj);
+ } else {
+ setnotworn(obj);
+ freeinv(obj);
+ obfree(obj, (struct obj *) 0);
+ }
+}
+
+freeinv(obj)
+register struct obj *obj;
+{
+ register struct obj *otmp;
+
+ if(obj == invent)
+ invent = invent->nobj;
+ else {
+ for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
+ if(!otmp->nobj) panic("freeinv");
+ otmp->nobj = obj->nobj;
+ }
+}
+
+/* destroy object in fobj chain (if unpaid, it remains on the bill) */
+delobj(obj) register struct obj *obj; {
+ freeobj(obj);
+ unpobj(obj);
+ obfree(obj, (struct obj *) 0);
+}
+
+/* unlink obj from chain starting with fobj */
+freeobj(obj) register struct obj *obj; {
+ register struct obj *otmp;
+
+ if(obj == fobj) fobj = fobj->nobj;
+ else {
+ for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj)
+ if(!otmp) panic("error in freeobj");
+ otmp->nobj = obj->nobj;
+ }
+}
+
+/* Note: freegold throws away its argument! */
+freegold(gold) register struct gold *gold; {
+ register struct gold *gtmp;
+
+ if(gold == fgold) fgold = gold->ngold;
+ else {
+ for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold)
+ if(!gtmp) panic("error in freegold");
+ gtmp->ngold = gold->ngold;
+ }
+ free((char *) gold);
+}
+
+deltrap(trap)
+register struct trap *trap;
+{
+ register struct trap *ttmp;
+
+ if(trap == ftrap)
+ ftrap = ftrap->ntrap;
+ else {
+ for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
+ ttmp->ntrap = trap->ntrap;
+ }
+ free((char *) trap);
+}
+
+struct wseg *m_atseg;
+
+struct monst *
+m_at(x,y)
+register x,y;
+{
+ register struct monst *mtmp;
+#ifndef NOWORM
+ register struct wseg *wtmp;
+#endif NOWORM
+
+ m_atseg = 0;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
+ if(mtmp->mx == x && mtmp->my == y)
+ return(mtmp);
+#ifndef NOWORM
+ if(mtmp->wormno){
+ for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)
+ if(wtmp->wx == x && wtmp->wy == y){
+ m_atseg = wtmp;
+ return(mtmp);
+ }
+ }
+#endif NOWORM
+ }
+ return(0);
+}
+
+struct obj *
+o_at(x,y)
+register x,y;
+{
+ register struct obj *otmp;
+
+ for(otmp = fobj; otmp; otmp = otmp->nobj)
+ if(otmp->ox == x && otmp->oy == y) return(otmp);
+ return(0);
+}
+
+struct obj *
+sobj_at(n,x,y)
+register n,x,y;
+{
+ register struct obj *otmp;
+
+ for(otmp = fobj; otmp; otmp = otmp->nobj)
+ if(otmp->ox == x && otmp->oy == y && otmp->otyp == n)
+ return(otmp);
+ return(0);
+}
+
+carried(obj) register struct obj *obj; {
+register struct obj *otmp;
+ for(otmp = invent; otmp; otmp = otmp->nobj)
+ if(otmp == obj) return(1);
+ return(0);
+}
+
+carrying(type)
+register int type;
+{
+ register struct obj *otmp;
+
+ for(otmp = invent; otmp; otmp = otmp->nobj)
+ if(otmp->otyp == type)
+ return(TRUE);
+ return(FALSE);
+}
+
+struct obj *
+o_on(id, objchn) unsigned int id; register struct obj *objchn; {
+ while(objchn) {
+ if(objchn->o_id == id) return(objchn);
+ objchn = objchn->nobj;
+ }
+ return((struct obj *) 0);
+}
+
+struct trap *
+t_at(x,y)
+register x,y;
+{
+ register struct trap *trap = ftrap;
+ while(trap) {
+ if(trap->tx == x && trap->ty == y) return(trap);
+ trap = trap->ntrap;
+ }
+ return(0);
+}
+
+struct gold *
+g_at(x,y)
+register x,y;
+{
+ register struct gold *gold = fgold;
+ while(gold) {
+ if(gold->gx == x && gold->gy == y) return(gold);
+ gold = gold->ngold;
+ }
+ return(0);
+}
+
+/* make dummy object structure containing gold - for temporary use only */
+struct obj *
+mkgoldobj(q)
+register long q;
+{
+ register struct obj *otmp;
+
+ otmp = newobj(0);
+ /* should set o_id etc. but otmp will be freed soon */
+ otmp->olet = '$';
+ u.ugold -= q;
+ OGOLD(otmp) = q;
+ flags.botl = 1;
+ return(otmp);
+}
+
+/*
+ * getobj returns:
+ * struct obj *xxx: object to do something with.
+ * (struct obj *) 0 error return: no object.
+ * &zeroobj explicitly no object (as in w-).
+ */
+struct obj *
+getobj(let,word)
+register char *let,*word;
+{
+ register struct obj *otmp;
+ register char ilet,ilet1,ilet2;
+ char buf[BUFSZ];
+ char lets[BUFSZ];
+ register int foo = 0, foo2;
+ register char *bp = buf;
+ xchar allowcnt = 0; /* 0, 1 or 2 */
+ boolean allowgold = FALSE;
+ boolean allowall = FALSE;
+ boolean allownone = FALSE;
+ xchar foox = 0;
+ long cnt;
+
+ if(*let == '0') let++, allowcnt = 1;
+ if(*let == '$') let++, allowgold = TRUE;
+ if(*let == '#') let++, allowall = TRUE;
+ if(*let == '-') let++, allownone = TRUE;
+ if(allownone) *bp++ = '-';
+ if(allowgold) *bp++ = '$';
+ if(bp > buf && bp[-1] == '-') *bp++ = ' ';
+
+ ilet = 'a';
+ for(otmp = invent; otmp; otmp = otmp->nobj){
+ if(!*let || index(let, otmp->olet)) {
+ bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
+
+ /* ugly check: remove inappropriate things */
+ if((!strcmp(word, "take off") &&
+ !(otmp->owornmask & (W_ARMOR - W_ARM2)))
+ || (!strcmp(word, "wear") &&
+ (otmp->owornmask & (W_ARMOR | W_RING)))
+ || (!strcmp(word, "wield") &&
+ (otmp->owornmask & W_WEP))) {
+ foo--;
+ foox++;
+ }
+ }
+ if(ilet == 'z') ilet = 'A'; else ilet++;
+ }
+ bp[foo] = 0;
+ if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
+ (void) strcpy(lets, bp); /* necessary since we destroy buf */
+ if(foo > 5) { /* compactify string */
+ foo = foo2 = 1;
+ ilet2 = bp[0];
+ ilet1 = bp[1];
+ while(ilet = bp[++foo2] = bp[++foo]){
+ if(ilet == ilet1+1){
+ if(ilet1 == ilet2+1)
+ bp[foo2 - 1] = ilet1 = '-';
+ else if(ilet2 == '-') {
+ bp[--foo2] = ++ilet1;
+ continue;
+ }
+ }
+ ilet2 = ilet1;
+ ilet1 = ilet;
+ }
+ }
+ if(!foo && !allowall && !allowgold && !allownone) {
+ pline("You don't have anything %sto %s.",
+ foox ? "else " : "", word);
+ return(0);
+ }
+ for(;;) {
+ if(!buf[0])
+ pline("What do you want to %s [*]? ", word);
+ else
+ pline("What do you want to %s [%s or ?*]? ",
+ word, buf);
+
+ cnt = 0;
+ ilet = readchar();
+ while(digit(ilet) && allowcnt) {
+ if (cnt < 100000000)
+ cnt = 10*cnt + (ilet - '0');
+ else
+ cnt = 999999999;
+ allowcnt = 2; /* signal presence of cnt */
+ ilet = readchar();
+ }
+ if(digit(ilet)) {
+ pline("No count allowed with this command.");
+ continue;
+ }
+ if(index(quitchars,ilet))
+ return((struct obj *)0);
+ if(ilet == '-') {
+ return(allownone ? &zeroobj : (struct obj *) 0);
+ }
+ if(ilet == '$') {
+ if(!allowgold){
+ pline("You cannot %s gold.", word);
+ continue;
+ }
+ if(!(allowcnt == 2 && cnt < u.ugold))
+ cnt = u.ugold;
+ return(mkgoldobj(cnt));
+ }
+ if(ilet == '?') {
+ doinv(lets);
+ if(!(ilet = morc)) continue;
+ /* he typed a letter (not a space) to more() */
+ } else if(ilet == '*') {
+ doinv((char *) 0);
+ if(!(ilet = morc)) continue;
+ /* ... */
+ }
+ if(flags.invlet_constant) {
+ for(otmp = invent; otmp; otmp = otmp->nobj)
+ if(otmp->invlet == ilet) break;
+ } else {
+ if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1;
+ ilet -= 'a';
+ for(otmp = invent; otmp && ilet;
+ ilet--, otmp = otmp->nobj) ;
+ }
+ if(!otmp) {
+ pline("You don't have that object.");
+ continue;
+ }
+ if(cnt < 0 || otmp->quan < cnt) {
+ pline("You don't have that many! [You have %u]"
+ , otmp->quan);
+ continue;
+ }
+ break;
+ }
+ if(!allowall && let && !index(let,otmp->olet)) {
+ pline("That is a silly thing to %s.",word);
+ return(0);
+ }
+ if(allowcnt == 2) { /* cnt given */
+ if(cnt == 0) return(0);
+ if(cnt != otmp->quan) {
+ register struct obj *obj;
+ obj = splitobj(otmp, (int) cnt);
+ if(otmp == uwep) setuwep(obj);
+ }
+ }
+ return(otmp);
+}
+
+ckunpaid(otmp) register struct obj *otmp; {
+ return( otmp->unpaid );
+}
+
+/* interactive version of getobj - used for Drop and Identify */
+/* return the number of times fn was called successfully */
+ggetobj(word, fn, max)
+char *word;
+int (*fn)(), max;
+{
+char buf[BUFSZ];
+register char *ip;
+register char sym;
+register int oletct = 0, iletct = 0;
+register boolean allflag = FALSE;
+char olets[20], ilets[20];
+int (*ckfn)() = (int (*)()) 0;
+xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */
+ if(!invent && !allowgold){
+ pline("You have nothing to %s.", word);
+ return(0);
+ } else {
+ register struct obj *otmp = invent;
+ register int uflg = 0;
+
+ if(allowgold) ilets[iletct++] = '$';
+ ilets[iletct] = 0;
+ while(otmp) {
+ if(!index(ilets, otmp->olet)){
+ ilets[iletct++] = otmp->olet;
+ ilets[iletct] = 0;
+ }
+ if(otmp->unpaid) uflg = 1;
+ otmp = otmp->nobj;
+ }
+ ilets[iletct++] = ' ';
+ if(uflg) ilets[iletct++] = 'u';
+ if(invent) ilets[iletct++] = 'a';
+ ilets[iletct] = 0;
+ }
+ pline("What kinds of thing do you want to %s? [%s] ",
+ word, ilets);
+ getlin(buf);
+ if(buf[0] == '\033') {
+ clrlin();
+ return(0);
+ }
+ ip = buf;
+ olets[0] = 0;
+ while(sym = *ip++){
+ if(sym == ' ') continue;
+ if(sym == '$') {
+ if(allowgold == 1)
+ (*fn)(mkgoldobj(u.ugold));
+ else if(!u.ugold)
+ pline("You have no gold.");
+ allowgold = 2;
+ } else
+ if(sym == 'a' || sym == 'A') allflag = TRUE; else
+ if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else
+ if(index("!%?[()=*/\"0", sym)){
+ if(!index(olets, sym)){
+ olets[oletct++] = sym;
+ olets[oletct] = 0;
+ }
+ }
+ else pline("You don't have any %c's.", sym);
+ }
+ if(allowgold == 2 && !oletct)
+ return(1); /* he dropped gold (or at least tried to) */
+ else
+ return(askchain(invent, olets, allflag, fn, ckfn, max));
+}
+
+/*
+ * Walk through the chain starting at objchn and ask for all objects
+ * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
+ * whether the action in question (i.e., fn) has to be performed.
+ * If allflag then no questions are asked. Max gives the max nr of
+ * objects to be treated. Return the number of objects treated.
+ */
+askchain(objchn, olets, allflag, fn, ckfn, max)
+struct obj *objchn;
+register char *olets;
+int allflag;
+int (*fn)(), (*ckfn)();
+int max;
+{
+register struct obj *otmp, *otmp2;
+register char sym, ilet;
+register int cnt = 0;
+ ilet = 'a'-1;
+ for(otmp = objchn; otmp; otmp = otmp2){
+ if(ilet == 'z') ilet = 'A'; else ilet++;
+ otmp2 = otmp->nobj;
+ if(olets && *olets && !index(olets, otmp->olet)) continue;
+ if(ckfn && !(*ckfn)(otmp)) continue;
+ if(!allflag) {
+ pline(xprname(otmp, ilet));
+ addtopl(" [nyaq]? ");
+ sym = readchar();
+ }
+ else sym = 'y';
+
+ switch(sym){
+ case 'a':
+ allflag = 1;
+ case 'y':
+ cnt += (*fn)(otmp);
+ if(--max == 0) goto ret;
+ case 'n':
+ default:
+ break;
+ case 'q':
+ goto ret;
+ }
+ }
+ pline(cnt ? "That was all." : "No applicable objects.");
+ret:
+ return(cnt);
+}
+
+obj_to_let(obj) /* should of course only be called for things in invent */
+register struct obj *obj;
+{
+ register struct obj *otmp;
+ register char ilet;
+
+ if(flags.invlet_constant)
+ return(obj->invlet);
+ ilet = 'a';
+ for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
+ if(++ilet > 'z') ilet = 'A';
+ return(otmp ? ilet : NOINVSYM);
+}
+
+prinv(obj)
+register struct obj *obj;
+{
+ pline(xprname(obj, obj_to_let(obj)));
+}
+
+static char *
+xprname(obj,let)
+register struct obj *obj;
+register char let;
+{
+ static char li[BUFSZ];
+
+ (void) sprintf(li, "%c - %s.",
+ flags.invlet_constant ? obj->invlet : let,
+ doname(obj));
+ return(li);
+}
+
+ddoinv()
+{
+ doinv((char *) 0);
+ return(0);
+}
+
+/* called with 0 or "": all objects in inventory */
+/* otherwise: all objects with (serial) letter in lets */
+doinv(lets)
+register char *lets;
+{
+ register struct obj *otmp;
+ register char ilet;
+ int ct = 0;
+ char any[BUFSZ];
+
+ morc = 0; /* just to be sure */
+
+ if(!invent){
+ pline("Not carrying anything.");
+ return;
+ }
+
+ cornline(0, (char *) 0);
+ ilet = 'a';
+ for(otmp = invent; otmp; otmp = otmp->nobj) {
+ if(flags.invlet_constant) ilet = otmp->invlet;
+ if(!lets || !*lets || index(lets, ilet)) {
+ cornline(1, xprname(otmp, ilet));
+ any[ct++] = ilet;
+ }
+ if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
+ }
+ any[ct] = 0;
+ cornline(2, any);
+}
+
+dotypeinv () /* free after Robert Viduya */
+/* Changed to one type only, so he doesnt have to type cr */
+{
+ char c, ilet;
+ char stuff[BUFSZ];
+ register int stct;
+ register struct obj *otmp;
+ boolean billx = inshop() && doinvbill(0);
+ boolean unpd = FALSE;
+
+ if (!invent && !u.ugold && !billx) {
+ pline ("You aren't carrying anything.");
+ return(0);
+ }
+
+ stct = 0;
+ if(u.ugold) stuff[stct++] = '$';
+ stuff[stct] = 0;
+ for(otmp = invent; otmp; otmp = otmp->nobj) {
+ if (!index (stuff, otmp->olet)) {
+ stuff[stct++] = otmp->olet;
+ stuff[stct] = 0;
+ }
+ if(otmp->unpaid)
+ unpd = TRUE;
+ }
+ if(unpd) stuff[stct++] = 'u';
+ if(billx) stuff[stct++] = 'x';
+ stuff[stct] = 0;
+
+ if(stct > 1) {
+ pline ("What type of object [%s] do you want an inventory of? ",
+ stuff);
+ c = readchar();
+ if(index(quitchars,c)) return(0);
+ } else
+ c = stuff[0];
+
+ if(c == '$')
+ return(doprgold());
+
+ if(c == 'x' || c == 'X') {
+ if(billx)
+ (void) doinvbill(1);
+ else
+ pline("No used-up objects on the shopping bill.");
+ return(0);
+ }
+
+ if((c == 'u' || c == 'U') && !unpd) {
+ pline("You are not carrying any unpaid objects.");
+ return(0);
+ }
+
+ stct = 0;
+ ilet = 'a';
+ for (otmp = invent; otmp; otmp = otmp -> nobj) {
+ if(flags.invlet_constant) ilet = otmp->invlet;
+ if (c == otmp -> olet || (c == 'u' && otmp -> unpaid))
+ stuff[stct++] = ilet;
+ if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
+ }
+ stuff[stct] = '\0';
+ if(stct == 0)
+ pline("You have no such objects.");
+ else
+ doinv (stuff);
+
+ return(0);
+}
+
+/* look at what is here */
+dolook() {
+ register struct obj *otmp, *otmp0;
+ register struct gold *gold;
+ char *verb = Blind ? "feel" : "see";
+ int ct = 0;
+
+ if(!u.uswallow) {
+ if(Blind) {
+ pline("You try to feel what is lying here on the floor.");
+ if(Levitation) { /* ab@unido */
+ pline("You cannot reach the floor!");
+ return(1);
+ }
+ }
+ otmp0 = o_at(u.ux, u.uy);
+ gold = g_at(u.ux, u.uy);
+ }
+
+ if(u.uswallow || (!otmp0 && !gold)) {
+ pline("You %s no objects here.", verb);
+ return(!!Blind);
+ }
+
+ cornline(0, "Things that are here:");
+ for(otmp = otmp0; otmp; otmp = otmp->nobj) {
+ if(otmp->ox == u.ux && otmp->oy == u.uy) {
+ ct++;
+ cornline(1, doname(otmp));
+ if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) {
+ pline("Touching the dead cockatrice is a fatal mistake ...");
+ pline("You die ...");
+ killer = "dead cockatrice";
+ done("died");
+ }
+ }
+ }
+
+ if(gold) {
+ char gbuf[30];
+
+ (void) sprintf(gbuf, "%ld gold piece%s",
+ gold->amount, plur(gold->amount));
+ if(!ct++)
+ pline("You %s here %s.", verb, gbuf);
+ else
+ cornline(1, gbuf);
+ }
+
+ if(ct == 1 && !gold) {
+ pline("You %s here %s.", verb, doname(otmp0));
+ cornline(3, (char *) 0);
+ }
+ if(ct > 1)
+ cornline(2, (char *) 0);
+ return(!!Blind);
+}
+
+stackobj(obj) register struct obj *obj; {
+register struct obj *otmp = fobj;
+ for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj)
+ if(otmp->ox == obj->ox && otmp->oy == obj->oy &&
+ merged(obj,otmp,1))
+ return;
+}
+
+/* merge obj with otmp and delete obj if types agree */
+merged(otmp,obj,lose) register struct obj *otmp, *obj; {
+ if(obj->otyp == otmp->otyp &&
+ obj->unpaid == otmp->unpaid &&
+ obj->spe == otmp->spe &&
+ obj->dknown == otmp->dknown &&
+ obj->cursed == otmp->cursed &&
+ (index("%*?!", obj->olet) ||
+ (obj->known == otmp->known &&
+ (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) {
+ otmp->quan += obj->quan;
+ otmp->owt += obj->owt;
+ if(lose) freeobj(obj);
+ obfree(obj,otmp); /* free(obj), bill->otmp */
+ return(1);
+ } else return(0);
+}
+
+/*
+ * Gold is no longer displayed; in fact, when you have a lot of money,
+ * it may take a while before you have counted it all.
+ * [Bug: d$ and pickup still tell you how much it was.]
+ */
+extern int (*occupation)();
+extern char *occtxt;
+static long goldcounted;
+
+countgold(){
+ if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) {
+ long eps = 0;
+ if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1));
+ pline("You probably have about %ld gold pieces.",
+ u.ugold + eps);
+ return(0); /* done */
+ }
+ return(1); /* continue */
+}
+
+doprgold(){
+ if(!u.ugold)
+ pline("You do not carry any gold.");
+ else if(u.ugold <= 500)
+ pline("You are carrying %ld gold pieces.", u.ugold);
+ else {
+ pline("You sit down in order to count your gold pieces.");
+ goldcounted = 500;
+ occupation = countgold;
+ occtxt = "counting your gold";
+ }
+ return(1);
+}
+
+/* --- end of gold counting section --- */
+
+doprwep(){
+ if(!uwep) pline("You are empty handed.");
+ else prinv(uwep);
+ return(0);
+}
+
+doprarm(){
+ if(!uarm && !uarmg && !uarms && !uarmh)
+ pline("You are not wearing any armor.");
+ else {
+ char lets[6];
+ register int ct = 0;
+
+ if(uarm) lets[ct++] = obj_to_let(uarm);
+ if(uarm2) lets[ct++] = obj_to_let(uarm2);
+ if(uarmh) lets[ct++] = obj_to_let(uarmh);
+ if(uarms) lets[ct++] = obj_to_let(uarms);
+ if(uarmg) lets[ct++] = obj_to_let(uarmg);
+ lets[ct] = 0;
+ doinv(lets);
+ }
+ return(0);
+}
+
+doprring(){
+ if(!uleft && !uright)
+ pline("You are not wearing any rings.");
+ else {
+ char lets[3];
+ register int ct = 0;
+
+ if(uleft) lets[ct++] = obj_to_let(uleft);
+ if(uright) lets[ct++] = obj_to_let(uright);
+ lets[ct] = 0;
+ doinv(lets);
+ }
+ return(0);
+}
+
+digit(c) char c; {
+ return(c >= '0' && c <= '9');
+}
diff --git a/hack/hack.ioctl.c b/hack/hack.ioctl.c
new file mode 100644
index 00000000..6669ceab
--- /dev/null
+++ b/hack/hack.ioctl.c
@@ -0,0 +1,53 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.ioctl.c - version 1.0.2 */
+
+/* This cannot be part of hack.tty.c (as it was earlier) since on some
+ systems (e.g. MUNIX) the include files <termio.h> and <sgtty.h>
+ define the same constants, and the C preprocessor complains. */
+#include <stdio.h>
+#include "config.h"
+#ifdef BSD
+#include <sgtty.h>
+struct ltchars ltchars, ltchars0;
+#else
+#include <termio.h> /* also includes part of <sgtty.h> */
+struct termio termio;
+#endif BSD
+
+getioctls() {
+#ifdef BSD
+ (void) ioctl(fileno(stdin), (int) TIOCGLTC, (char *) &ltchars);
+ (void) ioctl(fileno(stdin), (int) TIOCSLTC, (char *) &ltchars0);
+#else
+ (void) ioctl(fileno(stdin), (int) TCGETA, &termio);
+#endif BSD
+}
+
+setioctls() {
+#ifdef BSD
+ (void) ioctl(fileno(stdin), (int) TIOCSLTC, (char *) &ltchars);
+#else
+ (void) ioctl(fileno(stdin), (int) TCSETA, &termio);
+#endif BSD
+}
+
+#ifdef SUSPEND /* implies BSD */
+dosuspend() {
+#include <signal.h>
+#ifdef SIGTSTP
+ if(signal(SIGTSTP, SIG_IGN) == SIG_DFL) {
+ settty((char *) 0);
+ (void) signal(SIGTSTP, SIG_DFL);
+ (void) kill(0, SIGTSTP);
+ gettty();
+ setftty();
+ docrt();
+ } else {
+ pline("I don't think your shell has job control.");
+ }
+#else SIGTSTP
+ pline("Sorry, it seems we have no SIGTSTP here. Try ! or S.");
+#endif SIGTSTP
+ return(0);
+}
+#endif SUSPEND
diff --git a/hack/hack.lev.c b/hack/hack.lev.c
new file mode 100644
index 00000000..f011f675
--- /dev/null
+++ b/hack/hack.lev.c
@@ -0,0 +1,285 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.lev.c - version 1.0.3 */
+
+#include "hack.h"
+#include "def.mkroom.h"
+#include <stdio.h>
+extern struct monst *restmonchn();
+extern struct obj *restobjchn();
+extern struct obj *billobjs;
+extern char *itoa();
+extern char SAVEF[];
+extern int hackpid;
+extern xchar dlevel;
+extern char nul[];
+
+#ifndef NOWORM
+#include "def.wseg.h"
+extern struct wseg *wsegs[32], *wheads[32];
+extern long wgrowtime[32];
+#endif NOWORM
+
+boolean level_exists[MAXLEVEL+1];
+
+savelev(fd,lev)
+int fd;
+xchar lev;
+{
+#ifndef NOWORM
+ register struct wseg *wtmp, *wtmp2;
+ register tmp;
+#endif NOWORM
+
+ if(fd < 0) panic("Save on bad file!"); /* impossible */
+ if(lev >= 0 && lev <= MAXLEVEL)
+ level_exists[lev] = TRUE;
+
+ bwrite(fd,(char *) &hackpid,sizeof(hackpid));
+ bwrite(fd,(char *) &lev,sizeof(lev));
+ bwrite(fd,(char *) levl,sizeof(levl));
+ bwrite(fd,(char *) &moves,sizeof(long));
+ bwrite(fd,(char *) &xupstair,sizeof(xupstair));
+ bwrite(fd,(char *) &yupstair,sizeof(yupstair));
+ bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
+ bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
+ savemonchn(fd, fmon);
+ savegoldchn(fd, fgold);
+ savetrapchn(fd, ftrap);
+ saveobjchn(fd, fobj);
+ saveobjchn(fd, billobjs);
+ billobjs = 0;
+ save_engravings(fd);
+#ifndef QUEST
+ bwrite(fd,(char *) rooms,sizeof(rooms));
+ bwrite(fd,(char *) doors,sizeof(doors));
+#endif QUEST
+ fgold = 0;
+ ftrap = 0;
+ fmon = 0;
+ fobj = 0;
+#ifndef NOWORM
+ bwrite(fd,(char *) wsegs,sizeof(wsegs));
+ for(tmp=1; tmp<32; tmp++){
+ for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
+ wtmp2 = wtmp->nseg;
+ bwrite(fd,(char *) wtmp,sizeof(struct wseg));
+ }
+ wsegs[tmp] = 0;
+ }
+ bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
+#endif NOWORM
+}
+
+bwrite(fd,loc,num)
+register fd;
+register char *loc;
+register unsigned num;
+{
+/* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
+ if(write(fd, loc, (int) num) != num)
+ panic("cannot write %u bytes to file #%d", num, fd);
+}
+
+saveobjchn(fd,otmp)
+register fd;
+register struct obj *otmp;
+{
+ register struct obj *otmp2;
+ unsigned xl;
+ int minusone = -1;
+
+ while(otmp) {
+ otmp2 = otmp->nobj;
+ xl = otmp->onamelth;
+ bwrite(fd, (char *) &xl, sizeof(int));
+ bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
+ free((char *) otmp);
+ otmp = otmp2;
+ }
+ bwrite(fd, (char *) &minusone, sizeof(int));
+}
+
+savemonchn(fd,mtmp)
+register fd;
+register struct monst *mtmp;
+{
+ register struct monst *mtmp2;
+ unsigned xl;
+ int minusone = -1;
+ struct permonst *monbegin = &mons[0];
+
+ bwrite(fd, (char *) &monbegin, sizeof(monbegin));
+
+ while(mtmp) {
+ mtmp2 = mtmp->nmon;
+ xl = mtmp->mxlth + mtmp->mnamelth;
+ bwrite(fd, (char *) &xl, sizeof(int));
+ bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
+ if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
+ free((char *) mtmp);
+ mtmp = mtmp2;
+ }
+ bwrite(fd, (char *) &minusone, sizeof(int));
+}
+
+savegoldchn(fd,gold)
+register fd;
+register struct gold *gold;
+{
+ register struct gold *gold2;
+ while(gold) {
+ gold2 = gold->ngold;
+ bwrite(fd, (char *) gold, sizeof(struct gold));
+ free((char *) gold);
+ gold = gold2;
+ }
+ bwrite(fd, nul, sizeof(struct gold));
+}
+
+savetrapchn(fd,trap)
+register fd;
+register struct trap *trap;
+{
+ register struct trap *trap2;
+ while(trap) {
+ trap2 = trap->ntrap;
+ bwrite(fd, (char *) trap, sizeof(struct trap));
+ free((char *) trap);
+ trap = trap2;
+ }
+ bwrite(fd, nul, sizeof(struct trap));
+}
+
+getlev(fd,pid,lev)
+int fd,pid;
+xchar lev;
+{
+ register struct gold *gold;
+ register struct trap *trap;
+#ifndef NOWORM
+ register struct wseg *wtmp;
+#endif NOWORM
+ register tmp;
+ long omoves;
+ int hpid;
+ xchar dlvl;
+
+ /* First some sanity checks */
+ mread(fd, (char *) &hpid, sizeof(hpid));
+ mread(fd, (char *) &dlvl, sizeof(dlvl));
+ if((pid && pid != hpid) || (lev && dlvl != lev)) {
+ pline("Strange, this map is not as I remember it.");
+ pline("Somebody is trying some trickery here ...");
+ pline("This game is void ...");
+ done("tricked");
+ }
+
+ fgold = 0;
+ ftrap = 0;
+ mread(fd, (char *) levl, sizeof(levl));
+ mread(fd, (char *)&omoves, sizeof(omoves));
+ mread(fd, (char *)&xupstair, sizeof(xupstair));
+ mread(fd, (char *)&yupstair, sizeof(yupstair));
+ mread(fd, (char *)&xdnstair, sizeof(xdnstair));
+ mread(fd, (char *)&ydnstair, sizeof(ydnstair));
+
+ fmon = restmonchn(fd);
+
+ /* regenerate animals while on another level */
+ { long tmoves = (moves > omoves) ? moves-omoves : 0;
+ register struct monst *mtmp, *mtmp2;
+ extern char genocided[];
+
+ for(mtmp = fmon; mtmp; mtmp = mtmp2) {
+ long newhp; /* tmoves may be very large */
+
+ mtmp2 = mtmp->nmon;
+ if(index(genocided, mtmp->data->mlet)) {
+ mondead(mtmp);
+ continue;
+ }
+
+ if(mtmp->mtame && tmoves > 250) {
+ mtmp->mtame = 0;
+ mtmp->mpeaceful = 0;
+ }
+
+ newhp = mtmp->mhp +
+ (index(MREGEN, mtmp->data->mlet) ? tmoves : tmoves/20);
+ if(newhp > mtmp->mhpmax)
+ mtmp->mhp = mtmp->mhpmax;
+ else
+ mtmp->mhp = newhp;
+ }
+ }
+
+ setgd();
+ gold = newgold();
+ mread(fd, (char *)gold, sizeof(struct gold));
+ while(gold->gx) {
+ gold->ngold = fgold;
+ fgold = gold;
+ gold = newgold();
+ mread(fd, (char *)gold, sizeof(struct gold));
+ }
+ free((char *) gold);
+ trap = newtrap();
+ mread(fd, (char *)trap, sizeof(struct trap));
+ while(trap->tx) {
+ trap->ntrap = ftrap;
+ ftrap = trap;
+ trap = newtrap();
+ mread(fd, (char *)trap, sizeof(struct trap));
+ }
+ free((char *) trap);
+ fobj = restobjchn(fd);
+ billobjs = restobjchn(fd);
+ rest_engravings(fd);
+#ifndef QUEST
+ mread(fd, (char *)rooms, sizeof(rooms));
+ mread(fd, (char *)doors, sizeof(doors));
+#endif QUEST
+#ifndef NOWORM
+ mread(fd, (char *)wsegs, sizeof(wsegs));
+ for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
+ wheads[tmp] = wsegs[tmp] = wtmp = newseg();
+ while(1) {
+ mread(fd, (char *)wtmp, sizeof(struct wseg));
+ if(!wtmp->nseg) break;
+ wheads[tmp]->nseg = wtmp = newseg();
+ wheads[tmp] = wtmp;
+ }
+ }
+ mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
+#endif NOWORM
+}
+
+mread(fd, buf, len)
+register fd;
+register char *buf;
+register unsigned len;
+{
+ register int rlen;
+ extern boolean restoring;
+
+ rlen = read(fd, buf, (int) len);
+ if(rlen != len){
+ pline("Read %d instead of %u bytes.\n", rlen, len);
+ if(restoring) {
+ (void) unlink(SAVEF);
+ error("Error restoring old game.");
+ }
+ panic("Error reading level file.");
+ }
+}
+
+mklev()
+{
+ extern boolean in_mklev;
+
+ if(getbones()) return;
+
+ in_mklev = TRUE;
+ makelevel();
+ in_mklev = FALSE;
+}
diff --git a/hack/hack.main.c b/hack/hack.main.c
new file mode 100644
index 00000000..d2d59a2f
--- /dev/null
+++ b/hack/hack.main.c
@@ -0,0 +1,499 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.main.c - version 1.0.3 */
+
+#include <stdio.h>
+#include <signal.h>
+#include "hack.h"
+
+#ifdef QUEST
+#define gamename "quest"
+#else
+#define gamename "hack"
+#endif
+
+extern char *getlogin(), *getenv();
+extern char plname[PL_NSIZ], pl_character[PL_CSIZ];
+extern struct permonst mons[CMNUM+2];
+extern char genocided[], fut_geno[];
+
+int (*afternmv)();
+int (*occupation)();
+char *occtxt; /* defined when occupation != NULL */
+
+void done1();
+void hangup();
+
+int hackpid; /* current pid */
+int locknum; /* max num of players */
+#ifdef DEF_PAGER
+char *catmore; /* default pager */
+#endif
+char SAVEF[PL_NSIZ + 11] = "save/"; /* save/99999player */
+char *hname; /* name of the game (argv[0] of call) */
+char obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */
+
+extern char *nomovemsg;
+extern long wailmsg;
+
+#ifdef CHDIR
+static void chdirx();
+#endif
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ register int fd;
+#ifdef CHDIR
+ register char *dir;
+#endif
+
+ hname = argv[0];
+ hackpid = getpid();
+
+#ifdef CHDIR /* otherwise no chdir() */
+ /*
+ * See if we must change directory to the playground.
+ * (Perhaps hack runs suid and playground is inaccessible
+ * for the player.)
+ * The environment variable HACKDIR is overridden by a
+ * -d command line option (must be the first option given)
+ */
+
+ dir = getenv("HACKDIR");
+ if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
+ argc--;
+ argv++;
+ dir = argv[0]+2;
+ if(*dir == '=' || *dir == ':') dir++;
+ if(!*dir && argc > 1) {
+ argc--;
+ argv++;
+ dir = argv[0];
+ }
+ if(!*dir)
+ error("Flag -d must be followed by a directory name.");
+ }
+#endif
+
+ /*
+ * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS
+ * 2. Use $USER or $LOGNAME (if 1. fails)
+ * 3. Use getlogin() (if 2. fails)
+ * The resulting name is overridden by command line options.
+ * If everything fails, or if the resulting name is some generic
+ * account like "games", "play", "player", "hack" then eventually
+ * we'll ask him.
+ * Note that we trust him here; it is possible to play under
+ * somebody else's name.
+ */
+ { register char *s;
+
+ initoptions();
+ if(!*plname && (s = getenv("USER")))
+ (void) strncpy(plname, s, sizeof(plname)-1);
+ if(!*plname && (s = getenv("LOGNAME")))
+ (void) strncpy(plname, s, sizeof(plname)-1);
+ if(!*plname && (s = getlogin()))
+ (void) strncpy(plname, s, sizeof(plname)-1);
+ }
+
+ /*
+ * Now we know the directory containing 'record' and
+ * may do a prscore().
+ */
+ if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
+#ifdef CHDIR
+ chdirx(dir,0);
+#endif
+ prscore(argc, argv);
+ exit(0);
+ }
+
+ /*
+ * It seems he really wants to play.
+ * Remember tty modes, to be restored on exit.
+ */
+ gettty();
+ setbuf(stdout,obuf);
+ setrandom();
+ startup();
+ cls();
+ u.uhp = 1; /* prevent RIP on early quits */
+ u.ux = FAR; /* prevent nscr() */
+ (void) signal(SIGHUP, hangup);
+
+ /*
+ * Find the creation date of this game,
+ * so as to avoid restoring outdated savefiles.
+ */
+ gethdate(hname);
+
+ /*
+ * We cannot do chdir earlier, otherwise gethdate will fail.
+ */
+#ifdef CHDIR
+ chdirx(dir,1);
+#endif
+
+ /*
+ * Process options.
+ */
+ while(argc > 1 && argv[1][0] == '-'){
+ argv++;
+ argc--;
+ switch(argv[0][1]){
+#ifdef WIZARD
+ case 'D':
+/* if(!strcmp(getlogin(), WIZARD)) */
+ wizard = TRUE;
+/* else
+ printf("Sorry.\n"); */
+ break;
+#endif
+#ifdef NEWS
+ case 'n':
+ flags.nonews = TRUE;
+ break;
+#endif
+ case 'u':
+ if(argv[0][2])
+ (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
+ else if(argc > 1) {
+ argc--;
+ argv++;
+ (void) strncpy(plname, argv[0], sizeof(plname)-1);
+ } else
+ printf("Player name expected after -u\n");
+ break;
+ default:
+ /* allow -T for Tourist, etc. */
+ (void) strncpy(pl_character, argv[0]+1,
+ sizeof(pl_character)-1);
+
+ /* printf("Unknown option: %s\n", *argv); */
+ }
+ }
+
+ if(argc > 1)
+ locknum = atoi(argv[1]);
+#ifdef MAX_NR_OF_PLAYERS
+ if(!locknum || locknum > MAX_NR_OF_PLAYERS)
+ locknum = MAX_NR_OF_PLAYERS;
+#endif
+#ifdef DEF_PAGER
+ if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER")))
+ catmore = DEF_PAGER;
+#endif
+#ifdef MAIL
+ getmailstatus();
+#endif
+#ifdef WIZARD
+ if(wizard) (void) strcpy(plname, "wizard"); else
+#endif
+ if(!*plname || !strncmp(plname, "player", 4)
+ || !strncmp(plname, "games", 4))
+ askname();
+ plnamesuffix(); /* strip suffix from name; calls askname() */
+ /* again if suffix was whole name */
+ /* accepts any suffix */
+#ifdef WIZARD
+ if(!wizard) {
+#endif
+ /*
+ * check for multiple games under the same name
+ * (if !locknum) or check max nr of players (otherwise)
+ */
+ (void) signal(SIGQUIT,SIG_IGN);
+ (void) signal(SIGINT,SIG_IGN);
+ if(!locknum)
+ (void) strcpy(lock,plname);
+ getlock(); /* sets lock if locknum != 0 */
+#ifdef WIZARD
+ } else {
+ register char *sfoo;
+ (void) strcpy(lock,plname);
+ if(sfoo = getenv("MAGIC"))
+ while(*sfoo) {
+ switch(*sfoo++) {
+ case 'n': (void) srandom(*sfoo++);
+ break;
+ }
+ }
+ if(sfoo = getenv("GENOCIDED")){
+ if(*sfoo == '!'){
+ register struct permonst *pm = mons;
+ register char *gp = genocided;
+
+ while(pm < mons+CMNUM+2){
+ if(!index(sfoo, pm->mlet))
+ *gp++ = pm->mlet;
+ pm++;
+ }
+ *gp = 0;
+ } else
+ (void) strcpy(genocided, sfoo);
+ (void) strcpy(fut_geno, genocided);
+ }
+ }
+#endif
+ setftty();
+ (void) sprintf(SAVEF, "save/%d%s", getuid(), plname);
+ regularize(SAVEF+5); /* avoid . or / in name */
+ if((fd = open(SAVEF,0)) >= 0 &&
+ (uptodate(fd) || unlink(SAVEF) == 666)) {
+ (void) signal(SIGINT,done1);
+ pline("Restoring old save file...");
+ (void) fflush(stdout);
+ if(!dorecover(fd))
+ goto not_recovered;
+ pline("Hello %s, welcome to %s!", plname, gamename);
+ flags.move = 0;
+ } else {
+not_recovered:
+ fobj = fcobj = invent = 0;
+ fmon = fallen_down = 0;
+ ftrap = 0;
+ fgold = 0;
+ flags.ident = 1;
+ init_objects();
+ u_init();
+
+ (void) signal(SIGINT,done1);
+ mklev();
+ u.ux = xupstair;
+ u.uy = yupstair;
+ (void) inshop();
+ setsee();
+ flags.botlx = 1;
+ makedog();
+ { register struct monst *mtmp;
+ if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */
+ }
+ seemons();
+#ifdef NEWS
+ if(flags.nonews || !readnews())
+ /* after reading news we did docrt() already */
+#endif
+ docrt();
+
+ /* give welcome message before pickup messages */
+ pline("Hello %s, welcome to %s!", plname, gamename);
+
+ pickup(1);
+ read_engr_at(u.ux,u.uy);
+ flags.move = 1;
+ }
+
+ flags.moonphase = phase_of_the_moon();
+ if(flags.moonphase == FULL_MOON) {
+ pline("You are lucky! Full moon tonight.");
+ u.uluck++;
+ } else if(flags.moonphase == NEW_MOON) {
+ pline("Be careful! New moon tonight.");
+ }
+
+ initrack();
+
+ for(;;) {
+ if(flags.move) { /* actual time passed */
+
+ settrack();
+
+ if(moves%2 == 0 ||
+ (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
+ extern struct monst *makemon();
+ movemon();
+ if(!rn2(70))
+ (void) makemon((struct permonst *)0, 0, 0);
+ }
+ if(Glib) glibr();
+ timeout();
+ ++moves;
+ if(flags.time) flags.botl = 1;
+ if(u.uhp < 1) {
+ pline("You die...");
+ done("died");
+ }
+ if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
+ wailmsg = moves;
+ if(u.uhp == 1)
+ pline("You hear the wailing of the Banshee...");
+ else
+ pline("You hear the howling of the CwnAnnwn...");
+ }
+ if(u.uhp < u.uhpmax) {
+ if(u.ulevel > 9) {
+ if(Regeneration || !(moves%3)) {
+ flags.botl = 1;
+ u.uhp += rnd((int) u.ulevel-9);
+ if(u.uhp > u.uhpmax)
+ u.uhp = u.uhpmax;
+ }
+ } else if(Regeneration ||
+ (!(moves%(22-u.ulevel*2)))) {
+ flags.botl = 1;
+ u.uhp++;
+ }
+ }
+ if(Teleportation && !rn2(85)) tele();
+ if(Searching && multi >= 0) (void) dosearch();
+ gethungry();
+ invault();
+ amulet();
+ }
+ if(multi < 0) {
+ if(!++multi){
+ pline(nomovemsg ? nomovemsg :
+ "You can move again.");
+ nomovemsg = 0;
+ if(afternmv) (*afternmv)();
+ afternmv = 0;
+ }
+ }
+
+ find_ac();
+#ifndef QUEST
+ if(!flags.mv || Blind)
+#endif
+ {
+ seeobjs();
+ seemons();
+ nscr();
+ }
+ if(flags.botl || flags.botlx) bot();
+
+ flags.move = 1;
+
+ if(multi >= 0 && occupation) {
+ if(monster_nearby())
+ stop_occupation();
+ else if ((*occupation)() == 0)
+ occupation = 0;
+ continue;
+ }
+
+ if(multi > 0) {
+#ifdef QUEST
+ if(flags.run >= 4) finddir();
+#endif
+ lookaround();
+ if(!multi) { /* lookaround may clear multi */
+ flags.move = 0;
+ continue;
+ }
+ if(flags.mv) {
+ if(multi < COLNO && !--multi)
+ flags.mv = flags.run = 0;
+ domove();
+ } else {
+ --multi;
+ rhack(save_cm);
+ }
+ } else if(multi == 0) {
+#ifdef MAIL
+ ckmailstatus();
+#endif
+ rhack((char *) 0);
+ }
+ if(multi && multi%7 == 0)
+ (void) fflush(stdout);
+ }
+}
+
+glo(foo)
+register foo;
+{
+ /* construct the string xlock.n */
+ register char *tf;
+
+ tf = lock;
+ while(*tf && *tf != '.') tf++;
+ (void) sprintf(tf, ".%d", foo);
+}
+
+/*
+ * plname is filled either by an option (-u Player or -uPlayer) or
+ * explicitly (-w implies wizard) or by askname.
+ * It may still contain a suffix denoting pl_character.
+ */
+askname(){
+register int c,ct;
+ printf("\nWho are you? ");
+ (void) fflush(stdout);
+ ct = 0;
+ while((c = getchar()) != '\n'){
+ if(c == EOF) error("End of input\n");
+ /* some people get confused when their erase char is not ^H */
+ if(c == '\010') {
+ if(ct) ct--;
+ continue;
+ }
+ if(c != '-')
+ if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
+ if(ct < sizeof(plname)-1) plname[ct++] = c;
+ }
+ plname[ct] = 0;
+ if(ct == 0) askname();
+}
+
+/*VARARGS1*/
+impossible(s,x1,x2)
+register char *s;
+{
+ pline(s,x1,x2);
+ pline("Program in disorder - perhaps you'd better Quit.");
+}
+
+#ifdef CHDIR
+static void
+chdirx(dir, wr)
+char *dir;
+boolean wr;
+{
+
+#ifdef SECURE
+ if(dir /* User specified directory? */
+#ifdef HACKDIR
+ && strcmp(dir, HACKDIR) /* and not the default? */
+#endif
+ ) {
+ (void) setuid(getuid()); /* Ron Wessels */
+ (void) setgid(getgid());
+ }
+#endif
+
+#ifdef HACKDIR
+ if(dir == NULL)
+ dir = HACKDIR;
+#endif
+
+ if(dir && chdir(dir) < 0) {
+ perror(dir);
+ error("Cannot chdir to %s.", dir);
+ }
+
+ /* warn the player if he cannot write the record file */
+ /* perhaps we should also test whether . is writable */
+ /* unfortunately the access systemcall is worthless */
+ if(wr) {
+ register fd;
+
+ if(dir == NULL)
+ dir = ".";
+ if((fd = open(RECORD, 2)) < 0) {
+ printf("Warning: cannot write %s/%s", dir, RECORD);
+ getret();
+ } else
+ (void) close(fd);
+ }
+}
+#endif
+
+stop_occupation()
+{
+ if(occupation) {
+ pline("You stop %s.", occtxt);
+ occupation = 0;
+ }
+}
diff --git a/hack/hack.makemon.c b/hack/hack.makemon.c
new file mode 100644
index 00000000..bcf23b62
--- /dev/null
+++ b/hack/hack.makemon.c
@@ -0,0 +1,198 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.makemon.c - version 1.0.2 */
+
+#include "hack.h"
+extern char fut_geno[];
+extern char *index();
+extern struct obj *mkobj_at();
+struct monst zeromonst;
+
+/*
+ * called with [x,y] = coordinates;
+ * [0,0] means anyplace
+ * [u.ux,u.uy] means: call mnexto (if !in_mklev)
+ *
+ * In case we make an Orc or killer bee, we make an entire horde (swarm);
+ * note that in this case we return only one of them (the one at [x,y]).
+ */
+struct monst *
+makemon(ptr,x,y)
+register struct permonst *ptr;
+{
+ register struct monst *mtmp;
+ register tmp, ct;
+ boolean anything = (!ptr);
+ extern boolean in_mklev;
+
+ if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
+ if(ptr){
+ if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
+ } else {
+ ct = CMNUM - strlen(fut_geno);
+ if(index(fut_geno, 'm')) ct++; /* make only 1 minotaur */
+ if(index(fut_geno, '@')) ct++;
+ if(ct <= 0) return(0); /* no more monsters! */
+ tmp = rn2(ct*dlevel/24 + 7);
+ if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
+ if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
+ for(ct = 0; ct < CMNUM; ct++){
+ ptr = &mons[ct];
+ if(index(fut_geno, ptr->mlet))
+ continue;
+ if(!tmp--) goto gotmon;
+ }
+ panic("makemon?");
+ }
+gotmon:
+ mtmp = newmonst(ptr->pxlth);
+ *mtmp = zeromonst; /* clear all entries in structure */
+ for(ct = 0; ct < ptr->pxlth; ct++)
+ ((char *) &(mtmp->mextra[0]))[ct] = 0;
+ mtmp->nmon = fmon;
+ fmon = mtmp;
+ mtmp->m_id = flags.ident++;
+ mtmp->data = ptr;
+ mtmp->mxlth = ptr->pxlth;
+ if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
+ else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
+ else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
+ mtmp->mx = x;
+ mtmp->my = y;
+ mtmp->mcansee = 1;
+ if(ptr->mlet == 'M'){
+ mtmp->mimic = 1;
+ mtmp->mappearance = ']';
+ }
+ if(!in_mklev) {
+ if(x == u.ux && y == u.uy && ptr->mlet != ' ')
+ mnexto(mtmp);
+ if(x == 0 && y == 0)
+ rloc(mtmp);
+ }
+ if(ptr->mlet == 's' || ptr->mlet == 'S') {
+ mtmp->mhide = mtmp->mundetected = 1;
+ if(in_mklev)
+ if(mtmp->mx && mtmp->my)
+ (void) mkobj_at(0, mtmp->mx, mtmp->my);
+ }
+ if(ptr->mlet == ':') {
+ mtmp->cham = 1;
+ (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
+ }
+ if(ptr->mlet == 'I' || ptr->mlet == ';')
+ mtmp->minvis = 1;
+ if(ptr->mlet == 'L' || ptr->mlet == 'N'
+ || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
+ ) mtmp->msleep = 1;
+
+#ifndef NOWORM
+ if(ptr->mlet == 'w' && getwn(mtmp))
+ initworm(mtmp);
+#endif NOWORM
+
+ if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
+ coord enexto();
+ coord mm;
+ register int cnt = rnd(10);
+ mm.x = x;
+ mm.y = y;
+ while(cnt--) {
+ mm = enexto(mm.x, mm.y);
+ (void) makemon(ptr, mm.x, mm.y);
+ }
+ }
+
+ return(mtmp);
+}
+
+coord
+enexto(xx,yy)
+register xchar xx,yy;
+{
+ register xchar x,y;
+ coord foo[15], *tfoo;
+ int range;
+
+ tfoo = foo;
+ range = 1;
+ do { /* full kludge action. */
+ for(x = xx-range; x <= xx+range; x++)
+ if(goodpos(x, yy-range)) {
+ tfoo->x = x;
+ tfoo++->y = yy-range;
+ if(tfoo == &foo[15]) goto foofull;
+ }
+ for(x = xx-range; x <= xx+range; x++)
+ if(goodpos(x,yy+range)) {
+ tfoo->x = x;
+ tfoo++->y = yy+range;
+ if(tfoo == &foo[15]) goto foofull;
+ }
+ for(y = yy+1-range; y < yy+range; y++)
+ if(goodpos(xx-range,y)) {
+ tfoo->x = xx-range;
+ tfoo++->y = y;
+ if(tfoo == &foo[15]) goto foofull;
+ }
+ for(y = yy+1-range; y < yy+range; y++)
+ if(goodpos(xx+range,y)) {
+ tfoo->x = xx+range;
+ tfoo++->y = y;
+ if(tfoo == &foo[15]) goto foofull;
+ }
+ range++;
+ } while(tfoo == foo);
+foofull:
+ return( foo[rn2(tfoo-foo)] );
+}
+
+goodpos(x,y) /* used only in mnexto and rloc */
+{
+ return(
+ ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
+ m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
+ || (x == u.ux && y == u.uy)
+ || sobj_at(ENORMOUS_ROCK, x, y)
+ ));
+}
+
+rloc(mtmp)
+struct monst *mtmp;
+{
+ register tx,ty;
+ register char ch = mtmp->data->mlet;
+
+#ifndef NOWORM
+ if(ch == 'w' && mtmp->mx) return; /* do not relocate worms */
+#endif NOWORM
+ do {
+ tx = rn1(COLNO-3,2);
+ ty = rn2(ROWNO);
+ } while(!goodpos(tx,ty));
+ mtmp->mx = tx;
+ mtmp->my = ty;
+ if(u.ustuck == mtmp){
+ if(u.uswallow) {
+ u.ux = tx;
+ u.uy = ty;
+ docrt();
+ } else u.ustuck = 0;
+ }
+ pmon(mtmp);
+}
+
+struct monst *
+mkmon_at(let,x,y)
+char let;
+register int x,y;
+{
+ register int ct;
+ register struct permonst *ptr;
+
+ for(ct = 0; ct < CMNUM; ct++) {
+ ptr = &mons[ct];
+ if(ptr->mlet == let)
+ return(makemon(ptr,x,y));
+ }
+ return(0);
+}
diff --git a/hack/hack.mfndpos.h b/hack/hack.mfndpos.h
new file mode 100644
index 00000000..f4da529f
--- /dev/null
+++ b/hack/hack.mfndpos.h
@@ -0,0 +1,12 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.mfndpos.h - version 1.0.2 */
+
+#define ALLOW_TRAPS 0777
+#define ALLOW_U 01000
+#define ALLOW_M 02000
+#define ALLOW_TM 04000
+#define ALLOW_ALL (ALLOW_U | ALLOW_M | ALLOW_TM | ALLOW_TRAPS)
+#define ALLOW_SSM 010000
+#define ALLOW_ROCK 020000
+#define NOTONL 040000
+#define NOGARLIC 0100000
diff --git a/hack/hack.mhitu.c b/hack/hack.mhitu.c
new file mode 100644
index 00000000..ae7d204b
--- /dev/null
+++ b/hack/hack.mhitu.c
@@ -0,0 +1,363 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.mhitu.c - version 1.0.3 */
+
+#include "hack.h"
+extern struct monst *makemon();
+
+/*
+ * mhitu: monster hits you
+ * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise
+ */
+mhitu(mtmp)
+register struct monst *mtmp;
+{
+ register struct permonst *mdat = mtmp->data;
+ register int tmp, ctmp;
+
+ nomul(0);
+
+ /* If swallowed, can only be affected by hissers and by u.ustuck */
+ if(u.uswallow) {
+ if(mtmp != u.ustuck) {
+ if(mdat->mlet == 'c' && !rn2(13)) {
+ pline("Outside, you hear %s's hissing!",
+ monnam(mtmp));
+ pline("%s gets turned to stone!",
+ Monnam(u.ustuck));
+ pline("And the same fate befalls you.");
+ done_in_by(mtmp);
+ /* "notreached": not return(1); */
+ }
+ return(0);
+ }
+ switch(mdat->mlet) { /* now mtmp == u.ustuck */
+ case ',':
+ youswld(mtmp, (u.uac > 0) ? u.uac+4 : 4,
+ 5, "The trapper");
+ break;
+ case '\'':
+ youswld(mtmp,rnd(6),7,"The lurker above");
+ break;
+ case 'P':
+ youswld(mtmp,d(2,4),12,"The purple worm");
+ break;
+ default:
+ /* This is not impossible! */
+ pline("The mysterious monster totally digests you.");
+ u.uhp = 0;
+ }
+ if(u.uhp < 1) done_in_by(mtmp);
+ return(0);
+ }
+
+ if(mdat->mlet == 'c' && Stoned)
+ return(0);
+
+ /* make eels visible the moment they hit/miss us */
+ if(mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx,mtmp->my)){
+ mtmp->minvis = 0;
+ pmon(mtmp);
+ }
+ if(!index("1&DuxynNF",mdat->mlet))
+ tmp = hitu(mtmp,d(mdat->damn,mdat->damd));
+ else
+ tmp = 0;
+ if(index(UNDEAD, mdat->mlet) && midnight())
+ tmp += hitu(mtmp,d(mdat->damn,mdat->damd));
+
+ ctmp = tmp && !mtmp->mcan &&
+ (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50));
+ switch(mdat->mlet) {
+ case '1':
+ if(wiz_hit(mtmp)) return(1); /* he disappeared */
+ break;
+ case '&':
+ if(!mtmp->cham && !mtmp->mcan && !rn2(13)) {
+ (void) makemon(PM_DEMON,u.ux,u.uy);
+ } else {
+ (void) hitu(mtmp,d(2,6));
+ (void) hitu(mtmp,d(2,6));
+ (void) hitu(mtmp,rnd(3));
+ (void) hitu(mtmp,rnd(3));
+ (void) hitu(mtmp,rn1(4,2));
+ }
+ break;
+ case ',':
+ if(tmp) justswld(mtmp,"The trapper");
+ break;
+ case '\'':
+ if(tmp) justswld(mtmp, "The lurker above");
+ break;
+ case ';':
+ if(ctmp) {
+ if(!u.ustuck && !rn2(10)) {
+ pline("%s swings itself around you!",
+ Monnam(mtmp));
+ u.ustuck = mtmp;
+ } else if(u.ustuck == mtmp &&
+ levl[mtmp->mx][mtmp->my].typ == POOL) {
+ pline("%s drowns you ...", Monnam(mtmp));
+ done("drowned");
+ }
+ }
+ break;
+ case 'A':
+ if(ctmp && rn2(2)) {
+ if(Poison_resistance)
+ pline("The sting doesn't seem to affect you.");
+ else {
+ pline("You feel weaker!");
+ losestr(1);
+ }
+ }
+ break;
+ case 'C':
+ (void) hitu(mtmp,rnd(6));
+ break;
+ case 'c':
+ if(!rn2(5)) {
+ pline("You hear %s's hissing!", monnam(mtmp));
+ if(ctmp || !rn2(20) || (flags.moonphase == NEW_MOON
+ && !carrying(DEAD_LIZARD))) {
+ Stoned = 5;
+ /* pline("You get turned to stone!"); */
+ /* done_in_by(mtmp); */
+ }
+ }
+ break;
+ case 'D':
+ if(rn2(6) || mtmp->mcan) {
+ (void) hitu(mtmp,d(3,10));
+ (void) hitu(mtmp,rnd(8));
+ (void) hitu(mtmp,rnd(8));
+ break;
+ }
+ kludge("%s breathes fire!","The dragon");
+ buzz(-1,mtmp->mx,mtmp->my,u.ux-mtmp->mx,u.uy-mtmp->my);
+ break;
+ case 'd':
+ (void) hitu(mtmp,d(2, (flags.moonphase == FULL_MOON) ? 3 : 4));
+ break;
+ case 'e':
+ (void) hitu(mtmp,d(3,6));
+ break;
+ case 'F':
+ if(mtmp->mcan) break;
+ kludge("%s explodes!","The freezing sphere");
+ if(Cold_resistance) pline("You don't seem affected by it.");
+ else {
+ xchar dn;
+ if(17-(u.ulevel/2) > rnd(20)) {
+ pline("You get blasted!");
+ dn = 6;
+ } else {
+ pline("You duck the blast...");
+ dn = 3;
+ }
+ losehp_m(d(dn,6), mtmp);
+ }
+ mondead(mtmp);
+ return(1);
+ case 'g':
+ if(ctmp && multi >= 0 && !rn2(3)) {
+ kludge("You are frozen by %ss juices","the cube'");
+ nomul(-rnd(10));
+ }
+ break;
+ case 'h':
+ if(ctmp && multi >= 0 && !rn2(5)) {
+ nomul(-rnd(10));
+ kludge("You are put to sleep by %ss bite!",
+ "the homunculus'");
+ }
+ break;
+ case 'j':
+ tmp = hitu(mtmp,rnd(3));
+ tmp &= hitu(mtmp,rnd(3));
+ if(tmp){
+ (void) hitu(mtmp,rnd(4));
+ (void) hitu(mtmp,rnd(4));
+ }
+ break;
+ case 'k':
+ if((hitu(mtmp,rnd(4)) || !rn2(3)) && ctmp){
+ poisoned("bee's sting",mdat->mname);
+ }
+ break;
+ case 'L':
+ if(tmp) stealgold(mtmp);
+ break;
+ case 'N':
+ if(mtmp->mcan && !Blind) {
+ pline("%s tries to seduce you, but you seem not interested.",
+ Amonnam(mtmp, "plain"));
+ if(rn2(3)) rloc(mtmp);
+ } else if(steal(mtmp)) {
+ rloc(mtmp);
+ mtmp->mflee = 1;
+ }
+ break;
+ case 'n':
+ if(!uwep && !uarm && !uarmh && !uarms && !uarmg) {
+ pline("%s hits! (I hope you don't mind)",
+ Monnam(mtmp));
+ u.uhp += rnd(7);
+ if(!rn2(7)) u.uhpmax++;
+ if(u.uhp > u.uhpmax) u.uhp = u.uhpmax;
+ flags.botl = 1;
+ if(!rn2(50)) rloc(mtmp);
+ } else {
+ (void) hitu(mtmp,d(2,6));
+ (void) hitu(mtmp,d(2,6));
+ }
+ break;
+ case 'o':
+ tmp = hitu(mtmp,rnd(6));
+ if(hitu(mtmp,rnd(6)) && tmp && /* hits with both paws */
+ !u.ustuck && rn2(2)) {
+ u.ustuck = mtmp;
+ kludge("%s has grabbed you!","The owlbear");
+ u.uhp -= d(2,8);
+ } else if(u.ustuck == mtmp) {
+ u.uhp -= d(2,8);
+ pline("You are being crushed.");
+ }
+ break;
+ case 'P':
+ if(ctmp && !rn2(4))
+ justswld(mtmp,"The purple worm");
+ else
+ (void) hitu(mtmp,d(2,4));
+ break;
+ case 'Q':
+ (void) hitu(mtmp,rnd(2));
+ (void) hitu(mtmp,rnd(2));
+ break;
+ case 'R':
+ if(tmp && uarmh && !uarmh->rustfree &&
+ (int) uarmh->spe >= -1) {
+ pline("Your helmet rusts!");
+ uarmh->spe--;
+ } else
+ if(ctmp && uarm && !uarm->rustfree && /* Mike Newton */
+ uarm->otyp < STUDDED_LEATHER_ARMOR &&
+ (int) uarm->spe >= -1) {
+ pline("Your armor rusts!");
+ uarm->spe--;
+ }
+ break;
+ case 'S':
+ if(ctmp && !rn2(8)) {
+ poisoned("snake's bite",mdat->mname);
+ }
+ break;
+ case 's':
+ if(tmp && !rn2(8)) {
+ poisoned("scorpion's sting",mdat->mname);
+ }
+ (void) hitu(mtmp,rnd(8));
+ (void) hitu(mtmp,rnd(8));
+ break;
+ case 'T':
+ (void) hitu(mtmp,rnd(6));
+ (void) hitu(mtmp,rnd(6));
+ break;
+ case 't':
+ if(!rn2(5)) rloc(mtmp);
+ break;
+ case 'u':
+ mtmp->mflee = 1;
+ break;
+ case 'U':
+ (void) hitu(mtmp,d(3,4));
+ (void) hitu(mtmp,d(3,4));
+ break;
+ case 'v':
+ if(ctmp && !u.ustuck) u.ustuck = mtmp;
+ break;
+ case 'V':
+ if(tmp) u.uhp -= 4;
+ if(ctmp) losexp();
+ break;
+ case 'W':
+ if(ctmp) losexp();
+ break;
+#ifndef NOWORM
+ case 'w':
+ if(tmp) wormhit(mtmp);
+#endif NOWORM
+ break;
+ case 'X':
+ (void) hitu(mtmp,rnd(5));
+ (void) hitu(mtmp,rnd(5));
+ (void) hitu(mtmp,rnd(5));
+ break;
+ case 'x':
+ { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
+ pline("%s pricks in your %s leg!",
+ Monnam(mtmp), (side == RIGHT_SIDE) ? "right" : "left");
+ set_wounded_legs(side, rnd(50));
+ losehp_m(2, mtmp);
+ break;
+ }
+ case 'y':
+ if(mtmp->mcan) break;
+ mondead(mtmp);
+ if(!Blind) {
+ pline("You are blinded by a blast of light!");
+ Blind = d(4,12);
+ seeoff(0);
+ }
+ return(1);
+ case 'Y':
+ (void) hitu(mtmp,rnd(6));
+ break;
+ }
+ if(u.uhp < 1) done_in_by(mtmp);
+ return(0);
+}
+
+hitu(mtmp,dam)
+register struct monst *mtmp;
+register dam;
+{
+ register tmp, res;
+
+ nomul(0);
+ if(u.uswallow) return(0);
+
+ if(mtmp->mhide && mtmp->mundetected) {
+ mtmp->mundetected = 0;
+ if(!Blind) {
+ register struct obj *obj;
+ extern char * Xmonnam();
+ if(obj = o_at(mtmp->mx,mtmp->my))
+ pline("%s was hidden under %s!",
+ Xmonnam(mtmp), doname(obj));
+ }
+ }
+
+ tmp = u.uac;
+ /* give people with Ac = -10 at least some vulnerability */
+ if(tmp < 0) {
+ dam += tmp; /* decrease damage */
+ if(dam <= 0) dam = 1;
+ tmp = -rn2(-tmp);
+ }
+ tmp += mtmp->data->mlevel;
+ if(multi < 0) tmp += 4;
+ if((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) tmp -= 2;
+ if(mtmp->mtrapped) tmp -= 2;
+ if(tmp <= rnd(20)) {
+ if(Blind) pline("It misses.");
+ else pline("%s misses.",Monnam(mtmp));
+ res = 0;
+ } else {
+ if(Blind) pline("It hits!");
+ else pline("%s hits!",Monnam(mtmp));
+ losehp_m(dam, mtmp);
+ res = 1;
+ }
+ stop_occupation();
+ return(res);
+}
diff --git a/hack/hack.mklev.c b/hack/hack.mklev.c
new file mode 100644
index 00000000..89040213
--- /dev/null
+++ b/hack/hack.mklev.c
@@ -0,0 +1,741 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.mklev.c - version 1.0.3 */
+
+#include "hack.h"
+
+extern char *getlogin(), *getenv();
+extern struct monst *makemon();
+extern struct obj *mkobj_at();
+extern struct trap *maketrap();
+
+#define somex() ((random()%(croom->hx-croom->lx+1))+croom->lx)
+#define somey() ((random()%(croom->hy-croom->ly+1))+croom->ly)
+
+#include "def.mkroom.h"
+#define XLIM 4 /* define minimum required space around a room */
+#define YLIM 3
+boolean secret; /* TRUE while making a vault: increase [XY]LIM */
+struct mkroom rooms[MAXNROFROOMS+1];
+int smeq[MAXNROFROOMS+1];
+coord doors[DOORMAX];
+int doorindex;
+struct rm zerorm;
+int comp();
+schar nxcor;
+boolean goldseen;
+int nroom;
+xchar xdnstair,xupstair,ydnstair,yupstair;
+
+/* Definitions used by makerooms() and addrs() */
+#define MAXRS 50 /* max lth of temp rectangle table - arbitrary */
+struct rectangle {
+ xchar rlx,rly,rhx,rhy;
+} rs[MAXRS+1];
+int rscnt,rsmax; /* 0..rscnt-1: currently under consideration */
+ /* rscnt..rsmax: discarded */
+
+makelevel()
+{
+ register struct mkroom *croom, *troom;
+ register unsigned tryct;
+ register x,y;
+
+ nroom = 0;
+ doorindex = 0;
+ rooms[0].hx = -1; /* in case we are in a maze */
+
+ for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
+ levl[x][y] = zerorm;
+
+ oinit(); /* assign level dependent obj probabilities */
+
+ if(dlevel >= rn1(3, 26)) { /* there might be several mazes */
+ makemaz();
+ return;
+ }
+
+ /* construct the rooms */
+ nroom = 0;
+ secret = FALSE;
+ (void) makerooms();
+
+ /* construct stairs (up and down in different rooms if possible) */
+ croom = &rooms[rn2(nroom)];
+ xdnstair = somex();
+ ydnstair = somey();
+ levl[xdnstair][ydnstair].scrsym ='>';
+ levl[xdnstair][ydnstair].typ = STAIRS;
+ if(nroom > 1) {
+ troom = croom;
+ croom = &rooms[rn2(nroom-1)];
+ if(croom >= troom) croom++;
+ }
+ xupstair = somex(); /* %% < and > might be in the same place */
+ yupstair = somey();
+ levl[xupstair][yupstair].scrsym ='<';
+ levl[xupstair][yupstair].typ = STAIRS;
+
+ /* for each room: put things inside */
+ for(croom = rooms; croom->hx > 0; croom++) {
+
+ /* put a sleeping monster inside */
+ /* Note: monster may be on the stairs. This cannot be
+ avoided: maybe the player fell through a trapdoor
+ while a monster was on the stairs. Conclusion:
+ we have to check for monsters on the stairs anyway. */
+ if(!rn2(3)) (void)
+ makemon((struct permonst *) 0, somex(), somey());
+
+ /* put traps and mimics inside */
+ goldseen = FALSE;
+ while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
+ if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey());
+ if(!rn2(3)) {
+ (void) mkobj_at(0, somex(), somey());
+ tryct = 0;
+ while(!rn2(5)) {
+ if(++tryct > 100){
+ printf("tryct overflow4\n");
+ break;
+ }
+ (void) mkobj_at(0, somex(), somey());
+ }
+ }
+ }
+
+ qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
+ makecorridors();
+ make_niches();
+
+ /* make a secret treasure vault, not connected to the rest */
+ if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) {
+ troom = &rooms[nroom];
+ secret = TRUE;
+ if(makerooms()) {
+ troom->rtype = VAULT; /* treasure vault */
+ for(x = troom->lx; x <= troom->hx; x++)
+ for(y = troom->ly; y <= troom->hy; y++)
+ mkgold((long)(rnd(dlevel*100) + 50), x, y);
+ if(!rn2(3))
+ makevtele();
+ }
+ }
+
+#ifndef QUEST
+#ifdef WIZARD
+ if(wizard && getenv("SHOPTYPE")) mkshop(); else
+#endif WIZARD
+ if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop();
+ else
+ if(dlevel > 6 && !rn2(7)) mkzoo(ZOO);
+ else
+ if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE);
+ else
+ if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE);
+ else
+ if(dlevel > 18 && !rn2(6)) mkswamp();
+#endif QUEST
+}
+
+makerooms() {
+register struct rectangle *rsp;
+register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
+int tryct = 0, xlim, ylim;
+
+ /* init */
+ xlim = XLIM + secret;
+ ylim = YLIM + secret;
+ if(nroom == 0) {
+ rsp = rs;
+ rsp->rlx = rsp->rly = 0;
+ rsp->rhx = COLNO-1;
+ rsp->rhy = ROWNO-1;
+ rsmax = 1;
+ }
+ rscnt = rsmax;
+
+ /* make rooms until satisfied */
+ while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
+ if(!secret && nroom > (MAXNROFROOMS/3) &&
+ !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
+ return(0);
+
+ /* pick a rectangle */
+ rsp = &rs[rn2(rscnt)];
+ hx = rsp->rhx;
+ hy = rsp->rhy;
+ lx = rsp->rlx;
+ ly = rsp->rly;
+
+ /* find size of room */
+ if(secret)
+ dx = dy = 1;
+ else {
+ dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
+ dy = 2 + rn2(4);
+ if(dx*dy > 50)
+ dy = 50/dx;
+ }
+
+ /* look whether our room will fit */
+ if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) {
+ /* no, too small */
+ /* maybe we throw this area out */
+ if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
+ rscnt--;
+ rs[rsmax] = *rsp;
+ *rsp = rs[rscnt];
+ rs[rscnt] = rs[rsmax];
+ tryct = 0;
+ } else
+ tryct++;
+ continue;
+ }
+
+ lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
+ lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
+ hix = lowx + dx;
+ hiy = lowy + dy;
+
+ if(maker(lowx, dx, lowy, dy)) {
+ if(secret)
+ return(1);
+ addrs(lowx-1, lowy-1, hix+1, hiy+1);
+ tryct = 0;
+ } else
+ if(tryct++ > 100)
+ break;
+ }
+ return(0); /* failed to make vault - very strange */
+}
+
+addrs(lowx,lowy,hix,hiy)
+register int lowx,lowy,hix,hiy;
+{
+ register struct rectangle *rsp;
+ register int lx,ly,hx,hy,xlim,ylim;
+ boolean discarded;
+
+ xlim = XLIM + secret;
+ ylim = YLIM + secret;
+
+ /* walk down since rscnt and rsmax change */
+ for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
+
+ if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
+ (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
+ continue;
+ if((discarded = (rsp >= &rs[rscnt]))) {
+ *rsp = rs[--rsmax];
+ } else {
+ rsmax--;
+ rscnt--;
+ *rsp = rs[rscnt];
+ if(rscnt != rsmax)
+ rs[rscnt] = rs[rsmax];
+ }
+ if(lowy - ly > 2*ylim + 4)
+ addrsx(lx,ly,hx,lowy-2,discarded);
+ if(lowx - lx > 2*xlim + 4)
+ addrsx(lx,ly,lowx-2,hy,discarded);
+ if(hy - hiy > 2*ylim + 4)
+ addrsx(lx,hiy+2,hx,hy,discarded);
+ if(hx - hix > 2*xlim + 4)
+ addrsx(hix+2,ly,hx,hy,discarded);
+ }
+}
+
+addrsx(lx,ly,hx,hy,discarded)
+register int lx,ly,hx,hy;
+boolean discarded; /* piece of a discarded area */
+{
+ register struct rectangle *rsp;
+
+ /* check inclusions */
+ for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
+ if(lx >= rsp->rlx && hx <= rsp->rhx &&
+ ly >= rsp->rly && hy <= rsp->rhy)
+ return;
+ }
+
+ /* make a new entry */
+ if(rsmax >= MAXRS) {
+#ifdef WIZARD
+ if(wizard) pline("MAXRS may be too small.");
+#endif WIZARD
+ return;
+ }
+ rsmax++;
+ if(!discarded) {
+ *rsp = rs[rscnt];
+ rsp = &rs[rscnt];
+ rscnt++;
+ }
+ rsp->rlx = lx;
+ rsp->rly = ly;
+ rsp->rhx = hx;
+ rsp->rhy = hy;
+}
+
+comp(x,y)
+register struct mkroom *x,*y;
+{
+ if(x->lx < y->lx) return(-1);
+ return(x->lx > y->lx);
+}
+
+coord
+finddpos(xl,yl,xh,yh) {
+ coord ff;
+ register x,y;
+
+ x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
+ y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
+ if(okdoor(x, y))
+ goto gotit;
+
+ for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
+ if(okdoor(x, y))
+ goto gotit;
+
+ for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
+ if(levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR)
+ goto gotit;
+ /* cannot find something reasonable -- strange */
+ x = xl;
+ y = yh;
+gotit:
+ ff.x = x;
+ ff.y = y;
+ return(ff);
+}
+
+/* see whether it is allowable to create a door at [x,y] */
+okdoor(x,y)
+register x,y;
+{
+ if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||
+ levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||
+ levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||
+ levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||
+ (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||
+ doorindex >= DOORMAX)
+ return(0);
+ return(1);
+}
+
+dodoor(x,y,aroom)
+register x,y;
+register struct mkroom *aroom;
+{
+ if(doorindex >= DOORMAX) {
+ impossible("DOORMAX exceeded?");
+ return;
+ }
+ if(!okdoor(x,y) && nxcor)
+ return;
+ dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
+}
+
+dosdoor(x,y,aroom,type)
+register x,y;
+register struct mkroom *aroom;
+register type;
+{
+ register struct mkroom *broom;
+ register tmp;
+
+ if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with '+' as scrsym */
+ type = DOOR;
+ levl[x][y].typ = type;
+ if(type == DOOR)
+ levl[x][y].scrsym = '+';
+ aroom->doorct++;
+ broom = aroom+1;
+ if(broom->hx < 0) tmp = doorindex; else
+ for(tmp = doorindex; tmp > broom->fdoor; tmp--)
+ doors[tmp] = doors[tmp-1];
+ doorindex++;
+ doors[tmp].x = x;
+ doors[tmp].y = y;
+ for( ; broom->hx >= 0; broom++) broom->fdoor++;
+}
+
+/* Only called from makerooms() */
+maker(lowx,ddx,lowy,ddy)
+schar lowx,ddx,lowy,ddy;
+{
+ register struct mkroom *croom;
+ register x, y, hix = lowx+ddx, hiy = lowy+ddy;
+ register xlim = XLIM + secret, ylim = YLIM + secret;
+
+ if(nroom >= MAXNROFROOMS) return(0);
+ if(lowx < XLIM) lowx = XLIM;
+ if(lowy < YLIM) lowy = YLIM;
+ if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
+ if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
+chk:
+ if(hix <= lowx || hiy <= lowy) return(0);
+
+ /* check area around room (and make room smaller if necessary) */
+ for(x = lowx - xlim; x <= hix + xlim; x++) {
+ for(y = lowy - ylim; y <= hiy + ylim; y++) {
+ if(levl[x][y].typ) {
+#ifdef WIZARD
+ if(wizard && !secret)
+ pline("Strange area [%d,%d] in maker().",x,y);
+#endif WIZARD
+ if(!rn2(3)) return(0);
+ if(x < lowx)
+ lowx = x+xlim+1;
+ else
+ hix = x-xlim-1;
+ if(y < lowy)
+ lowy = y+ylim+1;
+ else
+ hiy = y-ylim-1;
+ goto chk;
+ }
+ }
+ }
+
+ croom = &rooms[nroom];
+
+ /* on low levels the room is lit (usually) */
+ /* secret vaults are always lit */
+ if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) {
+ for(x = lowx-1; x <= hix+1; x++)
+ for(y = lowy-1; y <= hiy+1; y++)
+ levl[x][y].lit = 1;
+ croom->rlit = 1;
+ } else
+ croom->rlit = 0;
+ croom->lx = lowx;
+ croom->hx = hix;
+ croom->ly = lowy;
+ croom->hy = hiy;
+ croom->rtype = croom->doorct = croom->fdoor = 0;
+
+ for(x = lowx-1; x <= hix+1; x++)
+ for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
+ levl[x][y].scrsym = '-';
+ levl[x][y].typ = HWALL;
+ }
+ for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
+ for(y = lowy; y <= hiy; y++) {
+ levl[x][y].scrsym = '|';
+ levl[x][y].typ = VWALL;
+ }
+ for(x = lowx; x <= hix; x++)
+ for(y = lowy; y <= hiy; y++) {
+ levl[x][y].scrsym = '.';
+ levl[x][y].typ = ROOM;
+ }
+
+ smeq[nroom] = nroom;
+ croom++;
+ croom->hx = -1;
+ nroom++;
+ return(1);
+}
+
+makecorridors() {
+ register a,b;
+
+ nxcor = 0;
+ for(a = 0; a < nroom-1; a++)
+ join(a, a+1);
+ for(a = 0; a < nroom-2; a++)
+ if(smeq[a] != smeq[a+2])
+ join(a, a+2);
+ for(a = 0; a < nroom; a++)
+ for(b = 0; b < nroom; b++)
+ if(smeq[a] != smeq[b])
+ join(a, b);
+ if(nroom > 2)
+ for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
+ a = rn2(nroom);
+ b = rn2(nroom-2);
+ if(b >= a) b += 2;
+ join(a, b);
+ }
+}
+
+join(a,b)
+register a,b;
+{
+ coord cc,tt;
+ register tx, ty, xx, yy;
+ register struct rm *crm;
+ register struct mkroom *croom, *troom;
+ register dx, dy, dix, diy, cct;
+
+ croom = &rooms[a];
+ troom = &rooms[b];
+
+ /* find positions cc and tt for doors in croom and troom
+ and direction for a corridor between them */
+
+ if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
+ if(troom->lx > croom->hx) {
+ dx = 1;
+ dy = 0;
+ xx = croom->hx+1;
+ tx = troom->lx-1;
+ cc = finddpos(xx,croom->ly,xx,croom->hy);
+ tt = finddpos(tx,troom->ly,tx,troom->hy);
+ } else if(troom->hy < croom->ly) {
+ dy = -1;
+ dx = 0;
+ yy = croom->ly-1;
+ cc = finddpos(croom->lx,yy,croom->hx,yy);
+ ty = troom->hy+1;
+ tt = finddpos(troom->lx,ty,troom->hx,ty);
+ } else if(troom->hx < croom->lx) {
+ dx = -1;
+ dy = 0;
+ xx = croom->lx-1;
+ tx = troom->hx+1;
+ cc = finddpos(xx,croom->ly,xx,croom->hy);
+ tt = finddpos(tx,troom->ly,tx,troom->hy);
+ } else {
+ dy = 1;
+ dx = 0;
+ yy = croom->hy+1;
+ ty = troom->ly-1;
+ cc = finddpos(croom->lx,yy,croom->hx,yy);
+ tt = finddpos(troom->lx,ty,troom->hx,ty);
+ }
+ xx = cc.x;
+ yy = cc.y;
+ tx = tt.x - dx;
+ ty = tt.y - dy;
+ if(nxcor && levl[xx+dx][yy+dy].typ)
+ return;
+ dodoor(xx,yy,croom);
+
+ cct = 0;
+ while(xx != tx || yy != ty) {
+ xx += dx;
+ yy += dy;
+
+ /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
+ if(cct++ > 500 || (nxcor && !rn2(35)))
+ return;
+
+ if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
+ return; /* impossible */
+
+ crm = &levl[xx][yy];
+ if(!(crm->typ)) {
+ if(rn2(100)) {
+ crm->typ = CORR;
+ crm->scrsym = CORR_SYM;
+ if(nxcor && !rn2(50))
+ (void) mkobj_at(ROCK_SYM, xx, yy);
+ } else {
+ crm->typ = SCORR;
+ crm->scrsym = ' ';
+ }
+ } else
+ if(crm->typ != CORR && crm->typ != SCORR) {
+ /* strange ... */
+ return;
+ }
+
+ /* find next corridor position */
+ dix = abs(xx-tx);
+ diy = abs(yy-ty);
+
+ /* do we have to change direction ? */
+ if(dy && dix > diy) {
+ register ddx = (xx > tx) ? -1 : 1;
+
+ crm = &levl[xx+ddx][yy];
+ if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
+ dx = ddx;
+ dy = 0;
+ continue;
+ }
+ } else if(dx && diy > dix) {
+ register ddy = (yy > ty) ? -1 : 1;
+
+ crm = &levl[xx][yy+ddy];
+ if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
+ dy = ddy;
+ dx = 0;
+ continue;
+ }
+ }
+
+ /* continue straight on? */
+ crm = &levl[xx+dx][yy+dy];
+ if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
+ continue;
+
+ /* no, what must we do now?? */
+ if(dx) {
+ dx = 0;
+ dy = (ty < yy) ? -1 : 1;
+ crm = &levl[xx+dx][yy+dy];
+ if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
+ continue;
+ dy = -dy;
+ continue;
+ } else {
+ dy = 0;
+ dx = (tx < xx) ? -1 : 1;
+ crm = &levl[xx+dx][yy+dy];
+ if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
+ continue;
+ dx = -dx;
+ continue;
+ }
+ }
+
+ /* we succeeded in digging the corridor */
+ dodoor(tt.x, tt.y, troom);
+
+ if(smeq[a] < smeq[b])
+ smeq[b] = smeq[a];
+ else
+ smeq[a] = smeq[b];
+}
+
+make_niches()
+{
+ register int ct = rnd(nroom/2 + 1);
+ while(ct--) makeniche(FALSE);
+}
+
+makevtele()
+{
+ makeniche(TRUE);
+}
+
+makeniche(with_trap)
+boolean with_trap;
+{
+ register struct mkroom *aroom;
+ register struct rm *rm;
+ register int vct = 8;
+ coord dd;
+ register dy,xx,yy;
+ register struct trap *ttmp;
+
+ if(doorindex < DOORMAX)
+ while(vct--) {
+ aroom = &rooms[rn2(nroom-1)];
+ if(aroom->rtype != 0) continue; /* not an ordinary room */
+ if(aroom->doorct == 1 && rn2(5)) continue;
+ if(rn2(2)) {
+ dy = 1;
+ dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1);
+ } else {
+ dy = -1;
+ dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1);
+ }
+ xx = dd.x;
+ yy = dd.y;
+ if((rm = &levl[xx][yy+dy])->typ) continue;
+ if(with_trap || !rn2(4)) {
+ rm->typ = SCORR;
+ rm->scrsym = ' ';
+ if(with_trap) {
+ ttmp = maketrap(xx, yy+dy, TELEP_TRAP);
+ ttmp->once = 1;
+ make_engr_at(xx, yy-dy, "ad ae?ar um");
+ }
+ dosdoor(xx, yy, aroom, SDOOR);
+ } else {
+ rm->typ = CORR;
+ rm->scrsym = CORR_SYM;
+ if(rn2(7))
+ dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
+ else {
+ mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
+ if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
+ }
+ }
+ return;
+ }
+}
+
+/* make a trap somewhere (in croom if mazeflag = 0) */
+mktrap(num,mazeflag,croom)
+register num,mazeflag;
+register struct mkroom *croom;
+{
+ register struct trap *ttmp;
+ register int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0;
+ register xchar mx,my;
+ extern char fut_geno[];
+
+ if(!num || num >= TRAPNUM) {
+ nopierc = (dlevel < 4) ? 1 : 0;
+ nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
+ if(index(fut_geno, 'M')) nomimic = 1;
+ kind = rn2(TRAPNUM - nopierc - nomimic);
+ /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */
+ } else kind = num;
+
+ if(kind == MIMIC) {
+ register struct monst *mtmp;
+
+ fakedoor = (!rn2(3) && !mazeflag);
+ fakegold = (!fakedoor && !rn2(2));
+ if(fakegold) goldseen = TRUE;
+ do {
+ if(++tryct > 200) return;
+ if(fakedoor) {
+ /* note: fakedoor maybe on actual door */
+ if(rn2(2)){
+ if(rn2(2))
+ mx = croom->hx+1;
+ else mx = croom->lx-1;
+ my = somey();
+ } else {
+ if(rn2(2))
+ my = croom->hy+1;
+ else my = croom->ly-1;
+ mx = somex();
+ }
+ } else if(mazeflag) {
+ extern coord mazexy();
+ coord mm;
+ mm = mazexy();
+ mx = mm.x;
+ my = mm.y;
+ } else {
+ mx = somex();
+ my = somey();
+ }
+ } while(m_at(mx,my) || levl[mx][my].typ == STAIRS);
+ if(mtmp = makemon(PM_MIMIC,mx,my)) {
+ mtmp->mimic = 1;
+ mtmp->mappearance =
+ fakegold ? '$' : fakedoor ? '+' :
+ (mazeflag && rn2(2)) ? AMULET_SYM :
+ "=/)%?![<>" [ rn2(9) ];
+ }
+ return;
+ }
+
+ do {
+ if(++tryct > 200)
+ return;
+ if(mazeflag){
+ extern coord mazexy();
+ coord mm;
+ mm = mazexy();
+ mx = mm.x;
+ my = mm.y;
+ } else {
+ mx = somex();
+ my = somey();
+ }
+ } while(t_at(mx, my) || levl[mx][my].typ == STAIRS);
+ ttmp = maketrap(mx, my, kind);
+ if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC)
+ ttmp->tseen = 1;
+}
diff --git a/hack/hack.mkmaze.c b/hack/hack.mkmaze.c
new file mode 100644
index 00000000..bee24f95
--- /dev/null
+++ b/hack/hack.mkmaze.c
@@ -0,0 +1,136 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.mkmaze.c - version 1.0.2 */
+
+#include "hack.h"
+#include "def.mkroom.h" /* not really used */
+extern struct monst *makemon();
+extern struct permonst pm_wizard;
+extern struct obj *mkobj_at();
+extern coord mazexy();
+struct permonst hell_hound =
+ { "hell hound", 'd', 12, 14, 2, 3, 6, 0 };
+
+makemaz()
+{
+ int x,y;
+ register zx,zy;
+ coord mm;
+ boolean al = (dlevel >= 30 && !flags.made_amulet);
+
+ for(x = 2; x < COLNO-1; x++)
+ for(y = 2; y < ROWNO-1; y++)
+ levl[x][y].typ = (x%2 && y%2) ? 0 : HWALL;
+ if(al) {
+ register struct monst *mtmp;
+
+ zx = 2*(COLNO/4) - 1;
+ zy = 2*(ROWNO/4) - 1;
+ for(x = zx-2; x < zx+4; x++) for(y = zy-2; y <= zy+2; y++) {
+ levl[x][y].typ =
+ (y == zy-2 || y == zy+2 || x == zx-2 || x == zx+3) ? POOL :
+ (y == zy-1 || y == zy+1 || x == zx-1 || x == zx+2) ? HWALL:
+ ROOM;
+ }
+ (void) mkobj_at(AMULET_SYM, zx, zy);
+ flags.made_amulet = 1;
+ walkfrom(zx+4, zy);
+ if(mtmp = makemon(&hell_hound, zx, zy))
+ mtmp->msleep = 1;
+ if(mtmp = makemon(PM_WIZARD, zx+1, zy)) {
+ mtmp->msleep = 1;
+ flags.no_of_wizards = 1;
+ }
+ } else {
+ mm = mazexy();
+ zx = mm.x;
+ zy = mm.y;
+ walkfrom(zx,zy);
+ (void) mksobj_at(WAN_WISHING, zx, zy);
+ (void) mkobj_at(ROCK_SYM, zx, zy); /* put a rock on top of it */
+ }
+
+ for(x = 2; x < COLNO-1; x++)
+ for(y = 2; y < ROWNO-1; y++) {
+ switch(levl[x][y].typ) {
+ case HWALL:
+ levl[x][y].scrsym = '-';
+ break;
+ case ROOM:
+ levl[x][y].scrsym = '.';
+ break;
+ }
+ }
+ for(x = rn1(8,11); x; x--) {
+ mm = mazexy();
+ (void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y);
+ }
+ for(x = rn1(10,2); x; x--) {
+ mm = mazexy();
+ (void) mkobj_at(ROCK_SYM, mm.x, mm.y);
+ }
+ mm = mazexy();
+ (void) makemon(PM_MINOTAUR, mm.x, mm.y);
+ for(x = rn1(5,7); x; x--) {
+ mm = mazexy();
+ (void) makemon((struct permonst *) 0, mm.x, mm.y);
+ }
+ for(x = rn1(6,7); x; x--) {
+ mm = mazexy();
+ mkgold(0L,mm.x,mm.y);
+ }
+ for(x = rn1(6,7); x; x--)
+ mktrap(0,1,(struct mkroom *) 0);
+ mm = mazexy();
+ levl[(xupstair = mm.x)][(yupstair = mm.y)].scrsym = '<';
+ levl[xupstair][yupstair].typ = STAIRS;
+ xdnstair = ydnstair = 0;
+}
+
+walkfrom(x,y) int x,y; {
+register int q,a,dir;
+int dirs[4];
+ levl[x][y].typ = ROOM;
+ while(1) {
+ q = 0;
+ for(a = 0; a < 4; a++)
+ if(okay(x,y,a)) dirs[q++]= a;
+ if(!q) return;
+ dir = dirs[rn2(q)];
+ move(&x,&y,dir);
+ levl[x][y].typ = ROOM;
+ move(&x,&y,dir);
+ walkfrom(x,y);
+ }
+}
+
+move(x,y,dir)
+register int *x, *y;
+register int dir;
+{
+ switch(dir){
+ case 0: --(*y); break;
+ case 1: (*x)++; break;
+ case 2: (*y)++; break;
+ case 3: --(*x); break;
+ }
+}
+
+okay(x,y,dir)
+int x,y;
+register int dir;
+{
+ move(&x,&y,dir);
+ move(&x,&y,dir);
+ if(x<3 || y<3 || x>COLNO-3 || y>ROWNO-3 || levl[x][y].typ != 0)
+ return(0);
+ else
+ return(1);
+}
+
+coord
+mazexy(){
+ coord mm;
+ mm.x = 3 + 2*rn2(COLNO/2 - 2);
+ mm.y = 3 + 2*rn2(ROWNO/2 - 2);
+ return mm;
+}
diff --git a/hack/hack.mkobj.c b/hack/hack.mkobj.c
new file mode 100644
index 00000000..18a69146
--- /dev/null
+++ b/hack/hack.mkobj.c
@@ -0,0 +1,148 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.mkobj.c - version 1.0.3 */
+
+#include "hack.h"
+
+char mkobjstr[] = "))[[!!!!????%%%%/=**))[[!!!!????%%%%/=**(%";
+struct obj *mkobj(), *mksobj();
+
+struct obj *
+mkobj_at(let,x,y)
+register let,x,y;
+{
+ register struct obj *otmp = mkobj(let);
+ otmp->ox = x;
+ otmp->oy = y;
+ otmp->nobj = fobj;
+ fobj = otmp;
+ return(otmp);
+}
+
+mksobj_at(otyp,x,y)
+register otyp,x,y;
+{
+ register struct obj *otmp = mksobj(otyp);
+ otmp->ox = x;
+ otmp->oy = y;
+ otmp->nobj = fobj;
+ fobj = otmp;
+}
+
+struct obj *
+mkobj(let) {
+ if(!let)
+ let = mkobjstr[rn2(sizeof(mkobjstr) - 1)];
+ return(
+ mksobj(
+ letter(let) ?
+ CORPSE + ((let > 'Z') ? (let-'a'+'Z'-'@'+1) : (let-'@'))
+ : probtype(let)
+ )
+ );
+}
+
+
+struct obj zeroobj;
+
+struct obj *
+mksobj(otyp)
+register otyp;
+{
+ register struct obj *otmp;
+ char let = objects[otyp].oc_olet;
+
+ otmp = newobj(0);
+ *otmp = zeroobj;
+ otmp->age = moves;
+ otmp->o_id = flags.ident++;
+ otmp->quan = 1;
+ otmp->olet = let;
+ otmp->otyp = otyp;
+ otmp->dknown = index("/=!?*", let) ? 0 : 1;
+ switch(let) {
+ case WEAPON_SYM:
+ otmp->quan = (otmp->otyp <= ROCK) ? rn1(6,6) : 1;
+ if(!rn2(11)) otmp->spe = rnd(3);
+ else if(!rn2(10)) {
+ otmp->cursed = 1;
+ otmp->spe = -rnd(3);
+ }
+ break;
+ case FOOD_SYM:
+ if(otmp->otyp >= CORPSE) break;
+#ifdef NOT_YET_IMPLEMENTED
+ /* if tins are to be identified, need to adapt doname() etc */
+ if(otmp->otyp == TIN)
+ otmp->spe = rnd(...);
+#endif NOT_YET_IMPLEMENTED
+ /* fall into next case */
+ case GEM_SYM:
+ otmp->quan = rn2(6) ? 1 : 2;
+ case TOOL_SYM:
+ case CHAIN_SYM:
+ case BALL_SYM:
+ case ROCK_SYM:
+ case POTION_SYM:
+ case SCROLL_SYM:
+ case AMULET_SYM:
+ break;
+ case ARMOR_SYM:
+ if(!rn2(8)) otmp->cursed = 1;
+ if(!rn2(10)) otmp->spe = rnd(3);
+ else if(!rn2(9)) {
+ otmp->spe = -rnd(3);
+ otmp->cursed = 1;
+ }
+ break;
+ case WAND_SYM:
+ if(otmp->otyp == WAN_WISHING) otmp->spe = 3; else
+ otmp->spe = rn1(5,
+ (objects[otmp->otyp].bits & NODIR) ? 11 : 4);
+ break;
+ case RING_SYM:
+ if(objects[otmp->otyp].bits & SPEC) {
+ if(!rn2(3)) {
+ otmp->cursed = 1;
+ otmp->spe = -rnd(2);
+ } else otmp->spe = rnd(2);
+ } else if(otmp->otyp == RIN_TELEPORTATION ||
+ otmp->otyp == RIN_AGGRAVATE_MONSTER ||
+ otmp->otyp == RIN_HUNGER || !rn2(9))
+ otmp->cursed = 1;
+ break;
+ default:
+ panic("impossible mkobj");
+ }
+ otmp->owt = weight(otmp);
+ return(otmp);
+}
+
+letter(c) {
+ return(('@' <= c && c <= 'Z') || ('a' <= c && c <= 'z'));
+}
+
+weight(obj)
+register struct obj *obj;
+{
+register int wt = objects[obj->otyp].oc_weight;
+ return(wt ? wt*obj->quan : (obj->quan + 1)/2);
+}
+
+mkgold(num,x,y)
+register long num;
+{
+ register struct gold *gold;
+ register long amount = (num ? num : 1 + (rnd(dlevel+2) * rnd(30)));
+
+ if(gold = g_at(x,y))
+ gold->amount += amount;
+ else {
+ gold = newgold();
+ gold->ngold = fgold;
+ gold->gx = x;
+ gold->gy = y;
+ gold->amount = amount;
+ fgold = gold;
+ /* do sth with display? */
+ }
+}
diff --git a/hack/hack.mkshop.c b/hack/hack.mkshop.c
new file mode 100644
index 00000000..9d99a22d
--- /dev/null
+++ b/hack/hack.mkshop.c
@@ -0,0 +1,274 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.mkshop.c - version 1.0.3 */
+
+#ifndef QUEST
+#include "hack.h"
+#include "def.mkroom.h"
+#include "def.eshk.h"
+#define ESHK ((struct eshk *)(&(shk->mextra[0])))
+extern struct monst *makemon();
+extern struct obj *mkobj_at();
+extern int nroom;
+extern char shtypes[]; /* = "=/)%?!["; 8 types: 7 specialized, 1 mixed */
+schar shprobs[] = { 3,3,5,5,10,10,14,50 }; /* their probabilities */
+
+mkshop(){
+register struct mkroom *sroom;
+register int sh,sx,sy,i = -1;
+register char let;
+int roomno;
+register struct monst *shk;
+#ifdef WIZARD
+ /* first determine shoptype */
+ if(wizard){
+ extern char *getenv();
+ register char *ep = getenv("SHOPTYPE");
+ if(ep){
+ if(*ep == 'z' || *ep == 'Z'){
+ mkzoo(ZOO);
+ return;
+ }
+ if(*ep == 'm' || *ep == 'M'){
+ mkzoo(MORGUE);
+ return;
+ }
+ if(*ep == 'b' || *ep == 'B'){
+ mkzoo(BEEHIVE);
+ return;
+ }
+ if(*ep == 's' || *ep == 'S'){
+ mkswamp();
+ return;
+ }
+ for(i=0; shtypes[i]; i++)
+ if(*ep == shtypes[i]) break;
+ goto gottype;
+ }
+ }
+gottype:
+#endif WIZARD
+ for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){
+ if(sroom->hx < 0) return;
+ if(sroom - rooms >= nroom) {
+ pline("rooms not closed by -1?");
+ return;
+ }
+ if(sroom->rtype) continue;
+ if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
+ continue;
+ if(
+#ifdef WIZARD
+ (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) ||
+#endif WIZARD
+ sroom->doorct <= 2 && sroom->doorct > 0) break;
+ }
+
+ if(i < 0) { /* shoptype not yet determined */
+ register int j;
+
+ for(j = rn2(100), i = 0; (j -= shprobs[i])>= 0; i++)
+ if(!shtypes[i]) break; /* superfluous */
+ if(isbig(sroom) && i + SHOPBASE == WANDSHOP)
+ i = GENERAL-SHOPBASE;
+ }
+ sroom->rtype = i + SHOPBASE;
+ let = shtypes[i];
+ sh = sroom->fdoor;
+ sx = doors[sh].x;
+ sy = doors[sh].y;
+ if(sx == sroom->lx-1) sx++; else
+ if(sx == sroom->hx+1) sx--; else
+ if(sy == sroom->ly-1) sy++; else
+ if(sy == sroom->hy+1) sy--; else {
+#ifdef WIZARD
+ /* This is said to happen sometimes, but I've never seen it. */
+ if(wizard) {
+ register int j = sroom->doorct;
+ extern int doorindex;
+
+ pline("Where is shopdoor?");
+ pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly,
+ sroom->hx, sroom->hy);
+ pline("doormax=%d doorct=%d fdoor=%d",
+ doorindex, sroom->doorct, sh);
+ while(j--) {
+ pline("door [%d,%d]", doors[sh].x, doors[sh].y);
+ sh++;
+ }
+ more();
+ }
+#endif WIZARD
+ return;
+ }
+ if(!(shk = makemon(PM_SHK,sx,sy))) return;
+ shk->isshk = shk->mpeaceful = 1;
+ shk->msleep = 0;
+ shk->mtrapseen = ~0; /* we know all the traps already */
+ ESHK->shoproom = roomno;
+ ESHK->shoplevel = dlevel;
+ ESHK->shd = doors[sh];
+ ESHK->shk.x = sx;
+ ESHK->shk.y = sy;
+ ESHK->robbed = 0;
+ ESHK->visitct = 0;
+ ESHK->following = 0;
+ shk->mgold = 1000 + 30*rnd(100); /* initial capital */
+ ESHK->billct = 0;
+ findname(ESHK->shknam, let);
+ for(sx = sroom->lx; sx <= sroom->hx; sx++)
+ for(sy = sroom->ly; sy <= sroom->hy; sy++){
+ register struct monst *mtmp;
+ if((sx == sroom->lx && doors[sh].x == sx-1) ||
+ (sx == sroom->hx && doors[sh].x == sx+1) ||
+ (sy == sroom->ly && doors[sh].y == sy-1) ||
+ (sy == sroom->hy && doors[sh].y == sy+1)) continue;
+ if(rn2(100) < dlevel && !m_at(sx,sy) &&
+ (mtmp = makemon(PM_MIMIC, sx, sy))){
+ mtmp->mimic = 1;
+ mtmp->mappearance =
+ (let && rn2(10) < dlevel) ? let : ']';
+ continue;
+ }
+ (void) mkobj_at(let, sx, sy);
+ }
+}
+
+mkzoo(type)
+int type;
+{
+ register struct mkroom *sroom;
+ register struct monst *mon;
+ register int sh,sx,sy,i;
+ int goldlim = 500 * dlevel;
+ int moct = 0;
+ struct permonst *morguemon();
+
+ i = nroom;
+ for(sroom = &rooms[rn2(nroom)]; ; sroom++) {
+ if(sroom == &rooms[nroom])
+ sroom = &rooms[0];
+ if(!i-- || sroom->hx < 0)
+ return;
+ if(sroom->rtype)
+ continue;
+ if(type == MORGUE && sroom->rlit)
+ continue;
+ if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
+ continue;
+ if(sroom->doorct == 1 || !rn2(5))
+ break;
+ }
+ sroom->rtype = type;
+ sh = sroom->fdoor;
+ for(sx = sroom->lx; sx <= sroom->hx; sx++)
+ for(sy = sroom->ly; sy <= sroom->hy; sy++){
+ if((sx == sroom->lx && doors[sh].x == sx-1) ||
+ (sx == sroom->hx && doors[sh].x == sx+1) ||
+ (sy == sroom->ly && doors[sh].y == sy-1) ||
+ (sy == sroom->hy && doors[sh].y == sy+1)) continue;
+ mon = makemon(
+ (type == MORGUE) ? morguemon() :
+ (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0,
+ sx, sy);
+ if(mon) mon->msleep = 1;
+ switch(type) {
+ case ZOO:
+ i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
+ if(i >= goldlim) i = 5*dlevel;
+ goldlim -= i;
+ mkgold((long)(10 + rn2(i)), sx, sy);
+ break;
+ case MORGUE:
+ /* Usually there is one dead body in the morgue */
+ if(!moct && rn2(3)) {
+ mksobj_at(CORPSE, sx, sy);
+ moct++;
+ }
+ break;
+ case BEEHIVE:
+ if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
+ break;
+ }
+ }
+}
+
+struct permonst *
+morguemon()
+{
+ extern struct permonst pm_ghost;
+ register int i = rn2(100), hd = rn2(dlevel);
+
+ if(hd > 10 && i < 10) return(PM_DEMON);
+ if(hd > 8 && i > 85) return(PM_VAMPIRE);
+ return((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE);
+}
+
+mkswamp() /* Michiel Huisjes & Fred de Wilde */
+{
+ register struct mkroom *sroom;
+ register int sx,sy,i,eelct = 0;
+ extern struct permonst pm_eel;
+
+ for(i=0; i<5; i++) { /* 5 tries */
+ sroom = &rooms[rn2(nroom)];
+ if(sroom->hx < 0 || sroom->rtype ||
+ has_upstairs(sroom) || has_dnstairs(sroom))
+ continue;
+
+ /* satisfied; make a swamp */
+ sroom->rtype = SWAMP;
+ for(sx = sroom->lx; sx <= sroom->hx; sx++)
+ for(sy = sroom->ly; sy <= sroom->hy; sy++)
+ if((sx+sy)%2 && !o_at(sx,sy) && !t_at(sx,sy)
+ && !m_at(sx,sy) && !nexttodoor(sx,sy)){
+ levl[sx][sy].typ = POOL;
+ levl[sx][sy].scrsym = POOL_SYM;
+ if(!eelct || !rn2(4)) {
+ (void) makemon(PM_EEL, sx, sy);
+ eelct++;
+ }
+ }
+ }
+}
+
+nexttodoor(sx,sy)
+register sx,sy;
+{
+ register dx,dy;
+ register struct rm *lev;
+ for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
+ if((lev = &levl[sx+dx][sy+dy])->typ == DOOR ||
+ lev->typ == SDOOR || lev->typ == LDOOR)
+ return(1);
+ return(0);
+}
+
+has_dnstairs(sroom)
+register struct mkroom *sroom;
+{
+ return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
+ sroom->ly <= ydnstair && ydnstair <= sroom->hy);
+}
+
+has_upstairs(sroom)
+register struct mkroom *sroom;
+{
+ return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
+ sroom->ly <= yupstair && yupstair <= sroom->hy);
+}
+
+isbig(sroom)
+register struct mkroom *sroom;
+{
+ register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
+ return( area > 20 );
+}
+
+dist2(x0,y0,x1,y1){
+ return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
+}
+
+sq(a) int a; {
+ return(a*a);
+}
+#endif QUEST
diff --git a/hack/hack.mon.c b/hack/hack.mon.c
new file mode 100644
index 00000000..b31c1592
--- /dev/null
+++ b/hack/hack.mon.c
@@ -0,0 +1,853 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.mon.c - version 1.0.3 */
+
+#include "hack.h"
+#include "hack.mfndpos.h"
+
+#ifndef NULL
+#define NULL (char *) 0
+#endif
+
+extern struct monst *makemon();
+extern struct obj *mkobj_at();
+
+int warnlevel; /* used by movemon and dochugw */
+long lastwarntime;
+int lastwarnlev;
+char *warnings[] = {
+ "white", "pink", "red", "ruby", "purple", "black"
+};
+
+movemon()
+{
+ register struct monst *mtmp;
+ register int fr;
+
+ warnlevel = 0;
+
+ while(1) {
+ /* find a monster that we haven't treated yet */
+ /* note that mtmp or mtmp->nmon might get killed
+ while mtmp moves, so we cannot just walk down the
+ chain (even new monsters might get created!) */
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->mlstmv < moves) goto next_mon;
+ /* treated all monsters */
+ break;
+
+ next_mon:
+ mtmp->mlstmv = moves;
+
+ /* most monsters drown in pools */
+ { boolean inpool, iseel;
+
+ inpool = (levl[mtmp->mx][mtmp->my].typ == POOL);
+ iseel = (mtmp->data->mlet == ';');
+ if(inpool && !iseel) {
+ if(cansee(mtmp->mx,mtmp->my))
+ pline("%s drowns.", Monnam(mtmp));
+ mondead(mtmp);
+ continue;
+ }
+ /* but eels have a difficult time outside */
+ if(iseel && !inpool) {
+ if(mtmp->mhp > 1) mtmp->mhp--;
+ mtmp->mflee = 1;
+ mtmp->mfleetim += 2;
+ }
+ }
+ if(mtmp->mblinded && !--mtmp->mblinded)
+ mtmp->mcansee = 1;
+ if(mtmp->mfleetim && !--mtmp->mfleetim)
+ mtmp->mflee = 0;
+ if(mtmp->mimic) continue;
+ if(mtmp->mspeed != MSLOW || !(moves%2)){
+ /* continue if the monster died fighting */
+ fr = -1;
+ if(Conflict && cansee(mtmp->mx,mtmp->my)
+ && (fr = fightm(mtmp)) == 2)
+ continue;
+ if(fr<0 && dochugw(mtmp))
+ continue;
+ }
+ if(mtmp->mspeed == MFAST && dochugw(mtmp))
+ continue;
+ }
+
+ warnlevel -= u.ulevel;
+ if(warnlevel >= SIZE(warnings))
+ warnlevel = SIZE(warnings)-1;
+ if(warnlevel >= 0)
+ if(warnlevel > lastwarnlev || moves > lastwarntime + 5){
+ register char *rr;
+ switch(Warning & (LEFT_RING | RIGHT_RING)){
+ case LEFT_RING:
+ rr = "Your left ring glows";
+ break;
+ case RIGHT_RING:
+ rr = "Your right ring glows";
+ break;
+ case LEFT_RING | RIGHT_RING:
+ rr = "Both your rings glow";
+ break;
+ default:
+ rr = "Your fingertips glow";
+ break;
+ }
+ pline("%s %s!", rr, warnings[warnlevel]);
+ lastwarntime = moves;
+ lastwarnlev = warnlevel;
+ }
+
+ dmonsfree(); /* remove all dead monsters */
+}
+
+justswld(mtmp,name)
+register struct monst *mtmp;
+char *name;
+{
+
+ mtmp->mx = u.ux;
+ mtmp->my = u.uy;
+ u.ustuck = mtmp;
+ pmon(mtmp);
+ kludge("%s swallows you!",name);
+ more();
+ seeoff(1);
+ u.uswallow = 1;
+ u.uswldtim = 0;
+ swallowed();
+}
+
+youswld(mtmp,dam,die,name)
+register struct monst *mtmp;
+register dam,die;
+char *name;
+{
+ if(mtmp != u.ustuck) return;
+ kludge("%s digests you!",name);
+ u.uhp -= dam;
+ if(u.uswldtim++ >= die){ /* a3 */
+ pline("It totally digests you!");
+ u.uhp = -1;
+ }
+ if(u.uhp < 1) done_in_by(mtmp);
+ /* flags.botlx = 1; /* should we show status line ? */
+}
+
+dochugw(mtmp) register struct monst *mtmp; {
+register x = mtmp->mx;
+register y = mtmp->my;
+register d = dochug(mtmp);
+register dd;
+ if(!d) /* monster still alive */
+ if(Warning)
+ if(!mtmp->mpeaceful)
+ if(mtmp->data->mlevel > warnlevel)
+ if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))
+ if(dd < 100)
+ if(!canseemon(mtmp))
+ warnlevel = mtmp->data->mlevel;
+ return(d);
+}
+
+/* returns 1 if monster died moving, 0 otherwise */
+dochug(mtmp)
+register struct monst *mtmp;
+{
+ register struct permonst *mdat;
+ register tmp, nearby, scared;
+
+ if(mtmp->cham && !rn2(6))
+ (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
+ mdat = mtmp->data;
+ if(mdat->mlevel < 0)
+ panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);
+
+ /* regenerate monsters */
+ if((!(moves%20) || index(MREGEN, mdat->mlet)) &&
+ mtmp->mhp < mtmp->mhpmax)
+ mtmp->mhp++;
+
+ if(mtmp->mfroz) return(0); /* frozen monsters don't do anything */
+
+ if(mtmp->msleep) {
+ /* wake up, or get out of here. */
+ /* ettins are hard to surprise */
+ /* Nymphs and Leprechauns do not easily wake up */
+ if(cansee(mtmp->mx,mtmp->my) &&
+ (!Stealth || (mdat->mlet == 'e' && rn2(10))) &&
+ (!index("NL",mdat->mlet) || !rn2(50)) &&
+ (Aggravate_monster || index("d1", mdat->mlet)
+ || (!rn2(7) && !mtmp->mimic)))
+ mtmp->msleep = 0;
+ else return(0);
+ }
+
+ /* not frozen or sleeping: wipe out texts written in the dust */
+ wipe_engr_at(mtmp->mx, mtmp->my, 1);
+
+ /* confused monsters get unconfused with small probability */
+ if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
+
+ /* some monsters teleport */
+ if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){
+ rloc(mtmp);
+ return(0);
+ }
+ if(mdat->mmove < rnd(6)) return(0);
+
+ /* fleeing monsters might regain courage */
+ if(mtmp->mflee && !mtmp->mfleetim
+ && mtmp->mhp == mtmp->mhpmax && !rn2(25))
+ mtmp->mflee = 0;
+
+ nearby = (dist(mtmp->mx, mtmp->my) < 3);
+ scared = (nearby && (sengr_at("Elbereth", u.ux, u.uy) ||
+ sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy)));
+ if(scared && !mtmp->mflee) {
+ mtmp->mflee = 1;
+ mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
+ }
+
+ if(!nearby ||
+ mtmp->mflee ||
+ mtmp->mconf ||
+ (mtmp->minvis && !rn2(3)) ||
+ (index("BIuy", mdat->mlet) && !rn2(4)) ||
+ (mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||
+ (!mtmp->mcansee && !rn2(4)) ||
+ mtmp->mpeaceful
+ ) {
+ tmp = m_move(mtmp,0); /* 2: monster died moving */
+ if(tmp == 2 || (tmp && mdat->mmove <= 12))
+ return(tmp == 2);
+ }
+
+ if(!index("Ea", mdat->mlet) && nearby &&
+ !mtmp->mpeaceful && u.uhp > 0 && !scared) {
+ if(mhitu(mtmp))
+ return(1); /* monster died (e.g. 'y' or 'F') */
+ }
+ /* extra movement for fast monsters */
+ if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);
+ return(tmp == 2);
+}
+
+m_move(mtmp,after)
+register struct monst *mtmp;
+{
+ register struct monst *mtmp2;
+ register nx,ny,omx,omy,appr,nearer,cnt,i,j;
+ xchar gx,gy,nix,niy,chcnt;
+ schar chi;
+ boolean likegold, likegems, likeobjs;
+ char msym = mtmp->data->mlet;
+ schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
+ coord poss[9];
+ int info[9];
+
+ if(mtmp->mfroz || mtmp->msleep)
+ return(0);
+ if(mtmp->mtrapped) {
+ i = mintrap(mtmp);
+ if(i == 2) return(2); /* he died */
+ if(i == 1) return(0); /* still in trap, so didnt move */
+ }
+ if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))
+ return(0); /* do not leave hiding place */
+
+#ifndef NOWORM
+ if(mtmp->wormno)
+ goto not_special;
+#endif NOWORM
+
+ /* my dog gets a special treatment */
+ if(mtmp->mtame) {
+ return( dog_move(mtmp, after) );
+ }
+
+ /* likewise for shopkeeper */
+ if(mtmp->isshk) {
+ mmoved = shk_move(mtmp);
+ if(mmoved >= 0)
+ goto postmov;
+ mmoved = 0; /* follow player outside shop */
+ }
+
+ /* and for the guard */
+ if(mtmp->isgd) {
+ mmoved = gd_move();
+ goto postmov;
+ }
+
+/* teleport if that lies in our nature ('t') or when badly wounded ('1') */
+ if((msym == 't' && !rn2(5))
+ || (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5))
+ || levl[u.ux][u.uy].typ == STAIRS))) {
+ if(mtmp->mhp < 7 || (msym == 't' && rn2(2)))
+ rloc(mtmp);
+ else
+ mnexto(mtmp);
+ mmoved = 1;
+ goto postmov;
+ }
+
+ /* spit fire ('D') or use a wand ('1') when appropriate */
+ if(index("D1", msym))
+ inrange(mtmp);
+
+ if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) &&
+ mtmp->mcansee && rn2(5)) {
+ if(!Confusion)
+ pline("%s's gaze has confused you!", Monnam(mtmp));
+ else
+ pline("You are getting more and more confused.");
+ if(rn2(3)) mtmp->mcan = 1;
+ Confusion += d(3,4); /* timeout */
+ }
+not_special:
+ if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
+ appr = 1;
+ if(mtmp->mflee) appr = -1;
+ if(mtmp->mconf || Invis || !mtmp->mcansee ||
+ (index("BIy", msym) && !rn2(3)))
+ appr = 0;
+ omx = mtmp->mx;
+ omy = mtmp->my;
+ gx = u.ux;
+ gy = u.uy;
+ if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold)
+ appr = -1;
+
+ /* random criterion for 'smell' or track finding ability
+ should use mtmp->msmell or sth
+ */
+ if(msym == '@' ||
+ ('a' <= msym && msym <= 'z')) {
+ extern coord *gettrack();
+ register coord *cp;
+ schar mroom;
+ mroom = inroom(omx,omy);
+ if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
+ cp = gettrack(omx,omy);
+ if(cp){
+ gx = cp->x;
+ gy = cp->y;
+ }
+ }
+ }
+
+ /* look for gold or jewels nearby */
+ likegold = (index("LOD", msym) != NULL);
+ likegems = (index("ODu", msym) != NULL);
+ likeobjs = mtmp->mhide;
+#define SRCHRADIUS 25
+ { xchar mind = SRCHRADIUS; /* not too far away */
+ register int dd;
+ if(likegold){
+ register struct gold *gold;
+ for(gold = fgold; gold; gold = gold->ngold)
+ if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){
+ mind = dd;
+ gx = gold->gx;
+ gy = gold->gy;
+ }
+ }
+ if(likegems || likeobjs){
+ register struct obj *otmp;
+ for(otmp = fobj; otmp; otmp = otmp->nobj)
+ if(likeobjs || otmp->olet == GEM_SYM)
+ if(msym != 'u' ||
+ objects[otmp->otyp].g_val != 0)
+ if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){
+ mind = dd;
+ gx = otmp->ox;
+ gy = otmp->oy;
+ }
+ }
+ if(mind < SRCHRADIUS && appr == -1) {
+ if(dist(omx,omy) < 10) {
+ gx = u.ux;
+ gy = u.uy;
+ } else
+ appr = 1;
+ }
+ }
+ nix = omx;
+ niy = omy;
+ cnt = mfndpos(mtmp,poss,info,
+ msym == 'u' ? NOTONL :
+ (msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) :
+ index(UNDEAD, msym) ? NOGARLIC : ALLOW_TRAPS);
+ /* ALLOW_ROCK for some monsters ? */
+ chcnt = 0;
+ chi = -1;
+ for(i=0; i<cnt; i++) {
+ nx = poss[i].x;
+ ny = poss[i].y;
+ for(j=0; j<MTSZ && j<cnt-1; j++)
+ if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
+ if(rn2(4*(cnt-j))) goto nxti;
+#ifdef STUPID
+ /* some stupid compilers think that this is too complicated */
+ { int d1 = DIST(nx,ny,gx,gy);
+ int d2 = DIST(nix,niy,gx,gy);
+ nearer = (d1 < d2);
+ }
+#else
+ nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));
+#endif STUPID
+ if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
+ !mmoved ||
+ (!appr && !rn2(++chcnt))){
+ nix = nx;
+ niy = ny;
+ chi = i;
+ mmoved = 1;
+ }
+ nxti: ;
+ }
+ if(mmoved){
+ if(info[chi] & ALLOW_M){
+ mtmp2 = m_at(nix,niy);
+ if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&
+ hitmm(mtmp2,mtmp) == 2) return(2);
+ return(0);
+ }
+ if(info[chi] & ALLOW_U){
+ (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);
+ return(0);
+ }
+ mtmp->mx = nix;
+ mtmp->my = niy;
+ for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
+ mtmp->mtrack[0].x = omx;
+ mtmp->mtrack[0].y = omy;
+#ifndef NOWORM
+ if(mtmp->wormno) worm_move(mtmp);
+#endif NOWORM
+ } else {
+ if(msym == 'u' && rn2(2)){
+ rloc(mtmp);
+ return(0);
+ }
+#ifndef NOWORM
+ if(mtmp->wormno) worm_nomove(mtmp);
+#endif NOWORM
+ }
+postmov:
+ if(mmoved == 1) {
+ if(mintrap(mtmp) == 2) /* he died */
+ return(2);
+ if(likegold) mpickgold(mtmp);
+ if(likegems) mpickgems(mtmp);
+ if(mtmp->mhide) mtmp->mundetected = 1;
+ }
+ pmon(mtmp);
+ return(mmoved);
+}
+
+mpickgold(mtmp) register struct monst *mtmp; {
+register struct gold *gold;
+ while(gold = g_at(mtmp->mx, mtmp->my)){
+ mtmp->mgold += gold->amount;
+ freegold(gold);
+ if(levl[mtmp->mx][mtmp->my].scrsym == '$')
+ newsym(mtmp->mx, mtmp->my);
+ }
+}
+
+mpickgems(mtmp) register struct monst *mtmp; {
+register struct obj *otmp;
+ for(otmp = fobj; otmp; otmp = otmp->nobj)
+ if(otmp->olet == GEM_SYM)
+ if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my)
+ if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){
+ freeobj(otmp);
+ mpickobj(mtmp, otmp);
+ if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM)
+ newsym(mtmp->mx, mtmp->my); /* %% */
+ return; /* pick only one object */
+ }
+}
+
+/* return number of acceptable neighbour positions */
+mfndpos(mon,poss,info,flag)
+register struct monst *mon;
+coord poss[9];
+int info[9], flag;
+{
+ register int x,y,nx,ny,cnt = 0,ntyp;
+ register struct monst *mtmp;
+ int nowtyp;
+ boolean pool;
+
+ x = mon->mx;
+ y = mon->my;
+ nowtyp = levl[x][y].typ;
+
+ pool = (mon->data->mlet == ';');
+nexttry: /* eels prefer the water, but if there is no water nearby,
+ they will crawl over land */
+ if(mon->mconf) {
+ flag |= ALLOW_ALL;
+ flag &= ~NOTONL;
+ }
+ for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
+ if(nx != x || ny != y) if(isok(nx,ny))
+ if(!IS_ROCK(ntyp = levl[nx][ny].typ))
+ if(!(nx != x && ny != y && (nowtyp == DOOR || ntyp == DOOR)))
+ if((ntyp == POOL) == pool) {
+ info[cnt] = 0;
+ if(nx == u.ux && ny == u.uy){
+ if(!(flag & ALLOW_U)) continue;
+ info[cnt] = ALLOW_U;
+ } else if(mtmp = m_at(nx,ny)){
+ if(!(flag & ALLOW_M)) continue;
+ info[cnt] = ALLOW_M;
+ if(mtmp->mtame){
+ if(!(flag & ALLOW_TM)) continue;
+ info[cnt] |= ALLOW_TM;
+ }
+ }
+ if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
+ if(flag & NOGARLIC) continue;
+ info[cnt] |= NOGARLIC;
+ }
+ if(sobj_at(SCR_SCARE_MONSTER, nx, ny) ||
+ (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) {
+ if(!(flag & ALLOW_SSM)) continue;
+ info[cnt] |= ALLOW_SSM;
+ }
+ if(sobj_at(ENORMOUS_ROCK, nx, ny)) {
+ if(!(flag & ALLOW_ROCK)) continue;
+ info[cnt] |= ALLOW_ROCK;
+ }
+ if(!Invis && online(nx,ny)){
+ if(flag & NOTONL) continue;
+ info[cnt] |= NOTONL;
+ }
+ /* we cannot avoid traps of an unknown kind */
+ { register struct trap *ttmp = t_at(nx, ny);
+ register int tt;
+ if(ttmp) {
+ tt = 1 << ttmp->ttyp;
+ if(mon->mtrapseen & tt){
+ if(!(flag & tt)) continue;
+ info[cnt] |= tt;
+ }
+ }
+ }
+ poss[cnt].x = nx;
+ poss[cnt].y = ny;
+ cnt++;
+ }
+ if(!cnt && pool && nowtyp != POOL) {
+ pool = FALSE;
+ goto nexttry;
+ }
+ return(cnt);
+}
+
+dist(x,y) int x,y; {
+ return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy));
+}
+
+poisoned(string, pname)
+register char *string, *pname;
+{
+ register int i;
+
+ if(Blind) pline("It was poisoned.");
+ else pline("The %s was poisoned!",string);
+ if(Poison_resistance) {
+ pline("The poison doesn't seem to affect you.");
+ return;
+ }
+ i = rn2(10);
+ if(i == 0) {
+ u.uhp = -1;
+ pline("I am afraid the poison was deadly ...");
+ } else if(i <= 5) {
+ losestr(rn1(3,3));
+ } else {
+ losehp(rn1(10,6), pname);
+ }
+ if(u.uhp < 1) {
+ killer = pname;
+ done("died");
+ }
+}
+
+mondead(mtmp)
+register struct monst *mtmp;
+{
+ relobj(mtmp,1);
+ unpmon(mtmp);
+ relmon(mtmp);
+ unstuck(mtmp);
+ if(mtmp->isshk) shkdead(mtmp);
+ if(mtmp->isgd) gddead();
+#ifndef NOWORM
+ if(mtmp->wormno) wormdead(mtmp);
+#endif NOWORM
+ monfree(mtmp);
+}
+
+/* called when monster is moved to larger structure */
+replmon(mtmp,mtmp2)
+register struct monst *mtmp, *mtmp2;
+{
+ relmon(mtmp);
+ monfree(mtmp);
+ mtmp2->nmon = fmon;
+ fmon = mtmp2;
+ if(u.ustuck == mtmp) u.ustuck = mtmp2;
+ if(mtmp2->isshk) replshk(mtmp,mtmp2);
+ if(mtmp2->isgd) replgd(mtmp,mtmp2);
+}
+
+relmon(mon)
+register struct monst *mon;
+{
+ register struct monst *mtmp;
+
+ if(mon == fmon) fmon = fmon->nmon;
+ else {
+ for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ;
+ mtmp->nmon = mon->nmon;
+ }
+}
+
+/* we do not free monsters immediately, in order to have their name
+ available shortly after their demise */
+struct monst *fdmon; /* chain of dead monsters, need not to be saved */
+
+monfree(mtmp) register struct monst *mtmp; {
+ mtmp->nmon = fdmon;
+ fdmon = mtmp;
+}
+
+dmonsfree(){
+register struct monst *mtmp;
+ while(mtmp = fdmon){
+ fdmon = mtmp->nmon;
+ free((char *) mtmp);
+ }
+}
+
+unstuck(mtmp)
+register struct monst *mtmp;
+{
+ if(u.ustuck == mtmp) {
+ if(u.uswallow){
+ u.ux = mtmp->mx;
+ u.uy = mtmp->my;
+ u.uswallow = 0;
+ setsee();
+ docrt();
+ }
+ u.ustuck = 0;
+ }
+}
+
+killed(mtmp)
+register struct monst *mtmp;
+{
+#ifdef lint
+#define NEW_SCORING
+#endif lint
+ register int tmp,tmp2,nk,x,y;
+ register struct permonst *mdat;
+ extern long newuexp();
+
+ if(mtmp->cham) mtmp->data = PM_CHAMELEON;
+ mdat = mtmp->data;
+ if(Blind) pline("You destroy it!");
+ else {
+ pline("You destroy %s!",
+ mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp));
+ }
+ if(u.umconf) {
+ if(!Blind) pline("Your hands stop glowing blue.");
+ u.umconf = 0;
+ }
+
+ /* count killed monsters */
+#define MAXMONNO 100
+ nk = 1; /* in case we cannot find it in mons */
+ tmp = mdat - mons; /* index in mons array (if not 'd', '@', ...) */
+ if(tmp >= 0 && tmp < CMNUM+2) {
+ extern char fut_geno[];
+ u.nr_killed[tmp]++;
+ if((nk = u.nr_killed[tmp]) > MAXMONNO &&
+ !index(fut_geno, mdat->mlet))
+ charcat(fut_geno, mdat->mlet);
+ }
+
+ /* punish bad behaviour */
+ if(mdat->mlet == '@') Telepat = 0, u.uluck -= 2;
+ if(mtmp->mpeaceful || mtmp->mtame) u.uluck--;
+ if(mdat->mlet == 'u') u.uluck -= 5;
+ if((int)u.uluck < LUCKMIN) u.uluck = LUCKMIN;
+
+ /* give experience points */
+ tmp = 1 + mdat->mlevel * mdat->mlevel;
+ if(mdat->ac < 3) tmp += 2*(7 - mdat->ac);
+ if(index("AcsSDXaeRTVWU&In:P", mdat->mlet))
+ tmp += 2*mdat->mlevel;
+ if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel);
+ if(mdat->mlevel > 6) tmp += 50;
+ if(mdat->mlet == ';') tmp += 1000;
+
+#ifdef NEW_SCORING
+ /* ------- recent addition: make nr of points decrease
+ when this is not the first of this kind */
+ { int ul = u.ulevel;
+ int ml = mdat->mlevel;
+
+ if(ul < 14) /* points are given based on present and future level */
+ for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++)
+ if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk
+ >= 10*pow((unsigned)(ul-1)))
+ if(++ul == 14) break;
+
+ tmp2 = ml - ul -1;
+ tmp = (tmp + ((tmp2 < 0) ? 0 : 4<<tmp2))/nk;
+ if(!tmp) tmp = 1;
+ }
+ /* note: ul is not necessarily the future value of u.ulevel */
+ /* ------- end of recent valuation change ------- */
+#endif NEW_SCORING
+
+ more_experienced(tmp,0);
+ flags.botl = 1;
+ while(u.ulevel < 14 && u.uexp >= newuexp()){
+ pline("Welcome to experience level %u.", ++u.ulevel);
+ tmp = rnd(10);
+ if(tmp < 3) tmp = rnd(10);
+ u.uhpmax += tmp;
+ u.uhp += tmp;
+ flags.botl = 1;
+ }
+
+ /* dispose of monster and make cadaver */
+ x = mtmp->mx; y = mtmp->my;
+ mondead(mtmp);
+ tmp = mdat->mlet;
+ if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */
+ /* note: the dead minotaur will be on top of it! */
+ mksobj_at(WAN_DIGGING, x, y);
+ /* if(cansee(x,y)) atl(x,y,fobj->olet); */
+ stackobj(fobj);
+ } else
+#ifndef NOWORM
+ if(tmp == 'w') {
+ mksobj_at(WORM_TOOTH, x, y);
+ stackobj(fobj);
+ } else
+#endif NOWORM
+ if(!letter(tmp) || (!index("mw", tmp) && !rn2(3))) tmp = 0;
+
+ if(ACCESSIBLE(levl[x][y].typ)) /* might be mimic in wall or dead eel*/
+ if(x != u.ux || y != u.uy) /* might be here after swallowed */
+ if(index("NTVm&",mdat->mlet) || rn2(5)) {
+ register struct obj *obj2 = mkobj_at(tmp,x,y);
+ if(cansee(x,y))
+ atl(x,y,obj2->olet);
+ stackobj(obj2);
+ }
+}
+
+kludge(str,arg)
+register char *str,*arg;
+{
+ if(Blind) {
+ if(*str == '%') pline(str,"It");
+ else pline(str,"it");
+ } else pline(str,arg);
+}
+
+rescham() /* force all chameleons to become normal */
+{
+ register struct monst *mtmp;
+
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->cham) {
+ mtmp->cham = 0;
+ (void) newcham(mtmp, PM_CHAMELEON);
+ }
+}
+
+newcham(mtmp,mdat) /* make a chameleon look like a new monster */
+ /* returns 1 if the monster actually changed */
+register struct monst *mtmp;
+register struct permonst *mdat;
+{
+ register mhp, hpn, hpd;
+
+ if(mdat == mtmp->data) return(0); /* still the same monster */
+#ifndef NOWORM
+ if(mtmp->wormno) wormdead(mtmp); /* throw tail away */
+#endif NOWORM
+ if (u.ustuck == mtmp) {
+ if (u.uswallow) {
+ u.uswallow = 0;
+ u.uswldtim = 0;
+ mnexto (mtmp);
+ docrt ();
+ prme ();
+ }
+ u.ustuck = 0;
+ }
+ hpn = mtmp->mhp;
+ hpd = (mtmp->data->mlevel)*8;
+ if(!hpd) hpd = 4;
+ mtmp->data = mdat;
+ mhp = (mdat->mlevel)*8;
+ /* new hp: same fraction of max as before */
+ mtmp->mhp = 2 + (hpn*mhp)/hpd;
+ hpn = mtmp->mhpmax;
+ mtmp->mhpmax = 2 + (hpn*mhp)/hpd;
+ mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0;
+#ifndef NOWORM
+ if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp);
+ /* perhaps we should clear mtmp->mtame here? */
+#endif NOWORM
+ unpmon(mtmp); /* necessary for 'I' and to force pmon */
+ pmon(mtmp);
+ return(1);
+}
+
+mnexto(mtmp) /* Make monster mtmp next to you (if possible) */
+struct monst *mtmp;
+{
+ extern coord enexto();
+ coord mm;
+ mm = enexto(u.ux, u.uy);
+ mtmp->mx = mm.x;
+ mtmp->my = mm.y;
+ pmon(mtmp);
+}
+
+ishuman(mtmp) register struct monst *mtmp; {
+ return(mtmp->data->mlet == '@');
+}
+
+setmangry(mtmp) register struct monst *mtmp; {
+ if(!mtmp->mpeaceful) return;
+ if(mtmp->mtame) return;
+ mtmp->mpeaceful = 0;
+ if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp));
+}
+
+/* not one hundred procent correct: now a snake may hide under an
+ invisible object */
+canseemon(mtmp)
+register struct monst *mtmp;
+{
+ return((!mtmp->minvis || See_invisible)
+ && (!mtmp->mhide || !o_at(mtmp->mx,mtmp->my))
+ && cansee(mtmp->mx, mtmp->my));
+}
diff --git a/hack/hack.monst.c b/hack/hack.monst.c
new file mode 100644
index 00000000..b682b59d
--- /dev/null
+++ b/hack/hack.monst.c
@@ -0,0 +1,79 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.monst.c - version 1.0.2 */
+
+#include "hack.h"
+#include "def.eshk.h"
+extern char plname[PL_NSIZ];
+
+struct permonst mons[CMNUM+2] = {
+ { "bat", 'B',1,22,8,1,4,0 },
+ { "gnome", 'G',1,6,5,1,6,0 },
+ { "hobgoblin", 'H',1,9,5,1,8,0 },
+ { "jackal", 'J',0,12,7,1,2,0 },
+ { "kobold", 'K',1,6,7,1,4,0 },
+ { "leprechaun", 'L',5,15,8,1,2,0 },
+ { "giant rat", 'r',0,12,7,1,3,0 },
+ { "acid blob", 'a',2,3,8,0,0,0 },
+ { "floating eye", 'E',2,1,9,0,0,0 },
+ { "homunculus", 'h',2,6,6,1,3,0 },
+ { "imp", 'i',2,6,2,1,4,0 },
+ { "orc", 'O',2,9,6,1,8,0 },
+ { "yellow light", 'y',3,15,0,0,0,0 },
+ { "zombie", 'Z',2,6,8,1,8,0 },
+ { "giant ant", 'A',3,18,3,1,6,0 },
+ { "fog cloud", 'f',3,1,0,1,6,0 },
+ { "nymph", 'N',6,12,9,1,2,0 },
+ { "piercer", 'p',3,1,3,2,6,0 },
+ { "quasit", 'Q',3,15,3,1,4,0 },
+ { "quivering blob", 'q',3,1,8,1,8,0 },
+ { "violet fungi", 'v',3,1,7,1,4,0 },
+ { "giant beetle", 'b',4,6,4,3,4,0 },
+ { "centaur", 'C',4,18,4,1,6,0 },
+ { "cockatrice", 'c',4,6,6,1,3,0 },
+ { "gelatinous cube", 'g',4,6,8,2,4,0 },
+ { "jaguar", 'j',4,15,6,1,8,0 },
+ { "killer bee", 'k',4,14,4,2,4,0 },
+ { "snake", 'S',4,15,3,1,6,0 },
+ { "freezing sphere", 'F',2,13,4,0,0,0 },
+ { "owlbear", 'o',5,12,5,2,6,0 },
+ { "rust monster", 'R',10,18,3,0,0,0 },
+ { "scorpion", 's',5,15,3,1,4,0 },
+ { "tengu", 't',5,13,5,1,7,0 },
+ { "wraith", 'W',5,12,5,1,6,0 },
+#ifdef NOWORM
+ { "wumpus", 'w',8,3,2,3,6,0 },
+#else
+ { "long worm", 'w',8,3,5,1,4,0 },
+#endif NOWORM
+ { "large dog", 'd',6,15,4,2,4,0 },
+ { "leocrotta", 'l',6,18,4,3,6,0 },
+ { "mimic", 'M',7,3,7,3,4,0 },
+ { "troll", 'T',7,12,4,2,7,0 },
+ { "unicorn", 'u',8,24,5,1,10,0 },
+ { "yeti", 'Y',5,15,6,1,6,0 },
+ { "stalker", 'I',8,12,3,4,4,0 },
+ { "umber hulk", 'U',9,6,2,2,10,0 },
+ { "vampire", 'V',8,12,1,1,6,0 },
+ { "xorn", 'X',8,9,-2,4,6,0 },
+ { "xan", 'x',7,18,-2,2,4,0 },
+ { "zruty", 'z',9,8,3,3,6,0 },
+ { "chameleon", ':',6,5,6,4,2,0 },
+ { "dragon", 'D',10,9,-1,3,8,0 },
+ { "ettin", 'e',10,12,3,2,8,0 },
+ { "lurker above", '\'',10,3,3,0,0,0 },
+ { "nurse", 'n',11,6,0,1,3,0 },
+ { "trapper", ',',12,3,3,0,0,0 },
+ { "purple worm", 'P',15,9,6,2,8,0 },
+ { "demon", '&',10,12,-4,1,4,0 },
+ { "minotaur", 'm',15,15,6,4,10,0 },
+ { "shopkeeper", '@', 12, 18, 0, 4, 8, sizeof(struct eshk) }
+};
+
+struct permonst pm_ghost = { "ghost", ' ', 10, 3, -5, 1, 1, sizeof(plname) };
+struct permonst pm_wizard = {
+ "wizard of Yendor", '1', 15, 12, -2, 1, 12, 0
+};
+#ifdef MAIL
+struct permonst pm_mail_daemon = { "mail daemon", '2', 100, 1, 10, 0, 0, 0 };
+#endif MAIL
+struct permonst pm_eel = { "giant eel", ';', 15, 6, -3, 3, 6, 0 };
diff --git a/hack/hack.o_init.c b/hack/hack.o_init.c
new file mode 100644
index 00000000..37b33aef
--- /dev/null
+++ b/hack/hack.o_init.c
@@ -0,0 +1,160 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.o_init.c - version 1.0.3 */
+
+#include "config.h" /* for typedefs */
+#include "def.objects.h"
+#include "hack.onames.h" /* for LAST_GEM */
+extern char *index();
+
+int
+letindex(let) register char let; {
+register int i = 0;
+register char ch;
+ while((ch = obj_symbols[i++]) != 0)
+ if(ch == let) return(i);
+ return(0);
+}
+
+init_objects(){
+register int i, j, first, last, sum, end;
+register char let, *tmp;
+ /* init base; if probs given check that they add up to 100,
+ otherwise compute probs; shuffle descriptions */
+ end = SIZE(objects);
+ first = 0;
+ while( first < end ) {
+ let = objects[first].oc_olet;
+ last = first+1;
+ while(last < end && objects[last].oc_olet == let
+ && objects[last].oc_name != NULL)
+ last++;
+ i = letindex(let);
+ if((!i && let != ILLOBJ_SYM) || bases[i] != 0)
+ error("initialization error");
+ bases[i] = first;
+
+ if(let == GEM_SYM)
+ setgemprobs();
+ check:
+ sum = 0;
+ for(j = first; j < last; j++) sum += objects[j].oc_prob;
+ if(sum == 0) {
+ for(j = first; j < last; j++)
+ objects[j].oc_prob = (100+j-first)/(last-first);
+ goto check;
+ }
+ if(sum != 100)
+ error("init-prob error for %c", let);
+
+ if(objects[first].oc_descr != NULL && let != TOOL_SYM){
+ /* shuffle, also some additional descriptions */
+ while(last < end && objects[last].oc_olet == let)
+ last++;
+ j = last;
+ while(--j > first) {
+ i = first + rn2(j+1-first);
+ tmp = objects[j].oc_descr;
+ objects[j].oc_descr = objects[i].oc_descr;
+ objects[i].oc_descr = tmp;
+ }
+ }
+ first = last;
+ }
+}
+
+probtype(let) register char let; {
+register int i = bases[letindex(let)];
+register int prob = rn2(100);
+ while((prob -= objects[i].oc_prob) >= 0) i++;
+ if(objects[i].oc_olet != let || !objects[i].oc_name)
+ panic("probtype(%c) error, i=%d", let, i);
+ return(i);
+}
+
+setgemprobs()
+{
+ register int j,first;
+ extern xchar dlevel;
+
+ first = bases[letindex(GEM_SYM)];
+
+ for(j = 0; j < 9-dlevel/3; j++)
+ objects[first+j].oc_prob = 0;
+ first += j;
+ if(first >= LAST_GEM || first >= SIZE(objects) ||
+ objects[first].oc_olet != GEM_SYM ||
+ objects[first].oc_name == NULL)
+ printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
+ first, j, LAST_GEM);
+ for(j = first; j < LAST_GEM; j++)
+ objects[j].oc_prob = (20+j-first)/(LAST_GEM-first);
+}
+
+oinit() /* level dependent initialization */
+{
+ setgemprobs();
+}
+
+extern long *alloc();
+
+savenames(fd) register fd; {
+register int i;
+unsigned len;
+ bwrite(fd, (char *) bases, sizeof bases);
+ bwrite(fd, (char *) objects, sizeof objects);
+ /* as long as we use only one version of Hack/Quest we
+ need not save oc_name and oc_descr, but we must save
+ oc_uname for all objects */
+ for(i=0; i < SIZE(objects); i++) {
+ if(objects[i].oc_uname) {
+ len = strlen(objects[i].oc_uname)+1;
+ bwrite(fd, (char *) &len, sizeof len);
+ bwrite(fd, objects[i].oc_uname, len);
+ }
+ }
+}
+
+restnames(fd) register fd; {
+register int i;
+unsigned len;
+ mread(fd, (char *) bases, sizeof bases);
+ mread(fd, (char *) objects, sizeof objects);
+ for(i=0; i < SIZE(objects); i++) if(objects[i].oc_uname) {
+ mread(fd, (char *) &len, sizeof len);
+ objects[i].oc_uname = (char *) alloc(len);
+ mread(fd, objects[i].oc_uname, len);
+ }
+}
+
+dodiscovered() /* free after Robert Viduya */
+{
+ extern char *typename();
+ register int i, end;
+ int ct = 0;
+
+ cornline(0, "Discoveries");
+
+ end = SIZE(objects);
+ for (i = 0; i < end; i++) {
+ if (interesting_to_discover (i)) {
+ ct++;
+ cornline(1, typename(i));
+ }
+ }
+ if (ct == 0) {
+ pline ("You haven't discovered anything yet...");
+ cornline(3, (char *) 0);
+ } else
+ cornline(2, (char *) 0);
+
+ return(0);
+}
+
+interesting_to_discover(i)
+register int i;
+{
+ return(
+ objects[i].oc_uname != NULL ||
+ (objects[i].oc_name_known && objects[i].oc_descr != NULL)
+ );
+}
diff --git a/hack/hack.objnam.c b/hack/hack.objnam.c
new file mode 100644
index 00000000..a1c966cd
--- /dev/null
+++ b/hack/hack.objnam.c
@@ -0,0 +1,547 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.objnam.c - version 1.0.2 */
+
+#include "hack.h"
+#define Sprintf (void) sprintf
+#define Strcat (void) strcat
+#define Strcpy (void) strcpy
+#define PREFIX 15
+extern char *eos();
+extern int bases[];
+
+char *
+strprepend(s,pref) register char *s, *pref; {
+register int i = strlen(pref);
+ if(i > PREFIX) {
+ pline("WARNING: prefix too short.");
+ return(s);
+ }
+ s -= i;
+ (void) strncpy(s, pref, i); /* do not copy trailing 0 */
+ return(s);
+}
+
+char *
+sitoa(a) int a; {
+static char buf[13];
+ Sprintf(buf, (a < 0) ? "%d" : "+%d", a);
+ return(buf);
+}
+
+char *
+typename(otyp)
+register int otyp;
+{
+static char buf[BUFSZ];
+register struct objclass *ocl = &objects[otyp];
+register char *an = ocl->oc_name;
+register char *dn = ocl->oc_descr;
+register char *un = ocl->oc_uname;
+register int nn = ocl->oc_name_known;
+ switch(ocl->oc_olet) {
+ case POTION_SYM:
+ Strcpy(buf, "potion");
+ break;
+ case SCROLL_SYM:
+ Strcpy(buf, "scroll");
+ break;
+ case WAND_SYM:
+ Strcpy(buf, "wand");
+ break;
+ case RING_SYM:
+ Strcpy(buf, "ring");
+ break;
+ default:
+ if(nn) {
+ Strcpy(buf, an);
+ if(otyp >= TURQUOISE && otyp <= JADE)
+ Strcat(buf, " stone");
+ if(un)
+ Sprintf(eos(buf), " called %s", un);
+ if(dn)
+ Sprintf(eos(buf), " (%s)", dn);
+ } else {
+ Strcpy(buf, dn ? dn : an);
+ if(ocl->oc_olet == GEM_SYM)
+ Strcat(buf, " gem");
+ if(un)
+ Sprintf(eos(buf), " called %s", un);
+ }
+ return(buf);
+ }
+ /* here for ring/scroll/potion/wand */
+ if(nn)
+ Sprintf(eos(buf), " of %s", an);
+ if(un)
+ Sprintf(eos(buf), " called %s", un);
+ if(dn)
+ Sprintf(eos(buf), " (%s)", dn);
+ return(buf);
+}
+
+char *
+xname(obj)
+register struct obj *obj;
+{
+static char bufr[BUFSZ];
+register char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */
+register int nn = objects[obj->otyp].oc_name_known;
+register char *an = objects[obj->otyp].oc_name;
+register char *dn = objects[obj->otyp].oc_descr;
+register char *un = objects[obj->otyp].oc_uname;
+register int pl = (obj->quan != 1);
+ if(!obj->dknown && !Blind) obj->dknown = 1; /* %% doesnt belong here */
+ switch(obj->olet) {
+ case AMULET_SYM:
+ Strcpy(buf, (obj->spe < 0 && obj->known)
+ ? "cheap plastic imitation of the " : "");
+ Strcat(buf,"Amulet of Yendor");
+ break;
+ case TOOL_SYM:
+ if(!nn) {
+ Strcpy(buf, dn);
+ break;
+ }
+ Strcpy(buf,an);
+ break;
+ case FOOD_SYM:
+ if(obj->otyp == DEAD_HOMUNCULUS && pl) {
+ pl = 0;
+ Strcpy(buf, "dead homunculi");
+ break;
+ }
+ /* fungis ? */
+ /* fall into next case */
+ case WEAPON_SYM:
+ if(obj->otyp == WORM_TOOTH && pl) {
+ pl = 0;
+ Strcpy(buf, "worm teeth");
+ break;
+ }
+ if(obj->otyp == CRYSKNIFE && pl) {
+ pl = 0;
+ Strcpy(buf, "crysknives");
+ break;
+ }
+ /* fall into next case */
+ case ARMOR_SYM:
+ case CHAIN_SYM:
+ case ROCK_SYM:
+ Strcpy(buf,an);
+ break;
+ case BALL_SYM:
+ Sprintf(buf, "%sheavy iron ball",
+ (obj->owt > objects[obj->otyp].oc_weight) ? "very " : "");
+ break;
+ case POTION_SYM:
+ if(nn || un || !obj->dknown) {
+ Strcpy(buf, "potion");
+ if(pl) {
+ pl = 0;
+ Strcat(buf, "s");
+ }
+ if(!obj->dknown) break;
+ if(un) {
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else {
+ Strcat(buf, " of ");
+ Strcat(buf, an);
+ }
+ } else {
+ Strcpy(buf, dn);
+ Strcat(buf, " potion");
+ }
+ break;
+ case SCROLL_SYM:
+ Strcpy(buf, "scroll");
+ if(pl) {
+ pl = 0;
+ Strcat(buf, "s");
+ }
+ if(!obj->dknown) break;
+ if(nn) {
+ Strcat(buf, " of ");
+ Strcat(buf, an);
+ } else if(un) {
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else {
+ Strcat(buf, " labeled ");
+ Strcat(buf, dn);
+ }
+ break;
+ case WAND_SYM:
+ if(!obj->dknown)
+ Sprintf(buf, "wand");
+ else if(nn)
+ Sprintf(buf, "wand of %s", an);
+ else if(un)
+ Sprintf(buf, "wand called %s", un);
+ else
+ Sprintf(buf, "%s wand", dn);
+ break;
+ case RING_SYM:
+ if(!obj->dknown)
+ Sprintf(buf, "ring");
+ else if(nn)
+ Sprintf(buf, "ring of %s", an);
+ else if(un)
+ Sprintf(buf, "ring called %s", un);
+ else
+ Sprintf(buf, "%s ring", dn);
+ break;
+ case GEM_SYM:
+ if(!obj->dknown) {
+ Strcpy(buf, "gem");
+ break;
+ }
+ if(!nn) {
+ Sprintf(buf, "%s gem", dn);
+ break;
+ }
+ Strcpy(buf, an);
+ if(obj->otyp >= TURQUOISE && obj->otyp <= JADE)
+ Strcat(buf, " stone");
+ break;
+ default:
+ Sprintf(buf,"glorkum %c (0%o) %u %d",
+ obj->olet,obj->olet,obj->otyp,obj->spe);
+ }
+ if(pl) {
+ register char *p;
+
+ for(p = buf; *p; p++) {
+ if(!strncmp(" of ", p, 4)) {
+ /* pieces of, cloves of, lumps of */
+ register int c1, c2 = 's';
+
+ do {
+ c1 = c2; c2 = *p; *p++ = c1;
+ } while(c1);
+ goto nopl;
+ }
+ }
+ p = eos(buf)-1;
+ if(*p == 's' || *p == 'z' || *p == 'x' ||
+ (*p == 'h' && p[-1] == 's'))
+ Strcat(buf, "es"); /* boxes */
+ else if(*p == 'y' && !index(vowels, p[-1]))
+ Strcpy(p, "ies"); /* rubies, zruties */
+ else
+ Strcat(buf, "s");
+ }
+nopl:
+ if(obj->onamelth) {
+ Strcat(buf, " named ");
+ Strcat(buf, ONAME(obj));
+ }
+ return(buf);
+}
+
+char *
+doname(obj)
+register struct obj *obj;
+{
+char prefix[PREFIX];
+register char *bp = xname(obj);
+ if(obj->quan != 1)
+ Sprintf(prefix, "%u ", obj->quan);
+ else
+ Strcpy(prefix, "a ");
+ switch(obj->olet) {
+ case AMULET_SYM:
+ if(strncmp(bp, "cheap ", 6))
+ Strcpy(prefix, "the ");
+ break;
+ case ARMOR_SYM:
+ if(obj->owornmask & W_ARMOR)
+ Strcat(bp, " (being worn)");
+ /* fall into next case */
+ case WEAPON_SYM:
+ if(obj->known) {
+ Strcat(prefix, sitoa(obj->spe));
+ Strcat(prefix, " ");
+ }
+ break;
+ case WAND_SYM:
+ if(obj->known)
+ Sprintf(eos(bp), " (%d)", obj->spe);
+ break;
+ case RING_SYM:
+ if(obj->owornmask & W_RINGR) Strcat(bp, " (on right hand)");
+ if(obj->owornmask & W_RINGL) Strcat(bp, " (on left hand)");
+ if(obj->known && (objects[obj->otyp].bits & SPEC)) {
+ Strcat(prefix, sitoa(obj->spe));
+ Strcat(prefix, " ");
+ }
+ break;
+ }
+ if(obj->owornmask & W_WEP)
+ Strcat(bp, " (weapon in hand)");
+ if(obj->unpaid)
+ Strcat(bp, " (unpaid)");
+ if(!strcmp(prefix, "a ") && index(vowels, *bp))
+ Strcpy(prefix, "an ");
+ bp = strprepend(bp, prefix);
+ return(bp);
+}
+
+/* used only in hack.fight.c (thitu) */
+setan(str,buf)
+register char *str,*buf;
+{
+ if(index(vowels,*str))
+ Sprintf(buf, "an %s", str);
+ else
+ Sprintf(buf, "a %s", str);
+}
+
+char *
+aobjnam(otmp,verb) register struct obj *otmp; register char *verb; {
+register char *bp = xname(otmp);
+char prefix[PREFIX];
+ if(otmp->quan != 1) {
+ Sprintf(prefix, "%u ", otmp->quan);
+ bp = strprepend(bp, prefix);
+ }
+
+ if(verb) {
+ /* verb is given in plural (i.e., without trailing s) */
+ Strcat(bp, " ");
+ if(otmp->quan != 1)
+ Strcat(bp, verb);
+ else if(!strcmp(verb, "are"))
+ Strcat(bp, "is");
+ else {
+ Strcat(bp, verb);
+ Strcat(bp, "s");
+ }
+ }
+ return(bp);
+}
+
+char *
+Doname(obj)
+register struct obj *obj;
+{
+ register char *s = doname(obj);
+
+ if('a' <= *s && *s <= 'z') *s -= ('a' - 'A');
+ return(s);
+}
+
+char *wrp[] = { "wand", "ring", "potion", "scroll", "gem" };
+char wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM };
+
+struct obj *
+readobjnam(bp) register char *bp; {
+register char *p;
+register int i;
+int cnt, spe, spesgn, typ, heavy;
+char let;
+char *un, *dn, *an;
+/* int the = 0; char *oname = 0; */
+ cnt = spe = spesgn = typ = heavy = 0;
+ let = 0;
+ an = dn = un = 0;
+ for(p = bp; *p; p++)
+ if('A' <= *p && *p <= 'Z') *p += 'a'-'A';
+ if(!strncmp(bp, "the ", 4)){
+/* the = 1; */
+ bp += 4;
+ } else if(!strncmp(bp, "an ", 3)){
+ cnt = 1;
+ bp += 3;
+ } else if(!strncmp(bp, "a ", 2)){
+ cnt = 1;
+ bp += 2;
+ }
+ if(!cnt && digit(*bp)){
+ cnt = atoi(bp);
+ while(digit(*bp)) bp++;
+ while(*bp == ' ') bp++;
+ }
+ if(!cnt) cnt = 1; /* %% what with "gems" etc. ? */
+
+ if(*bp == '+' || *bp == '-'){
+ spesgn = (*bp++ == '+') ? 1 : -1;
+ spe = atoi(bp);
+ while(digit(*bp)) bp++;
+ while(*bp == ' ') bp++;
+ } else {
+ p = rindex(bp, '(');
+ if(p) {
+ if(p > bp && p[-1] == ' ') p[-1] = 0;
+ else *p = 0;
+ p++;
+ spe = atoi(p);
+ while(digit(*p)) p++;
+ if(strcmp(p, ")")) spe = 0;
+ else spesgn = 1;
+ }
+ }
+ /* now we have the actual name, as delivered by xname, say
+ green potions called whisky
+ scrolls labeled "QWERTY"
+ egg
+ dead zruties
+ fortune cookies
+ very heavy iron ball named hoei
+ wand of wishing
+ elven cloak
+ */
+ for(p = bp; *p; p++) if(!strncmp(p, " named ", 7)) {
+ *p = 0;
+/* oname = p+7; */
+ }
+ for(p = bp; *p; p++) if(!strncmp(p, " called ", 8)) {
+ *p = 0;
+ un = p+8;
+ }
+ for(p = bp; *p; p++) if(!strncmp(p, " labeled ", 9)) {
+ *p = 0;
+ dn = p+9;
+ }
+
+ /* first change to singular if necessary */
+ if(cnt != 1) {
+ /* find "cloves of garlic", "worthless pieces of blue glass" */
+ for(p = bp; *p; p++) if(!strncmp(p, "s of ", 5)){
+ while(*p = p[1]) p++;
+ goto sing;
+ }
+ /* remove -s or -es (boxes) or -ies (rubies, zruties) */
+ p = eos(bp);
+ if(p[-1] == 's') {
+ if(p[-2] == 'e') {
+ if(p[-3] == 'i') {
+ if(!strcmp(p-7, "cookies"))
+ goto mins;
+ Strcpy(p-3, "y");
+ goto sing;
+ }
+
+ /* note: cloves / knives from clove / knife */
+ if(!strcmp(p-6, "knives")) {
+ Strcpy(p-3, "fe");
+ goto sing;
+ }
+
+ /* note: nurses, axes but boxes */
+ if(!strcmp(p-5, "boxes")) {
+ p[-2] = 0;
+ goto sing;
+ }
+ }
+ mins:
+ p[-1] = 0;
+ } else {
+ if(!strcmp(p-9, "homunculi")) {
+ Strcpy(p-1, "us"); /* !! makes string longer */
+ goto sing;
+ }
+ if(!strcmp(p-5, "teeth")) {
+ Strcpy(p-5, "tooth");
+ goto sing;
+ }
+ /* here we cannot find the plural suffix */
+ }
+ }
+sing:
+ if(!strcmp(bp, "amulet of yendor")) {
+ typ = AMULET_OF_YENDOR;
+ goto typfnd;
+ }
+ p = eos(bp);
+ if(!strcmp(p-5, " mail")){ /* Note: ring mail is not a ring ! */
+ let = ARMOR_SYM;
+ an = bp;
+ goto srch;
+ }
+ for(i = 0; i < sizeof(wrpsym); i++) {
+ register int j = strlen(wrp[i]);
+ if(!strncmp(bp, wrp[i], j)){
+ let = wrpsym[i];
+ bp += j;
+ if(!strncmp(bp, " of ", 4)) an = bp+4;
+ /* else if(*bp) ?? */
+ goto srch;
+ }
+ if(!strcmp(p-j, wrp[i])){
+ let = wrpsym[i];
+ p -= j;
+ *p = 0;
+ if(p[-1] == ' ') p[-1] = 0;
+ dn = bp;
+ goto srch;
+ }
+ }
+ if(!strcmp(p-6, " stone")){
+ p[-6] = 0;
+ let = GEM_SYM;
+ an = bp;
+ goto srch;
+ }
+ if(!strcmp(bp, "very heavy iron ball")){
+ heavy = 1;
+ typ = HEAVY_IRON_BALL;
+ goto typfnd;
+ }
+ an = bp;
+srch:
+ if(!an && !dn && !un)
+ goto any;
+ i = 1;
+ if(let) i = bases[letindex(let)];
+ while(i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)){
+ register char *zn = objects[i].oc_name;
+
+ if(!zn) goto nxti;
+ if(an && strcmp(an, zn))
+ goto nxti;
+ if(dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn)))
+ goto nxti;
+ if(un && (!(zn = objects[i].oc_uname) || strcmp(un, zn)))
+ goto nxti;
+ typ = i;
+ goto typfnd;
+ nxti:
+ i++;
+ }
+any:
+ if(!let) let = wrpsym[rn2(sizeof(wrpsym))];
+ typ = probtype(let);
+typfnd:
+ { register struct obj *otmp;
+ extern struct obj *mksobj();
+ let = objects[typ].oc_olet;
+ otmp = mksobj(typ);
+ if(heavy)
+ otmp->owt += 15;
+ if(cnt > 0 && index("%?!*)", let) &&
+ (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20)))
+ otmp->quan = cnt;
+
+ if(spe > 3 && spe > otmp->spe)
+ spe = 0;
+ else if(let == WAND_SYM)
+ spe = otmp->spe;
+ if(spe == 3 && u.uluck < 0)
+ spesgn = -1;
+ if(let != WAND_SYM && spesgn == -1)
+ spe = -spe;
+ if(let == BALL_SYM)
+ spe = 0;
+ else if(let == AMULET_SYM)
+ spe = -1;
+ else if(typ == WAN_WISHING && rn2(10))
+ spe = (rn2(10) ? -1 : 0);
+ otmp->spe = spe;
+
+ if(spesgn == -1)
+ otmp->cursed = 1;
+
+ return(otmp);
+ }
+}
diff --git a/hack/hack.onames.h b/hack/hack.onames.h
new file mode 100644
index 00000000..c0fe81ea
--- /dev/null
+++ b/hack/hack.onames.h
@@ -0,0 +1,227 @@
+#define STRANGE_OBJECT 0
+#define AMULET_OF_YENDOR 1
+#define FOOD_RATION 2
+#define TRIPE_RATION 3
+#define PANCAKE 4
+#define DEAD_LIZARD 5
+#define FORTUNE_COOKIE 6
+#define CARROT 7
+#define TIN 8
+#define ORANGE 9
+#define APPLE 10
+#define PEAR 11
+#define MELON 12
+#define BANANA 13
+#define CANDY_BAR 14
+#define EGG 15
+#define CLOVE_OF_GARLIC 16
+#define LUMP_OF_ROYAL_JELLY 17
+#define DEAD_HUMAN 18
+#define DEAD_GIANT_ANT 19
+#define DEAD_GIANT_BAT 20
+#define DEAD_CENTAUR 21
+#define DEAD_DRAGON 22
+#define DEAD_FLOATING_EYE 23
+#define DEAD_FREEZING_SPHERE 24
+#define DEAD_GNOME 25
+#define DEAD_HOBGOBLIN 26
+#define DEAD_STALKER 27
+#define DEAD_JACKAL 28
+#define DEAD_KOBOLD 29
+#define DEAD_LEPRECHAUN 30
+#define DEAD_MIMIC 31
+#define DEAD_NYMPH 32
+#define DEAD_ORC 33
+#define DEAD_PURPLE_WORM 34
+#define DEAD_QUASIT 35
+#define DEAD_RUST_MONSTER 36
+#define DEAD_SNAKE 37
+#define DEAD_TROLL 38
+#define DEAD_UMBER_HULK 39
+#define DEAD_VAMPIRE 40
+#define DEAD_WRAITH 41
+#define DEAD_XORN 42
+#define DEAD_YETI 43
+#define DEAD_ZOMBIE 44
+#define DEAD_ACID_BLOB 45
+#define DEAD_GIANT_BEETLE 46
+#define DEAD_COCKATRICE 47
+#define DEAD_DOG 48
+#define DEAD_ETTIN 49
+#define DEAD_FOG_CLOUD 50
+#define DEAD_GELATINOUS_CUBE 51
+#define DEAD_HOMUNCULUS 52
+#define DEAD_IMP 53
+#define DEAD_JAGUAR 54
+#define DEAD_KILLER_BEE 55
+#define DEAD_LEOCROTTA 56
+#define DEAD_MINOTAUR 57
+#define DEAD_NURSE 58
+#define DEAD_OWLBEAR 59
+#define DEAD_PIERCER 60
+#define DEAD_QUIVERING_BLOB 61
+#define DEAD_GIANT_RAT 62
+#define DEAD_GIANT_SCORPION 63
+#define DEAD_TENGU 64
+#define DEAD_UNICORN 65
+#define DEAD_VIOLET_FUNGI 66
+#define DEAD_LONG_WORM 67
+#define DEAD_XAN 68
+#define DEAD_YELLOW_LIGHT 69
+#define DEAD_ZRUTY 70
+#define ARROW 71
+#define SLING_BULLET 72
+#define CROSSBOW_BOLT 73
+#define DART 74
+#define ROCK 75
+#define BOOMERANG 76
+#define MACE 77
+#define AXE 78
+#define FLAIL 79
+#define LONG_SWORD 80
+#define TWO_HANDED_SWORD 81
+#define DAGGER 82
+#define WORM_TOOTH 83
+#define CRYSKNIFE 84
+#define SPEAR 85
+#define BOW 86
+#define SLING 87
+#define CROSSBOW 88
+#define WHISTLE 89
+#define MAGIC_WHISTLE 90
+#define EXPENSIVE_CAMERA 91
+#define ICE_BOX 92
+#define PICK_AXE 93
+#define CAN_OPENER 94
+#define HEAVY_IRON_BALL 95
+#define IRON_CHAIN 96
+#define ENORMOUS_ROCK 97
+#define HELMET 98
+#define PLATE_MAIL 99
+#define SPLINT_MAIL 100
+#define BANDED_MAIL 101
+#define CHAIN_MAIL 102
+#define SCALE_MAIL 103
+#define RING_MAIL 104
+#define STUDDED_LEATHER_ARMOR 105
+#define LEATHER_ARMOR 106
+#define ELVEN_CLOAK 107
+#define SHIELD 108
+#define PAIR_OF_GLOVES 109
+#define POT_RESTORE_STRENGTH 110
+#define POT_BOOZE 111
+#define POT_INVISIBILITY 112
+#define POT_FRUIT_JUICE 113
+#define POT_HEALING 114
+#define POT_PARALYSIS 115
+#define POT_MONSTER_DETECTION 116
+#define POT_OBJECT_DETECTION 117
+#define POT_SICKNESS 118
+#define POT_CONFUSION 119
+#define POT_GAIN_STRENGTH 120
+#define POT_SPEED 121
+#define POT_BLINDNESS 122
+#define POT_GAIN_LEVEL 123
+#define POT_EXTRA_HEALING 124
+#define POT_LEVITATION 125
+#define SCR_MAIL 130
+#define SCR_ENCHANT_ARMOR 131
+#define SCR_DESTROY_ARMOR 132
+#define SCR_CONFUSE_MONSTER 133
+#define SCR_SCARE_MONSTER 134
+#define SCR_BLANK_PAPER 135
+#define SCR_REMOVE_CURSE 136
+#define SCR_ENCHANT_WEAPON 137
+#define SCR_DAMAGE_WEAPON 138
+#define SCR_CREATE_MONSTER 139
+#define SCR_TAMING 140
+#define SCR_GENOCIDE 141
+#define SCR_LIGHT 142
+#define SCR_TELEPORTATION 143
+#define SCR_GOLD_DETECTION 144
+#define SCR_FOOD_DETECTION 145
+#define SCR_IDENTIFY 146
+#define SCR_MAGIC_MAPPING 147
+#define SCR_AMNESIA 148
+#define SCR_FIRE 149
+#define SCR_PUNISHMENT 150
+#define WAN_LIGHT 155
+#define WAN_SECRET_DOOR_DETECTION 156
+#define WAN_CREATE_MONSTER 157
+#define WAN_WISHING 158
+#define WAN_STRIKING 159
+#define WAN_SLOW_MONSTER 160
+#define WAN_SPEED_MONSTER 161
+#define WAN_UNDEAD_TURNING 162
+#define WAN_POLYMORPH 163
+#define WAN_CANCELLATION 164
+#define WAN_TELEPORTATION 165
+#define WAN_MAKE_INVISIBLE 166
+#define WAN_DIGGING 167
+#define WAN_MAGIC_MISSILE 168
+#define WAN_FIRE 169
+#define WAN_SLEEP 170
+#define WAN_COLD 171
+#define WAN_DEATH 172
+#define Adornment u.uprops[0].p_flgs
+#define RIN_ADORNMENT 176
+#define Teleportation u.uprops[1].p_flgs
+#define RIN_TELEPORTATION 177
+#define Regeneration u.uprops[2].p_flgs
+#define RIN_REGENERATION 178
+#define Searching u.uprops[3].p_flgs
+#define RIN_SEARCHING 179
+#define See_invisible u.uprops[4].p_flgs
+#define RIN_SEE_INVISIBLE 180
+#define Stealth u.uprops[5].p_flgs
+#define RIN_STEALTH 181
+#define Levitation u.uprops[6].p_flgs
+#define RIN_LEVITATION 182
+#define Poison_resistance u.uprops[7].p_flgs
+#define RIN_POISON_RESISTANCE 183
+#define Aggravate_monster u.uprops[8].p_flgs
+#define RIN_AGGRAVATE_MONSTER 184
+#define Hunger u.uprops[9].p_flgs
+#define RIN_HUNGER 185
+#define Fire_resistance u.uprops[10].p_flgs
+#define RIN_FIRE_RESISTANCE 186
+#define Cold_resistance u.uprops[11].p_flgs
+#define RIN_COLD_RESISTANCE 187
+#define Protection_from_shape_changers u.uprops[12].p_flgs
+#define RIN_PROTECTION_FROM_SHAPE_CHANGERS 188
+#define Conflict u.uprops[13].p_flgs
+#define RIN_CONFLICT 189
+#define Gain_strength u.uprops[14].p_flgs
+#define RIN_GAIN_STRENGTH 190
+#define Increase_damage u.uprops[15].p_flgs
+#define RIN_INCREASE_DAMAGE 191
+#define Protection u.uprops[16].p_flgs
+#define RIN_PROTECTION 192
+#define Warning u.uprops[17].p_flgs
+#define RIN_WARNING 193
+#define Teleport_control u.uprops[18].p_flgs
+#define RIN_TELEPORT_CONTROL 194
+#define DIAMOND 197
+#define RUBY 198
+#define SAPPHIRE 199
+#define EMERALD 200
+#define TURQUOISE 201
+#define AQUAMARINE 202
+#define TOURMALINE 203
+#define TOPAZ 204
+#define OPAL 205
+#define GARNET 206
+#define AMETHYST 207
+#define AGATE 208
+#define ONYX 209
+#define JASPER 210
+#define JADE 211
+/* #define WORTHLESS_PIECE_OF_BLUE_GLASS 212 */
+/* #define WORTHLESS_PIECE_OF_RED_GLASS 213 */
+/* #define WORTHLESS_PIECE_OF_YELLOW_GLASS 214 */
+/* #define WORTHLESS_PIECE_OF_GREEN_GLASS 215 */
+
+#define CORPSE DEAD_HUMAN
+#define LAST_GEM (JADE+1)
+#define LAST_RING 19
+#define NROFOBJECTS 215
diff --git a/hack/hack.options.c b/hack/hack.options.c
new file mode 100644
index 00000000..ed95de31
--- /dev/null
+++ b/hack/hack.options.c
@@ -0,0 +1,203 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.options.c - version 1.0.3 */
+
+#include "config.h"
+#include "hack.h"
+extern char *eos();
+
+initoptions()
+{
+ register char *opts;
+ extern char *getenv();
+
+ flags.time = flags.nonews = flags.notombstone = flags.end_own =
+ flags.standout = flags.nonull = FALSE;
+ flags.no_rest_on_space = TRUE;
+ flags.invlet_constant = TRUE;
+ flags.end_top = 5;
+ flags.end_around = 4;
+ flags.female = FALSE; /* players are usually male */
+
+ if(opts = getenv("HACKOPTIONS"))
+ parseoptions(opts,TRUE);
+}
+
+parseoptions(opts, from_env)
+register char *opts;
+boolean from_env;
+{
+ register char *op,*op2;
+ unsigned num;
+ boolean negated;
+
+ if(op = index(opts, ',')) {
+ *op++ = 0;
+ parseoptions(op, from_env);
+ }
+ if(op = index(opts, ' ')) {
+ op2 = op;
+ while(*op++)
+ if(*op != ' ') *op2++ = *op;
+ }
+ if(!*opts) return;
+ negated = FALSE;
+ while((*opts == '!') || !strncmp(opts, "no", 2)) {
+ if(*opts == '!') opts++; else opts += 2;
+ negated = !negated;
+ }
+
+ if(!strncmp(opts,"standout",8)) {
+ flags.standout = !negated;
+ return;
+ }
+
+ if(!strncmp(opts,"null",3)) {
+ flags.nonull = negated;
+ return;
+ }
+
+ if(!strncmp(opts,"tombstone",4)) {
+ flags.notombstone = negated;
+ return;
+ }
+
+ if(!strncmp(opts,"news",4)) {
+ flags.nonews = negated;
+ return;
+ }
+
+ if(!strncmp(opts,"time",4)) {
+ flags.time = !negated;
+ flags.botl = 1;
+ return;
+ }
+
+ if(!strncmp(opts,"restonspace",4)) {
+ flags.no_rest_on_space = negated;
+ return;
+ }
+
+ if(!strncmp(opts,"fixinv",4)) {
+ if(from_env)
+ flags.invlet_constant = !negated;
+ else
+ pline("The fixinvlet option must be in HACKOPTIONS.");
+ return;
+ }
+
+ if(!strncmp(opts,"male",4)) {
+ flags.female = negated;
+ return;
+ }
+ if(!strncmp(opts,"female",6)) {
+ flags.female = !negated;
+ return;
+ }
+
+ /* name:string */
+ if(!strncmp(opts,"name",4)) {
+ extern char plname[PL_NSIZ];
+ if(!from_env) {
+ pline("The playername can be set only from HACKOPTIONS.");
+ return;
+ }
+ op = index(opts,':');
+ if(!op) goto bad;
+ (void) strncpy(plname, op+1, sizeof(plname)-1);
+ return;
+ }
+
+ /* endgame:5t[op] 5a[round] o[wn] */
+ if(!strncmp(opts,"endgame",3)) {
+ op = index(opts,':');
+ if(!op) goto bad;
+ op++;
+ while(*op) {
+ num = 1;
+ if(digit(*op)) {
+ num = atoi(op);
+ while(digit(*op)) op++;
+ } else
+ if(*op == '!') {
+ negated = !negated;
+ op++;
+ }
+ switch(*op) {
+ case 't':
+ flags.end_top = num;
+ break;
+ case 'a':
+ flags.end_around = num;
+ break;
+ case 'o':
+ flags.end_own = !negated;
+ break;
+ default:
+ goto bad;
+ }
+ while(letter(*++op)) ;
+ if(*op == '/') op++;
+ }
+ return;
+ }
+bad:
+ if(!from_env) {
+ if(!strncmp(opts, "help", 4)) {
+ pline("%s%s%s",
+"To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ",
+"give the command 'o' followed by the line `<options>' while playing. ",
+"Here <options> is a list of <option>s separated by commas." );
+ pline("%s%s%s",
+"Simple (boolean) options are rest_on_space, news, time, ",
+"null, tombstone, (fe)male. ",
+"These can be negated by prefixing them with '!' or \"no\"." );
+ pline("%s",
+"A string option is name, as in HACKOPTIONS=\"name:Merlin-W\"." );
+ pline("%s%s%s",
+"A compound option is endgame; it is followed by a description of what ",
+"parts of the scorelist you want to see. You might for example say: ",
+"`endgame:own scores/5 top scores/4 around my score'." );
+ return;
+ }
+ pline("Bad option: %s.", opts);
+ pline("Type `o help<cr>' for help.");
+ return;
+ }
+ puts("Bad syntax in HACKOPTIONS.");
+ puts("Use for example:");
+ puts(
+"HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
+ );
+ getret();
+}
+
+doset()
+{
+ char buf[BUFSZ];
+
+ pline("What options do you want to set? ");
+ getlin(buf);
+ if(!buf[0] || buf[0] == '\033') {
+ (void) strcpy(buf,"HACKOPTIONS=");
+ (void) strcat(buf, flags.female ? "female," : "male,");
+ if(flags.standout) (void) strcat(buf,"standout,");
+ if(flags.nonull) (void) strcat(buf,"nonull,");
+ if(flags.nonews) (void) strcat(buf,"nonews,");
+ if(flags.time) (void) strcat(buf,"time,");
+ if(flags.notombstone) (void) strcat(buf,"notombstone,");
+ if(flags.no_rest_on_space)
+ (void) strcat(buf,"!rest_on_space,");
+ if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
+ (void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
+ flags.end_top, flags.end_around);
+ if(flags.end_own) (void) strcat(buf, "/own scores");
+ } else {
+ register char *eop = eos(buf);
+ if(*--eop == ',') *eop = 0;
+ }
+ pline(buf);
+ } else
+ parseoptions(buf, FALSE);
+
+ return(0);
+}
diff --git a/hack/hack.pager.c b/hack/hack.pager.c
new file mode 100644
index 00000000..b1edb916
--- /dev/null
+++ b/hack/hack.pager.c
@@ -0,0 +1,406 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.pager.c - version 1.0.3 */
+
+/* This file contains the command routine dowhatis() and a pager. */
+/* Also readmail() and doshell(), and generally the things that
+ contact the outside world. */
+
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <stdio.h>
+#include "hack.h"
+extern int CO, LI; /* usually COLNO and ROWNO+2 */
+extern char *CD;
+extern char quitchars[];
+extern char *getenv(), *getlogin();
+void done1();
+
+dowhatis()
+{
+ FILE *fp;
+ char bufr[BUFSZ+6];
+ register char *buf = &bufr[6], *ep, q;
+ extern char readchar();
+
+ if(!(fp = fopen(DATAFILE, "r")))
+ pline("Cannot open data file!");
+ else {
+ pline("Specify what? ");
+ q = readchar();
+ if(q != '\t')
+ while(fgets(buf,BUFSZ,fp))
+ if(*buf == q) {
+ ep = index(buf, '\n');
+ if(ep) *ep = 0;
+ /* else: bad data file */
+ /* Expand tab 'by hand' */
+ if(buf[1] == '\t'){
+ buf = bufr;
+ buf[0] = q;
+ (void) strncpy(buf+1, " ", 7);
+ }
+ pline(buf);
+ if(ep[-1] == ';') {
+ pline("More info? ");
+ if(readchar() == 'y') {
+ page_more(fp,1); /* does fclose() */
+ return(0);
+ }
+ }
+ (void) fclose(fp); /* kopper@psuvax1 */
+ return(0);
+ }
+ pline("I've never heard of such things.");
+ (void) fclose(fp);
+ }
+ return(0);
+}
+
+/* make the paging of a file interruptible */
+static int got_intrup;
+
+void
+intruph(){
+ got_intrup++;
+}
+
+/* simple pager, also used from dohelp() */
+page_more(fp,strip)
+FILE *fp;
+int strip; /* nr of chars to be stripped from each line (0 or 1) */
+{
+ register char *bufr, *ep;
+ sig_t prevsig = signal(SIGINT, intruph);
+
+ set_pager(0);
+ bufr = (char *) alloc((unsigned) CO);
+ bufr[CO-1] = 0;
+ while(fgets(bufr,CO-1,fp) && (!strip || *bufr == '\t') && !got_intrup){
+ ep = index(bufr, '\n');
+ if(ep)
+ *ep = 0;
+ if(page_line(bufr+strip)) {
+ set_pager(2);
+ goto ret;
+ }
+ }
+ set_pager(1);
+ret:
+ free(bufr);
+ (void) fclose(fp);
+ (void) signal(SIGINT, prevsig);
+ got_intrup = 0;
+}
+
+static boolean whole_screen = TRUE;
+#define PAGMIN 12 /* minimum # of lines for page below level map */
+
+set_whole_screen() { /* called in termcap as soon as LI is known */
+ whole_screen = (LI-ROWNO-2 <= PAGMIN || !CD);
+}
+
+#ifdef NEWS
+readnews() {
+ register int ret;
+
+ whole_screen = TRUE; /* force a docrt(), our first */
+ ret = page_file(NEWS, TRUE);
+ set_whole_screen();
+ return(ret); /* report whether we did docrt() */
+}
+#endif NEWS
+
+set_pager(mode)
+register int mode; /* 0: open 1: wait+close 2: close */
+{
+ static boolean so;
+ if(mode == 0) {
+ if(!whole_screen) {
+ /* clear topline */
+ clrlin();
+ /* use part of screen below level map */
+ curs(1, ROWNO+4);
+ } else {
+ cls();
+ }
+ so = flags.standout;
+ flags.standout = 1;
+ } else {
+ if(mode == 1) {
+ curs(1, LI);
+ more();
+ }
+ flags.standout = so;
+ if(whole_screen)
+ docrt();
+ else {
+ curs(1, ROWNO+4);
+ cl_eos();
+ }
+ }
+}
+
+page_line(s) /* returns 1 if we should quit */
+register char *s;
+{
+ extern char morc;
+
+ if(cury == LI-1) {
+ if(!*s)
+ return(0); /* suppress blank lines at top */
+ putchar('\n');
+ cury++;
+ cmore("q\033");
+ if(morc) {
+ morc = 0;
+ return(1);
+ }
+ if(whole_screen)
+ cls();
+ else {
+ curs(1, ROWNO+4);
+ cl_eos();
+ }
+ }
+ puts(s);
+ cury++;
+ return(0);
+}
+
+/*
+ * Flexible pager: feed it with a number of lines and it will decide
+ * whether these should be fed to the pager above, or displayed in a
+ * corner.
+ * Call:
+ * cornline(0, title or 0) : initialize
+ * cornline(1, text) : add text to the chain of texts
+ * cornline(2, morcs) : output everything and cleanup
+ * cornline(3, 0) : cleanup
+ */
+
+cornline(mode, text)
+int mode;
+char *text;
+{
+ static struct line {
+ struct line *next_line;
+ char *line_text;
+ } *texthead, *texttail;
+ static int maxlen;
+ static int linect;
+ register struct line *tl;
+
+ if(mode == 0) {
+ texthead = 0;
+ maxlen = 0;
+ linect = 0;
+ if(text) {
+ cornline(1, text); /* title */
+ cornline(1, ""); /* blank line */
+ }
+ return;
+ }
+
+ if(mode == 1) {
+ register int len;
+
+ if(!text) return; /* superfluous, just to be sure */
+ linect++;
+ len = strlen(text);
+ if(len > maxlen)
+ maxlen = len;
+ tl = (struct line *)
+ alloc((unsigned)(len + sizeof(struct line) + 1));
+ tl->next_line = 0;
+ tl->line_text = (char *)(tl + 1);
+ (void) strcpy(tl->line_text, text);
+ if(!texthead)
+ texthead = tl;
+ else
+ texttail->next_line = tl;
+ texttail = tl;
+ return;
+ }
+
+ /* --- now we really do it --- */
+ if(mode == 2 && linect == 1) /* topline only */
+ pline(texthead->line_text);
+ else
+ if(mode == 2) {
+ register int curline, lth;
+
+ if(flags.toplin == 1) more(); /* ab@unido */
+ remember_topl();
+
+ lth = CO - maxlen - 2; /* Use full screen width */
+ if (linect < LI && lth >= 10) { /* in a corner */
+ home ();
+ cl_end ();
+ flags.toplin = 0;
+ curline = 1;
+ for (tl = texthead; tl; tl = tl->next_line) {
+ curs (lth, curline);
+ if(curline > 1)
+ cl_end ();
+ putsym(' ');
+ putstr (tl->line_text);
+ curline++;
+ }
+ curs (lth, curline);
+ cl_end ();
+ cmore (text);
+ home ();
+ cl_end ();
+ docorner (lth, curline-1);
+ } else { /* feed to pager */
+ set_pager(0);
+ for (tl = texthead; tl; tl = tl->next_line) {
+ if (page_line (tl->line_text)) {
+ set_pager(2);
+ goto cleanup;
+ }
+ }
+ if(text) {
+ cgetret(text);
+ set_pager(2);
+ } else
+ set_pager(1);
+ }
+ }
+
+cleanup:
+ while(tl = texthead) {
+ texthead = tl->next_line;
+ free((char *) tl);
+ }
+}
+
+dohelp()
+{
+ char c;
+
+ pline ("Long or short help? ");
+ while (((c = readchar ()) != 'l') && (c != 's') && !index(quitchars,c))
+ bell ();
+ if (!index(quitchars, c))
+ (void) page_file((c == 'l') ? HELP : SHELP, FALSE);
+ return(0);
+}
+
+page_file(fnam, silent) /* return: 0 - cannot open fnam; 1 - otherwise */
+register char *fnam;
+boolean silent;
+{
+#ifdef DEF_PAGER /* this implies that UNIX is defined */
+ {
+ /* use external pager; this may give security problems */
+
+ register int fd = open(fnam, 0);
+
+ if(fd < 0) {
+ if(!silent) pline("Cannot open %s.", fnam);
+ return(0);
+ }
+ if(child(1)){
+ extern char *catmore;
+
+ /* Now that child() does a setuid(getuid()) and a chdir(),
+ we may not be able to open file fnam anymore, so make
+ it stdin. */
+ (void) close(0);
+ if(dup(fd)) {
+ if(!silent) printf("Cannot open %s as stdin.\n", fnam);
+ } else {
+ execl(catmore, "page", (char *) 0);
+ if(!silent) printf("Cannot exec %s.\n", catmore);
+ }
+ exit(1);
+ }
+ (void) close(fd);
+ }
+#else DEF_PAGER
+ {
+ FILE *f; /* free after Robert Viduya */
+
+ if ((f = fopen (fnam, "r")) == (FILE *) 0) {
+ if(!silent) {
+ home(); perror (fnam); flags.toplin = 1;
+ pline ("Cannot open %s.", fnam);
+ }
+ return(0);
+ }
+ page_more(f, 0);
+ }
+#endif DEF_PAGER
+
+ return(1);
+}
+
+#ifdef UNIX
+#ifdef SHELL
+dosh(){
+register char *str;
+ if(child(0)) {
+ if(str = getenv("SHELL"))
+ execl(str, str, (char *) 0);
+ else
+ execl("/bin/sh", "sh", (char *) 0);
+ pline("sh: cannot execute.");
+ exit(1);
+ }
+ return(0);
+}
+#endif SHELL
+
+#ifdef NOWAITINCLUDE
+union wait { /* used only for the cast (union wait *) 0 */
+ int w_status;
+ struct {
+ unsigned short w_Termsig:7;
+ unsigned short w_Coredump:1;
+ unsigned short w_Retcode:8;
+ } w_T;
+};
+
+#else
+
+#ifdef BSD
+#include <sys/wait.h>
+#else
+#include <wait.h>
+#endif BSD
+#endif NOWAITINCLUDE
+
+child(wt) {
+ int status;
+ register int f;
+
+ f = fork();
+ if(f == 0){ /* child */
+ settty((char *) 0); /* also calls end_screen() */
+ (void) setuid(getuid());
+ (void) setgid(getgid());
+#ifdef CHDIR
+ (void) chdir(getenv("HOME"));
+#endif CHDIR
+ return(1);
+ }
+ if(f == -1) { /* cannot fork */
+ pline("Fork failed. Try again.");
+ return(0);
+ }
+ /* fork succeeded; wait for child to exit */
+ (void) signal(SIGINT,SIG_IGN);
+ (void) signal(SIGQUIT,SIG_IGN);
+ (void) wait(&status);
+ gettty();
+ setftty();
+ (void) signal(SIGINT,done1);
+#ifdef WIZARD
+ if(wizard) (void) signal(SIGQUIT,SIG_DFL);
+#endif WIZARD
+ if(wt) getret();
+ docrt();
+ return(0);
+}
+#endif UNIX
diff --git a/hack/hack.potion.c b/hack/hack.potion.c
new file mode 100644
index 00000000..c860299e
--- /dev/null
+++ b/hack/hack.potion.c
@@ -0,0 +1,386 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.potion.c - version 1.0.3 */
+
+#include "hack.h"
+extern int float_down();
+extern char *nomovemsg;
+extern struct monst youmonst;
+extern struct monst *makemon();
+
+dodrink() {
+ register struct obj *otmp,*objs;
+ register struct monst *mtmp;
+ register int unkn = 0, nothing = 0;
+
+ otmp = getobj("!", "drink");
+ if(!otmp) return(0);
+ if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
+ ghost_from_bottle();
+ goto use_it;
+ }
+ switch(otmp->otyp){
+ case POT_RESTORE_STRENGTH:
+ unkn++;
+ pline("Wow! This makes you feel great!");
+ if(u.ustr < u.ustrmax) {
+ u.ustr = u.ustrmax;
+ flags.botl = 1;
+ }
+ break;
+ case POT_BOOZE:
+ unkn++;
+ pline("Ooph! This tastes like liquid fire!");
+ Confusion += d(3,8);
+ /* the whiskey makes us feel better */
+ if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
+ if(!rn2(4)) {
+ pline("You pass out.");
+ multi = -rnd(15);
+ nomovemsg = "You awake with a headache.";
+ }
+ break;
+ case POT_INVISIBILITY:
+ if(Invis || See_invisible)
+ nothing++;
+ else {
+ if(!Blind)
+ pline("Gee! All of a sudden, you can't see yourself.");
+ else
+ pline("You feel rather airy."), unkn++;
+ newsym(u.ux,u.uy);
+ }
+ Invis += rn1(15,31);
+ break;
+ case POT_FRUIT_JUICE:
+ pline("This tastes like fruit juice.");
+ lesshungry(20);
+ break;
+ case POT_HEALING:
+ pline("You begin to feel better.");
+ flags.botl = 1;
+ u.uhp += rnd(10);
+ if(u.uhp > u.uhpmax)
+ u.uhp = ++u.uhpmax;
+ if(Blind) Blind = 1; /* see on next move */
+ if(Sick) Sick = 0;
+ break;
+ case POT_PARALYSIS:
+ if(Levitation)
+ pline("You are motionlessly suspended.");
+ else
+ pline("Your feet are frozen to the floor!");
+ nomul(-(rn1(10,25)));
+ break;
+ case POT_MONSTER_DETECTION:
+ if(!fmon) {
+ strange_feeling(otmp, "You feel threatened.");
+ return(1);
+ } else {
+ cls();
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->mx > 0)
+ at(mtmp->mx,mtmp->my,mtmp->data->mlet);
+ prme();
+ pline("You sense the presence of monsters.");
+ more();
+ docrt();
+ }
+ break;
+ case POT_OBJECT_DETECTION:
+ if(!fobj) {
+ strange_feeling(otmp, "You feel a pull downward.");
+ return(1);
+ } else {
+ for(objs = fobj; objs; objs = objs->nobj)
+ if(objs->ox != u.ux || objs->oy != u.uy)
+ goto outobjmap;
+ pline("You sense the presence of objects close nearby.");
+ break;
+ outobjmap:
+ cls();
+ for(objs = fobj; objs; objs = objs->nobj)
+ at(objs->ox,objs->oy,objs->olet);
+ prme();
+ pline("You sense the presence of objects.");
+ more();
+ docrt();
+ }
+ break;
+ case POT_SICKNESS:
+ pline("Yech! This stuff tastes like poison.");
+ if(Poison_resistance)
+ pline("(But in fact it was biologically contaminated orange juice.)");
+ losestr(rn1(4,3));
+ losehp(rnd(10), "contaminated potion");
+ break;
+ case POT_CONFUSION:
+ if(!Confusion)
+ pline("Huh, What? Where am I?");
+ else
+ nothing++;
+ Confusion += rn1(7,16);
+ break;
+ case POT_GAIN_STRENGTH:
+ pline("Wow do you feel strong!");
+ if(u.ustr >= 118) break; /* > 118 is impossible */
+ if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
+ else u.ustr++;
+ if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
+ flags.botl = 1;
+ break;
+ case POT_SPEED:
+ if(Wounded_legs) {
+ heal_legs();
+ unkn++;
+ break;
+ }
+ if(!(Fast & ~INTRINSIC))
+ pline("You are suddenly moving much faster.");
+ else
+ pline("Your legs get new energy."), unkn++;
+ Fast += rn1(10,100);
+ break;
+ case POT_BLINDNESS:
+ if(!Blind)
+ pline("A cloud of darkness falls upon you.");
+ else
+ nothing++;
+ Blind += rn1(100,250);
+ seeoff(0);
+ break;
+ case POT_GAIN_LEVEL:
+ pluslvl();
+ break;
+ case POT_EXTRA_HEALING:
+ pline("You feel much better.");
+ flags.botl = 1;
+ u.uhp += d(2,20)+1;
+ if(u.uhp > u.uhpmax)
+ u.uhp = (u.uhpmax += 2);
+ if(Blind) Blind = 1;
+ if(Sick) Sick = 0;
+ break;
+ case POT_LEVITATION:
+ if(!Levitation)
+ float_up();
+ else
+ nothing++;
+ Levitation += rnd(100);
+ u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
+ break;
+ default:
+ impossible("What a funny potion! (%u)", otmp->otyp);
+ return(0);
+ }
+ if(nothing) {
+ unkn++;
+ pline("You have a peculiar feeling for a moment, then it passes.");
+ }
+ if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
+ if(!unkn) {
+ objects[otmp->otyp].oc_name_known = 1;
+ more_experienced(0,10);
+ } else if(!objects[otmp->otyp].oc_uname)
+ docall(otmp);
+ }
+use_it:
+ useup(otmp);
+ return(1);
+}
+
+pluslvl()
+{
+ register num;
+
+ pline("You feel more experienced.");
+ num = rnd(10);
+ u.uhpmax += num;
+ u.uhp += num;
+ if(u.ulevel < 14) {
+ extern long newuexp();
+
+ u.uexp = newuexp()+1;
+ pline("Welcome to experience level %u.", ++u.ulevel);
+ }
+ flags.botl = 1;
+}
+
+strange_feeling(obj,txt)
+register struct obj *obj;
+register char *txt;
+{
+ if(flags.beginner)
+ pline("You have a strange feeling for a moment, then it passes.");
+ else
+ pline(txt);
+ if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
+ docall(obj);
+ useup(obj);
+}
+
+char *bottlenames[] = {
+ "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
+};
+
+potionhit(mon, obj)
+register struct monst *mon;
+register struct obj *obj;
+{
+ extern char *xname();
+ register char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
+ boolean uclose, isyou = (mon == &youmonst);
+
+ if(isyou) {
+ uclose = TRUE;
+ pline("The %s crashes on your head and breaks into shivers.",
+ botlnam);
+ losehp(rnd(2), "thrown potion");
+ } else {
+ uclose = (dist(mon->mx,mon->my) < 3);
+ /* perhaps 'E' and 'a' have no head? */
+ pline("The %s crashes on %s's head and breaks into shivers.",
+ botlnam, monnam(mon));
+ if(rn2(5) && mon->mhp > 1)
+ mon->mhp--;
+ }
+ pline("The %s evaporates.", xname(obj));
+
+ if(!isyou && !rn2(3)) switch(obj->otyp) {
+
+ case POT_RESTORE_STRENGTH:
+ case POT_GAIN_STRENGTH:
+ case POT_HEALING:
+ case POT_EXTRA_HEALING:
+ if(mon->mhp < mon->mhpmax) {
+ mon->mhp = mon->mhpmax;
+ pline("%s looks sound and hale again!", Monnam(mon));
+ }
+ break;
+ case POT_SICKNESS:
+ if(mon->mhpmax > 3)
+ mon->mhpmax /= 2;
+ if(mon->mhp > 2)
+ mon->mhp /= 2;
+ break;
+ case POT_CONFUSION:
+ case POT_BOOZE:
+ mon->mconf = 1;
+ break;
+ case POT_INVISIBILITY:
+ unpmon(mon);
+ mon->minvis = 1;
+ pmon(mon);
+ break;
+ case POT_PARALYSIS:
+ mon->mfroz = 1;
+ break;
+ case POT_SPEED:
+ mon->mspeed = MFAST;
+ break;
+ case POT_BLINDNESS:
+ mon->mblinded |= 64 + rn2(64);
+ break;
+/*
+ case POT_GAIN_LEVEL:
+ case POT_LEVITATION:
+ case POT_FRUIT_JUICE:
+ case POT_MONSTER_DETECTION:
+ case POT_OBJECT_DETECTION:
+ break;
+*/
+ }
+ if(uclose && rn2(5))
+ potionbreathe(obj);
+ obfree(obj, Null(obj));
+}
+
+potionbreathe(obj)
+register struct obj *obj;
+{
+ switch(obj->otyp) {
+ case POT_RESTORE_STRENGTH:
+ case POT_GAIN_STRENGTH:
+ if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1;
+ break;
+ case POT_HEALING:
+ case POT_EXTRA_HEALING:
+ if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
+ break;
+ case POT_SICKNESS:
+ if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
+ flags.botl = 1;
+ break;
+ case POT_CONFUSION:
+ case POT_BOOZE:
+ if(!Confusion)
+ pline("You feel somewhat dizzy.");
+ Confusion += rnd(5);
+ break;
+ case POT_INVISIBILITY:
+ pline("For an instant you couldn't see your right hand.");
+ break;
+ case POT_PARALYSIS:
+ pline("Something seems to be holding you.");
+ nomul(-rnd(5));
+ break;
+ case POT_SPEED:
+ Fast += rnd(5);
+ pline("Your knees seem more flexible now.");
+ break;
+ case POT_BLINDNESS:
+ if(!Blind) pline("It suddenly gets dark.");
+ Blind += rnd(5);
+ seeoff(0);
+ break;
+/*
+ case POT_GAIN_LEVEL:
+ case POT_LEVITATION:
+ case POT_FRUIT_JUICE:
+ case POT_MONSTER_DETECTION:
+ case POT_OBJECT_DETECTION:
+ break;
+*/
+ }
+ /* note: no obfree() */
+}
+
+/*
+ * -- rudimentary -- to do this correctly requires much more work
+ * -- all sharp weapons get one or more qualities derived from the potions
+ * -- texts on scrolls may be (partially) wiped out; do they become blank?
+ * -- or does their effect change, like under Confusion?
+ * -- all objects may be made invisible by POT_INVISIBILITY
+ * -- If the flask is small, can one dip a large object? Does it magically
+ * -- become a jug? Etc.
+ */
+dodip(){
+ register struct obj *potion, *obj;
+
+ if(!(obj = getobj("#", "dip")))
+ return(0);
+ if(!(potion = getobj("!", "dip into")))
+ return(0);
+ pline("Interesting...");
+ if(obj->otyp == ARROW || obj->otyp == DART ||
+ obj->otyp == CROSSBOW_BOLT) {
+ if(potion->otyp == POT_SICKNESS) {
+ useup(potion);
+ if(obj->spe < 7) obj->spe++; /* %% */
+ }
+ }
+ return(1);
+}
+
+ghost_from_bottle(){
+ extern struct permonst pm_ghost;
+ register struct monst *mtmp;
+
+ if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){
+ pline("This bottle turns out to be empty.");
+ return;
+ }
+ mnexto(mtmp);
+ pline("As you open the bottle, an enormous ghost emerges!");
+ pline("You are frightened to death, and unable to move.");
+ nomul(-3);
+}
diff --git a/hack/hack.pri.c b/hack/hack.pri.c
new file mode 100644
index 00000000..13ee6b7d
--- /dev/null
+++ b/hack/hack.pri.c
@@ -0,0 +1,660 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.pri.c - version 1.0.3 */
+
+#include "hack.h"
+#include <stdio.h>
+xchar scrlx, scrhx, scrly, scrhy; /* corners of new area on screen */
+
+extern char *hu_stat[]; /* in eat.c */
+extern char *CD;
+
+swallowed()
+{
+ char *ulook = "|@|";
+ ulook[1] = u.usym;
+
+ cls();
+ curs(u.ux-1, u.uy+1);
+ fputs("/-\\", stdout);
+ curx = u.ux+2;
+ curs(u.ux-1, u.uy+2);
+ fputs(ulook, stdout);
+ curx = u.ux+2;
+ curs(u.ux-1, u.uy+3);
+ fputs("\\-/", stdout);
+ curx = u.ux+2;
+ u.udispl = 1;
+ u.udisx = u.ux;
+ u.udisy = u.uy;
+}
+
+
+/*VARARGS1*/
+boolean panicking;
+
+panic(str,a1,a2,a3,a4,a5,a6)
+char *str;
+{
+ if(panicking++) exit(1); /* avoid loops - this should never happen*/
+ home();
+ puts(" Suddenly, the dungeon collapses.");
+ fputs(" ERROR: ", stdout);
+ printf(str,a1,a2,a3,a4,a5,a6);
+#ifdef DEBUG
+#ifdef UNIX
+ if(!fork())
+ abort(); /* generate core dump */
+#endif UNIX
+#endif DEBUG
+ more(); /* contains a fflush() */
+ done("panicked");
+}
+
+atl(x,y,ch)
+register x,y;
+{
+ register struct rm *crm = &levl[x][y];
+
+ if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){
+ impossible("atl(%d,%d,%c)",x,y,ch);
+ return;
+ }
+ if(crm->seen && crm->scrsym == ch) return;
+ crm->scrsym = ch;
+ crm->new = 1;
+ on_scr(x,y);
+}
+
+on_scr(x,y)
+register x,y;
+{
+ if(x < scrlx) scrlx = x;
+ if(x > scrhx) scrhx = x;
+ if(y < scrly) scrly = y;
+ if(y > scrhy) scrhy = y;
+}
+
+/* call: (x,y) - display
+ (-1,0) - close (leave last symbol)
+ (-1,-1)- close (undo last symbol)
+ (-1,let)-open: initialize symbol
+ (-2,let)-change let
+*/
+
+tmp_at(x,y) schar x,y; {
+static schar prevx, prevy;
+static char let;
+ if((int)x == -2){ /* change let call */
+ let = y;
+ return;
+ }
+ if((int)x == -1 && (int)y >= 0){ /* open or close call */
+ let = y;
+ prevx = -1;
+ return;
+ }
+ if(prevx >= 0 && cansee(prevx,prevy)) {
+ delay_output();
+ prl(prevx, prevy); /* in case there was a monster */
+ at(prevx, prevy, levl[prevx][prevy].scrsym);
+ }
+ if(x >= 0){ /* normal call */
+ if(cansee(x,y)) at(x,y,let);
+ prevx = x;
+ prevy = y;
+ } else { /* close call */
+ let = 0;
+ prevx = -1;
+ }
+}
+
+/* like the previous, but the symbols are first erased on completion */
+Tmp_at(x,y) schar x,y; {
+static char let;
+static xchar cnt;
+static coord tc[COLNO]; /* but watch reflecting beams! */
+register xx,yy;
+ if((int)x == -1) {
+ if(y > 0) { /* open call */
+ let = y;
+ cnt = 0;
+ return;
+ }
+ /* close call (do not distinguish y==0 and y==-1) */
+ while(cnt--) {
+ xx = tc[cnt].x;
+ yy = tc[cnt].y;
+ prl(xx, yy);
+ at(xx, yy, levl[xx][yy].scrsym);
+ }
+ cnt = let = 0; /* superfluous */
+ return;
+ }
+ if((int)x == -2) { /* change let call */
+ let = y;
+ return;
+ }
+ /* normal call */
+ if(cansee(x,y)) {
+ if(cnt) delay_output();
+ at(x,y,let);
+ tc[cnt].x = x;
+ tc[cnt].y = y;
+ if(++cnt >= COLNO) panic("Tmp_at overflow?");
+ levl[x][y].new = 0; /* prevent pline-nscr erasing --- */
+ }
+}
+
+setclipped(){
+ error("Hack needs a screen of size at least %d by %d.\n",
+ ROWNO+2, COLNO);
+}
+
+at(x,y,ch)
+register xchar x,y;
+char ch;
+{
+#ifndef lint
+ /* if xchar is unsigned, lint will complain about if(x < 0) */
+ if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
+ impossible("At gets 0%o at %d %d.", ch, x, y);
+ return;
+ }
+#endif lint
+ if(!ch) {
+ impossible("At gets null at %d %d.", x, y);
+ return;
+ }
+ y += 2;
+ curs(x,y);
+ (void) putchar(ch);
+ curx++;
+}
+
+prme(){
+ if(!Invisible) at(u.ux,u.uy,u.usym);
+}
+
+doredraw()
+{
+ docrt();
+ return(0);
+}
+
+docrt()
+{
+ register x,y;
+ register struct rm *room;
+ register struct monst *mtmp;
+
+ if(u.uswallow) {
+ swallowed();
+ return;
+ }
+ cls();
+
+/* Some ridiculous code to get display of @ and monsters (almost) right */
+ if(!Invisible) {
+ levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
+ levl[u.udisx][u.udisy].seen = 1;
+ u.udispl = 1;
+ } else u.udispl = 0;
+
+ seemons(); /* reset old positions */
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ mtmp->mdispl = 0;
+ seemons(); /* force new positions to be shown */
+/* This nonsense should disappear soon --------------------------------- */
+
+ for(y = 0; y < ROWNO; y++)
+ for(x = 0; x < COLNO; x++)
+ if((room = &levl[x][y])->new) {
+ room->new = 0;
+ at(x,y,room->scrsym);
+ } else if(room->seen)
+ at(x,y,room->scrsym);
+ scrlx = COLNO;
+ scrly = ROWNO;
+ scrhx = scrhy = 0;
+ flags.botlx = 1;
+ bot();
+}
+
+docorner(xmin,ymax) register xmin,ymax; {
+ register x,y;
+ register struct rm *room;
+ register struct monst *mtmp;
+
+ if(u.uswallow) { /* Can be done more efficiently */
+ swallowed();
+ return;
+ }
+
+ seemons(); /* reset old positions */
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->mx >= xmin && mtmp->my < ymax)
+ mtmp->mdispl = 0;
+ seemons(); /* force new positions to be shown */
+
+ for(y = 0; y < ymax; y++) {
+ if(y > ROWNO && CD) break;
+ curs(xmin,y+2);
+ cl_end();
+ if(y < ROWNO) {
+ for(x = xmin; x < COLNO; x++) {
+ if((room = &levl[x][y])->new) {
+ room->new = 0;
+ at(x,y,room->scrsym);
+ } else
+ if(room->seen)
+ at(x,y,room->scrsym);
+ }
+ }
+ }
+ if(ymax > ROWNO) {
+ cornbot(xmin-1);
+ if(ymax > ROWNO+1 && CD) {
+ curs(1,ROWNO+3);
+ cl_eos();
+ }
+ }
+}
+
+curs_on_u(){
+ curs(u.ux, u.uy+2);
+}
+
+pru()
+{
+ if(u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
+ /* if(! levl[u.udisx][u.udisy].new) */
+ if(!vism_at(u.udisx, u.udisy))
+ newsym(u.udisx, u.udisy);
+ if(Invisible) {
+ u.udispl = 0;
+ prl(u.ux,u.uy);
+ } else
+ if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
+ atl(u.ux, u.uy, u.usym);
+ u.udispl = 1;
+ u.udisx = u.ux;
+ u.udisy = u.uy;
+ }
+ levl[u.ux][u.uy].seen = 1;
+}
+
+#ifndef NOWORM
+#include "def.wseg.h"
+extern struct wseg *m_atseg;
+#endif NOWORM
+
+/* print a position that is visible for @ */
+prl(x,y)
+{
+ register struct rm *room;
+ register struct monst *mtmp;
+ register struct obj *otmp;
+
+ if(x == u.ux && y == u.uy && (!Invisible)) {
+ pru();
+ return;
+ }
+ if(!isok(x,y)) return;
+ room = &levl[x][y];
+ if((!room->typ) ||
+ (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
+ return;
+ if((mtmp = m_at(x,y)) && !mtmp->mhide &&
+ (!mtmp->minvis || See_invisible)) {
+#ifndef NOWORM
+ if(m_atseg)
+ pwseg(m_atseg);
+ else
+#endif NOWORM
+ pmon(mtmp);
+ }
+ else if((otmp = o_at(x,y)) && room->typ != POOL)
+ atl(x,y,otmp->olet);
+ else if(mtmp && (!mtmp->minvis || See_invisible)) {
+ /* must be a hiding monster, but not hiding right now */
+ /* assume for the moment that long worms do not hide */
+ pmon(mtmp);
+ }
+ else if(g_at(x,y) && room->typ != POOL)
+ atl(x,y,'$');
+ else if(!room->seen || room->scrsym == ' ') {
+ room->new = room->seen = 1;
+ newsym(x,y);
+ on_scr(x,y);
+ }
+ room->seen = 1;
+}
+
+char
+news0(x,y)
+register xchar x,y;
+{
+ register struct obj *otmp;
+ register struct trap *ttmp;
+ struct rm *room;
+ register char tmp;
+
+ room = &levl[x][y];
+ if(!room->seen) tmp = ' ';
+ else if(room->typ == POOL) tmp = POOL_SYM;
+ else if(!Blind && (otmp = o_at(x,y))) tmp = otmp->olet;
+ else if(!Blind && g_at(x,y)) tmp = '$';
+ else if(x == xupstair && y == yupstair) tmp = '<';
+ else if(x == xdnstair && y == ydnstair) tmp = '>';
+ else if((ttmp = t_at(x,y)) && ttmp->tseen) tmp = '^';
+ else switch(room->typ) {
+ case SCORR:
+ case SDOOR:
+ tmp = room->scrsym; /* %% wrong after killing mimic ! */
+ break;
+ case HWALL:
+ tmp = '-';
+ break;
+ case VWALL:
+ tmp = '|';
+ break;
+ case LDOOR:
+ case DOOR:
+ tmp = '+';
+ break;
+ case CORR:
+ tmp = CORR_SYM;
+ break;
+ case ROOM:
+ if(room->lit || cansee(x,y) || Blind) tmp = '.';
+ else tmp = ' ';
+ break;
+/*
+ case POOL:
+ tmp = POOL_SYM;
+ break;
+*/
+ default:
+ tmp = ERRCHAR;
+ }
+ return(tmp);
+}
+
+newsym(x,y)
+register x,y;
+{
+ atl(x,y,news0(x,y));
+}
+
+/* used with wand of digging (or pick-axe): fill scrsym and force display */
+/* also when a POOL evaporates */
+mnewsym(x,y)
+register x,y;
+{
+ register struct rm *room;
+ char newscrsym;
+
+ if(!vism_at(x,y)) {
+ room = &levl[x][y];
+ newscrsym = news0(x,y);
+ if(room->scrsym != newscrsym) {
+ room->scrsym = newscrsym;
+ room->seen = 0;
+ }
+ }
+}
+
+nosee(x,y)
+register x,y;
+{
+ register struct rm *room;
+
+ if(!isok(x,y)) return;
+ room = &levl[x][y];
+ if(room->scrsym == '.' && !room->lit && !Blind) {
+ room->scrsym = ' ';
+ room->new = 1;
+ on_scr(x,y);
+ }
+}
+
+#ifndef QUEST
+prl1(x,y)
+register x,y;
+{
+ if(u.dx) {
+ if(u.dy) {
+ prl(x-(2*u.dx),y);
+ prl(x-u.dx,y);
+ prl(x,y);
+ prl(x,y-u.dy);
+ prl(x,y-(2*u.dy));
+ } else {
+ prl(x,y-1);
+ prl(x,y);
+ prl(x,y+1);
+ }
+ } else {
+ prl(x-1,y);
+ prl(x,y);
+ prl(x+1,y);
+ }
+}
+
+nose1(x,y)
+register x,y;
+{
+ if(u.dx) {
+ if(u.dy) {
+ nosee(x,u.uy);
+ nosee(x,u.uy-u.dy);
+ nosee(x,y);
+ nosee(u.ux-u.dx,y);
+ nosee(u.ux,y);
+ } else {
+ nosee(x,y-1);
+ nosee(x,y);
+ nosee(x,y+1);
+ }
+ } else {
+ nosee(x-1,y);
+ nosee(x,y);
+ nosee(x+1,y);
+ }
+}
+#endif QUEST
+
+vism_at(x,y)
+register x,y;
+{
+ register struct monst *mtmp;
+
+ return((x == u.ux && y == u.uy && !Invisible)
+ ? 1 :
+ (mtmp = m_at(x,y))
+ ? ((Blind && Telepat) || canseemon(mtmp)) :
+ 0);
+}
+
+#ifdef NEWSCR
+pobj(obj) register struct obj *obj; {
+register int show = (!obj->oinvis || See_invisible) &&
+ cansee(obj->ox,obj->oy);
+ if(obj->odispl){
+ if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
+ if(!vism_at(obj->odx,obj->ody)){
+ newsym(obj->odx, obj->ody);
+ obj->odispl = 0;
+ }
+ }
+ if(show && !vism_at(obj->ox,obj->oy)){
+ atl(obj->ox,obj->oy,obj->olet);
+ obj->odispl = 1;
+ obj->odx = obj->ox;
+ obj->ody = obj->oy;
+ }
+}
+#endif NEWSCR
+
+unpobj(obj) register struct obj *obj; {
+/* if(obj->odispl){
+ if(!vism_at(obj->odx, obj->ody))
+ newsym(obj->odx, obj->ody);
+ obj->odispl = 0;
+ }
+*/
+ if(!vism_at(obj->ox,obj->oy))
+ newsym(obj->ox,obj->oy);
+}
+
+seeobjs(){
+register struct obj *obj, *obj2;
+ for(obj = fobj; obj; obj = obj2) {
+ obj2 = obj->nobj;
+ if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
+ && obj->age + 250 < moves)
+ delobj(obj);
+ }
+ for(obj = invent; obj; obj = obj2) {
+ obj2 = obj->nobj;
+ if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
+ && obj->age + 250 < moves)
+ useup(obj);
+ }
+}
+
+seemons(){
+register struct monst *mtmp;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
+ if(mtmp->data->mlet == ';')
+ mtmp->minvis = (u.ustuck != mtmp &&
+ levl[mtmp->mx][mtmp->my].typ == POOL);
+ pmon(mtmp);
+#ifndef NOWORM
+ if(mtmp->wormno) wormsee(mtmp->wormno);
+#endif NOWORM
+ }
+}
+
+pmon(mon) register struct monst *mon; {
+register int show = (Blind && Telepat) || canseemon(mon);
+ if(mon->mdispl){
+ if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
+ unpmon(mon);
+ }
+ if(show && !mon->mdispl){
+ atl(mon->mx,mon->my,
+ (!mon->mappearance
+ || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHANGERS)].p_flgs
+ ) ? mon->data->mlet : mon->mappearance);
+ mon->mdispl = 1;
+ mon->mdx = mon->mx;
+ mon->mdy = mon->my;
+ }
+}
+
+unpmon(mon) register struct monst *mon; {
+ if(mon->mdispl){
+ newsym(mon->mdx, mon->mdy);
+ mon->mdispl = 0;
+ }
+}
+
+nscr()
+{
+ register x,y;
+ register struct rm *room;
+
+ if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
+ pru();
+ for(y = scrly; y <= scrhy; y++)
+ for(x = scrlx; x <= scrhx; x++)
+ if((room = &levl[x][y])->new) {
+ room->new = 0;
+ at(x,y,room->scrsym);
+ }
+ scrhx = scrhy = 0;
+ scrlx = COLNO;
+ scrly = ROWNO;
+}
+
+/* 100 suffices for bot(); no relation with COLNO */
+char oldbot[100], newbot[100];
+cornbot(lth)
+register int lth;
+{
+ if(lth < sizeof(oldbot)) {
+ oldbot[lth] = 0;
+ flags.botl = 1;
+ }
+}
+
+bot()
+{
+register char *ob = oldbot, *nb = newbot;
+register int i;
+extern char *eos();
+ if(flags.botlx) *ob = 0;
+ flags.botl = flags.botlx = 0;
+#ifdef GOLD_ON_BOTL
+ (void) sprintf(newbot,
+ "Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Str ",
+ dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
+#else
+ (void) sprintf(newbot,
+ "Level %-2d Hp %3d(%d) Ac %-2d Str ",
+ dlevel, u.uhp, u.uhpmax, u.uac);
+#endif GOLD_ON_BOTL
+ if(u.ustr>18) {
+ if(u.ustr>117)
+ (void) strcat(newbot,"18/**");
+ else
+ (void) sprintf(eos(newbot), "18/%02d",u.ustr-18);
+ } else
+ (void) sprintf(eos(newbot), "%-2d ",u.ustr);
+#ifdef EXP_ON_BOTL
+ (void) sprintf(eos(newbot), " Exp %2d/%-5lu ", u.ulevel,u.uexp);
+#else
+ (void) sprintf(eos(newbot), " Exp %2u ", u.ulevel);
+#endif EXP_ON_BOTL
+ (void) strcat(newbot, hu_stat[u.uhs]);
+ if(flags.time)
+ (void) sprintf(eos(newbot), " %ld", moves);
+ if(strlen(newbot) >= COLNO) {
+ register char *bp0, *bp1;
+ bp0 = bp1 = newbot;
+ do {
+ if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
+ *bp1++ = *bp0;
+ } while(*bp0++);
+ }
+ for(i = 1; i<COLNO; i++) {
+ if(*ob != *nb){
+ curs(i,ROWNO+2);
+ (void) putchar(*nb ? *nb : ' ');
+ curx++;
+ }
+ if(*ob) ob++;
+ if(*nb) nb++;
+ }
+ (void) strcpy(oldbot, newbot);
+}
+
+#ifdef WAN_PROBING
+mstatusline(mtmp) register struct monst *mtmp; {
+ pline("Status of %s: ", monnam(mtmp));
+ pline("Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Dam %d",
+ mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax,
+ mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
+}
+#endif WAN_PROBING
+
+cls(){
+ if(flags.toplin == 1)
+ more();
+ flags.toplin = 0;
+
+ clear_screen();
+
+ flags.botlx = 1;
+}
diff --git a/hack/hack.read.c b/hack/hack.read.c
new file mode 100644
index 00000000..5c0de3a7
--- /dev/null
+++ b/hack/hack.read.c
@@ -0,0 +1,539 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.read.c - version 1.0.3 */
+
+#include "hack.h"
+
+extern struct monst *makemon();
+extern struct obj *mkobj_at();
+int identify();
+
+doread() {
+ register struct obj *scroll;
+ register boolean confused = (Confusion != 0);
+ register boolean known = FALSE;
+ extern struct obj *some_armor();
+
+ scroll = getobj("?", "read");
+ if(!scroll) return(0);
+ if(!scroll->dknown && Blind) {
+ pline("Being blind, you cannot read the formula on the scroll.");
+ return(0);
+ }
+ if(Blind)
+ pline("As you pronounce the formula on it, the scroll disappears.");
+ else
+ pline("As you read the scroll, it disappears.");
+ if(confused)
+ pline("Being confused, you mispronounce the magic words ... ");
+
+ switch(scroll->otyp) {
+#ifdef MAIL
+ case SCR_MAIL:
+ readmail(/* scroll */);
+ break;
+#endif MAIL
+ case SCR_ENCHANT_ARMOR:
+ { register struct obj *otmp = some_armor();
+ if(!otmp) {
+ strange_feeling(scroll,"Your skin glows then fades.");
+ return(1);
+ }
+ if(confused) {
+ pline("Your %s glows silver for a moment.",
+ objects[otmp->otyp].oc_name);
+ otmp->rustfree = 1;
+ break;
+ }
+ if(otmp->spe > 3 && rn2(otmp->spe)) {
+ pline("Your %s glows violently green for a while, then evaporates.",
+ objects[otmp->otyp].oc_name);
+ useup(otmp);
+ break;
+ }
+ pline("Your %s glows green for a moment.",
+ objects[otmp->otyp].oc_name);
+ otmp->cursed = 0;
+ otmp->spe++;
+ break;
+ }
+ case SCR_DESTROY_ARMOR:
+ if(confused) {
+ register struct obj *otmp = some_armor();
+ if(!otmp) {
+ strange_feeling(scroll,"Your bones itch.");
+ return(1);
+ }
+ pline("Your %s glows purple for a moment.",
+ objects[otmp->otyp].oc_name);
+ otmp->rustfree = 0;
+ break;
+ }
+ if(uarm) {
+ pline("Your armor turns to dust and falls to the floor!");
+ useup(uarm);
+ } else if(uarmh) {
+ pline("Your helmet turns to dust and is blown away!");
+ useup(uarmh);
+ } else if(uarmg) {
+ pline("Your gloves vanish!");
+ useup(uarmg);
+ selftouch("You");
+ } else {
+ strange_feeling(scroll,"Your skin itches.");
+ return(1);
+ }
+ break;
+ case SCR_CONFUSE_MONSTER:
+ if(confused) {
+ pline("Your hands begin to glow purple.");
+ Confusion += rnd(100);
+ } else {
+ pline("Your hands begin to glow blue.");
+ u.umconf = 1;
+ }
+ break;
+ case SCR_SCARE_MONSTER:
+ { register int ct = 0;
+ register struct monst *mtmp;
+
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(cansee(mtmp->mx,mtmp->my)) {
+ if(confused)
+ mtmp->mflee = mtmp->mfroz =
+ mtmp->msleep = 0;
+ else
+ mtmp->mflee = 1;
+ ct++;
+ }
+ if(!ct) {
+ if(confused)
+ pline("You hear sad wailing in the distance.");
+ else
+ pline("You hear maniacal laughter in the distance.");
+ }
+ break;
+ }
+ case SCR_BLANK_PAPER:
+ if(confused)
+ pline("You see strange patterns on this scroll.");
+ else
+ pline("This scroll seems to be blank.");
+ break;
+ case SCR_REMOVE_CURSE:
+ { register struct obj *obj;
+ if(confused)
+ pline("You feel like you need some help.");
+ else
+ pline("You feel like someone is helping you.");
+ for(obj = invent; obj ; obj = obj->nobj)
+ if(obj->owornmask)
+ obj->cursed = confused;
+ if(Punished && !confused) {
+ Punished = 0;
+ freeobj(uchain);
+ unpobj(uchain);
+ free((char *) uchain);
+ uball->spe = 0;
+ uball->owornmask &= ~W_BALL;
+ uchain = uball = (struct obj *) 0;
+ }
+ break;
+ }
+ case SCR_CREATE_MONSTER:
+ { register int cnt = 1;
+
+ if(!rn2(73)) cnt += rnd(4);
+ if(confused) cnt += 12;
+ while(cnt--)
+ (void) makemon(confused ? PM_ACID_BLOB :
+ (struct permonst *) 0, u.ux, u.uy);
+ break;
+ }
+ case SCR_ENCHANT_WEAPON:
+ if(uwep && confused) {
+ pline("Your %s glows silver for a moment.",
+ objects[uwep->otyp].oc_name);
+ uwep->rustfree = 1;
+ } else
+ if(!chwepon(scroll, 1)) /* tests for !uwep */
+ return(1);
+ break;
+ case SCR_DAMAGE_WEAPON:
+ if(uwep && confused) {
+ pline("Your %s glows purple for a moment.",
+ objects[uwep->otyp].oc_name);
+ uwep->rustfree = 0;
+ } else
+ if(!chwepon(scroll, -1)) /* tests for !uwep */
+ return(1);
+ break;
+ case SCR_TAMING:
+ { register int i,j;
+ register int bd = confused ? 5 : 1;
+ register struct monst *mtmp;
+
+ for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
+ if(mtmp = m_at(u.ux+i, u.uy+j))
+ (void) tamedog(mtmp, (struct obj *) 0);
+ break;
+ }
+ case SCR_GENOCIDE:
+ { extern char genocided[], fut_geno[];
+ char buf[BUFSZ];
+ register struct monst *mtmp, *mtmp2;
+
+ pline("You have found a scroll of genocide!");
+ known = TRUE;
+ if(confused)
+ *buf = u.usym;
+ else do {
+ pline("What monster do you want to genocide (Type the letter)? ");
+ getlin(buf);
+ } while(strlen(buf) != 1 || !monstersym(*buf));
+ if(!index(fut_geno, *buf))
+ charcat(fut_geno, *buf);
+ if(!index(genocided, *buf))
+ charcat(genocided, *buf);
+ else {
+ pline("Such monsters do not exist in this world.");
+ break;
+ }
+ for(mtmp = fmon; mtmp; mtmp = mtmp2){
+ mtmp2 = mtmp->nmon;
+ if(mtmp->data->mlet == *buf)
+ mondead(mtmp);
+ }
+ pline("Wiped out all %c's.", *buf);
+ if(*buf == u.usym) {
+ killer = "scroll of genocide";
+ u.uhp = -1;
+ }
+ break;
+ }
+ case SCR_LIGHT:
+ if(!Blind) known = TRUE;
+ litroom(!confused);
+ break;
+ case SCR_TELEPORTATION:
+ if(confused)
+ level_tele();
+ else {
+#ifdef QUEST
+ register int oux = u.ux, ouy = u.uy;
+ tele();
+ if(dist(oux, ouy) > 100) known = TRUE;
+#else QUEST
+ register int uroom = inroom(u.ux, u.uy);
+ tele();
+ if(uroom != inroom(u.ux, u.uy)) known = TRUE;
+#endif QUEST
+ }
+ break;
+ case SCR_GOLD_DETECTION:
+ /* Unfortunately this code has become slightly less elegant,
+ now that gold and traps no longer are of the same type. */
+ if(confused) {
+ register struct trap *ttmp;
+
+ if(!ftrap) {
+ strange_feeling(scroll, "Your toes stop itching.");
+ return(1);
+ } else {
+ for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
+ if(ttmp->tx != u.ux || ttmp->ty != u.uy)
+ goto outtrapmap;
+ /* only under me - no separate display required */
+ pline("Your toes itch!");
+ break;
+ outtrapmap:
+ cls();
+ for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
+ at(ttmp->tx, ttmp->ty, '$');
+ prme();
+ pline("You feel very greedy!");
+ }
+ } else {
+ register struct gold *gtmp;
+
+ if(!fgold) {
+ strange_feeling(scroll, "You feel materially poor.");
+ return(1);
+ } else {
+ known = TRUE;
+ for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
+ if(gtmp->gx != u.ux || gtmp->gy != u.uy)
+ goto outgoldmap;
+ /* only under me - no separate display required */
+ pline("You notice some gold between your feet.");
+ break;
+ outgoldmap:
+ cls();
+ for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
+ at(gtmp->gx, gtmp->gy, '$');
+ prme();
+ pline("You feel very greedy, and sense gold!");
+ }
+ }
+ /* common sequel */
+ more();
+ docrt();
+ break;
+ case SCR_FOOD_DETECTION:
+ { register ct = 0, ctu = 0;
+ register struct obj *obj;
+ register char foodsym = confused ? POTION_SYM : FOOD_SYM;
+
+ for(obj = fobj; obj; obj = obj->nobj)
+ if(obj->olet == FOOD_SYM) {
+ if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
+ else ct++;
+ }
+ if(!ct && !ctu) {
+ strange_feeling(scroll,"Your nose twitches.");
+ return(1);
+ } else if(!ct) {
+ known = TRUE;
+ pline("You smell %s close nearby.",
+ confused ? "something" : "food");
+
+ } else {
+ known = TRUE;
+ cls();
+ for(obj = fobj; obj; obj = obj->nobj)
+ if(obj->olet == foodsym)
+ at(obj->ox, obj->oy, FOOD_SYM);
+ prme();
+ pline("Your nose tingles and you smell %s!",
+ confused ? "something" : "food");
+ more();
+ docrt();
+ }
+ break;
+ }
+ case SCR_IDENTIFY:
+ /* known = TRUE; */
+ if(confused)
+ pline("You identify this as an identify scroll.");
+ else
+ pline("This is an identify scroll.");
+ useup(scroll);
+ objects[SCR_IDENTIFY].oc_name_known = 1;
+ if(!confused)
+ while(
+ !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
+ && invent
+ );
+ return(1);
+ case SCR_MAGIC_MAPPING:
+ { register struct rm *lev;
+ register int num, zx, zy;
+
+ known = TRUE;
+ pline("On this scroll %s a map!",
+ confused ? "was" : "is");
+ for(zy = 0; zy < ROWNO; zy++)
+ for(zx = 0; zx < COLNO; zx++) {
+ if(confused && rn2(7)) continue;
+ lev = &(levl[zx][zy]);
+ if((num = lev->typ) == 0)
+ continue;
+ if(num == SCORR) {
+ lev->typ = CORR;
+ lev->scrsym = CORR_SYM;
+ } else
+ if(num == SDOOR) {
+ lev->typ = DOOR;
+ lev->scrsym = '+';
+ /* do sth in doors ? */
+ } else if(lev->seen) continue;
+#ifndef QUEST
+ if(num != ROOM)
+#endif QUEST
+ {
+ lev->seen = lev->new = 1;
+ if(lev->scrsym == ' ' || !lev->scrsym)
+ newsym(zx,zy);
+ else
+ on_scr(zx,zy);
+ }
+ }
+ break;
+ }
+ case SCR_AMNESIA:
+ { register int zx, zy;
+
+ known = TRUE;
+ for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
+ if(!confused || rn2(7))
+ if(!cansee(zx,zy))
+ levl[zx][zy].seen = 0;
+ docrt();
+ pline("Thinking of Maud you forget everything else.");
+ break;
+ }
+ case SCR_FIRE:
+ { register int num;
+ register struct monst *mtmp;
+
+ known = TRUE;
+ if(confused) {
+ pline("The scroll catches fire and you burn your hands.");
+ losehp(1, "scroll of fire");
+ } else {
+ pline("The scroll erupts in a tower of flame!");
+ if(Fire_resistance)
+ pline("You are uninjured.");
+ else {
+ num = rnd(6);
+ u.uhpmax -= num;
+ losehp(num, "scroll of fire");
+ }
+ }
+ num = (2*num + 1)/3;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
+ if(dist(mtmp->mx,mtmp->my) < 3) {
+ mtmp->mhp -= num;
+ if(index("FY", mtmp->data->mlet))
+ mtmp->mhp -= 3*num; /* this might well kill 'F's */
+ if(mtmp->mhp < 1) {
+ killed(mtmp);
+ break; /* primitive */
+ }
+ }
+ }
+ break;
+ }
+ case SCR_PUNISHMENT:
+ known = TRUE;
+ if(confused) {
+ pline("You feel guilty.");
+ break;
+ }
+ pline("You are being punished for your misbehaviour!");
+ if(Punished){
+ pline("Your iron ball gets heavier.");
+ uball->owt += 15;
+ break;
+ }
+ Punished = INTRINSIC;
+ setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
+ setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
+ uball->spe = 1; /* special ball (see save) */
+ break;
+ default:
+ impossible("What weird language is this written in? (%u)",
+ scroll->otyp);
+ }
+ if(!objects[scroll->otyp].oc_name_known) {
+ if(known && !confused) {
+ objects[scroll->otyp].oc_name_known = 1;
+ more_experienced(0,10);
+ } else if(!objects[scroll->otyp].oc_uname)
+ docall(scroll);
+ }
+ useup(scroll);
+ return(1);
+}
+
+identify(otmp) /* also called by newmail() */
+register struct obj *otmp;
+{
+ objects[otmp->otyp].oc_name_known = 1;
+ otmp->known = otmp->dknown = 1;
+ prinv(otmp);
+ return(1);
+}
+
+litroom(on)
+register boolean on;
+{
+ register num,zx,zy;
+
+ /* first produce the text (provided he is not blind) */
+ if(Blind) goto do_it;
+ if(!on) {
+ if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
+ !levl[u.ux][u.uy].lit) {
+ pline("It seems even darker in here than before.");
+ return;
+ } else
+ pline("It suddenly becomes dark in here.");
+ } else {
+ if(u.uswallow){
+ pline("%s's stomach is lit.", Monnam(u.ustuck));
+ return;
+ }
+ if(!xdnstair){
+ pline("Nothing Happens.");
+ return;
+ }
+#ifdef QUEST
+ pline("The cave lights up around you, then fades.");
+ return;
+#else QUEST
+ if(levl[u.ux][u.uy].typ == CORR) {
+ pline("The corridor lights up around you, then fades.");
+ return;
+ } else if(levl[u.ux][u.uy].lit) {
+ pline("The light here seems better now.");
+ return;
+ } else
+ pline("The room is lit.");
+#endif QUEST
+ }
+
+do_it:
+#ifdef QUEST
+ return;
+#else QUEST
+ if(levl[u.ux][u.uy].lit == on)
+ return;
+ if(levl[u.ux][u.uy].typ == DOOR) {
+ if(IS_ROOM(levl[u.ux][u.uy+1].typ)) zy = u.uy+1;
+ else if(IS_ROOM(levl[u.ux][u.uy-1].typ)) zy = u.uy-1;
+ else zy = u.uy;
+ if(IS_ROOM(levl[u.ux+1][u.uy].typ)) zx = u.ux+1;
+ else if(IS_ROOM(levl[u.ux-1][u.uy].typ)) zx = u.ux-1;
+ else zx = u.ux;
+ } else {
+ zx = u.ux;
+ zy = u.uy;
+ }
+ for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0;
+ seelx--);
+ for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0;
+ seehx++);
+ for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0;
+ seely--);
+ for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0;
+ seehy++);
+ for(zy = seely; zy <= seehy; zy++)
+ for(zx = seelx; zx <= seehx; zx++) {
+ levl[zx][zy].lit = on;
+ if(!Blind && dist(zx,zy) > 2)
+ if(on) prl(zx,zy); else nosee(zx,zy);
+ }
+ if(!on) seehx = 0;
+#endif QUEST
+}
+
+/* Test whether we may genocide all monsters with symbol ch */
+monstersym(ch) /* arnold@ucsfcgl */
+register char ch;
+{
+ register struct permonst *mp;
+ extern struct permonst pm_eel;
+
+ /*
+ * can't genocide certain monsters
+ */
+ if (index("12 &:", ch))
+ return FALSE;
+
+ if (ch == pm_eel.mlet)
+ return TRUE;
+ for (mp = mons; mp < &mons[CMNUM+2]; mp++)
+ if (mp->mlet == ch)
+ return TRUE;
+ return FALSE;
+}
diff --git a/hack/hack.rip.c b/hack/hack.rip.c
new file mode 100644
index 00000000..bdc28230
--- /dev/null
+++ b/hack/hack.rip.c
@@ -0,0 +1,81 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.rip.c - version 1.0.2 */
+
+#include <stdio.h>
+#include "hack.h"
+
+extern char plname[];
+
+static char *rip[] = {
+" ----------",
+" / \\",
+" / REST \\",
+" / IN \\",
+" / PEACE \\",
+" / \\",
+" | |",
+" | |",
+" | |",
+" | |",
+" | |",
+" | 1001 |",
+" *| * * * | *",
+" _________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n",
+0
+};
+
+outrip(){
+ register char **dp = rip;
+ register char *dpx;
+ char buf[BUFSZ];
+ register x,y;
+
+ cls();
+ (void) strcpy(buf, plname);
+ buf[16] = 0;
+ center(6, buf);
+ (void) sprintf(buf, "%ld AU", u.ugold);
+ center(7, buf);
+ (void) sprintf(buf, "killed by%s",
+ !strncmp(killer, "the ", 4) ? "" :
+ !strcmp(killer, "starvation") ? "" :
+ index(vowels, *killer) ? " an" : " a");
+ center(8, buf);
+ (void) strcpy(buf, killer);
+ if(strlen(buf) > 16) {
+ register int i,i0,i1;
+ i0 = i1 = 0;
+ for(i = 0; i <= 16; i++)
+ if(buf[i] == ' ') i0 = i, i1 = i+1;
+ if(!i0) i0 = i1 = 16;
+ buf[i1 + 16] = 0;
+ center(10, buf+i1);
+ buf[i0] = 0;
+ }
+ center(9, buf);
+ (void) sprintf(buf, "%4d", getyear());
+ center(11, buf);
+ for(y=8; *dp; y++,dp++){
+ x = 0;
+ dpx = *dp;
+ while(dpx[x]) {
+ while(dpx[x] == ' ') x++;
+ curs(x,y);
+ while(dpx[x] && dpx[x] != ' '){
+ extern int done_stopprint;
+ if(done_stopprint)
+ return;
+ curx++;
+ (void) putchar(dpx[x++]);
+ }
+ }
+ }
+ getret();
+}
+
+center(line, text) int line; char *text; {
+register char *ip,*op;
+ ip = text;
+ op = &rip[line][28 - ((strlen(text)+1)/2)];
+ while(*ip) *op++ = *ip++;
+}
diff --git a/hack/hack.rumors.c b/hack/hack.rumors.c
new file mode 100644
index 00000000..ee5f1399
--- /dev/null
+++ b/hack/hack.rumors.c
@@ -0,0 +1,63 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.rumors.c - version 1.0.3 */
+
+#include <stdio.h>
+#include "hack.h" /* for RUMORFILE and BSD (index) */
+#define CHARSZ 8 /* number of bits in a char */
+extern long *alloc();
+extern char *index();
+int n_rumors = 0;
+int n_used_rumors = -1;
+char *usedbits;
+
+init_rumors(rumf) register FILE *rumf; {
+register int i;
+ n_used_rumors = 0;
+ while(skipline(rumf)) n_rumors++;
+ rewind(rumf);
+ i = n_rumors/CHARSZ;
+ usedbits = (char *) alloc((unsigned)(i+1));
+ for( ; i>=0; i--) usedbits[i] = 0;
+}
+
+skipline(rumf) register FILE *rumf; {
+char line[COLNO];
+ while(1) {
+ if(!fgets(line, sizeof(line), rumf)) return(0);
+ if(index(line, '\n')) return(1);
+ }
+}
+
+outline(rumf) register FILE *rumf; {
+char line[COLNO];
+register char *ep;
+ if(!fgets(line, sizeof(line), rumf)) return;
+ if((ep = index(line, '\n')) != 0) *ep = 0;
+ pline("This cookie has a scrap of paper inside! It reads: ");
+ pline(line);
+}
+
+outrumor(){
+register int rn,i;
+register FILE *rumf;
+ if(n_rumors <= n_used_rumors ||
+ (rumf = fopen(RUMORFILE, "r")) == (FILE *) 0) return;
+ if(n_used_rumors < 0) init_rumors(rumf);
+ if(!n_rumors) goto none;
+ rn = rn2(n_rumors - n_used_rumors);
+ i = 0;
+ while(rn || used(i)) {
+ (void) skipline(rumf);
+ if(!used(i)) rn--;
+ i++;
+ }
+ usedbits[i/CHARSZ] |= (1 << (i % CHARSZ));
+ n_used_rumors++;
+ outline(rumf);
+none:
+ (void) fclose(rumf);
+}
+
+used(i) register int i; {
+ return(usedbits[i/CHARSZ] & (1 << (i % CHARSZ)));
+}
diff --git a/hack/hack.save.c b/hack/hack.save.c
new file mode 100644
index 00000000..fe09e1e7
--- /dev/null
+++ b/hack/hack.save.c
@@ -0,0 +1,238 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.save.c - version 1.0.3 */
+
+#include "hack.h"
+extern char genocided[60]; /* defined in Decl.c */
+extern char fut_geno[60]; /* idem */
+#include <signal.h>
+
+extern char SAVEF[], nul[];
+extern char pl_character[PL_CSIZ];
+extern long lseek();
+extern struct obj *restobjchn();
+extern struct monst *restmonchn();
+
+dosave(){
+ if(dosave0(0)) {
+ settty("Be seeing you ...\n");
+ exit(0);
+ }
+#ifdef lint
+ return(0);
+#endif lint
+}
+
+#ifndef NOSAVEONHANGUP
+hangup(){
+ (void) dosave0(1);
+ exit(1);
+}
+#endif NOSAVEONHANGUP
+
+/* returns 1 if save successful */
+dosave0(hu) int hu; {
+ register fd, ofd;
+ int tmp; /* not register ! */
+
+ (void) signal(SIGHUP, SIG_IGN);
+ (void) signal(SIGINT, SIG_IGN);
+ if((fd = creat(SAVEF, FMASK)) < 0) {
+ if(!hu) pline("Cannot open save file. (Continue or Quit)");
+ (void) unlink(SAVEF); /* ab@unido */
+ return(0);
+ }
+ if(flags.moonphase == FULL_MOON) /* ut-sally!fletcher */
+ u.uluck--; /* and unido!ab */
+ savelev(fd,dlevel);
+ saveobjchn(fd, invent);
+ saveobjchn(fd, fcobj);
+ savemonchn(fd, fallen_down);
+ tmp = getuid();
+ bwrite(fd, (char *) &tmp, sizeof tmp);
+ bwrite(fd, (char *) &flags, sizeof(struct flag));
+ bwrite(fd, (char *) &dlevel, sizeof dlevel);
+ bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
+ bwrite(fd, (char *) &moves, sizeof moves);
+ bwrite(fd, (char *) &u, sizeof(struct you));
+ if(u.ustuck)
+ bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
+ bwrite(fd, (char *) pl_character, sizeof pl_character);
+ bwrite(fd, (char *) genocided, sizeof genocided);
+ bwrite(fd, (char *) fut_geno, sizeof fut_geno);
+ savenames(fd);
+ for(tmp = 1; tmp <= maxdlevel; tmp++) {
+ extern int hackpid;
+ extern boolean level_exists[];
+
+ if(tmp == dlevel || !level_exists[tmp]) continue;
+ glo(tmp);
+ if((ofd = open(lock, 0)) < 0) {
+ if(!hu) pline("Error while saving: cannot read %s.", lock);
+ (void) close(fd);
+ (void) unlink(SAVEF);
+ if(!hu) done("tricked");
+ return(0);
+ }
+ getlev(ofd, hackpid, tmp);
+ (void) close(ofd);
+ bwrite(fd, (char *) &tmp, sizeof tmp); /* level number */
+ savelev(fd,tmp); /* actual level */
+ (void) unlink(lock);
+ }
+ (void) close(fd);
+ glo(dlevel);
+ (void) unlink(lock); /* get rid of current level --jgm */
+ glo(0);
+ (void) unlink(lock);
+ return(1);
+}
+
+dorecover(fd)
+register fd;
+{
+ register nfd;
+ int tmp; /* not a register ! */
+ unsigned mid; /* idem */
+ struct obj *otmp;
+ extern boolean restoring;
+
+ restoring = TRUE;
+ getlev(fd, 0, 0);
+ invent = restobjchn(fd);
+ for(otmp = invent; otmp; otmp = otmp->nobj)
+ if(otmp->owornmask)
+ setworn(otmp, otmp->owornmask);
+ fcobj = restobjchn(fd);
+ fallen_down = restmonchn(fd);
+ mread(fd, (char *) &tmp, sizeof tmp);
+ if(tmp != getuid()) { /* strange ... */
+ (void) close(fd);
+ (void) unlink(SAVEF);
+ puts("Saved game was not yours.");
+ restoring = FALSE;
+ return(0);
+ }
+ mread(fd, (char *) &flags, sizeof(struct flag));
+ mread(fd, (char *) &dlevel, sizeof dlevel);
+ mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
+ mread(fd, (char *) &moves, sizeof moves);
+ mread(fd, (char *) &u, sizeof(struct you));
+ if(u.ustuck)
+ mread(fd, (char *) &mid, sizeof mid);
+ mread(fd, (char *) pl_character, sizeof pl_character);
+ mread(fd, (char *) genocided, sizeof genocided);
+ mread(fd, (char *) fut_geno, sizeof fut_geno);
+ restnames(fd);
+ while(1) {
+ if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
+ break;
+ getlev(fd, 0, tmp);
+ glo(tmp);
+ if((nfd = creat(lock, FMASK)) < 0)
+ panic("Cannot open temp file %s!\n", lock);
+ savelev(nfd,tmp);
+ (void) close(nfd);
+ }
+ (void) lseek(fd, 0L, 0);
+ getlev(fd, 0, 0);
+ (void) close(fd);
+ (void) unlink(SAVEF);
+ if(Punished) {
+ for(otmp = fobj; otmp; otmp = otmp->nobj)
+ if(otmp->olet == CHAIN_SYM) goto chainfnd;
+ panic("Cannot find the iron chain?");
+ chainfnd:
+ uchain = otmp;
+ if(!uball){
+ for(otmp = fobj; otmp; otmp = otmp->nobj)
+ if(otmp->olet == BALL_SYM && otmp->spe)
+ goto ballfnd;
+ panic("Cannot find the iron ball?");
+ ballfnd:
+ uball = otmp;
+ }
+ }
+ if(u.ustuck) {
+ register struct monst *mtmp;
+
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->m_id == mid) goto monfnd;
+ panic("Cannot find the monster ustuck.");
+ monfnd:
+ u.ustuck = mtmp;
+ }
+#ifndef QUEST
+ setsee(); /* only to recompute seelx etc. - these weren't saved */
+#endif QUEST
+ docrt();
+ restoring = FALSE;
+ return(1);
+}
+
+struct obj *
+restobjchn(fd)
+register fd;
+{
+ register struct obj *otmp, *otmp2;
+ register struct obj *first = 0;
+ int xl;
+#ifdef lint
+ /* suppress "used before set" warning from lint */
+ otmp2 = 0;
+#endif lint
+ while(1) {
+ mread(fd, (char *) &xl, sizeof(xl));
+ if(xl == -1) break;
+ otmp = newobj(xl);
+ if(!first) first = otmp;
+ else otmp2->nobj = otmp;
+ mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
+ if(!otmp->o_id) otmp->o_id = flags.ident++;
+ otmp2 = otmp;
+ }
+ if(first && otmp2->nobj){
+ impossible("Restobjchn: error reading objchn.");
+ otmp2->nobj = 0;
+ }
+ return(first);
+}
+
+struct monst *
+restmonchn(fd)
+register fd;
+{
+ register struct monst *mtmp, *mtmp2;
+ register struct monst *first = 0;
+ int xl;
+
+ struct permonst *monbegin;
+ long differ;
+
+ mread(fd, (char *)&monbegin, sizeof(monbegin));
+ differ = (char *)(&mons[0]) - (char *)(monbegin);
+
+#ifdef lint
+ /* suppress "used before set" warning from lint */
+ mtmp2 = 0;
+#endif lint
+ while(1) {
+ mread(fd, (char *) &xl, sizeof(xl));
+ if(xl == -1) break;
+ mtmp = newmonst(xl);
+ if(!first) first = mtmp;
+ else mtmp2->nmon = mtmp;
+ mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
+ if(!mtmp->m_id)
+ mtmp->m_id = flags.ident++;
+ mtmp->data = (struct permonst *)
+ ((char *) mtmp->data + differ);
+ if(mtmp->minvent)
+ mtmp->minvent = restobjchn(fd);
+ mtmp2 = mtmp;
+ }
+ if(first && mtmp2->nmon){
+ impossible("Restmonchn: error reading monchn.");
+ mtmp2->nmon = 0;
+ }
+ return(first);
+}
diff --git a/hack/hack.search.c b/hack/hack.search.c
new file mode 100644
index 00000000..c0ef9932
--- /dev/null
+++ b/hack/hack.search.c
@@ -0,0 +1,133 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.search.c - version 1.0.3 */
+
+#include "hack.h"
+
+extern struct monst *makemon();
+
+findit() /* returns number of things found */
+{
+ int num;
+ register xchar zx,zy;
+ register struct trap *ttmp;
+ register struct monst *mtmp;
+ xchar lx,hx,ly,hy;
+
+ if(u.uswallow) return(0);
+ for(lx = u.ux; (num = levl[lx-1][u.uy].typ) && num != CORR; lx--) ;
+ for(hx = u.ux; (num = levl[hx+1][u.uy].typ) && num != CORR; hx++) ;
+ for(ly = u.uy; (num = levl[u.ux][ly-1].typ) && num != CORR; ly--) ;
+ for(hy = u.uy; (num = levl[u.ux][hy+1].typ) && num != CORR; hy++) ;
+ num = 0;
+ for(zy = ly; zy <= hy; zy++)
+ for(zx = lx; zx <= hx; zx++) {
+ if(levl[zx][zy].typ == SDOOR) {
+ levl[zx][zy].typ = DOOR;
+ atl(zx, zy, '+');
+ num++;
+ } else if(levl[zx][zy].typ == SCORR) {
+ levl[zx][zy].typ = CORR;
+ atl(zx, zy, CORR_SYM);
+ num++;
+ } else if(ttmp = t_at(zx, zy)) {
+ if(ttmp->ttyp == PIERC){
+ (void) makemon(PM_PIERCER, zx, zy);
+ num++;
+ deltrap(ttmp);
+ } else if(!ttmp->tseen) {
+ ttmp->tseen = 1;
+ if(!vism_at(zx, zy))
+ atl(zx,zy,'^');
+ num++;
+ }
+ } else if(mtmp = m_at(zx,zy)) if(mtmp->mimic){
+ seemimic(mtmp);
+ num++;
+ }
+ }
+ return(num);
+}
+
+dosearch()
+{
+ register xchar x,y;
+ register struct trap *trap;
+ register struct monst *mtmp;
+
+ if(u.uswallow)
+ pline("What are you looking for? The exit?");
+ else
+ for(x = u.ux-1; x < u.ux+2; x++)
+ for(y = u.uy-1; y < u.uy+2; y++) if(x != u.ux || y != u.uy) {
+ if(levl[x][y].typ == SDOOR) {
+ if(rn2(7)) continue;
+ levl[x][y].typ = DOOR;
+ levl[x][y].seen = 0; /* force prl */
+ prl(x,y);
+ nomul(0);
+ } else if(levl[x][y].typ == SCORR) {
+ if(rn2(7)) continue;
+ levl[x][y].typ = CORR;
+ levl[x][y].seen = 0; /* force prl */
+ prl(x,y);
+ nomul(0);
+ } else {
+ /* Be careful not to find anything in an SCORR or SDOOR */
+ if(mtmp = m_at(x,y)) if(mtmp->mimic){
+ seemimic(mtmp);
+ pline("You find a mimic.");
+ return(1);
+ }
+ for(trap = ftrap; trap; trap = trap->ntrap)
+ if(trap->tx == x && trap->ty == y &&
+ !trap->tseen && !rn2(8)) {
+ nomul(0);
+ pline("You find a%s.", traps[trap->ttyp]);
+ if(trap->ttyp == PIERC) {
+ deltrap(trap);
+ (void) makemon(PM_PIERCER,x,y);
+ return(1);
+ }
+ trap->tseen = 1;
+ if(!vism_at(x,y)) atl(x,y,'^');
+ }
+ }
+ }
+ return(1);
+}
+
+doidtrap() {
+register struct trap *trap;
+register int x,y;
+ if(!getdir(1)) return(0);
+ x = u.ux + u.dx;
+ y = u.uy + u.dy;
+ for(trap = ftrap; trap; trap = trap->ntrap)
+ if(trap->tx == x && trap->ty == y && trap->tseen) {
+ if(u.dz)
+ if((u.dz < 0) != (!xdnstair && trap->ttyp == TRAPDOOR))
+ continue;
+ pline("That is a%s.", traps[trap->ttyp]);
+ return(0);
+ }
+ pline("I can't see a trap there.");
+ return(0);
+}
+
+wakeup(mtmp)
+register struct monst *mtmp;
+{
+ mtmp->msleep = 0;
+ setmangry(mtmp);
+ if(mtmp->mimic) seemimic(mtmp);
+}
+
+/* NOTE: we must check if(mtmp->mimic) before calling this routine */
+seemimic(mtmp)
+register struct monst *mtmp;
+{
+ mtmp->mimic = 0;
+ mtmp->mappearance = 0;
+ unpmon(mtmp);
+ pmon(mtmp);
+}
diff --git a/hack/hack.sh b/hack/hack.sh
new file mode 100644
index 00000000..8136ec42
--- /dev/null
+++ b/hack/hack.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+HACKDIR=/usr/games/lib/hackdir
+HACK=$HACKDIR/hack
+MAXNROFPLAYERS=4
+
+cd $HACKDIR
+case $1 in
+ -s*)
+ exec $HACK $@
+ ;;
+ *)
+ exec $HACK $@ $MAXNROFPLAYERS
+ ;;
+esac
diff --git a/hack/hack.shk.c b/hack/hack.shk.c
new file mode 100644
index 00000000..1478b1d8
--- /dev/null
+++ b/hack/hack.shk.c
@@ -0,0 +1,987 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.shk.c - version 1.0.3 */
+
+#include "hack.h"
+#ifdef QUEST
+int shlevel = 0;
+struct monst *shopkeeper = 0;
+struct obj *billobjs = 0;
+obfree(obj,merge) register struct obj *obj, *merge; {
+ free((char *) obj);
+}
+inshop(){ return(0); }
+shopdig(){}
+addtobill(){}
+subfrombill(){}
+splitbill(){}
+dopay(){ return(0); }
+paybill(){}
+doinvbill(){ return(0); }
+shkdead(){}
+shkcatch(){ return(0); }
+shk_move(){ return(0); }
+replshk(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {}
+char *shkname(){ return(""); }
+
+#else QUEST
+#include "hack.mfndpos.h"
+#include "def.mkroom.h"
+#include "def.eshk.h"
+
+#define ESHK(mon) ((struct eshk *)(&(mon->mextra[0])))
+#define NOTANGRY(mon) mon->mpeaceful
+#define ANGRY(mon) !NOTANGRY(mon)
+
+extern char plname[], *xname();
+extern struct obj *o_on(), *bp_to_obj();
+
+/* Descriptor of current shopkeeper. Note that the bill need not be
+ per-shopkeeper, since it is valid only when in a shop. */
+static struct monst *shopkeeper = 0;
+static struct bill_x *bill;
+static int shlevel = 0; /* level of this shopkeeper */
+ struct obj *billobjs; /* objects on bill with bp->useup */
+ /* only accessed here and by save & restore */
+static long int total; /* filled by addupbill() */
+static long int followmsg; /* last time of follow message */
+
+/*
+ invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
+ obj->quan <= bp->bquan
+ */
+
+
+char shtypes[] = { /* 8 shoptypes: 7 specialized, 1 mixed */
+ RING_SYM, WAND_SYM, WEAPON_SYM, FOOD_SYM, SCROLL_SYM,
+ POTION_SYM, ARMOR_SYM, 0
+};
+
+static char *shopnam[] = {
+ "engagement ring", "walking cane", "antique weapon",
+ "delicatessen", "second hand book", "liquor",
+ "used armor", "assorted antiques"
+};
+
+char *
+shkname(mtmp) /* called in do_name.c */
+register struct monst *mtmp;
+{
+ return(ESHK(mtmp)->shknam);
+}
+
+static void setpaid();
+
+shkdead(mtmp) /* called in mon.c */
+register struct monst *mtmp;
+{
+ register struct eshk *eshk = ESHK(mtmp);
+
+ if(eshk->shoplevel == dlevel)
+ rooms[eshk->shoproom].rtype = 0;
+ if(mtmp == shopkeeper) {
+ setpaid();
+ shopkeeper = 0;
+ bill = (struct bill_x *) -1000; /* dump core when referenced */
+ }
+}
+
+replshk(mtmp,mtmp2)
+register struct monst *mtmp, *mtmp2;
+{
+ if(mtmp == shopkeeper) {
+ shopkeeper = mtmp2;
+ bill = &(ESHK(shopkeeper)->bill[0]);
+ }
+}
+
+static void
+setpaid(){ /* caller has checked that shopkeeper exists */
+ /* either we paid or left the shop or he just died */
+register struct obj *obj;
+register struct monst *mtmp;
+ for(obj = invent; obj; obj = obj->nobj)
+ obj->unpaid = 0;
+ for(obj = fobj; obj; obj = obj->nobj)
+ obj->unpaid = 0;
+ for(obj = fcobj; obj; obj = obj->nobj)
+ obj->unpaid = 0;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ for(obj = mtmp->minvent; obj; obj = obj->nobj)
+ obj->unpaid = 0;
+ for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
+ for(obj = mtmp->minvent; obj; obj = obj->nobj)
+ obj->unpaid = 0;
+ while(obj = billobjs){
+ billobjs = obj->nobj;
+ free((char *) obj);
+ }
+ ESHK(shopkeeper)->billct = 0;
+}
+
+static
+addupbill(){ /* delivers result in total */
+ /* caller has checked that shopkeeper exists */
+register ct = ESHK(shopkeeper)->billct;
+register struct bill_x *bp = bill;
+ total = 0;
+ while(ct--){
+ total += bp->price * bp->bquan;
+ bp++;
+ }
+}
+
+inshop(){
+register roomno = inroom(u.ux,u.uy);
+
+ static void findshk();
+
+ /* Did we just leave a shop? */
+ if(u.uinshop &&
+ (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
+ if(shopkeeper) {
+ if(ESHK(shopkeeper)->billct) {
+ if(inroom(shopkeeper->mx, shopkeeper->my)
+ == u.uinshop - 1) /* ab@unido */
+ pline("Somehow you escaped the shop without paying!");
+ addupbill();
+ pline("You stole for a total worth of %ld zorkmids.",
+ total);
+ ESHK(shopkeeper)->robbed += total;
+ setpaid();
+ if((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL)
+ == (rn2(3) == 0))
+ ESHK(shopkeeper)->following = 1;
+ }
+ shopkeeper = 0;
+ shlevel = 0;
+ }
+ u.uinshop = 0;
+ }
+
+ /* Did we just enter a zoo of some kind? */
+ if(roomno >= 0) {
+ register int rt = rooms[roomno].rtype;
+ register struct monst *mtmp;
+ if(rt == ZOO) {
+ pline("Welcome to David's treasure zoo!");
+ } else
+ if(rt == SWAMP) {
+ pline("It looks rather muddy down here.");
+ } else
+ if(rt == MORGUE) {
+ if(midnight())
+ pline("Go away! Go away!");
+ else
+ pline("You get an uncanny feeling ...");
+ } else
+ rt = 0;
+ if(rt != 0) {
+ rooms[roomno].rtype = 0;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(rt != ZOO || !rn2(3))
+ mtmp->msleep = 0;
+ }
+ }
+
+ /* Did we just enter a shop? */
+ if(roomno >= 0 && rooms[roomno].rtype >= 8) {
+ if(shlevel != dlevel || !shopkeeper
+ || ESHK(shopkeeper)->shoproom != roomno)
+ findshk(roomno);
+ if(!shopkeeper) {
+ rooms[roomno].rtype = 0;
+ u.uinshop = 0;
+ } else if(!u.uinshop){
+ if(!ESHK(shopkeeper)->visitct ||
+ strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)){
+
+ /* He seems to be new here */
+ ESHK(shopkeeper)->visitct = 0;
+ ESHK(shopkeeper)->following = 0;
+ (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ);
+ NOTANGRY(shopkeeper) = 1;
+ }
+ if(!ESHK(shopkeeper)->following) {
+ boolean box, pick;
+
+ pline("Hello %s! Welcome%s to %s's %s shop!",
+ plname,
+ ESHK(shopkeeper)->visitct++ ? " again" : "",
+ shkname(shopkeeper),
+ shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8] );
+ box = carrying(ICE_BOX);
+ pick = carrying(PICK_AXE);
+ if(box || pick) {
+ if(dochug(shopkeeper)) {
+ u.uinshop = 0; /* he died moving */
+ return(0);
+ }
+ pline("Will you please leave your %s outside?",
+ (box && pick) ? "box and pick-axe" :
+ box ? "box" : "pick-axe");
+ }
+ }
+ u.uinshop = roomno + 1;
+ }
+ }
+ return(u.uinshop);
+}
+
+static void
+findshk(roomno)
+register roomno;
+{
+register struct monst *mtmp;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->isshk && ESHK(mtmp)->shoproom == roomno
+ && ESHK(mtmp)->shoplevel == dlevel) {
+ shopkeeper = mtmp;
+ bill = &(ESHK(shopkeeper)->bill[0]);
+ shlevel = dlevel;
+ if(ANGRY(shopkeeper) &&
+ strncmp(ESHK(shopkeeper)->customer,plname,PL_NSIZ))
+ NOTANGRY(shopkeeper) = 1;
+ /* billobjs = 0; -- this is wrong if we save in a shop */
+ /* (and it is harmless to have too many things in billobjs) */
+ return;
+ }
+ shopkeeper = 0;
+ shlevel = 0;
+ bill = (struct bill_x *) -1000; /* dump core when referenced */
+}
+
+static struct bill_x *
+onbill(obj) register struct obj *obj; {
+register struct bill_x *bp;
+ if(!shopkeeper) return(0);
+ for(bp = bill; bp < &bill[ESHK(shopkeeper)->billct]; bp++)
+ if(bp->bo_id == obj->o_id) {
+ if(!obj->unpaid) pline("onbill: paid obj on bill?");
+ return(bp);
+ }
+ if(obj->unpaid) pline("onbill: unpaid obj not on bill?");
+ return(0);
+}
+
+/* called with two args on merge */
+obfree(obj,merge) register struct obj *obj, *merge; {
+register struct bill_x *bp = onbill(obj);
+register struct bill_x *bpm;
+ if(bp) {
+ if(!merge){
+ bp->useup = 1;
+ obj->unpaid = 0; /* only for doinvbill */
+ obj->nobj = billobjs;
+ billobjs = obj;
+ return;
+ }
+ bpm = onbill(merge);
+ if(!bpm){
+ /* this used to be a rename */
+ impossible("obfree: not on bill??");
+ return;
+ } else {
+ /* this was a merger */
+ bpm->bquan += bp->bquan;
+ ESHK(shopkeeper)->billct--;
+ *bp = bill[ESHK(shopkeeper)->billct];
+ }
+ }
+ free((char *) obj);
+}
+
+static
+pay(tmp,shkp)
+long tmp;
+register struct monst *shkp;
+{
+ long robbed = ESHK(shkp)->robbed;
+
+ u.ugold -= tmp;
+ shkp->mgold += tmp;
+ flags.botl = 1;
+ if(robbed) {
+ robbed -= tmp;
+ if(robbed < 0) robbed = 0;
+ ESHK(shkp)->robbed = robbed;
+ }
+}
+
+dopay(){
+long ltmp;
+register struct bill_x *bp;
+register struct monst *shkp;
+int pass, tmp;
+
+ static int dopayobj();
+
+ multi = 0;
+ (void) inshop();
+ for(shkp = fmon; shkp; shkp = shkp->nmon)
+ if(shkp->isshk && dist(shkp->mx,shkp->my) < 3)
+ break;
+ if(!shkp && u.uinshop &&
+ inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom)
+ shkp = shopkeeper;
+
+ if(!shkp) {
+ pline("There is nobody here to receive your payment.");
+ return(0);
+ }
+ ltmp = ESHK(shkp)->robbed;
+ if(shkp != shopkeeper && NOTANGRY(shkp)) {
+ if(!ltmp) {
+ pline("You do not owe %s anything.", monnam(shkp));
+ } else
+ if(!u.ugold) {
+ pline("You have no money.");
+ } else {
+ long ugold = u.ugold;
+
+ if(u.ugold > ltmp) {
+ pline("You give %s the %ld gold pieces he asked for.",
+ monnam(shkp), ltmp);
+ pay(ltmp, shkp);
+ } else {
+ pline("You give %s all your gold.", monnam(shkp));
+ pay(u.ugold, shkp);
+ }
+ if(ugold < ltmp/2) {
+ pline("Unfortunately, he doesn't look satisfied.");
+ } else {
+ ESHK(shkp)->robbed = 0;
+ ESHK(shkp)->following = 0;
+ if(ESHK(shkp)->shoplevel != dlevel) {
+ /* For convenience's sake, let him disappear */
+ shkp->minvent = 0; /* %% */
+ shkp->mgold = 0;
+ mondead(shkp);
+ }
+ }
+ }
+ return(1);
+ }
+
+ if(!ESHK(shkp)->billct){
+ pline("You do not owe %s anything.", monnam(shkp));
+ if(!u.ugold){
+ pline("Moreover, you have no money.");
+ return(1);
+ }
+ if(ESHK(shkp)->robbed){
+#define min(a,b) ((a<b)?a:b)
+ pline("But since his shop has been robbed recently,");
+ pline("you %srepay %s's expenses.",
+ (u.ugold < ESHK(shkp)->robbed) ? "partially " : "",
+ monnam(shkp));
+ pay(min(u.ugold, ESHK(shkp)->robbed), shkp);
+ ESHK(shkp)->robbed = 0;
+ return(1);
+ }
+ if(ANGRY(shkp)){
+ pline("But in order to appease %s,",
+ amonnam(shkp, "angry"));
+ if(u.ugold >= 1000){
+ ltmp = 1000;
+ pline(" you give him 1000 gold pieces.");
+ } else {
+ ltmp = u.ugold;
+ pline(" you give him all your money.");
+ }
+ pay(ltmp, shkp);
+ if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)
+ || rn2(3)){
+ pline("%s calms down.", Monnam(shkp));
+ NOTANGRY(shkp) = 1;
+ } else pline("%s is as angry as ever.",
+ Monnam(shkp));
+ }
+ return(1);
+ }
+ if(shkp != shopkeeper) {
+ impossible("dopay: not to shopkeeper?");
+ if(shopkeeper) setpaid();
+ return(0);
+ }
+ for(pass = 0; pass <= 1; pass++) {
+ tmp = 0;
+ while(tmp < ESHK(shopkeeper)->billct) {
+ bp = &bill[tmp];
+ if(!pass && !bp->useup) {
+ tmp++;
+ continue;
+ }
+ if(!dopayobj(bp)) return(1);
+ bill[tmp] = bill[--ESHK(shopkeeper)->billct];
+ }
+ }
+ pline("Thank you for shopping in %s's %s store!",
+ shkname(shopkeeper),
+ shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
+ NOTANGRY(shopkeeper) = 1;
+ return(1);
+}
+
+/* return 1 if paid successfully */
+/* 0 if not enough money */
+/* -1 if object could not be found (but was paid) */
+static
+dopayobj(bp) register struct bill_x *bp; {
+register struct obj *obj;
+long ltmp;
+
+ /* find the object on one of the lists */
+ obj = bp_to_obj(bp);
+
+ if(!obj) {
+ impossible("Shopkeeper administration out of order.");
+ setpaid(); /* be nice to the player */
+ return(0);
+ }
+
+ if(!obj->unpaid && !bp->useup){
+ impossible("Paid object on bill??");
+ return(1);
+ }
+ obj->unpaid = 0;
+ ltmp = bp->price * bp->bquan;
+ if(ANGRY(shopkeeper)) ltmp += ltmp/3;
+ if(u.ugold < ltmp){
+ pline("You don't have gold enough to pay %s.",
+ doname(obj));
+ obj->unpaid = 1;
+ return(0);
+ }
+ pay(ltmp, shopkeeper);
+ pline("You bought %s for %ld gold piece%s.",
+ doname(obj), ltmp, plur(ltmp));
+ if(bp->useup) {
+ register struct obj *otmp = billobjs;
+ if(obj == billobjs)
+ billobjs = obj->nobj;
+ else {
+ while(otmp && otmp->nobj != obj) otmp = otmp->nobj;
+ if(otmp) otmp->nobj = obj->nobj;
+ else pline("Error in shopkeeper administration.");
+ }
+ free((char *) obj);
+ }
+ return(1);
+}
+
+/* routine called after dying (or quitting) with nonempty bill */
+paybill(){
+ if(shlevel == dlevel && shopkeeper && ESHK(shopkeeper)->billct){
+ addupbill();
+ if(total > u.ugold){
+ shopkeeper->mgold += u.ugold;
+ u.ugold = 0;
+ pline("%s comes and takes all your possessions.",
+ Monnam(shopkeeper));
+ } else {
+ u.ugold -= total;
+ shopkeeper->mgold += total;
+ pline("%s comes and takes the %ld zorkmids you owed him.",
+ Monnam(shopkeeper), total);
+ }
+ setpaid(); /* in case we create bones */
+ }
+}
+
+/* find obj on one of the lists */
+struct obj *
+bp_to_obj(bp)
+register struct bill_x *bp;
+{
+ register struct obj *obj;
+ register struct monst *mtmp;
+ register unsigned id = bp->bo_id;
+
+ if(bp->useup)
+ obj = o_on(id, billobjs);
+ else if(!(obj = o_on(id, invent)) &&
+ !(obj = o_on(id, fobj)) &&
+ !(obj = o_on(id, fcobj))) {
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(obj = o_on(id, mtmp->minvent))
+ break;
+ for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
+ if(obj = o_on(id, mtmp->minvent))
+ break;
+ }
+ return(obj);
+}
+
+static int getprice();
+
+/* called in hack.c when we pickup an object */
+addtobill(obj) register struct obj *obj; {
+register struct bill_x *bp;
+ if(!inshop() ||
+ (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) ||
+ (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y) ||
+ onbill(obj) /* perhaps we threw it away earlier */
+ ) return;
+ if(ESHK(shopkeeper)->billct == BILLSZ){
+ pline("You got that for free!");
+ return;
+ }
+ bp = &bill[ESHK(shopkeeper)->billct];
+ bp->bo_id = obj->o_id;
+ bp->bquan = obj->quan;
+ bp->useup = 0;
+ bp->price = getprice(obj);
+ ESHK(shopkeeper)->billct++;
+ obj->unpaid = 1;
+}
+
+splitbill(obj,otmp) register struct obj *obj, *otmp; {
+ /* otmp has been split off from obj */
+register struct bill_x *bp;
+register int tmp;
+ bp = onbill(obj);
+ if(!bp) {
+ impossible("splitbill: not on bill?");
+ return;
+ }
+ if(bp->bquan < otmp->quan) {
+ impossible("Negative quantity on bill??");
+ }
+ if(bp->bquan == otmp->quan) {
+ impossible("Zero quantity on bill??");
+ }
+ bp->bquan -= otmp->quan;
+
+ /* addtobill(otmp); */
+ if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0;
+ else {
+ tmp = bp->price;
+ bp = &bill[ESHK(shopkeeper)->billct];
+ bp->bo_id = otmp->o_id;
+ bp->bquan = otmp->quan;
+ bp->useup = 0;
+ bp->price = tmp;
+ ESHK(shopkeeper)->billct++;
+ }
+}
+
+subfrombill(obj) register struct obj *obj; {
+long ltmp;
+register int tmp;
+register struct obj *otmp;
+register struct bill_x *bp;
+ if(!inshop() || (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) ||
+ (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y))
+ return;
+ if((bp = onbill(obj)) != 0){
+ obj->unpaid = 0;
+ if(bp->bquan > obj->quan){
+ otmp = newobj(0);
+ *otmp = *obj;
+ bp->bo_id = otmp->o_id = flags.ident++;
+ otmp->quan = (bp->bquan -= obj->quan);
+ otmp->owt = 0; /* superfluous */
+ otmp->onamelth = 0;
+ bp->useup = 1;
+ otmp->nobj = billobjs;
+ billobjs = otmp;
+ return;
+ }
+ ESHK(shopkeeper)->billct--;
+ *bp = bill[ESHK(shopkeeper)->billct];
+ return;
+ }
+ if(obj->unpaid){
+ pline("%s didn't notice.", Monnam(shopkeeper));
+ obj->unpaid = 0;
+ return; /* %% */
+ }
+ /* he dropped something of his own - probably wants to sell it */
+ if(shopkeeper->msleep || shopkeeper->mfroz ||
+ inroom(shopkeeper->mx,shopkeeper->my) != ESHK(shopkeeper)->shoproom)
+ return;
+ if(ESHK(shopkeeper)->billct == BILLSZ ||
+ ((tmp = shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype-8]) && tmp != obj->olet)
+ || index("_0", obj->olet)) {
+ pline("%s seems not interested.", Monnam(shopkeeper));
+ return;
+ }
+ ltmp = getprice(obj) * obj->quan;
+ if(ANGRY(shopkeeper)) {
+ ltmp /= 3;
+ NOTANGRY(shopkeeper) = 1;
+ } else ltmp /= 2;
+ if(ESHK(shopkeeper)->robbed){
+ if((ESHK(shopkeeper)->robbed -= ltmp) < 0)
+ ESHK(shopkeeper)->robbed = 0;
+pline("Thank you for your contribution to restock this recently plundered shop.");
+ return;
+ }
+ if(ltmp > shopkeeper->mgold)
+ ltmp = shopkeeper->mgold;
+ pay(-ltmp, shopkeeper);
+ if(!ltmp)
+ pline("%s gladly accepts %s but cannot pay you at present.",
+ Monnam(shopkeeper), doname(obj));
+ else
+ pline("You sold %s and got %ld gold piece%s.", doname(obj), ltmp,
+ plur(ltmp));
+}
+
+doinvbill(mode)
+int mode; /* 0: deliver count 1: paged */
+{
+ register struct bill_x *bp;
+ register struct obj *obj;
+ long totused, thisused;
+ char buf[BUFSZ];
+
+ if(mode == 0) {
+ register int cnt = 0;
+
+ if(shopkeeper)
+ for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++)
+ if(bp->useup ||
+ ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
+ cnt++;
+ return(cnt);
+ }
+
+ if(!shopkeeper) {
+ impossible("doinvbill: no shopkeeper?");
+ return(0);
+ }
+
+ set_pager(0);
+ if(page_line("Unpaid articles already used up:") || page_line(""))
+ goto quit;
+
+ totused = 0;
+ for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) {
+ obj = bp_to_obj(bp);
+ if(!obj) {
+ impossible("Bad shopkeeper administration.");
+ goto quit;
+ }
+ if(bp->useup || bp->bquan > obj->quan) {
+ register int cnt, oquan, uquan;
+
+ oquan = obj->quan;
+ uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
+ thisused = bp->price * uquan;
+ totused += thisused;
+ obj->quan = uquan; /* cheat doname */
+ (void) sprintf(buf, "x - %s", doname(obj));
+ obj->quan = oquan; /* restore value */
+ for(cnt = 0; buf[cnt]; cnt++);
+ while(cnt < 50)
+ buf[cnt++] = ' ';
+ (void) sprintf(&buf[cnt], " %5ld zorkmids", thisused);
+ if(page_line(buf))
+ goto quit;
+ }
+ }
+ (void) sprintf(buf, "Total:%50ld zorkmids", totused);
+ if(page_line("") || page_line(buf))
+ goto quit;
+ set_pager(1);
+ return(0);
+quit:
+ set_pager(2);
+ return(0);
+}
+
+static
+getprice(obj) register struct obj *obj; {
+register int tmp, ac;
+ static int realhunger();
+
+ switch(obj->olet){
+ case AMULET_SYM:
+ tmp = 10*rnd(500);
+ break;
+ case TOOL_SYM:
+ tmp = 10*rnd((obj->otyp == EXPENSIVE_CAMERA) ? 150 : 30);
+ break;
+ case RING_SYM:
+ tmp = 10*rnd(100);
+ break;
+ case WAND_SYM:
+ tmp = 10*rnd(100);
+ break;
+ case SCROLL_SYM:
+ tmp = 10*rnd(50);
+#ifdef MAIL
+ if(obj->otyp == SCR_MAIL)
+ tmp = rnd(5);
+#endif MAIL
+ break;
+ case POTION_SYM:
+ tmp = 10*rnd(50);
+ break;
+ case FOOD_SYM:
+ tmp = 10*rnd(5 + (2000/realhunger()));
+ break;
+ case GEM_SYM:
+ tmp = 10*rnd(20);
+ break;
+ case ARMOR_SYM:
+ ac = ARM_BONUS(obj);
+ if(ac <= -10) /* probably impossible */
+ ac = -9;
+ tmp = 100 + ac*ac*rnd(10+ac);
+ break;
+ case WEAPON_SYM:
+ if(obj->otyp < BOOMERANG)
+ tmp = 5*rnd(10);
+ else if(obj->otyp == LONG_SWORD ||
+ obj->otyp == TWO_HANDED_SWORD)
+ tmp = 10*rnd(150);
+ else tmp = 10*rnd(75);
+ break;
+ case CHAIN_SYM:
+ pline("Strange ..., carrying a chain?");
+ case BALL_SYM:
+ tmp = 10;
+ break;
+ default:
+ tmp = 10000;
+ }
+ return(tmp);
+}
+
+static
+realhunger(){ /* not completely foolproof */
+register tmp = u.uhunger;
+register struct obj *otmp = invent;
+ while(otmp){
+ if(otmp->olet == FOOD_SYM && !otmp->unpaid)
+ tmp += objects[otmp->otyp].nutrition;
+ otmp = otmp->nobj;
+ }
+ return((tmp <= 0) ? 1 : tmp);
+}
+
+shkcatch(obj)
+register struct obj *obj;
+{
+ register struct monst *shkp = shopkeeper;
+
+ if(u.uinshop && shkp && !shkp->mfroz && !shkp->msleep &&
+ u.dx && u.dy &&
+ inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop &&
+ shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y &&
+ u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) {
+ pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj));
+ obj->nobj = shkp->minvent;
+ shkp->minvent = obj;
+ return(1);
+ }
+ return(0);
+}
+
+/*
+ * shk_move: return 1: he moved 0: he didnt -1: let m_move do it
+ */
+shk_move(shkp)
+register struct monst *shkp;
+{
+ register struct monst *mtmp;
+ register struct permonst *mdat = shkp->data;
+ register xchar gx,gy,omx,omy,nx,ny,nix,niy;
+ register schar appr,i;
+ register int udist;
+ int z;
+ schar shkroom,chi,chcnt,cnt;
+ boolean uondoor, satdoor, avoid, badinv;
+ coord poss[9];
+ int info[9];
+ struct obj *ib = 0;
+
+ omx = shkp->mx;
+ omy = shkp->my;
+
+ if((udist = dist(omx,omy)) < 3) {
+ if(ANGRY(shkp)) {
+ (void) hitu(shkp, d(mdat->damn, mdat->damd)+1);
+ return(0);
+ }
+ if(ESHK(shkp)->following) {
+ if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)){
+ pline("Hello %s! I was looking for %s.",
+ plname, ESHK(shkp)->customer);
+ ESHK(shkp)->following = 0;
+ return(0);
+ }
+ if(!ESHK(shkp)->robbed) { /* impossible? */
+ ESHK(shkp)->following = 0;
+ return(0);
+ }
+ if(moves > followmsg+4) {
+ pline("Hello %s! Didn't you forget to pay?",
+ plname);
+ followmsg = moves;
+ }
+ if(udist < 2)
+ return(0);
+ }
+ }
+
+ shkroom = inroom(omx,omy);
+ appr = 1;
+ gx = ESHK(shkp)->shk.x;
+ gy = ESHK(shkp)->shk.y;
+ satdoor = (gx == omx && gy == omy);
+ if(ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){
+ gx = u.ux;
+ gy = u.uy;
+ if(shkroom < 0 || shkroom != inroom(u.ux,u.uy))
+ if(udist > 4)
+ return(-1); /* leave it to m_move */
+ } else if(ANGRY(shkp)) {
+ long saveBlind = Blind;
+ Blind = 0;
+ if(shkp->mcansee && !Invis && cansee(omx,omy)) {
+ gx = u.ux;
+ gy = u.uy;
+ }
+ Blind = saveBlind;
+ avoid = FALSE;
+ } else {
+#define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy))
+ if(Invis)
+ avoid = FALSE;
+ else {
+ uondoor = (u.ux == ESHK(shkp)->shd.x &&
+ u.uy == ESHK(shkp)->shd.y);
+ if(uondoor) {
+ if(ESHK(shkp)->billct)
+ pline("Hello %s! Will you please pay before leaving?",
+ plname);
+ badinv = (carrying(PICK_AXE) || carrying(ICE_BOX));
+ if(satdoor && badinv)
+ return(0);
+ avoid = !badinv;
+ } else {
+ avoid = (u.uinshop && dist(gx,gy) > 8);
+ badinv = FALSE;
+ }
+
+ if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid)
+ && GDIST(omx,omy) < 3){
+ if(!badinv && !online(omx,omy))
+ return(0);
+ if(satdoor)
+ appr = gx = gy = 0;
+ }
+ }
+ }
+ if(omx == gx && omy == gy)
+ return(0);
+ if(shkp->mconf) {
+ avoid = FALSE;
+ appr = 0;
+ }
+ nix = omx;
+ niy = omy;
+ cnt = mfndpos(shkp,poss,info,ALLOW_SSM);
+ if(avoid && uondoor) { /* perhaps we cannot avoid him */
+ for(i=0; i<cnt; i++)
+ if(!(info[i] & NOTONL)) goto notonl_ok;
+ avoid = FALSE;
+ notonl_ok:
+ ;
+ }
+ chi = -1;
+ chcnt = 0;
+ for(i=0; i<cnt; i++){
+ nx = poss[i].x;
+ ny = poss[i].y;
+ if(levl[nx][ny].typ == ROOM
+ || shkroom != ESHK(shkp)->shoproom
+ || ESHK(shkp)->following) {
+#ifdef STUPID
+ /* cater for stupid compilers */
+ register int zz;
+#endif STUPID
+ if(uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) {
+ nix = nx; niy = ny; chi = i; break;
+ }
+ if(avoid && (info[i] & NOTONL))
+ continue;
+ if((!appr && !rn2(++chcnt)) ||
+#ifdef STUPID
+ (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny))
+#else
+ (appr && GDIST(nx,ny) < GDIST(nix,niy))
+#endif STUPID
+ ) {
+ nix = nx;
+ niy = ny;
+ chi = i;
+ }
+ }
+ }
+ if(nix != omx || niy != omy){
+ if(info[chi] & ALLOW_M){
+ mtmp = m_at(nix,niy);
+ if(hitmm(shkp,mtmp) == 1 && rn2(3) &&
+ hitmm(mtmp,shkp) == 2) return(2);
+ return(0);
+ } else if(info[chi] & ALLOW_U){
+ (void) hitu(shkp, d(mdat->damn, mdat->damd)+1);
+ return(0);
+ }
+ shkp->mx = nix;
+ shkp->my = niy;
+ pmon(shkp);
+ if(ib) {
+ freeobj(ib);
+ mpickobj(shkp, ib);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+/* He is digging in the shop. */
+shopdig(fall)
+register int fall;
+{
+ if(!fall) {
+ if(u.utraptype == TT_PIT)
+ pline("\"Be careful, sir, or you might fall through the floor.\"");
+ else
+ pline("\"Please, do not damage the floor here.\"");
+ } else if(dist(shopkeeper->mx, shopkeeper->my) < 3) {
+ register struct obj *obj, *obj2;
+
+ pline("%s grabs your backpack!", shkname(shopkeeper));
+ for(obj = invent; obj; obj = obj2) {
+ obj2 = obj->nobj;
+ if(obj->owornmask) continue;
+ freeinv(obj);
+ obj->nobj = shopkeeper->minvent;
+ shopkeeper->minvent = obj;
+ if(obj->unpaid)
+ subfrombill(obj);
+ }
+ }
+}
+#endif QUEST
+
+online(x,y) {
+ return(x==u.ux || y==u.uy ||
+ (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy));
+}
+
+/* Does this monster follow me downstairs? */
+follower(mtmp)
+register struct monst *mtmp;
+{
+ return( mtmp->mtame || index("1TVWZi&, ", mtmp->data->mlet)
+#ifndef QUEST
+ || (mtmp->isshk && ESHK(mtmp)->following)
+#endif QUEST
+ );
+}
diff --git a/hack/hack.shknam.c b/hack/hack.shknam.c
new file mode 100644
index 00000000..9d4b860f
--- /dev/null
+++ b/hack/hack.shknam.c
@@ -0,0 +1,140 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.shknam.c - version 1.0.2 */
+
+#include "hack.h"
+
+char *shkliquors[] = {
+ /* Ukraine */
+ "Njezjin", "Tsjernigof", "Gomel", "Ossipewsk", "Gorlowka",
+ /* N. Russia */
+ "Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja",
+ "Narodnaja", "Kyzyl",
+ /* Silezie */
+ "Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice",
+ "Brzeg", "Krnov", "Hradec Kralove",
+ /* Schweiz */
+ "Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm",
+ "Flims", "Vals", "Schuls", "Zum Loch",
+ 0
+};
+
+char *shkbooks[] = {
+ /* Eire */
+ "Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch",
+ "Loughrea", "Croagh", "Maumakeogh", "Ballyjamesduff",
+ "Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra",
+ "Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan",
+ "Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh",
+ "Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea",
+ "Culdaff", "Dunfanaghy", "Inishbofin", "Kesh",
+ 0
+};
+
+char *shkarmors[] = {
+ /* Turquie */
+ "Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep",
+ "Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak",
+ "Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt",
+ "Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni",
+ "Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat",
+ "Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan",
+ 0
+};
+
+char *shkwands[] = {
+ /* Wales */
+ "Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach",
+ "Rhaeader", "Llandrindod", "Llanfair-ym-muallt",
+ "Y-Fenni", "Measteg", "Rhydaman", "Beddgelert",
+ "Curig", "Llanrwst", "Llanerchymedd", "Caergybi",
+ /* Scotland */
+ "Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar",
+ "Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven",
+ "Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch",
+ "Kyleakin", "Dunvegan",
+ 0
+};
+
+char *shkrings[] = {
+ /* Hollandse familienamen */
+ "Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken",
+ "Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy",
+ "Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix",
+ "Ypey",
+ /* Skandinaviske navne */
+ "Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko",
+ "Enontekis", "Rovaniemi", "Avasaksa", "Haparanda",
+ "Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske",
+ 0
+};
+
+char *shkfoods[] = {
+ /* Indonesia */
+ "Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan",
+ "Bandjar", "Parbalingga", "Bojolali", "Sarangan",
+ "Ngebel", "Djombang", "Ardjawinangun", "Berbek",
+ "Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi",
+ "Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan",
+ "Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe",
+ "Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe",
+ 0
+};
+
+char *shkweapons[] = {
+ /* Perigord */
+ "Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard",
+ "Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac",
+ "Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac",
+ "Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac",
+ "Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon",
+ "Eymoutiers", "Eygurande", "Eauze", "Labouheyre",
+ 0
+};
+
+char *shkgeneral[] = {
+ /* Suriname */
+ "Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi",
+ "Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo",
+ "Akalapi", "Sipaliwini",
+ /* Greenland */
+ "Annootok", "Upernavik", "Angmagssalik",
+ /* N. Canada */
+ "Aklavik", "Inuvik", "Tuktoyaktuk",
+ "Chicoutimi", "Ouiatchouane", "Chibougamau",
+ "Matagami", "Kipawa", "Kinojevis",
+ "Abitibi", "Maganasipi",
+ /* Iceland */
+ "Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri",
+ "Holmavik",
+ 0
+};
+
+struct shk_nx {
+ char x;
+ char **xn;
+} shk_nx[] = {
+ { POTION_SYM, shkliquors },
+ { SCROLL_SYM, shkbooks },
+ { ARMOR_SYM, shkarmors },
+ { WAND_SYM, shkwands },
+ { RING_SYM, shkrings },
+ { FOOD_SYM, shkfoods },
+ { WEAPON_SYM, shkweapons },
+ { 0, shkgeneral }
+};
+
+findname(nampt, let) char *nampt; char let; {
+register struct shk_nx *p = shk_nx;
+register char **q;
+register int i;
+ while(p->x && p->x != let) p++;
+ q = p->xn;
+ for(i=0; i<dlevel; i++) if(!q[i]){
+ /* Not enough names, try general name */
+ if(let) findname(nampt, 0);
+ else (void) strcpy(nampt, "Dirk");
+ return;
+ }
+ (void) strncpy(nampt, q[i], PL_NSIZ);
+ nampt[PL_NSIZ-1] = 0;
+}
diff --git a/hack/hack.steal.c b/hack/hack.steal.c
new file mode 100644
index 00000000..f123d37f
--- /dev/null
+++ b/hack/hack.steal.c
@@ -0,0 +1,203 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.steal.c - version 1.0.3 */
+
+#include "hack.h"
+
+long /* actually returns something that fits in an int */
+somegold(){
+ return( (u.ugold < 100) ? u.ugold :
+ (u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) );
+}
+
+stealgold(mtmp) register struct monst *mtmp; {
+register struct gold *gold = g_at(u.ux, u.uy);
+register long tmp;
+ if(gold && ( !u.ugold || gold->amount > u.ugold || !rn2(5))) {
+ mtmp->mgold += gold->amount;
+ freegold(gold);
+ if(Invisible) newsym(u.ux, u.uy);
+ pline("%s quickly snatches some gold from between your feet!",
+ Monnam(mtmp));
+ if(!u.ugold || !rn2(5)) {
+ rloc(mtmp);
+ mtmp->mflee = 1;
+ }
+ } else if(u.ugold) {
+ u.ugold -= (tmp = somegold());
+ pline("Your purse feels lighter.");
+ mtmp->mgold += tmp;
+ rloc(mtmp);
+ mtmp->mflee = 1;
+ flags.botl = 1;
+ }
+}
+
+/* steal armor after he finishes taking it off */
+unsigned stealoid; /* object to be stolen */
+unsigned stealmid; /* monster doing the stealing */
+stealarm(){
+ register struct monst *mtmp;
+ register struct obj *otmp;
+
+ for(otmp = invent; otmp; otmp = otmp->nobj)
+ if(otmp->o_id == stealoid) {
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->m_id == stealmid) {
+ if(dist(mtmp->mx,mtmp->my) < 3) {
+ freeinv(otmp);
+ pline("%s steals %s!", Monnam(mtmp), doname(otmp));
+ mpickobj(mtmp,otmp);
+ mtmp->mflee = 1;
+ rloc(mtmp);
+ }
+ break;
+ }
+ break;
+ }
+ stealoid = 0;
+}
+
+/* returns 1 when something was stolen */
+/* (or at least, when N should flee now) */
+/* avoid stealing the object stealoid */
+steal(mtmp)
+struct monst *mtmp;
+{
+ register struct obj *otmp;
+ register tmp;
+ register named = 0;
+
+ if(!invent){
+ if(Blind)
+ pline("Somebody tries to rob you, but finds nothing to steal.");
+ else
+ pline("%s tries to rob you, but she finds nothing to steal!",
+ Monnam(mtmp));
+ return(1); /* let her flee */
+ }
+ tmp = 0;
+ for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2)
+ tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1);
+ tmp = rn2(tmp);
+ for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2)
+ if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1))
+ < 0) break;
+ if(!otmp) {
+ impossible("Steal fails!");
+ return(0);
+ }
+ if(otmp->o_id == stealoid)
+ return(0);
+ if((otmp->owornmask & (W_ARMOR | W_RING))){
+ switch(otmp->olet) {
+ case RING_SYM:
+ ringoff(otmp);
+ break;
+ case ARMOR_SYM:
+ if(multi < 0 || otmp == uarms){
+ setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
+ break;
+ }
+ { int curssv = otmp->cursed;
+ otmp->cursed = 0;
+ stop_occupation();
+ pline("%s seduces you and %s off your %s.",
+ Amonnam(mtmp, Blind ? "gentle" : "beautiful"),
+ otmp->cursed ? "helps you to take"
+ : "you start taking",
+ (otmp == uarmg) ? "gloves" :
+ (otmp == uarmh) ? "helmet" : "armor");
+ named++;
+ (void) armoroff(otmp);
+ otmp->cursed = curssv;
+ if(multi < 0){
+ extern char *nomovemsg;
+ extern int (*afternmv)();
+ /*
+ multi = 0;
+ nomovemsg = 0;
+ afternmv = 0;
+ */
+ stealoid = otmp->o_id;
+ stealmid = mtmp->m_id;
+ afternmv = stealarm;
+ return(0);
+ }
+ break;
+ }
+ default:
+ impossible("Tried to steal a strange worn thing.");
+ }
+ }
+ else if(otmp == uwep)
+ setuwep((struct obj *) 0);
+ if(otmp->olet == CHAIN_SYM) {
+ impossible("How come you are carrying that chain?");
+ }
+ if(Punished && otmp == uball){
+ Punished = 0;
+ freeobj(uchain);
+ free((char *) uchain);
+ uchain = (struct obj *) 0;
+ uball->spe = 0;
+ uball = (struct obj *) 0; /* superfluous */
+ }
+ freeinv(otmp);
+ pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
+ mpickobj(mtmp,otmp);
+ return((multi < 0) ? 0 : 1);
+}
+
+mpickobj(mtmp,otmp)
+register struct monst *mtmp;
+register struct obj *otmp;
+{
+ otmp->nobj = mtmp->minvent;
+ mtmp->minvent = otmp;
+}
+
+stealamulet(mtmp)
+register struct monst *mtmp;
+{
+ register struct obj *otmp;
+
+ for(otmp = invent; otmp; otmp = otmp->nobj) {
+ if(otmp->olet == AMULET_SYM) {
+ /* might be an imitation one */
+ if(otmp == uwep) setuwep((struct obj *) 0);
+ freeinv(otmp);
+ mpickobj(mtmp,otmp);
+ pline("%s stole %s!", Monnam(mtmp), doname(otmp));
+ return(1);
+ }
+ }
+ return(0);
+}
+
+/* release the objects the killed animal has stolen */
+relobj(mtmp,show)
+register struct monst *mtmp;
+register show;
+{
+ register struct obj *otmp, *otmp2;
+
+ for(otmp = mtmp->minvent; otmp; otmp = otmp2){
+ otmp->ox = mtmp->mx;
+ otmp->oy = mtmp->my;
+ otmp2 = otmp->nobj;
+ otmp->nobj = fobj;
+ fobj = otmp;
+ stackobj(fobj);
+ if(show & cansee(mtmp->mx,mtmp->my))
+ atl(otmp->ox,otmp->oy,otmp->olet);
+ }
+ mtmp->minvent = (struct obj *) 0;
+ if(mtmp->mgold || mtmp->data->mlet == 'L') {
+ register long tmp;
+
+ tmp = (mtmp->mgold > 10000) ? 10000 : mtmp->mgold;
+ mkgold((long)(tmp + d(dlevel,30)), mtmp->mx, mtmp->my);
+ if(show & cansee(mtmp->mx,mtmp->my))
+ atl(mtmp->mx,mtmp->my,'$');
+ }
+}
diff --git a/hack/hack.termcap.c b/hack/hack.termcap.c
new file mode 100644
index 00000000..e94d6729
--- /dev/null
+++ b/hack/hack.termcap.c
@@ -0,0 +1,276 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.termcap.c - version 1.0.3 */
+
+#include <stdio.h>
+#include "config.h" /* for ROWNO and COLNO */
+#include "def.flag.h" /* for flags.nonull */
+extern char *tgetstr(), *tgoto(), *getenv();
+extern long *alloc();
+
+#ifndef lint
+extern /* it is defined in libtermlib (libtermcap) */
+#endif lint
+ short ospeed; /* terminal baudrate; used by tputs */
+static char tbuf[512];
+static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
+static char *VS, *VE;
+static int SG;
+static char PC = '\0';
+char *CD; /* tested in pri.c: docorner() */
+int CO, LI; /* used in pri.c and whatis.c */
+
+startup()
+{
+ register char *term;
+ register char *tptr;
+ char *tbufptr, *pc;
+
+ tptr = (char *) alloc(1024);
+
+ tbufptr = tbuf;
+ if(!(term = getenv("TERM")))
+ error("Can't get TERM.");
+ if(!strncmp(term, "5620", 4))
+ flags.nonull = 1; /* this should be a termcap flag */
+ if(tgetent(tptr, term) < 1)
+ error("Unknown terminal type: %s.", term);
+ if(pc = tgetstr("pc", &tbufptr))
+ PC = *pc;
+ if(!(BC = tgetstr("bc", &tbufptr))) {
+ if(!tgetflag("bs"))
+ error("Terminal must backspace.");
+ BC = tbufptr;
+ tbufptr += 2;
+ *BC = '\b';
+ }
+ HO = tgetstr("ho", &tbufptr);
+ CO = tgetnum("co");
+ LI = tgetnum("li");
+ if(CO < COLNO || LI < ROWNO+2)
+ setclipped();
+ if(!(CL = tgetstr("cl", &tbufptr)))
+ error("Hack needs CL.");
+ ND = tgetstr("nd", &tbufptr);
+ if(tgetflag("os"))
+ error("Hack can't have OS.");
+ CE = tgetstr("ce", &tbufptr);
+ UP = tgetstr("up", &tbufptr);
+ /* It seems that xd is no longer supported, and we should use
+ a linefeed instead; unfortunately this requires resetting
+ CRMOD, and many output routines will have to be modified
+ slightly. Let's leave that till the next release. */
+ XD = tgetstr("xd", &tbufptr);
+/* not: XD = tgetstr("do", &tbufptr); */
+ if(!(CM = tgetstr("cm", &tbufptr))) {
+ if(!UP && !HO)
+ error("Hack needs CM or UP or HO.");
+ printf("Playing hack on terminals without cm is suspect...\n");
+ getret();
+ }
+ SO = tgetstr("so", &tbufptr);
+ SE = tgetstr("se", &tbufptr);
+ SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */
+ if(!SO || !SE || (SG > 0)) SO = SE = 0;
+ CD = tgetstr("cd", &tbufptr);
+ set_whole_screen(); /* uses LI and CD */
+ if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
+ free(tptr);
+}
+
+start_screen()
+{
+ xputs(TI);
+ xputs(VS);
+}
+
+end_screen()
+{
+ xputs(VE);
+ xputs(TE);
+}
+
+/* Cursor movements */
+extern xchar curx, cury;
+
+curs(x, y)
+register int x, y; /* not xchar: perhaps xchar is unsigned and
+ curx-x would be unsigned as well */
+{
+
+ if (y == cury && x == curx)
+ return;
+ if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */
+ cmov(x, y); /* bunker!wtm */
+ return;
+ }
+ if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
+ nocmov(x, y);
+ else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
+ (void) putchar('\r');
+ curx = 1;
+ nocmov(x, y);
+ } else if(!CM) {
+ nocmov(x, y);
+ } else
+ cmov(x, y);
+}
+
+nocmov(x, y)
+{
+ if (cury > y) {
+ if(UP) {
+ while (cury > y) { /* Go up. */
+ xputs(UP);
+ cury--;
+ }
+ } else if(CM) {
+ cmov(x, y);
+ } else if(HO) {
+ home();
+ curs(x, y);
+ } /* else impossible("..."); */
+ } else if (cury < y) {
+ if(XD) {
+ while(cury < y) {
+ xputs(XD);
+ cury++;
+ }
+ } else if(CM) {
+ cmov(x, y);
+ } else {
+ while(cury < y) {
+ xputc('\n');
+ curx = 1;
+ cury++;
+ }
+ }
+ }
+ if (curx < x) { /* Go to the right. */
+ if(!ND) cmov(x, y); else /* bah */
+ /* should instead print what is there already */
+ while (curx < x) {
+ xputs(ND);
+ curx++;
+ }
+ } else if (curx > x) {
+ while (curx > x) { /* Go to the left. */
+ xputs(BC);
+ curx--;
+ }
+ }
+}
+
+cmov(x, y)
+register x, y;
+{
+ xputs(tgoto(CM, x-1, y-1));
+ cury = y;
+ curx = x;
+}
+
+xputc(c) char c; {
+ (void) fputc(c, stdout);
+}
+
+xputs(s) char *s; {
+ tputs(s, 1, xputc);
+}
+
+cl_end() {
+ if(CE)
+ xputs(CE);
+ else { /* no-CE fix - free after Harold Rynes */
+ /* this looks terrible, especially on a slow terminal
+ but is better than nothing */
+ register cx = curx, cy = cury;
+
+ while(curx < COLNO) {
+ xputc(' ');
+ curx++;
+ }
+ curs(cx, cy);
+ }
+}
+
+clear_screen() {
+ xputs(CL);
+ curx = cury = 1;
+}
+
+home()
+{
+ if(HO)
+ xputs(HO);
+ else if(CM)
+ xputs(tgoto(CM, 0, 0));
+ else
+ curs(1, 1); /* using UP ... */
+ curx = cury = 1;
+}
+
+standoutbeg()
+{
+ if(SO) xputs(SO);
+}
+
+standoutend()
+{
+ if(SE) xputs(SE);
+}
+
+backsp()
+{
+ xputs(BC);
+ curx--;
+}
+
+bell()
+{
+ (void) putchar('\007'); /* curx does not change */
+ (void) fflush(stdout);
+}
+
+static short tmspc10[] = { /* from termcap */
+ 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
+};
+
+delay_output() {
+ /* delay 50 ms - could also use a 'nap'-system call */
+ /* BUG: if the padding character is visible, as it is on the 5620
+ then this looks terrible. */
+ if(!flags.nonull)
+ tputs("50", 1, xputc);
+
+ /* cbosgd!cbcephus!pds for SYS V R2 */
+ /* is this terminfo, or what? */
+ /* tputs("$<50>", 1, xputc); */
+
+ else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
+ /* delay by sending cm(here) an appropriate number of times */
+ register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
+ register int i = 500 + tmspc10[ospeed]/2;
+
+ while(i > 0) {
+ cmov(curx, cury);
+ i -= cmlen*tmspc10[ospeed];
+ }
+ }
+}
+
+cl_eos() /* free after Robert Viduya */
+{ /* must only be called with curx = 1 */
+
+ if(CD)
+ xputs(CD);
+ else {
+ register int cx = curx, cy = cury;
+ while(cury <= LI-2) {
+ cl_end();
+ xputc('\n');
+ curx = 1;
+ cury++;
+ }
+ cl_end();
+ curs(cx, cy);
+ }
+}
diff --git a/hack/hack.timeout.c b/hack/hack.timeout.c
new file mode 100644
index 00000000..d8282976
--- /dev/null
+++ b/hack/hack.timeout.c
@@ -0,0 +1,62 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.timeout.c - version 1.0.3 */
+
+#include "hack.h"
+
+timeout(){
+register struct prop *upp;
+ if(Stoned) stoned_dialogue();
+ for(upp = u.uprops; upp < u.uprops+SIZE(u.uprops); upp++)
+ if((upp->p_flgs & TIMEOUT) && !--upp->p_flgs) {
+ if(upp->p_tofn) (*upp->p_tofn)();
+ else switch(upp - u.uprops){
+ case STONED:
+ killer = "cockatrice";
+ done("died");
+ break;
+ case SICK:
+ pline("You die because of food poisoning.");
+ killer = u.usick_cause;
+ done("died");
+ break;
+ case FAST:
+ pline("You feel yourself slowing down.");
+ break;
+ case CONFUSION:
+ pline("You feel less confused now.");
+ break;
+ case BLIND:
+ pline("You can see again.");
+ setsee();
+ break;
+ case INVIS:
+ on_scr(u.ux,u.uy);
+ pline("You are no longer invisible.");
+ break;
+ case WOUNDED_LEGS:
+ heal_legs();
+ break;
+ }
+ }
+}
+
+/* He is being petrified - dialogue by inmet!tower */
+char *stoned_texts[] = {
+ "You are slowing down.", /* 5 */
+ "Your limbs are stiffening.", /* 4 */
+ "Your limbs have turned to stone.", /* 3 */
+ "You have turned to stone.", /* 2 */
+ "You are a statue." /* 1 */
+};
+
+stoned_dialogue()
+{
+ register long i = (Stoned & TIMEOUT);
+
+ if(i > 0 && i <= SIZE(stoned_texts))
+ pline(stoned_texts[SIZE(stoned_texts) - i]);
+ if(i == 5)
+ Fast = 0;
+ if(i == 3)
+ nomul(-3);
+}
diff --git a/hack/hack.topl.c b/hack/hack.topl.c
new file mode 100644
index 00000000..13a033d1
--- /dev/null
+++ b/hack/hack.topl.c
@@ -0,0 +1,192 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.topl.c - version 1.0.2 */
+
+#include "hack.h"
+#include <stdio.h>
+extern char *eos();
+extern int CO;
+
+char toplines[BUFSZ];
+xchar tlx, tly; /* set by pline; used by addtopl */
+
+struct topl {
+ struct topl *next_topl;
+ char *topl_text;
+} *old_toplines, *last_redone_topl;
+#define OTLMAX 20 /* max nr of old toplines remembered */
+
+doredotopl(){
+ if(last_redone_topl)
+ last_redone_topl = last_redone_topl->next_topl;
+ if(!last_redone_topl)
+ last_redone_topl = old_toplines;
+ if(last_redone_topl){
+ (void) strcpy(toplines, last_redone_topl->topl_text);
+ }
+ redotoplin();
+ return(0);
+}
+
+redotoplin() {
+ home();
+ if(index(toplines, '\n')) cl_end();
+ putstr(toplines);
+ cl_end();
+ tlx = curx;
+ tly = cury;
+ flags.toplin = 1;
+ if(tly > 1)
+ more();
+}
+
+remember_topl() {
+register struct topl *tl;
+register int cnt = OTLMAX;
+ if(last_redone_topl &&
+ !strcmp(toplines, last_redone_topl->topl_text)) return;
+ if(old_toplines &&
+ !strcmp(toplines, old_toplines->topl_text)) return;
+ last_redone_topl = 0;
+ tl = (struct topl *)
+ alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 1));
+ tl->next_topl = old_toplines;
+ tl->topl_text = (char *)(tl + 1);
+ (void) strcpy(tl->topl_text, toplines);
+ old_toplines = tl;
+ while(cnt && tl){
+ cnt--;
+ tl = tl->next_topl;
+ }
+ if(tl && tl->next_topl){
+ free((char *) tl->next_topl);
+ tl->next_topl = 0;
+ }
+}
+
+addtopl(s) char *s; {
+ curs(tlx,tly);
+ if(tlx + strlen(s) > CO) putsym('\n');
+ putstr(s);
+ tlx = curx;
+ tly = cury;
+ flags.toplin = 1;
+}
+
+xmore(s)
+char *s; /* allowed chars besides space/return */
+{
+ if(flags.toplin) {
+ curs(tlx, tly);
+ if(tlx + 8 > CO) putsym('\n'), tly++;
+ }
+
+ if(flags.standout)
+ standoutbeg();
+ putstr("--More--");
+ if(flags.standout)
+ standoutend();
+
+ xwaitforspace(s);
+ if(flags.toplin && tly > 1) {
+ home();
+ cl_end();
+ docorner(1, tly-1);
+ }
+ flags.toplin = 0;
+}
+
+more(){
+ xmore("");
+}
+
+cmore(s)
+register char *s;
+{
+ xmore(s);
+}
+
+clrlin(){
+ if(flags.toplin) {
+ home();
+ cl_end();
+ if(tly > 1) docorner(1, tly-1);
+ remember_topl();
+ }
+ flags.toplin = 0;
+}
+
+/*VARARGS1*/
+pline(line,arg1,arg2,arg3,arg4,arg5,arg6)
+register char *line,*arg1,*arg2,*arg3,*arg4,*arg5,*arg6;
+{
+ char pbuf[BUFSZ];
+ register char *bp = pbuf, *tl;
+ register int n,n0;
+
+ if(!line || !*line) return;
+ if(!index(line, '%')) (void) strcpy(pbuf,line); else
+ (void) sprintf(pbuf,line,arg1,arg2,arg3,arg4,arg5,arg6);
+ if(flags.toplin == 1 && !strcmp(pbuf, toplines)) return;
+ nscr(); /* %% */
+
+ /* If there is room on the line, print message on same line */
+ /* But messages like "You die..." deserve their own line */
+ n0 = strlen(bp);
+ if(flags.toplin == 1 && tly == 1 &&
+ n0 + strlen(toplines) + 3 < CO-8 && /* leave room for --More-- */
+ strncmp(bp, "You ", 4)) {
+ (void) strcat(toplines, " ");
+ (void) strcat(toplines, bp);
+ tlx += 2;
+ addtopl(bp);
+ return;
+ }
+ if(flags.toplin == 1) more();
+ remember_topl();
+ toplines[0] = 0;
+ while(n0){
+ if(n0 >= CO){
+ /* look for appropriate cut point */
+ n0 = 0;
+ for(n = 0; n < CO; n++) if(bp[n] == ' ')
+ n0 = n;
+ if(!n0) for(n = 0; n < CO-1; n++)
+ if(!letter(bp[n])) n0 = n;
+ if(!n0) n0 = CO-2;
+ }
+ (void) strncpy((tl = eos(toplines)), bp, n0);
+ tl[n0] = 0;
+ bp += n0;
+
+ /* remove trailing spaces, but leave one */
+ while(n0 > 1 && tl[n0-1] == ' ' && tl[n0-2] == ' ')
+ tl[--n0] = 0;
+
+ n0 = strlen(bp);
+ if(n0 && tl[0]) (void) strcat(tl, "\n");
+ }
+ redotoplin();
+}
+
+putsym(c) char c; {
+ switch(c) {
+ case '\b':
+ backsp();
+ return;
+ case '\n':
+ curx = 1;
+ cury++;
+ if(cury > tly) tly = cury;
+ break;
+ default:
+ if(curx == CO)
+ putsym('\n'); /* 1 <= curx <= CO; avoid CO */
+ else
+ curx++;
+ }
+ (void) putchar(c);
+}
+
+putstr(s) register char *s; {
+ while(*s) putsym(*s++);
+}
diff --git a/hack/hack.track.c b/hack/hack.track.c
new file mode 100644
index 00000000..6b41c2cd
--- /dev/null
+++ b/hack/hack.track.c
@@ -0,0 +1,38 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.track.c - version 1.0.2 */
+
+#include "hack.h"
+
+#define UTSZ 50
+
+coord utrack[UTSZ];
+int utcnt = 0;
+int utpnt = 0;
+
+initrack(){
+ utcnt = utpnt = 0;
+}
+
+/* add to track */
+settrack(){
+ if(utcnt < UTSZ) utcnt++;
+ if(utpnt == UTSZ) utpnt = 0;
+ utrack[utpnt].x = u.ux;
+ utrack[utpnt].y = u.uy;
+ utpnt++;
+}
+
+coord *
+gettrack(x,y) register x,y; {
+register int i,cnt,dist;
+coord tc;
+ cnt = utcnt;
+ for(i = utpnt-1; cnt--; i--){
+ if(i == -1) i = UTSZ-1;
+ tc = utrack[i];
+ dist = (x-tc.x)*(x-tc.x) + (y-tc.y)*(y-tc.y);
+ if(dist < 3)
+ return(dist ? &(utrack[i]) : 0);
+ }
+ return(0);
+}
diff --git a/hack/hack.trap.c b/hack/hack.trap.c
new file mode 100644
index 00000000..e426dd1c
--- /dev/null
+++ b/hack/hack.trap.c
@@ -0,0 +1,447 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.trap.c - version 1.0.3 */
+
+#include "hack.h"
+
+extern struct monst *makemon();
+
+char vowels[] = "aeiou";
+
+char *traps[] = {
+ " bear trap",
+ "n arrow trap",
+ " dart trap",
+ " trapdoor",
+ " teleportation trap",
+ " pit",
+ " sleeping gas trap",
+ " piercer",
+ " mimic"
+};
+
+struct trap *
+maketrap(x,y,typ)
+register x,y,typ;
+{
+ register struct trap *ttmp;
+
+ ttmp = newtrap();
+ ttmp->ttyp = typ;
+ ttmp->tseen = 0;
+ ttmp->once = 0;
+ ttmp->tx = x;
+ ttmp->ty = y;
+ ttmp->ntrap = ftrap;
+ ftrap = ttmp;
+ return(ttmp);
+}
+
+dotrap(trap) register struct trap *trap; {
+ register int ttype = trap->ttyp;
+
+ nomul(0);
+ if(trap->tseen && !rn2(5) && ttype != PIT)
+ pline("You escape a%s.", traps[ttype]);
+ else {
+ trap->tseen = 1;
+ switch(ttype) {
+ case SLP_GAS_TRAP:
+ pline("A cloud of gas puts you to sleep!");
+ nomul(-rnd(25));
+ break;
+ case BEAR_TRAP:
+ if(Levitation) {
+ pline("You float over a bear trap.");
+ break;
+ }
+ u.utrap = 4 + rn2(4);
+ u.utraptype = TT_BEARTRAP;
+ pline("A bear trap closes on your foot!");
+ break;
+ case PIERC:
+ deltrap(trap);
+ if(makemon(PM_PIERCER,u.ux,u.uy)) {
+ pline("A piercer suddenly drops from the ceiling!");
+ if(uarmh)
+ pline("Its blow glances off your helmet.");
+ else
+ (void) thitu(3,d(4,6),"falling piercer");
+ }
+ break;
+ case ARROW_TRAP:
+ pline("An arrow shoots out at you!");
+ if(!thitu(8,rnd(6),"arrow")){
+ mksobj_at(ARROW, u.ux, u.uy);
+ fobj->quan = 1;
+ }
+ break;
+ case TRAPDOOR:
+ if(!xdnstair) {
+pline("A trap door in the ceiling opens and a rock falls on your head!");
+if(uarmh) pline("Fortunately, you are wearing a helmet!");
+ losehp(uarmh ? 2 : d(2,10),"falling rock");
+ mksobj_at(ROCK, u.ux, u.uy);
+ fobj->quan = 1;
+ stackobj(fobj);
+ if(Invisible) newsym(u.ux, u.uy);
+ } else {
+ register int newlevel = dlevel + 1;
+ while(!rn2(4) && newlevel < 29)
+ newlevel++;
+ pline("A trap door opens up under you!");
+ if(Levitation || u.ustuck) {
+ pline("For some reason you don't fall in.");
+ break;
+ }
+
+ goto_level(newlevel, FALSE);
+ }
+ break;
+ case DART_TRAP:
+ pline("A little dart shoots out at you!");
+ if(thitu(7,rnd(3),"little dart")) {
+ if(!rn2(6))
+ poisoned("dart","poison dart");
+ } else {
+ mksobj_at(DART, u.ux, u.uy);
+ fobj->quan = 1;
+ }
+ break;
+ case TELEP_TRAP:
+ if(trap->once) {
+ deltrap(trap);
+ newsym(u.ux,u.uy);
+ vtele();
+ } else {
+ newsym(u.ux,u.uy);
+ tele();
+ }
+ break;
+ case PIT:
+ if(Levitation) {
+ pline("A pit opens up under you!");
+ pline("You don't fall in!");
+ break;
+ }
+ pline("You fall into a pit!");
+ u.utrap = rn1(6,2);
+ u.utraptype = TT_PIT;
+ losehp(rnd(6),"fall into a pit");
+ selftouch("Falling, you");
+ break;
+ default:
+ impossible("You hit a trap of type %u", trap->ttyp);
+ }
+ }
+}
+
+mintrap(mtmp) register struct monst *mtmp; {
+ register struct trap *trap = t_at(mtmp->mx, mtmp->my);
+ register int wasintrap = mtmp->mtrapped;
+
+ if(!trap) {
+ mtmp->mtrapped = 0; /* perhaps teleported? */
+ } else if(wasintrap) {
+ if(!rn2(40)) mtmp->mtrapped = 0;
+ } else {
+ register int tt = trap->ttyp;
+ int in_sight = cansee(mtmp->mx,mtmp->my);
+ extern char mlarge[];
+
+ if(mtmp->mtrapseen & (1 << tt)) {
+ /* he has been in such a trap - perhaps he escapes */
+ if(rn2(4)) return(0);
+ }
+ mtmp->mtrapseen |= (1 << tt);
+ switch (tt) {
+ case BEAR_TRAP:
+ if(index(mlarge, mtmp->data->mlet)) {
+ if(in_sight)
+ pline("%s is caught in a bear trap!",
+ Monnam(mtmp));
+ else
+ if(mtmp->data->mlet == 'o')
+ pline("You hear the roaring of an angry bear!");
+ mtmp->mtrapped = 1;
+ }
+ break;
+ case PIT:
+ /* there should be a mtmp/data -> floating */
+ if(!index("EywBfk'& ", mtmp->data->mlet)) { /* ab */
+ mtmp->mtrapped = 1;
+ if(in_sight)
+ pline("%s falls in a pit!", Monnam(mtmp));
+ }
+ break;
+ case SLP_GAS_TRAP:
+ if(!mtmp->msleep && !mtmp->mfroz) {
+ mtmp->msleep = 1;
+ if(in_sight)
+ pline("%s suddenly falls asleep!",
+ Monnam(mtmp));
+ }
+ break;
+ case TELEP_TRAP:
+ rloc(mtmp);
+ if(in_sight && !cansee(mtmp->mx,mtmp->my))
+ pline("%s suddenly disappears!",
+ Monnam(mtmp));
+ break;
+ case ARROW_TRAP:
+ if(in_sight) {
+ pline("%s is hit by an arrow!",
+ Monnam(mtmp));
+ }
+ mtmp->mhp -= 3;
+ break;
+ case DART_TRAP:
+ if(in_sight) {
+ pline("%s is hit by a dart!",
+ Monnam(mtmp));
+ }
+ mtmp->mhp -= 2;
+ /* not mondied here !! */
+ break;
+ case TRAPDOOR:
+ if(!xdnstair) {
+ mtmp->mhp -= 10;
+ if(in_sight)
+pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
+ break;
+ }
+ if(mtmp->data->mlet != 'w'){
+ fall_down(mtmp);
+ if(in_sight)
+ pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
+ return(2); /* no longer on this level */
+ }
+ break;
+ case PIERC:
+ break;
+ default:
+ impossible("Some monster encountered a strange trap.");
+ }
+ }
+ return(mtmp->mtrapped);
+}
+
+selftouch(arg) char *arg; {
+ if(uwep && uwep->otyp == DEAD_COCKATRICE){
+ pline("%s touch the dead cockatrice.", arg);
+ pline("You turn to stone.");
+ killer = objects[uwep->otyp].oc_name;
+ done("died");
+ }
+}
+
+float_up(){
+ if(u.utrap) {
+ if(u.utraptype == TT_PIT) {
+ u.utrap = 0;
+ pline("You float up, out of the pit!");
+ } else {
+ pline("You float up, only your leg is still stuck.");
+ }
+ } else
+ pline("You start to float in the air!");
+}
+
+float_down(){
+ register struct trap *trap;
+ pline("You float gently to the ground.");
+ if(trap = t_at(u.ux,u.uy))
+ switch(trap->ttyp) {
+ case PIERC:
+ break;
+ case TRAPDOOR:
+ if(!xdnstair || u.ustuck) break;
+ /* fall into next case */
+ default:
+ dotrap(trap);
+ }
+ pickup(1);
+}
+
+vtele() {
+#include "def.mkroom.h"
+ register struct mkroom *croom;
+ for(croom = &rooms[0]; croom->hx >= 0; croom++)
+ if(croom->rtype == VAULT) {
+ register x,y;
+
+ x = rn2(2) ? croom->lx : croom->hx;
+ y = rn2(2) ? croom->ly : croom->hy;
+ if(teleok(x,y)) {
+ teleds(x,y);
+ return;
+ }
+ }
+ tele();
+}
+
+tele() {
+ extern coord getpos();
+ coord cc;
+ register int nux,nuy;
+
+ if(Teleport_control) {
+ pline("To what position do you want to be teleported?");
+ cc = getpos(1, "the desired position"); /* 1: force valid */
+ /* possible extensions: introduce a small error if
+ magic power is low; allow transfer to solid rock */
+ if(teleok(cc.x, cc.y)){
+ teleds(cc.x, cc.y);
+ return;
+ }
+ pline("Sorry ...");
+ }
+ do {
+ nux = rnd(COLNO-1);
+ nuy = rn2(ROWNO);
+ } while(!teleok(nux, nuy));
+ teleds(nux, nuy);
+}
+
+teleds(nux, nuy)
+register int nux,nuy;
+{
+ if(Punished) unplacebc();
+ unsee();
+ u.utrap = 0;
+ u.ustuck = 0;
+ u.ux = nux;
+ u.uy = nuy;
+ setsee();
+ if(Punished) placebc(1);
+ if(u.uswallow){
+ u.uswldtim = u.uswallow = 0;
+ docrt();
+ }
+ nomul(0);
+ if(levl[nux][nuy].typ == POOL && !Levitation)
+ drown();
+ (void) inshop();
+ pickup(1);
+ if(!Blind) read_engr_at(u.ux,u.uy);
+}
+
+teleok(x,y) register int x,y; { /* might throw him into a POOL */
+ return( isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y) &&
+ !sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y)
+ );
+ /* Note: gold is permitted (because of vaults) */
+}
+
+dotele() {
+ extern char pl_character[];
+
+ if(
+#ifdef WIZARD
+ !wizard &&
+#endif WIZARD
+ (!Teleportation || u.ulevel < 6 ||
+ (pl_character[0] != 'W' && u.ulevel < 10))) {
+ pline("You are not able to teleport at will.");
+ return(0);
+ }
+ if(u.uhunger <= 100 || u.ustr < 6) {
+ pline("You miss the strength for a teleport spell.");
+ return(1);
+ }
+ tele();
+ morehungry(100);
+ return(1);
+}
+
+placebc(attach) int attach; {
+ if(!uchain || !uball){
+ impossible("Where are your chain and ball??");
+ return;
+ }
+ uball->ox = uchain->ox = u.ux;
+ uball->oy = uchain->oy = u.uy;
+ if(attach){
+ uchain->nobj = fobj;
+ fobj = uchain;
+ if(!carried(uball)){
+ uball->nobj = fobj;
+ fobj = uball;
+ }
+ }
+}
+
+unplacebc(){
+ if(!carried(uball)){
+ freeobj(uball);
+ unpobj(uball);
+ }
+ freeobj(uchain);
+ unpobj(uchain);
+}
+
+level_tele() {
+register int newlevel;
+ if(Teleport_control) {
+ char buf[BUFSZ];
+
+ do {
+ pline("To what level do you want to teleport? [type a number] ");
+ getlin(buf);
+ } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
+ newlevel = atoi(buf);
+ } else {
+ newlevel = 5 + rn2(20); /* 5 - 24 */
+ if(dlevel == newlevel)
+ if(!xdnstair) newlevel--; else newlevel++;
+ }
+ if(newlevel >= 30) {
+ if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;
+ pline("You arrive at the center of the earth ...");
+ pline("Unfortunately it is here that hell is located.");
+ if(Fire_resistance) {
+ pline("But the fire doesn't seem to harm you.");
+ } else {
+ pline("You burn to a crisp.");
+ dlevel = maxdlevel = newlevel;
+ killer = "visit to the hell";
+ done("burned");
+ }
+ }
+ if(newlevel < 0) {
+ newlevel = 0;
+ pline("You are now high above the clouds ...");
+ if(Levitation) {
+ pline("You float gently down to earth.");
+ done("escaped");
+ }
+ pline("Unfortunately, you don't know how to fly.");
+ pline("You fall down a few thousand feet and break your neck.");
+ dlevel = 0;
+ killer = "fall";
+ done("died");
+ }
+
+ goto_level(newlevel, FALSE); /* calls done("escaped") if newlevel==0 */
+}
+
+drown()
+{
+ pline("You fall into a pool!");
+ pline("You can't swim!");
+ if(rn2(3) < u.uluck+2) {
+ /* most scrolls become unreadable */
+ register struct obj *obj;
+
+ for(obj = invent; obj; obj = obj->nobj)
+ if(obj->olet == SCROLL_SYM && rn2(12) > u.uluck)
+ obj->otyp = SCR_BLANK_PAPER;
+ /* we should perhaps merge these scrolls ? */
+
+ pline("You attempt a teleport spell."); /* utcsri!carroll */
+ (void) dotele();
+ if(levl[u.ux][u.uy].typ != POOL) return;
+ }
+ pline("You drown ...");
+ killer = "pool of water";
+ done("drowned");
+}
diff --git a/hack/hack.tty.c b/hack/hack.tty.c
new file mode 100644
index 00000000..68fefc4e
--- /dev/null
+++ b/hack/hack.tty.c
@@ -0,0 +1,338 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)hack.tty.c 5.3 (Berkeley) 5/13/91";
+#endif /* not lint */
+
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.tty.c - version 1.0.3 */
+/* With thanks to the people who sent code for SYSV - hpscdi!jon,
+ arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others. */
+
+#include "hack.h"
+#include <stdio.h>
+
+/*
+ * The distinctions here are not BSD - rest but rather USG - rest, as
+ * BSD still has the old sgttyb structure, but SYSV has termio. Thus:
+ */
+#ifdef BSD
+#define V7
+#else
+#define USG
+#endif BSD
+
+/*
+ * Some systems may have getchar() return EOF for various reasons, and
+ * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
+ */
+#ifndef BSD
+#define NR_OF_EOFS 20
+#endif BSD
+
+
+#ifdef USG
+
+#include <termio.h>
+#define termstruct termio
+#define kill_sym c_cc[VKILL]
+#define erase_sym c_cc[VERASE]
+#define EXTABS TAB3
+#define tabflgs c_oflag
+#define echoflgs c_lflag
+#define cbrkflgs c_lflag
+#define CBRKMASK ICANON
+#define CBRKON ! /* reverse condition */
+#define OSPEED(x) ((x).c_cflag & CBAUD)
+#define GTTY(x) (ioctl(0, TCGETA, x))
+#define STTY(x) (ioctl(0, TCSETA, x)) /* TCSETAF? TCSETAW? */
+
+#else /* V7 */
+
+#include <sgtty.h>
+#define termstruct sgttyb
+#define kill_sym sg_kill
+#define erase_sym sg_erase
+#define EXTABS XTABS
+#define tabflgs sg_flags
+#define echoflgs sg_flags
+#define cbrkflgs sg_flags
+#define CBRKMASK CBREAK
+#define CBRKON /* empty */
+#define OSPEED(x) (x).sg_ospeed
+#define GTTY(x) (gtty(0, x))
+#define STTY(x) (stty(0, x))
+
+#endif USG
+
+extern short ospeed;
+static char erase_char, kill_char;
+static boolean settty_needed = FALSE;
+struct termstruct inittyb, curttyb;
+
+/*
+ * Get initial state of terminal, set ospeed (for termcap routines)
+ * and switch off tab expansion if necessary.
+ * Called by startup() in termcap.c and after returning from ! or ^Z
+ */
+gettty(){
+ if(GTTY(&inittyb) < 0)
+ perror("Hack (gettty)");
+ curttyb = inittyb;
+ ospeed = OSPEED(inittyb);
+ erase_char = inittyb.erase_sym;
+ kill_char = inittyb.kill_sym;
+ getioctls();
+
+ /* do not expand tabs - they might be needed inside a cm sequence */
+ if(curttyb.tabflgs & EXTABS) {
+ curttyb.tabflgs &= ~EXTABS;
+ setctty();
+ }
+ settty_needed = TRUE;
+}
+
+/* reset terminal to original state */
+settty(s) char *s; {
+ clear_screen();
+ end_screen();
+ if(s) printf(s);
+ (void) fflush(stdout);
+ if(STTY(&inittyb) < 0)
+ perror("Hack (settty)");
+ flags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF;
+ flags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF;
+ setioctls();
+}
+
+setctty(){
+ if(STTY(&curttyb) < 0)
+ perror("Hack (setctty)");
+}
+
+
+setftty(){
+register int ef = 0; /* desired value of flags & ECHO */
+register int cf = CBRKON(CBRKMASK); /* desired value of flags & CBREAK */
+register int change = 0;
+ flags.cbreak = ON;
+ flags.echo = OFF;
+ /* Should use (ECHO|CRMOD) here instead of ECHO */
+ if((curttyb.echoflgs & ECHO) != ef){
+ curttyb.echoflgs &= ~ECHO;
+/* curttyb.echoflgs |= ef; */
+ change++;
+ }
+ if((curttyb.cbrkflgs & CBRKMASK) != cf){
+ curttyb.cbrkflgs &= ~CBRKMASK;
+ curttyb.cbrkflgs |= cf;
+#ifdef USG
+ /* be satisfied with one character; no timeout */
+ curttyb.c_cc[VMIN] = 1; /* was VEOF */
+ curttyb.c_cc[VTIME] = 0; /* was VEOL */
+#endif USG
+ change++;
+ }
+ if(change){
+ setctty();
+ }
+ start_screen();
+}
+
+
+/* fatal error */
+/*VARARGS1*/
+error(s,x,y) char *s; {
+ if(settty_needed)
+ settty((char *) 0);
+ printf(s,x,y);
+ putchar('\n');
+ exit(1);
+}
+
+/*
+ * Read a line closed with '\n' into the array char bufp[BUFSZ].
+ * (The '\n' is not stored. The string is closed with a '\0'.)
+ * Reading can be interrupted by an escape ('\033') - now the
+ * resulting string is "\033".
+ */
+getlin(bufp)
+register char *bufp;
+{
+ register char *obufp = bufp;
+ register int c;
+
+ flags.toplin = 2; /* nonempty, no --More-- required */
+ for(;;) {
+ (void) fflush(stdout);
+ if((c = getchar()) == EOF) {
+ *bufp = 0;
+ return;
+ }
+ if(c == '\033') {
+ *obufp = c;
+ obufp[1] = 0;
+ return;
+ }
+ if(c == erase_char || c == '\b') {
+ if(bufp != obufp) {
+ bufp--;
+ putstr("\b \b"); /* putsym converts \b */
+ } else bell();
+ } else if(c == '\n') {
+ *bufp = 0;
+ return;
+ } else if(' ' <= c && c < '\177') {
+ /* avoid isprint() - some people don't have it
+ ' ' is not always a printing char */
+ *bufp = c;
+ bufp[1] = 0;
+ putstr(bufp);
+ if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
+ bufp++;
+ } else if(c == kill_char || c == '\177') { /* Robert Viduya */
+ /* this test last - @ might be the kill_char */
+ while(bufp != obufp) {
+ bufp--;
+ putstr("\b \b");
+ }
+ } else
+ bell();
+ }
+}
+
+getret() {
+ cgetret("");
+}
+
+cgetret(s)
+register char *s;
+{
+ putsym('\n');
+ if(flags.standout)
+ standoutbeg();
+ putstr("Hit ");
+ putstr(flags.cbreak ? "space" : "return");
+ putstr(" to continue: ");
+ if(flags.standout)
+ standoutend();
+ xwaitforspace(s);
+}
+
+char morc; /* tell the outside world what char he used */
+
+xwaitforspace(s)
+register char *s; /* chars allowed besides space or return */
+{
+register int c;
+
+ morc = 0;
+
+ while((c = readchar()) != '\n') {
+ if(flags.cbreak) {
+ if(c == ' ') break;
+ if(s && index(s,c)) {
+ morc = c;
+ break;
+ }
+ bell();
+ }
+ }
+}
+
+char *
+parse()
+{
+ static char inputline[COLNO];
+ register foo;
+
+ flags.move = 1;
+ if(!Invisible) curs_on_u(); else home();
+ while((foo = readchar()) >= '0' && foo <= '9')
+ multi = 10*multi+foo-'0';
+ if(multi) {
+ multi--;
+ save_cm = inputline;
+ }
+ inputline[0] = foo;
+ inputline[1] = 0;
+ if(foo == 'f' || foo == 'F'){
+ inputline[1] = getchar();
+#ifdef QUEST
+ if(inputline[1] == foo) inputline[2] = getchar(); else
+#endif QUEST
+ inputline[2] = 0;
+ }
+ if(foo == 'm' || foo == 'M'){
+ inputline[1] = getchar();
+ inputline[2] = 0;
+ }
+ clrlin();
+ return(inputline);
+}
+
+char
+readchar() {
+ register int sym;
+
+ (void) fflush(stdout);
+ if((sym = getchar()) == EOF)
+#ifdef NR_OF_EOFS
+ { /*
+ * Some SYSV systems seem to return EOFs for various reasons
+ * (?like when one hits break or for interrupted systemcalls?),
+ * and we must see several before we quit.
+ */
+ register int cnt = NR_OF_EOFS;
+ while (cnt--) {
+ clearerr(stdin); /* omit if clearerr is undefined */
+ if((sym = getchar()) != EOF) goto noteof;
+ }
+ end_of_input();
+ noteof: ;
+ }
+#else
+ end_of_input();
+#endif NR_OF_EOFS
+ if(flags.toplin == 1)
+ flags.toplin = 2;
+ return((char) sym);
+}
+
+end_of_input()
+{
+ settty("End of input?\n");
+ clearlocks();
+ exit(0);
+}
diff --git a/hack/hack.u_init.c b/hack/hack.u_init.c
new file mode 100644
index 00000000..bc06fa5e
--- /dev/null
+++ b/hack/hack.u_init.c
@@ -0,0 +1,357 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.u_init.c - version 1.0.3 */
+
+#include "hack.h"
+#include <stdio.h>
+#include <signal.h>
+#define Strcpy (void) strcpy
+#define Strcat (void) strcat
+#define UNDEF_TYP 0
+#define UNDEF_SPE '\177'
+extern struct obj *addinv();
+extern char *eos();
+extern char plname[];
+
+struct you zerou;
+char pl_character[PL_CSIZ];
+char *(roles[]) = { /* must all have distinct first letter */
+ /* roles[4] may be changed to -man */
+ "Tourist", "Speleologist", "Fighter", "Knight",
+ "Cave-man", "Wizard"
+};
+#define NR_OF_ROLES SIZE(roles)
+char rolesyms[NR_OF_ROLES + 1]; /* filled by u_init() */
+
+struct trobj {
+ uchar trotyp;
+ schar trspe;
+ char trolet;
+ Bitfield(trquan,6);
+ Bitfield(trknown,1);
+};
+
+#ifdef WIZARD
+struct trobj Extra_objs[] = {
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 }
+};
+#endif WIZARD
+
+struct trobj Cave_man[] = {
+ { MACE, 1, WEAPON_SYM, 1, 1 },
+ { BOW, 1, WEAPON_SYM, 1, 1 },
+ { ARROW, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */
+ { LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
+ { 0, 0, 0, 0, 0}
+};
+
+struct trobj Fighter[] = {
+ { TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 },
+ { RING_MAIL, 0, ARMOR_SYM, 1, 1 },
+ { 0, 0, 0, 0, 0 }
+};
+
+struct trobj Knight[] = {
+ { LONG_SWORD, 0, WEAPON_SYM, 1, 1 },
+ { SPEAR, 2, WEAPON_SYM, 1, 1 },
+ { RING_MAIL, 1, ARMOR_SYM, 1, 1 },
+ { HELMET, 0, ARMOR_SYM, 1, 1 },
+ { SHIELD, 0, ARMOR_SYM, 1, 1 },
+ { PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1 },
+ { 0, 0, 0, 0, 0 }
+};
+
+struct trobj Speleologist[] = {
+ { STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
+ { UNDEF_TYP, 0, POTION_SYM, 2, 0 },
+ { FOOD_RATION, 0, FOOD_SYM, 3, 1 },
+ { PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0 },
+ { ICE_BOX, 0, TOOL_SYM, 1, 0 },
+ { 0, 0, 0, 0, 0}
+};
+
+struct trobj Tinopener[] = {
+ { CAN_OPENER, 0, TOOL_SYM, 1, 1 },
+ { 0, 0, 0, 0, 0 }
+};
+
+struct trobj Tourist[] = {
+ { UNDEF_TYP, 0, FOOD_SYM, 10, 1 },
+ { POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 },
+ { EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 },
+ { DART, 2, WEAPON_SYM, 25, 1 }, /* quan is variable */
+ { 0, 0, 0, 0, 0 }
+};
+
+struct trobj Wizard[] = {
+ { ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1 },
+ { UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 },
+ { UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 },
+ { UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 },
+ { UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 },
+ { 0, 0, 0, 0, 0 }
+};
+
+u_init(){
+register int i;
+char exper = 'y', pc;
+extern char readchar();
+ if(flags.female) /* should have been set in HACKOPTIONS */
+ roles[4] = "Cave-woman";
+ for(i = 0; i < NR_OF_ROLES; i++)
+ rolesyms[i] = roles[i][0];
+ rolesyms[i] = 0;
+
+ if(pc = pl_character[0]) {
+ if('a' <= pc && pc <= 'z') pc += 'A'-'a';
+ if((i = role_index(pc)) >= 0)
+ goto got_suffix; /* implies experienced */
+ printf("\nUnknown role: %c\n", pc);
+ pl_character[0] = pc = 0;
+ }
+
+ printf("\nAre you an experienced player? [ny] ");
+
+ while(!index("ynYN \n\004", (exper = readchar())))
+ bell();
+ if(exper == '\004') /* Give him an opportunity to get out */
+ end_of_input();
+ printf("%c\n", exper); /* echo */
+ if(index("Nn \n", exper)) {
+ exper = 0;
+ goto beginner;
+ }
+
+ printf("\nTell me what kind of character you are:\n");
+ printf("Are you");
+ for(i = 0; i < NR_OF_ROLES; i++) {
+ printf(" a %s", roles[i]);
+ if(i == 2) /* %% */
+ printf(",\n\t");
+ else if(i < NR_OF_ROLES - 2)
+ printf(",");
+ else if(i == NR_OF_ROLES - 2)
+ printf(" or");
+ }
+ printf("? [%s] ", rolesyms);
+
+ while(pc = readchar()) {
+ if('a' <= pc && pc <= 'z') pc += 'A'-'a';
+ if((i = role_index(pc)) >= 0) {
+ printf("%c\n", pc); /* echo */
+ (void) fflush(stdout); /* should be seen */
+ break;
+ }
+ if(pc == '\n')
+ break;
+ if(pc == '\004') /* Give him the opportunity to get out */
+ end_of_input();
+ bell();
+ }
+ if(pc == '\n')
+ pc = 0;
+
+beginner:
+ if(!pc) {
+ printf("\nI'll choose a character for you.\n");
+ i = rn2(NR_OF_ROLES);
+ pc = rolesyms[i];
+ printf("This game you will be a%s %s.\n",
+ exper ? "n experienced" : "",
+ roles[i]);
+ getret();
+ /* give him some feedback in case mklev takes much time */
+ (void) putchar('\n');
+ (void) fflush(stdout);
+ }
+ if(exper) {
+ roles[i][0] = pc;
+ }
+
+got_suffix:
+
+ (void) strncpy(pl_character, roles[i], PL_CSIZ-1);
+ pl_character[PL_CSIZ-1] = 0;
+ flags.beginner = 1;
+ u = zerou;
+ u.usym = '@';
+ u.ulevel = 1;
+ init_uhunger();
+#ifdef QUEST
+ u.uhorizon = 6;
+#endif QUEST
+ uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain =
+ uleft = uright = 0;
+
+ switch(pc) {
+ case 'c':
+ case 'C':
+ Cave_man[2].trquan = 12 + rnd(9)*rnd(9);
+ u.uhp = u.uhpmax = 16;
+ u.ustr = u.ustrmax = 18;
+ ini_inv(Cave_man);
+ break;
+ case 't':
+ case 'T':
+ Tourist[3].trquan = 20 + rnd(20);
+ u.ugold = u.ugold0 = rnd(1000);
+ u.uhp = u.uhpmax = 10;
+ u.ustr = u.ustrmax = 8;
+ ini_inv(Tourist);
+ if(!rn2(25)) ini_inv(Tinopener);
+ break;
+ case 'w':
+ case 'W':
+ for(i=1; i<=4; i++) if(!rn2(5))
+ Wizard[i].trquan += rn2(3) - 1;
+ u.uhp = u.uhpmax = 15;
+ u.ustr = u.ustrmax = 16;
+ ini_inv(Wizard);
+ break;
+ case 's':
+ case 'S':
+ Fast = INTRINSIC;
+ Stealth = INTRINSIC;
+ u.uhp = u.uhpmax = 12;
+ u.ustr = u.ustrmax = 10;
+ ini_inv(Speleologist);
+ if(!rn2(10)) ini_inv(Tinopener);
+ break;
+ case 'k':
+ case 'K':
+ u.uhp = u.uhpmax = 12;
+ u.ustr = u.ustrmax = 10;
+ ini_inv(Knight);
+ break;
+ case 'f':
+ case 'F':
+ u.uhp = u.uhpmax = 14;
+ u.ustr = u.ustrmax = 17;
+ ini_inv(Fighter);
+ break;
+ default: /* impossible */
+ u.uhp = u.uhpmax = 12;
+ u.ustr = u.ustrmax = 16;
+ }
+ find_ac();
+ if(!rn2(20)) {
+ register int d = rn2(7) - 2; /* biased variation */
+ u.ustr += d;
+ u.ustrmax += d;
+ }
+
+#ifdef WIZARD
+ if(wizard) wiz_inv();
+#endif WIZARD
+
+ /* make sure he can carry all he has - especially for T's */
+ while(inv_weight() > 0 && u.ustr < 118)
+ u.ustr++, u.ustrmax++;
+}
+
+ini_inv(trop) register struct trobj *trop; {
+register struct obj *obj;
+extern struct obj *mkobj();
+ while(trop->trolet) {
+ obj = mkobj(trop->trolet);
+ obj->known = trop->trknown;
+ /* not obj->dknown = 1; - let him look at it at least once */
+ obj->cursed = 0;
+ if(obj->olet == WEAPON_SYM){
+ obj->quan = trop->trquan;
+ trop->trquan = 1;
+ }
+ if(trop->trspe != UNDEF_SPE)
+ obj->spe = trop->trspe;
+ if(trop->trotyp != UNDEF_TYP)
+ obj->otyp = trop->trotyp;
+ else
+ if(obj->otyp == WAN_WISHING) /* gitpyr!robert */
+ obj->otyp = WAN_DEATH;
+ obj->owt = weight(obj); /* defined after setting otyp+quan */
+ obj = addinv(obj);
+ if(obj->olet == ARMOR_SYM){
+ switch(obj->otyp){
+ case SHIELD:
+ if(!uarms) setworn(obj, W_ARMS);
+ break;
+ case HELMET:
+ if(!uarmh) setworn(obj, W_ARMH);
+ break;
+ case PAIR_OF_GLOVES:
+ if(!uarmg) setworn(obj, W_ARMG);
+ break;
+ case ELVEN_CLOAK:
+ if(!uarm2)
+ setworn(obj, W_ARM);
+ break;
+ default:
+ if(!uarm) setworn(obj, W_ARM);
+ }
+ }
+ if(obj->olet == WEAPON_SYM)
+ if(!uwep) setuwep(obj);
+#ifndef PYRAMID_BUG
+ if(--trop->trquan) continue; /* make a similar object */
+#else
+ if(trop->trquan) { /* check if zero first */
+ --trop->trquan;
+ if(trop->trquan)
+ continue; /* make a similar object */
+ }
+#endif PYRAMID_BUG
+ trop++;
+ }
+}
+
+#ifdef WIZARD
+wiz_inv(){
+register struct trobj *trop = &Extra_objs[0];
+extern char *getenv();
+register char *ep = getenv("INVENT");
+register int type;
+ while(ep && *ep) {
+ type = atoi(ep);
+ ep = index(ep, ',');
+ if(ep) while(*ep == ',' || *ep == ' ') ep++;
+ if(type <= 0 || type > NROFOBJECTS) continue;
+ trop->trotyp = type;
+ trop->trolet = objects[type].oc_olet;
+ trop->trspe = 4;
+ trop->trknown = 1;
+ trop->trquan = 1;
+ ini_inv(trop);
+ }
+ /* give him a wand of wishing by default */
+ trop->trotyp = WAN_WISHING;
+ trop->trolet = WAND_SYM;
+ trop->trspe = 20;
+ trop->trknown = 1;
+ trop->trquan = 1;
+ ini_inv(trop);
+}
+#endif WIZARD
+
+plnamesuffix() {
+register char *p;
+ if(p = rindex(plname, '-')) {
+ *p = 0;
+ pl_character[0] = p[1];
+ pl_character[1] = 0;
+ if(!plname[0]) {
+ askname();
+ plnamesuffix();
+ }
+ }
+}
+
+role_index(pc)
+char pc;
+{ /* must be called only from u_init() */
+ /* so that rolesyms[] is defined */
+ register char *cp;
+
+ if(cp = index(rolesyms, pc))
+ return(cp - rolesyms);
+ return(-1);
+}
diff --git a/hack/hack.unix.c b/hack/hack.unix.c
new file mode 100644
index 00000000..03b294db
--- /dev/null
+++ b/hack/hack.unix.c
@@ -0,0 +1,430 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.unix.c - version 1.0.3 */
+
+/* This file collects some Unix dependencies; hack.pager.c contains some more */
+
+/*
+ * The time is used for:
+ * - seed for random()
+ * - year on tombstone and yymmdd in record file
+ * - phase of the moon (various monsters react to NEW_MOON or FULL_MOON)
+ * - night and midnight (the undead are dangerous at midnight)
+ * - determination of what files are "very old"
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "hack.h" /* mainly for index() which depends on BSD */
+
+#include <sys/types.h> /* for time_t and stat */
+#include <sys/stat.h>
+#ifdef BSD
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif BSD
+
+extern char *getenv();
+extern time_t time();
+
+setrandom()
+{
+ (void) srandom((int) time ((time_t *) 0));
+}
+
+struct tm *
+getlt()
+{
+ time_t date;
+ struct tm *localtime();
+
+ (void) time(&date);
+ return(localtime(&date));
+}
+
+getyear()
+{
+ return(1900 + getlt()->tm_year);
+}
+
+char *
+getdate()
+{
+ static char datestr[7];
+ register struct tm *lt = getlt();
+
+ (void) sprintf(datestr, "%2d%2d%2d",
+ lt->tm_year, lt->tm_mon + 1, lt->tm_mday);
+ if(datestr[2] == ' ') datestr[2] = '0';
+ if(datestr[4] == ' ') datestr[4] = '0';
+ return(datestr);
+}
+
+phase_of_the_moon() /* 0-7, with 0: new, 4: full */
+{ /* moon period: 29.5306 days */
+ /* year: 365.2422 days */
+ register struct tm *lt = getlt();
+ register int epact, diy, golden;
+
+ diy = lt->tm_yday;
+ golden = (lt->tm_year % 19) + 1;
+ epact = (11 * golden + 18) % 30;
+ if ((epact == 25 && golden > 11) || epact == 24)
+ epact++;
+
+ return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 );
+}
+
+night()
+{
+ register int hour = getlt()->tm_hour;
+
+ return(hour < 6 || hour > 21);
+}
+
+midnight()
+{
+ return(getlt()->tm_hour == 0);
+}
+
+struct stat buf, hbuf;
+
+gethdate(name) char *name; {
+/* old version - for people short of space */
+/*
+/* register char *np;
+/* if(stat(name, &hbuf))
+/* error("Cannot get status of %s.",
+/* (np = rindex(name, '/')) ? np+1 : name);
+/*
+/* version using PATH from: seismo!gregc@ucsf-cgl.ARPA (Greg Couch) */
+
+
+/*
+ * The problem with #include <sys/param.h> is that this include file
+ * does not exist on all systems, and moreover, that it sometimes includes
+ * <sys/types.h> again, so that the compiler sees these typedefs twice.
+ */
+#define MAXPATHLEN 1024
+
+register char *np, *path;
+char filename[MAXPATHLEN+1];
+ if (index(name, '/') != NULL || (path = getenv("PATH")) == NULL)
+ path = "";
+
+ for (;;) {
+ if ((np = index(path, ':')) == NULL)
+ np = path + strlen(path); /* point to end str */
+ if (np - path <= 1) /* %% */
+ (void) strcpy(filename, name);
+ else {
+ (void) strncpy(filename, path, np - path);
+ filename[np - path] = '/';
+ (void) strcpy(filename + (np - path) + 1, name);
+ }
+ if (stat(filename, &hbuf) == 0)
+ return;
+ if (*np == '\0')
+ break;
+ path = np + 1;
+ }
+ error("Cannot get status of %s.",
+ (np = rindex(name, '/')) ? np+1 : name);
+}
+
+uptodate(fd) {
+ if(fstat(fd, &buf)) {
+ pline("Cannot get status of saved level? ");
+ return(0);
+ }
+ if(buf.st_mtime < hbuf.st_mtime) {
+ pline("Saved level is out of date. ");
+ return(0);
+ }
+ return(1);
+}
+
+/* see whether we should throw away this xlock file */
+veryold(fd) {
+ register int i;
+ time_t date;
+
+ if(fstat(fd, &buf)) return(0); /* cannot get status */
+ if(buf.st_size != sizeof(int)) return(0); /* not an xlock file */
+ (void) time(&date);
+ if(date - buf.st_mtime < 3L*24L*60L*60L) { /* recent */
+ extern int errno;
+ int lockedpid; /* should be the same size as hackpid */
+
+ if(read(fd, (char *)&lockedpid, sizeof(lockedpid)) !=
+ sizeof(lockedpid))
+ /* strange ... */
+ return(0);
+
+ /* From: Rick Adams <seismo!rick>
+ /* This will work on 4.1cbsd, 4.2bsd and system 3? & 5.
+ /* It will do nothing on V7 or 4.1bsd. */
+ if(!(kill(lockedpid, 0) == -1 && errno == ESRCH))
+ return(0);
+ }
+ (void) close(fd);
+ for(i = 1; i <= MAXLEVEL; i++) { /* try to remove all */
+ glo(i);
+ (void) unlink(lock);
+ }
+ glo(0);
+ if(unlink(lock)) return(0); /* cannot remove it */
+ return(1); /* success! */
+}
+
+getlock()
+{
+ extern int errno, hackpid, locknum;
+ register int i = 0, fd;
+
+ (void) fflush(stdout);
+
+ /* we ignore QUIT and INT at this point */
+ if (link(HLOCK, LLOCK) == -1) {
+ register int errnosv = errno;
+
+ perror(HLOCK);
+ printf("Cannot link %s to %s\n", LLOCK, HLOCK);
+ switch(errnosv) {
+ case ENOENT:
+ printf("Perhaps there is no (empty) file %s ?\n", HLOCK);
+ break;
+ case EACCES:
+ printf("It seems you don't have write permission here.\n");
+ break;
+ case EEXIST:
+ printf("(Try again or rm %s.)\n", LLOCK);
+ break;
+ default:
+ printf("I don't know what is wrong.");
+ }
+ getret();
+ error("");
+ /*NOTREACHED*/
+ }
+
+ regularize(lock);
+ glo(0);
+ if(locknum > 25) locknum = 25;
+
+ do {
+ if(locknum) lock[0] = 'a' + i++;
+
+ if((fd = open(lock, 0)) == -1) {
+ if(errno == ENOENT) goto gotlock; /* no such file */
+ perror(lock);
+ (void) unlink(LLOCK);
+ error("Cannot open %s", lock);
+ }
+
+ if(veryold(fd)) /* if true, this closes fd and unlinks lock */
+ goto gotlock;
+ (void) close(fd);
+ } while(i < locknum);
+
+ (void) unlink(LLOCK);
+ error(locknum ? "Too many hacks running now."
+ : "There is a game in progress under your name.");
+gotlock:
+ fd = creat(lock, FMASK);
+ if(unlink(LLOCK) == -1)
+ error("Cannot unlink %s.", LLOCK);
+ if(fd == -1) {
+ error("cannot creat lock file.");
+ } else {
+ if(write(fd, (char *) &hackpid, sizeof(hackpid))
+ != sizeof(hackpid)){
+ error("cannot write lock");
+ }
+ if(close(fd) == -1) {
+ error("cannot close lock");
+ }
+ }
+}
+
+#ifdef MAIL
+
+/*
+ * Notify user when new mail has arrived. [Idea from Merlyn Leroy, but
+ * I don't know the details of his implementation.]
+ * { Later note: he disliked my calling a general mailreader and felt that
+ * hack should do the paging itself. But when I get mail, I want to put it
+ * in some folder, reply, etc. - it would be unreasonable to put all these
+ * functions in hack. }
+ * The mail daemon '2' is at present not a real monster, but only a visual
+ * effect. Thus, makemon() is superfluous. This might become otherwise,
+ * however. The motion of '2' is less restrained than usual: diagonal moves
+ * from a DOOR are possible. He might also use SDOOR's. Also, '2' is visible
+ * in a ROOM, even when you are Blind.
+ * Its path should be longer when you are Telepat-hic and Blind.
+ *
+ * Interesting side effects:
+ * - You can get rich by sending yourself a lot of mail and selling
+ * it to the shopkeeper. Unfortunately mail isn't very valuable.
+ * - You might die in case '2' comes along at a critical moment during
+ * a fight and delivers a scroll the weight of which causes you to
+ * collapse.
+ *
+ * Possible extensions:
+ * - Open the file MAIL and do fstat instead of stat for efficiency.
+ * (But sh uses stat, so this cannot be too bad.)
+ * - Examine the mail and produce a scroll of mail called "From somebody".
+ * - Invoke MAILREADER in such a way that only this single letter is read.
+ *
+ * - Make him lose his mail when a Nymph steals the letter.
+ * - Do something to the text when the scroll is enchanted or cancelled.
+ */
+#include "def.mkroom.h"
+static struct stat omstat,nmstat;
+static char *mailbox;
+static long laststattime;
+
+getmailstatus() {
+ if(!(mailbox = getenv("MAIL")))
+ return;
+ if(stat(mailbox, &omstat)){
+#ifdef PERMANENT_MAILBOX
+ pline("Cannot get status of MAIL=%s .", mailbox);
+ mailbox = 0;
+#else
+ omstat.st_mtime = 0;
+#endif PERMANENT_MAILBOX
+ }
+}
+
+ckmailstatus() {
+ if(!mailbox
+#ifdef MAILCKFREQ
+ || moves < laststattime + MAILCKFREQ
+#endif MAILCKFREQ
+ )
+ return;
+ laststattime = moves;
+ if(stat(mailbox, &nmstat)){
+#ifdef PERMANENT_MAILBOX
+ pline("Cannot get status of MAIL=%s anymore.", mailbox);
+ mailbox = 0;
+#else
+ nmstat.st_mtime = 0;
+#endif PERMANENT_MAILBOX
+ } else if(nmstat.st_mtime > omstat.st_mtime) {
+ if(nmstat.st_size)
+ newmail();
+ getmailstatus(); /* might be too late ... */
+ }
+}
+
+newmail() {
+ /* produce a scroll of mail */
+ register struct obj *obj;
+ register struct monst *md;
+ extern char plname[];
+ extern struct obj *mksobj(), *addinv();
+ extern struct monst *makemon();
+ extern struct permonst pm_mail_daemon;
+
+ obj = mksobj(SCR_MAIL);
+ if(md = makemon(&pm_mail_daemon, u.ux, u.uy)) /* always succeeds */
+ mdrush(md,0);
+
+ pline("\"Hello, %s! I have some mail for you.\"", plname);
+ if(md) {
+ if(dist(md->mx,md->my) > 2)
+ pline("\"Catch!\"");
+ more();
+
+ /* let him disappear again */
+ mdrush(md,1);
+ mondead(md);
+ }
+
+ obj = addinv(obj);
+ (void) identify(obj); /* set known and do prinv() */
+}
+
+/* make md run through the cave */
+mdrush(md,away)
+register struct monst *md;
+boolean away;
+{
+ register int uroom = inroom(u.ux, u.uy);
+ if(uroom >= 0) {
+ register int tmp = rooms[uroom].fdoor;
+ register int cnt = rooms[uroom].doorct;
+ register int fx = u.ux, fy = u.uy;
+ while(cnt--) {
+ if(dist(fx,fy) < dist(doors[tmp].x, doors[tmp].y)){
+ fx = doors[tmp].x;
+ fy = doors[tmp].y;
+ }
+ tmp++;
+ }
+ tmp_at(-1, md->data->mlet); /* open call */
+ if(away) { /* interchange origin and destination */
+ unpmon(md);
+ tmp = fx; fx = md->mx; md->mx = tmp;
+ tmp = fy; fy = md->my; md->my = tmp;
+ }
+ while(fx != md->mx || fy != md->my) {
+ register int dx,dy,nfx = fx,nfy = fy,d1,d2;
+
+ tmp_at(fx,fy);
+ d1 = DIST(fx,fy,md->mx,md->my);
+ for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
+ if(dx || dy) {
+ d2 = DIST(fx+dx,fy+dy,md->mx,md->my);
+ if(d2 < d1) {
+ d1 = d2;
+ nfx = fx+dx;
+ nfy = fy+dy;
+ }
+ }
+ if(nfx != fx || nfy != fy) {
+ fx = nfx;
+ fy = nfy;
+ } else {
+ if(!away) {
+ md->mx = fx;
+ md->my = fy;
+ }
+ break;
+ }
+ }
+ tmp_at(-1,-1); /* close call */
+ }
+ if(!away)
+ pmon(md);
+}
+
+readmail() {
+#ifdef DEF_MAILREADER /* This implies that UNIX is defined */
+ register char *mr = 0;
+ more();
+ if(!(mr = getenv("MAILREADER")))
+ mr = DEF_MAILREADER;
+ if(child(1)){
+ execl(mr, mr, (char *) 0);
+ exit(1);
+ }
+#else DEF_MAILREADER
+ (void) page_file(mailbox, FALSE);
+#endif DEF_MAILREADER
+ /* get new stat; not entirely correct: there is a small time
+ window where we do not see new mail */
+ getmailstatus();
+}
+#endif MAIL
+
+regularize(s) /* normalize file name - we don't like ..'s or /'s */
+register char *s;
+{
+ register char *lp;
+
+ while((lp = index(s, '.')) || (lp = index(s, '/')))
+ *lp = '_';
+}
diff --git a/hack/hack.vault.c b/hack/hack.vault.c
new file mode 100644
index 00000000..a82c9f9a
--- /dev/null
+++ b/hack/hack.vault.c
@@ -0,0 +1,259 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.vault.c - version 1.0.2 */
+
+#include "hack.h"
+#ifdef QUEST
+setgd(/* mtmp */) /* struct monst *mtmp; */ {}
+gd_move() { return(2); }
+gddead(mtmp) struct monst *mtmp; {}
+replgd(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {}
+invault(){}
+
+#else
+
+
+#include "def.mkroom.h"
+extern struct monst *makemon();
+#define FCSIZ (ROWNO+COLNO)
+struct fakecorridor {
+ xchar fx,fy,ftyp;
+};
+
+struct egd {
+ int fcbeg, fcend; /* fcend: first unused pos */
+ xchar gdx, gdy; /* goal of guard's walk */
+ unsigned gddone:1;
+ struct fakecorridor fakecorr[FCSIZ];
+};
+
+static struct permonst pm_guard =
+ { "guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd) };
+
+static struct monst *guard;
+static int gdlevel;
+#define EGD ((struct egd *)(&(guard->mextra[0])))
+
+static
+restfakecorr()
+{
+ register fcx,fcy,fcbeg;
+ register struct rm *crm;
+
+ while((fcbeg = EGD->fcbeg) < EGD->fcend) {
+ fcx = EGD->fakecorr[fcbeg].fx;
+ fcy = EGD->fakecorr[fcbeg].fy;
+ if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
+ m_at(fcx,fcy))
+ return;
+ crm = &levl[fcx][fcy];
+ crm->typ = EGD->fakecorr[fcbeg].ftyp;
+ if(!crm->typ) crm->seen = 0;
+ newsym(fcx,fcy);
+ EGD->fcbeg++;
+ }
+ /* it seems he left the corridor - let the guard disappear */
+ mondead(guard);
+ guard = 0;
+}
+
+static
+goldincorridor()
+{
+ register int fci;
+
+ for(fci = EGD->fcbeg; fci < EGD->fcend; fci++)
+ if(g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
+ return(1);
+ return(0);
+}
+
+setgd(){
+register struct monst *mtmp;
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
+ guard = mtmp;
+ gdlevel = dlevel;
+ return;
+ }
+ guard = 0;
+}
+
+invault(){
+register tmp = inroom(u.ux, u.uy);
+ if(tmp < 0 || rooms[tmp].rtype != VAULT) {
+ u.uinvault = 0;
+ return;
+ }
+ if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
+ char buf[BUFSZ];
+ register x,y,dd,gx,gy;
+
+ /* first find the goal for the guard */
+ for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
+ for(y = u.uy-dd; y <= u.uy+dd; y++) {
+ if(y < 0 || y > ROWNO-1) continue;
+ for(x = u.ux-dd; x <= u.ux+dd; x++) {
+ if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
+ x = u.ux+dd;
+ if(x < 0 || x > COLNO-1) continue;
+ if(levl[x][y].typ == CORR) goto fnd;
+ }
+ }
+ }
+ impossible("Not a single corridor on this level??");
+ tele();
+ return;
+fnd:
+ gx = x; gy = y;
+
+ /* next find a good place for a door in the wall */
+ x = u.ux; y = u.uy;
+ while(levl[x][y].typ == ROOM) {
+ register int dx,dy;
+
+ dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
+ dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
+ if(abs(gx-x) >= abs(gy-y))
+ x += dx;
+ else
+ y += dy;
+ }
+
+ /* make something interesting happen */
+ if(!(guard = makemon(&pm_guard,x,y))) return;
+ guard->isgd = guard->mpeaceful = 1;
+ EGD->gddone = 0;
+ gdlevel = dlevel;
+ if(!cansee(guard->mx, guard->my)) {
+ mondead(guard);
+ guard = 0;
+ return;
+ }
+
+ pline("Suddenly one of the Vault's guards enters!");
+ pmon(guard);
+ do {
+ pline("\"Hello stranger, who are you?\" - ");
+ getlin(buf);
+ } while (!letter(buf[0]));
+
+ if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
+ pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
+ mondead(guard);
+ guard = 0;
+ return;
+ }
+ clrlin();
+ pline("\"I don't know you.\"");
+ if(!u.ugold)
+ pline("\"Please follow me.\"");
+ else {
+ pline("\"Most likely all that gold was stolen from this vault.\"");
+ pline("\"Please drop your gold (say d$ ) and follow me.\"");
+ }
+ EGD->gdx = gx;
+ EGD->gdy = gy;
+ EGD->fcbeg = 0;
+ EGD->fakecorr[0].fx = x;
+ EGD->fakecorr[0].fy = y;
+ EGD->fakecorr[0].ftyp = levl[x][y].typ;
+ levl[x][y].typ = DOOR;
+ EGD->fcend = 1;
+ }
+}
+
+gd_move(){
+register int x,y,dx,dy,gx,gy,nx,ny,typ;
+register struct fakecorridor *fcp;
+register struct rm *crm;
+ if(!guard || gdlevel != dlevel){
+ impossible("Where is the guard?");
+ return(2); /* died */
+ }
+ if(u.ugold || goldincorridor())
+ return(0); /* didnt move */
+ if(dist(guard->mx,guard->my) > 1 || EGD->gddone) {
+ restfakecorr();
+ return(0); /* didnt move */
+ }
+ x = guard->mx;
+ y = guard->my;
+ /* look around (hor & vert only) for accessible places */
+ for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
+ if(nx == x || ny == y) if(nx != x || ny != y)
+ if(isok(nx,ny))
+ if(!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
+ register int i;
+ for(i = EGD->fcbeg; i < EGD->fcend; i++)
+ if(EGD->fakecorr[i].fx == nx &&
+ EGD->fakecorr[i].fy == ny)
+ goto nextnxy;
+ if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
+ goto nextnxy;
+ /* seems we found a good place to leave him alone */
+ EGD->gddone = 1;
+ if(ACCESSIBLE(typ)) goto newpos;
+ crm->typ = (typ == SCORR) ? CORR : DOOR;
+ goto proceed;
+ }
+ nextnxy: ;
+ }
+ nx = x;
+ ny = y;
+ gx = EGD->gdx;
+ gy = EGD->gdy;
+ dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
+ dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
+ if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
+
+ while((typ = (crm = &levl[nx][ny])->typ) != 0) {
+ /* in view of the above we must have IS_WALL(typ) or typ == POOL */
+ /* must be a wall here */
+ if(isok(nx+nx-x,ny+ny-y) && typ != POOL &&
+ ZAP_POS(levl[nx+nx-x][ny+ny-y].typ)){
+ crm->typ = DOOR;
+ goto proceed;
+ }
+ if(dy && nx != x) {
+ nx = x; ny = y+dy;
+ continue;
+ }
+ if(dx && ny != y) {
+ ny = y; nx = x+dx; dy = 0;
+ continue;
+ }
+ /* I don't like this, but ... */
+ crm->typ = DOOR;
+ goto proceed;
+ }
+ crm->typ = CORR;
+proceed:
+ if(cansee(nx,ny)) {
+ mnewsym(nx,ny);
+ prl(nx,ny);
+ }
+ fcp = &(EGD->fakecorr[EGD->fcend]);
+ if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
+ fcp->fx = nx;
+ fcp->fy = ny;
+ fcp->ftyp = typ;
+newpos:
+ if(EGD->gddone) nx = ny = 0;
+ guard->mx = nx;
+ guard->my = ny;
+ pmon(guard);
+ restfakecorr();
+ return(1);
+}
+
+gddead(){
+ guard = 0;
+}
+
+replgd(mtmp,mtmp2)
+register struct monst *mtmp, *mtmp2;
+{
+ if(mtmp == guard)
+ guard = mtmp2;
+}
+
+#endif QUEST
diff --git a/hack/hack.version.c b/hack/hack.version.c
new file mode 100644
index 00000000..7db39475
--- /dev/null
+++ b/hack/hack.version.c
@@ -0,0 +1,16 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.version.c - version 1.0.3 */
+/* $Header: /cvsroot/src/games/hack/hack.version.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $ */
+
+#include "date.h"
+
+doversion(){
+ pline("%s 1.0.3 - last edit %s.", (
+#ifdef QUEST
+ "Quest"
+#else
+ "Hack"
+#endif QUEST
+ ), datestring);
+ return(0);
+}
diff --git a/hack/hack.wield.c b/hack/hack.wield.c
new file mode 100644
index 00000000..d0609a1c
--- /dev/null
+++ b/hack/hack.wield.c
@@ -0,0 +1,99 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.wield.c - version 1.0.3 */
+
+#include "hack.h"
+extern struct obj zeroobj;
+
+setuwep(obj) register struct obj *obj; {
+ setworn(obj, W_WEP);
+}
+
+dowield()
+{
+ register struct obj *wep;
+ register int res = 0;
+
+ multi = 0;
+ if(!(wep = getobj("#-)", "wield"))) /* nothing */;
+ else if(uwep == wep)
+ pline("You are already wielding that!");
+ else if(uwep && uwep->cursed)
+ pline("The %s welded to your hand!",
+ aobjnam(uwep, "are"));
+ else if(wep == &zeroobj) {
+ if(uwep == 0){
+ pline("You are already empty handed.");
+ } else {
+ setuwep((struct obj *) 0);
+ res++;
+ pline("You are empty handed.");
+ }
+ } else if(uarms && wep->otyp == TWO_HANDED_SWORD)
+ pline("You cannot wield a two-handed sword and wear a shield.");
+ else if(wep->owornmask & (W_ARMOR | W_RING))
+ pline("You cannot wield that!");
+ else {
+ setuwep(wep);
+ res++;
+ if(uwep->cursed)
+ pline("The %s %s to your hand!",
+ aobjnam(uwep, "weld"),
+ (uwep->quan == 1) ? "itself" : "themselves"); /* a3 */
+ else prinv(uwep);
+ }
+ return(res);
+}
+
+corrode_weapon(){
+ if(!uwep || uwep->olet != WEAPON_SYM) return; /* %% */
+ if(uwep->rustfree)
+ pline("Your %s not affected.", aobjnam(uwep, "are"));
+ else {
+ pline("Your %s!", aobjnam(uwep, "corrode"));
+ uwep->spe--;
+ }
+}
+
+chwepon(otmp,amount)
+register struct obj *otmp;
+register amount;
+{
+register char *color = (amount < 0) ? "black" : "green";
+register char *time;
+ if(!uwep || uwep->olet != WEAPON_SYM) {
+ strange_feeling(otmp,
+ (amount > 0) ? "Your hands twitch."
+ : "Your hands itch.");
+ return(0);
+ }
+
+ if(uwep->otyp == WORM_TOOTH && amount > 0) {
+ uwep->otyp = CRYSKNIFE;
+ pline("Your weapon seems sharper now.");
+ uwep->cursed = 0;
+ return(1);
+ }
+
+ if(uwep->otyp == CRYSKNIFE && amount < 0) {
+ uwep->otyp = WORM_TOOTH;
+ pline("Your weapon looks duller now.");
+ return(1);
+ }
+
+ /* there is a (soft) upper limit to uwep->spe */
+ if(amount > 0 && uwep->spe > 5 && rn2(3)) {
+ pline("Your %s violently green for a while and then evaporate%s.",
+ aobjnam(uwep, "glow"), plur(uwep->quan));
+ while(uwep) /* let all of them disappear */
+ /* note: uwep->quan = 1 is nogood if unpaid */
+ useup(uwep);
+ return(1);
+ }
+ if(!rn2(6)) amount *= 2;
+ time = (amount*amount == 1) ? "moment" : "while";
+ pline("Your %s %s for a %s.",
+ aobjnam(uwep, "glow"), color, time);
+ uwep->spe += amount;
+ if(amount > 0) uwep->cursed = 0;
+ return(1);
+}
diff --git a/hack/hack.wizard.c b/hack/hack.wizard.c
new file mode 100644
index 00000000..835ecc3d
--- /dev/null
+++ b/hack/hack.wizard.c
@@ -0,0 +1,189 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.wizard.c - version 1.0.3 */
+
+/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */
+
+#include "hack.h"
+extern struct permonst pm_wizard;
+extern struct monst *makemon();
+
+#define WIZSHOT 6 /* one chance in WIZSHOT that wizard will try magic */
+#define BOLT_LIM 8 /* from this distance D and 1 will try to hit you */
+
+char wizapp[] = "@DNPTUVXcemntx";
+
+/* If he has found the Amulet, make the wizard appear after some time */
+amulet(){
+ register struct obj *otmp;
+ register struct monst *mtmp;
+
+ if(!flags.made_amulet || !flags.no_of_wizards)
+ return;
+ /* find wizard, and wake him if necessary */
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if(mtmp->data->mlet == '1' && mtmp->msleep && !rn2(40))
+ for(otmp = invent; otmp; otmp = otmp->nobj)
+ if(otmp->olet == AMULET_SYM && !otmp->spe) {
+ mtmp->msleep = 0;
+ if(dist(mtmp->mx,mtmp->my) > 2)
+ pline(
+ "You get the creepy feeling that somebody noticed your taking the Amulet."
+ );
+ return;
+ }
+}
+
+wiz_hit(mtmp)
+register struct monst *mtmp;
+{
+ /* if we have stolen or found the amulet, we disappear */
+ if(mtmp->minvent && mtmp->minvent->olet == AMULET_SYM &&
+ mtmp->minvent->spe == 0) {
+ /* vanish -- very primitive */
+ fall_down(mtmp);
+ return(1);
+ }
+
+ /* if it is lying around someplace, we teleport to it */
+ if(!carrying(AMULET_OF_YENDOR)) {
+ register struct obj *otmp;
+
+ for(otmp = fobj; otmp; otmp = otmp->nobj)
+ if(otmp->olet == AMULET_SYM && !otmp->spe) {
+ if((u.ux != otmp->ox || u.uy != otmp->oy) &&
+ !m_at(otmp->ox, otmp->oy)) {
+
+ /* teleport to it and pick it up */
+ mtmp->mx = otmp->ox;
+ mtmp->my = otmp->oy;
+ freeobj(otmp);
+ mpickobj(mtmp, otmp);
+ pmon(mtmp);
+ return(0);
+ }
+ goto hithim;
+ }
+ return(0); /* we don't know where it is */
+ }
+hithim:
+ if(rn2(2)) { /* hit - perhaps steal */
+
+ /* if hit 1/20 chance of stealing amulet & vanish
+ - amulet is on level 26 again. */
+ if(hitu(mtmp, d(mtmp->data->damn,mtmp->data->damd))
+ && !rn2(20) && stealamulet(mtmp))
+ ;
+ }
+ else
+ inrange(mtmp); /* try magic */
+ return(0);
+}
+
+inrange(mtmp)
+register struct monst *mtmp;
+{
+ register schar tx,ty;
+
+ /* do nothing if cancelled (but make '1' say something) */
+ if(mtmp->data->mlet != '1' && mtmp->mcan)
+ return;
+
+ /* spit fire only when both in a room or both in a corridor */
+ if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return;
+ tx = u.ux - mtmp->mx;
+ ty = u.uy - mtmp->my;
+ if((!tx && abs(ty) < BOLT_LIM) || (!ty && abs(tx) < BOLT_LIM)
+ || (abs(tx) == abs(ty) && abs(tx) < BOLT_LIM)){
+ switch(mtmp->data->mlet) {
+ case 'D':
+ /* spit fire in the direction of @ (not nec. hitting) */
+ buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty));
+ break;
+ case '1':
+ if(rn2(WIZSHOT)) break;
+ /* if you zapped wizard with wand of cancellation,
+ he has to shake off the effects before he can throw
+ spells successfully. 1/2 the time they fail anyway */
+ if(mtmp->mcan || rn2(2)) {
+ if(canseemon(mtmp))
+ pline("%s makes a gesture, then curses.",
+ Monnam(mtmp));
+ else
+ pline("You hear mumbled cursing.");
+ if(!rn2(3)) {
+ mtmp->mspeed = 0;
+ mtmp->minvis = 0;
+ }
+ if(!rn2(3))
+ mtmp->mcan = 0;
+ } else {
+ if(canseemon(mtmp)){
+ if(!rn2(6) && !Invis) {
+ pline("%s hypnotizes you.", Monnam(mtmp));
+ nomul(rn2(3) + 3);
+ break;
+ } else
+ pline("%s chants an incantation.",
+ Monnam(mtmp));
+ } else
+ pline("You hear a mumbled incantation.");
+ switch(rn2(Invis ? 5 : 6)) {
+ case 0:
+ /* create a nasty monster from a deep level */
+ /* (for the moment, 'nasty' is not implemented) */
+ (void) makemon((struct permonst *)0, u.ux, u.uy);
+ break;
+ case 1:
+ pline("\"Destroy the thief, my pets!\"");
+ aggravate(); /* aggravate all the monsters */
+ /* fall into next case */
+ case 2:
+ if (flags.no_of_wizards == 1 && rnd(5) == 0)
+ /* if only 1 wizard, clone himself */
+ clonewiz(mtmp);
+ break;
+ case 3:
+ if(mtmp->mspeed == MSLOW)
+ mtmp->mspeed = 0;
+ else
+ mtmp->mspeed = MFAST;
+ break;
+ case 4:
+ mtmp->minvis = 1;
+ break;
+ case 5:
+ /* Only if not Invisible */
+ pline("You hear a clap of thunder!");
+ /* shoot a bolt of fire or cold, or a sleep ray */
+ buzz(-rnd(3),mtmp->mx,mtmp->my,sgn(tx),sgn(ty));
+ break;
+ }
+ }
+ }
+ if(u.uhp < 1) done_in_by(mtmp);
+ }
+}
+
+aggravate()
+{
+ register struct monst *mtmp;
+
+ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
+ mtmp->msleep = 0;
+ if(mtmp->mfroz && !rn2(5))
+ mtmp->mfroz = 0;
+ }
+}
+
+clonewiz(mtmp)
+register struct monst *mtmp;
+{
+ register struct monst *mtmp2;
+
+ if(mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my)) {
+ flags.no_of_wizards = 2;
+ unpmon(mtmp2);
+ mtmp2->mappearance = wizapp[rn2(sizeof(wizapp)-1)];
+ pmon(mtmp);
+ }
+}
diff --git a/hack/hack.worm.c b/hack/hack.worm.c
new file mode 100644
index 00000000..ba3505d1
--- /dev/null
+++ b/hack/hack.worm.c
@@ -0,0 +1,183 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.worm.c - version 1.0.2 */
+
+#include "hack.h"
+#ifndef NOWORM
+#include "def.wseg.h"
+
+struct wseg *wsegs[32]; /* linked list, tail first */
+struct wseg *wheads[32];
+long wgrowtime[32];
+
+getwn(mtmp) struct monst *mtmp; {
+register tmp;
+ for(tmp=1; tmp<32; tmp++) if(!wsegs[tmp]) {
+ mtmp->wormno = tmp;
+ return(1);
+ }
+ return(0); /* level infested with worms */
+}
+
+/* called to initialize a worm unless cut in half */
+initworm(mtmp) struct monst *mtmp; {
+register struct wseg *wtmp;
+register tmp = mtmp->wormno;
+ if(!tmp) return;
+ wheads[tmp] = wsegs[tmp] = wtmp = newseg();
+ wgrowtime[tmp] = 0;
+ wtmp->wx = mtmp->mx;
+ wtmp->wy = mtmp->my;
+/* wtmp->wdispl = 0; */
+ wtmp->nseg = 0;
+}
+
+worm_move(mtmp) struct monst *mtmp; {
+register struct wseg *wtmp, *whd;
+register tmp = mtmp->wormno;
+ wtmp = newseg();
+ wtmp->wx = mtmp->mx;
+ wtmp->wy = mtmp->my;
+ wtmp->nseg = 0;
+/* wtmp->wdispl = 0; */
+ (whd = wheads[tmp])->nseg = wtmp;
+ wheads[tmp] = wtmp;
+ if(cansee(whd->wx,whd->wy)){
+ unpmon(mtmp);
+ atl(whd->wx, whd->wy, '~');
+ whd->wdispl = 1;
+ } else whd->wdispl = 0;
+ if(wgrowtime[tmp] <= moves) {
+ if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5);
+ else wgrowtime[tmp] += 2+rnd(15);
+ mtmp->mhpmax += 3;
+ mtmp->mhp += 3;
+ return;
+ }
+ whd = wsegs[tmp];
+ wsegs[tmp] = whd->nseg;
+ remseg(whd);
+}
+
+worm_nomove(mtmp) register struct monst *mtmp; {
+register tmp;
+register struct wseg *wtmp;
+ tmp = mtmp->wormno;
+ wtmp = wsegs[tmp];
+ if(wtmp == wheads[tmp]) return;
+ if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?");
+ wsegs[tmp] = wtmp->nseg;
+ remseg(wtmp);
+ mtmp->mhp -= 3; /* mhpmax not changed ! */
+}
+
+wormdead(mtmp) register struct monst *mtmp; {
+register tmp = mtmp->wormno;
+register struct wseg *wtmp, *wtmp2;
+ if(!tmp) return;
+ mtmp->wormno = 0;
+ for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
+ wtmp2 = wtmp->nseg;
+ remseg(wtmp);
+ }
+ wsegs[tmp] = 0;
+}
+
+wormhit(mtmp) register struct monst *mtmp; {
+register tmp = mtmp->wormno;
+register struct wseg *wtmp;
+ if(!tmp) return; /* worm without tail */
+ for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
+ (void) hitu(mtmp,1);
+}
+
+wormsee(tmp) register unsigned tmp; {
+register struct wseg *wtmp = wsegs[tmp];
+ if(!wtmp) panic("wormsee: wtmp==0");
+ for(; wtmp->nseg; wtmp = wtmp->nseg)
+ if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl){
+ newsym(wtmp->wx, wtmp->wy);
+ wtmp->wdispl = 0;
+ }
+}
+
+pwseg(wtmp) register struct wseg *wtmp; {
+ if(!wtmp->wdispl){
+ atl(wtmp->wx, wtmp->wy, '~');
+ wtmp->wdispl = 1;
+ }
+}
+
+cutworm(mtmp,x,y,weptyp)
+register struct monst *mtmp;
+register xchar x,y;
+register uchar weptyp; /* uwep->otyp or 0 */
+{
+ register struct wseg *wtmp, *wtmp2;
+ register struct monst *mtmp2;
+ register tmp,tmp2;
+ if(mtmp->mx == x && mtmp->my == y) return; /* hit headon */
+
+ /* cutting goes best with axe or sword */
+ tmp = rnd(20);
+ if(weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
+ weptyp == AXE) tmp += 5;
+ if(tmp < 12) return;
+
+ /* if tail then worm just loses a tail segment */
+ tmp = mtmp->wormno;
+ wtmp = wsegs[tmp];
+ if(wtmp->wx == x && wtmp->wy == y){
+ wsegs[tmp] = wtmp->nseg;
+ remseg(wtmp);
+ return;
+ }
+
+ /* cut the worm in two halves */
+ mtmp2 = newmonst(0);
+ *mtmp2 = *mtmp;
+ mtmp2->mxlth = mtmp2->mnamelth = 0;
+
+ /* sometimes the tail end dies */
+ if(rn2(3) || !getwn(mtmp2)){
+ monfree(mtmp2);
+ tmp2 = 0;
+ } else {
+ tmp2 = mtmp2->wormno;
+ wsegs[tmp2] = wsegs[tmp];
+ wgrowtime[tmp2] = 0;
+ }
+ do {
+ if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){
+ if(tmp2) wheads[tmp2] = wtmp;
+ wsegs[tmp] = wtmp->nseg->nseg;
+ remseg(wtmp->nseg);
+ wtmp->nseg = 0;
+ if(tmp2){
+ pline("You cut the worm in half.");
+ mtmp2->mhpmax = mtmp2->mhp =
+ d(mtmp2->data->mlevel, 8);
+ mtmp2->mx = wtmp->wx;
+ mtmp2->my = wtmp->wy;
+ mtmp2->nmon = fmon;
+ fmon = mtmp2;
+ pmon(mtmp2);
+ } else {
+ pline("You cut off part of the worm's tail.");
+ remseg(wtmp);
+ }
+ mtmp->mhp /= 2;
+ return;
+ }
+ wtmp2 = wtmp->nseg;
+ if(!tmp2) remseg(wtmp);
+ wtmp = wtmp2;
+ } while(wtmp->nseg);
+ panic("Cannot find worm segment");
+}
+
+remseg(wtmp) register struct wseg *wtmp; {
+ if(wtmp->wdispl)
+ newsym(wtmp->wx, wtmp->wy);
+ free((char *) wtmp);
+}
+#endif NOWORM
diff --git a/hack/hack.worn.c b/hack/hack.worn.c
new file mode 100644
index 00000000..bfec47f2
--- /dev/null
+++ b/hack/hack.worn.c
@@ -0,0 +1,65 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.worn.c - version 1.0.2 */
+
+#include "hack.h"
+
+struct worn {
+ long w_mask;
+ struct obj **w_obj;
+} worn[] = {
+ { W_ARM, &uarm },
+ { W_ARM2, &uarm2 },
+ { W_ARMH, &uarmh },
+ { W_ARMS, &uarms },
+ { W_ARMG, &uarmg },
+ { W_RINGL, &uleft },
+ { W_RINGR, &uright },
+ { W_WEP, &uwep },
+ { W_BALL, &uball },
+ { W_CHAIN, &uchain },
+ { 0, 0 }
+};
+
+setworn(obj, mask)
+register struct obj *obj;
+long mask;
+{
+ register struct worn *wp;
+ register struct obj *oobj;
+
+ for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
+ oobj = *(wp->w_obj);
+ if(oobj && !(oobj->owornmask & wp->w_mask))
+ impossible("Setworn: mask = %ld.", wp->w_mask);
+ if(oobj) oobj->owornmask &= ~wp->w_mask;
+ if(obj && oobj && wp->w_mask == W_ARM){
+ if(uarm2) {
+ impossible("Setworn: uarm2 set?");
+ } else
+ setworn(uarm, W_ARM2);
+ }
+ *(wp->w_obj) = obj;
+ if(obj) obj->owornmask |= wp->w_mask;
+ }
+ if(uarm2 && !uarm) {
+ uarm = uarm2;
+ uarm2 = 0;
+ uarm->owornmask ^= (W_ARM | W_ARM2);
+ }
+}
+
+/* called e.g. when obj is destroyed */
+setnotworn(obj) register struct obj *obj; {
+ register struct worn *wp;
+
+ for(wp = worn; wp->w_mask; wp++)
+ if(obj == *(wp->w_obj)) {
+ *(wp->w_obj) = 0;
+ obj->owornmask &= ~wp->w_mask;
+ }
+ if(uarm2 && !uarm) {
+ uarm = uarm2;
+ uarm2 = 0;
+ uarm->owornmask ^= (W_ARM | W_ARM2);
+ }
+}
diff --git a/hack/hack.zap.c b/hack/hack.zap.c
new file mode 100644
index 00000000..e1472b56
--- /dev/null
+++ b/hack/hack.zap.c
@@ -0,0 +1,642 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.zap.c - version 1.0.3 */
+
+#include "hack.h"
+
+extern struct obj *mkobj_at();
+extern struct monst *makemon(), *mkmon_at(), youmonst;
+struct monst *bhit();
+char *exclam();
+
+char *fl[]= {
+ "magic missile",
+ "bolt of fire",
+ "sleep ray",
+ "bolt of cold",
+ "death ray"
+};
+
+/* Routines for IMMEDIATE wands. */
+/* bhitm: monster mtmp was hit by the effect of wand otmp */
+bhitm(mtmp, otmp)
+register struct monst *mtmp;
+register struct obj *otmp;
+{
+ wakeup(mtmp);
+ switch(otmp->otyp) {
+ case WAN_STRIKING:
+ if(u.uswallow || rnd(20) < 10+mtmp->data->ac) {
+ register int tmp = d(2,12);
+ hit("wand", mtmp, exclam(tmp));
+ mtmp->mhp -= tmp;
+ if(mtmp->mhp < 1) killed(mtmp);
+ } else miss("wand", mtmp);
+ break;
+ case WAN_SLOW_MONSTER:
+ mtmp->mspeed = MSLOW;
+ break;
+ case WAN_SPEED_MONSTER:
+ mtmp->mspeed = MFAST;
+ break;
+ case WAN_UNDEAD_TURNING:
+ if(index(UNDEAD,mtmp->data->mlet)) {
+ mtmp->mhp -= rnd(8);
+ if(mtmp->mhp < 1) killed(mtmp);
+ else mtmp->mflee = 1;
+ }
+ break;
+ case WAN_POLYMORPH:
+ if( newcham(mtmp,&mons[rn2(CMNUM)]) )
+ objects[otmp->otyp].oc_name_known = 1;
+ break;
+ case WAN_CANCELLATION:
+ mtmp->mcan = 1;
+ break;
+ case WAN_TELEPORTATION:
+ rloc(mtmp);
+ break;
+ case WAN_MAKE_INVISIBLE:
+ mtmp->minvis = 1;
+ break;
+#ifdef WAN_PROBING
+ case WAN_PROBING:
+ mstatusline(mtmp);
+ break;
+#endif WAN_PROBING
+ default:
+ impossible("What an interesting wand (%u)", otmp->otyp);
+ }
+}
+
+bhito(obj, otmp) /* object obj was hit by the effect of wand otmp */
+register struct obj *obj, *otmp; /* returns TRUE if sth was done */
+{
+ register int res = TRUE;
+
+ if(obj == uball || obj == uchain)
+ res = FALSE;
+ else
+ switch(otmp->otyp) {
+ case WAN_POLYMORPH:
+ /* preserve symbol and quantity, but turn rocks into gems */
+ mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
+ ? GEM_SYM : obj->olet,
+ obj->ox, obj->oy) -> quan = obj->quan;
+ delobj(obj);
+ break;
+ case WAN_STRIKING:
+ if(obj->otyp == ENORMOUS_ROCK)
+ fracture_rock(obj);
+ else
+ res = FALSE;
+ break;
+ case WAN_CANCELLATION:
+ if(obj->spe && obj->olet != AMULET_SYM) {
+ obj->known = 0;
+ obj->spe = 0;
+ }
+ break;
+ case WAN_TELEPORTATION:
+ rloco(obj);
+ break;
+ case WAN_MAKE_INVISIBLE:
+ obj->oinvis = 1;
+ break;
+ case WAN_UNDEAD_TURNING:
+ res = revive(obj);
+ break;
+ case WAN_SLOW_MONSTER: /* no effect on objects */
+ case WAN_SPEED_MONSTER:
+#ifdef WAN_PROBING
+ case WAN_PROBING:
+#endif WAN_PROBING
+ res = FALSE;
+ break;
+ default:
+ impossible("What an interesting wand (%u)", otmp->otyp);
+ }
+ return(res);
+}
+
+dozap()
+{
+ register struct obj *obj;
+ xchar zx,zy;
+
+ obj = getobj("/", "zap");
+ if(!obj) return(0);
+ if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
+ pline("Nothing Happens.");
+ return(1);
+ }
+ if(obj->spe == 0)
+ pline("You wrest one more spell from the worn-out wand.");
+ if(!(objects[obj->otyp].bits & NODIR) && !getdir(1))
+ return(1); /* make him pay for knowing !NODIR */
+ obj->spe--;
+ if(objects[obj->otyp].bits & IMMEDIATE) {
+ if(u.uswallow)
+ bhitm(u.ustuck, obj);
+ else if(u.dz) {
+ if(u.dz > 0) {
+ register struct obj *otmp = o_at(u.ux, u.uy);
+ if(otmp)
+ (void) bhito(otmp, obj);
+ }
+ } else
+ (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
+ } else {
+ switch(obj->otyp){
+ case WAN_LIGHT:
+ litroom(TRUE);
+ break;
+ case WAN_SECRET_DOOR_DETECTION:
+ if(!findit()) return(1);
+ break;
+ case WAN_CREATE_MONSTER:
+ { register int cnt = 1;
+ if(!rn2(23)) cnt += rn2(7) + 1;
+ while(cnt--)
+ (void) makemon((struct permonst *) 0, u.ux, u.uy);
+ }
+ break;
+ case WAN_WISHING:
+ { char buf[BUFSZ];
+ register struct obj *otmp;
+ extern struct obj *readobjnam(), *addinv();
+ if(u.uluck + rn2(5) < 0) {
+ pline("Unfortunately, nothing happens.");
+ break;
+ }
+ pline("You may wish for an object. What do you want? ");
+ getlin(buf);
+ if(buf[0] == '\033') buf[0] = 0;
+ otmp = readobjnam(buf);
+ otmp = addinv(otmp);
+ prinv(otmp);
+ break;
+ }
+ case WAN_DIGGING:
+ /* Original effect (approximately):
+ * from CORR: dig until we pierce a wall
+ * from ROOM: piece wall and dig until we reach
+ * an ACCESSIBLE place.
+ * Currently: dig for digdepth positions;
+ * also down on request of Lennart Augustsson.
+ */
+ { register struct rm *room;
+ register int digdepth;
+ if(u.uswallow) {
+ register struct monst *mtmp = u.ustuck;
+
+ pline("You pierce %s's stomach wall!",
+ monnam(mtmp));
+ mtmp->mhp = 1; /* almost dead */
+ unstuck(mtmp);
+ mnexto(mtmp);
+ break;
+ }
+ if(u.dz) {
+ if(u.dz < 0) {
+ pline("You loosen a rock from the ceiling.");
+ pline("It falls on your head!");
+ losehp(1, "falling rock");
+ mksobj_at(ROCK, u.ux, u.uy);
+ fobj->quan = 1;
+ stackobj(fobj);
+ if(Invisible) newsym(u.ux, u.uy);
+ } else {
+ dighole();
+ }
+ break;
+ }
+ zx = u.ux+u.dx;
+ zy = u.uy+u.dy;
+ digdepth = 8 + rn2(18);
+ Tmp_at(-1, '*'); /* open call */
+ while(--digdepth >= 0) {
+ if(!isok(zx,zy)) break;
+ room = &levl[zx][zy];
+ Tmp_at(zx,zy);
+ if(!xdnstair){
+ if(zx < 3 || zx > COLNO-3 ||
+ zy < 3 || zy > ROWNO-3)
+ break;
+ if(room->typ == HWALL ||
+ room->typ == VWALL){
+ room->typ = ROOM;
+ break;
+ }
+ } else
+ if(room->typ == HWALL || room->typ == VWALL ||
+ room->typ == SDOOR || room->typ == LDOOR){
+ room->typ = DOOR;
+ digdepth -= 2;
+ } else
+ if(room->typ == SCORR || !room->typ) {
+ room->typ = CORR;
+ digdepth--;
+ }
+ mnewsym(zx,zy);
+ zx += u.dx;
+ zy += u.dy;
+ }
+ mnewsym(zx,zy); /* not always necessary */
+ Tmp_at(-1,-1); /* closing call */
+ break;
+ }
+ default:
+ buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
+ u.ux, u.uy, u.dx, u.dy);
+ break;
+ }
+ if(!objects[obj->otyp].oc_name_known) {
+ objects[obj->otyp].oc_name_known = 1;
+ more_experienced(0,10);
+ }
+ }
+ return(1);
+}
+
+char *
+exclam(force)
+register int force;
+{
+ /* force == 0 occurs e.g. with sleep ray */
+ /* note that large force is usual with wands so that !! would
+ require information about hand/weapon/wand */
+ return( (force < 0) ? "?" : (force <= 4) ? "." : "!" );
+}
+
+hit(str,mtmp,force)
+register char *str;
+register struct monst *mtmp;
+register char *force; /* usually either "." or "!" */
+{
+ if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str);
+ else pline("The %s hits %s%s", str, monnam(mtmp), force);
+}
+
+miss(str,mtmp)
+register char *str;
+register struct monst *mtmp;
+{
+ if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str);
+ else pline("The %s misses %s.",str,monnam(mtmp));
+}
+
+/* bhit: called when a weapon is thrown (sym = obj->olet) or when an
+ IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of
+ range or when a monster is hit; the monster is returned, and bhitpos
+ is set to the final position of the weapon thrown; the ray of a wand
+ may affect several objects and monsters on its path - for each of
+ these an argument function is called. */
+/* check !u.uswallow before calling bhit() */
+
+struct monst *
+bhit(ddx,ddy,range,sym,fhitm,fhito,obj)
+register int ddx,ddy,range; /* direction and range */
+char sym; /* symbol displayed on path */
+int (*fhitm)(), (*fhito)(); /* fns called when mon/obj hit */
+struct obj *obj; /* 2nd arg to fhitm/fhito */
+{
+ register struct monst *mtmp;
+ register struct obj *otmp;
+ register int typ;
+
+ bhitpos.x = u.ux;
+ bhitpos.y = u.uy;
+
+ if(sym) tmp_at(-1, sym); /* open call */
+ while(range-- > 0) {
+ bhitpos.x += ddx;
+ bhitpos.y += ddy;
+ typ = levl[bhitpos.x][bhitpos.y].typ;
+ if(mtmp = m_at(bhitpos.x,bhitpos.y)){
+ if(sym) {
+ tmp_at(-1, -1); /* close call */
+ return(mtmp);
+ }
+ (*fhitm)(mtmp, obj);
+ range -= 3;
+ }
+ if(fhito && (otmp = o_at(bhitpos.x,bhitpos.y))){
+ if((*fhito)(otmp, obj))
+ range--;
+ }
+ if(!ZAP_POS(typ)) {
+ bhitpos.x -= ddx;
+ bhitpos.y -= ddy;
+ break;
+ }
+ if(sym) tmp_at(bhitpos.x, bhitpos.y);
+ }
+
+ /* leave last symbol unless in a pool */
+ if(sym)
+ tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0);
+ return(0);
+}
+
+struct monst *
+boomhit(dx,dy) {
+ register int i, ct;
+ register struct monst *mtmp;
+ char sym = ')';
+ extern schar xdir[], ydir[];
+
+ bhitpos.x = u.ux;
+ bhitpos.y = u.uy;
+
+ for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
+ tmp_at(-1, sym); /* open call */
+ for(ct=0; ct<10; ct++) {
+ if(i == 8) i = 0;
+ sym = ')' + '(' - sym;
+ tmp_at(-2, sym); /* change let call */
+ dx = xdir[i];
+ dy = ydir[i];
+ bhitpos.x += dx;
+ bhitpos.y += dy;
+ if(mtmp = m_at(bhitpos.x, bhitpos.y)){
+ tmp_at(-1,-1);
+ return(mtmp);
+ }
+ if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
+ bhitpos.x -= dx;
+ bhitpos.y -= dy;
+ break;
+ }
+ if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
+ if(rn2(20) >= 10+u.ulevel){ /* we hit ourselves */
+ (void) thitu(10, rnd(10), "boomerang");
+ break;
+ } else { /* we catch it */
+ tmp_at(-1,-1);
+ pline("Skillfully, you catch the boomerang.");
+ return(&youmonst);
+ }
+ }
+ tmp_at(bhitpos.x, bhitpos.y);
+ if(ct % 5 != 0) i++;
+ }
+ tmp_at(-1, -1); /* do not leave last symbol */
+ return(0);
+}
+
+char
+dirlet(dx,dy) register dx,dy; {
+ return
+ (dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
+}
+
+/* type == -1: monster spitting fire at you */
+/* type == -1,-2,-3: bolts sent out by wizard */
+/* called with dx = dy = 0 with vertical bolts */
+buzz(type,sx,sy,dx,dy)
+register int type;
+register xchar sx,sy;
+register int dx,dy;
+{
+ int abstype = abs(type);
+ register char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype];
+ struct rm *lev;
+ xchar range;
+ struct monst *mon;
+
+ if(u.uswallow) {
+ register int tmp;
+
+ if(type < 0) return;
+ tmp = zhit(u.ustuck, type);
+ pline("The %s rips into %s%s",
+ fltxt, monnam(u.ustuck), exclam(tmp));
+ return;
+ }
+ if(type < 0) pru();
+ range = rn1(7,7);
+ Tmp_at(-1, dirlet(dx,dy)); /* open call */
+ while(range-- > 0) {
+ sx += dx;
+ sy += dy;
+ if((lev = &levl[sx][sy])->typ) Tmp_at(sx,sy);
+ else {
+ int bounce = 0;
+ if(cansee(sx-dx,sy-dy))
+ pline("The %s bounces!", fltxt);
+ if(ZAP_POS(levl[sx][sy-dy].typ))
+ bounce = 1;
+ if(ZAP_POS(levl[sx-dx][sy].typ)) {
+ if(!bounce || rn2(2)) bounce = 2;
+ }
+ switch(bounce){
+ case 0:
+ dx = -dx;
+ dy = -dy;
+ continue;
+ case 1:
+ dy = -dy;
+ sx -= dx;
+ break;
+ case 2:
+ dx = -dx;
+ sy -= dy;
+ break;
+ }
+ Tmp_at(-2,dirlet(dx,dy));
+ continue;
+ }
+ if(lev->typ == POOL && abstype == 1 /* fire */) {
+ range -= 3;
+ lev->typ = ROOM;
+ if(cansee(sx,sy)) {
+ mnewsym(sx,sy);
+ pline("The water evaporates.");
+ } else
+ pline("You hear a hissing sound.");
+ }
+ if((mon = m_at(sx,sy)) &&
+ (type != -1 || mon->data->mlet != 'D')) {
+ wakeup(mon);
+ if(rnd(20) < 18 + mon->data->ac) {
+ register int tmp = zhit(mon,abstype);
+ if(mon->mhp < 1) {
+ if(type < 0) {
+ if(cansee(mon->mx,mon->my))
+ pline("%s is killed by the %s!",
+ Monnam(mon), fltxt);
+ mondied(mon);
+ } else
+ killed(mon);
+ } else
+ hit(fltxt, mon, exclam(tmp));
+ range -= 2;
+ } else
+ miss(fltxt,mon);
+ } else if(sx == u.ux && sy == u.uy) {
+ nomul(0);
+ if(rnd(20) < 18+u.uac) {
+ register int dam = 0;
+ range -= 2;
+ pline("The %s hits you!",fltxt);
+ switch(abstype) {
+ case 0:
+ dam = d(2,6);
+ break;
+ case 1:
+ if(Fire_resistance)
+ pline("You don't feel hot!");
+ else dam = d(6,6);
+ if(!rn2(3))
+ burn_scrolls();
+ break;
+ case 2:
+ nomul(-rnd(25)); /* sleep ray */
+ break;
+ case 3:
+ if(Cold_resistance)
+ pline("You don't feel cold!");
+ else dam = d(6,6);
+ break;
+ case 4:
+ u.uhp = -1;
+ }
+ losehp(dam,fltxt);
+ } else pline("The %s whizzes by you!",fltxt);
+ stop_occupation();
+ }
+ if(!ZAP_POS(lev->typ)) {
+ int bounce = 0, rmn;
+ if(cansee(sx,sy)) pline("The %s bounces!",fltxt);
+ range--;
+ if(!dx || !dy || !rn2(20)){
+ dx = -dx;
+ dy = -dy;
+ } else {
+ if(ZAP_POS(rmn = levl[sx][sy-dy].typ) &&
+ (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ)))
+ bounce = 1;
+ if(ZAP_POS(rmn = levl[sx-dx][sy].typ) &&
+ (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ)))
+ if(!bounce || rn2(2))
+ bounce = 2;
+
+ switch(bounce){
+ case 0:
+ dy = -dy;
+ dx = -dx;
+ break;
+ case 1:
+ dy = -dy;
+ break;
+ case 2:
+ dx = -dx;
+ break;
+ }
+ Tmp_at(-2, dirlet(dx,dy));
+ }
+ }
+ }
+ Tmp_at(-1,-1);
+}
+
+zhit(mon,type) /* returns damage to mon */
+register struct monst *mon;
+register type;
+{
+ register int tmp = 0;
+
+ switch(type) {
+ case 0: /* magic missile */
+ tmp = d(2,6);
+ break;
+ case -1: /* Dragon blazing fire */
+ case 1: /* fire */
+ if(index("Dg", mon->data->mlet)) break;
+ tmp = d(6,6);
+ if(index("YF", mon->data->mlet)) tmp += 7;
+ break;
+ case 2: /* sleep*/
+ mon->mfroz = 1;
+ break;
+ case 3: /* cold */
+ if(index("YFgf", mon->data->mlet)) break;
+ tmp = d(6,6);
+ if(mon->data->mlet == 'D') tmp += 7;
+ break;
+ case 4: /* death*/
+ if(index(UNDEAD, mon->data->mlet)) break;
+ tmp = mon->mhp+1;
+ break;
+ }
+ mon->mhp -= tmp;
+ return(tmp);
+}
+
+#define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
+ ? 'a' + (otyp - DEAD_ACID_BLOB)\
+ : '@' + (otyp - DEAD_HUMAN))
+revive(obj)
+register struct obj *obj;
+{
+ register struct monst *mtmp;
+
+ if(obj->olet == FOOD_SYM && obj->otyp > CORPSE) {
+ /* do not (yet) revive shopkeepers */
+ /* Note: this might conceivably produce two monsters
+ at the same position - strange, but harmless */
+ mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp),obj->ox,obj->oy);
+ delobj(obj);
+ }
+ return(!!mtmp); /* TRUE if some monster created */
+}
+
+rloco(obj)
+register struct obj *obj;
+{
+ register tx,ty,otx,oty;
+
+ otx = obj->ox;
+ oty = obj->oy;
+ do {
+ tx = rn1(COLNO-3,2);
+ ty = rn2(ROWNO);
+ } while(!goodpos(tx,ty));
+ obj->ox = tx;
+ obj->oy = ty;
+ if(cansee(otx,oty))
+ newsym(otx,oty);
+}
+
+fracture_rock(obj) /* fractured by pick-axe or wand of striking */
+register struct obj *obj; /* no texts here! */
+{
+ /* unpobj(obj); */
+ obj->otyp = ROCK;
+ obj->quan = 7 + rn2(60);
+ obj->owt = weight(obj);
+ obj->olet = WEAPON_SYM;
+ if(cansee(obj->ox,obj->oy))
+ prl(obj->ox,obj->oy);
+}
+
+burn_scrolls()
+{
+ register struct obj *obj, *obj2;
+ register int cnt = 0;
+
+ for(obj = invent; obj; obj = obj2) {
+ obj2 = obj->nobj;
+ if(obj->olet == SCROLL_SYM) {
+ cnt++;
+ useup(obj);
+ }
+ }
+ if(cnt > 1) {
+ pline("Your scrolls catch fire!");
+ losehp(cnt, "burning scrolls");
+ } else if(cnt) {
+ pline("Your scroll catches fire!");
+ losehp(1, "burning scroll");
+ }
+}
diff --git a/hack/help b/hack/help
new file mode 100644
index 00000000..24b22a5d
--- /dev/null
+++ b/hack/help
@@ -0,0 +1,132 @@
+ Welcome to HACK! ( description of version 1.0.3 )
+
+ Hack is a Dungeons and Dragons like game where you (the adventurer)
+descend into the depths of the dungeon in search of the Amulet of Yendor
+(reputed to be hidden on the twentieth level). You are accompanied by a
+little dog that can help you in many ways and can be trained to do all
+sorts of things. On the way you will find useful (or useless) items, (quite
+possibly with magic properties) and assorted monsters. You attack a monster
+by trying to move into the space a monster is in (but often it is much
+wiser to leave it alone).
+
+ Unlike most adventure games, which give you a verbal description of
+your location, hack gives you a visual image of the dungeon level you are on.
+
+ Hack uses the following symbols:
+ A to Z and a to z: monsters. You can find out what a letter
+represents by saying "/ (letter)", as in "/A", which will tell you that 'A'
+is a giant ant.
+ - and | These form the walls of a room (or maze).
+ . this is the floor of a room.
+ # this is a corridor.
+ > this is the staircase to the next level.
+ < the staircase to the previous level.
+ ` A large boulder.
+ @ You (usually).
+ ^ A trap.
+ ) A weapon of some sort.
+ ( Some other useful object (key, rope, dynamite, camera, ...)
+ [ A suit of armor.
+ % A piece of food (not necessarily healthy ...).
+ / A wand.
+ = A ring.
+ ? A scroll.
+ ! A magic potion.
+ $ A pile or pot of gold.
+
+Commands:
+ Hack knows the following commands:
+ ? help: print this list.
+ Q Quit the game.
+ S Save the game.
+ ! Escape to a shell.
+ ^Z Suspend the game.
+ < up: go up the staircase (if you are standing on it).
+ > down: go down (just like up).
+ kjhlyubn - go one step in the direction indicated.
+ k: north (i.e., to the top of the screen),
+ j: south, h: west, l: east, y: ne, u: nw, b: se, n: sw.
+ KJHLYUBN - Go in that direction until you hit a wall or run
+ into something.
+ m (followed by one of kjhlyubn): move without picking up
+ any objects.
+ M (followed by one of KJHLYUBN): Move far, no pickup.
+ f (followed by one of kjhlyubn): move until something
+ interesting is found.
+ F (followed by one of KJHLYUBN): as previous, but forking
+ of corridors is not considered interesting.
+ i print your inventory.
+ I print selected parts of your inventory, like in
+ I* - print all gems in inventory;
+ IU - print all unpaid items;
+ IX - print all used up items that are on your shopping bill;
+ I$ - count your money.
+ s search for secret doors and traps around you.
+ ^ ask for the type of a trap you found earlier.
+ ) ask for current wielded weapon.
+ [ ask for current armor.
+ = ask for current rings.
+ $ count how many gold pieces you are carrying.
+ . rest, do nothing.
+ , pick up some things.
+ : look at what is here.
+ ^T teleport.
+ ^R redraw the screen.
+ ^P repeat last message
+ (subsequent ^P's repeat earlier messages).
+ / (followed by any symbol): tell what this symbol represents.
+ \ tell what has been discovered.
+ e eat food.
+ w wield weapon. w- means: wield nothing, use bare hands.
+ q drink (quaff) a potion.
+ r read a scroll.
+ T Takeoff armor.
+ R Remove Ring.
+ W Wear armor.
+ P Put on a ring.
+ z zap a wand.
+ t throw an object or shoot an arrow.
+ p pay your shopping bill.
+ d drop something. d7a: drop seven items of object a.
+ D Drop several things.
+ In answer to the question "What kinds of things do you
+ want to drop? [!%= au]" you should give zero or more
+ object symbols possibly followed by 'a' and/or 'u'.
+ 'a' means: drop all such objects, without asking for
+ confirmation.
+ 'u' means: drop only unpaid objects (when in a shop).
+ a use, apply - Generic command for using a key to lock
+ or unlock a door, using a camera, using a rope, etc.
+ c call: name a certain object or class of objects.
+ C Call: Name an individual monster.
+ E Engrave: Write a message in the dust on the floor.
+ E- means: use fingers for writing.
+ O Set options. You will be asked to enter an option line.
+ If this is empty, the current options are reported.
+ Otherwise it should be a list of options separated by commas.
+ Possible boolean options are: oneline, time, news, tombstone,
+ rest_on_space, fixinvlet, beginner, male, female.
+ They can be negated by prefixing them with '!' or "no".
+ A string option is name; it supplies the answer to the question
+ "Who are you?"; it may have a suffix.
+ A compound option is endgame; it is followed by a description
+ of what parts of the list of topscorers should be printed
+ when the game is finished.
+ Usually one will not want to use the 'O' command, but instead
+ put a HACKOPTIONS="...." line in one's environment.
+ v print version number.
+
+ You can put a number before a command to repeat it that many times,
+ as in "20s" or "40.".
+
+ At present, some information is displayed on the bottom line.
+ (It is expected that this information will go away in future versions.)
+ You see on what dungeon level you are, how many hit points you have
+ now (and will have when fully recovered), what your armor class is
+ (the lower the better), your strength, experience level and the
+ state of your stomach.
+
+ Have Fun, and Good Hacking!
+
+
+
diff --git a/hack/hh b/hack/hh
new file mode 100644
index 00000000..d777102d
--- /dev/null
+++ b/hack/hh
@@ -0,0 +1,55 @@
+y k u Move commands:
+ \|/ hykulnjb: single move in specified direction
+h-+-l HYKULNJB: repeated move in specified direction
+ /|\ (until stopped by e.g. a wall)
+b j n f<dir>: fast movement in direction <dir>
+ (until something interesting is seen)
+ m<dir>: move without picking up objects
+
+Meta commands:
+Q quit leave the game
+S save save the game (to be continued later)
+! sh escape to some SHELL
+^Z suspend suspend the game (independent of your current suspend char)
+O set set options
+? help print information
+/ whatis give name (and sometimes more info) of specified monster
+\ known print list of what's been discovered
+v version print version number
+^R redraw redraw the screen (^R denotes the symbol CTRL/R)
+^P print repeat last message (subsequent ^P's repeat earlier messages)
+# introduces a long command; not really implemented
+
+Game commands:
+^T teleport teleport
+a apply, use use something (a key, camera, etc.)
+c call give a name to a class of objects
+d drop drop an object. d7a: drop seven items of object a.
+e eat eat something
+i invent list the inventory (all objects you are carrying)
+I invent list selected parts of the inventory
+ IU: list unpaid objects
+ IX: list unpaid but used up items
+ I$: count your money
+p pay pay your bill
+q drink quaff a potion
+r read read a scroll
+s search search for secret doors, hidden traps and monsters
+t throw throw or shoot a weapon
+w wield wield a weapon (w- wield nothing)
+z zap zap a wand
+C name name an individual monster (e.g., baptize your dog)
+D Drop drop several things
+E Engrave write a message in the dust on the floor (E- use fingers)
+P wear put on a ring
+R remove remove a ring
+T remove take off some armor
+W wear put on some armor
+< up go up the stairs
+> down go down the stairs
+^ trap_id identify a previously found trap
+),[,= ask for current weapon, armor, rings, respectively
+$ gold count your gold
+. rest wait a moment
+, pickup pick up all you can carry
+: look look at what is here
diff --git a/hack/makedefs.c b/hack/makedefs.c
new file mode 100644
index 00000000..aa113b9f
--- /dev/null
+++ b/hack/makedefs.c
@@ -0,0 +1,224 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* makedefs.c - version 1.0.2 */
+
+#include <stdio.h>
+
+/* construct definitions of object constants */
+#define LINSZ 1000
+#define STRSZ 40
+
+int fd;
+char string[STRSZ];
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+register int index = 0;
+register int propct = 0;
+register char *sp;
+ if (argc != 2) {
+ (void)fprintf(stderr, "usage: makedefs file\n");
+ exit(1);
+ }
+ if ((fd = open(argv[1], 0)) < 0) {
+ perror(argv[1]);
+ exit(1);
+ }
+ skipuntil("objects[] = {");
+ while(getentry()) {
+ if(!*string){
+ index++;
+ continue;
+ }
+ for(sp = string; *sp; sp++)
+ if(*sp == ' ' || *sp == '\t' || *sp == '-')
+ *sp = '_';
+ if(!strncmp(string, "RIN_", 4)){
+ capitalize(string+4);
+ printf("#define %s u.uprops[%d].p_flgs\n",
+ string+4, propct++);
+ }
+ for(sp = string; *sp; sp++) capitalize(sp);
+ /* avoid trouble with stupid C preprocessors */
+ if(!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
+ printf("/* #define %s %d */\n", string, index);
+ else
+ printf("#define %s %d\n", string, index);
+ index++;
+ }
+ printf("\n#define CORPSE DEAD_HUMAN\n");
+ printf("#define LAST_GEM (JADE+1)\n");
+ printf("#define LAST_RING %d\n", propct);
+ printf("#define NROFOBJECTS %d\n", index-1);
+ exit(0);
+}
+
+char line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
+int eof;
+
+readline(){
+register int n = read(fd, lp0, (line+LINSZ)-lp0);
+ if(n < 0){
+ printf("Input error.\n");
+ exit(1);
+ }
+ if(n == 0) eof++;
+ lpe = lp0+n;
+}
+
+char
+nextchar(){
+ if(lp == lpe){
+ readline();
+ lp = lp0;
+ }
+ return((lp == lpe) ? 0 : *lp++);
+}
+
+skipuntil(s) char *s; {
+register char *sp0, *sp1;
+loop:
+ while(*s != nextchar())
+ if(eof) {
+ printf("Cannot skipuntil %s\n", s);
+ exit(1);
+ }
+ if(strlen(s) > lpe-lp+1){
+ register char *lp1, *lp2;
+ lp2 = lp;
+ lp1 = lp = lp0;
+ while(lp2 != lpe) *lp1++ = *lp2++;
+ lp2 = lp0; /* save value */
+ lp0 = lp1;
+ readline();
+ lp0 = lp2;
+ if(strlen(s) > lpe-lp+1) {
+ printf("error in skipuntil");
+ exit(1);
+ }
+ }
+ sp0 = s+1;
+ sp1 = lp;
+ while(*sp0 && *sp0 == *sp1) sp0++, sp1++;
+ if(!*sp0){
+ lp = sp1;
+ return(1);
+ }
+ goto loop;
+}
+
+getentry(){
+int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
+int prefix = 0;
+char ch;
+#define NSZ 10
+char identif[NSZ], *ip;
+ string[0] = string[4] = 0;
+ /* read until {...} or XXX(...) followed by ,
+ skip comment and #define lines
+ deliver 0 on failure
+ */
+ while(1) {
+ ch = nextchar();
+ swi:
+ if(letter(ch)){
+ ip = identif;
+ do {
+ if(ip < identif+NSZ-1) *ip++ = ch;
+ ch = nextchar();
+ } while(letter(ch) || digit(ch));
+ *ip = 0;
+ while(ch == ' ' || ch == '\t') ch = nextchar();
+ if(ch == '(' && !inparens && !stringseen)
+ if(!strcmp(identif, "WAND") ||
+ !strcmp(identif, "RING") ||
+ !strcmp(identif, "POTION") ||
+ !strcmp(identif, "SCROLL"))
+ (void) strncpy(string, identif, 3),
+ string[3] = '_',
+ prefix = 4;
+ }
+ switch(ch) {
+ case '/':
+ /* watch for comment */
+ if((ch = nextchar()) == '*')
+ skipuntil("*/");
+ goto swi;
+ case '{':
+ inbraces++;
+ continue;
+ case '(':
+ inparens++;
+ continue;
+ case '}':
+ inbraces--;
+ if(inbraces < 0) return(0);
+ continue;
+ case ')':
+ inparens--;
+ if(inparens < 0) {
+ printf("too many ) ?");
+ exit(1);
+ }
+ continue;
+ case '\n':
+ /* watch for #define at begin of line */
+ if((ch = nextchar()) == '#'){
+ register char pch;
+ /* skip until '\n' not preceded by '\\' */
+ do {
+ pch = ch;
+ ch = nextchar();
+ } while(ch != '\n' || pch == '\\');
+ continue;
+ }
+ goto swi;
+ case ',':
+ if(!inparens && !inbraces){
+ if(prefix && !string[prefix])
+ string[0] = 0;
+ if(stringseen) return(1);
+ printf("unexpected ,\n");
+ exit(1);
+ }
+ commaseen++;
+ continue;
+ case '\'':
+ if((ch = nextchar()) == '\\') ch = nextchar();
+ if(nextchar() != '\''){
+ printf("strange character denotation?\n");
+ exit(1);
+ }
+ continue;
+ case '"':
+ {
+ register char *sp = string + prefix;
+ register char pch;
+ register int store = (inbraces || inparens)
+ && !stringseen++ && !commaseen;
+ do {
+ pch = ch;
+ ch = nextchar();
+ if(store && sp < string+STRSZ)
+ *sp++ = ch;
+ } while(ch != '"' || pch == '\\');
+ if(store) *--sp = 0;
+ continue;
+ }
+ }
+ }
+}
+
+capitalize(sp) register char *sp; {
+ if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a';
+}
+
+letter(ch) register char ch; {
+ return( ('a' <= ch && ch <= 'z') ||
+ ('A' <= ch && ch <= 'Z') );
+}
+
+digit(ch) register char ch; {
+ return( '0' <= ch && ch <= '9' );
+}
diff --git a/hack/pathnames.h b/hack/pathnames.h
new file mode 100644
index 00000000..1df8f008
--- /dev/null
+++ b/hack/pathnames.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 5/2/90
+ */
+
+#define _PATH_MAIL "/usr/bin/mail"
+#define _PATH_QUEST "/var/games/questdir"
+#define _PATH_HACK "/var/games/hackdir"
+
diff --git a/hack/rnd.c b/hack/rnd.c
new file mode 100644
index 00000000..8547cef2
--- /dev/null
+++ b/hack/rnd.c
@@ -0,0 +1,30 @@
+/* rnd.c - version 1.0.2 */
+
+#define RND(x) ((random()>>3) % x)
+
+rn1(x,y)
+register x,y;
+{
+ return(RND(x)+y);
+}
+
+rn2(x)
+register x;
+{
+ return(RND(x));
+}
+
+rnd(x)
+register x;
+{
+ return(RND(x)+1);
+}
+
+d(n,x)
+register n,x;
+{
+ register tmp = n;
+
+ while(n--) tmp += RND(x);
+ return(tmp);
+}
diff --git a/hack/rumors b/hack/rumors
new file mode 100644
index 00000000..9435a5fe
--- /dev/null
+++ b/hack/rumors
@@ -0,0 +1,505 @@
+"Quit" is a four letter word.
+"So when I die, the first thing I will see in Heaven is a score list?"
+-- more --
+...and rings may protect your fingers.
+...and sometimes a piercer drops by.
+A Quasit is even faster than a jaguar!
+A chameleon imitating a postman often delivers scrolls of fire.
+A chameleon imitating a postman sometimes delivers scrolls of punishment.
+A clove of garlic a day keeps your best friends away.
+A cockatrice's corpse is guaranteed to be untainted!
+A confused acid blob may attack.
+A dead lizard is a good thing to turn undead.
+A dragon is just a Snake that ate a scroll of fire.
+A fading corridor enlightens your insight.
+A glowing potion is too hot to drink.
+A good amulet may protect you against guards.
+A homunculus wouldnt want to hurt a wizard.
+A jaguar shouldn't frighten you.
+A long worm can be defined recursively. So how should you attack it?
+A long worm hits with all of its length.
+A magic vomit pump is a necessity for gourmands.
+A monstrous mind is a toy for ever.
+A nurse a day keeps the doctor away.
+A potion of blindness makes you see invisible things.
+A ring is just a wound wand.
+A ring of adornment protects against Nymphs.
+A ring of conflict is a bad thing if there is a nurse in the room.
+A ring of extra ringfinger is useless if not enchanted.
+A ring of stealth can be recognised by that it does not teleport you.
+A rope may form a trail in a maze.
+A rumour has it that rumours are just rumours.
+A scroll of enchant amulet is only useful on your way back.
+A smoky potion surely affects your vision.
+A spear might hit a nurse.
+A spear will hit an ettin.
+A staff may recharge if you drop it for awhile.
+A tin of smoked eel is a wonderful find.
+A truly wise man never plays leapfrog with a unicorn.
+A two-handed sword usually misses.
+A unicorn can be tamed only by a fair maiden.
+A visit to the Zoo is very educational; you meet interesting animals.
+A wand of deaf is a more dangerous weapon than a wand of sheep.
+A wand of vibration might bring the whole cave crashing about your ears.
+A winner never quits. A quitter never wins.
+A xan is a small animal. It doesn't reach higher than your leg.
+Acid blobs should be attacked bare-handed.
+Affairs with Nymphs are often very expensive.
+Afraid of Mimics? Try to wear a ring of true seeing.
+Afraid of falling piercers? Wear a helmet!
+After being attacked by a Harpy you have a lot of arrows.
+All monsters are created evil, but some are more evil than others.
+Always attack a floating Eye from behind!
+Always be aware of the phase of the moon!
+Always read the info about a monster before dealing with it.
+Always sweep the floor before engraving important messages.
+Amulets are hard to make. Even for a wand of wishing.
+An Umber hulk can be a confusing sight.
+An elven cloak is always the height of fashion.
+An elven cloak protects against magic.
+An ettin is hard to kill; an imp is hard to hit. See the difference?
+Any small object that is accidentally dropped will hide under a larger object.
+Are you blind? Catch a floating Eye!
+Asking about monsters may be very useful.
+Attack long worms from the rear - that is so much safer!
+Attacking an eel when there is none usually is a fatal mistake!
+Balrogs only appear on the deeper levels.
+Be careful when eating bananas. Monsters might slip on the peels.
+Be careful when eating salmon - your fingers might become greasy.
+Be careful when the moon is in its last quarter.
+Be careful when throwing a boomerang - you might hit the back of your head.
+Be nice to a nurse: put away your weapon and take off your clothes.
+Being digested is a painfully slow process.
+Better go home and hit your kids. They are just little monsters!
+Better go home and play with your kids. They are just little monsters!
+Better leave the dungeon, otherwise you might get hurt badly.
+Beware of dark rooms - they may be the Morgue.
+Beware of death rays!
+Beware of falling rocks, wear a helmet!
+Beware of hungry dogs!
+Beware of the minotaur. He's very horny!
+Beware of the potion of Nitroglycerine - it's not for the weak of heart.
+Beware of wands of instant disaster.
+Beware: there's always a chance that your wand explodes as you try to zap it!
+Beyond the 23-rd level lies a happy retirement in a room of your own.
+Blank scrolls make more interesting reading.
+Blind? Eat a carrot!
+Booksellers never read scrolls; it might carry them too far away.
+Booksellers never read scrolls; it might leave their shop unguarded.
+Changing your suit without dropping your sword? You must be kidding!
+Cockatrices might turn themselves to stone faced with a mirror.
+Consumption of home-made food is strictly forbidden in this dungeon.
+Dark gems are just coloured glass.
+Dark room? Just flash often with your camera.
+Dark room? Your chance to develop your photographs!
+Dark rooms are not *completely* dark: just wait and let your eyes adjust...
+Dead lizards protect against a cockatrice.
+Death is just around the next door.
+Death is life's way of telling you you've been fired.
+Descend in order to meet more decent monsters.
+Did you know worms had teeth?
+Didn't you forget to pay?
+Didn't you forget to pay?
+Direct a direct hit on your direct opponent, directing in the right direction.
+Do something big today: lift a boulder.
+Do you want to visit hell? Dig a *very* deep hole.
+Dogs are attracted by the smell of tripe.
+Dogs do not eat when the moon is full.
+Dogs never step on cursed items.
+Dogs of ghosts aren't angry, just hungry.
+Don't bother about money: only Leprechauns and shopkeepers are interested.
+Don't create fireballs: they might turn against you.
+Don't eat too much: you might start hiccoughing!
+Don't forget! Large dogs are MUCH harder to kill than little dogs.
+Don't play hack at your work, your boss might hit you!
+Don't swim with weapons or armour: they might rust!
+Don't tell a soul you found a secret door, otherwise it isn't secret anymore.
+Don't throw gems. They are so precious! Besides, you might hit a roommate.
+Drinking might affect your health.
+Drop your vanity and get rid of your jewels! Pickpockets about!
+Dungeon expects every monster to do his duty.
+Dust is an armor of poor quality.
+Eat 10 cloves of garlic and keep all humans at a two-square distance.
+Eat a homunculus if you want to avoid sickness.
+Eating a Wraith is a rewarding experience!
+Eating a freezing sphere is like eating a yeti.
+Eating a killer bee is like eating a scorpion.
+Eating a tengu is like eating a Nymph.
+Eating unpaid Leprechauns may be advantageous.
+Eels hide under mud. Use a unicorn to clear the water and make them visible.
+Elven cloaks cannot rust.
+Engrave your wishes with a wand of wishing.
+Eventually all wands of striking do strike.
+Eventually you will come to admire the swift elegance of a retreating nymph.
+Ever fought with an enchanted tooth?
+Ever heard hissing outside? I *knew* you hadn't!
+Ever seen a leocrotta dancing the tengu?
+Ever slept in the arms of a homunculus?
+Ever tamed a shopkeeper?
+Ever tried digging through a Vault Guard?
+Ever tried enchanting a rope?
+Ever tried to catch a flying boomerang?
+Ever tried to put a Troll into a large box?
+Ever wondered why one would want to dip something in a potion?
+Every dog should be a domesticated one.
+Every hand has only one finger to put a ring on. You've got only two hands. So?
+Every level contains a shop; only the entrance is often hidden.
+Everybody should have tasted a scorpion at least once in his life.
+Expensive cameras have penetrating flashlights.
+Feeding the animals is strictly prohibited. The Management.
+Feeling lousy? Why don't you drink a potion of tea?
+Fiery letters might deter monsters.
+First Law of Hacking: leaving is much more difficult than entering.
+For any remedy there is a misery.
+Fourth Law of Hacking: you will find the exit at the entrance.
+Gems are the droppings of other inmates.
+Gems do get a burden.
+Genocide on shopkeepers is punishable.
+Getting Hungry? Stop wearing rings!
+Getting Hungry? Wear an amulet!
+Ghosts always empty the fridge.
+Ghosts are visible because they don't leave a trace.
+Giant beetles make giant holes in giant trees!
+Giving head to a long worm is like a long lasting reception.
+Gold is a heavy metal.
+Good day for overcoming obstacles. Try a steeplechase.
+Gossip is the opiate of the depressed.
+Hackers do it with bugs.
+Half Moon tonight. (At least it's better than no Moon at all.)
+Handle your flasks carefully - there might be a ghost inside!
+Have a good meal today: eat a minotaur.
+Hey guys, you *WIELD* a dead lizard against a cocatrice! [David London]
+Hissing is a sound I hate.
+Hitting is the lingua franca in these regions.
+Humans use walking canes when they grow old.
+Hunger is a confusing experience for a dog!
+Hungry dogs are unreliable.
+Hungry? There is an abundance of food on the next level.
+Hungry? Wear an amulet!
+I doubt whether nurses are virgins.
+I guess you have never hit a postman with an Amulet of Yendor yet...
+I once knew a hacker who ate too fast and choked to death.....
+I smell a maze of twisty little passages.
+I wished, I never wished a wand of wishing. (Wishful thinking)
+If "nothing happens", something *has* happened anyway!!
+If a chameleon mimics a mace, it really mimics a Mimic mimicking a mace.
+If a shopkeeper kicks you out of his shop, he'll kick you out of the dungeon.
+If you are being punished, it's done with a deadly weapon.
+If you are the shopkeeper you can take things for free.
+If you are too cute some monsters might be tempted to embrace you.
+If you can't learn to do it well, learn to enjoy doing it badly.
+If you need a wand of digging, kindly ask the minotaur.
+If you see nurses you better start looking somewhere for a doctor.
+If you turn blind: don't expect your dog to be turned into a seeing-eye dog.
+If you want to feal great, you must eat something real big.
+If you want to float you'd better eat a floating eye.
+If you want to genocide nurses, genocide @'s.
+If you want to hit, use a dagger.
+If you want to rob a shop, train your dog.
+If you're afraid of trapdoors, just cover the floor with all you've got.
+If you're lost, try buying a map next time you're in a shop.
+If your ghost kills a player, it increases your score.
+Important mail? Be careful that it isn't stolen!
+Improve your environment, using a wand of rearrangement.
+In a hurry? Try a ride on a fast moving quasit!
+In a way, a scorpion is like a snake.
+In need of a rest? Quaff a potion of sickness!
+In total, there are eight sorts of shops.
+Increase mindpower: Tame your own ghost!
+Inside a shop you better take a look at the price tags before buying anything.
+It furthers one to see the great man.
+It is bad manners to use a wand in a shop.
+It is not always a good idea to whistle for your dog.
+It is said that Giant Rabbits can be tamed with carrots only.
+It is said that purple worms and trappers fill the same niche.
+It might be a good idea to offer the unicorn a ruby.
+It seems you keep overlooking a sign reading "No trespassing"!
+It would be peculiarly sad were your dog turned to stone.
+It's all a matter of life and death, so beware of the undead.
+It's bad luck to drown a postman.
+It's bad luck, being punished.
+It's easy to overlook a monster in a wood.
+It's not safe to Save.
+Jackals are intrinsically rotten.
+Just below any trapdoor there may be another one. Just keep falling!
+Keep a clear mind: quaff clear potions.
+Keep your armours away from rust.
+Keep your weaponry away from acids.
+Kicking the terminal doesn't hurt the monsters.
+Kill a unicorn and you kill your luck.
+Killer bees keep appearing till you kill their queen.
+Large dogs make larger turds than little ones.
+Latest news? Put 'net.games.hack' in your .newsrc !
+Latest news? Put newsgroup 'netUNX.indoor.hackers-scroll' in your .newsrc!
+Learn how to spell. Play Hack!
+Leather armour cannot rust.
+Leprechauns are the most skilled cutpurses in this dungeon.
+Leprechauns hide their gold in a secret room.
+Let your fingers do the walking on the yulkjhnb keys.
+Let's face it: this time you're not going to win.
+Let's have a party, drink a lot of booze.
+Liquor sellers do not drink; they hate to see you twice.
+Looking for a monster -- use a staff of monster summoning.
+Looking pale? Quaff a red potion!
+M.M.Vault cashiers teleport any amount of gold to the next local branch.
+Many monsters make a murdering mob.
+Meet yourself! Commit suicide and type "hack"
+Meeting your own ghost decreases your luck considerably!
+Memory flaw - core dumped.
+Money is the root of all evil.
+Money to invest? Take it to the local branch of the Magic Memory Vault!
+Monsters come from nowhere to hit you everywhere.
+Monsters sleep because you are boring, not because they ever get tired.
+Most monsters can't swim.
+Most monsters prefer minced meat. That's why they are hitting you!
+Most rumors are just as misleading as this one.
+Much ado Nothing Happens.
+Murder complaint? Mail to 'netnix!devil!gamble!freak!trap!lastwill!rip'.
+Need money? Sell your corpses to a tin factory.
+Never ask a shopkeeper for a price list.
+Never attack a guard.
+Never drop a crysknife! No, never even unwield it, until...
+Never eat with glowing hands!
+Never fight a monster: you might get killed.
+Never go into the dungeon at midnight.
+Never kick a sleeping dog.
+Never kiss an animal. It may cause kissing disease.
+Never map the labyrinth.
+Never mind the monsters hitting you: they just replace the charwomen.
+Never ride a long worm.
+Never step on a cursed engraving.
+Never swim with a camera: there's nothing to take pictures of.
+Never trust a random generator in magic fields.
+Never use a wand of death.
+Never use your best weapon to engrave a curse.
+Never vomit on a door mat.
+No easy fighting with a heavy load!
+No level contains two shops. The maze is no level. So...
+No part of this fortune may be reproduced, stored in a retrieval system, ...
+No weapon is better than a crysknife.
+Not all rumors are as misleading as this one.
+Not even a spear will hit a Xorn.
+Now what is it that cures digestion?
+Nurses are accustomed to touch naked persons: they don't harm them.
+Nurses prefer undressed hackers.
+Nymphs and nurses like beautiful rings.
+Nymphs are blondes. Are you a gentleman?
+Nymphs are very pleased when you call them by their real name: Lorelei.
+Offering a unicorn a worthless piece of glass might prove to be fatal!
+Old hackers never die: young ones do.
+Old trees sometimes fall without a warning!
+Once your little dog will be a big dog, and you will be proud of it.
+One can even choke in a fortune cookie!
+One has to leave shops before closing time.
+One homunculus a day keeps the doctor away.
+One level further down somebody is getting killed, right now.
+One wand of concentration equals eight scrolls of create monster.
+Only Today! A dramatic price-cut on slightly used wands.
+Only a Nymph knows how to unlock chains.
+Only a dragon will never get a cold from a wand of cold.
+Only a real dummy would ever call his sword 'Elbereth'.
+Only a wizard can use a magic whistle.
+Only adventurers of evil alignment think of killing their dog.
+Only cave-women can catch a unicorn. And then only with a golden rope.
+Only chaotic evils kill sleeping monsters.
+Only david can find the zoo!
+Only real trappers escape traps.
+Only real wizards can write scrolls.
+Only wizards are able to zap a wand.
+Opening a tin is difficult, especially when you are not so strong!
+Opening a tin is difficult, especially when you attempt this bare handed!
+Operation coded OVERKILL has started now.
+Orcs and killer bees share their lifestyle.
+Orcs do not procreate in dark rooms.
+PLEASE ignore previous rumour.
+Plain nymphs are harmless.
+Playing billiards pays when you are in a shop.
+Polymorphing your dog probably makes you safer.
+Praying will frighten Demons.
+Punishment is a thing you call over yourself. So why complain?
+Pursue the monsters and you will be had indeed.
+Put on a ring of teleportation: it will take you away from onslaught.
+Rays aren't boomerangs, of course, but still...
+Read the manual before entering the cave - You might get killed otherwise.
+Reading Herbert will disgust you, but in one case it might be enlightening.
+Reading Tolkien might help you.
+Reading might change your vision.
+Reading might improve your scope.
+Relying on a dog might turn you in a dog addict.
+Reward your doggie with a giant Bat.
+Ropes are made from the long, blond hairs of dead Nymphs.
+Row (3x) that boat gently down the stream, Charon (4x), death is but a dream.
+Running is good for your legs.
+Rust monsters love water. There are potions they hate, however.
+Savings do include amnesia.
+Scorpions often hide under tripe rations.
+Screw up your courage! You've screwed up everything else.
+Scrolls of fire are useful against fog clouds.
+Second Law of Hacking: first in, first out.
+Selling and rebuying a wand will recharge it.
+Shopkeepers accept creditcards, as long as you pay cash.
+Shopkeepers are vegetarians: they only eat Swedes.
+Shopkeepers can't read, so what use is engraving in a shop?
+Shopkeepers can't swim.
+Shopkeepers have incredible patience.
+Shopkeepers often have strange names.
+Shopkeepers sometimes die from old age.
+Sleeping may increase your strength.
+Snakes are often found under worthless objects.
+Some Balrogs don't attack if you offer them a ring.
+Some mazes (especially small ones) have no solutions, says man 6 maze.
+Some monsters can be tamed. I once saw a hacker with a tame Dragon!
+Some potions are quite mind-expanding.
+Some questions Sphynxes ask just *don't* have any answers.
+Sometimes "mu" is the answer.
+Sometimes monsters are more likely to fight each other than attack you.
+Sorry, no fortune this time. Better luck next cookie!
+Spare your scrolls of make-edible until it's really necessary!
+Speed Kills (The Doors)
+Spinach, carrot, and a melon - a meal fit for a nurse!
+Stay clear of the level of no return.
+Suddenly the dungeon will collapse ...
+Surprise your dog with an acid blob!
+Tainted meat is even more sickening than poison!
+Take a long worm from the rear, according to its mate it's a lot more fun.
+Tame a troll and it will learn you fighting.
+Taming a postman may cause a system security violation.
+Taming is a gradual process of excercising and rewarding.
+Telepathy is just a trick: once you know how to do it, it's easy.
+Teleportation lessens your orientation.
+The "pray" command is not yet implemented.
+The Jackal only eats bad food.
+The Leprechaun Gold Tru$t is no division of the Magic Memory Vault.
+The Leprechauns hide their treasure in a small hidden room.
+The air is positively magic in here. Better wear a negative armor.
+The best equipment for your work is, of course, the most expensive.
+The emptiness of a ghost is too heavy to bear.
+The key to this game is that there are no keys.
+The longer the wand the better.
+The moon is not the only heavenly body to influence this game.
+The postman always rings twice.
+The proof of the quivering blob is in the eating thereof.
+The secret of wands of Nothing Happens: try again!
+The use of dynamite is dangerous.
+There are better information sources than fortune cookies.
+There are monsters of softening penetration.
+There are monsters of striking charity.
+There have been people like you in here; their ghosts seek revenge on you.
+There is a VIP-lounge on this level. Only first-class travellers admitted.
+There is a big treasure hidden in the zoo!
+There is a message concealed in each fortune cookie.
+There is a trap on this level!
+There is more magic in this cave than meets the eye.
+There is no business like throw business.
+There is no harm in praising a large dog.
+There is nothing like eating a Mimic.
+There seem to be monsters of touching benevolence.
+They say a gelatinous cube can paralyse you...
+They say that Elven cloaks absorb enchantments.
+They say that a dagger hits.
+They say that a dog avoids traps.
+They say that a dog can be trained to fetch objects.
+They say that a dog never steps on a cursed object.
+They say that a spear will hit a Dragon.
+They say that a spear will hit a Xorn.
+They say that a spear will hit a neo-otyugh. (Do YOU know what that is?)
+They say that a spear will hit an ettin.
+They say that a two-handed sword misses.
+They say that a unicorn might bring you luck.
+They say that an elven cloak may be worn over your armor.
+They say that an elven cloak protects against magic.
+They say that cavemen seldom find tins in the dungeon.
+They say that dead lizards protect against a cockatrice.
+They say that killing a shopkeeper brings bad luck.
+They say that monsters never step on a scare monster scroll.
+They say that only david can find the zoo!
+They say that shopkeepers often have a large amount of money in their purse.
+They say that the owner of the dungeon might change it slightly.
+They say that the use of dynamite is dangerous.
+They say that the walls in shops are made of extra hard material.
+They say that there is a big treasure hidden in the zoo!
+They say that there is a message concealed in each fortune cookie.
+They say that there is a trap on this level!
+They say that throwing food at a wild dog might tame him.
+They say that you can meet old friends in the caves.
+They say that you can't take your pick-axe into a shop.
+They say that you cannot trust scrolls of rumour.
+They say that you need a key in order to open locked doors.
+Third Law of Hacking: the last blow counts most.
+This dungeon is restroom equipped (for your convenience).
+This fortune cookie is property of Fortune Cookies, Inc.
+This is not a fortune.
+This is the Leprechaun Law: every purse has a price.
+Throwing food at a wild dog might tame him.
+Tin openers are rare indeed.
+Tired of irritating bats? Try a scroll of silence.
+To hit or not to hit, that is the question.
+To reach heaven, escape the dungeon while wearing a ring of levitation.
+Tranquillizers might get you killed.
+Travel fast, use some magic speed!
+Tripe on its own is revolting, but with onions it's delicious!
+Try hacking in the wee hours: you will have more room.
+Try the fall back end run play against ghosts.
+Ulch, that meat was painted.
+Unwanted mail? Sell it to the bookshop!
+Vampires hate garlic.
+Vault guards always make sure you aren't a shopkeeper.
+Vault guards never disturb their Lords.
+Visitors are requested not to apply genocide to shopkeepers.
+WARNING from H.M. Govt: Quaffing may be dangerous to your health.
+Wanna fly? Eat a bat.
+Want a hint? Zap a wand of make invisible on your weapon!
+Want fun? Throw a potion in a pool and go swimming!
+Want to conserve your dead corpses? Go to the tin factory!
+Wanted: shopkeepers. Send a scroll of mail to: Mage of Yendor/Level 35/Dungeon.
+Warning: end of file 'fortunes' reached.
+Warning: people who eat dragons can go to hell!!
+Watch your steps on staircases.
+Wear armor, going naked seems to offend public decency in here.
+What a pity, you cannot read it!
+What do you think is the use of dead lizards?
+What do you think would be the use of a two handed sword called "Orcrist" ?
+When a piercer drops in on you, you will be tempted to hit the ceiling!
+When in a maze follow the right wall and you will never get lost.
+When in a shop, do as shopkeepers do.
+When punished, watch your steps on the stairs!
+When you have a key, you don't have to wait for the guard.
+When you have seen one killer bee, you have seen them all.
+When your dog follows you through a trap door, don't hit it!
+Where do you think all those demons come from? From Hell, of course.
+Where do you think the hell is located? It must be deep, deep down.
+Who should ever have thought one could live from eating fog clouds?
+Why a "2" for the postman? Well, how many times does he ring?
+Why should one ever throw an egg to a cockatrice?
+Why would anybody in his sane mind engrave "Elbereth" ?
+Wish for a master key and open the Magic Memory Vault!
+Wish for a pass-key and pass all obstacles!
+Wish for a skeleton-key and open all doors!
+Wishing too much may bring you too little.
+Wizards do not sleep.
+You are heading for head-stone for sure.
+You are just the kind of bad food some monsters like to digest.
+You can always wear an elven cloak.
+You can eat what your dog can eat.
+You can get a genuine Amulet of Yendor by doing the following: -- more --
+You can't get rid of a cursed plate mail with a can-opener.
+You can't leave a shop through the back door: there ain't one!
+You cannot ride a long worm.
+You cannot trust scrolls of rumour.
+You die...
+You feel greedy and want more gold? Why don't you try digging?
+You feel like someone is pulling your leg.
+You have to outwit a Sphynx or pay her.
+You may get rich selling letters, but beware of being blackmailed!
+You may have a kick from kicking a little dog.
+You might choke on your food by eating fortune cookies.
+You might cut yourself on a long sword.
+You might trick a shopkeeper if you're invisible.
+You need a key in order to open locked doors.
+You offend Shai-Hulud by sheathing your crysknife without having drawn blood.
+You want to regain strength? Two levels ahead is a guesthouse!
+You'll need a spear if you want to attack a Dragon.
+You've got to know how to put out a yellow light.
+Your dog can buy cheaper than you do.
+Zapping a wand of Nothing Happens doesn't harm you a bit.
+Zapping a wand of undead turning might bring your dog back to life.
diff --git a/hangman/Makefile b/hangman/Makefile
new file mode 100644
index 00000000..bdb1d2c4
--- /dev/null
+++ b/hangman/Makefile
@@ -0,0 +1,13 @@
+# @(#)Makefile 5.7 (Berkeley) 5/11/90
+
+PROG= hangman
+SRCS= endgame.c extern.c getguess.c getword.c main.c playgame.c \
+ prdata.c prman.c prword.c setup.c
+MAN6= hangman.0
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermlib -lcompat
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
+
+
diff --git a/hangman/endgame.c b/hangman/endgame.c
new file mode 100644
index 00000000..4b08d532
--- /dev/null
+++ b/hangman/endgame.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)endgame.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * endgame:
+ * Do what's necessary at the end of the game
+ */
+endgame()
+{
+ register char ch;
+
+ prman();
+ if (Errors >= MAXERRS)
+ Errors = MAXERRS + 2;
+ prword();
+ prdata();
+ move(MESGY, MESGX);
+ if (Errors > MAXERRS)
+ printw("Sorry, the word was \"%s\"\n", Word);
+ else
+ printw("You got it!\n");
+
+ for (;;) {
+ mvaddstr(MESGY + 1, MESGX, "Another word? ");
+ leaveok(stdscr, FALSE);
+ refresh();
+ if ((ch = readch()) == 'n')
+ die();
+ else if (ch == 'y')
+ break;
+ mvaddstr(MESGY + 2, MESGX, "Please type 'y' or 'n'");
+ }
+
+ leaveok(stdscr, TRUE);
+ move(MESGY, MESGX);
+ addstr("\n\n\n");
+}
diff --git a/hangman/extern.c b/hangman/extern.c
new file mode 100644
index 00000000..1dd593de
--- /dev/null
+++ b/hangman/extern.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)extern.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "hangman.h"
+
+bool Guessed[26];
+
+char Word[BUFSIZ],
+ Known[BUFSIZ],
+ *Noose_pict[] = {
+ " ______",
+ " | |",
+ " |",
+ " |",
+ " |",
+ " |",
+ " __|_____",
+ " | |___",
+ " |_________|",
+ NULL
+ };
+
+int Errors,
+ Wordnum = 0;
+
+double Average = 0.0;
+
+ERR_POS Err_pos[MAXERRS] = {
+ { 2, 10, 'O' },
+ { 3, 10, '|' },
+ { 4, 10, '|' },
+ { 5, 9, '/' },
+ { 3, 9, '/' },
+ { 3, 11, '\\' },
+ { 5, 11, '\\' }
+};
+
+FILE *Dict = NULL;
+
+off_t Dict_size;
diff --git a/hangman/getguess.c b/hangman/getguess.c
new file mode 100644
index 00000000..c363e051
--- /dev/null
+++ b/hangman/getguess.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getguess.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * getguess:
+ * Get another guess
+ */
+getguess()
+{
+ register int i;
+ register int ch;
+ register bool correct;
+
+ leaveok(stdscr, FALSE);
+ for (;;) {
+ move(PROMPTY, PROMPTX + sizeof "Guess: ");
+ refresh();
+ ch = readch();
+ if (isalpha(ch)) {
+ if (isupper(ch))
+ ch = tolower(ch);
+ if (Guessed[ch - 'a'])
+ mvprintw(MESGY, MESGX, "Already guessed '%c'", ch);
+ else
+ break;
+ }
+ else if (ch == CTRL('D'))
+ die();
+ else
+ mvprintw(MESGY, MESGX, "Not a valid guess: '%s'",
+ unctrl(ch));
+ }
+ leaveok(stdscr, TRUE);
+ move(MESGY, MESGX);
+ clrtoeol();
+
+ Guessed[ch - 'a'] = TRUE;
+ correct = FALSE;
+ for (i = 0; Word[i] != '\0'; i++)
+ if (Word[i] == ch) {
+ Known[i] = ch;
+ correct = TRUE;
+ }
+ if (!correct)
+ Errors++;
+}
+
+/*
+ * readch;
+ * Read a character from the input
+ */
+readch()
+{
+ register int cnt, r;
+ auto char ch;
+
+ cnt = 0;
+ for (;;) {
+ if (read(0, &ch, sizeof ch) <= 0)
+ {
+ if (++cnt > 100)
+ die();
+ }
+ else if (ch == CTRL('L')) {
+ wrefresh(curscr);
+ mvcur(0, 0, curscr->_cury, curscr->_curx);
+ }
+ else
+ return ch;
+ }
+}
diff --git a/hangman/getword.c b/hangman/getword.c
new file mode 100644
index 00000000..35c51979
--- /dev/null
+++ b/hangman/getword.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getword.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "hangman.h"
+
+# if pdp11
+# define RN (((off_t) rand() << 16) | (off_t) rand())
+# else
+# define RN rand()
+# endif
+
+/*
+ * getword:
+ * Get a valid word out of the dictionary file
+ */
+getword()
+{
+ register FILE *inf;
+ register char *wp, *gp;
+
+ inf = Dict;
+ for (;;) {
+ fseek(inf, abs(RN % Dict_size), 0);
+ if (fgets(Word, BUFSIZ, inf) == NULL)
+ continue;
+ if (fgets(Word, BUFSIZ, inf) == NULL)
+ continue;
+ Word[strlen(Word) - 1] = '\0';
+ if (strlen(Word) < MINLEN)
+ continue;
+ for (wp = Word; *wp; wp++)
+ if (!islower(*wp))
+ goto cont;
+ break;
+cont: ;
+ }
+ gp = Known;
+ wp = Word;
+ while (*wp) {
+ *gp++ = '-';
+ wp++;
+ }
+ *gp = '\0';
+}
+
+/*
+ * abs:
+ * Return the absolute value of an integer
+ */
+off_t
+abs(i)
+off_t i;
+{
+ if (i < 0)
+ return -(off_t) i;
+ else
+ return (off_t) i;
+}
diff --git a/hangman/hangman.6 b/hangman/hangman.6
new file mode 100644
index 00000000..8743b090
--- /dev/null
+++ b/hangman/hangman.6
@@ -0,0 +1,50 @@
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)hangman.6 6.3 (Berkeley) 6/23/90
+.\"
+.TH HANGMAN 6 "June 23, 1990"
+.UC 4
+.SH NAME
+hangman \- Computer version of the game hangman
+.SH SYNOPSIS
+.B /usr/games/hangman
+.SH DESCRIPTION
+In
+.I hangman,
+the computer picks a word from the on-line word list
+and you must try to guess it.
+The computer keeps track of which letters have been guessed
+and how many wrong guesses you have made on the screen in a graphic fashion.
+.SH FILES
+/usr/dict/words On-line word list
+.SH AUTHOR
+Ken Arnold
diff --git a/hangman/hangman.h b/hangman/hangman.h
new file mode 100644
index 00000000..c41e5f82
--- /dev/null
+++ b/hangman/hangman.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)hangman.h 5.5 (Berkeley) 2/28/91
+ */
+
+# include <curses.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <ctype.h>
+# include <signal.h>
+# include "pathnames.h"
+
+# define MINLEN 6
+# define MAXERRS 7
+
+# define MESGY 12
+# define MESGX 0
+# define PROMPTY 11
+# define PROMPTX 0
+# define KNOWNY 10
+# define KNOWNX 1
+# define NUMBERY 4
+# define NUMBERX (COLS - 1 - 26)
+# define AVGY 5
+# define AVGX (COLS - 1 - 26)
+# define GUESSY 2
+# define GUESSX (COLS - 1 - 26)
+
+
+typedef struct {
+ short y, x;
+ char ch;
+} ERR_POS;
+
+extern bool Guessed[];
+
+extern char Word[], Known[], *Noose_pict[];
+
+extern int Errors, Wordnum;
+
+extern double Average;
+
+extern ERR_POS Err_pos[];
+
+extern FILE *Dict;
+
+extern off_t Dict_size;
+
+void die();
+
+off_t abs();
diff --git a/hangman/main.c b/hangman/main.c
new file mode 100644
index 00000000..47bffb5a
--- /dev/null
+++ b/hangman/main.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * This game written by Ken Arnold.
+ */
+main()
+{
+ void die();
+
+ initscr();
+ signal(SIGINT, die);
+ setup();
+ for (;;) {
+ Wordnum++;
+ playgame();
+ Average = (Average * (Wordnum - 1) + Errors) / Wordnum;
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * die:
+ * Die properly.
+ */
+void
+die()
+{
+ mvcur(0, COLS - 1, LINES - 1, 0);
+ endwin();
+ putchar('\n');
+ exit(0);
+}
diff --git a/hangman/pathnames.h b/hangman/pathnames.h
new file mode 100644
index 00000000..ebbaefd8
--- /dev/null
+++ b/hangman/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 6/1/90
+ */
+
+#define _PATH_DICT "/usr/share/dict/words"
diff --git a/hangman/playgame.c b/hangman/playgame.c
new file mode 100644
index 00000000..84eb3913
--- /dev/null
+++ b/hangman/playgame.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)playgame.c 5.3 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * playgame:
+ * play a game
+ */
+playgame()
+{
+ register bool *bp;
+
+ getword();
+ Errors = 0;
+ bp = Guessed;
+ while (bp < &Guessed[26])
+ *bp++ = FALSE;
+ while (Errors < MAXERRS && index(Known, '-') != NULL) {
+ prword();
+ prdata();
+ prman();
+ getguess();
+ }
+ endgame();
+}
diff --git a/hangman/prdata.c b/hangman/prdata.c
new file mode 100644
index 00000000..5ac6e0f3
--- /dev/null
+++ b/hangman/prdata.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)prdata.c 5.3 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * prdata:
+ * Print out the current guesses
+ */
+prdata()
+{
+ register bool *bp;
+
+ move(GUESSY, GUESSX + sizeof "Guessed: ");
+ bp = Guessed;
+ while (bp < &Guessed[26])
+ if (*bp++)
+ addch((bp - Guessed) + 'a' - 1);
+ clrtoeol();
+ mvprintw(NUMBERY, NUMBERX + sizeof "Word #: ", "%d", Wordnum);
+ mvprintw(AVGY, AVGX + sizeof "Current Average: ", "%.3f",
+ (Average * (Wordnum - 1) + Errors) / Wordnum);
+ mvprintw(AVGY + 1, AVGX + sizeof "Overall Average: ", "%.3f", Average);
+}
diff --git a/hangman/prman.c b/hangman/prman.c
new file mode 100644
index 00000000..a5225967
--- /dev/null
+++ b/hangman/prman.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)prman.c 5.3 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * prman:
+ * Print out the man appropriately for the give number
+ * of incorrect guesses.
+ */
+prman()
+{
+ register int i;
+
+ for (i = 0; i < Errors; i++)
+ mvaddch(Err_pos[i].y, Err_pos[i].x, Err_pos[i].ch);
+ while (i < MAXERRS) {
+ mvaddch(Err_pos[i].y, Err_pos[i].x, ' ');
+ i++;
+ }
+}
diff --git a/hangman/prword.c b/hangman/prword.c
new file mode 100644
index 00000000..1136cc8a
--- /dev/null
+++ b/hangman/prword.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)prword.c 5.3 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * prword:
+ * Print out the current state of the word
+ */
+prword()
+{
+ move(KNOWNY, KNOWNX + sizeof "Word: ");
+ addstr(Known);
+ clrtoeol();
+}
diff --git a/hangman/setup.c b/hangman/setup.c
new file mode 100644
index 00000000..a72df8e1
--- /dev/null
+++ b/hangman/setup.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)setup.c 5.4 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+# include "hangman.h"
+
+/*
+ * setup:
+ * Set up the strings on the screen.
+ */
+setup()
+{
+ register char **sp;
+ static struct stat sbuf;
+
+ noecho();
+ crmode();
+
+ mvaddstr(PROMPTY, PROMPTX, "Guess:");
+ mvaddstr(GUESSY, GUESSX, "Guessed:");
+ mvaddstr(NUMBERY, NUMBERX, "Word #:");
+ mvaddstr(AVGY, AVGX, "Current Average:");
+ mvaddstr(AVGY + 1, AVGX, "Overall Average:");
+ mvaddstr(KNOWNY, KNOWNX, "Word: ");
+
+ for (sp = Noose_pict; *sp != NULL; sp++) {
+ move(sp - Noose_pict, 0);
+ addstr(*sp);
+ }
+
+ srand(time(NULL) + getpid());
+ if ((Dict = fopen(_PATH_DICT, "r")) == NULL) {
+ perror(_PATH_DICT);
+ endwin();
+ exit(1);
+ }
+ fstat(fileno(Dict), &sbuf);
+ Dict_size = sbuf.st_size;
+}
diff --git a/larn/COPYRIGHT b/larn/COPYRIGHT
new file mode 100644
index 00000000..43ff637d
--- /dev/null
+++ b/larn/COPYRIGHT
@@ -0,0 +1,6 @@
+This entire subtree is copyright by Noah Morgan.
+The following copyright notice applies to all files found here. None of
+these files contain AT&T proprietary source code.
+_____________________________________________________________________________
+
+/* Larn is copyrighted 1986 by Noah Morgan. */
diff --git a/larn/Fixed.Bugs b/larn/Fixed.Bugs
new file mode 100644
index 00000000..d2acae0a
--- /dev/null
+++ b/larn/Fixed.Bugs
@@ -0,0 +1,216 @@
+This is a list of the fixes/enhancements made to larn V11.0 in Version 12.0.
+(Version numbers consist of 2 parts: ver.subver. When the save file format
+changes, ver must be bumped. This is why the next release of Larn is 12.0
+and not 11.1. This is used in the savefile routines to check for out-of-date
+save files). This list was mainly meant to be a record of what changed,
+for my own sanity. It's included for your benefit (Warning: SPOILER!):
+
+0. lprintf() in fileio.c (now called io.c) has been changed to use varargs
+ so that its variable number of arguments usage is now portable. Pyramids
+ primarily had this problem.
+
+1. Panic handler was added to signal.c. This routine catches fatal errors
+ like segmentation faults, bus errors, illegal instructions, etc., and
+ trys to performs a savegame() before dumping core. This helps prevent
+ the loss of a good game due to a game malfunction. Also, the name of the
+ signal received is printed, instead of just its number.
+
+2. The version number of the program is now selectable from the Makefile.
+ see the symbols VER and SUBVER.
+
+3. When at an altar, pray and donate 3000000000 gp. and ye used to receive
+ a whopping amount of gold due to a wraparound problem with the signed
+ ints. This has been fixed by using unsigned longs when asking for money
+ amounts.
+
+4. It was possible that when compiled with work hours checking, checkpointing
+ enabled, and having "play-day-play" in the .larnopts file a segmentation
+ fault would occur at its first attempt to do a checkpoint. This was due
+ to an improperly declared savefilename array in tok.c. This has been fixed.
+
+5. on level H, casting a missile weapon (mle cld ssp bal lit) off the edge of
+ the level would mess up the display, as it didn't know when to stop. This
+ is needless to say, fixed. Absolute bounds are now in effect for missile
+ type spells, see godirect() in monster.c.
+
+6. The create monster routine will now create monsters in random positions
+ around the player. Before, the 1st one would always be created to the
+ upper left.
+
+7. If you vpr or lit at a throne, it would summon a gnome king that you
+ would have to deal with. However, as each throne has only one king with it,
+ successive vpr's should not create more gnome kings. Presently, successive
+ vpr's will create more kings. This has been fixed.
+
+8. The mechanism to manage spheres of annihilation has been reworked to provide
+ a cleaner design and to eliminate some possible problems.
+
+9. The spell gen (genocide monsters) has been implemented.
+
+10. When dropping a ring of strength and having been weakened to STR=3 the
+ player might end up with a negative strength. Strength is now stored
+ in 2 variables, real strength, and strength bonuses. Only real strength
+ can now be weakened down to a minimum of 3, so unless you have a ring of
+ strength -3 or less, strengths below 3 should not occur.
+
+11. larn -h will now print out a list of all available command line options.
+
+12. larn -o<optsfile> now lets you specify a .larnopts file on the command
+ line. This was necessary as part of the solution to number 14 below.
+
+13. The "savefile:" statement has been aded to the .larnopts format to allow
+ specifying the savefilename (full path) for the savegame operation.
+ This too was needed as part of # 14 below.
+
+14. A player id facility has been added to larn. The complaint was that
+ the game used the userid to order the scoreboard, thus only one scoreboard
+ entry was allowed for each userid. If the compile time symbol UIDSCORE
+ is defined at compilation time (see Makefile), this will still be true.
+ However, if this define is omitted, the game will create and manage a
+ file called ".playerids" where names are taken from the specified
+ .larnopts file (now a command line option) and assigned a unique playerid.
+ playerid's will now be used to govern scoreboard entry posting. This
+ feature makes it easy for one person to have many characters, each
+ appearing on the scoreboard. Be kind to your fellow players!
+ The philosophy of one score per player gives more players the opportunity
+ to bask in glory for all to see!
+
+15. It is no longer required that the player be WIZID to create the scoreboard
+ or to examine the logfile. Anyone with the correct wizard's password can
+ now use these command line options (password is only needed to create/clear
+ the scoreboard). If you want to prevent players from zeroing the
+ scoreboard, change the wizard's password. (in config.c) By the way, wizards
+ may be alot of fun, but they are prevented from being placed on any
+ scoreboard. (for clarification)
+
+16. Monsters now have intelligence, that is some of them. This determines if
+ the monster moves using the previously stupid movement method, or by using
+ the new IMM (intelligent monster movement) algorithm. With IMM, monsters
+ will move around corners, avoid pits, traps, etc. With increasing levels
+ of difficulty, more monsters will be using IMM. Beware of IMM when
+ aggravated! Those little beasties can really find you!
+
+17. Added the scroll of life protection.
+
+18. Larn now consults the file ".holiday" to check for holidays if the TIMECHECK
+ option (no playing during working hours) is enabled. Before, larn knew
+ nothing about holidays. It should now let people play if it is a holiday.
+ The format for a .holiday entry is: "mmm dd yyyy comments . . .".
+
+19. In nap() and napms() it is possible that with nap(0) or napms(0) there
+ would be an infinite loop and the game would hang. The case of nap(0)
+ is now looked for.
+
+20. The granularity of gold piles has been increased. iarg[] has been changed
+ from char's to short's, so instead of 255 x 10^n granularity we now have
+ 32767 x 10^n granularity. This also means more than 255000 gp can be
+ dropped in one place. Not realistic, but it prevents a worthless
+ annoyance. Who said games were supposed to be realistic?
+
+21. Termcap capability has been added to larn. If the symbol VT100 is defined
+ in the makefile, the game will be compiled to use only VT100 compatible
+ terminals (Much more efficient). If the symbol VT100 is omitted, the game
+ will be compiled to use the termcap entry for whatever terminal you are
+ using. This involves an extra layer of output interpretation, as every
+ byte sent to the terminal must be inspected for control tokens.
+ Only 3 termcap entries need be found for the game to be functional:
+ CM (cursor movement), CE (clear to end of line), and CL (clear screen).
+ For a better display, the following are optional: AL (insert line), DL
+ (delete line), SO (Standout begin), SE (Standout end), and CD (clear to end
+ of screen). The .larn.help file was left as is, with VT100 escape
+ sequences in it. If the termcap version of larn reads it, it is translated
+ for the desired terminal type. The .mail60* files have been removed, and
+ their text is now included in bill.c so it can be used with any terminal.
+ Note: If compiled for termcap, and using a VT100, the display will act
+ a little different. This is because the VT100 does not have insert line/
+ delete line codes, and the scrolling region must be simulated with vertical
+ wraparound instead of scrolling. Thanks goes to Michiel Huisjes for the
+ original termcap patch.
+
+22. When playing as wizard, if you go down stairs on 10 or V3, or up stairs
+ on H, 1, or V1, etc. you would be placed in a phantom zone where the display
+ was really weird ([-1] subscripting), and would eventually lead to a
+ segmentation fault. Stairs and volcano shafts now check for the level
+ they are being used on.
+
+23. In response to some sites having only unsigned chars (flame the
+ manufacturer), the chars that were used to store positive and negative
+ numbers have been changed to shorts. This includes diroffx[], diroffy[],
+ iarg[][][], ivenarg[], and some others. I believe the changes are correct,
+ but I have none of these machines to try it out on. (Volunteers?)
+
+24. The function fullhit(n) in monster.c was supposed to return the damage
+ done by n full hits on a monster. It only returned the damage for ONE hit,
+ thus severely limiting the usefulness of the web and sle spells.
+
+25. Someone said that they were getting segmentation faults when they were
+ reading scrolls as the wizard. I couldn't find the problem, which may
+ have had something to do with the signed char problem mentioned above.
+ However, I've added a check in read_scroll() and quaff_potion() to trap
+ any scroll or potion types that are not in the game.
+
+26. "vt125" has been added to the acceptable terminal list
+ (checked only if compiled with -DVT100).
+
+27. In savegame() and restoregame(), there was a 6 hardwired into the i/o
+ statements which assumed the size of struct cel was 6. On some machines
+ this caused the rightmost part of each level to not be saved in a savefile.
+ These 6's have been replaced with sizeof(struct cel), and should now be
+ portable.
+
+28. The option "no-beep" has been added to the .larnopts file. When specified,
+ beeping is inhibited at the terminal.
+
+29. When becoming wizard, no longer to you wear the ring of protection, and
+ null scrolls and potions are no longer created.
+
+30. Many spelling errors have been fixed, both in player messages, and in the
+ code itself. A thanks goes to Mars Gralia who sent me a detailed list of
+ the mistakes.
+
+31. When a player wins a game, if getlogin() fails, a segmentation fault will
+ result, because the NULL returned from getlogin() is used as a pointer.
+ This call has been replaced (now using loginname already determined).
+ Also, the mail creation upon winning has been rewritten, mainly to allow
+ termcapping of the text.
+
+32. The Larn Revenue Service will now always appear on level H. Before, it
+ was only created if the player had outstanding taxes. In that multiple
+ save files per player are now more possible, this was seen as incorrect.
+
+33. Input buffer flushing is now in effect. If the input char queue exceeds
+ 5 bytes, the excess is discarded. Also, if the player hits or gets hit
+ all input bytes are flushed (within 1). This relieves the situation
+ where many moves have been typed ahead of the display and the player keeps
+ getting hit while the queue of moves is processed.
+
+34. When a savefile has been altered, a warning message is displayed to the
+ effect that you've cheated, and you will not be placed on the normal
+ scoreboard. If you then save the game, and start 'er up again, memory
+ of the cheating was lost. This has been fixed, by letting the scoreboard
+ routines consult the cheating flag. Also, the I node number of the
+ savefile is written into the savefile, so cp'ing, etc., will avail the
+ cheater not. If high security is needed, the game should be run suid.
+ This suid mode has not been made the default because most installations
+ do not want to install it that way.
+
+35. The sources have been run through lint, and most of lint's complaints have
+ been taken care of. An attempt was made to adjust the code for 16 bit int
+ machines. Many casts to long have been put in. I don't know if it will
+ run on a 16 bitter, but it should be closer to that end.
+
+36. When larn starts up, if it can't find the scoreboard, it will now make a
+ blank one instead of complaining that there is no scoreboard. It is not
+ necessary to do "larn -c" to initially create the scoreboard.
+
+37. When listing out the logfile (larn -l), the error message "error reading
+ from input file" has been fixed. Also, the date & time of a player's
+ demise is now included in the logfile.
+
+38. When casting web or sle into a mirror, the game will no longer bash the
+ player. Instead, the player will either fall asleep or get stuck in his
+ web.
+
+39. Items like cookies, books, chests, swords of slashing, and Bessmann's
+ flailing hammer can now be sold at the trading post.
+
diff --git a/larn/Makefile b/larn/Makefile
new file mode 100644
index 00000000..b2ab2ae2
--- /dev/null
+++ b/larn/Makefile
@@ -0,0 +1,69 @@
+# @(#)Makefile 5.9 (Berkeley) 7/25/90
+
+# EXTRA
+# Incorporates code to gather additional performance statistics
+# SYSV
+# Use system III/V (instead of V7) type ioctl calls
+# BSD
+# Use BSD specific features (mostly timer and signal stuff)
+# BSD4.1
+# Use BSD4.1 to avoid some 4.2 dependencies (must be used with
+# BSD above; do not mix with SYSV)
+# HIDEBYLINK
+# If defined, the program attempts to hide from ps
+# DOCHECKPOINTS
+# If not defined, checkpoint files are periodically written by the
+# larn process (no forking) if enabled in the .larnopts description
+# file. Checkpointing is handy on an unreliable system, but takes
+# CPU. Inclusion of DOCHECKPOINTS will cause fork()ing to perform the
+# checkpoints (again if enabled in the .larnopts file). This usually
+# avoids pauses in larn while the checkpointing is being done (on
+# large machines).
+# VER
+# This is the version of the software, example: 12
+# SUBVER
+# This is the revision of the software, example: 1
+# FLUSHNO=#
+# Set the input queue excess flushing threshold (default 5)
+# NOVARARGS
+# Define for systems that don't have varargs (a default varargs will
+# be used).
+# MACRORND
+# Define to use macro version of rnd() and rund() (fast and big)
+# UIDSCORE
+# Define to use user id's to manage scoreboard. Leaving this out will
+# cause player id's from the file ".playerids" to be used instead.
+# (.playerids is created upon demand). Only one entry per id # is
+# allowed in each scoreboard (winning & non-winning).
+# VT100
+# Compile for using vt100 family of terminals. Omission of this
+# define will cause larn to use termcap, but it will be MUCH slower
+# due to an extra layer of output interpretation. Also, only VT100
+# mode allows 2 different standout modes, inverse video, and bold video.
+# And only in VT100 mode is the scrolling region of the terminal used
+# (much nicer than insert/delete line sequences to simulate it, if
+# VT100 is omitted).
+# NONAP
+# This causes napms() to return immediately instead of delaying n
+# milliseconds. This define may be needed on some systems if the nap
+# stuff does not work correctly (possible hang). nap() is primarilly
+# used to delay for effect when casting missile type spells.
+# NOLOG
+# Turn off logging.
+
+PROG= larn
+MAN6= larn.0
+CFLAGS+=-DBSD -DVER=12 -DSUBVER=0 -DNONAP
+SRCS= main.c object.c create.c tok.c display.c global.c data.c io.c \
+ monster.c store.c diag.c help.c config.c nap.c bill.c scores.c \
+ signal.c moreobj.c movem.c regen.c fortune.c savelev.c
+DPADD= ${LIBTERM} ${LIBCOMPAT}
+LDADD= -ltermcap -lcompat
+HIDEGAME=hidegame
+
+beforeinstall:
+ (cd ${.CURDIR}/datfiles; install -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ larnmaze larnopts lfortune larn.help \
+ ${DESTDIR}/usr/share/games/larn)
+
+.include <bsd.prog.mk>
diff --git a/larn/OWNER b/larn/OWNER
new file mode 100644
index 00000000..06aaf47a
--- /dev/null
+++ b/larn/OWNER
@@ -0,0 +1,3 @@
+ Noah Morgan
+ panda!condor!noah
+ GenRad Inc. Bolton, MA
diff --git a/larn/README b/larn/README
new file mode 100644
index 00000000..71e477b3
--- /dev/null
+++ b/larn/README
@@ -0,0 +1,148 @@
+Larn is a dungeon type game program. Larn is a adventure/action game similar
+in concept to rogue or hack, but with a much different feel.
+Try it, you'll like it!
+
+You will have to edit the Makefile to reflect your configuration. Define
+LARNHOME as the place where the larn auxiliary files will reside, and
+BINDIR as the place where the larn executable should be placed. Type
+"make" to compile, or "make all" to compile and install ("make install"
+does just the install).
+
+Here's a list of what is in each of the various source files:
+
+Fixed.Bugs this is a list of the things that were changed
+ since ver 11.0
+Makefile makefile script to compile the program
+Make.lint makefile script to run larn sources through lint
+README this is what you are now reading
+bill.c code for the letters of praise if player wins
+config.c data definitions for the installation dependent data --
+ savefilenames, where the scorefiles are, etc.
+create.c code to create the dungeon and all objects
+data.c data definitions for the game -- no code here
+diag.c code to produce diagnostic data for wizards, & savegame stuff
+display.c code to update the display on the screen
+fortune.c code for the fortune cookies
+global.c code for globally used functions that are specific to larn
+header.h constant and structure definitions
+help.c code for the help screens in the game of larn
+.holidays data file which lists upcoming holidays
+io.c code to handle file and terminal i/o
+.larn.help.uue larn help file (UUENCODED)
+.larnmaze data file for pre-made mazes
+.larnopts a sample .larnopts option data file
+.lfortune data file which contains the hints
+main.c code for the main command control and parsing
+monster.c code to handle attack and defense modes with monsters
+moreobj.c code for the fountains, altars, thrones
+movem.c code to move the monsters around the dungeon
+nap.c code to sleep for less than a second
+object.c code to handle objects in the dungeon
+regen.c code to regenerate the player and advance game time
+savelev.c code to get/put a level from level storage into working
+ level memory
+scores.c code to process and manage the scoreboard
+signal.c code to handle UNIX signals that are trapped
+store.c code for the larn thrift shoppe, bank, trading post, lrs
+tok.c code for the input front end and options file processing
+
+To find out how to play the game, run it and type in a '?' to get the help
+screens. By the way, the wizards password is "pvnert(x)" and to become wizard
+type in an underscore, you are then prompted for the password. Wizards are
+non-scoring characters that get enlightenment, everlasting expanded
+awareness, and one of every object in the game. They help the author to debug
+the game.
+
+Note regarding the wizard id: If you are using userid's, then WIZID must be
+set to the userid of the person who can become wizard. If you are using
+player id's, WIZID must be set to the playerid (edit file .playerids if needed)
+of the player who can become wizard.
+
+You may want to clear out the scoreboard. The command "larn -c" will make a
+new scoreboard. It will prompt you for the wizards password.
+
+BUGS & FIXES:
+
+James McNamara has volunteered to maintain the latest sources, and provide
+latest bug fixes to anyone who asks. Both James and I will field requests for
+sources, for those who ask.
+
+ ___ Prince of Gems (alias Noah Morgan)
+ /. \ USENET: panda!condor!noah
+ \ / at GenRad Inc. Bolton MA
+ \ /
+ v
+
+Below is some additional info about the installation of larn:
+
+Install: Notes on the game LARN installation.
+Larn is copyrighted 1986 by Noah Morgan.
+This file (below) originally by James D. McNamara, last update 7/27/86 by nm
+
+THIS DISTRIBUTION:
+
+ You should receive six (6) shar files, which are:
+
+ larn.part-1
+ larn.part-2
+ larn.part-3
+ larn.part-4
+ larn.part-5
+ larn.part-6
+
+I. Use /bin/sh (or your system equivalent) to "unravel" shar files
+ larn.part-1, ..., larn.part-6. I suggest you do this directly
+ into $LARNHOME (See Section III.). Notable files:
+
+ README - The author's how-to.
+ MANIFEST - Files you should have.
+
+III. Edit a copy of "Makefile" and leave the edited version in $LARNHOME.
+
+All the "configuration" options are tidily near the top of the "Makefile."
+Here are the ones you probably will want to edit:
+
+LARNHOME I specified (literally) the directory, with path from root,
+ where "larn" will reside. This included where I put the *.c files,
+ it is where the *.o files ended up, as well as all data and *.h files.
+ i suspect the *.c and intallation-documentation files can be moved off,
+ but the data and bits must all remain here for execution.
+
+BINDIR I specified (literally) the directory, with path from root,
+ where the executable "larn" will reside. The "Makefile" will dump
+ the "a.out", named "larn", in this directory. My BINDIR was not
+ my LARNHOME, so $BINDIR/larn was the ONLY file dumed here. You'll
+ probably have to chmod it for public execute, etc.
+
+
+OPTIONS This is how *I* specified them... they are documented in-line:
+ OPTIONS = -DWIZZARD -DWIZID=157 -DEXTRA -DBSD -DSAVEINHOME
+
+IV. Compile the bugger. Read "README" before you do. You have a couple
+ of options here:
+
+ make - will not install, suspect good for updates.
+ make all - compile (and) intall
+ make install - just install
+
+ I did "make" and then "make install" -- seems to work "ok", but
+ "make all" probably safer, if I had known. Note that "Makefile"
+ is the default file for "make."
+
+V. Execute and have fun. If wizard code "ok", larn -c will refresh the
+ scoreboard. Play and win (or get killed) to put somebody on the
+ scoreboard.
+
+VI. BUGS and FIXES.
+
+ Please forward any bug-fixes in these regards to me (or Noah), so I may
+ compile a fix-list for other installers. Thanks.
+
+Regards,
+===============================================================================
+James D. McNamara CSNET: jim@bu-cs
+ ARPANET: jim%bu-cs@csnet-relay
+ UUCP: ...harvard!bu-cs!jim
+ BITNET: jim%bu-cs%csnet-relay.arpa@wiscvm
+===============================================================================
+
diff --git a/larn/bill.c b/larn/bill.c
new file mode 100644
index 00000000..3926a2e5
--- /dev/null
+++ b/larn/bill.c
@@ -0,0 +1,132 @@
+#include "header.h"
+/* bill.c "Larn is copyrighted 1986 by Noah Morgan. */
+static char mail600[32];
+/*
+ * function to create the tax bill for the user
+ */
+static int pid;
+static letter1()
+ {
+ sprintf(mail600,"/tmp/#%dmail600",pid); /* prepare path */
+ if (lcreat(mail600) < 0) { write(1,"can't write 600 letter\n",23); return(0);}
+ lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
+ standout("From:"); lprcat(" the LRS (Larn Revenue Service)\n");
+ standout("\nSubject:"); lprcat(" undeclared income\n");
+ lprcat("\n We heard you survived the caverns of Larn. Let me be the");
+ lprcat("\nfirst to congratulate you on your success. It is quite a feat.");
+ lprcat("\nIt must also have been very profitable for you.");
+ lprcat("\n\n The Dungeon Master has informed us that you brought");
+ lprintf("\n%d gold pieces back with you from your journey. As the",(long)c[GOLD]);
+ lprcat("\ncounty of Larn is in dire need of funds, we have spared no time");
+ lprintf("\nin preparing your tax bill. You owe %d gold pieces as",
+ (long)c[GOLD]*TAXRATE);
+ lprcat("\nof this notice, and is due within 5 days. Failure to pay will");
+ lprcat("\nmean penalties. Once again, congratulations, We look forward");
+ lprcat("\nto your future successful expeditions.\n");
+ lwclose(); return(1);
+ }
+
+static letter2()
+ {
+ sprintf(mail600,"/tmp/#%dmail600",pid); /* prepare path */
+ if (lcreat(mail600) < 0) { write(1,"can't write 601 letter\n",23); return(0);}
+ lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
+ standout("From:"); lprcat(" His Majesty King Wilfred of Larndom\n");
+ standout("\nSubject:"); lprcat(" a noble deed\n");
+ lprcat("\n I have heard of your magnificent feat, and I, King Wilfred,");
+ lprcat("\nforthwith declare today to be a national holiday. Furthermore,");
+ lprcat("\nhence three days, Ye be invited to the castle to receive the");
+ lprcat("\nhonour of Knight of the realm. Upon thy name shall it be written. . .");
+ lprcat("\nBravery and courage be yours.");
+ lprcat("\nMay you live in happiness forevermore . . .\n");
+ lwclose(); return(1);
+ }
+
+static letter3()
+ {
+ sprintf(mail600,"/tmp/#%dmail600",pid); /* prepare path */
+ if (lcreat(mail600) < 0) { write(1,"can't write 602 letter\n",23); return(0);}
+ lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
+ standout("From:"); lprcat(" Count Endelford\n");
+ standout("\nSubject:"); lprcat(" You Bastard!\n");
+ lprcat("\n I heard (from sources) of your journey. Congratulations!");
+ lprcat("\nYou Bastard! With several attempts I have yet to endure the");
+ lprcat(" caves,\nand you, a nobody, makes the journey! From this time");
+ lprcat(" onward, bewarned\nupon our meeting you shall pay the price!\n");
+ lwclose(); return(1);
+ }
+
+static letter4()
+ {
+ sprintf(mail600,"/tmp/#%dmail600",pid); /* prepare path */
+ if (lcreat(mail600) < 0) { write(1,"can't write 603 letter\n",23); return(0);}
+ lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
+ standout("From:"); lprcat(" Mainair, Duke of Larnty\n");
+ standout("\nSubject:"); lprcat(" High Praise\n");
+ lprcat("\n With a certainty a hero I declare to be amongst us! A nod of");
+ lprcat("\nfavour I send to thee. Me thinks Count Endelford this day of");
+ lprcat("\nright breath'eth fire as of dragon of whom ye are slayer. I");
+ lprcat("\nyearn to behold his anger and jealously. Should ye choose to");
+ lprcat("\nunleash some of thy wealth upon those who be unfortunate, I,");
+ lprcat("\nDuke Mainair, Shall equal thy gift also.\n");
+ lwclose(); return(1);
+ }
+
+static letter5()
+ {
+ sprintf(mail600,"/tmp/#%dmail600",pid); /* prepare path */
+ if (lcreat(mail600) < 0) { write(1,"can't write 604 letter\n",23); return(0);}
+ lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
+ standout("From:"); lprcat(" St. Mary's Children's Home\n");
+ standout("\nSubject:"); lprcat(" these poor children\n");
+ lprcat("\n News of your great conquests has spread to all of Larndom.");
+ lprcat("\nMight I have a moment of a great man's time. We here at St.");
+ lprcat("\nMary's Children's Home are very poor, and many children are");
+ lprcat("\nstarving. Disease is widespread and very often fatal without");
+ lprcat("\ngood food. Could you possibly find it in your heart to help us");
+ lprcat("\nin our plight? Whatever you could give will help much.");
+ lprcat("\n(your gift is tax deductible)\n");
+ lwclose(); return(1);
+ }
+
+static letter6()
+ {
+ sprintf(mail600,"/tmp/#%dmail600",pid); /* prepare path */
+ if (lcreat(mail600) < 0) { write(1,"can't write 605 letter\n",23); return(0);}
+ lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
+ standout("From:"); lprcat(" The National Cancer Society of Larn\n");
+ standout("\nSubject:"); lprcat(" hope\n");
+ lprcat("\nCongratulations on your successful expedition. We are sure much");
+ lprcat("\ncourage and determination were needed on your quest. There are");
+ lprcat("\nmany though, that could never hope to undertake such a journey");
+ lprcat("\ndue to an enfeebling disease -- cancer. We at the National");
+ lprcat("\nCancer Society of Larn wish to appeal to your philanthropy in");
+ lprcat("\norder to save many good people -- possibly even yourself a few");
+ lprcat("\nyears from now. Much work needs to be done in researching this");
+ lprcat("\ndreaded disease, and you can help today. Could you please see it");
+ lprcat("\nin your heart to give generously? Your continued good health");
+ lprcat("\ncan be your everlasting reward.\n");
+ lwclose(); return(1);
+ }
+
+/*
+ * function to mail the letters to the player if a winner
+ */
+static int (*pfn[])()= { letter1, letter2, letter3, letter4, letter5, letter6 };
+mailbill()
+ {
+ register int i;
+ char buf[128];
+ wait(0); pid=getpid();
+ if (fork() == 0)
+ {
+ resetscroll();
+ for (i=0; i<sizeof(pfn)/sizeof(int (*)()); i++)
+ if ((*pfn[i])())
+ {
+ sleep(20); sprintf(buf,"mail %s < %s",loginname,mail600);
+ system(buf); unlink(mail600);
+ }
+ exit();
+ }
+ }
diff --git a/larn/config.c b/larn/config.c
new file mode 100644
index 00000000..ccdd6d5f
--- /dev/null
+++ b/larn/config.c
@@ -0,0 +1,47 @@
+/*
+ * config.c -- This defines the installation dependent variables.
+ * Some strings are modified later. ANSI C would
+ * allow compile time string concatenation, we must
+ * do runtime concatenation, in main.
+ *
+ * Larn is copyrighted 1986 by Noah Morgan.
+ */
+#include "header.h"
+#include "pathnames.h"
+
+/*
+ * All these strings will be appended to in main() to be complete filenames
+ */
+
+/* the game save filename */
+char savefilename[1024];
+
+/* the logging file */
+char logfile[] = _PATH_LOG;
+
+/* the help text file */
+char helpfile[] = _PATH_HELP;
+
+/* the score file */
+char scorefile[] = _PATH_SCORE;
+
+/* the maze data file */
+char larnlevels[] = _PATH_LEVELS;
+
+/* the fortune data file */
+char fortfile[] = _PATH_FORTS;
+
+/* the .larnopts filename */
+char optsfile[1024] ="/.larnopts";
+
+/* the player id datafile name */
+char playerids[] = _PATH_PLAYERIDS;
+
+char diagfile[] ="Diagfile"; /* the diagnostic filename */
+char ckpfile[] ="Larn12.0.ckp"; /* the checkpoint filename */
+char *password ="pvnert(x)"; /* the wizards password <=32 */
+char psname[PSNAMESIZE]="larn"; /* the process name */
+
+#define WIZID 1
+int wisid=0; /* the user id of the only person who can be wizard */
+
diff --git a/larn/create.c b/larn/create.c
new file mode 100644
index 00000000..46c09c93
--- /dev/null
+++ b/larn/create.c
@@ -0,0 +1,463 @@
+/* create.c Larn is copyrighted 1986 by Noah Morgan. */
+#include "header.h"
+extern char spelknow[],larnlevels[];
+extern char beenhere[],wizard,level;
+extern short oldx,oldy;
+/*
+ makeplayer()
+
+ subroutine to create the player and the players attributes
+ this is called at the beginning of a game and at no other time
+ */
+makeplayer()
+ {
+ register int i;
+ scbr(); clear();
+ c[HPMAX]=c[HP]=10; /* start player off with 15 hit points */
+ c[LEVEL]=1; /* player starts at level one */
+ c[SPELLMAX]=c[SPELLS]=1; /* total # spells starts off as 3 */
+ c[REGENCOUNTER]=16; c[ECOUNTER]=96; /*start regeneration correctly*/
+ c[SHIELD] = c[WEAR] = c[WIELD] = -1;
+ for (i=0; i<26; i++) iven[i]=0;
+ spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/
+ if (c[HARDGAME]<=0)
+ {
+ iven[0]=OLEATHER; iven[1]=ODAGGER;
+ ivenarg[1]=ivenarg[0]=c[WEAR]=0; c[WIELD]=1;
+ }
+ playerx=rnd(MAXX-2); playery=rnd(MAXY-2);
+ oldx=0; oldy=25;
+ gtime=0; /* time clock starts at zero */
+ cbak[SPELLS] = -50;
+ for (i=0; i<6; i++) c[i]=12; /* make the attributes, ie str, int, etc. */
+ recalc();
+ }
+
+/*
+ newcavelevel(level)
+ int level;
+
+ function to enter a new level. This routine must be called anytime the
+ player changes levels. If that level is unknown it will be created.
+ A new set of monsters will be created for a new level, and existing
+ levels will get a few more monsters.
+ Note that it is here we remove genocided monsters from the present level.
+ */
+newcavelevel(x)
+ register int x;
+ {
+ register int i,j;
+ if (beenhere[level]) savelevel(); /* put the level back into storage */
+ level = x; /* get the new level and put in working storage */
+ if (beenhere[x]==0) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=mitem[j][i]=0;
+ else { getlevel(); sethp(0); goto chgn; }
+ makemaze(x); makeobject(x); beenhere[x]=1; sethp(1);
+
+#if WIZID
+ if (wizard || x==0)
+#else
+ if (x==0)
+#endif
+
+ for (j=0; j<MAXY; j++)
+ for (i=0; i<MAXX; i++)
+ know[i][j]=1;
+chgn: checkgen(); /* wipe out any genocided monsters */
+ }
+
+/*
+ makemaze(level)
+ int level;
+
+ subroutine to make the caverns for a given level. only walls are made.
+ */
+static int mx,mxl,mxh,my,myl,myh,tmp2;
+ makemaze(k)
+ int k;
+ {
+ register int i,j,tmp;
+ int z;
+ if (k > 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1))
+ {
+ if (cannedlevel(k)); return; /* read maze from data file */
+ }
+ if (k==0) tmp=0; else tmp=OWALL;
+ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) item[j][i]=tmp;
+ if (k==0) return; eat(1,1);
+ if (k==1) item[33][MAXY-1]=0; /* exit from dungeon */
+
+/* now for open spaces -- not on level 10 */
+ if (k != MAXLEVEL-1)
+ {
+ tmp2 = rnd(3)+3;
+ for (tmp=0; tmp<tmp2; tmp++)
+ {
+ my = rnd(11)+2; myl = my - rnd(2); myh = my + rnd(2);
+ if (k < MAXLEVEL)
+ {
+ mx = rnd(44)+5; mxl = mx - rnd(4); mxh = mx + rnd(12)+3;
+ z=0;
+ }
+ else
+ {
+ mx = rnd(60)+3; mxl = mx - rnd(2); mxh = mx + rnd(2);
+ z = makemonst(k);
+ }
+ for (i=mxl; i<mxh; i++) for (j=myl; j<myh; j++)
+ { item[i][j]=0;
+ if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints;
+ }
+ }
+ }
+ if (k!=MAXLEVEL-1) { my=rnd(MAXY-2); for (i=1; i<MAXX-1; i++) item[i][my] = 0; }
+ if (k>1) treasureroom(k);
+ }
+
+/*
+ function to eat away a filled in maze
+ */
+eat(xx,yy)
+ register int xx,yy;
+ {
+ register int dir,try;
+ dir = rnd(4); try=2;
+ while (try)
+ {
+ switch(dir)
+ {
+ case 1: if (xx <= 2) break; /* west */
+ if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break;
+ item[xx-1][yy] = item[xx-2][yy] = 0;
+ eat(xx-2,yy); break;
+
+ case 2: if (xx >= MAXX-3) break; /* east */
+ if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break;
+ item[xx+1][yy] = item[xx+2][yy] = 0;
+ eat(xx+2,yy); break;
+
+ case 3: if (yy <= 2) break; /* south */
+ if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break;
+ item[xx][yy-1] = item[xx][yy-2] = 0;
+ eat(xx,yy-2); break;
+
+ case 4: if (yy >= MAXY-3 ) break; /* north */
+ if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break;
+ item[xx][yy+1] = item[xx][yy+2] = 0;
+ eat(xx,yy+2); break;
+ };
+ if (++dir > 4) { dir=1; --try; }
+ }
+ }
+
+/*
+ * function to read in a maze from a data file
+ *
+ * Format of maze data file: 1st character = # of mazes in file (ascii digit)
+ * For each maze: 18 lines (1st 17 used) 67 characters per line
+ *
+ * Special characters in maze data file:
+ *
+ * # wall D door . random monster
+ * ~ eye of larn ! cure dianthroritis
+ * - random object
+ */
+cannedlevel(k)
+ int k;
+ {
+ char *row,*lgetl();
+ register int i,j;
+ int it,arg,mit,marg;
+ if (lopen(larnlevels)<0)
+ {
+ write(1,"Can't open the maze data file\n",30); died(-282); return(0);
+ }
+ i=lgetc(); if (i<='0') { died(-282); return(0); }
+ for (i=18*rund(i-'0'); i>0; i--) lgetl(); /* advance to desired maze */
+ for (i=0; i<MAXY; i++)
+ {
+ row = lgetl();
+ for (j=0; j<MAXX; j++)
+ {
+ it = mit = arg = marg = 0;
+ switch(*row++)
+ {
+ case '#': it = OWALL; break;
+ case 'D': it = OCLOSEDDOOR; arg = rnd(30); break;
+ case '~': if (k!=MAXLEVEL-1) break;
+ it = OLARNEYE;
+ mit = rund(8)+DEMONLORD;
+ marg = monster[mit].hitpoints; break;
+ case '!': if (k!=MAXLEVEL+MAXVLEVEL-1) break;
+ it = OPOTION; arg = 21;
+ mit = DEMONLORD+7;
+ marg = monster[mit].hitpoints; break;
+ case '.': if (k<MAXLEVEL) break;
+ mit = makemonst(k+1);
+ marg = monster[mit].hitpoints; break;
+ case '-': it = newobject(k+1,&arg); break;
+ };
+ item[j][i] = it; iarg[j][i] = arg;
+ mitem[j][i] = mit; hitp[j][i] = marg;
+
+#if WIZID
+ know[j][i] = (wizard) ? 1 : 0;
+#else
+ know[j][i] = 0;
+#endif
+ }
+ }
+ lrclose();
+ return(1);
+ }
+
+/*
+ function to make a treasure room on a level
+ level 10's treasure room has the eye in it and demon lords
+ level V3 has potion of cure dianthroritis and demon prince
+ */
+treasureroom(lv)
+ register int lv;
+ {
+ register int tx,ty,xsize,ysize;
+
+ for (tx=1+rnd(10); tx<MAXX-10; tx+=10)
+ if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2)
+ {
+ xsize = rnd(6)+3; ysize = rnd(3)+3;
+ ty = rnd(MAXY-9)+1; /* upper left corner of room */
+ if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1)
+ troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6);
+ else troom(lv,xsize,ysize,tx,ty,rnd(9));
+ }
+ }
+
+/*
+ * subroutine to create a treasure room of any size at a given location
+ * room is filled with objects and monsters
+ * the coordinate given is that of the upper left corner of the room
+ */
+troom(lv,xsize,ysize,tx,ty,glyph)
+ int lv,xsize,ysize,tx,ty,glyph;
+ {
+ register int i,j;
+ int tp1,tp2;
+ for (j=ty-1; j<=ty+ysize; j++)
+ for (i=tx-1; i<=tx+xsize; i++) /* clear out space for room */
+ item[i][j]=0;
+ for (j=ty; j<ty+ysize; j++)
+ for (i=tx; i<tx+xsize; i++) /* now put in the walls */
+ {
+ item[i][j]=OWALL; mitem[i][j]=0;
+ }
+ for (j=ty+1; j<ty+ysize-1; j++)
+ for (i=tx+1; i<tx+xsize-1; i++) /* now clear out interior */
+ item[i][j]=0;
+
+ switch(rnd(2)) /* locate the door on the treasure room */
+ {
+ case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR;
+ iarg[i][j] = glyph; /* on horizontal walls */
+ break;
+ case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR;
+ iarg[i][j] = glyph; /* on vertical walls */
+ break;
+ };
+
+ tp1=playerx; tp2=playery; playery=ty+(ysize>>1);
+ if (c[HARDGAME]<2)
+ for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
+ for (i=0, j=rnd(6); i<=j; i++)
+ { something(lv+2); createmonster(makemonst(lv+1)); }
+ else
+ for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
+ for (i=0, j=rnd(4); i<=j; i++)
+ { something(lv+2); createmonster(makemonst(lv+3)); }
+
+ playerx=tp1; playery=tp2;
+ }
+
+static void fillroom();
+
+/*
+ ***********
+ MAKE_OBJECT
+ ***********
+ subroutine to create the objects in the maze for the given level
+ */
+makeobject(j)
+ register int j;
+ {
+ register int i;
+ if (j==0)
+ {
+ fillroom(OENTRANCE,0); /* entrance to dungeon */
+ fillroom(ODNDSTORE,0); /* the DND STORE */
+ fillroom(OSCHOOL,0); /* college of Larn */
+ fillroom(OBANK,0); /* 1st national bank of larn */
+ fillroom(OVOLDOWN,0); /* volcano shaft to temple */
+ fillroom(OHOME,0); /* the players home & family */
+ fillroom(OTRADEPOST,0); /* the trading post */
+ fillroom(OLRS,0); /* the larn revenue service */
+ return;
+ }
+
+ if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */
+
+/* make the fixed objects in the maze STAIRS */
+ if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
+ fillroom(OSTAIRSDOWN,0);
+ if ((j > 1) && (j != MAXLEVEL)) fillroom(OSTAIRSUP,0);
+
+/* make the random objects in the maze */
+
+ fillmroom(rund(3),OBOOK,j); fillmroom(rund(3),OALTAR,0);
+ fillmroom(rund(3),OSTATUE,0); fillmroom(rund(3),OPIT,0);
+ fillmroom(rund(3),OFOUNTAIN,0); fillmroom( rnd(3)-2,OIVTELETRAP,0);
+ fillmroom(rund(2),OTHRONE,0); fillmroom(rund(2),OMIRROR,0);
+ fillmroom(rund(2),OTRAPARROWIV,0); fillmroom( rnd(3)-2,OIVDARTRAP,0);
+ fillmroom(rund(3),OCOOKIE,0);
+ if (j==1) fillmroom(1,OCHEST,j);
+ else fillmroom(rund(2),OCHEST,j);
+ if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
+ fillmroom(rund(2),OIVTRAPDOOR,0);
+ if (j<=10)
+ {
+ fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10);
+ fillmroom(rund(2),ORUBY,rnd(6*j+1)+6);
+ fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4);
+ fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2);
+ }
+ for (i=0; i<rnd(4)+3; i++)
+ fillroom(OPOTION,newpotion()); /* make a POTION */
+ for (i=0; i<rnd(5)+3; i++)
+ fillroom(OSCROLL,newscroll()); /* make a SCROLL */
+ for (i=0; i<rnd(12)+11; i++)
+ fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */
+ if (j==5) fillroom(OBANK2,0); /* branch office of the bank */
+ froom(2,ORING,0); /* a ring mail */
+ froom(1,OSTUDLEATHER,0); /* a studded leather */
+ froom(3,OSPLINT,0); /* a splint mail */
+ froom(5,OSHIELD,rund(3)); /* a shield */
+ froom(2,OBATTLEAXE,rund(3)); /* a battle axe */
+ froom(5,OLONGSWORD,rund(3)); /* a long sword */
+ froom(5,OFLAIL,rund(3)); /* a flail */
+ froom(4,OREGENRING,rund(3)); /* ring of regeneration */
+ froom(1,OPROTRING,rund(3)); /* ring of protection */
+ froom(2,OSTRRING,4); /* ring of strength + 4 */
+ froom(7,OSPEAR,rnd(5)); /* a spear */
+ froom(3,OORBOFDRAGON,0); /* orb of dragon slaying*/
+ froom(4,OSPIRITSCARAB,0); /*scarab of negate spirit*/
+ froom(4,OCUBEofUNDEAD,0); /* cube of undead control */
+ froom(2,ORINGOFEXTRA,0); /* ring of extra regen */
+ froom(3,ONOTHEFT,0); /* device of antitheft */
+ froom(2,OSWORDofSLASHING,0); /* sword of slashing */
+ if (c[BESSMANN]==0)
+ {
+ froom(4,OHAMMER,0);/*Bessman's flailing hammer*/ c[BESSMANN]=1;
+ }
+ if (c[HARDGAME]<3 || (rnd(4)==3))
+ {
+ if (j>3)
+ {
+ froom(3,OSWORD,3); /* sunsword + 3 */
+ froom(5,O2SWORD,rnd(4)); /* a two handed sword */
+ froom(3,OBELT,4); /* belt of striking */
+ froom(3,OENERGYRING,3); /* energy ring */
+ froom(4,OPLATE,5); /* platemail + 5 */
+ }
+ }
+ }
+
+/*
+ subroutine to fill in a number of objects of the same kind
+ */
+
+fillmroom(n,what,arg)
+ int n,arg;
+ char what;
+ {
+ register int i;
+ for (i=0; i<n; i++) fillroom(what,arg);
+ }
+froom(n,itm,arg)
+ int n,arg;
+ char itm;
+ { if (rnd(151) < n) fillroom(itm,arg); }
+
+/*
+ subroutine to put an object into an empty room
+ * uses a random walk
+ */
+static void
+fillroom(what,arg)
+ int arg;
+ char what;
+ {
+ register int x,y;
+
+#ifdef EXTRA
+ c[FILLROOM]++;
+#endif
+
+ x=rnd(MAXX-2); y=rnd(MAXY-2);
+ while (item[x][y])
+ {
+
+#ifdef EXTRA
+ c[RANDOMWALK]++; /* count up these random walks */
+#endif
+
+ x += rnd(3)-2; y += rnd(3)-2;
+ if (x > MAXX-2) x=1; if (x < 1) x=MAXX-2;
+ if (y > MAXY-2) y=1; if (y < 1) y=MAXY-2;
+ }
+ item[x][y]=what; iarg[x][y]=arg;
+ }
+
+/*
+ subroutine to put monsters into an empty room without walls or other
+ monsters
+ */
+fillmonst(what)
+ char what;
+ {
+ register int x,y,trys;
+ for (trys=5; trys>0; --trys) /* max # of creation attempts */
+ {
+ x=rnd(MAXX-2); y=rnd(MAXY-2);
+ if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y)))
+ {
+ mitem[x][y] = what; know[x][y]=0;
+ hitp[x][y] = monster[what].hitpoints; return(0);
+ }
+ }
+ return(-1); /* creation failure */
+ }
+
+/*
+ creates an entire set of monsters for a level
+ must be done when entering a new level
+ if sethp(1) then wipe out old monsters else leave them there
+ */
+sethp(flg)
+ int flg;
+ {
+ register int i,j;
+ if (flg) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0;
+ if (level==0) { c[TELEFLAG]=0; return; } /* if teleported and found level 1 then know level we are on */
+ if (flg) j = rnd(12) + 2 + (level>>1); else j = (level>>1) + 1;
+ for (i=0; i<j; i++) fillmonst(makemonst(level));
+ positionplayer();
+ }
+
+/*
+ * Function to destroy all genocided monsters on the present level
+ */
+checkgen()
+ {
+ register int x,y;
+ for (y=0; y<MAXY; y++)
+ for (x=0; x<MAXX; x++)
+ if (monster[mitem[x][y]].genocided)
+ mitem[x][y]=0; /* no more monster */
+ }
diff --git a/larn/data.c b/larn/data.c
new file mode 100644
index 00000000..a8739bab
--- /dev/null
+++ b/larn/data.c
@@ -0,0 +1,648 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)data.c 5.3 (Berkeley) 5/13/91";
+#endif /* not lint */
+
+/* data.c Larn is copyrighted 1986 by Noah Morgan. */
+#define NODEFS
+#include "header.h"
+
+/*
+ class[c[LEVEL]-1] gives the correct name of the players experience level
+ */
+static char aa1[] = " mighty evil master";
+static char aa2[] = "apprentice demi-god";
+static char aa3[] = " minor demi-god ";
+static char aa4[] = " major demi-god ";
+static char aa5[] = " minor deity ";
+static char aa6[] = " major deity ";
+static char aa7[] = " novice guardian ";
+static char aa8[] = "apprentice guardian";
+static char aa9[] = " The Creator ";
+char *class[]=
+{ " novice explorer ", "apprentice explorer", " practiced explorer",/* -3*/
+ " expert explorer ", " novice adventurer", " adventurer ",/* -6*/
+ "apprentice conjurer", " conjurer ", " master conjurer ",/* -9*/
+ " apprentice mage ", " mage ", " experienced mage ",/* -12*/
+ " master mage ", " apprentice warlord", " novice warlord ",/* -15*/
+ " expert warlord ", " master warlord ", " apprentice gorgon ",/* -18*/
+ " gorgon ", " practiced gorgon ", " master gorgon ",/* -21*/
+ " demi-gorgon ", " evil master ", " great evil master ",/* -24*/
+ aa1 , aa1 , aa1 ,/* -27*/
+ aa1 , aa1 , aa1 ,/* -30*/
+ aa1 , aa1 , aa1 ,/* -33*/
+ aa1 , aa1 , aa1 ,/* -36*/
+ aa1 , aa1 , aa1 ,/* -39*/
+ aa2 , aa2 , aa2 ,/* -42*/
+ aa2 , aa2 , aa2 ,/* -45*/
+ aa2 , aa2 , aa2 ,/* -48*/
+ aa3 , aa3 , aa3 ,/* -51*/
+ aa3 , aa3 , aa3 ,/* -54*/
+ aa3 , aa3 , aa3 ,/* -57*/
+ aa4 , aa4 , aa4 ,/* -60*/
+ aa4 , aa4 , aa4 ,/* -63*/
+ aa4 , aa4 , aa4 ,/* -66*/
+ aa5 , aa5 , aa5 ,/* -69*/
+ aa5 , aa5 , aa5 ,/* -72*/
+ aa5 , aa5 , aa5 ,/* -75*/
+ aa6 , aa6 , aa6 ,/* -78*/
+ aa6 , aa6 , aa6 ,/* -81*/
+ aa6 , aa6 , aa6 ,/* -84*/
+ aa7 , aa7 , aa7 ,/* -87*/
+ aa8 , aa8 , aa8 ,/* -90*/
+ aa8 , aa8 , aa8 ,/* -93*/
+ " earth guardian ", " air guardian ", " fire guardian ",/* -96*/
+ " water guardian ", " time guardian ", " ethereal guardian ",/* -99*/
+ aa9 , aa9 , aa9 ,/* -102*/
+};
+
+/*
+ table of experience needed to be a certain level of player
+ skill[c[LEVEL]] is the experience required to attain the next level
+ */
+#define MEG 1000000
+long skill[] = {
+0, 10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120, /* 1-11 */
+10240, 20480, 40960, 100000, 200000, 400000, 700000, 1*MEG, /* 12-19 */
+2*MEG,3*MEG,4*MEG,5*MEG,6*MEG,8*MEG,10*MEG, /* 20-26 */
+12*MEG,14*MEG,16*MEG,18*MEG,20*MEG,22*MEG,24*MEG,26*MEG,28*MEG, /* 27-35 */
+30*MEG,32*MEG,34*MEG,36*MEG,38*MEG,40*MEG,42*MEG,44*MEG,46*MEG, /* 36-44 */
+48*MEG,50*MEG,52*MEG,54*MEG,56*MEG,58*MEG,60*MEG,62*MEG,64*MEG, /* 45-53 */
+66*MEG,68*MEG,70*MEG,72*MEG,74*MEG,76*MEG,78*MEG,80*MEG,82*MEG, /* 54-62 */
+84*MEG,86*MEG,88*MEG,90*MEG,92*MEG,94*MEG,96*MEG,98*MEG,100*MEG, /* 63-71 */
+105*MEG,110*MEG,115*MEG,120*MEG, 125*MEG, 130*MEG, 135*MEG, 140*MEG, /* 72-79 */
+145*MEG,150*MEG,155*MEG,160*MEG, 165*MEG, 170*MEG, 175*MEG, 180*MEG, /* 80-87 */
+185*MEG,190*MEG,195*MEG,200*MEG, 210*MEG, 220*MEG, 230*MEG, 240*MEG, /* 88-95 */
+250*MEG,260*MEG,270*MEG,280*MEG, 290*MEG, 300*MEG /* 96-101*/
+};
+#undef MEG
+
+char *lpbuf,*lpnt,*inbuffer,*lpend; /* input/output pointers to the buffers */
+struct cel *cell; /* pointer to the dungeon storage */
+short hitp[MAXX][MAXY]; /* monster hp on level */
+short iarg[MAXX][MAXY]; /* arg for the item array */
+char item[MAXX][MAXY]; /* objects in maze if any */
+char know[MAXX][MAXY]; /* 1 or 0 if here before */
+char mitem[MAXX][MAXY]; /* monster item array */
+char moved[MAXX][MAXY]; /* monster movement flags */
+char stealth[MAXX][MAXY]; /* 0=sleeping 1=awake monst*/
+char iven[26]; /* inventory for player */
+short ivenarg[26]; /* inventory for player */
+char lastmonst[40]; /* this has the name of the current monster */
+char beenhere[MAXLEVEL+MAXVLEVEL]={0}; /* 1 if have been on this level */
+char VERSION=VER; /* this is the present version # of the program */
+char SUBVERSION=SUBVER;
+char nosignal=0; /* set to 1 to disable the signals from doing anything */
+char predostuff=0; /* 2 means that the trap handling routines must do a
+ showplayer() after a trap. 0 means don't showplayer()
+ 0 - we are in create player screen
+ 1 - we are in welcome screen
+ 2 - we are in the normal game */
+char loginname[20]; /* players login name */
+char logname[LOGNAMESIZE]; /* players name storage for scoring */
+char sex=1; /* default is a man 0=woman */
+char boldon=1; /* 1=bold objects 0=inverse objects */
+char ckpflag=0; /* 1 if want checkpointing of game, 0 otherwise */
+char cheat=0; /* 1 if the player has fudged save file */
+char level=0; /* cavelevel player is on = c[CAVELEVEL] */
+char wizard=0; /* the wizard mode flag */
+short lastnum=0; /* the number of the monster last hitting player */
+short hitflag=0; /* flag for if player has been hit when running */
+short hit2flag=0; /* flag for if player has been hit when running */
+short hit3flag=0; /* flag for if player has been hit flush input */
+short playerx,playery; /* the room on the present level of the player */
+short lastpx,lastpy; /* 0 --- MAXX-1 or 0 --- MAXY-1 */
+short oldx,oldy;
+short lasthx=0,lasthy=0; /* location of monster last hit by player */
+short nobeep=0; /* true if program is not to beep */
+unsigned long randx=33601; /* the random number seed */
+long initialtime=0; /* time playing began */
+long gtime=0; /* the clock for the game */
+long outstanding_taxes=0; /* present tax bill from score file */
+long c[100],cbak[100]; /* the character description arrays */
+int enable_scroll=0; /* constant for enabled/disabled scrolling regn */
+char aborted[] = " aborted";
+struct sphere *spheres=0; /*pointer to linked list for spheres of annihilation*/
+char *levelname[]=
+{ " H"," 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9","10","V1","V2","V3" };
+
+char objnamelist[]=" ATOP%^F&^+M=%^$$f*OD#~][[)))(((||||||||{?!BC}o:@.<<<<EVV))([[]]](^ [H*** ^^ S tsTLc............................................";
+char monstnamelist[]=" BGHJKOScjtAELNQRZabhiCTYdegmvzFWflorXV pqsyUkMwDDPxnDDuD ...............................................................";
+char *objectname[]=
+{ 0,"a holy altar","a handsome jewel encrusted throne","the orb","a pit",
+ "a staircase leading upwards","an elevator going up","a bubbling fountain",
+ "a great marble statue","a teleport trap","the college of Larn",
+ "a mirror","the DND store","a staircase going down","an elevator going down",
+ "the bank of Larn","the 5th branch of the Bank of Larn",
+ "a dead fountain","gold","an open door","a closed door",
+ "a wall","The Eye of Larn","plate mail","chain mail","leather armor",
+ "a sword of slashing","Bessman's flailing hammer","a sunsword",
+ "a two handed sword","a spear","a dagger",
+ "ring of extra regeneration","a ring of regeneration","a ring of protection",
+ "an energy ring","a ring of dexterity","a ring of strength",
+ "a ring of cleverness","a ring of increase damage","a belt of striking",
+ "a magic scroll","a magic potion","a book","a chest",
+ "an amulet of invisibility","an orb of dragon slaying",
+ "a scarab of negate spirit","a cube of undead control",
+ "device of theft prevention","a brilliant diamond","a ruby",
+ "an enchanting emerald","a sparkling sapphire","the dungeon entrance",
+ "a volcanic shaft leaning downward","the base of a volcanic shaft",
+ "a battle axe","a longsword","a flail","ring mail","studded leather armor",
+ "splint mail","plate armor","stainless plate armor","a lance of death",
+ "an arrow trap","an arrow trap","a shield","your home",
+ "gold","gold","gold","a dart trap",
+ "a dart trap","a trapdoor","a trapdoor","the local trading post",
+ "a teleport trap", "a massive throne",
+ "a sphere of annihilation","a handsome jewel encrusted throne",
+ "the Larn Revenue Service","a fortune cookie","","","","","","",
+ "","","","","","","","","","","","","","","","","","","",""
+ };
+
+
+/*
+ * for the monster data
+ *
+ * array to do rnd() to create monsters <= a given level
+ */
+char monstlevel[] = { 5, 11, 17, 22, 27, 33, 39, 42, 46, 50, 53, 56, 59 };
+
+struct monst monster[] = {
+/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
+----------------------------------------------------------------- */
+{ "", 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 },
+{ "bat", 1, 0, 1, 0, 0, 0, 3, 0, 1, 1 },
+{ "gnome", 1, 10, 1, 0, 0, 0, 8, 30, 2, 2 },
+{ "hobgoblin", 1, 14, 2, 0, 0, 0, 5, 25, 3, 2 },
+{ "jackal", 1, 17, 1, 0, 0, 0, 4, 0, 1, 1 },
+{ "kobold", 1, 20, 1, 0, 0, 0, 7, 10, 1, 1 },
+
+{ "orc", 2, 12, 1, 0, 0, 0, 9, 40, 4, 2 },
+{ "snake", 2, 15, 1, 0, 0, 0, 3, 0, 3, 1 },
+{ "giant centipede",2, 14, 0, 4, 0, 0, 3, 0, 1, 2 },
+{ "jaculi", 2, 20, 1, 0, 0, 0, 3, 0, 2, 1 },
+{ "troglodyte", 2, 10, 2, 0, 0, 0, 5, 80, 4, 3 },
+{ "giant ant", 2, 8, 1, 4, 0, 0, 4, 0, 5, 5 },
+
+/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
+----------------------------------------------------------------- */
+
+{ "floating eye", 3, 8, 1, 0, 0, 0, 3, 0, 5, 2 },
+{ "leprechaun", 3, 3, 0, 8, 0, 0, 3,1500, 13, 45 },
+{ "nymph", 3, 3, 0, 14, 0, 0, 9, 0, 18, 45 },
+{ "quasit", 3, 5, 3, 0, 0, 0, 3, 0, 10, 15 },
+{ "rust monster", 3, 4, 0, 1, 0, 0, 3, 0, 18, 25 },
+{ "zombie", 3, 12, 2, 0, 0, 0, 3, 0, 6, 7 },
+
+{ "assassin bug", 4, 9, 3, 0, 0, 0, 3, 0, 20, 15 },
+{ "bugbear", 4, 5, 4, 15, 0, 0, 5, 40, 20, 35 },
+{ "hell hound", 4, 5, 2, 2, 0, 0, 6, 0, 16, 35 },
+{ "ice lizard", 4, 11, 2, 10, 0, 0, 6, 50, 16, 25 },
+{ "centaur", 4, 6, 4, 0, 0, 0, 10, 40, 24, 45 },
+
+/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
+----------------------------------------------------------------- */
+
+{ "troll", 5, 4, 5, 0, 0, 0, 9, 80, 50, 300 },
+{ "yeti", 5, 6, 4, 0, 0, 0, 5, 50, 35, 100 },
+{ "white dragon", 5, 2, 4, 5, 0, 0, 16, 500, 55, 1000},
+{ "elf", 5, 8, 1, 0, 0, 0, 15, 50, 22, 35 },
+{ "gelatinous cube",5, 9, 1, 0, 0, 0, 3, 0, 22, 45 },
+
+{ "metamorph", 6, 7, 3, 0, 0, 0, 3, 0, 30, 40 },
+{ "vortex", 6, 4, 3, 0, 0, 0, 3, 0, 30, 55 },
+{ "ziller", 6, 15, 3, 0, 0, 0, 3, 0, 30, 35 },
+{ "violet fungi", 6, 12, 3, 0, 0, 0, 3, 0, 38, 100 },
+{ "wraith", 6, 3, 1, 6, 0, 0, 3, 0, 30, 325 },
+{ "forvalaka", 6, 2, 5, 0, 0, 0, 7, 0, 50, 280 },
+
+/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
+----------------------------------------------------------------- */
+
+{ "lama nobe", 7, 7, 3, 0, 0, 0, 6, 0, 35, 80 },
+{ "osequip", 7, 4, 3, 16, 0, 0, 4, 0, 35, 100 },
+{ "rothe", 7, 15, 5, 0, 0, 0, 3, 100, 50, 250 },
+{ "xorn", 7, 0, 6, 0, 0, 0, 13, 0, 60, 300 },
+{ "vampire", 7, 3, 4, 6, 0, 0, 17, 0, 50, 1000},
+{ "invisible stalker",7,3, 6, 0, 0, 0, 5, 0, 50, 350 },
+
+{ "poltergeist", 8, 1, 4, 0, 0, 0, 3, 0, 50, 450 },
+{ "disenchantress", 8, 3, 0, 9, 0, 0, 3, 0, 50, 500 },
+{ "shambling mound",8, 2, 5, 0, 0, 0, 6, 0, 45, 400 },
+{ "yellow mold", 8, 12, 4, 0, 0, 0, 3, 0, 35, 250 },
+{ "umber hulk", 8, 3, 7, 11, 0, 0, 14, 0, 65, 600 },
+
+/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
+----------------------------------------------------------------- */
+
+{ "gnome king", 9, -1, 10, 0, 0, 0, 18, 2000, 100,3000 },
+{ "mimic", 9, 5, 6, 0, 0, 0, 8, 0, 55, 99 },
+{ "water lord", 9, -10, 15, 7, 0, 0, 20, 0, 150,15000 },
+{ "bronze dragon", 9, 2, 9, 3, 0, 0, 16, 300, 80, 4000 },
+{ "green dragon", 9, 3, 8, 10, 0, 0, 15, 200, 70, 2500 },
+{ "purple worm", 9, -1, 11, 0, 0, 0, 3, 100, 120,15000 },
+{ "xvart", 9, -2, 12, 0, 0, 0, 13, 0, 90, 1000 },
+
+{ "spirit naga", 10, -20,12, 12, 0, 0, 23, 0, 95, 20000 },
+{ "silver dragon", 10, -1, 12, 3, 0, 0, 20, 700, 100,10000 },
+{ "platinum dragon",10, -5, 15, 13, 0, 0, 22, 1000, 130,24000 },
+{ "green urchin", 10, -3, 12, 0, 0, 0, 3, 0, 85, 5000 },
+{ "red dragon", 10, -2, 13, 3, 0, 0, 19, 800, 110,14000 },
+
+{ "type I demon lord", 12,-30, 18, 0, 0, 0, 20, 0, 140,50000 },
+{ "type II demon lord", 13,-30, 18, 0, 0, 0, 21, 0, 160,75000 },
+{ "type III demon lord",14,-30, 18, 0, 0, 0, 22, 0, 180,100000 },
+{ "type IV demon lord", 15,-35, 20, 0, 0, 0, 23, 0, 200,125000 },
+{ "type V demon lord", 16,-40, 22, 0, 0, 0, 24, 0, 220,150000 },
+{ "type VI demon lord", 17,-45, 24, 0, 0, 0, 25, 0, 240,175000 },
+{ "type VII demon lord",18,-70, 27, 6, 0, 0, 26, 0, 260,200000 },
+{ "demon prince", 25,-127,30, 6, 0, 0, 28, 0, 345,300000 }
+
+/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
+--------------------------------------------------------------------- */
+ };
+
+/* name array for scrolls */
+
+char *scrollname[] = {
+"\0enchant armor",
+"\0enchant weapon",
+"\0enlightenment",
+"\0blank paper",
+"\0create monster",
+"\0create artifact",
+"\0aggravate monsters",
+"\0time warp",
+"\0teleportation",
+"\0expanded awareness",
+"\0haste monsters",
+"\0monster healing",
+"\0spirit protection",
+"\0undead protection",
+"\0stealth",
+"\0magic mapping",
+"\0hold monsters",
+"\0gem perfection",
+"\0spell extension",
+"\0identify",
+"\0remove curse",
+"\0annihilation",
+"\0pulverization",
+"\0life protection",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 "
+ };
+
+/* name array for magic potions */
+char *potionname[] = {
+"\0sleep",
+"\0healing",
+"\0raise level",
+"\0increase ability",
+"\0wisdom",
+"\0strength",
+"\0raise charisma",
+"\0dizziness",
+"\0learning",
+"\0gold detection",
+"\0monster detection",
+"\0forgetfulness",
+"\0water",
+"\0blindness",
+"\0confusion",
+"\0heroism",
+"\0sturdiness",
+"\0giant strength",
+"\0fire resistance",
+"\0treasure finding",
+"\0instant healing",
+" cure dianthroritis",
+"\0poison",
+"\0see invisible",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 ",
+"\0 "
+ };
+
+
+/*
+ spell data
+ */
+char spelknow[SPNUM]={0};
+char splev[] = { 1, 4, 9, 14, 18, 22, 26, 29, 32, 35, 37, 37, 37, 37, 37 };
+
+char *spelcode[]={
+ "pro", "mle", "dex", "sle", "chm", "ssp",
+ "web", "str", "enl", "hel", "cbl", "cre", "pha", "inv",
+ "bal", "cld", "ply", "can", "has", "ckl", "vpr",
+ "dry", "lit", "drl", "glo", "flo", "fgr",
+ "sca", "hld", "stp", "tel", "mfi", /* 31 */
+ "sph", "gen", "sum", "wtw", "alt", "per"
+ };
+
+char *spelname[]={
+ "protection", "magic missile", "dexterity",
+ "sleep", "charm monster", "sonic spear",
+
+ "web", "strength", "enlightenment",
+ "healing", "cure blindness", "create monster",
+ "phantasmal forces", "invisibility",
+
+ "fireball", "cold", "polymorph",
+ "cancellation", "haste self", "cloud kill",
+ "vaporize rock",
+
+ "dehydration", "lightning", "drain life",
+ "invulnerability", "flood", "finger of death",
+
+ "scare monster", "hold monster", "time stop",
+ "teleport away", "magic fire",
+
+ "sphere of annihilation", "genocide", "summon demon",
+ "walk through walls", "alter reality", "permanence",
+ ""
+ };
+
+char *speldescript[]={
+/* 1 */
+ "generates a +2 protection field",
+ "creates and hurls a magic missile equivalent to a + 1 magic arrow",
+ "adds +2 to the casters dexterity",
+ "causes some monsters to go to sleep",
+ "some monsters may be awed at your magnificence",
+ "causes your hands to emit a screeching sound toward what they point",
+/* 7 */
+ "causes strands of sticky thread to entangle an enemy",
+ "adds +2 to the casters strength for a short term",
+ "the caster becomes aware of things around him",
+ "restores some hp to the caster",
+ "restores sight to one so unfortunate as to be blinded",
+ "creates a monster near the caster appropriate for the location",
+ "creates illusions, and if believed, monsters die",
+ "the caster becomes invisible",
+/* 15 */
+ "makes a ball of fire that burns on what it hits",
+ "sends forth a cone of cold which freezes what it touches",
+ "you can find out what this does for yourself",
+ "negates the ability of a monster to use his special abilities",
+ "speeds up the casters movements",
+ "creates a fog of poisonous gas which kills all that is within it",
+ "this changes rock to air",
+/* 22 */
+ "dries up water in the immediate vicinity",
+ "you finger will emit a lightning bolt when this spell is cast",
+ "subtracts hit points from both you and a monster",
+ "this globe helps to protect the player from physical attack",
+ "this creates an avalanche of H2O to flood the immediate chamber",
+ "this is a holy spell and calls upon your god to back you up",
+/* 28 */
+ "terrifies the monster so that hopefully he wont hit the magic user",
+ "the monster is frozen in his tracks if this is successful",
+ "all movement in the caverns ceases for a limited duration",
+ "moves a particular monster around in the dungeon (hopefully away from you)",
+ "this causes a curtain of fire to appear all around you",
+/* 33 */
+ "anything caught in this sphere is instantly killed. Warning -- dangerous",
+ "eliminates a species of monster from the game -- use sparingly",
+ "summons a demon who hopefully helps you out",
+ "allows the player to walk through walls for a short period of time",
+ "god only knows what this will do",
+ "makes a character spell permanent, i. e. protection, strength, etc.",
+ ""
+ };
+
+char spelweird[MAXMONST+8][SPNUM] = {
+/* p m d s c s w s e h c c p i b c p c h c v d l d g f f s h s t m s g s w a p */
+/* r l e l h s e t n e b r h n a l l a a k p r i r l l g c l t e f p e u t l e */
+/* o e x e m p b r l l l e a v l d y n s l r y t l o o r a d p l i h n m w t r */
+
+
+/* bat */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* gnome */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* hobgoblin */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* jackal */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* kobold */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* orc */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* snake */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/*giant centipede */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* jaculi */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* troglodyte */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* giant ant */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* floating eye */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* leprechaun */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* nymph */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* quasit */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* rust monster */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* zombie */ { 0,0,0,8,0,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* assassin bug */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* bugbear */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* hell hound */ { 0,6,0,0,0,0, 12,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* ice lizard */ { 0,0,0,0,0,0, 11,0,0,0,0,0,0,0, 0,15,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* centaur */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* troll */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* yeti */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,15,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* white dragon */ { 0,0,0,0,0,0, 0,0,0,0,0,0,14,0, 0,15,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* elf */ { 0,0,0,0,0,0, 0,0,0,0,0,0,14,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/*gelatinous cube */ { 0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 0,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* metamorph */ { 0,13,0,0,0,0, 2,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* vortex */ { 0,13,0,0,0,10, 1,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* ziller */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* violet fungi */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* wraith */ { 0,0,0,8,0,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* forvalaka */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* lama nobe */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* osequip */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* rothe */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* xorn */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* vampire */ { 0,0,0,8,0,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 0,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/*invisible staker*/ { 0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* poltergeist */ { 0,13,0,8,0,4, 1,0,0,0,0,0,0,0, 0,4,0,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* disenchantress */ { 0,0,0,8,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/*shambling mound */ { 0,0,0,0,0,10, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* yellow mold */ { 0,0,0,8,0,0, 1,0,0,0,0,0,4,0, 0,0,0,0,0,4,0, 0,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* umber hulk */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* gnome king */ { 0,7,0,0,3,0, 0,0,0,0,0,0,0,5, 0,0,9,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* mimic */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* water lord */ { 0,13,0,8,3,4, 1,0,0,0,0,0,0,0, 0,0,9,0,0,4,0, 0,0,0,0,16,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* bronze dragon */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* green dragon */ { 0,7,0,0,0,0, 11,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* purple worm */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* xvart */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* spirit naga */ { 0,13,0,8,3,4, 1,0,0,0,0,0,0,5, 0,4,9,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* silver dragon */ { 0,6,0,9,0,0, 12,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/*platinum dragon */ { 0,7,0,9,0,0, 11,0,0,0,0,0,14,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* green urchin */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+/* red dragon */ { 0,6,0,0,0,0, 12,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
+
+/* p m d s c s w s e h c c p i b c p c h c v d l d g f f s h s t m s g s w a p */
+/* r l e l h s e t n e b r h n a l l a a k p r i r l l g c l t e f p e u t l e */
+/* o e x e m p b r l l l e a v l d y n s l r y t l o o r a d p l i h n m w t r */
+
+/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
+/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
+/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
+/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
+/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
+/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
+/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
+/* demon prince */ { 0,7,0,4,3,9, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 4,0,0,0,4, 9,0,0,0,0,0 }
+
+ };
+
+char *spelmes[] = { "",
+/* 1 */ "the web had no effect on the %s",
+/* 2 */ "the %s changed shape to avoid the web",
+/* 3 */ "the %s isn't afraid of you",
+/* 4 */ "the %s isn't affected",
+/* 5 */ "the %s can see you with his infravision",
+/* 6 */ "the %s vaporizes your missile",
+/* 7 */ "your missile bounces off the %s",
+/* 8 */ "the %s doesn't sleep",
+/* 9 */ "the %s resists",
+/* 10 */ "the %s can't hear the noise",
+/* 11 */ "the %s's tail cuts it free of the web",
+/* 12 */ "the %s burns through the web",
+/* 13 */ "your missiles pass right through the %s",
+/* 14 */ "the %s sees through your illusions",
+/* 15 */ "the %s loves the cold!",
+/* 16 */ "the %s loves the water!"
+ };
+
+char to_lower[]= /* tolower[character] = lower case converted character */
+ {
+ 0000,0001,0002,0003,0004,0005,0006,0007,0010,0011,0012,0013,0014,0015,0016,0017, /* NUL-SI*/
+ 0020,0021,0022,0023,0024,0025,0026,0027,0030,0031,0032,0033,0034,0035,0036,0037, /* DLE-US*/
+ 0040,0041,0042,0043,0044,0045,0046,0047,0050,0051,0052,0053,0054,0055,0056,0057, /* SP-/ */
+ 0060,0061,0062,0063,0064,0065,0066,0067,0070,0071,0072,0073,0074,0075,0076,0077, /* 0-? */
+ 0100,0141,0142,0143,0144,0145,0146,0147,0150,0151,0152,0153,0154,0155,0156,0157, /* @-O */
+ 0160,0161,0162,0163,0164,0165,0166,0167,0170,0171,0172,0133,0134,0135,0136,0137, /* P-_ */
+ 0140,0141,0142,0143,0144,0145,0146,0147,0150,0151,0152,0153,0154,0155,0156,0157, /* `-o */
+ 0160,0161,0162,0163,0164,0165,0166,0167,0170,0171,0172,0173,0174,0175,0176,0177, /* p-DEL */
+ };
+
+char to_upper[]= /* toupper[character] = upper case converted character */
+ {
+ 0000,0001,0002,0003,0004,0005,0006,0007,0010,0011,0012,0013,0014,0015,0016,0017, /* NUL-SI*/
+ 0020,0021,0022,0023,0024,0025,0026,0027,0030,0031,0032,0033,0034,0035,0036,0037, /* DLE-US*/
+ 0040,0041,0042,0043,0044,0045,0046,0047,0050,0051,0052,0053,0054,0055,0056,0057, /* SP-/ */
+ 0060,0061,0062,0063,0064,0065,0066,0067,0070,0071,0072,0073,0074,0075,0076,0077, /* 0-? */
+ 0100,0101,0102,0103,0104,0105,0106,0107,0110,0111,0112,0113,0114,0115,0116,0117, /* @-O */
+ 0120,0121,0122,0123,0124,0125,0126,0127,0130,0131,0132,0133,0134,0135,0136,0137, /* P-_ */
+ 0140,0101,0102,0103,0104,0105,0106,0107,0110,0111,0112,0113,0114,0115,0116,0117, /* `-o */
+ 0120,0121,0122,0123,0124,0125,0126,0127,0130,0131,0132,0173,0174,0175,0176,0177, /* p-DEL */
+ };
+
+char is_digit[]= /* isdigit[character] = TRUE || FALSE */
+ {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* NUL-SI*/
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* DLE-US*/
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* SP-/ */
+ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, /* 0-? */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* @-O */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* P-_ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* `-o */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* p-DEL */
+ };
+
+char is_alpha[]= /* isalpha[character] = TRUE || FALSE */
+ {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* NUL-SI*/
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* DLE-US*/
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* SP-/ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0-? */
+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* @-O */
+ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, /* P-_ */
+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* `-o */
+ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, /* p-DEL */
+ };
+
+/*
+ * function to create scroll numbers with appropriate probability of
+ * occurrence
+ *
+ * 0 - armor 1 - weapon 2 - enlightenment 3 - paper
+ * 4 - create monster 5 - create item 6 - aggravate 7 - time warp
+ * 8 - teleportation 9 - expanded awareness 10 - haste monst
+ * 11 - heal monster 12 - spirit protection 13 - undead protection
+ * 14 - stealth 15 - magic mapping 16 - hold monster
+ * 17 - gem perfection 18 - spell extension 19 - identify
+ * 20 - remove curse 21 - annihilation 22 - pulverization
+ * 23 - life protection
+ */
+char scprob[]= { 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3,
+ 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9,
+ 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14,
+ 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 19, 20, 20, 20, 20, 21, 22,
+ 22, 22, 23 };
+
+/*
+ * function to return a potion number created with appropriate probability
+ * of occurrence
+ *
+ * 0 - sleep 1 - healing 2 - raise level
+ * 3 - increase ability 4 - gain wisdom 5 - gain strength
+ * 6 - charismatic character 7 - dizziness 8 - learning
+ * 9 - gold detection 10 - monster detection 11 - forgetfulness
+ * 12 - water 13 - blindness 14 - confusion
+ * 15 - heroism 16 - sturdiness 17 - giant strength
+ * 18 - fire resistance 19 - treasure finding 20 - instant healing
+ * 21 - cure dianthroritis 22 - poison 23 - see invisible
+ */
+char potprob[] = { 0, 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 20, 22, 22, 23, 23 };
+
+char nlpts[] = { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7 };
+char nch[] = { 0, 0, 0, 1, 1, 1, 2, 2, 3, 4 };
+char nplt[] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 4 };
+char ndgg[] = { 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5 };
+char nsw[] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3 };
diff --git a/larn/datfiles/larn.help b/larn/datfiles/larn.help
new file mode 100644
index 00000000..0e5edc5a
--- /dev/null
+++ b/larn/datfiles/larn.help
@@ -0,0 +1,140 @@
+5 Welcome to the game of Larn. At this moment, you face a great problem.
+Your daughter has contracted a strange disease, and none of your home remedies
+seem to have any effect. You sense that she is in mortal danger, and you must
+try to save her. Time ago you heard of a land of great danger and opportunity.
+Perhaps here is the solution you need.
+
+ It has been said that there once was a great magician who called himself
+Polinneaus. Many years ago, after having many miraculous successes, Polinneaus
+retired to the caverns of Larn, where he devoted most of his time to the
+creation of magic. Rumors have it that one day Polinneaus set out to dispel
+an attacking army in a forest some distance to the north. It is believed that
+here he met his demise.
+
+ The caverns of Larn, it is thought, must be magnificent in design,
+and contain much magic and treasure. One option you have is to undertake a
+journey into these caverns.
+
+
+ Good Luck! You're going to need it!
+
+
+
+
+ Help File for The Caverns of Larn
+
+h move to the left H run left . stay here
+j move down J run down Z teleport yourself
+k move up K run up c cast a spell
+l move to the right L run right r read a scroll
+y move northwest Y run northwest q quaff a potion
+u move northeast U run northeast W wear armor
+b move southwest B run southwest T take off armor
+n move southeast N run southeast w wield a weapon
+^ identify a trap g give present pack weight P give tax status
+d drop an item i inventory your pockets Q quit the game
+v print program version S save the game D list all items found
+? this help screen A create diagnostic file e eat something
+ (wizards only)
+larn ++ restore checkpointed game
+larn -s list the scoreboard
+larn -i list scores with inventories
+larn -n suppress welcome message when beginning a game
+larn -h print out all the command line options
+larn -<number> specify difficulty of the game (may be used with -n)
+larn -o<optsfile> specify the .larnopts file to be used
+larn -c create new scoreboards -- prompts for a password
+ Special Notes
+
+When dropping gold, if you type '*' as your amount, all your gold gets dropped.
+In general, typing in '*' means all of what your interested in. This is true
+when visiting the bank, or when contributing at altars.
+
+Larn may need a VT100 to operate. A check is made of the environment variable
+"TERM" and it must be equal to "vt100". This only applies if
+the game has been compiled with "VT100" defined in the Makefile. If compiled
+to use termcap, there are no terminal restrictions, save needing cm, ce, & cl
+termcap entries.
+
+When in the store, trading post, school, or home, an <escape> will get you out.
+
+larn -l print out the larn log file
+
+When casting a spell, if you need a list of spells you can cast, type 'D' as
+the first letter of your spell. The available list of spells will be shown,
+after which you may enter the spell code. This only works on the 1st letter
+of the spell you are casting.
+
+The Author of Larn is Noah Morgan (1982-3), Copying for Profit is Prohibited
+Copyright 1986 by Noah Morgan, All Rights Reserved.
+ Background Information for Larn
+
+ Welcome to the game of Larn. At this moment, you face a great problem.
+Your daughter has contracted a strange disease, and none of your home remedies
+seem to have any effect. You sense that she is in mortal danger, and you must
+try to save her. Time ago you heard of a land of great danger and opportunity.
+Perhaps here is the solution you need.
+
+ It has been said that there once was a great magician who called himself
+Polinneaus. Many years ago, after having many miraculous successes, Polinneaus
+retired to the caverns of Larn, where he devoted most of his time to the
+creation of magic. Rumors have it that one day Polinneaus set out to dispel
+an attacking army in a forest some distance to the north. It is believed that
+here he met his demise.
+
+ The caverns of Larn, it is thought, must be magnificent in design,
+and contain much magic and treasure. One option you have is to undertake a
+journey into these caverns.
+
+ Good Luck! You're going to need it!
+
+
+
+ How to use the .larnopts option file
+
+The file ".larnopts", if used, should be in your home directory (see -o).
+A sequence of words terminated by whitespace is used to specify options.
+
+ Word Meaning
+
+ bold-objects select bold display of objects
+ inverse-objects select inverse video display of objects
+ no-introduction do not display intro message
+ enable-checkpointing turn on periodic checkpointing
+ no-beep disable beeping of the terminal
+ male choose your sex to be a man
+ female choose your sex to be a woman
+ name: "your name" choose your playing name
+ monster: "monst name" choose a name for a monster
+ savefile: "save-file-name" define what the savegame filename will be
+
+Your name and monster names must be enclosed in double quotation marks and may
+be up to 34 characters long. Longer names are truncated. Anything enclosed in
+quotation marks is considered one word, and must be separated from other words
+by whitespace.
+
+ Explanation of the Larn scoreboard facility
+
+ Larn supports TWO scoreboards, one for winners, and one for deceased
+characters. Each player (by userid or playerid, see UIDSCORE in Makefile)
+is allowed one slot on each scoreboard, if the score is in the top ten for
+that scoreboard. This design helps insure that frequent players of Larn
+do not hog the scoreboard, and gives more players a chance for glory. Level
+of difficulty is also noted on the scoreboards, and this takes precedence
+over score for determining what entry is on the scoreboard. For example:
+if "Yar, the Bug Slayer" has a score of 128003 on the scoreboard at diff 0,
+then his game at diff 1 and a score of 4112 would replace his previous
+entry on the scoreboard. Note that when a player dies, his inventory is
+stored in the scoreboard so that everyone can see what items the player had
+at the time of his death.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/larn/datfiles/larnmaze b/larn/datfiles/larnmaze
new file mode 100644
index 00000000..37a89c34
--- /dev/null
+++ b/larn/datfiles/larnmaze
@@ -0,0 +1,288 @@
+@###################################################################
+# # . # # # # # . #
+# D D . . D . #
+###D########################################## # # ###D###
+# -# #. # # ################ . .#
+# ####### ######## ############ D #### # # #
+# ... #.# # # # . # # # #### # ############ # ###D###
+# #.# # # ## # # # ############ #### # #- # # # #. #
+# . # # # # ## #- # # # - D #### # # . D # #.# # ... #
+# # #.# # # # # # . . # # # # # # #-# # ~.! #
+###D### ### #######D## # ############ ###### ########## ### #######
+# # @ .# # ..... ...#
+###D###########################################################D###
+# . #.....# # # # -# # # # # #
+# ..... . D D D D. #
+# #.....# # # # # # .# # # #
+###################################################################
+
+###################################################################
+#.. . D # . # #- #
+############# ######### # ## ### ##### ## #### ###### ####### ### #
+#.#!#~# # # .-# # #- # # # # -# # # #
+# # #.# . # ####### # # # # # # # # # #####
+# # ..# ##### # # # #### # ## ## ## # ###### ####### # #
+# - ..D # D # . D # # # #.##### ## ## # #. #.# #..# # ### #
+####### ####### ### # # # # # # D # D D #..D # #
+#- # # # #### # ###### # ## # #. # #..# #####
+### #######################- # # # ###################### # #
+# ... # . #..# ### # - .. . #. ### #
+# # # # ### #################### # # #
+# ### #
+################################################################# #
+#- D ### # # # #
+# . # # # D #
+###################################################################
+
+###################################################################
+# .. #
+# ############## ############################################## # #
+# # # # # .. # # #
+# #D## # # ############D################# ########### # # #
+######### #- # # # #- D # # ~ # # # # # # #
+# # # # # # # ### # # # D - # # ####### # # # #
+# .... # #### # # # #!# # # ###### .. #.# # # # # # #
+# .... # # # # ### # # # # #########D#### # ### # # # # #
+# .... ######## # # D # #- # #.. # ...#.# # #.# # # # # #
+# # # ### # #### #.- D - #.# #.#.# # # # # #
+#####DD## ######## # # D D. # # # #...# # # # # #
+# # ..# # # # ############################## # ##### # # # # #
+# ......# # # # # # # # # #
+# ####### ###### ################################ ######### # ### #
+# .D. # #
+###################################################################
+
+###################################################################
+# ## ## ### ## #
+# ##### ## ..- ## ##.## ## #
+# # ! ## ## . ## ## .## .. ## #
+# #....###### ## ## ## . ## ## #
+# # - # ## ##D# ## . ## ## #
+# #####D ~ ####### ###........ ## ... ## ## #
+# # # ## ## .... ## . ## ## #
+# #. ######## ## ## . - ####D#### - #
+# #.- #...## ## ... ## ### ...... ## ## #
+# #. #..## ## ######### ## ... ## ### ## .. #
+# #.. #.## ## ## - ## . #### ## ## ##### ## #
+# #####D## ## ## ###### ## ## ####### ## #
+# D -.## #### ######## ##DD## ######## #D #
+# ###### ... ## ########## ## #
+#### . . ###
+###################################################################
+
+###################################################################
+# #
+# ####.########################################## ## ##########
+# # #.#.#.# #.. #. # # #
+####### # # # # # ##### #! # ########### # ### #
+# # # # # # # ##...## # # # # # #-# #
+# ..- D # # # # # ## . ## ####D##### .. ### # # # #
+# # # # ##. ~ .## # # ### # # ##### # #
+############ # # # # ## . . .## #...# .. #.# # # # #
+# .. .# # # # # ## - ## # # D.D # ######### #
+# . D # # # # ##.......## ####D#####.# # #
+# - . # # # # # ## ## # . # ### ########### #
+############ #.#.# # ###D### # . #....# # #
+# # #-# D .. # .# ###....## ##-### #
+#### ########################################## ###### ### #
+# . #
+###################################################################
+
+###################################################################
+# #
+# ###########################D####### ## #
+# ####################### # ##...... ## ## #
+# ########D###### # # !##.... ## ## #
+# ############ ## ## ... # # #...## ~ ## ###### #
+# # # # # ...... # # # .. ##### ## #
+# # - .. # # # ########### # # . ######### ## #
+# ##### ##### # # # # #... ## ## #
+# # # ########## ######## ########DD#### ####### #
+# # # .... # # # # # ## ## #
+# ##### # # ....# # ######### # # ##### ## #
+# #- ######D##########..# # ######### # - #.. ## ## #
+# ##### # # # #... #.....## #
+# # ################### ###############... #### # ######
+# # #
+###################################################################
+
+###################################################################
+# #
+########### ##### ##### #####D#### ##### ###### #
+#.. # #-..D ###### ## # ## # ## ..## ### #### #
+# #### ### ##### # ## # ##### # ## ### ## # # #
+# # # # # # ##### # ## # # #### # #..##### - ### #
+# # # ####### ### #...# # ######## # # #~. .... # #
+# # # # #...# # # ######### ############## #
+# # ###### ####### # ### ### # .. # #
+# # # - # #-#####!# # # #### ## #### # #
+# ###### # ########## #.. ....# # ######## # # # ## ## #
+# -.# ##### ####...## # . .# #..# # ## # #
+# #### ###### #.### #####.#### #### ### ## # #
+# #- #######....#### ...... #.# . # ## # #
+# ####### ##### ###########.############### ### #
+# . #
+###################################################################
+
+###################################################################
+# # #- . # # # # # # # # #
+# # # #####.##### # # # # # # # # # # ###########D########### #
+# # ##### # # ### # # # # # # # # # ### #.... # # # #
+# # # # # # # # # # # # # # #.!. -.. #.##.# # #
+# # . - # # ####### # # # # # # # # # ########## ## # #
+#.####### # # D # . # # #
+#. -# ################################################### #
+# ##### D. . #
+# # ### ###D### ### ### ###D### ### ### ###D### ###.### #
+# # ###### ### .# .# #. # # # # # # # # . # #
+# ### # -# ### .#. - .# # # #...- # # .. # # -..# # . # #
+# # # ### #. ~ .# # # # # # # # .. .# # # #
+#.###### # ### # # #.....# # # # # # # # # #
+# # ####### ####### ####### ####### ####### ####### ####### #
+# # ... .. #
+###################################################################
+
+###################################################################
+# # . # ### # # # # . #
+# D D . # . D . #
+############################################### # # ###D###
+# -# #. # # ################ . .#
+# #######D######## ############ # #### # # #
+# ... #. # #!~ . # # # #--# # ############ #####D###
+# #.# # # ## # # # ############ #--# # #- # # # #. #
+# . # #-# # ## #- # # # - D ## # # # . D #### #.# # ... #
+# # #-# # # # # # . . # # # # # # #-# # -.- #
+###D### ### ####### ## # ############ ###### ########## ### ###D###
+# # @ . ..... ...#
+##################################### ###############D###
+# . #.....# # # # -# # # # #
+# ..... . D D D D. #
+# #.....# # # # # .# # # #
+###################################################################
+
+###################################################################
+#.. . # D . #- #
+### ######### ######### # ## ### ##### ## ########### ####### ### #
+#.# # # # .-# # #- # # # # -# # # #
+# # #.# . # ####### # # # # # # # # # #####
+# # ..####### # # # #### # ## ## ##!# ###### ####### # #
+# - ..D # D # . D # # # #.##### ## ## # #. #.# #..# # ### #
+####### ####### ### # # # # # # D # D D #..D # #
+#- # # # #### # ###### # ## # #. # #..# #####
+### #######################- # # # ###################### # #
+# ... # . #..# ### # - .. . #. ### #
+# # # # #-# #################### # # #
+# # -# #
+################################-################################ #
+#-..... # ####D ### # # # #
+#~..... # # # # D #
+###################################################################
+
+###################################################################
+# .. #
+# ############## ############################################## # #
+# # # # # .. # # #
+# #D## # # ############D################# ########### # # #
+######### #- # # # #- D # #.!..# # # # # # #
+# # # # # # # # ### ## # #....D - # # ####### # # # #
+# .... # #### # # # #~# # # ###### .. #.# # # # # # #
+###....## # # # ###.# # # #########D## # # ### # # # # #
+# .... ######## # # D .# #- # .. # ...#.# # #.# # # # # #
+# # ## # ### .# #### .- D - #.# #.#.# # # # # #
+#####DD## ######## #... .# . # # # #.#. # # # # #
+# # ..# # # ############################## # # ##### # # # #
+# ......# # # # # # # # # # #
+# ####### ###### ################################D# ######### ### #
+# .D. #-.-#
+###################################################################
+
+###################################################################
+# ## ## ## ## ## #
+# ############## ## ..- ## ## . ## ## #
+# # # ## ## . ## ## . ##.. ## #
+# #....###### ## ## ######## ####### . ## ## #
+# # - # ## ## ##D# ## . ## ## #
+# # D###### ###........ ## ... ## ###### #
+# # # ## ## .... ## . ## ## - # #
+# #. ######## ## ## . - ####D####.. D #
+# #.- #...## ## ... ## ### ...... ## ##### #
+# #. #..## ## ######### ## ... ## ### ## .. #
+# #.. #.## ## ## - ## . #### ## ## ##### ## #
+# #####D####### # ## ## ##..## ## ## ## ## ## #
+# D -.## # # #### ##.-.-## ##DD## ### #### ## #
+# ######. ...# #### ## #### ##### ## ##D#
+####~!.... D . . #
+###################################################################
+
+###################################################################
+# #
+# ####.########################################## ## ##########
+# # #.#.#.# #.. . # # #
+####### # # # # # ############# # ########### # ### #
+# # # # # # # --##...##-- # # # # #-# #
+# ..- D # # # # # #-## . ##-# ####D##### .. ### # # # #
+# # # # ###. .### # ~ # ### ### ##### # #
+############ # # # # ## . . .## #...# .. #.# # #
+# .. .# # # # # ## - ## # # D. # ######### #
+# . D # # # # ###.......### ####D#####.# # #
+# - . # # # # # -## ##- # . ### ########### #
+############ #.#.# # ######D###### # . ....# # #
+# #!#-# # .. # . ###....## ##-### #
+#### ############################## ########## ###### ### #
+# D . #
+###################################################################
+
+###################################################################
+# #
+# ###############D####################D# #
+# ####################### # ##...... # #
+# ########D###### # # ##.... # #
+# ############### ## ## ... # # #...## ##### #
+# # ~ # # #!...... # # # .. ##### # #
+# # - .. # # # ########### # # . ######### # #
+# ##### ######## # # # # # #... ## # #
+# # # # ########## ######## ########D #### ###### #
+# # # ....# # # # # # ## # #
+# ##### # ###### # ....# # ######### # # #####D# #
+# #- ## # #######..# # ######### # - #.. #
+# ##### # # # #... #..... #
+# # ################### ###############... #### ######
+# # #
+###################################################################
+
+###################################################################
+# # #
+########### ##### # #####D#### ##### ###### #
+#.. # #~..D ###### ## # ## # ## ..## ### #### #
+# #### ### ##### # ## # ##### # ## ### ## # # #
+# # # # # # ##### # ## # # #### # #..##### - ### #
+# # # ####### ### #...# # ######## # # #!. .... # #
+# # # # #...# # # ######### ############## #
+# # ###### ####### # ### ### # .. # #
+# # # - # #- # # # ######## #### # #
+# # # ########## #.. ....# # ######## # ## ## #
+# # -. ##### ####...## # . .# .. # # #
+# # ###### ##### #####.#### ####### # #
+# # - #######....#### ...... #.# . # ## # #
+# ######### ##### ###########.############### ### #
+# . #
+###################################################################
+
+###################################################################
+# D D #-..........# # # # # #
+#D#D# #####.#####.# # # # # # #############D########### #
+# # ##### #.#~###.# # # # # # ### .... # # # #
+#D# # #.......# # # # # # # . . -.. #. #.# # #
+# # . - # #.####### # # # # # ################## # #
+#D####### #. # D # . # # #
+#. D D -# ################################################### #
+# ###### . . #
+# # D ### ###D### ####### ###D### ####### ###D### ####### #
+# # ###### # # .# .# #. # # # # # # # # . # #
+# ### -# # # .#. - .# # # #...- # # .. # # -..# # . # #
+#DD# # # # #. .# # # # # # # # .. .# # # #
+#.###### # # # # #.....# # # # # # ! # # # #
+# # ####### ####### ### ### ####### ### ### ####### ### ### #
+# # ... .. #
+###################################################################
+
diff --git a/larn/datfiles/larnopts b/larn/datfiles/larnopts
new file mode 100644
index 00000000..17216edf
--- /dev/null
+++ b/larn/datfiles/larnopts
@@ -0,0 +1,12 @@
+process-name: "Winnie-the-Pooh"
+enable-checkpointing
+bold-objects
+male
+play-day-play
+no-introduction
+name: "King of the Realm"
+monster: "abominable snowman"
+monster: "tooth fairy"
+monster: "Yaccerous Lexicous"
+savefile: "/save/noah/games/Larn12.0.sav"
+
diff --git a/larn/datfiles/lfortune b/larn/datfiles/lfortune
new file mode 100644
index 00000000..748f7f61
--- /dev/null
+++ b/larn/datfiles/lfortune
@@ -0,0 +1,34 @@
+gem value = gem * 2 ^ perfection
+sitting down can have unexpected results
+don't pry into the affairs of others
+drinking can be hazardous to your health
+beware of the gusher!
+some monsters are greedy
+nymphs have light fingers
+try kissing a disenchantress!
+hammers and brains don't mix
+what does a potion of cure dianthroritis taste like?
+hit point gain/loss when raising a level depends on constitution
+healing a mighty wizard can be exhilarating
+be sure to pay your taxes
+are Vampires afraid of something?
+some dragons can fly
+dos thou strive for perfection?
+patience is a virtue, unless your daughter dies
+what does the Eye of Larn see in its guardian?
+a level 25 player casts like crazy!
+energy rings affect spell regeneration
+difficulty affects regeneration
+control of the pesty spirits is most helpful
+don't fall into a bottomless pit
+dexterity allows you to carry more
+you can get 2 points of WC for the price of one
+never enter the dungeon naked! the monsters will laugh at you!
+did someone put itching powder in your armor?
+you klutz!
+avoid opening doors. you never know whats on the other side.
+infinite regeneration ---> temptation
+the greatest weapon in the game has not the highest Weapon Class
+you can't buy the most powerful scroll
+identify things before you use them
+there's more than one way through a wall
diff --git a/larn/diag.c b/larn/diag.c
new file mode 100644
index 00000000..4ed557d1
--- /dev/null
+++ b/larn/diag.c
@@ -0,0 +1,314 @@
+/* diag.c Larn is copyrighted 1986 by Noah Morgan. */
+#include <sys/types.h>
+#include <sys/times.h>
+#include <sys/stat.h>
+#include "header.h"
+extern long int initialtime;
+extern int rmst,maxitm,lasttime;
+extern char nosignal;
+static struct tms cputime;
+/*
+ ***************************
+ DIAG -- dungeon diagnostics
+ ***************************
+
+ subroutine to print out data for debugging
+ */
+#ifdef EXTRA
+static int rndcount[16];
+diag()
+ {
+ register int i,j;
+ int hit,dam;
+ cursors(); lwclose();
+ if (lcreat(diagfile) < 0) /* open the diagnostic file */
+ {
+ lcreat((char*)0); lprcat("\ndiagnostic failure\n"); return(-1);
+ }
+
+ write(1,"\nDiagnosing . . .\n",18);
+ lprcat("\n\nBeginning of DIAG diagnostics ----------\n");
+
+/* for the character attributes */
+
+ lprintf("\n\nPlayer attributes:\n\nHit points: %2d(%2d)",(long)c[HP],(long)c[HPMAX]);
+ lprintf("\ngold: %d Experience: %d Character level: %d Level in caverns: %d",
+ (long)c[GOLD],(long)c[EXPERIENCE],(long)c[LEVEL],(long)level);
+ lprintf("\nTotal types of monsters: %d",(long)MAXMONST+8);
+
+ lprcat("\f\nHere's the dungeon:\n\n");
+
+ i=level;
+ for (j=0; j<MAXLEVEL+MAXVLEVEL; j++)
+ {
+ newcavelevel(j);
+ lprintf("\nMaze for level %s:\n",levelname[level]);
+ diagdrawscreen();
+ }
+ newcavelevel(i);
+
+ lprcat("\f\nNow for the monster data:\n\n");
+ lprcat(" Monster Name LEV AC DAM ATT DEF GOLD HP EXP \n");
+ lprcat("--------------------------------------------------------------------------\n");
+ for (i=0; i<=MAXMONST+8; i++)
+ {
+ lprintf("%19s %2d %3d ",monster[i].name,(long)monster[i].level,(long)monster[i].armorclass);
+ lprintf(" %3d %3d %3d ",(long)monster[i].damage,(long)monster[i].attack,(long)monster[i].defense);
+ lprintf("%6d %3d %6d\n",(long)monster[i].gold,(long)monster[i].hitpoints,(long)monster[i].experience);
+ }
+
+ lprcat("\n\nHere's a Table for the to hit percentages\n");
+ lprcat("\n We will be assuming that players level = 2 * monster level");
+ lprcat("\n and that the players dexterity and strength are 16.");
+ lprcat("\n to hit: if (rnd(22) < (2[monst AC] + your level + dex + WC/8 -1)/2) then hit");
+ lprcat("\n damage = rund(8) + WC/2 + STR - c[HARDGAME] - 4");
+ lprcat("\n to hit: if rnd(22) < to hit then player hits\n");
+ lprcat("\n Each entry is as follows: to hit / damage / number hits to kill\n");
+ lprcat("\n monster WC = 4 WC = 20 WC = 40");
+ lprcat("\n---------------------------------------------------------------");
+ for (i=0; i<=MAXMONST+8; i++)
+ {
+ hit = 2*monster[i].armorclass+2*monster[i].level+16;
+ dam = 16 - c[HARDGAME];
+ lprintf("\n%20s %2d/%2d/%2d %2d/%2d/%2d %2d/%2d/%2d",
+ monster[i].name,
+ (long)(hit/2),(long)max(0,dam+2),(long)(monster[i].hitpoints/(dam+2)+1),
+ (long)((hit+2)/2),(long)max(0,dam+10),(long)(monster[i].hitpoints/(dam+10)+1),
+ (long)((hit+5)/2),(long)max(0,dam+20),(long)(monster[i].hitpoints/(dam+20)+1));
+ }
+
+ lprcat("\n\nHere's the list of available potions:\n\n");
+ for (i=0; i<MAXPOTION; i++) lprintf("%20s\n",&potionname[i][1]);
+ lprcat("\n\nHere's the list of available scrolls:\n\n");
+ for (i=0; i<MAXSCROLL; i++) lprintf("%20s\n",&scrollname[i][1]);
+ lprcat("\n\nHere's the spell list:\n\n");
+ lprcat("spell name description\n");
+ lprcat("-------------------------------------------------------------------------------------------\n\n");
+ for (j=0; j<SPNUM; j++)
+ {
+ lprc(' '); lprcat(spelcode[j]);
+ lprintf(" %21s %s\n",spelname[j],speldescript[j]);
+ }
+
+ lprcat("\n\nFor the c[] array:\n");
+ for (j=0; j<100; j+=10)
+ {
+ lprintf("\nc[%2d] = ",(long)j); for (i=0; i<9; i++) lprintf("%5d ",(long)c[i+j]);
+ }
+
+ lprcat("\n\nTest of random number generator ----------------");
+ lprcat("\n for 25,000 calls divided into 16 slots\n\n");
+
+ for (i=0; i<16; i++) rndcount[i]=0;
+ for (i=0; i<25000; i++) rndcount[rund(16)]++;
+ for (i=0; i<16; i++) { lprintf(" %5d",(long)rndcount[i]); if (i==7) lprc('\n'); }
+
+ lprcat("\n\n"); lwclose();
+ lcreat((char*)0); lprcat("Done Diagnosing . . .");
+ return(0);
+ }
+/*
+ subroutine to count the number of occurrences of an object
+ */
+dcount(l)
+ int l;
+ {
+ register int i,j,p;
+ int k;
+ k=0;
+ for (i=0; i<MAXX; i++)
+ for (j=0; j<MAXY; j++)
+ for (p=0; p<MAXLEVEL; p++)
+ if (cell[p*MAXX*MAXY+i*MAXY+j].item == l) k++;
+ return(k);
+ }
+
+/*
+ subroutine to draw the whole screen as the player knows it
+ */
+diagdrawscreen()
+ {
+ register int i,j,k;
+
+ for (i=0; i<MAXY; i++)
+
+/* for the east west walls of this line */
+ {
+ for (j=0; j<MAXX; j++) if (k=mitem[j][i]) lprc(monstnamelist[k]); else
+ lprc(objnamelist[item[j][i]]);
+ lprc('\n');
+ }
+ }
+#endif
+
+/*
+ to save the game in a file
+ */
+static long int zzz=0;
+savegame(fname)
+ char *fname;
+ {
+ register int i,k;
+ register struct sphere *sp;
+ struct stat statbuf;
+ nosignal=1; lflush(); savelevel();
+ ointerest();
+ if (lcreat(fname) < 0)
+ {
+ lcreat((char*)0); lprintf("\nCan't open file <%s> to save game\n",fname);
+ nosignal=0; return(-1);
+ }
+
+ set_score_output();
+ lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
+ for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
+ if (beenhere[k])
+ lwrite((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
+ times(&cputime); /* get cpu time */
+ c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60;
+ lwrite((char*)&c[0],100*sizeof(long));
+ lprint((long)gtime); lprc(level);
+ lprc(playerx); lprc(playery);
+ lwrite((char*)iven,26); lwrite((char*)ivenarg,26*sizeof(short));
+ for (k=0; k<MAXSCROLL; k++) lprc(scrollname[k][0]);
+ for (k=0; k<MAXPOTION; k++) lprc(potionname[k][0]);
+ lwrite((char*)spelknow,SPNUM); lprc(wizard);
+ lprc(rmst); /* random monster generation counter */
+ for (i=0; i<90; i++) lprc(itm[i].qty);
+ lwrite((char*)course,25); lprc(cheat); lprc(VERSION);
+ for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */
+ for (sp=spheres; sp; sp=sp->p)
+ lwrite((char*)sp,sizeof(struct sphere)); /* save spheres of annihilation */
+ time(&zzz); lprint((long)(zzz-initialtime));
+ lwrite((char*)&zzz,sizeof(long));
+ if (fstat(lfd,&statbuf)< 0) lprint(0L);
+ else lprint((long)statbuf.st_ino); /* inode # */
+ lwclose(); lastmonst[0] = 0;
+#ifndef VT100
+ setscroll();
+#endif VT100
+ lcreat((char*)0); nosignal=0;
+ return(0);
+ }
+
+restoregame(fname)
+ char *fname;
+ {
+ register int i,k;
+ register struct sphere *sp,*sp2;
+ struct stat filetimes;
+ cursors(); lprcat("\nRestoring . . ."); lflush();
+ if (lopen(fname) <= 0)
+ {
+ lcreat((char*)0); lprintf("\nCan't open file <%s>to restore game\n",fname);
+ nap(2000); c[GOLD]=c[BANKACCOUNT]=0; died(-265); return;
+ }
+
+ lrfill((char*)beenhere,MAXLEVEL+MAXVLEVEL);
+ for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
+ if (beenhere[k])
+ lrfill((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
+
+ lrfill((char*)&c[0],100*sizeof(long)); gtime = lrint();
+ level = c[CAVELEVEL] = lgetc();
+ playerx = lgetc(); playery = lgetc();
+ lrfill((char*)iven,26); lrfill((char*)ivenarg,26*sizeof(short));
+ for (k=0; k<MAXSCROLL; k++) scrollname[k][0] = lgetc();
+ for (k=0; k<MAXPOTION; k++) potionname[k][0] = lgetc();
+ lrfill((char*)spelknow,SPNUM); wizard = lgetc();
+ rmst = lgetc(); /* random monster creation flag */
+
+ for (i=0; i<90; i++) itm[i].qty = lgetc();
+ lrfill((char*)course,25); cheat = lgetc();
+ if (VERSION != lgetc()) /* version number */
+ {
+ cheat=1;
+ lprcat("Sorry, But your save file is for an older version of larn\n");
+ nap(2000); c[GOLD]=c[BANKACCOUNT]=0; died(-266); return;
+ }
+
+ for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc(); /* genocide info */
+ for (sp=0,i=0; i<c[SPHCAST]; i++)
+ {
+ sp2 = sp;
+ sp = (struct sphere *)malloc(sizeof(struct sphere));
+ if (sp==0) { write(2,"Can't malloc() for sphere space\n",32); break; }
+ lrfill((char*)sp,sizeof(struct sphere)); /* get spheres of annihilation */
+ sp->p=0; /* null out pointer */
+ if (i==0) spheres=sp; /* beginning of list */
+ else sp2->p = sp;
+ }
+
+ time(&zzz);
+ initialtime = zzz-lrint();
+ fstat(fd,&filetimes); /* get the creation and modification time of file */
+ lrfill((char*)&zzz,sizeof(long)); zzz += 6;
+ if (filetimes.st_ctime > zzz) fsorry(); /* file create time */
+ else if (filetimes.st_mtime > zzz) fsorry(); /* file modify time */
+ if (c[HP]<0) { died(284); return; } /* died a post mortem death */
+
+ oldx = oldy = 0;
+ i = lrint(); /* inode # */
+ if (i && (filetimes.st_ino!=i)) fsorry();
+ lrclose();
+ if (strcmp(fname,ckpfile) == 0)
+ {
+ if (lappend(fname) < 0) fcheat(); else { lprc(' '); lwclose(); }
+ lcreat((char*)0);
+ }
+ else if (unlink(fname) < 0) fcheat(); /* can't unlink save file */
+/* for the greedy cheater checker */
+ for (k=0; k<6; k++) if (c[k]>99) greedy();
+ if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy();
+ if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) /* if patch up lev 25 player */
+ {
+ long tmp;
+ tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
+ c[EXPERIENCE] = skill[24];
+ raiseexperience((long)tmp);
+ }
+ getlevel(); lasttime=gtime;
+ }
+
+/*
+ subroutine to not allow greedy cheaters
+ */
+greedy()
+ {
+#if WIZID
+ if (wizard) return;
+#endif
+
+ lprcat("\n\nI am so sorry, but your character is a little TOO good! Since this\n");
+ lprcat("cannot normally happen from an honest game, I must assume that you cheated.\n");
+ lprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n");
+ lprcat("to continue.\n"); nap(5000); c[GOLD]=c[BANKACCOUNT]=0; died(-267); return;
+ }
+
+/*
+ subroutine to not allow altered save files and terminate the attempted
+ restart
+ */
+fsorry()
+ {
+ lprcat("\nSorry, but your savefile has been altered.\n");
+ lprcat("However, seeing as I am a good sport, I will let you play.\n");
+ lprcat("Be advised though, you won't be placed on the normal scoreboard.");
+ cheat = 1; nap(4000);
+ }
+
+/*
+ subroutine to not allow game if save file can't be deleted
+ */
+fcheat()
+ {
+#if WIZID
+ if (wizard) return;
+#endif
+
+ lprcat("\nSorry, but your savefile can't be deleted. This can only mean\n");
+ lprcat("that you tried to CHEAT by protecting the directory the savefile\n");
+ lprcat("is in. Since this is unfair to the rest of the larn community, I\n");
+ lprcat("cannot let you play this game.\n");
+ nap(5000); c[GOLD]=c[BANKACCOUNT]=0; died(-268); return;
+ }
diff --git a/larn/display.c b/larn/display.c
new file mode 100644
index 00000000..b49de50c
--- /dev/null
+++ b/larn/display.c
@@ -0,0 +1,434 @@
+/* display.c Larn is copyrighted 1986 by Noah Morgan. */
+#include "header.h"
+#define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
+
+static int minx,maxx,miny,maxy,k,m;
+static char bot1f=0,bot2f=0,bot3f=0;
+char always=0;
+/*
+ bottomline()
+
+ now for the bottom line of the display
+ */
+bottomline()
+ { recalc(); bot1f=1; }
+bottomhp()
+ { bot2f=1; }
+bottomspell()
+ { bot3f=1; }
+bottomdo()
+ {
+ if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
+ if (bot2f) { bot2f=0; bot_hpx(); }
+ if (bot3f) { bot3f=0; bot_spellx(); }
+ }
+
+static void botsub();
+
+bot_linex()
+ {
+ register int i;
+ if (cbak[SPELLS] <= -50 || (always))
+ {
+ cursor( 1,18);
+ if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]);
+ else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]);
+ lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]);
+ if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]);
+ else lprintf(" %-2d",(long)c[LEVEL]);
+ lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]);
+ lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
+ (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]);
+ lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
+ (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]);
+
+ if ((level==0) || (wizard)) c[TELEFLAG]=0;
+ if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
+ lprintf(" Gold: %-6d",(long)c[GOLD]);
+ always=1; botside();
+ c[TMP] = c[STRENGTH]+c[STREXTRA];
+ for (i=0; i<100; i++) cbak[i]=c[i];
+ return;
+ }
+
+ botsub(makecode(SPELLS,8,18),"%3d");
+ if (c[SPELLMAX]>99) botsub(makecode(SPELLMAX,12,18),"%3d)");
+ else botsub(makecode(SPELLMAX,12,18),"%2d) ");
+ botsub(makecode(HP,5,19),"%3d");
+ botsub(makecode(HPMAX,9,19),"%3d");
+ botsub(makecode(AC,21,18),"%-3d");
+ botsub(makecode(WCLASS,30,18),"%-3d");
+ botsub(makecode(EXPERIENCE,49,18),"%-9d");
+ if (c[LEVEL] != cbak[LEVEL])
+ { cursor(59,18); lprcat(class[c[LEVEL]-1]); }
+ if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d");
+ else botsub(makecode(LEVEL,40,18)," %-2d");
+ c[TMP] = c[STRENGTH]+c[STREXTRA]; botsub(makecode(TMP,18,19),"%-2d");
+ botsub(makecode(INTELLIGENCE,25,19),"%-2d");
+ botsub(makecode(WISDOM,32,19),"%-2d");
+ botsub(makecode(CONSTITUTION,39,19),"%-2d");
+ botsub(makecode(DEXTERITY,46,19),"%-2d");
+ botsub(makecode(CHARISMA,53,19),"%-2d");
+ if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG]))
+ {
+ if ((level==0) || (wizard)) c[TELEFLAG]=0;
+ cbak[TELEFLAG] = c[TELEFLAG];
+ cbak[CAVELEVEL] = level; cursor(59,19);
+ if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
+ }
+ botsub(makecode(GOLD,69,19),"%-6d");
+ botside();
+ }
+
+/*
+ special subroutine to update only the gold number on the bottomlines
+ called from ogold()
+ */
+bottomgold()
+ {
+ botsub(makecode(GOLD,69,19),"%-6d");
+/* botsub(GOLD,"%-6d",69,19); */
+ }
+
+/*
+ special routine to update hp and level fields on bottom lines
+ called in monster.c hitplayer() and spattack()
+ */
+bot_hpx()
+ {
+ if (c[EXPERIENCE] != cbak[EXPERIENCE])
+ {
+ recalc(); bot_linex();
+ }
+ else botsub(makecode(HP,5,19),"%3d");
+ }
+
+/*
+ special routine to update number of spells called from regen()
+ */
+bot_spellx()
+ {
+ botsub(makecode(SPELLS,9,18),"%2d");
+ }
+
+/*
+ common subroutine for a more economical bottomline()
+ */
+static struct bot_side_def
+ {
+ int typ;
+ char *string;
+ }
+ bot_data[] =
+ {
+ STEALTH,"stealth", UNDEADPRO,"undead pro", SPIRITPRO,"spirit pro",
+ CHARMCOUNT,"Charm", TIMESTOP,"Time Stop", HOLDMONST,"Hold Monst",
+ GIANTSTR,"Giant Str", FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity",
+ STRCOUNT,"Strength", SCAREMONST,"Scare", HASTESELF,"Haste Self",
+ CANCELLATION,"Cancel", INVISIBILITY,"Invisible", ALTPRO,"Protect 3",
+ PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk"
+ };
+
+botside()
+ {
+ register int i,idx;
+ for (i=0; i<17; i++)
+ {
+ idx = bot_data[i].typ;
+ if ((always) || (c[idx] != cbak[idx]))
+ {
+ if ((always) || (cbak[idx] == 0))
+ { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else
+ if (c[idx]==0) { cursor(70,i+1); lprcat(" "); }
+ cbak[idx]=c[idx];
+ }
+ }
+ always=0;
+ }
+
+static void
+botsub(idx,str)
+ register int idx;
+ char *str;
+ {
+ register int x,y;
+ y = idx & 0xff; x = (idx>>8) & 0xff; idx >>= 16;
+ if (c[idx] != cbak[idx])
+ { cbak[idx]=c[idx]; cursor(x,y); lprintf(str,(long)c[idx]); }
+ }
+
+/*
+ * subroutine to draw only a section of the screen
+ * only the top section of the screen is updated. If entire lines are being
+ * drawn, then they will be cleared first.
+ */
+int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
+draws(xmin,xmax,ymin,ymax)
+ int xmin,xmax,ymin,ymax;
+ {
+ register int i,idx;
+ if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
+ {
+ if (ymin==0) cl_up(79,ymax);
+ else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
+ xmin = -1;
+ }
+ d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */
+ drawscreen();
+ if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
+ {
+ for (i=ymin; i<ymax; i++)
+ {
+ idx = bot_data[i].typ;
+ if (c[idx])
+ {
+ cursor(70,i+1); lprcat(bot_data[i].string);
+ }
+ cbak[idx]=c[idx];
+ }
+ }
+ }
+
+/*
+ drawscreen()
+
+ subroutine to redraw the whole screen as the player knows it
+ */
+char screen[MAXX][MAXY],d_flag; /* template for the screen */
+drawscreen()
+ {
+ register int i,j,k;
+ int lastx,lasty; /* variables used to optimize the object printing */
+ if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY)
+ {
+ d_flag=1; clear(); /* clear the screen */
+ }
+ else
+ {
+ d_flag=0; cursor(1,1);
+ }
+ if (d_xmin<0)
+ d_xmin=0; /* d_xmin=-1 means display all without bottomline */
+
+ for (i=d_ymin; i<d_ymax; i++)
+ for (j=d_xmin; j<d_xmax; j++)
+ if (know[j][i]==0) screen[j][i] = ' '; else
+ if (k=mitem[j][i]) screen[j][i] = monstnamelist[k]; else
+ if ((k=item[j][i])==OWALL) screen[j][i] = '#';
+ else screen[j][i] = ' ';
+
+ for (i=d_ymin; i<d_ymax; i++)
+ {
+ j=d_xmin; while ((screen[j][i]==' ') && (j<d_xmax)) j++;
+ /* was m=0 */
+ if (j >= d_xmax) m=d_xmin; /* don't search backwards if blank line */
+ else
+ { /* search backwards for end of line */
+ m=d_xmax-1; while ((screen[m][i]==' ') && (m>d_xmin)) --m;
+ if (j<=m) cursor(j+1,i+1); else continue;
+ }
+ while (j <= m)
+ {
+ if (j <= m-3)
+ {
+ for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000;
+ if (k < 1000)
+ { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); }
+ }
+ lprc(screen[j++][i]);
+ }
+ }
+ setbold(); /* print out only bold objects now */
+
+ for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
+ for (j=d_xmin; j<d_xmax; j++)
+ {
+ if (k=item[j][i])
+ if (k != OWALL)
+ if ((know[j][i]) && (mitem[j][i]==0))
+ if (objnamelist[k]!=' ')
+ {
+ if (lasty!=i+1 || lastx!=j)
+ cursor(lastx=j+1,lasty=i+1); else lastx++;
+ lprc(objnamelist[k]);
+ }
+ }
+
+ resetbold(); if (d_flag) { always=1; botside(); always=1; bot_linex(); }
+ oldx=99;
+ d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
+ }
+
+/*
+ showcell(x,y)
+
+ subroutine to display a cell location on the screen
+ */
+showcell(x,y)
+ int x,y;
+ {
+ register int i,j,k,m;
+ if (c[BLINDCOUNT]) return; /* see nothing if blind */
+ if (c[AWARENESS]) { minx = x-3; maxx = x+3; miny = y-3; maxy = y+3; }
+ else { minx = x-1; maxx = x+1; miny = y-1; maxy = y+1; }
+
+ if (minx < 0) minx=0; if (maxx > MAXX-1) maxx = MAXX-1;
+ if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1;
+
+ for (j=miny; j<=maxy; j++)
+ for (m=minx; m<=maxx; m++)
+ if (know[m][j]==0)
+ {
+ cursor(m+1,j+1);
+ x=maxx; while (know[x][j]) --x;
+ for (i=m; i<=x; i++)
+ {
+ if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]);
+ else switch(k=item[i][j])
+ {
+ case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
+ case OIVDARTRAP: case OIVTRAPDOOR:
+ lprc(objnamelist[k]); break;
+
+ default: setbold(); lprc(objnamelist[k]); resetbold();
+ };
+ know[i][j]=1;
+ }
+ m = maxx;
+ }
+ }
+
+/*
+ this routine shows only the spot that is given it. the spaces around
+ these coordinated are not shown
+ used in godirect() in monster.c for missile weapons display
+ */
+show1cell(x,y)
+ int x,y;
+ {
+ if (c[BLINDCOUNT]) return; /* see nothing if blind */
+ cursor(x+1,y+1);
+ if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]);
+ else switch(k=item[x][y])
+ {
+ case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
+ case OIVDARTRAP: case OIVTRAPDOOR:
+ lprc(objnamelist[k]); break;
+
+ default: setbold(); lprc(objnamelist[k]); resetbold();
+ };
+ know[x][y]|=1; /* we end up knowing about it */
+ }
+
+/*
+ showplayer()
+
+ subroutine to show where the player is on the screen
+ cursor values start from 1 up
+ */
+showplayer()
+ {
+ cursor(playerx+1,playery+1);
+ oldx=playerx; oldy=playery;
+ }
+
+/*
+ moveplayer(dir)
+
+ subroutine to move the player from one room to another
+ returns 0 if can't move in that direction or hit a monster or on an object
+ else returns 1
+ nomove is set to 1 to stop the next move (inadvertent monsters hitting
+ players when walking into walls) if player walks off screen or into wall
+ */
+short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
+short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
+moveplayer(dir)
+ int dir; /* from = present room # direction = [1-north]
+ [2-east] [3-south] [4-west] [5-northeast]
+ [6-northwest] [7-southeast] [8-southwest]
+ if direction=0, don't move--just show where he is */
+ {
+ register int k,m,i,j;
+ if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
+ k = playerx + diroffx[dir]; m = playery + diroffy[dir];
+ if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
+ i = item[k][m]; j = mitem[k][m];
+ if (i==OWALL && c[WTW]==0) { nomove=1; return(yrepcount = 0); } /* hit a wall */
+ if (k==33 && m==MAXY-1 && level==1)
+ {
+ newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
+ if (item[k][m]==OENTRANCE)
+ { playerx=k; playery=m; positionplayer(); drawscreen(); return(0); }
+ }
+ if (j>0) { hitmonster(k,m); return(yrepcount = 0); } /* hit a monster*/
+ lastpx = playerx; lastpy = playery;
+ playerx = k; playery = m;
+ if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0); else return(1);
+ }
+
+/*
+ * function to show what magic items have been discovered thus far
+ * enter with -1 for just spells, anything else will give scrolls & potions
+ */
+static int lincount,count;
+seemagic(arg)
+ int arg;
+ {
+ register int i,number;
+ count = lincount = 0; nosignal=1;
+
+ if (arg== -1) /* if display spells while casting one */
+ {
+ for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
+ number = (number+2)/3 + 4; /* # lines needed to display */
+ cl_up(79,number); cursor(1,1);
+ }
+ else
+ {
+ resetscroll(); clear();
+ }
+
+ lprcat("The magic spells you have discovered thus far:\n\n");
+ for (i=0; i<SPNUM; i++)
+ if (spelknow[i])
+ { lprintf("%s %-20s ",spelcode[i],spelname[i]); seepage(); }
+
+ if (arg== -1)
+ {
+ seepage(); more(); nosignal=0;
+ draws(0,MAXX,0,number); return;
+ }
+
+ lincount += 3; if (count!=0) { count=2; seepage(); }
+
+ lprcat("\nThe magic scrolls you have found to date are:\n\n");
+ count=0;
+ for (i=0; i<MAXSCROLL; i++)
+ if (scrollname[i][0])
+ if (scrollname[i][1]!=' ')
+ { lprintf("%-26s",&scrollname[i][1]); seepage(); }
+
+ lincount += 3; if (count!=0) { count=2; seepage(); }
+
+ lprcat("\nThe magic potions you have found to date are:\n\n");
+ count=0;
+ for (i=0; i<MAXPOTION; i++)
+ if (potionname[i][0])
+ if (potionname[i][1]!=' ')
+ { lprintf("%-26s",&potionname[i][1]); seepage(); }
+
+ if (lincount!=0) more(); nosignal=0; setscroll(); drawscreen();
+ }
+
+/*
+ * subroutine to paginate the seemagic function
+ */
+seepage()
+ {
+ if (++count==3)
+ {
+ lincount++; count=0; lprc('\n');
+ if (lincount>17) { lincount=0; more(); clear(); }
+ }
+ }
diff --git a/larn/fortune.c b/larn/fortune.c
new file mode 100644
index 00000000..f410375d
--- /dev/null
+++ b/larn/fortune.c
@@ -0,0 +1,63 @@
+/* fortune.c Larn is copyrighted 1986 by Noah Morgan. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "header.h"
+/*
+ * function to return a random fortune from the fortune file
+ */
+static char *base=0; /* pointer to the fortune text */
+static char **flines=0; /* array of pointers to each fortune */
+static int fd=0; /* true if we have load the fortune info */
+static int nlines=0; /* # lines in fortune database */
+
+char *fortune(file)
+ char *file;
+ {
+ register char *p;
+ register int lines,tmp;
+ struct stat stat;
+ char *malloc();
+ if (fd==0)
+ {
+ if ((fd=open(file,O_RDONLY)) < 0) /* open the file */
+ return(0); /* can't find file */
+
+ /* find out how big fortune file is and get memory for it */
+ stat.st_size = 16384;
+ if ((fstat(fd,&stat) < 0) || ((base=malloc(1+stat.st_size)) == 0))
+ {
+ close(fd); fd= -1; free((char*)base); return(0); /* can't stat file */
+ }
+
+ /* read in the entire fortune file */
+ if (read(fd,base,stat.st_size) != stat.st_size)
+ {
+ close(fd); fd= -1; free((char*)base); return(0); /* can't read file */
+ }
+ close(fd); base[stat.st_size]=0; /* final NULL termination */
+
+ /* count up all the lines (and NULL terminate) to know memory needs */
+ for (p=base,lines=0; p<base+stat.st_size; p++) /* count lines */
+ if (*p == '\n') *p=0,lines++;
+ nlines = lines;
+
+ /* get memory for array of pointers to each fortune */
+ if ((flines=(char**)malloc(nlines*sizeof(char*))) == 0)
+ {
+ free((char*)base); fd= -1; return(0); /* malloc() failure */
+ }
+
+ /* now assign each pointer to a line */
+ for (p=base,tmp=0; tmp<nlines; tmp++)
+ {
+ flines[tmp]=p; while (*p++); /* advance to next line */
+ }
+ }
+
+ if (fd > 2) /* if we have a database to look at */
+ return(flines[rund((nlines<=0)?1:nlines)]);
+ else
+ return(0);
+ }
diff --git a/larn/global.c b/larn/global.c
new file mode 100644
index 00000000..80a3dd46
--- /dev/null
+++ b/larn/global.c
@@ -0,0 +1,621 @@
+/* global.c Larn is copyrighted 1986 by Noah Morgan.
+ *
+ * raiselevel() subroutine to raise the player one level
+ * loselevel() subroutine to lower the player by one level
+ * raiseexperience(x) subroutine to increase experience points
+ * loseexperience(x) subroutine to lose experience points
+ * losehp(x) subroutine to remove hit points from the player
+ * losemhp(x) subroutine to remove max # hit points from the player
+ * raisehp(x) subroutine to gain hit points
+ * raisemhp(x) subroutine to gain maximum hit points
+ * losespells(x) subroutine to lose spells
+ * losemspells(x) subroutine to lose maximum spells
+ * raisespells(x) subroutine to gain spells
+ * raisemspells(x) subroutine to gain maximum spells
+ * recalc() function to recalculate the armor class of the player
+ * makemonst(lev) function to return monster number for a randomly selected monster
+ * positionplayer() function to be sure player is not in a wall
+ * quit() subroutine to ask if the player really wants to quit
+ */
+
+#include "header.h"
+extern int score[],srcount,dropflag;
+extern int random;/* the random number seed */
+extern short playerx,playery,lastnum;
+extern char cheat,level,monstnamelist[];
+extern char lastmonst[],*what[],*who[];
+extern char winner[];
+extern char logname[],monstlevel[];
+extern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
+/*
+ ***********
+ RAISE LEVEL
+ ***********
+ raiselevel()
+
+ subroutine to raise the player one level
+ uses the skill[] array to find level boundarys
+ uses c[EXPERIENCE] c[LEVEL]
+ */
+raiselevel()
+ {
+ if (c[LEVEL] < MAXPLEVEL) raiseexperience((long)(skill[c[LEVEL]]-c[EXPERIENCE]));
+ }
+
+/*
+ ***********
+ LOOSE LEVEL
+ ***********
+ loselevel()
+
+ subroutine to lower the players character level by one
+ */
+loselevel()
+ {
+ if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL]-1] + 1));
+ }
+
+/*
+ ****************
+ RAISE EXPERIENCE
+ ****************
+ raiseexperience(x)
+
+ subroutine to increase experience points
+ */
+raiseexperience(x)
+ register long x;
+ {
+ register int i,tmp;
+ i=c[LEVEL]; c[EXPERIENCE]+=x;
+ while (c[EXPERIENCE] >= skill[c[LEVEL]] && (c[LEVEL] < MAXPLEVEL))
+ {
+ tmp = (c[CONSTITUTION]-c[HARDGAME])>>1;
+ c[LEVEL]++; raisemhp((int)(rnd(3)+rnd((tmp>0)?tmp:1)));
+ raisemspells((int)rund(3));
+ if (c[LEVEL] < 7-c[HARDGAME]) raisemhp((int)(c[CONSTITUTION]>>2));
+ }
+ if (c[LEVEL] != i)
+ {
+ cursors();
+ beep(); lprintf("\nWelcome to level %d",(long)c[LEVEL]); /* if we changed levels */
+ }
+ bottomline();
+ }
+
+/*
+ ****************
+ LOOSE EXPERIENCE
+ ****************
+ loseexperience(x)
+
+ subroutine to lose experience points
+ */
+loseexperience(x)
+ register long x;
+ {
+ register int i,tmp;
+ i=c[LEVEL]; c[EXPERIENCE]-=x;
+ if (c[EXPERIENCE] < 0) c[EXPERIENCE]=0;
+ while (c[EXPERIENCE] < skill[c[LEVEL]-1])
+ {
+ if (--c[LEVEL] <= 1) c[LEVEL]=1; /* down one level */
+ tmp = (c[CONSTITUTION]-c[HARDGAME])>>1; /* lose hpoints */
+ losemhp((int)rnd((tmp>0)?tmp:1)); /* lose hpoints */
+ if (c[LEVEL] < 7-c[HARDGAME]) losemhp((int)(c[CONSTITUTION]>>2));
+ losemspells((int)rund(3)); /* lose spells */
+ }
+ if (i!=c[LEVEL])
+ {
+ cursors();
+ beep(); lprintf("\nYou went down to level %d!",(long)c[LEVEL]);
+ }
+ bottomline();
+ }
+
+/*
+ ********
+ LOOSE HP
+ ********
+ losehp(x)
+ losemhp(x)
+
+ subroutine to remove hit points from the player
+ warning -- will kill player if hp goes to zero
+ */
+losehp(x)
+ register int x;
+ {
+ if ((c[HP] -= x) <= 0)
+ {
+ beep(); lprcat("\n"); nap(3000); died(lastnum);
+ }
+ }
+
+losemhp(x)
+ register int x;
+ {
+ c[HP] -= x; if (c[HP] < 1) c[HP]=1;
+ c[HPMAX] -= x; if (c[HPMAX] < 1) c[HPMAX]=1;
+ }
+
+/*
+ ********
+ RAISE HP
+ ********
+ raisehp(x)
+ raisemhp(x)
+
+ subroutine to gain maximum hit points
+ */
+raisehp(x)
+ register int x;
+ {
+ if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX];
+ }
+
+raisemhp(x)
+ register int x;
+ {
+ c[HPMAX] += x; c[HP] += x;
+ }
+
+/*
+ ************
+ RAISE SPELLS
+ ************
+ raisespells(x)
+ raisemspells(x)
+
+ subroutine to gain maximum spells
+ */
+raisespells(x)
+ register int x;
+ {
+ if ((c[SPELLS] += x) > c[SPELLMAX]) c[SPELLS] = c[SPELLMAX];
+ }
+
+raisemspells(x)
+ register int x;
+ {
+ c[SPELLMAX]+=x; c[SPELLS]+=x;
+ }
+
+/*
+ ************
+ LOOSE SPELLS
+ ************
+ losespells(x)
+ losemspells(x)
+
+ subroutine to lose maximum spells
+ */
+losespells(x)
+ register int x;
+ {
+ if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
+ }
+
+losemspells(x)
+ register int x;
+ {
+ if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX]=0;
+ if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
+ }
+
+/*
+ makemonst(lev)
+ int lev;
+
+ function to return monster number for a randomly selected monster
+ for the given cave level
+ */
+makemonst(lev)
+ register int lev;
+ {
+ register int tmp,x;
+ if (lev < 1) lev = 1; if (lev > 12) lev = 12;
+ tmp=WATERLORD;
+ if (lev < 5)
+ while (tmp==WATERLORD) tmp=rnd((x=monstlevel[lev-1])?x:1);
+ else while (tmp==WATERLORD)
+ tmp=rnd((x=monstlevel[lev-1]-monstlevel[lev-4])?x:1)+monstlevel[lev-4];
+
+ while (monster[tmp].genocided && tmp<MAXMONST) tmp++; /* genocided? */
+ return(tmp);
+ }
+
+/*
+ positionplayer()
+
+ function to be sure player is not in a wall
+ */
+positionplayer()
+ {
+ int try;
+ try = 2;
+ while ((item[playerx][playery] || mitem[playerx][playery]) && (try))
+ if (++playerx >= MAXX-1)
+ {
+ playerx = 1;
+ if (++playery >= MAXY-1)
+ { playery = 1; --try; }
+ }
+ if (try==0) lprcat("Failure in positionplayer\n");
+ }
+
+/*
+ recalc() function to recalculate the armor class of the player
+ */
+recalc()
+ {
+ register int i,j,k;
+ c[AC] = c[MOREDEFENSES];
+ if (c[WEAR] >= 0)
+ switch(iven[c[WEAR]])
+ {
+ case OSHIELD: c[AC] += 2 + ivenarg[c[WEAR]]; break;
+ case OLEATHER: c[AC] += 2 + ivenarg[c[WEAR]]; break;
+ case OSTUDLEATHER: c[AC] += 3 + ivenarg[c[WEAR]]; break;
+ case ORING: c[AC] += 5 + ivenarg[c[WEAR]]; break;
+ case OCHAIN: c[AC] += 6 + ivenarg[c[WEAR]]; break;
+ case OSPLINT: c[AC] += 7 + ivenarg[c[WEAR]]; break;
+ case OPLATE: c[AC] += 9 + ivenarg[c[WEAR]]; break;
+ case OPLATEARMOR: c[AC] += 10 + ivenarg[c[WEAR]]; break;
+ case OSSPLATE: c[AC] += 12 + ivenarg[c[WEAR]]; break;
+ }
+
+ if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]];
+ if (c[WIELD] < 0) c[WCLASS] = 0; else
+ {
+ i = ivenarg[c[WIELD]];
+ switch(iven[c[WIELD]])
+ {
+ case ODAGGER: c[WCLASS] = 3 + i; break;
+ case OBELT: c[WCLASS] = 7 + i; break;
+ case OSHIELD: c[WCLASS] = 8 + i; break;
+ case OSPEAR: c[WCLASS] = 10 + i; break;
+ case OFLAIL: c[WCLASS] = 14 + i; break;
+ case OBATTLEAXE: c[WCLASS] = 17 + i; break;
+ case OLANCE: c[WCLASS] = 19 + i; break;
+ case OLONGSWORD: c[WCLASS] = 22 + i; break;
+ case O2SWORD: c[WCLASS] = 26 + i; break;
+ case OSWORD: c[WCLASS] = 32 + i; break;
+ case OSWORDofSLASHING: c[WCLASS] = 30 + i; break;
+ case OHAMMER: c[WCLASS] = 35 + i; break;
+ default: c[WCLASS] = 0;
+ }
+ }
+ c[WCLASS] += c[MOREDAM];
+
+/* now for regeneration abilities based on rings */
+ c[REGEN]=1; c[ENERGY]=0;
+ j=0; for (k=25; k>0; k--) if (iven[k]) {j=k; k=0; }
+ for (i=0; i<=j; i++)
+ {
+ switch(iven[i])
+ {
+ case OPROTRING: c[AC] += ivenarg[i] + 1; break;
+ case ODAMRING: c[WCLASS] += ivenarg[i] + 1; break;
+ case OBELT: c[WCLASS] += ((ivenarg[i]<<1)) + 2; break;
+
+ case OREGENRING: c[REGEN] += ivenarg[i] + 1; break;
+ case ORINGOFEXTRA: c[REGEN] += 5 * (ivenarg[i]+1); break;
+ case OENERGYRING: c[ENERGY] += ivenarg[i] + 1; break;
+ }
+ }
+ }
+
+
+/*
+ quit()
+
+ subroutine to ask if the player really wants to quit
+ */
+quit()
+ {
+ register int i;
+ cursors(); strcpy(lastmonst,"");
+ lprcat("\n\nDo you really want to quit?");
+ while (1)
+ {
+ i=getchar();
+ if (i == 'y') { died(300); return; }
+ if ((i == 'n') || (i == '\33')) { lprcat(" no"); lflush(); return; }
+ lprcat("\n"); setbold(); lprcat("Yes"); resetbold(); lprcat(" or ");
+ setbold(); lprcat("No"); resetbold(); lprcat(" please? Do you want to quit? ");
+ }
+ }
+
+/*
+ function to ask --more-- then the user must enter a space
+ */
+more()
+ {
+ lprcat("\n --- press "); standout("space"); lprcat(" to continue --- ");
+ while (getchar() != ' ');
+ }
+
+/*
+ function to put something in the players inventory
+ returns 0 if success, 1 if a failure
+ */
+take(itm,arg)
+ int itm,arg;
+ {
+ register int i,limit;
+/* cursors(); */
+ if ((limit = 15+(c[LEVEL]>>1)) > 26) limit=26;
+ for (i=0; i<limit; i++)
+ if (iven[i]==0)
+ {
+ iven[i] = itm; ivenarg[i] = arg; limit=0;
+ switch(itm)
+ {
+ case OPROTRING: case ODAMRING: case OBELT: limit=1; break;
+ case ODEXRING: c[DEXTERITY] += ivenarg[i]+1; limit=1; break;
+ case OSTRRING: c[STREXTRA] += ivenarg[i]+1; limit=1; break;
+ case OCLEVERRING: c[INTELLIGENCE] += ivenarg[i]+1; limit=1; break;
+ case OHAMMER: c[DEXTERITY] += 10; c[STREXTRA]+=10;
+ c[INTELLIGENCE]-=10; limit=1; break;
+
+ case OORBOFDRAGON: c[SLAYING]++; break;
+ case OSPIRITSCARAB: c[NEGATESPIRIT]++; break;
+ case OCUBEofUNDEAD: c[CUBEofUNDEAD]++; break;
+ case ONOTHEFT: c[NOTHEFT]++; break;
+ case OSWORDofSLASHING: c[DEXTERITY] +=5; limit=1; break;
+ };
+ lprcat("\nYou pick up:"); srcount=0; show3(i);
+ if (limit) bottomline(); return(0);
+ }
+ lprcat("\nYou can't carry anything else"); return(1);
+ }
+
+/*
+ subroutine to drop an object returns 1 if something there already else 0
+ */
+drop_object(k)
+ int k;
+ {
+ int itm;
+ if ((k<0) || (k>25)) return(0);
+ itm = iven[k]; cursors();
+ if (itm==0) { lprintf("\nYou don't have item %c! ",k+'a'); return(1); }
+ if (item[playerx][playery])
+ { beep(); lprcat("\nThere's something here already"); return(1); }
+ if (playery==MAXY-1 && playerx==33) return(1); /* not in entrance */
+ item[playerx][playery] = itm;
+ iarg[playerx][playery] = ivenarg[k];
+ srcount=0; lprcat("\n You drop:"); show3(k); /* show what item you dropped*/
+ know[playerx][playery] = 0; iven[k]=0;
+ if (c[WIELD]==k) c[WIELD]= -1; if (c[WEAR]==k) c[WEAR] = -1;
+ if (c[SHIELD]==k) c[SHIELD]= -1;
+ adjustcvalues(itm,ivenarg[k]);
+ dropflag=1; /* say dropped an item so wont ask to pick it up right away */
+ return(0);
+ }
+
+/*
+ function to enchant armor player is currently wearing
+ */
+enchantarmor()
+ {
+ register int tmp;
+ if (c[WEAR]<0) { if (c[SHIELD] < 0)
+ { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
+ else { tmp=iven[c[SHIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[SHIELD]]++; bottomline(); } } }
+ tmp = iven[c[WEAR]];
+ if (tmp!=OSCROLL) if (tmp!=OPOTION) { ivenarg[c[WEAR]]++; bottomline(); }
+ }
+
+/*
+ function to enchant a weapon presently being wielded
+ */
+enchweapon()
+ {
+ register int tmp;
+ if (c[WIELD]<0)
+ { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
+ tmp = iven[c[WIELD]];
+ if (tmp!=OSCROLL) if (tmp!=OPOTION)
+ { ivenarg[c[WIELD]]++;
+ if (tmp==OCLEVERRING) c[INTELLIGENCE]++; else
+ if (tmp==OSTRRING) c[STREXTRA]++; else
+ if (tmp==ODEXRING) c[DEXTERITY]++; bottomline(); }
+ }
+
+/*
+ routine to tell if player can carry one more thing
+ returns 1 if pockets are full, else 0
+ */
+pocketfull()
+ {
+ register int i,limit;
+ if ((limit = 15+(c[LEVEL]>>1)) > 26) limit=26;
+ for (i=0; i<limit; i++) if (iven[i]==0) return(0);
+ return(1);
+ }
+
+/*
+ function to return 1 if a monster is next to the player else returns 0
+ */
+nearbymonst()
+ {
+ register int tmp,tmp2;
+ for (tmp=playerx-1; tmp<playerx+2; tmp++)
+ for (tmp2=playery-1; tmp2<playery+2; tmp2++)
+ if (mitem[tmp][tmp2]) return(1); /* if monster nearby */
+ return(0);
+ }
+
+/*
+ function to steal an item from the players pockets
+ returns 1 if steals something else returns 0
+ */
+stealsomething()
+ {
+ register int i,j;
+ j=100;
+ while (1)
+ {
+ i=rund(26);
+ if (iven[i]) if (c[WEAR]!=i) if (c[WIELD]!=i) if (c[SHIELD]!=i)
+ {
+ srcount=0; show3(i);
+ adjustcvalues(iven[i],ivenarg[i]); iven[i]=0; return(1);
+ }
+ if (--j <= 0) return(0);
+ }
+ }
+
+/*
+ function to return 1 is player carrys nothing else return 0
+ */
+emptyhanded()
+ {
+ register int i;
+ for (i=0; i<26; i++)
+ if (iven[i]) if (i!=c[WIELD]) if (i!=c[WEAR]) if (i!=c[SHIELD]) return(0);
+ return(1);
+ }
+
+/*
+ function to create a gem on a square near the player
+ */
+creategem()
+ {
+ register int i,j;
+ switch(rnd(4))
+ {
+ case 1: i=ODIAMOND; j=50; break;
+ case 2: i=ORUBY; j=40; break;
+ case 3: i=OEMERALD; j=30; break;
+ default: i=OSAPPHIRE; j=20; break;
+ };
+ createitem(i,rnd(j)+j/10);
+ }
+
+/*
+ function to change character levels as needed when dropping an object
+ that affects these characteristics
+ */
+adjustcvalues(itm,arg)
+ int itm,arg;
+ {
+ register int flag;
+ flag=0;
+ switch(itm)
+ {
+ case ODEXRING: c[DEXTERITY] -= arg+1; flag=1; break;
+ case OSTRRING: c[STREXTRA] -= arg+1; flag=1; break;
+ case OCLEVERRING: c[INTELLIGENCE] -= arg+1; flag=1; break;
+ case OHAMMER: c[DEXTERITY] -= 10; c[STREXTRA] -= 10;
+ c[INTELLIGENCE] += 10; flag=1; break;
+ case OSWORDofSLASHING: c[DEXTERITY] -= 5; flag=1; break;
+ case OORBOFDRAGON: --c[SLAYING]; return;
+ case OSPIRITSCARAB: --c[NEGATESPIRIT]; return;
+ case OCUBEofUNDEAD: --c[CUBEofUNDEAD]; return;
+ case ONOTHEFT: --c[NOTHEFT]; return;
+ case OLANCE: c[LANCEDEATH]=0; return;
+ case OPOTION: case OSCROLL: return;
+
+ default: flag=1;
+ };
+ if (flag) bottomline();
+ }
+
+/*
+ function to read a string from token input "string"
+ returns a pointer to the string
+ */
+gettokstr(str)
+ register char *str;
+ {
+ register int i,j;
+ i=50;
+ while ((getchar() != '"') && (--i > 0));
+ i=36;
+ while (--i > 0)
+ {
+ if ((j=getchar()) != '"') *str++ = j; else i=0;
+ }
+ *str = 0;
+ i=50;
+ if (j != '"') while ((getchar() != '"') && (--i > 0)); /* if end due to too long, then find closing quote */
+ }
+
+/*
+ function to ask user for a password (no echo)
+ returns 1 if entered correctly, 0 if not
+ */
+static char gpwbuf[33];
+getpassword()
+ {
+ register int i,j;
+ register char *gpwp;
+ extern char *password;
+ scbr(); /* system("stty -echo cbreak"); */
+ gpwp = gpwbuf; lprcat("\nEnter Password: "); lflush();
+ i = strlen(password);
+ for (j=0; j<i; j++) read(0,gpwp++,1); gpwbuf[i]=0;
+ sncbr(); /* system("stty echo -cbreak"); */
+ if (strcmp(gpwbuf,password) != 0)
+ { lprcat("\nSorry\n"); lflush(); return(0); }
+ else return(1);
+ }
+
+/*
+ subroutine to get a yes or no response from the user
+ returns y or n
+ */
+getyn()
+ {
+ register int i;
+ i=0; while (i!='y' && i!='n' && i!='\33') i=getchar();
+ return(i);
+ }
+
+/*
+ function to calculate the pack weight of the player
+ returns the number of pounds the player is carrying
+ */
+packweight()
+ {
+ register int i,j,k;
+ k=c[GOLD]/1000; j=25; while ((iven[j]==0) && (j>0)) --j;
+ for (i=0; i<=j; i++)
+ switch(iven[i])
+ {
+ case 0: break;
+ case OSSPLATE: case OPLATEARMOR: k += 40; break;
+ case OPLATE: k += 35; break;
+ case OHAMMER: k += 30; break;
+ case OSPLINT: k += 26; break;
+ case OSWORDofSLASHING: case OCHAIN:
+ case OBATTLEAXE: case O2SWORD: k += 23; break;
+ case OLONGSWORD: case OSWORD:
+ case ORING: case OFLAIL: k += 20; break;
+ case OLANCE: case OSTUDLEATHER: k += 15; break;
+ case OLEATHER: case OSPEAR: k += 8; break;
+ case OORBOFDRAGON: case OBELT: k += 4; break;
+ case OSHIELD: k += 7; break;
+ case OCHEST: k += 30 + ivenarg[i]; break;
+ default: k++;
+ };
+ return(k);
+ }
+
+#ifndef MACRORND
+ /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */
+rnd(x)
+ int x;
+ {
+ return((((randx=randx*1103515245+12345)>>7)%(x))+1);
+ }
+
+rund(x)
+ int x;
+ {
+ return((((randx=randx*1103515245+12345)>>7)%(x)) );
+ }
+#endif MACRORND
diff --git a/larn/header.h b/larn/header.h
new file mode 100644
index 00000000..ed9a8b6f
--- /dev/null
+++ b/larn/header.h
@@ -0,0 +1,434 @@
+/* header.h Larn is copyrighted 1986 by Noah Morgan. */
+
+#define MAXLEVEL 11
+ /* max # levels in the dungeon */
+#define MAXVLEVEL 3
+ /* max # of levels in the temple of the luran */
+#define MAXX 67
+#define MAXY 17
+
+#define SCORESIZE 10
+ /* this is the number of people on a scoreboard max */
+#define MAXPLEVEL 100
+ /* maximum player level allowed */
+#define MAXMONST 56
+ /* maximum # monsters in the dungeon */
+#define SPNUM 38
+ /* maximum number of spells in existance */
+#define MAXSCROLL 28
+ /* maximum number of scrolls that are possible */
+#define MAXPOTION 35
+ /* maximum number of potions that are possible */
+#define TIMELIMIT 30000
+ /* the maximum number of moves before the game is called */
+#define TAXRATE 1/20
+ /* the tax rate for the LRS */
+#define MAXOBJ 93
+ /* the maximum number of objects n < MAXOBJ */
+
+/* this is the structure definition of the monster data */
+struct monst
+ {
+ char *name;
+ char level;
+ short armorclass;
+ char damage;
+ char attack;
+ char defense;
+ char genocided;
+ char intelligence; /* monsters intelligence -- used to choose movement */
+ short gold;
+ short hitpoints;
+ unsigned long experience;
+ };
+
+/* this is the structure definition for the items in the dnd store */
+struct _itm
+ {
+ short price;
+ char **mem;
+ char obj;
+ char arg;
+ char qty;
+ };
+
+/* this is the structure that holds the entire dungeon specifications */
+struct cel
+ {
+ short hitp; /* monster's hit points */
+ char mitem; /* the monster ID */
+ char item; /* the object's ID */
+ short iarg; /* the object's argument */
+ char know; /* have we been here before*/
+ };
+
+/* this is the structure for maintaining & moving the spheres of annihilation */
+struct sphere
+ {
+ struct sphere *p; /* pointer to next structure */
+ char x,y,lev; /* location of the sphere */
+ char dir; /* direction sphere is going in */
+ char lifetime; /* duration of the sphere */
+ };
+
+/* defines for the character attribute array c[] */
+#define STRENGTH 0 /* characters physical strength not due to objects */
+#define INTELLIGENCE 1
+#define WISDOM 2
+#define CONSTITUTION 3
+#define DEXTERITY 4
+#define CHARISMA 5
+#define HPMAX 6
+#define HP 7
+#define GOLD 8
+#define EXPERIENCE 9
+#define LEVEL 10
+#define REGEN 11
+#define WCLASS 12
+#define AC 13
+#define BANKACCOUNT 14
+#define SPELLMAX 15
+#define SPELLS 16
+#define ENERGY 17
+#define ECOUNTER 18
+#define MOREDEFENSES 19
+#define WEAR 20
+#define PROTECTIONTIME 21
+#define WIELD 22
+#define AMULET 23
+#define REGENCOUNTER 24
+#define MOREDAM 25
+#define DEXCOUNT 26
+#define STRCOUNT 27
+#define BLINDCOUNT 28
+#define CAVELEVEL 29
+#define CONFUSE 30
+#define ALTPRO 31
+#define HERO 32
+#define CHARMCOUNT 33
+#define INVISIBILITY 34
+#define CANCELLATION 35
+#define HASTESELF 36
+#define EYEOFLARN 37
+#define AGGRAVATE 38
+#define GLOBE 39
+#define TELEFLAG 40
+#define SLAYING 41
+#define NEGATESPIRIT 42
+#define SCAREMONST 43
+#define AWARENESS 44
+#define HOLDMONST 45
+#define TIMESTOP 46
+#define HASTEMONST 47
+#define CUBEofUNDEAD 48
+#define GIANTSTR 49
+#define FIRERESISTANCE 50
+#define BESSMANN 51
+#define NOTHEFT 52
+#define HARDGAME 53
+#define CPUTIME 54
+#define BYTESIN 55
+#define BYTESOUT 56
+#define MOVESMADE 57
+#define MONSTKILLED 58
+#define SPELLSCAST 59
+#define LANCEDEATH 60
+#define SPIRITPRO 61
+#define UNDEADPRO 62
+#define SHIELD 63
+#define STEALTH 64
+#define ITCHING 65
+#define LAUGHING 66
+#define DRAINSTRENGTH 67
+#define CLUMSINESS 68
+#define INFEEBLEMENT 69
+#define HALFDAM 70
+#define SEEINVISIBLE 71
+#define FILLROOM 72
+#define RANDOMWALK 73
+#define SPHCAST 74 /* nz if an active sphere of annihilation */
+#define WTW 75 /* walk through walls */
+#define STREXTRA 76 /* character strength due to objects or enchantments */
+#define TMP 77 /* misc scratch space */
+#define LIFEPROT 78 /* life protection counter */
+
+/* defines for the objects in the game */
+
+#define OALTAR 1
+#define OTHRONE 2
+#define OORB 3
+#define OPIT 4
+#define OSTAIRSUP 5
+#define OELEVATORUP 6
+#define OFOUNTAIN 7
+#define OSTATUE 8
+#define OTELEPORTER 9
+#define OSCHOOL 10
+#define OMIRROR 11
+#define ODNDSTORE 12
+#define OSTAIRSDOWN 13
+#define OELEVATORDOWN 14
+#define OBANK2 15
+#define OBANK 16
+#define ODEADFOUNTAIN 17
+#define OMAXGOLD 70
+#define OGOLDPILE 18
+#define OOPENDOOR 19
+#define OCLOSEDDOOR 20
+#define OWALL 21
+#define OTRAPARROW 66
+#define OTRAPARROWIV 67
+
+#define OLARNEYE 22
+
+#define OPLATE 23
+#define OCHAIN 24
+#define OLEATHER 25
+#define ORING 60
+#define OSTUDLEATHER 61
+#define OSPLINT 62
+#define OPLATEARMOR 63
+#define OSSPLATE 64
+#define OSHIELD 68
+#define OELVENCHAIN 92
+
+#define OSWORDofSLASHING 26
+#define OHAMMER 27
+#define OSWORD 28
+#define O2SWORD 29
+#define OSPEAR 30
+#define ODAGGER 31
+#define OBATTLEAXE 57
+#define OLONGSWORD 58
+#define OFLAIL 59
+#define OLANCE 65
+#define OVORPAL 90
+#define OSLAYER 91
+
+#define ORINGOFEXTRA 32
+#define OREGENRING 33
+#define OPROTRING 34
+#define OENERGYRING 35
+#define ODEXRING 36
+#define OSTRRING 37
+#define OCLEVERRING 38
+#define ODAMRING 39
+
+#define OBELT 40
+
+#define OSCROLL 41
+#define OPOTION 42
+#define OBOOK 43
+#define OCHEST 44
+#define OAMULET 45
+
+#define OORBOFDRAGON 46
+#define OSPIRITSCARAB 47
+#define OCUBEofUNDEAD 48
+#define ONOTHEFT 49
+
+#define ODIAMOND 50
+#define ORUBY 51
+#define OEMERALD 52
+#define OSAPPHIRE 53
+
+#define OENTRANCE 54
+#define OVOLDOWN 55
+#define OVOLUP 56
+#define OHOME 69
+
+#define OKGOLD 71
+#define ODGOLD 72
+#define OIVDARTRAP 73
+#define ODARTRAP 74
+#define OTRAPDOOR 75
+#define OIVTRAPDOOR 76
+#define OTRADEPOST 77
+#define OIVTELETRAP 78
+#define ODEADTHRONE 79
+#define OANNIHILATION 80 /* sphere of annihilation */
+#define OTHRONE2 81
+#define OLRS 82 /* Larn Revenue Service */
+#define OCOOKIE 83
+#define OURN 84
+#define OBRASSLAMP 85
+#define OHANDofFEAR 86 /* hand of fear */
+#define OSPHTAILSMAN 87 /* tailsman of the sphere */
+#define OWWAND 88 /* wand of wonder */
+#define OPSTAFF 89 /* staff of power */
+/* used up to 92 */
+
+/* defines for the monsters as objects */
+
+#define BAT 1
+#define GNOME 2
+#define HOBGOBLIN 3
+#define JACKAL 4
+#define KOBOLD 5
+#define ORC 6
+#define SNAKE 7
+#define CENTIPEDE 8
+#define JACULI 9
+#define TROGLODYTE 10
+#define ANT 11
+#define EYE 12
+#define LEPRECHAUN 13
+#define NYMPH 14
+#define QUASIT 15
+#define RUSTMONSTER 16
+#define ZOMBIE 17
+#define ASSASSINBUG 18
+#define BUGBEAR 19
+#define HELLHOUND 20
+#define ICELIZARD 21
+#define CENTAUR 22
+#define TROLL 23
+#define YETI 24
+#define WHITEDRAGON 25
+#define ELF 26
+#define CUBE 27
+#define METAMORPH 28
+#define VORTEX 29
+#define ZILLER 30
+#define VIOLETFUNGI 31
+#define WRAITH 32
+#define FORVALAKA 33
+#define LAMANOBE 34
+#define OSEQUIP 35
+#define ROTHE 36
+#define XORN 37
+#define VAMPIRE 38
+#define INVISIBLESTALKER 39
+#define POLTERGEIST 40
+#define DISENCHANTRESS 41
+#define SHAMBLINGMOUND 42
+#define YELLOWMOLD 43
+#define UMBERHULK 44
+#define GNOMEKING 45
+#define MIMIC 46
+#define WATERLORD 47
+#define BRONZEDRAGON 48
+#define GREENDRAGON 49
+#define PURPLEWORM 50
+#define XVART 51
+#define SPIRITNAGA 52
+#define SILVERDRAGON 53
+#define PLATINUMDRAGON 54
+#define GREENURCHIN 55
+#define REDDRAGON 56
+#define DEMONLORD 57
+#define DEMONPRINCE 64
+
+#define NULL 0
+#define BUFBIG 4096 /* size of the output buffer */
+#define MAXIBUF 4096 /* size of the input buffer */
+#define LOGNAMESIZE 40 /* max size of the players name */
+#define PSNAMESIZE 40 /* max size of the process name */
+
+#ifndef NODEFS
+extern char VERSION,SUBVERSION;
+extern char aborted[],alpha[],beenhere[],boldon,cheat,ckpfile[],ckpflag;
+extern char *class[],course[],diagfile[],fortfile[],helpfile[];
+extern char *inbuffer,is_alpha[],is_digit[];
+extern char item[MAXX][MAXY],iven[],know[MAXX][MAXY],larnlevels[],lastmonst[];
+extern char level,*levelname[],logfile[],loginname[],logname[],*lpbuf,*lpend;
+extern char *lpnt,moved[MAXX][MAXY],mitem[MAXX][MAXY],monstlevel[];
+extern char monstnamelist[],nch[],ndgg[],nlpts[],nomove,nosignal,nowelcome;
+extern char nplt[],nsw[],*objectname[];
+extern char objnamelist[],optsfile[],*potionname[],playerids[],potprob[];
+extern char predostuff,psname[],restorflag,savefilename[],scorefile[],scprob[];
+extern char screen[MAXX][MAXY],*scrollname[],sex,*spelcode[],*speldescript[];
+extern char spelknow[],*spelname[],*spelmes[],spelweird[MAXMONST+8][SPNUM];
+extern char splev[],stealth[MAXX][MAXY],to_lower[],to_upper[],wizard;
+extern short diroffx[],diroffy[],hitflag,hit2flag,hit3flag,hitp[MAXX][MAXY];
+extern short iarg[MAXX][MAXY],ivenarg[],lasthx,lasthy,lastnum,lastpx,lastpy;
+extern short nobeep,oldx,oldy,playerx,playery;
+extern int dayplay,enable_scroll,srcount,yrepcount,userid,wisid,lfd,fd;
+extern long initialtime,outstanding_taxes,skill[],gtime,c[],cbak[];
+extern unsigned long randx;
+extern struct cel *cell;
+extern struct monst monster[];
+extern struct sphere *spheres;
+extern struct _itm itm[];
+
+char *fortune(),*malloc(),*getenv(),*getlogin(),*lgetw(),*lgetl(),*ctime();
+char *tmcapcnv(),*tgetstr(),*tgoto();
+long paytaxes(),lgetc(),lrint(),time();
+unsigned long readnum();
+
+ /* macro to create scroll #'s with probability of occurrence */
+#define newscroll() (scprob[rund(81)])
+ /* macro to return a potion # created with probability of occurrence */
+#define newpotion() (potprob[rund(41)])
+ /* macro to return the + points on created leather armor */
+#define newleather() (nlpts[rund(c[HARDGAME]?13:15)])
+ /* macro to return the + points on chain armor */
+#define newchain() (nch[rund(10)])
+ /* macro to return + points on plate armor */
+#define newplate() (nplt[rund(c[HARDGAME]?4:12)])
+ /* macro to return + points on new daggers */
+#define newdagger() (ndgg[rund(13)])
+ /* macro to return + points on new swords */
+#define newsword() (nsw[rund(c[HARDGAME]?6:13)])
+ /* macro to destroy object at present location */
+#define forget() (item[playerx][playery]=know[playerx][playery]=0)
+ /* macro to wipe out a monster at a location */
+#define disappear(x,y) (mitem[x][y]=know[x][y]=0)
+
+#ifdef VT100
+ /* macro to turn on bold display for the terminal */
+#define setbold() (lprcat(boldon?"\33[1m":"\33[7m"))
+ /* macro to turn off bold display for the terminal */
+#define resetbold() (lprcat("\33[m"))
+ /* macro to setup the scrolling region for the terminal */
+#define setscroll() (lprcat("\33[20;24r"))
+ /* macro to clear the scrolling region for the terminal */
+#define resetscroll() (lprcat("\33[;24r"))
+ /* macro to clear the screen and home the cursor */
+#define clear() (lprcat("\33[2J\33[f"), cbak[SPELLS]= -50)
+#define cltoeoln() lprcat("\33[K")
+#else VT100
+ /* defines below are for use in the termcap mode only */
+#define ST_START 1
+#define ST_END 2
+#define BOLD 3
+#define END_BOLD 4
+#define CLEAR 5
+#define CL_LINE 6
+#define CL_DOWN 14
+#define CURSOR 15
+ /* macro to turn on bold display for the terminal */
+#define setbold() (*lpnt++ = ST_START)
+ /* macro to turn off bold display for the terminal */
+#define resetbold() (*lpnt++ = ST_END)
+ /* macro to setup the scrolling region for the terminal */
+#define setscroll() enable_scroll=1
+ /* macro to clear the scrolling region for the terminal */
+#define resetscroll() enable_scroll=0
+ /* macro to clear the screen and home the cursor */
+#define clear() (*lpnt++ =CLEAR, cbak[SPELLS]= -50)
+ /* macro to clear to end of line */
+#define cltoeoln() (*lpnt++ = CL_LINE)
+#endif VT100
+
+ /* macro to output one byte to the output buffer */
+#define lprc(ch) ((lpnt>=lpend)?(*lpnt++ =(ch), lflush()):(*lpnt++ =(ch)))
+
+ /* macro to seed the random number generator */
+#define srand(x) (randx=x)
+#ifdef MACRORND
+ /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */
+#define rnd(x) ((((randx=randx*1103515245+12345)>>7)%(x))+1)
+#define rund(x) ((((randx=randx*1103515245+12345)>>7)%(x)) )
+#endif MACRORND
+ /* macros for miscellaneous data conversion */
+#define min(x,y) (((x)>(y))?(y):(x))
+#define max(x,y) (((x)>(y))?(x):(y))
+#define isalpha(x) (is_alpha[x])
+#define isdigit(x) (is_digit[x])
+#define tolower(x) (to_lower[x])
+#define toupper(x) (to_upper[x])
+#define lcc(x) (to_lower[x])
+#define ucc(x) (to_upper[x])
+#endif NODEFS
+
diff --git a/larn/help.c b/larn/help.c
new file mode 100644
index 00000000..0f21367d
--- /dev/null
+++ b/larn/help.c
@@ -0,0 +1,87 @@
+/* help.c Larn is copyrighted 1986 by Noah Morgan. */
+#include "header.h"
+/*
+ * help function to display the help info
+ *
+ * format of the .larn.help file
+ *
+ * 1st character of file: # of pages of help available (ascii digit)
+ * page (23 lines) for the introductory message (not counted in above)
+ * pages of help text (23 lines per page)
+ */
+extern char helpfile[];
+help()
+ {
+ register int i,j;
+#ifndef VT100
+ char tmbuf[128]; /* intermediate translation buffer when not a VT100 */
+#endif VT100
+ if ((j=openhelp()) < 0) return; /* open the help file and get # pages */
+ for (i=0; i<23; i++) lgetl(); /* skip over intro message */
+ for (; j>0; j--)
+ {
+ clear();
+ for (i=0; i<23; i++)
+#ifdef VT100
+ lprcat(lgetl()); /* print out each line that we read in */
+#else VT100
+ { tmcapcnv(tmbuf,lgetl()); lprcat(tmbuf); } /* intercept \33's */
+#endif VT100
+ if (j>1)
+ {
+ lprcat(" ---- Press "); standout("return");
+ lprcat(" to exit, "); standout("space");
+ lprcat(" for more help ---- ");
+ i=0; while ((i!=' ') && (i!='\n') && (i!='\33')) i=getchar();
+ if ((i=='\n') || (i=='\33'))
+ {
+ lrclose(); setscroll(); drawscreen(); return;
+ }
+ }
+ }
+ lrclose(); retcont(); drawscreen();
+ }
+
+/*
+ * function to display the welcome message and background
+ */
+welcome()
+ {
+ register int i;
+#ifndef VT100
+ char tmbuf[128]; /* intermediate translation buffer when not a VT100 */
+#endif VT100
+ if (openhelp() < 0) return; /* open the help file */
+ clear();
+ for(i=0; i<23; i++)
+#ifdef VT100
+ lprcat(lgetl()); /* print out each line that we read in */
+#else VT100
+ { tmcapcnv(tmbuf,lgetl()); lprcat(tmbuf); } /* intercept \33's */
+#endif VT100
+ lrclose(); retcont(); /* press return to continue */
+ }
+
+/*
+ * function to say press return to continue and reset scroll when done
+ */
+retcont()
+ {
+ cursor(1,24); lprcat("Press "); standout("return");
+ lprcat(" to continue: "); while (getchar() != '\n');
+ setscroll();
+ }
+
+/*
+ * routine to open the help file and return the first character - '0'
+ */
+openhelp()
+ {
+ if (lopen(helpfile)<0)
+ {
+ lprintf("Can't open help file \"%s\" ",helpfile);
+ lflush(); sleep(4); drawscreen(); setscroll(); return(-1);
+ }
+ resetscroll(); return(lgetc() - '0');
+ }
+
diff --git a/larn/io.c b/larn/io.c
new file mode 100644
index 00000000..dc0d5e7c
--- /dev/null
+++ b/larn/io.c
@@ -0,0 +1,915 @@
+/* io.c Larn is copyrighted 1986 by Noah Morgan.
+ *
+ * Below are the functions in this file:
+ *
+ * setupvt100() Subroutine to set up terminal in correct mode for game
+ * clearvt100() Subroutine to clean up terminal when the game is over
+ * getchar() Routine to read in one character from the terminal
+ * scbr() Function to set cbreak -echo for the terminal
+ * sncbr() Function to set -cbreak echo for the terminal
+ * newgame() Subroutine to save the initial time and seed rnd()
+ *
+ * FILE OUTPUT ROUTINES
+ *
+ * lprintf(format,args . . .) printf to the output buffer
+ * lprint(integer) send binary integer to output buffer
+ * lwrite(buf,len) write a buffer to the output buffer
+ * lprcat(str) sent string to output buffer
+ *
+ * FILE OUTPUT MACROS (in header.h)
+ *
+ * lprc(character) put the character into the output buffer
+ *
+ * FILE INPUT ROUTINES
+ *
+ * long lgetc() read one character from input buffer
+ * long lrint() read one integer from input buffer
+ * lrfill(address,number) put input bytes into a buffer
+ * char *lgetw() get a whitespace ended word from input
+ * char *lgetl() get a \n or EOF ended line from input
+ *
+ * FILE OPEN / CLOSE ROUTINES
+ *
+ * lcreat(filename) create a new file for write
+ * lopen(filename) open a file for read
+ * lappend(filename) open for append to an existing file
+ * lrclose() close the input file
+ * lwclose() close output file
+ * lflush() flush the output buffer
+ *
+ * Other Routines
+ *
+ * cursor(x,y) position cursor at [x,y]
+ * cursors() position cursor at [1,24] (saves memory)
+ * cl_line(x,y) Clear line at [1,y] and leave cursor at [x,y]
+ * cl_up(x,y) Clear screen from [x,1] to current line.
+ * cl_dn(x,y) Clear screen from [1,y] to end of display.
+ * standout(str) Print the string in standout mode.
+ * set_score_output() Called when output should be literally printed.
+ ** putchar(ch) Print one character in decoded output buffer.
+ ** flush_buf() Flush buffer with decoded output.
+ ** init_term() Terminal initialization -- setup termcap info
+ ** char *tmcapcnv(sd,ss) Routine to convert VT100 \33's to termcap format
+ * beep() Routine to emit a beep if enabled (see no-beep in .larnopts)
+ *
+ * Note: ** entries are available only in termcap mode.
+ */
+
+#include "header.h"
+
+#ifdef SYSV /* system III or system V */
+#include <termio.h>
+#define sgttyb termio
+#define stty(_a,_b) ioctl(_a,TCSETA,_b)
+#define gtty(_a,_b) ioctl(_a,TCGETA,_b)
+static int rawflg = 0;
+static char saveeof,saveeol;
+#define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\
+ _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL)
+#define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL
+
+#else not SYSV
+
+#ifndef BSD
+#define CBREAK RAW /* V7 has no CBREAK */
+#endif
+
+#define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO)
+#define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO)
+#include <sgtty.h>
+#endif not SYSV
+
+#ifndef NOVARARGS /* if we have varargs */
+#include <varargs.h>
+#else NOVARARGS /* if we don't have varargs */
+typedef char *va_list;
+#define va_dcl int va_alist;
+#define va_start(plist) plist = (char *) &va_alist
+#define va_end(plist)
+#define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1]
+#endif NOVARARGS
+
+#define LINBUFSIZE 128 /* size of the lgetw() and lgetl() buffer */
+int lfd; /* output file numbers */
+int fd; /* input file numbers */
+static struct sgttyb ttx; /* storage for the tty modes */
+static int ipoint=MAXIBUF,iepoint=MAXIBUF; /* input buffering pointers */
+static char lgetwbuf[LINBUFSIZE]; /* get line (word) buffer */
+
+/*
+ * setupvt100() Subroutine to set up terminal in correct mode for game
+ *
+ * Attributes off, clear screen, set scrolling region, set tty mode
+ */
+setupvt100()
+ {
+ clear(); setscroll(); scbr(); /* system("stty cbreak -echo"); */
+ }
+
+/*
+ * clearvt100() Subroutine to clean up terminal when the game is over
+ *
+ * Attributes off, clear screen, unset scrolling region, restore tty mode
+ */
+clearvt100()
+ {
+ resetscroll(); clear(); sncbr(); /* system("stty -cbreak echo"); */
+ }
+
+/*
+ * getchar() Routine to read in one character from the terminal
+ */
+getchar()
+ {
+ char byt;
+#ifdef EXTRA
+ c[BYTESIN]++;
+#endif
+ lflush(); /* be sure output buffer is flushed */
+ read(0,&byt,1); /* get byte from terminal */
+ return(byt);
+ }
+
+/*
+ * scbr() Function to set cbreak -echo for the terminal
+ *
+ * like: system("stty cbreak -echo")
+ */
+scbr()
+ {
+ gtty(0,&ttx); doraw(ttx); stty(0,&ttx);
+ }
+
+/*
+ * sncbr() Function to set -cbreak echo for the terminal
+ *
+ * like: system("stty -cbreak echo")
+ */
+sncbr()
+ {
+ gtty(0,&ttx); unraw(ttx); stty(0,&ttx);
+ }
+
+/*
+ * newgame() Subroutine to save the initial time and seed rnd()
+ */
+newgame()
+ {
+ register long *p,*pe;
+ for (p=c,pe=c+100; p<pe; *p++ =0);
+ time(&initialtime); srand(initialtime);
+ lcreat((char*)0); /* open buffering for output to terminal */
+ }
+
+/*
+ * lprintf(format,args . . .) printf to the output buffer
+ * char *format;
+ * ??? args . . .
+ *
+ * Enter with the format string in "format", as per printf() usage
+ * and any needed arguments following it
+ * Note: lprintf() only supports %s, %c and %d, with width modifier and left
+ * or right justification.
+ * No correct checking for output buffer overflow is done, but flushes
+ * are done beforehand if needed.
+ * Returns nothing of value.
+ */
+#ifdef lint
+/*VARARGS*/
+lprintf(str)
+ char *str;
+ {
+ char *str2;
+ str2 = str;
+ str = str2; /* to make lint happy */
+ }
+/*VARARGS*/
+sprintf(str)
+ char *str;
+ {
+ char *str2;
+ str2 = str;
+ str = str2; /* to make lint happy */
+ }
+#else lint
+/*VARARGS*/
+lprintf(va_alist)
+va_dcl
+ {
+ va_list ap; /* pointer for variable argument list */
+ register char *fmt;
+ register char *outb,*tmpb;
+ register long wide,left,cont,n; /* data for lprintf */
+ char db[12]; /* %d buffer in lprintf */
+
+ va_start(ap); /* initialize the var args pointer */
+ fmt = va_arg(ap, char *); /* pointer to format string */
+ if (lpnt >= lpend) lflush();
+ outb = lpnt;
+ for ( ; ; )
+ {
+ while (*fmt != '%')
+ if (*fmt) *outb++ = *fmt++; else { lpnt=outb; return; }
+ wide = 0; left = 1; cont=1;
+ while (cont)
+ switch(*(++fmt))
+ {
+ case 'd': n = va_arg(ap, long);
+ if (n<0) { n = -n; *outb++ = '-'; if (wide) --wide; }
+ tmpb = db+11; *tmpb = (char)(n % 10 + '0');
+ while (n>9) *(--tmpb) = (char)((n /= 10) % 10 + '0');
+ if (wide==0) while (tmpb < db+12) *outb++ = *tmpb++;
+ else
+ {
+ wide -= db-tmpb+12;
+ if (left) while (wide-- > 0) *outb++ = ' ';
+ while (tmpb < db+12) *outb++ = *tmpb++;
+ if (left==0) while (wide-- > 0) *outb++ = ' ';
+ }
+ cont=0; break;
+
+ case 's': tmpb = va_arg(ap, char *);
+ if (wide==0) { while (*outb++ = *tmpb++); --outb; }
+ else
+ {
+ n = wide - strlen(tmpb);
+ if (left) while (n-- > 0) *outb++ = ' ';
+ while (*outb++ = *tmpb++); --outb;
+ if (left==0) while (n-- > 0) *outb++ = ' ';
+ }
+ cont=0; break;
+
+ case 'c': *outb++ = va_arg(ap, int); cont=0; break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': wide = 10*wide + *fmt - '0'; break;
+
+ case '-': left = 0; break;
+
+ default: *outb++ = *fmt; cont=0; break;
+ };
+ fmt++;
+ }
+ va_end(ap);
+ }
+#endif lint
+
+/*
+ * lprint(long-integer) send binary integer to output buffer
+ * long integer;
+ *
+ * +---------+---------+---------+---------+
+ * | high | | | low |
+ * | order | | | order |
+ * | byte | | | byte |
+ * +---------+---------+---------+---------+
+ * 31 --- 24 23 --- 16 15 --- 8 7 --- 0
+ *
+ * The save order is low order first, to high order (4 bytes total)
+ * and is written to be system independent.
+ * No checking for output buffer overflow is done, but flushes if needed!
+ * Returns nothing of value.
+ */
+lprint(x)
+ register long x;
+ {
+ if (lpnt >= lpend) lflush();
+ *lpnt++ = 255 & x; *lpnt++ = 255 & (x>>8);
+ *lpnt++ = 255 & (x>>16); *lpnt++ = 255 & (x>>24);
+ }
+
+/*
+ * lwrite(buf,len) write a buffer to the output buffer
+ * char *buf;
+ * int len;
+ *
+ * Enter with the address and number of bytes to write out
+ * Returns nothing of value
+ */
+lwrite(buf,len)
+ register char *buf;
+ int len;
+ {
+ register char *str;
+ register int num2;
+ if (len > 399) /* don't copy data if can just write it */
+ {
+#ifdef EXTRA
+ c[BYTESOUT] += len;
+#endif
+
+#ifndef VT100
+ for (str=buf; len>0; --len)
+ lprc(*str++);
+#else VT100
+ lflush();
+ write(lfd,buf,len);
+#endif VT100
+ }
+ else while (len)
+ {
+ if (lpnt >= lpend) lflush(); /* if buffer is full flush it */
+ num2 = lpbuf+BUFBIG-lpnt; /* # bytes left in output buffer */
+ if (num2 > len) num2=len;
+ str = lpnt; len -= num2;
+ while (num2--) *str++ = *buf++; /* copy in the bytes */
+ lpnt = str;
+ }
+ }
+
+/*
+ * long lgetc() Read one character from input buffer
+ *
+ * Returns 0 if EOF, otherwise the character
+ */
+long lgetc()
+ {
+ register int i;
+ if (ipoint != iepoint) return(inbuffer[ipoint++]);
+ if (iepoint!=MAXIBUF) return(0);
+ if ((i=read(fd,inbuffer,MAXIBUF))<=0)
+ {
+ if (i!=0) write(1,"error reading from input file\n",30);
+ iepoint = ipoint = 0; return(0);
+ }
+ ipoint=1; iepoint=i; return(*inbuffer);
+ }
+
+/*
+ * long lrint() Read one integer from input buffer
+ *
+ * +---------+---------+---------+---------+
+ * | high | | | low |
+ * | order | | | order |
+ * | byte | | | byte |
+ * +---------+---------+---------+---------+
+ * 31 --- 24 23 --- 16 15 --- 8 7 --- 0
+ *
+ * The save order is low order first, to high order (4 bytes total)
+ * Returns the int read
+ */
+long lrint()
+ {
+ register unsigned long i;
+ i = 255 & lgetc(); i |= (255 & lgetc()) << 8;
+ i |= (255 & lgetc()) << 16; i |= (255 & lgetc()) << 24;
+ return(i);
+ }
+
+/*
+ * lrfill(address,number) put input bytes into a buffer
+ * char *address;
+ * int number;
+ *
+ * Reads "number" bytes into the buffer pointed to by "address".
+ * Returns nothing of value
+ */
+lrfill(adr,num)
+ register char *adr;
+ int num;
+ {
+ register char *pnt;
+ register int num2;
+ while (num)
+ {
+ if (iepoint == ipoint)
+ {
+ if (num>5) /* fast way */
+ {
+ if (read(fd,adr,num) != num)
+ write(2,"error reading from input file\n",30);
+ num=0;
+ }
+ else { *adr++ = lgetc(); --num; }
+ }
+ else
+ {
+ num2 = iepoint-ipoint; /* # of bytes left in the buffer */
+ if (num2 > num) num2=num;
+ pnt = inbuffer+ipoint; num -= num2; ipoint += num2;
+ while (num2--) *adr++ = *pnt++;
+ }
+ }
+ }
+
+/*
+ * char *lgetw() Get a whitespace ended word from input
+ *
+ * Returns pointer to a buffer that contains word. If EOF, returns a NULL
+ */
+char *lgetw()
+ {
+ register char *lgp,cc;
+ register int n=LINBUFSIZE,quote=0;
+ lgp = lgetwbuf;
+ do cc=lgetc(); while ((cc <= 32) && (cc > NULL)); /* eat whitespace */
+ for ( ; ; --n,cc=lgetc())
+ {
+ if ((cc==NULL) && (lgp==lgetwbuf)) return(NULL); /* EOF */
+ if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); }
+ if (cc != '"') *lgp++ = cc; else quote ^= 1;
+ }
+ }
+
+/*
+ * char *lgetl() Function to read in a line ended by newline or EOF
+ *
+ * Returns pointer to a buffer that contains the line. If EOF, returns NULL
+ */
+char *lgetl()
+ {
+ register int i=LINBUFSIZE,ch;
+ register char *str=lgetwbuf;
+ for ( ; ; --i)
+ {
+ if ((*str++ = ch = lgetc()) == NULL)
+ {
+ if (str == lgetwbuf+1) return(NULL); /* EOF */
+ ot: *str = NULL; return(lgetwbuf); /* line ended by EOF */
+ }
+ if ((ch=='\n') || (i<=1)) goto ot; /* line ended by \n */
+ }
+ }
+
+/*
+ * lcreat(filename) Create a new file for write
+ * char *filename;
+ *
+ * lcreat((char*)0); means to the terminal
+ * Returns -1 if error, otherwise the file descriptor opened.
+ */
+lcreat(str)
+ char *str;
+ {
+ lpnt = lpbuf; lpend = lpbuf+BUFBIG;
+ if (str==NULL) return(lfd=1);
+ if ((lfd=creat(str,0644)) < 0)
+ {
+ lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1);
+ }
+ return(lfd);
+ }
+
+/*
+ * lopen(filename) Open a file for read
+ * char *filename;
+ *
+ * lopen(0) means from the terminal
+ * Returns -1 if error, otherwise the file descriptor opened.
+ */
+lopen(str)
+ char *str;
+ {
+ ipoint = iepoint = MAXIBUF;
+ if (str==NULL) return(fd=0);
+ if ((fd=open(str,0)) < 0)
+ {
+ lwclose(); lfd=1; lpnt=lpbuf; return(-1);
+ }
+ return(fd);
+ }
+
+/*
+ * lappend(filename) Open for append to an existing file
+ * char *filename;
+ *
+ * lappend(0) means to the terminal
+ * Returns -1 if error, otherwise the file descriptor opened.
+ */
+lappend(str)
+ char *str;
+ {
+ lpnt = lpbuf; lpend = lpbuf+BUFBIG;
+ if (str==NULL) return(lfd=1);
+ if ((lfd=open(str,2)) < 0)
+ {
+ lfd=1; return(-1);
+ }
+ lseek(lfd,0,2); /* seek to end of file */
+ return(lfd);
+ }
+
+/*
+ * lrclose() close the input file
+ *
+ * Returns nothing of value.
+ */
+lrclose()
+ {
+ if (fd > 0) close(fd);
+ }
+
+/*
+ * lwclose() close output file flushing if needed
+ *
+ * Returns nothing of value.
+ */
+lwclose()
+ {
+ lflush(); if (lfd > 2) close(lfd);
+ }
+
+/*
+ * lprcat(string) append a string to the output buffer
+ * avoids calls to lprintf (time consuming)
+ */
+lprcat(str)
+ register char *str;
+ {
+ register char *str2;
+ if (lpnt >= lpend) lflush();
+ str2 = lpnt;
+ while (*str2++ = *str++);
+ lpnt = str2 - 1;
+ }
+
+#ifdef VT100
+/*
+ * cursor(x,y) Subroutine to set the cursor position
+ *
+ * x and y are the cursor coordinates, and lpbuff is the output buffer where
+ * escape sequence will be placed.
+ */
+static char *y_num[]= { "\33[","\33[","\33[2","\33[3","\33[4","\33[5","\33[6",
+ "\33[7","\33[8","\33[9","\33[10","\33[11","\33[12","\33[13","\33[14",
+ "\33[15","\33[16","\33[17","\33[18","\33[19","\33[20","\33[21","\33[22",
+ "\33[23","\33[24" };
+
+static char *x_num[]= { "H","H",";2H",";3H",";4H",";5H",";6H",";7H",";8H",";9H",
+ ";10H",";11H",";12H",";13H",";14H",";15H",";16H",";17H",";18H",";19H",
+ ";20H",";21H",";22H",";23H",";24H",";25H",";26H",";27H",";28H",";29H",
+ ";30H",";31H",";32H",";33H",";34H",";35H",";36H",";37H",";38H",";39H",
+ ";40H",";41H",";42H",";43H",";44H",";45H",";46H",";47H",";48H",";49H",
+ ";50H",";51H",";52H",";53H",";54H",";55H",";56H",";57H",";58H",";59H",
+ ";60H",";61H",";62H",";63H",";64H",";65H",";66H",";67H",";68H",";69H",
+ ";70H",";71H",";72H",";73H",";74H",";75H",";76H",";77H",";78H",";79H",
+ ";80H" };
+
+cursor(x,y)
+ int x,y;
+ {
+ register char *p;
+ if (lpnt >= lpend) lflush();
+
+ p = y_num[y]; /* get the string to print */
+ while (*p) *lpnt++ = *p++; /* print the string */
+
+ p = x_num[x]; /* get the string to print */
+ while (*p) *lpnt++ = *p++; /* print the string */
+ }
+#else VT100
+/*
+ * cursor(x,y) Put cursor at specified coordinates staring at [1,1] (termcap)
+ */
+cursor (x,y)
+ int x,y;
+ {
+ if (lpnt >= lpend) lflush ();
+
+ *lpnt++ = CURSOR; *lpnt++ = x; *lpnt++ = y;
+ }
+#endif VT100
+
+/*
+ * Routine to position cursor at beginning of 24th line
+ */
+cursors()
+ {
+ cursor(1,24);
+ }
+
+#ifndef VT100
+/*
+ * Warning: ringing the bell is control code 7. Don't use in defines.
+ * Don't change the order of these defines.
+ * Also used in helpfiles. Codes used in helpfiles should be \E[1 to \E[7 with
+ * obvious meanings.
+ */
+
+static char cap[256];
+char *CM, *CE, *CD, *CL, *SO, *SE, *AL, *DL;/* Termcap capabilities */
+static char *outbuf=0; /* translated output buffer */
+
+int putchar ();
+
+/*
+ * init_term() Terminal initialization -- setup termcap info
+ */
+init_term()
+ {
+ char termbuf[1024];
+ char *capptr = cap+10;
+ char *term;
+
+ switch (tgetent(termbuf, term = getenv("TERM")))
+ {
+ case -1:
+ write(2, "Cannot open termcap file.\n", 26); exit();
+ case 0:
+ write(2, "Cannot find entry of ", 21);
+ write(2, term, strlen (term));
+ write(2, " in termcap\n", 12);
+ exit();
+ };
+
+ CM = tgetstr("cm", &capptr); /* Cursor motion */
+ CE = tgetstr("ce", &capptr); /* Clear to eoln */
+ CL = tgetstr("cl", &capptr); /* Clear screen */
+
+/* OPTIONAL */
+ AL = tgetstr("al", &capptr); /* Insert line */
+ DL = tgetstr("dl", &capptr); /* Delete line */
+ SO = tgetstr("so", &capptr); /* Begin standout mode */
+ SE = tgetstr("se", &capptr); /* End standout mode */
+ CD = tgetstr("cd", &capptr); /* Clear to end of display */
+
+ if (!CM) /* can't find cursor motion entry */
+ {
+ write(2, "Sorry, for a ",13); write(2, term, strlen(term));
+ write(2, ", I can't find the cursor motion entry in termcap\n",50);
+ exit();
+ }
+ if (!CE) /* can't find clear to end of line entry */
+ {
+ write(2, "Sorry, for a ",13); write(2, term, strlen(term));
+ write(2,", I can't find the clear to end of line entry in termcap\n",57);
+ exit();
+ }
+ if (!CL) /* can't find clear entire screen entry */
+ {
+ write(2, "Sorry, for a ",13); write(2, term, strlen(term));
+ write(2, ", I can't find the clear entire screen entry in termcap\n",56);
+ exit();
+ }
+ if ((outbuf=malloc(BUFBIG+16))==0) /* get memory for decoded output buffer*/
+ {
+ write(2,"Error malloc'ing memory for decoded output buffer\n",50);
+ died(-285); /* malloc() failure */
+ }
+ }
+#endif VT100
+
+/*
+ * cl_line(x,y) Clear the whole line indicated by 'y' and leave cursor at [x,y]
+ */
+cl_line(x,y)
+ int x,y;
+ {
+#ifdef VT100
+ cursor(x,y); lprcat("\33[2K");
+#else VT100
+ cursor(1,y); *lpnt++ = CL_LINE; cursor(x,y);
+#endif VT100
+ }
+
+/*
+ * cl_up(x,y) Clear screen from [x,1] to current position. Leave cursor at [x,y]
+ */
+cl_up(x,y)
+ register int x,y;
+ {
+#ifdef VT100
+ cursor(x,y); lprcat("\33[1J\33[2K");
+#else VT100
+ register int i;
+ cursor(1,1);
+ for (i=1; i<=y; i++) { *lpnt++ = CL_LINE; *lpnt++ = '\n'; }
+ cursor(x,y);
+#endif VT100
+ }
+
+/*
+ * cl_dn(x,y) Clear screen from [1,y] to end of display. Leave cursor at [x,y]
+ */
+cl_dn(x,y)
+ register int x,y;
+ {
+#ifdef VT100
+ cursor(x,y); lprcat("\33[J\33[2K");
+#else VT100
+ register int i;
+ cursor(1,y);
+ if (!CD)
+ {
+ *lpnt++ = CL_LINE;
+ for (i=y; i<=24; i++) { *lpnt++ = CL_LINE; if (i!=24) *lpnt++ = '\n'; }
+ cursor(x,y);
+ }
+ else
+ *lpnt++ = CL_DOWN;
+ cursor(x,y);
+#endif VT100
+ }
+
+/*
+ * standout(str) Print the argument string in inverse video (standout mode).
+ */
+standout(str)
+ register char *str;
+ {
+#ifdef VT100
+ setbold();
+ while (*str)
+ *lpnt++ = *str++;
+ resetbold();
+#else VT100
+ *lpnt++ = ST_START;
+ while (*str)
+ *lpnt++ = *str++;
+ *lpnt++ = ST_END;
+#endif VT100
+ }
+
+/*
+ * set_score_output() Called when output should be literally printed.
+ */
+set_score_output()
+ {
+ enable_scroll = -1;
+ }
+
+/*
+ * lflush() Flush the output buffer
+ *
+ * Returns nothing of value.
+ * for termcap version: Flush output in output buffer according to output
+ * status as indicated by `enable_scroll'
+ */
+#ifndef VT100
+static int scrline=18; /* line # for wraparound instead of scrolling if no DL */
+lflush ()
+ {
+ register int lpoint;
+ register char *str;
+ static int curx = 0;
+ static int cury = 0;
+
+ if ((lpoint = lpnt - lpbuf) > 0)
+ {
+#ifdef EXTRA
+ c[BYTESOUT] += lpoint;
+#endif
+ if (enable_scroll <= -1)
+ {
+ flush_buf();
+ if (write(lfd,lpbuf,lpoint) != lpoint)
+ write(2,"error writing to output file\n",29);
+ lpnt = lpbuf; /* point back to beginning of buffer */
+ return;
+ }
+ for (str = lpbuf; str < lpnt; str++)
+ {
+ if (*str>=32) { putchar (*str); curx++; }
+ else switch (*str)
+ {
+ case CLEAR: tputs (CL, 0, putchar); curx = cury = 0;
+ break;
+
+ case CL_LINE: tputs (CE, 0, putchar);
+ break;
+
+ case CL_DOWN: tputs (CD, 0, putchar);
+ break;
+
+ case ST_START: tputs (SO, 0, putchar);
+ break;
+
+ case ST_END: tputs (SE, 0, putchar);
+ break;
+
+ case CURSOR: curx = *++str - 1; cury = *++str - 1;
+ tputs (tgoto (CM, curx, cury), 0, putchar);
+ break;
+
+ case '\n': if ((cury == 23) && enable_scroll)
+ {
+ if (!DL || !AL) /* wraparound or scroll? */
+ {
+ if (++scrline > 23) scrline=19;
+
+ if (++scrline > 23) scrline=19;
+ tputs (tgoto (CM, 0, scrline), 0, putchar);
+ tputs (CE, 0, putchar);
+
+ if (--scrline < 19) scrline=23;
+ tputs (tgoto (CM, 0, scrline), 0, putchar);
+ tputs (CE, 0, putchar);
+ }
+ else
+ {
+ tputs (tgoto (CM, 0, 19), 0, putchar);
+ tputs (DL, 0, putchar);
+ tputs (tgoto (CM, 0, 23), 0, putchar);
+ /* tputs (AL, 0, putchar); */
+ }
+ }
+ else
+ {
+ putchar ('\n'); cury++;
+ }
+ curx = 0;
+ break;
+
+ default: putchar (*str); curx++;
+ };
+ }
+ }
+ lpnt = lpbuf;
+ flush_buf(); /* flush real output buffer now */
+ }
+#else VT100
+/*
+ * lflush() flush the output buffer
+ *
+ * Returns nothing of value.
+ */
+lflush()
+ {
+ register int lpoint;
+ if ((lpoint = lpnt - lpbuf) > 0)
+ {
+#ifdef EXTRA
+ c[BYTESOUT] += lpoint;
+#endif
+ if (write(lfd,lpbuf,lpoint) != lpoint)
+ write(2,"error writing to output file\n",29);
+ }
+ lpnt = lpbuf; /* point back to beginning of buffer */
+ }
+#endif VT100
+
+#ifndef VT100
+static int index=0;
+/*
+ * putchar(ch) Print one character in decoded output buffer.
+ */
+int putchar(c)
+int c;
+ {
+ outbuf[index++] = c;
+ if (index >= BUFBIG) flush_buf();
+ }
+
+/*
+ * flush_buf() Flush buffer with decoded output.
+ */
+flush_buf()
+ {
+ if (index) write(lfd, outbuf, index);
+ index = 0;
+ }
+
+/*
+ * char *tmcapcnv(sd,ss) Routine to convert VT100 escapes to termcap format
+ *
+ * Processes only the \33[#m sequence (converts . files for termcap use
+ */
+char *tmcapcnv(sd,ss)
+ register char *sd,*ss;
+ {
+ register int tmstate=0; /* 0=normal, 1=\33 2=[ 3=# */
+ char tmdigit=0; /* the # in \33[#m */
+ while (*ss)
+ {
+ switch(tmstate)
+ {
+ case 0: if (*ss=='\33') { tmstate++; break; }
+ ign: *sd++ = *ss;
+ ign2: tmstate = 0;
+ break;
+ case 1: if (*ss!='[') goto ign;
+ tmstate++;
+ break;
+ case 2: if (isdigit(*ss)) { tmdigit= *ss-'0'; tmstate++; break; }
+ if (*ss == 'm') { *sd++ = ST_END; goto ign2; }
+ goto ign;
+ case 3: if (*ss == 'm')
+ {
+ if (tmdigit) *sd++ = ST_START;
+ else *sd++ = ST_END;
+ goto ign2;
+ }
+ default: goto ign;
+ };
+ ss++;
+ }
+ *sd=0; /* NULL terminator */
+ return(sd);
+ }
+#endif VT100
+
+/*
+ * beep() Routine to emit a beep if enabled (see no-beep in .larnopts)
+ */
+beep()
+ {
+ if (!nobeep) *lpnt++ = '\7';
+ }
diff --git a/larn/larn.6 b/larn/larn.6
new file mode 100644
index 00000000..a4b14a4f
--- /dev/null
+++ b/larn/larn.6
@@ -0,0 +1,158 @@
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)larn.6 5.4 (Berkeley) 8/1/91
+.\"
+.Dd August 1, 1991
+.Dt LARN 6
+.Os
+.Sh NAME
+.Nm larn
+.Nd Exploring the caverns of Larn
+.Sh SYNOPSIS
+.Nm larn
+.Op Fl r
+.Op Fl H Ar number
+.Op Fl n
+.Op Fl h
+.Op Fl o Ar optsfile
+.Sh DESCRIPTION
+.Nm Larn
+is a fantasy games in which your child has contracted
+a strange disease, and none of your home remedies
+seem to have any effect. You set out to find a remedy in a limited
+amount of time, and to collect gold along the way of course!
+.Pp
+The options are:
+.Pp
+.Bl -tag -width flag
+.It Fl r
+The
+.Fl r
+option restores a checkpointed game after it has died.
+.It Fl H
+The
+.Fl H
+option sets the hardness of the game.
+.It Fl n
+The
+.Fl n
+option suppresses the welcome message at start up, putting you directly
+into the game.
+.It Fl h
+The
+.Fl h
+option prints the command line options.
+.It Fl o
+The
+.Fl o
+option specifies a different options file than
+.Pa ~/.larnopts .
+.Sh COMMANDS
+.Pp
+These are the movement commands:
+.Bl -column " print program version" " give present pack weight"
+h move to the left H run left . stay here
+j move down J run down Z teleport yourself
+k move up K run up c cast a spell
+l move to the right L run right r read a scroll
+y move northwest Y run northwest q quaff a potion
+u move northeast U run northeast W wear armor
+b move southwest B run southwest T take off armor
+n move southeast N run southeast w wield a weapon
+^ identify a trap g give present pack weight P give tax status
+d drop an item i inventory your pockets Q quit the game
+v print program version S save the game D list all items found
+? this help screen A create diagnostic file e eat something
+ (wizards only)
+.El
+.Sh OPTIONS FILE
+.Pp
+The file
+.Pa ~/.larnopts
+may be used to set a few options for
+.Nm Larn.
+A sequence of words terminated by whitespace is used to specify options.
+.Pp
+.Bl -tag -width "savefile: xsave-file-namex" -compact
+.It Sy Word
+.Sy Meaning
+.Pp
+.It bold-objects
+Select bold display of objects.
+.It inverse-objects
+Select inverse video display of objects.
+.It no-introduction
+Do not display intro message.
+.It enable-checkpointing
+Turn on periodic checkpointing.
+.It no-beep
+Disable beeping of the terminal.
+.It male
+Choose your sex to be a man.
+.It female
+Choose your sex to be a woman.
+.It name: \*qyour name\*q
+Choose your playing name.
+.It monster: \*qmonst name\*q
+Choose a name for a monster.
+.It savefile: \*qsave-file-name\*q
+Define what the savegame filename will be.
+.El
+.Pp
+Your name and monster names must be enclosed in double quotation marks and may
+be up to 34 characters long. Longer names are truncated.
+Anything enclosed in quotation marks is considered one word, and must be
+separated from other words by whitespace.
+.Sh SPECIAL NOTES
+.Pp
+When
+.Sy dropping gold ,
+if you type '*' as your amount, all your gold gets dropped.
+In general, typing in '*' means all of what your interested in. This is true
+when visiting the bank, or when contributing at altars.
+.Pp
+You can get out of the store, trading post, school, or home by hitting
+.Sy <esc> .
+.Pp
+When casting a spell, if you need a list of spells you can cast, type \fBD\fP
+as the first letter of your spell. The available list of spells will be shown,
+after which you may enter the spell code. This only works on the 1st letter
+of the spell you are casting.
+.Sh AUTHOR
+Noah Morgan
+.Sh FILES
+.Bl -tag -width "/var/games/larn.scores" -compact
+.It Pa /var/games/larn.scores
+Score file.
+.It Pa ~/.larnopts
+Options file.
+.El
diff --git a/larn/main.c b/larn/main.c
new file mode 100644
index 00000000..dbe0c89d
--- /dev/null
+++ b/larn/main.c
@@ -0,0 +1,878 @@
+/* main.c */
+#include <sys/types.h>
+#include "header.h"
+#include <pwd.h>
+static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";
+int srcount=0; /* line counter for showstr() */
+int dropflag=0; /* if 1 then don't lookforobject() next round */
+int rmst=80; /* random monster creation counter */
+int userid; /* the players login user id number */
+char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */
+static char viewflag=0;
+ /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */
+char restorflag=0; /* 1 means restore has been done */
+static char cmdhelp[] = "\
+Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\
+ -s show the scoreboard\n\
+ -l show the logfile (wizard id only)\n\
+ -i show scoreboard with inventories of dead characters\n\
+ -c create new scoreboard (wizard id only)\n\
+ -n suppress welcome message on starting game\n\
+ -## specify level of difficulty (example: -5)\n\
+ -h print this help text\n\
+ ++ restore game from checkpoint file\n\
+ -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
+";
+#ifdef VT100
+static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
+ "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
+ "vt341" };
+#endif VT100
+/*
+ ************
+ MAIN PROGRAM
+ ************
+ */
+main(argc,argv)
+ int argc;
+ char **argv;
+ {
+ register int i,j;
+ int hard;
+ char *ptr=0,*ttype;
+ struct passwd *pwe;
+
+/*
+ * first task is to identify the player
+ */
+#ifndef VT100
+ init_term(); /* setup the terminal (find out what type) for termcap */
+#endif VT100
+ if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */
+ if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
+ ptr = pwe->pw_name;
+ else
+ if ((ptr = getenv("USER")) == 0)
+ if ((ptr = getenv("LOGNAME")) == 0)
+ {
+ noone: write(2, "Can't find your logname. Who Are You?\n",39);
+ exit();
+ }
+ if (ptr==0) goto noone;
+ if (strlen(ptr)==0) goto noone;
+/*
+ * second task is to prepare the pathnames the player will need
+ */
+ strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
+ strcpy(logname,ptr); /* this will be overwritten with the players name */
+ if ((ptr = getenv("HOME")) == 0) ptr = ".";
+ strcpy(savefilename, ptr);
+ strcat(savefilename, "/Larn.sav"); /* save file name in home directory */
+ sprintf(optsfile, "%s/.larnopts",ptr); /* the .larnopts filename */
+
+/*
+ * now malloc the memory for the dungeon
+ */
+ cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
+ if (cell == 0) died(-285); /* malloc failure */
+ lpbuf = malloc((5* BUFBIG)>>2); /* output buffer */
+ inbuffer = malloc((5*MAXIBUF)>>2); /* output buffer */
+ if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */
+
+ lcreat((char*)0); newgame(); /* set the initial clock */ hard= -1;
+
+#ifdef VT100
+/*
+ * check terminal type to avoid users who have not vt100 type terminals
+ */
+ ttype = getenv("TERM");
+ for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
+ if (strcmp(ttype,termtypes[i]) == 0) { j=0; break; }
+ if (j)
+ {
+ lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
+ exit();
+ }
+#endif VT100
+
+/*
+ * now make scoreboard if it is not there (don't clear)
+ */
+ if (access(scorefile,0) == -1) /* not there */
+ makeboard();
+
+/*
+ * now process the command line arguments
+ */
+ for (i=1; i<argc; i++)
+ {
+ if (argv[i][0] == '-')
+ switch(argv[i][1])
+ {
+ case 's': showscores(); exit(); /* show scoreboard */
+
+ case 'l': /* show log file */
+ diedlog(); exit();
+
+ case 'i': showallscores(); exit(); /* show all scoreboard */
+
+ case 'c': /* anyone with password can create scoreboard */
+ lprcat("Preparing to initialize the scoreboard.\n");
+ if (getpassword() != 0) /*make new scoreboard*/
+ {
+ makeboard(); lprc('\n'); showscores();
+ }
+ exit();
+
+ case 'n': /* no welcome msg */ nowelcome=1; argv[i][0]=0; break;
+
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': /* for hardness */
+ sscanf(&argv[i][1],"%d",&hard);
+ break;
+
+ case 'h': /* print out command line arguments */
+ write(1,cmdhelp,sizeof(cmdhelp)); exit();
+
+ case 'o': /* specify a .larnopts filename */
+ strncpy(optsfile,argv[i]+2,127); break;
+
+ default: printf("Unknown option <%s>\n",argv[i]); exit();
+ };
+
+ if (argv[i][0] == '+')
+ {
+ clear(); restorflag = 1;
+ if (argv[i][1] == '+')
+ {
+ hitflag=1; restoregame(ckpfile); /* restore checkpointed game */
+ }
+ i = argc;
+ }
+ }
+
+ readopts(); /* read the options file if there is one */
+
+
+#ifdef UIDSCORE
+ userid = geteuid(); /* obtain the user's effective id number */
+#else UIDSCORE
+ userid = getplid(logname); /* obtain the players id number */
+#endif UIDSCORE
+ if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); }
+
+#ifdef HIDEBYLINK
+/*
+ * this section of code causes the program to look like something else to ps
+ */
+ if (strcmp(psname,argv[0])) /* if a different process name only */
+ {
+ if ((i=access(psname,1)) < 0)
+ { /* link not there */
+ if (link(argv[0],psname)>=0)
+ {
+ argv[0] = psname; execv(psname,argv);
+ }
+ }
+ else
+ unlink(psname);
+ }
+
+ for (i=1; i<argc; i++)
+ {
+ szero(argv[i]); /* zero the argument to avoid ps snooping */
+ }
+#endif HIDEBYLINK
+
+ if (access(savefilename,0)==0) /* restore game if need to */
+ {
+ clear(); restorflag = 1;
+ hitflag=1; restoregame(savefilename); /* restore last game */
+ }
+ sigsetup(); /* trap all needed signals */
+ sethard(hard); /* set up the desired difficulty */
+ setupvt100(); /* setup the terminal special mode */
+ if (c[HP]==0) /* create new game */
+ {
+ makeplayer(); /* make the character that will play */
+ newcavelevel(0);/* make the dungeon */
+ predostuff = 1; /* tell signals that we are in the welcome screen */
+ if (nowelcome==0) welcome(); /* welcome the player to the game */
+ }
+ drawscreen(); /* show the initial dungeon */
+ predostuff = 2; /* tell the trap functions that they must do a showplayer()
+ from here on */
+ /* nice(1); /* games should be run niced */
+ yrepcount = hit2flag = 0;
+ while (1)
+ {
+ if (dropflag==0) lookforobject(); /* see if there is an object here */
+ else dropflag=0; /* don't show it just dropped an item */
+ if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); } /* move the monsters */
+ if (viewflag==0) showcell(playerx,playery); else viewflag=0; /* show stuff around player */
+ if (hit3flag) flushall();
+ hitflag=hit3flag=0; nomove=1;
+ bot_linex(); /* update bottom line */
+ while (nomove)
+ {
+ if (hit3flag) flushall();
+ nomove=0; parse();
+ } /* get commands and make moves */
+ regen(); /* regenerate hp and spells */
+ if (c[TIMESTOP]==0)
+ if (--rmst <= 0)
+ { rmst = 120-(level<<2); fillmonst(makemonst(level)); }
+ }
+ }
+
+/*
+ showstr()
+
+ show character's inventory
+ */
+showstr()
+ {
+ register int i,number;
+ for (number=3, i=0; i<26; i++)
+ if (iven[i]) number++; /* count items in inventory */
+ t_setup(number); qshowstr(); t_endup(number);
+ }
+
+qshowstr()
+ {
+ register int i,j,k,sigsav;
+ srcount=0; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
+ if (c[GOLD]) { lprintf(".) %d gold pieces",(long)c[GOLD]); srcount++; }
+ for (k=26; k>=0; k--)
+ if (iven[k])
+ { for (i=22; i<84; i++)
+ for (j=0; j<=k; j++) if (i==iven[j]) show3(j); k=0; }
+
+ lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
+ more(); nosignal=sigsav;
+ }
+
+/*
+ * subroutine to clear screen depending on # lines to display
+ */
+t_setup(count)
+ register int count;
+ {
+ if (count<20) /* how do we clear the screen? */
+ {
+ cl_up(79,count); cursor(1,1);
+ }
+ else
+ {
+ resetscroll(); clear();
+ }
+ }
+
+/*
+ * subroutine to restore normal display screen depending on t_setup()
+ */
+t_endup(count)
+ register int count;
+ {
+ if (count<18) /* how did we clear the screen? */
+ draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
+ else
+ {
+ drawscreen(); setscroll();
+ }
+ }
+
+/*
+ function to show the things player is wearing only
+ */
+showwear()
+ {
+ register int i,j,sigsav,count;
+ sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
+ srcount=0;
+
+ for (count=2,j=0; j<=26; j++) /* count number of items we will display */
+ if (i=iven[j])
+ switch(i)
+ {
+ case OLEATHER: case OPLATE: case OCHAIN:
+ case ORING: case OSTUDLEATHER: case OSPLINT:
+ case OPLATEARMOR: case OSSPLATE: case OSHIELD:
+ count++;
+ };
+
+ t_setup(count);
+
+ for (i=22; i<84; i++)
+ for (j=0; j<=26; j++)
+ if (i==iven[j])
+ switch(i)
+ {
+ case OLEATHER: case OPLATE: case OCHAIN:
+ case ORING: case OSTUDLEATHER: case OSPLINT:
+ case OPLATEARMOR: case OSSPLATE: case OSHIELD:
+ show3(j);
+ };
+ more(); nosignal=sigsav; t_endup(count);
+ }
+
+/*
+ function to show the things player can wield only
+ */
+showwield()
+ {
+ register int i,j,sigsav,count;
+ sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
+ srcount=0;
+
+ for (count=2,j=0; j<=26; j++) /* count how many items */
+ if (i=iven[j])
+ switch(i)
+ {
+ case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
+ case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT:
+ case OSPIRITSCARAB: case OCUBEofUNDEAD:
+ case OPOTION: case OSCROLL: break;
+ default: count++;
+ };
+
+ t_setup(count);
+
+ for (i=22; i<84; i++)
+ for (j=0; j<=26; j++)
+ if (i==iven[j])
+ switch(i)
+ {
+ case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
+ case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT:
+ case OSPIRITSCARAB: case OCUBEofUNDEAD:
+ case OPOTION: case OSCROLL: break;
+ default: show3(j);
+ };
+ more(); nosignal=sigsav; t_endup(count);
+ }
+
+/*
+ * function to show the things player can read only
+ */
+showread()
+ {
+ register int i,j,sigsav,count;
+ sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
+ srcount=0;
+
+ for (count=2,j=0; j<=26; j++)
+ switch(iven[j])
+ {
+ case OBOOK: case OSCROLL: count++;
+ };
+ t_setup(count);
+
+ for (i=22; i<84; i++)
+ for (j=0; j<=26; j++)
+ if (i==iven[j])
+ switch(i)
+ {
+ case OBOOK: case OSCROLL: show3(j);
+ };
+ more(); nosignal=sigsav; t_endup(count);
+ }
+
+/*
+ * function to show the things player can eat only
+ */
+showeat()
+ {
+ register int i,j,sigsav,count;
+ sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
+ srcount=0;
+
+ for (count=2,j=0; j<=26; j++)
+ switch(iven[j])
+ {
+ case OCOOKIE: count++;
+ };
+ t_setup(count);
+
+ for (i=22; i<84; i++)
+ for (j=0; j<=26; j++)
+ if (i==iven[j])
+ switch(i)
+ {
+ case OCOOKIE: show3(j);
+ };
+ more(); nosignal=sigsav; t_endup(count);
+ }
+
+/*
+ function to show the things player can quaff only
+ */
+showquaff()
+ {
+ register int i,j,sigsav,count;
+ sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
+ srcount=0;
+
+ for (count=2,j=0; j<=26; j++)
+ switch(iven[j])
+ {
+ case OPOTION: count++;
+ };
+ t_setup(count);
+
+ for (i=22; i<84; i++)
+ for (j=0; j<=26; j++)
+ if (i==iven[j])
+ switch(i)
+ {
+ case OPOTION: show3(j);
+ };
+ more(); nosignal=sigsav; t_endup(count);
+ }
+
+show1(idx,str2)
+ register int idx;
+ register char *str2[];
+ {
+ if (str2==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]);
+ else if (*str2[ivenarg[idx]]==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]);
+ else lprintf("\n%c) %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]);
+ }
+
+show3(index)
+ register int index;
+ {
+ switch(iven[index])
+ {
+ case OPOTION: show1(index,potionname); break;
+ case OSCROLL: show1(index,scrollname); break;
+
+ case OLARNEYE: case OBOOK: case OSPIRITSCARAB:
+ case ODIAMOND: case ORUBY: case OCUBEofUNDEAD:
+ case OEMERALD: case OCHEST: case OCOOKIE:
+ case OSAPPHIRE: case ONOTHEFT: show1(index,(char **)0); break;
+
+ default: lprintf("\n%c) %s",index+'a',objectname[iven[index]]);
+ if (ivenarg[index]>0) lprintf(" + %d",(long)ivenarg[index]);
+ else if (ivenarg[index]<0) lprintf(" %d",(long)ivenarg[index]);
+ break;
+ }
+ if (c[WIELD]==index) lprcat(" (weapon in hand)");
+ if ((c[WEAR]==index) || (c[SHIELD]==index)) lprcat(" (being worn)");
+ if (++srcount>=22) { srcount=0; more(); clear(); }
+ }
+
+/*
+ subroutine to randomly create monsters if needed
+ */
+randmonst()
+ {
+ if (c[TIMESTOP]) return; /* don't make monsters if time is stopped */
+ if (--rmst <= 0)
+ {
+ rmst = 120 - (level<<2); fillmonst(makemonst(level));
+ }
+ }
+
+
+/*
+ parse()
+
+ get and execute a command
+ */
+parse()
+ {
+ register int i,j,k,flag;
+ while (1)
+ {
+ k = yylex();
+ switch(k) /* get the token from the input and switch on it */
+ {
+ case 'h': moveplayer(4); return; /* west */
+ case 'H': run(4); return; /* west */
+ case 'l': moveplayer(2); return; /* east */
+ case 'L': run(2); return; /* east */
+ case 'j': moveplayer(1); return; /* south */
+ case 'J': run(1); return; /* south */
+ case 'k': moveplayer(3); return; /* north */
+ case 'K': run(3); return; /* north */
+ case 'u': moveplayer(5); return; /* northeast */
+ case 'U': run(5); return; /* northeast */
+ case 'y': moveplayer(6); return; /* northwest */
+ case 'Y': run(6); return; /* northwest */
+ case 'n': moveplayer(7); return; /* southeast */
+ case 'N': run(7); return; /* southeast */
+ case 'b': moveplayer(8); return; /* southwest */
+ case 'B': run(8); return; /* southwest */
+
+ case '.': if (yrepcount) viewflag=1; return; /* stay here */
+
+ case 'w': yrepcount=0; wield(); return; /* wield a weapon */
+
+ case 'W': yrepcount=0; wear(); return; /* wear armor */
+
+ case 'r': yrepcount=0;
+ if (c[BLINDCOUNT]) { cursors(); lprcat("\nYou can't read anything when you're blind!"); } else
+ if (c[TIMESTOP]==0) readscr(); return; /* to read a scroll */
+
+ case 'q': yrepcount=0; if (c[TIMESTOP]==0) quaff(); return; /* quaff a potion */
+
+ case 'd': yrepcount=0; if (c[TIMESTOP]==0) dropobj(); return; /* to drop an object */
+
+ case 'c': yrepcount=0; cast(); return; /* cast a spell */
+
+ case 'i': yrepcount=0; nomove=1; showstr(); return; /* status */
+
+ case 'e': yrepcount=0;
+ if (c[TIMESTOP]==0) eatcookie(); return; /* to eat a fortune cookie */
+
+ case 'D': yrepcount=0; seemagic(0); nomove=1; return; /* list spells and scrolls */
+
+ case '?': yrepcount=0; help(); nomove=1; return; /* give the help screen*/
+
+ case 'S': clear(); lprcat("Saving . . ."); lflush();
+ savegame(savefilename); wizard=1; died(-257); /* save the game - doesn't return */
+
+ case 'Z': yrepcount=0; if (c[LEVEL]>9) { oteleport(1); return; }
+ cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation");
+ return; /* teleport yourself */
+
+ case '^': /* identify traps */ flag=yrepcount=0; cursors();
+ lprc('\n'); for (j=playery-1; j<playery+2; j++)
+ {
+ if (j < 0) j=0; if (j >= MAXY) break;
+ for (i=playerx-1; i<playerx+2; i++)
+ {
+ if (i < 0) i=0; if (i >= MAXX) break;
+ switch(item[i][j])
+ {
+ case OTRAPDOOR: case ODARTRAP:
+ case OTRAPARROW: case OTELEPORTER:
+ lprcat("\nIts "); lprcat(objectname[item[i][j]]); flag++;
+ };
+ }
+ }
+ if (flag==0) lprcat("\nNo traps are visible");
+ return;
+
+#if WIZID
+ case '_': /* this is the fudge player password for wizard mode*/
+ yrepcount=0; cursors(); nomove=1;
+ if (userid!=wisid)
+ {
+ lprcat("Sorry, you are not empowered to be a wizard.\n");
+ scbr(); /* system("stty -echo cbreak"); */
+ lflush(); return;
+ }
+ if (getpassword()==0)
+ {
+ scbr(); /* system("stty -echo cbreak"); */ return;
+ }
+ wizard=1; scbr(); /* system("stty -echo cbreak"); */
+ for (i=0; i<6; i++) c[i]=70; iven[0]=iven[1]=0;
+ take(OPROTRING,50); take(OLANCE,25); c[WIELD]=1;
+ c[LANCEDEATH]=1; c[WEAR] = c[SHIELD] = -1;
+ raiseexperience(6000000L); c[AWARENESS] += 25000;
+ {
+ register int i,j;
+ for (i=0; i<MAXY; i++)
+ for (j=0; j<MAXX; j++) know[j][i]=1;
+ for (i=0; i<SPNUM; i++) spelknow[i]=1;
+ for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
+ for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
+ }
+ for (i=0; i<MAXSCROLL; i++)
+ if (strlen(scrollname[i])>2) /* no null items */
+ { item[i][0]=OSCROLL; iarg[i][0]=i; }
+ for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
+ if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
+ { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
+ for (i=1; i<MAXY; i++)
+ { item[0][i]=i; iarg[0][i]=0; }
+ for (i=MAXY; i<MAXY+MAXX; i++)
+ { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
+ for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
+ { item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; }
+ c[GOLD]+=25000; drawscreen(); return;
+#endif
+
+ case 'T': yrepcount=0; cursors(); if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
+ if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
+ else lprcat("\nYou aren't wearing anything");
+ return;
+
+ case 'g': cursors();
+ lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
+ case ' ': yrepcount=0; nomove=1; return;
+
+ case 'v': yrepcount=0; cursors();
+ lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]);
+ if (wizard) lprcat(" Wizard"); nomove=1;
+ if (cheat) lprcat(" Cheater");
+ lprcat(copyright);
+ return;
+
+ case 'Q': yrepcount=0; quit(); nomove=1; return; /* quit */
+
+ case 'L'-64: yrepcount=0; drawscreen(); nomove=1; return; /* look */
+
+#if WIZID
+#ifdef EXTRA
+ case 'A': yrepcount=0; nomove=1; if (wizard) { diag(); return; } /* create diagnostic file */
+ return;
+#endif
+#endif
+ case 'P': cursors();
+ if (outstanding_taxes>0)
+ lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
+ else
+ lprcat("\nYou do not owe any taxes.");
+ return;
+ };
+ }
+ }
+
+parse2()
+ {
+ if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters */
+ randmonst(); regen();
+ }
+
+run(dir)
+ int dir;
+ {
+ register int i;
+ i=1; while (i)
+ {
+ i=moveplayer(dir);
+ if (i>0) { if (c[HASTEMONST]) movemonst(); movemonst(); randmonst(); regen(); }
+ if (hitflag) i=0;
+ if (i!=0) showcell(playerx,playery);
+ }
+ }
+
+/*
+ function to wield a weapon
+ */
+wield()
+ {
+ register int i;
+ while (1)
+ {
+ if ((i = whatitem("wield"))=='\33') return;
+ if (i != '.')
+ {
+ if (i=='*') showwield();
+ else if (iven[i-'a']==0) { ydhi(i); return; }
+ else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
+ else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
+ else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; }
+ else { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0; bottomline(); return; }
+ }
+ }
+ }
+
+/*
+ common routine to say you don't have an item
+ */
+ydhi(x)
+ int x;
+ { cursors(); lprintf("\nYou don't have item %c!",x); }
+ycwi(x)
+ int x;
+ { cursors(); lprintf("\nYou can't wield item %c!",x); }
+
+/*
+ function to wear armor
+ */
+wear()
+ {
+ register int i;
+ while (1)
+ {
+ if ((i = whatitem("wear"))=='\33') return;
+ if (i != '.')
+ {
+ if (i=='*') showwear(); else
+ switch(iven[i-'a'])
+ {
+ case 0: ydhi(i); return;
+ case OLEATHER: case OCHAIN: case OPLATE: case OSTUDLEATHER:
+ case ORING: case OSPLINT: case OPLATEARMOR: case OSSPLATE:
+ if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
+ c[WEAR]=i-'a'; bottomline(); return;
+ case OSHIELD: if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
+ if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
+ c[SHIELD] = i-'a'; bottomline(); return;
+ default: lprcat("\nYou can't wear that!");
+ };
+ }
+ }
+ }
+
+/*
+ function to drop an object
+ */
+dropobj()
+ {
+ register int i;
+ register char *p;
+ long amt;
+ p = &item[playerx][playery];
+ while (1)
+ {
+ if ((i = whatitem("drop"))=='\33') return;
+ if (i=='*') showstr(); else
+ {
+ if (i=='.') /* drop some gold */
+ {
+ if (*p) { lprcat("\nThere's something here already!"); return; }
+ lprcat("\n\n");
+ cl_dn(1,23);
+ lprcat("How much gold do you drop? ");
+ if ((amt=readnum((long)c[GOLD])) == 0) return;
+ if (amt>c[GOLD])
+ { lprcat("\nYou don't have that much!"); return; }
+ if (amt<=32767)
+ { *p=OGOLDPILE; i=amt; }
+ else if (amt<=327670L)
+ { *p=ODGOLD; i=amt/10; amt = 10*i; }
+ else if (amt<=3276700L)
+ { *p=OMAXGOLD; i=amt/100; amt = 100*i; }
+ else if (amt<=32767000L)
+ { *p=OKGOLD; i=amt/1000; amt = 1000*i; }
+ else
+ { *p=OKGOLD; i=32767; amt = 32767000L; }
+ c[GOLD] -= amt;
+ lprintf("You drop %d gold pieces",(long)amt);
+ iarg[playerx][playery]=i; bottomgold();
+ know[playerx][playery]=0; dropflag=1; return;
+ }
+ drop_object(i-'a');
+ return;
+ }
+ }
+ }
+
+/*
+ * readscr() Subroutine to read a scroll one is carrying
+ */
+readscr()
+ {
+ register int i;
+ while (1)
+ {
+ if ((i = whatitem("read"))=='\33') return;
+ if (i != '.')
+ {
+ if (i=='*') showread(); else
+ {
+ if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
+ if (iven[i-'a']==OBOOK) { readbook(ivenarg[i-'a']); iven[i-'a']=0; return; }
+ if (iven[i-'a']==0) { ydhi(i); return; }
+ lprcat("\nThere's nothing on it to read"); return;
+ }
+ }
+ }
+ }
+
+/*
+ * subroutine to eat a cookie one is carrying
+ */
+eatcookie()
+{
+register int i;
+char *p;
+while (1)
+ {
+ if ((i = whatitem("eat"))=='\33') return;
+ if (i != '.')
+ if (i=='*') showeat(); else
+ {
+ if (iven[i-'a']==OCOOKIE)
+ {
+ lprcat("\nThe cookie was delicious.");
+ iven[i-'a']=0;
+ if (!c[BLINDCOUNT])
+ {
+ if (p=fortune(fortfile))
+ {
+ lprcat(" Inside you find a scrap of paper that says:\n");
+ lprcat(p);
+ }
+ }
+ return;
+ }
+ if (iven[i-'a']==0) { ydhi(i); return; }
+ lprcat("\nYou can't eat that!"); return;
+ }
+ }
+}
+
+/*
+ * subroutine to quaff a potion one is carrying
+ */
+quaff()
+ {
+ register int i;
+ while (1)
+ {
+ if ((i = whatitem("quaff"))=='\33') return;
+ if (i != '.')
+ {
+ if (i=='*') showquaff(); else
+ {
+ if (iven[i-'a']==OPOTION) { quaffpotion(ivenarg[i-'a']); iven[i-'a']=0; return; }
+ if (iven[i-'a']==0) { ydhi(i); return; }
+ lprcat("\nYou wouldn't want to quaff that, would you? "); return;
+ }
+ }
+ }
+ }
+
+/*
+ function to ask what player wants to do
+ */
+whatitem(str)
+ char *str;
+ {
+ int i;
+ cursors(); lprintf("\nWhat do you want to %s [* for all] ? ",str);
+ i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
+ if (i=='\33') lprcat(" aborted");
+ return(i);
+ }
+
+/*
+ subroutine to get a number from the player
+ and allow * to mean return amt, else return the number entered
+ */
+unsigned long readnum(mx)
+ long mx;
+ {
+ register int i;
+ register unsigned long amt=0;
+ sncbr();
+ if ((i=getchar()) == '*') amt = mx; /* allow him to say * for all gold */
+ else
+ while (i != '\n')
+ {
+ if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
+ if ((i <= '9') && (i >= '0') && (amt<99999999))
+ amt = amt*10+i-'0';
+ i = getchar();
+ }
+ scbr(); return(amt);
+ }
+
+#ifdef HIDEBYLINK
+/*
+ * routine to zero every byte in a string
+ */
+szero(str)
+ register char *str;
+ {
+ while (*str)
+ *str++ = 0;
+ }
+#endif HIDEBYLINK
diff --git a/larn/monster.c b/larn/monster.c
new file mode 100644
index 00000000..6ec08651
--- /dev/null
+++ b/larn/monster.c
@@ -0,0 +1,1387 @@
+/*
+ * monster.c Larn is copyrighted 1986 by Noah Morgan.
+ *
+ * This file contains the following functions:
+ * ----------------------------------------------------------------------------
+ *
+ * createmonster(monstno) Function to create a monster next to the player
+ * int monstno;
+ *
+ * int cgood(x,y,itm,monst) Function to check location for emptiness
+ * int x,y,itm,monst;
+ *
+ * createitem(it,arg) Routine to place an item next to the player
+ * int it,arg;
+ *
+ * cast() Subroutine called by parse to cast a spell for the user
+ *
+ * speldamage(x) Function to perform spell functions cast by the player
+ * int x;
+ *
+ * loseint() Routine to decrement your int (intelligence) if > 3
+ *
+ * isconfuse() Routine to check to see if player is confused
+ *
+ * nospell(x,monst) Routine to return 1 if a spell doesn't affect a monster
+ * int x,monst;
+ *
+ * fullhit(xx) Function to return full damage against a monst (aka web)
+ * int xx;
+ *
+ * direct(spnum,dam,str,arg) Routine to direct spell damage 1 square in 1 dir
+ * int spnum,dam,arg;
+ * char *str;
+ *
+ * godirect(spnum,dam,str,delay,cshow) Function to perform missile attacks
+ * int spnum,dam,delay;
+ * char *str,cshow;
+ *
+ * ifblind(x,y) Routine to put "monster" or the monster name into lastmosnt
+ * int x,y;
+ *
+ * tdirect(spnum) Routine to teleport away a monster
+ * int spnum;
+ *
+ * omnidirect(sp,dam,str) Routine to damage all monsters 1 square from player
+ * int sp,dam;
+ * char *str;
+ *
+ * dirsub(x,y) Routine to ask for direction, then modify x,y for it
+ * int *x,*y;
+ *
+ * vxy(x,y) Routine to verify/fix (*x,*y) for being within bounds
+ * int *x,*y;
+ *
+ * dirpoly(spnum) Routine to ask for a direction and polymorph a monst
+ * int spnum;
+ *
+ * hitmonster(x,y) Function to hit a monster at the designated coordinates
+ * int x,y;
+ *
+ * hitm(x,y,amt) Function to just hit a monster at a given coordinates
+ * int x,y,amt;
+ *
+ * hitplayer(x,y) Function for the monster to hit the player from (x,y)
+ * int x,y;
+ *
+ * dropsomething(monst) Function to create an object when a monster dies
+ * int monst;
+ *
+ * dropgold(amount) Function to drop some gold around player
+ * int amount;
+ *
+ * something(level) Function to create a random item around player
+ * int level;
+ *
+ * newobject(lev,i) Routine to return a randomly selected new object
+ * int lev,*i;
+ *
+ * spattack(atckno,xx,yy) Function to process special attacks from monsters
+ * int atckno,xx,yy;
+ *
+ * checkloss(x) Routine to subtract hp from user and flag bottomline display
+ * int x;
+ *
+ * annihilate() Routine to annihilate monsters around player, playerx,playery
+ *
+ * newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation
+ * int x,y,dir,lifetime;
+ *
+ * rmsphere(x,y) Function to delete a sphere of annihilation from list
+ * int x,y;
+ *
+ * sphboom(x,y) Function to perform the effects of a sphere detonation
+ * int x,y;
+ *
+ * genmonst() Function to ask for monster and genocide from game
+ *
+ */
+#include "header.h"
+
+struct isave /* used for altar reality */
+ {
+ char type; /* 0=item, 1=monster */
+ char id; /* item number or monster number */
+ short arg; /* the type of item or hitpoints of monster */
+ };
+
+/*
+ * createmonster(monstno) Function to create a monster next to the player
+ * int monstno;
+ *
+ * Enter with the monster number (1 to MAXMONST+8)
+ * Returns no value.
+ */
+createmonster(mon)
+ int mon;
+ {
+ register int x,y,k,i;
+ if (mon<1 || mon>MAXMONST+8) /* check for monster number out of bounds */
+ {
+ beep(); lprintf("\ncan't createmonst(%d)\n",(long)mon); nap(3000); return;
+ }
+ while (monster[mon].genocided && mon<MAXMONST) mon++; /* genocided? */
+ for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
+ {
+ if (k>8) k=1; /* wraparound the diroff arrays */
+ x = playerx + diroffx[k]; y = playery + diroffy[k];
+ if (cgood(x,y,0,1)) /* if we can create here */
+ {
+ mitem[x][y] = mon;
+ hitp[x][y] = monster[mon].hitpoints;
+ stealth[x][y]=know[x][y]=0;
+ switch(mon)
+ {
+ case ROTHE: case POLTERGEIST: case VAMPIRE: stealth[x][y]=1;
+ };
+ return;
+ }
+ }
+ }
+
+/*
+ * int cgood(x,y,itm,monst) Function to check location for emptiness
+ * int x,y,itm,monst;
+ *
+ * Routine to return TRUE if a location does not have itm or monst there
+ * returns FALSE (0) otherwise
+ * Enter with itm or monst TRUE or FALSE if checking it
+ * Example: if itm==TRUE check for no item at this location
+ * if monst==TRUE check for no monster at this location
+ * This routine will return FALSE if at a wall or the dungeon exit on level 1
+ */
+int cgood(x,y,itm,monst)
+ register int x,y;
+ int itm,monst;
+ {
+ if ((y>=0) && (y<=MAXY-1) && (x>=0) && (x<=MAXX-1)) /* within bounds? */
+ if (item[x][y]!=OWALL) /* can't make anything on walls */
+ if (itm==0 || (item[x][y]==0)) /* is it free of items? */
+ if (monst==0 || (mitem[x][y]==0)) /* is it free of monsters? */
+ if ((level!=1) || (x!=33) || (y!=MAXY-1)) /* not exit to level 1 */
+ return(1);
+ return(0);
+ }
+
+/*
+ * createitem(it,arg) Routine to place an item next to the player
+ * int it,arg;
+ *
+ * Enter with the item number and its argument (iven[], ivenarg[])
+ * Returns no value, thus we don't know about createitem() failures.
+ */
+createitem(it,arg)
+ int it,arg;
+ {
+ register int x,y,k,i;
+ if (it >= MAXOBJ) return; /* no such object */
+ for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
+ {
+ if (k>8) k=1; /* wraparound the diroff arrays */
+ x = playerx + diroffx[k]; y = playery + diroffy[k];
+ if (cgood(x,y,1,0)) /* if we can create here */
+ {
+ item[x][y] = it; know[x][y]=0; iarg[x][y]=arg; return;
+ }
+ }
+ }
+
+/*
+ * cast() Subroutine called by parse to cast a spell for the user
+ *
+ * No arguments and no return value.
+ */
+static char eys[] = "\nEnter your spell: ";
+cast()
+ {
+ register int i,j,a,b,d;
+ cursors();
+ if (c[SPELLS]<=0) { lprcat("\nYou don't have any spells!"); return; }
+ lprcat(eys); --c[SPELLS];
+ while ((a=getchar())=='D')
+ { seemagic(-1); cursors(); lprcat(eys); }
+ if (a=='\33') goto over; /* to escape casting a spell */
+ if ((b=getchar())=='\33') goto over; /* to escape casting a spell */
+ if ((d=getchar())=='\33')
+ { over: lprcat(aborted); c[SPELLS]++; return; } /* to escape casting a spell */
+#ifdef EXTRA
+ c[SPELLSCAST]++;
+#endif
+ for (lprc('\n'),j= -1,i=0; i<SPNUM; i++) /*seq search for his spell, hash?*/
+ if ((spelcode[i][0]==a) && (spelcode[i][1]==b) && (spelcode[i][2]==d))
+ if (spelknow[i])
+ { speldamage(i); j = 1; i=SPNUM; }
+
+ if (j == -1) lprcat(" Nothing Happened ");
+ bottomline();
+ }
+
+static int dirsub();
+
+/*
+ * speldamage(x) Function to perform spell functions cast by the player
+ * int x;
+ *
+ * Enter with the spell number, returns no value.
+ * Please insure that there are 2 spaces before all messages here
+ */
+speldamage(x)
+ int x;
+ {
+ register int i,j,clev;
+ int xl,xh,yl,yh;
+ register char *p,*kn,*pm;
+ if (x>=SPNUM) return; /* no such spell */
+ if (c[TIMESTOP]) { lprcat(" It didn't seem to work"); return; } /* not if time stopped */
+ clev = c[LEVEL];
+ if ((rnd(23)==7) || (rnd(18) > c[INTELLIGENCE]))
+ { lprcat(" It didn't work!"); return; }
+ if (clev*3+2 < x) { lprcat(" Nothing happens. You seem inexperienced at this"); return; }
+
+ switch(x)
+ {
+/* ----- LEVEL 1 SPELLS ----- */
+
+ case 0: if (c[PROTECTIONTIME]==0) c[MOREDEFENSES]+=2; /* protection field +2 */
+ c[PROTECTIONTIME] += 250; return;
+
+ case 1: i = rnd(((clev+1)<<1)) + clev + 3;
+ godirect(x,i,(clev>=2)?" Your missiles hit the %s":" Your missile hit the %s",100,'+'); /* magic missile */
+
+ return;
+
+ case 2: if (c[DEXCOUNT]==0) c[DEXTERITY]+=3; /* dexterity */
+ c[DEXCOUNT] += 400; return;
+
+ case 3: i=rnd(3)+1;
+ p=" While the %s slept, you smashed it %d times";
+ ws: direct(x,fullhit(i),p,i); /* sleep */ return;
+
+ case 4: /* charm monster */ c[CHARMCOUNT] += c[CHARISMA]<<1; return;
+
+ case 5: godirect(x,rnd(10)+15+clev," The sound damages the %s",70,'@'); /* sonic spear */
+ return;
+
+/* ----- LEVEL 2 SPELLS ----- */
+
+ case 6: i=rnd(3)+2; p=" While the %s is entangled, you hit %d times";
+ goto ws; /* web */
+
+ case 7: if (c[STRCOUNT]==0) c[STREXTRA]+=3; /* strength */
+ c[STRCOUNT] += 150+rnd(100); return;
+
+ case 8: yl = playery-5; /* enlightenment */
+ yh = playery+6; xl = playerx-15; xh = playerx+16;
+ vxy(&xl,&yl); vxy(&xh,&yh); /* check bounds */
+ for (i=yl; i<=yh; i++) /* enlightenment */
+ for (j=xl; j<=xh; j++) know[j][i]=1;
+ draws(xl,xh+1,yl,yh+1); return;
+
+ case 9: raisehp(20+(clev<<1)); return; /* healing */
+
+ case 10: c[BLINDCOUNT]=0; return; /* cure blindness */
+
+ case 11: createmonster(makemonst(level+1)+8); return;
+
+ case 12: if (rnd(11)+7 <= c[WISDOM]) direct(x,rnd(20)+20+clev," The %s believed!",0);
+ else lprcat(" It didn't believe the illusions!");
+ return;
+
+ case 13: /* if he has the amulet of invisibility then add more time */
+ for (j=i=0; i<26; i++)
+ if (iven[i]==OAMULET) j+= 1+ivenarg[i];
+ c[INVISIBILITY] += (j<<7)+12; return;
+
+/* ----- LEVEL 3 SPELLS ----- */
+
+ case 14: godirect(x,rnd(25+clev)+25+clev," The fireball hits the %s",40,'*'); return; /* fireball */
+
+ case 15: godirect(x,rnd(25)+20+clev," Your cone of cold strikes the %s",60,'O'); /* cold */
+ return;
+
+ case 16: dirpoly(x); return; /* polymorph */
+
+ case 17: c[CANCELLATION]+= 5+clev; return; /* cancellation */
+
+ case 18: c[HASTESELF]+= 7+clev; return; /* haste self */
+
+ case 19: omnidirect(x,30+rnd(10)," The %s gasps for air"); /* cloud kill */
+ return;
+
+ case 20: xh = min(playerx+1,MAXX-2); yh = min(playery+1,MAXY-2);
+ for (i=max(playerx-1,1); i<=xh; i++) /* vaporize rock */
+ for (j=max(playery-1,1); j<=yh; j++)
+ {
+ kn = &know[i][j]; pm = &mitem[i][j];
+ switch(*(p= &item[i][j]))
+ {
+ case OWALL: if (level < MAXLEVEL+MAXVLEVEL-1)
+ *p = *kn = 0;
+ break;
+
+ case OSTATUE: if (c[HARDGAME]<3)
+ {
+ *p=OBOOK; iarg[i][j]=level; *kn=0;
+ }
+ break;
+
+ case OTHRONE: *pm=GNOMEKING; *kn=0; *p= OTHRONE2;
+ hitp[i][j]=monster[GNOMEKING].hitpoints; break;
+
+ case OALTAR: *pm=DEMONPRINCE; *kn=0;
+ hitp[i][j]=monster[DEMONPRINCE].hitpoints; break;
+ };
+ switch(*pm)
+ {
+ case XORN: ifblind(i,j); hitm(i,j,200); break; /* Xorn takes damage from vpr */
+ }
+ }
+ return;
+
+/* ----- LEVEL 4 SPELLS ----- */
+
+ case 21: direct(x,100+clev," The %s shrivels up",0); /* dehydration */
+ return;
+
+ case 22: godirect(x,rnd(25)+20+(clev<<1)," A lightning bolt hits the %s",1,'~'); /* lightning */
+ return;
+
+ case 23: i=min(c[HP]-1,c[HPMAX]/2); /* drain life */
+ direct(x,i+i,"",0); c[HP] -= i; return;
+
+ case 24: if (c[GLOBE]==0) c[MOREDEFENSES] += 10;
+ c[GLOBE] += 200; loseint(); /* globe of invulnerability */
+ return;
+
+ case 25: omnidirect(x,32+clev," The %s struggles for air in your flood!"); /* flood */
+ return;
+
+ case 26: if (rnd(151)==63) { beep(); lprcat("\nYour heart stopped!\n"); nap(4000); died(270); return; }
+ if (c[WISDOM]>rnd(10)+10) direct(x,2000," The %s's heart stopped",0); /* finger of death */
+ else lprcat(" It didn't work"); return;
+
+/* ----- LEVEL 5 SPELLS ----- */
+
+ case 27: c[SCAREMONST] += rnd(10)+clev; return; /* scare monster */
+
+ case 28: c[HOLDMONST] += rnd(10)+clev; return; /* hold monster */
+
+ case 29: c[TIMESTOP] += rnd(20)+(clev<<1); return; /* time stop */
+
+ case 30: tdirect(x); return; /* teleport away */
+
+ case 31: omnidirect(x,35+rnd(10)+clev," The %s cringes from the flame"); /* magic fire */
+ return;
+
+/* ----- LEVEL 6 SPELLS ----- */
+
+ case 32: if ((rnd(23)==5) && (wizard==0)) /* sphere of annihilation */
+ {
+ beep(); lprcat("\nYou have been enveloped by the zone of nothingness!\n");
+ nap(4000); died(258); return;
+ }
+ xl=playerx; yl=playery;
+ loseint();
+ i=dirsub(&xl,&yl); /* get direction of sphere */
+ newsphere(xl,yl,i,rnd(20)+11); /* make a sphere */
+ return;
+
+ case 33: genmonst(); spelknow[33]=0; /* genocide */
+ loseint();
+ return;
+
+ case 34: /* summon demon */
+ if (rnd(100) > 30) { direct(x,150," The demon strikes at the %s",0); return; }
+ if (rnd(100) > 15) { lprcat(" Nothing seems to have happened"); return; }
+ lprcat(" The demon turned on you and vanished!"); beep();
+ i=rnd(40)+30; lastnum=277;
+ losehp(i); /* must say killed by a demon */ return;
+
+ case 35: /* walk through walls */
+ c[WTW] += rnd(10)+5; return;
+
+ case 36: /* alter reality */
+ {
+ struct isave *save; /* pointer to item save structure */
+ int sc; sc=0; /* # items saved */
+ save = (struct isave *)malloc(sizeof(struct isave)*MAXX*MAXY*2);
+ for (j=0; j<MAXY; j++)
+ for (i=0; i<MAXX; i++) /* save all items and monsters */
+ {
+ xl = item[i][j];
+ if (xl && xl!=OWALL && xl!=OANNIHILATION)
+ {
+ save[sc].type=0; save[sc].id=item[i][j];
+ save[sc++].arg=iarg[i][j];
+ }
+ if (mitem[i][j])
+ {
+ save[sc].type=1; save[sc].id=mitem[i][j];
+ save[sc++].arg=hitp[i][j];
+ }
+ item[i][j]=OWALL; mitem[i][j]=0;
+ if (wizard) know[i][j]=1; else know[i][j]=0;
+ }
+ eat(1,1); if (level==1) item[33][MAXY-1]=0;
+ for (j=rnd(MAXY-2), i=1; i<MAXX-1; i++) item[i][j]=0;
+ while (sc>0) /* put objects back in level */
+ {
+ --sc;
+ if (save[sc].type == 0)
+ {
+ int trys;
+ for (trys=100, i=j=1; --trys>0 && item[i][j]; i=rnd(MAXX-1), j=rnd(MAXY-1));
+ if (trys) { item[i][j]=save[sc].id; iarg[i][j]=save[sc].arg; }
+ }
+ else
+ { /* put monsters back in */
+ int trys;
+ for (trys=100, i=j=1; --trys>0 && (item[i][j]==OWALL || mitem[i][j]); i=rnd(MAXX-1), j=rnd(MAXY-1));
+ if (trys) { mitem[i][j]=save[sc].id; hitp[i][j]=save[sc].arg; }
+ }
+ }
+ loseint();
+ draws(0,MAXX,0,MAXY); if (wizard==0) spelknow[36]=0;
+ free((char*)save); positionplayer(); return;
+ }
+
+ case 37: /* permanence */ adjtime(-99999L); spelknow[37]=0; /* forget */
+ loseint();
+ return;
+
+ default: lprintf(" spell %d not available!",(long)x); beep(); return;
+ };
+ }
+
+/*
+ * loseint() Routine to subtract 1 from your int (intelligence) if > 3
+ *
+ * No arguments and no return value
+ */
+loseint()
+ {
+ if (--c[INTELLIGENCE]<3) c[INTELLIGENCE]=3;
+ }
+
+/*
+ * isconfuse() Routine to check to see if player is confused
+ *
+ * This routine prints out a message saying "You can't aim your magic!"
+ * returns 0 if not confused, non-zero (time remaining confused) if confused
+ */
+isconfuse()
+ {
+ if (c[CONFUSE]) { lprcat(" You can't aim your magic!"); beep(); }
+ return(c[CONFUSE]);
+ }
+
+/*
+ * nospell(x,monst) Routine to return 1 if a spell doesn't affect a monster
+ * int x,monst;
+ *
+ * Subroutine to return 1 if the spell can't affect the monster
+ * otherwise returns 0
+ * Enter with the spell number in x, and the monster number in monst.
+ */
+nospell(x,monst)
+ int x,monst;
+ {
+ register int tmp;
+ if (x>=SPNUM || monst>=MAXMONST+8 || monst<0 || x<0) return(0); /* bad spell or monst */
+ if ((tmp=spelweird[monst-1][x])==0) return(0);
+ cursors(); lprc('\n'); lprintf(spelmes[tmp],monster[monst].name); return(1);
+ }
+
+/*
+ * fullhit(xx) Function to return full damage against a monster (aka web)
+ * int xx;
+ *
+ * Function to return hp damage to monster due to a number of full hits
+ * Enter with the number of full hits being done
+ */
+fullhit(xx)
+ int xx;
+ {
+ register int i;
+ if (xx<0 || xx>20) return(0); /* fullhits are out of range */
+ if (c[LANCEDEATH]) return(10000); /* lance of death */
+ i = xx * ((c[WCLASS]>>1)+c[STRENGTH]+c[STREXTRA]-c[HARDGAME]-12+c[MOREDAM]);
+ return( (i>=1) ? i : xx );
+ }
+
+/*
+ * direct(spnum,dam,str,arg) Routine to direct spell damage 1 square in 1 dir
+ * int spnum,dam,arg;
+ * char *str;
+ *
+ * Routine to ask for a direction to a spell and then hit the monster
+ * Enter with the spell number in spnum, the damage to be done in dam,
+ * lprintf format string in str, and lprintf's argument in arg.
+ * Returns no value.
+ */
+direct(spnum,dam,str,arg)
+ int spnum,dam,arg;
+ char *str;
+ {
+ int x,y;
+ register int m;
+ if (spnum<0 || spnum>=SPNUM || str==0) return; /* bad arguments */
+ if (isconfuse()) return;
+ dirsub(&x,&y);
+ m = mitem[x][y];
+ if (item[x][y]==OMIRROR)
+ {
+ if (spnum==3) /* sleep */
+ {
+ lprcat("You fall asleep! "); beep();
+ fool:
+ arg += 2;
+ while (arg-- > 0) { parse2(); nap(1000); }
+ return;
+ }
+ else if (spnum==6) /* web */
+ {
+ lprcat("You get stuck in your own web! "); beep();
+ goto fool;
+ }
+ else
+ {
+ lastnum=278;
+ lprintf(str,"spell caster (thats you)",(long)arg);
+ beep(); losehp(dam); return;
+ }
+ }
+ if (m==0)
+ { lprcat(" There wasn't anything there!"); return; }
+ ifblind(x,y);
+ if (nospell(spnum,m)) { lasthx=x; lasthy=y; return; }
+ lprintf(str,lastmonst,(long)arg); hitm(x,y,dam);
+ }
+
+/*
+ * godirect(spnum,dam,str,delay,cshow) Function to perform missile attacks
+ * int spnum,dam,delay;
+ * char *str,cshow;
+ *
+ * Function to hit in a direction from a missile weapon and have it keep
+ * on going in that direction until its power is exhausted
+ * Enter with the spell number in spnum, the power of the weapon in hp,
+ * lprintf format string in str, the # of milliseconds to delay between
+ * locations in delay, and the character to represent the weapon in cshow.
+ * Returns no value.
+ */
+godirect(spnum,dam,str,delay,cshow)
+ int spnum,dam,delay;
+ char *str,cshow;
+ {
+ register char *p;
+ register int x,y,m;
+ int dx,dy;
+ if (spnum<0 || spnum>=SPNUM || str==0 || delay<0) return; /* bad args */
+ if (isconfuse()) return;
+ dirsub(&dx,&dy); x=dx; y=dy;
+ dx = x-playerx; dy = y-playery; x = playerx; y = playery;
+ while (dam>0)
+ {
+ x += dx; y += dy;
+ if ((x > MAXX-1) || (y > MAXY-1) || (x < 0) || (y < 0))
+ {
+ dam=0; break; /* out of bounds */
+ }
+ if ((x==playerx) && (y==playery)) /* if energy hits player */
+ {
+ cursors(); lprcat("\nYou are hit my your own magic!"); beep();
+ lastnum=278; losehp(dam); return;
+ }
+ if (c[BLINDCOUNT]==0) /* if not blind show effect */
+ {
+ cursor(x+1,y+1); lprc(cshow); nap(delay); show1cell(x,y);
+ }
+ if ((m=mitem[x][y])) /* is there a monster there? */
+ {
+ ifblind(x,y);
+ if (nospell(spnum,m)) { lasthx=x; lasthy=y; return; }
+ cursors(); lprc('\n');
+ lprintf(str,lastmonst); dam -= hitm(x,y,dam);
+ show1cell(x,y); nap(1000); x -= dx; y -= dy;
+ }
+ else switch (*(p= &item[x][y]))
+ {
+ case OWALL: cursors(); lprc('\n'); lprintf(str,"wall");
+ if (dam>=50+c[HARDGAME]) /* enough damage? */
+ if (level<MAXLEVEL+MAXVLEVEL-1) /* not on V3 */
+ if ((x<MAXX-1) && (y<MAXY-1) && (x) && (y))
+ {
+ lprcat(" The wall crumbles");
+ god3: *p=0;
+ god: know[x][y]=0;
+ show1cell(x,y);
+ }
+ god2: dam = 0; break;
+
+ case OCLOSEDDOOR: cursors(); lprc('\n'); lprintf(str,"door");
+ if (dam>=40)
+ {
+ lprcat(" The door is blasted apart");
+ goto god3;
+ }
+ goto god2;
+
+ case OSTATUE: cursors(); lprc('\n'); lprintf(str,"statue");
+ if (c[HARDGAME]<3)
+ if (dam>44)
+ {
+ lprcat(" The statue crumbles");
+ *p=OBOOK; iarg[x][y]=level;
+ goto god;
+ }
+ goto god2;
+
+ case OTHRONE: cursors(); lprc('\n'); lprintf(str,"throne");
+ if (dam>39)
+ {
+ mitem[x][y]=GNOMEKING; hitp[x][y]=monster[GNOMEKING].hitpoints;
+ *p = OTHRONE2;
+ goto god;
+ }
+ goto god2;
+
+ case OMIRROR: dx *= -1; dy *= -1; break;
+ };
+ dam -= 3 + (c[HARDGAME]>>1);
+ }
+ }
+
+/*
+ * ifblind(x,y) Routine to put "monster" or the monster name into lastmosnt
+ * int x,y;
+ *
+ * Subroutine to copy the word "monster" into lastmonst if the player is blind
+ * Enter with the coordinates (x,y) of the monster
+ * Returns no value.
+ */
+ifblind(x,y)
+ int x,y;
+ {
+ char *p;
+ vxy(&x,&y); /* verify correct x,y coordinates */
+ if (c[BLINDCOUNT]) { lastnum=279; p="monster"; }
+ else { lastnum=mitem[x][y]; p=monster[lastnum].name; }
+ strcpy(lastmonst,p);
+ }
+
+/*
+ * tdirect(spnum) Routine to teleport away a monster
+ * int spnum;
+ *
+ * Routine to ask for a direction to a spell and then teleport away monster
+ * Enter with the spell number that wants to teleport away
+ * Returns no value.
+ */
+tdirect(spnum)
+ int spnum;
+ {
+ int x,y;
+ register int m;
+ if (spnum<0 || spnum>=SPNUM) return; /* bad args */
+ if (isconfuse()) return;
+ dirsub(&x,&y);
+ if ((m=mitem[x][y])==0)
+ { lprcat(" There wasn't anything there!"); return; }
+ ifblind(x,y);
+ if (nospell(spnum,m)) { lasthx=x; lasthy=y; return; }
+ fillmonst(m); mitem[x][y]=know[x][y]=0;
+ }
+
+/*
+ * omnidirect(sp,dam,str) Routine to damage all monsters 1 square from player
+ * int sp,dam;
+ * char *str;
+ *
+ * Routine to cast a spell and then hit the monster in all directions
+ * Enter with the spell number in sp, the damage done to wach square in dam,
+ * and the lprintf string to identify the spell in str.
+ * Returns no value.
+ */
+omnidirect(spnum,dam,str)
+ int spnum,dam;
+ char *str;
+ {
+ register int x,y,m;
+ if (spnum<0 || spnum>=SPNUM || str==0) return; /* bad args */
+ for (x=playerx-1; x<playerx+2; x++)
+ for (y=playery-1; y<playery+2; y++)
+ {
+ if (m=mitem[x][y])
+ if (nospell(spnum,m) == 0)
+ {
+ ifblind(x,y);
+ cursors(); lprc('\n'); lprintf(str,lastmonst);
+ hitm(x,y,dam); nap(800);
+ }
+ else { lasthx=x; lasthy=y; }
+ }
+ }
+
+/*
+ * static dirsub(x,y) Routine to ask for direction, then modify x,y for it
+ * int *x,*y;
+ *
+ * Function to ask for a direction and modify an x,y for that direction
+ * Enter with the origination coordinates in (x,y).
+ * Returns index into diroffx[] (0-8).
+ */
+static int
+dirsub(x,y)
+ int *x,*y;
+ {
+ register int i;
+ lprcat("\nIn What Direction? ");
+ for (i=0; ; )
+ switch(getchar())
+ {
+ case 'b': i++;
+ case 'n': i++;
+ case 'y': i++;
+ case 'u': i++;
+ case 'h': i++;
+ case 'k': i++;
+ case 'l': i++;
+ case 'j': i++; goto out;
+ };
+out:
+ *x = playerx+diroffx[i]; *y = playery+diroffy[i];
+ vxy(x,y); return(i);
+ }
+
+/*
+ * vxy(x,y) Routine to verify/fix coordinates for being within bounds
+ * int *x,*y;
+ *
+ * Function to verify x & y are within the bounds for a level
+ * If *x or *y is not within the absolute bounds for a level, fix them so that
+ * they are on the level.
+ * Returns TRUE if it was out of bounds, and the *x & *y in the calling
+ * routine are affected.
+ */
+vxy(x,y)
+ int *x,*y;
+ {
+ int flag=0;
+ if (*x<0) { *x=0; flag++; }
+ if (*y<0) { *y=0; flag++; }
+ if (*x>=MAXX) { *x=MAXX-1; flag++; }
+ if (*y>=MAXY) { *y=MAXY-1; flag++; }
+ return(flag);
+ }
+
+/*
+ * dirpoly(spnum) Routine to ask for a direction and polymorph a monst
+ * int spnum;
+ *
+ * Subroutine to polymorph a monster and ask for the direction its in
+ * Enter with the spell number in spmun.
+ * Returns no value.
+ */
+dirpoly(spnum)
+ int spnum;
+ {
+ int x,y,m;
+ if (spnum<0 || spnum>=SPNUM) return; /* bad args */
+ if (isconfuse()) return; /* if he is confused, he can't aim his magic */
+ dirsub(&x,&y);
+ if (mitem[x][y]==0)
+ { lprcat(" There wasn't anything there!"); return; }
+ ifblind(x,y);
+ if (nospell(spnum,mitem[x][y])) { lasthx=x; lasthy=y; return; }
+ while ( monster[m = mitem[x][y] = rnd(MAXMONST+7)].genocided );
+ hitp[x][y] = monster[m].hitpoints;
+ show1cell(x,y); /* show the new monster */
+ }
+
+/*
+ * hitmonster(x,y) Function to hit a monster at the designated coordinates
+ * int x,y;
+ *
+ * This routine is used for a bash & slash type attack on a monster
+ * Enter with the coordinates of the monster in (x,y).
+ * Returns no value.
+ */
+hitmonster(x,y)
+ int x,y;
+ {
+ register int tmp,monst,damag,flag;
+ if (c[TIMESTOP]) return; /* not if time stopped */
+ vxy(&x,&y); /* verify coordinates are within range */
+ if ((monst = mitem[x][y]) == 0) return;
+ hit3flag=1; ifblind(x,y);
+ tmp = monster[monst].armorclass + c[LEVEL] + c[DEXTERITY] + c[WCLASS]/4 - 12;
+ cursors();
+ if ((rnd(20) < tmp-c[HARDGAME]) || (rnd(71) < 5)) /* need at least random chance to hit */
+ {
+ lprcat("\nYou hit"); flag=1;
+ damag = fullhit(1);
+ if (damag<9999) damag=rnd(damag)+1;
+ }
+ else
+ {
+ lprcat("\nYou missed"); flag=0;
+ }
+ lprcat(" the "); lprcat(lastmonst);
+ if (flag) /* if the monster was hit */
+ if ((monst==RUSTMONSTER) || (monst==DISENCHANTRESS) || (monst==CUBE))
+ if (c[WIELD]>0)
+ if (ivenarg[c[WIELD]] > -10)
+ {
+ lprintf("\nYour weapon is dulled by the %s",lastmonst); beep();
+ --ivenarg[c[WIELD]];
+ }
+ if (flag) hitm(x,y,damag);
+ if (monst == VAMPIRE) if (hitp[x][y]<25) { mitem[x][y]=BAT; know[x][y]=0; }
+ }
+
+/*
+ * hitm(x,y,amt) Function to just hit a monster at a given coordinates
+ * int x,y,amt;
+ *
+ * Returns the number of hitpoints the monster absorbed
+ * This routine is used to specifically damage a monster at a location (x,y)
+ * Called by hitmonster(x,y)
+ */
+hitm(x,y,amt)
+ int x,y;
+ register amt;
+ {
+ register int monst;
+ int hpoints,amt2;
+ vxy(&x,&y); /* verify coordinates are within range */
+ amt2 = amt; /* save initial damage so we can return it */
+ monst = mitem[x][y];
+ if (c[HALFDAM]) amt >>= 1; /* if half damage curse adjust damage points */
+ if (amt<=0) amt2 = amt = 1;
+ lasthx=x; lasthy=y;
+ stealth[x][y]=1; /* make sure hitting monst breaks stealth condition */
+ c[HOLDMONST]=0; /* hit a monster breaks hold monster spell */
+ switch(monst) /* if a dragon and orb(s) of dragon slaying */
+ {
+ case WHITEDRAGON: case REDDRAGON: case GREENDRAGON:
+ case BRONZEDRAGON: case PLATINUMDRAGON: case SILVERDRAGON:
+ amt *= 1+(c[SLAYING]<<1); break;
+ }
+/* invincible monster fix is here */
+ if (hitp[x][y] > monster[monst].hitpoints)
+ hitp[x][y] = monster[monst].hitpoints;
+ if ((hpoints = hitp[x][y]) <= amt)
+ {
+#ifdef EXTRA
+ c[MONSTKILLED]++;
+#endif
+ lprintf("\nThe %s died!",lastmonst);
+ raiseexperience((long)monster[monst].experience);
+ amt = monster[monst].gold; if (amt>0) dropgold(rnd(amt)+amt);
+ dropsomething(monst); disappear(x,y); bottomline();
+ return(hpoints);
+ }
+ hitp[x][y] = hpoints-amt; return(amt2);
+ }
+
+/*
+ * hitplayer(x,y) Function for the monster to hit the player from (x,y)
+ * int x,y;
+ *
+ * Function for the monster to hit the player with monster at location x,y
+ * Returns nothing of value.
+ */
+hitplayer(x,y)
+ int x,y;
+ {
+ register int dam,tmp,mster,bias;
+ vxy(&x,&y); /* verify coordinates are within range */
+ lastnum = mster = mitem[x][y];
+/* spirit naga's and poltergeist's do nothing if scarab of negate spirit */
+ if (c[NEGATESPIRIT] || c[SPIRITPRO]) if ((mster ==POLTERGEIST) || (mster ==SPIRITNAGA)) return;
+/* if undead and cube of undead control */
+ if (c[CUBEofUNDEAD] || c[UNDEADPRO]) if ((mster ==VAMPIRE) || (mster ==WRAITH) || (mster ==ZOMBIE)) return;
+ if ((know[x][y]&1) == 0)
+ {
+ know[x][y]=1; show1cell(x,y);
+ }
+ bias = (c[HARDGAME]) + 1;
+ hitflag = hit2flag = hit3flag = 1;
+ yrepcount=0;
+ cursors(); ifblind(x,y);
+ if (c[INVISIBILITY]) if (rnd(33)<20)
+ {
+ lprintf("\nThe %s misses wildly",lastmonst); return;
+ }
+ if (c[CHARMCOUNT]) if (rnd(30)+5*monster[mster].level-c[CHARISMA]<30)
+ {
+ lprintf("\nThe %s is awestruck at your magnificence!",lastmonst);
+ return;
+ }
+ if (mster==BAT) dam=1;
+ else
+ {
+ dam = monster[mster].damage;
+ dam += rnd((int)((dam<1)?1:dam)) + monster[mster].level;
+ }
+ tmp = 0;
+ if (monster[mster].attack>0)
+ if (((dam + bias + 8) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
+ { if (spattack(monster[mster].attack,x,y)) { flushall(); return; }
+ tmp = 1; bias -= 2; cursors(); }
+ if (((dam + bias) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
+ {
+ lprintf("\n The %s hit you ",lastmonst); tmp = 1;
+ if ((dam -= c[AC]) < 0) dam=0;
+ if (dam > 0) { losehp(dam); bottomhp(); flushall(); }
+ }
+ if (tmp == 0) lprintf("\n The %s missed ",lastmonst);
+ }
+
+/*
+ * dropsomething(monst) Function to create an object when a monster dies
+ * int monst;
+ *
+ * Function to create an object near the player when certain monsters are killed
+ * Enter with the monster number
+ * Returns nothing of value.
+ */
+dropsomething(monst)
+ int monst;
+ {
+ switch(monst)
+ {
+ case ORC: case NYMPH: case ELF: case TROGLODYTE:
+ case TROLL: case ROTHE: case VIOLETFUNGI:
+ case PLATINUMDRAGON: case GNOMEKING: case REDDRAGON:
+ something(level); return;
+
+ case LEPRECHAUN: if (rnd(101)>=75) creategem();
+ if (rnd(5)==1) dropsomething(LEPRECHAUN); return;
+ }
+ }
+
+/*
+ * dropgold(amount) Function to drop some gold around player
+ * int amount;
+ *
+ * Enter with the number of gold pieces to drop
+ * Returns nothing of value.
+ */
+dropgold(amount)
+ register int amount;
+ {
+ if (amount > 250) createitem(OMAXGOLD,amount/100); else createitem(OGOLDPILE,amount);
+ }
+
+/*
+ * something(level) Function to create a random item around player
+ * int level;
+ *
+ * Function to create an item from a designed probability around player
+ * Enter with the cave level on which something is to be dropped
+ * Returns nothing of value.
+ */
+something(level)
+ int level;
+ {
+ register int j;
+ int i;
+ if (level<0 || level>MAXLEVEL+MAXVLEVEL) return; /* correct level? */
+ if (rnd(101)<8) something(level); /* possibly more than one item */
+ j = newobject(level,&i); createitem(j,i);
+ }
+
+/*
+ * newobject(lev,i) Routine to return a randomly selected new object
+ * int lev,*i;
+ *
+ * Routine to return a randomly selected object to be created
+ * Returns the object number created, and sets *i for its argument
+ * Enter with the cave level and a pointer to the items arg
+ */
+static char nobjtab[] = { 0, OSCROLL, OSCROLL, OSCROLL, OSCROLL, OPOTION,
+ OPOTION, OPOTION, OPOTION, OGOLDPILE, OGOLDPILE, OGOLDPILE, OGOLDPILE,
+ OBOOK, OBOOK, OBOOK, OBOOK, ODAGGER, ODAGGER, ODAGGER, OLEATHER, OLEATHER,
+ OLEATHER, OREGENRING, OPROTRING, OENERGYRING, ODEXRING, OSTRRING, OSPEAR,
+ OBELT, ORING, OSTUDLEATHER, OSHIELD, OFLAIL, OCHAIN, O2SWORD, OPLATE,
+ OLONGSWORD };
+
+newobject(lev,i)
+ register int lev,*i;
+ {
+ register int tmp=32,j;
+ if (level<0 || level>MAXLEVEL+MAXVLEVEL) return(0); /* correct level? */
+ if (lev>6) tmp=37; else if (lev>4) tmp=35;
+ j = nobjtab[tmp=rnd(tmp)]; /* the object type */
+ switch(tmp)
+ {
+ case 1: case 2: case 3: case 4: *i=newscroll(); break;
+ case 5: case 6: case 7: case 8: *i=newpotion(); break;
+ case 9: case 10: case 11: case 12: *i=rnd((lev+1)*10)+lev*10+10; break;
+ case 13: case 14: case 15: case 16: *i=lev; break;
+ case 17: case 18: case 19: if (!(*i=newdagger())) return(0); break;
+ case 20: case 21: case 22: if (!(*i=newleather())) return(0); break;
+ case 23: case 32: case 35: *i=rund(lev/3+1); break;
+ case 24: case 26: *i=rnd(lev/4+1); break;
+ case 25: *i=rund(lev/4+1); break;
+ case 27: *i=rnd(lev/2+1); break;
+ case 30: case 33: *i=rund(lev/2+1); break;
+ case 28: *i=rund(lev/3+1); if (*i==0) return(0); break;
+ case 29: case 31: *i=rund(lev/2+1); if (*i==0) return(0); break;
+ case 34: *i=newchain(); break;
+ case 36: *i=newplate(); break;
+ case 37: *i=newsword(); break;
+ }
+ return(j);
+ }
+
+/*
+ * spattack(atckno,xx,yy) Function to process special attacks from monsters
+ * int atckno,xx,yy;
+ *
+ * Enter with the special attack number, and the coordinates (xx,yy)
+ * of the monster that is special attacking
+ * Returns 1 if must do a show1cell(xx,yy) upon return, 0 otherwise
+ *
+ * atckno monster effect
+ * ---------------------------------------------------
+ * 0 none
+ * 1 rust monster eat armor
+ * 2 hell hound breathe light fire
+ * 3 dragon breathe fire
+ * 4 giant centipede weakening sing
+ * 5 white dragon cold breath
+ * 6 wraith drain level
+ * 7 waterlord water gusher
+ * 8 leprechaun steal gold
+ * 9 disenchantress disenchant weapon or armor
+ * 10 ice lizard hits with barbed tail
+ * 11 umber hulk confusion
+ * 12 spirit naga cast spells taken from special attacks
+ * 13 platinum dragon psionics
+ * 14 nymph steal objects
+ * 15 bugbear bite
+ * 16 osequip bite
+ *
+ * char rustarm[ARMORTYPES][2];
+ * special array for maximum rust damage to armor from rustmonster
+ * format is: { armor type , minimum attribute
+ */
+#define ARMORTYPES 6
+static char rustarm[ARMORTYPES][2] = { OSTUDLEATHER,-2, ORING,-4, OCHAIN,-5,
+ OSPLINT,-6, OPLATE,-8, OPLATEARMOR,-9 };
+static char spsel[] = { 1, 2, 3, 5, 6, 8, 9, 11, 13, 14 };
+spattack(x,xx,yy)
+ int x,xx,yy;
+ {
+ register int i,j=0,k,m;
+ register char *p=0;
+ if (c[CANCELLATION]) return(0);
+ vxy(&xx,&yy); /* verify x & y coordinates */
+ switch(x)
+ {
+ case 1: /* rust your armor, j=1 when rusting has occurred */
+ m = k = c[WEAR];
+ if ((i=c[SHIELD]) != -1)
+ if (--ivenarg[i] < -1) ivenarg[i]= -1; else j=1;
+ if ((j==0) && (k != -1))
+ {
+ m = iven[k];
+ for (i=0; i<ARMORTYPES; i++)
+ if (m == rustarm[i][0]) /* find his armor in table */
+ {
+ if (--ivenarg[k]< rustarm[i][1])
+ ivenarg[k]= rustarm[i][1]; else j=1;
+ break;
+ }
+ }
+ if (j==0) /* if rusting did not occur */
+ switch(m)
+ {
+ case OLEATHER: p = "\nThe %s hit you -- Your lucky you have leather on";
+ break;
+ case OSSPLATE: p = "\nThe %s hit you -- Your fortunate to have stainless steel armor!";
+ break;
+ }
+ else { beep(); p = "\nThe %s hit you -- your armor feels weaker"; }
+ break;
+
+ case 2: i = rnd(15)+8-c[AC];
+ spout: p="\nThe %s breathes fire at you!";
+ if (c[FIRERESISTANCE])
+ p="\nThe %s's flame doesn't phase you!";
+ else
+ spout2: if (p) { lprintf(p,lastmonst); beep(); }
+ checkloss(i);
+ return(0);
+
+ case 3: i = rnd(20)+25-c[AC]; goto spout;
+
+ case 4: if (c[STRENGTH]>3)
+ {
+ p="\nThe %s stung you! You feel weaker"; beep();
+ --c[STRENGTH];
+ }
+ else p="\nThe %s stung you!";
+ break;
+
+ case 5: p="\nThe %s blasts you with his cold breath";
+ i = rnd(15)+18-c[AC]; goto spout2;
+
+ case 6: lprintf("\nThe %s drains you of your life energy!",lastmonst);
+ loselevel(); beep(); return(0);
+
+ case 7: p="\nThe %s got you with a gusher!";
+ i = rnd(15)+25-c[AC]; goto spout2;
+
+ case 8: if (c[NOTHEFT]) return(0); /* he has a device of no theft */
+ if (c[GOLD])
+ {
+ p="\nThe %s hit you -- Your purse feels lighter";
+ if (c[GOLD]>32767) c[GOLD]>>=1;
+ else c[GOLD] -= rnd((int)(1+(c[GOLD]>>1)));
+ if (c[GOLD] < 0) c[GOLD]=0;
+ }
+ else p="\nThe %s couldn't find any gold to steal";
+ lprintf(p,lastmonst); disappear(xx,yy); beep();
+ bottomgold(); return(1);
+
+ case 9: for(j=50; ; ) /* disenchant */
+ {
+ i=rund(26); m=iven[i]; /* randomly select item */
+ if (m>0 && ivenarg[i]>0 && m!=OSCROLL && m!=OPOTION)
+ {
+ if ((ivenarg[i] -= 3)<0) ivenarg[i]=0;
+ lprintf("\nThe %s hits you -- you feel a sense of loss",lastmonst);
+ srcount=0; beep(); show3(i); bottomline(); return(0);
+ }
+ if (--j<=0)
+ {
+ p="\nThe %s nearly misses"; break;
+ }
+ break;
+ }
+ break;
+
+ case 10: p="\nThe %s hit you with his barbed tail";
+ i = rnd(25)-c[AC]; goto spout2;
+
+ case 11: p="\nThe %s has confused you"; beep();
+ c[CONFUSE]+= 10+rnd(10); break;
+
+ case 12: /* performs any number of other special attacks */
+ return(spattack(spsel[rund(10)],xx,yy));
+
+ case 13: p="\nThe %s flattens you with his psionics!";
+ i = rnd(15)+30-c[AC]; goto spout2;
+
+ case 14: if (c[NOTHEFT]) return(0); /* he has device of no theft */
+ if (emptyhanded()==1)
+ {
+ p="\nThe %s couldn't find anything to steal";
+ break;
+ }
+ lprintf("\nThe %s picks your pocket and takes:",lastmonst);
+ beep();
+ if (stealsomething()==0) lprcat(" nothing"); disappear(xx,yy);
+ bottomline(); return(1);
+
+ case 15: i= rnd(10)+ 5-c[AC];
+ spout3: p="\nThe %s bit you!";
+ goto spout2;
+
+ case 16: i= rnd(15)+10-c[AC]; goto spout3;
+ };
+ if (p) { lprintf(p,lastmonst); bottomline(); }
+ return(0);
+ }
+
+/*
+ * checkloss(x) Routine to subtract hp from user and flag bottomline display
+ * int x;
+ *
+ * Routine to subtract hitpoints from the user and flag the bottomline display
+ * Enter with the number of hit points to lose
+ * Note: if x > c[HP] this routine could kill the player!
+ */
+checkloss(x)
+ int x;
+ {
+ if (x>0) { losehp(x); bottomhp(); }
+ }
+
+/*
+ * annihilate() Routine to annihilate all monsters around player (playerx,playery)
+ *
+ * Gives player experience, but no dropped objects
+ * Returns the experience gained from all monsters killed
+ */
+annihilate()
+ {
+ int i,j;
+ register long k;
+ register char *p;
+ for (k=0, i=playerx-1; i<=playerx+1; i++)
+ for (j=playery-1; j<=playery+1; j++)
+ if (!vxy(&i,&j)) /* if not out of bounds */
+ if (*(p= &mitem[i][j])) /* if a monster there */
+ if (*p<DEMONLORD+2)
+ {
+ k += monster[*p].experience; *p=know[i][j]=0;
+ }
+ else
+ {
+ lprintf("\nThe %s barely escapes being annihilated!",monster[*p].name);
+ hitp[i][j] = (hitp[i][j]>>1) + 1; /* lose half hit points*/
+ }
+ if (k>0)
+ {
+ lprcat("\nYou hear loud screams of agony!"); raiseexperience((long)k);
+ }
+ return(k);
+ }
+
+/*
+ * newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation
+ * int x,y,dir,lifetime;
+ *
+ * Enter with the coordinates of the sphere in x,y
+ * the direction (0-8 diroffx format) in dir, and the lifespan of the
+ * sphere in lifetime (in turns)
+ * Returns the number of spheres currently in existence
+ */
+newsphere(x,y,dir,life)
+ int x,y,dir,life;
+ {
+ int m;
+ struct sphere *sp;
+ if (((sp=(struct sphere *)malloc(sizeof(struct sphere)))) == 0)
+ return(c[SPHCAST]); /* can't malloc, therefore failure */
+ if (dir>=9) dir=0; /* no movement if direction not found */
+ if (level==0) vxy(&x,&y); /* don't go out of bounds */
+ else
+ {
+ if (x<1) x=1; if (x>=MAXX-1) x=MAXX-2;
+ if (y<1) y=1; if (y>=MAXY-1) y=MAXY-2;
+ }
+ if ((m=mitem[x][y]) >= DEMONLORD+4) /* demons dispel spheres */
+ {
+ know[x][y]=1; show1cell(x,y); /* show the demon (ha ha) */
+ cursors(); lprintf("\nThe %s dispels the sphere!",monster[m].name);
+ beep(); rmsphere(x,y); /* remove any spheres that are here */
+ return(c[SPHCAST]);
+ }
+ if (m==DISENCHANTRESS) /* disenchantress cancels spheres */
+ {
+ cursors(); lprintf("\nThe %s causes cancellation of the sphere!",monster[m].name); beep();
+boom: sphboom(x,y); /* blow up stuff around sphere */
+ rmsphere(x,y); /* remove any spheres that are here */
+ return(c[SPHCAST]);
+ }
+ if (c[CANCELLATION]) /* cancellation cancels spheres */
+ {
+ cursors(); lprcat("\nAs the cancellation takes effect, you hear a great earth shaking blast!"); beep();
+ goto boom;
+ }
+ if (item[x][y]==OANNIHILATION) /* collision of spheres detonates spheres */
+ {
+ cursors(); lprcat("\nTwo spheres of annihilation collide! You hear a great earth shaking blast!"); beep();
+ rmsphere(x,y);
+ goto boom;
+ }
+ if (playerx==x && playery==y) /* collision of sphere and player! */
+ {
+ cursors();
+ lprcat("\nYou have been enveloped by the zone of nothingness!\n");
+ beep(); rmsphere(x,y); /* remove any spheres that are here */
+ nap(4000); died(258);
+ }
+ item[x][y]=OANNIHILATION; mitem[x][y]=0; know[x][y]=1;
+ show1cell(x,y); /* show the new sphere */
+ sp->x=x; sp->y=y; sp->lev=level; sp->dir=dir; sp->lifetime=life; sp->p=0;
+ if (spheres==0) spheres=sp; /* if first node in the sphere list */
+ else /* add sphere to beginning of linked list */
+ {
+ sp->p = spheres; spheres = sp;
+ }
+ return(++c[SPHCAST]); /* one more sphere in the world */
+ }
+
+/*
+ * rmsphere(x,y) Function to delete a sphere of annihilation from list
+ * int x,y;
+ *
+ * Enter with the coordinates of the sphere (on current level)
+ * Returns the number of spheres currently in existence
+ */
+rmsphere(x,y)
+ int x,y;
+ {
+ register struct sphere *sp,*sp2=0;
+ for (sp=spheres; sp; sp2=sp,sp=sp->p)
+ if (level==sp->lev) /* is sphere on this level? */
+ if ((x==sp->x) && (y==sp->y)) /* locate sphere at this location */
+ {
+ item[x][y]=mitem[x][y]=0; know[x][y]=1;
+ show1cell(x,y); /* show the now missing sphere */
+ --c[SPHCAST];
+ if (sp==spheres) { sp2=sp; spheres=sp->p; free((char*)sp2); }
+ else
+ { sp2->p = sp->p; free((char*)sp); }
+ break;
+ }
+ return(c[SPHCAST]); /* return number of spheres in the world */
+ }
+
+/*
+ * sphboom(x,y) Function to perform the effects of a sphere detonation
+ * int x,y;
+ *
+ * Enter with the coordinates of the blast, Returns no value
+ */
+sphboom(x,y)
+ int x,y;
+ {
+ register int i,j;
+ if (c[HOLDMONST]) c[HOLDMONST]=1;
+ if (c[CANCELLATION]) c[CANCELLATION]=1;
+ for (j=max(1,x-2); j<min(x+3,MAXX-1); j++)
+ for (i=max(1,y-2); i<min(y+3,MAXY-1); i++)
+ {
+ item[j][i]=mitem[j][i]=0;
+ show1cell(j,i);
+ if (playerx==j && playery==i)
+ {
+ cursors(); beep();
+ lprcat("\nYou were too close to the sphere!");
+ nap(3000);
+ died(283); /* player killed in explosion */
+ }
+ }
+ }
+
+/*
+ * genmonst() Function to ask for monster and genocide from game
+ *
+ * This is done by setting a flag in the monster[] structure
+ */
+genmonst()
+ {
+ register int i,j;
+ cursors(); lprcat("\nGenocide what monster? ");
+ for (i=0; (!isalpha(i)) && (i!=' '); i=getchar());
+ lprc(i);
+ for (j=0; j<MAXMONST; j++) /* search for the monster type */
+ if (monstnamelist[j]==i) /* have we found it? */
+ {
+ monster[j].genocided=1; /* genocided from game */
+ lprintf(" There will be no more %s's",monster[j].name);
+ /* now wipe out monsters on this level */
+ newcavelevel(level); draws(0,MAXX,0,MAXY); bot_linex();
+ return;
+ }
+ lprcat(" You sense failure!");
+ }
+
diff --git a/larn/moreobj.c b/larn/moreobj.c
new file mode 100644
index 00000000..f834b1a1
--- /dev/null
+++ b/larn/moreobj.c
@@ -0,0 +1,372 @@
+/* moreobj.c Larn is copyrighted 1986 by Noah Morgan.
+ *
+ * Routines in this file:
+ *
+ * oaltar()
+ * othrone()
+ * ochest()
+ * ofountain()
+ */
+#include "header.h"
+
+static void ohear();
+
+/*
+ * ******
+ * OALTAR
+ * ******
+ *
+ * subroutine to process an altar object
+ */
+oaltar()
+ {
+ unsigned long k;
+
+ lprcat("\nDo you (p) pray (d) desecrate"); iopts();
+ while (1)
+ {
+ while (1) switch(getchar())
+ {
+ case 'p': lprcat(" pray\nDo you (m) give money or (j) just pray? ");
+ while (1) switch(getchar())
+ {
+ case 'j': if (rnd(100)<75)
+ lprcat("\nnothing happens");
+ else if (rnd(13)<4) ohear();
+ else if (rnd(43) == 10)
+ {
+ if (c[WEAR]) lprcat("\nYou feel your armor vibrate for a moment");
+ enchantarmor(); return;
+ }
+ else if (rnd(43) == 10)
+ {
+ if (c[WIELD]) lprcat("\nYou feel your weapon vibrate for a moment");
+ enchweapon(); return;
+ }
+ else createmonster(makemonst(level+1));
+ return;
+
+ case 'm': lprcat("\n\n"); cursor(1,24); cltoeoln();
+ cursor(1,23); cltoeoln();
+ lprcat("how much do you donate? ");
+ k = readnum((long)c[GOLD]);
+ if (c[GOLD]<k)
+ {
+ lprcat("\nYou don't have that much!");
+ return;
+ }
+ c[GOLD] -= k;
+ if (k < c[GOLD]/10 || k<rnd(50))
+ { createmonster(makemonst(level+1)); c[AGGRAVATE] += 200; }
+ else if (rnd(101) > 50) { ohear(); return; }
+ else if (rnd(43) == 5)
+ {
+ if (c[WEAR]) lprcat("\nYou feel your armor vibrate for a moment");
+ enchantarmor(); return;
+ }
+ else if (rnd(43) == 8)
+ {
+ if (c[WIELD]) lprcat("\nYou feel your weapon vibrate for a moment");
+ enchweapon(); return;
+ }
+ else lprcat("\nThank You.");
+ bottomline(); return;
+
+ case '\33': return;
+ };
+
+ case 'd': lprcat(" desecrate");
+ if (rnd(100)<60)
+ { createmonster(makemonst(level+2)+8); c[AGGRAVATE] += 2500; }
+ else
+ if (rnd(101)<30)
+ {
+ lprcat("\nThe altar crumbles into a pile of dust before your eyes");
+ forget(); /* remember to destroy the altar */
+ }
+ else
+ lprcat("\nnothing happens");
+ return;
+
+ case 'i':
+ case '\33': ignore();
+ if (rnd(100)<30) { createmonster(makemonst(level+1)); c[AGGRAVATE] += rnd(450); }
+ else lprcat("\nnothing happens");
+ return;
+ };
+ }
+ }
+
+/*
+ function to cast a +3 protection on the player
+ */
+static void
+ohear()
+ {
+ lprcat("\nYou have been heard!");
+ if (c[ALTPRO]==0) c[MOREDEFENSES]+=3;
+ c[ALTPRO] += 500; /* protection field */
+ bottomline();
+ }
+
+/*
+ *******
+ OTHRONE
+ *******
+
+ subroutine to process a throne object
+ */
+othrone(arg)
+ int arg;
+ {
+ register int i,k;
+
+ lprcat("\nDo you (p) pry off jewels, (s) sit down"); iopts();
+ while (1)
+ {
+ while (1) switch(getchar())
+ {
+ case 'p': lprcat(" pry off"); k=rnd(101);
+ if (k<25)
+ {
+ for (i=0; i<rnd(4); i++) creategem(); /* gems pop off the throne */
+ item[playerx][playery]=ODEADTHRONE;
+ know[playerx][playery]=0;
+ }
+ else if (k<40 && arg==0)
+ {
+ createmonster(GNOMEKING);
+ item[playerx][playery]=OTHRONE2;
+ know[playerx][playery]=0;
+ }
+ else lprcat("\nnothing happens");
+ return;
+
+ case 's': lprcat(" sit down"); k=rnd(101);
+ if (k<30 && arg==0)
+ {
+ createmonster(GNOMEKING);
+ item[playerx][playery]=OTHRONE2;
+ know[playerx][playery]=0;
+ }
+ else if (k<35) { lprcat("\nZaaaappp! You've been teleported!\n"); beep(); oteleport(0); }
+ else lprcat("\nnothing happens");
+ return;
+
+ case 'i':
+ case '\33': ignore(); return;
+ };
+ }
+ }
+
+odeadthrone()
+ {
+ register int k;
+
+ lprcat("\nDo you (s) sit down"); iopts();
+ while (1)
+ {
+ while (1) switch(getchar())
+ {
+ case 's': lprcat(" sit down"); k=rnd(101);
+ if (k<35) { lprcat("\nZaaaappp! You've been teleported!\n"); beep(); oteleport(0); }
+ else lprcat("\nnothing happens");
+ return;
+
+ case 'i':
+ case '\33': ignore(); return;
+ };
+ }
+ }
+
+/*
+ ******
+ OCHEST
+ ******
+
+ subroutine to process a throne object
+ */
+ochest()
+ {
+ register int i,k;
+ lprcat("\nDo you (t) take it, (o) try to open it"); iopts();
+ while (1)
+ {
+ while (1) switch(getchar())
+ {
+ case 'o': lprcat(" open it"); k=rnd(101);
+ if (k<40)
+ {
+ lprcat("\nThe chest explodes as you open it"); beep();
+ i = rnd(10); lastnum=281; /* in case he dies */
+ lprintf("\nYou suffer %d hit points damage!",(long)i);
+ checkloss(i);
+ switch(rnd(10)) /* see if he gets a curse */
+ {
+ case 1: c[ITCHING]+= rnd(1000)+100;
+ lprcat("\nYou feel an irritation spread over your skin!");
+ beep();
+ break;
+
+ case 2: c[CLUMSINESS]+= rnd(1600)+200;
+ lprcat("\nYou begin to lose hand to eye coordination!");
+ beep();
+ break;
+
+ case 3: c[HALFDAM]+= rnd(1600)+200;
+ beep();
+ lprcat("\nA sickness engulfs you!"); break;
+ };
+ item[playerx][playery]=know[playerx][playery]=0;
+ if (rnd(100)<69) creategem(); /* gems from the chest */
+ dropgold(rnd(110*iarg[playerx][playery]+200));
+ for (i=0; i<rnd(4); i++) something(iarg[playerx][playery]+2);
+ }
+ else lprcat("\nnothing happens");
+ return;
+
+ case 't': lprcat(" take");
+ if (take(OCHEST,iarg[playerx][playery])==0)
+ item[playerx][playery]=know[playerx][playery]=0;
+ return;
+
+ case 'i':
+ case '\33': ignore(); return;
+ };
+ }
+ }
+
+/*
+ *********
+ OFOUNTAIN
+ *********
+ */
+
+ofountain()
+ {
+ register int x;
+ cursors();
+ lprcat("\nDo you (d) drink, (w) wash yourself"); iopts();
+ while (1) switch(getchar())
+ {
+ case 'd': lprcat("drink");
+ if (rnd(1501)<2)
+ {
+ lprcat("\nOops! You seem to have caught the dreadful sleep!");
+ beep(); lflush(); sleep(3); died(280); return;
+ }
+ x = rnd(100);
+ if (x<7)
+ {
+ c[HALFDAM] += 200+rnd(200);
+ lprcat("\nYou feel a sickness coming on");
+ }
+ else if (x<13) quaffpotion(23); /* see invisible */
+ else if (x < 45)
+ lprcat("\nnothing seems to have happened");
+ else if (rnd(3) != 2)
+ fntchange(1); /* change char levels upward */
+ else
+ fntchange(-1); /* change char levels downward */
+ if (rnd(12)<3)
+ {
+ lprcat("\nThe fountains bubbling slowly quiets");
+ item[playerx][playery]=ODEADFOUNTAIN; /* dead fountain */
+ know[playerx][playery]=0;
+ }
+ return;
+
+ case '\33':
+ case 'i': ignore(); return;
+
+ case 'w': lprcat("wash yourself");
+ if (rnd(100) < 11)
+ {
+ x=rnd((level<<2)+2);
+ lprintf("\nOh no! The water was foul! You suffer %d hit points!",(long)x);
+ lastnum=273; losehp(x); bottomline(); cursors();
+ }
+ else
+ if (rnd(100) < 29)
+ lprcat("\nYou got the dirt off!");
+ else
+ if (rnd(100) < 31)
+ lprcat("\nThis water seems to be hard water! The dirt didn't come off!");
+ else
+ if (rnd(100) < 34)
+ createmonster(WATERLORD); /* make water lord */
+ else
+ lprcat("\nnothing seems to have happened");
+ return;
+ }
+ }
+
+/*
+ ***
+ FCH
+ ***
+
+ subroutine to process an up/down of a character attribute for ofountain
+ */
+static void
+fch(how,x)
+ int how;
+ long *x;
+ {
+ if (how < 0) { lprcat(" went down by one!"); --(*x); }
+ else { lprcat(" went up by one!"); (*x)++; }
+ bottomline();
+ }
+
+/*
+ a subroutine to raise or lower character levels
+ if x > 0 they are raised if x < 0 they are lowered
+ */
+fntchange(how)
+ int how;
+ {
+ register long j;
+ lprc('\n');
+ switch(rnd(9))
+ {
+ case 1: lprcat("Your strength"); fch(how,&c[0]); break;
+ case 2: lprcat("Your intelligence"); fch(how,&c[1]); break;
+ case 3: lprcat("Your wisdom"); fch(how,&c[2]); break;
+ case 4: lprcat("Your constitution"); fch(how,&c[3]); break;
+ case 5: lprcat("Your dexterity"); fch(how,&c[4]); break;
+ case 6: lprcat("Your charm"); fch(how,&c[5]); break;
+ case 7: j=rnd(level+1);
+ if (how < 0)
+ { lprintf("You lose %d hit point",(long)j); if (j>1) lprcat("s!"); else lprc('!'); losemhp((int)j); }
+ else
+ { lprintf("You gain %d hit point",(long)j); if (j>1) lprcat("s!"); else lprc('!'); raisemhp((int)j); }
+ bottomline(); break;
+
+ case 8: j=rnd(level+1);
+ if (how > 0)
+ {
+ lprintf("You just gained %d spell",(long)j); raisemspells((int)j);
+ if (j>1) lprcat("s!"); else lprc('!');
+ }
+ else
+ {
+ lprintf("You just lost %d spell",(long)j); losemspells((int)j);
+ if (j>1) lprcat("s!"); else lprc('!');
+ }
+ bottomline(); break;
+
+ case 9: j = 5*rnd((level+1)*(level+1));
+ if (how < 0)
+ {
+ lprintf("You just lost %d experience point",(long)j);
+ if (j>1) lprcat("s!"); else lprc('!'); loseexperience((long)j);
+ }
+ else
+ {
+ lprintf("You just gained %d experience point",(long)j);
+ if (j>1) lprcat("s!"); else lprc('!'); raiseexperience((long)j);
+ }
+ break;
+ }
+ cursors();
+ }
diff --git a/larn/movem.c b/larn/movem.c
new file mode 100644
index 00000000..7239a068
--- /dev/null
+++ b/larn/movem.c
@@ -0,0 +1,312 @@
+/*
+ * movem.c (move monster) Larn is copyrighted 1986 by Noah Morgan.
+ *
+ * Here are the functions in this file:
+ *
+ * movemonst() Routine to move the monsters toward the player
+ * movemt(x,y) Function to move a monster at (x,y) -- must determine where
+ * mmove(x,y,xd,yd) Function to actually perform the monster movement
+ * movsphere() Function to look for and move spheres of annihilation
+ */
+#include "header.h"
+
+/*
+ * movemonst() Routine to move the monsters toward the player
+ *
+ * This routine has the responsibility to determine which monsters are to
+ * move, and call movemt() to do the move.
+ * Returns no value.
+ */
+static short w1[9],w1x[9],w1y[9];
+static int tmp1,tmp2,tmp3,tmp4,distance;
+movemonst()
+ {
+ register int i,j;
+ if (c[TIMESTOP]) return; /* no action if time is stopped */
+ if (c[HASTESELF]) if ((c[HASTESELF]&1)==0) return;
+ if (spheres) movsphere(); /* move the spheres of annihilation if any */
+ if (c[HOLDMONST]) return; /* no action if monsters are held */
+
+ if (c[AGGRAVATE]) /* determine window of monsters to move */
+ {
+ tmp1=playery-5; tmp2=playery+6; tmp3=playerx-10; tmp4=playerx+11;
+ distance=40; /* depth of intelligent monster movement */
+ }
+ else
+ {
+ tmp1=playery-3; tmp2=playery+4; tmp3=playerx-5; tmp4=playerx+6;
+ distance=17; /* depth of intelligent monster movement */
+ }
+
+ if (level == 0) /* if on outside level monsters can move in perimeter */
+ {
+ if (tmp1 < 0) tmp1=0; if (tmp2 > MAXY) tmp2=MAXY;
+ if (tmp3 < 0) tmp3=0; if (tmp4 > MAXX) tmp4=MAXX;
+ }
+ else /* if in a dungeon monsters can't be on the perimeter (wall there) */
+ {
+ if (tmp1 < 1) tmp1=1; if (tmp2 > MAXY-1) tmp2=MAXY-1;
+ if (tmp3 < 1) tmp3=1; if (tmp4 > MAXX-1) tmp4=MAXX-1;
+ }
+
+ for (j=tmp1; j<tmp2; j++) /* now reset monster moved flags */
+ for (i=tmp3; i<tmp4; i++)
+ moved[i][j] = 0;
+ moved[lasthx][lasthy]=0;
+
+ if (c[AGGRAVATE] || !c[STEALTH]) /* who gets moved? split for efficiency */
+ {
+ for (j=tmp1; j<tmp2; j++) /* look thru all locations in window */
+ for (i=tmp3; i<tmp4; i++)
+ if (mitem[i][j]) /* if there is a monster to move */
+ if (moved[i][j]==0) /* if it has not already been moved */
+ movemt(i,j); /* go and move the monster */
+ }
+ else /* not aggravated and not stealth */
+ {
+ for (j=tmp1; j<tmp2; j++) /* look thru all locations in window */
+ for (i=tmp3; i<tmp4; i++)
+ if (mitem[i][j]) /* if there is a monster to move */
+ if (moved[i][j]==0) /* if it has not already been moved */
+ if (stealth[i][j]) /* if it is asleep due to stealth */
+ movemt(i,j); /* go and move the monster */
+ }
+
+ if (mitem[lasthx][lasthy]) /* now move monster last hit by player if not already moved */
+ {
+ if (moved[lasthx][lasthy]==0) /* if it has not already been moved */
+ {
+ movemt(lasthx,lasthy);
+ lasthx = w1x[0]; lasthy = w1y[0];
+ }
+ }
+ }
+
+/*
+ * movemt(x,y) Function to move a monster at (x,y) -- must determine where
+ * int x,y;
+ *
+ * This routine is responsible for determining where one monster at (x,y) will
+ * move to. Enter with the monsters coordinates in (x,y).
+ * Returns no value.
+ */
+static int tmpitem,xl,xh,yl,yh;
+movemt(i,j)
+ int i,j;
+ {
+ register int k,m,z,tmp,xtmp,ytmp,monst;
+ switch(monst=mitem[i][j]) /* for half speed monsters */
+ {
+ case TROGLODYTE: case HOBGOBLIN: case METAMORPH: case XVART:
+ case INVISIBLESTALKER: case ICELIZARD: if ((gtime & 1) == 1) return;
+ };
+
+ if (c[SCAREMONST]) /* choose destination randomly if scared */
+ {
+ if ((xl = i+rnd(3)-2) < 0) xl=0; if (xl >= MAXX) xl=MAXX-1;
+ if ((yl = j+rnd(3)-2) < 0) yl=0; if (yl >= MAXY) yl=MAXY-1;
+ if ((tmp=item[xl][yl]) != OWALL)
+ if (mitem[xl][yl] == 0)
+ if ((mitem[i][j] != VAMPIRE) || (tmpitem != OMIRROR))
+ if (tmp != OCLOSEDDOOR) mmove(i,j,xl,yl);
+ return;
+ }
+
+ if (monster[monst].intelligence > 10-c[HARDGAME]) /* if smart monster */
+/* intelligent movement here -- first setup screen array */
+ {
+ xl=tmp3-2; yl=tmp1-2; xh=tmp4+2; yh=tmp2+2;
+ vxy(&xl,&yl); vxy(&xh,&yh);
+ for (k=yl; k<yh; k++)
+ for (m=xl; m<xh; m++)
+ {
+ switch(item[m][k])
+ {
+ case OWALL: case OPIT: case OTRAPARROW: case ODARTRAP:
+ case OCLOSEDDOOR: case OTRAPDOOR: case OTELEPORTER:
+ smm: screen[m][k]=127; break;
+ case OMIRROR: if (mitem[m][k]==VAMPIRE) goto smm;
+ default: screen[m][k]= 0; break;
+ };
+ }
+ screen[playerx][playery]=1;
+
+/* now perform proximity ripple from playerx,playery to monster */
+ xl=tmp3-1; yl=tmp1-1; xh=tmp4+1; yh=tmp2+1;
+ vxy(&xl,&yl); vxy(&xh,&yh);
+ for (tmp=1; tmp<distance; tmp++) /* only up to 20 squares away */
+ for (k=yl; k<yh; k++)
+ for (m=xl; m<xh; m++)
+ if (screen[m][k]==tmp) /* if find proximity n advance it */
+ for (z=1; z<9; z++) /* go around in a circle */
+ {
+ if (screen[xtmp=m+diroffx[z]][ytmp=k+diroffy[z]]==0)
+ screen[xtmp][ytmp]=tmp+1;
+ if (xtmp==i && ytmp==j) goto out;
+ }
+
+out: if (tmp<distance) /* did find connectivity */
+ /* now select lowest value around playerx,playery */
+ for (z=1; z<9; z++) /* go around in a circle */
+ if (screen[xl=i+diroffx[z]][yl=j+diroffy[z]]==tmp)
+ if (!mitem[xl][yl]) { mmove(i,j,w1x[0]=xl,w1y[0]=yl); return; }
+ }
+
+ /* dumb monsters move here */
+ xl=i-1; yl=j-1; xh=i+2; yh=j+2;
+ if (i<playerx) xl++; else if (i>playerx) --xh;
+ if (j<playery) yl++; else if (j>playery) --yh;
+ for (k=0; k<9; k++) w1[k] = 10000;
+
+ for (k=xl; k<xh; k++)
+ for (m=yl; m<yh; m++) /* for each square compute distance to player */
+ {
+ tmp = k-i+4+3*(m-j);
+ tmpitem = item[k][m];
+ if (tmpitem!=OWALL || (k==playerx && m==playery))
+ if (mitem[k][m]==0)
+ if ((mitem[i][j] != VAMPIRE) || (tmpitem != OMIRROR))
+ if (tmpitem!=OCLOSEDDOOR)
+ {
+ w1[tmp] = (playerx-k)*(playerx-k)+(playery-m)*(playery-m);
+ w1x[tmp] = k; w1y[tmp] = m;
+ }
+ }
+
+ tmp = 0;
+ for (k=1; k<9; k++) if (w1[tmp] > w1[k]) tmp=k;
+
+ if (w1[tmp] < 10000)
+ if ((i!=w1x[tmp]) || (j!=w1y[tmp]))
+ mmove(i,j,w1x[tmp],w1y[tmp]);
+ }
+
+/*
+ * mmove(x,y,xd,yd) Function to actually perform the monster movement
+ * int x,y,xd,yd;
+ *
+ * Enter with the from coordinates in (x,y) and the destination coordinates
+ * in (xd,yd).
+ */
+mmove(aa,bb,cc,dd)
+ int aa,bb,cc,dd;
+ {
+ register int tmp,i,flag;
+ char *who,*p;
+ flag=0; /* set to 1 if monster hit by arrow trap */
+ if ((cc==playerx) && (dd==playery))
+ {
+ hitplayer(aa,bb); moved[aa][bb] = 1; return;
+ }
+ i=item[cc][dd];
+ if ((i==OPIT) || (i==OTRAPDOOR))
+ switch(mitem[aa][bb])
+ {
+ case SPIRITNAGA: case PLATINUMDRAGON: case WRAITH:
+ case VAMPIRE: case SILVERDRAGON: case POLTERGEIST:
+ case DEMONLORD: case DEMONLORD+1: case DEMONLORD+2:
+ case DEMONLORD+3: case DEMONLORD+4: case DEMONLORD+5:
+ case DEMONLORD+6: case DEMONPRINCE: break;
+
+ default: mitem[aa][bb]=0; /* fell in a pit or trapdoor */
+ };
+ tmp = mitem[cc][dd] = mitem[aa][bb];
+ if (i==OANNIHILATION)
+ {
+ if (tmp>=DEMONLORD+3) /* demons dispel spheres */
+ {
+ cursors();
+ lprintf("\nThe %s dispels the sphere!",monster[tmp].name);
+ rmsphere(cc,dd); /* delete the sphere */
+ }
+ else i=tmp=mitem[cc][dd]=0;
+ }
+ stealth[cc][dd]=1;
+ if ((hitp[cc][dd] = hitp[aa][bb]) < 0) hitp[cc][dd]=1;
+ mitem[aa][bb] = 0; moved[cc][dd] = 1;
+ if (tmp == LEPRECHAUN)
+ switch(i)
+ {
+ case OGOLDPILE: case OMAXGOLD: case OKGOLD: case ODGOLD:
+ case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
+ item[cc][dd] = 0; /* leprechaun takes gold */
+ };
+
+ if (tmp == TROLL) /* if a troll regenerate him */
+ if ((gtime & 1) == 0)
+ if (monster[tmp].hitpoints > hitp[cc][dd]) hitp[cc][dd]++;
+
+ if (i==OTRAPARROW) /* arrow hits monster */
+ { who = "An arrow"; if ((hitp[cc][dd] -= rnd(10)+level) <= 0)
+ { mitem[cc][dd]=0; flag=2; } else flag=1; }
+ if (i==ODARTRAP) /* dart hits monster */
+ { who = "A dart"; if ((hitp[cc][dd] -= rnd(6)) <= 0)
+ { mitem[cc][dd]=0; flag=2; } else flag=1; }
+ if (i==OTELEPORTER) /* monster hits teleport trap */
+ { flag=3; fillmonst(mitem[cc][dd]); mitem[cc][dd]=0; }
+ if (c[BLINDCOUNT]) return; /* if blind don't show where monsters are */
+ if (know[cc][dd] & 1)
+ {
+ p=0;
+ if (flag) cursors();
+ switch(flag)
+ {
+ case 1: p="\n%s hits the %s"; break;
+ case 2: p="\n%s hits and kills the %s"; break;
+ case 3: p="\nThe %s%s gets teleported"; who=""; break;
+ };
+ if (p) { lprintf(p,who,monster[tmp].name); beep(); }
+ }
+/* if (yrepcount>1) { know[aa][bb] &= 2; know[cc][dd] &= 2; return; } */
+ if (know[aa][bb] & 1) show1cell(aa,bb);
+ if (know[cc][dd] & 1) show1cell(cc,dd);
+ }
+
+/*
+ * movsphere() Function to look for and move spheres of annihilation
+ *
+ * This function works on the sphere linked list, first duplicating the list
+ * (the act of moving changes the list), then processing each sphere in order
+ * to move it. They eat anything in their way, including stairs, volcanic
+ * shafts, potions, etc, except for upper level demons, who can dispel
+ * spheres.
+ * No value is returned.
+ */
+#define SPHMAX 20 /* maximum number of spheres movsphere can handle */
+movsphere()
+ {
+ register int x,y,dir,len;
+ register struct sphere *sp,*sp2;
+ struct sphere sph[SPHMAX];
+
+ /* first duplicate sphere list */
+ for (sp=0,x=0,sp2=spheres; sp2; sp2=sp2->p) /* look through sphere list */
+ if (sp2->lev == level) /* only if this level */
+ {
+ sph[x] = *sp2; sph[x++].p = 0; /* copy the struct */
+ if (x>1) sph[x-2].p = &sph[x-1]; /* link pointers */
+ }
+ if (x) sp= sph; /* if any spheres, point to them */
+ else return; /* no spheres */
+
+ for (sp=sph; sp; sp=sp->p) /* look through sphere list */
+ {
+ x = sp->x; y = sp->y;
+ if (item[x][y]!=OANNIHILATION) continue; /* not really there */
+ if (--(sp->lifetime) < 0) /* has sphere run out of gas? */
+ {
+ rmsphere(x,y); /* delete sphere */
+ continue;
+ }
+ switch(rnd((int)max(7,c[INTELLIGENCE]>>1))) /* time to move the sphere */
+ {
+ case 1:
+ case 2: /* change direction to a random one */
+ sp->dir = rnd(8);
+ default: /* move in normal direction */
+ dir = sp->dir; len = sp->lifetime;
+ rmsphere(x,y);
+ newsphere(x+diroffx[dir],y+diroffy[dir],dir,len);
+ };
+ }
+ }
diff --git a/larn/nap.c b/larn/nap.c
new file mode 100644
index 00000000..b7a877d1
--- /dev/null
+++ b/larn/nap.c
@@ -0,0 +1,116 @@
+/* nap.c Larn is copyrighted 1986 by Noah Morgan. */
+#include <signal.h>
+#include <sys/types.h>
+#ifdef SYSV
+#include <sys/times.h>
+#else
+#ifdef BSD
+#include <sys/timeb.h>
+#endif BSD
+#endif SYSV
+
+/*
+ * routine to take a nap for n milliseconds
+ */
+nap(x)
+ register int x;
+ {
+ if (x<=0) return; /* eliminate chance for infinite loop */
+ lflush();
+ if (x > 999) sleep(x/1000); else napms(x);
+ }
+
+#ifdef NONAP
+napms(x) /* do nothing */
+ int x;
+ {
+ }
+#else NONAP
+#ifdef SYSV
+/* napms - sleep for time milliseconds - uses times() */
+/* this assumes that times returns a relative time in 60ths of a second */
+/* this will do horrible things if your times() returns seconds! */
+napms(time)
+ int time;
+ {
+ long matchclock, times();
+ struct tms stats;
+
+ if (time<=0) time=1; /* eliminate chance for infinite loop */
+ if ((matchclock = times(&stats)) == -1 || matchclock == 0)
+ return; /* error, or BSD style times() */
+ matchclock += (time / 17); /*17 ms/tic is 1000 ms/sec / 60 tics/sec */
+
+ while(matchclock < times(&stats))
+ ;
+ }
+
+#else not SYSV
+#ifdef BSD
+#ifdef SIGVTALRM
+/* This must be BSD 4.2! */
+#include <sys/time.h>
+#define bit(_a) (1<<((_a)-1))
+
+static nullf()
+ {
+ }
+
+/* napms - sleep for time milliseconds - uses setitimer() */
+napms(time)
+ int time;
+ {
+ struct itimerval timeout;
+ int (*oldhandler) ();
+ int oldsig;
+
+ if (time <= 0) return;
+
+ timerclear(&timeout.it_interval);
+ timeout.it_value.tv_sec = time / 1000;
+ timeout.it_value.tv_usec = (time % 1000) * 1000;
+
+ oldsig = sigblock(bit(SIGALRM));
+ setitimer(ITIMER_REAL, &timeout, (struct itimerval *)0);
+ oldhandler = signal(SIGALRM, nullf);
+ sigpause(oldsig);
+ signal(SIGALRM, oldhandler);
+ sigsetmask(oldsig);
+ }
+
+#else
+/* napms - sleep for time milliseconds - uses ftime() */
+
+static napms(time)
+ int time;
+ {
+ /* assumed to be BSD UNIX */
+ struct timeb _gtime;
+ time_t matchtime;
+ unsigned short matchmilli;
+ register struct timeb *tp = & _gtime;
+
+ if (time <= 0) return;
+ ftime(tp);
+ matchmilli = tp->millitm + time;
+ matchtime = tp->time;
+ while (matchmilli >= 1000)
+ {
+ ++matchtime;
+ matchmilli -= 1000;
+ }
+
+ while(1)
+ {
+ ftime(tp);
+ if ((tp->time > matchtime) ||
+ ((tp->time == matchtime) && (tp->millitm >= matchmilli)))
+ break;
+ }
+ }
+#endif
+#else not BSD
+static napms(time) int time; {} /* do nothing, forget it */
+#endif BSD
+#endif SYSV
+#endif NONAP
diff --git a/larn/object.c b/larn/object.c
new file mode 100644
index 00000000..9bf7c3c5
--- /dev/null
+++ b/larn/object.c
@@ -0,0 +1,807 @@
+/* object.c Larn is copyrighted 1986 by Noah Morgan. */
+#include "header.h"
+
+/*
+ ***************
+ LOOK_FOR_OBJECT
+ ***************
+
+ subroutine to look for an object and give the player his options
+ if an object was found.
+ */
+lookforobject()
+{
+register int i,j;
+if (c[TIMESTOP]) return; /* can't find objects is time is stopped */
+i=item[playerx][playery]; if (i==0) return;
+showcell(playerx,playery); cursors(); yrepcount=0;
+switch(i)
+ {
+ case OGOLDPILE: case OMAXGOLD:
+ case OKGOLD: case ODGOLD: lprcat("\n\nYou have found some gold!"); ogold(i); break;
+
+ case OPOTION: lprcat("\n\nYou have found a magic potion");
+ i = iarg[playerx][playery];
+ if (potionname[i][0]) lprintf(" of %s",&potionname[i][1]); opotion(i); break;
+
+ case OSCROLL: lprcat("\n\nYou have found a magic scroll");
+ i = iarg[playerx][playery];
+ if (scrollname[i][0]) lprintf(" of %s",&scrollname[i][1]);
+ oscroll(i); break;
+
+ case OALTAR: if (nearbymonst()) return;
+ lprcat("\n\nThere is a Holy Altar here!"); oaltar(); break;
+
+ case OBOOK: lprcat("\n\nYou have found a book."); obook(); break;
+
+ case OCOOKIE: lprcat("\n\nYou have found a fortune cookie."); ocookie(); break;
+
+ case OTHRONE: if (nearbymonst()) return;
+ lprintf("\n\nThere is %s here!",objectname[i]); othrone(0); break;
+
+ case OTHRONE2: if (nearbymonst()) return;
+ lprintf("\n\nThere is %s here!",objectname[i]); othrone(1); break;
+
+ case ODEADTHRONE: lprintf("\n\nThere is %s here!",objectname[i]); odeadthrone(); break;
+
+ case OORB: lprcat("\n\nYou have found the Orb!!!!!"); oorb(); break;
+
+ case OPIT: lprcat("\n\nYou're standing at the top of a pit."); opit(); break;
+
+ case OSTAIRSUP: lprcat("\n\nThere is a circular staircase here"); ostairs(1); /* up */ break;
+
+ case OELEVATORUP: lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
+ oelevator(1); /* up */ break;
+
+ case OFOUNTAIN: if (nearbymonst()) return;
+ lprcat("\n\nThere is a fountain here"); ofountain(); break;
+
+ case OSTATUE: if (nearbymonst()) return;
+ lprcat("\n\nYou are standing in front of a statue"); ostatue(); break;
+
+ case OCHEST: lprcat("\n\nThere is a chest here"); ochest(); break;
+
+ case OIVTELETRAP: if (rnd(11)<6) return;
+ item[playerx][playery] = OTELEPORTER;
+ know[playerx][playery] = 1;
+
+ case OTELEPORTER: lprcat("\nZaaaappp! You've been teleported!\n");
+ beep(); nap(3000); oteleport(0);
+ break;
+
+ case OSCHOOL: if (nearbymonst()) return;
+ lprcat("\n\nYou have found the College of Larn.");
+ lprcat("\nDo you (g) go inside, or (i) stay here? ");
+ i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
+ if (i == 'g') { oschool(); /* the college of larn */ }
+ else lprcat(" stay here");
+ break;
+
+ case OMIRROR: if (nearbymonst()) return;
+ lprcat("\n\nThere is a mirror here"); omirror(); break;
+
+ case OBANK2:
+ case OBANK: if (nearbymonst()) return;
+ if (i==OBANK) lprcat("\n\nYou have found the bank of Larn.");
+ else lprcat("\n\nYou have found a branch office of the bank of Larn.");
+ lprcat("\nDo you (g) go inside, or (i) stay here? ");
+ j=0; while ((j!='g') && (j!='i') && (j!='\33')) j=getchar();
+ if (j == 'g') { if (i==OBANK) obank(); else obank2(); /* the bank of larn */ }
+ else lprcat(" stay here");
+ break;
+
+ case ODEADFOUNTAIN: if (nearbymonst()) return;
+ lprcat("\n\nThere is a dead fountain here"); break;
+
+ case ODNDSTORE: if (nearbymonst()) return;
+ lprcat("\n\nThere is a DND store here.");
+ lprcat("\nDo you (g) go inside, or (i) stay here? ");
+ i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
+ if (i == 'g')
+ dndstore(); /* the dnd adventurers store */
+ else lprcat(" stay here");
+ break;
+
+ case OSTAIRSDOWN: lprcat("\n\nThere is a circular staircase here"); ostairs(-1); /* down */ break;
+
+ case OELEVATORDOWN: lprcat("\n\nYou feel light for a moment, but the feeling disappears");
+ oelevator(-1); /* down */
+ break;
+
+ case OOPENDOOR: lprintf("\n\nYou have found %s",objectname[i]);
+ lprcat("\nDo you (c) close it"); iopts();
+ i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar();
+ if ((i=='\33') || (i=='i')) { ignore(); break; }
+ lprcat("close"); forget();
+ item[playerx][playery]=OCLOSEDDOOR;
+ iarg[playerx][playery]=0;
+ playerx = lastpx; playery = lastpy;
+ break;
+
+ case OCLOSEDDOOR: lprintf("\n\nYou have found %s",objectname[i]);
+ lprcat("\nDo you (o) try to open it"); iopts();
+ i=0; while ((i!='o') && (i!='i') && (i!='\33')) i=getchar();
+ if ((i=='\33') || (i=='i'))
+ { ignore(); playerx = lastpx;
+ playery = lastpy; break; }
+ else
+ {
+ lprcat("open");
+ if (rnd(11)<7)
+ {
+ switch(iarg[playerx][playery])
+ {
+ case 6: c[AGGRAVATE] += rnd(400); break;
+
+ case 7: lprcat("\nYou are jolted by an electric shock ");
+ lastnum=274; losehp(rnd(20)); bottomline(); break;
+
+ case 8: loselevel(); break;
+
+ case 9: lprcat("\nYou suddenly feel weaker ");
+ if (c[STRENGTH]>3) c[STRENGTH]--;
+ bottomline(); break;
+
+ default: break;
+ }
+ playerx = lastpx; playery = lastpy;
+ }
+ else
+ {
+ forget(); item[playerx][playery]=OOPENDOOR;
+ }
+ }
+ break;
+
+ case OENTRANCE: lprcat("\nYou have found "); lprcat(objectname[OENTRANCE]);
+ lprcat("\nDo you (g) go inside"); iopts();
+ i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
+ if (i == 'g')
+ {
+ newcavelevel(1); playerx=33; playery=MAXY-2;
+ item[33][MAXY-1]=know[33][MAXY-1]=mitem[33][MAXY-1]=0;
+ draws(0,MAXX,0,MAXY); bot_linex(); return;
+ }
+ else ignore();
+ break;
+
+ case OVOLDOWN: lprcat("\nYou have found "); lprcat(objectname[OVOLDOWN]);
+ lprcat("\nDo you (c) climb down"); iopts();
+ i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar();
+ if ((i=='\33') || (i=='i')) { ignore(); break; }
+ if (level!=0) { lprcat("\nThe shaft only extends 5 feet downward!"); return; }
+ if (packweight() > 45+3*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep();
+ lastnum=275; losehp(30+rnd(20)); bottomhp(); }
+
+ else lprcat("climb down"); nap(3000); newcavelevel(MAXLEVEL);
+ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) /* put player near volcano shaft */
+ if (item[j][i]==OVOLUP) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); }
+ draws(0,MAXX,0,MAXY); bot_linex(); return;
+
+ case OVOLUP: lprcat("\nYou have found "); lprcat(objectname[OVOLUP]);
+ lprcat("\nDo you (c) climb up"); iopts();
+ i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar();
+ if ((i=='\33') || (i=='i')) { ignore(); break; }
+ if (level!=11) { lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!"); return; }
+ if (packweight() > 45+5*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep();
+ lastnum=275; losehp(15+rnd(20)); bottomhp(); return; }
+ lprcat("climb up"); lflush(); nap(3000); newcavelevel(0);
+ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) /* put player near volcano shaft */
+ if (item[j][i]==OVOLDOWN) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); }
+ draws(0,MAXX,0,MAXY); bot_linex(); return;
+
+ case OTRAPARROWIV: if (rnd(17)<13) return; /* for an arrow trap */
+ item[playerx][playery] = OTRAPARROW;
+ know[playerx][playery] = 0;
+
+ case OTRAPARROW: lprcat("\nYou are hit by an arrow"); beep(); /* for an arrow trap */
+ lastnum=259; losehp(rnd(10)+level);
+ bottomhp(); return;
+
+ case OIVDARTRAP: if (rnd(17)<13) return; /* for a dart trap */
+ item[playerx][playery] = ODARTRAP;
+ know[playerx][playery] = 0;
+
+ case ODARTRAP: lprcat("\nYou are hit by a dart"); beep(); /* for a dart trap */
+ lastnum=260; losehp(rnd(5));
+ if ((--c[STRENGTH]) < 3) c[STRENGTH] = 3;
+ bottomline(); return;
+
+ case OIVTRAPDOOR: if (rnd(17)<13) return; /* for a trap door */
+ item[playerx][playery] = OTRAPDOOR;
+ know[playerx][playery] = 1;
+
+ case OTRAPDOOR: lastnum = 272; /* a trap door */
+ if ((level==MAXLEVEL-1) || (level==MAXLEVEL+MAXVLEVEL-1))
+ { lprcat("\nYou fell through a bottomless trap door!"); beep(); nap(3000); died(271); }
+ lprcat("\nYou fall through a trap door!"); beep(); /* for a trap door */
+ losehp(rnd(5+level));
+ nap(2000); newcavelevel(level+1); draws(0,MAXX,0,MAXY); bot_linex();
+ return;
+
+
+ case OTRADEPOST: if (nearbymonst()) return;
+ lprcat("\nYou have found the Larn trading Post.");
+ lprcat("\nDo you (g) go inside, or (i) stay here? ");
+ i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
+ if (i == 'g') otradepost(); else lprcat("stay here");
+ return;
+
+ case OHOME: if (nearbymonst()) return;
+ lprcat("\nYou have found your way home.");
+ lprcat("\nDo you (g) go inside, or (i) stay here? ");
+ i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
+ if (i == 'g') ohome(); else lprcat("stay here");
+ return;
+
+ case OWALL: break;
+
+ case OANNIHILATION: died(283); return; /* annihilated by sphere of annihilation */
+
+ case OLRS: if (nearbymonst()) return;
+ lprcat("\n\nThere is an LRS office here.");
+ lprcat("\nDo you (g) go inside, or (i) stay here? ");
+ i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
+ if (i == 'g')
+ olrs(); /* the larn revenue service */
+ else lprcat(" stay here");
+ break;
+
+ default: finditem(i); break;
+ };
+}
+
+/*
+ function to say what object we found and ask if player wants to take it
+ */
+finditem(itm)
+ int itm;
+ {
+ int tmp,i;
+ lprintf("\n\nYou have found %s ",objectname[itm]);
+ tmp=iarg[playerx][playery];
+ switch(itm)
+ {
+ case ODIAMOND: case ORUBY: case OEMERALD:
+ case OSAPPHIRE: case OSPIRITSCARAB: case OORBOFDRAGON:
+ case OCUBEofUNDEAD: case ONOTHEFT: break;
+
+ default:
+ if (tmp>0) lprintf("+ %d",(long)tmp); else if (tmp<0) lprintf(" %d",(long)tmp);
+ }
+ lprcat("\nDo you want to (t) take it"); iopts();
+ i=0; while (i!='t' && i!='i' && i!='\33') i=getchar();
+ if (i == 't')
+ { lprcat("take"); if (take(itm,tmp)==0) forget(); return; }
+ ignore();
+ }
+
+
+/*
+ *******
+ OSTAIRS
+ *******
+
+ subroutine to process the stair cases
+ if dir > 0 the up else down
+ */
+ostairs(dir)
+ int dir;
+ {
+ register int k;
+ lprcat("\nDo you (s) stay here ");
+ if (dir > 0) lprcat("(u) go up "); else lprcat("(d) go down ");
+ lprcat("or (f) kick stairs? ");
+
+ while (1) switch(getchar())
+ {
+ case '\33':
+ case 's': case 'i': lprcat("stay here"); return;
+
+ case 'f': lprcat("kick stairs");
+ if (rnd(2) == 1)
+ lprcat("\nI hope you feel better. Showing anger rids you of frustration.");
+ else
+ {
+ k=rnd((level+1)<<1);
+ lprintf("\nYou hurt your foot dumb dumb! You suffer %d hit points",(long)k);
+ lastnum=276; losehp(k); bottomline();
+ }
+ return;
+
+ case 'u': lprcat("go up");
+ if (dir < 0) lprcat("\nThe stairs don't go up!");
+ else
+ if (level>=2 && level!=11)
+ {
+ k = level; newcavelevel(level-1);
+ draws(0,MAXX,0,MAXY); bot_linex();
+ }
+ else lprcat("\nThe stairs lead to a dead end!");
+ return;
+
+ case 'd': lprcat("go down");
+ if (dir > 0) lprcat("\nThe stairs don't go down!");
+ else
+ if (level!=0 && level!=10 && level!=13)
+ {
+ k = level; newcavelevel(level+1);
+ draws(0,MAXX,0,MAXY); bot_linex();
+ }
+ else lprcat("\nThe stairs lead to a dead end!");
+ return;
+ };
+ }
+
+
+/*
+ *********
+ OTELEPORTER
+ *********
+
+ subroutine to handle a teleport trap +/- 1 level maximum
+ */
+oteleport(err)
+ int err;
+ {
+ register int tmp;
+ if (err) if (rnd(151)<3) died(264); /* stuck in a rock */
+ c[TELEFLAG]=1; /* show ?? on bottomline if been teleported */
+ if (level==0) tmp=0;
+ else if (level < MAXLEVEL)
+ { tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1;
+ if (tmp<1) tmp=1; }
+ else
+ { tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1;
+ if (tmp<MAXLEVEL) tmp=MAXLEVEL; }
+ playerx = rnd(MAXX-2); playery = rnd(MAXY-2);
+ if (level != tmp) newcavelevel(tmp); positionplayer();
+ draws(0,MAXX,0,MAXY); bot_linex();
+ }
+
+/*
+ *******
+ OPOTION
+ *******
+
+ function to process a potion
+ */
+opotion(pot)
+ int pot;
+ {
+ lprcat("\nDo you (d) drink it, (t) take it"); iopts();
+ while (1) switch(getchar())
+ {
+ case '\33':
+ case 'i': ignore(); return;
+
+ case 'd': lprcat("drink\n"); forget(); /* destroy potion */
+ quaffpotion(pot); return;
+
+ case 't': lprcat("take\n"); if (take(OPOTION,pot)==0) forget();
+ return;
+ };
+ }
+
+/*
+ function to drink a potion
+ */
+quaffpotion(pot)
+ int pot;
+ {
+ register int i,j,k;
+ if (pot<0 || pot>=MAXPOTION) return; /* check for within bounds */
+ potionname[pot][0] = ' ';
+ switch(pot)
+ {
+ case 9: lprcat("\nYou feel greedy . . ."); nap(2000);
+ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
+ if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD))
+ {
+ know[j][i]=1; show1cell(j,i);
+ }
+ showplayer(); return;
+
+ case 19: lprcat("\nYou feel greedy . . ."); nap(2000);
+ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
+ {
+ k=item[j][i];
+ if ((k==ODIAMOND) || (k==ORUBY) || (k==OEMERALD) || (k==OMAXGOLD)
+ || (k==OSAPPHIRE) || (k==OLARNEYE) || (k==OGOLDPILE))
+ {
+ know[j][i]=1; show1cell(j,i);
+ }
+ }
+ showplayer(); return;
+
+ case 20: c[HP] = c[HPMAX]; break; /* instant healing */
+
+ case 1: lprcat("\nYou feel better");
+ if (c[HP] == c[HPMAX]) raisemhp(1);
+ else if ((c[HP] += rnd(20)+20+c[LEVEL]) > c[HPMAX]) c[HP]=c[HPMAX]; break;
+
+ case 2: lprcat("\nSuddenly, you feel much more skillful!");
+ raiselevel(); raisemhp(1); return;
+
+ case 3: lprcat("\nYou feel strange for a moment");
+ c[rund(6)]++; break;
+
+ case 4: lprcat("\nYou feel more self confident!");
+ c[WISDOM] += rnd(2); break;
+
+ case 5: lprcat("\nWow! You feel great!");
+ if (c[STRENGTH]<12) c[STRENGTH]=12; else c[STRENGTH]++; break;
+
+ case 6: lprcat("\nYour charm went up by one!"); c[CHARISMA]++; break;
+
+ case 8: lprcat("\nYour intelligence went up by one!");
+ c[INTELLIGENCE]++; break;
+
+ case 10: for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
+ if (mitem[j][i])
+ {
+ know[j][i]=1; show1cell(j,i);
+ }
+ /* monster detection */ return;
+
+ case 12: lprcat("\nThis potion has no taste to it"); return;
+
+ case 15: lprcat("\nWOW!!! You feel Super-fantastic!!!");
+ if (c[HERO]==0) for (i=0; i<6; i++) c[i] += 11;
+ c[HERO] += 250; break;
+
+ case 16: lprcat("\nYou have a greater intestinal constitude!");
+ c[CONSTITUTION]++; break;
+
+ case 17: lprcat("\nYou now have incredibly bulging muscles!!!");
+ if (c[GIANTSTR]==0) c[STREXTRA] += 21;
+ c[GIANTSTR] += 700; break;
+
+ case 18: lprcat("\nYou feel a chill run up your spine!");
+ c[FIRERESISTANCE] += 1000; break;
+
+ case 0: lprcat("\nYou fall asleep. . .");
+ i=rnd(11)-(c[CONSTITUTION]>>2)+2; while(--i>0) { parse2(); nap(1000); }
+ cursors(); lprcat("\nYou woke up!"); return;
+
+ case 7: lprcat("\nYou become dizzy!");
+ if (--c[STRENGTH] < 3) c[STRENGTH]=3; break;
+
+ case 11: lprcat("\nYou stagger for a moment . .");
+ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
+ know[j][i]=0;
+ nap(2000); draws(0,MAXX,0,MAXY); /* potion of forgetfulness */ return;
+
+ case 13: lprcat("\nYou can't see anything!"); /* blindness */
+ c[BLINDCOUNT]+=500; return;
+
+ case 14: lprcat("\nYou feel confused"); c[CONFUSE]+= 20+rnd(9); return;
+
+ case 21: lprcat("\nYou don't seem to be affected"); return; /* cure dianthroritis */
+
+ case 22: lprcat("\nYou feel a sickness engulf you"); /* poison */
+ c[HALFDAM] += 200 + rnd(200); return;
+
+ case 23: lprcat("\nYou feel your vision sharpen"); /* see invisible */
+ c[SEEINVISIBLE] += rnd(1000)+400;
+ monstnamelist[INVISIBLESTALKER] = 'I'; return;
+ };
+ bottomline(); /* show new stats */ return;
+ }
+
+/*
+ *******
+ OSCROLL
+ *******
+
+ function to process a magic scroll
+ */
+oscroll(typ)
+ int typ;
+ {
+ lprcat("\nDo you ");
+ if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
+ while (1) switch(getchar())
+ {
+ case '\33':
+ case 'i': ignore(); return;
+
+ case 'r': if (c[BLINDCOUNT]) break;
+ lprcat("read"); forget();
+ if (typ==2 || typ==15) { show1cell(playerx,playery); cursors(); }
+ /* destroy it */ read_scroll(typ); return;
+
+ case 't': lprcat("take"); if (take(OSCROLL,typ)==0) forget(); /* destroy it */
+ return;
+ };
+ }
+
+/*
+ data for the function to read a scroll
+ */
+static int xh,yh,yl,xl;
+static char curse[] = { BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
+ LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM };
+static char exten[] = { PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT,
+ INVISIBILITY, CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP };
+char time_change[] = { HASTESELF,HERO,ALTPRO,PROTECTIONTIME,DEXCOUNT,
+ STRCOUNT,GIANTSTR,CHARMCOUNT,INVISIBILITY,CANCELLATION,
+ HASTESELF,AGGRAVATE,SCAREMONST,STEALTH,AWARENESS,HOLDMONST,HASTEMONST,
+ FIRERESISTANCE,GLOBE,SPIRITPRO,UNDEADPRO,HALFDAM,SEEINVISIBLE,
+ ITCHING,CLUMSINESS, WTW };
+/*
+ * function to adjust time when time warping and taking courses in school
+ */
+adjtime(tim)
+ register long tim;
+ {
+ register int j;
+ for (j=0; j<26; j++) /* adjust time related parameters */
+ if (c[time_change[j]])
+ if ((c[time_change[j]] -= tim) < 1) c[time_change[j]]=1;
+ regen();
+ }
+
+/*
+ function to read a scroll
+ */
+read_scroll(typ)
+ int typ;
+ {
+ register int i,j;
+ if (typ<0 || typ>=MAXSCROLL) return; /* be sure we are within bounds */
+ scrollname[typ][0] = ' ';
+ switch(typ)
+ {
+ case 0: lprcat("\nYour armor glows for a moment"); enchantarmor(); return;
+
+ case 1: lprcat("\nYour weapon glows for a moment"); enchweapon(); return; /* enchant weapon */
+
+ case 2: lprcat("\nYou have been granted enlightenment!");
+ yh = min(playery+7,MAXY); xh = min(playerx+25,MAXX);
+ yl = max(playery-7,0); xl = max(playerx-25,0);
+ for (i=yl; i<yh; i++) for (j=xl; j<xh; j++) know[j][i]=1;
+ nap(2000); draws(xl,xh,yl,yh); return;
+
+ case 3: lprcat("\nThis scroll seems to be blank"); return;
+
+ case 4: createmonster(makemonst(level+1)); return; /* this one creates a monster */
+
+ case 5: something(level); /* create artifact */ return;
+
+ case 6: c[AGGRAVATE]+=800; return; /* aggravate monsters */
+
+ case 7: gtime += (i = rnd(1000) - 850); /* time warp */
+ if (i>=0) lprintf("\nYou went forward in time by %d mobuls",(long)((i+99)/100));
+ else lprintf("\nYou went backward in time by %d mobuls",(long)(-(i+99)/100));
+ adjtime((long)i); /* adjust time for time warping */
+ return;
+
+ case 8: oteleport(0); return; /* teleportation */
+
+ case 9: c[AWARENESS] += 1800; return; /* expanded awareness */
+
+ case 10: c[HASTEMONST] += rnd(55)+12; return; /* haste monster */
+
+ case 11: for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
+ if (mitem[j][i])
+ hitp[j][i] = monster[mitem[j][i]].hitpoints;
+ return; /* monster healing */
+ case 12: c[SPIRITPRO] += 300 + rnd(200); bottomline(); return; /* spirit protection */
+
+ case 13: c[UNDEADPRO] += 300 + rnd(200); bottomline(); return; /* undead protection */
+
+ case 14: c[STEALTH] += 250 + rnd(250); bottomline(); return; /* stealth */
+
+ case 15: lprcat("\nYou have been granted enlightenment!"); /* magic mapping */
+ for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=1;
+ nap(2000); draws(0,MAXX,0,MAXY); return;
+
+ case 16: c[HOLDMONST] += 30; bottomline(); return; /* hold monster */
+
+ case 17: for (i=0; i<26; i++) /* gem perfection */
+ switch(iven[i])
+ {
+ case ODIAMOND: case ORUBY:
+ case OEMERALD: case OSAPPHIRE:
+ j = ivenarg[i]; j &= 255; j <<= 1;
+ if (j > 255) j=255; /* double value */
+ ivenarg[i] = j; break;
+ }
+ break;
+
+ case 18: for (i=0; i<11; i++) c[exten[i]] <<= 1; /* spell extension */
+ break;
+
+ case 19: for (i=0; i<26; i++) /* identify */
+ {
+ if (iven[i]==OPOTION) potionname[ivenarg[i]][0] = ' ';
+ if (iven[i]==OSCROLL) scrollname[ivenarg[i]][0] = ' ';
+ }
+ break;
+
+ case 20: for (i=0; i<10; i++) /* remove curse */
+ if (c[curse[i]]) c[curse[i]] = 1;
+ break;
+
+ case 21: annihilate(); break; /* scroll of annihilation */
+
+ case 22: godirect(22,150,"The ray hits the %s",0,' '); /* pulverization */
+ break;
+ case 23: c[LIFEPROT]++; break; /* life protection */
+ };
+ }
+
+
+oorb()
+ {
+ }
+
+opit()
+ {
+ register int i;
+ if (rnd(101)<81)
+ if (rnd(70) > 9*c[DEXTERITY]-packweight() || rnd(101)<5)
+ if (level==MAXLEVEL-1) obottomless(); else
+ if (level==MAXLEVEL+MAXVLEVEL-1) obottomless(); else
+ {
+ if (rnd(101)<20)
+ {
+ i=0; lprcat("\nYou fell into a pit! Your fall is cushioned by an unknown force\n");
+ }
+ else
+ {
+ i = rnd(level*3+3);
+ lprintf("\nYou fell into a pit! You suffer %d hit points damage",(long)i);
+ lastnum=261; /* if he dies scoreboard will say so */
+ }
+ losehp(i); nap(2000); newcavelevel(level+1); draws(0,MAXX,0,MAXY);
+ }
+ }
+
+obottomless()
+ {
+ lprcat("\nYou fell into a bottomless pit!"); beep(); nap(3000); died(262);
+ }
+oelevator(dir)
+ int dir;
+ {
+#ifdef lint
+ int x;
+ x=dir;
+ dir=x;
+#endif lint
+ }
+
+ostatue()
+ {
+ }
+
+omirror()
+ {
+ }
+
+obook()
+ {
+ lprcat("\nDo you ");
+ if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
+ while (1) switch(getchar())
+ {
+ case '\33':
+ case 'i': ignore(); return;
+
+ case 'r': if (c[BLINDCOUNT]) break;
+ lprcat("read");
+ /* no more book */ readbook(iarg[playerx][playery]); forget(); return;
+
+ case 't': lprcat("take"); if (take(OBOOK,iarg[playerx][playery])==0) forget(); /* no more book */
+ return;
+ };
+ }
+
+/*
+ function to read a book
+ */
+readbook(lev)
+ register int lev;
+ {
+ register int i,tmp;
+ if (lev<=3) i = rund((tmp=splev[lev])?tmp:1); else
+ i = rnd((tmp=splev[lev]-9)?tmp:1) + 9;
+ spelknow[i]=1;
+ lprintf("\nSpell \"%s\": %s\n%s",spelcode[i],spelname[i],speldescript[i]);
+ if (rnd(10)==4)
+ { lprcat("\nYour int went up by one!"); c[INTELLIGENCE]++; bottomline(); }
+ }
+
+ocookie()
+ {
+ char *p;
+ lprcat("\nDo you (e) eat it, (t) take it"); iopts();
+ while (1) switch(getchar())
+ {
+ case '\33':
+ case 'i': ignore(); return;
+
+ case 'e': lprcat("eat\nThe cookie tasted good.");
+ forget(); /* no more cookie */
+ if (c[BLINDCOUNT]) return;
+ if (!(p=fortune(fortfile))) return;
+ lprcat(" A message inside the cookie reads:\n"); lprcat(p);
+ return;
+
+ case 't': lprcat("take"); if (take(OCOOKIE,0)==0) forget(); /* no more book */
+ return;
+ };
+ }
+
+
+/* routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth 100* the argument */
+ogold(arg)
+ int arg;
+ {
+ register long i;
+ i = iarg[playerx][playery];
+ if (arg==OMAXGOLD) i *= 100;
+ else if (arg==OKGOLD) i *= 1000;
+ else if (arg==ODGOLD) i *= 10;
+ lprintf("\nIt is worth %d!",(long)i); c[GOLD] += i; bottomgold();
+ item[playerx][playery] = know[playerx][playery] = 0; /* destroy gold */
+ }
+
+ohome()
+ {
+ register int i;
+ nosignal = 1; /* disable signals */
+ for (i=0; i<26; i++) if (iven[i]==OPOTION) if (ivenarg[i]==21)
+ {
+ iven[i]=0; /* remove the potion of cure dianthroritis from inventory */
+ clear(); lprcat("Congratulations. You found a potion of cure dianthroritis.\n");
+ lprcat("\nFrankly, No one thought you could do it. Boy! Did you surprise them!\n");
+ if (gtime>TIMELIMIT)
+ {
+ lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
+ lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n");
+ nap(5000); died(269);
+ }
+ else
+ {
+ lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
+ lprcat("Your daughter should be well on her way to recovery.\n");
+ nap(6000);
+ lprcat("\nThe potion is"); nap(3000); lprcat(" working! The doctor thinks that\n");
+ lprcat("your daughter will recover in a few days. Congratulations!\n");
+ beep(); nap(5000); died(263);
+ }
+ }
+
+ while (1)
+ {
+ clear(); lprintf("Welcome home %s. Latest word from the doctor is not good.\n",logname);
+
+ if (gtime>TIMELIMIT)
+ {
+ lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
+ lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n");
+ nap(5000); died(269);
+ }
+
+ lprcat("\nThe diagnosis is confirmed as dianthroritis. He guesses that\n");
+ lprintf("your daughter has only %d mobuls left in this world. It's up to you,\n",(long)((TIMELIMIT-gtime+99)/100));
+ lprintf("%s, to find the only hope for your daughter, the very rare\n",logname);
+ lprcat("potion of cure dianthroritis. It is rumored that only deep in the\n");
+ lprcat("depths of the caves can this potion be found.\n\n\n");
+ lprcat("\n ----- press "); standout("return");
+ lprcat(" to continue, "); standout("escape");
+ lprcat(" to leave ----- ");
+ i=getchar(); while (i!='\33' && i!='\n') i=getchar();
+ if (i=='\33') { drawscreen(); nosignal = 0; /* enable signals */ return; }
+ }
+ }
+
+/* routine to save program space */
+iopts()
+ { lprcat(", or (i) ignore it? "); }
+ignore()
+ { lprcat("ignore\n"); }
+
diff --git a/larn/pathnames.h b/larn/pathnames.h
new file mode 100644
index 00000000..e398993f
--- /dev/null
+++ b/larn/pathnames.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 5/2/90
+ */
+
+#define _PATH_LOG "/var/games/larn/llog12.0"
+#define _PATH_SCORE "/var/games/larn/lscore12.0"
+#define _PATH_HELP "/usr/share/games/larn/larn.help"
+#define _PATH_LEVELS "/usr/share/games/larn/larnmaze"
+#define _PATH_FORTS "/usr/share/games/larn/lfortune"
+#define _PATH_PLAYERIDS "/usr/share/games/larn/playerids"
diff --git a/larn/regen.c b/larn/regen.c
new file mode 100644
index 00000000..b9f7a0f2
--- /dev/null
+++ b/larn/regen.c
@@ -0,0 +1,92 @@
+/* regen.c Larn is copyrighted 1986 by Noah Morgan. */
+#include "header.h"
+/*
+ *******
+ REGEN()
+ *******
+ regen()
+
+ subroutine to regenerate player hp and spells
+ */
+regen()
+ {
+ register int i,flag;
+ register long *d;
+ d = c;
+#ifdef EXTRA
+ d[MOVESMADE]++;
+#endif
+ if (d[TIMESTOP]) { if(--d[TIMESTOP]<=0) bottomline(); return; } /* for stop time spell */
+ flag=0;
+
+ if (d[STRENGTH]<3) { d[STRENGTH]=3; flag=1; }
+ if ((d[HASTESELF]==0) || ((d[HASTESELF] & 1) == 0))
+ gtime++;
+
+ if (d[HP] != d[HPMAX])
+ if (d[REGENCOUNTER]-- <= 0) /* regenerate hit points */
+ {
+ d[REGENCOUNTER] = 22 + (d[HARDGAME]<<1) - d[LEVEL];
+ if ((d[HP] += d[REGEN]) > d[HPMAX]) d[HP] = d[HPMAX];
+ bottomhp();
+ }
+
+ if (d[SPELLS] < d[SPELLMAX]) /* regenerate spells */
+ if (d[ECOUNTER]-- <= 0)
+ {
+ d[ECOUNTER] = 100+4*(d[HARDGAME]-d[LEVEL]-d[ENERGY]);
+ d[SPELLS]++; bottomspell();
+ }
+
+ if (d[HERO]) if (--d[HERO]<=0) { for (i=0; i<6; i++) d[i] -= 10; flag=1; }
+ if (d[ALTPRO]) if (--d[ALTPRO]<=0) { d[MOREDEFENSES]-=3; flag=1; }
+ if (d[PROTECTIONTIME]) if (--d[PROTECTIONTIME]<=0) { d[MOREDEFENSES]-=2; flag=1; }
+ if (d[DEXCOUNT]) if (--d[DEXCOUNT]<=0) { d[DEXTERITY]-=3; flag=1; }
+ if (d[STRCOUNT]) if (--d[STRCOUNT]<=0) { d[STREXTRA]-=3; flag=1; }
+ if (d[BLINDCOUNT]) if (--d[BLINDCOUNT]<=0) { cursors(); lprcat("\nThe blindness lifts "); beep(); }
+ if (d[CONFUSE]) if (--d[CONFUSE]<=0) { cursors(); lprcat("\nYou regain your senses"); beep(); }
+ if (d[GIANTSTR]) if (--d[GIANTSTR]<=0) { d[STREXTRA] -= 20; flag=1; }
+ if (d[CHARMCOUNT]) if ((--d[CHARMCOUNT]) <= 0) flag=1;
+ if (d[INVISIBILITY]) if ((--d[INVISIBILITY]) <= 0) flag=1;
+ if (d[CANCELLATION]) if ((--d[CANCELLATION]) <= 0) flag=1;
+ if (d[WTW]) if ((--d[WTW]) <= 0) flag=1;
+ if (d[HASTESELF]) if ((--d[HASTESELF]) <= 0) flag=1;
+ if (d[AGGRAVATE]) --d[AGGRAVATE];
+ if (d[SCAREMONST]) if ((--d[SCAREMONST]) <= 0) flag=1;
+ if (d[STEALTH]) if ((--d[STEALTH]) <= 0) flag=1;
+ if (d[AWARENESS]) --d[AWARENESS];
+ if (d[HOLDMONST]) if ((--d[HOLDMONST]) <= 0) flag=1;
+ if (d[HASTEMONST]) --d[HASTEMONST];
+ if (d[FIRERESISTANCE]) if ((--d[FIRERESISTANCE]) <= 0) flag=1;
+ if (d[GLOBE]) if (--d[GLOBE]<=0) { d[MOREDEFENSES]-=10; flag=1; }
+ if (d[SPIRITPRO]) if (--d[SPIRITPRO] <= 0) flag=1;
+ if (d[UNDEADPRO]) if (--d[UNDEADPRO] <= 0) flag=1;
+ if (d[HALFDAM]) if (--d[HALFDAM]<=0) { cursors(); lprcat("\nYou now feel better "); beep(); }
+ if (d[SEEINVISIBLE])
+ if (--d[SEEINVISIBLE]<=0)
+ { monstnamelist[INVISIBLESTALKER] = ' ';
+ cursors(); lprcat("\nYou feel your vision return to normal"); beep(); }
+ if (d[ITCHING])
+ {
+ if (d[ITCHING]>1)
+ if ((d[WEAR]!= -1) || (d[SHIELD]!= -1))
+ if (rnd(100)<50)
+ {
+ d[WEAR]=d[SHIELD]= -1; cursors();
+ lprcat("\nThe hysteria of itching forces you to remove your armor!");
+ beep(); recalc(); bottomline();
+ }
+ if (--d[ITCHING]<=0) { cursors(); lprcat("\nYou now feel the irritation subside!"); beep(); }
+ }
+ if (d[CLUMSINESS])
+ {
+ if (d[WIELD] != -1)
+ if (d[CLUMSINESS]>1)
+ if (item[playerx][playery]==0) /* only if nothing there */
+ if (rnd(100)<33) /* drop your weapon due to clumsiness */
+ drop_object((int)d[WIELD]);
+ if (--d[CLUMSINESS]<=0) { cursors(); lprcat("\nYou now feel less awkward!"); beep(); }
+ }
+ if (flag) bottomline();
+ }
+
diff --git a/larn/savelev.c b/larn/savelev.c
new file mode 100644
index 00000000..4419acb9
--- /dev/null
+++ b/larn/savelev.c
@@ -0,0 +1,47 @@
+/* savelev.c Larn is copyrighted 1986 by Noah Morgan. */
+#include "header.h"
+extern struct cel *cell;
+
+/*
+ * routine to save the present level into storage
+ */
+savelevel()
+ {
+ register struct cel *pcel;
+ register char *pitem,*pknow,*pmitem;
+ register short *phitp,*piarg;
+ register struct cel *pecel;
+ pcel = &cell[level*MAXX*MAXY]; /* pointer to this level's cells */
+ pecel = pcel + MAXX*MAXY; /* pointer to past end of this level's cells */
+ pitem=item[0]; piarg=iarg[0]; pknow=know[0]; pmitem=mitem[0]; phitp=hitp[0];
+ while (pcel < pecel)
+ {
+ pcel->mitem = *pmitem++;
+ pcel->hitp = *phitp++;
+ pcel->item = *pitem++;
+ pcel->know = *pknow++;
+ pcel++->iarg = *piarg++;
+ }
+ }
+
+/*
+ * routine to restore a level from storage
+ */
+getlevel()
+ {
+ register struct cel *pcel;
+ register char *pitem,*pknow,*pmitem;
+ register short *phitp,*piarg;
+ register struct cel *pecel;
+ pcel = &cell[level*MAXX*MAXY]; /* pointer to this level's cells */
+ pecel = pcel + MAXX*MAXY; /* pointer to past end of this level's cells */
+ pitem=item[0]; piarg=iarg[0]; pknow=know[0]; pmitem=mitem[0]; phitp=hitp[0];
+ while (pcel < pecel)
+ {
+ *pmitem++ = pcel->mitem;
+ *phitp++ = pcel->hitp;
+ *pitem++ = pcel->item;
+ *pknow++ = pcel->know;
+ *piarg++ = pcel++->iarg;
+ }
+ }
diff --git a/larn/scores.c b/larn/scores.c
new file mode 100644
index 00000000..f6cf15c1
--- /dev/null
+++ b/larn/scores.c
@@ -0,0 +1,652 @@
+/* scores.c Larn is copyrighted 1986 by Noah Morgan.
+ *
+ * Functions in this file are:
+ *
+ * readboard() Function to read in the scoreboard into a static buffer
+ * writeboard() Function to write the scoreboard from readboard()'s buffer
+ * makeboard() Function to create a new scoreboard (wipe out old one)
+ * hashewon() Function to return 1 if player has won a game before, else 0
+ * long paytaxes(x) Function to pay taxes if any are due
+ * winshou() Subroutine to print out the winning scoreboard
+ * shou(x) Subroutine to print out the non-winners scoreboard
+ * showscores() Function to show the scoreboard on the terminal
+ * showallscores() Function to show scores and the iven lists that go with them
+ * sortboard() Function to sort the scoreboard
+ * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard
+ * new1sub(score,i,whoo,taxes) Subroutine to put player into a
+ * new2sub(score,i,whoo,whyded) Subroutine to put player into a
+ * died(x) Subroutine to record who played larn, and what the score was
+ * diedsub(x) Subroutine to print out a line showing player when he is killed
+ * diedlog() Subroutine to read a log file and print it out in ascii format
+ * getplid(name) Function to get players id # from id file
+ *
+ */
+#include <sys/types.h>
+#include <sys/times.h>
+#include <sys/stat.h>
+#include "header.h"
+
+struct scofmt /* This is the structure for the scoreboard */
+ {
+ long score; /* the score of the player */
+ long suid; /* the user id number of the player */
+ short what; /* the number of the monster that killed player */
+ short level; /* the level player was on when he died */
+ short hardlev; /* the level of difficulty player played at */
+ short order; /* the relative ordering place of this entry */
+ char who[40]; /* the name of the character */
+ char sciv[26][2]; /* this is the inventory list of the character */
+ };
+struct wscofmt /* This is the structure for the winning scoreboard */
+ {
+ long score; /* the score of the player */
+ long timeused; /* the time used in mobuls to win the game */
+ long taxes; /* taxes he owes to LRS */
+ long suid; /* the user id number of the player */
+ short hardlev; /* the level of difficulty player played at */
+ short order; /* the relative ordering place of this entry */
+ char who[40]; /* the name of the character */
+ };
+
+struct log_fmt /* 102 bytes struct for the log file */
+ {
+ long score; /* the players score */
+ long diedtime; /* time when game was over */
+ short cavelev; /* level in caves */
+ short diff; /* difficulty player played at */
+#ifdef EXTRA
+ long elapsedtime; /* real time of game in seconds */
+ long bytout; /* bytes input and output */
+ long bytin;
+ long moves; /* number of moves made by player */
+ short ac; /* armor class of player */
+ short hp,hpmax; /* players hitpoints */
+ short cputime; /* cpu time needed in seconds */
+ short killed,spused;/* monsters killed and spells cast */
+ short usage; /* usage of the cpu in % */
+ short lev; /* player level */
+#endif
+ char who[12]; /* player name */
+ char what[46]; /* what happened to player */
+ };
+
+static struct scofmt sco[SCORESIZE]; /* the structure for the scoreboard */
+static struct wscofmt winr[SCORESIZE]; /* struct for the winning scoreboard */
+static struct log_fmt logg; /* structure for the log file */
+static char *whydead[] = {
+ "quit", "suspended", "self - annihilated", "shot by an arrow",
+ "hit by a dart", "fell into a pit", "fell into a bottomless pit",
+ "a winner", "trapped in solid rock", "killed by a missing save file",
+ "killed by an old save file", "caught by the greedy cheater checker trap",
+ "killed by a protected save file","killed his family and committed suicide",
+ "erased by a wayward finger", "fell through a bottomless trap door",
+ "fell through a trap door", "drank some poisonous water",
+ "fried by an electric shock", "slipped on a volcano shaft",
+ "killed by a stupid act of frustration", "attacked by a revolting demon",
+ "hit by his own magic", "demolished by an unseen attacker",
+ "fell into the dreadful sleep", "killed by an exploding chest",
+/*26*/ "killed by a missing maze data file", "annihilated in a sphere",
+ "died a post mortem death","wasted by a malloc() failure"
+ };
+
+/*
+ * readboard() Function to read in the scoreboard into a static buffer
+ *
+ * returns -1 if unable to read in the scoreboard, returns 0 if all is OK
+ */
+readboard()
+ {
+ if (lopen(scorefile)<0)
+ { lprcat("Can't read scoreboard\n"); lflush(); return(-1); }
+ lrfill((char*)sco,sizeof(sco)); lrfill((char*)winr,sizeof(winr));
+ lrclose(); lcreat((char*)0); return(0);
+ }
+
+/*
+ * writeboard() Function to write the scoreboard from readboard()'s buffer
+ *
+ * returns -1 if unable to write the scoreboard, returns 0 if all is OK
+ */
+writeboard()
+ {
+ set_score_output();
+ if (lcreat(scorefile)<0)
+ { lprcat("Can't write scoreboard\n"); lflush(); return(-1); }
+ lwrite((char*)sco,sizeof(sco)); lwrite((char*)winr,sizeof(winr));
+ lwclose(); lcreat((char*)0); return(0);
+ }
+
+/*
+ * makeboard() Function to create a new scoreboard (wipe out old one)
+ *
+ * returns -1 if unable to write the scoreboard, returns 0 if all is OK
+ */
+makeboard()
+ {
+ register int i;
+ for (i=0; i<SCORESIZE; i++)
+ {
+ winr[i].taxes = winr[i].score = sco[i].score = 0;
+ winr[i].order = sco[i].order = i;
+ }
+ if (writeboard()) return(-1);
+ chmod(scorefile,0660);
+ return(0);
+ }
+
+/*
+ * hashewon() Function to return 1 if player has won a game before, else 0
+ *
+ * This function also sets c[HARDGAME] to appropriate value -- 0 if not a
+ * winner, otherwise the next level of difficulty listed in the winners
+ * scoreboard. This function also sets outstanding_taxes to the value in
+ * the winners scoreboard.
+ */
+hashewon()
+ {
+ register int i;
+ c[HARDGAME] = 0;
+ if (readboard() < 0) return(0); /* can't find scoreboard */
+ for (i=0; i<SCORESIZE; i++) /* search through winners scoreboard */
+ if (winr[i].suid == userid)
+ if (winr[i].score > 0)
+ {
+ c[HARDGAME]=winr[i].hardlev+1; outstanding_taxes=winr[i].taxes;
+ return(1);
+ }
+ return(0);
+ }
+
+/*
+ * long paytaxes(x) Function to pay taxes if any are due
+ *
+ * Enter with the amount (in gp) to pay on the taxes.
+ * Returns amount actually paid.
+ */
+long paytaxes(x)
+ long x;
+ {
+ register int i;
+ register long amt;
+ if (x<0) return(0L);
+ if (readboard()<0) return(0L);
+ for (i=0; i<SCORESIZE; i++)
+ if (winr[i].suid == userid) /* look for players winning entry */
+ if (winr[i].score>0) /* search for a winning entry for the player */
+ {
+ amt = winr[i].taxes;
+ if (x < amt) amt=x; /* don't overpay taxes (Ughhhhh) */
+ winr[i].taxes -= amt;
+ outstanding_taxes -= amt;
+ if (writeboard()<0) return(0);
+ return(amt);
+ }
+ return(0L); /* couldn't find user on winning scoreboard */
+ }
+
+/*
+ * winshou() Subroutine to print out the winning scoreboard
+ *
+ * Returns the number of players on scoreboard that were shown
+ */
+winshou()
+ {
+ register struct wscofmt *p;
+ register int i,j,count;
+ for (count=j=i=0; i<SCORESIZE; i++) /* is there anyone on the scoreboard? */
+ if (winr[i].score != 0)
+ { j++; break; }
+ if (j)
+ {
+ lprcat("\n Score Difficulty Time Needed Larn Winners List\n");
+
+ for (i=0; i<SCORESIZE; i++) /* this loop is needed to print out the */
+ for (j=0; j<SCORESIZE; j++) /* winners in order */
+ {
+ p = &winr[j]; /* pointer to the scoreboard entry */
+ if (p->order == i)
+ {
+ if (p->score)
+ {
+ count++;
+ lprintf("%10d %2d %5d Mobuls %s \n",
+ (long)p->score,(long)p->hardlev,(long)p->timeused,p->who);
+ }
+ break;
+ }
+ }
+ }
+ return(count); /* return number of people on scoreboard */
+ }
+
+/*
+ * shou(x) Subroutine to print out the non-winners scoreboard
+ * int x;
+ *
+ * Enter with 0 to list the scores, enter with 1 to list inventories too
+ * Returns the number of players on scoreboard that were shown
+ */
+shou(x)
+ int x;
+ {
+ register int i,j,n,k;
+ int count;
+ for (count=j=i=0; i<SCORESIZE; i++) /* is the scoreboard empty? */
+ if (sco[i].score!= 0)
+ { j++; break; }
+ if (j)
+ {
+ lprcat("\n Score Difficulty Larn Visitor Log\n");
+ for (i=0; i<SCORESIZE; i++) /* be sure to print them out in order */
+ for (j=0; j<SCORESIZE; j++)
+ if (sco[j].order == i)
+ {
+ if (sco[j].score)
+ {
+ count++;
+ lprintf("%10d %2d %s ",
+ (long)sco[j].score,(long)sco[j].hardlev,sco[j].who);
+ if (sco[j].what < 256) lprintf("killed by a %s",monster[sco[j].what].name);
+ else lprintf("%s",whydead[sco[j].what - 256]);
+ if (x != 263) lprintf(" on %s",levelname[sco[j].level]);
+ if (x)
+ {
+ for (n=0; n<26; n++) { iven[n]=sco[j].sciv[n][0]; ivenarg[n]=sco[j].sciv[n][1]; }
+ for (k=1; k<99; k++)
+ for (n=0; n<26; n++)
+ if (k==iven[n]) { srcount=0; show3(n); }
+ lprcat("\n\n");
+ }
+ else lprc('\n');
+ }
+ j=SCORESIZE;
+ }
+ }
+ return(count); /* return the number of players just shown */
+ }
+
+/*
+ * showscores() Function to show the scoreboard on the terminal
+ *
+ * Returns nothing of value
+ */
+static char esb[] = "The scoreboard is empty.\n";
+showscores()
+ {
+ register int i,j;
+ lflush(); lcreat((char*)0); if (readboard()<0) return;
+ i=winshou(); j=shou(0);
+ if (i+j == 0) lprcat(esb); else lprc('\n');
+ lflush();
+ }
+
+/*
+ * showallscores() Function to show scores and the iven lists that go with them
+ *
+ * Returns nothing of value
+ */
+showallscores()
+ {
+ register int i,j;
+ lflush(); lcreat((char*)0); if (readboard()<0) return;
+ c[WEAR] = c[WIELD] = c[SHIELD] = -1; /* not wielding or wearing anything */
+ for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
+ for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
+ i=winshou(); j=shou(1);
+ if (i+j==0) lprcat(esb); else lprc('\n');
+ lflush();
+ }
+
+/*
+ * sortboard() Function to sort the scoreboard
+ *
+ * Returns 0 if no sorting done, else returns 1
+ */
+sortboard()
+ {
+ register int i,j,pos;
+ long jdat;
+ for (i=0; i<SCORESIZE; i++) sco[i].order = winr[i].order = -1;
+ pos=0; while (pos < SCORESIZE)
+ {
+ jdat=0;
+ for (i=0; i<SCORESIZE; i++)
+ if ((sco[i].order < 0) && (sco[i].score >= jdat))
+ { j=i; jdat=sco[i].score; }
+ sco[j].order = pos++;
+ }
+ pos=0; while (pos < SCORESIZE)
+ {
+ jdat=0;
+ for (i=0; i<SCORESIZE; i++)
+ if ((winr[i].order < 0) && (winr[i].score >= jdat))
+ { j=i; jdat=winr[i].score; }
+ winr[j].order = pos++;
+ }
+ return(1);
+ }
+
+/*
+ * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard
+ * int score, winner, whyded;
+ * char *whoo;
+ *
+ * Enter with the total score in gp in score, players name in whoo,
+ * died() reason # in whyded, and TRUE/FALSE in winner if a winner
+ * ex. newscore(1000, "player 1", 32, 0);
+ */
+newscore(score, whoo, whyded, winner)
+ long score;
+ int winner, whyded;
+ char *whoo;
+ {
+ register int i;
+ long taxes;
+ if (readboard() < 0) return; /* do the scoreboard */
+ /* if a winner then delete all non-winning scores */
+ if (cheat) winner=0; /* if he cheated, don't let him win */
+ if (winner)
+ {
+ for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) sco[i].score=0;
+ taxes = score*TAXRATE;
+ score += 100000*c[HARDGAME]; /* bonus for winning */
+ /* if he has a slot on the winning scoreboard update it if greater score */
+ for (i=0; i<SCORESIZE; i++) if (winr[i].suid == userid)
+ { new1sub(score,i,whoo,taxes); return; }
+ /* he had no entry. look for last entry and see if he has a greater score */
+ for (i=0; i<SCORESIZE; i++) if (winr[i].order == SCORESIZE-1)
+ { new1sub(score,i,whoo,taxes); return; }
+ }
+ else if (!cheat) /* for not winning scoreboard */
+ {
+ /* if he has a slot on the scoreboard update it if greater score */
+ for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid)
+ { new2sub(score,i,whoo,whyded); return; }
+ /* he had no entry. look for last entry and see if he has a greater score */
+ for (i=0; i<SCORESIZE; i++) if (sco[i].order == SCORESIZE-1)
+ { new2sub(score,i,whoo,whyded); return; }
+ }
+ }
+
+/*
+ * new1sub(score,i,whoo,taxes) Subroutine to put player into a
+ * int score,i,whyded,taxes; winning scoreboard entry if his score
+ * char *whoo; is high enough
+ *
+ * Enter with the total score in gp in score, players name in whoo,
+ * died() reason # in whyded, and TRUE/FALSE in winner if a winner
+ * slot in scoreboard in i, and the tax bill in taxes.
+ * Returns nothing of value
+ */
+new1sub(score,i,whoo,taxes)
+ long score,taxes;
+ int i;
+ char *whoo;
+ {
+ register struct wscofmt *p;
+ p = &winr[i];
+ p->taxes += taxes;
+ if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
+ {
+ strcpy(p->who,whoo); p->score=score;
+ p->hardlev=c[HARDGAME]; p->suid=userid;
+ p->timeused=gtime/100;
+ }
+ }
+
+/*
+ * new2sub(score,i,whoo,whyded) Subroutine to put player into a
+ * int score,i,whyded,taxes; non-winning scoreboard entry if his
+ * char *whoo; score is high enough
+ *
+ * Enter with the total score in gp in score, players name in whoo,
+ * died() reason # in whyded, and slot in scoreboard in i.
+ * Returns nothing of value
+ */
+new2sub(score,i,whoo,whyded)
+ long score;
+ int i,whyded;
+ char *whoo;
+ {
+ register int j;
+ register struct scofmt *p;
+ p = &sco[i];
+ if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
+ {
+ strcpy(p->who,whoo); p->score=score;
+ p->what=whyded; p->hardlev=c[HARDGAME];
+ p->suid=userid; p->level=level;
+ for (j=0; j<26; j++)
+ { p->sciv[j][0]=iven[j]; p->sciv[j][1]=ivenarg[j]; }
+ }
+ }
+
+/*
+ * died(x) Subroutine to record who played larn, and what the score was
+ * int x;
+ *
+ * if x < 0 then don't show scores
+ * died() never returns! (unless c[LIFEPROT] and a reincarnatable death!)
+ *
+ * < 256 killed by the monster number
+ * 256 quit
+ * 257 suspended
+ * 258 self - annihilated
+ * 259 shot by an arrow
+ * 260 hit by a dart
+ * 261 fell into a pit
+ * 262 fell into a bottomless pit
+ * 263 a winner
+ * 264 trapped in solid rock
+ * 265 killed by a missing save file
+ * 266 killed by an old save file
+ * 267 caught by the greedy cheater checker trap
+ * 268 killed by a protected save file
+ * 269 killed his family and killed himself
+ * 270 erased by a wayward finger
+ * 271 fell through a bottomless trap door
+ * 272 fell through a trap door
+ * 273 drank some poisonous water
+ * 274 fried by an electric shock
+ * 275 slipped on a volcano shaft
+ * 276 killed by a stupid act of frustration
+ * 277 attacked by a revolting demon
+ * 278 hit by his own magic
+ * 279 demolished by an unseen attacker
+ * 280 fell into the dreadful sleep
+ * 281 killed by an exploding chest
+ * 282 killed by a missing maze data file
+ * 283 killed by a sphere of annihilation
+ * 284 died a post mortem death
+ * 285 malloc() failure
+ * 300 quick quit -- don't put on scoreboard
+ */
+
+static int scorerror;
+died(x)
+ int x;
+ {
+ register int f,win;
+ char ch,*mod;
+ long zzz,i;
+ struct tms cputime;
+ if (c[LIFEPROT]>0) /* if life protection */
+ {
+ switch((x>0) ? x : -x)
+ {
+ case 256: case 257: case 262: case 263: case 265: case 266:
+ case 267: case 268: case 269: case 271: case 282: case 284:
+ case 285: case 300: goto invalid; /* can't be saved */
+ };
+ --c[LIFEPROT]; c[HP]=1; --c[CONSTITUTION];
+ cursors(); lprcat("\nYou feel wiiieeeeerrrrrd all over! "); beep();
+ lflush(); sleep(4);
+ return; /* only case where died() returns */
+ }
+invalid:
+ clearvt100(); lflush(); f=0;
+ if (ckpflag) unlink(ckpfile); /* remove checkpoint file if used */
+ if (x<0) { f++; x = -x; } /* if we are not to display the scores */
+ if ((x == 300) || (x == 257)) exit(); /* for quick exit or saved game */
+ if (x == 263) win = 1; else win = 0;
+ c[GOLD] += c[BANKACCOUNT]; c[BANKACCOUNT] = 0;
+ /* now enter the player at the end of the scoreboard */
+ newscore(c[GOLD], logname, x, win);
+ diedsub(x); /* print out the score line */ lflush();
+
+ set_score_output();
+ if ((wizard == 0) && (c[GOLD] > 0)) /* wizards can't score */
+ {
+#ifndef NOLOG
+ if (lappend(logfile)<0) /* append to file */
+ {
+ if (lcreat(logfile)<0) /* and can't create new log file */
+ {
+ lcreat((char*)0);
+ lprcat("\nCan't open record file: I can't post your score.\n");
+ sncbr(); resetscroll(); lflush(); exit();
+ }
+ chmod(logfile,0660);
+ }
+ strcpy(logg.who,loginname);
+ logg.score = c[GOLD]; logg.diff = c[HARDGAME];
+ if (x < 256)
+ {
+ ch = *monster[x].name;
+ if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
+ mod="an"; else mod="a";
+ sprintf(logg.what,"killed by %s %s",mod,monster[x].name);
+ }
+ else sprintf(logg.what,"%s",whydead[x - 256]);
+ logg.cavelev=level;
+ time(&zzz); /* get cpu time -- write out score info */
+ logg.diedtime=zzz;
+#ifdef EXTRA
+ times(&cputime); /* get cpu time -- write out score info */
+ logg.cputime = i = (cputime.tms_utime + cputime.tms_stime)/60 + c[CPUTIME];
+ logg.lev=c[LEVEL]; logg.ac=c[AC];
+ logg.hpmax=c[HPMAX]; logg.hp=c[HP];
+ logg.elapsedtime=(zzz-initialtime+59)/60;
+ logg.usage=(10000*i)/(zzz-initialtime);
+ logg.bytin=c[BYTESIN]; logg.bytout=c[BYTESOUT];
+ logg.moves=c[MOVESMADE]; logg.spused=c[SPELLSCAST];
+ logg.killed=c[MONSTKILLED];
+#endif
+ lwrite((char*)&logg,sizeof(struct log_fmt)); lwclose();
+#endif NOLOG
+
+/* now for the scoreboard maintenance -- not for a suspended game */
+ if (x != 257)
+ {
+ if (sortboard()) scorerror = writeboard();
+ }
+ }
+ if ((x==256) || (x==257) || (f != 0)) exit();
+ if (scorerror == 0) showscores(); /* if we updated the scoreboard */
+ if (x == 263) mailbill(); exit();
+ }
+
+/*
+ * diedsub(x) Subroutine to print out the line showing the player when he is killed
+ * int x;
+ */
+diedsub(x)
+int x;
+ {
+ register char ch,*mod;
+ lprintf("Score: %d, Diff: %d, %s ",(long)c[GOLD],(long)c[HARDGAME],logname);
+ if (x < 256)
+ {
+ ch = *monster[x].name;
+ if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
+ mod="an"; else mod="a";
+ lprintf("killed by %s %s",mod,monster[x].name);
+ }
+ else lprintf("%s",whydead[x - 256]);
+ if (x != 263) lprintf(" on %s\n",levelname[level]); else lprc('\n');
+ }
+
+/*
+ * diedlog() Subroutine to read a log file and print it out in ascii format
+ */
+diedlog()
+ {
+ register int n;
+ register char *p;
+ struct stat stbuf;
+ lcreat((char*)0);
+ if (lopen(logfile)<0)
+ {
+ lprintf("Can't locate log file <%s>\n",logfile);
+ return;
+ }
+ if (fstat(fd,&stbuf) < 0)
+ {
+ lprintf("Can't stat log file <%s>\n",logfile);
+ return;
+ }
+ for (n=stbuf.st_size/sizeof(struct log_fmt); n>0; --n)
+ {
+ lrfill((char*)&logg,sizeof(struct log_fmt));
+ p = ctime(&logg.diedtime); p[16]='\n'; p[17]=0;
+ lprintf("Score: %d, Diff: %d, %s %s on %d at %s",(long)(logg.score),(long)(logg.diff),logg.who,logg.what,(long)(logg.cavelev),p+4);
+#ifdef EXTRA
+ if (logg.moves<=0) logg.moves=1;
+ lprintf(" Experience Level: %d, AC: %d, HP: %d/%d, Elapsed Time: %d minutes\n",(long)(logg.lev),(long)(logg.ac),(long)(logg.hp),(long)(logg.hpmax),(long)(logg.elapsedtime));
+ lprintf(" CPU time used: %d seconds, Machine usage: %d.%02d%%\n",(long)(logg.cputime),(long)(logg.usage/100),(long)(logg.usage%100));
+ lprintf(" BYTES in: %d, out: %d, moves: %d, deaths: %d, spells cast: %d\n",(long)(logg.bytin),(long)(logg.bytout),(long)(logg.moves),(long)(logg.killed),(long)(logg.spused));
+ lprintf(" out bytes per move: %d, time per move: %d ms\n",(long)(logg.bytout/logg.moves),(long)((logg.cputime*1000)/logg.moves));
+#endif
+ }
+ lflush(); lrclose(); return;
+ }
+
+#ifndef UIDSCORE
+/*
+ * getplid(name) Function to get players id # from id file
+ *
+ * Enter with the name of the players character in name.
+ * Returns the id # of the players character, or -1 if failure.
+ * This routine will try to find the name in the id file, if its not there,
+ * it will try to make a new entry in the file. Only returns -1 if can't
+ * find him in the file, and can't make a new entry in the file.
+ * Format of playerids file:
+ * Id # in ascii \n character name \n
+ */
+static int havepid= -1; /* playerid # if previously done */
+getplid(nam)
+ char *nam;
+ {
+ int fd7,high=999,no;
+ register char *p,*p2;
+ char name[80];
+ if (havepid != -1) return(havepid); /* already did it */
+ lflush(); /* flush any pending I/O */
+ sprintf(name,"%s\n",nam); /* append a \n to name */
+ if (lopen(playerids) < 0) /* no file, make it */
+ {
+ if ((fd7=creat(playerids,0666)) < 0) return(-1); /* can't make it */
+ close(fd7); goto addone; /* now append new playerid record to file */
+ }
+ for (;;) /* now search for the name in the player id file */
+ {
+ p = lgetl(); if (p==NULL) break; /* EOF? */
+ no = atoi(p); /* the id # */
+ p2= lgetl(); if (p2==NULL) break; /* EOF? */
+ if (no>high) high=no; /* accumulate highest id # */
+ if (strcmp(p2,name)==0) /* we found him */
+ {
+ return(no); /* his id number */
+ }
+ }
+ lrclose();
+ /* if we get here, we didn't find him in the file -- put him there */
+addone:
+ if (lappend(playerids) < 0) return(-1); /* can't open file for append */
+ lprintf("%d\n%s",(long)++high,name); /* new id # and name */
+ lwclose();
+ lcreat((char*)0); /* re-open terminal channel */
+ return(high);
+ }
+#endif UIDSCORE
+
diff --git a/larn/signal.c b/larn/signal.c
new file mode 100644
index 00000000..60bd6ce1
--- /dev/null
+++ b/larn/signal.c
@@ -0,0 +1,148 @@
+#include <signal.h>
+#include "header.h" /* "Larn is copyrighted 1986 by Noah Morgan.\n" */
+#define BIT(a) (1<<((a)-1))
+extern char savefilename[],wizard,predostuff,nosignal;
+static s2choose() /* text to be displayed if ^C during intro screen */
+ {
+ cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold();
+ lprcat(" to continue: "); lflush();
+ }
+
+static void
+cntlc() /* what to do for a ^C */
+ {
+ if (nosignal) return; /* don't do anything if inhibited */
+ signal(SIGQUIT,SIG_IGN); signal(SIGINT,SIG_IGN);
+ quit(); if (predostuff==1) s2choose(); else showplayer();
+ lflush();
+ signal(SIGQUIT,cntlc); signal(SIGINT,cntlc);
+ }
+
+/*
+ * subroutine to save the game if a hangup signal
+ */
+static void
+sgam()
+ {
+ savegame(savefilename); wizard=1; died(-257); /* hangup signal */
+ }
+
+#ifdef SIGTSTP
+static void
+tstop() /* control Y */
+ {
+ if (nosignal) return; /* nothing if inhibited */
+ lcreat((char*)0); clearvt100(); lflush(); signal(SIGTSTP,SIG_DFL);
+#ifdef SIGVTALRM
+ /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
+ sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
+#endif
+ kill(getpid(),SIGTSTP);
+
+ setupvt100(); signal(SIGTSTP,tstop);
+ if (predostuff==1) s2choose(); else drawscreen();
+ showplayer(); lflush();
+ }
+#endif SIGTSTP
+
+/*
+ * subroutine to issue the needed signal traps called from main()
+ */
+static void sigpanic();
+static void sigill() { sigpanic(SIGILL); }
+static void sigtrap() { sigpanic(SIGTRAP); }
+static void sigiot() { sigpanic(SIGIOT); }
+static void sigemt() { sigpanic(SIGEMT); }
+static void sigfpe() { sigpanic(SIGFPE); }
+static void sigbus() { sigpanic(SIGBUS); }
+static void sigsegv() { sigpanic(SIGSEGV); }
+static void sigsys() { sigpanic(SIGSYS); }
+static void sigpipe() { sigpanic(SIGPIPE); }
+static void sigterm() { sigpanic(SIGTERM); }
+sigsetup()
+ {
+ signal(SIGQUIT, cntlc); signal(SIGINT, cntlc);
+ signal(SIGKILL, SIG_IGN); signal(SIGHUP, sgam);
+ signal(SIGILL, sigill); signal(SIGTRAP, sigtrap);
+ signal(SIGIOT, sigiot); signal(SIGEMT, sigemt);
+ signal(SIGFPE, sigfpe); signal(SIGBUS, sigbus);
+ signal(SIGSEGV, sigsegv); signal(SIGSYS, sigsys);
+ signal(SIGPIPE, sigpipe); signal(SIGTERM, sigterm);
+#ifdef SIGTSTP
+ signal(SIGTSTP,tstop); signal(SIGSTOP,tstop);
+#endif SIGTSTP
+ }
+
+#ifdef BSD /* for BSD UNIX? */
+
+static char *signame[NSIG] = { "",
+"SIGHUP", /* 1 hangup */
+"SIGINT", /* 2 interrupt */
+"SIGQUIT", /* 3 quit */
+"SIGILL", /* 4 illegal instruction (not reset when caught) */
+"SIGTRAP", /* 5 trace trap (not reset when caught) */
+"SIGIOT", /* 6 IOT instruction */
+"SIGEMT", /* 7 EMT instruction */
+"SIGFPE", /* 8 floating point exception */
+"SIGKILL", /* 9 kill (cannot be caught or ignored) */
+"SIGBUS", /* 10 bus error */
+"SIGSEGV", /* 11 segmentation violation */
+"SIGSYS", /* 12 bad argument to system call */
+"SIGPIPE", /* 13 write on a pipe with no one to read it */
+"SIGALRM", /* 14 alarm clock */
+"SIGTERM", /* 15 software termination signal from kill */
+"SIGURG", /* 16 urgent condition on IO channel */
+"SIGSTOP", /* 17 sendable stop signal not from tty */
+"SIGTSTP", /* 18 stop signal from tty */
+"SIGCONT", /* 19 continue a stopped process */
+"SIGCHLD", /* 20 to parent on child stop or exit */
+"SIGTTIN", /* 21 to readers pgrp upon background tty read */
+"SIGTTOU", /* 22 like TTIN for output if (tp->t_local&LTOSTOP) */
+"SIGIO", /* 23 input/output possible signal */
+"SIGXCPU", /* 24 exceeded CPU time limit */
+"SIGXFSZ", /* 25 exceeded file size limit */
+"SIGVTALRM",/* 26 virtual time alarm */
+"SIGPROF", /* 27 profiling time alarm */
+"","","","" };
+
+#else BSD /* for system V? */
+
+static char *signame[NSIG] = { "",
+"SIGHUP", /* 1 hangup */
+"SIGINT", /* 2 interrupt */
+"SIGQUIT", /* 3 quit */
+"SIGILL", /* 4 illegal instruction (not reset when caught) */
+"SIGTRAP", /* 5 trace trap (not reset when caught) */
+"SIGIOT", /* 6 IOT instruction */
+"SIGEMT", /* 7 EMT instruction */
+"SIGFPE", /* 8 floating point exception */
+"SIGKILL", /* 9 kill (cannot be caught or ignored) */
+"SIGBUS", /* 10 bus error */
+"SIGSEGV", /* 11 segmentation violation */
+"SIGSYS", /* 12 bad argument to system call */
+"SIGPIPE", /* 13 write on a pipe with no one to read it */
+"SIGALRM", /* 14 alarm clock */
+"SIGTERM", /* 15 software termination signal from kill */
+"SIGUSR1", /* 16 user defines signal 1 */
+"SIGUSR2", /* 17 user defines signal 2 */
+"SIGCLD", /* 18 child death */
+"SIGPWR", /* 19 power fail */
+"","","","","","","","","","","","" };
+
+#endif BSD
+
+/*
+ * routine to process a fatal error signal
+ */
+static void
+sigpanic(sig)
+ int sig;
+ {
+ char buf[128];
+ signal(sig,SIG_DFL);
+ sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]);
+ write(2,buf,strlen(buf)); sleep(2);
+ sncbr();
+ savegame(savefilename);
+ kill(getpid(),sig); /* this will terminate us */
+ }
diff --git a/larn/store.c b/larn/store.c
new file mode 100644
index 00000000..904cfade
--- /dev/null
+++ b/larn/store.c
@@ -0,0 +1,691 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)store.c 5.4 (Berkeley) 5/13/91";
+#endif /* not lint */
+
+/* store.c Larn is copyrighted 1986 by Noah Morgan. */
+#include "header.h"
+static int dndcount=0,dnditm=0;
+
+/* this is the data for the stuff in the dnd store */
+int maxitm=83; /* number of items in the dnd inventory table */
+struct _itm itm[90] = {
+/*cost memory iven name iven arg how
+ gp pointer iven[] ivenarg[] many */
+
+{ 2, 0, OLEATHER, 0, 3 },
+{ 10, 0, OSTUDLEATHER, 0, 2 },
+{ 40, 0, ORING, 0, 2 },
+{ 85, 0, OCHAIN, 0, 2 },
+{ 220, 0, OSPLINT, 0, 1 },
+{ 400, 0, OPLATE, 0, 1 },
+{ 900, 0, OPLATEARMOR, 0, 1 },
+{ 2600, 0, OSSPLATE, 0, 1 },
+{ 150, 0, OSHIELD, 0, 1 },
+
+/*cost memory iven name iven arg how
+ gp pointer iven[] ivenarg[] many */
+
+{ 2, 0, ODAGGER, 0, 3 },
+{ 20, 0, OSPEAR, 0, 3 },
+{ 80, 0, OFLAIL, 0, 2 },
+{ 150, 0, OBATTLEAXE, 0, 2 },
+{ 450, 0, OLONGSWORD, 0, 2 },
+{ 1000, 0, O2SWORD, 0, 2 },
+{ 5000, 0, OSWORD, 0, 1 },
+{ 16500, 0, OLANCE, 0, 1 },
+{ 6000, 0, OSWORDofSLASHING, 0, 0 },
+{ 10000, 0, OHAMMER, 0, 0 },
+
+/*cost memory iven name iven arg how
+ gp pointer iven[] ivenarg[] many */
+
+{ 150, 0, OPROTRING, 1, 1 },
+{ 85, 0, OSTRRING, 1, 1 },
+{ 120, 0, ODEXRING, 1, 1 },
+{ 120, 0, OCLEVERRING, 1, 1 },
+{ 180, 0, OENERGYRING, 0, 1 },
+{ 125, 0, ODAMRING, 0, 1 },
+{ 220, 0, OREGENRING, 0, 1 },
+{ 1000, 0, ORINGOFEXTRA, 0, 1 },
+
+{ 280, 0, OBELT, 0, 1 },
+
+{ 400, 0, OAMULET, 0, 1 },
+
+{ 6500, 0, OORBOFDRAGON, 0, 0 },
+{ 5500, 0, OSPIRITSCARAB, 0, 0 },
+{ 5000, 0, OCUBEofUNDEAD, 0, 0 },
+{ 6000, 0, ONOTHEFT, 0, 0 },
+
+{ 590, 0, OCHEST, 6, 1 },
+{ 200, 0, OBOOK, 8, 1 },
+{ 10, 0, OCOOKIE, 0, 3 },
+
+/*cost memory iven name iven arg how
+ gp pointer iven[] ivenarg[] many */
+
+{ 20, potionname, OPOTION, 0, 6 },
+{ 90, potionname, OPOTION, 1, 5 },
+{ 520, potionname, OPOTION, 2, 1 },
+{ 100, potionname, OPOTION, 3, 2 },
+{ 50, potionname, OPOTION, 4, 2 },
+{ 150, potionname, OPOTION, 5, 2 },
+{ 70, potionname, OPOTION, 6, 1 },
+{ 30, potionname, OPOTION, 7, 7 },
+{ 200, potionname, OPOTION, 8, 1 },
+{ 50, potionname, OPOTION, 9, 1 },
+{ 80, potionname, OPOTION, 10, 1 },
+
+/*cost memory iven name iven arg how
+ gp pointer iven[] ivenarg[] many */
+
+{ 30, potionname, OPOTION, 11, 3 },
+{ 20, potionname, OPOTION, 12, 5 },
+{ 40, potionname, OPOTION, 13, 3 },
+{ 35, potionname, OPOTION, 14, 2 },
+{ 520, potionname, OPOTION, 15, 1 },
+{ 90, potionname, OPOTION, 16, 2 },
+{ 200, potionname, OPOTION, 17, 2 },
+{ 220, potionname, OPOTION, 18, 4 },
+{ 80, potionname, OPOTION, 19, 6 },
+{ 370, potionname, OPOTION, 20, 3 },
+{ 50, potionname, OPOTION, 22, 1 },
+{ 150, potionname, OPOTION, 23, 3 },
+
+/*cost memory iven name iven arg how
+ gp pointer iven[] ivenarg[] many */
+
+{ 100, scrollname, OSCROLL, 0, 2 },
+{ 125, scrollname, OSCROLL, 1, 2 },
+{ 60, scrollname, OSCROLL, 2, 4 },
+{ 10, scrollname, OSCROLL, 3, 4 },
+{ 100, scrollname, OSCROLL, 4, 3 },
+{ 200, scrollname, OSCROLL, 5, 2 },
+{ 110, scrollname, OSCROLL, 6, 1 },
+{ 500, scrollname, OSCROLL, 7, 2 },
+{ 200, scrollname, OSCROLL, 8, 2 },
+{ 250, scrollname, OSCROLL, 9, 4 },
+{ 20, scrollname, OSCROLL, 10, 5 },
+{ 30, scrollname, OSCROLL, 11, 3 },
+
+/*cost memory iven name iven arg how
+ gp pointer iven[] ivenarg[] many */
+
+{ 340, scrollname, OSCROLL, 12, 1 },
+{ 340, scrollname, OSCROLL, 13, 1 },
+{ 300, scrollname, OSCROLL, 14, 2 },
+{ 400, scrollname, OSCROLL, 15, 2 },
+{ 500, scrollname, OSCROLL, 16, 2 },
+{ 1000, scrollname, OSCROLL, 17, 1 },
+{ 500, scrollname, OSCROLL, 18, 1 },
+{ 340, scrollname, OSCROLL, 19, 2 },
+{ 220, scrollname, OSCROLL, 20, 3 },
+{ 3900, scrollname, OSCROLL, 21, 0 },
+{ 610, scrollname, OSCROLL, 22, 1 },
+{ 3000, scrollname, OSCROLL, 23, 0 }
+ };
+
+/*
+ function for the dnd store
+ */
+dnd_2hed()
+ {
+ lprcat("Welcome to the Larn Thrift Shoppe. We stock many items explorers find useful\n");
+ lprcat(" in their adventures. Feel free to browse to your hearts content.\n");
+ lprcat("Also be advised, if you break 'em, you pay for 'em.");
+ }
+
+static void dnditem();
+
+dnd_hed()
+ {
+ register int i;
+ for (i=dnditm; i<26+dnditm; i++) dnditem(i);
+ cursor(50,18); lprcat("You have ");
+ }
+
+static void
+handsfull()
+{
+ lprcat("\nYou can't carry anything more!");
+ lflush();
+ nap(2200);
+}
+
+static void
+outofstock()
+{
+ lprcat("\nSorry, but we are out of that item.");
+ lflush();
+ nap(2200);
+}
+
+static void nogold()
+{
+ lprcat("\nYou don't have enough gold to pay for that!");
+ lflush();
+ nap(2200);
+}
+
+dndstore()
+ {
+ register int i;
+ dnditm = 0;
+ nosignal = 1; /* disable signals */
+ clear(); dnd_2hed();
+ if (outstanding_taxes>0)
+ {
+ lprcat("\n\nThe Larn Revenue Service has ordered us to not do business with tax evaders.\n"); beep();
+ lprintf("They have also told us that you owe %d gp in back taxes, and as we must\n",(long)outstanding_taxes);
+ lprcat("comply with the law, we cannot serve you at this time. Soo Sorry.\n");
+ cursors();
+ lprcat("\nPress "); standout("escape"); lprcat(" to leave: "); lflush();
+ i=0;
+ while (i!='\33') i=getchar();
+ drawscreen(); nosignal = 0; /* enable signals */ return;
+ }
+
+ dnd_hed();
+ while (1)
+ {
+ cursor(59,18); lprintf("%d gold pieces",(long)c[GOLD]);
+ cltoeoln(); cl_dn(1,20); /* erase to eod */
+ lprcat("\nEnter your transaction ["); standout("space");
+ lprcat(" for more, "); standout("escape");
+ lprcat(" to leave]? ");
+ i=0;
+ while ((i<'a' || i>'z') && (i!=' ') && (i!='\33') && (i!=12)) i=getchar();
+ if (i==12) { clear(); dnd_2hed(); dnd_hed(); }
+ else if (i=='\33')
+ { drawscreen(); nosignal = 0; /* enable signals */ return; }
+ else if (i==' ')
+ {
+ cl_dn(1,4);
+ if ((dnditm += 26) >= maxitm) dnditm=0; dnd_hed();
+ }
+ else
+ { /* buy something */
+ lprc(i); /* echo the byte */
+ i += dnditm - 'a';
+ if (i>=maxitm) outofstock(); else
+ if (itm[i].qty <= 0) outofstock(); else
+ if (pocketfull()) handsfull(); else
+ if (c[GOLD] < itm[i].price*10) nogold(); else
+ {
+ if (itm[i].mem != 0) *itm[i].mem[itm[i].arg] = ' ';
+ c[GOLD] -= itm[i].price*10;
+ itm[i].qty--; take(itm[i].obj,itm[i].arg);
+ if (itm[i].qty==0) dnditem(i); nap(1001);
+ }
+ }
+
+ }
+ }
+
+/*
+ dnditem(index)
+
+ to print the item list; used in dndstore() enter with the index into itm
+ */
+static void
+dnditem(i)
+ register int i;
+ {
+ register int j,k;
+ if (i >= maxitm) return;
+ cursor( (j=(i&1)*40+1) , (k=((i%26)>>1)+5) );
+ if (itm[i].qty == 0) { lprintf("%39s",""); return; }
+ lprintf("%c) ",(i%26)+'a');
+ if (itm[i].obj == OPOTION)
+ { lprcat("potion of "); lprintf("%s",&potionname[itm[i].arg][1]); }
+ else if (itm[i].obj == OSCROLL)
+ { lprcat("scroll of "); lprintf("%s",&scrollname[itm[i].arg][1]); }
+ else lprintf("%s",objectname[itm[i].obj]);
+ cursor( j+31,k ); lprintf("%6d",(long)(itm[i].price*10));
+ }
+
+
+/*
+ for the college of larn
+ */
+char course[26]={0}; /* the list of courses taken */
+char coursetime[] = { 10, 15, 10, 20, 10, 10, 10, 5 };
+/*
+ function to display the header info for the school
+ */
+sch_hed()
+ {
+ clear();
+ lprcat("The College of Larn offers the exciting opportunity of higher education to\n");
+ lprcat("all inhabitants of the caves. Here is a list of the class schedule:\n\n\n");
+ lprcat("\t\t Course Name \t Time Needed\n\n");
+
+ if (course[0]==0) lprcat("\t\ta) Fighters Training I 10 mobuls"); /*line 7 of crt*/
+ lprc('\n');
+ if (course[1]==0) lprcat("\t\tb) Fighters Training II 15 mobuls");
+ lprc('\n');
+ if (course[2]==0) lprcat("\t\tc) Introduction to Wizardry 10 mobuls");
+ lprc('\n');
+ if (course[3]==0) lprcat("\t\td) Applied Wizardry 20 mobuls");
+ lprc('\n');
+ if (course[4]==0) lprcat("\t\te) Behavioral Psychology 10 mobuls");
+ lprc('\n');
+ if (course[5]==0) lprcat("\t\tf) Faith for Today 10 mobuls");
+ lprc('\n');
+ if (course[6]==0) lprcat("\t\tg) Contemporary Dance 10 mobuls");
+ lprc('\n');
+ if (course[7]==0) lprcat("\t\th) History of Larn 5 mobuls");
+
+ lprcat("\n\n\t\tAll courses cost 250 gold pieces.");
+ cursor(30,18);
+ lprcat("You are presently carrying ");
+ }
+
+oschool()
+ {
+ register int i;
+ long time_used;
+ nosignal = 1; /* disable signals */
+ sch_hed();
+ while (1)
+ {
+ cursor(57,18); lprintf("%d gold pieces. ",(long)c[GOLD]); cursors();
+ lprcat("\nWhat is your choice ["); standout("escape");
+ lprcat(" to leave] ? "); yrepcount=0;
+ i=0; while ((i<'a' || i>'h') && (i!='\33') && (i!=12)) i=getchar();
+ if (i==12) { sch_hed(); continue; }
+ else if (i=='\33')
+ { nosignal = 0; drawscreen(); /* enable signals */ return; }
+ lprc(i);
+ if (c[GOLD] < 250) nogold(); else
+ if (course[i-'a'])
+ { lprcat("\nSorry, but that class is filled."); nap(1000); }
+ else
+ if (i <= 'h')
+ {
+ c[GOLD] -= 250; time_used=0;
+ switch(i)
+ {
+ case 'a': c[STRENGTH] += 2; c[CONSTITUTION]++;
+ lprcat("\nYou feel stronger!");
+ cl_line(16,7);
+ break;
+
+ case 'b': if (course[0]==0)
+ {
+ lprcat("\nSorry, but this class has a prerequisite of Fighters Training I");
+ c[GOLD]+=250; time_used= -10000; break;
+ }
+ lprcat("\nYou feel much stronger!");
+ cl_line(16,8);
+ c[STRENGTH] += 2; c[CONSTITUTION] += 2; break;
+
+ case 'c': c[INTELLIGENCE] += 2;
+ lprcat("\nThe task before you now seems more attainable!");
+ cl_line(16,9); break;
+
+ case 'd': if (course[2]==0)
+ {
+ lprcat("\nSorry, but this class has a prerequisite of Introduction to Wizardry");
+ c[GOLD]+=250; time_used= -10000; break;
+ }
+ lprcat("\nThe task before you now seems very attainable!");
+ cl_line(16,10);
+ c[INTELLIGENCE] += 2; break;
+
+ case 'e': c[CHARISMA] += 3;
+ lprcat("\nYou now feel like a born leader!");
+ cl_line(16,11); break;
+
+ case 'f': c[WISDOM] += 2;
+ lprcat("\nYou now feel more confident that you can find the potion in time!");
+ cl_line(16,12); break;
+
+ case 'g': c[DEXTERITY] += 3;
+ lprcat("\nYou feel like dancing!");
+ cl_line(16,13); break;
+
+ case 'h': c[INTELLIGENCE]++;
+ lprcat("\nYour instructor told you that the Eye of Larn is rumored to be guarded\n");
+ lprcat("by a platinum dragon who possesses psionic abilities. ");
+ cl_line(16,14); break;
+ }
+ time_used += coursetime[i-'a']*100;
+ if (time_used > 0)
+ {
+ gtime += time_used;
+ course[i-'a']++; /* remember that he has taken that course */
+ c[HP] = c[HPMAX]; c[SPELLS] = c[SPELLMAX]; /* he regenerated */
+
+ if (c[BLINDCOUNT]) c[BLINDCOUNT]=1; /* cure blindness too! */
+ if (c[CONFUSE]) c[CONFUSE]=1; /* end confusion */
+ adjtime((long)time_used); /* adjust parameters for time change */
+ }
+ nap(1000);
+ }
+ }
+ }
+
+/*
+ * for the first national bank of Larn
+ */
+int lasttime=0; /* last time he was in bank */
+static void banktitle();
+
+obank()
+ {
+ banktitle(" Welcome to the First National Bank of Larn.");
+ }
+obank2()
+ {
+ banktitle("Welcome to the 5th level branch office of the First National Bank of Larn.");
+ }
+static void
+banktitle(str)
+ char *str;
+ {
+ nosignal = 1; /* disable signals */
+ clear(); lprcat(str);
+ if (outstanding_taxes>0)
+ {
+ register int i;
+ lprcat("\n\nThe Larn Revenue Service has ordered that your account be frozen until all\n"); beep();
+ lprintf("levied taxes have been paid. They have also told us that you owe %d gp in\n",(long)outstanding_taxes);
+ lprcat("taxes, and we must comply with them. We cannot serve you at this time. Sorry.\n");
+ lprcat("We suggest you go to the LRS office and pay your taxes.\n");
+ cursors();
+ lprcat("\nPress "); standout("escape"); lprcat(" to leave: "); lflush();
+ i=0;
+ while (i!='\33') i=getchar();
+ drawscreen(); nosignal = 0; /* enable signals */ return;
+ }
+ lprcat("\n\n\tGemstone\t Appraisal\t\tGemstone\t Appraisal");
+ obanksub(); nosignal = 0; /* enable signals */
+ drawscreen();
+ }
+
+/*
+ * function to put interest on your bank account
+ */
+ointerest()
+ {
+ register int i;
+ if (c[BANKACCOUNT]<0) c[BANKACCOUNT] = 0;
+ else if ((c[BANKACCOUNT]>0) && (c[BANKACCOUNT]<500000))
+ {
+ i = (gtime-lasttime)/100; /* # mobuls elapsed */
+ while ((i-- > 0) && (c[BANKACCOUNT]<500000))
+ c[BANKACCOUNT] += c[BANKACCOUNT]/250;
+ if (c[BANKACCOUNT]>500000) c[BANKACCOUNT]=500000; /* interest limit */
+ }
+ lasttime = (gtime/100)*100;
+ }
+
+static short gemorder[26]={0}; /* the reference to screen location for each */
+static long gemvalue[26]={0}; /* the appraisal of the gems */
+obanksub()
+ {
+ unsigned long amt;
+ register int i,k;
+ ointerest(); /* credit any needed interest */
+
+ for (k=i=0; i<26; i++)
+ switch(iven[i])
+ {
+ case OLARNEYE: case ODIAMOND: case OEMERALD:
+ case ORUBY: case OSAPPHIRE:
+
+ if (iven[i]==OLARNEYE)
+ {
+ gemvalue[i]=250000-((gtime*7)/100)*100;
+ if (gemvalue[i]<50000) gemvalue[i]=50000;
+ }
+ else gemvalue[i] = (255&ivenarg[i])*100;
+ gemorder[i]=k;
+ cursor( (k%2)*40+1 , (k>>1)+4 );
+ lprintf("%c) %s",i+'a',objectname[iven[i]]);
+ cursor( (k%2)*40+33 , (k>>1)+4 );
+ lprintf("%5d",(long)gemvalue[i]); k++;
+ };
+ cursor(31,17); lprintf("You have %8d gold pieces in the bank.",(long)c[BANKACCOUNT]);
+ cursor(40,18); lprintf("You have %8d gold pieces",(long)c[GOLD]);
+ if (c[BANKACCOUNT]+c[GOLD] >= 500000)
+ lprcat("\nNote: Larndom law states that only deposits under 500,000gp can earn interest.");
+ while (1)
+ {
+ cl_dn(1,20);
+ lprcat("\nYour wish? [("); standout("d"); lprcat(") deposit, (");
+ standout("w"); lprcat(") withdraw, ("); standout("s");
+ lprcat(") sell a stone, or "); standout("escape"); lprcat("] ");
+ yrepcount=0;
+ i=0; while (i!='d' && i!='w' && i!='s' && i!='\33') i=getchar();
+ switch(i)
+ {
+ case 'd': lprcat("deposit\nHow much? "); amt = readnum((long)c[GOLD]);
+ if (amt<0) { lprcat("\nSorry, but we can't take negative gold!"); nap(2000); amt=0; } else
+ if (amt>c[GOLD])
+ { lprcat(" You don't have that much."); nap(2000); }
+ else { c[GOLD] -= amt; c[BANKACCOUNT] += amt; }
+ break;
+
+ case 'w': lprcat("withdraw\nHow much? "); amt = readnum((long)c[BANKACCOUNT]);
+ if (amt<0) { lprcat("\nSorry, but we don't have any negative gold!"); nap(2000); amt=0; }
+ else if (amt > c[BANKACCOUNT])
+ { lprcat("\nYou don't have that much in the bank!"); nap(2000); }
+ else { c[GOLD] += amt; c[BANKACCOUNT] -= amt; }
+ break;
+
+ case 's': lprcat("\nWhich stone would you like to sell? ");
+ i=0; while ((i<'a' || i>'z') && i!='*') i=getchar();
+ if (i=='*')
+ for (i=0; i<26; i++)
+ {
+ if (gemvalue[i])
+ {
+ c[GOLD]+=gemvalue[i]; iven[i]=0;
+ gemvalue[i]=0; k = gemorder[i];
+ cursor( (k%2)*40+1 , (k>>1)+4 );
+ lprintf("%39s","");
+ }
+ }
+ else
+ {
+ if (gemvalue[i=i-'a']==0)
+ {
+ lprintf("\nItem %c is not a gemstone!",i+'a');
+ nap(2000); break;
+ }
+ c[GOLD]+=gemvalue[i]; iven[i]=0;
+ gemvalue[i]=0; k = gemorder[i];
+ cursor( (k%2)*40+1 , (k>>1)+4 ); lprintf("%39s","");
+ }
+ break;
+
+ case '\33': return;
+ };
+ cursor(40,17); lprintf("%8d",(long)c[BANKACCOUNT]);
+ cursor(49,18); lprintf("%8d",(long)c[GOLD]);
+ }
+ }
+
+/*
+ subroutine to appraise any stone for the bank
+ */
+appraise(gemstone)
+ register int gemstone;
+ {
+ register int j,amt;
+ for (j=0; j<26; j++)
+ if (iven[j]==gemstone)
+ {
+ lprintf("\nI see you have %s",objectname[gemstone]);
+ if (gemstone==OLARNEYE) lprcat(" I must commend you. I didn't think\nyou could get it.");
+ lprcat(" Shall I appraise it for you? "); yrepcount=0;
+ if (getyn()=='y')
+ {
+ lprcat("yes.\n Just one moment please \n"); nap(1000);
+ if (gemstone==OLARNEYE)
+ {
+ amt = 250000-((gtime*7)/100)*100;
+ if (amt<50000) amt=50000;
+ }
+ else amt = (255 & ivenarg[j]) * 100;
+ lprintf("\nI can see this is an excellent stone, It is worth %d",(long)amt);
+ lprcat("\nWould you like to sell it to us? "); yrepcount=0;
+ if (getyn()=='y') { lprcat("yes\n"); c[GOLD]+=amt; iven[j]=0; }
+ else lprcat("no thank you.\n");
+ if (gemstone==OLARNEYE) lprcat("It is, of course, your privilege to keep the stone\n");
+ }
+ else lprcat("no\nO. K.\n");
+ }
+ }
+/*
+ function for the trading post
+ */
+static otradhead()
+ {
+ clear();
+ lprcat("Welcome to the Larn Trading Post. We buy items that explorers no longer find\n");
+ lprcat("useful. Since the condition of the items you bring in is not certain,\n");
+ lprcat("and we incur great expense in reconditioning the items, we usually pay\n");
+ lprcat("only 20% of their value were they to be new. If the items are badly\n");
+ lprcat("damaged, we will pay only 10% of their new value.\n\n");
+ }
+
+otradepost()
+ {
+ register int i,j,value,isub,izarg;
+ dnditm = dndcount = 0;
+ nosignal = 1; /* disable signals */
+ resetscroll(); otradhead();
+ while (1)
+ {
+ lprcat("\nWhat item do you want to sell to us ["); standout("*");
+ lprcat(" for list, or "); standout("escape"); lprcat("] ? ");
+ i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
+ if (i == '\33')
+ { setscroll(); recalc(); drawscreen(); nosignal=0; /* enable signals */ return; }
+ isub = i - 'a'; j=0;
+ if (iven[isub]==OSCROLL) if (scrollname[ivenarg[isub]][0]==0)
+ { j=1; cnsitm(); } /* can't sell unidentified item */
+ if (iven[isub]==OPOTION) if (potionname[ivenarg[isub]][0]==0)
+ { j=1; cnsitm(); } /* can't sell unidentified item */
+ if (!j)
+ if (i=='*') { clear(); qshowstr(); otradhead(); }
+ else if (iven[isub]==0) lprintf("\nYou don't have item %c!",isub+'a');
+ else
+ {
+ for (j=0; j<maxitm; j++)
+ if ((itm[j].obj == iven[isub]) || (iven[isub] == ODIAMOND) || (iven[isub] == ORUBY) || (iven[isub] == OEMERALD) || (iven[isub] == OSAPPHIRE))
+ {
+ srcount=0; show3(isub); /* show what the item was */
+ if ((iven[isub] == ODIAMOND) || (iven[isub] == ORUBY)
+ || (iven[isub] == OEMERALD) || (iven[isub] == OSAPPHIRE))
+ value = 20*ivenarg[isub];
+ else
+ if ((itm[j].obj == OSCROLL) || (itm[j].obj == OPOTION)) value = 2*itm[j+ivenarg[isub]].price;
+ else
+ {
+ izarg=ivenarg[isub]; value = itm[j].price; /* appreciate if a +n object */
+ if (izarg >= 0) value *= 2;
+ while ((izarg-- > 0) && ((value=14*(67+value)/10) < 500000));
+ }
+ lprintf("\nItem (%c) is worth %d gold pieces to us. Do you want to sell it? ",i,(long)value);
+ yrepcount=0;
+ if (getyn()=='y')
+ {
+ lprcat("yes\n"); c[GOLD]+=value;
+ if (c[WEAR] == isub) c[WEAR] = -1;
+ if (c[WIELD] == isub) c[WIELD] = -1;
+ if (c[SHIELD] == isub) c[SHIELD] = -1;
+ adjustcvalues(iven[isub],ivenarg[isub]);
+ iven[isub]=0;
+ }
+ else lprcat("no thanks.\n");
+ j = maxitm+100; /* get out of the inner loop */
+ }
+ if (j <= maxitm+2) lprcat("\nSo sorry, but we are not authorized to accept that item.");
+ }
+ }
+ }
+
+cnsitm()
+ { lprcat("\nSorry, we can't accept unidentified objects."); }
+
+/*
+ * for the Larn Revenue Service
+ */
+olrs()
+ {
+ register int i,first;
+ unsigned long amt;
+ first = nosignal = 1; /* disable signals */
+ clear(); resetscroll(); cursor(1,4);
+ lprcat("Welcome to the Larn Revenue Service district office. How can we help you?");
+ while (1)
+ {
+ if (first) { first=0; goto nxt; }
+ cursors();
+ lprcat("\n\nYour wish? [(");
+ standout("p");
+ lprcat(") pay taxes, or ");
+ standout("escape");
+ lprcat("] "); yrepcount=0;
+ i=0; while (i!='p' && i!='\33') i=getchar();
+ switch(i)
+ {
+ case 'p': lprcat("pay taxes\nHow much? "); amt = readnum((long)c[GOLD]);
+ if (amt<0) { lprcat("\nSorry, but we can't take negative gold\n"); amt=0; } else
+ if (amt>c[GOLD]) lprcat(" You don't have that much.\n");
+ else c[GOLD] -= paytaxes((long)amt);
+ break;
+
+ case '\33': nosignal = 0; /* enable signals */
+ setscroll(); drawscreen(); return;
+ };
+
+nxt: cursor(1,6);
+ if (outstanding_taxes>0)
+ lprintf("You presently owe %d gp in taxes. ",(long)outstanding_taxes);
+ else
+ lprcat("You do not owe us any taxes. ");
+ cursor(1,8);
+ if (c[GOLD]>0)
+ lprintf("You have %6d gp. ",(long)c[GOLD]);
+ else
+ lprcat("You have no gold pieces. ");
+ }
+ }
diff --git a/larn/tok.c b/larn/tok.c
new file mode 100644
index 00000000..ee4039b4
--- /dev/null
+++ b/larn/tok.c
@@ -0,0 +1,218 @@
+/* tok.c Larn is copyrighted 1986 by Noah Morgan. */
+#include <sys/types.h>
+#ifdef SYSV
+#include <fcntl.h>
+#include <termio.h>
+#else SYSV
+#include <sys/ioctl.h>
+#endif SYSV
+#include "header.h"
+
+static char lastok=0;
+int yrepcount=0,dayplay=0;
+#ifndef FLUSHNO
+#define FLUSHNO 5
+#endif FLUSHNO
+static int flushno=FLUSHNO; /* input queue flushing threshold */
+#define MAXUM 52 /* maximum number of user re-named monsters */
+#define MAXMNAME 40 /* max length of a monster re-name */
+static char usermonster[MAXUM][MAXMNAME]; /* the user named monster name goes here */
+static char usermpoint=0; /* the user monster pointer */
+
+/*
+ lexical analyzer for larn
+ */
+yylex()
+ {
+ char cc;
+ int ic;
+ if (hit2flag) { hit2flag=0; yrepcount=0; return(' '); }
+ if (yrepcount>0) { --yrepcount; return(lastok); } else yrepcount=0;
+ if (yrepcount==0) { bottomdo(); showplayer(); } /* show where the player is */
+ lflush();
+ while (1)
+ {
+ c[BYTESIN]++;
+ if (ckpflag)
+ if ((c[BYTESIN] % 400) == 0) /* check for periodic checkpointing */
+ {
+#ifndef DOCHECKPOINTS
+ savegame(ckpfile);
+#else
+ wait(0); /* wait for other forks to finish */
+ if (fork() == 0) { savegame(ckpfile); exit(); }
+#endif
+
+
+#ifdef TIMECHECK
+ if (dayplay==0)
+ if (playable())
+ {
+ cursor(1,19);
+ lprcat("\nSorry, but it is now time for work. Your game has been saved.\n"); beep();
+ lflush(); savegame(savefilename); wizard=nomove=1; sleep(4);
+ died(-257);
+ }
+#endif TIMECHECK
+
+ }
+
+ do /* if keyboard input buffer is too big, flush some of it */
+ {
+ ioctl(0,FIONREAD,&ic);
+ if (ic>flushno) read(0,&cc,1);
+ }
+ while (ic>flushno);
+
+ if (read(0,&cc,1) != 1) return(lastok = -1);
+
+ if (cc == 'Y'-64) /* control Y -- shell escape */
+ {
+ resetscroll(); clear(); /* scrolling region, home, clear, no attributes */
+ if ((ic=fork())==0) /* child */
+ {
+ execl("/bin/csh",0); exit();
+ }
+ wait(0);
+ if (ic<0) /* error */
+ {
+ write(2,"Can't fork off a shell!\n",25); sleep(2);
+ }
+
+ setscroll();
+ return(lastok = 'L'-64); /* redisplay screen */
+ }
+
+ if ((cc <= '9') && (cc >= '0'))
+ { yrepcount = yrepcount*10 + cc - '0'; }
+ else { if (yrepcount>0) --yrepcount; return(lastok = cc); }
+ }
+ }
+
+/*
+ * flushall() Function to flush all type-ahead in the input buffer
+ */
+flushall()
+ {
+ char cc;
+ int ic;
+ for (;;) /* if keyboard input buffer is too big, flush some of it */
+ {
+ ioctl(0,FIONREAD,&ic);
+ if (ic<=0) return;
+ while (ic>0) { read(0,&cc,1); --ic; } /* gobble up the byte */
+ }
+ }
+
+/*
+ function to set the desired hardness
+ enter with hard= -1 for default hardness, else any desired hardness
+ */
+sethard(hard)
+ int hard;
+ {
+ register int j,k,i;
+ j=c[HARDGAME]; hashewon();
+ if (restorflag==0) /* don't set c[HARDGAME] if restoring game */
+ {
+ if (hard >= 0) c[HARDGAME]= hard;
+ }
+ else c[HARDGAME]=j; /* set c[HARDGAME] to proper value if restoring game */
+
+ if (k=c[HARDGAME])
+ for (j=0; j<=MAXMONST+8; j++)
+ {
+ i = ((6+k)*monster[j].hitpoints+1)/6;
+ monster[j].hitpoints = (i<0) ? 32767 : i;
+ i = ((6+k)*monster[j].damage+1)/5;
+ monster[j].damage = (i>127) ? 127 : i;
+ i = (10*monster[j].gold)/(10+k);
+ monster[j].gold = (i>32767) ? 32767 : i;
+ i = monster[j].armorclass - k;
+ monster[j].armorclass = (i< -127) ? -127 : i;
+ i = (7*monster[j].experience)/(7+k) + 1;
+ monster[j].experience = (i<=0) ? 1 : i;
+ }
+ }
+
+/*
+ function to read and process the larn options file
+ */
+readopts()
+ {
+ register char *i;
+ register int j,k;
+ int flag;
+ flag=1; /* set to 0 if he specifies a name for his character */
+ if (lopen(optsfile) < 0)
+ {
+ strcpy(logname,loginname); return; /* user name if no character name */
+ }
+ i = " ";
+ while (*i)
+ {
+ if ((i=(char *)lgetw()) == 0) break; /* check for EOF */
+ while ((*i==' ') || (*i=='\t')) i++; /* eat leading whitespace */
+ switch(*i)
+ {
+ case 'b': if (strcmp(i,"bold-objects") == 0) boldon=1;
+ break;
+
+ case 'e': if (strcmp(i,"enable-checkpointing") == 0) ckpflag=1;
+ break;
+
+ case 'i': if (strcmp(i,"inverse-objects") == 0) boldon=0;
+ break;
+
+ case 'f': if (strcmp(i,"female") == 0) sex=0; /* male or female */
+ break;
+
+ case 'm': if (strcmp(i,"monster:")== 0) /* name favorite monster */
+ {
+ if ((i=lgetw())==0) break;
+ if (strlen(i)>=MAXMNAME) i[MAXMNAME-1]=0;
+ strcpy(usermonster[usermpoint],i);
+ if (usermpoint >= MAXUM) break; /* defined all of em */
+ if (isalpha(j=usermonster[usermpoint][0]))
+ {
+ for (k=1; k<MAXMONST+8; k++) /* find monster */
+ if (monstnamelist[k] == j)
+ {
+ monster[k].name = &usermonster[usermpoint++][0];
+ break;
+ }
+ }
+ }
+ else if (strcmp(i,"male") == 0) sex=1;
+ break;
+
+ case 'n': if (strcmp(i,"name:") == 0) /* defining players name */
+ {
+ if ((i=lgetw())==0) break;
+ if (strlen(i)>=LOGNAMESIZE) i[LOGNAMESIZE-1]=0;
+ strcpy(logname,i); flag=0;
+ }
+ else if (strcmp(i,"no-introduction") == 0) nowelcome=1;
+ else if (strcmp(i,"no-beep") == 0) nobeep=1;
+ break;
+
+ case 'p': if (strcmp(i,"process-name:")== 0)
+ {
+ if ((i=lgetw())==0) break;
+ if (strlen(i)>=PSNAMESIZE) i[PSNAMESIZE-1]=0;
+ strcpy(psname,i);
+ }
+ else if (strcmp(i,"play-day-play") == 0) dayplay=1;
+ break;
+
+ case 's': if (strcmp(i,"savefile:") == 0) /* defining savefilename */
+ {
+ if ((i=lgetw())==0) break;
+ strcpy(savefilename,i); flag=0;
+ }
+ break;
+ };
+ }
+ if (flag) strcpy(logname,loginname);
+ }
+
diff --git a/mille/Makefile b/mille/Makefile
new file mode 100644
index 00000000..2230f71a
--- /dev/null
+++ b/mille/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 5.10 (Berkeley) 5/11/90
+
+PROG= mille
+SRCS= comp.c end.c extern.c init.c mille.c misc.c move.c print.c \
+ roll.c save.c types.c varpush.c
+DPADD= ${LIBCURSES} ${LIBTERM}
+LDADD= -lcurses -ltermlib
+MAN6= mille.0
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
+
diff --git a/mille/comp.c b/mille/comp.c
new file mode 100644
index 00000000..64929fe7
--- /dev/null
+++ b/mille/comp.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)comp.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "mille.h"
+
+/*
+ * @(#)comp.c 1.1 (Berkeley) 4/1/82
+ */
+
+# define V_VALUABLE 40
+
+calcmove()
+{
+ register CARD card;
+ register int *value;
+ register PLAY *pp, *op;
+ register bool foundend, cango, canstop, foundlow;
+ register unsgn int i, count200, badcount, nummin, nummax, diff;
+ register int curmin, curmax;
+ register CARD safe, oppos;
+ int valbuf[HAND_SZ], count[NUM_CARDS];
+ bool playit[HAND_SZ];
+
+ wmove(Score, ERR_Y, ERR_X); /* get rid of error messages */
+ wclrtoeol(Score);
+ pp = &Player[COMP];
+ op = &Player[PLAYER];
+ safe = 0;
+ cango = 0;
+ canstop = FALSE;
+ foundend = FALSE;
+ for (i = 0; i < NUM_CARDS; i++)
+ count[i] = 0;
+ for (i = 0; i < HAND_SZ; i++) {
+ card = pp->hand[i];
+ switch (card) {
+ case C_STOP: case C_CRASH:
+ case C_FLAT: case C_EMPTY:
+ if (playit[i] = canplay(pp, op, card))
+ canstop = TRUE;
+ goto norm;
+ case C_LIMIT:
+ if ((playit[i] = canplay(pp, op, card))
+ && Numseen[C_25] == Numcards[C_25]
+ && Numseen[C_50] == Numcards[C_50])
+ canstop = TRUE;
+ goto norm;
+ case C_25: case C_50: case C_75:
+ case C_100: case C_200:
+ if ((playit[i] = canplay(pp, op, card))
+ && pp->mileage + Value[card] == End)
+ foundend = TRUE;
+ goto norm;
+ default:
+ playit[i] = canplay(pp, op, card);
+norm:
+ if (playit[i])
+ ++cango;
+ break;
+ case C_GAS_SAFE: case C_DRIVE_SAFE:
+ case C_SPARE_SAFE: case C_RIGHT_WAY:
+ if (pp->battle == opposite(card) ||
+ (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) {
+ Movetype = M_PLAY;
+ Card_no = i;
+ return;
+ }
+ ++safe;
+ playit[i] = TRUE;
+ break;
+ }
+ ++count[card];
+ }
+ if (pp->hand[0] == C_INIT && Topcard > Deck) {
+ Movetype = M_DRAW;
+ return;
+ }
+#ifdef DEBUG
+ if (Debug)
+ fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n",
+ cango, canstop, safe);
+#endif
+ if (foundend)
+ foundend = !check_ext(TRUE);
+ for (i = 0; safe && i < HAND_SZ; i++) {
+ if (issafety(pp->hand[i])) {
+ if (onecard(op) || (foundend && cango && !canstop)) {
+#ifdef DEBUG
+ if (Debug)
+ fprintf(outf,
+ "CALCMOVE: onecard(op) = %d, foundend = %d\n",
+ onecard(op), foundend);
+#endif
+playsafe:
+ Movetype = M_PLAY;
+ Card_no = i;
+ return;
+ }
+ oppos = opposite(pp->hand[i]);
+ if (Numseen[oppos] == Numcards[oppos] &&
+ !(pp->hand[i] == C_RIGHT_WAY &&
+ Numseen[C_LIMIT] != Numcards[C_LIMIT]))
+ goto playsafe;
+ else if (!cango
+ && (op->can_go || !pp->can_go || Topcard < Deck)) {
+ card = (Topcard - Deck) - roll(1, 10);
+ if ((!pp->mileage) != (!op->mileage))
+ card -= 7;
+#ifdef DEBUG
+ if (Debug)
+ fprintf(outf,
+ "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n",
+ card, DECK_SZ / 4);
+#endif
+ if (card < DECK_SZ / 4)
+ goto playsafe;
+ }
+ safe--;
+ playit[i] = cango;
+ }
+ }
+ if (!pp->can_go && !isrepair(pp->battle))
+ Numneed[opposite(pp->battle)]++;
+redoit:
+ foundlow = (cango || count[C_END_LIMIT] != 0
+ || Numseen[C_LIMIT] == Numcards[C_LIMIT]
+ || pp->safety[S_RIGHT_WAY] != S_UNKNOWN);
+ foundend = FALSE;
+ count200 = pp->nummiles[C_200];
+ badcount = 0;
+ curmax = -1;
+ curmin = 101;
+ nummin = -1;
+ nummax = -1;
+ value = valbuf;
+ for (i = 0; i < HAND_SZ; i++) {
+ card = pp->hand[i];
+ if (issafety(card) || playit[i] == (cango != 0)) {
+#ifdef DEBUG
+ if (Debug)
+ fprintf(outf, "CALCMOVE: switch(\"%s\")\n",
+ C_name[card]);
+#endif
+ switch (card) {
+ case C_25: case C_50:
+ diff = End - pp->mileage;
+ /* avoid getting too close */
+ if (Topcard > Deck && cango && diff <= 100
+ && diff / Value[card] > count[card]
+ && (card == C_25 || diff % 50 == 0)) {
+ if (card == C_50 && diff - 50 == 25
+ && count[C_25] > 0)
+ goto okay;
+ *value = 0;
+ if (--cango <= 0)
+ goto redoit;
+ break;
+ }
+okay:
+ *value = (Value[card] >> 3);
+ if (pp->speed == C_LIMIT)
+ ++*value;
+ else
+ --*value;
+ if (!foundlow
+ && (card == C_50 || count[C_50] == 0)) {
+ *value = (pp->mileage ? 10 : 20);
+ foundlow = TRUE;
+ }
+ goto miles;
+ case C_200:
+ if (++count200 > 2) {
+ *value = 0;
+ break;
+ }
+ case C_75: case C_100:
+ *value = (Value[card] >> 3);
+ if (pp->speed == C_LIMIT)
+ --*value;
+ else
+ ++*value;
+miles:
+ if (pp->mileage + Value[card] > End)
+ *value = (End == 700 ? card : 0);
+ else if (pp->mileage + Value[card] == End) {
+ *value = (foundend ? card : V_VALUABLE);
+ foundend = TRUE;
+ }
+ break;
+ case C_END_LIMIT:
+ if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
+ *value = (pp->safety[S_RIGHT_WAY] ==
+ S_PLAYED ? -1 : 1);
+ else if (pp->speed == C_LIMIT &&
+ End - pp->mileage <= 50)
+ *value = 1;
+ else if (pp->speed == C_LIMIT
+ || Numseen[C_LIMIT] != Numcards[C_LIMIT]) {
+ safe = S_RIGHT_WAY;
+ oppos = C_LIMIT;
+ goto repair;
+ }
+ else {
+ *value = 0;
+ --count[C_END_LIMIT];
+ }
+ break;
+ case C_REPAIRS: case C_SPARE: case C_GAS:
+ safe = safety(card) - S_CONV;
+ oppos = opposite(card);
+ if (pp->safety[safe] != S_UNKNOWN)
+ *value = (pp->safety[safe] ==
+ S_PLAYED ? -1 : 1);
+ else if (pp->battle != oppos
+ && (Numseen[oppos] == Numcards[oppos] ||
+ Numseen[oppos] + count[card] >
+ Numcards[oppos])) {
+ *value = 0;
+ --count[card];
+ }
+ else {
+repair:
+ *value = Numcards[oppos] * 6;
+ *value += Numseen[card] -
+ Numseen[oppos];
+ if (!cango)
+ *value /= (count[card]*count[card]);
+ count[card]--;
+ }
+ break;
+ case C_GO:
+ if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
+ *value = (pp->safety[S_RIGHT_WAY] ==
+ S_PLAYED ? -1 : 2);
+ else if (pp->can_go
+ && Numgos + count[C_GO] == Numneed[C_GO]) {
+ *value = 0;
+ --count[C_GO];
+ }
+ else {
+ *value = Numneed[C_GO] * 3;
+ *value += (Numseen[C_GO] - Numgos);
+ *value /= (count[C_GO] * count[C_GO]);
+ count[C_GO]--;
+ }
+ break;
+ case C_LIMIT:
+ if (op->mileage + 50 >= End) {
+ *value = (End == 700 && !cango);
+ break;
+ }
+ if (canstop || (cango && !op->can_go))
+ *value = 1;
+ else {
+ *value = (pp->safety[S_RIGHT_WAY] !=
+ S_UNKNOWN ? 2 : 3);
+ safe = S_RIGHT_WAY;
+ oppos = C_END_LIMIT;
+ goto normbad;
+ }
+ break;
+ case C_CRASH: case C_EMPTY: case C_FLAT:
+ safe = safety(card) - S_CONV;
+ oppos = opposite(card);
+ *value = (pp->safety[safe]!=S_UNKNOWN ? 3 : 4);
+normbad:
+ if (op->safety[safe] == S_PLAYED)
+ *value = -1;
+ else {
+ *value *= Numneed[oppos] +
+ Numseen[oppos] + 2;
+ if (!pp->mileage || foundend ||
+ onecard(op))
+ *value += 5;
+ if (op->mileage == 0 || onecard(op))
+ *value += 5;
+ if (op->speed == C_LIMIT)
+ *value -= 3;
+ if (cango &&
+ pp->safety[safe] != S_UNKNOWN)
+ *value += 3;
+ if (!cango)
+ *value /= ++badcount;
+ }
+ break;
+ case C_STOP:
+ if (op->safety[S_RIGHT_WAY] == S_PLAYED)
+ *value = -1;
+ else {
+ *value = (pp->safety[S_RIGHT_WAY] !=
+ S_UNKNOWN ? 3 : 4);
+ *value *= Numcards[C_STOP] +
+ Numseen[C_GO];
+ if (!pp->mileage || foundend ||
+ onecard(op))
+ *value += 5;
+ if (!cango)
+ *value /= ++badcount;
+ if (op->mileage == 0)
+ *value += 5;
+ if ((card == C_LIMIT &&
+ op->speed == C_LIMIT) ||
+ !op->can_go)
+ *value -= 5;
+ if (cango && pp->safety[S_RIGHT_WAY] !=
+ S_UNKNOWN)
+ *value += 5;
+ }
+ break;
+ case C_GAS_SAFE: case C_DRIVE_SAFE:
+ case C_SPARE_SAFE: case C_RIGHT_WAY:
+ *value = cango ? 0 : 101;
+ break;
+ case C_INIT:
+ *value = 0;
+ break;
+ }
+ }
+ else
+ *value = cango ? 0 : 101;
+ if (card != C_INIT) {
+ if (*value >= curmax) {
+ nummax = i;
+ curmax = *value;
+ }
+ if (*value <= curmin) {
+ nummin = i;
+ curmin = *value;
+ }
+ }
+#ifdef DEBUG
+ if (Debug)
+ mvprintw(i + 6, 2, "%3d %-14s", *value,
+ C_name[pp->hand[i]]);
+#endif
+ value++;
+ }
+ if (!pp->can_go && !isrepair(pp->battle))
+ Numneed[opposite(pp->battle)]++;
+ if (cango) {
+play_it:
+ mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
+#ifdef DEBUG
+ if (Debug)
+ getmove();
+ if (!Debug || Movetype == M_DRAW) {
+#else
+ if (Movetype == M_DRAW) {
+#endif
+ Movetype = M_PLAY;
+ Card_no = nummax;
+ }
+ }
+ else {
+ if (issafety(pp->hand[nummin])) { /* NEVER discard a safety */
+ nummax = nummin;
+ goto play_it;
+ }
+ mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
+#ifdef DEBUG
+ if (Debug)
+ getmove();
+ if (!Debug || Movetype == M_DRAW) {
+#else
+ if (Movetype == M_DRAW) {
+#endif
+ Movetype = M_DISCARD;
+ Card_no = nummin;
+ }
+ }
+ mvprintw(MOVE_Y + 2, MOVE_X, "%16s", C_name[pp->hand[Card_no]]);
+}
+
+onecard(pp)
+register PLAY *pp;
+{
+ register CARD bat, spd, card;
+
+ bat = pp->battle;
+ spd = pp->speed;
+ card = -1;
+ if (pp->can_go || ((isrepair(bat) || bat == C_STOP || spd == C_LIMIT) &&
+ Numseen[S_RIGHT_WAY] != 0) ||
+ Numseen[safety(bat)] != 0)
+ switch (End - pp->mileage) {
+ case 200:
+ if (pp->nummiles[C_200] == 2)
+ return FALSE;
+ card = C_200;
+ /* FALLTHROUGH */
+ case 100:
+ case 75:
+ if (card == -1)
+ card = (End - pp->mileage == 75 ? C_75 : C_100);
+ if (spd == C_LIMIT)
+ return Numseen[S_RIGHT_WAY] == 0;
+ case 50:
+ case 25:
+ if (card == -1)
+ card = (End - pp->mileage == 25 ? C_25 : C_50);
+ return Numseen[card] != Numcards[card];
+ }
+ return FALSE;
+}
+
+canplay(pp, op, card)
+register PLAY *pp, *op;
+register CARD card;
+{
+ switch (card) {
+ case C_200:
+ if (pp->nummiles[C_200] == 2)
+ break;
+ /* FALLTHROUGH */
+ case C_75: case C_100:
+ if (pp->speed == C_LIMIT)
+ break;
+ /* FALLTHROUGH */
+ case C_50:
+ if (pp->mileage + Value[card] > End)
+ break;
+ /* FALLTHROUGH */
+ case C_25:
+ if (pp->can_go)
+ return TRUE;
+ break;
+ case C_EMPTY: case C_FLAT: case C_CRASH:
+ case C_STOP:
+ if (op->can_go && op->safety[safety(card) - S_CONV] != S_PLAYED)
+ return TRUE;
+ break;
+ case C_LIMIT:
+ if (op->speed != C_LIMIT &&
+ op->safety[S_RIGHT_WAY] != S_PLAYED &&
+ op->mileage + 50 < End)
+ return TRUE;
+ break;
+ case C_GAS: case C_SPARE: case C_REPAIRS:
+ if (pp->battle == opposite(card))
+ return TRUE;
+ break;
+ case C_GO:
+ if (!pp->can_go &&
+ (isrepair(pp->battle) || pp->battle == C_STOP))
+ return TRUE;
+ break;
+ case C_END_LIMIT:
+ if (pp->speed == C_LIMIT)
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/mille/end.c b/mille/end.c
new file mode 100644
index 00000000..c9691fea
--- /dev/null
+++ b/mille/end.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)end.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "mille.h"
+
+/*
+ * @(#)end.c 1.1 (Berkeley) 4/1/82
+ */
+
+/*
+ * print out the score as if it was final, and add the totals for
+ * the end-of-games points to the user who deserves it (if any).
+ */
+finalscore(pp)
+reg PLAY *pp; {
+
+ reg int temp, tot, num;
+
+ if (pp->was_finished == Finished)
+ return;
+
+ pp->was_finished = Finished;
+ num = pp - Player;
+ temp = num * 6 + 21 + 1;
+ for (tot = 5; tot <= 9; tot++)
+ mvaddstr(tot, temp, " 0");
+ if (pp->mileage == End) {
+ mvaddstr(5, temp, "40");
+ tot = SC_TRIP;
+ if (pp->nummiles[C_200] == 0) {
+ mvaddstr(6, temp, "30");
+ tot = SC_TRIP + SC_SAFE;
+ }
+ if (Topcard <= Deck) {
+ mvaddstr(7, temp, "30");
+ tot += SC_DELAY;
+ }
+ if (End == 1000) {
+ mvaddstr(8, temp, "20");
+ tot += SC_EXTENSION;
+ }
+ if (Player[other(num)].mileage == 0) {
+ mvaddstr(9, temp, "50");
+ tot += SC_SHUT_OUT;
+ }
+ pp->total += tot;
+ pp->hand_tot += tot;
+ }
+}
+
+# ifdef EXTRAP
+static int Last_tot[2]; /* last tot used for extrapolate */
+
+/*
+ * print out the score as if it was final, and add the totals for
+ * the end-of-games points to the user who deserves it (if any).
+ */
+extrapolate(pp)
+reg PLAY *pp; {
+
+ reg int x, num, tot, count;
+
+ num = pp - Player;
+ tot += SC_TRIP + SC_DELAY + SC_EXT;
+ x = num * 6 + 21 + 3;
+ for (tot = 5; tot <= 9; tot++)
+ mvaddch(tot, x, '0');
+ x -= 2;
+ pp = &Player[other(num)];
+ for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
+ if (pp->safety[tot] != S_PLAYED)
+ count += SC_SAFE;
+ mvprintw(3, x, "%3d", count);
+ tot += count;
+ if (count == 400) {
+ mvaddstr(4, x, "30");
+ tot += SC_ALL_SAFE;
+ }
+ pp = &Player[num];
+ for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
+ if (pp->safety[tot] != S_PLAYED)
+ count += SC_COUP / 10;
+ mvprintw(4, x - 1, "%3d", count);
+ tot += count;
+ tot += 1000 - pp->mileage;
+ mvaddstr(5, x, "40");
+ mvaddstr(7, x, "30");
+ mvaddstr(8, x, "20");
+ if (pp->nummiles[C_200] == 0) {
+ mvaddstr(6, x, "30");
+ tot = SC_TRIP + SC_SAFE;
+ }
+ if (Player[other(num)].mileage == 0) {
+ mvaddstr(9, x, "50");
+ tot += SC_SHUT_OUT;
+ }
+ pp->total += tot;
+ pp->hand_tot += tot;
+ Last_tot[num] = tot;
+}
+
+undoex() {
+
+ reg PLAY *pp;
+ reg int i;
+
+ i = 0;
+ for (pp = Player; pp < &Player[2]; pp++) {
+ pp->total -= Last_tot[i];
+ pp->hand_tot -= Last_tot[i++];
+ }
+}
+# endif
+
diff --git a/mille/extern.c b/mille/extern.c
new file mode 100644
index 00000000..a08ab2b0
--- /dev/null
+++ b/mille/extern.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)extern.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "mille.h"
+
+/*
+ * @(#)extern.c 1.1 (Berkeley) 4/1/82
+ */
+
+bool Debug, /* set if debugging code on */
+ Finished, /* set if current hand is finished */
+ Next, /* set if changing players */
+ On_exit, /* set if game saved on exiting */
+ Order, /* set if hand should be sorted */
+ Saved; /* set if game just saved */
+
+char *C_fmt = "%-18.18s", /* format for printing cards */
+ *Fromfile = NULL, /* startup file for game */
+ Initstr[100], /* initial string for error field */
+ *_cn[NUM_CARDS] = { /* Card name buffer */
+ "",
+ "25",
+ "50",
+ "75",
+ "100",
+ "200",
+ "Out of Gas",
+ "Flat Tire",
+ "Accident",
+ "Stop",
+ "Speed Limit",
+ "Gasoline",
+ "Spare Tire",
+ "Repairs",
+ "Go",
+ "End of Limit",
+ "Extra Tank",
+ "Puncture Proof",
+ "Driving Ace",
+ "Right of Way"
+ },
+ **C_name = &_cn[1]; /* Card names */
+
+int Card_no, /* Card number for current move */
+ End, /* End value for current hand */
+ Handstart = COMP, /* Player who starts hand */
+ Movetype, /* Current move type */
+ Play, /* Current player */
+ Numgos, /* Number of Go cards used by computer */
+ Window = W_SMALL, /* Current window wanted */
+ Numseen[NUM_CARDS], /* Number of cards seen in current hand */
+ Value[NUM_MILES] = { /* Value of mileage cards */
+ 25, 50, 75, 100, 200
+ },
+ Numcards[NUM_CARDS] = { /* Number of cards in deck */
+ 10, /* C_25 */
+ 10, /* C_50 */
+ 10, /* C_75 */
+ 12, /* C_100 */
+ 4, /* C_200 */
+ 2, /* C_EMPTY */
+ 2, /* C_FLAT */
+ 2, /* C_CRASH */
+ 4, /* C_STOP */
+ 3, /* C_LIMIT */
+ 6, /* C_GAS */
+ 6, /* C_SPARE */
+ 6, /* C_REPAIRS */
+ 14, /* C_GO */
+ 6, /* C_END_LIMIT */
+ 1, /* C_GAS_SAFE */
+ 1, /* C_SPARE_SAFE */
+ 1, /* C_DRIVE_SAFE */
+ 1, /* C_RIGHT_WAY */
+ 0 /* C_INIT */
+ },
+ Numneed[NUM_CARDS] = { /* number of cards needed per hand */
+ 0, /* C_25 */
+ 0, /* C_50 */
+ 0, /* C_75 */
+ 0, /* C_100 */
+ 0, /* C_200 */
+ 2, /* C_EMPTY */
+ 2, /* C_FLAT */
+ 2, /* C_CRASH */
+ 4, /* C_STOP */
+ 3, /* C_LIMIT */
+ 2, /* C_GAS */
+ 2, /* C_SPARE */
+ 2, /* C_REPAIRS */
+ 10, /* C_GO */
+ 3, /* C_END_LIMIT */
+ 1, /* C_GAS_SAFE */
+ 1, /* C_SPARE_SAFE */
+ 1, /* C_DRIVE_SAFE */
+ 1, /* C_RIGHT_WAY */
+ 0 /* C_INIT */
+ };
+
+CARD Discard, /* Top of discard pile */
+ Sh_discard, /* Last discard card shown */
+ *Topcard, /* Pointer to next card to be picked */
+ Opposite[NUM_CARDS] = { /* Opposites of each card */
+ C_25, C_50, C_75, C_100, C_200, C_GAS, C_SPARE,
+ C_REPAIRS, C_GO, C_END_LIMIT, C_EMPTY, C_FLAT, C_CRASH,
+ C_STOP, C_LIMIT, C_EMPTY, C_FLAT, C_CRASH, C_STOP, C_INIT
+ },
+ Deck[DECK_SZ] = { /* Current deck */
+ C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25,
+ C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50,
+ C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75,
+ C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100,
+ C_100, C_100, C_100,
+ C_200, C_200, C_200, C_200,
+ C_EMPTY, C_EMPTY,
+ C_FLAT, C_FLAT,
+ C_CRASH, C_CRASH,
+ C_STOP, C_STOP, C_STOP, C_STOP,
+ C_LIMIT, C_LIMIT, C_LIMIT,
+ C_GAS, C_GAS, C_GAS, C_GAS, C_GAS, C_GAS,
+ C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE,
+ C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS,
+ C_REPAIRS,
+ C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT,
+ C_END_LIMIT,
+ C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO,
+ C_GO, C_GO, C_GO, C_GO,
+ C_GAS_SAFE, C_SPARE_SAFE, C_DRIVE_SAFE, C_RIGHT_WAY
+ };
+
+FILE *outf;
+
+PLAY Player[2]; /* Player descriptions */
+
+WINDOW *Board, /* Playing field screen */
+ *Miles, /* Mileage screen */
+ *Score; /* Score screen */
+
diff --git a/mille/init.c b/mille/init.c
new file mode 100644
index 00000000..f7dfeb1c
--- /dev/null
+++ b/mille/init.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "mille.h"
+
+/*
+ * @(#)init.c 1.1 (Berkeley) 4/1/82
+ */
+
+init() {
+
+ reg PLAY *pp;
+ reg int i, j;
+ reg CARD card;
+
+ bzero(Numseen, sizeof Numseen);
+ Numgos = 0;
+
+ for (i = 0; i < 2; i++) {
+ pp = &Player[i];
+ pp->hand[0] = C_INIT;
+ for (j = 0; j < NUM_SAFE; j++) {
+ pp->safety[j] = S_UNKNOWN;
+ pp->coups[j] = FALSE;
+ }
+ for (j = 1; j < HAND_SZ; j++) {
+ pp->hand[j] = *--Topcard;
+ if (i == COMP) {
+ account(card = *Topcard);
+ if (issafety(card))
+ pp->safety[card - S_CONV] = S_IN_HAND;
+ }
+ }
+ pp->mileage = 0;
+ pp->hand_tot = 0;
+ pp->safescore = 0;
+ pp->coupscore = 0;
+ pp->can_go = FALSE;
+ pp->speed = C_INIT;
+ pp->battle = C_INIT;
+ pp->new_speed = FALSE;
+ pp->new_battle = FALSE;
+ for (j = 0; j < NUM_MILES; j++)
+ pp->nummiles[j] = 0;
+ }
+ if (Order)
+ sort(Player[PLAYER].hand);
+ Discard = C_INIT;
+ Finished = FALSE;
+ End = 700;
+}
+
+shuffle() {
+
+ reg int i, r;
+ reg CARD temp;
+
+ for (i = 0; i < DECK_SZ; i++) {
+ r = roll(1, DECK_SZ) - 1;
+ if (r < 0 || r > DECK_SZ - 1) {
+ fprintf(stderr, "shuffle: card no. error: %d\n", r);
+ die();
+ }
+ temp = Deck[r];
+ Deck[r] = Deck[i];
+ Deck[i] = temp;
+ }
+ Topcard = &Deck[DECK_SZ];
+}
+
+newboard() {
+
+ register int i;
+ register PLAY *pp;
+ static int first = TRUE;
+
+ if (first) {
+ werase(Board);
+ werase(Score);
+ mvaddstr(5, 0, "--HAND--");
+ mvaddch(6, 0, 'P');
+ mvaddch(7, 0, '1');
+ mvaddch(8, 0, '2');
+ mvaddch(9, 0, '3');
+ mvaddch(10, 0, '4');
+ mvaddch(11, 0, '5');
+ mvaddch(12, 0, '6');
+ mvaddstr(13, 0, "--BATTLE--");
+ mvaddstr(15, 0, "--SPEED--");
+ mvaddstr(5, 20, "--DECK--");
+ mvaddstr(7, 20, "--DISCARD--");
+ mvaddstr(13, 20, "--BATTLE--");
+ mvaddstr(15, 20, "--SPEED--");
+ mvwaddstr(Miles, 0, 0, "--MILEAGE--");
+ mvwaddstr(Miles, 0, 41, "--MILEAGE--");
+ Sh_discard = -1;
+ for (pp = Player; pp <= &Player[COMP]; pp++) {
+ for (i = 0; i < HAND_SZ; i++)
+ pp->sh_hand[i] = -1;
+ pp->sh_battle = -1;
+ pp->sh_speed = -1;
+ pp->sh_mileage = -1;
+ }
+ first = FALSE;
+ }
+ else {
+ for (i = 0; i < 5; i++) {
+ move(i, 0);
+ clrtoeol();
+ }
+ wmove(Miles, 1, 0);
+ wclrtobot(Miles);
+ wmove(Board, MOVE_Y + 1, MOVE_X);
+ wclrtoeol(Board);
+ wmove(Board, MOVE_Y + 2, MOVE_X);
+ wclrtoeol(Board);
+ }
+ Sh_discard = -1;
+ for (pp = Player; pp <= &Player[COMP]; pp++) {
+ for (i = 0; i < NUM_SAFE; i++)
+ pp->sh_safety[i] = FALSE;
+ for (i = 0; i < NUM_MILES; i++)
+ pp->sh_nummiles[i] = 0;
+ pp->sh_safescore = -1;
+ }
+ newscore();
+}
+
+newscore() {
+
+ reg int i, new;
+ register PLAY *pp;
+ static int was_full = -1;
+ static int last_win = -1;
+
+ if (was_full < 0)
+ was_full = (Window != W_FULL);
+ stdscr = Score;
+ move(0, 22);
+ new = FALSE;
+ if (inch() != 'Y') {
+ erase();
+ mvaddstr(0, 22, "You Comp Value");
+ mvaddstr(1, 2, "Milestones Played");
+ mvaddstr(2, 8, "Each Safety");
+ mvaddstr(3, 5, "All 4 Safeties");
+ mvaddstr(4, 3, "Each Coup Fourre");
+ mvaddstr(2, 37, "100");
+ mvaddstr(3, 37, "300");
+ mvaddstr(4, 37, "300");
+ new = TRUE;
+ }
+ else if (((Window == W_FULL || Finished) ^ was_full) ||
+ pp->was_finished != Finished) {
+ move(5, 1);
+ clrtobot();
+ new = TRUE;
+ }
+ else if (Window != last_win)
+ new = TRUE;
+ if (new) {
+ for (i = 0; i < SCORE_Y; i++)
+ mvaddch(i, 0, '|');
+ move(SCORE_Y - 1, 1);
+ while (addch('_') != ERR)
+ continue;
+ for (pp = Player; pp <= &Player[COMP]; pp++) {
+ pp->sh_hand_tot = -1;
+ pp->sh_total = -1;
+ pp->sh_games = -1;
+ pp->sh_safescore = -1;
+ }
+ }
+ Player[PLAYER].was_finished = !Finished;
+ Player[COMP].was_finished = !Finished;
+ if (Window == W_FULL || Finished) {
+ if (!was_full || new) {
+ mvaddstr(5, 5, "Trip Completed");
+ mvaddstr(6, 10, "Safe Trip");
+ mvaddstr(7, 5, "Delayed Action");
+ mvaddstr(8, 10, "Extension");
+ mvaddstr(9, 11, "Shut-Out");
+ mvaddstr(10, 21, "---- ---- -----");
+ mvaddstr(11, 9, "Hand Total");
+ mvaddstr(12, 20, "----- -----");
+ mvaddstr(13, 6, "Overall Total");
+ mvaddstr(14, 15, "Games");
+ mvaddstr(5, 37, "400");
+ mvaddstr(6, 37, "300");
+ mvaddstr(7, 37, "300");
+ mvaddstr(8, 37, "200");
+ mvaddstr(9, 37, "500");
+ }
+ }
+ else
+ if (was_full || new) {
+ mvaddstr(5, 21, "---- ---- -----");
+ mvaddstr(6, 9, "Hand Total");
+ mvaddstr(7, 20, "----- -----");
+ mvaddstr(8, 6, "Overall Total");
+ mvaddstr(9, 15, "Games");
+ mvaddstr(11, 2, "p: pick");
+ mvaddstr(12, 2, "u: use #");
+ mvaddstr(13, 2, "d: discard #");
+ mvaddstr(14, 2, "w: toggle window");
+ mvaddstr(11, 21, "q: quit");
+ if (!Order)
+ mvaddstr(12, 21, "o: order hand");
+ else
+ mvaddstr(12, 21, "o: stop ordering");
+ mvaddstr(13, 21, "s: save");
+ mvaddstr(14, 21, "r: reprint");
+ }
+ stdscr = Board;
+ was_full = (Window == W_FULL || Finished);
+ last_win = Window;
+}
diff --git a/mille/mille.6 b/mille/mille.6
new file mode 100644
index 00000000..06ef679e
--- /dev/null
+++ b/mille/mille.6
@@ -0,0 +1,378 @@
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mille.6 6.4 (Berkeley) 6/23/90
+.\"
+.TH MILLE 6 "June 23, 1990"
+.UC 4
+.SH NAME
+mille \- play Mille Bournes
+.SH SYNOPSIS
+.B /usr/games/mille
+[ file ]
+.SH DESCRIPTION
+.I Mille
+plays a two-handed game reminiscent of
+the Parker Brother's game of Mille Bournes with you.
+The rules are described below.
+If a file name is given on the command line,
+the game saved in that file is started.
+.PP
+When a game is started up,
+the bottom of the score window will contain a list of commands.
+They are:
+.IP P
+Pick a card from the deck.
+This card is placed in the `P' slot in your hand.
+.IP D
+Discard a card from your hand.
+To indicate which card, type the number of the card in the hand
+(or \*(lqP\*(rq for the just-picked card) followed by a <RETURN> or <SPACE>.
+The <RETURN or <SPACE> is required to allow recovery from typos
+which can be very expensive, like discarding safeties.
+.IP U
+Use a card.
+The card is again indicated by its number, followed by a <RETURN> or <SPACE>.
+.IP O
+Toggle ordering the hand.
+By default off, if turned on it will sort the cards in your hand appropriately.
+This is not recommended for the impatient on slow terminals.
+.IP Q
+Quit the game.
+This will ask for confirmation, just to be sure.
+Hitting <DELETE> (or <RUBOUT>) is equivalent.
+.IP S
+Save the game in a file.
+If the game was started from a file,
+you will be given an opportunity to save it on the same file.
+If you don't wish to, or you did not start from a file,
+you will be asked for the file name.
+If you type a <RETURN> without a name,
+the save will be terminated and the game resumed.
+.IP R
+Redraw the screen from scratch.
+The command ^L (control `L') will also work.
+.IP W
+Toggle window type.
+This switches the score window between the startup window
+(with all the command names) and the end-of-game window.
+Using the end-of-game window
+saves time by eliminating the switch at the end of the game
+to show the final score.
+Recommended for hackers and other miscreants.
+.PP
+If you make a mistake, an error message will be printed
+on the last line of the score window, and a bell will beep.
+.PP
+At the end of each hand or game,
+you will be asked if you wish to play another.
+If not, it will ask you if you want to save the game.
+If you do, and the save is unsuccessful,
+play will be resumed as if you had said you wanted to play another hand/game.
+This allows you to use the
+.RB \*(lq S \*(rq
+command to reattempt the save.
+.SH AUTHOR
+Ken Arnold
+.br
+(The game itself is a product of Parker Brothers, Inc.)
+.SH "SEE ALSO"
+curses(3X),
+.I "Screen Updating and Cursor Movement Optimization:"
+.IR "A Library Package" ,
+Ken Arnold
+.SH CARDS
+.PP
+Here is some useful information.
+The number in parentheses after the card name
+is the number of that card in the deck:
+.sp
+.nf
+.ne 10
+.ta \w'Speed Limit (3)'u+3n \w'Speed Limit (3)'u+\w'End of Limit (6)'u+6n
+Hazard Repair Safety
+.sp
+Out of Gas (2) Gasoline (6) Extra Tank (1)
+Flat Tire (2) Spare Tire (6) Puncture Proof (1)
+Accident (2) Repairs (6) Driving Ace (1)
+Stop (4) Go (14) Right of Way (1)
+Speed Limit (3) End of Limit (6)
+.sp
+.ce
+25 \- (10), 50 \- (10), 75 \- (10), 100 \- (12), 200 \- (4)
+.sp
+.fi
+.DT
+.SH RULES
+.PP
+.BR Object :
+The point of this game is to get a total of 5000 points in several hands.
+Each hand is a race to put down exactly 700 miles before your opponent does.
+Beyond the points gained by putting down milestones,
+there are several other ways of making points.
+.PP
+.BR Overview :
+The game is played with a deck of 101 cards.
+.I Distance
+cards represent a number of miles traveled.
+They come in denominations of 25, 50, 75, 100, and 200.
+When one is played,
+it adds that many miles to the player's trip so far this hand.
+.I Hazard
+cards are used to prevent your opponent from putting down Distance cards.
+They can only be played if your opponent has a
+.I Go
+card on top of the Battle pile.
+The cards are
+.IR "Out of Gas" ,
+.IR "Accident" ,
+.IR "Flat Tire" ,
+.IR "Speed Limit" ,
+and
+.IR "Stop" .
+.I Remedy
+cards fix problems caused by Hazard cards played on you by your opponent.
+The cards are
+.IR "Gasoline" ,
+.IR "Repairs" ,
+.IR "Spare Tire" ,
+.IR "End of Limit" ,
+and
+.IR "Go" .
+.I Safety
+cards prevent your opponent from putting specific Hazard cards on you
+in the first place.
+They are
+.IR "Extra Tank" ,
+.IR "Driving Ace" ,
+.IR "Puncture Proof" ,
+and
+.IR "Right of Way" ,
+and there are only one of each in the deck.
+.PP
+.BR "Board Layout" :
+The board is split into several areas.
+From top to bottom, they are:
+.B "SAFETY AREA"
+(unlabeled): This is where the safeties will be placed as they are played.
+.BR HAND :
+These are the cards in your hand.
+.BR BATTLE :
+This is the Battle pile.
+All the Hazard and Remedy Cards are played here, except the
+.I "Speed Limit"
+and
+.I "End of Limit"
+cards. Only the top card is displayed, as it is the only effective one.
+.BR SPEED :
+The Speed pile. The
+.I "Speed Limit"
+and
+.I "End of Limit"
+cards are played here
+to control the speed at which the player is allowed to put down miles.
+.BR MILEAGE :
+Miles are placed here.
+The total of the numbers shown here is the distance traveled so far.
+.PP
+.BR Play :
+The first pick alternates between the two players.
+Each turn usually starts with a pick from the deck.
+The player then plays a card, or if this is not possible or desirable,
+discards one. Normally, a play or discard of a single card
+constitutes a turn. If the card played is a safety, however,
+the same player takes another turn immediately.
+.PP
+This repeats until one of the players reaches 700 points or the deck runs out.
+If someone reaches 700, they have the option of going for an
+.IR Extension ,
+which means that the play continues until someone reaches 1000 miles.
+.PP
+.BR "Hazard and Remedy Cards" :
+Hazard Cards are played on your opponent's Battle and Speed piles.
+Remedy Cards are used for undoing the effects of your opponent's nastiness.
+.PP
+.RB "\ \ \ \ " Go
+(Green Light)
+must be the top card on your Battle pile for you to play any mileage,
+unless you have played the
+.I "Right of Way"
+card (see below).
+.br
+.RB "\ \ \ \ " Stop
+is played on your opponent's
+.I Go
+card to prevent them from playing mileage until they play a
+.I Go
+card.
+.br
+.RB "\ \ \ \ " "Speed Limit"
+is played on your opponent's Speed pile.
+Until they play an
+.I "End of Limit"
+they can only play 25 or 50 mile cards, presuming their
+.I Go
+card allows them to do even that.
+.br
+.RB "\ \ \ \ " "End of Limit"
+is played on your Speed pile to nullify a
+.I "Speed Limit"
+played by your opponent.
+.br
+.RB "\ \ \ \ " "Out of Gas"
+is played on your opponent's
+.I Go
+card. They must then play a
+.I Gasoline
+card, and then a
+.I Go
+card before they can play any more mileage.
+.br
+.RB "\ \ \ \ " "Flat Tire"
+is played on your opponent's
+.I Go
+card. They must then play a
+.I "Spare Tire"
+card, and then a
+.I Go
+card before they can play any more mileage.
+.br
+.RB "\ \ \ \ " "Accident"
+is played on your opponent's
+.I Go
+card. They must then play a
+.I Repairs
+card, and then a
+.I Go
+card before they can play any more mileage.
+.br
+.PP
+.BR "Safety Cards" :
+Safety cards prevent your opponent
+from playing the corresponding Hazard cards on you for the rest of the hand.
+It cancels an attack in progress, and
+.IR "always entitles the player to an extra turn" .
+.br
+.RB "\ \ \ \ " "Right of Way"
+prevents your opponent from playing both
+.I Stop
+and
+.I "Speed Limit"
+cards on you. It also acts as a permanent
+.I Go
+card for the rest of the hand, so you can play mileage
+as long as there is not a Hazard card on top of your Battle pile.
+In this case only, your opponent can play Hazard cards directly on a Remedy card
+other than a Go card.
+.br
+.RB "\ \ \ \ " "Extra Tank"
+When played, your opponent cannot play an
+.I "Out of Gas"
+on your Battle Pile.
+.br
+.RB "\ \ \ \ " "Puncture Proof"
+When played, your opponent cannot play a
+.I "Flat Tire"
+on your Battle Pile.
+.br
+.RB "\ \ \ \ " "Driving Ace"
+When played, your opponent cannot play an
+.I Accident
+on your Battle Pile.
+.PP
+.BR "Distance Cards" :
+Distance cards are played when you have a
+.I Go
+card on your Battle pile,
+or a Right of Way in your Safety area and are not stopped by a Hazard Card.
+They can be played in any combination that totals exactly 700 miles,
+except that
+.IR "you cannot play more than two 200 mile cards in one hand" .
+A hand ends whenever one player gets exactly 700 miles or the deck runs out.
+In that case, play continues until neither someone reaches 700,
+or neither player can use any cards in their hand.
+If the trip is completed after the deck runs out, this is called
+.IR "Delayed Action" .
+.PP
+.BR "Coup Fourr\o'\(aae'" :
+This is a French fencing term for a counter-thrust move as part of a parry
+to an opponents attack.
+In Mille Bournes, it is used as follows:
+If an opponent plays a Hazard card,
+and you have the corresponding Safety in your hand,
+you play it immediately, even
+.I before
+you draw. This immediately removes the Hazard card from your Battle pile,
+and protects you from that card for the rest of the game. This
+gives you more points (see \*(lqScoring\*(rq below).
+.PP
+.BR Scoring :
+Scores are totaled at the end of each hand,
+whether or not anyone completed the trip.
+The terms used in the Score window have the following meanings:
+.br
+.RB "\ \ \ \ " "Milestones Played" :
+Each player scores as many miles as they played before the trip ended.
+.br
+.RB "\ \ \ \ " "Each Safety" :
+100 points for each safety in the Safety area.
+.br
+.RB "\ \ \ \ " "All 4 Safeties" :
+300 points if all four safeties are played.
+.br
+.RB "\ \ \ \ " "Each Coup Four\o'\(aae'" :
+300 points for each Coup Four\o'\(aae' accomplished.
+.PP
+The following bonus scores can apply only to the winning player.
+.br
+.RB "\ \ \ \ " "Trip Completed" :
+400 points bonus for completing the trip to 700 or 1000.
+.br
+.RB "\ \ \ \ " "Safe Trip" :
+300 points bonus for completing the trip without using any 200 mile cards.
+.br
+.RB "\ \ \ \ " "Delayed Action" :
+300 points bonus for finishing after the deck was exhausted.
+.br
+.RB "\ \ \ \ " "Extension" :
+200 points bonus for completing a 1000 mile trip.
+.br
+.RB "\ \ \ \ " "Shut-Out" :
+500 points bonus for completing the trip
+before your opponent played any mileage cards.
+.PP
+Running totals are also kept for the current score for each player
+for the hand
+.RB ( "Hand Total" ),
+the game
+.RB ( "Overall Total" ),
+and number of games won
+.RB ( Games ).
diff --git a/mille/mille.c b/mille/mille.c
new file mode 100644
index 00000000..0bd9010d
--- /dev/null
+++ b/mille/mille.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1982 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mille.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include "mille.h"
+# include <signal.h>
+# ifdef attron
+# include <term.h>
+# endif attron
+
+/*
+ * @(#)mille.c 1.3 (Berkeley) 5/10/83
+ */
+
+void rub();
+
+main(ac, av)
+reg int ac;
+reg char *av[]; {
+
+ reg bool restore;
+
+ /* run as the user */
+ setuid(getuid());
+
+ if (strcmp(av[0], "a.out") == 0) {
+ outf = fopen("q", "w");
+ setbuf(outf, (char *)NULL);
+ Debug = TRUE;
+ }
+ restore = FALSE;
+ switch (ac) {
+ case 2:
+ rest_f(av[1]);
+ restore = TRUE;
+ case 1:
+ break;
+ default:
+ printf("usage: milles [ restore_file ]\n");
+ exit(-1);
+ /* NOTREACHED */
+ }
+ Play = PLAYER;
+ initscr();
+# ifdef attron
+# define CA cursor_address
+# endif
+ if (!CA) {
+ printf("Sorry. Need cursor addressing to play mille\n");
+ exit(-1);
+ }
+ delwin(stdscr);
+ stdscr = Board = newwin(BOARD_Y, BOARD_X, 0, 0);
+ Score = newwin(SCORE_Y, SCORE_X, 0, 40);
+ Miles = newwin(MILES_Y, MILES_X, 17, 0);
+#ifdef attron
+ idlok(Board, TRUE);
+ idlok(Score, TRUE);
+ idlok(Miles, TRUE);
+#endif
+ leaveok(Score, TRUE);
+ leaveok(Miles, TRUE);
+ clearok(curscr, TRUE);
+# ifndef PROF
+ srandom(getpid());
+# else
+ srandom(0);
+# endif
+ crmode();
+ noecho();
+ signal(SIGINT, rub);
+ for (;;) {
+ if (!restore || (Player[PLAYER].total >= 5000
+ || Player[COMP].total >= 5000)) {
+ if (Player[COMP].total < Player[PLAYER].total)
+ Player[PLAYER].games++;
+ else if (Player[COMP].total > Player[PLAYER].total)
+ Player[COMP].games++;
+ Player[COMP].total = 0;
+ Player[PLAYER].total = 0;
+ }
+ do {
+ if (!restore)
+ Handstart = Play = other(Handstart);
+ if (!restore || On_exit) {
+ shuffle();
+ init();
+ }
+ newboard();
+ if (restore)
+ mvwaddstr(Score, ERR_Y, ERR_X, Initstr);
+ prboard();
+ do {
+ domove();
+ if (Finished)
+ newscore();
+ prboard();
+ } while (!Finished);
+ check_more();
+ restore = On_exit = FALSE;
+ } while (Player[COMP].total < 5000
+ && Player[PLAYER].total < 5000);
+ }
+}
+
+/*
+ * Routine to trap rubouts, and make sure they really want to
+ * quit.
+ */
+void
+rub() {
+
+ (void)signal(SIGINT, SIG_IGN);
+ if (getyn(REALLYPROMPT))
+ die();
+ (void)signal(SIGINT, rub);
+}
+
+/*
+ * Time to go beddy-by
+ */
+die() {
+
+ (void)signal(SIGINT, SIG_IGN);
+ if (outf)
+ fflush(outf);
+ mvcur(0, COLS - 1, LINES - 1, 0);
+ endwin();
+ exit(1);
+}
+
diff --git a/mille/mille.h b/mille/mille.h
new file mode 100644
index 00000000..9757bb77
--- /dev/null
+++ b/mille/mille.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mille.h 5.5 (Berkeley) 6/1/90
+ */
+
+# include <sys/types.h>
+# include <ctype.h>
+# include <curses.h>
+# include <string.h>
+
+/*
+ * @(#)mille.h 1.1 (Berkeley) 4/1/82
+ */
+
+/*
+ * Miscellaneous constants
+ */
+
+# define unsgn unsigned
+# define CARD short
+
+# define HAND_SZ 7 /* number of cards in a hand */
+# define DECK_SZ 101 /* number of cards in decks */
+# define NUM_SAFE 4 /* number of saftey cards */
+# define NUM_MILES 5 /* number of milestones types */
+# define NUM_CARDS 20 /* number of types of cards */
+# define BOARD_Y 17 /* size of board screen */
+# define BOARD_X 40
+# define MILES_Y 7 /* size of mileage screen */
+# define MILES_X 80
+# define SCORE_Y 17 /* size of score screen */
+# define SCORE_X 40
+# define MOVE_Y 10 /* Where to print move prompt */
+# define MOVE_X 20
+# define ERR_Y 15 /* Where to print errors */
+# define ERR_X 5
+# define EXT_Y 4 /* Where to put Extension */
+# define EXT_X 9
+
+# define PLAYER 0
+# define COMP 1
+
+# define W_SMALL 0 /* Small (initial) window */
+# define W_FULL 1 /* Full (final) window */
+
+/*
+ * Move types
+ */
+
+# define M_DISCARD 0
+# define M_DRAW 1
+# define M_PLAY 2
+# define M_ORDER 3
+
+/*
+ * Scores
+ */
+
+# define SC_SAFETY 100
+# define SC_ALL_SAFE 300
+# define SC_COUP 300
+# define SC_TRIP 400
+# define SC_SAFE 300
+# define SC_DELAY 300
+# define SC_EXTENSION 200
+# define SC_SHUT_OUT 500
+
+/*
+ * safety descriptions
+ */
+
+# define S_UNKNOWN 0 /* location of safety unknown */
+# define S_IN_HAND 1 /* safety in player's hand */
+# define S_PLAYED 2 /* safety has been played */
+# define S_GAS_SAFE 0 /* Gas safety card index */
+# define S_SPARE_SAFE 1 /* Tire safety card index */
+# define S_DRIVE_SAFE 2 /* Driveing safety card index */
+# define S_RIGHT_WAY 3 /* Right-of-Way card index */
+# define S_CONV 15 /* conversion from C_ to S_ */
+
+/*
+ * card numbers
+ */
+
+# define C_INIT -1
+# define C_25 0
+# define C_50 1
+# define C_75 2
+# define C_100 3
+# define C_200 4
+# define C_EMPTY 5
+# define C_FLAT 6
+# define C_CRASH 7
+# define C_STOP 8
+# define C_LIMIT 9
+# define C_GAS 10
+# define C_SPARE 11
+# define C_REPAIRS 12
+# define C_GO 13
+# define C_END_LIMIT 14
+# define C_GAS_SAFE 15
+# define C_SPARE_SAFE 16
+# define C_DRIVE_SAFE 17
+# define C_RIGHT_WAY 18
+
+/*
+ * prompt types
+ */
+
+# define MOVEPROMPT 0
+# define REALLYPROMPT 1
+# define ANOTHERHANDPROMPT 2
+# define ANOTHERGAMEPROMPT 3
+# define SAVEGAMEPROMPT 4
+# define SAMEFILEPROMPT 5
+# define FILEPROMPT 6
+# define EXTENSIONPROMPT 7
+# define OVERWRITEFILEPROMPT 8
+
+# ifdef SYSV
+# define srandom(x) srand(x)
+# define random() rand()
+
+# ifndef attron
+# define erasechar() _tty.c_cc[VERASE]
+# define killchar() _tty.c_cc[VKILL]
+# endif
+# else
+# ifndef erasechar
+# define erasechar() _tty.sg_erase
+# define killchar() _tty.sg_kill
+# endif
+# endif SYSV
+
+typedef struct {
+ bool coups[NUM_SAFE];
+ bool can_go;
+ bool new_battle;
+ bool new_speed;
+ short safety[NUM_SAFE];
+ short sh_safety[NUM_SAFE];
+ short nummiles[NUM_MILES];
+ short sh_nummiles[NUM_MILES];
+ CARD hand[HAND_SZ];
+ CARD sh_hand[HAND_SZ];
+ CARD battle;
+ CARD sh_battle;
+ CARD speed;
+ CARD sh_speed;
+ int mileage;
+ int sh_mileage;
+ int hand_tot;
+ int sh_hand_tot;
+ int safescore;
+ int sh_safescore;
+ int coupscore;
+ int total;
+ int sh_total;
+ int games;
+ int sh_games;
+ int was_finished;
+} PLAY;
+
+/*
+ * macros
+ */
+
+# define other(x) (1 - x)
+# define nextplay() (Play = other(Play))
+# define nextwin(x) (1 - x)
+# define opposite(x) (Opposite[x])
+# define issafety(x) (x >= C_GAS_SAFE)
+
+/*
+ * externals
+ */
+
+extern bool Debug, Finished, Next, On_exit, Order, Saved;
+
+extern char *C_fmt, **C_name, *Fromfile, Initstr[];
+
+extern int Card_no, End, Handstart, Movetype, Numcards[], Numgos,
+ Numneed[], Numseen[NUM_CARDS], Play, Value[], Window;
+
+extern CARD Deck[DECK_SZ], Discard, Opposite[NUM_CARDS], Sh_discard,
+ *Topcard;
+
+extern FILE *outf;
+
+extern PLAY Player[2];
+
+extern WINDOW *Board, *Miles, *Score;
+
+/*
+ * functions
+ */
+
+CARD getcard();
diff --git a/mille/misc.c b/mille/misc.c
new file mode 100644
index 00000000..acb0d385
--- /dev/null
+++ b/mille/misc.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)misc.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "mille.h"
+#ifndef unctrl
+#include "unctrl.h"
+#endif
+
+# include <sys/file.h>
+
+# ifdef attron
+# include <term.h>
+# define _tty cur_term->Nttyb
+# endif attron
+
+/*
+ * @(#)misc.c 1.2 (Berkeley) 3/28/83
+ */
+
+#define NUMSAFE 4
+
+/* VARARGS1 */
+error(str, arg)
+char *str;
+{
+ stdscr = Score;
+ mvprintw(ERR_Y, ERR_X, str, arg);
+ clrtoeol();
+ putchar('\07');
+ refresh();
+ stdscr = Board;
+ return FALSE;
+}
+
+CARD
+getcard()
+{
+ reg int c, c1;
+
+ for (;;) {
+ while ((c = readch()) == '\n' || c == '\r' || c == ' ')
+ continue;
+ if (islower(c))
+ c = toupper(c);
+ if (c == killchar() || c == erasechar())
+ return -1;
+ addstr(unctrl(c));
+ clrtoeol();
+ switch (c) {
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ c -= '0';
+ break;
+ case '0': case 'P': case 'p':
+ c = 0;
+ break;
+ default:
+ putchar('\07');
+ addch('\b');
+ if (!isprint(c))
+ addch('\b');
+ c = -1;
+ break;
+ }
+ refresh();
+ if (c >= 0) {
+ while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ')
+ if (c1 == killchar())
+ return -1;
+ else if (c1 == erasechar()) {
+ addch('\b');
+ clrtoeol();
+ refresh();
+ goto cont;
+ }
+ else
+ write(0, "\07", 1);
+ return c;
+ }
+cont: ;
+ }
+}
+
+check_ext(forcomp)
+reg bool forcomp; {
+
+
+ if (End == 700)
+ if (Play == PLAYER) {
+ if (getyn(EXTENSIONPROMPT)) {
+extend:
+ if (!forcomp)
+ End = 1000;
+ return TRUE;
+ }
+ else {
+done:
+ if (!forcomp)
+ Finished = TRUE;
+ return FALSE;
+ }
+ }
+ else {
+ reg PLAY *pp, *op;
+ reg int i, safe, miles;
+
+ pp = &Player[COMP];
+ op = &Player[PLAYER];
+ for (safe = 0, i = 0; i < NUMSAFE; i++)
+ if (pp->safety[i] != S_UNKNOWN)
+ safe++;
+ if (safe < 2)
+ goto done;
+ if (op->mileage == 0 || onecard(op)
+ || (op->can_go && op->mileage >= 500))
+ goto done;
+ for (miles = 0, i = 0; i < NUMSAFE; i++)
+ if (op->safety[i] != S_PLAYED
+ && pp->safety[i] == S_UNKNOWN)
+ miles++;
+ if (miles + safe == NUMSAFE)
+ goto extend;
+ for (miles = 0, i = 0; i < HAND_SZ; i++)
+ if ((safe = pp->hand[i]) <= C_200)
+ miles += Value[safe];
+ if (miles + (Topcard - Deck) * 3 > 1000)
+ goto extend;
+ goto done;
+ }
+ else
+ goto done;
+}
+
+/*
+ * Get a yes or no answer to the given question. Saves are
+ * also allowed. Return TRUE if the answer was yes, FALSE if no.
+ */
+getyn(promptno)
+register int promptno; {
+
+ reg char c;
+
+ Saved = FALSE;
+ for (;;) {
+ leaveok(Board, FALSE);
+ prompt(promptno);
+ clrtoeol();
+ refresh();
+ switch (c = readch()) {
+ case 'n': case 'N':
+ addch('N');
+ refresh();
+ leaveok(Board, TRUE);
+ return FALSE;
+ case 'y': case 'Y':
+ addch('Y');
+ refresh();
+ leaveok(Board, TRUE);
+ return TRUE;
+ case 's': case 'S':
+ addch('S');
+ refresh();
+ Saved = save();
+ continue;
+ default:
+ addstr(unctrl(c));
+ refresh();
+ putchar('\07');
+ break;
+ }
+ }
+}
+
+/*
+ * Check to see if more games are desired. If not, and game
+ * came from a saved file, make sure that they don't want to restore
+ * it. Exit appropriately.
+ */
+check_more() {
+
+ flush_input();
+
+ On_exit = TRUE;
+ if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
+ if (getyn(ANOTHERGAMEPROMPT))
+ return;
+ else {
+ /*
+ * must do accounting normally done in main()
+ */
+ if (Player[PLAYER].total > Player[COMP].total)
+ Player[PLAYER].games++;
+ else if (Player[PLAYER].total < Player[COMP].total)
+ Player[COMP].games++;
+ Player[COMP].total = 0;
+ Player[PLAYER].total = 0;
+ }
+ else
+ if (getyn(ANOTHERHANDPROMPT))
+ return;
+ if (!Saved && getyn(SAVEGAMEPROMPT))
+ if (!save())
+ return;
+ die();
+}
+
+readch()
+{
+ reg int cnt;
+ static char c;
+
+ for (cnt = 0; read(0, &c, 1) <= 0; cnt++)
+ if (cnt > 100)
+ exit(1);
+ return c;
+}
+
+flush_input()
+{
+# ifdef TIOCFLUSH
+ static int ioctl_args = O_RDONLY;
+
+ (void) ioctl(fileno(stdin), TIOCFLUSH, &ioctl_args);
+# else
+ fflush(stdin);
+# endif
+}
diff --git a/mille/move.c b/mille/move.c
new file mode 100644
index 00000000..c29baca2
--- /dev/null
+++ b/mille/move.c
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)move.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "mille.h"
+#ifndef unctrl
+#include "unctrl.h"
+#endif
+
+# ifdef attron
+# include <term.h>
+# define _tty cur_term->Nttyb
+# endif attron
+
+/*
+ * @(#)move.c 1.2 (Berkeley) 3/28/83
+ */
+
+#undef CTRL
+#define CTRL(c) (c - 'A' + 1)
+
+char *Movenames[] = {
+ "M_DISCARD", "M_DRAW", "M_PLAY", "M_ORDER"
+ };
+
+domove()
+{
+ reg PLAY *pp;
+ reg int i, j;
+ reg bool goodplay;
+
+ pp = &Player[Play];
+ if (Play == PLAYER)
+ getmove();
+ else
+ calcmove();
+ Next = FALSE;
+ goodplay = TRUE;
+ switch (Movetype) {
+ case M_DISCARD:
+ if (haspicked(pp)) {
+ if (pp->hand[Card_no] == C_INIT)
+ if (Card_no == 6)
+ Finished = TRUE;
+ else
+ error("no card there");
+ else {
+ if (issafety(pp->hand[Card_no])) {
+ error("discard a safety?");
+ goodplay = FALSE;
+ break;
+ }
+ Discard = pp->hand[Card_no];
+ pp->hand[Card_no] = C_INIT;
+ Next = TRUE;
+ if (Play == PLAYER)
+ account(Discard);
+ }
+ }
+ else
+ error("must pick first");
+ break;
+ case M_PLAY:
+ goodplay = playcard(pp);
+ break;
+ case M_DRAW:
+ Card_no = 0;
+ if (Topcard <= Deck)
+ error("no more cards");
+ else if (haspicked(pp))
+ error("already picked");
+ else {
+ pp->hand[0] = *--Topcard;
+#ifdef DEBUG
+ if (Debug)
+ fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
+#endif
+acc:
+ if (Play == COMP) {
+ account(*Topcard);
+ if (issafety(*Topcard))
+ pp->safety[*Topcard-S_CONV] = S_IN_HAND;
+ }
+ if (pp->hand[1] == C_INIT && Topcard > Deck) {
+ Card_no = 1;
+ pp->hand[1] = *--Topcard;
+#ifdef DEBUG
+ if (Debug)
+ fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
+#endif
+ goto acc;
+ }
+ pp->new_battle = FALSE;
+ pp->new_speed = FALSE;
+ }
+ break;
+
+ case M_ORDER:
+ break;
+ }
+ /*
+ * move blank card to top by one of two methods. If the
+ * computer's hand was sorted, the randomness for picking
+ * between equally valued cards would be lost
+ */
+ if (Order && Movetype != M_DRAW && goodplay && pp == &Player[PLAYER])
+ sort(pp->hand);
+ else
+ for (i = 1; i < HAND_SZ; i++)
+ if (pp->hand[i] == C_INIT) {
+ for (j = 0; pp->hand[j] == C_INIT; j++)
+ if (j >= HAND_SZ) {
+ j = 0;
+ break;
+ }
+ pp->hand[i] = pp->hand[j];
+ pp->hand[j] = C_INIT;
+ }
+ if (Topcard <= Deck)
+ check_go();
+ if (Next)
+ nextplay();
+}
+
+/*
+ * Check and see if either side can go. If they cannot,
+ * the game is over
+ */
+check_go() {
+
+ reg CARD card;
+ reg PLAY *pp, *op;
+ reg int i;
+
+ for (pp = Player; pp < &Player[2]; pp++) {
+ op = (pp == &Player[COMP] ? &Player[PLAYER] : &Player[COMP]);
+ for (i = 0; i < HAND_SZ; i++) {
+ card = pp->hand[i];
+ if (issafety(card) || canplay(pp, op, card)) {
+#ifdef DEBUG
+ if (Debug) {
+ fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card);
+ fprintf(outf, "issafety(card) = %d, ", issafety(card));
+ fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card));
+ }
+#endif
+ return;
+ }
+#ifdef DEBUG
+ else if (Debug)
+ fprintf(outf, "CHECK_GO: cannot play %s\n",
+ C_name[card]);
+#endif
+ }
+ }
+ Finished = TRUE;
+}
+
+playcard(pp)
+reg PLAY *pp;
+{
+ reg int v;
+ reg CARD card;
+
+ /*
+ * check and see if player has picked
+ */
+ switch (pp->hand[Card_no]) {
+ default:
+ if (!haspicked(pp))
+mustpick:
+ return error("must pick first");
+ case C_GAS_SAFE: case C_SPARE_SAFE:
+ case C_DRIVE_SAFE: case C_RIGHT_WAY:
+ break;
+ }
+
+ card = pp->hand[Card_no];
+#ifdef DEBUG
+ if (Debug)
+ fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]);
+#endif
+ Next = FALSE;
+ switch (card) {
+ case C_200:
+ if (pp->nummiles[C_200] == 2)
+ return error("only two 200's per hand");
+ case C_100: case C_75:
+ if (pp->speed == C_LIMIT)
+ return error("limit of 50");
+ case C_50:
+ if (pp->mileage + Value[card] > End)
+ return error("puts you over %d", End);
+ case C_25:
+ if (!pp->can_go)
+ return error("cannot move now");
+ pp->nummiles[card]++;
+ v = Value[card];
+ pp->total += v;
+ pp->hand_tot += v;
+ if ((pp->mileage += v) == End)
+ check_ext(FALSE);
+ break;
+
+ case C_GAS: case C_SPARE: case C_REPAIRS:
+ if (pp->battle != opposite(card))
+ return error("can't play \"%s\"", C_name[card]);
+ pp->battle = card;
+ if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
+ pp->can_go = TRUE;
+ break;
+
+ case C_GO:
+ if (pp->battle != C_INIT && pp->battle != C_STOP
+ && !isrepair(pp->battle))
+ return error("cannot play \"Go\" on a \"%s\"",
+ C_name[pp->battle]);
+ pp->battle = C_GO;
+ pp->can_go = TRUE;
+ break;
+
+ case C_END_LIMIT:
+ if (pp->speed != C_LIMIT)
+ return error("not limited");
+ pp->speed = C_END_LIMIT;
+ break;
+
+ case C_EMPTY: case C_FLAT: case C_CRASH:
+ case C_STOP:
+ pp = &Player[other(Play)];
+ if (!pp->can_go)
+ return error("opponent cannot go");
+ else if (pp->safety[safety(card) - S_CONV] == S_PLAYED)
+protected:
+ return error("opponent is protected");
+ pp->battle = card;
+ pp->new_battle = TRUE;
+ pp->can_go = FALSE;
+ pp = &Player[Play];
+ break;
+
+ case C_LIMIT:
+ pp = &Player[other(Play)];
+ if (pp->speed == C_LIMIT)
+ return error("opponent has limit");
+ if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
+ goto protected;
+ pp->speed = C_LIMIT;
+ pp->new_speed = TRUE;
+ pp = &Player[Play];
+ break;
+
+ case C_GAS_SAFE: case C_SPARE_SAFE:
+ case C_DRIVE_SAFE: case C_RIGHT_WAY:
+ if (pp->battle == opposite(card)
+ || (card == C_RIGHT_WAY && pp->speed == C_LIMIT)) {
+ if (!(card == C_RIGHT_WAY && !isrepair(pp->battle))) {
+ pp->battle = C_GO;
+ pp->can_go = TRUE;
+ }
+ if (card == C_RIGHT_WAY && pp->speed == C_LIMIT)
+ pp->speed = C_INIT;
+ if (pp->new_battle
+ || (pp->new_speed && card == C_RIGHT_WAY)) {
+ pp->coups[card - S_CONV] = TRUE;
+ pp->total += SC_COUP;
+ pp->hand_tot += SC_COUP;
+ pp->coupscore += SC_COUP;
+ }
+ }
+ /*
+ * if not coup, must pick first
+ */
+ else if (pp->hand[0] == C_INIT && Topcard > Deck)
+ goto mustpick;
+ pp->safety[card - S_CONV] = S_PLAYED;
+ pp->total += SC_SAFETY;
+ pp->hand_tot += SC_SAFETY;
+ if ((pp->safescore += SC_SAFETY) == NUM_SAFE * SC_SAFETY) {
+ pp->total += SC_ALL_SAFE;
+ pp->hand_tot += SC_ALL_SAFE;
+ }
+ if (card == C_RIGHT_WAY) {
+ if (pp->speed == C_LIMIT)
+ pp->speed = C_INIT;
+ if (pp->battle == C_STOP || pp->battle == C_INIT) {
+ pp->can_go = TRUE;
+ pp->battle = C_INIT;
+ }
+ if (!pp->can_go && isrepair(pp->battle))
+ pp->can_go = TRUE;
+ }
+ Next = -1;
+ break;
+
+ case C_INIT:
+ error("no card there");
+ Next = -1;
+ break;
+ }
+ if (pp == &Player[PLAYER])
+ account(card);
+ pp->hand[Card_no] = C_INIT;
+ Next = (Next == -1 ? FALSE : TRUE);
+ return TRUE;
+}
+
+getmove()
+{
+ reg char c, *sp;
+#ifdef EXTRAP
+ static bool last_ex = FALSE; /* set if last command was E */
+
+ if (last_ex) {
+ undoex();
+ prboard();
+ last_ex = FALSE;
+ }
+#endif
+ for (;;) {
+ prompt(MOVEPROMPT);
+ leaveok(Board, FALSE);
+ refresh();
+ while ((c = readch()) == killchar() || c == erasechar())
+ continue;
+ if (islower(c))
+ c = toupper(c);
+ if (isprint(c) && !isspace(c)) {
+ addch(c);
+ refresh();
+ }
+ switch (c) {
+ case 'P': /* Pick */
+ Movetype = M_DRAW;
+ goto ret;
+ case 'U': /* Use Card */
+ case 'D': /* Discard Card */
+ if ((Card_no = getcard()) < 0)
+ break;
+ Movetype = (c == 'U' ? M_PLAY : M_DISCARD);
+ goto ret;
+ case 'O': /* Order */
+ Order = !Order;
+ if (Window == W_SMALL) {
+ if (!Order)
+ mvwaddstr(Score, 12, 21,
+ "o: order hand");
+ else
+ mvwaddstr(Score, 12, 21,
+ "o: stop ordering");
+ wclrtoeol(Score);
+ }
+ Movetype = M_ORDER;
+ goto ret;
+ case 'Q': /* Quit */
+ rub(); /* Same as a rubout */
+ break;
+ case 'W': /* Window toggle */
+ Window = nextwin(Window);
+ newscore();
+ prscore(TRUE);
+ wrefresh(Score);
+ break;
+ case 'R': /* Redraw screen */
+ case CTRL('L'):
+ wrefresh(curscr);
+ break;
+ case 'S': /* Save game */
+ On_exit = FALSE;
+ save();
+ break;
+ case 'E': /* Extrapolate */
+#ifdef EXTRAP
+ if (last_ex)
+ break;
+ Finished = TRUE;
+ if (Window != W_FULL)
+ newscore();
+ prscore(FALSE);
+ wrefresh(Score);
+ last_ex = TRUE;
+ Finished = FALSE;
+#else
+ error("%c: command not implemented", c);
+#endif
+ break;
+ case '\r': /* Ignore RETURNs and */
+ case '\n': /* Line Feeds */
+ case ' ': /* Spaces */
+ case '\0': /* and nulls */
+ break;
+#ifdef DEBUG
+ case 'Z': /* Debug code */
+ if (!Debug && outf == NULL) {
+ char buf[MAXPATHLEN];
+
+ prompt(FILEPROMPT);
+ leaveok(Board, FALSE);
+ refresh();
+ sp = buf;
+ while ((*sp = readch()) != '\n') {
+ if (*sp == killchar())
+ goto over;
+ else if (*sp == erasechar()) {
+ if (--sp < buf)
+ sp = buf;
+ else {
+ addch('\b');
+ if (*sp < ' ')
+ addch('\b');
+ clrtoeol();
+ }
+ }
+ else
+ addstr(unctrl(*sp++));
+ refresh();
+ }
+ *sp = '\0';
+ leaveok(Board, TRUE);
+ if ((outf = fopen(buf, "w")) == NULL)
+ perror(buf);
+ setbuf(outf, (char *)NULL);
+ }
+ Debug = !Debug;
+ break;
+#endif
+ default:
+ error("unknown command: %s", unctrl(c));
+ break;
+ }
+ }
+ret:
+ leaveok(Board, TRUE);
+}
+/*
+ * return whether or not the player has picked
+ */
+haspicked(pp)
+reg PLAY *pp; {
+
+ reg int card;
+
+ if (Topcard <= Deck)
+ return TRUE;
+ switch (pp->hand[Card_no]) {
+ case C_GAS_SAFE: case C_SPARE_SAFE:
+ case C_DRIVE_SAFE: case C_RIGHT_WAY:
+ card = 1;
+ break;
+ default:
+ card = 0;
+ break;
+ }
+ return (pp->hand[card] != C_INIT);
+}
+
+account(card)
+reg CARD card; {
+
+ reg CARD oppos;
+
+ if (card == C_INIT)
+ return;
+ ++Numseen[card];
+ if (Play == COMP)
+ switch (card) {
+ case C_GAS_SAFE:
+ case C_SPARE_SAFE:
+ case C_DRIVE_SAFE:
+ oppos = opposite(card);
+ Numgos += Numcards[oppos] - Numseen[oppos];
+ break;
+ case C_CRASH:
+ case C_FLAT:
+ case C_EMPTY:
+ case C_STOP:
+ Numgos++;
+ break;
+ }
+}
+
+prompt(promptno)
+int promptno;
+{
+ static char *names[] = {
+ ">>:Move:",
+ "Really?",
+ "Another hand?",
+ "Another game?",
+ "Save game?",
+ "Same file?",
+ "file:",
+ "Extension?",
+ "Overwrite file?",
+ };
+ static int last_prompt = -1;
+
+ if (promptno == last_prompt)
+ move(MOVE_Y, MOVE_X + strlen(names[promptno]) + 1);
+ else {
+ move(MOVE_Y, MOVE_X);
+ if (promptno == MOVEPROMPT)
+ standout();
+ addstr(names[promptno]);
+ if (promptno == MOVEPROMPT)
+ standend();
+ addch(' ');
+ last_prompt = promptno;
+ }
+ clrtoeol();
+}
+
+sort(hand)
+reg CARD *hand;
+{
+ reg CARD *cp, *tp;
+ reg CARD temp;
+
+ cp = hand;
+ hand += HAND_SZ;
+ for ( ; cp < &hand[-1]; cp++)
+ for (tp = cp + 1; tp < hand; tp++)
+ if (*cp > *tp) {
+ temp = *cp;
+ *cp = *tp;
+ *tp = temp;
+ }
+}
+
diff --git a/mille/print.c b/mille/print.c
new file mode 100644
index 00000000..1d32a097
--- /dev/null
+++ b/mille/print.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)print.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "mille.h"
+
+/*
+ * @(#)print.c 1.1 (Berkeley) 4/1/82
+ */
+
+# define COMP_STRT 20
+# define CARD_STRT 2
+
+prboard() {
+
+ reg PLAY *pp;
+ reg int i, j, k, temp;
+
+ for (k = 0; k < 2; k++) {
+ pp = &Player[k];
+ temp = k * COMP_STRT + CARD_STRT;
+ for (i = 0; i < NUM_SAFE; i++)
+ if (pp->safety[i] == S_PLAYED && !pp->sh_safety[i]) {
+ mvaddstr(i, temp, C_name[i + S_CONV]);
+ if (pp->coups[i])
+ mvaddch(i, temp - CARD_STRT, '*');
+ pp->sh_safety[i] = TRUE;
+ }
+ show_card(14, temp, pp->battle, &pp->sh_battle);
+ show_card(16, temp, pp->speed, &pp->sh_speed);
+ for (i = C_25; i <= C_200; i++) {
+ reg char *name;
+ reg int end;
+
+ if (pp->nummiles[i] == pp->sh_nummiles[i])
+ continue;
+
+ name = C_name[i];
+ temp = k * 40;
+ end = pp->nummiles[i];
+ for (j = pp->sh_nummiles[i]; j < end; j++)
+ mvwaddstr(Miles, i + 1, (j << 2) + temp, name);
+ pp->sh_nummiles[i] = end;
+ }
+ }
+ prscore(TRUE);
+ temp = CARD_STRT;
+ pp = &Player[PLAYER];
+ for (i = 0; i < HAND_SZ; i++)
+ show_card(i + 6, temp, pp->hand[i], &pp->sh_hand[i]);
+ mvprintw(6, COMP_STRT + CARD_STRT, "%2d", Topcard - Deck);
+ show_card(8, COMP_STRT + CARD_STRT, Discard, &Sh_discard);
+ if (End == 1000) {
+ move(EXT_Y, EXT_X);
+ standout();
+ addstr("Extension");
+ standend();
+ }
+ wrefresh(Board);
+ wrefresh(Miles);
+ wrefresh(Score);
+}
+
+/*
+ * show_card:
+ * Show the given card if it is different from the last one shown
+ */
+show_card(y, x, c, lc)
+int y, x;
+register CARD c, *lc;
+{
+ if (c == *lc)
+ return;
+
+ mvprintw(y, x, C_fmt, C_name[c]);
+ *lc = c;
+}
+
+static char Score_fmt[] = "%4d";
+
+prscore(for_real)
+reg bool for_real; {
+
+ reg PLAY *pp;
+ reg int x;
+
+ stdscr = Score;
+ for (pp = Player; pp < &Player[2]; pp++) {
+ x = (pp - Player) * 6 + 21;
+ show_score(1, x, pp->mileage, &pp->sh_mileage);
+ if (pp->safescore != pp->sh_safescore) {
+ mvprintw(2, x, Score_fmt, pp->safescore);
+ if (pp->safescore == 400)
+ mvaddstr(3, x + 1, "300");
+ else
+ mvaddstr(3, x + 1, " 0");
+ mvprintw(4, x, Score_fmt, pp->coupscore);
+ pp->sh_safescore = pp->safescore;
+ }
+ if (Window == W_FULL || Finished) {
+#ifdef EXTRAP
+ if (for_real)
+ finalscore(pp);
+ else
+ extrapolate(pp);
+#else
+ finalscore(pp);
+#endif
+ show_score(11, x, pp->hand_tot, &pp->sh_hand_tot);
+ show_score(13, x, pp->total, &pp->sh_total);
+ show_score(14, x, pp->games, &pp->sh_games);
+ }
+ else {
+ show_score(6, x, pp->hand_tot, &pp->sh_hand_tot);
+ show_score(8, x, pp->total, &pp->sh_total);
+ show_score(9, x, pp->games, &pp->sh_games);
+ }
+ }
+ stdscr = Board;
+}
+
+/*
+ * show_score:
+ * Show a score value if it is different from the last time we
+ * showed it.
+ */
+show_score(y, x, s, ls)
+int y, x;
+register int s, *ls;
+{
+ if (s == *ls)
+ return;
+
+ mvprintw(y, x, Score_fmt, s);
+ *ls = s;
+}
diff --git a/mille/roll.c b/mille/roll.c
new file mode 100644
index 00000000..bdeedfef
--- /dev/null
+++ b/mille/roll.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)roll.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "mille.h"
+
+/*
+ * This routine rolls ndie nside-sided dice.
+ *
+ * @(#)roll.c 1.1 (Berkeley) 4/1/82
+ *
+ */
+
+roll(ndie, nsides)
+reg int ndie, nsides; {
+
+ reg int tot;
+ extern unsigned int random();
+
+ tot = 0;
+ while (ndie--)
+ tot += random() % nsides + 1;
+ return tot;
+}
diff --git a/mille/save.c b/mille/save.c
new file mode 100644
index 00000000..0467454a
--- /dev/null
+++ b/mille/save.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)save.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "mille.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#ifndef unctrl
+#include "unctrl.h"
+#endif
+
+# ifdef attron
+# include <term.h>
+# define _tty cur_term->Nttyb
+# endif attron
+
+/*
+ * @(#)save.c 1.2 (Berkeley) 3/28/83
+ */
+
+typedef struct stat STAT;
+
+char *ctime();
+
+int read(), write();
+
+/*
+ * This routine saves the current game for use at a later date
+ */
+
+save() {
+
+ extern int errno;
+ reg char *sp;
+ reg int outf;
+ reg time_t *tp;
+ char buf[80];
+ time_t tme;
+ STAT junk;
+
+ tp = &tme;
+ if (Fromfile && getyn(SAMEFILEPROMPT))
+ strcpy(buf, Fromfile);
+ else {
+over:
+ prompt(FILEPROMPT);
+ leaveok(Board, FALSE);
+ refresh();
+ sp = buf;
+ while ((*sp = readch()) != '\n') {
+ if (*sp == killchar())
+ goto over;
+ else if (*sp == erasechar()) {
+ if (--sp < buf)
+ sp = buf;
+ else {
+ addch('\b');
+ /*
+ * if the previous char was a control
+ * char, cover up two characters.
+ */
+ if (*sp < ' ')
+ addch('\b');
+ clrtoeol();
+ }
+ }
+ else {
+ addstr(unctrl(*sp));
+ ++sp;
+ }
+ refresh();
+ }
+ *sp = '\0';
+ leaveok(Board, TRUE);
+ }
+
+ /*
+ * check for existing files, and confirm overwrite if needed
+ */
+
+ if (sp == buf || (!Fromfile && stat(buf, &junk) > -1
+ && getyn(OVERWRITEFILEPROMPT) == FALSE))
+ return FALSE;
+
+ if ((outf = creat(buf, 0644)) < 0) {
+ error(strerror(errno));
+ return FALSE;
+ }
+ mvwaddstr(Score, ERR_Y, ERR_X, buf);
+ wrefresh(Score);
+ time(tp); /* get current time */
+ strcpy(buf, ctime(tp));
+ for (sp = buf; *sp != '\n'; sp++)
+ continue;
+ *sp = '\0';
+ varpush(outf, write);
+ close(outf);
+ wprintw(Score, " [%s]", buf);
+ wclrtoeol(Score);
+ wrefresh(Score);
+ return TRUE;
+}
+
+/*
+ * This does the actual restoring. It returns TRUE if the
+ * backup was made on exiting, in which case certain things must
+ * be cleaned up before the game starts.
+ */
+rest_f(file)
+reg char *file; {
+
+ reg char *sp;
+ reg int inf;
+ char buf[80];
+ STAT sbuf;
+
+ if ((inf = open(file, 0)) < 0) {
+ perror(file);
+ exit(1);
+ }
+ if (fstat(inf, &sbuf) < 0) { /* get file stats */
+ perror(file);
+ exit(1);
+ }
+ varpush(inf, read);
+ close(inf);
+ strcpy(buf, ctime(&sbuf.st_mtime));
+ for (sp = buf; *sp != '\n'; sp++)
+ continue;
+ *sp = '\0';
+ /*
+ * initialize some necessary values
+ */
+ (void)sprintf(Initstr, "%s [%s]\n", file, buf);
+ Fromfile = file;
+ return !On_exit;
+}
+
diff --git a/mille/table.c b/mille/table.c
new file mode 100644
index 00000000..767f9f8f
--- /dev/null
+++ b/mille/table.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1982 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)table.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# define DEBUG
+
+/*
+ * @(#)table.c 1.1 (Berkeley) 4/1/82
+ */
+
+# include "mille.h"
+
+main() {
+
+ reg int i, j, count;
+
+ printf(" %16s -> %5s %5s %4s %s\n", "Card", "cards", "count", "need", "opposite");
+ for (i = 0; i < NUM_CARDS - 1; i++) {
+ for (j = 0, count = 0; j < DECK_SZ; j++)
+ if (Deck[j] == i)
+ count++;
+ printf("%2d %16s -> %5d %5d %4d %s\n", i, C_name[i], Numcards[i], count, Numneed[i], C_name[opposite(i)]);
+ }
+}
+
diff --git a/mille/types.c b/mille/types.c
new file mode 100644
index 00000000..6ae59911
--- /dev/null
+++ b/mille/types.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)types.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "mille.h"
+
+/*
+ * @(#)types.c 1.1 (Berkeley) 4/1/82
+ */
+
+isrepair(card)
+reg CARD card; {
+
+ return card == C_GAS || card == C_SPARE || card == C_REPAIRS || card == C_INIT;
+}
+
+safety(card)
+reg CARD card; {
+
+ switch (card) {
+ case C_EMPTY:
+ case C_GAS:
+ case C_GAS_SAFE:
+ return C_GAS_SAFE;
+ case C_FLAT:
+ case C_SPARE:
+ case C_SPARE_SAFE:
+ return C_SPARE_SAFE;
+ case C_CRASH:
+ case C_REPAIRS:
+ case C_DRIVE_SAFE:
+ return C_DRIVE_SAFE;
+ case C_GO:
+ case C_STOP:
+ case C_RIGHT_WAY:
+ case C_LIMIT:
+ case C_END_LIMIT:
+ return C_RIGHT_WAY;
+ }
+ /* NOTREACHED */
+}
+
diff --git a/mille/unctrl.h b/mille/unctrl.h
new file mode 100644
index 00000000..9983a822
--- /dev/null
+++ b/mille/unctrl.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)unctrl.h 5.4 (Berkeley) 6/1/90
+ */
+
+/*
+ * unctrl.h
+ */
+
+extern char *_unctrl[];
+
+# define unctrl(ch) (_unctrl[ch & 0177])
diff --git a/mille/varpush.c b/mille/varpush.c
new file mode 100644
index 00000000..7603b800
--- /dev/null
+++ b/mille/varpush.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)varpush.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <paths.h>
+# include "mille.h"
+
+/*
+ * @(#)varpush.c 1.1 (Berkeley) 4/1/82
+ */
+
+int read(), write();
+
+/*
+ * push variables around via the routine func() on the file
+ * channel file. func() is either read or write.
+ */
+varpush(file, func)
+reg int file;
+reg int (*func)(); {
+
+ int temp;
+
+ (*func)(file, (char *) &Debug, sizeof Debug);
+ (*func)(file, (char *) &Finished, sizeof Finished);
+ (*func)(file, (char *) &Order, sizeof Order);
+ (*func)(file, (char *) &End, sizeof End);
+ (*func)(file, (char *) &On_exit, sizeof On_exit);
+ (*func)(file, (char *) &Handstart, sizeof Handstart);
+ (*func)(file, (char *) &Numgos, sizeof Numgos);
+ (*func)(file, (char *) Numseen, sizeof Numseen);
+ (*func)(file, (char *) &Play, sizeof Play);
+ (*func)(file, (char *) &Window, sizeof Window);
+ (*func)(file, (char *) Deck, sizeof Deck);
+ (*func)(file, (char *) &Discard, sizeof Discard);
+ (*func)(file, (char *) Player, sizeof Player);
+ if (func == read) {
+ read(file, (char *) &temp, sizeof temp);
+ Topcard = &Deck[temp];
+#ifdef DEBUG
+ if (Debug) {
+ char buf[80];
+over:
+ printf("Debug file:");
+ gets(buf);
+ if ((outf = fopen(buf, "w")) == NULL) {
+ perror(buf);
+ goto over;
+ }
+ if (strcmp(buf, _PATH_DEVNULL) != 0)
+ setbuf(outf, (char *)NULL);
+ }
+#endif
+ }
+ else {
+ temp = Topcard - Deck;
+ write(file, (char *) &temp, sizeof temp);
+ }
+}
diff --git a/monop/Makefile b/monop/Makefile
new file mode 100644
index 00000000..b7909b58
--- /dev/null
+++ b/monop/Makefile
@@ -0,0 +1,24 @@
+# @(#)Makefile 5.5 (Berkeley) 5/11/90
+
+PROG= monop
+SRCS= monop.c cards.c execute.c getinp.c houses.c jail.c misc.c morg.c \
+ print.c prop.c rent.c roll.c spec.c trade.c
+MAN6= monop.0
+DPADD= ${LIBCOMPAT}
+LDADD= -lcompat
+HIDEGAME=hidegame
+CLEANFILES+=initdeck cards.pck
+
+all: cards.pck
+
+cards.pck: initdeck
+ ./initdeck ${.CURDIR}/cards.inp
+
+initdeck: initdeck.c
+ ${CC} ${CFLAGS} -o ${.TARGET} ${.CURDIR}/initdeck.c
+
+beforeinstall:
+ install -o ${BINOWN} -g ${BINGRP} -m 444 cards.pck \
+ ${DESTDIR}/usr/share/games
+
+.include <bsd.prog.mk>
diff --git a/monop/brd.dat b/monop/brd.dat
new file mode 100644
index 00000000..60586fcd
--- /dev/null
+++ b/monop/brd.dat
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)brd.dat 5.4 (Berkeley) 4/8/91
+ */
+
+/* name (COLOR) owner type desc cost */
+
+{"=== GO ===", -1, SAFE, 0 },
+{"Mediterranean ave. (P)", -1, PRPTY, &prop[0], 60 },
+{"Community Chest i", -1, CC, },
+{"Baltic ave. (P)", -1, PRPTY, &prop[1], 60 },
+{"Income Tax", -1, INC_TAX, },
+{"Reading RR", -1, RR, &rr[0], 200 },
+{"Oriental ave. (L)", -1, PRPTY, &prop[2], 100 },
+{"Chance i", -1, CHANCE, },
+{"Vermont ave. (L)", -1, PRPTY, &prop[3], 100 },
+{"Connecticut ave. (L)", -1, PRPTY, &prop[4], 120 },
+{"Just Visiting", -1, SAFE, 0 },
+{"St. Charles pl. (V)", -1, PRPTY, &prop[5], 140 },
+{"Electric Co.", -1, UTIL, &util[0], 150 },
+{"States ave. (V)", -1, PRPTY, &prop[6], 140 },
+{"Virginia ave. (V)", -1, PRPTY, &prop[7], 160 },
+{"Pennsylvania RR", -1, RR, &rr[1], 200 },
+{"St. James pl. (O)", -1, PRPTY, &prop[8], 180 },
+{"Community Chest ii", -1, CC, },
+{"Tennessee ave. (O)", -1, PRPTY, &prop[9], 180 },
+{"New York ave. (O)", -1, PRPTY, &prop[10], 200 },
+{"Free Parking", -1, SAFE, 0 },
+{"Kentucky ave. (R)", -1, PRPTY, &prop[11], 220 },
+{"Chance ii", -1, CHANCE, },
+{"Indiana ave. (R)", -1, PRPTY, &prop[12], 220 },
+{"Illinois ave. (R)", -1, PRPTY, &prop[13], 240 },
+{"B&O RR", -1, RR, &rr[2], 200 },
+{"Atlantic ave. (Y)", -1, PRPTY, &prop[14], 260 },
+{"Ventnor ave. (Y)", -1, PRPTY, &prop[15], 260 },
+{"Water Works", -1, UTIL, &util[1], 150 },
+{"Marvin Gardens (Y)", -1, PRPTY, &prop[16], 280 },
+{"GO TO JAIL", -1, GOTO_J, },
+{"Pacific ave. (G)", -1, PRPTY, &prop[17], 300 },
+{"N. Carolina ave. (G)", -1, PRPTY, &prop[18], 300 },
+{"Community Chest iii", -1, CC, },
+{"Pennsylvania ave. (G)", -1, PRPTY, &prop[19], 320 },
+{"Short Line RR", -1, RR, &rr[3], 200 },
+{"Chance iii", -1, CHANCE, },
+{"Park place (D)", -1, PRPTY, &prop[20], 350 },
+{"Luxury Tax", -1, LUX_TAX, },
+{"Boardwalk (D)", -1, PRPTY, &prop[21], 400 },
+{"JAIL", -1, IN_JAIL, }
diff --git a/monop/cards.c b/monop/cards.c
new file mode 100644
index 00000000..5041c089
--- /dev/null
+++ b/monop/cards.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cards.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+# include "pathnames.h"
+
+/*
+ * These routine deal with the card decks
+ */
+
+# define GOJF 'F' /* char for get-out-of-jail-free cards */
+
+# ifndef DEV
+static char *cardfile = _PATH_CARDS;
+# else
+static char *cardfile = "cards.pck";
+# endif
+
+static FILE *deckf;
+
+/*
+ * This routine initializes the decks from the data file,
+ * which it opens.
+ */
+init_decks() {
+
+ if ((deckf=fopen(cardfile, "r")) == NULL) {
+file_err:
+ perror(cardfile);
+ exit(1);
+ }
+ if (fread(deck, sizeof (DECK), 2, deckf) != 2)
+ goto file_err;
+ set_up(&CC_D);
+ set_up(&CH_D);
+}
+/*
+ * This routine sets up the offset pointers for the given deck.
+ */
+set_up(dp)
+DECK *dp; {
+
+ reg int r1, r2;
+ int i;
+
+ dp->offsets = (long *) calloc(sizeof (long), dp->num_cards);
+ if (fread(dp->offsets, sizeof(long), dp->num_cards, deckf) != dp->num_cards) {
+ perror(cardfile);
+ exit(1);
+ }
+ dp->last_card = 0;
+ dp->gojf_used = FALSE;
+ for (i = 0; i < dp->num_cards; i++) {
+ reg long temp;
+
+ r1 = roll(1, dp->num_cards) - 1;
+ r2 = roll(1, dp->num_cards) - 1;
+ temp = dp->offsets[r2];
+ dp->offsets[r2] = dp->offsets[r1];
+ dp->offsets[r1] = temp;
+ }
+}
+/*
+ * This routine draws a card from the given deck
+ */
+get_card(dp)
+DECK *dp; {
+
+ reg char type_maj, type_min;
+ reg int num;
+ int i, per_h, per_H, num_h, num_H;
+ OWN *op;
+
+ do {
+ fseek(deckf, dp->offsets[dp->last_card], 0);
+ dp->last_card = ++(dp->last_card) % dp->num_cards;
+ type_maj = getc(deckf);
+ } while (dp->gojf_used && type_maj == GOJF);
+ type_min = getc(deckf);
+ num = getw(deckf);
+ printmes();
+ switch (type_maj) {
+ case '+': /* get money */
+ if (type_min == 'A') {
+ for (i = 0; i < num_play; i++)
+ if (i != player)
+ play[i].money -= num;
+ num = num * (num_play - 1);
+ }
+ cur_p->money += num;
+ break;
+ case '-': /* lose money */
+ if (type_min == 'A') {
+ for (i = 0; i < num_play; i++)
+ if (i != player)
+ play[i].money += num;
+ num = num * (num_play - 1);
+ }
+ cur_p->money -= num;
+ break;
+ case 'M': /* move somewhere */
+ switch (type_min) {
+ case 'F': /* move forward */
+ num -= cur_p->loc;
+ if (num < 0)
+ num += 40;
+ break;
+ case 'J': /* move to jail */
+ goto_jail();
+ return;
+ case 'R': /* move to railroad */
+ spec = TRUE;
+ num = (int)((cur_p->loc + 5)/10)*10 + 5 - cur_p->loc;
+ break;
+ case 'U': /* move to utility */
+ spec = TRUE;
+ if (cur_p->loc >= 12 && cur_p->loc < 28)
+ num = 28 - cur_p->loc;
+ else {
+ num = 12 - cur_p->loc;
+ if (num < 0)
+ num += 40;
+ }
+ break;
+ case 'B':
+ num = -num;
+ break;
+ }
+ move(num);
+ break;
+ case 'T': /* tax */
+ if (dp == &CC_D) {
+ per_h = 40;
+ per_H = 115;
+ }
+ else {
+ per_h = 25;
+ per_H = 100;
+ }
+ num_h = num_H = 0;
+ for (op = cur_p->own_list; op; op = op->next)
+ if (op->sqr->type == PRPTY)
+ if (op->sqr->desc->houses == 5)
+ ++num_H;
+ else
+ num_h += op->sqr->desc->houses;
+ num = per_h * num_h + per_H * num_H;
+ printf("You had %d Houses and %d Hotels, so that cost you $%d\n", num_h, num_H, num);
+ if (num == 0)
+ lucky("");
+ else
+ cur_p->money -= num;
+ break;
+ case GOJF: /* get-out-of-jail-free card */
+ cur_p->num_gojf++;
+ dp->gojf_used = TRUE;
+ break;
+ }
+ spec = FALSE;
+}
+/*
+ * This routine prints out the message on the card
+ */
+printmes() {
+
+ reg char c;
+
+ printline();
+ fflush(stdout);
+ while ((c = getc(deckf)) != '\0')
+ putchar(c);
+ printline();
+ fflush(stdout);
+}
diff --git a/monop/cards.inp b/monop/cards.inp
new file mode 100644
index 00000000..1867e87b
--- /dev/null
+++ b/monop/cards.inp
@@ -0,0 +1,122 @@
+FF
+>> GET OUT OF JAIL FREE <<
+Keep this card until needed or sold
+%%
+++25
+Receive for Services $25.
+%%
+++200
+Bank Error in Your Favor.
+Collect $200.
+%%
+++20
+Income Tax Refund.
+Collect $20.
+%%
+--100
+Pay Hospital $100
+%%
+++100
+Life Insurance Matures.
+Collect $100
+%%
+++45
+From sale of Stock You get $45.
+%%
+TX
+You are Assessed for street repairs.
+ $40 per House
+ $115 per Hotel
+%%
+++100
+X-mas Fund Matures.
+Collect $100.
+%%
+++11
+You have won Second Prize in a Beauty Contest
+Collect $11
+%%
+MF0
+Advance to GO
+(Collect $200)
+%%
+++100
+You inherit $100
+%%
+--150
+Pay School Tax of $150.
+%%
+MJ
+ >> GO TO JAIL <<
+Go Directly to Jail. Do not pass GO Do not collect $200.
+%%
++A50
+ >> GRAND OPERA OPENING <<
+Collect $50 from each player for opening night seats.
+%%
+--50
+Doctor's Fee: Pay $50.
+%-
+FF
+>> GET OUT OF JAIL FREE <<
+Keep this card until needed or sold
+%%
+MR
+Advance to the nearest Railroad, and pay owner
+Twice the rental to which he is otherwise entitled.
+If Railroad is unowned you may buy it from the bank
+%%
+MU
+Advance to the nearest Utility.
+If unowned, you may buy it from the bank.
+If owned, throw dice and pay oner a total of ten times
+the amount thrown.
+%%
+MB3
+Go Back 3 Spaces
+%%
+MR
+Advance to the nearest Railroad, and pay owner
+Twice the rental to which he is otherwise entitled.
+If Railroad is unowned you may buy it from the bank
+%%
+MJ
+ >> GO DIRECTLY TO JAIL <<
+Do not pass GO, Do not Collect $200.
+%%
+MF5
+Take a Ride on the Reading.
+If you pass GO, collect $200.
+%%
+MF39
+Take a Walk on the Board Walk.
+ (Advance To Board Walk)
+%%
+MF24
+Advance to Illinos Ave.
+%%
+MF0
+Advance to Go
+%%
+MF11
+Advance to St. Charles Place.
+If you pass GO, collect $200.
+%%
+TX
+Make general repairs on all of your Property.
+For Each House pay $25.
+For Each Hotel pay $100.
+%%
+-A50
+You have been elected Chairman of the Board.
+Pay each player $50.
+%%
+--15
+Pay Poor Tax of $15
+%%
+++50
+Bank pays you Dividend of $50.
+%%
+++150
+Your Building and Loan Matures.
+Collect $150.
diff --git a/monop/deck.h b/monop/deck.h
new file mode 100644
index 00000000..507b14c4
--- /dev/null
+++ b/monop/deck.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)deck.h 5.3 (Berkeley) 6/1/90
+ */
+
+# define bool char
+
+# define CC_D deck[0]
+# define CH_D deck[1]
+
+struct dk_st { /* deck description structure */
+ int num_cards; /* number of cards in deck */
+ int last_card; /* number of last card picked */
+ bool gojf_used; /* set if gojf card out of deck */
+ long *offsets; /* offests for start of cards */
+};
+
+typedef struct dk_st DECK;
diff --git a/monop/execute.c b/monop/execute.c
new file mode 100644
index 00000000..9b8889e4
--- /dev/null
+++ b/monop/execute.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)execute.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include "monop.ext"
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/time.h>
+
+# define SEGSIZE 8192
+
+typedef struct stat STAT;
+typedef struct tm TIME;
+
+extern char etext[], /* end of text space */
+ rub();
+
+static char buf[257],
+ *yn_only[] = { "yes", "no"};
+
+static bool new_play; /* set if move on to new player */
+
+/*
+ * This routine executes the given command by index number
+ */
+execute(com_num)
+reg int com_num; {
+
+ new_play = FALSE; /* new_play is true if fixing */
+ (*func[com_num])();
+ notify();
+ force_morg();
+ if (new_play)
+ next_play();
+ else if (num_doub)
+ printf("%s rolled doubles. Goes again\n", cur_p->name);
+}
+/*
+ * This routine moves a piece around.
+ */
+do_move() {
+
+ reg int r1, r2;
+ reg bool was_jail;
+
+ new_play = was_jail = FALSE;
+ printf("roll is %d, %d\n", r1=roll(1, 6), r2=roll(1, 6));
+ if (cur_p->loc == JAIL) {
+ was_jail++;
+ if (!move_jail(r1, r2)) {
+ new_play++;
+ goto ret;
+ }
+ }
+ else {
+ if (r1 == r2 && ++num_doub == 3) {
+ printf("That's 3 doubles. You go to jail\n");
+ goto_jail();
+ new_play++;
+ goto ret;
+ }
+ move(r1+r2);
+ }
+ if (r1 != r2 || was_jail)
+ new_play++;
+ret:
+ return;
+}
+/*
+ * This routine moves a normal move
+ */
+move(rl)
+reg int rl; {
+
+ reg int old_loc;
+
+ old_loc = cur_p->loc;
+ cur_p->loc = (cur_p->loc + rl) % N_SQRS;
+ if (cur_p->loc < old_loc && rl > 0) {
+ cur_p->money += 200;
+ printf("You pass %s and get $200\n", board[0].name);
+ }
+ show_move();
+}
+/*
+ * This routine shows the results of a move
+ */
+show_move() {
+
+ reg SQUARE *sqp;
+
+ sqp = &board[cur_p->loc];
+ printf("That puts you on %s\n", sqp->name);
+ switch (sqp->type) {
+ case SAFE:
+ printf("That is a safe place\n");
+ break;
+ case CC:
+ cc(); break;
+ case CHANCE:
+ chance(); break;
+ case INC_TAX:
+ inc_tax(); break;
+ case GOTO_J:
+ goto_jail(); break;
+ case LUX_TAX:
+ lux_tax(); break;
+ case PRPTY:
+ case RR:
+ case UTIL:
+ if (sqp->owner < 0) {
+ printf("That would cost $%d\n", sqp->cost);
+ if (getyn("Do you want to buy? ") == 0) {
+ buy(player, sqp);
+ cur_p->money -= sqp->cost;
+ }
+ else if (num_play > 2)
+ bid(sqp);
+ }
+ else if (sqp->owner == player)
+ printf("You own it.\n");
+ else
+ rent(sqp);
+ }
+}
+/*
+ * This routine saves the current game for use at a later date
+ */
+save() {
+
+ reg char *sp;
+ reg int outf, num;
+ time_t t;
+ int *dat_end;
+ struct stat sb;
+ unsgn start, end;
+
+ printf("Which file do you wish to save it in? ");
+ sp = buf;
+ while ((*sp++=getchar()) != '\n')
+ continue;
+ *--sp = '\0';
+
+ /*
+ * check for existing files, and confirm overwrite if needed
+ */
+
+ if (stat(buf, &sb) > -1
+ && getyn("File exists. Do you wish to overwrite? ", yn_only) > 0)
+ return;
+
+ if ((outf=creat(buf, 0644)) < 0) {
+ perror(buf);
+ return;
+ }
+ printf("\"%s\" ", buf);
+ time(&t); /* get current time */
+ strcpy(buf, ctime(&t));
+ for (sp = buf; *sp != '\n'; sp++)
+ continue;
+ *sp = '\0';
+# if 0
+ start = (((int) etext + (SEGSIZE-1)) / SEGSIZE ) * SEGSIZE;
+# else
+ start = 0;
+# endif
+ end = sbrk(0);
+ while (start < end) { /* write out entire data space */
+ num = start + 16 * 1024 > end ? end - start : 16 * 1024;
+ write(outf, start, num);
+ start += num;
+ }
+ close(outf);
+ printf("[%s]\n", buf);
+}
+/*
+ * This routine restores an old game from a file
+ */
+restore() {
+
+ reg char *sp;
+
+ printf("Which file do you wish to restore from? ");
+ for (sp = buf; (*sp=getchar()) != '\n'; sp++)
+ continue;
+ *sp = '\0';
+ rest_f(buf);
+}
+/*
+ * This does the actual restoring. It returns TRUE if the
+ * backup was successful, else false.
+ */
+rest_f(file)
+reg char *file; {
+
+ reg char *sp;
+ reg int inf, num;
+ char buf[80];
+ unsgn start, end;
+ STAT sbuf;
+
+ if ((inf=open(file, 0)) < 0) {
+ perror(file);
+ return FALSE;
+ }
+ printf("\"%s\" ", file);
+ if (fstat(inf, &sbuf) < 0) { /* get file stats */
+ perror(file);
+ exit(1);
+ }
+# if 0
+ start = (((int) etext + (SEGSIZE-1)) / SEGSIZE ) * SEGSIZE;
+# else
+ start = 0;
+# endif
+ brk(end = start + sbuf.st_size);
+ while (start < end) { /* write out entire data space */
+ num = start + 16 * 1024 > end ? end - start : 16 * 1024;
+ read(inf, start, num);
+ start += num;
+ }
+ close(inf);
+ strcpy(buf, ctime(&sbuf.st_mtime));
+ for (sp = buf; *sp != '\n'; sp++)
+ continue;
+ *sp = '\0';
+ printf("[%s]\n", buf);
+ return TRUE;
+}
diff --git a/monop/getinp.c b/monop/getinp.c
new file mode 100644
index 00000000..62ea845f
--- /dev/null
+++ b/monop/getinp.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getinp.c 5.4 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include <stdio.h>
+# include <ctype.h>
+
+# define reg register
+
+# define LINE 70
+
+static char buf[257];
+
+getinp(prompt, list)
+char *prompt, *list[]; {
+
+ reg int i, n_match, match;
+ char *sp;
+ int plen;
+ static int comp();
+
+ for (;;) {
+inter:
+ printf(prompt);
+ for (sp = buf; (*sp=getchar()) != '\n'; )
+ if (*sp == -1) /* check for interupted system call */
+ goto inter;
+ else if (sp != buf || *sp != ' ')
+ sp++;
+ if (buf[0] == '?' && buf[1] == '\n') {
+ printf("Valid inputs are: ");
+ for (i = 0, match = 18; list[i]; i++) {
+ if ((match+=(n_match=strlen(list[i]))) > LINE) {
+ printf("\n\t");
+ match = n_match + 8;
+ }
+ if (*list[i] == '\0') {
+ match += 8;
+ printf("<RETURN>");
+ }
+ else
+ printf(list[i]);
+ if (list[i+1])
+ printf(", ");
+ else
+ putchar('\n');
+ match += 2;
+ }
+ continue;
+ }
+ *sp = '\0';
+ for (sp = buf; *sp; sp++)
+ if (isupper(*sp))
+ *sp = tolower(*sp);
+ for (i = n_match = 0; list[i]; i++)
+ if (comp(list[i])) {
+ n_match++;
+ match = i;
+ }
+ if (n_match == 1)
+ return match;
+ else if (buf[0] != '\0')
+ printf("Illegal response: \"%s\". Use '?' to get list of valid answers\n", buf);
+ }
+}
+
+static
+comp(s1)
+char *s1; {
+
+ reg char *sp, *tsp, c;
+
+ if (buf[0] != '\0')
+ for (sp = buf, tsp = s1; *sp; ) {
+ c = isupper(*tsp) ? tolower(*tsp) : *tsp;
+ tsp++;
+ if (c != *sp++)
+ return 0;
+ }
+ else if (*s1 != '\0')
+ return 0;
+ return 1;
+}
diff --git a/monop/houses.c b/monop/houses.c
new file mode 100644
index 00000000..e59182c3
--- /dev/null
+++ b/monop/houses.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)houses.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+static char *names[N_MON+2],
+ cur_prop[80];
+
+static MON *monops[N_MON];
+
+/*
+ * These routines deal with buying and selling houses
+ */
+buy_houses() {
+
+ reg int num_mon;
+ reg MON *mp;
+ reg OWN *op;
+ bool good,got_morg;
+ int i,p;
+
+over:
+ num_mon = 0;
+ good = TRUE;
+ got_morg = FALSE;
+ for (op = cur_p->own_list; op && op->sqr->type != PRPTY; op = op->next)
+ continue;
+ while (op)
+ if (op->sqr->desc->monop) {
+ mp = op->sqr->desc->mon_desc;
+ names[num_mon] = (monops[num_mon]=mp)->name;
+ num_mon++;
+ got_morg = good = FALSE;
+ for (i = 0; i < mp->num_in; i++) {
+ if (op->sqr->desc->morg)
+ got_morg++;
+ if (op->sqr->desc->houses != 5)
+ good++;
+ op = op->next;
+ }
+ if (!good || got_morg)
+ --num_mon;
+ }
+ else
+ op = op->next;
+ if (num_mon == 0) {
+ if (got_morg)
+ printf("You can't build on mortgaged monopolies.\n");
+ else if (!good)
+ printf("You can't build any more.\n");
+ else
+ printf("But you don't have any monopolies!!\n");
+ return;
+ }
+ if (num_mon == 1)
+ buy_h(monops[0]);
+ else {
+ names[num_mon++] = "done";
+ names[num_mon--] = 0;
+ if ((p=getinp("Which property do you wish to buy houses for? ", names)) == num_mon)
+ return;
+ buy_h(monops[p]);
+ goto over;
+ }
+}
+
+buy_h(mnp)
+MON *mnp; {
+
+ reg int i;
+ reg MON *mp;
+ reg int price;
+ shrt input[3],temp[3];
+ int tot;
+ PROP *pp;
+
+ mp = mnp;
+ price = mp->h_cost * 50;
+blew_it:
+ list_cur(mp);
+ printf("Houses will cost $%d\n", price);
+ printf("How many houses do you wish to buy for\n");
+ for (i = 0; i < mp->num_in; i++) {
+ pp = mp->sq[i]->desc;
+over:
+ if (pp->houses == 5) {
+ printf("%s (H):\n", mp->sq[i]->name);
+ input[i] = 0;
+ temp[i] = 5;
+ continue;
+ }
+ (void)sprintf(cur_prop, "%s (%d): ",
+ mp->sq[i]->name, pp->houses);
+ input[i] = get_int(cur_prop);
+ temp[i] = input[i] + pp->houses;
+ if (temp[i] > 5) {
+ printf("That's too many. The most you can buy is %d\n",
+ 5 - pp->houses);
+ goto over;
+ }
+ }
+ if (mp->num_in == 3 && (abs(temp[0] - temp[1]) > 1 ||
+ abs(temp[0] - temp[2]) > 1 || abs(temp[1] - temp[2]) > 1)) {
+err: printf("That makes the spread too wide. Try again\n");
+ goto blew_it;
+ }
+ else if (mp->num_in == 2 && abs(temp[0] - temp[1]) > 1)
+ goto err;
+ for (tot = i = 0; i < mp->num_in; i++)
+ tot += input[i];
+ if (tot) {
+ printf("You asked for %d houses for $%d\n", tot, tot * price);
+ if (getyn("Is that ok? ", yn) == 0) {
+ cur_p->money -= tot * price;
+ for (tot = i = 0; i < mp->num_in; i++)
+ mp->sq[i]->desc->houses = temp[i];
+ }
+ }
+}
+
+/*
+ * This routine sells houses.
+ */
+sell_houses() {
+
+ reg int num_mon;
+ reg MON *mp;
+ reg OWN *op;
+ bool good;
+ int p;
+
+over:
+ num_mon = 0;
+ good = TRUE;
+ for (op = cur_p->own_list; op; op = op->next)
+ if (op->sqr->type == PRPTY && op->sqr->desc->monop) {
+ mp = op->sqr->desc->mon_desc;
+ names[num_mon] = (monops[num_mon]=mp)->name;
+ num_mon++;
+ good = 0;
+ do
+ if (!good && op->sqr->desc->houses != 0)
+ good++;
+ while (op->next && op->sqr->desc->mon_desc == mp
+ && (op=op->next));
+ if (!good)
+ --num_mon;
+ }
+ if (num_mon == 0) {
+ printf("You don't have any houses to sell!!\n");
+ return;
+ }
+ if (num_mon == 1)
+ sell_h(monops[0]);
+ else {
+ names[num_mon++] = "done";
+ names[num_mon--] = 0;
+ if ((p=getinp("Which property do you wish to sell houses from? ", names)) == num_mon)
+ return;
+ sell_h(monops[p]);
+ notify();
+ goto over;
+ }
+}
+
+sell_h(mnp)
+MON *mnp; {
+
+ reg int i;
+ reg MON *mp;
+ reg int price;
+ shrt input[3],temp[3];
+ int tot;
+ PROP *pp;
+
+ mp = mnp;
+ price = mp->h_cost * 25;
+blew_it:
+ printf("Houses will get you $%d apiece\n", price);
+ list_cur(mp);
+ printf("How many houses do you wish to sell from\n");
+ for (i = 0; i < mp->num_in; i++) {
+ pp = mp->sq[i]->desc;
+over:
+ if (pp->houses == 0) {
+ printf("%s (0):\n", mp->sq[i]->name);
+ input[i] = temp[i] = 0;
+ continue;
+ }
+ if (pp->houses < 5)
+ (void)sprintf(cur_prop,"%s (%d): ",
+ mp->sq[i]->name,pp->houses);
+ else
+ (void)sprintf(cur_prop,"%s (H): ",mp->sq[i]->name);
+ input[i] = get_int(cur_prop);
+ temp[i] = pp->houses - input[i];
+ if (temp[i] < 0) {
+ printf("That's too many. The most you can sell is %d\n", pp->houses);
+ goto over;
+ }
+ }
+ if (mp->num_in == 3 && (abs(temp[0] - temp[1]) > 1 ||
+ abs(temp[0] - temp[2]) > 1 || abs(temp[1] - temp[2]) > 1)) {
+err: printf("That makes the spread too wide. Try again\n");
+ goto blew_it;
+ }
+ else if (mp->num_in == 2 && abs(temp[0] - temp[1]) > 1)
+ goto err;
+ for (tot = i = 0; i < mp->num_in; i++)
+ tot += input[i];
+ if (tot) {
+ printf("You asked to sell %d houses for $%d\n",tot,tot * price);
+ if (getyn("Is that ok? ", yn) == 0) {
+ cur_p->money += tot * price;
+ for (tot = i = 0; i < mp->num_in; i++)
+ mp->sq[i]->desc->houses = temp[i];
+ }
+ }
+}
+
+list_cur(mp)
+reg MON *mp; {
+
+ reg int i;
+ reg SQUARE *sqp;
+
+ for (i = 0; i < mp->num_in; i++) {
+ sqp = mp->sq[i];
+ if (sqp->desc->houses == 5)
+ printf("%s (H) ", sqp->name);
+ else
+ printf("%s (%d) ", sqp->name, sqp->desc->houses);
+ }
+ putchar('\n');
+}
diff --git a/monop/initdeck.c b/monop/initdeck.c
new file mode 100644
index 00000000..b5c3b89a
--- /dev/null
+++ b/monop/initdeck.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)initdeck.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <stdio.h>
+# include "deck.h"
+
+/*
+ * This program initializes the card files for monopoly.
+ * It reads in a data file with Com. Chest cards, followed by
+ * the Chance card. The two are seperated by a line of "%-".
+ * All other cards are seperated by lines of "%%". In the front
+ * of the file is the data for the decks in the same order.
+ * This includes the seek pointer for the start of each card.
+ * All cards start with their execution code, followed by the
+ * string to print, terminated with a null byte.
+ */
+
+# define TRUE 1
+# define FALSE 0
+
+# define bool char
+# define reg register
+
+char *infile = "cards.inp", /* input file */
+ *outfile = "cards.pck"; /* "packed" file */
+
+extern long ftell();
+extern char *calloc();
+
+DECK deck[2];
+
+FILE *inf, *outf;
+
+main(ac, av)
+int ac;
+char *av[]; {
+
+ getargs(ac, av);
+ if ((inf = fopen(infile, "r")) == NULL) {
+ perror(infile);
+ exit(1);
+ }
+ count();
+ /*
+ * allocate space for pointers.
+ */
+ CC_D.offsets = (long *)calloc(CC_D.num_cards + 1, sizeof (long));
+ CH_D.offsets = (long *)calloc(CH_D.num_cards + 1, sizeof (long));
+ fseek(inf, 0L, 0);
+ if ((outf = fopen(outfile, "w")) == NULL) {
+ perror(outfile);
+ exit(0);
+ }
+
+ fwrite(deck, sizeof (DECK), 2, outf);
+ fwrite(CC_D.offsets, sizeof (long), CC_D.num_cards, outf);
+ fwrite(CH_D.offsets, sizeof (long), CH_D.num_cards, outf);
+ putem();
+
+ fclose(inf);
+ fseek(outf, 0, 0L);
+ fwrite(deck, sizeof (DECK), 2, outf);
+ fwrite(CC_D.offsets, sizeof (long), CC_D.num_cards, outf);
+ fwrite(CH_D.offsets, sizeof (long), CH_D.num_cards, outf);
+ fclose(outf);
+ printf("There were %d com. chest and %d chance cards\n", CC_D.num_cards, CH_D.num_cards);
+ exit(0);
+}
+
+getargs(ac, av)
+int ac;
+char *av[]; {
+
+ if (ac > 1)
+ infile = av[1];
+ if (ac > 2)
+ outfile = av[2];
+}
+
+/*
+ * count the cards
+ */
+count() {
+
+ reg bool newline;
+ reg DECK *in_deck;
+ reg char c;
+
+ newline = TRUE;
+ in_deck = &CC_D;
+ while ((c=getc(inf)) != EOF)
+ if (newline && c == '%') {
+ newline = FALSE;
+ in_deck->num_cards++;
+ if (getc(inf) == '-')
+ in_deck = &CH_D;
+ }
+ else
+ newline = (c == '\n');
+ in_deck->num_cards++;
+}
+/*
+ * put strings in the file
+ */
+putem() {
+
+ reg bool newline;
+ reg DECK *in_deck;
+ reg char c;
+ reg int num;
+
+ in_deck = &CC_D;
+ CC_D.num_cards = 1;
+ CH_D.num_cards = 0;
+ CC_D.offsets[0] = ftell(outf);
+ putc(getc(inf), outf);
+ putc(getc(inf), outf);
+ for (num = 0; (c=getc(inf)) != '\n'; )
+ num = num * 10 + (c - '0');
+ putw(num, outf);
+ newline = FALSE;
+ while ((c=getc(inf)) != EOF)
+ if (newline && c == '%') {
+ putc('\0', outf);
+ newline = FALSE;
+ if (getc(inf) == '-')
+ in_deck = &CH_D;
+ while (getc(inf) != '\n')
+ continue;
+ in_deck->offsets[in_deck->num_cards++] = ftell(outf);
+ if ((c=getc(inf)) == EOF)
+ break;
+ putc(c, outf);
+ putc(c = getc(inf), outf);
+ for (num = 0; (c=getc(inf)) != EOF && c != '\n'; )
+ num = num * 10 + (c - '0');
+ putw(num, outf);
+ }
+ else {
+ putc(c, outf);
+ newline = (c == '\n');
+ }
+ putc('\0', outf);
+}
diff --git a/monop/jail.c b/monop/jail.c
new file mode 100644
index 00000000..dfad88ee
--- /dev/null
+++ b/monop/jail.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)jail.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+/*
+ * This routine uses a get-out-of-jail-free card to get the
+ * player out of jail.
+ */
+card() {
+
+ if (cur_p->loc != JAIL) {
+ printf("But you're not IN Jail\n");
+ return;
+ }
+ if (cur_p->num_gojf == 0) {
+ printf("But you don't HAVE a get out of jail free card\n");
+ return;
+ }
+ ret_card(cur_p);
+ cur_p->loc = 10; /* just visiting */
+ cur_p->in_jail = 0;
+}
+/*
+ * This routine returns the players get-out-of-jail-free card
+ * to a deck.
+ */
+ret_card(plr)
+reg PLAY *plr; {
+
+ plr->num_gojf--;
+ if (CC_D.gojf_used)
+ CC_D.gojf_used = FALSE;
+ else
+ CH_D.gojf_used = FALSE;
+}
+/*
+ * This routine deals with paying your way out of jail.
+ */
+pay() {
+
+ if (cur_p->loc != JAIL) {
+ printf("But you're not IN Jail\n");
+ return;
+ }
+ cur_p->loc = 10;
+ cur_p->money -= 50;
+ cur_p->in_jail = 0;
+ printf("That cost you $50\n");
+}
+/*
+ * This routine deals with a move in jail
+ */
+move_jail(r1, r2)
+reg int r1, r2; {
+
+ if (r1 != r2) {
+ printf("Sorry, that doesn't get you out\n");
+ if (++(cur_p->in_jail) == 3) {
+ printf("It's your third turn and you didn't roll doubles. You have to pay $50\n");
+ cur_p->money -= 50;
+moveit:
+ cur_p->loc = 10;
+ cur_p->in_jail = 0;
+ move(r1+r2);
+ r1 = r2 - 1; /* kludge: stop new roll w/doub */
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else {
+ printf("Double roll gets you out.\n");
+ goto moveit;
+ }
+}
+printturn() {
+
+ if (cur_p->loc != JAIL)
+ return;
+ printf("(This is your ");
+ switch (cur_p->in_jail) {
+ case 0:
+ printf("1st");
+ break;
+ case 1:
+ printf("2nd");
+ break;
+ case 2:
+ printf("3rd (and final)");
+ break;
+ }
+ printf(" turn in JAIL)\n");
+}
diff --git a/monop/misc.c b/monop/misc.c
new file mode 100644
index 00000000..836437a4
--- /dev/null
+++ b/monop/misc.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)misc.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include "monop.ext"
+# include <ctype.h>
+# include <signal.h>
+
+# define execsh(sh) execl(sh, shell_name[roll(1, num_names)-1], 0)
+
+static char *shell_def = "/bin/csh",
+ *shell_name[] = {
+ ".Hi Mom!",
+ ".Kick Me",
+ ".I'm really the next process down",
+ ".Hi Kids!",
+ ".This space for rent",
+ ".Singin' in the rain....",
+ ".I am but a Cog in the Wheel of Life",
+ ".Look out!!! Behind you!!!!!",
+ ".Looking for a good time, sailor?",
+ ".I don't get NO respect...",
+ ".Augghh! You peeked!"
+ };
+
+static int num_names = sizeof shell_name / sizeof (char *);;
+
+char *shell_in();
+
+/*
+ * This routine executes a truncated set of commands until a
+ * "yes or "no" answer is gotten.
+ */
+getyn(prompt)
+reg char *prompt; {
+
+ reg int com;
+
+ for (;;)
+ if ((com=getinp(prompt, yn)) < 2)
+ return com;
+ else
+ (*func[com-2])();
+}
+/*
+ * This routine tells the player if he's out of money.
+ */
+notify() {
+
+ if (cur_p->money < 0)
+ printf("That leaves you $%d in debt\n", -cur_p->money);
+ else if (cur_p->money == 0)
+ printf("that leaves you broke\n");
+ else if (fixing && !told_em && cur_p->money > 0) {
+ printf("-- You are now Solvent ---\n");
+ told_em = TRUE;
+ }
+}
+/*
+ * This routine switches to the next player
+ */
+next_play() {
+
+ player = ++player % num_play;
+ cur_p = &play[player];
+ num_doub = 0;
+}
+/*
+ * This routine gets an integer from the keyboard after the
+ * given prompt.
+ */
+get_int(prompt)
+reg char *prompt; {
+
+ reg int num;
+ reg char *sp;
+ char buf[257];
+
+ for (;;) {
+inter:
+ printf(prompt);
+ num = 0;
+ for (sp = buf; (*sp=getchar()) != '\n'; sp++)
+ if (*sp == -1) /* check for interrupted system call */
+ goto inter;
+ if (sp == buf)
+ continue;
+ for (sp = buf; isspace(*sp); sp++)
+ continue;
+ for (; isdigit(*sp); sp++)
+ num = num * 10 + *sp - '0';
+ if (*sp == '\n')
+ return num;
+ else
+ printf("I can't understand that\n");
+ }
+}
+/*
+ * This routine sets the monopoly flag from the list given.
+ */
+set_ownlist(pl)
+int pl; {
+
+ reg int num; /* general counter */
+ reg MON *orig; /* remember starting monop ptr */
+ reg OWN *op; /* current owned prop */
+ OWN *orig_op; /* origianl prop before loop */
+
+ op = play[pl].own_list;
+#ifdef DEBUG
+ printf("op [%d] = play[pl [%d] ].own_list;\n", op, pl);
+#endif
+ while (op) {
+#ifdef DEBUG
+ printf("op->sqr->type = %d\n", op->sqr->type);
+#endif
+ switch (op->sqr->type) {
+ case UTIL:
+#ifdef DEBUG
+ printf(" case UTIL:\n");
+#endif
+ for (num = 0; op && op->sqr->type == UTIL; op = op->next)
+ num++;
+ play[pl].num_util = num;
+#ifdef DEBUG
+ printf("play[pl].num_util = num [%d];\n", num);
+#endif
+ break;
+ case RR:
+#ifdef DEBUG
+ printf(" case RR:\n");
+#endif
+ for (num = 0; op && op->sqr->type == RR; op = op->next) {
+#ifdef DEBUG
+ printf("iter: %d\n", num);
+ printf("op = %d, op->sqr = %d, op->sqr->type = %d\n", op, op->sqr, op->sqr->type);
+#endif
+ num++;
+ }
+ play[pl].num_rr = num;
+#ifdef DEBUG
+ printf("play[pl].num_rr = num [%d];\n", num);
+#endif
+ break;
+ case PRPTY:
+#ifdef DEBUG
+ printf(" case PRPTY:\n");
+#endif
+ orig = op->sqr->desc->mon_desc;
+ orig_op = op;
+ num = 0;
+ while (op && op->sqr->desc->mon_desc == orig) {
+#ifdef DEBUG
+ printf("iter: %d\n", num);
+#endif
+ num++;
+#ifdef DEBUG
+ printf("op = op->next ");
+#endif
+ op = op->next;
+#ifdef DEBUG
+ printf("[%d];\n", op);
+#endif
+ }
+#ifdef DEBUG
+ printf("num = %d\n");
+#endif
+ if (orig == 0) {
+ printf("panic: bad monopoly descriptor: orig = %d\n", orig);
+ printf("player # %d\n", pl+1);
+ printhold(pl);
+ printf("orig_op = %d\n", orig_op);
+ printf("orig_op->sqr->type = %d (PRPTY)\n", op->sqr->type);
+ printf("orig_op->next = %d\n", op->next);
+ printf("orig_op->sqr->desc = %d\n", op->sqr->desc);
+ printf("op = %d\n", op);
+ printf("op->sqr->type = %d (PRPTY)\n", op->sqr->type);
+ printf("op->next = %d\n", op->next);
+ printf("op->sqr->desc = %d\n", op->sqr->desc);
+ printf("num = %d\n", num);
+ }
+#ifdef DEBUG
+ printf("orig->num_in = %d\n", orig->num_in);
+#endif
+ if (num == orig->num_in)
+ is_monop(orig, pl);
+ else
+ isnot_monop(orig);
+ break;
+ }
+ }
+}
+/*
+ * This routine sets things up as if it is a new monopoly
+ */
+is_monop(mp, pl)
+reg MON *mp;
+int pl; {
+
+ reg char *sp;
+ reg int i;
+
+ mp->owner = pl;
+ mp->num_own = mp->num_in;
+ for (i = 0; i < mp->num_in; i++)
+ mp->sq[i]->desc->monop = TRUE;
+ mp->name = mp->mon_n;
+}
+/*
+ * This routine sets things up as if it is no longer a monopoly
+ */
+isnot_monop(mp)
+reg MON *mp; {
+
+ reg char *sp;
+ reg int i;
+
+ mp->owner = -1;
+ for (i = 0; i < mp->num_in; i++)
+ mp->sq[i]->desc->monop = FALSE;
+ mp->name = mp->not_m;
+}
+/*
+ * This routine gives a list of the current player's routine
+ */
+list() {
+
+ printhold(player);
+}
+/*
+ * This routine gives a list of a given players holdings
+ */
+list_all() {
+
+ reg int pl;
+
+ while ((pl=getinp("Whose holdings do you want to see? ", name_list)) < num_play)
+ printhold(pl);
+}
+/*
+ * This routine gives the players a chance before it exits.
+ */
+void
+quit() {
+
+ putchar('\n');
+ if (getyn("Do you all really want to quit? ", yn) == 0)
+ exit(0);
+ signal(SIGINT, quit);
+}
+/*
+ * This routine copies one structure to another
+ */
+cpy_st(s1, s2, size)
+reg int *s1, *s2, size; {
+
+ size /= 2;
+ while (size--)
+ *s1++ = *s2++;
+}
+/*
+ * This routine forks off a shell. It uses the users login shell
+ */
+shell_out() {
+
+ static char *shell = NULL;
+
+ printline();
+ if (shell == NULL)
+ shell = shell_in();
+ fflush(stdout);
+ if (!fork()) {
+ signal(SIGINT, SIG_DFL);
+ execsh(shell);
+ }
+ ignoresigs();
+ wait();
+ resetsigs();
+ putchar('\n');
+ printline();
+}
+/*
+ * This routine looks up the users login shell
+ */
+# include <sys/types.h>
+# include <pwd.h>
+
+char *getenv();
+
+char *
+shell_in() {
+
+ reg struct passwd *pp;
+ reg char *sp;
+
+ if ((sp = getenv("SHELL")) == NULL) {
+ pp = getpwuid(getuid());
+ if (pp->pw_shell[0] != '\0')
+ return pp->pw_shell;
+ else
+ return shell_def;
+ /*return (*(pp->pw_shell) != '\0' ? pp->pw_shell : shell_def);*/
+ }
+ return sp;
+}
+/*
+ * This routine sets things up to ignore all the signals.
+ */
+ignoresigs() {
+
+ reg int i;
+
+ for (i = 0; i < NSIG; i++)
+ signal(i, SIG_IGN);
+}
+/*
+ * This routine sets up things as they were before.
+ */
+resetsigs() {
+
+ reg int i;
+
+ for (i = 0; i < NSIG; i++)
+ signal(i, SIG_DFL);
+ signal(SIGINT, quit);
+}
diff --git a/monop/mon.dat b/monop/mon.dat
new file mode 100644
index 00000000..3c185248
--- /dev/null
+++ b/monop/mon.dat
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mon.dat 5.3 (Berkeley) 4/8/91
+ */
+
+/* name owner num_in num_own h_cost not_m mon_n sq */
+{0, -1, 2, 0, 1, "Purple", "PURPLE", {1,3}},
+{0, -1, 3, 0, 1, "Lt. Blue", "LT. BLUE", {6,8,9}},
+{0, -1, 3, 0, 2, "Violet", "VIOLET", {11,13,14}},
+{0, -1, 3, 0, 2, "Orange", "ORANGE", {16,18,19}},
+{0, -1, 3, 0, 3, "Red", "RED", {21,23,24}},
+{0, -1, 3, 0, 3, "Yellow", "YELLOW", {26,27,29}},
+{0, -1, 3, 0, 4, "Green", "GREEN", {31,32,34}},
+{0, -1, 2, 0, 4, "Dk. Blue", "DK. BLUE", {37,39}}
diff --git a/monop/monop.6 b/monop/monop.6
new file mode 100644
index 00000000..6bc7ba07
--- /dev/null
+++ b/monop/monop.6
@@ -0,0 +1,191 @@
+.\" Copyright (c) 1980 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)monop.6 6.4 (Berkeley) 6/23/90
+.\"
+.de Sc \" start command list macro
+.ie n .PD 0
+.el .PD 0.5
+.sp
+..
+.de Cm \" define command macro
+.TP 10
+.ie t .BR "\\$1" :
+.el .IR "\\$1" :
+..
+.de Ec \" end command macro
+.PD 1
+..
+.TH MONOP 6 "June 23, 1990"
+.UC 4
+.SH NAME
+monop \- Monopoly game
+.SH SYNOPSIS
+.B /usr/games/monop
+[ file ]
+.SH DESCRIPTION
+.I Monop
+is reminiscent of the Parker Brother's game Monopoly, and
+monitors a game between 1 to 9 users.
+It is assumed that the rules of Monopoly are known.
+The game follows the standard rules, with the exception that,
+if a property goes up for auction and there are only two solvent players,
+no auction is held and the property remains unowned.
+.PP
+The game, in effect, lends the player money,
+so it is possible to buy something which you cannot afford.
+However, as soon as a person goes into debt,
+he must \*(lqfix the problem\*(rq,
+.IR i.e. ,
+make himself solvent, before play can continue.
+If this is not possible, the player's property reverts to his debtee,
+either a player or the bank.
+A player can resign at any time to any person or the bank,
+which puts the property back on the board, unowned.
+.PP
+Any time that the response to a question is a
+.IR string ,
+e.g., a name, place or person, you can type `?' to get a list of valid answers.
+It is not possible to input a negative number, nor is it ever necessary.
+.Sc
+.IR "A Summary of Commands" :
+.Cm quit
+quit game: This allows you to quit the game. It asks you if you're sure.
+.Cm print
+print board: This prints out the current board.
+The columns have the following meanings (column headings are the same for the
+.BR where ,
+.BR "own holdings" ,
+and
+.B holdings
+commands):
+.PP
+.RS 10
+.TP "\w'Name\ \ 'u"
+Name
+The first ten characters of the name of the square
+.TP
+Own
+The \fInumber\fR of the owner of the property.
+.TP
+Price
+The cost of the property (if any)
+.TP
+Mg
+This field has a `*' in it if the property is mortgaged
+.TP
+#
+If the property is a Utility or Railroad, this is the number
+of such owned by the owner.
+If the property is land, this is the number of houses on it.
+.TP
+Rent
+Current rent on the property. If it is not owned, there is no rent.
+.RE
+.Cm where
+where players are: Tells you where all the players are.
+A `*' indicates the current player.
+.Cm "own\ holdings"
+List your own holdings,
+.IR i.e. ,
+money, get-out-of-jail-free cards, and property.
+.Cm holdings
+holdings list: Look at anyone's holdings.
+It will ask you whose holdings you wish to look at.
+When you are finished, type \*(lqdone\*(rq.
+.Cm shell
+shell escape: Escape to a shell. When the shell dies,
+the program continues where you left off.
+.Cm mortgage
+mortgage property:
+Sets up a list of mortgageable property, and asks which you wish to mortgage.
+.Cm unmortgage
+unmortgage property:
+Unmortgage mortgaged property.
+.Cm buy
+buy houses:
+Sets up a list of monopolies on which you can buy houses.
+If there is more than one, it asks you which you want to buy for.
+It then asks you how many for each piece of property,
+giving the current amount in parentheses after the property name.
+If you build in an unbalanced manner
+(a disparity of more than one house within the same monopoly),
+it asks you to re-input things.
+.Cm sell
+sell houses:
+Sets up a list of monopolies from which you can sell houses.
+It operates in an analogous manner to
+.I buy.
+.Cm card
+card for jail:
+Use a get-out-of-jail-free card to get out of jail.
+If you're not in jail, or you don't have one, it tells you so.
+.Cm pay
+pay for jail:
+Pay $50 to get out of jail, from whence you are put on Just Visiting.
+Difficult to do if you're not there.
+.Cm trade
+This allows you to trade with another player.
+It asks you whom you wish to trade with,
+and then asks you what each wishes to give up.
+You can get a summary at the end, and, in all cases,
+it asks for confirmation of the trade before doing it.
+.Cm resign
+Resign to another player or the bank.
+If you resign to the bank, all property reverts to its virgin state,
+and get-out-of-jail free cards revert to the deck.
+.Cm save
+save game:
+Save the current game in a file for later play.
+You can continue play after saving,
+either by adding the file in which you saved the game after the
+.I monop
+command, or by using the
+.I restore
+command (see below).
+It will ask you which file you wish to save it in,
+and, if the file exists, confirm that you wish to overwrite it.
+.Cm restore
+restore game:
+Read in a previously saved game from a file.
+It leaves the file intact.
+.Cm roll
+Roll the dice and move forward to your new location.
+If you simply hit the <RETURN> key instead of a command,
+it is the same as typing
+.IR roll .
+.Ec
+.SH AUTHOR
+Ken Arnold
+.SH FILES
+/usr/games/lib/cards.pck Chance and Community Chest cards
+.SH BUGS
+No command can be given an argument instead of a response to a query.
diff --git a/monop/monop.c b/monop/monop.c
new file mode 100644
index 00000000..4eeba06c
--- /dev/null
+++ b/monop/monop.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)monop.c 5.7 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.def"
+
+/*
+ * This program implements a monopoly game
+ */
+main(ac, av)
+reg int ac;
+reg char *av[]; {
+
+
+ srand(getpid());
+ if (ac > 1) {
+ if (!rest_f(av[1]))
+ restore();
+ }
+ else {
+ getplayers();
+ init_players();
+ init_monops();
+ }
+ num_luck = sizeof lucky_mes / sizeof (char *);
+ init_decks();
+ signal(2, quit);
+ for (;;) {
+ printf("\n%s (%d) (cash $%d) on %s\n", cur_p->name, player + 1,
+ cur_p->money, board[cur_p->loc].name);
+ printturn();
+ force_morg();
+ execute(getinp("-- Command: ", comlist));
+ }
+}
+/*
+ * This routine gets the names of the players
+ */
+getplayers() {
+
+ reg char *sp;
+ reg int i, j;
+ char buf[257];
+
+blew_it:
+ for (;;) {
+ if ((num_play=get_int("How many players? ")) <= 0 ||
+ num_play > MAX_PL)
+ printf("Sorry. Number must range from 1 to 9\n");
+ else
+ break;
+ }
+ cur_p = play = (PLAY *) calloc(num_play, sizeof (PLAY));
+ for (i = 0; i < num_play; i++) {
+over:
+ printf("Player %d's name: ", i + 1);
+ for (sp = buf; (*sp=getchar()) != '\n'; sp++)
+ continue;
+ if (sp == buf)
+ goto over;
+ *sp++ = '\0';
+ strcpy(name_list[i]=play[i].name=(char *)calloc(1,sp-buf),buf);
+ play[i].money = 1500;
+ }
+ name_list[i++] = "done";
+ name_list[i] = 0;
+ for (i = 0; i < num_play; i++)
+ for (j = i + 1; j < num_play; j++)
+ if (strcasecmp(name_list[i], name_list[j]) == 0) {
+ if (i != num_play - 1)
+ printf("Hey!!! Some of those are IDENTICAL!! Let's try that again....\n");
+ else
+ printf("\"done\" is a reserved word. Please try again\n");
+ for (i = 0; i < num_play; i++)
+ cfree(play[i].name);
+ cfree(play);
+ goto blew_it;
+ }
+}
+/*
+ * This routine figures out who goes first
+ */
+init_players() {
+
+ reg int i, rl, cur_max;
+ bool over;
+ int max_pl;
+
+again:
+ putchar('\n');
+ for (cur_max = i = 0; i < num_play; i++) {
+ printf("%s (%d) rolls %d\n", play[i].name, i+1, rl=roll(2, 6));
+ if (rl > cur_max) {
+ over = FALSE;
+ cur_max = rl;
+ max_pl = i;
+ }
+ else if (rl == cur_max)
+ over++;
+ }
+ if (over) {
+ printf("%d people rolled the same thing, so we'll try again\n",
+ over + 1);
+ goto again;
+ }
+ player = max_pl;
+ cur_p = &play[max_pl];
+ printf("%s (%d) goes first\n", cur_p->name, max_pl + 1);
+}
+/*
+ * This routine initalizes the monopoly structures.
+ */
+init_monops() {
+
+ reg MON *mp;
+ reg int i;
+
+ for (mp = mon; mp < &mon[N_MON]; mp++) {
+ mp->name = mp->not_m;
+ for (i = 0; i < mp->num_in; i++)
+ mp->sq[i] = &board[mp->sqnums[i]];
+ }
+}
diff --git a/monop/monop.def b/monop/monop.def
new file mode 100644
index 00000000..27da9e72
--- /dev/null
+++ b/monop/monop.def
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)monop.def 5.3 (Berkeley) 4/8/91
+ */
+
+# include "monop.h"
+# include "deck.h"
+
+bool fixing, /* set if fixing up debt */
+ trading, /* set if in process of trading */
+ told_em, /* set if told user he's out of debt */
+ spec; /* set if moving by card to RR or UTIL */
+
+char *name_list[MAX_PL+2], /* list of players' names */
+ *comlist[] = { /* list of normal commands */
+ "quit", /* 0 */ "print", /* 1 */
+ "where", /* 2 */ "own holdings", /* 3 */
+ "holdings", /* 4 */ "shell", /* 5 */
+ "mortgage", /* 6 */ "unmortgage", /* 7 */
+ "buy houses", /* 8 */ "sell houses", /* 9 */
+ "card", /* 10 */ "pay", /* 11 */
+ "trade", /* 12 */ "resign", /* 13 */
+ "save", /* 14 */ "restore", /* 15 */
+ "roll", /* 16 */ "", /* 17 */
+ 0
+ },
+ *yn[] = { /* list of commands for yes/no answers */
+ "yes", /* 0 */ "no", /* 1 */
+ "quit", /* 2 */ "print", /* 3 */
+ "where", /* 4 */ "own holdings", /* 5 */
+ "holdings", /* 6 */ "shell", /* 7 */
+ 0
+ },
+ *lucky_mes[] = { /* "got lucky" messages */
+ "You lucky stiff", "You got lucky",
+ "What a lucky person!", "You must have a 4-leaf clover",
+ "My, my! Aren't we lucky!", "Luck smiles upon you",
+ "You got lucky this time", "Lucky person!",
+ "Your karma must certainly be together",
+ "How beautifully Cosmic", "Wow, you must be really with it"
+ /* "I want your autograph", -- Save for later */
+ };
+
+int player, /* current player number */
+ num_play, /* current number of players */
+ num_doub, /* # of doubles current player rolled */
+ /* # of "got lucky" messages */
+ num_luck = sizeof lucky_mes / sizeof (char *),
+ /* list of command functions */
+ buy_houses(), card(), do_move(), do_move(), list(), list_all(),
+ mortgage(), pay(), printboard(), quit(), resign(), restore(),
+ rub(), save(), sell_houses(), shell_out(), trade(),
+ unmortgage(), where(),
+ (*func[])() = { /* array of function calls for commands */
+ quit, /* quit game |* 0 *| */
+ printboard, /* print board |* 1 *| */
+ where, /* where players are |* 2 *| */
+ list, /* own holdings |* 3 *| */
+ list_all, /* holdings list |* 4 *| */
+ shell_out, /* shell |* 5 *| */
+ mortgage, /* mortgage property |* 6 *| */
+ unmortgage, /* unmortgage property |* 7 *| */
+ buy_houses, /* buy houses |* 8 *| */
+ sell_houses, /* sell houses |* 9 *| */
+ card, /* card for jail |* 10 *| */
+ pay, /* pay for jail |* 11 *| */
+ trade, /* trade |* 12 *| */
+ resign, /* resign |* 13 *| */
+ save, /* save game |* 14 *| */
+ restore, /* restore game |* 15 *| */
+ do_move, /* roll |* 16 *| */
+ do_move /* "" |* 17 *| */
+ };
+
+DECK deck[2]; /* Chance and Community Chest */
+
+PLAY *play, /* player structure array ("calloc"ed) */
+ *cur_p; /* pointer to current player's struct */
+
+RR_S rr[N_RR]; /* raildroad descriptions */
+
+UTIL_S util[2]; /* utility descriptions */
+
+MON mon[N_MON] = { /* monopoly descriptions */
+# include "mon.dat"
+};
+
+PROP prop[N_PROP] = { /* typical properties */
+# include "prop.dat"
+};
+
+SQUARE board[N_SQRS+1] = { /* board itself (+1 for Jail) */
+# include "brd.dat"
+};
diff --git a/monop/monop.ext b/monop/monop.ext
new file mode 100644
index 00000000..0f109996
--- /dev/null
+++ b/monop/monop.ext
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)monop.ext 5.3 (Berkeley) 4/8/91
+ */
+
+# include "monop.h"
+# include "deck.h"
+
+extern bool trading, spec, fixing, told_em;
+
+extern char *yn[], *comlist[], *name_list[], *lucky_mes[];
+
+extern int num_play, player, num_doub, num_luck, (*func[])();
+
+extern DECK deck[2];
+
+extern MON mon[];
+
+extern PLAY *play, *cur_p;
+
+extern PROP prop[];
+
+extern RR_S rr[];
+
+extern SQUARE board[];
+
+extern UTIL_S util[];
diff --git a/monop/monop.h b/monop/monop.h
new file mode 100644
index 00000000..9aa3a090
--- /dev/null
+++ b/monop/monop.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)monop.h 5.5 (Berkeley) 6/1/90
+ */
+
+# include <stdio.h>
+
+# define reg register
+# define shrt char
+# define bool char
+# define unsgn unsigned
+
+# define TRUE (1)
+# define FALSE (0)
+
+# define N_MON 8 /* number of monopolies */
+# define N_PROP 22 /* number of normal property squares */
+# define N_RR 4 /* number of railroads */
+# define N_UTIL 2 /* number of utilities */
+# define N_SQRS 40 /* number of squares on board */
+# define MAX_PL 9 /* maximum number of players */
+# define MAX_PRP (N_PROP+N_RR+N_UTIL) /* max # ownable property */
+
+ /* square type numbers */
+# define PRPTY 0 /* normal property */
+# define RR 1 /* railroad */
+# define UTIL 2 /* water works - electric co */
+# define SAFE 3 /* safe spot */
+# define CC 4 /* community chest */
+# define CHANCE 5 /* chance (surprise!!!) */
+# define INC_TAX 6 /* Income tax */
+# define GOTO_J 7 /* Go To Jail! */
+# define LUX_TAX 8 /* Luxury tax */
+# define IN_JAIL 9 /* In jail */
+
+# define JAIL 40 /* JAIL square number */
+
+# define lucky(str) printf("%s%s\n",str,lucky_mes[roll(1,num_luck)-1])
+# define printline() printf("------------------------------\n")
+# define sqnum(sqp) (sqp - board)
+# define swap(A1,A2) if ((A1) != (A2)) { \
+ (A1) ^= (A2); \
+ (A2) ^= (A1); \
+ (A1) ^= (A2); \
+ }
+
+struct sqr_st { /* structure for square */
+ char *name; /* place name */
+ shrt owner; /* owner number */
+ shrt type; /* place type */
+ struct prp_st *desc; /* description struct */
+ int cost; /* cost */
+};
+
+typedef struct sqr_st SQUARE;
+
+struct mon_st { /* monopoly description structure */
+ char *name; /* monop. name (color) */
+ shrt owner; /* owner of monopoly */
+ shrt num_in; /* # in monopoly */
+ shrt num_own; /* # owned (-1: not poss. monop)*/
+ shrt h_cost; /* price of houses */
+ char *not_m; /* name if not monopoly */
+ char *mon_n; /* name if a monopoly */
+ char sqnums[3]; /* Square numbers (used to init)*/
+ SQUARE *sq[3]; /* list of squares in monop */
+};
+
+typedef struct mon_st MON;
+
+/*
+ * This struct describes a property. For railroads and utilities, only
+ * the "morg" member is used.
+ */
+struct prp_st { /* property description structure */
+ bool morg; /* set if mortgaged */
+ bool monop; /* set if monopoly */
+ shrt square; /* square description */
+ shrt houses; /* number of houses */
+ MON *mon_desc; /* name of color */
+ int rent[6]; /* rents */
+};
+
+struct own_st { /* element in list owned things */
+ SQUARE *sqr; /* pointer to square */
+ struct own_st *next; /* next in list */
+};
+
+typedef struct own_st OWN;
+
+struct plr_st { /* player description structure */
+ char *name; /* owner name */
+ shrt num_gojf; /* # of get-out-of-jail-free's */
+ shrt num_rr; /* # of railroads owned */
+ shrt num_util; /* # of water works/elec. co. */
+ shrt loc; /* location on board */
+ shrt in_jail; /* count of turns in jail */
+ int money; /* amount of money */
+ OWN *own_list; /* start of propery list */
+};
+
+typedef struct plr_st PLAY;
+typedef struct prp_st PROP;
+typedef struct prp_st RR_S;
+typedef struct prp_st UTIL_S;
+
+int cc(), chance(), lux_tax(), goto_jail(), inc_tax();
diff --git a/monop/morg.c b/monop/morg.c
new file mode 100644
index 00000000..2c4b97b5
--- /dev/null
+++ b/monop/morg.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)morg.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+/*
+ * These routines deal with mortgaging.
+ */
+
+static char *names[MAX_PRP+2],
+ *morg_coms[] = {
+ "quit", /* 0 */
+ "print", /* 1 */
+ "where", /* 2 */
+ "own holdings", /* 3 */
+ "holdings", /* 4 */
+ "shell", /* 5 */
+ "mortgage", /* 6 */
+ "unmortgage", /* 7 */
+ "buy", /* 8 */
+ "sell", /* 9 */
+ "card", /* 10 */
+ "pay", /* 11 */
+ "trade", /* 12 */
+ "resign", /* 13 */
+ "save game", /* 14 */
+ "restore game", /* 15 */
+ 0
+ };
+
+static shrt square[MAX_PRP+2];
+
+static int num_good,got_houses;
+
+/*
+ * This routine is the command level response the mortgage command.
+ * it gets the list of mortgageable property and asks which are to
+ * be mortgaged.
+ */
+mortgage() {
+
+ reg int prop;
+
+ for (;;) {
+ if (set_mlist() == 0) {
+ if (got_houses)
+ printf("You can't mortgage property with houses on it.\n");
+ else
+ printf("You don't have any un-mortgaged property.\n");
+ return;
+ }
+ if (num_good == 1) {
+ printf("Your only mortageable property is %s\n",names[0]);
+ if (getyn("Do you want to mortgage it? ") == 0)
+ m(square[0]);
+ return;
+ }
+ prop = getinp("Which property do you want to mortgage? ",names);
+ if (prop == num_good)
+ return;
+ m(square[prop]);
+ notify(cur_p);
+ }
+}
+/*
+ * This routine sets up the list of mortgageable property
+ */
+set_mlist() {
+
+ reg OWN *op;
+
+ num_good = 0;
+ for (op = cur_p->own_list; op; op = op->next)
+ if (!op->sqr->desc->morg)
+ if (op->sqr->type == PRPTY && op->sqr->desc->houses)
+ got_houses++;
+ else {
+ names[num_good] = op->sqr->name;
+ square[num_good++] = sqnum(op->sqr);
+ }
+ names[num_good++] = "done";
+ names[num_good--] = 0;
+ return num_good;
+}
+/*
+ * This routine actually mortgages the property.
+ */
+m(prop)
+reg int prop; {
+
+ reg int price;
+
+ price = board[prop].cost/2;
+ board[prop].desc->morg = TRUE;
+ printf("That got you $%d\n",price);
+ cur_p->money += price;
+}
+/*
+ * This routine is the command level repsponse to the unmortgage
+ * command. It gets the list of mortgaged property and asks which are
+ * to be unmortgaged.
+ */
+unmortgage() {
+
+ reg int prop;
+
+ for (;;) {
+ if (set_umlist() == 0) {
+ printf("You don't have any mortgaged property.\n");
+ return;
+ }
+ if (num_good == 1) {
+ printf("Your only mortaged property is %s\n",names[0]);
+ if (getyn("Do you want to unmortgage it? ") == 0)
+ unm(square[0]);
+ return;
+ }
+ prop = getinp("Which property do you want to unmortgage? ",names);
+ if (prop == num_good)
+ return;
+ unm(square[prop]);
+ }
+}
+/*
+ * This routine sets up the list of mortgaged property
+ */
+set_umlist() {
+
+ reg OWN *op;
+
+ num_good = 0;
+ for (op = cur_p->own_list; op; op = op->next)
+ if (op->sqr->desc->morg) {
+ names[num_good] = op->sqr->name;
+ square[num_good++] = sqnum(op->sqr);
+ }
+ names[num_good++] = "done";
+ names[num_good--] = 0;
+ return num_good;
+}
+/*
+ * This routine actually unmortgages the property
+ */
+unm(prop)
+reg int prop; {
+
+ reg int price;
+
+ price = board[prop].cost/2;
+ board[prop].desc->morg = FALSE;
+ price += price/10;
+ printf("That cost you $%d\n",price);
+ cur_p->money -= price;
+ set_umlist();
+}
+/*
+ * This routine forces the indebted player to fix his
+ * financial woes.
+ */
+force_morg() {
+
+ told_em = fixing = TRUE;
+ while (cur_p->money <= 0)
+ fix_ex(getinp("How are you going to fix it up? ",morg_coms));
+ fixing = FALSE;
+}
+/*
+ * This routine is a special execute for the force_morg routine
+ */
+fix_ex(com_num)
+reg int com_num; {
+
+ told_em = FALSE;
+ (*func[com_num])();
+ notify();
+}
diff --git a/monop/pathnames.h b/monop/pathnames.h
new file mode 100644
index 00000000..fb0a3f08
--- /dev/null
+++ b/monop/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 6/1/90
+ */
+
+#define _PATH_CARDS "/usr/share/games/cards.pck"
diff --git a/monop/print.c b/monop/print.c
new file mode 100644
index 00000000..6c91a5ec
--- /dev/null
+++ b/monop/print.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)print.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+static char buf[80], /* output buffer */
+ *header = "Name Own Price Mg # Rent";
+
+/*
+ * This routine prints out the current board
+ */
+printboard() {
+
+ reg int i;
+
+ printf("%s\t%s\n", header, header);
+ for (i = 0; i < N_SQRS/2; i++) {
+ printsq(i, FALSE);
+ putchar('\t');
+ printsq(i+N_SQRS/2, TRUE);
+ }
+}
+/*
+ * This routine lists where each player is.
+ */
+where() {
+
+ reg int i;
+ char *bsp;
+
+ printf("%s Player\n", header);
+ for (i = 0; i < num_play; i++) {
+ printsq(play[i].loc, FALSE);
+ printf(" %s (%d)", play[i].name, i+1);
+ if (cur_p == &play[i])
+ printf(" *");
+ putchar('\n');
+ }
+}
+/*
+ * This routine prints out an individual square
+ */
+printsq(sqn, eoln)
+int sqn;
+reg bool eoln; {
+
+ reg int rnt;
+ reg PROP *pp;
+ reg SQUARE *sqp;
+ int i;
+
+ sqp = &board[sqn];
+ printf("%-10.10s", sqp->name);
+ switch (sqp->type) {
+ case SAFE:
+ case CC:
+ case CHANCE:
+ case INC_TAX:
+ case GOTO_J:
+ case LUX_TAX:
+ case IN_JAIL:
+spec:
+ if (!eoln)
+ printf(" ");
+ break;
+ case PRPTY:
+ pp = sqp->desc;
+ if (sqp->owner < 0) {
+ printf(" - %-8.8s %3d", pp->mon_desc->name, sqp->cost);
+ if (!eoln)
+ printf(" ");
+ break;
+ }
+ printf(" %d %-8.8s %3d", sqp->owner+1, pp->mon_desc->name,
+ sqp->cost);
+ printmorg(sqp);
+ if (pp->monop) {
+ if (pp->houses < 5)
+ if (pp->houses > 0)
+ printf("%d %4d", pp->houses,
+ pp->rent[pp->houses]);
+ else
+ printf("0 %4d", pp->rent[0] * 2);
+ else
+ printf("H %4d", pp->rent[5]);
+ }
+ else
+ printf(" %4d", pp->rent[0]);
+ break;
+ case UTIL:
+ if (sqp->owner < 0) {
+ printf(" - 150");
+ if (!eoln)
+ printf(" ");
+ break;
+ }
+ printf(" %d 150", sqp->owner+1);
+ printmorg(sqp);
+ printf("%d", play[sqp->owner].num_util);
+ if (!eoln)
+ printf(" ");
+ break;
+ case RR:
+ if (sqp->owner < 0) {
+ printf(" - Railroad 200");
+ if (!eoln)
+ printf(" ");
+ break;
+ }
+ printf(" %d Railroad 200", sqp->owner+1);
+ printmorg(sqp);
+ rnt = 25;
+ rnt <<= play[sqp->owner].num_rr - 1;
+ printf("%d %4d", play[sqp->owner].num_rr, 25 << (play[sqp->owner].num_rr - 1));
+ break;
+ }
+ if (eoln)
+ putchar('\n');
+}
+/*
+ * This routine prints out the mortgage flag.
+ */
+printmorg(sqp)
+reg SQUARE *sqp; {
+
+ if (sqp->desc->morg)
+ printf(" * ");
+ else
+ printf(" ");
+}
+/*
+ * This routine lists the holdings of the player given
+ */
+printhold(pl)
+reg int pl; {
+
+ reg OWN *op;
+ reg PLAY *pp;
+ char *bsp;
+
+ pp = &play[pl];
+ printf("%s's (%d) holdings (Total worth: $%d):\n", name_list[pl], pl+1,
+ pp->money + prop_worth(pp));
+ printf("\t$%d", pp->money);
+ if (pp->num_gojf) {
+ printf(", %d get-out-of-jail-free card", pp->num_gojf);
+ if (pp->num_gojf > 1)
+ putchar('s');
+ }
+ putchar('\n');
+ if (pp->own_list) {
+ printf("\t%s\n", header);
+ for (op = pp->own_list; op; op = op->next) {
+ putchar('\t');
+ printsq(sqnum(op->sqr), TRUE);
+ }
+ }
+}
diff --git a/monop/prop.c b/monop/prop.c
new file mode 100644
index 00000000..86c15958
--- /dev/null
+++ b/monop/prop.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)prop.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+extern char *calloc();
+
+/*
+ * This routine deals with buying property, setting all the
+ * appropriate flags.
+ */
+buy(player, sqrp)
+reg int player;
+reg SQUARE *sqrp; {
+
+ trading = FALSE;
+ sqrp->owner = player;
+ add_list(player, &(play[player].own_list), cur_p->loc);
+}
+/*
+ * This routine adds an item to the list.
+ */
+add_list(plr, head, op_sqr)
+int plr;
+OWN **head;
+int op_sqr; {
+
+ reg int val;
+ reg OWN *tp, *last_tp;
+ MON *mp;
+ OWN *op;
+
+ op = (OWN *)calloc(1, sizeof (OWN));
+ op->sqr = &board[op_sqr];
+ val = value(op->sqr);
+ last_tp = NULL;
+ for (tp = *head; tp && value(tp->sqr) < val; tp = tp->next)
+ if (val == value(tp->sqr)) {
+ cfree(op);
+ return;
+ }
+ else
+ last_tp = tp;
+ op->next = tp;
+ if (last_tp != NULL)
+ last_tp->next = op;
+ else
+ *head = op;
+ if (!trading)
+ set_ownlist(plr);
+}
+/*
+ * This routine deletes property from the list.
+ */
+del_list(plr, head, op_sqr)
+int plr;
+OWN **head;
+shrt op_sqr; {
+
+ reg int i;
+ reg OWN *op, *last_op;
+
+ switch (board[op_sqr].type) {
+ case PRPTY:
+ board[op_sqr].desc->mon_desc->num_own--;
+ break;
+ case RR:
+ play[plr].num_rr--;
+ break;
+ case UTIL:
+ play[plr].num_util--;
+ break;
+ }
+ last_op = NULL;
+ for (op = *head; op; op = op->next)
+ if (op->sqr == &board[op_sqr])
+ break;
+ else
+ last_op = op;
+ if (last_op == NULL)
+ *head = op->next;
+ else {
+ last_op->next = op->next;
+ cfree(op);
+ }
+}
+/*
+ * This routine calculates the value for sorting of the
+ * given square.
+ */
+value(sqp)
+reg SQUARE *sqp; {
+
+ reg int sqr;
+
+ sqr = sqnum(sqp);
+ switch (sqp->type) {
+ case SAFE:
+ return 0;
+ default: /* Specials, etc */
+ return 1;
+ case UTIL:
+ if (sqr == 12)
+ return 2;
+ else
+ return 3;
+ case RR:
+ return 4 + sqr/10;
+ case PRPTY:
+ return 8 + (sqp->desc) - prop;
+ }
+}
+/*
+ * This routine accepts bids for the current peice
+ * of property.
+ */
+bid() {
+
+ static bool in[MAX_PL];
+ reg int i, num_in, cur_max;
+ char buf[80];
+ int cur_bid;
+
+ printf("\nSo it goes up for auction. Type your bid after your name\n");
+ for (i = 0; i < num_play; i++)
+ in[i] = TRUE;
+ i = -1;
+ cur_max = 0;
+ num_in = num_play;
+ while (num_in > 1 || (cur_max == 0 && num_in > 0)) {
+ i = ++i % num_play;
+ if (in[i]) {
+ do {
+ (void)sprintf(buf, "%s: ", name_list[i]);
+ cur_bid = get_int(buf);
+ if (cur_bid == 0) {
+ in[i] = FALSE;
+ if (--num_in == 0)
+ break;
+ }
+ else if (cur_bid <= cur_max) {
+ printf("You must bid higher than %d to stay in\n", cur_max);
+ printf("(bid of 0 drops you out)\n");
+ }
+ } while (cur_bid != 0 && cur_bid <= cur_max);
+ cur_max = (cur_bid ? cur_bid : cur_max);
+ }
+ }
+ if (cur_max != 0) {
+ while (!in[i])
+ i = ++i % num_play;
+ printf("It goes to %s (%d) for $%d\n",play[i].name,i+1,cur_max);
+ buy(i, &board[cur_p->loc]);
+ play[i].money -= cur_max;
+ }
+ else
+ printf("Nobody seems to want it, so we'll leave it for later\n");
+}
+/*
+ * This routine calculates the value of the property
+ * of given player.
+ */
+prop_worth(plp)
+reg PLAY *plp; {
+
+ reg OWN *op;
+ reg int worth;
+
+ worth = 0;
+ for (op = plp->own_list; op; op = op->next) {
+ if (op->sqr->type == PRPTY && op->sqr->desc->monop)
+ worth += op->sqr->desc->mon_desc->h_cost * 50 *
+ op->sqr->desc->houses;
+ worth += op->sqr->cost;
+ }
+ return worth;
+}
diff --git a/monop/prop.dat b/monop/prop.dat
new file mode 100644
index 00000000..dd4081d9
--- /dev/null
+++ b/monop/prop.dat
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)prop.dat 5.3 (Berkeley) 4/8/91
+ */
+
+/* morg monop square houses mon_desc rent */
+{0, 0, 1, 0, &mon[0], { 2, 10, 30, 90, 160, 250} },
+{0, 0, 3, 0, &mon[0], { 4, 20, 60, 180, 320, 450} },
+{0, 0, 6, 0, &mon[1], { 6, 30, 90, 270, 400, 550} },
+{0, 0, 7, 0, &mon[1], { 6, 30, 90, 270, 400, 550} },
+{0, 0, 9, 0, &mon[1], { 8, 40,100, 300, 450, 600} },
+{0, 0, 11, 0, &mon[2], {10, 50,150, 450, 625, 750} },
+{0, 0, 13, 0, &mon[2], {10, 50,150, 450, 625, 750} },
+{0, 0, 14, 0, &mon[2], {12, 60,180, 500, 700, 900} },
+{0, 0, 16, 0, &mon[3], {14, 70,200, 550, 750, 950} },
+{0, 0, 17, 0, &mon[3], {14, 70,200, 550, 750, 950} },
+{0, 0, 19, 0, &mon[3], {16, 80,220, 600, 800,1000} },
+{0, 0, 21, 0, &mon[4], {18, 90,250, 700, 875,1050} },
+{0, 0, 23, 0, &mon[4], {18, 90,250, 700, 875,1050} },
+{0, 0, 24, 0, &mon[4], {20,100,300, 750, 925,1100} },
+{0, 0, 26, 0, &mon[5], {22,110,330, 800, 975,1150} },
+{0, 0, 27, 0, &mon[5], {22,110,330, 800, 975,1150} },
+{0, 0, 29, 0, &mon[5], {24,120,360, 850,1025,1200} },
+{0, 0, 31, 0, &mon[6], {26,130,390, 900,1100,1275} },
+{0, 0, 32, 0, &mon[6], {26,130,390, 900,1100,1275} },
+{0, 0, 34, 0, &mon[6], {28,150,450,1000,1200,1400} },
+{0, 0, 37, 0, &mon[7], {35,175,500,1100,1300,1500} },
+{0, 0, 39, 0, &mon[7], {50,200,600,1400,1700,2000} }
diff --git a/monop/rent.c b/monop/rent.c
new file mode 100644
index 00000000..f3c5b050
--- /dev/null
+++ b/monop/rent.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)rent.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+/*
+ * This routine has the player pay rent
+ */
+rent(sqp)
+reg SQUARE *sqp; {
+
+ reg int rnt;
+ reg PROP *pp;
+ PLAY *plp;
+
+ plp = &play[sqp->owner];
+ printf("Owned by %s\n", plp->name);
+ if (sqp->desc->morg) {
+ lucky("The thing is mortgaged. ");
+ return;
+ }
+ switch (sqp->type) {
+ case PRPTY:
+ pp = sqp->desc;
+ if (pp->monop)
+ if (pp->houses == 0)
+ printf("rent is %d\n", rnt=pp->rent[0] * 2);
+ else if (pp->houses < 5)
+ printf("with %d houses, rent is %d\n",
+ pp->houses, rnt=pp->rent[pp->houses]);
+ else
+ printf("with a hotel, rent is %d\n",
+ rnt=pp->rent[pp->houses]);
+ else
+ printf("rent is %d\n", rnt = pp->rent[0]);
+ break;
+ case RR:
+ rnt = 25;
+ rnt <<= (plp->num_rr - 1);
+ if (spec)
+ rnt <<= 1;
+ printf("rent is %d\n", rnt);
+ break;
+ case UTIL:
+ rnt = roll(2, 6);
+ if (plp->num_util == 2 || spec) {
+ printf("rent is 10 * roll (%d) = %d\n", rnt, rnt * 10);
+ rnt *= 10;
+ }
+ else {
+ printf("rent is 4 * roll (%d) = %d\n", rnt, rnt * 4);
+ rnt *= 4;
+ }
+ break;
+ }
+ cur_p->money -= rnt;
+ plp->money += rnt;
+}
diff --git a/monop/roll.c b/monop/roll.c
new file mode 100644
index 00000000..9de116f4
--- /dev/null
+++ b/monop/roll.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)roll.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * This routine rolls ndie nside-sided dice.
+ */
+
+# define reg register
+
+# if !defined(vax) && !defined(tahoe)
+# define MAXRAND 32767L
+
+roll(ndie, nsides)
+int ndie, nsides; {
+
+ reg long tot;
+ reg unsigned n, r;
+
+ tot = 0;
+ n = ndie;
+ while (n--)
+ tot += rand();
+ return (int) ((tot * (long) nsides) / ((long) MAXRAND + 1)) + ndie;
+}
+
+# else
+
+roll(ndie, nsides)
+reg int ndie, nsides; {
+
+ reg int tot, r;
+ reg double num_sides;
+
+ num_sides = nsides;
+ tot = 0;
+ while (ndie--)
+ tot += (r = rand()) * (num_sides / 017777777777) + 1;
+ return tot;
+}
+# endif
diff --git a/monop/spec.c b/monop/spec.c
new file mode 100644
index 00000000..b040ca3b
--- /dev/null
+++ b/monop/spec.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)spec.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+static char *perc[] = {
+ "10%", "ten percent", "%", "$200", "200", 0
+ };
+
+inc_tax() { /* collect income tax */
+
+ reg int worth, com_num;
+
+ com_num = getinp("Do you wish to lose 10%% of your total worth or $200? ", perc);
+ worth = cur_p->money + prop_worth(cur_p);
+ printf("You were worth $%d", worth);
+ worth /= 10;
+ if (com_num > 2) {
+ if (worth < 200)
+ printf(". Good try, but not quite.\n");
+ else if (worth > 200)
+ lucky(".\nGood guess. ");
+ cur_p->money -= 200;
+ }
+ else {
+ printf(", so you pay $%d", worth);
+ if (worth > 200)
+ printf(" OUCH!!!!.\n");
+ else if (worth < 200)
+ lucky("\nGood guess. ");
+ cur_p->money -= worth;
+ }
+ if (worth == 200)
+ lucky("\nIt makes no difference! ");
+}
+goto_jail() { /* move player to jail */
+
+ cur_p->loc = JAIL;
+}
+lux_tax() { /* landing on luxury tax */
+
+ printf("You lose $75\n");
+ cur_p->money -= 75;
+}
+cc() { /* draw community chest card */
+
+ get_card(&CC_D);
+}
+chance() { /* draw chance card */
+
+ get_card(&CH_D);
+}
diff --git a/monop/trade.c b/monop/trade.c
new file mode 100644
index 00000000..57cca984
--- /dev/null
+++ b/monop/trade.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)trade.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "monop.ext"
+
+struct trd_st { /* how much to give to other player */
+ int trader; /* trader number */
+ int cash; /* amount of cash */
+ int gojf; /* # get-out-of-jail-free cards */
+ OWN *prop_list; /* property list */
+};
+
+typedef struct trd_st TRADE;
+
+static char *list[MAX_PRP+2];
+
+static int used[MAX_PRP];
+
+static TRADE trades[2];
+
+trade() {
+
+ reg int tradee, i;
+
+ trading = TRUE;
+ for (i = 0; i < 2; i++) {
+ trades[i].cash = 0;
+ trades[i].gojf = FALSE;
+ trades[i].prop_list = NULL;
+ }
+over:
+ if (num_play == 1) {
+ printf("There ain't no-one around to trade WITH!!\n");
+ return;
+ }
+ if (num_play > 2) {
+ tradee = getinp("Which player do you wish to trade with? ",
+ name_list);
+ if (tradee == num_play)
+ return;
+ if (tradee == player) {
+ printf("You can't trade with yourself!\n");
+ goto over;
+ }
+ }
+ else
+ tradee = 1 - player;
+ get_list(0, player);
+ get_list(1, tradee);
+ if (getyn("Do you wish a summary? ") == 0)
+ summate();
+ if (getyn("Is the trade ok? ") == 0)
+ do_trade();
+}
+/*
+ * This routine gets the list of things to be trader for the
+ * player, and puts in the structure given.
+ */
+get_list(struct_no, play_no)
+int struct_no, play_no; {
+
+ reg int sn, pn;
+ reg PLAY *pp;
+ int numin, prop, num_prp;
+ OWN *op;
+ TRADE *tp;
+
+ for (numin = 0; numin < MAX_PRP; numin++)
+ used[numin] = FALSE;
+ sn = struct_no, pn = play_no;
+ pp = &play[pn];
+ tp = &trades[sn];
+ tp->trader = pn;
+ printf("player %s (%d):\n", pp->name, pn+1);
+ if (pp->own_list) {
+ numin = set_list(pp->own_list);
+ for (num_prp = numin; num_prp; ) {
+ prop = getinp("Which property do you wish to trade? ",
+ list);
+ if (prop == numin)
+ break;
+ else if (used[prop])
+ printf("You've already allocated that.\n");
+ else {
+ num_prp--;
+ used[prop] = TRUE;
+ for (op = pp->own_list; prop--; op = op->next)
+ continue;
+ add_list(pn, &(tp->prop_list), sqnum(op->sqr));
+ }
+ }
+ }
+ if (pp->money > 0) {
+ printf("You have $%d. ", pp->money);
+ tp->cash = get_int("How much are you trading? ");
+ }
+ if (pp->num_gojf > 0) {
+once_more:
+ printf("You have %d get-out-of-jail-free cards. ",pp->num_gojf);
+ tp->gojf = get_int("How many are you trading? ");
+ if (tp->gojf > pp->num_gojf) {
+ printf("You don't have that many. Try again.\n");
+ goto once_more;
+ }
+ }
+}
+/*
+ * This routine sets up the list of tradable property.
+ */
+set_list(the_list)
+reg OWN *the_list; {
+
+ reg int i;
+ reg OWN *op;
+
+ i = 0;
+ for (op = the_list; op; op = op->next)
+ if (!used[i])
+ list[i++] = op->sqr->name;
+ list[i++] = "done";
+ list[i--] = 0;
+ return i;
+}
+/*
+ * This routine summates the trade.
+ */
+summate() {
+
+ reg bool some;
+ reg int i;
+ reg TRADE *tp;
+ OWN *op;
+
+ for (i = 0; i < 2; i++) {
+ tp = &trades[i];
+ some = FALSE;
+ printf("Player %s (%d) gives:\n", play[tp->trader].name,
+ tp->trader+1);
+ if (tp->cash > 0)
+ printf("\t$%d\n", tp->cash), some++;
+ if (tp->gojf > 0)
+ printf("\t%d get-out-of-jail-free card(s)\n", tp->gojf),
+ some++;
+ if (tp->prop_list) {
+ for (op = tp->prop_list; op; op = op->next)
+ putchar('\t'), printsq(sqnum(op->sqr), TRUE);
+ some++;
+ }
+ if (!some)
+ printf("\t-- Nothing --\n");
+ }
+}
+/*
+ * This routine actually executes the trade.
+ */
+do_trade() {
+
+ move_em(&trades[0], &trades[1]);
+ move_em(&trades[1], &trades[0]);
+}
+/*
+ * This routine does a switch from one player to another
+ */
+move_em(from, to)
+TRADE *from, *to; {
+
+ reg PLAY *pl_fr, *pl_to;
+ reg OWN *op;
+
+ pl_fr = &play[from->trader];
+ pl_to = &play[to->trader];
+
+ pl_fr->money -= from->cash;
+ pl_to->money += from->cash;
+ pl_fr->num_gojf -= from->gojf;
+ pl_to->num_gojf += from->gojf;
+ for (op = from->prop_list; op; op = op->next) {
+ add_list(to->trader, &(pl_to->own_list), sqnum(op->sqr));
+ op->sqr->owner = to->trader;
+ del_list(from->trader, &(pl_fr->own_list), sqnum(op->sqr));
+ }
+ set_ownlist(to->trader);
+}
+/*
+ * This routine lets a player resign
+ */
+resign() {
+
+ reg int i, new_own;
+ reg OWN *op;
+ SQUARE *sqp;
+
+ if (cur_p->money <= 0) {
+ switch (board[cur_p->loc].type) {
+ case UTIL:
+ case RR:
+ case PRPTY:
+ new_own = board[cur_p->loc].owner;
+ break;
+ default: /* Chance, taxes, etc */
+ new_own = num_play;
+ break;
+ }
+ if (new_own == num_play)
+ printf("You would resign to the bank\n");
+ else
+ printf("You would resign to %s\n", name_list[new_own]);
+ }
+ else if (num_play == 1) {
+ new_own = num_play;
+ printf("You would resign to the bank\n");
+ }
+ else {
+ name_list[num_play] = "bank";
+ do {
+ new_own = getinp("Who do you wish to resign to? ",
+ name_list);
+ if (new_own == player)
+ printf("You can't resign to yourself!!\n");
+ } while (new_own == player);
+ name_list[num_play] = "done";
+ }
+ if (getyn("Do you really want to resign? ", yn) != 0)
+ return;
+ if (num_play == 1) {
+ printf("Then NOBODY wins (not even YOU!)\n");
+ exit(0);
+ }
+ if (new_own < num_play) { /* resign to player */
+ printf("resigning to player\n");
+ trades[0].trader = new_own;
+ trades[0].cash = trades[0].gojf = 0;
+ trades[0].prop_list = NULL;
+ trades[1].trader = player;
+ trades[1].cash = cur_p->money > 0 ? cur_p->money : 0;
+ trades[1].gojf = cur_p->num_gojf;
+ trades[1].prop_list = cur_p->own_list;
+ do_trade();
+ }
+ else { /* resign to bank */
+ printf("resigning to bank\n");
+ for (op = cur_p->own_list; op; op = op->next) {
+ sqp = op->sqr;
+ sqp->owner = -1;
+ sqp->desc->morg = FALSE;
+ if (sqp->type == PRPTY) {
+ isnot_monop(sqp->desc->mon_desc);
+ sqp->desc->houses = 0;
+ }
+ }
+ if (cur_p->num_gojf)
+ ret_card(cur_p);
+ }
+ for (i = player; i < num_play; i++) {
+ name_list[i] = name_list[i+1];
+ if (i + 1 < num_play)
+ cpy_st(&play[i], &play[i+1], sizeof (PLAY));
+ }
+ name_list[num_play--] = 0;
+ for (i = 0; i < N_SQRS; i++)
+ if (board[i].owner > player)
+ --board[i].owner;
+ player = --player < 0 ? num_play - 1 : player;
+ next_play();
+ if (num_play < 2) {
+ printf("\nThen %s WINS!!!!!\n", play[0].name);
+ printhold(0);
+ printf("That's a grand worth of $%d.\n",
+ play[0].money+prop_worth(&play[0]));
+ exit(0);
+ }
+}
diff --git a/morse/Makefile b/morse/Makefile
new file mode 100644
index 00000000..22a5c91a
--- /dev/null
+++ b/morse/Makefile
@@ -0,0 +1,8 @@
+# @(#)Makefile 5.1 (Berkeley) 5/11/90
+
+PROG= morse
+NOMAN= noman
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
+
diff --git a/morse/morse.c b/morse/morse.c
new file mode 100644
index 00000000..dcf02e01
--- /dev/null
+++ b/morse/morse.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)morse.c 5.3 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <ctype.h>
+
+static char
+ *digit[] = {
+ "-----",
+ ".----",
+ "..---",
+ "...--",
+ "....-",
+ ".....",
+ "-....",
+ "--...",
+ "---..",
+ "----.",
+},
+ *alph[] = {
+ ".-",
+ "-...",
+ "-.-.",
+ "-..",
+ ".",
+ "..-.",
+ "--.",
+ "....",
+ "..",
+ ".---",
+ "-.-",
+ ".-..",
+ "--",
+ "-.",
+ "---",
+ ".--.",
+ "--.-",
+ ".-.",
+ "...",
+ "-",
+ "..-",
+ "...-",
+ ".--",
+ "-..-",
+ "-.--",
+ "--..",
+};
+
+static int sflag;
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern char *optarg;
+ extern int optind;
+ register int ch;
+ register char *p;
+
+ while ((ch = getopt(argc, argv, "s")) != EOF)
+ switch((char)ch) {
+ case 's':
+ sflag = 1;
+ break;
+ case '?':
+ default:
+ fprintf(stderr, "usage: morse [string ...]");
+ exit(1);
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (*argv)
+ do {
+ for (p = *argv; *p; ++p)
+ morse((int)*p);
+ } while (*++argv);
+ else while ((ch = getchar()) != EOF)
+ morse(ch);
+}
+
+morse(c)
+ register int c;
+{
+ if (isalpha(c))
+ show(alph[c - (isupper(c) ? 'A' : 'a')]);
+ else if (isdigit(c))
+ show(digit[c - '0']);
+ else if (c == ',')
+ show("--..--");
+ else if (c == '.')
+ show(".-.-.-");
+ else if (isspace(c))
+ show(" ...\n");
+}
+
+show(s)
+ register char *s;
+{
+ if (sflag)
+ printf(" %s", s);
+ else for (; *s; ++s)
+ printf(" %s", *s == '.' ? "dit" : "daw");
+ printf(",\n");
+}
diff --git a/number/Makefile b/number/Makefile
new file mode 100644
index 00000000..9ef23470
--- /dev/null
+++ b/number/Makefile
@@ -0,0 +1,6 @@
+# @(#)Makefile 5.2 (Berkeley) 5/11/90
+
+PROG= number
+MAN6= number.0
+
+.include <bsd.prog.mk>
diff --git a/number/number.6 b/number/number.6
new file mode 100644
index 00000000..fbf3eecb
--- /dev/null
+++ b/number/number.6
@@ -0,0 +1,52 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)number.6 6.4 (Berkeley) 6/23/90
+.\"
+.TH NUMBER 6 "June 23, 1990"
+.UC 4
+.SH NAME
+number \- convert Arabic numerals to English
+.SH SYNOPSIS
+.B number
+[ # ]
+.SH DESCRIPTION
+The
+.I number
+utility
+prints the English equivalent of the specified number to the
+standard output.
+If no argument is specified,
+.I number
+reads a number from the standard input.
+.SH BUGS
+.I Number
+doesn't understand exponents.
diff --git a/number/number.c b/number/number.c
new file mode 100644
index 00000000..110400ea
--- /dev/null
+++ b/number/number.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)number.c 5.1 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#define YES 1
+#define NO 0
+#define EOS '\0'
+#define MAXNUM 65 /* biggest number we handle */
+
+static char *name1[] = {
+ "", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "ten", "eleven",
+ "twelve", "thirteen", "fourteen", "fifteen",
+ "sixteen", "seventeen", "eighteen", "nineteen",
+},
+ *name2[] = {
+ "", "ten", "twenty", "thirty",
+ "forty", "fifty", "sixty", "seventy",
+ "eighty", "ninety",
+},
+ *name3[] = {
+ "hundred", "thousand", "million", "billion",
+ "trillion", "quadrillion", "quintillion", "sextillion",
+ "septillion", "octillion", "nonillion", "decillion",
+ "undecillion", "duodecillion", "tredecillion", "quattuordecillion",
+ "quindecillion", "sexdecillion",
+ "septendecillion", "octodecillion",
+ "novemdecillion", "vigintillion",
+};
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ register int cnt;
+ char line[MAXNUM * 2 + 2]; /* MAXNUM '.' MAXNUM '\0' */
+
+ if (argc > 1)
+ for (cnt = 1;cnt < argc;++cnt) {
+ convert(argv[cnt]);
+ puts("...");
+ }
+ else
+ while (fgets(line,sizeof(line),stdin)) {
+ convert(line);
+ puts("...");
+ }
+ exit(0);
+}
+
+convert(line)
+ char *line;
+{
+ register int len,
+ ret;
+ register char *C,
+ *fraction;
+
+ for (fraction = NULL, C = line;*C && *C != '\n';++C)
+ if (!isdigit(*C))
+ switch(*C) {
+ case '-':
+ if (C != line)
+ usage(NO);
+ break;
+ case '.':
+ if (!fraction) {
+ fraction = C + 1;
+ *C = EOS;
+ break;
+ }
+ default:
+ usage(NO);
+ }
+ *C = EOS;
+ if (*line == '-') {
+ puts("minus");
+ ++line;
+ }
+ ret = NO;
+ if (len = strlen(line)) {
+ if (len > MAXNUM)
+ usage(YES);
+ ret = unit(len,line);
+ }
+ if (fraction && (len = strlen(fraction))) {
+ if (len > MAXNUM)
+ usage(YES);
+ for (C = fraction;*C;++C)
+ if (*C != '0') {
+ if (ret)
+ puts("and");
+ if (unit(len,fraction)) {
+ ++ret;
+ pfract(len);
+ }
+ break;
+ }
+ }
+ if (!ret)
+ puts("zero.");
+}
+
+unit(len,C)
+ register int len;
+ register char *C;
+{
+ register int off,
+ ret;
+
+ ret = NO;
+ if (len > 3) {
+ if (len % 3) {
+ off = len % 3;
+ len -= off;
+ if (number(C,off)) {
+ ret = YES;
+ printf(" %s.\n",name3[len / 3]);
+ }
+ C += off;
+ }
+ for (;len > 3;C += 3) {
+ len -= 3;
+ if (number(C,3)) {
+ ret = YES;
+ printf(" %s.\n",name3[len / 3]);
+ }
+ }
+ }
+ if (number(C,len)) {
+ puts(".");
+ ret = YES;
+ }
+ return(ret);
+}
+
+number(C,len)
+ register char *C;
+ int len;
+{
+ register int val,
+ ret;
+
+ ret = 0;
+ switch(len) {
+ case 3:
+ if (*C != '0') {
+ ++ret;
+ printf("%s hundred",name1[*C - '0']);
+ }
+ ++C;
+ /*FALLTHROUGH*/
+ case 2:
+ val = (C[1] - '0') + (C[0] - '0') * 10;
+ if (val) {
+ if (ret++)
+ putchar(' ');
+ if (val < 20)
+ fputs(name1[val],stdout);
+ else {
+ fputs(name2[val / 10],stdout);
+ if (val % 10)
+ printf("-%s",name1[val % 10]);
+ }
+ }
+ break;
+ case 1:
+ if (*C != '0') {
+ ++ret;
+ fputs(name1[*C - '0'],stdout);
+ }
+ }
+ return(ret);
+}
+
+pfract(len)
+ register int len;
+{
+ static char *pref[] = { "", "ten-", "hundred-" };
+
+ switch(len) {
+ case 1:
+ puts("tenths.");
+ break;
+ case 2:
+ puts("hundredths.");
+ break;
+ default:
+ printf("%s%sths.\n",pref[len % 3],name3[len / 3]);
+ }
+}
+
+usage(toobig)
+ int toobig;
+{
+ if (toobig)
+ fprintf(stderr,"number: number too large, max %d digits.\n",MAXNUM);
+ fputs("usage: number # ...\n",stderr);
+ exit(-1);
+}
diff --git a/pom/Makefile b/pom/Makefile
new file mode 100644
index 00000000..bfae4b4f
--- /dev/null
+++ b/pom/Makefile
@@ -0,0 +1,8 @@
+# @(#)Makefile 5.1 (Berkeley) 5/11/90
+
+PROG= pom
+MAN6= pom.0
+DPADD= ${LIBM}
+LDADD= -lm
+
+.include <bsd.prog.mk>
diff --git a/pom/pom.6 b/pom/pom.6
new file mode 100644
index 00000000..882a803e
--- /dev/null
+++ b/pom/pom.6
@@ -0,0 +1,45 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)pom.6 5.2 (Berkeley) 6/23/90
+.\"
+.TH POM 6 "June 23, 1990"
+.UC 7
+.SH NAME
+pom \- display the phase of the moon
+.SH SYNOPSIS
+.B pom
+.SH DESCRIPTION
+The
+.I pom
+utility displays the current phase of the moon.
+Useful for selecting software completion target dates and predicting
+managerial behavior.
diff --git a/pom/pom.c b/pom/pom.c
new file mode 100644
index 00000000..a53f9d1f
--- /dev/null
+++ b/pom/pom.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software posted to USENET.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)pom.c 5.3 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * Phase of the Moon. Calculates the current phase of the moon.
+ * Based on routines from `Practical Astronomy with Your Calculator',
+ * by Duffett-Smith. Comments give the section from the book that
+ * particular piece of code was adapted from.
+ *
+ * -- Keith E. Brandt VIII 1984
+ *
+ */
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <tzfile.h>
+#include <math.h>
+
+#define PI 3.141592654
+#define EPOCH 85
+#define EPSILONg 279.611371 /* solar ecliptic long at EPOCH */
+#define RHOg 282.680403 /* solar ecliptic long of perigee at EPOCH */
+#define ECCEN 0.01671542 /* solar orbit eccentricity */
+#define lzero 18.251907 /* lunar mean long at EPOCH */
+#define Pzero 192.917585 /* lunar mean long of perigee at EPOCH */
+#define Nzero 55.204723 /* lunar mean long of node at EPOCH */
+
+double dtor(), potm(), adj360();
+
+main()
+{
+ extern int errno;
+ struct timeval tp;
+ struct timezone tzp;
+ struct tm *GMT, *gmtime();
+ double days, today, tomorrow;
+ int cnt;
+ char *strerror();
+
+ if (gettimeofday(&tp,&tzp)) {
+ (void)fprintf(stderr, "pom: %s\n", strerror(errno));
+ exit(1);
+ }
+ GMT = gmtime(&tp.tv_sec);
+ days = (GMT->tm_yday + 1) + ((GMT->tm_hour +
+ (GMT->tm_min / 60.0) + (GMT->tm_sec / 3600.0)) / 24.0);
+ for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt)
+ days += isleap(cnt) ? 366 : 365;
+ today = potm(days) + .5;
+ (void)printf("The Moon is ");
+ if ((int)today == 100)
+ (void)printf("Full\n");
+ else if (!(int)today)
+ (void)printf("New\n");
+ else {
+ tomorrow = potm(days + 1);
+ if ((int)today == 50)
+ (void)printf("%s\n", tomorrow > today ?
+ "at the First Quarter" : "at the Last Quarter");
+ else {
+ (void)printf("%s ", tomorrow > today ?
+ "Waxing" : "Waning");
+ if (today > 50)
+ (void)printf("Gibbous (%1.0f%% of Full)\n",
+ today);
+ else if (today < 50)
+ (void)printf("Crescent (%1.0f%% of Full)\n",
+ today);
+ }
+ }
+}
+
+/*
+ * potm --
+ * return phase of the moon
+ */
+double
+potm(days)
+ double days;
+{
+ double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
+ double A4, lprime, V, ldprime, D, Nm;
+
+ N = 360 * days / 365.2422; /* sec 42 #3 */
+ adj360(&N);
+ Msol = N + EPSILONg - RHOg; /* sec 42 #4 */
+ adj360(&Msol);
+ Ec = 360 / PI * ECCEN * sin(dtor(Msol)); /* sec 42 #5 */
+ LambdaSol = N + Ec + EPSILONg; /* sec 42 #6 */
+ adj360(&LambdaSol);
+ l = 13.1763966 * days + lzero; /* sec 61 #4 */
+ adj360(&l);
+ Mm = l - (0.1114041 * days) - Pzero; /* sec 61 #5 */
+ adj360(&Mm);
+ Nm = Nzero - (0.0529539 * days); /* sec 61 #6 */
+ adj360(&Nm);
+ Ev = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm)); /* sec 61 #7 */
+ Ac = 0.1858 * sin(dtor(Msol)); /* sec 61 #8 */
+ A3 = 0.37 * sin(dtor(Msol));
+ Mmprime = Mm + Ev - Ac - A3; /* sec 61 #9 */
+ Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 61 #10 */
+ A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 61 #11 */
+ lprime = l + Ev + Ec - Ac + A4; /* sec 61 #12 */
+ V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 61 #13 */
+ ldprime = lprime + V; /* sec 61 #14 */
+ D = ldprime - LambdaSol; /* sec 63 #2 */
+ return(50 * (1 - cos(dtor(D)))); /* sec 63 #3 */
+}
+
+/*
+ * dtor --
+ * convert degrees to radians
+ */
+double
+dtor(deg)
+ double deg;
+{
+ return(deg * PI / 180);
+}
+
+/*
+ * adj360 --
+ * adjust value so 0 <= deg <= 360
+ */
+double
+adj360(deg)
+ double *deg;
+{
+ for (;;)
+ if (*deg < 0)
+ *deg += 360;
+ else if (*deg > 360)
+ *deg -= 360;
+ else
+ break;
+}
diff --git a/ppt/Makefile b/ppt/Makefile
new file mode 100644
index 00000000..b766d40b
--- /dev/null
+++ b/ppt/Makefile
@@ -0,0 +1,8 @@
+# @(#)Makefile 5.1 (Berkeley) 5/11/90
+
+PROG= ppt
+NOMAN= noman
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
+
diff --git a/ppt/ppt.c b/ppt/ppt.c
new file mode 100644
index 00000000..41b8e8e0
--- /dev/null
+++ b/ppt/ppt.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)ppt.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <stdio.h>
+
+void putppt();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ register int c;
+ register char *p;
+
+ (void) puts("___________");
+ if (argc > 1)
+ while (p = *++argv)
+ for (; *p; ++p)
+ putppt((int)*p);
+ else while ((c = getchar()) != EOF)
+ putppt(c);
+ (void) puts("___________");
+ exit(0);
+}
+
+static void
+putppt(c)
+ register int c;
+{
+ register int i;
+
+ (void) putchar('|');
+ for (i = 7; i >= 0; i--) {
+ if (i == 2)
+ (void) putchar('.'); /* feed hole */
+ if ((c&(1<<i)) != 0)
+ (void) putchar('o');
+ else
+ (void) putchar(' ');
+ }
+ (void) putchar('|');
+ (void) putchar('\n');
+}
diff --git a/primes/Makefile b/primes/Makefile
new file mode 100644
index 00000000..ca68a7d8
--- /dev/null
+++ b/primes/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 5.1 (Berkeley) 5/11/90
+
+PROG= primes
+SRCS= pattern.c pr_tbl.c primes.c
+NOMAN= noman
+DPADD= ${LIBM}
+LDADD= -lm
+
+.include <bsd.prog.mk>
diff --git a/primes/pattern.c b/primes/pattern.c
new file mode 100644
index 00000000..34535b68
--- /dev/null
+++ b/primes/pattern.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Landon Curt Noll.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pattern.c 5.2 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * pattern - the Eratosthenes sieve on odd numbers for 3,5,7,11 and 13
+ *
+ * By: Landon Curt Noll chongo@toad.com
+ *
+ * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+ *
+ * To avoid excessive sieves for small factors, we use the table below to
+ * setup our sieve blocks. Each element represents a odd number starting
+ * with 1. All non-zero elements are factors of 3, 5, 7, 11 and 13.
+ */
+
+char pattern[] = {
+1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,
+0,0,0,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,
+0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,0,0,0,
+0,0,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,
+0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,0,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,
+0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,0,0,1,
+1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,0,0,0,1,0,1,
+1,0,0,1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+0,0,0,1,0,0,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,
+1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,0,1,
+1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0,0,
+1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,
+0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,
+0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,
+1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,
+1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,
+0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,
+1,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,
+0,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,
+1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,
+0,0,0,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,
+1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,
+0,0,1,0,0,1,0,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,0,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,
+1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+0,0,0,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+1,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,
+0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,
+1,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,1,
+1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,0,0,0,
+1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,1,
+0,0,0,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,
+1,0,1,0,0,1,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,
+0,0,1,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,
+1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,1,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,0,0,0,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,1,
+1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,0,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,0,0,0,0,0,0,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+0,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,
+1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,
+0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,0,0,0,
+1,0,0,1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,
+1,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,0,
+1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,
+1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,
+0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,
+0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,
+1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,
+0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,
+1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,
+0,0,1,0,0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+1,0,0,0,0,0,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,
+1,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,
+1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,
+1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,
+1,0,1,1,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,0,0,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,
+0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,
+1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,
+0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,1,0,0,1,
+1,0,1,0,0,0,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,
+1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,0,1,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,
+0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,
+1,0,0,1,0,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0,0,
+0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,
+0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,
+1,0,1,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0,0,1,0,1,1,0,0,
+0,0,0,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,
+0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,0,0,1,1,0,1,
+0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,
+1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,
+1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,1,
+1,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,0,
+1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,
+0,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,1,
+1,0,0,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,
+0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,
+1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,1,0,1,
+0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,
+1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,0,
+1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,
+1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,1,0,0,
+0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,
+0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,0,0,0,
+1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,
+1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,
+1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,1,0,0,
+1,0,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,0,1,0,0,1,
+0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,
+0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0,0,1
+};
+int pattern_size = (sizeof(pattern)/sizeof(pattern[0]));
diff --git a/primes/pr_tbl.c b/primes/pr_tbl.c
new file mode 100644
index 00000000..58c0ec68
--- /dev/null
+++ b/primes/pr_tbl.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Landon Curt Noll.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pr_tbl.c 5.2 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * prime - prime table
+ *
+ * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
+ *
+ * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+ *
+ * We are able to sieve 2^32-1 because this table has primes up to 65537
+ * and 65537^2 > 2^32-1.
+ */
+
+#include "primes.h"
+
+ubig prime[] = {
+2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,
+107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,
+211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,
+317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,
+439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,
+569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,
+677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,
+821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,
+947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,
+1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,
+1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,
+1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,
+1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,
+1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597,1601,
+1607,1609,1613,1619,1621,1627,1637,1657,1663,1667,1669,1693,1697,1699,1709,
+1721,1723,1733,1741,1747,1753,1759,1777,1783,1787,1789,1801,1811,1823,1831,
+1847,1861,1867,1871,1873,1877,1879,1889,1901,1907,1913,1931,1933,1949,1951,
+1973,1979,1987,1993,1997,1999,2003,2011,2017,2027,2029,2039,2053,2063,2069,
+2081,2083,2087,2089,2099,2111,2113,2129,2131,2137,2141,2143,2153,2161,2179,
+2203,2207,2213,2221,2237,2239,2243,2251,2267,2269,2273,2281,2287,2293,2297,
+2309,2311,2333,2339,2341,2347,2351,2357,2371,2377,2381,2383,2389,2393,2399,
+2411,2417,2423,2437,2441,2447,2459,2467,2473,2477,2503,2521,2531,2539,2543,
+2549,2551,2557,2579,2591,2593,2609,2617,2621,2633,2647,2657,2659,2663,2671,
+2677,2683,2687,2689,2693,2699,2707,2711,2713,2719,2729,2731,2741,2749,2753,
+2767,2777,2789,2791,2797,2801,2803,2819,2833,2837,2843,2851,2857,2861,2879,
+2887,2897,2903,2909,2917,2927,2939,2953,2957,2963,2969,2971,2999,3001,3011,
+3019,3023,3037,3041,3049,3061,3067,3079,3083,3089,3109,3119,3121,3137,3163,
+3167,3169,3181,3187,3191,3203,3209,3217,3221,3229,3251,3253,3257,3259,3271,
+3299,3301,3307,3313,3319,3323,3329,3331,3343,3347,3359,3361,3371,3373,3389,
+3391,3407,3413,3433,3449,3457,3461,3463,3467,3469,3491,3499,3511,3517,3527,
+3529,3533,3539,3541,3547,3557,3559,3571,3581,3583,3593,3607,3613,3617,3623,
+3631,3637,3643,3659,3671,3673,3677,3691,3697,3701,3709,3719,3727,3733,3739,
+3761,3767,3769,3779,3793,3797,3803,3821,3823,3833,3847,3851,3853,3863,3877,
+3881,3889,3907,3911,3917,3919,3923,3929,3931,3943,3947,3967,3989,4001,4003,
+4007,4013,4019,4021,4027,4049,4051,4057,4073,4079,4091,4093,4099,4111,4127,
+4129,4133,4139,4153,4157,4159,4177,4201,4211,4217,4219,4229,4231,4241,4243,
+4253,4259,4261,4271,4273,4283,4289,4297,4327,4337,4339,4349,4357,4363,4373,
+4391,4397,4409,4421,4423,4441,4447,4451,4457,4463,4481,4483,4493,4507,4513,
+4517,4519,4523,4547,4549,4561,4567,4583,4591,4597,4603,4621,4637,4639,4643,
+4649,4651,4657,4663,4673,4679,4691,4703,4721,4723,4729,4733,4751,4759,4783,
+4787,4789,4793,4799,4801,4813,4817,4831,4861,4871,4877,4889,4903,4909,4919,
+4931,4933,4937,4943,4951,4957,4967,4969,4973,4987,4993,4999,5003,5009,5011,
+5021,5023,5039,5051,5059,5077,5081,5087,5099,5101,5107,5113,5119,5147,5153,
+5167,5171,5179,5189,5197,5209,5227,5231,5233,5237,5261,5273,5279,5281,5297,
+5303,5309,5323,5333,5347,5351,5381,5387,5393,5399,5407,5413,5417,5419,5431,
+5437,5441,5443,5449,5471,5477,5479,5483,5501,5503,5507,5519,5521,5527,5531,
+5557,5563,5569,5573,5581,5591,5623,5639,5641,5647,5651,5653,5657,5659,5669,
+5683,5689,5693,5701,5711,5717,5737,5741,5743,5749,5779,5783,5791,5801,5807,
+5813,5821,5827,5839,5843,5849,5851,5857,5861,5867,5869,5879,5881,5897,5903,
+5923,5927,5939,5953,5981,5987,6007,6011,6029,6037,6043,6047,6053,6067,6073,
+6079,6089,6091,6101,6113,6121,6131,6133,6143,6151,6163,6173,6197,6199,6203,
+6211,6217,6221,6229,6247,6257,6263,6269,6271,6277,6287,6299,6301,6311,6317,
+6323,6329,6337,6343,6353,6359,6361,6367,6373,6379,6389,6397,6421,6427,6449,
+6451,6469,6473,6481,6491,6521,6529,6547,6551,6553,6563,6569,6571,6577,6581,
+6599,6607,6619,6637,6653,6659,6661,6673,6679,6689,6691,6701,6703,6709,6719,
+6733,6737,6761,6763,6779,6781,6791,6793,6803,6823,6827,6829,6833,6841,6857,
+6863,6869,6871,6883,6899,6907,6911,6917,6947,6949,6959,6961,6967,6971,6977,
+6983,6991,6997,7001,7013,7019,7027,7039,7043,7057,7069,7079,7103,7109,7121,
+7127,7129,7151,7159,7177,7187,7193,7207,7211,7213,7219,7229,7237,7243,7247,
+7253,7283,7297,7307,7309,7321,7331,7333,7349,7351,7369,7393,7411,7417,7433,
+7451,7457,7459,7477,7481,7487,7489,7499,7507,7517,7523,7529,7537,7541,7547,
+7549,7559,7561,7573,7577,7583,7589,7591,7603,7607,7621,7639,7643,7649,7669,
+7673,7681,7687,7691,7699,7703,7717,7723,7727,7741,7753,7757,7759,7789,7793,
+7817,7823,7829,7841,7853,7867,7873,7877,7879,7883,7901,7907,7919,7927,7933,
+7937,7949,7951,7963,7993,8009,8011,8017,8039,8053,8059,8069,8081,8087,8089,
+8093,8101,8111,8117,8123,8147,8161,8167,8171,8179,8191,8209,8219,8221,8231,
+8233,8237,8243,8263,8269,8273,8287,8291,8293,8297,8311,8317,8329,8353,8363,
+8369,8377,8387,8389,8419,8423,8429,8431,8443,8447,8461,8467,8501,8513,8521,
+8527,8537,8539,8543,8563,8573,8581,8597,8599,8609,8623,8627,8629,8641,8647,
+8663,8669,8677,8681,8689,8693,8699,8707,8713,8719,8731,8737,8741,8747,8753,
+8761,8779,8783,8803,8807,8819,8821,8831,8837,8839,8849,8861,8863,8867,8887,
+8893,8923,8929,8933,8941,8951,8963,8969,8971,8999,9001,9007,9011,9013,9029,
+9041,9043,9049,9059,9067,9091,9103,9109,9127,9133,9137,9151,9157,9161,9173,
+9181,9187,9199,9203,9209,9221,9227,9239,9241,9257,9277,9281,9283,9293,9311,
+9319,9323,9337,9341,9343,9349,9371,9377,9391,9397,9403,9413,9419,9421,9431,
+9433,9437,9439,9461,9463,9467,9473,9479,9491,9497,9511,9521,9533,9539,9547,
+9551,9587,9601,9613,9619,9623,9629,9631,9643,9649,9661,9677,9679,9689,9697,
+9719,9721,9733,9739,9743,9749,9767,9769,9781,9787,9791,9803,9811,9817,9829,
+9833,9839,9851,9857,9859,9871,9883,9887,9901,9907,9923,9929,9931,9941,9949,
+9967,9973,10007,10009,10037,10039,10061,10067,10069,10079,10091,10093,10099,
+10103,10111,10133,10139,10141,10151,10159,10163,10169,10177,10181,10193,10211,
+10223,10243,10247,10253,10259,10267,10271,10273,10289,10301,10303,10313,10321,
+10331,10333,10337,10343,10357,10369,10391,10399,10427,10429,10433,10453,10457,
+10459,10463,10477,10487,10499,10501,10513,10529,10531,10559,10567,10589,10597,
+10601,10607,10613,10627,10631,10639,10651,10657,10663,10667,10687,10691,10709,
+10711,10723,10729,10733,10739,10753,10771,10781,10789,10799,10831,10837,10847,
+10853,10859,10861,10867,10883,10889,10891,10903,10909,10937,10939,10949,10957,
+10973,10979,10987,10993,11003,11027,11047,11057,11059,11069,11071,11083,11087,
+11093,11113,11117,11119,11131,11149,11159,11161,11171,11173,11177,11197,11213,
+11239,11243,11251,11257,11261,11273,11279,11287,11299,11311,11317,11321,11329,
+11351,11353,11369,11383,11393,11399,11411,11423,11437,11443,11447,11467,11471,
+11483,11489,11491,11497,11503,11519,11527,11549,11551,11579,11587,11593,11597,
+11617,11621,11633,11657,11677,11681,11689,11699,11701,11717,11719,11731,11743,
+11777,11779,11783,11789,11801,11807,11813,11821,11827,11831,11833,11839,11863,
+11867,11887,11897,11903,11909,11923,11927,11933,11939,11941,11953,11959,11969,
+11971,11981,11987,12007,12011,12037,12041,12043,12049,12071,12073,12097,12101,
+12107,12109,12113,12119,12143,12149,12157,12161,12163,12197,12203,12211,12227,
+12239,12241,12251,12253,12263,12269,12277,12281,12289,12301,12323,12329,12343,
+12347,12373,12377,12379,12391,12401,12409,12413,12421,12433,12437,12451,12457,
+12473,12479,12487,12491,12497,12503,12511,12517,12527,12539,12541,12547,12553,
+12569,12577,12583,12589,12601,12611,12613,12619,12637,12641,12647,12653,12659,
+12671,12689,12697,12703,12713,12721,12739,12743,12757,12763,12781,12791,12799,
+12809,12821,12823,12829,12841,12853,12889,12893,12899,12907,12911,12917,12919,
+12923,12941,12953,12959,12967,12973,12979,12983,13001,13003,13007,13009,13033,
+13037,13043,13049,13063,13093,13099,13103,13109,13121,13127,13147,13151,13159,
+13163,13171,13177,13183,13187,13217,13219,13229,13241,13249,13259,13267,13291,
+13297,13309,13313,13327,13331,13337,13339,13367,13381,13397,13399,13411,13417,
+13421,13441,13451,13457,13463,13469,13477,13487,13499,13513,13523,13537,13553,
+13567,13577,13591,13597,13613,13619,13627,13633,13649,13669,13679,13681,13687,
+13691,13693,13697,13709,13711,13721,13723,13729,13751,13757,13759,13763,13781,
+13789,13799,13807,13829,13831,13841,13859,13873,13877,13879,13883,13901,13903,
+13907,13913,13921,13931,13933,13963,13967,13997,13999,14009,14011,14029,14033,
+14051,14057,14071,14081,14083,14087,14107,14143,14149,14153,14159,14173,14177,
+14197,14207,14221,14243,14249,14251,14281,14293,14303,14321,14323,14327,14341,
+14347,14369,14387,14389,14401,14407,14411,14419,14423,14431,14437,14447,14449,
+14461,14479,14489,14503,14519,14533,14537,14543,14549,14551,14557,14561,14563,
+14591,14593,14621,14627,14629,14633,14639,14653,14657,14669,14683,14699,14713,
+14717,14723,14731,14737,14741,14747,14753,14759,14767,14771,14779,14783,14797,
+14813,14821,14827,14831,14843,14851,14867,14869,14879,14887,14891,14897,14923,
+14929,14939,14947,14951,14957,14969,14983,15013,15017,15031,15053,15061,15073,
+15077,15083,15091,15101,15107,15121,15131,15137,15139,15149,15161,15173,15187,
+15193,15199,15217,15227,15233,15241,15259,15263,15269,15271,15277,15287,15289,
+15299,15307,15313,15319,15329,15331,15349,15359,15361,15373,15377,15383,15391,
+15401,15413,15427,15439,15443,15451,15461,15467,15473,15493,15497,15511,15527,
+15541,15551,15559,15569,15581,15583,15601,15607,15619,15629,15641,15643,15647,
+15649,15661,15667,15671,15679,15683,15727,15731,15733,15737,15739,15749,15761,
+15767,15773,15787,15791,15797,15803,15809,15817,15823,15859,15877,15881,15887,
+15889,15901,15907,15913,15919,15923,15937,15959,15971,15973,15991,16001,16007,
+16033,16057,16061,16063,16067,16069,16073,16087,16091,16097,16103,16111,16127,
+16139,16141,16183,16187,16189,16193,16217,16223,16229,16231,16249,16253,16267,
+16273,16301,16319,16333,16339,16349,16361,16363,16369,16381,16411,16417,16421,
+16427,16433,16447,16451,16453,16477,16481,16487,16493,16519,16529,16547,16553,
+16561,16567,16573,16603,16607,16619,16631,16633,16649,16651,16657,16661,16673,
+16691,16693,16699,16703,16729,16741,16747,16759,16763,16787,16811,16823,16829,
+16831,16843,16871,16879,16883,16889,16901,16903,16921,16927,16931,16937,16943,
+16963,16979,16981,16987,16993,17011,17021,17027,17029,17033,17041,17047,17053,
+17077,17093,17099,17107,17117,17123,17137,17159,17167,17183,17189,17191,17203,
+17207,17209,17231,17239,17257,17291,17293,17299,17317,17321,17327,17333,17341,
+17351,17359,17377,17383,17387,17389,17393,17401,17417,17419,17431,17443,17449,
+17467,17471,17477,17483,17489,17491,17497,17509,17519,17539,17551,17569,17573,
+17579,17581,17597,17599,17609,17623,17627,17657,17659,17669,17681,17683,17707,
+17713,17729,17737,17747,17749,17761,17783,17789,17791,17807,17827,17837,17839,
+17851,17863,17881,17891,17903,17909,17911,17921,17923,17929,17939,17957,17959,
+17971,17977,17981,17987,17989,18013,18041,18043,18047,18049,18059,18061,18077,
+18089,18097,18119,18121,18127,18131,18133,18143,18149,18169,18181,18191,18199,
+18211,18217,18223,18229,18233,18251,18253,18257,18269,18287,18289,18301,18307,
+18311,18313,18329,18341,18353,18367,18371,18379,18397,18401,18413,18427,18433,
+18439,18443,18451,18457,18461,18481,18493,18503,18517,18521,18523,18539,18541,
+18553,18583,18587,18593,18617,18637,18661,18671,18679,18691,18701,18713,18719,
+18731,18743,18749,18757,18773,18787,18793,18797,18803,18839,18859,18869,18899,
+18911,18913,18917,18919,18947,18959,18973,18979,19001,19009,19013,19031,19037,
+19051,19069,19073,19079,19081,19087,19121,19139,19141,19157,19163,19181,19183,
+19207,19211,19213,19219,19231,19237,19249,19259,19267,19273,19289,19301,19309,
+19319,19333,19373,19379,19381,19387,19391,19403,19417,19421,19423,19427,19429,
+19433,19441,19447,19457,19463,19469,19471,19477,19483,19489,19501,19507,19531,
+19541,19543,19553,19559,19571,19577,19583,19597,19603,19609,19661,19681,19687,
+19697,19699,19709,19717,19727,19739,19751,19753,19759,19763,19777,19793,19801,
+19813,19819,19841,19843,19853,19861,19867,19889,19891,19913,19919,19927,19937,
+19949,19961,19963,19973,19979,19991,19993,19997,20011,20021,20023,20029,20047,
+20051,20063,20071,20089,20101,20107,20113,20117,20123,20129,20143,20147,20149,
+20161,20173,20177,20183,20201,20219,20231,20233,20249,20261,20269,20287,20297,
+20323,20327,20333,20341,20347,20353,20357,20359,20369,20389,20393,20399,20407,
+20411,20431,20441,20443,20477,20479,20483,20507,20509,20521,20533,20543,20549,
+20551,20563,20593,20599,20611,20627,20639,20641,20663,20681,20693,20707,20717,
+20719,20731,20743,20747,20749,20753,20759,20771,20773,20789,20807,20809,20849,
+20857,20873,20879,20887,20897,20899,20903,20921,20929,20939,20947,20959,20963,
+20981,20983,21001,21011,21013,21017,21019,21023,21031,21059,21061,21067,21089,
+21101,21107,21121,21139,21143,21149,21157,21163,21169,21179,21187,21191,21193,
+21211,21221,21227,21247,21269,21277,21283,21313,21317,21319,21323,21341,21347,
+21377,21379,21383,21391,21397,21401,21407,21419,21433,21467,21481,21487,21491,
+21493,21499,21503,21517,21521,21523,21529,21557,21559,21563,21569,21577,21587,
+21589,21599,21601,21611,21613,21617,21647,21649,21661,21673,21683,21701,21713,
+21727,21737,21739,21751,21757,21767,21773,21787,21799,21803,21817,21821,21839,
+21841,21851,21859,21863,21871,21881,21893,21911,21929,21937,21943,21961,21977,
+21991,21997,22003,22013,22027,22031,22037,22039,22051,22063,22067,22073,22079,
+22091,22093,22109,22111,22123,22129,22133,22147,22153,22157,22159,22171,22189,
+22193,22229,22247,22259,22271,22273,22277,22279,22283,22291,22303,22307,22343,
+22349,22367,22369,22381,22391,22397,22409,22433,22441,22447,22453,22469,22481,
+22483,22501,22511,22531,22541,22543,22549,22567,22571,22573,22613,22619,22621,
+22637,22639,22643,22651,22669,22679,22691,22697,22699,22709,22717,22721,22727,
+22739,22741,22751,22769,22777,22783,22787,22807,22811,22817,22853,22859,22861,
+22871,22877,22901,22907,22921,22937,22943,22961,22963,22973,22993,23003,23011,
+23017,23021,23027,23029,23039,23041,23053,23057,23059,23063,23071,23081,23087,
+23099,23117,23131,23143,23159,23167,23173,23189,23197,23201,23203,23209,23227,
+23251,23269,23279,23291,23293,23297,23311,23321,23327,23333,23339,23357,23369,
+23371,23399,23417,23431,23447,23459,23473,23497,23509,23531,23537,23539,23549,
+23557,23561,23563,23567,23581,23593,23599,23603,23609,23623,23627,23629,23633,
+23663,23669,23671,23677,23687,23689,23719,23741,23743,23747,23753,23761,23767,
+23773,23789,23801,23813,23819,23827,23831,23833,23857,23869,23873,23879,23887,
+23893,23899,23909,23911,23917,23929,23957,23971,23977,23981,23993,24001,24007,
+24019,24023,24029,24043,24049,24061,24071,24077,24083,24091,24097,24103,24107,
+24109,24113,24121,24133,24137,24151,24169,24179,24181,24197,24203,24223,24229,
+24239,24247,24251,24281,24317,24329,24337,24359,24371,24373,24379,24391,24407,
+24413,24419,24421,24439,24443,24469,24473,24481,24499,24509,24517,24527,24533,
+24547,24551,24571,24593,24611,24623,24631,24659,24671,24677,24683,24691,24697,
+24709,24733,24749,24763,24767,24781,24793,24799,24809,24821,24841,24847,24851,
+24859,24877,24889,24907,24917,24919,24923,24943,24953,24967,24971,24977,24979,
+24989,25013,25031,25033,25037,25057,25073,25087,25097,25111,25117,25121,25127,
+25147,25153,25163,25169,25171,25183,25189,25219,25229,25237,25243,25247,25253,
+25261,25301,25303,25307,25309,25321,25339,25343,25349,25357,25367,25373,25391,
+25409,25411,25423,25439,25447,25453,25457,25463,25469,25471,25523,25537,25541,
+25561,25577,25579,25583,25589,25601,25603,25609,25621,25633,25639,25643,25657,
+25667,25673,25679,25693,25703,25717,25733,25741,25747,25759,25763,25771,25793,
+25799,25801,25819,25841,25847,25849,25867,25873,25889,25903,25913,25919,25931,
+25933,25939,25943,25951,25969,25981,25997,25999,26003,26017,26021,26029,26041,
+26053,26083,26099,26107,26111,26113,26119,26141,26153,26161,26171,26177,26183,
+26189,26203,26209,26227,26237,26249,26251,26261,26263,26267,26293,26297,26309,
+26317,26321,26339,26347,26357,26371,26387,26393,26399,26407,26417,26423,26431,
+26437,26449,26459,26479,26489,26497,26501,26513,26539,26557,26561,26573,26591,
+26597,26627,26633,26641,26647,26669,26681,26683,26687,26693,26699,26701,26711,
+26713,26717,26723,26729,26731,26737,26759,26777,26783,26801,26813,26821,26833,
+26839,26849,26861,26863,26879,26881,26891,26893,26903,26921,26927,26947,26951,
+26953,26959,26981,26987,26993,27011,27017,27031,27043,27059,27061,27067,27073,
+27077,27091,27103,27107,27109,27127,27143,27179,27191,27197,27211,27239,27241,
+27253,27259,27271,27277,27281,27283,27299,27329,27337,27361,27367,27397,27407,
+27409,27427,27431,27437,27449,27457,27479,27481,27487,27509,27527,27529,27539,
+27541,27551,27581,27583,27611,27617,27631,27647,27653,27673,27689,27691,27697,
+27701,27733,27737,27739,27743,27749,27751,27763,27767,27773,27779,27791,27793,
+27799,27803,27809,27817,27823,27827,27847,27851,27883,27893,27901,27917,27919,
+27941,27943,27947,27953,27961,27967,27983,27997,28001,28019,28027,28031,28051,
+28057,28069,28081,28087,28097,28099,28109,28111,28123,28151,28163,28181,28183,
+28201,28211,28219,28229,28277,28279,28283,28289,28297,28307,28309,28319,28349,
+28351,28387,28393,28403,28409,28411,28429,28433,28439,28447,28463,28477,28493,
+28499,28513,28517,28537,28541,28547,28549,28559,28571,28573,28579,28591,28597,
+28603,28607,28619,28621,28627,28631,28643,28649,28657,28661,28663,28669,28687,
+28697,28703,28711,28723,28729,28751,28753,28759,28771,28789,28793,28807,28813,
+28817,28837,28843,28859,28867,28871,28879,28901,28909,28921,28927,28933,28949,
+28961,28979,29009,29017,29021,29023,29027,29033,29059,29063,29077,29101,29123,
+29129,29131,29137,29147,29153,29167,29173,29179,29191,29201,29207,29209,29221,
+29231,29243,29251,29269,29287,29297,29303,29311,29327,29333,29339,29347,29363,
+29383,29387,29389,29399,29401,29411,29423,29429,29437,29443,29453,29473,29483,
+29501,29527,29531,29537,29567,29569,29573,29581,29587,29599,29611,29629,29633,
+29641,29663,29669,29671,29683,29717,29723,29741,29753,29759,29761,29789,29803,
+29819,29833,29837,29851,29863,29867,29873,29879,29881,29917,29921,29927,29947,
+29959,29983,29989,30011,30013,30029,30047,30059,30071,30089,30091,30097,30103,
+30109,30113,30119,30133,30137,30139,30161,30169,30181,30187,30197,30203,30211,
+30223,30241,30253,30259,30269,30271,30293,30307,30313,30319,30323,30341,30347,
+30367,30389,30391,30403,30427,30431,30449,30467,30469,30491,30493,30497,30509,
+30517,30529,30539,30553,30557,30559,30577,30593,30631,30637,30643,30649,30661,
+30671,30677,30689,30697,30703,30707,30713,30727,30757,30763,30773,30781,30803,
+30809,30817,30829,30839,30841,30851,30853,30859,30869,30871,30881,30893,30911,
+30931,30937,30941,30949,30971,30977,30983,31013,31019,31033,31039,31051,31063,
+31069,31079,31081,31091,31121,31123,31139,31147,31151,31153,31159,31177,31181,
+31183,31189,31193,31219,31223,31231,31237,31247,31249,31253,31259,31267,31271,
+31277,31307,31319,31321,31327,31333,31337,31357,31379,31387,31391,31393,31397,
+31469,31477,31481,31489,31511,31513,31517,31531,31541,31543,31547,31567,31573,
+31583,31601,31607,31627,31643,31649,31657,31663,31667,31687,31699,31721,31723,
+31727,31729,31741,31751,31769,31771,31793,31799,31817,31847,31849,31859,31873,
+31883,31891,31907,31957,31963,31973,31981,31991,32003,32009,32027,32029,32051,
+32057,32059,32063,32069,32077,32083,32089,32099,32117,32119,32141,32143,32159,
+32173,32183,32189,32191,32203,32213,32233,32237,32251,32257,32261,32297,32299,
+32303,32309,32321,32323,32327,32341,32353,32359,32363,32369,32371,32377,32381,
+32401,32411,32413,32423,32429,32441,32443,32467,32479,32491,32497,32503,32507,
+32531,32533,32537,32561,32563,32569,32573,32579,32587,32603,32609,32611,32621,
+32633,32647,32653,32687,32693,32707,32713,32717,32719,32749,32771,32779,32783,
+32789,32797,32801,32803,32831,32833,32839,32843,32869,32887,32909,32911,32917,
+32933,32939,32941,32957,32969,32971,32983,32987,32993,32999,33013,33023,33029,
+33037,33049,33053,33071,33073,33083,33091,33107,33113,33119,33149,33151,33161,
+33179,33181,33191,33199,33203,33211,33223,33247,33287,33289,33301,33311,33317,
+33329,33331,33343,33347,33349,33353,33359,33377,33391,33403,33409,33413,33427,
+33457,33461,33469,33479,33487,33493,33503,33521,33529,33533,33547,33563,33569,
+33577,33581,33587,33589,33599,33601,33613,33617,33619,33623,33629,33637,33641,
+33647,33679,33703,33713,33721,33739,33749,33751,33757,33767,33769,33773,33791,
+33797,33809,33811,33827,33829,33851,33857,33863,33871,33889,33893,33911,33923,
+33931,33937,33941,33961,33967,33997,34019,34031,34033,34039,34057,34061,34123,
+34127,34129,34141,34147,34157,34159,34171,34183,34211,34213,34217,34231,34253,
+34259,34261,34267,34273,34283,34297,34301,34303,34313,34319,34327,34337,34351,
+34361,34367,34369,34381,34403,34421,34429,34439,34457,34469,34471,34483,34487,
+34499,34501,34511,34513,34519,34537,34543,34549,34583,34589,34591,34603,34607,
+34613,34631,34649,34651,34667,34673,34679,34687,34693,34703,34721,34729,34739,
+34747,34757,34759,34763,34781,34807,34819,34841,34843,34847,34849,34871,34877,
+34883,34897,34913,34919,34939,34949,34961,34963,34981,35023,35027,35051,35053,
+35059,35069,35081,35083,35089,35099,35107,35111,35117,35129,35141,35149,35153,
+35159,35171,35201,35221,35227,35251,35257,35267,35279,35281,35291,35311,35317,
+35323,35327,35339,35353,35363,35381,35393,35401,35407,35419,35423,35437,35447,
+35449,35461,35491,35507,35509,35521,35527,35531,35533,35537,35543,35569,35573,
+35591,35593,35597,35603,35617,35671,35677,35729,35731,35747,35753,35759,35771,
+35797,35801,35803,35809,35831,35837,35839,35851,35863,35869,35879,35897,35899,
+35911,35923,35933,35951,35963,35969,35977,35983,35993,35999,36007,36011,36013,
+36017,36037,36061,36067,36073,36083,36097,36107,36109,36131,36137,36151,36161,
+36187,36191,36209,36217,36229,36241,36251,36263,36269,36277,36293,36299,36307,
+36313,36319,36341,36343,36353,36373,36383,36389,36433,36451,36457,36467,36469,
+36473,36479,36493,36497,36523,36527,36529,36541,36551,36559,36563,36571,36583,
+36587,36599,36607,36629,36637,36643,36653,36671,36677,36683,36691,36697,36709,
+36713,36721,36739,36749,36761,36767,36779,36781,36787,36791,36793,36809,36821,
+36833,36847,36857,36871,36877,36887,36899,36901,36913,36919,36923,36929,36931,
+36943,36947,36973,36979,36997,37003,37013,37019,37021,37039,37049,37057,37061,
+37087,37097,37117,37123,37139,37159,37171,37181,37189,37199,37201,37217,37223,
+37243,37253,37273,37277,37307,37309,37313,37321,37337,37339,37357,37361,37363,
+37369,37379,37397,37409,37423,37441,37447,37463,37483,37489,37493,37501,37507,
+37511,37517,37529,37537,37547,37549,37561,37567,37571,37573,37579,37589,37591,
+37607,37619,37633,37643,37649,37657,37663,37691,37693,37699,37717,37747,37781,
+37783,37799,37811,37813,37831,37847,37853,37861,37871,37879,37889,37897,37907,
+37951,37957,37963,37967,37987,37991,37993,37997,38011,38039,38047,38053,38069,
+38083,38113,38119,38149,38153,38167,38177,38183,38189,38197,38201,38219,38231,
+38237,38239,38261,38273,38281,38287,38299,38303,38317,38321,38327,38329,38333,
+38351,38371,38377,38393,38431,38447,38449,38453,38459,38461,38501,38543,38557,
+38561,38567,38569,38593,38603,38609,38611,38629,38639,38651,38653,38669,38671,
+38677,38693,38699,38707,38711,38713,38723,38729,38737,38747,38749,38767,38783,
+38791,38803,38821,38833,38839,38851,38861,38867,38873,38891,38903,38917,38921,
+38923,38933,38953,38959,38971,38977,38993,39019,39023,39041,39043,39047,39079,
+39089,39097,39103,39107,39113,39119,39133,39139,39157,39161,39163,39181,39191,
+39199,39209,39217,39227,39229,39233,39239,39241,39251,39293,39301,39313,39317,
+39323,39341,39343,39359,39367,39371,39373,39383,39397,39409,39419,39439,39443,
+39451,39461,39499,39503,39509,39511,39521,39541,39551,39563,39569,39581,39607,
+39619,39623,39631,39659,39667,39671,39679,39703,39709,39719,39727,39733,39749,
+39761,39769,39779,39791,39799,39821,39827,39829,39839,39841,39847,39857,39863,
+39869,39877,39883,39887,39901,39929,39937,39953,39971,39979,39983,39989,40009,
+40013,40031,40037,40039,40063,40087,40093,40099,40111,40123,40127,40129,40151,
+40153,40163,40169,40177,40189,40193,40213,40231,40237,40241,40253,40277,40283,
+40289,40343,40351,40357,40361,40387,40423,40427,40429,40433,40459,40471,40483,
+40487,40493,40499,40507,40519,40529,40531,40543,40559,40577,40583,40591,40597,
+40609,40627,40637,40639,40693,40697,40699,40709,40739,40751,40759,40763,40771,
+40787,40801,40813,40819,40823,40829,40841,40847,40849,40853,40867,40879,40883,
+40897,40903,40927,40933,40939,40949,40961,40973,40993,41011,41017,41023,41039,
+41047,41051,41057,41077,41081,41113,41117,41131,41141,41143,41149,41161,41177,
+41179,41183,41189,41201,41203,41213,41221,41227,41231,41233,41243,41257,41263,
+41269,41281,41299,41333,41341,41351,41357,41381,41387,41389,41399,41411,41413,
+41443,41453,41467,41479,41491,41507,41513,41519,41521,41539,41543,41549,41579,
+41593,41597,41603,41609,41611,41617,41621,41627,41641,41647,41651,41659,41669,
+41681,41687,41719,41729,41737,41759,41761,41771,41777,41801,41809,41813,41843,
+41849,41851,41863,41879,41887,41893,41897,41903,41911,41927,41941,41947,41953,
+41957,41959,41969,41981,41983,41999,42013,42017,42019,42023,42043,42061,42071,
+42073,42083,42089,42101,42131,42139,42157,42169,42179,42181,42187,42193,42197,
+42209,42221,42223,42227,42239,42257,42281,42283,42293,42299,42307,42323,42331,
+42337,42349,42359,42373,42379,42391,42397,42403,42407,42409,42433,42437,42443,
+42451,42457,42461,42463,42467,42473,42487,42491,42499,42509,42533,42557,42569,
+42571,42577,42589,42611,42641,42643,42649,42667,42677,42683,42689,42697,42701,
+42703,42709,42719,42727,42737,42743,42751,42767,42773,42787,42793,42797,42821,
+42829,42839,42841,42853,42859,42863,42899,42901,42923,42929,42937,42943,42953,
+42961,42967,42979,42989,43003,43013,43019,43037,43049,43051,43063,43067,43093,
+43103,43117,43133,43151,43159,43177,43189,43201,43207,43223,43237,43261,43271,
+43283,43291,43313,43319,43321,43331,43391,43397,43399,43403,43411,43427,43441,
+43451,43457,43481,43487,43499,43517,43541,43543,43573,43577,43579,43591,43597,
+43607,43609,43613,43627,43633,43649,43651,43661,43669,43691,43711,43717,43721,
+43753,43759,43777,43781,43783,43787,43789,43793,43801,43853,43867,43889,43891,
+43913,43933,43943,43951,43961,43963,43969,43973,43987,43991,43997,44017,44021,
+44027,44029,44041,44053,44059,44071,44087,44089,44101,44111,44119,44123,44129,
+44131,44159,44171,44179,44189,44201,44203,44207,44221,44249,44257,44263,44267,
+44269,44273,44279,44281,44293,44351,44357,44371,44381,44383,44389,44417,44449,
+44453,44483,44491,44497,44501,44507,44519,44531,44533,44537,44543,44549,44563,
+44579,44587,44617,44621,44623,44633,44641,44647,44651,44657,44683,44687,44699,
+44701,44711,44729,44741,44753,44771,44773,44777,44789,44797,44809,44819,44839,
+44843,44851,44867,44879,44887,44893,44909,44917,44927,44939,44953,44959,44963,
+44971,44983,44987,45007,45013,45053,45061,45077,45083,45119,45121,45127,45131,
+45137,45139,45161,45179,45181,45191,45197,45233,45247,45259,45263,45281,45289,
+45293,45307,45317,45319,45329,45337,45341,45343,45361,45377,45389,45403,45413,
+45427,45433,45439,45481,45491,45497,45503,45523,45533,45541,45553,45557,45569,
+45587,45589,45599,45613,45631,45641,45659,45667,45673,45677,45691,45697,45707,
+45737,45751,45757,45763,45767,45779,45817,45821,45823,45827,45833,45841,45853,
+45863,45869,45887,45893,45943,45949,45953,45959,45971,45979,45989,46021,46027,
+46049,46051,46061,46073,46091,46093,46099,46103,46133,46141,46147,46153,46171,
+46181,46183,46187,46199,46219,46229,46237,46261,46271,46273,46279,46301,46307,
+46309,46327,46337,46349,46351,46381,46399,46411,46439,46441,46447,46451,46457,
+46471,46477,46489,46499,46507,46511,46523,46549,46559,46567,46573,46589,46591,
+46601,46619,46633,46639,46643,46649,46663,46679,46681,46687,46691,46703,46723,
+46727,46747,46751,46757,46769,46771,46807,46811,46817,46819,46829,46831,46853,
+46861,46867,46877,46889,46901,46919,46933,46957,46993,46997,47017,47041,47051,
+47057,47059,47087,47093,47111,47119,47123,47129,47137,47143,47147,47149,47161,
+47189,47207,47221,47237,47251,47269,47279,47287,47293,47297,47303,47309,47317,
+47339,47351,47353,47363,47381,47387,47389,47407,47417,47419,47431,47441,47459,
+47491,47497,47501,47507,47513,47521,47527,47533,47543,47563,47569,47581,47591,
+47599,47609,47623,47629,47639,47653,47657,47659,47681,47699,47701,47711,47713,
+47717,47737,47741,47743,47777,47779,47791,47797,47807,47809,47819,47837,47843,
+47857,47869,47881,47903,47911,47917,47933,47939,47947,47951,47963,47969,47977,
+47981,48017,48023,48029,48049,48073,48079,48091,48109,48119,48121,48131,48157,
+48163,48179,48187,48193,48197,48221,48239,48247,48259,48271,48281,48299,48311,
+48313,48337,48341,48353,48371,48383,48397,48407,48409,48413,48437,48449,48463,
+48473,48479,48481,48487,48491,48497,48523,48527,48533,48539,48541,48563,48571,
+48589,48593,48611,48619,48623,48647,48649,48661,48673,48677,48679,48731,48733,
+48751,48757,48761,48767,48779,48781,48787,48799,48809,48817,48821,48823,48847,
+48857,48859,48869,48871,48883,48889,48907,48947,48953,48973,48989,48991,49003,
+49009,49019,49031,49033,49037,49043,49057,49069,49081,49103,49109,49117,49121,
+49123,49139,49157,49169,49171,49177,49193,49199,49201,49207,49211,49223,49253,
+49261,49277,49279,49297,49307,49331,49333,49339,49363,49367,49369,49391,49393,
+49409,49411,49417,49429,49433,49451,49459,49463,49477,49481,49499,49523,49529,
+49531,49537,49547,49549,49559,49597,49603,49613,49627,49633,49639,49663,49667,
+49669,49681,49697,49711,49727,49739,49741,49747,49757,49783,49787,49789,49801,
+49807,49811,49823,49831,49843,49853,49871,49877,49891,49919,49921,49927,49937,
+49939,49943,49957,49991,49993,49999,50021,50023,50033,50047,50051,50053,50069,
+50077,50087,50093,50101,50111,50119,50123,50129,50131,50147,50153,50159,50177,
+50207,50221,50227,50231,50261,50263,50273,50287,50291,50311,50321,50329,50333,
+50341,50359,50363,50377,50383,50387,50411,50417,50423,50441,50459,50461,50497,
+50503,50513,50527,50539,50543,50549,50551,50581,50587,50591,50593,50599,50627,
+50647,50651,50671,50683,50707,50723,50741,50753,50767,50773,50777,50789,50821,
+50833,50839,50849,50857,50867,50873,50891,50893,50909,50923,50929,50951,50957,
+50969,50971,50989,50993,51001,51031,51043,51047,51059,51061,51071,51109,51131,
+51133,51137,51151,51157,51169,51193,51197,51199,51203,51217,51229,51239,51241,
+51257,51263,51283,51287,51307,51329,51341,51343,51347,51349,51361,51383,51407,
+51413,51419,51421,51427,51431,51437,51439,51449,51461,51473,51479,51481,51487,
+51503,51511,51517,51521,51539,51551,51563,51577,51581,51593,51599,51607,51613,
+51631,51637,51647,51659,51673,51679,51683,51691,51713,51719,51721,51749,51767,
+51769,51787,51797,51803,51817,51827,51829,51839,51853,51859,51869,51871,51893,
+51899,51907,51913,51929,51941,51949,51971,51973,51977,51991,52009,52021,52027,
+52051,52057,52067,52069,52081,52103,52121,52127,52147,52153,52163,52177,52181,
+52183,52189,52201,52223,52237,52249,52253,52259,52267,52289,52291,52301,52313,
+52321,52361,52363,52369,52379,52387,52391,52433,52453,52457,52489,52501,52511,
+52517,52529,52541,52543,52553,52561,52567,52571,52579,52583,52609,52627,52631,
+52639,52667,52673,52691,52697,52709,52711,52721,52727,52733,52747,52757,52769,
+52783,52807,52813,52817,52837,52859,52861,52879,52883,52889,52901,52903,52919,
+52937,52951,52957,52963,52967,52973,52981,52999,53003,53017,53047,53051,53069,
+53077,53087,53089,53093,53101,53113,53117,53129,53147,53149,53161,53171,53173,
+53189,53197,53201,53231,53233,53239,53267,53269,53279,53281,53299,53309,53323,
+53327,53353,53359,53377,53381,53401,53407,53411,53419,53437,53441,53453,53479,
+53503,53507,53527,53549,53551,53569,53591,53593,53597,53609,53611,53617,53623,
+53629,53633,53639,53653,53657,53681,53693,53699,53717,53719,53731,53759,53773,
+53777,53783,53791,53813,53819,53831,53849,53857,53861,53881,53887,53891,53897,
+53899,53917,53923,53927,53939,53951,53959,53987,53993,54001,54011,54013,54037,
+54049,54059,54083,54091,54101,54121,54133,54139,54151,54163,54167,54181,54193,
+54217,54251,54269,54277,54287,54293,54311,54319,54323,54331,54347,54361,54367,
+54371,54377,54401,54403,54409,54413,54419,54421,54437,54443,54449,54469,54493,
+54497,54499,54503,54517,54521,54539,54541,54547,54559,54563,54577,54581,54583,
+54601,54617,54623,54629,54631,54647,54667,54673,54679,54709,54713,54721,54727,
+54751,54767,54773,54779,54787,54799,54829,54833,54851,54869,54877,54881,54907,
+54917,54919,54941,54949,54959,54973,54979,54983,55001,55009,55021,55049,55051,
+55057,55061,55073,55079,55103,55109,55117,55127,55147,55163,55171,55201,55207,
+55213,55217,55219,55229,55243,55249,55259,55291,55313,55331,55333,55337,55339,
+55343,55351,55373,55381,55399,55411,55439,55441,55457,55469,55487,55501,55511,
+55529,55541,55547,55579,55589,55603,55609,55619,55621,55631,55633,55639,55661,
+55663,55667,55673,55681,55691,55697,55711,55717,55721,55733,55763,55787,55793,
+55799,55807,55813,55817,55819,55823,55829,55837,55843,55849,55871,55889,55897,
+55901,55903,55921,55927,55931,55933,55949,55967,55987,55997,56003,56009,56039,
+56041,56053,56081,56087,56093,56099,56101,56113,56123,56131,56149,56167,56171,
+56179,56197,56207,56209,56237,56239,56249,56263,56267,56269,56299,56311,56333,
+56359,56369,56377,56383,56393,56401,56417,56431,56437,56443,56453,56467,56473,
+56477,56479,56489,56501,56503,56509,56519,56527,56531,56533,56543,56569,56591,
+56597,56599,56611,56629,56633,56659,56663,56671,56681,56687,56701,56711,56713,
+56731,56737,56747,56767,56773,56779,56783,56807,56809,56813,56821,56827,56843,
+56857,56873,56891,56893,56897,56909,56911,56921,56923,56929,56941,56951,56957,
+56963,56983,56989,56993,56999,57037,57041,57047,57059,57073,57077,57089,57097,
+57107,57119,57131,57139,57143,57149,57163,57173,57179,57191,57193,57203,57221,
+57223,57241,57251,57259,57269,57271,57283,57287,57301,57329,57331,57347,57349,
+57367,57373,57383,57389,57397,57413,57427,57457,57467,57487,57493,57503,57527,
+57529,57557,57559,57571,57587,57593,57601,57637,57641,57649,57653,57667,57679,
+57689,57697,57709,57713,57719,57727,57731,57737,57751,57773,57781,57787,57791,
+57793,57803,57809,57829,57839,57847,57853,57859,57881,57899,57901,57917,57923,
+57943,57947,57973,57977,57991,58013,58027,58031,58043,58049,58057,58061,58067,
+58073,58099,58109,58111,58129,58147,58151,58153,58169,58171,58189,58193,58199,
+58207,58211,58217,58229,58231,58237,58243,58271,58309,58313,58321,58337,58363,
+58367,58369,58379,58391,58393,58403,58411,58417,58427,58439,58441,58451,58453,
+58477,58481,58511,58537,58543,58549,58567,58573,58579,58601,58603,58613,58631,
+58657,58661,58679,58687,58693,58699,58711,58727,58733,58741,58757,58763,58771,
+58787,58789,58831,58889,58897,58901,58907,58909,58913,58921,58937,58943,58963,
+58967,58979,58991,58997,59009,59011,59021,59023,59029,59051,59053,59063,59069,
+59077,59083,59093,59107,59113,59119,59123,59141,59149,59159,59167,59183,59197,
+59207,59209,59219,59221,59233,59239,59243,59263,59273,59281,59333,59341,59351,
+59357,59359,59369,59377,59387,59393,59399,59407,59417,59419,59441,59443,59447,
+59453,59467,59471,59473,59497,59509,59513,59539,59557,59561,59567,59581,59611,
+59617,59621,59627,59629,59651,59659,59663,59669,59671,59693,59699,59707,59723,
+59729,59743,59747,59753,59771,59779,59791,59797,59809,59833,59863,59879,59887,
+59921,59929,59951,59957,59971,59981,59999,60013,60017,60029,60037,60041,60077,
+60083,60089,60091,60101,60103,60107,60127,60133,60139,60149,60161,60167,60169,
+60209,60217,60223,60251,60257,60259,60271,60289,60293,60317,60331,60337,60343,
+60353,60373,60383,60397,60413,60427,60443,60449,60457,60493,60497,60509,60521,
+60527,60539,60589,60601,60607,60611,60617,60623,60631,60637,60647,60649,60659,
+60661,60679,60689,60703,60719,60727,60733,60737,60757,60761,60763,60773,60779,
+60793,60811,60821,60859,60869,60887,60889,60899,60901,60913,60917,60919,60923,
+60937,60943,60953,60961,61001,61007,61027,61031,61043,61051,61057,61091,61099,
+61121,61129,61141,61151,61153,61169,61211,61223,61231,61253,61261,61283,61291,
+61297,61331,61333,61339,61343,61357,61363,61379,61381,61403,61409,61417,61441,
+61463,61469,61471,61483,61487,61493,61507,61511,61519,61543,61547,61553,61559,
+61561,61583,61603,61609,61613,61627,61631,61637,61643,61651,61657,61667,61673,
+61681,61687,61703,61717,61723,61729,61751,61757,61781,61813,61819,61837,61843,
+61861,61871,61879,61909,61927,61933,61949,61961,61967,61979,61981,61987,61991,
+62003,62011,62017,62039,62047,62053,62057,62071,62081,62099,62119,62129,62131,
+62137,62141,62143,62171,62189,62191,62201,62207,62213,62219,62233,62273,62297,
+62299,62303,62311,62323,62327,62347,62351,62383,62401,62417,62423,62459,62467,
+62473,62477,62483,62497,62501,62507,62533,62539,62549,62563,62581,62591,62597,
+62603,62617,62627,62633,62639,62653,62659,62683,62687,62701,62723,62731,62743,
+62753,62761,62773,62791,62801,62819,62827,62851,62861,62869,62873,62897,62903,
+62921,62927,62929,62939,62969,62971,62981,62983,62987,62989,63029,63031,63059,
+63067,63073,63079,63097,63103,63113,63127,63131,63149,63179,63197,63199,63211,
+63241,63247,63277,63281,63299,63311,63313,63317,63331,63337,63347,63353,63361,
+63367,63377,63389,63391,63397,63409,63419,63421,63439,63443,63463,63467,63473,
+63487,63493,63499,63521,63527,63533,63541,63559,63577,63587,63589,63599,63601,
+63607,63611,63617,63629,63647,63649,63659,63667,63671,63689,63691,63697,63703,
+63709,63719,63727,63737,63743,63761,63773,63781,63793,63799,63803,63809,63823,
+63839,63841,63853,63857,63863,63901,63907,63913,63929,63949,63977,63997,64007,
+64013,64019,64033,64037,64063,64067,64081,64091,64109,64123,64151,64153,64157,
+64171,64187,64189,64217,64223,64231,64237,64271,64279,64283,64301,64303,64319,
+64327,64333,64373,64381,64399,64403,64433,64439,64451,64453,64483,64489,64499,
+64513,64553,64567,64577,64579,64591,64601,64609,64613,64621,64627,64633,64661,
+64663,64667,64679,64693,64709,64717,64747,64763,64781,64783,64793,64811,64817,
+64849,64853,64871,64877,64879,64891,64901,64919,64921,64927,64937,64951,64969,
+64997,65003,65011,65027,65029,65033,65053,65063,65071,65089,65099,65101,65111,
+65119,65123,65129,65141,65147,65167,65171,65173,65179,65183,65203,65213,65239,
+65257,65267,65269,65287,65293,65309,65323,65327,65353,65357,65371,65381,65393,
+65407,65413,65419,65423,65437,65447,65449,65479,65497,65519,65521,65537
+};
+
+/* pr_limit - largest prime in the prime table */
+unsigned long *pr_limit = &prime[(sizeof(prime)/sizeof(prime[0]))-1];
diff --git a/primes/primes.c b/primes/primes.c
new file mode 100644
index 00000000..faabc05a
--- /dev/null
+++ b/primes/primes.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Landon Curt Noll.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)primes.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * primes - generate a table of primes between two values
+ *
+ * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
+ *
+ * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+ *
+ * usage:
+ * primes [start [stop]]
+ *
+ * Print primes >= start and < stop. If stop is omitted,
+ * the value 4294967295 (2^32-1) is assumed. If start is
+ * omitted, start is read from standard input.
+ *
+ * Prints "ouch" if start or stop is bogus.
+ *
+ * validation check: there are 664579 primes between 0 and 10^7
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <memory.h>
+#include <ctype.h>
+#include "primes.h"
+
+/*
+ * Eratosthenes sieve table
+ *
+ * We only sieve the odd numbers. The base of our sieve windows are always
+ * odd. If the base of table is 1, table[i] represents 2*i-1. After the
+ * sieve, table[i] == 1 if and only iff 2*i-1 is prime.
+ *
+ * We make TABSIZE large to reduce the overhead of inner loop setup.
+ */
+char table[TABSIZE]; /* Eratosthenes sieve of odd numbers */
+
+/*
+ * prime[i] is the (i-1)th prime.
+ *
+ * We are able to sieve 2^32-1 because this byte table yields all primes
+ * up to 65537 and 65537^2 > 2^32-1.
+ */
+extern ubig prime[];
+extern ubig *pr_limit; /* largest prime in the prime array */
+
+/*
+ * To avoid excessive sieves for small factors, we use the table below to
+ * setup our sieve blocks. Each element represents a odd number starting
+ * with 1. All non-zero elements are factors of 3, 5, 7, 11 and 13.
+ */
+extern char pattern[];
+extern int pattern_size; /* length of pattern array */
+
+#define MAX_LINE 255 /* max line allowed on stdin */
+
+char *read_num_buf(); /* read a number buffer */
+void primes(); /* print the primes in range */
+char *program; /* our name */
+
+main(argc, argv)
+ int argc; /* arg count */
+ char *argv[]; /* args */
+{
+ char buf[MAX_LINE+1]; /* input buffer */
+ char *ret; /* return result */
+ ubig start; /* where to start generating */
+ ubig stop; /* don't generate at or above this value */
+
+ /*
+ * parse args
+ */
+ program = argv[0];
+ start = 0;
+ stop = BIG;
+ if (argc == 3) {
+ /* convert low and high args */
+ if (read_num_buf(NULL, argv[1]) == NULL) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ if (read_num_buf(NULL, argv[2]) == NULL) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ if (sscanf(argv[1], "%ld", &start) != 1) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ if (sscanf(argv[2], "%ld", &stop) != 1) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+
+ } else if (argc == 2) {
+ /* convert low arg */
+ if (read_num_buf(NULL, argv[1]) == NULL) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ if (sscanf(argv[1], "%ld", &start) != 1) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+
+ } else {
+ /* read input until we get a good line */
+ if (read_num_buf(stdin, buf) != NULL) {
+
+ /* convert the buffer */
+ if (sscanf(buf, "%ld", &start) != 1) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ } else {
+ exit(0);
+ }
+ }
+ if (start > stop) {
+ fprintf(stderr, "%s: ouch\n", program);
+ exit(1);
+ }
+ primes(start, stop);
+ exit(0);
+}
+
+/*
+ * read_num_buf - read a number buffer from a stream
+ *
+ * Read a number on a line of the form:
+ *
+ * ^[ \t]*\(+?[0-9][0-9]\)*.*$
+ *
+ * where ? is a 1-or-0 operator and the number is within \( \).
+ *
+ * If does not match the above pattern, it is ignored and a new
+ * line is read. If the number is too large or small, we will
+ * print ouch and read a new line.
+ *
+ * We have to be very careful on how we check the magnitude of the
+ * input. We can not use numeric checks because of the need to
+ * check values against maximum numeric values.
+ *
+ * This routine will return a line containing a ascii number between
+ * 0 and BIG, or it will return NULL.
+ *
+ * If the stream is NULL then buf will be processed as if were
+ * a single line stream.
+ *
+ * returns:
+ * char * pointer to leading digit or +
+ * NULL EOF or error
+ */
+char *
+read_num_buf(input, buf)
+ FILE *input; /* input stream or NULL */
+ char *buf; /* input buffer */
+{
+ static char limit[MAX_LINE+1]; /* ascii value of BIG */
+ static int limit_len; /* digit count of limit */
+ int len; /* digits in input (excluding +/-) */
+ char *s; /* line start marker */
+ char *d; /* first digit, skip +/- */
+ char *p; /* scan pointer */
+ char *z; /* zero scan pointer */
+
+ /* form the ascii value of SEMIBIG if needed */
+ if (!isascii(limit[0]) || !isdigit(limit[0])) {
+ sprintf(limit, "%ld", SEMIBIG);
+ limit_len = strlen(limit);
+ }
+
+ /*
+ * the search for a good line
+ */
+ if (input != NULL && fgets(buf, MAX_LINE, input) == NULL) {
+ /* error or EOF */
+ return NULL;
+ }
+ do {
+
+ /* ignore leading whitespace */
+ for (s=buf; *s && s < buf+MAX_LINE; ++s) {
+ if (!isascii(*s) || !isspace(*s)) {
+ break;
+ }
+ }
+
+ /* object if - */
+ if (*s == '-') {
+ fprintf(stderr, "%s: ouch\n", program);
+ continue;
+ }
+
+ /* skip over any leading + */
+ if (*s == '+') {
+ d = s+1;
+ } else {
+ d = s;
+ }
+
+ /* note leading zeros */
+ for (z=d; *z && z < buf+MAX_LINE; ++z) {
+ if (*z != '0') {
+ break;
+ }
+ }
+
+ /* scan for the first non-digit/non-plus/non-minus */
+ for (p=d; *p && p < buf+MAX_LINE; ++p) {
+ if (!isascii(*p) || !isdigit(*p)) {
+ break;
+ }
+ }
+
+ /* ignore empty lines */
+ if (p == d) {
+ continue;
+ }
+ *p = '\0';
+
+ /* object if too many digits */
+ len = strlen(z);
+ len = (len<=0) ? 1 : len;
+ /* accept if digit count is below limit */
+ if (len < limit_len) {
+ /* we have good input */
+ return s;
+
+ /* reject very large numbers */
+ } else if (len > limit_len) {
+ fprintf(stderr, "%s: ouch\n", program);
+ continue;
+
+ /* carefully check against near limit numbers */
+ } else if (strcmp(z, limit) > 0) {
+ fprintf(stderr, "%s: ouch\n", program);
+ continue;
+ }
+ /* number is near limit, but is under it */
+ return s;
+ } while (input != NULL && fgets(buf, MAX_LINE, input) != NULL);
+
+ /* error or EOF */
+ return NULL;
+}
+
+/*
+ * primes - sieve and print primes from start up to and but not including stop
+ */
+void
+primes(start, stop)
+ ubig start; /* where to start generating */
+ ubig stop; /* don't generate at or above this value */
+{
+ register char *q; /* sieve spot */
+ register ubig factor; /* index and factor */
+ register char *tab_lim; /* the limit to sieve on the table */
+ register ubig *p; /* prime table pointer */
+ register ubig fact_lim; /* highest prime for current block */
+
+ /*
+ * A number of systems can not convert double values
+ * into unsigned longs when the values are larger than
+ * the largest signed value. Thus we take case when
+ * the double is larger than the value SEMIBIG. *sigh*
+ */
+ if (start < 3) {
+ start = (ubig)2;
+ }
+ if (stop < 3) {
+ stop = (ubig)2;
+ }
+ if (stop <= start) {
+ return;
+ }
+
+ /*
+ * be sure that the values are odd, or 2
+ */
+ if (start != 2 && (start&0x1) == 0) {
+ ++start;
+ }
+ if (stop != 2 && (stop&0x1) == 0) {
+ ++stop;
+ }
+
+ /*
+ * quick list of primes <= pr_limit
+ */
+ if (start <= *pr_limit) {
+ /* skip primes up to the start value */
+ for (p = &prime[0], factor = prime[0];
+ factor < stop && p <= pr_limit;
+ factor = *(++p)) {
+ if (factor >= start) {
+ printf("%u\n", factor);
+ }
+ }
+ /* return early if we are done */
+ if (p <= pr_limit) {
+ return;
+ }
+ start = *pr_limit+2;
+ }
+
+ /*
+ * we shall sieve a bytemap window, note primes and move the window
+ * upward until we pass the stop point
+ */
+ while (start < stop) {
+ /*
+ * factor out 3, 5, 7, 11 and 13
+ */
+ /* initial pattern copy */
+ factor = (start%(2*3*5*7*11*13))/2; /* starting copy spot */
+ memcpy(table, &pattern[factor], pattern_size-factor);
+ /* main block pattern copies */
+ for (fact_lim=pattern_size-factor;
+ fact_lim+pattern_size<=TABSIZE;
+ fact_lim+=pattern_size) {
+ memcpy(&table[fact_lim], pattern, pattern_size);
+ }
+ /* final block pattern copy */
+ memcpy(&table[fact_lim], pattern, TABSIZE-fact_lim);
+
+ /*
+ * sieve for primes 17 and higher
+ */
+ /* note highest useful factor and sieve spot */
+ if (stop-start > TABSIZE+TABSIZE) {
+ tab_lim = &table[TABSIZE]; /* sieve it all */
+ fact_lim = (int)sqrt(
+ (double)(start)+TABSIZE+TABSIZE+1.0);
+ } else {
+ tab_lim = &table[(stop-start)/2]; /* partial sieve */
+ fact_lim = (int)sqrt((double)(stop)+1.0);
+ }
+ /* sieve for factors >= 17 */
+ factor = 17; /* 17 is first prime to use */
+ p = &prime[7]; /* 19 is next prime, pi(19)=7 */
+ do {
+ /* determine the factor's initial sieve point */
+ q = (char *)(start%factor); /* temp storage for mod */
+ if ((int)q & 0x1) {
+ q = &table[(factor-(int)q)/2];
+ } else {
+ q = &table[q ? factor-((int)q/2) : 0];
+ }
+ /* sive for our current factor */
+ for ( ; q < tab_lim; q += factor) {
+ *q = '\0'; /* sieve out a spot */
+ }
+ } while ((factor=(ubig)(*(p++))) <= fact_lim);
+
+ /*
+ * print generated primes
+ */
+ for (q = table; q < tab_lim; ++q, start+=2) {
+ if (*q) {
+ printf("%u\n", start);
+ }
+ }
+ }
+}
diff --git a/primes/primes.h b/primes/primes.h
new file mode 100644
index 00000000..3cc34a20
--- /dev/null
+++ b/primes/primes.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Landon Curt Noll.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)primes.h 5.2 (Berkeley) 6/1/90
+ */
+
+/*
+ * primes - generate a table of primes between two values
+ *
+ * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
+ *
+ * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+ */
+
+/* ubig is the type that holds a large unsigned value */
+typedef unsigned long ubig; /* must be >=32 bit unsigned value */
+
+/*
+ * sieve parameters
+ */
+#define BIG ((ubig)0xffffffff) /* highest value we will sieve */
+#define SEMIBIG ((ubig)0x7fffffff) /* highest signed value */
+#define NEG_SEMIBIG ((ubig)0x80000000) /* lowest signed value */
+#define TABSIZE 256*1024 /* bytes in sieve table (must be > 3*5*7*11) */
diff --git a/rain/Makefile b/rain/Makefile
new file mode 100644
index 00000000..4e01dca9
--- /dev/null
+++ b/rain/Makefile
@@ -0,0 +1,8 @@
+# @(#)Makefile 5.3 (Berkeley) 5/11/90
+
+PROG= rain
+MAN6= rain.0
+DPADD= ${LIBTERM} ${LIBCOMPAT}
+LDADD= -ltermcap -lcompat
+
+.include <bsd.prog.mk>
diff --git a/rain/rain.6 b/rain/rain.6
new file mode 100644
index 00000000..3aecbdd7
--- /dev/null
+++ b/rain/rain.6
@@ -0,0 +1,54 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rain.6 6.3 (Berkeley) 6/23/90
+.\"
+.TH RAIN 6 "June 23, 1990"
+.UC 4
+.SH NAME
+rain \- animated raindrops display
+.SH SYNOPSIS
+rain
+.SH DESCRIPTION
+.PP
+.ad b
+.IR Rain 's
+display is modeled after the VAX/VMS program of the same name.
+The terminal has to be set for 9600 baud to obtain the proper effect.
+.PP
+As with all programs that use
+.IR termcap ,
+the TERM environment
+variable must be set (and exported) to the type of the terminal being used.
+.SH FILES
+/etc/termcap
+.SH AUTHOR
+Eric P. Scott
diff --git a/rain/rain.c b/rain/rain.c
new file mode 100644
index 00000000..1b126975
--- /dev/null
+++ b/rain/rain.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)rain.c 5.6 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * rain 11/3/1980 EPS/CITHEP
+ * cc rain.c -o rain -O -ltermlib
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef USG
+#include <termio.h>
+#else
+#include <sgtty.h>
+#endif
+#include <signal.h>
+
+#define cursor(c, r) tputs(tgoto(CM, c, r), 1, fputchar)
+
+#ifdef USG
+static struct termio sg, old_tty;
+#else
+static struct sgttyb sg, old_tty;
+#endif
+
+int fputchar();
+char *LL, *TE, *tgoto();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern short ospeed;
+ extern char *UP;
+ register int x, y, j;
+ register char *CM, *BC, *DN, *ND, *term;
+ char *TI, *tcp, *mp, tcb[100],
+ *malloc(), *getenv(), *strcpy(), *tgetstr();
+ long cols, lines, random();
+ int xpos[5], ypos[5];
+ static void onsig();
+
+ if (!(term = getenv("TERM"))) {
+ fprintf(stderr, "%s: TERM: parameter not set\n", *argv);
+ exit(1);
+ }
+ if (!(mp = malloc((u_int)1024))) {
+ fprintf(stderr, "%s: out of space.\n", *argv);
+ exit(1);
+ }
+ if (tgetent(mp, term) <= 0) {
+ fprintf(stderr, "%s: %s: unknown terminal type\n", *argv, term);
+ exit(1);
+ }
+ tcp = tcb;
+ if (!(CM = tgetstr("cm", &tcp))) {
+ fprintf(stderr, "%s: terminal not capable of cursor motion\n", *argv);
+ exit(1);
+ }
+ if (!(BC = tgetstr("bc", &tcp)))
+ BC = "\b";
+ if (!(DN = tgetstr("dn", &tcp)))
+ DN = "\n";
+ if (!(ND = tgetstr("nd", &tcp)))
+ ND = " ";
+ if ((cols = tgetnum("co")) == -1)
+ cols = 80;
+ if ((lines = tgetnum("li")) == -1)
+ lines = 24;
+ cols -= 4;
+ lines -= 4;
+ TE = tgetstr("te", &tcp);
+ TI = tgetstr("ti", &tcp);
+ UP = tgetstr("up", &tcp);
+ if (!(LL = tgetstr("ll", &tcp))) {
+ if (!(LL = malloc((u_int)10))) {
+ fprintf(stderr, "%s: out of space.\n", *argv);
+ exit(1);
+ }
+ (void)strcpy(LL, tgoto(CM, 0, 23));
+ }
+#ifdef USG
+ ioctl(1, TCGETA, &sg);
+ ospeed = sg.c_cflag&CBAUD;
+#else
+ gtty(1, &sg);
+ ospeed = sg.sg_ospeed;
+#endif
+ (void)signal(SIGHUP, onsig);
+ (void)signal(SIGINT, onsig);
+ (void)signal(SIGQUIT, onsig);
+ (void)signal(SIGSTOP, onsig);
+ (void)signal(SIGTSTP, onsig);
+ (void)signal(SIGTERM, onsig);
+#ifdef USG
+ ioctl(1, TCGETA, &old_tty); /* save tty bits for exit */
+ ioctl(1, TCGETA, &sg);
+ sg.c_iflag &= ~ICRNL;
+ sg.c_oflag &= ~ONLCR;
+ sg.c_lflag &= ~ECHO;
+ ioctl(1, TCSETAW, &sg);
+#else
+ gtty(1, &old_tty); /* save tty bits for exit */
+ gtty(1, &sg);
+ sg.sg_flags &= ~(CRMOD|ECHO);
+ stty(1, &sg);
+#endif
+ if (TI)
+ tputs(TI, 1, fputchar);
+ tputs(tgetstr("cl", &tcp), 1, fputchar);
+ (void)fflush(stdout);
+ for (j = 4; j >= 0; --j) {
+ xpos[j] = random() % cols + 2;
+ ypos[j] = random() % lines + 2;
+ }
+ for (j = 0;;) {
+ x = random() % cols + 2;
+ y = random() % lines + 2;
+ cursor(x, y);
+ fputchar('.');
+ cursor(xpos[j], ypos[j]);
+ fputchar('o');
+ if (!j--)
+ j = 4;
+ cursor(xpos[j], ypos[j]);
+ fputchar('O');
+ if (!j--)
+ j = 4;
+ cursor(xpos[j], ypos[j] - 1);
+ fputchar('-');
+ tputs(DN, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ fputs("|.|", stdout);
+ tputs(DN, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ fputchar('-');
+ if (!j--)
+ j = 4;
+ cursor(xpos[j], ypos[j] - 2);
+ fputchar('-');
+ tputs(DN, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ fputs("/ \\", stdout);
+ cursor(xpos[j] - 2, ypos[j]);
+ fputs("| O |", stdout);
+ cursor(xpos[j] - 1, ypos[j] + 1);
+ fputs("\\ /", stdout);
+ tputs(DN, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ fputchar('-');
+ if (!j--)
+ j = 4;
+ cursor(xpos[j], ypos[j] - 2);
+ fputchar(' ');
+ tputs(DN, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ fputchar(' ');
+ tputs(ND, 1, fputchar);
+ fputchar(' ');
+ cursor(xpos[j] - 2, ypos[j]);
+ fputchar(' ');
+ tputs(ND, 1, fputchar);
+ fputchar(' ');
+ tputs(ND, 1, fputchar);
+ fputchar(' ');
+ cursor(xpos[j] - 1, ypos[j] + 1);
+ fputchar(' ');
+ tputs(ND, 1, fputchar);
+ fputchar(' ');
+ tputs(DN, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ tputs(BC, 1, fputchar);
+ fputchar(' ');
+ xpos[j] = x;
+ ypos[j] = y;
+ (void)fflush(stdout);
+ }
+}
+
+static void
+onsig()
+{
+ tputs(LL, 1, fputchar);
+ if (TE)
+ tputs(TE, 1, fputchar);
+ (void)fflush(stdout);
+#ifdef USG
+ ioctl(1, TCSETAW, &old_tty);
+#else
+ stty(1, &old_tty);
+#endif
+ exit(0);
+}
+
+static
+fputchar(c)
+ char c;
+{
+ putchar(c);
+}
diff --git a/robots/Makefile b/robots/Makefile
new file mode 100644
index 00000000..264b77b3
--- /dev/null
+++ b/robots/Makefile
@@ -0,0 +1,16 @@
+# @(#)Makefile 5.10 (Berkeley) 5/11/90
+
+PROG= robots
+CFLAGS+=-DMAX_PER_UID=5
+SRCS= extern.c init_field.c main.c make_level.c move.c move_robs.c \
+ play_level.c query.c rnd_pos.c score.c flush_in.c
+MAN6= robots.0
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermlib -lcompat
+HIDEGAME=hidegame
+
+beforeinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 600 /dev/null \
+ ${DESTDIR}/var/games/robots_roll
+
+.include <bsd.prog.mk>
diff --git a/robots/extern.c b/robots/extern.c
new file mode 100644
index 00000000..86d2f757
--- /dev/null
+++ b/robots/extern.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)extern.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+
+bool Dead; /* Player is now dead */
+bool Full_clear = TRUE; /* Lots of junk for init_field to clear */
+bool Jump = FALSE; /* Jump while running, counting, or waiting */
+bool Newscore; /* There was a new score added */
+#ifdef FANCY
+bool Pattern_roll = FALSE; /* Auto play for YHBJNLUK pattern */
+#endif
+bool Real_time = FALSE; /* Play in real time? */
+bool Running = FALSE; /* Currently in the middle of a run */
+#ifdef FANCY
+bool Stand_still = FALSE; /* Auto play for standing still pattern */
+#endif
+bool Teleport = FALSE; /* Teleport automatically when player must */
+bool Waiting; /* Player is waiting for end */
+bool Was_bonus = FALSE; /* Was a bonus last level */
+
+char Cnt_move; /* Command which has preceded the count */
+char Field[Y_FIELDSIZE][X_FIELDSIZE]; /* the playing field itslef */
+char *Next_move; /* Next move to be used in the pattern */
+char *Move_list = "YHBJNLUK";/* List of moves in the pattern */
+char Run_ch; /* Character for the direction we are running */
+
+int Count = 0; /* Command count */
+int Level; /* Current level */
+int Num_robots; /* Number of robots left */
+int Num_scores; /* Number of scores posted */
+int Score; /* Current score */
+int Start_level = 1; /* Level on which to start */
+int Wait_bonus; /* bonus for waiting */
+
+COORD Max; /* Max area robots take up */
+COORD Min; /* Min area robots take up */
+COORD My_pos; /* Player's current position */
+COORD Robots[MAXROBOTS]; /* Robots' current positions */
+
+jmp_buf End_move; /* Jump to on Real_time */
diff --git a/robots/flush_in.c b/robots/flush_in.c
new file mode 100644
index 00000000..13db1e7b
--- /dev/null
+++ b/robots/flush_in.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)flush_in.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <curses.h>
+
+/*
+ * flush_in:
+ * Flush all pending input.
+ */
+flush_in()
+{
+# ifdef TIOCFLUSH
+ ioctl(fileno(stdin), TIOCFLUSH, NULL);
+# else TIOCFLUSH
+ crmode();
+# endif TIOCFLUSH
+}
diff --git a/robots/init_field.c b/robots/init_field.c
new file mode 100644
index 00000000..7fa5c0da
--- /dev/null
+++ b/robots/init_field.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init_field.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+
+/*
+ * init_field:
+ * Lay down the initial pattern whih is constant across all levels,
+ * and initialize all the global variables.
+ */
+init_field()
+{
+ register int i;
+ register WINDOW *wp;
+ register int j;
+ static bool first = TRUE;
+ static char *desc[] = {
+ "Directions:",
+ "",
+ "y k u",
+ " \\|/",
+ "h- -l",
+ " /|\\",
+ "b j n",
+ "",
+ "Commands:",
+ "",
+ "w: wait for end",
+ "t: teleport",
+ "q: quit",
+ "^L: redraw screen",
+ "",
+ "Legend:",
+ "",
+ "+: robot",
+ "*: junk heap",
+ "@: you",
+ "",
+ "Score: 0",
+ NULL
+ };
+
+ Dead = FALSE;
+ Waiting = FALSE;
+ flushok(stdscr, TRUE);
+ Score = 0;
+
+ erase();
+ move(0, 0);
+ addch('+');
+ for (i = 1; i < Y_FIELDSIZE; i++) {
+ move(i, 0);
+ addch('|');
+ }
+ move(Y_FIELDSIZE, 0);
+ addch('+');
+ for (i = 1; i < X_FIELDSIZE; i++)
+ addch('-');
+ addch('+');
+ if (first)
+ refresh();
+ move(0, 1);
+ for (i = 1; i < X_FIELDSIZE; i++)
+ addch('-');
+ addch('+');
+ for (i = 1; i < Y_FIELDSIZE; i++) {
+ move(i, X_FIELDSIZE);
+ addch('|');
+ }
+ if (first)
+ refresh();
+ for (i = 0; desc[i] != NULL; i++) {
+ move(i, X_FIELDSIZE + 2);
+ addstr(desc[i]);
+ }
+ if (first)
+ refresh();
+ first = FALSE;
+#ifdef FANCY
+ if (Pattern_roll)
+ Next_move = &Move_list[-1];
+#endif
+}
diff --git a/robots/main.c b/robots/main.c
new file mode 100644
index 00000000..d30928b7
--- /dev/null
+++ b/robots/main.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include "robots.h"
+# include <signal.h>
+# include <ctype.h>
+
+main(ac, av)
+int ac;
+char **av;
+{
+ register char *sp;
+ register bool bad_arg;
+ register bool show_only;
+ extern char *Scorefile;
+ extern int Max_per_uid;
+ void quit();
+
+ show_only = FALSE;
+ if (ac > 1) {
+ bad_arg = FALSE;
+ for (++av; ac > 1 && *av[0]; av++, ac--)
+ if (av[0][0] != '-')
+ if (isdigit(av[0][0]))
+ Max_per_uid = atoi(av[0]);
+ else {
+ setuid(getuid());
+ setgid(getgid());
+ Scorefile = av[0];
+# ifdef FANCY
+ sp = rindex(Scorefile, '/');
+ if (sp == NULL)
+ sp = Scorefile;
+ if (strcmp(sp, "pattern_roll") == 0)
+ Pattern_roll = TRUE;
+ else if (strcmp(sp, "stand_still") == 0)
+ Stand_still = TRUE;
+ if (Pattern_roll || Stand_still)
+ Teleport = TRUE;
+# endif
+ }
+ else
+ for (sp = &av[0][1]; *sp; sp++)
+ switch (*sp) {
+ case 's':
+ show_only = TRUE;
+ break;
+ case 'r':
+ Real_time = TRUE;
+ break;
+ case 'a':
+ Start_level = 4;
+ break;
+ case 'j':
+ Jump = TRUE;
+ break;
+ case 't':
+ Teleport = TRUE;
+ break;
+ default:
+ fprintf(stderr, "robots: uknown option: %c\n", *sp);
+ bad_arg = TRUE;
+ break;
+ }
+ if (bad_arg) {
+ exit(1);
+ /* NOTREACHED */
+ }
+ }
+
+ if (show_only) {
+ show_score();
+ exit(0);
+ /* NOTREACHED */
+ }
+
+ initscr();
+ signal(SIGINT, quit);
+ crmode();
+ noecho();
+ nonl();
+ if (LINES != Y_SIZE || COLS != X_SIZE) {
+ if (LINES < Y_SIZE || COLS < X_SIZE) {
+ endwin();
+ printf("Need at least a %dx%d screen\n",
+ Y_SIZE, X_SIZE);
+ exit(1);
+ }
+ delwin(stdscr);
+ stdscr = newwin(Y_SIZE, X_SIZE, 0, 0);
+ }
+
+ srand(getpid());
+ if (Real_time)
+ signal(SIGALRM, move_robots);
+ do {
+ init_field();
+ for (Level = Start_level; !Dead; Level++) {
+ make_level();
+ play_level();
+ }
+ move(My_pos.y, My_pos.x);
+ printw("AARRrrgghhhh....");
+ refresh();
+ score();
+ } while (another());
+ quit();
+}
+
+/*
+ * quit:
+ * Leave the program elegantly.
+ */
+void
+quit()
+{
+ extern int _putchar();
+
+ mvcur(0, COLS - 1, LINES - 1, 0);
+ if (CE) {
+ tputs(CE, 1, _putchar);
+ endwin();
+ }
+ else {
+ endwin();
+ putchar('\n');
+ }
+ exit(0);
+ /* NOTREACHED */
+}
+
+/*
+ * another:
+ * See if another game is desired
+ */
+another()
+{
+ register int y;
+
+#ifdef FANCY
+ if ((Stand_still || Pattern_roll) && !Newscore)
+ return TRUE;
+#endif
+
+ if (query("Another game?")) {
+ if (Full_clear) {
+ for (y = 1; y <= Num_scores; y++) {
+ move(y, 1);
+ clrtoeol();
+ }
+ refresh();
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/robots/make_level.c b/robots/make_level.c
new file mode 100644
index 00000000..422a7fc2
--- /dev/null
+++ b/robots/make_level.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)make_level.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+
+/*
+ * make_level:
+ * Make the current level
+ */
+make_level()
+{
+ register int i;
+ register COORD *cp;
+ register WINDOW *wp;
+ register int x, *endp;
+
+ reset_count();
+ for (i = 1; i < Y_FIELDSIZE; i++)
+ for (x = 1; x < X_FIELDSIZE; x++)
+ if (Field[i][x] != 0)
+ mvaddch(i, x, ' ');
+ if (My_pos.y > 0)
+ mvaddch(My_pos.y, My_pos.x, ' ');
+
+ Waiting = FALSE;
+ Wait_bonus = 0;
+ leaveok(stdscr, FALSE);
+ for (cp = Robots; cp < &Robots[MAXROBOTS]; cp++)
+ cp->y = -1;
+ My_pos.y = -1;
+
+ bzero(Field, sizeof Field);
+ Min.y = Y_FIELDSIZE;
+ Min.x = X_FIELDSIZE;
+ Max.y = 0;
+ Max.x = 0;
+ if ((i = Level * 10) > MAXROBOTS)
+ i = MAXROBOTS;
+ Num_robots = i;
+ while (i-- > 0) {
+ cp = rnd_pos();
+ Robots[i] = *cp;
+ Field[cp->y][cp->x]++;
+ if (cp->y < Min.y)
+ Min.y = cp->y;
+ if (cp->x < Min.x)
+ Min.x = cp->x;
+ if (cp->y > Max.y)
+ Max.y = cp->y;
+ if (cp->x > Max.x)
+ Max.x = cp->x;
+ }
+ My_pos = *rnd_pos();
+ refresh();
+}
diff --git a/robots/move.c b/robots/move.c
new file mode 100644
index 00000000..79364440
--- /dev/null
+++ b/robots/move.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)move.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+# include <ctype.h>
+
+# define ESC '\033'
+
+/*
+ * get_move:
+ * Get and execute a move from the player
+ */
+get_move()
+{
+ register int c;
+ register int y, x, lastmove;
+ static COORD newpos;
+
+ if (Waiting)
+ return;
+
+#ifdef FANCY
+ if (Pattern_roll) {
+ if (Next_move >= Move_list)
+ lastmove = *Next_move;
+ else
+ lastmove = -1; /* flag for "first time in" */
+ }
+#endif
+ for (;;) {
+ if (Teleport && must_telep())
+ goto teleport;
+ if (Running)
+ c = Run_ch;
+ else if (Count != 0)
+ c = Cnt_move;
+#ifdef FANCY
+ else if (Num_robots > 1 && Stand_still)
+ c = '>';
+ else if (Num_robots > 1 && Pattern_roll) {
+ if (*++Next_move == '\0') {
+ if (lastmove < 0)
+ goto over;
+ Next_move = Move_list;
+ }
+ c = *Next_move;
+ mvaddch(0, 0, c);
+ if (c == lastmove)
+ goto over;
+ }
+#endif
+ else {
+over:
+ c = getchar();
+ if (isdigit(c)) {
+ Count = (c - '0');
+ while (isdigit(c = getchar()))
+ Count = Count * 10 + (c - '0');
+ if (c == ESC)
+ goto over;
+ Cnt_move = c;
+ if (Count)
+ leaveok(stdscr, TRUE);
+ }
+ }
+
+ switch (c) {
+ case ' ':
+ case '.':
+ if (do_move(0, 0))
+ goto ret;
+ break;
+ case 'y':
+ if (do_move(-1, -1))
+ goto ret;
+ break;
+ case 'k':
+ if (do_move(-1, 0))
+ goto ret;
+ break;
+ case 'u':
+ if (do_move(-1, 1))
+ goto ret;
+ break;
+ case 'h':
+ if (do_move(0, -1))
+ goto ret;
+ break;
+ case 'l':
+ if (do_move(0, 1))
+ goto ret;
+ break;
+ case 'b':
+ if (do_move(1, -1))
+ goto ret;
+ break;
+ case 'j':
+ if (do_move(1, 0))
+ goto ret;
+ break;
+ case 'n':
+ if (do_move(1, 1))
+ goto ret;
+ break;
+ case 'Y': case 'U': case 'H': case 'J':
+ case 'K': case 'L': case 'B': case 'N':
+ case '>':
+ Running = TRUE;
+ if (c == '>')
+ Run_ch = ' ';
+ else
+ Run_ch = tolower(c);
+ leaveok(stdscr, TRUE);
+ break;
+ case 'q':
+ case 'Q':
+ if (query("Really quit?"))
+ quit();
+ refresh();
+ break;
+ case 'w':
+ case 'W':
+ Waiting = TRUE;
+ leaveok(stdscr, TRUE);
+ flushok(stdscr, FALSE);
+ goto ret;
+ case 't':
+ case 'T':
+teleport:
+ Running = FALSE;
+ mvaddch(My_pos.y, My_pos.x, ' ');
+ My_pos = *rnd_pos();
+ mvaddch(My_pos.y, My_pos.x, PLAYER);
+ leaveok(stdscr, FALSE);
+ refresh();
+ flush_in();
+ goto ret;
+ case CTRL(L):
+ wrefresh(curscr);
+ break;
+ case EOF:
+ break;
+ default:
+ putchar(CTRL(G));
+ reset_count();
+ fflush(stdout);
+ break;
+ }
+ }
+ret:
+ if (Count > 0)
+ if (--Count == 0)
+ leaveok(stdscr, FALSE);
+}
+
+/*
+ * must_telep:
+ * Must I teleport; i.e., is there anywhere I can move without
+ * being eaten?
+ */
+must_telep()
+{
+ register int x, y;
+ static COORD newpos;
+
+#ifdef FANCY
+ if (Stand_still && Num_robots > 1 && eaten(&My_pos))
+ return TRUE;
+#endif
+
+ for (y = -1; y <= 1; y++) {
+ newpos.y = My_pos.y + y;
+ if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE)
+ continue;
+ for (x = -1; x <= 1; x++) {
+ newpos.x = My_pos.x + x;
+ if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE)
+ continue;
+ if (Field[newpos.y][newpos.x] > 0)
+ continue;
+ if (!eaten(&newpos))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * do_move:
+ * Execute a move
+ */
+do_move(dy, dx)
+int dy, dx;
+{
+ static COORD newpos;
+
+ newpos.y = My_pos.y + dy;
+ newpos.x = My_pos.x + dx;
+ if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE ||
+ newpos.x <= 0 || newpos.x >= X_FIELDSIZE ||
+ Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) {
+ if (Running) {
+ Running = FALSE;
+ leaveok(stdscr, FALSE);
+ move(My_pos.y, My_pos.x);
+ refresh();
+ }
+ else {
+ putchar(CTRL(G));
+ reset_count();
+ }
+ return FALSE;
+ }
+ else if (dy == 0 && dx == 0)
+ return TRUE;
+ mvaddch(My_pos.y, My_pos.x, ' ');
+ My_pos = newpos;
+ mvaddch(My_pos.y, My_pos.x, PLAYER);
+ if (!jumping())
+ refresh();
+ return TRUE;
+}
+
+/*
+ * eaten:
+ * Player would get eaten at this place
+ */
+eaten(pos)
+register COORD *pos;
+{
+ register int x, y;
+
+ for (y = pos->y - 1; y <= pos->y + 1; y++) {
+ if (y <= 0 || y >= Y_FIELDSIZE)
+ continue;
+ for (x = pos->x - 1; x <= pos->x + 1; x++) {
+ if (x <= 0 || x >= X_FIELDSIZE)
+ continue;
+ if (Field[y][x] == 1)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * reset_count:
+ * Reset the count variables
+ */
+reset_count()
+{
+ Count = 0;
+ Running = FALSE;
+ leaveok(stdscr, FALSE);
+ refresh();
+}
+
+/*
+ * jumping:
+ * See if we are jumping, i.e., we should not refresh.
+ */
+jumping()
+{
+ return (Jump && (Count || Running || Waiting));
+}
diff --git a/robots/move_robs.c b/robots/move_robs.c
new file mode 100644
index 00000000..4eaa5b52
--- /dev/null
+++ b/robots/move_robs.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)move_robs.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include "robots.h"
+# include <signal.h>
+
+/*
+ * move_robots:
+ * Move the robots around
+ */
+void
+move_robots(was_sig)
+bool was_sig;
+{
+ register COORD *rp;
+ register int y, x;
+ register int mindist, d;
+ static COORD newpos;
+
+ if (Real_time)
+ signal(SIGALRM, move_robots);
+# ifdef DEBUG
+ move(Min.y, Min.x);
+ addch(inch());
+ move(Max.y, Max.x);
+ addch(inch());
+# endif DEBUG
+ for (rp = Robots; rp < &Robots[MAXROBOTS]; rp++) {
+ if (rp->y < 0)
+ continue;
+ mvaddch(rp->y, rp->x, ' ');
+ Field[rp->y][rp->x]--;
+ rp->y += sign(My_pos.y - rp->y);
+ rp->x += sign(My_pos.x - rp->x);
+ if (rp->y <= 0)
+ rp->y = 0;
+ else if (rp->y >= Y_FIELDSIZE)
+ rp->y = Y_FIELDSIZE - 1;
+ if (rp->x <= 0)
+ rp->x = 0;
+ else if (rp->x >= X_FIELDSIZE)
+ rp->x = X_FIELDSIZE - 1;
+ Field[rp->y][rp->x]++;
+ }
+
+ Min.y = Y_FIELDSIZE;
+ Min.x = X_FIELDSIZE;
+ Max.y = 0;
+ Max.x = 0;
+ for (rp = Robots; rp < &Robots[MAXROBOTS]; rp++)
+ if (rp->y < 0)
+ continue;
+ else if (rp->y == My_pos.y && rp->x == My_pos.x)
+ Dead = TRUE;
+ else if (Field[rp->y][rp->x] > 1) {
+ mvaddch(rp->y, rp->x, HEAP);
+ rp->y = -1;
+ Num_robots--;
+ if (Waiting)
+ Wait_bonus++;
+ add_score(ROB_SCORE);
+ }
+ else {
+ mvaddch(rp->y, rp->x, ROBOT);
+ if (rp->y < Min.y)
+ Min.y = rp->y;
+ if (rp->x < Min.x)
+ Min.x = rp->x;
+ if (rp->y > Max.y)
+ Max.y = rp->y;
+ if (rp->x > Max.x)
+ Max.x = rp->x;
+ }
+
+ if (was_sig) {
+ refresh();
+ if (Dead || Num_robots <= 0)
+ longjmp(End_move, 0);
+ }
+
+# ifdef DEBUG
+ standout();
+ move(Min.y, Min.x);
+ addch(inch());
+ move(Max.y, Max.x);
+ addch(inch());
+ standend();
+# endif DEBUG
+ if (Real_time)
+ alarm(3);
+}
+
+/*
+ * add_score:
+ * Add a score to the overall point total
+ */
+add_score(add)
+int add;
+{
+ Score += add;
+ move(Y_SCORE, X_SCORE);
+ printw("%d", Score);
+}
+
+/*
+ * sign:
+ * Return the sign of the number
+ */
+sign(n)
+int n;
+{
+ if (n < 0)
+ return -1;
+ else if (n > 0)
+ return 1;
+ else
+ return 0;
+}
diff --git a/robots/pathnames.h b/robots/pathnames.h
new file mode 100644
index 00000000..ec0784bd
--- /dev/null
+++ b/robots/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 5/2/90
+ */
+
+#define _PATH_SCORE "/var/games/robots_roll"
diff --git a/robots/play_level.c b/robots/play_level.c
new file mode 100644
index 00000000..887560ad
--- /dev/null
+++ b/robots/play_level.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)play_level.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+
+/*
+ * play_level:
+ * Let the player play the current level
+ */
+play_level()
+{
+ register COORD *cp;
+ register int y, x, bonus;
+
+ move(My_pos.y, My_pos.x);
+ addch(PLAYER);
+ refresh();
+ for (cp = Robots; cp < &Robots[MAXROBOTS]; cp++) {
+ if (cp->y < 0)
+ continue;
+ move(cp->y, cp->x);
+ addch(ROBOT);
+ }
+ refresh();
+# ifdef DEBUG
+ standout();
+ move(Min.y, Min.x);
+ addch(inch());
+ move(Max.y, Max.x);
+ addch(inch());
+ standend();
+# endif DEBUG
+ setjmp(End_move);
+ flush_in();
+ while (!Dead && Num_robots > 0) {
+ move(My_pos.y, My_pos.x);
+ if (!jumping())
+ refresh();
+ get_move();
+ if (Real_time)
+ alarm(0);
+ if (Field[My_pos.y][My_pos.x] != 0)
+ Dead = TRUE;
+ if (!Dead)
+ move_robots(FALSE);
+ if (Was_bonus) {
+ move(Y_PROMPT, X_PROMPT);
+ clrtoeol();
+ move(Y_PROMPT + 1, X_PROMPT);
+ clrtoeol();
+ Was_bonus = FALSE;
+ }
+ }
+
+ /*
+ * if the player didn't die, add on the possible bonuses
+ */
+
+ if (!Dead) {
+ Was_bonus = FALSE;
+
+ if (Level == Start_level && Start_level > 1) {
+ move(Y_PROMPT, X_PROMPT);
+ printw("Advance bonus: %d", S_BONUS);
+ refresh();
+ add_score(S_BONUS);
+ Was_bonus = TRUE;
+ }
+
+ if (Wait_bonus != 0) {
+ if (!Was_bonus)
+ move(Y_PROMPT, X_PROMPT);
+ else
+ move(Y_PROMPT + 1, X_PROMPT);
+ printw("Wait bonus: %d", Wait_bonus);
+ refresh();
+ add_score(Wait_bonus);
+ Was_bonus = TRUE;
+ }
+ }
+}
diff --git a/robots/query.c b/robots/query.c
new file mode 100644
index 00000000..fecf608c
--- /dev/null
+++ b/robots/query.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)query.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+
+/*
+ * query:
+ * Ask a question and get a yes or no answer. Default is "no".
+ */
+query(prompt)
+char *prompt;
+{
+ register int c, retval;
+ register int y, x;
+
+ getyx(stdscr, y, x);
+ move(Y_PROMPT, X_PROMPT);
+ addstr(prompt);
+ clrtoeol();
+ refresh();
+ retval = ((c = getchar()) == 'y' || c == 'Y');
+ move(Y_PROMPT, X_PROMPT);
+ clrtoeol();
+ move(y, x);
+ return retval;
+}
diff --git a/robots/rnd_pos.c b/robots/rnd_pos.c
new file mode 100644
index 00000000..0e49ff50
--- /dev/null
+++ b/robots/rnd_pos.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)rnd_pos.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+
+# define IS_SAME(p,y,x) ((p).y != -1 && (p).y == y && (p).x == x)
+
+/*
+ * rnd_pos:
+ * Pick a random, unoccupied position
+ */
+COORD *
+rnd_pos()
+{
+ static COORD pos;
+ static int call = 0;
+ register int i = 0;
+
+ do {
+ pos.y = rnd(Y_FIELDSIZE - 1) + 1;
+ pos.x = rnd(X_FIELDSIZE - 1) + 1;
+ refresh();
+ } while (Field[pos.y][pos.x] != 0);
+ call++;
+ return &pos;
+}
+
+rnd(range)
+int range;
+{
+ unsigned int rand();
+
+ return rand() % range;
+}
diff --git a/robots/robots.6 b/robots/robots.6
new file mode 100644
index 00000000..0f76c952
--- /dev/null
+++ b/robots/robots.6
@@ -0,0 +1,141 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)robots.6 6.2 (Berkeley) 4/8/91
+.\"
+.TH ROBOTS 6 "April 8, 1991"
+.UC 6
+.SH NAME
+robots \- fight off villainous robots
+.SH SYNOPSIS
+.B robots
+[
+.B \-sjta
+] [
+.B scorefile
+]
+.SH DESCRIPTION
+.I Robots
+pits you against evil robots, who are trying to kill you (which is why
+they are evil).
+Fortunately for you, even though they are evil, they are not very bright
+and have a habit of bumping into each other, thus destroying themselves.
+In order to survive, you must get them to kill each other off, since you
+have no offensive weaponry.
+.PP
+Since you are stuck without offensive weaponry, you are endowed with one
+piece of defensive weaponry: a teleportation device.
+When two robots run into each other or a junk pile, they die.
+If a robot runs into you, you die.
+When a robot dies, you get 10 points, and when all the robots die,
+you start on the next field.
+This keeps up until they finally get you.
+.PP
+Robots are represented on the screen by a
+.RB ` + ',
+the junk heaps from their collisions by a
+.RB ` \(** ',
+and you
+(the good guy)
+by a
+.RB ` @ '.
+.PP
+The commands are:
+.sp
+.nf
+.ta
+.ta \w'\fBHJKLBNYU\fP\ \ 'u
+\fBh\fP move one square left
+\fBl\fP move one square right
+\fBk\fP move one square up
+\fBj\fP move one square down
+\fBy\fP move one square up and left
+\fBu\fP move one square up and right
+\fBb\fP move one square down and left
+\fBn\fP move one square down and right
+\fB\&.\fP (also space) do nothing for one turn
+\fBHJKLBNYU\fP run as far as possible in the given direction
+\fB>\fP do nothing for as long as possible
+\fBt\fP teleport to a random location
+\fBw\fP wait until you die or they all do
+\fBq\fP quit
+\fB^L\fP redraw the screen
+.sp
+.fi
+All commands can be preceded by a count.
+.PP
+If you use the
+.RB ` w '
+command and survive to the next level, you will get a bonus of 10%
+for each robot which died after you decided to wait.
+If you die, however, you get nothing.
+For all other commands, the program will save you from typos
+by stopping short of being eaten.
+However, with
+.RB ` w '
+you take the risk of dying by miscalculation.
+.PP
+Only five scores are allowed per user on the score file.
+If you make it into the score file, you will be shown the list at the end
+of the game.
+If an alternate score file is specified, that will be used instead of the
+standard file for scores.
+.PP
+The options are
+.TP
+.B \-s
+Don't play, just show the score file.
+.TP
+.B \-j
+Jump,
+.IR i.e. ,
+when you run, don't show any intermediate positions; only show things at
+the end.
+This is useful on slow terminals.
+.TP
+.B \-t
+Teleport automatically when you have no other option.
+This is a little disconcerting until you get used to it, and then it is
+very nice.
+.TP
+.B \-a
+Advance into the higher levels directly, skipping the lower, easier levels.
+.SH AUTHOR
+Ken Arnold
+.SH FILES
+.ta
+.ta \w'/usr/games/lib/robots_roll\ \ \ \ 'u
+/usr/games/lib/robots_roll the score file
+.SH BUGS
+Bugs?
+You
+.IR crazy ,
+man?!?
diff --git a/robots/robots.h b/robots/robots.h
new file mode 100644
index 00000000..cafea703
--- /dev/null
+++ b/robots/robots.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)robots.h 5.6 (Berkeley) 2/28/91
+ */
+
+# include <curses.h>
+# include <setjmp.h>
+
+/*
+ * miscellaneous constants
+ */
+
+# define Y_FIELDSIZE 23
+# define X_FIELDSIZE 60
+# define Y_SIZE 24
+# define X_SIZE 80
+# define MAXLEVELS 4
+# define MAXROBOTS (MAXLEVELS * 10)
+# define ROB_SCORE 10
+# define S_BONUS (60 * ROB_SCORE)
+# define Y_SCORE 21
+# define X_SCORE (X_FIELDSIZE + 9)
+# define Y_PROMPT (Y_FIELDSIZE - 1)
+# define X_PROMPT (X_FIELDSIZE + 2)
+# define MAXSCORES (Y_SIZE - 2)
+# define MAXNAME 16
+# define MS_NAME "Ten"
+
+/*
+ * characters on screen
+ */
+
+# define ROBOT '+'
+# define HEAP '*'
+# define PLAYER '@'
+
+/*
+ * pseudo functions
+ */
+
+# undef CTRL
+# define CTRL(X) ('X' - 'A' + 1)
+
+/*
+ * type definitions
+ */
+
+typedef struct {
+ int y, x;
+} COORD;
+
+/*
+ * global variables
+ */
+
+extern bool Dead, Full_clear, Jump, Newscore, Real_time, Running,
+ Teleport, Waiting, Was_bonus;
+
+#ifdef FANCY
+extern bool Pattern_roll, Stand_still;
+#endif
+
+extern char Cnt_move, Field[Y_FIELDSIZE][X_FIELDSIZE], *Next_move,
+ *Move_list, Run_ch;
+
+extern int Count, Level, Num_robots, Num_scores, Score,
+ Start_level, Wait_bonus;
+
+extern COORD Max, Min, My_pos, Robots[];
+
+extern jmp_buf End_move;
+
+/*
+ * functions types
+ */
+
+int cmp_sc();
+void move_robots();
+
+COORD *rnd_pos();
diff --git a/robots/score.c b/robots/score.c
new file mode 100644
index 00000000..fc0fb757
--- /dev/null
+++ b/robots/score.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)score.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "robots.h"
+# include <sys/types.h>
+# include <pwd.h>
+# include "pathnames.h"
+
+typedef struct {
+ int s_uid;
+ int s_score;
+ char s_name[MAXNAME];
+} SCORE;
+
+typedef struct passwd PASSWD;
+
+char *Scorefile = _PATH_SCORE;
+
+int Max_per_uid = MAX_PER_UID;
+
+static SCORE Top[MAXSCORES];
+
+/*
+ * score:
+ * Post the player's score, if reasonable, and then print out the
+ * top list.
+ */
+score()
+{
+ register int inf;
+ register SCORE *scp;
+ register int uid;
+ register bool done_show = FALSE;
+ static int numscores, max_uid;
+
+ Newscore = FALSE;
+ if ((inf = open(Scorefile, 2)) < 0) {
+ perror(Scorefile);
+ return;
+ }
+
+ if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
+ read(inf, Top, sizeof Top);
+ else {
+ for (scp = Top; scp < &Top[MAXSCORES]; scp++)
+ scp->s_score = -1;
+ max_uid = Max_per_uid;
+ }
+
+ uid = getuid();
+ if (Top[MAXSCORES-1].s_score <= Score) {
+ numscores = 0;
+ for (scp = Top; scp < &Top[MAXSCORES]; scp++)
+ if (scp->s_score < 0 ||
+ (scp->s_uid == uid && ++numscores == max_uid)) {
+ if (scp->s_score > Score)
+ break;
+ scp->s_score = Score;
+ scp->s_uid = uid;
+ set_name(scp);
+ Newscore = TRUE;
+ break;
+ }
+ if (scp == &Top[MAXSCORES]) {
+ Top[MAXSCORES-1].s_score = Score;
+ Top[MAXSCORES-1].s_uid = uid;
+ set_name(&Top[MAXSCORES-1]);
+ Newscore = TRUE;
+ }
+ if (Newscore)
+ qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
+ }
+
+ if (!Newscore) {
+ Full_clear = FALSE;
+ close(inf);
+ return;
+ }
+ else
+ Full_clear = TRUE;
+
+ for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
+ if (scp->s_score < 0)
+ break;
+ move((scp - Top) + 1, 15);
+ if (!done_show && scp->s_uid == uid && scp->s_score == Score)
+ standout();
+ printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
+ if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
+ standend();
+ done_show = TRUE;
+ }
+ }
+ Num_scores = scp - Top;
+ refresh();
+
+ if (Newscore) {
+ lseek(inf, 0L, 0);
+ write(inf, &max_uid, sizeof max_uid);
+ write(inf, Top, sizeof Top);
+ }
+ close(inf);
+}
+
+set_name(scp)
+register SCORE *scp;
+{
+ register PASSWD *pp;
+
+ if ((pp = getpwuid(scp->s_uid)) == NULL)
+ pp->pw_name = "???";
+ strncpy(scp->s_name, pp->pw_name, MAXNAME);
+}
+
+/*
+ * cmp_sc:
+ * Compare two scores.
+ */
+cmp_sc(s1, s2)
+register SCORE *s1, *s2;
+{
+ return s2->s_score - s1->s_score;
+}
+
+/*
+ * show_score:
+ * Show the score list for the '-s' option.
+ */
+show_score()
+{
+ register SCORE *scp;
+ register int inf;
+ static int max_score;
+
+ if ((inf = open(Scorefile, 0)) < 0) {
+ perror(Scorefile);
+ return;
+ }
+
+ for (scp = Top; scp < &Top[MAXSCORES]; scp++)
+ scp->s_score = -1;
+
+ read(inf, &max_score, sizeof max_score);
+ read(inf, Top, sizeof Top);
+ close(inf);
+ inf = 1;
+ for (scp = Top; scp < &Top[MAXSCORES]; scp++)
+ if (scp->s_score >= 0)
+ printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
+}
diff --git a/rogue/CHANGES b/rogue/CHANGES
new file mode 100644
index 00000000..73a71353
--- /dev/null
+++ b/rogue/CHANGES
@@ -0,0 +1,53 @@
+From: tektronix!zeus.TEK.COM!tims@ucbvax.Berkeley.EDU
+Date: 30 Nov 87 15:08:15 PST (Mon)
+To: okeeffe.Berkeley.EDU!mckusick@ucbvax.Berkeley.EDU (Kirk McKusick)
+Subject: Re: Public domain rogue
+Return-Path: tektronix!zeus.TEK.COM!tims@ucbvax.Berkeley.EDU
+
+Here is a list of discrepencies from the documentation you sent me:
+
+The -d option not implemented.
+The -r option not implemented, use "rogue save_file" instead.
+Strength is between 1 and 99, not 3 and 32.
+The D command is not implemented.
+Only scrolls,potions,wands,and rings may be "call"ed something.
+The ^P command may be used to go 4 messages back, instead of just 1.
+The @ comand is not implemented.
+There are no dark rooms.
+ROGUEOPTS of flush,terse,seefloor,askme,inventory are ignored.
+ 'askquit' is added to prevent ^\ from terminating the game accidentally.
+ If 'noaskquit' is
+ found in the ROGUEOPTS string, the the ^\ kills the game, otherwise,
+ the player is asked if he really wants to quit. In either case, no
+ score file processing is attempted.
+The score is keyed to winning scores, and no player may appear twice.
+
+
+
+
+
+
+Other differences from "standard" rogue 5.3. This list covers externally
+visible differences only.
+
+There should be NO bugs with any severe consequences. Absolutely NO
+ game-stopping, or game-winning bugs should be present.
+Traps fail occasionally, that is, they sometimes are sprung but miss.
+The ^A command prints out some stuff you're probably not interested in.
+The '&' command silently saves your screen into the file 'rogue.screen'
+Any inventory selection command that takes '*' as a request to list all
+ appropriate items, can take one of "=?:)]!/" to list only rings,
+ scrolls, or whatever.
+Scrolls and potions, once used, become identified. All other objects become
+ identified only by scroll of identification.
+There is only one scroll of identification, and it works on any item.
+ROGUEOPTS
+ Only the following are implemented:
+ file,jump,name,askquit,tombstone,passgo
+ "askquit" is used to prevent accidental termination of the game via ^\
+You may drop objects in doorways.
+Prints a picture of a skull, not a tombstone, upon death.
+The save/restore game function is faster and machine-independent, but sometimes
+ requires modification when new variables are added to the source.
+The potion of detect monster lasts for the whole level.
+Their is no wand of light.
diff --git a/rogue/Makefile b/rogue/Makefile
new file mode 100644
index 00000000..312a6115
--- /dev/null
+++ b/rogue/Makefile
@@ -0,0 +1,13 @@
+# @(#)Makefile 5.7 (Berkeley) 5/11/90
+
+PROG= rogue
+CFLAGS+=-DUNIX -DUNIX_BSD4_2 -fwritable-strings
+SRCS= curses.c hit.c init.c inventory.c level.c machdep.c main.c \
+ message.c monster.c move.c object.c pack.c play.c random.c ring.c \
+ room.c save.c score.c spec_hit.c throw.c trap.c use.c zap.c
+DPADD= ${LIBCURSES} ${LIBTERM}
+LDADD= -lcurses -ltermlib
+HIDEGAME=hidegame
+MAN6= rogue.0
+
+.include <bsd.prog.mk>
diff --git a/rogue/curses.c b/rogue/curses.c
new file mode 100644
index 00000000..fc609383
--- /dev/null
+++ b/rogue/curses.c
@@ -0,0 +1,694 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)curses.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * curses.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#ifdef CURSES
+
+/* The following is a curses emulation package suitable for the rogue program
+ * in which it is included. No other suitability is claimed or suspected.
+ * Only those routines currently needed by this rogue program are included.
+ * This is being provided for those systems that don't have a suitable
+ * curses package and want to run this rogue program.
+ *
+ * Compile the entire program with -DCURSES to incorporate this package.
+ *
+ * The following is NOT supported:
+ * "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string.
+ * Terminals in which the cursor motion addresses the row differently from
+ * the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y"
+ * Termcap database stored in the TERMCAP environ variable as returned
+ * from md_getenv(). Only the termcap file name can be stored there.
+ * See the comments for md_getenv() in machdep.c.
+ * Terminals without non-destructive backspace. Backspace (^H) is used
+ * for cursor motion regardless of any termcap entries.
+ * The ":tc=" termcap entry is ignored.
+ *
+ * Suggestions:
+ * Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or
+ * ":do=\n" This will help cursor motion optimization. If line-feed
+ * won't work, then a short escape sequence will do.
+ */
+
+#include <stdio.h>
+#include "rogue.h"
+
+boolean tc_tname();
+
+#define BS 010
+#define LF 012
+#define CR 015
+#define ESC '\033'
+#define TAB '\011'
+
+#define ST_MASK 0x80
+#define BUFLEN 256
+
+char terminal[DROWS][DCOLS];
+char buffer[DROWS][DCOLS];
+char *tc_file;
+
+char cm_esc[16];
+char cm_sep[16];
+char cm_end[16];
+boolean cm_reverse = 0;
+boolean cm_two = 0;
+boolean cm_three = 0;
+boolean cm_char = 0;
+short cm_inc = 0;
+
+boolean screen_dirty;
+boolean lines_dirty[DROWS];
+boolean buf_stand_out = 0;
+boolean term_stand_out = 0;
+
+int LINES = DROWS;
+int COLS = DCOLS;
+WINDOW scr_buf;
+WINDOW *curscr = &scr_buf;
+
+char *CL = (char *) 0;
+char *CM = (char *) 0;
+char *UC = (char *) 0; /* UP */
+char *DO = (char *) 0;
+char *VS = "";
+char *VE = "";
+char *TI = "";
+char *TE = "";
+char *SO = "";
+char *SE = "";
+
+short cur_row;
+short cur_col;
+
+initscr()
+{
+ clear();
+ get_term_info();
+ printf("%s%s", TI, VS);
+}
+
+endwin()
+{
+ printf("%s%s", TE, VE);
+ md_cbreak_no_echo_nonl(0);
+}
+
+move(row, col)
+short row, col;
+{
+ curscr->_cury = row;
+ curscr->_curx = col;
+ screen_dirty = 1;
+}
+
+mvaddstr(row, col, str)
+short row, col;
+char *str;
+{
+ move(row, col);
+ addstr(str);
+}
+
+addstr(str)
+char *str;
+{
+ while (*str) {
+ addch((int) *str++);
+ }
+}
+
+addch(ch)
+register int ch;
+{
+ short row, col;
+
+ row = curscr->_cury;
+ col = curscr->_curx++;
+
+ if (buf_stand_out) {
+ ch |= ST_MASK;
+ }
+ buffer[row][col] = (char) ch;
+ lines_dirty[row] = 1;
+ screen_dirty = 1;
+}
+
+mvaddch(row, col, ch)
+short row, col;
+int ch;
+{
+ move(row, col);
+ addch(ch);
+}
+
+refresh()
+{
+ register i, j, line;
+ short old_row, old_col, first_row;
+
+ if (screen_dirty) {
+
+ old_row = curscr->_cury;
+ old_col = curscr->_curx;
+ first_row = cur_row;
+
+ for (i = 0; i < DROWS; i++) {
+ line = (first_row + i) % DROWS;
+ if (lines_dirty[line]) {
+ for (j = 0; j < DCOLS; j++) {
+ if (buffer[line][j] != terminal[line][j]) {
+ put_char_at(line, j, buffer[line][j]);
+ }
+ }
+ lines_dirty[line] = 0;
+ }
+ }
+ put_cursor(old_row, old_col);
+ screen_dirty = 0;
+ fflush(stdout);
+ }
+}
+
+wrefresh(scr)
+WINDOW *scr;
+{
+ short i, col;
+
+ printf("%s", CL);
+ cur_row = cur_col = 0;
+
+ for (i = 0; i < DROWS; i++) {
+ col = 0;
+ while (col < DCOLS) {
+ while ((col < DCOLS) && (buffer[i][col] == ' ')) {
+ col++;
+ }
+ if (col < DCOLS) {
+ put_cursor(i, col);
+ }
+ while ((col < DCOLS) && (buffer[i][col] != ' ')) {
+ put_st_char((int) buffer[i][col]);
+ cur_col++;
+ col++;
+ }
+ }
+ }
+ put_cursor(curscr->_cury, curscr->_curx);
+ fflush(stdout);
+ scr = scr; /* make lint happy */
+}
+
+mvinch(row, col)
+short row, col;
+{
+ move(row, col);
+ return((int) buffer[row][col]);
+}
+
+clear()
+{
+ printf("%s", CL);
+ fflush(stdout);
+ cur_row = cur_col = 0;
+ move(0, 0);
+ clear_buffers();
+}
+
+clrtoeol()
+{
+ short row, col;
+
+ row = curscr->_cury;
+
+ for (col = curscr->_curx; col < DCOLS; col++) {
+ buffer[row][col] = ' ';
+ }
+ lines_dirty[row] = 1;
+}
+
+standout()
+{
+ buf_stand_out = 1;
+}
+
+standend()
+{
+ buf_stand_out = 0;
+}
+
+crmode()
+{
+ md_cbreak_no_echo_nonl(1);
+}
+
+noecho()
+{
+ /* crmode() takes care of this */
+}
+
+nonl()
+{
+ /* crmode() takes care of this */
+}
+
+clear_buffers()
+{
+ register i, j;
+
+ screen_dirty = 0;
+
+ for (i = 0; i < DROWS; i++) {
+ lines_dirty[i] = 0;
+ for (j = 0; j < DCOLS; j++) {
+ terminal[i][j] = ' ';
+ buffer[i][j] = ' ';
+ }
+ }
+}
+
+put_char_at(row, col, ch)
+register row, col, ch;
+{
+ put_cursor(row, col);
+ put_st_char(ch);
+ terminal[row][col] = (char) ch;
+ cur_col++;
+}
+
+put_cursor(row, col)
+register row, col;
+{
+ register i, rdif, cdif;
+ short ch, t;
+
+ rdif = (row > cur_row) ? row - cur_row : cur_row - row;
+ cdif = (col > cur_col) ? col - cur_col : cur_col - col;
+
+ if (((row > cur_row) && DO) || ((cur_row > row) && UC)) {
+ if ((rdif < 4) && (cdif < 4)) {
+ for (i = 0; i < rdif; i++) {
+ printf("%s", ((row < cur_row) ? UC : DO));
+ }
+ cur_row = row;
+ if (col == cur_col) {
+ return;
+ }
+ }
+ }
+ if (row == cur_row) {
+ if (cdif <= 6) {
+ for (i = 0; i < cdif; i++) {
+ ch = (col < cur_col) ? BS :
+ terminal[row][cur_col + i];
+ put_st_char((int) ch);
+ }
+ cur_row = row;
+ cur_col = col;
+ return;
+ }
+ }
+ cur_row = row;
+ cur_col = col;
+
+ row += cm_inc;
+ col += cm_inc;
+
+ if (cm_reverse) {
+ t = row;
+ row = col;
+ col = t;
+ }
+ if (cm_two) {
+ printf("%s%02d%s%02d%s", cm_esc, row, cm_sep, col, cm_end);
+ } else if (cm_three) {
+ printf("%s%03d%s%03d%s", cm_esc, row, cm_sep, col, cm_end);
+ } else if (cm_char) {
+ printf("%s%c%s%c%s", cm_esc, row, cm_sep, col, cm_end);
+ } else {
+ printf("%s%d%s%d%s", cm_esc, row, cm_sep, col, cm_end);
+ }
+}
+
+put_st_char(ch)
+register ch;
+{
+ if ((ch & ST_MASK) && (!term_stand_out)) {
+ ch &= ~ST_MASK;
+ printf("%s%c", SO, ch);
+ term_stand_out = 1;
+ } else if ((!(ch & ST_MASK)) && term_stand_out) {
+ printf("%s%c", SE, ch);
+ term_stand_out = 0;
+ } else {
+ ch &= ~ST_MASK;
+ putchar(ch);
+ }
+}
+
+get_term_info()
+{
+ FILE *fp;
+ char *term, *tcf;
+ char buf[BUFLEN];
+
+ if (tcf = md_getenv("TERMCAP")) {
+ if (strlen(tcf) > 40) {
+ clean_up("TERMCAP file name too long");
+ }
+ tc_file = tcf;
+ } else {
+ if (!(tc_file = md_gdtcf())) {
+ clean_up("I need a termcap file");
+ }
+ }
+
+ if (!(term = md_getenv("TERM"))) {
+ clean_up("Cannot find TERM variable in environ");
+ }
+ if ((fp = fopen(tc_file, "r")) == NULL) {
+ sprintf(buf, "Cannot open TERMCAP file: %s", tc_file);
+ clean_up(buf);
+ }
+
+ if (!tc_tname(fp, term, buf)) {
+ sprintf(buf, "Cannot find TERM type: %s in TERMCAP file: %s", term,
+ tc_file);
+ clean_up(buf);
+ }
+ tc_gtdata(fp, buf);
+ fclose(fp);
+}
+
+boolean
+tc_tname(fp, term, buf)
+FILE *fp;
+char *term;
+char *buf;
+{
+ short i, j;
+ boolean found = 0;
+ char *fg;
+
+ while (!found) {
+ i = 0;
+ fg = fgets(buf, BUFLEN, fp);
+ if (fg != NULL) {
+ if ( (buf[0] != '#') && (buf[0] != ' ') && (buf[0] != TAB) &&
+ (buf[0] != CR) && (buf[0] != LF)) {
+ while (buf[i] && (!found)) {
+ j = 0;
+ while (buf[i] == term[j]) {
+ i++;
+ j++;
+ }
+ if ((!term[j]) && ((buf[i] == '|') || (buf[i] == ':'))) {
+ found = 1;
+ } else {
+ while (buf[i] && (buf[i] != '|') && (buf[i] != ':')) {
+ i++;
+ }
+ if (buf[i]) {
+ i++;
+ }
+ }
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ return(found);
+}
+
+tc_gtdata(fp, buf)
+FILE *fp;
+char *buf;
+{
+ short i;
+ boolean first = 1;
+
+ do {
+ if (!first) {
+ if ((buf[0] != TAB) && (buf[0] != ' ')) {
+ break;
+ }
+ }
+ first = 0;
+ i = 0;
+ while (buf[i]) {
+ while (buf[i] && (buf[i] != ':')) {
+ i++;
+ }
+ if (buf[i] == ':') {
+ if (!strncmp(buf + i, ":cl=", 4)) {
+ tc_gets(buf + i, &CL);
+ } else if (!strncmp(buf + i, ":cm=", 4)) {
+ tc_gets(buf + i, &CM);
+ } else if (!strncmp(buf + i, ":up=", 4)) {
+ tc_gets(buf + i, &UC);
+ } else if (!strncmp(buf + i, ":do=", 4)) {
+ tc_gets(buf + i, &DO);
+ } else if (!strncmp(buf + i, ":vs=", 4)) {
+ tc_gets(buf + i, &VS);
+ } else if (!strncmp(buf + i, ":ve=", 4)) {
+ tc_gets(buf + i, &VE);
+ } else if (!strncmp(buf + i, ":ti=", 4)) {
+ tc_gets(buf + i, &TI);
+ } else if (!strncmp(buf + i, ":te=", 4)) {
+ tc_gets(buf + i, &TE);
+ } else if (!strncmp(buf + i, ":vs=", 4)) {
+ tc_gets(buf + i, &VS);
+ } else if (!strncmp(buf + i, ":ve=", 4)) {
+ tc_gets(buf + i, &VE);
+ } else if (!strncmp(buf + i, ":so=", 4)) {
+ tc_gets(buf + i, &SO);
+ } else if (!strncmp(buf + i, ":se=", 4)) {
+ tc_gets(buf + i, &SE);
+ } else if (!strncmp(buf + i, ":li#", 4)) {
+ tc_gnum(buf + i, &LINES);
+ } else if (!strncmp(buf + i, ":co#", 4)) {
+ tc_gnum(buf + i, &COLS);
+ }
+ i++;
+ }
+ }
+ } while (fgets(buf, BUFLEN, fp) != NULL);
+
+ if ((!CM) || (!CL)) {
+ clean_up("Terminal and termcap must have cm and cl");
+ }
+ tc_cmget();
+}
+
+tc_gets(ibuf, tcstr)
+char *ibuf;
+char **tcstr;
+{
+ short i, j, k, n;
+ char obuf[BUFLEN];
+
+ i = 4;
+ j = 0;
+
+ while (ibuf[i] && is_digit(ibuf[i])) {
+ i++;
+ }
+
+ while (ibuf[i] && (ibuf[i] != ':')) {
+ if (ibuf[i] == '\\') {
+ i++;
+ switch(ibuf[i]) {
+ case 'E':
+ obuf[j] = ESC;
+ i++;
+ break;
+ case 'n':
+ obuf[j] = LF;
+ i++;
+ break;
+ case 'r':
+ obuf[j] = CR;
+ i++;
+ break;
+ case 'b':
+ obuf[j] = BS;
+ i++;
+ break;
+ case 't':
+ obuf[j] = TAB;
+ i++;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ n = 0;
+ k = 0;
+ while (k < 3 && ibuf[i] && is_digit(ibuf[i])) {
+ n = (8 * n) + (ibuf[i] - '0');
+ i++;
+ k++;
+ }
+ obuf[j] = (char) n;
+ break;
+ default:
+ obuf[j] = ibuf[i];
+ i++;
+ }
+ } else if (ibuf[i] == '^') {
+ obuf[j] = ibuf[i+1] - 64;
+ i += 2;
+ } else {
+ obuf[j] = ibuf[i++];
+ }
+ j++;
+ }
+ obuf[j] = 0;
+ if (!(*tcstr = md_malloc(j + 1))) {
+ clean_up("cannot alloc() memory");
+ }
+ (void) strcpy(*tcstr, obuf);
+}
+
+tc_gnum(ibuf, n)
+char *ibuf;
+int *n;
+{
+ short i;
+ int r = 0;
+
+ i = 4;
+
+ while (is_digit(ibuf[i])) {
+ r = (r * 10) + (ibuf[i] - '0');
+ i++;
+ }
+ *n = r;
+}
+
+tstp()
+{
+ endwin();
+ md_tstp();
+
+ start_window();
+ printf("%s%s", TI, VS);
+ wrefresh(curscr);
+ md_slurp();
+}
+
+tc_cmget()
+{
+ short i = 0, j = 0, rc_spec = 0;
+
+ while (CM[i] && (CM[i] != '%') && (j < 15)) {
+ cm_esc[j++] = CM[i++];
+ }
+ cm_esc[j] = 0;
+
+ while (CM[i] && (rc_spec < 2)) {
+ if (CM[i] == '%') {
+ i++;
+ switch(CM[i]) {
+ case 'd':
+ rc_spec++;
+ break;
+ case 'i':
+ cm_inc = 1;
+ break;
+ case '2':
+ cm_two = 1;
+ rc_spec++;
+ break;
+ case '3':
+ cm_three = 1;
+ rc_spec++;
+ break;
+ case '.':
+ cm_char = 1;
+ rc_spec++;
+ break;
+ case 'r':
+ cm_reverse = 1;
+ break;
+ case '+':
+ i++;
+ cm_inc = CM[i];
+ cm_char = 1;
+ rc_spec++;
+ break;
+ }
+ i++;
+ } else {
+ j = 0;
+ while (CM[i] && (CM[i] != '%')) {
+ cm_sep[j++] = CM[i++];
+ }
+ cm_sep[j] = 0;
+ }
+ }
+
+ j = 0;
+ if (rc_spec == 2) {
+ while (CM[i] && (j < 15)) {
+ cm_end[j++] = CM[i++];
+ }
+ }
+ cm_end[j] = 0;
+}
+
+#endif
diff --git a/rogue/hit.c b/rogue/hit.c
new file mode 100644
index 00000000..b83e6c59
--- /dev/null
+++ b/rogue/hit.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)hit.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * hit.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+object *fight_monster = 0;
+char hit_message[80] = "";
+
+extern short halluc, blind, cur_level;
+extern short add_strength, ring_exp, r_rings;
+extern boolean being_held, interrupted, wizard, con_mon;
+
+mon_hit(monster)
+register object *monster;
+{
+ short damage, hit_chance;
+ char *mn;
+ float minus;
+
+ if (fight_monster && (monster != fight_monster)) {
+ fight_monster = 0;
+ }
+ monster->trow = NO_ROOM;
+ if (cur_level >= (AMULET_LEVEL * 2)) {
+ hit_chance = 100;
+ } else {
+ hit_chance = monster->m_hit_chance;
+ hit_chance -= (((2 * rogue.exp) + (2 * ring_exp)) - r_rings);
+ }
+ if (wizard) {
+ hit_chance /= 2;
+ }
+ if (!fight_monster) {
+ interrupted = 1;
+ }
+ mn = mon_name(monster);
+
+ if (!rand_percent(hit_chance)) {
+ if (!fight_monster) {
+ sprintf(hit_message + strlen(hit_message), "the %s misses", mn);
+ message(hit_message, 1);
+ hit_message[0] = 0;
+ }
+ return;
+ }
+ if (!fight_monster) {
+ sprintf(hit_message + strlen(hit_message), "the %s hit", mn);
+ message(hit_message, 1);
+ hit_message[0] = 0;
+ }
+ if (!(monster->m_flags & STATIONARY)) {
+ damage = get_damage(monster->m_damage, 1);
+ if (cur_level >= (AMULET_LEVEL * 2)) {
+ minus = (float) ((AMULET_LEVEL * 2) - cur_level);
+ } else {
+ minus = (float) get_armor_class(rogue.armor) * 3.00;
+ minus = minus/100.00 * (float) damage;
+ }
+ damage -= (short) minus;
+ } else {
+ damage = monster->stationary_damage++;
+ }
+ if (wizard) {
+ damage /= 3;
+ }
+ if (damage > 0) {
+ rogue_damage(damage, monster, 0);
+ }
+ if (monster->m_flags & SPECIAL_HIT) {
+ special_hit(monster);
+ }
+}
+
+rogue_hit(monster, force_hit)
+register object *monster;
+boolean force_hit;
+{
+ short damage, hit_chance;
+
+ if (monster) {
+ if (check_imitator(monster)) {
+ return;
+ }
+ hit_chance = force_hit ? 100 : get_hit_chance(rogue.weapon);
+
+ if (wizard) {
+ hit_chance *= 2;
+ }
+ if (!rand_percent(hit_chance)) {
+ if (!fight_monster) {
+ (void) strcpy(hit_message, "you miss ");
+ }
+ goto RET;
+ }
+ damage = get_weapon_damage(rogue.weapon);
+ if (wizard) {
+ damage *= 3;
+ }
+ if (con_mon) {
+ s_con_mon(monster);
+ }
+ if (mon_damage(monster, damage)) { /* still alive? */
+ if (!fight_monster) {
+ (void) strcpy(hit_message, "you hit ");
+ }
+ }
+RET: check_gold_seeker(monster);
+ wake_up(monster);
+ }
+}
+
+rogue_damage(d, monster, other)
+short d;
+object *monster;
+short other;
+{
+ if (d >= rogue.hp_current) {
+ rogue.hp_current = 0;
+ print_stats(STAT_HP);
+ killed_by(monster, other);
+ }
+ if (d > 0) {
+ rogue.hp_current -= d;
+ print_stats(STAT_HP);
+ }
+}
+
+get_damage(ds, r)
+char *ds;
+boolean r;
+{
+ register i = 0, j, n, d, total = 0;
+
+ while (ds[i]) {
+ n = get_number(ds+i);
+ while (ds[i++] != 'd') ;
+ d = get_number(ds+i);
+ while ((ds[i] != '/') && ds[i]) i++;
+
+ for (j = 0; j < n; j++) {
+ if (r) {
+ total += get_rand(1, d);
+ } else {
+ total += d;
+ }
+ }
+ if (ds[i] == '/') {
+ i++;
+ }
+ }
+ return(total);
+}
+
+get_w_damage(obj)
+object *obj;
+{
+ char new_damage[12];
+ register to_hit, damage;
+ register i = 0;
+
+ if ((!obj) || (obj->what_is != WEAPON)) {
+ return(-1);
+ }
+ to_hit = get_number(obj->damage) + obj->hit_enchant;
+ while (obj->damage[i++] != 'd') ;
+ damage = get_number(obj->damage + i) + obj->d_enchant;
+
+ sprintf(new_damage, "%dd%d", to_hit, damage);
+
+ return(get_damage(new_damage, 1));
+}
+
+get_number(s)
+register char *s;
+{
+ register i = 0;
+ register total = 0;
+
+ while ((s[i] >= '0') && (s[i] <= '9')) {
+ total = (10 * total) + (s[i] - '0');
+ i++;
+ }
+ return(total);
+}
+
+long
+lget_number(s)
+char *s;
+{
+ short i = 0;
+ long total = 0;
+
+ while ((s[i] >= '0') && (s[i] <= '9')) {
+ total = (10 * total) + (s[i] - '0');
+ i++;
+ }
+ return(total);
+}
+
+to_hit(obj)
+object *obj;
+{
+ if (!obj) {
+ return(1);
+ }
+ return(get_number(obj->damage) + obj->hit_enchant);
+}
+
+damage_for_strength()
+{
+ short strength;
+
+ strength = rogue.str_current + add_strength;
+
+ if (strength <= 6) {
+ return(strength-5);
+ }
+ if (strength <= 14) {
+ return(1);
+ }
+ if (strength <= 17) {
+ return(3);
+ }
+ if (strength <= 18) {
+ return(4);
+ }
+ if (strength <= 20) {
+ return(5);
+ }
+ if (strength <= 21) {
+ return(6);
+ }
+ if (strength <= 30) {
+ return(7);
+ }
+ return(8);
+}
+
+mon_damage(monster, damage)
+object *monster;
+short damage;
+{
+ char *mn;
+ short row, col;
+
+ monster->hp_to_kill -= damage;
+
+ if (monster->hp_to_kill <= 0) {
+ row = monster->row;
+ col = monster->col;
+ dungeon[row][col] &= ~MONSTER;
+ mvaddch(row, col, (int) get_dungeon_char(row, col));
+
+ fight_monster = 0;
+ cough_up(monster);
+ mn = mon_name(monster);
+ sprintf(hit_message+strlen(hit_message), "defeated the %s", mn);
+ message(hit_message, 1);
+ hit_message[0] = 0;
+ add_exp(monster->kill_exp, 1);
+ take_from_pack(monster, &level_monsters);
+
+ if (monster->m_flags & HOLDS) {
+ being_held = 0;
+ }
+ free_object(monster);
+ return(0);
+ }
+ return(1);
+}
+
+fight(to_the_death)
+boolean to_the_death;
+{
+ short ch, c, d;
+ short row, col;
+ boolean first_miss = 1;
+ short possible_damage;
+ object *monster;
+
+ while (!is_direction(ch = rgetchar(), &d)) {
+ sound_bell();
+ if (first_miss) {
+ message("direction?", 0);
+ first_miss = 0;
+ }
+ }
+ check_message();
+ if (ch == CANCEL) {
+ return;
+ }
+ row = rogue.row; col = rogue.col;
+ get_dir_rc(d, &row, &col, 0);
+
+ c = mvinch(row, col);
+ if (((c < 'A') || (c > 'Z')) ||
+ (!can_move(rogue.row, rogue.col, row, col))) {
+ message("I see no monster there", 0);
+ return;
+ }
+ if (!(fight_monster = object_at(&level_monsters, row, col))) {
+ return;
+ }
+ if (!(fight_monster->m_flags & STATIONARY)) {
+ possible_damage = ((get_damage(fight_monster->m_damage, 0) * 2) / 3);
+ } else {
+ possible_damage = fight_monster->stationary_damage - 1;
+ }
+ while (fight_monster) {
+ (void) one_move_rogue(ch, 0);
+ if (((!to_the_death) && (rogue.hp_current <= possible_damage)) ||
+ interrupted || (!(dungeon[row][col] & MONSTER))) {
+ fight_monster = 0;
+ } else {
+ monster = object_at(&level_monsters, row, col);
+ if (monster != fight_monster) {
+ fight_monster = 0;
+ }
+ }
+ }
+}
+
+get_dir_rc(dir, row, col, allow_off_screen)
+short dir;
+short *row, *col;
+short allow_off_screen;
+{
+ switch(dir) {
+ case LEFT:
+ if (allow_off_screen || (*col > 0)) {
+ (*col)--;
+ }
+ break;
+ case DOWN:
+ if (allow_off_screen || (*row < (DROWS-2))) {
+ (*row)++;
+ }
+ break;
+ case UPWARD:
+ if (allow_off_screen || (*row > MIN_ROW)) {
+ (*row)--;
+ }
+ break;
+ case RIGHT:
+ if (allow_off_screen || (*col < (DCOLS-1))) {
+ (*col)++;
+ }
+ break;
+ case UPLEFT:
+ if (allow_off_screen || ((*row > MIN_ROW) && (*col > 0))) {
+ (*row)--;
+ (*col)--;
+ }
+ break;
+ case UPRIGHT:
+ if (allow_off_screen || ((*row > MIN_ROW) && (*col < (DCOLS-1)))) {
+ (*row)--;
+ (*col)++;
+ }
+ break;
+ case DOWNRIGHT:
+ if (allow_off_screen || ((*row < (DROWS-2)) && (*col < (DCOLS-1)))) {
+ (*row)++;
+ (*col)++;
+ }
+ break;
+ case DOWNLEFT:
+ if (allow_off_screen || ((*row < (DROWS-2)) && (*col > 0))) {
+ (*row)++;
+ (*col)--;
+ }
+ break;
+ }
+}
+
+get_hit_chance(weapon)
+object *weapon;
+{
+ short hit_chance;
+
+ hit_chance = 40;
+ hit_chance += 3 * to_hit(weapon);
+ hit_chance += (((2 * rogue.exp) + (2 * ring_exp)) - r_rings);
+ return(hit_chance);
+}
+
+get_weapon_damage(weapon)
+object *weapon;
+{
+ short damage;
+
+ damage = get_w_damage(weapon);
+ damage += damage_for_strength();
+ damage += ((((rogue.exp + ring_exp) - r_rings) + 1) / 2);
+ return(damage);
+}
+
+s_con_mon(monster)
+object *monster;
+{
+ if (con_mon) {
+ monster->m_flags |= CONFUSED;
+ monster->moves_confused += get_rand(12, 22);
+ message("the monster appears confused", 0);
+ con_mon = 0;
+ }
+}
diff --git a/rogue/init.c b/rogue/init.c
new file mode 100644
index 00000000..fe6d9b1b
--- /dev/null
+++ b/rogue/init.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init.c 5.4 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * init.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include <stdio.h>
+#include "rogue.h"
+
+char login_name[MAX_OPT_LEN];
+char *nick_name = (char *) 0;
+char *rest_file = 0;
+boolean cant_int = 0;
+boolean did_int = 0;
+boolean score_only;
+boolean init_curses = 0;
+boolean save_is_interactive = 1;
+boolean ask_quit = 1;
+boolean no_skull = 0;
+boolean passgo = 0;
+char *error_file = "rogue.esave";
+char *byebye_string = "Okay, bye bye!";
+
+extern char *fruit;
+extern char *save_file;
+extern short party_room;
+extern boolean jump;
+
+init(argc, argv)
+int argc;
+char *argv[];
+{
+ char *pn;
+ int seed;
+
+ pn = md_gln();
+ if ((!pn) || (strlen(pn) >= MAX_OPT_LEN)) {
+ clean_up("Hey! Who are you?");
+ }
+ (void) strcpy(login_name, pn);
+
+ do_args(argc, argv);
+ do_opts();
+
+ if (!score_only && !rest_file) {
+ printf("Hello %s, just a moment while I dig the dungeon...",
+ nick_name);
+ fflush(stdout);
+ }
+
+ initscr();
+ if ((LINES < DROWS) || (COLS < DCOLS)) {
+ clean_up("must be played on 24 x 80 screen");
+ }
+ start_window();
+ init_curses = 1;
+
+ md_heed_signals();
+
+ if (score_only) {
+ put_scores((object *) 0, 0);
+ }
+ seed = md_gseed();
+ (void) srrandom(seed);
+ if (rest_file) {
+ restore(rest_file);
+ return(1);
+ }
+ mix_colors();
+ get_wand_and_ring_materials();
+ make_scroll_titles();
+
+ level_objects.next_object = (object *) 0;
+ level_monsters.next_monster = (object *) 0;
+ player_init();
+ ring_stats(0);
+ return(0);
+}
+
+player_init()
+{
+ object *obj;
+
+ rogue.pack.next_object = (object *) 0;
+
+ obj = alloc_object();
+ get_food(obj, 1);
+ (void) add_to_pack(obj, &rogue.pack, 1);
+
+ obj = alloc_object(); /* initial armor */
+ obj->what_is = ARMOR;
+ obj->which_kind = RINGMAIL;
+ obj->class = RINGMAIL+2;
+ obj->is_protected = 0;
+ obj->d_enchant = 1;
+ (void) add_to_pack(obj, &rogue.pack, 1);
+ do_wear(obj);
+
+ obj = alloc_object(); /* initial weapons */
+ obj->what_is = WEAPON;
+ obj->which_kind = MACE;
+ obj->damage = "2d3";
+ obj->hit_enchant = obj->d_enchant = 1;
+ obj->identified = 1;
+ (void) add_to_pack(obj, &rogue.pack, 1);
+ do_wield(obj);
+
+ obj = alloc_object();
+ obj->what_is = WEAPON;
+ obj->which_kind = BOW;
+ obj->damage = "1d2";
+ obj->hit_enchant = 1;
+ obj->d_enchant = 0;
+ obj->identified = 1;
+ (void) add_to_pack(obj, &rogue.pack, 1);
+
+ obj = alloc_object();
+ obj->what_is = WEAPON;
+ obj->which_kind = ARROW;
+ obj->quantity = get_rand(25, 35);
+ obj->damage = "1d2";
+ obj->hit_enchant = 0;
+ obj->d_enchant = 0;
+ obj->identified = 1;
+ (void) add_to_pack(obj, &rogue.pack, 1);
+}
+
+clean_up(estr)
+char *estr;
+{
+ if (save_is_interactive) {
+ if (init_curses) {
+ move(DROWS-1, 0);
+ refresh();
+ stop_window();
+ }
+ printf("\n%s\n", estr);
+ }
+ md_exit(0);
+}
+
+start_window()
+{
+ crmode();
+ noecho();
+#ifndef BAD_NONL
+ nonl();
+#endif
+ md_control_keybord(0);
+}
+
+stop_window()
+{
+ endwin();
+ md_control_keybord(1);
+}
+
+void
+byebye()
+{
+ md_ignore_signals();
+ if (ask_quit) {
+ quit(1);
+ } else {
+ clean_up(byebye_string);
+ }
+ md_heed_signals();
+}
+
+void
+onintr()
+{
+ md_ignore_signals();
+ if (cant_int) {
+ did_int = 1;
+ } else {
+ check_message();
+ message("interrupt", 1);
+ }
+ md_heed_signals();
+}
+
+void
+error_save()
+{
+ save_is_interactive = 0;
+ save_into_file(error_file);
+ clean_up("");
+}
+
+do_args(argc, argv)
+int argc;
+char *argv[];
+{
+ short i, j;
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ for (j = 1; argv[i][j]; j++) {
+ switch(argv[i][j]) {
+ case 's':
+ score_only = 1;
+ break;
+ }
+ }
+ } else {
+ rest_file = argv[i];
+ }
+ }
+}
+
+do_opts()
+{
+ char *eptr;
+
+ if (eptr = md_getenv("ROGUEOPTS")) {
+ for (;;) {
+ while ((*eptr) == ' ') {
+ eptr++;
+ }
+ if (!(*eptr)) {
+ break;
+ }
+ if (!strncmp(eptr, "fruit=", 6)) {
+ eptr += 6;
+ env_get_value(&fruit, eptr, 1);
+ } else if (!strncmp(eptr, "file=", 5)) {
+ eptr += 5;
+ env_get_value(&save_file, eptr, 0);
+ } else if (!strncmp(eptr, "jump", 4)) {
+ jump = 1;
+ } else if (!strncmp(eptr, "name=", 5)) {
+ eptr += 5;
+ env_get_value(&nick_name, eptr, 0);
+ } else if (!strncmp(eptr, "noaskquit", 9)) {
+ ask_quit = 0;
+ } else if (!strncmp(eptr, "noskull", 5) ||
+ !strncmp(eptr,"notomb", 6)) {
+ no_skull = 1;
+ } else if (!strncmp(eptr, "passgo", 5)) {
+ passgo = 1;
+ }
+ while ((*eptr) && (*eptr != ',')) {
+ eptr++;
+ }
+ if (!(*(eptr++))) {
+ break;
+ }
+ }
+ }
+ /* If some strings have not been set through ROGUEOPTS, assign defaults
+ * to them so that the options editor has data to work with.
+ */
+ init_str(&nick_name, login_name);
+ init_str(&save_file, "rogue.save");
+ init_str(&fruit, "slime-mold");
+}
+
+env_get_value(s, e, add_blank)
+char **s, *e;
+boolean add_blank;
+{
+ short i = 0;
+ char *t;
+
+ t = e;
+
+ while ((*e) && (*e != ',')) {
+ if (*e == ':') {
+ *e = ';'; /* ':' reserved for score file purposes */
+ }
+ e++;
+ if (++i >= MAX_OPT_LEN) {
+ break;
+ }
+ }
+ *s = md_malloc(MAX_OPT_LEN + 2);
+ (void) strncpy(*s, t, i);
+ if (add_blank) {
+ (*s)[i++] = ' ';
+ }
+ (*s)[i] = '\0';
+}
+
+init_str(str, dflt)
+char **str, *dflt;
+{
+ if (!(*str)) {
+ *str = md_malloc(MAX_OPT_LEN + 2);
+ (void) strcpy(*str, dflt);
+ }
+}
diff --git a/rogue/inventory.c b/rogue/inventory.c
new file mode 100644
index 00000000..cc06eeb8
--- /dev/null
+++ b/rogue/inventory.c
@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)inventory.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * inventory.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+boolean is_wood[WANDS];
+char *press_space = " --press space to continue--";
+
+char *wand_materials[WAND_MATERIALS] = {
+ "steel ",
+ "bronze ",
+ "gold ",
+ "silver ",
+ "copper ",
+ "nickel ",
+ "cobalt ",
+ "tin ",
+ "iron ",
+ "magnesium ",
+ "chrome ",
+ "carbon ",
+ "platinum ",
+ "silicon ",
+ "titanium ",
+
+ "teak ",
+ "oak ",
+ "cherry ",
+ "birch ",
+ "pine ",
+ "cedar ",
+ "redwood ",
+ "balsa ",
+ "ivory ",
+ "walnut ",
+ "maple ",
+ "mahogany ",
+ "elm ",
+ "palm ",
+ "wooden "
+};
+
+char *gems[GEMS] = {
+ "diamond ",
+ "stibotantalite ",
+ "lapi-lazuli ",
+ "ruby ",
+ "emerald ",
+ "sapphire ",
+ "amethyst ",
+ "quartz ",
+ "tiger-eye ",
+ "opal ",
+ "agate ",
+ "turquoise ",
+ "pearl ",
+ "garnet "
+};
+
+char *syllables[MAXSYLLABLES] = {
+ "blech ",
+ "foo ",
+ "barf ",
+ "rech ",
+ "bar ",
+ "blech ",
+ "quo ",
+ "bloto ",
+ "oh ",
+ "caca ",
+ "blorp ",
+ "erp ",
+ "festr ",
+ "rot ",
+ "slie ",
+ "snorf ",
+ "iky ",
+ "yuky ",
+ "ooze ",
+ "ah ",
+ "bahl ",
+ "zep ",
+ "druhl ",
+ "flem ",
+ "behil ",
+ "arek ",
+ "mep ",
+ "zihr ",
+ "grit ",
+ "kona ",
+ "kini ",
+ "ichi ",
+ "tims ",
+ "ogr ",
+ "oo ",
+ "ighr ",
+ "coph ",
+ "swerr ",
+ "mihln ",
+ "poxi "
+};
+
+#define COMS 48
+
+struct id_com_s {
+ short com_char;
+ char *com_desc;
+};
+
+struct id_com_s com_id_tab[COMS] = {
+ '?', "? prints help",
+ 'r', "r read scroll",
+ '/', "/ identify object",
+ 'e', "e eat food",
+ 'h', "h left ",
+ 'w', "w wield a weapon",
+ 'j', "j down",
+ 'W', "W wear armor",
+ 'k', "k up",
+ 'T', "T take armor off",
+ 'l', "l right",
+ 'P', "P put on ring",
+ 'y', "y up & left",
+ 'R', "R remove ring",
+ 'u', "u up & right",
+ 'd', "d drop object",
+ 'b', "b down & left",
+ 'c', "c call object",
+ 'n', "n down & right",
+ NULL, "<SHIFT><dir>: run that way",
+ ')', ") print current weapon",
+ NULL, "<CTRL><dir>: run till adjacent",
+ ']', "] print current armor",
+ 'f', "f<dir> fight till death or near death",
+ '=', "= print current rings",
+ 't', "t<dir> throw something",
+ '\001', "^A print Hp-raise average",
+ 'm', "m<dir> move onto without picking up",
+ 'z', "z<dir> zap a wand in a direction",
+ 'o', "o examine/set options",
+ '^', "^<dir> identify trap type",
+ '\022', "^R redraw screen",
+ '&', "& save screen into 'rogue.screen'",
+ 's', "s search for trap/secret door",
+ '\020', "^P repeat last message",
+ '>', "> go down a staircase",
+ '\033', "^[ cancel command",
+ '<', "< go up a staircase",
+ 'S', "S save game",
+ '.', ". rest for a turn",
+ 'Q', "Q quit",
+ ',', ", pick something up",
+ '!', "! shell escape",
+ 'i', "i inventory",
+ 'F', "F<dir> fight till either of you dies",
+ 'I', "I inventory single item",
+ 'v', "v print version number",
+ 'q', "q quaff potion"
+};
+
+extern boolean wizard;
+extern char *m_names[], *more;
+
+inventory(pack, mask)
+object *pack;
+unsigned short mask;
+{
+ object *obj;
+ short i = 0, j, maxlen = 0, n;
+ char descs[MAX_PACK_COUNT+1][DCOLS];
+ short row, col;
+
+ obj = pack->next_object;
+
+ if (!obj) {
+ message("your pack is empty", 0);
+ return;
+ }
+ while (obj) {
+ if (obj->what_is & mask) {
+ descs[i][0] = ' ';
+ descs[i][1] = obj->ichar;
+ descs[i][2] = ((obj->what_is & ARMOR) && obj->is_protected)
+ ? '}' : ')';
+ descs[i][3] = ' ';
+ get_desc(obj, descs[i]+4);
+ if ((n = strlen(descs[i])) > maxlen) {
+ maxlen = n;
+ }
+ i++;
+ }
+ obj = obj->next_object;
+ }
+ (void) strcpy(descs[i++], press_space);
+ if (maxlen < 27) maxlen = 27;
+ col = DCOLS - (maxlen + 2);
+
+ for (row = 0; ((row < i) && (row < DROWS)); row++) {
+ if (row > 0) {
+ for (j = col; j < DCOLS; j++) {
+ descs[row-1][j-col] = mvinch(row, j);
+ }
+ descs[row-1][j-col] = 0;
+ }
+ mvaddstr(row, col, descs[row]);
+ clrtoeol();
+ }
+ refresh();
+ wait_for_ack();
+
+ move(0, 0);
+ clrtoeol();
+
+ for (j = 1; ((j < i) && (j < DROWS)); j++) {
+ mvaddstr(j, col, descs[j-1]);
+ }
+}
+
+id_com()
+{
+ int ch = 0;
+ short i, j, k;
+
+ while (ch != CANCEL) {
+ check_message();
+ message("Character you want help for (* for all):", 0);
+
+ refresh();
+ ch = getchar();
+
+ switch(ch) {
+ case LIST:
+ {
+ char save[(((COMS / 2) + (COMS % 2)) + 1)][DCOLS];
+ short rows = (((COMS / 2) + (COMS % 2)) + 1);
+ boolean need_two_screens;
+
+ if (rows > LINES) {
+ need_two_screens = 1;
+ rows = LINES;
+ }
+ k = 0;
+
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < DCOLS; j++) {
+ save[i][j] = mvinch(i, j);
+ }
+ }
+MORE:
+ for (i = 0; i < rows; i++) {
+ move(i, 0);
+ clrtoeol();
+ }
+ for (i = 0; i < (rows-1); i++) {
+ if (i < (LINES-1)) {
+ if (((i + i) < COMS) && ((i+i+k) < COMS)) {
+ mvaddstr(i, 0, com_id_tab[i+i+k].com_desc);
+ }
+ if (((i + i + 1) < COMS) && ((i+i+k+1) < COMS)) {
+ mvaddstr(i, (DCOLS/2),
+ com_id_tab[i+i+k+1].com_desc);
+ }
+ }
+ }
+ mvaddstr(rows - 1, 0, need_two_screens ? more : press_space);
+ refresh();
+ wait_for_ack();
+
+ if (need_two_screens) {
+ k += ((rows-1) * 2);
+ need_two_screens = 0;
+ goto MORE;
+ }
+ for (i = 0; i < rows; i++) {
+ move(i, 0);
+ for (j = 0; j < DCOLS; j++) {
+ addch(save[i][j]);
+ }
+ }
+ }
+ break;
+ default:
+ if (!pr_com_id(ch)) {
+ if (!pr_motion_char(ch)) {
+ check_message();
+ message("unknown character", 0);
+ }
+ }
+ ch = CANCEL;
+ break;
+ }
+ }
+}
+
+pr_com_id(ch)
+int ch;
+{
+ int i;
+
+ if (!get_com_id(&i, ch)) {
+ return(0);
+ }
+ check_message();
+ message(com_id_tab[i].com_desc, 0);
+ return(1);
+}
+
+get_com_id(index, ch)
+int *index;
+short ch;
+{
+ short i;
+
+ for (i = 0; i < COMS; i++) {
+ if (com_id_tab[i].com_char == ch) {
+ *index = i;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+pr_motion_char(ch)
+int ch;
+{
+ if ( (ch == 'J') ||
+ (ch == 'K') ||
+ (ch == 'L') ||
+ (ch == 'H') ||
+ (ch == 'Y') ||
+ (ch == 'U') ||
+ (ch == 'N') ||
+ (ch == 'B') ||
+ (ch == '\012') ||
+ (ch == '\013') ||
+ (ch == '\010') ||
+ (ch == '\014') ||
+ (ch == '\025') ||
+ (ch == '\031') ||
+ (ch == '\016') ||
+ (ch == '\002')) {
+ char until[18], buf[DCOLS];
+ int n;
+
+ if (ch <= '\031') {
+ ch += 96;
+ (void) strcpy(until, "until adjascent");
+ } else {
+ ch += 32;
+ until[0] = '\0';
+ }
+ (void) get_com_id(&n, ch);
+ sprintf(buf, "run %s %s", com_id_tab[n].com_desc + 8, until);
+ check_message();
+ message(buf, 0);
+ return(1);
+ } else {
+ return(0);
+ }
+}
+
+mix_colors()
+{
+ short i, j, k;
+ char *t;
+
+ for (i = 0; i <= 32; i++) {
+ j = get_rand(0, (POTIONS - 1));
+ k = get_rand(0, (POTIONS - 1));
+ t = id_potions[j].title;
+ id_potions[j].title = id_potions[k].title;
+ id_potions[k].title = t;
+ }
+}
+
+make_scroll_titles()
+{
+ short i, j, n;
+ short sylls, s;
+
+ for (i = 0; i < SCROLS; i++) {
+ sylls = get_rand(2, 5);
+ (void) strcpy(id_scrolls[i].title, "'");
+
+ for (j = 0; j < sylls; j++) {
+ s = get_rand(1, (MAXSYLLABLES-1));
+ (void) strcat(id_scrolls[i].title, syllables[s]);
+ }
+ n = strlen(id_scrolls[i].title);
+ (void) strcpy(id_scrolls[i].title+(n-1), "' ");
+ }
+}
+
+get_desc(obj, desc)
+object *obj;
+char *desc;
+{
+ char *item_name;
+ struct id *id_table;
+ char more_info[32];
+ short i;
+
+ if (obj->what_is == AMULET) {
+ (void) strcpy(desc, "the amulet of Yendor ");
+ return;
+ }
+ item_name = name_of(obj);
+
+ if (obj->what_is == GOLD) {
+ sprintf(desc, "%d pieces of gold", obj->quantity);
+ return;
+ }
+
+ if (obj->what_is != ARMOR) {
+ if (obj->quantity == 1) {
+ (void) strcpy(desc, "a ");
+ } else {
+ sprintf(desc, "%d ", obj->quantity);
+ }
+ }
+ if (obj->what_is == FOOD) {
+ if (obj->which_kind == RATION) {
+ if (obj->quantity > 1) {
+ sprintf(desc, "%d rations of ", obj->quantity);
+ } else {
+ (void) strcpy(desc, "some ");
+ }
+ } else {
+ (void) strcpy(desc, "a ");
+ }
+ (void) strcat(desc, item_name);
+ goto ANA;
+ }
+ id_table = get_id_table(obj);
+
+ if (wizard) {
+ goto ID;
+ }
+ if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
+ goto CHECK;
+ }
+
+ switch(id_table[obj->which_kind].id_status) {
+ case UNIDENTIFIED:
+CHECK:
+ switch(obj->what_is) {
+ case SCROL:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, "entitled: ");
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ break;
+ case POTION:
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ (void) strcat(desc, item_name);
+ break;
+ case WAND:
+ case RING:
+ if (obj->identified ||
+ (id_table[obj->which_kind].id_status == IDENTIFIED)) {
+ goto ID;
+ }
+ if (id_table[obj->which_kind].id_status == CALLED) {
+ goto CALL;
+ }
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ (void) strcat(desc, item_name);
+ break;
+ case ARMOR:
+ if (obj->identified) {
+ goto ID;
+ }
+ (void) strcpy(desc, id_table[obj->which_kind].title);
+ break;
+ case WEAPON:
+ if (obj->identified) {
+ goto ID;
+ }
+ (void) strcat(desc, name_of(obj));
+ break;
+ }
+ break;
+ case CALLED:
+CALL: switch(obj->what_is) {
+ case SCROL:
+ case POTION:
+ case WAND:
+ case RING:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, "called ");
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ break;
+ }
+ break;
+ case IDENTIFIED:
+ID: switch(obj->what_is) {
+ case SCROL:
+ case POTION:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, id_table[obj->which_kind].real);
+ break;
+ case RING:
+ if (wizard || obj->identified) {
+ if ((obj->which_kind == DEXTERITY) ||
+ (obj->which_kind == ADD_STRENGTH)) {
+ sprintf(more_info, "%s%d ", ((obj->class > 0) ? "+" : ""),
+ obj->class);
+ (void) strcat(desc, more_info);
+ }
+ }
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, id_table[obj->which_kind].real);
+ break;
+ case WAND:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, id_table[obj->which_kind].real);
+ if (wizard || obj->identified) {
+ sprintf(more_info, "[%d]", obj->class);
+ (void) strcat(desc, more_info);
+ }
+ break;
+ case ARMOR:
+ sprintf(desc, "%s%d ", ((obj->d_enchant >= 0) ? "+" : ""),
+ obj->d_enchant);
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ sprintf(more_info, "[%d] ", get_armor_class(obj));
+ (void) strcat(desc, more_info);
+ break;
+ case WEAPON:
+ sprintf(desc+strlen(desc), "%s%d,%s%d ",
+ ((obj->hit_enchant >= 0) ? "+" : ""), obj->hit_enchant,
+ ((obj->d_enchant >= 0) ? "+" : ""), obj->d_enchant);
+ (void) strcat(desc, name_of(obj));
+ break;
+ }
+ break;
+ }
+ANA:
+ if (!strncmp(desc, "a ", 2)) {
+ if (is_vowel(desc[2])) {
+ for (i = strlen(desc) + 1; i > 1; i--) {
+ desc[i] = desc[i-1];
+ }
+ desc[1] = 'n';
+ }
+ }
+ if (obj->in_use_flags & BEING_WIELDED) {
+ (void) strcat(desc, "in hand");
+ } else if (obj->in_use_flags & BEING_WORN) {
+ (void) strcat(desc, "being worn");
+ } else if (obj->in_use_flags & ON_LEFT_HAND) {
+ (void) strcat(desc, "on left hand");
+ } else if (obj->in_use_flags & ON_RIGHT_HAND) {
+ (void) strcat(desc, "on right hand");
+ }
+}
+
+get_wand_and_ring_materials()
+{
+ short i, j;
+ boolean used[WAND_MATERIALS];
+
+ for (i = 0; i < WAND_MATERIALS; i++) {
+ used[i] = 0;
+ }
+ for (i = 0; i < WANDS; i++) {
+ do {
+ j = get_rand(0, WAND_MATERIALS-1);
+ } while (used[j]);
+ used[j] = 1;
+ (void) strcpy(id_wands[i].title, wand_materials[j]);
+ is_wood[i] = (j > MAX_METAL);
+ }
+ for (i = 0; i < GEMS; i++) {
+ used[i] = 0;
+ }
+ for (i = 0; i < RINGS; i++) {
+ do {
+ j = get_rand(0, GEMS-1);
+ } while (used[j]);
+ used[j] = 1;
+ (void) strcpy(id_rings[i].title, gems[j]);
+ }
+}
+
+single_inv(ichar)
+short ichar;
+{
+ short ch;
+ char desc[DCOLS];
+ object *obj;
+
+ ch = ichar ? ichar : pack_letter("inventory what?", ALL_OBJECTS);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ desc[0] = ch;
+ desc[1] = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
+ desc[2] = ' ';
+ desc[3] = 0;
+ get_desc(obj, desc+3);
+ message(desc, 0);
+}
+
+struct id *
+get_id_table(obj)
+object *obj;
+{
+ switch(obj->what_is) {
+ case SCROL:
+ return(id_scrolls);
+ case POTION:
+ return(id_potions);
+ case WAND:
+ return(id_wands);
+ case RING:
+ return(id_rings);
+ case WEAPON:
+ return(id_weapons);
+ case ARMOR:
+ return(id_armors);
+ }
+ return((struct id *) 0);
+}
+
+inv_armor_weapon(is_weapon)
+boolean is_weapon;
+{
+ if (is_weapon) {
+ if (rogue.weapon) {
+ single_inv(rogue.weapon->ichar);
+ } else {
+ message("not wielding anything", 0);
+ }
+ } else {
+ if (rogue.armor) {
+ single_inv(rogue.armor->ichar);
+ } else {
+ message("not wearing anything", 0);
+ }
+ }
+}
+
+id_type()
+{
+ char *id;
+ int ch;
+ char buf[DCOLS];
+
+ message("what do you want identified?", 0);
+
+ ch = rgetchar();
+
+ if ((ch >= 'A') && (ch <= 'Z')) {
+ id = m_names[ch-'A'];
+ } else if (ch < 32) {
+ check_message();
+ return;
+ } else {
+ switch(ch) {
+ case '@':
+ id = "you";
+ break;
+ case '%':
+ id = "staircase";
+ break;
+ case '^':
+ id = "trap";
+ break;
+ case '+':
+ id = "door";
+ break;
+ case '-':
+ case '|':
+ id = "wall of a room";
+ break;
+ case '.':
+ id = "floor";
+ break;
+ case '#':
+ id = "passage";
+ break;
+ case ' ':
+ id = "solid rock";
+ break;
+ case '=':
+ id = "ring";
+ break;
+ case '?':
+ id = "scroll";
+ break;
+ case '!':
+ id = "potion";
+ break;
+ case '/':
+ id = "wand or staff";
+ break;
+ case ')':
+ id = "weapon";
+ break;
+ case ']':
+ id = "armor";
+ break;
+ case '*':
+ id = "gold";
+ break;
+ case ':':
+ id = "food";
+ break;
+ case ',':
+ id = "the Amulet of Yendor";
+ break;
+ default:
+ id = "unknown character";
+ break;
+ }
+ }
+ check_message();
+ sprintf(buf, "'%c': %s", ch, id);
+ message(buf, 0);
+}
diff --git a/rogue/level.c b/rogue/level.c
new file mode 100644
index 00000000..e04db8f7
--- /dev/null
+++ b/rogue/level.c
@@ -0,0 +1,881 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)level.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * level.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+#define swap(x,y) {t = x; x = y; y = t;}
+
+short cur_level = 0;
+short max_level = 1;
+short cur_room;
+char *new_level_message = 0;
+short party_room = NO_ROOM;
+short r_de;
+
+long level_points[MAX_EXP_LEVEL] = {
+ 10L,
+ 20L,
+ 40L,
+ 80L,
+ 160L,
+ 320L,
+ 640L,
+ 1300L,
+ 2600L,
+ 5200L,
+ 10000L,
+ 20000L,
+ 40000L,
+ 80000L,
+ 160000L,
+ 320000L,
+ 1000000L,
+ 3333333L,
+ 6666666L,
+ MAX_EXP,
+ 99900000L
+};
+
+short random_rooms[MAXROOMS] = {3, 7, 5, 2, 0, 6, 1, 4, 8};
+
+extern boolean being_held, wizard, detect_monster;
+extern boolean see_invisible;
+extern short bear_trap, levitate, extra_hp, less_hp, cur_room;
+
+make_level()
+{
+ short i, j;
+ short must_1, must_2, must_3;
+ boolean big_room;
+
+ if (cur_level < LAST_DUNGEON) {
+ cur_level++;
+ }
+ if (cur_level > max_level) {
+ max_level = cur_level;
+ }
+ must_1 = get_rand(0, 5);
+
+ switch(must_1) {
+ case 0:
+ must_1 = 0;
+ must_2 = 1;
+ must_3 = 2;
+ break;
+ case 1:
+ must_1 = 3;
+ must_2 = 4;
+ must_3 = 5;
+ break;
+ case 2:
+ must_1 = 6;
+ must_2 = 7;
+ must_3 = 8;
+ break;
+ case 3:
+ must_1 = 0;
+ must_2 = 3;
+ must_3 = 6;
+ break;
+ case 4:
+ must_1 = 1;
+ must_2 = 4;
+ must_3 = 7;
+ break;
+ case 5:
+ must_1 = 2;
+ must_2 = 5;
+ must_3 = 8;
+ break;
+ }
+ if (rand_percent(8)) {
+ party_room = 0;
+ }
+ big_room = ((party_room != NO_ROOM) && rand_percent(1));
+ if (big_room) {
+ make_room(BIG_ROOM, 0, 0, 0);
+ } else {
+ for (i = 0; i < MAXROOMS; i++) {
+ make_room(i, must_1, must_2, must_3);
+ }
+ }
+ if (!big_room) {
+ add_mazes();
+
+ mix_random_rooms();
+
+ for (j = 0; j < MAXROOMS; j++) {
+
+ i = random_rooms[j];
+
+ if (i < (MAXROOMS-1)) {
+ (void) connect_rooms(i, i+1);
+ }
+ if (i < (MAXROOMS-3)) {
+ (void) connect_rooms(i, i+3);
+ }
+ if (i < (MAXROOMS-2)) {
+ if (rooms[i+1].is_room & R_NOTHING) {
+ if (connect_rooms(i, i+2)) {
+ rooms[i+1].is_room = R_CROSS;
+ }
+ }
+ }
+ if (i < (MAXROOMS-6)) {
+ if (rooms[i+3].is_room & R_NOTHING) {
+ if (connect_rooms(i, i+6)) {
+ rooms[i+3].is_room = R_CROSS;
+ }
+ }
+ }
+ if (is_all_connected()) {
+ break;
+ }
+ }
+ fill_out_level();
+ }
+ if (!has_amulet() && (cur_level >= AMULET_LEVEL)) {
+ put_amulet();
+ }
+}
+
+make_room(rn, r1, r2, r3)
+short rn, r1, r2, r3;
+{
+ short left_col, right_col, top_row, bottom_row;
+ short width, height;
+ short row_offset, col_offset;
+ short i, j, ch;
+
+ switch(rn) {
+ case 0:
+ left_col = 0;
+ right_col = COL1-1;
+ top_row = MIN_ROW;
+ bottom_row = ROW1-1;
+ break;
+ case 1:
+ left_col = COL1+1;
+ right_col = COL2-1;
+ top_row = MIN_ROW;
+ bottom_row = ROW1-1;
+ break;
+ case 2:
+ left_col = COL2+1;
+ right_col = DCOLS-1;
+ top_row = MIN_ROW;
+ bottom_row = ROW1-1;
+ break;
+ case 3:
+ left_col = 0;
+ right_col = COL1-1;
+ top_row = ROW1+1;
+ bottom_row = ROW2-1;
+ break;
+ case 4:
+ left_col = COL1+1;
+ right_col = COL2-1;
+ top_row = ROW1+1;
+ bottom_row = ROW2-1;
+ break;
+ case 5:
+ left_col = COL2+1;
+ right_col = DCOLS-1;
+ top_row = ROW1+1;
+ bottom_row = ROW2-1;
+ break;
+ case 6:
+ left_col = 0;
+ right_col = COL1-1;
+ top_row = ROW2+1;
+ bottom_row = DROWS - 2;
+ break;
+ case 7:
+ left_col = COL1+1;
+ right_col = COL2-1;
+ top_row = ROW2+1;
+ bottom_row = DROWS - 2;
+ break;
+ case 8:
+ left_col = COL2+1;
+ right_col = DCOLS-1;
+ top_row = ROW2+1;
+ bottom_row = DROWS - 2;
+ break;
+ case BIG_ROOM:
+ top_row = get_rand(MIN_ROW, MIN_ROW+5);
+ bottom_row = get_rand(DROWS-7, DROWS-2);
+ left_col = get_rand(0, 10);;
+ right_col = get_rand(DCOLS-11, DCOLS-1);
+ rn = 0;
+ goto B;
+ }
+ height = get_rand(4, (bottom_row - top_row + 1));
+ width = get_rand(7, (right_col - left_col - 2));
+
+ row_offset = get_rand(0, ((bottom_row - top_row) - height + 1));
+ col_offset = get_rand(0, ((right_col - left_col) - width + 1));
+
+ top_row += row_offset;
+ bottom_row = top_row + height - 1;
+
+ left_col += col_offset;
+ right_col = left_col + width - 1;
+
+ if ((rn != r1) && (rn != r2) && (rn != r3) && rand_percent(40)) {
+ goto END;
+ }
+B:
+ rooms[rn].is_room = R_ROOM;
+
+ for (i = top_row; i <= bottom_row; i++) {
+ for (j = left_col; j <= right_col; j++) {
+ if ((i == top_row) || (i == bottom_row)) {
+ ch = HORWALL;
+ } else if ( ((i != top_row) && (i != bottom_row)) &&
+ ((j == left_col) || (j == right_col))) {
+ ch = VERTWALL;
+ } else {
+ ch = FLOOR;
+ }
+ dungeon[i][j] = ch;
+ }
+ }
+END:
+ rooms[rn].top_row = top_row;
+ rooms[rn].bottom_row = bottom_row;
+ rooms[rn].left_col = left_col;
+ rooms[rn].right_col = right_col;
+}
+
+connect_rooms(room1, room2)
+short room1, room2;
+{
+ short row1, col1, row2, col2, dir;
+
+ if ((!(rooms[room1].is_room & (R_ROOM | R_MAZE))) ||
+ (!(rooms[room2].is_room & (R_ROOM | R_MAZE)))) {
+ return(0);
+ }
+ if (same_row(room1, room2) &&
+ (rooms[room1].left_col > rooms[room2].right_col)) {
+ put_door(&rooms[room1], LEFT, &row1, &col1);
+ put_door(&rooms[room2], RIGHT, &row2, &col2);
+ dir = LEFT;
+ } else if (same_row(room1, room2) &&
+ (rooms[room2].left_col > rooms[room1].right_col)) {
+ put_door(&rooms[room1], RIGHT, &row1, &col1);
+ put_door(&rooms[room2], LEFT, &row2, &col2);
+ dir = RIGHT;
+ } else if (same_col(room1, room2) &&
+ (rooms[room1].top_row > rooms[room2].bottom_row)) {
+ put_door(&rooms[room1], UPWARD, &row1, &col1);
+ put_door(&rooms[room2], DOWN, &row2, &col2);
+ dir = UPWARD;
+ } else if (same_col(room1, room2) &&
+ (rooms[room2].top_row > rooms[room1].bottom_row)) {
+ put_door(&rooms[room1], DOWN, &row1, &col1);
+ put_door(&rooms[room2], UPWARD, &row2, &col2);
+ dir = DOWN;
+ } else {
+ return(0);
+ }
+
+ do {
+ draw_simple_passage(row1, col1, row2, col2, dir);
+ } while (rand_percent(4));
+
+ rooms[room1].doors[dir/2].oth_room = room2;
+ rooms[room1].doors[dir/2].oth_row = row2;
+ rooms[room1].doors[dir/2].oth_col = col2;
+
+ rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_room = room1;
+ rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_row = row1;
+ rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_col = col1;
+ return(1);
+}
+
+clear_level()
+{
+ short i, j;
+
+ for (i = 0; i < MAXROOMS; i++) {
+ rooms[i].is_room = R_NOTHING;
+ for (j = 0; j < 4; j++) {
+ rooms[i].doors[j].oth_room = NO_ROOM;
+ }
+ }
+
+ for (i = 0; i < MAX_TRAPS; i++) {
+ traps[i].trap_type = NO_TRAP;
+ }
+ for (i = 0; i < DROWS; i++) {
+ for (j = 0; j < DCOLS; j++) {
+ dungeon[i][j] = NOTHING;
+ }
+ }
+ detect_monster = see_invisible = 0;
+ being_held = bear_trap = 0;
+ party_room = NO_ROOM;
+ rogue.row = rogue.col = -1;
+ clear();
+}
+
+put_door(rm, dir, row, col)
+room *rm;
+short dir;
+short *row, *col;
+{
+ short wall_width;
+
+ wall_width = (rm->is_room & R_MAZE) ? 0 : 1;
+
+ switch(dir) {
+ case UPWARD:
+ case DOWN:
+ *row = ((dir == UPWARD) ? rm->top_row : rm->bottom_row);
+ do {
+ *col = get_rand(rm->left_col+wall_width,
+ rm->right_col-wall_width);
+ } while (!(dungeon[*row][*col] & (HORWALL | TUNNEL)));
+ break;
+ case RIGHT:
+ case LEFT:
+ *col = (dir == LEFT) ? rm->left_col : rm->right_col;
+ do {
+ *row = get_rand(rm->top_row+wall_width,
+ rm->bottom_row-wall_width);
+ } while (!(dungeon[*row][*col] & (VERTWALL | TUNNEL)));
+ break;
+ }
+ if (rm->is_room & R_ROOM) {
+ dungeon[*row][*col] = DOOR;
+ }
+ if ((cur_level > 2) && rand_percent(HIDE_PERCENT)) {
+ dungeon[*row][*col] |= HIDDEN;
+ }
+ rm->doors[dir/2].door_row = *row;
+ rm->doors[dir/2].door_col = *col;
+}
+
+draw_simple_passage(row1, col1, row2, col2, dir)
+short row1, col1, row2, col2, dir;
+{
+ short i, middle, t;
+
+ if ((dir == LEFT) || (dir == RIGHT)) {
+ if (col1 > col2) {
+ swap(row1, row2);
+ swap(col1, col2);
+ }
+ middle = get_rand(col1+1, col2-1);
+ for (i = col1+1; i != middle; i++) {
+ dungeon[row1][i] = TUNNEL;
+ }
+ for (i = row1; i != row2; i += (row1 > row2) ? -1 : 1) {
+ dungeon[i][middle] = TUNNEL;
+ }
+ for (i = middle; i != col2; i++) {
+ dungeon[row2][i] = TUNNEL;
+ }
+ } else {
+ if (row1 > row2) {
+ swap(row1, row2);
+ swap(col1, col2);
+ }
+ middle = get_rand(row1+1, row2-1);
+ for (i = row1+1; i != middle; i++) {
+ dungeon[i][col1] = TUNNEL;
+ }
+ for (i = col1; i != col2; i += (col1 > col2) ? -1 : 1) {
+ dungeon[middle][i] = TUNNEL;
+ }
+ for (i = middle; i != row2; i++) {
+ dungeon[i][col2] = TUNNEL;
+ }
+ }
+ if (rand_percent(HIDE_PERCENT)) {
+ hide_boxed_passage(row1, col1, row2, col2, 1);
+ }
+}
+
+same_row(room1, room2)
+{
+ return((room1 / 3) == (room2 / 3));
+}
+
+same_col(room1, room2)
+{
+ return((room1 % 3) == (room2 % 3));
+}
+
+add_mazes()
+{
+ short i, j;
+ short start;
+ short maze_percent;
+
+ if (cur_level > 1) {
+ start = get_rand(0, (MAXROOMS-1));
+ maze_percent = (cur_level * 5) / 4;
+
+ if (cur_level > 15) {
+ maze_percent += cur_level;
+ }
+ for (i = 0; i < MAXROOMS; i++) {
+ j = ((start + i) % MAXROOMS);
+ if (rooms[j].is_room & R_NOTHING) {
+ if (rand_percent(maze_percent)) {
+ rooms[j].is_room = R_MAZE;
+ make_maze(get_rand(rooms[j].top_row+1, rooms[j].bottom_row-1),
+ get_rand(rooms[j].left_col+1, rooms[j].right_col-1),
+ rooms[j].top_row, rooms[j].bottom_row,
+ rooms[j].left_col, rooms[j].right_col);
+ hide_boxed_passage(rooms[j].top_row, rooms[j].left_col,
+ rooms[j].bottom_row, rooms[j].right_col,
+ get_rand(0, 2));
+ }
+ }
+ }
+ }
+}
+
+fill_out_level()
+{
+ short i, rn;
+
+ mix_random_rooms();
+
+ r_de = NO_ROOM;
+
+ for (i = 0; i < MAXROOMS; i++) {
+ rn = random_rooms[i];
+ if ((rooms[rn].is_room & R_NOTHING) ||
+ ((rooms[rn].is_room & R_CROSS) && coin_toss())) {
+ fill_it(rn, 1);
+ }
+ }
+ if (r_de != NO_ROOM) {
+ fill_it(r_de, 0);
+ }
+}
+
+fill_it(rn, do_rec_de)
+int rn;
+boolean do_rec_de;
+{
+ short i, tunnel_dir, door_dir, drow, dcol;
+ short target_room, rooms_found = 0;
+ short srow, scol, t;
+ static short offsets[4] = {-1, 1, 3, -3};
+ boolean did_this = 0;
+
+ for (i = 0; i < 10; i++) {
+ srow = get_rand(0, 3);
+ scol = get_rand(0, 3);
+ t = offsets[srow];
+ offsets[srow] = offsets[scol];
+ offsets[scol] = t;
+ }
+ for (i = 0; i < 4; i++) {
+
+ target_room = rn + offsets[i];
+
+ if (((target_room < 0) || (target_room >= MAXROOMS)) ||
+ (!(same_row(rn,target_room) || same_col(rn,target_room))) ||
+ (!(rooms[target_room].is_room & (R_ROOM | R_MAZE)))) {
+ continue;
+ }
+ if (same_row(rn, target_room)) {
+ tunnel_dir = (rooms[rn].left_col < rooms[target_room].left_col) ?
+ RIGHT : LEFT;
+ } else {
+ tunnel_dir = (rooms[rn].top_row < rooms[target_room].top_row) ?
+ DOWN : UPWARD;
+ }
+ door_dir = ((tunnel_dir + 4) % DIRS);
+ if (rooms[target_room].doors[door_dir/2].oth_room != NO_ROOM) {
+ continue;
+ }
+ if (((!do_rec_de) || did_this) ||
+ (!mask_room(rn, &srow, &scol, TUNNEL))) {
+ srow = (rooms[rn].top_row + rooms[rn].bottom_row) / 2;
+ scol = (rooms[rn].left_col + rooms[rn].right_col) / 2;
+ }
+ put_door(&rooms[target_room], door_dir, &drow, &dcol);
+ rooms_found++;
+ draw_simple_passage(srow, scol, drow, dcol, tunnel_dir);
+ rooms[rn].is_room = R_DEADEND;
+ dungeon[srow][scol] = TUNNEL;
+
+ if ((i < 3) && (!did_this)) {
+ did_this = 1;
+ if (coin_toss()) {
+ continue;
+ }
+ }
+ if ((rooms_found < 2) && do_rec_de) {
+ recursive_deadend(rn, offsets, srow, scol);
+ }
+ break;
+ }
+}
+
+recursive_deadend(rn, offsets, srow, scol)
+short rn;
+short *offsets;
+short srow, scol;
+{
+ short i, de;
+ short drow, dcol, tunnel_dir;
+
+ rooms[rn].is_room = R_DEADEND;
+ dungeon[srow][scol] = TUNNEL;
+
+ for (i = 0; i < 4; i++) {
+ de = rn + offsets[i];
+ if (((de < 0) || (de >= MAXROOMS)) ||
+ (!(same_row(rn, de) || same_col(rn, de)))) {
+ continue;
+ }
+ if (!(rooms[de].is_room & R_NOTHING)) {
+ continue;
+ }
+ drow = (rooms[de].top_row + rooms[de].bottom_row) / 2;
+ dcol = (rooms[de].left_col + rooms[de].right_col) / 2;
+ if (same_row(rn, de)) {
+ tunnel_dir = (rooms[rn].left_col < rooms[de].left_col) ?
+ RIGHT : LEFT;
+ } else {
+ tunnel_dir = (rooms[rn].top_row < rooms[de].top_row) ?
+ DOWN : UPWARD;
+ }
+ draw_simple_passage(srow, scol, drow, dcol, tunnel_dir);
+ r_de = de;
+ recursive_deadend(de, offsets, drow, dcol);
+ }
+}
+
+boolean
+mask_room(rn, row, col, mask)
+short rn;
+short *row, *col;
+unsigned short mask;
+{
+ short i, j;
+
+ for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) {
+ for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) {
+ if (dungeon[i][j] & mask) {
+ *row = i;
+ *col = j;
+ return(1);
+ }
+ }
+ }
+ return(0);
+}
+
+make_maze(r, c, tr, br, lc, rc)
+short r, c, tr, br, lc, rc;
+{
+ char dirs[4];
+ short i, t;
+
+ dirs[0] = UPWARD;
+ dirs[1] = DOWN;
+ dirs[2] = LEFT;
+ dirs[3] = RIGHT;
+
+ dungeon[r][c] = TUNNEL;
+
+ if (rand_percent(20)) {
+ for (i = 0; i < 10; i++) {
+ short t1, t2;
+
+ t1 = get_rand(0, 3);
+ t2 = get_rand(0, 3);
+
+ swap(dirs[t1], dirs[t2]);
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ switch(dirs[i]) {
+ case UPWARD:
+ if (((r-1) >= tr) &&
+ (dungeon[r-1][c] != TUNNEL) &&
+ (dungeon[r-1][c-1] != TUNNEL) &&
+ (dungeon[r-1][c+1] != TUNNEL) &&
+ (dungeon[r-2][c] != TUNNEL)) {
+ make_maze((r-1), c, tr, br, lc, rc);
+ }
+ break;
+ case DOWN:
+ if (((r+1) <= br) &&
+ (dungeon[r+1][c] != TUNNEL) &&
+ (dungeon[r+1][c-1] != TUNNEL) &&
+ (dungeon[r+1][c+1] != TUNNEL) &&
+ (dungeon[r+2][c] != TUNNEL)) {
+ make_maze((r+1), c, tr, br, lc, rc);
+ }
+ break;
+ case LEFT:
+ if (((c-1) >= lc) &&
+ (dungeon[r][c-1] != TUNNEL) &&
+ (dungeon[r-1][c-1] != TUNNEL) &&
+ (dungeon[r+1][c-1] != TUNNEL) &&
+ (dungeon[r][c-2] != TUNNEL)) {
+ make_maze(r, (c-1), tr, br, lc, rc);
+ }
+ break;
+ case RIGHT:
+ if (((c+1) <= rc) &&
+ (dungeon[r][c+1] != TUNNEL) &&
+ (dungeon[r-1][c+1] != TUNNEL) &&
+ (dungeon[r+1][c+1] != TUNNEL) &&
+ (dungeon[r][c+2] != TUNNEL)) {
+ make_maze(r, (c+1), tr, br, lc, rc);
+ }
+ break;
+ }
+ }
+}
+
+hide_boxed_passage(row1, col1, row2, col2, n)
+short row1, col1, row2, col2, n;
+{
+ short i, j, t;
+ short row, col, row_cut, col_cut;
+ short h, w;
+
+ if (cur_level > 2) {
+ if (row1 > row2) {
+ swap(row1, row2);
+ }
+ if (col1 > col2) {
+ swap(col1, col2);
+ }
+ h = row2 - row1;
+ w = col2 - col1;
+
+ if ((w >= 5) || (h >= 5)) {
+ row_cut = ((h >= 2) ? 1 : 0);
+ col_cut = ((w >= 2) ? 1 : 0);
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < 10; j++) {
+ row = get_rand(row1 + row_cut, row2 - row_cut);
+ col = get_rand(col1 + col_cut, col2 - col_cut);
+ if (dungeon[row][col] == TUNNEL) {
+ dungeon[row][col] |= HIDDEN;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+put_player(nr)
+short nr; /* try not to put in this room */
+{
+ short rn = nr, misses;
+ short row, col;
+
+ for (misses = 0; ((misses < 2) && (rn == nr)); misses++) {
+ gr_row_col(&row, &col, (FLOOR | TUNNEL | OBJECT | STAIRS));
+ rn = get_room_number(row, col);
+ }
+ rogue.row = row;
+ rogue.col = col;
+
+ if (dungeon[rogue.row][rogue.col] & TUNNEL) {
+ cur_room = PASSAGE;
+ } else {
+ cur_room = rn;
+ }
+ if (cur_room != PASSAGE) {
+ light_up_room(cur_room);
+ } else {
+ light_passage(rogue.row, rogue.col);
+ }
+ rn = get_room_number(rogue.row, rogue.col);
+ wake_room(rn, 1, rogue.row, rogue.col);
+ if (new_level_message) {
+ message(new_level_message, 0);
+ new_level_message = 0;
+ }
+ mvaddch(rogue.row, rogue.col, rogue.fchar);
+}
+
+drop_check()
+{
+ if (wizard) {
+ return(1);
+ }
+ if (dungeon[rogue.row][rogue.col] & STAIRS) {
+ if (levitate) {
+ message("you're floating in the air!", 0);
+ return(0);
+ }
+ return(1);
+ }
+ message("I see no way down", 0);
+ return(0);
+}
+
+check_up()
+{
+ if (!wizard) {
+ if (!(dungeon[rogue.row][rogue.col] & STAIRS)) {
+ message("I see no way up", 0);
+ return(0);
+ }
+ if (!has_amulet()) {
+ message("your way is magically blocked", 0);
+ return(0);
+ }
+ }
+ new_level_message = "you feel a wrenching sensation in your gut";
+ if (cur_level == 1) {
+ win();
+ } else {
+ cur_level -= 2;
+ return(1);
+ }
+ return(0);
+}
+
+add_exp(e, promotion)
+int e;
+boolean promotion;
+{
+ char mbuf[40];
+ short new_exp;
+ short i, hp;
+
+ rogue.exp_points += e;
+
+ if (rogue.exp_points >= level_points[rogue.exp-1]) {
+ new_exp = get_exp_level(rogue.exp_points);
+ if (rogue.exp_points > MAX_EXP) {
+ rogue.exp_points = MAX_EXP + 1;
+ }
+ for (i = rogue.exp+1; i <= new_exp; i++) {
+ sprintf(mbuf, "welcome to level %d", i);
+ message(mbuf, 0);
+ if (promotion) {
+ hp = hp_raise();
+ rogue.hp_current += hp;
+ rogue.hp_max += hp;
+ }
+ rogue.exp = i;
+ print_stats(STAT_HP | STAT_EXP);
+ }
+ } else {
+ print_stats(STAT_EXP);
+ }
+}
+
+get_exp_level(e)
+long e;
+{
+ short i;
+
+ for (i = 0; i < (MAX_EXP_LEVEL - 1); i++) {
+ if (level_points[i] > e) {
+ break;
+ }
+ }
+ return(i+1);
+}
+
+hp_raise()
+{
+ int hp;
+
+ hp = (wizard ? 10 : get_rand(3, 10));
+ return(hp);
+}
+
+show_average_hp()
+{
+ char mbuf[80];
+ float real_average;
+ float effective_average;
+
+ if (rogue.exp == 1) {
+ real_average = effective_average = 0.00;
+ } else {
+ real_average = (float)
+ ((rogue.hp_max - extra_hp - INIT_HP) + less_hp) / (rogue.exp - 1);
+ effective_average = (float) (rogue.hp_max - INIT_HP) / (rogue.exp - 1);
+
+ }
+ sprintf(mbuf, "R-Hp: %.2f, E-Hp: %.2f (!: %d, V: %d)", real_average,
+ effective_average, extra_hp, less_hp);
+ message(mbuf, 0);
+}
+
+mix_random_rooms()
+{
+ short i, t;
+ short x, y;
+
+ for (i = 0; i < (3 * MAXROOMS); i++) {
+ do {
+ x = get_rand(0, (MAXROOMS-1));
+ y = get_rand(0, (MAXROOMS-1));
+ } while (x == y);
+ swap(random_rooms[x], random_rooms[y]);
+ }
+}
diff --git a/rogue/machdep.c b/rogue/machdep.c
new file mode 100644
index 00000000..149c5160
--- /dev/null
+++ b/rogue/machdep.c
@@ -0,0 +1,681 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)machdep.c 5.7 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * machdep.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+/* Included in this file are all system dependent routines. Extensive use
+ * of #ifdef's will be used to compile the appropriate code on each system:
+ *
+ * UNIX: all UNIX systems.
+ * UNIX_BSD4_2: UNIX BSD 4.2 and later, UTEK, (4.1 BSD too?)
+ * UNIX_SYSV: UNIX system V
+ * UNIX_V7: UNIX version 7
+ *
+ * All UNIX code should be included between the single "#ifdef UNIX" at the
+ * top of this file, and the "#endif" at the bottom.
+ *
+ * To change a routine to include a new UNIX system, simply #ifdef the
+ * existing routine, as in the following example:
+ *
+ * To make a routine compatible with UNIX system 5, change the first
+ * function to the second:
+ *
+ * md_function()
+ * {
+ * code;
+ * }
+ *
+ * md_function()
+ * {
+ * #ifdef UNIX_SYSV
+ * sys5code;
+ * #else
+ * code;
+ * #endif
+ * }
+ *
+ * Appropriate variations of this are of course acceptible.
+ * The use of "#elseif" is discouraged because of non-portability.
+ * If the correct #define doesn't exist, "UNIX_SYSV" in this case, make it up
+ * and insert it in the list at the top of the file. Alter the CFLAGS
+ * in you Makefile appropriately.
+ *
+ */
+
+#ifdef UNIX
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+#ifdef UNIX_BSD4_2
+#include <sys/time.h>
+#include <sgtty.h>
+#endif
+
+#ifdef UNIX_SYSV
+#include <time.h>
+#include <termio.h>
+#endif
+
+#include <signal.h>
+#include "rogue.h"
+#include "pathnames.h"
+
+/* md_slurp:
+ *
+ * This routine throws away all keyboard input that has not
+ * yet been read. It is used to get rid of input that the user may have
+ * typed-ahead.
+ *
+ * This function is not necessary, so it may be stubbed. The might cause
+ * message-line output to flash by because the game has continued to read
+ * input without waiting for the user to read the message. Not such a
+ * big deal.
+ */
+
+md_slurp()
+{
+ (void)fpurge(stdin);
+}
+
+/* md_control_keyboard():
+ *
+ * This routine is much like md_cbreak_no_echo_nonl() below. It sets up the
+ * keyboard for appropriate input. Specifically, it prevents the tty driver
+ * from stealing characters. For example, ^Y is needed as a command
+ * character, but the tty driver intercepts it for another purpose. Any
+ * such behavior should be stopped. This routine could be avoided if
+ * we used RAW mode instead of CBREAK. But RAW mode does not allow the
+ * generation of keyboard signals, which the program uses.
+ *
+ * The parameter 'mode' when true, indicates that the keyboard should
+ * be set up to play rogue. When false, it should be restored if
+ * necessary.
+ *
+ * This routine is not strictly necessary and may be stubbed. This may
+ * cause certain command characters to be unavailable.
+ */
+
+md_control_keybord(mode)
+boolean mode;
+{
+ static boolean called_before = 0;
+#ifdef UNIX_BSD4_2
+ static struct ltchars ltc_orig;
+ static struct tchars tc_orig;
+ struct ltchars ltc_temp;
+ struct tchars tc_temp;
+#endif
+#ifdef UNIX_SYSV
+ static struct termio _oldtty;
+ struct termio _tty;
+#endif
+
+ if (!called_before) {
+ called_before = 1;
+#ifdef UNIX_BSD4_2
+ ioctl(0, TIOCGETC, &tc_orig);
+ ioctl(0, TIOCGLTC, &ltc_orig);
+#endif
+#ifdef UNIX_SYSV
+ ioctl(0, TCGETA, &_oldtty);
+#endif
+ }
+#ifdef UNIX_BSD4_2
+ ltc_temp = ltc_orig;
+ tc_temp = tc_orig;
+#endif
+#ifdef UNIX_SYSV
+ _tty = _oldtty;
+#endif
+
+ if (!mode) {
+#ifdef UNIX_BSD4_2
+ ltc_temp.t_suspc = ltc_temp.t_dsuspc = -1;
+ ltc_temp.t_rprntc = ltc_temp.t_flushc = -1;
+ ltc_temp.t_werasc = ltc_temp.t_lnextc = -1;
+ tc_temp.t_startc = tc_temp.t_stopc = -1;
+#endif
+#ifdef UNIX_SYSV
+ _tty.c_cc[VSWTCH] = CNSWTCH;
+#endif
+ }
+#ifdef UNIX_BSD4_2
+ ioctl(0, TIOCSETC, &tc_temp);
+ ioctl(0, TIOCSLTC, &ltc_temp);
+#endif
+#ifdef UNIX_SYSV
+ ioctl(0, TCSETA, &_tty);
+#endif
+}
+
+/* md_heed_signals():
+ *
+ * This routine tells the program to call particular routines when
+ * certain interrupts/events occur:
+ *
+ * SIGINT: call onintr() to interrupt fight with monster or long rest.
+ * SIGQUIT: call byebye() to check for game termination.
+ * SIGHUP: call error_save() to save game when terminal hangs up.
+ *
+ * On VMS, SIGINT and SIGQUIT correspond to ^C and ^Y.
+ *
+ * This routine is not strictly necessary and can be stubbed. This will
+ * mean that the game cannot be interrupted properly with keyboard
+ * input, this is not usually critical.
+ */
+
+md_heed_signals()
+{
+ signal(SIGINT, onintr);
+ signal(SIGQUIT, byebye);
+ signal(SIGHUP, error_save);
+}
+
+/* md_ignore_signals():
+ *
+ * This routine tells the program to completely ignore the events mentioned
+ * in md_heed_signals() above. The event handlers will later be turned on
+ * by a future call to md_heed_signals(), so md_heed_signals() and
+ * md_ignore_signals() need to work together.
+ *
+ * This function should be implemented or the user risks interrupting
+ * critical sections of code, which could cause score file, or saved-game
+ * file, corruption.
+ */
+
+md_ignore_signals()
+{
+ signal(SIGQUIT, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+}
+
+/* md_get_file_id():
+ *
+ * This function returns an integer that uniquely identifies the specified
+ * file. It need not check for the file's existence. In UNIX, the inode
+ * number is used.
+ *
+ * This function is used to identify saved-game files.
+ */
+
+int
+md_get_file_id(fname)
+char *fname;
+{
+ struct stat sbuf;
+
+ if (stat(fname, &sbuf)) {
+ return(-1);
+ }
+ return((int) sbuf.st_ino);
+}
+
+/* md_link_count():
+ *
+ * This routine returns the number of hard links to the specified file.
+ *
+ * This function is not strictly necessary. On systems without hard links
+ * this routine can be stubbed by just returning 1.
+ */
+
+int
+md_link_count(fname)
+char *fname;
+{
+ struct stat sbuf;
+
+ stat(fname, &sbuf);
+ return((int) sbuf.st_nlink);
+}
+
+/* md_gct(): (Get Current Time)
+ *
+ * This function returns the current year, month(1-12), day(1-31), hour(0-23),
+ * minute(0-59), and second(0-59). This is used for identifying the time
+ * at which a game is saved.
+ *
+ * This function is not strictly necessary. It can be stubbed by returning
+ * zeros instead of the correct year, month, etc. If your operating
+ * system doesn't provide all of the time units requested here, then you
+ * can provide only those that it does, and return zeros for the others.
+ * If you cannot provide good time values, then users may be able to copy
+ * saved-game files and play them.
+ */
+
+md_gct(rt_buf)
+struct rogue_time *rt_buf;
+{
+ struct tm *t, *localtime();
+ long seconds;
+
+ time(&seconds);
+ t = localtime(&seconds);
+
+ rt_buf->year = t->tm_year;
+ rt_buf->month = t->tm_mon + 1;
+ rt_buf->day = t->tm_mday;
+ rt_buf->hour = t->tm_hour;
+ rt_buf->minute = t->tm_min;
+ rt_buf->second = t->tm_sec;
+}
+
+/* md_gfmt: (Get File Modification Time)
+ *
+ * This routine returns a file's date of last modification in the same format
+ * as md_gct() above.
+ *
+ * This function is not strictly necessary. It is used to see if saved-game
+ * files have been modified since they were saved. If you have stubbed the
+ * routine md_gct() above by returning constant values, then you may do
+ * exactly the same here.
+ * Or if md_gct() is implemented correctly, but your system does not provide
+ * file modification dates, you may return some date far in the past so
+ * that the program will never know that a saved-game file being modified.
+ * You may also do this if you wish to be able to restore games from
+ * saved-games that have been modified.
+ */
+
+md_gfmt(fname, rt_buf)
+char *fname;
+struct rogue_time *rt_buf;
+{
+ struct stat sbuf;
+ long seconds;
+ struct tm *t;
+
+ stat(fname, &sbuf);
+ seconds = (long) sbuf.st_mtime;
+ t = localtime(&seconds);
+
+ rt_buf->year = t->tm_year;
+ rt_buf->month = t->tm_mon + 1;
+ rt_buf->day = t->tm_mday;
+ rt_buf->hour = t->tm_hour;
+ rt_buf->minute = t->tm_min;
+ rt_buf->second = t->tm_sec;
+}
+
+/* md_df: (Delete File)
+ *
+ * This function deletes the specified file, and returns true (1) if the
+ * operation was successful. This is used to delete saved-game files
+ * after restoring games from them.
+ *
+ * Again, this function is not strictly necessary, and can be stubbed
+ * by simply returning 1. In this case, saved-game files will not be
+ * deleted and can be replayed.
+ */
+
+boolean
+md_df(fname)
+char *fname;
+{
+ if (unlink(fname)) {
+ return(0);
+ }
+ return(1);
+}
+
+/* md_gln: (Get login name)
+ *
+ * This routine returns the login name of the user. This string is
+ * used mainly for identifying users in score files.
+ *
+ * A dummy string may be returned if you are unable to implement this
+ * function, but then the score file would only have one name in it.
+ */
+
+char *
+md_gln()
+{
+ struct passwd *p;
+
+ if (!(p = getpwuid(getuid())))
+ return((char *)NULL);
+ return(p->pw_name);
+}
+
+/* md_sleep:
+ *
+ * This routine causes the game to pause for the specified number of
+ * seconds.
+ *
+ * This routine is not particularly necessary at all. It is used for
+ * delaying execution, which is useful to this program at some times.
+ */
+
+md_sleep(nsecs)
+int nsecs;
+{
+ (void) sleep(nsecs);
+}
+
+/* md_getenv()
+ *
+ * This routine gets certain values from the user's environment. These
+ * values are strings, and each string is identified by a name. The names
+ * of the values needed, and their use, is as follows:
+ *
+ * TERMCAP
+ * The name of the users's termcap file, NOT the termcap entries
+ * themselves. This is used ONLY if the program is compiled with
+ * CURSES defined (-DCURSES). Even in this case, the program need
+ * not find a string for TERMCAP. If it does not, it will use the
+ * default termcap file as returned by md_gdtcf();
+ * TERM
+ * The name of the users's terminal. This is used ONLY if the program
+ * is compiled with CURSES defined (-DCURSES). In this case, the string
+ * value for TERM must be found, or the routines in curses.c cannot
+ * function, and the program will quit.
+ * ROGUEOPTS
+ * A string containing the various game options. This need not be
+ * defined.
+ * HOME
+ * The user's home directory. This is only used when the user specifies
+ * '~' as the first character of a saved-game file. This string need
+ * not be defined.
+ * SHELL
+ * The user's favorite shell. If not found, "/bin/sh" is assumed.
+ *
+ * If your system does not provide a means of searching for these values,
+ * you will have to do it yourself. None of the values above really need
+ * to be defined except TERM when the program is compiled with CURSES
+ * defined. In this case, as a bare minimum, you can check the 'name'
+ * parameter, and if it is "TERM" find the terminal name and return that,
+ * else return zero. If the program is not compiled with CURSES, you can
+ * get by with simply always returning zero. Returning zero indicates
+ * that their is no defined value for the given string.
+ */
+
+char *
+md_getenv(name)
+char *name;
+{
+ char *value;
+ char *getenv();
+
+ value = getenv(name);
+
+ return(value);
+}
+
+/* md_malloc()
+ *
+ * This routine allocates, and returns a pointer to, the specified number
+ * of bytes. This routines absolutely MUST be implemented for your
+ * particular system or the program will not run at all. Return zero
+ * when no more memory can be allocated.
+ */
+
+char *
+md_malloc(n)
+int n;
+{
+ char *malloc();
+ char *t;
+
+ t = malloc(n);
+ return(t);
+}
+
+/* md_gseed() (Get Seed)
+ *
+ * This function returns a seed for the random number generator (RNG). This
+ * seed causes the RNG to begin generating numbers at some point in it's
+ * sequence. Without a random seed, the RNG will generate the same set
+ * of numbers, and every game will start out exactly the same way. A good
+ * number to use is the process id, given by getpid() on most UNIX systems.
+ *
+ * You need to find some single random integer, such as:
+ * process id.
+ * current time (minutes + seconds) returned from md_gct(), if implemented.
+ *
+ * It will not help to return "get_rand()" or "rand()" or the return value of
+ * any pseudo-RNG. If you don't have a random number, you can just return 1,
+ * but this means your games will ALWAYS start the same way, and will play
+ * exactly the same way given the same input.
+ */
+
+md_gseed()
+{
+ return(getpid());
+}
+
+/* md_exit():
+ *
+ * This function causes the program to discontinue execution and exit.
+ * This function must be implemented or the program will continue to
+ * hang when it should quit.
+ */
+
+md_exit(status)
+int status;
+{
+ exit(status);
+}
+
+/* md_lock():
+ *
+ * This function is intended to give the user exclusive access to the score
+ * file. It does so by "creat"ing a lock file, which can only be created
+ * if it does not already exist. The file is deleted when score file
+ * processing is finished. The lock file should be located in the same
+ * directory as the score file. These full path names should be defined for
+ * any particular site in rogue.h. The constants _PATH_SCOREFILE and
+ * _PATH_LOCKFILE define these file names.
+ *
+ * When the parameter 'l' is non-zero (true), a lock is requested. Otherwise
+ * the lock is released by removing the lock file.
+ */
+
+md_lock(l)
+boolean l;
+{
+ short tries;
+ char *lock_file = _PATH_LOCKFILE;
+
+ if (l) {
+ for (tries = 0; tries < 5; tries++) {
+ if (md_get_file_id(lock_file) == -1) {
+ if (creat(lock_file, 0444) != -1) {
+ break;
+ } else {
+ message("cannot lock score file", 0);
+ }
+ } else {
+ message("waiting to lock score file", 0);
+ }
+ sleep(2);
+ }
+ } else {
+ (void) unlink(lock_file);
+ }
+}
+
+/* md_shell():
+ *
+ * This function spawns a shell for the user to use. When this shell is
+ * terminated, the game continues. Since this program may often be run
+ * setuid to gain access to privileged files, care is taken that the shell
+ * is run with the user's REAL user id, and not the effective user id.
+ * The effective user id is restored after the shell completes.
+ */
+
+md_shell(shell)
+char *shell;
+{
+ long w[2];
+
+ if (!fork()) {
+ int uid;
+
+ uid = getuid();
+ setuid(uid);
+ execl(shell, shell, 0);
+ }
+ wait(w);
+}
+
+/* If you have a viable curses/termlib library, then use it and don't bother
+ * implementing the routines below. And don't compile with -DCURSES.
+ */
+
+#ifdef CURSES
+
+/* md_cbreak_no_echo_nonl:
+ *
+ * This routine sets up some terminal characteristics. The tty-driver
+ * must be told to:
+ * 1.) Not echo input.
+ * 2.) Transmit input characters immediately upon typing. (cbreak mode)
+ * 3.) Move the cursor down one line, without changing column, and
+ * without generating a carriage-return, when it
+ * sees a line-feed. This is only necessary if line-feed is ever
+ * used in the termcap 'do' (cursor down) entry, in which case,
+ * your system should must have a way of accomplishing this.
+ *
+ * When the parameter 'on' is true, the terminal is set up as specified
+ * above. When this parameter is false, the terminal is restored to the
+ * original state.
+ *
+ * Raw mode should not to be used. Keyboard signals/events/interrupts should
+ * be sent, although they are not strictly necessary. See notes in
+ * md_heed_signals().
+ *
+ * This function must be implemented for rogue to run properly if the
+ * program is compiled with CURSES defined to use the enclosed curses
+ * emulation package. If you are not using this, then this routine is
+ * totally unnecessary.
+ *
+ * Notice that information is saved between calls. This is used to
+ * restore the terminal to an initial saved state.
+ *
+ */
+
+md_cbreak_no_echo_nonl(on)
+boolean on;
+{
+#ifdef UNIX_BSD4_2
+ static struct sgttyb tty_buf;
+ static int tsave_flags;
+
+ if (on) {
+ ioctl(0, TIOCGETP, &tty_buf);
+ tsave_flags = tty_buf.sg_flags;
+ tty_buf.sg_flags |= CBREAK;
+ tty_buf.sg_flags &= ~(ECHO | CRMOD); /* CRMOD: see note 3 above */
+ ioctl(0, TIOCSETP, &tty_buf);
+ } else {
+ tty_buf.sg_flags = tsave_flags;
+ ioctl(0, TIOCSETP, &tty_buf);
+ }
+#endif
+#ifdef UNIX_SYSV
+ struct termio tty_buf;
+ static struct termio tty_save;
+
+ if (on) {
+ ioctl(0, TCGETA, &tty_buf);
+ tty_save = tty_buf;
+ tty_buf.c_lflag &= ~(ICANON | ECHO);
+ tty_buf.c_oflag &= ~ONLCR;
+ tty_buf.c_cc[4] = 1; /* MIN */
+ tty_buf.c_cc[5] = 2; /* TIME */
+ ioctl(0, TCSETAF, &tty_buf);
+ } else {
+ ioctl(0, TCSETAF, &tty_save);
+ }
+#endif
+}
+
+/* md_gdtcf(): (Get Default Termcap File)
+ *
+ * This function is called ONLY when the program is compiled with CURSES
+ * defined. If you use your system's curses/termlib library, this function
+ * won't be called. On most UNIX systems, "/etc/termcap" suffices.
+ *
+ * If their is no such termcap file, then return 0, but in that case, you
+ * must have a TERMCAP file returned from md_getenv("TERMCAP"). The latter
+ * will override the value returned from md_gdtcf(). If the program is
+ * compiled with CURSES defined, and md_gdtcf() returns 0, and
+ * md_getenv("TERMCAP") returns 0, the program will have no terminal
+ * capability information and will quit.
+ */
+
+char *
+md_gdtcf()
+{
+ return("/etc/termcap");
+}
+
+/* md_tstp():
+ *
+ * This function puts the game to sleep and returns to the shell. This
+ * only applies to UNIX 4.2 and 4.3. For other systems, the routine should
+ * be provided as a do-nothing routine. md_tstp() will only be referenced
+ * in the code when compiled with CURSES defined.
+ *
+ */
+
+md_tstp()
+{
+#ifdef UNIX_BSD4_2
+ kill(0, SIGTSTP);
+#endif
+}
+
+#endif
+
+#endif
diff --git a/rogue/main.c b/rogue/main.c
new file mode 100644
index 00000000..e27084e4
--- /dev/null
+++ b/rogue/main.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1988 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * main.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+extern short party_room;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ if (init(argc, argv)) { /* restored game */
+ goto PL;
+ }
+
+ for (;;) {
+ clear_level();
+ make_level();
+ put_objects();
+ put_stairs();
+ add_traps();
+ put_mons();
+ put_player(party_room);
+ print_stats(STAT_ALL);
+PL:
+ play_level();
+ free_stuff(&level_objects);
+ free_stuff(&level_monsters);
+ }
+}
diff --git a/rogue/message.c b/rogue/message.c
new file mode 100644
index 00000000..5761c8eb
--- /dev/null
+++ b/rogue/message.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)message.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * message.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include <stdio.h>
+#include "rogue.h"
+
+char msgs[NMESSAGES][DCOLS] = {"", "", "", "", ""};
+short msg_col = 0, imsg = -1;
+boolean msg_cleared = 1, rmsg = 0;
+char hunger_str[8] = "";
+char *more = "-more-";
+
+extern boolean cant_int, did_int, interrupted, save_is_interactive;
+extern short add_strength;
+extern short cur_level;
+
+message(msg, intrpt)
+char *msg;
+boolean intrpt;
+{
+ cant_int = 1;
+
+ if (!save_is_interactive) {
+ return;
+ }
+ if (intrpt) {
+ interrupted = 1;
+ md_slurp();
+ }
+
+ if (!msg_cleared) {
+ mvaddstr(MIN_ROW-1, msg_col, more);
+ refresh();
+ wait_for_ack();
+ check_message();
+ }
+ if (!rmsg) {
+ imsg = (imsg + 1) % NMESSAGES;
+ (void) strcpy(msgs[imsg], msg);
+ }
+ mvaddstr(MIN_ROW-1, 0, msg);
+ addch(' ');
+ refresh();
+ msg_cleared = 0;
+ msg_col = strlen(msg);
+
+ cant_int = 0;
+
+ if (did_int) {
+ did_int = 0;
+ onintr();
+ }
+}
+
+remessage(c)
+short c;
+{
+ if (imsg != -1) {
+ check_message();
+ rmsg = 1;
+ while (c > imsg) {
+ c -= NMESSAGES;
+ }
+ message(msgs[((imsg - c) % NMESSAGES)], 0);
+ rmsg = 0;
+ move(rogue.row, rogue.col);
+ refresh();
+ }
+}
+
+check_message()
+{
+ if (msg_cleared) {
+ return;
+ }
+ move(MIN_ROW-1, 0);
+ clrtoeol();
+ refresh();
+ msg_cleared = 1;
+}
+
+get_input_line(prompt, insert, buf, if_cancelled, add_blank, do_echo)
+char *prompt, *buf, *insert;
+char *if_cancelled;
+boolean add_blank;
+boolean do_echo;
+{
+ short ch;
+ short i = 0, n;
+
+ message(prompt, 0);
+ n = strlen(prompt);
+
+ if (insert[0]) {
+ mvaddstr(0, n + 1, insert);
+ (void) strcpy(buf, insert);
+ i = strlen(insert);
+ move(0, (n + i + 1));
+ refresh();
+ }
+
+ while (((ch = rgetchar()) != '\r') && (ch != '\n') && (ch != CANCEL)) {
+ if ((ch >= ' ') && (ch <= '~') && (i < MAX_TITLE_LENGTH-2)) {
+ if ((ch != ' ') || (i > 0)) {
+ buf[i++] = ch;
+ if (do_echo) {
+ addch(ch);
+ }
+ }
+ }
+ if ((ch == '\b') && (i > 0)) {
+ if (do_echo) {
+ mvaddch(0, i + n, ' ');
+ move(MIN_ROW-1, i+n);
+ }
+ i--;
+ }
+ refresh();
+ }
+ check_message();
+ if (add_blank) {
+ buf[i++] = ' ';
+ } else {
+ while ((i > 0) && (buf[i-1] == ' ')) {
+ i--;
+ }
+ }
+
+ buf[i] = 0;
+
+ if ((ch == CANCEL) || (i == 0) || ((i == 1) && add_blank)) {
+ if (if_cancelled) {
+ message(if_cancelled, 0);
+ }
+ return(0);
+ }
+ return(i);
+}
+
+rgetchar()
+{
+ register ch;
+
+ for(;;) {
+ ch = getchar();
+
+ switch(ch) {
+ case '\022':
+ wrefresh(curscr);
+ break;
+#ifdef UNIX_BSD4_2
+ case '\032':
+ printf(CL);
+ fflush(stdout);
+ tstp();
+ break;
+#endif
+ case '&':
+ save_screen();
+ break;
+ default:
+ return(ch);
+ }
+ }
+}
+/*
+Level: 99 Gold: 999999 Hp: 999(999) Str: 99(99) Arm: 99 Exp: 21/10000000 Hungry
+0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5
+*/
+
+print_stats(stat_mask)
+register stat_mask;
+{
+ char buf[16];
+ boolean label;
+ int row = DROWS - 1;
+
+ label = (stat_mask & STAT_LABEL) ? 1 : 0;
+
+ if (stat_mask & STAT_LEVEL) {
+ if (label) {
+ mvaddstr(row, 0, "Level: ");
+ }
+ /* max level taken care of in make_level() */
+ sprintf(buf, "%d", cur_level);
+ mvaddstr(row, 7, buf);
+ pad(buf, 2);
+ }
+ if (stat_mask & STAT_GOLD) {
+ if (label) {
+ mvaddstr(row, 10, "Gold: ");
+ }
+ if (rogue.gold > MAX_GOLD) {
+ rogue.gold = MAX_GOLD;
+ }
+ sprintf(buf, "%ld", rogue.gold);
+ mvaddstr(row, 16, buf);
+ pad(buf, 6);
+ }
+ if (stat_mask & STAT_HP) {
+ if (label) {
+ mvaddstr(row, 23, "Hp: ");
+ }
+ if (rogue.hp_max > MAX_HP) {
+ rogue.hp_current -= (rogue.hp_max - MAX_HP);
+ rogue.hp_max = MAX_HP;
+ }
+ sprintf(buf, "%d(%d)", rogue.hp_current, rogue.hp_max);
+ mvaddstr(row, 27, buf);
+ pad(buf, 8);
+ }
+ if (stat_mask & STAT_STRENGTH) {
+ if (label) {
+ mvaddstr(row, 36, "Str: ");
+ }
+ if (rogue.str_max > MAX_STRENGTH) {
+ rogue.str_current -= (rogue.str_max - MAX_STRENGTH);
+ rogue.str_max = MAX_STRENGTH;
+ }
+ sprintf(buf, "%d(%d)", (rogue.str_current + add_strength),
+ rogue.str_max);
+ mvaddstr(row, 41, buf);
+ pad(buf, 6);
+ }
+ if (stat_mask & STAT_ARMOR) {
+ if (label) {
+ mvaddstr(row, 48, "Arm: ");
+ }
+ if (rogue.armor && (rogue.armor->d_enchant > MAX_ARMOR)) {
+ rogue.armor->d_enchant = MAX_ARMOR;
+ }
+ sprintf(buf, "%d", get_armor_class(rogue.armor));
+ mvaddstr(row, 53, buf);
+ pad(buf, 2);
+ }
+ if (stat_mask & STAT_EXP) {
+ if (label) {
+ mvaddstr(row, 56, "Exp: ");
+ }
+ if (rogue.exp_points > MAX_EXP) {
+ rogue.exp_points = MAX_EXP;
+ }
+ if (rogue.exp > MAX_EXP_LEVEL) {
+ rogue.exp = MAX_EXP_LEVEL;
+ }
+ sprintf(buf, "%d/%ld", rogue.exp, rogue.exp_points);
+ mvaddstr(row, 61, buf);
+ pad(buf, 11);
+ }
+ if (stat_mask & STAT_HUNGER) {
+ mvaddstr(row, 73, hunger_str);
+ clrtoeol();
+ }
+ refresh();
+}
+
+pad(s, n)
+char *s;
+short n;
+{
+ short i;
+
+ for (i = strlen(s); i < n; i++) {
+ addch(' ');
+ }
+}
+
+save_screen()
+{
+ FILE *fp;
+ short i, j;
+ char buf[DCOLS+2];
+ boolean found_non_blank;
+
+ if ((fp = fopen("rogue.screen", "w")) != NULL) {
+ for (i = 0; i < DROWS; i++) {
+ found_non_blank = 0;
+ for (j = (DCOLS - 1); j >= 0; j--) {
+ buf[j] = mvinch(i, j);
+ if (!found_non_blank) {
+ if ((buf[j] != ' ') || (j == 0)) {
+ buf[j + ((j == 0) ? 0 : 1)] = 0;
+ found_non_blank = 1;
+ }
+ }
+ }
+ fputs(buf, fp);
+ putc('\n', fp);
+ }
+ fclose(fp);
+ } else {
+ sound_bell();
+ }
+}
+
+sound_bell()
+{
+ putchar(7);
+ fflush(stdout);
+}
+
+boolean
+is_digit(ch)
+short ch;
+{
+ return((ch >= '0') && (ch <= '9'));
+}
+
+r_index(str, ch, last)
+char *str;
+int ch;
+boolean last;
+{
+ int i = 0;
+
+ if (last) {
+ for (i = strlen(str) - 1; i >= 0; i--) {
+ if (str[i] == ch) {
+ return(i);
+ }
+ }
+ } else {
+ for (i = 0; str[i]; i++) {
+ if (str[i] == ch) {
+ return(i);
+ }
+ }
+ }
+ return(-1);
+}
diff --git a/rogue/monster.c b/rogue/monster.c
new file mode 100644
index 00000000..8cf39e25
--- /dev/null
+++ b/rogue/monster.c
@@ -0,0 +1,867 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)monster.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * monster.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+object level_monsters;
+boolean mon_disappeared;
+
+char *m_names[] = {
+ "aquator",
+ "bat",
+ "centaur",
+ "dragon",
+ "emu",
+ "venus fly-trap",
+ "griffin",
+ "hobgoblin",
+ "ice monster",
+ "jabberwock",
+ "kestrel",
+ "leprechaun",
+ "medusa",
+ "nymph",
+ "orc",
+ "phantom",
+ "quagga",
+ "rattlesnake",
+ "snake",
+ "troll",
+ "black unicorn",
+ "vampire",
+ "wraith",
+ "xeroc",
+ "yeti",
+ "zombie"
+};
+
+object mon_tab[MONSTERS] = {
+ {(ASLEEP|WAKENS|WANDERS|RUSTS),"0d0",25,'A',20,9,18,100,0,0,0,0,0},
+ {(ASLEEP|WANDERS|FLITS|FLIES),"1d3",10,'B',2,1,8,60,0,0,0,0,0},
+ {(ASLEEP|WANDERS),"3d3/2d5",32,'C',15,7,16,85,0,10,0,0,0},
+ {(ASLEEP|WAKENS|FLAMES),"4d6/4d9",145,'D',5000,21,126,100,0,90,0,0,0},
+ {(ASLEEP|WAKENS),"1d3",11,'E',2,1,7,65,0,0,0,0,0},
+ {(HOLDS|STATIONARY),"5d5",73,'F',91,12,126,80,0,0,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS|FLIES),"5d5/5d5",115,'G',
+ 2000,20,126,85,0,10,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS),"1d3/1d2",15,'H',3,1,10,67,0,0,0,0,0},
+ {(ASLEEP|FREEZES),"0d0",15,'I',5,2,11,68,0,0,0,0,0},
+ {(ASLEEP|WANDERS),"3d10/4d5",132,'J',3000,21,126,100,0,0,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS|FLIES),"1d4",10,'K',2,1,6,60,0,0,0,0,0},
+ {(ASLEEP|STEALS_GOLD),"0d0",25,'L',21,6,16,75,0,0,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS|CONFUSES),"4d4/3d7",97,'M',
+ 250,18,126,85,0,25,0,0,0},
+ {(ASLEEP|STEALS_ITEM),"0d0",25,'N',39,10,19,75,0,100,0,0,0},
+ {(ASLEEP|WANDERS|WAKENS|SEEKS_GOLD),"1d6",25,'O',5,4,13,70,0,10,0,0,0},
+ {(ASLEEP|INVISIBLE|WANDERS|FLITS),"5d4",76,'P',120,15,24,80,0,50,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS),"3d5",30,'Q',20,8,17,78,0,20,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS|STINGS),"2d5",19,'R',10,3,12,70,0,0,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS),"1d3",8,'S',2,1,9,50,0,0,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS),"4d6/1d4",75,'T',125,13,22,75,0,33,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS),"4d10",90,'U',
+ 200,17,26,85,0,33,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS|DRAINS_LIFE),"1d14/1d4",55,'V',
+ 350,19,126,85,0,18,0,0,0},
+ {(ASLEEP|WANDERS|DROPS_LEVEL),"2d8",45,'W',55,14,23,75,0,0,0,0,0},
+ {(ASLEEP|IMITATES),"4d6",42,'X',110,16,25,75,0,0,0,0,0},
+ {(ASLEEP|WANDERS),"3d6",35,'Y',50,11,20,80,0,20,0,0,0},
+ {(ASLEEP|WAKENS|WANDERS),"1d7",21,'Z',8,5,14,69,0,0,0,0,0}
+};
+
+extern short cur_level;
+extern short cur_room, party_room;
+extern short blind, halluc, haste_self;
+extern boolean detect_monster, see_invisible, r_see_invisible;
+extern short stealthy;
+
+put_mons()
+{
+ short i;
+ short n;
+ object *monster;
+ short row, col;
+
+ n = get_rand(4, 6);
+
+ for (i = 0; i < n; i++) {
+ monster = gr_monster((object *) 0, 0);
+ if ((monster->m_flags & WANDERS) && coin_toss()) {
+ wake_up(monster);
+ }
+ gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
+ put_m_at(row, col, monster);
+ }
+}
+
+object *
+gr_monster(monster, mn)
+register object *monster;
+register mn;
+{
+ if (!monster) {
+ monster = alloc_object();
+
+ for (;;) {
+ mn = get_rand(0, MONSTERS-1);
+ if ((cur_level >= mon_tab[mn].first_level) &&
+ (cur_level <= mon_tab[mn].last_level)) {
+ break;
+ }
+ }
+ }
+ *monster = mon_tab[mn];
+ if (monster->m_flags & IMITATES) {
+ monster->disguise = gr_obj_char();
+ }
+ if (cur_level > (AMULET_LEVEL + 2)) {
+ monster->m_flags |= HASTED;
+ }
+ monster->trow = NO_ROOM;
+ return(monster);
+}
+
+mv_mons()
+{
+ register object *monster, *next_monster;
+ boolean flew;
+
+ if (haste_self % 2) {
+ return;
+ }
+
+ monster = level_monsters.next_monster;
+
+ while (monster) {
+ next_monster = monster->next_monster;
+ mon_disappeared = 0;
+ if (monster->m_flags & HASTED) {
+ mv_1_monster(monster, rogue.row, rogue.col);
+ if (mon_disappeared) {
+ goto NM;
+ }
+ } else if (monster->m_flags & SLOWED) {
+ monster->slowed_toggle = !monster->slowed_toggle;
+ if (monster->slowed_toggle) {
+ goto NM;
+ }
+ }
+ if ((monster->m_flags & CONFUSED) && move_confused(monster)) {
+ goto NM;
+ }
+ flew = 0;
+ if ( (monster->m_flags & FLIES) &&
+ !(monster->m_flags & NAPPING) &&
+ !mon_can_go(monster, rogue.row, rogue.col)) {
+ flew = 1;
+ mv_1_monster(monster, rogue.row, rogue.col);
+ if (mon_disappeared) {
+ goto NM;
+ }
+ }
+ if (!(flew && mon_can_go(monster, rogue.row, rogue.col))) {
+ mv_1_monster(monster, rogue.row, rogue.col);
+ }
+NM: monster = next_monster;
+ }
+}
+
+party_monsters(rn, n)
+int rn, n;
+{
+ short i, j;
+ short row, col;
+ object *monster;
+ boolean found;
+
+ n += n;
+
+ for (i = 0; i < MONSTERS; i++) {
+ mon_tab[i].first_level -= (cur_level % 3);
+ }
+ for (i = 0; i < n; i++) {
+ if (no_room_for_monster(rn)) {
+ break;
+ }
+ for (j = found = 0; ((!found) && (j < 250)); j++) {
+ row = get_rand(rooms[rn].top_row+1,
+ rooms[rn].bottom_row-1);
+ col = get_rand(rooms[rn].left_col+1,
+ rooms[rn].right_col-1);
+ if ((!(dungeon[row][col] & MONSTER)) &&
+ (dungeon[row][col] & (FLOOR | TUNNEL))) {
+ found = 1;
+ }
+ }
+ if (found) {
+ monster = gr_monster((object *) 0, 0);
+ if (!(monster->m_flags & IMITATES)) {
+ monster->m_flags |= WAKENS;
+ }
+ put_m_at(row, col, monster);
+ }
+ }
+ for (i = 0; i < MONSTERS; i++) {
+ mon_tab[i].first_level += (cur_level % 3);
+ }
+}
+
+gmc_row_col(row, col)
+register row, col;
+{
+ register object *monster;
+
+ if (monster = object_at(&level_monsters, row, col)) {
+ if ((!(detect_monster || see_invisible || r_see_invisible) &&
+ (monster->m_flags & INVISIBLE)) || blind) {
+ return(monster->trail_char);
+ }
+ if (monster->m_flags & IMITATES) {
+ return(monster->disguise);
+ }
+ return(monster->m_char);
+ } else {
+ return('&'); /* BUG if this ever happens */
+ }
+}
+
+gmc(monster)
+object *monster;
+{
+ if ((!(detect_monster || see_invisible || r_see_invisible) &&
+ (monster->m_flags & INVISIBLE))
+ || blind) {
+ return(monster->trail_char);
+ }
+ if (monster->m_flags & IMITATES) {
+ return(monster->disguise);
+ }
+ return(monster->m_char);
+}
+
+mv_1_monster(monster, row, col)
+register object *monster;
+short row, col;
+{
+ short i, n;
+ boolean tried[6];
+
+ if (monster->m_flags & ASLEEP) {
+ if (monster->m_flags & NAPPING) {
+ if (--monster->nap_length <= 0) {
+ monster->m_flags &= (~(NAPPING | ASLEEP));
+ }
+ return;
+ }
+ if ((monster->m_flags & WAKENS) &&
+ rogue_is_around(monster->row, monster->col) &&
+ rand_percent(((stealthy > 0) ?
+ (WAKE_PERCENT / (STEALTH_FACTOR + stealthy)) :
+ WAKE_PERCENT))) {
+ wake_up(monster);
+ }
+ return;
+ } else if (monster->m_flags & ALREADY_MOVED) {
+ monster->m_flags &= (~ALREADY_MOVED);
+ return;
+ }
+ if ((monster->m_flags & FLITS) && flit(monster)) {
+ return;
+ }
+ if ((monster->m_flags & STATIONARY) &&
+ (!mon_can_go(monster, rogue.row, rogue.col))) {
+ return;
+ }
+ if (monster->m_flags & FREEZING_ROGUE) {
+ return;
+ }
+ if ((monster->m_flags & CONFUSES) && m_confuse(monster)) {
+ return;
+ }
+ if (mon_can_go(monster, rogue.row, rogue.col)) {
+ mon_hit(monster);
+ return;
+ }
+ if ((monster->m_flags & FLAMES) && flame_broil(monster)) {
+ return;
+ }
+ if ((monster->m_flags & SEEKS_GOLD) && seek_gold(monster)) {
+ return;
+ }
+ if ((monster->trow == monster->row) &&
+ (monster->tcol == monster->col)) {
+ monster->trow = NO_ROOM;
+ } else if (monster->trow != NO_ROOM) {
+ row = monster->trow;
+ col = monster->tcol;
+ }
+ if (monster->row > row) {
+ row = monster->row - 1;
+ } else if (monster->row < row) {
+ row = monster->row + 1;
+ }
+ if ((dungeon[row][monster->col] & DOOR) &&
+ mtry(monster, row, monster->col)) {
+ return;
+ }
+ if (monster->col > col) {
+ col = monster->col - 1;
+ } else if (monster->col < col) {
+ col = monster->col + 1;
+ }
+ if ((dungeon[monster->row][col] & DOOR) &&
+ mtry(monster, monster->row, col)) {
+ return;
+ }
+ if (mtry(monster, row, col)) {
+ return;
+ }
+
+ for (i = 0; i <= 5; i++) tried[i] = 0;
+
+ for (i = 0; i < 6; i++) {
+NEXT_TRY: n = get_rand(0, 5);
+ switch(n) {
+ case 0:
+ if (!tried[n] && mtry(monster, row, monster->col-1)) {
+ goto O;
+ }
+ break;
+ case 1:
+ if (!tried[n] && mtry(monster, row, monster->col)) {
+ goto O;
+ }
+ break;
+ case 2:
+ if (!tried[n] && mtry(monster, row, monster->col+1)) {
+ goto O;
+ }
+ break;
+ case 3:
+ if (!tried[n] && mtry(monster, monster->row-1, col)) {
+ goto O;
+ }
+ break;
+ case 4:
+ if (!tried[n] && mtry(monster, monster->row, col)) {
+ goto O;
+ }
+ break;
+ case 5:
+ if (!tried[n] && mtry(monster, monster->row+1, col)) {
+ goto O;
+ }
+ break;
+ }
+ if (!tried[n]) {
+ tried[n] = 1;
+ } else {
+ goto NEXT_TRY;
+ }
+ }
+O:
+ if ((monster->row == monster->o_row) && (monster->col == monster->o_col)) {
+ if (++(monster->o) > 4) {
+ if ((monster->trow == NO_ROOM) &&
+ (!mon_sees(monster, rogue.row, rogue.col))) {
+ monster->trow = get_rand(1, (DROWS - 2));
+ monster->tcol = get_rand(0, (DCOLS - 1));
+ } else {
+ monster->trow = NO_ROOM;
+ monster->o = 0;
+ }
+ }
+ } else {
+ monster->o_row = monster->row;
+ monster->o_col = monster->col;
+ monster->o = 0;
+ }
+}
+
+mtry(monster, row, col)
+register object *monster;
+register short row, col;
+{
+ if (mon_can_go(monster, row, col)) {
+ move_mon_to(monster, row, col);
+ return(1);
+ }
+ return(0);
+}
+
+move_mon_to(monster, row, col)
+register object *monster;
+register short row, col;
+{
+ short c;
+ register mrow, mcol;
+
+ mrow = monster->row;
+ mcol = monster->col;
+
+ dungeon[mrow][mcol] &= ~MONSTER;
+ dungeon[row][col] |= MONSTER;
+
+ c = mvinch(mrow, mcol);
+
+ if ((c >= 'A') && (c <= 'Z')) {
+ if (!detect_monster) {
+ mvaddch(mrow, mcol, monster->trail_char);
+ } else {
+ if (rogue_can_see(mrow, mcol)) {
+ mvaddch(mrow, mcol, monster->trail_char);
+ } else {
+ if (monster->trail_char == '.') {
+ monster->trail_char = ' ';
+ }
+ mvaddch(mrow, mcol, monster->trail_char);
+ }
+ }
+ }
+ monster->trail_char = mvinch(row, col);
+ if (!blind && (detect_monster || rogue_can_see(row, col))) {
+ if ((!(monster->m_flags & INVISIBLE) ||
+ (detect_monster || see_invisible || r_see_invisible))) {
+ mvaddch(row, col, gmc(monster));
+ }
+ }
+ if ((dungeon[row][col] & DOOR) &&
+ (get_room_number(row, col) != cur_room) &&
+ (dungeon[mrow][mcol] == FLOOR) && !blind) {
+ mvaddch(mrow, mcol, ' ');
+ }
+ if (dungeon[row][col] & DOOR) {
+ dr_course(monster, ((dungeon[mrow][mcol] & TUNNEL) ? 1 : 0),
+ row, col);
+ } else {
+ monster->row = row;
+ monster->col = col;
+ }
+}
+
+mon_can_go(monster, row, col)
+register object *monster;
+register short row, col;
+{
+ object *obj;
+ short dr, dc;
+
+ dr = monster->row - row; /* check if move distance > 1 */
+ if ((dr >= 2) || (dr <= -2)) {
+ return(0);
+ }
+ dc = monster->col - col;
+ if ((dc >= 2) || (dc <= -2)) {
+ return(0);
+ }
+ if ((!dungeon[monster->row][col]) || (!dungeon[row][monster->col])) {
+ return(0);
+ }
+ if ((!is_passable(row, col)) || (dungeon[row][col] & MONSTER)) {
+ return(0);
+ }
+ if ((monster->row!=row)&&(monster->col!=col)&&((dungeon[row][col]&DOOR) ||
+ (dungeon[monster->row][monster->col]&DOOR))) {
+ return(0);
+ }
+ if (!(monster->m_flags & (FLITS | CONFUSED | CAN_FLIT)) &&
+ (monster->trow == NO_ROOM)) {
+ if ((monster->row < rogue.row) && (row < monster->row)) return(0);
+ if ((monster->row > rogue.row) && (row > monster->row)) return(0);
+ if ((monster->col < rogue.col) && (col < monster->col)) return(0);
+ if ((monster->col > rogue.col) && (col > monster->col)) return(0);
+ }
+ if (dungeon[row][col] & OBJECT) {
+ obj = object_at(&level_objects, row, col);
+ if ((obj->what_is == SCROL) && (obj->which_kind == SCARE_MONSTER)) {
+ return(0);
+ }
+ }
+ return(1);
+}
+
+wake_up(monster)
+object *monster;
+{
+ if (!(monster->m_flags & NAPPING)) {
+ monster->m_flags &= (~(ASLEEP | IMITATES | WAKENS));
+ }
+}
+
+wake_room(rn, entering, row, col)
+short rn;
+boolean entering;
+short row, col;
+{
+ object *monster;
+ short wake_percent;
+ boolean in_room;
+
+ wake_percent = (rn == party_room) ? PARTY_WAKE_PERCENT : WAKE_PERCENT;
+ if (stealthy > 0) {
+ wake_percent /= (STEALTH_FACTOR + stealthy);
+ }
+
+ monster = level_monsters.next_monster;
+
+ while (monster) {
+ in_room = (rn == get_room_number(monster->row, monster->col));
+ if (in_room) {
+ if (entering) {
+ monster->trow = NO_ROOM;
+ } else {
+ monster->trow = row;
+ monster->tcol = col;
+ }
+ }
+ if ((monster->m_flags & WAKENS) &&
+ (rn == get_room_number(monster->row, monster->col))) {
+ if (rand_percent(wake_percent)) {
+ wake_up(monster);
+ }
+ }
+ monster = monster->next_monster;
+ }
+}
+
+char *
+mon_name(monster)
+object *monster;
+{
+ short ch;
+
+ if (blind || ((monster->m_flags & INVISIBLE) &&
+ !(detect_monster || see_invisible || r_see_invisible))) {
+ return("something");
+ }
+ if (halluc) {
+ ch = get_rand('A', 'Z') - 'A';
+ return(m_names[ch]);
+ }
+ ch = monster->m_char - 'A';
+ return(m_names[ch]);
+}
+
+rogue_is_around(row, col)
+register row, col;
+{
+ short rdif, cdif, retval;
+
+ rdif = row - rogue.row;
+ cdif = col - rogue.col;
+
+ retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
+ return(retval);
+}
+
+wanderer()
+{
+ object *monster;
+ short row, col, i;
+ boolean found = 0;
+
+ for (i = 0; ((i < 15) && (!found)); i++) {
+ monster = gr_monster((object *) 0, 0);
+ if (!(monster->m_flags & (WAKENS | WANDERS))) {
+ free_object(monster);
+ } else {
+ found = 1;
+ }
+ }
+ if (found) {
+ found = 0;
+ wake_up(monster);
+ for (i = 0; ((i < 25) && (!found)); i++) {
+ gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
+ if (!rogue_can_see(row, col)) {
+ put_m_at(row, col, monster);
+ found = 1;
+ }
+ }
+ if (!found) {
+ free_object(monster);
+ }
+ }
+}
+
+show_monsters()
+{
+ object *monster;
+
+ detect_monster = 1;
+
+ if (blind) {
+ return;
+ }
+ monster = level_monsters.next_monster;
+
+ while (monster) {
+ mvaddch(monster->row, monster->col, monster->m_char);
+ if (monster->m_flags & IMITATES) {
+ monster->m_flags &= (~IMITATES);
+ monster->m_flags |= WAKENS;
+ }
+ monster = monster->next_monster;
+ }
+}
+
+create_monster()
+{
+ short row, col;
+ short i;
+ boolean found = 0;
+ object *monster;
+
+ row = rogue.row;
+ col = rogue.col;
+
+ for (i = 0; i < 9; i++) {
+ rand_around(i, &row, &col);
+ if (((row == rogue.row) && (col = rogue.col)) ||
+ (row < MIN_ROW) || (row > (DROWS-2)) ||
+ (col < 0) || (col > (DCOLS-1))) {
+ continue;
+ }
+ if ((!(dungeon[row][col] & MONSTER)) &&
+ (dungeon[row][col] & (FLOOR|TUNNEL|STAIRS|DOOR))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ monster = gr_monster((object *) 0, 0);
+ put_m_at(row, col, monster);
+ mvaddch(row, col, gmc(monster));
+ if (monster->m_flags & (WANDERS | WAKENS)) {
+ wake_up(monster);
+ }
+ } else {
+ message("you hear a faint cry of anguish in the distance", 0);
+ }
+}
+
+put_m_at(row, col, monster)
+short row, col;
+object *monster;
+{
+ monster->row = row;
+ monster->col = col;
+ dungeon[row][col] |= MONSTER;
+ monster->trail_char = mvinch(row, col);
+ (void) add_to_pack(monster, &level_monsters, 0);
+ aim_monster(monster);
+}
+
+aim_monster(monster)
+object *monster;
+{
+ short i, rn, d, r;
+
+ rn = get_room_number(monster->row, monster->col);
+ r = get_rand(0, 12);
+
+ for (i = 0; i < 4; i++) {
+ d = (r + i) % 4;
+ if (rooms[rn].doors[d].oth_room != NO_ROOM) {
+ monster->trow = rooms[rn].doors[d].door_row;
+ monster->tcol = rooms[rn].doors[d].door_col;
+ break;
+ }
+ }
+}
+
+rogue_can_see(row, col)
+register row, col;
+{
+ register retval;
+
+ retval = !blind &&
+ (((get_room_number(row, col) == cur_room) &&
+ !(rooms[cur_room].is_room & R_MAZE)) ||
+ rogue_is_around(row, col));
+
+ return(retval);
+}
+
+move_confused(monster)
+object *monster;
+{
+ short i, row, col;
+
+ if (!(monster->m_flags & ASLEEP)) {
+ if (--monster->moves_confused <= 0) {
+ monster->m_flags &= (~CONFUSED);
+ }
+ if (monster->m_flags & STATIONARY) {
+ return(coin_toss() ? 1 : 0);
+ } else if (rand_percent(15)) {
+ return(1);
+ }
+ row = monster->row;
+ col = monster->col;
+
+ for (i = 0; i < 9; i++) {
+ rand_around(i, &row, &col);
+ if ((row == rogue.row) && (col == rogue.col)) {
+ return(0);
+ }
+ if (mtry(monster, row, col)) {
+ return(1);
+ }
+ }
+ }
+ return(0);
+}
+
+flit(monster)
+object *monster;
+{
+ short i, row, col;
+
+ if (!rand_percent(FLIT_PERCENT + ((monster->m_flags & FLIES) ? 20 : 0))) {
+ return(0);
+ }
+ if (rand_percent(10)) {
+ return(1);
+ }
+ row = monster->row;
+ col = monster->col;
+
+ for (i = 0; i < 9; i++) {
+ rand_around(i, &row, &col);
+ if ((row == rogue.row) && (col == rogue.col)) {
+ continue;
+ }
+ if (mtry(monster, row, col)) {
+ return(1);
+ }
+ }
+ return(1);
+}
+
+gr_obj_char()
+{
+ short r;
+ char *rs = "%!?]=/):*";
+
+ r = get_rand(0, 8);
+
+ return(rs[r]);
+}
+
+no_room_for_monster(rn)
+int rn;
+{
+ short i, j;
+
+ for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
+ for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
+ if (!(dungeon[i][j] & MONSTER)) {
+ return(0);
+ }
+ }
+ }
+ return(1);
+}
+
+aggravate()
+{
+ object *monster;
+
+ message("you hear a high pitched humming noise", 0);
+
+ monster = level_monsters.next_monster;
+
+ while (monster) {
+ wake_up(monster);
+ monster->m_flags &= (~IMITATES);
+ if (rogue_can_see(monster->row, monster->col)) {
+ mvaddch(monster->row, monster->col, monster->m_char);
+ }
+ monster = monster->next_monster;
+ }
+}
+
+boolean
+mon_sees(monster, row, col)
+object *monster;
+{
+ short rn, rdif, cdif, retval;
+
+ rn = get_room_number(row, col);
+
+ if ( (rn != NO_ROOM) &&
+ (rn == get_room_number(monster->row, monster->col)) &&
+ !(rooms[rn].is_room & R_MAZE)) {
+ return(1);
+ }
+ rdif = row - monster->row;
+ cdif = col - monster->col;
+
+ retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
+ return(retval);
+}
+
+mv_aquatars()
+{
+ object *monster;
+
+ monster = level_monsters.next_monster;
+
+ while (monster) {
+ if ((monster->m_char == 'A') &&
+ mon_can_go(monster, rogue.row, rogue.col)) {
+ mv_1_monster(monster, rogue.row, rogue.col);
+ monster->m_flags |= ALREADY_MOVED;
+ }
+ monster = monster->next_monster;
+ }
+}
diff --git a/rogue/move.c b/rogue/move.c
new file mode 100644
index 00000000..d8da6022
--- /dev/null
+++ b/rogue/move.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)move.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * move.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+short m_moves = 0;
+boolean jump = 0;
+char *you_can_move_again = "you can move again";
+
+extern short cur_room, halluc, blind, levitate;
+extern short cur_level, max_level;
+extern short bear_trap, haste_self, confused;
+extern short e_rings, regeneration, auto_search;
+extern char hunger_str[];
+extern boolean being_held, interrupted, r_teleport, passgo;
+
+one_move_rogue(dirch, pickup)
+short dirch, pickup;
+{
+ short row, col;
+ object *obj;
+ char desc[DCOLS];
+ short n, status, d;
+
+ row = rogue.row;
+ col = rogue.col;
+
+ if (confused) {
+ dirch = gr_dir();
+ }
+ (void) is_direction(dirch, &d);
+ get_dir_rc(d, &row, &col, 1);
+
+ if (!can_move(rogue.row, rogue.col, row, col)) {
+ return(MOVE_FAILED);
+ }
+ if (being_held || bear_trap) {
+ if (!(dungeon[row][col] & MONSTER)) {
+ if (being_held) {
+ message("you are being held", 1);
+ } else {
+ message("you are still stuck in the bear trap", 0);
+ (void) reg_move();
+ }
+ return(MOVE_FAILED);
+ }
+ }
+ if (r_teleport) {
+ if (rand_percent(R_TELE_PERCENT)) {
+ tele();
+ return(STOPPED_ON_SOMETHING);
+ }
+ }
+ if (dungeon[row][col] & MONSTER) {
+ rogue_hit(object_at(&level_monsters, row, col), 0);
+ (void) reg_move();
+ return(MOVE_FAILED);
+ }
+ if (dungeon[row][col] & DOOR) {
+ if (cur_room == PASSAGE) {
+ cur_room = get_room_number(row, col);
+ light_up_room(cur_room);
+ wake_room(cur_room, 1, row, col);
+ } else {
+ light_passage(row, col);
+ }
+ } else if ((dungeon[rogue.row][rogue.col] & DOOR) &&
+ (dungeon[row][col] & TUNNEL)) {
+ light_passage(row, col);
+ wake_room(cur_room, 0, rogue.row, rogue.col);
+ darken_room(cur_room);
+ cur_room = PASSAGE;
+ } else if (dungeon[row][col] & TUNNEL) {
+ light_passage(row, col);
+ }
+ mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col));
+ mvaddch(row, col, rogue.fchar);
+
+ if (!jump) {
+ refresh();
+ }
+ rogue.row = row;
+ rogue.col = col;
+ if (dungeon[row][col] & OBJECT) {
+ if (levitate && pickup) {
+ return(STOPPED_ON_SOMETHING);
+ }
+ if (pickup && !levitate) {
+ if (obj = pick_up(row, col, &status)) {
+ get_desc(obj, desc);
+ if (obj->what_is == GOLD) {
+ free_object(obj);
+ goto NOT_IN_PACK;
+ }
+ } else if (!status) {
+ goto MVED;
+ } else {
+ goto MOVE_ON;
+ }
+ } else {
+MOVE_ON:
+ obj = object_at(&level_objects, row, col);
+ (void) strcpy(desc, "moved onto ");
+ get_desc(obj, desc+11);
+ goto NOT_IN_PACK;
+ }
+ n = strlen(desc);
+ desc[n] = '(';
+ desc[n+1] = obj->ichar;
+ desc[n+2] = ')';
+ desc[n+3] = 0;
+NOT_IN_PACK:
+ message(desc, 1);
+ (void) reg_move();
+ return(STOPPED_ON_SOMETHING);
+ }
+ if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) {
+ if ((!levitate) && (dungeon[row][col] & TRAP)) {
+ trap_player(row, col);
+ }
+ (void) reg_move();
+ return(STOPPED_ON_SOMETHING);
+ }
+MVED: if (reg_move()) { /* fainted from hunger */
+ return(STOPPED_ON_SOMETHING);
+ }
+ return((confused ? STOPPED_ON_SOMETHING : MOVED));
+}
+
+multiple_move_rogue(dirch)
+short dirch;
+{
+ short row, col;
+ short m;
+
+ switch(dirch) {
+ case '\010':
+ case '\012':
+ case '\013':
+ case '\014':
+ case '\031':
+ case '\025':
+ case '\016':
+ case '\002':
+ do {
+ row = rogue.row;
+ col = rogue.col;
+ if (((m = one_move_rogue((dirch + 96), 1)) == MOVE_FAILED) ||
+ (m == STOPPED_ON_SOMETHING) ||
+ interrupted) {
+ break;
+ }
+ } while (!next_to_something(row, col));
+ if ( (!interrupted) && passgo && (m == MOVE_FAILED) &&
+ (dungeon[rogue.row][rogue.col] & TUNNEL)) {
+ turn_passage(dirch + 96, 0);
+ }
+ break;
+ case 'H':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'B':
+ case 'Y':
+ case 'U':
+ case 'N':
+ while ((!interrupted) && (one_move_rogue((dirch + 32), 1) == MOVED)) ;
+
+ if ( (!interrupted) && passgo &&
+ (dungeon[rogue.row][rogue.col] & TUNNEL)) {
+ turn_passage(dirch + 32, 1);
+ }
+ break;
+ }
+}
+
+is_passable(row, col)
+register row, col;
+{
+ if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) ||
+ (col > (DCOLS-1))) {
+ return(0);
+ }
+ if (dungeon[row][col] & HIDDEN) {
+ return((dungeon[row][col] & TRAP) ? 1 : 0);
+ }
+ return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP));
+}
+
+next_to_something(drow, dcol)
+register drow, dcol;
+{
+ short i, j, i_end, j_end, row, col;
+ short pass_count = 0;
+ unsigned short s;
+
+ if (confused) {
+ return(1);
+ }
+ if (blind) {
+ return(0);
+ }
+ i_end = (rogue.row < (DROWS-2)) ? 1 : 0;
+ j_end = (rogue.col < (DCOLS-1)) ? 1 : 0;
+
+ for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
+ for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) {
+ if ((i == 0) && (j == 0)) {
+ continue;
+ }
+ if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) {
+ continue;
+ }
+ row = rogue.row + i;
+ col = rogue.col + j;
+ s = dungeon[row][col];
+ if (s & HIDDEN) {
+ continue;
+ }
+ /* If the rogue used to be right, up, left, down, or right of
+ * row,col, and now isn't, then don't stop */
+ if (s & (MONSTER | OBJECT | STAIRS)) {
+ if (((row == drow) || (col == dcol)) &&
+ (!((row == rogue.row) || (col == rogue.col)))) {
+ continue;
+ }
+ return(1);
+ }
+ if (s & TRAP) {
+ if (!(s & HIDDEN)) {
+ if (((row == drow) || (col == dcol)) &&
+ (!((row == rogue.row) || (col == rogue.col)))) {
+ continue;
+ }
+ return(1);
+ }
+ }
+ if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) {
+ if (++pass_count > 1) {
+ return(1);
+ }
+ }
+ if ((s & DOOR) && ((i == 0) || (j == 0))) {
+ return(1);
+ }
+ }
+ }
+ return(0);
+}
+
+can_move(row1, col1, row2, col2)
+{
+ if (!is_passable(row2, col2)) {
+ return(0);
+ }
+ if ((row1 != row2) && (col1 != col2)) {
+ if ((dungeon[row1][col1] & DOOR) || (dungeon[row2][col2] & DOOR)) {
+ return(0);
+ }
+ if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) {
+ return(0);
+ }
+ }
+ return(1);
+}
+
+move_onto()
+{
+ short ch, d;
+ boolean first_miss = 1;
+
+ while (!is_direction(ch = rgetchar(), &d)) {
+ sound_bell();
+ if (first_miss) {
+ message("direction? ", 0);
+ first_miss = 0;
+ }
+ }
+ check_message();
+ if (ch != CANCEL) {
+ (void) one_move_rogue(ch, 0);
+ }
+}
+
+boolean
+is_direction(c, d)
+short c;
+short *d;
+{
+ switch(c) {
+ case 'h':
+ *d = LEFT;
+ break;
+ case 'j':
+ *d = DOWN;
+ break;
+ case 'k':
+ *d = UPWARD;
+ break;
+ case 'l':
+ *d = RIGHT;
+ break;
+ case 'b':
+ *d = DOWNLEFT;
+ break;
+ case 'y':
+ *d = UPLEFT;
+ break;
+ case 'u':
+ *d = UPRIGHT;
+ break;
+ case 'n':
+ *d = DOWNRIGHT;
+ break;
+ case CANCEL:
+ break;
+ default:
+ return(0);
+ }
+ return(1);
+}
+
+boolean
+check_hunger(msg_only)
+boolean msg_only;
+{
+ register short i, n;
+ boolean fainted = 0;
+
+ if (rogue.moves_left == HUNGRY) {
+ (void) strcpy(hunger_str, "hungry");
+ message(hunger_str, 0);
+ print_stats(STAT_HUNGER);
+ }
+ if (rogue.moves_left == WEAK) {
+ (void) strcpy(hunger_str, "weak");
+ message(hunger_str, 1);
+ print_stats(STAT_HUNGER);
+ }
+ if (rogue.moves_left <= FAINT) {
+ if (rogue.moves_left == FAINT) {
+ (void) strcpy(hunger_str, "faint");
+ message(hunger_str, 1);
+ print_stats(STAT_HUNGER);
+ }
+ n = get_rand(0, (FAINT - rogue.moves_left));
+ if (n > 0) {
+ fainted = 1;
+ if (rand_percent(40)) {
+ rogue.moves_left++;
+ }
+ message("you faint", 1);
+ for (i = 0; i < n; i++) {
+ if (coin_toss()) {
+ mv_mons();
+ }
+ }
+ message(you_can_move_again, 1);
+ }
+ }
+ if (msg_only) {
+ return(fainted);
+ }
+ if (rogue.moves_left <= STARVE) {
+ killed_by((object *) 0, STARVATION);
+ }
+
+ switch(e_rings) {
+ /*case -2:
+ Subtract 0, i.e. do nothing.
+ break;*/
+ case -1:
+ rogue.moves_left -= (rogue.moves_left % 2);
+ break;
+ case 0:
+ rogue.moves_left--;
+ break;
+ case 1:
+ rogue.moves_left--;
+ (void) check_hunger(1);
+ rogue.moves_left -= (rogue.moves_left % 2);
+ break;
+ case 2:
+ rogue.moves_left--;
+ (void) check_hunger(1);
+ rogue.moves_left--;
+ break;
+ }
+ return(fainted);
+}
+
+boolean
+reg_move()
+{
+ boolean fainted;
+
+ if ((rogue.moves_left <= HUNGRY) || (cur_level >= max_level)) {
+ fainted = check_hunger(0);
+ } else {
+ fainted = 0;
+ }
+
+ mv_mons();
+
+ if (++m_moves >= 120) {
+ m_moves = 0;
+ wanderer();
+ }
+ if (halluc) {
+ if (!(--halluc)) {
+ unhallucinate();
+ } else {
+ hallucinate();
+ }
+ }
+ if (blind) {
+ if (!(--blind)) {
+ unblind();
+ }
+ }
+ if (confused) {
+ if (!(--confused)) {
+ unconfuse();
+ }
+ }
+ if (bear_trap) {
+ bear_trap--;
+ }
+ if (levitate) {
+ if (!(--levitate)) {
+ message("you float gently to the ground", 1);
+ if (dungeon[rogue.row][rogue.col] & TRAP) {
+ trap_player(rogue.row, rogue.col);
+ }
+ }
+ }
+ if (haste_self) {
+ if (!(--haste_self)) {
+ message("you feel yourself slowing down", 0);
+ }
+ }
+ heal();
+ if (auto_search > 0) {
+ search(auto_search, auto_search);
+ }
+ return(fainted);
+}
+
+rest(count)
+{
+ int i;
+
+ interrupted = 0;
+
+ for (i = 0; i < count; i++) {
+ if (interrupted) {
+ break;
+ }
+ (void) reg_move();
+ }
+}
+
+gr_dir()
+{
+ short d;
+
+ d = get_rand(1, 8);
+
+ switch(d) {
+ case 1:
+ d = 'j';
+ break;
+ case 2:
+ d = 'k';
+ break;
+ case 3:
+ d = 'l';
+ break;
+ case 4:
+ d = 'h';
+ break;
+ case 5:
+ d = 'y';
+ break;
+ case 6:
+ d = 'u';
+ break;
+ case 7:
+ d = 'b';
+ break;
+ case 8:
+ d = 'n';
+ break;
+ }
+ return(d);
+}
+
+heal()
+{
+ static short heal_exp = -1, n, c = 0;
+ static boolean alt;
+
+ if (rogue.hp_current == rogue.hp_max) {
+ c = 0;
+ return;
+ }
+ if (rogue.exp != heal_exp) {
+ heal_exp = rogue.exp;
+
+ switch(heal_exp) {
+ case 1:
+ n = 20;
+ break;
+ case 2:
+ n = 18;
+ break;
+ case 3:
+ n = 17;
+ break;
+ case 4:
+ n = 14;
+ break;
+ case 5:
+ n = 13;
+ break;
+ case 6:
+ n = 10;
+ break;
+ case 7:
+ n = 9;
+ break;
+ case 8:
+ n = 8;
+ break;
+ case 9:
+ n = 7;
+ break;
+ case 10:
+ n = 4;
+ break;
+ case 11:
+ n = 3;
+ break;
+ case 12:
+ default:
+ n = 2;
+ }
+ }
+ if (++c >= n) {
+ c = 0;
+ rogue.hp_current++;
+ if (alt = !alt) {
+ rogue.hp_current++;
+ }
+ if ((rogue.hp_current += regeneration) > rogue.hp_max) {
+ rogue.hp_current = rogue.hp_max;
+ }
+ print_stats(STAT_HP);
+ }
+}
+
+static boolean
+can_turn(nrow, ncol)
+short nrow, ncol;
+{
+ if ((dungeon[nrow][ncol] & TUNNEL) && is_passable(nrow, ncol)) {
+ return(1);
+ }
+ return(0);
+}
+
+turn_passage(dir, fast)
+short dir;
+boolean fast;
+{
+ short crow = rogue.row, ccol = rogue.col, turns = 0;
+ short ndir;
+
+ if ((dir != 'h') && can_turn(crow, ccol + 1)) {
+ turns++;
+ ndir = 'l';
+ }
+ if ((dir != 'l') && can_turn(crow, ccol - 1)) {
+ turns++;
+ ndir = 'h';
+ }
+ if ((dir != 'k') && can_turn(crow + 1, ccol)) {
+ turns++;
+ ndir = 'j';
+ }
+ if ((dir != 'j') && can_turn(crow - 1, ccol)) {
+ turns++;
+ ndir = 'k';
+ }
+ if (turns == 1) {
+ multiple_move_rogue(ndir - (fast ? 32 : 96));
+ }
+}
diff --git a/rogue/object.c b/rogue/object.c
new file mode 100644
index 00000000..032cdd3e
--- /dev/null
+++ b/rogue/object.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)object.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * object.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+object level_objects;
+unsigned short dungeon[DROWS][DCOLS];
+short foods = 0;
+object *free_list = (object *) 0;
+char *fruit = (char *) 0;
+
+fighter rogue = {
+ INIT_AW, /* armor, weapon */
+ INIT_RINGS, /* rings */
+ INIT_HP, /* Hp current,max */
+ INIT_STR, /* Str current,max */
+ INIT_PACK, /* pack */
+ INIT_GOLD, /* gold */
+ INIT_EXP, /* exp level,points */
+ 0, 0, /* row, col */
+ INIT_CHAR, /* char */
+ INIT_MOVES /* moves */
+};
+
+struct id id_potions[POTIONS] = {
+{100, "blue \0 ", "of increase strength ", 0},
+{250, "red \0 ", "of restore strength ", 0},
+{100, "green \0 ", "of healing ", 0},
+{200, "grey \0 ", "of extra healing ", 0},
+ {10, "brown \0 ", "of poison ", 0},
+{300, "clear \0 ", "of raise level ", 0},
+ {10, "pink \0 ", "of blindness ", 0},
+ {25, "white \0 ", "of hallucination ", 0},
+{100, "purple \0 ", "of detect monster ", 0},
+{100, "black \0 ", "of detect things ", 0},
+ {10, "yellow \0 ", "of confusion ", 0},
+ {80, "plaid \0 ", "of levitation ", 0},
+{150, "burgundy \0 ", "of haste self ", 0},
+{145, "beige \0 ", "of see invisible ", 0}
+};
+
+struct id id_scrolls[SCROLS] = {
+{505, " ", "of protect armor ", 0},
+{200, " ", "of hold monster ", 0},
+{235, " ", "of enchant weapon ", 0},
+{235, " ", "of enchant armor ", 0},
+{175, " ", "of identify ", 0},
+{190, " ", "of teleportation ", 0},
+ {25, " ", "of sleep ", 0},
+{610, " ", "of scare monster ", 0},
+{210, " ", "of remove curse ", 0},
+ {80, " ", "of create monster ",0},
+ {25, " ", "of aggravate monster ",0},
+{180, " ", "of magic mapping ", 0},
+ {90, " ", "of confuse monster ", 0}
+};
+
+struct id id_weapons[WEAPONS] = {
+ {150, "short bow ", "", 0},
+ {8, "darts ", "", 0},
+ {15, "arrows ", "", 0},
+ {27, "daggers ", "", 0},
+ {35, "shurikens ", "", 0},
+ {360, "mace ", "", 0},
+ {470, "long sword ", "", 0},
+ {580, "two-handed sword ", "", 0}
+};
+
+struct id id_armors[ARMORS] = {
+ {300, "leather armor ", "", (UNIDENTIFIED)},
+ {300, "ring mail ", "", (UNIDENTIFIED)},
+ {400, "scale mail ", "", (UNIDENTIFIED)},
+ {500, "chain mail ", "", (UNIDENTIFIED)},
+ {600, "banded mail ", "", (UNIDENTIFIED)},
+ {600, "splint mail ", "", (UNIDENTIFIED)},
+ {700, "plate mail ", "", (UNIDENTIFIED)}
+};
+
+struct id id_wands[WANDS] = {
+ {25, " ", "of teleport away ",0},
+ {50, " ", "of slow monster ", 0},
+ {8, " ", "of invisibility ",0},
+ {55, " ", "of polymorph ",0},
+ {2, " ", "of haste monster ",0},
+ {20, " ", "of magic missile ",0},
+ {20, " ", "of cancellation ",0},
+ {0, " ", "of do nothing ",0},
+ {35, " ", "of drain life ",0},
+ {20, " ", "of cold ",0},
+ {20, " ", "of fire ",0}
+};
+
+struct id id_rings[RINGS] = {
+ {250, " ", "of stealth ",0},
+ {100, " ", "of teleportation ", 0},
+ {255, " ", "of regeneration ",0},
+ {295, " ", "of slow digestion ",0},
+ {200, " ", "of add strength ",0},
+ {250, " ", "of sustain strength ",0},
+ {250, " ", "of dexterity ",0},
+ {25, " ", "of adornment ",0},
+ {300, " ", "of see invisible ",0},
+ {290, " ", "of maintain armor ",0},
+ {270, " ", "of searching ",0},
+};
+
+extern short cur_level, max_level;
+extern short party_room;
+extern char *error_file;
+extern boolean is_wood[];
+
+put_objects()
+{
+ short i, n;
+ object *obj;
+
+ if (cur_level < max_level) {
+ return;
+ }
+ n = coin_toss() ? get_rand(2, 4) : get_rand(3, 5);
+ while (rand_percent(33)) {
+ n++;
+ }
+ if (party_room != NO_ROOM) {
+ make_party();
+ }
+ for (i = 0; i < n; i++) {
+ obj = gr_object();
+ rand_place(obj);
+ }
+ put_gold();
+}
+
+put_gold()
+{
+ short i, j;
+ short row,col;
+ boolean is_maze, is_room;
+
+ for (i = 0; i < MAXROOMS; i++) {
+ is_maze = (rooms[i].is_room & R_MAZE) ? 1 : 0;
+ is_room = (rooms[i].is_room & R_ROOM) ? 1 : 0;
+
+ if (!(is_room || is_maze)) {
+ continue;
+ }
+ if (is_maze || rand_percent(GOLD_PERCENT)) {
+ for (j = 0; j < 50; j++) {
+ row = get_rand(rooms[i].top_row+1,
+ rooms[i].bottom_row-1);
+ col = get_rand(rooms[i].left_col+1,
+ rooms[i].right_col-1);
+ if ((dungeon[row][col] == FLOOR) ||
+ (dungeon[row][col] == TUNNEL)) {
+ plant_gold(row, col, is_maze);
+ break;
+ }
+ }
+ }
+ }
+}
+
+plant_gold(row, col, is_maze)
+short row, col;
+boolean is_maze;
+{
+ object *obj;
+
+ obj = alloc_object();
+ obj->row = row; obj->col = col;
+ obj->what_is = GOLD;
+ obj->quantity = get_rand((2 * cur_level), (16 * cur_level));
+ if (is_maze) {
+ obj->quantity += obj->quantity / 2;
+ }
+ dungeon[row][col] |= OBJECT;
+ (void) add_to_pack(obj, &level_objects, 0);
+}
+
+place_at(obj, row, col)
+object *obj;
+{
+ obj->row = row;
+ obj->col = col;
+ dungeon[row][col] |= OBJECT;
+ (void) add_to_pack(obj, &level_objects, 0);
+}
+
+object *
+object_at(pack, row, col)
+register object *pack;
+short row, col;
+{
+ object *obj = (object *) 0;
+
+ if (dungeon[row][col] & (MONSTER | OBJECT)) {
+ obj = pack->next_object;
+
+ while (obj && ((obj->row != row) || (obj->col != col))) {
+ obj = obj->next_object;
+ }
+ if (!obj) {
+ message("object_at(): inconsistent", 1);
+ }
+ }
+ return(obj);
+}
+
+object *
+get_letter_object(ch)
+{
+ object *obj;
+
+ obj = rogue.pack.next_object;
+
+ while (obj && (obj->ichar != ch)) {
+ obj = obj->next_object;
+ }
+ return(obj);
+}
+
+free_stuff(objlist)
+object *objlist;
+{
+ object *obj;
+
+ while (objlist->next_object) {
+ obj = objlist->next_object;
+ objlist->next_object =
+ objlist->next_object->next_object;
+ free_object(obj);
+ }
+}
+
+char *
+name_of(obj)
+object *obj;
+{
+ char *retstring;
+
+ switch(obj->what_is) {
+ case SCROL:
+ retstring = obj->quantity > 1 ? "scrolls " : "scroll ";
+ break;
+ case POTION:
+ retstring = obj->quantity > 1 ? "potions " : "potion ";
+ break;
+ case FOOD:
+ if (obj->which_kind == RATION) {
+ retstring = "food ";
+ } else {
+ retstring = fruit;
+ }
+ break;
+ case WAND:
+ retstring = is_wood[obj->which_kind] ? "staff " : "wand ";
+ break;
+ case WEAPON:
+ switch(obj->which_kind) {
+ case DART:
+ retstring=obj->quantity > 1 ? "darts " : "dart ";
+ break;
+ case ARROW:
+ retstring=obj->quantity > 1 ? "arrows " : "arrow ";
+ break;
+ case DAGGER:
+ retstring=obj->quantity > 1 ? "daggers " : "dagger ";
+ break;
+ case SHURIKEN:
+ retstring=obj->quantity > 1?"shurikens ":"shuriken ";
+ break;
+ default:
+ retstring = id_weapons[obj->which_kind].title;
+ }
+ break;
+ case ARMOR:
+ retstring = "armor ";
+ break;
+ case RING:
+ retstring = "ring ";
+ break;
+ case AMULET:
+ retstring = "amulet ";
+ break;
+ default:
+ retstring = "unknown ";
+ break;
+ }
+ return(retstring);
+}
+
+object *
+gr_object()
+{
+ object *obj;
+
+ obj = alloc_object();
+
+ if (foods < (cur_level / 3)) {
+ obj->what_is = FOOD;
+ foods++;
+ } else {
+ obj->what_is = gr_what_is();
+ }
+ switch(obj->what_is) {
+ case SCROL:
+ gr_scroll(obj);
+ break;
+ case POTION:
+ gr_potion(obj);
+ break;
+ case WEAPON:
+ gr_weapon(obj, 1);
+ break;
+ case ARMOR:
+ gr_armor(obj);
+ break;
+ case WAND:
+ gr_wand(obj);
+ break;
+ case FOOD:
+ get_food(obj, 0);
+ break;
+ case RING:
+ gr_ring(obj, 1);
+ break;
+ }
+ return(obj);
+}
+
+unsigned short
+gr_what_is()
+{
+ short percent;
+ unsigned short what_is;
+
+ percent = get_rand(1, 91);
+
+ if (percent <= 30) {
+ what_is = SCROL;
+ } else if (percent <= 60) {
+ what_is = POTION;
+ } else if (percent <= 64) {
+ what_is = WAND;
+ } else if (percent <= 74) {
+ what_is = WEAPON;
+ } else if (percent <= 83) {
+ what_is = ARMOR;
+ } else if (percent <= 88) {
+ what_is = FOOD;
+ } else {
+ what_is = RING;
+ }
+ return(what_is);
+}
+
+gr_scroll(obj)
+object *obj;
+{
+ short percent;
+
+ percent = get_rand(0, 91);
+
+ obj->what_is = SCROL;
+
+ if (percent <= 5) {
+ obj->which_kind = PROTECT_ARMOR;
+ } else if (percent <= 10) {
+ obj->which_kind = HOLD_MONSTER;
+ } else if (percent <= 20) {
+ obj->which_kind = CREATE_MONSTER;
+ } else if (percent <= 35) {
+ obj->which_kind = IDENTIFY;
+ } else if (percent <= 43) {
+ obj->which_kind = TELEPORT;
+ } else if (percent <= 50) {
+ obj->which_kind = SLEEP;
+ } else if (percent <= 55) {
+ obj->which_kind = SCARE_MONSTER;
+ } else if (percent <= 64) {
+ obj->which_kind = REMOVE_CURSE;
+ } else if (percent <= 69) {
+ obj->which_kind = ENCH_ARMOR;
+ } else if (percent <= 74) {
+ obj->which_kind = ENCH_WEAPON;
+ } else if (percent <= 80) {
+ obj->which_kind = AGGRAVATE_MONSTER;
+ } else if (percent <= 86) {
+ obj->which_kind = CON_MON;
+ } else {
+ obj->which_kind = MAGIC_MAPPING;
+ }
+}
+
+gr_potion(obj)
+object *obj;
+{
+ short percent;
+
+ percent = get_rand(1, 118);
+
+ obj->what_is = POTION;
+
+ if (percent <= 5) {
+ obj->which_kind = RAISE_LEVEL;
+ } else if (percent <= 15) {
+ obj->which_kind = DETECT_OBJECTS;
+ } else if (percent <= 25) {
+ obj->which_kind = DETECT_MONSTER;
+ } else if (percent <= 35) {
+ obj->which_kind = INCREASE_STRENGTH;
+ } else if (percent <= 45) {
+ obj->which_kind = RESTORE_STRENGTH;
+ } else if (percent <= 55) {
+ obj->which_kind = HEALING;
+ } else if (percent <= 65) {
+ obj->which_kind = EXTRA_HEALING;
+ } else if (percent <= 75) {
+ obj->which_kind = BLINDNESS;
+ } else if (percent <= 85) {
+ obj->which_kind = HALLUCINATION;
+ } else if (percent <= 95) {
+ obj->which_kind = CONFUSION;
+ } else if (percent <= 105) {
+ obj->which_kind = POISON;
+ } else if (percent <= 110) {
+ obj->which_kind = LEVITATION;
+ } else if (percent <= 114) {
+ obj->which_kind = HASTE_SELF;
+ } else {
+ obj->which_kind = SEE_INVISIBLE;
+ }
+}
+
+gr_weapon(obj, assign_wk)
+object *obj;
+int assign_wk;
+{
+ short percent;
+ short i;
+ short blessing, increment;
+
+ obj->what_is = WEAPON;
+ if (assign_wk) {
+ obj->which_kind = get_rand(0, (WEAPONS - 1));
+ }
+ if ((obj->which_kind == ARROW) || (obj->which_kind == DAGGER) ||
+ (obj->which_kind == SHURIKEN) | (obj->which_kind == DART)) {
+ obj->quantity = get_rand(3, 15);
+ obj->quiver = get_rand(0, 126);
+ } else {
+ obj->quantity = 1;
+ }
+ obj->hit_enchant = obj->d_enchant = 0;
+
+ percent = get_rand(1, 96);
+ blessing = get_rand(1, 3);
+
+ if (percent <= 16) {
+ increment = 1;
+ } else if (percent <= 32) {
+ increment = -1;
+ obj->is_cursed = 1;
+ }
+ if (percent <= 32) {
+ for (i = 0; i < blessing; i++) {
+ if (coin_toss()) {
+ obj->hit_enchant += increment;
+ } else {
+ obj->d_enchant += increment;
+ }
+ }
+ }
+ switch(obj->which_kind) {
+ case BOW:
+ case DART:
+ obj->damage = "1d1";
+ break;
+ case ARROW:
+ obj->damage = "1d2";
+ break;
+ case DAGGER:
+ obj->damage = "1d3";
+ break;
+ case SHURIKEN:
+ obj->damage = "1d4";
+ break;
+ case MACE:
+ obj->damage = "2d3";
+ break;
+ case LONG_SWORD:
+ obj->damage = "3d4";
+ break;
+ case TWO_HANDED_SWORD:
+ obj->damage = "4d5";
+ break;
+ }
+}
+
+gr_armor(obj)
+object *obj;
+{
+ short percent;
+ short blessing;
+
+ obj->what_is = ARMOR;
+ obj->which_kind = get_rand(0, (ARMORS - 1));
+ obj->class = obj->which_kind + 2;
+ if ((obj->which_kind == PLATE) || (obj->which_kind == SPLINT)) {
+ obj->class--;
+ }
+ obj->is_protected = 0;
+ obj->d_enchant = 0;
+
+ percent = get_rand(1, 100);
+ blessing = get_rand(1, 3);
+
+ if (percent <= 16) {
+ obj->is_cursed = 1;
+ obj->d_enchant -= blessing;
+ } else if (percent <= 33) {
+ obj->d_enchant += blessing;
+ }
+}
+
+gr_wand(obj)
+object *obj;
+{
+ obj->what_is = WAND;
+ obj->which_kind = get_rand(0, (WANDS - 1));
+ obj->class = get_rand(3, 7);
+}
+
+get_food(obj, force_ration)
+object *obj;
+boolean force_ration;
+{
+ obj->what_is = FOOD;
+
+ if (force_ration || rand_percent(80)) {
+ obj->which_kind = RATION;
+ } else {
+ obj->which_kind = FRUIT;
+ }
+}
+
+put_stairs()
+{
+ short row, col;
+
+ gr_row_col(&row, &col, (FLOOR | TUNNEL));
+ dungeon[row][col] |= STAIRS;
+}
+
+get_armor_class(obj)
+object *obj;
+{
+ if (obj) {
+ return(obj->class + obj->d_enchant);
+ }
+ return(0);
+}
+
+object *
+alloc_object()
+{
+ object *obj;
+
+ if (free_list) {
+ obj = free_list;
+ free_list = free_list->next_object;
+ } else if (!(obj = (object *) md_malloc(sizeof(object)))) {
+ message("cannot allocate object, saving game", 0);
+ save_into_file(error_file);
+ }
+ obj->quantity = 1;
+ obj->ichar = 'L';
+ obj->picked_up = obj->is_cursed = 0;
+ obj->in_use_flags = NOT_USED;
+ obj->identified = UNIDENTIFIED;
+ obj->damage = "1d1";
+ return(obj);
+}
+
+free_object(obj)
+object *obj;
+{
+ obj->next_object = free_list;
+ free_list = obj;
+}
+
+make_party()
+{
+ short n;
+
+ party_room = gr_room();
+
+ n = rand_percent(99) ? party_objects(party_room) : 11;
+ if (rand_percent(99)) {
+ party_monsters(party_room, n);
+ }
+}
+
+show_objects()
+{
+ object *obj;
+ short mc, rc, row, col;
+ object *monster;
+
+ obj = level_objects.next_object;
+
+ while (obj) {
+ row = obj->row;
+ col = obj->col;
+
+ rc = get_mask_char(obj->what_is);
+
+ if (dungeon[row][col] & MONSTER) {
+ if (monster = object_at(&level_monsters, row, col)) {
+ monster->trail_char = rc;
+ }
+ }
+ mc = mvinch(row, col);
+ if (((mc < 'A') || (mc > 'Z')) &&
+ ((row != rogue.row) || (col != rogue.col))) {
+ mvaddch(row, col, rc);
+ }
+ obj = obj->next_object;
+ }
+
+ monster = level_monsters.next_object;
+
+ while (monster) {
+ if (monster->m_flags & IMITATES) {
+ mvaddch(monster->row, monster->col, (int) monster->disguise);
+ }
+ monster = monster->next_monster;
+ }
+}
+
+put_amulet()
+{
+ object *obj;
+
+ obj = alloc_object();
+ obj->what_is = AMULET;
+ rand_place(obj);
+}
+
+rand_place(obj)
+object *obj;
+{
+ short row, col;
+
+ gr_row_col(&row, &col, (FLOOR | TUNNEL));
+ place_at(obj, row, col);
+}
+
+c_object_for_wizard()
+{
+ short ch, max, wk;
+ object *obj;
+ char buf[80];
+
+ if (pack_count((object *) 0) >= MAX_PACK_COUNT) {
+ message("pack full", 0);
+ return;
+ }
+ message("type of object?", 0);
+
+ while (r_index("!?:)]=/,\033", (ch = rgetchar()), 0) == -1) {
+ sound_bell();
+ }
+ check_message();
+
+ if (ch == '\033') {
+ return;
+ }
+ obj = alloc_object();
+
+ switch(ch) {
+ case '!':
+ obj->what_is = POTION;
+ max = POTIONS - 1;
+ break;
+ case '?':
+ obj->what_is = SCROL;
+ max = SCROLS - 1;
+ break;
+ case ',':
+ obj->what_is = AMULET;
+ break;
+ case ':':
+ get_food(obj, 0);
+ break;
+ case ')':
+ gr_weapon(obj, 0);
+ max = WEAPONS - 1;
+ break;
+ case ']':
+ gr_armor(obj);
+ max = ARMORS - 1;
+ break;
+ case '/':
+ gr_wand(obj);
+ max = WANDS - 1;
+ break;
+ case '=':
+ max = RINGS - 1;
+ obj->what_is = RING;
+ break;
+ }
+ if ((ch != ',') && (ch != ':')) {
+GIL:
+ if (get_input_line("which kind?", "", buf, "", 0, 1)) {
+ wk = get_number(buf);
+ if ((wk >= 0) && (wk <= max)) {
+ obj->which_kind = (unsigned short) wk;
+ if (obj->what_is == RING) {
+ gr_ring(obj, 0);
+ }
+ } else {
+ sound_bell();
+ goto GIL;
+ }
+ } else {
+ free_object(obj);
+ return;
+ }
+ }
+ get_desc(obj, buf);
+ message(buf, 0);
+ (void) add_to_pack(obj, &rogue.pack, 1);
+}
diff --git a/rogue/pack.c b/rogue/pack.c
new file mode 100644
index 00000000..f0d37f69
--- /dev/null
+++ b/rogue/pack.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pack.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * pack.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+char *curse_message = "you can't, it appears to be cursed";
+
+extern short levitate;
+
+object *
+add_to_pack(obj, pack, condense)
+object *obj, *pack;
+{
+ object *op;
+
+ if (condense) {
+ if (op = check_duplicate(obj, pack)) {
+ free_object(obj);
+ return(op);
+ } else {
+ obj->ichar = next_avail_ichar();
+ }
+ }
+ if (pack->next_object == 0) {
+ pack->next_object = obj;
+ } else {
+ op = pack->next_object;
+
+ while (op->next_object) {
+ op = op->next_object;
+ }
+ op->next_object = obj;
+ }
+ obj->next_object = 0;
+ return(obj);
+}
+
+take_from_pack(obj, pack)
+object *obj, *pack;
+{
+ while (pack->next_object != obj) {
+ pack = pack->next_object;
+ }
+ pack->next_object = pack->next_object->next_object;
+}
+
+/* Note: *status is set to 0 if the rogue attempts to pick up a scroll
+ * of scare-monster and it turns to dust. *status is otherwise set to 1.
+ */
+
+object *
+pick_up(row, col, status)
+short *status;
+{
+ object *obj;
+
+ *status = 1;
+
+ if (levitate) {
+ message("you're floating in the air!", 0);
+ return((object *) 0);
+ }
+ obj = object_at(&level_objects, row, col);
+ if (!obj) {
+ message("pick_up(): inconsistent", 1);
+ return(obj);
+ }
+ if ( (obj->what_is == SCROL) &&
+ (obj->which_kind == SCARE_MONSTER) &&
+ obj->picked_up) {
+ message("the scroll turns to dust as you pick it up", 0);
+ dungeon[row][col] &= (~OBJECT);
+ vanish(obj, 0, &level_objects);
+ *status = 0;
+ if (id_scrolls[SCARE_MONSTER].id_status == UNIDENTIFIED) {
+ id_scrolls[SCARE_MONSTER].id_status = IDENTIFIED;
+ }
+ return((object *) 0);
+ }
+ if (obj->what_is == GOLD) {
+ rogue.gold += obj->quantity;
+ dungeon[row][col] &= ~(OBJECT);
+ take_from_pack(obj, &level_objects);
+ print_stats(STAT_GOLD);
+ return(obj); /* obj will be free_object()ed in caller */
+ }
+ if (pack_count(obj) >= MAX_PACK_COUNT) {
+ message("pack too full", 1);
+ return((object *) 0);
+ }
+ dungeon[row][col] &= ~(OBJECT);
+ take_from_pack(obj, &level_objects);
+ obj = add_to_pack(obj, &rogue.pack, 1);
+ obj->picked_up = 1;
+ return(obj);
+}
+
+drop()
+{
+ object *obj, *new;
+ short ch;
+ char desc[DCOLS];
+
+ if (dungeon[rogue.row][rogue.col] & (OBJECT | STAIRS | TRAP)) {
+ message("there's already something there", 0);
+ return;
+ }
+ if (!rogue.pack.next_object) {
+ message("you have nothing to drop", 0);
+ return;
+ }
+ if ((ch = pack_letter("drop what?", ALL_OBJECTS)) == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (obj->in_use_flags & BEING_WIELDED) {
+ if (obj->is_cursed) {
+ message(curse_message, 0);
+ return;
+ }
+ unwield(rogue.weapon);
+ } else if (obj->in_use_flags & BEING_WORN) {
+ if (obj->is_cursed) {
+ message(curse_message, 0);
+ return;
+ }
+ mv_aquatars();
+ unwear(rogue.armor);
+ print_stats(STAT_ARMOR);
+ } else if (obj->in_use_flags & ON_EITHER_HAND) {
+ if (obj->is_cursed) {
+ message(curse_message, 0);
+ return;
+ }
+ un_put_on(obj);
+ }
+ obj->row = rogue.row;
+ obj->col = rogue.col;
+
+ if ((obj->quantity > 1) && (obj->what_is != WEAPON)) {
+ obj->quantity--;
+ new = alloc_object();
+ *new = *obj;
+ new->quantity = 1;
+ obj = new;
+ } else {
+ obj->ichar = 'L';
+ take_from_pack(obj, &rogue.pack);
+ }
+ place_at(obj, rogue.row, rogue.col);
+ (void) strcpy(desc, "dropped ");
+ get_desc(obj, desc+8);
+ message(desc, 0);
+ (void) reg_move();
+}
+
+object *
+check_duplicate(obj, pack)
+object *obj, *pack;
+{
+ object *op;
+
+ if (!(obj->what_is & (WEAPON | FOOD | SCROL | POTION))) {
+ return(0);
+ }
+ if ((obj->what_is == FOOD) && (obj->which_kind == FRUIT)) {
+ return(0);
+ }
+ op = pack->next_object;
+
+ while (op) {
+ if ((op->what_is == obj->what_is) &&
+ (op->which_kind == obj->which_kind)) {
+
+ if ((obj->what_is != WEAPON) ||
+ ((obj->what_is == WEAPON) &&
+ ((obj->which_kind == ARROW) ||
+ (obj->which_kind == DAGGER) ||
+ (obj->which_kind == DART) ||
+ (obj->which_kind == SHURIKEN)) &&
+ (obj->quiver == op->quiver))) {
+ op->quantity += obj->quantity;
+ return(op);
+ }
+ }
+ op = op->next_object;
+ }
+ return(0);
+}
+
+next_avail_ichar()
+{
+ register object *obj;
+ register i;
+ boolean ichars[26];
+
+ for (i = 0; i < 26; i++) {
+ ichars[i] = 0;
+ }
+ obj = rogue.pack.next_object;
+ while (obj) {
+ ichars[(obj->ichar - 'a')] = 1;
+ obj = obj->next_object;
+ }
+ for (i = 0; i < 26; i++) {
+ if (!ichars[i]) {
+ return(i + 'a');
+ }
+ }
+ return('?');
+}
+
+wait_for_ack()
+{
+ while (rgetchar() != ' ') ;
+}
+
+pack_letter(prompt, mask)
+char *prompt;
+unsigned short mask;
+{
+ short ch;
+ unsigned short tmask = mask;
+
+ if (!mask_pack(&rogue.pack, mask)) {
+ message("nothing appropriate", 0);
+ return(CANCEL);
+ }
+ for (;;) {
+
+ message(prompt, 0);
+
+ for (;;) {
+ ch = rgetchar();
+ if (!is_pack_letter(&ch, &mask)) {
+ sound_bell();
+ } else {
+ break;
+ }
+ }
+
+ if (ch == LIST) {
+ check_message();
+ inventory(&rogue.pack, mask);
+ } else {
+ break;
+ }
+ mask = tmask;
+ }
+ check_message();
+ return(ch);
+}
+
+take_off()
+{
+ char desc[DCOLS];
+ object *obj;
+
+ if (rogue.armor) {
+ if (rogue.armor->is_cursed) {
+ message(curse_message, 0);
+ } else {
+ mv_aquatars();
+ obj = rogue.armor;
+ unwear(rogue.armor);
+ (void) strcpy(desc, "was wearing ");
+ get_desc(obj, desc+12);
+ message(desc, 0);
+ print_stats(STAT_ARMOR);
+ (void) reg_move();
+ }
+ } else {
+ message("not wearing any", 0);
+ }
+}
+
+wear()
+{
+ short ch;
+ register object *obj;
+ char desc[DCOLS];
+
+ if (rogue.armor) {
+ message("your already wearing some", 0);
+ return;
+ }
+ ch = pack_letter("wear what?", ARMOR);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (obj->what_is != ARMOR) {
+ message("you can't wear that", 0);
+ return;
+ }
+ obj->identified = 1;
+ (void) strcpy(desc, "wearing ");
+ get_desc(obj, desc + 8);
+ message(desc, 0);
+ do_wear(obj);
+ print_stats(STAT_ARMOR);
+ (void) reg_move();
+}
+
+unwear(obj)
+object *obj;
+{
+ if (obj) {
+ obj->in_use_flags &= (~BEING_WORN);
+ }
+ rogue.armor = (object *) 0;
+}
+
+do_wear(obj)
+object *obj;
+{
+ rogue.armor = obj;
+ obj->in_use_flags |= BEING_WORN;
+ obj->identified = 1;
+}
+
+wield()
+{
+ short ch;
+ register object *obj;
+ char desc[DCOLS];
+
+ if (rogue.weapon && rogue.weapon->is_cursed) {
+ message(curse_message, 0);
+ return;
+ }
+ ch = pack_letter("wield what?", WEAPON);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("No such item.", 0);
+ return;
+ }
+ if (obj->what_is & (ARMOR | RING)) {
+ sprintf(desc, "you can't wield %s",
+ ((obj->what_is == ARMOR) ? "armor" : "rings"));
+ message(desc, 0);
+ return;
+ }
+ if (obj->in_use_flags & BEING_WIELDED) {
+ message("in use", 0);
+ } else {
+ unwield(rogue.weapon);
+ (void) strcpy(desc, "wielding ");
+ get_desc(obj, desc + 9);
+ message(desc, 0);
+ do_wield(obj);
+ (void) reg_move();
+ }
+}
+
+do_wield(obj)
+object *obj;
+{
+ rogue.weapon = obj;
+ obj->in_use_flags |= BEING_WIELDED;
+}
+
+unwield(obj)
+object *obj;
+{
+ if (obj) {
+ obj->in_use_flags &= (~BEING_WIELDED);
+ }
+ rogue.weapon = (object *) 0;
+}
+
+call_it()
+{
+ short ch;
+ register object *obj;
+ struct id *id_table;
+ char buf[MAX_TITLE_LENGTH+2];
+
+ ch = pack_letter("call what?", (SCROL | POTION | WAND | RING));
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (!(obj->what_is & (SCROL | POTION | WAND | RING))) {
+ message("surely you already know what that's called", 0);
+ return;
+ }
+ id_table = get_id_table(obj);
+
+ if (get_input_line("call it:","",buf,id_table[obj->which_kind].title,1,1)) {
+ id_table[obj->which_kind].id_status = CALLED;
+ (void) strcpy(id_table[obj->which_kind].title, buf);
+ }
+}
+
+pack_count(new_obj)
+object *new_obj;
+{
+ object *obj;
+ short count = 0;
+
+ obj = rogue.pack.next_object;
+
+ while (obj) {
+ if (obj->what_is != WEAPON) {
+ count += obj->quantity;
+ } else if (!new_obj) {
+ count++;
+ } else if ((new_obj->what_is != WEAPON) ||
+ ((obj->which_kind != ARROW) &&
+ (obj->which_kind != DAGGER) &&
+ (obj->which_kind != DART) &&
+ (obj->which_kind != SHURIKEN)) ||
+ (new_obj->which_kind != obj->which_kind) ||
+ (obj->quiver != new_obj->quiver)) {
+ count++;
+ }
+ obj = obj->next_object;
+ }
+ return(count);
+}
+
+boolean
+mask_pack(pack, mask)
+object *pack;
+unsigned short mask;
+{
+ while (pack->next_object) {
+ pack = pack->next_object;
+ if (pack->what_is & mask) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
+is_pack_letter(c, mask)
+short *c;
+unsigned short *mask;
+{
+ if (((*c == '?') || (*c == '!') || (*c == ':') || (*c == '=') ||
+ (*c == ')') || (*c == ']') || (*c == '/') || (*c == ','))) {
+ switch(*c) {
+ case '?':
+ *mask = SCROL;
+ break;
+ case '!':
+ *mask = POTION;
+ break;
+ case ':':
+ *mask = FOOD;
+ break;
+ case ')':
+ *mask = WEAPON;
+ break;
+ case ']':
+ *mask = ARMOR;
+ break;
+ case '/':
+ *mask = WAND;
+ break;
+ case '=':
+ *mask = RING;
+ break;
+ case ',':
+ *mask = AMULET;
+ break;
+ }
+ *c = LIST;
+ return(1);
+ }
+ return(((*c >= 'a') && (*c <= 'z')) || (*c == CANCEL) || (*c == LIST));
+}
+
+has_amulet()
+{
+ return(mask_pack(&rogue.pack, AMULET));
+}
+
+kick_into_pack()
+{
+ object *obj;
+ char desc[DCOLS];
+ short n, stat;
+
+ if (!(dungeon[rogue.row][rogue.col] & OBJECT)) {
+ message("nothing here", 0);
+ } else {
+ if (obj = pick_up(rogue.row, rogue.col, &stat)) {
+ get_desc(obj, desc);
+ if (obj->what_is == GOLD) {
+ message(desc, 0);
+ free_object(obj);
+ } else {
+ n = strlen(desc);
+ desc[n] = '(';
+ desc[n+1] = obj->ichar;
+ desc[n+2] = ')';
+ desc[n+3] = 0;
+ message(desc, 0);
+ }
+ }
+ if (obj || (!stat)) {
+ (void) reg_move();
+ }
+ }
+}
diff --git a/rogue/pathnames.h b/rogue/pathnames.h
new file mode 100644
index 00000000..7be84041
--- /dev/null
+++ b/rogue/pathnames.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 6/1/90
+ */
+
+#define _PATH_SCOREFILE "/var/games/rogue.scores"
+#define _PATH_LOCKFILE "/var/games/rogue.lock"
+
diff --git a/rogue/play.c b/rogue/play.c
new file mode 100644
index 00000000..aaa6348c
--- /dev/null
+++ b/rogue/play.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)play.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * play.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+boolean interrupted = 0;
+char *unknown_command = "unknown command";
+
+extern short party_room, bear_trap;
+extern char hit_message[];
+extern boolean wizard, trap_door;
+
+play_level()
+{
+ short ch;
+ int count;
+
+ for (;;) {
+ interrupted = 0;
+ if (hit_message[0]) {
+ message(hit_message, 1);
+ hit_message[0] = 0;
+ }
+ if (trap_door) {
+ trap_door = 0;
+ return;
+ }
+ move(rogue.row, rogue.col);
+ refresh();
+
+ ch = rgetchar();
+CMCH:
+ check_message();
+ count = 0;
+CH:
+ switch(ch) {
+ case '.':
+ rest((count > 0) ? count : 1);
+ break;
+ case 's':
+ search(((count > 0) ? count : 1), 0);
+ break;
+ case 'i':
+ inventory(&rogue.pack, ALL_OBJECTS);
+ break;
+ case 'f':
+ fight(0);
+ break;
+ case 'F':
+ fight(1);
+ break;
+ case 'h':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'y':
+ case 'u':
+ case 'n':
+ case 'b':
+ (void) one_move_rogue(ch, 1);
+ break;
+ case 'H':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'B':
+ case 'Y':
+ case 'U':
+ case 'N':
+ case '\010':
+ case '\012':
+ case '\013':
+ case '\014':
+ case '\031':
+ case '\025':
+ case '\016':
+ case '\002':
+ multiple_move_rogue(ch);
+ break;
+ case 'e':
+ eat();
+ break;
+ case 'q':
+ quaff();
+ break;
+ case 'r':
+ read_scroll();
+ break;
+ case 'm':
+ move_onto();
+ break;
+ case ',':
+ kick_into_pack();
+ break;
+ case 'd':
+ drop();
+ break;
+ case 'P':
+ put_on_ring();
+ break;
+ case 'R':
+ remove_ring();
+ break;
+ case '\020':
+ do {
+ remessage(count++);
+ ch = rgetchar();
+ } while (ch == '\020');
+ goto CMCH;
+ break;
+ case '\027':
+ wizardize();
+ break;
+ case '>':
+ if (drop_check()) {
+ return;
+ }
+ break;
+ case '<':
+ if (check_up()) {
+ return;
+ }
+ break;
+ case ')':
+ case ']':
+ inv_armor_weapon(ch == ')');
+ break;
+ case '=':
+ inv_rings();
+ break;
+ case '^':
+ id_trap();
+ break;
+ case '/':
+ id_type();
+ break;
+ case '?':
+ id_com();
+ break;
+ case '!':
+ do_shell();
+ break;
+ case 'o':
+ edit_opts();
+ break;
+ case 'I':
+ single_inv(0);
+ break;
+ case 'T':
+ take_off();
+ break;
+ case 'W':
+ wear();
+ break;
+ case 'w':
+ wield();
+ break;
+ case 'c':
+ call_it();
+ break;
+ case 'z':
+ zapp();
+ break;
+ case 't':
+ throw();
+ break;
+ case 'v':
+ message("rogue-clone: Version III. (Tim Stoehr was here), tektronix!zeus!tims", 0);
+ break;
+ case 'Q':
+ quit(0);
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ move(rogue.row, rogue.col);
+ refresh();
+ do {
+ if (count < 100) {
+ count = (10 * count) + (ch - '0');
+ }
+ ch = rgetchar();
+ } while (is_digit(ch));
+ if (ch != CANCEL) {
+ goto CH;
+ }
+ break;
+ case ' ':
+ break;
+ case '\011':
+ if (wizard) {
+ inventory(&level_objects, ALL_OBJECTS);
+ } else {
+ message(unknown_command, 0);
+ }
+ break;
+ case '\023':
+ if (wizard) {
+ draw_magic_map();
+ } else {
+ message(unknown_command, 0);
+ }
+ break;
+ case '\024':
+ if (wizard) {
+ show_traps();
+ } else {
+ message(unknown_command, 0);
+ }
+ break;
+ case '\017':
+ if (wizard) {
+ show_objects();
+ } else {
+ message(unknown_command, 0);
+ }
+ break;
+ case '\001':
+ show_average_hp();
+ break;
+ case '\003':
+ if (wizard) {
+ c_object_for_wizard();
+ } else {
+ message(unknown_command, 0);
+ }
+ break;
+ case '\015':
+ if (wizard) {
+ show_monsters();
+ } else {
+ message(unknown_command, 0);
+ }
+ break;
+ case 'S':
+ save_game();
+ break;
+ default:
+ message(unknown_command, 0);
+ break;
+ }
+ }
+}
diff --git a/rogue/random.c b/rogue/random.c
new file mode 100644
index 00000000..bd829d6e
--- /dev/null
+++ b/rogue/random.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)random.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * random.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+static long rntb[32] = {
+ 3, 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342,
+ 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, 0x7449e56b,
+ 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 0x8c2e680f, 0xeb3d799f,
+ 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 0xe369735d,
+ 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
+ 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e,
+ 0x8999220b, 0x27fb47b9
+};
+
+static long *fptr = &rntb[4];
+static long *rptr = &rntb[1];
+static long *state = &rntb[1];
+static int rand_type = 3;
+static int rand_deg = 31;
+static int rand_sep = 3;
+static long *end_ptr = &rntb[32];
+
+srrandom(x)
+int x;
+{
+ register int i;
+ long rrandom();
+
+ state[0] = (long) x;
+ if (rand_type != 0) {
+ for (i = 1; i < rand_deg; i++) {
+ state[i] = 1103515245 * state[i - 1] + 12345;
+ }
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ for (i = 0; i < 10 * rand_deg; i++) {
+ (void) rrandom();
+ }
+ }
+}
+
+long
+rrandom()
+{
+ long i;
+
+ if (rand_type == 0) {
+ i = state[0] = (state[0]*1103515245 + 12345) & 0x7fffffff;
+ } else {
+ *fptr += *rptr;
+ i = (*fptr >> 1) & 0x7fffffff;
+ if (++fptr >= end_ptr) {
+ fptr = state;
+ ++rptr;
+ } else {
+ if (++rptr >= end_ptr) {
+ rptr = state;
+ }
+ }
+ }
+ return(i);
+}
+
+get_rand(x, y)
+register int x, y;
+{
+ register int r, t;
+ long lr;
+
+ if (x > y) {
+ t = y;
+ y = x;
+ x = t;
+ }
+ lr = rrandom();
+ lr &= (long) 0x00003fff;
+ r = (int) lr;
+ r = (r % ((y - x) + 1)) + x;
+ return(r);
+}
+
+rand_percent(percentage)
+register int percentage;
+{
+ return(get_rand(1, 100) <= percentage);
+}
+
+coin_toss()
+{
+
+ return(((rrandom() & 01) ? 1 : 0));
+}
diff --git a/rogue/ring.c b/rogue/ring.c
new file mode 100644
index 00000000..1014000a
--- /dev/null
+++ b/rogue/ring.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ring.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * ring.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+char *left_or_right = "left or right hand?";
+char *no_ring = "there's no ring on that hand";
+short stealthy;
+short r_rings;
+short add_strength;
+short e_rings;
+short regeneration;
+short ring_exp;
+short auto_search;
+boolean r_teleport;
+boolean r_see_invisible;
+boolean sustain_strength;
+boolean maintain_armor;
+
+extern char *curse_message;
+extern boolean wizard;
+
+put_on_ring()
+{
+ short ch;
+ char desc[DCOLS];
+ object *ring;
+
+ if (r_rings == 2) {
+ message("wearing two rings already", 0);
+ return;
+ }
+ if ((ch = pack_letter("put on what?", RING)) == CANCEL) {
+ return;
+ }
+ if (!(ring = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (!(ring->what_is & RING)) {
+ message("that's not a ring", 0);
+ return;
+ }
+ if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) {
+ message("that ring is already being worn", 0);
+ return;
+ }
+ if (r_rings == 1) {
+ ch = (rogue.left_ring ? 'r' : 'l');
+ } else {
+ message(left_or_right, 0);
+ do {
+ ch = rgetchar();
+ } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') &&
+ (ch != '\r'));
+ }
+ if ((ch != 'l') && (ch != 'r')) {
+ check_message();
+ return;
+ }
+ if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) {
+ check_message();
+ message("there's already a ring on that hand", 0);
+ return;
+ }
+ if (ch == 'l') {
+ do_put_on(ring, 1);
+ } else {
+ do_put_on(ring, 0);
+ }
+ ring_stats(1);
+ check_message();
+ get_desc(ring, desc);
+ message(desc, 0);
+ (void) reg_move();
+}
+
+/*
+ * Do not call ring_stats() from within do_put_on(). It will cause
+ * serious problems when do_put_on() is called from read_pack() in restore().
+ */
+
+do_put_on(ring, on_left)
+object *ring;
+boolean on_left;
+{
+ if (on_left) {
+ ring->in_use_flags |= ON_LEFT_HAND;
+ rogue.left_ring = ring;
+ } else {
+ ring->in_use_flags |= ON_RIGHT_HAND;
+ rogue.right_ring = ring;
+ }
+}
+
+remove_ring()
+{
+ boolean left = 0, right = 0;
+ short ch;
+ char buf[DCOLS];
+ object *ring;
+
+ if (r_rings == 0) {
+ inv_rings();
+ } else if (rogue.left_ring && !rogue.right_ring) {
+ left = 1;
+ } else if (!rogue.left_ring && rogue.right_ring) {
+ right = 1;
+ } else {
+ message(left_or_right, 0);
+ do {
+ ch = rgetchar();
+ } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') &&
+ (ch != '\n') && (ch != '\r'));
+ left = (ch == 'l');
+ right = (ch == 'r');
+ check_message();
+ }
+ if (left || right) {
+ if (left) {
+ if (rogue.left_ring) {
+ ring = rogue.left_ring;
+ } else {
+ message(no_ring, 0);
+ }
+ } else {
+ if (rogue.right_ring) {
+ ring = rogue.right_ring;
+ } else {
+ message(no_ring, 0);
+ }
+ }
+ if (ring->is_cursed) {
+ message(curse_message, 0);
+ } else {
+ un_put_on(ring);
+ (void) strcpy(buf, "removed ");
+ get_desc(ring, buf + 8);
+ message(buf, 0);
+ (void) reg_move();
+ }
+ }
+}
+
+un_put_on(ring)
+object *ring;
+{
+ if (ring && (ring->in_use_flags & ON_LEFT_HAND)) {
+ ring->in_use_flags &= (~ON_LEFT_HAND);
+ rogue.left_ring = 0;
+ } else if (ring && (ring->in_use_flags & ON_RIGHT_HAND)) {
+ ring->in_use_flags &= (~ON_RIGHT_HAND);
+ rogue.right_ring = 0;
+ }
+ ring_stats(1);
+}
+
+gr_ring(ring, assign_wk)
+object *ring;
+boolean assign_wk;
+{
+ ring->what_is = RING;
+ if (assign_wk) {
+ ring->which_kind = get_rand(0, (RINGS - 1));
+ }
+ ring->class = 0;
+
+ switch(ring->which_kind) {
+ /*
+ case STEALTH:
+ break;
+ case SLOW_DIGEST:
+ break;
+ case REGENERATION:
+ break;
+ case R_SEE_INVISIBLE:
+ break;
+ case SUSTAIN_STRENGTH:
+ break;
+ case R_MAINTAIN_ARMOR:
+ break;
+ case SEARCHING:
+ break;
+ */
+ case R_TELEPORT:
+ ring->is_cursed = 1;
+ break;
+ case ADD_STRENGTH:
+ case DEXTERITY:
+ while ((ring->class = (get_rand(0, 4) - 2)) == 0) ;
+ ring->is_cursed = (ring->class < 0);
+ break;
+ case ADORNMENT:
+ ring->is_cursed = coin_toss();
+ break;
+ }
+}
+
+inv_rings()
+{
+ char buf[DCOLS];
+
+ if (r_rings == 0) {
+ message("not wearing any rings", 0);
+ } else {
+ if (rogue.left_ring) {
+ get_desc(rogue.left_ring, buf);
+ message(buf, 0);
+ }
+ if (rogue.right_ring) {
+ get_desc(rogue.right_ring, buf);
+ message(buf, 0);
+ }
+ }
+ if (wizard) {
+ sprintf(buf, "ste %d, r_r %d, e_r %d, r_t %d, s_s %d, a_s %d, reg %d, r_e %d, s_i %d, m_a %d, aus %d",
+ stealthy, r_rings, e_rings, r_teleport, sustain_strength,
+ add_strength, regeneration, ring_exp, r_see_invisible,
+ maintain_armor, auto_search);
+ message(buf, 0);
+ }
+}
+
+ring_stats(pr)
+boolean pr;
+{
+ short i;
+ object *ring;
+
+ stealthy = 0;
+ r_rings = 0;
+ e_rings = 0;
+ r_teleport = 0;
+ sustain_strength = 0;
+ add_strength = 0;
+ regeneration = 0;
+ ring_exp = 0;
+ r_see_invisible = 0;
+ maintain_armor = 0;
+ auto_search = 0;
+
+ for (i = 0; i < 2; i++) {
+ if (!(ring = ((i == 0) ? rogue.left_ring : rogue.right_ring))) {
+ continue;
+ }
+ r_rings++;
+ e_rings++;
+ switch(ring->which_kind) {
+ case STEALTH:
+ stealthy++;
+ break;
+ case R_TELEPORT:
+ r_teleport = 1;
+ break;
+ case REGENERATION:
+ regeneration++;
+ break;
+ case SLOW_DIGEST:
+ e_rings -= 2;
+ break;
+ case ADD_STRENGTH:
+ add_strength += ring->class;
+ break;
+ case SUSTAIN_STRENGTH:
+ sustain_strength = 1;
+ break;
+ case DEXTERITY:
+ ring_exp += ring->class;
+ break;
+ case ADORNMENT:
+ break;
+ case R_SEE_INVISIBLE:
+ r_see_invisible = 1;
+ break;
+ case MAINTAIN_ARMOR:
+ maintain_armor = 1;
+ break;
+ case SEARCHING:
+ auto_search += 2;
+ break;
+ }
+ }
+ if (pr) {
+ print_stats(STAT_STRENGTH);
+ relight();
+ }
+}
diff --git a/rogue/rogue.6 b/rogue/rogue.6
new file mode 100644
index 00000000..bad531eb
--- /dev/null
+++ b/rogue/rogue.6
@@ -0,0 +1,113 @@
+.\" Copyright (c) 1988 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rogue.6 6.5 (Berkeley) 6/23/90
+.\"
+.TH ROGUE 6 "June 23, 1990"
+.UC 4
+.SH NAME
+rogue \- Exploring The Dungeons of Doom
+.SH SYNOPSIS
+.B /usr/games/rogue
+[
+.B \-r
+]
+[
+.I save_file
+]
+[
+.B \-s
+]
+[
+.B \-d
+]
+.SH DESCRIPTION
+.PP
+.I Rogue
+is a computer fantasy game with a new twist. It is crt oriented and the
+object of the game is to survive the attacks of various monsters and get
+a lot of gold, rather than the puzzle solving orientation of most computer
+fantasy games.
+.PP
+To get started you really only need to know two commands. The command
+.B ?
+will give you a list of the available commands and the command
+.B /
+will identify the things you see on the screen.
+.PP
+To win the game (as opposed to merely playing to beat other people's high
+scores) you must locate the Amulet of Yendor which is somewhere below
+the 20th level of the dungeon and get it out. Nobody has achieved this
+yet and if somebody does, they will probably go down in history as a hero
+among heroes.
+.PP
+When the game ends, either by your death, when you quit, or if you (by
+some miracle) manage to win,
+.I rogue
+will give you a list of the top-ten scorers. The scoring is based entirely
+upon how much gold you get. There is a 10% penalty for getting yourself
+killed.
+.PP
+If
+.I save_file
+is specified,
+rogue will be restored from the specified saved game file.
+.PP
+The
+.B \-s
+option will print out the list of scores.
+.PP
+For more detailed directions, read the document
+.I "A Guide to the Dungeons of Doom."
+.SH AUTHORS
+Timothy Stoehr,
+Michael C. Toy,
+Kenneth C. R. C. Arnold,
+Glenn Wichman
+.SH FILES
+.DT
+.ta \w'/usr/games/lib/rogue_roll\ \ \ 'u
+/usr/games/lib/rogue_roll Score file
+.br
+\fB~\fP/rogue.save Default save file
+.SH SEE ALSO
+Michael C. Toy
+and
+Kenneth C. R. C. Arnold,
+.I "A guide to the Dungeons of Doom"
+.SH BUGS
+.PP
+Probably infinite, although none are known.
+However,
+that Ice Monsters sometimes transfix you permanently is
+.I not
+a bug.
+It's a feature.
diff --git a/rogue/rogue.h b/rogue/rogue.h
new file mode 100644
index 00000000..9e3d67d6
--- /dev/null
+++ b/rogue/rogue.h
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timoth C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)rogue.h 5.6 (Berkeley) 2/28/91
+ */
+
+/*
+ * rogue.h
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) This notice shall not be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ */
+
+#define boolean char
+
+#define NOTHING ((unsigned short) 0)
+#define OBJECT ((unsigned short) 01)
+#define MONSTER ((unsigned short) 02)
+#define STAIRS ((unsigned short) 04)
+#define HORWALL ((unsigned short) 010)
+#define VERTWALL ((unsigned short) 020)
+#define DOOR ((unsigned short) 040)
+#define FLOOR ((unsigned short) 0100)
+#define TUNNEL ((unsigned short) 0200)
+#define TRAP ((unsigned short) 0400)
+#define HIDDEN ((unsigned short) 01000)
+
+#define ARMOR ((unsigned short) 01)
+#define WEAPON ((unsigned short) 02)
+#define SCROL ((unsigned short) 04)
+#define POTION ((unsigned short) 010)
+#define GOLD ((unsigned short) 020)
+#define FOOD ((unsigned short) 040)
+#define WAND ((unsigned short) 0100)
+#define RING ((unsigned short) 0200)
+#define AMULET ((unsigned short) 0400)
+#define ALL_OBJECTS ((unsigned short) 0777)
+
+#define LEATHER 0
+#define RINGMAIL 1
+#define SCALE 2
+#define CHAIN 3
+#define BANDED 4
+#define SPLINT 5
+#define PLATE 6
+#define ARMORS 7
+
+#define BOW 0
+#define DART 1
+#define ARROW 2
+#define DAGGER 3
+#define SHURIKEN 4
+#define MACE 5
+#define LONG_SWORD 6
+#define TWO_HANDED_SWORD 7
+#define WEAPONS 8
+
+#define MAX_PACK_COUNT 24
+
+#define PROTECT_ARMOR 0
+#define HOLD_MONSTER 1
+#define ENCH_WEAPON 2
+#define ENCH_ARMOR 3
+#define IDENTIFY 4
+#define TELEPORT 5
+#define SLEEP 6
+#define SCARE_MONSTER 7
+#define REMOVE_CURSE 8
+#define CREATE_MONSTER 9
+#define AGGRAVATE_MONSTER 10
+#define MAGIC_MAPPING 11
+#define CON_MON 12
+#define SCROLS 13
+
+#define INCREASE_STRENGTH 0
+#define RESTORE_STRENGTH 1
+#define HEALING 2
+#define EXTRA_HEALING 3
+#define POISON 4
+#define RAISE_LEVEL 5
+#define BLINDNESS 6
+#define HALLUCINATION 7
+#define DETECT_MONSTER 8
+#define DETECT_OBJECTS 9
+#define CONFUSION 10
+#define LEVITATION 11
+#define HASTE_SELF 12
+#define SEE_INVISIBLE 13
+#define POTIONS 14
+
+#define TELE_AWAY 0
+#define SLOW_MONSTER 1
+#define INVISIBILITY 2
+#define POLYMORPH 3
+#define HASTE_MONSTER 4
+#define MAGIC_MISSILE 5
+#define CANCELLATION 6
+#define DO_NOTHING 7
+#define DRAIN_LIFE 8
+#define COLD 9
+#define FIRE 10
+#define WANDS 11
+
+#define STEALTH 0
+#define R_TELEPORT 1
+#define REGENERATION 2
+#define SLOW_DIGEST 3
+#define ADD_STRENGTH 4
+#define SUSTAIN_STRENGTH 5
+#define DEXTERITY 6
+#define ADORNMENT 7
+#define R_SEE_INVISIBLE 8
+#define MAINTAIN_ARMOR 9
+#define SEARCHING 10
+#define RINGS 11
+
+#define RATION 0
+#define FRUIT 1
+
+#define NOT_USED ((unsigned short) 0)
+#define BEING_WIELDED ((unsigned short) 01)
+#define BEING_WORN ((unsigned short) 02)
+#define ON_LEFT_HAND ((unsigned short) 04)
+#define ON_RIGHT_HAND ((unsigned short) 010)
+#define ON_EITHER_HAND ((unsigned short) 014)
+#define BEING_USED ((unsigned short) 017)
+
+#define NO_TRAP -1
+#define TRAP_DOOR 0
+#define BEAR_TRAP 1
+#define TELE_TRAP 2
+#define DART_TRAP 3
+#define SLEEPING_GAS_TRAP 4
+#define RUST_TRAP 5
+#define TRAPS 6
+
+#define STEALTH_FACTOR 3
+#define R_TELE_PERCENT 8
+
+#define UNIDENTIFIED ((unsigned short) 00) /* MUST BE ZERO! */
+#define IDENTIFIED ((unsigned short) 01)
+#define CALLED ((unsigned short) 02)
+
+#define DROWS 24
+#define DCOLS 80
+#define NMESSAGES 5
+#define MAX_TITLE_LENGTH 30
+#define MAXSYLLABLES 40
+#define MAX_METAL 14
+#define WAND_MATERIALS 30
+#define GEMS 14
+
+#define GOLD_PERCENT 46
+
+#define MAX_OPT_LEN 40
+
+struct id {
+ short value;
+ char *title;
+ char *real;
+ unsigned short id_status;
+};
+
+/* The following #defines provide more meaningful names for some of the
+ * struct object fields that are used for monsters. This, since each monster
+ * and object (scrolls, potions, etc) are represented by a struct object.
+ * Ideally, this should be handled by some kind of union structure.
+ */
+
+#define m_damage damage
+#define hp_to_kill quantity
+#define m_char ichar
+#define first_level is_protected
+#define last_level is_cursed
+#define m_hit_chance class
+#define stationary_damage identified
+#define drop_percent which_kind
+#define trail_char d_enchant
+#define slowed_toggle quiver
+#define moves_confused hit_enchant
+#define nap_length picked_up
+#define disguise what_is
+#define next_monster next_object
+
+struct obj { /* comment is monster meaning */
+ unsigned long m_flags; /* monster flags */
+ char *damage; /* damage it does */
+ short quantity; /* hit points to kill */
+ short ichar; /* 'A' is for aquatar */
+ short kill_exp; /* exp for killing it */
+ short is_protected; /* level starts */
+ short is_cursed; /* level ends */
+ short class; /* chance of hitting you */
+ short identified; /* 'F' damage, 1,2,3... */
+ unsigned short which_kind; /* item carry/drop % */
+ short o_row, o_col, o; /* o is how many times stuck at o_row, o_col */
+ short row, col; /* current row, col */
+ short d_enchant; /* room char when detect_monster */
+ short quiver; /* monster slowed toggle */
+ short trow, tcol; /* target row, col */
+ short hit_enchant; /* how many moves is confused */
+ unsigned short what_is; /* imitator's charactor (?!%: */
+ short picked_up; /* sleep from wand of sleep */
+ unsigned short in_use_flags;
+ struct obj *next_object; /* next monster */
+};
+
+typedef struct obj object;
+
+#define INIT_AW (object*)0,(object*)0
+#define INIT_RINGS (object*)0,(object*)0
+#define INIT_HP 12,12
+#define INIT_STR 16,16
+#define INIT_EXP 1,0
+#define INIT_PACK {0}
+#define INIT_GOLD 0
+#define INIT_CHAR '@'
+#define INIT_MOVES 1250
+
+struct fightr {
+ object *armor;
+ object *weapon;
+ object *left_ring, *right_ring;
+ short hp_current;
+ short hp_max;
+ short str_current;
+ short str_max;
+ object pack;
+ long gold;
+ short exp;
+ long exp_points;
+ short row, col;
+ short fchar;
+ short moves_left;
+};
+
+typedef struct fightr fighter;
+
+struct dr {
+ short oth_room;
+ short oth_row,
+ oth_col;
+ short door_row,
+ door_col;
+};
+
+typedef struct dr door;
+
+struct rm {
+ short bottom_row, right_col, left_col, top_row;
+ door doors[4];
+ unsigned short is_room;
+};
+
+typedef struct rm room;
+
+#define MAXROOMS 9
+#define BIG_ROOM 10
+
+#define NO_ROOM -1
+
+#define PASSAGE -3 /* cur_room value */
+
+#define AMULET_LEVEL 26
+
+#define R_NOTHING ((unsigned short) 01)
+#define R_ROOM ((unsigned short) 02)
+#define R_MAZE ((unsigned short) 04)
+#define R_DEADEND ((unsigned short) 010)
+#define R_CROSS ((unsigned short) 020)
+
+#define MAX_EXP_LEVEL 21
+#define MAX_EXP 10000001L
+#define MAX_GOLD 999999
+#define MAX_ARMOR 99
+#define MAX_HP 999
+#define MAX_STRENGTH 99
+#define LAST_DUNGEON 99
+
+#define STAT_LEVEL 01
+#define STAT_GOLD 02
+#define STAT_HP 04
+#define STAT_STRENGTH 010
+#define STAT_ARMOR 020
+#define STAT_EXP 040
+#define STAT_HUNGER 0100
+#define STAT_LABEL 0200
+#define STAT_ALL 0377
+
+#define PARTY_TIME 10 /* one party somewhere in each 10 level span */
+
+#define MAX_TRAPS 10 /* maximum traps per level */
+
+#define HIDE_PERCENT 12
+
+struct tr {
+ short trap_type;
+ short trap_row, trap_col;
+};
+
+typedef struct tr trap;
+
+extern fighter rogue;
+extern room rooms[];
+extern trap traps[];
+extern unsigned short dungeon[DROWS][DCOLS];
+extern object level_objects;
+
+extern struct id id_scrolls[];
+extern struct id id_potions[];
+extern struct id id_wands[];
+extern struct id id_rings[];
+extern struct id id_weapons[];
+extern struct id id_armors[];
+
+extern object mon_tab[];
+extern object level_monsters;
+
+#define MONSTERS 26
+
+#define HASTED 01L
+#define SLOWED 02L
+#define INVISIBLE 04L
+#define ASLEEP 010L
+#define WAKENS 020L
+#define WANDERS 040L
+#define FLIES 0100L
+#define FLITS 0200L
+#define CAN_FLIT 0400L /* can, but usually doesn't, flit */
+#define CONFUSED 01000L
+#define RUSTS 02000L
+#define HOLDS 04000L
+#define FREEZES 010000L
+#define STEALS_GOLD 020000L
+#define STEALS_ITEM 040000L
+#define STINGS 0100000L
+#define DRAINS_LIFE 0200000L
+#define DROPS_LEVEL 0400000L
+#define SEEKS_GOLD 01000000L
+#define FREEZING_ROGUE 02000000L
+#define RUST_VANISHED 04000000L
+#define CONFUSES 010000000L
+#define IMITATES 020000000L
+#define FLAMES 040000000L
+#define STATIONARY 0100000000L /* damage will be 1,2,3,... */
+#define NAPPING 0200000000L /* can't wake up for a while */
+#define ALREADY_MOVED 0400000000L
+
+#define SPECIAL_HIT (RUSTS|HOLDS|FREEZES|STEALS_GOLD|STEALS_ITEM|STINGS|DRAINS_LIFE|DROPS_LEVEL)
+
+#define WAKE_PERCENT 45
+#define FLIT_PERCENT 40
+#define PARTY_WAKE_PERCENT 75
+
+#define HYPOTHERMIA 1
+#define STARVATION 2
+#define POISON_DART 3
+#define QUIT 4
+#define WIN 5
+#define KFIRE 6
+
+#define UPWARD 0
+#define UPRIGHT 1
+#define RIGHT 2
+#define DOWNRIGHT 3
+#define DOWN 4
+#define DOWNLEFT 5
+#define LEFT 6
+#define UPLEFT 7
+#define DIRS 8
+
+#define ROW1 7
+#define ROW2 15
+
+#define COL1 26
+#define COL2 52
+
+#define MOVED 0
+#define MOVE_FAILED -1
+#define STOPPED_ON_SOMETHING -2
+#define CANCEL '\033'
+#define LIST '*'
+
+#define HUNGRY 300
+#define WEAK 150
+#define FAINT 20
+#define STARVE 0
+
+#define MIN_ROW 1
+
+/* external routine declarations.
+ */
+char *strcpy();
+char *strncpy();
+char *strcat();
+
+char *mon_name();
+char *get_ench_color();
+char *name_of();
+char *md_gln();
+char *md_getenv();
+char *md_malloc();
+boolean is_direction();
+boolean mon_sees();
+boolean mask_pack();
+boolean mask_room();
+boolean is_digit();
+boolean check_hunger();
+boolean reg_move();
+boolean md_df();
+boolean has_been_touched();
+object *add_to_pack();
+object *alloc_object();
+object *get_letter_object();
+object *gr_monster();
+object *get_thrown_at_monster();
+object *get_zapped_monster();
+object *check_duplicate();
+object *gr_object();
+object *object_at();
+object *pick_up();
+struct id *get_id_table();
+unsigned short gr_what_is();
+long rrandom();
+long lget_number();
+long xxx();
+void byebye(), onintr(), error_save();
+
+struct rogue_time {
+ short year; /* >= 1987 */
+ short month; /* 1 - 12 */
+ short day; /* 1 - 31 */
+ short hour; /* 0 - 23 */
+ short minute; /* 0 - 59 */
+ short second; /* 0 - 59 */
+};
+
+#ifdef CURSES
+struct _win_st {
+ short _cury, _curx;
+ short _maxy, _maxx;
+};
+
+typedef struct _win_st WINDOW;
+
+extern int LINES, COLS;
+extern WINDOW *curscr;
+extern char *CL;
+
+char *md_gdtcf();
+
+#else
+#include <curses.h>
+#endif
diff --git a/rogue/room.c b/rogue/room.c
new file mode 100644
index 00000000..1154e51a
--- /dev/null
+++ b/rogue/room.c
@@ -0,0 +1,649 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)room.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * room.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+room rooms[MAXROOMS];
+boolean rooms_visited[MAXROOMS];
+
+extern short blind;
+extern boolean detect_monster, jump, passgo, no_skull, ask_quit;
+extern char *nick_name, *fruit, *save_file, *press_space;
+
+#define NOPTS 7
+
+struct option {
+ char *prompt;
+ boolean is_bool;
+ char **strval;
+ boolean *bval;
+} options[NOPTS] = {
+ {
+ "Show position only at end of run (\"jump\"): ",
+ 1, (char **) 0, &jump
+ },
+ {
+ "Follow turnings in passageways (\"passgo\"): ",
+ 1, (char **) 0, &passgo
+ },
+ {
+ "Don't print skull when killed (\"noskull\" or \"notombstone\"): ",
+ 1, (char **) 0, &no_skull
+ },
+ {
+ "Ask player before saying 'Okay, bye-bye!' (\"askquit\"): ",
+ 1, (char **) 0, &ask_quit
+ },
+ {
+ "Name (\"name\"): ",
+ 0, &nick_name
+ },
+ {
+ "Fruit (\"fruit\"): ",
+ 0, &fruit
+ },
+ {
+ "Save file (\"file\"): ",
+ 0, &save_file
+ }
+};
+
+light_up_room(rn)
+int rn;
+{
+ short i, j;
+
+ if (!blind) {
+ for (i = rooms[rn].top_row;
+ i <= rooms[rn].bottom_row; i++) {
+ for (j = rooms[rn].left_col;
+ j <= rooms[rn].right_col; j++) {
+ if (dungeon[i][j] & MONSTER) {
+ object *monster;
+
+ if (monster = object_at(&level_monsters, i, j)) {
+ dungeon[monster->row][monster->col] &= (~MONSTER);
+ monster->trail_char =
+ get_dungeon_char(monster->row, monster->col);
+ dungeon[monster->row][monster->col] |= MONSTER;
+ }
+ }
+ mvaddch(i, j, get_dungeon_char(i, j));
+ }
+ }
+ mvaddch(rogue.row, rogue.col, rogue.fchar);
+ }
+}
+
+light_passage(row, col)
+{
+ short i, j, i_end, j_end;
+
+ if (blind) {
+ return;
+ }
+ i_end = (row < (DROWS-2)) ? 1 : 0;
+ j_end = (col < (DCOLS-1)) ? 1 : 0;
+
+ for (i = ((row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
+ for (j = ((col > 0) ? -1 : 0); j <= j_end; j++) {
+ if (can_move(row, col, row+i, col+j)) {
+ mvaddch(row+i, col+j, get_dungeon_char(row+i, col+j));
+ }
+ }
+ }
+}
+
+darken_room(rn)
+short rn;
+{
+ short i, j;
+
+ for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) {
+ for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) {
+ if (blind) {
+ mvaddch(i, j, ' ');
+ } else {
+ if (!(dungeon[i][j] & (OBJECT | STAIRS)) &&
+ !(detect_monster && (dungeon[i][j] & MONSTER))) {
+ if (!imitating(i, j)) {
+ mvaddch(i, j, ' ');
+ }
+ if ((dungeon[i][j] & TRAP) && (!(dungeon[i][j] & HIDDEN))) {
+ mvaddch(i, j, '^');
+ }
+ }
+ }
+ }
+ }
+}
+
+get_dungeon_char(row, col)
+register row, col;
+{
+ register unsigned short mask = dungeon[row][col];
+
+ if (mask & MONSTER) {
+ return(gmc_row_col(row, col));
+ }
+ if (mask & OBJECT) {
+ object *obj;
+
+ obj = object_at(&level_objects, row, col);
+ return(get_mask_char(obj->what_is));
+ }
+ if (mask & (TUNNEL | STAIRS | HORWALL | VERTWALL | FLOOR | DOOR)) {
+ if ((mask & (TUNNEL| STAIRS)) && (!(mask & HIDDEN))) {
+ return(((mask & STAIRS) ? '%' : '#'));
+ }
+ if (mask & HORWALL) {
+ return('-');
+ }
+ if (mask & VERTWALL) {
+ return('|');
+ }
+ if (mask & FLOOR) {
+ if (mask & TRAP) {
+ if (!(dungeon[row][col] & HIDDEN)) {
+ return('^');
+ }
+ }
+ return('.');
+ }
+ if (mask & DOOR) {
+ if (mask & HIDDEN) {
+ if (((col > 0) && (dungeon[row][col-1] & HORWALL)) ||
+ ((col < (DCOLS-1)) && (dungeon[row][col+1] & HORWALL))) {
+ return('-');
+ } else {
+ return('|');
+ }
+ } else {
+ return('+');
+ }
+ }
+ }
+ return(' ');
+}
+
+get_mask_char(mask)
+register unsigned short mask;
+{
+ switch(mask) {
+ case SCROL:
+ return('?');
+ case POTION:
+ return('!');
+ case GOLD:
+ return('*');
+ case FOOD:
+ return(':');
+ case WAND:
+ return('/');
+ case ARMOR:
+ return(']');
+ case WEAPON:
+ return(')');
+ case RING:
+ return('=');
+ case AMULET:
+ return(',');
+ default:
+ return('~'); /* unknown, something is wrong */
+ }
+}
+
+gr_row_col(row, col, mask)
+short *row, *col;
+unsigned short mask;
+{
+ short rn;
+ short r, c;
+
+ do {
+ r = get_rand(MIN_ROW, DROWS-2);
+ c = get_rand(0, DCOLS-1);
+ rn = get_room_number(r, c);
+ } while ((rn == NO_ROOM) ||
+ (!(dungeon[r][c] & mask)) ||
+ (dungeon[r][c] & (~mask)) ||
+ (!(rooms[rn].is_room & (R_ROOM | R_MAZE))) ||
+ ((r == rogue.row) && (c == rogue.col)));
+
+ *row = r;
+ *col = c;
+}
+
+gr_room()
+{
+ short i;
+
+ do {
+ i = get_rand(0, MAXROOMS-1);
+ } while (!(rooms[i].is_room & (R_ROOM | R_MAZE)));
+
+ return(i);
+}
+
+party_objects(rn)
+{
+ short i, j, nf = 0;
+ object *obj;
+ short n, N, row, col;
+ boolean found;
+
+ N = ((rooms[rn].bottom_row - rooms[rn].top_row) - 1) *
+ ((rooms[rn].right_col - rooms[rn].left_col) - 1);
+ n = get_rand(5, 10);
+ if (n > N) {
+ n = N - 2;
+ }
+ for (i = 0; i < n; i++) {
+ for (j = found = 0; ((!found) && (j < 250)); j++) {
+ row = get_rand(rooms[rn].top_row+1,
+ rooms[rn].bottom_row-1);
+ col = get_rand(rooms[rn].left_col+1,
+ rooms[rn].right_col-1);
+ if ((dungeon[row][col] == FLOOR) || (dungeon[row][col] == TUNNEL)) {
+ found = 1;
+ }
+ }
+ if (found) {
+ obj = gr_object();
+ place_at(obj, row, col);
+ nf++;
+ }
+ }
+ return(nf);
+}
+
+get_room_number(row, col)
+register row, col;
+{
+ short i;
+
+ for (i = 0; i < MAXROOMS; i++) {
+ if ((row >= rooms[i].top_row) && (row <= rooms[i].bottom_row) &&
+ (col >= rooms[i].left_col) && (col <= rooms[i].right_col)) {
+ return(i);
+ }
+ }
+ return(NO_ROOM);
+}
+
+is_all_connected()
+{
+ short i, starting_room;
+
+ for (i = 0; i < MAXROOMS; i++) {
+ rooms_visited[i] = 0;
+ if (rooms[i].is_room & (R_ROOM | R_MAZE)) {
+ starting_room = i;
+ }
+ }
+
+ visit_rooms(starting_room);
+
+ for (i = 0; i < MAXROOMS; i++) {
+ if ((rooms[i].is_room & (R_ROOM | R_MAZE)) && (!rooms_visited[i])) {
+ return(0);
+ }
+ }
+ return(1);
+}
+
+visit_rooms(rn)
+int rn;
+{
+ short i;
+ short oth_rn;
+
+ rooms_visited[rn] = 1;
+
+ for (i = 0; i < 4; i++) {
+ oth_rn = rooms[rn].doors[i].oth_room;
+ if ((oth_rn >= 0) && (!rooms_visited[oth_rn])) {
+ visit_rooms(oth_rn);
+ }
+ }
+}
+
+draw_magic_map()
+{
+ short i, j, ch, och;
+ unsigned short mask = (HORWALL | VERTWALL | DOOR | TUNNEL | TRAP | STAIRS |
+ MONSTER);
+ unsigned short s;
+
+ for (i = 0; i < DROWS; i++) {
+ for (j = 0; j < DCOLS; j++) {
+ s = dungeon[i][j];
+ if (s & mask) {
+ if (((ch = mvinch(i, j)) == ' ') ||
+ ((ch >= 'A') && (ch <= 'Z')) || (s & (TRAP | HIDDEN))) {
+ och = ch;
+ dungeon[i][j] &= (~HIDDEN);
+ if (s & HORWALL) {
+ ch = '-';
+ } else if (s & VERTWALL) {
+ ch = '|';
+ } else if (s & DOOR) {
+ ch = '+';
+ } else if (s & TRAP) {
+ ch = '^';
+ } else if (s & STAIRS) {
+ ch = '%';
+ } else if (s & TUNNEL) {
+ ch = '#';
+ } else {
+ continue;
+ }
+ if ((!(s & MONSTER)) || (och == ' ')) {
+ addch(ch);
+ }
+ if (s & MONSTER) {
+ object *monster;
+
+ if (monster = object_at(&level_monsters, i, j)) {
+ monster->trail_char = ch;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+dr_course(monster, entering, row, col)
+object *monster;
+boolean entering;
+short row, col;
+{
+ short i, j, k, rn;
+ short r, rr;
+
+ monster->row = row;
+ monster->col = col;
+
+ if (mon_sees(monster, rogue.row, rogue.col)) {
+ monster->trow = NO_ROOM;
+ return;
+ }
+ rn = get_room_number(row, col);
+
+ if (entering) { /* entering room */
+ /* look for door to some other room */
+ r = get_rand(0, MAXROOMS-1);
+ for (i = 0; i < MAXROOMS; i++) {
+ rr = (r + i) % MAXROOMS;
+ if ((!(rooms[rr].is_room & (R_ROOM | R_MAZE))) || (rr == rn)) {
+ continue;
+ }
+ for (k = 0; k < 4; k++) {
+ if (rooms[rr].doors[k].oth_room == rn) {
+ monster->trow = rooms[rr].doors[k].oth_row;
+ monster->tcol = rooms[rr].doors[k].oth_col;
+ if ((monster->trow == row) &&
+ (monster->tcol == col)) {
+ continue;
+ }
+ return;
+ }
+ }
+ }
+ /* look for door to dead end */
+ for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) {
+ for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) {
+ if ((i != monster->row) && (j != monster->col) &&
+ (dungeon[i][j] & DOOR)) {
+ monster->trow = i;
+ monster->tcol = j;
+ return;
+ }
+ }
+ }
+ /* return monster to room that he came from */
+ for (i = 0; i < MAXROOMS; i++) {
+ for (j = 0; j < 4; j++) {
+ if (rooms[i].doors[j].oth_room == rn) {
+ for (k = 0; k < 4; k++) {
+ if (rooms[rn].doors[k].oth_room == i) {
+ monster->trow = rooms[rn].doors[k].oth_row;
+ monster->tcol = rooms[rn].doors[k].oth_col;
+ return;
+ }
+ }
+ }
+ }
+ }
+ /* no place to send monster */
+ monster->trow = NO_ROOM;
+ } else { /* exiting room */
+ if (!get_oth_room(rn, &row, &col)) {
+ monster->trow = NO_ROOM;
+ } else {
+ monster->trow = row;
+ monster->tcol = col;
+ }
+ }
+}
+
+get_oth_room(rn, row, col)
+short rn, *row, *col;
+{
+ short d = -1;
+
+ if (*row == rooms[rn].top_row) {
+ d = UPWARD/2;
+ } else if (*row == rooms[rn].bottom_row) {
+ d = DOWN/2;
+ } else if (*col == rooms[rn].left_col) {
+ d = LEFT/2;
+ } else if (*col == rooms[rn].right_col) {
+ d = RIGHT/2;
+ }
+ if ((d != -1) && (rooms[rn].doors[d].oth_room >= 0)) {
+ *row = rooms[rn].doors[d].oth_row;
+ *col = rooms[rn].doors[d].oth_col;
+ return(1);
+ }
+ return(0);
+}
+
+edit_opts()
+{
+ char save[NOPTS+1][DCOLS];
+ short i, j;
+ short ch;
+ boolean done = 0;
+ char buf[MAX_OPT_LEN + 2];
+
+ for (i = 0; i < NOPTS+1; i++) {
+ for (j = 0; j < DCOLS; j++) {
+ save[i][j] = mvinch(i, j);
+ }
+ if (i < NOPTS) {
+ opt_show(i);
+ }
+ }
+ opt_go(0);
+ i = 0;
+
+ while (!done) {
+ refresh();
+ ch = rgetchar();
+CH:
+ switch(ch) {
+ case '\033':
+ done = 1;
+ break;
+ case '\012':
+ case '\015':
+ if (i == (NOPTS - 1)) {
+ mvaddstr(NOPTS, 0, press_space);
+ refresh();
+ wait_for_ack();
+ done = 1;
+ } else {
+ i++;
+ opt_go(i);
+ }
+ break;
+ case '-':
+ if (i > 0) {
+ opt_go(--i);
+ } else {
+ sound_bell();
+ }
+ break;
+ case 't':
+ case 'T':
+ case 'f':
+ case 'F':
+ if (options[i].is_bool) {
+ *(options[i].bval) = (((ch == 't') || (ch == 'T')) ? 1 : 0);
+ opt_show(i);
+ opt_go(++i);
+ break;
+ }
+ default:
+ if (options[i].is_bool) {
+ sound_bell();
+ break;
+ }
+ j = 0;
+ if ((ch == '\010') || ((ch >= ' ') && (ch <= '~'))) {
+ opt_erase(i);
+ do {
+ if ((ch >= ' ') && (ch <= '~') && (j < MAX_OPT_LEN)) {
+ buf[j++] = ch;
+ buf[j] = '\0';
+ addch(ch);
+ } else if ((ch == '\010') && (j > 0)) {
+ buf[--j] = '\0';
+ move(i, j + strlen(options[i].prompt));
+ addch(' ');
+ move(i, j + strlen(options[i].prompt));
+ }
+ refresh();
+ ch = rgetchar();
+ } while ((ch != '\012') && (ch != '\015') && (ch != '\033'));
+ if (j != 0) {
+ (void) strcpy(*(options[i].strval), buf);
+ }
+ opt_show(i);
+ goto CH;
+ } else {
+ sound_bell();
+ }
+ break;
+ }
+ }
+
+ for (i = 0; i < NOPTS+1; i++) {
+ move(i, 0);
+ for (j = 0; j < DCOLS; j++) {
+ addch(save[i][j]);
+ }
+ }
+}
+
+opt_show(i)
+int i;
+{
+ char *s;
+ struct option *opt = &options[i];
+
+ opt_erase(i);
+
+ if (opt->is_bool) {
+ s = *(opt->bval) ? "True" : "False";
+ } else {
+ s = *(opt->strval);
+ }
+ addstr(s);
+}
+
+opt_erase(i)
+int i;
+{
+ struct option *opt = &options[i];
+
+ mvaddstr(i, 0, opt->prompt);
+ clrtoeol();
+}
+
+opt_go(i)
+int i;
+{
+ move(i, strlen(options[i].prompt));
+}
+
+do_shell()
+{
+#ifdef UNIX
+ char *sh;
+
+ md_ignore_signals();
+ if (!(sh = md_getenv("SHELL"))) {
+ sh = "/bin/sh";
+ }
+ move(LINES-1, 0);
+ refresh();
+ stop_window();
+ printf("\nCreating new shell...\n");
+ md_shell(sh);
+ start_window();
+ wrefresh(curscr);
+ md_heed_signals();
+#endif
+}
diff --git a/rogue/save.c b/rogue/save.c
new file mode 100644
index 00000000..54300e4e
--- /dev/null
+++ b/rogue/save.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)save.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * save.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include <stdio.h>
+#include "rogue.h"
+
+short write_failed = 0;
+char *save_file = (char *) 0;
+
+extern boolean detect_monster;
+extern short cur_level, max_level;
+extern char hunger_str[];
+extern char login_name[];
+extern short party_room;
+extern short foods;
+extern boolean is_wood[];
+extern short cur_room;
+extern boolean being_held;
+extern short bear_trap;
+extern short halluc;
+extern short blind;
+extern short confused;
+extern short levitate;
+extern short haste_self;
+extern boolean see_invisible;
+extern boolean detect_monster;
+extern boolean wizard;
+extern boolean score_only;
+extern short m_moves;
+
+extern boolean msg_cleared;
+
+save_game()
+{
+ char fname[64];
+
+ if (!get_input_line("file name?", save_file, fname, "game not saved",
+ 0, 1)) {
+ return;
+ }
+ check_message();
+ message(fname, 0);
+ save_into_file(fname);
+}
+
+save_into_file(sfile)
+char *sfile;
+{
+ FILE *fp;
+ int file_id;
+ char name_buffer[80];
+ char *hptr;
+ struct rogue_time rt_buf;
+
+ if (sfile[0] == '~') {
+ if (hptr = md_getenv("HOME")) {
+ (void) strcpy(name_buffer, hptr);
+ (void) strcat(name_buffer, sfile+1);
+ sfile = name_buffer;
+ }
+ }
+ if ( ((fp = fopen(sfile, "w")) == NULL) ||
+ ((file_id = md_get_file_id(sfile)) == -1)) {
+ message("problem accessing the save file", 0);
+ return;
+ }
+ md_ignore_signals();
+ write_failed = 0;
+ (void) xxx(1);
+ r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
+ r_write(fp, (char *) &cur_level, sizeof(cur_level));
+ r_write(fp, (char *) &max_level, sizeof(max_level));
+ write_string(hunger_str, fp);
+ write_string(login_name, fp);
+ r_write(fp, (char *) &party_room, sizeof(party_room));
+ write_pack(&level_monsters, fp);
+ write_pack(&level_objects, fp);
+ r_write(fp, (char *) &file_id, sizeof(file_id));
+ rw_dungeon(fp, 1);
+ r_write(fp, (char *) &foods, sizeof(foods));
+ r_write(fp, (char *) &rogue, sizeof(fighter));
+ write_pack(&rogue.pack, fp);
+ rw_id(id_potions, fp, POTIONS, 1);
+ rw_id(id_scrolls, fp, SCROLS, 1);
+ rw_id(id_wands, fp, WANDS, 1);
+ rw_id(id_rings, fp, RINGS, 1);
+ r_write(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
+ r_write(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
+ r_write(fp, (char *) &cur_room, sizeof(cur_room));
+ rw_rooms(fp, 1);
+ r_write(fp, (char *) &being_held, sizeof(being_held));
+ r_write(fp, (char *) &bear_trap, sizeof(bear_trap));
+ r_write(fp, (char *) &halluc, sizeof(halluc));
+ r_write(fp, (char *) &blind, sizeof(blind));
+ r_write(fp, (char *) &confused, sizeof(confused));
+ r_write(fp, (char *) &levitate, sizeof(levitate));
+ r_write(fp, (char *) &haste_self, sizeof(haste_self));
+ r_write(fp, (char *) &see_invisible, sizeof(see_invisible));
+ r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
+ r_write(fp, (char *) &wizard, sizeof(wizard));
+ r_write(fp, (char *) &score_only, sizeof(score_only));
+ r_write(fp, (char *) &m_moves, sizeof(m_moves));
+ md_gct(&rt_buf);
+ rt_buf.second += 10; /* allow for some processing time */
+ r_write(fp, (char *) &rt_buf, sizeof(rt_buf));
+ fclose(fp);
+
+ if (write_failed) {
+ (void) md_df(sfile); /* delete file */
+ } else {
+ clean_up("");
+ }
+}
+
+restore(fname)
+char *fname;
+{
+ FILE *fp;
+ struct rogue_time saved_time, mod_time;
+ char buf[4];
+ char tbuf[40];
+ int new_file_id, saved_file_id;
+
+ if ( ((new_file_id = md_get_file_id(fname)) == -1) ||
+ ((fp = fopen(fname, "r")) == NULL)) {
+ clean_up("cannot open file");
+ }
+ if (md_link_count(fname) > 1) {
+ clean_up("file has link");
+ }
+ (void) xxx(1);
+ r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
+ r_read(fp, (char *) &cur_level, sizeof(cur_level));
+ r_read(fp, (char *) &max_level, sizeof(max_level));
+ read_string(hunger_str, fp);
+
+ (void) strcpy(tbuf, login_name);
+ read_string(login_name, fp);
+ if (strcmp(tbuf, login_name)) {
+ clean_up("you're not the original player");
+ }
+
+ r_read(fp, (char *) &party_room, sizeof(party_room));
+ read_pack(&level_monsters, fp, 0);
+ read_pack(&level_objects, fp, 0);
+ r_read(fp, (char *) &saved_file_id, sizeof(saved_file_id));
+ if (new_file_id != saved_file_id) {
+ clean_up("sorry, saved game is not in the same file");
+ }
+ rw_dungeon(fp, 0);
+ r_read(fp, (char *) &foods, sizeof(foods));
+ r_read(fp, (char *) &rogue, sizeof(fighter));
+ read_pack(&rogue.pack, fp, 1);
+ rw_id(id_potions, fp, POTIONS, 0);
+ rw_id(id_scrolls, fp, SCROLS, 0);
+ rw_id(id_wands, fp, WANDS, 0);
+ rw_id(id_rings, fp, RINGS, 0);
+ r_read(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
+ r_read(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
+ r_read(fp, (char *) &cur_room, sizeof(cur_room));
+ rw_rooms(fp, 0);
+ r_read(fp, (char *) &being_held, sizeof(being_held));
+ r_read(fp, (char *) &bear_trap, sizeof(bear_trap));
+ r_read(fp, (char *) &halluc, sizeof(halluc));
+ r_read(fp, (char *) &blind, sizeof(blind));
+ r_read(fp, (char *) &confused, sizeof(confused));
+ r_read(fp, (char *) &levitate, sizeof(levitate));
+ r_read(fp, (char *) &haste_self, sizeof(haste_self));
+ r_read(fp, (char *) &see_invisible, sizeof(see_invisible));
+ r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
+ r_read(fp, (char *) &wizard, sizeof(wizard));
+ r_read(fp, (char *) &score_only, sizeof(score_only));
+ r_read(fp, (char *) &m_moves, sizeof(m_moves));
+ r_read(fp, (char *) &saved_time, sizeof(saved_time));
+
+ if (fread(buf, sizeof(char), 1, fp) > 0) {
+ clear();
+ clean_up("extra characters in file");
+ }
+
+ md_gfmt(fname, &mod_time); /* get file modification time */
+
+ if (has_been_touched(&saved_time, &mod_time)) {
+ clear();
+ clean_up("sorry, file has been touched");
+ }
+ if ((!wizard) && !md_df(fname)) {
+ clean_up("cannot delete file");
+ }
+ msg_cleared = 0;
+ ring_stats(0);
+ fclose(fp);
+}
+
+write_pack(pack, fp)
+object *pack;
+FILE *fp;
+{
+ object t;
+
+ while (pack = pack->next_object) {
+ r_write(fp, (char *) pack, sizeof(object));
+ }
+ t.ichar = t.what_is = 0;
+ r_write(fp, (char *) &t, sizeof(object));
+}
+
+read_pack(pack, fp, is_rogue)
+object *pack;
+FILE *fp;
+boolean is_rogue;
+{
+ object read_obj, *new_obj;
+
+ for (;;) {
+ r_read(fp, (char *) &read_obj, sizeof(object));
+ if (read_obj.ichar == 0) {
+ pack->next_object = (object *) 0;
+ break;
+ }
+ new_obj = alloc_object();
+ *new_obj = read_obj;
+ if (is_rogue) {
+ if (new_obj->in_use_flags & BEING_WORN) {
+ do_wear(new_obj);
+ } else if (new_obj->in_use_flags & BEING_WIELDED) {
+ do_wield(new_obj);
+ } else if (new_obj->in_use_flags & (ON_EITHER_HAND)) {
+ do_put_on(new_obj,
+ ((new_obj->in_use_flags & ON_LEFT_HAND) ? 1 : 0));
+ }
+ }
+ pack->next_object = new_obj;
+ pack = new_obj;
+ }
+}
+
+rw_dungeon(fp, rw)
+FILE *fp;
+boolean rw;
+{
+ short i, j;
+ char buf[DCOLS];
+
+ for (i = 0; i < DROWS; i++) {
+ if (rw) {
+ r_write(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
+ for (j = 0; j < DCOLS; j++) {
+ buf[j] = mvinch(i, j);
+ }
+ r_write(fp, buf, DCOLS);
+ } else {
+ r_read(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
+ r_read(fp, buf, DCOLS);
+ for (j = 0; j < DCOLS; j++) {
+ mvaddch(i, j, buf[j]);
+ }
+ }
+ }
+}
+
+rw_id(id_table, fp, n, wr)
+struct id id_table[];
+FILE *fp;
+int n;
+boolean wr;
+{
+ short i;
+
+ for (i = 0; i < n; i++) {
+ if (wr) {
+ r_write(fp, (char *) &(id_table[i].value), sizeof(short));
+ r_write(fp, (char *) &(id_table[i].id_status),
+ sizeof(unsigned short));
+ write_string(id_table[i].title, fp);
+ } else {
+ r_read(fp, (char *) &(id_table[i].value), sizeof(short));
+ r_read(fp, (char *) &(id_table[i].id_status),
+ sizeof(unsigned short));
+ read_string(id_table[i].title, fp);
+ }
+ }
+}
+
+write_string(s, fp)
+char *s;
+FILE *fp;
+{
+ short n;
+
+ n = strlen(s) + 1;
+ xxxx(s, n);
+ r_write(fp, (char *) &n, sizeof(short));
+ r_write(fp, s, n);
+}
+
+read_string(s, fp)
+char *s;
+FILE *fp;
+{
+ short n;
+
+ r_read(fp, (char *) &n, sizeof(short));
+ r_read(fp, s, n);
+ xxxx(s, n);
+}
+
+rw_rooms(fp, rw)
+FILE *fp;
+boolean rw;
+{
+ short i;
+
+ for (i = 0; i < MAXROOMS; i++) {
+ rw ? r_write(fp, (char *) (rooms + i), sizeof(room)) :
+ r_read(fp, (char *) (rooms + i), sizeof(room));
+ }
+}
+
+r_read(fp, buf, n)
+FILE *fp;
+char *buf;
+int n;
+{
+ if (fread(buf, sizeof(char), n, fp) != n) {
+ clean_up("read() failed, don't know why");
+ }
+}
+
+r_write(fp, buf, n)
+FILE *fp;
+char *buf;
+int n;
+{
+ if (!write_failed) {
+ if (fwrite(buf, sizeof(char), n, fp) != n) {
+ message("write() failed, don't know why", 0);
+ sound_bell();
+ write_failed = 1;
+ }
+ }
+}
+
+boolean
+has_been_touched(saved_time, mod_time)
+struct rogue_time *saved_time, *mod_time;
+{
+ if (saved_time->year < mod_time->year) {
+ return(1);
+ } else if (saved_time->year > mod_time->year) {
+ return(0);
+ }
+ if (saved_time->month < mod_time->month) {
+ return(1);
+ } else if (saved_time->month > mod_time->month) {
+ return(0);
+ }
+ if (saved_time->day < mod_time->day) {
+ return(1);
+ } else if (saved_time->day > mod_time->day) {
+ return(0);
+ }
+ if (saved_time->hour < mod_time->hour) {
+ return(1);
+ } else if (saved_time->hour > mod_time->hour) {
+ return(0);
+ }
+ if (saved_time->minute < mod_time->minute) {
+ return(1);
+ } else if (saved_time->minute > mod_time->minute) {
+ return(0);
+ }
+ if (saved_time->second < mod_time->second) {
+ return(1);
+ }
+ return(0);
+}
diff --git a/rogue/score.c b/rogue/score.c
new file mode 100644
index 00000000..6b1a06fd
--- /dev/null
+++ b/rogue/score.c
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)score.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * score.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include <stdio.h>
+#include "rogue.h"
+#include "pathnames.h"
+
+extern char login_name[];
+extern char *m_names[];
+extern short max_level;
+extern boolean score_only, no_skull, msg_cleared;
+extern char *byebye_string, *nick_name;
+
+killed_by(monster, other)
+object *monster;
+short other;
+{
+ char buf[128];
+
+ md_ignore_signals();
+
+ if (other != QUIT) {
+ rogue.gold = ((rogue.gold * 9) / 10);
+ }
+
+ if (other) {
+ switch(other) {
+ case HYPOTHERMIA:
+ (void) strcpy(buf, "died of hypothermia");
+ break;
+ case STARVATION:
+ (void) strcpy(buf, "died of starvation");
+ break;
+ case POISON_DART:
+ (void) strcpy(buf, "killed by a dart");
+ break;
+ case QUIT:
+ (void) strcpy(buf, "quit");
+ break;
+ case KFIRE:
+ (void) strcpy(buf, "killed by fire");
+ break;
+ }
+ } else {
+ (void) strcpy(buf, "Killed by ");
+ if (is_vowel(m_names[monster->m_char - 'A'][0])) {
+ (void) strcat(buf, "an ");
+ } else {
+ (void) strcat(buf, "a ");
+ }
+ (void) strcat(buf, m_names[monster->m_char - 'A']);
+ }
+ (void) strcat(buf, " with ");
+ sprintf(buf+strlen(buf), "%ld gold", rogue.gold);
+ if ((!other) && (!no_skull)) {
+ clear();
+ mvaddstr(4, 32, "__---------__");
+ mvaddstr(5, 30, "_~ ~_");
+ mvaddstr(6, 29, "/ \\");
+ mvaddstr(7, 28, "~ ~");
+ mvaddstr(8, 27, "/ \\");
+ mvaddstr(9, 27, "| XXXX XXXX |");
+ mvaddstr(10, 27, "| XXXX XXXX |");
+ mvaddstr(11, 27, "| XXX XXX |");
+ mvaddstr(12, 28, "\\ @ /");
+ mvaddstr(13, 29, "--\\ @@@ /--");
+ mvaddstr(14, 30, "| | @@@ | |");
+ mvaddstr(15, 30, "| | | |");
+ mvaddstr(16, 30, "| vvVvvvvvvvVvv |");
+ mvaddstr(17, 30, "| ^^^^^^^^^^^ |");
+ mvaddstr(18, 31, "\\_ _/");
+ mvaddstr(19, 33, "~---------~");
+ center(21, nick_name);
+ center(22, buf);
+ } else {
+ message(buf, 0);
+ }
+ message("", 0);
+ put_scores(monster, other);
+}
+
+win()
+{
+ unwield(rogue.weapon); /* disarm and relax */
+ unwear(rogue.armor);
+ un_put_on(rogue.left_ring);
+ un_put_on(rogue.right_ring);
+
+ clear();
+ mvaddstr(10, 11, "@ @ @@@ @ @ @ @ @ @@@ @ @ @");
+ mvaddstr(11, 11, " @ @ @ @ @ @ @ @ @ @ @ @@ @ @");
+ mvaddstr(12, 11, " @ @ @ @ @ @ @ @ @ @ @ @ @ @");
+ mvaddstr(13, 11, " @ @ @ @ @ @ @ @ @ @ @ @@");
+ mvaddstr(14, 11, " @ @@@ @@@ @@ @@ @@@ @ @ @");
+ mvaddstr(17, 11, "Congratulations, you have been admitted to the");
+ mvaddstr(18, 11, "Fighters' Guild. You return home, sell all your");
+ mvaddstr(19, 11, "treasures at great profit and retire into comfort.");
+ message("", 0);
+ message("", 0);
+ id_all();
+ sell_pack();
+ put_scores((object *) 0, WIN);
+}
+
+quit(from_intrpt)
+boolean from_intrpt;
+{
+ char buf[128];
+ short i, orow, ocol;
+ boolean mc;
+
+ md_ignore_signals();
+
+ if (from_intrpt) {
+ orow = rogue.row;
+ ocol = rogue.col;
+
+ mc = msg_cleared;
+
+ for (i = 0; i < DCOLS; i++) {
+ buf[i] = mvinch(0, i);
+ }
+ }
+ check_message();
+ message("really quit?", 1);
+ if (rgetchar() != 'y') {
+ md_heed_signals();
+ check_message();
+ if (from_intrpt) {
+ for (i = 0; i < DCOLS; i++) {
+ mvaddch(0, i, buf[i]);
+ }
+ msg_cleared = mc;
+ move(orow, ocol);
+ refresh();
+ }
+ return;
+ }
+ if (from_intrpt) {
+ clean_up(byebye_string);
+ }
+ check_message();
+ killed_by((object *) 0, QUIT);
+}
+
+put_scores(monster, other)
+object *monster;
+short other;
+{
+ short i, n, rank = 10, x, ne = 0, found_player = -1;
+ char scores[10][82];
+ char n_names[10][30];
+ char buf[128];
+ FILE *fp;
+ long s;
+ boolean pause = score_only;
+
+ md_lock(1);
+
+ if ((fp = fopen(_PATH_SCOREFILE, "a+")) == NULL) {
+ message("cannot read/write/create score file", 0);
+ sf_error();
+ }
+ rewind(fp);
+ (void) xxx(1);
+
+ for (i = 0; i < 10; i++) {
+ if (((n = fread(scores[i], sizeof(char), 80, fp)) < 80) && (n != 0)) {
+ sf_error();
+ } else if (n != 0) {
+ xxxx(scores[i], 80);
+ if ((n = fread(n_names[i], sizeof(char), 30, fp)) < 30) {
+ sf_error();
+ }
+ xxxx(n_names[i], 30);
+ } else {
+ break;
+ }
+ ne++;
+ if ((!score_only) && (found_player == -1)) {
+ if (!name_cmp(scores[i]+15, login_name)) {
+ x = 5;
+ while (scores[i][x] == ' ') {
+ x++;
+ }
+ s = lget_number(scores[i] + x);
+ if (rogue.gold < s) {
+ score_only = 1;
+ } else {
+ found_player = i;
+ }
+ }
+ }
+ }
+ if (found_player != -1) {
+ ne--;
+ for (i = found_player; i < ne; i++) {
+ (void) strcpy(scores[i], scores[i+1]);
+ (void) strcpy(n_names[i], n_names[i+1]);
+ }
+ }
+ if (!score_only) {
+ for (i = 0; i < ne; i++) {
+ x = 5;
+ while (scores[i][x] == ' ') {
+ x++;
+ }
+ s = lget_number(scores[i] + x);
+
+ if (rogue.gold >= s) {
+ rank = i;
+ break;
+ }
+ }
+ if (ne == 0) {
+ rank = 0;
+ } else if ((ne < 10) && (rank == 10)) {
+ rank = ne;
+ }
+ if (rank < 10) {
+ insert_score(scores, n_names, nick_name, rank, ne, monster,
+ other);
+ if (ne < 10) {
+ ne++;
+ }
+ }
+ rewind(fp);
+ }
+
+ clear();
+ mvaddstr(3, 30, "Top Ten Rogueists");
+ mvaddstr(8, 0, "Rank Score Name");
+
+ md_ignore_signals();
+
+ (void) xxx(1);
+
+ for (i = 0; i < ne; i++) {
+ if (i == rank) {
+ standout();
+ }
+ if (i == 9) {
+ scores[i][0] = '1';
+ scores[i][1] = '0';
+ } else {
+ scores[i][0] = ' ';
+ scores[i][1] = i + '1';
+ }
+ nickize(buf, scores[i], n_names[i]);
+ mvaddstr(i+10, 0, buf);
+ if (rank < 10) {
+ xxxx(scores[i], 80);
+ fwrite(scores[i], sizeof(char), 80, fp);
+ xxxx(n_names[i], 30);
+ fwrite(n_names[i], sizeof(char), 30, fp);
+ }
+ if (i == rank) {
+ standend();
+ }
+ }
+ md_lock(0);
+ refresh();
+ fclose(fp);
+ message("", 0);
+ if (pause) {
+ message("", 0);
+ }
+ clean_up("");
+}
+
+insert_score(scores, n_names, n_name, rank, n, monster, other)
+char scores[][82];
+char n_names[][30];
+char *n_name;
+short rank, n;
+object *monster;
+{
+ short i;
+ char buf[128];
+
+ if (n > 0) {
+ for (i = n; i > rank; i--) {
+ if ((i < 10) && (i > 0)) {
+ (void) strcpy(scores[i], scores[i-1]);
+ (void) strcpy(n_names[i], n_names[i-1]);
+ }
+ }
+ }
+ sprintf(buf, "%2d %6d %s: ", rank+1, rogue.gold, login_name);
+
+ if (other) {
+ switch(other) {
+ case HYPOTHERMIA:
+ (void) strcat(buf, "died of hypothermia");
+ break;
+ case STARVATION:
+ (void) strcat(buf, "died of starvation");
+ break;
+ case POISON_DART:
+ (void) strcat(buf, "killed by a dart");
+ break;
+ case QUIT:
+ (void) strcat(buf, "quit");
+ break;
+ case WIN:
+ (void) strcat(buf, "a total winner");
+ break;
+ case KFIRE:
+ (void) strcpy(buf, "killed by fire");
+ break;
+ }
+ } else {
+ (void) strcat(buf, "killed by ");
+ if (is_vowel(m_names[monster->m_char - 'A'][0])) {
+ (void) strcat(buf, "an ");
+ } else {
+ (void) strcat(buf, "a ");
+ }
+ (void) strcat(buf, m_names[monster->m_char - 'A']);
+ }
+ sprintf(buf+strlen(buf), " on level %d ", max_level);
+ if ((other != WIN) && has_amulet()) {
+ (void) strcat(buf, "with amulet");
+ }
+ for (i = strlen(buf); i < 79; i++) {
+ buf[i] = ' ';
+ }
+ buf[79] = 0;
+ (void) strcpy(scores[rank], buf);
+ (void) strcpy(n_names[rank], n_name);
+}
+
+is_vowel(ch)
+short ch;
+{
+ return( (ch == 'a') ||
+ (ch == 'e') ||
+ (ch == 'i') ||
+ (ch == 'o') ||
+ (ch == 'u') );
+}
+
+sell_pack()
+{
+ object *obj;
+ short row = 2, val;
+ char buf[DCOLS];
+
+ obj = rogue.pack.next_object;
+
+ clear();
+ mvaddstr(1, 0, "Value Item");
+
+ while (obj) {
+ if (obj->what_is != FOOD) {
+ obj->identified = 1;
+ val = get_value(obj);
+ rogue.gold += val;
+
+ if (row < DROWS) {
+ sprintf(buf, "%5d ", val);
+ get_desc(obj, buf+11);
+ mvaddstr(row++, 0, buf);
+ }
+ }
+ obj = obj->next_object;
+ }
+ refresh();
+ if (rogue.gold > MAX_GOLD) {
+ rogue.gold = MAX_GOLD;
+ }
+ message("", 0);
+}
+
+get_value(obj)
+object *obj;
+{
+ short wc;
+ int val;
+
+ wc = obj->which_kind;
+
+ switch(obj->what_is) {
+ case WEAPON:
+ val = id_weapons[wc].value;
+ if ((wc == ARROW) || (wc == DAGGER) || (wc == SHURIKEN) ||
+ (wc == DART)) {
+ val *= obj->quantity;
+ }
+ val += (obj->d_enchant * 85);
+ val += (obj->hit_enchant * 85);
+ break;
+ case ARMOR:
+ val = id_armors[wc].value;
+ val += (obj->d_enchant * 75);
+ if (obj->is_protected) {
+ val += 200;
+ }
+ break;
+ case WAND:
+ val = id_wands[wc].value * (obj->class + 1);
+ break;
+ case SCROL:
+ val = id_scrolls[wc].value * obj->quantity;
+ break;
+ case POTION:
+ val = id_potions[wc].value * obj->quantity;
+ break;
+ case AMULET:
+ val = 5000;
+ break;
+ case RING:
+ val = id_rings[wc].value * (obj->class + 1);
+ break;
+ }
+ if (val <= 0) {
+ val = 10;
+ }
+ return(val);
+}
+
+id_all()
+{
+ short i;
+
+ for (i = 0; i < SCROLS; i++) {
+ id_scrolls[i].id_status = IDENTIFIED;
+ }
+ for (i = 0; i < WEAPONS; i++) {
+ id_weapons[i].id_status = IDENTIFIED;
+ }
+ for (i = 0; i < ARMORS; i++) {
+ id_armors[i].id_status = IDENTIFIED;
+ }
+ for (i = 0; i < WANDS; i++) {
+ id_wands[i].id_status = IDENTIFIED;
+ }
+ for (i = 0; i < POTIONS; i++) {
+ id_potions[i].id_status = IDENTIFIED;
+ }
+}
+
+name_cmp(s1, s2)
+char *s1, *s2;
+{
+ short i = 0;
+ int r;
+
+ while(s1[i] != ':') {
+ i++;
+ }
+ s1[i] = 0;
+ r = strcmp(s1, s2);
+ s1[i] = ':';
+ return(r);
+}
+
+xxxx(buf, n)
+char *buf;
+short n;
+{
+ short i;
+ unsigned char c;
+
+ for (i = 0; i < n; i++) {
+
+ /* It does not matter if accuracy is lost during this assignment */
+ c = (unsigned char) xxx(0);
+
+ buf[i] ^= c;
+ }
+}
+
+long
+xxx(st)
+boolean st;
+{
+ static long f, s;
+ long r;
+
+ if (st) {
+ f = 37;
+ s = 7;
+ return(0L);
+ }
+ r = ((f * s) + 9337) % 8887;
+ f = s;
+ s = r;
+ return(r);
+}
+
+nickize(buf, score, n_name)
+char *buf, *score, *n_name;
+{
+ short i = 15, j;
+
+ if (!n_name[0]) {
+ (void) strcpy(buf, score);
+ } else {
+ (void) strncpy(buf, score, 16);
+
+ while (score[i] != ':') {
+ i++;
+ }
+
+ (void) strcpy(buf+15, n_name);
+ j = strlen(buf);
+
+ while (score[i]) {
+ buf[j++] = score[i++];
+ }
+ buf[j] = 0;
+ buf[79] = 0;
+ }
+}
+
+center(row, buf)
+short row;
+char *buf;
+{
+ short margin;
+
+ margin = ((DCOLS - strlen(buf)) / 2);
+ mvaddstr(row, margin, buf);
+}
+
+sf_error()
+{
+ md_lock(0);
+ message("", 1);
+ clean_up("sorry, score file is out of order");
+}
diff --git a/rogue/spec_hit.c b/rogue/spec_hit.c
new file mode 100644
index 00000000..25bb5db4
--- /dev/null
+++ b/rogue/spec_hit.c
@@ -0,0 +1,534 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)spec_hit.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * special_hit.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+short less_hp = 0;
+boolean being_held;
+
+extern short cur_level, max_level, blind, levitate, ring_exp;
+extern long level_points[];
+extern boolean detect_monster, mon_disappeared;
+extern boolean sustain_strength, maintain_armor;
+extern char *you_can_move_again;
+
+special_hit(monster)
+object *monster;
+{
+ if ((monster->m_flags & CONFUSED) && rand_percent(66)) {
+ return;
+ }
+ if (monster->m_flags & RUSTS) {
+ rust(monster);
+ }
+ if ((monster->m_flags & HOLDS) && !levitate) {
+ being_held = 1;
+ }
+ if (monster->m_flags & FREEZES) {
+ freeze(monster);
+ }
+ if (monster->m_flags & STINGS) {
+ sting(monster);
+ }
+ if (monster->m_flags & DRAINS_LIFE) {
+ drain_life();
+ }
+ if (monster->m_flags & DROPS_LEVEL) {
+ drop_level();
+ }
+ if (monster->m_flags & STEALS_GOLD) {
+ steal_gold(monster);
+ } else if (monster->m_flags & STEALS_ITEM) {
+ steal_item(monster);
+ }
+}
+
+rust(monster)
+object *monster;
+{
+ if ((!rogue.armor) || (get_armor_class(rogue.armor) <= 1) ||
+ (rogue.armor->which_kind == LEATHER)) {
+ return;
+ }
+ if ((rogue.armor->is_protected) || maintain_armor) {
+ if (monster && (!(monster->m_flags & RUST_VANISHED))) {
+ message("the rust vanishes instantly", 0);
+ monster->m_flags |= RUST_VANISHED;
+ }
+ } else {
+ rogue.armor->d_enchant--;
+ message("your armor weakens", 0);
+ print_stats(STAT_ARMOR);
+ }
+}
+
+freeze(monster)
+object *monster;
+{
+ short freeze_percent = 99;
+ short i, n;
+
+ if (rand_percent(12)) {
+ return;
+ }
+ freeze_percent -= (rogue.str_current+(rogue.str_current / 2));
+ freeze_percent -= ((rogue.exp + ring_exp) * 4);
+ freeze_percent -= (get_armor_class(rogue.armor) * 5);
+ freeze_percent -= (rogue.hp_max / 3);
+
+ if (freeze_percent > 10) {
+ monster->m_flags |= FREEZING_ROGUE;
+ message("you are frozen", 1);
+
+ n = get_rand(4, 8);
+ for (i = 0; i < n; i++) {
+ mv_mons();
+ }
+ if (rand_percent(freeze_percent)) {
+ for (i = 0; i < 50; i++) {
+ mv_mons();
+ }
+ killed_by((object *)0, HYPOTHERMIA);
+ }
+ message(you_can_move_again, 1);
+ monster->m_flags &= (~FREEZING_ROGUE);
+ }
+}
+
+steal_gold(monster)
+object *monster;
+{
+ int amount;
+
+ if ((rogue.gold <= 0) || rand_percent(10)) {
+ return;
+ }
+
+ amount = get_rand((cur_level * 10), (cur_level * 30));
+
+ if (amount > rogue.gold) {
+ amount = rogue.gold;
+ }
+ rogue.gold -= amount;
+ message("your purse feels lighter", 0);
+ print_stats(STAT_GOLD);
+ disappear(monster);
+}
+
+steal_item(monster)
+object *monster;
+{
+ object *obj;
+ short i, n, t;
+ char desc[80];
+ boolean has_something = 0;
+
+ if (rand_percent(15)) {
+ return;
+ }
+ obj = rogue.pack.next_object;
+
+ if (!obj) {
+ goto DSPR;
+ }
+ while (obj) {
+ if (!(obj->in_use_flags & BEING_USED)) {
+ has_something = 1;
+ break;
+ }
+ obj = obj->next_object;
+ }
+ if (!has_something) {
+ goto DSPR;
+ }
+ n = get_rand(0, MAX_PACK_COUNT);
+ obj = rogue.pack.next_object;
+
+ for (i = 0; i <= n; i++) {
+ obj = obj->next_object;
+ while ((!obj) || (obj->in_use_flags & BEING_USED)) {
+ if (!obj) {
+ obj = rogue.pack.next_object;
+ } else {
+ obj = obj->next_object;
+ }
+ }
+ }
+ (void) strcpy(desc, "she stole ");
+ if (obj->what_is != WEAPON) {
+ t = obj->quantity;
+ obj->quantity = 1;
+ }
+ get_desc(obj, desc+10);
+ message(desc, 0);
+
+ obj->quantity = ((obj->what_is != WEAPON) ? t : 1);
+
+ vanish(obj, 0, &rogue.pack);
+DSPR:
+ disappear(monster);
+}
+
+disappear(monster)
+object *monster;
+{
+ short row, col;
+
+ row = monster->row;
+ col = monster->col;
+
+ dungeon[row][col] &= ~MONSTER;
+ if (rogue_can_see(row, col)) {
+ mvaddch(row, col, get_dungeon_char(row, col));
+ }
+ take_from_pack(monster, &level_monsters);
+ free_object(monster);
+ mon_disappeared = 1;
+}
+
+cough_up(monster)
+object *monster;
+{
+ object *obj;
+ short row, col, i, n;
+
+ if (cur_level < max_level) {
+ return;
+ }
+
+ if (monster->m_flags & STEALS_GOLD) {
+ obj = alloc_object();
+ obj->what_is = GOLD;
+ obj->quantity = get_rand((cur_level * 15), (cur_level * 30));
+ } else {
+ if (!rand_percent((int) monster->drop_percent)) {
+ return;
+ }
+ obj = gr_object();
+ }
+ row = monster->row;
+ col = monster->col;
+
+ for (n = 0; n <= 5; n++) {
+ for (i = -n; i <= n; i++) {
+ if (try_to_cough(row+n, col+i, obj)) {
+ return;
+ }
+ if (try_to_cough(row-n, col+i, obj)) {
+ return;
+ }
+ }
+ for (i = -n; i <= n; i++) {
+ if (try_to_cough(row+i, col-n, obj)) {
+ return;
+ }
+ if (try_to_cough(row+i, col+n, obj)) {
+ return;
+ }
+ }
+ }
+ free_object(obj);
+}
+
+try_to_cough(row, col, obj)
+short row, col;
+object *obj;
+{
+ if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col>(DCOLS-1))) {
+ return(0);
+ }
+ if ((!(dungeon[row][col] & (OBJECT | STAIRS | TRAP))) &&
+ (dungeon[row][col] & (TUNNEL | FLOOR | DOOR))) {
+ place_at(obj, row, col);
+ if (((row != rogue.row) || (col != rogue.col)) &&
+ (!(dungeon[row][col] & MONSTER))) {
+ mvaddch(row, col, get_dungeon_char(row, col));
+ }
+ return(1);
+ }
+ return(0);
+}
+
+seek_gold(monster)
+object *monster;
+{
+ short i, j, rn, s;
+
+ if ((rn = get_room_number(monster->row, monster->col)) < 0) {
+ return(0);
+ }
+ for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
+ for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
+ if ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) {
+ monster->m_flags |= CAN_FLIT;
+ s = mon_can_go(monster, i, j);
+ monster->m_flags &= (~CAN_FLIT);
+ if (s) {
+ move_mon_to(monster, i, j);
+ monster->m_flags |= ASLEEP;
+ monster->m_flags &= (~(WAKENS | SEEKS_GOLD));
+ return(1);
+ }
+ monster->m_flags &= (~SEEKS_GOLD);
+ monster->m_flags |= CAN_FLIT;
+ mv_1_monster(monster, i, j);
+ monster->m_flags &= (~CAN_FLIT);
+ monster->m_flags |= SEEKS_GOLD;
+ return(1);
+ }
+ }
+ }
+ return(0);
+}
+
+gold_at(row, col)
+short row, col;
+{
+ if (dungeon[row][col] & OBJECT) {
+ object *obj;
+
+ if ((obj = object_at(&level_objects, row, col)) &&
+ (obj->what_is == GOLD)) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
+check_gold_seeker(monster)
+object *monster;
+{
+ monster->m_flags &= (~SEEKS_GOLD);
+}
+
+check_imitator(monster)
+object *monster;
+{
+ char msg[80];
+
+ if (monster->m_flags & IMITATES) {
+ wake_up(monster);
+ if (!blind) {
+ mvaddch(monster->row, monster->col,
+ get_dungeon_char(monster->row, monster->col));
+ check_message();
+ sprintf(msg, "wait, that's a %s!", mon_name(monster));
+ message(msg, 1);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+imitating(row, col)
+register short row, col;
+{
+ if (dungeon[row][col] & MONSTER) {
+ object *object_at(), *monster;
+
+ if (monster = object_at(&level_monsters, row, col)) {
+ if (monster->m_flags & IMITATES) {
+ return(1);
+ }
+ }
+ }
+ return(0);
+}
+
+sting(monster)
+object *monster;
+{
+ short sting_chance = 35;
+ char msg[80];
+
+ if ((rogue.str_current <= 3) || sustain_strength) {
+ return;
+ }
+ sting_chance += (6 * (6 - get_armor_class(rogue.armor)));
+
+ if ((rogue.exp + ring_exp) > 8) {
+ sting_chance -= (6 * ((rogue.exp + ring_exp) - 8));
+ }
+ if (rand_percent(sting_chance)) {
+ sprintf(msg, "the %s's bite has weakened you",
+ mon_name(monster));
+ message(msg, 0);
+ rogue.str_current--;
+ print_stats(STAT_STRENGTH);
+ }
+}
+
+drop_level()
+{
+ int hp;
+
+ if (rand_percent(80) || (rogue.exp <= 5)) {
+ return;
+ }
+ rogue.exp_points = level_points[rogue.exp-2] - get_rand(9, 29);
+ rogue.exp -= 2;
+ hp = hp_raise();
+ if ((rogue.hp_current -= hp) <= 0) {
+ rogue.hp_current = 1;
+ }
+ if ((rogue.hp_max -= hp) <= 0) {
+ rogue.hp_max = 1;
+ }
+ add_exp(1, 0);
+}
+
+drain_life()
+{
+ short n;
+
+ if (rand_percent(60) || (rogue.hp_max <= 30) || (rogue.hp_current < 10)) {
+ return;
+ }
+ n = get_rand(1, 3); /* 1 Hp, 2 Str, 3 both */
+
+ if ((n != 2) || (!sustain_strength)) {
+ message("you feel weaker", 0);
+ }
+ if (n != 2) {
+ rogue.hp_max--;
+ rogue.hp_current--;
+ less_hp++;
+ }
+ if (n != 1) {
+ if ((rogue.str_current > 3) && (!sustain_strength)) {
+ rogue.str_current--;
+ if (coin_toss()) {
+ rogue.str_max--;
+ }
+ }
+ }
+ print_stats((STAT_STRENGTH | STAT_HP));
+}
+
+m_confuse(monster)
+object *monster;
+{
+ char msg[80];
+
+ if (!rogue_can_see(monster->row, monster->col)) {
+ return(0);
+ }
+ if (rand_percent(45)) {
+ monster->m_flags &= (~CONFUSES); /* will not confuse the rogue */
+ return(0);
+ }
+ if (rand_percent(55)) {
+ monster->m_flags &= (~CONFUSES);
+ sprintf(msg, "the gaze of the %s has confused you", mon_name(monster));
+ message(msg, 1);
+ cnfs();
+ return(1);
+ }
+ return(0);
+}
+
+flame_broil(monster)
+object *monster;
+{
+ short row, col, dir;
+
+ if ((!mon_sees(monster, rogue.row, rogue.col)) || coin_toss()) {
+ return(0);
+ }
+ row = rogue.row - monster->row;
+ col = rogue.col - monster->col;
+ if (row < 0) {
+ row = -row;
+ }
+ if (col < 0) {
+ col = -col;
+ }
+ if (((row != 0) && (col != 0) && (row != col)) ||
+ ((row > 7) || (col > 7))) {
+ return(0);
+ }
+ dir = get_dir(monster->row, monster->col, row, col);
+ bounce(FIRE, dir, monster->row, monster->col, 0);
+
+ return(1);
+}
+
+get_dir(srow, scol, drow, dcol)
+short srow, scol, drow, dcol;
+{
+ if (srow == drow) {
+ if (scol < dcol) {
+ return(RIGHT);
+ } else {
+ return(LEFT);
+ }
+ }
+ if (scol == dcol) {
+ if (srow < drow) {
+ return(DOWN);
+ } else {
+ return(UPWARD);
+ }
+ }
+ if ((srow > drow) && (scol > dcol)) {
+ return(UPLEFT);
+ }
+ if ((srow < drow) && (scol < dcol)) {
+ return(DOWNRIGHT);
+ }
+ if ((srow < drow) && (scol > dcol)) {
+ return(DOWNLEFT);
+ }
+ /*if ((srow > drow) && (scol < dcol)) {*/
+ return(UPRIGHT);
+ /*}*/
+}
diff --git a/rogue/throw.c b/rogue/throw.c
new file mode 100644
index 00000000..ccb688d6
--- /dev/null
+++ b/rogue/throw.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)throw.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * throw.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+extern short cur_room;
+extern char *curse_message;
+extern char hit_message[];
+
+throw()
+{
+ short wch, d;
+ boolean first_miss = 1;
+ object *weapon;
+ short dir, row, col;
+ object *monster;
+
+ while (!is_direction(dir = rgetchar(), &d)) {
+ sound_bell();
+ if (first_miss) {
+ message("direction? ", 0);
+ first_miss = 0;
+ }
+ }
+ check_message();
+ if (dir == CANCEL) {
+ return;
+ }
+ if ((wch = pack_letter("throw what?", WEAPON)) == CANCEL) {
+ return;
+ }
+ check_message();
+
+ if (!(weapon = get_letter_object(wch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if ((weapon->in_use_flags & BEING_USED) && weapon->is_cursed) {
+ message(curse_message, 0);
+ return;
+ }
+ row = rogue.row; col = rogue.col;
+
+ if ((weapon->in_use_flags & BEING_WIELDED) && (weapon->quantity <= 1)) {
+ unwield(rogue.weapon);
+ } else if (weapon->in_use_flags & BEING_WORN) {
+ mv_aquatars();
+ unwear(rogue.armor);
+ print_stats(STAT_ARMOR);
+ } else if (weapon->in_use_flags & ON_EITHER_HAND) {
+ un_put_on(weapon);
+ }
+ monster = get_thrown_at_monster(weapon, d, &row, &col);
+ mvaddch(rogue.row, rogue.col, rogue.fchar);
+ refresh();
+
+ if (rogue_can_see(row, col) && ((row != rogue.row) || (col != rogue.col))){
+ mvaddch(row, col, get_dungeon_char(row, col));
+ }
+ if (monster) {
+ wake_up(monster);
+ check_gold_seeker(monster);
+
+ if (!throw_at_monster(monster, weapon)) {
+ flop_weapon(weapon, row, col);
+ }
+ } else {
+ flop_weapon(weapon, row, col);
+ }
+ vanish(weapon, 1, &rogue.pack);
+}
+
+throw_at_monster(monster, weapon)
+object *monster, *weapon;
+{
+ short damage, hit_chance;
+ short t;
+
+ hit_chance = get_hit_chance(weapon);
+ damage = get_weapon_damage(weapon);
+ if ((weapon->which_kind == ARROW) &&
+ (rogue.weapon && (rogue.weapon->which_kind == BOW))) {
+ damage += get_weapon_damage(rogue.weapon);
+ damage = ((damage * 2) / 3);
+ hit_chance += (hit_chance / 3);
+ } else if ((weapon->in_use_flags & BEING_WIELDED) &&
+ ((weapon->which_kind == DAGGER) ||
+ (weapon->which_kind == SHURIKEN) ||
+ (weapon->which_kind == DART))) {
+ damage = ((damage * 3) / 2);
+ hit_chance += (hit_chance / 3);
+ }
+ t = weapon->quantity;
+ weapon->quantity = 1;
+ sprintf(hit_message, "the %s", name_of(weapon));
+ weapon->quantity = t;
+
+ if (!rand_percent(hit_chance)) {
+ (void) strcat(hit_message, "misses ");
+ return(0);
+ }
+ s_con_mon(monster);
+ (void) strcat(hit_message, "hit ");
+ (void) mon_damage(monster, damage);
+ return(1);
+}
+
+object *
+get_thrown_at_monster(obj, dir, row, col)
+object *obj;
+short dir;
+short *row, *col;
+{
+ short orow, ocol;
+ short i, ch;
+
+ orow = *row; ocol = *col;
+
+ ch = get_mask_char(obj->what_is);
+
+ for (i = 0; i < 24; i++) {
+ get_dir_rc(dir, row, col, 0);
+ if ( (((*col <= 0) || (*col >= DCOLS-1)) ||
+ (dungeon[*row][*col] == NOTHING)) ||
+ ((dungeon[*row][*col] & (HORWALL | VERTWALL | HIDDEN)) &&
+ (!(dungeon[*row][*col] & TRAP)))) {
+ *row = orow;
+ *col = ocol;
+ return(0);
+ }
+ if ((i != 0) && rogue_can_see(orow, ocol)) {
+ mvaddch(orow, ocol, get_dungeon_char(orow, ocol));
+ }
+ if (rogue_can_see(*row, *col)) {
+ if (!(dungeon[*row][*col] & MONSTER)) {
+ mvaddch(*row, *col, ch);
+ }
+ refresh();
+ }
+ orow = *row; ocol = *col;
+ if (dungeon[*row][*col] & MONSTER) {
+ if (!imitating(*row, *col)) {
+ return(object_at(&level_monsters, *row, *col));
+ }
+ }
+ if (dungeon[*row][*col] & TUNNEL) {
+ i += 2;
+ }
+ }
+ return(0);
+}
+
+flop_weapon(weapon, row, col)
+object *weapon;
+short row, col;
+{
+ object *new_weapon, *monster;
+ short i = 0;
+ char msg[80];
+ boolean found = 0;
+ short mch, dch;
+ unsigned short mon;
+
+ while ((i < 9) && dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER)) {
+ rand_around(i++, &row, &col);
+ if ((row > (DROWS-2)) || (row < MIN_ROW) ||
+ (col > (DCOLS-1)) || (col < 0) || (!dungeon[row][col]) ||
+ (dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER))) {
+ continue;
+ }
+ found = 1;
+ break;
+ }
+
+ if (found || (i == 0)) {
+ new_weapon = alloc_object();
+ *new_weapon = *weapon;
+ new_weapon->in_use_flags = NOT_USED;
+ new_weapon->quantity = 1;
+ new_weapon->ichar = 'L';
+ place_at(new_weapon, row, col);
+ if (rogue_can_see(row, col) &&
+ ((row != rogue.row) || (col != rogue.col))) {
+ mon = dungeon[row][col] & MONSTER;
+ dungeon[row][col] &= (~MONSTER);
+ dch = get_dungeon_char(row, col);
+ if (mon) {
+ mch = mvinch(row, col);
+ if (monster = object_at(&level_monsters, row, col)) {
+ monster->trail_char = dch;
+ }
+ if ((mch < 'A') || (mch > 'Z')) {
+ mvaddch(row, col, dch);
+ }
+ } else {
+ mvaddch(row, col, dch);
+ }
+ dungeon[row][col] |= mon;
+ }
+ } else {
+ short t;
+
+ t = weapon->quantity;
+ weapon->quantity = 1;
+ sprintf(msg, "the %svanishes as it hits the ground",
+ name_of(weapon));
+ weapon->quantity = t;
+ message(msg, 0);
+ }
+}
+
+rand_around(i, r, c)
+short i, *r, *c;
+{
+ static char* pos = "\010\007\001\003\004\005\002\006\0";
+ static short row, col;
+ short j;
+
+ if (i == 0) {
+ short x, y, o, t;
+
+ row = *r;
+ col = *c;
+
+ o = get_rand(1, 8);
+
+ for (j = 0; j < 5; j++) {
+ x = get_rand(0, 8);
+ y = (x + o) % 9;
+ t = pos[x];
+ pos[x] = pos[y];
+ pos[y] = t;
+ }
+ }
+ switch((short)pos[i]) {
+ case 0:
+ *r = row + 1;
+ *c = col + 1;
+ break;
+ case 1:
+ *r = row + 1;
+ *c = col - 1;
+ break;
+ case 2:
+ *r = row - 1;
+ *c = col + 1;
+ break;
+ case 3:
+ *r = row - 1;
+ *c = col - 1;
+ break;
+ case 4:
+ *r = row;
+ *c = col + 1;
+ break;
+ case 5:
+ *r = row + 1;
+ *c = col;
+ break;
+ case 6:
+ *r = row;
+ *c = col;
+ break;
+ case 7:
+ *r = row - 1;
+ *c = col;
+ break;
+ case 8:
+ *r = row;
+ *c = col - 1;
+ break;
+ }
+}
diff --git a/rogue/trap.c b/rogue/trap.c
new file mode 100644
index 00000000..1f523ea2
--- /dev/null
+++ b/rogue/trap.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)trap.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * trap.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+trap traps[MAX_TRAPS];
+boolean trap_door = 0;
+short bear_trap = 0;
+
+char *trap_strings[TRAPS * 2] = {
+ "trap door",
+ "you fell down a trap",
+ "bear trap",
+ "you are caught in a bear trap",
+ "teleport trap",
+ "teleport",
+ "poison dart trap",
+ "a small dart just hit you in the shoulder",
+ "sleeping gas trap",
+ "a strange white mist envelops you and you fall asleep",
+ "rust trap",
+ "a gush of water hits you on the head"
+};
+
+extern short cur_level, party_room;
+extern char *new_level_message;
+extern boolean interrupted;
+extern short ring_exp;
+extern boolean sustain_strength;
+extern short blind;
+
+trap_at(row, col)
+register row, col;
+{
+ short i;
+
+ for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) {
+ if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) {
+ return(traps[i].trap_type);
+ }
+ }
+ return(NO_TRAP);
+}
+
+trap_player(row, col)
+short row, col;
+{
+ short t;
+
+ if ((t = trap_at(row, col)) == NO_TRAP) {
+ return;
+ }
+ dungeon[row][col] &= (~HIDDEN);
+ if (rand_percent(rogue.exp + ring_exp)) {
+ message("the trap failed", 1);
+ return;
+ }
+ switch(t) {
+ case TRAP_DOOR:
+ trap_door = 1;
+ new_level_message = trap_strings[(t*2)+1];
+ break;
+ case BEAR_TRAP:
+ message(trap_strings[(t*2)+1], 1);
+ bear_trap = get_rand(4, 7);
+ break;
+ case TELE_TRAP:
+ mvaddch(rogue.row, rogue.col, '^');
+ tele();
+ break;
+ case DART_TRAP:
+ message(trap_strings[(t*2)+1], 1);
+ rogue.hp_current -= get_damage("1d6", 1);
+ if (rogue.hp_current <= 0) {
+ rogue.hp_current = 0;
+ }
+ if ((!sustain_strength) && rand_percent(40) &&
+ (rogue.str_current >= 3)) {
+ rogue.str_current--;
+ }
+ print_stats(STAT_HP | STAT_STRENGTH);
+ if (rogue.hp_current <= 0) {
+ killed_by((object *) 0, POISON_DART);
+ }
+ break;
+ case SLEEPING_GAS_TRAP:
+ message(trap_strings[(t*2)+1], 1);
+ take_a_nap();
+ break;
+ case RUST_TRAP:
+ message(trap_strings[(t*2)+1], 1);
+ rust((object *) 0);
+ break;
+ }
+}
+
+add_traps()
+{
+ short i, n, tries = 0;
+ short row, col;
+
+ if (cur_level <= 2) {
+ n = 0;
+ } else if (cur_level <= 7) {
+ n = get_rand(0, 2);
+ } else if (cur_level <= 11) {
+ n = get_rand(1, 2);
+ } else if (cur_level <= 16) {
+ n = get_rand(2, 3);
+ } else if (cur_level <= 21) {
+ n = get_rand(2, 4);
+ } else if (cur_level <= (AMULET_LEVEL + 2)) {
+ n = get_rand(3, 5);
+ } else {
+ n = get_rand(5, MAX_TRAPS);
+ }
+ for (i = 0; i < n; i++) {
+ traps[i].trap_type = get_rand(0, (TRAPS - 1));
+
+ if ((i == 0) && (party_room != NO_ROOM)) {
+ do {
+ row = get_rand((rooms[party_room].top_row+1),
+ (rooms[party_room].bottom_row-1));
+ col = get_rand((rooms[party_room].left_col+1),
+ (rooms[party_room].right_col-1));
+ tries++;
+ } while (((dungeon[row][col] & (OBJECT|STAIRS|TRAP|TUNNEL)) ||
+ (dungeon[row][col] == NOTHING)) && (tries < 15));
+ if (tries >= 15) {
+ gr_row_col(&row, &col, (FLOOR | MONSTER));
+ }
+ } else {
+ gr_row_col(&row, &col, (FLOOR | MONSTER));
+ }
+ traps[i].trap_row = row;
+ traps[i].trap_col = col;
+ dungeon[row][col] |= (TRAP | HIDDEN);
+ }
+}
+
+id_trap()
+{
+ short dir, row, col, d, t;
+
+ message("direction? ", 0);
+
+ while (!is_direction(dir = rgetchar(), &d)) {
+ sound_bell();
+ }
+ check_message();
+
+ if (dir == CANCEL) {
+ return;
+ }
+ row = rogue.row;
+ col = rogue.col;
+
+ get_dir_rc(d, &row, &col, 0);
+
+ if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
+ t = trap_at(row, col);
+ message(trap_strings[t*2], 0);
+ } else {
+ message("no trap there", 0);
+ }
+}
+
+show_traps()
+{
+ short i, j;
+
+ for (i = 0; i < DROWS; i++) {
+ for (j = 0; j < DCOLS; j++) {
+ if (dungeon[i][j] & TRAP) {
+ mvaddch(i, j, '^');
+ }
+ }
+ }
+}
+
+search(n, is_auto)
+short n;
+boolean is_auto;
+{
+ short s, i, j, row, col, t;
+ short shown = 0, found = 0;
+ static boolean reg_search;
+
+ for (i = -1; i <= 1; i++) {
+ for (j = -1; j <= 1; j++) {
+ row = rogue.row + i;
+ col = rogue.col + j;
+ if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
+ (col < 0) || (col >= DCOLS)) {
+ continue;
+ }
+ if (dungeon[row][col] & HIDDEN) {
+ found++;
+ }
+ }
+ }
+ for (s = 0; s < n; s++) {
+ for (i = -1; i <= 1; i++) {
+ for (j = -1; j <= 1; j++) {
+ row = rogue.row + i;
+ col = rogue.col + j ;
+ if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
+ (col < 0) || (col >= DCOLS)) {
+ continue;
+ }
+ if (dungeon[row][col] & HIDDEN) {
+ if (rand_percent(17 + (rogue.exp + ring_exp))) {
+ dungeon[row][col] &= (~HIDDEN);
+ if ((!blind) && ((row != rogue.row) ||
+ (col != rogue.col))) {
+ mvaddch(row, col, get_dungeon_char(row, col));
+ }
+ shown++;
+ if (dungeon[row][col] & TRAP) {
+ t = trap_at(row, col);
+ message(trap_strings[t*2], 1);
+ }
+ }
+ }
+ if (((shown == found) && (found > 0)) || interrupted) {
+ return;
+ }
+ }
+ }
+ if ((!is_auto) && (reg_search = !reg_search)) {
+ (void) reg_move();
+ }
+ }
+}
diff --git a/rogue/use.c b/rogue/use.c
new file mode 100644
index 00000000..c4bc2240
--- /dev/null
+++ b/rogue/use.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)use.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * use.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+short halluc = 0;
+short blind = 0;
+short confused = 0;
+short levitate = 0;
+short haste_self = 0;
+boolean see_invisible = 0;
+short extra_hp = 0;
+boolean detect_monster = 0;
+boolean con_mon = 0;
+char *strange_feeling = "you have a strange feeling for a moment, then it passes";
+
+extern short bear_trap;
+extern char hunger_str[];
+extern short cur_room;
+extern long level_points[];
+extern boolean being_held;
+extern char *fruit, *you_can_move_again;
+extern boolean sustain_strength;
+
+quaff()
+{
+ short ch;
+ char buf[80];
+ object *obj;
+
+ ch = pack_letter("quaff what?", POTION);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (obj->what_is != POTION) {
+ message("you can't drink that", 0);
+ return;
+ }
+ switch(obj->which_kind) {
+ case INCREASE_STRENGTH:
+ message("you feel stronger now, what bulging muscles!",
+ 0);
+ rogue.str_current++;
+ if (rogue.str_current > rogue.str_max) {
+ rogue.str_max = rogue.str_current;
+ }
+ break;
+ case RESTORE_STRENGTH:
+ rogue.str_current = rogue.str_max;
+ message("this tastes great, you feel warm all over", 0);
+ break;
+ case HEALING:
+ message("you begin to feel better", 0);
+ potion_heal(0);
+ break;
+ case EXTRA_HEALING:
+ message("you begin to feel much better", 0);
+ potion_heal(1);
+ break;
+ case POISON:
+ if (!sustain_strength) {
+ rogue.str_current -= get_rand(1, 3);
+ if (rogue.str_current < 1) {
+ rogue.str_current = 1;
+ }
+ }
+ message("you feel very sick now", 0);
+ if (halluc) {
+ unhallucinate();
+ }
+ break;
+ case RAISE_LEVEL:
+ rogue.exp_points = level_points[rogue.exp - 1];
+ message("you suddenly feel much more skillful", 0);
+ add_exp(1, 1);
+ break;
+ case BLINDNESS:
+ go_blind();
+ break;
+ case HALLUCINATION:
+ message("oh wow, everything seems so cosmic", 0);
+ halluc += get_rand(500, 800);
+ break;
+ case DETECT_MONSTER:
+ show_monsters();
+ if (!(level_monsters.next_monster)) {
+ message(strange_feeling, 0);
+ }
+ break;
+ case DETECT_OBJECTS:
+ if (level_objects.next_object) {
+ if (!blind) {
+ show_objects();
+ }
+ } else {
+ message(strange_feeling, 0);
+ }
+ break;
+ case CONFUSION:
+ message((halluc ? "what a trippy feeling" :
+ "you feel confused"), 0);
+ cnfs();
+ break;
+ case LEVITATION:
+ message("you start to float in the air", 0);
+ levitate += get_rand(15, 30);
+ being_held = bear_trap = 0;
+ break;
+ case HASTE_SELF:
+ message("you feel yourself moving much faster", 0);
+ haste_self += get_rand(11, 21);
+ if (!(haste_self % 2)) {
+ haste_self++;
+ }
+ break;
+ case SEE_INVISIBLE:
+ sprintf(buf, "hmm, this potion tastes like %sjuice", fruit);
+ message(buf, 0);
+ if (blind) {
+ unblind();
+ }
+ see_invisible = 1;
+ relight();
+ break;
+ }
+ print_stats((STAT_STRENGTH | STAT_HP));
+ if (id_potions[obj->which_kind].id_status != CALLED) {
+ id_potions[obj->which_kind].id_status = IDENTIFIED;
+ }
+ vanish(obj, 1, &rogue.pack);
+}
+
+read_scroll()
+{
+ short ch;
+ object *obj;
+ char msg[DCOLS];
+
+ ch = pack_letter("read what?", SCROL);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (obj->what_is != SCROL) {
+ message("you can't read that", 0);
+ return;
+ }
+ switch(obj->which_kind) {
+ case SCARE_MONSTER:
+ message("you hear a maniacal laughter in the distance",
+ 0);
+ break;
+ case HOLD_MONSTER:
+ hold_monster();
+ break;
+ case ENCH_WEAPON:
+ if (rogue.weapon) {
+ if (rogue.weapon->what_is == WEAPON) {
+ sprintf(msg, "your %sglow%s %sfor a moment",
+ name_of(rogue.weapon),
+ ((rogue.weapon->quantity <= 1) ? "s" : ""),
+ get_ench_color());
+ message(msg, 0);
+ if (coin_toss()) {
+ rogue.weapon->hit_enchant++;
+ } else {
+ rogue.weapon->d_enchant++;
+ }
+ }
+ rogue.weapon->is_cursed = 0;
+ } else {
+ message("your hands tingle", 0);
+ }
+ break;
+ case ENCH_ARMOR:
+ if (rogue.armor) {
+ sprintf(msg, "your armor glows %sfor a moment",
+ get_ench_color());
+ message(msg, 0);
+ rogue.armor->d_enchant++;
+ rogue.armor->is_cursed = 0;
+ print_stats(STAT_ARMOR);
+ } else {
+ message("your skin crawls", 0);
+ }
+ break;
+ case IDENTIFY:
+ message("this is a scroll of identify", 0);
+ obj->identified = 1;
+ id_scrolls[obj->which_kind].id_status = IDENTIFIED;
+ idntfy();
+ break;
+ case TELEPORT:
+ tele();
+ break;
+ case SLEEP:
+ message("you fall asleep", 0);
+ take_a_nap();
+ break;
+ case PROTECT_ARMOR:
+ if (rogue.armor) {
+ message( "your armor is covered by a shimmering gold shield",0);
+ rogue.armor->is_protected = 1;
+ rogue.armor->is_cursed = 0;
+ } else {
+ message("your acne seems to have disappeared", 0);
+ }
+ break;
+ case REMOVE_CURSE:
+ message((!halluc) ?
+ "you feel as though someone is watching over you" :
+ "you feel in touch with the universal oneness", 0);
+ uncurse_all();
+ break;
+ case CREATE_MONSTER:
+ create_monster();
+ break;
+ case AGGRAVATE_MONSTER:
+ aggravate();
+ break;
+ case MAGIC_MAPPING:
+ message("this scroll seems to have a map on it", 0);
+ draw_magic_map();
+ break;
+ case CON_MON:
+ con_mon = 1;
+ sprintf(msg, "your hands glow %sfor a moment", get_ench_color());
+ message(msg, 0);
+ break;
+ }
+ if (id_scrolls[obj->which_kind].id_status != CALLED) {
+ id_scrolls[obj->which_kind].id_status = IDENTIFIED;
+ }
+ vanish(obj, (obj->which_kind != SLEEP), &rogue.pack);
+}
+
+/* vanish() does NOT handle a quiver of weapons with more than one
+ * arrow (or whatever) in the quiver. It will only decrement the count.
+ */
+
+vanish(obj, rm, pack)
+object *obj;
+short rm;
+object *pack;
+{
+ if (obj->quantity > 1) {
+ obj->quantity--;
+ } else {
+ if (obj->in_use_flags & BEING_WIELDED) {
+ unwield(obj);
+ } else if (obj->in_use_flags & BEING_WORN) {
+ unwear(obj);
+ } else if (obj->in_use_flags & ON_EITHER_HAND) {
+ un_put_on(obj);
+ }
+ take_from_pack(obj, pack);
+ free_object(obj);
+ }
+ if (rm) {
+ (void) reg_move();
+ }
+}
+
+potion_heal(extra)
+{
+ float ratio;
+ short add;
+
+ rogue.hp_current += rogue.exp;
+
+ ratio = ((float)rogue.hp_current) / rogue.hp_max;
+
+ if (ratio >= 1.00) {
+ rogue.hp_max += (extra ? 2 : 1);
+ extra_hp += (extra ? 2 : 1);
+ rogue.hp_current = rogue.hp_max;
+ } else if (ratio >= 0.90) {
+ rogue.hp_max += (extra ? 1 : 0);
+ extra_hp += (extra ? 1 : 0);
+ rogue.hp_current = rogue.hp_max;
+ } else {
+ if (ratio < 0.33) {
+ ratio = 0.33;
+ }
+ if (extra) {
+ ratio += ratio;
+ }
+ add = (short)(ratio * ((float)rogue.hp_max - rogue.hp_current));
+ rogue.hp_current += add;
+ if (rogue.hp_current > rogue.hp_max) {
+ rogue.hp_current = rogue.hp_max;
+ }
+ }
+ if (blind) {
+ unblind();
+ }
+ if (confused && extra) {
+ unconfuse();
+ } else if (confused) {
+ confused = (confused / 2) + 1;
+ }
+ if (halluc && extra) {
+ unhallucinate();
+ } else if (halluc) {
+ halluc = (halluc / 2) + 1;
+ }
+}
+
+idntfy()
+{
+ short ch;
+ object *obj;
+ struct id *id_table;
+ char desc[DCOLS];
+AGAIN:
+ ch = pack_letter("what would you like to identify?", ALL_OBJECTS);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item, try again", 0);
+ message("", 0);
+ check_message();
+ goto AGAIN;
+ }
+ obj->identified = 1;
+ if (obj->what_is & (SCROL | POTION | WEAPON | ARMOR | WAND | RING)) {
+ id_table = get_id_table(obj);
+ id_table[obj->which_kind].id_status = IDENTIFIED;
+ }
+ get_desc(obj, desc);
+ message(desc, 0);
+}
+
+eat()
+{
+ short ch;
+ short moves;
+ object *obj;
+ char buf[70];
+
+ ch = pack_letter("eat what?", FOOD);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (obj->what_is != FOOD) {
+ message("you can't eat that", 0);
+ return;
+ }
+ if ((obj->which_kind == FRUIT) || rand_percent(60)) {
+ moves = get_rand(950, 1150);
+ if (obj->which_kind == RATION) {
+ message("yum, that tasted good", 0);
+ } else {
+ sprintf(buf, "my, that was a yummy %s", fruit);
+ message(buf, 0);
+ }
+ } else {
+ moves = get_rand(750, 950);
+ message("yuk, that food tasted awful", 0);
+ add_exp(2, 1);
+ }
+ rogue.moves_left /= 3;
+ rogue.moves_left += moves;
+ hunger_str[0] = 0;
+ print_stats(STAT_HUNGER);
+
+ vanish(obj, 1, &rogue.pack);
+}
+
+hold_monster()
+{
+ short i, j;
+ short mcount = 0;
+ object *monster;
+ short row, col;
+
+ for (i = -2; i <= 2; i++) {
+ for (j = -2; j <= 2; j++) {
+ row = rogue.row + i;
+ col = rogue.col + j;
+ if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) ||
+ (col > (DCOLS-1))) {
+ continue;
+ }
+ if (dungeon[row][col] & MONSTER) {
+ monster = object_at(&level_monsters, row, col);
+ monster->m_flags |= ASLEEP;
+ monster->m_flags &= (~WAKENS);
+ mcount++;
+ }
+ }
+ }
+ if (mcount == 0) {
+ message("you feel a strange sense of loss", 0);
+ } else if (mcount == 1) {
+ message("the monster freezes", 0);
+ } else {
+ message("the monsters around you freeze", 0);
+ }
+}
+
+tele()
+{
+ mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col));
+
+ if (cur_room >= 0) {
+ darken_room(cur_room);
+ }
+ put_player(get_room_number(rogue.row, rogue.col));
+ being_held = 0;
+ bear_trap = 0;
+}
+
+hallucinate()
+{
+ object *obj, *monster;
+ short ch;
+
+ if (blind) return;
+
+ obj = level_objects.next_object;
+
+ while (obj) {
+ ch = mvinch(obj->row, obj->col);
+ if (((ch < 'A') || (ch > 'Z')) &&
+ ((obj->row != rogue.row) || (obj->col != rogue.col)))
+ if ((ch != ' ') && (ch != '.') && (ch != '#') && (ch != '+')) {
+ addch(gr_obj_char());
+ }
+ obj = obj->next_object;
+ }
+ monster = level_monsters.next_monster;
+
+ while (monster) {
+ ch = mvinch(monster->row, monster->col);
+ if ((ch >= 'A') && (ch <= 'Z')) {
+ addch(get_rand('A', 'Z'));
+ }
+ monster = monster->next_monster;
+ }
+}
+
+unhallucinate()
+{
+ halluc = 0;
+ relight();
+ message("everything looks SO boring now", 1);
+}
+
+unblind()
+{
+ blind = 0;
+ message("the veil of darkness lifts", 1);
+ relight();
+ if (halluc) {
+ hallucinate();
+ }
+ if (detect_monster) {
+ show_monsters();
+ }
+}
+
+relight()
+{
+ if (cur_room == PASSAGE) {
+ light_passage(rogue.row, rogue.col);
+ } else {
+ light_up_room(cur_room);
+ }
+ mvaddch(rogue.row, rogue.col, rogue.fchar);
+}
+
+take_a_nap()
+{
+ short i;
+
+ i = get_rand(2, 5);
+ md_sleep(1);
+
+ while (i--) {
+ mv_mons();
+ }
+ md_sleep(1);
+ message(you_can_move_again, 0);
+}
+
+go_blind()
+{
+ short i, j;
+
+ if (!blind) {
+ message("a cloak of darkness falls around you", 0);
+ }
+ blind += get_rand(500, 800);
+
+ if (detect_monster) {
+ object *monster;
+
+ monster = level_monsters.next_monster;
+
+ while (monster) {
+ mvaddch(monster->row, monster->col, monster->trail_char);
+ monster = monster->next_monster;
+ }
+ }
+ if (cur_room >= 0) {
+ for (i = rooms[cur_room].top_row + 1;
+ i < rooms[cur_room].bottom_row; i++) {
+ for (j = rooms[cur_room].left_col + 1;
+ j < rooms[cur_room].right_col; j++) {
+ mvaddch(i, j, ' ');
+ }
+ }
+ }
+ mvaddch(rogue.row, rogue.col, rogue.fchar);
+}
+
+char *
+get_ench_color()
+{
+ if (halluc) {
+ return(id_potions[get_rand(0, POTIONS-1)].title);
+ } else if (con_mon) {
+ return("red ");
+ }
+ return("blue ");
+}
+
+cnfs()
+{
+ confused += get_rand(12, 22);
+}
+
+unconfuse()
+{
+ char msg[80];
+
+ confused = 0;
+ sprintf(msg, "you feel less %s now", (halluc ? "trippy" : "confused"));
+ message(msg, 1);
+}
+
+uncurse_all()
+{
+ object *obj;
+
+ obj = rogue.pack.next_object;
+
+ while (obj) {
+ obj->is_cursed = 0;
+ obj = obj->next_object;
+ }
+}
diff --git a/rogue/zap.c b/rogue/zap.c
new file mode 100644
index 00000000..ecc4e9e0
--- /dev/null
+++ b/rogue/zap.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)zap.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * zap.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+boolean wizard = 0;
+
+extern boolean being_held, score_only, detect_monster;
+extern short cur_room;
+
+zapp()
+{
+ short wch;
+ boolean first_miss = 1;
+ object *wand;
+ short dir, d, row, col;
+ object *monster;
+
+ while (!is_direction(dir = rgetchar(), &d)) {
+ sound_bell();
+ if (first_miss) {
+ message("direction? ", 0);
+ first_miss = 0;
+ }
+ }
+ check_message();
+ if (dir == CANCEL) {
+ return;
+ }
+ if ((wch = pack_letter("zap with what?", WAND)) == CANCEL) {
+ return;
+ }
+ check_message();
+
+ if (!(wand = get_letter_object(wch))) {
+ message("no such item.", 0);
+ return;
+ }
+ if (wand->what_is != WAND) {
+ message("you can't zap with that", 0);
+ return;
+ }
+ if (wand->class <= 0) {
+ message("nothing happens", 0);
+ } else {
+ wand->class--;
+ row = rogue.row; col = rogue.col;
+ if ((wand->which_kind == COLD) || (wand->which_kind == FIRE)) {
+ bounce((short) wand->which_kind, d, row, col, 0);
+ } else {
+ monster = get_zapped_monster(d, &row, &col);
+ if (wand->which_kind == DRAIN_LIFE) {
+ wdrain_life(monster);
+ } else if (monster) {
+ wake_up(monster);
+ s_con_mon(monster);
+ zap_monster(monster, wand->which_kind);
+ relight();
+ }
+ }
+ }
+ (void) reg_move();
+}
+
+object *
+get_zapped_monster(dir, row, col)
+short dir;
+short *row, *col;
+{
+ short orow, ocol;
+
+ for (;;) {
+ orow = *row; ocol = *col;
+ get_dir_rc(dir, row, col, 0);
+ if (((*row == orow) && (*col == ocol)) ||
+ (dungeon[*row][*col] & (HORWALL | VERTWALL)) ||
+ (dungeon[*row][*col] == NOTHING)) {
+ return(0);
+ }
+ if (dungeon[*row][*col] & MONSTER) {
+ if (!imitating(*row, *col)) {
+ return(object_at(&level_monsters, *row, *col));
+ }
+ }
+ }
+}
+
+zap_monster(monster, kind)
+object *monster;
+unsigned short kind;
+{
+ short row, col;
+ object *nm;
+ short tc;
+
+ row = monster->row;
+ col = monster->col;
+
+ switch(kind) {
+ case SLOW_MONSTER:
+ if (monster->m_flags & HASTED) {
+ monster->m_flags &= (~HASTED);
+ } else {
+ monster->slowed_toggle = 0;
+ monster->m_flags |= SLOWED;
+ }
+ break;
+ case HASTE_MONSTER:
+ if (monster->m_flags & SLOWED) {
+ monster->m_flags &= (~SLOWED);
+ } else {
+ monster->m_flags |= HASTED;
+ }
+ break;
+ case TELE_AWAY:
+ tele_away(monster);
+ break;
+ case INVISIBILITY:
+ monster->m_flags |= INVISIBLE;
+ break;
+ case POLYMORPH:
+ if (monster->m_flags & HOLDS) {
+ being_held = 0;
+ }
+ nm = monster->next_monster;
+ tc = monster->trail_char;
+ (void) gr_monster(monster, get_rand(0, MONSTERS-1));
+ monster->row = row;
+ monster->col = col;
+ monster->next_monster = nm;
+ monster->trail_char = tc;
+ if (!(monster->m_flags & IMITATES)) {
+ wake_up(monster);
+ }
+ break;
+ case MAGIC_MISSILE:
+ rogue_hit(monster, 1);
+ break;
+ case CANCELLATION:
+ if (monster->m_flags & HOLDS) {
+ being_held = 0;
+ }
+ if (monster->m_flags & STEALS_ITEM) {
+ monster->drop_percent = 0;
+ }
+ monster->m_flags &= (~(FLIES | FLITS | SPECIAL_HIT | INVISIBLE |
+ FLAMES | IMITATES | CONFUSES | SEEKS_GOLD | HOLDS));
+ break;
+ case DO_NOTHING:
+ message("nothing happens", 0);
+ break;
+ }
+}
+
+tele_away(monster)
+object *monster;
+{
+ short row, col;
+
+ if (monster->m_flags & HOLDS) {
+ being_held = 0;
+ }
+ gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
+ mvaddch(monster->row, monster->col, monster->trail_char);
+ dungeon[monster->row][monster->col] &= ~MONSTER;
+ monster->row = row; monster->col = col;
+ dungeon[row][col] |= MONSTER;
+ monster->trail_char = mvinch(row, col);
+ if (detect_monster || rogue_can_see(row, col)) {
+ mvaddch(row, col, gmc(monster));
+ }
+}
+
+wizardize()
+{
+ char buf[100];
+
+ if (wizard) {
+ wizard = 0;
+ message("not wizard anymore", 0);
+ } else {
+ if (get_input_line("wizard's password:", "", buf, "", 0, 0)) {
+ (void) xxx(1);
+ xxxx(buf, strlen(buf));
+ if (!strncmp(buf, "\247\104\126\272\115\243\027", 7)) {
+ wizard = 1;
+ score_only = 1;
+ message("Welcome, mighty wizard!", 0);
+ } else {
+ message("sorry", 0);
+ }
+ }
+ }
+}
+
+wdrain_life(monster)
+object *monster;
+{
+ short hp;
+ object *lmon, *nm;
+
+ hp = rogue.hp_current / 3;
+ rogue.hp_current = (rogue.hp_current + 1) / 2;
+
+ if (cur_room >= 0) {
+ lmon = level_monsters.next_monster;
+ while (lmon) {
+ nm = lmon->next_monster;
+ if (get_room_number(lmon->row, lmon->col) == cur_room) {
+ wake_up(lmon);
+ (void) mon_damage(lmon, hp);
+ }
+ lmon = nm;
+ }
+ } else {
+ if (monster) {
+ wake_up(monster);
+ (void) mon_damage(monster, hp);
+ }
+ }
+ print_stats(STAT_HP);
+ relight();
+}
+
+bounce(ball, dir, row, col, r)
+short ball, dir, row, col, r;
+{
+ short orow, ocol;
+ char buf[DCOLS], *s;
+ short i, ch, new_dir = -1, damage;
+ static short btime;
+
+ if (++r == 1) {
+ btime = get_rand(3, 6);
+ } else if (r > btime) {
+ return;
+ }
+
+ if (ball == FIRE) {
+ s = "fire";
+ } else {
+ s = "ice";
+ }
+ if (r > 1) {
+ sprintf(buf, "the %s bounces", s);
+ message(buf, 0);
+ }
+ orow = row;
+ ocol = col;
+ do {
+ ch = mvinch(orow, ocol);
+ standout();
+ mvaddch(orow, ocol, ch);
+ get_dir_rc(dir, &orow, &ocol, 1);
+ } while (!( (ocol <= 0) ||
+ (ocol >= DCOLS-1) ||
+ (dungeon[orow][ocol] == NOTHING) ||
+ (dungeon[orow][ocol] & MONSTER) ||
+ (dungeon[orow][ocol] & (HORWALL | VERTWALL)) ||
+ ((orow == rogue.row) && (ocol == rogue.col))));
+ standend();
+ refresh();
+ do {
+ orow = row;
+ ocol = col;
+ ch = mvinch(row, col);
+ mvaddch(row, col, ch);
+ get_dir_rc(dir, &row, &col, 1);
+ } while (!( (col <= 0) ||
+ (col >= DCOLS-1) ||
+ (dungeon[row][col] == NOTHING) ||
+ (dungeon[row][col] & MONSTER) ||
+ (dungeon[row][col] & (HORWALL | VERTWALL)) ||
+ ((row == rogue.row) && (col == rogue.col))));
+
+ if (dungeon[row][col] & MONSTER) {
+ object *monster;
+
+ monster = object_at(&level_monsters, row, col);
+
+ wake_up(monster);
+ if (rand_percent(33)) {
+ sprintf(buf, "the %s misses the %s", s, mon_name(monster));
+ message(buf, 0);
+ goto ND;
+ }
+ if (ball == FIRE) {
+ if (!(monster->m_flags & RUSTS)) {
+ if (monster->m_flags & FREEZES) {
+ damage = monster->hp_to_kill;
+ } else if (monster->m_flags & FLAMES) {
+ damage = (monster->hp_to_kill / 10) + 1;
+ } else {
+ damage = get_rand((rogue.hp_current / 3), rogue.hp_max);
+ }
+ } else {
+ damage = (monster->hp_to_kill / 2) + 1;
+ }
+ sprintf(buf, "the %s hits the %s", s, mon_name(monster));
+ message(buf, 0);
+ (void) mon_damage(monster, damage);
+ } else {
+ damage = -1;
+ if (!(monster->m_flags & FREEZES)) {
+ if (rand_percent(33)) {
+ message("the monster is frozen", 0);
+ monster->m_flags |= (ASLEEP | NAPPING);
+ monster->nap_length = get_rand(3, 6);
+ } else {
+ damage = rogue.hp_current / 4;
+ }
+ } else {
+ damage = -2;
+ }
+ if (damage != -1) {
+ sprintf(buf, "the %s hits the %s", s, mon_name(monster));
+ message(buf, 0);
+ (void) mon_damage(monster, damage);
+ }
+ }
+ } else if ((row == rogue.row) && (col == rogue.col)) {
+ if (rand_percent(10 + (3 * get_armor_class(rogue.armor)))) {
+ sprintf(buf, "the %s misses", s);
+ message(buf, 0);
+ goto ND;
+ } else {
+ damage = get_rand(3, (3 * rogue.exp));
+ if (ball == FIRE) {
+ damage = (damage * 3) / 2;
+ damage -= get_armor_class(rogue.armor);
+ }
+ sprintf(buf, "the %s hits", s);
+ rogue_damage(damage, (object *) 0,
+ ((ball == FIRE) ? KFIRE : HYPOTHERMIA));
+ message(buf, 0);
+ }
+ } else {
+ short nrow, ncol;
+
+ND: for (i = 0; i < 10; i++) {
+ dir = get_rand(0, DIRS-1);
+ nrow = orow;
+ ncol = ocol;
+ get_dir_rc(dir, &nrow, &ncol, 1);
+ if (((ncol >= 0) && (ncol <= DCOLS-1)) &&
+ (dungeon[nrow][ncol] != NOTHING) &&
+ (!(dungeon[nrow][ncol] & (VERTWALL | HORWALL)))) {
+ new_dir = dir;
+ break;
+ }
+ }
+ if (new_dir != -1) {
+ bounce(ball, new_dir, orow, ocol, r);
+ }
+ }
+}
diff --git a/sail/:file b/sail/:file
new file mode 100644
index 00000000..dd5762fd
--- /dev/null
+++ b/sail/:file
@@ -0,0 +1,10 @@
+./"index"16t"captain"nD20C
++/"points"8t"loadL"8t"loadR"8t"readyL"8t"readyL"ndbbbb2+36+36+
++/"struck"8t"capture"8t"pcrew"8t"movebuf"nb3+pd10C
++/"drift"8t"nfoul"8t"ngrap"nb1+dd
++/"foul:"8t"count"8t"turn"16t"count"8t"turn"
++,5/8tdd16tddn
++/"grap:"8t"count"8t"turn"16t"count"8t"turn"
++,5/8tdd16tddn
++/"RH"8t"RG"8t"RR"8t"FS"8t"explode"8t"sink"n6b
++/"dir"8t"col"8t"row"8t"loadwit"8t"stern"nb+2d2b
diff --git a/sail/:scene b/sail/:scene
new file mode 100644
index 00000000..43c4d816
--- /dev/null
+++ b/sail/:scene
@@ -0,0 +1,3 @@
+./"winddir windspd windchg vessels"n4b
+.+8/"ship: "a
+*(.-4)/S
diff --git a/sail/:ship b/sail/:ship
new file mode 100644
index 00000000..fdf9dd09
--- /dev/null
+++ b/sail/:ship
@@ -0,0 +1,4 @@
+./"name"16t"specs"16t"nation"nppb+
++/"row"8t"col"8t"dir"nddb+
++/"file"np
++/t
diff --git a/sail/:specs b/sail/:specs
new file mode 100644
index 00000000..2a71f70a
--- /dev/null
+++ b/sail/:specs
@@ -0,0 +1,3 @@
+./"bs bs ta guns class hull qual"n3b+d3b
++/"crew1 crew2 crew3 gunL gunR carL carR"n8b
++/"rig1 rig2 rig3 rig4 pts"n4b+d
diff --git a/sail/Makefile b/sail/Makefile
new file mode 100644
index 00000000..59d7c560
--- /dev/null
+++ b/sail/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 5.10 (Berkeley) 5/11/90
+
+PROG= sail
+SRCS= main.c pl_main.c pl_1.c pl_2.c pl_3.c pl_4.c pl_5.c pl_6.c pl_7.c \
+ dr_main.c dr_1.c dr_2.c dr_3.c dr_4.c dr_5.c lo_main.c \
+ assorted.c game.c globals.c misc.c parties.c sync.c version.c
+MAN6= sail.0
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermlib -lcompat
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
diff --git a/sail/assorted.c b/sail/assorted.c
new file mode 100644
index 00000000..1b9bc2bd
--- /dev/null
+++ b/sail/assorted.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)assorted.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+table(rig, shot, hittable, on, from, roll)
+struct ship *on, *from;
+int rig, shot, hittable, roll;
+{
+ register int hhits = 0, chits = 0, ghits = 0, rhits = 0;
+ int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0;
+ int guns, car, pc, hull;
+ int crew[3];
+ register int n;
+ int rigg[4];
+ char *message;
+ struct Tables *tp;
+
+ pc = on->file->pcrew;
+ hull = on->specs->hull;
+ crew[0] = on->specs->crew1;
+ crew[1] = on->specs->crew2;
+ crew[2] = on->specs->crew3;
+ rigg[0] = on->specs->rig1;
+ rigg[1] = on->specs->rig2;
+ rigg[2] = on->specs->rig3;
+ rigg[3] = on->specs->rig4;
+ if (shot == L_GRAPE)
+ Chit = chits = hittable;
+ else {
+ tp = &(rig ? RigTable : HullTable)[hittable][roll-1];
+ Chit = chits = tp->C;
+ Rhit = rhits = tp->R;
+ Hhit = hhits = tp->H;
+ Ghit = ghits = tp->G;
+ if (on->file->FS)
+ rhits *= 2;
+ if (shot == L_CHAIN) {
+ Ghit = ghits = 0;
+ Hhit = hhits = 0;
+ }
+ }
+ if (on->file->captured != 0) {
+ pc -= (chits + 1) / 2;
+ chits /= 2;
+ }
+ for (n = 0; n < 3; n++)
+ if (chits > crew[n]) {
+ chits -= crew[n];
+ crew[n] = 0;
+ } else {
+ crew[n] -= chits;
+ chits = 0;
+ }
+ for (n = 0; n < 3; n++)
+ if (rhits > rigg[n]){
+ rhits -= rigg[n];
+ rigg[n] = 0;
+ } else {
+ rigg[n] -= rhits;
+ rhits = 0;
+ }
+ if (rigg[3] != -1 && rhits > rigg[3]) {
+ rhits -= rigg[3];
+ rigg[3] = 0;
+ } else if (rigg[3] != -1) {
+ rigg[3] -= rhits;
+ }
+ if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1))
+ makesignal(on, "dismasted!", (struct ship *)0);
+ if (portside(from, on, 0)) {
+ guns = on->specs->gunR;
+ car = on->specs->carR;
+ } else {
+ guns = on->specs->gunL;
+ car = on->specs->carL;
+ }
+ if (ghits > car) {
+ ghits -= car;
+ car = 0;
+ } else {
+ car -= ghits;
+ ghits = 0;
+ }
+ if (ghits > guns){
+ ghits -= guns;
+ guns = 0;
+ } else {
+ guns -= ghits;
+ ghits = 0;
+ }
+ hull -= ghits;
+ if (Ghit)
+ Write(portside(from, on, 0) ? W_GUNR : W_GUNL,
+ on, 0, guns, car, 0, 0);
+ hull -= hhits;
+ hull = hull < 0 ? 0 : hull;
+ if (on->file->captured != 0 && Chit)
+ Write(W_PCREW, on, 0, pc, 0, 0, 0);
+ if (Hhit)
+ Write(W_HULL, on, 0, hull, 0, 0, 0);
+ if (Chit)
+ Write(W_CREW, on, 0, crew[0], crew[1], crew[2], 0);
+ if (Rhit)
+ Write(W_RIGG, on, 0, rigg[0], rigg[1], rigg[2], rigg[3]);
+ switch (shot) {
+ case L_ROUND:
+ message = "firing round shot on %s (%c%c)";
+ break;
+ case L_GRAPE:
+ message = "firing grape shot on %s (%c%c)";
+ break;
+ case L_CHAIN:
+ message = "firing chain shot on %s (%c%c)";
+ break;
+ case L_DOUBLE:
+ message = "firing double shot on %s (%c%c)";
+ break;
+ case L_EXPLODE:
+ message = "exploding shot on %s (%c%c)";
+ }
+ makesignal(from, message, on);
+ if (roll == 6 && rig) {
+ switch(Rhit) {
+ case 0:
+ message = "fore topsail sheets parted";
+ break;
+ case 1:
+ message = "mizzen shrouds parted";
+ break;
+ case 2:
+ message = "main topsail yard shot away";
+ break;
+ case 4:
+ message = "fore topmast and foremast shrouds shot away";
+ break;
+ case 5:
+ message = "mizzen mast and yard shot through";
+ break;
+ case 6:
+ message = "foremast and spritsail yard shattered";
+ break;
+ case 7:
+ message = "main topmast and mizzen mast shattered";
+ break;
+ }
+ makesignal(on, message, (struct ship *)0);
+ } else if (roll == 6) {
+ switch (Hhit) {
+ case 0:
+ message = "anchor cables severed";
+ break;
+ case 1:
+ message = "two anchor stocks shot away";
+ break;
+ case 2:
+ message = "quarterdeck bulwarks damaged";
+ break;
+ case 3:
+ message = "three gun ports shot away";
+ break;
+ case 4:
+ message = "four guns dismounted";
+ break;
+ case 5:
+ message = "rudder cables shot through";
+ Write(W_TA, on, 0, 0, 0, 0, 0);
+ break;
+ case 6:
+ message = "shot holes below the water line";
+ break;
+ }
+ makesignal(on, message, (struct ship *)0);
+ }
+ /*
+ if (Chit > 1 && on->file->readyL&R_INITIAL && on->file->readyR&R_INITIAL) {
+ on->specs->qual--;
+ if (on->specs->qual <= 0) {
+ makesignal(on, "crew mutinying!", (struct ship *)0);
+ on->specs->qual = 5;
+ Write(W_CAPTURED, on, 0, on->file->index, 0, 0, 0);
+ } else
+ makesignal(on, "crew demoralized", (struct ship *)0);
+ Write(W_QUAL, on, 0, on->specs->qual, 0, 0, 0);
+ }
+ */
+ if (!hull)
+ strike(on, from);
+}
+
+Cleansnag(from, to, all, flag)
+register struct ship *from, *to;
+char all, flag;
+{
+ if (flag & 1) {
+ Write(W_UNGRAP, from, 0, to->file->index, all, 0, 0);
+ Write(W_UNGRAP, to, 0, from->file->index, all, 0, 0);
+ }
+ if (flag & 2) {
+ Write(W_UNFOUL, from, 0, to->file->index, all, 0, 0);
+ Write(W_UNFOUL, to, 0, from->file->index, all, 0, 0);
+ }
+ if (!snagged2(from, to)) {
+ if (!snagged(from)) {
+ unboard(from, from, 1); /* defense */
+ unboard(from, from, 0); /* defense */
+ } else
+ unboard(from, to, 0); /* offense */
+ if (!snagged(to)) {
+ unboard(to, to, 1); /* defense */
+ unboard(to, to, 0); /* defense */
+ } else
+ unboard(to, from, 0); /* offense */
+ }
+}
+
+strike(ship, from)
+register struct ship *ship, *from;
+{
+ int points;
+
+ if (ship->file->struck)
+ return;
+ Write(W_STRUCK, ship, 0, 1, 0, 0, 0);
+ points = ship->specs->pts + from->file->points;
+ Write(W_POINTS, from, 0, points, 0, 0, 0);
+ unboard(ship, ship, 0); /* all offense */
+ unboard(ship, ship, 1); /* all defense */
+ switch (die()) {
+ case 3:
+ case 4: /* ship may sink */
+ Write(W_SINK, ship, 0, 1, 0, 0, 0);
+ break;
+ case 5:
+ case 6: /* ship may explode */
+ Write(W_EXPLODE, ship, 0, 1, 0, 0, 0);
+ break;
+ }
+ Write(W_SIGNAL, ship, 1, (int) "striking her colours!", 0, 0, 0);
+}
diff --git a/sail/dr_1.c b/sail/dr_1.c
new file mode 100644
index 00000000..4dbe8995
--- /dev/null
+++ b/sail/dr_1.c
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_1.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "driver.h"
+
+unfoul()
+{
+ register struct ship *sp;
+ struct ship *to;
+ register int nat;
+ register i;
+
+ foreachship(sp) {
+ if (sp->file->captain[0])
+ continue;
+ nat = capship(sp)->nationality;
+ foreachship(to) {
+ if (nat != capship(to)->nationality &&
+ !toughmelee(sp, to, 0, 0))
+ continue;
+ for (i = fouled2(sp, to); --i >= 0;)
+ if (die() <= 2)
+ cleanfoul(sp, to, 0);
+ }
+ }
+}
+
+boardcomp()
+{
+ int crew[3];
+ register struct ship *sp, *sq;
+
+ foreachship(sp) {
+ if (*sp->file->captain)
+ continue;
+ if (sp->file->dir == 0)
+ continue;
+ if (sp->file->struck || sp->file->captured != 0)
+ continue;
+ if (!snagged(sp))
+ continue;
+ crew[0] = sp->specs->crew1 != 0;
+ crew[1] = sp->specs->crew2 != 0;
+ crew[2] = sp->specs->crew3 != 0;
+ foreachship(sq) {
+ if (!Xsnagged2(sp, sq))
+ continue;
+ if (meleeing(sp, sq))
+ continue;
+ if (!sq->file->dir
+ || sp->nationality == capship(sq)->nationality)
+ continue;
+ switch (sp->specs->class - sq->specs->class) {
+ case -3: case -4: case -5:
+ if (crew[0]) {
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100, 0);
+ crew[0] = 0;
+ } else if (crew[1]){
+ /* OBP */
+ sendbp(sp, sq, crew[1]*10, 0);
+ crew[1] = 0;
+ }
+ break;
+ case -2:
+ if (crew[0] || crew[1]) {
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100+crew[1]*10,
+ 0);
+ crew[0] = crew[1] = 0;
+ }
+ break;
+ case -1: case 0: case 1:
+ if (crew[0]) {
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100+crew[1]*10,
+ 0);
+ crew[0] = crew[1] = 0;
+ }
+ break;
+ case 2: case 3: case 4: case 5:
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
+ 0);
+ crew[0] = crew[1] = crew[2] = 0;
+ break;
+ }
+ }
+ }
+}
+
+fightitout(from, to, key)
+struct ship *from, *to;
+int key;
+{
+ struct ship *fromcap, *tocap;
+ int crewfrom[3], crewto[3], menfrom, mento;
+ int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
+ int topoints;
+ int index, totalfrom = 0, totalto = 0;
+ int count;
+ char message[60];
+
+ menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
+ mento = mensent(to, from, crewto, &tocap, &pcto, 0);
+ if (fromcap == 0)
+ fromcap = from;
+ if (tocap == 0)
+ tocap = to;
+ if (key) {
+ if (!menfrom) { /* if crew surprised */
+ if (fromcap == from)
+ menfrom = from->specs->crew1
+ + from->specs->crew2
+ + from->specs->crew3;
+ else
+ menfrom = from->file->pcrew;
+ } else {
+ menfrom *= 2; /* DBP's fight at an advantage */
+ }
+ }
+ fromstrength = menfrom * fromcap->specs->qual;
+ strengthto = mento * tocap->specs->qual;
+ for (count = 0;
+ (fromstrength < strengthto * 3 && strengthto < fromstrength * 3
+ || fromstrength == -1) && count < 4;
+ count++) {
+ index = fromstrength/10;
+ if (index > 8)
+ index = 8;
+ toinjured = MT[index][2 - die() / 3];
+ totalto += toinjured;
+ index = strengthto/10;
+ if (index > 8)
+ index = 8;
+ frominjured = MT[index][2 - die() / 3];
+ totalfrom += frominjured;
+ menfrom -= frominjured;
+ mento -= toinjured;
+ fromstrength = menfrom * fromcap->specs->qual;
+ strengthto = mento * tocap->specs->qual;
+ }
+ if (fromstrength >= strengthto * 3 || count == 4) {
+ unboard(to, from, 0);
+ subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
+ subtract(to, totalto, crewto, tocap, pcto);
+ makesignal(from, "boarders from %s repelled", to);
+ (void) sprintf(message, "killed in melee: %d. %s: %d",
+ totalto, from->shipname, totalfrom);
+ Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
+ if (key)
+ return 1;
+ } else if (strengthto >= fromstrength * 3) {
+ unboard(from, to, 0);
+ subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
+ subtract(to, totalto, crewto, tocap, pcto);
+ if (key) {
+ if (fromcap != from)
+ Write(W_POINTS, fromcap, 0,
+ fromcap->file->points -
+ from->file->struck
+ ? from->specs->pts
+ : 2 * from->specs->pts,
+ 0, 0, 0);
+
+/* ptr1 points to the shipspec for the ship that was just unboarded.
+ I guess that what is going on here is that the pointer is multiplied
+ or something. */
+
+ Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0);
+ topoints = 2 * from->specs->pts + to->file->points;
+ if (from->file->struck)
+ topoints -= from->specs->pts;
+ Write(W_POINTS, to, 0, topoints, 0, 0, 0);
+ mento = crewto[0] ? crewto[0] : crewto[1];
+ if (mento) {
+ subtract(to, mento, crewto, tocap, pcto);
+ subtract(from, - mento, crewfrom, to, 0);
+ }
+ (void) sprintf(message, "captured by the %s!",
+ to->shipname);
+ Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0);
+ (void) sprintf(message, "killed in melee: %d. %s: %d",
+ totalto, from->shipname, totalfrom);
+ Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
+ mento = 0;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+resolve()
+{
+ int thwart;
+ register struct ship *sp, *sq;
+
+ foreachship(sp) {
+ if (sp->file->dir == 0)
+ continue;
+ for (sq = sp + 1; sq < ls; sq++)
+ if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
+ (void) fightitout(sp, sq, 0);
+ thwart = 2;
+ foreachship(sq) {
+ if (sq->file->dir && meleeing(sq, sp))
+ thwart = fightitout(sp, sq, 1);
+ if (!thwart)
+ break;
+ }
+ if (!thwart) {
+ foreachship(sq) {
+ if (sq->file->dir && meleeing(sq, sp))
+ unboard(sq, sp, 0);
+ unboard(sp, sq, 0);
+ }
+ unboard(sp, sp, 1);
+ } else if (thwart == 2)
+ unboard(sp, sp, 1);
+ }
+}
+
+compcombat()
+{
+ register n;
+ register struct ship *sp;
+ struct ship *closest;
+ int crew[3], men = 0, target, temp;
+ int r, guns, ready, load, car;
+ int index, rakehim, sternrake;
+ int shootat, hit;
+
+ foreachship(sp) {
+ if (sp->file->captain[0] || sp->file->dir == 0)
+ continue;
+ crew[0] = sp->specs->crew1;
+ crew[1] = sp->specs->crew2;
+ crew[2] = sp->specs->crew3;
+ for (n = 0; n < 3; n++) {
+ if (sp->file->OBP[n].turnsent)
+ men += sp->file->OBP[n].mensent;
+ }
+ for (n = 0; n < 3; n++) {
+ if (sp->file->DBP[n].turnsent)
+ men += sp->file->DBP[n].mensent;
+ }
+ if (men){
+ crew[0] = men/100 ? 0 : crew[0] != 0;
+ crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
+ crew[2] = men%10 ? 0 : crew[2] != 0;
+ }
+ for (r = 0; r < 2; r++) {
+ if (!crew[2])
+ continue;
+ if (sp->file->struck)
+ continue;
+ if (r) {
+ ready = sp->file->readyR;
+ guns = sp->specs->gunR;
+ car = sp->specs->carR;
+ } else {
+ ready = sp->file->readyL;
+ guns = sp->specs->gunL;
+ car = sp->specs->carL;
+ }
+ if (!guns && !car)
+ continue;
+ if ((ready & R_LOADED) == 0)
+ continue;
+ closest = closestenemy(sp, r ? 'r' : 'l', 0);
+ if (closest == 0)
+ continue;
+ if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
+ continue;
+ if (closest->file->struck)
+ continue;
+ target = range(sp, closest);
+ if (target > 10)
+ continue;
+ if (!guns && target >= 3)
+ continue;
+ load = L_ROUND;
+ if (target == 1 && sp->file->loadwith == L_GRAPE)
+ load = L_GRAPE;
+ if (target <= 3 && closest->file->FS)
+ load = L_CHAIN;
+ if (target == 1 && load != L_GRAPE)
+ load = L_DOUBLE;
+ if (load > L_CHAIN && target < 6)
+ shootat = HULL;
+ else
+ shootat = RIGGING;
+ rakehim = gunsbear(sp, closest)
+ && !gunsbear(closest, sp);
+ temp = portside(closest, sp, 1)
+ - closest->file->dir + 1;
+ if (temp < 1)
+ temp += 8;
+ if (temp > 8)
+ temp -= 8;
+ sternrake = temp > 4 && temp < 6;
+ index = guns;
+ if (target < 3)
+ index += car;
+ index = (index - 1) / 3;
+ index = index > 8 ? 8 : index;
+ if (!rakehim)
+ hit = HDT[index][target-1];
+ else
+ hit = HDTrake[index][target-1];
+ if (rakehim && sternrake)
+ hit++;
+ hit += QUAL[index][capship(sp)->specs->qual - 1];
+ for (n = 0; n < 3 && sp->file->captured == 0; n++)
+ if (!crew[n])
+ if (index <= 5)
+ hit--;
+ else
+ hit -= 2;
+ if (ready & R_INITIAL) {
+ if (!r)
+ sp->file->readyL &= ~R_INITIAL;
+ else
+ sp->file->readyR &= ~R_INITIAL;
+ if (index <= 3)
+ hit++;
+ else
+ hit += 2;
+ }
+ if (sp->file->captured != 0)
+ if (index <= 1)
+ hit--;
+ else
+ hit -= 2;
+ hit += AMMO[index][load - 1];
+ temp = sp->specs->class;
+ if ((temp >= 5 || temp == 1) && windspeed == 5)
+ hit--;
+ if (windspeed == 6 && temp == 4)
+ hit -= 2;
+ if (windspeed == 6 && temp <= 3)
+ hit--;
+ if (hit >= 0) {
+ if (load != L_GRAPE)
+ hit = hit > 10 ? 10 : hit;
+ table(shootat, load, hit, closest, sp, die());
+ }
+ }
+ }
+}
+
+next()
+{
+ if (++turn % 55 == 0)
+ if (alive)
+ alive = 0;
+ else
+ people = 0;
+ if (people <= 0 || windspeed == 7) {
+ register struct ship *s;
+ struct ship *bestship;
+ float net, best = 0.0;
+ foreachship(s) {
+ if (*s->file->captain)
+ continue;
+ net = (float)s->file->points / s->specs->pts;
+ if (net > best) {
+ best = net;
+ bestship = s;
+ }
+ }
+ if (best > 0.0) {
+ char *p = getenv("WOTD");
+ if (p == 0)
+ p = "Driver";
+ if (islower(*p))
+ *p = toupper(*p);
+ (void) strncpy(bestship->file->captain, p,
+ sizeof bestship->file->captain);
+ bestship->file->captain
+ [sizeof bestship->file->captain - 1] = 0;
+ log(bestship);
+ }
+ return -1;
+ }
+ Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0);
+ if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) {
+ switch (die()) {
+ case 1:
+ winddir = 1;
+ break;
+ case 2:
+ break;
+ case 3:
+ winddir++;
+ break;
+ case 4:
+ winddir--;
+ break;
+ case 5:
+ winddir += 2;
+ break;
+ case 6:
+ winddir -= 2;
+ break;
+ }
+ if (winddir > 8)
+ winddir -= 8;
+ if (winddir < 1)
+ winddir += 8;
+ if (windspeed)
+ switch (die()) {
+ case 1:
+ case 2:
+ windspeed--;
+ break;
+ case 5:
+ case 6:
+ windspeed++;
+ break;
+ }
+ else
+ windspeed++;
+ Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0);
+ }
+ return 0;
+}
diff --git a/sail/dr_2.c b/sail/dr_2.c
new file mode 100644
index 00000000..420fc0d4
--- /dev/null
+++ b/sail/dr_2.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_2.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "driver.h"
+
+#define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5)
+
+thinkofgrapples()
+{
+ register struct ship *sp, *sq;
+ char friendly;
+
+ foreachship(sp) {
+ if (sp->file->captain[0] || sp->file->dir == 0)
+ continue;
+ foreachship(sq) {
+ friendly = sp->nationality == capship(sq)->nationality;
+ if (!friendly) {
+ if (sp->file->struck || sp->file->captured != 0)
+ continue;
+ if (range(sp, sq) != 1)
+ continue;
+ if (grappled2(sp, sq))
+ if (toughmelee(sp, sq, 0, 0))
+ ungrap(sp, sq);
+ else
+ grap(sp, sq);
+ else if (couldwin(sp, sq)) {
+ grap(sp, sq);
+ sp->file->loadwith = L_GRAPE;
+ }
+ } else
+ ungrap(sp, sq);
+ }
+ }
+}
+
+checkup()
+{
+ register struct ship *sp, *sq;
+ register char explode, sink;
+
+ foreachship(sp) {
+ if (sp->file->dir == 0)
+ continue;
+ explode = sp->file->explode;
+ sink = sp->file->sink;
+ if (explode != 1 && sink != 1)
+ continue;
+ if (die() < 5)
+ continue;
+ Write(sink == 1 ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0);
+ Write(W_DIR, sp, 0, 0, 0, 0, 0);
+ if (snagged(sp))
+ foreachship(sq)
+ cleansnag(sp, sq, 1);
+ if (sink != 1) {
+ makesignal(sp, "exploding!", (struct ship *)0);
+ foreachship(sq) {
+ if (sp != sq && sq->file->dir && range(sp, sq) < 4)
+ table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6);
+ }
+ } else
+ makesignal(sp, "sinking!", (struct ship *)0);
+ }
+}
+
+prizecheck()
+{
+ register struct ship *sp;
+
+ foreachship(sp) {
+ if (sp->file->captured == 0)
+ continue;
+ if (sp->file->struck || sp->file->dir == 0)
+ continue;
+ if (sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3 > sp->file->pcrew * 6) {
+ Write(W_SIGNAL, sp, 1,
+ (int)"prize crew overthrown", 0, 0, 0);
+ Write(W_POINTS, sp->file->captured, 0, sp->file->captured->file->points - 2 * sp->specs->pts, 0, 0, 0);
+ Write(W_CAPTURED, sp, 0, -1, 0, 0, 0);
+ }
+ }
+}
+
+strend(str)
+char *str;
+{
+ register char *p;
+
+ for (p = str; *p; p++)
+ ;
+ return p == str ? 0 : p[-1];
+}
+
+closeon(from, to, command, ta, ma, af)
+register struct ship *from, *to;
+char command[];
+int ma, ta, af;
+{
+ int high;
+ char temp[10];
+
+ temp[0] = command[0] = '\0';
+ high = -30000;
+ try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0);
+}
+
+int dtab[] = {0,1,1,2,3,4,4,5}; /* diagonal distances in x==y */
+
+score(movement, ship, to, onlytemp)
+char movement[];
+register struct ship *ship, *to;
+char onlytemp;
+{
+ char drift;
+ int row, col, dir, total, ran;
+ register struct File *fp = ship->file;
+
+ if ((dir = fp->dir) == 0)
+ return 0;
+ row = fp->row;
+ col = fp->col;
+ drift = fp->drift;
+ move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift);
+ if (!*movement)
+ (void) strcpy(movement, "d");
+
+ ran = range(ship, to);
+ total = -50 * ran;
+ if (ran < 4 && gunsbear(ship, to))
+ total += 60;
+ if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4)
+ total = -30000;
+
+ if (!onlytemp) {
+ fp->row = row;
+ fp->col = col;
+ fp->dir = dir;
+ }
+ return total;
+}
+
+move(p, ship, dir, row, col, drift)
+register char *p;
+register struct ship *ship;
+register char *dir;
+register short *row, *col;
+register char *drift;
+{
+ int dist;
+ char moved = 0;
+
+ for (; *p; p++) {
+ switch (*p) {
+ case 'r':
+ if (++*dir == 9)
+ *dir = 1;
+ break;
+ case 'l':
+ if (--*dir == 0)
+ *dir = 8;
+ break;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ moved++;
+ if (*dir % 2 == 0)
+ dist = dtab[*p - '0'];
+ else
+ dist = *p - '0';
+ *row -= dr[*dir] * dist;
+ *col -= dc[*dir] * dist;
+ break;
+ }
+ }
+ if (!moved) {
+ if (windspeed != 0 && ++*drift > 2) {
+ if (ship->specs->class >= 3 && !snagged(ship)
+ || (turn & 1) == 0) {
+ *row -= dr[winddir];
+ *col -= dc[winddir];
+ }
+ }
+ } else
+ *drift = 0;
+}
+
+try(command, temp, ma, ta, af, vma, dir, f, t, high, rakeme)
+register struct ship *f, *t;
+int ma, ta, af, *high, rakeme;
+char command[], temp[];
+{
+ register int new, n;
+ char st[4];
+#define rakeyou (gunsbear(f, t) && !gunsbear(t, f))
+
+ if ((n = strend(temp)) < '1' || n > '9')
+ for (n = 1; vma - n >= 0; n++) {
+ (void) sprintf(st, "%d", n);
+ (void) strcat(temp, st);
+ new = score(temp, f, t, rakeme);
+ if (new > *high && (!rakeme || rakeyou)) {
+ *high = new;
+ (void) strcpy(command, temp);
+ }
+ try(command, temp, ma-n, ta, af, vma-n,
+ dir, f, t, high, rakeme);
+ rmend(temp);
+ }
+ if (ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r' || !strlen(temp)) {
+ (void) strcat(temp, "r");
+ new = score(temp, f, t, rakeme);
+ if (new > *high && (!rakeme || gunsbear(f, t) && !gunsbear(t, f))) {
+ *high = new;
+ (void) strcpy(command, temp);
+ }
+ try(command, temp, ma-1, ta-1, af, min(ma-1, maxmove(f, (dir == 8 ? 1 : dir+1), 0)), (dir == 8 ? 1 : dir+1),f,t,high,rakeme);
+ rmend(temp);
+ }
+ if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)){
+ (void) strcat(temp, "l");
+ new = score(temp, f, t, rakeme);
+ if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){
+ *high = new;
+ (void) strcpy(command, temp);
+ }
+ try(command, temp, ma-1, ta-1, af, (min(ma-1,maxmove(f, (dir-1 ? dir-1 : 8), 0))), (dir-1 ? dir -1 : 8), f, t, high, rakeme);
+ rmend(temp);
+ }
+}
+
+rmend(str)
+char *str;
+{
+ register char *p;
+
+ for (p = str; *p; p++)
+ ;
+ if (p != str)
+ *--p = 0;
+}
diff --git a/sail/dr_3.c b/sail/dr_3.c
new file mode 100644
index 00000000..f3218ea4
--- /dev/null
+++ b/sail/dr_3.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_3.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "driver.h"
+
+moveall() /* move all comp ships */
+{
+ register struct ship *sp, *sq; /* r11, r10 */
+ register int n; /* r9 */
+ register int k, l; /* r8, r7 */
+ int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
+ char moved[NSHIP];
+
+ /*
+ * first try to create moves for OUR ships
+ */
+ foreachship(sp) {
+ struct ship *closest;
+ int ma, ta;
+ char af;
+
+ if (sp->file->captain[0] || sp->file->dir == 0)
+ continue;
+ if (!sp->file->struck && windspeed && !snagged(sp)
+ && sp->specs->crew3) {
+ ta = maxturns(sp, &af);
+ ma = maxmove(sp, sp->file->dir, 0);
+ closest = closestenemy(sp, 0, 0);
+ if (closest == 0)
+ *sp->file->movebuf = '\0';
+ else
+ closeon(sp, closest, sp->file->movebuf,
+ ta, ma, af);
+ } else
+ *sp->file->movebuf = '\0';
+ }
+ /*
+ * Then execute the moves for ALL ships (dead ones too),
+ * checking for collisions and snags at each step.
+ * The old positions are saved in row[], col[], dir[].
+ * At the end, we compare and write out the changes.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (snagged(sp))
+ (void) strcpy(sp->file->movebuf, "d");
+ else
+ if (*sp->file->movebuf != 'd')
+ (void) strcat(sp->file->movebuf, "d");
+ row[n] = sp->file->row;
+ col[n] = sp->file->col;
+ dir[n] = sp->file->dir;
+ drift[n] = sp->file->drift;
+ moved[n] = 0;
+ n++;
+ }
+ /*
+ * Now resolve collisions.
+ * This is the tough part.
+ */
+ for (k = 0; stillmoving(k); k++) {
+ /*
+ * Step once.
+ * And propagate the nulls at the end of sp->file->movebuf.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (!sp->file->movebuf[k])
+ sp->file->movebuf[k+1] = '\0';
+ else if (sp->file->dir)
+ step(sp->file->movebuf[k], sp, &moved[n]);
+ n++;
+ }
+ /*
+ * The real stuff.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (sp->file->dir == 0 || isolated(sp))
+ goto cont1;
+ l = 0;
+ foreachship(sq) {
+ char snap = 0;
+
+ if (sp == sq)
+ goto cont2;
+ if (sq->file->dir == 0)
+ goto cont2;
+ if (!push(sp, sq))
+ goto cont2;
+ if (snagged2(sp, sq) && range(sp, sq) > 1)
+ snap++;
+ if (!range(sp, sq) && !fouled2(sp, sq)) {
+ makesignal(sp,
+ "collision with %s (%c%c)", sq);
+ if (die() < 4) {
+ makesignal(sp,
+ "fouled with %s (%c%c)",
+ sq);
+ Write(W_FOUL, sp, 0, l, 0, 0, 0);
+ Write(W_FOUL, sq, 0, n, 0, 0, 0);
+ }
+ snap++;
+ }
+ if (snap) {
+ sp->file->movebuf[k + 1] = 0;
+ sq->file->movebuf[k + 1] = 0;
+ sq->file->row = sp->file->row - 1;
+ if (sp->file->dir == 1
+ || sp->file->dir == 5)
+ sq->file->col =
+ sp->file->col - 1;
+ else
+ sq->file->col = sp->file->col;
+ sq->file->dir = sp->file->dir;
+ }
+ cont2:
+ l++;
+ }
+ cont1:
+ n++;
+ }
+ }
+ /*
+ * Clear old moves. And write out new pos.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (sp->file->dir != 0) {
+ *sp->file->movebuf = 0;
+ if (row[n] != sp->file->row)
+ Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
+ if (col[n] != sp->file->col)
+ Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
+ if (dir[n] != sp->file->dir)
+ Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
+ if (drift[n] != sp->file->drift)
+ Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
+ }
+ n++;
+ }
+}
+
+stillmoving(k)
+register int k;
+{
+ register struct ship *sp;
+
+ foreachship(sp)
+ if (sp->file->movebuf[k])
+ return 1;
+ return 0;
+}
+
+isolated(ship)
+register struct ship *ship;
+{
+ register struct ship *sp;
+
+ foreachship(sp) {
+ if (ship != sp && range(ship, sp) <= 10)
+ return 0;
+ }
+ return 1;
+}
+
+push(from, to)
+register struct ship *from, *to;
+{
+ register int bs, sb;
+
+ sb = to->specs->guns;
+ bs = from->specs->guns;
+ if (sb > bs)
+ return 1;
+ if (sb < bs)
+ return 0;
+ return from < to;
+}
+
+step(com, sp, moved)
+char com;
+register struct ship *sp;
+char *moved;
+{
+ register int dist;
+
+ switch (com) {
+ case 'r':
+ if (++sp->file->dir == 9)
+ sp->file->dir = 1;
+ break;
+ case 'l':
+ if (--sp->file->dir == 0)
+ sp->file->dir = 8;
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ if (sp->file->dir % 2 == 0)
+ dist = dtab[com - '0'];
+ else
+ dist = com - '0';
+ sp->file->row -= dr[sp->file->dir] * dist;
+ sp->file->col -= dc[sp->file->dir] * dist;
+ *moved = 1;
+ break;
+ case 'b':
+ break;
+ case 'd':
+ if (!*moved) {
+ if (windspeed != 0 && ++sp->file->drift > 2 &&
+ (sp->specs->class >= 3 && !snagged(sp)
+ || (turn & 1) == 0)) {
+ sp->file->row -= dr[winddir];
+ sp->file->col -= dc[winddir];
+ }
+ } else
+ sp->file->drift = 0;
+ break;
+ }
+}
+
+sendbp(from, to, sections, isdefense)
+register struct ship *from, *to;
+int sections;
+char isdefense;
+{
+ int n;
+ register struct BP *bp;
+
+ bp = isdefense ? from->file->DBP : from->file->OBP;
+ for (n = 0; n < NBP && bp[n].turnsent; n++)
+ ;
+ if (n < NBP && sections) {
+ Write(isdefense ? W_DBP : W_OBP, from, 0,
+ n, turn, to->file->index, sections);
+ if (isdefense)
+ makesignal(from, "repelling boarders",
+ (struct ship *)0);
+ else
+ makesignal(from, "boarding the %s (%c%c)", to);
+ }
+}
+
+toughmelee(ship, to, isdefense, count)
+register struct ship *ship, *to;
+int isdefense, count;
+{
+ register struct BP *bp;
+ register obp = 0;
+ int n, OBP = 0, DBP = 0, dbp = 0;
+ int qual;
+
+ qual = ship->specs->qual;
+ bp = isdefense ? ship->file->DBP : ship->file->OBP;
+ for (n = 0; n < NBP; n++, bp++) {
+ if (bp->turnsent && (to == bp->toship || isdefense)) {
+ obp += bp->mensent / 100
+ ? ship->specs->crew1 * qual : 0;
+ obp += (bp->mensent % 100)/10
+ ? ship->specs->crew2 * qual : 0;
+ obp += bp->mensent % 10
+ ? ship->specs->crew3 * qual : 0;
+ }
+ }
+ if (count || isdefense)
+ return obp;
+ OBP = toughmelee(to, ship, 0, count + 1);
+ dbp = toughmelee(ship, to, 1, count + 1);
+ DBP = toughmelee(to, ship, 1, count + 1);
+ if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
+ return 1;
+ else
+ return 0;
+}
+
+reload()
+{
+ register struct ship *sp;
+
+ foreachship(sp) {
+ sp->file->loadwith = 0;
+ }
+}
+
+checksails()
+{
+ register struct ship *sp;
+ register int rig, full;
+ struct ship *close;
+
+ foreachship(sp) {
+ if (sp->file->captain[0] != 0)
+ continue;
+ rig = sp->specs->rig1;
+ if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
+ rig = 0;
+ if (rig && sp->specs->crew3) {
+ close = closestenemy(sp, 0, 0);
+ if (close != 0) {
+ if (range(sp, close) > 9)
+ full = 1;
+ else
+ full = 0;
+ } else
+ full = 0;
+ } else
+ full = 0;
+ if ((sp->file->FS != 0) != full)
+ Write(W_FS, sp, 0, full, 0, 0, 0);
+ }
+}
diff --git a/sail/dr_4.c b/sail/dr_4.c
new file mode 100644
index 00000000..e503ef51
--- /dev/null
+++ b/sail/dr_4.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_4.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+ungrap(from, to)
+register struct ship *from, *to;
+{
+ register k;
+ char friend;
+
+ if ((k = grappled2(from, to)) == 0)
+ return;
+ friend = capship(from)->nationality == capship(to)->nationality;
+ while (--k >= 0) {
+ if (friend || die() < 3) {
+ cleangrapple(from, to, 0);
+ makesignal(from, "ungrappling %s (%c%c)", to);
+ }
+ }
+}
+
+grap(from, to)
+register struct ship *from, *to;
+{
+ if (capship(from)->nationality != capship(to)->nationality && die() > 2)
+ return;
+ Write(W_GRAP, from, 0, to->file->index, 0, 0, 0);
+ Write(W_GRAP, to, 0, from->file->index, 0, 0, 0);
+ makesignal(from, "grappled with %s (%c%c)", to);
+}
diff --git a/sail/dr_5.c b/sail/dr_5.c
new file mode 100644
index 00000000..43d89a0a
--- /dev/null
+++ b/sail/dr_5.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_5.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+subtract(from, totalfrom, crewfrom, fromcap, pcfrom)
+struct ship *from, *fromcap;
+int pcfrom;
+register int totalfrom, crewfrom[3];
+{
+ register int n;
+
+ if (fromcap == from && totalfrom) { /* if not captured */
+ for (n = 0; n < 3; n++) {
+ if (totalfrom > crewfrom[n]) {
+ totalfrom -= crewfrom[n];
+ crewfrom[n] = 0;
+ } else {
+ crewfrom[n] -= totalfrom;
+ totalfrom = 0;
+ }
+ }
+ Write(W_CREW, from, 0, crewfrom[0], crewfrom[1], crewfrom[2], 0);
+ } else if (totalfrom) {
+ pcfrom -= totalfrom;
+ pcfrom = pcfrom < 0 ? 0 : pcfrom;
+ Write(W_PCREW, from, 0, pcfrom, 0, 0, 0);
+ }
+}
+
+mensent(from, to, crew, captured, pc, isdefense)
+struct ship *from, *to, **captured;
+int crew[3], *pc;
+char isdefense;
+{ /* returns # of crew squares sent */
+ int men = 0;
+ register int n;
+ int c1, c2, c3;
+ register struct BP *bp;
+
+ *pc = from->file->pcrew;
+ *captured = from->file->captured;
+ crew[0] = from->specs->crew1;
+ crew[1] = from->specs->crew2;
+ crew[2] = from->specs->crew3;
+ bp = isdefense ? from->file->DBP : from->file->OBP;
+ for (n=0; n < NBP; n++, bp++) {
+ if (bp->turnsent && bp->toship == to)
+ men += bp->mensent;
+ }
+ if (men) {
+ c1 = men/100 ? crew[0] : 0;
+ c2 = (men%100)/10 ? crew[1] : 0;
+ c3 = men/10 ? crew[2] : 0;
+ c3 = *captured == 0 ? crew[2] : *pc;
+ } else
+ c1 = c2 = c3 = 0;
+ return(c1 + c2 + c3);
+}
diff --git a/sail/dr_main.c b/sail/dr_main.c
new file mode 100644
index 00000000..c6e49681
--- /dev/null
+++ b/sail/dr_main.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_main.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "driver.h"
+
+dr_main()
+{
+ register int n;
+ register struct ship *sp;
+ int nat[NNATION];
+ int value = 0;
+
+ (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGQUIT, SIG_IGN);
+ (void) signal(SIGTSTP, SIG_IGN);
+ if (issetuid)
+ (void) setruid(geteuid());
+ if (game < 0 || game >= NSCENE) {
+ fprintf(stderr, "DRIVER: Bad game number %d\n", game);
+ exit(1);
+ }
+ cc = &scene[game];
+ ls = SHIP(cc->vessels);
+ if (sync_open() < 0) {
+ perror("driver: syncfile");
+ exit(1);
+ }
+ for (n = 0; n < NNATION; n++)
+ nat[n] = 0;
+ foreachship(sp) {
+ if (sp->file == NULL &&
+ (sp->file = (struct File *)calloc(1, sizeof (struct File))) == NULL) {
+ (void) fprintf(stderr, "DRIVER: Out of memory.\n");
+ exit(1);
+ }
+ sp->file->index = sp - SHIP(0);
+ sp->file->loadL = L_ROUND;
+ sp->file->loadR = L_ROUND;
+ sp->file->readyR = R_LOADED|R_INITIAL;
+ sp->file->readyL = R_LOADED|R_INITIAL;
+ sp->file->stern = nat[sp->nationality]++;
+ sp->file->dir = sp->shipdir;
+ sp->file->row = sp->shiprow;
+ sp->file->col = sp->shipcol;
+ }
+ windspeed = cc->windspeed;
+ winddir = cc->winddir;
+ people = 0;
+ for (;;) {
+ sleep(7);
+ if (Sync() < 0) {
+ value = 1;
+ break;
+ }
+ if (next() < 0)
+ break;
+ unfoul();
+ checkup();
+ prizecheck();
+ moveall();
+ thinkofgrapples();
+ boardcomp();
+ compcombat();
+ resolve();
+ reload();
+ checksails();
+ if (Sync() < 0) {
+ value = 1;
+ break;
+ }
+ }
+ sync_close(1);
+ return value;
+}
diff --git a/sail/driver.h b/sail/driver.h
new file mode 100644
index 00000000..9f487389
--- /dev/null
+++ b/sail/driver.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)driver.h 5.4 (Berkeley) 6/1/90
+ */
+
+#include "externs.h"
+
+int dtab[];
diff --git a/sail/externs.h b/sail/externs.h
new file mode 100644
index 00000000..64068c90
--- /dev/null
+++ b/sail/externs.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)externs.h 5.4 (Berkeley) 6/1/90
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include "machdep.h"
+
+ /* program mode */
+int mode;
+jmp_buf restart;
+#define MODE_PLAYER 1
+#define MODE_DRIVER 2
+#define MODE_LOGGER 3
+
+ /* command line flags */
+char debug; /* -D */
+char randomize; /* -x, give first available ship */
+char longfmt; /* -l, print score in long format */
+char nobells; /* -b, don't ring bell before Signal */
+
+ /* other initial modes */
+char issetuid; /* running setuid */
+
+#define die() ((rand() >> 3) % 6 + 1)
+#define sqr(a) ((a) * (a))
+#define abs(a) ((a) > 0 ? (a) : -(a))
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+#define grappled(a) ((a)->file->ngrap)
+#define fouled(a) ((a)->file->nfoul)
+#define snagged(a) (grappled(a) + fouled(a))
+
+#define grappled2(a, b) ((a)->file->grap[(b)->file->index].sn_count)
+#define fouled2(a, b) ((a)->file->foul[(b)->file->index].sn_count)
+#define snagged2(a, b) (grappled2(a, b) + fouled2(a, b))
+
+#define Xgrappled2(a, b) ((a)->file->grap[(b)->file->index].sn_turn < turn-1 ? grappled2(a, b) : 0)
+#define Xfouled2(a, b) ((a)->file->foul[(b)->file->index].sn_turn < turn-1 ? fouled2(a, b) : 0)
+#define Xsnagged2(a, b) (Xgrappled2(a, b) + Xfouled2(a, b))
+
+#define cleangrapple(a, b, c) Cleansnag(a, b, c, 1)
+#define cleanfoul(a, b, c) Cleansnag(a, b, c, 2)
+#define cleansnag(a, b, c) Cleansnag(a, b, c, 3)
+
+#define sterncolour(sp) ((sp)->file->stern+'0'-((sp)->file->captured?10:0))
+#define sternrow(sp) ((sp)->file->row + dr[(sp)->file->dir])
+#define sterncol(sp) ((sp)->file->col + dc[(sp)->file->dir])
+
+#define capship(sp) ((sp)->file->captured?(sp)->file->captured:(sp))
+
+#define readyname(r) ((r) & R_LOADING ? '*' : ((r) & R_INITIAL ? '!' : ' '))
+
+/* loadL and loadR, should match loadname[] */
+#define L_EMPTY 0 /* should be 0, don't change */
+#define L_GRAPE 1
+#define L_CHAIN 2
+#define L_ROUND 3
+#define L_DOUBLE 4
+#define L_EXPLODE 5
+
+/*
+ * readyL and readyR, these are bits, except R_EMPTY
+ */
+#define R_EMPTY 0 /* not loaded and not loading */
+#define R_LOADING 1 /* loading */
+#define R_DOUBLE 2 /* loading double */
+#define R_LOADED 4 /* loaded */
+#define R_INITIAL 8 /* loaded initial */
+
+#define HULL 0
+#define RIGGING 1
+
+#define W_CAPTAIN 1
+#define W_CAPTURED 2
+#define W_CLASS 3
+#define W_CREW 4
+#define W_DBP 5
+#define W_DRIFT 6
+#define W_EXPLODE 7
+#define W_FILE 8
+#define W_FOUL 9
+#define W_GUNL 10
+#define W_GUNR 11
+#define W_HULL 12
+#define W_MOVE 13
+#define W_OBP 14
+#define W_PCREW 15
+#define W_UNFOUL 16
+#define W_POINTS 17
+#define W_QUAL 18
+#define W_UNGRAP 19
+#define W_RIGG 20
+#define W_COL 21
+#define W_DIR 22
+#define W_ROW 23
+#define W_SIGNAL 24
+#define W_SINK 25
+#define W_STRUCK 26
+#define W_TA 27
+#define W_ALIVE 28
+#define W_TURN 29
+#define W_WIND 30
+#define W_FS 31
+#define W_GRAP 32
+#define W_RIG1 33
+#define W_RIG2 34
+#define W_RIG3 35
+#define W_RIG4 36
+#define W_BEGIN 37
+#define W_END 38
+#define W_DDEAD 39
+
+#define NLOG 10
+struct logs {
+ char l_name[20];
+ int l_uid;
+ int l_shipnum;
+ int l_gamenum;
+ int l_netpoints;
+};
+
+struct BP {
+ short turnsent;
+ struct ship *toship;
+ short mensent;
+};
+
+struct snag {
+ short sn_count;
+ short sn_turn;
+};
+
+#define NSCENE nscene
+#define NSHIP 10
+#define NBP 3
+
+#define NNATION 8
+#define N_A 0
+#define N_B 1
+#define N_S 2
+#define N_F 3
+#define N_J 4
+#define N_D 5
+#define N_K 6
+#define N_O 7
+
+struct File {
+ int index;
+ char captain[20]; /* 0 */
+ short points; /* 20 */
+ char loadL; /* 22 */
+ char loadR; /* 24 */
+ char readyL; /* 26 */
+ char readyR; /* 28 */
+ struct BP OBP[NBP]; /* 30 */
+ struct BP DBP[NBP]; /* 48 */
+ char struck; /* 66 */
+ struct ship *captured; /* 68 */
+ short pcrew; /* 70 */
+ char movebuf[10]; /* 72 */
+ char drift; /* 82 */
+ short nfoul;
+ short ngrap;
+ struct snag foul[NSHIP]; /* 84 */
+ struct snag grap[NSHIP]; /* 124 */
+ char RH; /* 224 */
+ char RG; /* 226 */
+ char RR; /* 228 */
+ char FS; /* 230 */
+ char explode; /* 232 */
+ char sink; /* 234 */
+ char dir;
+ short col;
+ short row;
+ char loadwith;
+ char stern;
+};
+
+struct ship {
+ char *shipname; /* 0 */
+ struct shipspecs *specs; /* 2 */
+ char nationality; /* 4 */
+ short shiprow; /* 6 */
+ short shipcol; /* 8 */
+ char shipdir; /* 10 */
+ struct File *file; /* 12 */
+};
+
+struct scenario {
+ char winddir; /* 0 */
+ char windspeed; /* 2 */
+ char windchange; /* 4 */
+ char vessels; /* 12 */
+ char *name; /* 14 */
+ struct ship ship[NSHIP]; /* 16 */
+};
+struct scenario scene[];
+int nscene;
+
+struct shipspecs {
+ char bs;
+ char fs;
+ char ta;
+ short guns;
+ char class;
+ char hull;
+ char qual;
+ char crew1;
+ char crew2;
+ char crew3;
+ char gunL;
+ char gunR;
+ char carL;
+ char carR;
+ char rig1;
+ char rig2;
+ char rig3;
+ char rig4;
+ short pts;
+};
+struct shipspecs specs[];
+
+struct scenario *cc; /* the current scenario */
+struct ship *ls; /* &cc->ship[cc->vessels] */
+
+#define SHIP(s) (&cc->ship[s])
+#define foreachship(sp) for ((sp) = cc->ship; (sp) < ls; (sp)++)
+
+struct windeffects {
+ char A, B, C, D;
+};
+struct windeffects WET[7][6];
+
+struct Tables {
+ char H, G, C, R;
+};
+struct Tables RigTable[11][6];
+struct Tables HullTable[11][6];
+
+char AMMO[9][4];
+char HDT[9][10];
+char HDTrake[9][10];
+char QUAL[9][5];
+char MT[9][3];
+
+char *countryname[];
+char *classname[];
+char *directionname[];
+char *qualname[];
+char loadname[];
+
+char rangeofshot[];
+
+char dr[], dc[];
+
+int winddir;
+int windspeed;
+int turn;
+int game;
+int alive;
+int people;
+char hasdriver;
+
+char *info();
+char *quality();
+double arctan();
+char *saywhat();
+struct ship *closestenemy();
+
+char *calloc();
+char *rindex();
+char *strcpy();
+char *strcat();
+char *strncpy();
+char *getenv();
+char *gets();
diff --git a/sail/game.c b/sail/game.c
new file mode 100644
index 00000000..9b8add72
--- /dev/null
+++ b/sail/game.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)game.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+maxturns(ship, af)
+register struct ship *ship;
+char *af;
+{
+ register int turns;
+
+ turns = ship->specs->ta;
+ if (*af = (ship->file->drift > 1 && turns)) {
+ turns--;
+ if (ship->file->FS == 1)
+ turns = 0;
+ }
+ return turns;
+}
+
+maxmove(ship, dir, fs)
+register struct ship *ship;
+int dir, fs;
+{
+ register int riggone = 0, Move, flank = 0;
+
+ Move = ship->specs->bs;
+ if (!ship->specs->rig1)
+ riggone++;
+ if (!ship->specs->rig2)
+ riggone++;
+ if (!ship->specs->rig3)
+ riggone++;
+ if (!ship->specs->rig4)
+ riggone++;
+ if ((ship->file->FS || fs) && fs != -1) {
+ flank = 1;
+ Move = ship->specs->fs;
+ }
+ if (dir == winddir)
+ Move -= 1 + WET[windspeed][ship->specs->class-1].B;
+ else if (dir == winddir + 2 || dir == winddir - 2 || dir == winddir - 6 || dir == winddir + 6)
+ Move -= 1 + WET[windspeed][ship->specs->class-1].C;
+ else if (dir == winddir + 3 || dir == winddir - 3 || dir == winddir - 5 || dir == winddir + 5)
+ Move = (flank ? 2 : 1) - WET[windspeed][ship->specs->class-1].D;
+ else if (dir == winddir + 4 || dir == winddir - 4)
+ Move = 0;
+ else
+ Move -= WET[windspeed][ship->specs->class-1].A;
+ Move -= riggone;
+ Move = Move < 0 ? 0 : Move;
+ return(Move);
+}
diff --git a/sail/globals.c b/sail/globals.c
new file mode 100644
index 00000000..2e673e97
--- /dev/null
+++ b/sail/globals.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)globals.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+struct scenario scene[] = {
+ /*
+ * int winddir;
+ * int windspeed;
+ * int windchange;
+ * int vessels;
+ * char *name;
+ * struct ship ship[NSHIP];
+ */
+ 5, 3, 5, 2, "Ranger vs. Drake",
+ {
+ { "Ranger", specs+0, N_A, 7, 20, 4, 0 },
+ { "Drake", specs+1, N_B, 7, 31, 5, 0 }
+ },
+ 1, 3, 6, 2, "The Battle of Flamborough Head",
+ {
+ { "Bonhomme Rich", specs+2, N_A, 13, 40, 2, 0 },
+ { "Serapis", specs+3, N_B, 2, 42, 2, 0 }
+ },
+ 5, 5, 5, 10, "Arbuthnot and Des Touches",
+ {
+ { "America", specs+4, N_B, 7, 37, 4, 0 },
+ { "Befford", specs+5, N_B, 5, 35, 4, 0 },
+ { "Adamant", specs+6, N_B, 3, 33, 4, 0 },
+ { "London", specs+7, N_B, 1, 31, 4, 0 },
+ { "Royal Oak", specs+8, N_B, -1, 29, 4, 0 },
+ { "Neptune", specs+9, N_F, 6, 44, 4, 0 },
+ { "Duc Bougogne", specs+10, N_F, 8, 46, 4, 0 },
+ { "Conquerant", specs+48, N_F, 10, 48, 4, 0 },
+ { "Provence", specs+11, N_F, 12, 50, 4, 0 },
+ { "Romulus", specs+12, N_F, 20, 58, 4, 0 }
+ },
+ 1, 3, 5, 10, "Suffren and Hughes",
+ {
+ { "Monmouth", specs+52, N_B, 9, 45, 2, 0 },
+ { "Hero", specs+5, N_B, 13, 49, 2, 0 },
+ { "Isis", specs+6, N_B, 12, 48, 2, 0 },
+ { "Superb", specs+50, N_B, 10, 46, 2, 0 },
+ { "Burford", specs+48, N_B, 11, 47, 2, 0 },
+ { "Flamband", specs+13, N_F, 7, 59, 4, 0 },
+ { "Annibal", specs+9, N_F, 4, 56, 4, 0 },
+ { "Severe", specs+11, N_F, 2, 54, 4, 0 },
+ { "Brilliant", specs+49, N_F, -1, 51, 4, 0 },
+ { "Sphinx", specs+51, N_F, -5, 47, 4, 0 }
+ },
+ 1, 3, 4, 2, "Nymphe vs. Cleopatre",
+ {
+ { "Nymphe", specs+14, N_B, 13, 30, 2, 0 },
+ { "Cleopatre", specs+15, N_F, 3, 41, 2, 0 }
+ },
+ 1, 3, 5, 2, "Mars vs. Hercule",
+ {
+ { "Mars", specs+16, N_B, 13, 30, 2, 0 },
+ { "Hercule", specs+17, N_F, 3, 41, 2, 0 }
+ },
+ 5, 3, 5, 2, "Ambuscade vs. Baionnaise",
+ {
+ { "Ambuscade", specs+18, N_B, 13, 30, 2, 0 },
+ { "Baionnaise", specs+19, N_F, 3, 41, 2, 0 }
+ },
+ 1, 5, 6, 2, "Constellation vs. Insurgent",
+ {
+ { "Constellation", specs+20, N_A, 9, 50, 8, 0 },
+ { "Insurgent", specs+22, N_F, 4, 24, 2, 0 }
+ },
+ 1, 3, 5, 2, "Constellation vs. Vengeance",
+ {
+ { "Constellation", specs+20, N_A, 12, 40, 2, 0 },
+ { "Vengeance", specs+21, N_F, 1, 43, 2, 0 }
+ },
+ 1, 3, 6, 10, "The Battle of Lissa",
+ {
+ { "Amphion", specs+23, N_B, 8, 50, 4, 0 },
+ { "Active", specs+24, N_B, 6, 48, 4, 0 },
+ { "Volage", specs+25, N_B, 4, 46, 4, 0 },
+ { "Cerberus", specs+26, N_B, 2, 44, 4, 0 },
+ { "Favorite", specs+27, N_F, 9, 34, 2, 0 },
+ { "Flore", specs+21, N_F, 13, 39, 2, 0 },
+ { "Danae", specs+64, N_F, 15, 37, 2, 0 },
+ { "Bellona", specs+28, N_F, 17, 35, 2, 0 },
+ { "Corona", specs+29, N_F, 12, 31, 2, 0 },
+ { "Carolina", specs+30, N_F, 15, 28, 2, 0 }
+ },
+ 2, 5, 6, 2, "Constitution vs. Guerriere",
+ {
+ { "Constitution", specs+31, N_A, 7, 35, 1, 0 },
+ { "Guerriere", specs+32, N_B, 7, 47, 4, 0 }
+ },
+ 1, 3, 5, 2, "United States vs. Macedonian",
+ {
+ { "United States", specs+33, N_A, 1, 52, 6, 0 },
+ { "Macedonian", specs+34, N_B, 14, 40, 1, 0 }
+ },
+ 1, 3, 6, 2, "Constitution vs. Java",
+ {
+ { "Constitution", specs+31, N_A, 1, 40, 2, 0 },
+ { "Java", specs+35, N_B, 11, 40, 2, 0 }
+ },
+ 1, 3, 5, 2, "Chesapeake vs. Shannon",
+ {
+ { "Chesapeake", specs+36, N_A, 13, 40, 2, 0 },
+ { "Shannon", specs+37, N_B, 1, 42, 2, 0 }
+ },
+ 1, 1, 6, 5, "The Battle of Lake Erie",
+ {
+ { "Lawrence", specs+38, N_A, 4, 55, 8, 0 },
+ { "Niagara", specs+42, N_A, 7, 61, 8, 0 },
+ { "Lady Prevost", specs+39, N_B, 4, 25, 2, 0 },
+ { "Detroit", specs+40, N_B, 7, 22, 2, 0 },
+ { "Q. Charlotte", specs+41, N_B, 10, 19, 2, 0 }
+ },
+ 1, 1, 5, 2, "Wasp vs. Reindeer",
+ {
+ { "Wasp", specs+42, N_A, 3, 41, 2, 0 },
+ { "Reindeer", specs+43, N_B, 10, 48, 2, 0 }
+ },
+ 1, 2, 5, 3, "Constitution vs. Cyane and Levant",
+ {
+ { "Constitution", specs+31, N_A, 10, 45, 2, 0 },
+ { "Cyane", specs+44, N_B, 3, 37, 2, 0 },
+ { "Levant", specs+45, N_B, 5, 35, 2, 0 }
+ },
+ 5, 5, 5, 3, "Pellew vs. Droits de L'Homme",
+ {
+ { "Indefatigable", specs+46, N_B, 12, 45, 6, 0 },
+ { "Amazon", specs+47, N_B, 9, 48, 6, 0 },
+ { "Droits L'Hom", specs+48, N_F, 3, 28, 5, 0 }
+ },
+ 2, 2, 3, 10, "Algeciras",
+ {
+ { "Caesar", specs+49, N_B, 7, 70, 6, 0 },
+ { "Pompee", specs+50, N_B, 5, 72, 6, 0 },
+ { "Spencer", specs+5, N_B, 3, 74, 6, 0 },
+ { "Hannibal", specs+7, N_B, 1, 76, 6, 0 },
+ { "Real-Carlos", specs+53, N_S, 9, 20, 3, 0 },
+ { "San Fernando", specs+54, N_S, 11, 16, 3, 0 },
+ { "Argonauta", specs+55, N_S, 10, 14, 4, 0 },
+ { "San Augustine", specs+56, N_S, 6, 22, 4, 0 },
+ { "Indomptable", specs+51, N_F, 7, 23, 5, 0 },
+ { "Desaix", specs+52, N_F, 7, 27, 7, 0 }
+ },
+ 5, 3, 6, 7, "Lake Champlain",
+ {
+ { "Saratoga", specs+60, N_A, 8, 10, 1, 0 },
+ { "Eagle", specs+61, N_A, 9, 13, 2, 0 },
+ { "Ticonderoga", specs+62, N_A, 12, 17, 3, 0 },
+ { "Preble", specs+63, N_A, 14, 20, 2, 0 },
+ { "Confiance", specs+57, N_B, 4, 70, 6, 0 },
+ { "Linnet", specs+58, N_B, 7, 68, 6, 0 },
+ { "Chubb", specs+59, N_B, 10, 65, 6, 0 }
+ },
+ 5, 3, 6, 4, "Last Voyage of the USS President",
+ {
+ { "President", specs+67, N_A, 12, 42, 5, 0 },
+ { "Endymion", specs+64, N_B, 5, 42, 5, 0 },
+ { "Pomone", specs+65, N_B, 7, 82, 6, 0 },
+ { "Tenedos", specs+66, N_B, 7, -1, 4, 0 }
+ },
+ 7, 5, 5, 2, "Hornblower and the Natividad",
+ {
+ { "Lydia", specs+68, N_B, 12, 40, 2, 0 },
+ { "Natividad", specs+69, N_S, 2, 40, 4, 0 }
+ },
+ 1, 3, 6, 2, "Curse of the Flying Dutchman",
+ {
+ { "Piece of Cake", specs+19, N_S, 7, 40, 2, 0 },
+ { "Flying Dutchy", specs+71, N_F, 7, 41, 1, 0 }
+ },
+ 1, 4, 1, 4, "The South Pacific",
+ {
+ { "USS Scurvy", specs+70, N_A, 7, 40, 1, 0 },
+ { "HMS Tahiti", specs+71, N_B, 12, 60, 1, 0 },
+ { "Australian", specs+18, N_S, 5, 20, 8, 0 },
+ { "Bikini Atoll", specs+63, N_F, 2, 60, 4, 0 }
+ },
+ 7, 3, 6, 5, "Hornblower and the battle of Rosas bay",
+ {
+ { "Sutherland", specs+5, N_B, 13, 30, 2, 0 },
+ { "Turenne", specs+10, N_F, 9, 35, 6, 0 },
+ { "Nightmare", specs+9, N_F, 7, 37, 6, 0 },
+ { "Paris", specs+53, N_F, 3, 45, 4, 0 },
+ { "Napolean", specs+56, N_F, 1, 40, 6, 0 }
+ },
+ 6, 4, 7, 5, "Cape Horn",
+ {
+ { "Concord", specs+51, N_A, 3, 20, 4, 0 },
+ { "Berkeley", specs+7, N_A, 5, 50, 5, 0 },
+ { "Thames", specs+71, N_B, 10, 40, 1, 0 },
+ { "Madrid", specs+53, N_S, 13, 60, 8, 0 },
+ { "Musket", specs+10, N_F, 10, 60, 7, 0 }
+ },
+ 8, 3, 7, 3, "New Orleans",
+ {
+ { "Alligator", specs+71, N_A, 13, 5, 1, 0 },
+ { "Firefly", specs+50, N_B, 10, 20, 8, 0 },
+ { "Cypress", specs+46, N_B, 5, 10, 6, 0 }
+ },
+ 5, 3, 7, 3, "Botany Bay",
+ {
+ { "Shark", specs+11, N_B, 6, 15, 4, 0 },
+ { "Coral Snake", specs+31, N_F, 3, 30, 6, 0 },
+ { "Sea Lion", specs+33, N_F, 13, 50, 8, 0 }
+ },
+ 4, 3, 6, 4, "Voyage to the Bottom of the Sea",
+ {
+ { "Seaview", specs+71, N_A, 6, 3, 3, 0 },
+ { "Flying Sub", specs+64, N_A, 8, 3, 3, 0 },
+ { "Mermaid", specs+70, N_B, 2, 5, 5, 0 },
+ { "Giant Squid", specs+53, N_S, 10, 30, 8, 0 }
+ },
+ 7, 3, 6, 3, "Frigate Action",
+ {
+ { "Killdeer", specs+21, N_A, 7, 20, 8, 0 },
+ { "Sandpiper", specs+27, N_B, 5, 40, 8, 0 },
+ { "Curlew", specs+34, N_S, 10, 60, 8, 0 }
+ },
+ 7, 2, 5, 6, "The Battle of Midway",
+ {
+ { "Enterprise", specs+49, N_A, 10, 70, 8, 0 },
+ { "Yorktown", specs+51, N_A, 3, 70, 7, 0 },
+ { "Hornet", specs+52, N_A, 6, 70, 7, 0 },
+ { "Akagi", specs+53, N_J, 6, 10, 4, 0 },
+ { "Kaga", specs+54, N_J, 4, 12, 4, 0 },
+ { "Soryu", specs+55, N_J, 2, 14, 4, 0 }
+ },
+ 1, 3, 4, 8, "Star Trek",
+ {
+ { "Enterprise", specs+76, N_D,-10, 60, 7, 0 },
+ { "Yorktown", specs+77, N_D, 0, 70, 7, 0 },
+ { "Reliant", specs+78, N_D, 10, 70, 7, 0 },
+ { "Galileo", specs+79, N_D, 20, 60, 7, 0 },
+ { "Kobayashi Maru", specs+80, N_K, 0,120, 7, 0 },
+ { "Klingon II", specs+81, N_K, 10,120, 7, 0 },
+ { "Red Orion", specs+82, N_O, 0, 0, 3, 0 },
+ { "Blue Orion", specs+83, N_O, 10, 0, 3, 0 }
+ }
+};
+int nscene = sizeof scene / sizeof (struct scenario);
+
+struct shipspecs specs[] = {
+/* bs fs ta guns hull crew1 crew3 gunR carR rig2 rig4 pts */
+/* class qual crew2 gunL carL rig1 rig3 */
+/*00*/ 4, 7, 3, 19, 5, 5, 4, 2, 2, 2, 2, 2, 0, 0, 4, 4, 4, 4, 7,
+/*01*/ 4, 7, 3, 17, 5, 5, 4, 2, 2, 2, 0, 0, 4, 4, 3, 3, 3, 3, 6,
+/*02*/ 3, 5, 2, 42, 4, 7, 4, 2, 2, 2, 2, 2, 0, 0, 5, 5, 5, -1, 11,
+/*03*/ 4, 6, 3, 44, 3, 7, 4, 2, 2, 2, 3, 3, 0, 0, 5, 5, 5, 5, 12,
+/*04*/ 3, 5, 2, 64, 2, 17, 4, 8, 6, 6, 12, 12, 2, 2, 7, 7, 7, -1, 20,
+/*05*/ 3, 5, 2, 74, 2, 20, 4, 8, 8, 8, 16, 16, 2, 2, 7, 7, 7, -1, 26,
+/*06*/ 3, 5, 2, 50, 2, 12, 4, 6, 4, 4, 8, 8, 2, 2, 6, 6, 6, -1, 17,
+/*07*/ 3, 5, 1, 98, 1, 23, 4, 10, 10, 10, 18, 18, 2, 2, 8, 8, 8, -1, 28,
+/*08*/ 3, 5, 2, 74, 2, 20, 4, 8, 8, 8, 16, 16, 2, 2, 7, 7, 7, -1, 26,
+/*09*/ 3, 5, 2, 74, 2, 21, 3, 10, 10, 8, 20, 20, 0, 0, 7, 7, 7, -1, 24,
+/*10*/ 3, 5, 1, 80, 1, 23, 3, 12, 12, 10, 22, 22, 0, 0, 7, 7, 7, -1, 27,
+/*11*/ 3, 5, 2, 64, 2, 18, 3, 8, 8, 6, 12, 12, 0, 0, 7, 7, 7, -1, 18,
+/*12*/ 3, 5, 2, 44, 2, 11, 3, 4, 4, 4, 6, 6, 2, 2, 5, 5, 5, -1, 10,
+/*13*/ 3, 5, 2, 50, 2, 14, 3, 6, 6, 4, 8, 8, 0, 0, 6, 6, 6, -1, 14,
+/*14*/ 4, 6, 3, 36, 3, 11, 4, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 11,
+/*15*/ 4, 6, 3, 36, 3, 11, 3, 4, 4, 4, 4, 4, 2, 2, 5, 5, 5, 5, 10,
+/*16*/ 3, 5, 2, 74, 2, 21, 4, 10, 8, 8, 18, 18, 2, 2, 7, 7, 7, -1, 26,
+/*17*/ 3, 5, 2, 74, 2, 21, 3, 10, 10, 8, 20, 20, 2, 2, 7, 7, 7, -1, 23,
+/*18*/ 4, 6, 3, 32, 3, 8, 3, 4, 2, 2, 4, 4, 2, 2, 5, 5, 5, 5, 9,
+/*19*/ 4, 6, 3, 24, 4, 6, 3, 4, 4, 4, 2, 2, 0, 0, 4, 4, 4, 4, 9,
+/*20*/ 4, 7, 3, 38, 4, 14, 5, 6, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5, 17,
+/*21*/ 4, 6, 3, 40, 3, 15, 3, 8, 6, 6, 6, 6, 4, 4, 5, 5, 5, 5, 15,
+/*22*/ 4, 7, 3, 36, 4, 11, 3, 6, 6, 4, 4, 4, 2, 2, 5, 5, 5, 5, 11,
+/*23*/ 4, 6, 3, 32, 3, 11, 5, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 13,
+/*24*/ 4, 6, 3, 38, 3, 14, 5, 4, 4, 4, 6, 6, 4, 4, 5, 5, 5, 5, 18,
+/*25*/ 4, 6, 3, 22, 3, 6, 5, 2, 2, 2, 0, 0, 8, 8, 4, 4, 4, 4, 11,
+/*26*/ 4, 6, 3, 32, 3, 11, 5, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 13,
+/*27*/ 4, 6, 3, 40, 3, 14, 3, 6, 6, 4, 6, 6, 4, 4, 5, 5, 5, 5, 15,
+/*28*/ 4, 6, 3, 32, 3, 11, 2, 4, 4, 4, 4, 4, 0, 0, 5, 5, 5, 5, 9,
+/*29*/ 4, 6, 3, 40, 3, 14, 2, 6, 6, 4, 6, 6, 4, 4, 5, 5, 5, 5, 12,
+/*30*/ 4, 6, 3, 32, 3, 8, 2, 4, 4, 1, 2, 2, 0, 0, 4, 4, 4, 4, 7,
+/*31*/ 4, 7, 3, 44, 4, 18, 5, 6, 6, 6, 8, 8, 6, 6, 6, 6, 6, 6, 24,
+/*32*/ 4, 6, 3, 38, 3, 14, 4, 4, 4, 2, 6, 6, 4, 4, 5, 5, 5, 5, 15,
+/*33*/ 4, 5, 3, 44, 3, 18, 5, 8, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 24,
+/*34*/ 4, 6, 3, 38, 3, 14, 4, 4, 4, 4, 6, 6, 4, 4, 5, 5, 5, 5, 16,
+/*35*/ 4, 7, 3, 38, 4, 14, 4, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 19,
+/*36*/ 4, 6, 3, 38, 3, 14, 3, 6, 6, 4, 6, 6, 6, 6, 5, 5, 5, 5, 14,
+/*37*/ 4, 6, 3, 38, 3, 14, 5, 6, 4, 4, 6, 6, 6, 6, 5, 5, 5, 5, 17,
+/*38*/ 4, 7, 3, 20, 5, 6, 4, 4, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 9,
+/*39*/ 4, 7, 3, 13, 6, 3, 4, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 5,
+/*40*/ 4, 7, 3, 19, 5, 5, 4, 2, 2, 2, 2, 2, 0, 0, 4, 4, 4, 4, 7,
+/*41*/ 4, 7, 3, 17, 5, 5, 4, 2, 2, 2, 2, 2, 0, 0, 3, 3, 3, 3, 6,
+/*42*/ 4, 7, 3, 20, 5, 6, 5, 4, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 12,
+/*43*/ 4, 7, 3, 18, 5, 5, 5, 2, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 9,
+/*44*/ 4, 7, 3, 24, 5, 6, 4, 4, 2, 2, 0, 0,10,10, 4, 4, 4, 4, 11,
+/*45*/ 4, 7, 3, 20, 5, 6, 4, 2, 2, 2, 0, 0, 8, 8, 4, 4, 4, 4, 10,
+/*46*/ 4, 6, 3, 44, 3, 11, 5, 4, 4, 4, 4, 4, 2, 2, 5, 5, 5, 5, 14,
+/*47*/ 4, 6, 3, 36, 3, 12, 4, 4, 4, 4, 6, 6, 2, 2, 5, 5, 5, 5, 14,
+/*48*/ 3, 5, 2, 74, 2, 21, 3, 10, 8, 8, 20, 20, 2, 2, 4, 4, 7, -1, 24,
+/*49*/ 3, 5, 2, 80, 2, 24, 4, 10, 8, 8, 20, 20, 2, 2, 8, 8, 8, -1, 31,
+/*50*/ 3, 5, 2, 74, 2, 21, 4, 8, 8, 6, 16, 16, 4, 4, 7, 7, 7, -1, 27,
+/*51*/ 3, 5, 2, 80, 2, 24, 3, 12, 12, 10, 22, 22, 2, 2, 7, 7, 7, -1, 27,
+/*52*/ 3, 5, 2, 74, 2, 21, 3, 10, 10, 8, 20, 20, 2, 2, 7, 7, 7, -1, 24,
+/*53*/ 3, 5, 1, 112, 1, 27, 2, 12, 12, 12, 24, 24, 0, 0, 9, 9, 9, -1, 27,
+/*54*/ 3, 5, 1, 96, 1, 24, 2, 12, 12, 10, 20, 20, 0, 0, 8, 8, 8, -1, 24,
+/*55*/ 3, 5, 2, 80, 2, 23, 2, 10, 10, 8, 20, 20, 0, 0, 7, 7, 7, -1, 23,
+/*56*/ 3, 5, 2, 74, 2, 21, 2, 10, 8, 8, 16, 16, 4, 4, 7, 7, 7, -1, 20,
+/*57*/ 4, 6, 3, 37, 3, 12, 4, 4, 4, 2, 6, 6, 4, 4, 5, 5, 5, 5, 14,
+/*58*/ 4, 7, 3, 16, 5, 5, 5, 2, 2, 2, 0, 0, 4, 4, 4, 4, 4, 4, 10,
+/*59*/ 4, 7, 3, 11, 6, 3, 4, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 5,
+/*60*/ 4, 7, 3, 26, 5, 6, 4, 4, 2, 2, 2, 2, 6, 6, 4, 4, 4, 4, 12,
+/*61*/ 4, 7, 3, 20, 5, 6, 4, 4, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 11,
+/*62*/ 4, 7, 3, 17, 5, 5, 4, 2, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 9,
+/*63*/ 4, 7, 3, 7, 6, 3, 4, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 4,
+/*64*/ 4, 6, 3, 40, 3, 15, 4, 4, 4, 4, 8, 8, 6, 6, 5, 5, 5, 5, 17,
+/*65*/ 4, 6, 3, 44, 3, 15, 4, 8, 8, 6, 10, 10, 2, 2, 6, 6, 6, 6, 20,
+/*66*/ 4, 6, 3, 38, 3, 14, 4, 4, 4, 4, 6, 6, 6, 6, 5, 5, 5, 5, 15,
+/*67*/ 4, 5, 3, 44, 3, 18, 5, 8, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 24,
+/*68*/ 4, 6, 3, 36, 3, 9, 5, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 13,
+/*69*/ 3, 5, 2, 50, 2, 14, 2, 6, 6, 6, 8, 8, 0, 0, 6, 6, 6, -1, 14,
+/*70*/ 3, 5, 1, 136, 1, 30, 1, 8, 14, 14, 28, 28, 0, 0, 9, 9, 9, -1, 27,
+/*71*/ 3, 5, 1, 120, 1, 27, 5, 16, 14, 14, 28, 28, 2, 2, 9, 9, 9, -1, 43,
+/*72*/ 3, 5, 1, 120, 2, 21, 5, 15, 17, 15, 25, 25, 7, 7, 9, 9, 9, -1, 36,
+/*73*/ 3, 5, 1, 90, 3, 18, 4, 13, 15, 13, 20, 20, 6, 6, 5, 5, 5, 5, 28,
+/*74*/ 4, 7, 3, 6, 6, 3, 4, 2, 2, 2, 20, 20, 6, 6, 2, 2, 3, 3, 5,
+/*75*/ 3, 5, 1, 110, 2, 20, 4, 14, 15, 11, 26, 26, 8, 8, 7, 8, 9, -1, 34,
+/*76*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*77*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*78*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*79*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*80*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*81*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*82*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*83*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/* bs fs ta guns hull crew1 crew3 gunR carR rig2 rig4 pts */
+/* class qual crew2 gunL carL rig1 rig3 */
+};
+
+struct windeffects WET[7][6] = {
+ { {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9} },
+ { {3,2,2,0}, {3,2,1,0}, {3,2,1,0}, {3,2,1,0}, {2,1,0,0}, {2,1,0,0} },
+ { {1,1,1,0}, {1,1,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0} },
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} },
+ { {0,0,0,0}, {1,0,0,0}, {1,1,0,0}, {1,1,0,0}, {2,2,1,0}, {2,2,1,0} },
+ { {1,0,0,0}, {1,1,0,0}, {1,1,1,0}, {1,1,1,0}, {3,2,2,0}, {3,2,2,0} },
+ { {2,1,1,0}, {3,2,1,0}, {3,2,1,0}, {3,2,1,0}, {3,3,2,0}, {3,3,2,0} }
+};
+
+struct Tables RigTable[11][6] = {
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,1}, {0,0,1,0} },
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,1}, {0,0,1,0}, {1,0,0,1}, {0,1,1,1} },
+ { {0,0,0,0}, {0,0,0,1}, {0,0,1,1}, {0,1,0,1}, {0,1,0,1}, {1,0,1,2} },
+ { {0,0,0,0}, {0,0,1,1}, {0,1,0,1}, {0,0,0,2}, {0,1,0,2}, {1,0,1,2} },
+ { {0,1,0,1}, {1,0,0,1}, {0,1,1,2}, {0,1,0,2}, {0,0,1,3}, {1,0,1,4} },
+ { {0,0,1,1}, {0,1,0,2}, {1,0,0,3}, {0,1,1,3}, {1,0,0,4}, {1,1,1,4} },
+ { {0,0,1,2}, {0,1,1,2}, {1,1,0,3}, {0,1,0,4}, {1,0,0,4}, {1,0,1,5} },
+ { {0,0,1,2}, {0,1,0,3}, {1,1,0,3}, {1,0,2,4}, {0,2,1,5}, {2,1,0,5} },
+ { {0,2,1,3}, {1,0,0,3}, {2,1,0,4}, {0,1,1,4}, {0,1,0,5}, {1,0,2,6} },
+ { {1,1,0,4}, {1,0,1,4}, {2,0,0,5}, {0,2,1,5}, {0,1,2,6}, {0,2,0,7} },
+ { {1,0,1,5}, {0,2,0,6}, {1,2,0,6}, {1,1,1,6}, {2,0,2,6}, {1,1,2,7} }
+};
+struct Tables HullTable[11][6] = {
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,0,0,0}, {0,1,0,0} },
+ { {0,0,0,0}, {0,0,0,0}, {0,1,0,0}, {1,1,0,0}, {1,0,1,0}, {1,0,1,1} },
+ { {0,1,0,0}, {1,0,0,0}, {1,1,0,0}, {1,0,1,0}, {1,0,1,1}, {2,1,0,0} },
+ { {0,1,1,0}, {1,0,0,0}, {1,1,1,0}, {2,0,0,1}, {2,0,1,0}, {2,2,0,0} },
+ { {0,1,1,0}, {1,0,0,1}, {2,1,0,1}, {2,2,1,0}, {3,0,1,0}, {3,1,0,0} },
+ { {1,1,1,0}, {2,0,2,1}, {2,1,1,0}, {2,2,0,0}, {3,1,0,1}, {3,1,1,0} },
+ { {1,2,2,0}, {2,0,2,1}, {2,1,0,1}, {2,2,0,0}, {3,1,1,0}, {4,2,1,0} },
+ { {2,1,1,0}, {2,0,1,1}, {3,2,2,0}, {3,2,0,0}, {4,2,1,0}, {4,2,1,1} },
+ { {2,1,2,0}, {3,1,1,1}, {3,2,2,0}, {4,2,1,0}, {4,1,0,2}, {4,2,2,0} },
+ { {2,3,1,0}, {3,2,2,0}, {3,2,2,1}, {4,2,2,0}, {4,1,0,3}, {5,1,2,0} },
+ { {2,2,4,0}, {3,3,1,1}, {4,2,1,1}, {5,1,0,2}, {5,1,2,1}, {6,2,2,0} },
+};
+
+char AMMO[9][4] = {
+ { -1, 1, 0, 1 },
+ { -1, 1, 0, 1 },
+ { -1, 1, 0, 1 },
+ { -2, 1, 0, 2 },
+ { -2, 2, 0, 2 },
+ { -2, 2, 0, 2 },
+ { -3, 2, 0, 2 },
+ { -3, 2, 0, 3 },
+ { -3, 2, 0, 3 }
+};
+
+char HDT[9][10] = {
+ { 1, 0,-1,-2,-3,-3,-4,-4,-4,-4 },
+ { 1, 1, 0,-1,-2,-2,-3,-3,-3,-3 },
+ { 2, 1, 0,-1,-2,-2,-3,-3,-3,-3 },
+ { 2, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 3, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 3, 3, 2, 1, 0, 0,-1,-1,-1,-1 },
+ { 4, 3, 2, 1, 0, 0,-1,-1,-1,-1 },
+ { 4, 4, 3, 2, 1, 1, 0, 0, 0, 0 },
+ { 5, 4, 3, 2, 1, 1, 0, 0, 0, 0 }
+};
+
+char HDTrake[9][10] = {
+ { 2, 1, 0,-1,-2,-2,-3,-3,-3,-3 },
+ { 2, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 3, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 4, 3, 2, 1, 0, 0,-1,-1,-1,-1 },
+ { 5, 4, 3, 2, 1, 1, 0, 0, 0, 0 },
+ { 6, 5, 4, 3, 2, 2, 1, 1, 1, 1 },
+ { 7, 6, 5, 4, 3, 3, 2, 2, 2, 2 },
+ { 8, 7, 6, 5, 4, 4, 3, 3, 3, 3 },
+ { 9, 8, 7, 6, 5, 5, 4, 4, 4, 4 }
+};
+
+char QUAL[9][5] = {
+ { -1, 0, 0, 1, 1 },
+ { -1, 0, 0, 1, 1 },
+ { -1, 0, 0, 1, 2 },
+ { -1, 0, 0, 1, 2 },
+ { -1, 0, 0, 2, 2 },
+ { -1,-1, 0, 2, 2 },
+ { -2,-1, 0, 2, 2 },
+ { -2,-1, 0, 2, 2 },
+ { -2,-1, 0, 2, 3 }
+};
+
+char MT[9][3] = {
+ { 1, 0, 0 },
+ { 1, 1, 0 },
+ { 2, 1, 0 },
+ { 2, 1, 1 },
+ { 2, 2, 1 },
+ { 3, 2, 1 },
+ { 3, 2, 2 },
+ { 4, 3, 2 },
+ { 4, 4, 2 }
+};
+
+char rangeofshot[] = {
+ 0,
+ 1, /* grape */
+ 3, /* chain */
+ 10, /* round */
+ 1 /* double */
+};
+
+char *countryname[] = {
+ "American", "British", "Spanish", "French", "Japanese",
+ "Federation", "Klingon", "Orion"
+};
+
+char *classname[] = {
+ "Drift wood",
+ "Ship of the Line",
+ "Ship of the Line",
+ "Frigate",
+ "Corvette",
+ "Sloop",
+ "Brig"
+};
+
+char *directionname[] = {
+ "dead ahead",
+ "off the starboard bow",
+ "off the starboard beam",
+ "off the starboard quarter",
+ "dead astern",
+ "off the port quarter",
+ "off the port beam",
+ "off the port bow",
+ "dead ahead"
+};
+
+char *qualname[] = { "dead", "mutinous", "green", "mundane", "crack", "elite" };
+
+char loadname[] = { '-', 'G', 'C', 'R', 'D', 'E' };
+
+char dr[] = { 0, 1, 1, 0, -1, -1, -1, 0, 1 };
+char dc[] = { 0, 0, -1, -1, -1, 0, 1, 1, 1 };
diff --git a/sail/lo_main.c b/sail/lo_main.c
new file mode 100644
index 00000000..1903258f
--- /dev/null
+++ b/sail/lo_main.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lo_main.c 5.7 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * Print out the top ten SAILors
+ *
+ * -l force a long listing (print out real usernames)
+ */
+#include <sys/types.h>
+#include <pwd.h>
+#include "externs.h"
+#include "pathnames.h"
+
+char *title[] = {
+ "Admiral", "Commodore", "Captain", "Captain",
+ "Captain", "Captain", "Captain", "Commander",
+ "Commander", "Lieutenant"
+};
+
+lo_main()
+{
+ FILE *fp;
+ char sbuf[32];
+ int n = 0, people;
+ struct passwd *pass;
+ struct logs log;
+ struct ship *ship;
+
+ if ((fp = fopen(_PATH_LOGFILE, "r")) == 0) {
+ perror(_PATH_LOGFILE);
+ exit(1);
+ }
+ switch (fread((char *)&people, sizeof people, 1, fp)) {
+ case 0:
+ printf("Nobody has sailed yet.\n");
+ exit(0);
+ case 1:
+ break;
+ default:
+ perror(_PATH_LOGFILE);
+ exit(1);
+ }
+ while (fread((char *)&log, sizeof log, 1, fp) == 1 &&
+ log.l_name[0] != '\0') {
+ if (longfmt && (pass = getpwuid(log.l_uid)) != NULL)
+ (void) sprintf(sbuf, "%10.10s (%s)",
+ log.l_name, pass->pw_name);
+ else
+ (void) sprintf(sbuf, "%20.20s", log.l_name);
+ ship = &scene[log.l_gamenum].ship[log.l_shipnum];
+ printf("%-10s %21s of the %15s %3d points, %5.2f equiv\n",
+ title[n++], sbuf, ship->shipname, log.l_netpoints,
+ (float) log.l_netpoints / ship->specs->pts);
+ }
+ printf("\n%d people have played.\n", people);
+ return 0;
+}
diff --git a/sail/machdep.h b/sail/machdep.h
new file mode 100644
index 00000000..223333d6
--- /dev/null
+++ b/sail/machdep.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)machdep.h 5.5 (Berkeley) 6/1/90
+ */
+
+#define TIMEOUT 300 /* Sync() timeout in seconds */
+
+/* for 4.2bsd machines */
+#define blockalarm() ((void) sigblock(1 << SIGALRM-1))
+#define unblockalarm() ((void) sigsetmask(sigblock(0) & ~(1 << SIGALRM-1)))
+
+/* for 2.9bsd machines (onyx)
+typedef int void;
+#define blockalarm() ((void) sighold(SIGALRM))
+#define unblockalarm() ((void) sigrelse(SIGALRM))
+*/
diff --git a/sail/main.c b/sail/main.c
new file mode 100644
index 00000000..35b5e388
--- /dev/null
+++ b/sail/main.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+/*ARGSUSED*/
+main(argc, argv)
+ int argc;
+ register char **argv;
+{
+ register char *p;
+ int i;
+
+ (void) srand(getpid());
+ issetuid = getuid() != geteuid();
+ if (p = rindex(*argv, '/'))
+ p++;
+ else
+ p = *argv;
+ if (strcmp(p, "driver") == 0 || strcmp(p, "saildriver") == 0)
+ mode = MODE_DRIVER;
+ else if (strcmp(p, "sail.log") == 0)
+ mode = MODE_LOGGER;
+ else
+ mode = MODE_PLAYER;
+ while ((p = *++argv) && *p == '-')
+ switch (p[1]) {
+ case 'd':
+ mode = MODE_DRIVER;
+ break;
+ case 's':
+ mode = MODE_LOGGER;
+ break;
+ case 'D':
+ debug++;
+ break;
+ case 'x':
+ randomize;
+ break;
+ case 'l':
+ longfmt++;
+ break;
+ case 'b':
+ nobells++;
+ break;
+ default:
+ fprintf(stderr, "SAIL: Unknown flag %s.\n", p);
+ exit(1);
+ }
+ if (*argv)
+ game = atoi(*argv);
+ else
+ game = -1;
+ if (i = setjmp(restart))
+ mode = i;
+ switch (mode) {
+ case MODE_PLAYER:
+ return pl_main();
+ case MODE_DRIVER:
+ return dr_main();
+ case MODE_LOGGER:
+ return lo_main();
+ default:
+ fprintf(stderr, "SAIL: Unknown mode %d.\n", mode);
+ abort();
+ }
+ /*NOTREACHED*/
+}
diff --git a/sail/misc.c b/sail/misc.c
new file mode 100644
index 00000000..15018ed7
--- /dev/null
+++ b/sail/misc.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)misc.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+#include "pathnames.h"
+
+#define distance(x,y) (abs(x) >= abs(y) ? abs(x) + abs(y)/2 : abs(y) + abs(x)/2)
+
+/* XXX */
+range(from, to)
+struct ship *from, *to;
+{
+ register bow1r, bow1c, bow2r, bow2c;
+ int stern1r, stern1c, stern2c, stern2r;
+ register int bb, bs, sb, ss, result;
+
+ if (!to->file->dir)
+ return -1;
+ stern1r = bow1r = from->file->row;
+ stern1c = bow1c = from->file->col;
+ stern2r = bow2r = to->file->row;
+ stern2c = bow2c = to->file->col;
+ result = bb = distance(bow2r - bow1r, bow2c - bow1c);
+ if (bb < 5) {
+ stern2r += dr[to->file->dir];
+ stern2c += dc[to->file->dir];
+ stern1r += dr[from->file->dir];
+ stern1c += dc[from->file->dir];
+ bs = distance((bow2r - stern1r), (bow2c - stern1c));
+ sb = distance((bow1r - stern2r), (bow1c - stern2c));
+ ss = distance((stern2r - stern1r) ,(stern2c - stern1c));
+ result = min(bb, min(bs, min(sb, ss)));
+ }
+ return result;
+}
+
+struct ship *
+closestenemy(from, side, anyship)
+register struct ship *from;
+char side, anyship;
+{
+ register struct ship *sp;
+ register char a;
+ int olddist = 30000, dist;
+ struct ship *closest = 0;
+
+ a = capship(from)->nationality;
+ foreachship(sp) {
+ if (sp == from)
+ continue;
+ if (sp->file->dir == 0)
+ continue;
+ if (a == capship(sp)->nationality && !anyship)
+ continue;
+ if (side && gunsbear(from, sp) != side)
+ continue;
+ dist = range(from, sp);
+ if (dist < olddist) {
+ closest = sp;
+ olddist = dist;
+ }
+ }
+ return closest;
+}
+
+angle(dr, dc)
+register dr, dc;
+{
+ register i;
+
+ if (dc >= 0 && dr > 0)
+ i = 0;
+ else if (dr <= 0 && dc > 0)
+ i = 2;
+ else if (dc <= 0 && dr < 0)
+ i = 4;
+ else
+ i = 6;
+ dr = abs(dr);
+ dc = abs(dc);
+ if ((i == 0 || i == 4) && dc * 2.4 > dr) {
+ i++;
+ if (dc > dr * 2.4)
+ i++;
+ } else if ((i == 2 || i == 6) && dr * 2.4 > dc) {
+ i++;
+ if (dr > dc * 2.4)
+ i++;
+ }
+ return i % 8 + 1;
+}
+
+gunsbear(from, to) /* checks for target bow or stern */
+register struct ship *from, *to;
+{
+ int Dr, Dc, i;
+ register ang;
+
+ Dr = from->file->row - to->file->row;
+ Dc = to->file->col - from->file->col;
+ for (i = 2; i; i--) {
+ if ((ang = angle(Dr, Dc) - from->file->dir + 1) < 1)
+ ang += 8;
+ if (ang >= 2 && ang <= 4)
+ return 'r';
+ if (ang >= 6 && ang <= 7)
+ return 'l';
+ Dr += dr[to->file->dir];
+ Dc += dc[to->file->dir];
+ }
+ return 0;
+}
+
+portside(from, on, quick)
+register struct ship *from, *on;
+int quick; /* returns true if fromship is */
+{ /* shooting at onship's starboard side */
+ register ang;
+ register Dr, Dc;
+
+ Dr = from->file->row - on->file->row;
+ Dc = on->file->col - from->file->col;
+ if (quick == -1) {
+ Dr += dr[on->file->dir];
+ Dc += dc[on->file->dir];
+ }
+ ang = angle(Dr, Dc);
+ if (quick != 0)
+ return ang;
+ ang = (ang + 4 - on->file->dir - 1) % 8 + 1;
+ return ang < 5;
+}
+
+colours(sp)
+register struct ship *sp;
+{
+ register char flag;
+
+ if (sp->file->struck)
+ flag = '!';
+ if (sp->file->explode)
+ flag = '#';
+ if (sp->file->sink)
+ flag = '~';
+ if (sp->file->struck)
+ return flag;
+ flag = *countryname[capship(sp)->nationality];
+ return sp->file->FS ? flag : tolower(flag);
+}
+
+#include <sys/file.h>
+log(s)
+register struct ship *s;
+{
+ FILE *fp;
+ int persons;
+ int n;
+ struct logs log[NLOG];
+ float net;
+ register struct logs *lp;
+
+ if ((fp = fopen(_PATH_LOGFILE, "r+")) == NULL)
+ return;
+#ifdef LOCK_EX
+ if (flock(fileno(fp), LOCK_EX) < 0)
+ return;
+#endif
+ net = (float)s->file->points / s->specs->pts;
+ persons = getw(fp);
+ n = fread((char *)log, sizeof(struct logs), NLOG, fp);
+ for (lp = &log[n]; lp < &log[NLOG]; lp++)
+ lp->l_name[0] = lp->l_uid = lp->l_shipnum
+ = lp->l_gamenum = lp->l_netpoints = 0;
+ rewind(fp);
+ if (persons < 0)
+ (void) putw(1, fp);
+ else
+ (void) putw(persons + 1, fp);
+ for (lp = log; lp < &log[NLOG]; lp++)
+ if (net > (float)lp->l_netpoints
+ / scene[lp->l_gamenum].ship[lp->l_shipnum].specs->pts) {
+ (void) fwrite((char *)log,
+ sizeof (struct logs), lp - log, fp);
+ (void) strcpy(log[NLOG-1].l_name, s->file->captain);
+ log[NLOG-1].l_uid = getuid();
+ log[NLOG-1].l_shipnum = s->file->index;
+ log[NLOG-1].l_gamenum = game;
+ log[NLOG-1].l_netpoints = s->file->points;
+ (void) fwrite((char *)&log[NLOG-1],
+ sizeof (struct logs), 1, fp);
+ (void) fwrite((char *)lp,
+ sizeof (struct logs), &log[NLOG-1] - lp, fp);
+ break;
+ }
+#ifdef LOCK_EX
+ (void) flock(fileno(fp), LOCK_UN);
+#endif
+ (void) fclose(fp);
+}
diff --git a/sail/parties.c b/sail/parties.c
new file mode 100644
index 00000000..682512d5
--- /dev/null
+++ b/sail/parties.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)parties.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+
+meleeing(from, to)
+struct ship *from;
+register struct ship *to;
+{
+ register struct BP *p = from->file->OBP;
+ register struct BP *q = p + NBP;
+
+ for (; p < q; p++)
+ if (p->turnsent && p->toship == to)
+ return 1;
+ return 0;
+}
+
+boarding(from, isdefense)
+register struct ship *from;
+char isdefense;
+{
+ register struct BP *p = isdefense ? from->file->DBP : from->file->OBP;
+ register struct BP *q = p + NBP;
+
+ for (; p < q; p++)
+ if (p->turnsent)
+ return 1;
+ return 0;
+}
+
+unboard(ship, to, isdefense)
+register struct ship *ship, *to;
+register char isdefense;
+{
+ register struct BP *p = isdefense ? ship->file->DBP : ship->file->OBP;
+ register n;
+
+ for (n = 0; n < NBP; p++, n++)
+ if (p->turnsent && (p->toship == to || isdefense || ship == to))
+ Write(isdefense ? W_DBP : W_OBP, ship, 0, n, 0, 0, 0);
+}
diff --git a/sail/pathnames.h b/sail/pathnames.h
new file mode 100644
index 00000000..5410f8eb
--- /dev/null
+++ b/sail/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 6/1/90
+ */
+
+#define _PATH_LOGFILE "/var/games/saillog"
diff --git a/sail/pl_1.c b/sail/pl_1.c
new file mode 100644
index 00000000..f4a4e228
--- /dev/null
+++ b/sail/pl_1.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_1.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include "player.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/*
+ * If we get here before a ship is chosen, then ms == 0 and
+ * we don't want to update the score file, or do any Write's either.
+ * We can assume the sync file is already created and may need
+ * to be removed.
+ * Of course, we don't do any more Sync()'s if we got here
+ * because of a Sync() failure.
+ */
+leave(conditions)
+int conditions;
+{
+ (void) signal(SIGHUP, SIG_IGN);
+ (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGQUIT, SIG_IGN);
+ (void) signal(SIGALRM, SIG_IGN);
+ (void) signal(SIGCHLD, SIG_IGN);
+
+ if (done_curses) {
+ Signal("It looks like you've had it!",
+ (struct ship *)0);
+ switch (conditions) {
+ case LEAVE_QUIT:
+ break;
+ case LEAVE_CAPTURED:
+ Signal("Your ship was captured.",
+ (struct ship *)0);
+ break;
+ case LEAVE_HURRICAN:
+ Signal("Hurricane! All ships destroyed.",
+ (struct ship *)0);
+ break;
+ case LEAVE_DRIVER:
+ Signal("The driver died.", (struct ship *)0);
+ break;
+ case LEAVE_SYNC:
+ Signal("Synchronization error.", (struct ship *)0);
+ break;
+ default:
+ Signal("A funny thing happened (%d).",
+ (struct ship *)0, conditions);
+ }
+ } else {
+ switch (conditions) {
+ case LEAVE_QUIT:
+ break;
+ case LEAVE_DRIVER:
+ printf("The driver died.\n");
+ break;
+ case LEAVE_FORK:
+ perror("fork");
+ break;
+ case LEAVE_SYNC:
+ printf("Synchronization error\n.");
+ break;
+ default:
+ printf("A funny thing happened (%d).\n",
+ conditions);
+ }
+ }
+
+ if (ms != 0) {
+ log(ms);
+ if (conditions != LEAVE_SYNC) {
+ makesignal(ms, "Captain %s relinquishing.",
+ (struct ship *)0, mf->captain);
+ Write(W_END, ms, 0, 0, 0, 0, 0);
+ (void) Sync();
+ }
+ }
+ sync_close(!hasdriver);
+ cleanupscreen();
+ exit(0);
+}
+
+void
+choke()
+{
+ leave(LEAVE_QUIT);
+}
+
+void
+child()
+{
+ union wait status;
+ int pid;
+
+ (void) signal(SIGCHLD, SIG_IGN);
+ do {
+ pid = wait3((int *)&status, WNOHANG, (struct rusage *)0);
+ if (pid < 0 || pid > 0 && !WIFSTOPPED(status))
+ hasdriver = 0;
+ } while (pid > 0);
+ (void) signal(SIGCHLD, child);
+}
diff --git a/sail/pl_2.c b/sail/pl_2.c
new file mode 100644
index 00000000..1ce1c7c7
--- /dev/null
+++ b/sail/pl_2.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_2.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "player.h"
+
+play()
+{
+ register struct ship *sp;
+
+ for (;;) {
+ switch (sgetch("~\b", (struct ship *)0, 0)) {
+ case 'm':
+ acceptmove();
+ break;
+ case 's':
+ acceptsignal();
+ break;
+ case 'g':
+ grapungrap();
+ break;
+ case 'u':
+ unfoulplayer();
+ break;
+ case 'v':
+ Signal("%s", (struct ship *)0, version);
+ break;
+ case 'b':
+ acceptboard();
+ break;
+ case 'f':
+ acceptcombat();
+ break;
+ case 'l':
+ loadplayer();
+ break;
+ case 'c':
+ changesail();
+ break;
+ case 'r':
+ repair();
+ break;
+ case 'B':
+ Signal("'Hands to stations!'", (struct ship *)0);
+ unboard(ms, ms, 1); /* cancel DBP's */
+ unboard(ms, ms, 0); /* cancel offense */
+ break;
+ case '\f':
+ centerview();
+ blockalarm();
+ draw_board();
+ draw_screen();
+ unblockalarm();
+ break;
+ case 'L':
+ mf->loadL = L_EMPTY;
+ mf->loadR = L_EMPTY;
+ mf->readyL = R_EMPTY;
+ mf->readyR = R_EMPTY;
+ Signal("Broadsides unloaded", (struct ship *)0);
+ break;
+ case 'q':
+ Signal("Type 'Q' to quit", (struct ship *)0);
+ break;
+ case 'Q':
+ leave(LEAVE_QUIT);
+ break;
+ case 'I':
+ foreachship(sp)
+ if (sp != ms)
+ eyeball(sp);
+ break;
+ case 'i':
+ if ((sp = closestenemy(ms, 0, 1)) == 0)
+ Signal("No more ships left.");
+ else
+ eyeball(sp);
+ break;
+ case 'C':
+ centerview();
+ blockalarm();
+ draw_view();
+ unblockalarm();
+ break;
+ case 'U':
+ upview();
+ blockalarm();
+ draw_view();
+ unblockalarm();
+ break;
+ case 'D':
+ case 'N':
+ downview();
+ blockalarm();
+ draw_view();
+ unblockalarm();
+ break;
+ case 'H':
+ leftview();
+ blockalarm();
+ draw_view();
+ unblockalarm();
+ break;
+ case 'J':
+ rightview();
+ blockalarm();
+ draw_view();
+ unblockalarm();
+ break;
+ case 'F':
+ lookout();
+ break;
+ case 'S':
+ dont_adjust = !dont_adjust;
+ blockalarm();
+ draw_turn();
+ unblockalarm();
+ break;
+ }
+ }
+}
diff --git a/sail/pl_3.c b/sail/pl_3.c
new file mode 100644
index 00000000..38b7ae17
--- /dev/null
+++ b/sail/pl_3.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_3.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "player.h"
+
+acceptcombat()
+{
+ int men = 0;
+ int target, temp;
+ int n, r;
+ int index, rakehim, sternrake;
+ int hhits = 0, ghits = 0, rhits = 0, chits = 0;
+ int crew[3];
+ int load;
+ int guns, car, ready, shootat, hit;
+ int roll;
+ struct ship *closest;
+
+ crew[0] = mc->crew1;
+ crew[1] = mc->crew2;
+ crew[2] = mc->crew3;
+ for (n = 0; n < 3; n++) {
+ if (mf->OBP[n].turnsent)
+ men += mf->OBP[n].mensent;
+ }
+ for (n = 0; n < 3; n++) {
+ if (mf->DBP[n].turnsent)
+ men += mf->DBP[n].mensent;
+ }
+ if (men) {
+ crew[0] = men/100 ? 0 : crew[0] != 0;
+ crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
+ crew[2] = men%10 ? 0 : crew[2] != 0;
+ }
+ for (r = 0; r < 2; r++) {
+ if (r) {
+ ready = mf->readyR;
+ load = mf->loadR;
+ guns = mc->gunR;
+ car = mc->carR;
+ } else {
+ ready = mf->readyL;
+ load = mf->loadL;
+ guns = mc->gunL;
+ car = mc->carL;
+ }
+ if (!guns && !car || load == L_EMPTY || (ready & R_LOADED) == 0)
+ goto cant;
+ if (mf->struck || !crew[2])
+ goto cant;
+ closest = closestenemy(ms, (r ? 'r' : 'l'), 1);
+ if (closest == 0)
+ goto cant;
+ if (closest->file->struck)
+ goto cant;
+ target = range(ms, closest);
+ if (target > rangeofshot[load] || !guns && target >= 3)
+ goto cant;
+ Signal("%s (%c%c) within range of %s broadside.",
+ closest, r ? "right" : "left");
+ if (load > L_CHAIN && target < 6) {
+ switch (sgetch("Aim for hull or rigging? ",
+ (struct ship *)0, 1)) {
+ case 'r':
+ shootat = RIGGING;
+ break;
+ case 'h':
+ shootat = HULL;
+ break;
+ default:
+ shootat = -1;
+ Signal("'Avast there! Hold your fire.'",
+ (struct ship *)0);
+ }
+ } else {
+ if (sgetch("Fire? ", (struct ship *)0, 1) == 'n') {
+ shootat = -1;
+ Signal("Belay that! Hold your fire.",
+ (struct ship *)0);
+ } else
+ shootat = RIGGING;
+ }
+ if (shootat == -1)
+ continue;
+ fired = 1;
+ rakehim = gunsbear(ms, closest) && !gunsbear(closest, ms);
+ temp = portside(closest, ms, 1) - closest->file->dir + 1;
+ if (temp < 1)
+ temp += 8;
+ else if (temp > 8)
+ temp -= 8;
+ sternrake = temp > 4 && temp < 6;
+ if (rakehim)
+ if (!sternrake)
+ Signal("Raking the %s!", closest);
+ else
+ Signal("Stern Rake! %s splintering!", closest);
+ index = guns;
+ if (target < 3)
+ index += car;
+ index = (index - 1)/3;
+ index = index > 8 ? 8 : index;
+ if (!rakehim)
+ hit = HDT[index][target-1];
+ else
+ hit = HDTrake[index][target-1];
+ if (rakehim && sternrake)
+ hit++;
+ hit += QUAL[index][mc->qual-1];
+ for (n = 0; n < 3 && mf->captured == 0; n++)
+ if (!crew[n])
+ if (index <= 5)
+ hit--;
+ else
+ hit -= 2;
+ if (ready & R_INITIAL)
+ if (index <= 3)
+ hit++;
+ else
+ hit += 2;
+ if (mf->captured != 0)
+ if (index <= 1)
+ hit--;
+ else
+ hit -= 2;
+ hit += AMMO[index][load - 1];
+ if (((temp = mc->class) >= 5 || temp == 1) && windspeed == 5)
+ hit--;
+ if (windspeed == 6 && temp == 4)
+ hit -= 2;
+ if (windspeed == 6 && temp <= 3)
+ hit--;
+ if (hit >= 0) {
+ roll = die();
+ if (load == L_GRAPE)
+ chits = hit;
+ else {
+ struct Tables *t;
+ if (hit > 10)
+ hit = 10;
+ t = &(shootat == RIGGING ? RigTable : HullTable)
+ [hit][roll-1];
+ chits = t->C;
+ rhits = t->R;
+ hhits = t->H;
+ ghits = t->G;
+ if (closest->file->FS)
+ rhits *= 2;
+ if (load == L_CHAIN) {
+ ghits = 0;
+ hhits = 0;
+ }
+ }
+ table(shootat, load, hit, closest, ms, roll);
+ }
+ Signal("Damage inflicted on the %s:",
+ (struct ship *)0, closest->shipname);
+ Signal("\t%d HULL, %d GUNS, %d CREW, %d RIGGING",
+ (struct ship *)0, hhits, ghits, chits, rhits);
+ if (!r) {
+ mf->loadL = L_EMPTY;
+ mf->readyL = R_EMPTY;
+ } else {
+ mf->loadR = L_EMPTY;
+ mf->readyR = R_EMPTY;
+ }
+ continue;
+ cant:
+ Signal("Unable to fire %s broadside",
+ (struct ship *)0, r ? "right" : "left");
+ }
+ blockalarm();
+ draw_stat();
+ unblockalarm();
+}
+
+grapungrap()
+{
+ register struct ship *sp;
+ register int i;
+
+ foreachship(sp) {
+ if (sp == ms || sp->file->dir == 0)
+ continue;
+ if (range(ms, sp) > 1 && !grappled2(ms, sp))
+ continue;
+ switch (sgetch("Attempt to grapple or ungrapple %s (%c%c): ",
+ sp, 1)) {
+ case 'g':
+ if (die() < 3
+ || ms->nationality == capship(sp)->nationality) {
+ Write(W_GRAP, ms, 0, sp->file->index, 0, 0, 0);
+ Write(W_GRAP, sp, 0, player, 0, 0, 0);
+ Signal("Attempt succeeds!", (struct ship *)0);
+ makesignal(ms, "grappled with %s (%c%c)", sp);
+ } else
+ Signal("Attempt fails.", (struct ship *)0);
+ break;
+ case 'u':
+ for (i = grappled2(ms, sp); --i >= 0;) {
+ if (ms->nationality
+ == capship(sp)->nationality
+ || die() < 3) {
+ cleangrapple(ms, sp, 0);
+ Signal("Attempt succeeds!",
+ (struct ship *)0);
+ makesignal(ms,
+ "ungrappling with %s (%c%c)",
+ sp);
+ } else
+ Signal("Attempt fails.",
+ (struct ship *)0);
+ }
+ break;
+ }
+ }
+}
+
+unfoulplayer()
+{
+ register struct ship *to;
+ register i;
+
+ foreachship(to) {
+ if (fouled2(ms, to) == 0)
+ continue;
+ if (sgetch("Attempt to unfoul with the %s (%c%c)? ", to, 1) != 'y')
+ continue;
+ for (i = fouled2(ms, to); --i >= 0;) {
+ if (die() <= 2) {
+ cleanfoul(ms, to, 0);
+ Signal("Attempt succeeds!", (struct ship *)0);
+ makesignal(ms, "Unfouling %s (%c%c)", to);
+ } else
+ Signal("Attempt fails.", (struct ship *)0);
+ }
+ }
+}
diff --git a/sail/pl_4.c b/sail/pl_4.c
new file mode 100644
index 00000000..be57fcb4
--- /dev/null
+++ b/sail/pl_4.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_4.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "player.h"
+
+changesail()
+{
+ int rig, full;
+
+ rig = mc->rig1;
+ full = mf->FS;
+ if (windspeed == 6 || windspeed == 5 && mc->class > 4)
+ rig = 0;
+ if (mc->crew3 && rig) {
+ if (!full) {
+ if (sgetch("Increase to Full sails? ",
+ (struct ship *)0, 1) == 'y') {
+ changed = 1;
+ Write(W_FS, ms, 0, 1, 0, 0, 0);
+ }
+ } else {
+ if (sgetch("Reduce to Battle sails? ",
+ (struct ship *)0, 1) == 'y') {
+ Write(W_FS, ms, 0, 0, 0, 0, 0);
+ changed = 1;
+ }
+ }
+ } else if (!rig)
+ Signal("Sails rent to pieces", (struct ship *)0);
+}
+
+acceptsignal()
+{
+ char buf[60];
+ register char *p = buf;
+
+ *p++ = '"';
+ sgetstr("Message? ", p, sizeof buf - 2);
+ while (*p++)
+ ;
+ p[-1] = '"';
+ *p = 0;
+ Write(W_SIGNAL, ms, 1, (int)buf, 0, 0, 0);
+}
+
+lookout()
+{
+ register struct ship *sp;
+ char buf[3];
+ register char c;
+
+ sgetstr("What ship? ", buf, sizeof buf);
+ foreachship(sp) {
+ c = *countryname[sp->nationality];
+ if ((c == *buf || tolower(c) == *buf || colours(sp) == *buf)
+ && (sp->file->stern == buf[1] || sterncolour(sp) == buf[1]
+ || buf[1] == '?')) {
+ eyeball(sp);
+ }
+ }
+}
+
+char *
+saywhat(sp, flag)
+register struct ship *sp;
+char flag;
+{
+ if (sp->file->captain[0])
+ return sp->file->captain;
+ else if (sp->file->struck)
+ return "(struck)";
+ else if (sp->file->captured != 0)
+ return "(captured)";
+ else if (flag)
+ return "(available)";
+ else
+ return "(computer)";
+}
+
+eyeball(ship)
+register struct ship *ship;
+{
+ int i;
+
+ if (ship->file->dir != 0) {
+ Signal("Sail ho! (range %d, %s)",
+ (struct ship *)0, range(ms, ship), saywhat(ship, 0));
+ i = portside(ms, ship, 1) - mf->dir;
+ if (i <= 0)
+ i += 8;
+ Signal("%s (%c%c) %s %s %s.",
+ ship, countryname[ship->nationality],
+ classname[ship->specs->class], directionname[i]);
+ }
+}
diff --git a/sail/pl_5.c b/sail/pl_5.c
new file mode 100644
index 00000000..b869b3cb
--- /dev/null
+++ b/sail/pl_5.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_5.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "player.h"
+
+#define turnfirst(x) (*x == 'r' || *x == 'l')
+
+acceptmove()
+{
+ int ta;
+ int ma;
+ char af;
+ int moved = 0;
+ int vma, dir;
+ char prompt[60];
+ char buf[60], last = '\0';
+ register char *p;
+
+ if (!mc->crew3 || snagged(ms) || !windspeed) {
+ Signal("Unable to move", (struct ship *)0);
+ return;
+ }
+
+ ta = maxturns(ms, &af);
+ ma = maxmove(ms, mf->dir, 0);
+ (void) sprintf(prompt, "move (%d,%c%d): ", ma, af ? '\'' : ' ', ta);
+ sgetstr(prompt, buf, sizeof buf);
+ dir = mf->dir;
+ vma = ma;
+ for (p = buf; *p; p++)
+ switch (*p) {
+ case 'l':
+ dir -= 2;
+ case 'r':
+ if (++dir == 0)
+ dir = 8;
+ else if (dir == 9)
+ dir = 1;
+ if (last == 't') {
+ Signal("Ship can't turn that fast.",
+ (struct ship *)0);
+ *p-- = '\0';
+ }
+ last = 't';
+ ma--;
+ ta--;
+ vma = min(ma, maxmove(ms, dir, 0));
+ if (ta < 0 && moved || vma < 0 && moved)
+ *p-- = '\0';
+ break;
+ case 'b':
+ ma--;
+ vma--;
+ last = 'b';
+ if (ta < 0 && moved || vma < 0 && moved)
+ *p-- = '\0';
+ break;
+ case '0':
+ case 'd':
+ *p-- = '\0';
+ break;
+ case '\n':
+ *p-- = '\0';
+ break;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ if (last == '0') {
+ Signal("Can't move that fast.",
+ (struct ship *)0);
+ *p-- = '\0';
+ }
+ last = '0';
+ moved = 1;
+ ma -= *p - '0';
+ vma -= *p - '0';
+ if (ta < 0 && moved || vma < 0 && moved)
+ *p-- = '\0';
+ break;
+ default:
+ if (!isspace(*p)) {
+ Signal("Input error.", (struct ship *)0);
+ *p-- = '\0';
+ }
+ }
+ if (ta < 0 && moved || vma < 0 && moved
+ || af && turnfirst(buf) && moved) {
+ Signal("Movement error.", (struct ship *)0);
+ if (ta < 0 && moved) {
+ if (mf->FS == 1) {
+ Write(W_FS, ms, 0, 0, 0, 0, 0);
+ Signal("No hands to set full sails.",
+ (struct ship *)0);
+ }
+ } else if (ma >= 0)
+ buf[1] = '\0';
+ }
+ if (af && !moved) {
+ if (mf->FS == 1) {
+ Write(W_FS, ms, 0, 0, 0, 0, 0);
+ Signal("No hands to set full sails.",
+ (struct ship *)0);
+ }
+ }
+ if (*buf)
+ (void) strcpy(movebuf, buf);
+ else
+ (void) strcpy(movebuf, "d");
+ Write(W_MOVE, ms, 1, (int)movebuf, 0, 0, 0);
+ Signal("Helm: %s.", (struct ship *)0, movebuf);
+}
+
+acceptboard()
+{
+ register struct ship *sp;
+ register int n;
+ int crew[3];
+ int men = 0;
+ char c;
+
+ crew[0] = mc->crew1;
+ crew[1] = mc->crew2;
+ crew[2] = mc->crew3;
+ for (n = 0; n < NBP; n++) {
+ if (mf->OBP[n].turnsent)
+ men += mf->OBP[n].mensent;
+ }
+ for (n = 0; n < NBP; n++) {
+ if (mf->DBP[n].turnsent)
+ men += mf->DBP[n].mensent;
+ }
+ if (men) {
+ crew[0] = men/100 ? 0 : crew[0] != 0;
+ crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
+ crew[2] = men%10 ? 0 : crew[2] != 0;
+ } else {
+ crew[0] = crew[0] != 0;
+ crew[1] = crew[1] != 0;
+ crew[2] = crew[2] != 0;
+ }
+ foreachship(sp) {
+ if (sp == ms || sp->file->dir == 0 || range(ms, sp) > 1)
+ continue;
+ if (ms->nationality == capship(sp)->nationality)
+ continue;
+ if (meleeing(ms, sp) && crew[2]) {
+ c = sgetch("How many more to board the %s (%c%c)? ",
+ sp, 1);
+ parties(crew, sp, 0, c);
+ } else if ((fouled2(ms, sp) || grappled2(ms, sp)) && crew[2]) {
+ c = sgetch("Crew sections to board the %s (%c%c) (3 max) ?", sp, 1);
+ parties(crew, sp, 0, c);
+ }
+ }
+ if (crew[2]) {
+ c = sgetch("How many sections to repel boarders? ",
+ (struct ship *)0, 1);
+ parties(crew, ms, 1, c);
+ }
+ blockalarm();
+ draw_slot();
+ unblockalarm();
+}
+
+parties(crew, to, isdefense, buf)
+register struct ship *to;
+int crew[3];
+char isdefense;
+char buf;
+{
+ register int k, j, men;
+ struct BP *ptr;
+ int temp[3];
+
+ for (k = 0; k < 3; k++)
+ temp[k] = crew[k];
+ if (isdigit(buf)) {
+ ptr = isdefense ? to->file->DBP : to->file->OBP;
+ for (j = 0; j < NBP && ptr[j].turnsent; j++)
+ ;
+ if (!ptr[j].turnsent && buf > '0') {
+ men = 0;
+ for (k = 0; k < 3 && buf > '0'; k++) {
+ men += crew[k]
+ * (k == 0 ? 100 : (k == 1 ? 10 : 1));
+ crew[k] = 0;
+ if (men)
+ buf--;
+ }
+ if (buf > '0')
+ Signal("Sending all crew sections.",
+ (struct ship *)0);
+ Write(isdefense ? W_DBP : W_OBP, ms, 0,
+ j, turn, to->file->index, men);
+ if (isdefense) {
+ (void) wmove(slot_w, 2, 0);
+ for (k=0; k < NBP; k++)
+ if (temp[k] && !crew[k])
+ (void) waddch(slot_w, k + '1');
+ else
+ (void) wmove(slot_w, 2, 1 + k);
+ (void) mvwaddstr(slot_w, 3, 0, "DBP");
+ makesignal(ms, "repelling boarders",
+ (struct ship *)0);
+ } else {
+ (void) wmove(slot_w, 0, 0);
+ for (k=0; k < NBP; k++)
+ if (temp[k] && !crew[k])
+ (void) waddch(slot_w, k + '1');
+ else
+ (void) wmove(slot_w, 0, 1 + k);
+ (void) mvwaddstr(slot_w, 1, 0, "OBP");
+ makesignal(ms, "boarding the %s (%c%c)", to);
+ }
+ blockalarm();
+ (void) wrefresh(slot_w);
+ unblockalarm();
+ } else
+ Signal("Sending no crew sections.", (struct ship *)0);
+ }
+}
diff --git a/sail/pl_6.c b/sail/pl_6.c
new file mode 100644
index 00000000..e0520482
--- /dev/null
+++ b/sail/pl_6.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_6.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "player.h"
+
+repair()
+{
+ char c;
+ register char *repairs;
+ register struct shipspecs *ptr = mc;
+ register int count;
+
+#define FIX(x, m) (m - ptr->x > count \
+ ? (ptr->x += count, count = 0) : (count -= m - ptr->x, ptr->x = m))
+
+ if (repaired || loaded || fired || changed || turned()) {
+ Signal("No hands free to repair", (struct ship *)0);
+ return;
+ }
+ c = sgetch("Repair (hull, guns, rigging)? ", (struct ship *)0, 1);
+ switch (c) {
+ case 'h':
+ repairs = &mf->RH;
+ break;
+ case 'g':
+ repairs = &mf->RG;
+ break;
+ case 'r':
+ repairs = &mf->RR;
+ break;
+ default:
+ Signal("Avast heaving!", (struct ship *)0);
+ return;
+ }
+ if (++*repairs >= 3) {
+ count = 2;
+ switch (c) {
+ case 'h': {
+ int max = ptr->guns/4;
+ if (ptr->hull < max) {
+ FIX(hull, max);
+ Write(W_HULL, ms, 0, ptr->hull, 0, 0, 0);
+ }
+ break;
+ }
+ case 'g':
+ if (ptr->gunL < ptr->gunR) {
+ int max = ptr->guns/5 - ptr->carL;
+ if (ptr->gunL < max) {
+ FIX(gunL, max);
+ Write(W_GUNL, ms, 0, ptr->gunL,
+ ptr->carL, 0, 0);
+ }
+ } else {
+ int max = ptr->guns/5 - ptr->carR;
+ if (ptr->gunR < max) {
+ FIX(gunR, max);
+ Write(W_GUNR, ms, 0, ptr->gunR,
+ ptr->carR, 0, 0);
+ }
+ }
+ break;
+ case 'r':
+#define X 2
+ if (ptr->rig4 >= 0 && ptr->rig4 < X) {
+ FIX(rig4, X);
+ Write(W_RIG4, ms, 0, ptr->rig4, 0, 0, 0);
+ }
+ if (count && ptr->rig3 < X) {
+ FIX(rig3, X);
+ Write(W_RIG3, ms, 0, ptr->rig3, 0, 0, 0);
+ }
+ if (count && ptr->rig2 < X) {
+ FIX(rig2, X);
+ Write(W_RIG2, ms, 0, ptr->rig2, 0, 0, 0);
+ }
+ if (count && ptr->rig1 < X) {
+ FIX(rig1, X);
+ Write(W_RIG1, ms, 0, ptr->rig1, 0, 0, 0);
+ }
+ break;
+ }
+ if (count == 2) {
+ Signal("Repairs completed.", (struct ship *)0);
+ *repairs = 2;
+ } else {
+ *repairs = 0;
+ blockalarm();
+ draw_stat();
+ unblockalarm();
+ }
+ }
+ blockalarm();
+ draw_slot();
+ unblockalarm();
+ repaired = 1;
+}
+
+turned()
+{
+ register char *p;
+
+ for (p = movebuf; *p; p++)
+ if (*p == 'r' || *p == 'l')
+ return 1;
+ return 0;
+}
+
+loadplayer()
+{
+ char c;
+ register loadL, loadR, ready, load;
+
+ if (!mc->crew3) {
+ Signal("Out of crew", (struct ship *)0);
+ return;
+ }
+ loadL = mf->loadL;
+ loadR = mf->loadR;
+ if (!loadL && !loadR) {
+ c = sgetch("Load which broadside (left or right)? ",
+ (struct ship *)0, 1);
+ if (c == 'r')
+ loadL = 1;
+ else
+ loadR = 1;
+ }
+ if (!loadL && loadR || loadL && !loadR) {
+ c = sgetch("Reload with (round, double, chain, grape)? ",
+ (struct ship *)0, 1);
+ switch (c) {
+ case 'r':
+ load = L_ROUND;
+ ready = 0;
+ break;
+ case 'd':
+ load = L_DOUBLE;
+ ready = R_DOUBLE;
+ break;
+ case 'c':
+ load = L_CHAIN;
+ ready = 0;
+ break;
+ case 'g':
+ load = L_GRAPE;
+ ready = 0;
+ break;
+ default:
+ Signal("Broadside not loaded.",
+ (struct ship *)0);
+ return;
+ }
+ if (!loadR) {
+ mf->loadR = load;
+ mf->readyR = ready|R_LOADING;
+ } else {
+ mf->loadL = load;
+ mf->readyL = ready|R_LOADING;
+ }
+ loaded = 1;
+ }
+}
diff --git a/sail/pl_7.c b/sail/pl_7.c
new file mode 100644
index 00000000..136db8bf
--- /dev/null
+++ b/sail/pl_7.c
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_7.c 5.7 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include "player.h"
+
+/*
+ * Display interface
+ */
+
+static char sc_hasprompt;
+static char *sc_prompt;
+static char *sc_buf;
+static int sc_line;
+
+initscreen()
+{
+ /* initscr() already done in SCREENTEST() */
+ view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L);
+ slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L);
+ scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L);
+ stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L);
+ turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L);
+ done_curses++;
+ (void) leaveok(view_w, 1);
+ (void) leaveok(slot_w, 1);
+ (void) leaveok(stat_w, 1);
+ (void) leaveok(turn_w, 1);
+#ifdef SIGTSTP
+ {
+ void susp();
+ (void) signal(SIGTSTP, susp);
+ }
+#endif
+ noecho();
+ crmode();
+}
+
+cleanupscreen()
+{
+ /* alarm already turned off */
+ if (done_curses) {
+ (void) wmove(scroll_w, SCROLL_Y - 1, 0);
+ (void) wclrtoeol(scroll_w);
+ draw_screen();
+ endwin();
+ }
+}
+
+void
+newturn()
+{
+ repaired = loaded = fired = changed = 0;
+ movebuf[0] = '\0';
+
+ (void) alarm(0);
+ if (mf->readyL & R_LOADING)
+ if (mf->readyL & R_DOUBLE)
+ mf->readyL = R_LOADING;
+ else
+ mf->readyL = R_LOADED;
+ if (mf->readyR & R_LOADING)
+ if (mf->readyR & R_DOUBLE)
+ mf->readyR = R_LOADING;
+ else
+ mf->readyR = R_LOADED;
+ if (!hasdriver)
+ Write(W_DDEAD, SHIP(0), 0, 0, 0, 0, 0);
+
+ if (sc_hasprompt) {
+ (void) wmove(scroll_w, sc_line, 0);
+ (void) wclrtoeol(scroll_w);
+ }
+ if (Sync() < 0)
+ leave(LEAVE_SYNC);
+ if (!hasdriver)
+ leave(LEAVE_DRIVER);
+ if (sc_hasprompt)
+ (void) wprintw(scroll_w, "%s%s", sc_prompt, sc_buf);
+
+ if (turn % 50 == 0)
+ Write(W_ALIVE, SHIP(0), 0, 0, 0, 0, 0);
+ if (mf->FS && (!mc->rig1 || windspeed == 6))
+ Write(W_FS, ms, 0, 0, 0, 0, 0);
+ if (mf->FS == 1)
+ Write(W_FS, ms, 0, 2, 0, 0, 0);
+
+ if (mf->struck)
+ leave(LEAVE_QUIT);
+ if (mf->captured != 0)
+ leave(LEAVE_CAPTURED);
+ if (windspeed == 7)
+ leave(LEAVE_HURRICAN);
+
+ adjustview();
+ draw_screen();
+
+ (void) signal(SIGALRM, newturn);
+ (void) alarm(7);
+}
+
+/*VARARGS2*/
+Signal(fmt, ship, a, b, c, d)
+char *fmt;
+register struct ship *ship;
+int a, b, c, d;
+{
+ if (!done_curses)
+ return;
+ if (*fmt == '\7')
+ putchar(*fmt++);
+ if (ship == 0)
+ (void) wprintw(scroll_w, fmt, a, b, c, d);
+ else
+ (void) wprintw(scroll_w, fmt, ship->shipname,
+ colours(ship), sterncolour(ship), a, b, c, d);
+ Scroll();
+}
+
+Scroll()
+{
+ if (++sc_line >= SCROLL_Y)
+ sc_line = 0;
+ (void) wmove(scroll_w, sc_line, 0);
+ (void) wclrtoeol(scroll_w);
+}
+
+prompt(p, ship)
+register char *p;
+struct ship *ship;
+{
+ static char buf[60];
+
+ if (ship != 0) {
+ (void)sprintf(buf, p, ship->shipname, colours(ship),
+ sterncolour(ship));
+ p = buf;
+ }
+ sc_prompt = p;
+ sc_buf = "";
+ sc_hasprompt = 1;
+ (void) waddstr(scroll_w, p);
+}
+
+endprompt(flag)
+char flag;
+{
+ sc_hasprompt = 0;
+ if (flag)
+ Scroll();
+}
+
+sgetch(p, ship, flag)
+char *p;
+struct ship *ship;
+char flag;
+{
+ register c;
+
+ prompt(p, ship);
+ blockalarm();
+ (void) wrefresh(scroll_w);
+ unblockalarm();
+ while ((c = wgetch(scroll_w)) == EOF)
+ ;
+ if (flag && c >= ' ' && c < 0x7f)
+ (void) waddch(scroll_w, c);
+ endprompt(flag);
+ return c;
+}
+
+sgetstr(pr, buf, n)
+char *pr;
+register char *buf;
+register n;
+{
+ register c;
+ register char *p = buf;
+
+ prompt(pr, (struct ship *)0);
+ sc_buf = buf;
+ for (;;) {
+ *p = 0;
+ blockalarm();
+ (void) wrefresh(scroll_w);
+ unblockalarm();
+ while ((c = wgetch(scroll_w)) == EOF)
+ ;
+ switch (c) {
+ case '\n':
+ case '\r':
+ endprompt(1);
+ return;
+ case '\b':
+ if (p > buf) {
+ (void) waddstr(scroll_w, "\b \b");
+ p--;
+ }
+ break;
+ default:
+ if (c >= ' ' && c < 0x7f && p < buf + n - 1) {
+ *p++ = c;
+ (void) waddch(scroll_w, c);
+ } else
+ (void) putchar(CTRL('g'));
+ }
+ }
+}
+
+draw_screen()
+{
+ draw_view();
+ draw_turn();
+ draw_stat();
+ draw_slot();
+ (void) wrefresh(scroll_w); /* move the cursor */
+}
+
+draw_view()
+{
+ register struct ship *sp;
+
+ (void) werase(view_w);
+ foreachship(sp) {
+ if (sp->file->dir
+ && sp->file->row > viewrow
+ && sp->file->row < viewrow + VIEW_Y
+ && sp->file->col > viewcol
+ && sp->file->col < viewcol + VIEW_X) {
+ (void) wmove(view_w, sp->file->row - viewrow,
+ sp->file->col - viewcol);
+ (void) waddch(view_w, colours(sp));
+ (void) wmove(view_w,
+ sternrow(sp) - viewrow,
+ sterncol(sp) - viewcol);
+ (void) waddch(view_w, sterncolour(sp));
+ }
+ }
+ (void) wrefresh(view_w);
+}
+
+draw_turn()
+{
+ (void) wmove(turn_w, 0, 0);
+ (void) wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn);
+ (void) wrefresh(turn_w);
+}
+
+draw_stat()
+{
+ (void) wmove(stat_w, STAT_1, 0);
+ (void) wprintw(stat_w, "Points %3d\n", mf->points);
+ (void) wprintw(stat_w, "Fouls %2d\n", fouled(ms));
+ (void) wprintw(stat_w, "Grapples %2d\n", grappled(ms));
+
+ (void) wmove(stat_w, STAT_2, 0);
+ (void) wprintw(stat_w, " 0 %c(%c)\n",
+ maxmove(ms, winddir + 3, -1) + '0',
+ maxmove(ms, winddir + 3, 1) + '0');
+ (void) waddstr(stat_w, " \\|/\n");
+ (void) wprintw(stat_w, " -^-%c(%c)\n",
+ maxmove(ms, winddir + 2, -1) + '0',
+ maxmove(ms, winddir + 2, 1) + '0');
+ (void) waddstr(stat_w, " /|\\\n");
+ (void) wprintw(stat_w, " | %c(%c)\n",
+ maxmove(ms, winddir + 1, -1) + '0',
+ maxmove(ms, winddir + 1, 1) + '0');
+ (void) wprintw(stat_w, " %c(%c)\n",
+ maxmove(ms, winddir, -1) + '0',
+ maxmove(ms, winddir, 1) + '0');
+
+ (void) wmove(stat_w, STAT_3, 0);
+ (void) wprintw(stat_w, "Load %c%c %c%c\n",
+ loadname[mf->loadL], readyname(mf->readyL),
+ loadname[mf->loadR], readyname(mf->readyR));
+ (void) wprintw(stat_w, "Hull %2d\n", mc->hull);
+ (void) wprintw(stat_w, "Crew %2d %2d %2d\n",
+ mc->crew1, mc->crew2, mc->crew3);
+ (void) wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR);
+ (void) wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR);
+ (void) wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3);
+ if (mc->rig4 < 0)
+ (void) waddch(stat_w, '-');
+ else
+ (void) wprintw(stat_w, "%d", mc->rig4);
+ (void) wrefresh(stat_w);
+}
+
+draw_slot()
+{
+ if (!boarding(ms, 0)) {
+ (void) mvwaddstr(slot_w, 0, 0, " ");
+ (void) mvwaddstr(slot_w, 1, 0, " ");
+ } else
+ (void) mvwaddstr(slot_w, 1, 0, "OBP");
+ if (!boarding(ms, 1)) {
+ (void) mvwaddstr(slot_w, 2, 0, " ");
+ (void) mvwaddstr(slot_w, 3, 0, " ");
+ } else
+ (void) mvwaddstr(slot_w, 3, 0, "DBP");
+
+ (void) wmove(slot_w, SLOT_Y-4, 0);
+ if (mf->RH)
+ (void) wprintw(slot_w, "%dRH", mf->RH);
+ else
+ (void) waddstr(slot_w, " ");
+ (void) wmove(slot_w, SLOT_Y-3, 0);
+ if (mf->RG)
+ (void) wprintw(slot_w, "%dRG", mf->RG);
+ else
+ (void) waddstr(slot_w, " ");
+ (void) wmove(slot_w, SLOT_Y-2, 0);
+ if (mf->RR)
+ (void) wprintw(slot_w, "%dRR", mf->RR);
+ else
+ (void) waddstr(slot_w, " ");
+
+#define Y (SLOT_Y/2)
+ (void) wmove(slot_w, 7, 1);
+ (void) wprintw(slot_w,"%d", windspeed);
+ (void) mvwaddch(slot_w, Y, 0, ' ');
+ (void) mvwaddch(slot_w, Y, 2, ' ');
+ (void) mvwaddch(slot_w, Y-1, 0, ' ');
+ (void) mvwaddch(slot_w, Y-1, 1, ' ');
+ (void) mvwaddch(slot_w, Y-1, 2, ' ');
+ (void) mvwaddch(slot_w, Y+1, 0, ' ');
+ (void) mvwaddch(slot_w, Y+1, 1, ' ');
+ (void) mvwaddch(slot_w, Y+1, 2, ' ');
+ (void) wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]);
+ switch (winddir) {
+ case 1:
+ case 5:
+ (void) waddch(slot_w, '|');
+ break;
+ case 2:
+ case 6:
+ (void) waddch(slot_w, '/');
+ break;
+ case 3:
+ case 7:
+ (void) waddch(slot_w, '-');
+ break;
+ case 4:
+ case 8:
+ (void) waddch(slot_w, '\\');
+ break;
+ }
+ (void) mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+');
+ (void) wrefresh(slot_w);
+}
+
+draw_board()
+{
+ register int n;
+
+ (void) clear();
+ (void) werase(view_w);
+ (void) werase(slot_w);
+ (void) werase(scroll_w);
+ (void) werase(stat_w);
+ (void) werase(turn_w);
+
+ sc_line = 0;
+
+ (void) move(BOX_T, BOX_L);
+ for (n = 0; n < BOX_X; n++)
+ (void) addch('-');
+ (void) move(BOX_B, BOX_L);
+ for (n = 0; n < BOX_X; n++)
+ (void) addch('-');
+ for (n = BOX_T+1; n < BOX_B; n++) {
+ (void) mvaddch(n, BOX_L, '|');
+ (void) mvaddch(n, BOX_R, '|');
+ }
+ (void) mvaddch(BOX_T, BOX_L, '+');
+ (void) mvaddch(BOX_T, BOX_R, '+');
+ (void) mvaddch(BOX_B, BOX_L, '+');
+ (void) mvaddch(BOX_B, BOX_R, '+');
+ (void) refresh();
+
+#define WSaIM "Wooden Ships & Iron Men"
+ (void) wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2);
+ (void) waddstr(view_w, WSaIM);
+ (void) wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2);
+ (void) waddstr(view_w, cc->name);
+ (void) wrefresh(view_w);
+
+ (void) move(LINE_T, LINE_L);
+ (void) printw("Class %d %s (%d guns) '%s' (%c%c)",
+ mc->class,
+ classname[mc->class],
+ mc->guns,
+ ms->shipname,
+ colours(ms),
+ sterncolour(ms));
+ (void) refresh();
+}
+
+centerview()
+{
+ viewrow = mf->row - VIEW_Y / 2;
+ viewcol = mf->col - VIEW_X / 2;
+}
+
+upview()
+{
+ viewrow -= VIEW_Y / 3;
+}
+
+downview()
+{
+ viewrow += VIEW_Y / 3;
+}
+
+leftview()
+{
+ viewcol -= VIEW_X / 5;
+}
+
+rightview()
+{
+ viewcol += VIEW_X / 5;
+}
+
+adjustview()
+{
+ if (dont_adjust)
+ return;
+ if (mf->row < viewrow + VIEW_Y/4)
+ viewrow = mf->row - (VIEW_Y - VIEW_Y/4);
+ else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4))
+ viewrow = mf->row - VIEW_Y/4;
+ if (mf->col < viewcol + VIEW_X/8)
+ viewcol = mf->col - (VIEW_X - VIEW_X/8);
+ else if (mf->col > viewcol + (VIEW_X - VIEW_X/8))
+ viewcol = mf->col - VIEW_X/8;
+}
+
+#ifdef SIGTSTP
+void
+susp()
+{
+ blockalarm();
+ tstp();
+ (void) signal(SIGTSTP, susp);
+ unblockalarm();
+}
+#endif
diff --git a/sail/pl_main.c b/sail/pl_main.c
new file mode 100644
index 00000000..d4d87826
--- /dev/null
+++ b/sail/pl_main.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_main.c 5.5 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include "player.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+
+void choke(), child();
+
+/*ARGSUSED*/
+pl_main()
+{
+
+ if (!SCREENTEST()) {
+ printf("Can't sail on this terminal.\n");
+ exit(1);
+ }
+ initialize();
+ Signal("Aye aye, Sir", (struct ship *)0);
+ play();
+ return 0; /* for lint, play() never returns */
+}
+
+initialize()
+{
+ register struct File *fp;
+ register struct ship *sp;
+ char captain[80];
+ char message[60];
+ int load;
+ register int n;
+ char *nameptr;
+ int nat[NNATION];
+
+ if (game < 0) {
+ (void) puts("Choose a scenario:\n");
+ (void) puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE");
+ for (n = 0; n < NSCENE; n++) {
+ /* ( */
+ printf("\t%d):\t%d\t%s\t%s\n", n, scene[n].vessels,
+ sync_exists(n) ? "YES" : "no",
+ scene[n].name);
+ }
+reprint:
+ printf("\nScenario number? ");
+ (void) fflush(stdout);
+ (void) scanf("%d", &game);
+ while (getchar() != '\n')
+ ;
+ }
+ if (game < 0 || game >= NSCENE) {
+ (void) puts("Very funny.");
+ exit(1);
+ }
+ cc = &scene[game];
+ ls = SHIP(cc->vessels);
+
+ for (n = 0; n < NNATION; n++)
+ nat[n] = 0;
+ foreachship(sp) {
+ if (sp->file == NULL &&
+ (sp->file = (struct File *)calloc(1, sizeof (struct File))) == NULL) {
+ (void) puts("OUT OF MEMORY");
+ exit(1);
+ }
+ sp->file->index = sp - SHIP(0);
+ sp->file->stern = nat[sp->nationality]++;
+ sp->file->dir = sp->shipdir;
+ sp->file->row = sp->shiprow;
+ sp->file->col = sp->shipcol;
+ }
+ windspeed = cc->windspeed;
+ winddir = cc->winddir;
+
+ (void) signal(SIGHUP, choke);
+ (void) signal(SIGINT, choke);
+
+ hasdriver = sync_exists(game);
+ if (sync_open() < 0) {
+ perror("sail: syncfile");
+ exit(1);
+ }
+
+ if (hasdriver) {
+ (void) puts("Synchronizing with the other players...");
+ (void) fflush(stdout);
+ if (Sync() < 0)
+ leave(LEAVE_SYNC);
+ }
+ for (;;) {
+ foreachship(sp)
+ if (sp->file->captain[0] == 0 && !sp->file->struck
+ && sp->file->captured == 0)
+ break;
+ if (sp >= ls) {
+ (void) puts("All ships taken in that scenario.");
+ foreachship(sp)
+ free((char *)sp->file);
+ sync_close(0);
+ people = 0;
+ goto reprint;
+ }
+ if (randomize) {
+ player = sp - SHIP(0);
+ } else {
+ printf("%s\n\n", cc->name);
+ foreachship(sp)
+ printf(" %2d: %-10s %-15s (%-2d pts) %s\n",
+ sp->file->index,
+ countryname[sp->nationality],
+ sp->shipname,
+ sp->specs->pts,
+ saywhat(sp, 1));
+ printf("\nWhich ship (0-%d)? ", cc->vessels-1);
+ (void) fflush(stdout);
+ if (scanf("%d", &player) != 1 || player < 0
+ || player >= cc->vessels) {
+ while (getchar() != '\n')
+ ;
+ (void) puts("Say what?");
+ player = -1;
+ } else
+ while (getchar() != '\n')
+ ;
+ }
+ if (player < 0)
+ continue;
+ if (Sync() < 0)
+ leave(LEAVE_SYNC);
+ fp = SHIP(player)->file;
+ if (fp->captain[0] || fp->struck || fp->captured != 0)
+ (void) puts("That ship is taken.");
+ else
+ break;
+ }
+
+ ms = SHIP(player);
+ mf = ms->file;
+ mc = ms->specs;
+
+ Write(W_BEGIN, ms, 0, 0, 0, 0, 0);
+ if (Sync() < 0)
+ leave(LEAVE_SYNC);
+
+ (void) signal(SIGCHLD, child);
+ if (!hasdriver)
+ switch (fork()) {
+ case 0:
+ longjmp(restart, MODE_DRIVER);
+ /*NOTREACHED*/
+ case -1:
+ perror("fork");
+ leave(LEAVE_FORK);
+ break;
+ default:
+ hasdriver++;
+ }
+
+ printf("Your ship is the %s, a %d gun %s (%s crew).\n",
+ ms->shipname, mc->guns, classname[mc->class],
+ qualname[mc->qual]);
+ if ((nameptr = (char *) getenv("SAILNAME")) && *nameptr)
+ (void) strncpy(captain, nameptr, sizeof captain);
+ else {
+ (void) printf("Your name, Captain? ");
+ (void) fflush(stdout);
+ (void) gets(captain);
+ if (!*captain)
+ (void) strcpy(captain, "no name");
+ }
+ captain[sizeof captain - 1] = '\0';
+ Write(W_CAPTAIN, ms, 1, (int)captain, 0, 0, 0);
+ for (n = 0; n < 2; n++) {
+ char buf[10];
+
+ printf("\nInitial broadside %s (grape, chain, round, double): ",
+ n ? "right" : "left");
+ (void) fflush(stdout);
+ (void) scanf("%s", buf);
+ switch (*buf) {
+ case 'g':
+ load = L_GRAPE;
+ break;
+ case 'c':
+ load = L_CHAIN;
+ break;
+ case 'r':
+ load = L_ROUND;
+ break;
+ case 'd':
+ load = L_DOUBLE;
+ break;
+ default:
+ load = L_ROUND;
+ }
+ if (n) {
+ mf->loadR = load;
+ mf->readyR = R_LOADED|R_INITIAL;
+ } else {
+ mf->loadL = load;
+ mf->readyL = R_LOADED|R_INITIAL;
+ }
+ }
+
+ initscreen();
+ draw_board();
+ (void) sprintf(message, "Captain %s assuming command", captain);
+ Write(W_SIGNAL, ms, 1, (int)message, 0, 0, 0);
+ newturn();
+}
diff --git a/sail/player.h b/sail/player.h
new file mode 100644
index 00000000..c28cdbc1
--- /dev/null
+++ b/sail/player.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)player.h 5.4 (Berkeley) 6/1/90
+ */
+
+#include <curses.h>
+#include "externs.h"
+
+/* sizes and coordinates for the screen */
+
+#define LINE_T 0
+#define LINE_L 0
+#define LINE_X COLS
+#define LINE_Y 1
+#define LINE_B (LINE_T+LINE_Y-1)
+#define LINE_R (LINE_L+LINE_X-1)
+
+#define BOX_T 1
+#define BOX_L 0
+#define BOX_X 65
+#define BOX_Y 16
+#define BOX_B (BOX_T+BOX_Y-1)
+#define BOX_R (BOX_L+BOX_X-1)
+
+#define TURN_T BOX_B
+#define TURN_Y 1
+#define TURN_L ((BOX_L+BOX_R-TURN_X)/2)
+#define TURN_X 9
+#define TURN_B (TURN_T+TURN_Y+1)
+#define TURN_R (TURN_L+TURN_X+1)
+
+#define STAT_T 0
+#define STAT_B BOX_B
+#define STAT_L (BOX_R+2)
+#define STAT_X 14
+#define STAT_Y (STAT_B-STAT_T+1)
+#define STAT_R (STAT_L+STAT_X-1)
+#define STAT_1 0
+#define STAT_2 (STAT_1+4)
+#define STAT_3 (STAT_2+7)
+
+#define SCROLL_T (BOX_B+1)
+#define SCROLL_L 0
+#define SCROLL_B (LINES-1)
+#define SCROLL_R (COLS-1)
+#define SCROLL_X (SCROLL_R-SCROLL_L+1)
+#define SCROLL_Y (SCROLL_B-SCROLL_T+1)
+
+#define VIEW_T (BOX_T+1)
+#define VIEW_L (BOX_L+1)
+#define VIEW_X (BOX_X-5)
+#define VIEW_Y (BOX_Y-2)
+#define VIEW_B (VIEW_T+VIEW_Y-1)
+#define VIEW_R (VIEW_L+VIEW_X-1)
+
+#define SLOT_T VIEW_T
+#define SLOT_L (VIEW_R+1)
+#define SLOT_X 3
+#define SLOT_Y VIEW_Y
+#define SLOT_B VIEW_B
+#define SLOT_R (SLOT_L+SLOT_X-1)
+
+#ifdef SIGTSTP
+#define SCREENTEST() (initscr() != ERR && signal(SIGTSTP, SIG_DFL) != BADSIG && STAT_R < COLS && SCROLL_Y > 0)
+#else
+#define SCREENTEST() (initscr() != ERR && STAT_R < COLS && SCROLL_Y > 0)
+#endif
+
+WINDOW *view_w;
+WINDOW *slot_w;
+WINDOW *scroll_w;
+WINDOW *stat_w;
+WINDOW *turn_w;
+
+char done_curses;
+char loaded, fired, changed, repaired;
+char dont_adjust;
+int viewrow, viewcol;
+char movebuf[sizeof SHIP(0)->file->movebuf];
+char version[];
+int player;
+struct ship *ms; /* memorial structure, &cc->ship[player] */
+struct File *mf; /* ms->file */
+struct shipspecs *mc; /* ms->specs */
+
+/* condition codes for leave() */
+#define LEAVE_QUIT 0
+#define LEAVE_CAPTURED 1
+#define LEAVE_HURRICAN 2
+#define LEAVE_DRIVER 3
+#define LEAVE_FORK 4
+#define LEAVE_SYNC 5
diff --git a/sail/sail.6 b/sail/sail.6
new file mode 100644
index 00000000..3419c641
--- /dev/null
+++ b/sail/sail.6
@@ -0,0 +1,896 @@
+.\" Copyright (c) 1988 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sail.6 5.6 (Berkeley) 6/23/90
+.\"
+.TH SAIL 6 "June 23, 1990"
+.UC 4
+.SH NAME
+sail \- multi-user wooden ships and iron men
+.SH SYNOPSIS
+.B sail
+[
+.B \-s
+[
+.B \-l
+] ] [
+.B \-x
+] [
+.B \-b
+] [
+.B num
+]
+.br
+.fi
+.SH DESCRIPTION
+.I Sail
+is a computer version of Avalon Hill's game of fighting sail
+originally developed by S. Craig Taylor.
+.PP
+Players of
+.I Sail
+take command of an old fashioned Man of War and fight other
+players or the computer. They may re-enact one of the many
+historical sea battles recorded in the game, or they can choose
+a fictional battle.
+.PP
+As a sea captain in the
+.I Sail
+Navy, the player has complete control over the workings of his ship.
+He must order every maneuver, change the set of his sails, and judge the
+right moment to let loose the terrible destruction of his broadsides.
+In addition to fighting the enemy, he must harness the powers of the wind
+and sea to make them work for him. The outcome of many battles during the
+age of sail was decided by the ability of one captain to hold the `weather
+gage.'
+.PP
+The flags are:
+.TP
+.B \-s
+Print the names and ships of the top ten sailors.
+.TP
+.B \-l
+Show the login name. Only effective with \fB-s\fP.
+.TP
+.B \-x
+Play the first available ship instead of prompting for a choice.
+.TP
+.B \-b
+No bells.
+.SH IMPLEMENTATION
+.I Sail
+is really two programs in one. Each player starts up a process which
+runs his own ship. In addition, a
+.I driver
+process is forked (by the first player) to run the computer ships
+and take care of global bookkeeping.
+.PP
+Because the
+.I driver
+must calculate moves for each ship it controls, the
+more ships the computer is playing, the slower the game will appear.
+.PP
+If a player joins a game in progress, he will synchronize
+with the other players (a rather slow process for everyone), and
+then he may play along with the rest.
+.PP
+To implement a multi-user game in Version 7 UNIX, which was the operating
+system
+.I Sail
+was first written under, the communicating processes must use a common
+temporary file as a place to read and write messages. In addition, a
+locking mechanism must be provided to ensure exclusive access to the
+shared file. For example,
+.I Sail
+uses a temporary file named /tmp/#sailsink.21 for scenario 21, and
+corresponding file names for the other scenarios. To provide exclusive
+access to the temporary file,
+.I Sail
+uses a technique stolen from an old game called "pubcaves" by Jeff Cohen.
+Processes do a busy wait in the loop
+.br
+.sp
+.ce 2
+ for (n = 0; link(sync_file, sync_lock) < 0 && n < 30; n++)
+ sleep(2);
+.br
+.sp
+until they are able to create a link to a file named "/tmp/#saillock.??".
+The "??" correspond to the scenario number of the game. Since UNIX
+guarantees that a link will point to only one file, the process that succeeds
+in linking will have exclusive access to the temporary file.
+.PP
+Whether or not this really works is open to speculation. When ucbmiro
+was rebooted after a crash, the file system check program found 3 links
+between the
+.I Sail
+temporary file and its link file.
+.SH CONSEQUENCES OF SEPARATE PLAYER AND DRIVER PROCESSES
+When players do something of global interest, such as moving or firing,
+the driver must coordinate the action with the other ships in the game.
+For example, if a player wants to move in a certain direction, he writes a
+message into the temporary file requesting the driver to move his ship.
+Each ``turn,'' the driver reads all the messages sent from the players and
+decides what happened. It then writes back into the temporary file new
+values of variables, etc.
+.PP
+The most noticeable effect this communication has on the game is the
+delay in moving. Suppose a player types a move for his ship and hits
+return. What happens then? The player process saves up messages to
+be written to the temporary file in a buffer. Every 7 seconds or so, the
+player process gets exclusive access to the temporary file and writes
+out its buffer to the file. The driver, running asynchronously, must
+read in the movement command, process it, and write out the results. This
+takes two exclusive accesses to the temporary file. Finally, when the player
+process gets around to doing another 7 second update, the results of the
+move are displayed on the screen. Hence, every movement requires four
+exclusive accesses to the temporary file (anywhere from 7 to 21 seconds
+depending upon asynchrony) before the player sees the results of his moves.
+.PP
+In practice, the delays are not as annoying as they would appear. There
+is room for "pipelining" in the movement. After the player writes out
+a first movement message, a second movement command can then be issued.
+The first message will be in the temporary file waiting for the driver, and
+the second will be in the file buffer waiting to be written to the file.
+Thus, by always typing moves a turn ahead of the time, the player can
+sail around quite quickly.
+.PP
+If the player types several movement commands between two 7 second updates,
+only the last movement command typed will be seen by the driver. Movement
+commands within the same update "overwrite" each other, in a sense.
+.SH THE HISTORY OF SAIL
+I wrote the first version of
+.I Sail
+on a PDP 11/70 in the fall of 1980. Needless to say, the code was horrendous,
+not portable in any sense of the word, and didn't work. The program was not
+very modular and had fseeks() and fwrites() every few lines. After a
+tremendous rewrite from the top down, I got the first working version up by
+1981. There were several annoying bugs concerning firing broadsides and
+finding angles.
+.I Sail
+uses no floating point, by the way, so the direction routines are rather
+tricky.
+Ed Wang rewrote my angle() routine in 1981 to be more correct (although
+it still doesn't work perfectly), and he added code to let a player select
+which ship he wanted at the start of the game (instead of the first one
+available).
+.PP
+Captain Happy (Craig Leres) is responsible for making
+.I Sail
+portable for the first time. This was no easy task, by the way. Constants
+like 2 and 10 were very frequent in the code. I also became famous for
+using "Riggle Memorial Structures" in
+.I Sail.
+Many of my structure references are so long that they run off the line
+printer page. Here is an example, if you promise not to laugh.
+.br
+.sp
+.ce
+specs[scene[flog.fgamenum].ship[flog.fshipnum].shipnum].pts
+.br
+.sp
+.PP
+.I Sail
+received its fourth and most thorough rewrite in the summer and fall
+of 1983. Ed Wang rewrote and modularized the code (a monumental feat)
+almost from scratch. Although he introduced many new bugs, the final
+result was very much cleaner and (?) faster. He added window movement
+commands and find ship commands.
+.SH HISTORICAL INFO
+Old Square Riggers were very maneuverable ships capable of intricate
+sailing. Their only disadvantage was an inability to sail very
+close to the wind. The design of a wooden ship allowed only for the
+guns to bear to the left and right sides. A few guns of small
+aspect (usually 6 or 9 pounders) could point forward, but their
+effect was small compared to a 68 gun broadside of 24 or 32 pounders.
+The guns bear approximately like so:
+.nf
+
+ \\
+ b----------------
+ ---0
+ \\
+ \\
+ \\ up to a range of ten (for round shot)
+ \\
+ \\
+ \\
+
+.fi
+An interesting phenomenon occurred when a broadside was fired
+down the length of an enemy ship. The shot tended to bounce along
+the deck and did several times more damage. This phenomenon was called
+a rake. Because the bows of a ship are very strong and present a smaller
+target than the stern, a stern rake (firing from the stern to the bow) causes
+more damage than a bow rake.
+.nf
+
+ b
+ 00 ---- Stern rake!
+ a
+
+.fi
+Most ships were equipped with carronades, which were very large, close
+range cannons. American ships from the revolution until the War of 1812
+were almost entirely armed with carronades.
+.PP
+The period of history covered in
+.I Sail
+is approximately from the 1770's until the end of Napoleanic France in 1815.
+There are many excellent books about the age of sail. My favorite author
+is Captain Frederick Marryat. More contemporary authors include C.S. Forester
+and Alexander Kent.
+.PP
+Fighting ships came in several sizes classed by armament. The mainstays of
+any fleet were its "Ships of the Line", or "Line of Battle Ships". They
+were so named because these ships fought together in great lines. They were
+close enough for mutual support, yet every ship could fire both its broadsides.
+We get the modern words "ocean liner," or "liner," and "battleship" from
+"ship of the line." The most common size was the the 74 gun two decked
+ship of the line. The two gun decks usually mounted 18 and 24 pounder guns.
+.PP
+The pride of the fleet were the first rates. These were huge three decked
+ships of the line mounting 80 to 136 guns. The guns in the three tiers
+were usually 18, 24, and 32 pounders in that order from top to bottom.
+.PP
+Various other ships came next. They were almost all "razees," or ships
+of the line with one deck sawed off. They mounted 40-64 guns and were
+a poor cross between a frigate and a line of battle ship. They neither
+had the speed of the former nor the firepower of the latter.
+.PP
+Next came the "eyes of the fleet." Frigates came in many sizes mounting
+anywhere from 32 to 44 guns. They were very handy vessels. They could
+outsail anything bigger and outshoot anything smaller. Frigates didn't
+fight in lines of battle as the much bigger 74's did. Instead, they
+harassed the enemy's rear or captured crippled ships. They were much
+more useful in missions away from the fleet, such as cutting out expeditions
+or boat actions. They could hit hard and get away fast.
+.PP
+Lastly, there were the corvettes, sloops, and brigs. These were smaller
+ships mounting typically fewer than 20 guns. A corvette was only slightly
+smaller than a frigate, so one might have up to 30 guns. Sloops were used
+for carrying dispatches or passengers. Brigs were something you built for
+land-locked lakes.
+.SH SAIL PARTICULARS
+Ships in
+.I Sail
+are represented by two characters. One character represents the bow of
+the ship, and the other represents the stern. Ships have nationalities
+and numbers. The first ship of a nationality is number 0, the second
+number 1, etc. Therefore, the first British ship in a game would be
+printed as "b0". The second Brit would be "b1", and the fifth Don
+would be "s4".
+.PP
+Ships can set normal sails, called Battle Sails, or bend on extra canvas
+called Full Sails. A ship under full sail is a beautiful sight indeed,
+and it can move much faster than a ship under Battle Sails. The only
+trouble is, with full sails set, there is so much tension on sail and
+rigging that a well aimed round shot can burst a sail into ribbons where
+it would only cause a little hole in a loose sail. For this reason,
+rigging damage is doubled on a ship with full sails set. Don't let
+that discourage you from using full sails. I like to keep them up
+right into the heat of battle. A ship
+with full sails set has a capital letter for its nationality. E.g.,
+a Frog, "f0", with full sails set would be printed as "F0".
+.PP
+When a ship is battered into a listing hulk, the last man aboard "strikes
+the colors." This ceremony is the ship's formal surrender. The nationality
+character
+of a surrendered ship is printed as "!". E.g., the Frog of our last example
+would soon be "!0".
+.PP
+A ship has a random chance of catching fire or sinking when it reaches the
+stage of listing hulk. A sinking ship has a "~" printed for its nationality,
+and a ship on fire and about to explode has a "#" printed.
+.PP
+Captured ships become the nationality of the prize crew. Therefore, if
+an American ship captures a British ship, the British ship will have an
+"a" printed for its nationality. In addition, the ship number is changed
+to "&","'", "(", ,")", "*", or "+" depending upon the original number,
+be it 0,1,2,3,4, or 5. E.g., the "b0" captured by an American becomes the
+"a&". The "s4" captured by a Frog becomes the "f*".
+.PP
+The ultimate example is, of course, an exploding Brit captured by an
+American: "#&".
+.SH MOVEMENT
+Movement is the most confusing part of
+.I Sail
+to many. Ships can head in 8 directions:
+.nf
+
+ 0 0 0
+ b b b0 b b b 0b b
+ 0 0 0
+
+.fi
+The stern of a ship moves when it turns. The bow remains stationary.
+Ships can always turn, regardless of the wind (unless they are becalmed).
+All ships drift when they lose headway. If a ship doesn't move forward
+at all for two turns, it will begin to drift. If a ship has begun to
+drift, then it must move forward before it turns, if it plans to do
+more than make a right or left turn, which is always possible.
+.PP
+Movement commands to
+.I Sail
+are a string of forward moves and turns. An example is "l3". It will
+turn a ship left and then move it ahead 3 spaces. In the drawing above,
+the "b0" made 7 successive left turns. When
+.I Sail
+prompts you for a move, it prints three characters of import. E.g.,
+.nf
+ move (7, 4):
+.fi
+The first number is the maximum number of moves you can make,
+including turns. The second number is the maximum number of turns
+you can make. Between the numbers is sometimes printed a quote "'".
+If the quote is present, it means that your ship has been drifting, and
+you must move ahead to regain headway before you turn (see note above).
+Some of the possible moves for the example above are as follows:
+.nf
+
+ move (7, 4): 7
+ move (7, 4): 1
+ move (7, 4): d /* drift, or do nothing */
+ move (7, 4): 6r
+ move (7, 4): 5r1
+ move (7, 4): 4r1r
+ move (7, 4): l1r1r2
+ move (7, 4): 1r1r1r1
+
+.fi
+Because square riggers performed so poorly sailing into the wind, if at
+any point in a movement command you turn into the wind, the movement stops
+there. E.g.,
+.nf
+
+ move (7, 4): l1l4
+ Movement Error;
+ Helm: l1l
+
+.fi
+Moreover, whenever you make a turn, your movement allowance drops to
+min(what's left, what you would have at the new attitude). In short,
+if you turn closer to the wind, you most likely won't be able to sail the
+full allowance printed in the "move" prompt.
+.PP
+Old sailing captains had to keep an eye constantly on the wind. Captains
+in
+.I Sail
+are no different. A ship's ability to move depends on its attitide to the
+wind. The best angle possible is to have the wind off your quarter, that is,
+just off the stern. The direction rose on the side of the screen gives the
+possible movements for your ship at all positions to the wind. Battle
+sail speeds are given first, and full sail speeds are given in parenthesis.
+.nf
+
+ 0 1(2)
+ \\|/
+ -^-3(6)
+ /|\\
+ | 4(7)
+ 3(6)
+
+.fi
+Pretend the bow of your ship (the "^") is pointing upward and the wind is
+blowing from the bottom to the top of the page. The
+numbers at the bottom "3(6)" will be your speed under battle or full
+sails in such a situation. If the wind is off your quarter, then you
+can move "4(7)". If the wind is off your beam, "3(6)". If the wind is
+off your bow, then you can only move "1(2)". Facing into the wind, you
+can't move at all. Ships facing into the wind were said to be "in irons".
+.SH WINDSPEED AND DIRECTION
+The windspeed and direction is displayed as a little weather vane on the
+side of the screen. The number in the middle of the vane indicates the wind
+speed, and the + to - indicates the wind direction. The wind blows from
+the + sign (high pressure) to the - sign (low pressure). E.g.,
+.nf
+
+ |
+ 3
+ +
+
+.fi
+.PP
+The wind speeds are 0 = becalmed, 1 = light breeze, 2 = moderate breeze,
+3 = fresh breeze, 4 = strong breeze, 5 = gale, 6 = full gale, 7 = hurricane.
+If a hurricane shows up, all ships are destroyed.
+.SH GRAPPLING AND FOULING
+If two ships collide, they run the risk of becoming tangled together. This
+is called "fouling." Fouled ships are stuck together, and neither can move.
+They can unfoul each other if they want to. Boarding parties can only be
+sent across to ships when the antagonists are either fouled or grappled.
+.PP
+Ships can grapple each other by throwing grapnels into the rigging of
+the other.
+.PP
+The number of fouls and grapples you have are displayed on the upper
+right of the screen.
+.SH BOARDING
+Boarding was a very costly venture in terms of human life. Boarding parties
+may be formed in
+.I Sail
+to either board an enemy ship or to defend your own ship against attack.
+Men organized as Defensive Boarding Parties fight twice as hard to save
+their ship as men left unorganized.
+.PP
+The boarding strength of a crew depends upon its quality and upon the
+number of men sent.
+.SH CREW QUALITY
+The British seaman was world renowned for his sailing abilities. American
+sailors, however, were actually the best seamen in the world. Because the
+American Navy offered twice the wages of the Royal Navy, British seamen
+who liked the sea defected to America by the thousands.
+.PP
+In
+.I Sail,
+crew quality is quantized into 5 energy levels. "Elite" crews can outshoot
+and outfight all other sailors. "Crack" crews are next. "Mundane" crews
+are average, and "Green" and "Mutinous" crews are below average. A good
+rule of thumb is that "Crack" or "Elite" crews get one extra hit
+per broadside compared to "Mundane" crews. Don't expect too much from
+"Green" crews.
+.SH BROADSIDES
+Your two broadsides may be loaded with four kinds of shot: grape, chain,
+round, and double. You have guns and carronades in both the port and starboard
+batteries. Carronades only have a range of two, so you have to get in
+close to be able to fire them. You have the choice of firing at the hull
+or rigging of another ship. If the range of the ship is greater than 6,
+then you may only shoot at the rigging.
+.PP
+The types of shot and their advantages are:
+.SH ROUND
+Range of 10. Good for hull or rigging hits.
+.SH DOUBLE
+Range of 1. Extra good for hull or rigging hits.
+Double takes two turns to load.
+.SH CHAIN
+Range of 3. Excellent for tearing down rigging.
+Cannot damage hull or guns, though.
+.SH GRAPE
+Range of 1. Sometimes devastating against enemy crews.
+.PP
+On the side of the screen is displayed some vital information about your
+ship:
+.nf
+
+ Load D! R!
+ Hull 9
+ Crew 4 4 2
+ Guns 4 4
+ Carr 2 2
+ Rigg 5 5 5 5
+
+.fi
+"Load" shows what your port (left) and starboard (right) broadsides are
+loaded with. A "!" after the type of shot indicates that it is an initial
+broadside. Initial broadside were loaded with care before battle and before
+the decks ran red with blood. As a consequence, initial broadsides are a
+little more effective than broadsides loaded later. A "*" after the type of
+shot indicates that the gun
+crews are still loading it, and you cannot fire yet. "Hull" shows how much
+hull you have left. "Crew" shows your three sections of crew. As your
+crew dies off, your ability to fire decreases. "Guns" and "Carr" show
+your port and starboard guns. As you lose guns, your ability to fire
+decreases. "Rigg" shows how much rigging you have on your 3 or 4 masts.
+As rigging is shot away, you lose mobility.
+.SH EFFECTIVENESS OF FIRE
+It is very dramatic when a ship fires its thunderous broadsides, but the
+mere opportunity to fire them does not guarantee any hits. Many factors
+influence the destructive force of a broadside. First of all, and the chief
+factor, is distance. It is harder to hit a ship at range ten than it is
+to hit one sloshing alongside. Next is raking. Raking fire, as
+mentioned before,
+can sometimes dismast a ship at range ten. Next, crew size and quality affects
+the damage done by a broadside. The number of guns firing also bears on the
+point,
+so to speak. Lastly, weather affects the accuracy of a broadside. If the
+seas are high (5 or 6), then the lower gunports of ships of the line can't
+even be opened to run out the guns. This gives frigates and other flush
+decked vessels an advantage in a storm. The scenario
+.I Pellew vs. The Droits de L'Homme
+takes advantage of this peculiar circumstance.
+.SH REPAIRS
+Repairs may be made to your Hull, Guns, and Rigging at the slow rate of
+two points per three turns. The message "Repairs Completed" will be
+printed if no more repairs can be made.
+.SH PECULIARITIES OF COMPUTER SHIPS
+Computer ships in
+.I Sail
+follow all the rules above with a few exceptions. Computer ships never
+repair damage. If they did, the players could never beat them. They
+play well enough as it is. As a consolation, the computer ships can fire double
+shot every turn. That fluke is a good reason to keep your distance. The
+.I
+Driver
+figures out the moves of the computer ships. It computes them with a typical
+A.I. distance function and a depth first search to find the maximum "score."
+It seems to work fairly well, although I'll be the first to admit it isn't
+perfect.
+.SH HOW TO PLAY
+Commands are given to
+.I Sail
+by typing a single character. You will then be prompted for further
+input. A brief summary of the commands follows.
+.bp
+.SH COMMAND SUMMARY
+.nf
+
+ 'f' Fire broadsides if they bear
+ 'l' Reload
+ 'L' Unload broadsides (to change ammo)
+ 'm' Move
+ 'i' Print the closest ship
+ 'I' Print all ships
+ 'F' Find a particular ship or ships (e.g. "a?" for all Americans)
+ 's' Send a message around the fleet
+ 'b' Attempt to board an enemy ship
+ 'B' Recall boarding parties
+ 'c' Change set of sail
+ 'r' Repair
+ 'u' Attempt to unfoul
+ 'g' Grapple/ungrapple
+ 'v' Print version number of game
+ '^L' Redraw screen
+ 'Q' Quit
+
+ 'C' Center your ship in the window
+ 'U' Move window up
+ 'D','N' Move window down
+ 'H' Move window left
+ 'J' Move window right
+ 'S' Toggle window to follow your ship or stay where it is
+
+.fi
+.bg
+.SH SCENARIOS
+Here is a summary of the scenarios in
+.I Sail:
+
+.br
+.SH Ranger vs. Drake:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(a) Ranger 19 gun Sloop (crack crew) (7 pts)
+(b) Drake 17 gun Sloop (crack crew) (6 pts)
+.SH The Battle of Flamborough Head:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+.fi
+This is John Paul Jones' first famous battle. Aboard the Bonhomme
+Richard, he was able to overcome the Serapis's greater firepower
+by quickly boarding her.
+.nf
+
+(a) Bonhomme Rich 42 gun Corvette (crack crew) (11 pts)
+(b) Serapis 44 gun Frigate (crack crew) (12 pts)
+.SH Arbuthnot and Des Touches:
+.nf
+Wind from the N, blowing a gale.
+
+(b) America 64 gun Ship of the Line (crack crew) (20 pts)
+(b) Befford 74 gun Ship of the Line (crack crew) (26 pts)
+(b) Adamant 50 gun Ship of the Line (crack crew) (17 pts)
+(b) London 98 gun 3 Decker SOL (crack crew) (28 pts)
+(b) Royal Oak 74 gun Ship of the Line (crack crew) (26 pts)
+(f) Neptune 74 gun Ship of the Line (average crew) (24 pts)
+(f) Duc Bougogne 80 gun 3 Decker SOL (average crew) (27 pts)
+(f) Conquerant 74 gun Ship of the Line (average crew) (24 pts)
+(f) Provence 64 gun Ship of the Line (average crew) (18 pts)
+(f) Romulus 44 gun Ship of the Line (average crew) (10 pts)
+.SH Suffren and Hughes:
+.nf
+
+Wind from the S, blowing a fresh breeze.
+
+(b) Monmouth 74 gun Ship of the Line (average crew) (24 pts)
+(b) Hero 74 gun Ship of the Line (crack crew) (26 pts)
+(b) Isis 50 gun Ship of the Line (crack crew) (17 pts)
+(b) Superb 74 gun Ship of the Line (crack crew) (27 pts)
+(b) Burford 74 gun Ship of the Line (average crew) (24 pts)
+(f) Flamband 50 gun Ship of the Line (average crew) (14 pts)
+(f) Annibal 74 gun Ship of the Line (average crew) (24 pts)
+(f) Severe 64 gun Ship of the Line (average crew) (18 pts)
+(f) Brilliant 80 gun Ship of the Line (crack crew) (31 pts)
+(f) Sphinx 80 gun Ship of the Line (average crew) (27 pts)
+.SH Nymphe vs. Cleopatre:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(b) Nymphe 36 gun Frigate (crack crew) (11 pts)
+(f) Cleopatre 36 gun Frigate (average crew) (10 pts)
+.SH Mars vs. Hercule:
+Wind from the S, blowing a fresh breeze.
+.nf
+(b) Mars 74 gun Ship of the Line (crack crew) (26 pts)
+(f) Hercule 74 gun Ship of the Line (average crew) (23 pts)
+.SH Ambuscade vs. Baionnaise:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(b) Ambuscade 32 gun Frigate (average crew) (9 pts)
+(f) Baionnaise 24 gun Corvette (average crew) (9 pts)
+.SH Constellation vs. Insurgent:
+.nf
+Wind from the S, blowing a gale.
+
+(a) Constellation 38 gun Corvette (elite crew) (17 pts)
+(f) Insurgent 36 gun Corvette (average crew) (11 pts)
+.SH Constellation vs. Vengeance:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Constellation 38 gun Corvette (elite crew) (17 pts)
+(f) Vengeance 40 gun Frigate (average crew) (15 pts)
+.SH The Battle of Lissa:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(b) Amphion 32 gun Frigate (elite crew) (13 pts)
+(b) Active 38 gun Frigate (elite crew) (18 pts)
+(b) Volage 22 gun Frigate (elite crew) (11 pts)
+(b) Cerberus 32 gun Frigate (elite crew) (13 pts)
+(f) Favorite 40 gun Frigate (average crew) (15 pts)
+(f) Flore 40 gun Frigate (average crew) (15 pts)
+(f) Danae 40 gun Frigate (crack crew) (17 pts)
+(f) Bellona 32 gun Frigate (green crew) (9 pts)
+(f) Corona 40 gun Frigate (green crew) (12 pts)
+(f) Carolina 32 gun Frigate (green crew) (7 pts)
+.SH Constitution vs. Guerriere:
+.nf
+Wind from the SW, blowing a gale.
+
+(a) Constitution 44 gun Corvette (elite crew) (24 pts)
+(b) Guerriere 38 gun Frigate (crack crew) (15 pts)
+.SH United States vs. Macedonian:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) United States 44 gun Frigate (elite crew) (24 pts)
+(b) Macedonian 38 gun Frigate (crack crew) (16 pts)
+.SH Constitution vs. Java:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Constitution 44 gun Corvette (elite crew) (24 pts)
+(b) Java 38 gun Corvette (crack crew) (19 pts)
+.SH Chesapeake vs. Shannon:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Chesapeake 38 gun Frigate (average crew) (14 pts)
+(b) Shannon 38 gun Frigate (elite crew) (17 pts)
+.SH The Battle of Lake Erie:
+.nf
+Wind from the S, blowing a light breeze.
+
+(a) Lawrence 20 gun Sloop (crack crew) (9 pts)
+(a) Niagara 20 gun Sloop (elite crew) (12 pts)
+(b) Lady Prevost 13 gun Brig (crack crew) (5 pts)
+(b) Detroit 19 gun Sloop (crack crew) (7 pts)
+(b) Q. Charlotte 17 gun Sloop (crack crew) (6 pts)
+.SH Wasp vs. Reindeer:
+.nf
+Wind from the S, blowing a light breeze.
+
+(a) Wasp 20 gun Sloop (elite crew) (12 pts)
+(b) Reindeer 18 gun Sloop (elite crew) (9 pts)
+.SH Constitution vs. Cyane and Levant:
+.br
+Wind from the S, blowing a moderate breeze.
+
+(a) Constitution 44 gun Corvette (elite crew) (24 pts)
+(b) Cyane 24 gun Sloop (crack crew) (11 pts)
+(b) Levant 20 gun Sloop (crack crew) (10 pts)
+.br
+.SH Pellew vs. Droits de L'Homme:
+.nf
+Wind from the N, blowing a gale.
+
+(b) Indefatigable 44 gun Frigate (elite crew) (14 pts)
+(b) Amazon 36 gun Frigate (crack crew) (14 pts)
+(f) Droits L'Hom 74 gun Ship of the Line (average crew) (24 pts)
+.SH Algeciras:
+.nf
+Wind from the SW, blowing a moderate breeze.
+
+(b) Caesar 80 gun Ship of the Line (crack crew) (31 pts)
+(b) Pompee 74 gun Ship of the Line (crack crew) (27 pts)
+(b) Spencer 74 gun Ship of the Line (crack crew) (26 pts)
+(b) Hannibal 98 gun 3 Decker SOL (crack crew) (28 pts)
+(s) Real-Carlos 112 gun 3 Decker SOL (green crew) (27 pts)
+(s) San Fernando 96 gun 3 Decker SOL (green crew) (24 pts)
+(s) Argonauta 80 gun Ship of the Line (green crew) (23 pts)
+(s) San Augustine 74 gun Ship of the Line (green crew) (20 pts)
+(f) Indomptable 80 gun Ship of the Line (average crew) (27 pts)
+(f) Desaix 74 gun Ship of the Line (average crew) (24 pts)
+.SH Lake Champlain:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(a) Saratoga 26 gun Sloop (crack crew) (12 pts)
+(a) Eagle 20 gun Sloop (crack crew) (11 pts)
+(a) Ticonderoga 17 gun Sloop (crack crew) (9 pts)
+(a) Preble 7 gun Brig (crack crew) (4 pts)
+(b) Confiance 37 gun Frigate (crack crew) (14 pts)
+(b) Linnet 16 gun Sloop (elite crew) (10 pts)
+(b) Chubb 11 gun Brig (crack crew) (5 pts)
+.SH Last Voyage of the USS President:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(a) President 44 gun Frigate (elite crew) (24 pts)
+(b) Endymion 40 gun Frigate (crack crew) (17 pts)
+(b) Pomone 44 gun Frigate (crack crew) (20 pts)
+(b) Tenedos 38 gun Frigate (crack crew) (15 pts)
+.SH Hornblower and the Natividad:
+.nf
+Wind from the E, blowing a gale.
+
+.fi
+A scenario for you Horny fans. Remember, he sank the Natividad
+against heavy odds and winds. Hint: don't try to board the Natividad,
+her crew is much bigger, albeit green.
+.nf
+
+(b) Lydia 36 gun Frigate (elite crew) (13 pts)
+(s) Natividad 50 gun Ship of the Line (green crew) (14 pts)
+.SH Curse of the Flying Dutchman:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+Just for fun, take the Piece of cake.
+
+(s) Piece of Cake 24 gun Corvette (average crew) (9 pts)
+(f) Flying Dutchy 120 gun 3 Decker SOL (elite crew) (43 pts)
+.SH The South Pacific:
+.nf
+Wind from the S, blowing a strong breeze.
+
+(a) USS Scurvy 136 gun 3 Decker SOL (mutinous crew) (27 pts)
+(b) HMS Tahiti 120 gun 3 Decker SOL (elite crew) (43 pts)
+(s) Australian 32 gun Frigate (average crew) (9 pts)
+(f) Bikini Atoll 7 gun Brig (crack crew) (4 pts)
+.SH Hornblower and the battle of Rosas bay:
+.nf
+Wind from the E, blowing a fresh breeze.
+
+The only battle Hornblower ever lost. He was able to dismast one
+ship and stern rake the others though. See if you can do as well.
+.nf
+
+(b) Sutherland 74 gun Ship of the Line (crack crew) (26 pts)
+(f) Turenne 80 gun 3 Decker SOL (average crew) (27 pts)
+(f) Nightmare 74 gun Ship of the Line (average crew) (24 pts)
+(f) Paris 112 gun 3 Decker SOL (green crew) (27 pts)
+(f) Napolean 74 gun Ship of the Line (green crew) (20 pts)
+.SH Cape Horn:
+.nf
+Wind from the NE, blowing a strong breeze.
+
+(a) Concord 80 gun Ship of the Line (average crew) (27 pts)
+(a) Berkeley 98 gun 3 Decker SOL (crack crew) (28 pts)
+(b) Thames 120 gun 3 Decker SOL (elite crew) (43 pts)
+(s) Madrid 112 gun 3 Decker SOL (green crew) (27 pts)
+(f) Musket 80 gun 3 Decker SOL (average crew) (27 pts)
+.SH New Orleans:
+.nf
+Wind from the SE, blowing a fresh breeze.
+
+Watch that little Cypress go!
+
+(a) Alligator 120 gun 3 Decker SOL (elite crew) (43 pts)
+(b) Firefly 74 gun Ship of the Line (crack crew) (27 pts)
+(b) Cypress 44 gun Frigate (elite crew) (14 pts)
+.SH Botany Bay:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(b) Shark 64 gun Ship of the Line (average crew) (18 pts)
+(f) Coral Snake 44 gun Corvette (elite crew) (24 pts)
+(f) Sea Lion 44 gun Frigate (elite crew) (24 pts)
+.SH Voyage to the Bottom of the Sea:
+.nf
+Wind from the NW, blowing a fresh breeze.
+
+This one is dedicated to Richard Basehart and David Hedison.
+
+(a) Seaview 120 gun 3 Decker SOL (elite crew) (43 pts)
+(a) Flying Sub 40 gun Frigate (crack crew) (17 pts)
+(b) Mermaid 136 gun 3 Decker SOL (mutinous crew) (27 pts)
+(s) Giant Squid 112 gun 3 Decker SOL (green crew) (27 pts)
+.SH Frigate Action:
+.nf
+Wind from the E, blowing a fresh breeze.
+
+(a) Killdeer 40 gun Frigate (average crew) (15 pts)
+(b) Sandpiper 40 gun Frigate (average crew) (15 pts)
+(s) Curlew 38 gun Frigate (crack crew) (16 pts)
+.SH The Battle of Midway:
+.nf
+Wind from the E, blowing a moderate breeze.
+
+(a) Enterprise 80 gun Ship of the Line (crack crew) (31 pts)
+(a) Yorktown 80 gun Ship of the Line (average crew) (27 pts)
+(a) Hornet 74 gun Ship of the Line (average crew) (24 pts)
+(j) Akagi 112 gun 3 Decker SOL (green crew) (27 pts)
+(j) Kaga 96 gun 3 Decker SOL (green crew) (24 pts)
+(j) Soryu 80 gun Ship of the Line (green crew) (23 pts)
+
+.SH Star Trek:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Enterprise 450 gun Ship of the Line (elite crew) (75 pts)
+(a) Yorktown 450 gun Ship of the Line (elite crew) (75 pts)
+(a) Reliant 450 gun Ship of the Line (elite crew) (75 pts)
+(a) Galileo 450 gun Ship of the Line (elite crew) (75 pts)
+(k) Kobayashi Maru 450 gun Ship of the Line (elite crew) (75 pts)
+(k) Klingon II 450 gun Ship of the Line (elite crew) (75 pts)
+(o) Red Orion 450 gun Ship of the Line (elite crew) (75 pts)
+(o) Blue Orion 450 gun Ship of the Line (elite crew) (75 pts)
+
+.SH CONCLUSION
+
+.I Sail
+has been a group effort.
+
+.SH AUTHOR
+Dave Riggle
+.SH CO-AUTHOR
+Ed Wang
+.SH REFITTING
+Craig Leres
+.SH CONSULTANTS
+.nf
+Chris Guthrie
+Captain Happy
+Horatio Nelson
+ and many valiant others...
+.fi
+.SH "REFERENCES"
+.nf
+Wooden Ships & Iron Men, by Avalon Hill
+Captain Horatio Hornblower Novels, (13 of them) by C.S. Forester
+Captain Richard Bolitho Novels, (12 of them) by Alexander Kent
+The Complete Works of Captain Frederick Marryat, (about 20) especially
+.in +6n
+Mr. Midshipman Easy
+Peter Simple
+Jacob Faithful
+Japhet in Search of a Father
+Snarleyyow, or The Dog Fiend
+Frank Mildmay, or The Naval Officer
+.in -6n
+.SH BUGS
+Probably a few, and please report them to "riggle@ernie.berkeley.edu" and
+"edward@ucbarpa.berkeley.edu"
diff --git a/sail/sync.c b/sail/sync.c
new file mode 100644
index 00000000..a4924518
--- /dev/null
+++ b/sail/sync.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sync.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "externs.h"
+#include <sys/file.h>
+#include <sys/errno.h>
+
+#define BUFSIZE 4096
+
+static char sync_buf[BUFSIZE];
+static char *sync_bp = sync_buf;
+static char sync_lock[25];
+static char sync_file[25];
+static long sync_seek;
+static FILE *sync_fp;
+#define SF "/tmp/#sailsink.%d"
+#define LF "/tmp/#saillock.%d"
+
+/*VARARGS3*/
+makesignal(from, fmt, ship, a, b, c)
+ struct ship *from;
+ char *fmt;
+ register struct ship *ship;
+{
+ char message[80];
+
+ if (ship == 0)
+ (void) sprintf(message, fmt, a, b, c);
+ else
+ (void) sprintf(message, fmt,
+ ship->shipname, colours(ship),
+ sterncolour(ship), a, b, c);
+ Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0);
+}
+
+#include <sys/types.h>
+#include <sys/stat.h>
+sync_exists(game)
+{
+ char buf[sizeof sync_file];
+ struct stat s;
+ time_t t;
+
+ (void) sprintf(buf, SF, game);
+ (void) time(&t);
+ if (stat(buf, &s) < 0)
+ return 0;
+ if (s.st_mtime < t - 60*60*2) { /* 2 hours */
+ (void) unlink(buf);
+ (void) sprintf(buf, LF, game);
+ (void) unlink(buf);
+ return 0;
+ } else
+ return 1;
+}
+
+sync_open()
+{
+ if (sync_fp != NULL)
+ (void) fclose(sync_fp);
+ (void) sprintf(sync_lock, LF, game);
+ (void) sprintf(sync_file, SF, game);
+ if (access(sync_file, 0) < 0) {
+ int omask = umask(issetuid ? 077 : 011);
+ sync_fp = fopen(sync_file, "w+");
+ (void) umask(omask);
+ } else
+ sync_fp = fopen(sync_file, "r+");
+ if (sync_fp == NULL)
+ return -1;
+ sync_seek = 0;
+ return 0;
+}
+
+sync_close(remove)
+ char remove;
+{
+ if (sync_fp != 0)
+ (void) fclose(sync_fp);
+ if (remove)
+ (void) unlink(sync_file);
+}
+
+Write(type, ship, isstr, a, b, c, d)
+ int type;
+ struct ship *ship;
+ char isstr;
+ int a, b, c, d;
+{
+ if (isstr)
+ (void) sprintf(sync_bp, "%d %d %d %s\n",
+ type, ship->file->index, isstr, a);
+ else
+ (void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n",
+ type, ship->file->index, isstr, a, b, c, d);
+ while (*sync_bp++)
+ ;
+ sync_bp--;
+ if (sync_bp >= &sync_buf[sizeof sync_buf])
+ abort();
+ (void) sync_update(type, ship, a, b, c, d);
+}
+
+Sync()
+{
+ sig_t sighup, sigint;
+ register n;
+ int type, shipnum, isstr, a, b, c, d;
+ char buf[80];
+ char erred = 0;
+ extern errno;
+
+ sighup = signal(SIGHUP, SIG_IGN);
+ sigint = signal(SIGINT, SIG_IGN);
+ for (n = TIMEOUT; --n >= 0;) {
+#ifdef LOCK_EX
+ if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
+ break;
+ if (errno != EWOULDBLOCK)
+ return -1;
+#else
+ if (link(sync_file, sync_lock) >= 0)
+ break;
+ if (errno != EEXIST)
+ return -1;
+#endif
+ sleep(1);
+ }
+ if (n <= 0)
+ return -1;
+ (void) fseek(sync_fp, sync_seek, 0);
+ for (;;) {
+ switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
+ case 3:
+ break;
+ case EOF:
+ goto out;
+ default:
+ goto bad;
+ }
+ if (shipnum < 0 || shipnum >= cc->vessels)
+ goto bad;
+ if (isstr != 0 && isstr != 1)
+ goto bad;
+ if (isstr) {
+ register char *p;
+ for (p = buf;;) {
+ switch (*p++ = getc(sync_fp)) {
+ case '\n':
+ p--;
+ case EOF:
+ break;
+ default:
+ if (p >= buf + sizeof buf)
+ p--;
+ continue;
+ }
+ break;
+ }
+ *p = 0;
+ for (p = buf; *p == ' '; p++)
+ ;
+ a = (int)p;
+ b = c = d = 0;
+ } else
+ if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4)
+ goto bad;
+ if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0)
+ goto bad;
+ }
+bad:
+ erred++;
+out:
+ if (!erred && sync_bp != sync_buf) {
+ (void) fseek(sync_fp, 0L, 2);
+ (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
+ sync_fp);
+ (void) fflush(sync_fp);
+ sync_bp = sync_buf;
+ }
+ sync_seek = ftell(sync_fp);
+#ifdef LOCK_EX
+ (void) flock(fileno(sync_fp), LOCK_UN);
+#else
+ (void) unlink(sync_lock);
+#endif
+ (void) signal(SIGHUP, sighup);
+ (void) signal(SIGINT, sigint);
+ return erred ? -1 : 0;
+}
+
+sync_update(type, ship, a, b, c, d)
+ int type;
+ register struct ship *ship;
+ int a, b, c, d;
+{
+ switch (type) {
+ case W_DBP: {
+ register struct BP *p = &ship->file->DBP[a];
+ p->turnsent = b;
+ p->toship = SHIP(c);
+ p->mensent = d;
+ break;
+ }
+ case W_OBP: {
+ register struct BP *p = &ship->file->OBP[a];
+ p->turnsent = b;
+ p->toship = SHIP(c);
+ p->mensent = d;
+ break;
+ }
+ case W_FOUL: {
+ register struct snag *p = &ship->file->foul[a];
+ if (SHIP(a)->file->dir == 0)
+ break;
+ if (p->sn_count++ == 0)
+ p->sn_turn = turn;
+ ship->file->nfoul++;
+ break;
+ }
+ case W_GRAP: {
+ register struct snag *p = &ship->file->grap[a];
+ if (SHIP(a)->file->dir == 0)
+ break;
+ if (p->sn_count++ == 0)
+ p->sn_turn = turn;
+ ship->file->ngrap++;
+ break;
+ }
+ case W_UNFOUL: {
+ register struct snag *p = &ship->file->foul[a];
+ if (p->sn_count > 0)
+ if (b) {
+ ship->file->nfoul -= p->sn_count;
+ p->sn_count = 0;
+ } else {
+ ship->file->nfoul--;
+ p->sn_count--;
+ }
+ break;
+ }
+ case W_UNGRAP: {
+ register struct snag *p = &ship->file->grap[a];
+ if (p->sn_count > 0)
+ if (b) {
+ ship->file->ngrap -= p->sn_count;
+ p->sn_count = 0;
+ } else {
+ ship->file->ngrap--;
+ p->sn_count--;
+ }
+ break;
+ }
+ case W_SIGNAL:
+ if (mode == MODE_PLAYER)
+ if (nobells)
+ Signal("%s (%c%c): %s", ship, a);
+ else
+ Signal("\7%s (%c%c): %s", ship, a);
+ break;
+ case W_CREW: {
+ register struct shipspecs *s = ship->specs;
+ s->crew1 = a;
+ s->crew2 = b;
+ s->crew3 = c;
+ break;
+ }
+ case W_CAPTAIN:
+ (void) strncpy(ship->file->captain, (char *)a,
+ sizeof ship->file->captain - 1);
+ ship->file->captain[sizeof ship->file->captain - 1] = 0;
+ break;
+ case W_CAPTURED:
+ if (a < 0)
+ ship->file->captured = 0;
+ else
+ ship->file->captured = SHIP(a);
+ break;
+ case W_CLASS:
+ ship->specs->class = a;
+ break;
+ case W_DRIFT:
+ ship->file->drift = a;
+ break;
+ case W_EXPLODE:
+ if ((ship->file->explode = a) == 2)
+ ship->file->dir = 0;
+ break;
+ case W_FS:
+ ship->file->FS = a;
+ break;
+ case W_GUNL: {
+ register struct shipspecs *s = ship->specs;
+ s->gunL = a;
+ s->carL = b;
+ break;
+ }
+ case W_GUNR: {
+ register struct shipspecs *s = ship->specs;
+ s->gunR = a;
+ s->carR = b;
+ break;
+ }
+ case W_HULL:
+ ship->specs->hull = a;
+ break;
+ case W_MOVE:
+ (void) strncpy(ship->file->movebuf, (char *)a,
+ sizeof ship->file->movebuf - 1);
+ ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0;
+ break;
+ case W_PCREW:
+ ship->file->pcrew = a;
+ break;
+ case W_POINTS:
+ ship->file->points = a;
+ break;
+ case W_QUAL:
+ ship->specs->qual = a;
+ break;
+ case W_RIGG: {
+ register struct shipspecs *s = ship->specs;
+ s->rig1 = a;
+ s->rig2 = b;
+ s->rig3 = c;
+ s->rig4 = d;
+ break;
+ }
+ case W_RIG1:
+ ship->specs->rig1 = a;
+ break;
+ case W_RIG2:
+ ship->specs->rig2 = a;
+ break;
+ case W_RIG3:
+ ship->specs->rig3 = a;
+ break;
+ case W_RIG4:
+ ship->specs->rig4 = a;
+ break;
+ case W_COL:
+ ship->file->col = a;
+ break;
+ case W_DIR:
+ ship->file->dir = a;
+ break;
+ case W_ROW:
+ ship->file->row = a;
+ break;
+ case W_SINK:
+ if ((ship->file->sink = a) == 2)
+ ship->file->dir = 0;
+ break;
+ case W_STRUCK:
+ ship->file->struck = a;
+ break;
+ case W_TA:
+ ship->specs->ta = a;
+ break;
+ case W_ALIVE:
+ alive = 1;
+ break;
+ case W_TURN:
+ turn = a;
+ break;
+ case W_WIND:
+ winddir = a;
+ windspeed = b;
+ break;
+ case W_BEGIN:
+ (void) strcpy(ship->file->captain, "begin");
+ people++;
+ break;
+ case W_END:
+ *ship->file->captain = 0;
+ ship->file->points = 0;
+ people--;
+ break;
+ case W_DDEAD:
+ hasdriver = 0;
+ break;
+ default:
+ fprintf(stderr, "sync_update: unknown type %d\r\n", type);
+ return -1;
+ }
+ return 0;
+}
diff --git a/sail/version.c b/sail/version.c
new file mode 100644
index 00000000..02961e07
--- /dev/null
+++ b/sail/version.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)version.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+char version[] = "Wooden Ships and Iron Men, Version 5.4 (90/06/01)";
diff --git a/snake/Makefile b/snake/Makefile
new file mode 100644
index 00000000..c57d83ca
--- /dev/null
+++ b/snake/Makefile
@@ -0,0 +1,5 @@
+# @(#)Makefile 5.1 (Berkeley) 2/28/91
+
+SUBDIR= snake snscore
+
+.include <bsd.subdir.mk>
diff --git a/snake/snake/Makefile b/snake/snake/Makefile
new file mode 100644
index 00000000..1bedbb37
--- /dev/null
+++ b/snake/snake/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 5.11 (Berkeley) 2/28/91
+
+PROG= snake
+SRCS= snake.c move.c
+MAN6= snake.0
+DPADD= ${LIBM} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lm -ltermcap -lcompat
+HIDEGAME=hidegame
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/snake/snake/move.c b/snake/snake/move.c
new file mode 100644
index 00000000..decddf6d
--- /dev/null
+++ b/snake/snake/move.c
@@ -0,0 +1,660 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)move.c 5.8 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*************************************************************************
+ *
+ * MOVE LIBRARY
+ *
+ * This set of subroutines moves a cursor to a predefined
+ * location, independent of the terminal type. If the
+ * terminal has an addressable cursor, it uses it. If
+ * not, it optimizes for tabs (currently) even if you don't
+ * have them.
+ *
+ * At all times the current address of the cursor must be maintained,
+ * and that is available as structure cursor.
+ *
+ * The following calls are allowed:
+ * move(sp) move to point sp.
+ * up() move up one line.
+ * down() move down one line.
+ * bs() move left one space (except column 0).
+ * nd() move right one space(no write).
+ * clear() clear screen.
+ * home() home.
+ * ll() move to lower left corner of screen.
+ * cr() carriage return (no line feed).
+ * pr() just like standard printf, but keeps track
+ * of cursor position. (Uses pstring).
+ * apr() same as printf, but first argument is &point.
+ * (Uses pstring).
+ * pstring(s) output the string of printing characters.
+ * However, '\r' is interpreted to mean return
+ * to column of origination AND do linefeed.
+ * '\n' causes <cr><lf>.
+ * putpad(str) calls tputs to output character with proper
+ * padding.
+ * outch() the output routine for a character used by
+ * tputs. It just calls putchar.
+ * pch(ch) output character to screen and update
+ * cursor address (must be a standard
+ * printing character). WILL SCROLL.
+ * pchar(ps,ch) prints one character if it is on the
+ * screen at the specified location;
+ * otherwise, dumps it.(no wrap-around).
+ *
+ * getcap() initializes strings for later calls.
+ * cap(string) outputs the string designated in the termcap
+ * data base. (Should not move the cursor.)
+ * done() returns the terminal to intial state and exits.
+ *
+ * point(&p,x,y) return point set to x,y.
+ *
+ * baudrate(x) returns the baudrate of the terminal.
+ * delay(t) causes an approximately constant delay
+ * independent of baudrate.
+ * Duration is ~ t/20 seconds.
+ *
+ ******************************************************************************/
+
+#include <stdarg.h>
+#include "snake.h"
+
+int CMlength;
+int NDlength;
+int BSlength;
+int delaystr[10];
+short ospeed;
+
+static char str[80];
+
+move(sp)
+struct point *sp;
+{
+ int distance;
+ int tabcol,ct;
+ struct point z;
+
+ if (sp->line <0 || sp->col <0 || sp->col > COLUMNS){
+ pr("move to [%d,%d]?",sp->line,sp->col);
+ return;
+ }
+ if (sp->line >= LINES){
+ move(point(&z,sp->col,LINES-1));
+ while(sp->line-- >= LINES)putchar('\n');
+ return;
+ }
+
+ if (CM != 0) {
+ char *cmstr = tgoto(CM, sp->col, sp->line);
+
+ CMlength = strlen(cmstr);
+ if(cursor.line == sp->line){
+ distance = sp->col - cursor.col;
+ if(distance == 0)return; /* Already there! */
+ if(distance > 0){ /* Moving to the right */
+ if(distance*NDlength < CMlength){
+ right(sp);
+ return;
+ }
+ if(TA){
+ ct=sp->col&7;
+ tabcol=(cursor.col|7)+1;
+ do{
+ ct++;
+ tabcol=(tabcol|7)+1;
+ }
+ while(tabcol<sp->col);
+ if(ct<CMlength){
+ right(sp);
+ return;
+ }
+ }
+ } else { /* Moving to the left */
+ if (-distance*BSlength < CMlength){
+ gto(sp);
+ return;
+ }
+ }
+ if(sp->col < CMlength){
+ cr();
+ right(sp);
+ return;
+ }
+ /* No more optimizations on same row. */
+ }
+ distance = sp->col - cursor.col;
+ distance = distance > 0 ?
+ distance*NDlength : -distance * BSlength;
+ if (distance < 0)
+ pr("ERROR: distance is negative: %d",distance);
+ distance += abs(sp->line - cursor.line);
+ if(distance >= CMlength){
+ putpad(cmstr);
+ cursor.line = sp->line;
+ cursor.col = sp->col;
+ return;
+ }
+ }
+
+ /*
+ * If we get here we have a terminal that can't cursor
+ * address but has local motions or one which can cursor
+ * address but can get there quicker with local motions.
+ */
+ gto(sp);
+}
+gto(sp)
+struct point *sp;
+{
+
+ int distance,f,tfield,j;
+
+ if (cursor.line > LINES || cursor.line <0 ||
+ cursor.col <0 || cursor.col > COLUMNS)
+ pr("ERROR: cursor is at %d,%d\n",
+ cursor.line,cursor.col);
+ if (sp->line > LINES || sp->line <0 ||
+ sp->col <0 || sp->col > COLUMNS)
+ pr("ERROR: target is %d,%d\n",sp->line,sp->col);
+ tfield = (sp->col) >> 3;
+ if (sp->line == cursor.line){
+ if (sp->col > cursor.col)right(sp);
+ else{
+ distance = (cursor.col -sp->col)*BSlength;
+ if (((TA) &&
+ (distance > tfield+((sp->col)&7)*NDlength)
+ ) ||
+ (((cursor.col)*NDlength) < distance)
+ ){
+ cr();
+ right(sp);
+ }
+ else{
+ while(cursor.col > sp->col) bs();
+ }
+ }
+ return;
+ }
+ /*must change row */
+ if (cursor.col - sp->col > (cursor.col >> 3)){
+ if (cursor.col == 0)f = 0;
+ else f = -1;
+ }
+ else f = cursor.col >> 3;
+ if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)){
+ /*
+ * home quicker than rlf:
+ * (sp->line + f > cursor.line - sp->line)
+ */
+ putpad(HO);
+ cursor.col = cursor.line = 0;
+ gto(sp);
+ return;
+ }
+ if (((sp->line << 1) > cursor.line + LINES+1 + f) && (LL != 0)){
+ /* home,rlf quicker than lf
+ * (LINES+1 - sp->line + f < sp->line - cursor.line)
+ */
+ if (cursor.line > f + 1){
+ /* is home faster than wraparound lf?
+ * (cursor.line + 20 - sp->line > 21 - sp->line + f)
+ */
+ ll();
+ gto(sp);
+ return;
+ }
+ }
+ if ((LL != 0) && (sp->line > cursor.line + (LINES >> 1) - 1))
+ cursor.line += LINES;
+ while(sp->line > cursor.line)down();
+ while(sp->line < cursor.line)up();
+ gto(sp); /*can recurse since cursor.line = sp->line */
+}
+
+right(sp)
+struct point *sp;
+{
+ int field,tfield;
+ int tabcol,strlength;
+
+ if (sp->col < cursor.col)
+ pr("ERROR:right() can't move left\n");
+ if(TA){ /* If No Tabs: can't send tabs because ttydrive
+ * loses count with control characters.
+ */
+ field = cursor.col >> 3;
+/*
+ * This code is useful for a terminal which wraps around on backspaces.
+ * (Mine does.) Unfortunately, this is not specified in termcap, and
+ * most terminals don't work that way. (Of course, most terminals
+ * have addressible cursors, too).
+ */
+ if (BW && (CM == 0) &&
+ ((sp->col << 1) - field > (COLUMNS - 8) << 1 )
+ ){
+ if (cursor.line == 0){
+ outch('\n');
+ }
+ outch('\r');
+ cursor.col = COLUMNS + 1;
+ while(cursor.col > sp->col)bs();
+ if (cursor.line != 0) outch('\n');
+ return;
+ }
+
+ tfield = sp->col >> 3;
+
+ while (field < tfield){
+ putpad(TA);
+ cursor.col = ++field << 3;
+ }
+ tabcol = (cursor.col|7) + 1;
+ strlength = (tabcol - sp->col)*BSlength + 1;
+ /* length of sequence to overshoot */
+ if (((sp->col - cursor.col)*NDlength > strlength) &&
+ (tabcol < COLUMNS)
+ ){
+ /*
+ * Tab past and backup
+ */
+ putpad(TA);
+ cursor.col = (cursor.col | 7) + 1;
+ while(cursor.col > sp->col)bs();
+ }
+ }
+ while (sp->col > cursor.col){
+ nd();
+ }
+}
+
+cr(){
+ outch('\r');
+ cursor.col = 0;
+}
+
+clear(){
+ int i;
+
+ if (CL){
+ putpad(CL);
+ cursor.col=cursor.line=0;
+ } else {
+ for(i=0; i<LINES; i++) {
+ putchar('\n');
+ }
+ cursor.line = LINES - 1;
+ home();
+ }
+}
+
+home(){
+ struct point z;
+
+ if(HO != 0){
+ putpad(HO);
+ cursor.col = cursor.line = 0;
+ return;
+ }
+ z.col = z.line = 0;
+ move(&z);
+}
+
+ll(){
+ int j,l;
+ struct point z;
+
+ l = lcnt + 2;
+ if(LL != NULL && LINES==l){
+ putpad(LL);
+ cursor.line = LINES-1;
+ cursor.col = 0;
+ return;
+ }
+ z.col = 0;
+ z.line = l-1;
+ move(&z);
+}
+
+up(){
+ putpad(UP);
+ cursor.line--;
+}
+
+down(){
+ putpad(DO);
+ cursor.line++;
+ if (cursor.line >= LINES)cursor.line=LINES-1;
+}
+bs(){
+ if (cursor.col > 0){
+ putpad(BS);
+ cursor.col--;
+ }
+}
+
+nd(){
+ putpad(ND);
+ cursor.col++;
+ if (cursor.col == COLUMNS+1){
+ cursor.line++;
+ cursor.col = 0;
+ if (cursor.line >= LINES)cursor.line=LINES-1;
+ }
+}
+
+pch(c)
+{
+ outch(c);
+ if(++cursor.col >= COLUMNS && AM) {
+ cursor.col = 0;
+ ++cursor.line;
+ }
+}
+
+apr(ps, fmt)
+ struct point *ps;
+ char *fmt;
+{
+ struct point p;
+ va_list ap;
+
+ p.line = ps->line+1; p.col = ps->col+1;
+ move(&p);
+ va_start(ap, fmt);
+ (void)vsprintf(str, fmt, ap);
+ va_end(ap);
+ pstring(str);
+}
+
+pr(fmt)
+ char *fmt;
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)vsprintf(str, fmt, ap);
+ va_end(ap);
+ pstring(str);
+}
+
+pstring(s)
+char *s;{
+ struct point z;
+ int stcol;
+
+ stcol = cursor.col;
+ while (s[0] != '\0'){
+ switch (s[0]){
+ case '\n':
+ move(point(&z,0,cursor.line+1));
+ break;
+ case '\r':
+ move(point(&z,stcol,cursor.line+1));
+ break;
+ case '\t':
+ z.col = (((cursor.col + 8) >> 3) << 3);
+ z.line = cursor.line;
+ move(&z);
+ break;
+ case '\b':
+ bs();
+ break;
+ case CTRL('g'):
+ outch(CTRL('g'));
+ break;
+ default:
+ if (s[0] < ' ')break;
+ pch(s[0]);
+ }
+ s++;
+ }
+}
+
+pchar(ps,ch)
+struct point *ps;
+char ch;{
+ struct point p;
+ p.col = ps->col + 1; p.line = ps->line + 1;
+ if (
+ (p.col >= 0) &&
+ (p.line >= 0) &&
+ (
+ (
+ (p.line < LINES) &&
+ (p.col < COLUMNS)
+ ) ||
+ (
+ (p.col == COLUMNS) &&
+ (p.line < LINES-1)
+ )
+ )
+ ){
+ move(&p);
+ pch(ch);
+ }
+}
+
+
+outch(c)
+{
+ putchar(c);
+}
+
+putpad(str)
+char *str;
+{
+ if (str)
+ tputs(str, 1, outch);
+}
+baudrate()
+{
+
+ switch (orig.sg_ospeed){
+ case B300:
+ return(300);
+ case B1200:
+ return(1200);
+ case B4800:
+ return(4800);
+ case B9600:
+ return(9600);
+ default:
+ return(0);
+ }
+}
+delay(t)
+int t;
+{
+ int k,j;
+
+ k = baudrate() * t / 300;
+ for(j=0;j<k;j++){
+ putchar(PC);
+ }
+}
+
+done()
+{
+ cook();
+ exit(0);
+}
+
+cook()
+{
+ delay(1);
+ putpad(TE);
+ putpad(KE);
+ fflush(stdout);
+ stty(0, &orig);
+#ifdef TIOCSLTC
+ ioctl(0, TIOCSLTC, &olttyc);
+#endif
+}
+
+raw()
+{
+ stty(0, &new);
+#ifdef TIOCSLTC
+ ioctl(0, TIOCSLTC, &nlttyc);
+#endif
+}
+
+struct point *point(ps,x,y)
+struct point *ps;
+int x,y;
+{
+ ps->col=x;
+ ps->line=y;
+ return(ps);
+}
+
+char *ap;
+
+getcap()
+{
+ char *getenv();
+ char *term;
+ char *xPC;
+ struct point z;
+ void stop();
+
+ term = getenv("TERM");
+ if (term==0) {
+ fprintf(stderr, "No TERM in environment\n");
+ exit(1);
+ }
+
+ switch (tgetent(tbuf, term)) {
+ case -1:
+ fprintf(stderr, "Cannot open termcap file\n");
+ exit(2);
+ case 0:
+ fprintf(stderr, "%s: unknown terminal", term);
+ exit(3);
+ }
+
+ ap = tcapbuf;
+
+ LINES = tgetnum("li");
+ COLUMNS = tgetnum("co");
+ if (!lcnt)
+ lcnt = LINES - 2;
+ if (!ccnt)
+ ccnt = COLUMNS - 3;
+
+ AM = tgetflag("am");
+ BW = tgetflag("bw");
+
+ ND = tgetstr("nd", &ap);
+ UP = tgetstr("up", &ap);
+
+ DO = tgetstr("do", &ap);
+ if (DO == 0)
+ DO = "\n";
+
+ BS = tgetstr("bc", &ap);
+ if (BS == 0 && tgetflag("bs"))
+ BS = "\b";
+ if (BS)
+ xBC = *BS;
+
+ TA = tgetstr("ta", &ap);
+ if (TA == 0 && tgetflag("pt"))
+ TA = "\t";
+
+ HO = tgetstr("ho", &ap);
+ CL = tgetstr("cl", &ap);
+ CM = tgetstr("cm", &ap);
+ LL = tgetstr("ll", &ap);
+
+ KL = tgetstr("kl", &ap);
+ KR = tgetstr("kr", &ap);
+ KU = tgetstr("ku", &ap);
+ KD = tgetstr("kd", &ap);
+ Klength = strlen(KL);
+ /* NOTE: If KL, KR, KU, and KD are not
+ * all the same length, some problems
+ * may arise, since tests are made on
+ * all of them together.
+ */
+
+ TI = tgetstr("ti", &ap);
+ TE = tgetstr("te", &ap);
+ KS = tgetstr("ks", &ap);
+ KE = tgetstr("ke", &ap);
+
+ xPC = tgetstr("pc", &ap);
+ if (xPC)
+ PC = *xPC;
+
+ NDlength = strlen(ND);
+ BSlength = strlen(BS);
+ if ((CM == 0) &&
+ (HO == 0 | UP==0 || BS==0 || ND==0)) {
+ fprintf(stderr, "Terminal must have addressible ");
+ fprintf(stderr, "cursor or home + 4 local motions\n");
+ exit(5);
+ }
+ if (tgetflag("os")) {
+ fprintf(stderr, "Terminal must not overstrike\n");
+ exit(5);
+ }
+ if (LINES <= 0 || COLUMNS <= 0) {
+ fprintf(stderr, "Must know the screen size\n");
+ exit(5);
+ }
+
+ gtty(0, &orig);
+ new=orig;
+ new.sg_flags &= ~(ECHO|CRMOD|ALLDELAY|XTABS);
+ new.sg_flags |= CBREAK;
+ signal(SIGINT,stop);
+ ospeed = orig.sg_ospeed;
+#ifdef TIOCGLTC
+ ioctl(0, TIOCGLTC, &olttyc);
+ nlttyc = olttyc;
+ nlttyc.t_suspc = '\377';
+ nlttyc.t_dsuspc = '\377';
+#endif
+ raw();
+
+ if ((orig.sg_flags & XTABS) == XTABS) TA=0;
+ putpad(KS);
+ putpad(TI);
+ point(&cursor,0,LINES-1);
+}
diff --git a/snake/snake/pathnames.h b/snake/snake/pathnames.h
new file mode 100644
index 00000000..bf3d5d5d
--- /dev/null
+++ b/snake/snake/pathnames.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.3 (Berkeley) 6/1/90
+ */
+
+#define _PATH_RAWSCORES "/var/games/snakerawscores"
+#define _PATH_LOGFILE "/var/games/snake.log"
diff --git a/snake/snake/snake.6 b/snake/snake/snake.6
new file mode 100644
index 00000000..5251f1a9
--- /dev/null
+++ b/snake/snake/snake.6
@@ -0,0 +1,113 @@
+.\" Copyright (c) 1980 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)snake.6 6.4 (Berkeley) 6/23/90
+.\"
+.TH SNAKE 6 "June 23, 1990"
+.UC 4
+.SH NAME
+snake, snscore \- display chase game
+.SH SYNOPSIS
+.B snake
+[
+.B -w width
+] [
+.B -l length
+]
+.br
+.B snscore
+.SH DESCRIPTION
+Snake is a display-based game which must be played on a CRT terminal.
+The object of the game is to make as much money as possible without
+getting eaten by the snake. The
+.B \-l
+and
+.B \-w
+options allow you to specify the length and width of the field.
+By default the entire screen (except for the last column) is used.
+.PP
+You are represented on the screen by an I.
+The snake is 6 squares long and is represented by S's.
+The money is $, and an exit is #.
+Your score is posted in the upper left hand corner.
+.PP
+You can move around using the same conventions as vi(1),
+the h, j, k, and l keys work, as do the arrow keys.
+Other possibilities include:
+.IP sefc
+These keys are like hjkl but form a directed pad around the d key.
+.IP HJKL
+These keys move you all the way in the indicated direction to the
+same row or column as the money. This does
+.I not
+let you jump away from the snake, but rather saves you from having
+to type a key repeatedly. The snake still gets all his turns.
+.IP SEFC
+Likewise for the upper case versions on the left.
+.IP ATPB
+These keys move you to the four edges of the screen.
+Their position on the keyboard is the mnemonic, e.g.
+P is at the far right of the keyboard.
+.IP x
+This lets you quit the game at any time.
+.IP p
+Points in a direction you might want to go.
+.IP w
+Space warp to get out of tight squeezes, at a price.
+.PP
+To earn money, move to the same square the money is on.
+A new $ will appear when you earn the current one.
+As you get richer, the snake gets hungrier.
+To leave the game, move to the exit (#).
+.PP
+A record is kept of the personal best score of each player.
+Scores are only counted if you leave at the exit,
+getting eaten by the snake is worth nothing.
+.PP
+As in pinball, matching the last digit of your score to the number
+which appears after the game is worth a bonus.
+.PP
+To see who wastes time playing snake, run
+.I snscore .
+.SH FILES
+.nf
+.ta \w'/usr/games/lib/snakerawscores 'u
+/usr/games/lib/snakerawscores database of personal bests
+/usr/games/lib/snake.log log of games played
+.DT
+.fi
+.SH BUGS
+.PP
+When playing on a small screen,
+it's hard to tell when you hit the edge of the screen.
+.PP
+The scoring function takes into account the size of the screen.
+A perfect function to do this equitably has not been devised.
diff --git a/snake/snake/snake.c b/snake/snake/snake.c
new file mode 100644
index 00000000..686465e7
--- /dev/null
+++ b/snake/snake/snake.c
@@ -0,0 +1,890 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)snake.c 5.10 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * snake - crt hack game.
+ *
+ * You move around the screen with arrow keys trying to pick up money
+ * without getting eaten by the snake. hjkl work as in vi in place of
+ * arrow keys. You can leave at the exit any time.
+ *
+ * compile as follows:
+ * cc -O snake.c move.c -o snake -lm -ltermlib
+ */
+
+#include <sys/param.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <errno.h>
+#include "snake.h"
+#include "pathnames.h"
+
+#define PENALTY 10 /* % penalty for invoking spacewarp */
+
+#define EOT '\004'
+#define LF '\n'
+#define DEL '\177'
+
+#define ME 'I'
+#define SNAKEHEAD 'S'
+#define SNAKETAIL 's'
+#define TREASURE '$'
+#define GOAL '#'
+
+#define BSIZE 80
+
+struct point you;
+struct point money;
+struct point finish;
+struct point snake[6];
+
+int loot, penalty;
+int long tl, tm=0L;
+int moves;
+char stri[BSIZE];
+char *p;
+char ch, savec;
+char *kl, *kr, *ku, *kd;
+int fast=1;
+int repeat=1;
+long tv;
+char *tn;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+ extern char *optarg;
+ extern int optind;
+ int ch, i, j, k;
+ time_t time();
+ long atol();
+ void stop();
+
+ (void)time(&tv);
+ srandom((int)tv);
+
+ while ((ch = getopt(argc, argv, "l:w:")) != EOF)
+ switch((char)ch) {
+#ifdef notdef
+ case 'd':
+ tv = atol(optarg);
+ break;
+#endif
+ case 'w': /* width */
+ ccnt = atoi(optarg);
+ break;
+ case 'l': /* length */
+ lcnt = atoi(optarg);
+ break;
+ case '?':
+ default:
+ fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr);
+ exit(1);
+ }
+
+ penalty = loot = 0;
+ getcap();
+
+ i = MIN(lcnt, ccnt);
+ if (i < 4) {
+ cook();
+ pr("snake: screen too small for a fair game.\n");
+ exit(1);
+ }
+
+ /*
+ * chunk is the amount of money the user gets for each $.
+ * The formula below tries to be fair for various screen sizes.
+ * We only pay attention to the smaller of the 2 edges, since
+ * that seems to be the bottleneck.
+ * This formula is a hyperbola which includes the following points:
+ * (24, $25) (original scoring algorithm)
+ * (12, $40) (experimentally derived by the "feel")
+ * (48, $15) (a guess)
+ * This will give a 4x4 screen $99/shot. We don't allow anything
+ * smaller than 4x4 because there is a 3x3 game where you can win
+ * an infinite amount of money.
+ */
+ if (i < 12) i = 12; /* otherwise it isn't fair */
+ /*
+ * Compensate for border. This really changes the game since
+ * the screen is two squares smaller but we want the default
+ * to be $25, and the high scores on small screens were a bit
+ * much anyway.
+ */
+ i += 2;
+ chunk = (675.0 / (i+6)) + 2.5; /* min screen edge */
+
+ signal (SIGINT, stop);
+ putpad(TI); /* String to begin programs that use cm */
+ putpad(KS); /* Put terminal in keypad transmit mode */
+
+ snrand(&finish);
+ snrand(&you);
+ snrand(&money);
+ snrand(&snake[0]);
+
+ if ((orig.sg_ospeed < B9600) ||
+ ((! CM) && (! TA))) fast=0;
+ for(i=1;i<6;i++)
+ chase (&snake[i], &snake[i-1]);
+ setup();
+ mainloop();
+}
+
+/* Main command loop */
+mainloop()
+{
+ int j, k;
+
+ for (;;) {
+ int c,lastc,match;
+
+ move(&you);
+ fflush(stdout);
+ if (((c = getchar() & 0177) <= '9') && (c >= '0')) {
+ ungetc(c,stdin);
+ j = scanf("%d",&repeat);
+ c = getchar() & 0177;
+ } else {
+ if (c != '.') repeat = 1;
+ }
+ if (c == '.') {
+ c = lastc;
+ }
+ if ((Klength > 0) &&
+ (c == *KL || c == *KR || c == *KU || c == *KD)) {
+ savec = c;
+ match = 0;
+ kl = KL;
+ kr = KR;
+ ku = KU;
+ kd = KD;
+ for (j=Klength;j>0;j--){
+ if (match != 1) {
+ match = 0;
+ if (*kl++ == c) {
+ ch = 'h';
+ match++;
+ }
+ if (*kr++ == c) {
+ ch = 'l';
+ match++;
+ }
+ if (*ku++ == c) {
+ ch = 'k';
+ match++;
+ }
+ if (*kd++ == c) {
+ ch = 'j';
+ match++;
+ }
+ if (match == 0) {
+ ungetc(c,stdin);
+ ch = savec;
+ /* Oops!
+ * This works if we figure it out on second character.
+ */
+ break;
+ }
+ }
+ savec = c;
+ if(j != 1) c = getchar() & 0177;
+ }
+ c = ch;
+ }
+ if (!fast) flushi();
+ lastc = c;
+ switch (c){
+ case CTRL('z'):
+ suspend();
+ continue;
+ case EOT:
+ case 'x':
+ case 0177: /* del or end of file */
+ ll();
+ length(moves);
+ logit("quit");
+ done();
+ case CTRL('l'):
+ setup();
+ winnings(cashvalue);
+ continue;
+ case 'p':
+ case 'd':
+ snap();
+ continue;
+ case 'w':
+ spacewarp(0);
+ continue;
+ case 'A':
+ repeat = you.col;
+ c = 'h';
+ break;
+ case 'H':
+ case 'S':
+ repeat = you.col - money.col;
+ c = 'h';
+ break;
+ case 'T':
+ repeat = you.line;
+ c = 'k';
+ break;
+ case 'K':
+ case 'E':
+ repeat = you.line - money.line;
+ c = 'k';
+ break;
+ case 'P':
+ repeat = ccnt - 1 - you.col;
+ c = 'l';
+ break;
+ case 'L':
+ case 'F':
+ repeat = money.col - you.col;
+ c = 'l';
+ break;
+ case 'B':
+ repeat = lcnt - 1 - you.line;
+ c = 'j';
+ break;
+ case 'J':
+ case 'C':
+ repeat = money.line - you.line;
+ c = 'j';
+ break;
+ }
+ for(k=1;k<=repeat;k++){
+ moves++;
+ switch(c) {
+ case 's':
+ case 'h':
+ case '\b':
+ if (you.col >0) {
+ if((fast)||(k == 1))
+ pchar(&you,' ');
+ you.col--;
+ if((fast) || (k == repeat) ||
+ (you.col == 0))
+ pchar(&you,ME);
+ }
+ break;
+ case 'f':
+ case 'l':
+ case ' ':
+ if (you.col < ccnt-1) {
+ if((fast)||(k == 1))
+ pchar(&you,' ');
+ you.col++;
+ if((fast) || (k == repeat) ||
+ (you.col == ccnt-1))
+ pchar(&you,ME);
+ }
+ break;
+ case CTRL('p'):
+ case 'e':
+ case 'k':
+ case 'i':
+ if (you.line > 0) {
+ if((fast)||(k == 1))
+ pchar(&you,' ');
+ you.line--;
+ if((fast) || (k == repeat) ||
+ (you.line == 0))
+ pchar(&you,ME);
+ }
+ break;
+ case CTRL('n'):
+ case 'c':
+ case 'j':
+ case LF:
+ case 'm':
+ if (you.line+1 < lcnt) {
+ if((fast)||(k == 1))
+ pchar(&you,' ');
+ you.line++;
+ if((fast) || (k == repeat) ||
+ (you.line == lcnt-1))
+ pchar(&you,ME);
+ }
+ break;
+ }
+
+ if (same(&you,&money))
+ {
+ char xp[20];
+ struct point z;
+ loot += 25;
+ if(k < repeat)
+ pchar(&you,' ');
+ do {
+ snrand(&money);
+ } while (money.col == finish.col && money.line == finish.line ||
+ money.col < 5 && money.line == 0 ||
+ money.col == you.col && money.line == you.line);
+ pchar(&money,TREASURE);
+ winnings(cashvalue);
+ continue;
+ }
+ if (same(&you,&finish))
+ {
+ win(&finish);
+ ll();
+ cook();
+ pr("You have won with $%d.\n",cashvalue);
+ fflush(stdout);
+ logit("won");
+ post(cashvalue,1);
+ length(moves);
+ done();
+ }
+ if (pushsnake())break;
+ }
+ fflush(stdout);
+ }
+}
+
+setup(){ /*
+ * setup the board
+ */
+ int i;
+
+ clear();
+ pchar(&you,ME);
+ pchar(&finish,GOAL);
+ pchar(&money,TREASURE);
+ for(i=1; i<6; i++) {
+ pchar(&snake[i],SNAKETAIL);
+ }
+ pchar(&snake[0], SNAKEHEAD);
+ drawbox();
+ fflush(stdout);
+}
+
+drawbox()
+{
+ register int i;
+ struct point p;
+
+ p.line = -1;
+ for (i= 0; i<ccnt; i++) {
+ p.col = i;
+ pchar(&p, '-');
+ }
+ p.col = ccnt;
+ for (i= -1; i<=lcnt; i++) {
+ p.line = i;
+ pchar(&p, '|');
+ }
+ p.col = -1;
+ for (i= -1; i<=lcnt; i++) {
+ p.line = i;
+ pchar(&p, '|');
+ }
+ p.line = lcnt;
+ for (i= 0; i<ccnt; i++) {
+ p.col = i;
+ pchar(&p, '-');
+ }
+}
+
+snrand(sp)
+struct point *sp;
+{
+ struct point p;
+ register int i;
+
+ for (;;) {
+ p.col = random() % ccnt;
+ p.line = random() % lcnt;
+
+ /* make sure it's not on top of something else */
+ if (p.line == 0 && p.col < 5)
+ continue;
+ if (same(&p, &you))
+ continue;
+ if (same(&p, &money))
+ continue;
+ if (same(&p, &finish))
+ continue;
+ for (i = 0; i < 5; i++)
+ if (same(&p, &snake[i]))
+ break;
+ if (i < 5)
+ continue;
+ break;
+ }
+ *sp = p;
+}
+
+post(iscore, flag)
+int iscore, flag;
+{
+ short score = iscore;
+ int rawscores;
+ short uid;
+ short oldbest=0;
+ short allbwho=0, allbscore=0;
+ struct passwd *p;
+
+ /*
+ * Neg uid, 0, and 1 cannot have scores recorded.
+ */
+ if ((uid = getuid()) <= 1) {
+ pr("No saved scores for uid %d.\n", uid);
+ return(1);
+ }
+ if ((rawscores = open(_PATH_RAWSCORES, O_RDWR|O_CREAT, 0644)) < 0) {
+ pr("No score file %s: %s.\n", _PATH_RAWSCORES,
+ strerror(errno));
+ return(1);
+ }
+ /* Figure out what happened in the past */
+ read(rawscores, &allbscore, sizeof(short));
+ read(rawscores, &allbwho, sizeof(short));
+ lseek(rawscores, ((long)uid)*sizeof(short), 0);
+ read(rawscores, &oldbest, sizeof(short));
+ if (!flag)
+ return (score > oldbest ? 1 : 0);
+
+ /* Update this jokers best */
+ if (score > oldbest) {
+ lseek(rawscores, ((long)uid)*sizeof(short), 0);
+ write(rawscores, &score, sizeof(short));
+ pr("You bettered your previous best of $%d\n", oldbest);
+ } else
+ pr("Your best to date is $%d\n", oldbest);
+
+ /* See if we have a new champ */
+ p = getpwuid(allbwho);
+ if (p == NULL || score > allbscore) {
+ lseek(rawscores, (long)0, 0);
+ write(rawscores, &score, sizeof(short));
+ write(rawscores, &uid, sizeof(short));
+ if (allbwho)
+ pr("You beat %s's old record of $%d!\n",
+ p->pw_name, allbscore);
+ else
+ pr("You set a new record!\n");
+ } else
+ pr("The highest is %s with $%d\n", p->pw_name, allbscore);
+ close(rawscores);
+ return (1);
+}
+
+/*
+ * Flush typeahead to keep from buffering a bunch of chars and then
+ * overshooting. This loses horribly at 9600 baud, but works nicely
+ * if the terminal gets behind.
+ */
+flushi()
+{
+ stty(0, &new);
+}
+int mx [8] = {
+ 0, 1, 1, 1, 0,-1,-1,-1};
+int my [8] = {
+ -1,-1, 0, 1, 1, 1, 0,-1};
+float absv[8]= {
+ 1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
+};
+int oldw=0;
+chase (np, sp)
+struct point *sp, *np;
+{
+ /* this algorithm has bugs; otherwise the
+ snake would get too good */
+ struct point d;
+ int w, i, wt[8];
+ double sqrt(), v1, v2, vp, max;
+ point(&d,you.col-sp->col,you.line-sp->line);
+ v1 = sqrt( (double) (d.col*d.col + d.line*d.line) );
+ w=0;
+ max=0;
+ for(i=0; i<8; i++)
+ {
+ vp = d.col*mx[i] + d.line*my[i];
+ v2 = absv[i];
+ if (v1>0)
+ vp = ((double)vp)/(v1*v2);
+ else vp=1.0;
+ if (vp>max)
+ {
+ max=vp;
+ w=i;
+ }
+ }
+ for(i=0; i<8; i++)
+ {
+ point(&d,sp->col+mx[i],sp->line+my[i]);
+ wt[i]=0;
+ if (d.col<0 || d.col>=ccnt || d.line<0 || d.line>=lcnt)
+ continue;
+ /*
+ * Change to allow snake to eat you if you're on the money,
+ * otherwise, you can just crouch there until the snake goes
+ * away. Not positive it's right.
+ *
+ * if (d.line == 0 && d.col < 5) continue;
+ */
+ if (same(&d,&money)) continue;
+ if (same(&d,&finish)) continue;
+ wt[i]= i==w ? loot/10 : 1;
+ if (i==oldw) wt [i] += loot/20;
+ }
+ for(w=i=0; i<8; i++)
+ w+= wt[i];
+ vp = (( rand() >> 6 ) & 01777) %w;
+ for(i=0; i<8; i++)
+ if (vp <wt[i])
+ break;
+ else
+ vp -= wt[i];
+ if (i==8) {
+ pr("failure\n");
+ i=0;
+ while (wt[i]==0) i++;
+ }
+ oldw=w=i;
+ point(np,sp->col+mx[w],sp->line+my[w]);
+}
+
+spacewarp(w)
+int w;{
+ struct point p;
+ int j;
+ char *str;
+
+ snrand(&you);
+ point(&p,COLUMNS/2 - 8,LINES/2 - 1);
+ if (p.col < 0)
+ p.col = 0;
+ if (p.line < 0)
+ p.line = 0;
+ if (w) {
+ str = "BONUS!!!";
+ loot = loot - penalty;
+ penalty = 0;
+ } else {
+ str = "SPACE WARP!!!";
+ penalty += loot/PENALTY;
+ }
+ for(j=0;j<3;j++){
+ clear();
+ delay(5);
+ apr(&p,str);
+ delay(10);
+ }
+ setup();
+ winnings(cashvalue);
+}
+snap()
+{
+ struct point p;
+ int i;
+
+ if(you.line < 3){
+ pchar(point(&p,you.col,0),'-');
+ }
+ if(you.line > lcnt-4){
+ pchar(point(&p,you.col,lcnt-1),'_');
+ }
+ if(you.col < 10){
+ pchar(point(&p,0,you.line),'(');
+ }
+ if(you.col > ccnt-10){
+ pchar(point(&p,ccnt-1,you.line),')');
+ }
+ if (! stretch(&money)) if (! stretch(&finish)) delay(10);
+ if(you.line < 3){
+ point(&p,you.col,0);
+ chk(&p);
+ }
+ if(you.line > lcnt-4){
+ point(&p,you.col,lcnt-1);
+ chk(&p);
+ }
+ if(you.col < 10){
+ point(&p,0,you.line);
+ chk(&p);
+ }
+ if(you.col > ccnt-10){
+ point(&p,ccnt-1,you.line);
+ chk(&p);
+ }
+ fflush(stdout);
+}
+stretch(ps)
+struct point *ps;{
+ struct point p;
+
+ point(&p,you.col,you.line);
+ if(abs(ps->col-you.col) < 6){
+ if(you.line < ps->line){
+ for (p.line = you.line+1;p.line <= ps->line;p.line++)
+ pchar(&p,'v');
+ delay(10);
+ for (;p.line > you.line;p.line--)
+ chk(&p);
+ } else {
+ for (p.line = you.line-1;p.line >= ps->line;p.line--)
+ pchar(&p,'^');
+ delay(10);
+ for (;p.line < you.line;p.line++)
+ chk(&p);
+ }
+ return(1);
+ } else if(abs(ps->line-you.line) < 3){
+ p.line = you.line;
+ if(you.col < ps->col){
+ for (p.col = you.col+1;p.col <= ps->col;p.col++)
+ pchar(&p,'>');
+ delay(10);
+ for (;p.col > you.col;p.col--)
+ chk(&p);
+ } else {
+ for (p.col = you.col-1;p.col >= ps->col;p.col--)
+ pchar(&p,'<');
+ delay(10);
+ for (;p.col < you.col;p.col++)
+ chk(&p);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+surround(ps)
+struct point *ps;{
+ struct point x;
+ int i,j;
+
+ if(ps->col == 0)ps->col++;
+ if(ps->line == 0)ps->line++;
+ if(ps->line == LINES -1)ps->line--;
+ if(ps->col == COLUMNS -1)ps->col--;
+ apr(point(&x,ps->col-1,ps->line-1),"/*\\\r* *\r\\*/");
+ for (j=0;j<20;j++){
+ pchar(ps,'@');
+ delay(1);
+ pchar(ps,' ');
+ delay(1);
+ }
+ if (post(cashvalue,0)) {
+ apr(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/");
+ delay(6);
+ apr(point(&x,ps->col-1,ps->line-1)," \ro.-\r\\_/");
+ delay(6);
+ }
+ apr(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/");
+}
+win(ps)
+struct point *ps;
+{
+ struct point x;
+ int j,k;
+ int boxsize; /* actually diameter of box, not radius */
+
+ boxsize = fast ? 10 : 4;
+ point(&x,ps->col,ps->line);
+ for(j=1;j<boxsize;j++){
+ for(k=0;k<j;k++){
+ pchar(&x,'#');
+ x.line--;
+ }
+ for(k=0;k<j;k++){
+ pchar(&x,'#');
+ x.col++;
+ }
+ j++;
+ for(k=0;k<j;k++){
+ pchar(&x,'#');
+ x.line++;
+ }
+ for(k=0;k<j;k++){
+ pchar(&x,'#');
+ x.col--;
+ }
+ }
+ fflush(stdout);
+}
+
+pushsnake()
+{
+ int i, bonus;
+ int issame = 0;
+
+ /*
+ * My manual says times doesn't return a value. Furthermore, the
+ * snake should get his turn every time no matter if the user is
+ * on a fast terminal with typematic keys or not.
+ * So I have taken the call to times out.
+ */
+ for(i=4; i>=0; i--)
+ if (same(&snake[i], &snake[5]))
+ issame++;
+ if (!issame)
+ pchar(&snake[5],' ');
+ for(i=4; i>=0; i--)
+ snake[i+1]= snake[i];
+ chase(&snake[0], &snake[1]);
+ pchar(&snake[1],SNAKETAIL);
+ pchar(&snake[0],SNAKEHEAD);
+ for(i=0; i<6; i++)
+ {
+ if (same(&snake[i],&you))
+ {
+ surround(&you);
+ i = (cashvalue) % 10;
+ bonus = ((rand()>>8) & 0377)% 10;
+ ll();
+ pr("%d\n", bonus);
+ delay(30);
+ if (bonus == i) {
+ spacewarp(1);
+ logit("bonus");
+ flushi();
+ return(1);
+ }
+ if ( loot >= penalty ){
+ pr("You and your $%d have been eaten\n",
+ cashvalue);
+ } else {
+ pr("The snake ate you. You owe $%d.\n",
+ -cashvalue);
+ }
+ logit("eaten");
+ length(moves);
+ done();
+ }
+ }
+ return(0);
+}
+
+chk(sp)
+struct point *sp;
+{
+ int j;
+
+ if (same(sp,&money)) {
+ pchar(sp,TREASURE);
+ return(2);
+ }
+ if (same(sp,&finish)) {
+ pchar(sp,GOAL);
+ return(3);
+ }
+ if (same(sp,&snake[0])) {
+ pchar(sp,SNAKEHEAD);
+ return(4);
+ }
+ for(j=1;j<6;j++){
+ if(same(sp,&snake[j])){
+ pchar(sp,SNAKETAIL);
+ return(4);
+ }
+ }
+ if ((sp->col < 4) && (sp->line == 0)){
+ winnings(cashvalue);
+ if((you.line == 0) && (you.col < 4)) pchar(&you,ME);
+ return(5);
+ }
+ if (same(sp,&you)) {
+ pchar(sp,ME);
+ return(1);
+ }
+ pchar(sp,' ');
+ return(0);
+}
+winnings(won)
+int won;
+{
+ struct point p;
+
+ p.line = p.col = 1;
+ if(won>0){
+ move(&p);
+ pr("$%d",won);
+ }
+}
+
+void
+stop(){
+ signal(SIGINT,SIG_IGN);
+ ll();
+ length(moves);
+ done();
+}
+
+suspend()
+{
+ char *sh;
+
+ ll();
+ cook();
+ kill(getpid(), SIGTSTP);
+ raw();
+ setup();
+ winnings(cashvalue);
+}
+
+length(num)
+int num;
+{
+ pr("You made %d moves.\n",num);
+}
+
+logit(msg)
+char *msg;
+{
+ FILE *logfile;
+ long t;
+
+ if ((logfile=fopen(_PATH_LOGFILE, "a")) != NULL) {
+ time(&t);
+ fprintf(logfile, "%s $%d %dx%d %s %s",
+ getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
+ fclose(logfile);
+ }
+}
diff --git a/snake/snake/snake.h b/snake/snake/snake.h
new file mode 100644
index 00000000..f8e7fd88
--- /dev/null
+++ b/snake/snake/snake.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)snake.h 5.5 (Berkeley) 6/1/90
+ */
+
+# include <stdio.h>
+# include <assert.h>
+# include <sys/types.h>
+# include <sgtty.h>
+# include <signal.h>
+# include <math.h>
+
+#define ESC '\033'
+
+struct tbuffer {
+ long t[4];
+} tbuffer;
+
+char *CL, *UP, *DO, *ND, *BS,
+ *HO, *CM,
+ *TA, *LL,
+ *KL, *KR, *KU, *KD,
+ *TI, *TE, *KS, *KE;
+int LINES, COLUMNS; /* physical screen size. */
+int lcnt, ccnt; /* user's idea of screen size */
+char xBC, PC;
+int AM, BW;
+char tbuf[1024], tcapbuf[128];
+char *tgetstr(), *tgoto();
+int Klength; /* length of KX strings */
+int chunk; /* amount of money given at a time */
+#ifdef debug
+#define cashvalue (loot-penalty)/25
+#else
+#define cashvalue chunk*(loot-penalty)/25
+#endif
+
+struct point {
+ int col, line;
+};
+struct point cursor;
+struct sgttyb orig, new;
+#ifdef TIOCLGET
+struct ltchars olttyc, nlttyc;
+#endif
+struct point *point();
+
+#define same(s1, s2) ((s1)->line == (s2)->line && (s1)->col == (s2)->col)
+
diff --git a/snake/snscore/Makefile b/snake/snscore/Makefile
new file mode 100644
index 00000000..3310300b
--- /dev/null
+++ b/snake/snscore/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 5.2 (Berkeley) 2/28/91
+
+PROG= snscore
+CFLAGS+=-I${.CURDIR}/../snake
+NOMAN= noman
+HIDEGAME=hidegame
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/snake/snscore/snscore.c b/snake/snscore/snscore.c
new file mode 100644
index 00000000..2dc09178
--- /dev/null
+++ b/snake/snscore/snscore.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)snscore.c 5.7 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "pathnames.h"
+
+char *recfile = _PATH_RAWSCORES;
+#define MAXPLAYERS 256
+
+struct player {
+ short uids;
+ short scores;
+ char *name;
+} players[MAXPLAYERS], temp;
+
+main()
+{
+ char buf[80], cp;
+ short uid, score;
+ FILE *fd;
+ int noplayers;
+ int i, j, notsorted;
+ short whoallbest, allbest;
+ char *q;
+ struct passwd *p;
+
+ fd = fopen(recfile, "r");
+ if (fd == NULL) {
+ perror(recfile);
+ exit(1);
+ }
+ printf("Snake players scores to date\n");
+ fread(&whoallbest, sizeof(short), 1, fd);
+ fread(&allbest, sizeof(short), 1, fd);
+ for (uid=2;;uid++) {
+ if(fread(&score, sizeof(short), 1, fd) == 0)
+ break;
+ if (score > 0) {
+ if (noplayers > MAXPLAYERS) {
+ printf("too many players\n");
+ exit(2);
+ }
+ players[noplayers].uids = uid;
+ players[noplayers].scores = score;
+ p = getpwuid(uid);
+ if (p == NULL)
+ continue;
+ q = p -> pw_name;
+ players[noplayers].name = malloc(strlen(q)+1);
+ strcpy(players[noplayers].name, q);
+ noplayers++;
+ }
+ }
+
+ /* bubble sort scores */
+ for (notsorted=1; notsorted; ) {
+ notsorted = 0;
+ for (i=0; i<noplayers-1; i++)
+ if (players[i].scores < players[i+1].scores) {
+ temp = players[i];
+ players[i] = players[i+1];
+ players[i+1] = temp;
+ notsorted++;
+ }
+ }
+
+ j = 1;
+ for (i=0; i<noplayers; i++) {
+ printf("%d:\t$%d\t%s\n", j, players[i].scores, players[i].name);
+ if (players[i].scores > players[i+1].scores)
+ j = i+2;
+ }
+ exit(0);
+}
diff --git a/trek/DOC/read_me.nr b/trek/DOC/read_me.nr
new file mode 100644
index 00000000..226b8ffd
--- /dev/null
+++ b/trek/DOC/read_me.nr
@@ -0,0 +1,251 @@
+.de @h
+'sp 4
+'tl 'TREK SETUP INSTRUCTIONS''%'
+'sp 2
+.ns
+..
+.de @f
+'bp
+..
+.wh 0 @h
+.wh -6 @f
+.de pp
+.sp
+.ne 2
+.ti +5
+..
+.de s1
+.sp 2
+.nr S1 +1
+.nr S2 0
+.ne 5
+.in 4
+.ti 0
+\\n(S1.\ \ \c
+..
+.de s2
+.sp 1
+.nr S2 +1
+.ne 3
+.in 8
+.ti 4
+\\n(S2.\ \ \c
+..
+.br
+.ce
+TREK SETUP INSTRUCTIONS
+.sp 2
+.pp
+This document describes all sorts of nifty things
+you should know
+before you start to muck around
+with the trek source code.
+Please read them carefully.
+.s1
+MAINTENANCE
+.s2
+There are a number of shell files
+which you may use to maintain the system.
+"Prtrek" produces a copy of the source code.
+It pipes its output to lpr
+and runs in background.
+"Comp" compiles up to nine source modules
+and leaves them in .o files.
+"Compile" is the same as "comp"
+except that it loads after compiling.
+If stated without any arguments,
+it loads from .o files.
+"Compall" compiles all the .c files
+into .o files,
+but does not load.
+It redirects its output to the file "output".
+To recompile the entire system,
+type
+.ti +8
+compall
+.ti +8
+compile
+.br
+.s2
+Main.c contains a variable called "Mother".
+This is initialized to the result of the
+"getuid()" call for the maintainer of trek
+at your installation.
+Only Mother is allowed to set trace flags
+and run the game at other than the default priority.
+.s2
+Speaking of priorities,
+trek eats up a lot of system resources.
+Hence, it normally runs at a very low priority.
+This makes it almost impossible to play
+if the system is loaded.
+However,
+the -pN flag sets the priority to N,
+which makes it possible to debug
+when the system is loaded.
+The default priority is set by a #define of
+PRIO,
+which is set to 10 in the default system.
+.s2
+Trace information is provided
+which may be useful in debugging things in the system.
+If you are in a bad way for space,
+comment out the #define xTRACE
+which appears in trek.h.
+This will cause the trace stuff to not occur
+in the object.
+.s2
+The version of trek released to you
+is compiled with the -f flag (for no floating point)
+and should work without problems on your machine.
+You can edit out the -f flag
+in "compile" if you have floating point hardware
+on your machine
+so that it will take less space.
+.s1
+THE PORTABLE C LIBRARY
+.pp
+The portable C library was used
+to do I/O in trek.
+Unfortunately,
+the version which we had at Berkeley
+had a number of small bugs
+which caused trek to do bad things at times.
+For some unknown reason
+(temporary insanity perhaps)
+I rewrote the portable C library.
+This version is much smaller than the old version
+and has cleaner code.
+It also works right
+(???).
+However, there are a few minor differences
+which you should be aware of.
+.s2
+Scanf no longer ignores the noise characters "\\n",
+"\\t", and space in the format string;
+i.e.,
+these characters now require a match
+in the input stream.
+.s2
+A variable
+f_log
+has been added
+which is the file descriptor
+of a "log" file.
+If f_log is greater than zero
+a copy of everything read from
+the standard input
+and written to
+the standard output
+is written in the file f_log.
+.s1
+DISCLAIMERS
+.s2
+Frankly,
+I am getting pretty sick of playing this game.
+Hence,
+the version which you get may have several bugs
+in it;
+I freely admit
+that it is probably buggier
+than some previous versions.
+Sorry about that.
+.s2
+Along with being buggy,
+the game never had quite everything implemented
+that was originally intended.
+If you see things that look weird,
+that may be why.
+There are even some features which I have taken out
+(like ghost starsystems)
+upon deciding that I didn't have the energy
+to implement them correctly.
+.s1
+REQUESTS
+.pp
+There are several things that I would like to ask of anyone
+who does work on the source code.
+.s2
+Please let me know of any bugs which you find
+in the code,
+and any fixes which you may have.
+Other copies will probably be going out to other people later,
+and it would be nice if those copies where less buggy.
+Also,
+I would be interested in hearing about any
+enhancements of the game which you might install.
+.s2
+Please note that I have a distinct coding style.
+I feel that it is cleaner
+and easier to read than a more
+casual style.
+If possible,
+please stick to it,
+especially if you end up sending tapes back to me.
+This goes along with my whole belief in clean code:
+I ask you to please avoid obscure code
+whenever possible.
+If you throw some in,
+please don't let me see it.
+It just depresses me.
+.s2
+Unfortunately,
+the game is huge.
+There are many neat things
+which could go in,
+if there were only enough space.
+However,
+I have specifically not gone to seperated I/D
+space.
+The main reason is that I would like future versions
+of the game
+to be 11/40 compatible.
+.s1
+SUGGESTIONS FOR THE FUTURE
+.pp
+If you happen to have more energy than I do,
+you may want to examine the following areas.
+These are things that I may get to,
+but don't hold your breath.
+.s2
+Frankly,
+making the portable C library work
+(even without bugs)
+was a bitch.
+I should have done the I/O in a more
+ad hoc manner.
+It is my intent to rewrite the I/O
+routines to bypass the portable C library entirely.
+.s2
+The routine "capture" is quite unclean.
+First, it should have a manner of selecting Klingons
+other than random,
+either selecting the most likely
+or asking the captain (probably best).
+It should either be fully implemented,
+which includes adding a "board" routine
+(half written,
+on some tapes as board.x)
+which sends a boarding party to forcefully
+take over the Klingon,
+or it should go out completely,
+which is probably what I will end up doing.
+When this happens,
+the transporter will go completely.
+It seems that the space may be better used
+for something which more directly enhances the game.
+.sp 3
+.in 0
+Well, that's about it.
+To get hold of me,
+write to:
+.nf
+.sp
+Eric P Allman
+Electronics Research Laboratory
+University of California
+Berkeley, California 94720
+.fi
+
+Happy trekking!!
+.pp
diff --git a/trek/DOC/things b/trek/DOC/things
new file mode 100644
index 00000000..535a0c97
--- /dev/null
+++ b/trek/DOC/things
@@ -0,0 +1,10 @@
+* tractor beams
+* power distribution
+* Romulans:
+- plasma bolts
+- neutral zone
+- cloaking device
+* the thing
+* ion storms
+* torpedoes with time delays
+* Put removal from event list into killk
diff --git a/trek/DOC/trekmanual.nr b/trek/DOC/trekmanual.nr
new file mode 100644
index 00000000..33ead488
--- /dev/null
+++ b/trek/DOC/trekmanual.nr
@@ -0,0 +1,895 @@
+.br
+.po 10
+.if n \!.
+.sp 15
+.tr ^ \"
+.ce 88
+^****^^^^*****^^^^^^*^^^^^^****^
+*^^^^^^^^^^*^^^^^^^*^*^^^^^*^^^*
+^***^^^^^^^*^^^^^^*****^^^^****^
+^^^^*^^^^^^*^^^^^^*^^^*^^^^*^^*^
+****^^^^^^^*^^^^^^*^^^*^^^^*^^^*
+
+
+*****^^^^****^^^^^*****^^^^*^^^*
+^^*^^^^^^*^^^*^^^^*^^^^^^^^*^^*^
+^^*^^^^^^****^^^^^***^^^^^^***^^
+^^*^^^^^^*^^*^^^^^*^^^^^^^^*^^*^
+^^*^^^^^^*^^^*^^^^*****^^^^*^^^*
+
+
+by
+
+Eric Allman
+University of California
+Berkeley
+.ce 0
+.tr ^^
+.de HE
+'sp 4
+'tl 'STAR TREK''%'
+'sp 3
+..
+.de FO
+'bp
+..
+.wh 0 HE
+.wh -5 FO
+.de pp
+.sp
+.ti +4
+..
+.bp 1
+.ce
+INTRODUCTION
+.pp
+Well, the federation is once again at war with the Klingon empire.
+It is up to you,
+as captain of the U.S.S. Enterprise,
+to wipe out the invasion fleet and save the Federation.
+.pp
+For the purposes of the game
+the galaxy is divided into 64 quadrants
+on an eight by eight grid,
+with quadrant 0,0 in the upper left hand corner.
+Each quadrant is divided into 100 sectors
+on a ten by ten grid.
+Each sector contains one object
+(e.g., the Enterprise, a Klingon, or a star).
+.pp
+Navigation is handled in degrees,
+with zero being straight up
+and ninty being to the right.
+Distances are measured in quadrants.
+One tenth quadrant is one sector.
+.pp
+The galaxy contains starbases,
+at which you can dock to refuel,
+repair damages, etc.
+The galaxy also contains stars.
+Stars usually have a knack for getting in your way,
+but they can be triggered into going nova
+by shooting a photon torpedo at one,
+thereby (hopefully) destroying any adjacent Klingons.
+This is not a good practice however,
+because you are penalized for destroying stars.
+Also, a star will sometimes go supernova,
+which obliterates an entire quadrant.
+You must never stop in a supernova quadrant,
+although you may "jump over" one.
+.pp
+Some starsystems
+have inhabited planets.
+Klingons can attack inhabited planets
+and enslave the populace,
+which they then put to work building more Klingon battle cruisers.
+.bp
+.ce
+STARTING UP THE GAME
+.pp
+To request the game, issue the command
+.sp
+.ti +12
+/usr/games/trek
+.sp
+from the shell.
+If a filename is stated,
+a log of the game is written
+onto that file.
+If omitted,
+the file is not written.
+If the "-a" flag is stated before the filename,
+that file is appended to
+rather than created.
+.pp
+The game will ask you what length game
+you would like.
+Valid responses are "short", "medium", and "long".
+Ideally the length of the game does not
+affect the difficulty,
+but currently the shorter games
+tend to be harder than the longer ones.
+You may also type "restart",
+which restarts a previously saved game.
+.pp
+You will then be prompted for the skill,
+to which you must respond
+"novice", "fair", "good", "expert",
+"commadore", or "impossible".
+You should start out with a novice
+and work up,
+but if you really want to see how fast
+you can be slaughtered,
+start out with an impossible game.
+.pp
+In general,
+throughout the game,
+if you forget what is appropriate
+the game will tell you what it expects
+if you just type in
+a question mark.
+.pp
+To get a copy of these rules,
+execute the command
+.sp
+.ti +12
+nroff /usr/games/trekmanual.nr
+.sp
+.bp
+.ce
+ISSUING COMMANDS
+.pp
+If the game expects you to enter a command,
+.hc ^
+it will say ^"Command:\ "
+and wait for your response.
+Most commands can be abbreviated.
+.pp
+At almost any time you can type more than one thing on a line.
+For example,
+to move straight up one quadrant,
+you can type
+.ti +12
+move 0 1
+.br
+or you could just type
+.ti +12
+move
+.br
+and the game would prompt you with
+.ti +12
+Course:
+.br
+to which you could type
+.ti +12
+0 1
+.br
+The "1" is the distance,
+which could be put on still another line.
+Also, the "move" command
+could have been abbreviated
+"mov", "mo", or just "m".
+.pp
+If you are partway through a command
+and you change your mind,
+you can usually type "-1"
+to cancel the command.
+.pp
+Klingons generally cannot hit you
+if you don't consume anything
+(e.g., time or energy),
+so some commands are considered "free".
+As soon as you consume anything though -- POW!
+.bp
+.de **
+.if \\n+l .**
+.as x *
+..
+.de bl
+.nr l \\w'\\$1' -\\w'*'
+.ds x ****
+.**
+.sp 3
+.ne 3
+\\*x
+.br
+.if t *\h'\w'*'u'\fB\\$1\fP\h'\w'*'u'*
+.if n * \\$1 *
+.br
+\\*x
+.sp
+.in +8
+.nf
+..
+.de FF
+.in -8
+.fi
+..
+.if !\n(.V .ta \w'Full Commands: '+1
+.if \n(.V .ta \w'Full Commands: 'u
+.ce
+THE COMMANDS
+.bl "Short Range Scan"
+Mnemonic: srscan
+Shortest Appreviation: s
+Full Commands: srscan
+ srscan yes/no
+Consumes: nothing
+.FF
+.pp
+The short range scan
+gives you a picture
+of the quadrant you are in,
+and (if you say "yes")
+a status report
+which tells you
+a whole bunch
+of interesting stuff.
+You can get a status report alone
+by using the
+.ul
+status
+command.
+An example follows:
+.sp
+.nf
+.in +4
+Short range sensor scan
+ 0 1 2 3 4 5 6 7 8 9
+0 . . . . . . . * . * 0 stardate 3702.16
+1 . . E . . . . . . . 1 condition RED
+2 . . . . . . . . . * 2 position 0,3/1,2
+3 * . . . . # . . . . 3 warp factor 5.0
+4 . . . . . . . . . . 4 total energy 4376
+5 . . * . * . . . . . 5 torpedoes 9
+6 . . . @ . . . . . 6 shields down, 78%
+7 . . . . . . . . . . 7 Klingons left 3
+8 . . . K . . . . . . 8 time left 6.43
+9 . . . . . . * . . . 9 life support damaged, reserves = 2.4
+ 0 1 2 3 4 5 6 7 8 9
+Distressed Starsystem Marcus XII
+
+.in +8
+.ti -8
+The cast of characters is as follows:
+E the hero
+K the villain
+# the starbase
+* stars
+@ inhabited starsystem
+\&. empty space
+ a black hole
+.in -12
+.fi
+.pp
+The name of the starsystem is listed underneath
+the short range scan.
+The word "distressed", if present,
+means that the starsystem
+is under attack.
+.pp
+Short range scans are absolutely free.
+They use no time, no energy,
+and they don't give the Klingons
+another chance to hit you.
+.bl "Status Report"
+Mnemonic: status
+Shortest Abbreviation: st
+Consumes: nothing
+.FF
+.pp
+This command gives you information
+about the current status
+of the game and your ship, as follows:
+.in +8
+.de qq
+.sp
+.ti -4
+..
+.qq
+Stardate -- The current stardate.
+.qq
+Condition -- as follows:
+.in +4
+.nf
+RED -- in battle
+YELLOW -- low on energy
+GREEN -- normal state
+DOCKED -- docked at starbase
+CLOAKED -- the cloaking device is activated
+.fi
+.in -4
+.qq
+Position -- Your current quadrant and sector.
+.qq
+Warp Factor -- The speed you will move at
+when you move under warp power
+(with the
+.ul
+move
+command).
+.qq
+Total Energy -- Your energy reserves.
+If they drop to zero,
+you die.
+Energy regenerates,
+but the higher the skill of the game,
+the slower it regenerates.
+.qq
+Torpedoes -- How many photon torpedoes you have left.
+.qq
+Shields -- Whether your shields are up or down,
+and how effective they are if up
+(what percentage of a hit they will absorb).
+.qq
+Klingons Left -- Guess.
+.qq
+Time Left -- How long the Federation can hold out
+if you sit on your fat ass and do nothing.
+If you kill Klingons quickly,
+this number goes up,
+otherwise,
+it goes down.
+If it hits zero,
+the Federation is conquered.
+.qq
+Life Support -- If "active", everything is fine.
+If "damaged", your reserves tell you
+how long you have
+to repair your life support
+or get to a starbase
+before you starve, suffocate,
+or something equally unpleasant.
+.qq
+Current Crew -- The number of crew members
+left.
+This figures does not include officers.
+.qq
+Brig Space -- The space left in your brig
+for Klingon captives.
+.qq
+Klingon Power -- The number of units
+needed to kill a Klingon.
+Remember, as Klingons fire at you
+they use up their own energy,
+so you probably need somewhat less
+than this.
+.qq
+Skill, Length -- The skill and length
+of the game you are playing.
+.in -8
+.pp
+Status information is absolutely free.
+.bl "Long Range Scan"
+Mnemonic: lrscan
+Shortest Abbreviation: l
+Consumes: nothing
+.FF
+.pp
+Long range scan gives you information about the
+eight quadrants
+that surround the quadrant
+you're in.
+A sample long range scan follows:
+.sp
+.in +12
+.nf
+Long range scan for quadrant 0,3
+
+ 2 3 4
+ -------------------
+ ! * ! * ! * !
+ -------------------
+0 ! 108 ! 6 ! 19 !
+ -------------------
+1 ! 9 ! /// ! 8 !
+ -------------------
+.sp
+.in -12
+.fi
+.pp
+The three digit numbers
+tell the number of objects
+in the quadrants.
+The units digit tells the number of stars,
+the tens digit the number of starbases,
+and the hundreds digit is the number of Klingons.
+"*" indicates the negative energy barrier
+at the edge of the galaxy,
+which you cannot enter.
+"///" means that that is a supernova quadrant
+and must not be entered.
+.bl "Damage Report"
+Mnemonic: damages
+Shortest Abbreviation: da
+Consumes: nothing
+.FF
+.pp
+A damage report tells you what devices are damaged
+and how long it will take to repair them.
+Repairs proceed faster
+when you are docked
+at a starbase.
+.bl "Set Warp Factor"
+Mnemonic: warp
+Shortest Abbreviation: w
+Full Command: warp factor
+Consumes: nothing
+.FF
+.pp
+The warp factor tells the speed of your starship
+when you move under warp power
+(with the
+.ul
+move
+command).
+The higher the warp factor,
+the faster you go,
+and the more energy you use.
+.pp
+The minimum warp factor is 1.0
+and the maximum is 10.0.
+At speeds above warp 6
+there is danger of the warp engines
+being damaged.
+The probability of this
+increases at higher warp speeds.
+Above warp 9.0 there is a chance of entering
+a time warp.
+.bl "Move Under Warp Power"
+Mnemonic: move
+Shortest Abbreviation: m
+Full Command: move course distance
+Consumes: time and energy
+.FF
+.pp
+This is the usual way of moving.
+The course is in degrees and the distance is in quadrants.
+To move one sector specify a distance of 0.1.
+.pp
+Time is consumed proportionately to
+the inverse of the warp factor squared,
+and directly to the distance.
+Energy is consumed as the warp factor cubed,
+and directly to the distance.
+If you move with your shields up
+it doubles the amount of energy consumed.
+.pp
+When you move in a quadrant containing Klingons,
+they get a chance to attack you.
+.pp
+The computer detects navigation errors.
+If the computer is out,
+you run the risk of running into things.
+.pp
+The course is determined by the
+Space Inertial Navigation System
+[SINS].
+As described in
+Star Fleet Technical Order TO:02:06:12,
+the SINS is calibrated,
+after which it becomes the base for navigation.
+If damaged,
+navigation becomes inaccurate.
+When it is fixed,
+Spock recalibrates it,
+however,
+it cannot be calibrated extremely accurately
+until you dock at starbase.
+.bl "Move Under Impulse Power"
+Mnemonic: impulse
+Shortest Abbreviation: i
+Full Command: impulse course distance
+Consumes: time and energy
+.FF
+.pp
+The impulse engines give you a chance to maneuver
+when your warp engines are damaged;
+however, they are incredibly slow
+(0.095 quadrants/stardate).
+They require 20 units of energy to engage,
+and ten units per sector to move.
+.pp
+The same comments about the computer and the SINS
+apply as above.
+.pp
+There is no penalty to move under impulse power
+with shields up.
+.bl "Deflector Shields"
+Mnemonic: shields
+Shortest Abbreviation: sh
+Full Command: shields up/down
+Consumes: energy
+.FF
+.pp
+Shields protect you from Klingon attack
+and nearby novas.
+As they protect you,
+they weaken.
+A shield which is 78% effective
+will absorb 78% of a hit
+and let 22% in to hurt you.
+.pp
+The Klingons have a chance to attack you
+every time you raise or lower shields.
+Shields do not rise and lower
+instantaneously,
+so the hit you receive
+will be computed with the shields
+at an intermediate effectiveness.
+.pp
+It takes energy to raise shields,
+but not to drop them.
+.bl "Cloaking Device"
+Mnemonic: cloak
+Shortest Abbreviation: cl
+Full Command: cloak up/down
+Consumes: energy
+.FF
+.pp
+When you are cloaked,
+Klingons cannot see you,
+and hence they do not fire at you.
+They are useful for entering
+a quadrant
+and selecting a good position,
+however,
+weapons cannot be fired through
+the cloak
+due to the huge energy drain
+that it requires.
+.pp
+The cloak up command
+only starts the cloaking process;
+Klingons will continue
+to fire at you
+until you do something
+which consumes time.
+.bl "Fire Phasers"
+Mnmemonic: phasers
+Shortest Abbreviation: p
+Full Commands: phasers automatic amount
+ phasers manual amt1 course1 spread1 ...
+Consumes: energy
+.FF
+.pp
+Phasers are energy weapons;
+the energy comes from your ship's reserves
+("total energy" on a srscan).
+It takes about 250 units of hits
+to kill a Klingon.
+Hits are cumulative as long as you stay
+in the quadrant.
+.pp
+Phasers become less effective
+the further from a Klingon you are.
+Adjacent Klingons receive about
+90% of what you fire,
+at five sectors about 60%,
+and at ten sectors about 35%.
+They have no effect outside of the quadrant.
+.pp
+Phasers cannot be fired while shields are up;
+to do so would fry you.
+They have no effect on starbases or stars.
+.pp
+In automatic mode
+the computer decides how to divide up the energy
+among the Klingons present;
+in manual mode you do that yourself.
+.pp
+In manual mode firing
+you specify a direction,
+amount (number of units to fire)
+and spread (0 -> 1.0)
+for each of the six phaser banks.
+A zero amount
+terminates the manual input.
+.bl "Fire Photon Torpedoes"
+Mnemonic: torpedo
+Shortest Abbreviation: t
+Full Command: torpedo course [yes/no] [burst angle]
+Consumes: torpedoes
+.FF
+.pp
+Torpedoes are projectile weapons -- there are no partial hits.
+You either hit your target or you don't.
+A hit on a Klingon destroys him.
+A hit on a starbase destroys that starbase
+(woops!).
+Hitting a star usually causes it to go nova,
+and occasionally supernova.
+.pp
+Photon torpedoes cannot be aimed precisely.
+They can be fired with shields up,
+but they get even more random
+as they pass through the shields.
+.pp
+Torpedoes may be fired in bursts of three.
+If this is desired,
+the burst angle is the angle
+between the three shots,
+which may vary from one to fifteen.
+The word "no"
+says that a burst is not wanted;
+the word "yes"
+(which may be omitted
+if stated on the same line as the course)
+says that a burst is wanted.
+.pp
+Photon torpedoes
+have no effect
+outside the quadrant.
+.bl "Onboard Computer Request"
+Mnemonic: computer
+Shortest Abbreviation: c
+Full Command: computer request; request;...
+Consumes: nothing
+.FF
+.pp
+The computer command gives you access to the facilities
+of the onboard computer,
+which allows you to do all sorts of fascinating stuff.
+Computer requests are:
+.in +8
+.qq
+score -- Shows your current score.
+.qq
+course quad/sect -- Computes the course and distance from whereever
+you are to the given location.
+If you type "course /x,y"
+you will be given the course
+to sector x,y in the current quadrant.
+.qq
+move quad/sect -- Identical to the course
+request,
+except that the move is executed.
+.qq
+chart -- prints a chart of the known galaxy,
+i.e.,
+everything that you have seen with a long range scan.
+The format is the same as on a long range scan,
+except that "..." means
+that you don't yet know what is there,
+and ".1." means that you know that a starbase
+exists, but you don't know anything else.
+"$$$" mans the quadrant
+that you are currently in.
+.qq
+trajectory -- prints the course and distance
+to all the Klingons in the quadrant.
+.qq
+warpcost dist warp_factor -- computes the cost in time and energy
+to move `dist' quadrants at warp `warp_factor'.
+.qq
+impcost dist -- same as warpcost for impulse engines.
+.qq
+pheff range -- tells how effective your phasers are
+at a given range.
+.qq
+distresslist -- gives a list of currently distressed
+starbases
+and starsystems.
+.in -8
+.pp
+More than one request may be stated
+on a line
+by seperating them
+with semicolons.
+.bl "Dock at Starbase"
+Mnemonic: dock
+Shortest Abbreviation: do
+Consumes: nothing
+.FF
+.pp
+You may dock at a starbase
+when you are in one of the eight
+adjacent sectors.
+.pp
+When you dock you are resupplied
+with energy, photon torpedoes, and life support reserves.
+Repairs are also done faster at starbase.
+Any prisoners you have taken
+are unloaded.
+You do not recieve points
+for taking prisoners
+until this time.
+.pp
+Starbases have their own deflector shields,
+so you are safe from attack while docked.
+.bl "Undock from Starbase"
+Mnemonic: undock
+Shortest Abbreviation: u
+Consumes: nothing
+.FF
+.pp
+This just allows you to leave starbase
+so that you may proceed on your way.
+.bl "Rest"
+Mnemonic: rest
+Shortest Abbreviation: r
+Full Command: rest time
+Consumes: time
+.FF
+.pp
+This command allows you to rest to repair damages.
+It is not advisable to rest while under attack.
+.bl "Call Starbase For Help"
+Mnemonic: help
+Shortest Abbreviation: help
+Consumes: nothing
+.FF
+.pp
+You may call starbase for help via your subspace radio.
+Starbase has long range transporter beams to get you.
+Problem is,
+they can't always rematerialize you.
+.pp
+You should avoid using this command unless absolutely necessary,
+for the above reason and because it counts heavily against you
+in the scoring.
+.bl "Capture Klingon"
+Mnemonic: capture
+Shortest Abbreviation: ca
+Consumes: time
+.FF
+.pp
+You may request that a Klingon surrender
+to you.
+If he accepts,
+you get to take captives
+(but only as many as your brig
+can hold).
+It is good if you do this,
+because you get points for captives.
+Also,
+if you ever get captured,
+you want to be sure that the Federation
+has prisoners to exchange for you.
+.pp
+You must go to a starbase
+to turn over your prisoners
+to Federation authorities.
+.bl "Visual Scan"
+Mnemonic: visual
+Shortest Abbreviation: v
+Full Command: visual course
+Consumes: time
+.FF
+.pp
+When your short range scanners are out,
+you can still see what is out "there"
+by doing a visual scan.
+Unfortunately,
+you can only see three sectors at one time,
+and it takes 0.005 stardates to perform.
+.pp
+The three sectors in the general direction
+of the course specified
+are examined
+and displayed.
+.bl "Abandon Ship"
+Mnemonic: abandon
+Shortest Abbreviation: abandon
+Consumes: nothing
+.FF
+.pp
+The officers escape the Enterprise in the shuttlecraft.
+If the transporter is working
+and there is an inhabitable starsystem
+in the area,
+the crew beams down,
+otherwise you leave them to die.
+You are given an old but still usable ship,
+the Faire Queene.
+.bl "Ram"
+Mnemonic: ram
+Shortest Abbreviation: ram
+Full Command: ram course distance
+Consumes: time and energy
+.FF
+.pp
+This command is identical to "move",
+except that the computer
+doesn't stop you
+from making navigation errors.
+.pp
+You get very nearly slaughtered
+if you ram anything.
+.bl "Self Destruct"
+Mnemonic: destruct
+Shortest Abbreviation: destruct
+Consumes: everything
+.FF
+.pp
+Your starship is self-destructed.
+Chances are you will destroy
+any Klingons
+(and stars,
+and starbases)
+left in your quadrant.
+.bl "Terminate the Game"
+Mnemonic: terminate
+Shortest Abbreviation: terminate
+Full Command: terminate yes/no
+.FF
+.pp
+Cancels the current game.
+No score is computed.
+If you answer yes,
+a new game will be started,
+otherwise trek exits.
+.bl "Call the Shell"
+Mnemonic: shell
+Shortest Abbreviation: shell
+.FF
+.pp
+Temporarily escapes to the shell.
+When you log out of the shell
+you will return to the game.
+.bp
+.ce
+SCORING
+.in +4
+.pp
+The scoring algorithm is rather complicated.
+Basically,
+you get points for each Klingon you kill,
+for your Klingon per stardate kill rate,
+and a bonus if you win the game.
+You lose
+points for the number of Klingons left
+in the galaxy
+at the end of the game,
+for getting killed,
+for each star, starbase, or inhabited starsystem
+you destroy,
+for calling for help,
+and for each casualty you incur.
+.pp
+You will be promoted
+if you play very well.
+You will never get a promotion if you
+call for help,
+abandon the Enterprise,
+get killed,
+destroy a starbase or inhabited starsystem,
+or destroy too many stars.
+.bp
+.ce
+REFERENCE PAGE
+.sp 2
+.ta 36 56
+.nf
+.ul
+Command Uses Consumes
+
+ABANDON shuttlecraft, -
+ transporter
+CApture subspace radio time
+CLoak Up/Down cloaking device energy
+Computer request; request;... computer -
+DAmages - -
+DESTRUCT computer -
+DOck - -
+HELP subspace radio -
+Impulse course distance impulse engines, time, energy
+ computer, SINS
+Lrscan L.R. sensors -
+Move course distance warp engines, time, energy
+ computer, SINS
+Phasers Automatic amount phasers, computer energy
+Phasers Manual amt1 course1 spread1 ... phasers energy
+Torpedo course [Yes] angle/No torpedo tubes torpedoes
+RAM course distance warp engines, time, energy
+ computer, SINS
+Rest time - time
+SHELL - -
+SHields Up/Down shields energy
+Srscan [Yes/No] S.R. sensors -
+STatus - -
+TERMINATE Yes/No - -
+Undock - -
+Visual course - time
+Warp warp_factor - -
+.fi
diff --git a/trek/Makefile b/trek/Makefile
new file mode 100644
index 00000000..02754f37
--- /dev/null
+++ b/trek/Makefile
@@ -0,0 +1,17 @@
+# @(#)Makefile 5.8 (Berkeley) 5/11/90
+
+PROG= trek
+SRCS= abandon.c attack.c autover.c capture.c check_out.c checkcond.c \
+ compkl.c computer.c damage.c damaged.c dcrept.c destruct.c \
+ dock.c dumpgame.c dumpme.c dumpssradio.c events.c externs.c \
+ getcodi.c getpar.c help.c impulse.c initquad.c kill.c klmove.c \
+ lose.c lrscan.c main.c move.c nova.c out.c phaser.c play.c ram.c \
+ ranf.c rest.c schedule.c score.c setup.c setwarp.c \
+ shield.c snova.c srscan.c systemname.c torped.c utility.c \
+ visual.c warp.c win.c cgetc.c
+MAN6= trek.0
+DPADD= ${LIBM} ${LIBCOMPAT}
+LDADD= -lm -lcompat
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
diff --git a/trek/abandon.c b/trek/abandon.c
new file mode 100644
index 00000000..431726ea
--- /dev/null
+++ b/trek/abandon.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)abandon.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Abandon Ship
+**
+** The ship is abandoned. If your current ship is the Faire
+** Queene, or if your shuttlecraft is dead, you're out of
+** luck. You need the shuttlecraft in order for the captain
+** (that's you!!) to escape.
+**
+** Your crew can beam to an inhabited starsystem in the
+** quadrant, if there is one and if the transporter is working.
+** If there is no inhabited starsystem, or if the transporter
+** is out, they are left to die in outer space.
+**
+** These currently just count as regular deaths, but they
+** should count very heavily against you.
+**
+** If there are no starbases left, you are captured by the
+** Klingons, who torture you mercilessly. However, if there
+** is at least one starbase, you are returned to the
+** Federation in a prisoner of war exchange. Of course, this
+** can't happen unless you have taken some prisoners.
+**
+** Uses trace flag 40
+*/
+
+abandon()
+{
+ register struct quad *q;
+ register int i;
+ int j;
+ register struct event *e;
+
+ if (Ship.ship == QUEENE)
+ return (printf("You may not abandon ye Faire Queene\n"));
+ if (Ship.cond != DOCKED)
+ {
+ if (damaged(SHUTTLE))
+ return (out(SHUTTLE));
+ printf("Officers escape in shuttlecraft\n");
+ /* decide on fate of crew */
+ q = &Quad[Ship.quadx][Ship.quady];
+ if (q->qsystemname == 0 || damaged(XPORTER))
+ {
+ printf("Entire crew of %d left to die in outer space\n",
+ Ship.crew);
+ Game.deaths += Ship.crew;
+ }
+ else
+ {
+ printf("Crew beams down to planet %s\n", systemname(q));
+ }
+ }
+ /* see if you can be exchanged */
+ if (Now.bases == 0 || Game.captives < 20 * Game.skill)
+ lose(L_CAPTURED);
+ /* re-outfit new ship */
+ printf("You are hereby put in charge of an antiquated but still\n");
+ printf(" functional ship, the Fairie Queene.\n");
+ Ship.ship = QUEENE;
+ Ship.shipname = "Fairie Queene";
+ Param.energy = Ship.energy = 3000;
+ Param.torped = Ship.torped = 6;
+ Param.shield = Ship.shield = 1250;
+ Ship.shldup = 0;
+ Ship.cloaked = 0;
+ Ship.warp = 5.0;
+ Ship.warp2 = 25.0;
+ Ship.warp3 = 125.0;
+ Ship.cond = GREEN;
+ /* clear out damages on old ship */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode != E_FIXDV)
+ continue;
+ unschedule(e);
+ }
+ /* get rid of some devices and redistribute probabilities */
+ i = Param.damprob[SHUTTLE] + Param.damprob[CLOAK];
+ Param.damprob[SHUTTLE] = Param.damprob[CLOAK] = 0;
+ while (i > 0)
+ for (j = 0; j < NDEV; j++)
+ {
+ if (Param.damprob[j] != 0)
+ {
+ Param.damprob[j] += 1;
+ i--;
+ if (i <= 0)
+ break;
+ }
+ }
+ /* pick a starbase to restart at */
+ i = ranf(Now.bases);
+ Ship.quadx = Now.base[i].x;
+ Ship.quady = Now.base[i].y;
+ /* setup that quadrant */
+ while (1)
+ {
+ initquad(1);
+ Sect[Ship.sectx][Ship.secty] = EMPTY;
+ for (i = 0; i < 5; i++)
+ {
+ Ship.sectx = Etc.starbase.x + ranf(3) - 1;
+ if (Ship.sectx < 0 || Ship.sectx >= NSECTS)
+ continue;
+ Ship.secty = Etc.starbase.y + ranf(3) - 1;
+ if (Ship.secty < 0 || Ship.secty >= NSECTS)
+ continue;
+ if (Sect[Ship.sectx][Ship.secty] == EMPTY)
+ {
+ Sect[Ship.sectx][Ship.secty] = QUEENE;
+ dock();
+ compkldist(0);
+ return;
+ }
+ }
+ }
+}
diff --git a/trek/attack.c b/trek/attack.c
new file mode 100644
index 00000000..61c23ed0
--- /dev/null
+++ b/trek/attack.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)attack.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Klingon Attack Routine
+**
+** This routine performs the Klingon attack provided that
+** (1) Something happened this move (i.e., not free), and
+** (2) You are not cloaked. Note that if you issue the
+** cloak command, you are not considered cloaked until you
+** expend some time.
+**
+** Klingons are permitted to move both before and after the
+** attack. They will tend to move toward you before the
+** attack and away from you after the attack.
+**
+** Under certain conditions you can get a critical hit. This
+** sort of hit damages devices. The probability that a given
+** device is damaged depends on the device. Well protected
+** devices (such as the computer, which is in the core of the
+** ship and has considerable redundancy) almost never get
+** damaged, whereas devices which are exposed (such as the
+** warp engines) or which are particularly delicate (such as
+** the transporter) have a much higher probability of being
+** damaged.
+**
+** The actual amount of damage (i.e., how long it takes to fix
+** it) depends on the amount of the hit and the "damfac[]"
+** entry for the particular device.
+**
+** Casualties can also occur.
+*/
+
+attack(resting)
+int resting; /* set if attack while resting */
+{
+ register int hit, i, l;
+ int maxhit, tothit, shldabsb;
+ double chgfac, propor, extradm;
+ double dustfac, tothe;
+ int cas;
+ int hitflag;
+
+ if (Move.free)
+ return;
+ if (Etc.nkling <= 0 || Quad[Ship.quadx][Ship.quady].stars < 0)
+ return;
+ if (Ship.cloaked && Ship.cloakgood)
+ return;
+ /* move before attack */
+ klmove(0);
+ if (Ship.cond == DOCKED)
+ {
+ if (!resting)
+ printf("Starbase shields protect the %s\n", Ship.shipname);
+ return;
+ }
+ /* setup shield effectiveness */
+ chgfac = 1.0;
+ if (Move.shldchg)
+ chgfac = 0.25 + 0.50 * franf();
+ maxhit = tothit = 0;
+ hitflag = 0;
+
+ /* let each Klingon do his damndest */
+ for (i = 0; i < Etc.nkling; i++)
+ {
+ /* if he's low on power he won't attack */
+ if (Etc.klingon[i].power < 20)
+ continue;
+ if (!hitflag)
+ {
+ printf("\nStardate %.2f: Klingon attack:\n",
+ Now.date);
+ hitflag++;
+ }
+ /* complete the hit */
+ dustfac = 0.90 + 0.01 * franf();
+ tothe = Etc.klingon[i].avgdist;
+ hit = Etc.klingon[i].power * pow(dustfac, tothe) * Param.hitfac;
+ /* deplete his energy */
+ dustfac = Etc.klingon[i].power;
+ Etc.klingon[i].power = dustfac * Param.phasfac * (1.0 + (franf() - 0.5) * 0.2);
+ /* see how much of hit shields will absorb */
+ shldabsb = 0;
+ if (Ship.shldup || Move.shldchg)
+ {
+ propor = Ship.shield;
+ propor /= Param.shield;
+ shldabsb = propor * chgfac * hit;
+ if (shldabsb > Ship.shield)
+ shldabsb = Ship.shield;
+ Ship.shield -= shldabsb;
+ }
+ /* actually do the hit */
+ printf("HIT: %d units", hit);
+ if (!damaged(SRSCAN))
+ printf(" from %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
+ cas = (shldabsb * 100) / hit;
+ hit -= shldabsb;
+ if (shldabsb > 0)
+ printf(", shields absorb %d%%, effective hit %d\n",
+ cas, hit);
+ else
+ printf("\n");
+ tothit += hit;
+ if (hit > maxhit)
+ maxhit = hit;
+ Ship.energy -= hit;
+ /* see if damages occurred */
+ if (hit >= (15 - Game.skill) * (25 - ranf(12)))
+ {
+ printf("CRITICAL HIT!!!\n");
+ /* select a device from probability vector */
+ cas = ranf(1000);
+ for (l = 0; cas >= 0; l++)
+ cas -= Param.damprob[l];
+ l -= 1;
+ /* compute amount of damage */
+ extradm = (hit * Param.damfac[l]) / (75 + ranf(25)) + 0.5;
+ /* damage the device */
+ damage(l, extradm);
+ if (damaged(SHIELD))
+ {
+ if (Ship.shldup)
+ printf("Sulu: Shields knocked down, captain.\n");
+ Ship.shldup = 0;
+ Move.shldchg = 0;
+ }
+ }
+ if (Ship.energy <= 0)
+ lose(L_DSTRYD);
+ }
+
+ /* see what our casualities are like */
+ if (maxhit >= 200 || tothit >= 500)
+ {
+ cas = tothit * 0.015 * franf();
+ if (cas >= 2)
+ {
+ printf("McCoy: we suffered %d casualties in that attack.\n",
+ cas);
+ Game.deaths += cas;
+ Ship.crew -= cas;
+ }
+ }
+
+ /* allow Klingons to move after attacking */
+ klmove(1);
+
+ return;
+}
diff --git a/trek/autover.c b/trek/autover.c
new file mode 100644
index 00000000..3a0f67e6
--- /dev/null
+++ b/trek/autover.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)autover.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Automatic Override
+**
+** If we should be so unlucky as to be caught in a quadrant
+** with a supernova in it, this routine is called. It is
+** called from checkcond().
+**
+** It sets you to a random warp (guaranteed to be over 6.0)
+** and starts sending you off "somewhere" (whereever that is).
+**
+** Please note that it is VERY important that you reset your
+** warp speed after the automatic override is called. The new
+** warp factor does not stay in effect for just this routine.
+**
+** This routine will never try to send you more than sqrt(2)
+** quadrants, since that is all that is needed.
+*/
+
+autover()
+{
+ double dist;
+ register int course;
+
+ printf("\07RED ALERT: The %s is in a supernova quadrant\n", Ship.shipname);
+ printf("*** Emergency override attempts to hurl %s to safety\n", Ship.shipname);
+ /* let's get our ass out of here */
+ Ship.warp = 6.0 + 2.0 * franf();
+ Ship.warp2 = Ship.warp * Ship.warp;
+ Ship.warp3 = Ship.warp2 * Ship.warp;
+ dist = 0.75 * Ship.energy / (Ship.warp3 * (Ship.shldup + 1));
+ if (dist > 1.4142)
+ dist = 1.4142;
+ course = ranf(360);
+ Etc.nkling = -1;
+ Ship.cond = RED;
+ warp(-1, course, dist);
+ attack(0);
+}
diff --git a/trek/board.x b/trek/board.x
new file mode 100644
index 00000000..0892a6da
--- /dev/null
+++ b/trek/board.x
@@ -0,0 +1,59 @@
+# include "trek.h"
+
+/*
+** BOARD A KLINGON
+**
+** A Klingon battle cruiser is boarded. If the boarding party
+** is successful, they take over the vessel, otherwise, you
+** have wasted a move. Needless to say, this move is not free.
+**
+** User parameters are the Klingon to be boarded and the size of
+** the boarding party.
+**
+** Three things are computed. The first is the probability that
+** the party takes over the Klingon. This is dependent on the
+** size of the party, the condition of the Klingon (for which
+** the energy left is used, which is definately incorrect), and
+** the number of losses that the boarding party sustains. If too
+** many of the boarding party are killed, the probability drops
+** to zero. The second quantity computed is the losses that the
+** boarding party sustains. This counts in your score. It
+** depends on the absolute and relative size of the boarding
+** party and the strength of the Klingon. The third quantity
+** computed is the number of Klingon captives you get to take.
+** It is actually computed as the number of losses they sustain
+** subtracted from the size of their crew. It depends on the
+** relative size of the party. All of these quantities are
+** randomized in some fashion.
+*/
+
+board()
+{
+ int prob;
+ int losses;
+ int captives;
+ float t;
+ int party;
+
+ if (checkout(XPORTER))
+ return;
+
+ k = selectklingon();
+ if (!k->srndreq)
+ {
+ return (printf("But captain! You must request surrender first\n"));
+ }
+
+ t = party / Param.crew;
+
+ prob = 1000 * t;
+ prob =- 500 * k->power / Param.klingpwr;
+
+ losses = party * k->power * t * 0.5 / Param.klingpwr * (franf() + 1.0);
+ if (losses * 4 > party)
+ prob = 0;
+
+ captives = %%% * (1.0 - t) * 0.5 * (franf() + 1.0);
+
+ if (prob > ranf(1000))
+ success!!!;
diff --git a/trek/capture.c b/trek/capture.c
new file mode 100644
index 00000000..77881b9b
--- /dev/null
+++ b/trek/capture.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)capture.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Ask a Klingon To Surrender
+**
+** (Fat chance)
+**
+** The Subspace Radio is needed to ask a Klingon if he will kindly
+** surrender. A random Klingon from the ones in the quadrant is
+** chosen.
+**
+** The Klingon is requested to surrender. The probability of this
+** is a function of that Klingon's remaining power, our power,
+** etc.
+*/
+
+capture()
+{
+ register int i;
+ register struct kling *k;
+ double x;
+ extern struct kling *selectklingon();
+
+ /* check for not cloaked */
+ if (Ship.cloaked)
+ {
+ printf("Ship-ship communications out when cloaked\n");
+ return;
+ }
+ if (damaged(SSRADIO))
+ return (out(SSRADIO));
+ /* find out if there are any at all */
+ if (Etc.nkling <= 0)
+ {
+ printf("Uhura: Getting no response, sir\n");
+ return;
+ }
+
+ /* if there is more than one Klingon, find out which one */
+ k = selectklingon();
+ Move.free = 0;
+ Move.time = 0.05;
+
+ /* check out that Klingon */
+ k->srndreq++;
+ x = Param.klingpwr;
+ x *= Ship.energy;
+ x /= k->power * Etc.nkling;
+ x *= Param.srndrprob;
+ i = x;
+# ifdef xTRACE
+ if (Trace)
+ printf("Prob = %d (%.4f)\n", i, x);
+# endif
+ if (i > ranf(100))
+ {
+ /* guess what, he surrendered!!! */
+ printf("Klingon at %d,%d surrenders\n", k->x, k->y);
+ i = ranf(Param.klingcrew);
+ if ( i > 0 )
+ printf("%d klingons commit suicide rather than be taken captive\n", Param.klingcrew - i);
+ if (i > Ship.brigfree)
+ i = Ship.brigfree;
+ Ship.brigfree -= i;
+ printf("%d captives taken\n", i);
+ killk(k->x, k->y);
+ return;
+ }
+
+ /* big surprise, he refuses to surrender */
+ printf("Fat chance, captain\n");
+ return;
+}
+
+
+/*
+** SELECT A KLINGON
+**
+** Cruddy, just takes one at random. Should ask the captain.
+*/
+
+struct kling *selectklingon()
+{
+ register int i;
+
+ if (Etc.nkling < 2)
+ i = 0;
+ else
+ i = ranf(Etc.nkling);
+ return (&Etc.klingon[i]);
+}
diff --git a/trek/cgetc.c b/trek/cgetc.c
new file mode 100644
index 00000000..cde6250d
--- /dev/null
+++ b/trek/cgetc.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cgetc.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <stdio.h>
+
+char cgetc(i)
+int i;
+{
+ return ( getchar() );
+}
diff --git a/trek/check_out.c b/trek/check_out.c
new file mode 100644
index 00000000..ded9eaba
--- /dev/null
+++ b/trek/check_out.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)check_out.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** CHECK IF A DEVICE IS OUT
+**
+** The indicated device is checked to see if it is disabled. If
+** it is, an attempt is made to use the starbase device. If both
+** of these fails, it returns non-zero (device is REALLY out),
+** otherwise it returns zero (I can get to it somehow).
+**
+** It prints appropriate messages too.
+*/
+
+check_out(device)
+int device;
+{
+ register int dev;
+
+ dev = device;
+
+ /* check for device ok */
+ if (!damaged(dev))
+ return (0);
+
+ /* report it as being dead */
+ out(dev);
+
+ /* but if we are docked, we can go ahead anyhow */
+ if (Ship.cond != DOCKED)
+ return (1);
+ printf(" Using starbase %s\n", Device[dev].name);
+ return (0);
+}
diff --git a/trek/checkcond.c b/trek/checkcond.c
new file mode 100644
index 00000000..e490c9bf
--- /dev/null
+++ b/trek/checkcond.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)checkcond.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Check for Condition After a Move
+**
+** Various ship conditions are checked. First we check
+** to see if we have already lost the game, due to running
+** out of life support reserves, running out of energy,
+** or running out of crew members. The check for running
+** out of time is in events().
+**
+** If we are in automatic override mode (Etc.nkling < 0), we
+** don't want to do anything else, lest we call autover
+** recursively.
+**
+** In the normal case, if there is a supernova, we call
+** autover() to help us escape. If after calling autover()
+** we are still in the grips of a supernova, we get burnt
+** up.
+**
+** If there are no Klingons in this quadrant, we nullify any
+** distress calls which might exist.
+**
+** We then set the condition code, based on the energy level
+** and battle conditions.
+*/
+
+checkcond()
+{
+ register int i, j;
+
+ /* see if we are still alive and well */
+ if (Ship.reserves < 0.0)
+ lose(L_NOLIFE);
+ if (Ship.energy <= 0)
+ lose(L_NOENGY);
+ if (Ship.crew <= 0)
+ lose(L_NOCREW);
+ /* if in auto override mode, ignore the rest */
+ if (Etc.nkling < 0)
+ return;
+ /* call in automatic override if appropriate */
+ if (Quad[Ship.quadx][Ship.quady].stars < 0)
+ autover();
+ if (Quad[Ship.quadx][Ship.quady].stars < 0)
+ lose(L_SNOVA);
+ /* nullify distress call if appropriate */
+ if (Etc.nkling <= 0)
+ killd(Ship.quadx, Ship.quady, 1);
+
+ /* set condition code */
+ if (Ship.cond == DOCKED)
+ return;
+
+ if (Etc.nkling > 0)
+ {
+ Ship.cond = RED;
+ return;
+ }
+ if (Ship.energy < Param.energylow)
+ {
+ Ship.cond = YELLOW;
+ return;
+ }
+ Ship.cond = GREEN;
+ return;
+}
diff --git a/trek/compkl.c b/trek/compkl.c
new file mode 100644
index 00000000..ad1d61cf
--- /dev/null
+++ b/trek/compkl.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)compkl.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** compute klingon distances
+**
+** The klingon list has the distances for all klingons recomputed
+** and sorted. The parameter is a Boolean flag which is set if
+** we have just entered a new quadrant.
+**
+** This routine is used every time the Enterprise or the Klingons
+** move.
+*/
+
+compkldist(f)
+int f; /* set if new quadrant */
+{
+ register int i, dx, dy;
+ double d;
+ double temp;
+
+ if (Etc.nkling == 0)
+ return;
+ for (i = 0; i < Etc.nkling; i++)
+ {
+ /* compute distance to the Klingon */
+ dx = Ship.sectx - Etc.klingon[i].x;
+ dy = Ship.secty - Etc.klingon[i].y;
+ d = dx * dx + dy * dy;
+ d = sqrt(d);
+
+ /* compute average of new and old distances to Klingon */
+ if (!f)
+ {
+ temp = Etc.klingon[i].dist;
+ Etc.klingon[i].avgdist = 0.5 * (temp + d);
+ }
+ else
+ {
+ /* new quadrant: average is current */
+ Etc.klingon[i].avgdist = d;
+ }
+ Etc.klingon[i].dist = d;
+ }
+
+ /* leave them sorted */
+ sortkl();
+}
+
+
+/*
+** sort klingons
+**
+** bubble sort on ascending distance
+*/
+
+sortkl()
+{
+ struct kling t;
+ register int f, i, m;
+
+ m = Etc.nkling - 1;
+ f = 1;
+ while (f)
+ {
+ f = 0;
+ for (i = 0; i < m; i++)
+ if (Etc.klingon[i].dist > Etc.klingon[i+1].dist)
+ {
+ bmove(&Etc.klingon[i], &t, sizeof t);
+ bmove(&Etc.klingon[i+1], &Etc.klingon[i], sizeof t);
+ bmove(&t, &Etc.klingon[i+1], sizeof t);
+ f = 1;
+ }
+ }
+}
diff --git a/trek/computer.c b/trek/computer.c
new file mode 100644
index 00000000..178d29b7
--- /dev/null
+++ b/trek/computer.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)computer.c 4.8 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+# include <stdio.h>
+/*
+** On-Board Computer
+**
+** A computer request is fetched from the captain. The requests
+** are:
+**
+** chart -- print a star chart of the known galaxy. This includes
+** every quadrant that has ever had a long range or
+** a short range scan done of it, plus the location of
+** all starbases. This is of course updated by any sub-
+** space radio broadcasts (unless the radio is out).
+** The format is the same as that of a long range scan
+** except that ".1." indicates that a starbase exists
+** but we know nothing else.
+**
+** trajectory -- gives the course and distance to every know
+** Klingon in the quadrant. Obviously this fails if the
+** short range scanners are out.
+**
+** course -- gives a course computation from whereever you are
+** to any specified location. If the course begins
+** with a slash, the current quadrant is taken.
+** Otherwise the input is quadrant and sector coordi-
+** nates of the target sector.
+**
+** move -- identical to course, except that the move is performed.
+**
+** score -- prints out the current score.
+**
+** pheff -- "PHaser EFFectiveness" at a given distance. Tells
+** you how much stuff you need to make it work.
+**
+** warpcost -- Gives you the cost in time and units to move for
+** a given distance under a given warp speed.
+**
+** impcost -- Same for the impulse engines.
+**
+** distresslist -- Gives a list of the currently known starsystems
+** or starbases which are distressed, together with their
+** quadrant coordinates.
+**
+** If a command is terminated with a semicolon, you remain in
+** the computer; otherwise, you escape immediately to the main
+** command processor.
+*/
+
+struct cvntab Cputab[] =
+{
+ "ch", "art", (int (*)())1, 0,
+ "t", "rajectory", (int (*)())2, 0,
+ "c", "ourse", (int (*)())3, 0,
+ "m", "ove", (int (*)())3, 1,
+ "s", "core", (int (*)())4, 0,
+ "p", "heff", (int (*)())5, 0,
+ "w", "arpcost", (int (*)())6, 0,
+ "i", "mpcost", (int (*)())7, 0,
+ "d", "istresslist", (int (*)())8, 0,
+ 0
+};
+
+computer()
+{
+ int ix, iy;
+ register int i, j;
+ int numout;
+ int tqx, tqy;
+ struct cvntab *r;
+ int cost;
+ int course;
+ double dist, time;
+ double warpfact;
+ struct quad *q;
+ register struct event *e;
+
+ if (check_out(COMPUTER))
+ return;
+ while (1)
+ {
+ r = getcodpar("\nRequest", Cputab);
+ switch ((int)r->value)
+ {
+
+ case 1: /* star chart */
+ printf("Computer record of galaxy for all long range sensor scans\n\n");
+ printf(" ");
+ /* print top header */
+ for (i = 0; i < NQUADS; i++)
+ printf("-%d- ", i);
+ printf("\n");
+ for (i = 0; i < NQUADS; i++)
+ {
+ printf("%d ", i);
+ for (j = 0; j < NQUADS; j++)
+ {
+ if (i == Ship.quadx && j == Ship.quady)
+ {
+ printf("$$$ ");
+ continue;
+ }
+ q = &Quad[i][j];
+ /* 1000 or 1001 is special case */
+ if (q->scanned >= 1000)
+ if (q->scanned > 1000)
+ printf(".1. ");
+ else
+ printf("/// ");
+ else
+ if (q->scanned < 0)
+ printf("... ");
+ else
+ printf("%3d ", q->scanned);
+ }
+ printf("%d\n", i);
+ }
+ printf(" ");
+ /* print bottom footer */
+ for (i = 0; i < NQUADS; i++)
+ printf("-%d- ", i);
+ printf("\n");
+ break;
+
+ case 2: /* trajectory */
+ if (check_out(SRSCAN))
+ {
+ break;
+ }
+ if (Etc.nkling <= 0)
+ {
+ printf("No Klingons in this quadrant\n");
+ break;
+ }
+ /* for each Klingon, give the course & distance */
+ for (i = 0; i < Etc.nkling; i++)
+ {
+ printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
+ course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist);
+ prkalc(course, dist);
+ }
+ break;
+
+ case 3: /* course calculation */
+ if (readdelim('/'))
+ {
+ tqx = Ship.quadx;
+ tqy = Ship.quady;
+ }
+ else
+ {
+ ix = getintpar("Quadrant");
+ if (ix < 0 || ix >= NSECTS)
+ break;
+ iy = getintpar("q-y");
+ if (iy < 0 || iy >= NSECTS)
+ break;
+ tqx = ix;
+ tqy = iy;
+ }
+ ix = getintpar("Sector");
+ if (ix < 0 || ix >= NSECTS)
+ break;
+ iy = getintpar("s-y");
+ if (iy < 0 || iy >= NSECTS)
+ break;
+ course = kalc(tqx, tqy, ix, iy, &dist);
+ if (r->value2)
+ {
+ warp(-1, course, dist);
+ break;
+ }
+ printf("%d,%d/%d,%d to %d,%d/%d,%d",
+ Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy);
+ prkalc(course, dist);
+ break;
+
+ case 4: /* score */
+ score();
+ break;
+
+ case 5: /* phaser effectiveness */
+ dist = getfltpar("range");
+ if (dist < 0.0)
+ break;
+ dist *= 10.0;
+ cost = pow(0.90, dist) * 98.0 + 0.5;
+ printf("Phasers are %d%% effective at that range\n", cost);
+ break;
+
+ case 6: /* warp cost (time/energy) */
+ dist = getfltpar("distance");
+ if (dist < 0.0)
+ break;
+ warpfact = getfltpar("warp factor");
+ if (warpfact <= 0.0)
+ warpfact = Ship.warp;
+ cost = (dist + 0.05) * warpfact * warpfact * warpfact;
+ time = Param.warptime * dist / (warpfact * warpfact);
+ printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n",
+ warpfact, dist, time, cost, cost + cost);
+ break;
+
+ case 7: /* impulse cost */
+ dist = getfltpar("distance");
+ if (dist < 0.0)
+ break;
+ cost = 20 + 100 * dist;
+ time = dist / 0.095;
+ printf("Distance %.2f cost %.2f stardates %d units\n",
+ dist, time, cost);
+ break;
+
+ case 8: /* distresslist */
+ j = 1;
+ printf("\n");
+ /* scan the event list */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ /* ignore hidden entries */
+ if (e->evcode & E_HIDDEN)
+ continue;
+ switch (e->evcode & E_EVENT)
+ {
+
+ case E_KDESB:
+ printf("Klingon is attacking starbase in quadrant %d,%d\n",
+ e->x, e->y);
+ j = 0;
+ break;
+
+ case E_ENSLV:
+ case E_REPRO:
+ printf("Starsystem %s in quadrant %d,%d is distressed\n",
+ Systemname[e->systemname], e->x, e->y);
+ j = 0;
+ break;
+ }
+ }
+ if (j)
+ printf("No known distress calls are active\n");
+ break;
+
+ }
+
+ /* skip to next semicolon or newline. Semicolon
+ * means get new computer request; newline means
+ * exit computer mode. */
+ while ((i = cgetc(0)) != ';')
+ {
+ if (i == '\0')
+ exit(1);
+ if (i == '\n')
+ {
+ ungetc(i, stdin);
+ return;
+ }
+ }
+ }
+}
+
+
+/*
+** Course Calculation
+**
+** Computes and outputs the course and distance from position
+** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy.
+*/
+
+kalc(tqx, tqy, tsx, tsy, dist)
+int tqx;
+int tqy;
+int tsx;
+int tsy;
+double *dist;
+{
+ double dx, dy;
+ double quadsize;
+ double angle;
+ register int course;
+
+ /* normalize to quadrant distances */
+ quadsize = NSECTS;
+ dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize);
+ dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize);
+
+ /* get the angle */
+ angle = atan2(dy, dx);
+ /* make it 0 -> 2 pi */
+ if (angle < 0.0)
+ angle += 6.283185307;
+ /* convert from radians to degrees */
+ course = angle * 57.29577951 + 0.5;
+ dx = dx * dx + dy * dy;
+ *dist = sqrt(dx);
+ return (course);
+}
+
+
+prkalc(course, dist)
+int course;
+double dist;
+{
+ printf(": course %d dist %.3f\n", course, dist);
+}
diff --git a/trek/damage.c b/trek/damage.c
new file mode 100644
index 00000000..b467f732
--- /dev/null
+++ b/trek/damage.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)damage.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Schedule Ship.damages to a Device
+**
+** Device `dev1' is damaged in an amount `dam'. Dam is measured
+** in stardates, and is an additional amount of damage. It should
+** be the amount to occur in non-docked mode. The adjustment
+** to docked mode occurs automatically if we are docked.
+**
+** Note that the repair of the device occurs on a DATE, meaning
+** that the dock() and undock() have to reschedule the event.
+*/
+
+damage(dev1, dam)
+int dev1; /* device index */
+double dam; /* time to repair */
+{
+ register int i;
+ register struct event *e;
+ int f;
+ register int dev;
+
+ /* ignore zero damages */
+ if (dam <= 0.0)
+ return;
+ dev = dev1;
+
+ printf("\t%s damaged\n", Device[dev].name);
+
+ /* find actual length till it will be fixed */
+ if (Ship.cond == DOCKED)
+ dam *= Param.dockfac;
+ /* set the damage flag */
+ f = damaged(dev);
+ if (!f)
+ {
+ /* new damages -- schedule a fix */
+ schedule(E_FIXDV, dam, 0, 0, dev);
+ return;
+ }
+ /* device already damaged -- add to existing damages */
+ /* scan for old damages */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode != E_FIXDV || e->systemname != dev)
+ continue;
+ /* got the right one; add on the new damages */
+ reschedule(e, e->date - Now.date + dam);
+ return;
+ }
+ syserr("Cannot find old damages %d\n", dev);
+}
diff --git a/trek/damaged.c b/trek/damaged.c
new file mode 100644
index 00000000..cf3ec080
--- /dev/null
+++ b/trek/damaged.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)damaged.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/* DAMAGED -- check for device damaged
+**
+** This is a boolean function which returns non-zero if the
+** specified device is broken. It does this by checking the
+** event list for a "device fix" action on that device.
+*/
+
+damaged(dev)
+int dev;
+{
+ register int d;
+ register struct event *e;
+ register int i;
+
+ d = dev;
+
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode != E_FIXDV)
+ continue;
+ if (e->systemname == d)
+ return (1);
+ }
+
+ /* device fix not in event list -- device must not be broken */
+ return (0);
+}
diff --git a/trek/dcrept.c b/trek/dcrept.c
new file mode 100644
index 00000000..3a59fe62
--- /dev/null
+++ b/trek/dcrept.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dcrept.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** damage control report
+**
+** Print damages and time to fix. This is taken from the event
+** list. A couple of factors are set up, based on whether or not
+** we are docked. (One of these factors will always be 1.0.)
+** The event list is then scanned for damage fix events, the
+** time until they occur is determined, and printed out. The
+** magic number DAMFAC is used to tell how much faster you can
+** fix things if you are docked.
+*/
+
+dcrept()
+{
+ register int i, f;
+ double x;
+ double m1, m2;
+ register struct event *e;
+
+ /* set up the magic factors to output the time till fixed */
+ if (Ship.cond == DOCKED)
+ {
+ m1 = 1.0 / Param.dockfac;
+ m2 = 1.0;
+ }
+ else
+ {
+ m1 = 1.0;
+ m2 = Param.dockfac;
+ }
+ printf("Damage control report:\n");
+ f = 1;
+
+ /* scan for damages */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode != E_FIXDV)
+ continue;
+
+ /* output the title first time */
+ if (f)
+ {
+ printf("\t\t\t repair times\n");
+ printf("device\t\t\tin flight docked\n");
+ f = 0;
+ }
+
+ /* compute time till fixed, then adjust by the magic factors */
+ x = e->date - Now.date;
+ printf("%-24s%7.2f %7.2f\n",
+ Device[e->systemname].name, x * m1 + 0.005, x * m2 + 0.005);
+
+ /* do a little consistancy checking */
+ }
+
+ /* if everything was ok, reassure the nervous captain */
+ if (f)
+ printf("All devices functional\n");
+}
diff --git a/trek/destruct.c b/trek/destruct.c
new file mode 100644
index 00000000..906f1400
--- /dev/null
+++ b/trek/destruct.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)destruct.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Self Destruct Sequence
+**
+** The computer starts up the self destruct sequence. Obviously,
+** if the computer is out nothing can happen. You get a countdown
+** and a request for password. This must match the password that
+** you entered at the start of the game.
+**
+** You get to destroy things when you blow up; hence, it is
+** possible to win the game by destructing if you take the last
+** Klingon with you.
+**
+** By the way, the \032 in the message is a ^Z, which is because
+** the terminal in my office is an ADM-3, which uses that char-
+** acter to clear the screen. I also stick in a \014 (form feed)
+** because that clears some other screens.
+**
+** Uses trace flag 41
+*/
+
+destruct()
+{
+ char checkpass[15];
+ register int i, j;
+ double zap;
+
+ if (damaged(COMPUTER))
+ return (out(COMPUTER));
+ printf("\n\07 --- WORKING ---\07\n");
+ sleep(3);
+ /* output the count 10 9 8 7 6 */
+ for (i = 10; i > 5; i--)
+ {
+ for (j = 10; j > i; j--)
+ printf(" ");
+ printf("%d\n", i);
+ sleep(1);
+ }
+ /* check for password on new line only */
+ skiptonl(0);
+ getstrpar("Enter password verification", checkpass, 14, 0);
+ sleep(2);
+ if (!sequal(checkpass, Game.passwd))
+ return (printf("Self destruct sequence aborted\n"));
+ printf("Password verified; self destruct sequence continues:\n");
+ sleep(2);
+ /* output count 5 4 3 2 1 0 */
+ for (i = 5; i >= 0; i--)
+ {
+ sleep(1);
+ for (j = 5; j > i; j--)
+ printf(" ");
+ printf("%d\n", i);
+ }
+ sleep(2);
+ printf("\032\014***** %s destroyed *****\n", Ship.shipname);
+ Game.killed = 1;
+ /* let's see what we can blow up!!!! */
+ zap = 20.0 * Ship.energy;
+ Game.deaths += Ship.crew;
+ for (i = 0; i < Etc.nkling; )
+ {
+ if (Etc.klingon[i].power * Etc.klingon[i].dist <= zap)
+ killk(Etc.klingon[i].x, Etc.klingon[i].y);
+ else
+ i++;
+ }
+ /* if we didn't kill the last Klingon (detected by killk), */
+ /* then we lose.... */
+ lose(L_DSTRCT);
+}
diff --git a/trek/dock.c b/trek/dock.c
new file mode 100644
index 00000000..d83ada39
--- /dev/null
+++ b/trek/dock.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dock.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** DOCK TO STARBASE
+**
+** The starship is docked to a starbase. For this to work you
+** must be adjacent to a starbase.
+**
+** You get your supplies replenished and your captives are
+** disembarked. Note that your score is updated now, not when
+** you actually take the captives.
+**
+** Any repairs that need to be done are rescheduled to take
+** place sooner. This provides for the faster repairs when you
+** are docked.
+*/
+
+dock()
+{
+ register int i, j;
+ int ok;
+ register struct event *e;
+
+ if (Ship.cond == DOCKED)
+ return (printf("Chekov: But captain, we are already docked\n"));
+ /* check for ok to dock, i.e., adjacent to a starbase */
+ ok = 0;
+ for (i = Ship.sectx - 1; i <= Ship.sectx + 1 && !ok; i++)
+ {
+ if (i < 0 || i >= NSECTS)
+ continue;
+ for (j = Ship.secty - 1; j <= Ship.secty + 1; j++)
+ {
+ if (j < 0 || j >= NSECTS)
+ continue;
+ if (Sect[i][j] == BASE)
+ {
+ ok++;
+ break;
+ }
+ }
+ }
+ if (!ok)
+ return (printf("Chekov: But captain, we are not adjacent to a starbase.\n"));
+
+ /* restore resources */
+ Ship.energy = Param.energy;
+ Ship.torped = Param.torped;
+ Ship.shield = Param.shield;
+ Ship.crew = Param.crew;
+ Game.captives += Param.brigfree - Ship.brigfree;
+ Ship.brigfree = Param.brigfree;
+
+ /* reset ship's defenses */
+ Ship.shldup = 0;
+ Ship.cloaked = 0;
+ Ship.cond = DOCKED;
+ Ship.reserves = Param.reserves;
+
+ /* recalibrate space inertial navigation system */
+ Ship.sinsbad = 0;
+
+ /* output any saved radio messages */
+ dumpssradio();
+
+ /* reschedule any device repairs */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode != E_FIXDV)
+ continue;
+ reschedule(e, (e->date - Now.date) * Param.dockfac);
+ }
+ return;
+}
+
+
+/*
+** LEAVE A STARBASE
+**
+** This is the inverse of dock(). The main function it performs
+** is to reschedule any damages so that they will take longer.
+*/
+
+undock()
+{
+ register struct event *e;
+ register int i;
+
+ if (Ship.cond != DOCKED)
+ {
+ printf("Sulu: Pardon me captain, but we are not docked.\n");
+ return;
+ }
+ Ship.cond = GREEN;
+ Move.free = 0;
+
+ /* reschedule device repair times (again) */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode != E_FIXDV)
+ continue;
+ reschedule(e, (e->date - Now.date) / Param.dockfac);
+ }
+ return;
+}
diff --git a/trek/dumpgame.c b/trek/dumpgame.c
new file mode 100644
index 00000000..51842072
--- /dev/null
+++ b/trek/dumpgame.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dumpgame.c 4.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*** THIS CONSTANT MUST CHANGE AS THE DATA SPACES CHANGE ***/
+# define VERSION 2
+
+struct dump
+{
+ char *area;
+ int count;
+};
+
+
+struct dump Dump_template[] =
+{
+ (char *)&Ship, sizeof (Ship),
+ (char *)&Now, sizeof (Now),
+ (char *)&Param, sizeof (Param),
+ (char *)&Etc, sizeof (Etc),
+ (char *)&Game, sizeof (Game),
+ (char *)Sect, sizeof (Sect),
+ (char *)Quad, sizeof (Quad),
+ (char *)&Move, sizeof (Move),
+ (char *)Event, sizeof (Event),
+ 0
+};
+
+/*
+** DUMP GAME
+**
+** This routine dumps the game onto the file "trek.dump". The
+** first two bytes of the file are a version number, which
+** reflects whether this image may be used. Obviously, it must
+** change as the size, content, or order of the data structures
+** output change.
+*/
+
+dumpgame()
+{
+ int version;
+ register int fd;
+ register struct dump *d;
+ register int i;
+
+ if ((fd = creat("trek.dump", 0644)) < 0)
+ return (printf("cannot dump\n"));
+ version = VERSION;
+ write(fd, &version, sizeof version);
+
+ /* output the main data areas */
+ for (d = Dump_template; d->area; d++)
+ {
+ write(fd, &d->area, sizeof d->area);
+ i = d->count;
+ write(fd, d->area, i);
+ }
+
+ close(fd);
+}
+
+
+/*
+** RESTORE GAME
+**
+** The game is restored from the file "trek.dump". In order for
+** this to succeed, the file must exist and be readable, must
+** have the correct version number, and must have all the appro-
+** priate data areas.
+**
+** Return value is zero for success, one for failure.
+*/
+
+restartgame()
+{
+ register int fd;
+ int version;
+
+ if ((fd = open("trek.dump", 0)) < 0 ||
+ read(fd, &version, sizeof version) != sizeof version ||
+ version != VERSION ||
+ readdump(fd))
+ {
+ printf("cannot restart\n");
+ close(fd);
+ return (1);
+ }
+
+ close(fd);
+ return (0);
+}
+
+
+/*
+** READ DUMP
+**
+** This is the business end of restartgame(). It reads in the
+** areas.
+**
+** Returns zero for success, one for failure.
+*/
+
+readdump(fd1)
+int fd1;
+{
+ register int fd;
+ register struct dump *d;
+ register int i;
+ int junk;
+
+ fd = fd1;
+
+ for (d = Dump_template; d->area; d++)
+ {
+ if (read(fd, &junk, sizeof junk) != (sizeof junk))
+ return (1);
+ if ((char *)junk != d->area)
+ return (1);
+ i = d->count;
+ if (read(fd, d->area, i) != i)
+ return (1);
+ }
+
+ /* make quite certain we are at EOF */
+ return (read(fd, &junk, 1));
+}
diff --git a/trek/dumpme.c b/trek/dumpme.c
new file mode 100644
index 00000000..ccb9039c
--- /dev/null
+++ b/trek/dumpme.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dumpme.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Dump the starship somewhere in the galaxy
+**
+** Parameter is zero if bounce off of negative energy barrier,
+** one if through a black hole
+**
+** Note that the quadrant is NOT initialized here. This must
+** be done from the calling routine.
+**
+** Repair of devices must be deferred.
+*/
+
+dumpme(flag)
+int flag;
+{
+ register int f;
+ double x;
+ register struct event *e;
+ register int i;
+
+ f = flag;
+ Ship.quadx = ranf(NQUADS);
+ Ship.quady = ranf(NQUADS);
+ Ship.sectx = ranf(NSECTS);
+ Ship.secty = ranf(NSECTS);
+ x += 1.5 * franf();
+ Move.time += x;
+ if (f)
+ {
+ printf("%s falls into a black hole.\n", Ship.shipname);
+ }
+ else
+ {
+ printf("Computer applies full reverse power to avoid hitting the\n");
+ printf(" negative energy barrier. A space warp was entered.\n");
+ }
+ /* bump repair dates forward */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode != E_FIXDV)
+ continue;
+ reschedule(e, (e->date - Now.date) + x);
+ }
+ events(1);
+ printf("You are now in quadrant %d,%d. It is stardate %.2f\n",
+ Ship.quadx, Ship.quady, Now.date);
+ Move.time = 0;
+}
diff --git a/trek/dumpssradio.c b/trek/dumpssradio.c
new file mode 100644
index 00000000..038dfd7f
--- /dev/null
+++ b/trek/dumpssradio.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dumpssradio.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/**
+ ** output hidden distress calls
+ **/
+
+dumpssradio()
+{
+ register struct event *e;
+ register int j;
+ register int chkrest;
+
+ chkrest = 0;
+ for (j = 0; j < MAXEVENTS; j++)
+ {
+ e = &Event[j];
+ /* if it is not hidden, then just ignore it */
+ if ((e->evcode & E_HIDDEN) == 0)
+ continue;
+ if (e->evcode & E_GHOST)
+ {
+ unschedule(e);
+ printf("Starsystem %s in quadrant %d,%d is no longer distressed\n",
+ systemname(e), e->x, e->y);
+ continue;
+ }
+
+ switch (e->evcode)
+ {
+
+ case E_KDESB:
+ printf("Starbase in quadrant %d,%d is under attack\n",
+ e->x, e->y);
+ chkrest++;
+ break;
+
+ case E_ENSLV:
+ case E_REPRO:
+ printf("Starsystem %s in quadrant %d,%d is distressed\n",
+ systemname(e), e->x, e->y);
+ chkrest++;
+ break;
+
+ }
+ }
+
+ return (chkrest);
+}
diff --git a/trek/events.c b/trek/events.c
new file mode 100644
index 00000000..4ed6d982
--- /dev/null
+++ b/trek/events.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)events.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** CAUSE TIME TO ELAPSE
+**
+** This routine does a hell of a lot. It elapses time, eats up
+** energy, regenerates energy, processes any events that occur,
+** and so on.
+*/
+
+
+events(warp)
+int warp; /* set if called in a time warp */
+{
+ register int i;
+ int j;
+ struct kling *k;
+ double rtime;
+ double xdate;
+ double idate;
+ struct event *ev, *xsched(), *schedule();
+ int ix, iy;
+ register struct quad *q;
+ register struct event *e;
+ int evnum;
+ int restcancel;
+
+ /* if nothing happened, just allow for any Klingons killed */
+ if (Move.time <= 0.0)
+ {
+ Now.time = Now.resource / Now.klings;
+ return (0);
+ }
+
+ /* indicate that the cloaking device is now working */
+ Ship.cloakgood = 1;
+
+ /* idate is the initial date */
+ idate = Now.date;
+
+ /* schedule attacks if resting too long */
+ if (Move.time > 0.5 && Move.resting)
+ schedule(E_ATTACK, 0.5, 0, 0, 0);
+
+ /* scan the event list */
+ while (1)
+ {
+ restcancel = 0;
+ evnum = -1;
+ /* xdate is the date of the current event */
+ xdate = idate + Move.time;
+
+ /* find the first event that has happened */
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode == 0 || (e->evcode & E_GHOST))
+ continue;
+ if (e->date < xdate)
+ {
+ xdate = e->date;
+ ev = e;
+ evnum = i;
+ }
+ }
+ e = ev;
+
+ /* find the time between events */
+ rtime = xdate - Now.date;
+
+ /* decrement the magic "Federation Resources" pseudo-variable */
+ Now.resource -= Now.klings * rtime;
+ /* and recompute the time left */
+ Now.time = Now.resource / Now.klings;
+
+ /* move us up to the next date */
+ Now.date = xdate;
+
+ /* check for out of time */
+ if (Now.time <= 0.0)
+ lose(L_NOTIME);
+# ifdef xTRACE
+ if (evnum >= 0 && Trace)
+ printf("xdate = %.2f, evcode %d params %d %d %d\n",
+ xdate, e->evcode, e->x, e->y, e->systemname);
+# endif
+
+ /* if evnum < 0, no events occurred */
+ if (evnum < 0)
+ break;
+
+ /* otherwise one did. Find out what it is */
+ switch (e->evcode & E_EVENT)
+ {
+
+ case E_SNOVA: /* supernova */
+ /* cause the supernova to happen */
+ snova(-1);
+ /* and schedule the next one */
+ xresched(e, E_SNOVA, 1);
+ break;
+
+ case E_LRTB: /* long range tractor beam */
+ /* schedule the next one */
+ xresched(e, E_LRTB, Now.klings);
+ /* LRTB cannot occur if we are docked */
+ if (Ship.cond != DOCKED)
+ {
+ /* pick a new quadrant */
+ i = ranf(Now.klings) + 1;
+ for (ix = 0; ix < NQUADS; ix++)
+ {
+ for (iy = 0; iy < NQUADS; iy++)
+ {
+ q = &Quad[ix][iy];
+ if (q->stars >= 0)
+ if ((i -= q->klings) <= 0)
+ break;
+ }
+ if (i <= 0)
+ break;
+ }
+
+ /* test for LRTB to same quadrant */
+ if (Ship.quadx == ix && Ship.quady == iy)
+ break;
+
+ /* nope, dump him in the new quadrant */
+ Ship.quadx = ix;
+ Ship.quady = iy;
+ printf("\n%s caught in long range tractor beam\n", Ship.shipname);
+ printf("*** Pulled to quadrant %d,%d\n", Ship.quadx, Ship.quady);
+ Ship.sectx = ranf(NSECTS);
+ Ship.secty = ranf(NSECTS);
+ initquad(0);
+ /* truncate the move time */
+ Move.time = xdate - idate;
+ }
+ break;
+
+ case E_KATSB: /* Klingon attacks starbase */
+ /* if out of bases, forget it */
+ if (Now.bases <= 0)
+ {
+ unschedule(e);
+ break;
+ }
+
+ /* check for starbase and Klingons in same quadrant */
+ for (i = 0; i < Now.bases; i++)
+ {
+ ix = Now.base[i].x;
+ iy = Now.base[i].y;
+ /* see if a Klingon exists in this quadrant */
+ q = &Quad[ix][iy];
+ if (q->klings <= 0)
+ continue;
+
+ /* see if already distressed */
+ for (j = 0; j < MAXEVENTS; j++)
+ {
+ e = &Event[j];
+ if ((e->evcode & E_EVENT) != E_KDESB)
+ continue;
+ if (e->x == ix && e->y == iy)
+ break;
+ }
+ if (j < MAXEVENTS)
+ continue;
+
+ /* got a potential attack */
+ break;
+ }
+ e = ev;
+ if (i >= Now.bases)
+ {
+ /* not now; wait a while and see if some Klingons move in */
+ reschedule(e, 0.5 + 3.0 * franf());
+ break;
+ }
+ /* schedule a new attack, and a destruction of the base */
+ xresched(e, E_KATSB, 1);
+ e = xsched(E_KDESB, 1, ix, iy, 0);
+
+ /* report it if we can */
+ if (!damaged(SSRADIO))
+ {
+ printf("\nUhura: Captain, we have recieved a distress signal\n");
+ printf(" from the starbase in quadrant %d,%d.\n",
+ ix, iy);
+ restcancel++;
+ }
+ else
+ /* SSRADIO out, make it so we can't see the distress call */
+ /* but it's still there!!! */
+ e->evcode |= E_HIDDEN;
+ break;
+
+ case E_KDESB: /* Klingon destroys starbase */
+ unschedule(e);
+ q = &Quad[e->x][e->y];
+ /* if the base has mysteriously gone away, or if the Klingon
+ got tired and went home, ignore this event */
+ if (q->bases <=0 || q->klings <= 0)
+ break;
+ /* are we in the same quadrant? */
+ if (e->x == Ship.quadx && e->y == Ship.quady)
+ {
+ /* yep, kill one in this quadrant */
+ printf("\nSpock: ");
+ killb(Ship.quadx, Ship.quady);
+ }
+ else
+ /* kill one in some other quadrant */
+ killb(e->x, e->y);
+ break;
+
+ case E_ISSUE: /* issue a distress call */
+ xresched(e, E_ISSUE, 1);
+ /* if we already have too many, throw this one away */
+ if (Ship.distressed >= MAXDISTR)
+ break;
+ /* try a whole bunch of times to find something suitable */
+ for (i = 0; i < 100; i++)
+ {
+ ix = ranf(NQUADS);
+ iy = ranf(NQUADS);
+ q = &Quad[ix][iy];
+ /* need a quadrant which is not the current one,
+ which has some stars which are inhabited and
+ not already under attack, which is not
+ supernova'ed, and which has some Klingons in it */
+ if (!((ix == Ship.quadx && iy == Ship.quady) || q->stars < 0 ||
+ (q->qsystemname & Q_DISTRESSED) ||
+ (q->qsystemname & Q_SYSTEM) == 0 || q->klings <= 0))
+ break;
+ }
+ if (i >= 100)
+ /* can't seem to find one; ignore this call */
+ break;
+
+ /* got one!! Schedule its enslavement */
+ Ship.distressed++;
+ e = xsched(E_ENSLV, 1, ix, iy, q->qsystemname);
+ q->qsystemname = (e - Event) | Q_DISTRESSED;
+
+ /* tell the captain about it if we can */
+ if (!damaged(SSRADIO))
+ {
+ printf("\nUhura: Captain, starsystem %s in quadrant %d,%d is under attack\n",
+ Systemname[e->systemname], ix, iy);
+ restcancel++;
+ }
+ else
+ /* if we can't tell him, make it invisible */
+ e->evcode |= E_HIDDEN;
+ break;
+
+ case E_ENSLV: /* starsystem is enslaved */
+ unschedule(e);
+ /* see if current distress call still active */
+ q = &Quad[e->x][e->y];
+ if (q->klings <= 0)
+ {
+ /* no Klingons, clean up */
+ /* restore the system name */
+ q->qsystemname = e->systemname;
+ break;
+ }
+
+ /* play stork and schedule the first baby */
+ e = schedule(E_REPRO, Param.eventdly[E_REPRO] * franf(), e->x, e->y, e->systemname);
+
+ /* report the disaster if we can */
+ if (!damaged(SSRADIO))
+ {
+ printf("\nUhura: We've lost contact with starsystem %s\n",
+ Systemname[e->systemname]);
+ printf(" in quadrant %d,%d.\n",
+ e->x, e->y);
+ }
+ else
+ e->evcode |= E_HIDDEN;
+ break;
+
+ case E_REPRO: /* Klingon reproduces */
+ /* see if distress call is still active */
+ q = &Quad[e->x][e->y];
+ if (q->klings <= 0)
+ {
+ unschedule(e);
+ q->qsystemname = e->systemname;
+ break;
+ }
+ xresched(e, E_REPRO, 1);
+ /* reproduce one Klingon */
+ ix = e->x;
+ iy = e->y;
+ if (Now.klings == 127)
+ break; /* full right now */
+ if (q->klings >= MAXKLQUAD)
+ {
+ /* this quadrant not ok, pick an adjacent one */
+ for (i = ix - 1; i <= ix + 1; i++)
+ {
+ if (i < 0 || i >= NQUADS)
+ continue;
+ for (j = iy - 1; j <= iy + 1; j++)
+ {
+ if (j < 0 || j >= NQUADS)
+ continue;
+ q = &Quad[i][j];
+ /* check for this quad ok (not full & no snova) */
+ if (q->klings >= MAXKLQUAD || q->stars < 0)
+ continue;
+ break;
+ }
+ if (j <= iy + 1)
+ break;
+ }
+ if (j > iy + 1)
+ /* cannot create another yet */
+ break;
+ ix = i;
+ iy = j;
+ }
+ /* deliver the child */
+ q->klings++;
+ Now.klings++;
+ if (ix == Ship.quadx && iy == Ship.quady)
+ {
+ /* we must position Klingon */
+ sector(&ix, &iy);
+ Sect[ix][iy] = KLINGON;
+ k = &Etc.klingon[Etc.nkling++];
+ k->x = ix;
+ k->y = iy;
+ k->power = Param.klingpwr;
+ k->srndreq = 0;
+ compkldist(Etc.klingon[0].dist == Etc.klingon[0].avgdist ? 0 : 1);
+ }
+
+ /* recompute time left */
+ Now.time = Now.resource / Now.klings;
+ break;
+
+ case E_SNAP: /* take a snapshot of the galaxy */
+ xresched(e, E_SNAP, 1);
+ i = (int) Etc.snapshot;
+ i = bmove(Quad, i, sizeof (Quad));
+ i = bmove(Event, i, sizeof (Event));
+ i = bmove(&Now, i, sizeof (Now));
+ Game.snap = 1;
+ break;
+
+ case E_ATTACK: /* Klingons attack during rest period */
+ if (!Move.resting)
+ {
+ unschedule(e);
+ break;
+ }
+ attack(1);
+ reschedule(e, 0.5);
+ break;
+
+ case E_FIXDV:
+ i = e->systemname;
+ unschedule(e);
+
+ /* de-damage the device */
+ printf("%s reports repair work on the %s finished.\n",
+ Device[i].person, Device[i].name);
+
+ /* handle special processing upon fix */
+ switch (i)
+ {
+
+ case LIFESUP:
+ Ship.reserves = Param.reserves;
+ break;
+
+ case SINS:
+ if (Ship.cond == DOCKED)
+ break;
+ printf("Spock has tried to recalibrate your Space Internal Navigation System,\n");
+ printf(" but he has no standard base to calibrate to. Suggest you get\n");
+ printf(" to a starbase immediately so that you can properly recalibrate.\n");
+ Ship.sinsbad = 1;
+ break;
+
+ case SSRADIO:
+ restcancel = dumpssradio();
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (restcancel && Move.resting && getynpar("Spock: Shall we cancel our rest period"))
+ Move.time = xdate - idate;
+
+ }
+
+ /* unschedule an attack during a rest period */
+ if (e = Now.eventptr[E_ATTACK])
+ unschedule(e);
+
+ if (!warp)
+ {
+ /* eat up energy if cloaked */
+ if (Ship.cloaked)
+ Ship.energy -= Param.cloakenergy * Move.time;
+
+ /* regenerate resources */
+ rtime = 1.0 - exp(-Param.regenfac * Move.time);
+ Ship.shield += (Param.shield - Ship.shield) * rtime;
+ Ship.energy += (Param.energy - Ship.energy) * rtime;
+
+ /* decrement life support reserves */
+ if (damaged(LIFESUP) && Ship.cond != DOCKED)
+ Ship.reserves -= Move.time;
+ }
+ return (0);
+}
diff --git a/trek/externs.c b/trek/externs.c
new file mode 100644
index 00000000..5df1d264
--- /dev/null
+++ b/trek/externs.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)externs.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** global variable definitions
+*/
+
+struct device Device[NDEV] =
+{
+ "warp drive", "Scotty",
+ "S.R. scanners", "Scotty",
+ "L.R. scanners", "Scotty",
+ "phasers", "Sulu",
+ "photon tubes", "Sulu",
+ "impulse engines", "Scotty",
+ "shield control", "Sulu",
+ "computer", "Spock",
+ "subspace radio", "Uhura",
+ "life support", "Scotty",
+ "navigation system", "Chekov",
+ "cloaking device", "Scotty",
+ "transporter", "Scotty",
+ "shuttlecraft", "Scotty",
+ "*ERR 14*", "Nobody",
+ "*ERR 15*", "Nobody"
+};
+
+char *Systemname[NINHAB] =
+{
+ "ERROR",
+ "Talos IV",
+ "Rigel III",
+ "Deneb VII",
+ "Canopus V",
+ "Icarus I",
+ "Prometheus II",
+ "Omega VII",
+ "Elysium I",
+ "Scalos IV",
+ "Procyon IV",
+ "Arachnid I",
+ "Argo VIII",
+ "Triad III",
+ "Echo IV",
+ "Nimrod III",
+ "Nemisis IV",
+ "Centarurus I",
+ "Kronos III",
+ "Spectros V",
+ "Beta III",
+ "Gamma Tranguli VI",
+ "Pyris III",
+ "Triachus",
+ "Marcus XII",
+ "Kaland",
+ "Ardana",
+ "Stratos",
+ "Eden",
+ "Arrikis",
+ "Epsilon Eridani IV",
+ "Exo III"
+};
diff --git a/trek/getcodi.c b/trek/getcodi.c
new file mode 100644
index 00000000..c10031c3
--- /dev/null
+++ b/trek/getcodi.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getcodi.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "getpar.h"
+
+/*
+** get course and distance
+**
+** The user is asked for a course and distance. This is used by
+** move, impulse, and some of the computer functions.
+**
+** The return value is zero for success, one for an invalid input
+** (meaning to drop the request).
+*/
+
+getcodi(co, di)
+int *co;
+double *di;
+{
+
+ *co = getintpar("Course");
+
+ /* course must be in the interval [0, 360] */
+ if (*co < 0 || *co > 360)
+ return (1);
+ *di = getfltpar("Distance");
+
+ /* distance must be in the interval [0, 15] */
+ if (*di <= 0.0 || *di > 15.0)
+ return (1);
+
+ /* good return */
+ return (0);
+}
diff --git a/trek/getpar.c b/trek/getpar.c
new file mode 100644
index 00000000..70142013
--- /dev/null
+++ b/trek/getpar.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getpar.c 4.8 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <stdio.h>
+# include "getpar.h"
+
+/**
+ ** get integer parameter
+ **/
+
+getintpar(s)
+char *s;
+{
+ register int i;
+ int n;
+
+ while (1)
+ {
+ if (testnl() && s)
+ printf("%s: ", s);
+ i = scanf("%d", &n);
+ if (i < 0)
+ exit(1);
+ if (i > 0 && testterm())
+ return (n);
+ printf("invalid input; please enter an integer\n");
+ skiptonl(0);
+ }
+}
+
+/**
+ ** get floating parameter
+ **/
+
+double getfltpar(s)
+char *s;
+{
+ register int i;
+ double d;
+
+ while (1)
+ {
+ if (testnl() && s)
+ printf("%s: ", s);
+ i = scanf("%lf", &d);
+ if (i < 0)
+ exit(1);
+ if (i > 0 && testterm())
+ return (d);
+ printf("invalid input; please enter a double\n");
+ skiptonl(0);
+ }
+}
+
+/**
+ ** get yes/no parameter
+ **/
+
+struct cvntab Yntab[] =
+{
+ "y", "es", (int (*)())1, 0,
+ "n", "o", (int (*)())0, 0,
+ 0
+};
+
+getynpar(s)
+char *s;
+{
+ struct cvntab *r;
+
+ r = getcodpar(s, Yntab);
+ return ((int) r->value);
+}
+
+
+/**
+ ** get coded parameter
+ **/
+
+struct cvntab *getcodpar(s, tab)
+char *s;
+struct cvntab tab[];
+{
+ char input[100];
+ register struct cvntab *r;
+ int flag;
+ register char *p, *q;
+ int c;
+ int f;
+
+ flag = 0;
+ while (1)
+ {
+ flag |= (f = testnl());
+ if (flag)
+ printf("%s: ", s);
+ if (f)
+ cgetc(0); /* throw out the newline */
+ scanf("%*[ \t;]");
+ if ((c = scanf("%[^ \t;\n]", input)) < 0)
+ exit(1);
+ if (c == 0)
+ continue;
+ flag = 1;
+
+ /* if command list, print four per line */
+ if (input[0] == '?' && input[1] == 0)
+ {
+ c = 4;
+ for (r = tab; r->abrev; r++)
+ {
+ concat(r->abrev, r->full, input);
+ printf("%14.14s", input);
+ if (--c > 0)
+ continue;
+ c = 4;
+ printf("\n");
+ }
+ if (c != 4)
+ printf("\n");
+ continue;
+ }
+
+ /* search for in table */
+ for (r = tab; r->abrev; r++)
+ {
+ p = input;
+ for (q = r->abrev; *q; q++)
+ if (*p++ != *q)
+ break;
+ if (!*q)
+ {
+ for (q = r->full; *p && *q; q++, p++)
+ if (*p != *q)
+ break;
+ if (!*p || !*q)
+ break;
+ }
+ }
+
+ /* check for not found */
+ if (!r->abrev)
+ {
+ printf("invalid input; ? for valid inputs\n");
+ skiptonl(0);
+ }
+ else
+ return (r);
+ }
+}
+
+
+/**
+ ** get string parameter
+ **/
+
+getstrpar(s, r, l, t)
+char *s;
+char *r;
+int l;
+char *t;
+{
+ register int i;
+ char format[20];
+ register int f;
+
+ if (t == 0)
+ t = " \t\n;";
+ (void)sprintf(format, "%%%d[^%s]", l, t);
+ while (1)
+ {
+ if ((f = testnl()) && s)
+ printf("%s: ", s);
+ if (f)
+ cgetc(0);
+ scanf("%*[\t ;]");
+ i = scanf(format, r);
+ if (i < 0)
+ exit(1);
+ if (i != 0)
+ return;
+ }
+}
+
+
+/**
+ ** test if newline is next valid character
+ **/
+
+testnl()
+{
+ register char c;
+
+ while ((c = cgetc(0)) != '\n')
+ if ((c >= '0' && c <= '9') || c == '.' || c == '!' ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') || c == '-')
+ {
+ ungetc(c, stdin);
+ return(0);
+ }
+ ungetc(c, stdin);
+ return (1);
+}
+
+
+/**
+ ** scan for newline
+ **/
+
+skiptonl(c)
+char c;
+{
+ while (c != '\n')
+ if (!(c = cgetc(0)))
+ return;
+ ungetc('\n', stdin);
+ return;
+}
+
+
+/**
+ ** test for valid terminator
+ **/
+
+testterm()
+{
+ register char c;
+
+ if (!(c = cgetc(0)))
+ return (1);
+ if (c == '.')
+ return (0);
+ if (c == '\n' || c == ';')
+ ungetc(c, stdin);
+ return (1);
+}
+
+
+/*
+** TEST FOR SPECIFIED DELIMETER
+**
+** The standard input is scanned for the parameter. If found,
+** it is thrown away and non-zero is returned. If not found,
+** zero is returned.
+*/
+
+readdelim(d)
+char d;
+{
+ register char c;
+
+ while (c = cgetc(0))
+ {
+ if (c == d)
+ return (1);
+ if (c == ' ')
+ continue;
+ ungetc(c, stdin);
+ break;
+ }
+ return (0);
+}
diff --git a/trek/getpar.h b/trek/getpar.h
new file mode 100644
index 00000000..4da3b071
--- /dev/null
+++ b/trek/getpar.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)getpar.h 5.4 (Berkeley) 6/1/90
+ */
+
+struct cvntab /* used for getcodpar() paramater list */
+{
+ char *abrev;
+ char *full;
+ int (*value)();
+ int value2;
+};
+
+extern double getfltpar();
+extern struct cvntab *getcodpar();
diff --git a/trek/help.c b/trek/help.c
new file mode 100644
index 00000000..091210b0
--- /dev/null
+++ b/trek/help.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)help.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** call starbase for help
+**
+** First, the closest starbase is selected. If there is a
+** a starbase in your own quadrant, you are in good shape.
+** This distance takes quadrant distances into account only.
+**
+** A magic number is computed based on the distance which acts
+** as the probability that you will be rematerialized. You
+** get three tries.
+**
+** When it is determined that you should be able to be remater-
+** ialized (i.e., when the probability thing mentioned above
+** comes up positive), you are put into that quadrant (anywhere).
+** Then, we try to see if there is a spot adjacent to the star-
+** base. If not, you can't be rematerialized!!! Otherwise,
+** it drops you there. It only tries five times to find a spot
+** to drop you. After that, it's your problem.
+*/
+
+char *Cntvect[3] =
+{"first", "second", "third"};
+
+help()
+{
+ register int i;
+ double dist, x;
+ register int dx, dy;
+ int j, l;
+
+ /* check to see if calling for help is reasonable ... */
+ if (Ship.cond == DOCKED)
+ return (printf("Uhura: But Captain, we're already docked\n"));
+
+ /* or possible */
+ if (damaged(SSRADIO))
+ return (out(SSRADIO));
+ if (Now.bases <= 0)
+ return (printf("Uhura: I'm not getting any response from starbase\n"));
+
+ /* tut tut, there goes the score */
+ Game.helps += 1;
+
+ /* find the closest base */
+ dist = 1e50;
+ if (Quad[Ship.quadx][Ship.quady].bases <= 0)
+ {
+ /* there isn't one in this quadrant */
+ for (i = 0; i < Now.bases; i++)
+ {
+ /* compute distance */
+ dx = Now.base[i].x - Ship.quadx;
+ dy = Now.base[i].y - Ship.quady;
+ x = dx * dx + dy * dy;
+ x = sqrt(x);
+
+ /* see if better than what we already have */
+ if (x < dist)
+ {
+ dist = x;
+ l = i;
+ }
+ }
+
+ /* go to that quadrant */
+ Ship.quadx = Now.base[l].x;
+ Ship.quady = Now.base[l].y;
+ initquad(1);
+ }
+ else
+ {
+ dist = 0.0;
+ }
+
+ /* dematerialize the Enterprise */
+ Sect[Ship.sectx][Ship.secty] = EMPTY;
+ printf("Starbase in %d,%d responds\n", Ship.quadx, Ship.quady);
+
+ /* this next thing acts as a probability that it will work */
+ x = pow(1.0 - pow(0.94, dist), 0.3333333);
+
+ /* attempt to rematerialize */
+ for (i = 0; i < 3; i++)
+ {
+ sleep(2);
+ printf("%s attempt to rematerialize ", Cntvect[i]);
+ if (franf() > x)
+ {
+ /* ok, that's good. let's see if we can set her down */
+ for (j = 0; j < 5; j++)
+ {
+ dx = Etc.starbase.x + ranf(3) - 1;
+ if (dx < 0 || dx >= NSECTS)
+ continue;
+ dy = Etc.starbase.y + ranf(3) - 1;
+ if (dy < 0 || dy >= NSECTS || Sect[dx][dy] != EMPTY)
+ continue;
+ break;
+ }
+ if (j < 5)
+ {
+ /* found an empty spot */
+ printf("succeeds\n");
+ Ship.sectx = dx;
+ Ship.secty = dy;
+ Sect[dx][dy] = Ship.ship;
+ dock();
+ compkldist(0);
+ return;
+ }
+ /* the starbase must have been surrounded */
+ }
+ printf("fails\n");
+ }
+
+ /* one, two, three strikes, you're out */
+ lose(L_NOHELP);
+}
diff --git a/trek/impulse.c b/trek/impulse.c
new file mode 100644
index 00000000..9905b338
--- /dev/null
+++ b/trek/impulse.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)impulse.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/**
+ ** move under impulse power
+ **/
+
+impulse()
+{
+ int course;
+ register int power;
+ double dist, time;
+ register int percent;
+ extern double move();
+
+ if (Ship.cond == DOCKED)
+ return (printf("Scotty: Sorry captain, but we are still docked.\n"));
+ if (damaged(IMPULSE))
+ return (out(IMPULSE));
+ if (getcodi(&course, &dist))
+ return;
+ power = 20 + 100 * dist;
+ percent = 100 * power / Ship.energy + 0.5;
+ if (percent >= 85)
+ {
+ printf("Scotty: That would consume %d%% of our remaining energy.\n",
+ percent);
+ if (!getynpar("Are you sure that is wise"))
+ return;
+ printf("Aye aye, sir\n");
+ }
+ time = dist / 0.095;
+ percent = 100 * time / Now.time + 0.5;
+ if (percent >= 85)
+ {
+ printf("Spock: That would take %d%% of our remaining time.\n",
+ percent);
+ if (!getynpar("Are you sure that is wise"))
+ return;
+ printf("(He's finally gone mad)\n");
+ }
+ Move.time = move(0, course, time, 0.095);
+ Ship.energy -= 20 + 100 * Move.time * 0.095;
+}
diff --git a/trek/initquad.c b/trek/initquad.c
new file mode 100644
index 00000000..b644a7f5
--- /dev/null
+++ b/trek/initquad.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)initquad.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Paramize Quadrant Upon Entering
+**
+** A quadrant is initialized from the information held in the
+** Quad matrix. Basically, everything is just initialized
+** randomly, except for the starship, which goes into a fixed
+** sector.
+**
+** If there are Klingons in the quadrant, the captain is informed
+** that the condition is RED, and he is given a chance to put
+** his shields up if the computer is working.
+**
+** The flag `f' is set to disable the check for condition red.
+** This mode is used in situations where you know you are going
+** to be docked, i.e., abandon() and help().
+*/
+
+initquad(f)
+int f;
+{
+ register int i, j;
+ int rx, ry;
+ int nbases, nstars;
+ register struct quad *q;
+ int nholes;
+
+ q = &Quad[Ship.quadx][Ship.quady];
+
+ /* ignored supernova'ed quadrants (this is checked again later anyway */
+ if (q->stars < 0)
+ return;
+ Etc.nkling = q->klings;
+ nbases = q->bases;
+ nstars = q->stars;
+ nholes = q->holes;
+
+ /* have we blundered into a battle zone w/ shields down? */
+ if (Etc.nkling > 0 && !f)
+ {
+ printf("Condition RED\n");
+ Ship.cond = RED;
+ if (!damaged(COMPUTER))
+ shield(1);
+ }
+
+ /* clear out the quadrant */
+ for (i = 0; i < NSECTS; i++)
+ for (j = 0; j < NSECTS; j++)
+ Sect[i][j] = EMPTY;
+
+ /* initialize Enterprise */
+ Sect[Ship.sectx][Ship.secty] = Ship.ship;
+
+ /* initialize Klingons */
+ for (i = 0; i < Etc.nkling; i++)
+ {
+ sector(&rx, &ry);
+ Sect[rx][ry] = KLINGON;
+ Etc.klingon[i].x = rx;
+ Etc.klingon[i].y = ry;
+ Etc.klingon[i].power = Param.klingpwr;
+ Etc.klingon[i].srndreq = 0;
+ }
+ compkldist(1);
+
+ /* initialize star base */
+ if (nbases > 0)
+ {
+ sector(&rx, &ry);
+ Sect[rx][ry] = BASE;
+ Etc.starbase.x = rx;
+ Etc.starbase.y = ry;
+ }
+
+ /* initialize inhabited starsystem */
+ if (q->qsystemname != 0)
+ {
+ sector(&rx, &ry);
+ Sect[rx][ry] = INHABIT;
+ nstars -= 1;
+ }
+
+ /* initialize black holes */
+ for (i = 0; i < nholes; i++)
+ {
+ sector(&rx, &ry);
+ Sect[rx][ry] = HOLE;
+ }
+
+ /* initialize stars */
+ for (i = 0; i < nstars; i++)
+ {
+ sector(&rx, &ry);
+ Sect[rx][ry] = STAR;
+ }
+ Move.newquad = 1;
+}
+
+
+sector(x, y)
+int *x, *y;
+{
+ register int i, j;
+
+ do
+ {
+ i = ranf(NSECTS);
+ j = ranf(NSECTS);
+ } while (Sect[i][j] != EMPTY);
+ *x = i;
+ *y = j;
+ return;
+}
diff --git a/trek/kill.c b/trek/kill.c
new file mode 100644
index 00000000..51a5ca6b
--- /dev/null
+++ b/trek/kill.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)kill.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** KILL KILL KILL !!!
+**
+** This file handles the killing off of almost anything.
+*/
+
+/*
+** Handle a Klingon's death
+**
+** The Klingon at the sector given by the parameters is killed
+** and removed from the Klingon list. Notice that it is not
+** removed from the event list; this is done later, when the
+** the event is to be caught. Also, the time left is recomputed,
+** and the game is won if that was the last klingon.
+*/
+
+killk(ix, iy)
+int ix, iy;
+{
+ register int i, j;
+
+ printf(" *** Klingon at %d,%d destroyed ***\n", ix, iy);
+
+ /* remove the scoundrel */
+ Now.klings -= 1;
+ Sect[ix][iy] = EMPTY;
+ Quad[Ship.quadx][Ship.quady].klings -= 1;
+ /* %%% IS THIS SAFE???? %%% */
+ Quad[Ship.quadx][Ship.quady].scanned -= 100;
+ Game.killk += 1;
+
+ /* find the Klingon in the Klingon list */
+ for (i = 0; i < Etc.nkling; i++)
+ if (ix == Etc.klingon[i].x && iy == Etc.klingon[i].y)
+ {
+ /* purge him from the list */
+ Etc.nkling -= 1;
+ for (; i < Etc.nkling; i++)
+ bmove(&Etc.klingon[i+1], &Etc.klingon[i], sizeof Etc.klingon[i]);
+ break;
+ }
+
+ /* find out if that was the last one */
+ if (Now.klings <= 0)
+ win();
+
+ /* recompute time left */
+ Now.time = Now.resource / Now.klings;
+ return;
+}
+
+
+/*
+** handle a starbase's death
+*/
+
+killb(qx, qy)
+int qx, qy;
+{
+ register struct quad *q;
+ register struct xy *b;
+
+ q = &Quad[qx][qy];
+
+ if (q->bases <= 0)
+ return;
+ if (!damaged(SSRADIO))
+ /* then update starchart */
+ if (q->scanned < 1000)
+ q->scanned -= 10;
+ else
+ if (q->scanned > 1000)
+ q->scanned = -1;
+ q->bases = 0;
+ Now.bases -= 1;
+ for (b = Now.base; ; b++)
+ if (qx == b->x && qy == b->y)
+ break;
+ bmove(&Now.base[Now.bases], b, sizeof *b);
+ if (qx == Ship.quadx && qy == Ship.quady)
+ {
+ Sect[Etc.starbase.x][Etc.starbase.y] = EMPTY;
+ if (Ship.cond == DOCKED)
+ undock();
+ printf("Starbase at %d,%d destroyed\n", Etc.starbase.x, Etc.starbase.y);
+ }
+ else
+ {
+ if (!damaged(SSRADIO))
+ {
+ printf("Uhura: Starfleet command reports that the starbase in\n");
+ printf(" quadrant %d,%d has been destroyed\n", qx, qy);
+ }
+ else
+ schedule(E_KATSB | E_GHOST, 1e50, qx, qy, 0);
+ }
+}
+
+
+/**
+ ** kill an inhabited starsystem
+ **/
+
+kills(x, y, f)
+int x, y; /* quad coords if f == 0, else sector coords */
+int f; /* f != 0 -- this quad; f < 0 -- Enterprise's fault */
+{
+ register struct quad *q;
+ register struct event *e;
+ register char *name;
+ char *systemname();
+
+ if (f)
+ {
+ /* current quadrant */
+ q = &Quad[Ship.quadx][Ship.quady];
+ Sect[x][y] = EMPTY;
+ name = systemname(q);
+ if (name == 0)
+ return;
+ printf("Inhabited starsystem %s at %d,%d destroyed\n",
+ name, x, y);
+ if (f < 0)
+ Game.killinhab += 1;
+ }
+ else
+ {
+ /* different quadrant */
+ q = &Quad[x][y];
+ }
+ if (q->qsystemname & Q_DISTRESSED)
+ {
+ /* distressed starsystem */
+ e = &Event[q->qsystemname & Q_SYSTEM];
+ printf("Distress call for %s invalidated\n",
+ Systemname[e->systemname]);
+ unschedule(e);
+ }
+ q->qsystemname = 0;
+ q->stars -= 1;
+}
+
+
+/**
+ ** "kill" a distress call
+ **/
+
+killd(x, y, f)
+int x, y; /* quadrant coordinates */
+int f; /* set if user is to be informed */
+{
+ register struct event *e;
+ register int i;
+ register struct quad *q;
+
+ q = &Quad[x][y];
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->x != x || e->y != y)
+ continue;
+ switch (e->evcode)
+ {
+ case E_KDESB:
+ if (f)
+ {
+ printf("Distress call for starbase in %d,%d nullified\n",
+ x, y);
+ unschedule(e);
+ }
+ break;
+
+ case E_ENSLV:
+ case E_REPRO:
+ if (f)
+ {
+ printf("Distress call for %s in quadrant %d,%d nullified\n",
+ Systemname[e->systemname], x, y);
+ q->qsystemname = e->systemname;
+ unschedule(e);
+ }
+ else
+ {
+ e->evcode |= E_GHOST;
+ }
+ }
+ }
+}
diff --git a/trek/klmove.c b/trek/klmove.c
new file mode 100644
index 00000000..ca9ba1ce
--- /dev/null
+++ b/trek/klmove.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)klmove.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Move Klingons Around
+**
+** This is a largely incomprehensible block of code that moves
+** Klingons around in a quadrant. It was written in a very
+** "program as you go" fashion, and is a prime candidate for
+** rewriting.
+**
+** The flag `fl' is zero before an attack, one after an attack,
+** and two if you are leaving a quadrant. This serves to
+** change the probability and distance that it moves.
+**
+** Basically, what it will try to do is to move a certain number
+** of steps either toward you or away from you. It will avoid
+** stars whenever possible. Nextx and nexty are the next
+** sector to move to on a per-Klingon basis; they are roughly
+** equivalent to Ship.sectx and Ship.secty for the starship. Lookx and
+** looky are the sector that you are going to look at to see
+** if you can move their. Dx and dy are the increment. Fudgex
+** and fudgey are the things you change around to change your
+** course around stars.
+*/
+
+klmove(fl)
+int fl;
+{
+ int n;
+ register struct kling *k;
+ double dx, dy;
+ int nextx, nexty;
+ register int lookx, looky;
+ int motion;
+ int fudgex, fudgey;
+ int qx, qy;
+ double bigger;
+ int i;
+
+# ifdef xTRACE
+ if (Trace)
+ printf("klmove: fl = %d, Etc.nkling = %d\n", fl, Etc.nkling);
+# endif
+ for (n = 0; n < Etc.nkling; k && n++)
+ {
+ k = &Etc.klingon[n];
+ i = 100;
+ if (fl)
+ i = 100.0 * k->power / Param.klingpwr;
+ if (ranf(i) >= Param.moveprob[2 * Move.newquad + fl])
+ continue;
+ /* compute distance to move */
+ motion = ranf(75) - 25;
+ motion *= k->avgdist * Param.movefac[2 * Move.newquad + fl];
+ /* compute direction */
+ dx = Ship.sectx - k->x + ranf(3) - 1;
+ dy = Ship.secty - k->y + ranf(3) - 1;
+ bigger = dx;
+ if (dy > bigger)
+ bigger = dy;
+ if (bigger == 0.0)
+ bigger = 1.0;
+ dx = dx / bigger + 0.5;
+ dy = dy / bigger + 0.5;
+ if (motion < 0)
+ {
+ motion = -motion;
+ dx = -dx;
+ dy = -dy;
+ }
+ fudgex = fudgey = 1;
+ /* try to move the klingon */
+ nextx = k->x;
+ nexty = k->y;
+ for (; motion > 0; motion--)
+ {
+ lookx = nextx + dx;
+ looky = nexty + dy;
+ if (lookx < 0 || lookx >= NSECTS || looky < 0 || looky >= NSECTS)
+ {
+ /* new quadrant */
+ qx = Ship.quadx;
+ qy = Ship.quady;
+ if (lookx < 0)
+ qx -= 1;
+ else
+ if (lookx >= NSECTS)
+ qx += 1;
+ if (looky < 0)
+ qy -= 1;
+ else
+ if (looky >= NSECTS)
+ qy += 1;
+ if (qx < 0 || qx >= NQUADS || qy < 0 || qy >= NQUADS ||
+ Quad[qx][qy].stars < 0 || Quad[qx][qy].klings > MAXKLQUAD - 1)
+ break;
+ if (!damaged(SRSCAN))
+ {
+ printf("Klingon at %d,%d escapes to quadrant %d,%d\n",
+ k->x, k->y, qx, qy);
+ motion = Quad[qx][qy].scanned;
+ if (motion >= 0 && motion < 1000)
+ Quad[qx][qy].scanned += 100;
+ motion = Quad[Ship.quadx][Ship.quady].scanned;
+ if (motion >= 0 && motion < 1000)
+ Quad[Ship.quadx][Ship.quady].scanned -= 100;
+ }
+ Sect[k->x][k->y] = EMPTY;
+ Quad[qx][qy].klings += 1;
+ Etc.nkling -= 1;
+ bmove(&Etc.klingon[Etc.nkling], k, sizeof *k);
+ Quad[Ship.quadx][Ship.quady].klings -= 1;
+ k = 0;
+ break;
+ }
+ if (Sect[lookx][looky] != EMPTY)
+ {
+ lookx = nextx + fudgex;
+ if (lookx < 0 || lookx >= NSECTS)
+ lookx = nextx + dx;
+ if (Sect[lookx][looky] != EMPTY)
+ {
+ fudgex = -fudgex;
+ looky = nexty + fudgey;
+ if (looky < 0 || looky >= NSECTS || Sect[lookx][looky] != EMPTY)
+ {
+ fudgey = -fudgey;
+ break;
+ }
+ }
+ }
+ nextx = lookx;
+ nexty = looky;
+ }
+ if (k && (k->x != nextx || k->y != nexty))
+ {
+ if (!damaged(SRSCAN))
+ printf("Klingon at %d,%d moves to %d,%d\n",
+ k->x, k->y, nextx, nexty);
+ Sect[k->x][k->y] = EMPTY;
+ Sect[k->x = nextx][k->y = nexty] = KLINGON;
+ }
+ }
+ compkldist(0);
+}
diff --git a/trek/lose.c b/trek/lose.c
new file mode 100644
index 00000000..27fa0c75
--- /dev/null
+++ b/trek/lose.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lose.c 5.6 (Berkeley) 6/26/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include <setjmp.h>
+
+/*
+** PRINT OUT LOSER MESSAGES
+**
+** The messages are printed out, the score is computed and
+** printed, and the game is restarted. Oh yeh, any special
+** actions which need be taken are taken.
+*/
+
+char *Losemsg[] =
+{
+ "You ran out of time",
+ "You ran out of energy",
+ "You have been destroyed",
+ "You ran into the negative energy barrier",
+ "You destroyed yourself by nova'ing that star",
+ "You have been caught in a supernova",
+ "You just suffocated in outer space",
+ "You could not be rematerialized",
+ "\n\032\014 ***\07 Ship's hull has imploded\07 ***",
+ "You have burned up in a star",
+ "Well, you destroyed yourself, but it didn't do any good",
+ "You have been captured by Klingons and mercilessly tortured",
+ "Your last crew member died",
+};
+
+lose(why)
+int why;
+{
+ extern jmp_buf env;
+
+ Game.killed = 1;
+ sleep(1);
+ printf("\n%s\n", Losemsg[why - 1]);
+ switch (why)
+ {
+
+ case L_NOTIME:
+ Game.killed = 0;
+ break;
+ }
+ Move.endgame = -1;
+ score();
+ skiptonl(0);
+ longjmp(env, 1);
+}
diff --git a/trek/lrscan.c b/trek/lrscan.c
new file mode 100644
index 00000000..ff603868
--- /dev/null
+++ b/trek/lrscan.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lrscan.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** LONG RANGE OF SCANNERS
+**
+** A summary of the quadrants that surround you is printed. The
+** hundreds digit is the number of Klingons in the quadrant,
+** the tens digit is the number of starbases, and the units digit
+** is the number of stars. If the printout is "///" it means
+** that that quadrant is rendered uninhabitable by a supernova.
+** It also updates the "scanned" field of the quadrants it scans,
+** for future use by the "chart" option of the computer.
+*/
+
+lrscan()
+{
+ register int i, j;
+ register struct quad *q;
+
+ if (check_out(LRSCAN))
+ {
+ return;
+ }
+ printf("Long range scan for quadrant %d,%d\n\n", Ship.quadx, Ship.quady);
+
+ /* print the header on top */
+ for (j = Ship.quady - 1; j <= Ship.quady + 1; j++)
+ {
+ if (j < 0 || j >= NQUADS)
+ printf(" ");
+ else
+ printf(" %1d", j);
+ }
+
+ /* scan the quadrants */
+ for (i = Ship.quadx - 1; i <= Ship.quadx + 1; i++)
+ {
+ printf("\n -------------------\n");
+ if (i < 0 || i >= NQUADS)
+ {
+ /* negative energy barrier */
+ printf(" ! * ! * ! * !");
+ continue;
+ }
+
+ /* print the left hand margin */
+ printf("%1d !", i);
+ for (j = Ship.quady - 1; j <= Ship.quady + 1; j++)
+ {
+ if (j < 0 || j >= NQUADS)
+ {
+ /* negative energy barrier again */
+ printf(" * !");
+ continue;
+ }
+ q = &Quad[i][j];
+ if (q->stars < 0)
+ {
+ /* supernova */
+ printf(" /// !");
+ q->scanned = 1000;
+ continue;
+ }
+ q->scanned = q->klings * 100 + q->bases * 10 + q->stars;
+ printf(" %3d !", q->scanned);
+ }
+ }
+ printf("\n -------------------\n");
+ return;
+}
diff --git a/trek/main.c b/trek/main.c
new file mode 100644
index 00000000..3cad83c2
--- /dev/null
+++ b/trek/main.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.7 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+# include "trek.h"
+# include <stdio.h>
+# include <sgtty.h>
+# include <setjmp.h>
+
+# define PRIO 00 /* default priority */
+
+int Mother = 51 + (51 << 8);
+
+/*
+** #### ##### # #### ##### #### ##### # #
+** # # # # # # # # # # # #
+** ### # ##### #### # #### ### ###
+** # # # # # # # # # # # #
+** #### # # # # # # # # ##### # #
+**
+** C version by Eric P. Allman 5/76 (U.C. Berkeley) with help
+** from Jeff Poskanzer and Pete Rubinstein.
+**
+** I also want to thank everyone here at Berkeley who
+** where crazy enough to play the undebugged game. I want to
+** particularly thank Nick Whyte, who made considerable
+** suggestions regarding the content of the game. Why, I'll
+** never forget the time he suggested the name for the
+** "capture" command.
+**
+** Please send comments, questions, and suggestions about this
+** game to:
+** Eric P. Allman
+** Project INGRES
+** Electronics Research Laboratory
+** Cory Hall
+** University of California
+** Berkeley, California 94720
+**
+** If you make ANY changes in the game, I sure would like to
+** know about them. It is sort of an ongoing project for me,
+** and I very much want to put in any bug fixes and improvements
+** that you might come up with.
+**
+** FORTRASH version by Kay R. Fisher (DEC) "and countless others".
+** That was adapted from the "original BASIC program" (ha!) by
+** Mike Mayfield (Centerline Engineering).
+**
+** Additional inspiration taken from FORTRAN version by
+** David Matuszek and Paul Reynolds which runs on the CDC
+** 7600 at Lawrence Berkeley Lab, maintained there by
+** Andy Davidson. This version is also available at LLL
+** and at LMSC. In all fairness, this version was the
+** major inspiration for this version of the game (trans-
+** lation: I ripped off a whole lot of code).
+**
+** Minor other input from the "Battelle Version 7A" by Joe Miller
+** (Graphics Systems Group, Battelle-Columbus Labs) and
+** Ross Pavlac (Systems Programmer, Battelle Memorial
+** Institute). That version was written in December '74
+** and extensively modified June '75. It was adapted
+** from the FTN version by Ron Williams of CDC Sunnyvale,
+** which was adapted from the Basic version distributed
+** by DEC. It also had "neat stuff swiped" from T. T.
+** Terry and Jim Korp (University of Texas), Hicks (Penn
+** U.), and Rick Maus (Georgia Tech). Unfortunately, it
+** was not as readable as it could have been and so the
+** translation effort was severely hampered. None the
+** less, I got the idea of inhabited starsystems from this
+** version.
+**
+** Permission is given for use, copying, and modification of
+** all or part of this program and related documentation,
+** provided that all reference to the authors are maintained.
+**
+**
+**********************************************************************
+**
+** NOTES TO THE MAINTAINER:
+**
+** There is a compilation option xTRACE which must be set for any
+** trace information to be generated. It is probably defined in
+** the version that you get. It can be removed, however, if you
+** have trouble finding room in core.
+**
+** Many things in trek are not as clear as they might be, but are
+** done to reduce space. I compile with the -f and -O flags. I
+** am constrained to running with non-seperated I/D space, since
+** we don't have doubleing point hardware here; even if we did, I
+** would like trek to be available to the large number of people
+** who either have an 11/40 or do not have FP hardware. I also
+** found it desirable to make the code run reentrant, so this
+** added even more space constraints.
+**
+** I use the portable C library to do my I/O. This is done be-
+** cause I wanted the game easily transportable to other C
+** implementations, and because I was too lazy to do the doubleing
+** point input myself. Little did I know. The portable C library
+** released by Bell Labs has more bugs than you would believe, so
+** I ended up rewriting the whole blessed thing. Trek excercises
+** many of the bugs in it, as well as bugs in some of the section
+** III UNIX routines. We have fixed them here. One main problem
+** was a bug in alloc() that caused it to always ask for a large
+** hunk of memory, which worked fine unless you were almost out,
+** which I inevitably was. If you want the code for all of this
+** stuff, it is also available through me.
+**
+***********************************************************************
+*/
+
+jmp_buf env;
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ long vect;
+ /* extern FILE *f_log; */
+ register char opencode;
+ int prio;
+ register int ac;
+ register char **av;
+ struct sgttyb argp;
+
+ av = argv;
+ ac = argc;
+ av++;
+ time(&vect);
+ srand(vect);
+ opencode = 'w';
+ prio = PRIO;
+ if (gtty(1, &argp) == 0)
+ {
+ if ((argp.sg_ispeed ) < B1200)
+ Etc.fast++;
+ }
+ while (ac > 1 && av[0][0] == '-')
+ {
+ switch (av[0][1])
+ {
+ case 'a': /* append to log file */
+ opencode = 'a';
+ break;
+
+ case 'f': /* set fast mode */
+ Etc.fast++;
+ break;
+
+ case 's': /* set slow mode */
+ Etc.fast = 0;
+ break;
+
+# ifdef xTRACE
+ case 't': /* trace */
+ if (getuid() != Mother)
+ goto badflag;
+ Trace++;
+ break;
+# endif
+
+ case 'p': /* set priority */
+ if (getuid() != Mother)
+ goto badflag;
+ prio = atoi(av[0] + 2);
+ break;
+
+ default:
+ badflag:
+ printf("Invalid option: %s\n", av[0]);
+
+ }
+ ac--;
+ av++;
+ }
+ if (ac > 2)
+ syserr(0, "arg count");
+ /*
+ if (ac > 1)
+ f_log = fopen(av[0], opencode);
+ */
+
+ printf("\n * * * S T A R T R E K * * *\n\nPress return to continue.\n");
+
+ if (setjmp(env))
+ {
+ if ( !getynpar("Another game") )
+ exit(0);
+ }
+ do
+ {
+ setup();
+ play();
+ } while (getynpar("Another game"));
+
+ fflush(stdout);
+}
diff --git a/trek/move.c b/trek/move.c
new file mode 100644
index 00000000..68bc9dc8
--- /dev/null
+++ b/trek/move.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)move.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Move Under Warp or Impulse Power
+**
+** `Ramflag' is set if we are to be allowed to ram stars,
+** Klingons, etc. This is passed from warp(), which gets it from
+** either play() or ram(). Course is the course (0 -> 360) at
+** which we want to move. `Speed' is the speed we
+** want to go, and `time' is the expected time. It
+** can get cut short if a long range tractor beam is to occur. We
+** cut short the move so that the user doesn't get docked time and
+** energy for distance which he didn't travel.
+**
+** We check the course through the current quadrant to see that he
+** doesn't run into anything. After that, though, space sort of
+** bends around him. Note that this puts us in the awkward posi-
+** tion of being able to be dropped into a sector which is com-
+** pletely surrounded by stars. Oh Well.
+**
+** If the SINS (Space Inertial Navigation System) is out, we ran-
+** domize the course accordingly before ever starting to move.
+** We will still move in a straight line.
+**
+** Note that if your computer is out, you ram things anyway. In
+** other words, if your computer and sins are both out, you're in
+** potentially very bad shape.
+**
+** Klingons get a chance to zap you as you leave the quadrant.
+** By the way, they also try to follow you (heh heh).
+**
+** Return value is the actual amount of time used.
+**
+**
+** Uses trace flag 4.
+*/
+
+double move(ramflag, course, time, speed)
+int ramflag;
+int course;
+double time;
+double speed;
+{
+ double angle;
+ double x, y, dx, dy;
+ register int ix, iy;
+ double bigger;
+ int n;
+ register int i;
+ double dist;
+ double sectsize;
+ double xn;
+ double evtime;
+
+# ifdef xTRACE
+ if (Trace)
+ printf("move: ramflag %d course %d time %.2f speed %.2f\n",
+ ramflag, course, time, speed);
+# endif
+ sectsize = NSECTS;
+ /* initialize delta factors for move */
+ angle = course * 0.0174532925;
+ if (damaged(SINS))
+ angle += Param.navigcrud[1] * (franf() - 0.5);
+ else
+ if (Ship.sinsbad)
+ angle += Param.navigcrud[0] * (franf() - 0.5);
+ dx = -cos(angle);
+ dy = sin(angle);
+ bigger = fabs(dx);
+ dist = fabs(dy);
+ if (dist > bigger)
+ bigger = dist;
+ dx /= bigger;
+ dy /= bigger;
+
+ /* check for long range tractor beams */
+ /**** TEMPORARY CODE == DEBUGGING ****/
+ evtime = Now.eventptr[E_LRTB]->date - Now.date;
+# ifdef xTRACE
+ if (Trace)
+ printf("E.ep = %u, ->evcode = %d, ->date = %.2f, evtime = %.2f\n",
+ Now.eventptr[E_LRTB], Now.eventptr[E_LRTB]->evcode,
+ Now.eventptr[E_LRTB]->date, evtime);
+# endif
+ if (time > evtime && Etc.nkling < 3)
+ {
+ /* then we got a LRTB */
+ evtime += 0.005;
+ time = evtime;
+ }
+ else
+ evtime = -1.0e50;
+ dist = time * speed;
+
+ /* move within quadrant */
+ Sect[Ship.sectx][Ship.secty] = EMPTY;
+ x = Ship.sectx + 0.5;
+ y = Ship.secty + 0.5;
+ xn = NSECTS * dist * bigger;
+ n = xn + 0.5;
+# ifdef xTRACE
+ if (Trace)
+ printf("dx = %.2f, dy = %.2f, xn = %.2f, n = %d\n", dx, dy, xn, n);
+# endif
+ Move.free = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ ix = (x += dx);
+ iy = (y += dy);
+# ifdef xTRACE
+ if (Trace)
+ printf("ix = %d, x = %.2f, iy = %d, y = %.2f\n", ix, x, iy, y);
+# endif
+ if (x < 0.0 || y < 0.0 || x >= sectsize || y >= sectsize)
+ {
+ /* enter new quadrant */
+ dx = Ship.quadx * NSECTS + Ship.sectx + dx * xn;
+ dy = Ship.quady * NSECTS + Ship.secty + dy * xn;
+ if (dx < 0.0)
+ ix = -1;
+ else
+ ix = dx + 0.5;
+ if (dy < 0.0)
+ iy = -1;
+ else
+ iy = dy + 0.5;
+# ifdef xTRACE
+ if (Trace)
+ printf("New quad: ix = %d, iy = %d\n", ix, iy);
+# endif
+ Ship.sectx = x;
+ Ship.secty = y;
+ compkldist(0);
+ Move.newquad = 2;
+ attack(0);
+ checkcond();
+ Ship.quadx = ix / NSECTS;
+ Ship.quady = iy / NSECTS;
+ Ship.sectx = ix % NSECTS;
+ Ship.secty = iy % NSECTS;
+ if (ix < 0 || Ship.quadx >= NQUADS || iy < 0 || Ship.quady >= NQUADS)
+ if (!damaged(COMPUTER))
+ {
+ dumpme(0);
+ }
+ else
+ lose(L_NEGENB);
+ initquad(0);
+ n = 0;
+ break;
+ }
+ if (Sect[ix][iy] != EMPTY)
+ {
+ /* we just hit something */
+ if (!damaged(COMPUTER) && ramflag <= 0)
+ {
+ ix = x - dx;
+ iy = y - dy;
+ printf("Computer reports navigation error; %s stopped at %d,%d\n",
+ Ship.shipname, ix, iy);
+ Ship.energy -= Param.stopengy * speed;
+ break;
+ }
+ /* test for a black hole */
+ if (Sect[ix][iy] == HOLE)
+ {
+ /* get dumped elsewhere in the galaxy */
+ dumpme(1);
+ initquad(0);
+ n = 0;
+ break;
+ }
+ ram(ix, iy);
+ break;
+ }
+ }
+ if (n > 0)
+ {
+ dx = Ship.sectx - ix;
+ dy = Ship.secty - iy;
+ dist = sqrt(dx * dx + dy * dy) / NSECTS;
+ time = dist / speed;
+ if (evtime > time)
+ time = evtime; /* spring the LRTB trap */
+ Ship.sectx = ix;
+ Ship.secty = iy;
+ }
+ Sect[Ship.sectx][Ship.secty] = Ship.ship;
+ compkldist(0);
+ return (time);
+}
diff --git a/trek/nova.c b/trek/nova.c
new file mode 100644
index 00000000..fc5f584e
--- /dev/null
+++ b/trek/nova.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)nova.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** CAUSE A NOVA TO OCCUR
+**
+** A nova occurs. It is the result of having a star hit with
+** a photon torpedo. There are several things which may happen.
+** The star may not be affected. It may go nova. It may turn
+** into a black hole. Any (yummy) it may go supernova.
+**
+** Stars that go nova cause stars which surround them to undergo
+** the same probabilistic process. Klingons next to them are
+** destroyed. And if the starship is next to it, it gets zapped.
+** If the zap is too much, it gets destroyed.
+*/
+
+nova(x, y)
+int x, y;
+{
+ register int i, j;
+ register int se;
+
+ if (Sect[x][y] != STAR || Quad[Ship.quadx][Ship.quady].stars < 0)
+ return;
+ if (ranf(100) < 15)
+ {
+ printf("Spock: Star at %d,%d failed to nova.\n", x, y);
+ return;
+ }
+ if (ranf(100) < 5)
+ return (snova(x, y));
+ printf("Spock: Star at %d,%d gone nova\n", x, y);
+
+ if (ranf(4) != 0)
+ Sect[x][y] = EMPTY;
+ else
+ {
+ Sect[x][y] = HOLE;
+ Quad[Ship.quadx][Ship.quady].holes += 1;
+ }
+ Quad[Ship.quadx][Ship.quady].stars -= 1;
+ Game.kills += 1;
+ for (i = x - 1; i <= x + 1; i++)
+ {
+ if (i < 0 || i >= NSECTS)
+ continue;
+ for (j = y - 1; j <= y + 1; j++)
+ {
+ if (j < 0 || j >= NSECTS)
+ continue;
+ se = Sect[i][j];
+ switch (se)
+ {
+
+ case EMPTY:
+ case HOLE:
+ break;
+
+ case KLINGON:
+ killk(i, j);
+ break;
+
+ case STAR:
+ nova(i, j);
+ break;
+
+ case INHABIT:
+ kills(i, j, -1);
+ break;
+
+ case BASE:
+ killb(i, j);
+ Game.killb += 1;
+ break;
+
+ case ENTERPRISE:
+ case QUEENE:
+ se = 2000;
+ if (Ship.shldup)
+ if (Ship.shield >= se)
+ {
+ Ship.shield -= se;
+ se = 0;
+ }
+ else
+ {
+ se -= Ship.shield;
+ Ship.shield = 0;
+ }
+ Ship.energy -= se;
+ if (Ship.energy <= 0)
+ lose(L_SUICID);
+ break;
+
+ default:
+ printf("Unknown object %c at %d,%d destroyed\n",
+ se, i, j);
+ Sect[i][j] = EMPTY;
+ break;
+ }
+ }
+ }
+ return;
+}
diff --git a/trek/out.c b/trek/out.c
new file mode 100644
index 00000000..627dc670
--- /dev/null
+++ b/trek/out.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)out.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** Announce Device Out
+*/
+
+out(dev)
+int dev;
+{
+ register struct device *d;
+
+ d = &Device[dev];
+ printf("%s reports %s ", d->person, d->name);
+ if (d->name[length(d->name) - 1] == 's')
+ printf("are");
+ else
+ printf("is");
+ printf(" damaged\n");
+}
diff --git a/trek/phaser.c b/trek/phaser.c
new file mode 100644
index 00000000..62b47fbc
--- /dev/null
+++ b/trek/phaser.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)phaser.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+
+/* factors for phaser hits; see description below */
+
+# define ALPHA 3.0 /* spread */
+# define BETA 3.0 /* franf() */
+# define GAMMA 0.30 /* cos(angle) */
+# define EPSILON 150.0 /* dist ** 2 */
+# define OMEGA 10.596 /* overall scaling factor */
+
+/* OMEGA ~= 100 * (ALPHA + 1) * (BETA + 1) / (EPSILON + 1) */
+
+/*
+** Phaser Control
+**
+** There are up to NBANKS phaser banks which may be fired
+** simultaneously. There are two modes, "manual" and
+** "automatic". In manual mode, you specify exactly which
+** direction you want each bank to be aimed, the number
+** of units to fire, and the spread angle. In automatic
+** mode, you give only the total number of units to fire.
+**
+** The spread is specified as a number between zero and
+** one, with zero being minimum spread and one being maximum
+** spread. You will normally want zero spread, unless your
+** short range scanners are out, in which case you probably
+** don't know exactly where the Klingons are. In that case,
+** you really don't have any choice except to specify a
+** fairly large spread.
+**
+** Phasers spread slightly, even if you specify zero spread.
+**
+** Uses trace flag 30
+*/
+
+struct cvntab Matab[] =
+{
+ "m", "anual", (int (*)())1, 0,
+ "a", "utomatic", 0, 0,
+ 0
+};
+
+struct banks
+{
+ int units;
+ double angle;
+ double spread;
+};
+
+
+
+phaser()
+{
+ register int i;
+ int j;
+ register struct kling *k;
+ double dx, dy;
+ double anglefactor, distfactor;
+ register struct banks *b;
+ int manual, flag, extra;
+ int hit;
+ double tot;
+ int n;
+ int hitreqd[NBANKS];
+ struct banks bank[NBANKS];
+ struct cvntab *ptr;
+
+ if (Ship.cond == DOCKED)
+ return(printf("Phasers cannot fire through starbase shields\n"));
+ if (damaged(PHASER))
+ return (out(PHASER));
+ if (Ship.shldup)
+ return (printf("Sulu: Captain, we cannot fire through shields.\n"));
+ if (Ship.cloaked)
+ {
+ printf("Sulu: Captain, surely you must realize that we cannot fire\n");
+ printf(" phasers with the cloaking device up.\n");
+ return;
+ }
+
+ /* decide if we want manual or automatic mode */
+ manual = 0;
+ if (testnl())
+ {
+ if (damaged(COMPUTER))
+ {
+ printf(Device[COMPUTER].name);
+ manual++;
+ }
+ else
+ if (damaged(SRSCAN))
+ {
+ printf(Device[SRSCAN].name);
+ manual++;
+ }
+ if (manual)
+ printf(" damaged, manual mode selected\n");
+ }
+
+ if (!manual)
+ {
+ ptr = getcodpar("Manual or automatic", Matab);
+ manual = (int) ptr->value;
+ }
+ if (!manual && damaged(COMPUTER))
+ {
+ printf("Computer damaged, manual selected\n");
+ skiptonl(0);
+ manual++;
+ }
+
+ /* initialize the bank[] array */
+ flag = 1;
+ for (i = 0; i < NBANKS; i++)
+ bank[i].units = 0;
+ if (manual)
+ {
+ /* collect manual mode statistics */
+ while (flag)
+ {
+ printf("%d units available\n", Ship.energy);
+ extra = 0;
+ flag = 0;
+ for (i = 0; i < NBANKS; i++)
+ {
+ b = &bank[i];
+ printf("\nBank %d:\n", i);
+ hit = getintpar("units");
+ if (hit < 0)
+ return;
+ if (hit == 0)
+ break;
+ extra += hit;
+ if (extra > Ship.energy)
+ {
+ printf("available energy exceeded. ");
+ skiptonl(0);
+ flag++;
+ break;
+ }
+ b->units = hit;
+ hit = getintpar("course");
+ if (hit < 0 || hit > 360)
+ return;
+ b->angle = hit * 0.0174532925;
+ b->spread = getfltpar("spread");
+ if (b->spread < 0 || b->spread > 1)
+ return;
+ }
+ Ship.energy -= extra;
+ }
+ extra = 0;
+ }
+ else
+ {
+ /* automatic distribution of power */
+ if (Etc.nkling <= 0)
+ return (printf("Sulu: But there are no Klingons in this quadrant\n"));
+ printf("Phasers locked on target. ");
+ while (flag)
+ {
+ printf("%d units available\n", Ship.energy);
+ hit = getintpar("Units to fire");
+ if (hit <= 0)
+ return;
+ if (hit > Ship.energy)
+ {
+ printf("available energy exceeded. ");
+ skiptonl(0);
+ continue;
+ }
+ flag = 0;
+ Ship.energy -= hit;
+ extra = hit;
+ n = Etc.nkling;
+ if (n > NBANKS)
+ n = NBANKS;
+ tot = n * (n + 1) / 2;
+ for (i = 0; i < n; i++)
+ {
+ k = &Etc.klingon[i];
+ b = &bank[i];
+ distfactor = k->dist;
+ anglefactor = ALPHA * BETA * OMEGA / (distfactor * distfactor + EPSILON);
+ anglefactor *= GAMMA;
+ distfactor = k->power;
+ distfactor /= anglefactor;
+ hitreqd[i] = distfactor + 0.5;
+ dx = Ship.sectx - k->x;
+ dy = k->y - Ship.secty;
+ b->angle = atan2(dy, dx);
+ b->spread = 0.0;
+ b->units = ((n - i) / tot) * extra;
+# ifdef xTRACE
+ if (Trace)
+ {
+ printf("b%d hr%d u%d df%.2f af%.2f\n",
+ i, hitreqd[i], b->units,
+ distfactor, anglefactor);
+ }
+# endif
+ extra -= b->units;
+ hit = b->units - hitreqd[i];
+ if (hit > 0)
+ {
+ extra += hit;
+ b->units -= hit;
+ }
+ }
+
+ /* give out any extra energy we might have around */
+ if (extra > 0)
+ {
+ for (i = 0; i < n; i++)
+ {
+ b = &bank[i];
+ hit = hitreqd[i] - b->units;
+ if (hit <= 0)
+ continue;
+ if (hit >= extra)
+ {
+ b->units += extra;
+ extra = 0;
+ break;
+ }
+ b->units = hitreqd[i];
+ extra -= hit;
+ }
+ if (extra > 0)
+ printf("%d units overkill\n", extra);
+ }
+ }
+ }
+
+# ifdef xTRACE
+ if (Trace)
+ {
+ for (i = 0; i < NBANKS; i++)
+ {
+ b = &bank[i];
+ printf("b%d u%d", i, b->units);
+ if (b->units > 0)
+ printf(" a%.2f s%.2f\n", b->angle, b->spread);
+ else
+ printf("\n");
+ }
+ }
+# endif
+
+ /* actually fire the shots */
+ Move.free = 0;
+ for (i = 0; i < NBANKS; i++)
+ {
+ b = &bank[i];
+ if (b->units <= 0)
+ {
+ continue;
+ }
+ printf("\nPhaser bank %d fires:\n", i);
+ n = Etc.nkling;
+ k = Etc.klingon;
+ for (j = 0; j < n; j++)
+ {
+ if (b->units <= 0)
+ break;
+ /*
+ ** The formula for hit is as follows:
+ **
+ ** zap = OMEGA * [(sigma + ALPHA) * (rho + BETA)]
+ ** / (dist ** 2 + EPSILON)]
+ ** * [cos(delta * sigma) + GAMMA]
+ ** * hit
+ **
+ ** where sigma is the spread factor,
+ ** rho is a random number (0 -> 1),
+ ** GAMMA is a crud factor for angle (essentially
+ ** cruds up the spread factor),
+ ** delta is the difference in radians between the
+ ** angle you are shooting at and the actual
+ ** angle of the klingon,
+ ** ALPHA scales down the significance of sigma,
+ ** BETA scales down the significance of rho,
+ ** OMEGA is the magic number which makes everything
+ ** up to "* hit" between zero and one,
+ ** dist is the distance to the klingon
+ ** hit is the number of units in the bank, and
+ ** zap is the amount of the actual hit.
+ **
+ ** Everything up through dist squared should maximize
+ ** at 1.0, so that the distance factor is never
+ ** greater than one. Conveniently, cos() is
+ ** never greater than one, but the same restric-
+ ** tion applies.
+ */
+ distfactor = BETA + franf();
+ distfactor *= ALPHA + b->spread;
+ distfactor *= OMEGA;
+ anglefactor = k->dist;
+ distfactor /= anglefactor * anglefactor + EPSILON;
+ distfactor *= b->units;
+ dx = Ship.sectx - k->x;
+ dy = k->y - Ship.secty;
+ anglefactor = atan2(dy, dx) - b->angle;
+ anglefactor = cos((anglefactor * b->spread) + GAMMA);
+ if (anglefactor < 0.0)
+ {
+ k++;
+ continue;
+ }
+ hit = anglefactor * distfactor + 0.5;
+ k->power -= hit;
+ printf("%d unit hit on Klingon", hit);
+ if (!damaged(SRSCAN))
+ printf(" at %d,%d", k->x, k->y);
+ printf("\n");
+ b->units -= hit;
+ if (k->power <= 0)
+ {
+ killk(k->x, k->y);
+ continue;
+ }
+ k++;
+ }
+ }
+
+ /* compute overkill */
+ for (i = 0; i < NBANKS; i++)
+ extra += bank[i].units;
+ if (extra > 0)
+ printf("\n%d units expended on empty space\n", extra);
+}
diff --git a/trek/play.c b/trek/play.c
new file mode 100644
index 00000000..729a2047
--- /dev/null
+++ b/trek/play.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)play.c 5.6 (Berkeley) 6/26/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+# include <setjmp.h>
+
+/*
+** INSTRUCTION READ AND MAIN PLAY LOOP
+**
+** Well folks, this is it. Here we have the guts of the game.
+** This routine executes moves. It sets up per-move variables,
+** gets the command, and executes the command. After the command,
+** it calls events() to use up time, attack() to have Klingons
+** attack if the move was not free, and checkcond() to check up
+** on how we are doing after the move.
+*/
+extern int abandon(), capture(), shield(), computer(), dcrept(),
+ destruct(), dock(), help(), impulse(), lrscan(),
+ warp(), dumpgame(), rest(), srscan(),
+ myreset(), torped(), visual(), setwarp(), undock(), phaser();
+
+struct cvntab Comtab[] =
+{
+ "abandon", "", abandon, 0,
+ "ca", "pture", capture, 0,
+ "cl", "oak", shield, -1,
+ "c", "omputer", computer, 0,
+ "da", "mages", dcrept, 0,
+ "destruct", "", destruct, 0,
+ "do", "ck", dock, 0,
+ "help", "", help, 0,
+ "i", "mpulse", impulse, 0,
+ "l", "rscan", lrscan, 0,
+ "m", "ove", warp, 0,
+ "p", "hasers", phaser, 0,
+ "ram", "", warp, 1,
+ "dump", "", dumpgame, 0,
+ "r", "est", rest, 0,
+ "sh", "ield", shield, 0,
+ "s", "rscan", srscan, 0,
+ "st", "atus", srscan, -1,
+ "terminate", "", myreset, 0,
+ "t", "orpedo", torped, 0,
+ "u", "ndock", undock, 0,
+ "v", "isual", visual, 0,
+ "w", "arp", setwarp, 0,
+ 0
+};
+
+myreset()
+{
+ extern jmp_buf env;
+
+ longjmp(env, 1);
+}
+
+play()
+{
+ struct cvntab *r;
+
+ while (1)
+ {
+ Move.free = 1;
+ Move.time = 0.0;
+ Move.shldchg = 0;
+ Move.newquad = 0;
+ Move.resting = 0;
+ skiptonl(0);
+ r = getcodpar("\nCommand", Comtab);
+ (*r->value)(r->value2);
+ events(0);
+ attack(0);
+ checkcond();
+ }
+}
diff --git a/trek/ram.c b/trek/ram.c
new file mode 100644
index 00000000..c3d65621
--- /dev/null
+++ b/trek/ram.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ram.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** RAM SOME OBJECT
+**
+** You have run into some sort of object. It may be a Klingon,
+** a star, or a starbase. If you run into a star, you are really
+** stupid, because there is no hope for you.
+**
+** If you run into something else, you destroy that object. You
+** also rack up incredible damages.
+*/
+
+ram(ix, iy)
+int ix, iy;
+{
+ register int i;
+ register char c;
+
+ printf("\07RED ALERT\07: collision imminent\n");
+ c = Sect[ix][iy];
+ switch (c)
+ {
+
+ case KLINGON:
+ printf("%s rams Klingon at %d,%d\n", Ship.shipname, ix, iy);
+ killk(ix, iy);
+ break;
+
+ case STAR:
+ case INHABIT:
+ printf("Yeoman Rand: Captain, isn't it getting hot in here?\n");
+ sleep(2);
+ printf("Spock: Hull temperature approaching 550 Degrees Kelvin.\n");
+ lose(L_STAR);
+
+ case BASE:
+ printf("You ran into the starbase at %d,%d\n", ix, iy);
+ killb(Ship.quadx, Ship.quady);
+ /* don't penalize the captain if it wasn't his fault */
+ if (!damaged(SINS))
+ Game.killb += 1;
+ break;
+ }
+ sleep(2);
+ printf("%s heavily damaged\n", Ship.shipname);
+
+ /* select the number of deaths to occur */
+ i = 10 + ranf(20 * Game.skill);
+ Game.deaths += i;
+ Ship.crew -= i;
+ printf("McCoy: Take it easy Jim; we had %d casualties.\n", i);
+
+ /* damage devices with an 80% probability */
+ for (i = 0; i < NDEV; i++)
+ {
+ if (ranf(100) < 20)
+ continue;
+ damage(i, (2.5 * (franf() + franf()) + 1.0) * Param.damfac[i]);
+ }
+
+ /* no chance that your shields remained up in all that */
+ Ship.shldup = 0;
+}
diff --git a/trek/ranf.c b/trek/ranf.c
new file mode 100644
index 00000000..21ad9a33
--- /dev/null
+++ b/trek/ranf.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ranf.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <stdio.h>
+
+ranf(max)
+int max;
+{
+ register int t;
+
+ if (max <= 0)
+ return (0);
+ t = rand() >> 5;
+ return (t % max);
+}
+
+
+double franf()
+{
+ double t;
+ t = rand() & 077777;
+ return (t / 32767.0);
+}
diff --git a/trek/rest.c b/trek/rest.c
new file mode 100644
index 00000000..e5bf6a62
--- /dev/null
+++ b/trek/rest.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)rest.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+
+/*
+** REST FOR REPAIRS
+**
+** You sit around and wait for repairs to happen. Actually, you
+** sit around and wait for anything to happen. I do want to point
+** out however, that Klingons are not as patient as you are, and
+** they tend to attack you while you are resting.
+**
+** You can never rest through a long range tractor beam.
+**
+** In events() you will be given an opportunity to cancel the
+** rest period if anything momentous happens.
+*/
+
+rest()
+{
+ double t;
+ register int percent;
+
+ /* get the time to rest */
+ t = getfltpar("How long");
+ if (t <= 0.0)
+ return;
+ percent = 100 * t / Now.time + 0.5;
+ if (percent >= 70)
+ {
+ printf("Spock: That would take %d%% of our remaining time.\n",
+ percent);
+ if (!getynpar("Are you really certain that is wise"))
+ return;
+ }
+ Move.time = t;
+
+ /* boundary condition is the LRTB */
+ t = Now.eventptr[E_LRTB]->date - Now.date;
+ if (Ship.cond != DOCKED && Move.time > t)
+ Move.time = t + 0.0001;
+ Move.free = 0;
+ Move.resting = 1;
+}
diff --git a/trek/schedule.c b/trek/schedule.c
new file mode 100644
index 00000000..fa7bced0
--- /dev/null
+++ b/trek/schedule.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)schedule.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** SCHEDULE AN EVENT
+**
+** An event of type 'type' is scheduled for time NOW + 'offset'
+** into the first available slot. 'x', 'y', and 'z' are
+** considered the attributes for this event.
+**
+** The address of the slot is returned.
+*/
+
+struct event *schedule(type, offset, x, y, z)
+int type;
+double offset;
+char x, y;
+char z;
+{
+ register struct event *e;
+ register int i;
+ double date;
+
+ date = Now.date + offset;
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ if (e->evcode)
+ continue;
+ /* got a slot */
+# ifdef xTRACE
+ if (Trace)
+ printf("schedule: type %d @ %.2f slot %d parm %d %d %d\n",
+ type, date, i, x, y, z);
+# endif
+ e->evcode = type;
+ e->date = date;
+ e->x = x;
+ e->y = y;
+ e->systemname = z;
+ Now.eventptr[type] = e;
+ return (e);
+ }
+ syserr("Cannot schedule event %d parm %d %d %d", type, x, y, z);
+}
+
+
+/*
+** RESCHEDULE AN EVENT
+**
+** The event pointed to by 'e' is rescheduled to the current
+** time plus 'offset'.
+*/
+
+reschedule(e1, offset)
+struct event *e1;
+double offset;
+{
+ double date;
+ register struct event *e;
+
+ e = e1;
+
+ date = Now.date + offset;
+ e->date = date;
+# ifdef xTRACE
+ if (Trace)
+ printf("reschedule: type %d parm %d %d %d @ %.2f\n",
+ e->evcode, e->x, e->y, e->systemname, date);
+# endif
+ return;
+}
+
+
+/*
+** UNSCHEDULE AN EVENT
+**
+** The event at slot 'e' is deleted.
+*/
+
+unschedule(e1)
+struct event *e1;
+{
+ register struct event *e;
+
+ e = e1;
+
+# ifdef xTRACE
+ if (Trace)
+ printf("unschedule: type %d @ %.2f parm %d %d %d\n",
+ e->evcode, e->date, e->x, e->y, e->systemname);
+# endif
+ Now.eventptr[e->evcode & E_EVENT] = 0;
+ e->date = 1e50;
+ e->evcode = 0;
+ return;
+}
+
+
+/*
+** Abreviated schedule routine
+**
+** Parameters are the event index and a factor for the time
+** figure.
+*/
+
+struct event *xsched(ev1, factor, x, y, z)
+int ev1;
+int factor;
+int x, y, z;
+{
+ register int ev;
+
+ ev = ev1;
+ return (schedule(ev, -Param.eventdly[ev] * Param.time * log(franf()) / factor, x, y, z));
+}
+
+
+/*
+** Simplified reschedule routine
+**
+** Parameters are the event index, the initial date, and the
+** division factor. Look at the code to see what really happens.
+*/
+
+xresched(e1, ev1, factor)
+struct event *e1;
+int ev1;
+int factor;
+{
+ register int ev;
+ register struct event *e;
+
+ ev = ev1;
+ e = e1;
+ reschedule(e, -Param.eventdly[ev] * Param.time * log(franf()) / factor);
+}
diff --git a/trek/score.c b/trek/score.c
new file mode 100644
index 00000000..e0e3be86
--- /dev/null
+++ b/trek/score.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)score.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+
+/*
+** PRINT OUT THE CURRENT SCORE
+*/
+
+long score()
+{
+ register int u;
+ register int t;
+ long s;
+ double r;
+ extern struct cvntab Skitab[];
+
+ printf("\n*** Your score:\n");
+ s = t = Param.klingpwr / 4 * (u = Game.killk);
+ if (t != 0)
+ printf("%d Klingons killed\t\t\t%6d\n", u, t);
+ r = Now.date - Param.date;
+ if (r < 1.0)
+ r = 1.0;
+ r = Game.killk / r;
+ s += (t = 400 * r);
+ if (t != 0)
+ printf("Kill rate %.2f Klingons/stardate \t%6d\n", r, t);
+ r = Now.klings;
+ r /= Game.killk + 1;
+ s += (t = -400 * r);
+ if (t != 0)
+ printf("Penalty for %d klingons remaining\t%6d\n", Now.klings, t);
+ if (Move.endgame > 0)
+ {
+ s += (t = 100 * (u = Game.skill));
+ printf("Bonus for winning a %s%s game\t\t%6d\n", Skitab[u - 1].abrev, Skitab[u - 1].full, t);
+ }
+ if (Game.killed)
+ {
+ s -= 500;
+ printf("Penalty for getting killed\t\t -500\n");
+ }
+ s += (t = -100 * (u = Game.killb));
+ if (t != 0)
+ printf("%d starbases killed\t\t\t%6d\n", u, t);
+ s += (t = -100 * (u = Game.helps));
+ if (t != 0)
+ printf("%d calls for help\t\t\t%6d\n", u, t);
+ s += (t = -5 * (u = Game.kills));
+ if (t != 0)
+ printf("%d stars destroyed\t\t\t%6d\n", u, t);
+ s += (t = -150 * (u = Game.killinhab));
+ if (t != 0)
+ printf("%d inhabited starsystems destroyed\t%6d\n", u, t);
+ if (Ship.ship != ENTERPRISE)
+ {
+ s -= 200;
+ printf("penalty for abandoning ship\t\t -200\n");
+ }
+ s += (t = 3 * (u = Game.captives));
+ if (t != 0)
+ printf("%d Klingons captured\t\t\t%6d\n", u, t);
+ s += (t = -(u = Game.deaths));
+ if (t != 0)
+ printf("%d casualties\t\t\t\t%6d\n", u, t);
+ printf("\n*** TOTAL\t\t\t%14ld\n", s);
+ return (s);
+}
diff --git a/trek/setup.c b/trek/setup.c
new file mode 100644
index 00000000..7f35a259
--- /dev/null
+++ b/trek/setup.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)setup.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+
+/*
+** INITIALIZE THE GAME
+**
+** The length, skill, and password are read, and the game
+** is initialized. It is far too difficult to describe all
+** that goes on in here, but it is all straight-line code;
+** give it a look.
+**
+** Game restart and tournament games are handled here.
+*/
+
+struct cvntab Lentab[] =
+{
+ "s", "hort", (int (*)())1, 0,
+ "m", "edium", (int (*)())2, 0,
+ "l", "ong", (int (*)())4, 0,
+ "restart", "", 0, 0,
+ 0
+};
+
+struct cvntab Skitab[] =
+{
+ "n", "ovice", (int (*)())1, 0,
+ "f", "air", (int (*)())2, 0,
+ "g", "ood", (int (*)())3, 0,
+ "e", "xpert", (int (*)())4, 0,
+ "c", "ommodore", (int (*)())5, 0,
+ "i", "mpossible", (int (*)())6, 0,
+ 0
+};
+
+setup()
+{
+ struct cvntab *r;
+ register int i, j;
+ double f;
+ int d;
+ int fd;
+ int klump;
+ int ix, iy;
+ register struct quad *q;
+ struct event *e;
+
+ while (1)
+ {
+ r = getcodpar("What length game", Lentab);
+ Game.length = (int) r->value;
+ if (Game.length == 0)
+ {
+ if (restartgame())
+ continue;
+ return;
+ }
+ break;
+ }
+ r = getcodpar("What skill game", Skitab);
+ Game.skill = (int) r->value;
+ Game.tourn = 0;
+ getstrpar("Enter a password", Game.passwd, 14, 0);
+ if (sequal(Game.passwd, "tournament"))
+ {
+ getstrpar("Enter tournament code", Game.passwd, 14, 0);
+ Game.tourn = 1;
+ d = 0;
+ for (i = 0; Game.passwd[i]; i++)
+ d += Game.passwd[i] << i;
+ srand(d);
+ }
+ Param.bases = Now.bases = ranf(6 - Game.skill) + 2;
+ if (Game.skill == 6)
+ Param.bases = Now.bases = 1;
+ Param.time = Now.time = 6.0 * Game.length + 2.0;
+ i = Game.skill;
+ j = Game.length;
+ Param.klings = Now.klings = i * j * 3.5 * (franf() + 0.75);
+ if (Param.klings < i * j * 5)
+ Param.klings = Now.klings = i * j * 5;
+ if (Param.klings <= i) /* numerical overflow problems */
+ Param.klings = Now.klings = 127;
+ Param.energy = Ship.energy = 5000;
+ Param.torped = Ship.torped = 10;
+ Ship.ship = ENTERPRISE;
+ Ship.shipname = "Enterprise";
+ Param.shield = Ship.shield = 1500;
+ Param.resource = Now.resource = Param.klings * Param.time;
+ Param.reserves = Ship.reserves = (6 - Game.skill) * 2.0;
+ Param.crew = Ship.crew = 387;
+ Param.brigfree = Ship.brigfree = 400;
+ Ship.shldup = 1;
+ Ship.cond = GREEN;
+ Ship.warp = 5.0;
+ Ship.warp2 = 25.0;
+ Ship.warp3 = 125.0;
+ Ship.sinsbad = 0;
+ Ship.cloaked = 0;
+ Param.date = Now.date = (ranf(20) + 20) * 100;
+ f = Game.skill;
+ f = log(f + 0.5);
+ for (i = 0; i < NDEV; i++)
+ if (Device[i].name[0] == '*')
+ Param.damfac[i] = 0;
+ else
+ Param.damfac[i] = f;
+ /* these probabilities must sum to 1000 */
+ Param.damprob[WARP] = 70; /* warp drive 7.0% */
+ Param.damprob[SRSCAN] = 110; /* short range scanners 11.0% */
+ Param.damprob[LRSCAN] = 110; /* long range scanners 11.0% */
+ Param.damprob[PHASER] = 125; /* phasers 12.5% */
+ Param.damprob[TORPED] = 125; /* photon torpedoes 12.5% */
+ Param.damprob[IMPULSE] = 75; /* impulse engines 7.5% */
+ Param.damprob[SHIELD] = 150; /* shield control 15.0% */
+ Param.damprob[COMPUTER] = 20; /* computer 2.0% */
+ Param.damprob[SSRADIO] = 35; /* subspace radio 3.5% */
+ Param.damprob[LIFESUP] = 30; /* life support 3.0% */
+ Param.damprob[SINS] = 20; /* navigation system 2.0% */
+ Param.damprob[CLOAK] = 50; /* cloaking device 5.0% */
+ Param.damprob[XPORTER] = 80; /* transporter 8.0% */
+ /* check to see that I didn't blow it */
+ for (i = j = 0; i < NDEV; i++)
+ j += Param.damprob[i];
+ if (j != 1000)
+ syserr("Device probabilities sum to %d", j);
+ Param.dockfac = 0.5;
+ Param.regenfac = (5 - Game.skill) * 0.05;
+ if (Param.regenfac < 0.0)
+ Param.regenfac = 0.0;
+ Param.warptime = 10;
+ Param.stopengy = 50;
+ Param.shupengy = 40;
+ i = Game.skill;
+ Param.klingpwr = 100 + 150 * i;
+ if (i >= 6)
+ Param.klingpwr += 150;
+ Param.phasfac = 0.8;
+ Param.hitfac = 0.5;
+ Param.klingcrew = 200;
+ Param.srndrprob = 0.0035;
+ Param.moveprob[KM_OB] = 45;
+ Param.movefac[KM_OB] = .09;
+ Param.moveprob[KM_OA] = 40;
+ Param.movefac[KM_OA] = -0.05;
+ Param.moveprob[KM_EB] = 40;
+ Param.movefac[KM_EB] = 0.075;
+ Param.moveprob[KM_EA] = 25 + 5 * Game.skill;
+ Param.movefac[KM_EA] = -0.06 * Game.skill;
+ Param.moveprob[KM_LB] = 0;
+ Param.movefac[KM_LB] = 0.0;
+ Param.moveprob[KM_LA] = 10 + 10 * Game.skill;
+ Param.movefac[KM_LA] = 0.25;
+ Param.eventdly[E_SNOVA] = 0.5;
+ Param.eventdly[E_LRTB] = 25.0;
+ Param.eventdly[E_KATSB] = 1.0;
+ Param.eventdly[E_KDESB] = 3.0;
+ Param.eventdly[E_ISSUE] = 1.0;
+ Param.eventdly[E_SNAP] = 0.5;
+ Param.eventdly[E_ENSLV] = 0.5;
+ Param.eventdly[E_REPRO] = 2.0;
+ Param.navigcrud[0] = 1.50;
+ Param.navigcrud[1] = 0.75;
+ Param.cloakenergy = 1000;
+ Param.energylow = 1000;
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ e = &Event[i];
+ e->date = 1e50;
+ e->evcode = 0;
+ }
+ xsched(E_SNOVA, 1, 0, 0, 0);
+ xsched(E_LRTB, Param.klings, 0, 0, 0);
+ xsched(E_KATSB, 1, 0, 0, 0);
+ xsched(E_ISSUE, 1, 0, 0, 0);
+ xsched(E_SNAP, 1, 0, 0, 0);
+ Ship.sectx = ranf(NSECTS);
+ Ship.secty = ranf(NSECTS);
+ Game.killk = Game.kills = Game.killb = 0;
+ Game.deaths = Game.negenbar = 0;
+ Game.captives = 0;
+ Game.killinhab = 0;
+ Game.helps = 0;
+ Game.killed = 0;
+ Game.snap = 0;
+ Move.endgame = 0;
+
+ /* setup stars */
+ for (i = 0; i < NQUADS; i++)
+ for (j = 0; j < NQUADS; j++)
+ {
+ q = &Quad[i][j];
+ q->klings = q->bases = 0;
+ q->scanned = -1;
+ q->stars = ranf(9) + 1;
+ q->holes = ranf(3) - q->stars / 5;
+ q->qsystemname = 0;
+ }
+
+ /* select inhabited starsystems */
+ for (d = 1; d < NINHAB; d++)
+ {
+ do
+ {
+ i = ranf(NQUADS);
+ j = ranf(NQUADS);
+ q = &Quad[i][j];
+ } while (q->qsystemname);
+ q->qsystemname = d;
+ }
+
+ /* position starbases */
+ for (i = 0; i < Param.bases; i++)
+ {
+ while (1)
+ {
+ ix = ranf(NQUADS);
+ iy = ranf(NQUADS);
+ q = &Quad[ix][iy];
+ if (q->bases > 0)
+ continue;
+ break;
+ }
+ q->bases = 1;
+ Now.base[i].x = ix;
+ Now.base[i].y = iy;
+ q->scanned = 1001;
+ /* start the Enterprise near starbase */
+ if (i == 0)
+ {
+ Ship.quadx = ix;
+ Ship.quady = iy;
+ }
+ }
+
+ /* position klingons */
+ for (i = Param.klings; i > 0; )
+ {
+ klump = ranf(4) + 1;
+ if (klump > i)
+ klump = i;
+ while (1)
+ {
+ ix = ranf(NQUADS);
+ iy = ranf(NQUADS);
+ q = &Quad[ix][iy];
+ if (q->klings + klump > MAXKLQUAD)
+ continue;
+ q->klings += klump;
+ i -= klump;
+ break;
+ }
+ }
+
+ /* initialize this quadrant */
+ printf("%d Klingons\n%d starbase", Param.klings, Param.bases);
+ if (Param.bases > 1)
+ printf("s");
+ printf(" at %d,%d", Now.base[0].x, Now.base[0].y);
+ for (i = 1; i < Param.bases; i++)
+ printf(", %d,%d", Now.base[i].x, Now.base[i].y);
+ printf("\nIt takes %d units to kill a Klingon\n", Param.klingpwr);
+ Move.free = 0;
+ initquad(0);
+ srscan(1);
+ attack(0);
+}
diff --git a/trek/setwarp.c b/trek/setwarp.c
new file mode 100644
index 00000000..8d3d8c89
--- /dev/null
+++ b/trek/setwarp.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)setwarp.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+
+/*
+** SET WARP FACTOR
+**
+** The warp factor is set for future move commands. It is
+** checked for consistancy.
+*/
+
+setwarp()
+{
+ double warpfac;
+
+ warpfac = getfltpar("Warp factor");
+ if (warpfac < 0.0)
+ return;
+ if (warpfac < 1.0)
+ return (printf("Minimum warp speed is 1.0\n"));
+ if (warpfac > 10.0)
+ return (printf("Maximum speed is warp 10.0\n"));
+ if (warpfac > 6.0)
+ printf("Damage to warp engines may occur above warp 6.0\n");
+ Ship.warp = warpfac;
+ Ship.warp2 = Ship.warp * warpfac;
+ Ship.warp3 = Ship.warp2 * warpfac;
+}
diff --git a/trek/shield.c b/trek/shield.c
new file mode 100644
index 00000000..e6fadfea
--- /dev/null
+++ b/trek/shield.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)shield.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+
+/*
+** SHIELD AND CLOAKING DEVICE CONTROL
+**
+** 'f' is one for auto shield up (in case of Condition RED),
+** zero for shield control, and negative one for cloaking
+** device control.
+**
+** Called with an 'up' or 'down' on the same line, it puts
+** the shields/cloak into the specified mode. Otherwise it
+** reports to the user the current mode, and asks if she wishes
+** to change.
+**
+** This is not a free move. Hits that occur as a result of
+** this move appear as though the shields are half up/down,
+** so you get partial hits.
+*/
+
+struct cvntab Udtab[] =
+{
+ "u", "p", (int (*)())1, 0,
+ "d", "own", 0, 0,
+ 0
+};
+
+shield(f)
+int f;
+{
+ register int i;
+ char c;
+ struct cvntab *r;
+ char s[100];
+ char *device, *dev2, *dev3;
+ int ind;
+ char *stat;
+
+ if (f > 0 && (Ship.shldup || damaged(SRSCAN)))
+ return;
+ if (f < 0)
+ {
+ /* cloaking device */
+ if (Ship.ship == QUEENE)
+ return (printf("Ye Faire Queene does not have the cloaking device.\n"));
+ device = "Cloaking device";
+ dev2 = "is";
+ ind = CLOAK;
+ dev3 = "it";
+ stat = &Ship.cloaked;
+ }
+ else
+ {
+ /* shields */
+ device = "Shields";
+ dev2 = "are";
+ dev3 = "them";
+ ind = SHIELD;
+ stat = &Ship.shldup;
+ }
+ if (damaged(ind))
+ {
+ if (f <= 0)
+ out(ind);
+ return;
+ }
+ if (Ship.cond == DOCKED)
+ {
+ printf("%s %s down while docked\n", device, dev2);
+ return;
+ }
+ if (f <= 0 && !testnl())
+ {
+ r = getcodpar("Up or down", Udtab);
+ i = (int) r->value;
+ }
+ else
+ {
+ if (*stat)
+ (void)sprintf(s, "%s %s up. Do you want %s down", device, dev2, dev3);
+ else
+ (void)sprintf(s, "%s %s down. Do you want %s up", device, dev2, dev3);
+ if (!getynpar(s))
+ return;
+ i = !*stat;
+ }
+ if (*stat == i)
+ {
+ printf("%s already ", device);
+ if (i)
+ printf("up\n");
+ else
+ printf("down\n");
+ return;
+ }
+ if (i)
+ if (f >= 0)
+ Ship.energy -= Param.shupengy;
+ else
+ Ship.cloakgood = 0;
+ Move.free = 0;
+ if (f >= 0)
+ Move.shldchg = 1;
+ *stat = i;
+ return;
+}
diff --git a/trek/snova.c b/trek/snova.c
new file mode 100644
index 00000000..94426153
--- /dev/null
+++ b/trek/snova.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)snova.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** CAUSE SUPERNOVA TO OCCUR
+**
+** A supernova occurs. If 'ix' < 0, a random quadrant is chosen;
+** otherwise, the current quadrant is taken, and (ix, iy) give
+** the sector quadrants of the star which is blowing up.
+**
+** If the supernova turns out to be in the quadrant you are in,
+** you go into "emergency override mode", which tries to get you
+** out of the quadrant as fast as possible. However, if you
+** don't have enough fuel, or if you by chance run into something,
+** or some such thing, you blow up anyway. Oh yeh, if you are
+** within two sectors of the star, there is nothing that can
+** be done for you.
+**
+** When a star has gone supernova, the quadrant becomes uninhab-
+** itable for the rest of eternity, i.e., the game. If you ever
+** try stopping in such a quadrant, you will go into emergency
+** override mode.
+*/
+
+snova(x, y)
+int x, y;
+{
+ int qx, qy;
+ register int ix, iy;
+ int f;
+ int dx, dy;
+ int n;
+ register struct quad *q;
+
+ f = 0;
+ ix = x;
+ if (ix < 0)
+ {
+ /* choose a quadrant */
+ while (1)
+ {
+ qx = ranf(NQUADS);
+ qy = ranf(NQUADS);
+ q = &Quad[qx][qy];
+ if (q->stars > 0)
+ break;
+ }
+ if (Ship.quadx == qx && Ship.quady == qy)
+ {
+ /* select a particular star */
+ n = ranf(q->stars);
+ for (ix = 0; ix < NSECTS; ix++)
+ {
+ for (iy = 0; iy < NSECTS; iy++)
+ if (Sect[ix][iy] == STAR || Sect[ix][iy] == INHABIT)
+ if ((n -= 1) <= 0)
+ break;
+ if (n <= 0)
+ break;
+ }
+ f = 1;
+ }
+ }
+ else
+ {
+ /* current quadrant */
+ iy = y;
+ qx = Ship.quadx;
+ qy = Ship.quady;
+ q = &Quad[qx][qy];
+ f = 1;
+ }
+ if (f)
+ {
+ /* supernova is in same quadrant as Enterprise */
+ printf("\nRED ALERT: supernova occuring at %d,%d\n", ix, iy);
+ dx = ix - Ship.sectx;
+ dy = iy - Ship.secty;
+ if (dx * dx + dy * dy <= 2)
+ {
+ printf("*** Emergency override attem");
+ sleep(1);
+ printf("\n");
+ lose(L_SNOVA);
+ }
+ q->scanned = 1000;
+ }
+ else
+ {
+ if (!damaged(SSRADIO))
+ {
+ q->scanned = 1000;
+ printf("\nUhura: Captain, Starfleet Command reports a supernova\n");
+ printf(" in quadrant %d,%d. Caution is advised\n", qx, qy);
+ }
+ }
+
+ /* clear out the supernova'ed quadrant */
+ dx = q->klings;
+ dy = q->stars;
+ Now.klings -= dx;
+ if (x >= 0)
+ {
+ /* Enterprise caused supernova */
+ Game.kills += dy;
+ if (q->bases)
+ killb(qx, qy, -1);
+ Game.killk += dx;
+ }
+ else
+ if (q->bases)
+ killb(qx, qy, 0);
+ killd(qx, qy, (x >= 0));
+ q->stars = -1;
+ q->klings = 0;
+ if (Now.klings <= 0)
+ {
+ printf("Lucky devil, that supernova destroyed the last klingon\n");
+ win();
+ }
+ return;
+}
diff --git a/trek/srscan.c b/trek/srscan.c
new file mode 100644
index 00000000..46803a27
--- /dev/null
+++ b/trek/srscan.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)srscan.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+
+/*
+** SHORT RANGE SENSOR SCAN
+**
+** A short range scan is taken of the current quadrant. If the
+** flag 'f' is one, it is an "auto srscan", which is not done
+** unless in 'fast' mode. It does a status report and a srscan.
+** If 'f' is -1, you get a status report only. If it is zero,
+** you get a srscan and an optional status report. The status
+** report is taken if you enter "srscan yes"; for all srscans
+** thereafter you get a status report with your srscan until
+** you type "srscan no". It defaults to on.
+**
+** The current quadrant is filled in on the computer chart.
+*/
+
+char *Color[4] =
+{
+ "GREEN",
+ "DOCKED",
+ "YELLOW",
+ "RED"
+};
+
+srscan(f)
+int f;
+{
+ register int i, j;
+ register int statinfo;
+ char *s;
+ int percent;
+ struct quad *q;
+ extern struct cvntab Skitab[];
+ extern struct cvntab Lentab[];
+ struct cvntab *p;
+
+ if (f >= 0 && check_out(SRSCAN))
+ {
+ return;
+ }
+ if (f)
+ statinfo = 1;
+ else
+ {
+ if (!testnl())
+ Etc.statreport = getynpar("status report");
+ statinfo = Etc.statreport;
+ }
+ if (f > 0)
+ {
+ Etc.statreport = 1;
+ if (!Etc.fast)
+ return;
+ }
+ if (f >= 0)
+ {
+ printf("\nShort range sensor scan\n");
+ q = &Quad[Ship.quadx][Ship.quady];
+ q->scanned = q->klings * 100 + q->bases * 10 + q->stars;
+ printf(" ");
+ for (i = 0; i < NSECTS; i++)
+ {
+ printf("%d ", i);
+ }
+ printf("\n");
+ }
+
+ for (i = 0; i < NSECTS; i++)
+ {
+ if (f >= 0)
+ {
+ printf("%d ", i);
+ for (j = 0; j < NSECTS; j++)
+ printf("%c ", Sect[i][j]);
+ printf("%d", i);
+ if (statinfo)
+ printf(" ");
+ }
+ if (statinfo)
+ switch (i)
+ {
+ case 0:
+ printf("stardate %.2f", Now.date);
+ break;
+ case 1:
+ printf("condition %s", Color[Ship.cond]);
+ if (Ship.cloaked)
+ printf(", CLOAKED");
+ break;
+ case 2:
+ printf("position %d,%d/%d,%d",Ship.quadx, Ship.quady, Ship.sectx, Ship.secty);
+ break;
+ case 3:
+ printf("warp factor %.1f", Ship.warp);
+ break;
+ case 4:
+ printf("total energy %d", Ship.energy);
+ break;
+ case 5:
+ printf("torpedoes %d", Ship.torped);
+ break;
+ case 6:
+ s = "down";
+ if (Ship.shldup)
+ s = "up";
+ if (damaged(SHIELD))
+ s = "damaged";
+ percent = 100.0 * Ship.shield / Param.shield;
+ printf("shields %s, %d%%", s, percent);
+ break;
+ case 7:
+ printf("Klingons left %d", Now.klings);
+ break;
+ case 8:
+ printf("time left %.2f", Now.time);
+ break;
+ case 9:
+ printf("life support ");
+ if (damaged(LIFESUP))
+ {
+ printf("damaged, reserves = %.2f", Ship.reserves);
+ break;
+ }
+ printf("active");
+ break;
+ }
+ printf("\n");
+ }
+ if (f < 0)
+ {
+ printf("current crew %d\n", Ship.crew);
+ printf("brig space %d\n", Ship.brigfree);
+ printf("Klingon power %d\n", Param.klingpwr);
+ p = &Lentab[Game.length - 1];
+ if (Game.length > 2)
+ p--;
+ printf("Length, Skill %s%s, ", p->abrev, p->full);
+ p = &Skitab[Game.skill - 1];
+ printf("%s%s\n", p->abrev, p->full);
+ return;
+ }
+ printf(" ");
+ for (i = 0; i < NSECTS; i++)
+ printf("%d ", i);
+ printf("\n");
+
+ if (q->qsystemname & Q_DISTRESSED)
+ printf("Distressed ");
+ if (q->qsystemname)
+ printf("Starsystem %s\n", systemname(q));
+}
diff --git a/trek/systemname.c b/trek/systemname.c
new file mode 100644
index 00000000..de16077a
--- /dev/null
+++ b/trek/systemname.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)systemname.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** RETRIEVE THE STARSYSTEM NAME
+**
+** Very straightforward, this routine just gets the starsystem
+** name. It returns zero if none in the specified quadrant
+** (which, by the way, is passed it).
+**
+** This routine knows all about such things as distressed
+** starsystems, etc.
+*/
+
+char *systemname(q1)
+struct quad *q1;
+{
+ register struct quad *q;
+ register int i;
+
+ q = q1;
+
+ i = q->qsystemname;
+ if (i & Q_DISTRESSED)
+ i = Event[i & Q_SYSTEM].systemname;
+
+ i &= Q_SYSTEM;
+ if (i == 0)
+ return (0);
+ return (Systemname[i]);
+}
diff --git a/trek/torped.c b/trek/torped.c
new file mode 100644
index 00000000..5e42d309
--- /dev/null
+++ b/trek/torped.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)torped.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include <stdio.h>
+# include "trek.h"
+
+/*
+** PHOTON TORPEDO CONTROL
+**
+** Either one or three photon torpedoes are fired. If three
+** are fired, it is called a "burst" and you also specify
+** a spread angle.
+**
+** Torpedoes are never 100% accurate. There is always a random
+** cludge factor in their course which is increased if you have
+** your shields up. Hence, you will find that they are more
+** accurate at close range. However, they have the advantage that
+** at long range they don't lose any of their power as phasers
+** do, i.e., a hit is a hit is a hit, by any other name.
+**
+** When the course spreads too much, you get a misfire, and the
+** course is randomized even more. You also have the chance that
+** the misfire damages your torpedo tubes.
+*/
+
+
+torped()
+{
+ register int ix, iy;
+ double x, y, dx, dy;
+ double angle;
+ int course, course2;
+ register int k;
+ double bigger;
+ double sectsize;
+ int burst;
+ int n;
+
+ if (Ship.cloaked)
+ {
+ return (printf("Federation regulations do not permit attack while cloaked.\n"));
+ }
+ if (check_out(TORPED))
+ return;
+ if (Ship.torped <= 0)
+ {
+ return (printf("All photon torpedos expended\n"));
+ }
+
+ /* get the course */
+ course = getintpar("Torpedo course");
+ if (course < 0 || course > 360)
+ return;
+ burst = -1;
+
+ /* need at least three torpedoes for a burst */
+ if (Ship.torped < 3)
+ {
+ printf("No-burst mode selected\n");
+ burst = 0;
+ }
+ else
+ {
+ /* see if the user wants one */
+ if (!testnl())
+ {
+ k = ungetc(cgetc(0), stdin);
+ if (k >= '0' && k <= '9')
+ burst = 1;
+ }
+ }
+ if (burst < 0)
+ {
+ burst = getynpar("Do you want a burst");
+ }
+ if (burst)
+ {
+ burst = getintpar("burst angle");
+ if (burst <= 0)
+ return;
+ if (burst > 15)
+ return (printf("Maximum burst angle is 15 degrees\n"));
+ }
+ sectsize = NSECTS;
+ n = -1;
+ if (burst)
+ {
+ n = 1;
+ course -= burst;
+ }
+ for (; n && n <= 3; n++)
+ {
+ /* select a nice random course */
+ course2 = course + randcourse(n);
+ angle = course2 * 0.0174532925; /* convert to radians */
+ dx = -cos(angle);
+ dy = sin(angle);
+ bigger = fabs(dx);
+ x = fabs(dy);
+ if (x > bigger)
+ bigger = x;
+ dx /= bigger;
+ dy /= bigger;
+ x = Ship.sectx + 0.5;
+ y = Ship.secty + 0.5;
+ if (Ship.cond != DOCKED)
+ Ship.torped -= 1;
+ printf("Torpedo track");
+ if (n > 0)
+ printf(", torpedo number %d", n);
+ printf(":\n%6.1f\t%4.1f\n", x, y);
+ while (1)
+ {
+ ix = x += dx;
+ iy = y += dy;
+ if (x < 0.0 || x >= sectsize || y < 0.0 || y >= sectsize)
+ {
+ printf("Torpedo missed\n");
+ break;
+ }
+ printf("%6.1f\t%4.1f\n", x, y);
+ switch (Sect[ix][iy])
+ {
+ case EMPTY:
+ continue;
+
+ case HOLE:
+ printf("Torpedo disappears into a black hole\n");
+ break;
+
+ case KLINGON:
+ for (k = 0; k < Etc.nkling; k++)
+ {
+ if (Etc.klingon[k].x != ix || Etc.klingon[k].y != iy)
+ continue;
+ Etc.klingon[k].power -= 500 + ranf(501);
+ if (Etc.klingon[k].power > 0)
+ {
+ printf("*** Hit on Klingon at %d,%d: extensive damages\n",
+ ix, iy);
+ break;
+ }
+ killk(ix, iy);
+ break;
+ }
+ break;
+
+ case STAR:
+ nova(ix, iy);
+ break;
+
+ case INHABIT:
+ kills(ix, iy, -1);
+ break;
+
+ case BASE:
+ killb(Ship.quadx, Ship.quady);
+ Game.killb += 1;
+ break;
+ default:
+ printf("Unknown object %c at %d,%d destroyed\n",
+ Sect[ix][iy], ix, iy);
+ Sect[ix][iy] = EMPTY;
+ break;
+ }
+ break;
+ }
+ if (damaged(TORPED) || Quad[Ship.quadx][Ship.quady].stars < 0)
+ break;
+ course += burst;
+ }
+ Move.free = 0;
+}
+
+
+/*
+** RANDOMIZE COURSE
+**
+** This routine randomizes the course for torpedo number 'n'.
+** Other things handled by this routine are misfires, damages
+** to the tubes, etc.
+*/
+
+randcourse(n)
+int n;
+{
+ double r;
+ register int d;
+
+ d = ((franf() + franf()) - 1.0) * 20;
+ if (abs(d) > 12)
+ {
+ printf("Photon tubes misfire");
+ if (n < 0)
+ printf("\n");
+ else
+ printf(" on torpedo %d\n", n);
+ if (ranf(2))
+ {
+ damage(TORPED, 0.2 * abs(d) * (franf() + 1.0));
+ }
+ d *= 1.0 + 2.0 * franf();
+ }
+ if (Ship.shldup || Ship.cond == DOCKED)
+ {
+ r = Ship.shield;
+ r = 1.0 + r / Param.shield;
+ if (Ship.cond == DOCKED)
+ r = 2.0;
+ d *= r;
+ }
+ return (d);
+}
diff --git a/trek/trek.6 b/trek/trek.6
new file mode 100644
index 00000000..07d950bd
--- /dev/null
+++ b/trek/trek.6
@@ -0,0 +1,90 @@
+.\" Copyright (c) 1980 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)trek.6 6.3 (Berkeley) 6/23/90
+.\"
+.TH TREK 6 "June 23, 1990"
+.UC 4
+.SH NAME
+trek \- trekkie game
+.SH SYNOPSIS
+.B /usr/games/trek
+[ [
+.B \-a
+] file ]
+.SH DESCRIPTION
+.I Trek
+is a game of space glory and war. Below is a summary of commands.
+For complete documentation, see
+.IR Trek
+by Eric Allman.
+.PP
+If a filename is given, a log of the game is written onto that file.
+If the
+.B \-a
+flag is given before the filename, that file is appended to, not truncated.
+.PP
+The game will ask you what length game you would like.
+Valid responses are \*(lqshort\*(rq, \*(lqmedium\*(rq, and \*(lqlong\*(rq.
+You may also type \*(lqrestart\*(rq, which restarts a previously saved game.
+You will then be prompted for the skill, to which you must respond
+\*(lqnovice\*(rq, \*(lqfair\*(rq, \*(lqgood\*(rq, \*(lqexpert\*(rq,
+\*(lqcommadore\*(rq, or \*(lqimpossible\*(rq.
+You should normally start out with a novice and work up.
+.PP
+In general, throughout the game, if you forget what is appropriate
+the game will tell you what it expects if you just type in a question mark.
+.SH AUTHOR
+Eric Allman
+.SH "SEE ALSO"
+/usr/doc/trek
+.SH "COMMAND SUMMARY"
+.ie t .ds f \fB
+.el .ds f \fI
+.ta 3i
+.nf
+\*fabandon\fR \*fca\fRpture
+\*fcl\fRoak \*fu\fRp/\*fd\fRown
+\*fc\fRomputer request; ... \*fda\fRmages
+\*fdestruct\fR \*fdo\fRck
+\*fhelp\fR \*fi\fRmpulse course distance
+\*fl\fRrscan \*fm\fRove course distance
+\*fp\fRhasers \*fa\fRutomatic amount
+\*fp\fRhasers \*fm\fRanual amt1 course1 spread1 ...
+\*ft\fRorpedo course [\*fy\fRes] angle/\*fn\fRo
+\*fram\fR course distance \*fr\fRest time
+\*fshell\fR \*fsh\fRields \*fu\fRp/\*fd\fRown
+\*fs\fRrscan [\*fy\fRes/\*fn\fRo]
+\*fst\fRatus \*fterminate\fR \*fy\fRes/\*fn\fRo
+\*fu\fRndock \*fv\fRisual course
+\*fw\fRarp warp_factor
+.fi
+.DT
diff --git a/trek/trek.h b/trek/trek.h
new file mode 100644
index 00000000..b798d0a1
--- /dev/null
+++ b/trek/trek.h
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)trek.h 5.5 (Berkeley) 6/1/90
+ */
+
+/*
+** Global Declarations
+**
+** Virtually all non-local variable declarations are made in this
+** file. Exceptions are those things which are initialized, which
+** are defined in "externs.c", and things which are local to one
+** program file.
+**
+** So far as I know, nothing in here must be preinitialized to
+** zero.
+**
+** You may have problems from the loader if you move this to a
+** different machine. These things actually get allocated in each
+** source file, which UNIX allows; however, you may (on other
+** systems) have to change everything in here to be "extern" and
+** actually allocate stuff in "externs.c"
+*/
+
+/* external function definitions */
+extern double franf(); /* floating random number function */
+extern double sqrt(); /* square root */
+extern double sin(), cos(); /* trig functions */
+extern double atan2(); /* fancy arc tangent function */
+extern double log(); /* log base e */
+extern double pow(); /* power function */
+extern double fabs(); /* absolute value function */
+extern double exp(); /* exponential function */
+
+/********************* GALAXY **************************/
+
+/* galactic parameters */
+# define NSECTS 10 /* dimensions of quadrant in sectors */
+# define NQUADS 8 /* dimension of galazy in quadrants */
+# define NINHAB 32 /* number of quadrants which are inhabited */
+
+struct quad /* definition for each quadrant */
+{
+ char bases; /* number of bases in this quadrant */
+ char klings; /* number of Klingons in this quadrant */
+ char holes; /* number of black holes in this quadrant */
+ int scanned; /* star chart entry (see below) */
+ char stars; /* number of stars in this quadrant */
+ char qsystemname; /* starsystem name (see below) */
+};
+
+# define Q_DISTRESSED 0200
+# define Q_SYSTEM 077
+
+/* systemname conventions:
+ * 1 -> NINHAB index into Systemname table for live system.
+ * + Q_DISTRESSED distressed starsystem -- systemname & Q_SYSTEM
+ * is the index into the Event table which will
+ * have the system name
+ * 0 dead or nonexistent starsystem
+ *
+ * starchart ("scanned") conventions:
+ * 0 -> 999 taken as is
+ * -1 not yet scanned ("...")
+ * 1000 supernova ("///")
+ * 1001 starbase + ??? (".1.")
+*/
+
+/* ascii names of systems */
+extern char *Systemname[NINHAB];
+
+/* quadrant definition */
+struct quad Quad[NQUADS][NQUADS];
+
+/* defines for sector map (below) */
+# define EMPTY '.'
+# define STAR '*'
+# define BASE '#'
+# define ENTERPRISE 'E'
+# define QUEENE 'Q'
+# define KLINGON 'K'
+# define INHABIT '@'
+# define HOLE ' '
+
+/* current sector map */
+char Sect[NSECTS][NSECTS];
+
+
+/************************ DEVICES ******************************/
+
+# define NDEV 16 /* max number of devices */
+
+/* device tokens */
+# define WARP 0 /* warp engines */
+# define SRSCAN 1 /* short range scanners */
+# define LRSCAN 2 /* long range scanners */
+# define PHASER 3 /* phaser control */
+# define TORPED 4 /* photon torpedo control */
+# define IMPULSE 5 /* impulse engines */
+# define SHIELD 6 /* shield control */
+# define COMPUTER 7 /* on board computer */
+# define SSRADIO 8 /* subspace radio */
+# define LIFESUP 9 /* life support systems */
+# define SINS 10 /* Space Inertial Navigation System */
+# define CLOAK 11 /* cloaking device */
+# define XPORTER 12 /* transporter */
+# define SHUTTLE 13 /* shuttlecraft */
+
+/* device names */
+struct device
+{
+ char *name; /* device name */
+ char *person; /* the person who fixes it */
+};
+
+struct device Device[NDEV];
+
+/*************************** EVENTS ****************************/
+
+# define NEVENTS 12 /* number of different event types */
+
+# define E_LRTB 1 /* long range tractor beam */
+# define E_KATSB 2 /* Klingon attacks starbase */
+# define E_KDESB 3 /* Klingon destroys starbase */
+# define E_ISSUE 4 /* distress call is issued */
+# define E_ENSLV 5 /* Klingons enslave a quadrant */
+# define E_REPRO 6 /* a Klingon is reproduced */
+# define E_FIXDV 7 /* fix a device */
+# define E_ATTACK 8 /* Klingon attack during rest period */
+# define E_SNAP 9 /* take a snapshot for time warp */
+# define E_SNOVA 10 /* supernova occurs */
+
+# define E_GHOST 0100 /* ghost of a distress call if ssradio out */
+# define E_HIDDEN 0200 /* event that is unreportable because ssradio out */
+# define E_EVENT 077 /* mask to get event code */
+
+struct event
+{
+ char x, y; /* coordinates */
+ double date; /* trap stardate */
+ char evcode; /* event type */
+ char systemname; /* starsystem name */
+};
+/* systemname conventions:
+ * 1 -> NINHAB index into Systemname table for reported distress calls
+ *
+ * evcode conventions:
+ * 1 -> NEVENTS-1 event type
+ * + E_HIDDEN unreported (SSradio out)
+ * + E_GHOST actually already expired
+ * 0 unallocated
+ */
+
+# define MAXEVENTS 25 /* max number of concurrently pending events */
+
+struct event Event[MAXEVENTS]; /* dynamic event list; one entry per pending event */
+
+/***************************** KLINGONS *******************************/
+
+struct kling
+{
+ char x, y; /* coordinates */
+ int power; /* power left */
+ double dist; /* distance to Enterprise */
+ double avgdist; /* average over this move */
+ char srndreq; /* set if surrender has been requested */
+};
+
+# define MAXKLQUAD 9 /* maximum klingons per quadrant */
+
+/********************** MISCELLANEOUS ***************************/
+
+/* condition codes */
+# define GREEN 0
+# define DOCKED 1
+# define YELLOW 2
+# define RED 3
+
+/* starbase coordinates */
+# define MAXBASES 9 /* maximum number of starbases in galaxy */
+
+/* distress calls */
+# define MAXDISTR 5 /* maximum concurrent distress calls */
+
+/* phaser banks */
+# define NBANKS 6 /* number of phaser banks */
+
+struct xy
+{
+ char x, y; /* coordinates */
+};
+
+
+/*
+ * note that much of the stuff in the following structs CAN NOT
+ * be moved around!!!!
+ */
+
+
+/* information regarding the state of the starship */
+struct
+{
+ double warp; /* warp factor */
+ double warp2; /* warp factor squared */
+ double warp3; /* warp factor cubed */
+ char shldup; /* shield up flag */
+ char cloaked; /* set if cloaking device on */
+ int energy; /* starship's energy */
+ int shield; /* energy in shields */
+ double reserves; /* life support reserves */
+ int crew; /* ship's complement */
+ int brigfree; /* space left in brig */
+ char torped; /* torpedoes */
+ char cloakgood; /* set if we have moved */
+ int quadx; /* quadrant x coord */
+ int quady; /* quadrant y coord */
+ int sectx; /* sector x coord */
+ int secty; /* sector y coord */
+ char cond; /* condition code */
+ char sinsbad; /* Space Inertial Navigation System condition */
+ char *shipname; /* name of current starship */
+ char ship; /* current starship */
+ int distressed; /* number of distress calls */
+} Ship;
+
+/* sinsbad is set if SINS is working but not calibrated */
+
+/* game related information, mostly scoring */
+struct
+{
+ int killk; /* number of klingons killed */
+ int deaths; /* number of deaths onboard Enterprise */
+ char negenbar; /* number of hits on negative energy barrier */
+ char killb; /* number of starbases killed */
+ int kills; /* number of stars killed */
+ char skill; /* skill rating of player */
+ char length; /* length of game */
+ char killed; /* set if you were killed */
+ char killinhab; /* number of inhabited starsystems killed */
+ char tourn; /* set if a tournament game */
+ char passwd[15]; /* game password */
+ char snap; /* set if snapshot taken */
+ char helps; /* number of help calls */
+ int captives; /* total number of captives taken */
+} Game;
+
+/* per move information */
+struct
+{
+ char free; /* set if a move is free */
+ char endgame; /* end of game flag */
+ char shldchg; /* set if shields changed this move */
+ char newquad; /* set if just entered this quadrant */
+ char resting; /* set if this move is a rest */
+ double time; /* time used this move */
+} Move;
+
+/* parametric information */
+struct
+{
+ char bases; /* number of starbases */
+ char klings; /* number of klingons */
+ double date; /* stardate */
+ double time; /* time left */
+ double resource; /* Federation resources */
+ int energy; /* starship's energy */
+ int shield; /* energy in shields */
+ double reserves; /* life support reserves */
+ int crew; /* size of ship's complement */
+ int brigfree; /* max possible number of captives */
+ char torped; /* photon torpedos */
+ double damfac[NDEV]; /* damage factor */
+ double dockfac; /* docked repair time factor */
+ double regenfac; /* regeneration factor */
+ int stopengy; /* energy to do emergency stop */
+ int shupengy; /* energy to put up shields */
+ int klingpwr; /* Klingon initial power */
+ int warptime; /* time chewer multiplier */
+ double phasfac; /* Klingon phaser power eater factor */
+ char moveprob[6]; /* probability that a Klingon moves */
+ double movefac[6]; /* Klingon move distance multiplier */
+ double eventdly[NEVENTS]; /* event time multipliers */
+ double navigcrud[2]; /* navigation crudup factor */
+ int cloakenergy; /* cloaking device energy per stardate */
+ double damprob[NDEV]; /* damage probability */
+ double hitfac; /* Klingon attack factor */
+ int klingcrew; /* number of Klingons in a crew */
+ double srndrprob; /* surrender probability */
+ int energylow; /* low energy mark (cond YELLOW) */
+} Param;
+
+/* Sum of damage probabilities must add to 1000 */
+
+/* other information kept in a snapshot */
+struct
+{
+ char bases; /* number of starbases */
+ char klings; /* number of klingons */
+ double date; /* stardate */
+ double time; /* time left */
+ double resource; /* Federation resources */
+ char distressed; /* number of currently distressed quadrants */
+ struct event *eventptr[NEVENTS]; /* pointer to event structs */
+ struct xy base[MAXBASES]; /* locations of starbases */
+} Now;
+
+/* Other stuff, not dumped in a snapshot */
+struct
+{
+ struct kling klingon[MAXKLQUAD]; /* sorted Klingon list */
+ char nkling; /* number of Klingons in this sector */
+ /* < 0 means automatic override mode */
+ char fast; /* set if speed > 300 baud */
+ struct xy starbase; /* starbase in current quadrant */
+ char snapshot[sizeof Quad + sizeof Event + sizeof Now]; /* snapshot for time warp */
+ char statreport; /* set to get a status report on a srscan */
+} Etc;
+
+/*
+ * eventptr is a pointer to the event[] entry of the last
+ * scheduled event of each type. Zero if no such event scheduled.
+ */
+
+/* Klingon move indicies */
+# define KM_OB 0 /* Old quadrant, Before attack */
+# define KM_OA 1 /* Old quadrant, After attack */
+# define KM_EB 2 /* Enter quadrant, Before attack */
+# define KM_EA 3 /* Enter quadrant, After attack */
+# define KM_LB 4 /* Leave quadrant, Before attack */
+# define KM_LA 5 /* Leave quadrant, After attack */
+
+/* you lose codes */
+# define L_NOTIME 1 /* ran out of time */
+# define L_NOENGY 2 /* ran out of energy */
+# define L_DSTRYD 3 /* destroyed by a Klingon */
+# define L_NEGENB 4 /* ran into the negative energy barrier */
+# define L_SUICID 5 /* destroyed in a nova */
+# define L_SNOVA 6 /* destroyed in a supernova */
+# define L_NOLIFE 7 /* life support died (so did you) */
+# define L_NOHELP 8 /* you could not be rematerialized */
+# define L_TOOFAST 9 /* pretty stupid going at warp 10 */
+# define L_STAR 10 /* ran into a star */
+# define L_DSTRCT 11 /* self destructed */
+# define L_CAPTURED 12 /* captured by Klingons */
+# define L_NOCREW 13 /* you ran out of crew */
+
+/****************** COMPILE OPTIONS ***********************/
+
+/* Trace info */
+# define xTRACE 1
+int Trace;
diff --git a/trek/utility.c b/trek/utility.c
new file mode 100644
index 00000000..b44e8acf
--- /dev/null
+++ b/trek/utility.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)utility.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+** ASSORTED UTILITY ROUTINES
+*/
+
+/*
+** BLOCK MOVE
+**
+** Moves a block of storage of length `l' bytes from the data
+** area pointed to by `a' to the area pointed to by `b'.
+** Returns the address of the byte following the `b' field.
+** Overflow of `b' is not tested.
+*/
+
+char *bmove(a, b, l)
+char *a, *b;
+int l;
+{
+ register int n;
+ register char *p, *q;
+
+ p = a;
+ q = b;
+ n = l;
+ while (n--)
+ *q++ = *p++;
+ return (q);
+}
+
+
+/*
+** STRING EQUALITY TEST
+** null-terminated strings `a' and `b' are tested for
+** absolute equality.
+** returns one if equal, zero otherwise.
+*/
+
+sequal(a, b)
+char *a, *b;
+{
+ register char *p, *q;
+
+ p = a;
+ q = b;
+ while (*p || *q)
+ if (*p++ != *q++)
+ return(0);
+ return(1);
+}
+
+
+/*
+** STRING CONCATENATE
+**
+** The strings `s1' and `s2' are concatenated and stored into
+** `s3'. It is ok for `s1' to equal `s3', but terrible things
+** will happen if `s2' equals `s3'. The return value is is a
+** pointer to the end of `s3' field.
+*/
+
+char *concat(s1, s2, s3)
+char *s1, *s2, *s3;
+{
+ register char *p;
+ register char *q;
+
+ p = s3;
+ q = s1;
+ while (*q)
+ *p++ = *q++;
+ q = s2;
+ while (*q)
+ *p++ = *q++;
+ *p = 0;
+ return (p);
+}
+
+
+/*
+** FIND STRING LENGTH
+**
+** The length of string `s' (excluding the null byte which
+** terminates the string) is returned.
+*/
+
+length(s)
+char *s;
+{
+ register int l;
+ register char *p;
+
+ l = 0;
+ p = s;
+ while (*p++)
+ l++;
+ return(l);
+}
+
+
+/*
+** SYSTEM ERROR
+*/
+
+syserr(p0, p1, p2, p3, p4, p5)
+{
+ extern int errno;
+
+ printf("\n\07TREK SYSERR: ");
+ printf(p0, p1, p2, p3, p4, p5);
+ printf("\n");
+ if (errno)
+ printf("\tsystem error %d\n", errno);
+ exit(-1);
+}
diff --git a/trek/visual.c b/trek/visual.c
new file mode 100644
index 00000000..a4f06c07
--- /dev/null
+++ b/trek/visual.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)visual.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** VISUAL SCAN
+**
+** A visual scan is made in a particular direction of three sectors
+** in the general direction specified. This takes time, and
+** Klingons can attack you, so it should be done only when sensors
+** are out.
+*/
+
+/* This struct[] has the delta x, delta y for particular directions */
+struct xy Visdelta[11] =
+{
+ -1, -1,
+ -1, 0,
+ -1, 1,
+ 0, 1,
+ 1, 1,
+ 1, 0,
+ 1, -1,
+ 0, -1,
+ -1, -1,
+ -1, 0,
+ -1, 1
+};
+
+visual()
+{
+ register int ix, iy;
+ int co;
+ register struct xy *v;
+
+ co = getintpar("direction");
+ if (co < 0 || co > 360)
+ return;
+ co = (co + 22) / 45;
+ v = &Visdelta[co];
+ ix = Ship.sectx + v->x;
+ iy = Ship.secty + v->y;
+ if (ix < 0 || ix >= NSECTS || iy < 0 || iy >= NSECTS)
+ co = '?';
+ else
+ co = Sect[ix][iy];
+ printf("%d,%d %c ", ix, iy, co);
+ v++;
+ ix = Ship.sectx + v->x;
+ iy = Ship.secty + v->y;
+ if (ix < 0 || ix >= NSECTS || iy < 0 || iy >= NSECTS)
+ co = '?';
+ else
+ co = Sect[ix][iy];
+ printf("%c ", co);
+ v++;
+ ix = Ship.sectx + v->x;
+ iy = Ship.secty + v->y;
+ if (ix < 0 || ix >= NSECTS || iy < 0 || iy >= NSECTS)
+ co = '?';
+ else
+ co = Sect[ix][iy];
+ printf("%c %d,%d\n", co, ix, iy);
+ Move.time = 0.05;
+ Move.free = 0;
+}
diff --git a/trek/warp.c b/trek/warp.c
new file mode 100644
index 00000000..2fc4852a
--- /dev/null
+++ b/trek/warp.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)warp.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+# include "trek.h"
+
+/*
+** MOVE UNDER WARP POWER
+**
+** This is both the "move" and the "ram" commands, differing
+** only in the flag 'fl'. It is also used for automatic
+** emergency override mode, when 'fl' is < 0 and 'c' and 'd'
+** are the course and distance to be moved. If 'fl' >= 0,
+** the course and distance are asked of the captain.
+**
+** The guts of this routine are in the routine move(), which
+** is shared with impulse(). Also, the working part of this
+** routine is very small; the rest is to handle the slight chance
+** that you may be moving at some riduculous speed. In that
+** case, there is code to handle time warps, etc.
+*/
+
+warp(fl, c, d)
+int fl, c;
+double d;
+{
+ int course;
+ double power;
+ double dist;
+ double time;
+ double speed;
+ double frac;
+ register int percent;
+ register int i;
+ extern double move();
+
+ if (Ship.cond == DOCKED)
+ return (printf("%s is docked\n", Ship.shipname));
+ if (damaged(WARP))
+ {
+ return (out(WARP));
+ }
+ if (fl < 0)
+ {
+ course = c;
+ dist = d;
+ }
+ else
+ if (getcodi(&course, &dist))
+ return;
+
+ /* check to see that we are not using an absurd amount of power */
+ power = (dist + 0.05) * Ship.warp3;
+ percent = 100 * power / Ship.energy + 0.5;
+ if (percent >= 85)
+ {
+ printf("Scotty: That would consume %d%% of our remaining energy.\n",
+ percent);
+ if (!getynpar("Are you sure that is wise"))
+ return;
+ }
+
+ /* compute the speed we will move at, and the time it will take */
+ speed = Ship.warp2 / Param.warptime;
+ time = dist / speed;
+
+ /* check to see that that value is not ridiculous */
+ percent = 100 * time / Now.time + 0.5;
+ if (percent >= 85)
+ {
+ printf("Spock: That would take %d%% of our remaining time.\n",
+ percent);
+ if (!getynpar("Are you sure that is wise"))
+ return;
+ }
+
+ /* compute how far we will go if we get damages */
+ if (Ship.warp > 6.0 && ranf(100) < 20 + 15 * (Ship.warp - 6.0))
+ {
+ frac = franf();
+ dist *= frac;
+ time *= frac;
+ damage(WARP, (frac + 1.0) * Ship.warp * (franf() + 0.25) * 0.20);
+ }
+
+ /* do the move */
+ Move.time = move(fl, course, time, speed);
+
+ /* see how far we actually went, and decrement energy appropriately */
+ dist = Move.time * speed;
+ Ship.energy -= dist * Ship.warp3 * (Ship.shldup + 1);
+
+ /* test for bizarre events */
+ if (Ship.warp <= 9.0)
+ return;
+ printf("\n\n ___ Speed exceeding warp nine ___\n\n");
+ sleep(2);
+ printf("Ship's safety systems malfunction\n");
+ sleep(2);
+ printf("Crew experiencing extreme sensory distortion\n");
+ sleep(4);
+ if (ranf(100) >= 100 * dist)
+ {
+ return (printf("Equilibrium restored -- all systems normal\n"));
+ }
+
+ /* select a bizzare thing to happen to us */
+ percent = ranf(100);
+ if (percent < 70)
+ {
+ /* time warp */
+ if (percent < 35 || !Game.snap)
+ {
+ /* positive time warp */
+ time = (Ship.warp - 8.0) * dist * (franf() + 1.0);
+ Now.date += time;
+ printf("Positive time portal entered -- it is now Stardate %.2f\n",
+ Now.date);
+ for (i = 0; i < MAXEVENTS; i++)
+ {
+ percent = Event[i].evcode;
+ if (percent == E_FIXDV || percent == E_LRTB)
+ Event[i].date += time;
+ }
+ return;
+ }
+
+ /* s/he got lucky: a negative time portal */
+ time = Now.date;
+ i = (int) Etc.snapshot;
+ bmove(i, Quad, sizeof Quad);
+ bmove(i += sizeof Quad, Event, sizeof Event);
+ bmove(i += sizeof Event, &Now, sizeof Now);
+ printf("Negative time portal entered -- it is now Stardate %.2f\n",
+ Now.date);
+ for (i = 0; i < MAXEVENTS; i++)
+ if (Event[i].evcode == E_FIXDV)
+ reschedule(&Event[i], Event[i].date - time);
+ return;
+ }
+
+ /* test for just a lot of damage */
+ if (percent < 80)
+ lose(L_TOOFAST);
+ printf("Equilibrium restored -- extreme damage occured to ship systems\n");
+ for (i = 0; i < NDEV; i++)
+ damage(i, (3.0 * (franf() + franf()) + 1.0) * Param.damfac[i]);
+ Ship.shldup = 0;
+}
diff --git a/trek/win.c b/trek/win.c
new file mode 100644
index 00000000..dc1f7c64
--- /dev/null
+++ b/trek/win.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)win.c 5.5 (Berkeley) 6/26/90";
+#endif /* not lint */
+
+# include "trek.h"
+# include "getpar.h"
+# include <setjmp.h>
+
+/*
+** Signal game won
+**
+** This routine prints out the win message, arranges to print out
+** your score, tells you if you have a promotion coming to you,
+** cleans up the current input line, and arranges to have you
+** asked whether or not you want another game (via the longjmp()
+** call).
+**
+** Pretty straightforward, although the promotion algorithm is
+** pretty off the wall.
+*/
+
+win()
+{
+ long s;
+ extern jmp_buf env;
+ extern long score();
+ extern struct cvntab Skitab[];
+ register struct cvntab *p;
+
+ sleep(1);
+ printf("\nCongratulations, you have saved the Federation\n");
+ Move.endgame = 1;
+
+ /* print and return the score */
+ s = score();
+
+ /* decide if she gets a promotion */
+ if (Game.helps == 0 && Game.killb == 0 && Game.killinhab == 0 && 5 * Game.kills + Game.deaths < 100 &&
+ s >= 1000 && Ship.ship == ENTERPRISE)
+ {
+ printf("In fact, you are promoted one step in rank,\n");
+ if (Game.skill >= 6)
+ printf("to the exalted rank of Commodore Emeritus\n");
+ else
+ {
+ p = &Skitab[Game.skill - 1];
+ printf("from %s%s ", p->abrev, p->full);
+ p++;
+ printf("to %s%s\n", p->abrev, p->full);
+ }
+ }
+
+ /* clean out input, and request new game */
+ skiptonl(0);
+ longjmp(env, 1);
+}
diff --git a/wargames/Makefile b/wargames/Makefile
new file mode 100644
index 00000000..f2fc076c
--- /dev/null
+++ b/wargames/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 5.3 (Berkeley) 6/8/90
+
+NOOBJ= noobj
+all wargames clean cleandir depend lint tags:
+
+install:
+ install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} wargames.sh \
+ ${DESTDIR}/usr/games/wargames
+
+.include <bsd.prog.mk>
diff --git a/wargames/wargames.sh b/wargames/wargames.sh
new file mode 100644
index 00000000..c945da7d
--- /dev/null
+++ b/wargames/wargames.sh
@@ -0,0 +1,45 @@
+#!/bin/sh -
+#
+# Copyright (c) 1985 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)wargames.sh 5.4 (Berkeley) 6/1/90
+#
+echo -n "Would you like to play a game? "
+read x
+
+if [ -f /usr/games/$x ] ; then
+ tput cl
+ exec /usr/games/$x
+else
+ echo "Funny, the only way to win is not to play at all."
+fi
+exit 0
diff --git a/worm/Makefile b/worm/Makefile
new file mode 100644
index 00000000..e599f0e5
--- /dev/null
+++ b/worm/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 5.3 (Berkeley) 5/11/90
+
+PROG= worm
+MAN6= worm.0
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermcap -lcompat
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
diff --git a/worm/worm.6 b/worm/worm.6
new file mode 100644
index 00000000..a7de0782
--- /dev/null
+++ b/worm/worm.6
@@ -0,0 +1,66 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)worm.6 6.3 (Berkeley) 6/23/90
+.\"
+.TH WORM 6 "June 23, 1990"
+.UC 4
+.SH NAME
+worm \- Play the growing worm game
+.SH SYNOPSIS
+.B worm
+[
+.I size
+]
+.SH DESCRIPTION
+.PP
+In
+.I worm,
+you are a little worm, your body is the "o"'s on the screen
+and your head is the "@". You move with the hjkl keys (as in the game
+snake). If you don't press any keys, you continue in the direction you
+last moved. The upper case HJKL keys move you as if you had pressed
+several (9 for HL and 5 for JK) of the corresponding lower case key
+(unless you run into a digit, then it stops).
+.PP
+On the screen you will see a digit, if your worm eats the digit is will
+grow longer, the actual amount longer depends on which digit it was
+that you ate. The object of the game is to see how long you can make
+the worm grow.
+.PP
+The game ends when the worm runs into either the sides of the screen,
+or itself. The current score (how much the worm has grown) is kept in
+the upper left corner of the screen.
+.PP
+The optional argument, if present, is the initial length of the worm.
+.SH BUGS
+If the initial length of the worm is set to less than one or more
+than 75, various strange things happen.
diff --git a/worm/worm.c b/worm/worm.c
new file mode 100644
index 00000000..65a7423b
--- /dev/null
+++ b/worm/worm.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)worm.c 5.8 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ * Worm. Written by Michael Toy
+ * UCSC
+ */
+
+#include <ctype.h>
+#include <curses.h>
+#include <signal.h>
+
+#define newlink() (struct body *) malloc(sizeof (struct body));
+#define HEAD '@'
+#define BODY 'o'
+#define LENGTH 7
+#define RUNLEN 8
+#define when break;case
+#define otherwise break;default
+#define CNTRL(p) (p-'A'+1)
+#ifndef baudrate
+# define baudrate() _tty.sg_ospeed
+#endif
+
+WINDOW *tv;
+WINDOW *stw;
+struct body {
+ int x;
+ int y;
+ struct body *prev;
+ struct body *next;
+} *head, *tail, goody;
+int growing = 0;
+int running = 0;
+int slow = 0;
+int score = 0;
+int start_len = LENGTH;
+char lastch;
+char outbuf[BUFSIZ];
+
+void leave(), wake(), suspend();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char ch;
+
+ if (argc == 2)
+ start_len = atoi(argv[1]);
+ if ((start_len <= 0) || (start_len > 500))
+ start_len = LENGTH;
+ setbuf(stdout, outbuf);
+ srand(getpid());
+ signal(SIGALRM, wake);
+ signal(SIGINT, leave);
+ signal(SIGQUIT, leave);
+ signal(SIGTSTP, suspend); /* process control signal */
+ initscr();
+ crmode();
+ noecho();
+ slow = (baudrate() <= B1200);
+ clear();
+ stw = newwin(1, COLS-1, 0, 0);
+ tv = newwin(LINES-1, COLS-1, 1, 0);
+ box(tv, '*', '*');
+ scrollok(tv, FALSE);
+ scrollok(stw, FALSE);
+ wmove(stw, 0, 0);
+ wprintw(stw, " Worm");
+ refresh();
+ wrefresh(stw);
+ wrefresh(tv);
+ life(); /* Create the worm */
+ prize(); /* Put up a goal */
+ while(1)
+ {
+ if (running)
+ {
+ running--;
+ process(lastch);
+ }
+ else
+ {
+ fflush(stdout);
+ if (read(0, &ch, 1) >= 0)
+ process(ch);
+ }
+ }
+}
+
+life()
+{
+ register struct body *bp, *np;
+ register int i;
+
+ head = newlink();
+ head->x = start_len+2;
+ head->y = 12;
+ head->next = NULL;
+ display(head, HEAD);
+ for (i = 0, bp = head; i < start_len; i++, bp = np) {
+ np = newlink();
+ np->next = bp;
+ bp->prev = np;
+ np->x = bp->x - 1;
+ np->y = bp->y;
+ display(np, BODY);
+ }
+ tail = np;
+ tail->prev = NULL;
+}
+
+display(pos, chr)
+struct body *pos;
+char chr;
+{
+ wmove(tv, pos->y, pos->x);
+ waddch(tv, chr);
+}
+
+void
+leave()
+{
+ endwin();
+ exit(0);
+}
+
+void
+wake()
+{
+ signal(SIGALRM, wake);
+ fflush(stdout);
+ process(lastch);
+}
+
+rnd(range)
+{
+ return abs((rand()>>5)+(rand()>>5)) % range;
+}
+
+newpos(bp)
+struct body * bp;
+{
+ do {
+ bp->y = rnd(LINES-3)+ 2;
+ bp->x = rnd(COLS-3) + 1;
+ wmove(tv, bp->y, bp->x);
+ } while(winch(tv) != ' ');
+}
+
+prize()
+{
+ int value;
+
+ value = rnd(9) + 1;
+ newpos(&goody);
+ waddch(tv, value+'0');
+ wrefresh(tv);
+}
+
+process(ch)
+char ch;
+{
+ register int x,y;
+ struct body *nh;
+
+ alarm(0);
+ x = head->x;
+ y = head->y;
+ switch(ch)
+ {
+ when 'h': x--;
+ when 'j': y++;
+ when 'k': y--;
+ when 'l': x++;
+ when 'H': x--; running = RUNLEN; ch = tolower(ch);
+ when 'J': y++; running = RUNLEN/2; ch = tolower(ch);
+ when 'K': y--; running = RUNLEN/2; ch = tolower(ch);
+ when 'L': x++; running = RUNLEN; ch = tolower(ch);
+ when '\f': setup(); return;
+ when CNTRL('Z'): suspend(); return;
+ when CNTRL('C'): crash(); return;
+ when CNTRL('D'): crash(); return;
+ otherwise: if (! running) alarm(1);
+ return;
+ }
+ lastch = ch;
+ if (growing == 0)
+ {
+ display(tail, ' ');
+ tail->next->prev = NULL;
+ nh = tail->next;
+ free(tail);
+ tail = nh;
+ }
+ else growing--;
+ display(head, BODY);
+ wmove(tv, y, x);
+ if (isdigit(ch = winch(tv)))
+ {
+ growing += ch-'0';
+ prize();
+ score += growing;
+ running = 0;
+ wmove(stw, 0, 68);
+ wprintw(stw, "Score: %3d", score);
+ wrefresh(stw);
+ }
+ else if(ch != ' ') crash();
+ nh = newlink();
+ nh->next = NULL;
+ nh->prev = head;
+ head->next = nh;
+ nh->y = y;
+ nh->x = x;
+ display(nh, HEAD);
+ head = nh;
+ if (!(slow && running))
+ wrefresh(tv);
+ if (!running)
+ alarm(1);
+}
+
+crash()
+{
+ sleep(2);
+ clear();
+ move(23, 0);
+ refresh();
+ printf("Well, you ran into something and the game is over.\n");
+ printf("Your final score was %d\n", score);
+ leave();
+}
+
+void
+suspend()
+{
+ char *sh;
+
+ move(LINES-1, 0);
+ refresh();
+ endwin();
+ fflush(stdout);
+ kill(getpid(), SIGTSTP);
+ signal(SIGTSTP, suspend);
+ crmode();
+ noecho();
+ setup();
+}
+
+setup()
+{
+ clear();
+ refresh();
+ touchwin(stw);
+ wrefresh(stw);
+ touchwin(tv);
+ wrefresh(tv);
+ alarm(1);
+}
diff --git a/worms/Makefile b/worms/Makefile
new file mode 100644
index 00000000..645b126f
--- /dev/null
+++ b/worms/Makefile
@@ -0,0 +1,8 @@
+# @(#)Makefile 5.3 (Berkeley) 5/11/90
+
+PROG= worms
+MAN6= worms.0
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermcap -lcompat
+
+.include <bsd.prog.mk>
diff --git a/worms/worms.6 b/worms/worms.6
new file mode 100644
index 00000000..45d258e5
--- /dev/null
+++ b/worms/worms.6
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)worms.6 6.4 (Berkeley) 6/23/90
+.\"
+.UC 7
+.TH WORMS 6 "June 23, 1990"
+.UC 4
+.SH NAME
+worms \- animate worms on a display terminal
+.SH SYNOPSIS
+.B worms
+[
+.B \-ft
+] [
+.B \-length
+# ] [
+.B \-number
+# ]
+.SH DESCRIPTION
+.ad b
+Brian Horn (cithep!bdh) showed me a
+.I TOPS-20
+program on the DEC-2136 machine called
+.IR WORM ,
+and suggested that I write a similar program that would run under
+.IR Unix .
+I did, and no apologies.
+.PP
+The options are as follows:
+.TP
+.I -f
+makes a ``field'' for the worm(s) to eat.
+.TP
+.I -t
+causes each worm to leave a trail behind it.
+.PP
+You can figure out the rest by yourself.
+.SH AUTHOR
+Eric P. Scott
+.SH BUGS
+The lower-right-hand character position will not be updated properly
+on a terminal that wraps at the right margin.
diff --git a/worms/worms.c b/worms/worms.c
new file mode 100644
index 00000000..0e780361
--- /dev/null
+++ b/worms/worms.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)worms.c 5.9 (Berkeley) 2/28/91";
+#endif /* not lint */
+
+/*
+ *
+ * @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
+ * @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@
+ * @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@
+ * @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
+ * @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
+ * @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@
+ * @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@
+ * @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@
+ * @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@
+ *
+ * Eric P. Scott
+ * Caltech High Energy Physics
+ * October, 1980
+ *
+ */
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef USG
+#include <termio.h>
+#else
+#include <sgtty.h>
+#endif
+#include <signal.h>
+
+static struct options {
+ int nopts;
+ int opts[3];
+}
+ normal[8] = {
+ { 3, { 7, 0, 1 } },
+ { 3, { 0, 1, 2 } },
+ { 3, { 1, 2, 3 } },
+ { 3, { 2, 3, 4 } },
+ { 3, { 3, 4, 5 } },
+ { 3, { 4, 5, 6 } },
+ { 3, { 5, 6, 7 } },
+ { 3, { 6, 7, 0 } }
+}, upper[8] = {
+ { 1, { 1, 0, 0 } },
+ { 2, { 1, 2, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 2, { 4, 5, 0 } },
+ { 1, { 5, 0, 0 } },
+ { 2, { 1, 5, 0 } }
+},
+ left[8] = {
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 2, { 2, 3, 0 } },
+ { 1, { 3, 0, 0 } },
+ { 2, { 3, 7, 0 } },
+ { 1, { 7, 0, 0 } },
+ { 2, { 7, 0, 0 } }
+},
+ right[8] = {
+ { 1, { 7, 0, 0 } },
+ { 2, { 3, 7, 0 } },
+ { 1, { 3, 0, 0 } },
+ { 2, { 3, 4, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 2, { 6, 7, 0 } }
+},
+ lower[8] = {
+ { 0, { 0, 0, 0 } },
+ { 2, { 0, 1, 0 } },
+ { 1, { 1, 0, 0 } },
+ { 2, { 1, 5, 0 } },
+ { 1, { 5, 0, 0 } },
+ { 2, { 5, 6, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } }
+},
+ upleft[8] = {
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 1, { 3, 0, 0 } },
+ { 2, { 1, 3, 0 } },
+ { 1, { 1, 0, 0 } }
+},
+ upright[8] = {
+ { 2, { 3, 5, 0 } },
+ { 1, { 3, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 1, { 5, 0, 0 } }
+},
+ lowleft[8] = {
+ { 3, { 7, 0, 1 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 1, { 1, 0, 0 } },
+ { 2, { 1, 7, 0 } },
+ { 1, { 7, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } }
+},
+ lowright[8] = {
+ { 0, { 0, 0, 0 } },
+ { 1, { 7, 0, 0 } },
+ { 2, { 5, 7, 0 } },
+ { 1, { 5, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } },
+ { 0, { 0, 0, 0 } }
+};
+
+#define cursor(c, r) tputs(tgoto(CM, c, r), 1, fputchar)
+
+char *tcp;
+int fputchar();
+
+static char flavor[] = {
+ 'O', '*', '#', '$', '%', '0', '@', '~'
+};
+static short xinc[] = {
+ 1, 1, 1, 0, -1, -1, -1, 0
+}, yinc[] = {
+ -1, 0, 1, 1, 1, 0, -1, -1
+};
+static struct worm {
+ int orientation, head;
+ short *xpos, *ypos;
+} *worm;
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern int optind;
+ extern short ospeed;
+ extern char *optarg, *UP;
+ register int x, y, h, n;
+ register struct worm *w;
+ register struct options *op;
+ register short *ip;
+ register char *term;
+ int CO, IN, LI, last, bottom, ch, length, number, trail, Wrap;
+ void onsig();
+ short **ref;
+ char *AL, *BC, *CM, *EI, *HO, *IC, *IM, *IP, *SR;
+ char *field, tcb[100], *mp, *malloc(), *getenv(), *tgetstr(), *tgoto();
+ long random();
+#ifdef USG
+ struct termio sg;
+#else
+ struct sgttyb sg;
+#endif
+
+ length = 16;
+ number = 3;
+ trail = ' ';
+ field = NULL;
+ while ((ch = getopt(argc, argv, "fl:n:t")) != EOF)
+ switch(ch) {
+ case 'f':
+ field = "WORM";
+ break;
+ case 'l':
+ if ((length = atoi(optarg)) < 2 || length > 1024) {
+ (void)fprintf(stderr,
+ "worms: invalid length (%d - %d).\n",
+ 2, 1024);
+ exit(1);
+ }
+ break;
+ case 'n':
+ if ((number = atoi(optarg)) < 1) {
+ (void)fprintf(stderr,
+ "worms: invalid number of worms.\n");
+ exit(1);
+ }
+ break;
+ case 't':
+ trail = '.';
+ break;
+ case '?':
+ default:
+ (void)fprintf(stderr,
+ "usage: worms [-ft] [-length #] [-number #]\n");
+ exit(1);
+ }
+
+ if (!(term = getenv("TERM"))) {
+ (void)fprintf(stderr, "worms: no TERM environment variable.\n");
+ exit(1);
+ }
+ if (!(worm = (struct worm *)malloc((u_int)number *
+ sizeof(struct worm))) || !(mp = malloc((u_int)1024)))
+ nomem();
+ if (tgetent(mp, term) <= 0) {
+ (void)fprintf(stderr, "worms: %s: unknown terminal type.\n",
+ term);
+ exit(1);
+ }
+ tcp = tcb;
+ if (!(CM = tgetstr("cm", &tcp))) {
+ (void)fprintf(stderr,
+ "worms: terminal incapable of cursor motion.\n");
+ exit(1);
+ }
+ AL = tgetstr("al", &tcp);
+ BC = tgetflag("bs") ? "\b" : tgetstr("bc", &tcp);
+ if ((CO = tgetnum("co")) <= 0)
+ CO = 80;
+ last = CO - 1;
+ EI = tgetstr("ei", &tcp);
+ HO = tgetstr("ho", &tcp);
+ IC = tgetstr("ic", &tcp);
+ IM = tgetstr("im", &tcp);
+ IN = tgetflag("in");
+ IP = tgetstr("ip", &tcp);
+ if ((LI = tgetnum("li")) <= 0)
+ LI = 24;
+ bottom = LI - 1;
+ SR = tgetstr("sr", &tcp);
+ UP = tgetstr("up", &tcp);
+#ifdef USG
+ ioctl(1, TCGETA, &sg);
+ ospeed = sg.c_cflag&CBAUD;
+#else
+ gtty(1, &sg);
+ ospeed = sg.sg_ospeed;
+#endif
+ Wrap = tgetflag("am");
+ if (!(ip = (short *)malloc((u_int)(LI * CO * sizeof(short)))))
+ nomem();
+ if (!(ref = (short **)malloc((u_int)(LI * sizeof(short *)))))
+ nomem();
+ for (n = 0; n < LI; ++n) {
+ ref[n] = ip;
+ ip += CO;
+ }
+ for (ip = ref[0], n = LI * CO; --n >= 0;)
+ *ip++ = 0;
+ if (Wrap)
+ ref[bottom][last] = 1;
+ for (n = number, w = &worm[0]; --n >= 0; w++) {
+ w->orientation = w->head = 0;
+ if (!(ip = (short *)malloc((u_int)(length * sizeof(short)))))
+ nomem();
+ w->xpos = ip;
+ for (x = length; --x >= 0;)
+ *ip++ = -1;
+ if (!(ip = (short *)malloc((u_int)(length * sizeof(short)))))
+ nomem();
+ w->ypos = ip;
+ for (y = length; --y >= 0;)
+ *ip++ = -1;
+ }
+
+ (void)signal(SIGHUP, onsig);
+ (void)signal(SIGINT, onsig);
+ (void)signal(SIGQUIT, onsig);
+ (void)signal(SIGSTOP, onsig);
+ (void)signal(SIGTSTP, onsig);
+ (void)signal(SIGTERM, onsig);
+
+ tputs(tgetstr("ti", &tcp), 1, fputchar);
+ tputs(tgetstr("cl", &tcp), 1, fputchar);
+ if (field) {
+ register char *p = field;
+
+ for (y = bottom; --y >= 0;) {
+ for (x = CO; --x >= 0;) {
+ fputchar(*p++);
+ if (!*p)
+ p = field;
+ }
+ if (!Wrap)
+ fputchar('\n');
+ (void)fflush(stdout);
+ }
+ if (Wrap) {
+ if (IM && !IN) {
+ for (x = last; --x > 0;) {
+ fputchar(*p++);
+ if (!*p)
+ p = field;
+ }
+ y = *p++;
+ if (!*p)
+ p = field;
+ fputchar(*p);
+ if (BC)
+ tputs(BC, 1, fputchar);
+ else
+ cursor(last - 1, bottom);
+ tputs(IM, 1, fputchar);
+ if (IC)
+ tputs(IC, 1, fputchar);
+ fputchar(y);
+ if (IP)
+ tputs(IP, 1, fputchar);
+ tputs(EI, 1, fputchar);
+ }
+ else if (SR || AL) {
+ if (HO)
+ tputs(HO, 1, fputchar);
+ else
+ cursor(0, 0);
+ if (SR)
+ tputs(SR, 1, fputchar);
+ else
+ tputs(AL, LI, fputchar);
+ for (x = CO; --x >= 0;) {
+ fputchar(*p++);
+ if (!*p)
+ p = field;
+ }
+ }
+ else for (x = last; --x >= 0;) {
+ fputchar(*p++);
+ if (!*p)
+ p = field;
+ }
+ }
+ else for (x = CO; --x >= 0;) {
+ fputchar(*p++);
+ if (!*p)
+ p = field;
+ }
+ }
+ for (;;) {
+ (void)fflush(stdout);
+ for (n = 0, w = &worm[0]; n < number; n++, w++) {
+ if ((x = w->xpos[h = w->head]) < 0) {
+ cursor(x = w->xpos[h] = 0,
+ y = w->ypos[h] = bottom);
+ fputchar(flavor[n % sizeof(flavor)]);
+ ref[y][x]++;
+ }
+ else
+ y = w->ypos[h];
+ if (++h == length)
+ h = 0;
+ if (w->xpos[w->head = h] >= 0) {
+ register int x1, y1;
+
+ x1 = w->xpos[h];
+ y1 = w->ypos[h];
+ if (--ref[y1][x1] == 0) {
+ cursor(x1, y1);
+ if (trail)
+ fputchar(trail);
+ }
+ }
+ op = &(!x ? (!y ? upleft : (y == bottom ? lowleft : left)) : (x == last ? (!y ? upright : (y == bottom ? lowright : right)) : (!y ? upper : (y == bottom ? lower : normal))))[w->orientation];
+ switch (op->nopts) {
+ case 0:
+ (void)fflush(stdout);
+ abort();
+ return;
+ case 1:
+ w->orientation = op->opts[0];
+ break;
+ default:
+ w->orientation =
+ op->opts[(int)random() % op->nopts];
+ }
+ cursor(x += xinc[w->orientation],
+ y += yinc[w->orientation]);
+ if (!Wrap || x != last || y != bottom)
+ fputchar(flavor[n % sizeof(flavor)]);
+ ref[w->ypos[h] = y][w->xpos[h] = x]++;
+ }
+ }
+}
+
+void
+onsig()
+{
+ tputs(tgetstr("cl", &tcp), 1, fputchar);
+ tputs(tgetstr("te", &tcp), 1, fputchar);
+ exit(0);
+}
+
+fputchar(c)
+ char c;
+{
+ putchar(c);
+}
+
+nomem()
+{
+ (void)fprintf(stderr, "worms: not enough memory.\n");
+ exit(1);
+}
diff --git a/wump/Makefile b/wump/Makefile
new file mode 100644
index 00000000..ecb49134
--- /dev/null
+++ b/wump/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 5.4 (Berkeley) 5/11/90
+
+PROG= wump
+MAN6= wump.0
+HIDEGAME=hidegame
+
+beforeinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/wump.info \
+ ${DESTDIR}/usr/share/games
+
+.include <bsd.prog.mk>
diff --git a/wump/pathnames.h b/wump/pathnames.h
new file mode 100644
index 00000000..62e4203e
--- /dev/null
+++ b/wump/pathnames.h
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.1 (Berkeley) 6/1/90
+ */
+
+#define _PATH_PAGER "/usr/bin/more"
+#define _PATH_WUMPINFO "/usr/share/games/wump.info"
diff --git a/wump/wump.6 b/wump/wump.6
new file mode 100644
index 00000000..b230aab2
--- /dev/null
+++ b/wump/wump.6
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Dave Taylor, of Intuitive Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)wump.6 6.3 (Berkeley) 6/23/90
+.\"
+.TH WUMP 6 "June 23, 1990"
+.UC 7
+.SH NAME
+wump \- hunt the wumpus in an underground cave
+.SH SYNOPSIS
+.ft B
+wump [-h] [-a arrows] [-b bats] [-p pits] [-r rooms] [-t tunnels]
+.ft R
+.SH DESCRIPTION
+The game
+.I wump
+is based on a fantasy game first presented in the pages of
+.I "People's Computer Company"
+in 1973.
+In Hunt the Wumpus you are placed in a cave built of many different rooms,
+all interconnected by tunnels.
+Your quest is to find and shoot the evil Wumpus that resides elsewhere in
+the cave without running into any pits or using up your limited supply of
+arrows.
+.PP
+The options are as follows:
+.TP
+.I -a
+Specifies the number of magic arrows the adventurer gets.
+The default is five.
+.TP
+.I -b
+Specifies the number of rooms in the cave which contain bats.
+The default is three.
+.TP
+.I -h
+Play the hard version -- more pits, more bats, and a generally more
+dangerous cave.
+.TP
+.I -n
+Specifies the number of rooms in the cave which contain bottomless pits.
+The default is three.
+.TP
+.I -r
+Specifies the number of rooms in the cave.
+The default cave size is twenty-five rooms.
+.TP
+.I -t
+Specifies the number of tunnels connecting each room in the cave to
+another room.
+Beware, too many tunnels in a small cave can easily cause it to collapse!
+The default cave room has three tunnels to other rooms.
+.PP
+While wandering through the cave you'll notice that, while there are tunnels
+everywhere, there are some mysterious quirks to the cave topology, including
+some tunnels that go from one room to another, but not necessarily back!
+Also, most pesky of all are the rooms that are home to large numbers of bats,
+which, upon being disturbed, will en masse grab you and move you to another
+portion of the cave (including those housing bottomless pits, sure
+death for unwary explorers).
+.PP
+Fortunately, you're not going into the cave without any weapons or tools,
+and in fact your biggest aids are your senses; you can often smell the
+rather odiferous Wumpus up to
+.I two
+rooms away, and you can always feel the drafts created by the occasional
+bottomless pit and hear the rustle of the bats in caves they might be
+sleeping within.
+.PP
+To kill the wumpus, you'll need to shoot it with one of your magic arrows.
+Fortunately, you don't have to be in the same room as the creature, and can
+instead shoot the arrow from as far as three or four rooms away!
+.PP
+When you shoot an arrow, you do so by typing in a list of rooms that you'd
+like it to travel to.
+If at any point in its travels it cannot find a tunnel to the room you
+specify from the room it's in, it will instead randomly fly down one of the
+tunnels, possibly, if you're real unlucky, even flying back into the room
+you're in and hitting you!
diff --git a/wump/wump.c b/wump/wump.c
new file mode 100644
index 00000000..7d40b69b
--- /dev/null
+++ b/wump/wump.c
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * Copyright (c) 1989 Dave Taylor, Intuitive Systems.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Dave Taylor, of Intuitive Systems.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)wump.c 4.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * A very new version of the age old favorite Hunt-The-Wumpus game that has
+ * been a part of the BSD distribution of Unix for longer than us old folk
+ * would care to remember.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include "pathnames.h"
+
+/* some defines to spec out what our wumpus cave should look like */
+
+#define MAX_ARROW_SHOT_DISTANCE 6 /* +1 for '0' stopper */
+#define MAX_LINKS_IN_ROOM 25 /* a complex cave */
+
+#define MAX_ROOMS_IN_CAVE 250
+#define ROOMS_IN_CAVE 20
+#define MIN_ROOMS_IN_CAVE 10
+
+#define LINKS_IN_ROOM 3
+#define NUMBER_OF_ARROWS 5
+#define PIT_COUNT 3
+#define BAT_COUNT 3
+
+#define EASY 1 /* levels of play */
+#define HARD 2
+
+/* some macro definitions for cleaner output */
+
+#define plural(n) (n == 1 ? "" : "s")
+
+/* simple cave data structure; +1 so we can index from '1' not '0' */
+struct room_record {
+ int tunnel[MAX_LINKS_IN_ROOM];
+ int has_a_pit, has_a_bat;
+} cave[MAX_ROOMS_IN_CAVE+1];
+
+/*
+ * global variables so we can keep track of where the player is, how
+ * many arrows they still have, where el wumpo is, and so on...
+ */
+int player_loc = -1; /* player location */
+int wumpus_loc = -1; /* The Bad Guy location */
+int level = EASY; /* level of play */
+int arrows_left; /* arrows unshot */
+
+#ifdef DEBUG
+int debug = 0;
+#endif
+
+int pit_num = PIT_COUNT; /* # pits in cave */
+int bat_num = BAT_COUNT; /* # bats */
+int room_num = ROOMS_IN_CAVE; /* # rooms in cave */
+int link_num = LINKS_IN_ROOM; /* links per room */
+int arrow_num = NUMBER_OF_ARROWS; /* arrow inventory */
+
+char answer[20]; /* user input */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern char *optarg;
+ int c;
+
+#ifdef DEBUG
+ while ((c = getopt(argc, argv, "a:b:hp:r:t:d")) != EOF)
+#else
+ while ((c = getopt(argc, argv, "a:b:hp:r:t:")) != EOF)
+#endif
+ switch (c) {
+ case 'a':
+ arrow_num = atoi(optarg);
+ break;
+ case 'b':
+ bat_num = atoi(optarg);
+ break;
+#ifdef DEBUG
+ case 'd':
+ debug = 1;
+ break;
+#endif
+ case 'h':
+ level = HARD;
+ break;
+ case 'p':
+ pit_num = atoi(optarg);
+ break;
+ case 'r':
+ room_num = atoi(optarg);
+ if (room_num < MIN_ROOMS_IN_CAVE) {
+ (void)fprintf(stderr,
+ "No self-respecting wumpus would live in such a small cave!\n");
+ exit(1);
+ }
+ if (room_num > MAX_ROOMS_IN_CAVE) {
+ (void)fprintf(stderr,
+ "Even wumpii can't furnish caves that large!\n");
+ exit(1);
+ }
+ break;
+ case 't':
+ link_num = atoi(optarg);
+ if (link_num < 2) {
+ (void)fprintf(stderr,
+ "Wumpii like extra doors in their caves!\n");
+ exit(1);
+ }
+ break;
+ case '?':
+ default:
+ usage();
+ }
+
+ if (link_num > MAX_LINKS_IN_ROOM ||
+ link_num > room_num - (room_num / 4)) {
+ (void)fprintf(stderr,
+"Too many tunnels! The cave collapsed!\n(Fortunately, the wumpus escaped!)\n");
+ exit(1);
+ }
+
+ if (level == HARD) {
+ bat_num += ((random() % (room_num / 2)) + 1);
+ pit_num += ((random() % (room_num / 2)) + 1);
+ }
+
+ if (bat_num > room_num / 2) {
+ (void)fprintf(stderr,
+"The wumpus refused to enter the cave, claiming it was too crowded!\n");
+ exit(1);
+ }
+
+ if (pit_num > room_num / 2) {
+ (void)fprintf(stderr,
+"The wumpus refused to enter the cave, claiming it was too dangerous!\n");
+ exit(1);
+ }
+
+ instructions();
+ cave_init();
+
+ /* and we're OFF! da dum, da dum, da dum, da dum... */
+ (void)printf(
+"\nYou're in a cave with %d rooms and %d tunnels leading from each room.\n\
+There are %d bat%s and %d pit%s scattered throughout the cave, and your\n\
+quiver holds %d custom super anti-evil Wumpus arrows. Good luck.\n",
+ room_num, link_num, bat_num, plural(bat_num), pit_num,
+ plural(pit_num), arrow_num);
+
+ for (;;) {
+ initialize_things_in_cave();
+ arrows_left = arrow_num;
+ do {
+ display_room_stats();
+ (void)printf("Move or shoot? (m-s) ");
+ (void)fflush(stdout);
+ if (!fgets(answer, sizeof(answer), stdin))
+ break;
+ } while (!take_action());
+
+ if (!getans("\nCare to play another game? (y-n) "))
+ exit(0);
+ if (getans("In the same cave? (y-n) "))
+ clear_things_in_cave();
+ else
+ cave_init();
+ }
+ /* NOTREACHED */
+}
+
+display_room_stats()
+{
+ register int i;
+
+ /*
+ * Routine will explain what's going on with the current room, as well
+ * as describe whether there are pits, bats, & wumpii nearby. It's
+ * all pretty mindless, really.
+ */
+ (void)printf(
+"\nYou are in room %d of the cave, and have %d arrow%s left.\n",
+ player_loc, arrows_left, plural(arrows_left));
+
+ if (bats_nearby())
+ (void)printf("*rustle* *rustle* (must be bats nearby)\n");
+ if (pit_nearby())
+ (void)printf("*whoosh* (I feel a draft from some pits).\n");
+ if (wump_nearby())
+ (void)printf("*sniff* (I can smell the evil Wumpus nearby!)\n");
+
+ (void)printf("There are tunnels to rooms %d, ",
+ cave[player_loc].tunnel[0]);
+
+ for (i = 1; i < link_num - 1; i++)
+ if (cave[player_loc].tunnel[i] <= room_num)
+ (void)printf("%d, ", cave[player_loc].tunnel[i]);
+ (void)printf("and %d.\n", cave[player_loc].tunnel[link_num - 1]);
+}
+
+take_action()
+{
+ /*
+ * Do the action specified by the player, either 'm'ove, 's'hoot
+ * or something exceptionally bizarre and strange! Returns 1
+ * iff the player died during this turn, otherwise returns 0.
+ */
+ switch (*answer) {
+ case 'M':
+ case 'm': /* move */
+ return(move_to(answer + 1));
+ case 'S':
+ case 's': /* shoot */
+ return(shoot(answer + 1));
+ case 'Q':
+ case 'q':
+ case 'x':
+ exit(0);
+ case '\n':
+ return(0);
+ }
+ if (random() % 15 == 1)
+ (void)printf("Que pasa?\n");
+ else
+ (void)printf("I don't understand!\n");
+ return(0);
+}
+
+move_to(room_number)
+ char *room_number;
+{
+ int i, just_moved_by_bats, next_room, tunnel_available;
+
+ /*
+ * This is responsible for moving the player into another room in the
+ * cave as per their directions. If room_number is a null string,
+ * then we'll prompt the user for the next room to go into. Once
+ * we've moved into the room, we'll check for things like bats, pits,
+ * and so on. This routine returns 1 if something occurs that kills
+ * the player and 0 otherwise...
+ */
+ tunnel_available = just_moved_by_bats = 0;
+ next_room = atoi(room_number);
+
+ /* crap for magic tunnels */
+ if (next_room == room_num + 1 &&
+ cave[player_loc].tunnel[link_num-1] != next_room)
+ ++next_room;
+
+ while (next_room < 1 || next_room > room_num + 1) {
+ if (next_room < 0 && next_room != -1)
+(void)printf("Sorry, but we're constrained to a semi-Euclidean cave!\n");
+ if (next_room > room_num + 1)
+(void)printf("What? The cave surely isn't quite that big!\n");
+ if (next_room == room_num + 1 &&
+ cave[player_loc].tunnel[link_num-1] != next_room) {
+ (void)printf("What? The cave isn't that big!\n");
+ ++next_room;
+ }
+ (void)printf("To which room do you wish to move? ");
+ (void)fflush(stdout);
+ if (!fgets(answer, sizeof(answer), stdin))
+ return(1);
+ next_room = atoi(answer);
+ }
+
+ /* now let's see if we can move to that room or not */
+ tunnel_available = 0;
+ for (i = 0; i < link_num; i++)
+ if (cave[player_loc].tunnel[i] == next_room)
+ tunnel_available = 1;
+
+ if (!tunnel_available) {
+ (void)printf("*Oof!* (You hit the wall)\n");
+ if (random() % 6 == 1) {
+(void)printf("Your colorful comments awaken the wumpus!\n");
+ move_wump();
+ if (wumpus_loc == player_loc) {
+ wump_kill();
+ return(1);
+ }
+ }
+ return(0);
+ }
+
+ /* now let's move into that room and check it out for dangers */
+ if (next_room == room_num + 1)
+ jump(next_room = (random() % room_num) + 1);
+
+ player_loc = next_room;
+ for (;;) {
+ if (next_room == wumpus_loc) { /* uh oh... */
+ wump_kill();
+ return(1);
+ }
+ if (cave[next_room].has_a_pit)
+ if (random() % 12 < 2) {
+ pit_survive();
+ return(0);
+ } else {
+ pit_kill();
+ return(1);
+ }
+
+ if (cave[next_room].has_a_bat) {
+ (void)printf(
+"*flap* *flap* *flap* (humongous bats pick you up and move you%s!)\n",
+ just_moved_by_bats ? " again": "");
+ next_room = player_loc = (random() % room_num) + 1;
+ just_moved_by_bats = 1;
+ }
+
+ else
+ break;
+ }
+ return(0);
+}
+
+shoot(room_list)
+ char *room_list;
+{
+ int chance, next, roomcnt;
+ int j, arrow_location, link, ok;
+ char *p, *strtok();
+
+ /*
+ * Implement shooting arrows. Arrows are shot by the player indicating
+ * a space-separated list of rooms that the arrow should pass through;
+ * if any of the rooms they specify are not accessible via tunnel from
+ * the room the arrow is in, it will instead fly randomly into another
+ * room. If the player hits the wumpus, this routine will indicate
+ * such. If it misses, this routine will *move* the wumpus one room.
+ * If it's the last arrow, the player then dies... Returns 1 if the
+ * player has won or died, 0 if nothing has happened.
+ */
+ arrow_location = player_loc;
+ for (roomcnt = 1;; ++roomcnt, room_list = NULL) {
+ if (!(p = strtok(room_list, " \t\n")))
+ if (roomcnt == 1) {
+ (void)printf(
+ "The arrow falls to the ground at your feet!\n");
+ return(0);
+ } else
+ break;
+ if (roomcnt > 5) {
+ (void)printf(
+"The arrow wavers in its flight and and can go no further!\n");
+ break;
+ }
+ next = atoi(p);
+ for (j = 0, ok = 0; j < link_num; j++)
+ if (cave[arrow_location].tunnel[j] == next)
+ ok = 1;
+
+ if (ok) {
+ if (next > room_num) {
+ (void)printf(
+"A faint gleam tells you the arrow has gone through a magic tunnel!\n");
+ arrow_location = (random() % room_num) + 1;
+ } else
+ arrow_location = next;
+ } else {
+ link = (random() % link_num);
+ if (link == player_loc)
+ (void)printf(
+"*thunk* The arrow can't find a way from %d to %d and flys back into\n\
+your room!\n",
+ arrow_location, next);
+ else if (cave[arrow_location].tunnel[link] > room_num)
+ (void)printf(
+"*thunk* The arrow flys randomly into a magic tunnel, thence into\n\
+room %d!\n",
+ cave[arrow_location].tunnel[link]);
+ else
+ (void)printf(
+"*thunk* The arrow can't find a way from %d to %d and flys randomly\n\
+into room %d!\n",
+ arrow_location, next,
+ cave[arrow_location].tunnel[link]);
+ arrow_location = cave[arrow_location].tunnel[link];
+ break;
+ }
+ chance = random() % 10;
+ if (roomcnt == 3 && chance < 2) {
+ (void)printf(
+"Your bowstring breaks! *twaaaaaang*\n\
+The arrow is weakly shot and can go no further!\n");
+ break;
+ } else if (roomcnt == 4 && chance < 6) {
+ (void)printf(
+"The arrow wavers in its flight and and can go no further!\n");
+ break;
+ }
+ }
+
+ /*
+ * now we've gotten into the new room let us see if El Wumpo is
+ * in the same room ... if so we've a HIT and the player WON!
+ */
+ if (arrow_location == wumpus_loc) {
+ kill_wump();
+ return(1);
+ }
+
+ if (arrow_location == player_loc) {
+ shoot_self();
+ return(1);
+ }
+
+ if (!--arrows_left) {
+ no_arrows();
+ return(1);
+ }
+
+ {
+ /* each time you shoot, it's more likely the wumpus moves */
+ static int lastchance = 2;
+
+ if (random() % level == EASY ? 12 : 9 < (lastchance += 2)) {
+ move_wump();
+ if (wumpus_loc == player_loc)
+ wump_kill();
+ lastchance = random() % 3;
+
+ }
+ }
+ return(0);
+}
+
+cave_init()
+{
+ register int i, j, k, link;
+ int delta, int_compare();
+ time_t time();
+
+ /*
+ * This does most of the interesting work in this program actually!
+ * In this routine we'll initialize the Wumpus cave to have all rooms
+ * linking to all others by stepping through our data structure once,
+ * recording all forward links and backwards links too. The parallel
+ * "linkcount" data structure ensures that no room ends up with more
+ * than three links, regardless of the quality of the random number
+ * generator that we're using.
+ */
+ srandom((int)time((time_t *)0));
+
+ /* initialize the cave first off. */
+ for (i = 1; i <= room_num; ++i)
+ for (j = 0; j < link_num ; ++j)
+ cave[i].tunnel[j] = -1;
+
+ /* choose a random 'hop' delta for our guaranteed link */
+ while (!(delta = random() % room_num));
+
+ for (i = 1; i <= room_num; ++i) {
+ link = ((i + delta) % room_num) + 1; /* connection */
+ cave[i].tunnel[0] = link; /* forw link */
+ cave[link].tunnel[1] = i; /* back link */
+ }
+ /* now fill in the rest of the cave with random connections */
+ for (i = 1; i <= room_num; i++)
+ for (j = 2; j < link_num ; j++) {
+ if (cave[i].tunnel[j] != -1)
+ continue;
+try_again: link = (random() % room_num) + 1;
+ /* skip duplicates */
+ for (k = 0; k < j; k++)
+ if (cave[i].tunnel[k] == link)
+ goto try_again;
+ cave[i].tunnel[j] = link;
+ if (random() % 2 == 1)
+ continue;
+ for (k = 0; k < link_num; ++k) {
+ /* if duplicate, skip it */
+ if (cave[link].tunnel[k] == i)
+ k = link_num;
+
+ /* if open link, use it, force exit */
+ if (cave[link].tunnel[k] == -1) {
+ cave[link].tunnel[k] = i;
+ k = link_num;
+ }
+ }
+ }
+ /*
+ * now that we're done, sort the tunnels in each of the rooms to
+ * make it easier on the intrepid adventurer.
+ */
+ for (i = 1; i <= room_num; ++i)
+ qsort(cave[i].tunnel, (u_int)link_num,
+ sizeof(cave[i].tunnel[0]), int_compare);
+
+#ifdef DEBUG
+ if (debug)
+ for (i = 1; i <= room_num; ++i) {
+ (void)printf("<room %d has tunnels to ", i);
+ for (j = 0; j < link_num; ++j)
+ (void)printf("%d ", cave[i].tunnel[j]);
+ (void)printf(">\n");
+ }
+#endif
+}
+
+clear_things_in_cave()
+{
+ register int i;
+
+ /*
+ * remove bats and pits from the current cave in preparation for us
+ * adding new ones via the initialize_things_in_cave() routines.
+ */
+ for (i = 1; i <= room_num; ++i)
+ cave[i].has_a_bat = cave[i].has_a_pit = 0;
+}
+
+initialize_things_in_cave()
+{
+ register int i, loc;
+
+ /* place some bats, pits, the wumpus, and the player. */
+ for (i = 0; i < bat_num; ++i) {
+ do {
+ loc = (random() % room_num) + 1;
+ } while (cave[loc].has_a_bat);
+ cave[loc].has_a_bat = 1;
+#ifdef DEBUG
+ if (debug)
+ (void)printf("<bat in room %d>\n", loc);
+#endif
+ }
+
+ for (i = 0; i < pit_num; ++i) {
+ do {
+ loc = (random() % room_num) + 1;
+ } while (cave[loc].has_a_pit && cave[loc].has_a_bat);
+ cave[loc].has_a_pit = 1;
+#ifdef DEBUG
+ if (debug)
+ (void)printf("<pit in room %d>\n", loc);
+#endif
+ }
+
+ wumpus_loc = (random() % room_num) + 1;
+#ifdef DEBUG
+ if (debug)
+ (void)printf("<wumpus in room %d>\n", loc);
+#endif
+
+ do {
+ player_loc = (random() % room_num) + 1;
+ } while (player_loc == wumpus_loc || (level == HARD ?
+ (link_num / room_num < 0.4 ? wump_nearby() : 0) : 0));
+}
+
+getans(prompt)
+ char *prompt;
+{
+ char buf[20];
+
+ /*
+ * simple routine to ask the yes/no question specified until the user
+ * answers yes or no, then return 1 if they said 'yes' and 0 if they
+ * answered 'no'.
+ */
+ for (;;) {
+ (void)printf("%s", prompt);
+ (void)fflush(stdout);
+ if (!fgets(buf, sizeof(buf), stdin))
+ return(0);
+ if (*buf == 'N' || *buf == 'n')
+ return(0);
+ if (*buf == 'Y' || *buf == 'y')
+ return(1);
+ (void)printf(
+"I don't understand your answer; please enter 'y' or 'n'!\n");
+ }
+ /* NOTREACHED */
+}
+
+bats_nearby()
+{
+ register int i;
+
+ /* check for bats in the immediate vicinity */
+ for (i = 0; i < link_num; ++i)
+ if (cave[cave[player_loc].tunnel[i]].has_a_bat)
+ return(1);
+ return(0);
+}
+
+pit_nearby()
+{
+ register int i;
+
+ /* check for pits in the immediate vicinity */
+ for (i = 0; i < link_num; ++i)
+ if (cave[cave[player_loc].tunnel[i]].has_a_pit)
+ return(1);
+ return(0);
+}
+
+wump_nearby()
+{
+ register int i, j;
+
+ /* check for a wumpus within TWO caves of where we are */
+ for (i = 0; i < link_num; ++i) {
+ if (cave[player_loc].tunnel[i] == wumpus_loc)
+ return(1);
+ for (j = 0; j < link_num; ++j)
+ if (cave[cave[player_loc].tunnel[i]].tunnel[j] ==
+ wumpus_loc)
+ return(1);
+ }
+ return(0);
+}
+
+move_wump()
+{
+ wumpus_loc = cave[wumpus_loc].tunnel[random() % link_num];
+}
+
+int_compare(a, b)
+ int *a, *b;
+{
+ return(*a < *b ? -1 : 1);
+}
+
+instructions()
+{
+ char buf[120], *p, *getenv();
+
+ /*
+ * read the instructions file, if needed, and show the user how to
+ * play this game!
+ */
+ if (!getans("Instructions? (y-n) "))
+ return;
+
+ if (access(_PATH_WUMPINFO, R_OK)) {
+ (void)printf(
+"Sorry, but the instruction file seems to have disappeared in a\n\
+puff of greasy black smoke! (poof)\n");
+ return;
+ }
+
+ if (!(p = getenv("PAGER")) ||
+ strlen(p) > sizeof(buf) + strlen(_PATH_WUMPINFO) + 5)
+ p = _PATH_PAGER;
+
+ (void)sprintf(buf, "%s %s", p, _PATH_WUMPINFO);
+ (void)system(buf);
+}
+
+usage()
+{
+ (void)fprintf(stderr,
+"usage: wump [-h] [-a arrows] [-b bats] [-p pits] [-r rooms] [-t tunnels]\n");
+ exit(1);
+}
+
+/* messages */
+
+wump_kill()
+{
+ (void)printf(
+"*ROAR* *chomp* *snurfle* *chomp*!\n\
+Much to the delight of the Wumpus, you walked right into his mouth,\n\
+making you one of the easiest dinners he's ever had! For you, however,\n\
+it's a rather unpleasant death. The only good thing is that it's been\n\
+so long since the evil Wumpus cleaned his teeth that you immediately\n\
+passed out from the stench!\n");
+}
+
+kill_wump()
+{
+ (void)printf(
+"*thwock!* *groan* *crash*\n\n\
+A horrible roar fills the cave, and you realize, with a smile, that you\n\
+have slain the evil Wumpus and won the game! You don't want to tarry for\n\
+long, however, because not only is the Wumpus famous, but the stench of\n\
+dead Wumpus is also quite well known, a stench plenty enough to slay the\n\
+mightiest adventurer at a single whiff!!\n");
+}
+
+no_arrows()
+{
+ (void)printf(
+"\nYou turn and look at your quiver, and realize with a sinking feeling\n\
+that you've just shot your last arrow (figuratively, too). Sensing this\n\
+with its psychic powers, the evil Wumpus rampagees through the cave, finds\n\
+you, and with a mighty *ROAR* eats you alive!\n");
+}
+
+shoot_self()
+{
+ (void)printf(
+"\n*Thwack!* A sudden piercing feeling informs you that the ricochet\n\
+of your wild arrow has resulted in it wedging in your side, causing\n\
+extreme agony. The evil Wumpus, with its psychic powers, realizes this\n\
+and immediately rushes to your side, not to help, alas, but to EAT YOU!\n\
+(*CHOMP*)\n");
+}
+
+jump(where)
+ int where;
+{
+ (void)printf(
+"\nWith a jaunty step you enter the magic tunnel. As you do, you\n\
+notice that the walls are shimmering and glowing. Suddenly you feel\n\
+a very curious, warm sensation and find yourself in room %d!!\n", where);
+}
+
+pit_kill()
+{
+ (void)printf(
+"*AAAUUUUGGGGGHHHHHhhhhhhhhhh...*\n\
+The whistling sound and updraft as you walked into this room of the\n\
+cave apparently wasn't enough to clue you in to the presence of the\n\
+bottomless pit. You have a lot of time to reflect on this error as\n\
+you fall many miles to the core of the earth. Look on the bright side;\n\
+you can at least find out if Jules Verne was right...\n");
+}
+
+pit_survive()
+{
+ (void)printf(
+"Without conscious thought you grab for the side of the cave and manage\n\
+to grasp onto a rocky outcrop. Beneath your feet stretches the limitless\n\
+depths of a bottomless pit! Rock crumbles beneath your feet!\n");
+}
diff --git a/wump/wump.info b/wump/wump.info
new file mode 100644
index 00000000..329e8219
--- /dev/null
+++ b/wump/wump.info
@@ -0,0 +1,41 @@
+Welcome to the game of Hunt the Wumpus.
+
+The Wumpus typically lives in a cave of twenty rooms, with each room having
+three tunnels connecting it to other rooms in the cavern. Caves may vary,
+however, depending on options specified when starting the game.
+
+The game has the following hazards for intrepid adventurers to wind their
+way through:
+
+ Pits -- If you fall into one of the bottomless pits, you find yourself
+ slung back out on the far side of the Earth and in very poor
+ shape to continue your quest since you're dead.
+
+ Bats -- As with any other cave, the Wumpus cave has bats in residence.
+ These are a bit more potent, however, and if you stumble into
+ one of their rooms they will rush up and carry you elsewhere in
+ the cave.
+
+ Wumpus -- If you happen to walk into the room the Wumpus is in you'll find
+ that he has quite an appetite for young adventurous humans! Not
+ recommended.
+
+The Wumpus, by the way, is not bothered by the hazards since he has sucker
+feet and is too big for a bat to lift. If you try to shoot him and miss,
+there's also a chance that he'll up and move himself into another cave,
+though by nature the Wumpus is a sedentary creature.
+
+Each turn you may either move or shoot a crooked arrow. Moving is done
+simply by specifying "m" for move and the number of the room that you'd
+like to move down a tunnel towards. Shooting is done similarly; indicate
+that you'd like to shoot one of your magic arrows with an "s" for shoot,
+then list a set of connected room numbers through which the deadly shaft
+should fly!
+
+If your path for the arrow is incorrect, however, it will flail about in
+the room it can't understand and randomly pick a tunnel to continue
+through. You might just end up shooting yourself in the foot if you're
+not careful! On the other hand, if you shoot the Wumpus you've WON!
+
+Good luck.
+