Skip to content

Commit 871acc7

Browse files
mayankkumar2Nick Vidal
authored andcommitted
feat: gamestate to hold state of the game
1 parent 3a767ac commit 871acc7

File tree

2 files changed

+67
-54
lines changed

2 files changed

+67
-54
lines changed

src/game_state.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use std::cell::RefCell;
2+
use std::rc::Rc;
3+
4+
pub struct GameState {
5+
pub guesses: Rc<RefCell<Vec<String>>>,
6+
pub matches: Rc<RefCell<Vec<String>>>,
7+
pub players: Rc<RefCell<Vec<String>>>,
8+
pub winners: Rc<RefCell<Vec<String>>>,
9+
pub letters: Rc<RefCell<Vec<String>>>,
10+
pub word: String,
11+
}
12+
13+
impl GameState {
14+
pub fn from(word: String) -> GameState {
15+
GameState {
16+
guesses: Rc::new(RefCell::new(vec![])),
17+
matches: Rc::new(RefCell::new(vec![])),
18+
players: Rc::new(RefCell::new(vec![])),
19+
winners: Rc::new(RefCell::new(vec![])),
20+
letters: Rc::new(RefCell::new(vec![String::new(); 5])),
21+
word,
22+
}
23+
}
24+
}

src/main.rs

Lines changed: 43 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
mod game_state;
2+
3+
use game_state::GameState;
14
use mini_http;
25
use mini_http::Server;
3-
use std::cell::RefCell;
4-
use std::rc::Rc;
56
use rand::Rng;
7+
use std::rc::Rc;
68

79
// All the web server and network code by Harald H.
810
// https://github.com/haraldh
@@ -35,7 +37,7 @@ const NOT_FOUND: &str = r#"
3537
// y (yellow): right letter, wrong position
3638
// g (green): letter at the right position
3739

