diff --git a/check.mjs b/check.mjs index f00f33b..b2dc985 100644 --- a/check.mjs +++ b/check.mjs @@ -119,6 +119,34 @@ all(n => { expect('game8', n, want, `раскладка кончается так: ${o.join(' или ')}`, true); }); +// Game 7: seven matches into the pot one or two at a time, then back to the table; whoever puts down +// the seventh wins; the opponent starts and the turns alternate throughout. The machine gets the count +// taken (first half) or put back (second half, with 2 entered as 111 and 5 as 110) and shows the count +// to reach. Against every opponent the player following it must always win. +const bad7 = new Set(); +const play7 = (half, table, myTurn, path) => { + if (!myTurn) { + for (const n of [1, 2]) { + const src = half === 1 ? table : 7 - table; + if (n > src) continue; + const t = half === 1 ? table - n : table + n; + if (half === 2 && t === 7) { bad7.add(path + ` противник ${n} и выигрывает`); continue; } + play7(half === 1 && t === 0 ? 2 : half, t, true, path + ` противник ${n};`); + } + return; + } + const count = half === 1 ? 7 - table : table; + const input = half === 2 && count === 2 ? 0b111 : half === 2 && count === 5 ? 0b110 : count; + const n = run(P.game7, input) - count; + const src = half === 1 ? table : 7 - table; + if (n < 1 || n > 2 || n > src) { bad7.add(path + ` машина советует ${run(P.game7, input)} при ${count}`); return; } + const t = half === 1 ? table - n : table + n; + if (half === 2 && t === 7) return; // the player puts down the seventh match + play7(half === 1 && t === 0 ? 2 : half, t, false, path + ` вы ${n};`); +}; +play7(1, 7, false, ''); +for (const s of bad7) { failed++; console.log('ОШИБКА game7:' + s); } + // Logic elements from the Habr article. all(n => { const A = n >> 2 & 1, B = n >> 1 & 1, C = n & 1; diff --git a/index.html b/index.html index 5365662..4b627ca 100644 --- a/index.html +++ b/index.html @@ -160,6 +160,15 @@ table.tt { border-collapse: collapse; font-family: var(--font-mono); font-size: .card { width: 64px; height: 56px; background: #fff; border: 1px solid #b9c3d6; border-radius: 4px; display: grid; place-items: center; align-content: center; color: #23409a; font: 700 10px var(--font-body); box-shadow: 0 1px 2px rgba(0, 0, 0, .18); flex: none; } .card svg { width: 42px; height: 30px; fill: none; stroke: #23409a; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; } .card.label { width: auto; height: 30px; padding: 0 8px; font-size: 11px; letter-spacing: .05em; } +.matches { display: flex; flex-wrap: wrap; gap: 3px; min-height: 40px; align-items: end; } +.match { width: 8px; height: 40px; } +.match rect { fill: #e8c48a; stroke: #b08a4e; stroke-width: .6; } +.match ellipse { fill: #b3261e; } +.players, .piles2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; width: 100%; } +.player { display: grid; gap: 6px; align-content: start; } +.player-top { display: flex; gap: 8px; align-items: center; min-height: 34px; } +.tok { width: 32px; height: 32px; border-radius: 50%; display: inline-grid; place-items: center; color: #fff; font: 700 15px var(--font-body); box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .25); } +.tok-0 { background: #c8222c; } .tok-1 { background: #23409a; } .tok-2 { background: #e0a800; } .tok-x { background: #8a8f99; } .card.back { background: repeating-linear-gradient(45deg, #23409a 0 4px, #3552ad 4px 8px); border-color: #1b2f73; } @@ -812,8 +821,8 @@ table.tt { border-collapse: collapse; font-family: var(--font-mono); font-size: let order, piles, placed, cur, shown, done; const deal = () => { const deck = Object.keys(KINDS).flatMap(k => KINDS[k].names.map(name => ({ k, name }))); - for (let i = deck.length - 1; i > 0; i--) { const j = rnd(i + 1); [deck[i], deck[j]] = [deck[j], deck[i]]; } - order = Object.keys(KINDS).sort(() => Math.random() - .5); + shuffle(deck); + order = shuffle(Object.keys(KINDS)); piles = { P: deck.slice(0, 4), Z: deck.slice(4, 8), N: deck.slice(8) }; // index 0 is the top card placed = { P: [], Z: [], N: [] }; cur = 'P'; shown = false; done = false; }; @@ -856,10 +865,88 @@ table.tt { border-collapse: collapse; font-family: var(--font-mono); font-size: deal(); draw(); } + const shuffle = a => { for (let i = a.length - 1; i > 0; i--) { const j = rnd(i + 1); [a[i], a[j]] = [a[j], a[i]]; } return a; }; + const MATCH = ''; + const matchesHtml = n => `
${stage < 3 ? 'Оператор отворачивается, пока игроки берут спички и делят фишки.' : + !open ? 'Теперь оператор считает спички на столе и вводит их число в машину (в игре 6 — ответы игрока на вопросы игры 1 про это число).' : + [0, 1, 2].map(i => `игрок № ${i + 1} — ${owner[i]}`).join(', ') + '. Сверьте с лампами.'}
+${winner !== null ? `Седьмую спичку положил${winner ? 'и вы. Победа!' : ' противник.'}` :
+ `${half === 1 ? 'Первая половина: берут со стола в котёл.' : 'Вторая половина: возвращают из котла на стол.'} ${turn ? 'Ваш ход' : 'Ходит противник'}.` +
+ (turn ? ` ${half === 1 ? 'Взято со стола' : 'Положено на стол'}: ${count}, в машину вводится ${input}.` : '')}
+
${log.join(' → ')}