Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local term = require("term")
- local unicode = require("unicode")
- local black_char = unicode.char(75435)
- local white_char = unicode.char(75434)
- local stone_chars = {black_char, white_char}
- local Go = {}
- Go._index = Go
- function Go:new(size, SX, SY, ratio)
- if not size then size = 9 end
- local o = {}
- -- {1,2,1,1},
- -- {1,2,1,1},
- -- {1,2,1,1},
- -- {1,1,2,1}
- -- }
- o.size = size
- o.move = 2
- o.SX = SX or 10
- o.SY = SY or 7
- o.ratio = ratio or {2,3}
- if true then
- for i = 1, size do
- o[i] = {}
- for j = 1, size do
- o[i][j] = 1
- end
- end
- end
- setmetatable(o, self)
- self.__index = self
- return o
- end
- function init_was(size, x, y)
- local was = {}
- for i = 1, size do
- was[i] = {}
- for j = 1, size do
- was[i][j] = false
- end
- end
- if x and y then
- was[x][y] = true
- end
- return was
- end
- ------------------------------------- BFS Function ---------------------------------------
- -- Explores a group specified by one of it's points (x,y)
- -- Return array of 3 elements:
- -- 1: Empty places group (if x,y on field is empty) OR list of empty places near the group
- -- 2: Black stones group (if x,y on field is black) OR list of black stones near the group
- -- 3: White stones group (if x,y on field is white) OR list of white stones near the group
- function Go:bfs(i, j, was)
- local list = {{},{},{}}
- local idx = 1
- local stone = self[i][j]
- list[stone][1] = {i,j}
- if not was then
- was = init_was(self.size)
- end
- was[i][j] = true
- while idx <= #list[stone] do
- local i = list[stone][idx][1]
- local j = list[stone][idx][2]
- if i - 1 > 0 and not was[i-1][j] then
- local l = list[self[i-1][j]]
- l[#l+1] = {i-1, j}
- was[i-1][j] = true
- end
- if j - 1 > 0 and not was[i][j-1] then
- local l = list[self[i][j-1]]
- l[#l+1] = {i, j-1}
- was[i][j-1] = true
- end
- if i + 1 <= self.size and not was[i+1][j] then
- local l = list[self[i+1][j]]
- l[#l+1] = {i+1, j}
- was[i+1][j] = true
- end
- if j + 1 <= self.size and not was[i][j+1] then
- local l = list[self[i][j+1]]
- l[#l+1] = {i, j+1}
- was[i][j+1] = true
- end
- idx = idx + 1
- end
- return list
- end
- function Go:place(i, j, v)
- if self[i][j] ~= 1 then
- return false
- end
- local stone = v or self.move
- local enemy = 5 - stone
- local modified = {}
- self[i][j] = stone
- local r = self:bfs(i,j)
- --Killing anyone?
- local killing = false
- local enemy_near = r[enemy]
- local was = init_was(self.size)
- for _i = 1, #enemy_near do
- local _x,_y = enemy_near[_i][1], enemy_near[_i][2]
- if not was[_x][_y] then
- local r1 = self:bfs(_x,_y)
- if #r1[1] == 0 then
- killing = true
- local l = r1[enemy]
- for _j = 1, #l do
- self[l[_j][1]][l[_j][2]] = 1
- modified[#modified+1] = {l[_j][1],l[_j][2]}
- end
- end
- end
- end
- --Suicide?
- if #r[1] == 0 and not killing then
- self[i][j] = 1
- return false
- end
- modified[#modified+1] = {i,j}
- self.move = 5 - self.move
- return modified
- end
- function space(i,j,size)
- if i == 1 then
- if j == 1 then
- return "┌"
- elseif j == size then
- return "┐"
- else
- return "┬"
- end
- elseif i == size then
- if j == 1 then
- return "└"
- elseif j == size then
- return "┘"
- else
- return "┴"
- end
- else
- if j == 1 then
- return "├"
- elseif j == size then
- return "┤"
- else
- return "┼"
- end
- end
- end
- function Go:show(SX, SY)
- if not SX or not SY then
- SX = self.SX
- SY = self.SY
- else
- self.SX = SX
- self.SY = SY
- end
- local ry = self.ratio[1]
- local rx = self.ratio[2]
- local ysize = ry*self.size - ry
- local xsize = rx*self.size - rx
- for i = 0, ysize do
- local s = ""
- term.setCursor(SX, SY + i)
- for j = 0, xsize do
- ymod = i % ry
- xmod = j % rx
- if ymod == 0 then
- if xmod == 0 then
- stone = self[i/ry + 1][j/rx + 1]
- if stone > 1 then
- term.write(stone_chars[stone-1])
- elseif i == 0 and j == 0 then
- term.write('┌')
- elseif i == 0 and j == xsize then
- term.write('┐')
- elseif i == ysize and j == 0 then
- term.write('└')
- elseif i == ysize and j == xsize then
- term.write('┘')
- elseif i == 0 then
- term.write('┬')
- elseif j == 0 then
- term.write('├')
- elseif i == ysize then
- term.write('┴')
- elseif j == xsize then
- term.write('┤')
- else
- term.write('┼')
- end
- else
- term.write('─')
- end
- elseif xmod == 0 then
- term.write('│')
- else
- term.write(' ')
- end
- end
- end
- end
- function Go:touched(x, y)
- x = x - self.SX
- y = y - self.SY
- if y % self.ratio[1] == 0 and x % self.ratio[2] == 0 then
- _y = y/self.ratio[1] + 1
- _x = x/self.ratio[2] + 1
- if _y > 0 and _y <= self.size and _x > 0 and _x <= self.size then
- local r = self:place(_y, _x)
- for k = 1, #r do
- term.setCursor(self.SX + self.ratio[2]*(r[k][2] - 1), self.SY + self.ratio[1]*(r[k][1] - 1))
- local stone = self[r[k][1]][r[k][2]]
- if stone == 1 then
- term.write(space(r[k][1], r[k][2], self.size))
- else
- term.write(stone_chars[stone-1])
- end
- end
- end
- end
- end
- if false then
- local x = Go:new()
- x:show()
- local z = x:bfs(1,1)[1]
- print(#z)
- for i = 1, #z do
- print(z[i][1] .. ',' .. z[i][2])
- end
- end
- return Go
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement