Created
July 17, 2014 01:26
-
-
Save thuzhf/51e1cdaa0c4efb178e2e to your computer and use it in GitHub Desktop.
我的备份
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using xna = Microsoft.Xna.Framework; | |
using URWPGSim2D.Common; | |
using URWPGSim2D.StrategyLoader; | |
using URWPGSim2D.Core; | |
namespace URWPGSim2D.Strategy | |
{ | |
public class Strategy : MarshalByRefObject, IStrategy | |
{ | |
#region reserved code never be changed or removed | |
/// <summary> | |
/// override the InitializeLifetimeService to return null instead of a valid ILease implementation | |
/// to ensure this type of remote object never dies | |
/// </summary> | |
/// <returns>null</returns> | |
public override object InitializeLifetimeService() | |
{ | |
//return base.InitializeLifetimeService(); | |
return null; // makes the object live indefinitely | |
} | |
#endregion | |
/// <summary> | |
/// 决策类当前对象对应的仿真使命参与队伍的决策数组引用 第一次调用GetDecision时分配空间 | |
/// </summary> | |
private Decision[] decisions = null; | |
private int dribbleState = 1; | |
private float epsilon = 100; | |
public enum State {our_penalty_area, defense_area, center_area, attack_area, opposing_penalty_area}; | |
private State state = State.center_area; | |
/// <summary> | |
/// 获取队伍名称 在此处设置参赛队伍的名称 | |
/// </summary> | |
/// <returns>队伍名称字符串</returns> | |
public string GetTeamName() | |
{ | |
return "水球5VS5 Test Team 1"; | |
} | |
/// <summary> | |
/// 获取当前仿真使命(比赛项目)当前队伍所有仿真机器鱼的决策数据构成的数组 | |
/// </summary> | |
/// <param name="mission">服务端当前运行着的仿真使命Mission对象</param> | |
/// <param name="teamId">当前队伍在服务端运行着的仿真使命中所处的编号 | |
/// 用于作为索引访问Mission对象的TeamsRef队伍列表中代表当前队伍的元素</param> | |
/// <returns>当前队伍所有仿真机器鱼的决策数据构成的Decision数组对象</returns> | |
public Decision[] GetDecision(Mission mission, int teamId) | |
{ | |
// 决策类当前对象第一次调用GetDecision时Decision数组引用为null | |
if (decisions == null) | |
{// 根据决策类当前对象对应的仿真使命参与队伍仿真机器鱼的数量分配决策数组空间 | |
decisions = new Decision[mission.CommonPara.FishCntPerTeam]; | |
} | |
#region 决策计算过程 需要各参赛队伍实现的部分 | |
#region 策略编写帮助信息 | |
//====================我是华丽的分割线====================// | |
//======================策略编写指南======================// | |
//1.策略编写工作直接目标是给当前队伍决策数组decisions各元素填充决策值 | |
//2.决策数据类型包括两个int成员,VCode为速度档位值,TCode为转弯档位值 | |
//3.VCode取值范围0-14共15个整数值,每个整数对应一个速度值,速度值整体但非严格递增 | |
//有个别档位值对应的速度值低于比它小的档位值对应的速度值,速度值数据来源于实验 | |
//4.TCode取值范围0-14共15个整数值,每个整数对应一个角速度值 | |
//整数7对应直游,角速度值为0,整数6-0,8-14分别对应左转和右转,偏离7越远,角度速度值越大 | |
//5.任意两个速度/转弯档位之间切换,都需要若干个仿真周期,才能达到稳态速度/角速度值 | |
//目前运动学计算过程决定稳态速度/角速度值接近但小于目标档位对应的速度/角速度值 | |
//6.决策类Strategy的实例在加载完毕后一直存在于内存中,可以自定义私有成员变量保存必要信息 | |
//但需要注意的是,保存的信息在中途更换策略时将会丢失 | |
//====================我是华丽的分割线====================// | |
//=======策略中可以使用的比赛环境信息和过程信息说明=======// | |
//场地坐标系: 以毫米为单位,矩形场地中心为原点,向右为正X,向下为正Z | |
// 负X轴顺时针转回负X轴角度范围为(-PI,PI)的坐标系,也称为世界坐标系 | |
//mission.CommonPara: 当前仿真使命公共参数 | |
//mission.CommonPara.FishCntPerTeam: 每支队伍仿真机器鱼数量 | |
//mission.CommonPara.MsPerCycle: 仿真周期毫秒数 | |
//mission.CommonPara.RemainingCycles: 当前剩余仿真周期数 | |
//mission.CommonPara.TeamCount: 当前仿真使命参与队伍数量 | |
//mission.CommonPara.TotalSeconds: 当前仿真使命运行时间秒数 | |
//mission.EnvRef.Balls: | |
//当前仿真使命涉及到的仿真水球列表,列表元素的成员意义参见URWPGSim2D.Common.Ball类定义中的注释 | |
//mission.EnvRef.FieldInfo: | |
//当前仿真使命涉及到的仿真场地,各成员意义参见URWPGSim2D.Common.Field类定义中的注释 | |
//mission.EnvRef.ObstaclesRect: | |
//当前仿真使命涉及到的方形障碍物列表,列表元素的成员意义参见URWPGSim2D.Common.RectangularObstacle类定义中的注释 | |
//mission.EnvRef.ObstaclesRound: | |
//当前仿真使命涉及到的圆形障碍物列表,列表元素的成员意义参见URWPGSim2D.Common.RoundedObstacle类定义中的注释 | |
//mission.TeamsRef[teamId]: | |
//决策类当前对象对应的仿真使命参与队伍(当前队伍) | |
//mission.TeamsRef[teamId].Para: | |
//当前队伍公共参数,各成员意义参见URWPGSim2D.Common.TeamCommonPara类定义中的注释 | |
//mission.TeamsRef[teamId].Fishes: | |
//当前队伍仿真机器鱼列表,列表元素的成员意义参见URWPGSim2D.Common.RoboFish类定义中的注释 | |
//mission.TeamsRef[teamId].Fishes[i].PositionMm和PolygonVertices[0],BodyDirectionRad,VelocityMmPs, | |
// AngularVelocityRadPs,Tactic: | |
//当前队伍第i条仿真机器鱼鱼体矩形中心和鱼头顶点在场地坐标系中的位置(用到X坐标和Z坐标),鱼体方向,速度值, | |
// 角速度值,决策值 | |
//====================我是华丽的分割线====================// | |
//========================典型循环========================// | |
//for (int i = 0; i < mission.CommonPara.FishCntPerTeam; i++) | |
//{ | |
// decisions[i].VCode = 0; // 静止 | |
// decisions[i].TCode = 7; // 直游 | |
//} | |
//====================我是华丽的分割线====================// | |
#endregion | |
//请从这里开始编写代码 | |
#region 定义变量 | |
int goal = (mission.TeamsRef[teamId].Para.MyHalfCourt == HalfCourt.LEFT ? 1 : 0); | |
xna.Vector3 goalPoint; | |
if (goal == 1) | |
{ | |
goalPoint = new xna.Vector3(2250, 0, 0); | |
} | |
else | |
{ | |
goalPoint = new xna.Vector3(-2250, 0, 0); | |
} | |
List<RoboFish> fishes = mission.TeamsRef[teamId].Fishes; | |
//xna.Vector3 fishPm0 = mission.TeamsRef[teamId].Fishes[0].PositionMm; | |
//xna.Vector3 fishPm2 = mission.TeamsRef[teamId].Fishes[2].PositionMm; | |
//xna.Vector3 fishPm3 = mission.TeamsRef[teamId].Fishes[3].PositionMm; | |
xna.Vector3 ballsPm = mission.EnvRef.Balls[0].PositionMm; | |
#endregion | |
if (state == State.center_area) | |
{ | |
if (ballsPm.X < -500) | |
{ | |
state = (goal == 0 ? State.defense_area : State.attack_area); | |
} | |
else if (ballsPm.X > 500) | |
{ | |
state = (goal == 0 ? State.attack_area : State.defense_area); | |
} | |
else | |
{ | |
xna.Vector3 targetPoint = new xna.Vector3(ballsPm.X, 0, ballsPm.Z); | |
float targetDirection = StrategyHelper.Helpers.GetAngleDegree(goalPoint - ballsPm) / 180f * (float)Math.PI; | |
for (int i = 0; i < 5; ++i) | |
{ | |
if (i == 0 || i == 2 || i == 3) | |
{ | |
number_act(i, 7, fishes[i].PositionMm, ballsPm, fishes[i], goalPoint); | |
} | |
} | |
} | |
} | |
if (state == State.attack_area) | |
{ | |
if (Math.Abs(ballsPm.X) < 500) | |
{ | |
state = State.center_area; | |
} | |
else if (Math.Abs(ballsPm.X) > 1700) | |
{ | |
state = State.opposing_penalty_area; | |
} | |
else | |
{ | |
} | |
} | |
if (state == State.opposing_penalty_area) | |
{ | |
if (Math.Abs(ballsPm.X) < 1700) | |
{ | |
state = State.attack_area; | |
} | |
else | |
{ | |
} | |
} | |
if (state == State.defense_area) | |
{ | |
if (Math.Abs(ballsPm.X) > 1700) | |
{ | |
state = State.our_penalty_area; | |
} | |
else if (Math.Abs(ballsPm.X) < 500) | |
{ | |
state = State.center_area; | |
} | |
else | |
{ | |
} | |
} | |
if (state == State.our_penalty_area) | |
{ | |
if (Math.Abs(ballsPm.X) < 1700) | |
{ | |
state = State.defense_area; | |
} | |
else | |
{ | |
} | |
} | |
/* | |
int i = 3; | |
xna.Vector3 targetPoint = new xna.Vector3(ballsPm.X, 0, ballsPm.Z); | |
float targetDirection = StrategyHelper.Helpers.GetAngleDegree(goalPoint - ballsPm) / 180f * (float)Math.PI; | |
//StrategyHelper.Helpers.Dribble(ref decisions[i], mission.TeamsRef[teamId].Fishes[i], targetPoint, targetDirection, 5, 10, 150, 6, 4, 15, 100, true); | |
if (dribbleState == 0) | |
{ | |
if (dist(fishes[i].PositionMm, targetPoint) > epsilon) | |
{ | |
actFast(i, targetPoint, fishes[i].PositionMm, targetDirection); | |
} | |
else | |
{ | |
dribbleState = 1; | |
} | |
} | |
if (dribbleState == 1) | |
{ | |
number_act(i, 7, fishes[i].PositionMm, ballsPm, fishes[i], goalPoint); | |
} | |
*/ | |
//#region fish4 | |
//i = 3; | |
//targetPoint = new xna.Vector3(ballsPm.X, 0, ballsPm.Z); | |
//targetDirection = StrategyHelper.Helpers.GetAngleDegree(goalPoint - ballsPm) / 180f * (float)Math.PI; | |
//StrategyHelper.Helpers.Dribble(ref decisions[i], mission.TeamsRef[teamId].Fishes[i], targetPoint, targetDirection, 5, 10, 150, 6, 4, 15, 100, true); | |
//#endregion | |
#endregion | |
return decisions; | |
} | |
public float dist(xna.Vector3 x1, xna.Vector3 x2) | |
{ | |
return (float)Math.Sqrt(Math.Pow(x1.X, x1.Z) + Math.Pow(x2.X, x2.Z)); | |
} | |
public Decision actFast(int i, xna.Vector3 position, xna.Vector3 fishPm, double bodyDirectionRad)//找点 | |
{ | |
double x = fishPm.X; | |
double z = fishPm.Z; //鱼的刚体坐标 | |
double num11 = position.X; | |
double num12 = position.Z; | |
double num14 = Math.Atan((num12 - z) / (num11 - x));//刚体和目标点这条直线与x轴的角度正切值 | |
if ((num11 - x) < 0.0)//鱼在球的右侧 | |
{ | |
if (num14 > 0.0) | |
{ | |
num14 -= Math.PI; | |
} | |
else | |
{ | |
num14 += Math.PI; | |
} | |
} | |
double num15 = num14 - bodyDirectionRad; | |
if (num15 > Math.PI)//---------鱼实际要转过的角度取最优法 | |
{ | |
num15 -= Math.PI * 2; | |
} | |
else if (num15 < -Math.PI) | |
{ | |
num15 += Math.PI * 2; | |
} | |
double juli = Math.Sqrt(Math.Pow(x - num11, 2.0) + Math.Pow(z - num12, 2.0)); | |
if (num15 > 0) | |
{ | |
if (Math.Abs(num15) > 0.1 * Math.PI) | |
{ | |
decisions[i].TCode = 15; | |
decisions[i].VCode = 1; | |
} | |
else | |
{ | |
decisions[i].TCode = 7; | |
if (juli > 10) | |
{ | |
decisions[i].VCode = 15; | |
} | |
else | |
{ | |
decisions[i].VCode = 0; | |
} | |
} | |
} | |
if (num15 < 0) | |
{ | |
if (Math.Abs(num15) > 0.1 * Math.PI) | |
{ | |
decisions[i].TCode = 0; | |
decisions[i].VCode = 1; | |
} | |
else | |
{ | |
decisions[i].TCode = 7; | |
if (juli > 10) | |
{ | |
decisions[i].VCode = 15; | |
} | |
else | |
{ | |
decisions[i].VCode = 0; | |
} | |
} | |
} | |
return decisions[i]; | |
} | |
public Decision actSlow(int i, xna.Vector3 position, xna.Vector3 fishPm, double bodyDirectionRad)//找点 | |
{ | |
double x = fishPm.X; | |
double z = fishPm.Z; //鱼的刚体坐标 | |
double num11 = position.X; | |
double num12 = position.Z; | |
double num14 = Math.Atan((num12 - z) / (num11 - x));//刚体和目标点这条直线与x轴的角度正切值 | |
if ((num11 - x) < 0.0)//鱼在球的右侧 | |
{ | |
if (num14 > 0.0) | |
{ | |
num14 -= Math.PI; | |
} | |
else | |
{ | |
num14 += Math.PI; | |
} | |
} | |
double num15 = num14 - bodyDirectionRad; | |
if (num15 > Math.PI)//---------鱼实际要转过的角度取最优法 | |
{ | |
num15 -= Math.PI * 2; | |
} | |
else if (num15 < -Math.PI) | |
{ | |
num15 += Math.PI * 2; | |
} | |
double juli = Math.Sqrt(Math.Pow(x - num11, 2.0) + Math.Pow(z - num12, 2.0)); | |
if (num15 > 0) | |
{ | |
if (Math.Abs(num15) > 0.1 * Math.PI) | |
{ | |
decisions[i].TCode = 15; | |
decisions[i].VCode = 1; | |
} | |
else | |
{ | |
decisions[i].TCode = 7; | |
if (juli > 550) | |
{ | |
decisions[i].VCode = 12; | |
} | |
if (juli > 350 && juli < 550) | |
{ | |
decisions[i].VCode = 9; | |
} | |
if (juli > 150 && juli < 350) | |
{ | |
decisions[i].VCode = 8; | |
} | |
if (juli > 50 && juli < 150) | |
{ | |
decisions[i].VCode = 7; | |
} | |
if (juli < 50) | |
{ | |
decisions[i].VCode = 0; | |
} | |
} | |
} | |
if (num15 < 0) | |
{ | |
if (Math.Abs(num15) > 0.1 * Math.PI) | |
{ | |
decisions[i].TCode = 0; | |
decisions[i].VCode = 1; | |
} | |
else | |
{ | |
decisions[i].TCode = 7; | |
if (juli > 550) | |
{ | |
decisions[i].VCode = 12; | |
} | |
if (juli > 350 && juli < 550) | |
{ | |
decisions[i].VCode = 9; | |
} | |
if (juli > 150 && juli < 350) | |
{ | |
decisions[i].VCode = 8; | |
} | |
if (juli > 50 && juli < 150) | |
{ | |
decisions[i].VCode = 7; | |
} | |
if (juli < 50) | |
{ | |
decisions[i].VCode = 0; | |
} | |
} | |
} | |
return decisions[i]; | |
} | |
public Decision number_act(int i, int j, xna.Vector3 fishPm, xna.Vector3 ballsPm, RoboFish fish, xna.Vector3 finish_place) | |
{ | |
double xg = finish_place.X; | |
double zg = finish_place.Z;//终点位置 | |
double r = 58.0; | |
double x = fishPm.X; | |
double z = fishPm.Z; //鱼的刚体坐标 | |
double num6 = ballsPm.X; | |
double num7 = ballsPm.Z; //球心坐标 | |
double d = Math.Atan((zg - num7) / (xg - num6));//球心到目标点这条直线和x轴的角度正切值 | |
if ((xg - num6) < 0.0)//目标点位于球心左侧 | |
{ | |
if (d > 0.0) | |
{ | |
d -= Math.PI; | |
} | |
else | |
{ | |
d += Math.PI; | |
} | |
} | |
float targetDirection = (float)d; | |
double num0 = ballsPm.X + (Math.Sqrt(3) * r * Math.Sin(d)); | |
double num1 = ballsPm.Z - (Math.Sqrt(3) * r * Math.Cos(d)); | |
double num2 = ballsPm.X - (Math.Sqrt(3) * r * Math.Sin(d)); | |
double num3 = ballsPm.Z + (Math.Sqrt(3) * r * Math.Cos(d)); | |
double num11 = num6 - (r * Math.Cos(d)); | |
double num12 = num7 - (r * Math.Sin(d));//找到击球点---延长线上 | |
double num13 = num6 + (r * Math.Cos(d)); | |
double num14 = num7 + (r * Math.Sin(d)); | |
double len1 = Math.Sqrt(Math.Pow(x - num11, 2.0) + Math.Pow(z - num12, 2.0)); | |
double len2 = Math.Sqrt(Math.Pow(x - num13, 2.0) + Math.Pow(z - num14, 2.0)); | |
if (len1 < len2) | |
{ | |
xna.Vector3 targetPoint = new xna.Vector3((float)num11, 0f, (float)num12); | |
switchDribble(i, j, fish, targetPoint, targetDirection, true); | |
} | |
else | |
{ | |
double len3 = Math.Sqrt(Math.Pow(x - num0, 2.0) + Math.Pow(z - num1, 2.0)); | |
double len4 = Math.Sqrt(Math.Pow(x - num2, 2.0) + Math.Pow(z - num3, 2.0)); | |
if (len3 > len4) | |
{ | |
xna.Vector3 targetPoint = new xna.Vector3((float)num2, 0f, (float)num3); | |
switchDribble(i, j, fish, targetPoint, targetDirection, true); | |
} | |
else | |
{ | |
xna.Vector3 targetPoint = new xna.Vector3((float)num0, 0f, (float)num1); | |
switchDribble(i, j, fish, targetPoint, targetDirection, true); | |
} | |
} | |
return decisions[i]; | |
} | |
public Decision switchDribble(int i, int j, RoboFish fish, xna.Vector3 targetPoint, float targetDirection, bool flag) | |
{ | |
switch (j) | |
{ | |
// angleTheta1, angleTheta2, disThreshold, VCode1, VCode2, cycles, msPerCycle, flag | |
case 1: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 4, 4, 200, 11, 4, 10, 100, flag); break; //1 | |
case 2: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 5, 3, 120, 3, 9, 6, 100, flag); break; //2 | |
case 3: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 6, 4, 200, 10, 5, 10, 100, flag); break; //3 | |
case 4: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 4, 4, 200, 10, 4, 10, 100, flag); break; //4 | |
case 5: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 6, 4, 200, 10, 5, 10, 100, flag); break; //5 | |
case 6: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 4, 4, 200, 10, 4, 10, 100, flag); break; //6 | |
case 7: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 10, 4, 200, 10, 8, 10, 100, flag); break; //7 快 | |
case 8: StrategyHelper.Helpers.Dribble(ref decisions[i], fish, targetPoint, targetDirection, 10, 4, 200, 14, 8, 10, 100, flag); break; //8 快 | |
default: break; | |
} | |
return decisions[i]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment