{"version":3,"sources":["components/board/Tile.Module.css","components/layout/Navbar.module.css","components/board/Piece.Module.css","pages/Index.Module.css","components/MessageBox.Module.css","components/layout/Footer.module.css","components/board/Board.Module.css","pages/HowToPlay.Module.css","pages/play/Play.Module.css","components/layout/Footer.jsx","components/layout/Navbar.jsx","withMediaQueries.js","pages/Index.jsx","pages/HowToPlay.jsx","components/MessageBox.jsx","pages/play/LocalMultiplayer.jsx","pages/play/OnlineMultiplayer.jsx","pages/play/Computer.jsx","pages/play/Play.jsx","components/board/Piece.jsx","components/board/Tile.jsx","components/board/Board.jsx","pages/Game.jsx","components/ScrollToTop.jsx","App.jsx","index.js"],"names":["module","exports","Footer","React","Component","render","_jsxs","className","styles","container","children","_jsx","left","right","href","target","rel","github","Navbar","constructor","props","super","onClick","this","setState","expanded","state","bar","Link","to","brand","logo","isDesktop","items","renderItems","isMobile","expandButton","e","stopPropagation","viewBox","width","height","y","Expand","open","opacity","close","itemsColumn","_Fragment","componentDidMount","document","addEventListener","componentWillUnmount","removeEventListener","withMediaQueries","setIsMobile","useState","window","matchMedia","matches","useEffect","onChange","media","Index","image","textContainer","title","subtitle","link","HowToPlay","style","color","MessageBox","messageBox","minWidth","message","load","Loader","loader","type","button","linkLabel","LocalMultiplayer","handleOnGameStarted","onGameStarted","redirect","gameCode","Redirect","_connection","on","code","invoke","gameType","off","OnlineMultiplayer","createGameSide","createGameCode","joinGameCode","joinGameCodeLocked","row","box","renderCreateGame","codeLabel","value","disabled","joiningGame","onJoinGameCodeChanged","maxLength","placeholder","codeInput","invalidGameCode","invalid","async","onSubmit","onSubmitCreateGame","inputGroup","parseInt","creatingGame","toUpperCase","length","preventDefault","side","Computer","engine","engineThinkingTime","Play","Switch","Route","exact","path","component","Mode","name","mode","src","alt","Piece","piece","transform","transformX","transformY","taken","zIndex","getClassNames","inside","king","classNames","black","white","selected","push","join","Tile","coords","playable","tile","pieceTransformX","pieceTransformY","pieceTaken","destinationDot","selectable","previous","forced","destination","forcedDestination","Board","selectedTile","board","renderRows","offsetMoveToAnimate","moveToAnimateJumped","rows","possibleSelectedTileMoves","validMoves","filter","move","areCoordinatesEqual","moveToAnimate","Math","abs","i","x","offsetX","tiles","readonly","some","nextMoveMustBeJump","turnMoves","moveCoords","flip","tileCoords","onTileClicked","reverse","componentDidUpdate","prevProps","every","onMoveTaken","a","b","Game","handleOnGameUpdated","game","onGameUpdated","handleOnPlayerLeft","onPlayerLeft","playerNumber","playerLeft","match","params","ableToTakeMove","nextPlayer","origin","onBoardMoveTaken","renderMessageBox","winner","winMessage","response","handlePlayerLeft","at","setTimeout","withRouter","ScrollToTop","useLocation","scrollTo","App","status","Router","renderContent","error","fetchAntiforgeryToken","connectHub","_window$_connection","stop","fetch","_config","backend","_antiForgeryToken","json","ex","connection","HubConnectionBuilder","withUrl","headers","withAutomaticReconnect","build","onreconnecting","onHubReconnecting","onreconnected","onHubReconnected","start","HubConnectionState","Connected","toString","ReactDOM","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.a57fd2a9.chunk.js","sourcesContent":["// extracted by mini-css-extract-plugin\nmodule.exports = {\"tile\":\"bC7sXGq1UIjdMpjjuHUBfA==\",\"white\":\"wAJ65o4zu5Wz9rVuiCEl9w==\",\"black\":\"XL55B-5GCr6KuW+rroPaug==\",\"selected\":\"xFWJp8t5krv1fn5b1jgllA==\",\"previous\":\"i5Tagrbd8Ayos5wt+QKn8w==\",\"selectable\":\"OaRTikLuWb2wwq7zRNQrBw==\",\"destination\":\"D1TjRc0ARn6wIEi9hlyMCA==\",\"destinationDot\":\"QQ5z2PkOh0D8KYrXJ9HkMw==\",\"forced\":\"PXBItuJ-OuKKITx9uT4neQ==\",\"forcedDestination\":\"B7NVyCviW7Ys5MX3RekejA==\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Navbar_container__lwcz4\",\"bar\":\"Navbar_bar__24ZfR\",\"left\":\"Navbar_left__1JRCz\",\"right\":\"Navbar_right__1JOzI\",\"brand\":\"Navbar_brand__19UqD\",\"logo\":\"Navbar_logo__3ej6N\",\"items\":\"Navbar_items__3GAoq\",\"itemsColumn\":\"Navbar_itemsColumn__pVu5A\",\"expandButton\":\"Navbar_expandButton__3zPMT\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"J6w2pGRv9ZjHqjDHJ35pdg==\",\"piece\":\"_2oMuEZKPNC8H1afP-dMQ0g==\",\"selected\":\"fBvE0mYKWUtUJ8DsFZun9A==\",\"black\":\"klIzwYA+Zwe2+h20Lm8oNg==\",\"white\":\"OAnmy6ll83czW9Oy7ssokA==\",\"inside\":\"lg2IWXMuPSnIU98-hn+5dg==\",\"king\":\"neYionozkKe5te9-nF6SGw==\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"PVrsX6pu5XLEd1XOFSJ9OQ==\",\"image\":\"SG7jUoTDfiPnTMrBJmkRWw==\",\"textContainer\":\"lZ4vCgtgH5FsnjOKbyOvfw==\",\"title\":\"_9oue0-l51Ms4D9j-vrR7uQ==\",\"subtitle\":\"_1Z12nFloVEluzqpjcdmLsw==\",\"link\":\"ZGw5bJ0MTBEp-TaUrPtXgQ==\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"vuCb8NO8qP0f49mMyPg-TA==\",\"messageBox\":\"ZBn0T-wJw56GZtsEM-RV9g==\",\"title\":\"i8YZXOnsLnWPXfTSt0lR-A==\",\"message\":\"xliP-VMLe-CSRQ5L-b1jyw==\",\"loader\":\"pxx+6sfe5WdrpI1uulRGWg==\",\"button\":\"WOno9uljuLlphgLshhhliQ==\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Footer_container__33ya0\",\"left\":\"Footer_left__1HQjT\",\"right\":\"Footer_right__PCLUT\",\"github\":\"Footer_github__1Vpez\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"_4-7hKgk9ZhoNxOBWn1VxzQ==\",\"board\":\"tVqnNZXoXc8opZhwNzUl-Q==\",\"row\":\"_4RomomMgKUFqTDspJw-gfQ==\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"MHIGQb549xElbmNkMO-qDg==\",\"link\":\"kq0scd4FDFnh2tz7iRLiNw==\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"_5lWssC1Y40iTzKiI8TKGWw==\",\"row\":\"ecbfE4Uc0ul8rMH3xevgiA==\",\"modes\":\"mQ+9sQ2PxNPjbE0WgvCclg==\",\"mode\":\"-ocjbya9OwDidolI7yFcIA==\",\"box\":\"_4KIQ0-0cLVN1iZlI2dTy-A==\",\"title\":\"_5WdZizOEXte8izbJnT+S7Q==\",\"inputGroup\":\"_8R9eKSG6EFoVk9GKjiwrFw==\",\"codeLabel\":\"DtYls0Ij7NdOZMEEKS-OmQ==\",\"invalid\":\"zJOafD5gZ9mT6tgXmQjKcg==\",\"codeInput\":\"_89G454slfnF-b8QtZqaaIg==\",\"loader\":\"MLPdpgceI9Nr5O7T9tV5sA==\",\"button\":\"_7UvpKRyKLJfcYS47NWI-dg==\"};","import React from \"react\";\n\nimport styles from \"./Footer.module.css\";\n\nexport default class Footer extends React.Component {\n\trender() {\n\t\treturn (\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\tยฉ Daniel Baynton 2021\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n}\n","import React from \"react\";\nimport { Link } from \"react-router-dom\";\nimport Expand from 'react-expand-animated';\n\nimport { withMediaQueries } from \"../../withMediaQueries\";\n\nimport styles from \"./Navbar.module.css\";\n\nclass Navbar extends React.Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\texpanded: false\n\t\t};\n\t}\n\n\trender() {\n\t\treturn (\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\tDraughts\n\t\t\t\t\t\t\n\t\t\t\t\t\t{/* If we're on a desktop screen always render the navbar items */}\n\t\t\t\t\t\t{this.props.isDesktop &&\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{this.renderItems()}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{/* If we're on a mobile screen render a hamburger button instead, when it's clicked toggle navbar expansion */}\n\t\t\t\t\t\t{this.props.isMobile &&\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t{/* If we're on a mobile screen render an Expand component which contains the navbar items as a column */}\n\t\t\t\t{this.props.isMobile &&\n\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{this.renderItems()}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t}\n\t\t\t
\n\t\t);\n\t}\n\n\trenderItems() {\n\t\treturn (\n\t\t\t<>\n\t\t\t\tHow to Play\n\t\t\t\tFind a Game\n\t\t\t\n\t\t);\n\t}\n\n\tcomponentDidMount() {\n\t\t// When the component mounts register the click event handler\n\t\tdocument.addEventListener(\"click\", this.onClick);\n\t}\n\n\tcomponentWillUnmount() {\n\t\t// To avoid a memory leak, unregister the click event handler just before the component unmounts\n\t\tdocument.removeEventListener(\"click\", this.onClick);\n\t}\n\n\tonClick = () => {\n\t\t// When the user clicks anywhere else on the page collapse the navbar\n\t\tthis.setState({ expanded: false });\n\t};\n}\n\n// We use the withMediaQueries function so that information about the device is passed to this component\n// It's necessary to decide whether to display the navbar in desktop or mobile mode\nexport default withMediaQueries(Navbar);\n","import { useEffect, useState } from \"react\";\n\n// Adds props isMobile and isDesktop to any component which requests the information.\n// This component unfortunately has to use react hooks which are a lot harder to understand than Class components.\n\nexport function withMediaQueries(Component) {\n\treturn function WithMediaQueriesComponent(props) {\n\n\t\tvar [isMobile, setIsMobile] = useState(window.matchMedia(\"(max-width: 700px)\").matches);\n\n\t\tuseEffect(() => {\n\n\t\t\tconst onChange = (e) => setIsMobile(e.matches);\n\t\t\tconst media = window.matchMedia(\"(max-width: 700px)\");\n\t\t\tmedia.addEventListener(\"change\", onChange);\n\n\t\t\treturn () => {\n\t\t\t\tmedia.removeEventListener(\"change\", onChange);\n\t\t\t};\n\n\t\t});\n\n\t\treturn ;\n\t};\n}\n","import React from \"react\";\nimport { Link } from \"react-router-dom\";\n\nimport styles from \"./Index.Module.css\";\n\nexport default class Index extends React.Component {\n\trender() {\n\t\treturn (\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

Draughts

\n\t\t\t\t\t

Because Chess would be too hard

\n\t\t\t\t\tFind a game โž”\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n}\n","import React from \"react\";\nimport { Link } from \"react-router-dom\";\n\nimport styles from \"./HowToPlay.Module.css\";\n\nexport default class HowToPlay extends React.Component {\n\trender() {\n\t\treturn (\n\t\t\t
\n\t\t\t\t

\n\t\t\t\t\tHow to Play Draughts\n\t\t\t\t

\n\n\t\t\t\t

Structure of the Game

\n\t\t\t\t

\n\t\t\t\t\tAt the start of the game both players have 3 rows of pieces.
\n\t\t\t\t\tThe objective of the game is to eliminate the opponents pieces, but the game is also won if your opponent doesn't have any vailid moves.\n\t\t\t\t

\n\n\t\t\t\t

Moving the Pieces

\n\t\t\t\t

\n\t\t\t\t\tNormal pieces can move one square diagonally forwards.
\n\t\t\t\t\tOn your turn, select the piece that you would like to move.
\n\t\t\t\t\tThe tiles it's able to move to will be highlighted with a green marker. Select one of these tiles to submit your move.\n\t\t\t\t

\n\n\t\t\t\t

Eliminating Opponent Pieces

\n\t\t\t\t

\n\t\t\t\t\tIf one of your pieces is highlighted in purple, it means that it has a jumping move where it can jump over an opponent piece to eliminate it.
\n\t\t\t\t\tIf a jumping move is possible, you must take it.
\n\t\t\t\t\tAfter you jump an opponent piece you can jump another opponent piece to form a jump chain, but all jumps must be performed by the same piece.\n\t\t\t\t

\n\n\t\t\t\t

Promoting to Kings

\n\t\t\t\t

\n\t\t\t\t\tIf a piece travels all the way to the other side of the board, it is promoted to a king.
\n\t\t\t\t\tA king can move backwards as well as forwards, and this also applies to jumping moves.
\n\t\t\t\t

\n\n\t\t\t\tFind a game โž”\n\t\t\t
\n\t\t);\n\t}\n}\n","import React from \"react\";\n\nimport Loader from \"react-loader-spinner\";\nimport { Link } from \"react-router-dom\";\n\nimport styles from \"./MessageBox.Module.css\";\n\nexport default class MessageBox extends React.Component {\n\trender() {\n\t\t// Render a message box using the props passed to the component\n\t\treturn (\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{this.props.title}\n\t\t\t\t\t{this.props.message}\n\t\t\t\t\t{this.props.load &&\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t\t{this.props.link &&\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n}\n","import React from \"react\";\nimport { Redirect } from \"react-router\";\n\nimport MessageBox from \"../../components/MessageBox\";\n\nexport default class LocalMultiplayer extends React.Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\tredirect: null\n\t\t};\n\t\tthis.gameCode = null;\n\t}\n\n\trender() {\n\t\tif (this.state.redirect) {\n\t\t\treturn (\n\t\t\t\t\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\t\t);\n\t}\n\n\tasync componentDidMount() {\n\t\twindow._connection.on(\"GAME_STARTED\", this.handleOnGameStarted);\n\n\t\tvar code = await window._connection.invoke(\"CREATE_GAME\", { gameType: 0 });\n\t\tthis.gameCode = code;\n\t\tawait window._connection.invoke(\"JOIN_GAME\", code);\n\t}\n\n\tcomponentWillUnmount() {\n\t\t// To avoid a memory leak, unregister the game updated event handler\n\t\twindow._connection.off(\"GAME_STARTED\", this.handleOnGameStarted);\n\t}\n\n\thandleOnGameStarted = () => this.onGameStarted();\n\n\tonGameStarted() {\n\t\tthis.setState({ redirect: `/game/${this.gameCode}` });\n\t}\n}\n","import React from \"react\";\nimport Loader from \"react-loader-spinner\";\nimport { Redirect } from \"react-router\";\n\nimport styles from \"./Play.Module.css\";\n\nexport default class OnlineMultiplayer extends React.Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\tredirect: null,\n\n\t\t\tcreateGameSide: -1,\n\t\t\tcreateGameCode: null,\n\n\t\t\tjoinGameCode: \"\",\n\t\t\tjoinGameCodeLocked: false\n\t\t};\n\t\tthis.gameCode = null;\n\t}\n\n\trender() {\n\t\tif (this.state.redirect) {\n\t\t\treturn (\n\t\t\t\t\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{this.renderCreateGame()}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\tJoin a game\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t this.onJoinGameCodeChanged(e)}\n\t\t\t\t\t\t\t\tmaxLength=\"6\"\n\t\t\t\t\t\t\t\tplaceholder=\"ABCDEF\"\n\t\t\t\t\t\t\t\tclassName={`${styles.codeInput} ${this.state.invalidGameCode ? styles.invalid : null}`}>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{this.state.invalidGameCode &&\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{this.state.joiningGame &&\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n\n\trenderCreateGame() {\n\t\tif (!this.state.createGameCode) {\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\tCreate a game\n\t\t\t\t\t
this.onSubmitCreateGame(e)}>\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t this.setState({ createGameSide: parseInt(e.target.value) })}>\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t{!this.state.creatingGame &&\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{this.state.creatingGame &&\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\tWaiting for opponent...\n\t\t\t\t\n\t\t\t\t{this.state.createGameCode}\n\t\t\t\t\n\t\t\t\n\t\t);\n\t}\n\n\tcomponentDidMount() {\n\t\twindow._connection.on(\"GAME_STARTED\", this.handleOnGameStarted);\n\t}\n\n\tcomponentWillUnmount() {\n\t\t// To avoid a memory leak, unregister the game updated event handler\n\t\twindow._connection.off(\"GAME_STARTED\", this.handleOnGameStarted);\n\t}\n\n\tasync onJoinGameCodeChanged(e) {\n\t\tvar code = e.target.value.toUpperCase();\n\n\t\t// If the code length is 6 the user has finished inputting it\n\t\tif (code.length === 6) {\n\n\t\t\t// Show a loading message\n\t\t\tthis.setState({ joinGameCode: code, joiningGame: true, invalidGameCode: false });\n\n\t\t\t// If this code matches the \"Create Game\" code reject it to avoid error state\n\t\t\tif (code === this.state.createGameCode) {\n\t\t\t\tthis.setState({ invalidGameCode: true, joiningGame: false });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Send the request to join the game\n\t\t\tthis.gameCode = code;\n\t\t\tvar response = await window._connection.invoke(\"JOIN_GAME\", code);\n\n\t\t\t// If the request fails show an error message\n\t\t\tif (!response) {\n\t\t\t\tthis.setState({ invalidGameCode: true, joiningGame: false });\n\t\t\t}\n\n\t\t\t// If the request succeeded the server will eventually send GAME_STARTED so we're done for now\n\t\t} else {\n\t\t\tthis.setState({ joinGameCode: code, invalidGameCode: false });\n\t\t}\n\t}\n\n\tasync onSubmitCreateGame(e) {\n\t\te.preventDefault();\n\n\t\tthis.setState({ creatingGame: true });\n\t\tvar code = await window._connection.invoke(\"CREATE_GAME\", { gameType: 1, side: this.state.createGameSide });\n\t\tthis.gameCode = code;\n\t\tawait window._connection.invoke(\"JOIN_GAME\", code);\n\n\t\tthis.setState({ creatingGame: false, createGameCode: code });\n\t}\n\n\thandleOnGameStarted = () => this.onGameStarted();\n\n\tonGameStarted() {\n\t\tif (!this.gameCode) return;\n\t\tthis.setState({ redirect: `/game/${this.gameCode}` });\n\t}\n}\n","import React from \"react\";\nimport Loader from \"react-loader-spinner\";\nimport { Redirect } from \"react-router\";\n\nimport styles from \"./Play.Module.css\";\n\nexport default class Computer extends React.Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\tredirect: null,\n\n\t\t\tside: 0,\n\t\t\tengine: 0,\n\t\t\tengineThinkingTime: 2000\n\t\t};\n\t\tthis.gameCode = null;\n\t}\n\n\trender() {\n\t\tif (this.state.redirect) {\n\t\t\treturn (\n\t\t\t\t\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\tCreate Computer Game\n\t\t\t\t\t\t
this.onSubmitCreateGame(e)}>\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t this.setState({ side: parseInt(e.target.value) })}>\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t this.setState({ engine: parseInt(e.target.value) })}>\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{this.state.engine === 0 &&\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t this.setState({ engineThinkingTime: parseInt(e.target.value) })}>\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{!this.state.creatingGame &&\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{this.state.creatingGame &&\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n\n\tcomponentDidMount() {\n\t\twindow._connection.on(\"GAME_STARTED\", this.handleOnGameStarted);\n\t}\n\n\tcomponentWillUnmount() {\n\t\t// To avoid a memory leak, unregister the game updated event handler\n\t\twindow._connection.off(\"GAME_STARTED\", this.handleOnGameStarted);\n\t}\n\n\tasync onSubmitCreateGame(e) {\n\t\te.preventDefault();\n\n\t\tthis.setState({ creatingGame: true });\n\t\tvar code = await window._connection.invoke(\"CREATE_GAME\", { gameType: 2, side: this.state.side, engine: this.state.engine, engineThinkingTime: this.state.engineThinkingTime });\n\t\tthis.gameCode = code;\n\t\tawait window._connection.invoke(\"JOIN_GAME\", code);\n\t}\n\n\thandleOnGameStarted = () => this.onGameStarted();\n\n\tonGameStarted() {\n\t\tif (!this.gameCode) return;\n\t\tthis.setState({ redirect: `/game/${this.gameCode}` });\n\t}\n}\n","import React from \"react\";\nimport { Switch, Route } from \"react-router\";\nimport { Link } from \"react-router-dom\";\n\nimport LocalMultiplayer from \"./LocalMultiplayer\";\nimport OnlineMultiplayer from \"./OnlineMultiplayer\";\nimport Computer from \"./Computer\";\n\nimport styles from \"./Play.Module.css\";\n\nexport default class Play extends React.Component {\n\trender() {\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n}\n\nclass Mode extends React.Component {\n\trender() {\n\t\treturn (\n\t\t\t\n\t\t\t\t{this.props.name}\n\t\t\t\t
\n\t\t\t\t\t\"\"\n\t\t\t\t
\n\t\t\t\n\t\t);\n\t}\n}\n","import React from \"react\";\n\nimport styles from \"./Piece.Module.css\";\n\nexport default class Piece extends React.Component {\n\trender() {\n\t\t// If the piece passed is -1 (empty), we don't need to render anything\n\t\tif (this.props.piece === -1)\n\t\t\treturn null;\n\n\t\t// Render the piece, and if it's a king (value is 2 or 3) add a king div for the crown.\n\t\treturn (\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{this.props.piece >= 2 &&\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n\n\t// Returns a className based on this component's props\n\t// Eg. if \"selected=true\" is passed then the selected class is added\n\tgetClassNames() {\n\t\tvar classNames = [styles.piece, this.props.piece % 2 === 0 ? styles.black : styles.white];\n\t\tif (this.props.selected) classNames.push(styles.selected);\n\t\treturn classNames.join(\" \");\n\t}\n}\n","import React from \"react\";\nimport Piece from \"./Piece\";\n\nimport styles from \"./Tile.Module.css\";\n\nexport default class Tile extends React.Component {\n\trender() {\n\t\t// Render the tile with an onClick event which elevates to the parent component (Board)\n\t\t// Render a piece within the tile and pass relevant props down to it\n\t\treturn (\n\t\t\t
this.props.onClick(this.props.coords)}>\n\t\t\t\t{this.props.playable &&\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n\n\t// Returns a className based on this component's props\n\t// Eg. if \"selected=true\" is passed then the selected class is added\n\tgetClassNames() {\n\t\tif (this.props.playable) {\n\t\t\tvar classNames = [styles.tile, styles.white];\n\t\t\tif (this.props.selectable) classNames.push(styles.selectable);\n\t\t\tif (this.props.selected) classNames.push(styles.selected);\n\t\t\tif (this.props.previous) classNames.push(styles.previous);\n\t\t\tif (this.props.forced) classNames.push(styles.forced);\n\t\t\tif (this.props.destination) classNames.push(styles.destination);\n\t\t\tif (this.props.forcedDestination) classNames.push(styles.forcedDestination);\n\t\t\treturn classNames.join(\" \");\n\t\t} else {\n\t\t\treturn `${styles.tile} ${styles.black}`;\n\t\t}\n\t}\n}\n","import React from \"react\";\n\nimport Tile from \"./Tile\";\n\nimport styles from \"./Board.Module.css\";\n\nexport default class Board extends React.Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\tselectedTile: null\n\t\t};\n\t}\n\n\trender() {\n\t\treturn (\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{this.renderRows()}\n\t\t\t\t
\n\t\t\t
\n\t\t);\n\t}\n\n\trenderRows() {\n\t\tvar rows = [];\n\n\t\tvar possibleSelectedTileMoves = this.state.selectedTile && this.props.board.validMoves.filter(move => areCoordinatesEqual(move[0], this.state.selectedTile));\n\n\t\tvar offsetMoveToAnimate;\n\t\tvar moveToAnimateJumped;\n\n\t\t// If there is a move to animate calculate the movement that will need to be shown on the board\n\t\tif (this.props.moveToAnimate) {\n\t\t\toffsetMoveToAnimate = [\n\t\t\t\t[(2 * this.props.moveToAnimate[0][0]) + ((this.props.moveToAnimate[0][1] + 1) % 2), this.props.moveToAnimate[0][1]],\n\t\t\t\t[(2 * this.props.moveToAnimate[1][0]) + ((this.props.moveToAnimate[1][1] + 1) % 2), this.props.moveToAnimate[1][1]]\n\t\t\t];\n\n\t\t\t// If the move was a jump (diff in Y is 2) calculate the tile that was jumped, this piece will need to fade out on the board\n\t\t\tif (Math.abs(this.props.moveToAnimate[0][1] - this.props.moveToAnimate[1][1]) === 2) {\n\t\t\t\tvar jumpedX = offsetMoveToAnimate[0][0] > offsetMoveToAnimate[1][0]\n\t\t\t\t\t? offsetMoveToAnimate[0][0] - 1\n\t\t\t\t\t: offsetMoveToAnimate[0][0] + 1;\n\t\t\t\tvar jumpedY = offsetMoveToAnimate[0][1] > offsetMoveToAnimate[1][1]\n\t\t\t\t\t? offsetMoveToAnimate[0][1] - 1\n\t\t\t\t\t: offsetMoveToAnimate[0][1] + 1;\n\t\t\t\tmoveToAnimateJumped = [jumpedX, jumpedY];\n\t\t\t}\n\t\t}\n\n\t\tvar i = 0;\n\t\tfor (var y = 0; y < 8; y++) {\n\n\t\t\tvar row = [];\n\t\t\tfor (var x = 0; x < 8; x++) {\n\n\t\t\t\ti++;\n\n\t\t\t\t// Check if the tile is one of the playable tiles,\n\t\t\t\t// if it isn't then we can skip some expensive logic.\n\t\t\t\tvar playable = x % 2 !== y % 2;\n\t\t\t\tif (playable) {\n\n\t\t\t\t\t// Convert the actual X value into the condensed value the server uses\n\t\t\t\t\tvar offsetX = (x - 1 + y % 2) / 2;\n\n\t\t\t\t\tvar tile = this.props.board.tiles[y][offsetX];\n\t\t\t\t\tlet coords = [offsetX, y];\n\n\t\t\t\t\t// Check if the valid moves allows this piece to be selectable\n\t\t\t\t\tvar selectable = !this.props.readonly && this.props.board.validMoves.some(move => areCoordinatesEqual(move[0], coords));\n\t\t\t\t\t// Check if this piece can take another and thus must be moved\n\t\t\t\t\tvar forced = selectable && this.props.board.nextMoveMustBeJump;\n\t\t\t\t\t// Check if this piece is the currently selected piece\n\t\t\t\t\tvar selected = selectable && this.state.selectedTile ? areCoordinatesEqual(this.state.selectedTile, coords) : false;\n\t\t\t\t\t// Check if this tile was part of the previous move\n\n\t\t\t\t\tvar previous = false;\n\t\t\t\t\tif (this.props.moveToAnimate) {\n\n\t\t\t\t\t\t// If the board's TurnMoves are part of the current turn we want to mark the tiles specified\n\t\t\t\t\t\tprevious = this.props.board.turnMoves.length > 1 && this.props.board.turnMoves.some(move => move.some(moveCoords => areCoordinatesEqual(moveCoords, coords)));\n\n\t\t\t\t\t\t// If the move being animated involves this tile we want to mark it\n\t\t\t\t\t\tif (!previous) previous = this.props.moveToAnimate.some(moveCoords => areCoordinatesEqual(moveCoords, coords));\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// If we're not animating a move at the moment just mark the tiles described by the board's TurnMoves\n\t\t\t\t\t\tprevious = this.props.board.turnMoves.some(move => move.some(moveCoords => areCoordinatesEqual(moveCoords, coords)));\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if the selected piece could move onto this tile\n\t\t\t\t\tvar destination = possibleSelectedTileMoves && possibleSelectedTileMoves.some(move => areCoordinatesEqual(move[1], coords));\n\t\t\t\t\tvar forcedDestination = destination && this.props.board.nextMoveMustBeJump;\n\n\t\t\t\t\t// If this tile needs to be animated calculate the transform required\n\t\t\t\t\tvar transformX = 0;\n\t\t\t\t\tvar transformY = 0;\n\t\t\t\t\tif (this.props.moveToAnimate && areCoordinatesEqual(this.props.moveToAnimate[0], coords)) {\n\t\t\t\t\t\ttransformX = (offsetMoveToAnimate[1][0] - x) * (this.props.flip ? -1 : 1);\n\t\t\t\t\t\ttransformY = (offsetMoveToAnimate[1][1] - y) * (this.props.flip ? -1 : 1);\n\t\t\t\t\t}\n\n\t\t\t\t\t// If this tile's piece was taken we pass this information to the piece to animate the shrink and fade\n\t\t\t\t\tvar taken = moveToAnimateJumped && areCoordinatesEqual(moveToAnimateJumped, [x, y]);\n\n\t\t\t\t\t// Pass all of the calculated values to a Tile component and add it to the row\n\t\t\t\t\trow.push((\n\t\t\t\t\t\t this.onTileClicked(tileCoords)}\n\t\t\t\t\t\t\tkey={i} />));\n\t\t\t\t} else {\n\t\t\t\t\trow.push((\n\t\t\t\t\t\t this.onTileClicked(tileCoords)}\n\t\t\t\t\t\t\tkey={i} />));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trows.push(\n\t\t\t\t
\n\t\t\t\t\t{this.props.flip ? row.reverse() : row}\n\t\t\t\t
\n\t\t\t);\n\t\t}\n\n\t\treturn this.props.flip ? rows.reverse() : rows;\n\t}\n\n\tcomponentDidUpdate(prevProps) {\n\t\t// Prevent infinite update loop by only updating the \n\t\t// selected tile if the board has changed\n\t\tif (this.props.board === prevProps.board) return;\n\n\t\t// If all of the valid moves originate from the same tile\n\t\t// we might as well select it to make for a smoother user experience\n\t\tif (!this.props.readonly &&\n\t\t\tthis.props.board.validMoves.length > 0 &&\n\t\t\tthis.props.board.validMoves.every(move => areCoordinatesEqual(move[0], this.props.board.validMoves[0][0]))) {\n\t\t\tthis.setState({ selectedTile: this.props.board.validMoves[0][0] });\n\t\t}\n\t}\n\n\tonTileClicked(coords) {\n\n\t\tif (this.props.readonly) {\n\t\t\treturn;\n\t\t}\n\n\t\t// A non-playable tile won't pass coordinates so unselect the previously selected tile and return\n\t\tif (!coords) {\n\t\t\tthis.setState({ selectedTile: null });\n\t\t\treturn;\n\t\t}\n\n\t\t// Check to see if clicking this tile completes a move starting from the previously selected tile\n\t\tvar completesMove = this.state.selectedTile\n\t\t\t&& this.props.board.validMoves\n\t\t\t\t.filter(move => areCoordinatesEqual(move[0], this.state.selectedTile))\n\t\t\t\t.some(move => areCoordinatesEqual(move[1], coords));\n\n\t\tif (completesMove) {\n\t\t\tvar tile = this.state.selectedTile;\n\t\t\tthis.setState({ selectedTile: null });\n\n\t\t\t// Tell the parent component (pages/Game) that the player has taken a move\n\t\t\tthis.props.onMoveTaken(tile, coords);\n\n\t\t} else {\n\n\t\t\t// Check to see if this tile can be selected\n\t\t\tvar selectable = this.props.board.validMoves.some(move => areCoordinatesEqual(move[0], coords));\n\n\t\t\tif (selectable) {\n\t\t\t\tthis.setState({ selectedTile: coords });\n\t\t\t} else {\n\t\t\t\tthis.setState({ selectedTile: null });\n\t\t\t}\n\t\t}\n\t}\n}\n\n// We can't compare two arrays with === because their references (memory pointers) will be compared, not their values\nfunction areCoordinatesEqual(a, b) {\n\treturn a[0] === b[0] && a[1] === b[1];\n}\n","import React from \"react\";\nimport { Redirect, withRouter } from \"react-router\";\n\nimport Board from \"../components/board/Board\";\nimport MessageBox from \"../components/MessageBox\";\n\nclass Game extends React.Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\tgame: null,\n\t\t\tboard: null,\n\t\t\tmoveToAnimate: null,\n\t\t\tplayerNumber: null,\n\t\t\tplayerLeft: false\n\t\t};\n\t\tthis.gameCode = this.props.match.params.gameCode;\n\t}\n\n\trender() {\n\t\t// If the state has been set to redirect the user, redirect them\n\t\tif (this.state.redirect) {\n\t\t\treturn (\n\t\t\t\t\n\t\t\t);\n\t\t}\n\n\t\t// If the game hasn't been received from the server yet display a loading message\n\t\tif (!this.state.game) {\n\t\t\treturn (\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t);\n\t\t}\n\n\t\tvar ableToTakeMove = this.state.game.type === 0 || this.state.game.board.nextPlayer === this.state.playerNumber;\n\n\t\t// Render the board and message box if necessary\n\t\treturn (\n\t\t\t
\n\t\t\t\t this.onBoardMoveTaken(origin, destination)} />\n\t\t\t\t{this.renderMessageBox()}\n\t\t\t
\n\t\t);\n\t}\n\n\trenderMessageBox() {\n\t\t// If someone has won display a message box with the winner\n\t\t// If the other player has left display an error message\n\t\t// If neither condition is met render no message box\n\t\tif (this.state.game.board.winner !== -1) {\n\n\t\t\t// If this is a local multiplayer game display Black/White won!\n\t\t\t// Otherwise display Victory! or Defeat!\n\t\t\tvar winMessage = null;\n\t\t\tif (this.state.game.type === 0)\n\t\t\t\twinMessage = `${this.state.game.board.winner === 0 ? \"Black\" : \"White\"} won!`;\n\t\t\telse\n\t\t\t\twinMessage = this.state.game.board.winner === this.state.playerNumber ? \"Victory!\" : \"Defeat!\";\n\n\t\t\treturn (\n\t\t\t\t\n\t\t\t);\n\t\t} else if (this.state.playerLeft) {\n\t\t\treturn (\n\t\t\t\t\n\t\t\t);\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync componentDidMount() {\n\t\t// When the component mounts register a handler to the server's game updated event\n\t\twindow._connection.on(\"GAME_UPDATED\", this.handleOnGameUpdated);\n\t\twindow._connection.on(\"PLAYER_LEFT\", this.handleOnPlayerLeft);\n\n\t\tvar response = await window._connection.invoke(\"READY\", this.gameCode);\n\t\tif (response === -1) this.setState({ redirect: \"/play\" });\n\n\t\tthis.setState({ playerNumber: response });\n\t}\n\n\tasync componentWillUnmount() {\n\t\t// To avoid a memory leak, unregister the game updated event handler\n\t\twindow._connection.off(\"GAME_UPDATED\", this.handleOnGameUpdated);\n\t\twindow._connection.off(\"PLAYER_LEFT\", this.handlePlayerLeft);\n\t\ttry {\n\t\t\tawait window._connection.invoke(\"LEAVE_GAME\", this.gameCode);\n\t\t} catch { }\n\t}\n\n\thandleOnGameUpdated = (game) => this.onGameUpdated(game);\n\n\tonGameUpdated(game) {\n\n\t\t// If this is the first game updated set the board as well as the game\n\t\tif (!this.state.game) {\n\t\t\tthis.setState({ game: game, board: game.board });\n\t\t\treturn;\n\t\t}\n\n\t\t// Update the game state but not the board\n\t\tthis.setState({ game: game });\n\n\t\t// Find the move to animate and tell the board to animate it.\n\t\tvar moveToAnimate = game.board.turnMoves.at(-1);\n\t\tif (moveToAnimate) {\n\t\t\tthis.setState({ moveToAnimate: moveToAnimate });\n\n\t\t\t// After a set delay (the animation should have completed), update the board.\n\t\t\t// If we updated the board immediately the Board would try to animate the move starting from the new board state.\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.setState({ board: game.board, moveToAnimate: null });\n\t\t\t}, 210);\n\t\t} else {\n\t\t\tthis.setState({ board: game.board });\n\t\t}\n\t}\n\n\thandleOnPlayerLeft = () => this.onPlayerLeft();\n\n\tonPlayerLeft() {\n\t\tthis.setState({ playerLeft: true });\n\t}\n\n\tasync onBoardMoveTaken(origin, destination) {\n\t\t// When the board tells us the player has taken a move, send it to the server\n\t\tawait window._connection.invoke(\"TAKE_MOVE\", this.gameCode, origin, destination);\n\t}\n}\n\nexport default withRouter(Game);\n","import { useLocation } from \"react-router-dom\";\n\nexport default function ScrollToTop(props) {\n\t// useLocation hook means this component always re-renders when page changes\n\tuseLocation();\n\t// When the page changes, scroll to the top\n\twindow.scrollTo(0, 0);\n\t// Don't render anything to the page\n\treturn null;\n}\n","import React from \"react\";\nimport { BrowserRouter as Router, Switch, Route } from \"react-router-dom\";\nimport { HubConnectionBuilder, HubConnectionState } from \"@microsoft/signalr\";\n\nimport Footer from \"./components/layout/Footer\";\nimport Navbar from \"./components/layout/Navbar\";\nimport Index from \"./pages/Index\";\nimport HowToPlay from \"./pages/HowToPlay\";\nimport Play from \"./pages/play/Play\";\nimport Game from \"./pages/Game\";\n\nimport MessageBox from \"./components/MessageBox\";\nimport ScrollToTop from \"./components/ScrollToTop\";\n\nexport default class App extends React.Component {\n\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\tstatus: \"Connecting to the server...\"\n\t\t};\n\t}\n\n\t// Render the main structure of the page including the navbar, content and footer\n\trender() {\n\t\treturn (\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{this.renderContent()}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t