Table of contents
- What is it?
- How does it work from the players perspective
- How does it work from Martens perspective
- C# and javascript code
- Small hacks to get it working
- Database
- What could be better
What is it?
This webpage is a simple question game. All the players, except for Marten, can answer a question, a question can be added by all the players and is selected to be answered by Marten. When all answers are submitted, Marten has to pick the best answer. All players also select the answer they think Marten will pick.
Next the scores are shown, points are given to the player that submitting the answer Marten selected, and points for every other player that selected your answer (regardless if it was picked by Marten or not).
How does it work the players perspective
At the main screen there is the option to insert a new question. This question has to be submitted under a category.
The player can change his/her name, as long as it is not used by another user already.
Next a question is presented to the player. The player has to fill in a lie (or something that is most likely to be picked by Marten or other players in the next phase). When the player has submitted it, the page shows the amount of lies entered for this question.
In the points phase, the player has to select the best lie, remember that points are given to the player that submitted the lie.
When also Marten has selected the best lie, the points for this round are given. 500 points are rewarded to the player that has submitted the lie that Marten selected. Another 100 points for every player that selected your lie (regardless if it was picked by Marten or not).
The result of the rounds points are displayed to every user, with their lie highlighted
How does it work from Martens perspective
In the select question overview, Marten can only see the category of the question. He than selected a question to be played. As soon as he does that, the select lies action becomes available.
In the select winning lie screen, Marten pickes the best lie, not knowing who of the players submitted it.
The lies are added to this screen as soon as the player submits them, so Marten can already read some lies before all players have submitted them.
The close question notifies the players that they cannot add any more answers, and now need to select the best lie for giving points.
In the overview the stop round action becomes available, when clicked the points are rewarded to the players and every player will see the points page. After this Marten can close the question and the game is in a waiting state for Marten to select a question to be played.
Score overview
At any moment of the game, a player can see the scores via the menu. The players row is highlighted.
The points are divided in the different categories and a grand total.
C# and javascript code
All the code can be found on my github page: https://github.com/timdows/webpages/tree/master/MJAGame
The solution consist of two project, a data and MVC project. The data project is responsible for creating, seeding and handling all database related actions. The seeder creates the database if it does not exist, next is adds the tables and inserts a new user (by the name of root), the different subjects (categories) and a couple of dozen of questions.
The MVC project is using Angular on the front-end, and 8 back-end controllers all extending MJAGameController.
- AddQuestionController
Saves new questions from players to the database - AnswerController
Saves a lie for the current question, also saves the players selection for best lie of another player - MartenController
It can be seen as the admin controller, get the questions, lies and scores for the game - PartialsController
Dedicated controller to get the different html pages that are requested by the Angular environment - QuestionController
Responsible for showing the player the correct information on the page when a question is played or a lie has been submitted - ScoreController
Returns a list with the scores per player per category - UserController
Get the current user object via the cookie if available and handles the name changes of a player - HomeController
Main controller that returns the default index page to the player with all scripts and css files - MJAGameController
Base controller to make sure the DataContext is available for all controllers extending this controller
The front-end part is based on a single page, with 8 controllers as well.
- mjaGameClientController
- sidebarLeftClientController
- nameClientController
- scoresClientController
- currentQuestionClientController
- addQuestionClientController
- selectQuestionClientController
- selectWinningAnswerClientController
At this moment it is a bad practice of implementing, as there is no routing used for this project on the Angular side.
The most important part is the mainRefresh that is responsible for asking the server every 2500 ms for the latest data. At the point of creating this application SignalR was not yet known by myself…
Small hacks to get it working
While developing I primarily test it on my development machine as well. The first issue arose quite quickly, the html pages (partials) would not be loaded. This had to do with the fact that there was no mapping for the html file extension. I followed the steps on Jon Galloways blogpost and after a IIS express restart it was working perfect. Below the specific line that was added:
[code lang=”xml”]
<add name="HtmlFileHandler" path="*.html" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
[/code]
When I tried to access the created webpage from another device I encountered two issues. The first was that the port 81 that I was using for the IIS express environment was not opened in my Windows firewall settings. Next a 400 error occured (Bad Request – Invalid Hostname), this had to do that the IIS express environment was not listening to anything other that localhost. After changing it to *:81:*, it worked like a charm. Below the specific part of my applicationhost.config file:
[code lang=”xml”]
<site name="MJAGame" id="3">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Dev\mja_game\MJAGame" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:81:*" />
</bindings>
</site>
[/code]
Database
The MSSQL database is created and seeded upon first run, it looks at the MJAGameConnection in the web.config file where the server is located and how to authenticate against it.
The only interesting about this environment would be the Answer_ChosenBy_User table. This table holds track of the select points round for the players. The Answer class has a list of Users defined:
[code lang=”csharp”]
public class Answer : SqlBase
{
public Answer()
{
this.ChosenBy = new List<User>();
}
public Question Question { get; set; }
public User User { get; set; }
public string AnswerString { get; set; }
public bool Correct { get; set; }
public List<User> ChosenBy { get; set; }
}
[/code]
In the MJAGameContext this list is mapped via the modelBuilder object:
[code lang=”csharp”]
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Answer>()
.HasMany(t => t.ChosenBy)
.WithMany()
.Map(a_mapping => a_mapping.ToTable("Answer_ChosenBy_User"));
}
[/code]
The result is a nice mapping table in the database
What could be better
- The Angular controllers should be split and the Angular route functionality should be used
- Using the Angular refresh function (the self created one) puts a lot of pressure on the webserver, but as at the time of creating the game had no knowledge of SignalR I still guess it worked out very well (around 15 players that request a json response every 2.5 second
- The admin page should be easier, on a mobile device it is quite hard to find the running question with corresponding action button
Comments are closed.