程序初始化电路板后应询问用户配置,然后使用用户配置打印电路板。然后它会打印“W' W' &安培; ' B'因此。最后一步是要求从已使用的移动,如果它与打印的可用移动匹配,然后它打印移动的消息有效,然后它使用有效移动最后一次打印板。我的代码工作正常,直到它打印配置的板,但在那之后我得到一些奇怪的输出。请帮忙,谢谢。 在下面的程序中,输入应该是以下形式:U-未占用,B-由黑色占用,W占用白色。这是一个示例输入和预期输出:Example
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void boardInitialize(char board[26][26], int n);
void printBoard(char board[26][26], int n);
void checkLegalMovesAvailable(char board[26][26], int N, char colour);
bool positionInBounds(int N, char row, char col);
void printMove(char board[26][26], int n);
void checkLegalInDirection(char board[26][26],int N,char row,char col,char colour,int deltaRow,int deltaCol);
bool checkLegalInMove(char board[26][26], int N, char row, char col, char colour);
int main(void){
int n;
char board[26][26];
printf("Enter the board dimension: ");
scanf("%d",&n);
boardInitialize(board,n);
printBoard(board,n);
checkLegalMovesAvailable(board,n,'W');
checkLegalMovesAvailable(board,n,'B');
printMove(board,n);
return (EXIT_SUCCESS);
}
//Function to initialize board
void boardInitialize(char board[26][26], int n){
printf(" ");
for(int i=0;i<n;i++){
printf("%c",97+i);
}
printf("\n");
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
board[i][j]='U';
}
}
board[(n/2)-1][(n/2)-1]='W';
board[n/2][n/2]='W';
board[(n/2)-1][n/2]='B';
board[n/2][(n/2)-1]='B';
for(int i=0;i<n;i++){
printf("%c ",97+i);
for(int j=0;j<n;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
}
//Function to print board after configuration
void printBoard(char board[26][26], int n){
printf("Enter board configuration:");
printf("\n");
char color,row,col;
for(int i=0;(color!='!' && row!='!' && col!='!');i++){
scanf(" %c%c%c",&color,&row,&col);
board[row-'a'][col-'a']=color;
}
printf(" ");
for(int i=0;i<n;i++){
printf("%c",97+i);
}
printf("\n");
for(int i=0;i<n;i++){
printf("%c ",97+i);
for(int j=0;j<n;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
}
//function to print available moves after configuration
void checkLegalMovesAvailable(char board[26][26], int N, char colour){
printf("Available moves for %c:\n",colour);
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(board[i][j]==colour){
for(int deltaRow=-1;deltaRow<=1;deltaRow++){
for(int deltaCol=-1;deltaCol<=1;deltaCol++){
if(deltaRow==0 && deltaCol==0)
;
else
if(positionInBounds(N,('a'+i+deltaRow), ('a'+j+deltaCol)))
checkLegalInDirection(board,N,('a'+i+deltaRow),('a'+j+deltaCol),colour,deltaRow,deltaCol);
}
}
}
}
}
}
//function to check if any move is legal in a specific direction
void checkLegalInDirection(char board[26][26],int N,char row,char col,char colour,int deltaRow,int deltaCol){
int r=row-'a', c=col-'a',count=0;
while((positionInBounds(N,'a'+r+(count*deltaRow),'a'+c+(count*deltaCol))) && (board[r+(count*deltaRow)][c+(count*deltaCol)]!=colour) && (board[r+(count*deltaRow)][c+(count*deltaCol)]!='U')){
count++;
if((positionInBounds(N,'a'+r+(count*deltaRow),'a'+c+(count*deltaCol))) && (board[r+(count*deltaRow)][c+(count*deltaCol)]=='U')){
printf("%c%c\n",(row+(count*deltaRow)),(col+(count*deltaCol)));
break;
}
}
}
//function to check if the specified row,col lies within the board dimensions
bool positionInBounds(int N, char row, char col){
int p=row-'a',q=col-'a';
if(p>=0 && q>=0 && p<N && q<N)
return true;
else
return false;
}
//function to print board after a legal move
void printMove(char board[26][26], int n){
char color,row,col,temp;
printf("Enter a move:\n");
scanf(" %c%c%c",&color,&row,&col);
temp=board[row-'a'][col-'a'];
board[row-'a'][col-'a']=color;
if(checkLegalInMove(board,n,row,col,color)){
printf(" ");
for(int i=0;i<n;i++){
printf("%c",97+i);
}
printf("\n");
for(int i=0;i<n;i++){
printf("%c ",97+i);
for(int j=0;j<n;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
}
else{
board[row-'a'][col-'a']=temp;
printf(" ");
for(int i=0;i<n;i++){
printf("%c",97+i);
}
printf("\n");
for(int i=0;i<n;i++){
printf("%c ",97+i);
for(int j=0;j<n;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
}
}
//function to check if any specific move is legal
bool checkLegalInMove(char board[26][26], int N, char row, char col, char colour){
int r=row-'a',c=col-'a';
for(int deltaRow=-1;deltaRow<=1;deltaRow++){
for(int deltaCol=-1;deltaCol<=1;deltaCol++){
if(positionInBounds(N,row,col)){
checkLegalInDirection(board,N,('a'+r),('a'+c),colour,deltaRow,deltaCol);
printf("Valid move.\n");
return true;
}
else
printf("Invalid move.\n");
return false;
}
}
}
答案 0 :(得分:0)
好的,这是一个简单的观察。您似乎更改了checkLegalMovesAvailable
,现在它始终返回true
,对吗?所以这是一个问题:这有意义吗?如果是这样,那么也许它根本不应该返回任何内容,并且它的调用者应该总是将其视为返回true
。如果没有,那么也许你应该重新思考你的逻辑,并弄清楚它应该在哪些情况下返回true
与false
。这有意义吗?
答案 1 :(得分:0)
好的,这里还有一些修复方法:
(1)在positionInBounds
,您正在核对p<=N
和q<=N
。我相信这些支票应该是p<N
和q<N
,对吗?所以他们都在0 ...(N-1)范围内。
(2)在checkLegalMovesAvailable
中,如果checkLegalInDirection
和deltaRow
都为0,则应跳过对deltaCol
的调用.9种组合中只有8种有效。< / p>
(3)在checkLegalMovesAvailable
中,检查所需方向的第一个方格是否在边界内。但是在checkLegalInDirection
中,你继续朝着同一个方向寻找,而不是检查你是否仍在界限内。我怀疑这会引起你一直看到的一些实际问题。
(4)在checkLegalInDirection
中,只要广场不是空或你的颜色,你就会继续向那个方向看,即只要它是对手的颜色。这很好,但最后,你需要检查最后的方块是否为空,而不是你自己的颜色。那张支票丢失了。
看看您是否可以在这些修复方面取得一些进展。那会让你忙个不停。如果你之后仍然遇到问题,我可能会再次看一下。
答案 2 :(得分:0)
好的,这是你的另一个改变,它可以解决几个问题。在搜索可用的移动时,您需要检查棋盘上是否有已经有玩家的棋子,然后您可以向所有方向查看,看看是否有移动方向。这是人们通常会这样做的倒退,也会导致问题(重复移动)。
例如,假设您正在寻找玩家X的移动,并且棋盘看起来像:
*OOOX
O
X
我用*
标记了有趣的开放位置。正如您所看到的那样,该位置是双重移动,因为合法捕获存在于同一位置的两个不同方向。
您当前的方法会将此举两次列出。它会首先从一个X位置开始,然后在遇到第二个X位置时再次找到它。
我们可以修复此错误,并通过简单的修复解决您的移动订购问题,这可能会简化您的程序。
目前,您检查棋盘上的每个方块,看它是否是玩家的颜色。如果是,那么你会寻找对手的颜色的相邻运行,由空方块终止,然后被认为是合法的移动。
相反,你应该反过来:检查棋盘上的每个方块,看它是否为空。如果是,则查找对手颜色的相邻运行,以您的颜色的正方形终止。如果你找到了,那么开始方(空的)将成为你的举动。
此更改实际上非常简单,它解决了两件事:(1)您将不再找到重复的动作(如上例所示),以及(2)动作将按顺序打印。
编辑:我应该补充一点,一旦你找到一个移动并打印它,你应该立即移动到下一个空方块。否则,如果您继续寻找其他方向,您可能会发现重复。这样做的好方法是将其分解为两个函数。第一个只是迭代所有方(行,列),并调用第二个来检查那里是否有合法的移动。第二个检查合法移动。如果找到一个,它会立即停止查看并返回。