home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh -
- # the next line restarts using wish \
- exec wish "$0" "$@"
-
- #####
- # The minesweeper game. ported to Tcl/Tk.
- # P Kern, pkern at utcc.utoronto.ca, 99/02/18
-
- set usage "
- -beginner beginner level (8x8 40 mines).
- -intermediate medium level (16x16 60 mines).
- -expert expert level (30x16 99 mines).
- -mammoth huge board (56x40 396 mines).
- -x <val> x dimension of board.
- -y <val> y dimension of board.
- -mines <val> number of mines.
- -ratio <val> ratio of mines to board squares.
- -seed <val> seed for random numbers."
-
- #####
- # initial settings.
-
- bind . <KeyPress-q> exit
-
- # standard parameters.
- set modes(beg,ident) Beginner
- set modes(beg,XSize) 8
- set modes(beg,YSize) 8
- set modes(beg,Mines) 10
-
- set modes(int,ident) Intermediate
- set modes(int,XSize) 16
- set modes(int,YSize) 16
- set modes(int,Mines) 40
-
- set modes(exp,ident) Expert
- set modes(exp,XSize) 30
- set modes(exp,YSize) 16
- set modes(exp,Mines) 99
-
- set modes(mam,ident) Mammoth
- set modes(mam,XSize) 56
- set modes(mam,YSize) 40
- set modes(mam,Mines) 396
-
- # user-defined board uses intermediate values as default.
- set modes(usr,ident) Custom
- set modes(usr,XSize) 16
- set modes(usr,YSize) 16
- set modes(usr,Mines) 40
-
- set board(Seed) -1
- set board(ratio) -1.0
- set board(custom) 0
-
- proc setmode { mode } {
- global board modes
-
- switch -glob -- $mode {
- -beg* -
- -int* -
- -exp* -
- -mam* -
- -usr* {
- set m [ string range $mode 1 3 ]
- set board(XSize) $modes($m,XSize)
- set board(YSize) $modes($m,YSize)
- set board(Mines) $modes($m,Mines)
- }
- default { return 0 }
- }
- return 1
- }
-
- # "intermediate" is default.
- setmode "-int"
-
- # parse command-line arguments.
- set ac 0
- foreach arg $argv {
- incr ac
- if {[ setmode $arg ] != 0} { continue }
- set field ""
- switch -glob -- $arg {
- -x { set field XSize }
- -y { set field YSize }
- -mines { set field Mines }
- -ratio { set board(ratio) [ lindex $argv $ac] }
- -seed { set board(Seed) [ lindex $argv $ac] }
- -* { puts stderr "$argv0 options: $usage"; exit 0 }
- }
- if {$field != ""} {
- set board($field) [ lindex $argv $ac ]
- set board(custom) 1
-
- }
- }
- if {$board(custom) > 0} {
- # save custom choices.
- foreach field { XSize YSize Mines } {
- set modes(usr,$field) $board($field)
- }
- }
-
- #####
- # define bitmaps.
-
- #
- # smiley-face bitmaps: smiley, shades, croak.
- #
-
- image create bitmap smiley -background yellow -data "
- #define smiley_width 26
- #define smiley_height 26
- static unsigned char smiley_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00,
- 0x00, 0x03, 0x06, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x20, 0x00, 0x20, 0x00,
- 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x40, 0x00, 0x08, 0x00, 0x80, 0x00,
- 0x08, 0x06, 0x83, 0x00, 0x04, 0x06, 0x03, 0x01, 0x04, 0x00, 0x00, 0x01,
- 0x04, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x01,
- 0x44, 0x00, 0x10, 0x01, 0x84, 0x00, 0x08, 0x01, 0x08, 0x03, 0x86, 0x00,
- 0x08, 0xfc, 0x81, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x40, 0x00,
- 0x20, 0x00, 0x20, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x03, 0x06, 0x00,
- 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
- " -maskdata "
- #define smiley_width 26
- #define smiley_height 26
- static unsigned char smiley_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00,
- 0x00, 0xff, 0x07, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x3f, 0x00,
- 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf8, 0xff, 0xff, 0x00,
- 0xf8, 0xff, 0xff, 0x00, 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01,
- 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01,
- 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01, 0xf8, 0xff, 0xff, 0x00,
- 0xf8, 0xff, 0xff, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x7f, 0x00,
- 0xe0, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x07, 0x00,
- 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
- "
-
- image create bitmap shades -background yellow -data "
- #define shades_width 26
- #define shades_height 26
- static unsigned char shades_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00,
- 0x00, 0x03, 0x06, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x20, 0x00, 0x20, 0x00,
- 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x40, 0x00, 0x08, 0x00, 0x80, 0x00,
- 0xc8, 0xff, 0x9f, 0x00, 0xe4, 0xdf, 0x3f, 0x01, 0x94, 0x8f, 0x4f, 0x01,
- 0x0c, 0x07, 0x87, 0x01, 0x04, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x01,
- 0x44, 0x00, 0x10, 0x01, 0x84, 0x00, 0x08, 0x01, 0x08, 0x03, 0x86, 0x00,
- 0x08, 0xfc, 0x81, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x40, 0x00,
- 0x20, 0x00, 0x20, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x03, 0x06, 0x00,
- 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
- " -maskdata "
- #define smiley_width 26
- #define smiley_height 26
- static unsigned char smiley_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00,
- 0x00, 0xff, 0x07, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x3f, 0x00,
- 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf8, 0xff, 0xff, 0x00,
- 0xf8, 0xff, 0xff, 0x00, 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01,
- 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01,
- 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01, 0xf8, 0xff, 0xff, 0x00,
- 0xf8, 0xff, 0xff, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x7f, 0x00,
- 0xe0, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x07, 0x00,
- 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
- "
-
- image create bitmap croak -background yellow -data "
- #define croak_width 26
- #define croak_height 26
- static unsigned char croak_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00,
- 0x00, 0x03, 0x06, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x20, 0x00, 0x20, 0x00,
- 0x10, 0x00, 0x40, 0x00, 0x90, 0x88, 0x48, 0x00, 0x08, 0x05, 0x85, 0x00,
- 0x08, 0x02, 0x82, 0x00, 0x04, 0x05, 0x05, 0x01, 0x84, 0x88, 0x08, 0x01,
- 0x04, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x01,
- 0x04, 0xfc, 0x01, 0x01, 0x04, 0xa3, 0x06, 0x01, 0x88, 0xa0, 0x8a, 0x00,
- 0x48, 0xa0, 0x92, 0x00, 0x10, 0x20, 0x42, 0x00, 0x10, 0xc0, 0x41, 0x00,
- 0x20, 0x00, 0x20, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x03, 0x06, 0x00,
- 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
- " -maskdata "
- #define smiley_width 26
- #define smiley_height 26
- static unsigned char smiley_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00,
- 0x00, 0xff, 0x07, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x3f, 0x00,
- 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf8, 0xff, 0xff, 0x00,
- 0xf8, 0xff, 0xff, 0x00, 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01,
- 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01,
- 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x01, 0xf8, 0xff, 0xff, 0x00,
- 0xf8, 0xff, 0xff, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x7f, 0x00,
- 0xe0, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x07, 0x00,
- 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
- "
-
- #
- # flag bitmap.
- #
- image create bitmap flag -background red -data "
- #define flag_width 12
- #define flag_height 12
- static unsigned char flag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xf8, 0x03, 0xf8, 0x03};
- " -maskdata "
- #define flag_width 12
- #define flag_height 12
- static unsigned char flag_bits[] = {
- 0x80, 0x00, 0xc0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xc0, 0x00,
- 0x80, 0x00, 0x80, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xf8, 0x03, 0xf8, 0x03};
- "
-
- #
- # blank bitmap.
- #
- set blankxbm "
- #define blank_width 12
- #define blank_height 12
- static unsigned char blank_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- "
- image create bitmap blank -data $blankxbm
-
- #
- # question mark bitmap.
- #
- image create bitmap qmark -foreground blue -data "
- #define huh_width 12
- #define huh_height 12
- static unsigned char huh_bits[] = {
- 0xf0, 0x00, 0xf8, 0x01, 0x0c, 0x03, 0x0c, 0x03, 0x80, 0x01, 0xc0, 0x00,
- 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00};
- "
-
- #
- # mine bitmaps: mine, wrong.
- #
- image create bitmap mine -data "
- #define mine_width 12
- #define mine_height 12
- static unsigned char mine_bits[] = {
- 0x00, 0x00, 0x42, 0x08, 0xf4, 0x05, 0xf8, 0x03, 0xec, 0x07, 0xec, 0x07,
- 0xfe, 0x0f, 0xfc, 0x07, 0xfc, 0x07, 0xf8, 0x03, 0xf4, 0x05, 0x42, 0x08};
- "
-
- image create bitmap wrong -background red -data "
- #define wrong_width 12
- #define wrong_height 12
- static unsigned char wrong_bits[] = {
- 0x00, 0x00, 0x40, 0x00, 0xf0, 0x01, 0xf0, 0x00, 0x64, 0x06, 0x0c, 0x07,
- 0x9e, 0x0f, 0x0c, 0x07, 0x64, 0x06, 0xf0, 0x00, 0xf0, 0x01, 0x40, 0x00};
- " -maskdata "
- #define wrong_width 12
- #define wrong_height 12
- static unsigned char wrong_bits[] = {
- 0x00, 0x00, 0x42, 0x0c, 0xf6, 0x07, 0xfc, 0x03, 0xec, 0x07, 0xfc, 0x07,
- 0xfe, 0x0f, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x03, 0xf6, 0x07, 0x42, 0x0c};
- "
-
- #
- # digit bitmaps: 0 thru 9.
- #
-
- set numb(0) "
- #define 0_width 12
- #define 0_height 12
- static unsigned char 0_bits[] = {
- 0xf0, 0x01, 0xf8, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03,
- 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0xf8, 0x03, 0xf0, 0x01};
- "
-
- set numb(1) "
- #define 1_width 12
- #define 1_height 12
- static unsigned char 1_bits[] = {
- 0xe0, 0x00, 0xe0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
- 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xf0, 0x03, 0xf0, 0x03};
- "
-
- set numb(2) "
- #define 2_width 12
- #define 2_height 12
- static unsigned char 2_bits[] = {
- 0xf8, 0x03, 0xf8, 0x03, 0x18, 0x03, 0x18, 0x03, 0x00, 0x03, 0x80, 0x03,
- 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0xf8, 0x03, 0xf8, 0x03};
- "
-
- set numb(3) "
- #define 3_width 12
- #define 3_height 12
- static unsigned char 3_bits[] = {
- 0xf8, 0x03, 0xf8, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0xf0, 0x03,
- 0xf0, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0xf8, 0x03, 0xf8, 0x03};
- "
-
- set numb(4) "
- #define 4_width 12
- #define 4_height 12
- static unsigned char 4_bits[] = {
- 0x18, 0x00, 0x18, 0x00, 0x98, 0x01, 0x98, 0x01, 0x98, 0x01, 0x98, 0x01,
- 0xf8, 0x03, 0xf8, 0x03, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01};
- "
-
- set numb(5) "
- #define 5_width 12
- #define 5_height 12
- static unsigned char 5_bits[] = {
- 0xf8, 0x03, 0xf8, 0x03, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0xf8, 0x01,
- 0xf0, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0xf8, 0x03, 0xf8, 0x01};
- "
-
- set numb(6) "
- #define 6_width 12
- #define 6_height 12
- static unsigned char 6_bits[] = {
- 0xf8, 0x03, 0xf8, 0x03, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0xf8, 0x03,
- 0xf8, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0xf8, 0x03, 0xf8, 0x03};
- "
-
- set numb(7) "
- #define 7_width 12
- #define 7_height 12
- static unsigned char 7_bits[] = {
- 0xf8, 0x03, 0xf8, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x80, 0x03,
- 0xc0, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00};
- "
-
- set numb(8) "
- #define 8_width 12
- #define 8_height 12
- static unsigned char 8_bits[] = {
- 0xf8, 0x03, 0xf8, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0xf8, 0x03,
- 0xf8, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0xf8, 0x03, 0xf8, 0x03};
- "
-
- set numb(9) "
- #define 9_width 12
- #define 9_height 12
- static unsigned char 9_bits[] = {
- 0xf8, 0x03, 0xf8, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0xf8, 0x03,
- 0xf8, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0xf8, 0x03, 0xf8, 0x03};
- "
-
- #
- # "register" the bitmaps.
- #
- image create bitmap 0 -data $blankxbm
- #image create bitmap 0 -data $numb(0) -foreground #646464
- image create bitmap 1 -data $numb(1) -foreground #0000ff
- image create bitmap 2 -data $numb(2) -foreground #00c850
- image create bitmap 3 -data $numb(3) -foreground #ff0000
- image create bitmap 4 -data $numb(4) -foreground #0000af
- image create bitmap 5 -data $numb(5) -foreground #ff00ff
- image create bitmap 6 -data $numb(6) -foreground #00c8c8
- image create bitmap 7 -data $numb(7) -foreground #b400b4
- image create bitmap 8 -data $numb(8) -foreground #000000
-
-
- # show all mines.
- proc reveal {} {
- global board Map
-
- foreach coord $Map(Coords) {
- set j [ lindex $coord 0 ]
- set i [ lindex $coord 1 ]
- .game.field.y$j.x$i configure -relief flat -image $board(type,$j,$i)
- set f [ lsearch $Map(Flags) $coord ]
- if { $f > -1 } {
- set Map(Flags) [ lreplace $Map(Flags) $f $f ]
- }
- }
-
- # show mistakes.
- foreach coord $Map(Flags) {
- set j [ lindex $coord 0 ]
- set i [ lindex $coord 1 ]
- .game.field.y$j.x$i configure -relief flat -image wrong
- }
- }
-
- # finished. show results.
- proc done { type } {
- after cancel timer
- .game.status.butn configure -image $type
- reveal
- }
-
- # step on a square.
- proc step { x y } {
- global board
-
- # disable buttonclicks.
- bind .game.field.y$y.x$x <Button> ""
-
- set type $board(type,$y,$x)
- if { $type == "seen" } { return $type }
- if { $type == "mine" } {
- # stepped on a mine! game over.
- .game.field.y$y.x$x configure -background red
- .game.field.y$y.x$x configure -activebackground red
-
- done croak
-
- return $type
- }
- .game.field.y$y.x$x configure -relief flat -image $board(type,$y,$x)
- set board(type,$y,$x) seen
- return $type
- }
-
- # update the status displays.
- proc updatestatus {} {
- global player status
-
- set status(count) [ format "%3d" $player(count) ]
- set status(scnds) [ format "%3d" $player(elapsed) ]
- }
-
- # game clock.
- set timing 0
- proc timer {} {
- global player
-
- incr player(elapsed)
- after 1000 timer
- updatestatus
- }
-
- # examine a square.
- proc look { x y } {
- global board timing
-
- if { $timing == 0 } {
- # start the game clock.
- incr timing
- after 1000 timer
- }
-
- # "step" on it to see what's there.
- set type [ step $x $y ]
- if { $type == "mine" } { return }
- if { $type == "seen" } { return }
- if { $type > 0 } { return }
-
- # no mine(s) near by. check out neighbouring squares.
- set ylist [list [expr $y - 1] $y [expr $y + 1]]
- set xlist [list [expr $x - 1] $x [expr $x + 1]]
-
- foreach j $ylist {
- if { $j < 0 || $j >= $board(YSize) } { continue }
- foreach i $xlist {
- if { $i < 0 || $i >= $board(XSize) } { continue }
- if { $j != $y || $i != $x } { look $i $j }
- }
- }
- }
-
- # mark a square.
- proc mark { x y } {
- global player Map board
-
- set coord [ list $y $x ]
-
- # cycle: blank -> flag -> qmark -> blank
- set bm [ .game.field.y$y.x$x cget -image ]
- switch -- $bm {
- blank {
- set bm flag
- incr player(count) -1
- lappend Map(Flags) $coord
- if { $board(type,$y,$x) == "mine" } {
- incr board(Mines,left) -1
- }
- }
- flag {
- set bm qmark
- incr player(count)
- set f [ lsearch $Map(Flags) $coord ]
- if { $f > -1 } {
- set Map(Flags) [ lreplace $Map(Flags) $f $f ]
- }
- if { $board(type,$y,$x) == "mine" } {
- incr board(Mines,left)
- }
- }
- qmark { set bm blank }
- }
- .game.field.y$y.x$x configure -image $bm
-
- updatestatus
- if { $board(Mines,left) <= 0 } { done shades }
- }
-
- #####
- #
- # random generator. lifted from netbsd's rand().
- #
- set next 1 ; set randmax 0x7fffffff
- proc rand {} {
- global next randmax
-
- set next [ expr $next * 1103515245 ]
- incr next 12345
- return [ expr $next % $randmax ]
- }
-
- proc srand { seed } {
- global next
- set next $seed
- }
- #####
-
- proc getrandom { range } {
-
- set val [ expr [ rand ] / 2147483647.0 ]
- set val [ expr $val * double($range) + 0.5 ]
- set x [ expr int($val) ]
-
- if { $x == $range } { set x 0 }
- return $x
- }
-
- # build the minefield. initialize settings.
- proc initboard {} {
- global board Map timing player
-
- for { set y -1 } { $y <= $board(YSize) } { incr y } {
- for { set x -1 } { $x <= $board(XSize) } { incr x } {
- set board(type,$y,$x) 0
- }
- }
-
- if {$board(Seed) < 0} {
- srand [ clock clicks ]
- } else {
- srand $board(Seed)
- }
- if {$board(ratio) > 0.0} {
- set v [ expr $board(ratio) * $board(XSize) * $board(YSize) + 0.5 ]
- set board(Mines) [ expr int($v) ]
- }
-
- set mines $board(Mines)
- set limit [ expr 50 * $mines ]
- set count 0
-
- set Map(Coords) {}
- set Map(Flags) {}
- while { $mines > 0 } {
- set x [ getrandom $board(XSize) ]
- set y [ getrandom $board(YSize) ]
-
- if { $board(type,$y,$x) != "mine" } {
- set board(type,$y,$x) mine
- incr mines -1
- lappend Map(Coords) [ list $y $x ]
-
- set ylist [list [expr $y - 1] $y [expr $y + 1]]
- set xlist [list [expr $x - 1] $x [expr $x + 1]]
-
- # increment neighbour's counts.
- foreach j $ylist {
- foreach i $xlist {
- if { $board(type,$j,$i) != "mine" } {
- incr board(type,$j,$i)
- }
- }
- }
- }
- incr count
- if { $count > $limit } {
- puts "Unable to initialize board"
- exit 0
- }
- }
-
- set player(count) $board(Mines)
- set board(Mines,left) $board(Mines)
-
- set win .game.field
- catch { destroy $win }
- frame $win -relief ridge -bd 8
- for { set y 0 } { $y < $board(YSize) } { incr y } {
- frame $win.y$y
- for { set x 0 } { $x < $board(XSize) } { incr x } {
- button $win.y$y.x$x -bd 3 -highlightthickness 0 -image blank
- set bgnd [ $win.y$y.x$x cget -background ]
- $win.y$y.x$x configure -activebackground $bgnd
- bind $win.y$y.x$x <Button-1> "look $x $y"
- bind $win.y$y.x$x <Button-3> "mark $x $y"
- pack $win.y$y.x$x -side left
- }
- pack $win.y$y
- }
- pack $win -side bottom
-
- after cancel timer
- set player(elapsed) 0
- set timing 0
- updatestatus
-
- .game.status.butn configure -image smiley
- bind .game.status.butn <Button> initboard
- }
-
- # choose another mode and restart (invoked by the "Mode" menu).
- proc newmode { type } {
- setmode "-$type"
- initboard
- }
-
- # display help information (invoked by the "Help" menu).
- proc help {} {
- global usage
-
- set msgtxt "
- Minesweeper
- ===========
-
-
- Operation
- ---------
- Click on mouseButton1 to ``step'' on a square.
- If there's a number showing, then that's the number of mines
- bordering on that square. If you ``step'' on a square where
- there's a mine, then the mine explodes and you've lost the game.
-
- Click on mouseButton3 to mark a square with a flag. Click again
- with mouseButton3 to change the mark from a flag to question mark.
- Clicking a third time with mouseButton3 will change the square
- back to being unmarked.
-
- You win the game by marking all the unexploded mines with flags.
-
- Click on the smiley face to start a fresh game.
-
- Press ``q'' to quit the game.
-
-
- Command-line options
- -------------------- $usage
- "
-
- append msglen [ string length $msgtxt ] "c"
-
- set win ".help"
- toplevel $win -relief raised -height 40m
- bind $win <KeyPress-q> "destroy $win"
- bind $win <KeyPress-space> "destroy $win"
- bind $win <KeyPress-Escape> "destroy $win"
- message $win.msg -pady 4m -text "$msgtxt" -width $msglen \
- -foreground blue -background yellow
- pack $win.msg -expand 1 -fill both
- }
-
- # a little blurb (invoked by the "Help" menu).
- proc myreadme {} {
- set msgtxt "
-
- This is a Tcl/Tk port of Greg Lesher's XMine.
-
- It was done as an exercise to try to become more familiar with Tk.
- Not all of XMine's original features have been included but the
- important ones should be there. It seems to work Ok although
- it can take some time to generate the mammoth board (And no wonder.
- 56x40 = 2240 buttons!!! There's probably a more efficient way to port
- this game but button widgets just seemed to be an obvious choice).
-
- All feedback is welcome.
-
- P. Kern, pkern at utcc.utoronto.ca 99/02/18
- "
-
- append msglen [ string length $msgtxt ] "c"
-
- set win ".readme"
- toplevel $win -relief raised -height 40m
- bind $win <KeyPress-q> "destroy $win"
- bind $win <KeyPress-space> "destroy $win"
- bind $win <KeyPress-Escape> "destroy $win"
- message $win.msg -pady 4m -text "$msgtxt" -width $msglen \
- -foreground blue
- pack $win.msg -expand 1 -fill both
- }
-
- # display XMine's README contents (invoked by the "Help" menu).
- proc original {} {
- set msgtxt "
-
- { The original XMine's README file: }
-
- AUTHOR:
- Greg Lesher 1/93
- lesher@cns.bu.edu
-
- DESCRIPTION:
- Color/BW version of Microsoft minesweeper
-
- COMMENTS:
- About the same graphics-wise as the comp.sources.x game ``demineur''
- but supports BW, has more run-time options, and what little
- documentation there is, is not in French.
-
- BUGS:
- Smiley covers digits at beginner level
- Sunglassed smiley appears if you blow up on the last bomb
-
- DISCLAIMER:
- I never heard of the program
- I never heard of you
-
- { Yeah. A wise guy. }
- "
-
- append msglen [ string length $msgtxt ] "c"
-
- set win ".original"
- toplevel $win -relief raised -height 40m
- bind $win <KeyPress-q> "destroy $win"
- bind $win <KeyPress-space> "destroy $win"
- bind $win <KeyPress-Escape> "destroy $win"
- message $win.msg -pady 4m -text "$msgtxt" -width $msglen \
- -foreground blue
- pack $win.msg -expand 1 -fill both
- }
-
- #####
- # set up the menus.
-
- frame .game
-
- set win .game.menubar
- frame $win -relief ridge -bd 8
- menubutton $win.file -text File -menu $win.file.menu -relief raised -bd 3
- menubutton $win.mode -text Mode -menu $win.mode.menu -relief raised -bd 3
- menubutton $win.help -text Help -menu $win.help.menu -relief raised -bd 3
- menu $win.file.menu
- $win.file.menu add separator
- $win.file.menu add command -label Quit -command exit
- menu $win.mode.menu
- set mlist { beg int exp mam }
- if {$board(custom) > 0} { lappend mlist usr }
- foreach mn $mlist {
- $win.mode.menu add command -command "newmode $mn" -label \
- $modes($mn,ident)
- # [ format "%s %dx%d, %d mines" $modes($mn,ident) \
- # $modes($mn,XSize) $modes($mn,YSize) $modes($mn,Mines) ]
- }
- menu $win.help.menu
- $win.help.menu add command -command help -label "Help"
- $win.help.menu add command -command original -label "about the original XMine"
- $win.help.menu add command -command myreadme -label "about this version"
-
- pack $win.file $win.mode -side left
- pack $win.help -side right
- pack $win -side top -fill both
-
- #####
- # set up the status display.
-
- set win .game.status
- frame $win -relief ridge -bd 8
- button $win.butn -bd 3 -image smiley
- label $win.minesleft -textvariable status(count) \
- -relief sunken -foreground red -background black -font 12x24
- label $win.seconds -textvariable status(scnds) \
- -relief sunken -foreground red -background black -font 12x24
- pack $win.minesleft -side left
- pack $win.seconds -side right
- pack $win.butn -before $win.minesleft
- pack $win -side top -fill both
-
- #####
- # get started.
-
- initboard
-
- pack .game
-
- # end of script.
-