Skip to content

Instantly share code, notes, and snippets.

@randrews
Created July 2, 2022 05:41
Show Gist options
  • Save randrews/86b469aa5df2c080a36ec141e0a07b5a to your computer and use it in GitHub Desktop.
Save randrews/86b469aa5df2c080a36ec141e0a07b5a to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>You Have A Sword!</title>
<script type="text/javascript">
const $ = s => document.querySelector(s)
const $$ = s => document.querySelectorAll(s)
let gameState = null
const startGame = () => {
gameState = {
playerHealth: 3, enemyHealth: 3,
playerLast: null, enemyLast: null,
gameOver: false,
message: 'The fight begins! Choose your action!'
}
updateDisplay()
}
const updateDisplay = () => {
console.log(gameState)
$('#playerHealth').innerText = healthString(gameState.playerHealth)
$('#enemyHealth').innerText = healthString(gameState.enemyHealth)
$('#message').innerText = gameState.message
$('#gameOverMessage').innerText = gameState.gameOverMessage
$('#gameOver').style.display = gameState.gameOver ? 'block' : 'none'
if (gameState.gameOver) {
$('#enemyActionDisplay').style.display = 'none'
$$('.buttons .actionLink').forEach(link => link.classList.add('disabled'))
} else {
$('#enemyActionDisplay').style.display = gameState.enemyLast ? 'block' : 'none'
$('#enemyAction').innerText = gameState.enemyLast
$$('.buttons .actionLink').forEach(link => link.classList.remove('disabled'))
if (gameState.playerLast) $(`.actionLink.${gameState.playerLast}`).classList.add('disabled')
}
}
const chooseEnemyAction = () => {
const actions = ['slash', 'stab', 'guard', 'dodge'].filter(a => a!== gameState.enemyLast)
return actions[Math.floor(Math.random() * actions.length)]
}
const actionClicked = (action) => {
if (gameState.playerLast === action || gameState.gameOver) { return }
const enemyAct = chooseEnemyAction()
gameState.enemyLast = enemyAct
gameState.playerLast = action
if (action === 'slash') {
if (enemyAct === 'slash') {
gameState.message = 'Your both slash, your swords clang together!'
} else if (enemyAct === 'guard') {
gameState.message = "Your slash is rebuffed by the enemy's block!"
} else if (enemyAct === 'stab') {
gameState.message = 'You slash him, he stabs you!'
gameState.playerHealth--; gameState.enemyHealth--;
} else if (enemyAct === 'dodge') {
gameState.message = 'His dodge cannot escape your mighty slash!'
gameState.enemyHealth--;
}
} else if (action === 'stab') {
if (enemyAct === 'slash') {
gameState.message = 'You stab him, he slashes you!'
gameState.playerHealth--; gameState.enemyHealth--;
} else if (enemyAct === 'guard') {
gameState.message = 'Your stab pierces right through his guard!'
gameState.enemyHealth--;
} else if (enemyAct === 'stab') {
gameState.message = 'You stab each other!'
gameState.playerHealth--; gameState.enemyHealth--;
} else if (enemyAct === 'dodge') {
gameState.message = 'His dodge neatly avoids your stab!'
}
} else if (action === 'guard') {
if (enemyAct === 'slash') {
gameState.message = 'Your guard rebuffs his slash!'
} else if (enemyAct === 'guard') {
gameState.message = boring(action, enemyAct)
} else if (enemyAct === 'stab') {
gameState.message = 'His stab pierces through your guard!'
gameState.playerHealth--;
} else if (enemyAct === 'dodge') {
gameState.message = boring(action, enemyAct)
}
} else if (action === 'dodge') {
if (enemyAct === 'slash') {
gameState.message = 'You dodge too slowly to avoid his slash!'
gameState.playerHealth--;
} else if (enemyAct === 'guard') {
gameState.message = boring(action, enemyAct)
} else if (enemyAct === 'stab') {
gameState.message = 'You dodge out of the way of his stab!'
} else if (enemyAct === 'dodge') {
gameState.message = boring(action, enemyAct)
}
}
if (gameState.playerHealth === 0 || gameState.enemyHealth === 0) { gameState.gameOver = true }
if (gameState.playerHealth === 0 && gameState.enemyHealth === 0) { gameState.gameOverMessage = "You have both killed each other! It's a tie!" }
else if (gameState.playerHealth === 0 && gameState.enemyHealth >= 0) { gameState.gameOverMessage = 'The enemy has defeated you!' }
else if (gameState.playerHealth >= 0 && gameState.enemyHealth == 0) { gameState.gameOverMessage = 'You have vanquished your enemy!' }
updateDisplay()
}
const healthString = (val) => {
let str = ''
for(let n = 0; n < val; n++) str = str + '<3 '
return str
}
const boring = (playerAction, enemyAction) => `You ${playerAction}, he ${presentTense(enemyAction)}`
const presentTense = act => (act === 'slash' ? 'slashes' : (act + 's'))
document.addEventListener("DOMContentLoaded", startGame)
</script>
<style>
.main {
border: 2px solid gray;
border-radius: 0.5em;
overflow: auto;
padding: 0.5em;
position: relative;
padding: 1em;
grid-area: 2 / 2 / 3 / 3;
}
.instructions {
grid-area: 3 / 2 / 4 / 3;
padding-top: 1em;
}
.buttons { position: absolute; bottom: 1em; }
body {
background-color: #202020;
color: lightgray;
font-family: 'Roboto Mono', monospace;
font-size: 16px;
display: grid;
grid-template-columns: auto 640px auto;
grid-template-rows: auto 480px auto;
height: 100vh;
margin: 0;
}
.healthDisplay { color: #ff6060 }
.actionLink { color: #60ff60; cursor: pointer }
.enemyActionName { color: #ffff60 }
.actionName { color: #60ff60 }
.actionLink.disabled { color: #909090 }
</style>
</head>
<body>
<div class="panel main">
<div>Your health: <span class="healthDisplay" id="playerHealth"></span></div>
<div>Enemy health: <span class="healthDisplay" id="enemyHealth"></span></div>
<hr/>
<div id="message"></div>
<div id="gameOver">
<div id="gameOverMessage"></div>
<div class="actionLink" onclick="startGame()">[ Fight again! ]</div>
</div>
<div class="buttons">
<div id="enemyActionDisplay">Enemy used <span class="enemyActionName" id="enemyAction">Stab!</span></div>
<div class="actionLink slash" onclick="actionClicked('slash')">[ Slash! ]</div>
<div class="actionLink stab" onclick="actionClicked('stab')">[ Stab!&nbsp; ]</div>
<div class="actionLink guard" onclick="actionClicked('guard')">[ Guard! ]</div>
<div class="actionLink dodge" onclick="actionClicked('dodge')"> [ Dodge! ]</div>
</div>
</div>
<div class="instructions">
<p><strong>How to play:</strong></p>
<p>You have a sword! You want to cut your enemy with it. But he wants to do the same to you!</p>
<p>Every turn, you both pick an action simultaneously. You cannot pick the same action twice in a row.</p>
<p>The four actions available:</p>
<ul>
<li><strong class="actionName">Slash</strong> will try to cut your enemy with the sword. Another <span class="actionName">Slash</span> or a <span class="actionName">Guard</span> will block this.</li>
<li><strong class="actionName">Stab</strong> will lunge at the enemy to wound them. <span class="actionName">Dodge</span> will protect from this, nothing else will.</li>
<li><strong class="actionName">Guard</strong> to use your sword to prevent a <span class="actionName">Slash</span>. Does nothing against <span class="actionName">Stab</span>.</li>
<li><strong class="actionName">Dodge</strong> to move out of the way of a <span class="actionName">Stab</span>. Does nothing against <span class="actionName">Slash</span>.</li>
</ul>
<p><span class="actionName">Stab</span> / <span class="actionName">Stab</span> or <span class="actionName">Stab</span> / <span class="actionName">Slash</span>, you both wound each other.</p>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment