Projet de saisie d'un rubik's cube en langage C
Projet de saisie d'un rubik's cube en langage C
Cet article propose en détaille un projet de saisie d'un rubik's cube en langage C.
L'originalité de ce démonstrateur est l'utilisation d'un menu contextuel pour proposer les couleurs possibles pour la facette que l'on souhaite renseigner. La difficulté est de déterminer ces couleurs compte tenu des facettes déjà renseignées.
Cette fonction est assurée par la classe « CCompletion ». Elle traite les 54 facettes suivant leur type : 6 facettes centre de face, 24 facettes arêtes et 24 facettes sommets. Ces deux derniers types sont pris en compte par la classe « CCompletion::CSlv ». Chacune de ces 24 facettes utilisent 4 fois les six couleurs.
Ce programme permet de recopier des Cubes réels que, par exemple, on souhaite résoudre, mais il peut aussi servir à créer des configurations particulières dont la disposition des couleurs est remarquable. Ces configurations seront toujours solubles par le programme RubixCube. La communication entre ces deux programme se fait par le Presse Papier. Il est aussi possible de créer des configurations insolubles en levant les tests de rotation et de permutation comme dans le cas d'un Cube qui a été démonté (avec un tournevis...) puis remonté au hasard.
Vous pourrez télécharger le fichier au format zip il contient le code sources complet.
Extrait du code source :
// Completion.cpp: implementation of the CCompletion class.
//
#include "stdafx.h"
#include "Colors.h"
#include "Cubes.h"
#include "Completion.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// From the current state, determines the different configurations possible
// for the Rubik's Cube
typedef enum { // errors code
er_missColor=-1, er_complete=-2, er_tooColors=-3, er_badColor=-4,
er_invalidColors=-5, er_unsolvable=-6, er_badRotation=-7,
er_centersUndefine=-8, er_badPermut=-9, er_last=-10
};
static const UINT maxTests = 1000; // limit of search process
static const UINT maxNodeTbl = 20;
static t_CUBIES cubesEdgCrn = 0; // bits of edge and corner cubies
static BYTE defColorsId[6]; // list of center facet numbers
// Construction/Destruction
CCompletion::CCompletion() : m_edges(2), m_corners(3)
{
if ( cubesEdgCrn == 0 ) {
// builds the orientation facets table with the default colors
BYTE facet, color, facets[54];
SetSideText(CCubes().GetText(), facets, "ORGBWYUDLRFB");
for (facet = 4; facet
color = facets[facet];
ASSERT(color
defColorsId[color] = facet;
}
// the cubies selected with this class
cubesEdgCrn = m_edges.m_cubesBits | m_corners.m_cubesBits;
ASSERT((GetCubiesVSC(2)|GetCubiesVSC(3)) == cubesEdgCrn);
}
}
CCompletion::~CCompletion()
{
}
// //
// Prends en compte un jeu de facettes //
// //
void CCompletion::Get(const BYTE facets[54]) //
{
m_edges.Create(facets);
m_corners.Create(facets);
}
// //
// Assure la mise a jour des facettes qui n'ont qu'une couleur possible //
// //
void CCompletion::Update(BYTE facets[54]) //
{
CentersUpdate(facets);
Get(facets);
m_edges.Update(facets, m_corners.getFlags());
m_corners.Update(facets, m_edges.getFlags());
}
// //
// Cherche les couleurs possibles pour une facette donnee //
// //
t_COLORS CCompletion::GetPossibleColors(// retourne les couleurs possibles //
BYTE facet, // no facette a renseigner //
const BYTE facets[54]) const// couleurs des facettes //
{
t_COLORS colors;
BYTE type;
if ((facets[facet] & 0x0f)
// facet already filled
colors = 0;
} else if ((type = getFacetType(facet)) == 1) {
// facet center of face
colors = CubeOrientation(facet, facets);
} else if (type == 2) {
// facet of edge
ASSERT(m_edges.Compare(facets));
ASSERT(m_corners.Compare(facets));
colors = m_edges.getPossibleColors(facet, m_corners.getFlags());
} else if (type == 3) {
// facet of corner
ASSERT(m_edges.Compare(facets));
ASSERT(m_corners.Compare(facets));
colors = m_corners.getPossibleColors(facet, m_edges.getFlags());
}
return colors;
}
// //
// Mets a jour une facette donnee //
// //
void CCompletion::SetAt(BYTE facet, // facet number to update 0..53 //
BYTE color, // color to update 0..5 or 0xff //
BYTE facets[54], // facets table //
bool upd) // enable to auto update //
{
// update the facet
if (facet % 9 != 4) facets[facet] = color;
// retains the orientation of the face centers
else facets[facet] = (facets[facet] & 0xf0) | (color & 0x0f);
Get(facets);
if (upd) Update(facets);
}
// //
// Efface toutes les facettes liees //
// //
void CCompletion::DelLinked(BYTE facet, // facet number to update //
BYTE facets[54]) // facets table //
{
BYTE side;
if (getFacetType(facet)== 1) {
// facets center of face
for (side = 4; side
} else {
// facets edges or corners
SetSideColors( GetAllSides(facet), GROUP_EMPTY, facets );
}
Get(facets);
}