@@ -2,7 +2,7 @@ use rand::{
2
2
seq:: { IteratorRandom , SliceRandom } ,
3
3
thread_rng,
4
4
} ;
5
- use rocket:: serde:: Serialize ;
5
+ use rocket:: serde:: { Deserialize , Serialize } ;
6
6
use std:: { collections:: HashMap , hash:: Hash } ;
7
7
8
8
macro_rules! repeated_vec {
@@ -21,19 +21,116 @@ macro_rules! repeated_vec {
21
21
} ;
22
22
}
23
23
24
- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize ) ]
24
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize , Deserialize ) ]
25
25
#[ serde( crate = "rocket::serde" ) ]
26
26
#[ serde( rename_all = "lowercase" ) ]
27
27
pub enum Team {
28
28
Sherlock ,
29
29
Moriarty ,
30
30
}
31
31
32
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize , Deserialize ) ]
33
+ #[ serde( crate = "rocket::serde" ) ]
34
+ #[ serde( rename_all = "lowercase" ) ]
35
+ pub enum Cable {
36
+ Safe ,
37
+ Defusing ,
38
+ Bomb ,
39
+ }
40
+
32
41
pub trait Player {
33
42
type ID : Eq + Hash + Clone + Copy ;
34
43
35
44
fn id ( & self ) -> Self :: ID ;
45
+ }
46
+
47
+ pub trait Room < PLAYER : Player > {
48
+ fn name ( & self ) -> & str ;
49
+ fn players ( & self ) -> & HashMap < PLAYER :: ID , PLAYER > ;
50
+ fn get_player ( & self , id : PLAYER :: ID ) -> Option < & PLAYER > ;
51
+ fn get_player_mut ( & mut self , id : PLAYER :: ID ) -> Option < & mut PLAYER > ;
52
+ }
53
+
54
+ pub trait WaitingPlayer : Player {
36
55
fn ready ( & self ) -> bool ;
56
+ }
57
+
58
+ pub struct Lobby < PLAYER : WaitingPlayer > {
59
+ name : String ,
60
+ players : HashMap < PLAYER :: ID , PLAYER > ,
61
+ }
62
+
63
+ impl < PLAYER : WaitingPlayer > Lobby < PLAYER > {
64
+ pub fn new ( name : String ) -> Self {
65
+ Self {
66
+ name,
67
+ players : HashMap :: new ( ) ,
68
+ }
69
+ }
70
+
71
+ pub fn add_player ( & mut self , player : PLAYER ) -> Result < ( ) , errors:: Join > {
72
+ if self . players . len ( ) >= 8 {
73
+ return Err ( errors:: Join :: GameFull ) ;
74
+ }
75
+
76
+ if self . players . contains_key ( & player. id ( ) ) {
77
+ return Err ( errors:: Join :: AlreadyConnected ) ;
78
+ }
79
+ self . players . insert ( player. id ( ) , player) ;
80
+
81
+ Ok ( ( ) )
82
+ }
83
+
84
+ pub fn remove_player ( & mut self , id : PLAYER :: ID ) {
85
+ self . players . remove ( & id) ;
86
+ }
87
+ }
88
+
89
+ impl < PLAYER : WaitingPlayer > Room < PLAYER > for Lobby < PLAYER > {
90
+ fn name ( & self ) -> & str {
91
+ & self . name
92
+ }
93
+
94
+ fn players ( & self ) -> & HashMap < PLAYER :: ID , PLAYER > {
95
+ & self . players
96
+ }
97
+
98
+ fn get_player ( & self , id : PLAYER :: ID ) -> Option < & PLAYER > {
99
+ self . players . get ( & id)
100
+ }
101
+
102
+ fn get_player_mut ( & mut self , id : PLAYER :: ID ) -> Option < & mut PLAYER > {
103
+ self . players . get_mut ( & id)
104
+ }
105
+ }
106
+
107
+ pub mod errors {
108
+ use thiserror:: Error ;
109
+
110
+ #[ derive( Error , Debug , Clone , Copy ) ]
111
+ pub enum Join {
112
+ #[ error( "this game is already full" ) ]
113
+ GameFull ,
114
+ #[ error( "you are already connected to this game" ) ]
115
+ AlreadyConnected ,
116
+ }
117
+ }
118
+
119
+ //
120
+ //
121
+ //
122
+ //
123
+ //
124
+ //
125
+ //
126
+ //
127
+ //
128
+ //
129
+ //
130
+ //
131
+ //
132
+
133
+ pub trait OldPlayer : WaitingPlayer {
37
134
fn connected ( & self ) -> bool ;
38
135
39
136
fn team ( & self ) -> Team ;
@@ -44,22 +141,13 @@ pub trait Player {
44
141
fn cables ( & self ) -> & [ Cable ] ;
45
142
}
46
143
47
- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize ) ]
48
- #[ serde( crate = "rocket::serde" ) ]
49
- #[ serde( rename_all = "lowercase" ) ]
50
- pub enum Cable {
51
- Safe ,
52
- Defusing ,
53
- Bomb ,
54
- }
55
-
56
144
pub enum CutOutcome {
57
145
Win ( Team ) ,
58
146
RoundEnd ,
59
147
Nothing ,
60
148
}
61
149
62
- enum GameState < PLAYER : Player > {
150
+ enum GameState < PLAYER : OldPlayer > {
63
151
Lobby ,
64
152
Ingame {
65
153
wire_cutters : PLAYER :: ID ,
@@ -68,57 +156,44 @@ enum GameState<PLAYER: Player> {
68
156
} ,
69
157
}
70
158
71
- pub struct Game < PLAYER : Player > {
159
+ pub struct Game < PLAYER : OldPlayer > {
72
160
name : String ,
73
161
players : HashMap < PLAYER :: ID , PLAYER > ,
74
162
state : GameState < PLAYER > ,
75
163
}
76
164
77
- impl < PLAYER : Player > Game < PLAYER > {
78
- pub fn new ( name : String ) -> Self {
79
- Self {
80
- name,
81
- players : HashMap :: new ( ) ,
82
- state : GameState :: Lobby ,
83
- }
84
- }
85
-
86
- pub fn name ( & self ) -> & str {
165
+ impl < PLAYER : Player + OldPlayer > Room < PLAYER > for Game < PLAYER > {
166
+ fn name ( & self ) -> & str {
87
167
& self . name
88
168
}
89
169
90
- pub const fn wire_cutters ( & self ) -> Option < PLAYER :: ID > {
91
- if let GameState :: Ingame { wire_cutters, .. } = self . state {
92
- Some ( wire_cutters)
93
- } else {
94
- None
95
- }
96
- }
97
-
98
- pub const fn players ( & self ) -> & HashMap < PLAYER :: ID , PLAYER > {
170
+ fn players ( & self ) -> & HashMap < PLAYER :: ID , PLAYER > {
99
171
& self . players
100
172
}
101
173
102
- pub fn get_player ( & self , id : PLAYER :: ID ) -> Option < & PLAYER > {
174
+ fn get_player ( & self , id : PLAYER :: ID ) -> Option < & PLAYER > {
103
175
self . players . get ( & id)
104
176
}
105
177
106
- pub fn get_player_mut ( & mut self , id : PLAYER :: ID ) -> Option < & mut PLAYER > {
178
+ fn get_player_mut ( & mut self , id : PLAYER :: ID ) -> Option < & mut PLAYER > {
107
179
self . players . get_mut ( & id)
108
180
}
181
+ }
109
182
110
- pub fn add_player ( & mut self , player : PLAYER ) -> Result < ( ) , errors :: PlayerJoin > {
111
- match self . state {
112
- GameState :: Lobby { .. } => {
113
- if self . players . len ( ) >= 8 {
114
- return Err ( errors :: PlayerJoin :: GameFull ) ;
115
- }
116
-
117
- self . players . entry ( player . id ( ) ) . or_insert ( player ) ;
183
+ impl < PLAYER : OldPlayer > Game < PLAYER > {
184
+ pub fn new ( name : String ) -> Self {
185
+ Self {
186
+ name ,
187
+ players : HashMap :: new ( ) ,
188
+ state : GameState :: Lobby ,
189
+ }
190
+ }
118
191
119
- Ok ( ( ) )
120
- }
121
- _ => Err ( errors:: PlayerJoin :: GameAlreadyStarted ) ,
192
+ pub const fn wire_cutters ( & self ) -> Option < PLAYER :: ID > {
193
+ if let GameState :: Ingame { wire_cutters, .. } = self . state {
194
+ Some ( wire_cutters)
195
+ } else {
196
+ None
122
197
}
123
198
}
124
199
@@ -147,12 +222,12 @@ impl<PLAYER: Player> Game<PLAYER> {
147
222
}
148
223
}
149
224
150
- pub fn start ( & mut self ) -> Result < ( ) , errors :: GameStart > {
225
+ pub fn start ( & mut self ) -> Result < ( ) , old_errors :: GameStart > {
151
226
if self . players . len ( ) < 4 {
152
- return Err ( errors :: GameStart :: NotEnoughPlayers ) ;
227
+ return Err ( old_errors :: GameStart :: NotEnoughPlayers ) ;
153
228
}
154
- if !self . players . values ( ) . all ( Player :: ready) {
155
- return Err ( errors :: GameStart :: NotAllPlayersReady ) ;
229
+ if !self . players . values ( ) . all ( WaitingPlayer :: ready) {
230
+ return Err ( old_errors :: GameStart :: NotAllPlayersReady ) ;
156
231
}
157
232
158
233
let mut teams = match self . players . len ( ) {
@@ -185,18 +260,18 @@ impl<PLAYER: Player> Game<PLAYER> {
185
260
& mut self ,
186
261
cutting : PLAYER :: ID ,
187
262
cutted : PLAYER :: ID ,
188
- ) -> Result < ( Cable , CutOutcome ) , errors :: Cut > {
263
+ ) -> Result < ( Cable , CutOutcome ) , old_errors :: Cut > {
189
264
if let GameState :: Ingame {
190
265
wire_cutters,
191
266
defusing_remaining,
192
267
cutted_count,
193
268
} = & mut self . state
194
269
{
195
270
if cutting != * wire_cutters {
196
- return Err ( errors :: Cut :: DontHaveWireCutter ) ;
271
+ return Err ( old_errors :: Cut :: DontHaveWireCutter ) ;
197
272
}
198
273
if cutted == cutting {
199
- return Err ( errors :: Cut :: CannotSelfCut ) ;
274
+ return Err ( old_errors :: Cut :: CannotSelfCut ) ;
200
275
}
201
276
202
277
let cable = self . players . get_mut ( & cutted) . unwrap ( ) . cut_cable ( ) ;
@@ -219,7 +294,7 @@ impl<PLAYER: Player> Game<PLAYER> {
219
294
Ok ( ( cable, CutOutcome :: Nothing ) )
220
295
}
221
296
} else {
222
- Err ( errors :: Cut :: GameNotStarted )
297
+ Err ( old_errors :: Cut :: GameNotStarted )
223
298
}
224
299
}
225
300
@@ -244,12 +319,7 @@ impl<PLAYER: Player> Game<PLAYER> {
244
319
}
245
320
}
246
321
247
- pub mod errors {
248
- pub enum PlayerJoin {
249
- GameFull ,
250
- GameAlreadyStarted ,
251
- }
252
-
322
+ pub mod old_errors {
253
323
pub enum GameStart {
254
324
NotEnoughPlayers ,
255
325
NotAllPlayersReady ,
0 commit comments