Improved sharing

This commit is contained in:
Simon Cambier 2022-03-03 12:55:50 +01:00
parent dfe3caa7eb
commit 5ef3abb66e
9 changed files with 56 additions and 45 deletions

View File

@ -8,7 +8,7 @@
</RouterLink> </RouterLink>
<h1 <h1
class="z-20 py-2 font-mono text-3xl text-center bg-stone-300 dark:bg-stone-900"> class="z-20 py-2 font-mono text-3xl text-center bg-stone-300 dark:bg-stone-900">
N<span class="text-cyan-500">0</span>mbers<span class="text-xs">beta</span> N<span class="text-cyan-500">0</span>mbers<span class="text-xs">alpha</span>
</h1> </h1>
<button @click="isSideMenuVisible = true"> <button @click="isSideMenuVisible = true">
<IconMenu class="text-xl btn" /> <IconMenu class="text-xl btn" />

View File

@ -8,7 +8,7 @@
<IconClose class="absolute top-0 right-1 h-12 text-xl btn" /> <IconClose class="absolute top-0 right-1 h-12 text-xl btn" />
</button> </button>
</div> </div>
<div class="flex flex-col flex-1 content-center items-center"> <div class="flex flex-col flex-1 content-center items-center text-sm">
<div class="h-12" /> <div class="h-12" />
<InputSwitch <InputSwitch
class="mb-4" class="mb-4"
@ -24,15 +24,6 @@
v-model="isLocaleFrench" /> v-model="isLocaleFrench" />
</div> </div>
<div class="mb-8 text-xs text-stone-500">
Features to come:
<ul class="ml-4 list-disc">
<li>Keyboard input</li>
<li>Random number</li>
<li>Less bugs</li>
</ul>
</div>
<div class="text-xs text-stone-500 dark:text-stone-600"> <div class="text-xs text-stone-500 dark:text-stone-600">
Build {{ buildDate }} Build {{ buildDate }}
</div> </div>

View File

@ -1,34 +1,50 @@
import { i18n } from '@/i18n' import { i18n } from '@/i18n'
import { percentageDiff } from '@/utils' import { percentageDiff, setDailyPRNG, shuffle } from '@/utils'
import { numberOfGamesSinceStart, operations, result } from './game-state' import { numberOfGamesSinceStart, operations, result } from './game-state'
import { showToast } from './toast-manager' import { showToast } from './toast-manager'
const squareSymbols = ['🟦', '🟨', '🟫', '🟧', '🟥', '🟩', '🟪']
const roundSymbols = ['🔵', '🟡', '🟤', '🟠', '🔴', '🟢', '🟣']
export function shuffleSymbols(): void {
setDailyPRNG()
shuffle(squareSymbols)
shuffle(roundSymbols)
}
function getSharingText(): string { function getSharingText(): string {
console.log(squareSymbols)
console.log(roundSymbols)
// × ÷ + - // × ÷ + -
const emojis: string[] = [] const endResult = operations[operations.length - 1].result?.value ?? 0
const lines: string[] = []
for (const op of operations) { for (const op of operations) {
switch (op.operator) { if (op.left && !op.left.symbol) {
case '+': op.left.symbol = op.left.original
emojis.push('+') ? squareSymbols.pop()
break : roundSymbols.pop()
case '-': }
emojis.push('-') if (op.right && !op.right.symbol) {
break op.right.symbol = op.right.original
case '*': ? squareSymbols.pop()
emojis.push('×') : roundSymbols.pop()
break }
case '/': if (op.result && !op.result.symbol) {
emojis.push('÷') op.result.symbol = roundSymbols.pop()
break
} }
} }
const endResult = operations[operations.length - 1].result?.value ?? 0 for (const op of operations) {
lines.push(
`${op.left?.symbol} ${op.operator} ${op.right?.symbol} = ${op.result?.value === endResult ? endResult : op.result?.symbol}`,
)
}
return `N0mbers #${numberOfGamesSinceStart()} return `N0mbers #${numberOfGamesSinceStart()}
===========
${emojis.join(' ')} = ${endResult} ${lines.join('\n')} ${result.value === endResult ? '✔' : '❌'}
Score: ${100 - percentageDiff(result.value, endResult) * 100}%
===========
https://n0mbers.scambier.xyz` https://n0mbers.scambier.xyz`
} }

View File

@ -8,8 +8,8 @@ export const LSK_STATS = 'n0_stats'
export const operators = ['+', '-', '*', '/'] as const export const operators = ['+', '-', '*', '/'] as const
export const pools = { export const pools = {
1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25], 1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100],
2: [2, 2, 3, 3, 5, 5, 7, 11, 13, 17, 19, 23], 2: [2, 2, 3, 3, 5, 5, 7, 7, 11, 13, 17, 19, 23],
3: [5, 5, 5, 5, 5, 2, 2, 2, 2, 2], 3: [5, 5, 5, 5, 5, 2, 2, 2, 2, 2],
} as const } as const

View File

