EXC_BAD_ACCESS(c ++)随机放置

时间:2015-04-07 12:56:30

标签: c++ recursion stack-overflow exc-bad-access

好吧,我正试图在游戏中做一个简单的洪水。这样的事情:http://floodit.appspot.com使用SFML。

我已经有了董事会,作为一名运营商,它运作良好。按下每个对应一种颜色的字母R,B,P,Y等,我可以改变电路板的颜色,直到我达到胜利状态。 我想要添加的是一个小型AI,用于检查电路板,以最少的移动数量解决它,并将该数字加上五个作为人类的上限。这将使游戏对玩家更有趣,因为每次游戏运行时棋盘都会有不同的上限。

但是,我有时会工作,有时我会在代码中的随机点获得EXC_BAD_ACCESS,几乎总是停在试图访问板阵列中特定部分的点上。但我确信这些部分存在,所以我怀疑这是因为Deallocation,还是指针被修改。它可能是一个堆栈溢出但我每次收到错误时只会递归大约100级。 我得到错误的部分通常在这些函数中的某个地方:

enum col // The colours of the squares
{
    Red,Green,Blue,Purple,Orange,Yellow,AI
};

enum dir // The directions that the function looks in once the player presses a colour
{
    stop,Up,Right,Down,Left
};

void move(int& i,int& j,dir x)
    {
    switch(x)
    {
        case Up:
            i--;
            break;
        case Right:
            j++;
            break;
        case Left:
            j--;
            break;
        case Down:
            i++;
            break;
        default: /*Do Nothing*/;
    }
}


dir get_direction(col board_colors[][size],int i,int j,col current)
{
    //If the coordinates of the surrounding squares are inside the board and greater than zero, check whether they are the same colour as the current square or not

    if((i - 1 > 0) && board_colors[i-1][j] == current)
        return Up;
    else if((j + 1 != size) && board_colors[i][j+1] == current)
        return Right;
    else if((i + 1 != size) && board_colors[i+1][j] == current)
        return Down;
    else if((j - 1 > 0) && board_colors[i][j-1] == current)
        return Left;
    else
        return stop;
}


void reset_temp_board(col temp[size][size])
{
    for(int i=0;i<size;i++)
        for(int j=0;j<size;j++)
            temp[i][j]=AI;
}


int get_land_mass(col temp[size][size])
{
    int mass=0;
    for(int i=0;i<size;i++)
        for(int j=0;j<size;j++)
            if(temp[i][j]!=AI)
                mass++;
    return mass;
}

void append_to_temp(col AIBoard[size][size],col temp[size][size],int i,int j,dir x, col current, int color_freq[6])
{
    move(i, j, x);

    temp[i][j]=current;
    AIBoard[i][j]=AI;

    x = get_direction(AIBoard, i, j, current);

    while(x != stop)
    {
        append_to_temp(AIBoard,temp, i, j, x, current,color_freq);
        x = get_direction(AIBoard, i, j, current);
    }
}


void scan_vicinity(col AIBoard[size][size],col mainColor,int i,int j,int color_freq[6])
{
    col temp_board[size][size];

    reset_temp_board(temp_board);

    if(i-1>0 && (AIBoard[i-1][j]!=mainColor) && (AIBoard[i-1][j]!=AI))
    {
        col current=AIBoard[i-1][j];
        append_to_temp(AIBoard, temp_board, i-1, j, stop, current, color_freq);
        color_freq[current]+=get_land_mass(temp_board);
        reset_temp_board(temp_board);
    }

    if(j+1>0 && (AIBoard[i][j+1]!=mainColor) && (AIBoard[i][j+1]!=AI))
    {
        col current=AIBoard[i][j+1];
        append_to_temp(AIBoard, temp_board, i, j+1, stop, current, color_freq);
        color_freq[(int)current]+=get_land_mass(temp_board);
        reset_temp_board(temp_board);
    }

    if(i+1>0 && (AIBoard[i+1][j]!=mainColor) && (AIBoard[i+1][j]!=AI))
    {
        col current=AIBoard[i+1][j];
        append_to_temp(AIBoard, temp_board, i+1, j, stop, current, color_freq);
        color_freq[(int)current]+=get_land_mass(temp_board);
        reset_temp_board(temp_board);
    }

    if(j-1>0 && (AIBoard[i][j-1]!=mainColor) && (AIBoard[i][j-1]!=AI))
    {
        col current=AIBoard[i][j-1];
        append_to_temp(AIBoard, temp_board, i, j-1, stop, current, color_freq);
        color_freq[(int)current]+=get_land_mass(temp_board);
        reset_temp_board(temp_board);
    }


}

