chainreaction/src/core/board2d.hpp

83 lines
2.4 KiB
C++

#ifndef CORE_BOARD2D_HPP
#define CORE_BOARD2D_HPP
#include <map>
#include <stdexcept>
#include <utility>
#include <vector>
#include "generator.hpp"
#include "player.hpp"
namespace core
{
class Board2D
{
public:
struct Space;
using Spaces = std::vector<Space>;
using const_iterator = Spaces::const_iterator;
using iterator = Spaces::iterator;
using size_type = Spaces::size_type;
struct Coord
{
size_type x;
size_type y;
};
struct Space
{
int capacity {};
Coord coord {};
Player owner {Player::NONE};
int value {0};
Space() = default;
Space(Coord c) : coord {c} {}
inline void reset() noexcept
{
owner = Player::NONE;
value = 0;
}
};
struct InvalidMove : public std::logic_error
{
using logic_error::logic_error;
};
Board2D() = default;
Board2D(size_type, size_type);
[[nodiscard]] auto begin() const noexcept -> const_iterator;
[[nodiscard]] auto end() const noexcept -> const_iterator;
void init(size_type, size_type);
[[nodiscard]] auto is_overloaded(Coord) const noexcept -> bool;
auto move(Coord, Player) -> Generator<std::pair<Space, Player>>;
[[nodiscard]] auto neighbours(Coord) const noexcept -> std::vector<Coord>;
[[nodiscard]] auto operator()(Coord) const noexcept -> const Space&;
[[nodiscard]] auto size() const noexcept -> std::pair<size_type, size_type>;
auto spread(Coord, const std::vector<Coord>&, Player) -> Generator<Space>;
[[nodiscard]] auto winner() const noexcept -> Player;
[[nodiscard]] static auto winner(const Board2D&) noexcept -> Player;
private:
size_type h;
Spaces spaces;
std::map<Player, int> units;
size_type w;
void add_unit(Coord);
[[nodiscard]] auto at(Coord) noexcept -> Space&;
[[nodiscard]] auto at(Coord) const noexcept -> const Space&;
void capture(Coord, Player) noexcept;
[[nodiscard]] auto coord2idx(Coord) const noexcept -> size_type;
void remove_unit(Coord);
};
}
#endif