///////////////////////////////////////////////////////////////////// // // // COPY THIS ENTIRE SOURCE LISTING AND SAVE IT AS A FILE NAMED // // "kit" (OR "kit.txt") IN YOUR PROJECT'S "Library" FOLDER // // // ///////////////////////////////////////////////////////////////////// Task draw field (Int a, Int b, Int c, Int d) * * Draws a field of gray tiles inside a gray frame. * * Enter with: * * (a,b) - the coordinates of the upper-left tile in the frame. * (c,d) - the coordinates of the lower-right tile in the frame. * Common Int data[40][25], boomz Common Int minx=1, miny=1, maxx=40, maxy=25 boomz=0 aa=a; cc=c If aa>cc aa=c; cc=a Endif bb=b; dd=d If bb>dd bb=d; dd=b Endif If (amaxx) cc=maxx If (d>maxy) dd=maxy frame (16*aa-12, 15*bb-16, 16*cc+4, 15*dd-1, 7) minx=aa; miny=bb; maxx=cc; maxy=dd Do y=bb,dd Do x=aa,cc draw tile (x, y) @ If (x=aa Or x=cc Or y=bb Or y=dd) data[x-1][y-1]=256*5 Else data[x-1][y-1]=256*8 Loop Loop data[aa-1][bb-1]=256*3 data[aa-1][dd-1]=256*3 data[cc-1][bb-1]=256*3 data[cc-1][dd-1]=256*3 wait (0) Task plant mine (Int x, Int y) * * Puts a mine at location (x,y) if no mine is already there. * Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return data[x-1][y-1]=bitor(data[x-1][y-1],1) Task remove mine (Int x, Int y) * * Removes a mine from location (x,y) if a mine is there. * Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return data[x-1][y-1]=bitand(data[x-1][y-1],15*256+6) Task plant mines (Int n) * * Randomly fills the field with mines. * (Each tile has 1/n chance of receiving a mine.) * Common Int data[40][25] Common Int minx, miny, maxx, maxy Do y=miny,maxy Do x=minx,maxx If (!random(n)) data[x-1][y-1]=bitor(data[x-1][y-1],1) Endif Loop Loop Task show nulls * * Uncovers all tiles whose mine proximity count is zero. * Common Int data[40][25], quiet Common Int minx, miny, maxx, maxy quiet=1 Do y=miny,maxy Do x=minx,maxx If data[x-1][y-1]%2 Continue If !count(x,y) Do yy=y-1,y+1 Do xx=x-1,x+1 reveal (xx, yy, 0) @ Loop Loop Endif Loop Loop quiet=0 Task auto proc (Int mode, Int err, Int x, Int y) * * Uncovers and/or marks all tiles whose identities are "obvious". * * Enter with: * mode=0, (do nothing) * mode=1, mark all obvious tiles * mode=2, uncover all obvious tiles * mode=3, mark and uncover all obvious tiles * * Return with: * err=0, no mines were uncovered * err<0, then (x,y) is location of uncovered mine * Common Int xx, yy Do marked =0; If (bitand(mode,1)) marked= markobv() revealed=0; If (bitand(mode,2)) revealed=revobv() If revealed<0 err=-1 x=xx; y=yy Return Endif If !marked And !revealed Break Loop err=0 Int markobv() Common Int data[40][25], quiet, nm, nv Common Int minx, miny, maxx, maxy flag=0; quiet=1 Do y=miny,maxy Do x=minx,maxx If !bitand(data[x-1][y-1],4) Continue nb=count(x,y) If data[x-1][y-1]/256-nv=nb Do yy=y-1,y+1 If yymaxy Continue Do xx=x-1,x+1 If xxmaxx Continue If xx=x And yy=y Continue If (!bitand(data[xx-1][yy-1],4) And !bitand(data[xx-1][yy-1],2)) toggle marker (xx, yy) @ flag=1 Endif Loop Loop Endif Loop Loop quiet=0 Return flag Int revobv() Common Int data[40][25], quiet, nm, nv Common Int minx, miny, maxx, maxy Common Int xx, yy, oops flag=0; quiet=1 Do y=miny,maxy Do x=minx,maxx If !bitand(data[x-1][y-1],4) Continue nb=count(x,y) If nm=nb Do yy=y-1,y+1 If yymaxy Continue Do xx=x-1,x+1 If xxmaxx Continue If xx=x And yy=y Continue If (!bitand(data[xx-1][yy-1],4) And !bitand(data[xx-1][yy-1],2)) reveal (xx, yy, oops) @ If oops<0 Return oops flag=1 Endif Loop Loop Endif Loop Loop quiet=0 Return flag Task toggle marker (Int x, Int y) * * Toggles on or off the mine marker on tile (x,y) * Common Int data[40][25], quiet Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return If bitand(data[x-1][y-1],4) Return If !quiet sound (1500) delay (5) nosound Endif data[x-1][y-1]=bitxor(data[x-1][y-1],2) If (bitand(data[x-1][y-1],2)) draw mine (x, y) @ Else draw tile (x, y) @ Task reveal (Int x, Int y, Int z) * * Uncovers the tile at location (x,y) and displays * the mine proximity count for that location. If * no mine is uncovered, returns z=0. If a mine is * revealed, it is displayed on a red square, and the * value -1 is returned in z. * Common Int data[40][25], quiet=0 Common Int minx, miny, maxx, maxy Common Int boomx, boomy, boomz z=0; boomz=0 If xmaxx Or y>maxy Return If bitand(data[x-1][y-1],4) Return If bitand(data[x-1][y-1],2) Return If !quiet sound (2000) delay (5) nosound Endif If bitand(data[x-1][y-1],1) draw oops (x, y) @ boomx=x boomy=y boomz=1 z=-1 Return Endif revealx (x, y) @ data[x-1][y-1]=bitor(data[x-1][y-1],4) Task revealx (Int x, Int y) * z=count(x,y) If (!z) ch=" " Else ch=char(48+z) color=0 If (z=1) color=9 If (z=2) color=2 If (z=3) color=12 If (z=4) color=1 If (z=5) color=4 If (z=6) color=5 If (z=7) color=6 draw textile (ch, color, x, y) @ Task test for done (Int z) * * Looks to see if all tiles have been either uncovered * or marked as mines. If so, returns z=1. Otherwise, * returns z=0. * Common Int data[40][25] Common Int minx, miny, maxx, maxy z=0 Do yy=miny,maxy Do xx=minx,maxx If bitand(data[xx-1][yy-1],3)=3 Continue If bitand(data[xx-1][yy-1],4) Continue Return Loop Loop z=1 Task show mines * * Reveals all unmarked mines in the field. * If a tile was incorrectly marked, a red * "X" is displayed on that tile. * Common Int minx, miny, maxx, maxy Common Int boomx, boomy, boomz Common Int data[40][25] frame (16*minx-12, 15*miny-16, 16*maxx+4, 15*maxy-1, 7) Do y=boomy-5, boomy+5 Do x=boomx-5, boomx+5 If (bitand(data[x-1][y-1],4)) revealx (x, y) @ Else draw tile (x, y) @ If (bitand(data[x-1][y-1],2)) draw mine (x, y) @ Endelse Loop Loop Do y=miny,maxy Do x=minx,maxx If (bitand(data[x-1][y-1],3)=1) xx=x; yy=y; tile to pixel (xx, yy) @ // solid color (7) // solid rectangle (xx-7, yy-7, xx+7, yy+7) draw tile (x, y) @ draw mine (x, y) @ Endif If (bitand(data[x-1][y-1],3)=2) draw red x (x, y) @ Loop Loop If (boomz) draw oops (boomx, boomy) @ //-------------------------------------------------------------------------- Task pixel to tile (Int x, Int y) * * Converts the numerical values of (x,y) from pixel * coordinates [640x480] into tile coordinates [40x25]. * x=(x+12)/16 y=(y+1)/15+1 Task tile to pixel (Int x, Int y) * * Converts the numerical values of (x,y) from tile * coordinates [40x25] into pixel coordinates [640x480] * centered on the tile. * x=16*x-4 y=15*y-9 Task status (Int x, Int y, Int visible, Int marked, Int mine) * * Returns the current state of the tile located at (x,y): * * visible - 0: tile has not yet been revealed * 4: tile has been revealed * marked - 0: tile is not currently marked as covering a mine * 2: tile is currently marked as covering a mine * mine - 0: tile is not actually covering a mine * 1: tile is actually covering a mine * Common Int minx, miny, maxx, maxy Common Int data[40][25] visible=0; marked=0; mine=0 If xmaxx Or y>maxy Return visible=bitand(data[x-1][y-1],4) marked =bitand(data[x-1][y-1],2) mine =bitand(data[x-1][y-1],1) Task neighbors (Int x, Int y, Int visible, Int marked, Int mines) * * Returns the proximity counts [0-8] for the tile located at (x,y): * * visible: number of neighboring tiles that have been revealed * marked: number of neighboring tiles that have been marked * mines: number of neighboring tiles that are covering a mine * Common Int nm, nv Common Int minx, miny, maxx, maxy visible=0; marked=0; mines=0 If xmaxx Or y>maxy Return mines=count(x,y) visible=nv; marked=nm Task wait mouse (Int x, Int y, Int z) * * Waits until a mouse button is pushed and released. * It then returns the current location (x,y) of the * mouse (in tile coordinates) along with the button * value (z). * * [If a graphics button on the screen has been pressed, * returns in z the negative id value of the button. If * the 'Esc' key is pressed, terminates the program.] * Int zz Do read quit key (27) read mouse (x, y, z) If z Break wait (0) Loop Do read mouse (x, y, zz) id=read buttons (x, y, zz) If (id) z=-iabs(id) If !zz Break wait (0) Loop pixel to tile (x, y) @ Task draw button (Int id, Text label, Int color) * * Draws a gray button on the screen at the current cursor position. * * Enter with: * id - the button's ID number (1-32) * label - the label to be drawn on the button * color - the color of the surrounding rectangle * x=wherex(); y=wherey() line color (0) fill color (color) filled rectangle (8*x-23, 15*y-29, 8*(x+length(label))+5, 15*y+12) draw button (id, label, 7, 1) Task victory * * Plays a bugle call. * id = open mci ("\\simple\\sounds\\bugle.mid") start mci (id) wait mci done (id) close mci (id) *------------------------------------------------------------------------- * * [The following tasks are intended for internal use only, but are made * available for those advanced users who may want to access them.] * Task draw mine (Int x, Int y) Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return xx=x; yy=y; tile to pixel (xx, yy) @ line color (0) line (xx-3, yy-4, xx+4, yy+3) line (xx-4, yy-4, xx+4, yy+4) line (xx-4, yy-3, xx+3, yy+4) line (xx-4, yy+3, xx+3, yy-4) line (xx-4, yy+4, xx+4, yy-4) line (xx-3, yy+4, xx+4, yy-3) line (xx-5, yy, xx+5, yy) line (xx, yy-5, xx, yy+5) fill color (4) filled circle (xx, yy, 3) put pixel (xx, yy, 12) Task draw oops (Int x, Int y) Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return xx=x; yy=y; tile to pixel (xx, yy) @ solid color (12) solid rectangle (xx-6, yy-6, xx+6, yy+6) draw mine (x, y) @ Task draw red x (Int x, Int y) Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return xx=x; yy=y; tile to pixel (xx, yy) @ line color (12) line (xx-4, yy-5, xx+5, yy+4) line (xx-5, yy-5, xx+5, yy+5) line (xx-5, yy-4, xx+4, yy+5) line (xx-5, yy+4, xx+4, yy-5) line (xx-5, yy+5, xx+5, yy-5) line (xx-4, yy+5, xx+5, yy-4) Task draw textile (Text t, Int color, Int x, Int y) Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return xx=16*x-8; yy=15*y-15 line color (0) fill color (7) filled rectangle (xx-4, yy-1, xx+12, yy+14) tabxy (2*x, y) cwrite (t, color, 7) line (xx-4, yy+14, xx+12, yy+14) Task draw tile (Int x, Int y) Common Int minx, miny, maxx, maxy If xmaxx Or y>maxy Return xx=16*x-8; yy=15*y-15 line color (0) fill color (7) filled rectangle (xx-4, yy-1, xx+12, yy+14) line color (15) line (xx-3, yy, xx+11, yy) line (xx-3, yy, xx-3, yy+14) line color (8) line (xx-2, yy+13, xx+11, yy+13) line (xx+11, yy+1, xx+11, yy+13) Int count (Int x, Int y) Common Int data[40][25], nm, nv Common Int minx, miny, maxx, maxy nb=0; nm=0; nv=0 Do a=x-1,x+1 If amaxx Continue Do b=y-1,y+1 If bmaxy Continue If a=x And b=y Continue If bitand(data[a-1][b-1],1) Set nb=nb+1 If bitand(data[a-1][b-1],2) Set nm=nm+1 If bitand(data[a-1][b-1],4) Set nv=nv+1 Loop Loop Return nb