diff --git a/app.js b/app.js index 2e8ba22..025369d 100644 --- a/app.js +++ b/app.js @@ -122,20 +122,57 @@ } /* ─── Coin animation ─── */ - function flipCoin(resultBit, areaId) { - const area = $(areaId); - if (!area) return; - area.hidden = false; - const coin = area.querySelector('.coin'); - coin.classList.remove('flipping','result-kopf','result-zahl'); - void coin.offsetWidth; - coin.classList.add('flipping'); + function flipCoinEl(coinEl, resultBit) { + coinEl.classList.remove('flipping','result-kopf','result-zahl'); + void coinEl.offsetWidth; + coinEl.classList.add('flipping'); setTimeout(() => { - coin.classList.remove('flipping'); - coin.classList.add(resultBit === 0 ? 'result-kopf' : 'result-zahl'); + coinEl.classList.remove('flipping'); + coinEl.classList.add(resultBit === 0 ? 'result-kopf' : 'result-zahl'); }, 1500); } + function renderResults(results) { + const container = $('results-container'); + container.innerHTML = ''; + container.hidden = false; + + const all = [mesh.myPeerId, ...mesh.getPeerIds()]; + const seen = new Set(); + + all.forEach(id => { + if (seen.has(id)) return; + seen.add(id); + const r = results.get(id); + if (r === undefined) return; + + const isMe = id === mesh.myPeerId; + const name = isMe ? 'Du' : id.slice(0, 8); + + const item = document.createElement('div'); + item.className = 'result-item'; + item.dataset.result = r; + item.innerHTML = ` +
+
+
K
+
Z
+
+
+
${name}
+ `; + container.appendChild(item); + }); + + requestAnimationFrame(() => { + const coins = container.querySelectorAll('.coin'); + coins.forEach((coin, i) => { + const r = parseInt(coin.closest('.result-item').dataset.result); + setTimeout(() => flipCoinEl(coin, r), i * 400); + }); + }); + } + /* ─── Protocol phases UI ─── */ function updatePhases(state) { const map = { IDLE:'ready', STARTING:'ready', COMMITTING:'commit', @@ -158,7 +195,7 @@ show('game'); renderPlayers('game-player-list'); $('btn-start-protocol').hidden = autostart || role !== 'host'; - $('coin-area').hidden = true; + $('results-container').hidden = true; $('result-area').hidden = true; $('protocol-text').textContent = autostart ? 'Starte Protokoll...' : 'Bereit zum Münzwurf'; updatePhases('IDLE'); @@ -170,12 +207,11 @@ $('protocol-text').textContent = phase === 'commit' ? `Commits: ${rcvd}/${total}` : `Reveals: ${rcvd}/${total}`; }; - protocol.oncomplete = result => { - const text = result === 0 ? 'KOPF' : 'ZAHL'; - $('protocol-text').textContent = `Ergebnis: ${text}!`; - flipCoin(result, 'coin-area'); + protocol.oncomplete = results => { + $('protocol-text').textContent = 'Ergebnisse'; + renderResults(results); $('result-area').hidden = false; - $('result-text').textContent = text; + $('result-text').textContent = 'Fertig'; $('btn-start-protocol').hidden = true; }; protocol.onerror = err => { @@ -188,7 +224,7 @@ mesh.ondata = (peerId, msg) => { if (msg.type === 'protocol_start') { if (protocol) protocol.reset(); - $('coin-area').hidden = true; + $('results-container').hidden = true; $('result-area').hidden = true; $('btn-start-protocol').hidden = true; updatePhases('IDLE'); @@ -335,7 +371,7 @@ /* ─── Retry / again ─── */ $('btn-retry').addEventListener('click', () => { if (protocol) protocol.reset(); - $('coin-area').hidden = true; + $('results-container').hidden = true; $('result-area').hidden = true; $('btn-start-protocol').hidden = role !== 'host'; $('protocol-text').textContent = 'Bereit zum Münzwurf'; @@ -345,7 +381,7 @@ /* ─── Result screen → play again ─── */ $('btn-play-again').addEventListener('click', () => { if (protocol) protocol.reset(); - $('coin-area').hidden = true; + $('results-container').hidden = true; $('result-area').hidden = true; setupGame(false); }); diff --git a/crypto.js b/crypto.js index 6a70c34..8e110fb 100644 --- a/crypto.js +++ b/crypto.js @@ -24,14 +24,23 @@ function arraysEqual(a, b) { return diff === 0; } -function combine(secrets) { +function combineAll(secrets) { const result = new Uint8Array(32); for (const secret of secrets) { for (let i = 0; i < 32; i++) { result[i] ^= secret[i]; } } - return result[0] & 1; + return result; +} + +async function computePeerResult(sharedSeed, peerId) { + const data = new TextEncoder().encode(peerId); + const combined = new Uint8Array(sharedSeed.length + data.length); + combined.set(sharedSeed); + combined.set(data, sharedSeed.length); + const hash = await crypto.subtle.digest('SHA-256', combined); + return new Uint8Array(hash)[0] & 1; } function bufToBase64(buf) { diff --git a/index.html b/index.html index 2854f1c..126b2c5 100644 --- a/index.html +++ b/index.html @@ -93,14 +93,7 @@
Ergebnis
Warte auf Start...
- +