remove json decoration
parent
3a47b0a76a
commit
f59e98981b
|
|
@ -6,9 +6,17 @@
|
|||
</head>
|
||||
<body>
|
||||
<h1>Poor Man's Blind Man's Poker</h1>
|
||||
<button onclick="start(); return false;">Start</button>
|
||||
<button onclick="join(); return false;">Join</button>
|
||||
<button onclick="drop(); return false;">Drop</button>
|
||||
<form id="control-games" onsubmit="return false;">
|
||||
<button onclick="start(); return false;">Start</button>
|
||||
<button onclick="join(); return false;">Join</button>
|
||||
<button onclick="drop(); return false;">Drop</button>
|
||||
</form>
|
||||
<form id="control-game" onsubmit="return false;">
|
||||
<button onclick="fold(this); return false;">Fold</button>
|
||||
<button onclick="check(this); return false;">Check</button>
|
||||
<input min=0 type="number"/>
|
||||
<button onclick="raise(this); return false;">Raise cents</button>
|
||||
</form>
|
||||
<div id="game"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ class Games {
|
|||
});
|
||||
}
|
||||
|
||||
forGame(id, cb) {
|
||||
this.get(id, (game) => {
|
||||
cb(game);
|
||||
games.update(id, game, (game) => {ui.drawGame(game)});
|
||||
});
|
||||
}
|
||||
|
||||
forUser(id, uid, cb) {
|
||||
this.get(id, (game) => {
|
||||
game.Players.forEach((player, idx) => {
|
||||
|
|
@ -98,6 +105,7 @@ class Games {
|
|||
}
|
||||
|
||||
update(id, game, cb) {
|
||||
// TODO compute turn
|
||||
this.requests.put("/api/games/"+id, JSON.stringify(game), (text, status) => {
|
||||
if (status != 200) {
|
||||
throw new Error("bad status updating game: "+status+": "+text);
|
||||
|
|
@ -145,15 +153,16 @@ class UI {
|
|||
`;
|
||||
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>
|
||||
`;
|
||||
var enabled = player.Active && myturn;
|
||||
var eleControlGame = this.eleControlGame();
|
||||
var enabledWas = eleControlGame.getAttribute("disabled") == null;
|
||||
if (enabled != enabledWas) {
|
||||
if (enabled) {
|
||||
eleControlGame.removeAttribute("disabled");
|
||||
} else {
|
||||
eleControlGame.setAttribute("disabled", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
state += `</player>`;
|
||||
}
|
||||
|
|
@ -170,6 +179,14 @@ class UI {
|
|||
this.ele().innerHTML = "";
|
||||
}
|
||||
|
||||
eleControlGame() {
|
||||
return document.getElementById("control-game");
|
||||
}
|
||||
|
||||
eleControlGames() {
|
||||
return document.getElementById("control-games");
|
||||
}
|
||||
|
||||
ele() {
|
||||
return document.getElementById("game");
|
||||
}
|
||||
|
|
@ -273,6 +290,8 @@ function join() {
|
|||
var db = new DB();
|
||||
var id = db.get("id");
|
||||
games.forUser("id", id, (player) => {
|
||||
if (player.Participating)
|
||||
throw new Error("redundant join");
|
||||
player.Participating = true;
|
||||
player.Active = false;
|
||||
});
|
||||
|
|
@ -282,18 +301,47 @@ function drop() {
|
|||
var db = new DB();
|
||||
var id = db.get("id");
|
||||
games.forUser("id", id, (player) => {
|
||||
if (!player.Participating)
|
||||
throw new Error("redundant drop");
|
||||
player.Participating = false;
|
||||
player.Active = false;
|
||||
});
|
||||
}
|
||||
|
||||
function fold(ele) {
|
||||
var db = new DB();
|
||||
var id = db.get("id");
|
||||
games.forUser("id", id, (player) => {
|
||||
if (!player.Active)
|
||||
throw new Error("redundant fold");
|
||||
player.Active = false;
|
||||
});
|
||||
}
|
||||
|
||||
function check(ele) {
|
||||
var db = new DB();
|
||||
var id = db.get("id");
|
||||
games.forGame("id", (game) => {
|
||||
game.Turn += 1;
|
||||
});
|
||||
}
|
||||
|
||||
function raise(ele) {
|
||||
var db = new DB();
|
||||
var id = db.get("id");
|
||||
var bump = ele.parentNode.getElementsByTagName("input")[0].value;
|
||||
games.forGame("id", (game) => {
|
||||
game.Turn += 1;
|
||||
game.Players.forEach((player, idx) => {
|
||||
if (player.ID == id) {
|
||||
// todo it's supposed to be a string, should render client-side
|
||||
player.Balance -= bump;
|
||||
if (player.Balance < 0)
|
||||
throw new Error("cannot bet more than you have");
|
||||
game.Pot += bump;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var games = new Games();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Players [16]Player
|
||||
|
||||
type Game struct {
|
||||
|
|
@ -40,41 +32,3 @@ func (game Game) GetPlayers() []Player {
|
|||
func (p Player) Empty() bool {
|
||||
return p == (Player{})
|
||||
}
|
||||
|
||||
func (c Currency) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(fmt.Sprintf(`$%v.%02d`, c/100, c%100))
|
||||
}
|
||||
|
||||
func (c *Currency) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
re := regexp.MustCompile(`^\$([0-9]+(\.[0-9][0-9])?|\.[0-9]{2})$`)
|
||||
if !re.MatchString(s) {
|
||||
return fmt.Errorf("illegal currency format: %q", s)
|
||||
}
|
||||
s = strings.TrimPrefix(s, "$")
|
||||
dollars := strings.Split(s, ".")[0]
|
||||
cents := strings.TrimPrefix(s, dollars+".")
|
||||
if !strings.HasPrefix(s, dollars+".") {
|
||||
cents = "0"
|
||||
}
|
||||
if dollars == "" {
|
||||
dollars = "0"
|
||||
}
|
||||
if cents == "00" {
|
||||
cents = "0"
|
||||
}
|
||||
dI, err := strconv.Atoi(dollars)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cI, err := strconv.Atoi(cents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c2 := Currency(dI*100 + cI)
|
||||
*c = c2
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,101 +1,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCurrencyMarshal(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
input Currency
|
||||
want string
|
||||
}{
|
||||
"zero": {
|
||||
want: "$0.00",
|
||||
},
|
||||
"one cent": {
|
||||
input: 1,
|
||||
want: "$0.01",
|
||||
},
|
||||
"one dollar and one cent": {
|
||||
input: 101,
|
||||
want: "$1.01",
|
||||
},
|
||||
"one dollar and no cent": {
|
||||
input: 100,
|
||||
want: "$1.00",
|
||||
},
|
||||
}
|
||||
|
||||
for name, d := range cases {
|
||||
c := d
|
||||
t.Run(name, func(t *testing.T) {
|
||||
b, err := json.Marshal(c.input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b = b[1 : len(b)-1]
|
||||
if s := string(b); s != c.want {
|
||||
t.Fatalf("given %v, want %q, got %q", c.input, c.want, s)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyUnmarshal(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
input string
|
||||
want Currency
|
||||
}{
|
||||
"no dollar and no cent": {
|
||||
input: "$0.00",
|
||||
want: 0,
|
||||
},
|
||||
"omitted no dollar and no cent": {
|
||||
input: "$.00",
|
||||
want: 0,
|
||||
},
|
||||
"no dollar and omitted no cent": {
|
||||
input: "$0",
|
||||
want: 0,
|
||||
},
|
||||
"no dollar and one cent": {
|
||||
input: "$0.01",
|
||||
want: 1,
|
||||
},
|
||||
"omitted no dollar and one cent": {
|
||||
input: "$.01",
|
||||
want: 1,
|
||||
},
|
||||
"one dollar and one cent": {
|
||||
input: "$1.01",
|
||||
want: 101,
|
||||
},
|
||||
"one dollar and no cent": {
|
||||
input: "$1.00",
|
||||
want: 100,
|
||||
},
|
||||
"one dollar and omitted no cent": {
|
||||
input: "$1",
|
||||
want: 100,
|
||||
},
|
||||
}
|
||||
|
||||
for name, d := range cases {
|
||||
c := d
|
||||
t.Run(name, func(t *testing.T) {
|
||||
var got Currency
|
||||
err := json.Unmarshal([]byte(`"`+c.input+`"`), &got)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got != c.want {
|
||||
t.Fatalf("given %s, want %v, got %v", c.input, c.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlayerEmpty(t *testing.T) {
|
||||
var p Player
|
||||
if !p.Empty() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue