const seed = 'none'
const scenario = 'standard'
const options = 'none'
//const rules = require("./rules")
const last_card = 110
const last_power_card = 52
let hover_timeout
const height = 65
const width = 105
const toolbar = document.getElementById('toolbar')
const vpMarker = document.getElementById('vp')
const counters = document.getElementById('counters')
const countries= ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
/*const aside_events = [
"honecker",
"st_nicholas_church",
"helsinki_final_act",
"eco_glasnost",
"we_are_the_people",
"foreign_currency_debt_burden",
"li_peng",
"austria_hungary_border_reopened",
"grenztruppen",
"presidential_visit",
"securitate",
"laslzo_tokes",
"stand_fast",
"elena",
"new_years_eve_party"
]*/
const board_events = [2, 9, 69, 97]
const box_events = [ 15, 24, 26, 39, 48, 49, 53, 58, 59, 65, 70, 73, 100, 101, 104 ]
let box_events_showing = false
let show_discard = false
const overlay = document.getElementById('overlay');
const spaceNameElement = document.getElementById('space-name');
const spaceCharacteristicsElement = document.getElementById('space-characteristics');
// Event listener to track mouse movement over the map
document.querySelector('.map').addEventListener('mousemove', function(event) {
const x = event.offsetX; // X-coordinate of mouse relative to container
const y = event.offsetY; // Y-coordinate of mouse relative to container
spaceCharacteristicsElement.innerText = `X: ${x}, Y: ${y}`;
})
// Create map areas dynamically based on coordinates
function create_ui() {
// CREATE MAP
spaces.forEach((space) => {
if (space && space.box) {
//CREATE SPACES
const { x, y} = space.box;
const spaceArea = document.createElement('div');
spaceArea.classList.add('space-area', space.country)
spaceArea.id=`space_${space.space_id}`;
spaceArea.style.left = x + 'px';
spaceArea.style.top = y + 'px';
spaceArea.style.width = width + 'px';
spaceArea.style.height = height + 'px';
spaceArea.style.zIndex = 2;
spaceArea.my_space = space.name_unique;
spaceArea.addEventListener('mousedown', on_click_space);
//CREATE DEMOCRATIC INFLUENCE MARKERS FOR EACH SPACE
const dem_img = document.createElement('div')
dem_img.classList.add('demInfl', space.country)
dem_img.style.display = 'none'
dem_img.id=`${space.name_unique}_demInfl`
dem_img.style.zIndex = 1
dem_img.my_space = space.name_unique;
dem_img.addEventListener('mousedown', on_click_space);
spaceArea.appendChild(dem_img)
//CREATE DEMOCRATIC INFLUENCE VALUES
const demInflValue = document.createElement('p')
demInflValue.className='demInflValue'
demInflValue.style.display = 'none'
demInflValue.id=`${space.name_unique}_demInflValue`
demInflValue.innerText=space.demInfl
demInflValue.style.zIndex = 1
demInflValue.my_space = space.name_unique;
demInflValue.addEventListener('mousedown', on_click_space);
spaceArea.appendChild(demInflValue)
//CREATE COMMUNIST INFLUENCE MARKERS FOR EACH SPACE
const com_img = document.createElement('div')
com_img.className='comInfl'
com_img.style.display='none'
com_img.id=`${space.name_unique}_comInfl`
com_img.style.zIndex = 1
com_img.my_space = space.name_unique;
com_img.addEventListener('mousedown', on_click_space);
spaceArea.appendChild(com_img)
//CREATE COMMUNIST INFLUENCE VALUES
const comInflValue = document.createElement('p')
comInflValue.className='comInflValue'
comInflValue.style.display='none'
comInflValue.id=`${space.name_unique}_comInflValue`
comInflValue.innerText=space.comInfl
comInflValue.style.zIndex = 1
comInflValue.my_space = space.name_unique;
comInflValue.addEventListener('mousedown', on_click_space);
spaceArea.appendChild(comInflValue)
//}
counters.appendChild(spaceArea);
}
});
// CREATE CARDS
const is_mobile = window.matchMedia("(pointer: coarse)").matches
for (let c = 1; c <= last_card; ++c) {
const hand_card = document.createElement('img');
hand_card.classList.add('hand_card')
hand_card.id=`card_${c}`;
hand_card.src = `cards/e${c}.gif`
hand_card.my_card = c;
hand_card.addEventListener('click', on_click_card);
if(!is_mobile) {
hand_card.addEventListener('mouseenter', () => {
hover_timeout = setTimeout(() => {
hand_card.classList.add('zoom');
}, 500) })
hand_card.addEventListener('mouseleave', () => {
clearTimeout(hover_timeout);
hand_card.classList.remove('zoom');
});
}
ui.cards.push(hand_card);
}
for (let card of power_cards) {
if (!card) continue;
const power_card = document.createElement('img');
power_card.classList.add('power_card');
power_card.id = `power_card_${card.number}`;
power_card.src = `cards_2/${card.url}.gif`;
power_card.my_card = card.number;
power_card.addEventListener('mousedown', on_click_card);
ui.power_cards.push(power_card);
}
}
function is_card_enabled(card) {
if (view.actions) {
if (card_action_menu.some(a => view.actions[a] && view.actions[a].includes(card)))
return true
if (view.actions.card_select && view.actions.card_select.includes(card))
return true
if (view.actions.card && view.actions.card.includes(card))
return true
}
return false
}
// SUPPORTING FUNCTIONS
function on_click_space(evt) {
if (evt.button === 0) {
const space = evt.target.my_space;
//console.log('on_click_space_called with space:', space);
if (send_action('infl', space)) {
evt.stopPropagation();
} else if (send_action('sc', space)) {
//console.log('send_action with sc:', space);
evt.stopPropagation();
} else {
// console.log('send_action failed for space:', space);
}
}
//hide_popup_menu();
}
function on_click_card(evt) {
if (evt.button === 0) {
const card = evt.target.my_card;
console.log('on_click_card_called with card:', card);
if (is_action('card', card)) {
console.log('in action card')
if (send_action('card', card)) {
evt.stopPropagation();
}
}
}
}
function is_action(action) {
//console.log('is_action called with: ', action)
console.log('view.actions', view.actions)
if (view.actions && view.actions[action])
return true
return false
}
function is_card_action(action, card) {
console.log('is_card_action called with action', action, 'card', card)
console.log('view.actions', view.actions, 'view.actions[action]', view.actions[action])
if (view.actions && view.actions[action] && view.actions[action].includes(card))
return true
return false
}
function on_log(text) { // eslint-disable-line no-unused-vars
let p = document.createElement("div")
/*
let last_text = last_log_entry ? last_log_entry.split(' ') : []
console.log('last text', last_text, 'text', text.split(' ')[3])
if (last_text[0] === 'Added' && last_text[4] === text.split(' ')[4]) {
let new_influence = parseInt(last_text[1]) + 1
new_text = `Added ${new_influence} influence in ${last_text[4]}`
console.log('new_influence', new_influence, 'new_text', new_text)
} */
if (text.match(/^>/)) {
text = text.substring(1)
p.className = 'i'
}
text = text.replace(/_/g, ' ')
text = text.replace(/C(\d+)/g, sub_card_name)
text = text.replace(/P(\d+)/g, sub_power_card_name)
text = text.replace(/V(\d+)/g, sub_power_card_value)
text = text.replace(/%(\d+)/g, sub_space_name)
if (text.match(/^\.h1/)) {
text = text.substring(4)
p.className = 'h1'
}
else if (text.match(/^\.h2d/)) {
text = text.substring(5)
p.className = 'h2 dem'
}
else if (text.match(/^\.h2c/)) {
text = text.substring(5)
p.className = 'h2 com'
}
else if (text.match(/^\.h2/)) {
text = text.substring(4)
p.className = 'h2'
}
else if (text.match(/^\.h3/)) {
text = text.substring(4)
p.className = 'h3'
}
//console.log('view.log', view.log)
/*console.log('new text', text)
if (last_log_entry_text) {
console.log('log = text', last_log_entry_text === text)
}
*/
p.innerHTML = text
return p
}
let ui = {
favicon: document.getElementById('favicon'),
player: [
document.getElementById("role_Democrat"),
document.getElementById("role_Communist"),
],
cards: [ null ],
power_cards: [null],
dem_hand_count: document.getElementById("role_stat_dem"),
com_hand_count: document.getElementById("role_stat_com"),
deck_length: document.getElementById("deck_length"),
played_card: 0,
table_panel: document.getElementById("table_panel"),
hand_panel: document.getElementById("hand_panel"),
turn: document.getElementById("turn-tracker"),
round: document.getElementById("action-round-tracker"),
stability: document.getElementById("stability-track"),
dem_TST: document.getElementById("dem-TST"),
com_TST: document.getElementById("com-TST"),
vp: document.getElementById("vp"),
spaces: document.getElementsByClassName("space-area")
}
function on_update() {
//console.log('on_update called')
//console.log('view.valid_spaces: ', view.valid_spaces)
//console.log('view.actions: ', view.actions)
//console.log('view.power_cards:', view.power_cards)
document.querySelectorAll('[id^="space_"].selected').forEach(spaceElement => {spaceElement.classList.remove('selected');});
document.getElementById("power_hand")?.querySelectorAll('.selected').forEach(cardElement => {cardElement.classList.remove('selected');});
view.valid_spaces.forEach(space_id => {
const spaceElementId = `space_${space_id}`;
const spaceElement = document.getElementById(spaceElementId);
if (spaceElement) {
spaceElement.classList.add('selected');
}
});
//Check influence values
for (let i = 1; i < spaces.length; i ++) {
const space = spaces[i]
const demInfl = view.demInfl[i]
const comInfl = view.comInfl[i]
//console.log('piece', piece)
//console.log('space', space)
const dem_marker = document.getElementById(`${space.name_unique}_demInfl`);
const dem_number = document.getElementById(`${space.name_unique}_demInflValue`);
const com_marker = document.getElementById(`${space.name_unique}_comInfl`);
const com_number = document.getElementById(`${space.name_unique}_comInflValue`);
dem_number.innerText=demInfl
if (demInfl > 0) {
dem_marker.style.display = 'block';
dem_number.style.display = 'block';
if (demInfl > 9) {
dem_number.classList.remove('demInflValue')
dem_number.classList.add('demInflValue_10')
} else {
dem_number.classList.add('demInflValue')
dem_number.classList.remove('demInflValue_10')
}
if(check_dem_control(demInfl, comInfl, space)){
dem_marker.classList.add('controlled')
dem_number.classList.add('outlined_text')
dem_marker.classList.remove('uncontrolled')
} else {
dem_marker.classList.add('uncontrolled')
dem_marker.classList.remove('controlled')
dem_number.classList.remove('outlined_text')
}
} else {
dem_marker.style.display = 'none';
dem_number.style.display = 'none';
}
com_number.innerText=comInfl
if (comInfl > 0) {
com_marker.style.display = 'block';
com_number.style.display = 'block';
if (comInfl > 9) {
com_number.classList.remove('comInflValue')
com_number.classList.add('comInflValue_10')
} else {
com_number.classList.add('comInflValue')
com_number.classList.remove('comInflValue_10')
}
if(check_com_control(demInfl, comInfl, space)){
com_marker.classList.add('controlled')
com_number.classList.add('controlled')
com_marker.classList.remove('uncontrolled')
com_number.classList.remove('uncontrolled')
} else {
com_marker.classList.add('uncontrolled')
com_number.classList.add('uncontrolled')
com_marker.classList.remove('controlled')
com_number.classList.remove('controlled')
}
} else {
com_marker.style.display = 'none';
com_number.style.display = 'none';
}
}
// UPDATE COUNTRY MARKERS
for (let i = 0; i < countries.length; i++) {
const country = countries[i];
const marker = document.getElementById(country)
const times_held = document.getElementById(`${country}_times_held`)
if (view.revolutions[find_country_index(country)]) {
marker.classList.add('revolution')
marker.classList.remove('held')
marker.style.display = 'block'
times_held.classList.add('outlined_text')
times_held.classList.remove('hide')
} else if (view.times_held[find_country_index(country)] > 0 ) {
//console.log('setting ', country)
marker.classList.add('held')
marker.style.display = 'block'
times_held.classList.remove('hide')
times_held.innerHTML = view.times_held[find_country_index(country)]
}
else {marker.style.display = 'none'}
}
// UPDATE ASIDE
if (view.is_pwr_struggle) {
ui.dem_hand_count.innerText = `${view.democrat_power_hand} Power cards`
ui.com_hand_count.innerText = `${view.communist_power_hand} Power cards`
} else{
ui.dem_hand_count.innerText = `${view.democrat_hand} cards in hand`
ui.com_hand_count.innerText = `${view.communist_hand} cards in hand`
}
ui.deck_length.innerText = `${view.strategy_deck} cards`
// UPDATE HAND
document.getElementById("hand").replaceChildren()
document.getElementById("played_card").replaceChildren()
if (view.hand.length && view.is_pwr_struggle === false) {
document.getElementById("hand_panel").classList.remove("hide")
for (let c of view.hand) {
let card = ui.cards[c]
document.getElementById("hand").appendChild(card);
if (view.valid_cards.includes(c)) {
card.classList.add('selected')
} else {
card.classList.remove('selected')
}
card.classList.remove('discard_card')
}
} else {
document.getElementById("hand_panel").classList.add("hide")
}
// UPDATE DISCARD
document.getElementById("discard").replaceChildren()
if (!view.is_pwr_struggle) {
for (let c of view.strategy_discard) {
let discard_card = ui.cards[c]
document.getElementById("discard").appendChild(discard_card)
discard_card.classList.add('discard_card')
discard_card.classList.remove('selected')
}
} else if (view.is_pwr_struggle) {
for (let c of view.strategy_discard) {
let discard_card = ui.power_cards[c]
document.getElementById("discard").appendChild(discard_card)
discard_card.classList.add('discard_card')
discard_card.classList.remove('selected')
}
}
// DISCARD FOR EVENTS
console.log('view.discard',view.discard)
if(view.discard) {
//document.getElementById("discard").replaceChildren()
document.getElementById("discard_panel").classList.remove("hide")
for (let c of view.strategy_discard) {
let discard_card = ui.cards[c]
document.getElementById("discard").appendChild(discard_card)
discard_card.classList.add('discard_card')
if (view.valid_cards.includes(c)) {
discard_card.classList.add('selected')
} else {
discard_card.classList.remove('selected')
}
}
} else {
if (!show_discard) {
document.getElementById("discard_panel").classList.add("hide")
}
}
// UPDATE PERMANENTLY REMOVED CARDS
document.getElementById("removed").replaceChildren()
for (let c of view.strategy_removed) {
let discard_card = ui.cards[c]
document.getElementById("removed").appendChild(discard_card)
discard_card.classList.add('discard_card')
discard_card.classList.remove('selected')
}
// PLAYED CARD PANEL
if (view.played_card > 0) {
document.getElementById("played_card_panel").classList.remove("hide")
document.getElementById("played_card").appendChild(ui.cards[view.played_card]);
} else {
document.getElementById("played_card_panel").classList.add("hide")
}
// TABLE CARDS PANEL
document.getElementById("table_cards").replaceChildren()
if (view.table_cards.length > 0) {
document.getElementById("table_panel").classList.remove("hide")
for (let c of view.table_cards) {
let card = ui.cards[c]
document.getElementById("table_cards").appendChild(card);
card.classList.remove("hand_card")
card.classList.add('event_card');
}
} else {
document.getElementById("table_panel").classList.add("hide")
}
// OPPONENT HAND
document.getElementById("opp_hand").replaceChildren()
if (!view.is_pwr_struggle) {
if (view.show_opp_hand && view.opp_hand.length >0) {
document.getElementById("opp_hand_panel").classList.remove("hide")
for (let c of view.opp_hand) {
let card = ui.cards[c]
//console.log('power_card:', power_card)
document.getElementById("opp_hand").appendChild(card);
card.classList.remove('discard_card')
}
} else {
document.getElementById("opp_hand_panel").classList.add("hide")
}
} else {
if (view.show_opp_hand && view.opp_hand.length >0) {
document.getElementById("opp_hand_panel").classList.remove("hide")
for (let c of view.opp_hand) {
let card = ui.power_cards[c]
//console.log('power_card:', power_card)
document.getElementById("opp_hand").appendChild(card);
card.classList.remove('discard_card')
}
} else {
document.getElementById("opp_hand_panel").classList.add("hide")
}
}
// POWER STRUGGLE HAND
document.getElementById("power_hand").replaceChildren()
if (view.power_hand.length && view.is_pwr_struggle) {
document.getElementById("power_panel").classList.remove("hide")
for (let c of view.power_hand) {
let power_card = ui.power_cards[c]
document.getElementById("power_hand").appendChild(power_card);
if (view.valid_cards.includes(c)) {
power_card.classList.add('selected');
}
}
} else {
document.getElementById("power_panel").classList.add("hide")
}
// CEAUSESCU
if (view.ceausescu_cards && view.ceausescu_cards.length > 0 && view.is_pwr_struggle === true) {
document.getElementById("ceausescu_panel").classList.remove("hide")
for (let c of view.ceausescu_cards) {
let power_card = ui.power_cards[c]
document.getElementById("ceausescu_hand").appendChild(power_card);
}
} else {
document.getElementById("ceausescu_panel").classList.add("hide")
}
// SAMIZDAT CARD
if (view.samizdat > 0 ) {
let samizdat_card = ui.cards[view.samizdat]
document.getElementById("samizdat_panel").classList.remove("hide")
document.getElementById("samizdat_card").appendChild(samizdat_card)
} else {
document.getElementById("samizdat_panel").classList.add("hide")
}
// UPDATE BOARD MARKERS
ui.turn.className = `t${view.turn}`
if (view.round_player === 'Democrat') {
ui.round.className = `dem-action-round-tracker r${view.round}`
} else {
ui.round.className = `com-action-round-tracker r${view.round}`
}
ui.stability.className = `s${view.stability}`
ui.dem_TST.className = `tst${view.dem_tst}`
ui.com_TST.className = `tst${view.com_tst}`
if (view.vp >= -20 && view.vp <= 20) {
ui.vp.className = `vp${view.vp}`
} else if (view.vp > 20) {
ui.vp.className = `vp21`
} else if (view.vp < -20) {
ui.vp.className = `vp-21`
}
//console.log('strategy discard: ', view.strategy_discard)
//console.log('valid spaces: ', view.valid_spaces)
//console.log('view.persistent_events', view.persistent_events)
// UPDATE EVENT MARKERS ON THE BOARD
for (let id of board_events) {
let marker = document.getElementById(`event_${id}`)
//console.log('event', id, marker)
if (view.persistent_events.includes(id)) {
marker.style.display = 'block'
} else {
marker.style.display = 'none'
}
}
// UPDATE EVENT MARKERS BELOW THE BOARD
for (let id of box_events) {
let marker = document.getElementById(`event_${id}`)
//console.log('event', id, marker)
if (view.persistent_events.includes(id)) {
marker.style.display = 'block'
} else {
marker.style.display = 'none'
}
}
// CHECK WHETHER ANY EVENT MARKERS ARE SHOWING IN THE EVENTS BOX
box_events_showing = false
for (let id of box_events) {
if (view.persistent_events.includes(id)) {
box_events_showing = true;
}
/*
//Special check for events which are not true/false
if (view.persistent_events['foreign_currency_debt_burden'] !== '') {
aside_events_showing = true
}
if (view.persistent_events['stand_fast'] !== '') {
aside_events_showing = true
}
*/
}
if (box_events_showing) {
document.getElementById('events_panel').classList.remove("hide")
} else {
document.getElementById('events_panel').classList.add("hide")
}
let systematization = document.getElementById('event_69')
if (view.persistent_events.includes(69)) {
systematization.style.left = (spaces[view.systematization].box.x +20) + 'px';
systematization.style.top = spaces[view.systematization].box.y + 'px';
}
let tyrant = document.getElementById('event_97')
if (view.persistent_events.includes(97)) {
tyrant.style.left = (spaces[view.the_tyrant_is_gone].box.x - 41) + 'px';
tyrant.style.top = (spaces[view.the_tyrant_is_gone].box.y + 23) + 'px';
} else {tyrant.style.display = 'none'}
action_button("yes", "Yes")
action_button("no", "No")
action_button("start", "Start")
action_button("check", "Check held cards")
action_button("tst_7", "Cancel opponent event")
action_button("tst_8", "Event and operations")
action_button("end", "End Game")
action_button("continue", "Continue playing")
action_button("east_germany", "East Germany")
action_button("poland", "Poland")
action_button("czechoslovakia", "Czechoslovakia")
action_button("hungary", "Hungary")
action_button("romania", "Romania")
action_button("bulgaria", "Bulgaria")
action_button("extra", "Take action round")
action_button("pass", "Pass")
action_button("remove", "Remove SPs")
action_button("add", "Add SPs")
action_button("ops", "Operations")
action_button("discard", "Discard")
action_button("strike", "Strike")
action_button("march", "March")
action_button("rally", "Rally in the Square")
action_button("petition", "Petition")
action_button("bonus", "Calculate VP bonus")
action_button("scoring", "Score country")
action_button("retain", "Retain Power")
action_button("surrender", "Surrender Power")
action_button("take", "Take Power")
action_button("concede", "Concede")
action_button("struggle", "Begin power struggle")
action_button("raise", "Raise the stakes")
action_button("draw", "Draw cards")
action_button("scoring", "Scoring")
action_button("event", "Event")
action_button("opp_event", "Resolve opponent event")
action_button("influence", "Place SPs")
action_button("support_check", "Support Checks")
action_button("tst", "Tiananmen Square Track")
action_button("roll", "Roll a die")
action_button("done", "Done")
action_button("undo", "Undo")
console.log('view.strategy_deck', view.strategy_deck)
}
// =========================== LOG FUNCTIONS ==============================================
function sub_card_name(match, p1) {
let x = p1 | 0
return `${cards[x].name}`
}
function sub_power_card_name(match, p1) {
let x = p1 | 0
return `${power_cards[x].name}`
}
function sub_power_card_value(match, p1) {
let x = p1 | 0
return `${x}`
}
function sub_space_name(match, p1) {
let x = p1 | 0
let id = spaces[x].space_id
let name = spaces[x].name_unique
return `${name}`
}
function sub_die(match) {
return die[match] || match
}
// =========================== VISUAL FUNCTIONS ==========================================#
function on_focus_card_tip(card_number) {
document.getElementById("tooltip").className = "card card_" + card_number
}
function on_blur_card_tip() {
document.getElementById("tooltip").classList = "card hide"
}
function on_focus_space_tip(id) {
space = document.getElementById(`space_${id}`)
space.classList.add("tip")
}
function on_click_space_tip(id) {
space = document.getElementById(`space_${id}`)
scroll_into_view(space)
}
function on_blur_space_tip(id) {
space = document.getElementById(`space_${id}`)
space.classList.remove("tip")
}
function toggle_pieces() {
document.getElementById("pieces").classList.toggle("hide")
}
function toggle_discard() {
if (show_discard) {
show_discard = false
} else {
show_discard = true
}
document.getElementById("discard_panel").classList.toggle("hide")
}
function toggle_removed() {
document.getElementById("removed_panel").classList.toggle("hide")
}
function check_dem_control(demInfl, comInfl, space) {
if ((demInfl - comInfl) >= space.stability) {
return true
} else{ false}
}
function check_com_control(demInfl, comInfl, space) {
if ((comInfl - demInfl) >= space.stability) {
return true
} else{ false}
}
function find_country_index(country) {
return countries.indexOf(country)
}
create_ui()