1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::collections::HashMap;
use std::fmt::Debug;
use serde::Serialize;
use serde::de::DeserializeOwned;
use serde_json::Value;
use serde_json;
use game::{GameWrapper, Game};
use errors::GameError;
use flow::UserFlow;
use state::UserState;
use actions::Action;
pub trait Store {
fn dispatch(&mut self, action: Action) -> Result<(), GameError>;
fn forfeit(&mut self, GameError);
fn get_state(&self) -> HashMap<u16, Value>;
fn get_move_names(&self) -> Vec<&'static str>;
fn get_player_id(&self) -> u16;
fn get_active_players(&self) -> Vec<u16>;
fn is_game_over(&self) -> bool;
}
pub trait StoreFactory {
fn create(&self, player_id: u16, players: Vec<u16>,
multiplayer: bool, server: bool, initialize: bool, seed: Option<u128>) -> Box<dyn Store>;
}
pub trait InnerStore<S: Default, T> {
fn new (game: Game<T>, player_id: u16, players: Vec<u16>,
multiplayer: bool, server: bool, initialize: bool) -> Self;
fn dispatch(&mut self, action: Action) -> Result<(), GameError>;
fn peek(&self) -> &UserState<S>;
fn reset(&mut self, state: UserState<S>);
fn forfeit(&mut self, GameError);
fn get_move_names(&self) -> Vec<&'static str>;
fn get_player_id(&self) -> u16;
fn get_active_players(&self) -> Vec<u16>;
fn is_game_over(&self) -> bool;
}
pub struct StoreImpl<S: Default, T> {
pub wrapper: GameWrapper<S, T>,
}
impl<S: Debug + Clone + Serialize + DeserializeOwned + Default, T: UserFlow<S>> InnerStore<S, T> for StoreImpl<S, T> {
fn new (game: Game<T>, player_id: u16, players: Vec<u16>,
multiplayer: bool, server: bool, initialize: bool) -> Self {
let wrapper = GameWrapper::new(game, player_id, players, multiplayer, server, initialize);
StoreImpl {
wrapper
}
}
fn dispatch(&mut self, action: Action) -> Result<(), GameError> {
self.wrapper.handle_action(action)
}
fn peek(&self) -> &UserState<S> {
self.wrapper.peek()
}
fn reset(&mut self, state: UserState<S>) {
self.wrapper.reset(state)
}
fn get_move_names(&self) -> Vec<&'static str> {
self.wrapper.game.flow.list_moves()
}
fn get_player_id(&self) -> u16 {
self.wrapper.player_id
}
fn get_active_players(&self) -> Vec<u16> {
self.wrapper.get_active_players()
}
fn is_game_over(&self) -> bool {
self.wrapper.is_game_over()
}
fn forfeit(&mut self, error: GameError) {
self.wrapper.forfeit(error)
}
}
impl<S: Default + Debug + Clone + Serialize + DeserializeOwned, T: UserFlow<S>> Store for StoreImpl<S, T> {
fn dispatch(&mut self, action: Action) -> Result<(), GameError> {
InnerStore::dispatch(self, action)
}
fn get_state(&self) -> HashMap<u16, Value> {
transform_state(self.wrapper.get_states())
}
fn get_move_names(&self) -> Vec<&'static str> {
InnerStore::get_move_names(self)
}
fn get_player_id(&self) -> u16 {
InnerStore::get_player_id(self)
}
fn get_active_players(&self) -> Vec<u16> {
InnerStore::get_active_players(self)
}
fn is_game_over(&self) -> bool {
InnerStore::is_game_over(self)
}
fn forfeit(&mut self, error: GameError) {
InnerStore::forfeit(self, error)
}
}
fn transform_state<S: Serialize + Default> (inner_state: HashMap<u16, UserState<S>>) -> HashMap<u16, Value> {
inner_state.iter()
.map(|(k, v)| (*k, serde_json::to_value(v).unwrap()))
.collect()
}