302 lines
7.4 KiB
JavaScript
302 lines
7.4 KiB
JavaScript
class DB {
|
|
constructor() {
|
|
if (typeof(localStorage) === "undefined") {
|
|
throw new Error('Hmmm... no "localStorage" support');
|
|
}
|
|
}
|
|
|
|
get(key) {
|
|
var b = localStorage.getItem(key);
|
|
if (b) {
|
|
b = JSON.parse(b);
|
|
} else {
|
|
b = null;
|
|
}
|
|
return b
|
|
}
|
|
|
|
set(key, value) {
|
|
var b = JSON.stringify(value);
|
|
localStorage.setItem(key, b);
|
|
}
|
|
|
|
del(key) {
|
|
localStorage.removeItem(key);
|
|
}
|
|
}
|
|
|
|
class Requests {
|
|
put(remote, body, callback) {
|
|
this.http("put", remote, callback, body);
|
|
}
|
|
|
|
post(remote, body, callback) {
|
|
this.http("post", remote, callback, body);
|
|
}
|
|
|
|
get(remote, callback) {
|
|
this.http("get", remote, callback, null);
|
|
}
|
|
|
|
http(method, remote, callback, body) {
|
|
var xmlhttp = new XMLHttpRequest();
|
|
xmlhttp.onreadystatechange = function() {
|
|
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
|
callback(xmlhttp.responseText, xmlhttp.status);
|
|
}
|
|
};
|
|
xmlhttp.open(method, remote, true);
|
|
if (typeof body == "undefined") {
|
|
body = null;
|
|
}
|
|
xmlhttp.send(body);
|
|
}
|
|
}
|
|
|
|
class Games {
|
|
constructor() {
|
|
this.db = new DB();
|
|
this.requests = new Requests();
|
|
}
|
|
|
|
list(cb) {
|
|
this.requests.get("/api/games", (text) => {
|
|
var list = JSON.parse(text);
|
|
cb(list);
|
|
});
|
|
}
|
|
|
|
forUser(id, uid, cb) {
|
|
this.get(id, (game) => {
|
|
game.Players.forEach((player, idx) => {
|
|
if (player.ID == uid) {
|
|
cb(game.Players[idx]);
|
|
}
|
|
});
|
|
games.update(id, game, (game) => {ui.drawGame(game)});
|
|
});
|
|
}
|
|
|
|
get(id, cb) {
|
|
this.requests.get("/api/games/"+id, (text, status) => {
|
|
if (status != 200) {
|
|
throw new Error("bad status getting game: "+status+": "+text);
|
|
}
|
|
var game = JSON.parse(text);
|
|
cb(game);
|
|
});
|
|
}
|
|
|
|
create(id, cb) {
|
|
this.requests.post("/api/games/"+id, null, (text, status) => {
|
|
if (status != 200) {
|
|
throw new Error("bad status creating game: "+status+": "+text);
|
|
}
|
|
var game = JSON.parse(text);
|
|
cb(game);
|
|
});
|
|
}
|
|
|
|
update(id, game, cb) {
|
|
this.requests.put("/api/games/"+id, JSON.stringify(game), (text, status) => {
|
|
if (status != 200) {
|
|
throw new Error("bad status updating game: "+status+": "+text);
|
|
}
|
|
var game2 = JSON.parse(text);
|
|
cb(game2);
|
|
});
|
|
}
|
|
}
|
|
|
|
class UI {
|
|
constructor(games) {
|
|
this.games = games;
|
|
this.ts = 0;
|
|
this.threshold = 2;
|
|
setInterval(() => { this.refresh() }, 2000);
|
|
}
|
|
|
|
now() {
|
|
return new Date() / 1000;
|
|
}
|
|
|
|
refresh() {
|
|
if (this.now() - this.ts < this.threshold) {
|
|
return;
|
|
}
|
|
this.games.get("id", (game) => {
|
|
this.drawGame(game);
|
|
});
|
|
}
|
|
|
|
drawGame(game) {
|
|
this.ts = this.now();
|
|
var state = `
|
|
<pot>${game.Pot}</pot>
|
|
<players>
|
|
`;
|
|
game.Players.forEach((player, seatnum) => {
|
|
if (player.ID != "") {
|
|
state += `<player ${player.Participating ? "participating" : ""} ${player.Active ? "active" : ""}>`;
|
|
state += `
|
|
<name>${player.Name}</name>
|
|
<balance>${player.Balance}</balance>
|
|
<card>${this.me(player) ? "?" : player.Card}</card>
|
|
`;
|
|
if (this.me(player)) {
|
|
var myturn = seatnum == game.Turn
|
|
var disabled = (!player.Active || !myturn) ? "disabled" : "";
|
|
state += `
|
|
<form>
|
|
<button ${disabled} onclick="fold(this); return false;">Fold</button>
|
|
<button ${disabled} onclick="check(this); return false;">Check</button>
|
|
<input ${disabled} type="text"/>
|
|
<button ${disabled} onclick="raise(this); return false;">Raise</button>
|
|
</form>
|
|
`;
|
|
}
|
|
state += `</player>`;
|
|
}
|
|
});
|
|
state += "</players>";
|
|
this.ele().innerHTML = state;
|
|
}
|
|
|
|
me(player) {
|
|
return new DB().get("id") == player.ID
|
|
}
|
|
|
|
clear() {
|
|
this.ele().innerHTML = "";
|
|
}
|
|
|
|
ele() {
|
|
return document.getElementById("game");
|
|
}
|
|
}
|
|
|
|
function uuid() {
|
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
|
return v.toString(16);
|
|
});
|
|
}
|
|
|
|
class Deck {
|
|
constructor() {
|
|
this.cards = new Array(52);
|
|
}
|
|
|
|
draw() {
|
|
while (true) {
|
|
var idx = Math.floor(Math.random() * 52);
|
|
if (!this.cards[idx]) {
|
|
this.cards[idx] = 1;
|
|
return idx;
|
|
}
|
|
}
|
|
}
|
|
|
|
card(idx) {
|
|
var suit = idx % 4;
|
|
switch (suit) {
|
|
case 0: suit = "hearts"; break;
|
|
case 1: suit = "clubs"; break;
|
|
case 2: suit = "diamonds"; break;
|
|
case 3: suit = "spades"; break;
|
|
}
|
|
var num = idx % 13;
|
|
num += 2
|
|
switch (num) {
|
|
case 10: num = "jack"; break;
|
|
case 11: num = "queen"; break;
|
|
case 12: num = "king"; break;
|
|
case 13: num = "ace"; break;
|
|
}
|
|
return `${num} of ${suit}`;
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
var db = new DB();
|
|
if (!db.get("id")) {
|
|
db.set("id", uuid());
|
|
}
|
|
if (!db.get("name")) {
|
|
var name = prompt("who are you?");
|
|
db.set("name", name);
|
|
}
|
|
var id = db.get("id");
|
|
var name = db.get("name");
|
|
|
|
games.create("id", () => {
|
|
games.update("id", {
|
|
Pot: "$0",
|
|
Players: [
|
|
{ID: id, Name: name},
|
|
],
|
|
}, (game) => ui.drawGame(game));
|
|
});
|
|
|
|
games.get("id", (game) => {
|
|
ui.drawGame(game);
|
|
});
|
|
}
|
|
|
|
function start() {
|
|
var db = new DB();
|
|
var deck = new Deck()
|
|
var id = db.get("id");
|
|
games.get("id", (game) => {
|
|
var myturn = 0;
|
|
var n = 0;
|
|
game.Players.forEach((player, idx) => {
|
|
myturn = player.ID == id ? idx : myturn;
|
|
if (player.Participating) {
|
|
n += 1;
|
|
game.Players[idx].Active = true;
|
|
game.Players[idx].Card = deck.draw();
|
|
}
|
|
});
|
|
if (n == 0) {
|
|
throw new Error("will not start game with no participants");
|
|
}
|
|
game.Turn = myturn;
|
|
while (!game.Players[game.Turn].Participating) {
|
|
game.Turn = (game.Turn+1) % game.Players.length;
|
|
}
|
|
games.update("id", game, (game) => {ui.drawGame(game)});
|
|
});
|
|
}
|
|
|
|
function join() {
|
|
var db = new DB();
|
|
var id = db.get("id");
|
|
games.forUser("id", id, (player) => {
|
|
player.Participating = true;
|
|
player.Active = false;
|
|
});
|
|
}
|
|
|
|
function drop() {
|
|
var db = new DB();
|
|
var id = db.get("id");
|
|
games.forUser("id", id, (player) => {
|
|
player.Participating = false;
|
|
player.Active = false;
|
|
});
|
|
}
|
|
|
|
function fold(ele) {
|
|
}
|
|
|
|
function check(ele) {
|
|
}
|
|
|
|
function raise(ele) {
|
|
}
|
|
|
|
var games = new Games();
|
|
var ui = new UI(games);
|
|
init()
|