From 77df14989301353cb727da828d657e990a6142af Mon Sep 17 00:00:00 2001 From: Nikita Ovchinnikov Date: Tue, 9 Nov 2021 10:28:04 +0400 Subject: [PATCH 1/4] Fix Cell size --- .../__snapshots__/GameLayout.test.tsx.snap | 24 ++-- src/components/Grid/Cell.tsx | 16 +-- .../Grid/__snapshots__/Cell.test.tsx.snap | 122 +++++++++--------- .../Grid/__snapshots__/Grid.test.tsx.snap | 32 ++--- .../GameWithHooks.snap.test.tsx.snap | 20 +-- .../__snapshots__/GameWithHooks.test.tsx.snap | 4 +- .../GameWithReactRedux.test.tsx.snap | 4 +- .../__snapshots__/Grid.test.tsx.snap | 50 +++---- .../GameWithUseReducer.test.tsx.snap | 90 ++++++------- .../MinesweeperWithHooks.test.tsx.snap | 4 +- .../MinesweeperWithReactRedux.test.tsx.snap | 4 +- .../MinesweeperWithUseReducer.test.tsx.snap | 4 +- 12 files changed, 187 insertions(+), 187 deletions(-) diff --git a/src/components/Game/__snapshots__/GameLayout.test.tsx.snap b/src/components/Game/__snapshots__/GameLayout.test.tsx.snap index 66af63a..f566275 100644 --- a/src/components/Game/__snapshots__/GameLayout.test.tsx.snap +++ b/src/components/Game/__snapshots__/GameLayout.test.tsx.snap @@ -171,8 +171,8 @@ exports[`Top renders correctly 1`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -210,8 +210,8 @@ exports[`Top renders correctly 1`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -249,8 +249,8 @@ exports[`Top renders correctly 1`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -273,8 +273,8 @@ exports[`Top renders correctly 1`] = ` .emotion-26 { border-radius: 50%; - width: 1vw; - height: 1vw; + width: 1vh; + height: 1vh; background-color: #333; } @@ -296,8 +296,8 @@ exports[`Top renders correctly 1`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -335,8 +335,8 @@ exports[`Top renders correctly 1`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; diff --git a/src/components/Grid/Cell.tsx b/src/components/Grid/Cell.tsx index ab92b02..47c39fa 100644 --- a/src/components/Grid/Cell.tsx +++ b/src/components/Grid/Cell.tsx @@ -131,8 +131,8 @@ export const ClosedFrame = styled.div` justify-content: center; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -171,8 +171,8 @@ const RevealedFrame = styled(ClosedFrame)` const Bomb = styled.div` border-radius: 50%; - width: 1vw; - height: 1vw; + width: 1vh; + height: 1vh; background-color: #333; `; @@ -184,11 +184,11 @@ const Flag = styled.div` width: 0px; height: 0px; color: ${transparent}; - border-top: 0.5vw solid transparent; - border-bottom: 0.5vw solid transparent; - border-left: 0.5vw solid #ec433c; + border-top: 0.5vh solid transparent; + border-bottom: 0.5vh solid transparent; + border-left: 0.5vh solid #ec433c; `; const WeakFlag = styled(Flag)` - border-left: 0.5vw solid #f19996; + border-left: 0.5vh solid #f19996; `; diff --git a/src/components/Grid/__snapshots__/Cell.test.tsx.snap b/src/components/Grid/__snapshots__/Cell.test.tsx.snap index 344289f..ed596b1 100644 --- a/src/components/Grid/__snapshots__/Cell.test.tsx.snap +++ b/src/components/Grid/__snapshots__/Cell.test.tsx.snap @@ -20,8 +20,8 @@ exports[`Cell component check Cell renders correct 1`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -71,8 +71,8 @@ exports[`Cell component check Cell renders correct 2`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -122,8 +122,8 @@ exports[`Cell component check Cell renders correct 3`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -173,8 +173,8 @@ exports[`Cell component check Cell renders correct 4`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -224,8 +224,8 @@ exports[`Cell component check Cell renders correct 5`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -275,8 +275,8 @@ exports[`Cell component check Cell renders correct 6`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -326,8 +326,8 @@ exports[`Cell component check Cell renders correct 7`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -377,8 +377,8 @@ exports[`Cell component check Cell renders correct 8`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -428,8 +428,8 @@ exports[`Cell component check Cell renders correct 9`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -479,8 +479,8 @@ exports[`Cell component check Cell renders correct 10`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -503,8 +503,8 @@ exports[`Cell component check Cell renders correct 10`] = ` .emotion-1 { border-radius: 50%; - width: 1vw; - height: 1vw; + width: 1vh; + height: 1vh; background-color: #333; } @@ -541,8 +541,8 @@ exports[`Cell component check Cell renders correct 11`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -584,8 +584,8 @@ exports[`Cell component check Cell renders correct 12`] = ` -ms-user-select: none; user-select: none; cursor: pointer; - width: 1.8vw; - height: 1.8vw; + width: 1.8vh; + height: 1.8vh; color: transparent; background-color: #d1d1d1; border: 0.6vh solid transparent; @@ -601,9 +601,9 @@ exports[`Cell component check Cell renders correct 12`] = ` width: 0px; height: 0px; color: rgba(0,0,0,0); - border-top: 0.5vw solid transparent; - border-bottom: 0.5vw solid transparent; - border-left: 0.5vw solid #ec433c; + border-top: 0.5vh solid transparent; + border-bottom: 0.5vh solid transparent; + border-left: 0.5vh solid #ec433c; }
Date: Tue, 9 Nov 2021 14:06:22 +0400 Subject: [PATCH 2/4] Add .lh directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 36feb17..2b82432 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .history +.lh .vscode dist coverage From a9fc19b6de67471bb34484edcd524d7c3402b57d Mon Sep 17 00:00:00 2001 From: Nikita Ovchinnikov Date: Tue, 9 Nov 2021 14:40:58 +0400 Subject: [PATCH 3/4] Fix game timer --- src/modules/GameWithRedux/game.test.ts | 59 +++++++++++++++++++------- src/modules/GameWithRedux/game.ts | 22 +++++++--- 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/modules/GameWithRedux/game.test.ts b/src/modules/GameWithRedux/game.test.ts index 5191794..75c7447 100644 --- a/src/modules/GameWithRedux/game.test.ts +++ b/src/modules/GameWithRedux/game.test.ts @@ -13,6 +13,7 @@ describe('Game reducer', () => { isGameOver: false, isGameStarted: false, isWin: false, + isTimerRunning: false, settings: GameSettings[level], bombs: 1, flagCounter: 0, @@ -140,7 +141,7 @@ describe('Game reducer', () => { }); }); - describe('Check reset and changeLevel', () => { + describe('Check reset, changeLevel and setTimerActive', () => { it('Reset game action should reset game to the default state', () => { const nextState = reducer(baseInitialState, actions.reset()); expect(nextState).toEqual( @@ -176,6 +177,10 @@ describe('Game reducer', () => { expect(nextState.gameField).toHaveLength(16); expect(nextState.playerField).toHaveLength(16); }); + it('setTimerActive should switch isTimerActive', () => { + const nextState = reducer(baseInitialState, actions.setTimerActive()); + expect(nextState.isTimerRunning).toBe(true); + }); }); describe('Check updateTime action', () => { @@ -198,72 +203,94 @@ describe('Game reducer', () => { }); describe('Async actions check', () => { - it('Check action runTimer with state { isGameStarted: true, time: 0 }', () => { + it('Check action runTimer with state { isGameStarted: true, isTimerRunning: false }', () => { const mockDispatch = jest.fn(); runTimer()( mockDispatch, () => ({ game: { isGameStarted: true, - time: 0, + isTimerRunning: false, } as State, }), undefined ); - expect(mockDispatch).toHaveBeenCalled(); + expect(mockDispatch).toHaveBeenCalledTimes(2); }); - it('Check action runTimer with state { isGameStarted: true, time: 1 }', () => { + it('Check action runTimer with state { isGameStarted: true, isTimerRunning: true }', () => { const mockDispatch = jest.fn(); runTimer()( mockDispatch, () => ({ game: { isGameStarted: true, - time: 1, + isTimerRunning: true, } as State, }), undefined ); expect(mockDispatch).not.toHaveBeenCalled(); }); - it('Check action runTimer with state { isGameStarted: false, time: 10 }', () => { + + it('Check action recursiveUpdate with state { isGameStarted: true, isTimerRunning: true } and the same gameField', () => { + jest.useFakeTimers(); const mockDispatch = jest.fn(); - runTimer()( + recursiveUpdate(baseInitialState.gameField)( mockDispatch, () => ({ game: { - isGameStarted: false, - time: 10, + isGameStarted: true, + isTimerRunning: true, + gameField: baseInitialState.gameField, + } as State, + }), + undefined + ); + jest.advanceTimersByTime(1000); + expect(mockDispatch).toHaveBeenCalledTimes(2); + }); + it('Check action recursiveUpdate with state { isGameStarted: true, isTimerRunning: true } and not the same gameField', () => { + jest.useFakeTimers(); + const mockDispatch = jest.fn(); + recursiveUpdate(baseInitialState.gameField)( + mockDispatch, + () => ({ + game: { + isGameStarted: true, + isTimerRunning: true, + gameField: [...baseInitialState.gameField], } as State, }), undefined ); + jest.advanceTimersByTime(1000); expect(mockDispatch).not.toHaveBeenCalled(); }); - - it('Check action recursiveUpdate with state { isGameStarted: true }', () => { + it('Check action recursiveUpdate with state { isGameStarted: true, isTimerRunning: false }', () => { jest.useFakeTimers(); const mockDispatch = jest.fn(); - recursiveUpdate()( + recursiveUpdate(baseInitialState.gameField)( mockDispatch, () => ({ game: { isGameStarted: true, + isTimerRunning: false, } as State, }), undefined ); jest.advanceTimersByTime(1000); - expect(mockDispatch).toHaveBeenCalledTimes(2); + expect(mockDispatch).not.toHaveBeenCalled(); }); - it('Check action recursiveUpdate with state { isGameStarted: false }', () => { + it('Check action recursiveUpdate with state { isGameStarted: false, isTimerRunning: false }', () => { jest.useFakeTimers(); const mockDispatch = jest.fn(); - recursiveUpdate()( + recursiveUpdate(baseInitialState.gameField)( mockDispatch, () => ({ game: { isGameStarted: false, + isTimerRunning: false, } as State, }), undefined diff --git a/src/modules/GameWithRedux/game.ts b/src/modules/GameWithRedux/game.ts index 1cf7298..985f3d7 100644 --- a/src/modules/GameWithRedux/game.ts +++ b/src/modules/GameWithRedux/game.ts @@ -24,6 +24,7 @@ export interface State { isGameOver: boolean; isGameStarted: boolean; isWin: boolean; + isTimerRunning: boolean; settings: [number, number]; playerField: Field; gameField: Field; @@ -41,6 +42,7 @@ export const getInitialState = (level: LevelNames = 'beginner'): State => { isGameOver: false, isGameStarted: false, isWin: false, + isTimerRunning: false, settings, flagCounter: 0, playerField: generateFieldWithDefaultState(size, CellState.hidden), @@ -90,6 +92,9 @@ export const { reducer, actions } = createSlice({ updateTime: (state) => { state.time = state.time + 1; }, + setTimerActive: (state) => { + state.isTimerRunning = true; + }, reset: ({ level }) => getInitialState(level), changeLevel: (state, { payload }: PayloadAction) => getInitialState(payload), @@ -97,21 +102,24 @@ export const { reducer, actions } = createSlice({ }); export const recursiveUpdate = - (): ThunkAction => + (prevGameField: Field): ThunkAction => (dispatch, getState) => setTimeout(() => { - const { isGameStarted } = getState().game; - if (isGameStarted) { + const { isGameStarted, isTimerRunning, gameField } = getState().game; + const isTheSameGame = gameField === prevGameField; + + if (isGameStarted && isTimerRunning && isTheSameGame) { dispatch(actions.updateTime()); - dispatch(recursiveUpdate()); + dispatch(recursiveUpdate(gameField)); } }, 1000); export const runTimer = (): ThunkAction => (dispatch, getState) => { - const { isGameStarted, time } = getState().game; - if (time === 0 && isGameStarted) { - dispatch(recursiveUpdate()); + const { isGameStarted, isTimerRunning, gameField } = getState().game; + if (isGameStarted && !isTimerRunning) { + dispatch(actions.setTimerActive()); + dispatch(recursiveUpdate(gameField)); } }; From ac761175a30831c2a8b3baa2e12bf23e42ceab89 Mon Sep 17 00:00:00 2001 From: Nikita Ovchinnikov Date: Tue, 9 Nov 2021 14:41:37 +0400 Subject: [PATCH 4/4] Edit readme.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 937c7b1..78af1f5 100644 --- a/README.md +++ b/README.md @@ -327,3 +327,7 @@ ### Refactoring with Stryker [Pull request](https://github.com/nickovchinnikov/minesweeper/pull/59/files) + +### Fix timer + +[Pull request](https://github.com/nickovchinnikov/minesweeper/pull/60/files)