server/www/game.js

222 lines
6.2 KiB
JavaScript

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: modules.i18n.get('youScored'),
answers: [
{label: 'endRound', action: function() {play({koiKoi: false})}},
{label: 'koikoi', action: function() {play({koiKoi: true});}}
]
});
} else {
modules.screen.dialog({
text: modules.i18n.get('theyScored')(modules.room.name(o.game.playing)),
answers: [
{label: 'ok', action: 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: modules.i18n.get('monthFlower')(modules.i18n.get(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 = modules.i18n.get("yourTurn");
} else {
sets.yourHand.dom.classList.remove("yourTurn");
turn = modules.i18n.get('playing')(modules.room.name(game.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});
}
}
}