Title image of Trivia game in Blazor

Trivia game in Blazor

25 November 2022

·
Blazor

A few weeks ago I created a silly game about cheese: https://cheeseordesease.com. It’s a simple quiz game written in Vue js and I had a lot of fun making it. I want to write another, but for a challenge, I will use Blazor.

The premise for the game is simple: What’s bigger?

In each round, the player will face a number of options and must choose which is the biggest. Silly but should be fun to build.

We need some datasets of stuff to be the database of the game. They can contain anything as long as they have a metric we can use for judging what’s bigger? The first one I found is the population of cities.

City population

https://simplemaps.com/data/world-cities provides a free list of 43,000 of the world’s towns and cities.

The smallest towns on the list only have a population of 10 people. Using these in the game would be way too hard so we can’t use the entire dataset.

Split the data into three: The top 50 cities in the UK, the top 50 cities in the USA and the top 2 cities from every country.

Place the files in the wwwroot so they can be retrieved by the front end:

File structure of the cities data

I like to get all the logic done before I make it look pretty. So it’s going to be ugly in the beginning.

The game only needs two pages: A home page and the city guessing page. So we can delete all of the default Blazor pages:

File structure of the pages folder

The home page acts as the menu for the different categories of cities. Three categories of cities require just three buttons:

Screenshot of the Whats bigger home page

If the game were expanded to other types of data it would be worth creating the buttons dynamically. But for now, each button is hardcoded:

<button class="btn btn-primary" @onclick="@(e => Navigation.NavigateTo("cities/uk"))">UK</button>

Each button navigates to the cities page with the city category in the URL. The cities page then uses the category e.g. UK to download the list of cities from the static files in the wwwroot. This is all done in the OnInitializedAsync method with the category string marked as a parameter:

@code {
    [Parameter]
    public string? Category { get; set; }

    protected City[] CitiesData { get; set;}

    protected override async Task OnInitializedAsync()
    {
        Category = Category ?? "Global";

        CitiesData = await Http.GetFromJsonAsync<City[]>($"cities-data/{Category}.json");
    }
}

Game logic

There are three game states or screens the player will play through:

Choosing - The player is choosing which city is the biggest.

Choice Made - The player has chosen which city they think is the biggest.

Game Over - The player has played through every combination of cities.

We can use an enum to control the state in the code:

public enum State
{
    Choosing,
    ChoiceMade,
    GameOver
}

Choosing

This state involves randomly picking two cities to put against each other and displaying those options to the player.

Screenshot of playing the game whats bigger

Every city combination needs to be unique. Players don’t want to keep playing through the same cities. So a loop is used to keep randomly picking cities until a new combination is found. This isn’t very efficient but it will do for our game :D

Picking a new city combination:

var choiceOne = CitiesData[random.Next(CitiesData.Length)];
var choiceTwo = CitiesData[random.Next(CitiesData.Length)];

while (previousChoices[$"{choiceOne.Country}-{choiceOne.Name}"]
    .Contains($"{choiceTwo.Country}-{choiceTwo.Name}") && choiceOne.Name == choiceTwo.Name)
{
    choiceOne = CitiesData[random.Next(CitiesData.Length)];
    choiceTwo = CitiesData[random.Next(CitiesData.Length)];
}

Once new cities have been chosen they are added to a list and displayed to the user:

@if(gameState == State.Choosing)
{
    @foreach(var choice in choices)
    {
        <button @onclick="@(e => Choose(e, choice.Name))">@choice.Name</button>
    }
}

Choice made

The choice made state comes after the player chooses which city they think is the biggest. On this screen, the game displays the result of choice (correct or incorrect), the populations of the cities and a button to start the next round.

Screenshot of playing the game after choosing an answer

The transition from the Choosing to this state is triggered by the Choose method:

private void Choose(MouseEventArgs e, string name)
{
	var biggestCity = choices.First(x => 
		x.Population == choices.Max(y => y.Population));

	if(name == biggestCity.Name)
	{
		results.Add(true);
	}
	else
	{
		results.Add(false);
	}

	gameState = State.ChoiceMade;
}

In this method, we work out which of the choices has the biggest population. Then compare it to what the player has chosen and increment the player’s score accordingly.

The game state is then set to ChoiceMade which updates the UI where we show the result and the population of the cities.

Game over

Finally when all of the city combinations have been exhausted the game is set to the game over state. Here we show some ‘game over’ text and the player’s final score.

Demo

A playthrough of the whats bigger trivia game written in Blazor

Complete code is available on Github: https://github.com/Liam-Hunt/whatsbigger