★「C++游戏」幻影之战 BattleOfPhantom:一款集合多种人机对战以及联机对战的战斗游戏

news/2024/11/21 1:27:03/

(原创)
目前正在不断更新!

★ 一款超级有趣的大乱斗游戏,包含多种游戏模式,支持双人联机。
离线情况下也可以与多个(或一群)机器玩家进行疯狂的对战
直接上图
标题画面

使用C++ with EGE图形库编写
有一定数量的BUG,请谅解。

双人离线模式下的一张截图
[ 双人离线的一张截图 ]

操作说明

A,W,S,D | 主玩家移动
1/2/3/4 | 主玩家选择武器或道具
J | 主玩家向面前方向攻击
Backspace退格 | 主玩家删除当前武器或道具(注意:装备是靠刷新更好的,不能删)
鼠标左键 | 向鼠标方向攻击(非常方便),将被识别成八个方向之一(双人离线为了平等不能使用)

↑←↓→ | 双人离线时玩家2的移动
小键盘1/2/3/4 | 双人离线时玩家2选择武器或道具
小键盘0 | 双人离线时玩家2向面前方向攻击(原先是5,但因为不太好操作于是改了)
小键盘减号 | 双人离线时玩家2删除当前武器或道具

F2 | 立即窗口截图,存入Screenshots文件夹中
Esc | 退出战斗

基本玩法

比如说人机离线对战模式(是可以使用鼠标攻击的),
开局就先随机获得两把武器,两个道具,没有装备。
你可以通过右侧的对方方位与距离锁定敌人的位置进行有效攻击。
机器玩家的算法还说得过去,有时真难弄死它。
人机对战的一张截图
[↑ 人机对战的一张截图 ]
普通模式下一般都是300滴血,只有比较容易死的模式会1000血甚至5000血。(自己探索)
有些武器带效果的,要注意防护与使用:
效果数据
有些剑是带剑气的;
有些弹药是会反弹/爆炸/分裂/追踪(分为3种等级)/穿墙的。
实体属性(局部)
武器千奇百怪,战斗场面琳琅满目:
混战模式的一张截图
[↑ 混战模式的一张截图 ——那个血量不是正常的血量,请忽视 ]
群殴模式是很难挺过去的,你可以尝试一下!!
群殴模式的一张截图
群殴模式会给你1000血加上长时间的矫捷效果与永久的穿人特权。就算这样也能死得很惨。
诀窍是不断逃跑,让他们自己误伤。逃跑的时候注意安全。

  • 离线团战一定要把对方所有人消灭,但自己死了就算失败了。
  • 作为队伍头领,一定要学会保护自己!
    团战的一张截图
  • 队伍颜色是随机的
  • 右侧将会有显示真实水平的击杀榜、队伍剩余人数、最近敌人等数据。

★ 新版本加了一个叫等级与经验的机制(如上图左上角),击杀、伤害敌人,拾取物资都会获取经验,经验达到一定水平后等级+1.等级的高低将决定所抽武器道具装甲的好坏!!(等级最高10级)

最后关于联机:

  • 在线模式下服务端开启后,客户端依次输入服务端IP地址和端口号即可
    (若无外网则必须同一局域网下)
    配置外网时映射的IP需要是服务端开启后显示的IP(也就是服务端电脑第一个能用的IP)
    服务端

  • 端口号一律填8888.
    使用外网时,在输入IP地址界面不得输入域名。
    客户端输入的端口号是映射后的端口号(一般是五位数而不是8888)
    需要使用IP地址。获取其IP地址可以通过ping命令获得:
    Win+R打开运行,输入cmd
    ping命令获取外网IP地址

  • 联机的时候经常会崩溃,应该是这个TCP连接太差劲的缘故,也么有办法,因此我尽量减少机器玩家的数量。凑合着玩吧。不要使用频率极高的武器,因为更容易致使崩溃。

这款游戏已经写了一年左右了,祝愿大家玩得愉快
源码真的很长(一万多行了!)真的想要的话(也不给 XD )
无源码的游戏链接: https://download.csdn.net/download/cjz2005/86287023

★★★

为了造福广大苍生,我决定放一点源码给大家看看!
这是机器玩家的AI算法,原创,还行,有兴趣的同志可以好好研究一下。

//Dir Modes
#define DIR_NONE 0x00
#define DIR_4 0x01
#define DIR_8 0x02//AI Modes
#define AAM_STILL 0		//静止
#define AAM_WANDER 1	//多逛
#define AAM_CHASE 2		//多追
#define AAM_FLEE 3		//多逃//Constants
#define AA_CHANGE_MODE_RATE 25			//模式更改机率
#define AA_CHANGE_MODE_MIN_T 1000*6	//模式更改最小周期
#define AA_CHANGE_WEAPON_RATE 32			//武器切换概率
#define AA_CHANGE_WEAPON_MIN_T 1000*8	//武器切换最小周期
#define AA_LEVEL_UP_T 1000*43		//等级提升周期
#define AA_DRINK_POTION_RATE 8		//喝药水概率
#define AA_DODGE_BASE_RATE 13	//基础闪避概率
#define AA_DODGE_RATE_MAX 60	//闪避概率最大值
#define AA_DODGE_UP_RATIO 0.5	//闪避提升率
#define AA_DODGE_T 1000*0.9		//闪避周期
#define AA_EXTRA_DODGE_RATE_T 1000*65	//闪避概率微调周期
#define AA_CHANGE_TARGET_MIN_T 11000	//目标切换最小周期 
#define AA_CHANGE_TARGET_RATE 8		//目标切换概率 
#define AA_REVENGE_RATE 40		//复仇概率class AIControl {	//AI控制玩家算法
public:bool enabled;	//是否启用 int my_index;		//附着玩家下标 int target_index;	//目标玩家下标(可变) int team_index;		//队伍下标clock_t lastModeChanged;	//上一次切换模式 clock_t lastWeaponChanged;	//上一次切换武器 clock_t lastChangeTarget;	//上一次切换攻击目标 clock_t lastUp;				clock_t lastDodge;			//上一次闪避 clock_t lastExtraRateChanged;	//上一次改变额外躲闪率 int extraDodgeRate;		//额外躲闪率 int mode;		//AI模式 int xp;		//经验值BYTE extraMode;		//作弊额外模式 float adjust;const vector<int> mode_prob = { 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3 };	//带比重const vector<int> curw_prob = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3 };	//带比重AIControl(){target_index = 0;	//默认主角为目标team_index = 0;adjust = 0;enabled = false;Init();}void Init()	//initialize{my_index = 1;	//<!>target_index = 0;	//默认主角为目标extraDodgeRate = 0;extraMode = AAE_NONE;mode = AAM_CHASE;lastModeChanged = clock() + 5000;lastWeaponChanged = clock();lastExtraRateChanged = clock();lastChangeTarget = clock();lastUp = clock();lastDodge = clock();xp = 0;adjust = (GetPlayerCount() * 5 + 10101 + RandomRange(0, 100, true, false)) % 100 / 100.0;}void Close()	//关闭 {enabled = false;mode = AAM_STILL;xp = 0;target_index = 0;}void Update()	//更新{if (!enabled || !IsPlayerAlive(my_index))	//未启用状态或死亡状态直接退出 return;CheckLevelUp();int r;//离线模式下,玩家2成为AI玩家//在线模式下,自己成为AI玩家(自动攻击)r = RandomRange(0, 100, true, false);	//percentif (r > 100 - AA_CHANGE_MODE_RATE - adjust*6 && (clock() - lastModeChanged > AA_CHANGE_MODE_MIN_T)){mode = mode_prob.at(RandomRange(0, mode_prob.size() - 1, true, true));lastModeChanged = clock();}if (clock() - lastExtraRateChanged > AA_EXTRA_DODGE_RATE_T){extraDodgeRate = Varience(0, 5+adjust*6);lastExtraRateChanged = clock();}Move();		//根据模式进行移动if (clock() - lastDodge > AA_DODGE_T + adjust * 3){TryToDodge();	//checking inside}if (g_bIdt != IDT_OFFLINE){if(GetDirMode(GetPlayerCurWeapon(my_index)) == DIR_8)GetPlayerFace(my_index) = FaceDir8(target_index);elseGetPlayerFace(my_index) = FaceDir4(target_index);}#ifndef AI_CONCENTRATEif(g_mode != 0 && g_mode != 1 && g_mode != 2 	//就两个玩家时无需切换 && g_mode != 3	//离线群殴始终只有一个目标&& (!IsPlayerAlive(target_index)	//目标死了就赶紧换目标 没有CD和概率要求|| (RandomRange(0,100,true,false) < AA_CHANGE_TARGET_RATE + adjust * 9	//还有概率 && clock() - lastChangeTarget >= AA_CHANGE_TARGET_MIN_T))){	//切换目标 int new_target_index = this->target_index;int min_dist = 9999;for(int i = 0; i < GetPlayerCount(); ++i){if (!IsPlayerAlive(i) || i == my_index)continue;if ((g_mode == 5 || g_mode == 9)&& GetPlayerTeam(i) == team_index){	//团战时 放过队友continue;}if ((g_mode == 6 || g_mode == 7) && i != 0 && i != 1)continue;	//在线群殴只能以人为目标auto _dist = Distance(GetX(),GetY(),GetPlayerX(i),GetPlayerY(i));if(_dist < min_dist){new_target_index = i;min_dist = _dist;}}this->target_index = new_target_index;/*if(mode != AAM_CHASE && RandomRange(0,100,true,false) < AA_CHANGE_MODE_RATE + adjust * 8){	//追赶加强this->mode = AAM_CHASE;}*/}
#endifif (RandomRange(0, 100, true, false) < 20 + adjust * 10)this->mode = AAM_CHASE;Attack();	//根据模式进行攻击}void CheckLevelUp(){if (clock() - lastUp > AA_LEVEL_UP_T){int upv = 1;	//升级默认1级if (GetPlayerHp(my_index) > 1 && GetPlayerHp(target_index) > GetPlayerHp(my_index) * 1.8)upv = 2;	//当血量差得太远的时候,升级加速xp += upv; lastUp = clock();}}void OnHurt(int hurt_by)	//受伤时调用{if(!enabled)return;lastUp += 1000 * RandomRange(0,3,true,true);	//经验有增长的趋势if(mode == AAM_STILL || mode == AAM_WANDER)		//迅速进入正常状态lastModeChanged += 1000 * 4 + adjust * 100;if (PlayerHasAffect(my_index,3) || PlayerHasAffect(my_index,7) || PlayerHasAffect(my_index,11) || PlayerHasAffect(my_index,12)){extraDodgeRate += RandomRange(5, 9 + adjust * 2, true, false);	//躲闪率微调}else {extraDodgeRate += RandomRange(4, 7 + adjust * 2, true, false);	//躲闪率微调}if (hurt_by != my_index && hurt_by != target_index	//非我非你&& (g_mode == 5 || g_mode == 9) || (GetPlayerTeam(hurt_by) != team_index)	//异队&& g_mode != 3 //<!>离线群殴没有复仇;在线群殴还是有复仇的){if (RandomRange(0, 100, true, false) < AA_REVENGE_RATE){	//复仇target_index = hurt_by;}}}DIR FaceDir8(int i) const{POINT et{GetPlayerX(i),GetPlayerY(i)};if (IsOuttaField(POINT2(et.x, et.y)))return 0;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index); int ey = GetPlayerY(target_index); if (x < ex){if (y > ey)	return RIGHTUP;else if (y < ey)	return RIGHTDOWN;else	return RIGHT;}else if (x > ex){if (y > ey)	return LEFTUP;else if (y < ey)	return LEFTDOWN;else	return LEFT;}else {if (y > ey)	return UP;else	return DOWN;}}DIR FaceDir4(int i) const{POINT et{GetPlayerX(i),GetPlayerY(i)};if (IsOuttaField(POINT2(et.x, et.y)))return 0;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index); int ey = GetPlayerY(target_index); if (ex > x){if (ey > y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? RIGHT : DOWN) : (RandomRange(1, 10) > 7 ? DOWN : RIGHT));else if (ey < y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? RIGHT : UP) : (RandomRange(1, 10) > 7 ? UP : RIGHT));elsereturn RIGHT;}else if (ex < x){if (ey > y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? LEFT : DOWN) : (RandomRange(1, 10) > 7 ? DOWN : LEFT));else if (ey < y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? LEFT : UP) : (RandomRange(1, 10) > 7 ? UP : LEFT));elsereturn LEFT;}else {if (ey > y)return DOWN;elsereturn UP;}}UINT GetI() const {			//获取下标/*if (enabled == false)return 2;	//无else if (g_bIdt == IDT_OFFLINE)return 1;elsereturn g_p_i;*/return my_index;}UINT GetOppoI() const {return target_index;	}int GetX() const{return GetPlayerX(GetI());}int GetY() const{return GetPlayerY(GetI());}void _Tag(string text) const{setcolor(WHITE);setbkmode(OPAQUE);setfont(20, 0, "微软雅黑");xyprintf(20, 500, "TAG:%s", text.c_str());}void Move(){EXCEPTION_L//debug _Tag("Move");/*if (mode == AAM_STILL){return;}else */if (mode == AAM_WANDER){if (!PlayerTimeToMove(my_index))return;DIR dir;int x, y;_retry:dir = 2 * RandomRange(1, 4, true, true) - 1;x = GetX();y = GetY();if (PlayerHasAffect(GetI(), 12))dir = OppoDir(dir);DirOffsetPos(x, y, dir, "AIControl::Move");if (IsOuttaField(POINT2(x,y)) || IsBarrier(bk(x, y, "AIControl::Move"))){goto _retry;}//MoveGetPlayerX(my_index) = x;GetPlayerY(my_index) = y;bool sendMsg = (g_bIdt != IDT_OFFLINE);if (sendMsg)SendTCP(UM_SETPOS, x, y, GetI());
//			p[GetI()].lastMove = clock();LastMove(my_index);}else if (mode == AAM_CHASE || mode == AAM_FLEE || mode == AAM_STILL){if (!PlayerTimeToMove(my_index))return;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index);int ey = GetPlayerY(target_index);DIR xd, yd;if (ex > x)xd = RIGHT;else if (ex < x)xd = LEFT;elsexd = 0;if (ey > y)yd = DOWN;else if (ey < y)yd = UP;elseyd = 0;int r = RandomRange(0, 1, true, true);DIR dir;	//final dirif (xd == RIGHT){if (yd == 0)dir = RIGHT;else {dir = (r ? RIGHT : yd);}}else if (xd == LEFT){if (yd == 0)dir = LEFT;else {dir = (r ? LEFT : yd);}}else {dir = yd;}if (mode == AAM_FLEE)	//相反逃离dir = OppoDir(dir);if (PlayerHasAffect(GetI(), 12))dir = OppoDir(dir);	//混沌效果 直接再反//Move(CHASE)DirOffsetPos(x, y, dir,"AIControl::Move");if (!IsOuttaField(POINT2(x, y)) &&!IsBarrier(bk(x,y,"AIControl::Move")) && //!(x == ex && y == ey)	&&	//不能与对方重叠!HasPlayerTouch(my_index,dir)	//不能与别的玩家重叠)	{if (mode != AAM_STILL){bool sendMsg = (g_bIdt != IDT_OFFLINE);GetPlayerX(my_index) = x;GetPlayerY(my_index) = y;if (sendMsg)SendTCP(UM_SETPOS, x, y, GetI());}GetPlayerFace(my_index) = dir;
//				p[GetI()].lastMove = clock();LastMove(my_index);//return;}elseLastMove(my_index);}else {}EXCEPTION_R_TITLED("BOP AIControl::Move EXCEPTION")}DIR GetComingDir(const Entity& et) const{if (IsOuttaField(POINT2(et.x, et.y)))return 0;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index);int ey = GetPlayerY(target_index);DIR eface = et.face;if (eface == RIGHT && y == ey && x > ex)return LEFT;else if (eface == LEFT && y == ey && x < ex)return RIGHT;else if (eface == DOWN && x == ex && y > ey)return UP;else if (eface == UP && x == ex && y < ey)return DOWN;else if (eface == LEFTDOWN && (x - ex < 0) && (x - ex) / float(y - ey) == -1.0f)return RIGHTUP;else if (eface == LEFTUP && (x - ex < 0) && (x - ex) / float(y - ey) == 1.0f)return RIGHTDOWN;else if (eface == RIGHTDOWN && (x - ex > 0) && (x - ex) / float(y - ey) == 1.0f)return LEFTUP;else if (eface == RIGHTUP && (x - ex > 0) && (x - ex) / float(y - ey) == -1.0f)return LEFTDOWN;elsereturn 0;}void TryToDodge(){	//尝试躲闪 if (entities.empty())return;int x = GetX();int y = GetY();int dp;int r;dp = Varience(AA_DODGE_BASE_RATE,4)	//基础也在变动+ xp * AA_DODGE_UP_RATIO + adjust * 3+ extraDodgeRate;//各种效果对其的影响if (PlayerHasAffect(my_index, 6))dp -= 4;if (PlayerHasAffect(my_index, 7))dp -= 3;if (PlayerHasAffect(my_index, 9))dp -= 6;if (PlayerHasAffect(my_index, 11))dp -= 10;else if (PlayerHasAffect(my_index, 12))dp -= 9;if (PlayerHasAffect(my_index, 1))dp -= 2;if (PlayerHasAffect(my_index, 14))dp -= 8;	//隐身的时候得削弱一下,否则太难玩了ClampA(dp, AA_DODGE_BASE_RATE-5, AA_DODGE_RATE_MAX);	//限制if (PlayerHasAffect(my_index, 4))	//矫捷dp += 3 + adjust * 1;//debug _Tag(ToString(dp));for (int i = 0; i < entities.size(); i++){double dist = Distance(x, y, entities.at(i).x, entities.at(i).y);DIR aimdir=0;if (aimdir = GetComingDir(entities.at(i))){int dextra_rate = 0;	//根据距离决定的 额外 补充/扣除 概率if (dist < 2.1f)dextra_rate = 4;else if (dist < 4.4f)dextra_rate = 0;else if (dist < 6.3f)dextra_rate = -4;else if (dist < 10.5f)dextra_rate = -8;else {dextra_rate = -16;}r = RandomRange(0, 100, true, false);if (r < dp + dextra_rate){Dodge(aimdir);	//尽力闪避}//continue;break;}}//end of for}bool FaceBarrier(int _x, int _y, DIR face){int nx = _x, ny = _y;DirOffsetPos(nx, ny, face, "FaceBarrier");if (IsBarrier(bk(nx, ny, string(__func__))) || IsOuttaField(POINT2(nx, ny)))return true;return false;}bool Dodge(DIR aimdir){	//调用此函数时,必须尽力闪避if (aimdir == 0)return false;if (PlayerHasAffect(my_index, 2) || PlayerHasAffect(my_index, 10))	//不能动的效果一定要中止,否则会被视为作弊return false;const vector<DIR> _choices{1,3,5,7};	//四向vector<DIR> choices{};DIR oppdir = 0;	//最终选择for (int i = 0; i < _choices.size(); i++){if (_choices.at(i) != aimdir && _choices.at(i) != OppoDir(aimdir)){choices.push_back(_choices.at(i));}else if (_choices.at(i) == OppoDir(aimdir)){oppdir = _choices.at(i);}}if (oppdir != 0){choices.push_back(oppdir);	//最后选择}bool sendMsg = (g_bIdt != IDT_OFFLINE);for (int k = 0; k < choices.size(); k++){if (!HasPlayerTouch(GetI(),choices.at(k))		//不碰玩家&&  !FaceBarrier(GetX(),GetY(),choices.at(k))	//不碰壁,不出图){int x = GetX(), y = GetY();DirOffsetPos(x, y, choices.at(k), "Dodge");SetPlayerPos(GetI(), x, y);		//闪避if (sendMsg)SendTCP(UM_SETPOS, x, y, GetI());return true;					//成功}}return false;	//闪避失败}
#define AA_CANREACH_RANGE_MAX 30bool CanReach(int x, int y, DIR face, int ex, int ey) const{	//能否打得到if (face == 0)return false;int _x = x, _y = y;int i = 0;if (face == RIGHT || face == LEFT){if (y != ey)return false;while (!IsOuttaField(POINT2(_x, _y)) && !IsBarrier(bk(_x, _y, "AIControl::CanReach")) && i < AA_CANREACH_RANGE_MAX){if (_x == ex && _y == ey)return true;DirOffsetPos(_x, _y, face, "AIControl::CanReach");i++;//DebugLog(ToString(i),false);}return false;}else if (face == DOWN || face == UP){if (x != ex)return false;while (!IsOuttaField(POINT2(_x, _y)) && !IsBarrier(bk(_x, _y, "AIControl::CanReach")) && i < AA_CANREACH_RANGE_MAX){if (_x == ex && _y == ey)return true;DirOffsetPos(_x, _y, face, "AIControl::CanReach");i++;//DebugLog(ToString(i), false);}return false;}else {if (x == ex || y == ey)return false;while (!IsOuttaField(POINT2(_x, _y)) && !IsBarrier(bk(_x, _y, "AIControl::CanReach")) && i < AA_CANREACH_RANGE_MAX){if (_x == ex && _y == ey)return true;DirOffsetPos(_x, _y, face, "AIControl::CanReach");i++;//DebugLog(ToString(i), false);}return false;}}double GetTargetDistance()	const{	//获取目标距离 return Distance(GetPlayerX(my_index),GetPlayerY(my_index),GetPlayerX(target_index),GetPlayerY(target_index));}void Attack(){EXCEPTION_L//_Tag("Attack");int r = RandomRange(0, 100, true, false);if (r > 100 - AA_CHANGE_WEAPON_RATE && (clock() - lastWeaponChanged) > AA_CHANGE_WEAPON_MIN_T){do {GetPlayerCurWeaponIndex(my_index) = curw_prob.at(RandomRange(0, curw_prob.size() - 1, true, true));} while (GetPlayerCurWeaponIndex(my_index) == 0);	//不能选空的格子lastWeaponChanged = clock();}
//		double distance = GetOppoDistance();double distance = GetTargetDistance();UINT type = GetItemType(GetPlayerCurWeapon(my_index));int x = GetX();int y = GetY();int ex = GetPlayerX(target_index);int ey = GetPlayerY(target_index);DIR face = GetPlayerFace(my_index);UINT ptype;ITEM_ID id = GetPlayerCurWeapon(my_index);if(type == ITT_PROP)ptype = GetItemPropType(GetPlayerCurWeapon(my_index));if (type == ITT_BOW || type == ITT_GUN|| (type == ITT_PROP && ptype == ITPT_THROWABLE))	//远程武器{bool reach = CanReach(x, y, face, ex, ey);r = RandomRange(0, 100, true, false);int blind_prob = 10;if (mode == AAM_FLEE)blind_prob = 2;else if (type == ITT_PROP && ptype == ITPT_THROWABLE)blind_prob = 1;elseblind_prob = 11;if(reach && r > (mode == AAM_CHASE ? 49 : 62) || r < blind_prob)
//				p[GetI()].TryToAttack(GetI(), (g_bIdt != IDT_OFFLINE));	//checking is insidePlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE));	//checking is inside}else if (type == ITT_CLOSE_WEAPON)	//近战武器{	bool reach = distance < 3.3;r = RandomRange(0, 100, true, false);if(reach && r > (mode == AAM_CHASE ? 43 : 45) || r > (mode == AAM_FLEE ? 86 : 97))PlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE));	//checking is inside}else if (type == ITT_PROP)	//道具{if (ptype == ITPT_PUT)	//放置类{if (id == 33)	//地雷{int prob = 5;if (distance < 6.0){if (mode == AAM_FLEE){	//逃亡中布地雷对方很容易中招prob = 40;}else if (mode == AAM_CHASE){	//追的时候就不一定了prob = 12;}else if (mode == AAM_STILL){	//判断对手是否朝自己方向来bool come = false;int delta_x, delta_y;DIR eface = GetPlayerFace(target_index);delta_x = ex - x;delta_y = ey - y;if (delta_x > 0 && eface == LEFT|| delta_x < 0 && eface == RIGHT|| delta_y > 0 && eface == UP|| delta_y < 0 && eface == DOWN)come = true;prob = (come?76:33);}}else {prob = 11;}r = RandomRange(0, 100, true, false);if (r < prob){	//布地雷PlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE));	//checking is inside}}else {//<!>other PUTs...}}else if (ptype == ITPT_POTION)	//药水类,好的药水{r = RandomRange(0, 100, true, false);float t = AA_DRINK_POTION_RATE;	//概率if (id >= 71 && id <= 73){if (GetPlayerHp(my_index) < GetPlayerMaxHp(my_index) * 0.10)t *= 5.0;else if (GetPlayerHp(my_index) < GetPlayerMaxHp(my_index) * 0.25)t *= 3.0;else if (GetPlayerHp(my_index) < GetPlayerMaxHp(my_index) * 0.45)t *= 1.6;}if (r < t){	//喝药水
//					p[GetI()].TryToAttack(GetI(), (g_bIdt != IDT_OFFLINE));PlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE));}}else {//other ITPTs...}}else {return;}EXCEPTION_R_TITLED("BOP AIControl::Attack EXCEPTION")}
};
//AIControl g_aic;
AIControl& GetPlayerAI(int index);

