This commit is contained in:
Simon Cambier 2022-02-16 22:48:04 +01:00
parent ba01bba5dc
commit 93e8da4ab4
7 changed files with 93 additions and 38 deletions

View File

@ -1,8 +1,5 @@
import { reactive, ref, watch } from 'vue' import { operators } from './globals'
import { Operation, OperatorType } from './types'
import { operators, pool } from './globals'
import { Operation, OperatorType, Plaquette } from './types'
import { randRange } from './utils'
type HistoryType = { a: number; b: number; op: OperatorType }[] type HistoryType = { a: number; b: number; op: OperatorType }[]

View File

@ -72,11 +72,11 @@ import {
isOperationResultValid, isOperationResultValid,
operate, operate,
} from '@/algo' } from '@/algo'
import { operations, plaquettes } from '@/game-state'
import { GameState, gameState } from '@/globals' import { GameState, gameState } from '@/globals'
import { operations, plaquettes } from '@/store'
import { Operation } from '@/types' import { Operation } from '@/types'
import IconSad from '~icons/bx/bx-sad'
import IconUndo from '~icons/bx/bx-undo' import IconUndo from '~icons/bx/bx-undo'
import IconSad from '~icons/ph/smiley-sad'
import PlaquetteBox from './common/PlaquetteBox.vue' import PlaquetteBox from './common/PlaquetteBox.vue'

View File

