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

Added playble tic tac toe game in Board game section #401

Closed

Conversation

Sumanbhadra
Copy link
Contributor

@Sumanbhadra Sumanbhadra commented Oct 25, 2024

Fixes: #385

  • Interactive Gameplay: Users can play as X or O, with the game alternating between players.
  • Win/Draw Detection: The game identifies winning conditions for both players and displays a message for a draw if all cells are filled without a winner.
  • Reset Functionality: A reset button allows players to start a new game.
Screen.Recording.2024-10-26.003644.mp4

@RamakrushnaBiswal take a look.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new Tic Tac Toe game component.
    • Added navigation to the Tic Tac Toe game via the Instant Play button.
    • New route established for the Tic Tac Toe game.
  • Documentation

    • Updated contributors' section in the README file, reflecting changes in contributor names and links.

Copy link

vercel bot commented Oct 25, 2024

@Sumanbhadra is attempting to deploy a commit to the bunty's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Oct 25, 2024

Walkthrough

The changes in this pull request involve updates to the README.md file to modify contributor information, the addition of a new TicTacToe component, and the introduction of routing for this component. The Boardgame component has been updated to include a navigation link for the Instant Play button, which redirects users to the Tic Tac Toe game. Overall, the modifications enhance navigation and introduce new gameplay functionality without altering existing project descriptions or features.

Changes

File Path Change Summary
README.md Updated contributors: alolika bhowmikAshwini_ab, Vinay Anand LodhiNilanchal, Ashwini_abalolika bhowmik.
frontend/src/components/Pages/Boardgame.jsx Added import for Link from react-router-dom; modified Instant Play button to use Link for navigation.
frontend/src/components/Pages/Games/TicTacToe.jsx Introduced TicTacToe component with game logic, including state management and rendering of the game board.
frontend/src/router/index.jsx Added new route for TicTacToe component: <Route path="/boardgame/TicTacToe" element={<TicTacToe />} />.

Assessment against linked issues

Objective Addressed Explanation
Redirect "Instant Play" button to Tic Tac Toe (385)
Implement Tic Tac Toe game functionality (385)

Possibly related PRs

Suggested labels

good first issue

Suggested reviewers

  • RamakrushnaBiswal

🐰 In the code, we hop and play,
With Tic Tac Toe, we’ll spend the day.
Contributors shine, their names now bright,
In the README, they take flight!
So gather round, let’s code and cheer,
For fun and games are finally here! 🎉


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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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
Contributor

Thank you for submitting your pull request! 🙌 We'll review it as soon as possible. In the meantime, please ensure that your changes align with our CONTRIBUTING.md. If there are any specific instructions or feedback regarding your PR, we'll provide them here. Thanks again for your contribution! 😊

Copy link
Contributor

@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: 9

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between abe91c3 and e5b2664.

📒 Files selected for processing (4)
  • README.md (3 hunks)
  • frontend/src/components/Pages/Boardgame.jsx (2 hunks)
  • frontend/src/components/Pages/Games/TicTacToe.jsx (1 hunks)
  • frontend/src/router/index.jsx (2 hunks)
🧰 Additional context used
🪛 Markdownlint
README.md

283-283: Column: 1
Hard tabs

(MD010, no-hard-tabs)


284-284: Column: 1
Hard tabs

(MD010, no-hard-tabs)

🔇 Additional comments (3)
frontend/src/router/index.jsx (1)

25-25: LGTM!

The import statement follows the project's conventions and maintains proper component organization under the Games directory.

frontend/src/components/Pages/Boardgame.jsx (1)

25-25: LGTM! Import statement is correctly placed.

The addition of the Link import from react-router-dom is appropriate for implementing navigation to the new TicTacToe game.

README.md (1)

277-280: LGTM: Contributor information updates are consistent.

The changes to the contributor information match the AI summary:

  • Added Ashwini_ab
  • Updated alolika bhowmik's information
  • Updated Vinay Anand Lodhi to Nilanchal

