Reputation: 11
So I wanted to create a game with a square world.
When starting the game, the user should be able to specify the size of the world.
The world is saved as a two-dimensional array of shorts.
const short gameSize = 4;
short world[gameSize][gameSize];
The short gameSize
must be const
, otherwise, I can't put gameSize
as the size of world[][]
.
However, this won't allow me to set gameSize
to the player-wished size.
I thought of something simple like
short gameSize = 0;
cout << "World size?" << endl;
cin >> gameSize;
short world[gameSize][gameSize];
As stated, this won't work.
In the game, it won't be possible to change the value of gameSize later on.
How could I make this happen?
Upvotes: 1
Views: 177
Reputation:
new
as the linked questions/answers would lead you to do. It's unnecessary in your case and will increase the risk of potential bugs for no good reason.std::vector<short>
to manage an indexable chunk of memory storing the world values.#include <vector>
#include <cassert>
#include <iostream>
class GameWorld {
std::size_t world_size_;
std::vector<short> data_;
public:
GameWorld(std::size_t size)
: world_size_(size)
, data_(size * size) {}
short& operator()(std::size_t x, std::size_t y) {
assert(x < world_size_ && y < world_size_);
return _data[y + x * world_size_];
}
const short& operator()(std::size_t x, std::size_t y) const {
assert(x < world_size_ && y < world_size_);
return _data[y + x * world_size_];
}
};
int main() {
short gameSize = 0;
std::cout << "World size?" << std::endl;
std::cin >> gameSize;
GameWorld world(gameSize);
// Set the value of [0, 0] to 4
world(0, 0) = 4;
}
There's a few things happening here:
vector<short>
will give you a dynamic size as well as memory safety. i.e. Things will get cleaned up "automatically" as appropriate.vector<vector<short>>
, so that world[x][y]
"just works". But that's not great because the memory will be all over the place, packing it tightly into a one-dimensional array gives you a bunch of performance benefits in general.world[x][y]
in your previous code, so no additional cost is incurred here.assert()
s will catch potential bugs when building in debug mode, and disappear entirely in release/NDEBUG mode. So you have an additional "free" safety net .Bonus: If you want to start dipping your toes into template programming, this is a great starting point to learn. Templating GameWorld
so that it can be a world of float
, int
, or some struct Cell
instead of always being a world of short
is useful, easy to do, and not disruptive to the rest of the code.
Upvotes: 6