!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! !
! MINE !
! !
! Mine is the classic game where a field of hidden mines is presented, and the !
! user tries to find the mines based on mine counts in adjacent squares. !
! !
! Derived from the Pascal version. !
! !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
etchar% = 0 ! ANSI character returned
etup% = 1 ! cursor up one line
etdown% = 2 ! down one line
etleft% = 3 ! left one character
etright% = 4 ! right one character
etleftw% = 5 ! left one word
etrightw% = 6 ! right one word
ethome% = 7 ! home of document
ethomes% = 8 ! home of screen
ethomel% = 9 ! home of line
etend% = 10 ! end of document
etends% = 11 ! end of screen
etendl% = 12 ! end of line
etscrl% = 13 ! scroll left one character
etscrr% = 14 ! scroll right one character
etscru% = 15 ! scroll up one line
etscrd% = 16 ! scroll down one line
etpagd% = 17 ! page down
etpagu% = 18 ! page up
ettab% = 19 ! tab
etenter% = 20 ! enter line
etinsert% = 21 ! insert block
etinsertl% = 22 ! insert line
etinsertt% = 23 ! insert toggle
etdel% = 24 ! delete block
etdell% = 25 ! delete line
etdelcf% = 26 ! delete character forward
etdelcb% = 27 ! delete character backward
etcopy% = 28 ! copy block
etcopyl% = 29 ! copy line
etcan% = 30 ! cancel current operation
etstop% = 31 ! stop current operation
etcont% = 32 ! continue current operation
etprint% = 33 ! print document
etprintb% = 34 ! print block
etprints% = 35 ! print screen
etfun% = 36 ! function key
etmenu% = 46 ! display menu
etmouba% = 47 ! mouse button assertion
etmoubd% = 51 ! mouse button deassertion
etmoumov% = 55 ! mouse move
ettim% = 56 ! timer matures
etjoyba% = 57 ! joystick button assertion
etjoybd% = 58 ! joystick button deassertion
etjoymov% = 59 ! joystick move
etterm% = 60 ! terminate program
! program defines
maxxs% = 8 ! size of grid
maxys% = 8
maxmine% = 10 ! number of mines to place
dim mine%(maxxs%, maxys%) ! mine exists map
dim vis%(maxxs%, maxys%) ! square is uncovered map
dim flag%(maxxs%, maxys%) ! square is flagged map
! Contruct table to calculate adjacent squares
dim xoff%(8) ! x offset table
dim yoff%(8) ! y offset table
xoff%(1) = 0: yoff%(1) = -1 ! up
xoff%(2) = +1: yoff%(2) = -1 ! upper right
xoff%(3) = +1: yoff%(3) = 0 ! right
xoff%(4) = +1: yoff%(4) = +1 ! lower right
xoff%(5) = 0: yoff%(5) = +1 ! down
xoff%(6) = -1: yoff%(6) = +1 ! lower left
xoff%(7) = -1: yoff%(7) = 0 ! left
xoff%(8) = -1: yoff%(8) = -1 ! upper left
! declares, not required but nice
dim x%, y% ! user move coordinates
dim done% ! game over
dim centerx% ! center of screen position x
dim centery% ! center of screen position y
dim cursorx% ! cursor location x
dim cursory% ! cursor location y
dim badguess% ! bad guess display flag
dim mousex% ! mouse position x
dim mousey% ! mouse position y
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Find adjacent mines
!
! Finds the number of mines adjacent to a given square.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
function adjacent%(x%, y%)
dim mines% ! number of mines
dim xn%, yn% ! neighbor coordinates }
dim i% ! index for move array }
mines% = 0 ! clear mine count
for i% = 1 to 8 ! process points of the compass
xn% = x%+xoff%(i%) ! find neighbor locations
yn% = y%+yoff%(i%)
if xn% >= 1 and xn% <= maxxs% and yn% >= 1 and yn% <= maxys% then
! valid location
if mine%(xn%, yn%) then mines% = mines%+1 ! count mines
endif
next i%
endfunc mines% ! return the number of mines
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Set adjacent squares visable
!
! Sets all of the valid adjacent squares visable. If any of those squares are
! not adjacent to a mine, then the neighbors of that square are set visable, etc.
! (recursively).
! This is done to "rip" grids of obviously empty neighbors off the board.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedure visadj(x%, y%)
dim xn%, yn% ! neighbor coordinates
dim i% ! index for move array
for i% = 1 to 8 ! process points of the compass
xn% = x%+xoff%(i%) ! find neighbor locations
yn% = y%+yoff%(i%)
if xn% >= 1 and xn% <= maxxs% and yn% >= 1 and yn% <= maxys% then
if not vis%(xn%, yn%) then ! not already visable
! valid location
vis%(xn%, yn%) = true% ! set visable
if adjacent%(xn%, yn%) = 0 then visadj(xn%, yn%) ! perform recursively
endif
endif
next i%
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Display board
!
! Displays the playing board.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedure display
dim x%
dim y%
dim cnt% ! count of adjacent mines
! scan screen
bcolor(yellow%) ! set background color
for y% = 1 to maxys%
for x% = 1 to maxxs%
cursor(centerx%+x%-1, centery%+y%-1) ! set start of next line
if vis%(x%, y%) then
if mine%(x%, y%) then print "*"; else
cnt% = adjacent%(x%, y%) ! find adjacent mine count
if cnt% = 0 then
print "." ! no adjacent
else
print chr$(cnt%+asc("0")); ! place the number
endif
endif
else if flag%(x%, y%) then ! display flagged location
if badguess% then print "X"; else print "M";
else print "=";
endif
next x%
next y%
print
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Initalize board
!
! Clears all board squares to no mines, invisible and not flagged.
! Then, the specified number of mines are layed on the board at random.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedure clrbrd
dim x%
dim y%
dim n%
for x% = 1 to maxxs% ! clear minefield
for y% = 1 to maxys%
mine%(x%, y%) = false ! set no mine
vis%(x%, y%) = false ! set not visible
flag%(x%, y%) = false ! set not flagged
next y%
next x%
for n% = 1 to maxmine ! place mine
repeat
x% = rnd(0)*maxxs%
y% = rnd(0)*maxys%
until not mine%(x%, y%) ! no mine exists at square
mine%(x%, y%) = true ! place mine
next n%
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Clear line
!
! Clears the specified line to spaces in the specified color.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedure clrlin(y%, clr%)
dim i%
cursor(1, y%) ! position to specified line
bcolor(clr%) ! set color
for i% = 1 to maxx% do print " "; ! clear line
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Print centered string
!
! Prints the given string centered on the given line.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedure prtmid(y%, s$)
cursor(maxx% div 2-len(s$) div 2, y%) ! position to start
print s$; ! output the string
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Draw character box
!
! Draws a box of the given color and character to the location.
! The colors are not saved or restored.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
bcolor(bclr%)
fcolor(fclr%)
cursor(sx%, sy%) ! position at box top left
for x% = sx% to ex%: print c$;: next x% ! draw box top
cursor(sx%, ey%) ! position at box lower left
for x% = sx% to ex%: print c$;: next x% ! draw box bottom
for y% = sy%+1 to ey%-1 ! draw box left side
cursor(sx%, y%) ! place cursor
print c$; ! place character
next y%
for y% = sy%+1 to ey%-1 ! draw box left side
cursor(ex%, y%) ! place cursor
print c$; ! place character
next y%
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Check coordinates on board
!
! Checks if the given x, y coordinates are in the valid playing area..
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
function insquare%(x%, y%)
dim inx% ! inside x
dim iny% ! inside y
inx% = mousex% >= centerx% and mousex% <= centerx%+maxxs%-1 ! find x
iny% = mousey% >= centery% and mousey% <= centery%+maxys%-1 ! find y
endfunc inx% and iny%
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Check replay
!
! Asks the user if a replay is desired, then either cancels the game, or
! sets up a new game as requested.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedure replay
! ask user for replay
bcolor(cyan%)
prtmid(maxy%, "PLAY AGAIN (Y/N) ?")
repeat ! wait for response
! wait till a character is pressed
repeat
event(nextevent)
until nextevent.etype = etchar% or nextevent.etype = etterm%
if nextevent.etype = etterm% then done% = true% ! force a quit
until lcase(nextevent.char$) = "y" or lcase(nextevent.char) = "n" or done%
if lcase(nextevent.char$) = "n" or done% then done% = true% else
! clear old messages
clrlin(maxy%-2, cyan%)
clrlin(maxy%, cyan%)
! start new game
clrbrd ! set up board
cursorx% = centerx% ! set inital cursor position
cursory% = centery%
badguess% = false% ! set bad guesses invisible
endif
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Process square "hit"
!
! Processes a "hit" on a square, which means revealing that square, and possibly
! triggering a mine.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedure hit(x%, y%)
dim xi%, yi% ! indexes for board
dim viscnt% ! visable squares count
vis%(x%, y%) = true% ! set that location visable
if mine%(x%, y%) then ! mine found
! make all mines visable, and bad guesses too.
for yi% = 1 to maxys%
for xi = 1 to maxxs%
if mine%(xi%, yi%) then vis%(xi%, yi%) = true%
next xi%
next yi%
badguess% = true% ! set bad guesses visable
display ! redisplay board
! announce that to the player
bcolor(red%)
prtmid(maxy%-2, "*** YOU HIT A MINE ! ***")
replay ! process replay
else ! valid hit
if adjacent%(x%, y%) = 0 then visadj(x%, y%) ! clean up adjacent spaces
! now, the player may have won. we find this out by counting all of the
! visable squares, and seeing if the number of squares left is equal
! to the number of mines
viscnt% = 0
for yi% = 1 to maxys%
for xi% = 1 to maxxs%
if vis%(xi%, yi%) then viscnt% = viscnt%+1 ! count visible
next xi%
next yi%
if maxxs%*maxys%-viscnt% = maxmine% then ! player wins
display ! redisplay board
! announce that to the player
bcolor(red%)
prtmid(maxy%-2, "*** YOU WIN ! ***")
replay ! process replay
endif
endif
display ! redisplay board
endproc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Main process
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
auto(false%) ! turn off scrolling
bcolor(cyan%) ! color the background
clear ! clear to that
bcolor(magenta%)
prtmid(1, "******* Mine game 1.0 ********") ! output title
! find center board position
centerx% = maxx% div 2-maxxs% div 2
centery% = maxy% div 2-maxys% div 2
! draw a border around that
tbox(centerx%-1, centery%-1, centerx%+maxxs%, centery%+maxys%, " ", blue%, black%)
bcolor(white%) ! restore the background
clrbrd ! set up board
display ! display board }
done% = false% ! set game in progress
cursorx% = centerx% ! set inital cursor position
cursory% = centery%
badguess% = false% ! set bad guesses invisible
repeat ! enter user moves
cursor(cursorx%, cursory%) ! place cursor
x% = cursorx%-centerx%+1 ! set location on board
y% = cursory-centery+1
event(nextevent) ! get the next event
select nextevent.etype% ! event
case ettab% ! process flag
! reverse flagging on location
flag(x%, y%) = not flag(x%, y%)
display ! redisplay board
case etenter%: hit(x%, y%) ! process hit
! move up
case etup%: if cursory% > centery% then cursory% = cursory%-1
! move left
case etleft%: if cursorx% > centerx% then cursorx% = cursorx%-1
! move down
case etdown%: if cursory% < centery%+maxys%-1 then cursory% = cursory%+1
! move right
case etright%: if cursorx% < centerx%+maxxs%-1 then cursorx% = cursorx%+1
case etmoumov% ! mouse movement
mousex% = nextevent.moupx% ! set new mouse position
mousey% = nextevent.moupy%
case etmouba ! mouse button 1, hit
if nextevent.amoubn% = 1 and onboard%(mousex%, mousey%) then
! mouse postion inside valid square
cursorx% = mousex% ! set current position to that
cursory% = mousey%
x% = cursorx%-centerx%+1 ! set location on board
y% = cursory%-centery%+1
hit(x%, y%) ! process hit
else if nextevent.amoubn% = 2 and onboard%(mousex%, mousey%) then
! mouse postion inside valid square
cursorx% = mousex% ! set current position to that
cursory% = mousey%
x% = cursorx%-centerx%+1 ! set location on board
y% = cursory%-centery%+1
! reverse flagging on location
flag(x%, y%) = flag(x%, y%)
display ! redisplay board
endif
endsel
until done% or nextevent.etype% = etterm% ! game complete
auto(true%) ! turn off scrolling
bcolor(white%) ! restore colors
fcolor(black%)
clear ! clear screen