tinker-reversi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/assets/index-CuF3OwS6.css +1 -0
- package/dist/assets/index-DJDOR1jz.js +3872 -0
- package/dist/images/fabric.jpg +0 -0
- package/dist/images/fabric_normal.jpg +0 -0
- package/dist/images/wood.jpg +0 -0
- package/dist/images/wood_normal.jpg +0 -0
- package/dist/index.html +128 -0
- package/dist/sound/place.mp3 +0 -0
- package/icon.png +0 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# tinker-reversi
|
|
2
|
+
|
|
3
|
+
A polished 3D Reversi game for [TINKER](https://github.com/liriliri/tinker), built with Three.js.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Play directly in [browser](https://tinker.liriliri.io/games/reversi/), or install via TINKER: download from `https://tinker.liriliri.io/`, then run `npm i -g tinker-reversi`.
|
|
10
|
+
|
|
11
|
+
## Highlights
|
|
12
|
+
|
|
13
|
+
- **Classic Reversi rules** — play on a standard 8×8 board with legal-move hints, automatic passes, piece flipping, and final scoring
|
|
14
|
+
- **Play your way** — local two-player mode or a computer opponent with Easy, Normal, and Hard difficulty
|
|
15
|
+
- **Flexible controls** — mouse, touch, keyboard, and gamepad support
|
|
16
|
+
- **Immersive 3D board** — textured felt, a wood frame, lighting, shadows, reflections, and piece-drop animation
|
|
17
|
+
- **Bilingual interface** — English and Simplified Chinese
|
|
18
|
+
|
|
19
|
+
## How to Play
|
|
20
|
+
|
|
21
|
+
1. Choose local two-player mode or play against the computer, then select a difficulty.
|
|
22
|
+
2. Place a piece inside a highlighted square to surround and flip the opponent's pieces.
|
|
23
|
+
3. Click a square, or move the cursor with the arrow keys, WASD, or a gamepad.
|
|
24
|
+
4. Press **Space** or **Enter** to place a piece. Black moves first.
|
|
25
|
+
5. If you have no legal move, the turn passes automatically.
|
|
26
|
+
6. The player with the most pieces when neither side can move wins.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--deep: #061316;--ink: #e9eedb;--felt: #123c35;--cream: #f4edcf;--muted: #a8c1b3;--copper: #d79a59;--line: rgba(215, 154, 89, .42);--safe-top: env(safe-area-inset-top, 0px);--safe-bottom: env(safe-area-inset-bottom, 0px);--safe-left: env(safe-area-inset-left, 0px);--safe-right: env(safe-area-inset-right, 0px)}*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}html,body{width:100%;height:100%;margin:0;overflow:hidden;background:var(--deep)}body{color:var(--cream);font-family:Avenir Next,Helvetica Neue,Segoe UI,sans-serif;letter-spacing:.01em;-webkit-user-select:none;user-select:none}button{font:inherit}#app,#ui{position:fixed;top:0;right:0;bottom:0;left:0}canvas{display:block;width:100%;height:100%;cursor:grab;touch-action:none}#ui{z-index:2;pointer-events:none}.topbar{position:absolute;z-index:3;top:0;left:0;right:0;display:flex;align-items:center;gap:14px;padding:calc(18px + var(--safe-top)) calc(22px + var(--safe-right)) 18px calc(22px + var(--safe-left));border-bottom:1px solid rgba(215,154,89,.12);background:linear-gradient(180deg,#040f12f0,#040f1233),radial-gradient(circle at 50% -120%,rgba(54,112,91,.28),transparent 65%)}.scoreboard{position:fixed;bottom:calc(18px + var(--safe-bottom));left:50%;z-index:4;display:flex;align-items:center;gap:8px;padding:9px 16px;transform:translate(-50%);border:1px solid rgba(168,201,178,.3);border-radius:999px;background:linear-gradient(135deg,#123530f0,#07191cf0);box-shadow:inset 0 1px #ffffff1a,0 8px 22px #00000052;color:#f2e8c8;font-size:18px;font-weight:600;letter-spacing:.04em;text-shadow:0 1px 8px rgba(0,0,0,.35)}.score{display:flex;align-items:center;gap:7px}.score-divider{color:#d79a59b8;font-size:14px}.score-stone,.turn-stone{display:block;border-radius:50%;box-shadow:inset 1px 1px 2px #ffffff40,0 2px 5px #0006}.score-stone{width:13px;height:13px}.turn-pill{position:absolute;top:calc(18px + var(--safe-top));left:50%;display:flex;align-items:center;gap:9px;padding:8px 14px;transform:translate(-50%);border:1px solid rgba(168,201,178,.34);border-radius:999px;background:linear-gradient(135deg,#123530f0,#07191cf0);box-shadow:inset 0 1px #ffffff1f,0 8px 26px #00000052;color:#c5d5c4;font-size:12px;letter-spacing:.1em;transition:border-color .18s,box-shadow .18s}.turn-pill.thinking{border-color:#e2a960eb;box-shadow:inset 0 1px #ffffff1f,0 0 22px #d99a5847}.turn-stone{width:14px;height:14px}.black{background:radial-gradient(circle at 35% 28%,#51666a,#0c171a 58%,#03090b)}.white{background:radial-gradient(circle at 35% 28%,#fffdf1,#eee5c9 58%,#b8a986)}.black-text{color:#d99b5c}.white-text{color:#eef0dc}.top-actions{display:flex;gap:8px;margin-left:auto}.ghost-button,.secondary-button{pointer-events:auto;min-height:38px;padding:8px 13px;border:1px solid rgba(168,201,178,.3);border-radius:4px;background:#081e20c7;color:#d9e2d0;cursor:pointer;font-size:11px;letter-spacing:.12em;text-transform:uppercase;transition:background .16s,border-color .16s,transform .16s}.ghost-button:hover,.secondary-button:hover{border-color:#d99a58db;background:#18433bf0;color:#fff2cf}.icon-button{display:grid;width:38px;padding:8px;place-items:center}.sound-icon{width:17px;height:17px;fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.7}.sound-off-line,.icon-button.muted .sound-waves{display:none}.icon-button.muted .sound-off-line{display:block}.secondary-button:active,.primary-button:active{transform:translateY(1px)}.overlay{position:absolute;top:0;right:0;bottom:0;left:0;z-index:5;display:grid;place-items:center;padding:calc(24px + var(--safe-top)) calc(20px + var(--safe-right)) calc(24px + var(--safe-bottom)) calc(20px + var(--safe-left));background:radial-gradient(circle at 50% 42%,rgba(39,93,75,.3),transparent 48%),linear-gradient(135deg,#030f12e6,#041417f7);pointer-events:auto}.overlay.hidden{display:none}.menu-panel,.result-panel{position:relative;width:min(530px,91vw);padding:38px 42px 30px;border:1px solid rgba(215,154,89,.72);border-radius:7px;background:linear-gradient(145deg,#143731fa,#071c1ffc);box-shadow:0 28px 90px #000000ad,inset 0 1px #ecdbab29,inset 0 0 0 1px #04121480;color:var(--ink)}.menu-panel:before,.result-panel:before{position:absolute;top:8px;right:8px;bottom:8px;left:8px;border:1px solid rgba(215,154,89,.24);content:"";pointer-events:none}h2{margin:10px 0 5px;color:#f0e7c9;font-family:Georgia,Times New Roman,serif;font-weight:400;letter-spacing:-.02em;text-shadow:0 2px 16px rgba(0,0,0,.24)}h2{font-size:39px;text-align:center}.settings-grid{display:grid;grid-template-columns:1fr;gap:20px;margin-bottom:26px}.setting label{display:block;margin-bottom:9px;color:#a9c7b0;font-size:10px;font-weight:700;letter-spacing:.16em}.segmented{display:flex;gap:5px}.choice{flex:1;min-height:40px;padding:7px 8px;border:1px solid rgba(152,192,169,.3);border-radius:4px;background:#04181a6b;color:#e0e9d3b3;cursor:pointer;font-size:11px;letter-spacing:.07em;transition:color .16s,background .16s,border-color .16s}.choice:hover{border-color:#a9cdb1d1;color:#f1edcf}.choice.selected{border-color:#70a58a;background:linear-gradient(135deg,#286550,#174538);color:#f6edcf;box-shadow:inset 0 1px #ffffff24,0 5px 14px #0003}#difficultySetting.disabled{opacity:.38;pointer-events:none}.primary-button{display:flex;align-items:center;justify-content:center;width:100%;min-height:52px;padding:12px 17px;border:1px solid rgba(243,195,121,.82);border-radius:4px;background:linear-gradient(135deg,#bd7040,#91472d);color:#fff0c8;box-shadow:inset 0 1px #fff5d033,0 8px 18px #0003;cursor:pointer;font-size:12px;font-weight:700;letter-spacing:.15em;transition:background .16s,transform .16s}.primary-button:hover{background:linear-gradient(135deg,#d1844d,#a75334);box-shadow:inset 0 1px #fff5d047,0 8px 22px #00000047}.result-panel{width:min(390px,88vw);text-align:center}.result-count{display:flex;align-items:center;justify-content:center;gap:12px;margin:13px 0 18px;color:#dbcea880;font-size:22px}.result-number{display:inline-block;min-width:48px;color:#edf0dd;text-shadow:0 2px 12px rgba(0,0,0,.3);font-size:32px;font-weight:600}.result-actions{display:flex;flex-direction:column;gap:9px}.result-actions .secondary-button{width:100%}.mobile-controls{position:absolute;right:calc(18px + var(--safe-right));bottom:calc(18px + var(--safe-bottom));z-index:3;display:none;grid-template-columns:repeat(3,38px);grid-template-rows:repeat(3,38px);gap:4px;pointer-events:auto}.mobile-controls button{border:1px solid rgba(168,201,178,.36);border-radius:6px;background:linear-gradient(145deg,#123933f0,#05191cf0);box-shadow:inset 0 1px #ffffff1a,0 5px 14px #00000042;color:#e9e6c9;cursor:pointer;font-size:17px}.mobile-controls button:first-child{grid-column:2}.mobile-controls button:nth-child(2){grid-column:1;grid-row:2}.mobile-controls button:nth-child(3){grid-column:2;grid-row:2;border-color:#d79a59ad;color:#e3ae65;font-size:12px}.mobile-controls button:hover{border-color:#d79a59cc;background:linear-gradient(145deg,#1f4c3ff5,#092423f5)}.mobile-controls button:nth-child(4){grid-column:3;grid-row:2}.mobile-controls button:nth-child(5){grid-column:2;grid-row:3}button:focus-visible{outline:2px solid #e3b36c;outline-offset:3px}@media (pointer: coarse){.mobile-controls{display:grid}}@media (max-width: 600px){.topbar{gap:8px;padding-left:calc(14px + var(--safe-left));padding-right:calc(14px + var(--safe-right))}.scoreboard{font-size:15px}.turn-pill{padding:7px 10px;font-size:10px}.ghost-button{padding:8px 9px;font-size:9px}.menu-panel,.result-panel{padding:28px 24px 23px}}@media (max-height: 560px){.menu-panel,.result-panel{padding:20px 25px 17px}.settings-grid{margin-bottom:15px}}@media (prefers-reduced-motion: reduce){*,*:before,*:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important}}
|