Gameplay loop ok

This commit is contained in:
Simon Cambier 2022-02-12 14:12:55 +01:00
parent 6232c2f682
commit aa3c4dfcfc
6 changed files with 57 additions and 29 deletions

View File

@ -6,9 +6,6 @@ import { randRange } from './utils'
type HistoryType = { a: number; b: number; op: OperatorType }[] type HistoryType = { a: number; b: number; op: OperatorType }[]
export const operations = reactive<Operation[]>([])
export const plaquettes = ref<Plaquette[]>([])
export function isOperationResultValid(op: Operation): boolean { export function isOperationResultValid(op: Operation): boolean {
return ( return (
!!op.operator && !!op.operator &&
@ -24,11 +21,7 @@ export function isOperationInvalid(op: Operation): boolean {
} }
export function isOperationReady(op: Operation): boolean { export function isOperationReady(op: Operation): boolean {
return ( return !!op.operator && !!op.left && !!op.right
!!op.operator &&
!!op.left &&
!!op.right
)
} }
export function getEmptyOperation(): Operation { export function getEmptyOperation(): Operation {

View File

@ -29,7 +29,9 @@
</div> </div>
<!-- RESULT --> <!-- RESULT -->
<PlaquetteBox :dynamic-size="true" class="w-[3.2em] border-none"> <PlaquetteBox
:dynamic-size="true"
class="w-[3.2em] h-8 border-none">
<IconSad v-if="isOperationInvalid(op)" /> <IconSad v-if="isOperationInvalid(op)" />
<span <span
v-else-if=" v-else-if="
@ -37,8 +39,10 @@
"> ">
{{ operate(op.operator, op.left.value, op.right.value) }} {{ operate(op.operator, op.left.value, op.right.value) }}
</span> </span>
<IconQuestion v-else /> <span v-else>?</span>
</PlaquetteBox> </PlaquetteBox>
<!-- UNDO -->
<button <button
class="ml-8" class="ml-8"
@click="undoOperation(i)"> @click="undoOperation(i)">
@ -60,15 +64,13 @@ import {
isOperationInvalid, isOperationInvalid,
isOperationResultValid, isOperationResultValid,
operate, operate,
operations,
plaquettes,
} from '@/algo' } from '@/algo'
import { GameState, gameState } from '@/globals'
import { operations, plaquettes } from '@/store'
import { Operation } from '@/types' import { Operation } from '@/types'
import IconQuestion from '~icons/bx/bx-question-mark'
import IconSad from '~icons/bx/bx-sad' import IconSad from '~icons/bx/bx-sad'
import IconUndo from '~icons/bx/bx-undo' import IconUndo from '~icons/bx/bx-undo'
import NumberBox from './common/NumberBox.vue'
import PlaquetteBox from './common/PlaquetteBox.vue' import PlaquetteBox from './common/PlaquetteBox.vue'
const transDelay = 100 const transDelay = 100
@ -78,9 +80,9 @@ function canOperationBeDeleted(op: Operation): boolean {
} }
function undoOperation(index: number): void { function undoOperation(index: number): void {
if (gameState.value !== GameState.Playing) return
const l = operations.length const l = operations.length
for (let i = operations.length - 1; i >= index; --i) { for (let i = operations.length - 1; i >= index; --i) {
console.log(i)
let popped: Operation let popped: Operation
if (i === index) { if (i === index) {
popped = operations[index] popped = operations[index]

View File

@ -1,19 +1,21 @@
<template> <template>
<div <Component
:is="is"
class="flex overflow-hidden justify-center font-bold rounded border border-stone-600 transition-all" class="flex overflow-hidden justify-center font-bold rounded border border-stone-600 transition-all"
:class="[textSize]"> :class="[textSize]">
<span <span
class="self-center text-center" class="self-center text-center"
ref="content"><slot /></span> ref="content"><slot /></span>
</div> </Component>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
const props = withDefaults( const props = withDefaults(
defineProps<{ dynamicSize: boolean }>(), defineProps<{ dynamicSize: boolean; is?: string }>(),
{ {
is: 'div',
dynamicSize: false, dynamicSize: false,
}, },
) )

View File

@ -1,3 +1,5 @@
import { ref } from 'vue'
export const operators = ['+', '-', 'x', '/'] as const export const operators = ['+', '-', 'x', '/'] as const
export const pool = [ 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, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100,
@ -8,3 +10,5 @@ export enum GameState {
Lost, Lost,
Won, Won,
} }
export const gameState = ref(GameState.Playing)

6
src/store.ts Normal file
View File

@ -0,0 +1,6 @@
import { reactive, ref } from 'vue'
import { Operation, Plaquette } from './types'
export const operations = reactive<Operation[]>([])
export const plaquettes = ref<Plaquette[]>([])

View File

@ -20,11 +20,12 @@
class="grid grid-cols-6 grid-rows-2 gap-2 justify-center px-2 mx-auto max-w-sm"> class="grid grid-cols-6 grid-rows-2 gap-2 justify-center px-2 mx-auto max-w-sm">
<TransitionGroup name="slide_left"> <TransitionGroup name="slide_left">
<PlaquetteBox <PlaquetteBox
is="button"
@click="selectNumber(item)"
:dynamic-size="true" :dynamic-size="true"
class="col-start-auto h-11" class="h-11"
:class="{ 'text-stone-600 border-stone-600': !item.free }" :class="{ 'text-stone-600 border-stone-600': !item.free }"
:style="{ transitionDelay: `${initDelay * i}ms` }" :style="{ transitionDelay: `${initDelay * i}ms` }"
@click="selectNumber(item)"
v-for="(item, i) in plaquettes" v-for="(item, i) in plaquettes"
:key="i"> :key="i">
{{ item.value }} {{ item.value }}
@ -45,7 +46,19 @@
<div class="my-4 mx-auto max-w-sm border-b" /> <div class="my-4 mx-auto max-w-sm border-b" />
<!-- List of Operations -->
<OperationsList /> <OperationsList />
<div class="flex justify-evenly items-center mt-8">
<Transition name="slide_up">
<button
v-if="gameState === GameState.Won"
class="p-2 rounded border"
@click="reboot">
Rejouer
</button>
</Transition>
</div>
</div> </div>
</template> </template>
@ -58,21 +71,17 @@ import {
isOperationResultValid, isOperationResultValid,
isSolvable, isSolvable,
operate, operate,
operations,
plaquettes,
} from '@/algo' } from '@/algo'
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, operators, pool } from '@/globals' import { GameState, gameState, operators, pool } from '@/globals'
import { operations, plaquettes } from '@/store'
import { OperatorType, Plaquette } from '@/types' import { OperatorType, Plaquette } from '@/types'
import { randItem, randRange } from '@/utils' import { randItem, randRange } from '@/utils'
const result = ref(0) const result = ref(0)
const initDelay = ref(100) const initDelay = ref(100)
const currentState = ref(GameState.Playing)
operations.push(getEmptyOperation())
const currentOperation = computed(() => operations[operations.length - 1]) const currentOperation = computed(() => operations[operations.length - 1])
@ -84,11 +93,12 @@ 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),
} }
plaquettes.value.push(op.result)
if (op.result.value === result.value) { if (op.result.value === result.value) {
// Winner // Winner
gameState.value = GameState.Won
} }
else { else if (operations.length < 5) {
plaquettes.value.push(op.result)
operations.push(getEmptyOperation()) operations.push(getEmptyOperation())
} }
} }
@ -113,12 +123,14 @@ function selectNumber(p: Plaquette): void {
} }
function selectOperator(o: OperatorType): void { function selectOperator(o: OperatorType): void {
if (gameState.value !== GameState.Playing) return
currentOperation.value.operator = o currentOperation.value.operator = o
} }
const difficultyLevel = randItem([1, 1, 1, 1, 1, 1, 2, 2, 2, 3]) const difficultyLevel = randItem([1, 1, 1, 1, 1, 1, 2, 2, 2, 3])
onMounted(() => { function reboot(): void {
gameState.value = GameState.Playing
do { do {
// Find a problem // Find a problem
// result.value = randRange(101, 1000) // result.value = randRange(101, 1000)
@ -132,6 +144,11 @@ onMounted(() => {
return randRange(250, 1000) return randRange(250, 1000)
} }
})() })()
// Reset Operations list
operations.splice(0)
operations.push(getEmptyOperation())
// Generate result and plaquettes
plaquettes.value = [] plaquettes.value = []
const poolCopy = [...pool] const poolCopy = [...pool]
for (let i = 0; i < 6; ++i) { for (let i = 0; i < 6; ++i) {
@ -147,5 +164,9 @@ onMounted(() => {
) )
) )
plaquettes.value.sort((a, b) => a.value - b.value) plaquettes.value.sort((a, b) => a.value - b.value)
}
onMounted(() => {
reboot()
}) })
</script> </script>