The changes maintain the table structure and include all necessary information (avatar, GitHub link, and name).

Also applies to: 286-289, 314-317, 330-333

@@ -41,6 +42,7 @@ const router = createBrowserRouter(
<Route path="/email-verify" element={<EmailVerify />} />
<Route path="/membership" element={<Membership />} />
<Route path="/help" element={<HelpAndSupport />} />
<Route path="/TicTacToe" element={<TicTacToe />} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider route naming consistency and organization.

The current implementation has a few areas for improvement:

  1. The route path uses PascalCase ("/TicTacToe") while other routes use kebab-case or lowercase. Consider using "/tic-tac-toe" for consistency.
  2. Since this is part of the Board game section, consider either:
    • Grouping it near the "/boardgame" route for better code organization
    • Using nested routing under "/boardgame" for better URL hierarchy

Consider this refactoring approach:

      <Route path="/boardgame" element={<Boardgame />} />
+     <Route path="/boardgame/tic-tac-toe" element={<TicTacToe />} />
      <Route path="/events" element={<Event />} />
      ...
-     <Route path="/TicTacToe" element={<TicTacToe />} />

Note: If you implement this change, remember to update the corresponding Link component in Boardgame.jsx to use the new path.

Committable suggestion was skipped due to low confidence.

Comment on lines +1 to +6
import React, { useState } from 'react';

function TicTacToe() {
const [board, setBoard] = useState(Array(9).fill(null));
const [isXNext, setIsXNext] = useState(true);
const winner = calculateWinner(board);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider enhancing type safety and accessibility

While the basic setup is correct, consider these improvements:

  1. Add PropTypes or TypeScript for better type safety
  2. Consider extracting game logic into a custom hook for better separation of concerns

Example implementation of a custom hook:

function useGameState() {
  const [board, setBoard] = useState(Array(9).fill(null));
  const [isXNext, setIsXNext] = useState(true);
  const winner = calculateWinner(board);
  
  // ... game logic here
  
  return { board, isXNext, winner, handleClick, resetGame };
}

Comment on lines 35 to 53
<div className="mt-5 content-center ">
{winner ? (
<h2 className="text-2xl font-semibold text-green-600 text-center">
{winner} Wins!
</h2>
) : board.every((cell) => cell) ? (
<h2 className="text-2xl font-semibold text-red-600 text-center">It's a Draw!</h2>
) : (
<h2 className="text-xl font-semibold text-gray-700 text-center">
Next Player: {isXNext ? 'X' : 'O'}
</h2>
)}
<button
onClick={resetGame}
className="ml-1 mt-4 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 hover:text-white transition-all duration-200"
>
Reset Game
</button>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance game status with score tracking

Consider adding a score tracking feature to make the game more engaging across multiple rounds.

Add score tracking:

+ const [scores, setScores] = useState({ X: 0, O: 0 });

  const resetGame = () => {
    setBoard(Array(9).fill(null));
    setIsXNext(true);
  };

+ const updateScore = (winner) => {
+   if (winner) {
+     setScores(prev => ({
+       ...prev,
+       [winner]: prev[winner] + 1
+     }));
+   }
+ };

+ // Add score display in the UI
+ <div className="mt-3 text-lg">
+   <span className="mr-4">X: {scores.X}</span>
+   <span>O: {scores.O}</span>
+ </div>

Committable suggestion was skipped due to low confidence.

Comment on lines +58 to +77
function calculateWinner(board) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];

for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (board[a] && board[a] === board[b] && board[a] === board[c]) {
return board[a];
}
}
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize winner calculation with memoization

The winner calculation could be optimized to prevent unnecessary recalculations.

Consider using useMemo:

+ import React, { useState, useMemo } from 'react';

  function TicTacToe() {
-   const winner = calculateWinner(board);
+   const winner = useMemo(() => calculateWinner(board), [board]);

Committable suggestion was skipped due to low confidence.

Comment on lines 25 to 33
{board.map((value, index) => (
<button
key={index}
onClick={() => handleClick(index)}
className="w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500 hover:bg-amber-300 transition-all duration-200 rounded-md"
>
{value}
</button>
))}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve accessibility and keyboard navigation

The game board buttons need accessibility enhancements:

  1. Missing aria-labels for screen readers
  2. No keyboard navigation support

Apply these improvements:

 <button
   key={index}
   onClick={() => handleClick(index)}
+  aria-label={`Cell ${index + 1}, ${value || 'empty'}`}
+  tabIndex={0}
+  disabled={board[index] || winner}
   className={`w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl 
-    font-semibold text-black-800 border-2 border-amber-500 hover:bg-amber-300
+    font-semibold text-black-800 border-2 border-amber-500 
+    ${!board[index] && !winner ? 'hover:bg-amber-300' : 'cursor-not-allowed opacity-75'}
     transition-all duration-200 rounded-md`}
 >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{board.map((value, index) => (
<button
key={index}
onClick={() => handleClick(index)}
className="w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500 hover:bg-amber-300 transition-all duration-200 rounded-md"
>
{value}
</button>
))}
{board.map((value, index) => (
<button
key={index}
onClick={() => handleClick(index)}
aria-label={`Cell ${index + 1}, ${value || 'empty'}`}
tabIndex={0}
disabled={board[index] || winner}
className={`w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500 ${!board[index] && !winner ? 'hover:bg-amber-300' : 'cursor-not-allowed opacity-75'} transition-all duration-200 rounded-md`}
>
{value}
</button>
))}

@@ -396,7 +397,7 @@ function Boardgame() {
onClick={() => handleInstantPlay(board)}
className="px-4 py-2 text-white bg-blue-500 rounded-lg opacity-0 transition-opacity duration-700 delay-300 group-hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
Instant Play
<Link to="/TicTacToe">Instant Play</Link>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Conditionally render the Instant Play button.

Currently, the "Instant Play" button appears for all board games, but based on the PR objectives, only Tic Tac Toe should be playable. This might confuse users who expect other games to be playable as well.

Consider conditionally rendering the button only for Tic Tac Toe:

<div className="flex space-x-2 mt-4">
  <button
    onClick={() => handleOpenInstructions(board)}
    className="px-4 py-2 text-white bg-green-500 rounded-lg opacity-0 transition-opacity duration-700 delay-300 group-hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
  >
    See Instructions
  </button>
+  {board.title === "Tic-Tac-Toe" && (
    <Link
      to="/TicTacToe"
      className="inline-block px-4 py-2 text-white bg-blue-500 rounded-lg opacity-0 transition-opacity duration-700 delay-300 group-hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
    >
      Instant Play
    </Link>
+  )}
</div>

Committable suggestion was skipped due to low confidence.


⚠️ Potential issue

Fix button accessibility and remove unused handler.

The current implementation has several issues:

  1. Nesting a Link inside a button is an accessibility anti-pattern as it creates nested interactive elements
  2. There's an unused onClick handler (handleInstantPlay)
  3. The styling might not properly propagate to the Link

Consider this implementation instead:

-<button
-  onClick={() => handleInstantPlay(board)}
-  className="px-4 py-2 text-white bg-blue-500 rounded-lg opacity-0 transition-opacity duration-700 delay-300 group-hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
->
-  <Link to="/TicTacToe">Instant Play</Link>
-</button>
+<Link
+  to="/TicTacToe"
+  className="inline-block px-4 py-2 text-white bg-blue-500 rounded-lg opacity-0 transition-opacity duration-700 delay-300 group-hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
+>
+  Instant Play
+</Link>

Committable suggestion was skipped due to low confidence.

Comment on lines +277 to +280
<a href="https://github.com/Ashwinib26">
<img src="https://avatars.githubusercontent.com/u/149402720?v=4" width="100;" alt="Ashwinib26"/>
<br />
<sub><b>alolika bhowmik</b></sub>
<sub><b>Ashwini_ab</b></sub>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix indentation using spaces instead of tabs.

The indentation in these sections uses hard tabs. For consistency with the rest of the file and to follow markdown best practices, replace tabs with spaces.

Apply this change to fix the indentation:

-                <a href="https://github.com/Ashwinib26">
-                    <img src="https://avatars.githubusercontent.com/u/149402720?v=4" width="100;" alt="Ashwinib26"/>
-                    <br />
-                    <sub><b>Ashwini_ab</b></sub>
+                <a href="https://github.com/Ashwinib26">
+                    <img src="https://avatars.githubusercontent.com/u/149402720?v=4" width="100;" alt="Ashwinib26"/>
+                    <br />
+                    <sub><b>Ashwini_ab</b></sub>

Also applies to: 286-289

@RamakrushnaBiswal RamakrushnaBiswal added enhancement New feature or request level2 for 25 points gssoc-ext gssoc-extd program hacktoberfest accepted hacktoberfest-accepted repo labels Oct 26, 2024
Copy link
Owner

@RamakrushnaBiswal RamakrushnaBiswal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sumanbhadra resolve the conflicts and resolve coderabit changes

Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (2)
frontend/src/components/Pages/Games/TicTacToe.jsx (2)

3-6: Add cleanup logic for component unmounting

Consider adding a cleanup mechanism using useEffect to prevent any potential memory leaks, especially if you plan to add features like timers or multiplayer functionality in the future.

+ import React, { useState, useEffect } from 'react';

  function TicTacToe() {
    const [board, setBoard] = useState(Array(9).fill(null));
    const [isXNext, setIsXNext] = useState(true);
    const winner = calculateWinner(board);
+   
+   useEffect(() => {
+     return () => {
+       // Cleanup logic for future implementations
+     };
+   }, []);

40-53: Enhance game status accessibility

Add ARIA live regions to announce game status changes to screen readers.

- <div className="mt-5 content-center ">
+ <div className="mt-5 content-center" role="status" aria-live="polite">
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5b94853 and 0b3bb78.

📒 Files selected for processing (2)
  • frontend/src/components/Pages/Boardgame.jsx (9 hunks)
  • frontend/src/components/Pages/Games/TicTacToe.jsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/Pages/Boardgame.jsx
🔇 Additional comments (1)
frontend/src/components/Pages/Games/TicTacToe.jsx (1)

1-86: Implementation doesn't match online gameplay requirement

The current implementation is a local-only game, but issue #385 specifically requests an online multiplayer feature. Consider extending this implementation to support online gameplay:

  1. Add WebSocket connection for real-time game state sync
  2. Implement player rooms/matching
  3. Add online player status indicators

Let's check if there are any WebSocket-related implementations in the codebase:

Would you like assistance in implementing the online multiplayer feature?

aria-label={`Cell ${index + 1}, ${value || 'empty'}`}
tabIndex={0}
disabled={board[index] || winner}
className="w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500 ${!board[index] && !winner ? 'hover:bg-amber-300' : 'cursor-not-allowed opacity-75'} transition-all duration-200 rounded-md"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix template string syntax in className

The className contains an improperly formatted template string that won't work as expected.

- className="w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500  ${!board[index] && !winner ? 'hover:bg-amber-300' : 'cursor-not-allowed opacity-75'} transition-all duration-200 rounded-md"
+ className={`w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500 ${!board[index] && !winner ? 'hover:bg-amber-300' : 'cursor-not-allowed opacity-75'} transition-all duration-200 rounded-md`}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
className="w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500 ${!board[index] && !winner ? 'hover:bg-amber-300' : 'cursor-not-allowed opacity-75'} transition-all duration-200 rounded-md"
className={`w-20 h-20 bg-amber-200 flex items-center justify-center text-3xl font-semibold text-black-800 border-2 border-amber-500 ${!board[index] && !winner ? 'hover:bg-amber-300' : 'cursor-not-allowed opacity-75'} transition-all duration-200 rounded-md`}

Comment on lines +54 to +60
<button
onClick={resetGame}
className="ml-1 mt-4 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 hover:text-white transition-all duration-200"
>
Reset Game
</button>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add keyboard shortcut for game reset

Consider adding a keyboard shortcut (e.g., 'R' key) for resetting the game to improve user experience.

+ useEffect(() => {
+   const handleKeyPress = (e) => {
+     if (e.key.toLowerCase() === 'r') {
+       resetGame();
+     }
+   };
+   window.addEventListener('keydown', handleKeyPress);
+   return () => window.removeEventListener('keydown', handleKeyPress);
+ }, []);

  <button
    onClick={resetGame}
+   title="Press 'R' to reset game"
    className="ml-1 mt-4 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 hover:text-white transition-all duration-200"
  >
    Reset Game
  </button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button
onClick={resetGame}
className="ml-1 mt-4 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 hover:text-white transition-all duration-200"
>
Reset Game
</button>
</div>
useEffect(() => {
const handleKeyPress = (e) => {
if (e.key.toLowerCase() === 'r') {
resetGame();
}
};
window.addEventListener('keydown', handleKeyPress);
return () => window.removeEventListener('keydown', handleKeyPress);
}, []);
<button
onClick={resetGame}
title="Press 'R' to reset game"
className="ml-1 mt-4 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 hover:text-white transition-all duration-200"
>
Reset Game
</button>
</div>

Comment on lines +8 to +14
const handleClick = (index) => {
if (board[index] || winner) return;
const newBoard = board.slice();
newBoard[index] = isXNext ? 'X' : 'O';
setBoard(newBoard);
setIsXNext(!isXNext);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add input validation and state update safety

The handleClick function should validate the input index and use the functional update form of setState to handle potential race conditions.

  const handleClick = (index) => {
+   if (typeof index !== 'number' || index < 0 || index > 8) return;
    if (board[index] || winner) return;
-   const newBoard = board.slice();
-   newBoard[index] = isXNext ? 'X' : 'O';
-   setBoard(newBoard);
+   setBoard(currentBoard => {
+     if (currentBoard[index]) return currentBoard;
+     const newBoard = currentBoard.slice();
+     newBoard[index] = isXNext ? 'X' : 'O';
+     return newBoard;
+   });
    setIsXNext(!isXNext);
  };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleClick = (index) => {
if (board[index] || winner) return;
const newBoard = board.slice();
newBoard[index] = isXNext ? 'X' : 'O';
setBoard(newBoard);
setIsXNext(!isXNext);
};
const handleClick = (index) => {
if (typeof index !== 'number' || index < 0 || index > 8) return;
if (board[index] || winner) return;
setBoard(currentBoard => {
if (currentBoard[index]) return currentBoard;
const newBoard = currentBoard.slice();
newBoard[index] = isXNext ? 'X' : 'O';
return newBoard;
});
setIsXNext(!isXNext);
};

Copy link

vercel bot commented Oct 27, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
play-cafe ❌ Failed (Inspect) Oct 27, 2024 1:51am

@RamakrushnaBiswal
Copy link
Owner

@Sumanbhadra error while deployment
Screenshot_2024-10-27-07-22-14-17_40deb401b9ffe8e1df2f1cc5ba480b12

Copy link
Contributor

This PR has been automatically closed due to inactivity from the owner for 3 days.

@github-actions github-actions bot added the Stale label Oct 31, 2024
@github-actions github-actions bot closed this Oct 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request gssoc-ext gssoc-extd program hacktoberfest accepted hacktoberfest-accepted repo level2 for 25 points Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feat: Adding online tic tac toe game
2 participants