Commit 7a14c083 authored by Guillaume CLOCHARD's avatar Guillaume CLOCHARD
Browse files

Merge branch 'master' into temps_execution

parents b910412a 1bb254f5
......@@ -2,7 +2,23 @@
All notable changes to this project will be documented in this file.
See http://keepachangelog.com
## [Unreleased]
## v1.0.0 - 13/01/2016
### Fixed
- Prise en charge des cubes insolvables
### Added
- Une visualisation ascii des mouvements à effectuer
- Statistiques sur `algo.py`
- Tests unitaires
- Détection et remplacement des formes type "R R" ou "U U'"
avec `heuristique/`
### Changed
- Un tuto amélioré
- `solve()` respecte l'API demandée
- Étape F2L améliorée
- Optimisation utilisation mémoire
## v0.4.0 - 07/01/2016
......
......@@ -19,7 +19,7 @@ python poqb.y --cube OGRBWYBGBGYYOYOWOWGRYOOOBGBRRYRBWWWRBWYGROWGRYBRGYWBOG
## Terminal
```bash
python poqb.py [--cube | -c] <cube> [--tuto] [--auto] [--speed | -s] <speed> [--colors]
python poqb.py [--cube | -c] <cube> [--tuto] [--auto] [--speed | -s] <speed> [--moves] [--colors]
```
- `--cube <cube>` (optionnel). Un cube à résoudre.
......@@ -42,6 +42,10 @@ python poqb.py [--cube | -c] <cube> [--tuto] [--auto] [--speed | -s] <speed> [--
La vitesse d'avancée avec `--auto` en mouvements par secondes. Défaut 2/sec.
- `-s<speed>` (optionnel). Voir `--speed`.
- `--moves` (optionnel). Afficher la représentation des mouvements à effectuer sur le cube
en plus du patron coloré.
- `--colors` (optionnel).
Activer les couleurs ascii sous Windows, par exemple
......
......@@ -31,6 +31,9 @@ import re
from sys import argv
from Cube import Cube
from lire_entree import lecture_cube
from utils import croix_valide, ftl_valide, cfop_valide
from stats import moyenne,ecart_type
from utils import croix_valide, ftl_valide, cfop_valide, replace_sublist
SHORTCUTS = "shortcuts.json"
......@@ -1596,7 +1599,6 @@ if __name__ == '__main__':
len(mouvements)
)
)
listeMoyenne[4].append(len(mouv+mouv2+mouv3+mouv4))
listeMoyenne[0].append(len(mouv))
listeMoyenne[1].append(len(mouv2))
......@@ -1615,25 +1617,36 @@ if __name__ == '__main__':
round(moyenne(listeMoyenne[4]), 2),
TermColors.end + '\n'
)
#Tests insolvabilité
#Voir http://jeays.net/rubiks.htm#unsolvable
tests = [
#One edge piece is flipped in place and all other pieces are correct.
'YYYOYYYYYOYOBBBRRRGGGOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW',
#Two edge pieces need to be swapped and all other pieces are correct.
'YYYYYYYYYOROBBBRORGGGOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW',
#One corner piece needs rotating and all other pieces are correct.
'OYYYYYYYYGOOBBBRRRGGYOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW',
#Two corner pieces need to be swapped and all other pieces are correct.
'YYYYYYYYYROOBBGORRGGBOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW'
]
for t in tests:
err, c = lecture_cube(t)
assert(not err)
err, _ = algo_cfop(c)
print(TermColors.bgGreen + "Insolvable" + TermColors.end, c.to_line())
print('\n' + TermColors.bold + 'Ecarts types :' + TermColors.end)
print('☞ Croix :', round(ecart_type(listeMoyenne[0]), 2))
print('☞ FTL :', round(ecart_type(listeMoyenne[1]), 2))
print('☞ OLL :', round(ecart_type(listeMoyenne[2]), 2))
print('☞ PLL :', round(ecart_type(listeMoyenne[3]), 2))
print(
'☞ ' + TermColors.bold + 'Total :',
round(ecart_type(listeMoyenne[4]), 2),
TermColors.end + '\n'
)
#Tests insolvabilité
#Voir http://jeays.net/rubiks.htm#unsolvable
tests = [
#One edge piece is flipped in place and all other pieces are correct.
'YYYOYYYYYOYOBBBRRRGGGOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW',
#Two edge pieces need to be swapped and all other pieces are correct.
'YYYYYYYYYOROBBBRORGGGOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW',
#One corner piece needs rotating and all other pieces are correct.
'OYYYYYYYYGOOBBBRRRGGYOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW',
#Two corner pieces need to be swapped and all other pieces are correct.
'YYYYYYYYYROOBBGORRGGBOOOBBBRRRGGGOOOBBBRRRGGGWWWWWWWWW'
]
for t in tests:
err, c = lecture_cube(t)
assert(not err)
err, _ = algo_cfop(c)
print(TermColors.bgGreen + "Insolvable" + TermColors.end, c.to_line())
\ No newline at end of file
import matplotlib.pyplot as plt
from Cube import *
from algo import algo_cfop
import json
from lire_entree import lecture_cube
from stats import moyenne
JEU_TEST = 'tests/samples/liste-sample.json'
with open(JEU_TEST) as data_file: #on parse le jeu de test JSON
data = json.load(data_file)
tests = data["cubes"]
# dictionnaire pour stocker en clé : nbMouvement et
#en valeur : Occurence sur les n tests
listeNbMouvements = {}
for test in tests: # on parcours tout les cubes
b,c = lecture_cube(test)
c,mouv = algo_cfop(c) # on fais l'algo
# si le nombre de mouvements est deja dans la dictionnaire,
# on ajoute 1 à son occurence
if len(mouv) in listeNbMouvements:
listeNbMouvements[len(mouv)] += 1
else:
listeNbMouvements[len(mouv)] = 1 # sinon on l'ajoute
listeX = []
listeY = []
# on "separe" le dictionnaire en deux liste correspondant aux clés et aux valeurs
for x,y in listeNbMouvements.items():
listeX.append(x)
listeY.append(y)
plt.plot(listeX,listeY) # affichage de la courbe dans pyplot
plt.xlabel('Nombre de mouvements')
plt.ylabel('Occurence sur '+str(len(tests))+' test')
plt.show()
class AffichageMoves():
def img_B(self):
return "\
__________ \n\
| |\n\
| |\n\
\/ |\n\
___ ___ ____ |\n\
/___/___/___/| |\n\
/___/___/___/||____|\n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
| | | | /|| \n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_B2(self):
return "\
__________ \n\
| |\n\
| x2 |\n\
\/ |\n\
___ ___ ____ |\n\
/___/___/___/| |\n\
/___/___/___/||____|\n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
| | | | /|| \n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_Bi(self):
return "\
__________ \n\
| | \n\
| | \n\
| | \n\
___ __|_ ___ \/\n\
/___/___/___/| \n\
/___/___/___/||____ \n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
| | | | /|| \n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
\n\
\n\
\n\
\n"
return imgStr
def img_F(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| \n\
/___/___/___/|| \n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
___|___|__ | | /|| \n\
| |___|__||___|/|/ \n\
| | | || | / \n\
| |___|__||___|/ \n\
| | \n\
| \/ \n\
|__________ \n\
\n"
def img_F2(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| \n\
/___/___/___/|| \n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
___|___|__ | | /|| \n\
| |___|__||___|/|/ \n\
| | | || | / \n\
| |___|__||___|/ \n\
| | \n\
| x2 \/ \n\
|__________ \n\
\n"
def img_Fi(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/|\n\
/___/___/___/||\n\
/___/___/__ /|/|\n\
| | | | /||\n\
|___|___|___|/|/|\n\
___|___|__ | | /||\n\
| |___|__||___|/|/ \n\
| | | || | / \n\
| |___|__||___|/ \n\
| | \n\
\/ | \n\
__________| \n\
\n"
def img_L(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/| /___/___/___/|\n\
/ | /___/___/___/||\n\
/ | /___/___/__ /|/|\n\
| | | | | | /||\n\
| | |___|___|___|/|/|\n\
\/ | | | | | /||\n\
/ |___|___|___|/|/ \n\
/ | | | | / \n\
/ |___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_L2(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/| /___/___/___/|\n\
/ | /___/___/___/||\n\
/ | /___/___/__ /|/|\n\
| | | | | | /||\n\
| x2| |___|___|___|/|/|\n\
\/ | | | | | /||\n\
/ |___|___|___|/|/ \n\
/ | | | | / \n\
/ |___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_Li(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/| /___/___/___/|\n\
/ | /___/___/___/||\n\
/ | /___/___/__ /|/|\n\
| \/| | | | /||\n\
| |___|___|___|/|/|\n\
| | | | | /||\n\
| / |___|___|___|/|/ \n\
| / | | | | / \n\
|/ |___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_U(self):
return "\
____________ \n\
/ / \n\
/ \/ \n\
/___________ \n\
___ ___ ____ \n\
/___/___/___/|\n\
/___/___/___/||\n\
/___/___/__ /|/|\n\
| | | | /||\n\
|___|___|___|/|/|\n\
| | | | /||\n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_U2(self):
return "\
____________ \n\
/ / \n\
/ x2 \/ \n\
/___________ \n\
___ ___ ____ \n\
/___/___/___/|\n\
/___/___/___/||\n\
/___/___/__ /|/|\n\
| | | | /||\n\
|___|___|___|/|/|\n\
| | | | /||\n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_Ui(self):
return "\
____________ \n\
/ / \n\
\/ / \n\
___________/ \n\
___ ___ ____ \n\
/___/___/___/|\n\
/___/___/___/||\n\
/___/___/__ /|/|\n\
| | | | /||\n\
|___|___|___|/|/|\n\
| | | | /||\n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
\n\
\n\
\n\
\n"
def img_D(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| \n\
/___/___/___/|| \n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
| | | | /|| \n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
____________ \n\
/ / \n\
\/ / \n\
___________/ \n"
def img_D2(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| \n\
/___/___/___/|| \n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
| | | | /|| \n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
____________ \n\
/ / \n\
\/ x2 / \n\
___________/ \n"
def img_Di(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| \n\
/___/___/___/|| \n\
/___/___/__ /|/| \n\
| | | | /|| \n\
|___|___|___|/|/| \n\
| | | | /|| \n\
|___|___|___|/|/ \n\
| | | | / \n\
|___|___|___|/ \n\
____________ \n\
/ / \n\
/ \/ \n\
/___________ \n"
def img_R(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| /| \n\
/___/___/___/|| / | \n\
/___/___/__ /|/| / | \n\
| | | | /|| | | \n\
|___|___|___|/|/| | \/\n\
| | | | /|| | \n\
|___|___|___|/|/ | / \n\
| | | | / | / \n\
|___|___|___|/ |/ \n\
\n\
\n\
\n\
\n"
def img_R2(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| /| \n\
/___/___/___/|| / | \n\
/___/___/__ /|/| / | \n\
| | | | /|| | | \n\
|___|___|___|/|/| | \/\n\
| | | | /|| | x2 \n\
|___|___|___|/|/ | / \n\
| | | | / | / \n\
|___|___|___|/ |/ \n\
\n\
\n\
\n\
\n"
def img_Ri(self):
return "\
\n\
\n\
\n\
\n\
___ ___ ____ \n\
/___/___/___/| /|\n\
/___/___/___/|| / |\n\
/___/___/__ /|/| / |\n\
| | | | /|| | |\n\
|___|___|___|/|/| | |\n\
| | | | /|| | |\n\
|___|___|___|/|/ \/ / \n\
| | | | / / \n\
|___|___|___|/ / \n\
\n\
\n\
\n\
\n"
return imgStr
Moves = AffichageMoves()
def aideMouvements(c, mouv):
"""
aideMouvements
Appose une représentation ASCII du mouvement `m` effectué
sur le cube `c`
:Args:
c {Cube} Le cube à afficher
mouv {String} Le mouvement effectué sur le cube
:Return:
{String}
"""
#L'image ASCII
methodToCall = getattr(Moves, 'img_' + mouv)
imgRot = methodToCall()
cube = c.__str__()
cubeSplit = cube.split("\n")
imgSplit = imgRot.split("\n")
sizeCube = len(cubeSplit)
sizeImg = len(imgSplit)
strImg = ""
i = 0
cptCube = 0
while i < sizeImg:
if i <=14 and i > 5:
if cptCube == 6 or cptCube == 7 or cptCube ==8:
spacesManquant = 10 * ' '
else:
spacesManquant = ''
strImg += cubeSplit[cptCube]
strImg += spacesManquant
strImg += imgSplit[i] + "\n"
cptCube += 1
else:
spacesManquant = 39 * ' '
strImg += spacesManquant
strImg += imgSplit[i] + "\n"
i += 1
return strImg
from math import sqrt,fabs
def moyenne (liste):
moyenne = 0
for i in liste:
moyenne += i
return moyenne/len(liste)
def variance(liste):
variance = 0
moy = moyenne(liste)
for i in liste:
variance += (i-moy)*(i-moy)
return variance/len(liste)
def ecart_type(liste):
return sqrt(variance(liste))
def ecart_moyen(liste):
ecart_moyen = 0
moy = moyenne(liste)
for i in liste:
ecart_moyen += fabs(i-moy)
return ecart_moyen/len(liste)
from time import sleep
from utils import clear, readArgs, colorize, translate_mvt, newGetch, TermColors
from algo import algo_cfop
from images_ascii import aideMouvements
SPEED = 2 #écrans / sec
SPEED = 0.5 #écrans / sec
def tuto(cube, mouvements):
"""
......@@ -24,6 +25,12 @@ def tuto(cube, mouvements):
mouvementsRestants = list(mouvements)
clear()
if 'auto' in params:
print('Positionnez la face bleue face à vous et la face blanche face au sol\n')
print('Le tuto en mode auto va bientôt commencer, tenez vous prêt !')