Okay so basically I am building a simple checkers game using C++ SDL2 library
Currently I am holding the game board state data in a 8x8 2d array which is all the possible board spaces on a checkerboard. The value inside the array is either: 0 for empty space, 1 for red checker, 2 for blue checker.
I have basically the entire game done using this board as the logic and I am now going to be implementing the minimax algorithm to add computer AI as the opponent. So what I need to do is get all the possible board states and use that in the algorithm. Right now I am trying to find the right way to approach storing a bunch of arrays (board states) in a dynamic way since I will not know exactly every time how many states there will be. Is there any easy way to use a main array to hold all the board states (2d Arrays)? It needs to be dynamic, and arrays can only be static right?
I'd suggest creating a wrapper class around std::array<checker_type, 8 * 8>
(since emulating 2D array using a 1D arrays usually proves to be faster due to caching). This way you can easily create and copy such boards.
#include <array>
#include <iostream>
#include <vector>
namespace game {
enum class checker_type {
empty, red, blue
};
struct board {
std::array<checker_type, 8 * 8> data{};
struct proxy_row {
std::array<checker_type, 8 * 8>& data_ref;
const std::size_t row;
proxy_row(std::array<checker_type, 64>& data_ref, const size_t row) noexcept
: data_ref(data_ref), row(row) { }
checker_type& operator [] (const std::size_t col) const noexcept {
return data_ref[8 * row + col];
}
};
struct const_proxy_row {
const std::array<checker_type, 8 * 8>& data_ref;
const std::size_t row;
const_proxy_row(const std::array<checker_type, 64>& data_ref, const size_t row) noexcept
: data_ref(data_ref), row(row) { }
const checker_type& operator [] (const std::size_t col) const noexcept {
return data_ref[8 * row + col];
}
};
proxy_row operator [] (const std::size_t row) noexcept {
return proxy_row(data, row);
};
const_proxy_row operator [] (const std::size_t row) const noexcept {
return const_proxy_row(data, row);
}
};
}
void print_board(const game::board& board) noexcept {
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
std::cout << static_cast<int>(board[i][j]) << ' ';
}
std::cout << '\n';
}
}
As for creating multiple boards to run minmax algorithm, you can use an std::vector
- a class template which provides a dynamic array functionality with lots of utilities:
int main() {
game::board board{};
board[0][0] = game::checker_type::blue;
board[1][1] = game::checker_type::blue;
board[2][2] = game::checker_type::red;
print_board(board);
std::vector<game::board> boards{};
const auto size = 1000;
boards.reserve(size); // reserve memory for *size* boards
for (int i = 0; i < size; ++i) {
boards.emplace_back(); // creating *size* boards to run minmax algorithm
}
}
To elaborate a little bit on your thought process:
Right now I am trying to find the right way to approach storing a bunch of arrays (board states) in a dynamic way since I will not know exactly every time how many states there will be.
You are correct that you want a dynamic way of storing some data if you do not know beforehand how much memory that data will require. std::vector
is an excellent tool to handle that.
[Array] needs to be dynamic, and arrays can only be static right?
Wrong. First of all, static is not the opposite of dynamic. You can have a dynamic, static array (for example static int* arr = new int[10];
).