Expert review sprint 3 Senna de Vries¶
K1 - Je hebt object georiënteerde software gemaakt die samenwerkt met een database.¶
Object georienteerd programmeren bestaat uit de volgende onderdelen: encapsulation, abstraction, inheritance en polymorphism.
Onderstaand zijn de classes en functies die ik heb geschreven gebruikmakend van de principes van OOP.
class SpecialTiles : GameObjectList
{
protected readonly Tile tile;
public SpriteGameObject SpecialTile;
public SpecialTiles() : base()
{
SpecialTile = new SpriteGameObject("Images/UI/special tile", 1, "special tile")
{
Scale = 0.993f,
};
Add(SpecialTile);
}
public override void Remove(GameObject obj)
{
Remove(SpecialTile);
Add(SpecialTile);
}
}
private void DrawSpecialTiles()
{
for(int i = 0; i < 3; i++)
{
Random number = new Random();
int col = number.Next(0, 7);
int row = number.Next(3, 6);
string tileID = $"{(char)('A' + row)}{col + 1}";
Tile.TileType type = Tile.TileType.S;
Tile specialTile = new Tile(type, row, col, tileID);
specialTile.Position = new Microsoft.Xna.Framework.Vector2(358 + (col * 72.5f), row * 72.5f);
Add(specialTile);
SpecialTileSelected specialTileSelected = new();
specialTileSelected.SpecialTileLocation = $"{specialTile.Position}";
SocketClient.Instance.SendDataPacket(specialTileSelected);
Console.WriteLine("SpecialTile selected = " + specialTileSelected.SpecialTileLocation);
CheckPieceMovement(specialTile);
}
}
#handleIncomingStartGameMessages(socket) {
socket.on('start game', async (data) => {
this._rooms[data.roomId].started = true;
playerId++;
elo = Math.random(499, 3500);
wins = Math.random(0, 100);
losses = Math.random(0, 100);
//send a message to all players that the game has started.
//the client in the specific room can then start the game.
//other clients can remove the game from the list of active games.
this._io.emit('start game', { roomId: data.roomId });
const response = await this._socketConnectionListener.executePreparedQuery("INSERT INTO player (idPlayer, Name, elo, Wins, Losses, Game_idGame) VALUES (?)",[playerId], [playerNameInput], [elo], [wins], [losses], ["1"]);
this._socketConnectionListener.executePreparedQuery("INSERT INTO game (idGame, LobbyName, GameState) VALUES (" + gameId, gameNameInput, + "Playing)")
console.log(response);
});
}
Encapsulation¶
Bij encapsulation wordt data bij elkaar gebundeld in een class. Deze class kan vervolgens verborgen worden gehouden voor andere classes/buitenstaanders waardoor de code van buiten af niet kan worden beinvloed. Dit zorgt ervoor dat de functies, variabelen en andere stukken code niet onbedoelt worden aangepast.
//Special Tile class
protected readonly Tile tile;
public SpriteGameObject SpecialTile;
public SpecialTiles() : base()
//Special Tile Selected class
public string SpecialTileLocation { get; set; }
public string SessionId { get; set; }
public string UserId { get; set; }
public string RoomId { get; set; }
public SpecialTileSelected() : base()
//GameState: Draw Special Tile functie
private void DrawSpecialTiles()
Abstraction¶
Abstraction is het kort en bondig maken van de code waarbij irrelevante details worden weggelaten. Dit vergroot de leesbaarheid en herbruikbaarheid van de code.
//GameState: Draw SpecialTiles functie
for(int i = 0; i < 3; i++)
{
Random number = new Random();
int col = number.Next(0, 7);
int row = number.Next(3, 6);
string tileID = $"{(char)('A' + row)}{col + 1}";
Tile.TileType type = Tile.TileType.S;
Tile specialTile = new Tile(type, row, col, tileID);
specialTile.Position = new Microsoft.Xna.Framework.Vector2(358 + (col * 72.5f), row * 72.5f);
Add(specialTile);
SpecialTileSelected specialTileSelected = new();
specialTileSelected.SpecialTileLocation = $"{NewSpecialTile.Position}";
SocketClient.Instance.SendDataPacket(specialTileSelected);
Console.WriteLine("SpecialTile selected = " + specialTileSelected.SpecialTileLocation);
}
//Special Tile Selected class
public string SpecialTileLocation { get; set; }
public string SessionId { get; set; }
public string UserId { get; set; }
public string RoomId { get; set; }
Inheritance¶
Inheritance is het overnemen van eigenschappen en methodes tussen classes. Hierbij neemt een child class de eigenschappen over van zijn parent class.
Polymorphisme¶
Polymorphisme is de mogelijkheid om een methode op meerdere manieren te kunnen gebruiken. Hiervoor kunnen inheritance gebruikmakend van virtual en override statements of interfaces gebruikt worden. Een class geeft een bepaalde standaardcode aan. Via inheritance of interfaces kan deze code worden overschreden waarbij eigen implementaties worden ingevoegd. Op deze manier kan de originele class code op meerdere manieren worden ingezet.
Interfaces¶
Een interface is een class die alleen maar methods en properties bevat. Om toegang te krijgen tot de interface moet je van de interface inheriten. De ‘body’ van een interface mag niks bevatten. Het enige doel is dus de methods aanroepen. Op deze manier wordt abstraction beter bereikt. In mijn code was een interface niet nodig. Wel kwam de functie van de GameState method aardig in de buurt van een interface.
UML klassendiagram¶
In het bovenstaande UML klassendiagram zijn mijn classes weergegeven. Te zien is dat er een specialTiles class is aangemaakt die inherit van GameObjectList wat weer inherit van IGameObjectLoop. Ook zijn de variabelen en methods van de specialTiles class weergegeven en is er met een plus of min aangegeven of de variabele/methode public of private is gemaakt. Ook is er een SpecialTileSelected class aangemaakt die inherit van DataPacket. Ook hier zijn de variabelen en methods aangegeven met een plus- of minteken ervoor.
Database¶
Voor de database heb ik eerst een EER model gemaakt. Ik heb meerdere tabellen gemaakt en deze aan elkaar gelinkt. Bij het linken hield ik rekening met de verschillende soorten relaties (one to one, one to many, zero to many, etc). In de tabellen heb ik primary keys, foreign keys en andere waarden toegevoegd. Ook heb ik een connectie opgezet. Het EER diagram is een nogal breed diagram met alle aspecten van de game. Dit biedt enkele voor- en nadelen.
Voordelen:
- De hele game is compleet weergegeven in 1 database
- Alle relaties tussen de verschillende aspecten van de game zijn in 1 oogopslag duidelijk te zien
Nadelen:
- De database is lastig te realiseren door de omvang
- Het ophalen en opslaan van data zal minder precies gaan door de omvang van de database
#handleIncomingStartGameMessages(socket) {
socket.on('start game', async (data) => {
this._rooms[data.roomId].started = true;
playerId++;
elo = Math.random(499, 3500);
wins = Math.random(0, 100);
losses = Math.random(0, 100);
//send a message to all players that the game has started.
//the client in the specific room can then start the game.
//other clients can remove the game from the list of active games.
this._io.emit('start game', { roomId: data.roomId });
const response = await this._socketConnectionListener.executePreparedQuery("INSERT INTO player (idPlayer, Name, elo, Wins, Losses, Game_idGame) VALUES (?)",[playerId], [playerNameInput], [elo], [wins], [losses], ["1"]);
this._socketConnectionListener.executePreparedQuery("INSERT INTO game (idGame, LobbyName, GameState) VALUES (" + gameId, gameNameInput, + "Playing)")
console.log(response);
});
}
K3 - Je hebt een infrastructuur ontworpen en gebouwd volgens de gegeven specificaties.¶
Voor het ontwerpen van de infrastructuur heb ik een Json pakketje gemaakt waarbij er informatie van en naar de server wordt verzonden. Ook heb ik een sequence- en network diagram gemaakt.
Network Diagram:
Sequence Diagram:
Bronnen¶
Encapsulation
Abstraction
Inheritance
Polymorphisme bron 1
Polymorphisme bron 2
Network diagram
Sequence diagram
interface