我正在为一个嵌入式ARM微控制器编写一个乒乓球游戏(该板是Keil MCBSTM32C,对于任何感兴趣的人),我现在正在尝试实现AI。基本功能相当简单,因为我只是简单地将玩家2控制器的位置映射到球的位置。然而,这显然不是理想的,因为我希望AI犯错,这样玩家才能获胜。
所以,我试图在AI运动中实现随机量的错误。然而,AI桨现在在屏幕周围“抖动”很多,抖动量大于误差量。我想了解为什么会发生这种情况(这是因为每次重绘桨的时候随机化难度偏移都会改变),但我不完全确定如何修复它。我试图让它朝着球的方向移动,而不是直接映射到球上,但这似乎没有多大帮助。
绘制播放器拨片的代码是:
void draw_player2(enum pMode mode) {
int adcValue;
static int lastValue = 0;
int direction;
switch (mode)
{
default:
break;
case DUAL:
adcValue = (ADC1->DR & 0x0FFF) >> 4; /* AD value (8 bit) */
if (lastValue != adcValue) {
thisGame.p2.y = (unsigned int) adcValue * (HEIGHT-BAR_H)/256;
LCDupdatePaddle(thisGame.p2);
lastValue = adcValue;
}
break;
case AI:
direction = thisGame.ball.y-lastValue;
adcValue = thisGame.ball.y; /* AD value (8 bit) */
if (lastValue != adcValue) {
thisGame.p2.y = (lastValue + direction + selectDiffMod()) * (HEIGHT-BAR_H)/256;
LCDupdatePaddle(thisGame.p2);
lastValue = adcValue;
}
break;
}
}
(HEIGHT = 240且BAR_H = 48,顺便说一句)
selectDiffMod()的代码是:
int selectDiffMod() {
int r;
if(thisGame.delay == T_SLOW) {
r = rand() % 100;
}
if(thisGame.delay == T_MEDIUM) {
r = rand() % 50;
}
if(thisGame.delay == T_FAST) {
r = rand() % 20;
}
return r;
}
我目前的想法是不经常生成难度修改器/偏移量,但我不确定这实际上会解决它,我想知道是否有人有更好的解决方案?
答案 0 :(得分:1)
我会通过为玩家2划分一个它可以移动的速度来做到这一点。在低难度下,它会变慢。根据需要,可以在其上添加较小的随机波动。它看起来像(未经过测试,根据您的具体情况需要进行修改):
int get_new_value_ai (const int currentValue, const int ballY)
{
int direction;
int speed = 2;
int newValue;
//basic sign calc: -1, 0, 1
direction = (currentValue < ballY) - (ballY < currentValue);
//Adjust speeds as needed
if (thisGame.delay == T_SLOW)
speed = 1;
else if (thisGame.delay == T_MEDIUM)
speed = 2;
else if (thisGame.delay == T_FAST)
speed = 3;
if (abs(currentValue - ballY) < speed) //Prevent overshooting
newValue = ballY;
else
newValue = currentValue + direction * speed;
newValue += (rand() % 3) - 2; //Random mod of -1, 0, +1
return newValue;
}
并将其命名为:
thisGame.p2.y = get_new_value_ai(thisGame.p2.y, thisGame.ball.y);
除此之外,当桨叶改变方向时,通过引入加速度/动量可以使它变得更加复杂。