Advertisement
Guest User

go.lua

a guest
Apr 30th, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.51 KB | None | 0 0
  1. local term = require("term")
  2. local unicode = require("unicode")
  3. local black_char = unicode.char(75435)
  4. local white_char = unicode.char(75434)
  5. local stone_chars = {black_char, white_char}
  6.  
  7. local Go = {}
  8. Go._index = Go
  9.  
  10. function Go:new(size, SX, SY, ratio)
  11.   if not size then size = 9 end
  12.   local o = {}
  13. --    {1,2,1,1},
  14. --    {1,2,1,1},
  15. --    {1,2,1,1},
  16. --    {1,1,2,1}
  17. --  }
  18.   o.size = size
  19.   o.move = 2
  20.   o.SX = SX or 10
  21.   o.SY = SY or 7
  22.   o.ratio = ratio or {2,3}
  23.   if true then
  24.     for i = 1, size do
  25.       o[i] = {}
  26.       for j = 1, size do
  27.         o[i][j] = 1
  28.       end
  29.     end
  30.   end
  31.  
  32.   setmetatable(o, self)
  33.   self.__index = self
  34.   return o
  35. end
  36.  
  37. function init_was(size, x, y)
  38.   local was = {}
  39.   for i = 1, size do
  40.     was[i] = {}
  41.     for j = 1, size do
  42.       was[i][j] = false
  43.     end
  44.   end
  45.   if x and y then
  46.     was[x][y] = true
  47.   end
  48.  
  49.   return was
  50. end
  51.  
  52. ------------------------------------- BFS Function ---------------------------------------
  53. -- Explores a group specified by one of it's points (x,y)
  54. -- Return array of 3 elements:
  55. -- 1: Empty places group (if x,y on field is empty) OR list of empty places near the group
  56. -- 2: Black stones group (if x,y on field is black) OR list of black stones near the group
  57. -- 3: White stones group (if x,y on field is white) OR list of white stones near the group
  58.  
  59. function Go:bfs(i, j, was)
  60.   local list = {{},{},{}}
  61.   local idx = 1
  62.   local stone = self[i][j]
  63.   list[stone][1] = {i,j}
  64.   if not was then
  65.     was = init_was(self.size)
  66.   end
  67.   was[i][j] = true
  68.  
  69.   while idx <= #list[stone] do
  70.     local i = list[stone][idx][1]
  71.     local j = list[stone][idx][2]
  72.     if i - 1 > 0 and not was[i-1][j] then
  73.       local l = list[self[i-1][j]]
  74.       l[#l+1] = {i-1, j}
  75.       was[i-1][j] = true
  76.     end
  77.     if j - 1 > 0 and not was[i][j-1] then
  78.       local l = list[self[i][j-1]]
  79.       l[#l+1] = {i, j-1}
  80.       was[i][j-1] = true
  81.     end
  82.     if i + 1 <= self.size and not was[i+1][j] then
  83.       local l = list[self[i+1][j]]
  84.       l[#l+1] = {i+1, j}
  85.       was[i+1][j] = true
  86.     end
  87.     if j + 1 <= self.size and not was[i][j+1] then
  88.       local l = list[self[i][j+1]]
  89.       l[#l+1] = {i, j+1}
  90.       was[i][j+1] = true
  91.     end
  92.     idx = idx + 1
  93.   end
  94.   return list
  95. end
  96.  
  97. function Go:place(i, j, v)
  98.   if self[i][j] ~= 1 then
  99.     return false
  100.   end
  101.  
  102.   local stone = v or self.move
  103.   local enemy = 5 - stone
  104.   local modified = {}
  105.  
  106.   self[i][j] = stone
  107.   local r = self:bfs(i,j)
  108.  
  109.   --Killing anyone?
  110.   local killing = false
  111.   local enemy_near = r[enemy]
  112.   local was = init_was(self.size)
  113.   for _i = 1, #enemy_near do
  114.     local _x,_y = enemy_near[_i][1], enemy_near[_i][2]
  115.     if not was[_x][_y] then
  116.       local r1 = self:bfs(_x,_y)
  117.       if #r1[1] == 0 then
  118.         killing = true
  119.         local l = r1[enemy]
  120.         for _j = 1, #l do
  121.           self[l[_j][1]][l[_j][2]] = 1
  122.           modified[#modified+1] = {l[_j][1],l[_j][2]}
  123.         end
  124.       end
  125.     end
  126.   end
  127.  
  128.   --Suicide?
  129.   if #r[1] == 0 and not killing then
  130.     self[i][j] = 1
  131.     return false
  132.   end
  133.   modified[#modified+1] = {i,j}
  134.  
  135.   self.move = 5 - self.move
  136.   return modified
  137. end
  138.  
  139. function space(i,j,size)
  140.   if i == 1 then
  141.     if j == 1 then
  142.       return "┌"
  143.     elseif j == size then
  144.       return "┐"
  145.     else
  146.       return "┬"
  147.     end
  148.   elseif i == size then
  149.     if j == 1 then
  150.       return "└"
  151.     elseif j == size then
  152.       return "┘"
  153.     else
  154.       return "┴"
  155.     end
  156.   else
  157.     if j == 1 then
  158.       return "├"
  159.     elseif j == size then
  160.       return "┤"
  161.     else
  162.       return "┼"
  163.     end
  164.   end
  165. end
  166.  
  167. function Go:show(SX, SY)
  168.   if not SX or not SY then
  169.     SX = self.SX
  170.     SY = self.SY
  171.   else
  172.     self.SX = SX
  173.     self.SY = SY
  174.   end
  175.  
  176.   local ry = self.ratio[1]
  177.   local rx = self.ratio[2]
  178.   local ysize = ry*self.size - ry
  179.   local xsize = rx*self.size - rx
  180.   for i = 0, ysize do
  181.     local s = ""
  182.     term.setCursor(SX, SY + i)
  183.     for j = 0, xsize do
  184.       ymod = i % ry
  185.       xmod = j % rx
  186.  
  187.       if ymod == 0 then
  188.         if xmod == 0 then
  189.           stone = self[i/ry + 1][j/rx + 1]
  190.           if stone > 1 then
  191.             term.write(stone_chars[stone-1])
  192.           elseif i == 0 and j == 0 then
  193.             term.write('┌')
  194.           elseif i == 0 and j == xsize then
  195.             term.write('┐')
  196.           elseif i == ysize and j == 0 then
  197.             term.write('└')
  198.           elseif i == ysize and j == xsize then
  199.             term.write('┘')
  200.           elseif i == 0 then
  201.             term.write('┬')
  202.           elseif j == 0 then
  203.             term.write('├')
  204.           elseif i == ysize then
  205.             term.write('┴')
  206.           elseif j == xsize then
  207.             term.write('┤')
  208.           else
  209.             term.write('┼')
  210.           end
  211.         else
  212.           term.write('─')
  213.         end
  214.       elseif xmod == 0 then
  215.         term.write('│')
  216.       else
  217.         term.write(' ')
  218.       end
  219.     end
  220.   end
  221. end
  222.  
  223. function Go:touched(x, y)
  224.   x = x - self.SX
  225.   y = y - self.SY
  226.   if y % self.ratio[1] == 0 and x % self.ratio[2] == 0 then
  227.     _y = y/self.ratio[1] + 1
  228.     _x = x/self.ratio[2] + 1
  229.     if _y > 0 and _y <= self.size and _x > 0 and _x <= self.size then
  230.       local r = self:place(_y, _x)
  231.       for k = 1, #r do
  232.         term.setCursor(self.SX + self.ratio[2]*(r[k][2] - 1), self.SY + self.ratio[1]*(r[k][1] - 1))
  233.         local stone = self[r[k][1]][r[k][2]]
  234.         if stone == 1 then
  235.           term.write(space(r[k][1], r[k][2], self.size))
  236.         else
  237.           term.write(stone_chars[stone-1])
  238.         end
  239.       end
  240.     end
  241.   end  
  242. end
  243.  
  244. if false then
  245.   local x = Go:new()
  246.   x:show()
  247.   local z = x:bfs(1,1)[1]
  248.   print(#z)
  249.   for i = 1, #z do
  250.     print(z[i][1] .. ',' .. z[i][2])
  251.   end
  252. end
  253.  
  254. return Go
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement