uno-game-js/src/js/room.js
2021-07-23 17:25:27 +09:00

164 lines
4.2 KiB
JavaScript

import BasicCanvas from './basic_canvas.js';
import Human from './human.js';
import Bot from './bot.js';
import Card from './card.js';
/* Images */
export default class Room extends BasicCanvas {
constructor(name) {
super(0, 0, global.uno_game_w, global.uno_game_h/10);
this._name = name;
this._players = [];
this._cards = [];
this._used_cards = [];
// Fill room name
this._ctx.font = Math.floor(this._h/3) + "px Arial";
this._ctx.fillText(name, 10, 50);
}
addHuman(name) {
this._players.push( new Human(name, this._players.length) );
console.log(this._players);
}
addBot() {
this._players.push( new Bot('bot', this._players.length) );
console.log(this._players);
}
initCards() {
console.log('Init')
const index_arr = [...Array(108).keys()];
let cnt = 0;
for (let num=0; num<14; num++) {
for (let color_n=0; color_n<8; color_n++) {
if ( (num === 0) && (color_n >= 4) ) { // Skip blank card
continue;
}
if ( (num === 13) && (color_n >= 4) ) { // +4 cards
num = 14;
}
const card_index = index_arr.splice(Math.floor( Math.random() * index_arr.length), 1)[0];
this._cards[ card_index ] = new Card(global.uno_game_w*6/16+card_index, global.uno_game_h/2, num, color_n%4);
cnt++;
}
}
for (let i=0; i<this._cards.length; i++) {
this._cards[i].refresh();
}
console.log(this._cards);
}
dealCards() {
console.log('Deal cards')
this._players.forEach( (player) => {
for (let i=0; i<7; i++) {
player.addCard( this._cards.pop() );
}
});
console.log(this._players);
}
async startGame() {
console.log('Game start');
this._turn_count = 0;
await( this.changeTopCard( this._cards.pop() ) );
await( this._current_player = this._players[0] );
if (this._current_player.type === 'bot') {
this.botPlay();
} else {
this.humanTurn();
}
// if (player.isEmpty()) {
// console.log('player: ' + player.name + ' has no card left. Game end');
// break
// }
}
async processPlay() {
await( this._current_player.refreshCards() );
this._turn_count++;
this._current_player = this.getNextPlayer();
if (this._current_player.type === 'human') {
this.humanTurn();
} else {
this.botPlay();
}
}
async botPlay() {
console.log('Turn count: ' + this._turn_count + ', current player: ' + this._current_player.name);
await new Promise(resolve => setTimeout(resolve, 1000));
const card = await( this._current_player.playCard(this._top_card) );
if (card) {
console.log('played card num: ' + card.num + ', color: ' + card.color_n);
this.changeTopCard(card);
} else {
const card = this._cards.pop();
console.log('drawed card num: ' + card.num + ', color: ' + card.color_n);
this._current_player.addCard(card);
}
this.processPlay();
}
humanTurn() {
console.log('Turn count: ' + this._turn_count + ', current player: ' + this._current_player.name);
this._current_player.cards.forEach( (card) => {
card.canvas.addEventListener('click', () => {
console.log('played card num: ' + card.num + ', color: ' + card.color_n);
// Remove event listener
this._current_player.cards.forEach( (card) => {
card.resetEventListener();
});
this.changeTopCard(card);
this._current_player.removeCard(card);
this.processPlay();
});
});
}
getNextPlayer() {
let current_player_id = this._current_player.id;
if (this._reverse) {
if (current_player_id === 0) {
current_player_id = this._players.length - 1;
} else {
current_player_id--;
}
} else {
if (current_player_id === this._players.length-1) {
current_player_id = 0;
} else {
current_player_id++;
}
}
return this._players[current_player_id];
}
changeTopCard(card) {
if (this._top_card) {
this._used_cards.push(this._top_card);
}
this._top_card = card;
this._top_card.drawImageFront(global.uno_game_w*8/16+this._turn_count, global.uno_game_h/2);
this._top_card.refresh();
}
}