tripeaks-solitaire-solver-j.../src/index.html
2022-09-14 07:17:24 -04:00

300 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Tripeaks Solver 73k</title>
</head>
<body class="text-dark">
<nav class="navbar navbar-expand navbar-light bg-light mb-4">
<div class="container-fluid">
<a class="navbar-brand text-dark" href="#">Tripeaks Solver 73k</a>
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link fs-5" href="https://73k.us/"
>73k
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-box-arrow-up-right"
viewBox="0 0 16 16"
style="margin-top: -0.27em"
>
<path
fill-rule="evenodd"
d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z"
/>
<path
fill-rule="evenodd"
d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z"
/></svg
></a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="https://github.com/apiontek/tripeaks-solitaire-solver-js-73k"
><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
class="bi bi-github"
viewBox="0 0 16 16"
>
<path
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
/></svg
></a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://twitter.com/adampiontek"
><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
class="bi bi-twitter"
viewBox="0 0 16 16"
>
<path
d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z"
/></svg
></a>
</li>
</ul>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col">
<!-- <h1 class="mb-3">Tripeaks Solver</h1> -->
<div
x-data="{show: false}"
class="accordion mb-4"
id="readMeAccordion"
>
<div class="accordion-item">
<h2 id="readMeHeader" class="accordion-header">
<button
class="accordion-button fs-5"
:class="{'collapsed': !show}"
type="button"
:aria-expanded="show ? 'true' : 'false'"
aria-controls="collapseOne"
@click="show = !show"
>
Read Me / How To
</button>
</h2>
<div
id="collapseOne"
class="accordion-collapse collapse"
:class="{'show': show}"
aria-labelledby="headingOne"
>
<div class="accordion-body">
<p>
Enter cards representing a Tripeaks game below. Enter each
card as 2 characters representing the rank (A, 2, 3, 4, 5,
6, 7, 8, 9, T, J, Q, K) and suit (C, D, H, S). For example,
"TH" is the Ten of Hearts.
</p>
<p>
Use a single zero ("0") for unknown cards. However, the last
34 cards (bottom row & stock) must be known, and you don't
need to enter unknown cards before the first card you know.
</p>
<p>
Entry is case-insensitive, and you can separate cards with
any character (space, comma, etc), or use no separator.
Valid examples:
</p>
<ul>
<li>
7S 5D 7C 2D 0 0 3S 2H 3H 9H KC QC TD 8D 9C 7H 9D JS QS 4H
5C 5S 4C 2C QD 8C KD 3D KS JD 2S 7D KH AH 5H 9S 4S QH 6S
6D 3C JC TC 8H 6C TH AS AD 6H
</li>
<li>
jc, ts, 6d, 7h, qh, 3s, 5h, jh, 6h, 2d, ac, 7s, 7c, 3d,
kd, 9s, 3c, th, 6c, ah, 8h, tc, 4s, 8c, ad, 3h, ks, 6s,
js, 7d, jd, td, 2c, kh
</li>
<li>
7c03s0qsjc00JSasTSadtcqd9s4s2h9h8sjh6c3dks5s5c6h9C2Cac8C6d5DTH8dkckd9d4c5h8hqh6s
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-9 col-xl-8">
<!-- User input of game cards -->
<form
id="cardsInputForm"
x-data="cardsInputForm"
@submit.prevent="$dispatch('solve-game')"
class="needs-validation"
:class="{'was-validated': isFormValid && inputValue.length > 2 }"
novalidate
>
<h3 id="cardsInputLabel" for="cardsInput" class="form-label">
Enter Your Cards
</h3>
<div class="input-group">
<input
id="cardsInput"
aria-describedby="cardsInputLabel"
type="text"
x-model="inputValue"
class="form-control"
:class="{ 'is-valid': isFormValid && inputValue.length > 2, 'is-invalid': !isFormValid && inputValue.length > 2 }"
maxlength="206"
@keyup.debounce="validateCardsInput()"
placeholder="e.g., 2S TC 4S QD KH 5S 9S ..."
:disabled="$store.global.solvingInProgress"
/>
<button
id="cardsInputButton"
type="submit"
class="btn btn-outline-primary"
:disabled="!isFormValid || $store.global.solvingInProgress"
>
Solve
</button>
</div>
<div class="mb-3">
<template x-for="msg in validMessages">
<div
class="valid-feedback"
:class="{ 'd-block': validCards.length > 0 }"
x-text="msg"
></div>
</template>
<template x-for="msg in invalidMessages">
<div
class="invalid-feedback"
:class="{ 'd-block': invalidMessages.length > 0 && inputValue.length > 2 }"
x-text="msg"
></div>
</template>
</div>
</form>
<!-- Friendly display of game cards -->
<div
id="playingCardsPreview"
x-data="playingCardsPreview"
class="mb-4"
>
<div
id="gamePyramid"
class="game-pyramid-container p-2 p-md-3 p-lg-4"
>
<!-- first/top row (index 0, row 1) -->
<span class="visually-hidden">Game Row 1, Top of Peaks</span>
<template x-for="(card, index) in cardsBySlice(0, 3)">
<div
x-html="cardSvg(card)"
:class="`game-pyramid-card game-pyramid-card-0-${index}`"
></div>
</template>
<!-- second row (index 1, row 2) -->
<span class="visually-hidden">Game Row 2, Second Row</span>
<template x-for="(card, index) in cardsBySlice(3, 9)">
<div
x-html="cardSvg(card)"
:class="`game-pyramid-card game-pyramid-card-1-${index}`"
></div>
</template>
<!-- third row (index 2, row 3) -->
<span class="visually-hidden">Game Row 3, Third Row</span>
<template x-for="(card, index) in cardsBySlice(9, 18)">
<div
x-html="cardSvg(card)"
:class="`game-pyramid-card game-pyramid-card-2-${index}`"
></div>
</template>
<!-- last/bottom row (index 3, row 4) -->
<span class="visually-hidden">Game Row 4, Base of Peaks</span>
<template x-for="(card, index) in cardsBySlice(18, 28)">
<div
x-html="cardSvg(card)"
:class="`game-pyramid-card game-pyramid-card-3-${index}`"
></div>
</template>
<!-- stock cards -->
<span class="visually-hidden"
>Game Stock, the Draw Cards</span
>
<template x-for="(card, index) in cardsBySlice(28, 52)">
<div
x-html="card === 0 || card === '0' ? cardSvgs['2B'] : cardSvgs[card]"
:class="`game-pyramid-card game-pyramid-card-4-${index}`"
></div>
</template>
</div>
</div>
</div>
<div class="col-12 col-lg-3 col-xl-4">
<!-- Display of solvingprogress or solution -->
<div id="gameSolving" x-data="gameSolving" x-init="onInit()">
<div class="d-flex justify-content-start">
<div
class="spinner-border me-2"
role="status"
x-show="$store.global.solvingInProgress"
></div>
<h3
@solve-game.window="startSolver()"
x-text="headerText"
></h3>
</div>
<ul x-show="$store.global.solvingInProgress">
<template x-for="msg in statusMessages">
<li x-text="msg"></li>
</template>
</ul>
<!-- <p x-show="" x-text="statusMessage"></p> -->
<ol x-show="solutionMoves.length > 0">
<template x-for="move in solutionMoves">
<li x-text="move"></li>
</template>
</ol>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class="py-3 my-4">
<p class="text-center text-muted">
© 2022 <a href="https://73k.us/">Adam Piontek</a>
</p>
</footer>
<script type="module" src="./js/main.js"></script>
</body>
</html>