Cavoke  1.1.0
A Platform for creating and hosting multiplayer turn-based board games
Loading...
Searching...
No Matches
game_state_storage.cpp
1#include "game_state_storage.h"
2#include <drogon/HttpAppFramework.h>
3#include <json/reader.h>
4#include <utility>
5#include "sql-models/Globalstates.h"
6#include "sql-models/Players.h"
7#include "utils.h"
8
9namespace cavoke::server::model {
10
11using json = nlohmann::json;
12using namespace drogon::orm;
13
14void GameStateStorage::save_state(const std::string &session_id,
15 GameStateStorage::GameState new_state,
16 DbClientPtr dbClient) {
17 auto mp_globalstates = MAPPER_WITH_CLIENT_FOR(
18 drogon_model::cavoke_orm::Globalstates, dbClient);
19 auto mp_players =
20 MAPPER_WITH_CLIENT_FOR(drogon_model::cavoke_orm::Players, dbClient);
21
22 auto global_state = mp_globalstates.findOne(
23 Criteria(drogon_model::cavoke_orm::Globalstates::Cols::_session_id,
24 CompareOperator::EQ, session_id));
25 auto players = mp_players.findBy(
26 Criteria(drogon_model::cavoke_orm::Players::Cols::_session_id,
27 CompareOperator::EQ, session_id));
28
29 global_state.setGlobalstate(new_state.global_state);
30 global_state.setIsTerminal(new_state.is_terminal);
31
32 for (auto &player : players) {
33 player.setPlayerstate(
34 new_state.players_state[player.getValueOfPlayerId()]);
35 if (new_state.is_terminal) {
36 // FIXME: move to a new winner system
37 bool is_winner =
38 std::any_of(new_state.winners.begin(), new_state.winners.end(),
39 [&](int player_id) {
40 return player.getValueOfPlayerId() == player_id;
41 });
42 player.setScore(is_winner ? 1 : 0);
43 } else {
44 player.setScoreToNull();
45 }
46 mp_players.update(player);
47 }
48 mp_globalstates.update(global_state);
49}
50
51GameStateStorage::GameState GameStateStorage::get_state(
52 const std::string &session_id,
53 drogon::orm::DbClientPtr dbClient) {
54 GameStateStorage::GameState state;
55
56 auto mp_globalstates = MAPPER_WITH_CLIENT_FOR(
57 drogon_model::cavoke_orm::Globalstates, dbClient);
58 auto global_state = mp_globalstates.findOne(drogon::orm::Criteria(
59 drogon_model::cavoke_orm::Globalstates::Cols::_session_id,
60 drogon::orm::CompareOperator::EQ, session_id));
61 state.global_state = global_state.getValueOfGlobalstate();
62 state.is_terminal = global_state.getValueOfIsTerminal();
63
64 auto mp_players =
65 MAPPER_WITH_CLIENT_FOR(drogon_model::cavoke_orm::Players, dbClient);
66 auto players = mp_players.findBy(drogon::orm::Criteria(
67 drogon_model::cavoke_orm::Players::Cols::_session_id,
68 drogon::orm::CompareOperator::EQ, session_id));
69 state.players_state = std::vector<std::string>(players.size());
70 for (auto &player : players) {
71 int player_id = player.getValueOfPlayerId();
72 if (player.getScore()) {
73 state.winners.push_back(player_id);
74 }
75 state.players_state[player_id] = player.getValueOfPlayerstate();
76 }
77 return state;
78}
79
80std::string GameStateStorage::get_player_state(const std::string &session_id,
81 int player_id,
82 DbClientPtr dbClient) {
83 auto mp_players =
84 MAPPER_WITH_CLIENT_FOR(drogon_model::cavoke_orm::Players, dbClient);
85 try {
86 auto player = mp_players.findOne(
87 Criteria(drogon_model::cavoke_orm::Players::Cols::_session_id,
88 CompareOperator::EQ, session_id) &&
89 Criteria(drogon_model::cavoke_orm::Players::Cols::_player_id,
90 CompareOperator::EQ, player_id));
91 return player.getValueOfPlayerstate();
92 } catch (const std::out_of_range &) {
93 throw game_state_error("There's no player '" +
94 std::to_string(player_id) + "' in session '" +
95 session_id + "'");
96 }
97}
98
99game_state_error::game_state_error(std::string message)
100 : cavoke_base_exception(std::move(message), NotFound, "cavoke/state") {
101}
102
103} // namespace cavoke::server::model