{"_id":"@ayshrj/checkers.js","_rev":"3-d47d4885e5d03ca8339aabe0ccedfe4f","name":"@ayshrj/checkers.js","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@ayshrj/checkers.js","version":"1.0.0","keywords":["ludo","board game","typescript","game","ai"],"author":{"name":"Ayush Raj"},"license":"MIT","_id":"@ayshrj/checkers.js@1.0.0","maintainers":[{"name":"ayshrj","email":"ayshrj10@gmail.com"}],"homepage":"https://github.com/ayshrj/checkers.js#readme","bugs":{"url":"https://github.com/ayshrj/checkers.js/issues"},"dist":{"shasum":"e18133437b2636e1569829840903d5bbf699b30e","tarball":"https://registry.npmjs.org/@ayshrj/checkers.js/-/checkers.js-1.0.0.tgz","fileCount":14,"integrity":"sha512-amxXjUvOv0iqGog3Mh+E1n2fkHjeu7gphU1MS9BfyUl/f+ZELmyPUPnJ8KHdoRr491Ue0epWt82CajtsMSOoJg==","signatures":[{"sig":"MEYCIQDJ//MmibpUAZu5yS/KXnJTtirM4vNSqp23ZFQ0X3Ii8QIhAOmQ227XwkvgXPcxGn0fAaigMZ3d31VGjdYHK6TuC/eX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51419},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"dd69a3e478eeccfadf19cbb4dfaabc97216ab8fa","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"tsc","prepare":"npm run build","prepublishOnly":"npm run build"},"_npmUser":{"name":"ayshrj","email":"ayshrj10@gmail.com"},"repository":{"url":"git+https://github.com/ayshrj/checkers.js.git","type":"git"},"_npmVersion":"10.5.1","description":"A TypeScript-based headless Checker game engine for simulating game logic, AI moves, and game state management.","directories":{},"_nodeVersion":"23.6.1","dependencies":{"events":"^3.3.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/events":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/checkers.js_1.0.0_1740832740647_0.4270391658047661","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@ayshrj/checkers.js","version":"1.0.1","keywords":["ludo","board game","typescript","game","ai"],"author":{"name":"Ayush Raj"},"license":"MIT","_id":"@ayshrj/checkers.js@1.0.1","maintainers":[{"name":"ayshrj","email":"ayshrj10@gmail.com"}],"homepage":"https://github.com/ayshrj/checkers.js#readme","bugs":{"url":"https://github.com/ayshrj/checkers.js/issues"},"dist":{"shasum":"6474b6595258eba88437f743a55d9ae9085c4b3e","tarball":"https://registry.npmjs.org/@ayshrj/checkers.js/-/checkers.js-1.0.1.tgz","fileCount":14,"integrity":"sha512-EVeSGBsOli6agSfCUFWs8a9YoL4XjNNA7KIH5PbF1cO7hpVXw+IFUhF0hnY4YEIV2DN2yjU7pc4DcjJn+2d78A==","signatures":[{"sig":"MEQCIHf+/q3mXsH8bln4uqEY0dJpavNkBWR8AGuW2HRRZku1AiBmzYMq1MhiEN9tpo1eNnNb/LGNFXhb91AlIbsC8Vt2PA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64192},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"c9c6341df7be32d6f5afddb336604a9bb65a5621","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"tsc","prepare":"npm run build","prepublishOnly":"npm run build"},"_npmUser":{"name":"ayshrj","email":"ayshrj10@gmail.com"},"repository":{"url":"git+https://github.com/ayshrj/checkers.js.git","type":"git"},"_npmVersion":"10.5.1","description":"A TypeScript-based headless Checker game engine for simulating game logic, AI moves, and game state management.","directories":{},"_nodeVersion":"23.6.1","dependencies":{"events":"^3.3.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/events":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/checkers.js_1.0.1_1740833610448_0.8845607972597358","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@ayshrj/checkers.js","version":"1.0.2","keywords":["checkers","board game","typescript","game","ai"],"author":{"name":"Ayush Raj"},"license":"MIT","_id":"@ayshrj/checkers.js@1.0.2","maintainers":[{"name":"ayshrj","email":"ayshrj10@gmail.com"}],"homepage":"https://github.com/ayshrj/checkers.js#readme","bugs":{"url":"https://github.com/ayshrj/checkers.js/issues"},"dist":{"shasum":"6ad85df1781a7efa323ec8b2988bd265d2b21228","tarball":"https://registry.npmjs.org/@ayshrj/checkers.js/-/checkers.js-1.0.2.tgz","fileCount":14,"integrity":"sha512-fKuhTSs33YdlTmcKSD5Kax0b21fel0Q4wAgP4CITctN9MDLNBIxhQjM0ZSiDy9OitdEle/iE4afD8+kWqeusmQ==","signatures":[{"sig":"MEYCIQDroLrGYP1bZFjrWLnVi0ms1m76Rpzmu3TBODLSBYpuFgIhAKZwyrNqTDs/quN1TR9r51XyehPDtm6uSoRIeW99bYZu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64196},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"689bf9ada27c26b3d31d81e1e5691a93871253da","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"tsc","prepare":"npm run build","prepublishOnly":"npm run build"},"_npmUser":{"name":"ayshrj","email":"ayshrj10@gmail.com"},"repository":{"url":"git+https://github.com/ayshrj/checkers.js.git","type":"git"},"_npmVersion":"10.5.1","description":"A TypeScript-based headless Checker game engine for simulating game logic, AI moves, and game state management.","directories":{},"_nodeVersion":"23.6.1","dependencies":{"events":"^3.3.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/events":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/checkers.js_1.0.2_1740897672016_0.972645306543285","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@ayshrj/checkers.js","version":"1.0.3","description":"A TypeScript-based headless Checker game engine for simulating game logic, AI moves, and game state management.","main":"dist/index.js","types":"dist/index.d.ts","repository":{"type":"git","url":"git+https://github.com/ayshrj/checkers.js.git"},"homepage":"https://github.com/ayshrj/checkers.js#readme","scripts":{"build":"tsup","prepare":"npm run build","test":"echo \"Error: no test specified\" && exit 1","prepublishOnly":"npm run build"},"keywords":["checkers","board game","typescript","game","ai"],"author":{"name":"Ayush Raj"},"license":"MIT","devDependencies":{"@types/events":"^3.0.3","tsup":"^8.4.0","typescript":"^5.8.2"},"dependencies":{"events":"^3.3.0"},"_id":"@ayshrj/checkers.js@1.0.3","gitHead":"b2e43d41fe9a764a45ecaf4fc3e8c56ef73cdb61","bugs":{"url":"https://github.com/ayshrj/checkers.js/issues"},"_nodeVersion":"23.6.1","_npmVersion":"10.5.1","dist":{"integrity":"sha512-y0F/RshQDy7BfQeuAGorXbZ27rkhic2yuhxBroDApO7StkcWHNw418q0weEc4ZjlGhj4w9MdoRySwzEoxFcX/g==","shasum":"01a58594e8e2ec8840ee3b940d7f0b94d17b2225","tarball":"https://registry.npmjs.org/@ayshrj/checkers.js/-/checkers.js-1.0.3.tgz","fileCount":11,"unpackedSize":64157,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCBC41plc/kAoL1DNhEeuN4fz+gURRXd3zQ4nL8oGgc6gIhAN6a4JqMCIAqJgfBKVtVGdkR+EicznJ7aG3p0pdza8mZ"}]},"_npmUser":{"name":"ayshrj","email":"ayshrj10@gmail.com"},"directories":{},"maintainers":[{"name":"ayshrj","email":"ayshrj10@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/checkers.js_1.0.3_1740898137266_0.8781837269884678"},"_hasShrinkwrap":false}},"time":{"created":"2025-03-01T12:39:00.578Z","modified":"2025-03-02T06:48:57.725Z","1.0.0":"2025-03-01T12:39:00.890Z","1.0.1":"2025-03-01T12:53:30.704Z","1.0.2":"2025-03-02T06:41:12.193Z","1.0.3":"2025-03-02T06:48:57.551Z"},"bugs":{"url":"https://github.com/ayshrj/checkers.js/issues"},"author":{"name":"Ayush Raj"},"license":"MIT","homepage":"https://github.com/ayshrj/checkers.js#readme","keywords":["checkers","board game","typescript","game","ai"],"repository":{"type":"git","url":"git+https://github.com/ayshrj/checkers.js.git"},"description":"A TypeScript-based headless Checker game engine for simulating game logic, AI moves, and game state management.","maintainers":[{"name":"ayshrj","email":"ayshrj10@gmail.com"}],"readme":"# @ayshrj/checkers.js\r\n\r\n[![npm](https://img.shields.io/npm/v/@ayshrj/checkers.js?color=blue)](https://www.npmjs.com/package/@ayshrj/checkers.js)\r\n[![npm](https://img.shields.io/npm/dm/@ayshrj/checkers.js)](https://www.npmjs.com/package/@ayshrj/checkers.js)\r\n\r\n**@ayshrj/checkers.js** is a TypeScript library for playing Checkers (Draughts) with AI and real-time state management. It provides:\r\n\r\n- **Full Rules Enforcement**: Ensures valid moves, mandatory captures, and king promotions.\r\n- **AI Support**: Minimax-based AI for strategic move recommendations.\r\n- **Event-Driven Updates**: Uses an event system to notify state changes.\r\n- **Typed Data Structures**: Full TypeScript support for safe and reliable development.\r\n\r\n---\r\n\r\n## Table of Contents\r\n\r\n- [@ayshrj/checkers.js](#ayshrjcheckersjs)\r\n  - [Table of Contents](#table-of-contents)\r\n  - [Installation](#installation)\r\n  - [Importing](#importing)\r\n    - [Import (as ESM)](#import-as-esm)\r\n    - [Import (as CommonJS)](#import-as-commonjs)\r\n  - [Quick Start Example](#quick-start-example)\r\n  - [Features](#features)\r\n  - [API](#api)\r\n    - [`Checkers` Class](#checkers-class)\r\n      - [Methods](#methods)\r\n      - [Event Handling](#event-handling)\r\n      - [Type Definitions](#type-definitions)\r\n  - [Example: React Integration](#example-react-integration)\r\n  - [License](#license)\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @ayshrj/checkers.js\r\n```\r\nor\r\n```bash\r\nyarn add @ayshrj/checkers.js\r\n```\r\n\r\n---\r\n\r\n## Importing\r\n\r\n### Import (as ESM)\r\n\r\n```ts\r\nimport { Checkers } from '@ayshrj/checkers.js';\r\n```\r\n\r\n### Import (as CommonJS)\r\n\r\n```ts\r\nconst { Checkers } = require('@ayshrj/checkers.js');\r\n```\r\n\r\n---\r\n\r\n## Quick Start Example\r\n\r\n```ts\r\nimport { Checkers } from '@ayshrj/checkers.js';\r\n\r\n// Initialize a new game\r\nconst game = new Checkers();\r\n\r\ngame.on('stateChange', (state) => {\r\n  console.log('New State:', state.boardStatus);\r\n});\r\n\r\n// Make first valid move\r\nconst moves = game.getCurrentState().allowedMoves;\r\nif (moves.length > 0) {\r\n  game.move(moves[0]);\r\n}\r\n\r\n// Get AI move suggestion and apply it\r\nconst best = game.bestMove(3);\r\nif (best) game.move(best);\r\n```\r\n\r\n---\r\n\r\n## Features\r\n\r\n1. **Rules Enforcement**  \r\n   - Ensures valid piece movement.\r\n   - Implements forced captures where required.\r\n   - Handles king promotions.\r\n\r\n2. **AI Move Suggestions**  \r\n   - Uses Minimax algorithm to provide best moves.\r\n   - Adjustable depth for AI difficulty.\r\n\r\n3. **Event-Driven Updates**  \r\n   - Emits `stateChange` event after every move.\r\n   - Helps in real-time UI updates.\r\n\r\n4. **Typed Data Structures**  \r\n   - TypeScript definitions for all game elements.\r\n\r\n---\r\n\r\n## API\r\n\r\n### `Checkers` Class\r\n\r\n#### Methods\r\n\r\n- **`reset()`**: Resets the game state to the initial configuration.\r\n- **`move(move: CheckersMove)`**: Executes a validated move.\r\n- **`bestMove(depth: number)`**: Returns the best AI move using Minimax.\r\n- **`getCurrentState()`**: Returns the current game state, including allowed moves and board setup.\r\n\r\n#### Event Handling\r\n\r\n- **`stateChange`**: Triggered after every valid move with the updated game state.\r\n  ```ts\r\n  game.on('stateChange', (state) => {\r\n    console.log(state);\r\n  });\r\n  ```\r\n\r\n#### Type Definitions\r\n\r\n- **`CheckersGameState`**: Represents the full game state, including the board, turn, and available moves.\r\n- **`CheckersMove`**: Defines a validated move with piece positions.\r\n- **`Piece`/`Position`**: Represents board components.\r\n\r\n---\r\n\r\n## Example: React Integration\r\n\r\n```tsx\r\n\"use client\";\r\n\r\nimport React, { useEffect, useState } from \"react\";\r\nimport { Checkers, CheckersMove, Piece } from \"@ayshrj/checkers.js\";\r\n\r\ninterface Position {\r\n  row: number;\r\n  col: number;\r\n}\r\n\r\nconst CheckerPage = () => {\r\n  const [checkers, setCheckers] = useState(new Checkers());\r\n  const [board, setBoard] = useState<(Piece | null)[][]>(\r\n    checkers.getCurrentState().board\r\n  );\r\n  const [difficulty, setDifficulty] = useState<2 | 4 | 6>(4);\r\n  const [selectedPos, setSelectedPos] = useState<Position | null>(null);\r\n  const [validMoves, setValidMoves] = useState<CheckersMove[]>([]);\r\n  const [gameStatus, setGameStatus] = useState<string>(\"Red to move\");\r\n  const [botThinking, setBotThinking] = useState(false);\r\n  const [gameMode, setGameMode] = useState<\"bot\" | \"human\" | null>(null);\r\n  const [isModalOpen, setIsModalOpen] = useState(false);\r\n\r\n  const updateBoard = () => {\r\n    setBoard(checkers.getCurrentState().board.map((row) => [...row]));\r\n    updateGameStatus();\r\n  };\r\n\r\n  const updateGameStatus = () => {\r\n    const allowedMoves = checkers.getCurrentState().allowedMoves;\r\n    if (allowedMoves.length === 0) {\r\n      const winner =\r\n        checkers.getCurrentState().turn === \"red\"\r\n          ? gameMode === \"bot\"\r\n            ? \"Green\"\r\n            : \"Black\"\r\n          : \"Red\";\r\n      setGameStatus(`Game over! ${winner} wins!`);\r\n    } else {\r\n      setGameStatus(\r\n        `${\r\n          checkers.getCurrentState().turn.charAt(0).toUpperCase() +\r\n          checkers.getCurrentState().turn.slice(1)\r\n        } to move`\r\n      );\r\n    }\r\n  };\r\n\r\n  const handleSquareClick = (row: number, col: number) => {\r\n    if (\r\n      botThinking ||\r\n      (gameMode === \"bot\" && checkers.getCurrentState().turn === \"black\")\r\n    )\r\n      return;\r\n\r\n    const piece = board[row][col];\r\n    if (!selectedPos) {\r\n      if (piece && piece.color === checkers.getCurrentState().turn) {\r\n        setSelectedPos({ row, col });\r\n        const allowedMoves = checkers.getCurrentState().allowedMoves;\r\n        const pieceMoves = allowedMoves.filter(\r\n          (move) => move.from.row === row && move.from.col === col\r\n        );\r\n        setValidMoves(pieceMoves);\r\n      }\r\n    } else {\r\n      const move = validMoves.find((m) => {\r\n        const final = m.path[m.path.length - 1];\r\n        return final.row === row && final.col === col;\r\n      });\r\n      if (move) {\r\n        const moveSuccess = checkers.move(move);\r\n        if (moveSuccess) {\r\n          updateBoard();\r\n          setSelectedPos(null);\r\n          setValidMoves([]);\r\n        }\r\n      } else {\r\n        if (piece && piece.color === checkers.getCurrentState().turn) {\r\n          setSelectedPos({ row, col });\r\n          const allowedMoves = checkers.getCurrentState().allowedMoves;\r\n          const pieceMoves = allowedMoves.filter(\r\n            (move) => move.from.row === row && move.from.col === col\r\n          );\r\n          setValidMoves(pieceMoves);\r\n        } else {\r\n          setSelectedPos(null);\r\n          setValidMoves([]);\r\n        }\r\n      }\r\n    }\r\n  };\r\n\r\n  useEffect(() => {\r\n    if (gameMode === \"bot\" && checkers.getCurrentState().turn === \"black\") {\r\n      setBotThinking(true);\r\n      setTimeout(() => {\r\n        const best = checkers.bestMove(difficulty);\r\n        if (best) {\r\n          checkers.move(best);\r\n          updateBoard();\r\n        }\r\n        setBotThinking(false);\r\n      }, 500);\r\n    }\r\n  }, [board, gameMode, difficulty]);\r\n\r\n  const startNewMatch = (mode: \"bot\" | \"human\") => {\r\n    const newCheckers = new Checkers();\r\n    setCheckers(newCheckers);\r\n    setBoard(newCheckers.getCurrentState().board.map((row) => [...row]));\r\n    setSelectedPos(null);\r\n    setValidMoves([]);\r\n    setGameStatus(\r\n      `${\r\n        newCheckers.getCurrentState().turn.charAt(0).toUpperCase() +\r\n        newCheckers.getCurrentState().turn.slice(1)\r\n      } to move`\r\n    );\r\n    setGameMode(mode);\r\n    setIsModalOpen(false);\r\n  };\r\n\r\n  const modalStyle: React.CSSProperties = {\r\n    position: \"fixed\",\r\n    top: \"50%\",\r\n    left: \"50%\",\r\n    transform: \"translate(-50%, -50%)\",\r\n    backgroundColor: \"white\",\r\n    padding: \"20px\",\r\n    borderRadius: \"8px\",\r\n    boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\r\n    zIndex: 1000,\r\n  };\r\n\r\n  const buttonStyle: React.CSSProperties = {\r\n    padding: \"10px 20px\",\r\n    borderRadius: \"4px\",\r\n    border: \"none\",\r\n    cursor: \"pointer\",\r\n    fontSize: \"16px\",\r\n  };\r\n\r\n  return (\r\n    <div\r\n      style={{\r\n        display: \"flex\",\r\n        flexDirection: \"column\",\r\n        alignItems: \"center\",\r\n        padding: \"16px\",\r\n        height: \"100vh\",\r\n      }}\r\n    >\r\n      {/* Game Status */}\r\n      <div\r\n        style={{\r\n          width: \"100%\",\r\n          display: \"flex\",\r\n          flexDirection: \"column\",\r\n          gap: \"8px\",\r\n        }}\r\n      >\r\n        <div style={{ width: \"100%\", textAlign: \"center\" }}>\r\n          <div style={{ fontSize: \"18px\", fontWeight: \"500\" }}>\r\n            {gameMode === \"bot\"\r\n              ? gameStatus.replace(\"Black\", \"Green\").replace(\"black\", \"green\")\r\n              : gameStatus}\r\n            {botThinking && (\r\n              <span style={{ color: \"#0000FF\", marginLeft: \"8px\" }}>\r\n                Bot is thinking...\r\n              </span>\r\n            )}\r\n          </div>\r\n        </div>\r\n        {/* Board */}\r\n        <div\r\n          style={{\r\n            width: \"100%\",\r\n            aspectRatio: \"1/1\",\r\n            backgroundColor: \"#f0f0f0\",\r\n            borderRadius: \"8px\",\r\n            position: \"relative\",\r\n          }}\r\n        >\r\n          {/* Files (columns) */}\r\n          <div\r\n            style={{\r\n              position: \"absolute\",\r\n              top: \"0\",\r\n              left: \"0\",\r\n              width: \"100%\",\r\n              display: \"flex\",\r\n              justifyContent: \"space-around\",\r\n              padding: \"0 16px\",\r\n            }}\r\n          >\r\n            {[\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"].map((file) => (\r\n              <div key={file} style={{ fontSize: \"12px\", opacity: \"0.7\" }}>\r\n                {file}\r\n              </div>\r\n            ))}\r\n          </div>\r\n          {/* Ranks (rows) */}\r\n          <div\r\n            style={{\r\n              position: \"absolute\",\r\n              top: \"0\",\r\n              left: \"0\",\r\n              height: \"100%\",\r\n              display: \"flex\",\r\n              flexDirection: \"column\",\r\n              justifyContent: \"space-around\",\r\n              alignItems: \"center\",\r\n              padding: \"16px 0\",\r\n            }}\r\n          >\r\n            {[8, 7, 6, 5, 4, 3, 2, 1].map((rank) => (\r\n              <div key={rank} style={{ fontSize: \"12px\", opacity: \"0.7\" }}>\r\n                {rank}\r\n              </div>\r\n            ))}\r\n          </div>\r\n          {/* Render the board grid */}\r\n          <div\r\n            style={{\r\n              width: \"100%\",\r\n              height: \"100%\",\r\n              display: \"grid\",\r\n              padding: \"16px\",\r\n              gridTemplateColumns: \"repeat(8, 1fr)\",\r\n              gridTemplateRows: \"repeat(8, 1fr)\",\r\n            }}\r\n          >\r\n            {board.map((row, rowIndex) =>\r\n              row.map((col, colIndex) => {\r\n                const isDarkSquare = (rowIndex + colIndex) % 2 === 1;\r\n                const isSelected =\r\n                  selectedPos &&\r\n                  selectedPos.row === rowIndex &&\r\n                  selectedPos.col === colIndex;\r\n                const isValidMove = validMoves.some((move) => {\r\n                  const final = move.path[move.path.length - 1];\r\n                  return final.row === rowIndex && final.col === colIndex;\r\n                });\r\n                return (\r\n                  <div\r\n                    key={`${rowIndex}-${colIndex}`}\r\n                    style={{\r\n                      width: \"100%\",\r\n                      height: \"100%\",\r\n                      borderBottom: \"1px solid #ccc\",\r\n                      borderRight: \"1px solid #ccc\",\r\n                      backgroundColor: isDarkSquare ? \"#e0e0e0\" : \"#f8f8f8\",\r\n                      border: isSelected ? \"4px solid #0000FF\" : \"none\",\r\n                      position: \"relative\",\r\n                      ...(isValidMove ? { backgroundColor: \"#00FF0030\" } : {}),\r\n                    }}\r\n                    onClick={() => handleSquareClick(rowIndex, colIndex)}\r\n                  >\r\n                    <div\r\n                      style={{\r\n                        position: \"absolute\",\r\n                        inset: \"0\",\r\n                        display: \"flex\",\r\n                        alignItems: \"center\",\r\n                        justifyContent: \"center\",\r\n                      }}\r\n                    >\r\n                      {col && (\r\n                        <div\r\n                          style={{\r\n                            borderRadius: \"50%\",\r\n                            height: \"60%\",\r\n                            width: \"60%\",\r\n                            backgroundColor:\r\n                              col.color === \"black\" ? \"#00FF00\" : \"#FF0000\",\r\n                            position: \"absolute\",\r\n                          }}\r\n                        >\r\n                          {col.type === \"king\" && (\r\n                            <div\r\n                              style={{\r\n                                position: \"absolute\",\r\n                                left: \"50%\",\r\n                                top: \"50%\",\r\n                                transform: \"translate(-50%, -50%)\",\r\n                                height: \"50%\",\r\n                                width: \"50%\",\r\n                                backgroundColor: \"white\",\r\n                              }}\r\n                            />\r\n                          )}\r\n                        </div>\r\n                      )}\r\n                    </div>\r\n                  </div>\r\n                );\r\n              })\r\n            )}\r\n          </div>\r\n        </div>\r\n      </div>\r\n      {/* Controls */}\r\n      <div\r\n        style={{\r\n          display: \"flex\",\r\n          flexDirection: \"column\",\r\n          gap: \"8px\",\r\n          width: \"100%\",\r\n        }}\r\n      >\r\n        {gameMode === \"bot\" && (\r\n          <div\r\n            style={{\r\n              display: \"flex\",\r\n              width: \"100%\",\r\n              gap: \"8px\",\r\n              alignItems: \"center\",\r\n              justifyContent: \"space-between\",\r\n            }}\r\n          >\r\n            {[\r\n              { value: 2, label: \"Easy\" },\r\n              { value: 4, label: \"Medium\" },\r\n              { value: 6, label: \"Hard\" },\r\n            ].map(({ value, label }) => (\r\n              <button\r\n                key={value}\r\n                style={{\r\n                  ...buttonStyle,\r\n                  width: \"33%\",\r\n                  backgroundColor: value === difficulty ? \"#00FF00\" : \"#ccc\",\r\n                  color: value === difficulty ? \"white\" : \"black\",\r\n                }}\r\n                onClick={() => setDifficulty(value as 2 | 4 | 6)}\r\n              >\r\n                {label}\r\n              </button>\r\n            ))}\r\n          </div>\r\n        )}\r\n        <button\r\n          style={{\r\n            ...buttonStyle,\r\n            backgroundColor: \"#0000FF\",\r\n            color: \"white\",\r\n            width: \"100%\",\r\n          }}\r\n          onClick={() => setIsModalOpen(true)}\r\n        >\r\n          Reset\r\n        </button>\r\n      </div>\r\n\r\n      {/* Initial Game Mode Selection Modal */}\r\n      {gameMode === null && (\r\n        <div style={modalStyle}>\r\n          <h2 style={{ marginBottom: \"16px\" }}>Select Game Mode</h2>\r\n          <div\r\n            style={{\r\n              display: \"flex\",\r\n              justifyContent: \"space-around\",\r\n              gap: \"16px\",\r\n            }}\r\n          >\r\n            <button\r\n              style={{\r\n                ...buttonStyle,\r\n                width: \"50%\",\r\n                backgroundColor: \"#00FF00\",\r\n                color: \"white\",\r\n              }}\r\n              onClick={() => startNewMatch(\"bot\")}\r\n            >\r\n              Vs Bot\r\n            </button>\r\n            <button\r\n              style={{\r\n                ...buttonStyle,\r\n                width: \"50%\",\r\n                backgroundColor: \"#00FF00\",\r\n                color: \"white\",\r\n              }}\r\n              onClick={() => startNewMatch(\"human\")}\r\n            >\r\n              Vs Human\r\n            </button>\r\n          </div>\r\n        </div>\r\n      )}\r\n\r\n      {/* Reset Game Mode Modal */}\r\n      {isModalOpen && (\r\n        <div style={modalStyle}>\r\n          <h2 style={{ marginBottom: \"16px\" }}>Reset Game</h2>\r\n          <div\r\n            style={{\r\n              display: \"flex\",\r\n              justifyContent: \"space-around\",\r\n              gap: \"16px\",\r\n            }}\r\n          >\r\n            <button\r\n              style={{\r\n                ...buttonStyle,\r\n                width: \"50%\",\r\n                backgroundColor: \"#00FF00\",\r\n                color: \"white\",\r\n              }}\r\n              onClick={() => startNewMatch(\"bot\")}\r\n            >\r\n              Vs Bot\r\n            </button>\r\n            <button\r\n              style={{\r\n                ...buttonStyle,\r\n                width: \"50%\",\r\n                backgroundColor: \"#00FF00\",\r\n                color: \"white\",\r\n              }}\r\n              onClick={() => startNewMatch(\"human\")}\r\n            >\r\n              Vs Human\r\n            </button>\r\n          </div>\r\n        </div>\r\n      )}\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default CheckerPage;\r\n```\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT - Free for commercial and personal use.","readmeFilename":"README.md"}