好吧,我正试图在游戏中做一个简单的洪水。这样的事情: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);
}
总而言之,我很难过......
答案 0 :(得分:0)
Moldinbo是正确的!!!!!!因为我是堆叠交换的新手,所以我不知道如何选择他的答案是最好的。
无论如何,谢谢你。
我不得不在这里使用递归,因为我需要在遍历棋盘时保留i和j的先前位置。