function Game(modules) { var deck = document.getElementById("deck"); var rest = document.getElementById("rest"); var status = { dom: document.getElementById("status"), playing: false, step: null, month: null }; var sets = { river: { card: null, dom: document.getElementById("river") }, yourHand: { card: null, dom: document.getElementById("you").getElementsByClassName("hand")[0] }, theirHand: { dom: document.getElementById("them").getElementsByClassName("hand")[0] } }; var selected = null; modules.messaging.addEventListener(["Game"], function(o) { setStatus(o.game); setCaptures(o.game); [ ['river', o.game.river, RiverCard], ['yourHand', o.game.players[modules.session.getKey()].hand, HandCard] ].forEach(function(args) {setCardSet.apply(null, args)}); setTheirCards(o.game); if(status.step == "Turned") { setTurned(o.game.step.contents); } else { if(status.step == "ToPlay" && o.game.playing == o.game.oyake) { rest.className = ["card", "count" + o.game.deck].join(' '); } if(deck.lastChild.id != "rest") { deck.removeChild(deck.lastChild); } } if(status.step == "Scored") { if(status.playing) { modules.screen.dialog({ text: "You scored ! Do you want to get your points and end the round or KoiKoi ?", answers: { 'End the round': function() {play({koiKoi: false})}, 'KoiKoi !': function() {play({koiKoi: true});} } }); } else { modules.screen.dialog({ text: modules.room.name(o.game.playing) + " scored", answers: { 'Ok': function() {} } }); } } }); function play(move) { modules.messaging.send({ tag: "Play", move: move }); } function matchingInRiver(card) { return modules.fun.mapFilter( modules.fun.of(sets.river.card), modules.fun.isSet )(modules.hanafuda.sameMonth(card).map(modules.fun.proj('name'))); } function setStatus(game) { modules.dom.clear(status.dom); status.step = game.step.tag; if(game.month != status.month) { status.month = game.month; } status.dom.appendChild( modules.dom.make('li', {textContent: "This month's flower is the " + status.month}) ); var turn = null; status.playing = modules.session.is(game.playing); if(status.playing) { sets.yourHand.dom.classList.toggle("yourTurn", status.step == "ToPlay"); turn = "Your turn"; } else { sets.yourHand.dom.classList.remove("yourTurn"); turn = modules.room.name(game.playing) + " is playing"; } status.dom.appendChild(modules.dom.make('li', {textContent: turn})); } function setCaptures(game) { for(var key in game.players) { var elem = document.getElementById(modules.session.is(key) ? "you" : "them"); elem.getElementsByClassName('score')[0].textContent = game.scores[key] + " pts"; var byClass = {} Object.values(modules.hanafuda.Family).forEach(function(family) { byClass[family.class] = elem.getElementsByClassName(family.class)[0]; modules.dom.clear(byClass[family.class]); }); game.players[key].meld.forEach(function(cardName) { var card = new Card(cardName); byClass[card.value.family.class].appendChild(card.dom); }); } } function setCardSet(setName, cardNames, constructor) { constructor = constructor || Card; var set = sets[setName]; set.card = {}; modules.dom.clear(set.dom); cardNames.forEach(function(cardName) { var card = new constructor(cardName); set.card[cardName] = card; set.dom.appendChild(card.dom); }); } function setTheirCards(game) { var turnsTheyPlayed = Math.floor( (24 - game.deck + (modules.session.is(game.oyake) ? 0 : 1)) / 2 ); modules.dom.clear(sets.theirHand.dom); for(var i = 0; i < 8 - turnsTheyPlayed; i++) { sets.theirHand.dom.appendChild(modules.dom.make('li', {class: "card"})); } } function setTurned(cardName) { var card = new Card(cardName); card.dom.id = "turned"; deck.appendChild(card.dom); if(status.playing) { selected = cardName; showCandidates(modules.hanafuda.Card[selected], true); } } function showCandidates(card, yes) { matchingInRiver(card).forEach(function(riverCard) {riverCard.setCandidate(yes);}); } function Card(name) { this.value = modules.hanafuda.Card[name]; this.name = name; this.dom = modules.dom.make('li', { class: [ "card", "value" + modules.hanafuda.getValue(this.value), "month" + this.value.flower ], onClick: this.onClick() }); } Card.prototype.onClick = function() {return function() {};}; function RiverCard() { Card.apply(this, arguments); this.candidate = false; } RiverCard.prototype.onClick = function() { var card = this; return function() { if(card.candidate) { var withCard = selected; selected = null; play( status.step == 'ToPlay' ? {capture: [withCard, card.name]} : {choose: card.name} ); } }; }; RiverCard.prototype.setCandidate = function(yes) { this.candidate = yes; this.dom.classList.toggle("candidate", yes); } function HandCard() { Card.apply(this, arguments); } HandCard.prototype.onClick = function() { if(status.playing && status.step == "ToPlay") { var card = this; return function() { if(selected != undefined) { sets.yourHand.card[selected].setSelected(false); } else { card.play(); } }; } else { return function() {}; } }; HandCard.prototype.setSelected = function(yes) { selected = yes ? this.name : null; this.dom.classList.toggle('selected', yes); showCandidates(this.value, yes); } HandCard.prototype.play = function() { var matching = matchingInRiver(this.value); if(matching.length > 1) { this.setSelected(true); } else { play({play: this.name}); } } }