diff options
-rw-r--r-- | play.css | 35 | ||||
-rw-r--r-- | play.js | 136 | ||||
-rw-r--r-- | rules.js | 60 |
3 files changed, 156 insertions, 75 deletions
@@ -58,18 +58,6 @@ header.your_turn.saxony { background-color: var(--color-light-saxony); } header.your_turn.pragmatic { background-color: var(--color-light-pragmatic); } header.your_turn.austria { background-color: var(--color-light-austria); } -svg .road { - stroke: dimgray; - stroke-width: 8; - stroke-dasharray: 2 2; -} - -svg .main_road { - stroke: dimgray; - stroke-width: 16; - stroke-dasharray: 4 2; -} - /* COLORS */ :root { @@ -161,9 +149,8 @@ svg .main_road { min-height: 6px; } -#log .city_tip:hover { cursor: pointer; text-decoration: underline; } - -#log .piece_tip:hover { cursor: pointer; text-decoration: underline; } +.city_tip .piece_tip, .move_tip { cursor: pointer; } +.city_tip:hover, .piece_tip:hover, .move_tip:hover { text-decoration: underline; } #log .h { background-color: tan; @@ -171,9 +158,9 @@ svg .main_road { margin: 8px 0; } -#log .h.fate { text-align: center; } -#log .h.fate::before { content: "\2014 " } -#log .h.fate::after { content: " \2014" } +#log .h.turn { text-align: center; } +#log .h.turn::before { content: "\2014 " } +#log .h.turn::after { content: " \2014" } #log .combat { background-color: #d7cfb8; } @@ -410,6 +397,18 @@ span.suit.reserve { color: var(--color-reserve); font-weight: bold; font-family: .number.n7 { background-position: -84px 0px; } .number.n8 { background-position: -98px 0px; } +/* ROADS */ + +.space.move { + background-color: #fff6; +} + +svg .road { + stroke: red; + stroke-width: 6; + stroke-linecap: round; +} + /* CARD COUNTING AIDS */ @media (hover: hover) { @@ -140,14 +140,18 @@ function to_value(c) { const svgNS = "http://www.w3.org/2000/svg" -function make_road(c1, c2, type) { +var _show_path_pcs = [] +var _show_path = [] + +function make_road(a, b, type) { let e = document.createElementNS(svgNS, "line") e.setAttribute("class", type) - let x1 = data.cities.x[c1] - let y1 = data.cities.y[c1] - let x2 = data.cities.x[c2] - let y2 = data.cities.y[c2] + let x1 = data.cities.x[a] + let y1 = data.cities.y[a] + let x2 = data.cities.x[b] + let y2 = data.cities.y[b] + /* let v = Math.hypot(x2 - x1, y2 - y1) let dx = (x2 - x1) / v let dy = (y2 - y1) / v @@ -156,12 +160,63 @@ function make_road(c1, c2, type) { y1 += r * dy x2 -= r * dx y2 -= r * dy + */ e.setAttribute("x1", x1) e.setAttribute("y1", y1) e.setAttribute("x2", x2) e.setAttribute("y2", y2) document.getElementById("roads").appendChild(e) + + if (!ui.roads[a]) ui.roads[a] = {} + if (!ui.roads[b]) ui.roads[b] = {} + ui.roads[a][b] = e + ui.roads[b][a] = e +} + +function on_focus_path_tip(ps, ss) { + _show_path_pcs = ps + for (let p of _show_path_pcs) + on_focus_piece_tip(p) + hide_move_path() + _show_path = ss + show_move_path(view.pos[ps[0]] !== ss[ss.length-1]) + ui.status.textContent = ss.map(s => data.cities.name[s]).join(" - ") +} + +function on_blur_path_tip() { + for (let p of _show_path_pcs) + on_blur_piece_tip(p) + hide_move_path() + ui.status.textContent = "" +} + +function show_move_path(tip_end) { + if (_show_path && _show_path.length > 0) { + for (let i = 0; i < _show_path.length; ++i) + ui.cities[_show_path[i]].classList.add("move") + if (tip_end) + ui.cities[_show_path[_show_path.length-1]].classList.add("tip") + for (let i = 1; i < _show_path.length; ++i) { + let x = _show_path[i-1] + let y = _show_path[i] + ui.roads[x][y].setAttribute("visibility", "visible") + } + } +} + +function hide_move_path() { + if (_show_path && _show_path.length > 0) { + for (let i = 0; i < _show_path.length; ++i) + ui.cities[_show_path[i]].classList.remove("move") + ui.cities[_show_path[_show_path.length-1]].classList.remove("tip") + for (let i = 1; i < _show_path.length; ++i) { + let x = _show_path[i-1] + let y = _show_path[i] + ui.roads[x][y].setAttribute("visibility", "hidden") + } + _show_path = null + } } /* PANEL ORDER */ @@ -271,6 +326,7 @@ const ui = { document.getElementById("hand_austria"), ], cities: [], + roads: [], action_register: [], } @@ -343,7 +399,7 @@ function make_tc_deck_back(n) { return list } -function make_tc_deck_discard(n) { +function make_tc_deck_pile(n) { let list = [] for (let i = 0; i < 10; ++i) { let e = document.createElement("div") @@ -353,6 +409,16 @@ function make_tc_deck_discard(n) { return list } +function make_tc_deck_hand(n) { + let list = [] + for (let i = 0; i < 100; ++i) { + let e = document.createElement("div") + e.className = "card tc hand reverse " + n + list.push(e) + } + return list +} + function make_political_card(fc) { let e = document.createElement("div") if (fc === 0) @@ -446,11 +512,20 @@ function on_init() { make_tc_deck_back("deck_4"), ] + ui.tc_hand = [ + make_tc_deck_pile("deck_1"), + make_tc_deck_pile("deck_1"), + make_tc_deck_pile("deck_1"), + make_tc_deck_pile("deck_1"), + make_tc_deck_pile("deck_1"), + make_tc_deck_pile("deck_1"), + ] + ui.tc_discard = [ - make_tc_deck_discard("deck_1"), - make_tc_deck_discard("deck_2"), - make_tc_deck_discard("deck_3"), - make_tc_deck_discard("deck_4"), + make_tc_deck_pile("deck_1"), + make_tc_deck_pile("deck_2"), + make_tc_deck_pile("deck_3"), + make_tc_deck_pile("deck_4"), ] ui.combat = document.createElement("div") @@ -524,20 +599,17 @@ function on_init() { ui.spaces_element.appendChild(e) } - sort_power_panel(false) - - // TOD: debug road network - if (0) { - for (let a = 0; a <= last_city; ++a) { - for (let b of data.cities.main_roads[a]) - if (a < b) - make_road(a, b, "main_road") - for (let b of data.cities.roads[a]) - if (a < b) - make_road(a, b, "road") - } + for (let a = 0; a <= last_city; ++a) { + for (let b of data.cities.main_roads[a]) + if (a < b) + make_road(a, b, "road") + for (let b of data.cities.roads[a]) + if (a < b) + make_road(a, b, "road") } + sort_power_panel(false) + update_favicon() } @@ -786,7 +858,7 @@ function colorize(text) { } function on_prompt(text) { - return colorize(view.prompt) + return colorize(text) } function on_update() { @@ -822,13 +894,17 @@ function on_update() { */ ui.hand[pow].replaceChildren() - view.hand[pow].sort(cmp_tc) - for (let c of view.hand[pow]) { - console.log("C", c, c&15) - if ((c & 15) === 0) - ui.hand[pow].appendChild(ui.tc_back[c>>7][back[c>>7]++]) - else - ui.hand[pow].appendChild(ui.tc[c]) + if (typeof view.hand[pow] === "number") { + for (let i = 0; i < view.hand[pow]; ++i) + ui.hand[pow].appendChild(ui.tc_hand[pow][i]) + } else { + view.hand[pow].sort(cmp_tc) + for (let c of view.hand[pow]) { + if ((c & 15) === 0) + ui.hand[pow].appendChild(ui.tc_back[c>>7][back[c>>7]++]) + else + ui.hand[pow].appendChild(ui.tc[c]) + } } } @@ -242,6 +242,11 @@ function log_selected() { log(game.selected.map(p => "P" + p).join(" and ")) } +function log_move_path() { + if (game.move_path.length > 1) + log("@" + game.selected.join(",") + ";" + game.move_path.join(",")) +} + /* OBJECTIVES */ const all_objectives = [] @@ -519,11 +524,6 @@ function eliminate_general(p) { set_in_supply(p) } -function eliminate_train(p) { - log("P" + p + " eliminated.") - game.pos[p] = ELIMINATED -} - /* SEQUENCE OF PLAY */ const POWER_FROM_ACTION_STEP = [ @@ -839,10 +839,9 @@ states.movement = { else prompt("Move your generals and supply trains.") - if (done_trains && done_generals) - view.actions.end_movement = 1 + if (game.moved.length === 0) + view.actions.confirm_end_movement = 1 else - // TODO view.actions.confirm_end_movement = 1 view.actions.end_movement = 1 }, piece(p) { @@ -866,6 +865,7 @@ states.movement = { else game.main = 0 + game.move_path = [ here ] if (is_supply_train(p)) game.state = "move_supply_train" else @@ -951,7 +951,7 @@ function move_general_to(to) { if (is_protected_from_conquest(from)) { set_add(game.retro, from) } else { - game.move_conq.push(from) + set_add(game.move_conq, from) set_add(game.conquest, from) } } @@ -961,7 +961,7 @@ function move_general_to(to) { if (is_protected_from_reconquest(from)) { set_add(game.retro, from) } else { - game.move_reconq.push(from) + set_add(game.move_reconq, from) set_delete(game.conquest, from) } } @@ -969,8 +969,10 @@ function move_general_to(to) { // eliminate supply train for (let p of all_enemy_trains[pow]) { if (game.pos[p] === to) { - eliminate_train(p) - stop = true + if (!game.move_elim) + game.move_elim = [] + set_add(game.move_elim, p) + game.pos[p] = ELIMINATED } } @@ -1019,12 +1021,7 @@ states.move_supply_train = { let who = game.selected[0] let from = game.pos[who] - if (game.count === 0) { - log_selected() - log(">from S" + from) - } - - log(">to S" + to) + game.move_path.push(to) if (!set_has(data.cities.main_roads[from], to)) game.main = 0 @@ -1111,12 +1108,7 @@ states.move_general = { let who = game.selected[0] let from = game.pos[who] - if (game.count === 0) { - log_selected() - log(">from S" + from) - } - - log(">to S" + to) + game.move_path.push(to) if (!set_has(data.cities.main_roads[from], to)) game.main = 0 @@ -1169,6 +1161,15 @@ states.move_give = { } function end_move_piece() { + log_selected_move_path() + + if (game.move_elim) { + for (let p of game.move_elim) + log("P" + p + " eliminated.") + delete game.move_elim + } + + delete game.move_path game.selected = null game.state = "movement" } @@ -1408,10 +1409,12 @@ function end_recruit() { if (game.recruit) { if (game.recruit.used.length > 0) { log_br() - log("Recruited") - log(">" + game.recruit.used.map(format_card).join(", ")) + if (game.recruit.troops > 0) + log("Recruited " + game.recruit.troops + " troops with " + game.recruit.used.map(format_card).join(", ") + ".") + else + log("Recruited with " + game.recruit.used.map(format_card).join(", ") + ".") map_for_each(game.recruit.pieces, (p,s) => { - log(">P" + p + " at S" + s) + log("Re-entered P" + p + " at S" + s) }) if (game.recruit.troops) log(">" + game.recruit.troops + " troops") @@ -2585,6 +2588,9 @@ function mask_hand(player) { view_hand[pow] = game.hand[pow] else view_hand[pow] = game.hand[pow].map(c => c & ~127) + //view_hand[pow] = game.hand[pow].length + //view_hand[pow] = Math.ceil(game.hand[pow].length / 3) * 3 + //view_hand[pow] = Math.ceil(game.hand[pow].length / 5) } return view_hand } |