home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group90c.txt < prev    next >
Text File  |  1991-01-03  |  460KB  |  12,905 lines

  1.  
  2. From ralph  Tue Oct  9 08:37:22 1990
  3. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  4.     id AA05206; Tue, 9 Oct 90 08:37:22 -0700
  5. Date: Tue, 9 Oct 90 08:37:20 MST
  6. From: "Ralph Griswold" <ralph>
  7. Message-Id: <9010091537.AA11439@cheltenham.cs.arizona.edu>
  8. Received: by cheltenham.cs.arizona.edu; Tue, 9 Oct 90 08:37:20 MST
  9. To: icon-group
  10. Subject: large messages
  11.  
  12. Please remember that large e-mail messages cause some gateways, especially
  13. PCs, to crash.  If you're sending something over 20K or so characters,
  14. please break it up into separate messages.  If it's something like a 
  15. program, take care to identify the parts clearly.
  16.  
  17.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  18.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  19.  
  20. From tenaglia@mis.mcw.edu  Tue Oct  9 14:34:25 1990
  21. Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  22.     id AA03729; Tue, 9 Oct 90 14:34:25 -0700
  23. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  24.     id AA21071; Tue, 9 Oct 90 17:18:44 EDT
  25. Received: by uwm.edu; id AA12064; Tue, 9 Oct 90 15:49:36 -0500
  26. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  27.           Tue,  9 Oct 90 15:16:51 CDT
  28. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  29.           Tue,  9 Oct 90 15:15:31 CDT
  30. Date: Tue,  9 Oct 90 15:15:31 CDT
  31. Message-Id: <0093DF0203306BA0.2040083E@mis.mcw.edu>
  32. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  33. Subject: Time and Date Routines
  34. To: icon-group@cs.arizona.edu
  35.  
  36.  
  37. Perhaps I didn't look close enough at the IPL, but I am interested in time
  38. and date manipulation routines. One the outside it sounds simple. Here're
  39. the specs.
  40.  
  41. procedure dow(d)     : Day of week. Should return either 1 through 7 or
  42.                        Sunday through Saturday.
  43.  
  44. procedure difdate(d1,d2,uom) : Subtracts date d1 from date d2. uom is the
  45.                                unit of measure for the result as seconds,
  46.                                minutes, hours, days, weeks, months, years.
  47.  
  48. procedure future(d1,d2,uom)  : Adds duration d2 to date d1, yielding answer.
  49.                                duration in unit of measure uom, being either
  50.                                seconds, minutes, hours, days, weeks, months,
  51.                                years.
  52.  
  53. Date formats => YYYY-MMM-DD:HH:MM:SS
  54.                 Month Day, Year HH:MM:SS
  55.  
  56. The routines should be smart enough to handle leap years, and be able to make
  57. due with partial specs. 1990-oct-04 would default with 00:00:00. oct-04 would
  58. also assume the current year. Examples...
  59.  
  60.           difdate("oct-04","oct-16","day")   returns 12
  61.           future("oct-02",6,"month")         returns "1991-apr-02:00:00:00"
  62.           dow("oct-9")                       returns 3 or Tuesday
  63.  
  64. I think these might make a good addition to the IPL. Perhaps others have better
  65. ideas. Is date manipulation of interest to anyone else? I haven't developed the
  66. bodies of the procedures yet, but wonder if someone else has already?
  67.  
  68. Chris Tenaglia (System Manager)
  69. Medical College of Wisconsin
  70. 8701 W. Watertown Plank Rd.
  71. Milwaukee, WI 53226
  72. (414)257-8765
  73. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  74.  
  75.  
  76. From goer%sophist@gargoyle.uchicago.edu  Tue Oct  9 21:41:04 1990
  77. Resent-From: goer%sophist@gargoyle.uchicago.edu
  78. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  79.     id AA26047; Tue, 9 Oct 90 21:41:04 -0700
  80. Return-Path: goer@sophist.uchicago.edu
  81. Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 9 Oct 90 21:40 MST
  82. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  83.  AA15188; Tue, 9 Oct 90 23:40:27 199
  84. Received: by sophist (4.1/UofC3.1X) id AA21196; Tue, 9 Oct 90 23:44:23 CDT
  85. Resent-Date: Tue, 9 Oct 90 21:40 MST
  86. Date: Tue, 9 Oct 90 23:44:23 CDT
  87. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  88. Subject: parsing natural languages
  89. Resent-To: icon-group@cs.arizona.edu
  90. To: icon-group@arizona.edu
  91. Resent-Message-Id: <20C82A039A47201ECF@Arizona.edu>
  92. Message-Id: <9010100444.AA21196@sophist>
  93. X-Envelope-To: icon-group@CS.Arizona.EDU
  94. X-Vms-To: icon-group@Arizona.EDU
  95.  
  96. I'm just curious what sort of work is being done in natural languages
  97. using Icon.  Naturally, I know of my own work in phonology and phonologi-
  98. cal databases.  I wonder, though, whether anyone out there has done very
  99. much with the syntax of natural languages.  A while back, I was working
  100. on several different approaches to bottom-up parsing in Icon, but got a
  101. bit sidetracked.  I also tried implementing DFSA's in Icon, but found
  102. it difficult to get them to run quickly, with reasonable memory require-
  103. ments.  Anyway, you can't parse natural languages with a DFSA.  I'd ap-
  104. preciate it very much if anyone who has worked in such areas - in Icon -
  105. would drop me a line (or post a followup).
  106.  
  107. -Richard
  108.  
  109. From goer%sophist@gargoyle.uchicago.edu  Tue Oct  9 22:27:56 1990
  110. Resent-From: goer%sophist@gargoyle.uchicago.edu
  111. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  112.     id AA27111; Tue, 9 Oct 90 22:27:56 -0700
  113. Return-Path: goer@sophist.uchicago.edu
  114. Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 9 Oct 90 22:27 MST
  115. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  116.  AA15801; Wed, 10 Oct 90 00:27:19 199
  117. Received: by sophist (4.1/UofC3.1X) id AA21302; Wed, 10 Oct 90 00:31:14 CDT
  118. Resent-Date: Tue, 9 Oct 90 22:27 MST
  119. Date: Wed, 10 Oct 90 00:31:14 CDT
  120. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  121. Subject: coaxing makes to handle Icon programs
  122. Resent-To: icon-group@cs.arizona.edu
  123. To: icon-group@arizona.edu
  124. Resent-Message-Id: <20C19B5B464720263C@Arizona.edu>
  125. Message-Id: <9010100531.AA21302@sophist>
  126. X-Envelope-To: icon-group@CS.Arizona.EDU
  127. X-Vms-To: icon-group@Arizona.EDU
  128.  
  129. I often find that I can't coax make programs to handle Icon programs.
  130. Since I send out a lot of code over this newsgroup, I have a vested
  131. interest in making sure my makefiles work.  Below is a shar archive
  132. of a test program.  If anyone is feeling adventurous, I'd appreciate
  133. it very much if they would direct their adventursomeness in the fol-
  134. lowing way:  Un-shar the following archive, then make.  Write me if
  135. it doesn't work.  Write me if it does work.  Tell me your OS, and your
  136. make program.
  137.  
  138. Note that the following shar archive can be "made" using gnu make.
  139. I can't get it to work on my Xenix (SysVR3-based) system using the
  140. stock make program.  Nor can I get it to work using the stock Sun
  141. make here on sophist.  It "should" work, though.  The fact that it
  142. doesn't explains the ponderousness of the makefiles I distribute
  143. with my programs.
  144.  
  145. -Richard
  146.  
  147. ---- Cut Here and feed the following to sh ----
  148. #!/bin/sh
  149. # This is a shell archive (produced by shar 3.49)
  150. # To extract the files from this archive, save it to a file, remove
  151. # everything above the "!/bin/sh" line above, and type "sh file_name".
  152. #
  153. if test -r _shar_seq_.tmp; then
  154.     echo 'Must unpack archives in sequence!'
  155.     echo Please unpack part `cat _shar_seq_.tmp` next
  156.     exit 1
  157. fi
  158. # ============= Makefile ==============
  159. if test -f 'Makefile' -a X"$1" != X"-c"; then
  160.     echo 'x - skipping Makefile (File already exists)'
  161.     rm -f _shar_wnt_.tmp
  162. else
  163. > _shar_wnt_.tmp
  164. echo 'x - extracting Makefile (Text)'
  165. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  166. X.SUFFIXES: .u2 .icn .icn~
  167. X
  168. X.icn.u2:
  169. X    icont -c $*.icn
  170. X.u2:
  171. X    icont -o $* $*.u1 $*.u2
  172. X    @/bin/rm $*.u?
  173. X
  174. Xall: tmp
  175. SHAR_EOF
  176. true || echo 'restore of Makefile failed'
  177. rm -f _shar_wnt_.tmp
  178. fi
  179. # ============= s.tmp.icn ==============
  180. if test -f 's.tmp.icn' -a X"$1" != X"-c"; then
  181.     echo 'x - skipping s.tmp.icn (File already exists)'
  182.     rm -f _shar_wnt_.tmp
  183. else
  184. > _shar_wnt_.tmp
  185. echo 'x - extracting s.tmp.icn (Text)'
  186. sed 's/^X//' << 'SHAR_EOF' > 's.tmp.icn' &&
  187. Xh11144
  188. Xs 00003/00000/00000
  189. Xd D 1.1 90/10/10 00:09:09 richard 1 0
  190. Xc date and time created 90/10/10 00:09:09 by richard
  191. Xe
  192. Xu
  193. XU
  194. Xt
  195. XT
  196. XI 1
  197. Xprocedure main()
  198. Xwrite("hello")
  199. Xend
  200. XE 1
  201. SHAR_EOF
  202. true || echo 'restore of s.tmp.icn failed'
  203. rm -f _shar_wnt_.tmp
  204. fi
  205. exit 0
  206.  
  207. From nickerso@SPUNKY.CS.NYU.EDU  Wed Oct 10 16:41:20 1990
  208. Received: from SPUNKY.CS.NYU.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  209.     id AA22368; Wed, 10 Oct 90 16:41:20 -0700
  210. Received: by SPUNKY.CS.NYU.EDU (5.61/1.34)
  211.     id AA12133; Wed, 10 Oct 90 19:41:37 -0400
  212. Date: Wed, 10 Oct 90 19:41:37 -0400
  213. From: nickerso@SPUNKY.CS.NYU.EDU (Jeff Nickerson)
  214. Message-Id: <9010102341.AA12133@SPUNKY.CS.NYU.EDU>
  215. To: icon-group@cs.arizona.edu
  216. Subject: desubscribe
  217.  
  218. Please desubscribe me from your electronic mailing list.
  219.  
  220. From icon-group-request@arizona.edu  Fri Oct 12 07:11:29 1990
  221. Resent-From: icon-group-request@arizona.edu
  222. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  223.     id AA29291; Fri, 12 Oct 90 07:11:29 -0700
  224. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 12 Oct 90 07:10 MST
  225. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA23854; Fri, 12 Oct 90
  226.  06:59:01 -0700
  227. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  228.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  229.  usenet@ucbvax.Berkeley.EDU if you have questions)
  230. Resent-Date: Fri, 12 Oct 90 07:11 MST
  231. Date: 10 Oct 90 20:57:37 GMT
  232. From: eru!hagbard!sunic!mcsun!ukc!warwick!nott-cs!christopher-robin.cs.bham.ac.uk!lxg@bloom-beacon.mit.edu
  233. Subject: An introduction to Icon?
  234. Sender: icon-group-request@arizona.edu
  235. Resent-To: icon-group@cs.arizona.edu
  236. To: icon-group@arizona.edu
  237. Resent-Message-Id: <1EE6281A5AE7203E3F@Arizona.edu>
  238. Message-Id: <1004@christopher-robin.cs.bham.ac.uk>
  239. Organization: Birmingham University, England
  240. X-Envelope-To: icon-group@CS.Arizona.EDU
  241. X-Vms-To: icon-group@Arizona.EDU
  242.  
  243.  
  244.  
  245.  I have just picked up version 8 of Icon and would like to
  246.  explore it further. Does anyone know if there is a tutorial
  247.  on it floating around and accessible by ftp? 
  248.  
  249.     
  250.     Cheers
  251.     
  252.         Griff, University of Birmingham.
  253.  
  254. -------------------------------------------------------------
  255. -------------------------------------------------------------
  256.  
  257. From icon-group-request@arizona.edu  Thu Oct 18 17:14:05 1990
  258. Resent-From: icon-group-request@arizona.edu
  259. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  260.     id AA16109; Thu, 18 Oct 90 17:14:05 -0700
  261. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 18 Oct 90 17:13 MST
  262. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA22642; Thu, 18 Oct 90
  263.  17:04:45 -0700
  264. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  265.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  266.  usenet@ucbvax.Berkeley.EDU if you have questions)
  267. Resent-Date: Thu, 18 Oct 90 17:13 MST
  268. Date: 17 Oct 90 23:35:34 GMT
  269. From: bsu-cs!bsu-ucs!earlham!johnb@iuvax.cs.indiana.edu
  270. Subject: Icon and Oracle.  A great mix
  271. Sender: icon-group-request@arizona.edu
  272. Resent-To: icon-group@cs.arizona.edu
  273. To: icon-group@arizona.edu
  274. Resent-Message-Id: <19DAF65F7A0B206CB7@Arizona.edu>
  275. Message-Id: <3145@yang.earlham.edu>
  276. Organization: Earlham College, Richmond, Indiana
  277. X-Envelope-To: icon-group@CS.Arizona.EDU
  278. X-Vms-To: icon-group@Arizona.EDU
  279.  
  280. For anyone who is interested.....
  281.  
  282.     At Earlham College (Heard of it?) we undertook a project of 
  283. intergrating Icon with the Oralce Relational Database.  We are finished 
  284. now, and the project seems to have alot of potential.  
  285.     Our interface is a new built in function called 'oracle' which 
  286. accepts any SQL statement (Not SQL*PLUS).  The information is returned 
  287. through the list data type.  All DMLs, DDL, and queries supported as well 
  288. as a new built in &OracleError code.
  289.     We chose Icon because it is such a strong language for use with 
  290. strings and text.  Our intergration, called OraConIt allows for 
  291. sophisticated manipulation of the information returned.  It could be used 
  292. as a SQL front end, or as a report writer, or for DBAs be able to 
  293. intergote the Data Dictionary and be able to process the data in a 
  294. high-level laguage.  Samples of code written in PRO*C and OraCon are very 
  295. interesting to compare.  (Of course OraCon takes less code.)
  296.     We have developed only a VAX/VMS version, but conversion to any 
  297. other platform should be painless.  One needs the Oracle C run time 
  298. library and the source code for that version of Icon.
  299.  
  300. If you are interested by this little bit of info, (there is alot more) 
  301. drop me a 'line' here.  I would love to get some feedback on it.
  302.  
  303.             Thank you,
  304.                 The OraCon Group
  305.                         John Benjamin
  306.                         Johnb@yang.Earlham.Edu
  307.  
  308. From kwalker  Thu Oct 18 17:35:57 1990
  309. Received: from gacham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  310.     id AA16751; Thu, 18 Oct 90 17:35:57 -0700
  311. Date: Thu, 18 Oct 90 17:35:55 MST
  312. From: "Kenneth Walker" <kwalker>
  313. Message-Id: <9010190035.AA02399@gacham.cs.arizona.edu>
  314. Received: by gacham.cs.arizona.edu; Thu, 18 Oct 90 17:35:55 MST
  315. To: icon-group
  316. Subject: Re:  Icon and Oracle.  A great mix
  317.  
  318.     Date: 17 Oct 90 23:35:34 GMT
  319.     From: bsu-cs!bsu-ucs!earlham!johnb@iuvax.cs.indiana.edu
  320.  
  321.     At Earlham College (Heard of it?) we undertook a project of 
  322.     intergrating Icon with the Oralce Relational Database.  We are finished 
  323.     now, and the project seems to have alot of potential.  
  324.  
  325.         Our interface is a new built in function called 'oracle' which 
  326.     accepts any SQL statement (Not SQL*PLUS).  The information is returned 
  327.     through the list data type. 
  328.  
  329. Neat!
  330.  
  331. I was wondering if there is information that would be reasonable to
  332. "generate" rather than return in a list (I don't know much about Oracle
  333. or SQL, or data bases in general). Generating results is a more "Iconish"
  334. approach to returning multiple homogenous results than using a data
  335. structure. The programmer can then put them in a list if desired.
  336.  
  337.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  338.   +1 602 621-4252  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  339.  
  340.  
  341. From nowlin@iwtqg.att.com  Fri Oct 19 05:17:25 1990
  342. Resent-From: nowlin@iwtqg.att.com
  343. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  344.     id AA11455; Fri, 19 Oct 90 05:17:25 -0700
  345. Received: from att.att.com by Arizona.edu; Fri, 19 Oct 90 05:16 MST
  346. Resent-Date: Fri, 19 Oct 90 05:17 MST
  347. Date: Fri, 19 Oct 90 06:51 CDT
  348. From: nowlin@iwtqg.att.com
  349. Subject: RE: Icon and Oracle (SQL)
  350. Resent-To: icon-group@cs.arizona.edu
  351. To: att!arizona.edu!icon-group@cs.arizona.edu
  352. Resent-Message-Id: <1975EF2F382B2077AF@Arizona.edu>
  353. Message-Id: <1975F7C2F5958016D3@Arizona.edu>
  354. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  355. X-Envelope-To: icon-group@CS.Arizona.EDU
  356. X-Vms-To: att!arizona.edu!icon-group@cs.Arizona.edu
  357.  
  358. We've prototyped an interface to Informix that contains a single function
  359. called sql().  This function is a generator that's passed an SQL
  360. statement.  It either fails or generates results.
  361.  
  362. If the SQL statement passed is a "select" statement the sql() procedure
  363. generates a series of Icon tables that correspond to the records selected.
  364. The keys to the tables are the field names selected and the values are the
  365. corresponding values from the database.
  366.  
  367. If the SQL statement passed isn't a "select" statement the result generated
  368. is the integer number of records in the database affected by the SQL
  369. statement.  For example, a "delete" statement with a where clause that
  370. deleted 12 records from a database table would generate the single integer
  371. 12 before failing.
  372.  
  373. Right now this Informix interface is implemented as an Icon procedure that
  374. calls a C program written with ESQL.  We plan to eventually implement it as
  375. a built-in function using a pi.
  376.  
  377. It would certainly be possible to use Oracle or most any database that
  378. supports SQL the same way.  There's a definite advantage to being able to
  379. manipulate the results of a database query with Icon instead of C.
  380.  
  381. Jerry Nowlin
  382. (...!att!iwtqg!nowlin)
  383.  
  384. From @mirsa.inria.fr:ol@cerisi.cerisi.Fr  Fri Oct 19 13:47:52 1990
  385. Resent-From: @mirsa.inria.fr:ol@cerisi.cerisi.Fr
  386. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  387.     id AA06197; Fri, 19 Oct 90 13:47:52 -0700
  388. Received: from mirsa.inria.fr by Arizona.edu; Fri, 19 Oct 90 13:47 MST
  389. Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP (5.61+++/IDA-1.2.8)
  390.  id AA11424; Fri, 19 Oct 90 21:48:49 +0100
  391. Resent-Date: Fri, 19 Oct 90 13:47 MST
  392. Date: Fri, 19 Oct 90 21:45:28 -0100
  393. From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
  394. Subject: Icon and X-windows
  395. Resent-To: icon-group@cs.arizona.edu
  396. To: icon-group@arizona.edu
  397. Resent-Message-Id: <192E9AD0116B207EB8@Arizona.edu>
  398. Message-Id: <9010192048.AA11424@mirsa.inria.fr>
  399. Posted-Date: Fri, 19 Oct 90 21:45:28 -0100
  400. X-Envelope-To: icon-group@CS.Arizona.EDU
  401. X-Vms-To: icon-group@Arizona.EDU
  402.  
  403. I have the project of using the variant translator capability of Icon,
  404. as well as the personalized interpreter, in order to define an extension
  405. to Icon interfaced with X-windows. The idea would be to have a very
  406. powerful and flexible language for prototyping interactive graphic
  407. environments. 
  408.  
  409. Has anybody already attempted something similar? Has anybody any
  410. interesting idea about this matter?
  411.  
  412.  
  413.                 Olivier Lecarme
  414.  
  415. From cjeffery  Fri Oct 19 14:51:13 1990
  416. Resent-From: "Clinton Jeffery" <cjeffery>
  417. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  418.     id AA09356; Fri, 19 Oct 90 14:51:13 -0700
  419. Received: from megaron.cs.Arizona.EDU by Arizona.edu; Fri, 19 Oct 90 14:50 MST
  420. Received: from caslon.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via
  421.  SMTP id AA09319; Fri, 19 Oct 90 14:50:33 -0700
  422. Received: by caslon.cs.arizona.edu; Fri, 19 Oct 90 14:50:30 -0700
  423. Resent-Date: Fri, 19 Oct 90 14:50 MST
  424. Date: Fri, 19 Oct 90 14:50:30 -0700
  425. From: Clinton Jeffery <cjeffery@cs.arizona.edu>
  426. Subject: Icon and X-windows
  427. Resent-To: icon-group@cs.arizona.edu
  428. To: ol@cerisi.cerisi.Fr
  429. Cc: icon-group@arizona.edu
  430. Resent-Message-Id: <1925C158F62B2075CA@Arizona.edu>
  431. Message-Id: <9010192150.AA06946@caslon.cs.arizona.edu>
  432. In-Reply-To: Lecarme Olivier's message of Fri, 19 Oct 90 21:45:28 -0100
  433.  <9010192048.AA11424@mirsa.inria.fr>
  434. X-Envelope-To: icon-group@CS.Arizona.EDU
  435. X-Vms-To: ol@cerisi.cerisi.Fr
  436. X-Vms-Cc: icon-group@Arizona.EDU
  437.  
  438. We are using an Icon X Windows interface internally here in our
  439. program visualization research.  There is a 15 page reference
  440. document describing it, Icon Project Document 150.  The interface
  441. is built on top of Xlib.  There is no public distribution that
  442. includes the X Windows interface at this time.
  443.  
  444. Interested persons may obtain more information from me by electronic
  445. mail.  I would also enjoy hearing from persons who are working on
  446. Icon interfaces to other window systems.
  447.  
  448. Clint Jeffery, U. of Arizona Dept. of Computer Science
  449. cjeffery@cs.arizona.edu -or- {noao allegra}!arizona!cjeffery
  450.  
  451. From goer@midway.uchicago.edu  Sat Oct 20 23:52:57 1990
  452. Resent-From: goer@midway.uchicago.edu
  453. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  454.     id AA03592; Sat, 20 Oct 90 23:52:57 -0700
  455. Received: from midway.uchicago.edu by Arizona.edu; Sat, 20 Oct 90 23:52 MST
  456. Received: from quads.uchicago.edu  (quads.uchicago.edu) by midway.uchicago.edu
  457.  Sun, 21 Oct 90 01:52:24 CDT
  458. Resent-Date: Sat, 20 Oct 90 23:52 MST
  459. Date: Sun, 21 Oct 90 01:52:24 CDT
  460. From: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
  461. Subject: test posting of dir lister
  462. Resent-To: icon-group@cs.arizona.edu
  463. To: icon-group@arizona.edu
  464. Resent-Message-Id: <1810E919AC6B20793F@Arizona.edu>
  465. Message-Id: <9010210652.AA08963@midway.uchicago.edu>
  466. X-Envelope-To: icon-group@CS.Arizona.EDU
  467. X-Vms-To: icon-group@Arizona.EDU
  468.  
  469. It's hard to get directory listings from within Icon.  Here are
  470. some routines that do this in a generic way.  The idea of doing
  471. things generically is to avoid OS-specificity, at least on the
  472. level on which these routines are called (not, in other words,
  473. in the actual mechanics of how to get the listing, which are very
  474. OS-specific).
  475.  
  476. Anyway, I hope someone finds these routines useful.
  477.  
  478. -Richard
  479.  
  480. ############################################################################
  481. #
  482. #    Name:     gdl.icn
  483. #
  484. #    Title:    Get directory list 
  485. #
  486. #    Author:    Richard L. Goerwitz
  487. #
  488. #    Version: 1.2
  489. #
  490. ############################################################################
  491. #
  492. #  Gdl returns a list containing everything in a directory (whose name
  493. #  must be passed as an argument to gdl).  Nothing fancy.  I use this file
  494. #  as a template, modifying the procedures according to the needs of the
  495. #  program in which they are used.
  496. #
  497. ############################################################################
  498. #
  499. #  Requires:  UNIX or MS-DOS
  500. #
  501. ############################################################################
  502.  
  503.  
  504. procedure gdl(dir)
  505.  
  506.     getdir := set_getdir_by_os()
  507.     return getdir(dir)
  508.  
  509. end
  510.  
  511.  
  512.  
  513. procedure set_getdir_by_os()
  514.  
  515.     # Decide how to get a directory, based on whether we are running
  516.     # under Unix or MS-DOS.
  517.  
  518.     if find("UNIX", &features)
  519.     then return unix_get_dir
  520.     else if find("MS-DOS", &features)
  521.     then return msdos_get_dir
  522.     else stop("Your operating system is not (yet) supported.")
  523.  
  524. end
  525.  
  526.  
  527.  
  528. procedure msdos_get_dir(dir)
  529.  
  530.     # Returns a sorted list of all filenames (full paths included) in
  531.     # directory "dir."  The list is sorted.  Fails on invalid or empty
  532.     # directory.  Aborts if temp file cannot be opened.
  533.     #
  534.     # Temp files can be directed to one or another directory either by
  535.     # manually setting the variable temp_dir below, or by setting the
  536.     # value of the environment variable TEMPDIR to an appropriate
  537.     # directory name.
  538.  
  539.     local in_dir, filename_list, line
  540.     static temp_dir
  541.     initial {
  542.         temp_dir := 
  543.             (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
  544.                 ".\\"
  545.     }
  546.  
  547.     # Get name of tempfile to be used.
  548.     temp_name := get_dos_tempname(temp_dir) |
  549.     stop("No more available tempfile names!")
  550.  
  551.     # Make sure we have an unambiguous directory name, with backslashes
  552.     # instead of Unix-like forward slashes.
  553.     dir := trim(map(dir, "/", "\\"), '\\') || "\\"
  554.  
  555.     # Put dir listing into a temp file.
  556.     system("dir "||dir||" > "||temp_name)
  557.  
  558.     # Put tempfile entries into a list, removing blank- and
  559.     # space-initial lines.  Exclude directories (i.e. return file
  560.     # names only).
  561.     in_dir := open(temp_name,"r") |
  562.     stop("Can't open temp file in directory ",temp_dir,".")
  563.     filename_list := list()
  564.     every filename := ("" ~== !in_dir) do {
  565.         match(" ",filename) | find(" <DIR>", filename) & next
  566.     # Exclude our own tempfiles (may not always be appropriate).
  567.     filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
  568.     put(filename_list, map(dir || filename))
  569.     }
  570.  
  571.     # Clean up.
  572.     close(in_dir) & remove(temp_name)
  573.  
  574.     # Check to be sure we actually managed to read some files.
  575.     if *filename_list = 0 then fail
  576.     else return sort(filename_list)
  577.  
  578. end
  579.  
  580.  
  581.  
  582. procedure get_dos_tempname(dir)
  583.  
  584.     # Don't clobber existing files.  Get a unique temp file name for
  585.     # use as a temporary storage site.
  586.  
  587.     every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
  588.     temp_file := open(temp_name,"r") | break
  589.         close(temp_file)
  590.     }
  591.     return \temp_name
  592.  
  593. end
  594.  
  595.  
  596.  
  597. procedure unix_get_dir(dir)
  598.  
  599.     dir := trim(dir, '/') || "/"
  600.     filename_list := list()
  601.     in_dir := open("/bin/ls -F "||dir, "pr")
  602.     every filename := ("" ~== !in_dir) do {
  603.     match("/",filename,*filename) & next
  604.     put(filename_list, trim(dir || filename, '*'))
  605.     }
  606.     close(in_dir)
  607.  
  608.     if *filename_list = 0 then fail
  609.     else return filename_list
  610.  
  611. end
  612.  
  613. From ralph  Tue Oct 23 05:38:12 1990
  614. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  615.     id AA26192; Tue, 23 Oct 90 05:38:12 -0700
  616. Date: Tue, 23 Oct 90 05:38:08 MST
  617. From: "Ralph Griswold" <ralph>
  618. Message-Id: <9010231238.AA23237@cheltenham.cs.arizona.edu>
  619. Received: by cheltenham.cs.arizona.edu; Tue, 23 Oct 90 05:38:08 MST
  620. To: icon-group
  621. Subject: Message forwarded by request
  622.  
  623.  
  624. For anyone who is interested.....
  625.  
  626.     At Earlham College (Heard of it?) we undertook a project of 
  627. intergrating Icon with the Oralce Relational Database.  We are finished 
  628. now, and the project seems to have alot of potential.  
  629.     Our interface is a new built in function called 'oracle' which 
  630. accepts any SQL statement (Not SQL*PLUS).  The information is returned 
  631. through the list data type.  All DMLs, DDL, and queries supported as well 
  632. as a new built in &OracleError code.
  633.     We chose Icon because it is such a strong language for use with 
  634. strings and text.  Our intergration, called OraConIt allows for 
  635. sophisticated manipulation of the information returned.  It could be used 
  636. as a SQL front end, or as a report writer, or for DBAs be able to 
  637. intergote the Data Dictionary and be able to process the data in a 
  638. high-level laguage.  Samples of code written in PRO*C and OraCon are very 
  639. interesting to compare.  (Of course OraCon takes less code.)
  640.     We have developed only a VAX/VMS version, but conversion to any 
  641. other platform should be painless.  One needs the Oracle C run time 
  642. library and the source code for that version of Icon.
  643.  
  644. If you are interested by this little bit of info, (there is alot more) 
  645. drop me a 'line' here.  I would love to get some feedback on it.
  646.  
  647.             Thank you,
  648.                 The OraCon Group
  649.                         John Benjamin
  650.                         Johnb@yang.Earlham.Edu
  651.  
  652.  
  653.  
  654. From goer%sophist@gargoyle.uchicago.edu  Tue Oct 23 18:56:58 1990
  655. Resent-From: goer%sophist@gargoyle.uchicago.edu
  656. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  657.     id AA03478; Tue, 23 Oct 90 18:56:58 -0700
  658. Return-Path: goer@sophist.uchicago.edu
  659. Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 23 Oct 90 18:56 MST
  660. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  661.  AA16775; Tue, 23 Oct 90 20:56:22 199
  662. Received: by sophist (4.1/UofC3.1X) id AA07035; Tue, 23 Oct 90 21:00:05 CDT
  663. Resent-Date: Tue, 23 Oct 90 18:56 MST
  664. Date: Tue, 23 Oct 90 21:00:05 CDT
  665. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  666. Subject: BCD
  667. Resent-To: icon-group@cs.arizona.edu
  668. To: icon-group@arizona.edu
  669. Resent-Message-Id: <15DEC3453B0B209EA7@Arizona.edu>
  670. Message-Id: <9010240200.AA07035@sophist>
  671. X-Envelope-To: icon-group@CS.Arizona.EDU
  672. X-Vms-To: icon-group@Arizona.EDU
  673.  
  674. I recall someone posting some nice little routines that turned
  675. integers into binary coded decimal strings.  I remember looking
  676. at them and thinking they looked useful.
  677.  
  678. I wonder if these are still around somewhere.
  679.  
  680. -Richard (goer@sophist.uchicago.edu)
  681.  
  682. From tenaglia@mis.mcw.edu  Wed Oct 24 11:35:43 1990
  683. Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  684.     id AA08895; Wed, 24 Oct 90 11:35:43 -0700
  685. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  686.     id AA24606; Wed, 24 Oct 90 14:21:50 EDT
  687. Received: by uwm.edu; id AA22598; Wed, 24 Oct 90 13:02:18 -0500
  688. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  689.           Wed, 24 Oct 90 11:59:16 CDT
  690. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  691.           Wed, 24 Oct 90 08:15:25 CDT
  692. Date: Wed, 24 Oct 90 08:15:25 CDT
  693. Message-Id: <0093EA90CFB67D60.20400660@mis.mcw.edu>
  694. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  695. Subject: Packed Decimal Procedures
  696. To: icon-group@cs.arizona.edu
  697.  
  698.  
  699. Here are the procedures pack() and unpack(). They are part of my
  700. personal IPL. Most of my icon programs have so much in common that
  701. this 10 module library I use as a program starter. I 'include' the
  702. file into the editor, chop out from 2 to 7 modules, and begin coding 
  703.  
  704.   while line := read(in) do
  705.     {
  706. HERE
  707.     }
  708.  
  709. which is pretty good in regards to 'reusable modules' or 'software chips',
  710. the chief goal of ADA and OOPS. I wonder if anyone else has developed
  711. their own 'software chips' or 'program starter'?
  712.  
  713. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  714. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  715. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  716.  
  717. ##################################################################
  718. #                                                                #
  719. # THIS PROCEDURE PACKS AN INTEGER IN TO PACKED DECIMAL STRING.   #
  720. #                                                                #
  721. ##################################################################
  722. procedure pack(num,width)     
  723.   local int,sign,prep,packed,i,word
  724.   (int := integer(num)) | fail                
  725.   if int < 0 then sign := "=" else sign := "<"
  726.   prep   := int || sign
  727.   packed := ""
  728.   if (*prep % 2) ~= 0 then prep := "0" || prep
  729.   every i := 1 to *prep by 2 do
  730.     {
  731.     word := prep[i+:2]
  732.     if word[-1] == ("=" | "<") then
  733.       {
  734.       packed ||:= char(word[1]*16 + ord(word[2])-48)
  735.       next
  736.       }
  737.     packed ||:= char(word[1]*16 + word[2])
  738.     }
  739.   /width := *packed
  740.   return right(packed,width,"\0")
  741.   end                                   
  742.  
  743. ##################################################################
  744. #                                                                #
  745. # THIS PROCEDURE UNPACKS A VALUE INTO AN INTEGER. USING THIS     #
  746. # CODE SEGMENT REQUIRES LINKING WITH RADCON FROM THE IPL.        #
  747. #                                                                #
  748. ##################################################################
  749. procedure unpack(val,width)   
  750.   local tmp,number,tens,ones,sign
  751.   tmp  := ""
  752.   sign := 1
  753.   every number := ord(!val) do
  754.     tmp ||:= right(map(radcon(number,10,16),&lcase,&ucase),2,"0")
  755.   if tmp[-1] == ("B" | "D") then sign := -1
  756.   tmp[-1] := ""
  757.   tmp    *:= sign
  758.   /width  := *tmp
  759.   return right(tmp,width)
  760.   end
  761.  
  762.  
  763.  
  764. From sboisen@BBN.COM  Wed Oct 24 13:06:05 1990
  765. Message-Id: <9010242006.AA03609@megaron.cs.arizona.edu>
  766. Received: from SLANG.BBN.COM by megaron.cs.arizona.edu (5.61/15) via SMTP
  767.     id AA03609; Wed, 24 Oct 90 13:06:05 -0700
  768. To: tenaglia@mis.mcw.edu
  769. Cc: icon-group@cs.arizona.edu
  770. In-Reply-To: Chris Tenaglia - 257-8765's message of Wed, 24 Oct 90 08:15:25 CDT <0093EA90CFB67D60.20400660@mis.mcw.edu>
  771. Subject: Packed Decimal Procedures
  772. From: Sean Boisen <sboisen@BBN.COM>
  773. Sender: sboisen@BBN.COM
  774. Reply-To: sboisen@BBN.COM
  775. Date: Wed, 24 Oct 90 16:02:47 EDT
  776.  
  777. > I wonder if anyone else has developed
  778. > their own 'software chips' or 'program starter'?
  779. > Chris Tenaglia (System Manager) | Medical College of Wisconsin
  780. > 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  781. > (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  782.  
  783. Since most of the Icon code i write is for small Unix-like utilities,
  784. i frequently care about setting up handling for command line
  785. arguments. My basic template therefore looks like this (i believe i
  786. got this from one of the newsletters):
  787.  
  788. ----------------------------------------------------------------------
  789.  
  790. procedure main(cmdline)
  791.     local switch
  792.     while switch := get(cmdline) do
  793.     {
  794.     case switch of
  795.     {
  796.         "-t":   tswitch := 1
  797.         "-l":   limit := integer(get(cmdline)) | Usage()
  798.         default: Usage()
  799.     }
  800.     }
  801. end
  802.  
  803. #  stop, informing of incorrect usage
  804. #
  805. procedure Usage()
  806.     stop("usage for :  [-t] [-l n]")
  807. end
  808. ----------------------------------------------------------------------
  809.  
  810. This gives me two examples of command line switches, one with and one
  811. without args, and an helpful message if i get the args wrong.
  812. Typically the first thing i do is edit the args and usage message, and
  813. then start working on the guts of the thing.
  814.  
  815. ........................................
  816. Sean Boisen -- sboisen@bbn.com
  817. BBN Systems and Technologies, Cambridge MA
  818.  
  819. From icon-group-request@arizona.edu  Thu Oct 25 11:49:31 1990
  820. Resent-From: icon-group-request@arizona.edu
  821. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  822.     id AA17695; Thu, 25 Oct 90 11:49:31 -0700
  823. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 25 Oct 90 11:48 MST
  824. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09800; Thu, 25 Oct 90
  825.  11:37:45 -0700
  826. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  827.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  828.  usenet@ucbvax.Berkeley.EDU if you have questions)
  829. Resent-Date: Thu, 25 Oct 90 11:48 MST
  830. Date: 25 Oct 90 01:32:31 GMT
  831. From: att!linac!midway!quads.uchicago.edu!goer@ucbvax.Berkeley.EDU
  832. Subject: RE: Packed Decimal Procedures
  833. Sender: icon-group-request@arizona.edu
  834. Resent-To: icon-group@cs.arizona.edu
  835. To: icon-group@arizona.edu
  836. Resent-Message-Id: <14882FAEA41520A50F@Arizona.edu>
  837. Message-Id: <1990Oct25.013231.21009@midway.uchicago.edu>
  838. Organization: University of Chicago
  839. X-Envelope-To: icon-group@CS.Arizona.EDU
  840. X-Vms-To: icon-group@Arizona.EDU
  841. References: <0093EA90CFB67D60.20400660@mis.mcw.edu>
  842.  
  843. Tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
  844. >
  845. >Here are the procedures pack() and unpack(). They are part of my
  846. >personal IPL.
  847.  
  848. I couldn't resist toying with the (un)pack routines just posted.
  849. There's no reason I can see for storing the sign if the int is
  850. positive, so I cut that part out.  I also added another unpack
  851. routine, which runs a bit faster, and behaves somewhat differently
  852. than the one Chris wrote.
  853.  
  854. Oh, I should perhaps add that the thing has been redone in IPL
  855. format, and I've eliminated most automatic type conversions.
  856. They automatic type conversion thing is just a pet peeve of mine.
  857. I hope no one holds it against me :-).
  858.  
  859. -Richard
  860.  
  861.  
  862. ############################################################################
  863. #
  864. #    Name:     packunpk.icn
  865. #
  866. #    Title:     Pack and unpack packed-decimal strings
  867. #
  868. #    Author:     Chris Tenaglia (modified by Richard L. Goerwitz)
  869. #
  870. #    Version: 1.1
  871. #
  872. ############################################################################
  873. #
  874. #      Integers written directly as strings occupy much more space
  875. #  than they need to.  One easy way to shrink them a bit is to "pack"
  876. #  them, i.e.  convert each decimal digit into a four-byte binary
  877. #  code, and pack these four-bit chunks into eight-bit characters,
  878. #  which can be written to a file.
  879. #
  880. #      Interestingly, packing decimal strings in this manner lends
  881. #  itself to unpacking by treating each character as a base-10
  882. #  integer, and then converting it to base-16.  Say we have an input
  883. #  string "99."  Pack() would convert it to an internal representation
  884. #  of char(16*9 + 9), i.e. char(153).  Unpack would treat this
  885. #  char(153) representation as a base-10 integer, and convert it to
  886. #  base 16 (i.e. 10r153 -> 16r99).  The 99 is, of course, what we
  887. #  started with.
  888. #
  889. #      Note that two unpack routines are provided here:  The first, by
  890. #  Tanaglia, utilizes radcon.icn from the IPL.  The second, by
  891. #  Goerwitz, does not.  They utilize very different methods, but both
  892. #  amount to basically the same thing.  Goerwitz's routine returns an
  893. #  integer, though, and has no "width" argument.
  894. #
  895. ############################################################################
  896. #
  897. #  Links:  radcon.icn
  898. #
  899. ############################################################################
  900.  
  901. # link radcon.icn
  902.  
  903.  
  904. procedure pack(num,width)     
  905.  
  906.     # THIS PROCEDURE PACKS AN INTEGER INTO A PACKED DECIMAL STRING.
  907.  
  908.     local int, sign, prep, packed, word
  909.  
  910.     int := integer(num) | fail
  911.     # There's really no need to store the sign if it's positive.
  912.     if int < 0 then sign := "=" else sign := ""
  913.     prep   := string(abs(int)) || sign
  914.     packed := ""
  915.     if (*prep % 2) ~= 0 then prep := "0" || prep
  916.  
  917.     prep ? {
  918.     while word := move(2) do {
  919.         if pos(0)
  920.         then packed ||:= char(integer(word[1])*16 + ord(word[2])-48)
  921.         else packed ||:= char(integer(word[1])*16 + integer(word[2]))
  922.     }
  923.     }
  924.  
  925.     /width := *packed
  926.     return right(packed, width, "\0")
  927.  
  928. end
  929.  
  930.  
  931.  
  932. procedure unpack(val,width)
  933.  
  934.     # THIS PROCEDURE UNPACKS A VALUE INTO A STRING-INTEGER. USING THIS
  935.     # CODE SEGMENT REQUIRES LINKING WITH RADCON FROM THE IPL.
  936.  
  937.     local tmp, number, tens, ones, sign
  938.  
  939.     tmp  := ""
  940.     sign := 1
  941.  
  942.     every number := ord(!val) do
  943.     tmp ||:= right(map(radcon(number,10,16),&lcase,&ucase),2,"0")
  944.  
  945.     if tmp[-1] == ("B" | "D") then {
  946.     sign := -1
  947.     tmp[-1] :=  ""
  948.     }
  949.     tmp    *:= sign
  950.     /width  := *string(tmp)
  951.  
  952.     return right(string(tmp), width)
  953.  
  954. end
  955.  
  956.  
  957.  
  958. procedure unpack2(val)
  959.  
  960.     # THIS PROCEDURE UNPACKS A VALUE INTO AN STRING-INTEGER.
  961.  
  962.     local unpacked, int
  963.  
  964.     unpacked := ""
  965.     val ? {
  966.     while int := ord(move(1)) do {
  967.         unpacked ||:= string(iand(2r11110000,int) / 16)
  968.         if pos(0) then {
  969.         if iand(2r00001111,int) = 13 then {
  970.             unpacked := "-" || unpacked
  971.             break
  972.         }
  973.         }
  974.         unpacked ||:= string(iand(2r00001111,int))
  975.     }
  976.     }
  977.  
  978.     return integer(unpacked)
  979.  
  980. end
  981.  
  982. From tenaglia@mis.mcw.edu  Sat Oct 27 08:23:20 1990
  983. Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  984.     id AA09782; Sat, 27 Oct 90 08:23:20 -0700
  985. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  986.     id AA07803; Sat, 27 Oct 90 11:16:11 EDT
  987. Received: by uwm.edu; id AA12078; Sat, 27 Oct 90 09:51:02 -0500
  988. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  989.           Sat, 27 Oct 90 08:59:29 CDT
  990. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  991.           Sat, 27 Oct 90 08:29:55 CDT
  992. Date: Sat, 27 Oct 90 08:29:55 CDT
  993. Message-Id: <0093ECEE55262040.20400CCB@mis.mcw.edu>
  994. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  995. Subject: pack and unpack routines
  996. To: icon-group@cs.arizona.edu
  997.  
  998.  
  999. regarding : suggested enhancements to the pack & unpack routines
  1000.  
  1001. >
  1002. >Tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
  1003. >>
  1004. >>Here are the procedures pack() and unpack(). They are part of my
  1005. >>personal IPL.
  1006. >
  1007. >I couldn't resist toying with the (un)pack routines just posted.
  1008. >There's no reason I can see for storing the sign if the int is
  1009. >positive, so I cut that part out.  I also added another unpack
  1010. >routine, which runs a bit faster, and behaves somewhat differently
  1011. >than the one Chris wrote.
  1012. >
  1013. >Oh, I should perhaps add that the thing has been redone in IPL
  1014. >format, and I've eliminated most automatic type conversions.
  1015. >They automatic type conversion thing is just a pet peeve of mine.
  1016. >I hope no one holds it against me :-).
  1017. >
  1018. >-Richard
  1019. MORE,...
  1020.  
  1021. The reason I handled the sign in the manner I did was that DEC and IBM
  1022. computers actually handle numbers in that format in some modes of operation.
  1023. Other language programs (COBOL, BASIC, FORTRAN, etc,..) may still need
  1024. access to those numbers for some reason, thus I maintained the sign, even
  1025. though it cost me 4 bits. Your versions are fine so long as icon programs
  1026. using this are the only accessors to the data.
  1027.  
  1028. Chris Tenaglia (System Manager)
  1029. Medical College of Wisconsin
  1030. 8701 W. Watertown Plank Rd.
  1031. Milwaukee, WI 53226
  1032. (414)257-8765
  1033. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  1034.  
  1035.  
  1036. From cary@hpcllak.cup.hp.com  Wed Oct 31 16:10:31 1990
  1037. Received: from relay.hp.com (hp-sde.sde.hp.com) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1038.     id AA13689; Wed, 31 Oct 90 16:10:31 -0700
  1039. Received: from hpcllak.cup.hp.com by relay.hp.com with SMTP
  1040.     (16.5/15.5+IOS 3.13) id AA29399; Wed, 31 Oct 90 15:10:27 -0800
  1041. Message-Id: <9010312310.AA29399@relay.hp.com>
  1042. Received: by hpcllak; Wed, 31 Oct 90 15:09:41 pst
  1043. Date: Wed, 31 Oct 90 15:09:41 pst
  1044. From: Cary Coutant <cary@hpcllak.cup.hp.com>
  1045. To: icon-group@cs.arizona.edu
  1046. Subject: date arithmetic
  1047.  
  1048. > Perhaps I didn't look close enough at the IPL, but I am interested in time
  1049. > and date manipulation routines.
  1050.  
  1051. Well, it doesn't quite meet your specs, but I have here a set of Icon
  1052. procedures that convert dates to and from Julian day numbers.  Given the
  1053. Julian day numbers, you can do all of the arithmetic you like and the
  1054. convert back.
  1055.  
  1056. These routines are as correct as I can establish from a several sources,
  1057. the most helpful ones being the _Astronomical_Calendar_ (annual) and
  1058. _Astronomical_Companion_, both by Guy Ottewell (great books, both!).
  1059. I got the trick for converting month number to days-in-year-so-far from
  1060. some well-known published calculator algorithms floating around the net.
  1061.  
  1062. -Cary Coutant, Hewlett-Packard Computer Language Laboratory
  1063.  
  1064.  
  1065. # This is a shell archive.  Remove anything before this line,
  1066. # then unpack it by saving it in a file and typing "sh file".
  1067. #
  1068. # Wrapped by Cary Coutant <cary@hpcllak> on Wed Oct 31 15:04:41 1990
  1069. #
  1070. # This archive contains:
  1071. #    jdate.icn    
  1072. #
  1073.  
  1074. LANG=""; export LANG
  1075. PATH=/bin:/usr/bin:$PATH; export PATH
  1076.  
  1077. echo x - jdate.icn
  1078. cat >jdate.icn <<'@EOF'
  1079. # Note:  "Julian day" is named after the father of the astronomer who
  1080. # invented the Julian day numbering system.  It is unrelated to the
  1081. # "Julian calendar", which was the one established by Julius Caesar,
  1082. # and introduced the concept of a leap year every fourth year.  The
  1083. # Gregorian calendar, established by Pope Gregory the somethingorother,
  1084. # corrected the Julian calendar by eliminating three leap years out of
  1085. # every four hundred years, bringing the average year to a length of
  1086. # 365 + 1/4 - 3/100 = 365.22 days.
  1087.  
  1088. # By the way, to astronomers (and to this program), the year 1 B.C.
  1089. # is year 0, 2 B.C. is -1, etc.
  1090.  
  1091. global cutover        # julian day number of cutover from Julian to
  1092.             # Gregorian calendar (should be the first day
  1093.             # skipped).
  1094.  
  1095. procedure main(args)
  1096.     cutover := julian(9, 3, 1752)  # England and the Colonies
  1097.     if !args == "-c" then cutover := julian(10, 5, 1582) # Catholic countries
  1098.     convert()
  1099.     return
  1100. end
  1101.  
  1102. procedure convert()
  1103.     local g
  1104.  
  1105.     while read() ? {
  1106.     month := integer(tab(many('0123456789')))
  1107.     tab(many(' /'))
  1108.     day := integer(tab(many('0123456789')))
  1109.     tab(many(' /'))
  1110.     year := integer(tab(many('-0123456789')))
  1111.     g := gregorian(month, day, year)
  1112.     write(datestring(g), " = ", g)
  1113.     }
  1114.     return
  1115. end
  1116.  
  1117. ## gregorian(m,d,y) - Return the Julian day number for 12:00 noon
  1118. #  on the given m/d/y, using the Gregorian calendar.
  1119.  
  1120. procedure gregorian(month, day, year)
  1121.     local g
  1122.  
  1123.     g := julian(month, day, year)
  1124.     if g >= cutover then {
  1125.     if month < 3 then year -:= 1
  1126.     g +:= 2 - floor(year/100.0) + floor(year/400.0)
  1127.     }
  1128.     return g
  1129. end
  1130.  
  1131. ## julian(m,d,y) - Return the Julian day number for 12:00 noon
  1132. #  on the given m/d/y, using the Julian calendar.
  1133.  
  1134. procedure julian(month, day, year)
  1135.     month -:= 3
  1136.     if month < 0 then {
  1137.     month +:= 12
  1138.     year -:= 1
  1139.     }
  1140.     return 1721117 + floor(year*365.25) + (month*153+2)/5 + day
  1141. end
  1142.  
  1143. ## datestring() - produces a formatted date string for a julian day number.
  1144.  
  1145. procedure datestring(g)
  1146.     local dow, mdy, m, d, y
  1147.  
  1148.     dow := dayofweek(g)
  1149.     mdy := tomdy(g)
  1150.     m := mdy[1]
  1151.     d := mdy[2]
  1152.     y := mdy[3]
  1153.     return left(dow, 10) ||
  1154.         right(m, 2, "0") || "/" ||
  1155.         right(d, 2, "0") || "/" ||
  1156.         (right(0<y, 4, "0") | (right(1-y, 4, "0") || "BC"))
  1157. end
  1158.  
  1159. ## dayofweek() - returns day of the week for a julian day number.
  1160.  
  1161. procedure dayofweek(g)
  1162.     local dow
  1163.  
  1164.     dow := g % 7
  1165.     if dow < 0 then dow +:= 7
  1166.     return (dow+1)("Monday", "Tuesday", "Wednesday",
  1167.             "Thursday", "Friday", "Saturday", "Sunday")
  1168. end
  1169.  
  1170. ## tomdy() - converts julian day number to a list [m,d,y].
  1171.  
  1172. procedure tomdy(g)
  1173.     local month, day, year, qc, c
  1174.  
  1175.     day := g - 1721117 - 1  # 3/1/0000 = 0
  1176.  
  1177.     # eliminate gregorian calendar correction
  1178.     if g >= cutover then {
  1179.     qc := floor(day/146097.0)
  1180.     c := floor((day-qc*146097)/36525.0)
  1181.     day +:= c + qc*3 - 2
  1182.     }
  1183.  
  1184.     year := floor((day*4+3)/1461.0)
  1185.     day -:= floor(year*1461/4.0)
  1186.     month := (day*5+2)/153
  1187.     day := day - (month*153+2)/5 + 1
  1188.     month +:= 3
  1189.     if month > 12 then {
  1190.     month -:= 12
  1191.     year +:= 1
  1192.     }
  1193.     return [month, day, year]
  1194. end
  1195.  
  1196. ## floor() - rounds to an integer towards negative infinity.
  1197.  
  1198. procedure floor(f)
  1199.     local i
  1200.  
  1201.     i := integer(f)
  1202.     if i > f then i -:= 1
  1203.     return i
  1204. end
  1205.  
  1206. ## test() - Tests the date conversion routines by brute force,
  1207. #  by stepping through day by day through the years 1601 to 2000.
  1208. #
  1209. # procedure test()
  1210. #     local g, year, month, day, mdy
  1211. #     g := julian(1, 1, 1601)
  1212. #     every year := 1601 to 2000 do {
  1213. #     every month := 1 to 12 do {
  1214. #         every day := 1 to ndays(year, month) do {
  1215. #         if year = 1752 & month = 9 & 2 < day < 14 then next
  1216. #         g1 := gregorian(month, day, year)
  1217. #         if g ~= g1 then
  1218. #             write("gregorian(", month, "/", day, "/", year, ") is ",
  1219. #                 g1, ", should be ", g)
  1220. #         mdy := tomdy(g)
  1221. #         if mdy[1] ~= month | mdy[2] ~= day | mdy[3] ~= year then
  1222. #             write("tomdy(", g, ") is ",
  1223. #                 mdy[1], "/", mdy[2], "/", mdy[3],
  1224. #                 ", should be ",
  1225. #                 month, "/", day, "/", year)
  1226. #         g +:= 1
  1227. #         }
  1228. #         }
  1229. #     if year % 25 = 0 then write(year)
  1230. #     }
  1231. #     return
  1232. # end
  1233. # procedure ndays(year, month)
  1234. #     local mdays
  1235. #     static stdyear, leapyear
  1236. #     initial {
  1237. #     stdyear := [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  1238. #     leapyear := [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  1239. #     }
  1240. #     mdays := stdyear
  1241. #     if year % 4 = 0 then mdays := leapyear
  1242. #     if (1752 < year) % 400 = (100|200|300) then mdays := stdyear
  1243. #     return .mdays[month]
  1244. # end
  1245. @EOF
  1246.  
  1247. chmod 664 jdate.icn
  1248.  
  1249. exit 0
  1250.  
  1251. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Fri Nov  2 14:13:59 1990
  1252. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1253.     id AA27706; Fri, 2 Nov 90 14:13:59 -0700
  1254. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  1255.     id AA04865; Fri, 2 Nov 90 16:13:55 -0500
  1256. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Fri, 2 Nov 90 16:09:19 EST
  1257. Date: Fri, 2 Nov 90 14:33:12 EST
  1258. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  1259. To: icon-group@cs.arizona.edu
  1260. Message-Id: <266508@Wayne-MTS>
  1261. Subject: Generating variables
  1262.  
  1263.  
  1264. The Icon operator ! generates a sequence of variables when it's applied to
  1265. a list, string, or record.  My question is: is there any way that a
  1266. user-defined procedure can generate variables (other than using the "variable"
  1267. function)?  Here is my attempt at it; it didn't work.
  1268.  
  1269. Paul Abrahams
  1270. abrahams%wayne-mts@um.cc.umich.edu
  1271.  
  1272.  
  1273. procedure main ()
  1274.    l := [1,2,3,4]
  1275.    every writes(!l, " ")
  1276.    write() # writes 1 2 3 4
  1277.    every !l := 9
  1278.    every writes(!l, " ")
  1279.    write() # writes 9 9 9 9
  1280.    every !p1(l) := 7  # produces an error; can't assign 7 to "9"
  1281.    every writes(!l, " ")
  1282.    write()
  1283. end
  1284.  
  1285. procedure p1(z)
  1286.    suspend !z
  1287. end 
  1288.  
  1289. From cary@hpcllak.cup.hp.com  Fri Nov  2 16:04:49 1990
  1290. Received: from relay.hp.com ([15.255.152.2]) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1291.     id AA01495; Fri, 2 Nov 90 16:04:49 -0700
  1292. Received: from hpcllak.cup.hp.com by relay.hp.com with SMTP
  1293.     (16.5/15.5+IOS 3.13) id AA26865; Fri, 2 Nov 90 15:03:48 -0800
  1294. Message-Id: <9011022303.AA26865@relay.hp.com>
  1295. Received: by hpcllak; Fri, 2 Nov 90 15:03:02 pst
  1296. Date: Fri, 2 Nov 90 15:03:02 pst
  1297. From: Cary Coutant <cary@hpcllak.cup.hp.com>
  1298. To: icon-group@cs.arizona.edu
  1299. Subject: Generating variables
  1300.  
  1301. The program would have worked but for a double bang -- you applied
  1302. the bang operator within the procedure, and on the procedure call.
  1303. Removing the latter yields a program that does what you were
  1304. expecting.
  1305.  
  1306. -Cary Coutant, HP Computer Language Lab
  1307.  
  1308. procedure main ()
  1309.    l := [1,2,3,4]
  1310.    every writes(!l, " ")
  1311.    write() # writes 1 2 3 4
  1312.    every !l := 9
  1313.    every writes(!l, " ")
  1314.    write() # writes 9 9 9 9
  1315.    every p1(l) := 7          # no extra bang operator here
  1316.    every writes(!l, " ")
  1317.    write()
  1318. end
  1319.  
  1320. procedure p1(z)
  1321.    suspend !z
  1322. end 
  1323.  
  1324.  
  1325. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Sat Nov  3 02:13:57 1990
  1326. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1327.     id AA14051; Sat, 3 Nov 90 02:13:57 -0700
  1328. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  1329.     id AA01640; Sat, 3 Nov 90 04:13:51 -0500
  1330. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sat, 3 Nov 90 04:10:13 EST
  1331. Date: Fri, 2 Nov 90 22:52:16 EST
  1332. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  1333. To: icon-group@cs.arizona.edu
  1334. Message-Id: <266657@Wayne-MTS>
  1335. Subject: Dereferencing
  1336.  
  1337.  
  1338. Yes, Beth was absolutely right about the way to fix my example of a generator
  1339. that returns variables.
  1340.  
  1341. I find it interesting that Icon attempts to preserve the "variable"-ness of
  1342. a returned entity, dereferencing it only if it has to.  But I can't think of a
  1343. way of moving a variable in the other direction: from caller to callee.  Not
  1344. only does Icon have call-by-value---there doesn't seem to be any way to
  1345. circumvent it.  Or is there------?
  1346.  
  1347. Paul
  1348.  
  1349. Paul Abrahams
  1350. abrahams%wayne-mts@um.cc.umich.edu
  1351.  
  1352. From icon-group-request@arizona.edu  Fri Nov  9 02:27:38 1990
  1353. Resent-From: icon-group-request@arizona.edu
  1354. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1355.     id AA14768; Fri, 9 Nov 90 02:27:38 -0700
  1356. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 9 Nov 90 02:27 MST
  1357. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19952; Fri, 9 Nov 90 01:17:06
  1358.  -0800
  1359. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1360.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1361.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1362. Resent-Date: Fri, 9 Nov 90 02:27 MST
  1363. Date: 8 Nov 90 19:35:41 GMT
  1364. From: wuarchive!cs.utexas.edu!news-server.csri.toronto.edu!clyde.concordia.ca!NSTN.NS.CA!cs.dal.ca!dal1!06davis@decwrl.dec.com
  1365. Subject: What are ICONS?
  1366. Sender: icon-group-request@arizona.edu
  1367. Resent-To: icon-group@cs.arizona.edu
  1368. To: icon-group@arizona.edu
  1369. Resent-Message-Id: <090D2BD08B19A041D2@Arizona.edu>
  1370. Message-Id: <2219@ac.dal.ca>
  1371. X-Envelope-To: icon-group@CS.Arizona.EDU
  1372. X-Vms-To: icon-group@Arizona.EDU
  1373.  
  1374.  
  1375.     Please forgive me, all those who are knowledgeable, but what are icons
  1376. as applied to computers. I know that they are in plain 'ol English, but what
  1377. are they and what kind of system do they run on?
  1378.     No flames please, I might just go and slit my wrists.
  1379.  
  1380.                     Davis B.
  1381.  
  1382. From icon-group-request@arizona.edu  Fri Nov  9 09:58:12 1990
  1383. Resent-From: icon-group-request@arizona.edu
  1384. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1385.     id AA06160; Fri, 9 Nov 90 09:58:12 -0700
  1386. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 9 Nov 90 09:57 MST
  1387. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA28203; Fri, 9 Nov 90 08:55:35
  1388.  -0800
  1389. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1390.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1391.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1392. Resent-Date: Fri, 9 Nov 90 09:57 MST
  1393. Date: 9 Nov 90 16:42:27 GMT
  1394. From: cme!cam!koontz@uunet.uu.net
  1395. Subject: RE: What are ICONS?
  1396. Sender: icon-group-request@arizona.edu
  1397. Resent-To: icon-group@cs.arizona.edu
  1398. To: icon-group@arizona.edu
  1399. Resent-Message-Id: <08CE390FA6B9A046CE@Arizona.edu>
  1400. Message-Id: <5726@alpha.cam.nist.gov>
  1401. Organization: National Institute of Standards & Technology, Gaithersburg, MD
  1402. X-Envelope-To: icon-group@CS.Arizona.EDU
  1403. X-Vms-To: icon-group@Arizona.EDU
  1404. References: <2219@ac.dal.ca>
  1405.  
  1406.  
  1407.  
  1408. Icon has two meanings in the computer context, neither having anything to
  1409. do with the Black Virgin of Kiev.
  1410.  
  1411. 1) In the context of this newsgroup it is a programming language called
  1412.    Icon.  Icon is a descendent of SNOBOL, but emphasizes the succeed/fail
  1413.    attribute of programming language statements in SNOBOL, rather than
  1414.    the pattern matching application per se.  
  1415.  
  1416. 2) More generally, an icon is a representation of a file or process in
  1417.    certain graphics-based user interfaces.  You click on the icon with your
  1418.    mouse to get a menu of things that you can do to the file or with the
  1419.    application.  For example, suppose that you are conducting a terminal
  1420.    session in a window.  You can reduce the window to an icon (perhaps a 
  1421.    picture of a terminal), and stick it in the corner of your screen while
  1422.    you do something else.  Later you can click on the icon to get a menu that 
  1423.    includes the option of converting the icon back into a window in which
  1424.    there is a terminal session.
  1425.     
  1426.  
  1427. From goer%sophist@gargoyle.uchicago.edu  Fri Nov  9 10:28:38 1990
  1428. Resent-From: goer%sophist@gargoyle.uchicago.edu
  1429. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1430.     id AA08389; Fri, 9 Nov 90 10:28:38 -0700
  1431. Return-Path: goer@sophist.uchicago.edu
  1432. Received: from gargoyle.uchicago.edu by Arizona.edu; Fri, 9 Nov 90 10:28 MST
  1433. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  1434.  AA07751; Fri, 9 Nov 90 11:27:56 199
  1435. Received: by sophist (4.1/UofC3.1X) id AA19459; Fri, 9 Nov 90 11:31:24 CST
  1436. Resent-Date: Fri, 9 Nov 90 10:28 MST
  1437. Date: Fri, 9 Nov 90 11:31:24 CST
  1438. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  1439. Subject: what are icons
  1440. Resent-To: icon-group@cs.arizona.edu
  1441. To: icon-group@arizona.edu
  1442. Resent-Message-Id: <08C9F83D3F79A045C3@Arizona.edu>
  1443. Message-Id: <9011091731.AA19459@sophist>
  1444. X-Envelope-To: icon-group@CS.Arizona.EDU
  1445. X-Vms-To: icon-group@Arizona.EDU
  1446.  
  1447.       Please forgive me, all those who are knowledgeable, but what are icons
  1448.     as applied to computers. I know that they are in plain 'ol English, but what
  1449.     are they and what kind of system do they run on?
  1450.  
  1451.       No flames please, I might just go and slit my wrists.
  1452.  
  1453. Before you do that, make sure to donate some blood to your local hospital,
  1454. where it is probably badly needed.
  1455.  
  1456. Seriously, though, here's an brief answer to your question:  Icons, as used
  1457. in relatively recent computer lingo, refer to symbols on your computer screen
  1458. that, when activated in one way or another, function in a way that bears some
  1459. analogy to their form.  For instance, what do you think activating a picture
  1460. of a trash can does?  Sure:  It trashes something.
  1461.  
  1462. Anyway, you have just posted to the Icon group, a mailing list dedicated to
  1463. discussion of the Icon programming language.  It's got nothing to do with
  1464. those cute pictures on your computer screen (if, that is, you are working
  1465. with a windowing system that has them).  Icon is the successor to Snobol4,
  1466. and is used by people for general programming tasks, especially those in-
  1467. volving heuristic "algorithms," symbol manipulation, and anything to do
  1468. with language and text.  It's especially popular among people involved in
  1469. nonnumeric computing (in my case, the study of ancient languages).
  1470.  
  1471. I hope you don't find this response cause to slit your wrists, by the way.
  1472. (Maybe you need to develop a bit thicker skin....)
  1473.  
  1474. -Richard
  1475.  
  1476. From nowlin@iwtqg.att.com  Fri Nov  9 15:42:56 1990
  1477. Message-Id: <9011092242.AA24842@megaron.cs.arizona.edu>
  1478. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  1479.     id AA24842; Fri, 9 Nov 90 15:42:56 -0700
  1480. From: nowlin@iwtqg.att.com
  1481. Date: Fri, 9 Nov 90 15:22 CST
  1482. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  1483. To: att!cs.arizona.edu!icon-group
  1484. Subject: MS-DOS Problem
  1485.  
  1486. Here's a message I'm passing along for a friend.  He's having a problem
  1487. with Icon on MS-DOS and it doesn't have anything to do with memory this
  1488. time!  Any help would be appreciated.
  1489.  
  1490. ===========================================================================
  1491.  
  1492. I think I've tripped on an honest to goodness bug in MS-DOS Icon for
  1493. Version 8.  I've been wrong on things like this before but here's what I
  1494. found last night.
  1495.  
  1496. I am reading in a PC-FILE database and processing it with V8 of Icon on an
  1497. AT&T 6300+ MS-DOS compatible computer.  The file is not too long - about
  1498. 5000 bytes.  I start by reading in a number of fixed length (32 byte)
  1499. header records until I get to a record that starts with a newline
  1500. character.
  1501.  
  1502. Normally it would read 20-30 such 32-byte records.  But with V8 it read the
  1503. first and then the next:
  1504.  
  1505.     line := reads(fd,32)
  1506.  
  1507. returns not 32 characters but just 16 and a subsequent read attempt fails.
  1508. I presume with EOF.
  1509.  
  1510. A dump of the database file shows that the 49th character is an octal 032
  1511. which is the DOS CONTROL-Z or end-of-file marker.  What appears to be
  1512. happening is that V8 is stopping when it sees that CTL-Z.  V7 did not do
  1513. this!
  1514.  
  1515. The open was like:
  1516.  
  1517.     fd := open("TESTOFF.DBF","ru") | stop("DBF open failed")
  1518.  
  1519. and the open succeeds.
  1520.  
  1521. Joe T. Hall
  1522. (att!ihlpf!pax)
  1523.  
  1524. From pax@pax7300.att.com  Fri Nov  9 18:10:49 1990
  1525. Date: Fri, 9 Nov 90 18:10:49 -0700
  1526. From: pax@pax7300.att.com
  1527. Message-Id: <9011100110.AA00524@megaron.cs.arizona.edu>
  1528. Received: from att.UUCP by megaron.cs.arizona.edu (5.61/15) via UUCP
  1529.     id AA00524; Fri, 9 Nov 90 18:10:49 -0700
  1530. To: att!cs.arizona.edu!icon-group
  1531. Subject: MSDOS V8 reads
  1532. Cc: pax@ihlpf.att.com, nowlin@iwtqg.att.com
  1533.  
  1534. Icon Trekkies!
  1535.  
  1536. Is it possible that Version 8 of Icon on MS-DOS will not read past
  1537. an octal 32 with reads???
  1538.  
  1539.     procedure main()
  1540.         fd := open("TESTOFF.DBF","ru") | stop("DBF open failed")
  1541.         while line := reads(fd,32) do {
  1542.               write("*line=",*line)
  1543.         }
  1544.     end
  1545.  
  1546. TESTOFF.DBF happens to have an octal 032 in position 49 of the file.
  1547.  
  1548. The above program on MS-DOS returns:
  1549.  
  1550. *line=32
  1551. *line-16
  1552.  
  1553. The above program on my UNIX-pc reads continuous 32 byte lines
  1554. until it reaches the real end-of-file.
  1555.  
  1556. It appears to me that Version 8 of Icon for MS-DOS will not read past
  1557. this CTL-Z (octal 032) character.
  1558.  
  1559. Joe Hall
  1560.  
  1561.  
  1562. From sbw@turing.cse.nau.edu  Fri Nov  9 18:52:47 1990
  1563. Received: from turing.cse.nau.edu ([134.114.64.4]) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1564.     id AA00115; Fri, 9 Nov 90 18:52:47 -0700
  1565. Received: by turing.cse.nau.edu (5.64/1.34)
  1566.     id AA02657; Fri, 9 Nov 90 17:53:05 -0700
  1567. Message-Id: <9011100053.AA02657@turing.cse.nau.edu>
  1568. From: sbw@turing.cse.nau.edu (Steve Wampler)
  1569. Date: Fri, 9 Nov 1990 17:53:04 MST
  1570. X-Mailer: Mail User's Shell (7.2.0 10/31/90)
  1571. To: icon-group@cs.arizona.edu
  1572. Subject: example of function tracing...
  1573.  
  1574. A recent Icon Newsletter showed a neat way to trace a builtin
  1575. function.  The following little package shows how this might
  1576. be used conveniently.  Briefly, the procedure 'trace_option()'
  1577. is passed the argument list to 'main'.  The argument '-trace'
  1578. turns on general tracing.  Arguments of the form '-Ffunction'
  1579. turn on tracing of the builtin function 'function', if possible.
  1580.  
  1581. I think the comments explain everything else.
  1582.  
  1583. Right now, the package only traces functions that I frequently
  1584. want to trace, though it is easy to add tracing of others.
  1585.  
  1586. ---- snip 'traceset.icn' ----
  1587. procedure trace_options(args)
  1588.    local nextarg, arg
  1589.  
  1590.     #
  1591.     # Check arguments for tracing parameters
  1592.     #
  1593.     #    can trace some builtin functions, e.g.:
  1594.     #
  1595.     #        -Ftab
  1596.     # 
  1597.     #    will trace tab()
  1598.     #
  1599.  
  1600.    every arg := !args do {
  1601.       if map(arg) == "-trace" then
  1602.          &trace := -1
  1603.       else if match("-F",arg) then {    # trace a built-in function
  1604.          set_trace(arg[3:0])
  1605.          }
  1606.       }
  1607.  
  1608.    return
  1609. end
  1610.  
  1611. procedure set_trace(vf)
  1612.    local traceset, vp
  1613.  
  1614.     #
  1615.     # trace the builtin function 'vf', if possible
  1616.     #
  1617.  
  1618.    if not find("Version 8",&version) then {
  1619.       write(&errout,"You are running ",&version,", which doesn't support")
  1620.       write(&errout,"   this package.  You need version 8.")
  1621.       stop()
  1622.       }
  1623.   
  1624.     # so far, can only trace these (easy to add more)
  1625.    traceset := set(["any","bal","copy","find","many","move","tab","upto"])
  1626.     
  1627.    if member(traceset,vf) then {
  1628.       &trace := -1        # have to also trace all procedures!
  1629.       vp := vf
  1630.       vp[1] := map(vp[1],&lcase,&ucase)
  1631.       variable(vp) :=: variable(vf)
  1632.       write(&errout, "Calls of '",vf,"' will be traced as calls of '",vp,"'")
  1633.       }
  1634.    else
  1635.       write(&errout, vf, " is not a function that can be traced!")
  1636.  
  1637.    return
  1638. end
  1639.  
  1640. procedure Any(cs,s,i,j)
  1641.    return Any(cs,s,i,j)
  1642. end
  1643.  
  1644. procedure Bal(cs,cl,cr,s,i,j)
  1645.    suspend Bal(cs,cl,cr,s,i,j)
  1646. end
  1647.  
  1648. procedure Copy(cs)
  1649.    return Copy(cs)
  1650. end
  1651.  
  1652. procedure Find(s1,s,i,j)
  1653.    suspend Find(s1,s,i,j)
  1654. end
  1655.  
  1656. procedure Many(cs,s,i,j)
  1657.    return Many(cs,s,i,j)
  1658. end
  1659.  
  1660. procedure Match(s1,s,i,j)
  1661.    return Match(s1,s,i,j)
  1662. end
  1663.  
  1664. procedure Move(cs)
  1665.    suspend Move(cs)
  1666. end
  1667.  
  1668. procedure Tab(i)
  1669.    suspend Tab(i)
  1670. end
  1671.  
  1672. procedure Upto(cs,s,i,j)
  1673.    suspend Upto(cs)
  1674. end
  1675. ---- snip 'traceset.icn' end ----
  1676.  
  1677. -- 
  1678.     Steve Wampler
  1679.     {....!arizona!naucse!sbw}
  1680.     {sbw@turing.cse.nau.edu}
  1681.  
  1682. From icon-group-request@arizona.edu  Fri Nov  9 19:01:38 1990
  1683. Resent-From: icon-group-request@arizona.edu
  1684. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1685.     id AA00530; Fri, 9 Nov 90 19:01:38 -0700
  1686. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 9 Nov 90 17:11 MST
  1687. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03261; Fri, 9 Nov 90 16:05:33
  1688.  -0800
  1689. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1690.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1691.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1692. Resent-Date: Fri, 9 Nov 90 17:12 MST
  1693. Date: 9 Nov 90 22:39:30 GMT
  1694. From: julius.cs.uiuc.edu!zaphod.mps.ohio-state.edu!unix.cis.pitt.edu!dsinc!netnews.upenn.edu!msuinfo!midway!iitmax!ed@apple.com
  1695. Subject: RE: What are ICONS?
  1696. Sender: icon-group-request@arizona.edu
  1697. Resent-To: icon-group@cs.arizona.edu
  1698. To: icon-group@arizona.edu
  1699. Resent-Message-Id: <089190666E99A04A34@Arizona.edu>
  1700. Message-Id: <4495@iitmax.IIT.EDU>
  1701. Organization: Illinois Institute of Technology
  1702. X-Envelope-To: icon-group@CS.Arizona.EDU
  1703. X-Vms-To: icon-group@Arizona.edu
  1704. References: <2219@ac.dal.ca>, <5726@alpha.cam.nist.gov>
  1705.  
  1706. In article <5726@alpha.cam.nist.gov> koontz@cam.nist.gov (John E. Koontz X5180) writes:
  1707. > [what does Icon mean?]
  1708. >1) In the context of this newsgroup it is a programming language called
  1709. >   Icon.  Icon is a descendent of SNOBOL, but emphasizes the succeed/fail
  1710. >   attribute of programming language statements in SNOBOL, rather than
  1711. >   the pattern matching application per se.  
  1712.  
  1713. One thing I've been wondering, and I've not seen it in the forward to the
  1714. Icon book, is WHY is the language named "Icon"??  By the way, as long
  1715. as I'm asking, does anyone know how SNOBOL and SPITBOL get thier names...
  1716.  
  1717. You know, almost _every_ FORTRAN book mentions that its name comes from
  1718. FORmula TRANslation, or BASIC is Beginners All-purpose Symbolic Instruction Code
  1719. (or whatever) :-)
  1720.  
  1721. -- 
  1722. //==========================================================================\\
  1723. ||  Ed Federmeyer                     ||    Internet:  ed@iitMax.iit.edu    ||
  1724. ||      "Unauthorized access is       ||    Bitnet:    sysed@iitVax         ||
  1725. ||         strictly unauthorized."    ||    Office:    (312) 567-5981       ||
  1726. \\==========================================================================//
  1727.  
  1728. From sbw@turing.cse.nau.edu  Sun Nov 11 10:50:19 1990
  1729. Received: from turing.cse.nau.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1730.     id AA08540; Sun, 11 Nov 90 10:50:19 -0700
  1731. Received: by turing.cse.nau.edu (5.64/1.34)
  1732.     id AA04852; Sun, 11 Nov 90 10:49:56 -0700
  1733. Message-Id: <9011111749.AA04852@turing.cse.nau.edu>
  1734. From: sbw@turing.cse.nau.edu (Steve Wampler)
  1735. Date: Sun, 11 Nov 1990 10:49:56 MST
  1736. X-Mailer: Mail User's Shell (7.2.0 10/31/90)
  1737. To: icon-group@cs.arizona.edu
  1738. Subject: Oops, wrong publication...
  1739.  
  1740. The description for simple builtin function tracing came from
  1741. the Icon Analyst, not the Icon Newsletter.  (If you're only
  1742. getting the Newsletter, you might look into the Analyst - it
  1743. has some neat things in it.)
  1744.  
  1745. -- 
  1746.     Steve Wampler
  1747.     {....!arizona!naucse!sbw}
  1748.     {sbw@turing.cse.nau.edu}
  1749.  
  1750. From @s.ms.uky.edu:mtbb83@ms.uky.edu  Sun Nov 11 12:22:11 1990
  1751. Resent-From: @s.ms.uky.edu:mtbb83@ms.uky.edu
  1752. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1753.     id AA10366; Sun, 11 Nov 90 12:22:11 -0700
  1754. Received: from e.ms.uky.edu by Arizona.edu; Sun, 11 Nov 90 12:21 MST
  1755. Received: from s.ms.uky.edu by g.ms.uky.edu id aa26311; 11 Nov 90 14:16 EST
  1756. Resent-Date: Sun, 11 Nov 90 12:21 MST
  1757. Date: Sun, 11 Nov 90 14:16:24 EST
  1758. From: Dr Jerome Krumpelman <mtbb83@ms.uky.edu>
  1759. Subject: Remove name
  1760. Resent-To: icon-group@cs.arizona.edu
  1761. To: icon-group@arizona.edu
  1762. Resent-Message-Id: <0727C1C63859A05510@Arizona.edu>
  1763. Message-Id: <9011111416.aa25042@s.s.ms.uky.edu>
  1764. X-Envelope-To: icon-group@CS.Arizona.EDU
  1765. X-Vms-To: icon-group@Arizona.edu
  1766.  
  1767. I have enjoyed and learned from receiving the Icon traffic on
  1768. *.edu net.  However, please remove my name from the list, for now.
  1769. Please do not re-send this message over the net, and do not purge
  1770. me from the mailed material ( ICON news...).
  1771. Thanx -- jk
  1772. --
  1773.              Jerome Krumpelman
  1774.              mtbb83@ms.uky.edu
  1775.              {rutgers,uunet}!ukma!ms!mtbb83
  1776.              CompuServe 70441,2760
  1777.  
  1778.  
  1779. From icon-group-request@arizona.edu  Mon Nov 12 12:01:41 1990
  1780. Resent-From: icon-group-request@arizona.edu
  1781. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1782.     id AA28358; Mon, 12 Nov 90 12:01:41 -0700
  1783. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 12 Nov 90 12:01 MST
  1784. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA07849; Mon, 12 Nov 90
  1785.  10:57:19 -0800
  1786. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1787.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1788.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1789. Resent-Date: Mon, 12 Nov 90 12:01 MST
  1790. Date: 12 Nov 90 07:19:43 GMT
  1791. From: castor.ucdavis.edu!f140026@ucdavis.ucdavis.edu
  1792. Subject: p/d icon wanted for Macintosh
  1793. Sender: icon-group-request@arizona.edu
  1794. Resent-To: icon-group@cs.arizona.edu
  1795. To: icon-group@arizona.edu
  1796. Resent-Message-Id: <0661772D616780041E@Arizona.edu>
  1797. Message-Id: <9266@aggie.ucdavis.edu>
  1798. Organization: University of California, Davis
  1799. X-Envelope-To: icon-group@CS.Arizona.EDU
  1800. X-Vms-To: icon-group@Arizona.edu
  1801.  
  1802.  
  1803.  
  1804. Hi, I'm looking for an anonymously ftp-able version of Icon that will
  1805. run on the Macintosh SE.  The back of my Icon book says the University
  1806. of Arizona to Tucson has it -- does anyone know if it's ftp-able?
  1807. Thanks!
  1808.  
  1809. f140026@castor.ucdavis.edu
  1810.  
  1811. From MYankowski.BSPO@DOCKMASTER.NCSC.MIL  Mon Nov 12 15:31:51 1990
  1812. Received: from DOCKMASTER.NCSC.MIL by megaron.cs.arizona.edu (5.61/15) via SMTP
  1813.     id AA05913; Mon, 12 Nov 90 15:31:51 -0700
  1814. Date:  Mon, 12 Nov 90 17:27 EST
  1815. From: MYankowski@DOCKMASTER.NCSC.MIL
  1816. Subject:  Icon Analyst
  1817. To: icon-group@cs.arizona.edu
  1818. Message-Id:  <901112222754.543046@DOCKMASTER.NCSC.MIL>
  1819.  
  1820. Could someone please provide more information on the ICON Analyst?
  1821.  
  1822.  
  1823. Mike DOCKMASTER
  1824.  
  1825. From ralph  Mon Nov 12 16:02:27 1990
  1826. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1827.     id AA07058; Mon, 12 Nov 90 16:02:27 -0700
  1828. Date: Mon, 12 Nov 90 16:02:20 MST
  1829. From: "Ralph Griswold" <ralph>
  1830. Message-Id: <9011122302.AA04186@cheltenham.cs.arizona.edu>
  1831. Received: by cheltenham.cs.arizona.edu; Mon, 12 Nov 90 16:02:20 MST
  1832. To: MYankowski@DOCKMASTER.NCSC.MIL
  1833. Subject: Re:  Icon Analyst
  1834. Cc: icon-group
  1835.  
  1836.  
  1837. The Icon Analyst is a technical newsletter published 6 times a year
  1838. by the Icon Project.  It is 12 pages, 8.5x11".  It covers various
  1839. aspects of the Icon programming language, mostly related to programming.
  1840.  
  1841. The editors are Ralph E. Griswold and Madge T. Griswold, the same as
  1842. for the Icon Newsletter, which features less tehcnical material of a more
  1843. topical interest.
  1844.  
  1845. The first issue of the Analyst was published in August, 1990. The third issue is
  1846. presently being prepared for mailing.
  1847.  
  1848. Articles so far have covered "getting started", memory monitoring, benchmarking
  1849. expressions, expression evaluation, syntactic pitfalls, program readability,
  1850. writing portable programs, string scanning, generators, and so forth. There's
  1851. also a regular "programming tips" feature.
  1852.  
  1853. A subscription to the Icon Analyst is $25 per year, which includes first-class
  1854. postage in the United States, Canada, and Mexico. There is an additional
  1855. charge of $10 per year for overseas subscriptions, which are sent by
  1856. first-class airmail.
  1857.  
  1858. Persons wishing to subscribe should make checks payable to The University
  1859. of Arizona and send them to
  1860.  
  1861.     Icon Project
  1862.     Department of Computer Science
  1863.     The University of Arizona
  1864.     Tucson, AZ   85721
  1865.     U.S.A.
  1866.  
  1867. Mastercard and Visa also are acceptable.
  1868.  
  1869.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  1870.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  1871.  
  1872. From icon-group-request@arizona.edu  Tue Nov 13 14:01:54 1990
  1873. Resent-From: icon-group-request@arizona.edu
  1874. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1875.     id AA28621; Tue, 13 Nov 90 14:01:54 -0700
  1876. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 13 Nov 90 14:01 MST
  1877. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03231; Tue, 13 Nov 90
  1878.  13:00:49 -0800
  1879. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1880.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1881.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1882. Resent-Date: Tue, 13 Nov 90 14:01 MST
  1883. Date: 12 Nov 90 21:28:19 GMT
  1884. From: hpcc05!col!hpldola!hp-lsd!egul@hplabs.hpl.hp.com
  1885. Subject: RE: What are ICONS?
  1886. Sender: icon-group-request@arizona.edu
  1887. Resent-To: icon-group@cs.arizona.edu
  1888. To: icon-group@arizona.edu
  1889. Resent-Message-Id: <058780800407800E43@Arizona.edu>
  1890. Message-Id: <10110001@hp-lsd.COS.HP.COM>
  1891. Organization: HP Logic Systems Division - ColoSpgs, CO
  1892. X-Envelope-To: icon-group@CS.Arizona.EDU
  1893. X-Vms-To: icon-group@Arizona.edu
  1894. References: <2219@ac.dal.ca>
  1895.  
  1896.  
  1897. an icon is a bitmap, created by either you or by the application shell, that
  1898. pictorally represents an application, process, login, ...... whatever, 
  1899. to which you can jump from the current window.  This is usually done via
  1900. a mouse.  "Clicking" the   icon will usually start a script which otherwise you would
  1901. have to run or key in manually.  
  1902.  
  1903. A picture (icon) is worth a thousand words, get it? 
  1904.  
  1905. From ralph  Wed Nov 14 10:34:41 1990
  1906. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1907.     id AA17349; Wed, 14 Nov 90 10:34:41 -0700
  1908. Date: Wed, 14 Nov 90 10:34:39 MST
  1909. From: "Ralph Griswold" <ralph>
  1910. Message-Id: <9011141734.AA01002@cheltenham.cs.arizona.edu>
  1911. Received: by cheltenham.cs.arizona.edu; Wed, 14 Nov 90 10:34:39 MST
  1912. To: icon-group
  1913. Subject: Bug in MS-DOS Version 8 Icon
  1914.  
  1915. As noted in recent icon-group mail, there is a bug in the first release
  1916. of Version 8 Icon for MS-DOS.  The bug is that the "untranslated"
  1917. mode of input/output doesn't work -- input/output always is in the translated
  1918. mode.
  1919.  
  1920. This means that if you're reading a "binary" file carriage-return/line-feed
  1921. combintations get turned into line-feeds on input and conversely on output.
  1922. That's not so bad, as long as you're not examining or changing the file inside
  1923. an Icon program. Much worse is that a control-Z character (hex 1A) terminates
  1924. input.
  1925.  
  1926. Note that this is a problem only if you're doing input/output on binary
  1927. files. It does not affect input/output on text files.
  1928.  
  1929. We corrected this problem a couple of months ago and diskettes distributed
  1930. after mid-September have the correction. If you got Version 8 MS-DOS Icon
  1931. diskettes from us, check the date on ICON.ARC on the second diskette. If it's
  1932. before September 16, 1990, it has the bug.
  1933.  
  1934. We've only recently updated our FTP and RBBS files for MS-DOS Icon, so
  1935. if you got MS-DOS Icon from us electronically, you probably have a version
  1936. with the error.
  1937.  
  1938. If this bug is likely to bother you, you can download the corrected version.
  1939. If you purchased MS-DOS Icon diskettes from us, send back the second
  1940. diskette (DE.2) and we'll send you a free replacement.
  1941.  
  1942.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  1943.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  1944.  
  1945. From icon-group-request@arizona.edu  Wed Nov 14 13:08:29 1990
  1946. Resent-From: icon-group-request@arizona.edu
  1947. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1948.     id AA25496; Wed, 14 Nov 90 13:08:29 -0700
  1949. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 14 Nov 90 13:07 MST
  1950. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA04770; Wed, 14 Nov 90
  1951.  12:08:00 -0800
  1952. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1953.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1954.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1955. Resent-Date: Wed, 14 Nov 90 13:08 MST
  1956. Date: 14 Nov 90 02:11:45 GMT
  1957. From: usc!zaphod.mps.ohio-state.edu!unix.cis.pitt.edu!dsinc!netnews.upenn.edu!vax1.cc.lehigh.edu!lehigh.bitnet!GB03@ucsd.edu
  1958. Subject: RE:RE: WHAT ARE ICONS
  1959. Sender: icon-group-request@arizona.edu
  1960. Resent-To: icon-group@cs.arizona.edu
  1961. To: icon-group@arizona.edu
  1962. Resent-Message-Id: <04C5CDEDB927801349@Arizona.edu>
  1963. Message-Id: <13119021:11:45GB03@lehigh.bitnet>
  1964. X-Envelope-To: icon-group@CS.Arizona.EDU
  1965. X-Vms-To: icon-group@Arizona.edu
  1966.  
  1967. @bitnet@lehigh@gb03
  1968.  
  1969. It might interest most people to know that BASIC was originally BASIC.
  1970. Kemeny and Kurtz got tired of telling people it was only BASIC.  No one
  1971. believed the inventors.  They finally came up with Beginners All
  1972. Purpose Simplified Code
  1973.  
  1974. Ain't history wunderful!?
  1975.  
  1976. From ralph  Wed Nov 14 14:57:24 1990
  1977. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1978.     id AA01067; Wed, 14 Nov 90 14:57:24 -0700
  1979. Date: Wed, 14 Nov 90 14:57:22 MST
  1980. From: "Ralph Griswold" <ralph>
  1981. Message-Id: <9011142157.AA08332@cheltenham.cs.arizona.edu>
  1982. Received: by cheltenham.cs.arizona.edu; Wed, 14 Nov 90 14:57:22 MST
  1983. To: icon-group
  1984. Subject: Language names
  1985.  
  1986. To dispel any misconceptions, the name "Icon" for the Icon programming
  1987. language is not an acronym nor does it stand for anything.  It's just a
  1988. name.  It seemed appropriate (at the time) -- I recall mentioning that
  1989. the language design was somewhat iconoclastic.
  1990.  
  1991. Regrettably, we couldn't see the future and the use of the word "icon"
  1992. for pictograms to identify functions and objects on computer screens.
  1993. This has caused some confusion and misunderstanding -- some folks see
  1994. the word "Icon" and expect a programming language for manipulating
  1995. Icons.  The fact that our selection of the word came first doesn't
  1996. help a lot.
  1997.  
  1998. Someone asked about the origin of the name SNOBOL4 for an earlier
  1999. programming language. SNOBOL4 is an acronmyn (of sorts) for StriNg
  2000. Oriented symBOic Language. We were intending to poke fun at the
  2001. way acronyms for programming languages were derived.  But no one
  2002. thought it was funny.
  2003.  
  2004.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  2005.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  2006.  
  2007. From icon-group-request@arizona.edu  Wed Nov 14 16:26:46 1990
  2008. Resent-From: icon-group-request@arizona.edu
  2009. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2010.     id AA05411; Wed, 14 Nov 90 16:26:46 -0700
  2011. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 14 Nov 90 16:26 MST
  2012. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA10416; Wed, 14 Nov 90
  2013.  15:18:20 -0800
  2014. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2015.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2016.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2017. Resent-Date: Wed, 14 Nov 90 16:26 MST
  2018. Date: 14 Nov 90 22:36:09 GMT
  2019. From: usc!elroy.jpl.nasa.gov!suned1!zaft@ucsd.edu
  2020. Subject: RE: p/d icon wanted for Macintosh
  2021. Sender: icon-group-request@arizona.edu
  2022. Resent-To: icon-group@cs.arizona.edu
  2023. To: icon-group@arizona.edu
  2024. Resent-Message-Id: <04AA1C182A27801BD1@Arizona.edu>
  2025. Message-Id: <6070@suned1.Nswses.Navy.MIL>
  2026. Organization: NSWSES, Port Hueneme, CA
  2027. X-Envelope-To: icon-group@CS.Arizona.EDU
  2028. X-Vms-To: icon-group@Arizona.edu
  2029. References: <9266@aggie.ucdavis.edu>
  2030.  
  2031. In article <9266@aggie.ucdavis.edu> f140026@castor.ucdavis.edu () writes:
  2032. >Hi, I'm looking for an anonymously ftp-able version of Icon that will
  2033. >run on the Macintosh SE.  The back of my Icon book says the University
  2034. >of Arizona to Tucson has it -- does anyone know if it's ftp-able?
  2035. >Thanks!
  2036.  
  2037.     Well, you can FTP to cs.arizona.edu to try to find it; but to the
  2038. best of my knowledge (correct me if I'm wrong!) the only version of Icon
  2039. available for the Mac is ProIcon, which is NOT shareware, but is supposed
  2040. to be inexpensive and very spiffy.
  2041.  
  2042.     Anyone else have more info?
  2043.  
  2044. [Arizona slaughters ASU 11/24!  Nine will be fine ! :-)]
  2045.  
  2046. --
  2047. +  Gordon Zaft                        |  zaft@suned1.nswses.navy.mil         +
  2048. +  NSWSES, Code 4Y33                  |  suned1!zaft@elroy.jpl.nasa.gov      +
  2049. +  Port Hueneme, CA 93043-5007        |  Phone: (805) 982-0684 FAX: 982-8768 +
  2050.                   ++++ Ubi caritas et amor, Deus ibi est.++++
  2051.  
  2052. From ralph  Wed Nov 14 16:44:02 1990
  2053. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2054.     id AA06158; Wed, 14 Nov 90 16:44:02 -0700
  2055. Date: Wed, 14 Nov 90 16:44:00 MST
  2056. From: "Ralph Griswold" <ralph>
  2057. Message-Id: <9011142344.AA11247@cheltenham.cs.arizona.edu>
  2058. Received: by cheltenham.cs.arizona.edu; Wed, 14 Nov 90 16:44:00 MST
  2059. To: icon-group
  2060. Subject: Icon for the Macintosh
  2061.  
  2062. To clarify the situation, there is a public-domain version of Icon
  2063. available from the Icon Project, but it is not a stand-alone
  2064. application and requires the MPW to run.  MPW is a subsystem for
  2065. the Macintosh that vaguely resembles UNIX.  Running Icon under MPW
  2066. is similar to running Icon under UNIX -- a command-line environment
  2067. without the usual graphical interface.
  2068.  
  2069. ProIcon is a standard Macintosh application that has an integrated
  2070. environment with an editor that allows you to write and debug
  2071. Icon programs without leaving the application.  ProIcon also has
  2072. several extensions to Icon, including some capabilities for
  2073. manipulating windows and handling dialogs from within a ProIcon
  2074. program.
  2075.  
  2076. Version 2.0 of ProIcon, which is scheduled for release later this
  2077. month, also has an interface to HyperCard XCMDs and XFCNs.
  2078.  
  2079. For information about ProIcon, contact:
  2080.  
  2081.     Catspaw, Inc.
  2082.     P.O. Box 1123
  2083.     Salida, CO   81201-1123
  2084.  
  2085.     719-539-3884
  2086.  
  2087.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  2088.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  2089.  
  2090. From icon-group-request@arizona.edu  Fri Nov 16 11:25:59 1990
  2091. Resent-From: icon-group-request@arizona.edu
  2092. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2093.     id AA21839; Fri, 16 Nov 90 11:25:59 -0700
  2094. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 16 Nov 90 11:25 MST
  2095. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA07705; Fri, 16 Nov 90
  2096.  10:19:51 -0800
  2097. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2098.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2099.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2100. Resent-Date: Fri, 16 Nov 90 11:25 MST
  2101. Date: 12 Nov 90 18:10:25 GMT
  2102. From: zodiac!tsommers@rutgers.edu
  2103. Subject: RE: MSDOS V8 reads
  2104. Sender: icon-group-request@arizona.edu
  2105. Resent-To: icon-group@cs.arizona.edu
  2106. To: icon-group@arizona.edu
  2107. Resent-Message-Id: <0341CD3AFAE7A00526@Arizona.edu>
  2108. Message-Id: <201.273ee591@zodiac.rutgers.edu>
  2109. Organization: Rutgers University - Computing Services
  2110. X-Envelope-To: icon-group@CS.Arizona.EDU
  2111. X-Vms-To: icon-group@Arizona.edu
  2112. References: <9011100110.AA00524@megaron.cs.arizona.edu>
  2113.  
  2114. In article <9011100110.AA00524@megaron.cs.arizona.edu>, pax@pax7300.att.com writes:
  2115. > Is it possible that Version 8 of Icon on MS-DOS will not read past
  2116. > an octal 32 with reads???
  2117. >     procedure main()
  2118. >         fd := open("TESTOFF.DBF","ru") | stop("DBF open failed")
  2119. >         while line := reads(fd,32) do {
  2120. >               write("*line=",*line)
  2121. >         }
  2122. >     end
  2123. > TESTOFF.DBF happens to have an octal 032 in position 49 of the file.
  2124. > The above program on MS-DOS returns:
  2125. > *line=32
  2126. > *line-16
  2127.  
  2128. My guess would be that Icon is opening the file in text mode, and that
  2129. the particular C compiler used to make Icon treats Control-Z as EOF in
  2130. text mode. If Icon just passes the mode string unaltered to the C fopen
  2131. (or whatever), then perhaps all that is required is to use the
  2132. appropriate binary mode mode string when opening the file.
  2133.  
  2134. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Fri Nov 16 20:27:37 1990
  2135. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2136.     id AA12222; Fri, 16 Nov 90 20:27:37 -0700
  2137. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  2138.     id AA26271; Fri, 16 Nov 90 22:27:34 -0500
  2139. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Fri, 16 Nov 90 22:22:54 EST
  2140. Date: Fri, 16 Nov 90 20:47:38 EST
  2141. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  2142. To: icon-group@cs.arizona.edu
  2143. Message-Id: <270675@Wayne-MTS>
  2144. Subject: Uses of dynamic typing
  2145.  
  2146.  
  2147. As I mentioned in an earlier posting, I'm working on the design of SPLASH,
  2148. a Systems Programming Language for Software Hackers.  A question came up about
  2149. how people use Icon's dynamic typing.  In Icon the type of a variable isn't
  2150. determined until you assign something to it, and even then it can change. 
  2151. That's in contrast with other languages of the Algol/Pascal/Ada/C sort, in
  2152. which every variable has a declared type. 
  2153.  
  2154. My question is: how important is this flexibility for Icon programming, and
  2155. how do people utilize it?  There's one place where it clearly pays off: the
  2156. possibility of writing a procedure that prints its argument no matter what the
  2157. type of the argument.  The fact that you can't write the C printf function in
  2158. standard C shows why you want this.  But aside from printing arguments and
  2159. writing out their storage, I haven't been able to think of other operations
  2160. that use the flexibility.  Interestingly, sorting isn't one of those examples,
  2161. since not all data types have a natural ordering relation and even for those
  2162. that do, you use different operators in Icon (`<' for numbers, `<<' for
  2163. strings.) 
  2164.  
  2165. Examples, anyone--particularly from programs that do something rather than
  2166. just prove something?
  2167.  
  2168. Paul Abrahams
  2169. abrahams%wayne-mts@um.cc.umich.edu
  2170.  
  2171. From gmt  Fri Nov 16 21:50:19 1990
  2172. Received: from owl.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2173.     id AA14316; Fri, 16 Nov 90 21:50:19 -0700
  2174. Date: Fri, 16 Nov 90 21:50:18 MST
  2175. From: "Gregg Townsend" <gmt>
  2176. Message-Id: <9011170450.AA03673@owl.cs.arizona.edu>
  2177. Received: by owl.cs.arizona.edu; Fri, 16 Nov 90 21:50:18 MST
  2178. To: icon-group
  2179. Subject: Re:  Uses of dynamic typing
  2180.  
  2181. I've used Icon's type flexibility a few times to implement traps in
  2182. subroutine packages.  The paradigm works like this:
  2183.  
  2184. (1)  call enable() passing an arbitrary procedure p and other object x
  2185.      along with whatever is necessary to specify the trap conditions.
  2186.  
  2187. (2)  when the trap condition occurs -- for example, on every 60th
  2188.      call to an output routine -- p(x) is called using p and x
  2189.      from the enable() call.  Because x can be any type including
  2190.      a list or record, any desired amount of data can be passed to p.
  2191.  
  2192. This is clumsier in C because instead of an arbitrary object x one must
  2193. pass a *pointer* to x, with an appropriate cast, and then access the data
  2194. indirectly.
  2195.  
  2196. To pick a nit, printf actually can be written in standard C, because the
  2197. format specifies the expected types of the remaining arguments and there
  2198. are standard routines for retrieving them.  There are other problems such
  2199. as a danger that getc() has been replaced, but they're irrelevant to this
  2200. discussion.
  2201.  
  2202.     Gregg Townsend / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  2203.     +1 602 621 4325     gmt@cs.arizona.edu     110 57 16 W / 32 13 45 N / +758m
  2204.  
  2205. From gudeman  Sat Nov 17 01:01:50 1990
  2206. Date: Sat, 17 Nov 90 01:01:50 -0700
  2207. From: "David Gudeman" <gudeman>
  2208. Message-Id: <9011170801.AA19991@megaron.cs.arizona.edu>
  2209. Received: by megaron.cs.arizona.edu (5.61/15)
  2210.     id AA19991; Sat, 17 Nov 90 01:01:50 -0700
  2211. To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  2212. Cc: icon-group@cs.arizona.edu
  2213. In-Reply-To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu's message of Fri, 16 Nov 90 20:47:38 EST <270675@Wayne-MTS>
  2214. Subject: Uses of dynamic typing
  2215.  
  2216. One important use of dynamic typing is that the type itself gives
  2217. some information.  I write functions all the time where I _usually_
  2218. want a return value of a certain type, but on exceptional conditions I
  2219. want something different.  For example
  2220.  
  2221. # factorial(i) return the factorial of i if i > = 0,
  2222. #              otherwise return &null.
  2223.  
  2224. You can get much the same effect with exception handlers, but it has a
  2225. different flavor.
  2226.  
  2227. Another use is in program developement.  The ability to assign
  2228. different types to variables lets you try things out with fewer
  2229. changes to a program.  At least I think so.  Two other features that
  2230. help in this are polymorphism and automatic type conversions.  Since
  2231. Icon has all three, it is hard to say exactly which feature or set of
  2232. features is most involved in this.
  2233.  
  2234. Incidentally, there is no reason that run-time typing and static
  2235. typing can't peacefully coexist in the same language.  I can see two
  2236. different ways of doing this: the first way is to say that all
  2237. variables are untyped.  This dynamically typed language also has type
  2238. declarations that restrict the types that can be assigned to a given
  2239. variable _at run time_.  However, a given implementation _may_ give
  2240. errors at compile time if a given path might lead to a type conflict.
  2241. Furthermore, the implementation may optimize variables that always
  2242. have a known type.
  2243.  
  2244. The other way is to say that the language is statically typed, but
  2245. that there are union types that carry type information around as a
  2246. part of the union value.  Also, all operators are overloaded so that
  2247. they operate on the union types by checking the type at run time and
  2248. doing the right operation.  There is a specially named union type
  2249. "any" that is a union of all other types.  One might define that the
  2250. default type of a variable is "any".
  2251.  
  2252. Both of these paradigms allow the expressiveness of dynamic typing and
  2253. the security and efficiency of static typing.  In such a language, you
  2254. can do developement with dynamic types and then "optimize" the program
  2255. by declaring the types of most of the variables.
  2256.  
  2257. From ralph  Sat Nov 17 06:36:19 1990
  2258. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2259.     id AA00227; Sat, 17 Nov 90 06:36:19 -0700
  2260. Date: Sat, 17 Nov 90 06:36:15 MST
  2261. From: "Ralph Griswold" <ralph>
  2262. Message-Id: <9011171336.AA22105@cheltenham.cs.arizona.edu>
  2263. Received: by cheltenham.cs.arizona.edu; Sat, 17 Nov 90 06:36:15 MST
  2264. To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  2265. Subject: Re:  Uses of dynamic typing
  2266. Cc: icon-group
  2267.  
  2268. I disagree with your characterization of types and variables in Icon. It's not
  2269. that a variable doesn't have a type until an assignment is made to it, but
  2270. rather that variables are not typed, but values are. Note that every variable
  2271. has the null value initially.
  2272.  
  2273. I realize this distinction may seem a bit strange to persons who are used
  2274. to languages like Pascal, but if you look at the implementation of Icon,
  2275. you'll see that's exactly what's going on.  A variable is simply a place
  2276. to store a value, all variables are the same size, as are all values.  All
  2277. values carry an identifying type.
  2278.  
  2279. As to the usefulness of non-types variables, in my experience, it's mostly
  2280. in heterogeneous structures. The elements of a list, for example, are
  2281. variables. They can have different types in the same list. Heterogeneous
  2282. structures occur frequently in Icon programs. I believe the second edition
  2283. of the Icon Programming Language points out examples.
  2284.  
  2285.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  2286.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  2287.  
  2288. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Sat Nov 17 14:08:43 1990
  2289. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2290.     id AA12907; Sat, 17 Nov 90 14:08:43 -0700
  2291. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  2292.     id AA25821; Sat, 17 Nov 90 16:08:38 -0500
  2293. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sat, 17 Nov 90 16:03:27 EST
  2294. Date: Sat, 17 Nov 90 15:45:32 EST
  2295. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  2296. To: icon-group@cs.arizona.edu
  2297. Message-Id: <270830@Wayne-MTS>
  2298. Subject: Dynamic typing revisited
  2299.  
  2300.  
  2301. Thanks to all for your replies to my query on this subject.
  2302.  
  2303. Re Ralph's comment: yes, I was being sloppy in saying that the type of a
  2304. variable can change.  Viewing variables as untyped containers of arbitrary
  2305. values is both cleaner and and the correct depiction of reality.
  2306.  
  2307. Yes, you can use Icon's flexible typing structure to construct heterogeneous
  2308. lists.  But what isn't clear to me is what such lists are good for, particu-
  2309. larly when they contain values of truly arbitrary types rather than of
  2310. related types.
  2311.  
  2312. In SPLASH I have a `box' type that can designate variables of any type.  That
  2313. provides an escape from strong typing---the second approach that Dave Gudeman
  2314. suggested.  I'm still wrestling with the semantics of boxes, though.  What
  2315. prompted my query was wondering what operations you might want on a box in
  2316. addition to the image operation (in the sense of the Icon `image' procedure). 
  2317. In particular, the image operation would suffice for the trapping that Gregg
  2318. gave as an example.
  2319.  
  2320. You might think that an obvious operation on boxes would be to get a string
  2321. giving the type of the box.  But that turns out to be remarkably difficult in
  2322. the presence of recursive types.  That problem doesn't come up in Icon
  2323. because Icon doesn't have recursive types---with dynamic typing, you don't
  2324. need them.
  2325.  
  2326. To clarify: in Pascalish languages you can have something like:
  2327.     type t is record v: integer; link: ref t end
  2328. How then would you display the definition of t in a form that id independent
  2329. of the name you give the type?  In Icon the type would simply be `t' (which
  2330. actually isn't very revealing if you don't have the definition of `t' handy).     
  2331.  
  2332. By the way, Modula-3 has a `refany' type which provides an escape from strong
  2333. typing in that language.  But you can only dereference a `refany' value using
  2334. a `typecase' construction, which forces you to enumerate all the
  2335. possibilities.  That's less general than being able to apply `image' without
  2336. knowing the type.
  2337.  
  2338. Paul
  2339.  
  2340. abrahams%wayne-mts@um.cc.umich.edu 
  2341.  
  2342. From nowlin@iwtqg.att.com  Sat Nov 17 15:02:49 1990
  2343. Message-Id: <9011172202.AA14204@megaron.cs.arizona.edu>
  2344. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  2345.     id AA14204; Sat, 17 Nov 90 15:02:49 -0700
  2346. From: nowlin@iwtqg.att.com
  2347. Date: Sat, 17 Nov 90 15:39 CST
  2348. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  2349. To: att!cs.arizona.edu!icon-group
  2350. Subject: Re: Uses of dynamic typing
  2351.  
  2352. > than just prove something?
  2353.  
  2354. I have three specific examples.  The first is the use of the types "null"
  2355. and "file" in programs that can read input from files or from standard
  2356. input.  The same expressions can be used for input if the variable used as
  2357. a file is set to &null when reading from standard input.  I've used this
  2358. many times.  The same kind of scheme can be used for output.
  2359.  
  2360. The second example is a set of procedures that does regular expression
  2361. matching.  It uses a list of records.  Each record contains a pair of
  2362. values; a procedure and an argument to be passed to the procedure.
  2363. Sometimes the argument is a string, sometimes it's a cset, and sometimes
  2364. it's &null.  Icon doesn't care which I store as the second value in the
  2365. record.
  2366.  
  2367. The third use is a set of procedures I wrote for a friend.  These
  2368. procedures allow a series of global variables to be dumped into a file.  A
  2369. complementary set of procedures can read the dump file and reconstruct the
  2370. global variables with the same values as the program that dumped them.
  2371. These procedures are used to chain together a series of programs.  This
  2372. would require a whole series of different variables if Icon didn't allow me
  2373. to use the same variable over and over with different types each time.
  2374. Very handy.
  2375.  
  2376. As a side note we've just recently achieved a breakthrough at work (AT&T)
  2377. and we're now allowed to use Icon for "real" projects.  It's great.  Our
  2378. methodology calls for code inspections and those of us who are familiar
  2379. with Icon initially thought Icon would be much easier to code inspect than
  2380. C++ or C.  WRONGO!  The tie in to this subject is that dynamic typing may
  2381. contribute to the problem.  It just seems counter intuitive that Icon would
  2382. be harder to inspect but after our initial session that was definitely my
  2383. impression.  I'll try to figure out why on my own but if anyone has any
  2384. ideas throw them out.
  2385.  
  2386. Jerry Nowlin (iwtqg!nowlin)
  2387.  
  2388. From nowlin@iwtqg.att.com  Sat Nov 17 15:02:53 1990
  2389. Message-Id: <9011172202.AA14215@megaron.cs.arizona.edu>
  2390. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  2391.     id AA14215; Sat, 17 Nov 90 15:02:53 -0700
  2392. From: nowlin@iwtqg.att.com
  2393. Date: Sat, 17 Nov 90 15:51 CST
  2394. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  2395. To: att!cs.arizona.edu!icon-group
  2396. Subject: Re: Dynamic typing revisited
  2397.  
  2398. > ...
  2399. > How then would you display the definition of t in a form that is
  2400. > independent of the name you give the type?  In Icon the type would
  2401. > simply be `t' (which actually isn't very revealing if you don't have
  2402. > the definition of `t' handy).     
  2403. > ...
  2404. >  
  2405. > Paul
  2406.  
  2407. In fact, type 't' from Icon isn't that bad for some applications.  You can
  2408. get the fact that type 't' is a record by looking at the image() and then
  2409. you can just treat values of 't' like lists and generate the members or
  2410. directly subscript them.  I don't know how you'd find the specific member
  2411. names but you can get at the member values and that's more important in
  2412. most cases.
  2413.  
  2414. Jerry Nowlin (iwtqg!nowlin)
  2415.  
  2416. From att!arizona!wgg@cs.washington.edu  Sat Nov 17 15:37:18 1990
  2417. Received: from att.UUCP by megaron.cs.arizona.edu (5.61/15) via UUCP
  2418.     id AA15114; Sat, 17 Nov 90 15:37:18 -0700
  2419. Received: from june.cs.washington.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2420.     id AA14976; Sat, 17 Nov 90 15:30:40 -0700
  2421. Received: by june.cs.washington.edu (5.64/7.0jh)
  2422.     id AA16599; Sat, 17 Nov 90 14:30:35 -0800
  2423. Date: Sat, 17 Nov 90 14:30:35 -0800
  2424. From: wgg@cs.washington.edu (William Griswold)
  2425. Return-Path: <wgg@cs.washington.edu>
  2426. Message-Id: <9011172230.AA16599@june.cs.washington.edu>
  2427. To: att!cs.arizona.edu!icon-group, nowlin@iwtqg.att.com
  2428. Subject: Re: Uses of dynamic typing
  2429.  
  2430. Re: Jerry Nowlin's message
  2431.  
  2432. >As a side note we've just recently achieved a breakthrough at work (AT&T)
  2433. >and we're now allowed to use Icon for "real" projects.  It's great.  Our
  2434. >methodology calls for code inspections and those of us who are familiar
  2435. >with Icon initially thought Icon would be much easier to code inspect than
  2436. >C++ or C.  WRONGO!  The tie in to this subject is that dynamic typing may
  2437. >contribute to the problem.  It just seems counter intuitive that Icon would
  2438. >be harder to inspect but after our initial session that was definitely my
  2439. >impression.  I'll try to figure out why on my own but if anyone has any
  2440. >ideas throw them out.
  2441. >
  2442.  
  2443. To me this suggests that a language in which you could add typing information
  2444. during later phases of a project would be valuable.  Having a tool
  2445. to infer the types and insert them for you would be great, and could be
  2446. revealing in itself.  In the presence of tools like Ken Walker's Icon compiler,
  2447. this doesn't sound impractical.
  2448.  
  2449. This type information serves as constructive comments in the code.  Not
  2450. only does it tell a new programmer what is going on, but type violations
  2451. created by the programmer's changes to the code will signal that the changes
  2452. are outside the intents of the original implementation. 
  2453.  
  2454.                     bill
  2455.  
  2456. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Sun Nov 18 16:36:41 1990
  2457. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2458.     id AA03210; Sun, 18 Nov 90 16:36:41 -0700
  2459. Received: by uwm.edu; id AA23452; Sun, 18 Nov 90 09:06:31 -0600
  2460. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  2461.           Sun, 18 Nov 90 08:01:12 CDT
  2462. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  2463.           Sun, 18 Nov 1990 07:13 CDT
  2464. Date: Sun, 18 Nov 1990 07:13 CDT
  2465. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  2466. Subject: Re: Uses of dynamic typing
  2467. To: icon-group@cs.arizona.edu
  2468. Cc: icon-group@cs.arizona.edu
  2469. Message-Id: <2D4AF1A400600126@mis.mcw.edu>
  2470. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  2471. X-Envelope-To: icon-group@cs.arizona.edu,
  2472.           Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  2473. X-Vms-To: IN%"Paul_Abrahams%Wayne-MTS@um.cc.umich.edu"
  2474. X-Vms-Cc: IN%"icon-group@cs.arizona.edu"
  2475.  
  2476. Regarding:    Uses of dynamic typing
  2477.  
  2478. > ... text ...
  2479. > My question is: how important is this flexibility for Icon programming, and
  2480. > how do people utilize it?
  2481. >
  2482. > ... text ...
  2483. >
  2484. > Examples, anyone--particularly from programs that do something rather than
  2485. > just prove something?
  2486. >
  2487. > Paul Abrahams
  2488. > abrahams%wayne-mts@um.cc.umich.edu
  2489.  
  2490. Some things are implicitly utilized. Dynamic typing, in my opinion, causes
  2491. some things.
  2492.  
  2493. 1. Reduces lines of code, since many variable type declarations become
  2494.    un-necessary.
  2495. 2. Reduces code clutter from having to cast this type to that in expressions.
  2496.    Although I still find it necessary for floating point calculations.
  2497. 3. I suppose I'm just a lazy programmer, and when programming in Icon, I'm
  2498.    not fighting the datatypes. I just code away, much like I did when BASIC
  2499.    was my native computer language.
  2500. 4. No need for separate sets of procedure libraries. Well, I suppose if well
  2501.    designed, C & Pascal can have smart procedures that adapt to the type of
  2502.    data passed.
  2503.  
  2504. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  2505. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  2506. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  2507.  
  2508. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Mon Nov 19 06:27:14 1990
  2509. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2510.     id AA00165; Mon, 19 Nov 90 06:27:14 -0700
  2511. Received: by uwm.edu; id AA09863; Mon, 19 Nov 90 07:27:02 -0600
  2512. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  2513.           Mon, 19 Nov 90 06:55:13 CDT
  2514. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  2515.           Mon, 19 Nov 1990 06:19 CDT
  2516. Date: Mon, 19 Nov 1990 06:19 CDT
  2517. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  2518. Subject: Card game algorythms
  2519. To: icon-group@cs.arizona.edu
  2520. Message-Id: <EEE17FFF40600175@mis.mcw.edu>
  2521. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  2522. X-Envelope-To: icon-group@cs.arizona.edu
  2523. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  2524.  
  2525.  
  2526. I've been thinking about card game algorythms. It seems to me that cards
  2527. belong in a set rather than a list. Each hand would also be a set. Since
  2528. order in a set is arbitrary, I become a little confused as to shuffling
  2529. the deck. And even if one were to use lists, shuffling is an operational
  2530. remnant of our physical world. In a computer, virtual shuffling could
  2531. just consist of dealing cards from random deck positions.
  2532.  
  2533. Is there one basic shuffling concept, or are there several approaches?
  2534.  
  2535. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  2536. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  2537. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  2538.  
  2539.  
  2540. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Mon Nov 19 08:21:57 1990
  2541. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2542.     id AA03820; Mon, 19 Nov 90 08:21:57 -0700
  2543. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  2544.     id AA09475; Mon, 19 Nov 90 10:21:49 -0500
  2545. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Mon, 19 Nov 90 10:17:21 EST
  2546. Date: Sun, 18 Nov 90 22:36:28 EST
  2547. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  2548. To: icon-group@cs.arizona.edu
  2549. Message-Id: <270978@Wayne-MTS>
  2550. Subject: Dynamic typing (more)
  2551.  
  2552.  
  2553. To respond to various points:
  2554.  
  2555. (1) Finding a representation of dynamic types is more difficult when (a) the
  2556. types involve mutual recursions, not just one, and (b) your language has
  2557. structural equivalence rather than name equivalence (like Modula-3). 
  2558. Structurally equivalent types should have the same representation even if
  2559. their declarations use different names.  In fact, it's an interesting job
  2560. for an Icon program (given, say, a textual representation of a collection of
  2561. Modula-3 type declarations). 
  2562.  
  2563. (2) Of Jerry Nowlin's three examples, the one I find most interesting is the
  2564. third, in which global variables of arbitrary types are dumped to a file and
  2565. read back in again by another program (or another execution of the same
  2566. program, I gather).  The first two could be done with variant records,
  2567. subclasses, or what have you since there are only a small, finite number of
  2568. choices.  The third one involved a kind of inverse of `image' that
  2569. transforms an image into a value for almost any type at all (but not for
  2570. procedures, I'd guess).
  2571.  
  2572. (3) My box type in SPLASH isn't overloaded in the sense that x+y adds x and
  2573. y even if x and y are boxes containing numbers.  It will probably have an
  2574. extraction operator that extracts the variable or value contained in a box,
  2575. but I haven't figured out how to do this because I only want to permit the
  2576. extraction in a context where the type of the box's contents has been
  2577. proclaimed (using something like the Modula-3 TYPECASE statement).  But
  2578. TYPECASE doesn't work well when you have complex nested types.
  2579.  
  2580. (4) There isn't a necessary connection between compile-time typing and
  2581. operator overloading, but languages with dynamic typing generally don't seem
  2582. to have operator overloading except in the weak sense of things like
  2583. overloading + to work both on integers and reals.  In fact, Icon probably
  2584. could have been designed to use overloading more extensively and even to
  2585. make it available to users, with type declarations used in parameter lists
  2586. solely for the purpose of overload resolution.  Then you wouldn't have
  2587. different operators for lexical versus numerical comparison.  I won't try to
  2588. argue very strongly that it would be better that way, but it's an
  2589. interesting possibility that as far as I know no language designers have
  2590. considered.
  2591.  
  2592. (5) I probably should reiterate that a lot of the design of SPLASH was
  2593. inspired by Icon, and SPLASH has a lot of Icon features in it (especially
  2594. the central notions of generators and of failure as a possible outcome of
  2595. expression evaluation).  The current state of it is that the definition is
  2596. about 50 pages long and, I'd estimate, about 60% complete (which doesn't
  2597. imply that the final version will be 80 pages long).
  2598.  
  2599. Paul
  2600.  
  2601. abrahams%wayne-mts@um.cc.umich.edu 
  2602.  
  2603. From gudeman  Tue Nov 20 13:09:12 1990
  2604. Date: Tue, 20 Nov 90 13:09:12 -0700
  2605. From: "David Gudeman" <gudeman>
  2606. Message-Id: <9011202009.AA14193@megaron.cs.arizona.edu>
  2607. Received: by megaron.cs.arizona.edu (5.61/15)
  2608.     id AA14193; Tue, 20 Nov 90 13:09:12 -0700
  2609. To: icon-group@cs.arizona.edu
  2610. In-Reply-To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu's message of Sun, 18 Nov 90 22:36:28 EST <270978@Wayne-MTS>
  2611. Subject: Dynamic typing (more)
  2612.  
  2613. >Date: Sun, 18 Nov 90 22:36:28 EST
  2614. >From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  2615.  
  2616. >Structurally equivalent types should have the same representation even if
  2617. >their declarations use different names.
  2618.  
  2619. Hmm, that really isn't obvious to me.  If I declare two structurally
  2620. equivalent types with different names, then I probably have some
  2621. reason for wanting to distinguish them.  In this case I would rather
  2622. have the representations include the names explicitely.  Of course, if
  2623. type equivalence isn't the same as representation equivalence then I
  2624. would also want a predicate on representations to tell me when two
  2625. representations denote the same type.
  2626.  
  2627. >...The first two could be done with variant records,
  2628. >subclasses, or what have you since there are only a small, finite number of
  2629. >choices...
  2630.  
  2631. But what "could be done" isn't the issue.  Obviously you can do
  2632. anything in Pascal that you can do in Icon, the issue is how easy it
  2633. is to do and how easy it is to understand.  Typing in a list of
  2634. different things to do for different types is more cumbersome than
  2635. letting the language figure it out.  Strict static typing in this
  2636. sense violates one of my cardinal rules of language design: "Make the
  2637. computer do any work that it can.  The programmer should only be
  2638. required to do what the computer can't."
  2639.  
  2640. >(3) My box type in SPLASH isn't overloaded in the sense that x+y adds x and
  2641. >y even if x and y are boxes containing numbers.
  2642.  
  2643. In this case, I would say that the box type does not give you the
  2644. advantages of dynamic typing at all.  It is just an abbreviation for a
  2645. union of everything.  Incidentally, in the union approach to dynamic
  2646. typing (that is, unions-with-type-information and universal
  2647. overloading) the operators should be overloaded on all unions.  For
  2648. example if
  2649.  
  2650.   union int_or_string {int, string}
  2651.  
  2652. declares a new type "int_or_string", and I declare variables "x" and
  2653. "y" of this type, then the expression "x + y" should be understood to
  2654. do the correct thing based on the dynamic types of "x" and "y".  In
  2655. other words, there is no reason to limit this overloading to unions of
  2656. everything.
  2657.  
  2658. >(4) There isn't a necessary connection between compile-time typing and
  2659. >operator overloading, but languages with dynamic typing generally don't seem
  2660. >to have operator overloading except in the weak sense of things like
  2661. >overloading + to work both on integers and reals...
  2662.  
  2663. Icon has two ways in which an operator can work on different types:
  2664. automatic conversion and overloading.  There is actually quite a bit
  2665. of overloading, look at unary "!" and "?", subscripting, sectioning,
  2666. general comparisons ("===" and friends), member(), sort(), and copy().
  2667. The comparison operators could not be overloaded without losing some
  2668. functionality.  They are currently defined to do automatic type
  2669. conversions, which has different uses.
  2670.  
  2671. From icon-group-request@arizona.edu  Thu Nov 22 06:25:36 1990
  2672. Resent-From: icon-group-request@arizona.edu
  2673. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2674.     id AA11121; Thu, 22 Nov 90 06:25:36 -0700
  2675. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 22 Nov 90 06:25 MST
  2676. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA00781; Thu, 22 Nov 90
  2677.  05:25:07 -0800
  2678. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2679.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2680.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2681. Resent-Date: Thu, 22 Nov 90 06:25 MST
  2682. Date: 20 Nov 90 06:25:31 GMT
  2683. From: news@psuvax1.cs.psu.edu
  2684. Subject: RE: Card game algorythms
  2685. Sender: icon-group-request@arizona.edu
  2686. Resent-To: icon-group@cs.arizona.edu
  2687. To: icon-group@arizona.edu
  2688. Resent-Message-Id: <FEB4C1A24D9DA04D3D@Arizona.edu>
  2689. Message-Id: <Fe+tb1a3@cs.psu.edu>
  2690. Organization: Penn State Computer Science
  2691. X-Envelope-To: icon-group@CS.Arizona.EDU
  2692. X-Vms-To: icon-group@Arizona.edu
  2693. References: <EEE17FFF40600175@mis.mcw.edu>
  2694.  
  2695. Each hand is a set, but the deck itself is a list.  If you consider
  2696. solitaire games, then the various piles, the talon, and the stock are
  2697. all lists.  I've wanted a generalized solitaire language for a while..
  2698. --
  2699. Felix Lee    flee@cs.psu.edu
  2700.  
  2701. From icon-group-request@arizona.edu  Thu Nov 22 08:41:49 1990
  2702. Resent-From: icon-group-request@arizona.edu
  2703. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2704.     id AA16629; Thu, 22 Nov 90 08:41:49 -0700
  2705. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 22 Nov 90 08:41 MST
  2706. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA06651; Thu, 22 Nov 90
  2707.  07:28:01 -0800
  2708. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2709.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2710.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2711. Resent-Date: Thu, 22 Nov 90 08:41 MST
  2712. Date: 21 Nov 90 02:43:46 GMT
  2713. From: iris!hildum@ucdavis.ucdavis.edu
  2714. Subject: Icon I/O system and X Windows/Motif
  2715. Sender: icon-group-request@arizona.edu
  2716. Resent-To: icon-group@cs.arizona.edu
  2717. To: icon-group@arizona.edu
  2718. Resent-Message-Id: <FEA1BA85254DA03AB8@Arizona.edu>
  2719. Message-Id: <7999@ucdavis.ucdavis.edu>
  2720. Organization: U.C. Davis - Department of Electrical Engineering and Computer
  2721.  Science
  2722. X-Envelope-To: icon-group@CS.Arizona.EDU
  2723. X-Vms-To: icon-group@Arizona.edu
  2724.  
  2725. I have been looking at some articles on the X window system recently,
  2726. and am curious about the Icon communities' thoughts on how an X
  2727. Window/Motif based graphical interface would most naturally be
  2728. incorporated. I realize that the intent of Icon is the development of
  2729. high level language constructs and semantics; however, with the growing
  2730. importance of graphical interfaces, the current simple I/O system Icon
  2731. supports seems inadequate.
  2732.  
  2733. In particular, I am interested in the the effects of language
  2734. constructs and semantics such as coexpressions, suspend and resume,
  2735. generators, and failure in combination with the asynchronous model of
  2736. the X protocol.
  2737.  
  2738. Any comments on how such an interface might be built and what form it
  2739. should take?
  2740.                 dehildum@ucdavis.ucdavis.edu    (Internet)
  2741.                 dehildum@ucdavis.bitnet    (BITNET)
  2742.                 ucbvax!ucdavis!dehildum    (uucp)
  2743.  
  2744. From icon-group-request@arizona.edu  Fri Nov 23 18:29:56 1990
  2745. Resent-From: icon-group-request@arizona.edu
  2746. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2747.     id AA13934; Fri, 23 Nov 90 18:29:56 -0700
  2748. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 23 Nov 90 18:29 MST
  2749. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13064; Fri, 23 Nov 90
  2750.  17:24:52 -0800
  2751. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2752.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2753.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2754. Resent-Date: Fri, 23 Nov 90 18:29 MST
  2755. Date: 23 Nov 90 20:54:07 GMT
  2756. From: usc!bbn.com!nic!chaos.cs.brandeis.edu!iad@rutgers.edu
  2757. Subject: Help/hint needed
  2758. Sender: icon-group-request@arizona.edu
  2759. Resent-To: icon-group@cs.arizona.edu
  2760. To: icon-group@arizona.edu
  2761. Resent-Message-Id: <FD8666DAE9FDA05941@Arizona.edu>
  2762. Message-Id: <1990Nov23.205407.4570@chaos.cs.brandeis.edu>
  2763. Organization: Brandeis University Computer Science Dept
  2764. X-Envelope-To: icon-group@CS.Arizona.EDU
  2765. X-Vms-To: icon-group@Arizona.edu
  2766.  
  2767.  
  2768. SOS!
  2769.  
  2770. I've been only using Icon for about four weeks, and I'm enjoying it
  2771. more than I can tell. However, today I ran into the following problem:
  2772.  
  2773. I was trying to write a procedure that takes a list of coexpressions
  2774. (its length must be allowed to vary) and suspends lists of the
  2775. corresponding values of the arguments. For example, the call
  2776.  
  2777. f ([create 1 to 3, create "Q" | "Z"])
  2778.  
  2779. would produce the result sequence
  2780.  
  2781. { [1,"Q"], [1,"Z"], [2,"Q"], [2,"Z"], [3,"Q"], [3,"Z"] }.
  2782.  
  2783. I thought is should be easy (given the overall power of Icon), but
  2784. somehow I can't think of any way of doing it without recursion. Can
  2785. anyone give me a hint?
  2786.  
  2787. Thanks,
  2788.  
  2789. Ivan A. Derzhanski
  2790.  
  2791. P.S. My apologies if it turns out to be actually very simple.
  2792. -- 
  2793. Ivan A. Derzhanski          iad@chaos.brandeis.edu
  2794. MB 1766    Brandeis University    P.O.Box 9110    Waltham, MA 02254-9110
  2795.  
  2796. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Mon Nov 26 08:50:06 1990
  2797. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2798.     id AA02332; Mon, 26 Nov 90 08:50:06 -0700
  2799. Received: by uwm.edu; id AA20516; Mon, 26 Nov 90 09:49:54 -0600
  2800. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  2801.           Mon, 26 Nov 90 09:34:07 CDT
  2802. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  2803.           Mon, 26 Nov 1990 08:55 CDT
  2804. Date: Mon, 26 Nov 1990 08:54 CDT
  2805. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  2806. Subject: Icon in Windowing environments
  2807. To: icon-group@cs.arizona.edu
  2808. Message-Id: <84CC7215C06007E3@mis.mcw.edu>
  2809. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  2810. X-Envelope-To: icon-group@cs.arizona.edu
  2811. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  2812.  
  2813.  
  2814. Icon  seems  to  be designed around the data stream concept of the unix shell
  2815. (character cell) environment. It's not not fast enough with image processing.
  2816. I've tried it.
  2817.  
  2818. Still, here is some thinking from the keyboard. I won't mention any new
  2819. language constructs that may be needed to support it. I'm just going over
  2820. the most external look and feel of what an X-Window/Motif Icon
  2821. environment might look like ...
  2822.  
  2823. Obviously,  with a windowing interface the term 'icon' becomes overloaded. To
  2824. preserve  the  'Icon'  language we'd call the pictures objects or pix to keep
  2825. the  names  straight. These objects will have a file name squeezed into them,
  2826. and  a  user editable pictogram to make it more recognizable. Each file type,
  2827. should   have   special   distinguishing  features  to  make  them  instantly
  2828. recognizable. icont may be another object to which source and ucode is fed,
  2829. and new icode objects generated.
  2830.  
  2831. Files : (Source)
  2832.         These contain icon source code. Clicking on a source object brings
  2833.         them up in an editor window of choice.
  2834.  
  2835.         (Ucode)
  2836.         These contain the intermediate ucode. An IPATH window contains ones
  2837.         that one may want to link with.
  2838.  
  2839.         (Icode exec)
  2840.         Under unix these can be made self-starting. I'm not sure what to do
  2841.         about other operating systems. This graphical object would have input
  2842.         and output sockets (stdin & stdout always by default, others declared
  2843.         in the program). Data files have only a stdin/stdout socket pair,
  2844.         where icode files can have many sockets. These sockets should have
  2845.         'gender' and allow one to construct applications much like LEGO
  2846.         blocks.
  2847.  
  2848.         (Data files (pipes))
  2849.         These are data files or other shell filters. The icon environment
  2850.         would give them each a stdin/stdout socket pair. If the object is
  2851.         a textual data file, clicking on it should pop it into an editor
  2852.         window just like source code.
  2853.  
  2854. These are just some food for thought. I come from a VAX VMS VT100 style shop
  2855. with a few PCs and MACs laying around, so my vision may be clouded by
  2856. ignorance.
  2857.  
  2858. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  2859. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  2860. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  2861.  
  2862.  
  2863. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Mon Nov 26 08:50:21 1990
  2864. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2865.     id AA02366; Mon, 26 Nov 90 08:50:21 -0700
  2866. Received: by uwm.edu; id AA20522; Mon, 26 Nov 90 09:50:09 -0600
  2867. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  2868.           Mon, 26 Nov 90 09:34:22 CDT
  2869. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  2870.           Mon, 26 Nov 1990 09:18 CDT
  2871. Date: Mon, 26 Nov 1990 09:17 CDT
  2872. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  2873. Subject: final language construct
  2874. To: icon-group@cs.arizona.edu
  2875. Message-Id: <87FEAFB0806007E3@mis.mcw.edu>
  2876. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  2877. X-Envelope-To: icon-group@cs.arizona.edu
  2878. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  2879.  
  2880.  
  2881. Icon is a pretty nifty programming language. I like and use the 'initial'
  2882. construct. But sometimes I wished I had a 'final' construct. This may be
  2883. a crummy example, but it illustrates the concept of the final pass through
  2884. a procedure. Perhaps this isn't even implementable? Any comments on it's
  2885. usefullness or implementation problems?
  2886.  
  2887. procedure print(fo,line)
  2888.   static ff, pageno, line_count
  2889.   initial
  2890.     {
  2891.     ff := ""
  2892.     pageno := 0
  2893.     line_count := 0
  2894.     }
  2895.   if (line_count -:= 1) < 0 then
  2896.     {
  2897.     write(fo,ff,"title line ",(pageno +:= 1))
  2898.     line_count := 55
  2899.     ff := "\f"
  2900.     }
  2901.   write(fo,format(line))
  2902.   final
  2903.     {
  2904.     output_summary()
  2905.     }
  2906.   end
  2907.  
  2908. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  2909. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  2910. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  2911.  
  2912.  
  2913. From goer%sophist@gargoyle.uchicago.edu  Mon Nov 26 13:03:38 1990
  2914. Resent-From: goer%sophist@gargoyle.uchicago.edu
  2915. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2916.     id AA14510; Mon, 26 Nov 90 13:03:38 -0700
  2917. Return-Path: goer@sophist.uchicago.edu
  2918. Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 26 Nov 90 13:02 MST
  2919. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  2920.  (4.0/1.14) id AA25249; Mon, 26 Nov 90 14:02:47 CST
  2921. Received: by sophist (4.1/UofC3.1X) id AA29090; Mon, 26 Nov 90 14:06:04 CST
  2922. Resent-Date: Mon, 26 Nov 90 13:03 MST
  2923. Date: Mon, 26 Nov 90 14:06:04 CST
  2924. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  2925. Subject: final, initial
  2926. Resent-To: icon-group@cs.arizona.edu
  2927. To: icon-group@arizona.edu
  2928. Resent-Message-Id: <FB5882BD4C6DA05D84@Arizona.edu>
  2929. Message-Id: <9011262006.AA29090@sophist>
  2930. X-Envelope-To: icon-group@CS.Arizona.EDU
  2931. X-Vms-To: icon-group@Arizona.edu
  2932.  
  2933.  
  2934. In additions to initial clauses, I've often wanted to use second
  2935. clauses, thirds, fourths, as well as finals.  I guess it could go
  2936. on forever.  With "finals" the real problem seems to be how the
  2937. interpreter is supposed to know that a given call is really the
  2938. last one.  I don't see how it can know this sort of thing.
  2939.  
  2940. -Richard (goer@sophist.uchicago.edu)
  2941.  
  2942. From icon-group-request@arizona.edu  Mon Nov 26 22:47:58 1990
  2943. Resent-From: icon-group-request@arizona.edu
  2944. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2945.     id AA06914; Mon, 26 Nov 90 22:47:58 -0700
  2946. Received: from UCBVAX.Berkeley.EDU by Arizona.edu; Mon, 26 Nov 90 22:47 MST
  2947. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02485; Mon, 26 Nov 90
  2948.  21:44:23 -0800
  2949. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2950.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2951.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2952. Resent-Date: Mon, 26 Nov 90 22:47 MST
  2953. Date: 27 Nov 90 05:30:22 GMT
  2954. From: iris!hildum@ucdavis.ucdavis.edu
  2955. Subject: RE: final, initial
  2956. Sender: icon-group-request@arizona.edu
  2957. Resent-To: icon-group@cs.arizona.edu
  2958. To: icon-group@arizona.edu
  2959. Resent-Message-Id: <FB06DC0653EDA06F20@Arizona.edu>
  2960. Message-Id: <8008@ucdavis.ucdavis.edu>
  2961. Organization: U.C. Davis - Department of Electrical Engineering and Computer
  2962.  Science
  2963. X-Envelope-To: icon-group@CS.Arizona.EDU
  2964. X-Vms-To: icon-group@Arizona.edu
  2965. References: <9011262006.AA29090@sophist>
  2966.  
  2967.  
  2968. Two cents worth: probably the only way to do this is to have the
  2969. interpreter invoke the final clauses as part of the program
  2970. termination. This leads to the following issues:
  2971.  
  2972. 1. Error termination - are final clauses executed?
  2973.  
  2974. 2. What order are multiple final clauses executed - the order in which
  2975. the procedures were first invoked?
  2976.  
  2977. Of course, all this can be handled by placing the appropriate calls at
  2978. the "end" of the program, so I am not sure this really helps (other
  2979. than grouping code...)
  2980.  
  2981. If you are actually trying to execute the code as part of the final
  2982. call, I suspect that it cannot be done. It looks suspicously like a
  2983. halting problem to me...
  2984.  
  2985.                     Eric
  2986.                 dehildum@ucdavis.ucdavis.edu    (Internet)
  2987.                 dehildum@ucdavis.bitnet    (BITNET)
  2988.                 ucbvax!ucdavis!dehildum    (uucp)
  2989.  
  2990. From nowlin@iwtqg.att.com  Tue Nov 27 08:49:45 1990
  2991. Message-Id: <9011271549.AA28956@megaron.cs.arizona.edu>
  2992. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  2993.     id AA28956; Tue, 27 Nov 90 08:49:45 -0700
  2994. From: nowlin@iwtqg.att.com
  2995. Date: Tue, 27 Nov 90 08:05 CST
  2996. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  2997. To: icon-group@cs.arizona.edu
  2998. Subject: Re: help/hint needed
  2999.  
  3000. > Date: 23 Nov 90 20:54:07 GMT
  3001. > From: usc!bbn.com!nic!chaos.cs.brandeis.edu!iad@rutgers.edu
  3002. > Subject: Help/hint needed
  3003. >
  3004. > SOS!
  3005. >
  3006. > I've been only using Icon for about four weeks, and I'm enjoying it
  3007. > more than I can tell. However, today I ran into the following problem:
  3008. >
  3009. > I was trying to write a procedure that takes a list of coexpressions
  3010. > (its length must be allowed to vary) and suspends lists of the
  3011. > corresponding values of the arguments. For example, the call
  3012. >
  3013. > f ([create 1 to 3, create "Q" | "Z"])
  3014. >
  3015. > would produce the result sequence
  3016. >
  3017. > { [1,"Q"], [1,"Z"], [2,"Q"], [2,"Z"], [3,"Q"], [3,"Z"] }.
  3018. >
  3019. > I thought is should be easy (given the overall power of Icon), but
  3020. > somehow I can't think of any way of doing it without recursion. Can
  3021. > anyone give me a hint?
  3022. >
  3023. > Thanks,
  3024. >
  3025. > Ivan A. Derzhanski
  3026. >
  3027. > P.S. My apologies if it turns out to be actually very simple.
  3028. > -- 
  3029. > Ivan A. Derzhanski          iad@chaos.brandeis.edu
  3030. > MB 1766    Brandeis University    P.O.Box 9110    Waltham, MA 02254-9110
  3031.  
  3032. Admittedly coexpressions are not a piece of Icon I use much.  I can't think
  3033. of a way to do this with coexpressions without recursing either.  But I
  3034. stopped and asked my self why should I use coexpressions if what I want is
  3035. all the possible combinations of a list of generators?  Maybe the example
  3036. you used was oversimplifying your problem but the following program
  3037. generates the sequences you asked for without even requiring a procedure:
  3038.  
  3039.     procedure main()
  3040.  
  3041.         every l :=
  3042.  
  3043.         [1 to 3, "Q" | "Z"]
  3044.  
  3045.         do {
  3046.             writes("[ ")
  3047.             every writes(!l," ")
  3048.             write("]")
  3049.         }
  3050.  
  3051.     end
  3052.  
  3053. This isn't the normal coding style I'd use but it isolates the piece of
  3054. code that's pertinent to the original question.  To make this more general
  3055. you can use a procedure but it's a simple procedure.  The following is the
  3056. same basic program but with a procedure call.  The key is to use a list of
  3057. generators instead of a list of coexpressions.  I just prefer to simplify.
  3058.  
  3059.     procedure main()
  3060.  
  3061.         every l :=
  3062.  
  3063.         f( [1 to 3, "Q" | "Z"] )
  3064.  
  3065.         do {
  3066.             writes("[ ")
  3067.             every writes(!l," ")
  3068.             write("]")
  3069.         }
  3070.  
  3071.     end
  3072.  
  3073.     procedure f(lg)
  3074.  
  3075.         suspend lg
  3076.  
  3077.     end
  3078.  
  3079. This seems almost too easy so if I've really missed the point please let me
  3080. know.  Otherwise, isn't Icon great!
  3081.  
  3082. Jerry Nowlin
  3083. (att!iwtqg!nowlin)
  3084.  
  3085. From nowlin@iwtqg.att.com  Tue Nov 27 08:49:53 1990
  3086. Message-Id: <9011271549.AA28965@megaron.cs.arizona.edu>
  3087. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  3088.     id AA28965; Tue, 27 Nov 90 08:49:53 -0700
  3089. From: nowlin@iwtqg.att.com
  3090. Date: Tue, 27 Nov 90 08:59 CST
  3091. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  3092. To: icon-group@cs.arizona.edu
  3093. Subject: Re: hints...
  3094.  
  3095. >     procedure main()
  3096. >         every l :=
  3097. >         [1 to 3, "Q" | "Z"]
  3098. >         do {
  3099. >             writes("[ ")
  3100. >             every writes(!l," ")
  3101. >             write("]")
  3102. >         }
  3103. >     end
  3104. > ...
  3105. > This seems almost too easy so if I've really missed the point please let
  3106. > me know.  Otherwise, isn't Icon great!
  3107.  
  3108. Forget the procedure example (not shown).  In fact, forget the whole
  3109. solution unless you can use constant lists of generators as above.
  3110.  
  3111.     Rule #1 - When something seems too easy to be true, it is.
  3112.  
  3113. The generation that makes this work is driven by goal directed evaluation
  3114. in the context of the every.  It works the way I thought it did almost but
  3115. requires a constant list of generators in that context.  If you assign a
  3116. list of generators to a variable and use the variable in this construct it
  3117. won't generate the result sequence wanted.  This requires more thought. 
  3118. Too bad I have real work to do!
  3119.  
  3120. Jerry
  3121.  
  3122. From icon-group-request@arizona.edu  Tue Nov 27 14:33:40 1990
  3123. Resent-From: icon-group-request@arizona.edu
  3124. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  3125.     id AA15180; Tue, 27 Nov 90 14:33:40 -0700
  3126. Received: from UCBVAX.Berkeley.EDU by Arizona.edu; Tue, 27 Nov 90 14:32 MST
  3127. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA21614; Tue, 27 Nov 90
  3128.  13:21:42 -0800
  3129. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3130.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3131.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3132. Resent-Date: Tue, 27 Nov 90 14:32 MST
  3133. Date: 27 Nov 90 17:25:25 GMT
  3134. From: ingr!@uunet.uu.net
  3135. Subject: RE: WHAT ARE ICONS
  3136. Sender: icon-group-request@arizona.edu
  3137. Resent-To: icon-group@cs.arizona.edu
  3138. To: icon-group@arizona.edu
  3139. Resent-Message-Id: <FA82CFE70ACDA06D27@Arizona.edu>
  3140. Message-Id: <1805@b15.INGR.COM>
  3141. Organization: Intergraph Huntsville
  3142. X-Envelope-To: icon-group@CS.Arizona.EDU
  3143. X-Vms-To: icon-group@Arizona.edu
  3144. References: <13119021:11:45GB03@lehigh.bitnet>
  3145.  
  3146. In <13119021:11:45GB03@lehigh.bitnet> GB03@Lehigh writes:
  3147.  
  3148. :It might interest most people to know that BASIC was originally BASIC.
  3149. :Kemeny and Kurtz got tired of telling people it was only BASIC.  No one
  3150. :believed the inventors.  They finally came up with Beginners All
  3151. :Purpose Simplified Code
  3152.  
  3153. The American Heritage Dictionary (2nd College Edition, 1985) says:
  3154.  
  3155.     Beginner's All-purpose Symbolic Instruction Code
  3156.  
  3157. From nowlin@iwtqg.att.com  Tue Nov 27 20:46:12 1990
  3158. Message-Id: <9011280346.AA29841@megaron.cs.arizona.edu>
  3159. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  3160.     id AA29841; Tue, 27 Nov 90 20:46:12 -0700
  3161. From: nowlin@iwtqg.att.com
  3162. Date: Tue, 27 Nov 90 17:16 CST
  3163. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  3164. To: icon-group@cs.arizona.edu
  3165. Subject: Re: final clause
  3166.  
  3167. > Icon is a pretty nifty programming language. I like and use the 'initial'
  3168. > construct. But sometimes I wished I had a 'final' construct. This may be
  3169. > a crummy example, but it illustrates the concept of the final pass through
  3170. > a procedure. Perhaps this isn't even implementable? Any comments on it's
  3171. > usefulness or implementation problems?
  3172.  
  3173. I don't see anyway to implement a final clause.  You might have the
  3174. interpreter go through all the declared procedures when it's told to
  3175. terminate and execute the final clauses.  Even then how do you know that
  3176. the order of execution of final clauses isn't significant?  How would you
  3177. handle run time errors or external interrupts?
  3178.  
  3179. If that won't work, how could the interpreter possibly know that a
  3180. procedure won't be executed again?  I don't think procedures ever go out of
  3181. scope in Icon so that's not a valid criteria.  What happens when you
  3182. declare a variable with the same name as a procedure?  What happens when a
  3183. procedure is assigned to a variable?  I don't see any way to do this.
  3184. Is this an attempt to get construction and destruction type constructs for
  3185. procedures?
  3186.  
  3187. > procedure print(fo,line)
  3188. >   static ff, pageno, line_count
  3189. >   initial
  3190. >     {
  3191. >     ff := ""
  3192. >     pageno := 0
  3193. >     line_count := 0
  3194. >     }
  3195. >   if (line_count -:= 1) < 0 then
  3196. >     {
  3197. >     write(fo,ff,"title line ",(pageno +:= 1))
  3198. >     line_count := 55
  3199. >     ff := "\f"
  3200. >     }
  3201. >   write(fo,format(line))
  3202. >   final
  3203. >     {
  3204. >     output_summary()
  3205. >     }
  3206. >   end
  3207.  
  3208. The example above has some problems since the output_summary() procedure is
  3209. called as part of the final clause but it isn't passed the parameters that
  3210. were initialized in the initial clause.  I get the idea though.  This could
  3211. be handled by making the 'fo' and 'line' parameters optional.  If they're
  3212. missing invoke the equivalent of the final clause.  I use optional
  3213. parameters frequently although not usually for this kind of thing.
  3214.  
  3215. Jerry Nowlin
  3216. (...!att!iwtqg!nowlin)
  3217.  
  3218. From djbailey@skyler.mavd.honeywell.com  Wed Nov 28 09:51:09 1990
  3219. Message-Id: <9011281651.AA25093@megaron.cs.arizona.edu>
  3220. Received: from skyler.mavd.honeywell.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  3221.     id AA25093; Wed, 28 Nov 90 09:51:09 -0700
  3222. Date: 28 Nov 90 10:49:00 CDT
  3223. From: "BAILEY, DON" <djbailey@skyler.mavd.honeywell.com>
  3224. Subject: Re: final clause
  3225. To: "icon-group" <icon-group@cs.arizona.edu>
  3226.  
  3227. Has anyone else suggested the simple brute force solution to implementing
  3228. a "final" clause?  Just push your program down a level in the calling 
  3229. sequence.  For example,
  3230.  
  3231. procedure main(args)
  3232. #
  3233. my_real_program(args,final_parameter_list)
  3234. do_final_work(final_parameter_list)
  3235. end
  3236.  
  3237. The real program can have an initial clause if it really needs it.
  3238. Whenever it finishes, "do_final_work" will be called. At worst, you
  3239. have to make some extra data global and deal with the success or 
  3240. failure of your program.  This approach lets you invoke different
  3241. final processing, by adding an "if", depending on success or failure 
  3242. or a state variable you pass back up.
  3243.  
  3244. -- Don J. Bailey  (djbailey@skyler.mavd.honeywell.com)
  3245.  
  3246.  
  3247.  
  3248. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Wed Nov 28 13:17:15 1990
  3249. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  3250.     id AA04749; Wed, 28 Nov 90 13:17:15 -0700
  3251. Received: by uwm.edu; id AA10695; Wed, 28 Nov 90 14:16:58 -0600
  3252. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  3253.           Wed, 28 Nov 90 14:00:48 CDT
  3254. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  3255.           Wed, 28 Nov 1990 13:00 CDT
  3256. Date: Wed, 28 Nov 1990 13:00 CDT
  3257. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  3258. Subject: The Final Clause
  3259. To: icon-group@cs.arizona.edu
  3260. Message-Id: <396C1E3A80400B3F@mis.mcw.edu>
  3261. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  3262. X-Envelope-To: icon-group@cs.arizona.edu
  3263. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  3264.  
  3265.  
  3266. Regarding : The Final Clause
  3267.  
  3268. I've seen a lot of interesting replies on this problem. Some say it's not
  3269. possible because it's 'decidable'. Someone else mentioned the 'halting
  3270. problem', which I assume refers to Turing machines. How does a procedure
  3271. 'know' when it's finally called? Also the example I furnished wasn't very
  3272. good, but I can't seem to think of another at the moment. I didn't think
  3273. it would have been such a big deal. After all, how does program know when
  3274. it's reached the end of file or pipe? (The operating system tells it).
  3275. I also thought that since Icon is a virtual machine, that its extensibility
  3276. would allow something like the Variant Translator or Personal Interpreter
  3277. to handle it.
  3278.  
  3279. Practically, though, the method I envisioned was that Icon would do a silent
  3280. run, recording activity to a journal (much like MEMMON). Upon exit, the final
  3281. clause(s) would be inserted into the journal stream, and then the whole mess
  3282. flushed (kind of like a database commit).
  3283.  
  3284. I thought about that a bit, and I guessed it would gobble tons of memory/disk
  3285. and cause everything to run slow. I also dreaded permutations with 'final's
  3286. getting tied up in recursive infinite loops. I also considered limiting it
  3287. to one 'final' per program, or allowing only in main(), but that really did
  3288. not seem too useful.
  3289.  
  3290. I guess the best approach is to use a procedure final() called near the end
  3291. of main() using passed or global variables. Thanx for all the ideas.
  3292.  
  3293. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  3294. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  3295. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  3296.  
  3297. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Sat Dec  1 11:47:20 1990
  3298. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  3299.     id AA25239; Sat, 1 Dec 90 11:47:20 -0700
  3300. Received: by uwm.edu; id AA18340; Sat, 1 Dec 90 12:46:59 -0600
  3301. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  3302.           Sat,  1 Dec 90 12:22:02 CDT
  3303. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  3304.           Sat, 1 Dec 1990 08:48 CDT
  3305. Date: Sat, 1 Dec 1990 08:48 CDT
  3306. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  3307. Subject: A more useful concept
  3308. To: icon-group@cs.arizona.edu
  3309. Message-Id: <71AFB0BFE0401C1A@mis.mcw.edu>
  3310. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  3311. X-Envelope-To: icon-group@cs.arizona.edu
  3312. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  3313.  
  3314.  
  3315.  
  3316. In the past icon has been getting better and better. For example there's
  3317. now a remove(filespec) procedure to delete files which is better than
  3318.                             system("rm "||filespec)
  3319.  
  3320. and I think there's also a rename(ofile,nfile) instead of
  3321.                        system("mv "||ofile||" "||nfile)
  3322.  
  3323. I think it would be nice to have a few more file management primitives. Oh oh,
  3324. maybe they already exist, and I should just read the manual?
  3325.  
  3326. cpfile(oldfile,newfile)         # copy files
  3327. appfile(oldfile,existingfile)   # append files together
  3328. listvar := dir(path)            # generate a list of file names (directory)
  3329. freedisk:= df(dspec)            # returns number of blocks of free disk
  3330.                                   like unix df or vms show dev/mount
  3331.  
  3332. ----
  3333.  
  3334. Also there are the environmental variables that are accessible with
  3335. getenv(), and known as logicals to VMS people.
  3336.  
  3337. Is it possible to capture aliases (symbols to vms people)? Or doesn't that
  3338. sound like a useful enough feature?
  3339.  
  3340.  
  3341. From icon-group-request@arizona.edu  Tue Dec  4 14:36:50 1990
  3342. Resent-From: icon-group-request@arizona.edu
  3343. Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  3344.     id AA06044; Tue, 4 Dec 90 14:36:50 -0700
  3345. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 4 Dec
  3346.  1990 14:36 MST
  3347. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA00435; Tue, 4 Dec 90 13:24:37
  3348.  -0800
  3349. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3350.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3351.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3352. Resent-Date: Tue, 4 Dec 1990 14:36 MST
  3353. Date: 4 Dec 90 19:26:00 GMT
  3354. From: timbuk!cs.umn.edu!mmm.serc.3m.com!us269574@uunet.uu.net (Darryn J. Kozak)
  3355. Subject: Is ICON the successor to SNOBOL?
  3356. Sender: icon-group-request@arizona.edu
  3357. Resent-To: icon-group@cs.arizona.edu
  3358. To: icon-group@arizona.edu
  3359. Resent-Message-Id: <FDDB0097CC4004B1@Arizona.edu>
  3360. Message-Id: <1990Dec4.192600.16430@mmm.serc.3m.com>
  3361. X-Envelope-To: icon-group@CS.Arizona.EDU
  3362. X-Vms-To: icon-group@Arizona.edu
  3363. Organization: 3M - St. Paul, MN  55144-1000 US
  3364.  
  3365. Is ICON the successor to SNOBOL?
  3366.  
  3367.         Darryn Kozak
  3368.  
  3369.         3M Center
  3370.         260-4A-08
  3371.         St. Paul, MN 55144
  3372.  
  3373.         phone:          612-733-3271
  3374.         email:          us269574@mmm.3m.com or kozak@umn-cs.edu
  3375.         FAX:            612-737-3213
  3376.  
  3377. From goer%sophist@gargoyle.uchicago.edu  Wed Dec  5 10:05:04 1990
  3378. Resent-From: goer%sophist@gargoyle.uchicago.edu
  3379. Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  3380.     id AA21479; Wed, 5 Dec 90 10:05:04 -0700
  3381. Return-Path: goer@sophist.uchicago.edu
  3382. Received: from gargoyle.uchicago.edu by Arizona.edu with PMDF#10282; Wed, 5 Dec
  3383.  1990 10:03 MST
  3384. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  3385.  (4.0/1.14) id AA13345; Wed, 5 Dec 90 11:03:29 CST
  3386. Received: by sophist (4.1/UofC3.1X) id AA05261; Wed, 5 Dec 90 11:06:47 CST
  3387. Resent-Date: Wed, 5 Dec 1990 10:04 MST
  3388. Date: Wed, 5 Dec 90 11:06:47 CST
  3389. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  3390. Subject: Snobol -> Icon
  3391. Resent-To: icon-group@cs.arizona.edu
  3392. To: icon-group@arizona.edu
  3393. Resent-Message-Id: <A1006ED19C400F44@Arizona.edu>
  3394. Message-Id: <9012051706.AA05261@sophist>
  3395. X-Envelope-To: icon-group@CS.Arizona.EDU
  3396. X-Vms-To: icon-group@Arizona.edu
  3397.  
  3398.  
  3399. (I didn't see anyone else respond, and it seems worthwhile, I'll
  3400. try to answer this question.  Note that I am not part of the Icon
  3401. Project, and that some of what I say may not be entirely accurate
  3402. :-)).
  3403.  
  3404. Re:  Is ICON the successor to SNOBOL?
  3405.  
  3406. Sure.  They started working on SL5, but suddenly felt inspired with
  3407. the knowledge that the backtracking mechanisms found in string scan-
  3408. ning could be superimposed on a consistent, general-purpose program-
  3409. ming language with a modern, procedurally oriented program struc-
  3410. ture.  Icon is, at once, like Snobol string processing gone wild, and
  3411. at the same time like languages such as C and Pascal.  I've also heard
  3412. it described as an Algolish Prolog as well, because it essentially im-
  3413. plements a backtracking mechanism somewhat like that of Prolog in
  3414. terms of control structures we all know and "love."  It is not really
  3415. quite a *successor* to Snobol, but it is certainly a logical step
  3416. forward.  I don't believe SL5 (which *would* have been the successor
  3417. to SNOBOL4) was ever released.
  3418.  
  3419. If you know Snobol, don't expect the conversion to be immediate.
  3420. You can write a 3-line Arb() procedure, if you like.  But it's not
  3421. built in.  Icon offers low-level tools with which to construct your
  3422. own matching functions.  It is very flexible, but what I'm trying to
  3423. say is that, at first, Snobol programmers often feel a bit lost.
  3424.  
  3425. Perhaps some former Snobol-ers can comment on this statement.
  3426.  
  3427. Icon is nice in the sense that it runs on almost all small and mid-range
  3428. machines, and on many high-end ones.  It's very portable, and is pretty
  3429. much free.
  3430.  
  3431. -Richard
  3432.  
  3433. From icon-group-request@arizona.edu  Wed Dec  5 23:33:53 1990
  3434. Resent-From: icon-group-request@arizona.edu
  3435. Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  3436.     id AA10370; Wed, 5 Dec 90 23:33:53 -0700
  3437. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 5 Dec
  3438.  1990 23:33 MST
  3439. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11733; Wed, 5 Dec 90 22:18:49
  3440.  -0800
  3441. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3442.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3443.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3444. Resent-Date: Wed, 5 Dec 1990 23:33 MST
  3445. Date: 6 Dec 90 02:03:04 GMT
  3446. From: att!linac!pacific.mps.ohio-state.edu!zaphod.mps.ohio-state.edu!van-bc!ubc-cs!alberta!herald.usask.ca!skorpio!gulati@ucbvax.Berkeley.EDU
  3447.  (Neeraj Gulati)
  3448. Subject: Just a test ...
  3449. Sender: icon-group-request@arizona.edu
  3450. Resent-To: icon-group@cs.arizona.edu
  3451. To: icon-group@arizona.edu
  3452. Resent-Message-Id: <120BE8FBBC4010BB@Arizona.edu>
  3453. Message-Id: <1990Dec6.020304.18013@herald.usask.ca>
  3454. X-Envelope-To: icon-group@CS.Arizona.EDU
  3455. X-Vms-To: icon-group@Arizona.edu
  3456. Organization: University of Saskatchewan
  3457.  
  3458.  
  3459.  Please ignore !!
  3460.  
  3461. From icon-group-request@arizona.edu  Thu Dec  6 07:34:40 1990
  3462. Resent-From: icon-group-request@arizona.edu
  3463. Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  3464.     id AA26318; Thu, 6 Dec 90 07:34:40 -0700
  3465. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec
  3466.  1990 07:34 MST
  3467. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19462; Thu, 6 Dec 90 06:21:58
  3468.  -0800
  3469. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3470.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3471.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3472. Resent-Date: Thu, 6 Dec 1990 07:34 MST
  3473. Date: 6 Dec 90 12:33:55 GMT
  3474. From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu
  3475.  (Norman H. Azadian)
  3476. Subject: Klondike card game, version 1.41.  part 1/4
  3477. Sender: icon-group-request@arizona.edu
  3478. Resent-To: icon-group@cs.arizona.edu
  3479. To: icon-group@arizona.edu
  3480. Resent-Message-Id: <553247FFCC4022BE@Arizona.edu>
  3481. Message-Id: <1687@hslrswi.UUCP>
  3482. X-Envelope-To: icon-group@CS.Arizona.EDU
  3483. X-Vms-To: icon-group@Arizona.edu
  3484. Organization: Hasler AG
  3485.  
  3486. This is a new version of the solitaire card game that I posted some
  3487. months ago.  This one improved ICONisms, an improved user interface,
  3488. and a much better chance of actually running on any ANSI terminal.
  3489. There is even a man page, klondike.man, included in this message.
  3490.  
  3491. The source is now split into three files:
  3492.  
  3493.     klondike.icn    main program, top-level user-interface routines
  3494.     kloncon.icn    console I/O subroutines
  3495.     klonsub.icn    assorted other subroutines
  3496.  
  3497. To execute from scratch, I believe the following suffices:
  3498.  
  3499.     icont -c kloncon klonsub
  3500.     icont klondike
  3501.     iconx klondike  <<any options here>>
  3502.  
  3503. Should you wish to peruse the source, use a tab interval of 4, not 8.
  3504.  
  3505. NHA
  3506. ---
  3507. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  3508. X.400:  naz@hslrswi.hasler
  3509. UUCP:   ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
  3510. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  3511.  
  3512. --------------- cut here -------------------- cut here ---------------------
  3513.  
  3514.     NAME
  3515.         klondike -- one of the many versions of solitaire
  3516.  
  3517.     SYNOPSIS
  3518.         klondike  -[ACD]  [-B gameCount]  [-R randomSeed]
  3519.  
  3520.     DESCRIPTION
  3521.         This is actually a popular variation on the Klondike version of
  3522.         Solitaire (or Patience) as described on page 181 of my 1963
  3523.         version of "Hoyle's Rules of Games".  The difference is that
  3524.         here we go through the deck (stock) 3 cards at a time instead
  3525.         of one-by-one, and we allow it any number of times.
  3526.  
  3527.         It should run on any ANSI-compatible terminal, but it looks
  3528.         best on a PC, preferably color.
  3529.  
  3530.     OPTIONS
  3531.         Options may be either upper or lower case.  They may be given
  3532.         in any order.  Parameters follow their options with whitespace
  3533.     inbetween.  Each option must be given as a separate argument.
  3534.  
  3535.         -A      disables automatically putting uncovered Ace cards
  3536.                 on the appropriate pile.  Note that, in any case, it is
  3537.                 not allowed to put an Ace onto a stack, as this could lead
  3538.                 to building stacks which are too big to display with 25 lines.
  3539.  
  3540.     -B count
  3541.         Batch mode.  The requested number of games is played and
  3542.         the average number of cards promoted to the ace piles is
  3543.         written to the standard output.  No other I/O is performed.
  3544.  
  3545.         -C      disable the "click" for silent games
  3546.  
  3547.         -D      enable special debugging commands which, among other things,
  3548.                 allow one to cheat
  3549.  
  3550.         -R seed
  3551.         set the random seed to the designated value
  3552.  
  3553.     COMMANDS
  3554.         H or ?  display a Help screen
  3555.  
  3556.         ^L      (control-L) redraws the screen
  3557.  
  3558.         A       Automatic mode.  Plays the game until nothing useful
  3559.         remains to be done, or until any key is struck.
  3560.  
  3561.         B       Boss key.  The screen is blanked and the current position
  3562.                 is saved.  When the game is started again in the usual
  3563.                 way, this saved game will be automatically restored and
  3564.         the save file deleted.
  3565.  
  3566.         C       Continuous mode.  The computer plays games automatically
  3567.                 until a key is struck.  Two statistics are displayed:
  3568.                 the number of games already played, and the total number
  3569.                 of aces which have been promoted to the ace piles.
  3570.  
  3571.         M       Move a card from the deck or a stack to a stack or an
  3572.                 ace pile.
  3573.  
  3574.         Q       Quit this game, with the opportunity to play another.
  3575.  
  3576.         S       Suggest a possible move.  Hitting this key multiple times
  3577.                 results in multiple suggestions being displayed.  When
  3578.                 there is nothing interesting left to do, it will suggest
  3579.                 "Thumb".
  3580.  
  3581.         T       Thumb.  Remove the top 3 cards from the face-down deck
  3582.         and lay them face-up on the face-up deck.
  3583.  
  3584.         U       Undo.  This can be used all the way back to the start
  3585.                 of the current game.
  3586.  
  3587.         Z       Debug.  This is only enabled when the -D option has
  3588.                 been given on the command line.  There is a sub-menu
  3589.                 of commands available, including a (very brief) Help
  3590.                 summary.
  3591.  
  3592.         The Move command takes two parameters: source and destination.
  3593.         Possible sources are:  D for the Deck of face-up cards; and a
  3594.         number from 1 to 7 inclusive, meaning the corresponding stack.
  3595.         Possible destinations are the stacks (1-7) and A for the
  3596.         appropriate ace pile.  For instance, to move the visible card
  3597.         from the face-up deck to stack 4, one types the three characters:
  3598.         "MD4".  Actually, the "M" character itself is optional, which
  3599.         explains why the "debug" command isn't invoked with a "D".
  3600.  
  3601.     BUGS
  3602.         Slow.
  3603.         Doesn't use termcap for maximum portability.
  3604.         The program's play is simplistic, with no concept of strategy.
  3605.  
  3606.  
  3607.     FILES
  3608.         klondike.sav    Position is checkpointed here when the Boss key is used.
  3609.         klondike.sv?    Position checkpointed here with the "S" debug command.
  3610.                         "?" can be any (upper-case) character legal in your
  3611.                         filesystem.
  3612.  
  3613.     ACKNOWLEDGEMENT
  3614.         The inspiration, name, and user interface were lifted
  3615.         wholesale from a game copyrighted in 1985 by Allyn Wade.
  3616.  
  3617.     VERSION
  3618.         1.41 -- 26 November, 1990
  3619.  
  3620.     AUTHOR
  3621.         Norman H. Azadian
  3622.         naz@hslrswi
  3623. -- 
  3624. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  3625. X.400:  naz@hslrswi.hasler
  3626. UUCP:   ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
  3627. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  3628.  
  3629. From icon-group-request@arizona.edu  Thu Dec  6 07:35:40 1990
  3630. Resent-From: icon-group-request@arizona.edu
  3631. Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  3632.     id AA26388; Thu, 6 Dec 90 07:35:40 -0700
  3633. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec
  3634.  1990 07:34 MST
  3635. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19656; Thu, 6 Dec 90 06:32:50
  3636.  -0800
  3637. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3638.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3639.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3640. Resent-Date: Thu, 6 Dec 1990 07:34 MST
  3641. Date: 6 Dec 90 12:43:12 GMT
  3642. From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu
  3643.  (Norman H. Azadian)
  3644. Subject: klondike, version 1.41.  part 3/4
  3645. Sender: icon-group-request@arizona.edu
  3646. Resent-To: icon-group@cs.arizona.edu
  3647. To: icon-group@arizona.edu
  3648. Resent-Message-Id: <55429BAFCC401D40@Arizona.edu>
  3649. Message-Id: <1689@hslrswi.UUCP>
  3650. X-Envelope-To: icon-group@CS.Arizona.EDU
  3651. X-Vms-To: icon-group@Arizona.edu
  3652. Organization: Hasler AG
  3653.  
  3654.  
  3655. #kloncon.icn    901029    NHA
  3656. # Console interface routines for Klondike
  3657. # Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display.
  3658. #
  3659. # TO FIX:
  3660. #
  3661. #
  3662. # TO DO:
  3663. #
  3664. # -    termcap for portability ??
  3665. # -    click for each card moved in a stack ?
  3666. #
  3667.  
  3668.  
  3669. # constants
  3670. global    suitID                                        #suit identification chars
  3671. global    isDOS                                        # 1 when running under DOS
  3672. global    monochrome                                    # 1 when running Black&White
  3673. # Video control strings (ANSI.SYS)
  3674. global  ESC
  3675. global    Vnormal, Vreverse, Vblink, Vbold, VclearAll, VclearEOL, Vbell
  3676. global    color                                        #list of suit color strings
  3677.  
  3678.  
  3679. #    i n i t C o n s t a n t s
  3680. # Initialize the program "constants".  These are actually variables that
  3681. # are set just once at the beginning of the world.
  3682. procedure initConstants ()
  3683. local i
  3684. local Vred, Vblack                                #suit color strings
  3685.  
  3686.     if \invisible  then  return
  3687.  
  3688.     #ensure that we are dealing with an ANSI-compatible screen
  3689.     writes ("\33[6n")                        #request cursor position report
  3690.     #NOTE that the first character to match should be an ESCape.
  3691.     #Unfortunately, reads() seems to eat that character
  3692.     match ("[", reads (&input, 8))  |
  3693.         stop ("Klondike:  requires ANSI.SYS screen driver")
  3694.  
  3695.     isDOS := find("MS-DOS", &host)
  3696.  
  3697.     if \isDOS  then  {
  3698.         i := ord (Peek([16r40, 16r49]))            #BIOS display mode byte
  3699.         case i  of  {
  3700.             2        :    monochrome := 1
  3701.             3        :    monochrome := &null        #living color
  3702.             7        :    monochrome := 1
  3703.             default    :    stop ("Klondike:  unknown display mode ", i)
  3704.         }
  3705.     } else
  3706.         monochrome := 1
  3707.  
  3708.     ESC            := "\33"                    #escape character
  3709.     VclearAll    := "\33[2J"                    #also homes cursor
  3710.     VclearEOL    := "\33[K"
  3711.     Vnormal        := "\33[0m"
  3712.     Vbold        := "\33[1m"
  3713.     Vblink        := "\33[5m"
  3714.     Vreverse    := "\33[7m"
  3715.     Vbell        := "\^G"
  3716.     if \monochrome  then  {
  3717.         Vred    := Vnormal
  3718.         Vblack    := Vreverse
  3719.     } else {
  3720.         Vred    := "\33[0;47;31m"            # "extra" 0 seems to be necessary
  3721.         Vblack    := "\33[0;47;30m"
  3722.     }
  3723.  
  3724.     # Suits are: 1=Hearts, 2=Diamonds, 3=Clubs, 4=Spades
  3725.     suitID := if \isDOS  then  "\3\4\5\6"  else  "HDCS"
  3726.     color  := [Vred, Vred, Vblack, Vblack]
  3727. end                                            #initConstants
  3728.  
  3729.  
  3730. #    i n i t S c r e e n
  3731. # Initialize output and write the fixed parts of the screen.
  3732. # initConstants() must have been called earlier.
  3733. procedure initScreen ()
  3734. local i
  3735. static vertical
  3736. initial {
  3737.     vertical  :=  if \isDOS  then  "\272"  else  "|"
  3738. }
  3739.  
  3740.     if \invisible  then  return
  3741.     if \monochrome  then  writes ("\33[=2h")        #25x80 B&W   text mode
  3742.     else  writes ("\33[=3h")                        #25x80 color text mode
  3743.  
  3744.     writes (VclearAll, "\33[=7l")                    #clear screen, prevent wrap
  3745.  
  3746.     every  i := 1 to 7  do
  3747.         writeStackNumber (i, Vnormal)
  3748.     every  i := 2 to 25  do
  3749.         writes ("\33[",i,";64H", vertical)
  3750.     if \isDOS  then
  3751.         writes ("\33[2;64H\311\315\315\315\315SOLITAIRE\315\315\315\315")
  3752.     else
  3753.         writes ("\33[2;64H=====SOLITAIRE====")
  3754. end                                            #initScreen
  3755.  
  3756.  
  3757. #    w r i t e S t a c k N u m b e r
  3758. # Write the indicated stack number with the specified video attribute.
  3759. # Cursor position is preserved -- WARNING: THIS IS NOT NESTABLE.
  3760. procedure writeStackNumber (num, attr)
  3761.     if \invisible  then  return
  3762.     writes (ESC, "[s")                        #save cursor position
  3763.     writeCursor (1, [2,11,20,29,38,47,56][num])
  3764.     writes (attr, num, Vnormal)
  3765.     writes (ESC, "[u")                        #restore cursor position
  3766. end                                            #writeStackNumber
  3767.  
  3768.  
  3769. #    w r i t e C u r s o r
  3770. # Position the cursor to row,col.
  3771. # Screen origin (top left corner) is row=1 and col=1.
  3772. procedure writeCursor (row, col)
  3773.     if /invisible  then
  3774.         writes ("\33[", row, ";", col, "H") 
  3775. end                                            #writeCursor
  3776.  
  3777.  
  3778. #    w r i t e F r o n t
  3779. # Displays an image of the specified card fronts at the specified spot.
  3780. # WARNING: this eats the list that you provide -- pass a copy() if you care!!
  3781. # Top left corner of the first card will be placed at the specified position.
  3782. # Successive cards are displayed two rows higher (lower position on the screen).
  3783. # Cursor need not be in any particular position before this, and is left
  3784. # in a random position afterwards.  Video is always left normal (not reversed).
  3785. # Cards are 7 columns wide by 5 rows tall.
  3786. # With 25 rows, we can put 12 cards in a stack (assuming we start in row 2).
  3787. # But if there are 11 in the stack we can only display 4 rows of the top card.
  3788. # If there are 12 cards, we can only display 2 rows of the topmost card.
  3789. ##We can only write a row at a time due to a problem with ANSI col 80 handling.
  3790. procedure writeFront (cardlist, row, col)
  3791. local suit, rank, card
  3792. static vertical, topHorizontal, bottomHorizontal
  3793. initial {
  3794.     if \isDOS  then  {
  3795.         vertical := "\263"
  3796.         topHorizontal    := "\332\304\304\304\304\304\277"
  3797.         bottomHorizontal := "\300\304\304\304\304\304\331"
  3798.     } else {
  3799.         vertical := "|"
  3800.         topHorizontal    := "-------"
  3801.         bottomHorizontal := "-------"
  3802.     }
  3803. }
  3804.     while  card := get(cardlist)  do  {
  3805.         #first 2 rows of card
  3806.         writeCursor (row+0, col);
  3807.         writes (Vreverse, topHorizontal)
  3808.         writeCursor (row+1, col);
  3809.         writes (vertical, color[card.suit], "A23456789TJQK"[card.rank],
  3810.                 suitID[card.suit], Vreverse, "   ", vertical)
  3811.         if (*cardlist = 0)  &  (row < 24)  then  {
  3812.             #next 2 rows of top card unless it's the 12th card on the stack
  3813.             writeCursor (row+2, col);
  3814.             writes (Vreverse, vertical, "     ", vertical)
  3815.             writeCursor (row+3, col);
  3816.             writes (vertical, "   ",color[card.suit],"A23456789TJQK"[card.rank],
  3817.                     suitID[card.suit], Vreverse, vertical)
  3818.             if row < 22  then  {
  3819.                 #last row of card unless it's the 11th on the stack
  3820.                 writeCursor (row+4, col);
  3821.                 writes (bottomHorizontal)
  3822.             }
  3823.         }
  3824.         row +:= 2
  3825.     }
  3826.     writes (Vnormal)
  3827. end                                            #writeFront
  3828.  
  3829.  
  3830. #    w r i t e B a c k
  3831. # Puts an image of the back of a card at the specified spot on the screen.
  3832. procedure writeBack (row, col)
  3833. static backLine
  3834. initial {
  3835.     backLine := repl (if \isDOS  then  "\260"  else  "#",  7)
  3836. }
  3837.     if \invisible  then  return
  3838.     writeCursor (row+0, col);  writes (backLine)
  3839.     writeCursor (row+1, col);  writes (backLine)
  3840.     writeCursor (row+2, col);  writes (backLine)
  3841.     writeCursor (row+3, col);  writes (backLine)
  3842.     writeCursor (row+4, col);  writes (backLine)
  3843. end                                            #writeBack
  3844.  
  3845.  
  3846. #    w r i t e B l a n k
  3847. # Blanks a card-sized area at the specified spot on the screen.
  3848. procedure writeBlank (row, col)
  3849. static blankLine
  3850. initial {
  3851.     blankLine := repl (" ", 7)
  3852. }
  3853.     if \invisible  then  return
  3854.     writeCursor (row+0, col);  writes (blankLine)
  3855.     writeCursor (row+1, col);  writes (blankLine)
  3856.     writeCursor (row+2, col);  writes (blankLine)
  3857.     writeCursor (row+3, col);  writes (blankLine)
  3858.     writeCursor (row+4, col);  writes (blankLine)
  3859. end                                            #writeBlank
  3860.  
  3861.  
  3862. #    w r i t e S t a c k
  3863. # Display the specified stack.  Left end is bottom of stackUp, top of stackDown.
  3864. # Stacks start in row 2, column1; with 2 columns between stacks.
  3865. # last[] holds, for each stack, the total number of visible cards
  3866. # on that stack as of the last time writeStack() was called.  This allows
  3867. # us to simply draw (or erase) the cards that have been added (or subtracted).
  3868. # By special arrangement, this routine can be called with a negative stack
  3869. # number!  This is a hint that our idea of what is on the display is actually
  3870. # wrong, and therefore the entire stack needs to be re-displayed.  This can
  3871. # happen in two situations:  1) in refreshScreen(), the entire screen is cleared
  3872. # before calling writeStack();  2) in undo() when undoing a move between
  3873. # stacks, the bottom card needs to be changed, although the normal algorithm
  3874. # would consider that it is already correctly displayed.  Note that in neither
  3875. # case is the stack shrinking, therefore we don't need to worry about erasing
  3876. # any cards that were displayed last time.
  3877. procedure writeStack (n)
  3878. local row, col, s
  3879. static last, blankLine, firstRow, lastRow
  3880. initial    {
  3881.     last := [0,0,0,0,0,0,0]
  3882.     blankLine := repl (" ", 7)
  3883.     firstRow := [2,4,6,8,10,12,14,16,18,20,22,24]    #first row of a card
  3884.     lastRow  := [6,8,10,12,14,16,18,20,22,24,25,25]    #last row of a card
  3885. }
  3886.     if \invisible  then  return
  3887.     if n < 0  then  {
  3888.         n := -n
  3889.         last[n] := 0                            #force complete re-write
  3890.     }
  3891.  
  3892.     col := 1 + ((n -1) * 9)                        #leftmost column for this stack
  3893.  
  3894.     if *stackUp[n] <= last[n]  then  {
  3895.         #the stack just got smaller (or stayed the same)
  3896.         #blank out two rows for each card that has been removed
  3897.         row := lastRow[last[n]]                    #last row used by top card
  3898.         while *stackUp[n] < last[n]  do  {
  3899.             writeCursor (row-0, col);  writes (blankLine)
  3900.             writeCursor (row-1, col);  writes (blankLine)
  3901.             row -:= 2
  3902.             last[n] -:= 1                        #count and update simultaneously
  3903.         }
  3904.         dieIf (*stackUp[n] ~= last[n], last[n])
  3905.         #re-write new top card
  3906.         if *stackUp[n] = 0  then
  3907.             if *stackDown[n] = 0  then
  3908.                 writeBlank (2, col)
  3909.             else
  3910.                 writeBack (2, col)
  3911.         else
  3912.             writeFront ([stackUp[n][-1]], firstRow[last[n]], col)
  3913.     } else {
  3914.         #the stack just got bigger -- display new cards
  3915.         s := stackUp[n][last[n]-(*stackUp[n]):0]    #list of new cards
  3916.         writeFront (s, firstRow[last[n]+1], col)
  3917.         last[n] := *stackUp[n]                #remember how much is displayed
  3918.     }
  3919.  
  3920.     writeCursor (2, (7 + col))
  3921.     writes (" 123456???"[1+*stackDown[n]])    #display the number of hidden cards
  3922. end                                            #writeStack
  3923.  
  3924.  
  3925. #    w r i t e P i l e
  3926. # Displays an image of the specified ace pile, face up (or blank if empty)
  3927. procedure writePile (n)
  3928. static pileRow, pileCol
  3929. initial {
  3930.     pileRow := [3,3,9,9]
  3931.     pileCol := [66,74,66,74]
  3932. }
  3933.     if \invisible  then  return
  3934.     if  0 = pile[n]  then  writeBlank (pileRow[n], pileCol[n])
  3935.     else  writeFront ([card(n,pile[n])], pileRow[n], pileCol[n])
  3936. end                                            #writePile
  3937.  
  3938.  
  3939. #    w r i t e D e c k D o w n
  3940. # Displays an image of deckDown (the face-down deck) in the proper spot.
  3941. procedure writeDeckDown ()
  3942.     if \invisible  then  return
  3943.     if 0 < *deckDown  then
  3944.         writeBack (21, 74)
  3945.     else
  3946.         writeBlank (21, 74)
  3947.     writeCursor (20, 76)
  3948.     writes (right(*deckDown, 2))
  3949. end                                            #writeDeckDown
  3950.  
  3951.  
  3952. #    w r i t e D e c k U p
  3953. # Displays an image of deckUp (the face-up deck) in the proper spot.
  3954. procedure writeDeckUp ()
  3955.     if \invisible  then  return
  3956.     if 0 < *deckUp  then
  3957.         writeFront ([deckUp[1]], 21, 66)
  3958.     else
  3959.         writeBlank (21, 66)
  3960.     writeCursor (20, 68)
  3961.     writes (right(*deckUp, 2))
  3962. end                                            #writeDeckUp
  3963.  
  3964.  
  3965. #    w r i t e I n f o
  3966. # Displays a new short string (up to 12 printing characters) in the
  3967. # officially approved information area of the screen.
  3968. # An empty string results in clearing the area and restoring normal attributes.
  3969. procedure writeInfo (s)
  3970.     if \invisible  then  return
  3971.     writeCursor (16, 65)
  3972.     writes (Vnormal, VclearEOL)
  3973.     if  *s ~= 0  then  writes (s)
  3974. end                                            #writeInfo
  3975.  
  3976.  
  3977. #    c l i c k
  3978. # Make a quick sound to accompany card transfers
  3979. procedure click ()
  3980. local x
  3981.     if (\clicking)  &  (\isDOS)  then  {
  3982.         x := InPort (16r61)
  3983.         OutPort (16r61, 3)
  3984.         OutPort (16r61, x)
  3985.     }
  3986. end                                            #click
  3987.  
  3988.  
  3989. #    g e t C m d C h a r
  3990. # Returns an upper-case command character, echoed to current cursor position.
  3991. # Fails if character wasn't "normal" and complaint was made.
  3992. # For ESC, abort information is written, and ESC is returned.
  3993. # Normal calling sequence (from within a command procedure) is thus:
  3994. #        until (s := getCmdChar ())
  3995. #        if s == ESC  then  fail
  3996. procedure getCmdChar ()
  3997. local s
  3998.     s := getch ()                        #get command character
  3999.     if  s == "\0"  then  {                #non-ASCII character
  4000.         getch ()                        #discard keyboard scan code
  4001.         complain ()
  4002.         fail
  4003.     }
  4004.     s := map (s, &lcase, &ucase)
  4005.     if s == ESC  then
  4006.         writeInfo (Vbold || "Cmd Aborted.")
  4007.     else
  4008.         writes (s)                            #echo the command character
  4009.     return  s
  4010. end                                            #getCmdChar
  4011.  
  4012.  
  4013. #    c o m p l a i n
  4014. # Let the boob know he done something wrong
  4015. # The short beep produced under isDOS is not as annoying as the normal beeeeep.
  4016. procedure complain ()
  4017. local x
  4018.     writeInfo (Vbold || "INVALID")
  4019.     if \clicking  then
  4020.         if \isDOS then  {
  4021.             x := InPort (16r61)
  4022.             every 1 to 22 do
  4023.                 OutPort (16r61, 3)
  4024.             OutPort (16r61, x)
  4025.         } else
  4026.             writes (Vbell)
  4027. end                                            #complain
  4028.  
  4029.  
  4030. #    r e f r e s h S c r e e n
  4031. # Re-write entire screen.
  4032. procedure refreshScreen ()
  4033.     if \invisible  then  return
  4034.     initScreen ()
  4035.     every writeStack (-1 to -7 by -1)
  4036.     every writePile (1 to 4)
  4037.     writeDeckDown ()
  4038.     writeDeckUp ()
  4039. end                                            #refreshScreen
  4040. -- 
  4041. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  4042. X.400:  naz@hslrswi.hasler
  4043. UUCP:   ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
  4044. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  4045.  
  4046. From icon-group-request@arizona.edu  Thu Dec  6 07:35:46 1990
  4047. Resent-From: icon-group-request@arizona.edu
  4048. Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  4049.     id AA26395; Thu, 6 Dec 90 07:35:46 -0700
  4050. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec
  4051.  1990 07:34 MST
  4052. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19678; Thu, 6 Dec 90 06:33:14
  4053.  -0800
  4054. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  4055.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  4056.  usenet@ucbvax.Berkeley.EDU if you have questions)
  4057. Resent-Date: Thu, 6 Dec 1990 07:35 MST
  4058. Date: 6 Dec 90 12:44:22 GMT
  4059. From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu
  4060.  (Norman H. Azadian)
  4061. Subject: klondike, version 1.41.  part 4/4
  4062. Sender: icon-group-request@arizona.edu
  4063. Resent-To: icon-group@cs.arizona.edu
  4064. To: icon-group@arizona.edu
  4065. Resent-Message-Id: <555A54FD6C4022C1@Arizona.edu>
  4066. Message-Id: <1690@hslrswi.UUCP>
  4067. X-Envelope-To: icon-group@CS.Arizona.EDU
  4068. X-Vms-To: icon-group@Arizona.edu
  4069. Organization: Hasler AG
  4070.  
  4071.  
  4072. #klonsub.icn    901029    NHA
  4073. #subroutines for Klondike
  4074.  
  4075.  
  4076. #    d i e I f
  4077. # If the first argument succeeds, then write out the remaining args & die.
  4078. # Note that the remaining arguments must succeed.
  4079. procedure dieIf (failed, writeArgs[])
  4080.     every writes (&output, !writeArgs)
  4081.     write (&output)
  4082.     display ()
  4083.     every writes (&errout, !writeArgs)
  4084.     write (&errout)
  4085.     runerr (500)
  4086. end                                            #dieIf
  4087.  
  4088.  
  4089. #    f i t O n S t a c k
  4090. # Given a card and a stack number, fail unless card can be added to the stack.
  4091. # Note that we disallow putting an Ace on a stack, period.  This prevents
  4092. # ever building a stack with 13 cards, which we can't display in 25 rows.
  4093. procedure fitOnStack (c, n)
  4094. local top                                                    #top card on stack
  4095.     if *stackUp[n] = 0  then  {
  4096.         dieIf (*stackDown[n] ~= 0, "Up empty, Down not")
  4097.         if c.rank ~= 13  then  fail            #only a king can go to empty stack
  4098.     } else {
  4099.         top := stackUp[n][-1]                #copy of top card
  4100.         if (c.rank ~= (top.rank - 1))  then  fail            #wrong rank
  4101.         if (c.suit < 3)  &  (top.suit < 3)  then  fail        #same color
  4102.         if (c.suit > 2)  &  (top.suit > 2)  then  fail        #same color
  4103.         if c.rank = 1  then  fail                            #no ace on stack
  4104.         dieIf (*stackUp[n] >= 12, "stack too big")
  4105.     }
  4106.     return                                    #success
  4107. end                                            #fitOnStack
  4108.  
  4109.  
  4110. #    c h e c k 4 a c e
  4111. # Only has an effect when global automaticAce is set!
  4112. # Given a stack number, check for an ace as the top of stackUp[n].
  4113. # If present, move it over to it's ace pile, turn over the next card
  4114. # from stackDown, and check again.
  4115. # Must not be more than one up card in stack.
  4116. # Returns a string of the operations performed.
  4117. procedure check4ace (n)
  4118. local c, op
  4119.     op := ""
  4120.     if \automaticAce  then  {
  4121.         dieIf (1 < *stackUp[n])
  4122.         while 0 < *stackUp[n]  do  {
  4123.             c := stackUp[n][1]                    #copy of (top = bottom) up card
  4124.             if c.rank = 1  then  {                #it's an ace!
  4125.                 pop (stackUp[n])                #remove it from the stack
  4126.                 pile[c.suit] := 1                #move to ace pile
  4127.                 op ||:= c.suit
  4128.                 push (stackUp[n], get(stackDown[n])) #turn over card underneath
  4129.                 writeStack (n)
  4130.                 writePile (c.suit)
  4131.                 click ()
  4132.             } else
  4133.                 break                            #not an ace
  4134.         }
  4135.     }
  4136.     return op
  4137. end                                            #check4ace
  4138.  
  4139.  
  4140. #    m o v e S t a c k
  4141. # Move a stack to another stack, no questions asked.
  4142. # Updates video and audio.
  4143. # Returns any automatic ace operations that were done as a consequence.
  4144. ##It would be nice to do this in a visually and audibly more satisfying way
  4145. procedure moveStack (src, dst)
  4146.     while put (stackUp[dst], get(stackUp[src]))
  4147.     put (stackUp[src], get(stackDown[src]))
  4148.     writeStack (src)
  4149.     writeStack (dst)
  4150.     click ()
  4151.     return  check4ace (src)
  4152. end                                            #moveStack
  4153.  
  4154.  
  4155. #    m o v e
  4156. # This is the internal move, taking a operation string.  No Thumbs allowed.
  4157. # Upon success it returns the (possibly modified) operation string.
  4158. procedure move (op)
  4159. local src, dst, c, moved
  4160.     dieIf (op[1] ~== "M", "op is ", op)
  4161.     src := op[2]
  4162.     dst := op[3]
  4163.     moved := 0
  4164.     if src == "D"  then  {
  4165.         c := deckUp[1]
  4166.         if dst == "A"  then  {                # Deck -> Ace
  4167.             if c.rank = (pile[c.suit] + 1)  then  {
  4168.                 op[4] := c.suit                # Deck -> Ace:  fits - do it
  4169.                 pile[c.suit] +:= 1
  4170.                 writePile (c.suit)
  4171.                 moved := 1
  4172.             } else
  4173.                 fail                        # Deck -> Ace:  doesn't fit
  4174.         } else  {                            # Deck -> stack
  4175.             if fitOnStack (c, dst)  then {
  4176.                 put (stackUp[dst], c)        # Deck -> stack:  fits - do it
  4177.                 writeStack (dst)
  4178.                 moved := 1
  4179.             } else
  4180.                 fail                        # Deck -> stack: doesn't fit
  4181.         }
  4182.         while moved ~= 0  do  {
  4183.             pop (deckUp)
  4184.             writeDeckUp ()                    # Deck -> somewhere, with success
  4185.             click ()
  4186.             moved := 0
  4187.             if \automaticAce  then  {
  4188.                 if (c := deckUp[1]).rank = 1  then  {    #automatic Ace handling
  4189.                     pile[c.suit] := 1
  4190.                     op ||:= c.suit
  4191.                     writePile (c.suit)
  4192.                     moved := 1
  4193.                 }
  4194.             }
  4195.         }
  4196.     } else {
  4197.         if dst == "A"  then  {                # stack -> Ace
  4198.             c := stackUp[src][-1]            #copy of card on top of stack
  4199.             if c.rank = (pile[c.suit] + 1)  then  {
  4200.                 op[4] := c.suit                # stack -> Ace:  fits - do it
  4201.                 pile[c.suit] +:= 1
  4202.                 pull (stackUp[src])
  4203.                 writeStack (src)
  4204.                 click ()
  4205.                 writePile (c.suit)
  4206.                 if *stackUp[src] = 0  then  {
  4207.                     op[4] +:= 4                #mark this case for undo()
  4208.                     put (stackUp[src], get(stackDown[src]))    #turn over a card
  4209.                     writeStack (src)
  4210.                     click ()
  4211.                     op ||:= check4ace (src)
  4212.                 }
  4213.             } else {
  4214.                 fail                        # stack -> Ace:  doesn't fit
  4215.             }
  4216.         } else {                            # stack -> stack
  4217.             if fitOnStack (stackUp[src][1], dst)  then  {
  4218.                                             # stack -> stack:  fits - do it
  4219.                 op[4] := "123456789abcdef"[*stackUp[src]]
  4220.                 op ||:= moveStack (src, dst)
  4221.             } else
  4222.                 fail                        # stack -> stack:  doesn't fit
  4223.         }
  4224.     }
  4225.     return  op                                #success
  4226. end                                            #move
  4227.  
  4228.  
  4229. #    t h u m b
  4230. # Move to next spot in deckDown
  4231. # Returns the operation performed (usually just "T3"), or fail if none possible.
  4232. procedure thumb ()
  4233. local c, op, moved
  4234.     if *deckDown = *deckUp = 0  then
  4235.         return complain()                        #no cards left in the deck
  4236.     if *deckDown = 0  then
  4237.         while push (deckDown, pop(deckUp))
  4238.     op :=  "T"  ||  if *deckDown < 3  then  *deckDown  else  3
  4239.     push (deckUp, pop(deckDown))
  4240.     push (deckUp, pop(deckDown))
  4241.     push (deckUp, pop(deckDown))
  4242.     writeDeckDown ()
  4243.     moved := 1
  4244.     while moved ~= 0  do  {
  4245.         writeDeckUp ()
  4246.         click ()
  4247.         moved := 0
  4248.         if \automaticAce  then  {
  4249.             if deckUp[1].rank = 1  then  {
  4250.                 c := pop (deckUp)
  4251.                 pile[c.suit] := 1
  4252.                 op ||:= c.suit
  4253.                 writePile (c.suit)
  4254.                 moved := 1
  4255.             }
  4256.         }
  4257.     }
  4258.     return op
  4259. end                                            #thumb
  4260.  
  4261.  
  4262. #    u n d o
  4263. # backup one move, including any automatic ace moves
  4264. procedure undo ()
  4265. local op, suit
  4266.     writes ("ndo")
  4267.     if op := pop (ops)  then  {
  4268.         writeInfo (op)
  4269.         # op looks like:  Msdixxx
  4270.         # where x is an [optional] number 1..4 of an ace pile
  4271.         # and s is either a stack number or "D"
  4272.         # and d is either "A" or a number 1..7 of a stack
  4273.         # and i is an extra piece of info which may be valid
  4274.         case op[1]  of   {
  4275.         "M"        :    {
  4276.                     dieIf ((*op < 4) | ((/automaticAce) & (4 < *op)), op)
  4277.                     if op[2] == "D"  then  {
  4278.                         #Move cards from Ace piles to deck, starting at end
  4279.                         while 4 < *op  do  {
  4280.                             suit := op[-1]
  4281.                             pile[suit] := 0
  4282.                             writePile (suit)
  4283.                             push (deckUp, card(suit,1))
  4284.                             writeDeckUp ()
  4285.                             click ()
  4286.                             op[-1] := ""
  4287.                         }
  4288.                         if op[3] == "A"  then  {
  4289.                             # unMove Deck to Ace op[4]
  4290.                             suit := op[4]
  4291.                             push (deckUp, card(suit,pile[suit]))
  4292.                             pile[suit] -:= 1
  4293.                             writePile (suit)
  4294.                         } else {
  4295.                             # unMove Deck to stack op[3]
  4296.                             push (deckUp, pull(stackUp[op[3]]))
  4297.                             writeStack (op[3])
  4298.                         }
  4299.                         writeDeckUp ()
  4300.                     } else {
  4301.                         #Move cards from Ace piles to stack, starting at end
  4302.                         while 4 < *op  do  {
  4303.                             suit := op[-1]
  4304.                             pile[suit] := 0
  4305.                             writePile (suit)
  4306.                             dieIf (1 < *stackUp[op[2]])
  4307.                             push (stackDown[op[2]], pull(stackUp[op[2]]))
  4308.                             push (stackUp[op[2]], card(suit,1))
  4309.                             writeStack (op[2])
  4310.                             click ()
  4311.                             op[-1] := ""
  4312.                         }
  4313.                         if op[3] == "A"  then  {
  4314.                             # unMove stack op[2] to Ace pile op[4]
  4315.                             suit := op[4]
  4316.                             if 4 < suit  then  {
  4317.                                 suit -:= 4        #ace pile card was last on stack
  4318.                                 dieIf (1 < *stackUp[op[2]])
  4319.                                 push (stackDown[op[2]], pull(stackUp[op[2]]))
  4320.                             }
  4321.                             put (stackUp[op[2]], card(suit,pile[suit]))
  4322.                             pile[suit] -:= 1
  4323.                             writePile (suit)
  4324.                             writeStack (op[2])
  4325.                         } else {
  4326.                             # unMove top op[4] cards on stack op[2]
  4327.                             # to stack op[3]
  4328.                             dieIf (1 < *stackUp[op[2]])
  4329.                             push (stackDown[op[2]], pull(stackUp[op[2]]))
  4330.                             every 1 to ("16r" || op[4])  do
  4331.                                 push (stackUp[op[2]], pull(stackUp[op[3]]))
  4332.                             writeStack (op[3])
  4333.                             writeStack (-op[2])
  4334.                         }
  4335.                     }
  4336.                 }
  4337.         "T"        :    {
  4338.                     dieIf ((/automaticAce) & (*op ~= 2))
  4339.                     ### op looks like:  Tcxx
  4340.                     ### where c is the number of cards thumbed (usually 3)
  4341.                     ### and x is an optional number 1..4 of an ace pile
  4342.                     ### There can be 0,1,2, or 3 of these x's.
  4343.                     # move cards from Ace piles to deck, starting at end
  4344.                     while 2 < *op  do  {
  4345.                         suit := op[-1]
  4346.                         pile[suit] := 0
  4347.                         writePile (suit)
  4348.                         push (deckUp, card(suit,1))
  4349.                         writeDeckUp ()
  4350.                         click ()
  4351.                         op[-1] := ""
  4352.                     }
  4353.                     # then undo the Thumb operation itself
  4354.                     dieIf (*deckUp = 0)
  4355.                     every 1 to op[2]  do
  4356.                         push (deckDown, pop(deckUp))
  4357.                     if *deckUp = 0  then
  4358.                         while push (deckUp, pop(deckDown))
  4359.                     writeDeckUp ()
  4360.                     writeDeckDown ()
  4361.                 }
  4362.         default    :    stop ("Klondike: unknown operation `", op, "' in ops[]")
  4363.         }
  4364.         click ()
  4365.     } else {
  4366.         ## Admittedly this is a bit of a kluge, but better than nothing ?
  4367.         if *deckDown = 0  then
  4368.             while push (deckDown, pop(deckUp))
  4369.         writeDeckUp ()
  4370.         writeDeckDown ()
  4371.         writeInfo ("Stack Empty")
  4372.     }
  4373.  
  4374. end                                            #undo
  4375.  
  4376.  
  4377. #    s h o w L i s t
  4378. # Display a list of cards at the current cursor position.
  4379. # Intended for debugging only .
  4380. procedure showList (lst)
  4381. local c
  4382.     every c := !lst  do
  4383.         writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit],
  4384.                 Vnormal, " ");
  4385. end                                            #showList
  4386.  
  4387.  
  4388. #    c a r d 2 s t r
  4389. # Given a list of card records, returns a string representation.
  4390. # Even an empty list results in a non-zero string length.
  4391. procedure card2str (lst)
  4392. local c, s
  4393.     s := "$"
  4394.     every c := !lst  do
  4395.         s ||:= string(c.suit) || "123456789abcd"[c.rank]
  4396.     return s
  4397. end                                            #card2str
  4398.  
  4399.  
  4400. #    s t r 2 c a r d
  4401. # Given a string [as generated by card2str()],
  4402. # return corresponding list of card records.
  4403. # Fails if the string is invalid.
  4404. procedure str2card (s)
  4405. local cc, i
  4406.     if s[i:=1] ~== "$"  then  fail
  4407.     cc := []
  4408.     while put (cc, card(s[i+:=1], integer("14r"||s[i+:=1])))
  4409.     return cc
  4410. end                                            #str2card
  4411.  
  4412.  
  4413. #    s a v e S t a t e
  4414. # Saves the current state in the named file, which is created/overwritten
  4415. # as necessary.
  4416. # Fails if the state was not successfully saved.
  4417. procedure saveState (filename)
  4418. local f, i
  4419.     (f := open (filename, "c"))  |  fail
  4420.     write (f, &dateline)
  4421.     write (f, if \automaticAce then 1 else 0)
  4422.     write (f, if \clicking     then 1 else 0)
  4423.     write (f, firstSeed)
  4424.     write (f, lastSeed)
  4425.     write (f, &random)
  4426.     every write (f, !pile)
  4427.     every write (f, card2str(!stackUp))
  4428.     every write (f, card2str(!stackDown))
  4429.     write (f, card2str(deckUp))
  4430.     write (f, card2str(deckDown))
  4431.     write (f, totalGames)
  4432.     write (f, totalAces)
  4433.     every write (f, !ops)
  4434.     return close (f)
  4435. end                                            #saveState
  4436.  
  4437.  
  4438. #    r e s t o r e S t a t e
  4439. # Restore game from the named file.
  4440. # Fails if the file isn't there, isn't readable, or isn't correct format.
  4441. # Otherwise returns date the file was last written.
  4442. # Note that we do not update the screen here !!
  4443. procedure restoreState (filename)
  4444. local f, date
  4445.     if not (f := open (filename, "r"))  then  fail
  4446.     if (not (date := read(f)))  |  (*date = 0)  then  fail
  4447.     automaticAce := if read (f) == "0"  then  &null  else  1
  4448.     clicking     := if read (f) == "0"  then  &null  else  1
  4449.     firstSeed    := read (f)
  4450.     lastSeed     := read (f)
  4451.     &random      := read (f)
  4452.     every ((!pile) := read(f))
  4453.     every ((!stackUp)   := str2card (read(f)))
  4454.     every ((!stackDown) := str2card (read(f)))
  4455.     deckUp   := str2card (read(f))
  4456.     deckDown := str2card (read(f))
  4457.     totalGames    := read (f)
  4458.     totalAces    := read (f)
  4459.     ops := []
  4460.     while push (ops, read (f))
  4461.     dieIf (not close (f), "can't close")
  4462.     return date
  4463. end                                            #restoreState
  4464.  
  4465.  
  4466. #    n e w G a m e
  4467. # Set up all the global variables for a new game.
  4468. # Returns the seed used to generate this game.
  4469. procedure newGame ()
  4470. local i, j, s, seed
  4471.     initScreen ()
  4472.  
  4473.     #initialize deck, stacks, piles
  4474.     ops       := []                            #no operations done yet
  4475.     deckUp    := []                            #deck in hand, face-up
  4476.     deckDown  := []                            #deck in hand, face-down
  4477.     stackUp   := list(7, 0)                    #columns on table, face up
  4478.     stackDown := list(7, 0)                    #columns on table, face down
  4479.     pile      := list(4, 0)                    #aces - only top rank stored
  4480.     every  i := 1 to 4  do
  4481.         every  j := 1 to 13  do
  4482.             put (deckDown, card(i, j))        #take cards out of the box
  4483.  
  4484.     seed := &random
  4485.     if not \invisible  then                    #Vblink not defined in Batch mode
  4486.         writeInfo (Vblink || "Shuffling")
  4487.     every 1 to 100 do
  4488.         ?deckDown :=: ?deckDown
  4489.     writeInfo ("")
  4490.  
  4491.     every !stackUp   := []
  4492.     every !stackDown := []
  4493.     every  i := 1 to 7  do  {
  4494.         push (stackUp[i], get(deckDown))
  4495.         writeStack (-i)
  4496.         click ()
  4497.         every  j := (i+1) to 7  do  {
  4498.             push (stackDown[j], get(deckDown))
  4499.             writeStack (-j)
  4500.             click ()
  4501.         }
  4502. ###        writeStack (-i)                        ### this replaces 2 calls above
  4503.     }
  4504.     writeDeckDown()
  4505.  
  4506.     #handle any Aces which are showing
  4507.     every  i := 1 to 7  do
  4508.         if *(s := check4ace (i)) ~= 0  then
  4509.             push (ops, "M" || string(i) || "A" || string(integer(s) + 4))
  4510.     return seed
  4511. end                                            #newGame
  4512. -- 
  4513. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  4514. X.400:  naz@hslrswi.hasler
  4515. UUCP:   ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
  4516. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  4517.  
  4518. From icon-group-request@arizona.edu  Thu Dec  6 07:36:54 1990
  4519. Resent-From: icon-group-request@arizona.edu
  4520. Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  4521.     id AA26473; Thu, 6 Dec 90 07:36:54 -0700
  4522. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec
  4523.  1990 07:35 MST
  4524. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19641; Thu, 6 Dec 90 06:32:04
  4525.  -0800
  4526. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  4527.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  4528.  usenet@ucbvax.Berkeley.EDU if you have questions)
  4529. Resent-Date: Thu, 6 Dec 1990 07:36 MST
  4530. Date: 6 Dec 90 12:42:14 GMT
  4531. From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu
  4532.  (Norman H. Azadian)
  4533. Subject: klondike, version 1.41.  part 2/4
  4534. Sender: icon-group-request@arizona.edu
  4535. Resent-To: icon-group@cs.arizona.edu
  4536. To: icon-group@arizona.edu
  4537. Resent-Message-Id: <5580B0A18C401FC4@Arizona.edu>
  4538. Message-Id: <1688@hslrswi.UUCP>
  4539. X-Envelope-To: icon-group@CS.Arizona.EDU
  4540. X-Vms-To: icon-group@Arizona.edu
  4541. Organization: Hasler AG
  4542.  
  4543.  
  4544. #klondike.icn    900720    NHA
  4545. #The Klondike version of Solitaire.
  4546. # Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display.
  4547. #
  4548. # TO FIX:
  4549. #
  4550. #
  4551. #
  4552. # TO DO:
  4553. #
  4554. # -    Use space to step to next non-thumb move, and enter to do it ???
  4555. # -    Implement an heuristic to discover optimal play strategy.
  4556. #
  4557.  
  4558. link    kloncon                                #console I/O
  4559. link    klonsub                                #general subroutines
  4560.  
  4561. record card(suit, rank)                                #suit is 1..4, rank is 1..13
  4562.  
  4563. # variables
  4564. global deckUp, deckDown, stackUp, stackDown            #collections of card
  4565. global pile                                            #ace piles - top rank only
  4566. global ops                                            #list of all operations done
  4567. global debugging, automaticAce                        #command-line flags
  4568. global invisible, clicking                            #visual, audible feedback
  4569. global firstSeed, lastSeed                            #&random remembered
  4570. global totalGames, totalAces                        #ace pile statistics
  4571.  
  4572.  
  4573. #    a u t o m a t i c 1
  4574. # Do 1 move, thumbing as necessary to achieve it.
  4575. # Fails if there is nothing useful left to do.
  4576. # This is an internal routine that doesn't worry at all about the user.
  4577. procedure automatic1 ()
  4578. local s, thumbCount
  4579.     thumbCount := 0
  4580.     while thumbCount <= ((*deckUp + *deckDown + 2) / 3)  do  {
  4581.         if s := suggest()  then  {
  4582.             push (ops, move ("M" || s || "0"))
  4583.             thumbCount := 0
  4584.             return;
  4585.         } else {                            #no good move found -- thumb
  4586.             if (*deckUp = 0)  &  (*deckDown = 0)  then
  4587.                 fail                        #no cards left to thumb through
  4588.             push (ops, s := thumb())
  4589.             if 2 < *s  then
  4590.                 return                        #must have turned up an Ace
  4591.             thumbCount +:= 1
  4592.         }
  4593.     }
  4594. end                                            #automatic1
  4595.  
  4596.  
  4597. #    a u t o m a t i c
  4598. # Run the game, as far as possible, untouched by human hands
  4599. # This is an internal routine that only worries a little about the user.
  4600. # Returns when either there is nothing useful left to do or a key is struck.
  4601. procedure automatic ()
  4602. local s, thumbCount
  4603.     thumbCount := 0
  4604.     repeat  {
  4605.         if kbhit ()  then
  4606.             return                            #stopped by human intervention
  4607.         if pile[1] = pile[2] = pile[3] = pile[4] = 13  then
  4608.             return                            #victory
  4609.         automatic1 ()  |  return
  4610.         }
  4611. end                                            #automatic
  4612.  
  4613.  
  4614. #    u a u t o m a t i c
  4615. # Play this hand automatically, untouched by human hands.
  4616. # This is the fuction that interacts with the user.
  4617. procedure uautomatic ()
  4618.     writes ("utomatic")
  4619.     automatic()
  4620.     if kbhit()  then
  4621.         if  getch() == "\0"  then  getch()
  4622. end                                            #uautomatic
  4623.  
  4624.  
  4625. #    u c o n t i n u o u s
  4626. # Plays automatic games -- forever (or until any keystroke)
  4627. procedure ucontinuous()
  4628.     writes ("ontinuous")
  4629.     repeat  {
  4630.         writeInfo (string(totalGames) || "   " || string(totalAces))
  4631.         automatic()
  4632.         if kbhit()  then  {
  4633.             if  getch() == "\0"  then        #eat stopping char(s)
  4634.                 getch()
  4635.             return
  4636.         } else
  4637.             totalAces  +:=  pile[1] + pile[2] + pile[3] + pile[4]
  4638.         totalGames +:= 1
  4639.         lastSeed := newGame()
  4640.     }
  4641. end                                            #ucontinuous
  4642.  
  4643.  
  4644. #    u h e l p
  4645. # Provide command summary for user, plus statistics to date, if any.
  4646. procedure uhelp ()
  4647.     write (VclearAll, Vnormal)
  4648.     write ("Klondike version 1.41  901126 NHA\t\t", &version)
  4649.     write ("\n\nThe following commands are available:\n")
  4650.     write ("\t", Vbold, "^L\tre-draw", Vnormal, " screen")
  4651.     write ("\t", Vbold, "A\tAutomatic", Vnormal, " mode -- plays 1 game by itself until any key is hit")
  4652.     write ("\t", Vbold, "B\tBoss", Vnormal, " key for when you-know-who visits")
  4653.     write ("\t", Vbold, "C\tContinuous", Vnormal, " mode -- plays games continuously until any key hit")
  4654.     write ("\t", Vbold, "H,?\tHelp", Vnormal, ", this help screen")
  4655.     write ("\t", Vbold, "M\tMove", Vnormal, " card (or stack) from Deck/Stack to Stack/Ace pile")
  4656.     write ("\t", Vbold, "Q\tQuit", Vnormal, " this game")
  4657.     write ("\t", Vbold, "S\tSuggest", Vnormal, " (another) possible move")
  4658.     write ("\t", Vbold, "T\tThumb", Vnormal, " through the deck")
  4659.     write ("\t", Vbold, "U\tUndo", Vnormal, " -- back up one move")
  4660.     if \debugging  then
  4661.         write ("\t", Vbold, "Z\tDebug", Vnormal)
  4662.     write ("\t", Vbold, "ESC\tEscape", Vnormal, " -- abort current command")
  4663.  
  4664.     if totalGames ~= 0  then
  4665.         write ("\n\ntotalGames = ", totalGames, "      totalAces = ", totalAces,
  4666.                 "     average = ", real(totalAces) / real(totalGames))
  4667.     write ("\n\n", Vblink, "Press any key to resume game", Vnormal)
  4668.     if  getch() == "\0"  then  getch()
  4669.     refreshScreen ()
  4670. end                                            #uhelp
  4671.  
  4672.  
  4673. #    u m o v e
  4674. # Move a card from deck to stack, or from stack to ace pile,
  4675. # or move a stack to another stack.
  4676. # Parameter is the source [1-7 or D] or &null to indicate that "M" was used
  4677. # and therefore source should be gathered from the keyboard.
  4678. # Fails if indicated move is not possible
  4679. # This is the routine that interacts with the user.
  4680. procedure umove (src)
  4681. local dst, c, op, moved
  4682.     if \src  then
  4683.         writes ("\bMove ", Vbold, src)
  4684.     else {
  4685.         writes ("ove " || Vbold);
  4686.         until (src := getCmdChar ())
  4687.         if src == ESC  then  return
  4688.     }
  4689.     if src == "D"  then  {
  4690.         if *deckUp = 0  then  fail
  4691.     } else {
  4692.         if not any ('1234567', src)  then  fail
  4693.         if *stackUp[src] = 0  then  fail
  4694.         writeStackNumber (src, Vblink)
  4695.     }
  4696.  
  4697.     writes (Vnormal || " to " || Vbold)
  4698.     until (dst := getCmdChar ())
  4699.     if  src ~== "D"  then  writeStackNumber (src, Vnormal)
  4700.     if dst == ESC  then  return
  4701.     if not any ('A1234567', dst)  then  fail
  4702.     if dst == src  then  fail
  4703.  
  4704.     return  push (ops, move("M" || src || dst || "0"))
  4705. end                                            #umove
  4706.  
  4707.  
  4708. #    s u g g e s t
  4709. # Find a (reasonable) possible move in this situation
  4710. # This is the internal routine.
  4711. procedure suggest ()
  4712. local i, j, k, c
  4713.     #look at deckUp to see if the top card fits on a pile
  4714.     if c := deckUp[1]  then
  4715.         if c.rank = (pile[c.suit] + 1)  then
  4716.             suspend "DA"
  4717.     #look at deckUp to see if the top card fits on a stack
  4718.     if c := deckUp[1]  then
  4719.         every i := 1 to 7  do
  4720.             if fitOnStack (c, i)  then
  4721.                 suspend "D" || string(i)
  4722.     #look at each stack to see if top card can be put on ace pile
  4723.     every i := 1 to 7  do
  4724.         if c := stackUp[i][-1]  then        #top card
  4725.             if c.rank = (pile[c.suit] + 1)  then
  4726.                 suspend  string(i) || "A"
  4727.     #look at each stack to see if something can be (reasonably) moved
  4728.     every i := 7 to 1 by -1  do
  4729.         every j := 1 to 7  do
  4730.             if fitOnStack (stackUp[i][1], j)  then  {
  4731.                 if (0 < *stackDown[i])  then
  4732.                     suspend  string(i) || string(j)
  4733.                 else {
  4734.                     # possibility, but since there are no cards hidden under
  4735.                     # this pile, we reject it UNLESS there are no empty slots
  4736.                     # AND one of the following is true:
  4737.                     #    1) deckUp[1].rank = 13
  4738.                     #    2) there is a king with cards hidden beneath it
  4739.                     c := 0                    #number of empty stacks
  4740.                     every k := 1 to 7  do
  4741.                         if *stackUp[k] = 0  then  c +:= 1
  4742.                     if c = 0  then
  4743.                         if (deckUp[1].rank = 13)  |
  4744.                           (every k := 1 to 7  do
  4745.                                 if (stackUp[k][1].rank = 13) &
  4746.                                    (0 < *stackDown[k])  then
  4747.                                     break            #success
  4748.                           )
  4749.                     then
  4750.                         suspend  string(i) || string(j)
  4751.                 }
  4752.             }
  4753.     #punt
  4754.     fail
  4755. end                                            #suggest
  4756.  
  4757.  
  4758. #    u s u g g e s t
  4759. # Suggest a (reasonable) possible move in this situation.
  4760. # Repeated invocations produce successive possibilities, until the
  4761. # only thing left to do is Thumb.  After this, it cycles around to the start.
  4762. procedure usuggest (another)
  4763. static suggestions, i
  4764. local s, ss
  4765.     writes ("uggest")
  4766.     if another = 0  then  {
  4767.         suggestions := []                    #generate a new list of suggestions
  4768.         every put (suggestions, suggest())
  4769.         i := 0
  4770.     }
  4771.     if ss := suggestions[i+:=1]  then  {
  4772.         s := "Move " ||    if ss[1] == "A"  then  "Ace"
  4773.                         else if ss[1] == "D"  then  "Deck"
  4774.                         else ss[1]
  4775.         s ||:= " to " || if ss[2] == "A"  then  "Ace" else ss[2]
  4776.         writeInfo (s)
  4777.     } else {
  4778.         writeInfo ("Thumb")
  4779.         i := 0
  4780.     }
  4781. end                                            #usuggest
  4782.  
  4783.  
  4784. #    u t e r m i n a t e
  4785. # Parameter should be non-zero if termination is due to complete success.
  4786. # Returns success to quit this game and start another.
  4787. # Returns failure to just continue this game.
  4788. # If program termination is wished, that is done right here.
  4789. procedure uterminate (victory)
  4790. local s
  4791.     if \victory  then  {
  4792.         totalAces +:= 52
  4793.         pile[1] := pile[2] := pile[3] := pile[4] := 0    #prevent victory loops
  4794.         writeCursor (12, 22)
  4795.         writes (Vbold, Vblink, "Congratulations -- You've WON !!!", Vnormal)
  4796.     } else
  4797.         writes ("uit")
  4798.     writeInfo (Vbold || "Another game? ")
  4799.     until (s := getCmdChar ())
  4800.     if s  == ESC  then  fail()            #didn't really want to quit anyway
  4801.     if s  == "Y"  then  return            #please start a new game
  4802.     if s ~== "N"  then  return complain ()
  4803.  
  4804.     #program termination requested
  4805.     writes ("\33[=7h", Vnormal)            #set cursor wrap mode, normal attr
  4806.     totalGames +:= 1
  4807.     if /victory  then
  4808.         totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
  4809.     write (VclearAll, "In ", totalGames, " games, you put ", totalAces,
  4810.             " cards on the ace piles")
  4811.     write ("average = ", real(totalAces) / real(totalGames), " per game")
  4812.     exit ()
  4813. end                                            #uterminate
  4814.  
  4815.  
  4816. #    u d e b u g
  4817. # Additional commands to support the implementer.
  4818. procedure udebug ()
  4819. local s, d, c, name
  4820.     if not \debugging  then  return complain()
  4821.     writes ("\bDebug ")
  4822.     until (s := getCmdChar ())
  4823.     case s  of  {
  4824.         ESC        :    fail
  4825.         "A"        :    {
  4826.                     writes ("gain")
  4827.                     &random := lastSeed
  4828.                     writeCursor (23, 1)
  4829.                     write (Vbold, "&random set.  Quit to play this game again.",
  4830.                             Vnormal, VclearEOL)
  4831.                 }
  4832.         "D"        :    display()
  4833.         "H"|"?"    :    {
  4834.                     writes (if s == "?" then "\bhelp" else "elp")
  4835.                     writeCursor (23, 1)
  4836.                     write (Vbold,
  4837.                      "Again, Dump, Options, Move, Peek{1-7UD}, Restore, Save, Toggle{ACT}.",
  4838.                      Vnormal, VclearEOL)
  4839.                 }
  4840.         "M"        :    {
  4841.                     writes ("ove ")
  4842.                     until (s := getCmdChar ())    #Source
  4843.                     if s == ESC  then  fail
  4844.                     if s == "A"  then  fail
  4845.                     until (d := getCmdChar ())    #Destination
  4846.                     if d == ESC  then  fail
  4847.                     if d == s  then  fail
  4848.                     if not any('1234567', d)  then  fail
  4849.                     if s == "D"  then  {
  4850.                         if *deckUp = 0  then  fail
  4851.                         put (stackUp[d], get(deckUp))
  4852.                         writeDeckUp ()
  4853.                         writeStack (d)
  4854.                         push (ops, "MD" || d || "0")
  4855.                     } else {
  4856.                         c := "123456789abcdef"[*stackUp[s]]
  4857.                         moveStack (s, d)
  4858.                         push (ops, "M" || s || d || c)
  4859.                     }
  4860.                 }
  4861.         "O"        :    {
  4862.                     writes ("ptions")
  4863.                     writeCursor (23, 1)
  4864.                     write (Vbold,
  4865.                      if \automaticAce then "AutomaticAce "  else  " ",
  4866.                      if \clicking then "Clicking "  else  " ",
  4867.                      " &trace=", &trace, 
  4868.                      " seeds=", firstSeed, ",", lastSeed, Vnormal, VclearEOL)
  4869.                 }
  4870.         "P"        :    {
  4871.                     writes ("eek ")
  4872.                     until (s := getCmdChar ())
  4873.                     if s == ESC  then  fail
  4874.                     writeCursor (23, 1)
  4875.                     writes (VclearEOL, Vnormal)
  4876.                     if any('1234567', s)  then  showList (stackDown[s])
  4877.                     else if s == "D"      then  showList (deckDown)
  4878.                     else if s == "U"      then  showList (deckUp)
  4879.                     else complain ()
  4880.                 }
  4881.         "R"        :    {
  4882.                     writes ("estore")
  4883.                     until (s := getCmdChar ())
  4884.                     if s == ESC  then  fail
  4885.                     name := "klondike.sv" || s
  4886.                     if (d := restoreState(name))  then  {
  4887.                         refreshScreen()
  4888.                         writeCursor (23, 1)
  4889.                         write (Vbold, "Restored position from file ", name,
  4890.                                 " of ", d, Vnormal, VclearEOL)
  4891.                     } else {
  4892.                         writeCursor (23, 1)
  4893.                         write (Vblink, "Can't restore from file ", name, ".",
  4894.                                 Vnormal, VclearEOL)
  4895.                     }
  4896.                 }
  4897.         "S"        :    {
  4898.                     writes ("ave ")
  4899.                     until (s := getCmdChar ())
  4900.                     if s == ESC  then  fail
  4901.                     name := "klondike.sv" || s
  4902.                     writeCursor (23, 1)
  4903.                     if saveState (name)  then
  4904.                         write (Vbold, "Position saved in file ",name,
  4905.                                 Vnormal, VclearEOL)
  4906.                     else
  4907.                         write (Vblink, "Can't save in file ", name, ".",
  4908.                                 Vnormal, VclearEOL)
  4909.                 }
  4910.         "T"        :    {
  4911.                     writes ("oggle ")
  4912.                     until (s := getCmdChar ())
  4913.                     if s == ESC  then  fail
  4914.                     case s  of  {
  4915.                         "A"        : automaticAce := if \automaticAce then &null
  4916.                                                                           else 1
  4917.                         "C"        : clicking  := if \clicking   then &null  else 1
  4918.                         "T"        : &trace    := if &trace  = 0 then -1     else 0
  4919.                         default    : complain ()
  4920.                     }                                    #case for Toggle
  4921.                 }
  4922.         default    :    complain ()
  4923.     }                                            #case for Debug command
  4924. end                                            #udebug
  4925.  
  4926.  
  4927. #    u b o s s
  4928. # Cheese it, the Fuzz.
  4929. # Quick -- clear the screen and save the state in a file.
  4930. procedure uboss ()
  4931.     writes ("oss")
  4932.     writes ("\33[=7h", VclearAll, "C>")        #set cursor-wrap mode, look innocent
  4933.     saveState ("klondike.sav")
  4934.     exit ()
  4935. end                                            #uboss
  4936.  
  4937.  
  4938.  
  4939. #    m a i n
  4940. procedure main (av)
  4941. local s, prevsCmd, maxGames
  4942.  
  4943.     # set defaults
  4944.     automaticAce    := 1                    # automatic ace handling
  4945.     clicking        := 1                    # give audible feedback
  4946.     debugging        := &null                # no debugging allowed
  4947.     invisible        := &null                # let's see the action
  4948.     maxGames        := &null                # interactive mode
  4949.     &random := map (&clock, ":", "0")        # randomize the seed
  4950.  
  4951.     # deal with command-line parameters
  4952.     while  s := get (av)  do
  4953.         case  map (s, &lcase, &ucase)  of  {
  4954.             "-A"    :    automaticAce := &null    #disable automatic ace handling
  4955.             "-B"    :    maxGames     := get (av)    #batch mode, this many games
  4956.             "-C"    :    clicking     := &null        #run silent
  4957.             "-D"    :    debugging     := 1            #grant all sorts of perqs
  4958.             "-R"    :    &random      := get (av)    #unrandomize
  4959.         default    :    {write ("klondike  [-ACD]  [-B gameCount]  [-R randomSeed]")
  4960.                     stop("klondike: bogus option ", s)  }
  4961.         }
  4962.  
  4963.     totalGames := totalAces := 0
  4964.  
  4965.     if \maxGames  then  {
  4966.         # In Batch mode there is absolutely no console I/O.
  4967.         # The requested number of games is played
  4968.         # and the average result is printed on the standard output.
  4969.         invisible := 1
  4970.         clicking  := &null
  4971.         totalGames := maxGames
  4972.         while 0 <= (maxGames -:= 1)  do  {
  4973.             newGame ()
  4974.             while automatic1 ()                    #don't allow user to interrupt
  4975.             totalAces  +:=  pile[1] + pile[2] + pile[3] + pile[4]
  4976.         }
  4977.         write (real(totalAces) / real(totalGames))
  4978.         exit ()
  4979.     }
  4980.  
  4981.  
  4982.     initConstants()                                #for console I/O
  4983.     firstSeed := &random                        #initial seed
  4984.  
  4985.     lastSeed := newGame ()
  4986.     #if last game terminated via the Boss key, then restore it now
  4987.     if restoreState ("klondike.sav")  then  {
  4988.         refreshScreen ()
  4989.         writeInfo ("Game restored")
  4990.         close (open ("klondike.sav", "c"))        #truncate boss save file
  4991.     }
  4992.  
  4993.  
  4994.     repeat  {                                    #game loop
  4995.         prevsCmd := "x"                            #anything but "S"uggest
  4996.  
  4997.     #respond to user input
  4998.         repeat  {                                    #command loop
  4999.             writeCursor (18, 65)
  5000.             writes (VclearEOL || Vnormal || "> ")    #clear command line
  5001.             if pile[1] = pile[2] = pile[3] = pile[4] = 13  then
  5002.                 if uterminate (1) then break        # VICTORY!
  5003.             s := getCmdChar ()
  5004.             writeInfo ("")                            #clear info line
  5005.             writeCursor (18, 68)
  5006.             case  s  of  {
  5007.                 "?"|"H"    :    uhelp()
  5008.                 "1"|"2"|"3"|"4"|"5"|"6"|"7"|"D"    :
  5009.                             if not umove(s) then complain()
  5010.                 "A"        :    uautomatic()                    #look Ma, no hands!
  5011.                 "B"        :    uboss()                            #bail out -- quick
  5012.                 "C"        :    ucontinuous()                    #no hands, forever
  5013.                 "M"        :    if not umove(&null) then complain()
  5014.                 "Q"        :    if uterminate(&null) then break    #new game
  5015.                 "S"        :    usuggest (if s == prevsCmd then 1 else 0)
  5016.                 "T"        :    { writes("humb");  push(ops, thumb()) }
  5017.                 "U"        :    undo()
  5018.                 "Z"        :    udebug()
  5019.                 "\^L"    :    refreshScreen()
  5020.                 ESC        :    s                                #do nothing here
  5021.                 default    :    complain()
  5022.             }                                #case
  5023.             prevsCmd := s
  5024.         }                                    #repeat command
  5025.         totalAces  +:= pile[1] + pile[2] + pile[3] + pile[4]
  5026.         totalGames +:= 1
  5027.         lastSeed := newGame ()
  5028.     }                                        #repeat game
  5029. end                                            #main
  5030. -- 
  5031. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  5032. X.400:  naz@hslrswi.hasler
  5033. UUCP:   ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
  5034. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  5035.  
  5036. From goer%sophist@gargoyle.uchicago.edu  Thu Dec  6 14:22:17 1990
  5037. Resent-From: goer%sophist@gargoyle.uchicago.edu
  5038. Received: from MERLIN.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  5039.     id AA15356; Thu, 6 Dec 90 14:22:17 -0700
  5040. Return-Path: goer@sophist.uchicago.edu
  5041. Received: from gargoyle.uchicago.edu by Arizona.edu with PMDF#10282; Thu, 6 Dec
  5042.  1990 14:21 MST
  5043. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  5044.  (4.0/1.14) id AA24137; Thu, 6 Dec 90 15:21:01 CST
  5045. Received: by sophist (4.1/UofC3.1X) id AA07162; Thu, 6 Dec 90 15:24:20 CST
  5046. Resent-Date: Thu, 6 Dec 1990 14:21 MST
  5047. Date: Thu, 6 Dec 90 15:24:20 CST
  5048. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  5049. Subject: klondike
  5050. Resent-To: icon-group@cs.arizona.edu
  5051. To: icon-group@arizona.edu
  5052. Resent-Message-Id: <8E234DAE5C402A2E@Arizona.edu>
  5053. Message-Id: <9012062124.AA07162@sophist>
  5054. X-Envelope-To: icon-group@CS.Arizona.EDU
  5055. X-Vms-To: icon-group@Arizona.edu
  5056.  
  5057. I just thought I'd mention that Norman Azadian's klondike game is
  5058. a pretty nicely done piece of software.  My son hasn't stopped
  5059. playing it since I compiled it this afternoon.  He's running it
  5060. under a DOS emulator on our Xenix box.
  5061.  
  5062. So far, no luck compiling it under Xenix.  I'll try to figure
  5063. out the problem, and perhaps re-post a Unix version some time in
  5064. the near future.
  5065.  
  5066. It's probably the best game I've seen done in Icon.  And, con-
  5067. sidering all the screen processing, it runs pretty fast, too.
  5068.  
  5069. -Richard
  5070.  
  5071. From icon-group-request@arizona.edu  Thu Dec  6 16:49:46 1990
  5072. Resent-From: icon-group-request@arizona.edu
  5073. Received: from MERLIN.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  5074.     id AA19847; Thu, 6 Dec 90 16:49:46 -0700
  5075. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec
  5076.  1990 16:49 MST
  5077. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17065; Thu, 6 Dec 90 15:42:43
  5078.  -0800
  5079. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  5080.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  5081.  usenet@ucbvax.Berkeley.EDU if you have questions)
  5082. Resent-Date: Thu, 6 Dec 1990 16:49 MST
  5083. Date: 6 Dec 90 22:46:19 GMT
  5084. From: midway!quads.uchicago.edu!goer@handies.ucar.edu (Richard L. Goerwitz)
  5085. Subject: sgml stripping
  5086. Sender: icon-group-request@arizona.edu
  5087. Resent-To: icon-group@cs.arizona.edu
  5088. To: icon-group@arizona.edu
  5089. Resent-Message-Id: <A2BFA7AEEC402091@Arizona.edu>
  5090. Message-Id: <1990Dec6.224619.22998@midway.uchicago.edu>
  5091. X-Envelope-To: icon-group@CS.Arizona.EDU
  5092. X-Vms-To: icon-group@Arizona.edu
  5093. Organization: University of Chicago
  5094.  
  5095. Mad as this sounds, I occasionally find it expedient simply to
  5096. strip out <>-style tags from a SGML-encoded file.  Here's a very
  5097. simple program to do this.  I dunno, but I'd expect that it would
  5098. work with the perverted variant of SGML mandated in the U of Chi-
  5099. cago guide to electronic manuscripts.  I posted this elsewhere,
  5100. but since it's Icon code, I figured someone might here might want
  5101. to take a look at it.
  5102.  
  5103. -Richard
  5104.  
  5105. ---- Cut Here and feed the following to sh ----
  5106. #!/bin/sh
  5107. # This is a shell archive (produced by shar 3.49)
  5108. # To extract the files from this archive, save it to a file, remove
  5109. # everything above the "!/bin/sh" line above, and type "sh file_name".
  5110. #
  5111. # made 12/06/1990 07:11 UTC by goer@sophist.uchicago.edu
  5112. # Source directory /u/richard/Stripsgml
  5113. #
  5114. # existing files will NOT be overwritten unless -c is specified
  5115. # This format requires very little intelligence at unshar time.
  5116. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  5117. #                                                                          
  5118. # This shar contains:
  5119. # length  mode       name
  5120. # ------ ---------- ------------------------------------------
  5121. #   3170 -r--r--r-- stripsgml.icn
  5122. #   2615 -r--r--r-- stripunb.icn
  5123. #   1915 -r--r--r-- readtbl.icn
  5124. #   2084 -r--r--r-- slashbal.icn
  5125. #    981 -rw-r--r-- README
  5126. #    659 -rw-r--r-- Makefile.dist
  5127. #
  5128. if test -r _shar_seq_.tmp; then
  5129.     echo 'Must unpack archives in sequence!'
  5130.     echo Please unpack part `cat _shar_seq_.tmp` next
  5131.     exit 1
  5132. fi
  5133. # ============= stripsgml.icn ==============
  5134. if test -f 'stripsgml.icn' -a X"$1" != X"-c"; then
  5135.     echo 'x - skipping stripsgml.icn (File already exists)'
  5136.     rm -f _shar_wnt_.tmp
  5137. else
  5138. > _shar_wnt_.tmp
  5139. echo 'x - extracting stripsgml.icn (Text)'
  5140. sed 's/^X//' << 'SHAR_EOF' > 'stripsgml.icn' &&
  5141. X############################################################################
  5142. X#
  5143. X#    Name:     stripsgml.icn
  5144. X#
  5145. X#    Title:     Strip (or translate) simple SGML tags from a file
  5146. X#
  5147. X#    Author:     Richard L. Goerwitz
  5148. X#
  5149. X#    Version: 1.7
  5150. X#
  5151. X############################################################################
  5152. X#
  5153. X#  This program, stripsgml, may be used either to strip SGML tags
  5154. X#  from a file, or to translate them into some other format (or perhaps
  5155. X#  some combination of the two).  Note that it only handles very
  5156. X#  simple SGML codes, either stripping or translating set strings.
  5157. X#  This is a VERY simple program, merely intended to satisfy a need
  5158. X#  many have expressed for being able to remove, or perform simple
  5159. X#  manipulations on, files containing <>-style tags.
  5160. X#
  5161. X#  In its basic mode, you would simply have stripsgml read the
  5162. X#  standard input (an SGML-marked file).  Stripsgml would then write
  5163. X#  an SGML-free text on the standard output.  Used in this way,
  5164. X#  stripsgml is just a simple stripping program.
  5165. X#
  5166. X#  If you want some or all of the SGML codes translated into another set
  5167. X#  of codes, simply create a file in which each line has 1) the name of
  5168. X#  the SGML code, and then 2) the way you want that code translated on
  5169. X#  both initialization and completion.  The completion specification is
  5170. X#  optional.  Put succinctly, the format is:
  5171. X#
  5172. X#      code    initialization    completion
  5173. X#
  5174. X#  A tab or colon separates the fields.  If you want to use a tab or colon
  5175. X#  as part of the text (and not as a separator), place a backslash before
  5176. X#  it.  The completion field is optional.  There is not currently any way
  5177. X#  of specifying a completion field without an initialization field.
  5178. X#
  5179. X#  In its translation mode, stripsgml is invoked with one argument (the
  5180. X#  name of the file containing the translation information).  As before,
  5181. X#  the standard input is expected to contain an SGML encoded file:
  5182. X#
  5183. X#      stripsgml translation_file < SGML-file
  5184. X#
  5185. X#  To the standard output is written a SGML-free text.
  5186. X#
  5187. X#  Note that, if you are translating SGML code into font change or escape
  5188. X#  sequences, you may get unexpected results.  This isn't stripsgml's
  5189. X#  fault.  It's just a matter of how your terminal or WP operate.  Some
  5190. X#  need to be "reminded" at the beginning of each line what mode or font
  5191. X#  is being used.  Note also that stripsgml assumes < and > as delimiters.
  5192. X#  If you want to put a greater-than or less-than sign into your text,
  5193. X#  put a backslash before it.  This will effectively "escape" the spe-
  5194. X#  cial meaning of those symbols.  There is currently no way to change
  5195. X#  the default delimiters.
  5196. X#
  5197. X############################################################################
  5198. X#
  5199. X#  Links: slashbal.icn ./stripunb.icn ./readtbl.icn
  5200. X#
  5201. X############################################################################
  5202. X
  5203. X
  5204. Xprocedure main(a)
  5205. X
  5206. X    usage := "usage:  stripsgml [map-file]"
  5207. X    *a > 1 & stop(usage)
  5208. X
  5209. X    map_file := open(a[1]) & t := readtbl(map_file)
  5210. X
  5211. X    every line := !&input do
  5212. X    write(stripunb('<','>',line,&null,&null,t))
  5213. X
  5214. X    # last_k is the stack used in stripunb.icn
  5215. X    if *\last_k ~= 0 then
  5216. X    stop("Unexpected EOF encountered.  Expecting ", pop(last_k), ".")
  5217. X
  5218. Xend
  5219. SHAR_EOF
  5220. true || echo 'restore of stripsgml.icn failed'
  5221. rm -f _shar_wnt_.tmp
  5222. fi
  5223. # ============= stripunb.icn ==============
  5224. if test -f 'stripunb.icn' -a X"$1" != X"-c"; then
  5225.     echo 'x - skipping stripunb.icn (File already exists)'
  5226.     rm -f _shar_wnt_.tmp
  5227. else
  5228. > _shar_wnt_.tmp
  5229. echo 'x - extracting stripunb.icn (Text)'
  5230. sed 's/^X//' << 'SHAR_EOF' > 'stripunb.icn' &&
  5231. X############################################################################
  5232. X#
  5233. X#    Name:     stripunb.icn
  5234. X#
  5235. X#    Title:     Strip unbalanced material
  5236. X#
  5237. X#    Author:     Richard L. Goerwitz
  5238. X#
  5239. X#    Version: 1.3
  5240. X#
  5241. X############################################################################
  5242. X#  
  5243. X#  This routine strips material from a line which is unbalanced with
  5244. X#  respect to the characters defined in arguments 1 and 2 (unbalanced
  5245. X#  being defined as bal() defines it, except that characters preceded
  5246. X#  by a backslash are counted as regular characters, and are not taken
  5247. X#  into account by the balancing algorithm).
  5248. X#
  5249. X#  One little bit of weirdness I added in is a table argument. Put
  5250. X#  simply, if you call stripunb() as follows,
  5251. X#
  5252. X#      stripunb('<','>',s,&null,&null,t)
  5253. X#
  5254. X#  and if t is a table having the form,
  5255. X#
  5256. X#      key:  "bold"        value: outstr("\e[2m", "\e1m")
  5257. X#      key:  "underline"   value: outstr("\e[4m", "\e1m")
  5258. X#      etc.
  5259. X#
  5260. X#  then every instance of "<bold>" in string s will be mapped to
  5261. X#  "\e2m," and every instance of "</bold>" will be mapped to "\e[1m."
  5262. X#  Values in table t must be records of type output(on, off).  When
  5263. X#  "</>" is encountered, stripunb will output the .off value for the
  5264. X#  preceding .on string encountered.
  5265. X#
  5266. X############################################################################
  5267. X#
  5268. X#  Links: slashbal.icn
  5269. X#
  5270. X############################################################################
  5271. X
  5272. Xglobal last_k
  5273. Xrecord outstr(on, off)
  5274. X
  5275. X
  5276. Xprocedure stripunb(c1,c2,s,i,j,t)
  5277. X
  5278. X    # NB:  Stripunb() returns a string - not an integer (like find,
  5279. X    # upto).
  5280. X
  5281. X    local lookinfor, bothcs, s2, k
  5282. X    #global last_k
  5283. X    initial last_k := list()
  5284. X
  5285. X    /c1 := '<'
  5286. X    /c2 := '>'
  5287. X    bothcs := c1 ++ c2
  5288. X    lookinfor := c1 ++ '\\'
  5289. X    c := &cset -- c1 -- c2
  5290. X
  5291. X    /s := \&subject | stop("stripunb:  No string argument.")
  5292. X    /i := \&pos | 1
  5293. X    /j := *s + 1
  5294. X
  5295. X    s2 := ""
  5296. X    s ? {
  5297. X    tab(i) | fail
  5298. X    while s2 ||:= tab(upto(lookinfor)) do {
  5299. X        if ="\\" & any(bothcs) then {
  5300. X        &pos+1 > j & (return s2)
  5301. X        s2 ||:= move(1)
  5302. X        next
  5303. X        }
  5304. X        else {
  5305. X        &pos > j & (return s2)
  5306. X        any(c1) |
  5307. X            stop("stripunb:  Unbalanced string, pos(",&pos,").\n",s)
  5308. X        k := tab(slashbal(c,c1,c2,&null,&null,&null,1)) | tab(0)
  5309. X        if \t then {
  5310. X            k ?:= 2(="<", tab(find(">")), =">", pos(0))
  5311. X            if k ?:= (="/", tab(0)) then {
  5312. X            compl := pop(last_k) | stop("Unclosed <>, ",&subject) 
  5313. X            if k == ""
  5314. X            then k := compl
  5315. X            else k == compl | stop("Incorrectly paired <>, </>.")
  5316. X            s2 ||:= \(\t[k]).off
  5317. X            }
  5318. X            else {
  5319. X            s2 ||:= \(\t[k]).on
  5320. X            push(last_k, k)
  5321. X            }
  5322. X        }
  5323. X        }
  5324. X    }
  5325. X    s2 ||:= tab(0)
  5326. X    }
  5327. X
  5328. X    return s2
  5329. X
  5330. Xend
  5331. SHAR_EOF
  5332. true || echo 'restore of stripunb.icn failed'
  5333. rm -f _shar_wnt_.tmp
  5334. fi
  5335. # ============= readtbl.icn ==============
  5336. if test -f 'readtbl.icn' -a X"$1" != X"-c"; then
  5337.     echo 'x - skipping readtbl.icn (File already exists)'
  5338.     rm -f _shar_wnt_.tmp
  5339. else
  5340. > _shar_wnt_.tmp
  5341. echo 'x - extracting readtbl.icn (Text)'
  5342. sed 's/^X//' << 'SHAR_EOF' > 'readtbl.icn' &&
  5343. X############################################################################
  5344. X#
  5345. X#    Name:     readtbl.icn
  5346. X#
  5347. X#    Title:     Read user-created stripsgml table
  5348. X#
  5349. X#    Author:     Richard L. Goerwitz
  5350. X#
  5351. X#    Version: 1.1
  5352. X#
  5353. X############################################################################
  5354. X#  
  5355. X#  This file is part of the stripsgml package.  It does the job of read-
  5356. X#  ing option user-created mapping information from a file.  The purpose
  5357. X#  of this file is to specify how each code in a given input text should
  5358. X#  be translated.  Each line has the form:
  5359. X#
  5360. X#      SGML-designator    start_code    end_code
  5361. X#
  5362. X#  where the SGML designator is something like "quote" (without the quota-
  5363. X#  tion marks), and the start and end codes are the way in which you want
  5364. X#  the beginning and end of a <quote>...<\quote> sequence to be transla-
  5365. X#  ted.  Presumably, in this instance, your codes would indicate some set
  5366. X#  level of indentation, and perhaps a font change.  If you don't have an
  5367. X#  end code for a particular SGML designator, just leave it blank.
  5368. X#
  5369. X############################################################################
  5370. X#
  5371. X#  Links: stripsgml.icn
  5372. X#
  5373. X############################################################################
  5374. X
  5375. X
  5376. Xprocedure readtbl(f)
  5377. X
  5378. X    local t, line, k, on_sequence, off_sequence
  5379. X
  5380. X    /f & stop("readtbl:  Arg must be a valid open file.")
  5381. X
  5382. X    t := table()
  5383. X
  5384. X    every line := trim(!f,'\t ') do {
  5385. X    line ? {
  5386. X        k := tabslashupto('\t:') &
  5387. X        tab(many('\t:')) &
  5388. X        on_sequence := tabslashupto('\t:') | tab(0)
  5389. X        tab(many('\t:'))
  5390. X        off_sequence := tab(0)
  5391. X    } | stop("readtbl:  Bad map file format.")
  5392. X    insert(t, k, outstr(on_sequence, off_sequence))
  5393. X    }
  5394. X
  5395. X    return t
  5396. X
  5397. Xend
  5398. X
  5399. X
  5400. X
  5401. Xprocedure tabslashupto(c,s)
  5402. X
  5403. X    POS := &pos
  5404. X
  5405. X    while tab(upto('\\' ++ c)) do {
  5406. X    if ="\\" then {
  5407. X        move(1)
  5408. X        next
  5409. X    }
  5410. X    else {
  5411. X        if any(c) then {
  5412. X        suspend &subject[POS:.&pos]
  5413. X        }
  5414. X    }
  5415. X    }
  5416. X
  5417. X    &pos := POS
  5418. X    fail
  5419. X
  5420. Xend
  5421. SHAR_EOF
  5422. true || echo 'restore of readtbl.icn failed'
  5423. rm -f _shar_wnt_.tmp
  5424. fi
  5425. # ============= slashbal.icn ==============
  5426. if test -f 'slashbal.icn' -a X"$1" != X"-c"; then
  5427.     echo 'x - skipping slashbal.icn (File already exists)'
  5428.     rm -f _shar_wnt_.tmp
  5429. else
  5430. > _shar_wnt_.tmp
  5431. echo 'x - extracting slashbal.icn (Text)'
  5432. sed 's/^X//' << 'SHAR_EOF' > 'slashbal.icn' &&
  5433. X############################################################################
  5434. X#
  5435. X#    Name:     slashbal.icn
  5436. X#
  5437. X#    Title:     Bal() with backslash escaping
  5438. X#
  5439. X#    Author:     Richard L. Goerwitz
  5440. X#
  5441. X#    Version: 1.4
  5442. X#
  5443. X############################################################################
  5444. X#
  5445. X#  I am often frustrated at bal()'s inability to deal elegantly with
  5446. X#  the common \backslash escaping convention (a way of telling Unix
  5447. X#  Bourne and C shells, for instance, not to interpret a given
  5448. X#  character as a "metacharacter").  I recognize that bal()'s generic
  5449. X#  behavior is a must, and so I wrote slashbal() to fill the gap.
  5450. X#
  5451. X#  Slashbal behaves like bal, except that it ignores, for purposes of
  5452. X#  balancing, any c2/c3 char which is preceded by a backslash.  Note
  5453. X#  that we are talking about internally represented backslashes, and
  5454. X#  not necessarily the backslashes used in Icon string literals.  If
  5455. X#  you have "\(" in your source code, the string produced will have no
  5456. X#  backslash.  To get this effect, you would need to write "\\(."
  5457. X#
  5458. X#  BUGS:  Note that, like bal() (v8), slashbal() cannot correctly
  5459. X#  handle cases where c2 and c3 intersect.
  5460. X#
  5461. X############################################################################
  5462. X#
  5463. X#  Links: none
  5464. X#
  5465. X############################################################################
  5466. X
  5467. Xprocedure slashbal(c1, c2, c3, s, i, j)
  5468. X
  5469. X    local twocs, allcs, chr2, count
  5470. X
  5471. X    /c1 := &cset
  5472. X    /c2 := '('
  5473. X    /c3 := ')'
  5474. X    twocs := c2 ++ c3
  5475. X    allcs := c1 ++ c2 ++ c3 ++ '\\'
  5476. X
  5477. X    /s := \&subject | stop("slashbal:  No string argument.")
  5478. X    /i := \&pos | 1
  5479. X    /j := *s + 1
  5480. X
  5481. X    count := 0
  5482. X    s ? {
  5483. X    tab(i) | fail
  5484. X    while tab(upto(allcs)) do {
  5485. X        chr := move(1)
  5486. X        if chr == "\\" & any(twocs) then {
  5487. X        chr2 := move(1)
  5488. X        &pos > j & fail
  5489. X        if any(c1, chr) & count = 0 then
  5490. X            suspend .&pos - 2
  5491. X        if any(c1, chr2) & count = 0 then
  5492. X            suspend .&pos - 1
  5493. X        }
  5494. X        else {
  5495. X        &pos > j & fail
  5496. X        if any(c1, chr) & count = 0 then
  5497. X            suspend .&pos - 1
  5498. X        if any(c2, chr) then
  5499. X            count +:= 1
  5500. X        else if any(c3, chr) then
  5501. X            count -:= 1
  5502. X        }
  5503. X    }
  5504. X    }
  5505. X
  5506. Xend
  5507. SHAR_EOF
  5508. true || echo 'restore of slashbal.icn failed'
  5509. rm -f _shar_wnt_.tmp
  5510. fi
  5511. # ============= README ==============
  5512. if test -f 'README' -a X"$1" != X"-c"; then
  5513.     echo 'x - skipping README (File already exists)'
  5514.     rm -f _shar_wnt_.tmp
  5515. else
  5516. > _shar_wnt_.tmp
  5517. echo 'x - extracting README (Text)'
  5518. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  5519. XRe:  stripsgml.icn & associated files
  5520. X
  5521. XThis program is documented in the various source files, most notably
  5522. Xstripsgml.icn.  Please look them over, even if you are not an Icon
  5523. Xprogrammer.
  5524. X
  5525. XIn order to compile this program, you will need an Icon interpreter
  5526. X(or compiler).  If you do not have it, get it.  It is free, and can
  5527. Xbe obtained via ftp from cs.arizona.edu.  If you do not have access
  5528. Xto the internet, drop a line to the icon-project@arizona.edu, and
  5529. Xthey will fill you in on what to do.
  5530. X
  5531. XIf you are working on a Unix system, you can simply mv Makefile.dist
  5532. Xto Makefile, and then make.  Users on other systems will need to
  5533. Xtype:
  5534. X
  5535. X     icont -o stripsgml readtbl.icn slashbal.icn stripsgml.icn stripunb.icn
  5536. X
  5537. XAs I said above, see the file stripsgml.icn for more information on how
  5538. Xto use this program.  This program is not fancy, and handles only the
  5539. Xsimplest <>-style markup.  It is in no way an attempt to handle the full
  5540. Xmetalanguage!
  5541. X
  5542. X-Richard (goer@sophist.uchicago.edu)
  5543. SHAR_EOF
  5544. true || echo 'restore of README failed'
  5545. rm -f _shar_wnt_.tmp
  5546. fi
  5547. # ============= Makefile.dist ==============
  5548. if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
  5549.     echo 'x - skipping Makefile.dist (File already exists)'
  5550.     rm -f _shar_wnt_.tmp
  5551. else
  5552. > _shar_wnt_.tmp
  5553. echo 'x - extracting Makefile.dist (Text)'
  5554. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
  5555. XPROGNAME = stripsgml
  5556. X
  5557. X# Please edit these to reflect your local file structure & conventions.
  5558. XDESTDIR = /usr/local/bin
  5559. XOWNER = bin
  5560. XGROUP = bin
  5561. X
  5562. XSRC = $(PROGNAME).icn stripunb.icn readtbl.icn slashbal.icn
  5563. X
  5564. X$(PROGNAME): $(SRC)
  5565. X    icont -o $(PROGNAME) $(SRC)
  5566. X
  5567. X# Pessimistic assumptions regarding the environment (in particular,
  5568. X# I don't assume you have the BSD "install" shell script).
  5569. Xinstall: $(PROGNAME)
  5570. X    @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
  5571. X    cp $(PROGNAME) $(DESTDIR)/
  5572. X    chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  5573. X    chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  5574. X    @echo "\nInstallation done.\n"
  5575. X
  5576. Xclean:
  5577. X    -rm -f *~ .u?
  5578. X    -rm -f $(PROGNAME)
  5579. SHAR_EOF
  5580. true || echo 'restore of Makefile.dist failed'
  5581. rm -f _shar_wnt_.tmp
  5582. fi
  5583. exit 0
  5584.  
  5585. From goer%sophist@gargoyle.uchicago.edu  Thu Dec  6 22:48:10 1990
  5586. Resent-From: goer%sophist@gargoyle.uchicago.edu
  5587. Received: from MERLIN.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP
  5588.     id AA28085; Thu, 6 Dec 90 22:48:10 -0700
  5589. Return-Path: goer@sophist.uchicago.edu
  5590. Received: from gargoyle.uchicago.edu by Arizona.edu with PMDF#10282; Thu, 6 Dec
  5591.  1990 22:47 MST
  5592. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  5593.  (4.0/1.14) id AA05683; Thu, 6 Dec 90 23:47:26 CST
  5594. Received: by sophist (4.1/UofC3.1X) id AA07496; Thu, 6 Dec 90 23:50:44 CST
  5595. Resent-Date: Thu, 6 Dec 1990 22:47 MST
  5596. Date: Thu, 6 Dec 90 23:50:44 CST
  5597. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  5598. Subject: klondike
  5599. Resent-To: icon-group@cs.arizona.edu
  5600. To: icon-group@arizona.edu
  5601. Resent-Message-Id: <D4D38E850C402D3C@Arizona.edu>
  5602. Message-Id: <9012070550.AA07496@sophist>
  5603. X-Envelope-To: icon-group@CS.Arizona.EDU
  5604. X-Vms-To: icon-group@Arizona.edu
  5605.  
  5606.     Richard Goerwitz writes [re Klondike]:
  5607.  
  5608.      > So far, no luck compiling it under Xenix.  I'll try to figure
  5609.      > out the problem, and perhaps re-post a Unix version some time in
  5610.      > the near future.
  5611.  
  5612.     I hope you will.  Icon needs a great, portable game.
  5613.  
  5614. I've located the problems.  Basically they are simply that klondike
  5615. a) calls kbhit, which simply can't be done easily and portably from
  5616. within Icon under Unix, b) that it calls getch(), c) that it uses
  5617. the cursor report request to test for ANSI console conformancy, and
  5618. d) that it mixes straight text with screen control codes.  These
  5619. problems are mainly pretty easy to get around.  Kbhit() is called
  5620. but once, as I recall.  I wrote a getch() implementation for Unix
  5621. that will cover (b).  Under Unix, (c) isn't necessary (we'll just
  5622. check the current environment).  I still haven't figured an easy
  5623. way to lift screen control codes out of write() functions outputting
  5624. straight text, but even in a worst case scenario it will mean just
  5625. spending some time doing searches and replaces.
  5626.  
  5627. Klondike is indeed a nice game under DOS.  Really nicely done.  And
  5628. this from a guy who claims to be a novice at Icon!
  5629.  
  5630. Ron, you'll be the first I'll let know if I do in fact actually get
  5631. a Unix version out, since I know you are running Xenix like me, and
  5632. also (like me) have some of those blasted magic cookie terminals
  5633. sitting around.
  5634.  
  5635. -Richard
  5636.  
  5637. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Fri Dec  7 10:08:19 1990
  5638. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  5639.     id AA24517; Fri, 7 Dec 90 10:08:19 -0700
  5640. Received: by uwm.edu; id AA00863; Fri, 7 Dec 90 11:08:11 -0600
  5641. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  5642.           Fri,  7 Dec 90 08:23:04 CDT
  5643. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  5644.           Fri, 7 Dec 1990 08:10 CDT
  5645. Date: Fri, 7 Dec 1990 08:09 CDT
  5646. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  5647. Subject: Klondike - Neato
  5648. To: icon-group@cs.arizona.edu
  5649. Message-Id: <23551171406002A9@mis.mcw.edu>
  5650. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  5651. X-Envelope-To: icon-group@cs.arizona.edu
  5652. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  5653.  
  5654.  
  5655. I liked both versions. I got the original PC one running quickly. I liked
  5656. the colors. But my chief platform is VAX VMS with VT compatible terminals.
  5657. So the ANSI version was welcome. I also took it one step further by using
  5658. the ANSI line drawing. For example I replaced "|" with "\e(0x\e(B" and
  5659. likewise for the tops and bottoms of cards. I also had to comment out a lot
  5660. of getch() and kbhit() which isn't available from VMS, and add read() instead.
  5661. Fortunately my wyse terminal also has a 25 line mode.
  5662.  
  5663. These added escape sequences may slow things done a little, but the
  5664. esthetics are worth it. My daughter loves it, although she gets lazy after
  5665. a few minutes and shifts into automatic.
  5666.  
  5667. Thanx for the nifty program. I'm interested in game playing heuristics.
  5668. I'd like to post another one I use on my daughter. It's call Spelling test.
  5669.  
  5670. I type the words into a file. This file is then redirected into the spelltest
  5671. program which asks for words. It assumes that you have the words on another
  5672. sheet as well from which the test is administered. The words can be given in
  5673. any order. The masters and answers are then sorted and compared in parallel.
  5674. It works almost like magic as long as the words are not too lexically similar
  5675. and the student isn't too bad of a speller. Perhaps the parallel checking might
  5676. have been done better with coexpressions, but I'm not skilled with them.
  5677.  
  5678. #
  5679. # SPELLTEST.ICN          11/26/90          BY TENAGLIA
  5680. #
  5681. # THIS SIMPLE PROGRAM ADMINISTERS A SPELLING TEST. THE WORDS SHOULD BE LISTED
  5682. # ONE PER LINE IN AN ANSWER FILE. THE TEACHER CAN ISSUE THE WORDS IN ANY ORDER
  5683. # AS THE TRIES AND ANSWERS ARE FINALY SORTED AND COMPARED IN PARALLEL. THIS
  5684. # SORT OF IMPLIES THAT THE WORDS SHOULD NOT BE TOO LEXICALLY ALIKE. THE GOOF
  5685. # UPS AND SCORES ARE OUTPUT AT THE END OF THE TEST. THE ANSWER FILE IS PIPED
  5686. # INTO STDIN. USAGE : ICONX SPELLTEST <ANSWERS
  5687. #
  5688. global tty
  5689. procedure main()
  5690.  
  5691.   answers := []          # THE CORRECT WORDS LOADED HERE
  5692.   words   := []          # THE STUDENTS TRIES STORED HERE
  5693.   tally   := table(0)    # SCORE KEEPER
  5694.   tty     := open("tt:","b")
  5695. #
  5696. # INITIAL DIALOG
  5697. #
  5698.   write("\e[2J\e[H\e#3Spelling Test")
  5699.   write("\e#4Spelling Test")
  5700.   write("\nLoading spelling words...")
  5701.   while put(answers,map(read()))
  5702.   write("Spelling words loaded. Commencing test. ",*answers," problems.\n")
  5703.  
  5704. #
  5705. # ADMINISTER THE TEST
  5706. #
  5707.   every i := 1 to *answers do
  5708.     put(words,map(input("\e#6" || i || ". ")))
  5709.  
  5710. #
  5711. # SORT FOR CORRECTING
  5712. #
  5713.   first  := sort(answers)
  5714.   second := sort(words)
  5715.  
  5716. #
  5717. # CORRECT THE RESULTS
  5718. #
  5719.   every i := 1 to *first do
  5720.     {
  5721.     result := if first[i] == second[i] then "correct" else "incorrect"
  5722.     tally[result] +:= 1
  5723.     (first[i] == second[i]) | write("\e[1;5m",second[i],"\e[m is wrong. It should have been spelled \e[1;5m",first[i],"\e[m")
  5724.     }
  5725.  
  5726. #
  5727. # SUMMARY OF PERFORMANCE
  5728. #
  5729.   write("\n",tally["incorrect"]," were incorrect.")
  5730.   write(tally["correct"]," were correct out of ",*answers," words.")
  5731.   write("Final score is ",tally["correct"]*100/(*answers),"%.")
  5732.   end
  5733.  
  5734. #
  5735. # THIS PROCEDURE TAKES A PROMPTED STRING INPUT
  5736. #
  5737. procedure input(prompt)
  5738.   writes(prompt)
  5739.   return read(tty)
  5740.   end
  5741.  
  5742. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  5743. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  5744. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  5745.  
  5746.  
  5747. From goer%sophist@gargoyle.uchicago.edu  Sat Dec  8 03:50:54 1990
  5748. Resent-From: goer%sophist@gargoyle.uchicago.edu
  5749. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  5750.     id AA02456; Sat, 8 Dec 90 03:50:54 -0700
  5751. Return-Path: goer@sophist.uchicago.edu
  5752. Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:50 MST
  5753. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  5754.  (4.0/1.14) id AA04481; Sat, 8 Dec 90 04:49:50 CST
  5755. Received: by sophist (4.1/UofC3.1X) id AA08404; Sat, 8 Dec 90 04:53:09 CST
  5756. Resent-Date: Sat, 8 Dec 90 03:50 MST
  5757. Date: Sat, 8 Dec 90 04:53:09 CST
  5758. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  5759. Subject: klondike -> unix (preliminary)
  5760. Resent-To: icon-group@cs.arizona.edu
  5761. To: icon-group@arizona.edu
  5762. Resent-Message-Id: <F237BB2DDBC3403C42@Arizona.edu>
  5763. Message-Id: <9012081053.AA08404@sophist>
  5764. X-Envelope-To: icon-group@CS.Arizona.EDU
  5765. X-Vms-To: icon-group@Arizona.edu
  5766.  
  5767. OK, I hacked this together tonight for fun.  It's not perfect.
  5768. The saving mechanism isn't working quite right, and when com-
  5769. piled under DOS the help screen needs work.  I did this so that
  5770. I could run the executable under Xenix at an ANSI console.  It
  5771. will probably work on any Unix variant that implements the -g
  5772. option for stty, and which looks remotely USG.  Who knows, it
  5773. might work under BSD.  Definitely not well tested, though.  I
  5774. kind of hoped that others who had wanted this thing up and run-
  5775. ning under Unix would fix it up some more in the usual hand-me-
  5776. down fashion....
  5777.  
  5778. Five-part shar follows in fairly small pieces.
  5779.  
  5780. -Richard
  5781.  
  5782. ---- Cut Here and feed the following to sh ----
  5783. #!/bin/sh
  5784. # This is a shell archive (produced by shar 3.49)
  5785. # To extract the files from this archive, save it to a file, remove
  5786. # everything above the "!/bin/sh" line above, and type "sh file_name".
  5787. #
  5788. # made 12/08/1990 11:18 UTC by goer@sophist.uchicago.edu
  5789. # Source directory /u/richard/Klondike
  5790. #
  5791. # existing files will NOT be overwritten unless -c is specified
  5792. # This format requires very little intelligence at unshar time.
  5793. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  5794. #
  5795. # This is part 1 of a multipart archive                                    
  5796. # do not concatenate these parts, unpack them in order with /bin/sh        
  5797. #
  5798. # This shar contains:
  5799. # length  mode       name
  5800. # ------ ---------- ------------------------------------------
  5801. #  20981 -r--r--r-- klondike.icn
  5802. #  17168 -r--r--r-- kloncon.icn
  5803. #  15873 -r--r--r-- klonsub.icn
  5804. #  12240 -r--r--r-- itlib.icn
  5805. #   8538 -r--r--r-- getchlib.icn
  5806. #   4418 -r--r--r-- iscreen.icn
  5807. #   4513 -rw-r--r-- klondike.man
  5808. #    477 -rw-r--r-- README
  5809. #    707 -rw-r--r-- Makefile.dist
  5810. #
  5811. if test -r _shar_seq_.tmp; then
  5812.     echo 'Must unpack archives in sequence!'
  5813.     echo Please unpack part `cat _shar_seq_.tmp` next
  5814.     exit 1
  5815. fi
  5816. # ============= klondike.icn ==============
  5817. if test -f 'klondike.icn' -a X"$1" != X"-c"; then
  5818.     echo 'x - skipping klondike.icn (File already exists)'
  5819.     rm -f _shar_wnt_.tmp
  5820. else
  5821. > _shar_wnt_.tmp
  5822. echo 'x - extracting klondike.icn (Text)'
  5823. sed 's/^X//' << 'SHAR_EOF' > 'klondike.icn' &&
  5824. X############################################################################
  5825. X#
  5826. X#    Name:    klondike.icn
  5827. X#
  5828. X#    Title:   klondike card game
  5829. X#
  5830. X#    Author:  Norman H. Azadian, ported to Unix by Richard Goerwitz
  5831. X#
  5832. X#    Version: 1.5  (beta)
  5833. X#
  5834. X############################################################################
  5835. X#
  5836. X#  klondike.icn   900720   NHA
  5837. X#  The Klondike version of Solitaire.
  5838. X#  Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display.
  5839. X#
  5840. X#  TO FIX:
  5841. X#
  5842. X#
  5843. X#  TO DO:
  5844. X#
  5845. X#  -  Use space to step to next non-thumb move, and enter to do it ???
  5846. X#  -  Implement an heuristic to discover optimal play strategy.
  5847. X#
  5848. X#  UNIX VERSION:  This Unix port of the MS-DOS game classifies as some-
  5849. X#  thing of a hack.  It's what I could do in an evening.  Don't bug me
  5850. X#  about it :-).  -RLG
  5851. X#
  5852. X############################################################################
  5853. X#
  5854. X#  Links:
  5855. X#
  5856. X#  See also: kloncon.icn, klonsub.icn
  5857. X#
  5858. X############################################################################
  5859. X
  5860. Xlink  kloncon                       #console I/O
  5861. Xlink  klonsub                       #general subroutines
  5862. X
  5863. Xrecord card(suit, rank)                      #suit is 1..4, rank is 1..13
  5864. X
  5865. X# variables
  5866. Xglobal deckUp, deckDown, stackUp, stackDown        #collections of card
  5867. Xglobal pile                               #ace piles - top rank only
  5868. Xglobal ops                                #list of all operations done
  5869. Xglobal debugging, automaticAce                  #command-line flags
  5870. Xglobal invisible, clicking                   #visual, audible feedback
  5871. Xglobal firstSeed, lastSeed                   #&random remembered
  5872. Xglobal totalGames, totalAces                 #ace pile statistics
  5873. X
  5874. X
  5875. X#  a u t o m a t i c 1
  5876. X# Do 1 move, thumbing as necessary to achieve it.
  5877. X# Fails if there is nothing useful left to do.
  5878. X# This is an internal routine that doesn't worry at all about the user.
  5879. Xprocedure automatic1 ()
  5880. Xlocal s, thumbCount
  5881. X   thumbCount := 0
  5882. X   while thumbCount <= ((*deckUp + *deckDown + 2) / 3)  do  {
  5883. X      if s := suggest()  then  {
  5884. X         push (ops, _move ("M" || s || "0"))
  5885. X         thumbCount := 0
  5886. X         return;
  5887. X      } else {                   #no good move found -- thumb
  5888. X         if (*deckUp = 0)  &  (*deckDown = 0)  then
  5889. X            fail                 #no cards left to thumb through
  5890. X         push (ops, s := thumb())
  5891. X         if 2 < *s  then
  5892. X            return                  #must have turned up an Ace
  5893. X         thumbCount +:= 1
  5894. X      }
  5895. X   }
  5896. Xend                                 #automatic1
  5897. X
  5898. X
  5899. X#  a u t o m a t i c
  5900. X# Run the game, as far as possible, untouched by human hands
  5901. X# This is an internal routine that only worries a little about the user.
  5902. X# Returns when either there is nothing useful left to do or a key is struck.
  5903. Xprocedure automatic ()
  5904. Xlocal s, thumbCount
  5905. X   thumbCount := 0
  5906. X   repeat  {
  5907. X      if \isDOS then {
  5908. X         if kbhit ()  then
  5909. X            return                  #stopped by human intervention
  5910. X      }
  5911. X      if pile[1] = pile[2] = pile[3] = pile[4] = 13  then
  5912. X         return                     #victory
  5913. X      automatic1 ()  |  return
  5914. X      }
  5915. Xend                                 #automatic
  5916. X
  5917. X
  5918. X#  u a u t o m a t i c
  5919. X# Play this hand automatically, untouched by human hands.
  5920. X# This is the fuction that interacts with the user.
  5921. Xprocedure uautomatic ()
  5922. X        writes ("utomatic")
  5923. X   automatic()
  5924. X   if \isDOS then {
  5925. X      if kbhit()  then
  5926. X         if  getch() == "\0"  then  getch()
  5927. X   }
  5928. Xend                                 #uautomatic
  5929. X
  5930. X
  5931. X#  u c o n t i n u o u s
  5932. X# Plays automatic games -- forever (or until any keystroke)
  5933. Xprocedure ucontinuous()
  5934. X   writes ("ontinuous")
  5935. X   repeat  {
  5936. X      writeInfo (string(totalGames) || "   " || string(totalAces))
  5937. X      automatic()
  5938. X      if \isDOS & kbhit()  then  {
  5939. X         if  getch() == "\0"  then     #eat stopping char(s)
  5940. X            getch()
  5941. X         return
  5942. X      } else
  5943. X         totalAces  +:=  pile[1] + pile[2] + pile[3] + pile[4]
  5944. X      totalGames +:= 1
  5945. X      if \isUNIX then {
  5946. X         writeCursor (18, 65)
  5947. X         iputs(getval("ce"))
  5948. X         writes ("Continue?  ")
  5949. X         until (s := getCmdChar ())
  5950. X         map(s) == "n" | next
  5951. X         return
  5952. X      }
  5953. X      lastSeed := newGame()
  5954. X   }
  5955. Xend                                 #ucontinuous
  5956. X
  5957. X
  5958. X#  u h e l p
  5959. X# Provide command summary for user, plus statistics to date, if any.
  5960. Xprocedure uhelp ()
  5961. X   if \isDOS  then
  5962. X      write (VclearAll, Vnormal)
  5963. X   else if \isUNIX  then  {
  5964. X      normal ();  clear ()
  5965. X   }
  5966. X   writeCursor (2, 1)
  5967. X   writes ("Klondike version 1.5  901126 NHA", repl(" ",8), &version)
  5968. X   writeCursor (5, 1)
  5969. X   writes ("The following commands are available:")
  5970. X   writeCursor (8, 8)
  5971. X   bwrite ("^L\tre-draw", " screen")
  5972. X   writeCursor (9, 8)
  5973. X   if \isDOS then
  5974. X      bwrite ("A\tAutomatic", " mode -- plays 1 game by itself until any key is hit")
  5975. X   else if \isUNIX then
  5976. X      bwrite ("A\tAutomatic", " mode -- plays 1 game by itself.")
  5977. X   writeCursor (10, 8)
  5978. X   bwrite ("B\tBoss", " key for when you-know-who visits")
  5979. X   writeCursor (11, 8)
  5980. X   if \isDOS  then
  5981. X      bwrite ("C\tContinuous", " mode -- plays games continuously until any key hit")
  5982. X   else if \isUNIX  then
  5983. X      bwrite ("C\tContinuous", " mode -- plays games by itself")
  5984. X   writeCursor (12, 8)
  5985. X   bwrite ("H,?\tHelp", ", this help screen")
  5986. X   writeCursor (13, 8)
  5987. X   bwrite ("M\tMove", " card (or stack) from Deck/Stack to Stack/Ace pile")
  5988. X   writeCursor (14, 8)
  5989. X   bwrite ("Q\tQuit", " this game")
  5990. X   writeCursor (15, 8)
  5991. X   bwrite ("S\tSuggest", " (another) possible move")
  5992. X   writeCursor (16, 8)
  5993. X   bwrite ("T\tThumb", " through the deck")
  5994. X   writeCursor (17, 8)
  5995. X   bwrite ("U\tUndo", " -- back up one move")
  5996. X   writeCursor (18, 8)
  5997. X   bwrite ("ESC\tEscape", " -- abort current command")
  5998. X   writeCursor (19, 9)
  5999. X   if \debugging  then
  6000. X      bwrite ("Z\tDebug")
  6001. X   writeCursor (20, 1)
  6002. X   if totalGames ~= 0  then
  6003. X      writes ("totalGames = ", totalGames, "      totalAces = ", totalAces,
  6004. X            "     average = ", real(totalAces) / real(totalGames))
  6005. X   writeCursor (23, 1)
  6006. X   bwrite ("", "Press any key to resume game")
  6007. X   writeCursor (24, 1)
  6008. X   if  getch() == "\0"  then  getch()
  6009. X   refreshScreen ()
  6010. Xend                                 #uhelp
  6011. X
  6012. X
  6013. X#  b w r i t e
  6014. X# Boldface first arg in 1-4 string-arg procedure.
  6015. Xprocedure bwrite(a, b[])
  6016. X   if \isDOS  then
  6017. X      writes (Vbold)
  6018. X   else if \isUNIX  then
  6019. X      emphasize()
  6020. X   writes(a)
  6021. X   if \isDOS  then
  6022. X      writes (Vnormal)
  6023. X   else if \isUNIX  then
  6024. X      normal()
  6025. X   every writes(\!b)
  6026. X   return
  6027. Xend
  6028. X
  6029. X
  6030. X#  u m o v e
  6031. X# Move a card from deck to stack, or from stack to ace pile,
  6032. X# or move a stack to another stack.
  6033. X# Parameter is the source [1-7 or D] or &null to indicate that "M" was used
  6034. X# and therefore source should be gathered from the keyboard.
  6035. X# Fails if indicated move is not possible
  6036. X# This is the routine that interacts with the user.
  6037. Xprocedure umove (src)
  6038. Xlocal dst, c, op, moved
  6039. X   if \src  then  {
  6040. X      if \isDOS  then
  6041. X         writes ("\bMove ", Vbold, src)
  6042. X      else if \isUNIX  then  {
  6043. X         writes ("\bMove ")
  6044. X         emphasize ()
  6045. X         writes (src)
  6046. X      }
  6047. X   }
  6048. X   else {
  6049. X      if \isDOS  then
  6050. X         writes ("ove " || Vbold)
  6051. X      else if \isUNIX  then  {
  6052. X         writes ("ove ")
  6053. X         emphasize ()
  6054. X      }
  6055. X      until (src := getCmdChar ())
  6056. X      if src == ESC  then  return
  6057. X   }
  6058. X   if src == "D"  then  {
  6059. X      if *deckUp = 0  then  fail
  6060. X   } else {
  6061. X      if not any ('1234567', src)  then  fail
  6062. X      if *stackUp[src] = 0  then  fail
  6063. X      writeStackNumber (src, Vblink)
  6064. X   }
  6065. X
  6066. X   if \isDOS  then
  6067. X      writes (Vnormal || " to " || Vbold)
  6068. X   else if \isUNIX  then  {
  6069. X      normal ()
  6070. X      writes (" to ")
  6071. X      emphasize ()
  6072. X   }
  6073. X   until (dst := getCmdChar ())
  6074. X   if  src ~== "D"  then  writeStackNumber (src, Vnormal)
  6075. X   if dst == ESC  then  return
  6076. X   if not any ('A1234567', dst)  then  fail
  6077. X   if dst == src  then  fail
  6078. X
  6079. X   return  push (ops, _move("M" || src || dst || "0"))
  6080. Xend                                 #umove
  6081. X
  6082. X
  6083. X#  s u g g e s t
  6084. X# Find a (reasonable) possible move in this situation
  6085. X# This is the internal routine.
  6086. Xprocedure suggest ()
  6087. Xlocal i, j, k, c
  6088. X   #look at deckUp to see if the top card fits on a pile
  6089. X   if c := deckUp[1]  then
  6090. X      if c.rank = (pile[c.suit] + 1)  then
  6091. X         suspend "DA"
  6092. X   #look at deckUp to see if the top card fits on a stack
  6093. X   if c := deckUp[1]  then
  6094. X      every i := 1 to 7  do
  6095. X         if fitOnStack (c, i)  then
  6096. X            suspend "D" || string(i)
  6097. X   #look at each stack to see if top card can be put on ace pile
  6098. X   every i := 1 to 7  do
  6099. X      if c := stackUp[i][-1]  then     #top card
  6100. X         if c.rank = (pile[c.suit] + 1)  then
  6101. X            suspend  string(i) || "A"
  6102. X   #look at each stack to see if something can be (reasonably) moved
  6103. X   every i := 7 to 1 by -1  do
  6104. X      every j := 1 to 7  do
  6105. X         if fitOnStack (stackUp[i][1], j)  then  {
  6106. X            if (0 < *stackDown[i])  then
  6107. X               suspend  string(i) || string(j)
  6108. X            else {
  6109. X               # possibility, but since there are no cards hidden under
  6110. X               # this pile, we reject it UNLESS there are no empty slots
  6111. X               # AND one of the following is true:
  6112. X               #  1) deckUp[1].rank = 13
  6113. X               #  2) there is a king with cards hidden beneath it
  6114. X               c := 0               #number of empty stacks
  6115. X               every k := 1 to 7  do
  6116. X                  if *stackUp[k] = 0  then  c +:= 1
  6117. X               if c = 0  then
  6118. X                  if (deckUp[1].rank = 13)  |
  6119. X                    (every k := 1 to 7  do
  6120. X                        if (stackUp[k][1].rank = 13) &
  6121. X                           (0 < *stackDown[k])  then
  6122. X                           break       #success
  6123. X                    )
  6124. X               then
  6125. X                  suspend  string(i) || string(j)
  6126. X            }
  6127. X         }
  6128. X   #punt
  6129. X   fail
  6130. Xend                                 #suggest
  6131. X
  6132. X
  6133. X#  u s u g g e s t
  6134. X# Suggest a (reasonable) possible move in this situation.
  6135. X# Repeated invocations produce successive possibilities, until the
  6136. X# only thing left to do is Thumb.  After this, it cycles around to the start.
  6137. Xprocedure usuggest (another)
  6138. Xstatic suggestions, i
  6139. Xlocal s, ss
  6140. X   writes ("uggest")
  6141. X   if another = 0  then  {
  6142. X      suggestions := []             #generate a new list of suggestions
  6143. X      every put (suggestions, suggest())
  6144. X      i := 0
  6145. X   }
  6146. X   if ss := suggestions[i+:=1]  then  {
  6147. X      s := "Move " ||   if ss[1] == "A"  then  "Ace"
  6148. X                  else if ss[1] == "D"  then  "Deck"
  6149. X                  else ss[1]
  6150. X      s ||:= " to " || if ss[2] == "A"  then  "Ace" else ss[2]
  6151. X      writeInfo (s)
  6152. X   } else {
  6153. X      writeInfo ("Thumb")
  6154. X      i := 0
  6155. X   }
  6156. Xend                                 #usuggest
  6157. X
  6158. X
  6159. X#  u t e r m i n a t e
  6160. X# Parameter should be non-zero if termination is due to complete success.
  6161. X# Returns success to quit this game and start another.
  6162. X# Returns failure to just continue this game.
  6163. X# If program termination is wished, that is done right here.
  6164. Xprocedure uterminate (victory)
  6165. Xlocal s
  6166. X   if \victory  then  {
  6167. X      totalAces +:= 52
  6168. X      pile[1] := pile[2] := pile[3] := pile[4] := 0   #prevent victory loops
  6169. X      writeCursor (12, 22)
  6170. X      if \isDOS  then
  6171. X         writes (Vbold, Vblink, "Congratulations -- You've WON !!!", Vnormal)
  6172. X      else if \isUNIX  then  {
  6173. X         emphasize ()
  6174. X         writes ("Congratulations -- You've WON !!!")
  6175. X         normal ()
  6176. X      }
  6177. X   } else
  6178. X      writes ("uit")
  6179. X   if \isDOS  then
  6180. X      writeInfo (Vbold || "Another game? ")
  6181. X   else if \isUNIX  then
  6182. X      writeInfo ("Another game? ")
  6183. X   until (s := getCmdChar ())
  6184. X   if s  == ESC  then  fail()       #didn't really want to quit anyway
  6185. X   if s  == "Y"  then  return       #please start a new game
  6186. X   if s ~== "N"  then  return complain ()
  6187. X
  6188. X   #program termination requested
  6189. X   if \isDOS then
  6190. X      writes ("\33[=7h", Vnormal)         #set cursor wrap mode, normal attr
  6191. X   else if \isUNIX  then
  6192. X      normal ()  &  clear ()
  6193. X   totalGames +:= 1
  6194. X   if /victory  then
  6195. X      totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
  6196. X   writeCursor (2, 1)
  6197. X   writes (VclearAll, "In ", totalGames, " games, you put ", totalAces,
  6198. X         " cards on the ace piles")
  6199. X   writeCursor (3, 1)
  6200. X   write ("average = ", real(totalAces) / real(totalGames), " per game")
  6201. X   writeCursor (5, 1)
  6202. X   if \isUNIX  then  reset_tty()
  6203. X   exit ()
  6204. Xend                                 #uterminate
  6205. X
  6206. X
  6207. X#  u d e b u g
  6208. X# Additional commands to support the implementer.
  6209. Xprocedure udebug ()
  6210. Xlocal s, d, c, name
  6211. X   if not \debugging  then  return complain()
  6212. X   writes ("\bDebug ")
  6213. X   until (s := getCmdChar ())
  6214. X   case s  of  {
  6215. X      ESC      :  fail
  6216. X      "A"      :  {
  6217. X               writes ("gain")
  6218. X               &random := lastSeed
  6219. X               writeCursor (23, 1)
  6220. X               write (Vbold, "&random set.  Quit to play this game again.",
  6221. X                     Vnormal, VclearEOL)
  6222. X            }
  6223. X      "D"      :  display()
  6224. X      "H"|"?"  :  {
  6225. X               writes (if s == "?" then "\bhelp" else "elp")
  6226. X               writeCursor (23, 1)
  6227. X               write (Vbold,
  6228. X                 "Again, Dump, Options, Move, Peek{1-7UD}, Restore, Save, Toggle{ACT}.",
  6229. X                Vnormal, VclearEOL)
  6230. X            }
  6231. X      "M"      :  {
  6232. X               writes ("ove ")
  6233. X               until (s := getCmdChar ()) #Source
  6234. X               if s == ESC  then  fail
  6235. X               if s == "A"  then  fail
  6236. X               until (d := getCmdChar ()) #Destination
  6237. X               if d == ESC  then  fail
  6238. X               if d == s  then  fail
  6239. X               if not any('1234567', d)  then  fail
  6240. X               if s == "D"  then  {
  6241. X                  if *deckUp = 0  then  fail
  6242. X                  put (stackUp[d], get(deckUp))
  6243. X                  writeDeckUp ()
  6244. X                  writeStack (d)
  6245. X                  push (ops, "MD" || d || "0")
  6246. X               } else {
  6247. X                  c := "123456789abcdef"[*stackUp[s]]
  6248. X                  moveStack (s, d)
  6249. X                  push (ops, "M" || s || d || c)
  6250. X               }
  6251. X            }
  6252. X      "O"      :  {
  6253. X               writes ("ptions")
  6254. X               writeCursor (23, 1)
  6255. X               write (Vbold,
  6256. X                if \automaticAce then "AutomaticAce "  else  " ",
  6257. X                if \clicking then "Clicking "  else  " ",
  6258. X                " &trace=", &trace,
  6259. X                " seeds=", firstSeed, ",", lastSeed, Vnormal, VclearEOL)
  6260. X            }
  6261. X      "P"      :  {
  6262. X               writes ("eek ")
  6263. X               until (s := getCmdChar ())
  6264. X               if s == ESC  then  fail
  6265. X               writeCursor (23, 1)
  6266. X               writes (VclearEOL, Vnormal)
  6267. X               if any('1234567', s)  then  showList (stackDown[s])
  6268. X               else if s == "D"      then  showList (deckDown)
  6269. X               else if s == "U"      then  showList (deckUp)
  6270. X               else complain ()
  6271. X            }
  6272. X      "R"      :  {
  6273. X               writes ("estore")
  6274. X               until (s := getCmdChar ())
  6275. X               if s == ESC  then  fail
  6276. X               name := "klondike.sv" || s
  6277. X               if (d := restoreState(name))  then  {
  6278. X                  refreshScreen()
  6279. X                  writeCursor (23, 1)
  6280. X                  write (Vbold, "Restored position from file ", name,
  6281. X                        " of ", d, Vnormal, VclearEOL)
  6282. X               } else {
  6283. X                  writeCursor (23, 1)
  6284. X                  write (Vblink, "Can't restore from file ", name, ".",
  6285. X                        Vnormal, VclearEOL)
  6286. X               }
  6287. X            }
  6288. X      "S"      :  {
  6289. X               writes ("ave ")
  6290. X               until (s := getCmdChar ())
  6291. X               if s == ESC  then  fail
  6292. X               name := "klondike.sv" || s
  6293. X               writeCursor (23, 1)
  6294. X               if saveState (name)  then
  6295. X                  write (Vbold, "Position saved in file ",name,
  6296. X                        Vnormal, VclearEOL)
  6297. X               else
  6298. X                  write (Vblink, "Can't save in file ", name, ".",
  6299. X                        Vnormal, VclearEOL)
  6300. X            }
  6301. X      "T"      :  {
  6302. X               writes ("oggle ")
  6303. X               until (s := getCmdChar ())
  6304. X               if s == ESC  then  fail
  6305. X               case s  of  {
  6306. X                  "A"      : automaticAce := if \automaticAce then &null
  6307. X                                                        else 1
  6308. X                  "C"      : clicking  := if \clicking   then &null  else 1
  6309. X                  "T"      : &trace    := if &trace  = 0 then -1     else 0
  6310. X                  default  : complain ()
  6311. X               }                          #case for Toggle
  6312. X            }
  6313. X      default  :  complain ()
  6314. X   }                                #case for Debug command
  6315. Xend                                 #udebug
  6316. X
  6317. X
  6318. X#  u b o s s
  6319. X# Cheese it, the Fuzz.
  6320. X# Quick -- clear the screen and save the state in a file.
  6321. Xprocedure uboss ()
  6322. X   writes ("oss")
  6323. X   if \isDOS  then  {
  6324. X      writes("\33[=7h", VclearAll, "C>")    #set cursor-wrap mode, look innocent
  6325. X      saveState ("klondike.sav")
  6326. X   }
  6327. X   else if \isUNIX  then  {
  6328. X      normal()
  6329. X      clear()
  6330. X      saveState("~/.klondike.sav")
  6331. X      reset_tty()
  6332. X   }
  6333. X   exit ()
  6334. Xend                                 #uboss
  6335. X
  6336. X
  6337. X
  6338. X#  m a i n
  6339. Xprocedure main (av)
  6340. Xlocal s, prevsCmd, maxGames, f_nam
  6341. X
  6342. X   # set defaults
  6343. X   automaticAce   := 1              # automatic ace handling
  6344. X   clicking       := 1              # give audible feedback
  6345. X   debugging      := &null          # no debugging allowed
  6346. X   invisible      := &null          # let's see the action
  6347. X   maxGames       := &null          # interactive mode
  6348. X   &random := map (&clock, ":", "0")      # randomize the seed
  6349. X
  6350. X   # deal with command-line parameters
  6351. X   while  s := get (av)  do
  6352. X      case  map (s, &lcase, &ucase)  of  {
  6353. X         "-A"  :  automaticAce := &null   #disable automatic ace handling
  6354. X         "-B"  :  maxGames  := get (av)   #batch mode, this many games
  6355. SHAR_EOF
  6356. true || echo 'restore of klondike.icn failed'
  6357. fi
  6358. echo 'End of  part 1'
  6359. echo 'File klondike.icn is continued in part 2'
  6360. echo 2 > _shar_seq_.tmp
  6361. exit 0
  6362.  
  6363. From goer%sophist@gargoyle.uchicago.edu  Sat Dec  8 03:51:42 1990
  6364. Resent-From: goer%sophist@gargoyle.uchicago.edu
  6365. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  6366.     id AA02492; Sat, 8 Dec 90 03:51:42 -0700
  6367. Return-Path: goer@sophist.uchicago.edu
  6368. Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:50 MST
  6369. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  6370.  (4.0/1.14) id AA04503; Sat, 8 Dec 90 04:50:40 CST
  6371. Received: by sophist (4.1/UofC3.1X) id AA08417; Sat, 8 Dec 90 04:53:59 CST
  6372. Resent-Date: Sat, 8 Dec 90 03:51 MST
  6373. Date: Sat, 8 Dec 90 04:53:59 CST
  6374. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  6375. Subject: klondike, part 02 of 05
  6376. Resent-To: icon-group@cs.arizona.edu
  6377. To: icon-group@arizona.edu
  6378. Resent-Message-Id: <F2379D404493403944@Arizona.edu>
  6379. Message-Id: <9012081053.AA08417@sophist>
  6380. X-Envelope-To: icon-group@CS.Arizona.EDU
  6381. X-Vms-To: icon-group@Arizona.edu
  6382.  
  6383. ---- Cut Here and feed the following to sh ----
  6384. #!/bin/sh
  6385. # this is klondike.02 (part 2 of a multipart archive)
  6386. # do not concatenate these parts, unpack them in order with /bin/sh
  6387. # file klondike.icn continued
  6388. #
  6389. if test ! -r _shar_seq_.tmp; then
  6390.     echo 'Please unpack part 1 first!'
  6391.     exit 1
  6392. fi
  6393. (read Scheck
  6394.  if test "$Scheck" != 2; then
  6395.     echo Please unpack part "$Scheck" next!
  6396.     exit 1
  6397.  else
  6398.     exit 0
  6399.  fi
  6400. ) < _shar_seq_.tmp || exit 1
  6401. if test ! -f _shar_wnt_.tmp; then
  6402.     echo 'x - still skipping klondike.icn'
  6403. else
  6404. echo 'x - continuing file klondike.icn'
  6405. sed 's/^X//' << 'SHAR_EOF' >> 'klondike.icn' &&
  6406. X         "-C"  :  clicking  := &null      #run silent
  6407. X         "-D"  :  debugging    := 1       #grant all sorts of perqs
  6408. X         "-R"  :  &random      := get (av)   #unrandomize
  6409. X      default  :  {write ("klondike  [-ACD]  [-B gameCount]  [-R randomSeed]")
  6410. X           if \isUNIX  then  reset_tty()
  6411. X               stop("klondike: bogus option ", s)  }
  6412. X      }
  6413. X
  6414. X   totalGames := totalAces := 0
  6415. X
  6416. X   if \maxGames  then  {
  6417. X      # In Batch mode there is absolutely no console I/O.
  6418. X      # The requested number of games is played
  6419. X      # and the average result is printed on the standard output.
  6420. X      invisible := 1
  6421. X      clicking  := &null
  6422. X      totalGames := maxGames
  6423. X      while 0 <= (maxGames -:= 1)  do  {
  6424. X         newGame ()
  6425. X         while automatic1 ()              #don't allow user to interrupt
  6426. X         totalAces  +:=  pile[1] + pile[2] + pile[3] + pile[4]
  6427. X      }
  6428. X      write (real(totalAces) / real(totalGames))
  6429. X      if \isUNIX  then  reset_tty()
  6430. X      exit ()
  6431. X   }
  6432. X
  6433. X
  6434. X   initConstants()                        #for console I/O
  6435. X   firstSeed := &random                #initial seed
  6436. X
  6437. X   lastSeed := newGame ()
  6438. X   #if last game terminated via the Boss key, then restore it now
  6439. X   if \isDOS  then
  6440. X      f_nam := "klondike.sav"
  6441. X   else if \isUNIX  then
  6442. X      f_nam := "~/.klondike.sav"
  6443. X   if restoreState (f_nam)  then  {
  6444. X      refreshScreen ()
  6445. X      writeInfo ("Game restored")
  6446. X      close (open (f_nam, "c"))     #truncate boss save file
  6447. X   }
  6448. X
  6449. X
  6450. X   repeat  {                           #game loop
  6451. X      prevsCmd := "x"                     #anything but "S"uggest
  6452. X
  6453. X   #respond to user input
  6454. X      repeat  {                           #command loop
  6455. X         writeCursor (18, 65)
  6456. X         if \isDOS  then
  6457. X            writes (VclearEOL || Vnormal || "> ")  #clear command line
  6458. X         else if \isUNIX  then  {
  6459. X            iputs (getval("ce"))
  6460. X            normal ()
  6461. X            writes ("> ")  #clear command line
  6462. X         }
  6463. X         if pile[1] = pile[2] = pile[3] = pile[4] = 13  then
  6464. X            if uterminate (1) then break     # VICTORY!
  6465. X         s := getCmdChar ()
  6466. X         writeInfo ("")                   #clear info line
  6467. X         writeCursor (18, 68)
  6468. X         case  s  of  {
  6469. X            "?"|"H"  :  uhelp()
  6470. X            "1"|"2"|"3"|"4"|"5"|"6"|"7"|"D"  :
  6471. X                     if not umove(s) then complain()
  6472. X            "A"      :  uautomatic()               #look Ma, no hands!
  6473. X            "B"      :  uboss()                    #bail out -- quick
  6474. X            "C"      :  ucontinuous()              #no hands, forever
  6475. X            "M"      :  if not umove(&null) then complain()
  6476. X            "Q"      :  if uterminate(&null) then break  #new game
  6477. X            "S"      :  usuggest (if s == prevsCmd then 1 else 0)
  6478. X            "T"      :  { writes("humb");  push(ops, thumb()) }
  6479. X            "U"      :  undo()
  6480. X            "Z"      :  udebug()
  6481. X            "\^L" :  refreshScreen()
  6482. X            ESC      :  s                       #do nothing here
  6483. X            default  :  complain()
  6484. X         }                       #case
  6485. X         prevsCmd := s
  6486. X      }                          #repeat command
  6487. X      totalAces  +:= pile[1] + pile[2] + pile[3] + pile[4]
  6488. X      totalGames +:= 1
  6489. X      lastSeed := newGame ()
  6490. X   }                             #repeat game
  6491. Xend                                 #main
  6492. SHAR_EOF
  6493. echo 'File klondike.icn is complete' &&
  6494. true || echo 'restore of klondike.icn failed'
  6495. rm -f _shar_wnt_.tmp
  6496. fi
  6497. # ============= kloncon.icn ==============
  6498. if test -f 'kloncon.icn' -a X"$1" != X"-c"; then
  6499.     echo 'x - skipping kloncon.icn (File already exists)'
  6500.     rm -f _shar_wnt_.tmp
  6501. else
  6502. > _shar_wnt_.tmp
  6503. echo 'x - extracting kloncon.icn (Text)'
  6504. sed 's/^X//' << 'SHAR_EOF' > 'kloncon.icn' &&
  6505. X############################################################################
  6506. X#
  6507. X#    Name:    kloncon.icn
  6508. X#
  6509. X#    Title:   klondike console interface routines
  6510. X#
  6511. X#    Author:  Norman H. Azadian
  6512. X#
  6513. X#    Version: 1.3
  6514. X#
  6515. X############################################################################
  6516. X#
  6517. X#  kloncon.icn 901029   NHA
  6518. X#  Console interface routines for Klondike
  6519. X#  Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display.
  6520. X#
  6521. X#  TO FIX:
  6522. X#
  6523. X#
  6524. X#  TO DO:
  6525. X#
  6526. X#  -  termcap for portability ??
  6527. X#  -  click for each card moved in a stack ?
  6528. X#
  6529. X############################################################################
  6530. X#
  6531. X#  Links:
  6532. X#
  6533. X#  See also: klondike.icn, klonsub.icn
  6534. X#
  6535. X############################################################################
  6536. X
  6537. X
  6538. X# constants
  6539. Xglobal   suitID                              #suit identification chars
  6540. Xglobal   isDOS                               # 1 when running under DOS
  6541. Xglobal   isUNIX                         # 1 when running under UNIX
  6542. Xglobal   isXENIXconsole                      # 1 if XENIX ansi console
  6543. Xglobal   monochrome                          # 1 when running Black&White
  6544. X# Video control strings (ANSI.SYS)
  6545. Xglobal  ESC
  6546. Xglobal   Vnormal, Vreverse, Vblink, Vbold, VclearAll, VclearEOL, Vbell
  6547. Xglobal   color                            #list of suit color strings
  6548. X
  6549. X
  6550. X#  i n i t C o n s t a n t s
  6551. X# Initialize the program "constants".  These are actually variables that
  6552. X# are set just once at the beginning of the world.
  6553. Xprocedure initConstants ()
  6554. Xlocal i
  6555. Xlocal Vred, Vblack                        #suit color strings
  6556. X
  6557. X   if \invisible  then  return
  6558. X
  6559. X   isUNIX := find("UNIX",&features)
  6560. X   isDOS := find("MS-DOS",&host)
  6561. X   isXENIXconsole := 1(find("XENIX",&host), find("ansi"|"li",getname()))
  6562. X
  6563. X   if \isDOS  then  {
  6564. X      #ensure that we are dealing with an ANSI-compatible screen
  6565. X      writes ("\33[6n")                #request cursor position report
  6566. X      #NOTE that the first character to match should be an ESCape.
  6567. X      #Unfortunately, reads() seems to eat that character
  6568. X      match ("[", reads (&input, 8))  |
  6569. X         stop ("Klondike:  requires (N)ANSI.SYS screen driver")
  6570. X
  6571. X      i := ord (Peek([16r40, 16r49]))        #BIOS display mode byte
  6572. X      case i  of  {
  6573. X         2     :  monochrome := 1
  6574. X         3     :  monochrome := &null     #living color
  6575. X         7     :  monochrome := 1
  6576. X         default  :  {
  6577. X            stop ("Klondike:  unknown display mode ", i)
  6578. X         }
  6579. X      }
  6580. X   } else
  6581. X      monochrome := 1
  6582. X
  6583. X   if \isDOS then {
  6584. X      ESC         := "\33"             #escape character
  6585. X      VclearAll   := "\33[2J"             #also homes cursor
  6586. X      VclearEOL   := "\33[K"
  6587. X      Vnormal     := "\33[0m"
  6588. X      Vbold       := "\33[1m"
  6589. X      Vblink      := "\33[5m"
  6590. X      Vreverse    := "\33[7m"
  6591. X      Vbell       := "\^G"
  6592. X      if \monochrome  then  {
  6593. X         Vred     := Vnormal
  6594. X         Vblack   := Vreverse
  6595. X      } else {
  6596. X         Vred     := "\33[0;47;31m"       # "extra" 0 seems to be necessary
  6597. X         Vblack   := "\33[0;47;30m"
  6598. X      }
  6599. X   }
  6600. X   else if \isUNIX then {
  6601. X      # Check terminal size.
  6602. X      24 < getval("li") < 29 & 79 < getval("co") < 85 |
  6603. X      { reset_tty(); stop("klondike:  terminal must be 80x25.") }
  6604. X      ESC         := "\e"
  6605. X      VclearAll   := getval("cl")
  6606. X      Vnormal     := getval("se") || (getval("ue") | "") |
  6607. X      { reset_tty(); stop("klondike:  terminal must have standout mode.") }
  6608. X      VclearEOL   := Vnormal || getval("ce")
  6609. X      Vbold       := getval("so")
  6610. X      Vblink      := getval("us")
  6611. X      Vreverse    := getval("so")
  6612. X      Vbell       := "\^G"
  6613. X# color not implemented for UNIX
  6614. X#      if \monochrome  then  {
  6615. X         Vred     := Vnormal
  6616. X         Vblack   := Vreverse
  6617. X#      } else {
  6618. X#         Vred     := "\33[0;47;31m"       # "extra" 0 seems to be necessary
  6619. X#         Vblack   := "\33[0;47;30m"
  6620. X#      }
  6621. X   }
  6622. X   else
  6623. X      stop("Klondike:  OS not supported.")
  6624. X
  6625. X   # Suits are: 1=Hearts, 2=Diamonds, 3=Clubs, 4=Spades
  6626. X   suitID := if \isDOS  then  "\3\4\5\6"  else  "HDCS"
  6627. X   color  := [Vred, Vred, Vblack, Vblack]
  6628. Xend                                 #initConstants
  6629. X
  6630. X
  6631. X#  i n i t S c r e e n
  6632. X# Initialize output and write the fixed parts of the screen.
  6633. X# initConstants() must have been called earlier.
  6634. Xprocedure initScreen ()
  6635. Xlocal i
  6636. Xstatic vertical
  6637. Xinitial {
  6638. X   vertical  :=  if \isDOS  then  "\272"  else  "|"
  6639. X}
  6640. X
  6641. X   if \invisible  then  return
  6642. X   if \isDOS  then  {
  6643. X       if \monochrome  then  writes ("\33[=2h")     #25x80 B&W   text mode
  6644. X       else  writes ("\33[=3h")                        #25x80 color text mode
  6645. X       writes (VclearAll, "\33[=7l")             #clear screen, prevent wrap
  6646. X   }
  6647. X   else if \isUNIX  then  {
  6648. X       iputs(getval("se"))
  6649. X       iputs(getval("ue"))
  6650. X       clear()
  6651. X   }
  6652. X
  6653. X   every  i := 1 to 7  do
  6654. X      writeStackNumber (i, Vnormal)
  6655. X   every  i := 2 to 25  do  {
  6656. X      if \isDOS then
  6657. X     writes ("\33[",i,";64H", vertical)
  6658. X      else if \isUNIX then {
  6659. X     iputs(igoto(getval("cm"), 64, i))
  6660. X     writes (vertical)
  6661. X      }
  6662. X   }
  6663. X   if \isDOS  then
  6664. X      writes ("\33[2;64H\311\315\315\315\315SOLITAIRE\315\315\315\315")
  6665. X   else if \isUNIX then {
  6666. X      iputs(igoto(getval("cm"), 64, 2))
  6667. X      writes ("=====SOLITAIRE====")
  6668. X   }
  6669. Xend                                 #initScreen
  6670. X
  6671. X
  6672. X#  w r i t e S t a c k N u m b e r
  6673. X# Write the indicated stack number with the specified video attribute.
  6674. X# Cursor position is preserved -- WARNING: THIS IS NOT NESTABLE.
  6675. Xprocedure writeStackNumber (num, attr)
  6676. X   if \invisible  then  return
  6677. X   if \isDOS  then
  6678. X      writes (ESC, "[s")                  #save cursor position
  6679. X   writeCursor (1, [2,11,20,29,38,47,56][num])
  6680. X   if \isDOS  then  {
  6681. X      writes (attr, num, Vnormal)
  6682. X      writes (ESC, "[u")                  #restore cursor position
  6683. X   }
  6684. X   else if \isUNIX  then  {
  6685. X      iputs(attr); writes(num); iputs(Vnormal)
  6686. X      writeCursor (18, 73)
  6687. X   }
  6688. Xend                                    #writeStackNumber
  6689. X
  6690. X
  6691. X#  w r i t e C u r s o r
  6692. X# Position the cursor to row,col.
  6693. X# Screen origin (top left corner) is row=1 and col=1.
  6694. Xprocedure writeCursor (row, col)
  6695. X   if /invisible  then {
  6696. X       if \isDOS  then
  6697. X       writes ("\33[", row, ";", col, "H")
  6698. X       else if \isUNIX then
  6699. X       iputs(igoto(getval("cm"), col, row))
  6700. X   }
  6701. Xend                                 #writeCursor
  6702. X
  6703. X
  6704. X#  w r i t e F r o n t
  6705. X# Displays an image of the specified card fronts at the specified spot.
  6706. X# WARNING: this eats the list that you provide -- pass a copy() if you care!!
  6707. X# Top left corner of the first card will be placed at the specified position.
  6708. X# Successive cards are displayed two rows higher (lower position on the screen).
  6709. X# Cursor need not be in any particular position before this, and is left
  6710. X# in a random position afterwards.  Video is always left normal (not reversed).
  6711. X# Cards are 7 columns wide by 5 rows tall.
  6712. X# With 25 rows, we can put 12 cards in a stack (assuming we start in row 2).
  6713. X# But if there are 11 in the stack we can only display 4 rows of the top card.
  6714. X# If there are 12 cards, we can only display 2 rows of the topmost card.
  6715. X##We can only write a row at a time due to a problem with ANSI col 80 handling.
  6716. Xprocedure writeFront (cardlist, row, col)
  6717. Xlocal suit, rank, card
  6718. Xstatic vertical, topHorizontal, bottomHorizontal
  6719. Xinitial {
  6720. X   if \isDOS  then  {
  6721. X      vertical := "\263"
  6722. X      topHorizontal    := "\332\304\304\304\304\304\277"
  6723. X      bottomHorizontal := "\300\304\304\304\304\304\331"
  6724. X   } else {
  6725. X      vertical := "|"
  6726. X      topHorizontal    := "-------"
  6727. X      bottomHorizontal := "-------"
  6728. X   }
  6729. X}
  6730. X   if \isDOS then {
  6731. X      while  card := get(cardlist)  do  {
  6732. X         #first 2 rows of card
  6733. X         writeCursor (row+0, col);
  6734. X     writes (Vreverse, topHorizontal)
  6735. X     writeCursor (row+1, col);
  6736. X     writes (vertical, color[card.suit], "A23456789TJQK"[card.rank],
  6737. X         suitID[card.suit], Vreverse, "   ", vertical)
  6738. X     if (*cardlist = 0)  &  (row < 24)  then  {
  6739. X            #next 2 rows of top card unless it's the 12th card on the stack
  6740. X        writeCursor (row+2, col);
  6741. X        writes (Vreverse, vertical, "     ", vertical)
  6742. X        writeCursor (row+3, col);
  6743. X        writes (vertical,"   ",color[card.suit],"A23456789TJQK"[card.rank],
  6744. X            suitID[card.suit], Vreverse, vertical)
  6745. X        if row < 22  then  {
  6746. X               #last row of card unless it's the 11th on the stack
  6747. X               writeCursor (row+4, col);
  6748. X           writes (bottomHorizontal)
  6749. X        }
  6750. X         }
  6751. X         row +:= 2
  6752. X      }
  6753. X      writes (Vnormal)
  6754. X   }
  6755. X   else if \isUNIX then {
  6756. X      if (row = 21, col > 65, getval("li") = 25, \getval("am"))  then
  6757. X      row -:= 1
  6758. X      while  card := get(cardlist)  do  {
  6759. X         #first 2 rows of card
  6760. X         writeCursor (row+0, col);
  6761. X     emphasize (); writes (topHorizontal)
  6762. X     writeCursor (row+1, col);
  6763. X     writes (vertical, color[card.suit], "A23456789TJQK"[card.rank],
  6764. X         suitID[card.suit]); emphasize (); writes ("   ", vertical)
  6765. X     if (*cardlist = 0)  &  (row < 24)  then  {
  6766. X            #next 2 rows of top card unless it's the 12th card on the stack
  6767. X        writeCursor (row+2, col);
  6768. X        emphasize (); writes (vertical, "     ", vertical)
  6769. X        writeCursor (row+3, col);
  6770. X        writes (vertical,"   ",color[card.suit],"A23456789TJQK"[card.rank],
  6771. X            suitID[card.suit]); emphasize (); writes (vertical)
  6772. X        if row < 22  then  {
  6773. X               #last row of card unless it's the 11th on the stack
  6774. X               writeCursor (row+4, col);
  6775. X           writes (bottomHorizontal)
  6776. X        }
  6777. X         }
  6778. X         row +:= 2
  6779. X      }
  6780. X      normal ()
  6781. X   }
  6782. Xend                                 #writeFront
  6783. X
  6784. X
  6785. X#  w r i t e B a c k
  6786. X# Puts an image of the back of a card at the specified spot on the screen.
  6787. Xprocedure writeBack (row, col)
  6788. Xstatic backLine
  6789. Xinitial {
  6790. X   backLine := repl (if \isDOS  then  "\260"  else  "#",  7)
  6791. X}
  6792. X   if \invisible  then  return
  6793. X   if (row = 21, col > 65, \isUNIX, getval("li") = 25, \getval("am"))  then
  6794. X      row -:= 1
  6795. X   writeCursor (row+0, col);  writes (backLine)
  6796. X   writeCursor (row+1, col);  writes (backLine)
  6797. X   writeCursor (row+2, col);  writes (backLine)
  6798. X   writeCursor (row+3, col);  writes (backLine)
  6799. X   writeCursor (row+4, col);  writes (backLine)
  6800. Xend                                 #writeBack
  6801. X
  6802. X
  6803. X#  w r i t e B l a n k
  6804. X# Blanks a card-sized area at the specified spot on the screen.
  6805. Xprocedure writeBlank (row, col)
  6806. Xstatic blankLine
  6807. Xinitial {
  6808. X   blankLine := repl (" ", 7)
  6809. X}
  6810. X   if \invisible  then  return
  6811. X   if (row = 21, col > 65, \isUNIX, getval("li") = 25, \getval("am"))  then
  6812. X      row -:= 1
  6813. X   writeCursor (row+0, col);  writes (blankLine)
  6814. X   writeCursor (row+1, col);  writes (blankLine)
  6815. X   writeCursor (row+2, col);  writes (blankLine)
  6816. X   writeCursor (row+3, col);  writes (blankLine)
  6817. X   writeCursor (row+4, col);  writes (blankLine)
  6818. Xend                                 #writeBlank
  6819. X
  6820. X
  6821. X#  w r i t e S t a c k
  6822. X# Display the specified stack.  Left end is bottom of stackUp, top of stackDown.
  6823. X# Stacks start in row 2, column1; with 2 columns between stacks.
  6824. X# last[] holds, for each stack, the total number of visible cards
  6825. X# on that stack as of the last time writeStack() was called.  This allows
  6826. X# us to simply draw (or erase) the cards that have been added (or subtracted).
  6827. X# By special arrangement, this routine can be called with a negative stack
  6828. X# number!  This is a hint that our idea of what is on the display is actually
  6829. X# wrong, and therefore the entire stack needs to be re-displayed.  This can
  6830. X# happen in two situations:  1) in refreshScreen(), the entire screen is cleared
  6831. X# before calling writeStack();  2) in undo() when undoing a move between
  6832. X# stacks, the bottom card needs to be changed, although the normal algorithm
  6833. X# would consider that it is already correctly displayed.  Note that in neither
  6834. X# case is the stack shrinking, therefore we don't need to worry about erasing
  6835. X# any cards that were displayed last time.
  6836. Xprocedure writeStack (n)
  6837. Xlocal row, col, s
  6838. Xstatic last, blankLine, firstRow, lastRow
  6839. Xinitial  {
  6840. X   last := [0,0,0,0,0,0,0]
  6841. X   blankLine := repl (" ", 7)
  6842. X   firstRow := [2,4,6,8,10,12,14,16,18,20,22,24]   #first row of a card
  6843. X   lastRow  := [6,8,10,12,14,16,18,20,22,24,25,25] #last row of a card
  6844. X}
  6845. X   if \invisible  then  return
  6846. X   if n < 0  then  {
  6847. X      n := -n
  6848. X      last[n] := 0                     #force complete re-write
  6849. X   }
  6850. X
  6851. X   col := 1 + ((n -1) * 9)                #leftmost column for this stack
  6852. X
  6853. X   if *stackUp[n] <= last[n]  then  {
  6854. X      #the stack just got smaller (or stayed the same)
  6855. X      #blank out two rows for each card that has been removed
  6856. X      row := lastRow[last[n]]             #last row used by top card
  6857. X      while *stackUp[n] < last[n]  do  {
  6858. X         writeCursor (row-0, col);  writes (blankLine)
  6859. X         writeCursor (row-1, col);  writes (blankLine)
  6860. X         row -:= 2
  6861. X         last[n] -:= 1                 #count and update simultaneously
  6862. X      }
  6863. X      dieIf (*stackUp[n] ~= last[n], last[n])
  6864. X      #re-write new top card
  6865. X      if *stackUp[n] = 0  then
  6866. X         if *stackDown[n] = 0  then
  6867. X            writeBlank (2, col)
  6868. X         else
  6869. X            writeBack (2, col)
  6870. X      else
  6871. X         writeFront ([stackUp[n][-1]], firstRow[last[n]], col)
  6872. X   } else {
  6873. X      #the stack just got bigger -- display new cards
  6874. X      s := stackUp[n][last[n]-(*stackUp[n]):0]  #list of new cards
  6875. X      writeFront (s, firstRow[last[n]+1], col)
  6876. X      last[n] := *stackUp[n]           #remember how much is displayed
  6877. X   }
  6878. X
  6879. X   writeCursor (2, (7 + col))
  6880. X   writes (" 123456???"[1+*stackDown[n]]) #display the number of hidden cards
  6881. Xend                                 #writeStack
  6882. X
  6883. X
  6884. X#  w r i t e P i l e
  6885. X# Displays an image of the specified ace pile, face up (or blank if empty)
  6886. Xprocedure writePile (n)
  6887. Xstatic pileRow, pileCol
  6888. Xinitial {
  6889. X   pileRow := [3,3,9,9]
  6890. X   pileCol := [66,74,66,74]
  6891. X}
  6892. X   if \invisible  then  return
  6893. X   if  0 = pile[n]  then  writeBlank (pileRow[n], pileCol[n])
  6894. X   else  writeFront ([card(n,pile[n])], pileRow[n], pileCol[n])
  6895. Xend                                 #writePile
  6896. X
  6897. X
  6898. X#  w r i t e D e c k D o w n
  6899. X# Displays an image of deckDown (the face-down deck) in the proper spot.
  6900. Xprocedure writeDeckDown ()
  6901. X   if \invisible  then  return
  6902. X   if 0 < *deckDown  then
  6903. X      writeBack (21, 74)
  6904. X   else
  6905. X      writeBlank (21, 74)
  6906. X   if (\isUNIX, getval("li") = 25, \getval("am"))  then
  6907. X      writeCursor (19, 76)
  6908. X   else
  6909. X      writeCursor (20, 76)
  6910. X   writes (right(*deckDown, 2))
  6911. Xend                                 #writeDeckDown
  6912. X
  6913. X
  6914. X#  w r i t e D e c k U p
  6915. X# Displays an image of deckUp (the face-up deck) in the proper spot.
  6916. Xprocedure writeDeckUp ()
  6917. X   if \invisible  then  return
  6918. X   if 0 < *deckUp  then
  6919. X      writeFront ([deckUp[1]], 21, 66)
  6920. X   else
  6921. X      writeBlank (21, 66)
  6922. X   if (\isUNIX, getval("li") = 25, \getval("am"))  then
  6923. X      writeCursor (19, 68)
  6924. X   else
  6925. X      writeCursor (20, 68)
  6926. X   writes (right(*deckUp, 2))
  6927. Xend                                 #writeDeckUp
  6928. X
  6929. X
  6930. X#  w r i t e I n f o
  6931. X# Displays a new short string (up to 12 printing characters) in the
  6932. X# officially approved information area of the screen.
  6933. X# An empty string results in clearing the area and restoring normal attributes.
  6934. Xprocedure writeInfo (s)
  6935. SHAR_EOF
  6936. true || echo 'restore of kloncon.icn failed'
  6937. fi
  6938. echo 'End of  part 2'
  6939. echo 'File kloncon.icn is continued in part 3'
  6940. echo 3 > _shar_seq_.tmp
  6941. exit 0
  6942.  
  6943. From goer%sophist@gargoyle.uchicago.edu  Sat Dec  8 03:52:25 1990
  6944. Resent-From: goer%sophist@gargoyle.uchicago.edu
  6945. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  6946.     id AA02517; Sat, 8 Dec 90 03:52:25 -0700
  6947. Return-Path: goer@sophist.uchicago.edu
  6948. Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:51 MST
  6949. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  6950.  (4.0/1.14) id AA04506; Sat, 8 Dec 90 04:51:08 CST
  6951. Received: by sophist (4.1/UofC3.1X) id AA08425; Sat, 8 Dec 90 04:54:27 CST
  6952. Resent-Date: Sat, 8 Dec 90 03:51 MST
  6953. Date: Sat, 8 Dec 90 04:54:27 CST
  6954. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  6955. Subject: klondike, part 03 of 05
  6956. Resent-To: icon-group@cs.arizona.edu
  6957. To: icon-group@arizona.edu
  6958. Resent-Message-Id: <F2378841D133403C82@Arizona.edu>
  6959. Message-Id: <9012081054.AA08425@sophist>
  6960. X-Envelope-To: icon-group@CS.Arizona.EDU
  6961. X-Vms-To: icon-group@Arizona.edu
  6962.  
  6963. ---- Cut Here and feed the following to sh ----
  6964. #!/bin/sh
  6965. # this is klondike.03 (part 3 of a multipart archive)
  6966. # do not concatenate these parts, unpack them in order with /bin/sh
  6967. # file kloncon.icn continued
  6968. #
  6969. if test ! -r _shar_seq_.tmp; then
  6970.     echo 'Please unpack part 1 first!'
  6971.     exit 1
  6972. fi
  6973. (read Scheck
  6974.  if test "$Scheck" != 3; then
  6975.     echo Please unpack part "$Scheck" next!
  6976.     exit 1
  6977.  else
  6978.     exit 0
  6979.  fi
  6980. ) < _shar_seq_.tmp || exit 1
  6981. if test ! -f _shar_wnt_.tmp; then
  6982.     echo 'x - still skipping kloncon.icn'
  6983. else
  6984. echo 'x - continuing file kloncon.icn'
  6985. sed 's/^X//' << 'SHAR_EOF' >> 'kloncon.icn' &&
  6986. X   if \invisible  then  return
  6987. X   writeCursor (16, 65)
  6988. X   if \isDOS  then
  6989. X      writes (Vnormal, VclearEOL)
  6990. X   else if \isUNIX  then
  6991. X      normal ()  &  iputs (VclearEOL)
  6992. X   if  *s ~= 0  then  writes (s)
  6993. Xend                                 #writeInfo
  6994. X
  6995. X
  6996. X#  c l i c k
  6997. X# Make a quick sound to accompany card transfers
  6998. Xprocedure click ()
  6999. Xlocal x
  7000. X   if (\clicking)  &  (\isDOS)  then  {
  7001. X      x := InPort (16r61)
  7002. X      OutPort (16r61, 3)
  7003. X      OutPort (16r61, x)
  7004. X   }
  7005. Xend                                 #click
  7006. X
  7007. X
  7008. X#  g e t C m d C h a r
  7009. X# Returns an upper-case command character, echoed to current cursor position.
  7010. X# Fails if character wasn't "normal" and complaint was made.
  7011. X# For ESC, abort information is written, and ESC is returned.
  7012. X# Normal calling sequence (from within a command procedure) is thus:
  7013. X#     until (s := getCmdChar ())
  7014. X#     if s == ESC  then  fail
  7015. Xprocedure getCmdChar ()
  7016. Xlocal s
  7017. X   s := getch ()                    #get command character
  7018. X   if  s == "\0"  then  {           #non-ASCII character
  7019. X      getch ()                      #discard keyboard scan code
  7020. X      complain ()
  7021. X      fail
  7022. X   }
  7023. X   s := map (s, &lcase, &ucase)
  7024. X   if s == ESC  then  {
  7025. X      if \isDOS  then
  7026. X     writeInfo (Vbold || "Cmd Aborted.")
  7027. X      else if \isUNIX  then
  7028. X     writeInfo ("Cmd aborted.")
  7029. X   }
  7030. X   else
  7031. X      writes (s)                    #echo the command character
  7032. X   return  s
  7033. Xend                                 #getCmdChar
  7034. X
  7035. X
  7036. X#  c o m p l a i n
  7037. X# Let the boob know he done something wrong
  7038. X# The short beep produced under isDOS is not as annoying as the normal beeeeep.
  7039. Xprocedure complain ()
  7040. Xlocal x
  7041. X   if \isDOS  then
  7042. X      writeInfo (Vbold || "INVALID")
  7043. X   else if \isUNIX  then
  7044. X      writeInfo ("INVALID")
  7045. X   if \clicking  then
  7046. X      if \isDOS then  {
  7047. X         x := InPort (16r61)
  7048. X         every 1 to 22 do
  7049. X            OutPort (16r61, 3)
  7050. X         OutPort (16r61, x)
  7051. X      } else
  7052. X         writes (Vbell)
  7053. Xend                                 #complain
  7054. X
  7055. X
  7056. X#  r e f r e s h S c r e e n
  7057. X# Re-write entire screen.
  7058. Xprocedure refreshScreen ()
  7059. X   if \invisible  then  return
  7060. X   initScreen ()
  7061. X   every writeStack (-1 to -7 by -1)
  7062. X   every writePile (1 to 4)
  7063. X   writeDeckDown ()
  7064. X   writeDeckUp ()
  7065. Xend                                 #refreshScreen
  7066. SHAR_EOF
  7067. echo 'File kloncon.icn is complete' &&
  7068. true || echo 'restore of kloncon.icn failed'
  7069. rm -f _shar_wnt_.tmp
  7070. fi
  7071. # ============= klonsub.icn ==============
  7072. if test -f 'klonsub.icn' -a X"$1" != X"-c"; then
  7073.     echo 'x - skipping klonsub.icn (File already exists)'
  7074.     rm -f _shar_wnt_.tmp
  7075. else
  7076. > _shar_wnt_.tmp
  7077. echo 'x - extracting klonsub.icn (Text)'
  7078. sed 's/^X//' << 'SHAR_EOF' > 'klonsub.icn' &&
  7079. X############################################################################
  7080. X#
  7081. X#    Name:    klonsub.icn
  7082. X#
  7083. X#    Title:   subroutines for klondike
  7084. X#
  7085. X#    Author:  Norman H. Azadian
  7086. X#
  7087. X#    Version: 1.2
  7088. X#
  7089. X############################################################################
  7090. X#
  7091. X#  Links: 
  7092. X#
  7093. X#  See also: klondike.icn
  7094. X#
  7095. X############################################################################
  7096. X
  7097. X
  7098. X#klonsub.icn   901029   NHA
  7099. X#subroutines for Klondike
  7100. X
  7101. X#  d i e I f
  7102. X# If the first argument succeeds, then write out the remaining args & die.
  7103. X# Note that the remaining arguments must succeed.
  7104. Xprocedure dieIf (failed, writeArgs[])
  7105. X   every writes (&output, !writeArgs)
  7106. X   write (&output)
  7107. X   display ()
  7108. X   every writes (&errout, !writeArgs)
  7109. X   write (&errout)
  7110. X   runerr (500)
  7111. Xend                                 #dieIf
  7112. X
  7113. X
  7114. X#  f i t O n S t a c k
  7115. X# Given a card and a stack number, fail unless card can be added to the stack.
  7116. X# Note that we disallow putting an Ace on a stack, period.  This prevents
  7117. X# ever building a stack with 13 cards, which we can't display in 25 rows.
  7118. Xprocedure fitOnStack (c, n)
  7119. Xlocal top                                       #top card on stack
  7120. X   if *stackUp[n] = 0  then  {
  7121. X      dieIf (*stackDown[n] ~= 0, "Up empty, Down not")
  7122. X      if c.rank ~= 13  then  fail         #only a king can go to empty stack
  7123. X   } else {
  7124. X      top := stackUp[n][-1]            #copy of top card
  7125. X      if (c.rank ~= (top.rank - 1))  then  fail       #wrong rank
  7126. X      if (c.suit < 3)  &  (top.suit < 3)  then  fail     #same color
  7127. X      if (c.suit > 2)  &  (top.suit > 2)  then  fail     #same color
  7128. X      if c.rank = 1  then  fail                    #no ace on stack
  7129. X      dieIf (*stackUp[n] >= 12, "stack too big")
  7130. X   }
  7131. X   return                           #success
  7132. Xend                                 #fitOnStack
  7133. X
  7134. X
  7135. X#  c h e c k 4 a c e
  7136. X# Only has an effect when global automaticAce is set!
  7137. X# Given a stack number, check for an ace as the top of stackUp[n].
  7138. X# If present, move it over to it's ace pile, turn over the next card
  7139. X# from stackDown, and check again.
  7140. X# Must not be more than one up card in stack.
  7141. X# Returns a string of the operations performed.
  7142. Xprocedure check4ace (n)
  7143. Xlocal c, op
  7144. X   op := ""
  7145. X   if \automaticAce  then  {
  7146. X      dieIf (1 < *stackUp[n])
  7147. X      while 0 < *stackUp[n]  do  {
  7148. X         c := stackUp[n][1]               #copy of (top = bottom) up card
  7149. X         if c.rank = 1  then  {           #it's an ace!
  7150. X            pop (stackUp[n])           #remove it from the stack
  7151. X            pile[c.suit] := 1          #move to ace pile
  7152. X            op ||:= c.suit
  7153. X            push (stackUp[n], get(stackDown[n])) #turn over card underneath
  7154. X            writeStack (n)
  7155. X            writePile (c.suit)
  7156. X            click ()
  7157. X         } else
  7158. X            break                   #not an ace
  7159. X      }
  7160. X   }
  7161. X   return op
  7162. Xend                                 #check4ace
  7163. X
  7164. X
  7165. X#  m o v e S t a c k
  7166. X# Move a stack to another stack, no questions asked.
  7167. X# Updates video and audio.
  7168. X# Returns any automatic ace operations that were done as a consequence.
  7169. X##It would be nice to do this in a visually and audibly more satisfying way
  7170. Xprocedure moveStack (src, dst)
  7171. X   while put (stackUp[dst], get(stackUp[src]))
  7172. X   put (stackUp[src], get(stackDown[src]))
  7173. X   writeStack (src)
  7174. X   writeStack (dst)
  7175. X   click ()
  7176. X   return  check4ace (src)
  7177. Xend                                 #moveStack
  7178. X
  7179. X
  7180. X#  _ m o v e
  7181. X# This is the internal move, taking a operation string.  No Thumbs allowed.
  7182. X# Upon success it returns the (possibly modified) operation string.
  7183. Xprocedure _move (op)
  7184. Xlocal src, dst, c, moved
  7185. X   dieIf (op[1] ~== "M", "op is ", op)
  7186. X   src := op[2]
  7187. X   dst := op[3]
  7188. X   moved := 0
  7189. X   if src == "D"  then  {
  7190. X      c := deckUp[1]
  7191. X      if dst == "A"  then  {           # Deck -> Ace
  7192. X         if c.rank = (pile[c.suit] + 1)  then  {
  7193. X            op[4] := c.suit            # Deck -> Ace:  fits - do it
  7194. X            pile[c.suit] +:= 1
  7195. X            writePile (c.suit)
  7196. X            moved := 1
  7197. X         } else
  7198. X            fail                 # Deck -> Ace:  doesn't fit
  7199. X      } else  {                     # Deck -> stack
  7200. X         if fitOnStack (c, dst)  then {
  7201. X            put (stackUp[dst], c)      # Deck -> stack:  fits - do it
  7202. X            writeStack (dst)
  7203. X            moved := 1
  7204. X         } else
  7205. X            fail                 # Deck -> stack: doesn't fit
  7206. X      }
  7207. X      while moved ~= 0  do  {
  7208. X         pop (deckUp)
  7209. X         writeDeckUp ()             # Deck -> somewhere, with success
  7210. X         click ()
  7211. X         moved := 0
  7212. X         if \automaticAce  then  {
  7213. X            if (c := deckUp[1]).rank = 1  then  {  #automatic Ace handling
  7214. X               pile[c.suit] := 1
  7215. X               op ||:= c.suit
  7216. X               writePile (c.suit)
  7217. X               moved := 1
  7218. X            }
  7219. X         }
  7220. X      }
  7221. X   } else {
  7222. X      if dst == "A"  then  {           # stack -> Ace
  7223. X         c := stackUp[src][-1]         #copy of card on top of stack
  7224. X         if c.rank = (pile[c.suit] + 1)  then  {
  7225. X            op[4] := c.suit            # stack -> Ace:  fits - do it
  7226. X            pile[c.suit] +:= 1
  7227. X            pull (stackUp[src])
  7228. X            writeStack (src)
  7229. X            click ()
  7230. X            writePile (c.suit)
  7231. X            if *stackUp[src] = 0  then  {
  7232. X               op[4] +:= 4          #mark this case for undo()
  7233. X               put (stackUp[src], get(stackDown[src]))   #turn over a card
  7234. X               writeStack (src)
  7235. X               click ()
  7236. X               op ||:= check4ace (src)
  7237. X            }
  7238. X         } else {
  7239. X            fail                 # stack -> Ace:  doesn't fit
  7240. X         }
  7241. X      } else {                   # stack -> stack
  7242. X         if fitOnStack (stackUp[src][1], dst)  then  {
  7243. X                                 # stack -> stack:  fits - do it
  7244. X            op[4] := "123456789abcdef"[*stackUp[src]]
  7245. X            op ||:= moveStack (src, dst)
  7246. X         } else
  7247. X            fail                 # stack -> stack:  doesn't fit
  7248. X      }
  7249. X   }
  7250. X   return  op                       #success
  7251. Xend                                 #move
  7252. X
  7253. X
  7254. X#  t h u m b
  7255. X# Move to next spot in deckDown
  7256. X# Returns the operation performed (usually just "T3"), or fail if none possible.
  7257. Xprocedure thumb ()
  7258. Xlocal c, op, moved
  7259. X   if *deckDown = *deckUp = 0  then
  7260. X      return complain()                #no cards left in the deck
  7261. X   if *deckDown = 0  then
  7262. X      while push (deckDown, pop(deckUp))
  7263. X   op :=  "T"  ||  if *deckDown < 3  then  *deckDown  else  3
  7264. X   push (deckUp, pop(deckDown))
  7265. X   push (deckUp, pop(deckDown))
  7266. X   push (deckUp, pop(deckDown))
  7267. X   writeDeckDown ()
  7268. X   moved := 1
  7269. X   while moved ~= 0  do  {
  7270. X      writeDeckUp ()
  7271. X      click ()
  7272. X      moved := 0
  7273. X      if \automaticAce  then  {
  7274. X         if deckUp[1].rank = 1  then  {
  7275. X            c := pop (deckUp)
  7276. X            pile[c.suit] := 1
  7277. X            op ||:= c.suit
  7278. X            writePile (c.suit)
  7279. X            moved := 1
  7280. X         }
  7281. X      }
  7282. X   }
  7283. X   return op
  7284. Xend                                 #thumb
  7285. X
  7286. X
  7287. X#  u n d o
  7288. X# backup one move, including any automatic ace moves
  7289. Xprocedure undo ()
  7290. Xlocal op, suit
  7291. X   writes ("ndo")
  7292. X   if op := pop (ops)  then  {
  7293. X      writeInfo (op)
  7294. X      # op looks like:  Msdixxx
  7295. X      # where x is an [optional] number 1..4 of an ace pile
  7296. X      # and s is either a stack number or "D"
  7297. X      # and d is either "A" or a number 1..7 of a stack
  7298. X      # and i is an extra piece of info which may be valid
  7299. X      case op[1]  of   {
  7300. X      "M"      :  {
  7301. X               dieIf ((*op < 4) | ((/automaticAce) & (4 < *op)), op)
  7302. X               if op[2] == "D"  then  {
  7303. X                  #Move cards from Ace piles to deck, starting at end
  7304. X                  while 4 < *op  do  {
  7305. X                     suit := op[-1]
  7306. X                     pile[suit] := 0
  7307. X                     writePile (suit)
  7308. X                     push (deckUp, card(suit,1))
  7309. X                     writeDeckUp ()
  7310. X                     click ()
  7311. X                     op[-1] := ""
  7312. X                  }
  7313. X                  if op[3] == "A"  then  {
  7314. X                     # unMove Deck to Ace op[4]
  7315. X                     suit := op[4]
  7316. X                     push (deckUp, card(suit,pile[suit]))
  7317. X                     pile[suit] -:= 1
  7318. X                     writePile (suit)
  7319. X                  } else {
  7320. X                     # unMove Deck to stack op[3]
  7321. X                     push (deckUp, pull(stackUp[op[3]]))
  7322. X                     writeStack (op[3])
  7323. X                  }
  7324. X                  writeDeckUp ()
  7325. X               } else {
  7326. X                  #Move cards from Ace piles to stack, starting at end
  7327. X                  while 4 < *op  do  {
  7328. X                     suit := op[-1]
  7329. X                     pile[suit] := 0
  7330. X                     writePile (suit)
  7331. X                     dieIf (1 < *stackUp[op[2]])
  7332. X                     push (stackDown[op[2]], pull(stackUp[op[2]]))
  7333. X                     push (stackUp[op[2]], card(suit,1))
  7334. X                     writeStack (op[2])
  7335. X                     click ()
  7336. X                     op[-1] := ""
  7337. X                  }
  7338. X                  if op[3] == "A"  then  {
  7339. X                     # unMove stack op[2] to Ace pile op[4]
  7340. X                     suit := op[4]
  7341. X                     if 4 < suit  then  {
  7342. X                        suit -:= 4     #ace pile card was last on stack
  7343. X                        dieIf (1 < *stackUp[op[2]])
  7344. X                        push (stackDown[op[2]], pull(stackUp[op[2]]))
  7345. X                     }
  7346. X                     put (stackUp[op[2]], card(suit,pile[suit]))
  7347. X                     pile[suit] -:= 1
  7348. X                     writePile (suit)
  7349. X                     writeStack (op[2])
  7350. X                  } else {
  7351. X                     # unMove top op[4] cards on stack op[2]
  7352. X                     # to stack op[3]
  7353. X                     dieIf (1 < *stackUp[op[2]])
  7354. X                     push (stackDown[op[2]], pull(stackUp[op[2]]))
  7355. X                     every 1 to ("16r" || op[4])  do
  7356. X                        push (stackUp[op[2]], pull(stackUp[op[3]]))
  7357. X                     writeStack (op[3])
  7358. X                     writeStack (-op[2])
  7359. X                  }
  7360. X               }
  7361. X            }
  7362. X      "T"      :  {
  7363. X               dieIf ((/automaticAce) & (*op ~= 2))
  7364. X               ### op looks like:  Tcxx
  7365. X               ### where c is the number of cards thumbed (usually 3)
  7366. X               ### and x is an optional number 1..4 of an ace pile
  7367. X               ### There can be 0,1,2, or 3 of these x's.
  7368. X               # move cards from Ace piles to deck, starting at end
  7369. X               while 2 < *op  do  {
  7370. X                  suit := op[-1]
  7371. X                  pile[suit] := 0
  7372. X                  writePile (suit)
  7373. X                  push (deckUp, card(suit,1))
  7374. X                  writeDeckUp ()
  7375. X                  click ()
  7376. X                  op[-1] := ""
  7377. X               }
  7378. X               # then undo the Thumb operation itself
  7379. X               dieIf (*deckUp = 0)
  7380. X               every 1 to op[2]  do
  7381. X                  push (deckDown, pop(deckUp))
  7382. X               if *deckUp = 0  then
  7383. X                  while push (deckUp, pop(deckDown))
  7384. X               writeDeckUp ()
  7385. X               writeDeckDown ()
  7386. X            }
  7387. X      default  :  {
  7388. X         if \isUNIX  then  reset_tty()
  7389. X         stop ("Klondike: unknown operation `", op, "' in ops[]")
  7390. X         }
  7391. X      }
  7392. X      click ()
  7393. X   } else {
  7394. X      ## Admittedly this is a bit of a kluge, but better than nothing ?
  7395. X      if *deckDown = 0  then
  7396. X         while push (deckDown, pop(deckUp))
  7397. X      writeDeckUp ()
  7398. X      writeDeckDown ()
  7399. X      writeInfo ("Stack Empty")
  7400. X   }
  7401. X
  7402. Xend                                 #undo
  7403. X
  7404. X
  7405. X#  s h o w L i s t
  7406. X# Display a list of cards at the current cursor position.
  7407. X# Intended for debugging only .
  7408. Xprocedure showList (lst)
  7409. Xlocal c
  7410. X   every c := !lst  do  {
  7411. X      if \isDOS  then
  7412. X     writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit],
  7413. X         Vnormal, " ")
  7414. X      else if \isUNIX  then  {
  7415. X     writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit])
  7416. X     normal ();  writes(" ")
  7417. X      }
  7418. X  }
  7419. Xend                                 #showList
  7420. X
  7421. X
  7422. X#  c a r d 2 s t r
  7423. X# Given a list of card records, returns a string representation.
  7424. X# Even an empty list results in a non-zero string length.
  7425. Xprocedure card2str (lst)
  7426. Xlocal c, s
  7427. X   s := "$"
  7428. X   every c := !lst  do
  7429. X      s ||:= string(c.suit) || "123456789abcd"[c.rank]
  7430. X   return s
  7431. Xend                                 #card2str
  7432. X
  7433. X
  7434. X#  s t r 2 c a r d
  7435. X# Given a string [as generated by card2str()],
  7436. X# return corresponding list of card records.
  7437. X# Fails if the string is invalid.
  7438. Xprocedure str2card (s)
  7439. Xlocal cc, i
  7440. X   if s[i:=1] ~== "$"  then  fail
  7441. X   cc := []
  7442. X   while put (cc, card(s[i+:=1], integer("14r"||s[i+:=1])))
  7443. X   return cc
  7444. Xend                                 #str2card
  7445. X
  7446. X
  7447. X#  s a v e S t a t e
  7448. X# Saves the current state in the named file, which is created/overwritten
  7449. X# as necessary.
  7450. X# Fails if the state was not successfully saved.
  7451. Xprocedure saveState (filename)
  7452. Xlocal f, i
  7453. X   (f := open (filename, "c"))  |  fail
  7454. X   write (f, &dateline)
  7455. X   write (f, if \automaticAce then 1 else 0)
  7456. X   write (f, if \clicking     then 1 else 0)
  7457. X   write (f, firstSeed)
  7458. X   write (f, lastSeed)
  7459. X   write (f, &random)
  7460. X   every write (f, !pile)
  7461. X   every write (f, card2str(!stackUp))
  7462. X   every write (f, card2str(!stackDown))
  7463. X   write (f, card2str(deckUp))
  7464. X   write (f, card2str(deckDown))
  7465. X   write (f, totalGames)
  7466. X   write (f, totalAces)
  7467. X   every write (f, !ops)
  7468. X   return close (f)
  7469. Xend                                 #saveState
  7470. X
  7471. X
  7472. X#  r e s t o r e S t a t e
  7473. X# Restore game from the named file.
  7474. X# Fails if the file isn't there, isn't readable, or isn't correct format.
  7475. X# Otherwise returns date the file was last written.
  7476. X# Note that we do not update the screen here !!
  7477. Xprocedure restoreState (filename)
  7478. Xlocal f, date
  7479. X   if not (f := open (filename, "r"))  then  fail
  7480. X   if (not (date := read(f)))  |  (*date = 0)  then  fail
  7481. X   automaticAce := if read (f) == "0"  then  &null  else  1
  7482. X   clicking     := if read (f) == "0"  then  &null  else  1
  7483. X   firstSeed    := read (f)
  7484. X   lastSeed     := read (f)
  7485. X   &random      := read (f)
  7486. X   every ((!pile) := read(f))
  7487. X   every ((!stackUp)   := str2card (read(f)))
  7488. X   every ((!stackDown) := str2card (read(f)))
  7489. X   deckUp   := str2card (read(f))
  7490. X   deckDown := str2card (read(f))
  7491. X   totalGames  := read (f)
  7492. X   totalAces   := read (f)
  7493. X   ops := []
  7494. X   while push (ops, read (f))
  7495. X   dieIf (not close (f), "can't close")
  7496. X   return date
  7497. Xend                                 #restoreState
  7498. X
  7499. X
  7500. X#  n e w G a m e
  7501. X# Set up all the global variables for a new game.
  7502. X# Returns the seed used to generate this game.
  7503. Xprocedure newGame ()
  7504. Xlocal i, j, s, seed
  7505. X   initScreen ()
  7506. X
  7507. X   #initialize deck, stacks, piles
  7508. X   ops       := []                     #no operations done yet
  7509. X   deckUp    := []                     #deck in hand, face-up
  7510. X   deckDown  := []                     #deck in hand, face-down
  7511. X   stackUp   := list(7, 0)             #columns on table, face up
  7512. X   stackDown := list(7, 0)             #columns on table, face down
  7513. X   pile      := list(4, 0)             #aces - only top rank stored
  7514. X   every  i := 1 to 4  do
  7515. X      every  j := 1 to 13  do
  7516. X         put (deckDown, card(i, j))    #take cards out of the box
  7517. X
  7518. X   seed := &random
  7519. X   if not \invisible  then  {          #Vblink not defined in Batch mode
  7520. X      if \isDOS  then
  7521. X     writeInfo (Vblink || "Shuffling")
  7522. X      else if \isUNIX  then
  7523. X     writeInfo ("Shuffling")
  7524. X   }
  7525. X   every 1 to 100 do
  7526. X      ?deckDown :=: ?deckDown
  7527. X   writeInfo ("")
  7528. X
  7529. X   every !stackUp   := []
  7530. X   every !stackDown := []
  7531. X   every  i := 1 to 7  do  {
  7532. X      push (stackUp[i], get(deckDown))
  7533. X      writeStack (-i)
  7534. X      click ()
  7535. X      every  j := (i+1) to 7  do  {
  7536. X         push (stackDown[j], get(deckDown))
  7537. X         writeStack (-j)
  7538. X         click ()
  7539. X      }
  7540. X###      writeStack (-i)                  ### this replaces 2 calls above
  7541. X   }
  7542. X   writeDeckDown()
  7543. X
  7544. X   #handle any Aces which are showing
  7545. X   every  i := 1 to 7  do
  7546. X      if *(s := check4ace (i)) ~= 0  then
  7547. X         push (ops, "M" || string(i) || "A" || string(integer(s) + 4))
  7548. X   return seed
  7549. Xend                                 #newGame
  7550. SHAR_EOF
  7551. true || echo 'restore of klonsub.icn failed'
  7552. rm -f _shar_wnt_.tmp
  7553. fi
  7554. # ============= itlib.icn ==============
  7555. if test -f 'itlib.icn' -a X"$1" != X"-c"; then
  7556.     echo 'x - skipping itlib.icn (File already exists)'
  7557.     rm -f _shar_wnt_.tmp
  7558. else
  7559. > _shar_wnt_.tmp
  7560. echo 'x - extracting itlib.icn (Text)'
  7561. sed 's/^X//' << 'SHAR_EOF' > 'itlib.icn' &&
  7562. X########################################################################
  7563. SHAR_EOF
  7564. true || echo 'restore of itlib.icn failed'
  7565. fi
  7566. echo 'End of  part 3'
  7567. echo 'File itlib.icn is continued in part 4'
  7568. echo 4 > _shar_seq_.tmp
  7569. exit 0
  7570.  
  7571. From goer%sophist@gargoyle.uchicago.edu  Sat Dec  8 03:53:06 1990
  7572. Resent-From: goer%sophist@gargoyle.uchicago.edu
  7573. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  7574.     id AA02536; Sat, 8 Dec 90 03:53:06 -0700
  7575. Return-Path: goer@sophist.uchicago.edu
  7576. Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:51 MST
  7577. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  7578.  (4.0/1.14) id AA04509; Sat, 8 Dec 90 04:51:37 CST
  7579. Received: by sophist (4.1/UofC3.1X) id AA08433; Sat, 8 Dec 90 04:54:56 CST
  7580. Resent-Date: Sat, 8 Dec 90 03:52 MST
  7581. Date: Sat, 8 Dec 90 04:54:56 CST
  7582. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  7583. Subject: klondike, part 04 of 05
  7584. Resent-To: icon-group@cs.arizona.edu
  7585. To: icon-group@arizona.edu
  7586. Resent-Message-Id: <F2376F204103403C03@Arizona.edu>
  7587. Message-Id: <9012081054.AA08433@sophist>
  7588. X-Envelope-To: icon-group@CS.Arizona.EDU
  7589. X-Vms-To: icon-group@Arizona.edu
  7590.  
  7591. ---- Cut Here and feed the following to sh ----
  7592. #!/bin/sh
  7593. # this is klondike.04 (part 4 of a multipart archive)
  7594. # do not concatenate these parts, unpack them in order with /bin/sh
  7595. # file itlib.icn continued
  7596. #
  7597. if test ! -r _shar_seq_.tmp; then
  7598.     echo 'Please unpack part 1 first!'
  7599.     exit 1
  7600. fi
  7601. (read Scheck
  7602.  if test "$Scheck" != 4; then
  7603.     echo Please unpack part "$Scheck" next!
  7604.     exit 1
  7605.  else
  7606.     exit 0
  7607.  fi
  7608. ) < _shar_seq_.tmp || exit 1
  7609. if test ! -f _shar_wnt_.tmp; then
  7610.     echo 'x - still skipping itlib.icn'
  7611. else
  7612. echo 'x - continuing file itlib.icn'
  7613. sed 's/^X//' << 'SHAR_EOF' >> 'itlib.icn' &&
  7614. X#    
  7615. X#    Name:    itlib.icn
  7616. X#    
  7617. X#    Title:    Icon termlib-type tools
  7618. X#    
  7619. X#    Author:    Richard L. Goerwitz
  7620. X#
  7621. X#    Version: 1.23
  7622. X#
  7623. X#########################################################################
  7624. X#
  7625. X#  I place this and future versions of itlib in the public domain - RLG
  7626. X#
  7627. X#########################################################################
  7628. X#
  7629. X#  The following library represents a series of rough functional
  7630. X#  equivalents to the standard Unix low-level termcap routines.  They
  7631. X#  are not meant as exact termlib clones.  Nor are they enhanced to
  7632. X#  take care of magic cookie terminals, terminals that use \D in their
  7633. X#  termcap entries, or, in short, anything I felt would not affect my
  7634. X#  normal, day-to-day work with ANSI and vt100 terminals.
  7635. X#
  7636. X#  Requires:  A unix platform & co-expressions.  There is an MS-DOS
  7637. X#  version, itlibdos.icn.
  7638. X#
  7639. X#  setname(term)
  7640. X#    Use only if you wish to initialize itermlib for a terminal
  7641. X#  other than what your current environment specifies.  "Term" is the
  7642. X#  name of the termcap entry to use.  Normally this initialization is
  7643. X#  done automatically, and need not concern the user.
  7644. X#
  7645. X#  getval(id)
  7646. X#    Works something like tgetnum, tgetflag, and tgetstr.  In the
  7647. X#  spirit of Icon, all three have been collapsed into one routine.
  7648. X#  Integer valued caps are returned as integers, strings as strings,
  7649. X#  and flags as records (if a flag is set, then type(flag) will return
  7650. X#  "true").  Absence of a given capability is signalled by procedure
  7651. X#  failure.
  7652. X#
  7653. X#  igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
  7654. X#    Analogous to tgoto.  "Cm" is the cursor movement command for
  7655. X#  the current terminal, as obtained via getval("cm").  Igoto()
  7656. X#  returns a string which, when output via iputs, will cause the
  7657. X#  cursor to move to column "destcol" and line "destline."  Column and
  7658. X#  line are always calculated using a *one* offset.  This is far more
  7659. X#  Iconish than the normal zero offset used by tgoto.  If you want to
  7660. X#  go to the first square on your screen, then include in your program
  7661. X#  "iputs(igoto(getval("cm"),1,1))."
  7662. X#
  7663. X#  iputs(cp,affcnt)
  7664. X#    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  7665. X#  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  7666. X#  count of affected lines.  It is only relevant for terminals which
  7667. X#  specify proportional (starred) delays in their termcap entries.
  7668. X#
  7669. X#  Bugs:  I have not tested these routines on terminals that require
  7670. X#  padding.  These routines WILL NOT WORK if your machines stty com-
  7671. X#  mand has no -g option (tisk, tisk).  This includes NeXT worksta-
  7672. X#  tions, and some others that I haven't had time to pinpoint.
  7673. X#
  7674. X##########################################################################
  7675. X#
  7676. X#  Requires: UNIX, co-expressions
  7677. X#
  7678. X#  See also: iscreen.icn (a set of companion utilities)
  7679. X#
  7680. X##########################################################################
  7681. X
  7682. X
  7683. Xglobal tc_table, tty_speed
  7684. Xrecord true()
  7685. X
  7686. X
  7687. Xprocedure check_features()
  7688. X
  7689. X    local in_params, line
  7690. X    # global tty_speed
  7691. X
  7692. X    initial {
  7693. X    find("unix",map(&features)) |
  7694. X        er("check_features","unix system required",1)
  7695. X    find("o-expres",&features) |
  7696. X        er("check_features","co-expressions not implemented - &$#!",1)
  7697. X    system("/bin/stty tabs") |
  7698. X        er("check_features","can't set tabs option",1)
  7699. X    }
  7700. X
  7701. X    # clumsy, clumsy, clumsy, and probably won't work on all systems
  7702. X    tty_speed := getspeed()
  7703. X    return "term characteristics reset; features check out"
  7704. X
  7705. Xend
  7706. X
  7707. X
  7708. X
  7709. Xprocedure setname(name)
  7710. X
  7711. X    # Sets current terminal type to "name" and builds a new termcap
  7712. X    # capability database (residing in tc_table).  Fails if unable to
  7713. X    # find a termcap entry for terminal type "name."  If you want it
  7714. X    # to terminate with an error message under these circumstances,
  7715. X    # comment out "| fail" below, and uncomment the er() line.
  7716. X
  7717. X    #tc_table is global
  7718. X    
  7719. X    check_features()
  7720. X
  7721. X    tc_table := table()
  7722. X    tc_table := maketc_table(getentry(name)) | fail
  7723. X    # er("setname","no termcap entry found for "||name,3)
  7724. X    return "successfully reset for terminal " || name
  7725. X
  7726. Xend
  7727. X
  7728. X
  7729. X
  7730. Xprocedure getname()
  7731. X
  7732. X    # Getname() first checks to be sure we're running under Unix, and,
  7733. X    # if so, tries to figure out what the current terminal type is,
  7734. X    # checking successively the value of the environment variable
  7735. X    # TERM, and then the output of "tset -".  Terminates with an error
  7736. X    # message if the terminal type cannot be ascertained.
  7737. X
  7738. X    local term, tset_output
  7739. X
  7740. X    check_features()
  7741. X
  7742. X    if not (term := getenv("TERM")) then {
  7743. X    tset_output := open("/bin/tset -","pr") |
  7744. X        er("getname","can't find tset command",1)
  7745. X    term := !tset_output
  7746. X    close(tset_output)
  7747. X    }
  7748. X    return \term |
  7749. X    er("getname","can't seem to determine your terminal type",1)
  7750. X
  7751. Xend
  7752. X
  7753. X
  7754. X
  7755. Xprocedure er(func,msg,errnum)
  7756. X
  7757. X    # short error processing utility
  7758. X    write(&errout,func,":  ",msg)
  7759. X    exit(errnum)
  7760. X
  7761. Xend
  7762. X
  7763. X
  7764. X
  7765. Xprocedure getentry(name, termcap_string)
  7766. X
  7767. X    # "Name" designates the current terminal type.  Getentry() scans
  7768. X    # the current environment for the variable TERMCAP.  If the
  7769. X    # TERMCAP string represents a termcap entry for a terminal of type
  7770. X    # "name," then getentry() returns the TERMCAP string.  Otherwise,
  7771. X    # getentry() will check to see if TERMCAP is a file name.  If so,
  7772. X    # getentry() will scan that file for an entry corresponding to
  7773. X    # "name."  If the TERMCAP string does not designate a filename,
  7774. X    # getentry() will scan /etc/termcap for the correct entry.
  7775. X    # Whatever the input file, if an entry for terminal "name" is
  7776. X    # found, getentry() returns that entry.  Otherwise, getentry()
  7777. X    # fails.
  7778. X
  7779. X    local f, getline, line, nm, ent1, ent2
  7780. X
  7781. X    # You can force getentry() to use a specific termcap file by cal-
  7782. X    # ling it with a second argument - the name of the termcap file
  7783. X    # to use instead of the regular one, or the one specified in the
  7784. X    # termcap environment variable.
  7785. X    /termcap_string := getenv("TERMCAP")
  7786. X
  7787. X    if \termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name)
  7788. X    then return termcap_string
  7789. X    else {
  7790. X
  7791. X    # The logic here probably isn't clear.  The idea is to try to use
  7792. X    # the termcap environment variable successively as 1) a termcap en-
  7793. X    # try and then 2) as a termcap file.  If neither works, 3) go to
  7794. X    # the /etc/termcap file.  The else clause here does 2 and, if ne-
  7795. X    # cessary, 3.  The "\termcap_string ? (not match..." expression
  7796. X    # handles 1.
  7797. X
  7798. X    if find("/",\termcap_string)
  7799. X    then f := open(termcap_string)
  7800. X    /f := open("/etc/termcap") |
  7801. X        er("getentry","I can't access your /etc/termcap file",1)
  7802. X
  7803. X    getline := create read_file(f)
  7804. X    
  7805. X    while line := @getline do {
  7806. X        if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
  7807. X        entry := ""
  7808. X        while (\line | @getline) ? {
  7809. X            if entry ||:= 1(tab(find(":")+1), pos(0))
  7810. X            then {
  7811. X            close(f)
  7812. X            # if entry ends in tc= then add in the named tc entry
  7813. X            entry ?:= tab(find("tc=")) ||
  7814. X                # recursively fetch the new termcap entry
  7815. X                (move(3), getentry(tab(find(":"))) ?
  7816. X                    # remove the name field from the new entry
  7817. X                     (tab(find(":")+1), tab(0)))
  7818. X            return entry
  7819. X            }
  7820. X            else {
  7821. X            \line := &null # must precede the next line
  7822. X            entry ||:= trim(trim(tab(0),'\\'),':')
  7823. X            }
  7824. X        }
  7825. X        }
  7826. X    }
  7827. X    }
  7828. X
  7829. X    close(f)
  7830. X    er("getentry","can't find and/or process your termcap entry",3)
  7831. Xend
  7832. X
  7833. X
  7834. X
  7835. Xprocedure read_file(f)
  7836. X
  7837. X    # Suspends all non #-initial lines in the file f.
  7838. X    # Removes leading tabs and spaces from lines before suspending
  7839. X    # them.
  7840. X
  7841. X    local line
  7842. X
  7843. X    \f | er("read_tcap_file","no valid termcap file found",3)
  7844. X    while line := read(f) do {
  7845. X    match("#",line) & next
  7846. X    line ?:= (tab(many('\t ')) | &null, tab(0))
  7847. X    suspend line
  7848. X    }
  7849. X
  7850. X    fail
  7851. X
  7852. Xend
  7853. X
  7854. X
  7855. X
  7856. Xprocedure maketc_table(entry)
  7857. X
  7858. X    # Maketc_table(s) (where s is a valid termcap entry for some
  7859. X    # terminal-type): Returns a table in which the keys are termcap
  7860. X    # capability designators, and the values are the entries in
  7861. X    # "entry" for those designators.
  7862. X
  7863. X    local k, v
  7864. X
  7865. X    /entry & er("maketc_table","no entry given",8)
  7866. X    if entry[-1] ~== ":" then entry ||:= ":"
  7867. X    
  7868. X    /tc_table := table()
  7869. X
  7870. X    entry ? {
  7871. X
  7872. X    tab(find(":")+1)    # tab past initial (name) field
  7873. X
  7874. X    while tab((find(":")+1) \ 1) ? {
  7875. X        &subject == "" & next
  7876. X        if k := 1(move(2), ="=")
  7877. X        then tc_table[k] := Decode(tab(find(":")))
  7878. X        else if k := 1(move(2), ="#")
  7879. X        then tc_table[k] := integer(tab(find(":")))
  7880. X        else if k := 1(tab(find(":")), pos(-1))
  7881. X        then tc_table[k] := true()
  7882. X        else er("maketc_table", "your termcap file has a bad entry",3)
  7883. X    }
  7884. X    }
  7885. X
  7886. X    return tc_table
  7887. X
  7888. Xend
  7889. X
  7890. X
  7891. X
  7892. Xprocedure getval(id)
  7893. X
  7894. X    /tc_table := maketc_table(getentry(getname())) |
  7895. X    er("getval","can't make a table for your terminal",4)
  7896. X
  7897. X    return \tc_table[id] | fail
  7898. X    # er("getval","the current terminal doesn't support "||id,7)
  7899. X
  7900. Xend
  7901. X
  7902. X
  7903. X
  7904. Xprocedure Decode(s)
  7905. X
  7906. X    # Does things like turn ^ plus a letter into a genuine control
  7907. X    # character.
  7908. X
  7909. X    new_s := ""
  7910. X
  7911. X    s ? {
  7912. X
  7913. X    while new_s ||:= tab(upto('\\^')) do {
  7914. X        chr := move(1)
  7915. X        if chr == "\\" then {
  7916. X        new_s ||:= {
  7917. X            case chr2 := move(1) of {
  7918. X            "\\" : "\\"
  7919. X            "^"  : "^"
  7920. X            "E"  : "\e"
  7921. X            "b"  : "\b"
  7922. X            "f"  : "\f"
  7923. X            "n"  : "\n"
  7924. X            "r"  : "\r"
  7925. X            "t"  : "\t"
  7926. X            default : {
  7927. X                if any(&digits,chr2) then {
  7928. X                char(integer("8r"||chr2||move(2 to 0 by -1))) |
  7929. X                    er("Decode","bad termcap entry",3)
  7930. X                }
  7931. X               else chr2
  7932. X            }
  7933. X            }
  7934. X        }
  7935. X        }
  7936. X        else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  7937. X    }
  7938. X    new_s ||:= tab(0)
  7939. X    }
  7940. X
  7941. X    return new_s
  7942. X
  7943. Xend
  7944. X
  7945. X
  7946. X
  7947. Xprocedure igoto(cm,col,line)
  7948. X
  7949. X    local colline, range, increment, str, outstr, chr, x, y
  7950. X
  7951. X    if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  7952. X    colline := string(\col) || "," || string(\line) | string(\col|line)
  7953. X    range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  7954. X    er("igoto",colline || " out of range " || (\range|""),9)
  7955. X    } 
  7956. X
  7957. X    # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
  7958. X    increment := -1
  7959. X    outstr := ""
  7960. X    
  7961. X    cm ? {
  7962. X    while outstr ||:= tab(find("%")) do {
  7963. X        tab(match("%"))
  7964. X        chr := move(1)
  7965. X        if case chr of {
  7966. X        "." :  outstr ||:= char(line + increment)
  7967. X        "+" :  outstr ||:= char(line + ord(move(1)) + increment)
  7968. X        "d" :  {
  7969. X            str := string(line + increment)
  7970. X            outstr ||:= right(str, integer(tab(any('23'))), "0") | str
  7971. X        }
  7972. X        }
  7973. X        then line :=: col
  7974. X        else {
  7975. X        case chr of {
  7976. X            "n" :  line := ixor(line,96) & col := ixor(col,96)
  7977. X            "i" :  increment := 0
  7978. X            "r" :  line :=: col
  7979. X            "%" :  outstr ||:= "%"
  7980. X            "B" :  line := ior(ishift(line / 10, 4), line % 10)
  7981. X            ">" :  {
  7982. X            x := move(1); y := move(1)
  7983. X            line > ord(x) & line +:= ord(y)
  7984. X            &null
  7985. X            }
  7986. X        } | er("goto","bad termcap entry",5)
  7987. X        }
  7988. X    }
  7989. X    return outstr || tab(0)
  7990. X    }
  7991. X
  7992. Xend
  7993. X
  7994. X
  7995. X
  7996. Xprocedure iputs(cp, affcnt)
  7997. X
  7998. X    local baud_rates, char_rates, i, delay, PC
  7999. X    static num_chars, char_times
  8000. X    # global tty_speed
  8001. X
  8002. X    initial {
  8003. X    num_chars := &digits ++ '.'
  8004. X    char_times := table()
  8005. X    # Baud rates in decimal, not octal (as in termio.h)
  8006. X    baud_rates := [0,7,8,9,10,11,12,13,14,15]
  8007. X    char_rates := [0,333,166,83,55,41,20,10,10,10]
  8008. X    every i := 1 to *baud_rates do {
  8009. X        char_times[baud_rates[i]] := char_rates[i]
  8010. X    }
  8011. X    }
  8012. X
  8013. X    type(cp) == "string" |
  8014. X    er("iputs","you can't iputs() a non-string value!",10)
  8015. X
  8016. X    cp ? {
  8017. X    delay := tab(many(num_chars))
  8018. X    if ="*" then {
  8019. X        delay *:= \affcnt |
  8020. X        er("iputs","affected line count missing",6)
  8021. X    }
  8022. X    writes(tab(0))
  8023. X    }
  8024. X
  8025. X    if (\delay, tty_speed ~= 0) then {
  8026. X    PC := tc_table["pc"] | "\000"
  8027. X    char_time := char_times[tty_speed] | (return "speed error")
  8028. X    delay := (delay * char_time) + (char_time / 2)
  8029. X    every 1 to delay by 10
  8030. X    do writes(PC)
  8031. X    }
  8032. X
  8033. X    return
  8034. X
  8035. Xend
  8036. X
  8037. X
  8038. X
  8039. Xprocedure getspeed()
  8040. X
  8041. X    local stty_g, stty_output, c_cflag, o_speed
  8042. X
  8043. X    stty_g := open("/bin/stty -g 2>&1","pr") |
  8044. X    er("getspeed","Can't access your stty command.",4)
  8045. X    stty_output := !stty_g
  8046. X    close(stty_g)
  8047. X
  8048. X    \stty_output ? {
  8049. X    # tab to the third field of the output of the stty -g cmd
  8050. X        tab(find(":")+1) & tab(find(":")+1) &
  8051. X    c_cflag := integer("16r"||tab(find(":")))
  8052. X    } | er("getspeed","Unable to unwind your stty -g output.",4)
  8053. X
  8054. X    o_speed := iand(15,c_cflag)
  8055. X    return o_speed
  8056. X
  8057. Xend
  8058. SHAR_EOF
  8059. echo 'File itlib.icn is complete' &&
  8060. true || echo 'restore of itlib.icn failed'
  8061. rm -f _shar_wnt_.tmp
  8062. fi
  8063. # ============= getchlib.icn ==============
  8064. if test -f 'getchlib.icn' -a X"$1" != X"-c"; then
  8065.     echo 'x - skipping getchlib.icn (File already exists)'
  8066.     rm -f _shar_wnt_.tmp
  8067. else
  8068. > _shar_wnt_.tmp
  8069. echo 'x - extracting getchlib.icn (Text)'
  8070. sed 's/^X//' << 'SHAR_EOF' > 'getchlib.icn' &&
  8071. X############################################################################
  8072. X#
  8073. X#    Name:     getchlib.icn
  8074. X#
  8075. X#    Title:     Implementation of getch() for Unix (and more)
  8076. X#
  8077. X#    Author:     Richard L. Goerwitz
  8078. X#
  8079. X#    Version: 1.11
  8080. X#
  8081. X############################################################################
  8082. X#
  8083. X#  I place this and future versions of getchlib in the public domain - RLG
  8084. X#
  8085. X############################################################################
  8086. X#
  8087. X#  Implementing getch() is a much, much more complex affair under Unix
  8088. X#  than it is under, say, MS-DOS.  This library represents one,
  8089. X#  solution to the problem - one which can be run as a library, and
  8090. X#  need not be compiled into the run-time system.
  8091. X#
  8092. X#  Four basic utilities are included here:
  8093. X#
  8094. X#    getch()        - waits until a keystroke is available &
  8095. X#        returns it without displaying it on the screen
  8096. X#    getche()    - same as getch() only with echo
  8097. X#    getse(s)    - like getche() only for strings.  The optional
  8098. X#        argument s gives getse() something to start with.  Use this
  8099. X#           if, say, you want to read single characters in cbreak mode,
  8100. X#           but get more input if the character read is the first part
  8101. X#           of a longer command.  If the user backspaces over everything
  8102. X#           that has been input, getse() fails.  Returns on \r or \n.
  8103. X#    reset_tty()    - absolutely vital routine for putting the cur-
  8104. X#           rent tty line back into cooked mode; call it before exiting
  8105. X#           or you will find yourself with a locked-up terminal; use it
  8106. X#           also if you must temporarily restore the terminal to cooked
  8107. X#           mode
  8108. X#
  8109. X#  Note that getse() *must* be used in place of read(&input) if you
  8110. X#  are planning on using getch() or getche(), since read(&input)
  8111. X#  assumes a tty with "sane" settings.
  8112. X#
  8113. X#  Warning:  The routines below do not do any sophisticated output
  8114. X#  processing.  As noted above, they also put your tty line in raw
  8115. X#  mode.  I know, I know:  "Raw is overkill - use cbreak."  But in
  8116. X#  a world that includes SysV, one must pick a lowest common denomi-
  8117. X#  nator.  And no, icanon != cbreak.
  8118. X#
  8119. X#  Bugs:  These routines will not work on systems that do not imple-
  8120. X#  ment the -g option for the stty command.  The NeXT workstation is
  8121. X#  an example of such a system.  Tisk, tisk.
  8122. X#
  8123. X############################################################################
  8124. X#
  8125. X#  Example program:
  8126. X#
  8127. X#      The following program is a simple file viewer.  To run, it
  8128. X#  needs to be linked with itlib.icn, iscreen.icn, and this file
  8129. X#  (getchlib.icn).
  8130. X#
  8131. X#  procedure main(a)
  8132. X#
  8133. X#      # Simple pager/file searcher for Unix systems.  Must be linked
  8134. X#      # with itlib.icn and iscreen.icn.
  8135. X#  
  8136. X#      local intext, c, s
  8137. X#  
  8138. X#      # Open input file
  8139. X#      intext := open(a[1],"r") | {
  8140. X#      write(&errout,"Can't open input file.")
  8141. X#      exit(1)
  8142. X#      }
  8143. X#  
  8144. X#      # Initialize screen
  8145. X#      clear()
  8146. X#      print_screen(intext) | exit(0)
  8147. X#  
  8148. X#      # Prompt & read input
  8149. X#      repeat {
  8150. X#      iputs(igoto(getval("cm"), 1, getval("li")))
  8151. X#      emphasize()
  8152. X#      writes("More? (y/n or /search):")
  8153. X#      write_ce(" ")
  8154. X#      case c := getche() of {
  8155. X#          "y" : print_screen(intext) | break
  8156. X#          " " : print_screen(intext) | break
  8157. X#          "n" : break
  8158. X#          "q" : break
  8159. X#          "/" : {
  8160. X#          iputs(igoto(getval("cm"), 1, getval("li")))
  8161. X#          emphasize()
  8162. X#          writes("Enter search string:")
  8163. X#          write_ce(" ")
  8164. X#          pattern := GetMoreInput()
  8165. X#          /pattern | "" == pattern & next
  8166. X#          # For more complex patterns, use findre() (IPL findre.icn)
  8167. X#          if not find(pattern, s := !intext) then {
  8168. X#              iputs(igoto(getval("cm"), 1, getval("li")))
  8169. X#              emphasize()
  8170. X#              write_ce("String not found.")
  8171. X#              break
  8172. X#          }
  8173. X#          else print_screen(intext, s) | break
  8174. X#          }
  8175. X#      }
  8176. X#      }
  8177. X#  
  8178. X#      reset_tty()
  8179. X#      write()
  8180. X#      exit(0)
  8181. X#
  8182. X#  end
  8183. X#  
  8184. X#  procedure GetMoreInput(c)
  8185. X#  
  8186. X#      local input_string
  8187. X#      static BS
  8188. X#      initial BS := getval("bc") | "\b"
  8189. X#  
  8190. X#      /c := ""
  8191. X#      if any('\n\r', chr := getch())
  8192. X#      then return c
  8193. X#      else {
  8194. X#      chr == BS & fail
  8195. X#      writes(chr)
  8196. X#      input_string := getse(c || chr) | fail
  8197. X#      if any('\n\r', input_string)
  8198. X#      then fail else (return input_string)
  8199. X#      }
  8200. X#  
  8201. X#  end
  8202. X#  
  8203. X#  procedure print_screen(f,s)
  8204. X#  
  8205. X#      if /s then
  8206. X#      begin := 1
  8207. X#      # Print top line, if one is supplied
  8208. X#      else {
  8209. X#      iputs(igoto(getval("cm"), 1, 1))
  8210. X#      write_ce(s ? tab(getval("co") | 0))
  8211. X#      begin := 2
  8212. X#      }
  8213. X#  
  8214. X#      # Fill the screen with lines from f; clear and fail on EOF.
  8215. X#      every i := begin to getval("li") - 1 do {
  8216. X#      iputs(igoto(getval("cm"), 1, i))
  8217. X#      if not write_ce(read(f) ? tab(getval("co") | 0)) then {
  8218. X#          # Clear remaining lines on the screen.
  8219. X#          every j := i to getval("li") do {
  8220. X#          iputs(igoto(getval("cm"), 1, j))
  8221. X#          iputs(getval("ce"))
  8222. X#          }
  8223. X#          iputs(igoto(getval("cm"), 1, i))
  8224. X#          fail
  8225. X#      }
  8226. X#      }
  8227. X#      return
  8228. X#  
  8229. X#  end
  8230. X#  
  8231. X#  procedure write_ce(s)
  8232. X#  
  8233. X#      normal()
  8234. X#      iputs(getval("ce")) |
  8235. X#      writes(repl(" ",getval("co") - *s))
  8236. X#      writes(s)
  8237. X#      return
  8238. X#
  8239. X#  end
  8240. X#
  8241. X############################################################################
  8242. X#
  8243. X#  Requires: UNIX
  8244. X#
  8245. X#  Links: itlib.icn
  8246. X#
  8247. X############################################################################
  8248. X
  8249. X
  8250. Xglobal c_cc, current_mode        # what mode are we in, raw or cooked?
  8251. Xrecord termio_struct(vintr,vquit,verase,vkill)
  8252. X
  8253. Xprocedure getse(s)
  8254. X
  8255. X    # getse() - like getche, only for strings instead of single chars
  8256. X    #
  8257. X    # This procedure *must* be used instead of read(&input) if getch
  8258. X    # and/or getche are to be used, since these put the current tty
  8259. X    # line in raw mode.
  8260. X    #
  8261. X    # Note that the buffer can be initialized by calling getse with a
  8262. X    # string argument.  Note also that, as getse now stands, it will
  8263. X    # fail if the user backspaces over everything that has been input.
  8264. X    # This change does not coincide with its behavior in previous ver-
  8265. X    # sions.  It can be changed by commenting out the line "if *s < 1
  8266. SHAR_EOF
  8267. true || echo 'restore of getchlib.icn failed'
  8268. fi
  8269. echo 'End of  part 4'
  8270. echo 'File getchlib.icn is continued in part 5'
  8271. echo 5 > _shar_seq_.tmp
  8272. exit 0
  8273.  
  8274. From goer%sophist@gargoyle.uchicago.edu  Sat Dec  8 03:53:23 1990
  8275. Resent-From: goer%sophist@gargoyle.uchicago.edu
  8276. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8277.     id AA02554; Sat, 8 Dec 90 03:53:23 -0700
  8278. Return-Path: goer@sophist.uchicago.edu
  8279. Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:52 MST
  8280. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  8281.  (4.0/1.14) id AA04514; Sat, 8 Dec 90 04:52:01 CST
  8282. Received: by sophist (4.1/UofC3.1X) id AA08441; Sat, 8 Dec 90 04:55:20 CST
  8283. Resent-Date: Sat, 8 Dec 90 03:52 MST
  8284. Date: Sat, 8 Dec 90 04:55:20 CST
  8285. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  8286. Subject: klondike, part 05 of 05
  8287. Resent-To: icon-group@cs.arizona.edu
  8288. To: icon-group@arizona.edu
  8289. Resent-Message-Id: <F23763851003403005@Arizona.edu>
  8290. Message-Id: <9012081055.AA08441@sophist>
  8291. X-Envelope-To: icon-group@CS.Arizona.EDU
  8292. X-Vms-To: icon-group@Arizona.edu
  8293.  
  8294. ---- Cut Here and feed the following to sh ----
  8295. #!/bin/sh
  8296. # this is klondike.05 (part 5 of a multipart archive)
  8297. # do not concatenate these parts, unpack them in order with /bin/sh
  8298. # file getchlib.icn continued
  8299. #
  8300. if test ! -r _shar_seq_.tmp; then
  8301.     echo 'Please unpack part 1 first!'
  8302.     exit 1
  8303. fi
  8304. (read Scheck
  8305.  if test "$Scheck" != 5; then
  8306.     echo Please unpack part "$Scheck" next!
  8307.     exit 1
  8308.  else
  8309.     exit 0
  8310.  fi
  8311. ) < _shar_seq_.tmp || exit 1
  8312. if test ! -f _shar_wnt_.tmp; then
  8313.     echo 'x - still skipping getchlib.icn'
  8314. else
  8315. echo 'x - continuing file getchlib.icn'
  8316. sed 's/^X//' << 'SHAR_EOF' >> 'getchlib.icn' &&
  8317. X    # then fail" below, and uncommenting the line "if *s < 1 then
  8318. X    # next."
  8319. X
  8320. X    local chr
  8321. X    static BS
  8322. X    initial {
  8323. X    BS := getval("bc") | "\b"
  8324. X    if not getval("bs") then {
  8325. X        reset_tty()
  8326. X        stop("Your terminal can't backspace!")
  8327. X    }
  8328. X    }
  8329. X
  8330. X    /s := ""
  8331. X    repeat {
  8332. X    case chr := getch() | fail of {
  8333. X        "\r"|"\n"    : return s
  8334. X        c_cc.vkill   : {
  8335. X        if *s < 1 then next
  8336. X        every 1 to *s do writes(BS)
  8337. X        s := ""
  8338. X        }
  8339. X        c_cc.verase   : {
  8340. X        # if *s < 1 then next
  8341. X        writes(BS) & s := s[1:-1]
  8342. X        if *s < 1 then fail
  8343. X        }
  8344. X        default: writes(chr) & s ||:= chr
  8345. X    }
  8346. X    }
  8347. X
  8348. Xend
  8349. X
  8350. X
  8351. X
  8352. Xprocedure setup_tty()
  8353. X    change_tty_mode("setup")
  8354. X    return
  8355. Xend
  8356. X
  8357. X
  8358. X
  8359. Xprocedure reset_tty()
  8360. X
  8361. X    # Reset (global) mode switch to &null to show we're in cooked mode.
  8362. X    current_mode := &null
  8363. X    change_tty_mode("reset")
  8364. X    return
  8365. X
  8366. Xend
  8367. X
  8368. X
  8369. X
  8370. Xprocedure getch()
  8371. X
  8372. X    local chr
  8373. X
  8374. X    # If the global variable current_mode is null, then we have to
  8375. X    # reset the terminal to raw mode.
  8376. X    if /current_mode := 1 then
  8377. X    setup_tty()
  8378. X
  8379. X    chr := reads(&input)
  8380. X    case chr of {
  8381. X    c_cc.vintr : reset_tty() & stop()  # shouldn't hard code this in
  8382. X    c_cc.vquit  : reset_tty() & stop()
  8383. X    default : return chr
  8384. X    }
  8385. X
  8386. Xend
  8387. X
  8388. X
  8389. X
  8390. Xprocedure getche()
  8391. X
  8392. X    local chr
  8393. X
  8394. X    # If the global variable current_mode is null, then we have to
  8395. X    # reset the terminal to raw mode.
  8396. X    if /current_mode := 1 then
  8397. X    setup_tty()
  8398. X
  8399. X    chr := reads(&input)
  8400. X    case chr of {
  8401. X    c_cc.vintr  : reset_tty() & stop()
  8402. X    c_cc.vquit  : reset_tty() & stop()
  8403. X    default : writes(chr) & return chr
  8404. X    }
  8405. X
  8406. Xend
  8407. X
  8408. X
  8409. X
  8410. Xprocedure change_tty_mode(switch)
  8411. X
  8412. X    # global c_cc   (global record containing values for kill, etc. chars)
  8413. X    local get_term_params, i
  8414. X    static reset_string
  8415. X    initial {
  8416. X    getval("li")    # check to be sure itlib is set up
  8417. X    find("unix",map(&features)) |
  8418. X        stop("change_tty_mode:  These routines must run under Unix.")
  8419. X    get_term_params := open("/bin/stty -g 2>&1","pr")
  8420. X    reset_string := !get_term_params
  8421. X    close(get_term_params)
  8422. X    reset_string ? {
  8423. X        # tab upto the fifth field of the output of the stty -g cmd
  8424. X        # fields of stty -g seem to be the same as those of the
  8425. X        # termio struct, except that the c_line field is missing
  8426. X        every 1 to 4 do tab(find(":")+1)
  8427. X        c_cc := termio_struct("\x03","\x1C","\x08","\x15")
  8428. X        every i := 1 to 3 do {
  8429. X        c_cc[i] := char(integer("16r"||tab(find(":"))))
  8430. X        move(1)
  8431. X        }
  8432. X        c_cc[i+1] := char(integer("16r"||tab(0)))
  8433. X    }
  8434. X    }
  8435. X
  8436. X    if switch == "setup"
  8437. X    then system("/bin/stty -echo raw")
  8438. X    else system("/bin/stty "||reset_string)
  8439. X
  8440. X    return
  8441. X
  8442. Xend
  8443. SHAR_EOF
  8444. echo 'File getchlib.icn is complete' &&
  8445. true || echo 'restore of getchlib.icn failed'
  8446. rm -f _shar_wnt_.tmp
  8447. fi
  8448. # ============= iscreen.icn ==============
  8449. if test -f 'iscreen.icn' -a X"$1" != X"-c"; then
  8450.     echo 'x - skipping iscreen.icn (File already exists)'
  8451.     rm -f _shar_wnt_.tmp
  8452. else
  8453. > _shar_wnt_.tmp
  8454. echo 'x - extracting iscreen.icn (Text)'
  8455. sed 's/^X//' << 'SHAR_EOF' > 'iscreen.icn' &&
  8456. X############################################################################
  8457. X#
  8458. X#    Name:     iscreen.icn
  8459. X#
  8460. X#    Title:     Icon screen functions
  8461. X#
  8462. X#    Author:     Richard L. Goerwitz
  8463. X#
  8464. X#    Version: 1.12
  8465. X#
  8466. X############################################################################
  8467. X#
  8468. X#  This and future version of iscreen are placed in the public domain - RLG
  8469. X#
  8470. X############################################################################
  8471. X#  
  8472. X#      This file contains some rudimentary screen functions for use with
  8473. X#  itlib.icn (termlib-like routines for Icon).
  8474. X#
  8475. X#      clear()              - clears the screen (tries several methods)
  8476. X#      emphasize()          - initiates emphasized mode
  8477. X#      normal(mode)         - resets to normal mode; if mode is null,
  8478. X#        or "b," normal() assumes you were in emphasize mode,
  8479. X#        otherwise you are assumed to have been in underline mode
  8480. X#      message(s)           - displays message s on 2nd-to-last line
  8481. X#      underline()          - initiates underline mode
  8482. X#      status_line(s,s2,p)  - draws status line s on the 3rd-to-last
  8483. X#        screen line; if s is too short for the terminal, s2 is used;
  8484. X#        if p is nonnull then it either centers, left-, or right-justi-
  8485. X#        fies, depending on the value, "c," "l," or "r."
  8486. X#
  8487. X############################################################################
  8488. X#
  8489. X#  Requires: UNIX
  8490. X#
  8491. X#  Links: itlib.icn (or your OS-specific port of itlib)
  8492. X#
  8493. X#  See also: boldface.icn
  8494. X#
  8495. X############################################################################
  8496. X
  8497. X
  8498. Xprocedure clear()
  8499. X
  8500. X    # Clears the screen.  Tries several methods.
  8501. X
  8502. X    if not iputs(getval("cl"))
  8503. X    then iputs(igoto(getval("cm"),1,1))
  8504. X    if not iputs(getval("cd"))
  8505. X    then {
  8506. X    every i := 1 to getval("li") do {
  8507. X        iputs(igoto(getval("cm"),1,i))
  8508. X        iputs(getval("ce"))
  8509. X    }
  8510. X    iputs(igoto(getval("cm"),1,1))
  8511. X    }
  8512. X    return
  8513. X
  8514. Xend
  8515. X
  8516. X
  8517. X
  8518. Xprocedure emphasize()
  8519. X    
  8520. X    static bold_str, cookie_str
  8521. X    initial {
  8522. X    if bold_str := getval("so")
  8523. X    then cookie_str := repl(getval("bc") | "\b", getval("sg"))
  8524. X    else {
  8525. X        if bold_str := getval("us")
  8526. X        then cookie_str := repl(getval("bc") | "\b", getval("ug"))
  8527. X    }
  8528. X    }        
  8529. X    
  8530. X    iputs(\bold_str)
  8531. X    iputs(\cookie_str)
  8532. X    return
  8533. X
  8534. Xend
  8535. X
  8536. X
  8537. X
  8538. Xprocedure underline()
  8539. X    
  8540. X    static underline_str, cookie_str
  8541. X    initial {
  8542. X    if underline_str := getval("us")
  8543. X    then cookie_str := repl(getval("bc") | "\b", getval("sg"))
  8544. X    }        
  8545. X    
  8546. X    iputs(\underline_str)
  8547. X    iputs(\cookie_str)
  8548. X    return
  8549. X
  8550. Xend
  8551. X
  8552. X
  8553. X
  8554. Xprocedure normal(mode)
  8555. X
  8556. X    static UN_bold_str, bold_cookie_str,
  8557. X    UN_underline_str, underline_cookie_str
  8558. X    initial {
  8559. X
  8560. X    if UN_bold_str := getval("se") then
  8561. X        bold_cookie_str := repl(getval("bc") | "\b", getval("sg"))
  8562. X    else {
  8563. X        UN_bold_str := getval("ue")
  8564. X        bold_cookie_str := repl(getval("bc")|"\b", getval("ug"))
  8565. X    }
  8566. X    if UN_underline_str := getval("ue") then
  8567. X        underline_cookie_str := repl(getval("bc")|"\b", getval("ug"))
  8568. X    }        
  8569. X    
  8570. X    if /mode | (mode == "b") then {
  8571. X    iputs(\UN_bold_str)
  8572. X    iputs(\bold_cookie_str)
  8573. X    return
  8574. X    }
  8575. X
  8576. X    iputs(\UN_underline_str)
  8577. X    iputs(\underline_cookie_str)
  8578. X    return
  8579. X
  8580. Xend
  8581. X
  8582. X
  8583. X
  8584. Xprocedure status_line(s,s2,p)
  8585. X
  8586. X    # Writes a status line on the terminal's third-to-last line
  8587. X    # The only necessary argument is s.  S2 (optional) is used
  8588. X    # for extra narrow screens.  In other words, by specifying
  8589. X    # s2 you give status_line an alternate, shorter status string
  8590. X    # to display, in case the terminal isn't wide enough to sup-
  8591. X    # port s.  If p is nonnull, then the status line is either
  8592. X    # centered (if equal to "c"), left justified ("l"), or right
  8593. X    # justified ("r").
  8594. X
  8595. X    local width
  8596. X
  8597. X    /s := ""
  8598. X    width := getval("co")
  8599. X    if *s > width then {
  8600. X    (*s2 < width, s := \s2) |
  8601. X        er("status_line","Your terminal is too narrow.",4)
  8602. X    }
  8603. X    case \p of {
  8604. X    "c"    : s := center(s,width-1)
  8605. X    "l"    : s := left(s,width-1)
  8606. X    "r"    : s := right(s,width-1)
  8607. X    default: stop("status_line:  Unknown option "||string(p),4)
  8608. X    }
  8609. X
  8610. X    iputs(igoto(getval("cm"), 1, getval("li")-2))
  8611. X    emphasize(); writes(s); iputs(getval("ce"))
  8612. X    normal()
  8613. X    return
  8614. X
  8615. Xend
  8616. X
  8617. X
  8618. X
  8619. Xprocedure message(s)
  8620. X
  8621. X    # Display prompt s on the second-to-last line of the screen.
  8622. X    # I hate to use the last line, due to all the problems with
  8623. X    # automatic scrolling.
  8624. X
  8625. X    /s := ""
  8626. X    normal()
  8627. X    iputs(igoto(getval("cm"), 1, getval("li")-1))
  8628. X    writes(s[1:getval("co")] | s)
  8629. X    iputs(getval("ce"))
  8630. X    return
  8631. X
  8632. Xend
  8633. SHAR_EOF
  8634. true || echo 'restore of iscreen.icn failed'
  8635. rm -f _shar_wnt_.tmp
  8636. fi
  8637. # ============= klondike.man ==============
  8638. if test -f 'klondike.man' -a X"$1" != X"-c"; then
  8639.     echo 'x - skipping klondike.man (File already exists)'
  8640.     rm -f _shar_wnt_.tmp
  8641. else
  8642. > _shar_wnt_.tmp
  8643. echo 'x - extracting klondike.man (Text)'
  8644. sed 's/^X//' << 'SHAR_EOF' > 'klondike.man' &&
  8645. X
  8646. X
  8647. X                                  - 1 -
  8648. X
  8649. X
  8650. XKLONDIKE(6)                                               KLONDIKE(6)
  8651. X
  8652. X
  8653. X
  8654. X    NAME
  8655. X        klondike -- one of the many versions of solitaire
  8656. X
  8657. X    SYNOPSIS
  8658. X        klondike  -[ACD]  [-B gameCount]  [-R randomSeed]
  8659. X
  8660. X    DESCRIPTION
  8661. X        This is actually a popular variation on the Klondike version of
  8662. X        Solitaire (or Patience) as described on page 181 of my 1963
  8663. X        version of "Hoyle's Rules of Games".  The difference is that
  8664. X        here we go through the deck (stock) 3 cards at a time instead
  8665. X        of one-by-one, and we allow it any number of times.
  8666. X
  8667. X        It should run on any ANSI-compatible terminal, but it looks
  8668. X        best on a PC, preferably color.
  8669. X
  8670. X    OPTIONS
  8671. X        Options may be either upper or lower case.  They may be given
  8672. X        in any order.  Parameters follow their options with whitespace
  8673. X    inbetween.  Each option must be given as a separate argument.
  8674. X
  8675. X        -A      disables automatically putting uncovered Ace cards
  8676. X                on the appropriate pile.  Note that, in any case, it is
  8677. X                not allowed to put an Ace onto a stack, as this could lead
  8678. X                to building stacks which are too big to display with 25 lines.
  8679. X
  8680. X    -B count
  8681. X        Batch mode.  The requested number of games is played and
  8682. X        the average number of cards promoted to the ace piles is
  8683. X        written to the standard output.  No other I/O is performed.
  8684. X
  8685. X        -C      disable the "click" for silent games
  8686. X
  8687. X        -D      enable special debugging commands which, among other things,
  8688. X                allow one to cheat
  8689. X
  8690. X        -R seed
  8691. X        set the random seed to the designated value
  8692. X
  8693. X    COMMANDS
  8694. X        H or ?  display a Help screen
  8695. X
  8696. X        ^L      (control-L) redraws the screen
  8697. X
  8698. X        A       Automatic mode.  Plays the game until nothing useful
  8699. X        remains to be done, or until any key is struck.
  8700. X
  8701. X        B       Boss key.  The screen is blanked and the current position
  8702. X                is saved.  When the game is started again in the usual
  8703. X                way, this saved game will be automatically restored and
  8704. X        the save file deleted.
  8705. X
  8706. X        C       Continuous mode.  The computer plays games automatically
  8707. X                until a key is struck.  Two statistics are displayed:
  8708. X                the number of games already played, and the total number
  8709. X                of aces which have been promoted to the ace piles.
  8710. X
  8711. X        M       Move a card from the deck or a stack to a stack or an
  8712. X                ace pile.
  8713. X
  8714. X        Q       Quit this game, with the opportunity to play another.
  8715. X
  8716. X        S       Suggest a possible move.  Hitting this key multiple times
  8717. X                results in multiple suggestions being displayed.  When
  8718. X                there is nothing interesting left to do, it will suggest
  8719. X                "Thumb".
  8720. X
  8721. X        T       Thumb.  Remove the top 3 cards from the face-down deck
  8722. X        and lay them face-up on the face-up deck.
  8723. X
  8724. X        U       Undo.  This can be used all the way back to the start
  8725. X                of the current game.
  8726. X
  8727. X        Z       Debug.  This is only enabled when the -D option has
  8728. X                been given on the command line.  There is a sub-menu
  8729. X                of commands available, including a (very brief) Help
  8730. X                summary.
  8731. X
  8732. X        The Move command takes two parameters: source and destination.
  8733. X        Possible sources are:  D for the Deck of face-up cards; and a
  8734. X        number from 1 to 7 inclusive, meaning the corresponding stack.
  8735. X        Possible destinations are the stacks (1-7) and A for the
  8736. X        appropriate ace pile.  For instance, to move the visible card
  8737. X        from the face-up deck to stack 4, one types the three characters:
  8738. X        "MD4".  Actually, the "M" character itself is optional, which
  8739. X        explains why the "debug" command isn't invoked with a "D".
  8740. X
  8741. X    BUGS
  8742. X        Slow.
  8743. X        Doesn't use termcap for maximum portability.
  8744. X        The program's play is simplistic, with no concept of strategy.
  8745. X
  8746. X
  8747. X    FILES
  8748. X        klondike.sav    Position is checkpointed here when the Boss key is used.
  8749. X        klondike.sv?    Position checkpointed here with the "S" debug command.
  8750. X                        "?" can be any (upper-case) character legal in your
  8751. X                        filesystem.
  8752. X
  8753. X    ACKNOWLEDGEMENT
  8754. X        The inspiration, name, and user interface were lifted
  8755. X        wholesale from a game copyrighted in 1985 by Allyn Wade.
  8756. X
  8757. X    VERSION
  8758. X        1.41 -- 26 November, 1990
  8759. X
  8760. X    AUTHOR
  8761. X        Norman H. Azadian
  8762. X        naz@hslrswi
  8763. X
  8764. SHAR_EOF
  8765. true || echo 'restore of klondike.man failed'
  8766. rm -f _shar_wnt_.tmp
  8767. fi
  8768. # ============= README ==============
  8769. if test -f 'README' -a X"$1" != X"-c"; then
  8770.     echo 'x - skipping README (File already exists)'
  8771.     rm -f _shar_wnt_.tmp
  8772. else
  8773. > _shar_wnt_.tmp
  8774. echo 'x - extracting README (Text)'
  8775. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  8776. XThis package is the Unix port of Norman H. Azadian's DOS klondike
  8777. Xprogram.  To test, just mv Makefile.dist to Makefile, and make.
  8778. XTo install, su root, and then make install.  Needs a 25-line term
  8779. Xwith at least 80 cols.  WILL NOT WORK ON SYSTEMS THAT DO NOT IM-
  8780. XPLEMENT THE STTY -G OPTION (TSK, TSK).  UNLESS YOU LIKE HAVING A
  8781. XLOCKED UP KEYBOARD, DON'T EVEN THINK OF TRYING KLONDIKE ON SUCH A
  8782. XSYSTEM.
  8783. X
  8784. XIt's a nice card game, but a pretty rough hack for Unix.
  8785. X
  8786. X-Richard Goerwitz
  8787. SHAR_EOF
  8788. true || echo 'restore of README failed'
  8789. rm -f _shar_wnt_.tmp
  8790. fi
  8791. # ============= Makefile.dist ==============
  8792. if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
  8793.     echo 'x - skipping Makefile.dist (File already exists)'
  8794.     rm -f _shar_wnt_.tmp
  8795. else
  8796. > _shar_wnt_.tmp
  8797. echo 'x - extracting Makefile.dist (Text)'
  8798. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
  8799. XPROGNAME = klondike
  8800. X
  8801. X# Please edit these to reflect your local file structure & conventions.
  8802. XDESTDIR = /usr/local/bin
  8803. XOWNER = bin
  8804. XGROUP = bin
  8805. X
  8806. XMAN = klondike.man
  8807. XSRC = klondike.icn kloncon.icn klonsub.icn
  8808. XLIB = itlib.icn getchlib.icn iscreen.icn
  8809. X
  8810. XSHELL = /bin/sh
  8811. X
  8812. X$(PROGNAME): $(SRC) $(LIB)
  8813. X    icont -Si 1000 -Sn 2000 -o $(PROGNAME) $(SRC) $(LIB)
  8814. X
  8815. X# Pessimistic assumptions regarding the environment (in particular,
  8816. X# I don't assume you have the BSD "install" shell script).
  8817. Xinstall: $(PROGNAME)
  8818. X    @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
  8819. X    cp $(PROGNAME) $(DESTDIR)/
  8820. X    chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  8821. X    chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  8822. X    @echo "\nInstallation done.\n"
  8823. SHAR_EOF
  8824. true || echo 'restore of Makefile.dist failed'
  8825. rm -f _shar_wnt_.tmp
  8826. fi
  8827. rm -f _shar_seq_.tmp
  8828. echo You have unpacked the last part
  8829. exit 0
  8830.  
  8831. From icon-group-request@arizona.edu  Mon Dec 10 22:09:27 1990
  8832. Resent-From: icon-group-request@arizona.edu
  8833. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8834.     id AA23425; Mon, 10 Dec 90 22:09:27 -0700
  8835. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 10 Dec 90 22:08 MST
  8836. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11002; Mon, 10 Dec 90
  8837.  21:02:50 -0800
  8838. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8839.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8840.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8841. Resent-Date: Mon, 10 Dec 90 22:09 MST
  8842. Date: 11 Dec 90 03:15:50 GMT
  8843. From: midway!ellis.uchicago.edu!goer@handies.ucar.edu
  8844. Subject: continuation of the code orgy
  8845. Sender: icon-group-request@arizona.edu
  8846. Resent-To: icon-group@cs.arizona.edu
  8847. To: icon-group@arizona.edu
  8848. Resent-Message-Id: <F00BEDD3CF4340453E@Arizona.edu>
  8849. Message-Id: <1990Dec11.031550.9454@midway.uchicago.edu>
  8850. Organization: University of Chicago
  8851. X-Envelope-To: icon-group@CS.Arizona.EDU
  8852. X-Vms-To: icon-group@Arizona.edu
  8853.  
  8854. I get annoyed when software requires that I be in this or that
  8855. directory, and refuses to poke around a bit, looking for files.
  8856. To help remedy the deficiency, I wrote the procedure appended
  8857. below.
  8858.  
  8859. Right now I've only tested it under Unix and MS-DOS.  I'd love
  8860. it if someone would repost with additions to make it work under
  8861. other operating systems.
  8862.  
  8863. -Richard (goer@sophist.uchicago.edu)
  8864.  
  8865.  
  8866. ############################################################################
  8867. #
  8868. #    Name:     getpaths.icn
  8869. #
  8870. #    Title:     suspend elements in path environment variable
  8871. #
  8872. #    Author:     Richard L. Goerwitz
  8873. #
  8874. #    Version: 1.3
  8875. #
  8876. ############################################################################
  8877. #
  8878. #      Suspends, in turn, the paths supplied as args to getpaths(),
  8879. #  then all paths in the PATH environment variable.  A typical
  8880. #  invocation might look like:
  8881. #
  8882. #     open(getpaths("/usr/local/lib/icon/procs") || filename)
  8883. #
  8884. #  Note that getpaths() will be resumed in the above context until
  8885. #  open succeeds in finding an existing, readable file.  Getpaths()
  8886. #  can take any number of arguments.
  8887. #
  8888. ############################################################################
  8889. #
  8890. #  Requires: UNIX or MS-DOS
  8891. #
  8892. ############################################################################
  8893.  
  8894.  
  8895. procedure getpaths(base_paths[])
  8896.  
  8897.     local paths, p
  8898.     static sep, trailer, trimmer
  8899.     initial {
  8900.     if find("UNIX", &features) then {
  8901.         sep := ":"
  8902.         trailer := "/"
  8903.         trimmer := cset(trailer || " ")
  8904.         }
  8905.     else if find("MS-DOS", &features) then {
  8906.         sep := ";"
  8907.         trailer := "\\"
  8908.         trimmer := cset(trailer || " ")
  8909.     }
  8910.         else stop("getpaths:  OS not supported.")
  8911.     }
  8912.  
  8913.     suspend !base_paths
  8914.     paths := getenv("PATH")
  8915.     \paths ? {
  8916.     tab(match(sep))
  8917.     while p := 1(tab(find(sep)), move(1))
  8918.     do suspend ("" ~== trim(p,trimmer)) || trailer
  8919.     return ("" ~== trim(tab(0),trimmer)) || trailer
  8920.     }
  8921.  
  8922. end
  8923.  
  8924. From icon-group-request@arizona.edu  Tue Dec 11 02:07:46 1990
  8925. Resent-From: icon-group-request@arizona.edu
  8926. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8927.     id AA29311; Tue, 11 Dec 90 02:07:46 -0700
  8928. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 11 Dec 90 02:07 MST
  8929. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15203; Tue, 11 Dec 90
  8930.  00:54:35 -0800
  8931. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8932.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8933.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8934. Resent-Date: Tue, 11 Dec 90 02:07 MST
  8935. Date: 11 Dec 90 08:50:41 GMT
  8936. From: zaphod.mps.ohio-state.edu!usc!samsung!munnari.oz.au!goanna!ok@tut.cis.ohio-state.edu
  8937. Subject: RE: continuation of the code orgy
  8938. Sender: icon-group-request@arizona.edu
  8939. Resent-To: icon-group@cs.arizona.edu
  8940. To: icon-group@arizona.edu
  8941. Resent-Message-Id: <EFEAA16F3DE3404F2B@Arizona.edu>
  8942. Message-Id: <4482@goanna.cs.rmit.oz.au>
  8943. Organization: Comp Sci, RMIT, Melbourne, Australia
  8944. X-Envelope-To: icon-group@CS.Arizona.EDU
  8945. X-Vms-To: icon-group@Arizona.edu
  8946. References: <1990Dec11.031550.9454@midway.uchicago.edu>
  8947.  
  8948. In article <1990Dec11.031550.9454@midway.uchicago.edu>, goer@ellis.uchicago.edu (Richard L. Goerwitz) writes:
  8949. >     paths := getenv("PATH")
  8950.  
  8951. $PATH is for *programs*.  Data files do not belong there.
  8952. A better approach would be to allow $env substitution in the argument
  8953. to getpaths, e.g.
  8954.     getpaths("$HOME/lib/foo:$PROJECT/lib", file)
  8955.  
  8956. -- 
  8957. The Marxists have merely _interpreted_ Marxism in various ways;
  8958. the point, however, is to _change_ it.        -- R. Hochhuth.
  8959.  
  8960. From goer%sophist@gargoyle.uchicago.edu  Tue Dec 11 07:23:38 1990
  8961. Resent-From: goer%sophist@gargoyle.uchicago.edu
  8962. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8963.     id AA09506; Tue, 11 Dec 90 07:23:38 -0700
  8964. Return-Path: goer@sophist.uchicago.edu
  8965. Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 11 Dec 90 07:23 MST
  8966. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  8967.  (4.0/1.14) id AA23936; Tue, 11 Dec 90 08:22:41 CST
  8968. Received: by sophist (4.1/UofC3.1X) id AA09758; Tue, 11 Dec 90 08:26:00 CST
  8969. Resent-Date: Tue, 11 Dec 90 07:23 MST
  8970. Date: Tue, 11 Dec 90 08:26:00 CST
  8971. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  8972. Subject: RE: continuation of the code orgy
  8973. Resent-To: icon-group@cs.arizona.edu
  8974. To: zaphod.mps.ohio-state.edu!usc!samsung!munnari.oz.au!goanna!ok@tut.cis.ohio-state.edu
  8975. Cc: icon-group@arizona.edu
  8976. Resent-Message-Id: <EFBE814EEC334052AF@Arizona.edu>
  8977. Message-Id: <9012111426.AA09758@sophist>
  8978. X-Envelope-To: icon-group@CS.Arizona.EDU
  8979. X-Vms-To: 
  8980.  zaphod.mps.ohio-state.edu!usc!samsung!munnari.oz.au!goanna!ok@tut.cis.ohio-state.edu
  8981. X-Vms-Cc: icon-group@Arizona.edu
  8982.  
  8983.     $PATH is for *programs*.  Data files do not belong there.
  8984.  
  8985. A relevant consideration.  BUT:  Icon programs are often unpacked into
  8986. user directories, and people aren't as careful about separating files
  8987. into lib/src/bin as you might suppose (nor should they necessesarily
  8988. be).
  8989.  
  8990.     A better approach would be to allow $env substitution in the argument
  8991.     to getpaths, e.g.
  8992.         getpaths("$HOME/lib/foo:$PROJECT/lib", file)
  8993.  
  8994. I utilized the PATH environment variable because Unix and MS-DOS happen to
  8995. share this feature.  It would be easy enough to change the particular
  8996. environment variable used, according to the OS, but when you start put-
  8997. ting $STRINGS into the arguments, you are not going to be able to run
  8998. the program under anything but Unix.
  8999.  
  9000. What I'd really like to see at this point is some revisions to the code
  9001. along the lines you suggested.  Can this be done in a way that will make
  9002. the program broadly useful?
  9003.  
  9004. -Richard (goer@sophist.uchicago.edu)
  9005.  
  9006. From icon-group-request@arizona.edu  Tue Dec 11 14:54:42 1990
  9007. Resent-From: icon-group-request@arizona.edu
  9008. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9009.     id AA27425; Tue, 11 Dec 90 14:54:42 -0700
  9010. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 11 Dec 90 14:54 MST
  9011. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA01894; Tue, 11 Dec 90
  9012.  13:47:05 -0800
  9013. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9014.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9015.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9016. Resent-Date: Tue, 11 Dec 90 14:54 MST
  9017. Date: 11 Dec 90 21:42:51 GMT
  9018. From: news@psuvax1.cs.psu.edu
  9019. Subject: iconx.hdr size on a Sun-4.
  9020. Sender: icon-group-request@arizona.edu
  9021. Resent-To: icon-group@cs.arizona.edu
  9022. To: icon-group@arizona.edu
  9023. Resent-Message-Id: <EF7F80EA3593405DB0@Arizona.edu>
  9024. Message-Id: <Fnx$o1s3@cs.psu.edu>
  9025. Organization: Penn State Computer Science
  9026. X-Envelope-To: icon-group@CS.Arizona.EDU
  9027. X-Vms-To: icon-group@Arizona.edu
  9028.  
  9029. 12.8k is a little large.  The changes below will reduce the size to
  9030. 2.6k.  Apply the patch below to src/icont/ixhdr.c, and add the
  9031. following to config/unix/sun4/define.h:
  9032.     #define MaxHdr    2688
  9033.     #define UseFakeFunctionsInHdr
  9034.  
  9035. UseFakeFunctionsInHdr will replace some standard C library functions
  9036. with smaller and simpler versions in ixhdr.c.
  9037.  
  9038. This may have benefit for systems other than Sun-4s; I haven't tried.
  9039.  
  9040. The real trick is to reduce the header to 20 bytes.
  9041. --
  9042. Felix Lee    flee@cs.psu.edu
  9043.  
  9044. *** /tmp/,RCSt1a04604    Tue Dec 11 16:30:01 1990
  9045. --- ixhdr.c    Tue Sep 11 19:22:57 1990
  9046. ***************
  9047. *** 30,35 ****
  9048. --- 30,61 ----
  9049.   #define Iconx IconxPath
  9050.   #endif                    /* Iconx */
  9051.   
  9052. + #ifdef UseFakeFunctionsInHdr
  9053. + /* fake functions to reduce executable size. */
  9054. + novalue exit(x) int x; { _exit(x); }
  9055. + /* small, inefficient strcpy(). */
  9056. + char * strcpy(a, b) register char * a; register char * b;
  9057. + {
  9058. +     while (*a++ = *b++) ;
  9059. +     return a;    /* note! this is incompatible with real strcpy */
  9060. + }
  9061. + /* small, inefficient strlen(). */
  9062. + int strlen(s) char * s;
  9063. + {
  9064. +     register char * p;
  9065. +     while (*p++) ;
  9066. +     return p - s;
  9067. + }
  9068. + /* small, inefficient strcat(). */
  9069. + char * strcat(a, b) register char * a; register char * b;
  9070. + {
  9071. +     while (*a++) ;
  9072. +     while (*a++ = *b++) ;
  9073. +     return a;    /* note! this is incompatible with real strcat */
  9074. + }
  9075. + #endif UseFakeFunctionsInHdr
  9076.   novalue main(argc, argv)
  9077.   int argc;
  9078.   char **argv;
  9079.  
  9080. From icon-group-request@arizona.edu  Thu Dec 13 05:27:38 1990
  9081. Resent-From: icon-group-request@arizona.edu
  9082. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9083.     id AA13790; Thu, 13 Dec 90 05:27:38 -0700
  9084. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 13 Dec 90 05:27 MST
  9085. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17639; Thu, 13 Dec 90
  9086.  04:18:03 -0800
  9087. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9088.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9089.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9090. Resent-Date: Thu, 13 Dec 90 05:27 MST
  9091. Date: 12 Dec 90 13:37:46 GMT
  9092. From: jvb@cs.duke.edu
  9093. Subject: public domain/free version
  9094. Sender: icon-group-request@arizona.edu
  9095. Resent-To: icon-group@cs.arizona.edu
  9096. To: icon-group@arizona.edu
  9097. Resent-Message-Id: <EE3C5F1089E34072AD@Arizona.edu>
  9098. Message-Id: <661009065@helios.cs.duke.edu>
  9099. Organization: Duke University Computer Science Dept.; Durham, N.C.
  9100. X-Envelope-To: icon-group@CS.Arizona.EDU
  9101. X-Vms-To: icon-group@Arizona.edu
  9102.  
  9103. I will be teaching a programming languages course this Spring and am 
  9104. looking to teach a string manipulation language.  ICON is one natural
  9105. choice.  However, I have a zero budget.  This leaves me with awk as
  9106. my only choice.  I don't think it is bad choice, but ICON would be better.
  9107. Is there a free ICON interpretter out there?
  9108.  
  9109. Jack
  9110.  
  9111. From icon-group-request@arizona.edu  Thu Dec 13 06:30:54 1990
  9112. Resent-From: icon-group-request@arizona.edu
  9113. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9114.     id AA15025; Thu, 13 Dec 90 06:30:54 -0700
  9115. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 13 Dec 90 06:30 MST
  9116. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA20514; Thu, 13 Dec 90
  9117.  05:25:11 -0800
  9118. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9119.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9120.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9121. Resent-Date: Thu, 13 Dec 90 06:30 MST
  9122. Date: 12 Dec 90 17:01:31 GMT
  9123. From: hub.ucsb.edu!anywhere!aks@ucsd.edu
  9124. Subject: RE: public domain/free version
  9125. Sender: icon-group-request@arizona.edu
  9126. Resent-To: icon-group@cs.arizona.edu
  9127. To: icon-group@arizona.edu
  9128. Resent-Message-Id: <EE338A503FF3406EA4@Arizona.edu>
  9129. Message-Id: <7794@hub.ucsb.edu>
  9130. Organization: CCSE, Univ. of CA, Santa Barbara
  9131. X-Envelope-To: icon-group@CS.Arizona.EDU
  9132. X-Vms-To: icon-group@Arizona.edu
  9133. References: <661009065@helios.cs.duke.edu>
  9134.  
  9135. In <661009065@helios.cs.duke.edu> jvb@duke.cs.duke.edu (Jack V. Briner, Jr.) writes:
  9136.  
  9137. >I will be teaching a programming languages course this Spring and am 
  9138. >looking to teach a string manipulation language.  ICON is one natural
  9139. >choice.  However, I have a zero budget.  This leaves me with awk as
  9140. >my only choice.  I don't think it is bad choice, but ICON would be better.
  9141. >Is there a free ICON interpretter out there?
  9142.  
  9143. For the benefit of others, here's Griswold's original posting announcing 
  9144. Version 8:
  9145.  
  9146. From +comp.lang.icon Wed Dec 12 08:56:24 1990
  9147. From: ralph@CS.ARIZONA.EDU ("Ralph Griswold")
  9148. Newsgroups: comp.lang.icon
  9149. Subject: Version 8 of Icon for UNIX
  9150. Message-ID: <9003311250.AA18283@megaron.cs.arizona.edu>
  9151. Date: 31 Mar 90 12:50:35 GMT
  9152. Distribution: inet
  9153. Organization: The Internet
  9154. Lines: 37
  9155.  
  9156. Version 8 of Icon for UNIX systems is now available. This implementation
  9157. can be configured for a wide variety of UNIX systems. Configuration
  9158. information is provided for 56 different systems, including the Sun
  9159. Sparcstation, the DecStation, the NeXT, the DG AViiON, and the Cray-2.
  9160.  
  9161. Configurations for new systems can be added with relative ease.
  9162.  
  9163. The UNIX distribution includes source code, configuration files,
  9164. documentation, the Icon program library (new in Version 8), and
  9165. several auxiliary components of Icon.
  9166.  
  9167. Version 8 of Icon for UNIX systems can be obtained by anonymous FTP
  9168. to cs.arizona.edu. After connecting, cd /icon/v8.  Get READ.ME
  9169. there for more information.
  9170.  
  9171. If you do not have FTP access or prefer to obtain a magnetic tape
  9172. and printed documentation, Version 8 of Icon for UNIX can be ordered
  9173. ~from:
  9174.  
  9175.     Icon Project
  9176.     Department of Computer Science
  9177.     Gould-Simpson Building
  9178.     The University of Arizona
  9179.     Tucson, AZ   85721
  9180.  
  9181.     602 621-2018 (voice)
  9182.     602 621-4246 (FAX)
  9183.  
  9184. The price is $30, payable in US dollars with a check written on a bank
  9185. in the United States.  Orders also can be charged to MasterCard or Visa.
  9186. This price includes shipping by parcel post in the United States, Canada,
  9187. and Mexico. Add $10 for air mail delivery to other countries.
  9188.  
  9189. Please direct any questions to me, not to icon-project or icon-group.
  9190.  
  9191.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  9192.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  9193.  
  9194. --
  9195.  
  9196. Alan Stebbens <aks@hub.ucsb.edu>
  9197.  
  9198. From goer%sophist@gargoyle.uchicago.edu  Thu Dec 13 15:50:14 1990
  9199. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9200. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9201.     id AA07464; Thu, 13 Dec 90 15:50:14 -0700
  9202. Return-Path: goer@sophist.uchicago.edu
  9203. Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 13 Dec 90 15:49 MST
  9204. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  9205.  (4.0/1.14) id AA11262; Thu, 13 Dec 90 16:49:36 CST
  9206. Received: by sophist (4.1/UofC3.1X) id AA02207; Thu, 13 Dec 90 16:52:40 CST
  9207. Resent-Date: Thu, 13 Dec 90 15:49 MST
  9208. Date: Thu, 13 Dec 90 16:52:40 CST
  9209. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9210. Subject: Iconish b-trees
  9211. Resent-To: icon-group@cs.arizona.edu
  9212. To: icon-group@arizona.edu
  9213. Resent-Message-Id: <EDE56A557013407B36@Arizona.edu>
  9214. Message-Id: <9012132252.AA02207@sophist>
  9215. X-Envelope-To: icon-group@CS.Arizona.EDU
  9216. X-Vms-To: icon-group@Arizona.edu
  9217.  
  9218. Has anyone worked on b-tree algorithms for use in Icon - i.e. on
  9219. b-trees which use hash tables or other built-in Iconish data struc-
  9220. tures, as part of their implementation.  I'm just curious whether
  9221. I need to think this stuff through from scratch.
  9222.  
  9223. -Richard
  9224.  
  9225. From goer%sophist@gargoyle.uchicago.edu  Thu Dec 13 18:05:50 1990
  9226. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9227. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9228.     id AA10873; Thu, 13 Dec 90 18:05:50 -0700
  9229. Return-Path: goer@sophist.uchicago.edu
  9230. Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 13 Dec 90 18:05 MST
  9231. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  9232.  (4.0/1.14) id AA14286; Thu, 13 Dec 90 19:05:13 CST
  9233. Received: by sophist (4.1/UofC3.1X) id AA02487; Thu, 13 Dec 90 19:08:17 CST
  9234. Resent-Date: Thu, 13 Dec 90 18:05 MST
  9235. Date: Thu, 13 Dec 90 19:08:17 CST
  9236. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9237. Subject: Iconish b-trees
  9238. Resent-To: icon-group@cs.arizona.edu
  9239. To: icon-group@arizona.edu
  9240. Resent-Message-Id: <EDD2763741A34077AB@Arizona.edu>
  9241. Message-Id: <9012140108.AA02487@sophist>
  9242. X-Envelope-To: icon-group@CS.Arizona.EDU
  9243. X-Vms-To: icon-group@Arizona.edu
  9244.  
  9245. Blasted noisy lines.  I'll try again.
  9246.  
  9247. Has anyone given any thought to the question of how b-trees might best
  9248. be implemented in Icon, taking advantage data structures like tables
  9249. and sets?
  9250.  
  9251. -Richard (goer@sophist.uchicago.edu)
  9252.  
  9253. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Sat Dec 15 10:36:39 1990
  9254. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  9255.     id AA24856; Sat, 15 Dec 90 10:36:39 -0700
  9256. Received: by uwm.edu; id AA04923; Sat, 15 Dec 90 11:36:30 -0600
  9257. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  9258.           Sat, 15 Dec 90 10:55:06 CDT
  9259. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  9260.           Sat, 15 Dec 1990 07:36 CDT
  9261. Date: Sat, 15 Dec 1990 07:36 CDT
  9262. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  9263. Subject: Draw Poker Game
  9264. To: icon-group@cs.arizona.edu
  9265. Message-Id: <67EEF267C0600950@mis.mcw.edu>
  9266. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  9267. X-Envelope-To: icon-group@cs.arizona.edu
  9268. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  9269.  
  9270.  
  9271. Since the submission of the solitaire game, I felt it might be nice if I
  9272. could contribute one. Here's a draw poker game. I use ICON on VAX/VMS 5.2
  9273. with VT terminals, so I do everything with ANSI escape sequences. I also
  9274. realize that I could have done some of the table manipulations more
  9275. efficiently, but I thought in this case, tab["key"] := something, helped
  9276. the readability of the code. Invoke it with ICONX DRAW [credits]. The
  9277. parameter is how much virtual money you want to start with. 3 is default.
  9278. Have fun!
  9279.  
  9280. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  9281. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  9282. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  9283.  
  9284. #########################################################
  9285. #                                                       #
  9286. # DRAW.ICN          12/15/90          BY TENAGLIA       #
  9287. #                                                       #
  9288. # SIMPLE BUT FUN DRAW POKER GAME. WORKS ON ANSI SCREEN. #
  9289. # USAGE : ICONX DRAW [starting credits]                 #
  9290. #                                                       #
  9291. #########################################################
  9292. global money, message
  9293. procedure main(param)
  9294.   money := integer(param[1]) | 3
  9295.   write("\e[2J\e[2H          \e#3\e[1;7mDRAW : Nothing Wild\e[m")
  9296.   write("          \e#4\e[1;7mDRAW : Nothing Wild\e[m")
  9297.   repeat
  9298.     {
  9299.     deck    := shuffle()
  9300.     message := ""
  9301.     hand    := []
  9302.     every 1 to 5 do put(hand,pop(deck))
  9303.     display(hand,1,4)
  9304.     repeat
  9305.       {
  9306.       keep := obtain("\e[12;1fKeep which ones (1 2 3 4 5):\e[J")
  9307.       if map(input("\e[12;50fAre you sure y/n :\e[K"))[1] == "y" then break
  9308.       }
  9309.     all := set() ; every i := 1 to 5 do insert(all,i)
  9310.     every delete(all,integer(!keep))
  9311.     every hand[!all] := pop(deck)
  9312.     money +:= evaluate(hand)
  9313.     display(hand,1,15)
  9314.     if map(input("\e[23;1fAnother game? y/n :\e[K"))[1] ~== "y" then break
  9315.     }
  9316.   write("\e[2J\e[H")
  9317.   end
  9318.  
  9319. #
  9320. # THIS SECTION OBTAINS THE VALIDATES INPUT
  9321. #
  9322. procedure obtain(prompt)
  9323.   bad := 0
  9324.   repeat
  9325.     {
  9326.     nums := parse(input(prompt),' \t,')
  9327.     every num := !nums do
  9328.       {
  9329.       integer(num)       | { input(num || " not a number. Press <RETURN>")            ; bad := 1 ; next }
  9330.       (integer(num) > 0) | { input(num || " must be between 1 and 5. Press <RETURN>") ; bad := 1 ; next }
  9331.       (integer(num) < 6) | { input(num || " must be between 1 and 5. Press <RETURN>") ; bad := 1 ; next }
  9332.       }
  9333.     (bad = 1) | return nums
  9334.     }
  9335.   end
  9336.  
  9337. #
  9338. # THIS ROUTINE DISPLAYS THE CURRENT HAND AT THE GIVEN X,Y COORDINATES
  9339. #
  9340. procedure display(cards,x,y)
  9341.   all   := []
  9342.   every card := !cards do
  9343.     {
  9344.     j := y
  9345.     if find(card[2],"CS") then card := "\e[1;7m" || card || "\e[m"
  9346.     shape := ["\e["||(j+:=1)||";"||x||"f\e(0lqqqqqqqk\e(B"]
  9347.     put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x " || card || "    x\e(B")
  9348.     put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x       x\e(B")
  9349.     put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x       x\e(B")
  9350.     put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x       x\e(B")
  9351.     put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x    " || card || " x\e(B")
  9352.     put(shape,"\e["||(j+:=1)||";"||x||"f\e(0mqqqqqqqj\e(B")
  9353.     put(all,shape)
  9354.     x +:= 14
  9355.     }
  9356.   while shape := pop(all) do every writes(!shape)
  9357.   writes(message,"\e[",y+2,";",x-3,"fCredits\e[K")
  9358.   writes("\e[",y+3,";",x-5,"f  \e[1m",right(money,7),"\e[m\e[K")
  9359.   end
  9360.  
  9361. #
  9362. # THIS ROUTINE SHUFFLES THE CARD DECK
  9363. #
  9364. procedure shuffle()
  9365.   static faces, suits
  9366.   local cards
  9367.   initial {
  9368.           &random := map(&clock,":","7")   # initial on multiple shuffles
  9369.           faces   := ["2","3","4","5","6","7","8","9","T","J","Q","K","A"]
  9370.           suits   := ["D","H","C","S"]
  9371.           }
  9372.   cards   := []
  9373.   every put(cards,!faces || !suits)
  9374.   swaps := 52 + ?12
  9375.   every 1 to swaps do cards[?52] :=: cards[?52]
  9376.   return cards
  9377.   end
  9378.  
  9379. #
  9380. # THIS SECTION EVALUATES THE FINAL HAND, TALLIES WINNINGS OR LOOSINGS
  9381. #
  9382. procedure evaluate(cards)
  9383.  
  9384.   static  hash1,hash2
  9385.   initial {
  9386.           hash1 := "23456789TJQKA"
  9387.           hash2 := "CSHD"
  9388.           }
  9389.  
  9390.   temp  := table(0) ; suit := table(0) ; result := table(0)
  9391.   four  := 0 ; three := 0 ; twopair := 0 ; job     := 0 ; points := -1
  9392.   flush := 0 ; full  := 0 ; royal   := 0 ; straight:= 0 ; pair:= 0
  9393.  
  9394.   every card := !cards do
  9395.     temp[card[1]] +:= 1
  9396.   every tmp := key(temp) do
  9397.     case temp[tmp] of
  9398.       {
  9399.       4 : { result["four"]  := 1 ; result["job"] := 1 }
  9400.       3 : { result["three"] := 1 ; result["job"] := 1 }
  9401.       2 : { result["pair"] +:= 1 ; result["job"] := if find(tmp,hash1) > 9 then 1 }
  9402.       }
  9403.   if result["pair"] = 2 then { result["twopair"] := 1 ; result["job"] := 1 }
  9404.   every card := !cards    do suit[card[2]] +:= 1
  9405.   every tmp  := key(suit) do if suit[tmp] = 5 then { result["flush"] := 1 ; result["job"] := 1 }
  9406.   tmp := sort(cards) ; test := ""
  9407.   every card := !tmp do test ||:= card[1]
  9408.   if (result["three"] = 1) & (result["pair"] = 1) then { result["full"] := 1 ; result["job"] := 1 }
  9409.   if find(test,hash1) then
  9410.     {
  9411.     result["straight"] := 1
  9412.     result["job"]      := 1
  9413.     if test[1] == "T" then result["royal"] := 1
  9414.     }
  9415.   if result["job"]     = 1 then points +:= 1
  9416.   if result["twopair"] = 1 then points +:= 1
  9417.   if result["three"]   = 1 then points +:= 5
  9418.   if result["full"]    = 1 then points +:= 10
  9419.   if result["flush"]   = 1 then points +:= 10
  9420.   if result["straight"]= 1 then points +:= 10
  9421.   if result["four"]    = 1 then points +:= 100
  9422.   if result["royal"]   = 1 then points +:= 500
  9423.   message := "\e[14;1fHand Evaluation -> "
  9424.   every thing := key(result) do message ||:= thing || ", "
  9425.   return points
  9426.   end
  9427.  
  9428. #
  9429. # THIS ROUTINE PARSES A STRING WITH RESPECT TO SOME DELIMITER
  9430. #
  9431. procedure parse(line,delims)
  9432.   static chars
  9433.   chars  := &cset -- delims
  9434.   tokens := []
  9435.   line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
  9436.   return tokens
  9437.   end
  9438.  
  9439. #
  9440. # THIS ROUTINE PROMPTS FOR INPUT AND RETURNS A STRING
  9441. #
  9442. procedure input(prompt)
  9443.   writes(prompt)
  9444.   return read()
  9445.   end
  9446.  
  9447.  
  9448.  
  9449. From icon-group-request@arizona.edu  Sun Dec 16 11:10:25 1990
  9450. Resent-From: icon-group-request@arizona.edu
  9451. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9452.     id AA28760; Sun, 16 Dec 90 11:10:25 -0700
  9453. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Sun, 16 Dec 90 11:10 MST
  9454. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03555; Sun, 16 Dec 90
  9455.  09:50:35 -0800
  9456. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9457.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9458.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9459. Resent-Date: Sun, 16 Dec 90 11:10 MST
  9460. Date: 15 Dec 90 02:04:05 GMT
  9461. From: snorkelwacker.mit.edu!usc!zaphod.mps.ohio-state.edu!mips!daver!kcdev!obrien@bloom-beacon.mit.edu
  9462. Subject: klondike
  9463. Sender: icon-group-request@arizona.edu
  9464. Resent-To: icon-group@cs.arizona.edu
  9465. To: icon-group@arizona.edu
  9466. Resent-Message-Id: <EBB0FCF68D03408C28@Arizona.edu>
  9467. Message-Id: <1259@kcdev.UUCP>
  9468. Organization: AT&T Kansas City, MO.
  9469. X-Envelope-To: icon-group@CS.Arizona.EDU
  9470. X-Vms-To: icon-group@Arizona.edu
  9471.  
  9472.  
  9473. Would some kind person send me sector 5 of the unix version of klondike.
  9474. I can not seem to get the one I captured to download to my machine.
  9475.  
  9476. Please send to    obrien@spam
  9477. because this feed appears to be about gone.
  9478.  
  9479. -- 
  9480. | John D. O'Brien      AT&T Communications     Kansas City, MO     64106 |
  9481. |            Ph(816)654-4085            Home(816)229-7648                |
  9482. | Email: obrien@kcdev.UUCP          ATTMail: attmail!kc1sur!jdobrien     |
  9483. | $include {std_disclaimer.h}       "Please don't drink and drive"       |
  9484.  
  9485. From icon-group-request@arizona.edu  Sun Dec 16 12:04:55 1990
  9486. Resent-From: icon-group-request@arizona.edu
  9487. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9488.     id AA29965; Sun, 16 Dec 90 12:04:55 -0700
  9489. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Sun, 16 Dec 90 12:04 MST
  9490. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA06641; Sun, 16 Dec 90
  9491.  10:56:14 -0800
  9492. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9493.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9494.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9495. Resent-Date: Sun, 16 Dec 90 12:04 MST
  9496. Date: 15 Dec 90 19:21:20 GMT
  9497. From: midway!quads.uchicago.edu!goer@uunet.uu.net
  9498. Subject: RE: Draw Poker Game
  9499. Sender: icon-group-request@arizona.edu
  9500. Resent-To: icon-group@cs.arizona.edu
  9501. To: icon-group@arizona.edu
  9502. Resent-Message-Id: <EBA96CBD07234086BF@Arizona.edu>
  9503. Message-Id: <1990Dec15.192120.1009@midway.uchicago.edu>
  9504. Organization: University of Chicago
  9505. X-Envelope-To: icon-group@CS.Arizona.EDU
  9506. X-Vms-To: icon-group@Arizona.edu
  9507. References: <67EEF267C0600950@mis.mcw.edu>
  9508.  
  9509. In article <67EEF267C0600950@mis.mcw.edu>
  9510. TENAGLIA@mis.mcw.edu (Chris Tenaglia - 257-8765) writes:
  9511.  
  9512. >global money, message
  9513. >procedure main(param)
  9514. >  money := integer(param[1]) | 3
  9515. >  write("\e[2J\e[2H          \e#3\e[1;7mDRAW : Nothing Wild\e[m")
  9516.           ^^^^^^^^^^          ^^^^^^^^^^^^                  ^^^^^
  9517.  
  9518. I love to try to port people's things to Unix, but it's sometimes
  9519. pretty hard.  The code above is part of a really neat game, and I
  9520. like it a lot.  But unless a person happens to know ANSI escape se-
  9521. quences like the back of his or her hand, it's kinda hard to know
  9522. what is going on.  It's also a fact that most ANSI terminals don't
  9523. really implement the full, exact ANSI standard, and in general peo-
  9524. ple (at least here at the U of Chicago) are using Wyse, Televideo,
  9525. or VT-100 terminals (or emulators).
  9526.  
  9527. It's hard to say this, especially when the code is otherwise so clear
  9528. and clean, but my own personal observation is that code which assumes
  9529. hard-coded screen control 1) is hard to read, 2) is harder to main-
  9530. tain, and 3) is very tedious to port.
  9531.  
  9532. One solution (the one used in the klondike game) is to make all the
  9533. screen control sequences into global variables, and put them together
  9534. in one place, so they can easily be altered.  If the global variables
  9535. are mnemonic, this solves 1 and 2, but leaves 3 still up in the air.
  9536. (I've written a lot of code that has all three problems, so don't
  9537. take this as a flame.)  The workability of the "klondike" solution is
  9538. evinced by the fact that I was able to port it to Unix in a very short
  9539. period of time and repost.  I admit that the repost was something of a
  9540. hack.  When the next klondike version comes out I'll do a more serious
  9541. job.  The mnemonic global variables really helped.
  9542.  
  9543. Another solution is to isolate screen control sequences in a single
  9544. procedure, which would be called mnemonically.  This solution is not
  9545. perfect, because it is not always as easy to read as the "klondike"
  9546. solution.  But is does make maintenance a snap, and leaves would-be
  9547. port-ers with very little work to do.  I'll give a little example
  9548. below that will show how things can be done this way, and yet kept
  9549. readable:
  9550.  
  9551. >  write("\e[2J\e[2H          \e#3\e[1;7mDRAW : Nothing Wild\e[m")
  9552.  
  9553.    output("clear")
  9554.    output("goto",1,2)
  9555.    writes("          ")
  9556.    output(whatever \e#3 does)
  9557.    output("bold-reverse")  # or output("bold"); output("reverse") ???
  9558.    write("DRAW : Nothing Wild")
  9559.    output("normal")
  9560.  
  9561. By doing things this way, even someone who doesn't know the least bit
  9562. about ANSI screen codes will be able to understand what is going on.
  9563. What is more, no changes will be required if, say, some escape sequence
  9564. needs to be changed.  In fact, one could insert codes for a _whole dif-
  9565. ferent terminal_ and it wouldn't require changing a single scratch of
  9566. the above code.  All changes would be isolated within the output pro-
  9567. cedure.
  9568.  
  9569. I admit that things are more bulky this way.  But you don't have to have
  9570. your ANSI chart out while programming.  And in fact, you don't even have
  9571. to think about what sort of terminal you're using.  Nor does anyone else
  9572. who reads your code.  The sequence output("clear") is infinitely more
  9573. clear, portable, and maintainable than "\e[2J"!
  9574.  
  9575. One more bit that might be useful to inject here:  Most terminals can han-
  9576. dle 24 lines of text.  Not all can handle 25.  To hit the majority of
  9577. users, keep screen I/O within a range of 24 lines.
  9578.  
  9579. I hope that this will help, and not seem like a gratuitous flame!
  9580.  
  9581. -Richard
  9582.  
  9583. From mlfarm!ron@hsi.hsi.com  Mon Dec 17 05:48:21 1990
  9584. Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  9585.     id AA29256; Mon, 17 Dec 90 05:48:21 -0700
  9586. Received: by hsi.hsi.com (5.61+++/1.34)
  9587.     id AA29734; Mon, 17 Dec 90 07:46:30 -0500
  9588. Received: by mlfarm.com (smail2.5)
  9589.     id AA09251; 17 Dec 90 06:16:37 EST (Mon)
  9590. To: icon-group@cs.arizona.edu
  9591. In-Reply-To: goer@quads.uchicago.edu's message of  Dec 15 19:21:20 GMT
  9592. Subject: RE: Draw Poker Game
  9593. Message-Id: <9012170616.AA09251@mlfarm.com>
  9594. Date: 17 Dec 90 06:16:37 EST (Mon)
  9595. From: mlfarm!ron@hsi.hsi.com (Ronald Florence)
  9596.  
  9597. I'd like to add a strong second to Richard Goerwitz's comments on code
  9598. portability.  One of the most welcome features of Icon is the
  9599. implementation independence of the code.  With few exceptions, Icon
  9600. code works on a broad range of machines.  How depressing, then, to
  9601. discover valuable utilites and clever games which require hours of
  9602. porting with an editor because of hard-coded screen-control escape
  9603. sequences.  Richard Goerwitz's Icon termcap library, which includes
  9604. ms-dos entries, is one solution.  For those who don't want to use the
  9605. termcap code, screen control sequences can be isolated in global
  9606. strings or functions, so that porting doesn't require line-by-line
  9607. changes of an entire program.
  9608.  
  9609. While I'm griping, I'd urge that program instructions omit
  9610. implementation-dependent exceptions:
  9611.  
  9612.  > # DRAW.ICN          12/15/90          BY TENAGLIA       #
  9613.  > #                                                       #
  9614.  > # SIMPLE BUT FUN DRAW POKER GAME. WORKS ON ANSI SCREEN. #
  9615.  > # USAGE : ICONX DRAW [starting credits]                 #
  9616.  
  9617. If I'm not wrong, the need for `iconx' before the program name is
  9618. confined to ms-dos and VMS.  Users of those systems surely know how to
  9619. run Icon programs on their systems.
  9620.  
  9621. My comments are not in any way intended as a flame of Chris Tenaglia's
  9622. excellent game, which would probably work unchanged on some of the
  9623. terminals here.  With a few changes that would be easy when the code
  9624. is written, though time-consuming later, the game would work right off
  9625. the icon-group mailing list on any terminal and operating system
  9626. running Icon.  
  9627. --
  9628.  
  9629. Ronald Florence            ron@mlfarm.com
  9630.  
  9631.  
  9632.  
  9633. From icon-group-request@arizona.edu  Mon Dec 17 06:49:02 1990
  9634. Resent-From: icon-group-request@arizona.edu
  9635. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9636.     id AA00502; Mon, 17 Dec 90 06:49:02 -0700
  9637. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 17 Dec 90 06:48 MST
  9638. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02160; Mon, 17 Dec 90
  9639.  05:34:50 -0800
  9640. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9641.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9642.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9643. Resent-Date: Mon, 17 Dec 90 06:48 MST
  9644. Date: 17 Dec 90 13:15:23 GMT
  9645. From: eru!hagbard!sunic!sics.se!sics!soder@bloom-beacon.mit.edu
  9646. Subject: Exit codes in SunOS 4.1
  9647. Sender: icon-group-request@arizona.edu
  9648. Resent-To: icon-group@cs.arizona.edu
  9649. To: icon-group@arizona.edu
  9650. Resent-Message-Id: <EB0C5B1AA563408EBB@Arizona.edu>
  9651. Message-Id: <SODER.90Dec17141522@basm.inmic.se>
  9652. Organization: Swedish Institute of Microelectronics, Kista
  9653. X-Envelope-To: icon-group@CS.Arizona.EDU
  9654. X-Vms-To: icon-group@Arizona.edu
  9655.  
  9656. Has anybody else noticed this:
  9657.  
  9658. Problem: Icon programs return spurious (?) exit codes under
  9659. recent versions of SunOS. When terminating normally the exit
  9660. code is an unpredictable small integer, sometimes even
  9661. negative (as reported by /bin/csh).
  9662.  
  9663. The problem didn't appear until I ported some software we
  9664. developed to SunOS 4.0.1 for the Sun 386i. Now the same
  9665. symptom appears when porting the software to a SPARCstation
  9666. 1+ under SunOS 4.1. (The 4.0.1 for the 386i is more similar
  9667. to 4.1 than 4.0.3 for the SPARC.)
  9668.  
  9669. My conclusion from browsing the Icon source is that even a
  9670. 'procedure main (...)' that just flows out through its 'end'
  9671. executes a proper Unix 'exit'. Can anybody confirm that?
  9672. (Under these OSes a C program that just flows out through
  9673. its final brace does not return a predictable return code.)
  9674.  
  9675. Reply to me and I'll post a summary. Thanks.
  9676.  
  9677.     Hakan
  9678. ----------------------------------------------------
  9679. Hakan Soderstrom             Phone: +46 (8) 752 1138
  9680. NMP-CAD                      Fax:   +46 (8) 750 8056
  9681. P.O. Box 1193                E-mail: soder@nmpcad.se
  9682. S-164 22 Kista, Sweden
  9683. --
  9684. ----------------------------------------------------
  9685. Hakan Soderstrom             Phone: +46 (8) 752 1138
  9686. NMP-CAD                      Fax:   +46 (8) 750 8056
  9687. P.O. Box 1193                E-mail: soder@nmpcad.se
  9688. S-164 22 Kista, Sweden
  9689.  
  9690. From goer%sophist@gargoyle.uchicago.edu  Mon Dec 17 08:54:29 1990
  9691. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9692. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9693.     id AA03897; Mon, 17 Dec 90 08:54:29 -0700
  9694. Return-Path: goer@sophist.uchicago.edu
  9695. Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 17 Dec 90 08:53 MST
  9696. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  9697.  (4.0/1.14) id AA08765; Mon, 17 Dec 90 09:53:13 CST
  9698. Received: by sophist (4.1/UofC3.1X) id AA01710; Mon, 17 Dec 90 09:56:15 CST
  9699. Resent-Date: Mon, 17 Dec 90 08:53 MST
  9700. Date: Mon, 17 Dec 90 09:56:15 CST
  9701. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9702. Subject: followup on games
  9703. Resent-To: icon-group@cs.arizona.edu
  9704. To: icon-group@arizona.edu
  9705. Resent-Message-Id: <EAFAD8812CC34091AC@Arizona.edu>
  9706. Message-Id: <9012171556.AA01710@sophist>
  9707. X-Envelope-To: icon-group@CS.Arizona.EDU
  9708. X-Vms-To: icon-group@Arizona.edu
  9709.  
  9710.     I'd like to add a strong second to Richard Goerwitz's comments on code
  9711.     portability.  One of the most welcome features of Icon is the
  9712.     implementation independence of the code.  With few exceptions, Icon
  9713.     code works on a broad range of machines.  How depressing, then, to
  9714.     discover valuable utilites and clever games which require hours of
  9715.     porting with an editor because of hard-coded screen-control escape
  9716.     sequences.  Richard Goerwitz's Icon termcap library, which includes
  9717.     ms-dos entries, is one solution...
  9718.  
  9719. ...albeit a slightly clumsy one for DOS.  For DOS the only advantage to us-
  9720. ing these routines is that they allow you to move your code unaltered over
  9721. to Unix.  And you don't have to know the slightest thing about Unix, other
  9722. than the basic termcap codes (e.g. "so" for boldface, etc.).  Termcap files,
  9723. though, don't know about color, about the difference between bold and re-
  9724. verse video, and can't take advantage of really fancy terminal features.
  9725. It's a mixed bag.
  9726.  
  9727. I'll be glad to send the full DOS/UNIX Icon termlib-type routines in their
  9728. latest incarnation to anyone that asks.  The most recent changes have been
  9729. a full DOS implementation.
  9730.  
  9731. The main point is just to isolate screen control codes in a single proce-
  9732. dure, and to output them via a separate routine.  Anyone who does this is
  9733. going to make porting his or her code to another OS or output device a
  9734. real snap.
  9735.  
  9736.     While I'm griping, I'd urge that program instructions omit
  9737.     implementation-dependent exceptions:
  9738.  
  9739.      > # DRAW.ICN          12/15/90          BY TENAGLIA       #
  9740.      > #                                                       #
  9741.      > # SIMPLE BUT FUN DRAW POKER GAME. WORKS ON ANSI SCREEN. #
  9742.      > # USAGE : ICONX DRAW [starting credits]                 #
  9743.  
  9744.     If I'm not wrong, the need for `iconx' before the program name is
  9745.     confined to ms-dos and VMS.  Users of those systems surely know how to
  9746.     run Icon programs on their systems.
  9747.  
  9748. I've only used Icon under Unix and MS-DOS.  I'm sure that's pretty typical.
  9749. I mean, few have run it under more than one or two operating systems.  I
  9750. gather that Chris is MS-DOS/VMS.  Just so happens that these don't support
  9751. direct execution of Icon programs (as you point out).  (For those who don't
  9752. know, "direct execution" means, in practical terms, that you can just type
  9753. the name of the program, and don't need to type in "iconx").
  9754.  
  9755.     My comments are not in any way intended as a flame of Chris Tenaglia's
  9756.     excellent game, which would probably work unchanged on some of the
  9757.     terminals here.
  9758.  
  9759. Yes, we don't want to discourage Chris from posting!  He's written some very
  9760. interesting stuff.  And he's one of the few VMS users we see posting, so it
  9761. is very nice to have his input (esp. for people like me who hardly know VMS
  9762. from MVS).  Incidentally, the game runs here on my Xenix console.
  9763.  
  9764. -Richard
  9765.  
  9766. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Mon Dec 17 15:15:35 1990
  9767. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  9768.     id AA17643; Mon, 17 Dec 90 15:15:35 -0700
  9769. Received: by uwm.edu; id AA08233; Mon, 17 Dec 90 16:15:03 -0600
  9770. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  9771.           Mon, 17 Dec 90 14:13:51 CDT
  9772. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  9773.           Mon, 17 Dec 1990 13:43 CDT
  9774. Date: Mon, 17 Dec 1990 13:43 CDT
  9775. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  9776. Subject: crt handler library
  9777. To: icon-group@cs.arizona.edu
  9778. Message-Id: <2D9076E640200646@mis.mcw.edu>
  9779. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  9780. X-Envelope-To: icon-group@cs.arizona.edu
  9781. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  9782.  
  9783.  
  9784. Well, appararently raw ansi escape sequences in write() statements are not
  9785. as commonplace as I thought. I put together a video manipulator library
  9786. collection. Since I only have VT terminals and ansi to work with, I coded
  9787. in only those cases. Someone else will have to fill in the rest. These
  9788. procedures generate escape sequence strings for write() commands. In places
  9789. where this doesn't apply, one would have them return "", and generate the
  9790. desired side effect. For example,...
  9791.  
  9792. write(crt_dark(),crt_clear(),crt_upper_half(),crt_mode("high","inverse"),
  9793.       center("Header",39),crt_mode("normal"))
  9794. write(crt_lower_half(),crt_mode("high","inverse"),center("Header",39),
  9795.       crt_mode("normal"))
  9796.  
  9797. Would output the header to some screen in double sized characters centered
  9798. at the top of the screen in bright, inverse video. This scenario requires
  9799. a global variable called TERM that defines the terminal used. On unix
  9800. systems a getenv() could probably generate sufficient clues to have this
  9801. determined at run time.
  9802.  
  9803. Granted, my draw poker game was a quick and dirty implementation. On VMS
  9804. screen painting is so slow with ICON that I didn't want to further slow the
  9805. application by adding layers of object oriented display managers.
  9806.  
  9807. Thanx for the suggestions! Below are 162 lines of code, in 22 or so procedures.
  9808. Have fun!
  9809.  
  9810. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  9811. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  9812. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  9813.  
  9814. #
  9815. # CRT.ICN          CREATED 12/17/90          BY TENAGLIA
  9816. #
  9817. # THIS IS A SCREEN FUNCTION LIBRARY. I AM SUBMITTING PARTS PERTAINING TO
  9818. # VT,ANSI EMULATION. OTHERS, PLEASE FEEL FREE TO ADD YOURS. UNDER VT
  9819. # TERMINAL EMULATION SPECIAL STRINGS BEGINNING WITH ESCAPE X'1B' START
  9820. # SEQUENCES THAT DO USEFUL THINGS TO DISPLAYS. THE VT FUNCTIONS RETURN
  9821. # THE ESCAPE SEQUENCES. OTHER VIDEO METHODS MAY PERFORM INTERRUPTS, PORT
  9822. # OR I/O RETURNING "" TO ACCOMPLISH THE SAME THING.
  9823. #
  9824. global TERM          #  DEFINE A GLOBAL VARIABLE CALLED TERM
  9825. procedure main()     #  IT DECLARES THE TERMINAL TYPE. "VT" IS
  9826.   TERM := "VT"       #  FOR DEC VT100,2XX,3XX,4XX SERIES.
  9827.   end                #  OTHERS MAY BE "X", "4014", "TTY", ETC,...
  9828.  
  9829. procedure crt_error()
  9830.   stop("TERM as (",TERM,") not properly defined.")
  9831.   end
  9832.  
  9833. procedure crt_clear()
  9834.   case TERM of {
  9835.     "VT"    : return "\e[2J\e[H"  # CLEAR SCREEN AND HOME
  9836.     default : crt_error() }
  9837.   end
  9838.  
  9839. procedure crt_home()
  9840.   case TERM of {
  9841.     "VT"    : return "\e[H"       # MOVE CURSOR TO TOP OF SCREEN LEFT SIDE
  9842.     default : crt_error() }
  9843.   end
  9844.  
  9845. procedure crt_goto(x,y)   # SET CURSOR TO X(COLUMN) Y(ROW) SCREEN POSITION
  9846.   case TERM of {
  9847.     "VT"    : return "\e[" || y || ";" || x || "f"
  9848.     default : crt_error() }
  9849.   end
  9850.  
  9851. procedure crt_upper_half()      #
  9852.   case TERM of {                # TOP HALF OF DOUBLE WIDTH, DOUBLE HEIGHT CHARS
  9853.     "VT"    : return "\e#3"     #
  9854.     default : crt_error() }
  9855.   end
  9856.  
  9857. procedure crt_lower_half()      #
  9858.   case TERM of {                # BOTTOM HALF OF DOUBLE WIDTH, DOUBLE HEIGHT
  9859.     "VT"    : return "\e#4"     #
  9860.     default : crt_error() }
  9861.   end
  9862.  
  9863. procedure crt_mode(p1,p2,p3,p4,p5)            #
  9864.   /p5 := "n/a"                                # THIS ROUTINE SETS THE OUTPUT
  9865.   /p4 := "n/a"                                # ATTRIBUTES FOR CHARACTERS.
  9866.   /p3 := "n/a"                                # SOME ENVIRONMENTS MAY USE
  9867.   /p2 := "n/a"                                # COLORS.
  9868.   /p1 := "n/a"                                #
  9869.   all := [p1,p2,p3,p4,p5]                     #
  9870.   case TERM of {                              #
  9871.     "VT"    : {                               #
  9872.               seq := "\e["                    #
  9873.               every mode := !all do           # THESE CAN BE COMBINED MUCH
  9874.                 case mode of                  # LIKE SETTING BITS.
  9875.                   {                           #
  9876.                   "normal   : seq ||:= "0;"   # NORMAL VIDEO
  9877.                   "high"    : seq ||:= "1;"   # HIGH INTENSITY
  9878.                   "dim"     : seq ||:= "2;"   # LOW INTENSITY
  9879.                   "under"   : seq ||:= "4;"   # UNDERSCORED
  9880.                   "blink"   : seq ||:= "5;"   # BLINKING
  9881.                   "inverse" : seq ||:= "7;"   # INVERSE VIDEO
  9882.                   "conceal" : seq ||:= "8;"   # INVISIBLE
  9883.                   default   : &null           # IGNORE OTHERS
  9884.                   }                           #
  9885.               seq[-1] := "m"                  #
  9886.               return seq                      #
  9887.               }                               #
  9888.     default : crt_error() }
  9889.   end
  9890.  
  9891. procedure crt_graphic()        #
  9892.   case TERM of {               # TURN ON ANSI LINE GRAPHICS CHARACTERS
  9893.     "VT"    : return "\e(0"    #
  9894.     default : crt_error() }
  9895.   end
  9896.  
  9897. procedure crt_nographic()      #
  9898.   case TERM of {               # TURN OFF ANSI LINE GRAPHICS CHARACTERS
  9899.     "VT"    : return "\e(B"    #
  9900.     default : crt_error() }
  9901.   end
  9902.  
  9903. procedure crt_smooth()         #
  9904.   case TERM of {               # PUTS CRT IN SMOOTH SCROLLING MODE
  9905.     "VT"    : return "\e[?4h"  #
  9906.     default : crt_error() }
  9907.   end
  9908.  
  9909. procedure crt_jump()           #
  9910.   case TERM of {               # PUTS CRT IN JUMP SCROLLING MODE
  9911.     "VT"    : return "\e[?4l"  #
  9912.     default : crt_error() }
  9913.   end
  9914.  
  9915. procedure crt_scroll(t,b)                              #
  9916.   /b := ""                                             # SET UP SCROLLING
  9917.   /t := ""                                             # REGIONS ON THE SCREEN
  9918.   case TERM of {                                       # T IS THE TOP MARGIN
  9919.     "VT"    : {                                        # B IS THE BOTTOM MARGIN
  9920.               if (t=="") & (b=="") then return "\e[r"  # OMIT B, THEN BOTTOM OF
  9921.               if b=="" then return "\e[" || t || "r"   # SCREEN IS BOTTOM MARGIN
  9922.               return "\e[" || t || ";" || b || "r"     # OMIT B & T TO RESET TO
  9923.               }                                        # NORMAL FULL SCREEN
  9924.     default : crt_error() }
  9925.   end
  9926.  
  9927. procedure crt_erase_eol()      #
  9928.   case TERM of {               #  ERASE CHARACTERS FROM CURSOR TO
  9929.     "VT"    : return "\e[K"    #  END OF LINE
  9930.     default : crt_error() }
  9931.   end
  9932.  
  9933. procedure crt_erase_sol()      #
  9934.   case TERM of {               #  ERASE CHARACTERS FROM CURSOR TO
  9935.     "VT"    : return "\e[1K"   #  START OF LINE
  9936.     default : crt_error() }
  9937.   end
  9938.  
  9939. procedure crt_erase_eos()      #
  9940.   case TERM of {               #  ERASE CHARACTERS FROM CURSOR TO
  9941.     "VT"    : return "\e[J"    #  END OF SCREEN
  9942.     default : crt_error() }
  9943.   end
  9944.  
  9945. procedure crt_erase_tos()      #
  9946.   case TERM of {               #  ERASE CHARACTERS FROM CURSOR TO
  9947.     "VT"    : return "\e[1J"   #  TOP OF SCREEN
  9948.     default : crt_error() }
  9949.   end
  9950.  
  9951. procedure crt_light()          #
  9952.   case TERM of {               #  MAKE SCREEN LIGHT BACKGROUND
  9953.     "VT"    : return "\e[?5h"  #
  9954.     default : crt_error() }
  9955.   end
  9956.  
  9957. procedure crt_dark()           #
  9958.   case TERM of {               #  MAKE SCREEN DARK BACKGROUND
  9959.     "VT"    : return "\e[?5l"  #
  9960.     default : crt_error() }
  9961.   end
  9962.  
  9963. procedure crt_132()            #
  9964.   case TERM of {               #  MAKE SCREEN 132 COLUMNS WIDE
  9965.     "VT"    : return "\e[?3h"  #
  9966.     default : crt_error() }
  9967.   end
  9968.  
  9969. procedure crt_80()             #
  9970.   case TERM of {               #  MAKE SCREEN 80 COLUMNS WIDE
  9971.     "VT"    : return "\e[?3l"  #
  9972.     default : crt_error() }
  9973.   end
  9974.  
  9975.  
  9976.  
  9977. From goer%sophist@gargoyle.uchicago.edu  Mon Dec 17 18:26:02 1990
  9978. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9979. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9980.     id AA23453; Mon, 17 Dec 90 18:26:02 -0700
  9981. Return-Path: goer@sophist.uchicago.edu
  9982. Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 17 Dec 90 18:25 MST
  9983. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  9984.  (4.0/1.14) id AA23714; Mon, 17 Dec 90 19:25:05 CST
  9985. Received: by sophist (4.1/UofC3.1X) id AA02016; Mon, 17 Dec 90 19:28:06 CST
  9986. Resent-Date: Mon, 17 Dec 90 18:25 MST
  9987. Date: Mon, 17 Dec 90 19:28:06 CST
  9988. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9989. Subject: crt_dark()
  9990. Resent-To: icon-group@cs.arizona.edu
  9991. To: icon-group@arizona.edu
  9992. Resent-Message-Id: <EAAB06C827A3409438@Arizona.edu>
  9993. Message-Id: <9012180128.AA02016@sophist>
  9994. X-Envelope-To: icon-group@CS.Arizona.EDU
  9995. X-Vms-To: icon-group@Arizona.edu
  9996.  
  9997.     write(crt_lower_half(),crt_mode("high","inverse"),center("Header",39),
  9998.           crt_mode("normal"))
  9999.  
  10000.  
  10001. This approach is good.  The better you hide terminal characteristics
  10002. behind a high-level interface, the easier it will be to port your
  10003. software.
  10004.  
  10005.     write(crt_dark(),crt_clear(),crt_upper_half()...
  10006.  
  10007. One suggestion:  Make crt_dark() and crt_clear() and crt_mode() into
  10008. a single routine.  That way I don't have to go try to modify all the
  10009. different procedures.  You could, of course, just do this:
  10010.  
  10011.     procedure output(s)
  10012.  
  10013.         case s of {
  10014.             "clear" : crt_clear()
  10015.             "dark"  : crt_dark()
  10016.             "normal": etc....
  10017.  
  10018. This would make porting a snap, and I wouldn't even have to modify the
  10019. crt_clear routine.  To port your software to Unix, all I'd have to do
  10020. is insert my own screen clearing routine in place of crt_clear().
  10021.  
  10022. Just some thoughts.
  10023.  
  10024. -Richard
  10025.  
  10026. From goer%sophist@gargoyle.uchicago.edu  Mon Dec 17 22:30:04 1990
  10027. Resent-From: goer%sophist@gargoyle.uchicago.edu
  10028. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10029.     id AA00811; Mon, 17 Dec 90 22:30:04 -0700
  10030. Return-Path: goer@sophist.uchicago.edu
  10031. Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 17 Dec 90 22:29 MST
  10032. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  10033.  (4.0/1.14) id AA00435; Mon, 17 Dec 90 23:29:17 CST
  10034. Received: by sophist (4.1/UofC3.1X) id AA02212; Mon, 17 Dec 90 23:32:18 CST
  10035. Resent-Date: Mon, 17 Dec 90 22:29 MST
  10036. Date: Mon, 17 Dec 90 23:32:18 CST
  10037. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  10038. Subject: termcap md/me
  10039. Resent-To: icon-group@cs.arizona.edu
  10040. To: icon-group@arizona.edu
  10041. Resent-Message-Id: <EA88E452B6D3406404@Arizona.edu>
  10042. Message-Id: <9012180532.AA02212@sophist>
  10043. X-Envelope-To: icon-group@CS.Arizona.EDU
  10044. X-Vms-To: icon-group@Arizona.edu
  10045.  
  10046. Hmmm.  It's true that md and me are present in my termcap entries,
  10047. but this isn't discussed in my man pages (Xenix).  I note that the
  10048. SunOS man pages for sophist here do discuss md/me.  I'm no expert
  10049. on termcap's history.
  10050.  
  10051. -Richard
  10052.  
  10053. From mlfarm!ron@hsi.hsi.com  Tue Dec 18 07:17:16 1990
  10054. Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  10055.     id AA14911; Tue, 18 Dec 90 07:17:16 -0700
  10056. Received: by hsi.hsi.com (5.61+++/1.34)
  10057.     id AA18203; Tue, 18 Dec 90 09:15:33 -0500
  10058. Received: by mlfarm.com (smail2.5)
  10059.     id AA11465; 18 Dec 90 08:26:01 EST (Tue)
  10060. To: icon-group@cs.arizona.edu
  10061. In-Reply-To: Chris Tenaglia - 257-8765's message of Mon Dec 17 13:43 CDT
  10062. Subject: crt handler library
  10063. Message-Id: <9012180826.AA11465@mlfarm.com>
  10064. Date: 18 Dec 90 08:26:01 EST (Tue)
  10065. From: mlfarm!ron@hsi.hsi.com (Ronald Florence)
  10066.  
  10067. Chris Tenaglia - 257-8765 writes:
  10068.  
  10069.  > Well, appararently raw ansi escape sequences in write() statements are not
  10070.  > as commonplace as I thought. I put together a video manipulator library
  10071.  > collection. Since I only have VT terminals and ansi to work with, I coded
  10072.  > in only those cases. Someone else will have to fill in the rest. 
  10073.  > [...]  This scenario requires
  10074.  > a global variable called TERM that defines the terminal used. On unix
  10075.  > systems a getenv() could probably generate sufficient clues to have this
  10076.  > determined at run time.
  10077.  
  10078. Bravo to Chris for a quick and generous response to comments.  His
  10079. solution is a great improvement to the chaos of screen-writing code.
  10080. Still, a problem remains ...  
  10081.  
  10082. Ms-dos and VMS implementations, like Chris', are written for systems
  10083. which assume that screen displays are on a limited variety of
  10084. terminals.  Adding another terminal requires hand-coding another
  10085. option in each case statement.  Most Unix systems automatically
  10086. determine the user's terminal-type at login, then use a database of
  10087. terminal characteristics (termcap or terminfo) to look up the screen
  10088. display sequences.  For example, our small system here has ansi
  10089. 25-line terminals, ansi 43-line terminals, a Wyse 150 emulating a
  10090. Wyse50+, a Wyse 99gt emulating a vt220, various vt100 emulations,
  10091. laptops emulating whatever their software can do, and occasional
  10092. logins from odd places with odd terminals.  Users expect all of these
  10093. terminals to function with full-screen displays _automatically_.
  10094.  
  10095. I'd like to see us arrive at a convention or library of display
  10096. functions to simplify the porting of Icon code with full-screen
  10097. displays.  Perhaps the way to do it would be to include a lookup of
  10098. &features in an initialization function, which would then toggle
  10099. between a termcap library (for Unix systems), hard-coded ansi
  10100. display strings (for ms-dos systems), and a case statement with a
  10101. few options (for VMS systems).  If we could develop such a library,
  10102. porting a game like Chris' to Unix or ms-dos would require only the
  10103. linking of an appropriate library during the make.
  10104.  
  10105. Am I crazy or fascist to propose this?  
  10106. --
  10107.  
  10108. Ronald Florence            ron@mlfarm.com
  10109.  
  10110.  
  10111.  
  10112. From nowlin@iwtqg.att.com  Tue Dec 18 09:31:54 1990
  10113. Message-Id: <9012181631.AA21106@megaron.cs.arizona.edu>
  10114. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  10115.     id AA21106; Tue, 18 Dec 90 09:31:54 -0700
  10116. From: nowlin@iwtqg.att.com
  10117. Date: Tue, 18 Dec 90 09:34 CST
  10118. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  10119. To: icon-group@cs.arizona.edu
  10120. Subject: Re: crt handler library
  10121.  
  10122. > ...  Perhaps the way to do it would be to include a lookup of
  10123. > &features in an initialization function, which would then toggle
  10124. > between a termcap library (for Unix systems), hard-coded ansi
  10125. > display strings (for ms-dos systems), and a case statement with a
  10126. > few options (for VMS systems).  If we could develop such a library,
  10127. > porting a game like Chris' to Unix or ms-dos would require only the
  10128. > linking of an appropriate library during the make.
  10129. > Am I crazy or fascist to propose this?  
  10130. > --
  10131. > Ronald Florence            ron@mlfarm.com
  10132.  
  10133. I frequently use the UNIX tput command with read pipes in Icon to define
  10134. a series of terminal specific escape sequences before having a program do
  10135. fancy stuff with screen output.
  10136.  
  10137. If the list of screen attributes is relatively short this is a good
  10138. way to populate a few global values at the start of UNIX programs.  If
  10139. there is some equivalent VMS command then UNIX and VMS could be handled
  10140. easily.  The PC is pretty standard and set definitions for PC screen
  10141. attributes would make more sense.  This would make implementing the above
  10142. scheme relatively simple.
  10143.  
  10144. Here's a small example of what I'm talking about:
  10145.  
  10146. global    CLEAR, ON, OFF
  10147.  
  10148. procedure main()
  10149.     term_attr_set()
  10150.  
  10151.     write(CLEAR)
  10152.     write("\n\n\t",ON,"Happy",OFF," ~ ",ON,"Holidays",OFF,"\n\n")
  10153. end
  10154.  
  10155. procedure term_attr_set()
  10156.     CLEAR := \do_tput("clear")
  10157.     ON    := \do_tput("smso")
  10158.     ON  ||:= \do_tput("blink")
  10159.     OFF   := \do_tput("sgr0")
  10160. end
  10161.  
  10162. procedure do_tput(attr)
  10163.     local    cmd, in, ret
  10164.  
  10165.     cmd := "tput " || attr
  10166.     in  := open(cmd,"rp")
  10167.     ret := read(in)
  10168.     close(in)
  10169.  
  10170.     return ret
  10171. end
  10172.  
  10173. Jerry Nowlin
  10174. (...!att!iwtqg!nowlin)
  10175.  
  10176. From callas@eris.enet.dec.com  Tue Dec 18 09:36:24 1990
  10177. Received: from decpa.pa.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  10178.     id AA21263; Tue, 18 Dec 90 09:36:24 -0700
  10179. Received: by decpa.pa.dec.com; id AA27630; Tue, 18 Dec 90 08:17:35 -0800
  10180. Message-Id: <9012181617.AA27630@decpa.pa.dec.com>
  10181. Received: from eris.enet; by decwrl.enet; Tue, 18 Dec 90 08:17:37 PST
  10182. Date: Tue, 18 Dec 90 08:17:37 PST
  10183. From: This message sent with 100% recycled bits  18-Dec-1990 1103 <callas@eris.enet.dec.com>
  10184. To: icon-group@cs.arizona.edu
  10185. Subject: CRT handling
  10186.  
  10187. Actually, on VMS systems, there is a termcap-like library of terminals, and
  10188. it's easily extensible. Also, the C run-time library contains an implementation
  10189. of curses. No doubt there's a way to code an application so that it'll not
  10190. port between some unix and VMS, but I've tossed programs around with little
  10191. trouble.
  10192.  
  10193.     Jon Callas
  10194.  
  10195. From goer%sophist@gargoyle.uchicago.edu  Tue Dec 18 13:43:48 1990
  10196. Resent-From: goer%sophist@gargoyle.uchicago.edu
  10197. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10198.     id AA29612; Tue, 18 Dec 90 13:43:48 -0700
  10199. Return-Path: goer@sophist.uchicago.edu
  10200. Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 18 Dec 90 13:42 MST
  10201. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu)
  10202.  (4.0/1.14) id AA16957; Tue, 18 Dec 90 14:42:45 CST
  10203. Received: by sophist (4.1/UofC3.1X) id AA02520; Tue, 18 Dec 90 14:45:45 CST
  10204. Resent-Date: Tue, 18 Dec 90 13:43 MST
  10205. Date: Tue, 18 Dec 90 14:45:45 CST
  10206. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  10207. Subject: RE: crt library
  10208. Resent-To: icon-group@cs.arizona.edu
  10209. To: icon-group@arizona.edu
  10210. Resent-Message-Id: <EA09488C6D6340AA35@Arizona.edu>
  10211. Message-Id: <9012182045.AA02520@sophist>
  10212. X-Envelope-To: icon-group@CS.Arizona.EDU
  10213. X-Vms-To: icon-group@Arizona.edu
  10214.  
  10215. Jerry Nowlin writes:
  10216.  
  10217.     global    CLEAR, ON, OFF
  10218.  
  10219.     procedure main()
  10220.         term_attr_set()
  10221.  
  10222.         write(CLEAR)
  10223.         write("\n\n\t",ON,"Happy",OFF," ~ ",ON,"Holidays",OFF,"\n\n")
  10224.     end
  10225.  
  10226.     procedure term_attr_set()
  10227.         CLEAR := \do_tput("clear")
  10228.         ON    := \do_tput("smso")
  10229.         ON  ||:= \do_tput("blink")
  10230.         OFF   := \do_tput("sgr0")
  10231.     end
  10232.  
  10233.     etc...
  10234.  
  10235. This is a very good solution.  All we have to do in order to port the
  10236. software to a new OS is to change this one procedure, term_attr_set().
  10237.  
  10238. Is it time for a repost of my itlib routines, with the DOS port,
  10239. UNIX getch(), getche(), kbhit() hacks, and various support rou-
  10240. tines (e.g. clear(), underline(), and other procedures meant to work
  10241. even on magic cookie terminals)?  The post would not be small.  It
  10242. would probably need to be sent out as a five-part shar, with a pro-
  10243. mise to mail individual copies to people who can't unpack shell ar-
  10244. chives.  Should I post to alt.sources?  Post at all?
  10245.  
  10246. I expect that an energetic VMS user could easily code up a set of
  10247. equivalent routines for that OS.  The basic routines a) read the
  10248. termcap database file, 2) check to see what terminal type the user
  10249. is using, and then 3) make the codes in the terminal database
  10250. available to the user via calls to a procedure called getval().
  10251. Output of codes is done through a separate iputs() command, which
  10252. takes care of time delays and padding.  In most cases, one could
  10253. just use writse() instead of iputs, since only the most ornery of
  10254. terminals still need silly things like padding.
  10255.  
  10256. The only difficulty I envision (and it is hardly a difficulty) is
  10257. to work things so that by calling getval() with a Unix capname,
  10258. such as "so" (i.e. getval("so")), the VMS port would a) be able to
  10259. recognize what "so" means, and b) be able to access its VMS equi-
  10260. valent.
  10261.  
  10262. I'll make an offer:  If someone will make up a set of VMS routines
  10263. that can look up a user's terminal type at run-time, and then ac-
  10264. cess the database for that terminal by a single routine (e.g.
  10265. lookup("clear")), I'll put a wrapper around the procedure that
  10266. will be compatible with my Unix/DOS termlib-like routines.
  10267.  
  10268. Naturally, it would help if someone doing this had half an eye on
  10269. the Unix/DOS termlib-like routines, so that the structure of the
  10270. system is analogous to what's already been done by me.
  10271.  
  10272. -Richard (goer@sophist.uchicago.edu)
  10273.  
  10274. From @po10.andrew.cmu.edu:mss+@andrew.cmu.edu  Wed Dec 19 14:28:49 1990
  10275. Received: from po10.andrew.cmu.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10276.     id AA02468; Wed, 19 Dec 90 14:28:49 -0700
  10277. Received: by po10.andrew.cmu.edu (5.54/3.15) id <AA04272> for icon-group@cs.arizona.edu; Wed, 19 Dec 90 16:28:07 EST
  10278. Received: via switchmail; Wed, 19 Dec 90 16:28:01 -0500 (EST)
  10279. Received: from po10.andrew.cmu.edu via qmail
  10280.           ID </afs/andrew.cmu.edu/service/mailqs/sq2/QF.AbOdgAC00UdiE2jUJC>;
  10281.           Sat, 15 Dec 90 16:52:17 -0500 (EST)
  10282. Received: from mss.andrew.cmu.edu via qmail
  10283.           ID </afs/andrew.cmu.edu/service/mailqs/q002/QF.wbOdefW00VsAE0K4MC>;
  10284.           Sat, 15 Dec 90 16:50:37 -0500 (EST)
  10285. Received: from mss.andrew.cmu.edu via qmail
  10286.           ID </afs/andrew.cmu.edu/usr18/mss/.Outgoing/QF.obOddXi00VsA8AfWNp>;
  10287.           Sat, 15 Dec 1990 16:49:24 -0500 (EST)
  10288. Received: from Messages.7.14.N.CUILIB.3.45.SNAP.NOT.LINKED.mss.andrew.cmu.edu.rt.r3
  10289.           via MS.5.6.mss.andrew.cmu.edu.rt_r3;
  10290.           Sat, 15 Dec 1990 16:49:23 -0500 (EST)
  10291. Message-Id: <0bOddXa00VsAMAfWFb@andrew.cmu.edu>
  10292. Date: Sat, 15 Dec 1990 16:49:23 -0500 (EST)
  10293. From: Mark Sherman <mss+@andrew.cmu.edu>
  10294. To: icon-group@cs.arizona.edu
  10295. Subject: Mac graphics from Icon
  10296.  
  10297. I'm probably displaying some ignorance, but...
  10298.  
  10299. Does anyone know of a way to get native Macintosh graphics from within
  10300. Icon on the Macintosh? In reading the TR on personalized interpreters, I
  10301. am led to believe that the facility is only available on Unix machines,
  10302. so trying to build my own Mac system may not be an answer.
  10303.  
  10304.         -Mark
  10305.  
  10306. From ralph  Wed Dec 19 14:40:50 1990
  10307. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10308.     id AA02880; Wed, 19 Dec 90 14:40:50 -0700
  10309. Date: Wed, 19 Dec 90 14:40:49 MST
  10310. From: "Ralph Griswold" <ralph>
  10311. Message-Id: <9012192140.AA04124@cheltenham.cs.arizona.edu>
  10312. Received: by cheltenham.cs.arizona.edu; Wed, 19 Dec 90 14:40:49 MST
  10313. To: mss+@andrew.cmu.edu
  10314. Subject: Re:  Mac graphics from Icon
  10315. Cc: icon-group
  10316.  
  10317. Personalized interpreters are available only under UNIX Icon. They
  10318. just make it possible to add functionality without having to have
  10319. or recompile the entire source.
  10320.  
  10321. You can add functionality to any version of Icon, given the source
  10322. code and enough knowledge of Icon internals.
  10323.  
  10324. I won't attempt to characterize the difficulty of accessing the
  10325. Macintosh Toolbox in any general way, however.
  10326.  
  10327.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  10328.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  10329.  
  10330. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Thu Dec 20 13:02:52 1990
  10331. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10332.     id AA11489; Thu, 20 Dec 90 13:02:52 -0700
  10333. Received: by uwm.edu; id AA12489; Thu, 20 Dec 90 14:02:17 -0600
  10334. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  10335.           Thu, 20 Dec 90 13:41:03 CDT
  10336. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  10337.           Thu, 20 Dec 1990 08:30 CDT
  10338. Date: Thu, 20 Dec 1990 08:30 CDT
  10339. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  10340. Subject: Code Dichotomy
  10341. To: icon-group@cs.arizona.edu
  10342. Message-Id: <5D628D4580200921@mis.mcw.edu>
  10343. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  10344. X-Envelope-To: icon-group@cs.arizona.edu
  10345. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  10346.  
  10347.  
  10348. Why is it, The prettier (and more consistent) the user interface, The
  10349. uglier the code? Or maybe this is the mark of true software craftsman,
  10350. to couple elegant looking (and readible) code with elegant looking and
  10351. consistent functionality. Any comments?
  10352.  
  10353. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  10354. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  10355. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  10356.  
  10357.  
  10358. From djbailey@skyler.mavd.honeywell.com  Thu Dec 20 14:55:06 1990
  10359. Message-Id: <9012202155.AA15557@megaron.cs.arizona.edu>
  10360. Received: from skyler.mavd.honeywell.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  10361.     id AA15557; Thu, 20 Dec 90 14:55:06 -0700
  10362. Date: 20 Dec 90 15:52:00 CDT
  10363. From: "BAILEY, DON" <djbailey@skyler.mavd.honeywell.com>
  10364. Subject: Re: Code Dichotomy
  10365. To: "icon-group" <icon-group@cs.arizona.edu>
  10366.  
  10367.  
  10368. >Why is it, The prettier (and more consistent) the user interface, The
  10369. >uglier the code? Or maybe this is the mark of true software craftsman,
  10370. >to couple elegant looking (and readible) code with elegant looking and
  10371. >consistent functionality. Any comments?
  10372.  
  10373.  
  10374. I have a theory that there is a specific amount of mental effort
  10375. associated with solving a problem.  You can move the effort 
  10376. around but you can't get rid of it.  Computer programs that are driven
  10377. by the real world always seem to have some "naughty bits" that just
  10378. aren't very nice.  If you do solve a real world problem without any
  10379. "naughty bits" you have done well.  (Of course, your solution is 
  10380. resting on someone else's naughty bits in the language processor
  10381. or operating system.)
  10382.  
  10383.  
  10384.  
  10385.  
  10386.  
  10387. From icon-group-request@arizona.edu  Thu Dec 20 23:54:59 1990
  10388. Resent-From: icon-group-request@arizona.edu
  10389. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10390.     id AA28309; Thu, 20 Dec 90 23:54:59 -0700
  10391. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 20 Dec 90 23:54 MST
  10392. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA21082; Thu, 20 Dec 90
  10393.  22:46:28 -0800
  10394. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  10395.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  10396.  usenet@ucbvax.Berkeley.EDU if you have questions)
  10397. Resent-Date: Thu, 20 Dec 90 23:54 MST
  10398. Date: 21 Dec 90 06:13:05 GMT
  10399. From: midway!ellis.uchicago.edu!goer@handies.ucar.edu
  10400. Subject: itlib on alt.sources
  10401. Sender: icon-group-request@arizona.edu
  10402. Resent-To: icon-group@cs.arizona.edu
  10403. To: icon-group@arizona.edu
  10404. Resent-Message-Id: <E82185301DA340C53F@Arizona.edu>
  10405. Message-Id: <1990Dec21.061305.25347@midway.uchicago.edu>
  10406. Organization: University of Chicago
  10407. X-Envelope-To: icon-group@CS.Arizona.EDU
  10408. X-Vms-To: icon-group@Arizona.edu
  10409.  
  10410. Rather than mail out individual copies of my Icon termlib-like
  10411. routines, I decided to post them to alt.sources.  People who don't
  10412. get alt.sources, write me.  I will send out individual copies to
  10413. those who request them.  I've burdened this non-source group with
  10414. a lot of source code already, and I believe it will be much bet-
  10415. ter to put this rather largish posting in a more appropriate place.
  10416.  
  10417. This is a repost, but I believe it is justified by the improvements
  10418. I've made, and also by the simple fact that I was asked to post them
  10419. again.
  10420.  
  10421. -Richard (goer@sophist.uchicago.edu)
  10422.  
  10423. From reid@ctc.contel.com  Fri Dec 21 06:51:16 1990
  10424. Received: from ctc.contel.com (turing.ctc.contel.com) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10425.     id AA09522; Fri, 21 Dec 90 06:51:16 -0700
  10426. Received: from absurd.ctc.contel.com by ctc.contel.com (4.0/SMI-4.0)
  10427.     id AA11474; Fri, 21 Dec 90 08:50:45 EST
  10428. Date: Fri, 21 Dec 90 08:50:45 EST
  10429. From: reid@ctc.contel.com (Tom Reid  x4505)
  10430. Message-Id: <9012211350.AA11474@ctc.contel.com>
  10431. To: djbailey@skyler.mavd.honeywell.com, icon-group@cs.arizona.edu
  10432. Subject: Re: Code Dichotomy
  10433. Cc: reid@ctc.contel.com, sel@ctc.contel.com
  10434.  
  10435. = >Why is it, The prettier (and more consistent) the user interface, The
  10436. = >uglier the code? Or maybe this is the mark of true software craftsman,
  10437. = >to couple elegant looking (and readible) code with elegant looking and
  10438. = >consistent functionality. Any comments?
  10439. = I have a theory that there is a specific amount of mental effort
  10440. = associated with solving a problem.  You can move the effort 
  10441. = around but you can't get rid of it.  Computer programs that are driven
  10442. = by the real world always seem to have some "naughty bits" that just
  10443. = aren't very nice.  If you do solve a real world problem without any
  10444. = "naughty bits" you have done well.  (Of course, your solution is 
  10445. = resting on someone else's naughty bits in the language processor
  10446. = or operating system.)
  10447. Ugly or voluminous code is an indication that the abstractions supported
  10448. by the language do not support (well) those of the problem domain.  
  10449. Traditional languages supported "algorithmic" programming well.  ICON 
  10450. has excellent list processing and stream processing abstractions.  There
  10451. are few (any?) languages that have graphics or user interface abstractions.  
  10452. Still evolving libraries (Interviews, X, OpenLook, Motif) are the 
  10453. state-of-the-art.  Visual languages are still in their infancy.
  10454.  
  10455. Of course, the limits of how well a basically one-dimensional technology 
  10456. (traditional text languages) can describe two and three dimensional
  10457. problem domains is another question.
  10458.  
  10459. From nowlin@iwtqg.att.com  Fri Dec 21 07:22:01 1990
  10460. Message-Id: <9012211422.AA10123@megaron.cs.arizona.edu>
  10461. Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  10462.     id AA10123; Fri, 21 Dec 90 07:22:01 -0700
  10463. From: nowlin@iwtqg.att.com
  10464. Date: Fri, 21 Dec 90 07:36 CST
  10465. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  10466. To: icon-group@cs.arizona.edu
  10467. Subject: Re: Code Dichotomy
  10468.  
  10469. > >Why is it, The prettier (and more consistent) the user interface, The
  10470. > >uglier the code? Or maybe this is the mark of true software craftsman,
  10471. > >to couple elegant looking (and readible) code with elegant looking and
  10472. > >consistent functionality. Any comments?
  10473. > I have a theory that there is a specific amount of mental effort
  10474. > associated with solving a problem.  You can move the effort 
  10475. > around but you can't get rid of it.  Computer programs that are driven
  10476. > by the real world always seem to have some "naughty bits" that just
  10477. > aren't very nice.  If you do solve a real world problem without any
  10478. > "naughty bits" you have done well.  (Of course, your solution is 
  10479. > resting on someone else's naughty bits in the language processor
  10480. > or operating system.)
  10481.  
  10482. When there's a finite amount of mental effort available (I'd extend this to
  10483. a finite amount of available time and other computing resources when
  10484. working in the real world) you have to balance that time between making it
  10485. easy for the people that use your code, making it easy for the people that
  10486. maintain your code, and making it easy on yourself as the programmer.  The
  10487. usual balance seems to be making it easy on the user and the programmer and
  10488. the maintainer gets the short end of the stick.  That explains the ugly
  10489. code.  A reason for this balance is that too many programmers think their
  10490. code is good and why would they or someone else ever want to change it.
  10491. These are usually (no slur intended) non-real world types who don't have
  10492. managers or users to pick at all their nits or market pressure to
  10493. constantly improve their products.
  10494.  
  10495. The balance should be to make it easy for the user first.  If they don't
  10496. buy/use your software who cares how elegant it is or how easy it is to
  10497. maintain.  The second priority should be maintainability.  Maintainability
  10498. doesn't just mean fixing bugs is easy.  It also means modifying your code
  10499. to add functionality is easy.  If your software is good someone will one-up
  10500. you and you'd better be able to leap frog them fast when they do.  Finally,
  10501. the ease of development/implementation should be considered but never at
  10502. the expense of the first two priorities.  You should be in this for the
  10503. long haul.  One shot programs are for personal use.  To treat distributed
  10504. software that way is naive.
  10505.  
  10506. Another thing that hurts software is lack of testing.  Software is like
  10507. wine with testing being analogous to aging.  It should never be released
  10508. before its time.  Too much software currently out there is the equivalent
  10509. of Ripple or Boones Farm.
  10510.  
  10511. Jerry Nowlin (...!att!iwtqg!nowlin)
  10512.  
  10513. From icon-group-request@arizona.edu  Fri Dec 21 12:13:47 1990
  10514. Resent-From: icon-group-request@arizona.edu
  10515. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10516.     id AA20751; Fri, 21 Dec 90 12:13:47 -0700
  10517. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 21 Dec 90 12:13 MST
  10518. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA04971; Fri, 21 Dec 90
  10519.  10:54:45 -0800
  10520. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  10521.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  10522.  usenet@ucbvax.Berkeley.EDU if you have questions)
  10523. Resent-Date: Fri, 21 Dec 90 12:13 MST
  10524. Date: 21 Dec 90 17:08:47 GMT
  10525. From: swrinde!zaphod.mps.ohio-state.edu!casbah.acns.nwu.edu!accuvax.nwu.edu!midway!ellis.uchicago.edu!goer@ucsd.edu
  10526. Subject: itlib (blanket explanation)
  10527. Sender: icon-group-request@arizona.edu
  10528. Resent-To: icon-group@cs.arizona.edu
  10529. To: icon-group@arizona.edu
  10530. Resent-Message-Id: <E7BA5263FCF340C7B8@Arizona.edu>
  10531. Message-Id: <1990Dec21.170847.6080@midway.uchicago.edu>
  10532. Organization: University of Chicago
  10533. X-Envelope-To: icon-group@CS.Arizona.EDU
  10534. X-Vms-To: icon-group@Arizona.edu
  10535.  
  10536. My mailbox was pretty full this morning, mostly with requests for
  10537. the termlib-like routines I said I'd put on alt.sources.  I again
  10538. state that I am happy to send out individual copies to people who
  10539. don't get alt.sources.
  10540.  
  10541. I received a couple of questions regarding programs I've posted be-
  10542. fore - programs which were packed with earlier versions of itlib.
  10543. The questions were mostly along the lines of, "Does the current ver-
  10544. sion of itlib and associated routines serve as a drop-in replace-
  10545. ment for earlier itlib incarnations?"  The answer is "yes."  This
  10546. means that anyone running
  10547.  
  10548.     klondike - Unix _hack_
  10549.     hebcalen - Unix port of Alan Corre's calendar program
  10550.     snake    - cute "game"
  10551.  
  10552. can use the new routines if he/she desires (if the old ones work
  10553. fine, though, I really don't see the point).
  10554.  
  10555. Itlib is now packed 1) with generalized routines for turning on empha-
  10556. size and underline modes (yes, they even work on many magic cookie
  10557. terminals), 2) implementations for getch() and getche() under Unix,
  10558. and 3) a DOS port of the itlib routines themselves.  Included is a DOS
  10559. termcap file.  I forget where I got it.  It works, but could surely
  10560. use some messaging.  Many of these changes and improvements were
  10561. posted to the icon-group.  This posting integrates them all into one
  10562. package.
  10563.  
  10564. I'm sorry to have taken so much space.  It just seemed sensible to
  10565. post the information I'm being asked for repeatedly by email.
  10566.  
  10567. The offer still stands that if someone creates a set of equivalent
  10568. routines for VMS, I'll put a wrapper around them that will render
  10569. them compatible with itlib.
  10570.  
  10571. -Richard Goerwitz (goer@sophist.uchicago.edu)
  10572.  
  10573. From cjeffery  Fri Dec 21 13:25:44 1990
  10574. Received: from caslon.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10575.     id AA23022; Fri, 21 Dec 90 13:25:44 -0700
  10576. Date: Fri, 21 Dec 90 13:25:39 -0700
  10577. From: "Clinton Jeffery" <cjeffery>
  10578. Message-Id: <9012212025.AA01028@caslon.cs.arizona.edu>
  10579. Received: by caslon.cs.arizona.edu; Fri, 21 Dec 90 13:25:39 -0700
  10580. To: reid@ctc.contel.com
  10581. Cc: djbailey@skyler.mavd.honeywell.com, icon-group@cs.arizona.edu,
  10582.         sel@ctc.contel.com
  10583. In-Reply-To: Tom Reid  x4505's message of Fri, 21 Dec 90 08:50:45 EST <9012211350.AA11474@ctc.contel.com>
  10584. Subject: Code Dichotomy
  10585.  
  10586. > Of course, the limits of how well a basically one-dimensional technology 
  10587. > (traditional text languages) can describe two and three dimensional
  10588. > problem domains is another question.
  10589.  
  10590. Text languages are only one dimensional when you lay them out "flat" in
  10591. source files.  When they execute, they are something else; recursion
  10592. (for example) just doesn't seem one-dimensional to me.
  10593.  
  10594. Outside the realm of graphics and visualization modern text languages are
  10595. routinely used to solve multidimensional problems.  A language's support
  10596. for multidimensional problem domains might be limited by its control and
  10597. data structures, but I think the bigger problem for graphics applications
  10598. (as well as natural language processing) is the "semantic gap" between the
  10599. source language and the problem domain.  Semantic gap can, I think, be
  10600. addressed linguistically once it is understood.
  10601.  
  10602. From ralph  Sat Dec 22 07:39:40 1990
  10603. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10604.     id AA18753; Sat, 22 Dec 90 07:39:40 -0700
  10605. Date: Sat, 22 Dec 90 07:39:38 MST
  10606. From: "Ralph Griswold" <ralph>
  10607. Message-Id: <9012221439.AA05788@cheltenham.cs.arizona.edu>
  10608. Received: by cheltenham.cs.arizona.edu; Sat, 22 Dec 90 07:39:38 MST
  10609. To: icon-group
  10610. Subject: ProIcon 2.0
  10611.  
  10612. Version 2.0 of ProIcon, an implementation of Icon for the Macintosh,
  10613. is now available.
  10614.  
  10615. ProIcon is a stand-alone application with a standard Macintosh interface.
  10616. It includes a capable program editor and has facilities for compiling
  10617. and running Icon programs, setting program options, managing windows,
  10618. and so forth; programs can be created, tested, and debugged without
  10619. leaving the application. Program execution can be suspended and resumed
  10620. at will or terminated at any time. On-line help is provided.
  10621.  
  10622. ProIcon has many extensions beyond the standard version of Icon, including
  10623.  
  10624.     o  function tracing (in addition to procedure tracing)
  10625.  
  10626.     o  an optional termination dump of variables and their values
  10627.  
  10628.     o  functions for manipulating windows, their contents, and the clipboard
  10629.  
  10630.     o  functions for navigating through folders
  10631.  
  10632.     o  functions for determining and setting file signatures
  10633.  
  10634. Version 2.0 of ProIcon corresponds to Version 8 of Icon and has all its
  10635. features.
  10636.  
  10637. New with ProIcon 2.0 is support for external functions that provide access to
  10638. HyperCard XCMDs and XFCNs, as well as functions that manipulate Icon data
  10639. directly.
  10640.  
  10641. ProIcon 2.0 also supports Icon's memory monitoring facility for saving details
  10642. of storage allocation and garbage collection in allocation history files. A
  10643. separate application provides animated color displays of allocation history
  10644. files.
  10645.  
  10646. Programs compiled under ProIcon can be given or sold to others; there are
  10647. no licensing requirements or royalty fees for such distribution.
  10648.  
  10649. For information about ProIcon, contact:
  10650.  
  10651.     Catspaw, Inc.
  10652.     P.O. Box 1123
  10653.     Salida, Colorado   81201-1123
  10654.     
  10655.     (719) 539-3884
  10656.  
  10657.  
  10658.  Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  10659.  (602) 621-6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  10660.  
  10661. From R.J.Hare@edinburgh.ac.uk  Mon Dec 24 03:21:01 1990
  10662. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10663.     id AA19706; Mon, 24 Dec 90 03:21:01 -0700
  10664. Received: from UKACRL.BITNET by Arizona.edu; Mon, 24 Dec 90 03:20 MST
  10665. Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 0079; Mon,
  10666.  24 Dec 90 10:20:02 GMT
  10667. Received:  from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 9567; Mon, 24
  10668.  Dec 90 10:20:02 GMT
  10669. Date: 24 Dec 90  10:20:18 gmt
  10670. From: R.J.Hare@edinburgh.ac.uk
  10671. Subject: system routine
  10672. To: icon-group@cs.arizona.edu
  10673. Message-Id: <24 Dec 90  10:20:18 gmt  060101@EMAS-A>
  10674. Via:        UK.AC.ED.EMAS-A; 24 DEC 90 10:20:00 GMT
  10675. X-Envelope-To: icon-group@cs.arizona.edu
  10676.  
  10677. Hi. I wrote the following short routine to demonstrate (prove) to someone that
  10678. the system routine worked (I included the modified prompt as visual evidence
  10679. of the proof).
  10680.  
  10681. procedure main()
  10682. writes(&clock[1:6]," ERCVAX:")
  10683. #main loop
  10684. while line:=read() do Eif line=="quit" then exit()
  10685.                                        else Esystem(line)
  10686.                                              write()
  10687.                                              writes(&clock[1:6]," ERCVAX:")LL
  10688. end
  10689.  
  10690. The program seems to work ok in that if I pass a VMS command string to the
  10691. program, it all works fine *except* that if I do a set default mumble,
  10692. mumble], ie: try to change directories, it fails.
  10693.  
  10694. Any ideas why please?
  10695.  
  10696. Thanks.
  10697.  
  10698. Roger Hare.
  10699.  
  10700. From R.J.Hare@edinburgh.ac.uk  Mon Dec 24 04:16:07 1990
  10701. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10702.     id AA22283; Mon, 24 Dec 90 04:16:07 -0700
  10703. Received: from UKACRL.BITNET by Arizona.edu; Mon, 24 Dec 90 04:15 MST
  10704. Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 0243; Mon,
  10705.  24 Dec 90 11:15:13 GMT
  10706. Received:  from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 9789; Mon, 24
  10707.  Dec 90 11:15:13 GMT
  10708. Date: 24 Dec 90  11:15:34 gmt
  10709. From: R.J.Hare@edinburgh.ac.uk
  10710. Subject: Last message
  10711. To: icon-group@cs.arizona.edu
  10712. Message-Id: <24 Dec 90  11:15:34 gmt  060109@EMAS-A>
  10713. Via:        UK.AC.ED.EMAS-A; 24 DEC 90 11:15:12 GMT
  10714. X-Envelope-To: icon-group@cs.arizona.edu
  10715.  
  10716. Please ignore my last message - I should have sent it to the Icon project,
  10717. not to the Icon group.
  10718.  
  10719. Roger Hare.
  10720.  
  10721. From mlfarm!ron@hsi.hsi.com  Wed Dec 26 07:29:57 1990
  10722. Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  10723.     id AA24245; Wed, 26 Dec 90 07:29:57 -0700
  10724. Received: by hsi.hsi.com (5.61+++/1.34)
  10725.     id AA21170; Wed, 26 Dec 90 09:28:10 -0500
  10726. Received: by mlfarm.com (smail2.5)
  10727.     id AA07340; 23 Dec 90 07:39:17 EST (Sun)
  10728. To: icon-group@cs.arizona.edu
  10729. Subject: Icon as a teaching language 
  10730. Message-Id: <9012230739.AA07340@mlfarm.com>
  10731. Date: 23 Dec 90 07:39:17 EST (Sun)
  10732. From: mlfarm!ron@hsi.hsi.com (Ronald Florence)
  10733.  
  10734. With the Christmas vacation upon us and a 12-year old around the
  10735. house, I wonder if anyone has had experience with Icon as a first
  10736. structured language.  My son is adept at vi and gnuplot, and for
  10737. homework problems I have occasionally kludged together awk scripts,
  10738. which he then modifies as he needs.  I suspect some of the more
  10739. elegant and terse Icon constructions could be daunting, but the
  10740. multiplicity of approaches to a given problem could be fun.
  10741.  
  10742. Has anyone tried this?  Any wisdom or suggestions?  
  10743. --
  10744.  
  10745. Ronald Florence            ron@mlfarm.com
  10746.  
  10747.  
  10748.  
  10749. From wgg@cs.washington.edu  Wed Dec 26 11:40:25 1990
  10750. Received: from june.cs.washington.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10751.     id AA29524; Wed, 26 Dec 90 11:40:25 -0700
  10752. Received: by june.cs.washington.edu (5.64/7.0jh)
  10753.     id AA07710; Wed, 26 Dec 90 10:40:10 -0800
  10754. Date: Wed, 26 Dec 90 10:40:10 -0800
  10755. From: wgg@cs.washington.edu (William Griswold)
  10756. Return-Path: <wgg@cs.washington.edu>
  10757. Message-Id: <9012261840.AA07710@june.cs.washington.edu>
  10758. To: icon-group@cs.arizona.edu, mlfarm!ron@hsi.hsi.com
  10759. Subject: Re:  Icon as a teaching language
  10760.  
  10761. >From: mlfarm!ron@hsi.hsi.com (Ronald Florence)
  10762. >
  10763. >With the Christmas vacation upon us and a 12-year old around the
  10764. >house, I wonder if anyone has had experience with Icon as a first
  10765. >structured language....
  10766.  
  10767. Well, I was programming in SNOBOL at this age.  The results were fun
  10768. but aesthetically disasterous.  Certainly Icon would be at least as
  10769. fun and perhaps a better language to begin with.  If you can get him
  10770. playing with some of the more advanced functions, such as map and
  10771. random selection (kids eat this stuff up), he'll have a blast.
  10772. Actually, giving him something to modify could be very effective.
  10773. Small changes in small Icon programs can yield vastly different but
  10774. useful results.  The Icon books are full of small programs that are easy to
  10775. write and modify.
  10776.  
  10777.  
  10778. Don't forget numeric calculations as well.  Your child may be old enough
  10779. to program a sieve for primes (my first program divided by all the numbers
  10780. less than or equal to 1/2 the number.  It wasn't long before I figured out
  10781. I could leave out most of the even numbers....) or some other such program. 
  10782.  
  10783. Unfortunately Icon isn't interactively interpretive, so you can't
  10784. run-as-you-program.  I've written a little line-oriented interpreter loop
  10785. for Icon, but it changes the syntax and doesn't allow procedures....
  10786.  
  10787.                     Bill Griswold
  10788.  
  10789. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Fri Dec 28 09:23:47 1990
  10790. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10791.     id AA04048; Fri, 28 Dec 90 09:23:47 -0700
  10792. Received: by uwm.edu; id AA29316; Fri, 28 Dec 90 10:23:25 -0600
  10793. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  10794.           Fri, 28 Dec 90 09:32:52 CDT
  10795. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  10796.           Fri, 28 Dec 1990 09:05 CST
  10797. Date: Fri, 28 Dec 1990 09:05 CST
  10798. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  10799. Subject: TAR
  10800. To: icon-group@cs.arizona.edu
  10801. Message-Id: <AB97A89CC0200EAF@mis.mcw.edu>
  10802. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  10803. X-Envelope-To: icon-group@cs.arizona.edu
  10804. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  10805.  
  10806.  
  10807. I run Icon V8 under VAX/VMS 5.2. I occasionally come across tar tapes/files.
  10808. I know tar is built into unix. But I'll ask anyway,
  10809.  
  10810. Has anyone written their own TAR utility in ICON? If not, could someone
  10811. mail or post me the spec, both the syntax of the tar utility, and the
  10812. data layout.
  10813.  
  10814. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  10815. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  10816. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  10817.  
  10818. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Fri Dec 28 10:08:21 1990
  10819. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10820.     id AA05206; Fri, 28 Dec 90 10:08:21 -0700
  10821. Received: by uwm.edu; id AA29925; Fri, 28 Dec 90 11:08:17 -0600
  10822. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  10823.           Fri, 28 Dec 90 10:40:20 CDT
  10824. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  10825.           Fri, 28 Dec 1990 09:36 CST
  10826. Date: Fri, 28 Dec 1990 09:36 CST
  10827. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  10828. Subject: iconx
  10829. To: icon-group@cs.arizona.edu
  10830. Message-Id: <AFEE8D5860200EAF@mis.mcw.edu>
  10831. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  10832. X-Envelope-To: icon-group@cs.arizona.edu
  10833. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  10834.  
  10835.  
  10836. I noticed on my postings that some had commented that the
  10837.  
  10838. ICONX PROGRAM ...
  10839.  
  10840. is unnecessary. This may be partly true under unix. MSDOS needs the ICONX
  10841. all the time. Under VMS we have a script called IEXE which converts
  10842. ICONX PROG  unto a symbol(alias) PROG. This is handy for utilities that
  10843. are used very commonly. Under VMS icon paints screens so slow that I
  10844. usually use DCL (shell commands) to build the screen or menu, and build icon
  10845. filters to manipulate the files underneathe.
  10846.  
  10847. Some years ago I ported ICON to a ZS-1 super-minicomputer from Astronautics.
  10848. There were certain configuration parameters that were set before building
  10849. the software. One or more parameters were concerned with whether icon utilities
  10850. needed iconx explicitly, or if it rolled a little executable into the icode.
  10851. However, since main(){printf("hello\n");} generated about 200k of executable.
  10852. The icode of most of the utilities I wrote was typically 2-4k, and the disks
  10853. were pretty full, it was smarter there to keep the icode separate, so iconx
  10854. would be required. That was in the Icon 7.0 days, and maybe Icon 8 is much
  10855. different under unix.
  10856.  
  10857. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  10858. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  10859. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  10860.  
  10861.  
  10862. From mlfarm!ron@hsi.hsi.com  Sat Dec 29 09:47:04 1990
  10863. Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  10864.     id AA08896; Sat, 29 Dec 90 09:47:04 -0700
  10865. Received: by hsi.hsi.com (5.61+++/1.34)
  10866.     id AA23539; Sat, 29 Dec 90 11:45:16 -0500
  10867. Received: by mlfarm.com (smail2.5)
  10868.     id AA14370; 29 Dec 90 11:43:14 EST (Sat)
  10869. To: icon-group@cs.arizona.edu
  10870. In-Reply-To: Chris Tenaglia - 257-8765's message of Fri Dec 28 09:36 CST
  10871. Subject: iconx
  10872. Message-Id: <9012291143.AA14370@mlfarm.com>
  10873. Date: 29 Dec 90 11:43:14 EST (Sat)
  10874. From: mlfarm!ron@hsi.hsi.com (Ronald Florence)
  10875.  
  10876. Chris Tenaglia - 257-8765 writes:
  10877.  
  10878.  > I noticed on my postings that some had commented that the
  10879.  > 
  10880.  > ICONX PROGRAM ...
  10881.  > 
  10882.  > is unnecessary. 
  10883.  
  10884. What I wrote was that the `ICONX' is system-specific, and that the
  10885. users of systems which do not have direct execution (VMS, ms-dos) will
  10886. know to use it.  Because commands are case-sensitive, `ICONX PROGRAM'
  10887. won't work on most unix systems.
  10888.  
  10889.  > The icode of most of the utilities I wrote was typically 2-4k, and the disks
  10890.  > were pretty full, it was smarter there to keep the icode separate, so iconx
  10891.  > would be required. 
  10892.  
  10893. It would be interesting to compare the size of the compiled code on
  10894. various systems.  The canonical hello.icn compiles to 6941 bytes here
  10895. (Xenix 386, direct execution).  Is it much smaller on VMS or ms-dos
  10896. systems without direct execution?  
  10897. --
  10898.  
  10899. Ronald Florence            ron@mlfarm.com
  10900.  
  10901.  
  10902.  
  10903. From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu  Tue Jan  1 09:42:36 1991
  10904. Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  10905.     id AA00177; Tue, 1 Jan 91 09:42:36 -0700
  10906. Received: by uwm.edu; id AA01354; Tue, 1 Jan 91 08:34:39 -0600
  10907. Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  10908.           Tue,  1 Jan 91 08:01:24 CDT
  10909. Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP);
  10910.           Tue, 1 Jan 1991 07:32 CST
  10911. Date: Tue, 1 Jan 1991 07:31 CST
  10912. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  10913. Subject: Happy New Year ! Black Jack Game.
  10914. To: icon-group@cs.arizona.edu
  10915. Message-Id: <C3284CA4006019D9@mis.mcw.edu>
  10916. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  10917. X-Envelope-To: icon-group@cs.arizona.edu
  10918. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  10919.  
  10920.  
  10921. Happy New Year! After considering all the good advice on the draw poker game
  10922. I kloojed together a simple version of black jack. It's about 291 lines.
  10923. The shuffling on the draw poker game also wasn't very good, so this game
  10924. uses the technique in the IPL which I think is more correct anyway. Enjoy!
  10925.  
  10926. Yours truly,
  10927. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  10928. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  10929. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  10930.  
  10931. #########################################################
  10932. #                                                       #
  10933. # BJ.ICN            12/19/90          BY TENAGLIA       #
  10934. #                                                       #
  10935. # SIMPLE BUT FUN BLACK JACK GAME. WORKS ON ANSI SCREEN. #
  10936. # USAGE : iconx bj   [starting credits]                 #
  10937. #                                                       #
  10938. #########################################################
  10939. global deck, message, lookup,
  10940.        user_money,  host_money,
  10941.        user_hand,   host_hand
  10942.  
  10943. procedure main(param)
  10944.   user_money := integer(param[1]) | 3 ; host_money := user_money
  10945.   write(screen("cls"),"               ",screen("top"),screen("hinv"),
  10946.         "BLACK JACK",screen("norm"))
  10947.   write("               ",screen("bot"),screen("hinv"),
  10948.         "BLACK JACK",screen("norm"))
  10949.   bonus := 0
  10950.   repeat
  10951.     {
  10952.     if not any('y',(map(input(at(1,4)   || screen("under") ||
  10953.                    "Want to play? y/n :"|| screen("norm")  ||
  10954.                    screen("eeol")))[1])) then break
  10955.     writes(at(1,4),screen("eeos"))
  10956.     display_score()
  10957.     deck    := shuffle()
  10958.     message := ""
  10959.     user_hand := []          ; host_hand := []
  10960.     put(user_hand,pop(deck)) ; put(host_hand,pop(deck))
  10961.     put(user_hand,pop(deck)) ; put(host_hand,pop(deck))
  10962.     user_points := first(host_hand[1])
  10963.     if user_points > 21 then
  10964.       {
  10965.       writes(at(1,14),user_points," points. You went over. You loose.")
  10966.       user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0
  10967.       display_score()
  10968.       next
  10969.       }
  10970.     display_host(2)
  10971.     host_points := second(user_points)
  10972.     if host_points > 21 then
  10973.       {
  10974.       writes(at(50,23),host_points," points. ",&host," went over.")
  10975.       writes(at(1,14),screen("hiblink"),"You win.",screen("norm"))
  10976.       host_money -:= 1 ; user_money +:= 1 + bonus ; bonus := 0
  10977.       display_score()
  10978.       next
  10979.       }
  10980.     if host_points = user_points then
  10981.       {
  10982.       writes(at(1,23),screen("hiblink"),"It's a draw at ",user_points,
  10983.             ". The ANTY goes to bonus.",screen("norm"))
  10984.       bonus +:= 2 ; host_money -:= 1 ; user_money -:= 1
  10985.       display_score()
  10986.       next
  10987.       }
  10988.     writes(at(20,13),user_points," points for user.")
  10989.     writes(at(1,15),host_points," points for ",&host)
  10990.     if user_points < host_points then
  10991.       {
  10992.       write(at(1,23),screen("hiblink"),&host," wins.",
  10993.             screen("norm"),screen("eeol"))
  10994.       user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0
  10995.       display_score()
  10996.       next
  10997.       } else {
  10998.       writes(at(1,13),screen("hiblink"),"You win.",screen("norm"),screen("eeol"))
  10999.       user_money +:= 1 + bonus ; host_money -:= 1 ; bonus := 0
  11000.       display_score()
  11001.       next
  11002.       }
  11003.     }
  11004.   write(screen("clear"))
  11005.   end
  11006.  
  11007. #
  11008. # THIS PROCEDURE ALLOWS THE USER TO PLAY AND TAKE HITS
  11009. #
  11010. procedure first(host_card)
  11011.   display_user()
  11012.   display_host(1)
  11013.   points := value(user_hand)   # just in case
  11014.   writes(at(1,10),"(",points,") ")
  11015.   repeat
  11016.     if any('hy',map(input(at(1,23) || "Hit ? y/n :" || screen("eeol")))) then
  11017.       {
  11018.       put(user_hand,pop(deck))
  11019.       display_user()
  11020.       if (points := value(user_hand)) > 21 then return points
  11021.       writes(at(1,10),"(",points,") ")
  11022.       } else break
  11023.   (points > 0) | (points := value(user_hand))
  11024.   writes(at(1,10),"(",points,") ")
  11025.   write(at(60,12),"You stay with ",points)
  11026.   return points
  11027.   end
  11028.  
  11029. #
  11030. # THIS SECOND PROCEDURE IS THE HOST PLAYING AGAINST THE USER
  11031. #
  11032. procedure second(ceiling)
  11033.   static limits
  11034.   initial limits := [14,14,15,15,19,16,17,18]
  11035.   stop_at := ?limits ; points := 0
  11036.   until (points := value(host_hand)) > stop_at do
  11037.     {
  11038.     if points > ceiling then return points
  11039.     writes(at(1,20),"(",points,") ")
  11040.     write(at(1,23),screen("eeol"),&host," will take a hit.",screen("eeol"))
  11041.     put(host_hand,pop(deck))
  11042.     display_host(2)
  11043.     }
  11044.   (points > 0) | (points := value(host_hand))
  11045.   writes(at(1,20),"(",points,") ")
  11046.   return points
  11047.   end
  11048.  
  11049. #
  11050. # THIS ROUTINE DISPLAYS THE CURRENT SCORE
  11051. #
  11052. procedure display_score()
  11053.   writes(screen("nocursor"))
  11054.   writes(screen("dim"),at(1,8),"Credits",screen("norm"))
  11055.   writes(screen("high"),at(1,9),right(user_money,7),screen("norm"))
  11056.   writes(screen("dim"),at(1,18),"Credits",screen("norm"))
  11057.   writes(screen("high"),at(1,19),right(host_money,7),screen("norm"))
  11058.   end
  11059. #
  11060. # THIS PROCEDURE EVALUATES THE POINTS OF A HAND. IT TRIES TO MAKE THEM
  11061. # AS HIGH AS POSSIBLE WITHOUT GOING OVER 21.
  11062. #
  11063. procedure value(sample)
  11064.   hand     := copy(sample)
  11065.   possible := []
  11066.   repeat
  11067.     {
  11068.     sum := 0
  11069.     every card := !hand do sum +:= lookup[card[1]]
  11070.     put(possible,sum)
  11071.     if Aces(hand) == "none" then break else
  11072.       every i := 1 to *hand do if hand[i][1] == "A" then hand[i][1] := "a"
  11073.     }
  11074.   every score := !possible do
  11075.     if score <= 21 then return score
  11076.   return possible[1]
  11077.   end
  11078.  
  11079. #
  11080. # ARE THERE ANY 11 POINT ACES LEFT IN HAND
  11081. #
  11082. procedure Aces(cards)
  11083.   every look := !cards do if look[1] == "A" then return "some"
  11084.   return "none"
  11085.   end
  11086.  
  11087. #
  11088. # THIS ROUTINE DISPLAYS THE USER HAND AND STATUS
  11089. #
  11090. procedure display_user()
  11091.   writes(screen("nocursor"),at(4,7),screen("hinv"),"USER",screen("norm"))
  11092.   x := 10 ; y := 5
  11093.   every card := !user_hand do
  11094.     {
  11095.     display(card,x,y)
  11096.     x +:= 7
  11097.     }
  11098.   end
  11099.  
  11100. #
  11101. # THIS ROUTINE DISPLAYS THE HOST HAND AND STATUS
  11102. #
  11103. procedure display_host(flag)
  11104.   writes(screen("nocursor"),at(1,17),screen("hinv"),&host,screen("norm"))
  11105.   x := 10 ; y := 15 ; /flag := 0
  11106.   every card := !host_hand do
  11107.     {
  11108.     if (flag=1) & (x=10) then card := "XX"
  11109.     display(card,x,y)
  11110.     x +:= 7
  11111.     }
  11112.   end
  11113.  
  11114. #
  11115. # THIS ROUTINE DISPLAYS A GIVEN CARD AT A GIVEN X,Y SCREEN LOCATION
  11116. #
  11117. procedure display(card,x,y)
  11118.     all := [] ; j := y
  11119.     if find(card[2],"CS") then card := screen("hinv") || card || screen("norm")
  11120.     shape := [at(x,(j+:=1)) || screen("gchar") || "lqqqqqqqk"]
  11121.     put(shape,at(x,(j+:=1)) || "x " || card || "    x")
  11122.     put(shape,at(x,(j+:=1)) || "x       x")
  11123.     put(shape,at(x,(j+:=1)) || "x       x")
  11124.     put(shape,at(x,(j+:=1)) || "x       x")
  11125.     put(shape,at(x,(j+:=1)) || "x    " || card || " x")
  11126.     put(shape,at(x,(j+:=1)) || "mqqqqqqqj" || screen("nchar"))
  11127.     put(all,shape)
  11128.     x +:= 14
  11129.   while shape := pop(all) do every writes(!shape)
  11130.   end
  11131.  
  11132. #
  11133. # THIS ROUTINE SHUFFLES THE CARD DECK
  11134. #
  11135. procedure shuffle()
  11136.   static faces, suits
  11137.   local cards, i
  11138.   initial {
  11139.           &random := map(&clock,":","7")   # initial on multiple shuffles
  11140.           faces   := ["2","3","4","5","6","7","8","9","T","J","Q","K","A"]
  11141.           suits   := ["D","H","C","S"]
  11142.           lookup  := table(0)
  11143.           every i := 2 to 9 do insert(lookup,string(i),i)
  11144.           insert(lookup,"T",10)
  11145.           insert(lookup,"J",10)
  11146.           insert(lookup,"Q",10)
  11147.           insert(lookup,"K",10)
  11148.           insert(lookup,"A",11)
  11149.           insert(lookup,"a",1)
  11150.           }
  11151.   cards   := []
  11152.   every put(cards,!faces || !suits)
  11153.   every i := *cards to 2 by -1 do cards[?i] :=: cards[i]
  11154.   return cards
  11155.   end
  11156.  
  11157. #
  11158. # THIS ROUTINE PARSES A STRING WITH RESPECT TO SOME DELIMITER
  11159. #
  11160. procedure parse(line,delims)
  11161.   static chars
  11162.   chars  := &cset -- delims
  11163.   tokens := []
  11164.   line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
  11165.   return tokens
  11166.   end
  11167.  
  11168. #
  11169. # THIS ROUTINE PROMPTS FOR INPUT AND RETURNS A STRING
  11170. #
  11171. procedure input(prompt)
  11172.   writes(screen("cursor"),prompt)
  11173.   return read()
  11174.   end
  11175.  
  11176.  
  11177. #
  11178. # THIS ROUTINE SETS THE VIDEO OUTPUT ATTRIBUTES FOR VT102 OR LATER
  11179. # COMPATIBLE TERMINALS.
  11180. #
  11181. procedure screen(attr)
  11182.   case attr of
  11183.     {
  11184.     "cls"  : return "\e[2J\e[H"  # CLEAR SCREEN
  11185.     "clear": return "\e[2J\e[H"  # CLEAR SCREEN
  11186.     "top"  : return "\e#3"       # UPPER HALF CHARACTERS
  11187.     "bot"  : return "\e#4"       # LOWER HALF CHARACTERS
  11188.     "fat"  : return "\e#6"       # SINGLE HEIGHT FAT LETTERS
  11189.     "thin" : return "\e#5"       # NORMAL SIZED CHARACTERS
  11190.     "hinv" : return "\e[1;7m"    # HIGH INTENSITY & INVERSE
  11191.     "norm" : return "\e[m"       # RESTORE NORMAL VIDEO ATTRIBUTES
  11192.     "dim"  : return "\e[2m"      # LOW INTENSITY VIDEO
  11193.     "blink": return "\e[5m"      # VIDEO BLINKING ATTRIBUTE
  11194.   "hiblink": return "\e[1;5m"    # HIGH INTENSITY BLINKING
  11195.     "under": return "\e[4m"      # VIDEO UNDERLINING ATTRIBUTE
  11196.     "high" : return "\e[1m"      # VIDEO HIGH INTENSITY ATTRIBUTE
  11197.     "inv"  : return "\e[7m"      # VIDEO INVERSE ATTRIBUTE
  11198.     "eeol" : return "\e[K"       # ERASE TO END OF LINE
  11199.     "esol" : return "\e[1K"      # ERASE TO START OF LINE
  11200.     "eeos" : return "\e[J"       # ERASE TO END OF SCREEN
  11201.     "gchar": return "\e(0"       # TURN ON ANSI GRAPHICS MODE
  11202.     "nchar": return "\e(B"       # TURN OFF ANSI GRAPHICS MODE
  11203.     "light": return "\e[?5h"     # LIGHT COLORED SCREEN
  11204.     "dark" : return "\e[?5l"     # DARK  COLORED SCREEN
  11205.     "80"   : return "\e[?3l"     # 80    COLUMNS ON SCREEN
  11206.     "132"  : return "\e[?3h"     # 132   COLUMNS ON SCREEN
  11207.     "smooth": return "\e[?4h"    # SMOOTH SCREEN SCROLLING
  11208.     "jump" : return "\e[?4l"     # JUMP   SCREEN SCROLLING
  11209.     "cursor": return "\e[?25h"   # MAKE SURE CURSOR IS VISIBLE
  11210.   "nocursor": return "\e[?25l"   # HIDE THE CURSOR
  11211.     default: return "("||attr||")"
  11212.     }
  11213.   end
  11214.  
  11215. #
  11216. # THIS ROUTINE SETS THE CURSOR TO A GIVEN X (COL) Y(ROW) SCREEN LOCATION
  11217. #
  11218. procedure at(x,y)
  11219.   return "\e[" || y || ";" || x || "f"
  11220.   end
  11221.  
  11222.  
  11223.  
  11224. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Tue Jan  1 20:06:36 1991
  11225. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  11226.     id AA12591; Tue, 1 Jan 91 20:06:36 -0700
  11227. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  11228.     id AA04966; Tue, 1 Jan 91 22:06:27 -0500
  11229. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Tue, 1 Jan 91 22:03:41 EST
  11230. Date: Tue, 1 Jan 91 16:34:36 EST
  11231. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  11232. To: icon-group@cs.arizona.edu
  11233. Message-Id: <281696@Wayne-MTS>
  11234. Subject: Message conventions
  11235.  
  11236.  
  11237. This isn't exactly an Icon question, but.....
  11238.  
  11239. I've noticed that in many of the postings to icon-group, the messages have
  11240. excerpts from previous messages preceded by "> ".  Could anyone let me know
  11241. what software you're using to get this effect, and how you're using it? 
  11242. Thanks. 
  11243.  
  11244. Paul Abrahams
  11245. abrahams%wayne-mts@um.cc.umich.edu
  11246.  
  11247. From icon-group-request@arizona.edu  Tue Jan  1 21:52:02 1991
  11248. Resent-From: icon-group-request@arizona.edu
  11249. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  11250.     id AA14616; Tue, 1 Jan 91 21:52:02 -0700
  11251. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 1 Jan 91 21:51 MST
  11252. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29802; Tue, 1 Jan 91 20:44:27
  11253.  -0800
  11254. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11255.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  11256.  usenet@ucbvax.Berkeley.EDU if you have questions)
  11257. Resent-Date: Tue, 1 Jan 91 21:51 MST
  11258. Date: 2 Jan 91 02:56:21 GMT
  11259. From: netnews.upenn.edu!msuinfo!midway!quads.uchicago.edu!goer@rutgers.edu
  11260. Subject: bj, part 3 of 3
  11261. Sender: icon-group-request@arizona.edu
  11262. Resent-To: icon-group@cs.arizona.edu
  11263. To: icon-group@arizona.edu
  11264. Resent-Message-Id: <DEC4BED6C699400483@Arizona.edu>
  11265. Message-Id: <1991Jan2.025621.21511@midway.uchicago.edu>
  11266. Organization: University of Chicago
  11267. X-Envelope-To: icon-group@CS.Arizona.EDU
  11268. X-Vms-To: icon-group@Arizona.edu
  11269. References: <1991Jan2.025428.21379@midway.uchicago.edu>
  11270.  
  11271.  
  11272. stty: Operation not supported on socket
  11273. ---- Cut Here and feed the following to sh ----
  11274. #!/bin/sh
  11275. # this is bj.03 (part 3 of a multipart archive)
  11276. # do not concatenate these parts, unpack them in order with /bin/sh
  11277. # file itlibdos.icn continued
  11278. #
  11279. if test ! -r _shar_seq_.tmp; then
  11280.     echo 'Please unpack part 1 first!'
  11281.     exit 1
  11282. fi
  11283. (read Scheck
  11284.  if test "$Scheck" != 3; then
  11285.     echo Please unpack part "$Scheck" next!
  11286.     exit 1
  11287.  else
  11288.     exit 0
  11289.  fi
  11290. ) < _shar_seq_.tmp || exit 1
  11291. if test ! -f _shar_wnt_.tmp; then
  11292.     echo 'x - still skipping itlibdos.icn'
  11293. else
  11294. echo 'x - continuing file itlibdos.icn'
  11295. sed 's/^X//' << 'SHAR_EOF' >> 'itlibdos.icn' &&
  11296. X    range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  11297. X    er("igoto",colline || " out of range " || (\range|""),9)
  11298. X    } 
  11299. X
  11300. X    # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
  11301. X    increment := -1
  11302. X    outstr := ""
  11303. X    
  11304. X    cm ? {
  11305. X    while outstr ||:= tab(find("%")) do {
  11306. X        tab(match("%"))
  11307. X        chr := move(1)
  11308. X        if case chr of {
  11309. X        "." :  outstr ||:= char(line + increment)
  11310. X        "+" :  outstr ||:= char(line + ord(move(1)) + increment)
  11311. X        "d" :  {
  11312. X            str := string(line + increment)
  11313. X            outstr ||:= right(str, integer(tab(any('23'))), "0") | str
  11314. X        }
  11315. X        }
  11316. X        then line :=: col
  11317. X        else {
  11318. X        case chr of {
  11319. X            "n" :  line := ixor(line,96) & col := ixor(col,96)
  11320. X            "i" :  increment := 0
  11321. X            "r" :  line :=: col
  11322. X            "%" :  outstr ||:= "%"
  11323. X            "B" :  line := ior(ishift(line / 10, 4), line % 10)
  11324. X            ">" :  {
  11325. X            x := move(1); y := move(1)
  11326. X            line > ord(x) & line +:= ord(y)
  11327. X            &null
  11328. X            }
  11329. X        } | er("goto","bad termcap entry",5)
  11330. X        }
  11331. X    }
  11332. X    return outstr || tab(0)
  11333. X    }
  11334. X
  11335. Xend
  11336. X
  11337. X
  11338. X
  11339. Xprocedure iputs(cp, affcnt)
  11340. X
  11341. X    # Writes cp to the screen.  Use this instead of writes() for
  11342. X    # compatibility with the Unix version (which will need to send
  11343. X    # null padding in some cases).  Iputs() also does a useful type
  11344. X    # check.
  11345. X
  11346. X    static num_chars
  11347. X    initial num_chars := &digits ++ '.'
  11348. X
  11349. X    type(cp) == "string" |
  11350. X    er("iputs","you can't iputs() a non-string value!",10)
  11351. X
  11352. X    cp ? {
  11353. X    if tab(many(num_chars)) & ="*" then
  11354. X        stop("iputs:  MS-DOS termcap files shouldn't specify padding.")
  11355. X    writes(tab(0))
  11356. X    }
  11357. X
  11358. X    return
  11359. X
  11360. Xend
  11361. SHAR_EOF
  11362. echo 'File itlibdos.icn is complete' &&
  11363. true || echo 'restore of itlibdos.icn failed'
  11364. rm -f _shar_wnt_.tmp
  11365. fi
  11366. # ============= termcap.dos ==============
  11367. if test -f 'termcap.dos' -a X"$1" != X"-c"; then
  11368.     echo 'x - skipping termcap.dos (File already exists)'
  11369.     rm -f _shar_wnt_.tmp
  11370. else
  11371. > _shar_wnt_.tmp
  11372. echo 'x - extracting termcap.dos (Text)'
  11373. sed 's/^X//' << 'SHAR_EOF' > 'termcap.dos' &&
  11374. Xansi|color|ansi-color|ibm|ibmpc|ANSI.SYS color:\
  11375. X    :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\
  11376. X    :cl=\E[H\E[2J:ce=\E[K:\
  11377. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  11378. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  11379. X    :ti=\E[0;44m:te=\E[0m:\
  11380. X    :so=\E[1;35;44m:se=\E[0;44m:\
  11381. X    :us=\E[1;31;44m:ue=\E[0;44m:\
  11382. X    :mb=\E[5m:md=\E[1m:me=\E[0;44m:
  11383. Xmono|ansi-mono|ANSI.SYS:\
  11384. X    :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\
  11385. X    :cl=\E[H\E[2J:ce=\E[K:\
  11386. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  11387. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  11388. X    :so=\E[1m:se=\E[m:us=\E[4m:ue=\E[m:\
  11389. X    :mb=\E[5m:md=\E[1m:me=\E[m:
  11390. Xnnansi-mono|NNANSI.SYS:\
  11391. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  11392. X    :cl=\E[2J:cd=\E[J:ce=\E[K:\
  11393. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  11394. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  11395. X    :so=\E[1m:se=\E[2m:\
  11396. X    :us=\E[4m:ue=\E[24m:\
  11397. X    :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[m:\
  11398. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  11399. Xnnansi|nnansi-color|NNANSI.SYS color:\
  11400. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  11401. X    :cl=\E[2J:cd=\E[J:ce=\E[K:\
  11402. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  11403. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  11404. X    :ti=\E[0;44m:te=\E[0m:\
  11405. X    :so=\E[1;35;44m:se=\E[2;37m:\
  11406. X    :us=\E[4m:ue=\E[24m:\
  11407. X    :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[0;44m:\
  11408. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  11409. Xnansi-mono|zansi-mono|N/ZANSI.SYS:\
  11410. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  11411. X    :cl=\E[2J:ce=\E[K:\
  11412. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  11413. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  11414. X    :ti=\E[0m:te=\E[0m:\
  11415. X    :so=\E[1;35m:se=\E[0m:\
  11416. X    :us=\E[1;31m:ue=\E[0m:\
  11417. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:\
  11418. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  11419. Xnansi|zansi|nansi-color|zansi-color|N/ZANSI.SYS color:\
  11420. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  11421. X    :cl=\E[2J:ce=\E[K:\
  11422. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  11423. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  11424. X    :ti=\E[0;44m:te=\E[0m:\
  11425. X    :so=\E[1;35;44m:se=\E[0;44m:\
  11426. X    :us=\E[1;31;44m:ue=\E[0;44m:\
  11427. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[0;44m:\
  11428. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  11429. XAX|ANSI X3.64|full ANSI X3.64 (1977) standard:\
  11430. X    :co#80:li#24:bs:pt:am:mi:bl=^G:le=^H:\
  11431. X    :cl=\E[2J:ce=\E[K:cd=\E[J:\
  11432. X    :ho=\E[H:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:\
  11433. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  11434. X    :UP=\E[%dA:DO=\E[%dB:LE=\E[%dC:RI=\E[%dD:\
  11435. X    :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
  11436. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:as=^N:ae=^O:\
  11437. X    :ku=\E[A:kd=\E[B:kl=\E[C:kr=\E[D:kb=^H:\
  11438. X    :kn#4:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\
  11439. X    :im=\E[4h:ei=\E[4l:al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:sf=\ED:sr=\EM:
  11440. SHAR_EOF
  11441. true || echo 'restore of termcap.dos failed'
  11442. rm -f _shar_wnt_.tmp
  11443. fi
  11444. # ============= README ==============
  11445. if test -f 'README' -a X"$1" != X"-c"; then
  11446.     echo 'x - skipping README (File already exists)'
  11447.     rm -f _shar_wnt_.tmp
  11448. else
  11449. > _shar_wnt_.tmp
  11450. echo 'x - extracting README (Text)'
  11451. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  11452. XThis package is a simple UNIX port of Chris Tenaglia's blackjack
  11453. Xgame for full ANSI terminals.  Because of the structure of the
  11454. Xoriginal program (read: because I was lazy) this port won't work
  11455. Xwith magic cookie terminals.  It works best on terminals that have
  11456. Xboldface, reverse, dim, and blink modes.  If any of these are mis-
  11457. Xsing, the appearance of the game will be somewhat altered.  Ter-
  11458. Xminals must be at least 24x80.
  11459. X
  11460. XTo make for UNIX, just copy Makefile.dist to Makefile and type
  11461. X"make."  If all goes well, and you have root priviledges, su to
  11462. Xroot and type "make install."  You'll have to edit the makefile
  11463. Xto reflect local file structures and conventions.
  11464. X
  11465. XIncluded with this distribution is also a DOS implementation of
  11466. Xthe itlib routines and a termcap file.  To run this program on a
  11467. XDOS system, first compile using
  11468. X
  11469. X     icont -o bj bj.icn itlibdos.icn
  11470. X
  11471. XRead the directions in the file itlibdos.icn for instructions as
  11472. Xto how to install a termcap file.  NOTE WELL:  THE TERMCAP FOR
  11473. XDOS IS NOT TERRIBLY GOOD, AND IN ORDER TO GET IT TO WORK, YOU
  11474. XWILL CERTAINLY NEED TO FIX IT UP.  I don't use DOS much, and will
  11475. Xjust have to hope that some any revisions that get made will make
  11476. Xtheir way back to me.
  11477. X
  11478. XNaturally, UNIX users can erase all the DOS files ("rm *dos*").
  11479. XDOS users can erase itlibdos.icn and Makefile.dist.  If anything
  11480. Xgoes awry, or if a standard terminal such as a VT-XXX or and
  11481. XANSI fails to run bj, please let me know.  I expect that older
  11482. Xterminals without a full assortment of modes - if they run it
  11483. Xat all - will not do so very smartly.
  11484. X
  11485. XEnjoy Chris's game, and have a good 1991!
  11486. X
  11487. X-Richard Goerwitz (goer@sophist.uchicago.edu)
  11488. SHAR_EOF
  11489. true || echo 'restore of README failed'
  11490. rm -f _shar_wnt_.tmp
  11491. fi
  11492. # ============= Makefile.dist ==============
  11493. if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
  11494.     echo 'x - skipping Makefile.dist (File already exists)'
  11495.     rm -f _shar_wnt_.tmp
  11496. else
  11497. > _shar_wnt_.tmp
  11498. echo 'x - extracting Makefile.dist (Text)'
  11499. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
  11500. X# Don't change this unless you know what you are doing :-).
  11501. XPROGNAME = bj
  11502. X
  11503. X# Please edit these to reflect your local file structure & conventions.
  11504. XDESTDIR = /usr/local/bin
  11505. XOWNER = bin
  11506. XGROUP = bin
  11507. X
  11508. X# Please don't change these.
  11509. XSRC = $(PROGNAME).icn itlib.icn
  11510. X
  11511. X# I hope you won't have to use this.
  11512. X# DEBUGFLAG = -t
  11513. X
  11514. X$(PROGNAME): $(SRC)
  11515. X    /usr/local/bin/icont $(DEBUGFLAG) -o $(PROGNAME) $(SRC)
  11516. X
  11517. X# Pessimistic assumptions regarding the environment (in particular,
  11518. X# I don't assume you have the BSD "install" shell script).
  11519. Xinstall: $(PROGNAME)
  11520. X    @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
  11521. X    cp $(PROGNAME) $(DESTDIR)/
  11522. X    chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  11523. X    chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  11524. X    @echo "\nInstallation done.\n"
  11525. X
  11526. SHAR_EOF
  11527. true || echo 'restore of Makefile.dist failed'
  11528. rm -f _shar_wnt_.tmp
  11529. fi
  11530. rm -f _shar_seq_.tmp
  11531. echo You have unpacked the last part
  11532. exit 0
  11533.  
  11534. From icon-group-request@arizona.edu  Tue Jan  1 21:52:26 1991
  11535. Resent-From: icon-group-request@arizona.edu
  11536. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  11537.     id AA14625; Tue, 1 Jan 91 21:52:26 -0700
  11538. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 1 Jan 91 21:51 MST
  11539. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29795; Tue, 1 Jan 91 20:44:06
  11540.  -0800
  11541. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11542.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  11543.  usenet@ucbvax.Berkeley.EDU if you have questions)
  11544. Resent-Date: Tue, 1 Jan 91 21:51 MST
  11545. Date: 2 Jan 91 02:55:23 GMT
  11546. From: netnews.upenn.edu!msuinfo!midway!quads.uchicago.edu!goer@rutgers.edu
  11547. Subject: bj, part 2 of 3
  11548. Sender: icon-group-request@arizona.edu
  11549. Resent-To: icon-group@cs.arizona.edu
  11550. To: icon-group@arizona.edu
  11551. Resent-Message-Id: <DEC4AF716E39400484@Arizona.edu>
  11552. Message-Id: <1991Jan2.025523.21456@midway.uchicago.edu>
  11553. Organization: University of Chicago
  11554. X-Envelope-To: icon-group@CS.Arizona.EDU
  11555. X-Vms-To: icon-group@Arizona.edu
  11556. References: <1991Jan2.025428.21379@midway.uchicago.edu>
  11557.  
  11558.  
  11559. stty: Operation not supported on socket
  11560. ---- Cut Here and feed the following to sh ----
  11561. #!/bin/sh
  11562. # this is bj.02 (part 2 of a multipart archive)
  11563. # do not concatenate these parts, unpack them in order with /bin/sh
  11564. # file itlib.icn continued
  11565. #
  11566. if test ! -r _shar_seq_.tmp; then
  11567.     echo 'Please unpack part 1 first!'
  11568.     exit 1
  11569. fi
  11570. (read Scheck
  11571.  if test "$Scheck" != 2; then
  11572.     echo Please unpack part "$Scheck" next!
  11573.     exit 1
  11574.  else
  11575.     exit 0
  11576.  fi
  11577. ) < _shar_seq_.tmp || exit 1
  11578. if test ! -f _shar_wnt_.tmp; then
  11579.     echo 'x - still skipping itlib.icn'
  11580. else
  11581. echo 'x - continuing file itlib.icn'
  11582. sed 's/^X//' << 'SHAR_EOF' >> 'itlib.icn' &&
  11583. X                     (tab(find(":")+1), tab(0)))
  11584. X            return entry
  11585. X            }
  11586. X            else {
  11587. X            \line := &null # must precede the next line
  11588. X            entry ||:= trim(trim(tab(0),'\\'),':')
  11589. X            }
  11590. X        }
  11591. X        }
  11592. X    }
  11593. X    }
  11594. X
  11595. X    close(f)
  11596. X    er("getentry","can't find and/or process your termcap entry",3)
  11597. Xend
  11598. X
  11599. X
  11600. X
  11601. Xprocedure read_file(f)
  11602. X
  11603. X    # Suspends all non #-initial lines in the file f.
  11604. X    # Removes leading tabs and spaces from lines before suspending
  11605. X    # them.
  11606. X
  11607. X    local line
  11608. X
  11609. X    \f | er("read_tcap_file","no valid termcap file found",3)
  11610. X    while line := read(f) do {
  11611. X    match("#",line) & next
  11612. X    line ?:= (tab(many('\t ')) | &null, tab(0))
  11613. X    suspend line
  11614. X    }
  11615. X
  11616. X    fail
  11617. X
  11618. Xend
  11619. X
  11620. X
  11621. X
  11622. Xprocedure maketc_table(entry)
  11623. X
  11624. X    # Maketc_table(s) (where s is a valid termcap entry for some
  11625. X    # terminal-type): Returns a table in which the keys are termcap
  11626. X    # capability designators, and the values are the entries in
  11627. X    # "entry" for those designators.
  11628. X
  11629. X    local k, v
  11630. X
  11631. X    /entry & er("maketc_table","no entry given",8)
  11632. X    if entry[-1] ~== ":" then entry ||:= ":"
  11633. X    
  11634. X    /tc_table := table()
  11635. X
  11636. X    entry ? {
  11637. X
  11638. X    tab(find(":")+1)    # tab past initial (name) field
  11639. X
  11640. X    while tab((find(":")+1) \ 1) ? {
  11641. X        &subject == "" & next
  11642. X        if k := 1(move(2), ="=")
  11643. X        then tc_table[k] := Decode(tab(find(":")))
  11644. X        else if k := 1(move(2), ="#")
  11645. X        then tc_table[k] := integer(tab(find(":")))
  11646. X        else if k := 1(tab(find(":")), pos(-1))
  11647. X        then tc_table[k] := true()
  11648. X        else er("maketc_table", "your termcap file has a bad entry",3)
  11649. X    }
  11650. X    }
  11651. X
  11652. X    return tc_table
  11653. X
  11654. Xend
  11655. X
  11656. X
  11657. X
  11658. Xprocedure getval(id)
  11659. X
  11660. X    /tc_table := maketc_table(getentry(getname())) |
  11661. X    er("getval","can't make a table for your terminal",4)
  11662. X
  11663. X    return \tc_table[id] | fail
  11664. X    # er("getval","the current terminal doesn't support "||id,7)
  11665. X
  11666. Xend
  11667. X
  11668. X
  11669. X
  11670. Xprocedure Decode(s)
  11671. X
  11672. X    # Does things like turn ^ plus a letter into a genuine control
  11673. X    # character.
  11674. X
  11675. X    new_s := ""
  11676. X
  11677. X    s ? {
  11678. X
  11679. X    while new_s ||:= tab(upto('\\^')) do {
  11680. X        chr := move(1)
  11681. X        if chr == "\\" then {
  11682. X        new_s ||:= {
  11683. X            case chr2 := move(1) of {
  11684. X            "\\" : "\\"
  11685. X            "^"  : "^"
  11686. X            "E"  : "\e"
  11687. X            "b"  : "\b"
  11688. X            "f"  : "\f"
  11689. X            "n"  : "\n"
  11690. X            "r"  : "\r"
  11691. X            "t"  : "\t"
  11692. X            default : {
  11693. X                if any(&digits,chr2) then {
  11694. X                char(integer("8r"||chr2||move(2 to 0 by -1))) |
  11695. X                    er("Decode","bad termcap entry",3)
  11696. X                }
  11697. X               else chr2
  11698. X            }
  11699. X            }
  11700. X        }
  11701. X        }
  11702. X        else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  11703. X    }
  11704. X    new_s ||:= tab(0)
  11705. X    }
  11706. X
  11707. X    return new_s
  11708. X
  11709. Xend
  11710. X
  11711. X
  11712. X
  11713. Xprocedure igoto(cm,col,line)
  11714. X
  11715. X    local colline, range, increment, str, outstr, chr, x, y
  11716. X
  11717. X    if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  11718. X    colline := string(\col) || "," || string(\line) | string(\col|line)
  11719. X    range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  11720. X    er("igoto",colline || " out of range " || (\range|""),9)
  11721. X    } 
  11722. X
  11723. X    # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
  11724. X    increment := -1
  11725. X    outstr := ""
  11726. X    
  11727. X    cm ? {
  11728. X    while outstr ||:= tab(find("%")) do {
  11729. X        tab(match("%"))
  11730. X        chr := move(1)
  11731. X        if case chr of {
  11732. X        "." :  outstr ||:= char(line + increment)
  11733. X        "+" :  outstr ||:= char(line + ord(move(1)) + increment)
  11734. X        "d" :  {
  11735. X            str := string(line + increment)
  11736. X            outstr ||:= right(str, integer(tab(any('23'))), "0") | str
  11737. X        }
  11738. X        }
  11739. X        then line :=: col
  11740. X        else {
  11741. X        case chr of {
  11742. X            "n" :  line := ixor(line,96) & col := ixor(col,96)
  11743. X            "i" :  increment := 0
  11744. X            "r" :  line :=: col
  11745. X            "%" :  outstr ||:= "%"
  11746. X            "B" :  line := ior(ishift(line / 10, 4), line % 10)
  11747. X            ">" :  {
  11748. X            x := move(1); y := move(1)
  11749. X            line > ord(x) & line +:= ord(y)
  11750. X            &null
  11751. X            }
  11752. X        } | er("goto","bad termcap entry",5)
  11753. X        }
  11754. X    }
  11755. X    return outstr || tab(0)
  11756. X    }
  11757. X
  11758. Xend
  11759. X
  11760. X
  11761. X
  11762. Xprocedure iputs(cp, affcnt)
  11763. X
  11764. X    local baud_rates, char_rates, i, delay, PC
  11765. X    static num_chars, char_times
  11766. X    # global tty_speed
  11767. X
  11768. X    initial {
  11769. X    num_chars := &digits ++ '.'
  11770. X    char_times := table()
  11771. X    # Baud rates in decimal, not octal (as in termio.h)
  11772. X    baud_rates := [0,7,8,9,10,11,12,13,14,15]
  11773. X    char_rates := [0,333,166,83,55,41,20,10,10,10]
  11774. X    every i := 1 to *baud_rates do {
  11775. X        char_times[baud_rates[i]] := char_rates[i]
  11776. X    }
  11777. X    }
  11778. X
  11779. X    type(cp) == "string" |
  11780. X    er("iputs","you can't iputs() a non-string value!",10)
  11781. X
  11782. X    cp ? {
  11783. X    delay := tab(many(num_chars))
  11784. X    if ="*" then {
  11785. X        delay *:= \affcnt |
  11786. X        er("iputs","affected line count missing",6)
  11787. X    }
  11788. X    writes(tab(0))
  11789. X    }
  11790. X
  11791. X    if (\delay, tty_speed ~= 0) then {
  11792. X    PC := tc_table["pc"] | "\000"
  11793. X    char_time := char_times[tty_speed] | (return "speed error")
  11794. X    delay := (delay * char_time) + (char_time / 2)
  11795. X    every 1 to delay by 10
  11796. X    do writes(PC)
  11797. X    }
  11798. X
  11799. X    return
  11800. X
  11801. Xend
  11802. X
  11803. X
  11804. X
  11805. Xprocedure getspeed()
  11806. X
  11807. X    local stty_g, stty_output, c_cflag, o_speed
  11808. X
  11809. X    stty_g := open("/bin/stty -g 2>&1","pr") |
  11810. X    er("getspeed","Can't access your stty command.",4)
  11811. X    stty_output := !stty_g
  11812. X    close(stty_g)
  11813. X
  11814. X    \stty_output ? {
  11815. X    # tab to the third field of the output of the stty -g cmd
  11816. X        tab(find(":")+1) & tab(find(":")+1) &
  11817. X    c_cflag := integer("16r"||tab(find(":")))
  11818. X    } | er("getspeed","Unable to unwind your stty -g output.",4)
  11819. X
  11820. X    o_speed := iand(15,c_cflag)
  11821. X    return o_speed
  11822. X
  11823. Xend
  11824. SHAR_EOF
  11825. echo 'File itlib.icn is complete' &&
  11826. true || echo 'restore of itlib.icn failed'
  11827. rm -f _shar_wnt_.tmp
  11828. fi
  11829. # ============= itlibdos.icn ==============
  11830. if test -f 'itlibdos.icn' -a X"$1" != X"-c"; then
  11831.     echo 'x - skipping itlibdos.icn (File already exists)'
  11832.     rm -f _shar_wnt_.tmp
  11833. else
  11834. > _shar_wnt_.tmp
  11835. echo 'x - extracting itlibdos.icn (Text)'
  11836. sed 's/^X//' << 'SHAR_EOF' > 'itlibdos.icn' &&
  11837. X##########################################################################
  11838. X#    
  11839. X#    Name:    itlibdos.icn
  11840. X#    
  11841. X#    Title:    Icon termlib-type tools (MS-DOS version)
  11842. X#    
  11843. X#    Author:    Richard L. Goerwitz
  11844. X#
  11845. X#    Version: 1.12
  11846. X#
  11847. X###########################################################################
  11848. X#
  11849. X#  I place this and future versions of itlibdos in the public domain - RLG
  11850. X#
  11851. X###########################################################################
  11852. X#
  11853. X#  The following library represents a series of rough functional
  11854. X#  equivalents to the standard Unix low-level termcap routines.  They
  11855. X#  are not meant as exact termlib clones.  Nor are they enhanced to
  11856. X#  take care of magic cookie terminals, terminals that use \D in their
  11857. X#  termcap entries, or, in short, anything I felt would not affect my
  11858. X#  normal, day-to-day work with ANSI and vt100 terminals.
  11859. X#
  11860. X#  Requires:  An MS-DOS platform & co-expressions.  The MS-DOS version
  11861. X#  is a port of the Unix version.  Software you write for this library
  11862. X#  can be made to run under Unix simply by substituting the Unix ver-
  11863. X#  sion of this library.  See below for additional notes on how to use
  11864. X#  this MS-DOS port.
  11865. X#
  11866. X#  setname(term)
  11867. X#    Use only if you wish to initialize itermlib for a terminal
  11868. X#  other than what your current environment specifies.  "Term" is the
  11869. X#  name of the termcap entry to use.  Normally this initialization is
  11870. X#  done automatically, and need not concern the user.
  11871. X#
  11872. X#  getval(id)
  11873. X#    Works something like tgetnum, tgetflag, and tgetstr.  In the
  11874. X#  spirit of Icon, all three have been collapsed into one routine.
  11875. X#  Integer valued caps are returned as integers, strings as strings,
  11876. X#  and flags as records (if a flag is set, then type(flag) will return
  11877. X#  "true").  Absence of a given capability is signalled by procedure
  11878. X#  failure.
  11879. X#
  11880. X#  igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
  11881. X#    Analogous to tgoto.  "Cm" is the cursor movement command for
  11882. X#  the current terminal, as obtained via getval("cm").  Igoto()
  11883. X#  returns a string which, when output via iputs, will cause the
  11884. X#  cursor to move to column "destcol" and line "destline."  Column and
  11885. X#  line are always calculated using a *one* offset.  This is far more
  11886. X#  Iconish than the normal zero offset used by tgoto.  If you want to
  11887. X#  go to the first square on your screen, then include in your program
  11888. X#  "iputs(igoto(getval("cm"),1,1))."
  11889. X#
  11890. X#  iputs(cp,affcnt)
  11891. X#    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  11892. X#  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  11893. X#  count of affected lines.  It is only relevant for terminals which
  11894. X#  specify proportional (starred) delays in their termcap entries.
  11895. X#
  11896. X#  Notes on the MS-DOS version:
  11897. X#    There are two basic reasons for using the I/O routines
  11898. X#  contained in this package.  First, by using a set of generalized
  11899. X#  routines, your code will become much more readable.  Secondly, by
  11900. X#  using a high level interface, you can avoid the cardinal
  11901. X#  programming error of hard coding things like screen length and
  11902. X#  escape codes into your programs.
  11903. X#    To use this collection of programs, you must do two things.
  11904. X#  First, you must add the line "device=ansi.sys" (or the name of some
  11905. X#  other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new
  11906. X#  nansi.sys]) to your config.sys file.  Secondly, you must add two
  11907. X#  lines to your autoexec.bat file:  1) "set TERM=ansi-mono" and 2)
  11908. X#  "set TERMCAP=\location\termcap."  The purpose of setting the TERM
  11909. X#  variable is to tell this program what driver you are using.  If you
  11910. X#  have a color system, use "ansi-color" instead of "ansi-mono," and
  11911. X#  if you are using nansi or zansi instead of vanilla ansi, use one of
  11912. X#  these names instead of the "ansi" (e.g. "zansi-mono").  The purpose
  11913. X#  of setting TERMCAP is to make it possible to determine where the
  11914. X#  termcap file is located.  The termcap file (which should have been
  11915. X#  packed with this library as termcap.dos) is a short database of all
  11916. X#  the escape sequences used by the various terminal drivers.  Set
  11917. X#  TERMCAP so that it reflects the location of this file (which should
  11918. X#  be renamed as termcap, for the sake of consistency with the Unix
  11919. X#  version).  Naturally, you must change "\location\" above to reflect
  11920. X#  the correct path on your system.
  11921. X#    Although I make no pretense here of providing here a complete
  11922. X#  introduction to the format of the termcap database file, it will be
  11923. X#  useful, I think, to explain a few basic facts about how to use this
  11924. X#  program in conjunction with it.  If, say, you want to clear the
  11925. X#  screen, add the line,
  11926. X#
  11927. X#    iputs(getval("cl"))
  11928. X#
  11929. X#  to your program.  The function iputs() outputs screen control
  11930. X#  sequences.  Getval retrieves a specific sequence from the termcap
  11931. X#  file.  The string "cl" is the symbol used in the termcap file to
  11932. X#  mark the code used to clear the screen.  By executing the
  11933. X#  expression "iputs(getval("cl"))," you are 1) looking up the "cl"
  11934. X#  (clear) code in the termcap database entry for your terminal, and
  11935. X#  the 2) outputting that sequence to the screen.
  11936. X#    Some other useful termcap symbols are "ce" (clear to end of
  11937. X#  line), "ho" (go to the top left square on the screen), "so" (begin
  11938. X#  standout mode), and "se" (end standout mode).  To output a
  11939. X#  boldfaced string, str, to the screen, you would write -
  11940. X#
  11941. X#    iputs(getval("so"))
  11942. X#    writes(str)
  11943. X#    iputs(getval("se"))
  11944. X#
  11945. X#  You could write "iputs(getval("so") || str || getval("se")), but
  11946. X#  this would only work for DOS.  Some Unix terminals require padding,
  11947. X#  and iputs() handles them specially.  Normally you should not worry
  11948. X#  about Unix quirks under DOS.  It is in general wise, though, to
  11949. X#  separate out screen control sequences, and output them via iputs().
  11950. X#    It is also heartily to be recommended that MS-DOS programmers
  11951. X#  try not to assume that everyone will be using a 25-line screen.
  11952. X#  Some terminals are 24-line.  Some 43.  Some have variable window
  11953. X#  sizes.  If you want to put a status line on, say, the 2nd-to-last
  11954. X#  line of the screen, then determine what that line is by executing
  11955. X#  "getval("li")."  The termcap database holds not only string-valued
  11956. X#  sequences, but numeric ones as well.  The value of "li" tells you
  11957. X#  how many lines the terminal has (compare "co," which will tell you
  11958. X#  how many columns).  To go to the beginning of the second-to-last
  11959. X#  line on the screen, type in:
  11960. X#
  11961. X#    iputs(igoto(getval("cm"), 1, getval("li")-1))
  11962. X#
  11963. X#  The "cm" capability is a special capability, and needs to be output
  11964. X#  via igoto(cm,x,y), where cm is the sequence telling your computer
  11965. X#  to move the cursor to a specified spot, x is the column, and y is
  11966. X#  the row.  The expression "getval("li")-1" will return the number of
  11967. X#  the second-to-last line on your screen.
  11968. X#
  11969. X##########################################################################
  11970. X#
  11971. X#  Requires: MS-DOS, coexpressions
  11972. X#
  11973. X#  See also: iscreen.icn (a set of companion utilities) 
  11974. X#
  11975. X##########################################################################
  11976. X
  11977. X
  11978. Xglobal tc_table
  11979. Xrecord true()
  11980. X
  11981. X
  11982. Xprocedure check_features()
  11983. X
  11984. X    local in_params, line
  11985. X
  11986. X    initial {
  11987. X    find("ms-dos",map(&features)) |
  11988. X        er("check_features","MS-DOS system required",1)
  11989. X    find("o-expres",&features) |
  11990. X        er("check_features","co-expressions not implemented - &$#!",1)
  11991. X    }
  11992. X
  11993. X    return
  11994. X
  11995. Xend
  11996. X
  11997. X
  11998. X
  11999. Xprocedure setname(name)
  12000. X
  12001. X    # Sets current terminal type to "name" and builds a new termcap
  12002. X    # capability database (residing in tc_table).  Fails if unable to
  12003. X    # find a termcap entry for terminal type "name."  If you want it
  12004. X    # to terminate with an error message under these circumstances,
  12005. X    # comment out "| fail" below, and uncomment the er() line.
  12006. X
  12007. X    #tc_table is global
  12008. X    
  12009. X    check_features()
  12010. X
  12011. X    tc_table := maketc_table(getentry(name)) | fail
  12012. X    # er("setname","no termcap entry found for "||name,3)
  12013. X    return
  12014. X
  12015. Xend
  12016. X
  12017. X
  12018. X
  12019. Xprocedure getname()
  12020. X
  12021. X    # Getname() first checks to be sure we're running under DOS, and,
  12022. X    # if so, tries to figure out what the current terminal type is,
  12023. X    # checking the value of the environment variable TERM, and if this
  12024. X    # is unsuccessful, defaulting to "mono."
  12025. X
  12026. X    local term, tset_output
  12027. X
  12028. X    check_features()
  12029. X    term := getenv("TERM") | "mono"
  12030. X    
  12031. X    return \term |
  12032. X    er("getname","can't seem to determine your terminal type",1)
  12033. X
  12034. Xend
  12035. X
  12036. X
  12037. X
  12038. Xprocedure er(func,msg,errnum)
  12039. X
  12040. X    # short error processing utility
  12041. X    write(&errout,func,":  ",msg)
  12042. X    exit(errnum)
  12043. X
  12044. Xend
  12045. X
  12046. X
  12047. X
  12048. Xprocedure getentry(name, termcap_string)
  12049. X
  12050. X    # "Name" designates the current terminal type.  Getentry() scans
  12051. X    # the current environment for the variable TERMCAP.  If the
  12052. X    # TERMCAP string represents a termcap entry for a terminal of type
  12053. X    # "name," then getentry() returns the TERMCAP string.  Otherwise,
  12054. X    # getentry() will check to see if TERMCAP is a file name.  If so,
  12055. X    # getentry() will scan that file for an entry corresponding to
  12056. X    # "name."  If the TERMCAP string does not designate a filename,
  12057. X    # getentry() will look through ./termcap for the correct entry.
  12058. X    # Whatever the input file, if an entry for terminal "name" is
  12059. X    # found, getentry() returns that entry.  Otherwise, getentry()
  12060. X    # fails.
  12061. X
  12062. X    local f, getline, line, nm, ent1, ent2
  12063. X
  12064. X    /termcap_string := getenv("TERMCAP")
  12065. X
  12066. X    if \termcap_string ? (not match("\\"), pos(0) | tab(find("|")+1), =name)
  12067. X    then return termcap_string
  12068. X    else {
  12069. X
  12070. X    # The logic here probably isn't clear.  The idea is to try to use
  12071. X    # the termcap environment variable successively as 1) a termcap en-
  12072. X    # try and then 2) as a termcap file.  If neither works, 3) go to
  12073. X    # the ./termcap file.  The else clause here does 2 and, if ne-
  12074. X    # cessary, 3.  The "\termcap_string ? (not match..." expression
  12075. X    # handles 1.
  12076. X
  12077. X    if find("\\",\termcap_string)
  12078. X    then f := open(termcap_string)
  12079. X    /f := open("termcap") |
  12080. X        er("getentry","I can't access your termcap file",1)
  12081. X
  12082. X    getline := create read_file(f)
  12083. X    
  12084. X    while line := @getline do {
  12085. X        if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
  12086. X        entry := ""
  12087. X        while (\line | @getline) ? {
  12088. X            if entry ||:= 1(tab(find(":")+1), pos(0))
  12089. X            then {
  12090. X            close(f)
  12091. X            # if entry ends in tc= then add in the named tc entry
  12092. X            entry ?:= tab(find("tc=")) ||
  12093. X                # recursively fetch the new termcap entry
  12094. X                (move(3), getentry(tab(find(":"))) ?
  12095. X                    # remove the name field from the new entry
  12096. X                     (tab(find(":")+1), tab(0)))
  12097. X            return entry
  12098. X            }
  12099. X            else {
  12100. X            \line := &null # must precede the next line
  12101. X            entry ||:= trim(trim(tab(0),'\\'),':')
  12102. X            }
  12103. X        }
  12104. X        }
  12105. X    }
  12106. X    }
  12107. X
  12108. X    close(f)
  12109. X    er("getentry","can't find and/or process your termcap entry",3)
  12110. Xend
  12111. X
  12112. X
  12113. X
  12114. Xprocedure read_file(f)
  12115. X
  12116. X    # Suspends all non #-initial lines in the file f.
  12117. X    # Removes leading tabs and spaces from lines before suspending
  12118. X    # them.
  12119. X
  12120. X    local line
  12121. X
  12122. X    \f | er("read_tcap_file","no valid termcap file found",3)
  12123. X    while line := read(f) do {
  12124. X    match("#",line) & next
  12125. X    line ?:= (tab(many('\t ')) | &null, tab(0))
  12126. X    suspend line
  12127. X    }
  12128. X
  12129. X    fail
  12130. X
  12131. Xend
  12132. X
  12133. X
  12134. X
  12135. Xprocedure maketc_table(entry)
  12136. X
  12137. X    # Maketc_table(s) (where s is a valid termcap entry for some
  12138. X    # terminal-type): Returns a table in which the keys are termcap
  12139. X    # capability designators, and the values are the entries in
  12140. X    # "entry" for those designators.
  12141. X
  12142. X    local k, v
  12143. X
  12144. X    /entry & er("maketc_table","no entry given",8)
  12145. X    if entry[-1] ~== ":" then entry ||:= ":"
  12146. X    
  12147. X    tc_table := table()
  12148. X
  12149. X    entry ? {
  12150. X
  12151. X    tab(find(":")+1)    # tab past initial (name) field
  12152. X
  12153. X    while tab((find(":")+1) \ 1) ? {
  12154. X
  12155. X        &subject == "" & next
  12156. X        if k := 1(move(2), ="=")
  12157. X        then tc_table[k] := Decode(tab(find(":")))
  12158. X        else if k := 1(move(2), ="#")
  12159. X        then tc_table[k] := integer(tab(find(":")))
  12160. X        else if k := 1(tab(find(":")), pos(-1))
  12161. X        then tc_table[k] := true()
  12162. X        else er("maketc_table", "your termcap file has a bad entry",3)
  12163. X    }
  12164. X    }
  12165. X
  12166. X    return tc_table
  12167. X
  12168. Xend
  12169. X
  12170. X
  12171. X
  12172. Xprocedure getval(id)
  12173. X
  12174. X    /tc_table := maketc_table(getentry(getname())) |
  12175. X    er("getval","can't make a table for your terminal",4)
  12176. X
  12177. X    return \tc_table[id] | fail
  12178. X    # er("getval","the current terminal doesn't support "||id,7)
  12179. X
  12180. Xend
  12181. X
  12182. X
  12183. X
  12184. Xprocedure Decode(s)
  12185. X
  12186. X    # Does things like turn ^ plus a letter into a genuine control
  12187. X    # character.
  12188. X
  12189. X    new_s := ""
  12190. X
  12191. X    s ? {
  12192. X    while new_s ||:= tab(upto('\\^')) do {
  12193. X        chr := move(1)
  12194. X        if chr == "\\" then {
  12195. X        new_s ||:= {
  12196. X            case chr2 := move(1) of {
  12197. X            "\\" : "\\"
  12198. X            "^"  : "^"
  12199. X            "E"  : "\e"
  12200. X            "b"  : "\b"
  12201. X            "f"  : "\f"
  12202. X            "n"  : "\n"
  12203. X            "r"  : "\r"
  12204. X            "t"  : "\t"
  12205. X            default : {
  12206. X                if any(&digits,chr2) then {
  12207. X                char(integer("8r"||chr2||move(2 to 0 by -1))) |
  12208. X                    er("Decode","bad termcap entry",3)
  12209. X                }
  12210. X               else chr2
  12211. X            }
  12212. X            }
  12213. X        }
  12214. X        }
  12215. X        else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  12216. X    }
  12217. X    new_s ||:= tab(0)
  12218. X    }
  12219. X
  12220. X    return new_s
  12221. X
  12222. Xend
  12223. X
  12224. X
  12225. X
  12226. Xprocedure igoto(cm,col,line)
  12227. X
  12228. X    local colline, range, increment, str, outstr, chr, x, y
  12229. X
  12230. X    if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  12231. X    colline := string(\col) || "," || string(\line) | string(\col|line)
  12232. SHAR_EOF
  12233. true || echo 'restore of itlibdos.icn failed'
  12234. fi
  12235. echo 'End of  part 2'
  12236. echo 'File itlibdos.icn is continued in part 3'
  12237. echo 3 > _shar_seq_.tmp
  12238. exit 0
  12239.  
  12240. From icon-group-request@arizona.edu  Tue Jan  1 21:52:55 1991
  12241. Resent-From: icon-group-request@arizona.edu
  12242. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  12243.     id AA14640; Tue, 1 Jan 91 21:52:55 -0700
  12244. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 1 Jan 91 21:51 MST
  12245. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29778; Tue, 1 Jan 91 20:43:37
  12246.  -0800
  12247. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  12248.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  12249.  usenet@ucbvax.Berkeley.EDU if you have questions)
  12250. Resent-Date: Tue, 1 Jan 91 21:52 MST
  12251. Date: 2 Jan 91 02:54:28 GMT
  12252. From: netnews.upenn.edu!msuinfo!midway!quads.uchicago.edu!goer@rutgers.edu
  12253. Subject: UNIX port of bj, part 1 of 3
  12254. Sender: icon-group-request@arizona.edu
  12255. Resent-To: icon-group@cs.arizona.edu
  12256. To: icon-group@arizona.edu
  12257. Resent-Message-Id: <DEC49C5CF08940048B@Arizona.edu>
  12258. Message-Id: <1991Jan2.025428.21379@midway.uchicago.edu>
  12259. Organization: University of Chicago
  12260. X-Envelope-To: icon-group@CS.Arizona.EDU
  12261. X-Vms-To: icon-group@Arizona.edu
  12262.  
  12263. Tenaglia's blackjack game was very cleanly written, and I ported
  12264. it before dinner tonight.  Some of the character graphics and fonts
  12265. couldn't be reproduced portably using standard Unix terminals, so
  12266. I had to remove them.  Oh well.
  12267.  
  12268. Needless to say, I haven't tested this program terribly thoroughly
  12269. on any system but my own, and even there some bugs might remain.
  12270. Still, I don't expect that anyone will encounter any big problems
  12271. running it (or fixing it up).
  12272.  
  12273. It's a nice game.  In fact, I must hurry up, since my son is breathing
  12274. down my neck to let him have the console so that he can run it here at
  12275. home.  Here's the first of three shell archives.
  12276.  
  12277. -Richard (goer@sophist.uchicago.edu)
  12278.  
  12279.  
  12280. stty: Operation not supported on socket
  12281. ---- Cut Here and feed the following to sh ----
  12282. #!/bin/sh
  12283. # This is a shell archive (produced by shar 3.49)
  12284. # To extract the files from this archive, save it to a file, remove
  12285. # everything above the "!/bin/sh" line above, and type "sh file_name".
  12286. #
  12287. # made 01/02/1991 02:37 UTC by goer@sophist.uchicago.edu
  12288. # Source directory /u/richard/Bj
  12289. #
  12290. # existing files will NOT be overwritten unless -c is specified
  12291. # This format requires very little intelligence at unshar time.
  12292. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  12293. #
  12294. # This is part 1 of a multipart archive                                    
  12295. # do not concatenate these parts, unpack them in order with /bin/sh        
  12296. #
  12297. # This shar contains:
  12298. # length  mode       name
  12299. # ------ ---------- ------------------------------------------
  12300. #  10389 -r--r--r-- bj.icn
  12301. #  12240 -r--r--r-- itlib.icn
  12302. #  14586 -r--r--r-- itlibdos.icn
  12303. #   2391 -r--r--r-- termcap.dos
  12304. #   1654 -rw-r--r-- README
  12305. #    754 -rw-r--r-- Makefile.dist
  12306. #
  12307. if test -r _shar_seq_.tmp; then
  12308.     echo 'Must unpack archives in sequence!'
  12309.     echo Please unpack part `cat _shar_seq_.tmp` next
  12310.     exit 1
  12311. fi
  12312. # ============= bj.icn ==============
  12313. if test -f 'bj.icn' -a X"$1" != X"-c"; then
  12314.     echo 'x - skipping bj.icn (File already exists)'
  12315.     rm -f _shar_wnt_.tmp
  12316. else
  12317. > _shar_wnt_.tmp
  12318. echo 'x - extracting bj.icn (Text)'
  12319. sed 's/^X//' << 'SHAR_EOF' > 'bj.icn' &&
  12320. X############################################################################
  12321. X#
  12322. X#    Names:     bj.icn
  12323. X#
  12324. X#    Title:     blackjack game
  12325. X#
  12326. X#    Author:     Chris Tenaglia (modified by Richard L. Goerwitz)
  12327. X#
  12328. X#    Version: 1.1
  12329. X#
  12330. X############################################################################
  12331. X#  
  12332. X#  Simple but fun blackjack game.  The original version was for an ANSI
  12333. X#  screen.  This version has been modified to work with the Unix termcap
  12334. X#  database file.
  12335. X#
  12336. X############################################################################
  12337. X#
  12338. X#  Links: 
  12339. X#
  12340. X############################################################################
  12341. X
  12342. Xglobal deck, message, lookup,
  12343. X       user_money,  host_money,
  12344. X       user_hand,   host_hand
  12345. X
  12346. Xprocedure main(param)
  12347. X  user_money := integer(param[1]) | 3 ; host_money := user_money
  12348. X  write(screen("cls"))
  12349. X#  Most terminals don't do oversize characters like this.
  12350. X#  write(screen("cls"),"               ",screen("top"),screen("hinv"),
  12351. X#        "BLACK JACK",screen("norm"))
  12352. X#  write("               ",screen("bot"),screen("hinv"),
  12353. X#        "BLACK JACK",screen("norm"))
  12354. X  write(screen("high"),"  ---- BLACK JACK ----",screen("norm"))
  12355. X  bonus := 0
  12356. X  repeat
  12357. X    {
  12358. X    if not any('y',(map(input(at(1,3) || "  " || screen("under") ||
  12359. X                   "Play a game? y/n : "|| screen("norm") ||
  12360. X                   screen("eeol")))[1])) then break
  12361. X    every writes(at(1,3|4),screen("eeos"))
  12362. X    display_score()
  12363. X    deck    := shuffle()
  12364. X    message := ""
  12365. X    user_hand := []          ; host_hand := []
  12366. X    put(user_hand,pop(deck)) ; put(host_hand,pop(deck))
  12367. X    put(user_hand,pop(deck)) ; put(host_hand,pop(deck))
  12368. X    user_points := first(host_hand[1])
  12369. X    if user_points > 21 then
  12370. X      {
  12371. X      writes(at(1,13),user_points," points. You went over. You lose.")
  12372. X      user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0
  12373. X      display_score()
  12374. X      next
  12375. X      }
  12376. X    display_host(2)
  12377. X    host_points := second(user_points)
  12378. X    if host_points > 21 then
  12379. X      {
  12380. X      writes(at(50,22),host_points," points. ",&host ? tab(find(" ")),
  12381. X         " went over.")
  12382. X      writes(at(1,13),screen("hiblink"),"You win.",screen("norm"))
  12383. X      host_money -:= 1 ; user_money +:= 1 + bonus ; bonus := 0
  12384. X      display_score()
  12385. X      next
  12386. X      }
  12387. X    if host_points = user_points then
  12388. X      {
  12389. X      writes(at(1,22),screen("hiblink"),"It's a draw at ",user_points,
  12390. X            ". The ANTY goes to bonus.",screen("norm"))
  12391. X      bonus +:= 2 ; host_money -:= 1 ; user_money -:= 1
  12392. X      display_score()
  12393. X      next
  12394. X      }
  12395. X    writes(at(20,12),user_points," points for user.")
  12396. X    writes(at(1,14),host_points," points for ",&host ? tab(find(" ")))
  12397. X    if user_points < host_points then
  12398. X      {
  12399. X      write(at(1,22),screen("hiblink"),&host ? tab(find(" "))," wins.",
  12400. X            screen("norm"),screen("eeol"))
  12401. X      user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0
  12402. X      display_score()
  12403. X      next
  12404. X      } else {
  12405. X      writes(at(1,12),screen("hiblink"),"You win.",screen("norm"),
  12406. X         screen("eeol"))
  12407. X      user_money +:= 1 + bonus ; host_money -:= 1 ; bonus := 0
  12408. X      display_score()
  12409. X      next
  12410. X      }
  12411. X    }
  12412. X  write(screen("clear"))
  12413. X  end
  12414. X
  12415. X#
  12416. X# THIS PROCEDURE ALLOWS THE USER TO PLAY AND TAKE HITS
  12417. X#
  12418. Xprocedure first(host_card)
  12419. X  display_user()
  12420. X  display_host(1)
  12421. X  points := value(user_hand)   # just in case
  12422. X  writes(at(1,9),"(",points,") ")
  12423. X  repeat
  12424. X    if any('hy',map(input(at(1,23) || "Hit ? y/n : " || screen("eeol")))) then
  12425. X      {
  12426. X      put(user_hand,pop(deck))
  12427. X      display_user()
  12428. X      if (points := value(user_hand)) > 21 then return points
  12429. X      writes(at(1,9),"(",points,") ")
  12430. X      } else break
  12431. X  (points > 0) | (points := value(user_hand))
  12432. X  writes(at(1,9),"(",points,") ")
  12433. X  write(at(60,11),"You stay with ",points)
  12434. X  return points
  12435. X  end
  12436. X
  12437. X#
  12438. X# THIS SECOND PROCEDURE IS THE HOST PLAYING AGAINST THE USER
  12439. X#
  12440. Xprocedure second(ceiling)
  12441. X  static limits
  12442. X  initial limits := [14,14,15,15,19,16,17,18]
  12443. X  stop_at := ?limits ; points := 0
  12444. X  until (points := value(host_hand)) > stop_at do
  12445. X    {
  12446. X    if points > ceiling then return points
  12447. X    writes(at(1,19),"(",points,") ")
  12448. X#    write(at(1,22),screen("eeol"),&host," will take a hit.",screen("eeol"))
  12449. X    write(at(1,22),screen("eeol"),&host ? tab(find(" ")),
  12450. X      " will take a hit.",screen("eeol"))
  12451. X    put(host_hand,pop(deck))
  12452. X    display_host(2)
  12453. X    }
  12454. X  (points > 0) | (points := value(host_hand))
  12455. X  writes(at(1,19),"(",points,") ")
  12456. X  return points
  12457. X  end
  12458. X
  12459. X#
  12460. X# THIS ROUTINE DISPLAYS THE CURRENT SCORE
  12461. X#
  12462. Xprocedure display_score()
  12463. X  writes(screen("nocursor"))
  12464. X  writes(screen("dim"),at(1,7),"Credits",screen("norm"))
  12465. X  writes(screen("high"),at(1,8),right(user_money,7),screen("norm"))
  12466. X  writes(screen("dim"),at(1,17),"Credits",screen("norm"))
  12467. X  writes(screen("high"),at(1,18),right(host_money,7),screen("norm"))
  12468. X  end
  12469. X#
  12470. X# THIS PROCEDURE EVALUATES THE POINTS OF A HAND. IT TRIES TO MAKE THEM
  12471. X# AS HIGH AS POSSIBLE WITHOUT GOING OVER 21.
  12472. X#
  12473. Xprocedure value(sample)
  12474. X  hand     := copy(sample)
  12475. X  possible := []
  12476. X  repeat
  12477. X    {
  12478. X    sum := 0
  12479. X    every card := !hand do sum +:= lookup[card[1]]
  12480. X    put(possible,sum)
  12481. X    if Aces(hand) == "none" then break else
  12482. X      every i := 1 to *hand do if hand[i][1] == "A" then hand[i][1] := "a"
  12483. X    }
  12484. X  every score := !possible do
  12485. X    if score <= 21 then return score
  12486. X  return possible[1]
  12487. X  end
  12488. X
  12489. X#
  12490. X# ARE THERE ANY 11 POINT ACES LEFT IN HAND
  12491. X#
  12492. Xprocedure Aces(cards)
  12493. X  every look := !cards do if look[1] == "A" then return "some"
  12494. X  return "none"
  12495. X  end
  12496. X
  12497. X#
  12498. X# THIS ROUTINE DISPLAYS THE USER HAND AND STATUS
  12499. X#
  12500. Xprocedure display_user()
  12501. X  writes(screen("nocursor"),at(1,6),screen("hinv"),"USER",screen("norm"))
  12502. X  x := 10 ; y := 4
  12503. X  every card := !user_hand do
  12504. X    {
  12505. X    display(card,x,y)
  12506. X    x +:= 7
  12507. X    }
  12508. X  end
  12509. X
  12510. X#
  12511. X# THIS ROUTINE DISPLAYS THE HOST HAND AND STATUS
  12512. X#
  12513. Xprocedure display_host(flag)
  12514. X  writes(screen("nocursor"),at(1,16),screen("hinv"),
  12515. X     &host ? tab(find(" ")),screen("norm"))
  12516. X  x := 10 ; y := 14 ; /flag := 0
  12517. X  every card := !host_hand do
  12518. X    {
  12519. X    if (flag=1) & (x=10) then card := "XX"
  12520. X    display(card,x,y)
  12521. X    x +:= 7
  12522. X    }
  12523. X  end
  12524. X
  12525. X#
  12526. X# THIS ROUTINE DISPLAYS A GIVEN CARD AT A GIVEN X,Y SCREEN LOCATION
  12527. X#
  12528. Xprocedure display(card,x,y)
  12529. X    all := [] ; j := y
  12530. X    if find(card[2],"CS") then card := screen("hinv") || card || screen("norm")
  12531. X#    shape := [at(x,(j+:=1)) || screen("gchar") || "lqqqqqqqk"]
  12532. X    shape := [at(x,(j+:=1)) || screen("inv") || "         " || screen("norm")]
  12533. X    put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
  12534. X    " " || card || "    " || screen("inv") || " " || screen("norm"))
  12535. X    put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
  12536. X    "       " || screen("inv") || " " || screen("norm"))
  12537. X    put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
  12538. X    "       " || screen("inv") || " " || screen("norm"))
  12539. X    put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
  12540. X    "       " || screen("inv") || " " || screen("norm"))
  12541. X#    put(shape,at(x,(j+:=1)) || "x       x")
  12542. X#    put(shape,at(x,(j+:=1)) || "x       x")
  12543. X    put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
  12544. X    "    " || card || " " || screen("inv") || " " || screen("norm"))
  12545. X#    put(shape,at(x,(j+:=1)) || "mqqqqqqqj" || screen("nchar"))
  12546. X    put(shape,at(x,(j+:=1)) || screen("inv") || "         " || screen("norm"))
  12547. X    put(all,shape)
  12548. X    x +:= 14
  12549. X  while shape := pop(all) do every writes(!shape)
  12550. X  end
  12551. X
  12552. X#
  12553. X# THIS ROUTINE SHUFFLES THE CARD DECK
  12554. X#
  12555. Xprocedure shuffle()
  12556. X  static faces, suits
  12557. X  local cards, i
  12558. X  initial {
  12559. X          &random := map(&clock,":","7")   # initial on multiple shuffles
  12560. X          faces   := ["2","3","4","5","6","7","8","9","T","J","Q","K","A"]
  12561. X          suits   := ["D","H","C","S"]
  12562. X          lookup  := table(0)
  12563. X          every i := 2 to 9 do insert(lookup,string(i),i)
  12564. X          insert(lookup,"T",10)
  12565. X          insert(lookup,"J",10)
  12566. X          insert(lookup,"Q",10)
  12567. X          insert(lookup,"K",10)
  12568. X          insert(lookup,"A",11)
  12569. X          insert(lookup,"a",1)
  12570. X          }
  12571. X  cards   := []
  12572. X  every put(cards,!faces || !suits)
  12573. X  every i := *cards to 2 by -1 do cards[?i] :=: cards[i]
  12574. X  return cards
  12575. X  end
  12576. X
  12577. X#
  12578. X# THIS ROUTINE PARSES A STRING WITH RESPECT TO SOME DELIMITER
  12579. X#
  12580. Xprocedure parse(line,delims)
  12581. X  static chars
  12582. X  chars  := &cset -- delims
  12583. X  tokens := []
  12584. X  line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
  12585. X  return tokens
  12586. X  end
  12587. X
  12588. X#
  12589. X# THIS ROUTINE PROMPTS FOR INPUT AND RETURNS A STRING
  12590. X#
  12591. Xprocedure input(prompt)
  12592. X  writes(screen("cursor"),prompt)
  12593. X  return read()
  12594. X  end
  12595. X
  12596. X
  12597. X#
  12598. X# THIS ROUTINE SETS THE VIDEO OUTPUT ATTRIBUTES FOR VT102 OR LATER
  12599. X# COMPATIBLE TERMINALS.
  12600. X#
  12601. Xprocedure screen(attr)
  12602. X  initial if getval("ug"|"mg"|"sg") > 0 then
  12603. X    er("screen","oops, magic cookie terminal!",34)
  12604. X  return {
  12605. X    case attr of
  12606. X      {
  12607. X      "cls"  : getval("cl")
  12608. X      "clear": getval("cl")
  12609. X      # HIGH INTENSITY & INVERSE
  12610. X      "hinv" : (getval("md") | "") || getval("so")
  12611. X      "norm" : (getval("se") | "") || (getval("me") | "") || (getval("ue")|"")
  12612. X      # LOW INTENSITY VIDEO
  12613. X      "dim"  : getval("mh"|"me")
  12614. X      "blink": getval("mb"|"md"|"so")
  12615. X      # HIGH INTENSITY BLINKING
  12616. X      "hiblink": (getval("md") | "") || getval("mb") | getval("so")
  12617. X      "under": getval("us"|"md"|"so")
  12618. X      "high" : getval("md"|"so"|"ul")
  12619. X      "inv"  : getval("so"|"md"|"ul")
  12620. X      # ERASE TO END OF LINE
  12621. X      "eeol" : getval("ce")
  12622. X      # ERASE TO START OF LINE
  12623. X      "esol" : getval("cb")
  12624. X      # ERASE TO END OF SCREEN
  12625. X      "eeos" : getval("cd")
  12626. X      # MAKE CURSOR INVISIBLE
  12627. X      "cursor": getval("vi"|"CO") | ""
  12628. X      # MAKE CURSOR VISIBLE
  12629. X      "nocursor": getval("ve"|"CF") | ""
  12630. X#      # START ALTERNATE FONT      <- very non-portable
  12631. X#      "gchar": getval("as") | ""
  12632. X#      # END ALTERNATE FONT
  12633. X#      "nchar": getval("ae") | ""
  12634. X#      "light": return "\e[?5h"     # LIGHT COLORED SCREEN
  12635. X#      "dark" : return "\e[?5l"     # DARK  COLORED SCREEN
  12636. X#      "80"   : return "\e[?3l"     # 80    COLUMNS ON SCREEN
  12637. X#      "132"  : return "\e[?3h"     # 132   COLUMNS ON SCREEN
  12638. X#      "smooth": return "\e[?4h"    # SMOOTH SCREEN SCROLLING
  12639. X#      "jump" : return "\e[?4l"     # JUMP   SCREEN SCROLLING
  12640. X      default : er("screen",attr||" is just too weird for most terminals",34)
  12641. X      } | er("screen","I just can't cope with your terminal.",35)
  12642. X    }
  12643. X  end
  12644. X
  12645. X#
  12646. X# THIS ROUTINE SETS THE CURSOR TO A GIVEN X (COL) Y(ROW) SCREEN LOCATION
  12647. X#
  12648. Xprocedure at(x,y)
  12649. X#  return "\e[" || y || ";" || x || "f"
  12650. X  return igoto(getval("cm"),x,y)
  12651. X  end
  12652. X
  12653. SHAR_EOF
  12654. true || echo 'restore of bj.icn failed'
  12655. rm -f _shar_wnt_.tmp
  12656. fi
  12657. # ============= itlib.icn ==============
  12658. if test -f 'itlib.icn' -a X"$1" != X"-c"; then
  12659.     echo 'x - skipping itlib.icn (File already exists)'
  12660.     rm -f _shar_wnt_.tmp
  12661. else
  12662. > _shar_wnt_.tmp
  12663. echo 'x - extracting itlib.icn (Text)'
  12664. sed 's/^X//' << 'SHAR_EOF' > 'itlib.icn' &&
  12665. X########################################################################
  12666. X#    
  12667. X#    Name:    itlib.icn
  12668. X#    
  12669. X#    Title:    Icon termlib-type tools
  12670. X#    
  12671. X#    Author:    Richard L. Goerwitz
  12672. X#
  12673. X#    Version: 1.23
  12674. X#
  12675. X#########################################################################
  12676. X#
  12677. X#  I place this and future versions of itlib in the public domain - RLG
  12678. X#
  12679. X#########################################################################
  12680. X#
  12681. X#  The following library represents a series of rough functional
  12682. X#  equivalents to the standard Unix low-level termcap routines.  They
  12683. X#  are not meant as exact termlib clones.  Nor are they enhanced to
  12684. X#  take care of magic cookie terminals, terminals that use \D in their
  12685. X#  termcap entries, or, in short, anything I felt would not affect my
  12686. X#  normal, day-to-day work with ANSI and vt100 terminals.
  12687. X#
  12688. X#  Requires:  A unix platform & co-expressions.  There is an MS-DOS
  12689. X#  version, itlibdos.icn.
  12690. X#
  12691. X#  setname(term)
  12692. X#    Use only if you wish to initialize itermlib for a terminal
  12693. X#  other than what your current environment specifies.  "Term" is the
  12694. X#  name of the termcap entry to use.  Normally this initialization is
  12695. X#  done automatically, and need not concern the user.
  12696. X#
  12697. X#  getval(id)
  12698. X#    Works something like tgetnum, tgetflag, and tgetstr.  In the
  12699. X#  spirit of Icon, all three have been collapsed into one routine.
  12700. X#  Integer valued caps are returned as integers, strings as strings,
  12701. X#  and flags as records (if a flag is set, then type(flag) will return
  12702. X#  "true").  Absence of a given capability is signalled by procedure
  12703. X#  failure.
  12704. X#
  12705. X#  igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
  12706. X#    Analogous to tgoto.  "Cm" is the cursor movement command for
  12707. X#  the current terminal, as obtained via getval("cm").  Igoto()
  12708. X#  returns a string which, when output via iputs, will cause the
  12709. X#  cursor to move to column "destcol" and line "destline."  Column and
  12710. X#  line are always calculated using a *one* offset.  This is far more
  12711. X#  Iconish than the normal zero offset used by tgoto.  If you want to
  12712. X#  go to the first square on your screen, then include in your program
  12713. X#  "iputs(igoto(getval("cm"),1,1))."
  12714. X#
  12715. X#  iputs(cp,affcnt)
  12716. X#    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  12717. X#  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  12718. X#  count of affected lines.  It is only relevant for terminals which
  12719. X#  specify proportional (starred) delays in their termcap entries.
  12720. X#
  12721. X#  Bugs:  I have not tested these routines on terminals that require
  12722. X#  padding.  These routines WILL NOT WORK if your machines stty com-
  12723. X#  mand has no -g option (tisk, tisk).  This includes NeXT worksta-
  12724. X#  tions, and some others that I haven't had time to pinpoint.
  12725. X#
  12726. X##########################################################################
  12727. X#
  12728. X#  Requires: UNIX, co-expressions
  12729. X#
  12730. X#  See also: iscreen.icn (a set of companion utilities)
  12731. X#
  12732. X##########################################################################
  12733. X
  12734. X
  12735. Xglobal tc_table, tty_speed
  12736. Xrecord true()
  12737. X
  12738. X
  12739. Xprocedure check_features()
  12740. X
  12741. X    local in_params, line
  12742. X    # global tty_speed
  12743. X
  12744. X    initial {
  12745. X    find("unix",map(&features)) |
  12746. X        er("check_features","unix system required",1)
  12747. X    find("o-expres",&features) |
  12748. X        er("check_features","co-expressions not implemented - &$#!",1)
  12749. X    system("/bin/stty tabs") |
  12750. X        er("check_features","can't set tabs option",1)
  12751. X    }
  12752. X
  12753. X    # clumsy, clumsy, clumsy, and probably won't work on all systems
  12754. X    tty_speed := getspeed()
  12755. X    return "term characteristics reset; features check out"
  12756. X
  12757. Xend
  12758. X
  12759. X
  12760. X
  12761. Xprocedure setname(name)
  12762. X
  12763. X    # Sets current terminal type to "name" and builds a new termcap
  12764. X    # capability database (residing in tc_table).  Fails if unable to
  12765. X    # find a termcap entry for terminal type "name."  If you want it
  12766. X    # to terminate with an error message under these circumstances,
  12767. X    # comment out "| fail" below, and uncomment the er() line.
  12768. X
  12769. X    #tc_table is global
  12770. X    
  12771. X    check_features()
  12772. X
  12773. X    tc_table := table()
  12774. X    tc_table := maketc_table(getentry(name)) | fail
  12775. X    # er("setname","no termcap entry found for "||name,3)
  12776. X    return "successfully reset for terminal " || name
  12777. X
  12778. Xend
  12779. X
  12780. X
  12781. X
  12782. Xprocedure getname()
  12783. X
  12784. X    # Getname() first checks to be sure we're running under Unix, and,
  12785. X    # if so, tries to figure out what the current terminal type is,
  12786. X    # checking successively the value of the environment variable
  12787. X    # TERM, and then the output of "tset -".  Terminates with an error
  12788. X    # message if the terminal type cannot be ascertained.
  12789. X
  12790. X    local term, tset_output
  12791. X
  12792. X    check_features()
  12793. X
  12794. X    if not (term := getenv("TERM")) then {
  12795. X    tset_output := open("/bin/tset -","pr") |
  12796. X        er("getname","can't find tset command",1)
  12797. X    term := !tset_output
  12798. X    close(tset_output)
  12799. X    }
  12800. X    return \term |
  12801. X    er("getname","can't seem to determine your terminal type",1)
  12802. X
  12803. Xend
  12804. X
  12805. X
  12806. X
  12807. Xprocedure er(func,msg,errnum)
  12808. X
  12809. X    # short error processing utility
  12810. X    write(&errout,func,":  ",msg)
  12811. X    exit(errnum)
  12812. X
  12813. Xend
  12814. X
  12815. X
  12816. X
  12817. Xprocedure getentry(name, termcap_string)
  12818. X
  12819. X    # "Name" designates the current terminal type.  Getentry() scans
  12820. X    # the current environment for the variable TERMCAP.  If the
  12821. X    # TERMCAP string represents a termcap entry for a terminal of type
  12822. X    # "name," then getentry() returns the TERMCAP string.  Otherwise,
  12823. X    # getentry() will check to see if TERMCAP is a file name.  If so,
  12824. X    # getentry() will scan that file for an entry corresponding to
  12825. X    # "name."  If the TERMCAP string does not designate a filename,
  12826. X    # getentry() will scan /etc/termcap for the correct entry.
  12827. X    # Whatever the input file, if an entry for terminal "name" is
  12828. X    # found, getentry() returns that entry.  Otherwise, getentry()
  12829. X    # fails.
  12830. X
  12831. X    local f, getline, line, nm, ent1, ent2
  12832. X
  12833. X    # You can force getentry() to use a specific termcap file by cal-
  12834. X    # ling it with a second argument - the name of the termcap file
  12835. X    # to use instead of the regular one, or the one specified in the
  12836. X    # termcap environment variable.
  12837. X    /termcap_string := getenv("TERMCAP")
  12838. X
  12839. X    if \termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name)
  12840. X    then return termcap_string
  12841. X    else {
  12842. X
  12843. X    # The logic here probably isn't clear.  The idea is to try to use
  12844. X    # the termcap environment variable successively as 1) a termcap en-
  12845. X    # try and then 2) as a termcap file.  If neither works, 3) go to
  12846. X    # the /etc/termcap file.  The else clause here does 2 and, if ne-
  12847. X    # cessary, 3.  The "\termcap_string ? (not match..." expression
  12848. X    # handles 1.
  12849. X
  12850. X    if find("/",\termcap_string)
  12851. X    then f := open(termcap_string)
  12852. X    /f := open("/etc/termcap") |
  12853. X        er("getentry","I can't access your /etc/termcap file",1)
  12854. X
  12855. X    getline := create read_file(f)
  12856. X    
  12857. X    while line := @getline do {
  12858. X        if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
  12859. X        entry := ""
  12860. X        while (\line | @getline) ? {
  12861. X            if entry ||:= 1(tab(find(":")+1), pos(0))
  12862. X            then {
  12863. X            close(f)
  12864. X            # if entry ends in tc= then add in the named tc entry
  12865. X            entry ?:= tab(find("tc=")) ||
  12866. X                # recursively fetch the new termcap entry
  12867. X                (move(3), getentry(tab(find(":"))) ?
  12868. X                    # remove the name field from the new entry
  12869. SHAR_EOF
  12870. true || echo 'restore of itlib.icn failed'
  12871. fi
  12872. echo 'End of  part 1'
  12873. echo 'File itlib.icn is continued in part 2'
  12874. echo 2 > _shar_seq_.tmp
  12875. exit 0
  12876.  
  12877.