perf: track a small list of highlighted cells
This commit is contained in:
parent
6e6cf2c4f8
commit
749b47fe40
2 changed files with 39 additions and 8 deletions
|
|
@ -84,6 +84,8 @@ const Minesweeper = function(appId, version, hooks = undefined) {
|
||||||
let flagsCount = setting.mines
|
let flagsCount = setting.mines
|
||||||
// Mine positions stored as a Set of numeric keys (row * cols + col) for O(1) lookup
|
// Mine positions stored as a Set of numeric keys (row * cols + col) for O(1) lookup
|
||||||
let mines = new Set()
|
let mines = new Set()
|
||||||
|
// Cells currently highlighted, so removeHighlights only resets these (<=9) instead of the whole grid
|
||||||
|
let highlightedCells = []
|
||||||
|
|
||||||
this.initialize = function() {
|
this.initialize = function() {
|
||||||
const headingElement = document.createElement('h1')
|
const headingElement = document.createElement('h1')
|
||||||
|
|
@ -190,6 +192,7 @@ const Minesweeper = function(appId, version, hooks = undefined) {
|
||||||
grid.oncontextmenu = () => false
|
grid.oncontextmenu = () => false
|
||||||
flagsCount = setting.mines
|
flagsCount = setting.mines
|
||||||
mines.clear()
|
mines.clear()
|
||||||
|
highlightedCells = []
|
||||||
|
|
||||||
for (let i = 0; i < setting.rows; i++) {
|
for (let i = 0; i < setting.rows; i++) {
|
||||||
let row = grid.insertRow(i)
|
let row = grid.insertRow(i)
|
||||||
|
|
@ -637,19 +640,20 @@ const Minesweeper = function(appId, version, hooks = undefined) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeHighlights() {
|
function removeHighlights() {
|
||||||
for (let i=0; i<setting.rows; i++) {
|
for (let i = 0; i < highlightedCells.length; i++) {
|
||||||
const rows = grid.rows[i]
|
const currentCell = highlightedCells[i]
|
||||||
if (!rows) continue
|
// guard: a tracked cell may have been flagged/clicked since it was highlighted
|
||||||
for(let j=0; j<setting.cols; j++) {
|
|
||||||
let currentCell = grid.rows[i].cells[j]
|
|
||||||
if (getStatus(currentCell) == 'highlighted') setStatus(currentCell, 'default')
|
if (getStatus(currentCell) == 'highlighted') setStatus(currentCell, 'default')
|
||||||
}
|
}
|
||||||
}
|
highlightedCells = []
|
||||||
}
|
}
|
||||||
|
|
||||||
function highlightCell(cell) {
|
function highlightCell(cell) {
|
||||||
if (isFlagged(cell)) return
|
if (isFlagged(cell)) return
|
||||||
if (!gameIsDone() && getStatus(cell) == 'default') setStatus(cell, 'highlighted') // currentCell.classList.add('highlight');
|
if (!gameIsDone() && getStatus(cell) == 'default') {
|
||||||
|
setStatus(cell, 'highlighted') // currentCell.classList.add('highlight');
|
||||||
|
highlightedCells.push(cell)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function highlightSurroundingCell(cell) {
|
function highlightSurroundingCell(cell) {
|
||||||
|
|
|
||||||
|
|
@ -89,4 +89,31 @@ describe('Minesweeper board', () => {
|
||||||
expect(grid.getAttribute('game-status')).toBe('inactive')
|
expect(grid.getAttribute('game-status')).toBe('inactive')
|
||||||
everyCell(grid, cell => expect(cell.getAttribute('data-status')).toBe('default'))
|
everyCell(grid, cell => expect(cell.getAttribute('data-status')).toBe('default'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('highlights the pressed cell and clears it when the press moves away', () => {
|
||||||
|
const grid = mountGame()
|
||||||
|
const a = grid.rows[5].cells[5]
|
||||||
|
const b = grid.rows[5].cells[6]
|
||||||
|
const c = grid.rows[5].cells[7]
|
||||||
|
|
||||||
|
// Press-and-hold left on A -> A highlighted.
|
||||||
|
a.dispatchEvent(new MouseEvent('mousedown', { button: 0, bubbles: true }))
|
||||||
|
expect(a.getAttribute('data-status')).toBe('highlighted')
|
||||||
|
|
||||||
|
// Drag the held press across B then C. Each move must clear the previous
|
||||||
|
// highlight and leave no stale ones behind.
|
||||||
|
b.dispatchEvent(new MouseEvent('mousemove', { bubbles: true }))
|
||||||
|
c.dispatchEvent(new MouseEvent('mousemove', { bubbles: true }))
|
||||||
|
|
||||||
|
expect(a.getAttribute('data-status')).toBe('default')
|
||||||
|
expect(b.getAttribute('data-status')).toBe('default')
|
||||||
|
expect(c.getAttribute('data-status')).toBe('highlighted')
|
||||||
|
|
||||||
|
// Exactly one cell should remain highlighted across the whole grid.
|
||||||
|
let highlighted = 0
|
||||||
|
everyCell(grid, cell => {
|
||||||
|
if (cell.getAttribute('data-status') === 'highlighted') highlighted++
|
||||||
|
})
|
||||||
|
expect(highlighted).toBe(1)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue