Browse Source

way better

Nicolas Winkler 4 years ago
parent
commit
f8a2fbec06
4 changed files with 317 additions and 64 deletions
  1. 61 25
      src/game.rs
  2. 180 38
      src/server.rs
  3. 11 0
      src/websocket.rs
  4. 65 1
      static/index.html

+ 61 - 25
src/game.rs

@@ -6,6 +6,7 @@ use crate::server;
 
 
 #[derive(Serialize, Deserialize, Clone, PartialEq)]
 #[derive(Serialize, Deserialize, Clone, PartialEq)]
 pub enum GameState {
 pub enum GameState {
+    Starting,
     Creating,
     Creating,
     Guessing
     Guessing
 }
 }
@@ -16,25 +17,19 @@ pub struct CreatingEx {
     pub letters: Vec<char>
     pub letters: Vec<char>
 }
 }
 
 
-#[derive(Serialize, Deserialize, Clone)]
-pub struct Round {
-    pub exercises: Vec<CreatingEx>
-}
-
 #[derive(Serialize, Clone)]
 #[derive(Serialize, Clone)]
 pub struct Player {
 pub struct Player {
     pub nick: String,
     pub nick: String,
+    pub creating_exercise: Option<CreatingEx>,
     pub submitted_word: Option<String>,
     pub submitted_word: Option<String>,
-    pub submitted_guess: Option<Vec<(String, String)>>,
+    pub submitted_guess: Option<Vec<(String, String)>>
 }
 }
 
 
 #[derive(Serialize, Clone)]
 #[derive(Serialize, Clone)]
 pub struct Game {
 pub struct Game {
     pub players: Vec<Player>,
     pub players: Vec<Player>,
     pub round_number: i32,
     pub round_number: i32,
-
-    #[serde(skip_serializing)]
-    pub round: Round,
+    pub additional_questions: Vec<CreatingEx>,
 
 
     pub state: GameState,
     pub state: GameState,
 }
 }
@@ -43,10 +38,10 @@ pub struct Game {
 impl Game {
 impl Game {
     pub fn new() -> Self {
     pub fn new() -> Self {
         Self {
         Self {
-            players: vec![],
+            players: Vec::new(),
             round_number: 0,
             round_number: 0,
-            round: Round{ exercises: vec![] },
-            state: GameState::Creating
+            additional_questions: Vec::new(),
+            state: GameState::Starting
         }
         }
     }
     }
 
 
@@ -84,15 +79,13 @@ impl Game {
         }
         }
     }
     }
 
 
-    pub fn all_submitted(&self) -> bool {
-        match self.state {
-            GameState::Creating => {
-                self.players.iter().map(|p| p.submitted_word.is_some()).fold(true, |a, b| a && b)
-            },
-            GameState::Guessing => {
-                self.players.iter().map(|p| p.submitted_guess.is_some()).fold(true, |a, b| a && b)
-            }
-        }
+    pub fn all_words_submitted(&self) -> bool {
+        self.state == GameState::Creating &&
+            self.players.iter().map(|p| p.submitted_word.is_some()).fold(true, |a, b| a && b)
+    }
+    pub fn all_guesses_submitted(&self) -> bool {
+        self.state == GameState::Guessing &&
+            self.players.iter().map(|p| p.submitted_guess.is_some()).fold(true, |a, b| a && b)
     }
     }
 
 
     pub fn next_state(&mut self) {
     pub fn next_state(&mut self) {
@@ -100,29 +93,72 @@ impl Game {
             self.clear_submissions();
             self.clear_submissions();
         }
         }
         self.state = match self.state {
         self.state = match self.state {
+            GameState::Starting => GameState::Creating,
             GameState::Creating => GameState::Guessing,
             GameState::Creating => GameState::Guessing,
-            GameState::Guessing => GameState::Creating
+            GameState::Guessing => GameState::Starting
         }
         }
     }
     }
 
 
