Gameplay loop ok
This commit is contained in:
		
							parent
							
								
									6232c2f682
								
							
						
					
					
						commit
						aa3c4dfcfc
					
				|  | @ -6,9 +6,6 @@ import { randRange } from './utils' | |||
| 
 | ||||
| type HistoryType = { a: number; b: number; op: OperatorType }[] | ||||
| 
 | ||||
| export const operations = reactive<Operation[]>([]) | ||||
| export const plaquettes = ref<Plaquette[]>([]) | ||||
| 
 | ||||
| export function isOperationResultValid(op: Operation): boolean { | ||||
|   return ( | ||||
|     !!op.operator && | ||||
|  | @ -24,11 +21,7 @@ export function isOperationInvalid(op: Operation): boolean { | |||
| } | ||||
| 
 | ||||
| export function isOperationReady(op: Operation): boolean { | ||||
|   return ( | ||||
|     !!op.operator && | ||||
|     !!op.left && | ||||
|     !!op.right | ||||
|   ) | ||||
|   return !!op.operator && !!op.left && !!op.right | ||||
| } | ||||
| 
 | ||||
| export function getEmptyOperation(): Operation { | ||||
|  |  | |||
|  | @ -29,7 +29,9 @@ | |||
|           </div> | ||||
| 
 | ||||
|           <!-- 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)" /> | ||||
|             <span | ||||
|               v-else-if=" | ||||
|  | @ -37,8 +39,10 @@ | |||
|               "> | ||||
|               {{ operate(op.operator, op.left.value, op.right.value) }} | ||||
|             </span> | ||||
|             <IconQuestion v-else /> | ||||
|             <span v-else>?</span> | ||||
|           </PlaquetteBox> | ||||
| 
 | ||||
|           <!-- UNDO --> | ||||
|           <button | ||||
|             class="ml-8" | ||||
|             @click="undoOperation(i)"> | ||||
|  | @ -60,15 +64,13 @@ import { | |||
|   isOperationInvalid, | ||||
|   isOperationResultValid, | ||||
|   operate, | ||||
|   operations, | ||||
|   plaquettes, | ||||
| } from '@/algo' | ||||
| import { GameState, gameState } from '@/globals' | ||||
| import { operations, plaquettes } from '@/store' | ||||
| import { Operation } from '@/types' | ||||
| import IconQuestion from '~icons/bx/bx-question-mark' | ||||
| import IconSad from '~icons/bx/bx-sad' | ||||
| import IconUndo from '~icons/bx/bx-undo' | ||||
| 
 | ||||
| import NumberBox from './common/NumberBox.vue' | ||||
| import PlaquetteBox from './common/PlaquetteBox.vue' | ||||
| 
 | ||||
| const transDelay = 100 | ||||
|  | @ -78,9 +80,9 @@ function canOperationBeDeleted(op: Operation): boolean { | |||
| } | ||||
| 
 | ||||
| function undoOperation(index: number): void { | ||||
|   if (gameState.value !== GameState.Playing) return | ||||
|   const l = operations.length | ||||
|   for (let i = operations.length - 1; i >= index; --i) { | ||||
|     console.log(i) | ||||
|     let popped: Operation | ||||
|     if (i === index) { | ||||
|       popped = operations[index] | ||||
|  |  | |||
|  | @ -1,19 +1,21 @@ | |||
| <template> | ||||
|   <div | ||||
|   <Component | ||||
|     :is="is" | ||||
|     class="flex overflow-hidden justify-center font-bold rounded border border-stone-600 transition-all" | ||||
|     :class="[textSize]"> | ||||
|     <span | ||||
|       class="self-center text-center" | ||||
|       ref="content"><slot /></span> | ||||
|   </div> | ||||
|   </Component> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| import { ref, watch } from 'vue' | ||||
| 
 | ||||
| const props = withDefaults( | ||||
|   defineProps<{ dynamicSize: boolean }>(), | ||||
|   defineProps<{ dynamicSize: boolean; is?: string }>(), | ||||
|   { | ||||
|     is: 'div', | ||||
|     dynamicSize: false, | ||||
|   }, | ||||
| ) | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| import { ref } from 'vue' | ||||
| 
 | ||||
| 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, | ||||
|  | @ -8,3 +10,5 @@ export enum GameState { | |||
|   Lost, | ||||
|   Won, | ||||
| } | ||||
| 
 | ||||
| export const gameState = ref(GameState.Playing) | ||||
|  |  | |||
							
								
								
									
										6
									
								
								src/store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/store.ts
									
									
									
									
									
										Normal 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[]>([]) | ||||
|  | @ -20,11 +20,12 @@ | |||
|       class="grid grid-cols-6 grid-rows-2 gap-2 justify-center px-2 mx-auto max-w-sm"> | ||||
|       <TransitionGroup name="slide_left"> | ||||
|         <PlaquetteBox | ||||
|           is="button" | ||||
|           @click="selectNumber(item)" | ||||
|           :dynamic-size="true" | ||||
|           class="col-start-auto h-11" | ||||
|           class="h-11" | ||||
|           :class="{ 'text-stone-600 border-stone-600': !item.free }" | ||||
|           :style="{ transitionDelay: `${initDelay * i}ms` }" | ||||
|           @click="selectNumber(item)" | ||||
|           v-for="(item, i) in plaquettes" | ||||
|           :key="i"> | ||||
|           {{ item.value }} | ||||
|  | @ -45,7 +46,19 @@ | |||
| 
 | ||||
|     <div class="my-4 mx-auto max-w-sm border-b" /> | ||||
| 
 | ||||
|     <!-- List of Operations --> | ||||
|     <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> | ||||
| </template> | ||||
| 
 | ||||
|  | @ -58,21 +71,17 @@ import { | |||
|   isOperationResultValid, | ||||
|   isSolvable, | ||||
|   operate, | ||||
|   operations, | ||||
|   plaquettes, | ||||
| } from '@/algo' | ||||
| import NumberBox from '@/components/common/NumberBox.vue' | ||||
| import PlaquetteBox from '@/components/common/PlaquetteBox.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 { randItem, randRange } from '@/utils' | ||||
| 
 | ||||
| const result = ref(0) | ||||
| const initDelay = ref(100) | ||||
| const currentState = ref(GameState.Playing) | ||||
| 
 | ||||
| operations.push(getEmptyOperation()) | ||||
| 
 | ||||
| const currentOperation = computed(() => operations[operations.length - 1]) | ||||
| 
 | ||||
|  | @ -84,11 +93,12 @@ watch( | |||
|         free: true, | ||||
|         value: operate(op.operator!, op.left!.value, op.right!.value), | ||||
|       } | ||||
|       plaquettes.value.push(op.result) | ||||
|       if (op.result.value === result.value) { | ||||
|         // Winner | ||||
|         gameState.value = GameState.Won | ||||
|       } | ||||
|       else { | ||||
|       else if (operations.length < 5) { | ||||
|         plaquettes.value.push(op.result) | ||||
|         operations.push(getEmptyOperation()) | ||||
|       } | ||||
|     } | ||||
|  | @ -113,12 +123,14 @@ function selectNumber(p: Plaquette): void { | |||
| } | ||||
| 
 | ||||
| function selectOperator(o: OperatorType): void { | ||||
|   if (gameState.value !== GameState.Playing) return | ||||
|   currentOperation.value.operator = o | ||||
| } | ||||
| 
 | ||||
| const difficultyLevel = randItem([1, 1, 1, 1, 1, 1, 2, 2, 2, 3]) | ||||
| 
 | ||||
| onMounted(() => { | ||||
| function reboot(): void { | ||||
|   gameState.value = GameState.Playing | ||||
|   do { | ||||
|     // Find a problem | ||||
|     // result.value = randRange(101, 1000) | ||||
|  | @ -132,6 +144,11 @@ onMounted(() => { | |||
|           return randRange(250, 1000) | ||||
|       } | ||||
|     })() | ||||
|     // Reset Operations list | ||||
|     operations.splice(0) | ||||
|     operations.push(getEmptyOperation()) | ||||
| 
 | ||||
|     // Generate result and plaquettes | ||||
|     plaquettes.value = [] | ||||
|     const poolCopy = [...pool] | ||||
|     for (let i = 0; i < 6; ++i) { | ||||
|  | @ -147,5 +164,9 @@ onMounted(() => { | |||
|     ) | ||||
|   ) | ||||
|   plaquettes.value.sort((a, b) => a.value - b.value) | ||||
| } | ||||
| 
 | ||||
| onMounted(() => { | ||||
|   reboot() | ||||
| }) | ||||
| </script> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user