goer@ellis.uchicago.edu (Richard L. Goerwitz) (04/22/91)
These are a some fairly minor patches which I applied to klondike in order to get it to run on my local system here. Since the vast, vast majority of UNIX systems out there don't use the PC character set, I've changed the defaults around so that klondike doesn't as- sume a PC character set if \isPC and \isDOS are not defined. I did a few other things here and there to get klondike to run on a vt100 terminal at my home using my (poor) system termcap file. Really, though, I didn't do much. I don't believe I've ever seen such a nice piece of software posted on this newsgroup. (N.A., why not cross-post to comp.sources.games when we've all had our fun with it?) What's especially interesting about klondike is that the author - who used to claim novice-hood at Icon - clearly has come into full mastery of his medium, and has gone to great lengths to write clean and readable code. It'll be a pleasure to stick this in my source tree! -Richard P.S. Unix users: Apply these using patch -p < patchfilename. ----------------------- diffs for klondike ------------------------- *** kloncon.icn~ Sun Apr 21 22:30:15 1991 --- kloncon.icn Mon Apr 22 01:27:44 1991 *************** *** 32,48 **** # For DOS, we simply look to see if any keystroke is waiting, discarding # it/them. Your system may be different. procedure userInterrupt () ! static keyWaiting ! initial { ! keyWaiting := if \type(kbhit) then "kbhit" ! } if \isDOS then ! while keyWaiting() do { (getch() == "\0") & getch() #eat interrupting keystroke return #success means "interrupt requested" } else ! (\keyWaiting) & keyWaiting() & getch() & return fail #failure = "interrupt NOT requested" end #userInterrupt --- 32,45 ---- # For DOS, we simply look to see if any keystroke is waiting, discarding # it/them. Your system may be different. procedure userInterrupt () ! if \isDOS then ! while kbhit() do { (getch() == "\0") & getch() #eat interrupting keystroke return #success means "interrupt requested" } else ! (\kbhit)() & getch() & return fail #failure = "interrupt NOT requested" end #userInterrupt *************** *** 58,69 **** static outstr local s initial { ! outstr := table("Oops!") outstr[VclearAll] := getval("cl") | (getval("ho") || getval("cd")) outstr[VclearEOL] := getval("ce") ! outstr[Vnormal] := getval("me") || getval("ue") outstr[Vbold] := getval("md" | "us") ! outstr[Vblink] := getval("mb") outstr[Vreverse] := getval("mr" | "so") outstr[VbackSpace] := if getval("bs") then "\b" else getval("le") if \isQuiet then --- 55,66 ---- static outstr local s initial { ! outstr := table(getval("me" | "se") || getval("ue")) outstr[VclearAll] := getval("cl") | (getval("ho") || getval("cd")) outstr[VclearEOL] := getval("ce") ! outstr[Vnormal] := getval("me" | "se") || (getval("ue") | "") outstr[Vbold] := getval("md" | "us") ! outstr[Vblink] := getval("mb" | "us" | "md") outstr[Vreverse] := getval("mr" | "so") outstr[VbackSpace] := if getval("bs") then "\b" else getval("le") if \isQuiet then *************** *** 107,118 **** local Vred, Vblack #suit color strings lineCount := 25 #assume the best ! case (map(termtype, &lcase, &ucase)) of { "PC" : { getANSItype (); isANSI := 1 } "MONO" : { isMonochrome := 1; isANSI := 1 } "COLOR" : { isMonochrome := &null; isANSI := 1 } default : { isMonochrome := 1; isANSI := &null ! (0 < *termtype) & setname (termtype) lineCount := getval("li") } } --- 104,116 ---- local Vred, Vblack #suit color strings lineCount := 25 #assume the best ! termtype := (map(\termtype, &lcase, &ucase)) ! case termtype of { "PC" : { getANSItype (); isANSI := 1 } "MONO" : { isMonochrome := 1; isANSI := 1 } "COLOR" : { isMonochrome := &null; isANSI := 1 } default : { isMonochrome := 1; isANSI := &null ! setname (map("" ~== \termtype)) lineCount := getval("li") } } *************** *** 202,218 **** # t e r m i n a t e S c r e e n # Put the screen in the correct state prior to program termination. procedure terminateScreen () - static resetCooked - initial { - resetCooked := if \type(reset_tty) then "reset_tty" - } if /invisible then ! if \isANSI then write ("\e[=7h", VclearAll, Vnormal) #set cursor wrap mode ! else { ! output (VclearAll, Vnormal, getval("te")) ! (/isDOS) & (\resetCooked) & resetCooked () } return end #terminateScreen --- 200,215 ---- # t e r m i n a t e S c r e e n # Put the screen in the correct state prior to program termination. procedure terminateScreen () if /invisible then ! if \isANSI then { write ("\e[=7h", VclearAll, Vnormal) #set cursor wrap mode ! (\reset_tty) () } + else { + output (VclearAll, Vnormal) + iputs (getval("te")) + (\reset_tty) () # will be nonnull only if getchlib + } # is linked return end #terminateScreen *** klondike.icn~ Sun Apr 21 22:30:14 1991 --- klondike.icn Mon Apr 22 00:42:25 1991 *************** *** 44,50 **** helpInfo := [ ["A", "Automatic", " mode -- finish out this game on automatic pilot"], ["B", "Boss", " key for when you-know-who visits"], ! ["C","Continuous"," mode -- play games continuously until interrupted"], ["F", "Find", " (next) useful move to do"], ["H,?", "Help", ", this help screen"], ["M", "Move", " card (or stack) from Deck/Stack to Stack/Ace pile"], --- 44,50 ---- helpInfo := [ ["A", "Automatic", " mode -- finish out this game on automatic pilot"], ["B", "Boss", " key for when you-know-who visits"], ! ["C","Continuous"," mode -- play until interrupted (not UNIX)"], ["F", "Find", " (next) useful move to do"], ["H,?", "Help", ", this help screen"], ["M", "Move", " card (or stack) from Deck/Stack to Stack/Ace pile"], *************** *** 365,371 **** procedure uboss () writes ("oss") # "consistency is the hobgoblin of small minds" terminateScreen () #put screen in the correct state - writes ("C>") #look innocent saveState ("klondike.sav") exit () end #uboss --- 365,370 ---- *************** *** 457,464 **** # Results are reported after every interval (0 => only at end) games. # Statistics are output when done or interrupted, whichever comes first. procedure ubatch (gamesToPlay, interval) ! local veryFirstSeed, stat ! isQuiet := invisible := 1 veryFirstSeed := &random #remember the initial random seed (interval = 0) & (interval := gamesToPlay) repeat { --- 456,463 ---- # Results are reported after every interval (0 => only at end) games. # Statistics are output when done or interrupted, whichever comes first. procedure ubatch (gamesToPlay, interval) ! local veryFirstSeed, stat ! isQuiet := invisible := 1 veryFirstSeed := &random #remember the initial random seed (interval = 0) & (interval := gamesToPlay) repeat { *************** *** 472,479 **** (stat[1] ~= interval) & break #interrupted by user (0 = (gamesToPlay -:= interval)) & break } ! firstSeed := veryFirstSeed #required for writeStatistics() ! writeStatistics () exit () end #ubatch --- 471,479 ---- (stat[1] ~= interval) & break #interrupted by user (0 = (gamesToPlay -:= interval)) & break } ! firstSeed := veryFirstSeed #required for writeStatistics() ! (\reset_tty)() ! writeStatistics () exit () end #ubatch *************** *** 483,490 **** local s, prevsCmd, batchMode, reportInterval, again, termtype # initialize ! isDOS := find("MS-DOS", &host) #probably a reasonable assumption ! isPC := isDOS #really a pretty poor assumption totalGames:=totalAces:=totalWins := 0 #statistics # set defaults --- 483,491 ---- local s, prevsCmd, batchMode, reportInterval, again, termtype # initialize ! if isDOS := find("MS-DOS", ! &host|&features) #probably a reasonable assumption ! then isPC := isDOS #really a pretty poor assumption totalGames:=totalAces:=totalWins := 0 #statistics # set defaults *************** *** 497,503 **** reportInterval := 0 # report only at end of batch mode phraseFile := &null # use all built-in phrases isQuiet := &null # make clicks & beeps if possible ! termtype := if \isPC then "pc" else "mono" &random := map (&clock, ":", "7") # randomize the seed # deal with command-line parameters --- 498,504 ---- reportInterval := 0 # report only at end of batch mode phraseFile := &null # use all built-in phrases isQuiet := &null # make clicks & beeps if possible ! termtype := if \isPC then "pc" # default term type for PCs &random := map (&clock, ":", "7") # randomize the seed # deal with command-line parameters *************** *** 518,523 **** --- 519,525 ---- "-R" | "-r" : &random := integer (s[3:0]) "-S" | "-s" : findBest (s[3:0]) #check & store strategy "-T" | "-t" : termtype := s[3:0] + "-Z" | "-z" : debugging := if \debugging then &null else 1 default : { # screen mode not yet initialized, so write() is OK *************** *** 529,535 **** } # initializations which use command-line parameters ! (map(termtype, &lcase, &ucase) == "PC") & isPC := 1 initConstants (termtype) #need updated termtype from cmdline initVariables () #establish all the lists and such --- 531,537 ---- } # initializations which use command-line parameters ! (map(\termtype, &lcase, &ucase) == "PC") & isPC := 1 initConstants (termtype) #need updated termtype from cmdline initVariables () #establish all the lists and such *************** *** 566,572 **** umove (s) | complain () "A" : uautomatic() #look Ma, no hands! "B" : uboss() #bail out quick ! "C" : ucontinuous() #no hands, forever "F" : ufind (again) & break #new game "M" : umove (&null) | complain () "Q" : uterminate () & break #new game --- 568,574 ---- umove (s) | complain () "A" : uautomatic() #look Ma, no hands! "B" : uboss() #bail out quick ! "C" : \isDOS & ucontinuous() #no hands, forever "F" : ufind (again) & break #new game "M" : umove (&null) | complain () "Q" : uterminate () & break #new game *** makefile.unx~ Sun Apr 21 22:30:12 1991 --- makefile.unx Mon Apr 22 00:45:46 1991 *************** *** 1,18 **** #makefile.unx 910322 NHA ! #An unix makefile for klondike # ! #Assumes that iolib.u? and getchlib.u? are already available somewhere ! #along $IPATH. ! #Note that only getchlib is linked on the command line. Everything else ! #is linked in the program. ! .SUFFIXES: .u1 .icn .icn.u1: icont -c $? ! klondike: klondike.icn kloncon.u1 klonstr.u1 klonsub.u1 getchlib.u1 ! icont -u -Si1000 -Sn2000 klondike getchlib.u1 clean: rm -f *.u? klondike --- 1,19 ---- #makefile.unx 910322 NHA ! #Unix makefile for klondike # ! #Note that only getchlib and iolib are explicitly linked on the command ! #line; other auxiliary files are loaded by link directives withing klon- ! #dike.icn. ! .SUFFIXES: .u1 .icn .icn.u1: icont -c $? ! SHELL = /bin/sh ! ! klondike: klondike.icn kloncon.u1 klonstr.u1 klonsub.u1 getchlib.u1 iolib.u1 ! icont -u -Si1000 -Sn2000 klondike getchlib.u1 iolib.u1 clean: rm -f *.u? klondike -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
goer@ellis.uchicago.edu (Richard L. Goerwitz) (04/23/91)
Just a note - an IMPORTANT one - to tack onto the preceding: Please read through the getchlib docs if you are on a system that does not implement the -g option for stty. Also if your stty command can't write its output to a pipe (what a sorry world this is), check the getchlib.icn file as well. OTHERWISE YOUR TERMINAL ENDS UP IN RAW MODE! People with regular System V stty commands or older BSD ones (or some newer BSD ones -it apparently works here on our Sun3) should have no- thing to worry about. I'm sorry I didn't mention this sooner. -Richard -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
goer@ellis.uchicago.edu (Richard L. Goerwitz) (04/23/91)
goer@ellis.uchicago.edu (Richard L. Goerwitz) writes: >Also if your stty command can't write its output to a pipe... ...then gloom and doom. I just fixed getchlib so that it runs on our Sun4 cluster here, even with the oddball stty command. It's all in the makefile now. Having burdened the net with patches already (ones that should probably work for most machines), I'm not going to post a bunch more patches. If anyone wants them, please let me know. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer