Skip to content
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

Closed
wants to merge 4 commits into from
Closed

Conversation

od-hunter
Copy link

@od-hunter od-hunter commented Aug 27, 2024

Hi @Cheelax , Here i created another component, created game state and wrote a draft custom hook for the useGameLogic

Summary by CodeRabbit

  • New Features
    • Introduced a custom hook for managing game logic in a grid-based game.
    • Added a new PlayerPanel component to display player statistics with dynamic rendering.
  • Improvements
    • Refactored the GameBoard component to enhance state management and organization.
    • Streamlined game state updates to improve clarity and maintainability.

Copy link

vercel bot commented Aug 27, 2024

@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.

Copy link

coderabbitai bot commented Aug 27, 2024

Walkthrough

The changes introduce a custom React hook, useGameLogic, to manage the logic of a grid-based game, alongside a refactored GameBoard component that centralizes game state management. Additionally, a new PlayerPanel component is added to display player statistics effectively. These modifications aim to enhance the modularity and maintainability of the codebase.

Changes

Files Change Summary
client/src/hooks/useGameLogic.ts Introduced a custom hook to manage game logic, including state handling for grid, animations, and user interactions.
client/src/ui/components/GameBoard.tsx Refactored to use a consolidated GameState interface, simplifying state management and improving code organization.
client/src/ui/components/PlayerPanel.tsx Added a new component to display player statistics with dynamic rendering based on props, enhancing UI presentation.

Possibly related issues

🐇 In a game where blocks fall and play,
A hook brings logic to save the day!
With panels for scores and states all neat,
The code now dances to a rhythmic beat!
Hooray for structure, oh what a sight,
A modular game, oh what delight! 🥳✨


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?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between 6d8a290 and 9b857da.

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.

Comment on lines +79 to +131
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;
}, []);
Copy link

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.

Comment on lines +133 to +203
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,
}));
}, []);
Copy link

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.

Comment on lines +205 to +241
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;
}, []);
Copy link

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.

Comment on lines +271 to +339
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;
Copy link

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.

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between 9b857da and d50483d.

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.

Comment on lines +146 to +190
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;
Copy link

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.

Comment on lines +271 to +301
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;
Copy link

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.

Comment on lines +309 to +339
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;
Copy link

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.

@Cheelax Cheelax closed this Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants