一.核心代码结构
// 基础头文件(依赖平台SDK)
#include <rcsc/player/player_agent.h>
#include <rcsc/geom/vector_2d.h>
using namespace rcsc;
// 自定义世界模型类
class WorldModel {
public:
void update(const PlayerAgent* agent) {
// 从agent获取实时信息
wm_ball = agent->world().ball().pos();
wm_self = agent->world().self().pos();
// 更新队友/对手位置
updateTeammates(agent);
updateOpponents(agent);
}
Vector2D ballPos() const { return wm_ball; }
Vector2D selfPos() const { return wm_self; }
private:
Vector2D wm_ball;
Vector2D wm_self;
std::vector<Vector2D> teammates;
std::vector<Vector2D> opponents;
};
// 决策主类继承官方PlayerAgent
class MyPlayer : public PlayerAgent {
public:
MyPlayer() : wm(new WorldModel) {}
// 主决策入口
void actionImpl() override {
wm->update(this);
if (isGoalie()) {
executeGoalieBehavior();
} else {
fieldPlayerDecision();
}
}
private:
std::unique_ptr<WorldModel> wm;
// 门将行为
void executeGoalieBehavior() {
Vector2D move_point = calculateGoalieMove();
doMove(move_point);
}
// 场员决策
void fieldPlayerDecision() {
if (shouldInterceptBall()) {
interceptBall();
} else if (isInAttackArea()) {
executeAttack();
} else {
positioning();
}
}
};
二、关键模块实现
1. 世界状态感知
// 球轨迹预测
Vector2D predictBallTrajectory(int steps) {
Vector2D vel = world().ball().vel();
return wm_ball + vel * steps * 0.94; // 考虑空气阻力系数
}
// 判断是否最接近球
bool isClosestToBall() const {
double my_dist = (selfPos() - ballPos()).r();
for (const auto& tm : teammates) {
if ((tm - ballPos()).r() < my_dist) return false;
}
return true;
}
2. 动作技能库
// 基础移动动作
void doMove(const Vector2D& target) {
double dash_power = calcDashPower(target);
double angle = (target - selfPos()).th();
dash(dash_power, angle);
}
// 精确传球实现
void executePass(int receiver_unum) {
PlayerObject* receiver = findTeammate(receiver_unum);
Vector2D target_point = receiver->pos() + receiver->vel() * 0.5; // 提前量
kickToPoint(target_point, 80); // 80%力量
}
// 射门计算
void shootToGoal() {
Vector2D goal_pos(52.5, 0); // 对方球门坐标
double angle_error = calcShootError(goal_pos);
kick(100, angle_error); // 满力射门
}
三、策略逻辑示例
1.区域防守策略
void executeZoneDefense() {
const Rect2D my_zone = getAssignedZone(world().self().unum());
Vector2D ball_proj = predictBallTrajectory(5);
if (my_zone.contains(ball_proj)) {
interceptBall();
} else {
moveToZoneCenter(my_zone);
}
}
2.快速反击
void fastCounterAttack() {
if (isBallHolder()) {
PlayerObject* forward = findFastestForward();
if (isPassPathClear(forward)) {
executePass(forward->unum());
} else {
dribbleToSpace();
}
} else {
makeForwardRun();
}
}
3.通信协议实现
// 发送消息给队友
void sendPositionMessage() {
std::ostringstream oss;
oss << "(say " << world().self().unum()
<< " " << selfPos().x << " " << selfPos().y << ")";
sendMessage(oss.str());
}
// 解析队友消息
void parseTeammateMessage(const std::string& msg) {
int unum;
double x, y;
if (sscanf(msg.c_str(), "%d %lf %lf", &unum, &x, &y) == 3) {
updateTeammatePosition(unum, Vector2D(x, y));
}
}
4.性能优化技巧
// 空间索引加速查询
class SpatialHash {
public:
void update(const std::vector<Player>& players) {
grid_.clear();
for (const auto& p : players) {
int key = hashPosition(p.pos());
grid_[key].push_back(p);
}
}
std::vector<Player> queryArea(const Rect2D& area) {
// 通过哈希快速检索区域内对象
}
};
// 内存池优化
template<typename T>
class ObjectPool {
public:
T* acquire() {
if (pool_.empty()) return new T;
T* obj = pool_.back();
pool_.pop_back();
return obj;
}
void release(T* obj) {
pool_.push_back(obj);
}
};
四、基础移动与感知
1.路径规划与避障
// 基于势场法的移动(示例)
void AdvancedPlayer::moveToTarget(const Vector2D& target) {
const double max_speed = 1.0; // 最大速度限制
Vector2D desired_velocity = (target - world().self().pos()).normalize() * max_speed;
// 避障势场计算
for (const auto& obj : world().opponents()) {
if (obj.distFromSelf() < 3.0) {
Vector2D repulse = (world().self().pos() - obj.pos()).normalize()
* (3.0 / obj.distFromSelf());
desired_velocity += repulse;
}
}
// 执行移动
doDash(desired_velocity.r(), desired_velocity.th() - world().self().body());
}
2.球状态感知
// 判断是否控球
bool hasBallControl() const {
const double BALL_CONTROL_DIST = 0.5; // 控球判定距离
return world().self().pos().dist(world().ball().pos()) < BALL_CONTROL_DIST
&& world().self().body().abs() - world().ball().vel().th().abs() < 30.0;
}
五、 高级策略实现
1.动态角色分配
// 基于 Voronoi 图的位置分配
void assignRoles() {
std::vector<Vector2D> positions = calculateVoronoiRegions();
for (int unum = 1; unum <= 11; ++unum) {
if (world().self().unum() == unum) {
Vector2D target = positions[unum - 1];
moveToTarget(target);
break;
}
}
}
2.团队传球配合
// 三角传球策略
void executeTrianglePass() {
const PlayerObject* left = findTeammateOnLeft();
const PlayerObject* right = findTeammateOnRight();
if (left && right && isPassSafe(left)) {
kickToPoint(left->pos() + left->vel() * 0.8, 85.0); // 带提前量
} else if (right && isPassSafe(right)) {
kickToPoint(right->pos() + right->vel() * 0.6, 75.0);
} else {
dribbleToSpace(); // 无法传球则带球突破
}
}
3.角球战术模板
void executeCornerKick() {
if (world().self().isKickTaker()) {
// 选择传中或短传
if (findHeaderTarget()) {
kickToGoalArea(90.0); // 高球传中
} else {
shortPassToNearest();
}
} else {
// 其他球员跑位
if (isNearPostPlayer()) {
makeNearPostRun();
} else {
createSpaceMovement();
}
}
}
4.人盯人防守
void markOpponent(int opp_unum) {
const PlayerObject* opponent = world().getOpponent(opp_unum);
if (!opponent) return;
Vector2D mark_pos = opponent->pos() + opponent->vel() * 0.5; // 预测位置
mark_pos += (opponent->pos() - world().ball().pos()).normalize() * 1.5; // 保持安全距离
moveToTarget(mark_pos);
faceBall(); // 始终面向球
}
5.动态越位陷阱
void checkOffsideTrap() {
if (isDefensiveLeader()) { // 防守指挥官触发
double trap_line = calculateOffsideLine();
if (world().ball().pos().x < trap_line - 5.0) {
broadcastCommand("PUSH_LINE"); // 通知队友前压
}
}
}
6.加密通信格式
// 发送带校验的消息
void sendEncodedMessage(const std::string& msg) {
std::string encoded = Base64::encode(msg); // 使用Base64编码
agent->addSayMessage(encoded.substr(0, 50)); // 限制长度
}
// 解析队友消息
void parseMessage(const std::string& msg) {
std::string decoded = Base64::decode(msg);
std::istringstream iss(decoded);
int code;
double x, y;
if (iss >> code >> x >> y) {
updateTeammatePosition(code, Vector2D(x, y));
}
}
7.快速球轨迹预测
// 使用二阶运动模型预测
Vector2D predictBallPos(int cycle) const {
const double BALL_DECAY = 0.94; // 官方定义的衰减系数
Vector2D pos = world().ball().pos();
Vector2D vel = world().ball().vel();
for (int i = 0; i < cycle; ++i) {
pos += vel;
vel *= BALL_DECAY;
}
return pos;
}
8.空间哈希加速查询
class SpatialHash {
public:
void update(const std::vector<Player>& players) {
grid.clear();
for (const auto& p : players) {
int key = hash(p.pos());
grid[key].push_back(p);
}
}
std::vector<Player> queryNearby(const Vector2D& center, double radius) {
// 通过哈希快速检索附近球员
}
};
9.实时状态记录
// 使用宏定义调试输出
#ifdef DEBUG
#define LOG_DEBUG(msg) do { \
std::ofstream log("debug.log", std::ios::app); \
log << world().time() << ": " << msg << std::endl; \
} while(0)
#else
#define LOG_DEBUG(msg)
#endif
// 使用示例
LOG_DEBUG("Ball pos: " << world().ball().pos());