-    pub fn new_round(&mut self) {
-        self.round.exercises = vec![
+    pub fn start_round(&mut self) {
+        self.clear_submissions();
+
+        let mut exes = vec![
             CreatingEx{ question: "An Alphabet".to_owned(), letters: vec!['a', 'b', 'c'] },
             CreatingEx{ question: "An Alphabet".to_owned(), letters: vec!['a', 'b', 'c'] },
             CreatingEx{ question: "A Betabet".to_owned(), letters: vec!['b', 'c', 'd'] },
             CreatingEx{ question: "A Betabet".to_owned(), letters: vec!['b', 'c', 'd'] },
             CreatingEx{ question: "A Gammaabet".to_owned(), letters: vec!['c', 'd', 'e'] },
             CreatingEx{ question: "A Gammaabet".to_owned(), letters: vec!['c', 'd', 'e'] },
             CreatingEx{ question: "A Deltaabet".to_owned(), letters: vec!['d', 'e', 'f'] },
             CreatingEx{ question: "A Deltaabet".to_owned(), letters: vec!['d', 'e', 'f'] },
         ];
         ];
+        for p in &mut self.players {
+            p.creating_exercise = exes.pop();
+        }
+        self.additional_questions.clear();
+        self.additional_questions.append(&mut exes);
+        self.state = GameState::Creating;
     }
     }
 
 
     pub fn clear_submissions(&mut self) {
     pub fn clear_submissions(&mut self) {
         for p in &mut self.players {
         for p in &mut self.players {
             p.submitted_word = None;
             p.submitted_word = None;
             p.submitted_guess = None;
             p.submitted_guess = None;
+            p.creating_exercise = None;
         }
         }
     }
     }
 
 
     pub fn player_join(&mut self, nick: String) {
     pub fn player_join(&mut self, nick: String) {
-        self.players.push(Player{ nick: nick, submitted_word: None, submitted_guess: None });
+        self.players.push(Player{
+            nick: nick,
+            creating_exercise: None,
+            submitted_word: None,
+            submitted_guess: None
+        });
+    }
+
+    pub fn create_results(&self) -> Vec<Vec<Vec<String>>> {
+        let mut result: Vec<Vec<Vec<String>>> = Vec::new();
+        let mut questions = self.players.iter()
+                        .map(|p| p.creating_exercise.clone().unwrap().question)
+                        .collect::<Vec<_>>();
+        questions.append(&mut self.additional_questions.iter()
+                                .map(|x| x.question.clone())
+                                .collect::<Vec<_>>()
+                        );
+        for player in &self.players {
+            let mut line: Vec<Vec<String>> = Vec::new();
+            let word = player.submitted_word.as_ref().unwrap();
+            for question in &questions {
+                let mut cell: Vec<String> = Vec::new();
+                for p in &self.players {
+                    if let Some(guess) = &p.submitted_guess {
+                        if let Some(_corr) = guess.iter().find(|(w, q)| w == word && q == question) {
+                            cell.push(p.nick.clone());
+                        }
+                    }
+                }
+                line.push(cell);
+            }
+            result.push(line);
+        }
+        return result;
     }
     }
 }
 }
 
 

+ 180 - 38
src/server.rs

@@ -25,12 +25,27 @@ struct CreateLobbyRequest{ lobby_id: String, p: Addr<GameConnection> }
 
 
 #[derive(Message)]
 #[derive(Message)]
 #[rtype(result = "()")]
 #[rtype(result = "()")]
+struct ReadyMsg(String);
+
+#[derive(Message)]
+#[rtype(result = "()")]
 struct SubmitWordMsg{ word: String, nick: String }
 struct SubmitWordMsg{ word: String, nick: String }
 
 
 #[derive(Message)]
 #[derive(Message)]
