wwwRong

minesweeper_pil_2_lua

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