home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume18 / xbowl / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-07-11  |  30.1 KB

  1. Path: uunet!news.tek.com!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v18i014:  xbowl - bowling game in TCL/Tk, Part01/01
  5. Date: 12 Jul 1993 06:16:49 GMT
  6. Organization: Tektronix, Inc, Redmond, OR, USA
  7. Lines: 829
  8. Approved: billr@saab.CNA.TEK.COM
  9. Message-ID: <21qvkh$gmu@ying.cna.tek.com>
  10. NNTP-Posting-Host: saab.cna.tek.com
  11. Xref: uunet comp.sources.games:1814
  12.  
  13. Submitted-by: grina@fai.COM (Peter Grina)
  14. Posting-number: Volume 18, Issue 14
  15. Archive-name: xbowl/part01
  16. Environment: TCL/Tk, X11
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 1 (of 1)."
  26. # Contents:  README MANIFEST xbowl
  27. # Wrapped by billr@saab on Sun Jul 11 23:15:53 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'README' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'README'\"
  31. else
  32. echo shar: Extracting \"'README'\" \(1047 characters\)
  33. sed "s/^X//" >'README' <<'END_OF_FILE'
  34. X                           xbowl Version 1.2
  35. X
  36. XOverview
  37. X  xbowl is a bowling game written in John Ousterhout's wonderful TCL/Tk
  38. X  language.  No TCL/Tk extensions are required by xbowl.  Please send
  39. X  your complaints and suggestions to grina@fai.com. 
  40. X
  41. XUsage
  42. X         xbowl
  43. X         - or -
  44. X         xbowl <play sound command> <sounds directory>
  45. X                          ^             ^
  46. X                         optional arguments
  47. X
  48. XInvoking xbowl with no arguments assumes that your play command
  49. Xis "/usr/demo/SOUND/play -v20" and that your sounds are stored in
  50. X"/usr/demo/SOUND/sounds", which happen to be the default locations
  51. Xfor SunOS 4.x.  
  52. X
  53. XIf you don't have sound capability, don't worry... it is not absolutely
  54. Xrequired by xbowl.  Skill isn't required either... I'm proof of that :-)
  55. X
  56. X------------------------------------------------------------
  57. XIF YOU DO NOT HAVE WISH AND TCL:
  58. XAnonymous ftp from sprite.berkeley.edu, directory "tcl": get
  59. Xtk3.2.tar.Z and tcl6.7.tar.Z. Uncomress, untar, and
  60. Xfollow the instructions in the README's therein.
  61. END_OF_FILE
  62. if test 1047 -ne `wc -c <'README'`; then
  63.     echo shar: \"'README'\" unpacked with wrong size!
  64. fi
  65. # end of 'README'
  66. fi
  67. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  68.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  69. else
  70. echo shar: Extracting \"'MANIFEST'\" \(207 characters\)
  71. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  72. X   File Name        Archive #    Description
  73. X-----------------------------------------------------------
  74. X MANIFEST                   1    This shipping list
  75. X README                     1    
  76. X xbowl                      1    
  77. END_OF_FILE
  78. if test 207 -ne `wc -c <'MANIFEST'`; then
  79.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  80. fi
  81. # end of 'MANIFEST'
  82. fi
  83. if test -f 'xbowl' -a "${1}" != "-c" ; then 
  84.   echo shar: Will not clobber existing file \"'xbowl'\"
  85. else
  86. echo shar: Extracting \"'xbowl'\" \(26305 characters\)
  87. sed "s/^X//" >'xbowl' <<'END_OF_FILE'
  88. X#!/usr/local/bin/wish -f
  89. X#                            xbowl Version 1.2
  90. X#
  91. X# Overview
  92. X#   xbowl is a bowling game written in John Ousterhout's wonderful TCL/Tk
  93. X#   language.  No TCL/Tk extensions are required by xbowl.  Please send
  94. X#   your complaints and suggestions to grina@fai.com. 
  95. X#
  96. X# Usage
  97. X#           xbowl
  98. X#           - or -
  99. X#           xbowl <play sound command> <sounds directory>
  100. X#                            ^             ^
  101. X#                           optional arguments
  102. X#
  103. X#  Invoking xbowl with no arguments assumes that your play command
  104. X#  is "/usr/demo/SOUND/play -v20" and that your sounds are stored in
  105. X#  "/usr/demo/SOUND/sounds", which happen to be the default locations
  106. X#  for SunOS 4.x.  
  107. X#
  108. X#  If you don't have sound capability, don't worry... it is not absolutely
  109. X#  required by xbowl.  Skill isn't required either... I'm proof of that :-)
  110. X#
  111. X# Copyright
  112. X#   This is the copyright notice for  TCL/Tk:
  113. X#     * Copyright 1991-1992 Regents of the University of California
  114. X#     * Permission to use, copy, modify, and distribute this
  115. X#     * software and its documentation for any purpose and without
  116. X#     * fee is hereby granted, provided that this copyright
  117. X#     * notice appears in all copies.  The University of California
  118. X#     * makes no representations about the suitability of this
  119. X#     * software for any purpose.  It is provided "as is" without
  120. X#     * express or implied warranty.
  121. X#
  122. X#  The only additional restriction on this version of xbowl is that 
  123. X#  "Copyright (C) 1993 Peter Grina" must appear in all copies of xbowl.
  124. X#
  125. X#  xbowl comes with no warranty. (I hope that you weren't shocked by this.)
  126. X#
  127. X# History
  128. X#   Originally designed and coded by Peter Grina (grina@fai.com)
  129. X#   Release 1.0  game finally works
  130. X#   Release 1.1  added help text; sound on/off buttons; added some pin 
  131. X#                combinations in case conditions.
  132. X#   Release 1.2  big red X for strikes; play command and sound directory
  133. X#                arguments can be passed on command line; make "help" text 
  134. X#                politically correct (i.e. "button 1" instead of "left 
  135. X#                button"); righty-lefty preference is remembered for each 
  136. X#                bowlerl
  137. X#
  138. X
  139. Xproc Binds {} {
  140. X    global ball
  141. X    global sound
  142. X    global sounds_dir
  143. X    global play_cmd
  144. X    global status
  145. X    global status2
  146. X    .c2 bind $ball <ButtonPress-1> {set initial "[.c2 coords $ball]"}
  147. X    .c2 bind $ball <ButtonRelease-1> {
  148. X    set final "[.c2 coords $ball]"
  149. X        if {[lindex $final 3] < 0} {
  150. X            if {$sound == 1} {
  151. X                catch {eval exec $play_cmd $sounds_dir/touchtone.3.au}
  152. X            }
  153. X            set msg [.c1 create text 100 300 -fill "red" -text "Scratch!"\
  154. X                -font -Adobe-helvetica-medium-r-normal--*-240* -tags text]
  155. X            $status config -text "SCRATCH!  score: 0"
  156. X            $status2 config -text " "
  157. X            $status flash
  158. X            after 2000 ".c1 delete text"
  159. X            CalcScore
  160. X        } else {
  161. X            if {[expr [lindex $initial 1]-[lindex $final 1]] > 20} {
  162. X                Roll $ball [expr ([lindex $final 0]-[lindex $initial 0])] \
  163. X                   [expr ([lindex $final 1]-[lindex $initial 1])] 
  164. X            } else {
  165. X                set msg [.c1 create text 100 300 -fill "red" -text \
  166. X                    "Please roll ball toward the pins" -font \
  167. X                    -Adobe-helvetica-medium-r-normal--*-120*  -tags text]
  168. X                after 2500 ".c1 delete text"
  169. X            }
  170. X        }
  171. X    }
  172. X    .c2 bind $ball <B1-Motion> {set x %x; set y %y; .c2 coords $ball \
  173. X        [expr $x-10] [expr $y-10] [expr $x+10] [expr $y+10]}
  174. X    .c2 bind $ball <B2-Motion> {set x %x; set y %y; .c2 coords $ball \
  175. X        [expr $x-10] [expr $y-10] [expr $x+10] [expr $y+10]}
  176. X}
  177. X
  178. Xproc NewBall {} {
  179. X        global ball
  180. X    global score
  181. X    global whichball
  182. X    set score 0
  183. X        catch {[.c2 delete ball]}
  184. X    set ball [.c2 create oval 180 180 200 200 -fill black -tag ball];Binds
  185. X    if {$whichball == "1"} { SetupPins }
  186. X}
  187. X
  188. Xproc Roll { ball xmove ymove } {
  189. X    set newball no
  190. X    .c2 move ball $xmove $ymove
  191. X    set ballposition [.c2 coords $ball]
  192. X    if {[lindex $ballposition 1] <= 16} {
  193. X        set newball [.c1 create oval [lindex $ballposition 0]  \
  194. X                490 [lindex $ballposition 2] 510 -fill black -tag newball]
  195. X        .c2 delete ball
  196. X        JustRoll $newball 40 $xmove $ymove
  197. X    }
  198. X    if {$newball == "no"} {
  199. X        after 40 "Roll $ball $xmove $ymove"
  200. X    }
  201. X}
  202. X
  203. Xproc JustRoll {ball {delay 50} {xroll 0}  {yroll -10} } {
  204. X    global score
  205. X    global RL
  206. X    global kd
  207. X    set end no
  208. X    set delay [expr $delay+1]
  209. X
  210. X    .c1 move $ball [expr $xroll/5] [expr $yroll/5]
  211. X
  212. X#       Uncomment these two lines if you want to see the path of the ball
  213. X#       Also, there are two similar lines about 10 lines below
  214. X#    if {$score} ".c1 create rectangle [.c1 coords $ball] -width 1 \
  215. X#        -fill burlywood -tags path"
  216. X
  217. X    if {$score} { \
  218. X        append kd " "
  219. X        append kd [eval ".c1 find overlapping [.c1 coords $ball]" ]
  220. X    }
  221. X
  222. X    set ballposition [.c1 coords $ball]
  223. X    set xroll [expr $xroll-$RL]
  224. X    if {[lindex $ballposition 0] <= 12 || [lindex $ballposition 0] >= 192} {
  225. X        set xroll 0
  226. X    }
  227. X    if {!$score} {
  228. X        if {[lindex $ballposition 1] <= 135} {
  229. X        set score [lindex $ballposition 0]
  230. X
  231. X#               See note above regarding these two lines
  232. X#        set path1 ".c1 create rectangle $ballposition -width 1 \
  233. X#                     -fill burlywood -tags path"
  234. X
  235. X        set kd [eval ".c1 find overlapping $ballposition"]
  236. X        }
  237. X    }
  238. X    if {[lindex $ballposition 1] <= -20} {
  239. X        set score2 [lindex $ballposition 0]
  240. X        WhichPins $score $score2
  241. X        set end yes
  242. X        .c1 delete $ball
  243. X    }
  244. X    if {$end == "no"} {after $delay "JustRoll $ball $delay $xroll $yroll"}
  245. X}
  246. X
  247. Xproc WhichPins {position endposition} {
  248. X    global status
  249. X    global status2
  250. X    global sound
  251. X    global sounds_dir
  252. X    global play_cmd
  253. X    if {$position > 100} { set position [expr 200-$position] }
  254. X    if {$endposition > 100} { set endposition [expr 200-$endposition] }
  255. X    if {$endposition > $position} { set position $endposition}
  256. X
  257. X    if {$position < 20 } {
  258. X        if {$sound == 1} {
  259. X        catch {eval exec $play_cmd $sounds_dir/clink.au }
  260. X        }
  261. X    $status config -text "Gutter Ball!"
  262. X    $status2 config -text "Gutter Ball!"
  263. X        $status flash
  264. X        CalcScore
  265. X    } else { KnockDowns }
  266. X}
  267. Xproc SetupPins {} {
  268. X    global array pin
  269. X    set pin(1) [.c1 create oval 100 120 120 140 -fill white \
  270. X        -outline red -tags pin1]
  271. X    set pin(2) [.c1 create oval 80 80 100 100 -fill white \
  272. X        -outline red -tags pin2]
  273. X    set pin(3) [.c1 create oval 120 80 140 100 -fill white \
  274. X        -outline red -tags pin3]
  275. X    set pin(4) [.c1 create oval 60 40 80 60 -fill white \
  276. X        -outline red -tags pin4]
  277. X    set pin(5) [.c1 create oval 100 40 120 60 -fill white \
  278. X        -outline red -tags pin5]
  279. X    set pin(6) [.c1 create oval 140 40 160 60 -fill white \
  280. X        -outline red -tags pin6]
  281. X    set pin(7) [.c1 create oval 40 0 60 20 -fill white \
  282. X        -outline red -tags pin7]
  283. X    set pin(8) [.c1 create oval 80 0 100 20 -fill white \
  284. X        -outline red -tags pin8]
  285. X    set pin(9) [.c1 create oval 120 0 140 20 -fill white \
  286. X        -outline red -tags pin9]
  287. X    set pin(10) [.c1 create oval 160 0 180 20 -fill white \
  288. X        -outline red -tags pin10]
  289. X}
  290. X
  291. Xproc KnockDowns {} {
  292. X    global kd
  293. X    global array pin
  294. X    global status
  295. X    global status2
  296. X    global sound
  297. X    global sounds_dir
  298. X    global play_cmd
  299. X    set direct_hits ""
  300. X    set tumbles ""
  301. X    set indirect_hits ""
  302. X    foreach i {1 2 3 4 5 6 7 8 9 10} {
  303. X    if {[lsearch $kd $pin($i)] != -1 } {
  304. X        append direct_hits "$i "
  305. X        .c1 delete pin$i
  306. X    }
  307. X    } 
  308. X    if {[llength $direct_hits] == 0} {
  309. X        if {$sound == 1} {
  310. X        catch {eval exec $play_cmd $sounds_dir/whistle.au }
  311. X        }
  312. X    $status config -text "Air Ball!"
  313. X    $status2 config -text " "
  314. X        $status flash
  315. X    } else {    
  316. X        if {$sound == 1} {
  317. X            catch {eval exec $play_cmd $sounds_dir/crash.au }
  318. X        }
  319. X    # figure out indirect hits here
  320. X    case $direct_hits in {
  321. X      {"1 3 6 9 10 "} {set indirect_hits "2 4 5 8" }
  322. X      {"1 2 3 5 8 9 "}  {set indirect_hits "4 6 7 10" }
  323. X      {"1 2 3 5 8 "}  {set indirect_hits "4 6 7 9 10" }
  324. X      {"1 2 3 5 9 "}  {set indirect_hits "4 6 7 8 10" }
  325. X      {"1 2 4 5 8 "}  {set indirect_hits "3 6 7 9 10" }
  326. X      {"1 2 4 7 8 "}  {set indirect_hits "3 5 6 9" }
  327. X      {"1 2 5 8 9 "}  {set indirect_hits "3 4 6 7 10" }
  328. X      {"1 3 5 8 9 "}  {set indirect_hits "2 4 6 7 10" }
  329. X      {"1 3 5 6 9 "}  {set indirect_hits "2 4 7 8 10" }
  330. X      {"1 3 6 10 "}  {set indirect_hits "2 4 7 8 9" }
  331. X      {"3 6 9 10 "}  {set indirect_hits "5 8" }
  332. X          {"1 2 3 5 "}  {set indirect_hits "4 6 7 8 9 10" }
  333. X          {"1 2 4 5 "}  {set indirect_hits "3 6 7 8 9 10" }
  334. X          {"1 2 4 7 "}  {set indirect_hits "3 5 6 8 9" }
  335. X          {"1 2 4 8 "}  {set indirect_hits "3 5 6 7 9" }
  336. X          {"1 2 5 8 "}  {set indirect_hits "3 4 6 7 9 10" }
  337. X          {"1 2 5 9 "}  {set indirect_hits "3 4 6 7 8 10" }
  338. X          {"1 3 5 8 "}  {set indirect_hits "2 4 6 7 9 10" }
  339. X          {"1 3 5 9 "}  {set indirect_hits "2 4 6 7 8 10" }
  340. X          {"1 3 6 9 "}  {set indirect_hits "2 4 7 8 10" }
  341. X          {"2 4 5 8 "} {set indirect_hits "7 9" }
  342. X          {"2 4 7 8 "} {set indirect_hits "5 9" }
  343. X          {"2 5 8 9 "} {set indirect_hits "4 7" }
  344. X          {"3 5 6 9 "} {set indirect_hits "8 10" }
  345. X          {"3 5 8 9 "} {set indirect_hits "6 10" }
  346. X          {"3 6 10 "} {set indirect_hits "5 8 9" }
  347. X          {"1 2 4 "} {set indirect_hits "3 5 7 8 9" }
  348. X          {"1 3 5 "} {set indirect_hits "2 4 6 7 8 9 10" }
  349. X          {"1 3 6 "} {set indirect_hits "2 5 8 9 10" }
  350. X          {"1 5 8 "} {set indirect_hits "2 3 4 6 7 9 10" }
  351. X          {"1 5 9 "} {set indirect_hits "2 3 4 6 7 8 10" }
  352. X          {"2 4 5 "} {set indirect_hits "7 8 9" }
  353. X          {"2 4 7 "} {set indirect_hits "5 8 9" }
  354. X          {"2 4 8 "} {set indirect_hits "5 7 9" }
  355. X          {"2 5 8 "} {set indirect_hits "4 7 9" }
  356. X          {"2 5 9 "} {set indirect_hits "4 7 8" }
  357. X         {"3 10 "} {set indirect_hits "5 6 9" }
  358. X          {"3 5 6 "} {set indirect_hits "8 9 10" }
  359. X          {"3 5 8 "} {set indirect_hits "6 9 10" }
  360. X          {"3 5 9 "} {set indirect_hits "6 8 10" }
  361. X          {"3 6 9 "} {set indirect_hits "5 8 10" }
  362. X       {"6 10 "} {set indirect_hits "9" }
  363. X      {"1 2 "} {set indirect_hits "4 5 8 9" }
  364. X      {"1 3 "} {set indirect_hits "5 6 8 9" }
  365. X      {"1 5 "} {set indirect_hits "2 3 4 6 8 9" }
  366. X          {"2 4 "} {set indirect_hits "5 8 9" }
  367. X          {"2 5 "} {set indirect_hits "4 8 9" }
  368. X          {"2 7 "} {set indirect_hits "4 5 8" }
  369. X          {"2 8 "} {set indirect_hits "4 5 7 9" }
  370. X          {"2 9 "} {set indirect_hits "4 5 8" }
  371. X          {"3 5 "} {set indirect_hits "6 8 9" }
  372. X          {"3 6 "} {set indirect_hits "5 8 9" }
  373. X          {"3 8 "} {set indirect_hits "5 6 9" }
  374. X          {"3 9 "} {set indirect_hits "5 6 8 10" }
  375. X          {"4 7 "} {set indirect_hits "8" }
  376. X          {"4 8 "} {set indirect_hits "7" }
  377. X          {"5 8 "} {set indirect_hits "9" }
  378. X          {"5 9 "} {set indirect_hits "8" }
  379. X          {"6 9 "} {set indirect_hits "10" }
  380. X      {"1 "} {set indirect_hits "2 3 4 5 6 8 9" }
  381. X      {"2 "} {set indirect_hits "4 5 7 8 9" }
  382. X      {"3 "} {set indirect_hits "5 6 8 9 10" }
  383. X      {"4 "} {set indirect_hits "7 8" }
  384. X      {"5 "} {set indirect_hits "8 9" }
  385. X      {"6 "} {set indirect_hits "9 10" }
  386. X    }
  387. X    foreach i {1 2 3 4 5 6 7 8 9 10} {
  388. X        if {[lsearch $indirect_hits $i] != -1} {
  389. X            if {[lsearch [.c1 find overlapping 30 0 160 140] \
  390. X                    $pin($i)] != -1} { 
  391. X            .c1 delete pin$i
  392. X            append tumbles "$i "
  393. X        }
  394. X        }
  395. X    }
  396. X    }
  397. X    update idletasks
  398. X    CalcScore "$direct_hits$tumbles"
  399. X}
  400. X
  401. Xproc ScoreSheet {} {
  402. X    toplevel .score
  403. X    wm title .score "Bowling Scoresheet"
  404. X    global numplayers
  405. X    set width 600
  406. X    set height [expr $numplayers*40]
  407. X    set headerh 40
  408. X    set totalh [expr $height+$headerh]
  409. X    canvas .score.c1 -width $width -height $totalh -bg black -border 10
  410. X    pack append .score .score.c1 {top expand fill}
  411. X    set header [.score.c1 create rectangle 0 0 $width $headerh -fill white]
  412. X    set scorearea [.score.c1 create rectangle 0 $headerh $width \
  413. X    [expr $totalh] -fill white]
  414. X    .score.c1 create text 50 [expr $headerh/2] -text Name -fill black \
  415. X    -font -Adobe-helvetica-medium-r-normal--*-240*
  416. X    foreach i {1 2 3 4 5 6 7 8 9} {
  417. X    set offset [expr 40*$i]
  418. X        .score.c1 create line [expr $offset+60] $headerh [expr $offset+60] \
  419. X        $totalh -fill black
  420. X        .score.c1 create text [expr $offset+80] [expr $headerh/2] -text $i \
  421. X        -fill black -font -Adobe-helvetica-medium-r-normal--*-240*
  422. X    }
  423. X    .score.c1 create line 460 $headerh 460 $totalh -fill black
  424. X    .score.c1 create text 480 [expr $headerh/2] -text 10 -fill black \
  425. X    -font -Adobe-helvetica-medium-r-normal--*-240*
  426. X    .score.c1 create line 510 $headerh 510 $totalh -fill black
  427. X    .score.c1 create text 550 [expr $headerh/2] -text Total -fill black \
  428. X    -font -Adobe-helvetica-medium-r-normal--*-240*
  429. X    for {set i 1} {$i <= $numplayers} {incr i} {
  430. X        set offsety [expr 40*$i+8]
  431. X    label .score.c1.player$i -bg white \
  432. X        -font -Adobe-helvetica-medium-r-normal--*-180*
  433. X    .score.c1 create window 50 [expr $offsety+12] \
  434. X        -window .score.c1.player$i -width 100 -height 35
  435. X    entry .score.c1.grandtotal$i -bg white \
  436. X        -font -Adobe-helvetica-medium-r-normal--*-240*
  437. X    .score.c1 create window 550 [expr $offsety+15] -height 25 -width 40 \
  438. X        -window .score.c1.grandtotal$i
  439. X    foreach j {1 2 3 4 5 6 7 8 9 10} {
  440. X        set offsetx [expr 40*$j+68]
  441. X        entry .score.c1.total$i$j -bg white \
  442. X         -font -Adobe-helvetica-medium-r-normal--*-180*
  443. X        .score.c1 create window [expr $offsetx+11] [expr $offsety+20] \
  444. X        -window .score.c1.total$i$j -width 35 -height 20
  445. X        entry .score.c1.first$i$j -bg white -border 1 -relief raised
  446. X            .score.c1 create window $offsetx $offsety -height 15 -width 15 \
  447. X        -window .score.c1.first$i$j
  448. X            entry .score.c1.second$i$j -bg white -border 1 -relief raised
  449. X        .score.c1 create window [expr $offsetx+15] $offsety \
  450. X            -window .score.c1.second$i$j -height 15 -width 15
  451. X        if {$j == 10} {
  452. X                entry .score.c1.third$i$j -bg white -border 1 -relief raised
  453. X            .score.c1 create window [expr $offsetx+30] $offsety \
  454. X                -window .score.c1.third$i$j -height 15 -width 15
  455. X        }
  456. X    }
  457. X    .score.c1 create line 0 [expr 40*$i+$headerh] $width \
  458. X        [expr 40*$i+$headerh] -fill black
  459. X    }
  460. X
  461. X
  462. X}
  463. Xproc CalcScore { {pins_hit 0} } {
  464. X    global whichball
  465. X    global whoisup
  466. X    global whichframe
  467. X    global firstballkd
  468. X    global secondballkd
  469. X    global array runningtotals
  470. X    global array playername
  471. X    global numplayers
  472. X    global thirdball
  473. X
  474. X    # calculate the score and enter on scoresheet
  475. X    set moo [expr [string length $pins_hit]/2]
  476. X
  477. X    if {$whichball == 1} {
  478. X        # take care of strikes in previous frame
  479. X        if {$whichframe > 1 && \
  480. X            [.score.c1.second$whoisup[expr $whichframe-1] get] == "/"} {
  481. X            .score.c1.total$whoisup[expr $whichframe-1] \
  482. X                insert 0 "[incr runningtotals($whoisup) [expr 10+$moo]]"
  483. X    }    
  484. X    # take care of strikes in previous-previous frame (i.e. 2 frames ago)
  485. X    if {$whichframe > 2 && \
  486. X            [.score.c1.second$whoisup[expr $whichframe-1] get] == "X" && \
  487. X            [.score.c1.second$whoisup[expr $whichframe-2] get] == "X"} {
  488. X            .score.c1.total$whoisup[expr $whichframe-2] \
  489. X                 insert 0 "[incr runningtotals($whoisup) [expr 20+$moo]]"
  490. X        }
  491. X    # done with those annoying strikes from previous frames
  492. X
  493. X        set firstballkd $moo
  494. X    # is the current roll a strike?
  495. X    if {$moo == "10"} { 
  496. X            Strike
  497. X            if {$whichframe == "10"} {
  498. X        .score.c1.first$whoisup$whichframe insert 0 "X"
  499. X                SetupPins
  500. X        } else {
  501. X                .score.c1.second$whoisup$whichframe insert 0 "X"
  502. X                incr whichball
  503. X        }
  504. X    } else {    # not a strike
  505. X        if {$moo == 0} {set moo "-"}
  506. X            .score.c1.first$whoisup$whichframe  insert 0 $moo
  507. X    }
  508. X
  509. X    } else {  
  510. X        if {$whichball == "2"} {
  511. X            set secondballkd $moo
  512. X            if {$moo == 10} { Strike }
  513. X        # take care of strike in previous frame when current frame is not
  514. X        # a strike
  515. X            if {$whichframe > 1 && \
  516. X                [.score.c1.second$whoisup[expr $whichframe-1] get] == "X"} {
  517. X                .score.c1.total$whoisup[expr $whichframe-1] insert \
  518. X                    0 "[incr runningtotals($whoisup) [expr 10+$moo+$firstballkd]]"
  519. X        }
  520. X
  521. X            if {$whichframe == "10" && $moo == "10"} {
  522. X               if {$firstballkd == "10"} {
  523. X                   .score.c1.second$whoisup$whichframe insert 0 "X"
  524. X               } else {
  525. X                   .score.c1.second$whoisup$whichframe insert 0 "/"
  526. X               }
  527. X            } else {
  528. X                # did the second ball make a spare?
  529. X                if "[expr $moo+$firstballkd] == 10" {  
  530. X                set moo "/" 
  531. X                } else {    
  532. X                    if {$whichframe != "10"} { # hah, this is an open frame
  533. X                    .score.c1.total$whoisup$whichframe insert 0 \
  534. X                        "[incr runningtotals($whoisup) [expr $firstballkd+$moo]]"
  535. X                    }
  536. X                }
  537. X                if {$moo == 0} {set moo "-"}   # who needs this line?
  538. X                .score.c1.second$whoisup$whichframe  insert 0 $moo
  539. X            }
  540. X            if {$whichframe == "10"} {
  541. X         # check for strike or spare for another ball here for 10th frame
  542. X                if {[expr $secondballkd+$firstballkd] >= 10} {
  543. X                    incr whichball
  544. X                    set thirdball yes
  545. X                    if {[expr $secondballkd+$firstballkd] == 10 || \
  546. X                        [expr $secondballkd+$firstballkd] == 20} {
  547. X                        SetupPins
  548. X                    }
  549. X                } else {
  550. X                    .score.c1.total$whoisup$whichframe insert 0 \
  551. X                        "[incr runningtotals($whoisup) \
  552. X                         [expr $firstballkd+$secondballkd]]"
  553. X                    .score.c1.grandtotal$whoisup insert 0 \
  554. X                        $runningtotals($whoisup)
  555. X                }
  556. X            }
  557. X        } else {  # this is the third ball
  558. X            set thirdballkd $moo
  559. X            if {$moo == "10"} { 
  560. X                Strike
  561. X                set moo "X" 
  562. X            }
  563. X            if {$firstballkd == 10 && $secondballkd < 10 && \
  564. X                [expr $moo+$secondballkd] == 10} {
  565. X                set moo "/"
  566. X            }
  567. X        if {$moo == 0} {set moo "-"}
  568. X           .score.c1.third$whoisup$whichframe insert \
  569. X               0 $moo
  570. X           incr runningtotals($whoisup) $firstballkd
  571. X           incr runningtotals($whoisup) $secondballkd
  572. X           .score.c1.total$whoisup$whichframe insert \
  573. X               0 "[incr runningtotals($whoisup) $thirdballkd]"
  574. X           .score.c1.grandtotal$whoisup insert \
  575. X               0 $runningtotals($whoisup)
  576. X        }
  577. X    }
  578. X    NextUp
  579. X}
  580. Xproc Strike {} {
  581. X    global status
  582. X    global status2
  583. X    global line1
  584. X    global line2
  585. X    $status config -text STRIKE
  586. X    $status2 config -text "X X X X"
  587. X    set line1 [.c1 create line 60 10 160 170 -fill red -width 5]
  588. X    set line2 [.c1 create line 160 10 60 170 -fill red -width 5]
  589. X    after 1000 {
  590. X        .c1 delete $line1
  591. X        .c1 delete $line2
  592. X    }
  593. X}    
  594. Xproc NextUp {} {
  595. X    global numplayers
  596. X    global whoisup
  597. X    global whichball
  598. X    global whichframe
  599. X    global array runningtotals
  600. X    global array playername
  601. X    global status
  602. X    global status2
  603. X    global thirdball
  604. X    global RL
  605. X    global array rightylefty
  606. X
  607. X    if {$whichball == "2"} {
  608. X        after 1300
  609. X        set whichball 1
  610. X        incr whoisup
  611. X        if {$whoisup > $numplayers} {
  612. X            set whoisup 1
  613. X            incr whichframe
  614. X        }
  615. X    } else {
  616. X        if {$whichball == "1"} {
  617. X            incr whichball
  618. X        } else {  # third ball
  619. X            if {$thirdball == "yes"} {
  620. X                set whichball 3
  621. X                set thirdball no
  622. X            } else {
  623. X                set whichball 1
  624. X                incr whoisup
  625. X                if {$whoisup > $numplayers} {
  626. X                    set whoisup 1
  627. X                    incr whichframe
  628. X                }
  629. X            }
  630. X        }
  631. X    }
  632. X    set RL $rightylefty($whoisup)
  633. X    if {$whichframe < "11"} { 
  634. X        $status config -text "Player $playername($whoisup)"
  635. X        $status2 config -text "Ball number $whichball"
  636. X        NewBall 
  637. X     } else {  # all done with frame number 10
  638. X        $status config -text "Game" -background red
  639. X        $status2 config -text "Over" -background red
  640. X        update idletasks
  641. X    }
  642. X}
  643. X   
  644. Xproc GetInfo {} {
  645. X    global numplayers
  646. X    global whoisup
  647. X    global whichball
  648. X    global whichframe
  649. X    global array playername
  650. X    global array runningtotals
  651. X        global array rightylefty
  652. X    global status
  653. X    global status2
  654. X    set numplayers [.info.f.ent1 get]
  655. X    set whoisup 1
  656. X    set whichball 1
  657. X    set whichframe 1
  658. X
  659. X    destroy .info.f.but1
  660. X        .info.f.ent1 config -state disabled
  661. X    for {set i 1} {$i <= $numplayers} {incr i} {
  662. X        frame .info.f$i
  663. X        label .info.f$i.lab$i -text "Player $i " 
  664. X        entry .info.f$i.ent$i -width 10 -relief sunken -border 1 -bg white
  665. X        bind  .info.f$i.ent$i <Enter> "focus .info.f$i.ent$i"
  666. X        bind  .info.f$i.ent$i <KeyPress-Return> \
  667. X                "focus .info.f[expr $i+1].ent[expr $i+1]"
  668. X        pack append .info.f$i  .info.f$i.lab$i {left} \
  669. X        .info.f$i.ent$i {left}
  670. X        pack append .info .info.f$i {top pady 20}
  671. X            set rightylefty($i) 1
  672. X    }
  673. X    bind  .info.f$numplayers.ent$numplayers <KeyPress-Return> \
  674. X        "focus .info.f1.ent1"        
  675. X
  676. X    button .info.button -text "OK" -command {
  677. X            DrawAlley
  678. X            Binds
  679. X            ScoreSheet 
  680. X        for {set i 1} {$i <= $numplayers} {incr i} {
  681. X            set playername($i) "[.info.f$i.ent$i get]"
  682. X            .score.c1.player$i configure -text $playername($i)
  683. X            set runningtotals($i) 0
  684. X        }
  685. X        catch {destroy .info}
  686. X        $status config -text "Player $playername(1)"
  687. X        $status2 config -text "Ball number $whichball"
  688. X
  689. X    }
  690. X    pack append .info .info.button {bottom expand fill}
  691. X
  692. X}
  693. X
  694. Xproc DrawAlley {} {
  695. Xglobal ball
  696. Xglobal status
  697. Xglobal status2
  698. Xglobal RL
  699. Xglobal whoisup
  700. X
  701. Xset xbowl "xbowl version 1.2"
  702. Xwm title . $xbowl
  703. Xwm iconname . $xbowl
  704. X    canvas .c1 -width 220 -height 510 -bg burlywood
  705. X        set alley [.c1 create rectangle 30 0 190 510 -fill burlywood]
  706. X        set foulline [.c1 create line 0 510 210 510 -fill black]
  707. X        set guttertl [.c1 create rectangle 10 0 30 510 -fill gainsboro]
  708. X        set guttertr [.c1 create rectangle 190 0 210 510 -fill gainsboro]
  709. X
  710. X    SetupPins
  711. X
  712. X    canvas .c2 -width 220 -height 210 -bg wheat
  713. X        set ball [.c2 create oval 180 180 200 200 -fill black -tag ball]
  714. X        frame .side -relief sunken -bg "pale green"
  715. X        set status [button .side.status -relief sunken -border 1 -bg white \
  716. X            -width 30] 
  717. X        set status2 [button .side.status2 -relief sunken -border 1 -bg white \
  718. X            -width 30] 
  719. X        message .side.msg -text "Status" -bg yellow -aspect 900 \
  720. X            -font  -Adobe-helvetica-medium-r-normal--*-240* 
  721. X        message .side.help -text "Use button 2 to move ball to initial position
  722. X
  723. XUse button 1 to \"push\" the ball toward the pins" -bg "pale green"
  724. X
  725. X        label .side.style -text "Bowling Style" -bg "pale green"
  726. X        radiobutton .side.r1 -variable RL -text "lefty"  -value -1 -width 15 \
  727. X            -anchor w -command {set rightylefty($whoisup) -1}
  728. X        radiobutton .side.r2 -variable RL -text "righty" -value 1 -width 15 \
  729. X            -anchor w -command {set rightylefty($whoisup) 1}
  730. X        radiobutton .side.r3 -variable RL -text "between the legs" -value 0 \
  731. X            -width 15 -anchor w -command {set rightylefty($whoisup) 0}
  732. X        label .side.sound -text "Sound" -bg "pale green"
  733. X        radiobutton .side.soundon -variable sound -text "Sound On" -value 1 \
  734. X            -width 15 -anchor w
  735. X        radiobutton .side.soundoff -variable sound -text "Sound Off" -value 0 \
  736. X            -width 15 -anchor w
  737. X        button .side.b2 -text "New Game" -command { ReStart } -relief raised \
  738. X            -border 2 -activebackground red
  739. X        button .side.b1 -text Quit -command {destroy .} -relief raised \
  740. X            -border 2 -activebackground red
  741. X        pack append .side \
  742. X            .side.msg {top pady 40 fillx} $status {top} $status2 {top} \
  743. X            .side.help {top pady 50} \
  744. X            .side.b1 {bottom pady 40} \
  745. X            .side.b2 {bottom pady 40} \
  746. X            .side.soundoff {bottom pady 10} \
  747. X            .side.soundon {bottom pady 10} \
  748. X            .side.sound {bottom pady 20} \
  749. X            .side.r1 {bottom pady 10} \
  750. X            .side.r2 {bottom pady 10} \
  751. X            .side.r3 {bottom pady 10} \
  752. X            .side.style {bottom pady 20}
  753. X
  754. X    pack append . .side {right expand fill padx 5} .c1 {top} .c2 {top} 
  755. X
  756. X}
  757. Xproc ReStart {} {
  758. X    global array runningtotals
  759. X    global array playername
  760. X    global numplayers
  761. X    global status
  762. X    global status2
  763. X    global whoisup; set whoisup 1
  764. X    global whichball; set whichball 1
  765. X    global whichframe; set whichframe 1
  766. X
  767. X    catch {[.c1 delete newball]}
  768. X    catch {[.c2 delete ball]}
  769. X    catch {destroy .score}
  770. X    ScoreSheet 
  771. X    for {set i 1} {$i <= $numplayers} {incr i} {
  772. X    .score.c1.player$i configure -text $playername($i)
  773. X    set runningtotals($i) 0
  774. X    }
  775. X    catch {destroy .info}
  776. X    $status config -text "Player $playername(1)" -bg white
  777. X    $status2 config -text "Ball number $whichball" -bg white
  778. X    SetupPins
  779. X    NewBall
  780. X}
  781. X
  782. X#  Main program starts here
  783. X
  784. Xglobal sound; set sound 0
  785. Xglobal ball
  786. Xglobal score; set score 0
  787. Xglobal RL; set RL 1
  788. Xglobal array pin
  789. Xglobal status
  790. Xglobal status2
  791. Xglobal whoisup
  792. Xglobal whichball
  793. Xglobal whichframe
  794. Xglobal numplayers
  795. Xglobal array runningtotals
  796. Xglobal array playername
  797. Xglobal thirdball; set thirdball no
  798. Xglobal play_cmd; set play_cmd "/usr/demo/SOUND/play -v20"
  799. Xglobal sounds_dir; set sounds_dir "/usr/demo/SOUND/sounds"
  800. X
  801. Xif {$argc > 0} {set play_cmd [lindex $argv 0]}
  802. Xif {$argc > 1} {set sounds_dir [lindex $argv 1]}
  803. X
  804. Xwm title . "Bowling Info/Shoe Rental"
  805. X
  806. Xframe .info
  807. Xframe .info.f
  808. Xlabel .info.f.lab1 -text "Number of players: " 
  809. Xentry .info.f.ent1 -width 2 -bg white -relief sunken -border 1
  810. Xbind .info <Enter> "focus .info.f.ent1"
  811. Xbutton .info.f.but1 -text "OK" -command GetInfo -relief raised -border 2
  812. Xpack append .info.f .info.f.lab1 {left} .info.f.ent1 {left padx 20} \
  813. X    .info.f.but1 {left padx 60}
  814. Xbind .info.f.ent1 <KeyPress-Return> GetInfo
  815. Xpack append .info .info.f {top}
  816. Xpack append . .info {top}
  817. X
  818. END_OF_FILE
  819. if test 26305 -ne `wc -c <'xbowl'`; then
  820.     echo shar: \"'xbowl'\" unpacked with wrong size!
  821. fi
  822. chmod +x 'xbowl'
  823. # end of 'xbowl'
  824. fi
  825. echo shar: End of archive 1 \(of 1\).
  826. cp /dev/null ark1isdone
  827. MISSING=""
  828. for I in 1 ; do
  829.     if test ! -f ark${I}isdone ; then
  830.     MISSING="${MISSING} ${I}"
  831.     fi
  832. done
  833. if test "${MISSING}" = "" ; then
  834.     echo You have the archive.
  835.     rm -f ark[1-9]isdone
  836. else
  837.     echo You still need to unpack the following archives:
  838.     echo "        " ${MISSING}
  839. fi
  840. ##  End of shell archive.
  841. exit 0
  842.