diff options
-rw-r--r-- | play.css | 31 | ||||
-rw-r--r-- | play.js | 32 | ||||
-rw-r--r-- | rules.js | 167 |
3 files changed, 204 insertions, 26 deletions
@@ -73,6 +73,37 @@ body.Communist header.your_turn { background-color: hsl(355, 70%, 75%); } #log .card_name:hover { text-decoration: underline; } #log .space_tip:hover { cursor: pointer; text-decoration: underline; } +#log .icon { + display: inline-block; + vertical-align: -2px; + width: 12px; + height: 12px; + box-shadow: none; + border: none; + background-size: contain; + background-position: center; + background-repeat: no-repeat; +} + +#log .com_nc { background-image: url(images/SVd_blank.gif);} +#log .com_c {background-image: url(images/SV_blank.gif);} +#log .dem_nc { background-image: url(images/USd_blank.gif);} +#log .dem_c {background-image: url(images/favicon_dem.svg);} + +#log .number { + display: inline-block; + margin: 0; + text-indent: 0; + text-align: center; + width: 12px; + height: 12px; + line-height: 12px; + border: 1px solid #444; +} + +#log .number.d_tst { background-color: hsl(206, 85%, 80%); } +#log .number.c_tst { background-color: hsl(355, 70%, 80%); } + /* MAP */ #mapwrap { @@ -863,6 +863,32 @@ function sub_die(match) { return die[match] || match } +function sub_icon(match) { + console.log('sub_icon called, match', match) + return ICONS[match] || match +} + +function sub_arrow(match) { + return '<span>→</span>' +} + +const ICONS = { + '£CC': '<span class="icon com_c"></span>', + '£CU': '<span class="icon com_nc"></span>', + '£DC': '<span class="icon dem_c"></span>', + '£DU': '<span class="icon dem_nc"></span>', + '.dT5': '<span class="number d_tst">5</span>', + '.dT6': '<span class="number d_tst">6</span>', + '.dT7': '<span class="number d_tst">7</span>', + '.dT8': '<span class="number d_tst">8</span>', + '.dT9': '<span class="number d_tst">9</span>', + '.dT10': '<span class="number d_tst">10</span>', + '.cT5': '<span class="number c_tst">5</span>', + '.cT6': '<span class="number c_tst">6</span>', + '.cT7': '<span class="number c_tst">7</span>', + '.cT8': '<span class="number c_tst">8</span>' +} + const die = { D1: '<span class="die white d1"></span>', D2: '<span class="die white d2"></span>', @@ -889,7 +915,7 @@ function on_log(text, ix) { p.className = "i" } - + console.log('text', text) text = text.replace(/_/g, " ") text = text.replace(/C(\d+)/g, sub_card_name) @@ -897,6 +923,10 @@ function on_log(text, ix) { text = text.replace(/V(\d+)/g, sub_power_card_value) text = text.replace(/%(\d+)/g, sub_space_name) text = text.replace(/D[1-6]/g, sub_die) + text = text.replace(/£[CD][CU]\b/g, sub_icon) + text = text.replace(/\.cT(\d+)/g, sub_icon) + text = text.replace(/\.dT(\d+)/g, sub_icon) + text = text.replace(/.to/g, sub_arrow) if (text.match(/^\.h1/)) { text = text.substring(4) @@ -2213,7 +2213,9 @@ states.stasi_resolve_common_european_home = { function add_infl(space, ops) { push_undo() - log_summary(`£ in %${space}`) + //log_summary(`£ in %${space}`) + + let starting_control = check_control(space) // If AHBR - check AHBR conditions if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) { @@ -2244,9 +2246,25 @@ function add_infl(space, ops) { // Update influence values if (game.active === COM) { game.comInfl[space]++ + /*if (check_com_control(space)) + logi(`£CC in %${space}`) + else + logi(`£CU in %${space}`) */ } else { game.demInfl[space]++ + /*if (check_dem_control(space)) + logi(`£DC in %${space}`) + else + logi(`£DU in %${space}`)*/ } + + let end_control = check_control(space) + + console.log('starting_control', starting_control, 'end_control', end_control) + + log_summary('£ in %' + space + get_icons(starting_control,end_control)) + + console.log('influence add, game.summary', game.summary) check_tyrant() // Check Austria Hungary Border Reopened is true and condition has been met @@ -2286,7 +2304,8 @@ function add_infl(space, ops) { function remove_infl(space, ops) { push_undo() - log_summary(`£ in %${space}`) + //log_summary(`£ in %${space}`) + let starting_control = check_control(space) if (game.remove_opponent_infl === true) { if (game.active === COM) { @@ -2300,7 +2319,6 @@ function remove_infl(space, ops) { game.valid_spaces = game.valid_spaces.filter(id => id !== space) } } - check_tyrant() } else { if (game.active === COM) { @@ -2314,8 +2332,10 @@ function remove_infl(space, ops) { game.valid_spaces = game.valid_spaces.filter(id => id !== space) } } - check_tyrant() } + let end_control = check_control(space) + log_summary('£ from %' + space + get_icons(starting_control,end_control)) + check_tyrant() game[ops]-- if (game.vm_influence_added && game.vm_influence_added[space] >= 0) { game.vm_influence_added[space]++ @@ -2330,6 +2350,7 @@ function do_sc(space) { let tear_gas_start = game.persistent_events.includes(C_TEAR_GAS) let the_wall_start = game.persistent_events.includes(C_THE_WALL) log(`%${space}:`) + let starting_control = check_control(space) let roll = roll_d6() // Check for The Wall @@ -2451,7 +2472,6 @@ function do_sc(space) { logii(`-${stability*2} (stability * 2)`) const change_infl = Math.max(0, roll - stability*2) if (change_infl > 0) { - logi(`Change: ${change_infl} SP`) if (game.active === DEM) { if (change_infl > game.comInfl[space]) { const residual = change_infl - game.comInfl[space] @@ -2475,6 +2495,8 @@ function do_sc(space) { game.valid_spaces = game.valid_spaces.filter(id => id !== space) } } + let end_control = check_control(space) + logi('Change: ' + change_infl + ' SP' + get_icons(starting_control, end_control)) check_tyrant_sc() } else { @@ -2703,7 +2725,7 @@ function count_adj(space_id) { return {dem_adj, com_adj} } -function check_control(space_id) { +function is_controlled(space_id) { if ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) { return true } else if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) { @@ -2739,6 +2761,53 @@ function check_com_control(space_id) { } } +function check_control(space) { + if (check_dem_control(space)) + return DEM + else if (check_com_control(space)) + return COM + else if (game.demInfl[space] > game.comInfl[space]) + return 'd_ahead' + else if (game.comInfl[space] > game.demInfl[space]) + return 'c_ahead' + else + return "none" +} + +function get_icons(starting_control, end_control) { + console.log('starting_control', starting_control, 'end_control', end_control) + if (starting_control !== end_control) { + console.log('in long bit') + if (starting_control === DEM && end_control === COM) + return ' (£DC .to £CC)' + else if (starting_control === COM && end_control === COM) + return ' (£CC .to £DC)' + else if (starting_control === 'd_ahead' && end_control === DEM) + return ' (£DU .to £DC)' + else if (starting_control === 'd_ahead' && end_control === COM) + return ' (£DU .to £DC)' + else if (starting_control === 'c_ahead' && end_control === DEM) + return ' (£CU .to £DC)' + else if (starting_control === 'c_ahead' && end_control === COM) + return ' (£CU .to £CC)' + else if (starting_control === DEM && (end_control === 'd_ahead' || 'none')) + return ' (£DC .to £DU)' + else if (starting_control === DEM && end_control === 'c_ahead') + return ' (£DC .to £CU)' + else if (starting_control === COM && (end_control === 'c_ahead' || 'none')) + return ' (£CC .to £CU)' + else if (starting_control === COM && end_control === 'd_ahead') + return ' (£CC .to £DU)' + else if (starting_control === 'none' && end_control === DEM) + return ' (£DU .to £DC)' + else if (starting_control === 'none' && end_control === COM) + return ' (£CU .to £CC)' + else + return '' + } else + return '' +} + function do_tst_attempt() { let roll = roll_d6() log(`Roll: D${roll}`) @@ -2779,7 +2848,7 @@ function do_tst_attempt() { if (game.active === DEM) { game.dem_tst_attempted_this_turn = 1 if (roll >= dem_tst_req[game.dem_tst_position]) { - log(`Success: ${roll} >= ${dem_tst_req[game.dem_tst_position]}`) + log(`Success: ${roll} >= .dT${dem_tst_req[game.dem_tst_position]}`) game.dem_tst_position++ game.dem_tst_attempted = 0 @@ -2807,14 +2876,14 @@ function do_tst_attempt() { } game.state = 'tiananmen_square_attempt_success' } else { - log(`Fail: ${roll} < ${dem_tst_req[game.dem_tst_position]}`) + log(`Fail: ${roll} < .dT${dem_tst_req[game.dem_tst_position]}`) game.dem_tst_attempted = 1 game.state = 'tiananmen_square_attempt_fail' } } else { game.com_tst_attempted_this_turn = 1 if (roll >= com_tst_req[game.com_tst_position]) { - log(`Success: ${roll} >= ${com_tst_req[game.com_tst_position]}`) + log(`Success: ${roll} >= .cT${com_tst_req[game.com_tst_position]}`) game.com_tst_position++ game.com_tst_attempted = 0 @@ -2846,7 +2915,7 @@ function do_tst_attempt() { } game.state = 'tiananmen_square_attempt_success' } else { - log(`Fail: ${roll} < ${com_tst_req[game.com_tst_position]}`) + log(`Fail: ${roll} < .cT${com_tst_req[game.com_tst_position]}`) game.com_tst_attempted = 1 game.state = 'tiananmen_square_attempt_fail' } @@ -3350,7 +3419,7 @@ function is_auto_resolve(card) { return true } } else if (card === C_GOVERNMENT_RESIGNS && game.active === COM) { - let uncontrolled_elites = spaces.filter(space => spaces[space.space_id].socio === SOCIO_ELITE && game.comInfl[space.space_id] > 0 && !check_control(space.space_id)).length + let uncontrolled_elites = spaces.filter(space => spaces[space.space_id].socio === SOCIO_ELITE && game.comInfl[space.space_id] > 0 && !is_controlled(space.space_id)).length if (uncontrolled_elites === 0) { if (!game.state.startsWith('vm')) { log('No uncontrolled Elite spaces.') @@ -4354,7 +4423,7 @@ function pop_summary() { } game.summary = [] } - +/* function pop_summary_i() { if (game.summary.length > 0) { for (let [n, msg] of game.summary) { @@ -4362,10 +4431,48 @@ function pop_summary_i() { } } game.summary = [] -} +} */ + + function pop_summary_i() { + if (game.summary.length > 0) { + // Create a map to group by space and track totals and details + let grouped_summary = new Map(); + + for (let [n, msg] of game.summary) { + // Extract the space identifier (e.g., %67) from the message + let space_match = msg.match(/%\d+/); + let space = space_match ? space_match[0] : "unknown"; + + // Extract any details (e.g., £CU to £CC) from the message + let details_match = msg.match(/\(.*?\)$/); + let details = details_match ? details_match[0] : ""; + + // Update or initialize the entry for the space + if (!grouped_summary.has(space)) { + grouped_summary.set(space, { total: 0, details }); + } + let entry = grouped_summary.get(space); + entry.total += n; + + // Always keep the most specific details (non-empty) + if (details) { + entry.details = details; + } + } + + // Log the grouped results + for (let [space, { total, details }] of grouped_summary) { + logi(`${total} in ${space} ${details}`); + } + } + game.summary = []; + } + + function do_log_summary() { if (game.summary.length > 0) { + console.log('game.summary', game.summary) pop_summary_i() } } @@ -4779,7 +4886,7 @@ function vm_valid_spaces_solidarity_legalised() { let valid_spaces = [] for (let i = 0; i < spaces.length; i++) { let space = spaces[i] - let uncontrolled = !check_control(i) && !check_opp_control(i) + let uncontrolled = !is_controlled(i) && !check_opp_control(i) if ( (space.country === 'Poland' && uncontrolled && space.socio === SOCIO_WORKER) || (space.country === 'Poland' && uncontrolled && space.socio === SOCIO_FARMER) @@ -4801,6 +4908,7 @@ function vm_take_control_prep() { } function vm_take_control(space) { + let starting_control = check_control(space) if (game.active === DEM) { let current_infl = game.demInfl[space] let opponent_infl = game.comInfl[space] @@ -4819,22 +4927,25 @@ function vm_take_control(space) { } } game.valid_spaces = game.valid_spaces.filter(id => id !== space) + let end_control = check_control(space) if (game.state === 'vm_kremlin_coup_take_control') - logi(`Took control of %${space}.`) + logi('Took control of %' + space + get_icons(starting_control, end_control) +'.') else - log(`Took control of %${space}.`) + log('Took control of %' + space + get_icons(starting_control, end_control) +'.') } function vm_do_add_infl_free(space) { push_undo() - log_summary(`£ in %${space}`) - + //log_summary(`£ in %${space}`) + let starting_control = check_control(space) // Update influence values if (game.active === COM) { game.comInfl[space]++ } else { game.demInfl[space]++ } + let end_control = check_control(space) + log_summary('£ in %' + space + get_icons(starting_control,end_control)) game.vm_available_ops-- check_tyrant() } @@ -4884,7 +4995,8 @@ function vm_add_limited_infl() { function vm_do_add_limited_infl(space, max_infl) { push_undo() - log_summary(`£ in %${space}`) + //log_summary(`£ in %${space}`) + let starting_control = check_control(space) game.vm_available_ops -- if (!game.vm_influence_added) { @@ -4901,6 +5013,8 @@ function vm_do_add_limited_infl(space, max_infl) { game.demInfl[space] ++ } + let end_control = check_control(space) + log_summary('£ in %' + space + get_icons(starting_control,end_control)) game.vm_influence_added[space] ++ if (game.vm_influence_added[space] === max_infl) { @@ -4937,7 +5051,7 @@ function vm_remove_x_opp_infl() { function vm_do_remove_x_infl(space) { push_undo() - + let starting_control = check_control(space) if (game.remove_opponent_infl) { if (game.active === COM) { if (game.demInfl[space] >= game.vm_available_ops) { @@ -4971,8 +5085,8 @@ function vm_do_remove_x_infl(space) { } } } - - logi(`${game.vm_available_ops} - %${space}`) + let end_control = check_control(space) + logi(`${game.vm_available_ops} from %${space}${get_icons(starting_control, end_control)}`) check_tyrant() game.vm_available_ops = 0 game.valid_spaces = [] @@ -4988,7 +5102,8 @@ function vm_remove_limited_opp_infl() { function vm_do_remove_limited_infl(space, max_infl) { push_undo() - log_summary(`£ in %${space}`) + //log_summary(`£ in %${space}`) + let starting_control = check_control(space) game.vm_available_ops -- if (!game.vm_influence_added) { @@ -5017,6 +5132,8 @@ function vm_do_remove_limited_infl(space, max_infl) { game.valid_spaces = game.valid_spaces.filter(id => id !== space) } + let end_control = check_control(space) + log_summary('£ from %' + space + get_icons(starting_control,end_control)) check_tyrant() if (game.vm_available_ops === 0) { game.valid_spaces = [] @@ -5030,7 +5147,7 @@ function vm_remove_all_infl() { function vm_do_remove_all_infl(space) { push_undo() - + if (game.remove_opponent_infl === true) { if (game.active === COM) { log(`Removed all Democratic SP from %${space}.`) @@ -5442,7 +5559,7 @@ function vm_goodbye_lenin() { function vm_government_resigns() { for (let i = 0; i < spaces.length; i++) { let space = spaces[i] - if (space.socio === SOCIO_ELITE && game.comInfl[i] > 0 && !check_control(i)) { + if (space.socio === SOCIO_ELITE && game.comInfl[i] > 0 && !is_controlled(i)) { game.valid_spaces.push(i) } } |