-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Od hunter branch #31
Od hunter branch #31
Conversation
@od-hunter is attempting to deploy a commit to the z-korp Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThe changes introduce a custom React hook, Changes
Possibly related issues
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Outside diff range, codebase verification and nitpick comments (1)
client/src/ui/components/GameBoard.tsx (1)
Line range hint
146-265
: Consider optimizing the nested loops for performance.The function logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (3)
- client/src/hooks/useGameLogic.ts (1 hunks)
- client/src/ui/components/GameBoard.tsx (25 hunks)
- client/src/ui/components/PlayerPanel.tsx (1 hunks)
Additional comments not posted (9)
client/src/ui/components/PlayerPanel.tsx (4)
1-15
: LGTM!The imports and interface declaration are correct.
The code changes are approved.
17-23
: LGTM!The component declaration and props destructuring are correct.
The code changes are approved.
24-73
: LGTM!The JSX structure and usage of conditional classes are correct. The component correctly renders player statistics and uses FontAwesome icons.
The code changes are approved.
78-78
: LGTM!The export statement is correct.
The code changes are approved.
client/src/hooks/useGameLogic.ts (3)
1-44
: LGTM!The imports and interface declarations are correct.
The code changes are approved.
46-66
: LGTM!The hook declaration and initial state setup are correct.
The code changes are approved.
243-544
: LGTM!The remaining functions and hook return statement are correct.
The code changes are approved.
client/src/ui/components/GameBoard.tsx (2)
Line range hint
1-53
: LGTM!The imports and interface declarations are correct.
The code changes are approved.
Line range hint
54-85
: LGTM!The component declaration and initial state setup are correct.
The code changes are approved.
const applyGravity = useCallback(async () => { | ||
let changesMade = false; | ||
|
||
await new Promise((resolve) => { | ||
const newGrid = gameState.grid.map((row) => | ||
row.map((cell) => ({ ...cell })) | ||
); | ||
changesMade = false; | ||
|
||
for (let row = rows - 2; row >= 0; row--) { | ||
for (let col = 0; col < cols; col++) { | ||
if (newGrid[row][col].pieceId !== null && newGrid[row][col].isStart) { | ||
const piece = PIECES.find( | ||
(p) => String(p.id) === newGrid[row][col].pieceId | ||
); | ||
if (piece) { | ||
let canFall = true; | ||
for (let i = 0; i < piece.width; i++) { | ||
if ( | ||
col + i >= cols || | ||
newGrid[row + 1][col + i].pieceId !== null | ||
) { | ||
canFall = false; | ||
break; | ||
} | ||
} | ||
if (canFall) { | ||
// Déplacer la pièce d'une ligne vers le bas | ||
for (let i = 0; i < piece.width; i++) { | ||
newGrid[row + 1][col + i] = { ...newGrid[row][col + i] }; | ||
newGrid[row][col + i] = { | ||
id: `${row}-${col + i}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
}; | ||
} | ||
changesMade = true; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
resolve(newGrid); | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
grid: newGrid, | ||
})); | ||
return newGrid; | ||
}); | ||
|
||
return changesMade; | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider optimizing the nested loops for performance.
The function logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
const applyGravityLoop = useCallback(async () => { | ||
// Implement applyGravityLoop logic | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
isAnimating: true, | ||
isFalling: true, | ||
})); | ||
|
||
let rowsCleared = true; | ||
while (rowsCleared) { | ||
let changesMade = true; | ||
while (changesMade) { | ||
changesMade = await applyGravity(); | ||
await new Promise((resolve) => setTimeout(resolve, 200)); | ||
} | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
isFalling: false, | ||
})); | ||
|
||
await new Promise((resolve) => setTimeout(resolve, 200)); | ||
rowsCleared = await checkAndClearFullLines(); | ||
await new Promise((resolve) => setTimeout(resolve, 200)); | ||
} | ||
await new Promise((resolve) => setTimeout(resolve, 200)); | ||
|
||
//Si aucun bonus n'est utilisé alors nouvelle ligne | ||
if ( | ||
!gameState.bonusHammer && | ||
!gameState.bonusTiki && | ||
!gameState.bonusWave | ||
) { | ||
await insertNewLine(); | ||
} | ||
|
||
await new Promise((resolve) => setTimeout(resolve, 300)); | ||
|
||
rowsCleared = true; | ||
while (rowsCleared) { | ||
let changesMade = true; | ||
while (changesMade) { | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
isFalling: true, | ||
})); | ||
changesMade = await applyGravity(); | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
isFalling: false, | ||
})); | ||
await new Promise((resolve) => setTimeout(resolve, 100)); | ||
} | ||
await new Promise((resolve) => setTimeout(resolve, 500)); | ||
rowsCleared = await checkAndClearFullLines(); | ||
await new Promise((resolve) => setTimeout(resolve, 100)); | ||
} | ||
|
||
if (isGridEmpty(stateGridRef.current)) { | ||
handleEmptyGrid(); | ||
|
||
await new Promise((resolve) => setTimeout(resolve, 200)); | ||
|
||
await insertNewLine(); | ||
|
||
await new Promise((resolve) => setTimeout(resolve, 300)); | ||
} | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
isAnimating: false, | ||
})); | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider optimizing the nested loops for performance.
The function logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
const checkAndClearFullLines = useCallback(async () => { | ||
let rowsCleared = false; | ||
await new Promise((resolve) => { | ||
const newGrid = gameState.grid.map((row) => | ||
row.map((cell) => ({ ...cell })) | ||
); | ||
|
||
for (let row = 0; row < rows; row++) { | ||
if (newGrid[row].every((cell) => cell.pieceId !== null)) { | ||
// Ligne complète, on la supprime | ||
rowsCleared = true; | ||
for (let i = row; i > 0; i--) { | ||
newGrid[i] = newGrid[i - 1].map((cell) => ({ | ||
...cell, | ||
id: `${i}-${cell.id.split("-")[1]}`, | ||
})); | ||
} | ||
// Vider la première ligne | ||
newGrid[0] = newGrid[0].map((cell, col) => ({ | ||
id: `0-${col}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
})); | ||
} | ||
} | ||
|
||
resolve(newGrid); | ||
stateGridRef.current = newGrid; | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
grid: newGrid, | ||
})); | ||
return newGrid; | ||
}); | ||
return rowsCleared; | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider optimizing the nested loops for performance.
The function logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
const newGrid = gameState.grid.map((row) => | ||
row.map((cell) => ({ ...cell })) | ||
); | ||
|
||
for (let row = 0; row < rows; row++) { | ||
if (newGrid[row].every((cell) => cell.pieceId !== null)) { | ||
// Ligne complète, on la supprime | ||
rowsCleared = true; | ||
for (let i = row; i > 0; i--) { | ||
newGrid[i] = newGrid[i - 1].map((cell) => ({ | ||
...cell, | ||
id: `${i}-${cell.id.split("-")[1]}`, | ||
})); | ||
} | ||
// Vider la première ligne | ||
newGrid[0] = newGrid[0].map((cell, col) => ({ | ||
id: `0-${col}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
})); | ||
} | ||
} | ||
|
||
resolve(newGrid); | ||
stateGridRef.current = newGrid; | ||
return newGrid; | ||
}); | ||
resolve(newGrid); | ||
stateGridRef.current = newGrid; | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
grid: newGrid, | ||
})); | ||
return newGrid; | ||
}); | ||
return rowsCleared; | ||
}; | ||
|
||
const checkAndClearFullLinesFromBot = async () => { | ||
let rowsCleared = false; | ||
await new Promise((resolve) => { | ||
setGrid((prevGrid) => { | ||
const newGrid = prevGrid.map((row) => row.map((cell) => ({ ...cell }))); | ||
|
||
for (let row = rows - 1; row >= 0; row--) { | ||
if (newGrid[row].every((cell) => cell.pieceId !== null)) { | ||
// Ligne complète, on la supprime | ||
rowsCleared = true; | ||
for (let i = row; i > 0; i--) { | ||
newGrid[i] = newGrid[i - 1].map((cell) => ({ | ||
...cell, | ||
id: `${i}-${cell.id.split("-")[1]}`, | ||
})); | ||
} | ||
// Vider la première ligne | ||
newGrid[0] = newGrid[0].map((cell, col) => ({ | ||
id: `0-${col}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
const newGrid = gameState.grid.map((row) => | ||
row.map((cell) => ({ ...cell })) | ||
); | ||
|
||
for (let row = rows - 1; row >= 0; row--) { | ||
if (newGrid[row].every((cell) => cell.pieceId !== null)) { | ||
// Ligne complète, on la supprime | ||
rowsCleared = true; | ||
for (let i = row; i > 0; i--) { | ||
newGrid[i] = newGrid[i - 1].map((cell) => ({ | ||
...cell, | ||
id: `${i}-${cell.id.split("-")[1]}`, | ||
})); | ||
break; | ||
} | ||
// Vider la première ligne | ||
newGrid[0] = newGrid[0].map((cell, col) => ({ | ||
id: `0-${col}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
})); | ||
break; | ||
} | ||
} | ||
|
||
resolve(newGrid); | ||
return newGrid; | ||
}); | ||
resolve(newGrid); | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
grid: newGrid, | ||
})); | ||
return newGrid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider optimizing the nested loops for performance.
The function logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- client/src/ui/components/GameBoard.tsx (26 hunks)
Additional context used
Biome
client/src/ui/components/GameBoard.tsx
[error] 1048-1055: Expected corresponding JSX closing tag for 'Card'.
Opening tag
closing tag
(parse)
[error] 1048-1048: JSX fragment has no corresponding closing tag.
Opening fragment
Closing tag
(parse)
Additional comments not posted (21)
client/src/ui/components/GameBoard.tsx (21)
1-11
: LGTM!The imports are appropriate and necessary for the component's functionality.
Line range hint
14-26
: LGTM!The
GameBoardProps
interface is well-defined and appropriate for the component.
34-53
: LGTM!The
GameState
interface is comprehensive and well-structured, encapsulating all necessary state properties.
72-85
: LGTM!The state initialization is well-structured and consolidates multiple state properties into a single object, improving maintainability.
115-124
: LGTM!The
useEffect
hooks are correctly implemented to handle state changes and initialize the grid.
Line range hint
198-265
: LGTM!The
applyGravityLoop
method is correctly implemented to apply gravity in a loop and handle state changes.
347-366
: LGTM!The
clearSelectedLine
method is correctly implemented to clear the selected line and update the grid state.
373-395
: LGTM!The
insertNewLine
method is correctly implemented to insert a new line and update the grid state.
Line range hint
407-414
: LGTM!The
placePiece
method is correctly implemented to place a piece on the grid and update the grid cells.
Line range hint
420-433
: LGTM!The
checkCollision
method is correctly implemented to check for collisions when moving a piece on the grid.
Line range hint
440-473
: LGTM!The
startDragging
method is correctly implemented to initialize the dragging state and calculate the starting position and offset.
477-550
: LGTM!The
computeXAndDrag
method is correctly implemented to calculate the new position for the dragging piece and update the state.
Line range hint
555-621
: LGTM!The
setPieceToNewPositionAndTx
method is correctly implemented to set the piece to its new position and handle the move transaction.
626-633
: LGTM!The
handleTouchMove
method is correctly implemented to handle touch move events and update the dragging position.
638-644
: LGTM!The
handleMouseMove
method is correctly implemented to handle mouse move events and update the dragging position.
648-653
: LGTM!The
handleMouseEnd
method is correctly implemented to handle mouse end events and set the piece to its new position.
Line range hint
672-691
: LGTM!The
handleMove
method is correctly implemented to handle the move transaction and update the state.
Line range hint
701-717
: LGTM!The
handleEmptyGrid
method is correctly implemented to handle the move transaction when the grid is empty and update the state.
722-727
: LGTM!The
handleMouseUp
method is correctly implemented to handle mouse up events and set the piece to its new position.
Line range hint
730-760
: LGTM!The
initializeGrid
method is correctly implemented to initialize the grid and update the grid state.
Line range hint
773-803
: LGTM!The
markStartingCells
method is correctly implemented to mark the starting cells for each piece in the grid and update the grid cells.
const newGrid = gameState.grid.map((row) => | ||
row.map((cell) => ({ ...cell })) | ||
); | ||
changesMade = false; | ||
|
||
for (let row = rows - 2; row >= 0; row--) { | ||
for (let col = 0; col < cols; col++) { | ||
if (newGrid[row][col].pieceId !== null && newGrid[row][col].isStart) { | ||
const piece = PIECES.find( | ||
(p) => p.id === newGrid[row][col].pieceId | ||
); | ||
if (piece) { | ||
let canFall = true; | ||
for (let i = 0; i < piece.width; i++) { | ||
if ( | ||
col + i >= cols || | ||
newGrid[row + 1][col + i].pieceId !== null | ||
) { | ||
canFall = false; | ||
break; | ||
} | ||
if (canFall) { | ||
// Déplacer la pièce d'une ligne vers le bas | ||
for (let i = 0; i < piece.width; i++) { | ||
newGrid[row + 1][col + i] = { ...newGrid[row][col + i] }; | ||
newGrid[row][col + i] = { | ||
id: `${row}-${col + i}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
}; | ||
} | ||
changesMade = true; | ||
} | ||
if (canFall) { | ||
// Déplacer la pièce d'une ligne vers le bas | ||
for (let i = 0; i < piece.width; i++) { | ||
newGrid[row + 1][col + i] = { ...newGrid[row][col + i] }; | ||
newGrid[row][col + i] = { | ||
id: `${row}-${col + i}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
}; | ||
} | ||
changesMade = true; | ||
} | ||
} | ||
} | ||
} | ||
resolve(newGrid); | ||
return newGrid; | ||
}); | ||
} | ||
resolve(newGrid); | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
grid: newGrid, | ||
})); | ||
return newGrid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider optimizing the nested loops for performance.
The method logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
const newGrid = gameState.grid.map((row) => | ||
row.map((cell) => ({ ...cell })) | ||
); | ||
|
||
for (let row = 0; row < rows; row++) { | ||
if (newGrid[row].every((cell) => cell.pieceId !== null)) { | ||
// Ligne complète, on la supprime | ||
rowsCleared = true; | ||
for (let i = row; i > 0; i--) { | ||
newGrid[i] = newGrid[i - 1].map((cell) => ({ | ||
...cell, | ||
id: `${i}-${cell.id.split("-")[1]}`, | ||
})); | ||
} | ||
// Vider la première ligne | ||
newGrid[0] = newGrid[0].map((cell, col) => ({ | ||
id: `0-${col}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
})); | ||
} | ||
} | ||
|
||
resolve(newGrid); | ||
stateGridRef.current = newGrid; | ||
return newGrid; | ||
}); | ||
resolve(newGrid); | ||
stateGridRef.current = newGrid; | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
grid: newGrid, | ||
})); | ||
return newGrid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider optimizing the nested loops for performance.
The method logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
const newGrid = gameState.grid.map((row) => | ||
row.map((cell) => ({ ...cell })) | ||
); | ||
|
||
for (let row = rows - 1; row >= 0; row--) { | ||
if (newGrid[row].every((cell) => cell.pieceId !== null)) { | ||
// Ligne complète, on la supprime | ||
rowsCleared = true; | ||
for (let i = row; i > 0; i--) { | ||
newGrid[i] = newGrid[i - 1].map((cell) => ({ | ||
...cell, | ||
id: `${i}-${cell.id.split("-")[1]}`, | ||
})); | ||
break; | ||
} | ||
// Vider la première ligne | ||
newGrid[0] = newGrid[0].map((cell, col) => ({ | ||
id: `0-${col}`, | ||
pieceId: null, | ||
isStart: false, | ||
pieceIndex: null, | ||
})); | ||
break; | ||
} | ||
} | ||
|
||
resolve(newGrid); | ||
return newGrid; | ||
}); | ||
resolve(newGrid); | ||
setGameState((prevState) => ({ | ||
...prevState, | ||
grid: newGrid, | ||
})); | ||
return newGrid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider optimizing the nested loops for performance.
The method logic appears correct, but the nested loops may cause performance issues with larger grids.
Consider optimizing the nested loops to improve performance.
Hi @Cheelax , Here i created another component, created game state and wrote a draft custom hook for the useGameLogic
Summary by CodeRabbit
PlayerPanel
component to display player statistics with dynamic rendering.GameBoard
component to enhance state management and organization.