From 8749fad48dfca5d4374e15539b160db28a4ed2dc Mon Sep 17 00:00:00 2001 From: Frans Bongers Date: Fri, 27 Dec 2024 20:45:12 +0100 Subject: refactor selected cards --- land-and-freedom.css | 26 ++++++++++++ land-and-freedom.scss | 26 ++++++++++++ play.html | 3 ++ play.js | 12 +++++- play.ts | 16 ++++++- rules.js | 87 ++++++++++++-------------------------- rules.ts | 114 +++++++++++++++++++++++++------------------------- types.d.ts | 29 +++++-------- 8 files changed, 173 insertions(+), 140 deletions(-) diff --git a/land-and-freedom.css b/land-and-freedom.css index b3ee0a8..4ef7c15 100644 --- a/land-and-freedom.css +++ b/land-and-freedom.css @@ -26,6 +26,32 @@ main { background-image: url(images/map100.png); } } +/* CURRENT CARD */ +#turn_info { + border-bottom: 1px solid black; + overflow: clip; + background-color: gray; + white-space: normal; + padding: 8px 0px; +} + +#turn_info .card { + margin: 0 auto; +} + +@media (max-height: 800px) { + #turn_info { + height: 95px; + } + #turn_info:hover { + height: auto; + } +} +@media (max-height: 600px) { + #turn_info { + display: none; + } +} .game_info { padding: 3px 4px; border-bottom: 1px solid black; diff --git a/land-and-freedom.scss b/land-and-freedom.scss index 4447e4c..cae059a 100644 --- a/land-and-freedom.scss +++ b/land-and-freedom.scss @@ -50,6 +50,32 @@ main { } } +/* CURRENT CARD */ + +#turn_info { + border-bottom: 1px solid black; + // padding: 12px; + overflow: clip; + background-color: gray; + white-space: normal; + padding: 8px 0px; +} + +#turn_info .card { + margin: 0 auto; +} + +@media (max-height: 800px) { + #turn_info { height: 95px; } + #turn_info:hover { height: auto; } +} + +@media (max-height: 600px) { + #turn_info { + display: none; + } +} + .game_info { padding: 3px 4px; border-bottom: 1px solid black; diff --git a/play.html b/play.html index e7b3e7f..d15c6dd 100644 --- a/play.html +++ b/play.html @@ -58,6 +58,9 @@
+
+
+
diff --git a/play.js b/play.js index 356e5a0..ffef09f 100644 --- a/play.js +++ b/play.js @@ -62,6 +62,8 @@ const ui = { }, tracks: document.getElementById('tracks'), hero_points: document.querySelector('#role_Anarchist .role_stat'), + turn_info: document.getElementById('turn_info'), + turn_info_card: document.getElementById('turn_info_card'), year: document.getElementById('year'), blank_markers: [], bonuses: [], @@ -284,7 +286,7 @@ function on_update() { for (let c of view.hand) { ui.cards[c].classList.remove('selected'); ui.hand.appendChild(ui.cards[c]); - if (c === view.selected_card || view.final_bid.includes(c)) { + if (view.selected_cards.includes(c)) { ui.cards[c].classList.add('selected'); } } @@ -324,6 +326,12 @@ function on_update() { ui.tableaus[faction_id].appendChild(ui.cards[c]); } } + if (view.played_card === null) { + ui.turn_info.style.display = 'none'; + } + else { + ui.turn_info_card.setAttribute('data-card-id', view.played_card + ''); + } for (let g = 0; g < view.glory.length; ++g) { ui.glory[g].setAttribute('data-faction-id', view.glory[g]); } @@ -331,9 +339,9 @@ function on_update() { e.classList.toggle('action', is_action(e.my_action, e.my_id)); ui.year.replaceChildren(`Year ${view.year}`); action_button('add_to_front', '+1 to a Front'); + action_button('d_liberty', 'Decrease Liberty'); action_button('soviet_support', 'Soviet Support'); action_button('collectivization', 'Collectivization'); - action_button('d_liberty', 'Decrease Liberty'); action_button('d_collectivization', 'Decrease Collectivization'); action_button('d_foreign_aid', 'Decrease Foreign Aid'); action_button('d_government', 'Decrease Government'); diff --git a/play.ts b/play.ts index af7f825..898982e 100644 --- a/play.ts +++ b/play.ts @@ -76,6 +76,8 @@ const ui = { }, tracks: document.getElementById('tracks'), hero_points: document.querySelector('#role_Anarchist .role_stat'), + turn_info: document.getElementById('turn_info'), + turn_info_card: document.getElementById('turn_info_card'), year: document.getElementById('year'), blank_markers: [], bonuses: [], @@ -373,7 +375,7 @@ function on_update() { for (let c of view.hand) { ui.cards[c].classList.remove('selected'); ui.hand.appendChild(ui.cards[c]); - if (c === view.selected_card || view.final_bid.includes(c)) { + if (view.selected_cards.includes(c)) { ui.cards[c].classList.add('selected'); } } @@ -424,6 +426,15 @@ function on_update() { } } + // ui.turn_info.replaceChildren(); + // console.log('played_card', view.played_card); + // console.log('turn_info', ui.turn_info); + if (view.played_card === null) { + ui.turn_info.style.display = 'none'; + } else { + ui.turn_info_card.setAttribute('data-card-id', view.played_card + ''); + } + for (let g = 0; g < view.glory.length; ++g) { ui.glory[g].setAttribute('data-faction-id', view.glory[g]); } @@ -434,9 +445,10 @@ function on_update() { ui.year.replaceChildren(`Year ${view.year}`); action_button('add_to_front', '+1 to a Front'); + action_button('d_liberty', 'Decrease Liberty'); action_button('soviet_support', 'Soviet Support'); action_button('collectivization', 'Collectivization'); - action_button('d_liberty', 'Decrease Liberty'); + action_button('d_collectivization', 'Decrease Collectivization'); action_button('d_foreign_aid', 'Decrease Foreign Aid'); action_button('d_government', 'Decrease Government'); diff --git a/rules.js b/rules.js index 711573c..1573b05 100644 --- a/rules.js +++ b/rules.js @@ -147,6 +147,7 @@ function start_of_player_turn() { const args = get_active_node_args(); const player = faction_player_map[args.f]; log_h2(player, player); + game.faction_turn = args.f; resolve_active_and_proceed(); } const engine_functions = { @@ -261,19 +262,17 @@ function game_view(state, player) { engine: game.engine, log: game.log, prompt: null, - location: game.location, - selected: game.selected, bag_of_glory: game.bag_of_glory, bonuses: game.bonuses, current_events: game.current_events, - final_bid: game.final_bid[faction_id], fronts: game.fronts, glory: game.glory, hand: game.hands[faction_id], hero_points: game.hero_points, initiative: game.initiative, medallions: game.medallions, - selected_card: game.chosen_cards[faction_id], + played_card: game.played_card, + selected_cards: game.selected_cards[faction_id], tableaus: game.tableaus, tracks: game.tracks, triggered_track_effects: game.triggered_track_effects, @@ -315,11 +314,7 @@ function setup(seed, _scenario, _options) { f: [], }, engine: [], - final_bid: { - a: [], - c: [], - m: [], - }, + faction_turn: null, fronts: { a: { value: -2, @@ -354,11 +349,6 @@ function setup(seed, _scenario, _options) { m: 0, pool: 14, }, - chosen_cards: { - a: null, - c: null, - m: null, - }, initiative: data_1.MODERATES_ID, medallions: { a: [], @@ -366,6 +356,12 @@ function setup(seed, _scenario, _options) { m: [], pool: [], }, + played_card: null, + selected_cards: { + a: [], + c: [], + m: [], + }, tableaus: { a: [], c: [], @@ -383,7 +379,6 @@ function setup(seed, _scenario, _options) { used_medallions: [], turn: 0, year: 0, - state_data: null, }; draw_medallions(); start_year(); @@ -438,7 +433,7 @@ states.activate_icon = { inactive: 'activate an icon', prompt() { view.prompt = 'Choose an icon to activate'; - const c = cards[game.chosen_cards[get_active_faction_id()]]; + const c = cards[game.selected_cards[get_active_faction_id()][0]]; for (const i of c.icons) { gen_action(i); } @@ -774,7 +769,7 @@ states.choose_card = { gen_action_card(c); }, card(c) { - game.chosen_cards[player_faction_map[game.active]] = c; + game.selected_cards[player_faction_map[game.active]].push(c); resolve_active_and_proceed(); }, }; @@ -784,7 +779,7 @@ states.choose_final_bid = { view.prompt = 'Choose a card to add to the Final Bid'; const faction = get_active_faction(); for (let c of game.hands[faction]) { - if (!game.final_bid[faction].includes(c)) { + if (!game.selected_cards[faction].includes(c)) { gen_action_card(c); } } @@ -792,8 +787,8 @@ states.choose_final_bid = { }, card(c) { const faction = get_active_faction(); - game.final_bid[faction].push(c); - if (game.final_bid[faction].length < 3) { + game.selected_cards[faction].push(c); + if (game.selected_cards[faction].length < 3) { next(); } else { @@ -1033,7 +1028,7 @@ states.player_turn = { prompt() { const faction_id = get_faction_id(game.active); const can_spend_hp = game.hero_points[faction_id] > 0; - const can_play_card = game.hands[faction_id].includes(game.chosen_cards[faction_id]); + const can_play_card = game.hands[faction_id].includes(game.selected_cards[faction_id][0]); view.prompt = 'Play a card or spend Hero points'; if (!(can_play_card || can_spend_hp)) { view.prompt = 'End turn'; @@ -1053,11 +1048,14 @@ states.player_turn = { } }, done() { + game.faction_turn = null; + game.played_card = null; resolve_active_and_proceed(true); }, play_for_ap() { const faction_id = get_faction_id(game.active); - const card = game.chosen_cards[faction_id]; + const card = game.selected_cards[faction_id][0]; + game.played_card = card; log_h3(`${game.active} plays ${cards[card].title} for the Action Points`); array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card)); game.tableaus[faction_id].push(card); @@ -1071,7 +1069,8 @@ states.player_turn = { }, play_for_event() { const faction_id = get_faction_id(game.active); - const card = game.chosen_cards[faction_id]; + const card = game.selected_cards[faction_id][0]; + game.played_card = card; array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card)); game.trash[faction_id].push(card); log_h3(`${game.active} plays ${cards[card].title} for the Event`); @@ -1219,7 +1218,6 @@ states.swap_card_tableau_hand = { gen_action_card(c); } }, - card(c) { }, }; states.take_hero_points = { inactive: 'take Hero Points', @@ -1550,7 +1548,7 @@ function resolve_final_bid() { let winners = []; for (const f of get_player_order()) { let player_bid = 0; - for (const c of game.final_bid[f]) { + for (const c of game.selected_cards[f]) { player_bid += cards[c].strength; } log(`${faction_player_map[f]} bids ${player_bid}`); @@ -1561,9 +1559,9 @@ function resolve_final_bid() { highest_bid = player_bid; winners = [f]; } - game.hands[f] = game.hands[f].filter((c) => !game.final_bid[f].includes(c)); - game.discard[f].concat(game.final_bid[f]); - game.final_bid[f] = []; + game.hands[f] = game.hands[f].filter((c) => !game.selected_cards[f].includes(c)); + game.discard[f].concat(game.selected_cards[f]); + game.selected_cards[f] = []; } if (winners.length === 1) { win_final_bid(winners[0]); @@ -2120,39 +2118,6 @@ function array_insert(array, index, item) { array[i] = array[i - 1]; array[index] = item; } -function set_clear(set) { - set.length = 0; -} -function set_has(set, item) { - let a = 0; - let b = set.length - 1; - while (a <= b) { - const m = (a + b) >> 1; - const x = set[m]; - if (item < x) - b = m - 1; - else if (item > x) - a = m + 1; - else - return true; - } - return false; -} -function set_add(set, item) { - let a = 0; - let b = set.length - 1; - while (a <= b) { - const m = (a + b) >> 1; - const x = set[m]; - if (item < x) - b = m - 1; - else if (item > x) - a = m + 1; - else - return set; - } - return array_insert(set, a, item); -} function set_delete(set, item) { let a = 0; let b = set.length - 1; diff --git a/rules.ts b/rules.ts index 98a6806..7b49f1b 100644 --- a/rules.ts +++ b/rules.ts @@ -283,6 +283,7 @@ function start_of_player_turn() { const args = get_active_node_args(); const player = faction_player_map[args.f]; log_h2(player, player); + game.faction_turn = args.f; resolve_active_and_proceed(); } @@ -435,19 +436,17 @@ function game_view(state: Game, player: Player) { engine: game.engine, // TODO: remove log: game.log, prompt: null, - location: game.location, - selected: game.selected, bag_of_glory: game.bag_of_glory, bonuses: game.bonuses, current_events: game.current_events, - final_bid: game.final_bid[faction_id], fronts: game.fronts, glory: game.glory, hand: game.hands[faction_id], hero_points: game.hero_points, initiative: game.initiative, medallions: game.medallions, - selected_card: game.chosen_cards[faction_id], + played_card: game.played_card, + selected_cards: game.selected_cards[faction_id], tableaus: game.tableaus, tracks: game.tracks, triggered_track_effects: game.triggered_track_effects, @@ -493,11 +492,7 @@ export function setup(seed: number, _scenario: string, _options: unknown) { f: [], }, engine: [], - final_bid: { - a: [], - c: [], - m: [], - }, + faction_turn: null, fronts: { a: { value: -2, @@ -532,11 +527,6 @@ export function setup(seed: number, _scenario: string, _options: unknown) { m: 0, pool: 14, }, - chosen_cards: { - a: null, - c: null, - m: null, - }, initiative: MODERATES_ID, medallions: { a: [], @@ -544,6 +534,12 @@ export function setup(seed: number, _scenario: string, _options: unknown) { m: [], pool: [], }, + played_card: null, + selected_cards: { + a: [], + c: [], + m: [], + }, tableaus: { a: [], c: [], @@ -561,7 +557,6 @@ export function setup(seed: number, _scenario: string, _options: unknown) { used_medallions: [], turn: 0, year: 0, - state_data: null, }; draw_medallions(); @@ -639,7 +634,7 @@ states.activate_icon = { inactive: 'activate an icon', prompt() { view.prompt = 'Choose an icon to activate'; - const c = cards[game.chosen_cards[get_active_faction_id()]] as PlayerCard; + const c = cards[game.selected_cards[get_active_faction_id()][0]] as PlayerCard; for (const i of c.icons) { gen_action(i); } @@ -987,7 +982,7 @@ states.choose_card = { for (let c of hand) gen_action_card(c); }, card(c: CardId) { - game.chosen_cards[player_faction_map[game.active]] = c; + game.selected_cards[player_faction_map[game.active]].push(c); resolve_active_and_proceed(); }, }; @@ -998,7 +993,7 @@ states.choose_final_bid = { view.prompt = 'Choose a card to add to the Final Bid'; const faction = get_active_faction(); for (let c of game.hands[faction]) { - if (!game.final_bid[faction].includes(c)) { + if (!game.selected_cards[faction].includes(c)) { gen_action_card(c); } } @@ -1006,8 +1001,8 @@ states.choose_final_bid = { }, card(c: CardId) { const faction = get_active_faction(); - game.final_bid[faction].push(c); - if (game.final_bid[faction].length < 3) { + game.selected_cards[faction].push(c); + if (game.selected_cards[faction].length < 3) { next(); } else { resolve_active_and_proceed(); @@ -1272,8 +1267,9 @@ states.player_turn = { prompt() { const faction_id = get_faction_id(game.active as Player); const can_spend_hp = game.hero_points[faction_id] > 0; + // TODO: refactor to check selected_cards.length const can_play_card = game.hands[faction_id].includes( - game.chosen_cards[faction_id] + game.selected_cards[faction_id][0] ); view.prompt = 'Play a card or spend Hero points'; if (!(can_play_card || can_spend_hp)) { @@ -1295,11 +1291,14 @@ states.player_turn = { } }, done() { + game.faction_turn = null; + game.played_card = null; resolve_active_and_proceed(true); }, play_for_ap() { const faction_id = get_faction_id(game.active as Player); - const card = game.chosen_cards[faction_id]; + const card = game.selected_cards[faction_id][0]; + game.played_card = card; log_h3(`${game.active} plays ${cards[card].title} for the Action Points`); array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card)); game.tableaus[faction_id].push(card); @@ -1315,7 +1314,8 @@ states.player_turn = { }, play_for_event() { const faction_id = get_faction_id(game.active as Player); - const card = game.chosen_cards[faction_id]; + const card = game.selected_cards[faction_id][0]; + game.played_card = card; array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card)); game.trash[faction_id].push(card); log_h3(`${game.active} plays ${cards[card].title} for the Event`); @@ -1497,7 +1497,7 @@ states.swap_card_tableau_hand = { gen_action_card(c); } }, - card(c: CardId) {}, + // card(c: CardId) {}, }; // TODO: implement, card 12 + card 32 + card 44 @@ -1929,7 +1929,7 @@ function resolve_final_bid() { let winners: FactionId[] = []; for (const f of get_player_order()) { let player_bid = 0; - for (const c of game.final_bid[f]) { + for (const c of game.selected_cards[f]) { player_bid += (cards[c] as PlayerCard).strength; } log(`${faction_player_map[f]} bids ${player_bid}`); @@ -1939,9 +1939,9 @@ function resolve_final_bid() { highest_bid = player_bid; winners = [f]; } - game.hands[f] = game.hands[f].filter((c) => !game.final_bid[f].includes(c)); - game.discard[f].concat(game.final_bid[f]); - game.final_bid[f] = []; + game.hands[f] = game.hands[f].filter((c) => !game.selected_cards[f].includes(c)); + game.discard[f].concat(game.selected_cards[f]); + game.selected_cards[f] = []; } if (winners.length === 1) { @@ -2731,37 +2731,37 @@ function array_insert(array: T[], index: number, item: T) { // Set as plain sorted array -function set_clear(set: T[]) { - // eslint-disable-line @typescript-eslint/no-unused-vars - set.length = 0; -} +// function set_clear(set: T[]) { +// // eslint-disable-line @typescript-eslint/no-unused-vars +// set.length = 0; +// } -function set_has(set: T[], item: T) { - let a = 0; - let b = set.length - 1; - while (a <= b) { - const m = (a + b) >> 1; - const x = set[m]; - if (item < x) b = m - 1; - else if (item > x) a = m + 1; - else return true; - } - return false; -} +// function set_has(set: T[], item: T) { +// let a = 0; +// let b = set.length - 1; +// while (a <= b) { +// const m = (a + b) >> 1; +// const x = set[m]; +// if (item < x) b = m - 1; +// else if (item > x) a = m + 1; +// else return true; +// } +// return false; +// } -function set_add(set: T[], item: T) { - // eslint-disable-line @typescript-eslint/no-unused-vars - let a = 0; - let b = set.length - 1; - while (a <= b) { - const m = (a + b) >> 1; - const x = set[m]; - if (item < x) b = m - 1; - else if (item > x) a = m + 1; - else return set; - } - return array_insert(set, a, item); -} +// function set_add(set: T[], item: T) { +// // eslint-disable-line @typescript-eslint/no-unused-vars +// let a = 0; +// let b = set.length - 1; +// while (a <= b) { +// const m = (a + b) >> 1; +// const x = set[m]; +// if (item < x) b = m - 1; +// else if (item > x) a = m + 1; +// else return set; +// } +// return array_insert(set, a, item); +// } // function set_delete(set: T[], item: T) { // let a = 0; diff --git a/types.d.ts b/types.d.ts index 33e8456..b2b7aae 100644 --- a/types.d.ts +++ b/types.d.ts @@ -25,6 +25,8 @@ export interface Game { seed: number; state: string | null; undo: Game[]; + result?: string; + victory?: string; // Game specific active_abilities: number[]; turn: number; @@ -32,11 +34,13 @@ export interface Game { bag_of_glory: FactionId[]; blank_markers: number[][]; bonuses: number[]; - chosen_cards: Record; current_events: CardId[]; discard: Record; engine: EngineNode[]; - final_bid: Record; + // Set to faction whos turn it is or null if not player turn + // Used to determine who can spend Hero Points. Could be the case + // a faction is active in another factions turn. + faction_turn: FactionId | null; fronts: { a: Front; m: Front; @@ -48,22 +52,13 @@ export interface Game { hero_points: Record; initiative: FactionId; medallions: Record & { pool: Array }; + played_card: CardId | null; + selected_cards: Record; tableaus: Record; tracks: number[]; - trash: Record; + trash: Record; triggered_track_effects: number[]; used_medallions: number[]; - - result?: string; - victory?: string; - - location?: string; - selected?: string; - - state_data: any; - // played_card: CardId - - // turn: Turn } export interface View { @@ -73,20 +68,18 @@ export interface View { prompt: string | null; actions?: any; victory?: string; - location?: string; - selected?: string; - selected_card: CardId | null; + selected_cards: CardId[]; bag_of_glory: Game['bag_of_glory']; bonuses: Game['bonuses']; current_events: CardId[]; - final_bid: CardId[]; fronts: Game['fronts']; glory: Game['glory']; hand: CardId[]; hero_points: Game['hero_points']; initiative: Game['initiative']; medallions: Game['medallions']; + played_card: Game['played_card']; tableaus: Game['tableaus']; tracks: number[]; triggered_track_effects: Game['triggered_track_effects']; -- cgit v1.2.3