中间状态,添加记牌器
This commit is contained in:
parent
a1fdb90abe
commit
c3fbd52383
|
@ -8,7 +8,8 @@
|
|||
|
||||
"doudizhu": {
|
||||
"ai_hand_faceup": "Hand Face-Up",
|
||||
"ai_prediction": "AI Prediction",
|
||||
"ai_prediction": "Prediction",
|
||||
"card_recorder": "Card Recorder",
|
||||
"play_as_landlord": "Play As Landlord",
|
||||
"play_as_peasant": "Play As Peasant",
|
||||
"landlord_up": "Landlord Up",
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
"reset": "重置",
|
||||
|
||||
"doudizhu": {
|
||||
"ai_hand_faceup": "显示手牌",
|
||||
"ai_prediction": "显示预测",
|
||||
"ai_hand_faceup": "明牌",
|
||||
"ai_prediction": "预测",
|
||||
"card_recorder": "记牌器",
|
||||
"play_as_landlord": "扮演地主",
|
||||
"play_as_peasant": "扮演农民",
|
||||
"landlord_up": "地主上家",
|
||||
|
|
|
@ -45,6 +45,36 @@ export function deepCopy(toCopy) {
|
|||
return JSON.parse(JSON.stringify(toCopy));
|
||||
}
|
||||
|
||||
export function translateDouzeroCardData(card) {
|
||||
let rankClass;
|
||||
let suitClass = '';
|
||||
let rankText;
|
||||
let suitText = '';
|
||||
// translate rank
|
||||
if (card === 'D') {
|
||||
rankClass = 'big';
|
||||
rankText = '+';
|
||||
suitClass = 'joker';
|
||||
suitText = 'Joker';
|
||||
} else if (card === 'X') {
|
||||
rankClass = 'little';
|
||||
rankText = '-';
|
||||
suitClass = 'joker';
|
||||
suitText = 'Joker';
|
||||
} else {
|
||||
rankClass = card.charAt(0) === 'T' ? `10` : card.charAt(0).toLowerCase();
|
||||
rankClass = `rank-${rankClass}`;
|
||||
rankText = 'H';
|
||||
}
|
||||
// translate suitClass
|
||||
if (card !== 'X' && card !== 'D') {
|
||||
suitClass = suitMap.get('H');
|
||||
suitText = suitMapSymbol.get('H');
|
||||
}
|
||||
|
||||
return [rankClass, suitClass, rankText, suitText];
|
||||
}
|
||||
|
||||
export function translateCardData(card) {
|
||||
let rankClass;
|
||||
let suitClass = '';
|
||||
|
@ -110,6 +140,8 @@ export function card2SuiteAndRank(card) {
|
|||
}
|
||||
}
|
||||
|
||||
export const fullDouzeroDeck = ['3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A', '2', 'X', 'D']
|
||||
|
||||
export const fullDoudizhuDeck = [
|
||||
'RJ',
|
||||
'BJ',
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
card2SuiteAndRank,
|
||||
computeHandCardsWidth,
|
||||
deepCopy,
|
||||
fullDouzeroDeck,
|
||||
fullDoudizhuDeck,
|
||||
isDoudizhuBomb,
|
||||
shuffleArray,
|
||||
|
@ -67,6 +68,7 @@ let legalActions = { turn: -1, actions: [] };
|
|||
let hintIdx = -1;
|
||||
let gameEndDialogTitle = '';
|
||||
let syncGameStatus = localStorage.getItem('LOCALE') ? 'ready' : 'localeSelection';
|
||||
let cardRecorder = {};
|
||||
|
||||
function PvEDoudizhuDemoView() {
|
||||
const { t, i18n } = useTranslation();
|
||||
|
@ -87,6 +89,7 @@ function PvEDoudizhuDemoView() {
|
|||
const [predictionRes, setPredictionRes] = useState({ prediction: [], hands: [] });
|
||||
const [hideRivalHand, setHideRivalHand] = useState(true);
|
||||
const [hidePredictionArea, setHidePredictionArea] = useState(true);
|
||||
const [showCardRecorder, setShowCardRecorder] = useState(true);
|
||||
const [locale, setLocale] = useState(localStorage.getItem('LOCALE') || 'en');
|
||||
const [statisticRows, setStatisticRows] = useState([]);
|
||||
|
||||
|
@ -350,6 +353,23 @@ function PvEDoudizhuDemoView() {
|
|||
setIsGameEndDialogOpen(true);
|
||||
}, 2000);
|
||||
} else {
|
||||
// update card recorder
|
||||
if(showCardRecorder) {
|
||||
|
||||
const cardArr = cardArr2DouzeroFormat(
|
||||
sortDoudizhuCards(
|
||||
gameState.hands[(gameState.currentPlayer + 1) % 4].concat(
|
||||
gameState.hands[(gameState.currentPlayer + 2) % 4],
|
||||
gameState.hands[(gameState.currentPlayer + 3) % 4],
|
||||
),
|
||||
true,
|
||||
),
|
||||
)
|
||||
fullDouzeroDeck.forEach((card) => {
|
||||
cardRecorder[card] = cardArr.split('').reduce((acc, ch) => ch === 'card' ? acc + 1: acc, 0)
|
||||
})
|
||||
}
|
||||
|
||||
setConsiderationTime(initConsiderationTime);
|
||||
// manually trigger timer if consideration time equals initConsiderationTime
|
||||
if (initConsiderationTime === considerationTime) gameStateTimer();
|
||||
|
@ -518,6 +538,10 @@ function PvEDoudizhuDemoView() {
|
|||
setHidePredictionArea(!hidePredictionArea);
|
||||
};
|
||||
|
||||
const toggleShowCardRecorder = () => {
|
||||
setShowCardRecorder(!showCardRecorder);
|
||||
};
|
||||
|
||||
const handleSelectedCards = (cards) => {
|
||||
let newSelectedCards = selectedCards.slice();
|
||||
cards.forEach((card) => {
|
||||
|
@ -679,7 +703,7 @@ function PvEDoudizhuDemoView() {
|
|||
});
|
||||
setSelectedCards([]); // user selected hand card
|
||||
setPredictionRes({ prediction: [], hands: [] });
|
||||
setHideRivalHand(hideRivalHand);
|
||||
setHideRivalHand(true);
|
||||
|
||||
setGameStatus('ready');
|
||||
syncGameStatus = 'ready';
|
||||
|
@ -844,6 +868,27 @@ function PvEDoudizhuDemoView() {
|
|||
}
|
||||
};
|
||||
|
||||
const computeCardRecorderCards = (cards) => {
|
||||
return (
|
||||
<div className={'unselectable playingCards loose ' + toggleFade}>
|
||||
<ul className="hand" style={{ width: computeHandCardsWidth(computedCards.length, 10) }}>
|
||||
{cards.map((card) => {
|
||||
const [rankClass, suitClass, rankText, suitText] = translateDouzeroCardData(card);
|
||||
return (
|
||||
<li key={`handCard-${card}`}>
|
||||
<label className={`card ${rankClass} ${suitClass}`} href="/#">
|
||||
<span className="rank">{rankText}</span>
|
||||
<span className="suit">{suitText}</span>
|
||||
<span className="count">{cards[card]}</span>
|
||||
</label>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const computeProbabilityItem = (idx) => {
|
||||
if (gameStatus !== 'ready') {
|
||||
if (hidePredictionArea) {
|
||||
|
@ -880,6 +925,29 @@ function PvEDoudizhuDemoView() {
|
|||
}
|
||||
};
|
||||
|
||||
const computeCardRecorder = () => {
|
||||
if (gameStatus !== 'ready') {
|
||||
if (!showCardRecorder) {
|
||||
return (
|
||||
<div className={'playing'}>
|
||||
<div className={'non-card'}>
|
||||
<span>{t('hidden')}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className={'playing'}>
|
||||
<div className="probability-move">
|
||||
{computeCardRecorderCards(cardRecorder)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return <span className={'waiting'}>{t('waiting...')}</span>;
|
||||
}
|
||||
};
|
||||
|
||||
const gameSpeedMarks = [
|
||||
{
|
||||
value: 0,
|
||||
|
@ -1053,7 +1121,7 @@ function PvEDoudizhuDemoView() {
|
|||
<div className={'probability-item'}>{computeProbabilityItem(0)}</div>
|
||||
<div className={'probability-item'}>{computeProbabilityItem(1)}</div>
|
||||
<div className={'probability-item'}>{computeProbabilityItem(2)}</div>
|
||||
<div className={'probability-item'}>{computeProbabilityItem(3)}</div>
|
||||
<div className={'probability-item'}>{computeCardRecorder()}</div>
|
||||
</div>
|
||||
</Paper>
|
||||
</Layout.Col>
|
||||
|
@ -1079,6 +1147,14 @@ function PvEDoudizhuDemoView() {
|
|||
}
|
||||
label={t('doudizhu.ai_prediction')}
|
||||
/>
|
||||
<FormControlLabel
|
||||
style={{ textAlign: 'center', height: '100%', display: 'inline-block' }}
|
||||
className="switch-control"
|
||||
control={
|
||||
<Switch checked={!showCardRecorder} onChange={toggleShowCardRecorder} />
|
||||
}
|
||||
label={t('doudizhu.card_recorder')}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Layout.Col>
|
||||
<Layout.Col span="1" style={{ height: '100%', width: '1px' }}>
|
||||
|
|
Loading…
Reference in New Issue