diff options
author | Frans Bongers <fransbongers@franss-mbp.home> | 2024-12-27 20:45:12 +0100 |
---|---|---|
committer | Frans Bongers <fransbongers@franss-mbp.home> | 2024-12-27 20:45:12 +0100 |
commit | 8749fad48dfca5d4374e15539b160db28a4ed2dc (patch) | |
tree | 12c3b418a99cdb15285d3cfebf99120b96dc7af9 | |
parent | 9d0630a33e0358f943e68008823f355bceb71be1 (diff) | |
download | land-and-freedom-8749fad48dfca5d4374e15539b160db28a4ed2dc.tar.gz |
refactor selected cards
-rw-r--r-- | land-and-freedom.css | 26 | ||||
-rw-r--r-- | land-and-freedom.scss | 26 | ||||
-rw-r--r-- | play.html | 3 | ||||
-rw-r--r-- | play.js | 12 | ||||
-rw-r--r-- | play.ts | 16 | ||||
-rw-r--r-- | rules.js | 87 | ||||
-rw-r--r-- | rules.ts | 114 | ||||
-rw-r--r-- | 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; @@ -58,6 +58,9 @@ <div class="role_medallions"></div> <div class="role_info"></div> </div> + <div id="turn_info"> + <div id="turn_info_card" class="card"></div> + </div> </div> <div id="log"></div> </aside> @@ -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'); @@ -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'); @@ -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; @@ -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<T>(array: T[], index: number, item: T) { // Set as plain sorted array -function set_clear<T>(set: T[]) { - // eslint-disable-line @typescript-eslint/no-unused-vars - set.length = 0; -} +// function set_clear<T>(set: T[]) { +// // eslint-disable-line @typescript-eslint/no-unused-vars +// set.length = 0; +// } -function set_has<T>(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<T>(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<T>(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<T>(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<T>(set: T[], item: T) { // let a = 0; @@ -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<FactionId, CardId>; current_events: CardId[]; discard: Record<FactionId | 'f', number[]>; engine: EngineNode[]; - final_bid: Record<FactionId, CardId[]>; + // 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<FactionId | 'pool', number>; initiative: FactionId; medallions: Record<FactionId, number[]> & { pool: Array<number | null> }; + played_card: CardId | null; + selected_cards: Record<FactionId, CardId[]>; tableaus: Record<FactionId, CardId[]>; tracks: number[]; - trash: Record<FactionId, number[]>; + trash: Record<FactionId, CardId[]>; 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']; |