Compare commits
10 Commits
80064a98e5
...
ba0000af2a
Author | SHA1 | Date | |
---|---|---|---|
ba0000af2a | |||
43198a382b | |||
38d77bcc7c | |||
bbb7460723 | |||
fe831a6004 | |||
53261b719e | |||
cada72746a | |||
5ef3abb66e | |||
dfe3caa7eb | |||
fb0b8c010f |
|
@ -12,6 +12,7 @@
|
||||||
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png" sizes="180x180">
|
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png" sizes="180x180">
|
||||||
<link rel="mask-icon" href="/icons/favicon.svg" color="#1C1917">
|
<link rel="mask-icon" href="/icons/favicon.svg" color="#1C1917">
|
||||||
<meta name="theme-color" content="#1C1917">
|
<meta name="theme-color" content="#1C1917">
|
||||||
|
<script async src="https://stats.scambier.xyz/script.js" data-website-id="25b0bcf4-c4c1-4da4-a1bd-3251f7bc3878"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-stone-300 text-stone-900 dark:bg-stone-900 dark:text-stone-200 h-full relative">
|
<body class="bg-stone-300 text-stone-900 dark:bg-stone-900 dark:text-stone-200 h-full relative">
|
||||||
|
|
|
@ -20,14 +20,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted } from 'vue'
|
|
||||||
|
|
||||||
import AppHeader from '@/components/AppHeader.vue'
|
import AppHeader from '@/components/AppHeader.vue'
|
||||||
import SideMenu from '@/components/SideMenu.vue'
|
import SideMenu from '@/components/SideMenu.vue'
|
||||||
import ToastMessage from '@/components/ToastMessage.vue'
|
import ToastMessage from '@/components/ToastMessage.vue'
|
||||||
import { plausible } from '@/analytics'
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
plausible.enableAutoPageviews()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
10
src/algo.ts
10
src/algo.ts
|
@ -5,7 +5,7 @@ import { shuffle } from './utils'
|
||||||
type HistoryType = { a: number; b: number; op: OperatorType }[]
|
type HistoryType = { a: number; b: number; op: OperatorType }[]
|
||||||
|
|
||||||
export function isHardEnough(num: number): boolean {
|
export function isHardEnough(num: number): boolean {
|
||||||
return num % 100 > 0
|
return num % 100 > 0 && num % 50 > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isOperationResultValid(op: Operation): boolean {
|
export function isOperationResultValid(op: Operation): boolean {
|
||||||
|
@ -63,7 +63,7 @@ export function isSolvable(result: number, plaquettes: number[]): boolean {
|
||||||
for (const item of history) {
|
for (const item of history) {
|
||||||
if (item.a < item.b) [item.a, item.b] = [item.b, item.a]
|
if (item.a < item.b) [item.a, item.b] = [item.b, item.a]
|
||||||
console.log(
|
console.log(
|
||||||
`${item.a} ${item.op} ${item.b} = ${operate(item.op, item.a, item.b)}`,
|
`${item.a} ${item.op === '*' ? 'x' : item.op} ${item.b} = ${operate(item.op, item.a, item.b)}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ export function isSolvable(result: number, plaquettes: number[]): boolean {
|
||||||
histories.push(history)
|
histories.push(history)
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = true
|
found = true
|
||||||
console.log(`1e solution trouvée en ${Date.now() - start}ms`)
|
console.log(`1st solution found in ${Date.now() - start}ms`)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -138,12 +138,12 @@ export function isSolvable(result: number, plaquettes: number[]): boolean {
|
||||||
loopOperations(plaquettes, [])
|
loopOperations(plaquettes, [])
|
||||||
if (found) {
|
if (found) {
|
||||||
console.log(
|
console.log(
|
||||||
`Réussite : ${Date.now() - start}ms et ${numberOfIterations} iterations`,
|
`Success : ${Date.now() - start}ms and ${numberOfIterations} iterations`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(
|
console.log(
|
||||||
`Echec : ${Date.now() - start}ms et ${numberOfIterations} iterations`,
|
`Failure : ${Date.now() - start}ms and ${numberOfIterations} iterations`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
import Plausible from 'plausible-tracker'
|
|
||||||
|
|
||||||
// Setup tracking
|
|
||||||
export const plausible = Plausible({
|
|
||||||
domain: 'n0mbers.scambier.xyz',
|
|
||||||
apiHost: 'https://stats.scambier.xyz',
|
|
||||||
})
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -17,7 +17,7 @@ export const operations = reactive<Operation[]>([getEmptyOperation()])
|
||||||
export const plaquettes = ref<Plaquette[]>([])
|
export const plaquettes = ref<Plaquette[]>([])
|
||||||
export const result = ref(0)
|
export const result = ref(0)
|
||||||
|
|
||||||
// #region Difficulty-related constants
|
// #region Difficulty-related values
|
||||||
|
|
||||||
export const gameDifficulty = ref(GameDifficultyType.Normal)
|
export const gameDifficulty = ref(GameDifficultyType.Normal)
|
||||||
|
|
||||||
|
@ -29,6 +29,10 @@ export const startingNumberOfPlaquettes = computed(() =>
|
||||||
gameDifficulty.value === GameDifficultyType.Hard ? 6 : 5,
|
gameDifficulty.value === GameDifficultyType.Hard ? 6 : 5,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const isHardMode = computed(
|
||||||
|
() => gameDifficulty.value === GameDifficultyType.Hard,
|
||||||
|
)
|
||||||
|
|
||||||
// #endregion Difficulty-related constants
|
// #endregion Difficulty-related constants
|
||||||
|
|
||||||
export const currentOperation = computed(
|
export const currentOperation = computed(
|
||||||
|
|
|
@ -1,34 +1,56 @@
|
||||||
import { i18n } from '@/i18n'
|
import { i18n } from '@/i18n'
|
||||||
import { percentageDiff } from '@/utils'
|
|
||||||
|
|
||||||
import { numberOfGamesSinceStart, operations, result } from './game-state'
|
import {
|
||||||
|
isHardMode,
|
||||||
|
numberOfGamesSinceStart,
|
||||||
|
operations,
|
||||||
|
result,
|
||||||
|
} from './game-state'
|
||||||
import { showToast } from './toast-manager'
|
import { showToast } from './toast-manager'
|
||||||
|
|
||||||
function getSharingText(): string {
|
function getSharingText(): string {
|
||||||
// × ÷ + -
|
const endResult = operations[operations.length - 1].result?.value ?? 0
|
||||||
const emojis: string[] = []
|
const success = result.value === endResult
|
||||||
|
|
||||||
|
// const allSymbols = ['𝙰', '𝙱', '𝙲', '𝙳', '𝙴', '𝙵', '𝚅', '𝚆', '𝚇', '𝚈', '𝚉']
|
||||||
|
const abcSymbols = ['𝚊', '𝚋', '𝚌', '𝚍', '𝚎', '𝚏']
|
||||||
|
const xyzSymbols = ['𝚟', '𝚠', '𝚡', '𝚢', '𝚣'].slice(-(operations.length - 1))
|
||||||
|
// const xyzSymbols = ["𝚊'", "𝚋'", "𝚌'", "𝚍'", "𝚎'", "𝚏'"]
|
||||||
|
// const xyzSymbols = ['𝚅', '𝚆', '𝚇', '𝚈', '𝚉']
|
||||||
|
const squares = ['🟦', '🟩', '🟨', '🟧', '🟥']
|
||||||
|
|
||||||
|
const lines: string[] = []
|
||||||
for (const op of operations) {
|
for (const op of operations) {
|
||||||
|
op.left!.symbol = op.left!.symbol ?? abcSymbols.shift()
|
||||||
|
op.right!.symbol = op.right!.symbol ?? abcSymbols.shift()
|
||||||
|
op.result!.symbol = op.result!.symbol ?? xyzSymbols.shift()
|
||||||
|
|
||||||
|
let s = ''
|
||||||
switch (op.operator) {
|
switch (op.operator) {
|
||||||
case '+':
|
|
||||||
emojis.push('+')
|
|
||||||
break
|
|
||||||
case '-':
|
|
||||||
emojis.push('-')
|
|
||||||
break
|
|
||||||
case '*':
|
case '*':
|
||||||
emojis.push('×')
|
s = '×'
|
||||||
break
|
break
|
||||||
case '/':
|
case '/':
|
||||||
emojis.push('÷')
|
s = '÷'
|
||||||
|
break
|
||||||
|
case '-':
|
||||||
|
s = '−'
|
||||||
|
break
|
||||||
|
case '+':
|
||||||
|
s = '+'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
lines.push(
|
||||||
|
`${squares.shift()} ${op.left?.symbol} ${s} ${op.right?.symbol} = ${
|
||||||
|
op.result?.value === endResult ? endResult : op.result?.symbol
|
||||||
|
}`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
const endResult = operations[operations.length - 1].result?.value ?? 0
|
|
||||||
return `N0mbers #${numberOfGamesSinceStart()}
|
return `N0mbers #${numberOfGamesSinceStart()} - ${
|
||||||
===========
|
isHardMode.value ? 'Advanced' : 'Normal'
|
||||||
${emojis.join(' ')} = ${endResult}
|
}
|
||||||
Score: ${100 - percentageDiff(result.value, endResult) * 100}%
|
${lines.join('\n')} ${success ? '✔' : '❌'}
|
||||||
===========
|
|
||||||
https://n0mbers.scambier.xyz`
|
https://n0mbers.scambier.xyz`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { merge } from 'lodash-es'
|
import { merge } from 'lodash-es'
|
||||||
import { reactive, watch } from 'vue'
|
import { reactive, watch } from 'vue'
|
||||||
|
|
||||||
// import { plausible } from '@/analytics'
|
|
||||||
import { LSK_STATS } from '@/globals'
|
import { LSK_STATS } from '@/globals'
|
||||||
import * as storage from '@/storage'
|
import * as storage from '@/storage'
|
||||||
import { GameStats } from '@/types'
|
import { GameStats } from '@/types'
|
||||||
|
@ -62,8 +61,7 @@ function setScore(seed: string, won: boolean, score: number): void {
|
||||||
// Don't overwrite an existing score
|
// Don't overwrite an existing score
|
||||||
if (!gameStats.games[seed]) {
|
if (!gameStats.games[seed]) {
|
||||||
gameStats.games[seed] = { score, won }
|
gameStats.games[seed] = { score, won }
|
||||||
// plausible.trackEvent(won ? 'win_game' : 'lose_game')
|
|
||||||
// plausible.trackEvent('end_game')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const GAME_STARTING_DATE = '2022-02-18'
|
export const GAME_STARTING_DATE = '2022-03-22'
|
||||||
export const BXL_TZ = 'Europe/Brussels'
|
export const BXL_TZ = 'Europe/Brussels'
|
||||||
|
|
||||||
export const LSK_DARKMODE = 'n0_dark'
|
export const LSK_DARKMODE = 'n0_dark'
|
||||||
|
@ -8,9 +8,9 @@ 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: [1, 1, 2, 3, 5, 8, 13, 21],
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export enum GameStateType {
|
export enum GameStateType {
|
||||||
|
|
|
@ -12,10 +12,14 @@
|
||||||
"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",
|
||||||
"dailyHard": "Hard Mode",
|
"dailyHard": "Advanced Mode",
|
||||||
"dailyNormal": "Normal Mode"
|
"dailyNormal": "Normal Mode",
|
||||||
|
"practiceMode": "Practice",
|
||||||
|
"practiceModeDescription": "Use the Practice mode to improve your skills.",
|
||||||
|
"hardModeDescription": "The Advanced mode is generally more challenging, with 6 starting numbers.",
|
||||||
|
"normalModeDescription": "The Normal mode has 5 starting numbers, for a generally easier challenge."
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
@ -17,5 +17,9 @@
|
||||||
"copiedInClipboard": "Copié dans le presse-papier",
|
"copiedInClipboard": "Copié dans le presse-papier",
|
||||||
"soon": "Bientôt",
|
"soon": "Bientôt",
|
||||||
"dailyNormal": "Mode Normal",
|
"dailyNormal": "Mode Normal",
|
||||||
"dailyHard": "Mode Difficile"
|
"dailyHard": "Mode Avancé",
|
||||||
|
"practiceMode": "Entraînement",
|
||||||
|
"practiceModeDescription": "Profitez du mode Entraînement pour améliorer vos compétences.",
|
||||||
|
"hardModeDescription": "Le mode Avancé propose un challenge généralement plus relevé, avec 6 nombres de base.",
|
||||||
|
"normalModeDescription": "Le mode Normal propose un challenge généralement plus facile, avec 5 nombres de base."
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ const router = createRouter({
|
||||||
meta: { transition: '' },
|
meta: { transition: '' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/hard',
|
path: '/advanced',
|
||||||
name: 'hard',
|
name: 'advanced',
|
||||||
component: () => import('../views/GameView.vue'),
|
component: () => import('../views/GameView.vue'),
|
||||||
meta: { transition: 'route' },
|
meta: { transition: 'route' },
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,12 @@ const router = createRouter({
|
||||||
component: () => import('../views/GameView.vue'),
|
component: () => import('../views/GameView.vue'),
|
||||||
meta: { transition: 'route' },
|
meta: { transition: 'route' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/practice',
|
||||||
|
name: 'practice',
|
||||||
|
component: () => import('../views/GameView.vue'),
|
||||||
|
meta: { transition: 'route' },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -12,11 +12,16 @@
|
||||||
class="text-center"
|
class="text-center"
|
||||||
v-if="gameState <= GameStateType.Waiting">
|
v-if="gameState <= GameStateType.Waiting">
|
||||||
{{ t('dailyDescription') }}<br><br>
|
{{ t('dailyDescription') }}<br><br>
|
||||||
<div v-if="isHardMode">
|
<div v-if="isPracticeMode">
|
||||||
{{ t('hardModeDescription') }}
|
{{ t('practiceModeDescription') }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
{{ t('normalModeDescription') }}
|
<div v-if="isHardMode">
|
||||||
|
{{ t('hardModeDescription') }}
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ t('normalModeDescription') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -35,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 -->
|
||||||
|
@ -58,11 +63,19 @@
|
||||||
v-else
|
v-else
|
||||||
v-html="t('endGame.failureLabel')" />
|
v-html="t('endGame.failureLabel')" />
|
||||||
<button
|
<button
|
||||||
@click="toClipboard"
|
v-if="!isPracticeMode"
|
||||||
|
@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') }}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
v-else
|
||||||
|
@click="reboot"
|
||||||
|
class="inline-flex items-center btn-border">
|
||||||
|
<IconReload class="mr-2" />
|
||||||
|
{{ t('playAgain') }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
|
@ -91,23 +104,17 @@ import {
|
||||||
gameIsRunning,
|
gameIsRunning,
|
||||||
gameState,
|
gameState,
|
||||||
isEndGame,
|
isEndGame,
|
||||||
|
isHardMode,
|
||||||
isResultPerfect,
|
isResultPerfect,
|
||||||
operations,
|
operations,
|
||||||
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 { GameDifficultyType, GameStateType, pools } from '@/globals'
|
import { GameDifficultyType, GameStateType, pools } from '@/globals'
|
||||||
import { OperatorType, Plaquette } from '@/types'
|
import { OperatorType, Plaquette } from '@/types'
|
||||||
import {
|
import { randItem, random, randRange, setDailyPRNG, setMathPRNG } from '@/utils'
|
||||||
getCurrentSessionKey,
|
import IconReload from '~icons/ph/arrow-clockwise'
|
||||||
randItem,
|
|
||||||
random,
|
|
||||||
randRange,
|
|
||||||
setDailyPRNG,
|
|
||||||
setMathPRNG,
|
|
||||||
} from '@/utils'
|
|
||||||
import IconShare from '~icons/ph/share-network'
|
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
|
||||||
|
@ -119,9 +126,7 @@ const { t } = useI18n() // call `useI18n`, and spread `t` from `useI18n` return
|
||||||
const poolType = ref<1 | 2 | 3>(1)
|
const poolType = ref<1 | 2 | 3>(1)
|
||||||
const cmpPlaquettes = ref<InstanceType<typeof PlaquettesList> | null>(null)
|
const cmpPlaquettes = ref<InstanceType<typeof PlaquettesList> | null>(null)
|
||||||
|
|
||||||
const isHardMode = computed(
|
const isPracticeMode = ref(false)
|
||||||
() => gameDifficulty.value === GameDifficultyType.Hard,
|
|
||||||
)
|
|
||||||
const shownPlaquettes = computed(() =>
|
const shownPlaquettes = computed(() =>
|
||||||
gameIsRunning.value ? plaquettes.value : [],
|
gameIsRunning.value ? plaquettes.value : [],
|
||||||
)
|
)
|
||||||
|
@ -136,6 +141,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) {
|
||||||
|
@ -187,15 +193,12 @@ function selectOperator(o: OperatorType): void {
|
||||||
function reboot(): void {
|
function reboot(): void {
|
||||||
gameState.value = GameStateType.Playing
|
gameState.value = GameStateType.Playing
|
||||||
|
|
||||||
// The daily number is >= 500 to have a minimum challenge
|
const minValue = 101
|
||||||
const minValue = isHardMode.value ? 500 : 101
|
const numPlaquettes = isHardMode.value || isPracticeMode.value ? 6 : 5
|
||||||
const numPlaquettes = isHardMode.value ? 6 : 5
|
|
||||||
do {
|
do {
|
||||||
// Find a problem
|
// Find a problem
|
||||||
// result.value = randRange(101, 1000)
|
|
||||||
poolType.value = randItem([1, 1, 1, 1, 1, 2, 3])
|
poolType.value = randItem([1, 1, 1, 1, 1, 2, 3])
|
||||||
result.value = randRange(minValue, 1000)
|
result.value = randRange(minValue, 1000)
|
||||||
// result.value = 29
|
|
||||||
// Reset Operations list
|
// Reset Operations list
|
||||||
clearOperationsList()
|
clearOperationsList()
|
||||||
|
|
||||||
|
@ -205,12 +208,9 @@ 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 })
|
||||||
}
|
}
|
||||||
// plaquettes.value = [4, 8, 10, 25, 50, 100].map(value => ({
|
|
||||||
// free: true,
|
|
||||||
// value,
|
|
||||||
// }))
|
|
||||||
// Solve it
|
// Solve it
|
||||||
} while (
|
} while (
|
||||||
(isHardMode.value ? !isHardEnough(result.value) : false) ||
|
(isHardMode.value ? !isHardEnough(result.value) : false) ||
|
||||||
|
@ -228,11 +228,18 @@ function reboot(): void {
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
gameDifficulty.value =
|
gameDifficulty.value =
|
||||||
useRoute()?.name === 'hard'
|
useRoute()?.name !== 'normal'
|
||||||
? GameDifficultyType.Hard
|
? GameDifficultyType.Hard
|
||||||
: GameDifficultyType.Normal
|
: GameDifficultyType.Normal
|
||||||
|
|
||||||
setDailyPRNG()
|
isPracticeMode.value = useRoute().name === 'practice'
|
||||||
|
|
||||||
|
if (isPracticeMode.value) {
|
||||||
|
setMathPRNG()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setDailyPRNG()
|
||||||
|
}
|
||||||
result.value = 0
|
result.value = 0
|
||||||
|
|
||||||
// Wait until after the page transion to generate the number
|
// Wait until after the page transion to generate the number
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
<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-16 justify-center md:mt-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><br>
|
|
||||||
<span v-html="t('dailyDescription')" />
|
|
||||||
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Normal -->
|
<!-- Normal -->
|
||||||
<div class="flex flex-col gap-4 items-center">
|
<div class="flex flex-col items-center">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
to="/normal"
|
to="/normal"
|
||||||
class="text-2xl btn-border">
|
class="text-2xl btn-border">
|
||||||
|
@ -18,14 +13,22 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Hard -->
|
<!-- Hard -->
|
||||||
<div class="flex flex-col gap-4 items-center">
|
<div class="flex flex-col items-center">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
to="/hard"
|
to="/advanced"
|
||||||
class="text-2xl btn-border">
|
class="text-2xl btn-border">
|
||||||
{{ t('dailyHard') }}
|
{{ t('dailyHard') }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Practice -->
|
||||||
|
<div class="flex flex-col items-center mt-4">
|
||||||
|
<RouterLink
|
||||||
|
to="/practice"
|
||||||
|
class="text-xl btn-border">
|
||||||
|
{{ t('practiceMode') }}
|
||||||
|
</RouterLink>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user