Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在二维数组中沿有效方向搜索_C - Fatal编程技术网

C 在二维数组中沿有效方向搜索

C 在二维数组中沿有效方向搜索,c,C,我希望实现一个类似这样的板: UUUU UWBU UBWU UUUU or UUBU BWBU WBWU UUUU 合法移动的条件: 检查数组中的“U” 如果找到“U”,检查周围(8?)方向以找到“B”(我被困在如何保持在外圈边界内,即仅检查3个方向的角件) 如果找到“B”,则继续该方向,并在该方向为真时继续,直到找到“W”。如果找到“W”,则打印“U”的原始位置 编辑更新的代码 我已经查找了更多的资源,并更改了代码的逻辑,但是配置的电路板现在打印不正确,函数运行以打印一些移动,但不

我希望实现一个类似这样的板:

UUUU
UWBU
UBWU
UUUU

or 

UUBU
BWBU
WBWU
UUUU
合法移动的条件:

  • 检查数组中的“U”

  • 如果找到“U”,检查周围(8?)方向以找到“B”(我被困在如何保持在外圈边界内,即仅检查3个方向的角件)

  • 如果找到“B”,则继续该方向,并在该方向为真时继续,直到找到“W”。如果找到“W”,则打印“U”的原始位置

编辑更新的代码 我已经查找了更多的资源,并更改了代码的逻辑,但是配置的电路板现在打印不正确,函数运行以打印一些移动,但不是全部,我的逻辑是否有缺陷

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> 

void initializeBoard(char board[][26], int n){
  int i, j;
  for (i=0; i<n; i++){
    for (j=0; j<n; j++){
      board[i][j] = 'U'; 
    }
  }
  board[(n/2)-1][(n/2)-1] = 'W';
  board[(n/2)-1][n/2] = 'B';
  board[n/2][n/2] = 'W';
  board[n/2][(n/2)-1] = 'B';
  // prints alphabet 
  char rowletter[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  printf("  "); 
  int c; 
  for(c=0; c<n; c++){
    printf("%c", rowletter[c]);
  }
  printf("\n"); 
//prints board with alphabet
  int e=0; 
  int a, b;
  for (a=0; a<n; a++){
    printf("%c ", rowletter[e]);
    for (b=0; b<n; b++){
      printf("%c", board[a][b]); 
    }
    e++; 
    printf("\n"); 
  }
}

//prints board depending on what player inputs 
void configuredBoard(char playerBoard[][26], int n){
  char colour=0, row = 0, col = 0; 
  //player enters move for desired colour i.e Wba is white on row b column a 
  scanf("%c%c%c", &colour, &row, &col); 

  int i, j;
  for (i=0; i<n; i++){
    for (j=0; j<n; j++){
      playerBoard[i][j] = 'U'; 
    }
  }
  playerBoard[(n/2)-1][(n/2)-1] = 'W';
  playerBoard[(n/2)-1][n/2] = 'B';
  playerBoard[n/2][n/2] = 'W';
  playerBoard[n/2][(n/2)-1] = 'B';

  while(colour != '!'){
    row = (int)row-97;
    col = (int)col-97;
    playerBoard[row][col] = colour; 
    scanf(" %c%c%c", &colour, &row, &col);
  }

  // prints alphabet 
  char rowletter[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  printf("  "); 
  int c; 
  for(c=0; c<n; c++){
    printf("%c", rowletter[c]);
  }
  printf("\n"); 
//prints board with alphabet
  int e=0; 
  int a, b;
  for (a=0; a<n; a++){
    printf("%c ", rowletter[e]);
    for (b=0; b<n; b++){
      printf("%c", playerBoard[a][b]); 
    }
    e++; 
    printf("\n"); 
  }
}


bool checkLineMatch(char colour, int dr, int dc, int r, int c, char playerBoard[][26], int n){
  if(playerBoard[r][c] == colour){
    return true; 
  }
  if((r+dr < 0) || (r+dr > n)){
    return false;
  }
  if((c+dc <0 ) || (c+dc >n)){
    return false;
  }
  if (playerBoard[r][c] == 'U'){
    return false; 
  }
  checkLineMatch(colour, dr, dc, r+dr, c+dc, playerBoard, n); 
}

bool validMove(char colour, int dr, int dc, int r, int c, char playerBoard[][26], int n){
char oppositeColour;
  if(colour == 'B'){
    oppositeColour = 'W';
  }
  else if(colour == 'W'){
    oppositeColour = 'B'; 
  }

  if((r+dr < 0) || (r+dr > n)){
    return false;
  }
  if((c+dc <0 ) || (c+dc >n)){
    return false;
  }
  if(playerBoard[r+dr][c+dc] != oppositeColour){
    return false; 
  }
  if((r+dr+dr < 0) || (r+dr+dr > n)){
    return false;
  }
  if((c+dc+dc <0 ) || (c+dc+dc >n)){
    return false;
  }

  return checkLineMatch(colour, dr, dc, r+dr+dr, r+dc+dc, playerBoard, n);

}

void findAvailableMoves(char colour, char playerBoard[][26], int n){
  printf("Available Moves for %c: \n", colour);
  int i, j; 
  for (int i=0; i<n; i++){
    for (int j=0; j<n; j++){
      if (playerBoard[i][j] == 'U'){
        //nw is northwest, etc. 
          bool nw = validMove(colour, -1, -1, i, j, playerBoard, n);
          bool nn = validMove(colour, -1, 0, i, j, playerBoard, n);
          bool ne = validMove(colour, -1, 1, i, j, playerBoard, n);

          bool ww = validMove(colour, 0, -1, i, j, playerBoard, n);
          bool ee = validMove(colour, 0, 1, i, j, playerBoard, n);

          bool sw = validMove(colour, 1, -1, i, j, playerBoard, n);
          bool ss = validMove(colour, 1, 0, i, j, playerBoard, n);
          bool se = validMove(colour, 1, 1, i, j, playerBoard, n);

        // if direction is valid, 
        if (nw || nn || ne || ww || ee || sw || ss ||se){
          //is valid move

          printf("%c%c\n", (char)i+97, (char)j+97); //typecast to ascii
        }
      }
    }
  }
}



int main(void){
  int n; 
  char board[26][26];
  printf("Enter the board dimension: ");
  scanf("%d", &n);
  initializeBoard(board, n); 

  char playerBoard[26][26];
  printf("Enter board configuration: \n");
  configuredBoard(playerBoard, n); 

  findAvailableMoves('W', playerBoard, n); 
  findAvailableMoves('B', playerBoard, n);

  printf("Enter a move: "); 



}
#包括
#包括
#包括
无效初始化板(字符板[][26],内部n){
int i,j;
对于(i=0;i
我被困在如何保持在外环的范围内,即
检查角件的3个方向

基于此目标,检查邻居(如果存在),此功能应有助于:

bool checkNeighbours( int n, int row, int col ) {
    // set up directions for all the neighbor cells
    int dx[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
    int dy[8] = { 0, 1, 1, 1, 0, -1, -1, -1 }; 

    int x, y;
    for( int i=0; i<8; i++ ) {
        x = row + dx[i];
        y = col + dy[i];
        if( positionInBounds( n, x, y ) ) { // check if out of bounds
            if( playerBoard[x][y] == oppositeColor ) { // add legalibility condition
                return true;

                // I don't understand exactly what this legality means 
                // but here you can add up any logic you want
                // The idea is that here you can return either true or false based on your legality meaning
            }
        }
    }
}
bool checkneights(整数n、整数行、整数列){
//设置所有相邻单元的方向
int dx[8]={1,1,0,-1,-1,0,1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
int x,y;

对于(inti=0;i我已经修改了您的代码,并在代码注释中进行了解释

现在,它编译并匹配预期输出:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

/*
I have used this format of commenting
So that it does not conflict with your comments that are in // format
*/

/* Prefer 4 space indentation over 2 spaces, just a matter of taste */

/* It would have been better to have function prototypes to make the code more readable */

/* You are reusing this code many times, so I moved it to a function */
void displayBoard(char board[26][26], int n)
{
    /*
    // prints alphabet
    char rowletter[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    printf("  ");
    int c;
    for(c=0; c<n; c++){
        printf("%c", rowletter[c]);
    }
    printf("\n");
    A Better way:
    */
    char marker = 'a';
    printf("  ");
    for (int i = 0; i < n; ++i, ++marker)
        printf("%c", marker);
    printf("\n");

    /*
    //prints board with alphabet
    int e=0;
    int a, b;
    for (a=0; a<n; a++){
        printf("%c ", rowletter[e]);
        for (b=0; b<n; b++){
            printf("%c", board[a][b]);
        }
        e++;
        printf("\n");
    }
    A better way:
    */
    marker = 'a';
    for (int i = 0; i < n; ++i, ++marker)
    {
        printf("%c ", marker);
        for (int j = 0; j < n; ++j)
        {
            printf("%c", board[i][j]);
        }
        printf("\n");
    }
}

void initializeBoard(char board[][26], int n){
    int i, j;
    for (i=0; i<n; i++){
        for (j=0; j<n; j++){
            board[i][j] = 'U';
        }
    }
    board[(n/2)-1][(n/2)-1] = 'W';
    board[(n/2)-1][n/2] = 'B';
    board[n/2][n/2] = 'W';
    board[n/2][(n/2)-1] = 'B';

    /* INITIALIZE != DISPLAY
    // prints alphabet
    char rowletter[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    printf("  ");
    int c;
    for(c=0; c<n; c++){
        printf("%c", rowletter[c]);
    }
    printf("\n");
    //prints board with alphabet
    int e=0;
    int a, b;
    for (a=0; a<n; a++){
        printf("%c ", rowletter[e]);
        for (b=0; b<n; b++){
            printf("%c", board[a][b]);
        }
        e++;
        printf("\n");
    }
    */
}

/*
//prints board depending on what player inputs
NO, CONFIGURING != PRINTING
Each function should serve a specific purpose, not multiple purposes
You are violating the modular design and making your code less maintainable
*/
/*
// void configuredBoard(char playerBoard[][26], int n){
configured?
*/
void configureBoard(char playerBoard[][26], int n){
    char colour=0, row = 0, col = 0;

    /* Also have two ints for storing the coordinates of char input */
    int x, y;

    /*
    You are doing this inside the while loop
    //player enters move for desired colour i.e Wba is white on row b column a
    scanf("%c%c%c", &colour, &row, &col);
    */

    /*
    You have already done this in initializeBoard()
    int i, j;
    for (i=0; i<n; i++){
        for (j=0; j<n; j++){
            playerBoard[i][j] = 'U';
        }
    }
    playerBoard[(n/2)-1][(n/2)-1] = 'W';
    playerBoard[(n/2)-1][n/2] = 'B';
    playerBoard[n/2][n/2] = 'W';
    playerBoard[n/2][(n/2)-1] = 'B';
    */

    /* Make this an infinite loop and break it when the user enters "!!!"
       Otherwise, playerBoard[!][!] = '!' will happen at the end of the loop
    while(colour != '!'){/
    */
    while (true) {
        scanf(" %c%c%c", &colour, &row, &col);

        /* Check for "!!!" */
        if (colour == '!' && row == '!' && col == '!')
            break;

        /*
        Array subscript has type 'char'
        row = (int)row-97;
        col = (int)col-97;
        playerBoard[row][col] = colour;
        */
        x = row - 97;
        y = col - 97;
        playerBoard[x][y] = colour;
        /* Problem with the order of execution
        playerBoard[x][y] = colour;
        scanf(" %c%c%c", &colour, &row, &col);
        */
    }

    /* I guess, I don't have to repeat it again
    // prints alphabet
    char rowletter[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    printf("  ");
    int c;
    for(c=0; c<n; c++){
        printf("%c", rowletter[c]);
    }
    printf("\n");
    //prints board with alphabet
    int e=0;
    int a, b;
    for (a=0; a<n; a++){
    printf("%c ", rowletter[e]);
    for (b=0; b<n; b++){
        printf("%c", playerBoard[a][b]);
    }
    e++;
    printf("\n");
    }
    */
}

/*
x and y would have been a better choice over r and c in this function
Just a matter of convention:
    r and c are more like constants
    x and y are more like arbitrary constants
    i and j are more like variables
Your r and c are actually the (x, y) coordinates of the board here
*/

/*
I'm finding it hard to correct the following three functions because
I'm unable to understand the logic:
Unwanted recursion,
Control reaches the end of non-void function,
Ambiguous comparisons,
...
Though you tried to implement Alin's approach,
I'll make it clear
*/

/*
bool checkLineMatch(char colour, int dr, int dc, int r, int c, char playerBoard[][26], int n){
    if(playerBoard[r][c] == colour){
        return true;
    }
    if((r+dr < 0) || (r+dr > n)){
        return false;
    }
    if((c+dc <0 ) || (c+dc >n)){
        return false;
    }
    if (playerBoard[r][c] == 'U'){
        return false;
    }
    checkLineMatch(colour, dr, dc, r+dr, c+dc, playerBoard, n);
}

bool validMove(char colour, int dr, int dc, int r, int c, char playerBoard[][26], int n){
    char oppositeColour;
    if(colour == 'B'){
        oppositeColour = 'W';
    }
    else if(colour == 'W'){
        oppositeColour = 'B';
    }

    if((r+dr < 0) || (r+dr > n)){
        return false;
    }
    if((c+dc <0 ) || (c+dc >n)){
        return false;
    }
    if(playerBoard[r+dr][c+dc] != oppositeColour){
        return false;
    }
    if((r+dr+dr < 0) || (r+dr+dr > n)){
        return false;
    }
    if((c+dc+dc <0 ) || (c+dc+dc >n)){
        return false;
    }

    return checkLineMatch(colour, dr, dc, r+dr+dr, r+dc+dc, playerBoard, n);
}

void findAvailableMoves(char colour, char playerBoard[][26], int n){
    printf("Available Moves for %c: \n", colour);
    int i, j;
    for (int i=0; i<n; i++){
        for (int j=0; j<n; j++){
            if (playerBoard[i][j] == 'U'){
                //nw is northwest, etc.
                bool nw = validMove(colour, -1, -1, i, j, playerBoard, n);
                bool nn = validMove(colour, -1, 0, i, j, playerBoard, n);
                bool ne = validMove(colour, -1, 1, i, j, playerBoard, n);

                bool ww = validMove(colour, 0, -1, i, j, playerBoard, n);
                bool ee = validMove(colour, 0, 1, i, j, playerBoard, n);

                bool sw = validMove(colour, 1, -1, i, j, playerBoard, n);
                bool ss = validMove(colour, 1, 0, i, j, playerBoard, n);
                bool se = validMove(colour, 1, 1, i, j, playerBoard, n);

                // if direction is valid,
                if (nw || nn || ne || ww || ee || sw || ss ||se){
                    //is valid move

                    printf("%c%c\n", (char)i+97, (char)j+97); //typecast to ascii
                }
            }
        }
    }
}
*/

/* Bring back your old function */
bool positionInBounds(int n, int x, int y)
{
    return (x >= 0 && x < n && y >= 0 && y < n);
}

/* I've rewritten this function */
void findAvailableMoves(const char colour, const char board[][26], const int n)
{
    int x, y;
    const int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
    const int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};

    const char oppositeColour = colour == 'W' ? 'B' : 'W';

    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] == 'U')
            {
                for (int k = 0; k < 8; k++)
                {
                    x = i + dx[k];
                    y = j + dy[k];
                    while (positionInBounds(n, x, y) && board[x][y] == oppositeColour)
                    {
                        x += dx[k];
                        y += dy[k];
                        if (positionInBounds(n, x, y) && board[x][y] == colour)
                        {
                            printf("%c%c\n", (char)i + 97, (char)j + 97);
                            break;
                        }
                    }
                }
            }
        }
    }
}

int main(void){
    int n;
    char board[26][26];

    printf("Enter the board dimension: ");
    scanf("%d", &n);
    initializeBoard(board, n);

    /* Make a separate call to displayBoard instead of putting it inside initializeBoard */
    displayBoard(board, n);

    /* THIS TOOK A LOT OF TIME TO FIGURE OUT!
       Why are you having a different board here!?
    char playerBoard[26][26];
    */
    printf("Enter board configuration: \n");
    // configuredBoard(playerBoard, n);
    configureBoard(board, n);

    /* Make a separate call to displayBoard instead of putting it inside configureBoard */
    displayBoard(board, n);

    /* This would have been much cleaner if OOP was available */
    // findAvailableMoves('W', playerBoard, n);
    // findAvailableMoves('B', playerBoard, n);
    findAvailableMoves('W', board, n);
    findAvailableMoves('B', board, n);

    printf("Enter a move: ");
    /*
    There are still many issues regarding
    Formatting
    Algorithm efficiency
    Invalid input handling
    and much more...
        But, I hope that I've removed the 'errors'
    */
}

#包括
#包括
#包括
/*
我用过这种形式的评论
这样它就不会与//格式的注释冲突
*/
/*喜欢4格缩进而不是2格缩进,只是口味的问题*/
/*最好有函数原型,使代码更具可读性*/
/*您多次重复使用此代码,因此我将其移动到函数中*/
无效显示板(字符板[26][26],int n)
{
/*
//打印字母表
字符行字母[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
printf(“”);
INTC;

对于(c=0;对于dx-dy,cThumbs向上approach@ArdentCoder我已经实现了Alin建议的类似想法,如果你不介意的话,你现在可以看一下代码并给我一些建议吗?@kat好吧,不管怎样,这是一个无聊的假期,我将把这当作一个练习。评论不用于长时间的讨论;这段对话已经结束。