0

I am attempting to write a text based Othello engine in C as a way of starting to learn C. I have already got this working in higher level languages so have decided to give it a go in C as the basic logic is correct and working.

I am trying to represent the board as an 8x8 array, which can be dynamically reset using a function.

The board should look like so:

* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * w b * * *
* * * b w * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *

I am trying to pass a pointer to the array storing the board into the resetBoard function so that I can reset the board at any time. How can I get the board to update the array with the corresponding characters?

This is what I am trying:

int resetBoard(char *board) {
    int i;
    int j;
    for (i = 0; i<8; i++) {
        for (j = 0; j<8; j++) {
            
            if ((i == 4 && j == 4) | (i == 5 && j == 5)) {
                board[i][j] = "w";
            } else if ((i == 5 && j == 4) | (i == 4 && j == 5)) {
                board[i][j] = "b";
            } else {
                board[i][j] = "*";
            }
        
        }
    }

    return 0;
}

void main() {
    char board[8][8];
    resetBoard(*board);

    for (int i = 0; i<8; i++) {
        for (int j = 0; j<8; j++) {
            char x = board[i][j];
            printf(" %c ", x);
        
        }
        printf("\n");
    }

}

And when I try to compile i get the following error message:

.\Othello.c: In function 'resetBoard':
.\Othello.c:10:25: error: subscripted value is neither array nor pointer nor vector
                 board[i][j] = "w";
                         ^
.\Othello.c:12:25: error: subscripted value is neither array nor pointer nor vector
                 board[i][j] = "b";
                         ^
.\Othello.c:14:25: error: subscripted value is neither array nor pointer nor vector
                 board[i][j] = "*";

I have tried just assigning the character to board[i] instead of board[i][j] however that provides this error:

.\Othello.c: In function 'resetBoard':
.\Othello.c:10:26: warning: assignment to 'char' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
                 board[i] = "w";
                          ^
.\Othello.c:12:26: warning: assignment to 'char' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
                 board[i] = "b";
                          ^
.\Othello.c:14:26: warning: assignment to 'char' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
                 board[i] = "*";

So I know I have multiple problems. I am completely new to C programming, or any low level programming for that matter so any help would be welcomed!

Many thanks!

  • `board` is a two-dimensional array, and therefore `int resetBoard(char *board)` should be `int resetBoard(char** board)` – Robert Harvey Feb 25 '21 at 16:52
  • @RobertHarvey That is incorrect. `char **` means a pointer to `char *` – M.M Feb 26 '21 at 03:56
  • 1
    @RobertHarvey: A 2D array is not a "1D array of pointers to 1D arrays". Sadly, in C, accesses use the same syntax for both cases (e.g. `x = array[y][z]`;` can be like `x = *(array + y*8 + z);` or like `temp = array[y]; x = temp[z];` depending on what `array` is) which creates lots of confusion. – Brendan Feb 26 '21 at 04:16

2 Answers2

1
  • Pass (the pointer to the first element of) the whole array board, not the first row.
  • The elements of each elements of board are char, so character constants like 'w' should be used instead of string literals "w".
int resetBoard(char board[][8]) { /* change argument type to accept the whole array */
    int i;
    int j;
    for (i = 0; i<8; i++) {
        for (j = 0; j<8; j++) {
            
            if ((i == 4 && j == 4) | (i == 5 && j == 5)) {
                board[i][j] = 'w'; /* use character constant */
            } else if ((i == 5 && j == 4) | (i == 4 && j == 5)) {
                board[i][j] = 'b'; /* use character constant */
            } else {
                board[i][j] = '*'; /* use character constant */
            }
        
        }
    }

    return 0;
}

void main() {
    char board[8][8];
    resetBoard(board); /* pass the whole array */

    for (int i = 0; i<8; i++) {
        for (int j = 0; j<8; j++) {
            char x = board[i][j];
            printf(" %c ", x);
        
        }
        printf("\n");
    }

}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • Thanks, I think I get it now... I had got confused about passing an array into a function - had assumed you had to actively pass the pointer to the array and not just the array... So you pass the variable name of the array into the function, but the function must accept an array like that? – Robert Soane Feb 25 '21 at 18:18
  • down voted as there are still several errors in the code – user3629249 Feb 26 '21 at 02:43
  • @user3629249: Stack Overflow's charter doesn't include fixing every error in someone's code. – Robert Harvey Feb 26 '21 at 15:08
0

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. eliminates 'magic' numbers
  4. appropriately vertically spaced for readability
  5. commented on each changed line as to the reason for the change.
  6. uses 'logical' OR rather than 'bit wise' OR
  7. uses one of the two valid signatures for 'main()'
  8. includes the (missing) #include for the header file that contains the prototype for printf()

And now, the proposed code:

// note vertical spacing for readability
#include <stdio.h>  // added for 'printf()'

// to give 'magic' numbers meaningful names
#define ROWS 8  
#define COLS 8  


// return type modified as nothing uses the returned value
void resetBoard(char board[ROWS][COLS]) // valid parameter, which compiler needs
{ 
    int i;
    int j;
    
    for (i = 0; i< ROWS; i++)   // ROWS rather than 'magic' number
    {
        for (j = 0; j< COLS; j++)  // COLS rather than 'magic' number
        { 
            
            if ((i == 4 && j == 4) || (i == 5 && j == 5)) // || for logical OR
            {
                board[i][j] = 'w';  // 'w' for a single char rather than array
            } 
            
            else if ((i == 5 && j == 4) || (i == 4 && j == 5))  // || for logical OR
            {
                board[i][j] = 'b';  // 'b' for a single char rather than an array
            }
            
            else  // these lines modified to follow axiom:
                  // only one statement per line and (at most) one variable declaration per statement
            {
                board[i][j] = '*';  // '*' for a single char rather than an array
            }
        
        }
    }
}


int main( void )   // valid C signature for 'main()'
{
    char board[ROWS][COLS];    // rather than 'magic' numbers
    resetBoard(board);         // since 'board[][]' is array, bare reference degrades to address of first byte of array

    for (int i = 0; i<ROWS; i++)   // use meaningful name rather than 'magic' number
    { 
        for (int j = 0; j<COLS; j++)  // use meaningful name rather than 'magic' number
        { 
            char x = board[i][j];
            printf(" %c ", x);
        
        }
        printf("\n");
    }
}

a run of the proposed code results in:

 *  *  *  *  *  *  *  * 
 *  *  *  *  *  *  *  * 
 *  *  *  *  *  *  *  * 
 *  *  *  *  *  *  *  * 
 *  *  *  *  w  b  *  * 
 *  *  *  *  b  w  *  * 
 *  *  *  *  *  *  *  * 
 *  *  *  *  *  *  *  * 

Note: the starting position is offset 1 too far down and 1 too far to the right. This is because in C, arrays start with 0, not 1

user3629249
  • 16,402
  • 1
  • 16
  • 17