I would like to improve my Go skills and thought about creating a small Minesweeper backend. For the domain model I started with this
import "github.com/google/uuid"
type Game struct {
ID uuid.UUID
Board [][]*BoardCell
AmountOfMines uint8
}
type BoardCell struct {
IsRevealed bool
HasBeenRevealedAfterEndOfGame bool
HasFlag bool
HasMine bool
AmountOfNeighbourMines uint8
}
With these information you can inspect the whole game board while tracking the AmountOfNeighbourMines field is just for performance purposes ( since we only need to calculate it once )
I would like to know how you would design a database model for this.
I personally think that I would use the same schema as SQL tables
Game => ID, AmountOfMines
BoardCell => gameID ( foreign key ), …fields…
but when it comes to a DTO I’m not sure if I should simply copy paste the domain model. If that’s the case the in memory database could track games in a map [gameID, game] but maybe there are better ways to manage the games in the database layer.
Regarding your question, I’m not entirely sure I understand everything you’re asking. However, I approach design from a database perspective.
I understand that you need the AmountOfNeighbourMines to save processing power at some point, but I prefer not to include it in the database. I assume you want to save it at a specific point, correct? So performance does not matter that much and all info is there.
You haven’t provided much information, but I feel that people generally use too much object-oriented programming (OOP) for Go. Transferring a Data Transfer Object (DTO) feels unnecessarily complex. It might be better to simply send the required data directly and think in those terms.
Again, it’s hard to be certain without more details, but my intuition tells me that your code might have at least one or two unnecessary layers of complexity and is more in a Java or Cpp style.
I don’t think I would store things like AmountOfMines in my game table since it can be calculated. Maybe start with something like this (BTW I typed this into notepad so syntax might be slightly wrong and I am currently used to MariaDB so this is MySQL-ish):
-- Create games table
CREATE TABLE games (
id int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
);
-- Create game cells table
CREATE TABLE game_cells (
id int(11) NOT NULL AUTO_INCREMENT,
game_id int(11) NOT NULL,
x int(11) NOT NULL,
y int(11) NOT NULL,
is_revealed tinyint(1) NOT NULL,
is_flagged tinyint(1) NOT NULL,
is_mine tinyint(1) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (game_id) REFERENCES games(id)
);
Anyway, my point there is: you could easily construct things like AmountOfMines:
select
count(id) as num_cells,
sum(is_mine) as num_mines
from game_cells where game_id = 1;