imwithye commited on
Commit
4c67d79
·
1 Parent(s): c6ef322
src/components/consts.tsx CHANGED
@@ -11,6 +11,15 @@ export const CubeColors: Record<FacingDirection, string> = {
11
  bottom: '#ffffff', // White
12
  };
13
 
 
 
 
 
 
 
 
 
 
14
  export const Rotations: Record<FacingDirection, [number, number, number]> = {
15
  front: [0, 0, 0],
16
  back: [0, Math.PI, 0],
 
11
  bottom: '#ffffff', // White
12
  };
13
 
14
+ export const CubeColorIndices: Record<FacingDirection, number> = {
15
+ front: 0,
16
+ back: 1,
17
+ right: 2,
18
+ left: 3,
19
+ top: 4,
20
+ bottom: 5,
21
+ };
22
+
23
  export const Rotations: Record<FacingDirection, [number, number, number]> = {
24
  front: [0, 0, 0],
25
  back: [0, Math.PI, 0],
src/components/cube-piece.tsx CHANGED
@@ -4,7 +4,7 @@ import { RoundedBox } from '@react-three/drei';
4
  import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
5
  import { Mesh } from 'three';
6
 
7
- import { CubeColors, FacingDirection, Rotations } from './consts';
8
  import { rotationController } from './rotation-controller';
9
 
10
  export type CubePieceRef = {
@@ -66,8 +66,8 @@ export const CubePiece = forwardRef<CubePieceRef, CubePieceProps>(({ roughness,
66
  rotation={Rotations[face as FacingDirection]}
67
  userData={{
68
  isFace: true,
69
- faceDirection: face,
70
  faceColor: color,
 
71
  }}
72
  >
73
  <planeGeometry args={[0.8, 0.8]} />
 
4
  import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
5
  import { Mesh } from 'three';
6
 
7
+ import { CubeColorIndices, CubeColors, FacingDirection, Rotations } from './consts';
8
  import { rotationController } from './rotation-controller';
9
 
10
  export type CubePieceRef = {
 
66
  rotation={Rotations[face as FacingDirection]}
67
  userData={{
68
  isFace: true,
 
69
  faceColor: color,
70
+ faceColorIndex: CubeColorIndices[face as FacingDirection],
71
  }}
72
  >
73
  <planeGeometry args={[0.8, 0.8]} />
src/components/rotation-controller.ts CHANGED
@@ -58,7 +58,7 @@ export class RotationController {
58
  return false;
59
  }
60
 
61
- private getCubeFace(mesh: Mesh, faceDirection: FacingDirection) {
62
  const faces = mesh.children.filter((child) => child.userData.isFace);
63
  let axis: 'x' | 'y' | 'z' = 'x';
64
  switch (faceDirection) {
@@ -86,8 +86,8 @@ export class RotationController {
86
  maxFace = face as Mesh;
87
  }
88
  }
89
- if (!maxFace) return null;
90
- return maxFace;
91
  }
92
 
93
  static getInstance() {
@@ -123,10 +123,10 @@ export class RotationController {
123
  return this.cubes.filter((m) => m.position.z > 0);
124
  case 'back':
125
  return this.cubes.filter((m) => m.position.z < 0);
126
- case 'left':
127
- return this.cubes.filter((m) => m.position.x < 0);
128
  case 'right':
129
  return this.cubes.filter((m) => m.position.x > 0);
 
 
130
  case 'top':
131
  return this.cubes.filter((m) => m.position.y > 0);
132
  case 'bottom':
@@ -134,9 +134,13 @@ export class RotationController {
134
  }
135
  }
136
 
137
- getFaces(faceDirection: FacingDirection) {
138
- const cubes = this.getCubes(faceDirection);
139
- return cubes.map((cube) => this.getCubeFace(cube, faceDirection));
 
 
 
 
140
  }
141
 
142
  setCubeSpeed(cubeSpeed: number) {
 
58
  return false;
59
  }
60
 
61
+ private getCubeFaceColorIndex(mesh: Mesh, faceDirection: FacingDirection) {
62
  const faces = mesh.children.filter((child) => child.userData.isFace);
63
  let axis: 'x' | 'y' | 'z' = 'x';
64
  switch (faceDirection) {
 
86
  maxFace = face as Mesh;
87
  }
88
  }
89
+ if (!maxFace) return -1; // this should never happen
90
+ return maxFace.userData.faceColorIndex as number;
91
  }
92
 
93
  static getInstance() {
 
123
  return this.cubes.filter((m) => m.position.z > 0);
124
  case 'back':
125
  return this.cubes.filter((m) => m.position.z < 0);
 
 
126
  case 'right':
127
  return this.cubes.filter((m) => m.position.x > 0);
128
+ case 'left':
129
+ return this.cubes.filter((m) => m.position.x < 0);
130
  case 'top':
131
  return this.cubes.filter((m) => m.position.y > 0);
132
  case 'bottom':
 
134
  }
135
  }
136
 
137
+ getStatus() {
138
+ return ['front', 'back', 'right', 'left', 'top', 'bottom'].map((f) => {
139
+ const faceDirection = f as FacingDirection;
140
+ const cubes = this.getCubes(faceDirection);
141
+ const indices = cubes.map((cube) => this.getCubeFaceColorIndex(cube, faceDirection));
142
+ return indices;
143
+ });
144
  }
145
 
146
  setCubeSpeed(cubeSpeed: number) {
src/components/state-modal.tsx ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use client';
2
+
3
+ import { Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, useDisclosure } from '@heroui/react';
4
+ import { forwardRef, useImperativeHandle, useState } from 'react';
5
+
6
+ export type StateModalRef = {
7
+ open: (status: Array<Array<number>>) => void;
8
+ };
9
+
10
+ export const StateModal = forwardRef<StateModalRef, unknown>((_, ref) => {
11
+ const [state, setState] = useState<Array<Array<number>>>([]);
12
+ const { isOpen, onOpen, onOpenChange } = useDisclosure();
13
+
14
+ useImperativeHandle(ref, () => ({
15
+ open: (state: Array<Array<number>>) => {
16
+ setState(state);
17
+ onOpen();
18
+ },
19
+ }));
20
+
21
+ const copy = () => {
22
+ navigator.clipboard.writeText(JSON.stringify(state));
23
+ };
24
+
25
+ return (
26
+ <Modal isOpen={isOpen} onOpenChange={onOpenChange}>
27
+ <ModalContent>
28
+ {(onClose) => (
29
+ <>
30
+ <ModalHeader>State</ModalHeader>
31
+ <ModalBody>
32
+ <div className="flex flex-col gap-2">
33
+ <div className="flex gap-2 items-center">
34
+ <div className="text-sm w-24 font-mont">Front</div>
35
+ <div className="font-mono">{JSON.stringify(state[0])}</div>
36
+ </div>
37
+ <div className="flex gap-2 items-center">
38
+ <div className="text-sm w-24 font-mont">Back</div>
39
+ <div className="font-mono">{JSON.stringify(state[1])}</div>
40
+ </div>
41
+ <div className="flex gap-2 items-center">
42
+ <div className="text-sm w-24 font-mont">Right</div>
43
+ <div className="font-mono">{JSON.stringify(state[2])}</div>
44
+ </div>
45
+ <div className="flex gap-2 items-center">
46
+ <div className="text-sm w-24 font-mont">Left</div>
47
+ <div className="font-mono">{JSON.stringify(state[3])}</div>
48
+ </div>
49
+ <div className="flex gap-2 items-center">
50
+ <div className="text-sm w-24 font-mont">Up</div>
51
+ <div className="font-mono">{JSON.stringify(state[4])}</div>
52
+ </div>
53
+ <div className="flex gap-2 items-center">
54
+ <div className="text-sm w-24 font-mont">Down</div>
55
+ <div className="font-mono">{JSON.stringify(state[5])}</div>
56
+ </div>
57
+ </div>
58
+ </ModalBody>
59
+ <ModalFooter>
60
+ <Button color="danger" variant="light" size="sm" onPress={onClose}>
61
+ Close
62
+ </Button>
63
+ <Button color="primary" size="sm" onPress={copy}>
64
+ Copy
65
+ </Button>
66
+ </ModalFooter>
67
+ </>
68
+ )}
69
+ </ModalContent>
70
+ </Modal>
71
+ );
72
+ });
73
+
74
+ StateModal.displayName = 'StateModal';
src/components/ui-controls.tsx CHANGED
@@ -1,14 +1,16 @@
1
  'use client';
2
 
3
  import { Button, ButtonGroup, Card, CardBody, Checkbox, Slider } from '@heroui/react';
4
- import { useState } from 'react';
5
 
6
  import { useControlContext } from '@/contexts/control-context';
7
 
8
  import { Actions } from './consts';
9
  import { rotationController } from './rotation-controller';
 
10
 
11
  export const UIControls = () => {
 
12
  const [isControlsOpen, setIsControlsOpen] = useState(true);
13
  const {
14
  rubiksCubeRef,
@@ -31,8 +33,8 @@ export const UIControls = () => {
31
  };
32
 
33
  const showState = () => {
34
- const faces = rotationController.getFaces('front');
35
- console.log(faces);
36
  };
37
 
38
  const solve = () => {
@@ -115,6 +117,8 @@ export const UIControls = () => {
115
  </div>
116
  </CardBody>
117
  </Card>
 
 
118
  </div>
119
  );
120
  };
 
1
  'use client';
2
 
3
  import { Button, ButtonGroup, Card, CardBody, Checkbox, Slider } from '@heroui/react';
4
+ import { useRef, useState } from 'react';
5
 
6
  import { useControlContext } from '@/contexts/control-context';
7
 
8
  import { Actions } from './consts';
9
  import { rotationController } from './rotation-controller';
10
+ import { StateModal, StateModalRef } from './state-modal';
11
 
12
  export const UIControls = () => {
13
+ const stateModalRef = useRef<StateModalRef | null>(null);
14
  const [isControlsOpen, setIsControlsOpen] = useState(true);
15
  const {
16
  rubiksCubeRef,
 
33
  };
34
 
35
  const showState = () => {
36
+ const status = rotationController.getStatus();
37
+ stateModalRef.current?.open(status);
38
  };
39
 
40
  const solve = () => {
 
117
  </div>
118
  </CardBody>
119
  </Card>
120
+
121
+ <StateModal ref={stateModalRef} />
122
  </div>
123
  );
124
  };