chore: move gameboard logic to own component
This commit is contained in:
parent
22dfcb0265
commit
8e74da5443
124
src/App/Game.tsx
124
src/App/Game.tsx
@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import React, { ReactElement, useEffect, useState } from "react";
|
||||
import { SessionInfoPlayResultOver, useSession } from "../lib/store"
|
||||
import { CPUNAME, CPUS_NAMES } from "../lib/CPUS";
|
||||
import { Play, PLAYER_OPTIONS, PlayerAction, PlayResult } from "../lib/game";
|
||||
@ -39,21 +39,13 @@ export function Game() {
|
||||
return <></>
|
||||
}
|
||||
|
||||
function getBoxClass(target: PlayResult) {
|
||||
if (lastGame?.winner === 'tie') return 'h-full w-full';
|
||||
if (lastGame?.winner !== target) return 'loser-shrink-to-zero h-0 md:h-full w-full md:w-0';
|
||||
return 'h-1/2 w-full md:w-1/2 md:h-full flex-grow'
|
||||
}
|
||||
|
||||
// TODO maybe add an icon on top of the winner
|
||||
return <>
|
||||
<div className="h-[500px] flex flex-col md:flex-row rounded-xl overflow-hidden relative">
|
||||
<div className={`bg-blue-500/50 grid place-items-center overflow-hidden ${getBoxClass('user')}`}>
|
||||
<span className="text-4xl whitespace-nowrap">{session.currentUser}</span>
|
||||
</div>
|
||||
<div className={`bg-red-500/50 grid place-items-center overflow-hidden ${getBoxClass('cpu')}`}>
|
||||
<span className="text-4xl whitespace-nowrap">{lastGame.game.cpu}</span>
|
||||
</div>
|
||||
<GameBoard
|
||||
shrinkLoser={lastGame.winner}
|
||||
playerSide={<span className="text-4xl whitespace-nowrap">{session.currentUser}</span>}
|
||||
cpuSide={<span className="text-4xl whitespace-nowrap">{lastGame.game.cpu}</span>}
|
||||
>
|
||||
{lastGame.winner === 'tie' && <span className="top-1/2 left-1/2 -translate-1/2 text-yellow-400 drop-shadow-lg drop-shadow-yellow-400 absolute text-6xl">It's a Tie</span>}
|
||||
<button
|
||||
className="defaultBtn absolute bottom-[2em] left-1/2 -translate-x-1/2 shadow-md"
|
||||
@ -63,31 +55,28 @@ export function Game() {
|
||||
>
|
||||
New Game
|
||||
</button>
|
||||
</div>
|
||||
</GameBoard>
|
||||
<GameHistory />
|
||||
</>
|
||||
}
|
||||
|
||||
if (!session.currentGame) {
|
||||
return <div className="h-[500px] flex flex-col md:flex-row rounded-xl overflow-hidden relative">
|
||||
<div className="bg-blue-500/50 h-1/2 md:h-full w-full md:w-1/2 p-4 grid place-items-center">
|
||||
<span className="text-3xl">{session.currentUser}</span>
|
||||
</div>
|
||||
<div className="bg-red-500/50 h-1/2 md:h-full w-full md:w-1/2 p-4 grid place-items-center">
|
||||
return <GameBoard
|
||||
playerSide={<span className="text-3xl">{session.currentUser}</span>}
|
||||
cpuSide={
|
||||
<select className="text-3xl" value={selectedCPU} onChange={(e) => setSelectedCPU(e.currentTarget.value as CPUNAME)}>
|
||||
{CPUS_NAMES.map(a => <option key={a} value={a}>{a}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<button
|
||||
className="defaultBtn absolute bottom-[2em] left-1/2 -translate-x-1/2 shadow-md"
|
||||
onClick={() => {
|
||||
session.startGame(selectedCPU);
|
||||
}}
|
||||
onClick={() => session.startGame(selectedCPU)}
|
||||
>
|
||||
Start Game
|
||||
</button>
|
||||
<span className="absolute top-1/2 left-1/2 -translate-x-[56%] -translate-y-1/2 drop-shadow-lg font-bold text-6xl">VS</span>
|
||||
</div>
|
||||
</GameBoard>
|
||||
}
|
||||
|
||||
if (gameState === 'result') {
|
||||
@ -97,8 +86,8 @@ export function Game() {
|
||||
return <></>
|
||||
}
|
||||
return <>
|
||||
<div className="h-[500px] flex flex-col md:flex-row rounded-xl overflow-hidden relative">
|
||||
<div className="bg-blue-500/50 h-1/2 md:h-full w-full md:w-1/2 p-4 grid place-items-center relative">
|
||||
<GameBoard
|
||||
playerSide={<>
|
||||
<span className="absolute top-[1em] left-1/2 -translate-1/2 text-2xl">{session.currentUser}</span>
|
||||
<div className="text-2xl">
|
||||
<span className="font-bold">
|
||||
@ -106,8 +95,8 @@ export function Game() {
|
||||
</span>
|
||||
<WinnerText me='user' result={result.winner} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-red-500/50 h-1/2 md:h-full w-full md:w-1/2 p-4 grid place-items-center relative">
|
||||
</>}
|
||||
cpuSide={<>
|
||||
<span className="absolute bottom-2 md:bottom-[unset] md:top-[1em] left-1/2 -translate-x-1/2 text-2xl whitespace-nowrap">{session.currentGame!.cpu}</span>
|
||||
<div className="text-2xl">
|
||||
<span className="font-bold">
|
||||
@ -115,7 +104,8 @@ export function Game() {
|
||||
</span>
|
||||
<WinnerText me='cpu' result={result.winner} />
|
||||
</div>
|
||||
</div>
|
||||
</>}
|
||||
>
|
||||
<span className="absolute top-1/2 left-1/2 -translate-x-[56%] -translate-y-1/2 drop-shadow-lg font-bold text-6xl">VS</span>
|
||||
<button
|
||||
className="defaultBtn absolute text-xs px-2! md:text-base right-1 top-1/2 md:top-[unset] -translate-x-0 md:right-[unset] md:-translate-x-1/2 md:bottom-[2em] md:left-1/2 -translate-1/2 shadow-md"
|
||||
@ -126,7 +116,7 @@ export function Game() {
|
||||
Next Round
|
||||
</button>
|
||||
<PointsDisplay />
|
||||
</div>
|
||||
</GameBoard>
|
||||
<GameHistory />
|
||||
</>
|
||||
}
|
||||
@ -144,30 +134,29 @@ export function Game() {
|
||||
|
||||
if (gameState === 'play') {
|
||||
return <>
|
||||
<div className="h-[500px] flex flex-col md:flex-row rounded-xl overflow-hidden relative">
|
||||
<div className="bg-blue-500/50 h-1/2 md:h-full w-full md:w-1/2 p-4 grid place-items-center relative">
|
||||
<span className="absolute top-[1em] left-1/2 -translate-1/2 text-2xl">{session.currentUser}</span>
|
||||
<div className="flex flex-wrap justify-around gap-2">
|
||||
{PLAYER_OPTIONS.map((a) =>
|
||||
<button
|
||||
key={a}
|
||||
type="button"
|
||||
className="p-2 drop-shadow-lg text-md md:text-2xl hover:drop-shadow-white cursor-pointer"
|
||||
onClick={() => play(a)}
|
||||
>
|
||||
{a}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-red-500/50 h-1/2 md:h-full w-full md:w-1/2 p-4 grid place-items-center">
|
||||
<select className="text-4xl" value={selectedCPU} onChange={(e) => setSelectedCPU(e.currentTarget.value as CPUNAME)}>
|
||||
{CPUS_NAMES.map(a => <option key={a} value={a}>{a}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
<GameBoard
|
||||
playerSide={
|
||||
<>
|
||||
<span className="absolute top-[1em] left-1/2 -translate-1/2 text-2xl">{session.currentUser}</span>
|
||||
<div className="flex flex-wrap justify-around gap-2">
|
||||
{PLAYER_OPTIONS.map((a) =>
|
||||
<button
|
||||
key={a}
|
||||
type="button"
|
||||
className="p-2 drop-shadow-lg text-md md:text-2xl hover:drop-shadow-white cursor-pointer"
|
||||
onClick={() => play(a)}
|
||||
>
|
||||
{a}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
cpuSide={<span className="text-4xl">{session.currentGame.cpu}</span>}
|
||||
>
|
||||
<span className="absolute top-1/2 left-1/2 -translate-x-[56%] -translate-y-1/2 drop-shadow-lg font-bold text-6xl">VS</span>
|
||||
<PointsDisplay />
|
||||
</div>
|
||||
</GameBoard>
|
||||
<GameHistory />
|
||||
</>
|
||||
}
|
||||
@ -221,3 +210,32 @@ function GameHistory() {
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
function GameBoard({
|
||||
cpuSide,
|
||||
playerSide,
|
||||
children,
|
||||
shrinkLoser
|
||||
}: {
|
||||
cpuSide?: React.ReactNode,
|
||||
playerSide?: React.ReactNode,
|
||||
children?: React.ReactNode,
|
||||
shrinkLoser?: PlayResult
|
||||
}) {
|
||||
function getBoxClass(target: PlayResult) {
|
||||
if (!shrinkLoser) return 'h-1/2 w-full md:w-1/2 md:h-full flex-grow'
|
||||
if (shrinkLoser === 'tie') return 'h-full w-full';
|
||||
if (shrinkLoser !== target) return 'loser-shrink-to-zero h-0 md:h-full w-full md:w-0';
|
||||
return 'h-1/2 w-full md:w-1/2 md:h-full flex-grow'
|
||||
}
|
||||
|
||||
return <div className="h-[500px] flex flex-col md:flex-row rounded-xl overflow-hidden relative">
|
||||
<div className={`bg-blue-500/50 h-1/2 md:h-full w-full md:w-1/2 p-4 grid place-items-center relative ${getBoxClass('user')}`}>
|
||||
{playerSide}
|
||||
</div>
|
||||
<div className={`bg-red-500/50 grid place-items-center overflow-hidden relative ${getBoxClass('cpu')}`}>
|
||||
{cpuSide}
|
||||
</div>
|
||||
{children}
|
||||
</div >
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user