everyone can play !
This commit is contained in:
parent
0c15a9e3cb
commit
52570f80b1
3 changed files with 300 additions and 150 deletions
|
|
@ -46,8 +46,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.hand-tile-item.draw-tile {
|
.hand-tile-item.draw-tile {
|
||||||
/* Le draw s'affiche simplement à droite grâce à flex */
|
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Orientation variations */
|
/* Orientation variations */
|
||||||
|
|
|
||||||
135
frontend/js/game.js
Normal file
135
frontend/js/game.js
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
// frontend/js/game.js
|
||||||
|
// Adaptation frontend de la logique de game.py en JavaScript
|
||||||
|
|
||||||
|
async function think(t) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, 1000 * t));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Wall {
|
||||||
|
constructor() {
|
||||||
|
this.tiles = Tile.generateAll();
|
||||||
|
this.shuffle();
|
||||||
|
}
|
||||||
|
shuffle() {
|
||||||
|
for (let i = this.tiles.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[this.tiles[i], this.tiles[j]] = [this.tiles[j], this.tiles[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
draw() {
|
||||||
|
return this.tiles.shift();
|
||||||
|
}
|
||||||
|
drawHand() {
|
||||||
|
const handTiles = this.tiles.splice(0, 13);
|
||||||
|
return new Hand(handTiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Hand {
|
||||||
|
constructor(tiles) {
|
||||||
|
this.tiles = tiles;
|
||||||
|
this.draw = null;
|
||||||
|
}
|
||||||
|
drawTile(tile) {
|
||||||
|
this.draw = tile;
|
||||||
|
}
|
||||||
|
discardTile(tileId) {
|
||||||
|
let idx = this.tiles.findIndex(t => t.id === tileId);
|
||||||
|
if (idx !== -1) {
|
||||||
|
return this.tiles.splice(idx, 1)[0];
|
||||||
|
}
|
||||||
|
if (this.draw && this.draw.id === tileId) {
|
||||||
|
const discarded = this.draw;
|
||||||
|
this.draw = null;
|
||||||
|
return discarded;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
flatten() {
|
||||||
|
if (this.draw) {
|
||||||
|
this.tiles.push(this.draw);
|
||||||
|
this.draw = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Game {
|
||||||
|
constructor(onUpdate) {
|
||||||
|
this.wall = new Wall();
|
||||||
|
this.handPlayer = this.wall.drawHand();
|
||||||
|
this.discardPlayer = [];
|
||||||
|
this.handsBots = [this.wall.drawHand(), this.wall.drawHand(), this.wall.drawHand()];
|
||||||
|
this.discardsBots = [[], [], []];
|
||||||
|
this.turn = 0;
|
||||||
|
this.hasDraw = true;
|
||||||
|
this.end = false;
|
||||||
|
this.onUpdate = onUpdate || (() => {});
|
||||||
|
// Est pioche une tuile
|
||||||
|
const tile = this.wall.draw();
|
||||||
|
if (tile) this.handPlayer.drawTile(tile);
|
||||||
|
this.onUpdate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawTile(hand) {
|
||||||
|
const tile = this.wall.draw();
|
||||||
|
if (tile) hand.drawTile(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTile(hand, tileId) {
|
||||||
|
const discarded = hand.discardTile(tileId);
|
||||||
|
if (discarded) {
|
||||||
|
this.wall.tiles.push(discarded);
|
||||||
|
this.wall.shuffle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async nextTurn() {
|
||||||
|
this.turn = (this.turn + 1) % 4;
|
||||||
|
this.hasDraw = false;
|
||||||
|
this.onUpdate(this);
|
||||||
|
if (this.turn !== 0) {
|
||||||
|
await this.botTurn();
|
||||||
|
} else {
|
||||||
|
this.drawTile(this.handPlayer);
|
||||||
|
this.hasDraw = true;
|
||||||
|
this.onUpdate(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async botTurn() {
|
||||||
|
const bot = this.handsBots[this.turn - 1];
|
||||||
|
this.drawTile(bot);
|
||||||
|
this.onUpdate(this); // Affiche la pioche
|
||||||
|
await think(2);
|
||||||
|
// Défausse une tuile aléatoire
|
||||||
|
const idx = Math.floor(Math.random() * bot.tiles.length);
|
||||||
|
const tileToDiscard = bot.tiles[idx];
|
||||||
|
const discarded = bot.discardTile(tileToDiscard.id);
|
||||||
|
bot.flatten()
|
||||||
|
this.onUpdate(this); // Affiche la défausse
|
||||||
|
await think(0.5);
|
||||||
|
if (discarded) this.discardsBots[this.turn - 1].push(discarded);
|
||||||
|
await this.nextTurn();
|
||||||
|
}
|
||||||
|
|
||||||
|
async discardTile(tileId) {
|
||||||
|
if (this.turn === 0 && this.hasDraw) {
|
||||||
|
const wasDraw = (this.handPlayer.draw && this.handPlayer.draw.id === tileId);
|
||||||
|
const discarded = this.handPlayer.discardTile(tileId);
|
||||||
|
// Si la tuile défaussée n'était pas draw, on intègre draw à la main avant le rendu
|
||||||
|
if (!wasDraw) {
|
||||||
|
this.handPlayer.flatten();
|
||||||
|
}
|
||||||
|
this.onUpdate(this); // Affiche la défausse
|
||||||
|
if (discarded) this.discardPlayer.push(discarded);
|
||||||
|
await this.nextTurn();
|
||||||
|
return discarded;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expose dans le scope global
|
||||||
|
window.Game = Game;
|
||||||
|
window.Hand = Hand;
|
||||||
|
window.Wall = Wall;
|
||||||
|
|
@ -140,164 +140,179 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/frontend/js/fr/texts.js"></script>
|
<script src="/frontend/js/fr/texts.js"></script>
|
||||||
|
<script src="/frontend/js/tile.js"></script>
|
||||||
|
<script src="/frontend/js/game.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let isDrawing = false;
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Charger le menu
|
||||||
|
fetch('/components/menu.html')
|
||||||
|
.then(r => r.text())
|
||||||
|
.then(html => document.getElementById('menu').innerHTML = html);
|
||||||
|
|
||||||
// Fonction pour mettre à jour l'état du jeu
|
// Afficher la mascotte et le texte
|
||||||
function updateGameState() {
|
const mascotteEl = document.getElementById('mascotte');
|
||||||
fetch('/api/game/state')
|
mascotteEl.innerHTML = '<img src="/img/tilineau/idle.png" alt="Tilineau">';
|
||||||
.then(r => r.json())
|
document.getElementById('speech-text').innerHTML = texts.riichi.chap5;
|
||||||
.then(data => {
|
|
||||||
if (data.state && Array.isArray(data.state.hand_player)) {
|
|
||||||
window.lastDrawTile = data.state.draw ? data.state.draw.svg : null;
|
|
||||||
displayHand(data.state.hand_player, 'hand-0');
|
|
||||||
}
|
|
||||||
[1, 2, 3].forEach(id => {
|
|
||||||
fetch(`/api/game/hand/${id}`)
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(botData => {
|
|
||||||
if (botData.hand) {
|
|
||||||
displayHand(botData.hand, `hand-${id}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setInterval(updateGameState, 500);
|
// Toggle bulle de dialogue au clic sur la mascotte
|
||||||
// Charger le menu
|
const speechBubble = document.querySelector('.speech-bubble');
|
||||||
fetch('/components/menu.html')
|
mascotteEl.addEventListener('click', () => {
|
||||||
.then(r => r.text())
|
speechBubble.classList.toggle('visible');
|
||||||
.then(html => document.getElementById('menu').innerHTML = html);
|
mascotteEl.innerHTML = speechBubble.classList.contains('visible')
|
||||||
|
? '<img class="explaining" src="/img/tilineau/explaining.png" alt="Tilineau">'
|
||||||
|
: '<img src="/img/tilineau/idle.png" alt="Tilineau">';
|
||||||
|
});
|
||||||
|
|
||||||
// Afficher la mascotte et le texte
|
// Logique de jeu frontend
|
||||||
const mascotteEl = document.getElementById('mascotte');
|
let game;
|
||||||
mascotteEl.innerHTML = '<img src="/img/tilineau/idle.png" alt="Tilineau">';
|
function renderPlayerHand(gameInstance) {
|
||||||
document.getElementById('speech-text').innerHTML = texts.riichi.chap5;
|
const handDiv = document.getElementById('hand-0');
|
||||||
|
handDiv.innerHTML = '';
|
||||||
// Toggle bulle de dialogue au clic sur la mascotte
|
let handTiles = gameInstance.handPlayer.tiles.slice();
|
||||||
const speechBubble = document.querySelector('.speech-bubble');
|
sortHand(handTiles);
|
||||||
mascotteEl.addEventListener('click', () => {
|
handTiles.forEach((tile, idx) => {
|
||||||
speechBubble.classList.toggle('visible');
|
const tileDiv = document.createElement('div');
|
||||||
mascotteEl.innerHTML = speechBubble.classList.contains('visible')
|
tileDiv.className = 'hand-tile-item';
|
||||||
? '<img class="explaining" src="/img/tilineau/explaining.png" alt="Tilineau">'
|
tileDiv.innerHTML = tile.getSVG();
|
||||||
: '<img src="/img/tilineau/idle.png" alt="Tilineau">';
|
tileDiv.dataset.tileId = tile.id;
|
||||||
});
|
|
||||||
|
|
||||||
// Fonction d'affichage d'une main
|
|
||||||
function displayHand(hand, displayId) {
|
|
||||||
const display = document.getElementById(displayId);
|
|
||||||
// Pour hand-0, on compare l'état actuel
|
|
||||||
if (displayId === 'hand-0') {
|
|
||||||
// Génère une signature simple de la main
|
|
||||||
const handSignature = hand.map(tile => tile.id).join(',') + (window.lastDrawTile || '');
|
|
||||||
if (display.dataset.signature === handSignature) {
|
|
||||||
// Rien n'a changé, on ne réécrit pas
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
display.dataset.signature = handSignature;
|
|
||||||
}
|
|
||||||
display.innerHTML = '';
|
|
||||||
hand.forEach(tile => {
|
|
||||||
const tileDiv = document.createElement('div');
|
|
||||||
// Affiche le dos des tuiles pour les bots
|
|
||||||
if (displayId !== 'hand-0') {
|
|
||||||
tileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
|
||||||
} else {
|
|
||||||
tileDiv.innerHTML = tile.svg;
|
|
||||||
tileDiv.style.cursor = 'pointer';
|
tileDiv.style.cursor = 'pointer';
|
||||||
tileDiv.addEventListener('click', () => discard_tile(tile.id));
|
tileDiv.addEventListener('click', () => discardTile(tile.id));
|
||||||
}
|
handDiv.appendChild(tileDiv);
|
||||||
display.appendChild(tileDiv);
|
|
||||||
});
|
|
||||||
// Affiche la tuile draw à la fin si elle existe (pour hand-0)
|
|
||||||
if (displayId === 'hand-0' && window.lastDrawTile) {
|
|
||||||
const drawDiv = document.createElement('div');
|
|
||||||
drawDiv.id = 'draw-tile';
|
|
||||||
drawDiv.style.marginLeft = '10px';
|
|
||||||
drawDiv.innerHTML = window.lastDrawTile;
|
|
||||||
display.appendChild(drawDiv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function discard_tile(tileId) {
|
|
||||||
console.log('[JS] discard_tile', tileId);
|
|
||||||
fetch('/api/discard_tile', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ tile_id: tileId })
|
|
||||||
})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(data => {
|
|
||||||
console.log('[JS] discard response', data);
|
|
||||||
if (data.state && Array.isArray(data.state.hand_player)) {
|
|
||||||
window.lastDrawTile = data.state.draw ? data.state.draw.svg : null;
|
|
||||||
displayHand(data.state.hand_player, 'hand-0');
|
|
||||||
}
|
|
||||||
// Affiche la défausse du joueur
|
|
||||||
if (data.state) {
|
|
||||||
fetch('/api/game/discards/0')
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(discardsData => {
|
|
||||||
displayDiscards(discardsData.discards, 'discards-0');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
// Pioche
|
||||||
|
if (gameInstance.handPlayer.draw) {
|
||||||
function displayDiscards(discards, displayId) {
|
const drawTileDiv = document.createElement('div');
|
||||||
const display = document.getElementById(displayId);
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
||||||
display.innerHTML = '';
|
drawTileDiv.innerHTML = gameInstance.handPlayer.draw.getSVG();
|
||||||
discards.forEach(tile => {
|
drawTileDiv.dataset.tileId = gameInstance.handPlayer.draw.id;
|
||||||
const tileDiv = document.createElement('div');
|
drawTileDiv.style.cursor = 'pointer';
|
||||||
tileDiv.innerHTML = tile.svg;
|
drawTileDiv.addEventListener('click', () => discardTile(gameInstance.handPlayer.draw.id));
|
||||||
display.appendChild(tileDiv);
|
handDiv.appendChild(drawTileDiv);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Polling pour récupérer la main d'un bot
|
|
||||||
function fetchBotHandWithRetry(id, tries = 8, delay = 500) {
|
|
||||||
fetch(`/api/game/hand/${id}`)
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(botData => {
|
|
||||||
if (botData.hand) {
|
|
||||||
displayHand(botData.hand, `hand-${id}`);
|
|
||||||
} else if (tries > 0) {
|
|
||||||
setTimeout(() => fetchBotHandWithRetry(id, tries - 1, delay), delay);
|
|
||||||
} else {
|
|
||||||
console.error(`Main vide pour joueur ${id}`);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
if (tries > 0) {
|
|
||||||
setTimeout(() => fetchBotHandWithRetry(id, tries - 1, delay), delay);
|
|
||||||
} else {
|
|
||||||
console.error(`Erreur main ${id}`, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialiser une partie au chargement du chapitre 5
|
|
||||||
fetch('/api/game/start', { method: 'POST' })
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(data => {
|
|
||||||
console.log('Réponse API', data);
|
|
||||||
// Si has_draw est False, on appelle play_draw et on attend le reload
|
|
||||||
if (data.state && data.state.has_draw === false) {
|
|
||||||
fetch('/api/play_draw', { method: 'POST' })
|
|
||||||
.then(() => {
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// Afficher la main du joueur
|
// Afficher les mains des bots
|
||||||
if (data.state && data.state.hand_player) {
|
for (let bot = 0; bot < 3; bot++) {
|
||||||
displayHand(data.state.hand_player, 'hand-0');
|
const botDiv = document.getElementById('hand-' + (bot + 1));
|
||||||
// Affichage des mains bots (1, 2, 3) avec polling
|
botDiv.innerHTML = '';
|
||||||
[1, 2, 3].forEach(id => {
|
let botTiles = gameInstance.handsBots[bot].tiles.slice();
|
||||||
fetchBotHandWithRetry(id);
|
botTiles.forEach(() => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
||||||
|
botDiv.appendChild(tileDiv);
|
||||||
});
|
});
|
||||||
|
if (gameInstance.handsBots[bot].draw) {
|
||||||
|
const drawTileDiv = document.createElement('div');
|
||||||
|
drawTileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
||||||
|
botDiv.appendChild(drawTileDiv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
game = new window.Game(renderPlayerHand);
|
||||||
|
|
||||||
|
function sortHand(hand) {
|
||||||
|
const familyOrder = { 'man': 0, 'pin': 1, 'sou': 2, 'wind': 3, 'dragon': 4 };
|
||||||
|
return hand.sort((a, b) => {
|
||||||
|
const famA = familyOrder[a.family] ?? 99;
|
||||||
|
const famB = familyOrder[b.family] ?? 99;
|
||||||
|
if (famA !== famB) return famA - famB;
|
||||||
|
if (a.value !== undefined && b.value !== undefined) return a.value - b.value;
|
||||||
|
if (a.wind !== undefined && b.wind !== undefined) return a.wind - b.wind;
|
||||||
|
if (a.dragon !== undefined && b.dragon !== undefined) return a.dragon - b.dragon;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderPlayerHand() {
|
||||||
|
const handDiv = document.getElementById('hand-0');
|
||||||
|
handDiv.innerHTML = '';
|
||||||
|
let handTiles = game.handPlayer.tiles.slice();
|
||||||
|
sortHand(handTiles);
|
||||||
|
handTiles.forEach((tile, idx) => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.className = 'hand-tile-item';
|
||||||
|
tileDiv.innerHTML = tile.getSVG();
|
||||||
|
tileDiv.dataset.tileId = tile.id;
|
||||||
|
tileDiv.style.cursor = 'pointer';
|
||||||
|
tileDiv.addEventListener('click', () => discardTile(tile.id));
|
||||||
|
handDiv.appendChild(tileDiv);
|
||||||
|
});
|
||||||
|
// Pioche
|
||||||
|
if (game.handPlayer.draw) {
|
||||||
|
const drawTileDiv = document.createElement('div');
|
||||||
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
||||||
|
drawTileDiv.innerHTML = game.handPlayer.draw.getSVG();
|
||||||
|
drawTileDiv.dataset.tileId = game.handPlayer.draw.id;
|
||||||
|
drawTileDiv.style.cursor = 'pointer';
|
||||||
|
drawTileDiv.addEventListener('click', () => discardTile(game.handPlayer.draw.id));
|
||||||
|
handDiv.appendChild(drawTileDiv);
|
||||||
|
}
|
||||||
|
// Afficher les mains des bots
|
||||||
|
for (let bot = 0; bot < 3; bot++) {
|
||||||
|
const botDiv = document.getElementById('hand-' + (bot + 1));
|
||||||
|
botDiv.innerHTML = '';
|
||||||
|
let botTiles = game.handsBots[bot].tiles.slice();
|
||||||
|
// Affiche le dos des tuiles
|
||||||
|
botTiles.forEach(() => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
||||||
|
botDiv.appendChild(tileDiv);
|
||||||
|
});
|
||||||
|
// Pioche du bot (si présente)
|
||||||
|
if (game.handsBots[bot].draw) {
|
||||||
|
const drawTileDiv = document.createElement('div');
|
||||||
|
drawTileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
||||||
|
botDiv.appendChild(drawTileDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function renderPlayerHand(gameInstance) {
|
||||||
|
const handDiv = document.getElementById('hand-0');
|
||||||
|
handDiv.innerHTML = '';
|
||||||
|
let handTiles = gameInstance.handPlayer.tiles.slice();
|
||||||
|
sortHand(handTiles);
|
||||||
|
handTiles.forEach((tile, idx) => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.className = 'hand-tile-item';
|
||||||
|
tileDiv.innerHTML = tile.getSVG();
|
||||||
|
tileDiv.dataset.tileId = tile.id;
|
||||||
|
tileDiv.style.cursor = 'pointer';
|
||||||
|
tileDiv.addEventListener('click', () => discardTile(tile.id));
|
||||||
|
handDiv.appendChild(tileDiv);
|
||||||
|
});
|
||||||
|
// Pioche
|
||||||
|
if (gameInstance.handPlayer.draw) {
|
||||||
|
const drawTileDiv = document.createElement('div');
|
||||||
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
||||||
|
drawTileDiv.innerHTML = gameInstance.handPlayer.draw.getSVG();
|
||||||
|
drawTileDiv.dataset.tileId = gameInstance.handPlayer.draw.id;
|
||||||
|
drawTileDiv.style.cursor = 'pointer';
|
||||||
|
drawTileDiv.addEventListener('click', () => discardTile(gameInstance.handPlayer.draw.id));
|
||||||
|
handDiv.appendChild(drawTileDiv);
|
||||||
|
}
|
||||||
|
// Afficher les mains des bots
|
||||||
|
for (let bot = 0; bot < 3; bot++) {
|
||||||
|
const botDiv = document.getElementById('hand-' + (bot + 1));
|
||||||
|
botDiv.innerHTML = '';
|
||||||
|
let botTiles = gameInstance.handsBots[bot].tiles.slice();
|
||||||
|
botTiles.forEach(() => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
||||||
|
botDiv.appendChild(tileDiv);
|
||||||
|
});
|
||||||
|
if (gameInstance.handsBots[bot].draw) {
|
||||||
|
const drawTileDiv = document.createElement('div');
|
||||||
|
drawTileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
||||||
|
botDiv.appendChild(drawTileDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function discardTile(tileId) {
|
||||||
|
await game.discardTile(tileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// renderPlayerHand(game); // Removed direct call to renderPlayerHand with game
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in a new issue