From b3cc17ea0d53edca3b7f7a648ae94a591ec98d44 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 21 Jan 2024 17:08:36 +0900
Subject: [PATCH] enhance(reversi): tweak reversi

---
 packages/frontend/assets/reversi/lose.mp3     | Bin 0 -> 9565 bytes
 packages/frontend/assets/reversi/win.mp3      | Bin 0 -> 25703 bytes
 .../frontend/src/pages/reversi/game.board.vue | 124 ++++++++++------
 .../src/pages/reversi/game.setting.vue        | 133 ++++++++++--------
 4 files changed, 153 insertions(+), 104 deletions(-)
 create mode 100644 packages/frontend/assets/reversi/lose.mp3
 create mode 100644 packages/frontend/assets/reversi/win.mp3

diff --git a/packages/frontend/assets/reversi/lose.mp3 b/packages/frontend/assets/reversi/lose.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..b62d50baf778bfe2beaf879ad10cd46433c50164
GIT binary patch
literal 9565
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
B<h}p^

literal 0
HcmV?d00001

diff --git a/packages/frontend/assets/reversi/win.mp3 b/packages/frontend/assets/reversi/win.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..25402ce2a683a7591017d9c6edaee9c84b4ad4ff
GIT binary patch
literal 25703
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

literal 0
HcmV?d00001

diff --git a/packages/frontend/src/pages/reversi/game.board.vue b/packages/frontend/src/pages/reversi/game.board.vue
index 5e28f55902..6ad779c605 100644
--- a/packages/frontend/src/pages/reversi/game.board.vue
+++ b/packages/frontend/src/pages/reversi/game.board.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<MkSpacer :contentMax="600">
+<MkSpacer :contentMax="500">
 	<div :class="$style.root" class="_gaps">
 		<div style="display: flex; align-items: center; justify-content: center; gap: 10px;">
 			<span>({{ i18n.ts._reversi.black }})</span>
@@ -35,53 +35,55 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 
 		<div :class="$style.board">
-			<div v-if="showBoardLabels" :class="$style.labelsX">
-				<span v-for="i in game.map[0].length" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
-			</div>
-			<div style="display: flex;">
-				<div v-if="showBoardLabels" :class="$style.labelsY">
-					<div v-for="i in game.map.length" :class="$style.labelsYLabel">{{ i }}</div>
+			<div :class="$style.boardInner">
+				<div v-if="showBoardLabels" :class="$style.labelsX">
+					<span v-for="i in game.map[0].length" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
 				</div>
-				<div :class="$style.boardCells" :style="cellsStyle">
-					<div
-						v-for="(stone, i) in engine.board"
-						:key="i"
-						v-tooltip="`${String.fromCharCode(65 + engine.posToXy(i)[0])}${engine.posToXy(i)[1] + 1}`"
-						:class="[$style.boardCell, {
-							[$style.boardCell_empty]: stone == null,
-							[$style.boardCell_none]: engine.map[i] === 'null',
-							[$style.boardCell_isEnded]: game.isEnded,
-							[$style.boardCell_myTurn]: !game.isEnded && isMyTurn,
-							[$style.boardCell_can]: turnUser ? engine.canPut(turnUser.id === blackUser.id, i) : null,
-							[$style.boardCell_prev]: engine.prevPos === i
-						}]"
-						@click="putStone(i)"
-					>
-						<Transition
-							:enterActiveClass="$style.transition_flip_enterActive"
-							:leaveActiveClass="$style.transition_flip_leaveActive"
-							:enterFromClass="$style.transition_flip_enterFrom"
-							:leaveToClass="$style.transition_flip_leaveTo"
-							mode="default"
+				<div style="display: flex;">
+					<div v-if="showBoardLabels" :class="$style.labelsY">
+						<div v-for="i in game.map.length" :class="$style.labelsYLabel">{{ i }}</div>
+					</div>
+					<div :class="$style.boardCells" :style="cellsStyle">
+						<div
+							v-for="(stone, i) in engine.board"
+							:key="i"
+							v-tooltip="`${String.fromCharCode(65 + engine.posToXy(i)[0])}${engine.posToXy(i)[1] + 1}`"
+							:class="[$style.boardCell, {
+								[$style.boardCell_empty]: stone == null,
+								[$style.boardCell_none]: engine.map[i] === 'null',
+								[$style.boardCell_isEnded]: game.isEnded,
+								[$style.boardCell_myTurn]: !game.isEnded && isMyTurn,
+								[$style.boardCell_can]: turnUser ? engine.canPut(turnUser.id === blackUser.id, i) : null,
+								[$style.boardCell_prev]: engine.prevPos === i
+							}]"
+							@click="putStone(i)"
 						>