@ -12,7 +12,7 @@
"dailyDescription": "The daily challenge changes every day at midnight (CET), and is common to all players.", "dailyDescription": "The daily challenge changes every day at midnight (CET), and is common to all players.",
"share": "Share", "share": "Share",
"finishDailyToPlayRandom": "Finish the daily challenge to unlock.", "finishDailyToPlayRandom": "Finish the daily challenge to unlock.",
"gameDescription": "Combine the numbers to reach the result.", "gameDescription": "Combine the required numbers to reach the result.<br><strong>Game under development, some features are missing or changing.</strong>",
"randomDescription": "A challenge at random, just for fun.", "randomDescription": "A challenge at random, just for fun.",
"copiedInClipboard": "Copied in clipboard", "copiedInClipboard": "Copied in clipboard",
"soon": "Soon", "soon": "Soon",

View File

@ -9,7 +9,7 @@
"impossible": "☠", "impossible": "☠",
"dailyGame": "Défi quotidien", "dailyGame": "Défi quotidien",
"randomGame": "Nombre au hasard", "randomGame": "Nombre au hasard",
"gameDescription": "Combinez les nombres imposés afin d'atteindre le résultat.", "gameDescription": "Combinez les nombres imposés afin d'atteindre le résultat.<br><strong>Jeu en cours de développement, certaines fonctionnalités sont manquantes ou changeantes.</strong>",
"dailyDescription": "Le défi quotidien change chaque jour à minuit (CET), et est commun à tous les joueurs.", "dailyDescription": "Le défi quotidien change chaque jour à minuit (CET), et est commun à tous les joueurs.",
"randomDescription": "Une partie au hasard, pour le plaisir.", "randomDescription": "Une partie au hasard, pour le plaisir.",
"share": "Partager", "share": "Partager",

View File

@ -3,6 +3,12 @@ export type OperatorType = '+' | '-' | '*' | '/'
export type Plaquette = { export type Plaquette = {
value: number value: number
free: boolean free: boolean
/** If the plaquette is one of the pre-selected */
original: boolean
/** For sharing */
symbol?: string
} }
export type Operation = { export type Operation = {

View File

@ -40,7 +40,7 @@
<Transition name="slide_up"> <Transition name="slide_up">
<div v-if="gameIsRunning"> <div v-if="gameIsRunning">
<!-- OPERATORS --> <!-- Operators -->
<OperatorsList @click="selectOperator" /> <OperatorsList @click="selectOperator" />
<!-- Divider --> <!-- Divider -->
@ -64,7 +64,7 @@
v-html="t('endGame.failureLabel')" /> v-html="t('endGame.failureLabel')" />
<button <button
v-if="!isPracticeMode" v-if="!isPracticeMode"
@click="toClipboard" @click="sharing.toClipboard"
class="inline-flex items-center btn-border"> class="inline-flex items-center btn-border">
<IconShare class="mr-2" /> <IconShare class="mr-2" />
{{ t('share') }} {{ t('share') }}
@ -109,7 +109,7 @@ import {
plaquettes, plaquettes,
result, result,
} from '@/composables/game-state' } from '@/composables/game-state'
import { toClipboard } from '@/composables/sharing' import * as sharing from '@/composables/sharing'
import { hasPlayed } from '@/composables/statistics' import { hasPlayed } from '@/composables/statistics'
import { GameDifficultyType, GameStateType, pools } from '@/globals' import { GameDifficultyType, GameStateType, pools } from '@/globals'
import { OperatorType, Plaquette } from '@/types' import { OperatorType, Plaquette } from '@/types'
@ -121,8 +121,8 @@ import {
setDailyPRNG, setDailyPRNG,
setMathPRNG, setMathPRNG,
} from '@/utils' } from '@/utils'
import IconShare from '~icons/ph/share-network'
import IconReload from '~icons/ph/arrow-clockwise' import IconReload from '~icons/ph/arrow-clockwise'
import IconShare from '~icons/ph/share-network'
const { t } = useI18n() // call `useI18n`, and spread `t` from `useI18n` returning const { t } = useI18n() // call `useI18n`, and spread `t` from `useI18n` returning
@ -151,6 +151,7 @@ watch(
if (isOperationReady(op) && isOperationResultValid(op) && !op.result) { if (isOperationReady(op) && isOperationResultValid(op) && !op.result) {
op.result = { op.result = {
free: true, free: true,
original: false,
value: operate(op.operator!, op.left!.value, op.right!.value), value: operate(op.operator!, op.left!.value, op.right!.value),
} }
if (operations.length < 5 && !isEndGame.value) { if (operations.length < 5 && !isEndGame.value) {
@ -218,7 +219,7 @@ function reboot(): void {
for (let i = 0; i < numPlaquettes; ++i) { for (let i = 0; i < numPlaquettes; ++i) {
const rndItem = Math.floor(random() * poolCopy.length) const rndItem = Math.floor(random() * poolCopy.length)
const el = poolCopy.splice(rndItem, 1)[0] const el = poolCopy.splice(rndItem, 1)[0]
plaquettes.value.push({ value: el, free: true }) plaquettes.value.push({ value: el, free: true, original: true })
} }
// Solve it // Solve it

View File

@ -1,10 +1,7 @@
<template> <template>
<div class="flex flex-col grow p-1 w-full text-center"> <div class="flex flex-col grow p-1 w-full text-center">
<div class="flex flex-col grow gap-8 justify-center my-4 md:my-16"> <div class="flex flex-col grow gap-8 justify-center my-4 md:my-16">
<div> <div v-html="t('gameDescription')" />
{{ t('gameDescription') }}
<br>
</div>
<!-- Normal --> <!-- Normal -->
<div class="flex flex-col items-center"> <div class="flex flex-col items-center">