void start_analysis(col AIB[size][size], int i, int j, dir x, col current, int color_freq[6])
{
    move(i, j, x); //Moves cursor

    AIB[i][j]=AI;

    scan_vicinity(AIB,current,i,j,color_freq);

    x = get_direction(AIB, i, j, current); //Gets the next direction

    while(x != stop)
    {
        start_analysis(AIB, i, j, x, current,color_freq); //Next turn

        x = get_direction(AIB, i, j, current); //Next direction to check
    }
}

col analyse_board(col AI[size][size]) //returns best choice of color
{
    int color_freq[6]={0,0,0,0,0,0};
    start_analysis(AI, 0, 0, stop, AI[0][0],color_freq);
    return (col)maxIndex(color_freq);
}

AI工作的方式是它移动到我当前控制的区域,它扫描每个块的极值(向上,向下,向左,向右)并确定它们是否附着到其他不同颜色的块上。从不同颜色的块开始,它开始穿过小块并在临时板中复制它们的位置,该临时板用于确定与该起始块相关联的块的数量。因此,它确定了任何特定颜色的块总数,附加到我控制的区域的极端。 然后,它在color_freq数组中找到索引(这恰好是实际颜色),该索引具有获得的最大块数。

有时,代码也会在flood_it函数中的随机点停止 这是功能:

void set_color(col board_colors[][size],RectangleShape board[][size],int i,int j,col New)
{
    Color PURPLE(128,0,128);
    Color ORANGE(255,165,0);
    board_colors[i][j]= New;
    switch(New) //Sets the colour of the rest of the squares to be the same as the new one
    {
        case Red:
            board[i][j].setFillColor(Color::Red);
            break;
        case Green:
            board[i][j].setFillColor(Color::Green);
            break;
        case Blue:
            board[i][j].setFillColor(Color::Blue);
            break;
        case Purple:
            board[i][j].setFillColor(PURPLE);
            break;
        case Orange:
            board[i][j].setFillColor(ORANGE);
            break;
        case Yellow:
            board[i][j].setFillColor(Color::Yellow);
            break;
        default:;
    }
}

dir get_direction(col board_colors[][size],int i,int j,col current)
{
    //If the coordinates of the surrounding squares are inside the board and greater than zero, check whether they are the same colour as the current square or not

    if((i - 1 > 0) && board_colors[i-1][j] == current)
        return Up;
    else if((j + 1 != size) && board_colors[i][j+1] == current)
        return Right;
    else if((i + 1 != size) && board_colors[i+1][j] == current)
        return Down;
    else if((j - 1 > 0) && board_colors[i][j-1] == current)
        return Left;
    else
        return stop;
}

void move(int& i,int& j,dir x)
{
    switch(x)
    {
        case Up:
            i--;
            break;
        case Right:
            j++;
            break;
        case Left:
            j--;
            break;
        case Down:
            i++;
            break;
        default: /*Do Nothing*/;
    }
}

void start_traversing(RectangleShape board[size][size], col board_colors[][size], int i, int j, dir x, col current,col New)
{
    move(i, j, x); //Moves cursor

    set_color(board_colors, board, i, j, New); //Sets the colour

    x = get_direction(board_colors, i, j, current); //Gets the next direction

    while(x != stop)
    {
        start_traversing(board, board_colors, i, j, x, current, New); //Next turn

        x = get_direction(board_colors, i, j, current); //Next direction to check
    }
}
void flood_it(col board_colors[size][size],RectangleShape board[size][size], col New)
{
    if(WinCondition(board_colors) == 1) //Still more moves left
        start_traversing(board, board_colors,0,0,stop,board_colors[0][0], New);
}

总而言之,我很难过......

1 个答案:

答案 0 :(得分:0)

Moldinbo是正确的!!!!!!因为我是堆叠交换的新手,所以我不知道如何选择他的答案是最好的。

无论如何,谢谢你。

我不得不在这里使用递归,因为我需要在遍历棋盘时保留i和j的先前位置。