wwwRong

minesweeper_pil_2_lua

Oct 28th, 2021
718
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2. โค้ดต้นฉบับจาก https://rosettacode.org/wiki/Minesweeper_game#PicoLisp
  3.  
  4. # NIL    Hidden: Empty field
  5. # T      Hidden: Mine
  6. # 0-8    Marked: Empty field
  7. # ?      Marked: Mine
  8.  
  9. (de minesweeper (DX DY Density)
  10.    (default Density 20)
  11.    (setq *Field (make (do DY (link (need DX)))))
  12.    (use (X Y)
  13.       (do (prinl "Number of mines: " (*/ DX DY Density 100))
  14.          (while
  15.             (get *Field
  16.                (setq Y (rand 1 DY))
  17.                (setq X (rand 1 DX)) ) )
  18.          (set (nth *Field Y X) T) ) )
  19.    (showMines) )
  20.  
  21. (de showMines ()
  22.    (for L *Field
  23.       (for F L
  24.          (prin (if (flg? F) "." F)) )
  25.       (prinl) ) )
  26.  
  27. (de *NeighborX -1  0 +1 -1  +1 -1  0 +1)
  28. (de *NeighborY -1 -1 -1  0   0 +1 +1 +1)
  29.  
  30. (de c (X Y)
  31.    (if (=T (get *Field Y X))
  32.       "KLABOOM!! You hit a mine."
  33.       (let Visit NIL
  34.          (recur (X Y)
  35.             (when
  36.                (=0
  37.                   (set (nth *Field Y X)
  38.                      (cnt
  39.                         '((DX DY)
  40.                            (=T (get *Field (+ Y DY) (+ X DX))) )
  41.                         *NeighborX
  42.                         *NeighborY ) ) )
  43.                (mapc
  44.                   '((DX DY)
  45.                      (and
  46.                         (get *Field (inc 'DY Y))
  47.                         (nth @ (inc 'DX X))
  48.                         (not (member (cons DX DY) Visit))
  49.                         (push 'Visit (cons DX DY))
  50.                         (recurse DX DY) ) )
  51.                   *NeighborX
  52.                   *NeighborY ) ) ) )
  53.       (showMines) ) )
  54.  
  55. (de m (X Y)
  56.    (set (nth *Field Y X) '?)
  57.    (showMines)
  58.    (unless (fish =T *Field)
  59.       "Congratulations! You won!!" ) )
  60. ]]
  61.  
  62. -- แปลงเป็น Lua ดัดแปลงเพิ่มเติมจากโค้ด Julia ด้วย
  63.  
  64. local Field, Visit, Mark = {}, {}, {}
  65. local Mines = {}
  66. local Neighbor = {
  67.   {-1,-1}, {-1,0}, {-1,1},
  68.   {0,-1}, {0,1},
  69.   {1,-1}, {1,0}, {1,1}
  70. }
  71. local total_mines, mines
  72. local visited = 0
  73. local end_game = false
  74.  
  75. function init_mines(dx, dy)
  76.   for y=1, dy do
  77.     Field[y] = {}
  78.     Visit[y] = {}
  79.     Mark[y] = {}
  80.     for x=1, dx do
  81.       Field[y][x] = false
  82.       Visit[y][x] = false
  83.       Mark[y][x] = false
  84.     end
  85.   end
  86.   total_mines = ("%.f"):format(dx * dy * 0.15)
  87.   mines = tonumber(total_mines)
  88.   for i=1, mines do
  89.     local x = math.random(1, dx)
  90.     local y = math.random(1, dy)
  91.     while Field[y][x] do
  92.       x = math.random(1, dx)
  93.       y = math.random(1, dy)
  94.     end
  95.     Field[y][x] = true
  96.   end
  97.   show_mines()
  98. end
  99.  
  100. function show_mines()
  101.   print("Number of mines: "..mines .."/".. total_mines .."\n")
  102.   io.write("   ")
  103.   for i=1, #Field[1] do
  104.     io.write(i .."  ")
  105.   end
  106.   print("\n"..("-"):rep(#Field[1]*3+2))
  107.   for y, row in ipairs(Field) do
  108.     io.write(y .."| ")
  109.     for x, pos in ipairs(row) do
  110.       if end_game then
  111.         io.write(pos==true and "*" or (pos==false and ".") or pos)
  112.       else
  113.         io.write(Mark[y][x] and Mark[y][x] or (type(pos)=="boolean" and "." or pos))
  114.       end
  115.       io.write "  "
  116.     end
  117.     print()
  118.   end
  119.   print()
  120. end
  121.  
  122. function Mines.o(x, y)
  123.   if Field[y][x]==true then
  124.     print "KLABOOM!! You hit a mine."
  125.     end_game = true
  126.   else
  127.     visited = visited + 1
  128.     function o(x, y)
  129.       local cnt = 0
  130.       for _, v in ipairs(Neighbor) do
  131.         if Field[y+v[1]] and Field[y+v[1]][x+v[2]]==true then
  132.           cnt = cnt + 1
  133.         end
  134.       end
  135.       Field[y][x] = cnt>0 and cnt or " "
  136.       if Field[y][x]==" " then
  137.         for _, v in ipairs(Neighbor) do
  138.           local dx, dy = x+v[2], y+v[1]
  139.           if Field[dy] and Field[dy][dx]==false then
  140.             if not Visit[dy][dx] then
  141.               Visit[dy][dx] = true
  142.               visited = visited + 1
  143.             end
  144.             o(dx, dy)
  145.           end
  146.         end
  147.       end
  148.     end
  149.     o(x, y)
  150.   end
  151.   show_mines()
  152. end
  153.  
  154. function Mines.m(x, y)
  155.   local tmp = Mark[y][x]
  156.   if not tmp then
  157.     Mark[y][x] = "?"
  158.     visited = visited + 1
  159.     mines = mines - 1
  160.   elseif tmp=="?" then
  161.     Mark[y][x] = false
  162.     visited = visited - 1
  163.     mines = mines + 1
  164.   end
  165.   show_mines()
  166. end
  167.  
  168. io.write("Enter grid size X Y: ")
  169. local col, row = io.read("n", "n")
  170. init_mines(col, row)
  171. local fn, x, y
  172. while true do
  173.   io.write("Enter command\n 'o x y' for open at position x,y\n 'm x y' for mark at position x,y\n 'c' for close\n: ")
  174.   while true do
  175.     local cmd = io.read()
  176.     if cmd=='c' then
  177.       print("You closed the game.")
  178.       os.exit()
  179.     end
  180.     fn, x, y = cmd:match("([om])%s(%d)%s(%d)")
  181.     x, y = math.tointeger(x), math.tointeger(y)
  182.     if Mines[fn]
  183.       and 0 < x and x <= col
  184.       and 0 < y and y <= row
  185.     then
  186.       break
  187.     end
  188.   end
  189.   Mines[fn](x, y)
  190.   print(visited, col*row-mines)
  191.   if visited >= (col*row)-mines then
  192.     print "Congratulations! You won!!"
  193.     break
  194.   elseif end_game then
  195.     break
  196.   end
  197. end
RAW Paste Data