Skip to content

RobinAxelsson/LudoV2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

image

PGBSNH20 Group 5 Ludo Web

Ludo Web project is a .NET online Ludo Board Game Platform. It was made between 10th of may and 30th of may 2021, during our studies to .NET Developer at Teknik Högskolan.

Albin Alm -> GitHub

Robin Axelsson -> GitHub


Table of content


Features

  • Game rooms
  • Multiplayer
  • AI players
  • Email invitations
  • SQL database with users, gamedata
  • Token and cookie authentication
  • Server Side Logic

Technologies

  • ASP.NET
  • Razor Pages
  • C#
  • SignalR
  • SQL-Server
  • Entity Framework
  • Git version control
  • GitHub
  • JavaScript
  • Visual Studio
  • SMTP client

Architecture

With SOLID principles in mind we keep the libraries (LudoGame, LudoTranslation) as libraries - independent of the main projects.

  • LudoGame: is the logic and the factories for the game objects.
  • LudoDataAccess: Manages the data layer with users and game data.
  • LudoTranslation: Manages the language translations in email and web interface.
  • LudoWeb: Manages the frontend (Razor pages and JavaScript), the networking of the game and the game rooms (and more).

image


Project: Ludo Game & Ludo Web

All the game logic is calculated on the server (to eliminate cheating).

Server Side Game Loop

    foreach (var player in _orderedPlayers)
    {
    /*
    rolling dice
    check board for valid options to provide the player
    waits for player response
    validates the response
    if valid:
        update the board in memory
        send updated pawns through SignalR
    */
    }
}

A full loop across the network with SignalR

This image describes the loop with both a human player connected over the network, but also our AI (called Stefan).

image

Links to classes in the diagram.


Custom Dependency Injection of Game

A good way to clear up dependencies is a good design for instantiating the Library classes. This is made through stand alone container injection of LudoGame in LudoProvider.cs. This design creates an additional dependency injection system separate from ASP.NETs. The system adds a new container of game services for every created instance of the LudoProvider. This makes it possible to have multiple game rooms with different Ludo games at the same time.

public LudoProvider()
{
    var container = new ServiceCollection();

    container
        .AddSingleton<IBoardCollection, BoardCollection>()
        .AddSingleton<IGameAction, GameAction>()
        .AddSingleton<IGamePlay, GamePlay>()
        .AddSingleton<IGameFunction, GameFunction>()
        .AddSingleton<IGameEvent, DefaultGameEvent>()
        .AddSingleton<IOptionsValidator, OptionsValidator>()
        .AddSingleton<IEqualityComparer<Pawn>, PawnComparer>()
        .AddSingleton<IGameFunction, GameFunction>()
        .AddSingleton<IBoardOrm, BoardOrm>();

    _provider = container.BuildServiceProvider();
}

public T GetGameService<T>()
{
    return _provider.GetService<T>();
}

This class provide the needed game services for each game and is applied in GameRoom.cs

        public GameRoom(AbstractFactory gameFactory, IGameNetworkManager manager, string gameId, LudoNetworkFactory factory)
        {
            var provider = gameFactory.BuildLudoProvider();
            _gamePlay = provider.GetGameService<IGamePlay>();
            _gameEvent = provider.GetGameService<IGameEvent>();
            _boardCollection = provider.GetGameService<IBoardCollection>();

Project: LudoDataAccess; EmailClient

Generates a HTML Email body and sends it to clients using SMTP-protocol.

Flow:


First of all we instantiate a new SMTP client using Google Server, since our host email is using Gmail.

bild


We then wish to get a list of all the account objects connected to the recipients. This is because we want the e-mail to be formatted in the receivers preferred language using TranslationEngine.

bild


We are also sending the emails separately using a for-loop. This is of two reasons:
  1. We don't want to leak any data to the recipients. Like other receivers.
  2. We want the e-mail to be translated individually based on the recipients preferred language
Also, notice the email body is set using the method GenerateBody(). This method basically imports our HTML-body and then alters it for the user using simple string.replace.

bild


Project: LudoTranslation

Alters strings using reflection and source files

Flow:


bild

First of all we have .lang files which contains lines of the respective translation and it's correspondent property name. The content is split using double equal signs.
Example: Game_H1Title==Välkommen till Ludo!

bild

Now on the InitializeLanguage() method will firstly make a new instance of the class Dict that contains the properties. Secondly, a StreamReader will reach each line in the .lang file and find a property with the same name as the left section in that new instance of Dict. If it finds such property it will set that value to it's correspondant left section. Then this process is repeated until the entire file has been read.

bild

As a final result you will get back the newly instanced Dict class and can access all the properties with it's values.
Then just set the chosen content value to any property of Dict.

Why this way?


We chose to structure it this way since it is very simple to extend the translation afterwards.
If we want to add a completely new string, the only thing we gotta do is to create that property in Dict.cs and then add that property and it's value to the language file.
If we instead wish to add another language we just need to name the file a 2-character ISO standard country name(SE, US, RU...) and then .lang.
In that file just copy over the properties and set the desired values.

Example load:

bild
With reflection it becomes very simple.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published