-							<template v-if="useAvatarAsStone">
-								<img v-if="stone === true" :class="$style.boardCellStone" :src="blackUser.avatarUrl"/>
-								<img v-else-if="stone === false" :class="$style.boardCellStone" :src="whiteUser.avatarUrl"/>
-							</template>
-							<template v-else>
-								<img v-if="stone === true" :class="$style.boardCellStone" src="/client-assets/reversi/stone_b.png"/>
-								<img v-else-if="stone === false" :class="$style.boardCellStone" src="/client-assets/reversi/stone_w.png"/>
-							</template>
-						</Transition>
+							<Transition
+								:enterActiveClass="$style.transition_flip_enterActive"
+								:leaveActiveClass="$style.transition_flip_leaveActive"
+								:enterFromClass="$style.transition_flip_enterFrom"
+								:leaveToClass="$style.transition_flip_leaveTo"
+								mode="default"
+							>
+								<template v-if="useAvatarAsStone">
+									<img v-if="stone === true" :class="$style.boardCellStone" :src="blackUser.avatarUrl"/>
+									<img v-else-if="stone === false" :class="$style.boardCellStone" :src="whiteUser.avatarUrl"/>
+								</template>
+								<template v-else>
+									<img v-if="stone === true" :class="$style.boardCellStone" src="/client-assets/reversi/stone_b.png"/>
+									<img v-else-if="stone === false" :class="$style.boardCellStone" src="/client-assets/reversi/stone_w.png"/>
+								</template>
+							</Transition>
+						</div>
+					</div>
+					<div v-if="showBoardLabels" :class="$style.labelsY">
+						<div v-for="i in game.map.length" :class="$style.labelsYLabel">{{ i }}</div>
 					</div>
 				</div>
-				<div v-if="showBoardLabels" :class="$style.labelsY">
-					<div v-for="i in game.map.length" :class="$style.labelsYLabel">{{ i }}</div>
+				<div v-if="showBoardLabels" :class="$style.labelsX">
+					<span v-for="i in game.map[0].length" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
 				</div>
 			</div>
-			<div v-if="showBoardLabels" :class="$style.labelsX">
-				<span v-for="i in game.map[0].length" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
-			</div>
 		</div>
 
 		<div v-if="game.isEnded" class="_panel _gaps_s" style="padding: 16px;">
@@ -155,6 +157,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
 import { userPage } from '@/filters/user.js';
 import * as sound from '@/scripts/sound.js';
 import * as os from '@/os.js';
+import { confetti } from '@/scripts/confetti.js';
 
 const $i = signinRequired();
 
