一旦初始化电路板,程序就应该请求用户配置,然后使用用户配置打印电路板。然后它打印"W"one_answers"B’。最后一步是从已使用的中请求移动,如果它与之前打印的可用移动相匹配,则它会打印移动有效的消息,然后使用有效移动最后一次打印电路板。在打印配置好的板之前,我的代码运行良好,但在那之后,我在这里得到了一些奇怪的输出。请帮忙,谢谢。在以下程序中,输入的形式应该是:U-未被占用,B-被黑色占用,W-被白色占用。这是一个示例输入和预期输出:示例
#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%cn",(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;
}
}
}
好的,这里有另一个变化,应该可以解决几个问题。在搜索可用的移动时,你要检查棋盘上是否有已经有玩家棋子的方块,然后你要向各个方向看是否有移动。这与通常的做法相反,也会造成问题(重复移动)。
例如,假设你正在为玩家X寻找移动,棋盘看起来像:
*OOOX
O
X
我用*
标记了这个有趣的空缺职位。正如你所看到的,这个位置是双重移动,因为合法捕获存在于同一位置的两个不同方向。
你目前的做法会列出两次这一举措。它会首先从X位置中的一个开始找到它,然后当它遇到第二个X位置时会再次找到它。
我们可以通过一个简单的修复程序来修复这个错误,并解决您的移动顺序问题,这实际上可能会简化您的程序。
目前,你会检查棋盘上的每个方块,看看它是否是玩家的颜色。如果是,那么你会寻找对手颜色的相邻跑动,以一个空正方形结束,然后这被认为是合法的移动。
相反,你应该颠倒这一点:检查板上的每个方块,看看它是否是空的。如果是,那么寻找对手颜色的相邻跑动,以你的颜色的正方形结束。如果你找到了,那么起始方块(空方块)就变成了你的移动。
这个更改实际上非常简单,它解决了两件事:(1)您将不再发现重复的移动(如上面的示例),以及(2)移动将按顺序打印。
编辑:我应该补充一点,一旦你找到一个移动并打印出来,你应该立即移动到下一个空方块。否则,如果你一直往其他方向看,你可能会发现重复的。一个很好的方法是将它分解为两个函数。第一个只是在所有正方形(行、列)上迭代,并调用第二个来检查是否有合法的移动。第二个检查是否合法。如果它找到一个,它会立即停止寻找并返回。
好的,这里有一个简单的观察结果。看起来您更改了checkLegalMovesAvailable
,所以它现在总是返回true
,对吗?所以这里有一个问题要问你:这有意义吗?如果是这样,那么也许它根本不应该返回任何内容,并且它的调用者应该始终将其视为返回了true
。如果没有,那么也许您应该重新思考您的逻辑,并弄清楚在什么情况下它应该返回true
和false
。这有道理吗?
好的,这里还有一些修复程序:
(1) 在positionInBounds
中,您正在检查p<=N
和q<=N
。我认为这些支票应该是p<N
和q<N
,对吧?所以它们都在0…(N-1)的范围内。
(2) 在checkLegalMovesAvailable
中,如果deltaRow
和deltaCol
都为0,则应跳过对checkLegalInDirection
的调用。9种组合中只有8种是有效的。
(3) 在checkLegalMovesAvailable
中,检查所需方向上的第一个正方形是否在边界内。但在checkLegalInDirection
中,你会朝着同一个方向看得越来越远,而不会检查自己是否仍在边界内。我怀疑这造成了你所看到的一些真正的问题。
(4) 在checkLegalInDirection
中,只要正方形不是空的或你的颜色,也就是说,只要是你对手的颜色,你就一直朝那个方向看。这很好,但最后,你需要检查最后的正方形是空的,而不是你自己的颜色。那张支票不见了。
看看你是否能在这些修复上取得一些进展。这应该会让你忙一段时间。如果你在那之后仍然有问题,我也许可以再看一次。