File size: 5,164 Bytes
b570cf2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import numpy as np

# Target State
# 用整数表示颜色(0=白, 1=红, 2=绿, 3=黄, 4=橙, 5=蓝)
TARGET_STATE = np.array([
    0,0,0, 0,0,0, 0,0,0,  # U 面
    1,1,1, 1,1,1, 1,1,1,  # R 面
    2,2,2, 2,2,2, 2,2,2,  # F 面
    3,3,3, 3,3,3, 3,3,3,  # D 面
    4,4,4, 4,4,4, 4,4,4,  # L 面
    5,5,5, 5,5,5, 5,5,5   # B 面
], dtype=np.int32)

TARGET_STATE_ONE_HOT = np.eye(6)[TARGET_STATE]

# Function to print state as a cube unfolded diagram
def print_cube_state(state, title=None):
    print(title)
    # U face
    print(" " * 6 + " ".join(map(str, state[0:3])))
    print(" " * 6 + " ".join(map(str, state[3:6])))
    print(" " * 6 + " ".join(map(str, state[6:9])))
    # L, F, R, B faces
    for i in range(3):
        print(" ".join(map(str, state[36+i*3:39+i*3])) + " " + 
              " ".join(map(str, state[18+i*3:21+i*3])) + " " + 
              " ".join(map(str, state[9+i*3:12+i*3])) + " " + 
              " ".join(map(str, state[51+i*3:48+i*3])))
    # D face
    print(" " * 6 + " ".join(map(str, state[27:30])))
    print(" " * 6 + " ".join(map(str, state[30:33])))
    print(" " * 6 + " ".join(map(str, state[33:36])))
    print()

def invert_mapping(mapping):
        """生成逆映射"""
        inv = np.empty(len(mapping), dtype=int)
        inv[mapping] = np.arange(len(mapping))
        return inv

def make_moves():
    """
    生成 3x3x3 魔方的贴纸索引映射(逆时针 + 顺时针)
    贴纸编号顺序:
      U: 0-8,  R: 9-17,  F: 18-26,
      D: 27-35, L: 36-44, B: 51-47
    """

    moves = {}

    def cycle(mapping, positions):
        """按循环位置更新映射"""
        temp = mapping.copy()
        for cycle_pos in positions:
            cycle = np.append(cycle_pos, cycle_pos[0])
            mapping[cycle[:-1]] = temp[cycle[1:]]

    # 初始化基础状态(映射到自身)
    identity = np.arange(54)

    # 定义每个面的顺时针旋转
    face_cycles = {
        'U': [
            # 上面自身旋转
            [2, 8, 6, 0], [5, 7, 3, 1],
            # 侧面环
            [20, 9, 53, 36], [19, 10, 52, 37], [18, 11, 51, 38] 
        ],
        'D': [
            [29, 35, 33, 27], [28, 32, 34, 30],
            [24, 44, 45, 17], [25, 43, 46, 16], [26, 42, 47, 15]
        ],
        'F': [
            [18, 24, 26, 20], [19, 21, 25, 23],
            [17, 2, 36, 33], [14, 1, 39, 34], [11, 0, 42, 35]
        ],
        'B': [
            [51, 45, 47, 53], [52, 48, 46, 50],
            [9, 29, 44, 6], [12, 28, 41, 7], [15, 27, 38, 8]
        ],
        'L': [
            [36, 38, 44, 42], [37, 41, 43, 39],
            [33, 18, 6, 47], [30, 21, 3, 50], [27, 24, 0, 53]
        ],
        'R': [
            [17, 15, 9, 11], [16, 12, 10, 14],
            [45, 8, 20, 35], [48, 5, 23, 32], [51, 2, 26, 29]
        ]
    }

    # 生成顺时针和逆时针映射
    for face, cycles in face_cycles.items():
        mapping = identity.copy()
        cycle(mapping, cycles)
        moves[face] = mapping
        moves[face + "_inv"] = invert_mapping(mapping)

    return moves

class Cube:
    def __init__(self):
        # 初始化移动映射
        self.moves = make_moves()
        
    def apply_action(self, state, action):
        """
        根据输入的action和state得到新的state
        参数:
            state: 当前魔方状态,np.array
            action: 要执行的动作,如 'U', 'R_inv', 等
        返回:
            新的魔方状态
        """
        if action not in self.moves.keys():
            raise ValueError(f'不支持的动作: {action}')
        return state[self.moves[action]]
    
    def get_neibor_state(self, state):
        """
        获取当前state的所有邻居状态
        参数:
            state: 当前魔方状态,np.array
        返回:
            所有邻居状态的列表,np.array
        """
        neibor_states = []
        for action in self.moves.keys():
            neibor_states.append(self.apply_action(state, action))
        return np.stack(neibor_states, axis=0)

    def is_solved(self, state):
        """
        判断当前state是否是魔方被还原后的state
        参数:
            state: 当前魔方状态,np.array
        返回:
            是否还原的布尔值
        """
        return np.array_equal(state, TARGET_STATE)
    
    def view_state(self, state):
        pass



if __name__ == "__main__":
    # Initialize the Cube object
    cube = Cube()
    
    # Get the initial solved state
    initial_state = np.arange(54)

    # Define the rotation action
    action = 'F'
    # Print the initial state
    print_cube_state(initial_state, "Initial Cube State:")
    
    # Print the applied action
    print(f"Applied action: {action}")

    # Apply the rotation action
    new_state = cube.apply_action(initial_state, action)
    
    # Print the new state
    print_cube_state(new_state, "Cube State after Rotation:")

    action = 'U'

    new_state = cube.apply_action(new_state, action)
    
    # Print the applied action
    print(f"Applied action: {action}")
    print_cube_state(new_state, "Cube State after Rotation:")