[PYTHON] Logiciel mis à jour pour Rubik Cube Robot 1. Fonctions de base

Quel est cet article?

Je développe actuellement un robot qui résout un cube rubic 2x2x2. Ceci est une collection d'articles de commentaires sur le programme du robot. soltvvo3.jpg J'ai écrit une fois une collection d'articles représentés par l'article ici, mais depuis cette fois, le logiciel a été considérablement mis à jour, je vais donc introduire un nouveau programme. pense.

Le code applicable est disponible ici [https://github.com/Nyanyan/soltvvo/tree/master/Soltvvo3.2).

Articles Liés

"Faisons un robot qui résout le Rubik Cube!"

  1. Présentation
  2. Algorithme
  3. Logiciel
  4. Matériel

"Logiciel mis à jour pour Rubik Cube Robot"

  1. Fonction de base (cet article)
  2. Pré-calcul
  3. Recherche de solution
  4. Reconnaissance de l'État
  5. Fonctionnement de la machine (Python)
  6. Fonctionnement de la machine (Arduino)
  7. Traitement principal

Cette fois, nous allons introduire basic_functions.py``` comme fonctions de base.

Fonction pour faire pivoter le puzzle

Apprenez à conserver les puzzles dans un tableau et à mettre en œuvre le processus de rotation des puzzles.

'''Fonction pour faire pivoter le cube'''
''' Functions for twisting cube '''

#Traitement de rotation CP
# Rotate CP
def move_cp(cp, arr):
    #Remplacer les pièces en utilisant la surface et remplacer les baies
    surface = [[3, 1, 7, 5], [1, 0, 6, 7], [0, 2, 4, 6], [2, 3, 5, 4]]
    replace = [[3, 0, 1, 2], [2, 3, 0, 1], [1, 2, 3, 0]]
    res = [i for i in cp]
    for i, j in zip(surface[arr[0]], replace[-(arr[1] + 1)]):
        res[surface[arr[0]][j]] = cp[i]
    return res

#Traitement de rotation CO
# Rotate CO
def move_co(co, arr):
    #Après avoir remplacé les pièces en utilisant la surface et remplacé les tableaux, le tableau pls est utilisé pour reproduire le changement de CO lors d'une rotation de 90 degrés.
    surface = [[3, 1, 7, 5], [1, 0, 6, 7], [0, 2, 4, 6], [2, 3, 5, 4]]
    replace = [[3, 0, 1, 2], [2, 3, 0, 1], [1, 2, 3, 0]]
    pls = [2, 1, 2, 1]
    res = [i for i in co]
    for i, j in zip(surface[arr[0]], replace[-(arr[1] + 1)]):
        res[surface[arr[0]][j]] = co[i]
    if arr[1] != -2:
        for i in range(4):
            res[surface[arr[0]][i]] += pls[i]
            res[surface[arr[0]][i]] %= 3
    return res

Le Rubik Cube 2x2x2 (pars colorés) comprend huit parties d'un même type, comme indiqué sur la figure. iOS の画像(26).jpg Ce ne serait pas génial si vous aviez cet état de puzzle dans un arrangement de couleurs, par exemple, mais cela utilise beaucoup de mémoire et est avant tout gênant. Par conséquent, nous conserverons l'état du puzzle dans deux tableaux.

Il existe deux types. Chacun est représenté par un tableau de 8 éléments. Puisqu'il y a 8 parties, il y a des éléments 0, 1, 2, 3, 4, 5, 6, 7 '' '' du tableau CP, et il y a 3 types d'orientation de chaque partie, donc le tableau CO Les éléments sont 0, 1, 2 ''.

La fonction introduite exprime essentiellement l'action de ** rotation ** du puzzle par le ** remplacement ** du tableau. En ce qui concerne la disposition du CO, l'orientation des pièces change en fonction de la façon dont le puzzle est tourné, il y a donc un traitement supplémentaire.

Indexation d'état

Il n'est pas très bon de garder les puzzles dans un tableau à tout moment. Le traitement prend beaucoup de temps et consomme de la mémoire. Par conséquent, dans le prochain article (pré-calcul), nous associerons une valeur unique à chaque état du puzzle. J'expliquerai la fonction ** qui relie le tableau et la valeur ** qui est très utile en ce moment.

'''Indexation du tableau'''
''' Indexing'''

#Créer un numéro unique à partir du tableau cp
# Return the number of CP
def cp2idx(cp):
    #Indexé par multiplicateur de rang
    res = 0
    for i in range(8):
        cnt = cp[i]
        for j in cp[:i]:
            if j < cp[i]:
                cnt -= 1
        res += fac[7 - i] * cnt
    return res

#Créer un numéro unique à partir du tableau co
# Return the number of CO
def co2idx(co):
    #Indexé en ternaire. L'état est uniquement déterminé en regardant les 7 parties
    res = 0
    for i in co[:7]:
        res *= 3
        res += i
    return res

#Créer un tableau cp à partir d'un numéro unique
# Return the array of CP
def idx2cp(cp_idx):
    #Conversion du multiplicateur de base au tableau
    res = [-1 for _ in range(8)]
    for i in range(8):
        candidate = cp_idx // fac[7 - i]
        marked = [True for _ in range(i)]
        for _ in range(8):
            for j, k in enumerate(res[:i]):
                if k <= candidate and marked[j]:
                    candidate += 1
                    marked[j] = False
        res[i] = candidate
        cp_idx %= fac[7 - i]
    return res

#Créer un tableau co à partir d'un numéro unique
# Return the array of CO
def idx2co(co_idx):
    #Conversion de ternaire en tableau
    res = [0 for _ in range(8)]
    for i in range(7):
        res[6 - i] = co_idx % 3
        co_idx //= 3
    res[7] = (3 - sum(res) % 3) % 3
    return res

Pour l'indexation, le tableau CP doit être numéroté dans l'ordre, de sorte que le numéro de base est utilisé. Le tableau CO considère le tableau lui-même comme un nombre ternaire à 7 chiffres et le convertit en nombre décimal.

Je viens de mettre en œuvre ce qui est écrit sur le site ici pour calculer le nombre de rangs.

Vous vous demandez peut-être à propos de l'indexation des tableaux de CO, "Pourquoi le considérez-vous comme un nombre ternaire à 7 chiffres alors que le nombre d'éléments est de 8?" Tant que le CO du puzzle est dans le même état, si vous regardez les sept parties, vous pouvez voir l'état de la partie restante. C'est pourquoi un nombre ternaire à 7 chiffres suffit.

Constantes fréquemment utilisées

Les constantes et les tableaux qui sont souvent utilisés dans plusieurs programmes sont écrits ensemble.

'''constant'''
''' Constants '''

#Valeur du plancher
fac = [1]
for i in range(1, 9):
    fac.append(fac[-1] * i)

#Valeurs et tableaux fréquemment utilisés
grip_cost = 1
j2color = ['g', 'b', 'r', 'o', 'y', 'w']
dic = {'w':'white', 'g':'green', 'r':'red', 'b':'blue', 'o':'magenta', 'y':'yellow'}
parts_color = [['w', 'o', 'b'], ['w', 'b', 'r'], ['w', 'g', 'o'], ['w', 'r', 'g'], ['y', 'o', 'g'], ['y', 'g', 'r'], ['y', 'b', 'o'], ['y', 'r', 'b']]
parts_place = [[[0, 2], [2, 0], [2, 7]], [[0, 3], [2, 6], [2, 5]], [[1, 2], [2, 2], [2, 1]], [[1, 3], [2, 4], [2, 3]], [[4, 2], [3, 1], [3, 2]], [[4, 3], [3, 3], [3, 4]], [[5, 2], [3, 7], [3, 0]], [[5, 3], [3, 5], [3, 6]]]
twist_lst = [[[0, -1]], [[0, -2]], [[2, -1]], [[0, -1], [2, -1]], [[0, -2], [2, -1]], [[0, -1], [2, -2]], [[1, -1]], [[1, -2]], [[3, -1]], [[1, -1], [3, -1]], [[1, -2], [3, -1]], [[1, -1], [3, -2]]]
cost_lst = [1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 2]
solved_cp = [[0, 1, 2, 3, 4, 5, 6, 7], [2, 3, 4, 5, 6, 7, 0, 1], [4, 5, 6, 7, 0, 1, 2, 3], [6, 7, 0, 1, 2, 3, 4, 5], [1, 7, 3, 5, 2, 4, 0, 6], [3, 5, 2, 4, 0, 6, 1, 7], [2, 4, 0, 6, 1, 7, 3, 5], [0, 6, 1, 7, 3, 5, 2, 4], [7, 6, 5, 4, 3, 2, 1, 0], [5, 4, 3, 2, 1, 0, 7, 6], [3, 2, 1, 0, 7, 6, 5, 4], [1, 0, 7, 6, 5, 4, 3, 2], [6, 0, 4, 2, 5, 3, 7, 1], [4, 2, 5, 3, 7, 1, 6, 0], [5, 3, 7, 1, 6, 0, 4, 2], [7, 1, 6, 0, 4, 2, 5, 3], [2, 0, 3, 1, 5, 7, 4, 6], [3, 1, 5, 7, 4, 6, 2, 0], [5, 7, 4, 6, 2, 0, 3, 1], [4, 6, 2, 0, 3, 1, 5, 7], [6, 4, 7, 5, 1, 3, 0, 2], [7, 5, 1, 3, 0, 2, 6, 4], [1, 3, 0, 2, 6, 4, 7, 5], [0, 2, 6, 4, 7, 5, 1, 3]]
solved_co = [[0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2], [0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2], [1, 2, 2, 1, 1, 2, 2, 1], [1, 2, 2, 1, 1, 2, 2, 1], [1, 2, 2, 1, 1, 2, 2, 1], [1, 2, 2, 1, 1, 2, 2, 1], [0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2], [0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2], [1, 2, 2, 1, 1, 2, 2, 1], [1, 2, 2, 1, 1, 2, 2, 1], [1, 2, 2, 1, 1, 2, 2, 1], [1, 2, 2, 1, 1, 2, 2, 1], [0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2], [0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2], [0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2], [0, 0, 0, 0, 0, 0, 0, 0], [2, 1, 1, 2, 2, 1, 1, 2]]
neary_solved_depth = 15

La signification de chaque constante et tableau sera expliquée lors de son utilisation réelle.

Résumé

J'ai expliqué les fonctions de base du robot Rubik Cube. Tous les autres programmes utilisent cette fonction et ces constantes.

Recommended Posts

Logiciel mis à jour pour Rubik Cube Robot 1. Fonctions de base
Logiciel mis à jour pour Rubik Cube Robot 7. Opérations clés
Logiciel mis à jour pour Rubik Cube Robot 2. Pré-calcul
Logiciel mis à jour pour Rubik Cube Robot 3. Recherche de solutions
Logiciel mis à jour pour Rubik Cube Robot 4. Reconnaissance de statut
Logiciel mis à jour pour Rubik Cube Robot 6. Fonctionnement de la machine (Arduino)
Logiciel mis à jour pour Rubik Cube Robot 5. Machine Operation (Python)
Faisons un robot qui résout le Rubik Cube! 3 Logiciel
Cours de base Python (12 fonctions)
Faisons un robot qui résout le Rubik Cube! 2 Algorithme
Faisons un robot qui résout le Rubik Cube! 1. Vue d'ensemble