Creating the Grid

Custom Grid Shapes in Minesweeper

Can we implement a custom grid shape instead of just rectangular?

Abstract art representing computer programming

Absolutely! Implementing a custom grid shape can add a unique twist to our Minesweeper game.

While rectangular grids are traditional, we can create various shapes like hexagonal, triangular, or even completely custom layouts. Let's explore how we might implement a hexagonal grid as an example.

Hexagonal Grid Implementation

To create a hexagonal grid, we need to adjust our MinesweeperGrid and MinesweeperCell classes. Here's a basic implementation:

#include <cmath>
#include <vector>
#include "Minesweeper/Cell.h"

class HexCell : public MinesweeperCell {
public:
  HexCell(int X, int Y, int Size, int Row,
          int Col) :
      MinesweeperCell(X, Y, Size, Size, Row,
                      Col) {}

  void Render(SDL_Surface *Surface) override {
    // Draw hexagon shape instead of rectangle
    const int centerX = X + Width / 2;
    const int centerY = Y + Height / 2;
    const int radius = Width / 2;

    std::vector<SDL_Point> points;
    for (int i = 0; i < 6; ++i) {
      const double angle =
        i * M_PI / 3 - M_PI / 6;
      points.push_back(
        {static_cast<int>(
           centerX + radius * std::cos(angle)),
         static_cast<int>(centerY +
                          radius *
                            std::sin(angle))});
    }

    // Draw filled hexagon
    filledPolygonRGBA(
      Surface,
      reinterpret_cast<const Sint16 *>(
        &points[0].x),
      reinterpret_cast<const Sint16 *>(
        &points[0].y),
      6, Color.r, Color.g, Color.b, Color.a);
  }
};

class HexGrid {
public:
  HexGrid(int x, int y) {
    using namespace Config;
    const int hexRadius = CELL_SIZE / 2;
    const int verticalSpacing =
      hexRadius * 3 / 2;

    for (int row = 0; row < GRID_ROWS; ++row) {
      for (int col = 0; col < GRID_COLUMNS;
           ++col) {
        int xPos = x +
          col * (hexRadius * sqrt(3)) +
          (row % 2) * (hexRadius * sqrt(3) / 2);
        int yPos = y + row * verticalSpacing;
        Cells.emplace_back(xPos, yPos,
                           CELL_SIZE, row, col);
      }
    }
  }

  void Render(SDL_Surface *Surface) {
    for (auto &cell : Cells) {
      cell.Render(Surface);
    }
  }

  std::vector<HexCell> Cells;
};

In this implementation:

  1. We create a HexCell class that inherits from MinesweeperCell but overrides the Render() method to draw a hexagon instead of a rectangle.
  2. The HexGrid class calculates the position of each hexagonal cell based on its row and column.
  3. We use the SDL2_gfx library's filledPolygonRGBA() function to draw the hexagonal shape.

Adapting Game Logic

Implementing a custom grid shape also requires adjusting our game logic:

  1. Neighbor calculation: In a hexagonal grid, each cell has 6 neighbors instead of 8.
  2. Cell selection: We need to implement a method to determine which cell was clicked based on the hexagonal layout.
  3. Grid navigation: Moving between cells (e.g., with keyboard controls) would need to account for the hexagonal pattern.

Here's a basic neighbor calculation for hexagonal grids:

std::vector<HexCell *> GetNeighbors(int row,
                                    int col) {
  std::vector<HexCell *> neighbors;
  const std::vector<std::pair<int, int>>
    offsets = {{-1, 0},
               {1, 0},
               {0, -1},
               {0, 1},
               {row % 2 ? 1 : -1, -1},
               {row % 2 ? 1 : -1, 1}};

  for (const auto &[rowOffset, colOffset] :
       offsets) {
    int newRow = row + rowOffset;
    int newCol = col + colOffset;
    if (newRow >= 0 && newRow < GRID_ROWS &&
        newCol >= 0 && newCol < GRID_COLUMNS) {
      neighbors.push_back(
        &Cells[newRow * GRID_COLUMNS + newCol]);
    }
  }
  return neighbors;
}

Implementing a custom grid shape adds complexity but can make your Minesweeper game stand out. Remember to adjust all parts of your game logic to accommodate the new shape, including mine placement, cell clearing, and win condition checking.

This Question is from the Lesson:

Creating the Grid

Building a two-dimensional grid of interactive minesweeper cells

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Creating the Grid

Building a two-dimensional grid of interactive minesweeper cells

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 51 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved