1
+ mod game_state;
2
+
3
+ use game_state:: GameState ;
1
4
use mini_http;
2
5
use mini_http:: Server ;
3
- use std:: cell:: RefCell ;
4
- use std:: rc:: Rc ;
5
6
use rand:: Rng ;
7
+ use std:: rc:: Rc ;
6
8
7
9
// All the web server and network code by Harald H.
8
10
// https://github.com/haraldh
@@ -35,7 +37,7 @@ const NOT_FOUND: &str = r#"
35
37
// y (yellow): right letter, wrong position
36
38
// g (green): letter at the right position
37
39
38
- fn check_single ( query : Option < & str > , the_word : String ) -> Vec < u8 > {
40
+ fn check_single ( query : Option < & str > , state : Rc < GameState > ) -> Vec < u8 > {
39
41
let mut response = vec ! [ b'c' ; 5 ] ;
40
42
41
43
// Get guess parameter
@@ -47,14 +49,16 @@ fn check_single(query: Option<&str>, the_word: String) -> Vec<u8> {
47
49
let guess = the_guess_parts. 1 ;
48
50
//println!("The guess: {}", guess);
49
51
50
- let guess_size: usize = guess. len ( ) as usize ;
52
+ let guess_size: usize = guess. len ( ) as usize ;
51
53
if guess_size == 5 {
52
54
for letter_index in 0 ..guess_size {
53
- if guess. as_bytes ( ) [ letter_index] == the_word . as_bytes ( ) [ letter_index] {
55
+ if guess. as_bytes ( ) [ letter_index] == state . word . as_bytes ( ) [ letter_index] {
54
56
response[ letter_index] = b'g' ;
55
57
} else {
56
- for letter_byte in the_word. as_bytes ( ) {
57
- if guess. as_bytes ( ) [ letter_index] . eq ( letter_byte) && response[ letter_index] == b'c' {
58
+ for letter_byte in state. word . as_bytes ( ) {
59
+ if guess. as_bytes ( ) [ letter_index] . eq ( letter_byte)
60
+ && response[ letter_index] == b'c'
61
+ {
58
62
response[ letter_index] = b'y' ;
59
63
}
60
64
}
@@ -73,7 +77,7 @@ fn check_single(query: Option<&str>, the_word: String) -> Vec<u8> {
73
77
// p (purple): word match
74
78
// r (red): word was already a match
75
79
76
- fn check_multi ( query : Option < & str > , guesses : Rc < RefCell < Vec < String > > > , matches : Rc < RefCell < Vec < String > > > , letters : Rc < RefCell < Vec < String > > > , players : Rc < RefCell < Vec < String > > > , winners : Rc < RefCell < Vec < String > > > ) -> Vec < u8 > {
80
+ fn check_multi ( query : Option < & str > , state : Rc < GameState > ) -> Vec < u8 > {
77
81
let mut response = vec ! [ b'c' ; 5 ] ;
78
82
79
83
// Get guess and player parameters
@@ -90,13 +94,13 @@ fn check_multi(query: Option<&str>, guesses: Rc<RefCell<Vec<String>>>, matches:
90
94
//println!("The player: {}", player);
91
95
92
96
// Wrong word size
93
- let word_size: usize = guess. len ( ) as usize ;
97
+ let word_size: usize = guess. len ( ) as usize ;
94
98
if word_size != 5 {
95
- return response;
99
+ return response;
96
100
}
97
101
98
102
// Check if this word was already a match
99
- let matches_index = matches. borrow_mut ( ) . iter ( ) . position ( |x| x == guess) ;
103
+ let matches_index = state . matches . borrow ( ) . iter ( ) . position ( |x| x == guess) ;
100
104
if matches_index. is_some ( ) {
101
105
response = vec ! [ b'r' ; 5 ] ;
102
106
return response;
@@ -105,53 +109,53 @@ fn check_multi(query: Option<&str>, guesses: Rc<RefCell<Vec<String>>>, matches:
105
109
// Check letters
106
110
for letter_index in 0 ..word_size {
107
111
let letter_char = guess. as_bytes ( ) [ letter_index] as char ;
108
- let found_char = letters. borrow_mut ( ) [ letter_index] . chars ( ) . any ( |ch| ch == letter_char) ;
112
+ let found_char = state. letters . borrow ( ) [ letter_index]
113
+ . chars ( )
114
+ . any ( |ch| ch == letter_char) ;
109
115
if found_char {
110
116
response[ letter_index] = b'b' ;
111
117
} else {
112
- letters. borrow_mut ( ) [ letter_index] . push_str ( & letter_char. to_string ( ) ) ;
118
+ state . letters . borrow_mut ( ) [ letter_index] . push_str ( & letter_char. to_string ( ) ) ;
113
119
}
114
120
}
115
121
116
122
// Check if this word is a new match
117
- let guesses_index = guesses. borrow_mut ( ) . iter ( ) . position ( |x| x == guess) ;
123
+ let guesses_index = state . guesses . borrow ( ) . iter ( ) . position ( |x| x == guess) ;
118
124
if guesses_index. is_some ( ) {
119
-
120
125
// Check if it matches a previous guess from the player
121
- let winner = & players. borrow_mut ( ) [ guesses_index. unwrap ( ) ] ;
126
+ let winner = & state . players . borrow ( ) [ guesses_index. unwrap ( ) ] ;
122
127
if winner == player {
123
128
response = vec ! [ b'r' ; 5 ] ;
124
129
return response;
125
130
}
126
-
131
+
127
132
// Push word to matches
128
- matches. borrow_mut ( ) . push ( guess. to_string ( ) ) ;
133
+ state . matches . borrow_mut ( ) . push ( guess. to_string ( ) ) ;
129
134
response = vec ! [ b'p' ; 5 ] ;
130
135
//println!("New match: {}", guess.to_string());
131
136
132
137
// Push winners
133
- winners. borrow_mut ( ) . push ( player. to_string ( ) ) ;
134
- winners. borrow_mut ( ) . push ( winner. to_string ( ) ) ;
138
+ state . winners . borrow_mut ( ) . push ( player. to_string ( ) ) ;
139
+ state . winners . borrow_mut ( ) . push ( winner. to_string ( ) ) ;
135
140
//println!("Winners: {}, {}", player.to_string(), winner.to_string());
136
141
} else {
137
142
// Push new word to guesses
138
- guesses. borrow_mut ( ) . push ( guess. to_string ( ) ) ;
139
- players. borrow_mut ( ) . push ( player. to_string ( ) ) ;
143
+ state . guesses . borrow_mut ( ) . push ( guess. to_string ( ) ) ;
144
+ state . players . borrow_mut ( ) . push ( player. to_string ( ) ) ;
140
145
//println!("New word: {}", guess.to_string());
141
146
}
142
-
143
147
}
144
148
145
149
return response;
146
150
}
147
151
148
- fn check_winners ( winners : Rc < RefCell < Vec < String > > > ) -> Vec < u8 > {
152
+ fn check_winners ( state : Rc < GameState > ) -> Vec < u8 > {
149
153
let mut response = String :: from ( "" ) ;
150
154
let comma = String :: from ( ", " ) ;
151
- let winners_size: usize = winners. borrow_mut ( ) . len ( ) as usize ;
155
+ let winners_size: usize = state . winners . borrow ( ) . len ( ) as usize ;
152
156
153
157
for winners_index in 0 ..winners_size {
154
- let winner = & winners. borrow_mut ( ) [ winners_index] ;
158
+ let winner = & state . winners . borrow ( ) [ winners_index] ;
155
159
if response == "" {
156
160
response = winner. to_string ( ) ;
157
161
} else {
@@ -162,13 +166,13 @@ fn check_winners(winners: Rc<RefCell<Vec<String>>>) -> Vec<u8> {
162
166
return response. as_bytes ( ) . to_vec ( ) ;
163
167
}
164
168
165
- fn check_matches ( matches : Rc < RefCell < Vec < String > > > ) -> Vec < u8 > {
169
+ fn check_matches ( state : Rc < GameState > ) -> Vec < u8 > {
166
170
let mut response = String :: from ( "" ) ;
167
171
let comma = String :: from ( ", " ) ;
168
- let matches_size: usize = matches. borrow_mut ( ) . len ( ) as usize ;
172
+ let matches_size = state . matches . borrow ( ) . len ( ) ;
169
173
170
174
for matches_index in 0 ..matches_size {
171
- let matched = & matches. borrow_mut ( ) [ matches_index] ;
175
+ let matched = & state . matches . borrow ( ) [ matches_index] ;
172
176
if response == "" {
173
177
response = matched. to_string ( ) ;
174
178
} else {
@@ -179,8 +183,6 @@ fn check_matches(matches: Rc<RefCell<Vec<String>>>) -> Vec<u8> {
179
183
return response. as_bytes ( ) . to_vec ( ) ;
180
184
}
181
185
182
-
183
-
184
186
#[ cfg( target_os = "wasi" ) ]
185
187
fn get_server ( ) -> Server {
186
188
mini_http:: Server :: preopened ( ) . unwrap ( )
@@ -192,37 +194,24 @@ fn get_server() -> Server {
192
194
}
193
195
194
196
fn run ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
195
-
196
197
// Generate random number from word list
197
198
const WORDLIST : & str = include_str ! ( "../client/wordList.txt" ) ;
198
199
199
200
let mut rng = rand:: thread_rng ( ) ;
200
- let mut random_index: usize = rng. gen_range ( 0 ..WORDLIST . len ( ) / 6 ) ;
201
+ let mut random_index: usize = rng. gen_range ( 0 ..WORDLIST . len ( ) / 6 ) ;
201
202
202
- while WORDLIST . as_bytes ( ) [ random_index] != 0x0A { // check for newline
203
+ while WORDLIST . as_bytes ( ) [ random_index] != 0x0A {
204
+ // check for newline
203
205
random_index += 1 ;
204
206
}
205
207
random_index += 1 ;
206
- let the_word_static = & WORDLIST [ random_index..random_index+ 5 ] ;
208
+ let the_word_static = & WORDLIST [ random_index..random_index + 5 ] ;
207
209
let the_word_copy: & ' static str = the_word_static. clone ( ) ;
208
210
let the_word_string = the_word_copy. to_lowercase ( ) ;
209
211
210
- //println!("The word: {}", the_word_string);
211
-
212
-
213
- // Vectors for multi-player mode
214
- let guesses = Rc :: new ( RefCell :: new ( Vec :: < String > :: new ( ) ) ) ;
215
- let matches = Rc :: new ( RefCell :: new ( Vec :: < String > :: new ( ) ) ) ;
216
- let players = Rc :: new ( RefCell :: new ( Vec :: < String > :: new ( ) ) ) ;
217
- let winners = Rc :: new ( RefCell :: new ( Vec :: < String > :: new ( ) ) ) ;
212
+ // ("The word: {}", the_word_string);
218
213
219
- // Letters vector with 5 elements [a..z, a..z, a..z, a..z, a..z]
220
- let letters = Rc :: new ( RefCell :: new ( Vec :: < String > :: new ( ) ) ) ;
221
- letters. borrow_mut ( ) . push ( "" . to_string ( ) ) ;
222
- letters. borrow_mut ( ) . push ( "" . to_string ( ) ) ;
223
- letters. borrow_mut ( ) . push ( "" . to_string ( ) ) ;
224
- letters. borrow_mut ( ) . push ( "" . to_string ( ) ) ;
225
- letters. borrow_mut ( ) . push ( "" . to_string ( ) ) ;
214
+ let state: Rc < GameState > = Rc :: new ( GameState :: from ( the_word_string) ) ;
226
215
227
216
// Run server
228
217
get_server ( )
@@ -241,22 +230,22 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
241
230
"/single" => mini_http:: Response :: builder ( )
242
231
. status ( 200 )
243
232
. header ( "Content-Type" , "text/plain" )
244
- . body ( check_single ( req. uri ( ) . query ( ) , the_word_string . clone ( ) ) )
233
+ . body ( check_single ( req. uri ( ) . query ( ) , state . clone ( ) ) )
245
234
. unwrap ( ) ,
246
235
"/multi" => mini_http:: Response :: builder ( )
247
236
. status ( 200 )
248
237
. header ( "Content-Type" , "text/plain" )
249
- . body ( check_multi ( req. uri ( ) . query ( ) , guesses . clone ( ) , matches . clone ( ) , letters . clone ( ) , players . clone ( ) , winners . clone ( ) ) )
238
+ . body ( check_multi ( req. uri ( ) . query ( ) , state . clone ( ) ) )
250
239
. unwrap ( ) ,
251
240
"/winners" => mini_http:: Response :: builder ( )
252
241
. status ( 200 )
253
242
. header ( "Content-Type" , "text/plain" )
254
- . body ( check_winners ( winners . clone ( ) ) )
243
+ . body ( check_winners ( state . clone ( ) ) )
255
244
. unwrap ( ) ,
256
245
"/matches" => mini_http:: Response :: builder ( )
257
246
. status ( 200 )
258
247
. header ( "Content-Type" , "text/plain" )
259
- . body ( check_matches ( matches . clone ( ) ) )
248
+ . body ( check_matches ( state . clone ( ) ) )
260
249
. unwrap ( ) ,
261
250
"/" => mini_http:: Response :: builder ( )
262
251
. status ( 200 )
0 commit comments