84 lines
2.1 KiB
C++
84 lines
2.1 KiB
C++
#include <cassert>
|
|
#include <iostream>
|
|
|
|
#include "game.hpp"
|
|
|
|
using namespace game;
|
|
using namespace game::data;
|
|
|
|
Boards game::logic::play(Board& b, const Coordinate& c, const Player p)
|
|
{
|
|
auto& square = Board::square(b, c);
|
|
Boards state_transitions;
|
|
|
|
if (square.owner != Player::NONE && p != square.owner)
|
|
throw error::invalid_move();
|
|
|
|
square.owner = p;
|
|
square.value++;
|
|
if (square.value > logic::square_capacity(b, c))
|
|
state_transitions = spread(b, c);
|
|
|
|
return state_transitions;
|
|
}
|
|
|
|
Boards game::logic::spread(data::Board& b, const data::Coordinate& c)
|
|
{
|
|
Boards state_transitions;
|
|
|
|
data::Player owner = Board::square(b, c).owner;
|
|
if (logic::winner(b) == data::Player::NONE)
|
|
{
|
|
state_transitions.push_back(b);
|
|
data::Square::reset(Board::square(b, c));
|
|
state_transitions.push_back(b);
|
|
|
|
for (data::Coordinate neighboors[4] {
|
|
{c.x, c.y + 1},
|
|
{c.x + 1, c.y},
|
|
{c.x, c.y - 1},
|
|
{c.x - 1, c.y}
|
|
}; const data::Coordinate& c : neighboors)
|
|
{
|
|
if (c.x >= 0 && c.y >= 0 && c.x < b.width && c.y < b.height)
|
|
{
|
|
Board::square(b, c).value++;
|
|
Board::square(b, c).owner = owner;
|
|
state_transitions.push_back(b);
|
|
|
|
if (Board::square(b, c).value > square_capacity(b, c))
|
|
{
|
|
auto transitions = spread(b, c);
|
|
state_transitions.insert(std::end(state_transitions),
|
|
std::cbegin(transitions),
|
|
std::cend(transitions));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return state_transitions;
|
|
}
|
|
|
|
Player game::logic::winner(const Board& b) noexcept
|
|
{
|
|
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;
|
|
}
|