From 201383ebb8390cce41ef5082fb257cb85fc6c97b Mon Sep 17 00:00:00 2001 From: Nikita Ovchinnikov Date: Thu, 22 Jul 2021 18:02:00 +0300 Subject: [PATCH] Add openCell action --- README.md | 8 ++ src/helpers/CellsManipulator.test.ts | 165 ++++++++++++++++++++++----- src/helpers/CellsManipulator.ts | 54 ++++++++- 3 files changed, 196 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 032df72..2d77d2f 100644 --- a/README.md +++ b/README.md @@ -154,3 +154,11 @@ [Pull request](https://github.com/nickovchinnikov/minesweeper/pull/21) [Pull request2](https://github.com/nickovchinnikov/minesweeper/pull/22) + +[Pull request3](https://github.com/nickovchinnikov/minesweeper/pull/23) + +## Section 8: React hooks advanced + +### Game logic + +[Pull request](https://github.com/nickovchinnikov/minesweeper/pull/24) diff --git a/src/helpers/CellsManipulator.test.ts b/src/helpers/CellsManipulator.test.ts index 8d703a2..2078522 100644 --- a/src/helpers/CellsManipulator.test.ts +++ b/src/helpers/CellsManipulator.test.ts @@ -3,9 +3,10 @@ import { incrementNeibours, getNeigboursItems, checkItemInField, + openCell, } from './CellsManipulator'; -const { empty, bomb } = CellState; +const { empty: e, hidden: h, bomb: b } = CellState; describe('Check neigbours selectors', () => { it('With [0, 0] coords', () => { @@ -36,7 +37,7 @@ describe('Check neigbours selectors', () => { describe('checkItemInField tests', () => { describe('Simple cases', () => { - const field: Field = [[empty]]; + const field: Field = [[e]]; it('Out of y range', () => { expect(checkItemInField([1, 0], field)).toBe(false); @@ -52,11 +53,11 @@ describe('checkItemInField tests', () => { }); describe('Big field', () => { const field: Field = [ - [empty, empty, empty, empty, empty], - [empty, empty, empty, empty, empty], - [empty, empty, empty, empty, empty], - [empty, empty, empty, empty, empty], - [empty, empty, empty, empty, empty], + [e, e, e, e, e], + [e, e, e, e, e], + [e, e, e, e, e], + [e, e, e, e, e], + [e, e, e, e, e], ]; it('Out of x range', () => { @@ -80,19 +81,19 @@ describe('checkItemInField tests', () => { describe('Check Increment Neibours', () => { describe('Simple cases', () => { it('Field with only one item', () => { - expect(incrementNeibours([0, 0], [[bomb]])).toStrictEqual([[bomb]]); + expect(incrementNeibours([0, 0], [[b]])).toStrictEqual([[b]]); }); it('Field 2x2 with one mine', () => { expect( incrementNeibours( [0, 0], [ - [bomb, empty], - [empty, empty], + [b, e], + [e, e], ] ) ).toStrictEqual([ - [bomb, 1], + [b, 1], [1, 1], ]); }); @@ -101,13 +102,13 @@ describe('Check Increment Neibours', () => { incrementNeibours( [0, 0], [ - [bomb, empty], - [empty, bomb], + [b, e], + [e, b], ] ) ).toStrictEqual([ - [bomb, 1], - [1, bomb], + [b, 1], + [1, b], ]); }); }); @@ -117,14 +118,14 @@ describe('Check Increment Neibours', () => { incrementNeibours( [1, 1], [ - [empty, empty, empty], - [empty, bomb, empty], - [empty, empty, empty], + [e, e, e], + [e, b, e], + [e, e, e], ] ) ).toStrictEqual([ [1, 1, 1], - [1, bomb, 1], + [1, b, 1], [1, 1, 1], ]); }); @@ -133,14 +134,14 @@ describe('Check Increment Neibours', () => { incrementNeibours( [1, 1], [ - [0, 1, bomb], - [0, bomb, 1], + [0, 1, b], + [0, b, 1], [0, 0, 0], ] ) ).toStrictEqual([ - [1, 2, bomb], - [1, bomb, 2], + [1, 2, b], + [1, b, 2], [1, 1, 1], ]); }); @@ -149,14 +150,14 @@ describe('Check Increment Neibours', () => { incrementNeibours( [1, 1], [ - [0, 1, bomb], - [8, bomb, 1], + [0, 1, b], + [8, b, 1], [8, 8, 8], ] ) ).toStrictEqual([ - [1, 2, bomb], - [8, bomb, 2], + [1, 2, b], + [8, b, 2], [8, 8, 8], ]); }); @@ -220,3 +221,113 @@ describe('Check Increment Neibours', () => { }); }); }); + +describe('Open cell action', () => { + describe('Simple cases with loose', () => { + it('Open cell with the bomb', () => { + expect(() => + openCell( + [1, 1], + [ + [h, h], + [h, h], + ], + [ + [1, 1], + [1, b], + ] + ) + ).toThrow('Game Over'); + }); + }); + describe('Open cell with number', () => { + it('Open cell with state == 1', () => { + const playerField = openCell( + [1, 1], + [ + [h, h, h], + [h, h, h], + [h, h, h], + ], + [ + [1, 1, 0], + [9, 1, 0], + [1, 1, 0], + ] + ); + expect(playerField).toStrictEqual([ + [h, h, h], + [h, 1, h], + [h, h, h], + ]); + }); + it('Open cell with state == 3', () => { + const playerField = openCell( + [1, 1], + [ + [h, h, h], + [h, h, h], + [h, h, h], + ], + [ + [9, 2, 0], + [9, 3, 0], + [9, 2, 0], + ] + ); + expect(playerField).toStrictEqual([ + [h, h, h], + [h, 3, h], + [h, h, h], + ]); + }); + }); + describe('Open empty cell', () => { + it('Open empty cell, simple 3*3 case', () => { + const playerField = openCell( + [1, 2], + [ + [h, h, h], + [h, h, h], + [h, h, h], + ], + [ + [1, 1, 0], + [9, 1, 0], + [1, 1, 0], + ] + ); + expect(playerField).toStrictEqual([ + [h, 1, 0], + [h, 1, 0], + [h, 1, 0], + ]); + }); + it('Open empty cell 5*5 case', () => { + const playerField = openCell( + [2, 2], + [ + [h, h, h, h, h], + [h, h, h, h, h], + [h, h, h, h, h], + [h, h, h, h, h], + [h, h, h, h, h], + ], + [ + [9, 9, 1, 1, 2], + [9, 3, 1, 0, 0], + [1, 1, 0, 1, 1], + [1, 0, 0, 1, 9], + [2, 1, 0, 1, 0], + ] + ); + expect(playerField).toStrictEqual([ + [h, h, 1, 1, 2], + [h, 3, 1, 0, 0], + [1, 1, 0, 1, 1], + [1, 0, 0, 1, h], + [2, 1, 0, 1, h], + ]); + }); + }); +}); diff --git a/src/helpers/CellsManipulator.ts b/src/helpers/CellsManipulator.ts index ad9bbd9..266216c 100644 --- a/src/helpers/CellsManipulator.ts +++ b/src/helpers/CellsManipulator.ts @@ -1,4 +1,4 @@ -import { Cell, Coords, Field } from './Field'; +import { Cell, CellState, Coords, Field } from './Field'; /** * Get neighbour cells indexes @@ -37,9 +37,8 @@ export const checkItemInField = ([y, x]: Coords, { length }: Field): boolean => export const incrementNeibours = (coords: Coords, field: Field): Field => { const items = getNeigboursItems(coords); - for (const item of Object.values(items)) { - if (checkItemInField(item, field)) { - const [y, x] = item; + for (const [y, x] of Object.values(items)) { + if (checkItemInField([y, x], field)) { const cell = field[y][x]; if (cell < 8) { field[y][x] = (cell + 1) as Cell; @@ -49,3 +48,50 @@ export const incrementNeibours = (coords: Coords, field: Field): Field => { return field; }; + +/** + * Open cell in the player field using game field info + * @param {Coords} coords + * @param {Field} playerField + * @param {Field} gameField + * @returns {Field} + */ +export const openCell = ( + coords: Coords, + playerField: Field, + gameField: Field +): Field => { + const { empty, hidden, bomb } = CellState; + + const [y, x] = coords; + const gameCell = gameField[y][x]; + + if (gameCell === bomb) { + throw new Error('Game Over'); + } + + if (gameCell === empty) { + playerField[y][x] = gameCell; + + const items = getNeigboursItems(coords); + + for (const [y, x] of Object.values(items)) { + if (checkItemInField([y, x], gameField)) { + const gameCell = gameField[y][x]; + const playerCell = playerField[y][x]; + + if (gameCell === empty && playerCell === hidden) { + playerField = openCell([y, x], playerField, gameField); + } + + if (gameCell < bomb) { + playerField[y][x] = gameCell; + } + } + } + } + + playerField[y][x] = gameCell; + + return playerField; +};