How to change a dynamic 2d array from another func

I'm trying to create a dynamic 2d array to play chess with only 2 pieces: White King and Black queen.

The user inputs the size of the board and then I place the black queen on (2,0) and white king on (0,1).

I'm stuck with changing the position of the pieces. Whenever I try board2d[1][3] from another function, it gives me an error.Please see the "void change()" function and let me know how to properly user arr[4][4] = whiteking; to change the array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//David Chen
//Home Project 6
#include <iostream>

using namespace std;

void print_board(int *board2d, int Size) //spent 4 hours learning how to pass a 2d array from google.
{
  int k = 0;
    for (int i = 0; i < Size; i++)
    {
      for (int j = 0; j < Size; j++)
      {
      cout << board2d[k] << ' ';
      k++;
      }
    cout << '\n';
     }
}

void new_game(int *board2d, int Size)
{
  int k = 0;
    for (int i = 0; i < Size; i++)
     {
      for (int j = 0; j < Size; j++)
        {
        board2d[k] = 0;
        k++;
        }
     }

}

void change(int *board2d, int Size) // spent 2 hours figuring out how to change an array using pointers then found out I was doing the wrong thing!!
{
boarded[2][0] = 5;
}


int main() 
{
  const int wk = 1, //White King
            bq = 2; //Black Queen

  int Size; //Board Size

  cout << "Enter board size (one number for both length and width):";
  cin >> Size;
  while (Size <= 2)
  {
    cout << "Board size must be greater than 2, Re-enter board size: ";
    cin >> Size;
  }

  int board2d[Size][Size];
  new_game(*board2d,Size);


  change(*board2d,Size);
  board2d[0][1] = wk;
  board2d[2][0] = bq;
  print_board(*board2d,Size);

//for (int i = 0; i < Size; ++i)
  // delete [] board2d[i];
//delete [] board2d;
return 0;
}
Last edited on
int * is 1d.
int ** is 2d.

presumably a chessboard is 8x8 constant so

void foo(int **board)
{
board[3][4] = pawn;
}

it is possible to access board as 1d IF it was allocated as one block, as you did. But your syntax for that is not correct, you have to put the location in a single [] and manually find the correct index (desired row* # cols + desired col).
Last edited on
1
2
3
4
void change(int *board2d, int Size) // spent 2 hours figuring out how to change an array using pointers then found out I was doing the wrong thing!!
{
boarded[2][0] = 5;
}

What is boarded??

You have no dynamic arrays in your program. You have what are known as "VLAs" on line 56, which are illegal to do in C++, and error prone.

I would std::vectors. Apologies if this goes over your head, feel free to respond with questions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Example program
#include <iostream>
#include <vector>

// pass the board to a function
void change(std::vector<std::vector<int>>& board)
{
    board[2][0] = 5;
}

int main()
{
    int Size;
    std::cin >> Size;
    
    if (Size < 3) { /* error handling */ }
    
    // Create a 2D vector (vector of vectors, each of Size size)
    std::vector<std::vector<int>> board( Size, std::vector<int>(Size) );
    
    change(board);  
}


Last edited on
Unfortunately, my professor specifically asked for a 2d dynamic array to be used and that the user inputs the board size.

I tried using ** in the function, but it doesn't work. I'm not allowed to use vectors.

Here is the assignment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Your program simulates some sort of chess.

 

    First, your program asks user for an integer Board_Size greater than 2. This integer is the size of the chessboard. I deliberately move from the fixed chessboard size of 8 to enforce dynamic memory allocation.
    You dynamically allocate a classic C-style 2D-array of size Board_Size x Board_Size. You “place” a white king and a black queen on it. White king is 1, black queen is 2 and empty square is 0.

Coordinates on the board are defined by the row number and column number. Create a structure for it similar to the Point structure from the assignment number 4. Initial position of the white king is (0,1). Initial position of black queen is (2,0) . For example, for the Board_Size=4 the initial board is a following 2D-array

 

0 0 0 0

2 0 0 0

0 0 0 0

0 1 0 0

 

    Program starts asking the user for a next kings position. If the move is legal you update the board (2D-array) correspondingly. If the suggested move is illegal you ask the user to choose another move. You keep asking for the legal move until the user suggests one.

Legal move is a move one square away from the current position in any direction to the square NOT ATTAKED by the black queen.

 

      Program starts asking the user for a next queens position. If the move is legal you update the board (2D-array) correspondingly. If the suggested move is illegal you ask the user to choose another move. You keep asking for the legal move until the user suggests one.

Legal move is a move any distance in any direction from the current position to the square NOT ATTAKED by the white king.

Then you go back to the step 3.

 

    During the steps 3 and 4 there is a special position (-1,-1). By itself it is impossible (out of the chessboard). When you see this input, display the array that represents the chessboard (like in the example in step 2). After that you should ask the user for the correct next move as always in case of illegal moves.

 

ADDITIONAL:

 

    Obviously, any legal move should be within the chessboard, so you have to control the chessboard boundaries.
    Since you dynamically allocate a 2D-array, you are responsible to delete it before the end of the program.

I don’t mind if you loop steps 3 and 4 in an infinite loop. But anyway, I want to see correct delete commands after that loop.

 

    It is possible for stalemate to occur. In that case your program is endlessly stuck on step 3 or 4. You DON’T need to do anything about this situation and it’s up to user to avoid it.
    In this particular project maintaining a chessboard-representing array might seem unnecessary, but it enforced by our assignment so you can practice 2D-array. Feel free to represent the king and queen anyway you want in your program, but make sure that the chessboard array is correctly maintained at all times. You MUST use dynamic allocation and classic C-style arrays.
    I want a structured approach to programming here. Please do not implement the whole program as a single main() function. For example, checking if the next kings move is possible feels like a separate function. Checking if the next queens move is possible feels like another function.
Last edited on
Okay fine, use 2d dynamic arrays. But make them correctly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Example program
#include <iostream>
#include <vector>

// pass the board to a function
void change(int** board)
{
    board[2][0] = 5;
}

int main()
{
    int Size;
    std::cin >> Size;
    
    if (Size < 3) { /* error handling */ }
    
    // Create a 2D dyanmic
    int** board = new int*[Size];
    for (int i = 0; i < Size; i++)
    {
        board[i] = new int[Size];
        for (int j = 0 ; j < Size; j++)
            board[i][j] = 0;
    }

    change(board);  
    std::cout << board[2][0] << "\n";
    
    // delete dynamic memory
    for (int i = 0; i < Size; i++)
    {
        delete[] board[i];
    }
    delete[] board;
}

If you want to simulate a 2D array with a 1D array, which you seem to be doing, then you need to access the elements like this:

1
2
3
4
    board2d[row * Size + col];

    // So for board2d[2][0] it would be
    board2d[2 * Size + 0];


BTW, you should always post real code when possible. I doubt the variable in change is actually called "boarded"!
Thanks, I'm using this code now and it's working great:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>

using namespace std;

void print_board(int **board2d, int Size) //spent 4 hours learning how to pass a 2d array from google.
{
    for (int i = 0; i < Size; i++)
    {
      for (int j = 0; j < Size; j++)
      {
      cout << board2d[i][j] << ' ';
      }
    cout << '\n';
     }
}

void new_game(int **board2d, int Size)
{
    for (int i = 0; i < Size; i++)
     {
      for (int j = 0; j < Size; j++)
        {
            board2d[i][j] = 0;
        }
     }

}

void changeBQ(int **board2d, int p1, int p2) // spent 2 hours figuring out how to change an array using pointers then found out I was doing the wrong thing!!
{
// board2d[p1][p2] = 2;
}

int getcurrentposbq(int **board2d,int size)
{
  for (int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        if (board2d[i][j] == 2)
        return (j,i);
      }
    }
    return 0;
}


