Undo ok
This commit is contained in:
parent
efcab7b77b
commit
725cbd0dbe
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
14
src/algo.ts
14
src/algo.ts
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
Loading…
Reference in New Issue
Block a user