rework moving forward/backward in game
This commit is contained in:
parent
f3fe367988
commit
5308eeaf6e
4 changed files with 52 additions and 21 deletions
|
@ -259,11 +259,12 @@ protected:
|
||||||
// A game mimics a game state together with a list of actions and allows to traverse the game
|
// A game mimics a game state together with a list of actions and allows to traverse the game
|
||||||
// history by making and reverting the stored actions.
|
// history by making and reverting the stored actions.
|
||||||
struct Game {
|
struct Game {
|
||||||
|
Game(std::unique_ptr<HanabiStateIF> state, std::vector<Action> actions, std::vector<Card> deck);
|
||||||
void make_turn();
|
void make_turn();
|
||||||
void revert_turn();
|
void revert_turn();
|
||||||
void forward_until(size_t turn = 100, size_t draw_pile_break = 0);
|
|
||||||
void revert_until(size_t draw_pile_break);
|
|
||||||
|
|
||||||
|
bool goto_draw_pile_size(size_t draw_pile_break);
|
||||||
|
bool goto_turn(size_t turn);
|
||||||
|
|
||||||
std::unique_ptr<HanabiStateIF> state;
|
std::unique_ptr<HanabiStateIF> state;
|
||||||
std::vector<Action> actions;
|
std::vector<Action> actions;
|
||||||
|
|
|
@ -182,7 +182,7 @@ namespace Download {
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (!game_json_opt.has_value() or game_json_opt.value().empty()) {
|
if (!game_json_opt.has_value() or game_json_opt.value().empty()) {
|
||||||
return {nullptr, {}, {}, 0};
|
return Hanabi::Game(nullptr, {}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const boost::json::object& game_json = game_json_opt.value();
|
const boost::json::object& game_json = game_json_opt.value();
|
||||||
|
@ -202,7 +202,7 @@ namespace Download {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return {get_base_state(num_suits, num_players, deck, score_goal), actions, deck, 0};
|
return {get_base_state(num_suits, num_players, deck, score_goal), actions, deck};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Download
|
} // namespace Download
|
||||||
|
|
|
@ -1,7 +1,26 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <utility>
|
||||||
#include "game_state.h"
|
#include "game_state.h"
|
||||||
|
|
||||||
namespace Hanabi {
|
namespace Hanabi {
|
||||||
|
|
||||||
|
Game::Game(std::unique_ptr<HanabiStateIF> state, std::vector<Action> actions, std::vector<Card> deck):
|
||||||
|
state(std::move(state)), actions(std::move(actions)), deck(std::move(deck)), next_action(0)
|
||||||
|
{
|
||||||
|
// If there is a 'Null' action that only signals the game's end, we want to get rid of it now,
|
||||||
|
// as this will mess with our moves.
|
||||||
|
if(not this->actions.empty()) {
|
||||||
|
switch(this->actions.back().type) {
|
||||||
|
case ActionType::vote_terminate:
|
||||||
|
case ActionType::vote_terminate_players:
|
||||||
|
case ActionType::end_game:
|
||||||
|
this->actions.pop_back();
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Game::make_turn()
|
void Game::make_turn()
|
||||||
{
|
{
|
||||||
ASSERT(next_action < actions.size());
|
ASSERT(next_action < actions.size());
|
||||||
|
@ -35,26 +54,35 @@ namespace Hanabi {
|
||||||
void Game::revert_turn()
|
void Game::revert_turn()
|
||||||
{
|
{
|
||||||
state->revert();
|
state->revert();
|
||||||
|
--next_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::forward_until(size_t turn, size_t draw_pile_break)
|
bool Game::goto_turn(size_t turn)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < std::min(turn - 1, actions.size()); i++) {
|
size_t const cur_turn = next_action + 1;
|
||||||
if (state->draw_pile_size() == draw_pile_break) {
|
if (cur_turn >= turn) {
|
||||||
break;
|
for(size_t i = 0; i < cur_turn - turn; i++) {
|
||||||
|
revert_turn();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
while(next_action < actions.size() and next_action + 1 < turn) {
|
||||||
|
make_turn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return next_action + 1 == turn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::goto_draw_pile_size(size_t draw_pile_break)
|
||||||
|
{
|
||||||
|
while (state->draw_pile_size() > draw_pile_break and next_action < actions.size()) {
|
||||||
make_turn();
|
make_turn();
|
||||||
}
|
}
|
||||||
|
while(state->draw_pile_size() < draw_pile_break or (state->draw_pile_size() == draw_pile_break and state->last_action_type() == ActionType::clue)) {
|
||||||
|
revert_turn();
|
||||||
|
}
|
||||||
|
std::cout << "Moved to turn " << next_action + 1 << " with draw pile size " << state->draw_pile_size() << ".\n";
|
||||||
|
return state->draw_pile_size() == draw_pile_break;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::revert_until(size_t draw_pile_break)
|
|
||||||
{
|
|
||||||
while(state->draw_pile_size() < draw_pile_break) {
|
|
||||||
revert_turn();
|
|
||||||
}
|
|
||||||
while(state->last_action_type() == ActionType::clue)
|
|
||||||
{
|
|
||||||
revert_turn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace Hanabi {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.forward_until(turn, draw_pile_size);
|
game.goto_draw_pile_size(draw_pile_size);
|
||||||
if (draw_pile_size != 0 and game.state->draw_pile_size() != static_cast<size_t>(draw_pile_size)) {
|
if (draw_pile_size != 0 and game.state->draw_pile_size() != static_cast<size_t>(draw_pile_size)) {
|
||||||
std::cout << "This given draw pile size (" << draw_pile_size << ") cannot be obtained with the specified replay." << std::endl;
|
std::cout << "This given draw pile size (" << draw_pile_size << ") cannot be obtained with the specified replay." << std::endl;
|
||||||
return;
|
return;
|
||||||
|
@ -57,9 +57,11 @@ namespace Hanabi {
|
||||||
if (print_remaining_states)
|
if (print_remaining_states)
|
||||||
{
|
{
|
||||||
size_t const max_draw_pile_size = game.state->draw_pile_size();
|
size_t const max_draw_pile_size = game.state->draw_pile_size();
|
||||||
game.forward_until(100, 1);
|
|
||||||
for(size_t remaining_cards = 1; remaining_cards <= max_draw_pile_size; remaining_cards++) {
|
for(size_t remaining_cards = 1; remaining_cards <= max_draw_pile_size; remaining_cards++) {
|
||||||
game.revert_until(remaining_cards);
|
if (!game.goto_draw_pile_size(remaining_cards))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
};
|
||||||
if (all_clues) {
|
if (all_clues) {
|
||||||
clue_t original_num_clues = game.state->num_clues();
|
clue_t original_num_clues = game.state->num_clues();
|
||||||
for(clue_t num_clues = 0; num_clues <= 8; num_clues++) {
|
for(clue_t num_clues = 0; num_clues <= 8; num_clues++) {
|
||||||
|
|
Loading…
Reference in a new issue