implement reading from file. cleanup

This commit is contained in:
Maximilian Keßler 2023-08-05 11:55:46 +02:00
parent 262d909f3d
commit 3b993030ea
Signed by: max
GPG key ID: BCC5A619923C0BA5
4 changed files with 197 additions and 181 deletions

View file

@ -5,6 +5,8 @@
#include <boost/json/src.hpp> #include <boost/json/src.hpp>
#include <cpr/cpr.h> #include <cpr/cpr.h>
#include <iostream> #include <iostream>
#include <fstream>
#include <variant>
#include "game_state.h" #include "game_state.h"
@ -58,15 +60,27 @@ boost::json::object download_game_json(int game_id) {
return boost::json::parse(r.text).as_object(); return boost::json::parse(r.text).as_object();
} }
void download_game(int game_id) { boost::json::object open_game_json(const char* filename) {
boost::json::object game = download_game_json(game_id); std::ifstream file(filename);
std::cout << game << std::endl; if (!file.is_open()) {
const auto deck = parse_deck(game.at("deck")); std::cout << "Failed to open " << filename << "." << std::endl;
const unsigned num_players = game.at("players").as_array().size(); return {};
for(const auto& card : deck) {
std::cout << card << std::endl;
} }
std::string game_json ((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
return boost::json::parse(game_json).as_object();
}
void get_game(std::variant<int, const char*> game_spec) {
const boost::json::object game = [&game_spec](){
if (game_spec.index() == 0) {
return download_game_json(std::get<int>(game_spec));
} else {
return open_game_json(std::get<const char*>(game_spec));
}
}();
const std::vector<Hanabi::Card> deck = parse_deck(game.at("deck"));
const unsigned num_players = game.at("players").as_array().size();
std::cout << deck.size() << std::endl;
std::cout << num_players; std::cout << num_players;
} }

View file

@ -1,7 +1,3 @@
//
// Created by maximilian on 7/13/23.
//
#ifndef DYNAMIC_PROGRAM_GAME_STATE_H #ifndef DYNAMIC_PROGRAM_GAME_STATE_H
#define DYNAMIC_PROGRAM_GAME_STATE_H #define DYNAMIC_PROGRAM_GAME_STATE_H
@ -41,7 +37,7 @@ constexpr player_t draw_pile = -1;
constexpr player_t trash_or_play_stack = -2; constexpr player_t trash_or_play_stack = -2;
constexpr clue_t max_num_clues = 8; constexpr clue_t max_num_clues = 8;
constexpr std::array<std::string, 5> suit_initials{"r", "y", "g", "b", "p"}; constexpr std::array<std::string, 6> suit_initials{"r", "y", "g", "b", "p", "t"};
struct Card { struct Card {
suit_t suit; suit_t suit;
@ -157,10 +153,11 @@ operator<<(std::ostream &os,
HanabiState<num_suits, num_players, hand_size, max_draw_pile_size> HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>
hanabi_state); hanabi_state);
#include "game_state.hpp"
template class HanabiState<5, 3, 4, 20>; template class HanabiState<5, 3, 4, 20>;
} }
#include "game_state.hpp"
#endif // DYNAMIC_PROGRAM_GAME_STATE_H #endif // DYNAMIC_PROGRAM_GAME_STATE_H

View file

@ -2,70 +2,72 @@
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
namespace Hanabi {
Card& Card::operator++() { Card &Card::operator++() {
rank++; rank++;
return *this; return *this;
} }
Card Card::successor() const { Card Card::successor() const { return {suit, static_cast<rank_t>(rank + 1)}; }
return {suit, static_cast<rank_t>(rank + 1)};
}
const Card Card::operator++(int) { const Card Card::operator++(int) {
Card ret = *this; Card ret = *this;
rank++; rank++;
return ret; return ret;
} }
template<std::size_t num_suits> template<std::size_t num_suits>
std::ostream& operator<<(std::ostream& os, const Stacks<num_suits>& stacks) { std::ostream &operator<<(std::ostream &os, const Stacks<num_suits> &stacks) {
for (size_t i = 0; i < stacks.size() - 1; i++) { for (size_t i = 0; i < stacks.size() - 1; i++) {
os << +stacks[i] << ", "; os << +stacks[i] << ", ";
} }
os << +stacks.back(); os << +stacks.back();
return os; return os;
} }
template<std::size_t num_suits> template<std::size_t num_suits>
const player_t & CardPositions<num_suits>::operator[](const Card& card) const { const player_t &CardPositions<num_suits>::operator[](const Card &card) const {
return _card_positions[card.suit][card.rank][card.copy]; return _card_positions[card.suit][card.rank][card.copy];
}; };
template<std::size_t num_suits> template<std::size_t num_suits>
player_t & CardPositions<num_suits>::operator[](const Card& card) { player_t &CardPositions<num_suits>::operator[](const Card &card) {
return _card_positions[card.suit][card.rank][card.copy]; return _card_positions[card.suit][card.rank][card.copy];
}; };
template <size_t num_suits, size_t num_players, size_t hand_size, uint8_t max_draw_pile_size> template<size_t num_suits, size_t num_players, size_t hand_size, uint8_t max_draw_pile_size>
Action HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::clue() { Action HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::clue() {
assert(_num_clues > 0); assert(_num_clues > 0);
--_num_clues; --_num_clues;
incr_turn(); incr_turn();
return Action {ActionType::clue, {}, {}}; return Action{ActionType::clue, {}, {}};
} }
template <size_t num_suits, size_t num_players, size_t hand_size, uint8_t max_draw_pile_size> template<size_t num_suits, size_t num_players, size_t hand_size, uint8_t max_draw_pile_size>
void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::incr_turn() { void HanabiState<num_suits, num_players, hand_size,
max_draw_pile_size>::incr_turn() {
_turn = (_turn + 1) % num_players; _turn = (_turn + 1) % num_players;
} }
template <size_t num_suits, size_t num_players, size_t hand_size, uint8_t max_draw_pile_size> template<size_t num_suits, size_t num_players, size_t hand_size, uint8_t max_draw_pile_size>
void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::decr_turn() { void HanabiState<num_suits, num_players, hand_size,
max_draw_pile_size>::decr_turn() {
_turn = (_turn + num_players - 1) % num_players; _turn = (_turn + num_players - 1) % num_players;
} }
template <std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size> template<std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size>
Action HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::play(std::uint8_t index) { Action HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::play(
std::uint8_t index) {
assert(index < _hands[_turn].size()); assert(index < _hands[_turn].size());
const Card card = _hands[_turn][index]; const Card card = _hands[_turn][index];
assert(card.rank == _stacks[card.suit] - 1); assert(card.rank == _stacks[card.suit] - 1);
--_stacks[card.suit]; --_stacks[card.suit];
Action ret {ActionType::play, _hands[_turn][index], index}; Action ret{ActionType::play, _hands[_turn][index], index};
if (card.rank == 0) { if (card.rank == 0) {
// update clues if we played the last card of a stack // update clues if we played the last card of a stack
@ -76,29 +78,29 @@ Action HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::play(
incr_turn(); incr_turn();
return ret; return ret;
} }
template <std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size> template<std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size>
Action HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::discard(std::uint8_t index) { Action HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::discard(
std::uint8_t index) {
assert(index < _hands[_turn].size()); assert(index < _hands[_turn].size());
assert(_num_clues != max_num_clues); assert(_num_clues != max_num_clues);
_num_clues++; _num_clues++;
Action ret {ActionType::discard, _hands[_turn][index], index}; Action ret{ActionType::discard, _hands[_turn][index], index};
draw(index); draw(index);
incr_turn(); incr_turn();
return ret; return ret;
} }
template<std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size>
template <std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size> std::ostream &operator<<(std::ostream &os, const HanabiState<num_suits, num_players, hand_size, max_draw_pile_size> hanabi_state) {
std::ostream& operator<<(std::ostream& os, const HanabiState<num_suits, num_players, hand_size, max_draw_pile_size> hanabi_state) {
os << "Stacks: " << hanabi_state._stacks << std::endl; os << "Stacks: " << hanabi_state._stacks << std::endl;
os << "Draw pile: "; os << "Draw pile: ";
for (const auto &[card, mul] : hanabi_state._draw_pile) { for (const auto &[card, mul]: hanabi_state._draw_pile) {
os << card; os << card;
if (mul > 1) { if (mul > 1) {
os << " (" << +mul << ")"; os << " (" << +mul << ")";
@ -106,17 +108,17 @@ std::ostream& operator<<(std::ostream& os, const HanabiState<num_suits, num_play
} }
os << std::endl; os << std::endl;
os << "Hands: "; os << "Hands: ";
for (const auto& hand: hanabi_state._hands) { for (const auto &hand: hanabi_state._hands) {
for (const auto &card: hand) { for (const auto &card: hand) {
os << card << ", "; os << card << ", ";
} }
os << " | "; os << " | ";
} }
return os; return os;
} }
template <std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size> template<std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size>
void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::draw(std::uint8_t index) { void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::draw(std::uint8_t index) {
assert(index < _hands[_turn].size()); assert(index < _hands[_turn].size());
_card_positions[_hands[_turn][index]] = trash_or_play_stack; _card_positions[_hands[_turn][index]] = trash_or_play_stack;
@ -134,10 +136,10 @@ void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::draw(st
_hands[_turn][index] = draw.card; _hands[_turn][index] = draw.card;
_card_positions[draw.card] = _turn; _card_positions[draw.card] = _turn;
} }
} }
template <std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size> template<std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size>
void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::revert_draw(std::uint8_t index, Card card) { void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::revert_draw(std::uint8_t index, Card card) {
assert(index < _hands[_turn].size()); assert(index < _hands[_turn].size());
_card_positions[_hands[_turn][index]] = draw_pile; _card_positions[_hands[_turn][index]] = draw_pile;
@ -152,10 +154,11 @@ void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::revert_
_hands[_turn][index] = card; _hands[_turn][index] = card;
_card_positions[card] = _turn; _card_positions[card] = _turn;
_draw_pile_size++; _draw_pile_size++;
} }
template <std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size> template<std::size_t num_suits, std::size_t num_players, std::size_t hand_size, uint8_t max_draw_pile_size>
void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::revert(const Action &action) { void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::revert(
const Action &action) {
decr_turn(); decr_turn();
switch (action.type) { switch (action.type) {
case ActionType::clue: case ActionType::clue:
@ -174,4 +177,6 @@ void HanabiState<num_suits, num_players, hand_size, max_draw_pile_size>::revert(
revert_draw(action.index, action.discarded); revert_draw(action.index, action.discarded);
_stacks[action.discarded.suit]++; _stacks[action.discarded.suit]++;
} }
} }
} // namespace Hanabi

View file

@ -38,7 +38,7 @@ void test_game() {
assert(state == state2); assert(state == state2);
} }
void download() { download_game(1000000); } void download() { get_game("314159.json"); }
void print_sizes() { void print_sizes() {
std::cout << "size of card -> hand map: " << sizeof(HanabiState<5, 3, 4, 5>) std::cout << "size of card -> hand map: " << sizeof(HanabiState<5, 3, 4, 5>)