用户:
yee089查看:17 回复:9 评论:17 创建时间:2022-05-09T10:13:31
声明:
1、本教程和编创协的算法部没有半毛钱关系。
2、如果有bug,各位大佬在评论区使劲喷,我只是一个萌新
3、这段代码是第一版,所以更像‘面向过程’编程。后面我会封装的。
4、父节点是非常正常的术语,你
————————————————————————————————————————————————(分鸽线)
玩家的联盟实际上就是一个非常容易想到,非常‘裸’(也就是模板题)的并查集,
并查集,这个名字非常高级()()但是其实基础版的非常好实现。我们来模拟亿下:
首先有n个人:a_1,a_2,a_3,a_4,a_5,a_6,……,a_n.
我们要实现两个功能:合并a_i和a_j(merge),
检查a_i和a_j是否在同一组织里(check)
首先我们建立一个父节点的数组f,初始化为:对于任意0~n间的i,a_i=i(好像这么说(?))
合并a,b,我们先找到a的祖先c,b的祖先d,让d指向c。怎么找到祖先呢?我们看这个初始化,根节点的父节点指向自己,那么我们可以这么写find:
function find(z){
let x = z;
while(x != a[x]){
a[x] = a[a[x]];//经典的路径压缩优化,非常棒
x = a[x];
}
return x;
}
(a就是f,不想改了)
检查a,b是否在同一集合呢?只需要检查a的祖先和b的祖先是不是一个人就可以了。上代码:
function check(az,b){
let ax = find(az),
bx = find(b);
return ax == bx;
}
好的,现在你应该会写并查集了吧
()()
————————————————————————————————————————————————(分鸽线)
接下来我们要做一个玩家进入后的联盟(左键攻击,右键询问是否联盟,联盟后不能互相攻击)。
这一段有手就行
,我们直接上代码:
let player_list = new Map();//映射表方便。
let num_to_pla = [];
player_list.clear();
let a = [0];
world.onPlayerJoin(async({entity})=>{
entity.enableDamage = true
if(player_list.get(entity.player.name) == undefined){
player_list.set(entity.player.name,num_to_pla.length);
num_to_pla.push(entity.player.name)
a.push(a.length);//之所以这么写,主要是为了节省内存,还省的再打初始化)
}
entity.onClick(async({clicker,button})=>{
if(button == Box3ButtonType.ACTION1 && !check(entity.player,clicker.player)){//虽然名义上是一个O(n)的check,但是经过足够多的路径压缩后整课树会成为‘菊花树’(只有两层的树),所以其实基本是O(1)check
const ans = await entity.player.dialog({
type:Box3DialogType.SELECT,
title:clicker.player.name + '对你发送了联盟请求',
options:['同意','不同意']
})
if(!ans ||ans == null)return;
if(ans.index == 0){
console.log(clicker.player.name+' 与 '+entity.player.name+'联合')
//merge
let xf = find(player_list.get(entity.player.name)),
yf = find(player_list.get(clicker.player.name));
a[yf] = a[xf];
}
}
if(button == Box3ButtonType.ACTION0 && !check(entity.player,clicker.player)){
entity.hurt(1)
}
})
})
评论区发全部代码~。
你学废了吗?
yee089let player_list = new Map();
let num_to_pla = [];
player_list.clear();
let a = [0];
c喵ole.clear()
c喵ole.clear()
function find(z){
let x = z;
while(x != a[x]){
a[x] = a[a[x]];
x = a[x];
}
return x;
}
function check(az,b){
let ax = find(player_list.get(az.name)),
bx = find(player_list.get(b.name));
return ax == bx;
}
world.onPlayerJoin(async({entity})=>{
entity.enableDamage = true
if(player_list.get(entity.player.name) == undefined){
player_list.set(entity.player.name,num_to_pla.length);
num_to_pla.push(entity.player.name)
a.push(a.length);
}
entity.onClick(async({clicker,button})=>{
if(button == Box3ButtonType.ACTION1 && !check(entity.player,clicker.player)){
c喵t ans = await entity.player.dialog({
type:Box3DialogType.SELECT,
title:clicker.player.name + '对你发送了联盟请求',
opti喵:['同意','不同意']
})
if(!ans ||ans == null)return;
if(ans.index == 0){
c喵ole.log(clicker.player.name+' 与 '+entity.player.name+'联合')
//merge
let xf = find(player_list.get(entity.player.name)),
yf = find(player_list.get(clicker.player.name));
a[yf] = a[xf];
}
}
if(button == Box3ButtonType.ACTION0 && !check(entity.player,clicker.player)){
entity.hurt(1)
}
})
})点赞0
评论