@ -13,7 +13,7 @@
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
const props = withDefaults( const props = withDefaults(
defineProps<{ dynamicSize: boolean; is?: string }>(), defineProps<{ dynamicSize?: boolean; is?: string }>(),
{ {
is: 'div', is: 'div',
dynamicSize: false, dynamicSize: false,

View File

@ -1,9 +1,9 @@
import { computed, reactive, ref } from 'vue' import { computed, reactive, ref } from 'vue'
import { isOperationReady } from './algo' import { getEmptyOperation, isOperationReady } from './algo'
import { Operation, Plaquette } from './types' import { Operation, Plaquette } from './types'
export const operations = reactive<Operation[]>([]) 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)
@ -13,9 +13,11 @@ export const currentOperation = computed(
) )
export const isEndGame = computed( export const isEndGame = computed(
() => operations.length === 5 && isOperationReady(currentOperation.value), () =>
(operations.length === 5 && isOperationReady(currentOperation.value)) ||
isResultPerfect.value,
) )
export const isResultPerfect = computed( export const isResultPerfect = computed(
() => currentOperation.value.result!.value === result.value, () => !!operations.some(o => o.result?.value === result.value),
) )

View File

@ -1,9 +1,16 @@
import { ref } from 'vue' import { ref } from 'vue'
export const operators = ['+', '-', 'x', '/'] as const export const operators = ['+', '-', 'x', '/'] as const
export const pool = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100, export const pools = {
] as const 1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25],
2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75],
3: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75,
100,
],
4: [2, 2, 3, 3, 5, 5, 7, 11, 13, 17, 19, 23],
} as const
export enum GameState { export enum GameState {
Undefined = 0, Undefined = 0,

View File

@ -1,6 +1,10 @@
{ {
"playAgain": "Rejouer", "playAgain": "Rejouer",
"endGame.victoryLabel": "Bien joué !", "endGame.victoryLabel": "Le compte est bon !",
"endGame.failureLabel": "Presque", "endGame.failureLabel": "Dommage...<br>Une autre partie ?",
"startGame": "Démarrer" "startGame": "Démarrer",
"easy": "facile",
"medium": "moyen",
"hard": "difficile",
"impossible": "☠"
} }

View File

@ -10,7 +10,8 @@
:class="{ :class="{
'text-green-400': difficultyLevel === 1, 'text-green-400': difficultyLevel === 1,
'text-amber-400': difficultyLevel === 2, 'text-amber-400': difficultyLevel === 2,
'text-red-400': difficultyLevel === 3, 'text-orange-400': difficultyLevel === 3,
'text-red-500': difficultyLevel === 4,
}"> }">
{{ result }} {{ result }}
</NumberBox> </NumberBox>
@ -24,8 +25,23 @@
<div> <div>
Combinez les nombres imposés afin de trouver le résultat ci-dessus, ou Combinez les nombres imposés afin de trouver le résultat ci-dessus, ou
de vous en approcher le plus possible.<br> de vous en approcher le plus possible.<br>
Le compteur démarre quand vous cliquez sur le bouton.<br>Partagez vos Le compteur démarre quand vous cliquez sur le bouton.<br>Partagez
meilleurs temps ! vos meilleurs temps !
</div>
<div
class="my-4 font-bold"
:class="{
'text-green-400': difficultyLevel === 1,
'text-amber-400': difficultyLevel === 2,
'text-orange-400': difficultyLevel === 3,
'text-red-500': difficultyLevel === 4,
}">
Niveau de difficulté :
<span v-if="difficultyLevel < 4">{{ difficultyLabel }}</span>
<IconSkull
class="inline"
v-else />
</div> </div>
<button <button
@ -58,13 +74,14 @@
<Transition name="slide_up"> <Transition name="slide_up">
<div v-if="gameIsRunning"> <div v-if="gameIsRunning">
<div class="flex gap-2 justify-center my-4"> <div class="flex gap-2 justify-center my-4">
<NumberBox <PlaquetteBox
is="button"
class="aspect-square w-[1.5em] text-2xl" class="aspect-square w-[1.5em] text-2xl"
@click="selectOperator(item)" @click="selectOperator(item)"
v-for="(item, i) in operators" v-for="(item, i) in operators"
:key="i"> :key="i">
{{ item }} {{ item }}
</NumberBox> </PlaquetteBox>
</div> </div>
<!-- Divider --> <!-- Divider -->
@ -78,9 +95,13 @@
<Transition name="slide_up"> <Transition name="slide_up">
<div <div
v-if="isEndGame" v-if="isEndGame"
class="flex flex-row justify-evenly items-center mt-8"> class="flex flex-row justify-evenly items-center mx-auto mt-8 max-w-sm">
<span v-if="isResultPerfect">{{ t('endGame.victoryLabel') }}</span> <span
<span v-else>{{ t('endGame.failureLabel') }}</span> v-if="isResultPerfect"
v-html="t('endGame.victoryLabel')" />
<span
v-else
v-html="t('endGame.failureLabel')" />
<button <button
class="p-2 rounded border" class="p-2 rounded border"
@click="reboot"> @click="reboot">
@ -105,7 +126,6 @@ import {
import NumberBox from '@/components/common/NumberBox.vue' import NumberBox from '@/components/common/NumberBox.vue'
import PlaquetteBox from '@/components/common/PlaquetteBox.vue' import PlaquetteBox from '@/components/common/PlaquetteBox.vue'
import OperationsList from '@/components/OperationsList.vue' import OperationsList from '@/components/OperationsList.vue'
import { GameState, gameState, operators, pool } from '@/globals'
import { import {
currentOperation, currentOperation,
isEndGame, isEndGame,
@ -113,9 +133,11 @@ import {
operations, operations,
plaquettes, plaquettes,
result, result,
} from '@/store' } from '@/game-state'
import { GameState, gameState, operators, pools } from '@/globals'
import { OperatorType, Plaquette } from '@/types' import { OperatorType, Plaquette } from '@/types'
import { randItem, randRange } from '@/utils' import { randItem, randRange } from '@/utils'
import IconSkull from '~icons/ph/skull'
const { t } = useI18n() // call `useI18n`, and spread `t` from `useI18n` returning const { t } = useI18n() // call `useI18n`, and spread `t` from `useI18n` returning
@ -132,6 +154,7 @@ const shownPlaquettes = computed(() =>
onMounted(() => { onMounted(() => {
reboot() reboot()
gameState.value = GameState.Waiting
}) })
watch( watch(
@ -142,7 +165,7 @@ watch(
free: true, free: true,
value: operate(op.operator!, op.left!.value, op.right!.value), value: operate(op.operator!, op.left!.value, op.right!.value),
} }
if (operations.length < 5) { if (operations.length < 5 && !isEndGame.value) {
plaquettes.value.push(op.result) plaquettes.value.push(op.result)
operations.push(getEmptyOperation()) operations.push(getEmptyOperation())
} }
@ -157,6 +180,7 @@ function startGame(): void {
} }
function selectNumber(p: Plaquette): void { function selectNumber(p: Plaquette): void {
if (isEndGame.value) return
initDelay.value = 0 initDelay.value = 0
const op = currentOperation.value const op = currentOperation.value
@ -173,39 +197,60 @@ function selectNumber(p: Plaquette): void {
} }
function selectOperator(o: OperatorType): void { function selectOperator(o: OperatorType): void {
if (gameState.value !== GameState.Playing) return if (isEndGame.value) return
currentOperation.value.operator = o currentOperation.value.operator = o
} }
const difficultyLevel = randItem([1, 1, 1, 1, 1, 1, 2, 2, 2, 3]) const difficultyLevel = ref<1 | 2 | 3 | 4>(1)
const difficultyLabel = computed(() => {
switch (difficultyLevel.value) {
case 1:
return t('easy')
case 2:
return t('medium')
case 3:
return t('hard')
default:
return t('impossible')
}
})
function reboot(): void { function reboot(): void {
gameState.value = GameState.Waiting gameState.value = GameState.Playing
do { do {
// Find a problem // Find a problem
// result.value = randRange(101, 1000) // result.value = randRange(101, 1000)
difficultyLevel.value = randItem([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4])
result.value = (() => { result.value = (() => {
switch (difficultyLevel) { switch (difficultyLevel.value) {
case 1: case 1:
return randRange(101, 25) return randRange(80, 200)
case 2: case 2:
return randRange(251, 500) return randRange(201, 400)
default: case 3:
return randRange(501, 1000) return randRange(401, 1000)
case 4:
return randRange(50, 1000)
} }
})() })()
// result.value = 29
// Reset Operations list // Reset Operations list
operations.splice(0) operations.splice(0)
operations.push(getEmptyOperation()) operations.push(getEmptyOperation())
// Generate result and plaquettes // Generate result and plaquettes
plaquettes.value = [] plaquettes.value = []
const poolCopy = [...pool] const poolCopy = [...pools[difficultyLevel.value]]
for (let i = 0; i < 6; ++i) { for (let i = 0; i < 6; ++i) {
const random = Math.floor(Math.random() * poolCopy.length) const random = Math.floor(Math.random() * poolCopy.length)
const el = poolCopy.splice(random, 1)[0] const el = poolCopy.splice(random, 1)[0]
plaquettes.value.push({ value: el, free: true }) plaquettes.value.push({ value: el, free: true })
} }
// plaquettes.value = [4, 8, 10, 25, 50, 100].map(value => ({
// free: true,
// value,
// }))
// Solve it // Solve it
} while ( } while (
!isSolvable( !isSolvable(