RASMUS GÖRANSSON

GAME PROGRAMMER

Minesweeper Extended

Minesweeper Extended offers a gathered place to play the original classic take on Minesweeper, same rules, same style. Or, you could try some completely different styles of the original!

Play Hex mode, an entirely different grid style.

Experience the game in a new perspective and play it in 3D mode.

You can also challenge yourself in the Endless Mode where you play until you lose or reach the end with each game getting more diffucult than the previous!

Key Features:

Classic

Hexagonal

3D

Endless

                    
public class Grid
{
    private CellData[,] _grid;

    public int Width => _grid.GetLength(0);
    public int Height => _grid.GetLength(1);

    public CellData this[int x, int y] => _grid[x, y];
    public Grid(int width, int height)
    {
        _grid = new CellData[width, height];

        for (int x = 0; x < _grid.GetLength(0); x++)
        {
            for (int y = 0; y < _grid.GetLength(1); y++)
            {
                CellData cellData = ScriptableObject.CreateInstance<CellData>();
                _grid[x, y] = cellData;
                cellData.Position = new Vector3Int(x, y, 0);
                cellData.Type = CellData.CellType.Empty;
            }
        }
    }
}
                    
                

Mine Placement

Mines are generated when the player first clicks on a cell.

A list of valid cells is created, which includes every cell in the grid, excluding the initial clicked cell and it's adjacent neighbors. The list is then shuffled into a random order.

Mines are placed by looping through the list until the set number of mines have been placed.

                    
public void CreateCellNumbers()
{
    int width = Width;
    int height = Height;

    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            CellData cellData = _grid[x, y];

            if (cellData.Type == CellData.CellType.Mine) continue;

            cellData.Number = GetAdjacentMines(cellData);
            cellData.Type = cellData.Number > 0 ? CellData.CellType.Number : CellData.CellType.Empty;
        }
    }
}
                    
                

Reveal Cells

When a hidden cell is clicked there are three outcomes:
- If the cell is a mine, the game ends.
- If the cell is empty, an area of cells are revealed.
- If the cell is a number, the number is revealed.

An area of cells is revealed by recursively checking the adjacent neighbors of empty cells. If a neighbor is either empty or a number, it is revealed.

                    
private void Unchord(CellData chord)
{
    chord.IsChorded = false;

    IEnumerable<Vector2Int> adjacentOffsets = GameModeManager.Instance.CurrentGameMode != GameModeManager.GameMode.Hex
            ? _grid.GetAllAdjacent()
            : _grid.GetAdjacentHex(chord);

    foreach (Vector2Int offset in adjacentOffsets)
    {
        int x = chord.Position.x + offset.x;
        int y = chord.Position.y + offset.y;

        if (_grid.TryGetCellData(x, y, out CellData cellData))
        {
            if (cellData.IsRevealed && cellData.Type == CellData.CellType.Number)
            {
                if (_grid.GetAdjacentFlags(cellData) >= cellData.Number)
                {
                    RevealCellData(chord);
                    return;
                }
            }
        }
            
    }
}
                    
                

Steam Achievements Manager

The Achievements Manager uses Steam's Steamworks API to set and update achievements.

It follows the singleton pattern to ensure only one instance exists.

- SetAchievement sets a specific achievement and saves it.
- SetStats updates a stat and saves it. For example, an achievement requiring 10 wins would update after each win.