/*
* 坦克大战(TankCraft) AI程序
* 颜世光
* 2010.05.21
*/
#define _CRT_SECURE_NO_DEPRECATE
#include "Tank.h"
#include <string.h>
//请勿修改以上头文件
#include <iostream>
#include <algorithm>
#include <limits>
#include <queue>
#include <map>
#include <set>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <fstream>
using namespace std;
ofstream fout("./amai.log");
// 判断坐标是否合法
#define in_range(nx,ny) (nx>=0 && nx<=22 && ny>=0 && ny <=22)
#define valid(nx,ny) (nx > 0 && nx <22 && ny>0 && ny<22 && smap[nx][ny].type !=STONE)
// 翻转坐标
#define RV(x) (22-(x))
// 浮点差值
#define eps (numeric_limits<double>::epsilon())
// 上一轮的命令
struct LSO
{
LSO(){type = STOP;target = -1;conf = 0;}
OrderType type; // 行为
int target; // 目标坦克
int x,y; // 目标点
int conf; // 自信
};
struct point
{
int x,y;
point(int xx,int yy):x(xx),y(yy) {}
point():x(-2),y(-2) {}
bool operator<(const point& ot) const
{
return x<ot.x; // 仅仅是为了能用set
}
};
// pos
struct pos
{
int x;
int y;
double p; // 处在此位置的可能性
double stop_p; // 这些可能性中来自stop的部分
double fork[5]; // 向4个方向的贡献
pos():x(-1),y(-1),p(0.0),stop_p(0.0)
{
for(int i=0;i<5;i++)
fork[i] = 0.0;
}
pos(int xx,int yy,double pp=1.0) :x(xx),y(yy),p(pp),stop_p(0.0)
{
for(int i=0;i<5;i++)
fork[i] = 0.0;
}
// 相等被定义为位置一样
bool operator==(const pos& ot) const
{
return (x==ot.x && y==ot.y);
}
bool operator!=(const pos& ot) const
{
return !(*this==ot);
}
bool operator>(const pos& ot) const
{
if(p > ot.p + eps)
return true;
else if( p + eps <ot.p)
return false;
if(x > ot.x)
return true;
else if(x <ot.x)
return false;
return y > ot.y;
}
bool operator<(const pos& ot) const
{
if(p + eps < ot.p)
return true;
else if( p > ot.p + eps)
return false;
if(x < ot.x)
return true;
else if(x>ot.x)
return false;
return y < ot.y;
}
};
// *-------------------常量----------------------*
const int d0x[1] = {0};
const int d0y[1] = {0};
const int ddx[5] = {-1,0,1,0,0};
const int ddy[5] = {0,-1,0,1,0};
const int d2x[8] = {-2,-1,0,1,2,1,0,-1}; // 2格
const int d2y[8] = {0,1,2,1,0,-1,-2,-1};
const int d3x[12]= {-3,-2,-1,0,1,2,3,2,1,0,-1,-2}; // 3格
const int d3y[12]= {0,1,2,3,2,1,0,-1,-2,-3,-2,-1}; //
const int d4x[16]= {-4,-3,-2,-1,0,1,2,3,4,3,2,1,0,-1,-2,-3};
const int d4y[16]= {0,1,2,3,4,3,2,1,0,-1,-2,-3,-4,-3,-2,-1};
const int d5x[20]= {-5,-4,-3,-2,-1,0,1,2,3,4,5,4,3,2,1,0,-1,-2,-3,-4};
const int d5y[20]= {0,1,2,3,4,5,4,3,2,1,0,-1,-2,-3,-4,-5,-4,-3,-2,-1};
const int *xdx[] = {d0x,ddx,d2x,d3x,d4x,d5x};
const int *xdy[] = {d0y,ddy,d2y,d3y,d4y,d5y};
const int ddn[] = {1,4,8,12,16,20};
const int MX_STOP = 4; // 允许我方坦克最多stop次数
const int O_STOP = 5; // 敌方stop多少次后判定为故意
// *------------------全局变量-------------------*
DataForAI sdata; // 翻转后的data参数
int mask[23][23]; // 我方迷雾 非0为不可视, 0为可视
int dmask[23][23]; // 敌方迷雾
Point* src; // 矿点
TankData *stank; // 原始坦克数组
TankData tank[11]; // 坦克数组
int vtank[10]; // 坦克位置可确定
Order orders[10]; // 当前回合的所有指令
MapCell lsmap[23][23]; // 上一轮地图
MapCell (*smap)[23]; // 传入地图
int src_num; // 矿点数量
int nround; // 当前回合
LSO last_orders[10]; // 上回合指令
int tank_w[10][23][23]; // 坦克到各个点的距离
int src_w[2][13][23][23]; // 矿到各点的距离
int esc_w[11][23][23]; // 逃跑用距离 10为出生点的...
int esc_v[11]; // 距离有效
TankData dtank[10]; // 敌方坦克数组,用于预测敌方坦克行动
pos e_next[10]; // 敌方下一步要走的(如果不攻击的话)
int wt_map[4][23][23]; // 路径权值
int m_src; // 己矿个数
int e_src; // 敌矿个数
int m_gold;
int e_gold;
Order norder; // STOP
int willfire[10]; // 愿意开火
int willstop[10]; // 当前轮准备stop
int sn_stop[10]; // stop轮数
int e_willstop[10]; // 断定敌方本轮stop
int e_target[10]; // 敌方本轮目标
int stop_for[10]; // 为某个sn停止的轮数
// *------------------全息变量-------------------*
pos tankpt[405][10]; // 坐标
vector<pos> allpt[405][10]; // 所有坐标
TankData ldtank[10]; // 当前轮坦克信息(包含预测的敌方位置)
// *------------------策略变量-------------------*
bool st_track = false; // st是否追逐
bool pn_track = true; // p是否追逐
int e_forecast; // 对方预测指数
int e_stop; // 对方stop指数
int e_farbreak; // 远距离开路
int dir_p[4][4]; // 4向优先级对比矩阵
int e_sniper,e_pioneer,e_striker; // 敌方坦克个数
// *------------------临时变量-------------------*
int tmp_mx[23][23];
// *------------------前向声明-------------------*
void init_data(DataForAI& data); // 初始化本轮数据
void flood(int id); // 搜索坦克与矿的距离
Order step_to(int id,int dx,int dy); // 单步移动
Order attack(int sid,int did); // 攻击
void analyse(); // 分析 决策
bool fire(); // 寻找目标开火
Order move_to(int id,int dx,int dy); // 向某点移动
Order sniper_escape(int id); // sniper躲避
void sniper_ai(int id); // sniper行动ai
void sniper_stop(); // sniper是否要停下一轮
void pioneer_ai(int id); // pioneer行动ai
int tank_dis(int id,int did,TankData* _tank = tank);
void recalc_p(vector<pos>& vpt); // 重新计算概率
void calc_w(); // 计算路径权值
void calc_w_for_run(void); // 闪避路径权值
void calc_w_for_move(); //
void flood_from(int sx,int sy,int vm[][23],int at);
Order rv_order(Order order); // 翻转命令
void rv_data(DataForAI& data); // 翻转数据
Order suicide(int id); // 自杀
Order dance(DataForAI& data); // 跳舞
// *-------------------入口函数-------------------*
//平台0回合时调用此函数获取AI名称及坦克类型信息,请勿修改此函数声明。
extern "C" InitiateInfo chooseType()
{
InitiateInfo Info;
Info.tank[0] = Sniper;
Info.tank[1] = Sniper;
Info.tank[2] = Sniper;
Info.tank[3] = Sniper;
Info.tank[4] = Sniper;
strcpy(Info.aiName,"AMAI"); //AI名请勿使用中文
// nround = 0;
nround = 0;
// 空指令
norder.type = STOP;
// sn的连续埋伏次数
for(int i=0;i<10;i++)
sn_stop[i] = 0;
// 远距离打墙
e_farbreak = 0;
// tank位置
for(int i=0;i<10;i++)
tankpt[0][i] = pos(-2,-2);
// 这个没必要么?
for(int i=0;i<400;i++)
for(int d=0;d<10;d++)
allpt[i][d].clear();
return Info;
}
//平台从第1回合开始调用此函数获得每回合指令,请勿修改此函数声明。
extern "C" Order makeOrder(DataForAI data)
{
// 计时开始
int start = clock();
// 数据预处理,现在我们永远是红方
rv_data(data);
// 当前坦克id
int nid = sdata.myID;
// 如果不是新的一轮,返回决策
if(sdata.round == nround)
return orders[nid];
// 新的一轮
nround = sdata.round;
// fout<<"--------------------------------Round: "<<nround<<"----------------------------------"<<endl;
// 更新全局变量
init_data(sdata);
// 决策
analyse();
// 保存结果地图
memcpy(lsmap,smap,sizeof(lsmap));
// 打印敌方参数
// fout<<"敌方参数:e_forecast-"<<e_forecast<<" e_stop-"<<e_stop<<endl;
// 处理指令
for(int i=0;i<10;i++)
if(data.myFlag == BLUE)
orders[i] = rv_order(orders[i]);
// 输出处理时间
int usetime = clock() - start;
// fout<<"Time: "<<usetime<<endl;
if(usetime > 100)
fout<<"Round "<<nround<<"用时:"<<usetime<<"毫秒"<<endl;
return orders[nid];
}
// *-------------------------------自定义函数---------------------------------*
// 向x,y点开火,不处理伤害
Order fire_at(int x,int y)
{
Order order;
order.type = FIRE;
order.row = x;
order.col = y;
return order;
}
// 计算我方视野
void our_shadow()
{
// 没有视野的地方是 -1 而不是 1
memset(mask,-1,sizeof(mask));
// 矿点视野
for(int si=0;si<src_num;si++)
{
int sx = src[si].row;
int sy = src[si].col;
for(int i=-2;i<=2;i++)
for(int j=-2;j<=2;j++)
if( abs(i) + abs(j) <=2 && valid(sx+i,sy+j)) // 所有矿点视野
mask[sx+i][sy+j] = 0;
}
// tank视野
for(int id=0 ;id
AI.rar_ai_坦克大战
版权申诉
17 浏览量
2022-09-14
18:12:05
上传
评论
收藏 25KB RAR 举报
御道御小黑
- 粉丝: 62
- 资源: 1万+
最新资源
- python建模算法 - 组合赋权法.rar
- c#解析SQL语句(分析语句).zip
- 2024 年上海高职院校学生技能大赛“互联网+国际经济与贸易”赛项样题-外贸 B2B 模块.pdf
- 1111111111111111111
- 2024 年上海高职院校学生技能大赛“电子商务”赛项样题.pdf
- 附件2春节档-电影票房三十日时段趋势数据.xlsx
- 2024 年上海高职院校学生技能大赛 高职组“软件测试”赛项样题.pdf
- 2024 年上海高职院校技能大赛样题-GZ018智能飞行器应用技术(学生赛)竞赛任务书.pdf
- MC56F827xx快速上手指南.docx
- Binlog数据恢复,生成反向SQL语句.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0