mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
MISC: Validate bet input of casino mini games (#1694)
This commit is contained in:
86
src/Casino/BetInput.tsx
Normal file
86
src/Casino/BetInput.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import TextField from "@mui/material/TextField";
|
||||
import React, { useState } from "react";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { formatMoney } from "../ui/formatNumber";
|
||||
|
||||
export interface BetInputProps {
|
||||
initialBet: number;
|
||||
maxBet: number;
|
||||
gameInProgress: boolean;
|
||||
setBet: (bet: number) => void;
|
||||
validBetCallback?: () => void;
|
||||
invalidBetCallback?: () => void;
|
||||
}
|
||||
|
||||
export function BetInput({
|
||||
initialBet,
|
||||
maxBet,
|
||||
gameInProgress,
|
||||
setBet,
|
||||
validBetCallback,
|
||||
invalidBetCallback,
|
||||
}: BetInputProps): React.ReactElement {
|
||||
const [betValue, setBetValue] = useState<string>(initialBet.toString());
|
||||
const [helperText, setHelperText] = useState<string>("");
|
||||
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const betInput = event.target.value;
|
||||
setBetValue(betInput);
|
||||
const bet = Math.round(parseFloat(betInput));
|
||||
let isValid = false;
|
||||
/**
|
||||
* We intentionally do not check if the player has enough money. The player's money can change between these checks
|
||||
* and when the bet is actually used.
|
||||
*/
|
||||
if (isNaN(bet)) {
|
||||
setBet(0);
|
||||
setHelperText("Not a valid number");
|
||||
} else if (bet <= 0) {
|
||||
setBet(0);
|
||||
setHelperText("Must bet a positive amount");
|
||||
} else if (bet > maxBet) {
|
||||
// This is for the player's convenience. They can type a bunch of 9s, and we will set the max bet for them.
|
||||
setBetValue(String(maxBet));
|
||||
setBet(maxBet);
|
||||
} else {
|
||||
// Valid wager
|
||||
isValid = true;
|
||||
setBet(bet);
|
||||
setHelperText("");
|
||||
}
|
||||
if (isValid) {
|
||||
if (validBetCallback) {
|
||||
validBetCallback();
|
||||
}
|
||||
} else {
|
||||
if (invalidBetCallback) {
|
||||
invalidBetCallback();
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<TextField
|
||||
sx={{
|
||||
marginTop: "20px",
|
||||
marginBottom: "20px",
|
||||
width: "200px",
|
||||
"& .MuiInputLabel-root.Mui-disabled": {
|
||||
WebkitTextFillColor: Settings.theme.disabled,
|
||||
},
|
||||
"& .MuiInputBase-input.Mui-disabled": {
|
||||
WebkitTextFillColor: Settings.theme.disabled,
|
||||
},
|
||||
}}
|
||||
value={betValue}
|
||||
label={<>Wager (Max: {formatMoney(maxBet)})</>}
|
||||
disabled={gameInProgress}
|
||||
onChange={onChange}
|
||||
error={helperText !== ""}
|
||||
helperText={helperText}
|
||||
type="number"
|
||||
InputProps={{
|
||||
// Without startAdornment, label and placeholder are only shown when TextField is focused
|
||||
startAdornment: <></>,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,23 +1,24 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { Player } from "@player";
|
||||
import { Money } from "../ui/React/Money";
|
||||
import { win, reachedLimit } from "./Game";
|
||||
import { Deck } from "./CardDeck/Deck";
|
||||
import { Hand } from "./CardDeck/Hand";
|
||||
import { InputAdornment } from "@mui/material";
|
||||
import { ReactCard } from "./CardDeck/ReactCard";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { Money } from "../ui/React/Money";
|
||||
import { BetInput } from "./BetInput";
|
||||
import { Deck } from "./CardDeck/Deck";
|
||||
import { Hand } from "./CardDeck/Hand";
|
||||
import { ReactCard } from "./CardDeck/ReactCard";
|
||||
import { hasEnoughMoney, reachedLimit, win } from "./Game";
|
||||
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||
|
||||
const initialBet = 1e6;
|
||||
const maxBet = 100e6;
|
||||
|
||||
const MAX_BET = 100e6;
|
||||
export const DECK_COUNT = 5; // 5-deck multideck
|
||||
|
||||
enum Result {
|
||||
Pending = "",
|
||||
Pending = "Pending",
|
||||
PlayerWon = "You won!",
|
||||
PlayerWonByBlackjack = "You Won! Blackjack!",
|
||||
DealerWon = "You lost!",
|
||||
@@ -44,8 +45,6 @@ export class Blackjack extends React.Component<Record<string, never>, State> {
|
||||
|
||||
this.deck = new Deck(DECK_COUNT);
|
||||
|
||||
const initialBet = 1e6;
|
||||
|
||||
this.state = {
|
||||
playerHand: new Hand([]),
|
||||
dealerHand: new Hand([]),
|
||||
@@ -59,14 +58,8 @@ export class Blackjack extends React.Component<Record<string, never>, State> {
|
||||
};
|
||||
}
|
||||
|
||||
canStartGame = (): boolean => {
|
||||
const { bet } = this.state;
|
||||
|
||||
return Player.canAfford(bet);
|
||||
};
|
||||
|
||||
startGame = (): void => {
|
||||
if (!this.canStartGame() || reachedLimit()) {
|
||||
if (reachedLimit() || !hasEnoughMoney(this.state.bet)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,18 +196,37 @@ export class Blackjack extends React.Component<Record<string, never>, State> {
|
||||
};
|
||||
|
||||
finishGame = (result: Result): void => {
|
||||
const gains =
|
||||
result === Result.DealerWon
|
||||
? 0 // We took away the bet at the start, don't need to take more
|
||||
: result === Result.Tie
|
||||
? this.state.bet // We took away the bet at the start, give it back
|
||||
: result === Result.PlayerWon
|
||||
? 2 * this.state.bet // Give back their bet plus their winnings
|
||||
: result === Result.PlayerWonByBlackjack
|
||||
? 2.5 * this.state.bet // Blackjack pays out 1.5x bet!
|
||||
: (() => {
|
||||
throw new Error(`Unexpected result: ${result}`);
|
||||
})(); // This can't happen, right?
|
||||
/**
|
||||
* Explicitly declare the type of "gains". If we forget a case here, TypeScript will notify us: "Variable 'gains' is
|
||||
* used before being assigned.".
|
||||
*/
|
||||
let gains: number;
|
||||
switch (result) {
|
||||
case Result.DealerWon:
|
||||
// We took away the bet at the start, don't need to take more
|
||||
gains = 0;
|
||||
break;
|
||||
case Result.Tie:
|
||||
// We took away the bet at the start, give it back
|
||||
gains = this.state.bet;
|
||||
break;
|
||||
case Result.PlayerWon:
|
||||
// Give back their bet plus their winnings
|
||||
gains = 2 * this.state.bet;
|
||||
break;
|
||||
case Result.PlayerWonByBlackjack:
|
||||
// Blackjack pays out 1.5x bet!
|
||||
gains = 2.5 * this.state.bet;
|
||||
break;
|
||||
case Result.Pending:
|
||||
/**
|
||||
* Don't throw an error. Callers of this function are event handlers (onClick) of buttons. If we throw an error,
|
||||
* it won't be shown to the player.
|
||||
*/
|
||||
exceptionAlert(new Error(`Unexpected Blackjack result: ${result}.`));
|
||||
gains = 0;
|
||||
break;
|
||||
}
|
||||
win(gains);
|
||||
this.setState({
|
||||
gameInProgress: false,
|
||||
@@ -223,49 +235,6 @@ export class Blackjack extends React.Component<Record<string, never>, State> {
|
||||
});
|
||||
};
|
||||
|
||||
wagerOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
const betInput = event.target.value;
|
||||
const wager = Math.round(parseFloat(betInput));
|
||||
if (isNaN(wager)) {
|
||||
this.setState({
|
||||
bet: 0,
|
||||
betInput,
|
||||
wagerInvalid: true,
|
||||
wagerInvalidHelperText: "Not a valid number",
|
||||
});
|
||||
} else if (wager <= 0) {
|
||||
this.setState({
|
||||
bet: 0,
|
||||
betInput,
|
||||
wagerInvalid: true,
|
||||
wagerInvalidHelperText: "Must bet a positive amount",
|
||||
});
|
||||
} else if (wager > MAX_BET) {
|
||||
this.setState({
|
||||
bet: 0,
|
||||
betInput,
|
||||
wagerInvalid: true,
|
||||
wagerInvalidHelperText: "Exceeds max bet",
|
||||
});
|
||||
} else if (!Player.canAfford(wager)) {
|
||||
this.setState({
|
||||
bet: 0,
|
||||
betInput,
|
||||
wagerInvalid: true,
|
||||
wagerInvalidHelperText: "Not enough money",
|
||||
});
|
||||
} else {
|
||||
// Valid wager
|
||||
this.setState({
|
||||
bet: wager,
|
||||
betInput,
|
||||
wagerInvalid: false,
|
||||
wagerInvalidHelperText: "",
|
||||
result: Result.Pending, // Reset previous game status to clear the win/lose text UI
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Start game button
|
||||
startOnClick = (event: React.MouseEvent): void => {
|
||||
// Protect against scripting...although maybe this would be fun to automate
|
||||
@@ -279,8 +248,7 @@ export class Blackjack extends React.Component<Record<string, never>, State> {
|
||||
};
|
||||
|
||||
render(): React.ReactNode {
|
||||
const { betInput, playerHand, dealerHand, gameInProgress, result, wagerInvalid, wagerInvalidHelperText, gains } =
|
||||
this.state;
|
||||
const { playerHand, dealerHand, gameInProgress, result, wagerInvalid, gains } = this.state;
|
||||
|
||||
// Get the player totals to display.
|
||||
const playerHandValues = this.getHandDisplayValues(playerHand);
|
||||
@@ -288,31 +256,26 @@ export class Blackjack extends React.Component<Record<string, never>, State> {
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Wager input */}
|
||||
<Box>
|
||||
<TextField
|
||||
value={betInput}
|
||||
label={
|
||||
<>
|
||||
{"Wager (Max: "}
|
||||
<Money money={MAX_BET} />
|
||||
{")"}
|
||||
</>
|
||||
}
|
||||
disabled={gameInProgress}
|
||||
onChange={this.wagerOnChange}
|
||||
error={wagerInvalid}
|
||||
helperText={wagerInvalid ? wagerInvalidHelperText : ""}
|
||||
type="number"
|
||||
style={{
|
||||
width: "200px",
|
||||
<BetInput
|
||||
initialBet={initialBet}
|
||||
maxBet={maxBet}
|
||||
gameInProgress={gameInProgress}
|
||||
setBet={(bet) => {
|
||||
this.setState({
|
||||
bet,
|
||||
});
|
||||
}}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<Typography>$</Typography>
|
||||
</InputAdornment>
|
||||
),
|
||||
validBetCallback={() => {
|
||||
this.setState({
|
||||
wagerInvalid: false,
|
||||
result: Result.Pending,
|
||||
});
|
||||
}}
|
||||
invalidBetCallback={() => {
|
||||
this.setState({
|
||||
wagerInvalid: true,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -324,7 +287,7 @@ export class Blackjack extends React.Component<Record<string, never>, State> {
|
||||
|
||||
{/* Buttons */}
|
||||
{!gameInProgress ? (
|
||||
<Button onClick={this.startOnClick} disabled={wagerInvalid || !this.canStartGame()}>
|
||||
<Button onClick={this.startOnClick} disabled={wagerInvalid}>
|
||||
Start
|
||||
</Button>
|
||||
) : (
|
||||
|
||||
@@ -1,54 +1,53 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { hasEnoughMoney, reachedLimit, win } from "./Game";
|
||||
import { BadRNG } from "./RNG";
|
||||
import { win, reachedLimit } from "./Game";
|
||||
import { trusted } from "./utils";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Button from "@mui/material/Button";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { BetInput } from "./BetInput";
|
||||
|
||||
const minPlay = 0;
|
||||
const maxPlay = 10e3;
|
||||
const initialBet = 1000;
|
||||
const maxBet = 10e3;
|
||||
|
||||
enum CoinFlipResult {
|
||||
Head = "Head",
|
||||
Tail = "Tail",
|
||||
}
|
||||
|
||||
export function CoinFlip(): React.ReactElement {
|
||||
const [investment, setInvestment] = useState(1000);
|
||||
const [result, setResult] = useState(<span> </span>);
|
||||
const [investment, setInvestment] = useState(initialBet);
|
||||
const [result, setResult] = useState(<span></span>);
|
||||
const [status, setStatus] = useState("");
|
||||
const [playLock, setPlayLock] = useState(false);
|
||||
|
||||
function updateInvestment(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||
let investment: number = parseInt(e.currentTarget.value);
|
||||
if (isNaN(investment)) {
|
||||
investment = minPlay;
|
||||
function play(guess: CoinFlipResult): void {
|
||||
if (reachedLimit() || !hasEnoughMoney(investment)) {
|
||||
return;
|
||||
}
|
||||
if (investment > maxPlay) {
|
||||
investment = maxPlay;
|
||||
}
|
||||
if (investment < minPlay) {
|
||||
investment = minPlay;
|
||||
}
|
||||
setInvestment(investment);
|
||||
}
|
||||
|
||||
function play(guess: string): void {
|
||||
if (reachedLimit()) return;
|
||||
const v = BadRNG.random();
|
||||
let letter: string;
|
||||
let letter: CoinFlipResult;
|
||||
if (v < 0.5) {
|
||||
letter = "H";
|
||||
letter = CoinFlipResult.Head;
|
||||
} else {
|
||||
letter = "T";
|
||||
letter = CoinFlipResult.Tail;
|
||||
}
|
||||
const correct: boolean = guess === letter;
|
||||
const correct = guess === letter;
|
||||
|
||||
setResult(
|
||||
<Box display="flex">
|
||||
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }} color={correct ? "primary" : "error"}>
|
||||
<div>
|
||||
<Typography component="span">Result:</Typography>
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{ lineHeight: "1em", whiteSpace: "pre" }}
|
||||
color={correct ? "primary" : "error"}
|
||||
>
|
||||
{letter}
|
||||
</Typography>
|
||||
</Box>,
|
||||
,
|
||||
</div>,
|
||||
);
|
||||
setStatus(correct ? " win!" : "lose!");
|
||||
setPlayLock(true);
|
||||
@@ -59,31 +58,30 @@ export function CoinFlip(): React.ReactElement {
|
||||
} else {
|
||||
win(-investment);
|
||||
}
|
||||
if (reachedLimit()) return;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography>Result:</Typography> {result}
|
||||
<Box display="flex" alignItems="center">
|
||||
<TextField
|
||||
type="number"
|
||||
onChange={updateInvestment}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<>
|
||||
<Button onClick={trusted(() => play("H"))} disabled={playLock}>
|
||||
Head!
|
||||
</Button>
|
||||
<Button onClick={trusted(() => play("T"))} disabled={playLock}>
|
||||
Tail!
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
<Box>
|
||||
<BetInput
|
||||
initialBet={initialBet}
|
||||
maxBet={maxBet}
|
||||
gameInProgress={playLock}
|
||||
setBet={(bet) => {
|
||||
setInvestment(bet);
|
||||
}}
|
||||
/>
|
||||
<Box>
|
||||
<Button onClick={trusted(() => play(CoinFlipResult.Head))} disabled={playLock}>
|
||||
Head!
|
||||
</Button>
|
||||
<Button onClick={trusted(() => play(CoinFlipResult.Tail))} disabled={playLock}>
|
||||
Tail!
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<Typography variant="h3">{status}</Typography>
|
||||
{result}
|
||||
<Typography variant="h4">{status}</Typography>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,3 +17,11 @@ export function reachedLimit(): boolean {
|
||||
}
|
||||
return reached;
|
||||
}
|
||||
|
||||
export function hasEnoughMoney(bet: number): boolean {
|
||||
const result = Player.canAfford(bet);
|
||||
if (!result) {
|
||||
dialogBoxCreate("You do not have enough money.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import Button from "@mui/material/Button";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { Money } from "../ui/React/Money";
|
||||
import { win, reachedLimit } from "./Game";
|
||||
import { BetInput } from "./BetInput";
|
||||
import { hasEnoughMoney, reachedLimit, win } from "./Game";
|
||||
import { WHRNG } from "./RNG";
|
||||
import { trusted } from "./utils";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import TextField from "@mui/material/TextField";
|
||||
|
||||
const minPlay = 0;
|
||||
const maxPlay = 1e7;
|
||||
const initialBet = 1000;
|
||||
const maxBet = 1e7;
|
||||
|
||||
function isRed(n: number): boolean {
|
||||
return [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36].includes(n);
|
||||
@@ -108,7 +108,7 @@ function Single(s: number): Strategy {
|
||||
|
||||
export function Roulette(): React.ReactElement {
|
||||
const [rng] = useState(new WHRNG(new Date().getTime()));
|
||||
const [investment, setInvestment] = useState(1000);
|
||||
const [investment, setInvestment] = useState(initialBet);
|
||||
const [canPlay, setCanPlay] = useState(true);
|
||||
const [status, setStatus] = useState<string | JSX.Element>("waiting");
|
||||
const [n, setN] = useState(0);
|
||||
@@ -125,20 +125,6 @@ export function Roulette(): React.ReactElement {
|
||||
}
|
||||
}
|
||||
|
||||
function updateInvestment(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||
let investment: number = parseInt(e.currentTarget.value);
|
||||
if (isNaN(investment)) {
|
||||
investment = minPlay;
|
||||
}
|
||||
if (investment > maxPlay) {
|
||||
investment = maxPlay;
|
||||
}
|
||||
if (investment < minPlay) {
|
||||
investment = minPlay;
|
||||
}
|
||||
setInvestment(investment);
|
||||
}
|
||||
|
||||
function currentNumber(): string {
|
||||
if (n === 0) return "0";
|
||||
const color = isRed(n) ? "R" : "B";
|
||||
@@ -146,7 +132,9 @@ export function Roulette(): React.ReactElement {
|
||||
}
|
||||
|
||||
function play(strategy: Strategy): void {
|
||||
if (reachedLimit()) return;
|
||||
if (reachedLimit() || !hasEnoughMoney(investment)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setCanPlay(false);
|
||||
setLock(false);
|
||||
@@ -185,15 +173,20 @@ export function Roulette(): React.ReactElement {
|
||||
setLock(true);
|
||||
setStatus(status);
|
||||
setN(n);
|
||||
|
||||
reachedLimit();
|
||||
}, 1600);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4">{currentNumber()}</Typography>
|
||||
<TextField type="number" onChange={updateInvestment} placeholder={"Amount to play"} disabled={!canPlay} />
|
||||
<BetInput
|
||||
initialBet={initialBet}
|
||||
maxBet={maxBet}
|
||||
gameInProgress={!canPlay}
|
||||
setBet={(bet) => {
|
||||
setInvestment(bet);
|
||||
}}
|
||||
/>
|
||||
<Typography variant="h4">{status}</Typography>
|
||||
<table>
|
||||
<tbody>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import Button from "@mui/material/Button";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { Player } from "@player";
|
||||
import { Money } from "../ui/React/Money";
|
||||
import { BetInput } from "./BetInput";
|
||||
import { hasEnoughMoney, reachedLimit, win } from "./Game";
|
||||
import { WHRNG } from "./RNG";
|
||||
import { win, reachedLimit } from "./Game";
|
||||
import { trusted } from "./utils";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Button from "@mui/material/Button";
|
||||
|
||||
// statically shuffled array of symbols.
|
||||
const symbols = [
|
||||
@@ -134,14 +134,14 @@ const payLines = [
|
||||
],
|
||||
];
|
||||
|
||||
const minPlay = 0;
|
||||
const maxPlay = 1e6;
|
||||
const initialBet = 1000;
|
||||
const maxBet = 1e6;
|
||||
|
||||
export function SlotMachine(): React.ReactElement {
|
||||
const [rng] = useState(new WHRNG(Player.totalPlaytime));
|
||||
const [index, setIndex] = useState<number[]>([0, 0, 0, 0, 0]);
|
||||
const [locks, setLocks] = useState<number[]>([0, 0, 0, 0, 0]);
|
||||
const [investment, setInvestment] = useState(1000);
|
||||
const [investment, setInvestment] = useState(initialBet);
|
||||
const [canPlay, setCanPlay] = useState(true);
|
||||
const [status, setStatus] = useState<string | JSX.Element>("waiting");
|
||||
|
||||
@@ -187,7 +187,9 @@ export function SlotMachine(): React.ReactElement {
|
||||
}
|
||||
|
||||
function play(): void {
|
||||
if (reachedLimit()) return;
|
||||
if (reachedLimit() || !hasEnoughMoney(investment)) {
|
||||
return;
|
||||
}
|
||||
setStatus("playing");
|
||||
win(-investment);
|
||||
if (!canPlay) return;
|
||||
@@ -240,7 +242,6 @@ export function SlotMachine(): React.ReactElement {
|
||||
</>,
|
||||
);
|
||||
setCanPlay(true);
|
||||
if (reachedLimit()) return;
|
||||
}
|
||||
|
||||
function unlock(): void {
|
||||
@@ -248,20 +249,6 @@ export function SlotMachine(): React.ReactElement {
|
||||
setCanPlay(false);
|
||||
}
|
||||
|
||||
function updateInvestment(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||
let investment: number = parseInt(e.currentTarget.value);
|
||||
if (isNaN(investment)) {
|
||||
investment = minPlay;
|
||||
}
|
||||
if (investment > maxPlay) {
|
||||
investment = maxPlay;
|
||||
}
|
||||
if (investment < minPlay) {
|
||||
investment = minPlay;
|
||||
}
|
||||
setInvestment(investment);
|
||||
}
|
||||
|
||||
const t = getTable(index, symbols);
|
||||
// prettier-ignore
|
||||
return (
|
||||
@@ -273,16 +260,19 @@ export function SlotMachine(): React.ReactElement {
|
||||
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>| | | | | | | |</Typography>
|
||||
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>| | {symbols[(index[0]+1)%symbols.length]} | {symbols[(index[1]+1)%symbols.length]} | {symbols[(index[2]+1)%symbols.length]} | {symbols[(index[3]+1)%symbols.length]} | {symbols[(index[4]+1)%symbols.length]} | |</Typography>
|
||||
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>+———————————————————————+</Typography>
|
||||
<TextField
|
||||
type="number"
|
||||
onChange={updateInvestment}
|
||||
placeholder={"Amount to play"}
|
||||
disabled={!canPlay}
|
||||
InputProps={{endAdornment:(<Button
|
||||
onClick={trusted(play)}
|
||||
disabled={!canPlay}
|
||||
>Spin!</Button>)}}
|
||||
<BetInput
|
||||
initialBet={initialBet}
|
||||
maxBet={maxBet}
|
||||
gameInProgress={!canPlay}
|
||||
setBet={(bet) => {
|
||||
setInvestment(bet);
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<Button onClick={trusted(play)} disabled={!canPlay}>
|
||||
Spin!
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Typography variant="h4">{status}</Typography>
|
||||
<Typography>Pay lines</Typography>
|
||||
|
||||
Reference in New Issue
Block a user