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
|
||||
// Mine positions stored as a Set of numeric keys (row * cols + col) for O(1) lookup
|
||||
let mines = new Set()
|
||||
// Cells currently highlighted, so removeHighlights only resets these (<=9) instead of the whole grid
|
||||
let highlightedCells = []
|
||||
|
||||
this.initialize = function() {
|
||||
const headingElement = document.createElement('h1')
|
||||
|
|
@ -190,6 +192,7 @@ const Minesweeper = function(appId, version, hooks = undefined) {
|
|||
grid.oncontextmenu = () => false
|
||||
flagsCount = setting.mines
|
||||
mines.clear()
|
||||
highlightedCells = []
|
||||
|
||||
for (let i = 0; i < setting.rows; i++) {
|
||||
let row = grid.insertRow(i)
|
||||
|
|
@ -637,19 +640,20 @@ const Minesweeper = function(appId, version, hooks = undefined) {
|
|||
}
|
||||
|
||||
function removeHighlights() {
|
||||
for (let i=0; i<setting.rows; i++) {
|
||||
const rows = grid.rows[i]
|
||||
if (!rows) continue
|
||||
for(let j=0; j<setting.cols; j++) {
|
||||
let currentCell = grid.rows[i].cells[j]
|
||||
if (getStatus(currentCell) == 'highlighted') setStatus(currentCell, 'default')
|
||||
}
|
||||
for (let i = 0; i < highlightedCells.length; i++) {
|
||||
const currentCell = highlightedCells[i]
|
||||
// guard: a tracked cell may have been flagged/clicked since it was highlighted
|
||||
if (getStatus(currentCell) == 'highlighted') setStatus(currentCell, 'default')
|
||||
}
|
||||
highlightedCells = []
|
||||
}
|
||||
|
||||
function highlightCell(cell) {
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -89,4 +89,31 @@ describe('Minesweeper board', () => {
|
|||
expect(grid.getAttribute('game-status')).toBe('inactive')
|
||||
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