函数被执行多次,而被调用一次

Posted

技术标签:

【中文标题】函数被执行多次,而被调用一次【英文标题】:Function gets executed multiple times, while called once 【发布时间】:2017-12-09 09:12:53 【问题描述】:

我目前正在做一个学校项目,我们必须在 c++ 控制台应用程序中制作一个游戏。我目前在人工智能移动方面遇到了一些问题。因此,一旦玩家移动,机器人就可以移动。但由于某种原因,该函数被多次执行。

机器人移动的函数(monsterMove):

void playerMove() 
COORD playerCord =  playerX,playerY ; 
memset(map3, 0, sizeof(map3));
int c = 0;
switch ((c = _getch())) 
case KEY_UP:
    if (map[playerY-1][playerX] == ' ')
    
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), playerCord);
        cout << " ";
        map[playerY][playerX] = ' ';
        playerY--;
    
    break;
case KEY_DOWN:
    if (map[playerY + 1][playerX] == ' ')
    
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), playerCord);
        cout << " ";
        map[playerY][playerX] = ' ';
        playerY++;
    

    break;
case KEY_LEFT:
    if (map[playerY][playerX-1]== ' ')
    
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), playerCord);
        cout << " ";
        map[playerY][playerX] = ' ';
        playerX--;
    
    break;
case KEY_RIGHT:
    if (map[playerY][playerX + 1] == ' ')

    
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), playerCord);
        cout << " ";
        map[playerY][playerX] = ' ';
        playerX++;
    
    break;
default:
    break;

monsterMove(1);
map[playerY][playerX] = 157;
COORD playerCord2 =  playerX,playerY ;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), playerCord2);
cout << "I";

playerMove();

函数本身:

void monsterMove(int moves) 
map[monsterY][monsterX] = ' ';
int row[] =  -1, 0, 0, 1 ;
int col[] =  0, -1, 1, 0 ;
int toMove =BFS(map, playerX, playerY, monsterX, monsterY)-moves;

COORD monsterCoord2 =  monsterX,monsterY;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), monsterCoord2);
cout << ' ';
while (map3[monsterY][monsterX] != toMove)

    for (int k = 0; k < 4; k++)
    
        if ((map3[monsterY + col[k]][monsterX + row[k]] == map3[monsterY][monsterX] -1) && !( map3[monsterY][monsterX] == toMove))
        
            monsterX = monsterX+ row[k];
            monsterY =monsterY+ col[k]; 
        
    

COORD monsterCoord =  monsterX,monsterY ;
map[monsterY][monsterX] = 157;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), monsterCoord);
cout << 'M';

我已经设置了断点来看看到底发生了什么,以及'monsterMove();'这一行被执行多次。我真的不明白我做错了什么。

【问题讨论】:

离题(因为 fix-my-code 请求没有任何minimal reproducible example)。编译所有警告和调试信息:g++ -Wall -Wextra -g 和 GCC。改进代码以获得没有警告。 使用调试器gdb,或许可以逐步运行您的程序并了解发生了什么。 playerMove()的最后一条语句。它无条件地递归调用自己。这意味着在此之前代码中的所有其他内容(包括对monsterMove() 的调用)都将被执行多次。 是的,这就是重点,一旦你采取行动,机器人也会采取行动。但是在你有机会采取第二步之前,机器人需要 2,因为它被执行了多次。还是我错过了什么? 无条件递归不是实现目标的正确方法。使用某种循环而不是无条件递归。 你是如何输入的?我怀疑有一些额外的字符导致_getch() 不等待并多次调用您的函数而无需在每次上/下/左/右按键之间等待? 【参考方案1】:

您的代码的一个明显问题是您在playerMove() 中调用playerMove(),并且我可以从您粘贴的代码中看到到目前为止没有什么可以阻止递归。另外,我在代码中根本找不到您提到的MonsterMove(); 行,即使确实存在这样的行,您也缺少一个参数,甚至无法编译。

【讨论】:

暂时不应该停止。我仍在测试 AI 是否正常工作,我在函数中给出的参数是机器人可以进行的移动量。这部分工作正常,但我只是不明白为什么他要走 2-3 步才能提供另一个输入。 在您的问题中澄清它,而不仅仅是 cmets。 尽管无条件递归很糟糕并且将来可能会导致问题,但这显然不是 OP 问题的答案。并且 monsterMoveswitch 语句之后以正确的参数类型调用。你可能错过了那条线。 OP 声明MonsterMove(); 所以我确实检查了这一点。而且我不会与您争论进行这种文字检查是否合适,或者我应该猜测 OP 的含义。

以上是关于函数被执行多次,而被调用一次的主要内容,如果未能解决你的问题,请参考以下文章

UseEffect 被多次调用

setTimeout()和setInterval() 何时被调用执行(非多线程).RP

H2用户自定义函数被多次调用

Onmouseover被调用多次

Google Maps 的“map_changed”监听器内部调用的函数被多次调用

线程重复执行问题与线程池