check if the game ends

This commit is contained in:
songyih 2020-01-16 22:00:38 -08:00
parent cb4fa7b2b7
commit 691ab7b120
22 changed files with 201 additions and 15 deletions

View File

@ -0,0 +1,150 @@
{
"initHands": [
"S2 H2 HK DK HQ CQ DQ CJ S9 H9 D9 C7 S6 H6 C4 D4 S3",
"C2 HA CA DA SQ ST HT D8 S7 H7 C6 D6 S5 H5 C5 S4 H4",
"RJ BJ D2 SA SK CK SJ HJ DJ CT DT C9 S8 H8 C8 D7 D5 H3 S3 D3"
],
"playerInfo": [
{
"id": 0,
"index": 0,
"role": "peasant"
},
{
"id": 1,
"index": 1,
"role": "peasant"
},
{
"id": 2,
"index": 2,
"role": "landlord"
}
],
"moveHistory": [
{
"playerIdx": 2,
"move": "H3 S3 D3 D5"
},
{
"playerIdx": 0,
"move": "S9 H9 D9 S3"
},
{
"playerIdx": 1,
"move": "P"
},
{
"playerIdx": 2,
"move": "SJ HJ DJ D7"
},
{
"playerIdx": 0,
"move": "HQ CQ DQ C7"
},
{
"playerIdx": 1,
"move": "P"
},
{
"playerIdx": 2,
"move": "P"
},
{
"playerIdx": 0,
"move": "C4 D4"
},
{
"playerIdx": 1,
"move": "ST HT"
},
{
"playerIdx": 2,
"move": "SK CK"
},
{
"playerIdx": 0,
"move": "S2 H2"
},
{
"playerIdx": 1,
"move": "P"
},
{
"playerIdx": 2,
"move": "P"
},
{
"playerIdx": 0,
"move": "S6 H6"
},
{
"playerIdx": 1,
"move": "P"
},
{
"playerIdx": 2,
"move": "CT DT"
},
{
"playerIdx": 0,
"move": "HK DK"
},
{
"playerIdx": 1,
"move": "P"
},
{
"playerIdx": 2,
"move": "RJ BJ"
},
{
"playerIdx": 0,
"move": "P"
},
{
"playerIdx": 1,
"move": "P"
},
{
"playerIdx": 2,
"move": "S8 H8 C8 C9"
},
{
"playerIdx": 0,
"move": "P"
},
{
"playerIdx": 1,
"move": "HA CA DA H5"
},
{
"playerIdx": 2,
"move": "P"
},
{
"playerIdx": 0,
"move": "P"
},
{
"playerIdx": 1,
"move": "SQ"
},
{
"playerIdx": 2,
"move": "D2"
},
{
"playerIdx": 0,
"move": "P"
},
{
"playerIdx": 1,
"move": "P"
},
{
"playerIdx": 2,
"move": "SA"
}
]
}

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -1,6 +1,6 @@
import React from 'react';
import './index.scss';
import '../../assets/doudizhu.scss';
class DoudizhuGameBoard extends React.Component {
constructor(props) {
@ -15,9 +15,9 @@ class DoudizhuGameBoard extends React.Component {
}
translateCardData(card) {
let rankClass = "";
let rankClass;
let suitClass = "";
let rankText = "";
let rankText;
let suitText = "";
// translate rank
if(card === "RJ"){
@ -51,7 +51,6 @@ class DoudizhuGameBoard extends React.Component {
}
computeSingleLineHand(cards) {
console.log(cards);
if(cards === "P"){
return <div className="non-card"><span>Pass</span></div>
}else{
@ -68,7 +67,7 @@ class DoudizhuGameBoard extends React.Component {
}
computeSideHand(cards) {
let upCards = [];
let upCards;
let downCards = [];
if(cards.length > 10){
upCards = cards.slice(0, 10);
@ -107,7 +106,6 @@ class DoudizhuGameBoard extends React.Component {
}
playerDecisionArea(playerIdx){
console.log(this.props.currentPlayer, playerIdx);
if(this.props.currentPlayer === playerIdx){
return <div className="non-card"><span>{`Consideration Time: ${this.millisecond2Second(this.props.considerationTime)}s`}</span></div>
}else{
@ -115,6 +113,13 @@ class DoudizhuGameBoard extends React.Component {
}
}
componentDidUpdate(prevProps, prevState, snapshot) {
if(prevProps.turn !== this.props.turn){
// new turn starts
this.props.runNewTurn(prevProps);
}
}
render() {
// compute the id as well as index in list for every player
const bottomId = this.props.mainPlayerId;
@ -140,7 +145,6 @@ class DoudizhuGameBoard extends React.Component {
}
return (
<div style={{width: "100%", height: "100%", backgroundColor: "#ffcc99", position: "relative"}}>
<div>{`Current Player: ${this.props.currentPlayer} , Consideration Time: ${this.props.considerationTime}`}</div>
<div id={"left-player"}>
<div className="player-main-area">
<div className="player-info">

View File

@ -1,6 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import './assets/index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

View File

@ -19,3 +19,10 @@ export function removeCards(cards, hands){ // remove cards from hands, retur
return remainedHands;
}
export function doubleRaf (callback) {
// secure all the animation got rendered before callback function gets executed
requestAnimationFrame(() => {
requestAnimationFrame(callback)
})
}

View File

@ -1,15 +1,15 @@
import React from 'react';
import DoudizhuGameBoard from '../components/GameBoard';
import webSocket from "socket.io-client";
import {removeCards} from "../utils";
import {removeCards, doubleRaf} from "../utils";
class DoudizhuGameView extends React.Component {
constructor(props) {
super(props);
const mainViewerId = 0; // Id of the player at the bottom of screen
this.initConsiderationTime = 2000;
this.considerationTimeDeduction = 1000;
this.initConsiderationTime = 0;
this.considerationTimeDeduction = 100;
this.gameStateTimeout = null;
this.initGameState = {
@ -20,7 +20,7 @@ class DoudizhuGameView extends React.Component {
turn: 0,
currentPlayer: null,
considerationTime: this.initConsiderationTime,
}
};
this.state = {
ws: null,
@ -86,7 +86,6 @@ class DoudizhuGameView extends React.Component {
break;
case 1:
// getting player actions
console.log(message.message);
let res = message.message;
if(res.turn === this.state.gameInfo.turn && res.playerIdx === this.state.gameInfo.currentPlayer){
let gameInfo = JSON.parse(JSON.stringify(this.state.gameInfo));
@ -101,8 +100,9 @@ class DoudizhuGameView extends React.Component {
console.log("Cannot find cards in move from player's hand");
}
gameInfo.considerationTime = this.initConsiderationTime;
this.setState({gameInfo: gameInfo});
this.gameStateTimer();
this.setState({gameInfo: gameInfo}, ()=>{
});
}else{
console.log("Mismatched game turn or current player index", message);
}
@ -116,6 +116,26 @@ class DoudizhuGameView extends React.Component {
this.setState({ws: ws});
};
runNewTurn(prevTurn){
// check if the game ends
if(this.state.gameInfo.hands[prevTurn.currentPlayer].length === 0){
doubleRaf(()=>{
const winner = this.state.gameInfo.playerInfo.find(element => {
return element.index === prevTurn.currentPlayer;
});
if(winner){
if(winner.role === "landlord")
alert("Landlord Wins");
else
alert("Peasants Win");
}else{
console.log("Error in finding winner");
}
});
}else
this.gameStateTimer();
}
render(){
return (
<div>
@ -127,12 +147,17 @@ class DoudizhuGameView extends React.Component {
mainPlayerId={this.state.gameInfo.mainViewerId}
currentPlayer={this.state.gameInfo.currentPlayer}
considerationTime={this.state.gameInfo.considerationTime}
turn={this.state.gameInfo.turn}
runNewTurn={(prevTurn)=>this.runNewTurn(prevTurn)}
/>
</div>
<div style={{marginTop: "10px"}}>
<input type='button' value='Connect' onClick={()=>{this.connectWebSocket()}} />
<input style={{marginLeft: "10px"}} type='button' value='Start Replay' onClick={()=>{this.startReplay()}} />
</div>
<div style={{marginTop: "10px"}}>
{`Current Player: ${this.state.gameInfo.currentPlayer} , Consideration Time: ${this.state.gameInfo.considerationTime}, Turn: ${this.state.gameInfo.turn}`}
</div>
</div>
)
}