+#[rtype(result = "()")]
+struct SubmitGuessMsg{ guesses: Vec<(String, String)>, nick: String }
+
+#[derive(Message)]
+#[rtype(result = "()")]
+struct ResultMsg{ results: RoundResultData }
+
+#[derive(Message)]
 #[rtype(result = "Result<game::Game, ()>")]
 #[rtype(result = "Result<game::Game, ()>")]
 struct GetGame;
 struct GetGame;
 
 
+#[derive(Message)]
+#[rtype(result = "()")]
+struct NoSuchLobby(String);
 
 
 #[derive(Message)]
 #[derive(Message)]
 #[rtype(result = "()")]
 #[rtype(result = "()")]
@@ -92,7 +107,10 @@ impl Handler<JoinRequest> for Server {
                 let _sent = lobby.do_send(jr);
                 let _sent = lobby.do_send(jr);
                 Answer::LobbyJoined(lobby.clone())
                 Answer::LobbyJoined(lobby.clone())
             },
             },
-            None => Answer::NoSuchLobby
+            None => {
+                jr.p.do_send(NoSuchLobby(jr.lobby_id));
+                Answer::NoSuchLobby
+            }
         }
         }
     }
     }
 }
 }
@@ -113,27 +131,57 @@ impl Handler<CreateLobbyRequest> for Server {
     }
     }
 }
 }
 
 
+#[derive(PartialEq)]
+enum LobbyState {
+    Starting,
+    Creating,
+    Guessing,
+    Revealing
+}
+
 pub struct GameLobby {
 pub struct GameLobby {
     connected_players: BTreeMap<String, Addr<GameConnection>>,
     connected_players: BTreeMap<String, Addr<GameConnection>>,
     game_id: String,
     game_id: String,
     game: game::Game,
     game: game::Game,
+    waiting_players: BTreeMap<String, Addr<GameConnection>>,
+    ready_players: Vec<String>,
+    lobby_state: LobbyState
 }
 }
 
 
 impl Actor for GameLobby {
 impl Actor for GameLobby {
     type Context = Context<Self>;
     type Context = Context<Self>;
     fn started(&mut self, ctx: &mut Self::Context) {
     fn started(&mut self, ctx: &mut Self::Context) {
-        self.game.new_round();
+        self.game.start_round();
     }
     }
 }
 }
 
 
 impl Handler<JoinRequest> for GameLobby {
 impl Handler<JoinRequest> for GameLobby {
     type Result = Answer;
     type Result = Answer;
     fn handle(&mut self, jr: JoinRequest, ctx: &mut Self::Context) -> Self::Result {
     fn handle(&mut self, jr: JoinRequest, ctx: &mut Self::Context) -> Self::Result {
-        jr.p.do_send(LobbyJoined(ctx.address()));
-        self.connected_players.insert(jr.nick.clone(), jr.p);
-        self.game.player_join(jr.nick);
-        self.send_game_to_all();
-        Answer::LobbyJoined(ctx.address())
+        if self.lobby_state == LobbyState::Starting {
+            jr.p.do_send(LobbyJoined(ctx.address()));
+            self.connected_players.insert(jr.nick.clone(), jr.p);
+            self.game.player_join(jr.nick);
+            self.send_game_to_all();
+            Answer::LobbyJoined(ctx.address())
+        }
+        else {
+            self.waiting_players.insert(jr.nick.clone(), jr.p);
+            Answer::NoSuchLobby
+        }
+    }
+}
+
+impl Handler<ReadyMsg> for GameLobby {
+    type Result = ();
+    fn handle(&mut self, rm: ReadyMsg, ctx: &mut Self::Context) -> Self::Result {
+        if !self.ready_players.contains(&rm.0) {
+            self.ready_players.push(rm.0);
+        }
+        if self.ready_players.len() >= self.connected_players.len() {
+            self.set_state(LobbyState::Creating);
+            self.send_game_to_all();
+        }
     }
     }
 }
 }
 
 
