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;
|
-ms-user-select: none;
|
||||||
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 ExpandMore from '@material-ui/icons/ExpandMore';
|
||||||
import {makeStyles} from "@material-ui/core/styles";
|
import {makeStyles} from "@material-ui/core/styles";
|
||||||
import qs from 'query-string';
|
import qs from 'query-string';
|
||||||
|
import ListSubheader from "@material-ui/core/ListSubheader";
|
||||||
|
|
||||||
const drawerWidth = 250;
|
const drawerWidth = 250;
|
||||||
|
|
||||||
|
@ -75,13 +76,15 @@ function MenuBar (props) {
|
||||||
</List>
|
</List>
|
||||||
});
|
});
|
||||||
|
|
||||||
const agentMenu = props.modelList.map(model => {
|
const generateAgentMenu = (modelList) => {
|
||||||
return <List component="div" disablePadding key={"game-menu-"+model.model}>
|
return modelList.map((model) => {
|
||||||
<ListItem button className={classes.nested} onClick={() => {handleAgentJump(model.model)}}>
|
return <List component="div" disablePadding key={"game-menu-"+model}>
|
||||||
<ListItemText primary={model.dispName} className={`${classes.menuLayer2} ${(type === 'agent' && name === model.model) ? classes.active : classes.inactive}`} />
|
<ListItem button className={classes.nested} onClick={() => {handleAgentJump(model)}}>
|
||||||
|
<ListItemText primary={model} className={`${classes.menuLayer2} ${(type === 'agent' && name === model) ? classes.active : classes.inactive}`} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
});
|
})
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
|
@ -108,7 +111,15 @@ function MenuBar (props) {
|
||||||
{open.game ? <ExpandLess /> : <ExpandMore />}
|
{open.game ? <ExpandLess /> : <ExpandMore />}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Collapse in={open.game} timeout="auto" unmountOnExit>
|
<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>
|
</Collapse>
|
||||||
</List>
|
</List>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
|
@ -7,7 +7,8 @@ import Navbar from '../../components/Navbar';
|
||||||
import {deepCopy} from "../../utils";
|
import {deepCopy} from "../../utils";
|
||||||
import { apiUrl } from "../../utils/config";
|
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 Slider from '@material-ui/core/Slider';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
import Paper from '@material-ui/core/Paper';
|
import Paper from '@material-ui/core/Paper';
|
||||||
|
@ -87,7 +88,7 @@ class LeducHoldemGameView extends React.Component {
|
||||||
case "check":
|
case "check":
|
||||||
break;
|
break;
|
||||||
case "raise":
|
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;
|
break;
|
||||||
case "call":
|
case "call":
|
||||||
// the upstream player must have bet more
|
// the upstream player must have bet more
|
||||||
|
@ -197,12 +198,22 @@ class LeducHoldemGameView extends React.Component {
|
||||||
startReplay() {
|
startReplay() {
|
||||||
const { name, agent0, agent1, index } = qs.parse(window.location.search);
|
const { name, agent0, agent1, index } = qs.parse(window.location.search);
|
||||||
const requestUrl = `${apiUrl}/tournament/replay?name=${name}&agent0=${agent0}&agent1=${agent1}&index=${index}`;
|
const requestUrl = `${apiUrl}/tournament/replay?name=${name}&agent0=${agent0}&agent1=${agent1}&index=${index}`;
|
||||||
|
|
||||||
// start full screen loading
|
// start full screen loading
|
||||||
this.setState({fullScreenLoading: true});
|
this.setState({fullScreenLoading: true});
|
||||||
|
|
||||||
axios.get(requestUrl)
|
axios.get(requestUrl)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
res = res.data;
|
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
|
// init replay info
|
||||||
this.moveHistory = res.moveHistory;
|
this.moveHistory = res.moveHistory;
|
||||||
this.moveHistoryTotalLength = this.moveHistory.reduce((count, round) => count + round.length, 0) - 1;
|
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.playerInfo = res.playerInfo;
|
||||||
gameInfo.hands = res.initHands;
|
gameInfo.hands = res.initHands;
|
||||||
gameInfo.currentPlayer = res.moveHistory[0][0].playerIdx;
|
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;
|
gameInfo.publicCard = res.publicCard;
|
||||||
if(this.gameStateHistory.length !== 0 && this.gameStateHistory[0].length === 0){
|
if(this.gameStateHistory.length !== 0 && this.gameStateHistory[0].length === 0){
|
||||||
this.gameStateHistory[gameInfo.round].push(gameInfo);
|
this.gameStateHistory[gameInfo.round].push(gameInfo);
|
||||||
|
@ -290,9 +303,12 @@ class LeducHoldemGameView extends React.Component {
|
||||||
{currentMove !== null ?
|
{currentMove !== null ?
|
||||||
(<div className={"non-card"}>
|
(<div className={"non-card"}>
|
||||||
{
|
{
|
||||||
currentMove.probabilities[idx].probability < 0 ?
|
currentMove.probabilities[idx].probability === -1 ?
|
||||||
<span>Illegal</span>
|
<span>Illegal</span>
|
||||||
:
|
:
|
||||||
|
currentMove.probabilities[idx].probability === -2 ?
|
||||||
|
<span>Rule Based</span>
|
||||||
|
:
|
||||||
<span>{`Probability ${(currentMove.probabilities[idx].probability * 100).toFixed(2)}%`}</span>
|
<span>{`Probability ${(currentMove.probabilities[idx].probability * 100).toFixed(2)}%`}</span>
|
||||||
}
|
}
|
||||||
</div>) : ""}
|
</div>) : ""}
|
||||||
|
|
|
@ -25,13 +25,8 @@ const gameList = [
|
||||||
{game: 'doudizhu', dispName: 'Dou Dizhu'},
|
{game: 'doudizhu', dispName: 'Dou Dizhu'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const modelList = [
|
// {'doudizhu': ['agent1', 'agent2', 'agent3']}
|
||||||
{model: 'leduc-holdem-random', dispName: 'Leduc Hold\'em Random'},
|
const modelList = {};
|
||||||
{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'}
|
|
||||||
];
|
|
||||||
|
|
||||||
function LeaderBoard () {
|
function LeaderBoard () {
|
||||||
const initRowsPerPage = 10;
|
const initRowsPerPage = 10;
|
||||||
|
@ -40,6 +35,17 @@ function LeaderBoard () {
|
||||||
const [rowsTotal, setRowsTotal] = React.useState(0);
|
const [rowsTotal, setRowsTotal] = React.useState(0);
|
||||||
const [rows, setRows] = React.useState([]);
|
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);
|
const { type, name } = qs.parse(window.location.search);
|
||||||
let requestUrl = `${apiUrl}/tournament/`;
|
let requestUrl = `${apiUrl}/tournament/`;
|
||||||
if (type === 'game') {
|
if (type === 'game') {
|
||||||
|
@ -112,8 +118,7 @@ function createLeaderBoardData(resData, rank) {
|
||||||
const agentHeadCells = [
|
const agentHeadCells = [
|
||||||
{ id: 'id', numeric: false, disablePadding: false, label: 'ID' },
|
{ id: 'id', numeric: false, disablePadding: false, label: 'ID' },
|
||||||
{ id: 'game', numeric: false, disablePadding: false, label: 'Game' },
|
{ id: 'game', numeric: false, disablePadding: false, label: 'Game' },
|
||||||
{ id: 'agent0', numeric: false, disablePadding: false, label: 'Agent 0' },
|
{ id: 'agent1', numeric: false, disablePadding: false, label: 'Opponent Agent' },
|
||||||
{ id: 'agent1', numeric: false, disablePadding: false, label: 'Agent 1' },
|
|
||||||
{ id: 'win', numeric: false, disablePadding: false, label: 'Result' },
|
{ id: 'win', numeric: false, disablePadding: false, label: 'Result' },
|
||||||
{ id: 'payoff', numeric: false, disablePadding: false, label: 'Payoff' },
|
{ id: 'payoff', numeric: false, disablePadding: false, label: 'Payoff' },
|
||||||
{ id: 'replay', numeric: false, disablePadding: false, label: 'Replay' }
|
{ id: 'replay', numeric: false, disablePadding: false, label: 'Replay' }
|
||||||
|
@ -188,10 +193,7 @@ const EnhancedTableToolbar = (props) => {
|
||||||
});
|
});
|
||||||
name = foundItem.dispName;
|
name = foundItem.dispName;
|
||||||
} else if (routeInfo.type === 'agent') {
|
} else if (routeInfo.type === 'agent') {
|
||||||
const foundItem = modelList.find(model => {
|
name = routeInfo.name;
|
||||||
return model.model === routeInfo.name;
|
|
||||||
});
|
|
||||||
name = foundItem.dispName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -308,7 +310,6 @@ const AgentTableContent = (props) => {
|
||||||
{row.id}
|
{row.id}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{row.game}</TableCell>
|
<TableCell>{row.game}</TableCell>
|
||||||
<TableCell>{row.agent0}</TableCell>
|
|
||||||
<TableCell>{row.agent1}</TableCell>
|
<TableCell>{row.agent1}</TableCell>
|
||||||
<TableCell>{row.win}</TableCell>
|
<TableCell>{row.win}</TableCell>
|
||||||
<TableCell>{row.payoff}</TableCell>
|
<TableCell>{row.payoff}</TableCell>
|
||||||
|
|
Loading…
Reference in New Issue