int main() 
{
  const int wk = 1, //White King
            bq = 2; //Black Queen

  int Size; //Board Size

  cout << "Enter board size (one number for both length and width):";
  cin >> Size;
  while (Size <= 2)
  {
    cout << "Board size must be greater than 2, Re-enter board size: ";
    cin >> Size;
  }
// int** a = new int*[rowCount];
// for(int i = 0; i < rowCount; ++i)
//     a[i] = new int[colCount];
  int** board2d = new int*[Size];
  for (int i =0; i < Size; ++i)
    {
      board2d[i] = new int[Size];
    }
  
  new_game(board2d,Size);
  // changeBQ(board2d,1,2);
  board2d[0][1] = wk;
  board2d[2][0] = bq;
  print_board(board2d,Size);

//for (int i = 0; i < Size; ++i)
  // delete [] board2d[i];
//delete [] board2d;
return 0;
}
I think your instructor wants you to keep the delete[] calls, by the way.

Line 41 is probably not going what you think it's doing. Also, stick to a good habit of indenting properly (indent line 41).
1
2
if (board2d[i][j] == 2)
    return (j,i);

You can't return two things from a function that returns an int.

You either have to return it as one struct/class, or have the j,i position be reference parameters.

i.e.
1
2
3
4
5
6
7
void foo(int** b, int& i, int& j) // pass a variable for i and j by reference
{
   // logic
    i = 3;
    j = 2;
    // now j and i are set to the variables you passed in when calling this function
}


1
2
3
int i, j;
foo(board2d, i, j);
// at this point, i == 3 and j == 2. 

The_Professor wrote:
Coordinates on the board are defined by the row number and column number. Create a structure for it similar to the Point structure from the assignment number 4. Initial position of the white king is (0,1). Initial position of black queen is (2,0) . For example, for the Board_Size=4 the initial board is a following 2D-array

0 0 0 0

2 0 0 0

0 0 0 0

0 1 0 0


woah, that is a weird coordinate system... if you really want it to be chess-like, left->right is "A"->"H" and bottom to top is the one-based "1"->"8". So initial positions would be "B1" for king, and "A3" for the queen.

Edit: Also, the way the program is structured with a prompt to move the king, there appears to always be exactly one opening move for the king, for every board size greater than 2.

Edit2: your current code,
1
2
3
4
  new_game(board2d,Size);
  // changeBQ(board2d,1,2);
  board2d[0][1] = wk;
  board2d[2][0] = bq;


would actually create a board that looks like
0 1 0 0

0 0 0 0

2 0 0 0

0 0 0 0


If you want to follow the crazed coordinate system from the instructions, you need to apply some care with the row -- board2d[Size-1-row][col] , I believe.
Last edited on
I didn't explain that well, I left the array in place due to total brain death or something. to use ** you have to go ** all the way, unfortunately. A 2-d array (or vector) is frustratingly not compatible with **. I avoid the whole mess by always using 1-d and manual indexing. This will work, but its a royal pain to manage. You had this in one version, its OK to do it if you like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

 void seta(int **z)
 {
   z[3][4] = 5;   
  }
 
 int main()  
 {
    int **x;     //sigh
     x = new int*[5];
    for(int i = 0; i < 5; i++)
     x[i] = new int[10];
    seta(x);
 
  return 0;
}


Last edited on
I agree, doing a manual 2D->1D indexing (y*width + x) is very nice (it also can be a lot quicker since it's 1 call to new instead of N fragmented new's. It's what APIs like OpenGL expect anyway, and it can be encapsulated by having a function int& grid(x, y) or something.
Last edited on
Topic archived. No new replies allowed.