@@ -148,7 +196,23 @@ impl Handler<SubmitWordMsg> for GameLobby {
     type Result = ();
     type Result = ();
     fn handle(&mut self, swm: SubmitWordMsg, ctx: &mut Self::Context) -> Self::Result {
     fn handle(&mut self, swm: SubmitWordMsg, ctx: &mut Self::Context) -> Self::Result {
         self.game.submit_creation(&swm.nick, swm.word);
         self.game.submit_creation(&swm.nick, swm.word);
-        if self.game.all_submitted() {
+        if self.game.all_words_submitted() {
+            self.set_state(LobbyState::Guessing);
+            self.game.next_state();
+            self.send_game_to_all();
+        }
+    }
+}
+
+impl Handler<SubmitGuessMsg> for GameLobby {
+    type Result = ();
+    fn handle(&mut self, sgm: SubmitGuessMsg, ctx: &mut Self::Context) -> Self::Result {
+        self.game.submit_guess(&sgm.nick, sgm.guesses);
+        if self.game.all_guesses_submitted() {
+            self.set_state(LobbyState::Revealing);
+            let results = self.create_result_data();
+            self.broadcast_results(results);
+
             self.game.next_state();
             self.game.next_state();
             self.send_game_to_all();
             self.send_game_to_all();
         }
         }
@@ -160,10 +224,30 @@ impl GameLobby {
         GameLobby {
         GameLobby {
             connected_players: BTreeMap::new(),
             connected_players: BTreeMap::new(),
             game_id: gi,
             game_id: gi,
-            game: game::Game::new()
+            game: game::Game::new(),
+            waiting_players: BTreeMap::new(),
+            ready_players: Vec::new(),
+            lobby_state: LobbyState::Starting,
         }
         }
     }
     }
 
 
+    fn set_state(&mut self, new_state: LobbyState) {
+        match new_state {
+            LobbyState::Starting => {
+                for (nick, _addr) in &self.waiting_players {
+                    self.game.player_join(nick.clone());
+                }
+                self.connected_players.append(&mut self.waiting_players);
+                self.ready_players.clear();
+            },
+            LobbyState::Creating => {
+                self.game.start_round();
+            },
+            _ => {}
+        }
+        self.lobby_state = new_state;
+    }
+
     pub fn send_game_to_all(&self) {
     pub fn send_game_to_all(&self) {
         for (nick, player) in &self.connected_players {
         for (nick, player) in &self.connected_players {
             let game_state = self.create_opaque_message(nick);
             let game_state = self.create_opaque_message(nick);
@@ -171,36 +255,74 @@ impl GameLobby {
         }
         }
     }
     }
 
 
+    pub fn create_result_data(&self) -> RoundResultData {
+        let results_table = self.game.create_results();
+
+        let words = self.game.players.iter()
+                        .map(|p| p.submitted_word.clone().unwrap())
+                        .collect::<Vec<_>>();
+        let questions = self.game.players.iter()
+                        .map(|x| x.creating_exercise.clone().unwrap().question)
+                        .collect::<Vec<_>>();
+        let solutions = words.iter()
+                        .map(|x| x.clone())
+                        .zip(questions.iter().map(|x| x.clone()))
+                        .collect::<Vec<_>>();
+
+        let guesses = self.game.create_results();
+
+        RoundResultData {
+            words,
+            questions,
+            solutions,
+            guesses
+        }
+    }
+
+    pub fn broadcast_results(&self, results: RoundResultData) {
+        for (_nick, player) in &self.connected_players {
+            player.do_send(ResultMsg{ results: results.clone() });
+        }
+    }
+
     pub fn create_opaque_message(&self, nick: &str) -> GameData {
     pub fn create_opaque_message(&self, nick: &str) -> GameData {
+
         GameData {
         GameData {
-            players: self.game.players.iter().map(|p| websocket::PlayerData{ nick: p.nick.clone(), points: 0 }).collect::<Vec<_>>(),
-            state_data: match self.game.state {
-                game::GameState::Creating => {
-                    GameStateData::Creating{
-                        question: "Ein Gerät um Elche zu häuten".to_owned(),
-                        available_chars: vec!['a', 'b', 'c']
-                    }
-                },
-                game::GameState::Guessing => {
-                    self.create_guessing()
-                },
-            }
+            players: self.game.players.iter()
+                        .map(|p| websocket::PlayerData{ nick: p.nick.clone(), points: 0 })
+                        .collect::<Vec<_>>(),
+            state_data:
+                match self.game.state {
+                    game::GameState::Starting => {
+                        GameStateData::Starting
+                    },
+                    game::GameState::Creating => {
+                        GameStateData::Creating{
+                            question: "Ein Gerät um Elche zu häuten".to_owned(),
+                            available_chars: vec!['a', 'b', 'c']
+                        }
+                    },
+                    game::GameState::Guessing => {
+                        self.create_guessing()
+                    },
+                }
         }
         }
     }
     }
 
 
     pub fn create_guessing(&self) -> GameStateData {
     pub fn create_guessing(&self) -> GameStateData {
-        let chars = self.game.round.exercises.iter()
-            .map(|x| x.letters.clone())
-            .collect::<Vec<_>>();
-        
         let words_with_chars = self.game.players.iter()
         let words_with_chars = self.game.players.iter()
-            .map(|p| p.submitted_word.clone().unwrap_or("".to_owned()))
-            .zip(chars)
+            .map(|p|
+                (p.submitted_word.clone().unwrap(),
+                p.creating_exercise.clone().unwrap().letters))
             .collect::<Vec<_>>();
             .collect::<Vec<_>>();
 
 
-        let mut questions = self.game.round.exercises.iter()
-            .map(|x| x.question.clone())
+        let mut questions = self.game.players.iter()
+            .map(|p| p.creating_exercise.clone().unwrap().question)
             .collect::<Vec<_>>();
             .collect::<Vec<_>>();
+        questions.append(&mut self.game.additional_questions.iter()
+                            .map(|x| x.question.clone())
+                            .collect::<Vec<_>>()
+                        );
 
 
         questions.shuffle(&mut thread_rng());
         questions.shuffle(&mut thread_rng());
 
 
@@ -237,6 +359,13 @@ impl Handler<LobbyJoined> for GameConnection {
     }
     }
 }
 }
 
 
+impl Handler<NoSuchLobby> for GameConnection {
+    type Result = ();
+    fn handle(&mut self, nsl: NoSuchLobby, ctx: &mut Self::Context) -> Self::Result {
+        self.send_message(&UpdateMessage::GameNotFound{ game_id: nsl.0 }, ctx);
+    }
+}
+
 impl Handler<GameUpdate> for GameConnection {
 impl Handler<GameUpdate> for GameConnection {
     type Result = ();
     type Result = ();
     fn handle(&mut self, gu: GameUpdate, ctx: &mut Self::Context) -> Self::Result {
     fn handle(&mut self, gu: GameUpdate, ctx: &mut Self::Context) -> Self::Result {
@@ -244,6 +373,13 @@ impl Handler<GameUpdate> for GameConnection {
     }
     }
 }
 }
 
 
+impl Handler<ResultMsg> for GameConnection {
+    type Result = ();
+    fn handle(&mut self, rm: ResultMsg, ctx: &mut Self::Context) -> Self::Result {
+        self.send_message(&UpdateMessage::RoundResult(rm.results), ctx);
+    }
+}
+
 impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for GameConnection {
 impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for GameConnection {
     fn handle(
     fn handle(
         &mut self,
         &mut self,
@@ -314,20 +450,26 @@ impl GameConnection {
                     self.game_id = Some(game_id.clone());
                     self.game_id = Some(game_id.clone());
                     self.nick = Some(nick);
                     self.nick = Some(nick);
                 },
                 },
+                ClientMessage::Ready => {
+                    if let Some(lobby) = &self.game_lobby {
+                        if let Some(nick) = &self.nick {
+                            lobby.do_send(ReadyMsg(nick.clone()));
+                        }
+                    }
+                },
                 ClientMessage::SubmitWord{ word } => {
                 ClientMessage::SubmitWord{ word } => {
-                    match &self.game_lobby {
-                        Some(lobby) => {
-                            if let Some(nick) = &self.nick {
-                                lobby.do_send(SubmitWordMsg{ word: word, nick: nick.clone() });
-                            }
-                        },
-                        None => {
-                            
+                    if let Some(lobby) = &self.game_lobby {
+                        if let Some(nick) = &self.nick {
+                            lobby.do_send(SubmitWordMsg{ word: word, nick: nick.clone() });
                         }
                         }
                     }
                     }
                 },
                 },
                 ClientMessage::SubmitGuess{ guesses } => {
                 ClientMessage::SubmitGuess{ guesses } => {
-                    
+                    if let Some(lobby) = &self.game_lobby {
+                        if let Some(nick) = &self.nick {
+                            lobby.do_send(SubmitGuessMsg{ guesses: guesses, nick: nick.clone() });
+                        }
+                    }
                 }
                 }
             }
             }
         }
         }

+ 11 - 0
src/websocket.rs

@@ -20,6 +20,7 @@ pub async fn ws_initiate(server: web::Data<Addr<server::Server>>, r: HttpRequest
 pub enum ClientMessage {
 pub enum ClientMessage {
     CreateGame{ game_id: String, nick: String },
     CreateGame{ game_id: String, nick: String },
     Join{ game_id: String, nick: String },
     Join{ game_id: String, nick: String },
+    Ready,
     SubmitWord{ word: String },
     SubmitWord{ word: String },
     SubmitGuess{ guesses: Vec<(String, String)> },
     SubmitGuess{ guesses: Vec<(String, String)> },
 }
 }
@@ -47,12 +48,22 @@ pub struct GameData {
     pub state_data: GameStateData
     pub state_data: GameStateData
 }
 }
 
 
+#[derive(Serialize, Clone)]
+#[serde(rename_all = "snake_case")]
+pub struct RoundResultData {
+    pub words: Vec<String>,
+    pub questions: Vec<String>,
+    pub solutions: Vec<(String, String)>,
+    pub guesses: Vec<Vec<Vec<String>>>,
+}
+
 #[derive(Serialize)]
 #[derive(Serialize)]
 #[serde(rename_all = "snake_case")]
 #[serde(rename_all = "snake_case")]
 pub enum UpdateMessage {
 pub enum UpdateMessage {
     GameNotFound{ game_id: String },
     GameNotFound{ game_id: String },
     GameAlreadyExists{ game_id: String },
     GameAlreadyExists{ game_id: String },
     GameState(GameData),
     GameState(GameData),
+    RoundResult(RoundResultData),
 }
 }
 
 
 
 

+ 65 - 1
static/index.html

@@ -7,6 +7,9 @@
         $(function() {
         $(function() {
             var connection = null;
             var connection = null;
 
 
+            var wordlist = null;
+            var questionlist = null;
+
             $('#join').click(function() {
             $('#join').click(function() {
                 var game_id = $('#gameId').val();
                 var game_id = $('#gameId').val();
                 var nick = $('#nick').val();
                 var nick = $('#nick').val();
@@ -31,6 +34,13 @@
                 connect(msg);
                 connect(msg);
             });
             });
 
 
+            $('#ready').click(function() {
+                var game_id = $('#gameId').val();
+                var nick = $('#nick').val();
+                var msg = "ready";
+                send(msg);
+            });
+
             $('#submit').click(function() {
             $('#submit').click(function() {
                 var word = $('#word').val();
                 var word = $('#word').val();
                 var msg = {
                 var msg = {
@@ -41,6 +51,26 @@
                 send(msg);
                 send(msg);
             });
             });
 
 
+            $('#submitGuess').click(function() {
+                var list = [];
+                for(var i = 0; i < wordlist.length; i++) {
+                    var number = parseInt($("g" + i).val());
+                    if (number == NaN) {
+                        $("#status").html("Please enter a valid number");
+                        return;
+                    }
+                    else if (number > 0 && number <= questionlist.length) {
+                        list.push([wordlist[i], questionlist[number - 1]]);
+                    }
+                }
+                var msg = {
+                    submit_guess: {
+                        guesses: list
+                    }
+                };
+                send(msg);
+            });
+
             function connect(initial_message) {
             function connect(initial_message) {
                 if (connection != null) {
                 if (connection != null) {
                     disconnect();
                     disconnect();
@@ -79,7 +109,10 @@
                 }
                 }
                 else if (obj.game_state != null) {
                 else if (obj.game_state != null) {
                     var gs = obj.game_state;
                     var gs = obj.game_state;
-                    if (gs.state_data.creating != null) {
+                    if (gs.state_data === "starting") {
+                        $('#startingform').show();
+                    }
+                    else if (gs.state_data.creating != null) {
                         var players = gs.players;
                         var players = gs.players;
                         playerlist = "";
                         playerlist = "";
                         for (var i = 0; i < players.length; i++) {
                         for (var i = 0; i < players.length; i++) {
@@ -96,6 +129,25 @@
                         $('#createform').show();
                         $('#createform').show();
                     }
                     }
                     else if (gs.state_data.guessing != null) {
                     else if (gs.state_data.guessing != null) {
+                        var guesses = gs.state_data.guessing;
+                        var sub_words = guesses.submitted_words;
+                        var questions = guesses.questions;
+                        var questionsHtml = "";
+                        for (var i = 0; i < questions.length; i++) {
+                            questionsHtml += (i + 1) + ": " + questions[i] + "<br>";
+                        }
+                        $('#guessingDynTable').html(questionsHtml);
+                        $('#guessingDyn').html("");
+                        for (var i = 0; i < sub_words.length; i++) {
+                            var $label = $("<label to='g" + i + "'>" + sub_words[i][0] + "</label>");
+                            var $field = $("<input name='g" + i + "' type='text' /><br>");
+                            $('#guessingDyn').append($label);
+                            $('#guessingDyn').append($field);
+                        }
+
+                        questionlist = questions;
+                        wordlist = sub_words.map(pair => pair[0]);
+                        
                         $('#createform').hide();
                         $('#createform').hide();
                         $('#guessing').show();
                         $('#guessing').show();
                     }
                     }
@@ -117,6 +169,10 @@
   <input id="create" type="button" value="Create Game" />
   <input id="create" type="button" value="Create Game" />
 </form>
 </form>
 
 
+<form id="startingform" style="display:none">
+    <input id="ready" type="button" value="Ready" />
+</form>
+
 <form id="createform" style="display:none">
 <form id="createform" style="display:none">
     <input id="question" type="text" readonly="readonly" /><br>
     <input id="question" type="text" readonly="readonly" /><br>
     <label for="letters">Create a word with the following letters</label>
     <label for="letters">Create a word with the following letters</label>
@@ -127,6 +183,14 @@
 </form>
 </form>
 <div id="guessing" style="display:none">
 <div id="guessing" style="display:none">
     You now have to guess!
     You now have to guess!
+    <div id="guessingDynTable">
+    </div>
+ 
+    <form id="guessingform">
+        <div id="guessingDyn">
+        </div>
+        <input id="submitGuess" type="button" value="Submit Guess" />
+    </form>
 </div>
 </div>
 <div id="status">
 <div id="status">
 </div>
 </div>