From 8c988ada17bdde1524ffb4f6b73d294dfed5ff4d Mon Sep 17 00:00:00 2001 From: iainp5 Date: Mon, 17 Jun 2024 14:06:49 +0100 Subject: Add files via upload --- 1989_card_back_ps.gif | Bin 0 -> 42223 bytes 1989_map.jpg | Bin 0 -> 1532763 bytes favicon.png | Bin 0 -> 10723 bytes play.css | 219 +++++++++++++++++++ play.html | 95 +++++++++ play.js | 580 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 894 insertions(+) create mode 100644 1989_card_back_ps.gif create mode 100644 1989_map.jpg create mode 100644 favicon.png create mode 100644 play.css create mode 100644 play.html create mode 100644 play.js diff --git a/1989_card_back_ps.gif b/1989_card_back_ps.gif new file mode 100644 index 0000000..d77b791 Binary files /dev/null and b/1989_card_back_ps.gif differ diff --git a/1989_map.jpg b/1989_map.jpg new file mode 100644 index 0000000..b0d38b9 Binary files /dev/null and b/1989_map.jpg differ diff --git a/favicon.png b/favicon.png new file mode 100644 index 0000000..7431f53 Binary files /dev/null and b/favicon.png differ diff --git a/play.css b/play.css new file mode 100644 index 0000000..ac8f519 --- /dev/null +++ b/play.css @@ -0,0 +1,219 @@ +main { background-color: dimgray; } +header { background-color: silver; } +header.your_turn { background-color: orange; } +#role_Dem { background-color: hsl(210,30%,80%); } +#role_Com { background-color: hsl(35,40%,80%); } +#turn_info { background-color: gray; } + +#log { background-color: whitesmoke; } +#log .h1 { font-weight: bold; padding-top:2px; padding-bottom:2px; text-align: center; } +#log .h2 { padding-top:2px; padding-bottom:2px; text-align: center; } +#log .h3 { text-align: center; } +#log .h4 { text-decoration: underline; } +#log .h5 { text-decoration: underline; } + +#log .h1 { background-color: hsl(0,0%,80%); } +#log .h2.teutonic { background-color: hsl(210,30%,85%); } +#log .h2.russian { background-color: hsl(36,40%,85%); } +#log .h3.teutonic { background-color: hsl(210,30%,90%); } +#log .h3.russian { background-color: hsl(35,40%,90%); } + +#log div { padding-left: 20px; text-indent: -12px; } +#log div.i { padding-left: 32px; text-indent: -12px; } +#log div.ii { padding-left: 44px; text-indent: -12px; } + +#log .card_tip { font-style: italic; } +#log .card_tip:hover { text-decoration: underline; } +#log .lord_tip:hover { cursor: pointer; text-decoration: underline; } +#log .locale_tip:hover { cursor: pointer; text-decoration: underline; } +#log .way_tip:hover { cursor: pointer; text-decoration: underline; } + +.action { + cursor: pointer; +} + +#log { + font-variant-numeric: tabular-nums; +} + +/* TOOLBAR */ + +#toolbar { + justify-content: space-evenly; +} + +#prompt { + display: flex; + margin-left: auto; +} + +#button { + display: flex; + margin-left: auto; +} +/* MAP */ + +#map { + margin: 0 auto ; + position: relative; + background-repeat: no-repeat; + background-size: cover; + width: 1275px; /* was 1275*/ + height: 2000px; + /*border: solid black;*/ + overflow: clip; + box-shadow: 0px 1px 10px #0008; + z-index: 3; +} + +#map { background-image: url(1989_map.jpg) } + +/* Containers to appear on hover*/ + #overlay { + position: relative; + top: 0; + left: 0; + width: 100%; + height: 100%; + //background-color: rgba(255, 255, 255, 0.8); /* Semi-transparent overlay */ + //display: none; + justify-content: center; + align-items: center; + text-align: left; + } + +/* SPACES */ + +.space-area { + position: absolute; + box-sizing: border-box; + border: solid red 2px; + +} + +/* CARDS */ + +.playedCard { + display: flex; + margin: auto; + height: 300px; +} + +.handCard { + padding: 10px; + height: 250px; + box-shadow: 0 0 20px 5px rgba(255, 255, 255, 0.5); /* White glowing effect */ + border-radius: 5px; /* Optional: Adds rounded corners */ +} + +.handCard:hover { + cursor: pointer; +} + +/* INFLUENCE MARKERS */ + +.demInfl { + position: absolute; + box-sizing: border-box; + bottom: 1px; + left: 6px; + height: 35px; +} + +.demInfl:hover { + cursor: pointer; +} + +.comInfl { + position: absolute; + box-sizing: border-box; + bottom: 1px; + right: 6px; + height: 35px; +} + +.comInfl:hover { + cursor: pointer; +} + +.demInflValue { + position: absolute; + box-sizing: border-box; + font-family: 'Open Sans'; + font-size: 20px; + font-weight: bold; + top: 10px; + left: 16px; +} + +.comInflValue { + position: absolute; + box-sizing: border-box; + font-family: 'Open Sans'; + font-size: 20px; + font-weight: bold; + top: 10px; + left: 72px; +} + +/* GAME MARKERS */ + +#turn-tracker { + position:absolute; + top: 65px; + left: 511px; + height: 35px; + width: 36px; +} + +.action-round-tracker { + position: absolute; + top: 114px; + left: 554px; + height: 30px; + width: 35px; +} + +#stability-track { + position:absolute; + top: 853px; + left: 1085px; + height: 35px; + width: 35px; +} + +#dem-TST { + position: absolute; + top: 1680px; + left: 0; + height: 35px; + width: 35px; +} + +#com-TST { + position: absolute; + top: 1782px; + left: 0; + height: 35px; + width: 35px; +} + +#vp { + position: absolute; + top: 1912px; + left: 661px; + height: 40px; + width: 40px; +} + + + + +.locale { + box-sizing: border-box; + position: absolute; + border: 3px solid transparent; +} + +.locale.town { border-radius: 80px 80px 36px 36px; } + diff --git a/play.html b/play.html new file mode 100644 index 0000000..0fb9321 --- /dev/null +++ b/play.html @@ -0,0 +1,95 @@ + + + + + + + +1989 + + + + + + + + + + + +
+
+
+ + +
  • Rules of Play +
  • Background Book +
  • Reference Sheets + +
  • +
    + +
    +
    + + + +
    + + +
    + +
    + +
    +

    here I am!

    +

    Text holder

    + + + + + + +
    +
    + +
    +
    Events
    +
    +
    + +
    + + +
    + +
    +
    Hand
    +
    +
    + +
    + +
    + + + + + + \ No newline at end of file diff --git a/play.js b/play.js new file mode 100644 index 0000000..2691439 --- /dev/null +++ b/play.js @@ -0,0 +1,580 @@ +const dem = 0 +const com = 1 +const dem_name= "Democrat" +const com_name= "Communist" +const stability=0 +const US_tiananmen=0 +const USSR_tiananmen=0 +const toolbar = document.getElementById('toolbar') +const vpMarker = document.getElementById('vp') +const mapContainer = document.querySelector('.map') +let handActive=0 +let doInfl=0 +let doSupportCheck=0 +let availableOps=0 +let demTSTPos=0 +let comTSTPos=0 +let demTSTPrev=0 +let comTSTPrev=0 +let turn=1 +let actionRound=1 +let supportCheckTargetName='' +let supportCheckTargetCountry=0 +let vp = 0 +let germanyRevolution=0 +let polandRevolution=0 +let czechRevolution=0 +let hungaryRevolution=0 +let romaniaRevolution=0 +let buglariaRevolution=0 +let germanyHeld=0 +let polandHeld=0 +let czechHeld=0 +let hungaryHeld=0 +let romaniaHeld=0 +let bulgariaHeld=0 + + +const countryNames= [ + null, + "East Germany", + "Poland", + "Czechoslovakia", + "Hungary", + "Romania", + "Bulgaria" +] + + +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 createMap() { + mapContainer.querySelectorAll('.space-area').forEach(spaceArea => { + spaceArea.remove() + }) + + spaces.forEach((space) => { + if (space && space.box) { + const { x, y, h, w } = space.box; + const spaceArea = document.createElement('div'); + spaceArea.classList.add('space-area', space.country) + spaceArea.id=space.name; + spaceArea.style.left = x + 'px'; + spaceArea.style.top = y + 'px'; + spaceArea.style.width = w + 'px'; + spaceArea.style.height = h + 'px'; + spaceArea.addEventListener('click', changeInfl) + spaceArea.addEventListener('click', finishSupportCheck) + spaceArea.querySelectorAll('img').forEach(img => { + img.remove(); + }); + spaceArea.querySelectorAll('p').forEach(p => { + p.remove(); + }); + + if (space.demInfl > 0 && space.demInfl - space.comInfl >= space.stability) { + const img = document.createElement('img') + img.classList.add('demInfl', space.country) + img.id=space.name + img.src = `images/US_${space.demInfl}.gif` + spaceArea.appendChild(img) + } else if (space.demInfl > 0) { + const img = document.createElement('img') + img.classList.add('demInfl', space.country) + img.id=space.name + img.src = `images/USd_blank.gif` + spaceArea.appendChild(img) + + const demInflValue = document.createElement('p') + demInflValue.className='demInflValue' + demInflValue.id=space.name + demInflValue.innerText=space.demInfl + spaceArea.appendChild(demInflValue) + } + + spaceArea.querySelectorAll('img.comInfl').forEach(img => { + img.remove(); }) + + if (space.comInfl === 0) { + + spaceArea.querySelectorAll('img.comInfl').forEach(img => { + img.remove(); }) + + } else if (space.comInfl > 0 && space.comInfl - space.demInfl >= space.stability) { + const img = document.createElement('img') + img.className='comInfl' + img.id=space.name + img.src = `images/SV_${space.comInfl}.gif` + spaceArea.appendChild(img) + } else if (space.comInfl > 0) { + const img = document.createElement('img') + img.className='comInfl' + img.id=space.name + img.src = `images/SVd_blank.gif` + spaceArea.appendChild(img) + + const comInflValue = document.createElement('p') + comInflValue.className='comInflValue' + comInflValue.id=space.name + comInflValue.innerText=space.comInfl + spaceArea.appendChild(comInflValue) + } + + mapContainer.appendChild(spaceArea); + } + }); + +} + + + +/* Create hands */ + + +const handLimit = 8; +const comHandLimit = 8; //Will be needed for Presidential Visit +const hand =[]; +const discard =[]; + +/* Step 1 create a draw deck */ + +const deck = cards + .filter(card => card.period === 1) + .map(card => card.number); + +console.log(deck); + +function drawCards(deck, handLimit) { + while (hand.length < handLimit && deck.length >0) { + let randomIndex = Math.floor(Math.random()*deck.length); + let drawnCard = deck.splice(randomIndex, 1)[0]; + hand.push(drawnCard) + } +console.log('Hand: ', hand) +} + +drawCards(deck, handLimit); + +function displayHand(hand) { + const handDiv = document.getElementById('hand'); + hand.forEach(card => { + const img = document.createElement('img') + img.src = `images/e${card}.gif` + img.className='handCard' + img.alt = `Card ${card}` + img.addEventListener('click', playCard) + handDiv.appendChild(img) + }) + +} + +displayHand(hand); + + +/*---------- INFLUENCE ON THE BOARD ---------------*/ + + + + + + + +/*---------- INITIALIZE GAME ---------------*/ + +function startNewRound() { + toolbar.querySelectorAll('button').forEach(button => { + button.remove(); + }); + + createMap() + + + const prompt = document.createElement('p'); + prompt.textContent = 'Select a card'; + prompt.id='prompt'; + toolbar.appendChild(prompt); + handActive=1; + +} + +function playCard(event) { + if (handActive===1) { +/* Update the toolbar */ + toolbar.querySelectorAll('button').forEach(button => { + button.remove(); + }); + clearPrompt() + + const buttonOps = document.createElement('button'); + buttonOps.textContent = 'Add Influence'; + buttonOps.id='button'; + buttonOps.onclick = influence; + toolbar.appendChild(buttonOps); + + const buttonEvent = document.createElement('button'); + buttonEvent.textContent = 'Play for event'; + buttonEvent.id='button'; + buttonEvent.onclick = event; + toolbar.appendChild(buttonEvent); + + const buttonSC = document.createElement('button'); + buttonSC.textContent = 'Play for a Support Check'; + buttonSC.id='button'; + buttonSC.onclick = supportCheck; + toolbar.appendChild(buttonSC); + + const buttonTian = document.createElement('button'); + buttonTian.textContent = 'Play to the Tiananmen Square Track'; + buttonTian.id='button'; + buttonTian.onclick = tiananmenSquareTrack; + toolbar.appendChild(buttonTian); + + const buttonPoland = document.createElement('button'); + buttonPoland.textContent = 'Score Poland'; + buttonPoland.id='button'; + buttonPoland.onclick = scorePoland; + toolbar.appendChild(buttonPoland); + +/* Update the hand */ + const getLink = event.target.src; + const match = getLink.match(/\/e(\d+)\.gif$/); + const playedCard = parseInt(match[1]); + //const playedCard = parseFloat(event.target.src.split('e')[1].split('.gif')[0]); + console.log('playedCard: ', playedCard) + console.log('match: ', match) + console.log('playedCard: ', playedCard) + + const indexToRemove = hand.indexOf(playedCard); + + if (indexToRemove !== -1) { + hand.splice(indexToRemove, 1); + discard.push(playedCard); + event.target.remove(); + handActive=0; + + availableOps=getOpsValue(playedCard) + console.log('Available ops: ', availableOps) + + const playedCardName=getCardName(playedCard) + console.log('Played card name: ', playedCardName) + + const eventPanel = document.getElementById('events'); + const activeCard = document.createElement('img') + activeCard.src = `images/e${playedCard}.gif` + activeCard.className='playedCard' + activeCard.alt = `Card ${playedCard}` + eventPanel.appendChild(activeCard) + + + } + + console.log('New Hand:', hand); + console.log('Discard:', discard); + +} +} + +function influence() { + clearPrompt() + clearButtons() + const prompt=document.getElementById('prompt') + prompt.innerText='Add Influence' + doInfl=1 +} + +function getOpsValue(cardNumber) { + const cardOps = cards.find(card => card.number === cardNumber); + return cardOps ? cardOps.ops : null; // Return null if the card is not found +} + +function getCardName(cardNumber) { + const cardName = cards.find(card => card.number === cardNumber); + return cardName ? cardName.name : null; // Return null if the card is not found +} + +function rolld6() { + const d6 = Math.floor(Math.random()*6+1) + return d6; +} + +function event() {} +function supportCheck() { + clearPrompt() + clearButtons() + const prompt=document.getElementById('prompt') + prompt.innerText='Select First Target' + doSupportCheck=2 + +} + +function finishSupportCheck(event) { + if (doSupportCheck>0) { + doSupportCheck-- + const roll = rolld6() + console.log('You rolled a: ',roll) + const spaceName = event.target.id; + console.log('spaceName: ', spaceName) + const spaceCountry = parseInt(event.target.classList[1]); // The country of the clicked space, 2nd element in the classList. + console.log('spaceCountry: ', spaceCountry) + + const space = spaces.find(space => space && space.name === spaceName && space.country === spaceCountry); // Find the corresponding space object. + const stability=space.stability * 2 + const supportCheckValue = availableOps + roll + const startingOppInf = space.comInfl + const initialChange = supportCheckValue - stability + console.log('support check value =',availableOps, ' ops + ', roll,' + from roll = ', supportCheckValue) + console.log('stability: ', stability) + console.log('change: ', initialChange) + console.log('starting opp inf: ', startingOppInf) + + if (space) { + if (supportCheckValue > stability){ + if (space.comInfl - initialChange >= 0) { + space.comInfl -=initialChange + console.log('new Com influence: ', space.comInfl) + } else { + space.comInfl = 0 + console.log('new Com influence: ', space.comInfl) + const remainingChange = initialChange-startingOppInf + space.demInfl += remainingChange + } + } + } + + const prompt=document.getElementById('prompt') + if (doSupportCheck===1) { + prompt.innerText='Select Second Target' + } + if (doSupportCheck===0) { + endRound() + } + createMap() + } +} + + +function tiananmenSquareTrack() { + clearButtons () + + const buttonRoll = document.createElement('button'); + buttonRoll.textContent = 'Roll a Die'; + buttonRoll.id='button'; + buttonRoll.onclick = finishTiananmenSquareTrack; + toolbar.appendChild(buttonRoll); +} + + +function finishTiananmenSquareTrack() { + const demTSTMarker=document.getElementById('dem-TST') + const roll = rolld6() + console.log('You rolled a: ',roll) + const attemptTST = availableOps+roll+demTSTPrev + console.log('Total TST attempt value: ', attemptTST) + if (attemptTST >= demTST[demTSTPos]) { + console.log('TST success') + demTSTPos++ + demTSTMarker.style.left=`38px` + + } else { + console.log('TST fail') + demTSTPrev=1 + } + + clearButtons() + clearEvents() + + const endRound = document.createElement('button'); + endRound.textContent = 'End Action Round'; + endRound.id='button'; + endRound.onclick = endActionRound; + toolbar.appendChild(endRound); + +} + + + +function clearButtons () { + toolbar.querySelectorAll('button').forEach(button => { + button.remove(); + }); +} + +function clearEvents () { + events.querySelectorAll('img').forEach(img => { + img.remove() + }) +} + +function clearPrompt() { + const prompt=document.getElementById('prompt') + prompt.innerText='' +} + +function endActionRound() { + clearButtons() + clearEvents() + actionRound++ + const actionRoundTracker=document.querySelector('.action-round-tracker') + const actionRoundPos= 511+actionRound*42 + console.log('Action Round Position: ', actionRoundPos) + actionRoundTracker.style.left=actionRoundPos+'px' + startNewRound() +} + + +function changeInfl(event) { + + if (availableOps>0 && doInfl===1) { + const spaceName = event.target.id; + console.log('spaceName: ', spaceName) + const spaceCountry = parseInt(event.target.classList[1]); // The country of the clicked space, 2nd element in the classList. + console.log('spaceCountry: ', spaceCountry) + + const space = spaces.find(space => space && space.name === spaceName && space.country === spaceCountry); // Find the corresponding space object. + if (space) { + space.demInfl++ + availableOps-- + } + if (availableOps===0) { + clearPrompt() + endRound() + doInfl=0 + } + } + createMap() + +} + + +function endRound() { + clearPrompt() + clearButtons() + const endRound = document.createElement('button'); + endRound.textContent = 'End Action Round'; + endRound.id='button'; + endRound.onclick = endActionRound; + toolbar.appendChild(endRound); +} + + +function scorePoland() { + let demVP = 0 + let comVP = 0 + + const demPresence = spaces.filter(space => space && space.country === 2 && space.demCtrl === 1) + const comPresence = spaces.filter(space => space && space.country === 2 && space.comCtrl === 1) + if (demPresence.length>0) { + demVP+=3 + } + + if (comPresence.length>0) { + comVP+=3 + } + + const demBattlegroundCheck = spaces.filter(space => space && space.country === 2 && space.demCtrl === 1 && space.battleground === 1) + demBattlegrounds = demBattlegroundCheck.length + demVP += demBattlegrounds + const comBattlegroundCheck = spaces.filter(space => space && space.country === 2 && space.comCtrl === 1 && space.battleground === 1) + comBattlegrounds = demBattlegroundCheck.length + comVP += comBattlegrounds + + const demDomination = demBattlegrounds > comBattlegrounds && demPresence > comPresence + const comDomination = comBattlegrounds > demBattlegrounds && comPresence > demPresence + + if (demDomination) { + demVP += 3 + } + + if (comDomination) { + comVP += 3 + } + + const demControl = demBattlegrounds === 6 && demPresence > comPresence + const comControl = demBattlegrounds === 6 && comPresence > demPresence + + if (demControl) { + demVP += 3 + } + + if (comControl) { + comVP += 3 + } + + if (polandRevolution===0) { + polandHeld++ + comVP += polandHeld*3 + + const img = document.createElement('img') + img.classList.add('powerToken', 2) + img.src = `images/SV_1.gif` + mapContainer.appendChild(img) + } + + changeVP = demVP - comVP + vp += changeVP + console.log('Democrats have presence: ', demPresence, ' ', demBattlegrounds, ' battlegrounds') + console.log('Democrat VP: ', demVP) + console.log('Communist VP: ', comVP) + console.log('change VP: ', changeVP) + console.log('VP: ', vp) + + console.log('vp =ve odd: ', isPositiveAndOdd(vp)) + const vpSteps = Math.ceil(Math.abs(vp)/2) + + if (vp === 0) { + vpMarker.style.top = '1912px' + vpMarker.style.left = '661px' + } else if (isPositiveAndEven(vp)) { + vpMarker.style.top = '1937px' + const vpMarkerPos = 666 + vpSteps*50 + vpMarker.style.left = vpMarkerPos + 'px' + } else if (isPositiveAndOdd(vp)) { + vpMarker.style.top = '1889px' + const vpMarkerPos = 642 + vpSteps*50 + vpMarker.style.left = vpMarkerPos + 'px' + } else if (isNegativeAndEven(vp)) { + vpMarker.style.top = '1889px' + const vpMarkerPos = 656 - vpSteps*50 + vpMarker.style.left = vpMarkerPos + 'px' + } else if (isNegativeAndOdd(vp)) { + vpMarker.style.top = '1937px' + const vpMarkerPos = 679 - vpSteps*50 + vpMarker.style.left = vpMarkerPos + 'px' + } + createMap() + endRound() +} + +function isPositiveAndEven(number) { + return number > 0 && number % 2 === 0; +} + +function isPositiveAndOdd(number) { + return number > 0 && number % 2 !== 0; +} + +function isNegativeAndEven(number) { + return number < 0 && number % 2 === 0; +} + +function isNegativeAndOdd(number) { + return number < 0 && number % 2 !== 0; +} + +startNewRound() + -- cgit v1.2.3