[comp.lang.icon] UNIX diffs, klondike

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