There is an n by m grid that has a random number (between 10% to 20% of the total number of tiles, though older implementations may use 20%..60% instead) of randomly placed mines that need to be found.

Positions in the grid are modified by entering their coordinates where the first coordinate is horizontal in the grid and the second vertical. The top left of the grid is position 1,1; the bottom right is at n,m.

 The total number of mines to be found is shown at the beginning of the game.
 Each mine occupies a single grid point, and its position is initially unknown to the player
 The grid is shown as a rectangle of characters between moves.
 You are initially shown all grids as obscured, by a single dot '.'
 You may mark what you think is the position of a mine which will show as a '?'
 You can mark what you think is free space by entering its coordinates.
 If the point is free space then it is cleared, as are any adjacent points that are also free space- this is repeated recursively for subsequent adjacent free points unless that point is marked as a mine or is a mine.
 Points marked as a mine show as a '?'.
 Other free points show as an integer count of the number of adjacent true mines in its immediate neighborhood, or as a single space ' ' if the free point is not adjacent to any true mines.
 Of course you lose if you try to clear space that has a hidden mine.
 You win when you have correctly identified all mines.
The Task is to create a program that allows you to play minesweeper on a 6 by 4 grid, and that assumes all user input is formatted correctly and so checking inputs for correct form may be omitted.
You may also omit all GUI parts of the task and work using text input and output.

Note: Changes may be made to the method of clearing mines to more closely follow a particular implementation of the game so long as such differences and the implementation that they more accurately follow are described.


C.F: wp:Minesweeper (computer game)

len cell[] 56
len cnt[] 56
len flag[] 56
# 
subr initvars
  state = 0
  ticks = 0
  indx = -1
  no_time = 0
.
func getind r c . ind .
  ind = -1
  if r >= 0 and r <= 6 and c >= 0 and c <= 7
    ind = r * 8 + c
  .
.
func draw_cell ind h . .
  r = ind div 8
  c = ind mod 8
  x = c * 12 + 2.5
  y = r * 12 + 14.5
  move x y
  rect 11 11
  if h > 0
    # count
    move x + 3 y + 2
    color 000
    text h
  elif h = -3
    # flag
    x += 4
    color 000
    linewidth 0.8
    move x y + 3
    line x y + 8
    color 600
    linewidth 2
    move x + 0.5 y + 4
    line x + 2 y + 4
  elif h <> 0
    # mine
    color 333
    if h = -2
      color 800
    .
    move x + 5 y + 6
    circle 3
    line x + 8 y + 2
  .
.
func open ind . .
  if ind <> -1 and cell[ind] = 0
    cell[ind] = 2
    flag[ind] = 0
    color 686
    call draw_cell ind cnt[ind]
    if cnt[ind] = 0
      r0 = ind div 8
      c0 = ind mod 8
      for r = r0 - 1 to r0 + 1
        for c = c0 - 1 to c0 + 1
          if r <> r0 or c <> c0
            call getind r c ind
            call open ind
          .
        .
      .
    .
  .
.
func show_mines m . .
  for ind range 56
    if cell[ind] = 1
      color 686
      if m = -1
        color 353
      .
      call draw_cell ind m
    .
  .
.
func outp col s$ . .
  move 2.5 2
  color col
  rect 59 11
  color 000
  move 5 4.5
  text s$
.
func upd_info . .
  nm = 0
  nc = 0
  for i range 56
    nm += flag[i]
    if cell[i] < 2
      nc += 1
    .
  .
  if nc = 8
    call outp 484 "Well done"
    call show_mines -1
    state = 1
  else
    call outp 464 8 - nm & " mines left"
  .
.
func test ind . .
  if cell[ind] < 2 and flag[ind] = 0
    if cell[ind] = 1
      call show_mines -1
      color 686
      call draw_cell ind -2
      call outp 844 "B O O M !"
      state = 1
    else
      call open ind
      call upd_info
    .
  .
.
background 676
func start . .
  clear
  color 353
  for ind range 56
    cnt[ind] = 0
    cell[ind] = 0
    flag[ind] = 0
    call draw_cell ind 0
  .
  n = 8
  while n > 0
    c = random 8
    r = random 7
    ind = r * 8 + c
    if cell[ind] = 0
      n -= 1
      cell[ind] = 1
      for rx = r - 1 to r + 1
        for cx = c - 1 to c + 1
          call getind rx cx ind
          if ind > -1
            cnt[ind] += 1
          .
        .
      .
    .
  .
  call initvars
  call outp 464 ""
  textsize 4
  move 5 3
  text "Minesweeper - 8 mines"
  move 5 7.8
  text "Long-press for flagging"
  textsize 6
  timer 0
.
on mouse_down
  if state = 0
    if mouse_y < 14 and mouse_x > 60
      no_time = 1
      move 64.5 2
      color 464
      rect 33 11
    .
    call getind (mouse_y - 14) div 12 (mouse_x - 2) div 12 indx
    ticks0 = ticks
  elif state = 3
    call start
  .
.
on mouse_up
  if state = 0 and indx <> -1
    call test indx
  .
  indx = -1
.
on timer
  if state = 1
    state = 2
    timer 1
  elif state = 2
    state = 3
  elif no_time = 0 and ticks > 3000
    call outp 844 "B O O M !"
    call show_mines -2
    state = 2
    timer 1
  else
    if indx > -1 and ticks = ticks0 + 2
      if cell[indx] < 2
        color 353
        flag[indx] = 1 - flag[indx]
        opt = 0
        if flag[indx] = 1
          opt = -3
        .
        call draw_cell indx opt
        call upd_info
      .
      indx = -1
    .
    if no_time = 0 and ticks mod 10 = 0
      move 64.5 2
      color 464
      if ticks >= 2500
        color 844
      .
      rect 33 11
      color 000
      move 66 4.5
      text "Time:" & 300 - ticks / 10
    .
    ticks += 1
    timer 0.1
  .
.
call start