Skip to content

Commit

Permalink
Basic functionality but mobile layout broken
Browse files Browse the repository at this point in the history
  • Loading branch information
Dean Sofer authored and Dean Sofer committed May 14, 2024
1 parent c4db5a1 commit 57e6a97
Show file tree
Hide file tree
Showing 31 changed files with 600 additions and 99 deletions.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/Game/Dice/index.tsx → src/Game/Dice.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MouseEventHandler } from 'react';
import * as IMAGES from './images';
import type { MouseEventHandler } from 'react';
import * as IMAGES from './images/dice';
import './Dice.css'

type DiceProps = {
Expand Down
12 changes: 0 additions & 12 deletions src/Game/Dice/images/index.ts

This file was deleted.

7 changes: 6 additions & 1 deletion src/Game/Game.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@

:nth-child(1 of .bar) {
order: 3;
display: flex;
flex-direction: column;
justify-content: flex-end;
}

:nth-child(2 of .bar) {
order: 7;
}
Expand Down Expand Up @@ -88,6 +90,9 @@

/* bottom */
:nth-child(n+13 of .point) {
display: flex;
flex-direction: column;
justify-content: flex-end;
&::before {
border-top: none;
border-bottom: 40vh solid black;
Expand Down
19 changes: 19 additions & 0 deletions src/Game/Piece.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.piece {
width: 100%;
aspect-ratio: 1;
cursor: pointer;
border-radius: 50%;

&.white {
/* background: white; */
}

&.black {
/* background: black; */
}

img {
width: 100%;
height: 100%;
}
}
29 changes: 29 additions & 0 deletions src/Game/Piece.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useCallback, type DragEventHandler } from "react";
import black from './images/piece-black-2.png';
import white from './images/piece-white-2.png';
import './Piece.css'

const IMAGES = { black, white }

type PieceProps = {
color: 'black' | 'white',
position?: number
}

export default function Piece({ color, position }: PieceProps) {
const onDragStart: DragEventHandler = useCallback((event) => {
switch (position) {
case undefined:
break;
case -1:
event.dataTransfer?.setData('text', color)
break;
default:
event.dataTransfer?.setData('text', position.toString())
}
}, [position, color]);

return <div className={`piece ${color}`} onDragStart={onDragStart} draggable={position !== undefined}>
<img src={IMAGES[color]} />
</div>
}
12 changes: 0 additions & 12 deletions src/Game/Piece/Piece.css

This file was deleted.

32 changes: 0 additions & 32 deletions src/Game/Piece/index.tsx

This file was deleted.

23 changes: 23 additions & 0 deletions src/Game/Point.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useCallback, type DragEventHandler } from "react";
import Piece from './Piece'

type PointProps = {
pieces: number,
move: (from: number, to: number) => void,
position: number
}

export default function Point({ pieces, move, position }: PointProps) {
const onDragOver: DragEventHandler = useCallback((event) => { event.preventDefault(); }, [])
const onDrop: DragEventHandler = useCallback((event) => {
event.preventDefault();
let from = event.dataTransfer?.getData("text")!
return move(from, position)
}, [move])

const color = pieces > 0 ? 'white' : 'black';

return <div className="point" onDragOver={onDragOver} onDrop={onDrop}>
{Array.from({ length: Math.abs(pieces) }, (_, index) => <Piece key={index} color={color} position={position} />)}
</div>
}
File renamed without changes.
12 changes: 12 additions & 0 deletions src/Game/images/dice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export { default as black1 } from './digit-1-black.png';
export { default as black2 } from './digit-2-black.png';
export { default as black3 } from './digit-3-black.png';
export { default as black4 } from './digit-4-black.png';
export { default as black5 } from './digit-5-black.png';
export { default as black6 } from './digit-6-black.png';
export { default as white1 } from './digit-1-white.png';
export { default as white2 } from './digit-2-white.png';
export { default as white3 } from './digit-3-white.png';
export { default as white4 } from './digit-4-white.png';
export { default as white5 } from './digit-5-white.png';
export { default as white6 } from './digit-6-white.png';
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
106 changes: 74 additions & 32 deletions src/Game/index.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,80 @@
import './Game.css';
import Dice from './Dice';
import Point from './Piece';
import { useCallback, useState } from 'react';
import Point from './Point';
import Piece from './Piece';
import { useCallback, useState, type DragEventHandler } from 'react';


// White = Positive, Black = Negative
const DEFAULT_BOARD = [
5, 0, 0, 0, -3, 0, -5, 0, 0, 0, 0, 2,
-5, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, -2,
]

export default function Game() {
const [home, setHome] = useState(() => [0, 0])
const [blackHome, setBlackHome] = useState(0)
const [whiteHome, setWhiteHome] = useState(0)
const [blackBar, setBlackBar] = useState(0)
const [whiteBar, setWhiteBar] = useState(0)
const [board, setBoard] = useState(() => [...DEFAULT_BOARD])
const [dice, setDice] = useState(() => [6, 6])



const reset = useCallback(() => {
// TODO: skip confirmation if game is over?
if (!confirm('Are you sure you want to restart the game?')) { return; }

setBoard(DEFAULT_BOARD);
}, [])

const move = useCallback((from: number, to: number) => {
const fromPieces = board[from];
if (!fromPieces) return;
// TODO: Validate moves against dice
const move = useCallback((from: number | "white" | "black", to: number) => {
if (from == to) return; // no move
const nextBoard = [...board];
if (from == "white") { // white re-enter
if (board[to] == -1) { // hit
setBlackBar(bar => bar + 1)
nextBoard[to] = 0
}
if (board[to] >= -1) {
setWhiteBar(bar => bar - 1)
nextBoard[to]++
}
} else if (from == 'black') { // black re-enter
if (board[to] == 1) { // hit
setWhiteBar(bar => bar + 1)
nextBoard[to] = 0
}
if (board[to] <= 1) {
setBlackBar(bar => bar - 1)
nextBoard[to]--
}
} else {
const offense = board[from];
const defense = board[to];

// TODO: Validate moves against dice
if (!defense || Math.sign(defense) === Math.sign(offense)) { // move
nextBoard[to] += Math.sign(offense)
} else if (to === -1) { // bear off
if (offense > 0) {
setWhiteHome(count => count + 1)
} else {
setBlackHome(count => count + 1)
}
} else if (Math.abs(defense) === 1) { // hit
nextBoard[to] = -Math.sign(defense);
if (offense > 0)
setBlackBar(bar => bar + 1)
else
setWhiteBar(bar => bar + 1)
} else { // stalemate
return
}

if (to === -1) {
// TODO: bear off piece
} else if (board[to] === 1) {
board[to] = -1;
// TODO: move piece to bar
} else if (board[to] === -1) {
board[to] = 1;
// TODO: move piece to bar
} else if (board[to] > 0 && fromPieces > 0) {
board[to]++;
board[from]--;
} else if (board[to] < 0 && fromPieces < 0) {
board[to]--;
board[from]++;
} else {
return
nextBoard[from] -= Math.sign(offense)
}
setBoard([...board]);

console.log('moveend', nextBoard)
setBoard([...nextBoard]);
}, [board])

const roll = useCallback(() => {
Expand All @@ -54,15 +83,28 @@ export default function Game() {
setDice([first, second])
}, [])

const onDragOver: DragEventHandler = useCallback((event) => { event.preventDefault(); }, [])
const onDrop: DragEventHandler = useCallback((event) => {
event.preventDefault();
let from = parseInt(event.dataTransfer?.getData("text")!)
return move(from, -1,)
}, [move])

return <div id="board">
<Dice onClick={roll} values={dice} />

{board.slice(0, 12).map((pieces, index) => <Point pieces={pieces} move={move} position={index} />)}
<div className="bar"></div>
<div className="bar"></div>
{board.slice(12).map((pieces, index) => <Point pieces={pieces} move={move} position={index} />)}
<div className="home"></div>
<div className="home"></div>
<div className="bar">
{Array.from({ length: whiteBar }, (_, index) => <Piece key={index} position={-1} color="white" />)}
</div>
<div className="bar">
{Array.from({ length: blackBar }, (_, index) => <Piece key={index} position={-1} color="black" />)}
</div>
<div className="home" onDragOver={onDragOver} onDrop={onDrop}>
{Array.from({ length: blackHome }, (_, index) => <Piece key={index} color="black" />)}
</div>
<div className="home" onDragOver={onDragOver} onDrop={onDrop}>
{Array.from({ length: whiteHome }, (_, index) => <Piece key={index} color="white" />)}
</div>
{board.map((pieces, index) => <Point key={index} pieces={pieces} move={move} position={index} />)}
</div >;
}
Loading

0 comments on commit 57e6a97

Please sign in to comment.