78 lines
2.3 KiB
C++
78 lines
2.3 KiB
C++
#include "game.hpp"
|
|
|
|
using namespace game;
|
|
using namespace game::data;
|
|
|
|
auto game::logic::play(const Board& b, const Coordinate& c, const Player p) -> Boards
|
|
{
|
|
auto new_state(b);
|
|
auto& square = Board::square(new_state, c);
|
|
Boards states;
|
|
|
|
if (square.owner != Player::NONE && p != square.owner) throw error::invalid_move();
|
|
|
|
square.owner = p;
|
|
square.value++;
|
|
states = spread(new_state);
|
|
|
|
return states;
|
|
}
|
|
|
|
auto game::logic::spread(const data::Board& b) noexcept -> Boards
|
|
{
|
|
Boards states;
|
|
Board current = b;
|
|
int overflows;
|
|
do {
|
|
overflows = 0;
|
|
auto new_state = current;
|
|
for (auto y = 0; y < current.height; y++) {
|
|
for (auto x = 0; x < current.width; x++) {
|
|
auto sqr = Board::square(current, {x, y});
|
|
if (sqr.value > square_capacity(current, {x, y})) {
|
|
overflows++;
|
|
Square::reset(Board::square(new_state, {x, y}));
|
|
states.push_back(new_state);
|
|
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
for (data::Coordinate neighboors[4] {
|
|
{ x, y + 1},
|
|
{x + 1, y},
|
|
{ x, y - 1},
|
|
{x - 1, y}
|
|
};
|
|
const data::Coordinate& c : neighboors)
|
|
{
|
|
if (c.x >= 0 && c.y >= 0 && c.x < current.width
|
|
&& c.y < current.height) {
|
|
auto& adj_sqr = Board::square(new_state, c);
|
|
adj_sqr.value++;
|
|
adj_sqr.owner = sqr.owner;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
states.push_back(new_state);
|
|
current = new_state;
|
|
} while (overflows > 0 && winner(current) == Player::NONE);
|
|
|
|
return states;
|
|
}
|
|
auto game::logic::winner(const Board& b) noexcept -> Player
|
|
{
|
|
auto winner {Player::NONE};
|
|
|
|
for (const auto& s : b.squares) {
|
|
if (winner == Player::NONE) {
|
|
if (s.owner != Player::NONE) {
|
|
winner = s.owner;
|
|
}
|
|
}
|
|
else if (s.owner != Player::NONE && winner != s.owner) {
|
|
return Player::NONE;
|
|
}
|
|
}
|
|
|
|
return winner;
|
|
}
|