@@ -329,6 +332,22 @@ function onStreamLog(log: Reversi.Serializer.Log & { id: string | null }) {
 
 function onStreamEnded(x) {
 	game.value = deepClone(x.game);
+
+	if (game.value.winnerId === $i.id) {
+		confetti({
+			duration: 1000 * 3,
+		});
+
+		sound.playUrl('/client-assets/reversi/win.mp3', {
+			volume: 1,
+			playbackRate: 1,
+		});
+	} else {
+		sound.playUrl('/client-assets/reversi/lose.mp3', {
+			volume: 1,
+			playbackRate: 1,
+		});
+	}
 }
 
 function checkEnd() {
@@ -465,8 +484,27 @@ $gap: 4px;
 
 .board {
 	width: 100%;
-	max-width: 500px;
+	box-sizing: border-box;
 	margin: 0 auto;
+
+	padding: 7px;
+	background: #8C4F26;
+	box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
+	border-radius: 12px;
+}
+
+.boardInner {
+	padding: 32px;
+
+	background: var(--panel);
+	box-shadow: 0 0 2px 1px #ce8a5c, inset 0 0 1px 1px #693410;
+	border-radius: 8px;
+}
+
+@container (max-width: 400px) {
+	.boardInner {
+		padding: 16px;
+	}
 }
 
 .labelsX {
diff --git a/packages/frontend/src/pages/reversi/game.setting.vue b/packages/frontend/src/pages/reversi/game.setting.vue
index 9ca107278b..d69176e25a 100644
--- a/packages/frontend/src/pages/reversi/game.setting.vue
+++ b/packages/frontend/src/pages/reversi/game.setting.vue
@@ -8,72 +8,74 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<MkSpacer :contentMax="600">
 		<div style="text-align: center;"><b><MkUserName :user="game.user1"/></b> vs <b><MkUserName :user="game.user2"/></b></div>
 
-		<div class="_gaps">
-			<div style="font-size: 1.5em; text-align: center;">{{ i18n.ts._reversi.gameSettings }}</div>
+		<div :class="{ [$style.disallow]: isReady }">
+			<div class="_gaps" :class="{ [$style.disallowInner]: isReady }">
+				<div style="font-size: 1.5em; text-align: center;">{{ i18n.ts._reversi.gameSettings }}</div>
 
-			<div class="_panel">
-				<div style="display: flex; align-items: center; padding: 16px; border-bottom: solid 1px var(--divider);">
-					<div>{{ mapName }}</div>
-					<MkButton style="margin-left: auto;" @click="chooseMap">{{ i18n.ts._reversi.chooseBoard }}</MkButton>
-				</div>
+				<div class="_panel">
+					<div style="display: flex; align-items: center; padding: 16px; border-bottom: solid 1px var(--divider);">
+						<div>{{ mapName }}</div>
+						<MkButton style="margin-left: auto;" @click="chooseMap">{{ i18n.ts._reversi.chooseBoard }}</MkButton>
+					</div>
 
-				<div style="padding: 16px;">
-					<div v-if="game.map == null"><i class="ti ti-dice"></i></div>
-					<div v-else :class="$style.board" :style="{ 'grid-template-rows': `repeat(${ game.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.map[0].length }, 1fr)` }">
-						<div v-for="(x, i) in game.map.join('')" :class="[$style.boardCell, { [$style.boardCellNone]: x == ' ' }]" @click="onMapCellClick(i, x)">
-							<i v-if="x === 'b' || x === 'w'" style="pointer-events: none; user-select: none;" :class="x === 'b' ? 'ti ti-circle-filled' : 'ti ti-circle'"></i>
+					<div style="padding: 16px;">
+						<div v-if="game.map == null"><i class="ti ti-dice"></i></div>
+						<div v-else :class="$style.board" :style="{ 'grid-template-rows': `repeat(${ game.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.map[0].length }, 1fr)` }">
+							<div v-for="(x, i) in game.map.join('')" :class="[$style.boardCell, { [$style.boardCellNone]: x == ' ' }]" @click="onMapCellClick(i, x)">
+								<i v-if="x === 'b' || x === 'w'" style="pointer-events: none; user-select: none;" :class="x === 'b' ? 'ti ti-circle-filled' : 'ti ti-circle'"></i>
+							</div>
 						</div>
 					</div>
 				</div>
+
+				<MkFolder :defaultOpen="true">
+					<template #label>{{ i18n.ts._reversi.blackOrWhite }}</template>
+
+					<MkRadios v-model="game.bw">
+						<option value="random">{{ i18n.ts.random }}</option>
+						<option :value="'1'">
+							<I18n :src="i18n.ts._reversi.blackIs" tag="span">
+								<template #name>
+									<b><MkUserName :user="game.user1"/></b>
+								</template>
+							</I18n>
+						</option>
+						<option :value="'2'">
+							<I18n :src="i18n.ts._reversi.blackIs" tag="span">
+								<template #name>
+									<b><MkUserName :user="game.user2"/></b>
+								</template>
+							</I18n>
+						</option>
+					</MkRadios>
+				</MkFolder>
+
+				<MkFolder :defaultOpen="true">
+					<template #label>{{ i18n.ts._reversi.timeLimitForEachTurn }}</template>
+					<template #suffix>{{ game.timeLimitForEachTurn }}{{ i18n.ts._time.second }}</template>
+
+					<MkRadios v-model="game.timeLimitForEachTurn">
+						<option :value="5">5{{ i18n.ts._time.second }}</option>
+						<option :value="10">10{{ i18n.ts._time.second }}</option>
+						<option :value="30">30{{ i18n.ts._time.second }}</option>
+						<option :value="60">60{{ i18n.ts._time.second }}</option>
+						<option :value="90">90{{ i18n.ts._time.second }}</option>
+						<option :value="120">120{{ i18n.ts._time.second }}</option>
+						<option :value="180">180{{ i18n.ts._time.second }}</option>
+						<option :value="3600">3600{{ i18n.ts._time.second }}</option>
+					</MkRadios>
+				</MkFolder>
+
+				<MkFolder :defaultOpen="true">
+					<template #label>{{ i18n.ts._reversi.rules }}</template>
+
+					<div class="_gaps_s">
+						<MkSwitch v-model="game.isLlotheo" @update:modelValue="updateSettings('isLlotheo')">{{ i18n.ts._reversi.isLlotheo }}</MkSwitch>
+						<MkSwitch v-model="game.loopedBoard" @update:modelValue="updateSettings('loopedBoard')">{{ i18n.ts._reversi.loopedMap }}</MkSwitch>
+						<MkSwitch v-model="game.canPutEverywhere" @update:modelValue="updateSettings('canPutEverywhere')">{{ i18n.ts._reversi.canPutEverywhere }}</MkSwitch>
+					</div>
+				</MkFolder>
 			</div>
-
-			<MkFolder :defaultOpen="true">
-				<template #label>{{ i18n.ts._reversi.blackOrWhite }}</template>
-
-				<MkRadios v-model="game.bw">
-					<option value="random">{{ i18n.ts.random }}</option>
-					<option :value="'1'">
-						<I18n :src="i18n.ts._reversi.blackIs" tag="span">
-							<template #name>
-								<b><MkUserName :user="game.user1"/></b>
-							</template>
-						</I18n>
-					</option>
-					<option :value="'2'">
-						<I18n :src="i18n.ts._reversi.blackIs" tag="span">
-							<template #name>
-								<b><MkUserName :user="game.user2"/></b>
-							</template>
-						</I18n>
-					</option>
-				</MkRadios>
-			</MkFolder>
-
-			<MkFolder :defaultOpen="true">
-				<template #label>{{ i18n.ts._reversi.timeLimitForEachTurn }}</template>
-				<template #suffix>{{ game.timeLimitForEachTurn }}{{ i18n.ts._time.second }}</template>
-
-				<MkRadios v-model="game.timeLimitForEachTurn">
-					<option :value="5">5{{ i18n.ts._time.second }}</option>
-					<option :value="10">10{{ i18n.ts._time.second }}</option>
-					<option :value="30">30{{ i18n.ts._time.second }}</option>
-					<option :value="60">60{{ i18n.ts._time.second }}</option>
-					<option :value="90">90{{ i18n.ts._time.second }}</option>
-					<option :value="120">120{{ i18n.ts._time.second }}</option>
-					<option :value="180">180{{ i18n.ts._time.second }}</option>
-					<option :value="3600">3600{{ i18n.ts._time.second }}</option>
-				</MkRadios>
-			</MkFolder>
-
-			<MkFolder :defaultOpen="true">
-				<template #label>{{ i18n.ts._reversi.rules }}</template>
-
-				<div class="_gaps_s">
-					<MkSwitch v-model="game.isLlotheo" @update:modelValue="updateSettings('isLlotheo')">{{ i18n.ts._reversi.isLlotheo }}</MkSwitch>
-					<MkSwitch v-model="game.loopedBoard" @update:modelValue="updateSettings('loopedBoard')">{{ i18n.ts._reversi.loopedMap }}</MkSwitch>
-					<MkSwitch v-model="game.canPutEverywhere" @update:modelValue="updateSettings('canPutEverywhere')">{{ i18n.ts._reversi.canPutEverywhere }}</MkSwitch>
-				</div>
-			</MkFolder>
 		</div>
 	</MkSpacer>
 	<template #footer>
@@ -123,7 +125,7 @@ const props = defineProps<{
 }>();
 
 const game = ref<Misskey.entities.ReversiGameDetailed>(deepClone(props.game));
-const isLlotheo = ref<boolean>(false);
+
 const mapName = computed(() => {
 	if (game.value.map == null) return 'Random';
 	const found = Object.values(Reversi.maps).find(x => x.data.join('') === game.value.map.join(''));
@@ -236,6 +238,15 @@ onUnmounted(() => {
 </script>
 
 <style lang="scss" module>
+.disallow {
+	cursor: not-allowed;
+}
+.disallowInner {
+	pointer-events: none;
+	user-select: none;
+	opacity: 0.7;
+}
+
 .board {
 	display: grid;
 	grid-gap: 4px;