summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--land-and-freedom.css26
-rw-r--r--land-and-freedom.scss26
-rw-r--r--play.html3
-rw-r--r--play.js12
-rw-r--r--play.ts16
-rw-r--r--rules.js87
-rw-r--r--rules.ts114
-rw-r--r--types.d.ts29
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 @@
<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>
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<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;
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<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'];