diff --git a/src/assets/gameview.scss b/src/assets/gameview.scss index 2f389cc..593e761 100644 --- a/src/assets/gameview.scss +++ b/src/assets/gameview.scss @@ -8,7 +8,6 @@ margin-right: auto; padding: 5px; display: flex; - .stretch { flex: 1; } diff --git a/src/assets/images/Actions/Call.png b/src/assets/images/Actions/Call.png new file mode 100644 index 0000000..20c006e Binary files /dev/null and b/src/assets/images/Actions/Call.png differ diff --git a/src/assets/images/Actions/Check.png b/src/assets/images/Actions/Check.png new file mode 100644 index 0000000..a8a33e1 Binary files /dev/null and b/src/assets/images/Actions/Check.png differ diff --git a/src/assets/images/Actions/Fold.png b/src/assets/images/Actions/Fold.png new file mode 100644 index 0000000..04aeab6 Binary files /dev/null and b/src/assets/images/Actions/Fold.png differ diff --git a/src/assets/images/Actions/Raise.png b/src/assets/images/Actions/Raise.png new file mode 100644 index 0000000..d158211 Binary files /dev/null and b/src/assets/images/Actions/Raise.png differ diff --git a/src/assets/images/Tokens/Token_Black_100.png b/src/assets/images/Tokens/Token_Black_100.png new file mode 100644 index 0000000..c32c414 Binary files /dev/null and b/src/assets/images/Tokens/Token_Black_100.png differ diff --git a/src/assets/images/Tokens/Token_Blue_10.png b/src/assets/images/Tokens/Token_Blue_10.png new file mode 100644 index 0000000..6e0b617 Binary files /dev/null and b/src/assets/images/Tokens/Token_Blue_10.png differ diff --git a/src/assets/images/Tokens/Token_Green_25.png b/src/assets/images/Tokens/Token_Green_25.png new file mode 100644 index 0000000..068f94c Binary files /dev/null and b/src/assets/images/Tokens/Token_Green_25.png differ diff --git a/src/assets/images/Tokens/Token_Red_5.png b/src/assets/images/Tokens/Token_Red_5.png new file mode 100644 index 0000000..6a22bec Binary files /dev/null and b/src/assets/images/Tokens/Token_Red_5.png differ diff --git a/src/assets/images/Tokens/Token_White_1.png b/src/assets/images/Tokens/Token_White_1.png new file mode 100644 index 0000000..fbfd15e Binary files /dev/null and b/src/assets/images/Tokens/Token_White_1.png differ diff --git a/src/assets/leducholdem.scss b/src/assets/leducholdem.scss index 3213d32..767ff96 100644 --- a/src/assets/leducholdem.scss +++ b/src/assets/leducholdem.scss @@ -1,5 +1,13 @@ @import "cards.css"; .leduc-holdem-wrapper { + width: 100%; + height: 100%; + background-color: #C3CDFF; + // background-image: url("./images/table.png"); + // background-repeat: no-repeat; + // background-size: 100% 70%; + // background-position: bottom; + position: relative; .played-card-area { font-size: 12px; @@ -8,17 +16,41 @@ display: flex; justify-content: center; + .timer.fade-in { + visibility: hidden; + opacity: 0; + } + + .timer.fade-out { + visibility: hidden; + transition: visibility 0.1s, opacity 0.05s; + opacity: 0; + } + + .timer { + visibility: visible; + transition: visibility 0s, opacity 0.2s, transform 0.3s; + opacity: 1; + width: 51px; + height: 60px; + .timer-text { + color: #303133; + margin-top: 3px; + font-size: 23px; + font-weight: bold; + text-shadow: 0 2px 2px #909399; + line-height: 57px; + } + text-align: center; + background-image: url("./images/timer.png"); + background-repeat: no-repeat; + background-size: 100% 100%; + } + .non-card { display: table; - width: 280px; - height: 100px; - - span { - display: table-cell; - vertical-align: middle; - text-align: center; - font-size: 16px; - } + width: 80px; + height: 40px; } } @@ -37,14 +69,11 @@ font-size: 16px; width: 130px; height: 130px; - border-radius: 25px; - border: 2px solid #73AD21; - display: table; - + div { + text-align: center; + } span { white-space: pre; - display: table-cell; - vertical-align: middle; text-align: center; } } @@ -96,16 +125,17 @@ margin-top: -75px; width: 130px; height: 150px; - border-radius: 25px; - border: 2px solid blue; display: table; .info-area { display: table-cell; vertical-align: middle; text-align: center; + font-size: 20px; + font-weight: bold; + text-shadow: 0 2px 2px rgba(0, 0, 0, 0.87); + color: #F2F6FC; } - .playingCards { transform: translate(3px, 10px); } diff --git a/src/components/GameBoard/LeducHoldemGameBoard.js b/src/components/GameBoard/LeducHoldemGameBoard.js index 097946e..262b8c5 100644 --- a/src/components/GameBoard/LeducHoldemGameBoard.js +++ b/src/components/GameBoard/LeducHoldemGameBoard.js @@ -2,17 +2,65 @@ import React from 'react'; import { translateCardData, millisecond2Second } from '../../utils' import '../../assets/leducholdem.scss'; +import Player1 from '../../assets/images/Portrait/Player1.png' +import Player2 from '../../assets/images/Portrait/Player2.png' +import PlaceHolderPlayer from '../../assets/images/Portrait/Player.png'; + +import Chip from '@material-ui/core/Chip'; +import Avatar from '@material-ui/core/Avatar'; class LeducHoldemGameBoard extends React.Component { constructor(props) { super(props); } + computePlayerPortrait(playerId, playerIdx){ + if(this.props.playerInfo.length > 0){ + return this.props.playerInfo[playerIdx].id === 0 ? +
+ {"Player + ID} + label={playerId} + clickable + color="primary" + /> +
+ : +
+ {"Player + ID} + label={playerId} + clickable + color="primary" + /> +
+ }else + return ( +
+ {"Player"} + ID} + label={playerId} + clickable + color="primary" + /> +
+ ) + } + + computeActionImage(action) { + if (action.length > 0) { + return {action} + } + } + computeHand(card) { const [rankClass, suitClass, rankText, suitText] = translateCardData(card); return ( -
-
+
+
{rankText} {suitText}
@@ -22,9 +70,13 @@ class LeducHoldemGameBoard extends React.Component { playerDecisionArea(playerIdx){ if(this.props.currentPlayer === playerIdx){ - return
{`Consideration Time: ${millisecond2Second(this.props.considerationTime)}s`}
+ return ( +
+
{millisecond2Second(this.props.considerationTime)}
+
+ ) }else{ - return
{this.props.latestAction[playerIdx]}
+ return
{this.computeActionImage(this.props.latestAction[playerIdx])}
} } @@ -39,7 +91,7 @@ class LeducHoldemGameBoard extends React.Component { const [rankClass, suitClass, rankText, suitText] = translateCardData(this.props.publicCard); return (
-
+
{rankText} {suitText}
@@ -65,14 +117,15 @@ class LeducHoldemGameBoard extends React.Component { topId = found.id; } return ( -
+
{bottomIdx >= 0 ? this.playerDecisionArea(bottomIdx) : ""}
- {`Player Id: ${bottomId}\nBet: ${this.props.pot[bottomIdx]}`} + {this.computePlayerPortrait(bottomId, bottomIdx)} + {`Bet: ${this.props.pot[bottomIdx]}`}
{bottomIdx >= 0 ?
{this.computeHand(this.props.hands[bottomIdx])}
:
Waiting...
}
@@ -80,7 +133,8 @@ class LeducHoldemGameBoard extends React.Component {
- {`Player Id: ${topId}\nBet: ${this.props.pot[topIdx]}`} + {this.computePlayerPortrait(topId, topIdx)} + {`Bet: ${this.props.pot[topIdx]}`}
{topIdx >= 0 ?
{this.computeHand(this.props.hands[topIdx])}
:
Waiting...
}
diff --git a/src/view/LeducHoldemGameView.js b/src/view/LeducHoldemGameView.js index 67e70ab..a833640 100644 --- a/src/view/LeducHoldemGameView.js +++ b/src/view/LeducHoldemGameView.js @@ -2,9 +2,10 @@ import React from 'react'; import axios from 'axios'; import '../assets/gameview.scss'; import {LeducHoldemGameBoard} from '../components/GameBoard'; +import Navbar from '../components/Navbar'; import {deepCopy} from "../utils"; -import { Layout } from 'element-react'; +import { Layout, Message, Loading } from 'element-react'; import Slider from '@material-ui/core/Slider'; import Button from '@material-ui/core/Button'; import Paper from '@material-ui/core/Paper'; @@ -46,12 +47,12 @@ class LeducHoldemGameView extends React.Component { this.state = { gameInfo: this.initGameState, gameStateLoop: null, - gameSpeed: 0 + gameSpeed: 0, + fullScreenLoading: false } } generateNewState(){ - // console.log(this.state.gameInfo.latestAction); let gameInfo = deepCopy(this.state.gameInfo); const turn = this.state.gameInfo.turn; if(turn >= this.moveHistory[this.state.gameInfo.round].length){ @@ -85,7 +86,11 @@ class LeducHoldemGameView extends React.Component { if(gameInfo.pot[(gameInfo.currentPlayer+2-1)%2] > gameInfo.pot[gameInfo.currentPlayer]){ gameInfo.pot[gameInfo.currentPlayer] = gameInfo.pot[(gameInfo.currentPlayer+2-1)%2]; }else{ - console.log("Current player choose call but has bet more or equal to the upstream player"); + Message({ + message: "Current player choose call but has bet more or equal to the upstream player", + type: "error", + showClose: true + }); } break; case "Fold": @@ -101,7 +106,11 @@ class LeducHoldemGameView extends React.Component { }, 200); return gameInfo; default: - console.log("Error in player's latest action"); + Message({ + message: "Error in player's latest action", + type: "error", + showClose: true + }); } gameInfo.turn++; if(gameInfo.round !== 0 && gameInfo.turn === this.moveHistory[gameInfo.round].length){ @@ -119,14 +128,22 @@ class LeducHoldemGameView extends React.Component { gameInfo.gameStatus = "playing"; this.setState({ gameInfo: gameInfo }); }else{ - console.log("Mismatch in current player & move history"); + Message({ + message: "Mismatch in current player & move history", + type: "error", + showClose: true + }); } } // if current state is new to game state history, push it to the game state history array if(gameInfo.turn === this.gameStateHistory[gameInfo.round].length){ this.gameStateHistory[gameInfo.round].push(gameInfo); }else{ - console.log("inconsistent game state history length and turn number"); + Message({ + message: "Inconsistent game state history length and turn number", + type: "error", + showClose: true + }); } return gameInfo; } @@ -172,6 +189,8 @@ class LeducHoldemGameView extends React.Component { // for test use const replayId = 0; + // start full screen loading + this.setState({fullScreenLoading: true}); axios.get(`${this.apiUrl}/replay/leduc_holdem/${replayId}`) .then(res => { res = res.data; @@ -187,7 +206,7 @@ class LeducHoldemGameView extends React.Component { if(this.gameStateHistory.length !== 0 && this.gameStateHistory[0].length === 0){ this.gameStateHistory[gameInfo.round].push(gameInfo); } - this.setState({gameInfo: gameInfo}, ()=>{ + this.setState({gameInfo: gameInfo, fullScreenLoading: false}, ()=>{ if(this.gameStateTimeout){ window.clearTimeout(this.gameStateTimeout); this.gameStateTimeout = null; @@ -242,11 +261,14 @@ class LeducHoldemGameView extends React.Component { currentMove = this.moveHistory[this.state.gameInfo.round][this.state.gameInfo.turn]; } let style = {}; - style["backgroundColor"] = currentMove !== null ? `rgba(189,183,107,${currentMove.probabilities[idx].probability})` : "#bdbdbd"; + style["backgroundColor"] = currentMove !== null ? `rgba(130, 151, 255, ${currentMove.probabilities[idx].probability})` : "#bdbdbd"; return (
- {currentMove !== null ? currentMove.probabilities[idx].move : } + {currentMove !== null ? + {currentMove.probabilities[idx].move} + : + }
{currentMove !== null ? (
@@ -316,111 +338,116 @@ class LeducHoldemGameView extends React.Component { ]; return ( -
- - -
- - - -
-
- - -
- { - this.state.gameInfo.playerInfo.length > 0 ? - Current Player: {this.state.gameInfo.currentPlayer} - : - Waiting... - } +
+ +
+ + +
+ + +
- -
-
- {this.computeProbabilityItem(0)} + + + +
+ { + this.state.gameInfo.playerInfo.length > 0 ? + Current Player: {this.state.gameInfo.currentPlayer} + : + Waiting... + }
-
- {this.computeProbabilityItem(1)} -
-
- {this.computeProbabilityItem(2)} -
-
- {this.computeProbabilityItem(3)} -
-
- - - -
- -
-
- - - -
- - { this.gameStatusButton(this.state.gameInfo.gameStatus) } - -
-
- - - - -
{`Turn: ${this.state.gameInfo.turn}`}
-
- - - - -
- -
- {this.changeGameSpeed(newVal)}} - aria-labelledby="discrete-slider-custom" - step={1} - min={-3} - max={3} - track={false} - valueLabelDisplay="off" - marks={gameSpeedMarks} - /> + +
+
+ {this.computeProbabilityItem(0)} +
+
+ {this.computeProbabilityItem(1)} +
+
+ {this.computeProbabilityItem(2)} +
+
+ {this.computeProbabilityItem(3)}
- - - + + + +
+ +
+ +
+ + + +
+ + { this.gameStatusButton(this.state.gameInfo.gameStatus) } + +
+
+ + + + +
{`Turn: ${this.state.gameInfo.turn}`}
+
+ + + + +
+ +
+ {this.changeGameSpeed(newVal)}} + aria-labelledby="discrete-slider-custom" + step={1} + min={-3} + max={3} + track={false} + valueLabelDisplay="off" + marks={gameSpeedMarks} + /> +
+
+
+
+
+
+
);