summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-12-11 14:39:55 +0100
committerTor Andersson <tor@ccxvii.net>2023-12-11 20:26:07 +0100
commitf3aa1d4862a6f85a201ce51c24c2e4f1b1dbdbdc (patch)
tree4e3cb4ce519d9fe448df46d708e1e1a251098cdc
parent6da83fe13cc580770a4a556bac9d53447da404b5 (diff)
downloadvotes-for-women-f3aa1d4862a6f85a201ce51c24c2e4f1b1dbdbdc.tar.gz
Add temporary "drawn" and "deck" panel displays.
Use this to show drawn cards while choosing cards for events that draw X cards, play one, and put the rest on top / bottom. Use stack of "draw" arrays in VM to handle nested events. NOTE: This is not necessary now, but will be if we change the Winning Moves event to play its event immediately.
-rw-r--r--play.css21
-rw-r--r--play.html12
-rw-r--r--play.js32
-rw-r--r--rules.js197
4 files changed, 190 insertions, 72 deletions
diff --git a/play.css b/play.css
index 12045bb..4d8a7ce 100644
--- a/play.css
+++ b/play.css
@@ -181,9 +181,10 @@ body.Opposition header.your_turn { background-color: var(--opp-75); }
body.Suffragist #hand_header { background-color: var(--suf-75); }
body.Opposition #hand_header { background-color: var(--opp-75); }
-
-body.Suffragist #set_aside_header { background-color: var(--suf-85); }
-body.Opposition #set_aside_header { background-color: var(--opp-85); }
+body.Suffragist #drawn_header { background-color: var(--suf-85); }
+body.Opposition #drawn_header { background-color: var(--opp-85); }
+body.Suffragist #deck_header { background-color: var(--suf-85); }
+body.Opposition #deck_header { background-color: var(--opp-85); }
section {
margin-top: 24px;
@@ -194,7 +195,7 @@ section {
.panel {
padding: 3px;
- font-family: TiffanyGothicCC;
+ font-family: TiffanyGothicCC, "Source Sans";
background-color: hsl(43, 52%, 88%);
box-shadow: 1px 2px 4px #0004;
width: fit-content;
@@ -222,6 +223,8 @@ section {
}
#hand { grid-template-columns: repeat(4, 250px); grid-template-rows: repeat(2, 350px); }
+#deck { grid-template-columns: repeat(4, 250px) }
+#drawn { grid-template-columns: repeat(4, 250px) }
#set_aside { grid-template-columns: repeat(4, 250px) }
#support_claimed { grid-template-columns: repeat(3, 250px) }
#opposition_claimed { grid-template-columns: repeat(3, 250px) }
@@ -235,11 +238,13 @@ section {
#opposition_claimed_panel { margin-left: 0; grid-column: span 1; }
}
-@media (min-width: 1590px) { #set_aside { grid-template-columns: repeat(5, 250px) } }
-@media (min-width: 1840px) { #set_aside { grid-template-columns: repeat(6, 250px) } }
+@media (min-width: 1590px) { #deck, #drawn, #set_aside { grid-template-columns: repeat(5, 250px) } }
+@media (min-width: 1840px) { #deck, #drawn, #set_aside { grid-template-columns: repeat(6, 250px) } }
@media (min-width: 2120px) {
#hand { grid-template-columns: repeat(7, 250px); grid-template-rows: repeat(1, 350px); }
+ #deck { grid-template-columns: repeat(7, 250px); }
+ #drawn { grid-template-columns: repeat(7, 250px); }
#set_aside { grid-template-columns: repeat(7, 250px); }
#support_claimed { grid-template-columns: repeat(3, 250px) }
#opposition_claimed { grid-template-columns: repeat(3, 250px) }
@@ -571,6 +576,8 @@ div.button_box .button {
.card_support_back{background-image:url(cards.1x/support_01.jpg)}
.card_opposition_back{background-image:url(cards.1x/opposition_01.jpg)}
+.card_strategy_back{background-image:url(cards.1x/strategy_01.jpg)}
+.card_states_back{background-image:url(cards.1x/states_01.jpg)}
.card_1{background-image:url(cards.1x/support_02.jpg)}
.card_2{background-image:url(cards.1x/support_03.jpg)}
.card_3{background-image:url(cards.1x/support_04.jpg)}
@@ -703,6 +710,8 @@ div.button_box .button {
@media (min-resolution: 97dpi) {
.card_support_back{background-image:url(cards.2x/support_01.jpg)}
.card_opposition_back{background-image:url(cards.2x/opposition_01.jpg)}
+.card_strategy_back{background-image:url(cards.2x/strategy_01.jpg)}
+.card_states_back{background-image:url(cards.2x/states_01.jpg)}
.card_1{background-image:url(cards.2x/support_02.jpg)}
.card_2{background-image:url(cards.2x/support_03.jpg)}
.card_3{background-image:url(cards.2x/support_04.jpg)}
diff --git a/play.html b/play.html
index 2a50af9..1e5d0f2 100644
--- a/play.html
+++ b/play.html
@@ -609,6 +609,18 @@ c5 3 13 7 17 8 8 2 9 3 11 12 1 5 5 12 8 16 5 8 5 8 3 22 l-3 14 -30 -1 c-35
</div>
</div>
+ <div id="drawn_panel" class="panel hide">
+ <div id="drawn_header" class="panel_header">Drawn Cards</div>
+ <div id="drawn" class="panel_body"></div>
+ </div>
+ </div>
+
+ <div id="deck_panel" class="panel hide">
+ <div id="deck_header" class="panel_header">Top &#x25c0; Draw Deck &#x25b6; Bottom</div>
+ <div id="deck" class="panel_body"></div>
+ </div>
+ </div>
+
<div id="set_aside_panel" class="panel hide">
<div id="set_aside_header" class="panel_header">Set-aside Cards</div>
<div id="set_aside" class="panel_body"></div>
diff --git a/play.js b/play.js
index 40086ed..6493559 100644
--- a/play.js
+++ b/play.js
@@ -72,10 +72,15 @@ const US_STATES = [
const region_count = 6
const us_states_count = region_count * 8
-const card_count = 128
+const last_card = 128
const green_check_count = 36
const red_x_count = 13
+const SUF_CARD_BACK = last_card + 1
+const OPP_CARD_BACK = last_card + 2
+const STRATEGY_CARD_BACK = last_card + 3
+const STATE_CARD_BACK = last_card + 4
+
let ui = {
favicon: document.getElementById("favicon"),
status: document.getElementById("status"),
@@ -454,7 +459,7 @@ function build_user_interface() {
})
}
- for (let c = 1; c <= card_count; ++c) {
+ for (let c = 1; c <= last_card; ++c) {
elt = ui.cards[c] = create("div", {
className: `card card_${c} ${CARDS[c].type}`,
my_card: c,
@@ -463,6 +468,11 @@ function build_user_interface() {
elt.addEventListener("click", on_click_card)
}
+ ui.cards[SUF_CARD_BACK] = create("div", { className: "card card_support_back" })
+ ui.cards[OPP_CARD_BACK] = create("div", { className: "card card_opposition_back" })
+ ui.cards[STRATEGY_CARD_BACK] = create("div", { className: "card card_strategy_back" })
+ ui.cards[STATE_CARD_BACK] = create("div", { className: "card card_states_back" })
+
for (let r = 1; r <= region_count; ++r) {
let region_name_css = REGION_NAMES[r].replaceAll(' & ', '')
elt = ui.regions[r] = document.querySelector(`#map #${region_name_css}`)
@@ -718,6 +728,8 @@ function on_update() { // eslint-disable-line no-unused-vars
}
document.getElementById("hand").replaceChildren()
+ document.getElementById("deck").replaceChildren()
+ document.getElementById("drawn").replaceChildren()
document.getElementById("set_aside").replaceChildren()
document.getElementById("support_claimed").replaceChildren()
document.getElementById("opposition_claimed").replaceChildren()
@@ -732,6 +744,22 @@ function on_update() { // eslint-disable-line no-unused-vars
document.getElementById("hand_panel").classList.add("hide")
}
+ if (view.drawn) {
+ document.getElementById("drawn_panel").classList.remove("hide")
+ for (let c of view.drawn)
+ document.getElementById("drawn").appendChild(ui.cards[c])
+ } else {
+ document.getElementById("drawn_panel").classList.add("hide")
+ }
+
+ if (view.deck) {
+ document.getElementById("deck_panel").classList.remove("hide")
+ for (let c of view.deck)
+ document.getElementById("deck").appendChild(ui.cards[c])
+ } else {
+ document.getElementById("deck_panel").classList.add("hide")
+ }
+
if (view.set_aside.length) {
document.getElementById("set_aside_panel").classList.remove("hide")
for (let c of view.set_aside)
diff --git a/rules.js b/rules.js
index 32d007d..5694fe5 100644
--- a/rules.js
+++ b/rules.js
@@ -17,6 +17,7 @@ const first_strategy_card = 105
const last_strategy_card = 116
const first_states_card = 117
const last_states_card = 128
+const last_card = last_states_card
const MAX_SUPPORT_BUTTONS = 12
const MAX_OPPOSITION_BUTTONS = 6
@@ -24,6 +25,11 @@ const MAX_OPPOSITION_BUTTONS = 6
const GREEN_CHECK_VICTORY = 36
const RED_X_VICTORY = 13
+const SUF_CARD_BACK = last_card + 1
+const OPP_CARD_BACK = last_card + 2
+const STRATEGY_CARD_BACK = last_card + 3
+const STATE_CARD_BACK = last_card + 4
+
const WEST = 1
const PLAINS = 2
const SOUTH = 3
@@ -782,6 +788,9 @@ exports.view = function(state, player) {
view.red_xs = count_red_xs()
}
+ if (player === game.active && game.vm && game.vm.draw)
+ view.drawn = game.vm.draw
+
if (player === SUF) {
view.hand = game.support_hand
view.set_aside = game.support_set_aside
@@ -2373,14 +2382,33 @@ function vm_counter_strat() {
game.state = "vm_counter_strat"
}
+function start_vm_draw() {
+ if (game.vm.draw) {
+ if (!game.vm.save_draw)
+ game.vm.save_draw = []
+ game.vm.save_draw.push(game.vm.draw)
+ }
+ game.vm.draw = []
+}
+
+function end_vm_draw() {
+ if (game.vm.save_draw) {
+ game.vm.draw = game.vm.save_draw.pop()
+ if (game.vm.save_draw.length === 0)
+ delete game.vm.save_draw
+ } else {
+ delete game.vm.draw
+ }
+}
+
function vm_draw_2_play_1_event() {
vm_assert_argcount(0)
clear_undo()
- game.vm.draw = []
+
+ start_vm_draw()
for (let i = 0; i < 2; ++i) {
let card = draw_card(player_deck())
game.vm.draw.push(card)
- player_hand().push(card)
}
log(`${game.active} drew 2 cards.`)
@@ -3034,104 +3062,145 @@ states.vm_draw_2_play_1_event = {
card(c) {
push_undo()
end_play_card(game.played_card)
+
let other = game.vm.draw.find(x => x !== c)
- discard_card_from_hand(other)
log(`Discarded C${other}.`)
- delete game.vm.draw
+
+ end_vm_draw()
+
+ // move to hand to play
+ player_hand().push(c)
play_card_event(c)
},
skip() {
log("None of the cards could be played for their event.")
- for (let c of game.vm.draw) {
- discard_card_from_hand(c)
- }
- delete game.vm.draw
+ for (let c of game.vm.draw)
+ log(`Discarded C${c}.`)
+ end_vm_draw()
vm_next()
}
}
function goto_vm_place_any_on_top_of_draw() {
clear_undo()
- game.vm.draw = []
- game.selected_cards = []
+ start_vm_draw()
+ game.vm.on_top = []
+ game.vm.on_bottom = []
let draw_count = Math.min(player_deck().length, 6)
for (let i = 0; i < draw_count; ++i) {
let card = draw_card(player_deck())
game.vm.draw.push(card)
- player_hand().push(card)
}
log(`${game.active} drew ${draw_count} cards.`)
- game.state = "vm_place_any_on_top_of_draw"
+ if (game.vm.play_one < 0)
+ game.state = "vm_place_any_on_top_of_draw_play"
+ else
+ game.state = "vm_place_any_on_top_of_draw"
}
-states.vm_place_any_on_top_of_draw = {
- inactive: "choose which cards to put on top of their Draw Deck.",
+states.vm_place_any_on_top_of_draw_play = {
+ inactive: "choose which card to play for its event.",
prompt() {
let can_play = false
- if (game.vm.play_one && !game.selected_cards.length) {
- event_prompt("Select which card to play as Event.")
- for (let c of game.vm.draw) {
- if (can_play_event(c)) {
- gen_action_card(c)
- can_play = true
- }
- }
- } else {
- event_prompt("Select which cards to put on top of your Draw Deck. The rest go to the bottom.")
- if (game.vm.play_one) {
- let event_card_name = CARDS[game.selected_cards[0]].name
- view.prompt += ` Will play "${event_card_name}" for its event.`
- }
- for (let c of game.vm.draw) {
- if (!game.selected_cards.includes(c))
- gen_action_card(c)
+ event_prompt("Select which card to play as Event.")
+ for (let c of game.vm.draw) {
+ if (can_play_event(c)) {
+ gen_action_card(c)
+ can_play = true
}
}
-
-
- if (!game.vm.play_one || game.selected_cards.length) {
- gen_action("done")
- } else if (!can_play) {
+ if (!can_play) {
gen_action("skip")
}
},
card(c) {
push_undo()
- game.selected_cards.push(c)
+ array_remove_item(game.vm.draw, c)
+ player_hand().push(c)
+ game.vm.play_one = c
+ game.state = "vm_place_any_on_top_of_draw"
},
skip() {
log("None of the drawn cards could be played for their Event.")
- delete game.vm.play_one
+ game.vm.play_one = -1
+ game.state = "vm_place_any_on_top_of_draw"
+ },
+}
+
+states.vm_place_any_on_top_of_draw = {
+ inactive: "choose which cards to place on top of their Draw Deck.",
+ prompt() {
+ event_prompt("Select which cards to place on TOP of your Draw Deck.")
+ if (game.vm.play_one >= 0)
+ view.prompt += ` Will play "${CARDS[game.vm.play_one].name}" for its event.`
+
+ // show cards going on top
+ if (game.active === OPP)
+ view.deck = [ ...game.vm.on_top, OPP_CARD_BACK ]
+ else
+ view.deck = [ ...game.vm.on_top, SUF_CARD_BACK ]
+
+ for (let c of game.vm.draw)
+ gen_action_card(c)
+
+ gen_action("next")
+ },
+ card(c) {
+ push_undo()
+ array_remove_item(game.vm.draw, c)
+ game.vm.on_top.unshift(c)
+ },
+ next() {
+ if (game.vm.draw.length > 0)
+ game.state = "vm_place_any_on_bottom_of_draw"
+ else
+ end_vm_place_any_on_top_of_draw()
+ },
+}
+
+states.vm_place_any_on_bottom_of_draw = {
+ inactive: "choose which cards to place at the bottom of their Draw Deck.",
+ prompt() {
+ event_prompt("Place the remaining cards at the BOTTOM of your Draw Deck.")
+ if (game.vm.play_one >= 0)
+ view.prompt += ` Will play "${CARDS[game.vm.play_one].name}" for its event.`
+
+ // show cards going at the bottom
+ if (game.active === OPP)
+ view.deck = [ ...game.vm.on_top, OPP_CARD_BACK, ...game.vm.on_bottom ]
+ else
+ view.deck = [ ...game.vm.on_top, SUF_CARD_BACK, ...game.vm.on_bottom ]
+
+ for (let c of game.vm.draw)
+ gen_action_card(c)
+
+ if (game.vm.draw.length === 0)
+ gen_action("done")
+ },
+ card(c) {
+ push_undo()
+ array_remove_item(game.vm.draw, c)
+ game.vm.on_bottom.push(c)
},
done() {
- // first selected card is the to be played event card
- if (game.vm.play_one)
- game.vm.play_one = game.selected_cards.shift()
- log(`${game.active} selected ${pluralize(game.selected_cards.length, 'card')} to put on top of their Draw Deck.`)
-
- // first selected card goes on top.
- for (let c of game.selected_cards.reverse()) {
- player_deck().push(c)
- array_remove_item(game.vm.draw, c)
- array_remove_item(player_hand(), c)
- }
- // rest goes to the bottom, except for the to be played event card
- for (let c of game.vm.draw) {
- if (c !== game.vm.play_one) {
- player_deck().unshift(c)
- array_remove_item(player_hand(), c)
- }
- }
+ end_vm_place_any_on_top_of_draw()
+ },
+}
- delete game.vm.draw
- game.selected_cards = []
- if (game.vm.play_one) {
- end_play_card(game.played_card)
- play_card_event(game.vm.play_one)
- } else {
- vm_next()
- }
+function end_vm_place_any_on_top_of_draw() {
+ log(`${game.active} placed ${pluralize(game.vm.on_top.length, 'card')} on top and ${pluralize(game.vm.on_bottom.length, 'card')} at the bottom of their Draw Deck.`)
+ while (game.vm.on_top.length > 0)
+ player_deck().push(game.vm.on_top.pop())
+ for (let c of game.vm.on_bottom)
+ player_deck().unshift(c)
+ end_vm_draw()
+
+ if (game.vm.play_one >= 0) {
+ end_play_card(game.played_card)
+ play_card_event(game.vm.play_one)
+ } else {
+ vm_next()
}
}