binmat
Version:
binmat simulator
144 lines (143 loc) • 6.08 kB
JavaScript
import { doMoveCombat } from "./doMoveCombat.js"
import { doMoveDiscard } from "./doMoveDiscard.js"
import { doMoveDraw } from "./doMoveDraw.js"
import { doMovePass } from "./doMovePass.js"
import { doMovePlay } from "./doMovePlay.js"
import { doMovePlayFaceUp } from "./doMovePlayFaceUp.js"
import { MoveKind, StatusCode, AttackerDeck } from "./shared.js"
import "./doCombat.js"
import "@samual/lib/shuffle"
import "@samual/lib/assert"
function doMove(state, move) {
const turn = String(state.turn).padStart(3, "0"),
roleTurn = state.turn % 2 ? "a" : "d"
switch (move.kind) {
case MoveKind.Draw: {
const deckIsEmpty = !(move.deck == AttackerDeck ? state.attackerDeck : state.laneDecks[move.deck]).length,
result = doMoveDraw(state, move.deck),
deck = move.deck == AttackerDeck ? "a" : move.deck
if (result.status == StatusCode.AttackerWin)
return { status: StatusCode.AttackerWin, binlog: [`\`V${turn}\` \`n------\``, `${roleTurn}0 d${deck}`] }
if (result.status == StatusCode.Ok || result.status == StatusCode.DefenderWin) {
const card = move.deck < 3 || move.deck == AttackerDeck || deckIsEmpty ? "X" : result.cardDrawn
return {
status: result.status,
binlog: [`\`V${turn}\` \`n------\``, `${roleTurn}0 d${deck} / ${card} h${roleTurn}0 `]
}
}
return { status: result.status }
}
case MoveKind.Play: {
const result = doMovePlay(state, move.card, move.lane)
return result.status == StatusCode.Ok || result.status == StatusCode.DefenderWin ?
{
status: result.status,
binlog: [`\`V${turn}\` \`n------\``, `${roleTurn}0 pX${move.lane} / X ${roleTurn}${move.lane}`]
}
: { status: result.status }
}
case MoveKind.PlayFaceUp: {
const result = doMovePlayFaceUp(state, move.card, move.lane)
if (
result.status == StatusCode.Ok ||
result.status == StatusCode.AttackerWin ||
result.status == StatusCode.DefenderWin
) {
const binlog = [
`\`V${turn}\` \`n------\``,
`${roleTurn}0 u${result.cardPlayed[0]}${move.lane} / ${result.cardPlayed} ${roleTurn}${move.lane}`
]
return (
result.combat && pushCombatBinlog(binlog, result.combat, move.lane, result.cardPlayed),
{ status: result.status, binlog: binlog }
)
}
return { status: result.status }
}
case MoveKind.Combat: {
const result = doMoveCombat(state, move.lane)
if (
result.status == StatusCode.Ok ||
result.status == StatusCode.DefenderWin ||
result.status == StatusCode.AttackerWin
) {
const binlog = [`\`V${turn}\` \`n------\``, `${roleTurn}0 c${move.lane}`]
return pushCombatBinlog(binlog, result, move.lane), { status: result.status, binlog: binlog }
}
return { status: result.status }
}
case MoveKind.Discard: {
const result = doMoveDiscard(state, move.card, move.discardPile)
if (result.status == StatusCode.Ok || result.status == StatusCode.DefenderWin) {
const discardPile = move.discardPile == AttackerDeck ? "a" : move.discardPile
return {
status: result.status,
binlog: [
`\`V${turn}\` \`n------\``,
`${roleTurn}0 x${result.cardDiscarded[0]}${discardPile} / ${result.cardDiscarded} x${discardPile}`
]
}
}
return { status: result.status }
}
case MoveKind.Pass: {
const status = doMovePass(state)
return status == StatusCode.MadeMoveOnFinishedGame ?
{ status: status }
: { status: status, binlog: [`\`V${turn}\` \`n------\``, `${roleTurn}0 \`n--\``] }
}
}
function pushCombatBinlog(binlog, combatData, lane, cardIsPlayedFaceUp) {
const {
attackerAttackPower: attackerAttackPower,
attackerStack: attackerStack,
defenderAttackPower: defenderAttackPower,
defenderStack: defenderStack,
attackerCardsTrapped: attackerCardsTrapped,
defenderCardsTrapped: defenderCardsTrapped,
attackerBouncesDiscarded: attackerBouncesDiscarded,
defenderBouncesDiscarded: defenderBouncesDiscarded,
damageValue: damageValue,
defenderStackWasFaceUp: defenderStackWasFaceUp
} = combatData,
attackerSide =
"a" == roleTurn && cardIsPlayedFaceUp && attackerStack.length ?
`${attackerStack.join(" ")}u`
: attackerStack.join(" "),
defenderSide =
defenderStackWasFaceUp ? defenderStack.map(card => `${card}u`).join(" ") : defenderStack.join(" ")
binlog.push(`\`n--\` c${lane} / ${attackerSide} / ${defenderSide}`),
"d" == roleTurn ?
(attackerCardsTrapped.length && binlog.push(`\`n--\` d@ / ${attackerCardsTrapped.join(" ")} x${lane}`),
defenderCardsTrapped.length && binlog.push(`\`n--\` a@ / ${defenderCardsTrapped.join(" ")} xa`))
: (defenderCardsTrapped.length && binlog.push(`\`n--\` a@ / ${defenderCardsTrapped.join(" ")} xa`),
attackerCardsTrapped.length && binlog.push(`\`n--\` d@ / ${attackerCardsTrapped.join(" ")} x${lane}`)),
attackerBouncesDiscarded.length &&
binlog.push(`\`n--\` a? / ${attackerBouncesDiscarded.join(" ")} x${lane}`),
defenderBouncesDiscarded.length && binlog.push(`\`n--\` d? / ${defenderBouncesDiscarded.join(" ")} xa`)
const attackerStackDiscarded =
"a" == roleTurn && cardIsPlayedFaceUp && combatData.attackerStackDiscarded.at(-1) == cardIsPlayedFaceUp ?
`${combatData.attackerStackDiscarded.join(" ")}u`
: combatData.attackerStackDiscarded.join(" ")
if (damageValue) {
const cardsDrawnToDiscard =
combatData.cardsDrawnToDiscard.length ? ` / ${combatData.cardsDrawnToDiscard.join(" ")} xa` : ""
let cardsDrawn
;(cardsDrawn =
combatData.cardsDrawn.length ?
lane < 3 ?
` / ${"X ".repeat(combatData.cardsDrawn.length)}ha0 `
: ` / ${combatData.cardsDrawn.join(" ")} ha0 `
: ""),
binlog.push(
`\`n--\` ${attackerAttackPower} ${defenderAttackPower} ${damageValue} / ${attackerStackDiscarded} xa${cardsDrawnToDiscard}${cardsDrawn}`
)
} else
attackerAttackPower || defenderAttackPower ?
binlog.push(
`\`n--\` ${attackerAttackPower} ${defenderAttackPower} - / ${attackerStackDiscarded} x${lane}`
)
: binlog.push(`\`n--\` 0 0 0 / ${attackerStackDiscarded} xa`)
}
}
export { doMove }