Skip to content

Commit

Permalink
Merge pull request #180 from daithihearn/full-auto-play-2
Browse files Browse the repository at this point in the history
Full auto play 2
  • Loading branch information
daithihearn authored Jul 9, 2023
2 parents 20d20e2 + de426c4 commit 79b0c62
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 62 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "7.3.0",
"version": "7.3.1",
"description": "React frontend for the Cards 110",
"author": "Daithi Hearn",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"short_name": "Cards 110",
"name": "Cards 110",
"version": "7.3.0",
"version": "7.3.1",
"icons": [
{
"src": "./assets/favicon.png",
Expand Down
122 changes: 68 additions & 54 deletions src/components/Game/Actions/PlayCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,66 @@ import { getGameId, getIsMyGo, getRound } from "caches/GameSlice"
import { BLANK_CARD } from "model/Cards"
import parseError from "utils/ErrorUtils"
import { RoundStatus } from "model/Round"
import { Button } from "@mui/material"
import {
Button,
ButtonGroup,
FormControl,
InputLabel,
MenuItem,
Select,
SelectChangeEvent,
useTheme,
} from "@mui/material"
import { getCardToPlay, updateCardToPlay } from "caches/PlayCardSlice"
import { bestCardLead, getBestCard, getWorstCard } from "utils/GameUtils"

const WaitingForYourTurn = () => (
<Button variant="contained" disableRipple color="secondary">
<b>Wait for your turn...</b>
</Button>
)
type AutoPlayState = "off" | "best" | "worst"

const PlayCard = () => {
const dispatch = useAppDispatch()
const theme = useTheme()
const round = useAppSelector(getRound)
const [autoPlay, setAutoPlay] = useState(false)
const [autoPlay, setAutoPlay] = useState<AutoPlayState>("off")
const gameId = useAppSelector(getGameId)
const myCards = useAppSelector(getMyCardsWithoutBlanks)
const isMyGo = useAppSelector(getIsMyGo)
const selectedCards = useAppSelector(getSelectedCards)
const cardToPlay = useAppSelector(getCardToPlay)

const togglePlayCard = useCallback(() => setAutoPlay(!autoPlay), [autoPlay])
const handleAutoPlayChange = useCallback(
(event: SelectChangeEvent<AutoPlayState>) => {
const value = event.target.value as AutoPlayState
setAutoPlay(value)
},
[],
)

const AutoPlayDropdown = () => (
<FormControl variant="filled" sx={{ minWidth: 90 }}>
<InputLabel id="autoplay-select-label">Autoplay</InputLabel>
<Select
labelId="autoplay-select-label"
label="Autoplay"
value={autoPlay}
onChange={handleAutoPlayChange}
sx={{
backgroundColor: theme.palette.primary.main,
"&:hover": {
backgroundColor: theme.palette.primary.main,
},
"& .MuiSelect-select:focus": {
backgroundColor: theme.palette.primary.main,
},
"& .MuiSelect-icon": {
color: theme.palette.primary.contrastText,
},
}}>
<MenuItem value="off">Off</MenuItem>
<MenuItem value="best">Best</MenuItem>
<MenuItem value="worst">Worst</MenuItem>
</Select>
</FormControl>
)

const playButtonEnabled = useMemo(
() =>
Expand All @@ -41,6 +80,17 @@ const PlayCard = () => {
[isMyGo, round, myCards],
)

const PlayCardButton = () => (
<Button
id="playCardButton"
type="button"
disabled={!playButtonEnabled}
onClick={selectCardToPlay}
color="warning">
<b>Play Card</b>
</Button>
)

const playCard = useCallback(
(card: string) =>
dispatch(GameService.playCard(gameId!, card)).catch(e => {
Expand All @@ -55,62 +105,26 @@ const PlayCard = () => {
}, [selectedCards])

// 1. Play card when you've pre-selected a card
// 2. If auto play is enabled, play best card
// 3. Play worst card if best card lead out
// 2. If best card lead or lead from bottom enabled, play worst card
// 3. If lead from the top enabled, play best card
useEffect(() => {
if (round?.suit && isMyGo) {
if (cardToPlay) playCard(cardToPlay)
else if (autoPlay) {
const bestCard = getBestCard(myCards, round.suit)
playCard(bestCard.name)
} else if (bestCardLead(round)) {
else if (autoPlay === "best" || bestCardLead(round)) {
const worstCard = getWorstCard(myCards, round.suit)
playCard(worstCard.name)
} else if (autoPlay === "worst") {
const bestCard = getBestCard(myCards, round.suit)
playCard(bestCard.name)
}
}
}, [playCard, autoPlay, round, isMyGo, myCards, cardToPlay])

if (autoPlay) {
return (
<Button
id="autoPlayCardButton"
type="button"
onClick={togglePlayCard}
color="error">
<b>Disable Auto Play</b>
</Button>
)
} else if (!playButtonEnabled)
return (
<>
<WaitingForYourTurn />
<Button
id="autoPlayCardButton"
type="button"
onClick={togglePlayCard}
color="warning">
<b>Enable Auto Play</b>
</Button>
</>
)
return (
<>
<Button
id="playCardButton"
type="button"
onClick={selectCardToPlay}
color="primary">
<b>Play Card</b>
</Button>

<Button
id="autoPlayCardButton"
type="button"
onClick={togglePlayCard}
color="warning">
<b>Enable Auto Play</b>
</Button>
</>
<ButtonGroup disableElevation variant="contained" size="large">
<PlayCardButton />
<AutoPlayDropdown />
</ButtonGroup>
)
}

Expand Down
1 change: 0 additions & 1 deletion src/components/Game/Actions/ThrowCardsWarningModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
CardMedia,
CardContent,
} from "@mui/material"
import { getGameId } from "caches/GameSlice"
import { useAppSelector } from "caches/hooks"
import { getMyCardsWithoutBlanks, getSelectedCards } from "caches/MyCardsSlice"
import { SelectableCard } from "model/Cards"
Expand Down
4 changes: 0 additions & 4 deletions src/pages/Game/_game.scss
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,6 @@
padding-left: 5px;
}

#playCardButton:disabled {
display: none;
}

@media (min-width: 576px) {

.modal-dialog {
Expand Down
25 changes: 24 additions & 1 deletion src/utils/GameUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,32 @@ export const riskOfMistakeBuyingCards = <T extends Card>(
selectedCards: T[],
myCards: T[],
) => {
// If you have selected 5 trumps then return false
if (areAllTrumpCards(selectedCards, suit)) {
return false
}

const deletingCards = removeAllFromHand(selectedCards, myCards)

for (const element of deletingCards) {
return containsATrumpCard(deletingCards, suit)
}

export const areAllTrumpCards = <T extends Card>(cards: T[], suit: Suit) => {
for (const element of cards) {
if (
element.name !== "JOKER" &&
element.name !== "ACE_HEARTS" &&
element.suit !== suit
) {
return false
}
}

return true
}

export const containsATrumpCard = <T extends Card>(cards: T[], suit: Suit) => {
for (const element of cards) {
if (
element.name === "JOKER" ||
element.name === "ACE_HEARTS" ||
Expand Down

0 comments on commit 79b0c62

Please sign in to comment.