MVP ok
This commit is contained in:
parent
ba01bba5dc
commit
93e8da4ab4
|
@ -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 }[]
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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),
|
||||||
)
|
)
|
|
@ -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,
|
||||||
|
|
|
@ -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": "☠"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user