From 43a433760704a41bed04af31f01fb629ef12d101 Mon Sep 17 00:00:00 2001 From: Interrobangs <35430583+Interrobangs@users.noreply.github.com> Date: Tue, 22 Nov 2022 23:44:36 +0100 Subject: [PATCH 01/13] Create README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..0736453 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ + +# Klods + +Klods is a game where you have to think a head. At each level random bricks appear, now stackle them up to get full lines either up/down or to the side to get points. + + + + +## Screenshots + +![App Screenshot](https://screenshot.launchbrightly.com/klods/klods/desktop/dark/game.png) + From f61e1ce812d89ae64ff8d7128925b6ba4df48f40 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 01:14:57 +0100 Subject: [PATCH 02/13] Move undos to constants --- src/App.tsx | 12 ++++++------ src/constants.ts | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 2c3bf90..a797c6c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,15 +4,15 @@ import { pieces } from './pieces' import type { IBoard, IPiece, IState } from './model' import { Square } from './components/Square' import { checkIfPieceFitsAndUpdateBoard, clearFullRows, createEmptyBoard, generateFitTest, getPieceHeight, getPieceWidth, snapPositionToBoard, drawN, calculateLocationFromIndex, createRainbowBoard, checkIfPieceCanBePlaced } from './util' -import { boardSize, getSquareSizePixels, highscoreLocalStorageKey } from './constants' +import { boardSize, getSquareSizePixels, highscoreLocalStorageKey, undos } from './constants' import { usePointerExit } from './hooks' -const INITIAL_UNDOSLEFT = 3 + export default function App() { const [state, setState] = useState(getInitialState) const [prevState, setPrevState] = useState(state) - const [undosLeft, setUndosLeft] = useState(INITIAL_UNDOSLEFT) + const [undosLeft, setUndosLeft] = useState(undos) const [queue, setQueue] = useState<(IPiece | null)[] | null>(null) const boardRef = useRef(null) const [pointer, setPointer] = useState<{ @@ -77,7 +77,7 @@ export default function App() { ...getInitialState(), highscore: Math.max(prevState.highscore, prevState.score) })) - setUndosLeft(INITIAL_UNDOSLEFT) + setUndosLeft(undos) setPrevState(getInitialState) } @@ -149,9 +149,9 @@ export default function App() {
Score: {state.score}
High Score: {state.highscore}
- {/* */} +
diff --git a/src/constants.ts b/src/constants.ts index a89549a..69e49dd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -29,3 +29,5 @@ export const hues = [ ] export const highscoreLocalStorageKey = "KLODS_HIGHSCORE" + +export const undos = 3 \ No newline at end of file From f02806072f390bd60cb7f8dcbf8378ff99481229 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 01:41:36 +0100 Subject: [PATCH 03/13] Fix undo reset game --- src/App.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index a797c6c..c8a7714 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,8 +7,6 @@ import { checkIfPieceFitsAndUpdateBoard, clearFullRows, createEmptyBoard, genera import { boardSize, getSquareSizePixels, highscoreLocalStorageKey, undos } from './constants' import { usePointerExit } from './hooks' - - export default function App() { const [state, setState] = useState(getInitialState) const [prevState, setPrevState] = useState(state) @@ -78,12 +76,22 @@ export default function App() { highscore: Math.max(prevState.highscore, prevState.score) })) setUndosLeft(undos) - setPrevState(getInitialState) + setPrevState(getInitialState()) } const undo = () => { + // console.log(Object.is(prevState, state)) // This gives false.. - if(JSON.stringify(prevState) !== JSON.stringify(state)){ + // this will just exclude userPieces from both objects, because they (almost) never match. + // this wil prevent undo when reset has been done + + const state_ = JSON.stringify(state, (k, v) => k === "userPieces" ? null : v) + const getInitialState_ = JSON.stringify(getInitialState(), (k, v) => k === "userPieces" ? null : v) + + if( + JSON.stringify(prevState.userPieces) !== JSON.stringify(state.userPieces) && + state_ !== getInitialState_ + ){ setState(prevState) setQueue(state.userPieces) setUndosLeft(undosLeft - 1) From c178d554a2d1b1c73600d905f33079f4751a1707 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 02:55:00 +0100 Subject: [PATCH 04/13] Fix undo after new round + disable undo button --- src/App.tsx | 34 ++++++++++++++++++++++++++++------ src/util.ts | 2 +- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c8a7714..a4981fe 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,6 +12,7 @@ export default function App() { const [prevState, setPrevState] = useState(state) const [undosLeft, setUndosLeft] = useState(undos) const [queue, setQueue] = useState<(IPiece | null)[] | null>(null) + const undoRef = useRef(null!) const boardRef = useRef(null) const [pointer, setPointer] = useState<{ offset: [number, number], @@ -50,7 +51,7 @@ export default function App() { const { width, height, x, y } = boardRef.current.getBoundingClientRect() const { colIndex, rowIndex } = snapPositionToBoard({ boardSize, width, height, x, y, pageX: mousePosWithOffset[0], pageY: mousePosWithOffset[1] }) const [fit, board] = checkIfPieceFitsAndUpdateBoard( - { board: state.board, piece: selectedPiece, squareLocation: [colIndex, rowIndex], boardSize } ) + { board: state.board, piece: selectedPiece, squareLocation: [colIndex, rowIndex], boardSize }) return [fit, fit ? board : state.board] }, [gameOver, mousePosWithOffset, state]) @@ -65,6 +66,9 @@ export default function App() { return { boardWithClearedRows, rowsToClear, colsToClear} }, [boardWithPreview, fit, state.board]) + // set this initial to disabled. So we don't mess with the 'undosLeft <= 0' on the button tag + useEffect(() => {undoRef.current.disabled = true}, []) + useEffect(() => { const highscore = Math.max(state.highscore, state.score).toString() localStorage.setItem(highscoreLocalStorageKey, highscore) @@ -77,6 +81,8 @@ export default function App() { })) setUndosLeft(undos) setPrevState(getInitialState()) + // disable on reset + undoRef.current.disabled = true } const undo = () => { @@ -87,7 +93,7 @@ export default function App() { const state_ = JSON.stringify(state, (k, v) => k === "userPieces" ? null : v) const getInitialState_ = JSON.stringify(getInitialState(), (k, v) => k === "userPieces" ? null : v) - + if( JSON.stringify(prevState.userPieces) !== JSON.stringify(state.userPieces) && state_ !== getInitialState_ @@ -95,6 +101,10 @@ export default function App() { setState(prevState) setQueue(state.userPieces) setUndosLeft(undosLeft - 1) + // disable after undo + undoRef.current.disabled = true + // Cancel that the brick was picked up, because we set the prevState on the pick-up + pointerUpHandler() } } @@ -114,10 +124,12 @@ export default function App() { const { newBoard, rowsAndColsCleared } = clearFullRows(boardWithPreview, boardSize) setState(prevState => { const userPieces = prevState.userPieces.map((piece, i) => i === selectedPieceIndex ? null : piece) + // only enable if user has any undos left + undoRef.current.disabled = undosLeft <= 0 return ({ board: newBoard, userPieces: userPieces.every(p => p == null) - ? getNewPieces(queue) + ? getNewPieces(queue, undoRef) : userPieces, selectedPieceIndex: null, score: prevState.score + rowsAndColsCleared * boardSize, @@ -125,11 +137,13 @@ export default function App() { }) }) + setPrevState(state) setQueue(null) // if (shouldSucceed !== fit) { // prompt("red test", newTest) // } + }, [boardWithPreview, fit, queue, state]) usePointerExit(pointerUpHandler) @@ -157,7 +171,7 @@ export default function App() {
Score: {state.score}
High Score: {state.highscore}
- @@ -277,9 +291,17 @@ const getOffsetFromPieceInPixels: (p: IPiece, pointerType: string) => [number, n const getInitialState: () => IState = () => ({ highscore: Number(window.localStorage.getItem(highscoreLocalStorageKey)) ?? 0, board: createEmptyBoard(boardSize), - userPieces: getNewPieces(null), + userPieces: getNewPieces(null, null), selectedPieceIndex: null, score: 0 }) -const getNewPieces = (queue: (IPiece | null)[] | null) => (queue ? queue : drawN(pieces, 3)) +const getNewPieces = (queue: (IPiece | null)[] | null, undoRef: any) => { + if(queue !== null){ + return queue + } else{ + // disable undo when new round has been seen + undoRef && (undoRef.current.disabled = true) + return drawN(pieces, 3) + } +} diff --git a/src/util.ts b/src/util.ts index 093f739..3f3fd61 100644 --- a/src/util.ts +++ b/src/util.ts @@ -49,7 +49,7 @@ export function checkIfPieceFitsAndUpdateBoard({ ) { return [false, null] } - + const updatedBoard = board.slice() as IBoard for (let i = 0; i < piece.length; i++) { From 6abe29f31538cff456a03befbc12a77cc6edc6e7 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 03:06:43 +0100 Subject: [PATCH 05/13] Add undosleft to useEffect --- src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index a4981fe..b9a58ba 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -67,7 +67,7 @@ export default function App() { }, [boardWithPreview, fit, state.board]) // set this initial to disabled. So we don't mess with the 'undosLeft <= 0' on the button tag - useEffect(() => {undoRef.current.disabled = true}, []) + useEffect(() => {undoRef.current.disabled = true}, [undoRef]) useEffect(() => { const highscore = Math.max(state.highscore, state.score).toString() From 0b60adb43794f7d8469b9cfd4482c94240d60e51 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 03:09:26 +0100 Subject: [PATCH 06/13] Fix removed undoRef from setState --- src/App.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index b9a58ba..85fa5c9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -125,7 +125,7 @@ export default function App() { setState(prevState => { const userPieces = prevState.userPieces.map((piece, i) => i === selectedPieceIndex ? null : piece) // only enable if user has any undos left - undoRef.current.disabled = undosLeft <= 0 + return ({ board: newBoard, userPieces: userPieces.every(p => p == null) @@ -136,7 +136,7 @@ export default function App() { highscore: prevState.highscore }) }) - + undoRef.current.disabled = undosLeft <= 0 setPrevState(state) setQueue(null) From bb56476ba5b23acdafdb8ace908fdfd3fb6e4948 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 03:12:25 +0100 Subject: [PATCH 07/13] Add undoRef to useCallback --- src/App.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 85fa5c9..c34b2f5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -125,7 +125,7 @@ export default function App() { setState(prevState => { const userPieces = prevState.userPieces.map((piece, i) => i === selectedPieceIndex ? null : piece) // only enable if user has any undos left - + return ({ board: newBoard, userPieces: userPieces.every(p => p == null) @@ -144,7 +144,7 @@ export default function App() { // prompt("red test", newTest) // } - }, [boardWithPreview, fit, queue, state]) + }, [boardWithPreview, fit, queue, state, undosLeft]) usePointerExit(pointerUpHandler) From e157d417650ee0067df9a36386b4e50779fb9952 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 03:15:27 +0100 Subject: [PATCH 08/13] Added undosLeft to useCallback --- src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index c34b2f5..1f0cbe8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -144,7 +144,7 @@ export default function App() { // prompt("red test", newTest) // } - }, [boardWithPreview, fit, queue, state, undosLeft]) + }, [boardWithPreview, fit, queue, state, undoRef, undosLeft]) usePointerExit(pointerUpHandler) From f6c0996bb0c85daf3c2289a7ce23a3943fc21567 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 03:20:03 +0100 Subject: [PATCH 09/13] Fix README error --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 0736453..68d7fbf 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # Klods -Klods is a game where you have to think a head. At each level random bricks appear, now stackle them up to get full lines either up/down or to the side to get points. - - +Klods is a game where you have to think ahead. At each level random bricks appear, now stackle them up to get full lines either up/down or to the side to get points. ## Screenshots From f21877e2d7729fadf2ccc79d1448ae592134c88d Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 03:32:11 +0100 Subject: [PATCH 10/13] Changed margin to grid --- src/App.css | 11 ++++++----- src/App.tsx | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/App.css b/src/App.css index 060ec42..28b6b16 100644 --- a/src/App.css +++ b/src/App.css @@ -10,10 +10,6 @@ overflow: hidden; } -.undo { - margin-top: 1em; -} - .app-wrapper { height: 100vh; width: 100vw; @@ -21,10 +17,15 @@ margin: auto; display: grid; grid-template-rows: auto 1fr; - gap: 16px 0; + gap: 16px 10px; justify-items: center; } +.undo { + grid-column-start: 1; + grid-column-end: 3; +} + .header { text-align: center; margin: 0; diff --git a/src/App.tsx b/src/App.tsx index 1f0cbe8..1a70859 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -170,10 +170,11 @@ export default function App() {
Score: {state.score}
High Score: {state.highscore}
+ +
-
From 6fd3f0559bb1e49a38d6a0baf73a9542e2b4b233 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 23 Nov 2022 03:35:25 +0100 Subject: [PATCH 11/13] Fix changed gap back to 0 --- src/App.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.css b/src/App.css index 28b6b16..8afcc54 100644 --- a/src/App.css +++ b/src/App.css @@ -17,7 +17,7 @@ margin: auto; display: grid; grid-template-rows: auto 1fr; - gap: 16px 10px; + gap: 16px 0; justify-items: center; } From ef2d67b4083460ab0e82ca6844ed6e8c7c513f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Wed, 23 Nov 2022 23:32:57 +0100 Subject: [PATCH 12/13] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 68d7fbf..a6c5aa7 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,7 @@ # Klods -Klods is a game where you have to think ahead. At each level random bricks appear, now stackle them up to get full lines either up/down or to the side to get points. - - -## Screenshots +Klods is a tetris-like game where you have to think ahead. Random puzzle pieces appear, and it is your job to fit them together, to clear rows and columns. Each tile cleared gives a point! ![App Screenshot](https://screenshot.launchbrightly.com/klods/klods/desktop/dark/game.png) From 39e17cba8c01a0cb85ffd82c42596a8f9156bdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Wed, 23 Nov 2022 23:34:52 +0100 Subject: [PATCH 13/13] Add missing linebreaks --- src/constants.ts | 2 +- src/util.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 69e49dd..256ab13 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -30,4 +30,4 @@ export const hues = [ export const highscoreLocalStorageKey = "KLODS_HIGHSCORE" -export const undos = 3 \ No newline at end of file +export const undos = 3 diff --git a/src/util.ts b/src/util.ts index 3f3fd61..093f739 100644 --- a/src/util.ts +++ b/src/util.ts @@ -49,7 +49,7 @@ export function checkIfPieceFitsAndUpdateBoard({ ) { return [false, null] } - + const updatedBoard = board.slice() as IBoard for (let i = 0; i < piece.length; i++) {