This commit is contained in:
Simon Cambier 2022-02-11 22:57:04 +01:00
parent efcab7b77b
commit 725cbd0dbe
6 changed files with 56 additions and 30 deletions

View File

@ -11,7 +11,6 @@
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore" "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
}, },
"dependencies": { "dependencies": {
"pinia": "^2.0.11",
"vue": "^3.2.30", "vue": "^3.2.30",
"vue-router": "^4.0.12" "vue-router": "^4.0.12"
}, },

View File

@ -1,12 +1,13 @@
import { reactive, ref, watch } from 'vue' import { reactive, ref, watch } from 'vue'
import { operators, pool } from './globals' import { operators, pool } from './globals'
import { Operation, OperatorType } from './types' import { Operation, OperatorType, Plaquette } from './types'
import { randRange } from './utils' 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 operations = reactive<Operation[]>([])
export const plaquettes = ref<Plaquette[]>([])
export function isOperationResultValid(op: Operation): boolean { export function isOperationResultValid(op: Operation): boolean {
return ( return (
@ -30,13 +31,13 @@ export function isOperationReady(op: Operation): boolean {
) )
} }
export function pushEmptyOperation(): void { export function getEmptyOperation(): Operation {
operations.push({ return {
left: null, left: null,
right: null, right: null,
operator: null, operator: null,
executed: false, result: null,
}) }
} }
export function operate( export function operate(
@ -64,7 +65,6 @@ export function isSolvable(result: number, plaquettes: number[]): boolean {
`${item.a} ${item.op} ${item.b} = ${operate(item.op, item.a, item.b)}`, `${item.a} ${item.op} ${item.b} = ${operate(item.op, item.a, item.b)}`,
) )
} }
console.log()
} }
function loopOperations(plaquettes: number[], history: HistoryType): void { function loopOperations(plaquettes: number[], history: HistoryType): void {
@ -135,8 +135,6 @@ export function isSolvable(result: number, plaquettes: number[]): boolean {
if (histories.length) { if (histories.length) {
printHistory(histories[0]) printHistory(histories[0])
} }
console.log(new Date().getTime() - startTime.getTime() + 'ms')
console.log(found)
return found return found
// histories.sort((a, b) => a.length - b.length) // histories.sort((a, b) => a.length - b.length)

View File

@ -3,6 +3,7 @@
<div <div
class="mb-2 text-center" class="mb-2 text-center"
v-for="(op, i) in operations" v-for="(op, i) in operations"
:style="{ transitionDelay: `${transDelay * (operations.length - i)}ms` }"
:key="i"> :key="i">
<div class="inline-block relative text-xl"> <div class="inline-block relative text-xl">
<!-- OPERATION --> <!-- OPERATION -->
@ -55,11 +56,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
getEmptyOperation,
isOperationInvalid, isOperationInvalid,
isOperationResultValid, isOperationResultValid,
operate, operate,
operations, operations,
pushEmptyOperation, plaquettes,
} from '@/algo' } from '@/algo'
import { Operation } from '@/types' import { Operation } from '@/types'
import IconQuestion from '~icons/bx/bx-question-mark' import IconQuestion from '~icons/bx/bx-question-mark'
@ -68,12 +70,31 @@ import IconUndo from '~icons/bx/bx-undo'
import NumberBox from './common/NumberBox.vue' import NumberBox from './common/NumberBox.vue'
const transDelay = 100
function canOperationBeDeleted(op: Operation): boolean { function canOperationBeDeleted(op: Operation): boolean {
return !!op.left || !!op.right || !!op.operator return !!op.left || !!op.right || !!op.operator
} }
function undoOperation(index: number): void { function undoOperation(index: number): void {
while (operations.length > index) operations.pop() const l = operations.length
if (!operations.length) pushEmptyOperation() for (let i = operations.length - 1; i >= index; --i) {
console.log(i)
let popped: Operation
if (i === index) {
popped = operations[index]
setTimeout(() => {
operations[index] = getEmptyOperation()
}, transDelay * l)
}
else {
popped = operations.pop()!
}
if (popped?.left) popped.left.free = true
if (popped?.right) popped.right.free = true
if (popped.result) {
plaquettes.value = plaquettes.value.filter(p => p !== popped.result)
}
}
} }
</script> </script>

View File

@ -2,3 +2,9 @@ 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,
] as const ] as const
export enum GameState {
Playing,
Lost,
Won,
}

View File

@ -9,5 +9,5 @@ export type Operation = {
left: Plaquette | null left: Plaquette | null
right: Plaquette | null right: Plaquette | null
operator: OperatorType | null operator: OperatorType | null
executed: boolean result: Plaquette | null
} }

View File

@ -49,44 +49,46 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue' import { computed, onMounted, ref, watch } from 'vue'
import { import {
isOperationInvalid, getEmptyOperation,
isOperationReady, isOperationReady,
isOperationResultValid, isOperationResultValid,
isSolvable, isSolvable,
operate, operate,
operations, operations,
pushEmptyOperation, plaquettes,
} from '@/algo' } from '@/algo'
import NumberBox from '@/components/common/NumberBox.vue' import NumberBox from '@/components/common/NumberBox.vue'
import OperationsList from '@/components/OperationsList.vue' import OperationsList from '@/components/OperationsList.vue'
import { operators, pool } from '@/globals' import { GameState, operators, pool } from '@/globals'
import { Operation, 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 plaquettes = ref<Plaquette[]>([])
const initDelay = ref(100) const initDelay = ref(100)
const currentState = ref(GameState.Playing)
pushEmptyOperation() operations.push(getEmptyOperation())
// pushEmptyOperation()
const currentOperation = computed( const currentOperation = computed(() => operations[operations.length - 1])
() => operations[operations.length - 1],
)
watch( watch(
currentOperation, currentOperation,
op => { op => {
if (isOperationReady(op) && isOperationResultValid(op) && !op.executed) { if (isOperationReady(op) && isOperationResultValid(op) && !op.result) {
op.executed = true op.result = {
plaquettes.value.push({
value: operate(op.operator!, op.left!.value, op.right!.value),
free: true, free: true,
}) value: operate(op.operator!, op.left!.value, op.right!.value),
pushEmptyOperation() }
plaquettes.value.push(op.result)
if (op.result.value === result.value) {
// Winner
}
else {
operations.push(getEmptyOperation())
}
} }
}, },
{ deep: true }, { deep: true },