add hint to doudizhu demo; add citation info

This commit is contained in:
Songyi Huang 2021-05-24 19:25:32 -07:00
parent 8381c01d38
commit 076ead97f2
3 changed files with 84 additions and 3 deletions

View File

@ -24,3 +24,26 @@ code {
.el-message { .el-message {
z-index: 9999; z-index: 9999;
} }
.citation {
margin-top: 20px;
padding: 5px;
-webkit-user-select: text;
-ms-user-select: text;
user-select: text;
a {
&:visited {
color: blue;
}
}
pre {
padding: 10px;
border-radius: 5px;
color: #212529;
background-color: rgb(255, 255, 255);
border: solid 1px #e9e9e9;
}
}

View File

@ -224,6 +224,18 @@ class DoudizhuGameBoard extends React.Component {
> >
Deselect Deselect
</Button> </Button>
<Button
disabled={this.props.isHintDisabled}
onClick={(e) => {
e.stopPropagation();
this.props.handleMainPlayerAct('hint');
}}
style={{ marginRight: '2em' }}
variant="contained"
color="primary"
>
Hint
</Button>
<Button <Button
disabled={this.props.isPassDisabled} disabled={this.props.isPassDisabled}
onClick={(e) => { onClick={(e) => {

View File

@ -59,6 +59,7 @@ let playedCardsLandlord = [];
let playedCardsLandlordDown = []; let playedCardsLandlordDown = [];
let playedCardsLandlordUp = []; let playedCardsLandlordUp = [];
let legalActions = { turn: -1, actions: [] }; let legalActions = { turn: -1, actions: [] };
let hintIdx = -1;
let gameEndDialogTitle = ''; let gameEndDialogTitle = '';
let statisticRows = []; let statisticRows = [];
let syncGameStatus = 'ready'; let syncGameStatus = 'ready';
@ -77,6 +78,7 @@ function PvEDoudizhuDemoView() {
}); });
const [selectedCards, setSelectedCards] = useState([]); // user selected hand card const [selectedCards, setSelectedCards] = useState([]); // user selected hand card
const [isPassDisabled, setIsPassDisabled] = useState(true); const [isPassDisabled, setIsPassDisabled] = useState(true);
const [isHintDisabled, setIsHintDisabled] = useState(true);
const [predictionRes, setPredictionRes] = useState({ prediction: [], hands: [] }); const [predictionRes, setPredictionRes] = useState({ prediction: [], hands: [] });
const [hideRivalHand, setHideRivalHand] = useState(true); const [hideRivalHand, setHideRivalHand] = useState(true);
const [hidePredictionArea, setHidePredictionArea] = useState(true); const [hidePredictionArea, setHidePredictionArea] = useState(true);
@ -117,6 +119,7 @@ function PvEDoudizhuDemoView() {
// if next player is user, get legal actions // if next player is user, get legal actions
if ((gameState.currentPlayer + 1) % 3 === mainPlayerId) { if ((gameState.currentPlayer + 1) % 3 === mainPlayerId) {
hintIdx = -1;
const player_hand_cards = cardArr2DouzeroFormat(gameState.hands[mainPlayerId].slice().reverse()); const player_hand_cards = cardArr2DouzeroFormat(gameState.hands[mainPlayerId].slice().reverse());
let rival_move = ''; let rival_move = '';
if (playingCard.length === 0) { if (playingCard.length === 0) {
@ -134,7 +137,7 @@ function PvEDoudizhuDemoView() {
turn: gameState.turn + 1, turn: gameState.turn + 1,
actions: data.legal_action.split(','), actions: data.legal_action.split(','),
}; };
setIsHintDisabled(data.legal_action === '');
setIsPassDisabled(playingCard.length === 0 && gameHistory[gameHistory.length - 1].length === 0); setIsPassDisabled(playingCard.length === 0 && gameHistory[gameHistory.length - 1].length === 0);
} }
@ -561,6 +564,7 @@ function PvEDoudizhuDemoView() {
setConsiderationTime(initConsiderationTime); setConsiderationTime(initConsiderationTime);
setToggleFade(''); setToggleFade('');
setIsPassDisabled(true); setIsPassDisabled(true);
setIsHintDisabled(true);
setGameState({ setGameState({
hands: [[], [], []], hands: [[], [], []],
latestAction: [[], [], []], latestAction: [[], [], []],
@ -598,6 +602,7 @@ function PvEDoudizhuDemoView() {
turn: 0, turn: 0,
actions: data.legal_action.split(','), actions: data.legal_action.split(','),
}; };
setIsHintDisabled(data.legal_action === '');
} }
setGameState(newGameState); setGameState(newGameState);
@ -658,6 +663,33 @@ function PvEDoudizhuDemoView() {
setSelectedCards([]); setSelectedCards([]);
break; break;
} }
case 'hint': {
if (gameState.turn === legalActions.turn) {
setSelectedCards([]);
hintIdx++;
if (hintIdx >= legalActions.actions.length) {
hintIdx = 0;
}
const hintRanks = legalActions.actions[hintIdx].split('');
let hintCards = [];
gameState.hands[gameState.currentPlayer].forEach((card) => {
const { rank } = card2SuiteAndRank(card);
const idx = hintRanks.indexOf(rank);
if (idx >= 0) {
hintRanks.splice(idx, 1);
hintCards.push(card);
}
});
setSelectedCards(hintCards);
} else {
Message({
message: 'Legal Action not received or turn info inconsistant',
type: 'error',
showClose: true,
});
}
break;
}
} }
}; };
@ -827,7 +859,7 @@ function PvEDoudizhuDemoView() {
</TableHead> </TableHead>
<TableBody> <TableBody>
{statisticRows.map((row) => ( {statisticRows.map((row) => (
<TableRow key={row.name}> <TableRow key={'statistic-row-' + row.role}>
<TableCell component="th" scope="row"> <TableCell component="th" scope="row">
{row.role} {row.role}
</TableCell> </TableCell>
@ -866,9 +898,10 @@ function PvEDoudizhuDemoView() {
<div style={{ height: '100%' }}> <div style={{ height: '100%' }}>
<Paper className={'doudizhu-gameboard-paper'} elevation={3}> <Paper className={'doudizhu-gameboard-paper'} elevation={3}>
<DoudizhuGameBoard <DoudizhuGameBoard
showCardBack={hideRivalHand} showCardBack={gameStatus === 'playing' && hideRivalHand}
handleSelectRole={handleSelectRole} handleSelectRole={handleSelectRole}
isPassDisabled={isPassDisabled} isPassDisabled={isPassDisabled}
isHintDisabled={isHintDisabled}
gamePlayable={true} gamePlayable={true}
playerInfo={playerInfo} playerInfo={playerInfo}
hands={gameState.hands} hands={gameState.hands}
@ -1001,6 +1034,19 @@ function PvEDoudizhuDemoView() {
</Layout.Row> </Layout.Row>
</Paper> </Paper>
</div> </div>
<div className="citation">
This demo is based on <a href="https://github.com/datamllab/rlcard">RLCard</a> and{' '}
<a href="https://github.com/daochenzha/douzero">DouZero</a>. If you find these projects useful,
please cite:
<pre>
{`@article{zha2019rlcard,
title={RLCard: A Toolkit for Reinforcement Learning in Card Games},
author={Zha, Daochen and Lai, Kwei-Herng and Cao, Yuanpu and Huang, Songyi and Wei, Ruzhe and Guo, Junyu and Hu, Xia},
journal={arXiv preprint arXiv:1910.04376},
year={2019}
}`}
</pre>
</div>
</div> </div>
</div> </div>
); );