Can someone explain what's wrong here?

I've gotten utterly lost in the world of pointers and arrays.

I'm trying to make a very simple game. The first step is getting a "unit" to move across a grid-like board (like in Chess).

My board is a 2-dimensional array.

I have a unit class (since my game will have different types of units) and each unit object has a "move" function.

This "move" function requires the board to be passed, since moving the unit amounts to nothing but changing the board.

Passing the 2-dimensional array, however, proved to be an enormous syntax disaster. I thought it was all behind me, but now I'm stuck in a segmentation fault.

Here's the code (I will bold and italicize the most relevant lines):

Game.cpp (the main tester program)
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
#include <iostream>
using namespace std;

#include "Unit.h"

static const int r = 15;
static const int c = 15;

char board[r][c];

int main()
{
	void printBoard();

        cout << endl;

	for (int Row = 1; Row < r-1; Row++)
        {
                for (int Col = 1; Col < c-1; Col++)
                {
			board[Row][Col] = ' ';
                }
        }	

        Unit Alexander (52, 80, 1, 10, 3, 20, 1, true, 2, 8);

        board[Alexander.get_ypos()][Alexander.get_xpos()] = 'A';
	
	printBoard();

	Alexander.Move(board, 3, 9);

	printBoard();
	
}

void printBoard()
{

	//Number the columns so the user can easily identify coordinates
        cout << "    ";
        for (int i = 1; i < r-1; i++)
        {
                cout << i;
		if (i <= 9)
			cout << "  ";
        	else
			cout << " ";
	}

        cout << endl;
        for (int Row = 1; Row < r-1; Row++)
        {
                cout << Row;
		if (Row <= 9)
			cout << "  "; // Output Row so the rows are numbered
                else
			cout << " ";
		for (int Col = 1; Col < c-1; Col++)
                {
                        if ((Col != 1 || Row != 1) && (Col != 13 || Row != 1) && (Col != 1 || Row != 13) && (Col != 13 || Row != 13) )
				cout << "[" << board[Row][Col] << "]";
			else
				cout << "   ";
			
                }
                cout << "\n";
        }

        cout << endl;
}
	


Here's the Unit.h
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
82
83
84
85
86
87
88
#ifndef Unit_h
#define Unit_h

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

//#include "Student.h"
//#include "Node.h"

class Unit
{
        public:
                // Default constructor
                Unit();

		// Constructor that specifies a unit
		Unit(int h, int a, int w, int c, int m, int p, int r, bool l, int x, int y);

		// Unit moves across arena, returns whether it's a legal movement. Takes in coordinates as arguments. 
		void Move(char **board, int x, int y);
		
		// Unit executes its ability (attacks, heal, etc). Takes in defending unit as argument. Returns whether attack is leagal.
		bool Attack(Unit defender);

		// Unit counters an attack. Takes in original attacker as argumentt, as well as original attacker's coordinates.
		void Counter(Unit attacker, int x, int y); 
		
		// Returns true if a given unit is still alive
		bool isAlive(Unit patient);
		
		// Unit changes direction
		void Turn();


		void setHealth(int h);
	
		void setArmor(int a);

		void setWait(int w);
		
		void setCounter(int c);
	
		void setMove(int m);
		
		void setPower(int p);

		void setRange(int r);

		void set_xpos(int x);
		
		void set_ypos(int y);


		int getHealth();

                int getArmor();

                int getWait();

                int getCounter();

                int getMove();

                int getPower();

                int getRange();
		
		int get_xpos();

		int get_ypos();
		
		
	private:

		int health;
		int armor;
		int wait;
		int counter;
		int move;
		int power;
		int range;//?????? will have to be a set of coordinates

                bool living;
		int xpos;
		int ypos;
};
#endif 


And here's the Unit.cpp

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
#include "Unit.h"

#include <iostream>
using namespace std;

Unit:: Unit()
{
        health = 0;
	armor = 0;
	wait = 0;
	counter = 0; 
	move = 0;
	power = 0; 
	range = 0;
	xpos = 0;
	ypos = 0;
	living = false;
}

Unit:: Unit(int h, int a, int w, int c, int m, int p, int r, bool l, int x, int y)
{
	health = h;
	armor = a;
	wait = w;
	counter = c;
	move = m;
	power = p;
	range = r;
	living = l;
	xpos = x;
	ypos = y;	
}

void Unit:: Move(char **board, int x, int y) 
{
	bool legalMove = true;

	int x_distance;
	int y_distance;
	int tot_distance;

	cout << "x = " << x << endl;
	cout << "y = " << y << endl;
	

	if (board[5][5] != ' ')
		legalMove = false;
	else
	{
		x_distance = abs(x - this -> get_xpos());	
		y_distance = abs(y - this -> get_ypos());
		tot_distance = x_distance + y_distance;

		if (tot_distance > this -> getMove())
			legalMove = false; 
	}
	
	if (legalMove)
        {
                board[ypos][xpos] = ' ';
                xpos = x;
                ypos = y;
                board[ypos][xpos] = 'A';
        }
        else
                cout << "You can't move there";

}


Thanks in advance. I know the problem has something to do with the board being a pointer to a board, and not the actual board itself. Not sure how to work around that problem. Nothing I tried worked.
What I would strongly recommend is that you place the board array inside an actual Board class, and have all units keep a reference or pointer to the board they are on, rather than the board array itself. There's two lessons here:

1. When you have a variable that needs to be accessed from multiple places, you should abstract access to it (e.g. by placing it in a class) so that management code is all in one place.

2. When you have a parameter in common between several functions, that's a sign that that parameter should really be a member of a class containing those functions.

Try restructuring or even re-writing your program to try again with this new approach - trying to mess with code that you describe as "an enormous syntax disaster" will only lead to you becoming more confused and adding more problems than you solve.

Sometimes you just have to restart with a different approach. Alternatively, if you think you can still salvage your code, you can go with cire's solution below.
Last edited on
1
2
3
4
void Unit::Move(char board[][c], int x, int y)
{
   // ...
}


alternately:
1
2
3
4
void Unit::Move(char (*board)[c], int x, int y)
{
    // ...
}


I would second L B's suggestion.
Last edited on
Okay guys, thanks a ton for the advice!

The thought had occurred to me that maybe I should have a whole class for the board.

I only spent a few hours on this, so there's really no harm in rewriting the whole thing.

Thanks again!
Last edited on
Topic archived. No new replies allowed.