aboutsummaryrefslogtreecommitdiff
path: root/html/boss
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-06-08 20:34:11 -0500
committerFlorian Fischer <florian.fischer@muhq.space>2025-08-20 15:57:19 +0200
commit4223ee27c9d83d5ba71870233ee32655ccbf3ec6 (patch)
treebdca9b0554c376b3d6818d7c732cb315a2f9503f /html/boss
parenteec6cf18c8d6081b8b956de2f42e81084f6f747e (diff)
downloadmuhqs-game-4223ee27c9d83d5ba71870233ee32655ccbf3ec6.tar.gz
muhqs-game-4223ee27c9d83d5ba71870233ee32655ccbf3ec6.zip
add boss overview pages
Diffstat (limited to 'html/boss')
-rw-r--r--html/boss/ai-companion.html184
-rw-r--r--html/boss/index.md10
2 files changed, 194 insertions, 0 deletions
diff --git a/html/boss/ai-companion.html b/html/boss/ai-companion.html
new file mode 100644
index 00000000..65923543
--- /dev/null
+++ b/html/boss/ai-companion.html
@@ -0,0 +1,184 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
+ <title>AI Companion</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/eruda/3.4.1/eruda.js" integrity="sha512-3h7ROKDcr6JDuNeJM83xKEnx4cqMvii81NQ+9bSOwOTQL6AKhSmp5oVRL1R4rrM6H23CarCgDK3FIFl3ZnZEZA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+ <script>eruda.init();</script>
+
+ <script src="../js/wasm_exec.js"></script>
+
+ <style>
+:root {
+ /* define applied colors */
+ --bg: #fdfdfd;
+ --fg: #1a1a1a;
+}
+
+@media (prefers-color-scheme: dark) {
+ /* change apllied colors to the dark gruvbox pallet
+ * https://github.com/morhetz/gruvbox
+ */
+ :root {
+ --bg: #282828; /* dark bg */
+ --fg: #ebdbb2; /* dark fg */
+ }
+}
+
+html {
+ line-height: 1.5;
+ font-family: Georgia, serif;
+ font-size: 20px;
+ color: var(--fg);
+ background-color: var(--bg);
+}
+
+body {
+ margin: 0 auto;
+ max-width: 36em;
+ padding-left: 50px;
+ padding-right: 50px;
+ padding-top: 50px;
+ padding-bottom: 50px;
+ hyphens: auto;
+ word-wrap: break-word;
+ text-rendering: optimizeLegibility;
+ font-kerning: normal;
+}
+
+@media (max-width: 600px) {
+ body {
+ font-size: 0.9em;
+ padding: 1em;
+ }
+}
+.card-remove-button {
+ margin: 5px;
+ border: solid;
+ border-radius: 1px;
+ background: gray;
+}
+</style>
+
+ <datalist id="maps">
+ <option value="the-kraken"></option>
+ <option value="the-tyrant"></option>
+ </datalist>
+ <datalist id="cards">
+ %CARDS%
+ </datalist>
+
+ <script>
+ if (!WebAssembly.instantiateStreaming) { // polyfill
+ WebAssembly.instantiateStreaming = async (resp, importObject) => {
+ const source = await (await resp).arrayBuffer();
+ return await WebAssembly.instantiate(source, importObject);
+ };
+ }
+
+ const go = new Go();
+ let mod, inst;
+ const wasm = "ai-companion.wasm"
+
+ WebAssembly.instantiateStreaming(fetch(wasm), go.importObject).then((result) => {
+ mod = result.module;
+ inst = result.instance;
+ document.getElementById("runButton").disabled = false;
+ }).catch((err) => {
+ console.error(err);
+ });
+
+ var cards = {};
+ for (const opt of document.getElementById("cards").options) {
+ cards[opt.value] = true;
+ }
+
+ var players = {};
+
+ var ebitenArgs;
+ async function run() {
+ const map = document.getElementById("mapInput").value;
+ // global value retrieved by the go wasm
+ ebitenArgs = JSON.stringify({mapName: map, players: players.values});
+ await go.run(inst);
+ inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance
+ }
+
+ function addCard(cardInput) {
+ const card = cardInput.value;
+ if (!cards[card]) return;
+ let playerDisplay = cardInput.parentNode;
+ const playerName = playerDisplay.id.slice(0, -4);
+ let player = players[playerName];
+ let pcards = player.cards;
+
+ console.log(playerName + " " + card);
+ pcards.push(card);
+ const cardIdx = pcards.length;
+
+ let cardElem = document.createElement("div");
+ cardElem.appendChild(document.createTextNode(card));
+ let rmvBtn = document.createElement("span");
+ rmvBtn.innerHTML = "x";
+ rmvBtn.onclick = function() {
+ pcards.splice(cardIdx, 1);
+ playerDisplay.removeChild(cardElem);
+ };
+ rmvBtn.classList.add("card-remove-button");
+ cardElem.appendChild(rmvBtn);
+ playerDisplay.appendChild(cardElem);
+ }
+
+ function addPlayer() {
+ let nameInput = document.getElementById("playerName");
+ const name = nameInput.value;
+ players[name] = {name: name, cards: []}
+
+ nameInput.value = "";
+
+ let player = document.createElement("div");
+ player.id = name;
+ player.innerHTML = `${name}
+<div id="${name}Deck">
+<input list="cards" oninput="addCard(this)">
+</input>
+</div>`;
+ document.getElementById("players").appendChild(player);
+ }
+
+ function prefillInputsFromUrl() {
+ const queryParams = window.location.search.substring(1).split("?");
+ for (const param of queryParams) {
+ let parts = param.split("=")
+ let key = parts[0]
+ let value = parts[1]
+
+ let input = document.getElementById(key);
+ if (input) {
+ input.value = value;
+ }
+ }
+ }
+window.onload = function() {
+ prefillInputsFromUrl();
+}
+ </script>
+</head>
+
+<body>
+ <h1>AI Companion</h1>
+ <label for="mapInput">Map:</label>
+ <input autocomplete="on" id="mapInput" list="maps"></input>
+ <br>
+
+ <label for="playerName">Player name:</label>
+ <input id="playerName"></input>
+ <button onclick="addPlayer()">add</button>
+
+ <div id="players"></div>
+
+ <button onClick="run();" id="runButton" disabled>Run</button>
+</body>
+</html>
diff --git a/html/boss/index.md b/html/boss/index.md
new file mode 100644
index 00000000..ec3c7776
--- /dev/null
+++ b/html/boss/index.md
@@ -0,0 +1,10 @@
+%Bosses
+
+For muhq's game there exist multiple [maps](../maps.html#coop) offering a cooperative game experience battling an AI opponent.
+
+## Available Bosses
+
+The following Bosses are available:
+
+* The Kraken - a simple AI opponent [[map](../maps.html#the-kraken)] [[overview](kraken.html)] [[ai-companion](ai-companion.html?mapInput=the-kraken)]
+* The Tyrant - a sophisticated AI altering the map [[map](../maps.html#the-tyrant)] [[overview](tyrant.html)] [[ai-companion](ai-companion.html?mapInput=the-tyrant)]