diff --git a/goban.lua b/goban.lua index 9be518d..61c94bf 100644 --- a/goban.lua +++ b/goban.lua @@ -7,9 +7,3 @@ nodecore.register_concrete_pattern({description = "Crossy"}) nodecore.register_concrete_pattern({description = "Starcrossy"}) nodecore.register_concrete_pattern({description = "Edgy", paramtype2 = "4dir"}) nodecore.register_concrete_pattern({description = "Corny", paramtype2 = "4dir"}) - - ---nodecore.register_concrete_pattern({description = "Crossy", groups = {goban = 1}}) ---nodecore.register_concrete_pattern({description = "Starcrossy", groups = {goban = 1}}) ---nodecore.register_concrete_pattern({description = "Edgy", paramtype2 = "4dir", groups = {goban = 1}}) ---nodecore.register_concrete_pattern({description = "Corny", paramtype2 = "4dir", groups = {goban = 1}}) diff --git a/init.lua b/init.lua index 4806ff7..9a72086 100755 --- a/init.lua +++ b/init.lua @@ -3,6 +3,7 @@ local include, nodecore = include, nodecore -- LUALOCALS > --------------------------------------------------------- +lc_liberties = {} include("goban") include("rules") diff --git a/rules.lua b/rules.lua index 995d9b3..0a3891e 100644 --- a/rules.lua +++ b/rules.lua @@ -30,81 +30,54 @@ local W = ("W"):byte(1) local E = ("E"):byte(1) local C = ("C"):byte(1) -function handle_placement(pos) - cache = {} - --minetest.chat_send_all(tostring(pos)) - --nodecore.node_sound(pos, "dug") - - local our_stone = check_position(pos) - if not (our_stone:byte(1) == S) then - return - end - our_stone = our_stone:sub(2, -1) - local captureses = {} - local captured = false - for i,v in pairs(neighbor_dirs(pos)) do - local new_pos = pos + directions[v] +--[[ +E: empty +Stype: a go stone of some type +W: full block wall +WE0-WE3: edge concrete +WC0-WC3: corner concrete +--]] +local function _check_position_uncached(pos) + local node = minetest.get_node(pos) + local reg_item = minetest.registered_items[node.name] - local hash = minetest.hash_node_position(new_pos) + if not reg_item then + return "W" + end - local checked = false - for i2,v2 in pairs(captureses) do - if v2.stones[hash] then - checked = true - end - end + if reg_item.groups and reg_item.groups.go_stone then + return "S" .. reg_item.go_team + end - if not checked then - local node = check_position(new_pos) - if (node:byte(1) == S) and (not (node:sub(2, -1) == our_stone)) then - local captures = check_captures(new_pos) - captured = captured or captures.capture - captureses[#captureses+1] = captures - end + if reg_item.pattern_def then + if reg_item.pattern_def.name == "edgy" then + return "WE" .. node.param2 + elseif reg_item.pattern_def.name == "corny" then + return "WC" .. node.param2 end end - if captured then - for i,v in pairs(captureses) do - if v.capture then - local proximal = {} - - for i2, v2 in pairs(v.stones) do - nodecore.set_loud(v2, {name = "nc_fire:fire"}) - end - - -- todo: spawn itemstack of captured stones somehow - end - end + if solid_drawtypes[reg_item.drawtype] and not reg_item.groups.falling_node then + return "W" else - local captures = check_captures(pos) - if captures.capture then - minetest.chat_send_all("You gotcher self a suicide move right there! size: "..#(captures.stones)) - -- todo: replace with itemstack of one stone - end + return "E" end end ---[[ -give valid neighbor directions from a position, excluding solid blocks -and also respecting borders indicated by goban concrete ---]] -function neighbor_dirs(pos) - local neighbors = {} - for i,v in pairs(directions) do - if not edge_check(pos, i) then - if not (check_position(pos + directions[i]):byte(1) == W) then - neighbors[#neighbors+1] = i - end - end +local function check_position(pos) + local hash = minetest.hash_node_position(pos) + if cache[hash] then + return cache[hash] end - return neighbors + local ret = _check_position_uncached(pos) + cache[hash] = ret + return ret end -- check for walls, physical or implied -function edge_check(pos, dir, terminate) +local function edge_check(pos, dir, terminate) local under = check_position(pos + down) if under:byte(1) == W and under:len() == 3 then @@ -125,50 +98,21 @@ function edge_check(pos, dir, terminate) return false end - --[[ -E: empty -Stype: a go stone of some type -W: full block wall -WE0-WE3: edge concrete -WC0-WC3: corner concrete +give valid neighbor directions from a position, excluding solid blocks +and also respecting borders indicated by goban concrete --]] -function check_position(pos) - local hash = minetest.hash_node_position(pos) - if cache[hash] then - return cache[hash] - end - - local ret = _check_position_uncached(pos) - cache[hash] = ret - return ret -end - -function _check_position_uncached(pos) - local node = minetest.get_node(pos) - local reg_item = minetest.registered_items[node.name] - - if not reg_item then - return "W" - end - - if reg_item.groups and reg_item.groups.go_stone then - return "S" .. reg_item.go_team - end - - if reg_item.pattern_def then - if reg_item.pattern_def.name == "edgy" then - return "WE" .. node.param2 - elseif reg_item.pattern_def.name == "corny" then - return "WC" .. node.param2 +local function neighbor_dirs(pos) + local neighbors = {} + for i,v in pairs(directions) do + if not edge_check(pos, i) then + if not (check_position(pos + directions[i]):byte(1) == W) then + neighbors[#neighbors+1] = i + end end end - if solid_drawtypes[reg_item.drawtype] and not reg_item.groups.falling_node then - return "W" - else - return "E" - end + return neighbors end --[[ @@ -176,7 +120,7 @@ Scans for a connected group, until enumerating the whole group, or finding a liberty. Returns list of captured nodes, or empty list if no captures. --]] -function check_captures(pos) +local function check_captures(pos) local group = {pos} local stones = {[minetest.hash_node_position(pos)] = pos} local checked = {} @@ -210,29 +154,60 @@ function check_captures(pos) return {capture = true, stones = stones} end +function lc_liberties.handle_placement(pos) + cache = {} + minetest.chat_send_all(tostring(pos)) + --nodecore.node_sound(pos, "dug") + local our_stone = check_position(pos) + if not (our_stone:byte(1) == S) then + return + end + our_stone = our_stone:sub(2, -1) + + local captureses = {} + local captured = false + for i,v in pairs(neighbor_dirs(pos)) do + local new_pos = pos + directions[v] + + local hash = minetest.hash_node_position(new_pos) + + local checked = false + for i2,v2 in pairs(captureses) do + if v2.stones[hash] then + checked = true + end + end + + if not checked then + local node = check_position(new_pos) + if (node:byte(1) == S) and (not (node:sub(2, -1) == our_stone)) then + local captures = check_captures(new_pos) + captured = captured or captures.capture + captureses[#captureses+1] = captures + end + end + end -function print_r ( t ) - local print_r_cache={} - local function sub_print_r(t,indent) - if (print_r_cache[tostring(t)]) then - print(indent.."*"..tostring(t)) - else - print_r_cache[tostring(t)]=true - if (type(t)=="table") then - for pos,val in pairs(t) do - if (type(val)=="table") then - print(indent.."["..pos.."] => "..tostring(t).." {") - sub_print_r(val,indent..string.rep(" ",string.len(pos)+8)) - print(indent..string.rep(" ",string.len(pos)+6).."}") - else - print(indent.."["..pos.."] => "..tostring(val)) - end + if captured then + for i,v in pairs(captureses) do + if v.capture then + local proximal = {} + + for i2, v2 in pairs(v.stones) do + nodecore.set_loud(v2, {name = "nc_fire:fire"}) end - else - print(indent..tostring(t)) + + -- todo: spawn itemstack of captured stones somehow end end + else + local captures = check_captures(pos) + if captures.capture then + minetest.chat_send_all("You gotcher self a suicide move right there! size: "..#(captures.stones)) + -- todo: replace with itemstack of one stone + end end - sub_print_r(t," ") -end \ No newline at end of file +end + + diff --git a/stones.lua b/stones.lua index 9b61830..1398a25 100644 --- a/stones.lua +++ b/stones.lua @@ -68,7 +68,7 @@ local function reg(name, basename, basedef) sounds = basedef.sounds, - on_construct = handle_placement + on_construct = lc_liberties.handle_placement }) nodecore.register_craft({