仿真足球队的整体的策略简单实现
在上一篇文章中,我们已经基于CSharp球队模板实现了一个最快截球。 在这篇文章中,我们将以这个球队代码为基础,在他上面添加一些简单的策略,让其成为一个更加完整的示例。
我们首先需要实现一个具有一定通用性的踢球函数,通过这个踢球函数,我们可以组合出球队的带球,传球,以及射门策略。在这里,我定义了这样一个踢球函数:将足球在指定的周期内踢到指定的位置。
将足球在指定的周期内踢到指定的位置”函数的原理:
- 求出足球应该具有什么样的速度才能在指定的周期内运动到指定的位置
- 求出Kick命令的2个参数值,能让球具有上一步求出的速度
- 求出Kick命令的2个参数后,咱们判断一下是否符合咱们平台的限制:
- 如果不行,说明在这个足球在指定的周期X内是无法运动到指定的位置的。让X+ 1 重复步骤1,如果X > 100,直接返回无法成功。
- 如果行,说明已经找到了一个Kick的命令,满足在X周期内将球踢向指定的位置。
代码中的实际实现在DemoTeamCSharp.Agent.Kick2Point中。
借助这样的踢球函数,我将向大家介绍2个简单的策略:
传球策略:
- 如果自己是守门员(1号),从2号到5号球员中随机选出一个球员,然后执行将球提到选中的球员所在的位置的命令。
- 如果自己不是守门员,这从2号到5号球员中随机选出一个球员(不包括自己),然后执行将球提到选中的球员所在的位置的命令。
射门策略:
对上图中的标记出的红点分别测试,如果球员可以在12个周期内将球踢向那一点,那么那一点就是我们可以射门成功的点。
代码实现:
//罗列出可以进球的出射门点
for (int i = 1; i < FieldSettings.Instance.FieldDoorY2 - FieldSettings.Instance.FieldDoorY1; i++)
{
Vector2f shootPoint = new Vector2f(FieldSettings.Instance.FieldLength, i + FieldSettings.Instance.FieldDoorY1);
//判断这个射门点是否可以进球
Kick2PointResult res = agent.Kick2Point(wm.Ball, shootPoint, 1);
if (res.Success && res.NeedCycle < 12)
{
//fine the shoot point.
return shootPoint;
}}
当然,光有传球和射门还不行,我们的球员还需要跑位,不然永久都是傻站在一个地方不会动;(
下面,我接着向大家介绍2种简单的跑位:
进攻跑位:
我们采用定点的跑位方法:
当守门员拿球的时候,其余四名球员的跑位位置是固定的,他们将分别跑向这些事前指定好的位置:
不是守门员拿球的时候,,拿球队员决定是传球还是射门,非拿球队员将跑向事前指定好的位置:
防守跑位:
防守跑位的实现原理是让2号到5号球员分别跑向对方的对应号码球队的位置去。如我方2号防守对方2号,我方3号防守对方3号,依此类推。
最后,我们综合上面给出的4个策略,实现了一个球队决策总体流程:
InterceptStruct interceptStruct = Predictor.PredictFastestInterceptBall(_wm);
if (interceptStruct.Own)//我方处于进攻状态
{
if (Predictor.PredictAgentCanKickBall(_wm.OwnAgents[interceptStruct.Num], _wm.Ball.Pos))//控球
{
Vector2f shootPoint = _coach.GetShootPoint(_wm, interceptStruct.Num);
if (shootPoint != Vector2f.NotExist)//射门
{
_commands[interceptStruct.Num] = _wm.OwnAgents[interceptStruct.Num].Kick2Point(_wm.Ball, shootPoint, 1).KickCommand;
}
else//传球
{
Vector2f passPoint = _coach.GetPassPoint(_wm, interceptStruct.Num);
_commands[interceptStruct.Num] = _wm.OwnAgents[interceptStruct.Num].Kick2Point(_wm.Ball, passPoint, 3).KickCommand;
}
}
else//去拿球
{
_commands[interceptStruct.Num] = _wm.OwnAgents[interceptStruct.Num].Dash2Point(interceptStruct.BallPos, true);
}
//非控球队员进行进攻跑位
for (int num = 1; num < _wm.OwnAgents.Length; num++)
{
if (num != interceptStruct.Num)
{
_commands[num] = _wm.OwnAgents[num].Dash2Point(_coach.GetAttackPos(_wm, num), false);
}
}
}
else//我方处于防守状态
{
for (int num = 1; num < _wm.OwnAgents.Length; num++)
{
_commands[num] = _wm.OwnAgents[num].Dash2Point(_coach.GetDefencePos(_wm, num), false);
}
}
大家可以通过下载CSharp范例球队的代码来查看具体的实现效果和代码。
接下来,我将发布一个更新的博客园仿真足球竞赛平台,并公布平台的PhysicalModel.dll,Engine.dll和Utility.dll的源代码。