changed agent leaderboard table columns; fixed bugs in leduc holdem game replay; load agents lists from backend api
This commit is contained in:
parent
b7b722761e
commit
379edbb4f3
|
@ -20,3 +20,7 @@ code {
|
|||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.el-message {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import ExpandLess from '@material-ui/icons/ExpandLess';
|
|||
import ExpandMore from '@material-ui/icons/ExpandMore';
|
||||
import {makeStyles} from "@material-ui/core/styles";
|
||||
import qs from 'query-string';
|
||||
import ListSubheader from "@material-ui/core/ListSubheader";
|
||||
|
||||
const drawerWidth = 250;
|
||||
|
||||
|
@ -75,13 +76,15 @@ function MenuBar (props) {
|
|||
</List>
|
||||
});
|
||||
|
||||
const agentMenu = props.modelList.map(model => {
|
||||
return <List component="div" disablePadding key={"game-menu-"+model.model}>
|
||||
<ListItem button className={classes.nested} onClick={() => {handleAgentJump(model.model)}}>
|
||||
<ListItemText primary={model.dispName} className={`${classes.menuLayer2} ${(type === 'agent' && name === model.model) ? classes.active : classes.inactive}`} />
|
||||
</ListItem>
|
||||
</List>
|
||||
});
|
||||
const generateAgentMenu = (modelList) => {
|
||||
return modelList.map((model) => {
|
||||
return <List component="div" disablePadding key={"game-menu-"+model}>
|
||||
<ListItem button className={classes.nested} onClick={() => {handleAgentJump(model)}}>
|
||||
<ListItemText primary={model} className={`${classes.menuLayer2} ${(type === 'agent' && name === model) ? classes.active : classes.inactive}`} />
|
||||
</ListItem>
|
||||
</List>
|
||||
})
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
|
@ -108,7 +111,15 @@ function MenuBar (props) {
|
|||
{open.game ? <ExpandLess /> : <ExpandMore />}
|
||||
</ListItem>
|
||||
<Collapse in={open.game} timeout="auto" unmountOnExit>
|
||||
{agentMenu}
|
||||
{Object.keys(props.modelList).map(gameName => {
|
||||
return (
|
||||
<div key={`agentMenu-sublist-${gameName}`}>
|
||||
<ListSubheader className={classes.nested}>{gameName}</ListSubheader>
|
||||
{generateAgentMenu(props.modelList[gameName])}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
</Collapse>
|
||||
</List>
|
||||
</Drawer>
|
||||
|
|
|
@ -7,7 +7,8 @@ import Navbar from '../../components/Navbar';
|
|||
import {deepCopy} from "../../utils";
|
||||
import { apiUrl } from "../../utils/config";
|
||||
|
||||
import { Layout, Message, Loading } from 'element-react';
|
||||
import { Layout, Loading } from 'element-react';
|
||||
import { Message } from 'element-react';
|
||||
import Slider from '@material-ui/core/Slider';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
|
@ -87,7 +88,7 @@ class LeducHoldemGameView extends React.Component {
|
|||
case "check":
|
||||
break;
|
||||
case "raise":
|
||||
gameInfo.pot[gameInfo.currentPlayer] += (gameInfo.round+1) * 2;
|
||||
gameInfo.pot[gameInfo.currentPlayer] = (gameInfo.pot[(gameInfo.currentPlayer+2-1)%2] + (gameInfo.round+1) * 2);
|
||||
break;
|
||||
case "call":
|
||||
// the upstream player must have bet more
|
||||
|
@ -197,12 +198,22 @@ class LeducHoldemGameView extends React.Component {
|
|||
startReplay() {
|
||||
const { name, agent0, agent1, index } = qs.parse(window.location.search);
|
||||
const requestUrl = `${apiUrl}/tournament/replay?name=${name}&agent0=${agent0}&agent1=${agent1}&index=${index}`;
|
||||
|
||||
// start full screen loading
|
||||
this.setState({fullScreenLoading: true});
|
||||
|
||||
axios.get(requestUrl)
|
||||
.then(res => {
|
||||
res = res.data;
|
||||
if (res.moveHistory.length === 0) {
|
||||
Message({
|
||||
message: "Empty move history",
|
||||
type: "error",
|
||||
showClose: true,
|
||||
duration: 0
|
||||
});
|
||||
this.setState({fullScreenLoading: false});
|
||||
return false;
|
||||
}
|
||||
// init replay info
|
||||
this.moveHistory = res.moveHistory;
|
||||
this.moveHistoryTotalLength = this.moveHistory.reduce((count, round) => count + round.length, 0) - 1;
|
||||
|
@ -211,6 +222,8 @@ class LeducHoldemGameView extends React.Component {
|
|||
gameInfo.playerInfo = res.playerInfo;
|
||||
gameInfo.hands = res.initHands;
|
||||
gameInfo.currentPlayer = res.moveHistory[0][0].playerIdx;
|
||||
// the other player is big blind, should have 2 unit in pot
|
||||
gameInfo.pot[(res.moveHistory[0][0].playerIdx + 1) % 2] = 2;
|
||||
gameInfo.publicCard = res.publicCard;
|
||||
if(this.gameStateHistory.length !== 0 && this.gameStateHistory[0].length === 0){
|
||||
this.gameStateHistory[gameInfo.round].push(gameInfo);
|
||||
|
@ -290,9 +303,12 @@ class LeducHoldemGameView extends React.Component {
|
|||
{currentMove !== null ?
|
||||
(<div className={"non-card"}>
|
||||
{
|
||||
currentMove.probabilities[idx].probability < 0 ?
|
||||
currentMove.probabilities[idx].probability === -1 ?
|
||||
<span>Illegal</span>
|
||||
:
|
||||
currentMove.probabilities[idx].probability === -2 ?
|
||||
<span>Rule Based</span>
|
||||
:
|
||||
<span>{`Probability ${(currentMove.probabilities[idx].probability * 100).toFixed(2)}%`}</span>
|
||||
}
|
||||
</div>) : ""}
|
||||
|
|
|
@ -25,13 +25,8 @@ const gameList = [
|
|||
{game: 'doudizhu', dispName: 'Dou Dizhu'},
|
||||
];
|
||||
|
||||
const modelList = [
|
||||
{model: 'leduc-holdem-random', dispName: 'Leduc Hold\'em Random'},
|
||||
{model: 'leduc-holdem-cfr', dispName: 'Leduc Hold\'em CFR'},
|
||||
{model: 'leduc-holdem-rule-v1', dispName: 'Leduc Hold\'em Rule V1'},
|
||||
{model: 'doudizhu-random', dispName: 'Dou Dizhu Random'},
|
||||
{model: 'doudizhu-rule-v1', dispName: 'Dou Dizhu Rule V1'}
|
||||
];
|
||||
// {'doudizhu': ['agent1', 'agent2', 'agent3']}
|
||||
const modelList = {};
|
||||
|
||||
function LeaderBoard () {
|
||||
const initRowsPerPage = 10;
|
||||
|
@ -40,6 +35,17 @@ function LeaderBoard () {
|
|||
const [rowsTotal, setRowsTotal] = React.useState(0);
|
||||
const [rows, setRows] = React.useState([]);
|
||||
|
||||
// passing an empty array as second argument triggers the callback in useEffect
|
||||
// only after the initial render thus replicating `componentDidMount` lifecycle behaviour
|
||||
useEffect(() => {
|
||||
gameList.forEach((game) => {
|
||||
axios.get(`${apiUrl}/tournament/list_baseline_agents?game=${game.game}`)
|
||||
.then(res => {
|
||||
modelList[game.game] = res.data.data;
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
const { type, name } = qs.parse(window.location.search);
|
||||
let requestUrl = `${apiUrl}/tournament/`;
|
||||
if (type === 'game') {
|
||||
|
@ -112,8 +118,7 @@ function createLeaderBoardData(resData, rank) {
|
|||
const agentHeadCells = [
|
||||
{ id: 'id', numeric: false, disablePadding: false, label: 'ID' },
|
||||
{ id: 'game', numeric: false, disablePadding: false, label: 'Game' },
|
||||
{ id: 'agent0', numeric: false, disablePadding: false, label: 'Agent 0' },
|
||||
{ id: 'agent1', numeric: false, disablePadding: false, label: 'Agent 1' },
|
||||
{ id: 'agent1', numeric: false, disablePadding: false, label: 'Opponent Agent' },
|
||||
{ id: 'win', numeric: false, disablePadding: false, label: 'Result' },
|
||||
{ id: 'payoff', numeric: false, disablePadding: false, label: 'Payoff' },
|
||||
{ id: 'replay', numeric: false, disablePadding: false, label: 'Replay' }
|
||||
|
@ -188,10 +193,7 @@ const EnhancedTableToolbar = (props) => {
|
|||
});
|
||||
name = foundItem.dispName;
|
||||
} else if (routeInfo.type === 'agent') {
|
||||
const foundItem = modelList.find(model => {
|
||||
return model.model === routeInfo.name;
|
||||
});
|
||||
name = foundItem.dispName;
|
||||
name = routeInfo.name;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -308,7 +310,6 @@ const AgentTableContent = (props) => {
|
|||
{row.id}
|
||||
</TableCell>
|
||||
<TableCell>{row.game}</TableCell>
|
||||
<TableCell>{row.agent0}</TableCell>
|
||||
<TableCell>{row.agent1}</TableCell>
|
||||
<TableCell>{row.win}</TableCell>
|
||||
<TableCell>{row.payoff}</TableCell>
|
||||
|
|
Loading…
Reference in New Issue