游戏建筑可用性标识算法设计

问题描述

建筑(AABB相同)之间可以相交,建筑与城堡(AABB包围盒大于建筑)之间可以相交(包含建筑在城堡中的情况),建筑(AABB相同)之间可以相交,建筑与城堡(AABB包围盒大于建筑)之间可以相交(建筑在城堡中),如果建筑A满足一下情况视为建筑可用:
1.建筑A直接与城堡B相交
2.建筑A1直接与建筑A2相交,A2与A3相交... 建筑An与城堡

算法设计

把建筑和城堡抽象成有向有环图中的一个个节点Node,如果节点N1与邻近建筑(或城堡)N2相交,则加上N1->N2和N2<-N1两条边。如果某个建筑节点到任意一个城堡节点的连通路径都不存在,
我们称之为孤悬节点,标识0;否则可用标识1.

erlang 的digraph 模块满足本算法中对于图的需求。另外我们需要借助四叉树(或者九宫格)用来做相交检测。主要关注节点的插入和删除造成的状态改变。

节点插入:
I 如果待插入节点没有相交节点,插入节点,设置标识插入节点标识0
II 如果待插入节点是城堡节点,有相交节点且标识都为1,插入节点和边,设置标识插入节点标识0
III 如果待插入节点是城堡节点,有相交节点且标识不都为1,插入节点和边,设置标识插入节点标识0。
    递归设置标识不为1的相交节点(城堡节点除外)标识为1.递归的截至条件遇到节点标识为1,或者城堡节点。
IV  如果与待插入节点相交的节点标识都是1,插入节点和边,设置插入节点的标识为1
V   如果与待插入节点相交的节点(不包含城堡节点)标识都是0,插入节点和边,插入节点的标识为0
VI  如果与待插入节点相交的节点标识都为0,同时插入节点又与城堡节点相交,插入节点和边,插入节点标识设为1。递归设置相交节点(城堡节点除外)的标识1,
    递归的截至条件遇到节点标识为1,或者城堡节点。
VII 如果与待插入节点的相交的节点标识不都为1,插入节点和边,设置插入节点标识1。递归设置标识不为1的相交节点(城堡节点除外)标识为1,
    递归的截至条件遇到节点标识为1,或者城堡节点。

节点删除:
I. 如果待删除节点没有相交节点,直接删除
II.如果待删除节点标识为0,删除。递归设置相交节点的标识为0,递归的截至条件遇到节点标识为0
III. 如果待删除节点标识为1且如果相交节点都不是孤悬节点,直接删除。
III. 如果待删除节点标识为1且如果相交节点有孤悬节点,直接删除。递归设置孤悬节点的标识为0,递归的截至条件遇到节点标识为0

测试用例(删除节点)

 // 1,20节点是城堡节点
 // 节点孤立意味着节点到任一城堡的没有连通路径
 D = digraph:new().
 [digraph:add_vertex(D,N) || N <- lists:seq(1, 24)]. 
 [digraph:add_edge(D, V1, V2) || {V1, V2} <-[{1,2},{2,1},{2,3},{3,2},{1,4},{4,1},{4,5},{5,4}, {5,6},{6,5},{3,6},{6,3},{3,7},{7,3},{7,8},{8,7},{8,9},{9,8},{8,10},{10,8},{9,12},{12,9},{12,13},{13,12}, {10,11},{11,10},{11,13},{13,11},{10,15},{15,10},{15,16},{16,15},{16,17},{17,16},{17,20},{20,17}, {16,18},{18,16},{18,21},{21,18},{21,23},{23,21},{13,22},{22,13},{22,24},{24,22}]].
 
 //删除节点7
 digraph:del_vertex(D,7).
 //判断节点3和8是否孤悬节点
 lists:all(fun(E)-> digraph:get_short_path(D, 3, E)=:= false end, [1,20]).
 lists:all(fun(E)-> digraph:get_short_path(D, 8, E)=:= false end, [1,20]).

3和8都不是孤悬节点,不需要继续处理
 
 //删除节点13
 digraph:del_vertex(D,13).
 
 //判断节点11、12、22是否孤悬节点
 lists:all(fun(E)-> digraph:get_short_path(D, 11, E)=:= false end, [1,20]).
 lists:all(fun(E)-> digraph:get_short_path(D, 12, E)=:= false end, [1,20]).
 lists:all(fun(E)-> digraph:get_short_path(D, 22, E)=:= false end, [1,20]).
 //节点22孤立,递归获取相连的节点,并设置状态为0.递归的截至条件遇到节点标识为0
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值