binmat
Version:
binmat simulator
111 lines (110 loc) • 3.85 kB
JavaScript
import { assert } from "@samual/lib/assert"
import { CardModifier, CardSuit, MoveKind, AttackerDiscardPile, AttackerDeck } from "./shared.js"
const CardValues = [
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"a",
CardModifier.Trap,
CardModifier.Wild,
CardModifier.Bounce,
CardModifier.Break
],
CardSuits = [CardSuit.Form, CardSuit.Kin, CardSuit.Data, CardSuit.Chaos, CardSuit.Void, CardSuit.Choice]
function parseMove(move, extra = !1) {
if ((assert(move.length > 1, `move must at least than 2 character, got ${move.length}`), "--" == move))
return { kind: MoveKind.Pass }
switch (move[0]) {
case "d": {
if (
(assert(2 == move.length, `draw moves must always be 2 characters, got ${move.length}`), "a" == move[1])
)
return { kind: MoveKind.Draw, deck: AttackerDeck }
const lane = Number(move[1])
return (
assert(lane >= 0 && lane < 6, `invalid lane number "${move[1]}" (expected 0 - 5 or "a")`),
{ kind: MoveKind.Draw, deck: lane }
)
}
case "c": {
assert(2 == move.length, `combat moves must always be 2 characters, got ${move.length}`)
const lane = Number(move[1])
return (
assert(lane >= 0 && lane < 6, `invalid lane number "${move[1]}" (expected 0 - 5)`),
{ kind: MoveKind.Combat, lane: lane }
)
}
case "p":
case "u":
if (3 == move.length) {
assert(
CardValues.includes(move[1]),
`invalid card value "${move[1]}" (expected one of ${CardValues.join(", ")})`
)
const lane = Number(move[2])
return (
assert(lane >= 0 && lane < 6, `invalid lane number "${move[2]}" (expected 0 - 5)`),
{ kind: "p" == move[0] ? MoveKind.Play : MoveKind.PlayFaceUp, card: move[1], lane: lane }
)
}
if (4 == move.length) {
assert(
CardValues.includes(move[1]),
`invalid card value "${move[1]}" (expected one of ${CardValues.join(", ")})`
),
assert(
CardSuits.includes(move[2]),
`invalid card suit "${move[2]}" (expected one of ${CardSuits.join(", ")})`
)
const lane = Number(move[3])
return (
assert(lane >= 0 && lane < 6, `invalid lane number "${move[3]}" (expected 0 - 5)`),
{ kind: "p" == move[0] ? MoveKind.Play : MoveKind.PlayFaceUp, card: move.slice(1, 3), lane: lane }
)
}
throw new Error(`play moves must be 3 or 4 characters, got ${move.length}`)
case "x":
if (
(assert(
CardValues.includes(move[1]),
`invalid card value "${move[1]}" (expected one of ${CardValues.join(", ")})`
),
extra && 2 == move.length)
)
return { kind: MoveKind.Discard, card: move[1], discardPile: AttackerDiscardPile }
if (3 == move.length) {
if ("a" == move[2]) return { kind: MoveKind.Discard, card: move[1], discardPile: AttackerDiscardPile }
if (extra && CardSuits.includes(move[2]))
return { kind: MoveKind.Discard, card: move.slice(1, 3), discardPile: AttackerDiscardPile }
const lane = Number(move[2])
return (
assert(lane >= 0 && lane < 6, `invalid discard pile "${move[2]}" (expected 0 - 5 or "a")`),
{ kind: MoveKind.Discard, card: move[1], discardPile: lane }
)
}
if (4 == move.length) {
if (
(assert(
CardSuits.includes(move[2]),
`invalid card suit "${move[2]}" (expected one of ${CardSuits.join(", ")})`
),
"a" == move[3])
)
return { kind: MoveKind.Discard, card: move.slice(1, 3), discardPile: AttackerDiscardPile }
const lane = Number(move[3])
return (
assert(lane >= 0 && lane < 6, `invalid discard pile "${move[3]}" (expected 0 - 5 or "a")`),
{ kind: MoveKind.Discard, card: move.slice(1, 3), discardPile: lane }
)
}
throw new Error(`discard moves must be 3 or 4 characters, got ${move.length}`)
default:
throw new Error(`invalid move kind "${move[0]}" in "${move}"`)
}
}
export { CardSuits, CardValues, parseMove }