601 lines
20 KiB
JavaScript
601 lines
20 KiB
JavaScript
|
|
// 卡片类
|
|||
|
|
class Card {
|
|||
|
|
constructor(suit, rank, value) {
|
|||
|
|
this.suit = suit; // 花色:spades, hearts, clubs, diamonds, joker
|
|||
|
|
this.rank = rank; // 点数:A, 2, 3, ..., 10, J, Q, K, 小王, 大王
|
|||
|
|
this.value = value; // 牌值:用于比较大小
|
|||
|
|
this.selected = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取卡片的HTML表示
|
|||
|
|
getHTML(selected = false) {
|
|||
|
|
const cardDiv = document.createElement('div');
|
|||
|
|
cardDiv.className = `card ${this.suit} ${selected ? 'selected' : ''}`;
|
|||
|
|
cardDiv.dataset.suit = this.suit;
|
|||
|
|
cardDiv.dataset.rank = this.rank;
|
|||
|
|
cardDiv.dataset.value = this.value;
|
|||
|
|
|
|||
|
|
// 花色符号
|
|||
|
|
const suitSymbol = {
|
|||
|
|
spades: '♠',
|
|||
|
|
hearts: '♥',
|
|||
|
|
clubs: '♣',
|
|||
|
|
diamonds: '♦'
|
|||
|
|
}[this.suit] || this.rank;
|
|||
|
|
|
|||
|
|
// 创建卡片内容
|
|||
|
|
const rankTop = document.createElement('div');
|
|||
|
|
rankTop.className = 'rank-top';
|
|||
|
|
rankTop.textContent = this.rank;
|
|||
|
|
|
|||
|
|
const suitMiddle = document.createElement('div');
|
|||
|
|
suitMiddle.className = 'suit-middle';
|
|||
|
|
suitMiddle.textContent = suitSymbol;
|
|||
|
|
|
|||
|
|
const rankBottom = document.createElement('div');
|
|||
|
|
rankBottom.className = 'rank-bottom';
|
|||
|
|
rankBottom.textContent = this.rank;
|
|||
|
|
|
|||
|
|
// 组装卡片
|
|||
|
|
cardDiv.appendChild(rankTop);
|
|||
|
|
cardDiv.appendChild(suitMiddle);
|
|||
|
|
cardDiv.appendChild(rankBottom);
|
|||
|
|
|
|||
|
|
return cardDiv;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取背面HTML
|
|||
|
|
static getBackHTML() {
|
|||
|
|
const cardDiv = document.createElement('div');
|
|||
|
|
cardDiv.className = 'card card-back';
|
|||
|
|
return cardDiv;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 游戏类
|
|||
|
|
class LandlordGame {
|
|||
|
|
constructor() {
|
|||
|
|
this.players = [
|
|||
|
|
{ id: 0, name: '我', cards: [], role: '', lastPlay: [] },
|
|||
|
|
{ id: 1, name: '电脑玩家1', cards: [], role: '', lastPlay: [] },
|
|||
|
|
{ id: 2, name: '电脑玩家2', cards: [], role: '', lastPlay: [] }
|
|||
|
|
];
|
|||
|
|
this.deck = [];
|
|||
|
|
this.landlordCards = [];
|
|||
|
|
this.currentPlayer = 0;
|
|||
|
|
this.gameStatus = 'waiting'; // waiting, calling, playing, ended
|
|||
|
|
this.landlord = -1;
|
|||
|
|
this.lastPlayPlayer = -1;
|
|||
|
|
this.lastPlayCards = [];
|
|||
|
|
this.score = 0;
|
|||
|
|
this.callLandlordCount = 0;
|
|||
|
|
|
|||
|
|
this.initializeElements();
|
|||
|
|
this.initializeEventListeners();
|
|||
|
|
this.initializeDeck();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化DOM元素
|
|||
|
|
initializeElements() {
|
|||
|
|
this.elements = {
|
|||
|
|
startGame: document.getElementById('start-game'),
|
|||
|
|
gameStatus: document.getElementById('game-status'),
|
|||
|
|
currentPlayer: document.getElementById('current-player'),
|
|||
|
|
landlordCardsArea: document.getElementById('landlord-cards-area'),
|
|||
|
|
landlordButtons: document.querySelector('.landlord-buttons'),
|
|||
|
|
callLandlord: document.getElementById('call-landlord'),
|
|||
|
|
noCall: document.getElementById('no-call'),
|
|||
|
|
playButtons: document.querySelector('.play-buttons'),
|
|||
|
|
playCards: document.getElementById('play-cards'),
|
|||
|
|
pass: document.getElementById('pass'),
|
|||
|
|
currentPlayCards: document.getElementById('current-play-cards'),
|
|||
|
|
currentPlayInfo: document.getElementById('current-play-info'),
|
|||
|
|
playerCards: [
|
|||
|
|
document.getElementById('self-cards'),
|
|||
|
|
document.getElementById('player-1-cards'),
|
|||
|
|
document.getElementById('player-2-cards')
|
|||
|
|
],
|
|||
|
|
playerCardsCount: [
|
|||
|
|
document.getElementById('self-cards-count'),
|
|||
|
|
document.getElementById('player-1-cards-count'),
|
|||
|
|
document.getElementById('player-2-cards-count')
|
|||
|
|
],
|
|||
|
|
playerRoles: [
|
|||
|
|
document.getElementById('self-role'),
|
|||
|
|
document.getElementById('player-1-role'),
|
|||
|
|
document.getElementById('player-2-role')
|
|||
|
|
],
|
|||
|
|
lastPlay: [
|
|||
|
|
document.getElementById('self-last-play'),
|
|||
|
|
document.getElementById('player-1-last-play'),
|
|||
|
|
document.getElementById('player-2-last-play')
|
|||
|
|
],
|
|||
|
|
score: document.getElementById('score')
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化事件监听器
|
|||
|
|
initializeEventListeners() {
|
|||
|
|
this.elements.startGame.addEventListener('click', () => this.startGame());
|
|||
|
|
this.elements.callLandlord.addEventListener('click', () => this.callLandlord());
|
|||
|
|
this.elements.noCall.addEventListener('click', () => this.noCall());
|
|||
|
|
this.elements.playCards.addEventListener('click', () => this.playSelectedCards());
|
|||
|
|
this.elements.pass.addEventListener('click', () => this.pass());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化牌组
|
|||
|
|
initializeDeck() {
|
|||
|
|
this.deck = [];
|
|||
|
|
const suits = ['spades', 'hearts', 'clubs', 'diamonds'];
|
|||
|
|
const ranks = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2'];
|
|||
|
|
const values = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
|||
|
|
|
|||
|
|
// 添加普通牌
|
|||
|
|
for (let i = 0; i < ranks.length; i++) {
|
|||
|
|
for (const suit of suits) {
|
|||
|
|
this.deck.push(new Card(suit, ranks[i], values[i]));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 添加大小王
|
|||
|
|
this.deck.push(new Card('joker', '小王', 16));
|
|||
|
|
this.deck.push(new Card('joker', '大王', 17));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 洗牌算法
|
|||
|
|
shuffleDeck() {
|
|||
|
|
for (let i = this.deck.length - 1; i > 0; i--) {
|
|||
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|||
|
|
[this.deck[i], this.deck[j]] = [this.deck[j], this.deck[i]];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 开始游戏
|
|||
|
|
startGame() {
|
|||
|
|
this.gameStatus = 'calling';
|
|||
|
|
this.currentPlayer = 0;
|
|||
|
|
this.landlord = -1;
|
|||
|
|
this.lastPlayPlayer = -1;
|
|||
|
|
this.lastPlayCards = [];
|
|||
|
|
this.callLandlordCount = 0;
|
|||
|
|
|
|||
|
|
// 重置玩家数据
|
|||
|
|
for (const player of this.players) {
|
|||
|
|
player.cards = [];
|
|||
|
|
player.role = '';
|
|||
|
|
player.lastPlay = [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 洗牌发牌
|
|||
|
|
this.initializeDeck();
|
|||
|
|
this.shuffleDeck();
|
|||
|
|
this.dealCards();
|
|||
|
|
|
|||
|
|
// 更新UI
|
|||
|
|
this.updateGameStatus('开始叫地主');
|
|||
|
|
this.updateCurrentPlayer();
|
|||
|
|
this.renderAllCards();
|
|||
|
|
this.elements.startGame.style.display = 'none';
|
|||
|
|
this.elements.landlordButtons.style.display = 'flex';
|
|||
|
|
this.elements.playButtons.style.display = 'none';
|
|||
|
|
this.clearCurrentPlay();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 发牌
|
|||
|
|
dealCards() {
|
|||
|
|
// 发牌给三个玩家
|
|||
|
|
for (let i = 0; i < 17; i++) {
|
|||
|
|
this.players[0].cards.push(this.deck.pop());
|
|||
|
|
this.players[1].cards.push(this.deck.pop());
|
|||
|
|
this.players[2].cards.push(this.deck.pop());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 剩余的3张作为地主牌
|
|||
|
|
this.landlordCards = [...this.deck];
|
|||
|
|
this.deck = [];
|
|||
|
|
|
|||
|
|
// 排序玩家的牌
|
|||
|
|
for (const player of this.players) {
|
|||
|
|
this.sortCards(player.cards);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 排序卡片
|
|||
|
|
sortCards(cards) {
|
|||
|
|
cards.sort((a, b) => a.value - b.value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 叫地主
|
|||
|
|
callLandlord() {
|
|||
|
|
this.landlord = this.currentPlayer;
|
|||
|
|
this.players[this.currentPlayer].role = '地主';
|
|||
|
|
this.players[(this.currentPlayer + 1) % 3].role = '农民';
|
|||
|
|
this.players[(this.currentPlayer + 2) % 3].role = '农民';
|
|||
|
|
|
|||
|
|
// 将地主牌加入地主手中
|
|||
|
|
this.players[this.currentPlayer].cards.push(...this.landlordCards);
|
|||
|
|
this.sortCards(this.players[this.currentPlayer].cards);
|
|||
|
|
|
|||
|
|
// 开始游戏
|
|||
|
|
this.gameStatus = 'playing';
|
|||
|
|
this.updateGameStatus('游戏开始,地主出牌');
|
|||
|
|
this.updatePlayerRoles();
|
|||
|
|
this.renderAllCards();
|
|||
|
|
this.elements.landlordButtons.style.display = 'none';
|
|||
|
|
this.elements.playButtons.style.display = 'flex';
|
|||
|
|
|
|||
|
|
// 如果是电脑地主,自动出牌
|
|||
|
|
if (this.currentPlayer !== 0) {
|
|||
|
|
setTimeout(() => this.computerPlay(), 1000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 不叫地主
|
|||
|
|
noCall() {
|
|||
|
|
this.callLandlordCount++;
|
|||
|
|
this.currentPlayer = (this.currentPlayer + 1) % 3;
|
|||
|
|
this.updateCurrentPlayer();
|
|||
|
|
|
|||
|
|
// 如果三个玩家都不叫,重新开始
|
|||
|
|
if (this.callLandlordCount === 3) {
|
|||
|
|
this.updateGameStatus('无人叫地主,重新开始');
|
|||
|
|
setTimeout(() => this.startGame(), 1500);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果是电脑玩家,自动选择
|
|||
|
|
if (this.currentPlayer !== 0) {
|
|||
|
|
setTimeout(() => this.computerCallLandlord(), 1000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 电脑叫地主
|
|||
|
|
computerCallLandlord() {
|
|||
|
|
// 简单AI:如果有王或多张大牌,叫地主
|
|||
|
|
const hasBigCards = this.players[this.currentPlayer].cards.some(card =>
|
|||
|
|
card.value >= 16 ||
|
|||
|
|
(card.value >= 14 && this.players[this.currentPlayer].cards.filter(c => c.value >= 14).length >= 3)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (hasBigCards) {
|
|||
|
|
this.callLandlord();
|
|||
|
|
} else {
|
|||
|
|
this.noCall();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 选择卡片
|
|||
|
|
toggleCardSelection(cardElement) {
|
|||
|
|
if (this.gameStatus !== 'playing' || this.currentPlayer !== 0) return;
|
|||
|
|
|
|||
|
|
cardElement.classList.toggle('selected');
|
|||
|
|
const selected = cardElement.classList.contains('selected');
|
|||
|
|
const suit = cardElement.dataset.suit;
|
|||
|
|
const rank = cardElement.dataset.rank;
|
|||
|
|
const value = parseInt(cardElement.dataset.value);
|
|||
|
|
|
|||
|
|
// 更新卡片对象的选中状态
|
|||
|
|
const card = this.players[0].cards.find(c =>
|
|||
|
|
c.suit === suit && c.rank === rank && c.value === value
|
|||
|
|
);
|
|||
|
|
if (card) {
|
|||
|
|
card.selected = selected;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 出牌
|
|||
|
|
playSelectedCards() {
|
|||
|
|
if (this.gameStatus !== 'playing' || this.currentPlayer !== 0) return;
|
|||
|
|
|
|||
|
|
// 获取选中的卡片
|
|||
|
|
const selectedCards = this.players[0].cards.filter(card => card.selected);
|
|||
|
|
if (selectedCards.length === 0) return;
|
|||
|
|
|
|||
|
|
// 验证出牌是否合法
|
|||
|
|
if (this.isValidPlay(selectedCards)) {
|
|||
|
|
// 更新游戏状态
|
|||
|
|
this.players[0].lastPlay = selectedCards;
|
|||
|
|
this.lastPlayPlayer = 0;
|
|||
|
|
this.lastPlayCards = selectedCards;
|
|||
|
|
|
|||
|
|
// 从手中移除出的牌
|
|||
|
|
this.players[0].cards = this.players[0].cards.filter(card => !card.selected);
|
|||
|
|
|
|||
|
|
// 检查是否获胜
|
|||
|
|
if (this.players[0].cards.length === 0) {
|
|||
|
|
this.endGame(0);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新UI
|
|||
|
|
this.renderPlayerCards(0);
|
|||
|
|
this.updateCardsCount(0);
|
|||
|
|
this.updateCurrentPlay(0, selectedCards);
|
|||
|
|
this.updateSelfLastPlay(selectedCards);
|
|||
|
|
|
|||
|
|
// 切换到下一个玩家
|
|||
|
|
this.currentPlayer = 1;
|
|||
|
|
this.updateCurrentPlayer();
|
|||
|
|
|
|||
|
|
// 电脑玩家自动出牌
|
|||
|
|
setTimeout(() => this.computerPlay(), 1000);
|
|||
|
|
} else {
|
|||
|
|
alert('出牌不合法,请重新选择');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 不出牌
|
|||
|
|
pass() {
|
|||
|
|
if (this.gameStatus !== 'playing' || this.currentPlayer !== 0) return;
|
|||
|
|
|
|||
|
|
// 更新游戏状态
|
|||
|
|
this.players[0].lastPlay = [];
|
|||
|
|
this.updateGameStatus('玩家不出牌');
|
|||
|
|
|
|||
|
|
// 切换到下一个玩家
|
|||
|
|
this.currentPlayer = 1;
|
|||
|
|
this.updateCurrentPlayer();
|
|||
|
|
|
|||
|
|
// 电脑玩家自动出牌
|
|||
|
|
setTimeout(() => this.computerPlay(), 1000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 电脑出牌
|
|||
|
|
computerPlay() {
|
|||
|
|
const player = this.players[this.currentPlayer];
|
|||
|
|
const playableCards = this.findPlayableCards(player.cards);
|
|||
|
|
|
|||
|
|
if (playableCards.length > 0) {
|
|||
|
|
// 选择最合适的牌组
|
|||
|
|
const selectedCards = this.chooseBestCards(playableCards);
|
|||
|
|
|
|||
|
|
// 更新游戏状态
|
|||
|
|
player.lastPlay = selectedCards;
|
|||
|
|
this.lastPlayPlayer = this.currentPlayer;
|
|||
|
|
this.lastPlayCards = selectedCards;
|
|||
|
|
|
|||
|
|
// 从手中移除出的牌
|
|||
|
|
player.cards = player.cards.filter(card => !selectedCards.includes(card));
|
|||
|
|
|
|||
|
|
// 检查是否获胜
|
|||
|
|
if (player.cards.length === 0) {
|
|||
|
|
this.endGame(this.currentPlayer);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新UI
|
|||
|
|
this.renderPlayerCards(this.currentPlayer);
|
|||
|
|
this.updateCardsCount(this.currentPlayer);
|
|||
|
|
this.updateCurrentPlay(this.currentPlayer, selectedCards);
|
|||
|
|
this.updateComputerLastPlay(this.currentPlayer, selectedCards);
|
|||
|
|
|
|||
|
|
this.updateGameStatus(`${player.name} 出牌`);
|
|||
|
|
} else {
|
|||
|
|
// 不出牌
|
|||
|
|
player.lastPlay = [];
|
|||
|
|
this.updateGameStatus(`${player.name} 不出牌`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 切换到下一个玩家
|
|||
|
|
this.currentPlayer = (this.currentPlayer + 1) % 3;
|
|||
|
|
this.updateCurrentPlayer();
|
|||
|
|
|
|||
|
|
// 如果下一个是电脑,继续自动出牌
|
|||
|
|
if (this.currentPlayer !== 0) {
|
|||
|
|
setTimeout(() => this.computerPlay(), 1000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 查找可出的牌组
|
|||
|
|
findPlayableCards(cards) {
|
|||
|
|
const playable = [];
|
|||
|
|
|
|||
|
|
// 如果是第一个出牌,可以出任何牌组
|
|||
|
|
if (this.lastPlayPlayer === -1) {
|
|||
|
|
// 简单实现:找出所有可能的单牌、对子、顺子等
|
|||
|
|
// 这里简化处理,只考虑单牌
|
|||
|
|
for (const card of cards) {
|
|||
|
|
playable.push([card]);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 必须出比上一次大的同类型牌
|
|||
|
|
const lastType = this.getCardType(this.lastPlayCards);
|
|||
|
|
const lastMaxValue = Math.max(...this.lastPlayCards.map(c => c.value));
|
|||
|
|
|
|||
|
|
if (lastType === 'single') {
|
|||
|
|
// 找比lastMaxValue大的单牌
|
|||
|
|
const singles = cards.filter(card => card.value > lastMaxValue);
|
|||
|
|
for (const card of singles) {
|
|||
|
|
playable.push([card]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return playable;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 选择最好的牌组
|
|||
|
|
chooseBestCards(playableCards) {
|
|||
|
|
// 简单AI:选择最小的可出牌组
|
|||
|
|
if (playableCards.length === 0) return [];
|
|||
|
|
|
|||
|
|
// 由于只允许单牌,直接选择最小的可出牌
|
|||
|
|
return playableCards[0];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 验证出牌是否合法
|
|||
|
|
isValidPlay(cards) {
|
|||
|
|
if (cards.length === 0) return false;
|
|||
|
|
|
|||
|
|
// 简化版:只允许出单牌
|
|||
|
|
if (cards.length !== 1) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果是第一个出牌
|
|||
|
|
if (this.lastPlayPlayer === -1) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查牌型是否相同(都是单牌)
|
|||
|
|
const currentType = this.getCardType(cards);
|
|||
|
|
const lastType = this.getCardType(this.lastPlayCards);
|
|||
|
|
|
|||
|
|
if (currentType !== 'single' || lastType !== 'single') {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查大小
|
|||
|
|
const currentMax = Math.max(...cards.map(c => c.value));
|
|||
|
|
const lastMax = Math.max(...this.lastPlayCards.map(c => c.value));
|
|||
|
|
|
|||
|
|
return currentMax > lastMax;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取牌型
|
|||
|
|
getCardType(cards) {
|
|||
|
|
if (cards.length === 0) return 'empty';
|
|||
|
|
if (cards.length === 1) return 'single';
|
|||
|
|
if (cards.length === 2) {
|
|||
|
|
if (cards[0].value === cards[1].value) return 'pair';
|
|||
|
|
if (cards[0].value === 16 && cards[1].value === 17) return 'rocket';
|
|||
|
|
return 'invalid';
|
|||
|
|
}
|
|||
|
|
// 这里可以扩展更多牌型判断
|
|||
|
|
return 'invalid';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 结束游戏
|
|||
|
|
endGame(winner) {
|
|||
|
|
this.gameStatus = 'ended';
|
|||
|
|
const winnerPlayer = this.players[winner];
|
|||
|
|
const isLandlordWin = winnerPlayer.role === '地主';
|
|||
|
|
|
|||
|
|
if (isLandlordWin) {
|
|||
|
|
this.score += 200;
|
|||
|
|
this.updateGameStatus(`地主 ${winnerPlayer.name} 获胜!`);
|
|||
|
|
} else {
|
|||
|
|
this.score -= 100;
|
|||
|
|
this.updateGameStatus(`农民 ${winnerPlayer.name} 获胜!`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新UI
|
|||
|
|
this.elements.landlordButtons.style.display = 'none';
|
|||
|
|
this.elements.playButtons.style.display = 'none';
|
|||
|
|
this.elements.startGame.style.display = 'block';
|
|||
|
|
this.elements.startGame.textContent = '再来一局';
|
|||
|
|
this.updateScore();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新游戏状态
|
|||
|
|
updateGameStatus(status) {
|
|||
|
|
this.elements.gameStatus.textContent = status;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新当前玩家
|
|||
|
|
updateCurrentPlayer() {
|
|||
|
|
this.elements.currentPlayer.textContent = `当前玩家:${this.players[this.currentPlayer].name}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新玩家角色
|
|||
|
|
updatePlayerRoles() {
|
|||
|
|
for (let i = 0; i < 3; i++) {
|
|||
|
|
this.elements.playerRoles[i].textContent = this.players[i].role;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 渲染所有卡片
|
|||
|
|
renderAllCards() {
|
|||
|
|
for (let i = 0; i < 3; i++) {
|
|||
|
|
this.renderPlayerCards(i);
|
|||
|
|
this.updateCardsCount(i);
|
|||
|
|
}
|
|||
|
|
this.renderLandlordCards();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 渲染玩家卡片
|
|||
|
|
renderPlayerCards(playerIndex) {
|
|||
|
|
const container = this.elements.playerCards[playerIndex];
|
|||
|
|
container.innerHTML = '';
|
|||
|
|
|
|||
|
|
const player = this.players[playerIndex];
|
|||
|
|
|
|||
|
|
if (playerIndex === 0) {
|
|||
|
|
// 自己的卡片,可以选择
|
|||
|
|
for (const card of player.cards) {
|
|||
|
|
const cardElement = card.getHTML(card.selected);
|
|||
|
|
cardElement.addEventListener('click', () => this.toggleCardSelection(cardElement));
|
|||
|
|
container.appendChild(cardElement);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 电脑玩家的卡片,显示背面
|
|||
|
|
for (let i = 0; i < player.cards.length; i++) {
|
|||
|
|
const cardElement = Card.getBackHTML();
|
|||
|
|
container.appendChild(cardElement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 渲染地主牌
|
|||
|
|
renderLandlordCards() {
|
|||
|
|
this.elements.landlordCardsArea.innerHTML = '';
|
|||
|
|
for (const card of this.landlordCards) {
|
|||
|
|
const cardElement = card.getHTML();
|
|||
|
|
this.elements.landlordCardsArea.appendChild(cardElement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新牌数
|
|||
|
|
updateCardsCount(playerIndex) {
|
|||
|
|
this.elements.playerCardsCount[playerIndex].textContent = this.players[playerIndex].cards.length;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新当前出牌
|
|||
|
|
updateCurrentPlay(playerIndex, cards) {
|
|||
|
|
this.elements.currentPlayInfo.textContent = `${this.players[playerIndex].name} 出牌:`;
|
|||
|
|
this.elements.currentPlayCards.innerHTML = '';
|
|||
|
|
|
|||
|
|
for (const card of cards) {
|
|||
|
|
const cardElement = card.getHTML();
|
|||
|
|
this.elements.currentPlayCards.appendChild(cardElement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清空当前出牌
|
|||
|
|
clearCurrentPlay() {
|
|||
|
|
this.elements.currentPlayInfo.textContent = '当前出牌:';
|
|||
|
|
this.elements.currentPlayCards.innerHTML = '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新自己的上次出牌
|
|||
|
|
updateSelfLastPlay(cards) {
|
|||
|
|
const container = this.elements.lastPlay[0];
|
|||
|
|
container.innerHTML = '';
|
|||
|
|
|
|||
|
|
for (const card of cards) {
|
|||
|
|
const cardElement = card.getHTML();
|
|||
|
|
container.appendChild(cardElement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新电脑玩家的上次出牌
|
|||
|
|
updateComputerLastPlay(playerIndex, cards) {
|
|||
|
|
const container = this.elements.lastPlay[playerIndex];
|
|||
|
|
container.innerHTML = '';
|
|||
|
|
|
|||
|
|
for (const card of cards) {
|
|||
|
|
const cardElement = card.getHTML();
|
|||
|
|
container.appendChild(cardElement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新分数
|
|||
|
|
updateScore() {
|
|||
|
|
this.elements.score.textContent = this.score;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化游戏
|
|||
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|||
|
|
window.game = new LandlordGame();
|
|||
|
|
});
|