比赛结束!阅读有关Blob的评论以查看其得分。
此KoTH受到Primer自然选择模拟的大致启发。您的漫游器是一个Blob。为了生存,您必须吃掉颗粒以重新获得用于移动的能量。有了额外的能量,斑点可以一分为二。
能量与运动
您的Blob每回合都会以100的能量开始,并且对其可以收集的能量数量没有限制。每个回合都是轮流进行,每个Blob可以选择在任意给定的回合中向北,向东,向南或向西移动,或保持静止。移动消耗1能量,而静止不动使用0.25能量。地图的边长是ceil(0.25 * blobCount) * 2 - 1
单位,最少9个单位。所有Blob都始于地图的边缘,每个角处都放置一个Blob,随后的每个Blob都应与其他Blob放置2个单位。每30圈,一阵子弹便被放置在地图周围的任意位置,距离任意边缘至少1个单位。每次出现一波颗粒波时,下一波中的颗粒数量(最初为斑点数的两倍或图的宽度(以较大者为准))减少1,迫使斑点数随时间减少。每个药丸可恢复5至15的能量。当Blob的能量小于或等于0时,它就会死掉。
吃
如果两个或多个Blob试图占据同一位置,则能量最大的一个将吞噬其他能量,并吸收它们的能量。如果两者具有相等的能量,则两者都会消失。
检测与信息
斑点可以在4个单位的距离内看到任何颗粒或其他斑点。调用其函数时,将为blob提供:
- 地图的边长
- 斑点在地图上的位置
- 所有小球在其搜索半径内的位置及其值
- 所有Blob在其搜索半径内的位置,以及它们的能量和UID
- 执行功能的Blob的能量,UID和位置
- Blob唯一的存储对象
- 通过拆分由与该blob相关的所有blob共享的存储对象
分裂
如果斑点的能量超过50,则可以选择拆分。拆分会消耗50能量,并且所有剩余能量将在两个Blob之间平均分配。所有blob都是原始副本或拆分副本,每个副本都可追溯到原始副本。所有这些都是“亲戚”。所有亲戚都有一个公共存储对象。亲戚仍然可以互相吃饭,可以分裂,使用自己的存储对象或收集能量而不会影响他人。
能量转移
如果两个Blob彼此相邻(移动后),则其中一个机器人可以将能量传递给另一个机器人。这是通过返回完成SendNorth(amt)
,SendEast(amt)
,SendSouth(amt)
,或SendWest(amt)
,其中amt
是代表所述量的号码发送。这可以是发件人可以负担的任何金额,包括其所有能量。建议告知接收能量的斑点在公共存储中保持静止,以使其在转移能量时不会移开(尽管在这种情况下不会从发送者的总量中扣除能量)。
函数,存储和UID
为了允许更复杂的学习行为,所有Blob都将被赋予一个整数UID(唯一标识符)。这些UID将在每个地图上随机生成,从而防止基于单个目标的策略。调用Blob的函数时,将为其传递四个参数:
- 地图的边长(整数)
- 具有两个数组的对象:
pellets
和blobs
。两个数组都包含对象,两个对象都具有一个pos
属性,该属性包含格式为的颗粒或团块位置[x,y]
。丸粒将具有energy
属性,而斑点将具有uid
属性和energy
属性 - 含有团块的各种属性的对象它被传递给:
energy
,uid
,和pos
。该pos
阵列被格式化为[x,y]
- 包含Blob的两个存储对象的对象。一个
self
属性包含一个可以修改的单独存储对象,但是blob认为合适(通过操纵所传递对象的communal
属性),以及一个可以被任何亲戚修改的属性。
斑点不立即移动以防止较早/较晚的转弯具有优势。所有运动均按组进行处理(所有碰撞/进食,然后是所有药丸,然后分裂,等等)。如果某个药丸落在药丸或较小药丸上,并且在此过程中使用了其最后的能量,药丸仍将消耗药丸/能量,而不管其总能量是否大于0。
为了使相对Blob能够相互识别,必须为每个Blob使用公用存储,以在阵列中或通过其他系统记录其UID。
返回值
为了移动或拆分,使用了函数的返回值。首先,基本方向在坐标方面的含义:
- 北= -Y
- 东= + X
- 南= + Y
- 西= -X
请注意,它[0,0]
是左上角,并且Y随您的下降而增加。函数的返回值应遵循以下规则:
- 不执行任何操作:不返回任何内容,0,null,undefined,false或任何其他等于false的值
- 移动:返回四个全局变量之一:北,东,南或西,它们等于“北”,“东”,“南”或“西”(也可用作返回值)
- 要拆分:返回全局变量SplitNorth,SplitEast,SplitSouth或SplitWest,其方向指示将新Blob放置在何处
如果返回拆分命令,并且所需能量大于或等于斑点的能量,则不会发生任何事情。Blob将无法离开地图。
预定义的库函数
默认情况下,有一些基本功能可以节省一些时间:
taxiDist(pt1,pt2)
返回两点之间的出租车距离(X距离加Y距离)。
taxiDist([0, 0], [2, 2]) //4
taxiDist([3, 4], [1, 5]) //3
taxiDist([1.25, 1.3], [1.3, 1.4]) //0.15
taxiDist([0, 0], [5, 2.5], 2.5) //3
taxiDist([0, 0], [2, 4], 2.5) //2.4
hypotDist(pt1,pt2)
根据勾股定理返回两点之间的距离
hypotDist([0, 0], [5, 12]) //13
hypotDist([4, 6], [8, 9]) //5
hypotDist([0, 1], [2, 1]) //2
hypotDist([1, 1], [2, 2]) //sqrt(2)
modDir(dir,amt)
采取输入方向,顺时针旋转90度amt
,然后返回新值。
modDist(North, 1) //East
modDist(East, 2) //West
modDist(West, 3) //South
modDist(South, 4) //South
示例Blob
直到找到附近的沉淀,该团块才会移动。然后,它将朝着它认为最有可能奖励它的方向移动。如果其能量超过150,它将分裂。
function(map, near, me, storage) {
if (me.energy > 150)
return SplitNorth;
if (!near.pellets.length)
return null;
var dirs = [0, 0, 0, 0];
for (let p, i = 0; i < near.pellets.length; i++) {
p = near.pellets[i];
dirs[0] += me.pos[1] - p.pos[1];
dirs[1] += p.pos[0] - me.pos[0];
dirs[2] += p.pos[1] - me.pos[1];
dirs[3] += me.pos[0] - p.pos[0];
}
return [North, East, South, West][dirs.indexOf(Math.max(...dirs))];
}
规则
- 禁止使用标准漏洞。另外,没有非标准漏洞。
- 任何Blob均不得尝试修改或读取未通过其参数传递给它的任何数据
- 任何Blob都不能尝试修改返回值变量来破坏其他Blob
- 持续一轮直到剩下的唯一的斑点是亲戚
- 没有Blob可以通过将函数注入参数中来修改数据,这些函数使用
this
关键字来修改值 - 所有提交都必须使用Java脚本或与Java脚本没有太大区别的语言(例如Python)。所有答案都将转换为Javascript以进行比赛。
- 胜利者是Blob,它在所有回合中总计收集了最多的能量(来自颗粒或消耗的不是亲戚的较小Blob)
控制器: https : //gist.github.com/RedwolfPrograms/1facc0afe24c5dfd3ada8b8a2c493242
聊天室: https ://chat.stackexchange.com/rooms/93370/hungry-blobs-koth