Skip to content

Commit

Permalink
fix the canMove function to cover a edge-case
Browse files Browse the repository at this point in the history
  • Loading branch information
fgandellini committed Jun 9, 2024
1 parent adc50f4 commit de37094
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 19 deletions.
24 changes: 23 additions & 1 deletion packages/game-engine/src/board.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('Board', () => {
expect(hasTile(board, { value: 2 })).toBe(false)
})

it('The board can move if there is at least one empty cell', () => {
it('The board can move if there is at least one reachable empty cell', () => {
let board = createEmptyBoard(3)
board = setCell(board, { x: 0, y: 0 }, { value: 2 })
board = setCell(board, { x: 1, y: 0 }, { value: 4 })
Expand Down Expand Up @@ -146,6 +146,28 @@ describe('Board', () => {
expect(canMove(board)).toBe(false)
})

it('The board cannot move if there are unreachable cells', () => {
let board = createEmptyBoard(3)
board = setCell(board, { x: 0, y: 0 }, { obstacle: true })
board = setCell(board, { x: 1, y: 0 }, { value: 2 })
board = setCell(board, { x: 2, y: 0 }, { value: 1 })
board = setCell(board, { x: 0, y: 1 }, { obstacle: true })
board = setCell(board, { x: 1, y: 1 }, { obstacle: true })
board = setCell(board, { x: 2, y: 1 }, { value: 2 })
board = setCell(board, { x: 0, y: 2 }, null)
board = setCell(board, { x: 1, y: 2 }, { obstacle: true })
board = setCell(board, { x: 2, y: 2 }, { value: 1 })

// prettier-ignore
expect(boardToMatrix(board)).toEqual([
['X' , 2 , 1],
['X' , 'X' , 2],
[null, 'X' , 1],
])

expect(canMove(board)).toBe(false)
})

it('Finds the farthest empty tile on the right', () => {
let board = createEmptyBoard(6)
const t1 = {
Expand Down
23 changes: 5 additions & 18 deletions packages/game-engine/src/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,13 @@ export const hasTile = (board: Board, tile: Tile): boolean =>
* @param board the board to check
* @returns true if the board can move in any direction, false otherwise
*/
export const canMove = (board: Board): boolean => {
// if there are empty cells, we can move
if (hasEmpty(board)) {
return true
}

// if there are adjacent cells with the same value, we can move
const directions: Array<Direction> = ['up', 'down', 'left', 'right']
return directions.some(direction => {
export const canMove = (board: Board): boolean =>
(['up', 'down', 'left', 'right'] as const).some(direction => {
// try to move the board
const newBoard = move(board, direction)
return hasEmpty(newBoard)
// if the board changed, we can move
return !isBoardEqual(board, newBoard)
})
}

/**
* Finds the farthest position in a given direction
Expand Down Expand Up @@ -244,13 +238,6 @@ export const isEmpty = (cell: Tile | Obstacle | null): cell is null =>
export const isObstacle = (cell: Tile | Obstacle | null): cell is Obstacle =>
cell !== null && 'obstacle' in cell && cell.obstacle === true

/**
* Checks if the board has empty cells
* @param board the board to check
* @returns true if the board has emptycells, false otherwise
*/
const hasEmpty = (board: Board): boolean => board.grid.some(isEmpty)

/**
* Checks if two cells are equal
* @param cell1 the first cell to compare
Expand Down

0 comments on commit de37094

Please sign in to comment.