changed style for leduc
|
@ -8,7 +8,6 @@
|
|||
margin-right: auto;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
|
||||
.stretch {
|
||||
flex: 1;
|
||||
}
|
||||
|
|
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 7.8 KiB |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 ?
|
||||
<div>
|
||||
<img src={Player1} alt={"Player 1"} height="70%" width="70%" />
|
||||
<Chip
|
||||
avatar={<Avatar>ID</Avatar>}
|
||||
label={playerId}
|
||||
clickable
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
<div>
|
||||
<img src={Player2} alt={"Player 2"} height="70%" width="70%" />
|
||||
<Chip
|
||||
avatar={<Avatar>ID</Avatar>}
|
||||
label={playerId}
|
||||
clickable
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
}else
|
||||
return (
|
||||
<div>
|
||||
<img src={PlaceHolderPlayer} alt={"Player"} height="70%" width="70%" />
|
||||
<Chip
|
||||
avatar={<Avatar>ID</Avatar>}
|
||||
label={playerId}
|
||||
clickable
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
computeActionImage(action) {
|
||||
if (action.length > 0) {
|
||||
return <img src={require('../../assets/images/Actions/' + action + '.png')} alt={action} height="80%" width="100%" />
|
||||
}
|
||||
}
|
||||
|
||||
computeHand(card) {
|
||||
const [rankClass, suitClass, rankText, suitText] = translateCardData(card);
|
||||
return (
|
||||
<div className="playingCards faceImages">
|
||||
<div className={`card ${rankClass} ${suitClass}`}>
|
||||
<div className="playingCards faceImages unselectable">
|
||||
<div className={`card ${rankClass} full-content ${suitClass}`}>
|
||||
<span className="rank">{rankText}</span>
|
||||
<span className="suit">{suitText}</span>
|
||||
</div>
|
||||
|
@ -22,9 +70,13 @@ class LeducHoldemGameBoard extends React.Component {
|
|||
|
||||
playerDecisionArea(playerIdx){
|
||||
if(this.props.currentPlayer === playerIdx){
|
||||
return <div className="non-card"><span>{`Consideration Time: ${millisecond2Second(this.props.considerationTime)}s`}</span></div>
|
||||
return (
|
||||
<div className={"timer"}>
|
||||
<div className="timer-text">{millisecond2Second(this.props.considerationTime)}</div>
|
||||
</div>
|
||||
)
|
||||
}else{
|
||||
return <div className="non-card"><span>{this.props.latestAction[playerIdx]}</span></div>
|
||||
return <div className="non-card">{this.computeActionImage(this.props.latestAction[playerIdx])}</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +91,7 @@ class LeducHoldemGameBoard extends React.Component {
|
|||
const [rankClass, suitClass, rankText, suitText] = translateCardData(this.props.publicCard);
|
||||
return (
|
||||
<div className="playingCards faceImages">
|
||||
<div className={`card ${rankClass} ${suitClass}`}>
|
||||
<div className={`card ${rankClass} full-content ${suitClass}`}>
|
||||
<span className="rank">{rankText}</span>
|
||||
<span className="suit">{suitText}</span>
|
||||
</div>
|
||||
|
@ -65,14 +117,15 @@ class LeducHoldemGameBoard extends React.Component {
|
|||
topId = found.id;
|
||||
}
|
||||
return (
|
||||
<div className="leduc-holdem-wrapper" style={{width: "100%", height: "100%", backgroundColor: "#ffcc99", position: "relative"}}>
|
||||
<div className="leduc-holdem-wrapper">
|
||||
<div id={"bottom-player"}>
|
||||
<div className="played-card-area">
|
||||
{bottomIdx >= 0 ? this.playerDecisionArea(bottomIdx) : ""}
|
||||
</div>
|
||||
<div className="player-main-area">
|
||||
<div className="player-info">
|
||||
<span>{`Player Id: ${bottomId}\nBet: ${this.props.pot[bottomIdx]}`}</span>
|
||||
{this.computePlayerPortrait(bottomId, bottomIdx)}
|
||||
<span>{`Bet: ${this.props.pot[bottomIdx]}`}</span>
|
||||
</div>
|
||||
{bottomIdx >= 0 ? <div className="player-hand">{this.computeHand(this.props.hands[bottomIdx])}</div> : <div className="player-hand-placeholder"><span>Waiting...</span></div>}
|
||||
</div>
|
||||
|
@ -80,7 +133,8 @@ class LeducHoldemGameBoard extends React.Component {
|
|||
<div id={"top-player"}>
|
||||
<div className="player-main-area">
|
||||
<div className="player-info">
|
||||
<span>{`Player Id: ${topId}\nBet: ${this.props.pot[topIdx]}`}</span>
|
||||
{this.computePlayerPortrait(topId, topIdx)}
|
||||
<span>{`Bet: ${this.props.pot[topIdx]}`}</span>
|
||||
</div>
|
||||
{topIdx >= 0 ? <div className="player-hand">{this.computeHand(this.props.hands[topIdx])}</div> : <div className="player-hand-placeholder"><span>Waiting...</span></div>}
|
||||
</div>
|
||||
|
|
|
@ -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 (
|
||||
<div className={"playing"} style={style}>
|
||||
<div className="probability-move">
|
||||
{currentMove !== null ? currentMove.probabilities[idx].move : <NotInterestedIcon fontSize="large" />}
|
||||
{currentMove !== null ?
|
||||
<img src={require('../assets/images/Actions/' + currentMove.probabilities[idx].move + '.png')} alt={currentMove.probabilities[idx].move} height="30%" width="30%" />
|
||||
:
|
||||
<NotInterestedIcon fontSize="large" />}
|
||||
</div>
|
||||
{currentMove !== null ?
|
||||
(<div className={"non-card"}>
|
||||
|
@ -316,6 +338,8 @@ class LeducHoldemGameView extends React.Component {
|
|||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Navbar gameName="Leduc Hold'em" />
|
||||
<div className={"leduc-view-container"}>
|
||||
<Layout.Row style={{"height": "540px"}}>
|
||||
<Layout.Col style={{"height": "100%"}} span="17">
|
||||
|
@ -367,6 +391,7 @@ class LeducHoldemGameView extends React.Component {
|
|||
<div className="progress-bar">
|
||||
<LinearProgress variant="determinate" value={this.state.gameInfo.completedPercent} />
|
||||
</div>
|
||||
<Loading loading={this.state.fullScreenLoading}>
|
||||
<div className="game-controller">
|
||||
<Paper className={"game-controller-paper"} elevation={3}>
|
||||
<Layout.Row style={{"height": "51px"}}>
|
||||
|
@ -422,6 +447,8 @@ class LeducHoldemGameView extends React.Component {
|
|||
</Layout.Row>
|
||||
</Paper>
|
||||
</div>
|
||||
</Loading>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|