Skip to content

Commit d1abde5

Browse files
authored
Merge pull request #204 from daithihearn/autoplay
Autoplay
2 parents 8304979 + 7bb9ada commit d1abde5

28 files changed

+665
-1306
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "frontend",
3-
"version": "8.0.2",
3+
"version": "8.0.3",
44
"description": "React frontend for the Cards 110",
55
"author": "Daithi Hearn",
66
"license": "MIT",

public/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"short_name": "Cards 110",
33
"name": "Cards 110",
4-
"version": "8.0.2",
4+
"version": "8.0.3",
55
"icons": [
66
{
77
"src": "./assets/favicon.png",

src/caches/GameSlice.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { createSelector, createSlice, PayloadAction } from "@reduxjs/toolkit"
33
import { GameState, GameStateResponse, GameStatus } from "model/Game"
44
import { RoundStatus } from "model/Round"
55
import { RootState } from "./caches"
6-
import { processOrderedCardsAfterGameUpdate } from "utils/GameUtils"
6+
import {
7+
padMyHand,
8+
parseCards,
9+
processOrderedCardsAfterGameUpdate,
10+
} from "utils/GameUtils"
711
import { Card, CARDS, EMPTY } from "model/Cards"
812
import { determineEvent } from "utils/EventUtils"
913
import { Event } from "model/Events"
@@ -30,7 +34,9 @@ export const gameSlice = createSlice({
3034
if (action.payload.id !== state.id) {
3135
return {
3236
...action.payload,
33-
cardsFull: (action.payload.cards ?? []).map(c => CARDS[c]),
37+
cardsFull: padMyHand(
38+
parseCards(action.payload.cards ?? []),
39+
),
3440
event: Event.Unknown,
3541
}
3642
}

src/components/Game/Actions/Buying.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,31 @@ import { useCallback, useState } from "react"
33
import { useAppSelector } from "caches/hooks"
44
import {
55
getGameId,
6+
getIHavePlayed,
7+
getIamGoer,
68
getIsMyGo,
79
getSelectedCards,
810
getSuit,
911
} from "caches/GameSlice"
1012
import ThrowCardsWarningModal from "./ThrowCardsWarningModal"
1113
import { Button } from "@mui/material"
1214
import { useGameActions } from "components/Hooks/useGameActions"
15+
import { useSettings } from "components/Hooks/useSettings"
16+
17+
const WaitingForRoundToStart = () => (
18+
<Button variant="contained" disableRipple color="primary">
19+
<b>Waiting for round to start...</b>
20+
</Button>
21+
)
1322

1423
const Buying = () => {
1524
const { buyCards } = useGameActions()
16-
25+
const { settings } = useSettings()
1726
const gameId = useAppSelector(getGameId)
1827
const suit = useAppSelector(getSuit)
1928
const isMyGo = useAppSelector(getIsMyGo)
29+
const iHavePlayed = useAppSelector(getIHavePlayed)
30+
const iamGoer = useAppSelector(getIamGoer)
2031

2132
const [deleteCardsDialog, setDeleteCardsDialog] = useState(false)
2233

@@ -34,6 +45,8 @@ const Buying = () => {
3445
setDeleteCardsDialog(false)
3546
}, [])
3647

48+
if (iHavePlayed || settings?.autoBuyCards || iamGoer)
49+
return <WaitingForRoundToStart />
3750
return (
3851
<>
3952
<Button type="button" onClick={buyCardsWrapper} color="primary">

src/components/Game/AutoActionManager.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
11
import { useEffect } from "react"
22

33
import { useAppSelector } from "caches/hooks"
4-
import { getGameId, getIsInBunker } from "caches/GameSlice"
4+
import { getGame, getIsInBunker } from "caches/GameSlice"
55
import { useGameActions } from "components/Hooks/useGameActions"
6+
import { RoundStatus } from "model/Round"
7+
import { useSettings } from "components/Hooks/useSettings"
8+
import { pickBestCards } from "utils/GameUtils"
69

710
const AutoActionManager = () => {
8-
const { call } = useGameActions()
9-
const gameId = useAppSelector(getGameId)
11+
const { call, buyCards } = useGameActions()
12+
const { settings } = useSettings()
13+
const game = useAppSelector(getGame)
1014
const isInBunker = useAppSelector(getIsInBunker)
1115

12-
// If in the bunker, Pass
1316
useEffect(() => {
14-
if (gameId && isInBunker) call({ gameId, call: "0" })
15-
}, [gameId, isInBunker])
17+
if (game.id && game.isMyGo) {
18+
// Card Buying
19+
if (game.round?.status === RoundStatus.BUYING) {
20+
if (game.iamGoer) {
21+
buyCards({ gameId: game.id, cards: game.cards })
22+
} else if (settings?.autoBuyCards && game.round?.suit) {
23+
buyCards({
24+
gameId: game.id,
25+
cards: pickBestCards(
26+
game.cards,
27+
game.round.suit,
28+
game.players.length,
29+
),
30+
})
31+
}
32+
}
33+
34+
if (game.id && isInBunker) call({ gameId: game.id, call: "0" })
35+
}
36+
}, [game, settings, isInBunker])
1637

1738
return null
1839
}

src/components/Game/PlayerCard.tsx

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useMemo, useState } from "react"
1+
import React, { useCallback, useEffect, useMemo, useState } from "react"
22
import {
33
Grid,
44
CardMedia,
@@ -17,9 +17,9 @@ import { Player, PlayerProfile } from "model/Player"
1717
import Leaderboard from "components/Leaderboard/Leaderboard"
1818
import { Suit } from "model/Suit"
1919
import { FormatName } from "utils/FormattingUtils"
20-
import { CardName } from "model/Cards"
2120
import { useAppSelector } from "caches/hooks"
22-
import { getIsRoundPlaying, getRound } from "caches/GameSlice"
21+
import { getGame, getIsRoundPlaying, getRound } from "caches/GameSlice"
22+
import { Event } from "model/Events"
2323

2424
interface PlayerRowI {
2525
player: Player
@@ -153,7 +153,11 @@ const DealerChip: React.FC<{
153153

154154
const PlayerCard: React.FC<PlayerRowI> = ({ player, profile, className }) => {
155155
const theme = useTheme()
156-
const round = useAppSelector(getRound)
156+
const game = useAppSelector(getGame)
157+
const [revisionActioned, setRevisionActioned] = useState(-1)
158+
const [playedCard, setPlayedCard] = useState<PlayedCard | undefined>(
159+
undefined,
160+
)
157161
const [modalLeaderboard, setModalLeaderboard] = useState(false)
158162

159163
const toggleLeaderboardModal = useCallback(
@@ -162,22 +166,53 @@ const PlayerCard: React.FC<PlayerRowI> = ({ player, profile, className }) => {
162166
)
163167

164168
const isGoer: boolean = useMemo(
165-
() => !!round && round.goerId === player.id,
166-
[round, player],
169+
() => !!game.round && game.round.goerId === player.id,
170+
[game.round, player],
167171
)
168172

169-
const playedCard = useMemo<PlayedCard | undefined>(() => {
170-
if (round) {
171-
return round.currentHand.playedCards?.find(
172-
c => c.playerId === player.id,
173-
)
173+
const delayResetCard = useCallback(() => {
174+
// The in 3 seconds set it back to undefined
175+
setTimeout(() => {
176+
setPlayedCard(undefined)
177+
}, 3000)
178+
}, [])
179+
180+
useEffect(() => {
181+
if (game.round && game.revision > revisionActioned) {
182+
if (game.event === Event.HandEnd) {
183+
// Set card from the last hand
184+
setPlayedCard(
185+
game.round.completedHands
186+
.toReversed()[0]
187+
?.playedCards?.find(c => c.playerId === player.id),
188+
)
189+
delayResetCard()
190+
} else if (game.event === Event.RoundEnd) {
191+
// Set card from the previous round
192+
if (game.previousRound) {
193+
setPlayedCard(
194+
game.previousRound.completedHands
195+
.toReversed()[0]
196+
?.playedCards?.find(c => c.playerId === player.id),
197+
)
198+
}
199+
delayResetCard()
200+
} else {
201+
setPlayedCard(
202+
game.round.currentHand.playedCards?.find(
203+
c => c.playerId === player.id,
204+
),
205+
)
206+
}
207+
setRevisionActioned(game.revision)
174208
}
175-
return { card: CardName.EMPTY, playerId: player.id }
176-
}, [round, player])
209+
}, [game, player, delayResetCard, revisionActioned])
177210

178211
const isCurrentPlayer: boolean = useMemo(
179-
() => !!round && round.currentHand.currentPlayerId === player.id,
180-
[round, player],
212+
() =>
213+
!!game.round &&
214+
game.round.currentHand.currentPlayerId === player.id,
215+
[game.round, player],
181216
)
182217

183218
const scoreClassName = useMemo(() => {
@@ -248,7 +283,7 @@ const PlayerCard: React.FC<PlayerRowI> = ({ player, profile, className }) => {
248283
<BlankCard name={profile.name} />
249284
<DealerChip
250285
player={player}
251-
dealerId={round?.dealerId}
286+
dealerId={game.round?.dealerId}
252287
/>
253288
<CallChip call={player.call} isGoer={isGoer} />
254289
<SuitChip isGoer={isGoer} />

src/model/Game.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface GameStateResponse {
3838
cards: CardName[]
3939
status: GameStatus
4040
round?: Round
41+
previousRound?: Round
4142
maxCall?: number
4243
me?: Player
4344
players: Player[]

src/test/data/buy-cards/after-buy-cards.json

Lines changed: 0 additions & 65 deletions
This file was deleted.

src/test/data/buy-cards/before-buy-cards.json

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)