2

所以,我正在创建一个程序来创建一个(某种)模拟近战死亡竞赛视频游戏(目前实际上不是制作视频游戏,只是制作简单的人工智能,目标是互相杀死)。为了做到这一点,我使用了基于图块的回合制系统。

现在介绍已经结束,这里是具体问题:在我使用的一个数组中,最后一个值错误地存储在 RAM 中,无论数组中有多少变量。以下是相关代码:

(我将在底部发布我拥有的所有代码,但问题出在此处)

#include "stdafx.h"
#include <iostream>


int _tmain(int argc, _TCHAR* argv[])
{
    using namespace std;


    int npcTileAttacker[] = { 0, 0, 0, 0, 0};

    int s = 0;
    while (s < 6)
    {
        cout << "The value that is being selected from the array is " << s << endl;
        cout << npcTileAttacker[s] << endl;
        s++;
        cout << "The value of s has now been set to " << s << endl;
    }

这输出:

The value that is being selected from the array is 0
0
The value of s has now been set to 1
The value that is being selected from the array is 1
0
The value of s has now been set to 2
The value that is being selected from the array is 2
0
The value of s has now been set to 3
The value that is being selected from the array is 3
0
The value of s has now been set to 4
The value that is being selected from the array is 4
0
The value of s has now been set to 5
The value that is being selected from the array is 5
-858993640
The value of s has now been set to 6

显然,数组中的最后一个值是不正确的。我想知道的是为什么会发生这种情况。除此之外,当程序结束时,我收到一条错误消息:“运行时检查失败 #2 - 变量 'npcTileAttacker' 周围的堆栈已损坏。”

我尝试将 s 的输出值和数组代码段放置在程序中的其他数组周围,导致出现同样的问题。

如果需要,这是我的完整代码:

#include "stdafx.h"
#include <iostream>


int _tmain(int argc, _TCHAR* argv[])
{
    using namespace std;

int numberOfNPCs = 5;

//Remember whose alive (so we can skip the dead's turns)
int npcAlive[5] = { 1, 1, 1, 1, 1 };


/*This determines what action is going to be carried out on this square. For the moment:
if npcTileActivity[n] = 1;
the goals is death

WARNING! THIS WILL RESULT IN BUGS!!! I need to figure out a way that allows multiple activities on a tile 
(maybe apply actions onto NPCs directly, rather than onto their tiles)
*/
int npcTileActivity[] = { 0, 0, 0, 0, 0};



//This tells you who is doing the action on this tile
int npcTileAttacker[5] = { 1, 2, 3, 4, 0 };

    int s = 0;
while (s < 6)
{
    cout << "The value that is being selected from the array is " << s << endl;
    cout << npcTileAttacker[s] << endl;
    s++;
    cout << "The value of s has now been set to " << s << endl;
}
//This determines whether or not the NPC will fight back. Currently pointless, as this will just kill them.
int npcPacifism[5] = { 0 };



//This is their HP
int npcDefense[5] = {5, 5, 5, 5, 5};



//This is the default damage (presumably this is done with knives)
int npcOffense[5] = {1, 1, 1, 1, 1};



/*This determines what each NPC wants to do.
1   -   Kill Target
*/
int npcGoal[5] = {1, 1, 1, 1, 1};


//This is the NPC they are aiming at
int npcTarget[5] = {1, 2, 3, 4, 0};


/*The x coord for their target. In the future:
-I want this to be able to be changed during the sim
-This should be disabled until the NPC can find out where their target is
*/
int npcGoalLocationX[5] = {4, 1, 4, 3, 1};


/* The Y coord for their target
*/
int npcGoalLocationY[5] = {2, 3, 4, 2, 1};


/*Their x coord.
This will change, then the all npcGoalLocations need to be updated
*/
int npcLocationX[5] = {1, 4, 1, 4, 3};


/* Their y coord.
*/
int npcLocationY[5] = {1, 2, 3, 4, 2};

int m = 1;
while (m != 0)
{

    int i = 0;

    //Loop until every npc has had a turn
    while (i < (numberOfNPCs + 1))
    {
        /*npcGoalLocationY[i] = npcLocationY[npcTarget[i]];
        npcGoalLocationY[i] = npcLocationY[npcTarget[i]];*/
        if (npcAlive[i] = 1)
        {
            /* Tile activities:
            1 - Kill occupant
            */ 
            if (npcTileActivity[i] = 1)
            {
                cout << "This shouldn't be the first thing." << endl;

                //This gets the attack and defense values for the appropriate acting NPC
                int j = 0;
                while (j < (numberOfNPCs + 1))
                {

                    if (npcTileAttacker[i] = j)
                    {
                        //Defender's HP - Attacker's damage
                        int rollAttack1 = npcDefense[i] - npcOffense[j];
                        if (rollAttack1 > 0)
                            {
                            npcDefense[i] = rollAttack1;
                            cout << "NPC " << j << " attacks NPC " << i << endl;
                            if (npcPacifism[i] = 0)
                            {
                                //Defender retaliates
                                int rollAttack2 = npcDefense[j] - npcOffense[i];
                                if (rollAttack2 > 0)
                                {
                                    npcDefense[j] = rollAttack2;
                                    cout << "NPC " << i << " retaliates" << endl;
                                }else
                                {
                                    npcAlive[j] = 0;
                                    cout << "NPC " << j << " dies" << endl;
                                }
                            }
                        }else
                        {
                            npcAlive[i] = 0;
                            cout << "NPC " << i << " dies" << endl;
                        }
                    }
                    j++;
                }
            }else
            {
                cout << "This should be the first." << endl;
                if (npcGoal[i] != 0)
                {
                    if (npcGoalLocationX[i] = npcLocationX[i])
                    {
                        if (npcGoalLocationY[i] = npcLocationY[i])
                        {
                            //The Tile Activity of the current NPC's target is set to whatever the current NPC's goal is
                            npcTileActivity[npcTarget[i]] = npcGoal[i];
                        }
                    }
                    if (npcGoalLocationX[i] > npcLocationX[i])
                    {
                        npcLocationX[i]++;
                    }
                    if (npcGoalLocationX[i] < npcLocationX[i])
                    {
                        npcLocationX[i]--;
                    }
                    if (npcGoalLocationY[i] > npcLocationY[i])
                    {
                        npcLocationY[i]++;
                    }
                    if (npcGoalLocationY[i] < npcLocationY[i])
                    {
                        npcLocationY[i]--;
                    }
                }
            }
        }
        i++;
    }
    cin >> m;
}
return 0;
}

另外,我遇​​到了一个问题(围绕“这应该是第一件事”和“这不应该是第一件事”的行):不应该是第一个的是第一个,应该是第一个甚至永远不会执行。然而,这可能与数组错误有关。

感谢你的协助。

4

4 回答 4

3

你的条件差了一个:

while (s < 6)  

应该

while (s < 5)

该数组{ 0, 0, 0, 0, 0}有五个元素,因此有效索引为0,1,2,3,4.

s < 6你的条件在is时停止false,所以它仍然是 true for s == 5

于 2012-10-26T08:41:54.457 回答
1

您在 while 循环表达式中以 1 的优势出局。

最好使用 for 循环而不是硬编码数组的长度。尝试这样的事情:

int npcTileAttacker[] = { 0, 0, 0, 0, 0};
int npcTileAttackerLength = sizeof(npcTileAttacker)/sizeof(npcTileAttacker[0]);

for(int s=0; s<npcTileAttackerLength; s++)
{
    cout << "The value that is being selected from the array is " << s << endl;
    cout << npcTileAttacker[s] << endl;
}

这样,长度变量将始终保存数组中的项目数。

于 2012-10-26T08:46:51.430 回答
1

您的数组只有 5 个单元格:

int npcTileAttacker[] = { 0, 0, 0, 0, 0};

也就是说,s应该从 0 到 4,而不是从 0 到 5。

您看到的“随机”值实际上是npcTileAttacker数组后堆栈上的任何值,因为您正在溢出该数组。

于 2012-10-26T08:42:22.610 回答
1

数组的大小为 5。因此有效索引为 0-4。因此,npcTileAttacker[5] 将始终发布垃圾。

于 2012-10-26T08:44:40.317 回答