From 6a4acfa5199456e77fbae8d14ef7d2b43919b6b1 Mon Sep 17 00:00:00 2001 From: capitalthree Date: Mon, 20 Nov 2023 08:04:42 -0600 Subject: [PATCH] neighbor search respects both physical walls (solid blocks) and goban-indicated walls --- rules.lua | 95 +++++++++++++++++++++++++++++++++++++++++++----------- stones.lua | 2 +- 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/rules.lua b/rules.lua index 30a517d..c3cf046 100644 --- a/rules.lua +++ b/rules.lua @@ -11,18 +11,90 @@ local modname = minetest.get_current_modname() local cache = {} -local relative_neighbors = { - vector.new(1, 0, 0), - vector.new(0, 0, 1), +local directions = { [0] = + vector.new(0, 0, -1), vector.new(-1, 0, 0), - vector.new(0, 0, -1) + vector.new(0, 0, 1), + vector.new(1, 0, 0), } +local down = vector.new(0, -1, 0) + local solid_drawtypes = { normal = true, glasslike_framed = true, } +local S = ("S"):byte(1) +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) + + -- print_r(neighbor_dirs(pos)) + + for i,v in pairs(neighbor_dirs(pos)) do + local node = check_position(pos +directions[v]) + if node:byte(1) == S then + + end + + --neighbors[i] = pos + v + 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 + end + + return neighbors +end + +-- check for walls, physical or implied +function edge_check(pos, dir, terminate) + local under = check_position(pos + down) + + if under:byte(1) == W and under:len() == 3 then + local corner = (under:byte(2) == C) + local edge_dir = tonumber(under:sub(3, 3)) + + if (dir == edge_dir) or (corner and (dir == (edge_dir+1)%4)) then + return true + end + end + + if not terminate then + if edge_check(pos+directions[dir], (dir+2)%4, true) then + return true + end + end + + return false +end + + --[[ E: empty Stype: a go stone of some type @@ -61,26 +133,13 @@ function _check_position_uncached(pos) end end - if solid_drawtypes[reg_item.drawtype] then + if solid_drawtypes[reg_item.drawtype] and not reg_item.groups.falling_node then return "W" else return "E" end end -function check_captures(pos) - minetest.chat_send_all(tostring(pos)) - nodecore.node_sound(pos, "dug") - - check_position(pos + vector.new(0, -1, 0)) - - local neighbors = {} - - for i,v in ipairs(relative_neighbors) do - neighbors[i] = pos + v - end - -end function surrounded_group(pos) local group = {} diff --git a/stones.lua b/stones.lua index 0a19ab5..9b61830 100644 --- a/stones.lua +++ b/stones.lua @@ -68,7 +68,7 @@ local function reg(name, basename, basedef) sounds = basedef.sounds, - on_construct = check_captures + on_construct = handle_placement }) nodecore.register_craft({