Published
Edited
May 13, 2020
Insert cell
md`# 100 days of code - Days 97 - 100 - Creating a minesweeper game `
Insert cell
md`**Day 98**

The last couple days of the challenge will bring all these new skills together. Use this [example](https://observablehq.com/@benjaminadk/minesweeper) as inspiration for the design.

- Use svg
- Add style sheet`
Insert cell
Insert cell
minesweeper = {
// Board design variables
const { margin, cellSize, statusSize, buttonSize, displayWidth, gridWidth, gridHeight, bombs } = constants
// Create svg
const svg = d3
.create('svg')
.attr('width', gridWidth * cellSize + margin * 2)
.attr('height', gridHeight * cellSize + statusSize + margin * 2)

// Create scoreboard
const scoreBoard = svg.append('g').attr('transform', `translate(${margin},${margin - 10})`)

// Create game board
const gameBoard = svg.append('g').attr('transform', `translate(${margin},${statusSize + margin})`)

// Create grid layer
const grid = gameBoard.append('g')

// Create top layer - buttons and flags
const buttons = gameBoard.append('g')

// status bar background
scoreBoard
.append('rect')
.attr('width', gridWidth * cellSize)
.attr('height', statusSize)
.attr('fill', '#d1d1d1') // Give background light gray colour
// timer container
scoreBoard
.append('rect')
.attr('x', gridWidth * cellSize - displayWidth - 5)
.attr('y', (statusSize - buttonSize) / 2)
.attr('width', displayWidth)
.attr('height', buttonSize)
.attr('fill', '#000')
// Add timer red text placeholder
scoreBoard
.append('text')
.attr('fill', 'red')

// Add reset button
scoreBoard
.append('rect')
.attr('id', 'reset')
.attr('x', (gridWidth * cellSize) / 2 - buttonSize / 2)
.attr('y', (statusSize - buttonSize) / 2)
.attr('width', buttonSize)
.attr('height', buttonSize)
.attr('fill', 'darkgrey')// temporary fill until fix fill with smiley face `url("https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/240/microsoft/209/slightly-smiling-face_1f642.png")`)

// Add mine count container
scoreBoard
.append('rect')
.attr('x', 5)
.attr('y', (statusSize - buttonSize) / 2)
.attr('width', displayWidth)
.attr('height', buttonSize)
.attr('fill', '#000') // background as black

// Add mine count text placeholder
scoreBoard
.append('text')
.attr('fill', 'red')


// Add bottom grid for cell background and bombs
grid
.selectAll('rect')
.attr('width', gridWidth * cellSize)
.attr('height', cellSize)
.attr('fill', '#d1d1d1')

// Add bomb counts placeholder text
grid
.selectAll('text')


// Add buttons
buttons
.selectAll('rect')
.join('rect')
.attr('x', d => d.x)
.attr('y', d => d.y)
.attr('width', cellSize)
.attr('height', cellSize)
.attr('fill', 'darkgrey')// temporary until we fill with pop up buttons

const frame = createFrame()
return html`<div style="position: relative;">${frame}${svg.node()}</div>`
}
Insert cell
// Create a game design object called constants
constants = ({
margin: 50,
cellSize: 25,
statusSize: 50,
buttonSize: 40,
displayWidth: 50,
gridWidth: 9, // For a standard beginner game the cell width x height is 9x9
gridHeight:9,
bombs: 10,// For a standard beginner game there are 10 hidden bombs
})
Insert cell
// Create a function that uses HTML to position the frame of the game

function createFrame() {
const { cellSize, gridWidth, gridHeight, statusSize, margin } = constants

const frame = html`<div style="position: absolute; top: ${margin/2}px; left: ${margin/2 + 10}px; pointer-events:none;"></div>`
return frame
}
Insert cell
d3 = require('d3@5')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more