GithubHelp home page GithubHelp logo

guessing-game's Introduction

Guessing game

An implementation of a party game in which players stick post-its with a name of some character (real or not) on each other's foreheads and then take turns trying to guess who they are by asking simple yes/no questions.

Features

The following features are expected to be implemented for an MVP:

  1. ✅ User creates a game with a unique URL which can be joined by other players by just pasting it to their address bar
  2. The creator of the game sets the settings of the game:
  • (❌ To be removed and set to a constant, rational value, like 10) Max number of players able to join the game
  • When should the game finish:
    • when a first player wins
    • when all but last player win (so positions are known)
    • when all players finish
  • Whether players should be able to see the history of their questions and their vote results
  • Whether the game is public or not. Public games would then appear at some page under "join a public game" menu button. Public games would need an obligatory topic description (e.g. "American politicians", "Marvel movie characters" etc.) so that others can decide whether to join the game. No enforcement of whether a character matches the category is made though.
  1. ✅ Players set their names after joining the game. The game can be started by any of them after there are min. 2 players, all of whom have set their name
  2. ✅ After the game is started, the order of players is randomized and they assign a character to a player next to them (for example, if there are 4 players, the order of assignment is 1→2, 2→3, 3→4, 4→1)
  3. ✅ Optionally along with a character a player can provide a link to a webpage describing this character, so that every player can know more about it. If it is provided, then the name of the character appears as a link during the game
  4. ✅ The game starts when all the players assign a character
  5. ✅ Players take turns. Each turn means either asking a question which brings a player closer to the guess or making a guess if the player believes they know the character
  6. ✅ After a question/guess is made, voting phase begins with all other players being able to choose among Yes/No/Don't know/Needs discussion options as their vote
  7. ✅ Only the yes/no options are available when voting on a guess
  8. After all players vote, the results are displayed:
  • ✅ (without chat) If there is at least one "needs discussion" vote or the vote is not unanimous, the player who asked the question is prompted to either accept the majority option as the answer or discuss it in a simple chat
  • ✅ Otherwise if the vote is unanimous, the voted option is automatically considered as the answer to the question
  • ✅ For the purpose of the two rules above, voting is considered "unanimous" without taking "Don't know" votes into account. For example, if there are two "yes" and three "don't know" votes, the voting is unanimous for "yes". On the other hand, if everyone votes "Don't know", then it's automatically considered as an answer and the game proceeds to the next turn
  1. ✅ When the player makes a guess and it is equal to their character, the voting is skipped and the game is finished for this player. On the other hand, if it's not, the voting takes place anyway (considering for example that the player's character may be a singer known under a nickname but player answers with their full name, the other players may still vote to accept this answer)
  2. ✅ For the voting on a guess to succeed, the "Yes" option must have a clear majority over "No" votes. So 3-2 result passes but 3-3 does not
  3. ✅ The game continues until the condition for finishing the game selected during its setup is met
  4. After the game is finished a summary screen is displayed. It shows players with their characters and standings, including number of turns needed for them come to a guess
  5. As convenient, old games can be either removed automatically by a cron-like process or manually

Technologies

Frontend

Communication

  • socket.io - a communication platform making use of Websockets but providing nice additional features like rooms, disconnection detection etc.

Backend

  • NodeJS with Express and TypeScript
  • Sequelize, a JS ORM framework
  • SQLite database for testing to be replaced with a full-fledged solution (possibly Postgres) in production

guessing-game's People

Contributors

jakubraban avatar

Stargazers

Jacek Kuśnierz avatar

Watchers

 avatar

guessing-game's Issues

Implement "make a guess" algorithm

  • If a player makes a guess and its correct (i.e. comparing the guess and the assigned character using === yields true), the guess is automatically considered correct
  • Otherwise, voting is started for other players with only "yes"/"no" options
  • If most players vote "yes" (strictly more than "no") then the guess is considered correct
  • If the guess is considered correct, a message is displayed to everyone and next rounds (if applicable) skip that player's turn
  • If the guess is voted incorrect, the game continues normally, just like after asking a question

Notes:

  • Comparison should take place on the server

Introduce DB transactions

Currently if the controller makes more than one call to the DB we are exposed on leaving it in an invalid state if one of the subsequent calls fail. Transactions must be introduced to be able to rollback the changes in case of failure.

Implement the game summary screen

After a game is finished, summary should be displayed, including:

  • players' standings - players in order of guessing their character, together with the number of turns it took them to guess
  • each player's history of questions and guesses with the voting results
  • "return to menu" and "start new game" buttons

This summary should be accessible until we decide to remove the game from the DB by just pasting the link, like when joining the game

Implement public games

I imagine that when creating the game, a user should be presented a checkbox with an option to make the game public. Such games would appear in a list accessible from the main menu, unlike non-public games. Player would join them by clicking a button in the list. An only exception to the functioning of public games would be that the creator would be required to provide a category to which characters should belong to (like "American politicians" or "Marvel movie characters"), based on which a wannabe-player would decide whether they'd like to join this game or not.

Decouple controllers and DB access

Currently controllers call the Sequelize commands directly. Layers of abstraction should be created in order to facilitate potential future change of data source. I imagine the following ones:

  • Repositories/DAOs: contain methods calling the DB and executing simple operations (find all, find one, select, insert etc.)
  • Services: do stuff on results returned from DAOs
  • Controllers: receive data, call services on this data and emit an event based on the result from service

Mark player as disconnected

A disconnected player should:

  • not be displayed on votes list
  • not be awaited for vote

Ideally, a player who disconnects during voting or their turn should trigger immediate effect as described above, but timeouts should suffice

Implement different conditions for the end of game

When creating the game, the user should be able to choose when the game should finish:

  • when a first player wins
  • when all but last player win (so positions are known)
  • when all players finish

Add an appropriate control to the game setup wizard and implement all the 3 behaviors

Unify `playerId` and `socketId` naming

Currently playerId and socketId are used exchangably in the code, in addition to the player's table id primary key. We should decide which name to use and go for it. Alternatively use one of them on backend (probably socketId) and another one on frontend.

Implement an in-game chat

Implement a very simple chat which could be used to discuss questions if such discussion is deemed necessary during the voting. The only more "advanced" feature could be typing status. I imagine chat could be placed in an expandable panel.

Implement correct disconnection and reconnection logic

When a player disconnects from the game:

  • If the game is in lobby state, remove this player from the players list
  • If the game is in playing state, mark the player as disconnected. Such player's turns should then be skipped and their vote should not be awaited
  • If the game is in finished state, disconnection is normal and nothing should happen

As a part of this task, consider what should happen when all but one players disconnect from the game in progress.

A separate thing is to implement a reconnection logic. Things to be done:

  • Verify which player reconnects. As other player's IDs are known on all clients, this must involve some different mechanics than just relying on socketId sent from the client. One way would be to separately provide "reconnection token" to each player, which could be just an AES encryption of socketId using some constant, random and stored on server key. Upon receiving reconnection request, server would decrypt it and match against existing players
  • Mark the player as connected back
  • Replay the game state from scratch. This probably involves storing all the game events in the DB.

Additionally, make sure the socket ID changes after leaving the game and joining another one (ie. socket is closed and a new one is created)

Implement an option to view history of questions in-game

This is one of the option a user should be presented with when creating a game. If it's checked, users will be able to see all the questions and attempted guesses they made during the game, together with voting result. Otherwise, they can only see their last question.

TBD: if the option was not checked, should players be able to see other players' history anyway?

Correctly type the model classes on backend

Currently TS on backend feels kinda useless becuase all the sequelize classes are not correctly typed, thus extensive use of .get() and // @ts-ignore in controller methods. A way to correctly type those classes must be found and implemented

Serve bundled JS from the server

Currently two servers must be run, one for backend and one for frontend, on different ports. The code should be rewritten in a way so server serves main page at the / endpoint and the JS bundle as a static file in production

Implement calculating vote result for "ask a question" turn type

  • server detects that all votes have been cast
  • depending on the results, either automatically accepts the answer or indicates the player must decide what to do
  • when the answer is accepted, the next turn starts automatically in 5s or after the player clicks "Next round" button

Implement timeouts in certain parts of the app

Add the following timeouts:

  • 30 seconds for taking a turn (after this, skip to next player)
  • 10 seconds for voting (after this, auto-vote "Don't know")
  • 90 seconds for potential discussion
  • 5 seconds after proceeding with game after last player is assigned a character (right now it happens instantly)

Don't stop the server on error

Currently any exception thrown in the controller will cause the server to terminate. Considering that we will never avoid every possible exception, we should find a way in Node which allows us to keep the server running when an exception happens in the controller.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.