大致就包括自动移动、攻击、躲闪、喝药、埋地雷等,特别是那个躲闪很有意思,经验值越高躲闪越容易成功。
以后打算搞个游击模式算法。。等更新吧

下载: https://download.csdn.net/download/cjz2005/86287023

喜欢的朋友别忘了点赞关注!!


http://www.ppmy.cn/news/140653.html

相关文章

玩编程,玩游戏

1.coding Games 2.codecombat 3.screeps 4.checkio 5.vim Adventures 6.cgber dojo 7.code Monkey 8.Elevator saga 9.codewars 10.codewars 11.ruby quiz 12.git-Game 13.Hacker.org 14.code hunt 15.Fight code

c语言之玩游戏

1 二分查找/折半查找 2 密码登录 int main() { int i 0; char password[20] ""; // 假设密码是"123456" for (i 0; i < 3; i) { printf("请输入密码&#xff1a;>"); scanf("%s", passwo…

CPO技术重塑光模块:行业变革与突破

随着OpenAI的ChatGPT重磅面世&#xff0c;在短短时间内&#xff0c;内容生成式人工智能消费级应用掀起一波新的科技浪潮。ChatGPT用户数也在短短两个月内破亿,成为史上活跃用户破亿速度最快的软件。 可以预料的是,未来算力和数据需求将迎来爆发式的增长,且传统可插拔光模块技术…

C++小游戏---坦克大战(一)

刚开始写的时候想想这个应该是非常好写的&#xff0c;但是写到后面&#xff0c;尤其是遇到很多莫名其妙的bug之后&#xff0c;发现似乎没那么简单。以下是开发过程中的一些想法&#xff0c;在这里做个笔记。 目录 游戏介绍 素材引入 初始化 全局初始化 关卡初始化 初始化效果 对…

[UOJ299][CTSC2017] 游戏

【CTSC2017】游戏 problem UOJ299 solution 定义 X i : X_i: Xi​: 当前已知条件第 i i i 局的状态 1 / 0 1/0 1/0&#xff08;胜/败&#xff09;。 将 X i C i X_iC_i Xi​Ci​ 记为事件 A i A_i Ai​。 假设现在已知条件共有 s s s 个&#xff0c;即&#xff1a…

零基础学会用Airtest-Selenium对Firefox进行自动化测试

1. 前言 本文将详细介绍如何使用AirtestIDE驱动Firefox测试&#xff0c;以及脱离AirtestIDE怎么驱动Firefox&#xff08;VScode为例&#xff09;。 看完本文零基础小白也能学会Firefox浏览器自动化测试&#xff01;&#xff01;&#xff01; 2. 如何使用AirtestIDE驱动Firef…

电脑mp3转换器哪个好用?我来告诉你电脑mp3转换器哪个好

假如你下载了一些音乐或者录音文件&#xff0c;但是它们可能不是mp3格式的&#xff0c;而是其他格式&#xff0c;如wav、flac等。而有一些设备又只能播放mp3格式的音频&#xff0c;这时候就需要使用mp3转换器将其转换成mp3格式&#xff0c;以便于在各种设备上播放和分享。不过你…

风险投资成功案例分析_著名的风投成功案例

风险投资成功案例分析1 转换科技公司(Transition Technology Inc.以下简称TTI)在1987年初开始寻求风险资本&#xff0c;直到212天后终于获得了3i风险投资公司(以下简称3i)等提供的300万美元风险资本。这是一个比较常规的风险投资过程&#xff0c;但其中的曲折历程也颇耐人…