38-
fn check_single(query: Option<&str>, the_word: String) -> Vec<u8> {
40+
fn check_single(query: Option<&str>, state: Rc<GameState>) -> Vec<u8> {
3941
let mut response = vec![b'c'; 5];
4042

4143
// Get guess parameter
@@ -47,14 +49,16 @@ fn check_single(query: Option<&str>, the_word: String) -> Vec<u8> {
4749
let guess = the_guess_parts.1;
4850
//println!("The guess: {}", guess);
4951

50-
let guess_size:usize = guess.len() as usize;
52+
let guess_size: usize = guess.len() as usize;
5153
if guess_size == 5 {
5254
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] {
5456
response[letter_index] = b'g';
5557
} 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+
{
5862
response[letter_index] = b'y';
5963
}
6064
}
@@ -73,7 +77,7 @@ fn check_single(query: Option<&str>, the_word: String) -> Vec<u8> {
7377
// p (purple): word match
7478
// r (red): word was already a match
7579

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> {
7781
let mut response = vec![b'c'; 5];
7882

7983
// Get guess and player parameters
@@ -90,13 +94,13 @@ fn check_multi(query: Option<&str>, guesses: Rc<RefCell<Vec<String>>>, matches:
9094
//println!("The player: {}", player);
9195

9296
// Wrong word size
93-
let word_size:usize = guess.len() as usize;
97+
let word_size: usize = guess.len() as usize;
9498
if word_size != 5 {
95-
return response;
99+
return response;
96100
}
97101

98102
// 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);
100104
if matches_index.is_some() {
101105
response = vec![b'r'; 5];
102106
return response;
@@ -105,53 +109,53 @@ fn check_multi(query: Option<&str>, guesses: Rc<RefCell<Vec<String>>>, matches:
105109
// Check letters
106110
for letter_index in 0..word_size {
107111
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);
109115
if found_char {
110116
response[letter_index] = b'b';
111117
} 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());
113119
}
114120
}
115121

116122
// 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);
118124
if guesses_index.is_some() {
119-
120125
// 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()];
122127
if winner == player {
123128
response = vec![b'r'; 5];
124129
return response;
125130
}
126-
131+
127132
// Push word to matches
128-
matches.borrow_mut().push(guess.to_string());
133+
state.matches.borrow_mut().push(guess.to_string());
129134
response = vec![b'p'; 5];
130135
//println!("New match: {}", guess.to_string());
131136

132137
// 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());
135140
//println!("Winners: {}, {}", player.to_string(), winner.to_string());
136141
} else {
137142
// 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());
140145
//println!("New word: {}", guess.to_string());
141146
}
142-
143147
}
144148

145149
return response;
146150
}
147151

148-
fn check_winners(winners: Rc<RefCell<Vec<String>>>) -> Vec<u8> {
152+
fn check_winners(state: Rc<GameState>) -> Vec<u8> {
149153
let mut response = String::from("");
150154
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;
152156

153157
for winners_index in 0..winners_size {
154-
let winner = &winners.borrow_mut()[winners_index];
158+
let winner = &state.winners.borrow()[winners_index];
155159
if response == "" {
156160
response = winner.to_string();
157161
} else {
@@ -162,13 +166,13 @@ fn check_winners(winners: Rc<RefCell<Vec<String>>>) -> Vec<u8> {
162166
return response.as_bytes().to_vec();
163167
}
164168

165-
fn check_matches(matches: Rc<RefCell<Vec<String>>>) -> Vec<u8> {
169+
fn check_matches(state: Rc<GameState>) -> Vec<u8> {
166170
let mut response = String::from("");
167171
let comma = String::from(", ");
168-
let matches_size:usize = matches.borrow_mut().len() as usize;
172+
let matches_size = state.matches.borrow().len();
169173

170174
for matches_index in 0..matches_size {
171-
let matched = &matches.borrow_mut()[matches_index];
175+
let matched = &state.matches.borrow()[matches_index];
172176
if response == "" {
173177
response = matched.to_string();
174178
} else {
@@ -179,8 +183,6 @@ fn check_matches(matches: Rc<RefCell<Vec<String>>>) -> Vec<u8> {
179183
return response.as_bytes().to_vec();
180184
}
181185

182-
183-
184186
#[cfg(target_os = "wasi")]
185187
fn get_server() -> Server {
186188
mini_http::Server::preopened().unwrap()
@@ -192,37 +194,24 @@ fn get_server() -> Server {
192194
}
193195

194196
fn run() -> Result<(), Box<dyn std::error::Error>> {
195-
196197
// Generate random number from word list
197198
const WORDLIST: &str = include_str!("../client/wordList.txt");
198199

199200
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);
201202

202-
while WORDLIST.as_bytes()[random_index] != 0x0A { // check for newline
203+
while WORDLIST.as_bytes()[random_index] != 0x0A {
204+
// check for newline
203205
random_index += 1;
204206
}
205207
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];
207209
let the_word_copy: &'static str = the_word_static.clone();
208210
let the_word_string = the_word_copy.to_lowercase();
209211

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);
218213

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));
226215

227216
// Run server
228217
get_server()
@@ -241,22 +230,22 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
241230
"/single" => mini_http::Response::builder()
242231
.status(200)
243232
.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()))
245234
.unwrap(),
246235
"/multi" => mini_http::Response::builder()
247236
.status(200)
248237
.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()))
250239
.unwrap(),
251240
"/winners" => mini_http::Response::builder()
252241
.status(200)
253242
.header("Content-Type", "text/plain")
254-
.body(check_winners(winners.clone()))
243+
.body(check_winners(state.clone()))
255244
.unwrap(),
256245
"/matches" => mini_http::Response::builder()
257246
.status(200)
258247
.header("Content-Type", "text/plain")
259-
.body(check_matches(matches.clone()))
248+
.body(check_matches(state.clone()))
260249
.unwrap(),
261250
"/" => mini_http::Response::builder()
262251
.status(200)

0 commit comments

Comments
 (0)