这是一个带自动还原算法的魔方小游戏,标准的七步还原法。适合初学者,可以一步步执行,也可以输入公式执行。魔方的每个小面上附加了一些装饰模型,直接在3dsmax中做好导出即可很方便配置。

魔方笼统的分为两大类:
    1,正阶魔方,正阶魔方最常见的是三阶魔方,有些看起来比较怪异的魔方比如镜面魔方和移楞魔方也属于正三阶魔方,因为转法是一样的。
    2,异形魔方,比如SQ1,金字塔,五魔方。

图 镜面魔方

图  移楞魔方(用圆柱魔方代替,只不过是模型不同而已)

魔方标准解法:
     正三阶魔方:七步还原法
     1,底层十字
     2,底层角块
     3,第二层楞块 (五转四回公式).
     4,顶层十字    (R'U'F' UFR  + 小鱼公式)
     5,顶层角块顶面(小鱼公式R'U'RU' R'U'U'R)
     6,顶层角块侧面(公式LF'LBB L'FLBB LL)
     7,顶层楞块侧面(FF ULR'FFL'R UFF)

正四阶魔方:仅需要比正三阶多记忆一个公式
     1,将6个面的4个中心块拼成颜色一致。
     2,将12条楞的中间2个棱块拼成颜色一致。(公式)
     3,按正三阶魔方的方法完成接下来的工作。

SQ1魔方:
     1,先还原到立方体(异形魔方的公式也是比较异形的)
     2,还原颜色

金字塔魔方:
     1,先还原4个角块
     2,还原楞块(交叉拧底部两个角和楞)

五魔方:公式比较多,但是有些公式跟正三阶很像。

降群法还原魔方:kociemba,IDA*。

魔方最小步数解法:
    正三阶魔方的上帝之数为20,意思是说任何正三阶魔方打乱状态都可以在20步之内还原。
    也就是说用深度优先搜索算法求解时可以限制递归深度为20。

如果直接遍历搜索可能会需要很长时间,需要一些优化方法。
    比如先列举N步内所能打乱的状态,在求解还原时只要找到这些列举状态中的一个即可,这样就把搜索的深度减少到了20-N。

网上有一些经过优化的算法可以达到在几十毫秒内搜索到二三十步还原的目标。

玩家基类:

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/MagicSquare/MagicSquare.h
//  @Brief:     MagicSquare
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================#ifndef  __MagicSquarePlayer__H__
#define  __MagicSquarePlayer__H__#include "Rpg/MiniGame.h"
namespace RendSys
{class Frame;
}
struct AABB;
enum Axis{X,Y,Z};
enum ChunkIndex{NEGATIVE,MIDDLE,POSITIVE};
enum RotateDir{CLOCKWISE,COUNTERCLOCKWISE,NOROTATE};
//6个面
enum FaceDir{FRONT,BACK,LEFT,RIGHT,UP,DOWN,NOASPECT};
enum FaceColor
{BLUE  ,GREEN ,RED   ,ORANGE,WHITE ,YELLOW,GRAY
};//小面
class Facelet
{
public:FaceDir   asp;int       index;FaceColor color;Facelet():asp(NOASPECT),index(-1),color(GRAY){}
};
//棱块
class Edge
{
public:Facelet faceletMain;Facelet faceletSide;
};
//角块
//class Corner
//{
//public:
//  Facelet faceletMain;
//  Facelet facelet1;
//  Facelet facelet2;
//};class MagicSquareSolver
{
public:MagicSquareSolver();MagicSquareSolver(MagicSquareSolver& other);virtual void Reset();virtual void Random();bool    IsValidLayout();void    GetFacelet4(Facelet* facelet,FaceColor color);Facelet GetNeighborEdgeFacelet(Facelet facelet);void    GetNeighborCornerFacelets(Facelet* neighbor2,Facelet facelet);Edge    GetEdge(FaceColor colorMain,FaceColor colorSide);//第一层十字bool IsCrossed();void Cross();//第一层角bool IsFirstLayerCornerRestored();    void Layer1Corner();//第二层棱bool IsSecondLayerEdgeRestored();void Layer2Edge();//前两层bool IsF2L();void F2L();//第三层十字bool IsTopCrossed();void TopCross();//1:fewer formulas methodbool IsTopCrossMatched();void MatchTopCross();bool IsTopCornerBack();bool IsTopCornerBack(Facelet f);int  HashCorner(FaceColor c1,FaceColor c2,FaceColor c3);void BackTopCorner();bool IsTopCornerRestored();void RestoreTopCorner();void MethodFewerFormula();//2:standard cfop methodvoid HashOLL(char*);bool IsTopFaceRestored();void OLL();void HashPLL(char*);//not finishedvoid PLL();void CFOP();typedef void (MagicSquareSolver::*RotateFun)(int flag);static RotateFun RotateFunTable[3][3][2];static const char* RotateFunNameTable[3][3][2];//==================^_^//look from positive to negative along axis to decide clockwise or notvirtual void rotateFullAspectCW(FaceDir asp, int* index);virtual void rotateFullAspectACW(FaceDir asp, int* index);virtual void rotateXLeftCW(int flag=3);virtual void rotateXLeftACW(int flag=3);virtual void rotateXRightCW(int flag=3);virtual void rotateXRightACW(int flag=3);virtual void rotateXMiddleCW(int flag=3);virtual void rotateXMiddleACW(int flag=3);virtual void rotateYDownCW(int flag=3);virtual void rotateYDownACW(int flag=3);virtual void rotateYUpCW(int flag=3);virtual void rotateYUpACW(int flag=3);virtual void rotateYMiddleCW(int flag=3);virtual void rotateYMiddleACW(int flag=3);virtual void rotateZFrontCW(int flag=3);virtual void rotateZFrontACW(int flag=3);virtual void rotateZBackCW(int flag=3);virtual void rotateZBackACW(int flag=3);virtual void rotateZMiddleCW(int flag=3);virtual void rotateZMiddleACW(int flag=3);//==================^_^void F();void Fr();void B();void Br();void R();void Rr();void L();void Lr();void U();void Ur();void D();void Dr();//rotate middle layer along y axis void E ();void Er();void E2();//rotate middle layer along x axis void M ();void Mr();void M2();//rotate middle layer along z axis void S ();void Sr();void S2();void F2();void B2();void R2();void L2();void U2();void D2();//rotate whole cube along x axis void x();void xr();void x2();//rotate whole cube along y axis void y();void yr();void y2();//rotate whole cube along z axis void z();void zr();void z2();//rotate top two layer void u();void ur();void u2();//rotate right two layer void r();void rr();void r2();//rotate front two layer void f();void fr();void f2();//rotate down two layer void d();void dr();void d2();//rotate left two layer void l();void lr();void l2();//rotate back two layer void b();void br();void b2();void Execute(const char* cmd);void SaveFromFile();void LoadFromFile();FaceColor  m_blockColors[6][9];//char       m_history[1024];int        m_historyNum;
};
//多阶正魔方很容易扩展,但自动求解算法比较难//异形魔方 旋转面不再是AABB 旋转轴心 旋转的角度不再是90度  可能带绑定(限制转动)//todo   3个观察镜面 class MagicSquarePlayer: public MiniPlayer,public MagicSquareSolver
{
public:MagicSquarePlayer();virtual ~MagicSquarePlayer();virtual bool Start();virtual bool Stop();virtual void Update();virtual void Render();FaceDir GetAspect(const vec2I& point);int  GetSmallAspectIndex(FaceDir asp,const vec2I& point);bool IsInThisRect(vec2I* pts,const vec2I& point);virtual void Reset();void OnRandom();void OnSolution();void OnExecute(const char* str);void OnStopExecute();typedef void (MagicSquarePlayer::*RotateFun)(int flag);static RotateFun RotateFunTable[3][3][2];//==================^_^void AnimRotate(float ang);void BackupFrame(const AABB& bound);void RestoreFrame();void rotate3D(const AABB& bound,const vec3& axis);//look from positive to negative along axis to decide clockwise or notvirtual void rotateFullAspectCW(FaceDir asp, int* index);virtual void rotateFullAspectACW(FaceDir asp, int* index);virtual void rotateXLeftCW(int flag=3);virtual void rotateXLeftACW(int flag=3);virtual void rotateXRightCW(int flag=3);virtual void rotateXRightACW(int flag=3);virtual void rotateXMiddleCW(int flag=3);virtual void rotateXMiddleACW(int flag=3);virtual void rotateYDownCW(int flag=3);virtual void rotateYDownACW(int flag=3);virtual void rotateYUpCW(int flag=3);virtual void rotateYUpACW(int flag=3);virtual void rotateYMiddleCW(int flag=3);virtual void rotateYMiddleACW(int flag=3);virtual void rotateZFrontCW(int flag=3);virtual void rotateZFrontACW(int flag=3);virtual void rotateZBackCW(int flag=3);virtual void rotateZBackACW(int flag=3);virtual void rotateZMiddleCW(int flag=3);virtual void rotateZMiddleACW(int flag=3);//==================^_^//private:enum PlayerState{None,DragRotating,AnimRotating,ExecuteRotating,};static const int BlockSize=30;vec2I      m_offset;//indexes for small aspects in a big aspect is in the order shown in 3d versionvec2I      blockVertexes[6][9][4];//小面vec2I      aspectVertexes[6][4];  //大面TexturePtr m_texture;RectF      m_colorTexRects[8];//PlayerState  m_state;bool         m_dragRotDecided;MovieClip*   m_dragStartMovie;vec3         m_dragBeginRegularPos;vec3         m_dragBeginRegularNormal;vec2         m_dragBeginMousePos;vec2         m_dragDecideMousePos;char         m_executeStr[1024];//float        RotSpeed;float        m_rotAnimAng;//m_rotAnimAng!=0 be rotatingvec3         m_rotAxis;float        m_rotPlane;MovieClip*   m_movieCube3;MovieClip*   m_movieSelect;MovieClip*   m_movieOrnament;#define BlockNum 26
#define OrnamentNum 54*2  //装饰Frame*       m_blockFrames;MovieClip*   m_movieBlocks[BlockNum];bool         m_bBlockRotating[BlockNum];MovieClip*   m_movieOrnamentBlocks[OrnamentNum];bool         m_bOrnamentRotating[OrnamentNum];Frame*       m_ornamentFrames;int          m_ornamentBlockNum;};#endif
//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/MagicSquare/MagicSquare.cpp
//  @Brief:     MagicSquare
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================#include "General/Pch.h"
#include "General/Window.h"
#include "Math/MathLibAdvance.h"
#include "MagicSquare/MagicSquarePlayer.h"
#include "MagicSquare/MiniGameMagicSquare.h"
#include "General/Timer.h"
#include "Rpg/SyncGameInfo.h"
#include "Sound/SoundManager.h"
#include "Packet/PacketMiniGame.h"
#include "Render/RendDriver.h"
#include "Render/MC_MovieClip.h"
#include "Render/MC_Misc.h"
#include "General/Pce.h"static FaceColor AspectColorOri[6][9] =
{//front{BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE},//back{GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN},//left{RED, RED, RED, RED, RED, RED, RED, RED, RED},//right{ORANGE, ORANGE, ORANGE, ORANGE, ORANGE, ORANGE, ORANGE, ORANGE, ORANGE},//up{WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE},//down{YELLOW, YELLOW, YELLOW, YELLOW, YELLOW, YELLOW, YELLOW, YELLOW, YELLOW}
};
//==================^_^==================^_^==================^_^==================^_^MagicSquareSolver::MagicSquareSolver()
{for (int i=0;i<6;i++){for (int j=0;j<9;j++){m_blockColors[i][j] = AspectColorOri[i][j];}}memset(m_history,0,sizeof(m_history));m_historyNum = 0;
}MagicSquareSolver::MagicSquareSolver(MagicSquareSolver& other)
{for (int i=0;i<6;i++){for (int j=0;j<9;j++){m_blockColors[i][j] = other.m_blockColors[i][j];}}memset(m_history,0,sizeof(m_history));m_historyNum = 0;
}void MagicSquareSolver::Reset()
{memcpy(m_blockColors, AspectColorOri, sizeof(AspectColorOri));m_history[0] = '\0';m_historyNum = 0;
}
void MagicSquareSolver::Random()
{Reset();char buf[128] = "";int scrambleNumber = 30;while(scrambleNumber-- > 0){//有多态RotateFun fun = RotateFunTable[rand() % 3][rand() % 2 * 2][rand() % 2];(this->*fun)(3);//strcat(ra)}
}MagicSquareSolver::RotateFun MagicSquareSolver::RotateFunTable[3][3][2] =
{//x from negative to positive,i.e. from left to right{   {&MagicSquareSolver::rotateXLeftCW  , &MagicSquareSolver::rotateXLeftACW},{&MagicSquareSolver::rotateXMiddleCW, &MagicSquareSolver::rotateXMiddleACW},{&MagicSquareSolver::rotateXRightCW , &MagicSquareSolver::rotateXRightACW}},//y{   {&MagicSquareSolver::rotateYDownCW  , &MagicSquareSolver::rotateYDownACW},{&MagicSquareSolver::rotateYMiddleCW, &MagicSquareSolver::rotateYMiddleACW},{&MagicSquareSolver::rotateYUpCW    , &MagicSquareSolver::rotateYUpACW}},//z{  {&MagicSquareSolver::rotateZBackCW  , &MagicSquareSolver::rotateZBackACW},{&MagicSquareSolver::rotateZMiddleCW, &MagicSquareSolver::rotateZMiddleACW},{&MagicSquareSolver::rotateZFrontCW , &MagicSquareSolver::rotateZFrontACW}},
};const char* MagicSquareSolver::RotateFunNameTable[3][3][2] =
{//x from negative to positive,i.e. from left to right{   {"L'" , "L"},{"M'" , "M"},{"R'" , "R"}},//y{  {"D'" , "D"},{"E'" , "E"},{"U'" , "U"}},//z{  {"B'" , "B"},{"S'" , "S"},{"F'" , "F"}},
};//==================^_^==================^_^==================^_^==================^_^
//look from positive to negative along axis to decide clockwise or not
void MagicSquareSolver::rotateFullAspectCW(FaceDir asp, int* index)
{FaceColor t[2];for(int i = 0; i < 2; i++){t[i] = m_blockColors[asp][index[i + 6]];}for(int i = 7; i > 1; i--){m_blockColors[asp][index[i]] = m_blockColors[asp][index[i - 2]];}for(int i = 0; i < 2; i++){m_blockColors[asp][index[i]] = t[i];}
}
void MagicSquareSolver::rotateFullAspectACW(FaceDir asp, int* index)
{FaceColor t[2];for(int i = 0; i < 2; i++){t[i] = m_blockColors[asp][index[i]];}for(int i = 0; i < 6; i++){m_blockColors[asp][index[i]] = m_blockColors[asp][index[i + 2]];}for(int i = 0; i < 2; i++){m_blockColors[asp][index[i + 6]] = t[i];}
}
void MagicSquareSolver::rotateXLeftCW(int flag)
{int index[9] = {6, 7, 8, 5, 2, 1, 0, 3};rotateFullAspectCW(LEFT, index);//front ,down,back,upfor(int i = 0; i <= 6; i += 3){FaceColor t = m_blockColors[FRONT][i];m_blockColors[FRONT][i] = m_blockColors[DOWN][i];m_blockColors[DOWN][i] = m_blockColors[BACK][6 - i];m_blockColors[BACK][6 - i] = m_blockColors[UP][6 - i];m_blockColors[UP][6 - i] = t;}
}
void MagicSquareSolver::rotateXLeftACW(int flag)
{int index[9] = {6, 7, 8, 5, 2, 1, 0, 3};rotateFullAspectACW(LEFT, index);//front ,up,back,downfor(int i = 0; i <= 6; i += 3){FaceColor t = m_blockColors[FRONT][i];m_blockColors[FRONT][i] = m_blockColors[UP][6 - i];m_blockColors[UP][6 - i] = m_blockColors[BACK][6 - i];m_blockColors[BACK][6 - i] = m_blockColors[DOWN][i];m_blockColors[DOWN][i] = t;}
}
void MagicSquareSolver::rotateXRightCW(int flag)
{int index[9] = {6, 7, 8, 5, 2, 1, 0, 3};rotateFullAspectCW(RIGHT, index);//front ,down,back,upfor(int i = 0; i <= 6; i += 3){FaceColor t = m_blockColors[FRONT][i + 2];m_blockColors[FRONT][i + 2] = m_blockColors[DOWN][i + 2];m_blockColors[DOWN][i + 2] = m_blockColors[BACK][6 - i + 2];m_blockColors[BACK][6 - i + 2] = m_blockColors[UP][6 - i + 2];m_blockColors[UP][6 - i + 2] = t;}
}
void MagicSquareSolver::rotateXRightACW(int flag)
{int index[9] = {6, 7, 8, 5, 2, 1, 0, 3};rotateFullAspectACW(RIGHT, index);//front ,up,back,downfor(int i = 0; i <= 6; i += 3){FaceColor t = m_blockColors[FRONT][i + 2];m_blockColors[FRONT][i + 2] = m_blockColors[UP][6 - i + 2];m_blockColors[UP][6 - i + 2] = m_blockColors[BACK][6 - i + 2];m_blockColors[BACK][6 - i + 2] = m_blockColors[DOWN][i + 2];m_blockColors[DOWN][i + 2] = t;}
}
void MagicSquareSolver::rotateXMiddleCW(int flag)
{//front ,down,back,upfor(int i = 0; i <= 6; i += 3){FaceColor t = m_blockColors[FRONT][i + 1];m_blockColors[FRONT][i + 1] = m_blockColors[DOWN][i + 1];m_blockColors[DOWN][i + 1] = m_blockColors[BACK][6 - i + 1];m_blockColors[BACK][6 - i + 1] = m_blockColors[UP][6 - i + 1];m_blockColors[UP][6 - i + 1] = t;}
}
void MagicSquareSolver::rotateXMiddleACW(int flag)
{//front ,up,back,downfor(int i = 0; i <= 6; i += 3){FaceColor t = m_blockColors[FRONT][i + 1];m_blockColors[FRONT][i + 1] = m_blockColors[UP][6 - i + 1];m_blockColors[UP][6 - i + 1] = m_blockColors[BACK][6 - i + 1];m_blockColors[BACK][6 - i + 1] = m_blockColors[DOWN][i + 1];m_blockColors[DOWN][i + 1] = t;}
}
void MagicSquareSolver::rotateYDownCW(int flag)
{int index[9] = {6, 3, 0, 1, 2, 5, 8, 7};rotateFullAspectCW(DOWN, index);//front,right,back,leftfor(int i = 0; i < 3; i++){FaceColor t = m_blockColors[FRONT][i];m_blockColors[FRONT][i] = m_blockColors[RIGHT][3 * (2 - i)];m_blockColors[RIGHT][3 * (2 - i)] = m_blockColors[BACK][2 - i];m_blockColors[BACK][2 - i] = m_blockColors[LEFT][i * 3];m_blockColors[LEFT][i * 3] = t;}
}
void MagicSquareSolver::rotateYDownACW(int flag)
{int index[9] = {6, 3, 0, 1, 2, 5, 8, 7};rotateFullAspectACW(DOWN, index);//front,left,back,rightfor(int i = 0; i < 3; i++){FaceColor t = m_blockColors[FRONT][i];m_blockColors[FRONT][i] = m_blockColors[LEFT][3 * i];m_blockColors[LEFT][3 * i] = m_blockColors[BACK][2 - i];m_blockColors[BACK][2 - i] = m_blockColors[RIGHT][(2 - i) * 3];m_blockColors[RIGHT][(2 - i) * 3] = t;}
}
void MagicSquareSolver::rotateYUpCW(int flag)
{int index[9] = {6, 3, 0, 1, 2, 5, 8, 7};rotateFullAspectCW(UP, index);//front,right,back,leftfor(int i = 0; i < 3; i++){FaceColor t = m_blockColors[FRONT][6 + i];m_blockColors[FRONT][6 + i] = m_blockColors[RIGHT][2 + 3 * (2 - i)];m_blockColors[RIGHT][2 + 3 * (2 - i)] = m_blockColors[BACK][6 + 2 - i];m_blockColors[BACK][6 + 2 - i] = m_blockColors[LEFT][2 + i * 3];m_blockColors[LEFT][2 + i * 3] = t;}
}
void MagicSquareSolver::rotateYUpACW(int flag)
{int index[9] = {6, 3, 0, 1, 2, 5, 8, 7};rotateFullAspectACW(UP, index);//front,left,back,rightfor(int i = 0; i < 3; i++){FaceColor t = m_blockColors[FRONT][6 + i];m_blockColors[FRONT][6 + i] = m_blockColors[LEFT][2 + 3 * i];m_blockColors[LEFT][2 + 3 * i] = m_blockColors[BACK][6 + 2 - i];m_blockColors[BACK][6 + 2 - i] = m_blockColors[RIGHT][2 + (2 - i) * 3];m_blockColors[RIGHT][2 + (2 - i) * 3] = t;}
}
void MagicSquareSolver::rotateYMiddleCW(int flag)
{   //front,right,back,leftfor(int i = 0; i < 3; i++){FaceColor t = m_blockColors[FRONT][3 + i];m_blockColors[FRONT][3 + i] = m_blockColors[RIGHT][1 + 3 * (2 - i)];m_blockColors[RIGHT][1 + 3 * (2 - i)] = m_blockColors[BACK][3 + 2 - i];m_blockColors[BACK][3 + 2 - i] = m_blockColors[LEFT][1 + i * 3];m_blockColors[LEFT][1 + i * 3] = t;}
}
void MagicSquareSolver::rotateYMiddleACW(int flag)
{//front,left,back,rightfor(int i = 0; i < 3; i++){FaceColor t = m_blockColors[FRONT][3 + i];m_blockColors[FRONT][3 + i] = m_blockColors[LEFT][1 + 3 * i];m_blockColors[LEFT][1 + 3 * i] = m_blockColors[BACK][3 + 2 - i];m_blockColors[BACK][3 + 2 - i] = m_blockColors[RIGHT][1 + (2 - i) * 3];m_blockColors[RIGHT][1 + (2 - i) * 3] = t;}
}
void MagicSquareSolver::rotateZFrontCW(int flag)
{int index[9] = {0, 3, 6, 7, 8, 5, 2, 1};rotateFullAspectCW(FRONT, index);FaceColor t = m_blockColors[UP][6];m_blockColors[UP][6] = m_blockColors[UP][8];m_blockColors[UP][8] = t;t = m_blockColors[DOWN][6];m_blockColors[DOWN][6] = m_blockColors[DOWN][8];m_blockColors[DOWN][8] = t;FaceColor tmp[3];int size = 3 * sizeof(FaceColor);memcpy(tmp, &m_blockColors[LEFT][6], size);memcpy(&m_blockColors[LEFT][6], &m_blockColors[DOWN][6], size);memcpy(&m_blockColors[DOWN][6], &m_blockColors[RIGHT][6], size);memcpy(&m_blockColors[RIGHT][6], &m_blockColors[UP][6], size);memcpy(&m_blockColors[UP][6], tmp, size);
}
void MagicSquareSolver::rotateZFrontACW(int flag)
{int index[9] = {0, 3, 6, 7, 8, 5, 2, 1};rotateFullAspectACW(FRONT, index);FaceColor t = m_blockColors[LEFT][6];m_blockColors[LEFT][6] = m_blockColors[LEFT][8];m_blockColors[LEFT][8] = t;t = m_blockColors[RIGHT][6];m_blockColors[RIGHT][6] = m_blockColors[RIGHT][8];m_blockColors[RIGHT][8] = t;FaceColor tmp[3];int size = 3 * sizeof(FaceColor);memcpy(tmp, &m_blockColors[LEFT][6], size);memcpy(&m_blockColors[LEFT][6], &m_blockColors[UP][6], size);memcpy(&m_blockColors[UP][6], &m_blockColors[RIGHT][6], size);memcpy(&m_blockColors[RIGHT][6], &m_blockColors[DOWN][6], size);memcpy(&m_blockColors[DOWN][6], tmp, size);
}
void MagicSquareSolver::rotateZBackCW(int flag)
{int index[9] = {0, 3, 6, 7, 8, 5, 2, 1};rotateFullAspectCW(BACK, index);FaceColor t = m_blockColors[UP][0];m_blockColors[UP][0] = m_blockColors[UP][2];m_blockColors[UP][2] = t;t = m_blockColors[DOWN][0];m_blockColors[DOWN][0] = m_blockColors[DOWN][2];m_blockColors[DOWN][2] = t;FaceColor tmp[3];int size = 3 * sizeof(FaceColor);memcpy(tmp, &m_blockColors[LEFT][0], size);memcpy(&m_blockColors[LEFT][0], &m_blockColors[DOWN][0], size);memcpy(&m_blockColors[DOWN][0], &m_blockColors[RIGHT][0], size);memcpy(&m_blockColors[RIGHT][0], &m_blockColors[UP][0], size);memcpy(&m_blockColors[UP][0], tmp, size);
}
void MagicSquareSolver::rotateZBackACW(int flag)
{int index[9] = {0, 3, 6, 7, 8, 5, 2, 1};rotateFullAspectACW(BACK, index);FaceColor t = m_blockColors[LEFT][0];m_blockColors[LEFT][0] = m_blockColors[LEFT][2];m_blockColors[LEFT][2] = t;t = m_blockColors[RIGHT][0];m_blockColors[RIGHT][0] = m_blockColors[RIGHT][2];m_blockColors[RIGHT][2] = t;FaceColor tmp[3];int size = 3 * sizeof(FaceColor);memcpy(tmp, &m_blockColors[LEFT][0], size);memcpy(&m_blockColors[LEFT][0], &m_blockColors[UP][0], size);memcpy(&m_blockColors[UP][0], &m_blockColors[RIGHT][0], size);memcpy(&m_blockColors[RIGHT][0], &m_blockColors[DOWN][0], size);memcpy(&m_blockColors[DOWN][0], tmp, size);
}
void MagicSquareSolver::rotateZMiddleCW(int flag)
{FaceColor t = m_blockColors[UP][3];m_blockColors[UP][3] = m_blockColors[UP][5];m_blockColors[UP][5] = t;t = m_blockColors[DOWN][3];m_blockColors[DOWN][3] = m_blockColors[DOWN][5];m_blockColors[DOWN][5] = t;FaceColor tmp[3];int size = 3 * sizeof(FaceColor);memcpy(tmp, &m_blockColors[LEFT][3], size);memcpy(&m_blockColors[LEFT][3], &m_blockColors[DOWN][3], size);memcpy(&m_blockColors[DOWN][3], &m_blockColors[RIGHT][3], size);memcpy(&m_blockColors[RIGHT][3], &m_blockColors[UP][3], size);memcpy(&m_blockColors[UP][3], tmp, size);
}
void MagicSquareSolver::rotateZMiddleACW(int flag)
{FaceColor t = m_blockColors[LEFT][3];m_blockColors[LEFT][3] = m_blockColors[LEFT][5];m_blockColors[LEFT][5] = t;t = m_blockColors[RIGHT][3];m_blockColors[RIGHT][3] = m_blockColors[RIGHT][5];m_blockColors[RIGHT][5] = t;FaceColor tmp[3];int size = 3 * sizeof(FaceColor);memcpy(tmp, &m_blockColors[LEFT][3], size);memcpy(&m_blockColors[LEFT][3], &m_blockColors[UP][3], size);memcpy(&m_blockColors[UP][3], &m_blockColors[RIGHT][3], size);memcpy(&m_blockColors[RIGHT][3], &m_blockColors[DOWN][3], size);memcpy(&m_blockColors[DOWN][3], tmp, size);
}//check whether the user edited cube is a valid cube
bool MagicSquareSolver::IsValidLayout(void)
{return false;
}
//find the four facelets on edge for a color
void MagicSquareSolver::GetFacelet4(Facelet* facelet, FaceColor color)
{int pointer = 0;int index[4] = {1, 3, 5, 7}; //facelets numbered 1,3,5,7 is on edgesfor(int i = 0; i < 6; i++){for(int j = 0; j < 4; j++){if(m_blockColors[i][index[j]] == color){facelet[pointer].asp = (FaceDir)i;facelet[pointer].index = index[j];facelet[pointer].color = m_blockColors[facelet[pointer].asp][facelet[pointer].index];pointer++;if(pointer >= 4) //all have been found{return;}}}}//ASSERT(pointer==4);
}
//find the other facelet on the same edge
Facelet MagicSquareSolver::GetNeighborEdgeFacelet(Facelet facelet)
{Facelet faceletNeighbor;switch(facelet.asp){case FRONT:faceletNeighbor.index = 7;switch(facelet.index){case 1:faceletNeighbor.asp = DOWN;break;case 3:faceletNeighbor.asp = LEFT;break;case 5:faceletNeighbor.asp = RIGHT;break;case 7:faceletNeighbor.asp = UP;break;default:break;}break;case BACK:faceletNeighbor.index = 1;switch(facelet.index){case 1:faceletNeighbor.asp = DOWN;break;case 3:faceletNeighbor.asp = LEFT;break;case 5:faceletNeighbor.asp = RIGHT;break;case 7:faceletNeighbor.asp = UP;break;default:break;}break;case RIGHT:faceletNeighbor.index = 5;switch(facelet.index){case 1:faceletNeighbor.asp = BACK;break;case 3:faceletNeighbor.asp = DOWN;break;case 5:faceletNeighbor.asp = UP;break;case 7:faceletNeighbor.asp = FRONT;break;default:break;}break;case LEFT:faceletNeighbor.index = 3;switch(facelet.index){case 1:faceletNeighbor.asp = BACK;break;case 3:faceletNeighbor.asp = DOWN;break;case 5:faceletNeighbor.asp = UP;break;case 7:faceletNeighbor.asp = FRONT;break;default:break;}break;case UP:switch(facelet.index){case 1:faceletNeighbor.asp = BACK;faceletNeighbor.index = 7;break;case 3:faceletNeighbor.asp = LEFT;faceletNeighbor.index = 5;break;case 5:faceletNeighbor.asp = RIGHT;faceletNeighbor.index = 5;break;case 7:faceletNeighbor.asp = FRONT;faceletNeighbor.index = 7;break;default:break;}break;case DOWN:switch(facelet.index){case 1:faceletNeighbor.asp = BACK;faceletNeighbor.index = 1;break;case 3:faceletNeighbor.asp = LEFT;faceletNeighbor.index = 3;break;case 5:faceletNeighbor.asp = RIGHT;faceletNeighbor.index = 3;break;case 7:faceletNeighbor.asp = FRONT;faceletNeighbor.index = 1;break;default:break;}break;default:break;}faceletNeighbor.color = m_blockColors[faceletNeighbor.asp][faceletNeighbor.index];return faceletNeighbor;
}
//find the other two facelets on the same corner
void MagicSquareSolver::GetNeighborCornerFacelets(Facelet* neighbor2, Facelet facelet)
{if(facelet.asp == FRONT){switch(facelet.index){case 0:neighbor2[0].asp = LEFT;neighbor2[0].index = 6;neighbor2[1].asp = DOWN;neighbor2[1].index = 6;break;case 2:neighbor2[0].asp = DOWN;neighbor2[0].index = 8;neighbor2[1].asp = RIGHT;neighbor2[1].index = 6;break;case 6:neighbor2[0].asp = LEFT;neighbor2[0].index = 8;neighbor2[1].asp = UP;neighbor2[1].index = 6;break;case 8:neighbor2[0].asp = UP;neighbor2[0].index = 8;neighbor2[1].asp = RIGHT;neighbor2[1].index = 8;break;default:break;}}else if(facelet.asp == BACK){switch(facelet.index){case 0:neighbor2[0].asp = LEFT;neighbor2[0].index = 0;neighbor2[1].asp = DOWN;neighbor2[1].index = 0;break;case 2:neighbor2[0].asp = DOWN;neighbor2[0].index = 2;neighbor2[1].asp = RIGHT;neighbor2[1].index = 0;break;case 6:neighbor2[0].asp = UP;neighbor2[0].index = 0;neighbor2[1].asp = LEFT;neighbor2[1].index = 2;break;case 8:neighbor2[0].asp = UP;neighbor2[0].index = 2;neighbor2[1].asp = RIGHT;neighbor2[1].index = 2;break;default:break;}}neighbor2[0].color = m_blockColors[neighbor2[0].asp][neighbor2[0].index];neighbor2[1].color = m_blockColors[neighbor2[1].asp][neighbor2[1].index];
}
//find the edge contains the two given color ,in which first is color
//main face ,the second is color of side face
Edge MagicSquareSolver::GetEdge(FaceColor colorMain, FaceColor colorSide)
{Edge edge;Facelet facelets[4];GetFacelet4(facelets, colorMain);Facelet faceletOther;for(int i = 0; i < 4; i++){faceletOther = GetNeighborEdgeFacelet(facelets[i]);if(faceletOther.color == colorSide){edge.faceletMain = facelets[i];edge.faceletSide = faceletOther;return edge;}}return edge;
}
//rotate cube to cross state,and the cross is built on down face
void MagicSquareSolver::Cross(void)
{//two method to make cross:rule database or search//rules are used here/* for an edge which contained in the cross,there are 24 situations.*but I categorize them into 3 kinds in a clear way which came up my*mind in a sudden.Set front face is the face on which the cross will*be built.colorMain on LEFT/RIGHT/BACK contains 12 situations,while*colorSide on LEFT/RIGHT/BACK contains 12 situations too.*4 situations was repetive.there 4 situations are on the front face.*/int testCount = 0;while(!IsCrossed()){testCount++;if(testCount > 3){//CString filename="bug/Cross.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();//MessageBox("bug emerged in function:Cross,saved as Cross.ml");break;}//record number of faces doneint numDone = 0;//check whether there is a facelet is of same color with center on FRONT face/*Facelet facelet;facelet.asp=FRONT;for (int i=1;i<9;i+=2){if (aspectColors[FRONT][i]==aspectColors[FRONT][4]){facelet.index=i;facelet.color=aspectColors[FRONT][4];break;}}*///it will work still,if this 'if' sentence does not exist.//this is a special situation detection//if (facelet.index>=0){//found//    //turn the facelet to left//    if (facelet.index==1){//      F();//  }else if (facelet.index==7){//        Fr();// }else if (facelet.index==5){//        F2();// }// //get neighbor's color//   Facelet f=GetNeighborEdgeFacelet(facelet);//   //turn corresponding face to position// if(aspectColors[3][4]==f.color){//        b2();// }else if (aspectColors[4][4]==f.color){//     b();//  }else if (aspectColors[5][4]==f.color){//     br();// }// numDone=1;//   zr();//}while(numDone < 4){//find edgesEdge edge = GetEdge(m_blockColors[FRONT][4], m_blockColors[UP][4]);if(edge.faceletMain.asp == LEFT) //main facelet{//move main color to position 5 firstif(edge.faceletMain.index == 7){Lr();Ur();}else if(edge.faceletMain.index == 1){/* numDone estimation is to check whether there is a need to*turn side rotated back .this can reduce the steps needed to*restore the cube.but is hindered optimization of program*/L();Ur();if(numDone != 0){Lr();}}else if(edge.faceletMain.index == 3){L2();Ur();if(numDone != 0){L2();}}else if(edge.faceletMain.index == 5) //5{Ur();}//then//Ur();}else if(edge.faceletMain.asp == RIGHT){//move main color to position 5 firstif(edge.faceletMain.index == 7){R();U();}else if(edge.faceletMain.index == 1){Rr();U();if(numDone == 3){R();}}else if(edge.faceletMain.index == 3){R2();U();if(numDone == 3){R2();}}else if(edge.faceletMain.index == 5) //5{U();}//then//U();}else if(edge.faceletMain.asp == BACK && edge.faceletMain.index == 1){//move main color to position 7 firstB2();U2();}else if(edge.faceletMain.asp == BACK && edge.faceletMain.index == 7){U2();/*else if (edge.faceletMain.index==3){Br();}else if (edge.faceletMain.index==5){B();}*///then//U2();}else if(edge.faceletSide.asp == LEFT) //side facelet{//move side color to position 1 firstif(edge.faceletSide.index == 3){L();Br();if(numDone != 0){Lr();}U2();}else if(edge.faceletSide.index == 5){Lr();Br();if(numDone != 0){L();}U2();}else if(edge.faceletSide.index == 7){if(numDone == 0){F();}else{L2();Br();if(numDone != 0){L2();}U2();}}else if(edge.faceletSide.index == 1){Br();U2();}//then//U2();}else if(edge.faceletSide.asp == RIGHT){//move side color to position 1 firstif(edge.faceletSide.index == 3){Rr();B();if(numDone == 3){R();}U2();}else if(edge.faceletSide.index == 5){R();B();if(numDone == 3){Rr();}U2();}else if(edge.faceletSide.index == 7){if(numDone == 0){Fr();}else{R2();B();if(numDone == 3){R2();}U2();}}else if(edge.faceletSide.index == 1){Br();U2();}//then//U2();}else if(edge.faceletSide.asp == BACK && edge.faceletSide.index == 7){//for the symmetry of code,I did not merge the code belowB();L();Ur();if(numDone != 0){Lr();}}/*else if (edge.faceletSide.index==3){L();Ur();if (numDone!=0){Lr();}}*/else if(edge.faceletSide.asp == BACK && edge.faceletSide.index == 1){B();Rr();U();if(numDone == 3){R();}/*else if (edge.faceletSide.index==5){Rr();U();if (numDone==3){R();}}*/}else if(edge.faceletMain.asp == FRONT){if(edge.faceletMain.index == 1) //special situations on FRONT face{if(numDone == 0){F2();}else{D2();B2();U2();}}//else{//  //in correct position//}}else if(edge.faceletSide.asp == FRONT){if(edge.faceletSide.index == 1){D();Rr();B();U2();if(numDone == 3){R();}}else  //7{U();Lr();Br();U2();if(numDone != 0){L();}}}zr();numDone++;}}
}
//whether the cross has been built
bool MagicSquareSolver::IsCrossed()
{for(int i = 1; i < 8; i += 2){if(m_blockColors[FRONT][4] != m_blockColors[FRONT][i]){return false;}}for(int i = 2; i <= 5; i++){if(m_blockColors[i][4] != m_blockColors[i][7]){return false;}}return true;
}
//whether corner of first layer is ready
bool MagicSquareSolver::IsFirstLayerCornerRestored()
{if(m_blockColors[FRONT][0] == m_blockColors[FRONT][1] &&m_blockColors[FRONT][2] == m_blockColors[FRONT][1] &&m_blockColors[BACK][0] == m_blockColors[BACK][1] &&m_blockColors[BACK][2] == m_blockColors[BACK][1] &&m_blockColors[LEFT][0] == m_blockColors[LEFT][3] &&m_blockColors[LEFT][6] == m_blockColors[LEFT][3] &&m_blockColors[RIGHT][0] == m_blockColors[RIGHT][3] &&m_blockColors[RIGHT][6] == m_blockColors[RIGHT][3]){bool allSame = true;for(int i = 1; i < 9; i += 2){if(m_blockColors[DOWN][i] != m_blockColors[DOWN][4]){allSame = false;break;}}if(allSame){return true;}}return false;
}
//restore corners of first layer
void MagicSquareSolver::Layer1Corner()
{int testCount = 0;while(!IsFirstLayerCornerRestored()){testCount++;if(testCount > 20){//MessageBox("bug emerged in function:RestoreFirstLayerCorner");//CString filename="bug/RestoreFirstLayerCorner.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();return;}bool searchUp = true;//search corners on top which should be on bottomfor(int i = 0; i < 4; i++){bool found = false;//find and adjust the correct corner blockif(m_blockColors[FRONT][6] == m_blockColors[DOWN][4]) //left{if(m_blockColors[UP][6] == m_blockColors[FRONT][4]) // UP FRONT{if(m_blockColors[LEFT][8] == m_blockColors[LEFT][4]) //LEFT LEFT{yr();}else  //LEFT RIGHT{Ur();}}else if(m_blockColors[UP][6] == m_blockColors[LEFT][4]) //UP LEFT{if(m_blockColors[LEFT][8] == m_blockColors[FRONT][4]) //LEFT FRONT{yr();}else  //LEFT BACK{U();y2();}}else if(m_blockColors[LEFT][8] == m_blockColors[FRONT][4]) //LEFT FRONT{Ur();}else if(m_blockColors[LEFT][8] == m_blockColors[LEFT][4]) //LEFT LEFT{U();y2();}else   //left front corner should be on right back{U2();y();}found = true;}else if(m_blockColors[FRONT][8] == m_blockColors[DOWN][4]) //right{if(m_blockColors[UP][8] == m_blockColors[FRONT][4]) // UP FRONT{if(m_blockColors[RIGHT][8] == m_blockColors[RIGHT][4]) //RIGHT RIGHT{//on correct position}else  //RIGHT LEFT{//U();yr();d();}}else if(m_blockColors[UP][8] == m_blockColors[RIGHT][4]) //UP RIGHT{if(m_blockColors[RIGHT][8] == m_blockColors[FRONT][4]) //RIGHT FRONT{//on correct position}else  //RIGHT BACK{//Ur();y();dr();}}else if(m_blockColors[RIGHT][8] == m_blockColors[FRONT][4]) //RIGHT FRONT{d();}else if(m_blockColors[RIGHT][8] == m_blockColors[RIGHT][4]) //RIGHT RIGHT{dr();}else  //right front corner should be on left back{U2();y2();}found = true;}if(found)  //if found ,use formula to restore the corner{//the corner is on FRT cornerif(m_blockColors[FRONT][8] == m_blockColors[DOWN][4]){U();R();Ur();Rr();}else{R();U();Rr();}searchUp = false;break;/* for */}else  //if not found,search next side{y();}}//search top if target not found on sidesbool searchDown = false;if(!searchUp){continue;/* while */}else{bool found = true;//search top and adjustif(m_blockColors[UP][0] == m_blockColors[DOWN][4]){y2();}else if(m_blockColors[UP][2] == m_blockColors[DOWN][4]){y();}else if(m_blockColors[UP][6] == m_blockColors[DOWN][4]){yr();}else if(m_blockColors[UP][8] == m_blockColors[DOWN][4]){//correct}else{searchDown = true;found = false;}if(found){//adjustmentif(m_blockColors[FRONT][8] == m_blockColors[FRONT][4]){d();}else if(m_blockColors[RIGHT][8] == m_blockColors[RIGHT][4]){dr();}else{d2();}//formulaR();U2();Rr();Ur();//then to another situation//R();U();Rr();}}if(searchDown){//search bottom and adjustfor(int i = 0; i < 4; i++){bool found = true;if(m_blockColors[FRONT][0] == m_blockColors[DOWN][4]){yr();}else if(m_blockColors[FRONT][2] == m_blockColors[DOWN][4]){//correct}else{if(m_blockColors[DOWN][6] == m_blockColors[DOWN][4] &&m_blockColors[FRONT][0] != m_blockColors[FRONT][4]){R();U();Rr();}y();found = false;}if(found){//restoreif(m_blockColors[RIGHT][6] == m_blockColors[DOWN][4]){R();U();Rr();U();//then//R();U();Rr();}else if(m_blockColors[FRONT][2] == m_blockColors[DOWN][4]){R();Ur();Rr();//then//U();R();Ur();Rr();}break;}}}}
}
//whether edges on second layer are restored
bool MagicSquareSolver::IsSecondLayerEdgeRestored(void)
{if(m_blockColors[FRONT][4] == m_blockColors[FRONT][3] &&m_blockColors[FRONT][4] == m_blockColors[FRONT][5] &&m_blockColors[BACK][4] == m_blockColors[BACK][3] &&m_blockColors[BACK][4] == m_blockColors[BACK][5] &&m_blockColors[LEFT][4] == m_blockColors[LEFT][1] &&m_blockColors[LEFT][4] == m_blockColors[LEFT][7] &&m_blockColors[RIGHT][4] == m_blockColors[RIGHT][1] &&m_blockColors[RIGHT][4] == m_blockColors[RIGHT][7]){return true;}return false;
}//restore edges of second layer
void MagicSquareSolver::Layer2Edge()
{//ASSERT(IsFirstLayerCornerRestored());int testCount = 0;while(!IsSecondLayerEdgeRestored()){testCount++;if(testCount > 10){//MessageBox("bug emerged in function:RestoreSecondLayerEdge");//CString filename="bug/RestoreSecondLayerEdge.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();return;}bool found = false;for(int i = 0; i < 4; i++){if(m_blockColors[FRONT][7] != m_blockColors[UP][4] &&m_blockColors[UP][7] != m_blockColors[UP][4]) //found{if(m_blockColors[FRONT][7] != m_blockColors[FRONT][4]) //front not matched{//rotate to matchif(m_blockColors[FRONT][7] == m_blockColors[LEFT][4]){d();}else if(m_blockColors[FRONT][7] == m_blockColors[RIGHT][4]){dr();}else if(m_blockColors[FRONT][7] == m_blockColors[BACK][4]){d2();}}yr();//adjustment//formulaif(m_blockColors[UP][5] == m_blockColors[FRONT][4]) //RIGHT FRONT{Rr();Ur();Rr();Ur();Rr();U();R();U();R();}else   //RIGHT BACK{R();U();R();U();R();Ur();Rr();Ur();Rr();}found = true;break;}y();}if(!found)  //search middle layer{for(int i = 0; i < 4; i++){if(m_blockColors[FRONT][5] != m_blockColors[FRONT][4]){Rr();Ur();Rr();Ur();Rr();U();R();U();R();break;}y();}}}
}
//whether F2L is done
bool MagicSquareSolver::IsF2L()
{if(IsFirstLayerCornerRestored() &&IsSecondLayerEdgeRestored()){return true;}return false;
}
//restore First 2 Layer
void MagicSquareSolver::F2L(void)
{//make crossCross();xr();//restore corners of first layerLayer1Corner();//restore edges of second layerLayer2Edge();
}
//==================^_^==================^_^==================^_^==================^_^
//method 1:ferwer formula
//reference:Meissen
//whether top cross is built
bool MagicSquareSolver::IsTopCrossed()
{for(int i = 1; i < 9; i += 2){if(m_blockColors[UP][i] != m_blockColors[UP][4]){return false;}}return true;
}
//built cross on top
void MagicSquareSolver::TopCross()
{//ASSERT(IsF2L());int testCount = 0;while(!IsTopCrossed()){testCount++;if(testCount > 5){//CString filename="bug/BuildTopCross.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();//MessageBox("bug emerged in function:BuildTopCross");return;}if(m_blockColors[UP][3] == m_blockColors[UP][4] &&m_blockColors[UP][5] == m_blockColors[UP][4]) //situation 1a{if(m_blockColors[FRONT][7] != m_blockColors[UP][4]){//adjustmenty2();}F();R();U();Rr();Ur();Fr();}else if(m_blockColors[UP][1] == m_blockColors[UP][4] && //situation 1bm_blockColors[UP][7] == m_blockColors[UP][4]){y();if(m_blockColors[FRONT][7] != m_blockColors[UP][4]){//adjustmenty2();}F();R();U();Rr();Ur();Fr();}else if(m_blockColors[UP][3] == m_blockColors[UP][4]) //situation 2a{bool isTwo = false;if(m_blockColors[UP][7] == m_blockColors[UP][4]){y();isTwo = true;}else if(m_blockColors[UP][1] == m_blockColors[UP][4]){isTwo = true;}if(isTwo){F();U();R();Ur();Rr();Fr();}}else if(m_blockColors[UP][5] == m_blockColors[UP][4]) //situation 2b{bool isTwo = false;if(m_blockColors[UP][7] == m_blockColors[UP][4]){y2();isTwo = true;}else if(m_blockColors[UP][1] == m_blockColors[UP][4]){yr();isTwo = true;}if(isTwo){F();U();R();Ur();Rr();Fr();}}else  //situation 3{for(int i = 0; i < 4; i++){if(m_blockColors[FRONT][7] == m_blockColors[UP][4] &&m_blockColors[RIGHT][5] == m_blockColors[UP][4]){F();U();R();Ur();Rr();Fr();//then//F();R();U();Rr();Ur();Fr();break;}y();}}}
}//
bool MagicSquareSolver::IsTopCrossMatched(void)
{if(m_blockColors[FRONT][7] != m_blockColors[FRONT][4]){return false;}if(m_blockColors[BACK][7] != m_blockColors[BACK][4]){return false;}if(m_blockColors[LEFT][5] != m_blockColors[LEFT][4]){return false;}if(m_blockColors[RIGHT][5] != m_blockColors[RIGHT][4]){return false;}return true;
}
void MagicSquareSolver::MatchTopCross(void)
{//ASSERT(IsTopCrossed());int testCount = 0;while(!IsTopCrossMatched()){testCount++;if(testCount > 1){//MessageBox("bug emerged in function:MatchTopCross,saved in MatchTopCross.ml");//CString filename="bug/MatchTopCross.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();return;}//match edge first,then use formulafor(int jj = 0; jj < 4; jj++){//matchfor(int i = 0; i < 4; i++) //match Back{if(m_blockColors[BACK][4] != m_blockColors[BACK][7]){U();}else{break;}}if(IsTopCrossMatched()){return;}//formulaif(m_blockColors[LEFT][4] == m_blockColors[LEFT][5]) //LEFT match{char* formula = "(RU2R')(U'RU'R')U'";Execute(formula);return;}else if(m_blockColors[FRONT][4] == m_blockColors[FRONT][7]) //RIGHT match{char* formula = "(RU2R')(U'RU'R')y(RU2R')(U'RU'R')U'";Execute(formula);return;}yr();}//MessageBox("special situation not recorded found,saved in file :MatchTopCross-special.ml");//CString filename="MatchTopCross-special.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();}
}
bool MagicSquareSolver::IsTopCornerBack(void)
{int cornerHashDst[4];//hash value of this corner should beint cornerHashSrc[4];//hash value for current corners//start from leftFront corner,counterclockwisecornerHashDst[0] = HashCorner(m_blockColors[UP][4], m_blockColors[LEFT][4], m_blockColors[FRONT][4]);cornerHashDst[1] = HashCorner(m_blockColors[UP][4], m_blockColors[FRONT][4], m_blockColors[RIGHT][4]);cornerHashDst[2] = HashCorner(m_blockColors[UP][4], m_blockColors[RIGHT][4], m_blockColors[BACK][4]);cornerHashDst[3] = HashCorner(m_blockColors[UP][4], m_blockColors[BACK][4], m_blockColors[LEFT][4]);cornerHashSrc[0] = HashCorner(m_blockColors[UP][6], m_blockColors[LEFT][8], m_blockColors[FRONT][6]);cornerHashSrc[1] = HashCorner(m_blockColors[UP][8], m_blockColors[FRONT][8], m_blockColors[RIGHT][8]);cornerHashSrc[2] = HashCorner(m_blockColors[UP][2], m_blockColors[RIGHT][2], m_blockColors[BACK][8]);cornerHashSrc[3] = HashCorner(m_blockColors[UP][0], m_blockColors[BACK][6], m_blockColors[LEFT][2]);for(int i = 0; i < 4; i++){if(cornerHashSrc[i] != cornerHashDst[i]){return false;}}return true;
}
//calculate a hash value for a corner to differ from other corners
//according to its colors.there are various methods
int  MagicSquareSolver::HashCorner(FaceColor c1, FaceColor c2, FaceColor c3)
{return (c1 + 1) * (c2 + 1) * (c3 + 1);
}
void MagicSquareSolver::BackTopCorner(void)
{//ASSERT(IsTopCrossMatched());int testCount = 0;while(!IsTopCornerBack()){testCount++;if(testCount > 3){//CString filename="bug/PutBackTopCorner.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();//MessageBox("bug emerged in function:PutBackTopCorner");return;}int cornerHashDst[4];//hash value of this corner should beint cornerHashSrc[4];//hash value for current corners//start from leftFront corner,counterclockwisecornerHashDst[0] = HashCorner(m_blockColors[UP][4], m_blockColors[LEFT][4], m_blockColors[FRONT][4]);cornerHashDst[1] = HashCorner(m_blockColors[UP][4], m_blockColors[FRONT][4], m_blockColors[RIGHT][4]);cornerHashDst[2] = HashCorner(m_blockColors[UP][4], m_blockColors[RIGHT][4], m_blockColors[BACK][4]);cornerHashDst[3] = HashCorner(m_blockColors[UP][4], m_blockColors[BACK][4], m_blockColors[LEFT][4]);cornerHashSrc[0] = HashCorner(m_blockColors[UP][6], m_blockColors[LEFT][8], m_blockColors[FRONT][6]);cornerHashSrc[1] = HashCorner(m_blockColors[UP][8], m_blockColors[FRONT][8], m_blockColors[RIGHT][8]);cornerHashSrc[2] = HashCorner(m_blockColors[UP][2], m_blockColors[RIGHT][2], m_blockColors[BACK][8]);cornerHashSrc[3] = HashCorner(m_blockColors[UP][0], m_blockColors[BACK][6], m_blockColors[LEFT][2]);//analysis//find backed corner firstbool found = false;for(int i = 0; i < 4; i++){if(cornerHashDst[i] == cornerHashSrc[i]){found = true;//analyze relative positions of the other three cornersRotateDir direction;if(cornerHashDst[(i + 1) % 4] == cornerHashSrc[(i + 2) % 4]) //clockwise{direction = CLOCKWISE;}else if(cornerHashDst[(i + 2) % 4] == cornerHashSrc[(i + 1) % 4]) //clockwise{direction = COUNTERCLOCKWISE;}else{
//                  MessageBox("something wrong with PutBackTopCorner");return;}if(direction == COUNTERCLOCKWISE){//adjust direction of the cubeif(i == 3){yr();}else if(i == 2){y2();}else if(i == 1){y();}char* cmd = "RU'L'UR'U'LU";Execute(cmd);}else{if(i == 3){y2();}else if(i == 2){y();}else if(i == 1){yr();}char* cmd = "L'URU'LUR'U'";Execute(cmd);}}}if(!found)  //none of the four corners is in right position{char* cmd = "RU'L'UR'U'LUy";Execute(cmd);}}
}
bool MagicSquareSolver::IsTopCornerRestored(void)
{if(m_blockColors[UP][0] != m_blockColors[UP][4] ||m_blockColors[UP][2] != m_blockColors[UP][4] ||m_blockColors[UP][6] != m_blockColors[UP][4] ||m_blockColors[UP][8] != m_blockColors[UP][4] ||m_blockColors[LEFT][2] != m_blockColors[LEFT][4] ||m_blockColors[LEFT][8] != m_blockColors[LEFT][4] ||m_blockColors[RIGHT][2] != m_blockColors[RIGHT][4] ||m_blockColors[RIGHT][8] != m_blockColors[RIGHT][4] ||m_blockColors[FRONT][6] != m_blockColors[FRONT][4] ||m_blockColors[FRONT][8] != m_blockColors[FRONT][4] ||m_blockColors[BACK][6] != m_blockColors[BACK][4] ||m_blockColors[BACK][8] != m_blockColors[BACK][4]){return false;}return true;
}
void MagicSquareSolver::RestoreTopCorner(void)
{//TOP FRONT:RF'R'F twice//TOP RIGHT:F'RFR' twiceASSERT(IsTopCornerBack());if(!IsTopCornerRestored()){//find a start cornerfor(int i = 0; i < 4; i++){if(m_blockColors[UP][8] != m_blockColors[UP][4]){break;}y();}int testCount = 0;while(!IsTopCornerRestored()){testCount++;if(testCount > 12){//MessageBox("bug merged in function:RestoreTopCorner");//CString filename="bug/RestoreTopCorner.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();return;}if(m_blockColors[UP][8] != m_blockColors[UP][4]){if(m_blockColors[FRONT][8] == m_blockColors[UP][4]){char* cmd = "RF'R'FRF'R'F";Execute(cmd);}else{char* cmd = "F'RFR'F'RFR'";Execute(cmd);}}else{U();}}//last step to restoreif(m_blockColors[FRONT][7] != m_blockColors[FRONT][4]){if(m_blockColors[BACK][7] != m_blockColors[FRONT][4]){U2();}else if(m_blockColors[LEFT][5] != m_blockColors[FRONT][4]){Ur();}else if(m_blockColors[RIGHT][5] != m_blockColors[FRONT][4]){U();}}else{//bingo}}
}void MagicSquareSolver::MethodFewerFormula()
{F2L();TopCross();MatchTopCross();BackTopCorner();RestoreTopCorner();
}
//==================^_^==================^_^==================^_^==================^_^
//Method 2:cfop,not finished
//hash function for oll
void MagicSquareSolver::HashOLL(char* hashstr)
{//start from left side,then front,right,back//length of the hash string is 12,for 12 facelets around top facememset(hashstr, '0', 12);if(m_blockColors[LEFT][2] == m_blockColors[UP][4]){hashstr[0] = '1';}if(m_blockColors[LEFT][5] == m_blockColors[UP][4]){hashstr[1] = '1';}if(m_blockColors[LEFT][8] == m_blockColors[UP][4]){hashstr[2] = '1';}if(m_blockColors[FRONT][6] == m_blockColors[UP][4]){hashstr[3] = '1';}if(m_blockColors[FRONT][7] == m_blockColors[UP][4]){hashstr[4] = '1';}if(m_blockColors[FRONT][8] == m_blockColors[UP][4]){hashstr[5] = '1';}if(m_blockColors[RIGHT][8] == m_blockColors[UP][4]){hashstr[6] = '1';}if(m_blockColors[RIGHT][5] == m_blockColors[UP][4]){hashstr[7] = '1';}if(m_blockColors[RIGHT][2] == m_blockColors[UP][4]){hashstr[8] = '1';}if(m_blockColors[BACK][8] == m_blockColors[UP][4]){hashstr[9] = '1';}if(m_blockColors[BACK][7] == m_blockColors[UP][4]){hashstr[10] = '1';}if(m_blockColors[BACK][6] == m_blockColors[UP][4]){hashstr[11] = '1';}
}
//whether top face is restored
bool MagicSquareSolver::IsTopFaceRestored(void)
{for(int i = 0; i < 9; i++){if(m_blockColors[UP][i] != m_blockColors[UP][4]){return false;}}return true;
}
//Orientation the Last Layer
void MagicSquareSolver::OLL(void)
{//BuildTopCross();//I choose standard OLL method to restore top face,there are//too many situations.A possible way is to hash them.This will//highly reduce program complexity .//length of the string is 12,for the sack of rotation,4 string//is used,in yr rotation order,i.e. counterclockwise.char hashstr[4][13] = {0};HashOLL(hashstr[0]);for(int i = 1; i < 4; i++){int t = i * 3;memcpy(hashstr[i], hashstr[0] + 12 - t, t);memcpy(hashstr[i] + t, hashstr[0], 12 - t);}//hash of every situations//if BuildTopCross function is used first,only first 7 ollHash//strings are used.the second part are corresponding operationsstatic const char* ollHash[57][2] ={/* 01 */{"100100100000", "(RU'2)R'U'(RU'R')"},/* 02 */{"000001001001", "RUR'URU2R'"}, //U'R'U2RUR'UR/* 03 */{"101000101000", "(RUR'U)(RU'R'U)(RU2R')"}, // (RU'2)(R'U'RUR'U')(RU'R')/* 04 */{"101001000100", "RU'2(R'2U')(R2U')(R'2U'2R"},/* 05 */{"000100000001", "(rUR'U')(r'FRF')"},/* 06 */{"000101000000", "(RUR'URU'2R')U(RU'2R'U'RU'R'"},/* 07 */{"100001000000", "F'(rUR'U')(r'FR)"},/* 08 */{"111010111010", "(RU'2)(R'2FRF')U2(R'FRF')"},/* 09 */{"111011010110", "(FRUR'U'F')(fRUR'U'f')"},/* 10 */{"011010011011", "(f R U R' U' f')U' (F R U R' U' F')"},/* 11 */{"110110110010", "(fRUR'U'f')y(FRUR'U'F')"},/* 12 */{"011010010110", "(RUR'U)(R'FRF')U2(R'FRF')"},/* 13 */{"010010010111", "F(RUR'U)y'(R'U2)(R'FRF')"},/* 14 */{"011010110010", "r'(RURUR'U')r(R'2FRF')"},/* 15 */{"010010010010", "r'(RURUR'U')r2(R'2UR U')"},/* 16 */{"101011000110", "f (R U R' U')2 f'"},/* 17 */{"010100111001", "(R'U'RU'R'U)y'(R' URB)"},/* 18 */{"101010101010", "(r U r')(U R U' R' ) 2 (r U' r')"},/* 19 */{"111000111000", "(RU'U')(R'2U')(R U'R' U2)(F R F')"},/* 20 */{"000011001011", "(rU'r'U')(rU r')y' (R' U R)"},/* 21 */{"100110000110", "(R'FRUR' F'R) y'(R U' R')"},/* 22 */{"001010001011", "(r' U' r)(R' U' R U)(r' U r)"},/* 23 */{"100110100010", "(rUr')(RUR'U')(rU' r')"},/* 24 */{"000110000011", "(RUR'U')(R'F R F')"},/* 25 */{"101010000010", "F(R U R' U') F'"},/* 26 */{"000010000010", "(RUR'U' r)(R'U R U') r'"},/* 27 */{"000010010000", "(rUR'U')(r' RU)(R U' R')"},/* 28 */{"000010100011", "(r U' r' U' r) y (R U R' f')"},/* 29 */{"001010000110", "(R'F R U R' U') (F' U R)"},/* 30 */{"001010100010", "(R'U' R U) y (r U R' U') r' R"},/* 31 */{"010000111000", "(R'U')(R' F R F') (U R)"},/* 32 */{"010110000001", "(R'U' F)(U R U' R' F' R)"},/* 33 */{"010100000011", "(R U B'U')(R' U R B R')"},/* 34 */{"000000111010", "x'U'F'R'FR U"},/* 35 */{"111000000010", "f(RUR'U')f'"},/* 36 */{"000110011000", "F(RU'R'U')(R U R' F')"},/* 37 */{"010100001010", "R U'2(R'2FR F')(R U'2 R')"},/* 38 */{"011000001011", "(r'U2)(R UR' U) r"},/* 39 */{"110110100000", "(rU2)(R'U'R U') r'"},/* 40 */{"000100110110", "r'U'R U'R'U2 r"},/* 41 */{"000011011001", "rUR'UR U'2r'"},/* 42 */{"010001001011", "r'(R2U)(R'U R) U'2 (R' U R')"},/* 43 */{"010110100100", "r(R'2U')(RU'R') U2 (R U' R) r'"},/* 44 */{"100110010100", "(R'U'R) y'x'(R U' R' F)(R U R')"},/* 45 */{"001001010011", "(RUR'U)(R'FR F')(R U'2 R')"},/* 46 */{"000111010101", "(r U2)(R' U' R U R' U')(R U' r')"},/* 47 */{"101001010110", "B'(R'U'RU)2B"},/* 48 */{"000101010111", "r' U2(R U R' U')(R U R' U) r"},/* 49 */{"101011010100", "F(RU R'U')2 F'"},/* 50 */{"000110111001", "R'FR2 B' R'2 F' R2 B R'"},/* 51 */{"000100111011", "RB'R'2 F R2 B R'2 F' R"},/* 52 */{"011000100010", "(R2U R' B')(R U' R'2 U)(R B R')"},/* 53 */{"110010001000", "(RUR' U')(R U' R' F') U' (F R U R')"},/* 54 */{"010010000101", "(R' U R U'2 R' U') y (L' U L U F)"},/* 55 */{"010101000010", "(RU' R' U2 R U) y (R U' R' U' F')"},/* 56 */{"000010110001", "(RU R' U)(R U' R' U')(R' F R F')"},/* 57 */{"000100011010", "(R' U' R U')(R' U R U)(R B' R' B)"}};char buf[1024] = "";for(int i = 0; i < 57; i++){for(int j = 0; j < 4; j++){if(strcmp(hashstr[j], ollHash[i][0]) == 0){if(j == 1){//yr();strcat(buf,"y'");}else if(j == 2){//y2();strcat(buf,"yy");}else if(j == 3){//y();strcat(buf,"y");}Execute(ollHash[i][1]);//strcat(buf,ollHash[i][1]);if(!IsTopFaceRestored()){char errorInfo[100];sprintf_s(errorInfo, 100, "something wrong with ollHash:%s\nnumber%d", ollHash[i][1], i);}return;}}}//MessageBox("special situation not recorded found,saved in file :OLLSpecialFound.ml");//CString filename="OLLSpecialFound.ml";//CFile fileout(filename.GetBuffer());//fileout.Write(aspectColors,sizeof(aspectColors));//fileout.Close();
}
//hash function for PLL
void MagicSquareSolver::HashPLL(char* hashstr)
{//not finished
}
//Permutation the Last Layer
void MagicSquareSolver::PLL(void)
{//ASSERT(IsTopFaceRestored());char hashstr[4][13] = {0};HashPLL(hashstr[0]);for(int i = 1; i < 4; i++){int t = i * 3;memcpy(hashstr[i], hashstr[0] + 12 - t, t);memcpy(hashstr[i] + t, hashstr[0], 12 - t);}//hash string here is different with oll hash,because one hash//maybe correspond two situationsstatic const char* pllHash[18][3] = //0,1,14 are special{/* 0102 */{"101101101111", "(R2 U)(R U R' U')(R' U')(R' U R')", "(R U' R)(U R U R)(U' R' U' R2)"},/* 0304 */{"110010010011", "(l U' R)D2(R' U R)D2 R2", "x' R2 D2(R' U' R)D2(R' U R')"},/* 05 */{"101000000110", "(R'2 u' R U' R)(U R' u)(R2 f R' f')", ""},/* 06 */{"101000110000", "(R U R')y'(R2' u' R U')(R' U R' u R2)", ""},/* 07 */{"101011000000", "(R2 u)(R' U R' U')(R u') (R2' F' U F)", ""},/* 08 */{"101000011000", "(R' d' F) (R2 u) (R' U) (R U' R u' R'2)", ""},/* 09 */{"111100000011", "(R U R' F')(R U R' U')(R' F R2 U' R' U')", ""},/* 10 */{"110000001111", "z (U' R D') (R2 U R' U' R2 U) z' (R U')", ""},/* 11 */{"011101100010", "(R' U2)(R U2')(R' F)(R U R' U')(R' F' R2 U')", ""},/* 12 */{"110010001101", "(R U'2 R' U2) (R B' R' U') (R U R B R'2 U) ", ""}, //  x'(R2 u' R' u)R2 x' y'(R' U R' U')R2/* 13 */{"101110000011", "(R U R' U')(R' F)(R2 U' R' U')(R U R' F')", ""},/* 14 */{"000110011000", "F(R U' R' U')(R U R' F')(R U R' U')(R' F R F')", ""},/* 15 */{"110001110001", "z (U' R D') (R2 U R' U')z'( R U R')z (R2 U R')z' (R U')", ""},/* 16 */{"011100011100", "L U' R U'2 r' F r R' U' R U'2 r' F R' F", ""},/* 1721 */{"101101101101", "(U R' U')(R U' R)(U R U')(R' U R U)(R2 U')(R' U)", "M'2 U' M'2 U2 M'2 U' M'2"},/* 18 */{"011110001100", "(R' U R' U') y x2 (R' U R' U' R2) y x (R' U' R U R)", ""},/* 19 */{"010010010010", "L x' (R U R')(D R U')(r' R' F) r D' r' F' ", ""}, //(R' U R' U')B' D B' D' B2 R' (B' R B R)/* 20 */{"111100010001", "U'(R' U R U') R'2 F' z R' F R D z' x (U R' U' R2)", ""},};
}
//I use CFOP method to restore the cube
void MagicSquareSolver::CFOP(void)
{F2L();OLL();PLL();
}void MagicSquareSolver::SaveFromFile()
{/* CFileDialog fileDlg(false,NULL,NULL,4|2,"MagicCube Layout Files(*.ml)|*.ml||");if (fileDlg.DoModal()==IDOK){CString filename=fileDlg.GetPathName();CString ext=fileDlg.GetFileExt();if (ext!="ml"){filename.Append(".ml");}CFile fileout(filename.GetBuffer());fileout.Write(aspectColors,sizeof(aspectColors));fileout.Close();}*/
}void MagicSquareSolver::LoadFromFile()
{//CFileDialog fileDlg(true,NULL,NULL,4|2,"MagicCube Layout Files(*.ml)|*.ml||");//if (fileDlg.DoModal()==IDOK){//  CString filename=fileDlg.GetPathName();//  CFile filein(filename.GetBuffer(),CFile::modeRead);//   filein.Read(aspectColors,sizeof(aspectColors));//   filein.Close();//}
}void MagicSquareSolver::Execute(const char* cmd)
{//space,'(' and ')' can be filtered //"'2" can be replaced by 2while(*cmd){switch(*cmd){case ' ':case '(':case ')':break;case 'F':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{F2();cmd++;}else{Fr();}cmd++;}else if(*(cmd + 1) == '2'){F2();cmd++;}else{F();}break;case 'B':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{B2();cmd++;}else{Br();}cmd++;}else if(*(cmd + 1) == '2'){B2();cmd++;}else{B();}break;case 'L':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{L2();cmd++;}else{Lr();}cmd++;}else if(*(cmd + 1) == '2'){L2();cmd++;}else{L();}break;case 'R':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{R2();cmd++;}else{Rr();}cmd++;}else if(*(cmd + 1) == '2'){R2();cmd++;}else{R();}break;case 'U':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{U2();cmd++;}else{Ur();}cmd++;}else if(*(cmd + 1) == '2'){U2();cmd++;}else{U();}break;case 'D':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{D2();cmd++;}else{Dr();}cmd++;}else if(*(cmd + 1) == '2'){D2();cmd++;}else{D();}break;case 'x':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{x2();cmd++;}else{xr();}cmd++;}else if(*(cmd + 1) == '2'){x2();cmd++;}else{x();}break;case 'y':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{y2();cmd++;}else{yr();}cmd++;}else if(*(cmd + 1) == '2'){y2();cmd++;}else{y();}break;case 'z':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{z2();cmd++;}else{zr();}cmd++;}else if(*(cmd + 1) == '2'){z2();cmd++;}else{z();}break;case 'f':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{f2();cmd++;}else{fr();}cmd++;}else if(*(cmd + 1) == '2'){f2();cmd++;}else{f();}break;case 'b':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{b2();cmd++;}else{br();}cmd++;}else if(*(cmd + 1) == '2'){b2();cmd++;}else{b();}break;case 'l':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{l2();cmd++;}else{lr();}cmd++;}else if(*(cmd + 1) == '2'){l2();cmd++;}else{l();}break;case 'r':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{r2();cmd++;}else{rr();}cmd++;}else if(*(cmd + 1) == '2'){r2();cmd++;}else{r();}break;case 'u':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{u2();cmd++;}else{ur();}cmd++;}else if(*(cmd + 1) == '2'){u2();cmd++;}else{u();}break;case 'd':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{d2();cmd++;}else{dr();}cmd++;}else if(*(cmd + 1) == '2'){d2();cmd++;}else{d();}break;case 'E':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{E2();cmd++;}else{Er();}cmd++;}else if(*(cmd + 1) == '2'){E2();cmd++;}else{E();}break;case 'M':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{M2();cmd++;}else{Mr();}cmd++;}else if(*(cmd + 1) == '2'){M2();cmd++;}else{M();}break;case 'S':if(*(cmd + 1) == '\''){if(*(cmd + 2) == '2') //E'2==E2{S2();cmd++;}else{Sr();}cmd++;}else if(*(cmd + 1) == '2'){S2();cmd++;}else{S();}break;default:break;}cmd++;}
}void MagicSquareSolver::b2()
{b();b();
}void MagicSquareSolver::br()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'b';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateZMiddleCW();rotateZBackCW();
}void MagicSquareSolver::b()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'b';m_history[m_historyNum] = '\0';}rotateZMiddleACW();rotateZBackACW();
}void MagicSquareSolver::l2()
{l();l();
}void MagicSquareSolver::lr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'l';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateXMiddleCW();rotateXLeftCW();
}void MagicSquareSolver::l()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'l';m_history[m_historyNum] = '\0';}rotateXMiddleACW();rotateXLeftACW();
}void MagicSquareSolver::d2()
{d();d();
}void MagicSquareSolver::dr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'd';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}//(this->*RotateFunTable[Y][NEGATIVE][CLOCKWISE])(3);rotateYDownCW();rotateYMiddleCW();
}void MagicSquareSolver::d()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'd';m_history[m_historyNum] = '\0';}rotateYMiddleACW();rotateYDownACW();
}void MagicSquareSolver::f2()
{f();f();
}void MagicSquareSolver::fr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'f';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateZFrontACW();rotateZMiddleACW();
}void MagicSquareSolver::f()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'f';m_history[m_historyNum] = '\0';}rotateZFrontCW();rotateZMiddleCW();
}void MagicSquareSolver::r2()
{r();r();
}void MagicSquareSolver::rr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'r';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateXRightACW();rotateXMiddleACW();
}void MagicSquareSolver::r()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'r';m_history[m_historyNum] = '\0';}rotateXRightCW();rotateXMiddleCW();
}void MagicSquareSolver::u2()
{u();u();
}void MagicSquareSolver::ur()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'u';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateYUpACW();rotateYMiddleACW();
}void MagicSquareSolver::u()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'u';m_history[m_historyNum] = '\0';}rotateYUpCW();rotateYMiddleCW();
}void MagicSquareSolver::z2()
{z();z();
}void MagicSquareSolver::zr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'z';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateZBackACW();rotateZMiddleACW();rotateZFrontACW();
}void MagicSquareSolver::z()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'z';m_history[m_historyNum] = '\0';}rotateZBackCW();rotateZMiddleCW();rotateZFrontCW();
}void MagicSquareSolver::y2()
{y();y();
}void MagicSquareSolver::yr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'y';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateYDownACW();rotateYMiddleACW();rotateYUpACW();
}void MagicSquareSolver::y()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'y';m_history[m_historyNum] = '\0';}rotateYDownCW();rotateYMiddleCW();rotateYUpCW();
}void MagicSquareSolver::x2()
{x();x();
}void MagicSquareSolver::xr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'x';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateXLeftACW();rotateXMiddleACW();rotateXRightACW();
}void MagicSquareSolver::x()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'x';m_history[m_historyNum] = '\0';}rotateXLeftCW();rotateXMiddleCW();rotateXRightCW();
}void MagicSquareSolver::D2()
{D();D();
}void MagicSquareSolver::U2()
{U();U();
}void MagicSquareSolver::L2()
{L();L();
}void MagicSquareSolver::R2()
{R();R();
}void MagicSquareSolver::B2()
{B();B();
}void MagicSquareSolver::F2()
{F();F();
}void MagicSquareSolver::S2()
{S();S();
}void MagicSquareSolver::Sr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'S';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateZMiddleCW();
}void MagicSquareSolver::S()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'S';m_history[m_historyNum] = '\0';}rotateZMiddleCW();
}void MagicSquareSolver::M2()
{E();E();
}void MagicSquareSolver::Mr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'M';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateXMiddleACW();
}void MagicSquareSolver::M()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'M';m_history[m_historyNum] = '\0';}rotateXMiddleCW();
}void MagicSquareSolver::E2()
{E();E();
}void MagicSquareSolver::Er()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'E';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateYMiddleACW();
}void MagicSquareSolver::E()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'E';m_history[m_historyNum] = '\0';}rotateYMiddleCW();
}void MagicSquareSolver::Dr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'D';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateYDownCW();
}void MagicSquareSolver::D()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'D';m_history[m_historyNum] = '\0';}rotateYDownACW();
}void MagicSquareSolver::Ur()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'U';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateYUpACW();
}void MagicSquareSolver::U()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'U';m_history[m_historyNum] = '\0';}rotateYUpCW();
}void MagicSquareSolver::Lr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'L';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateXLeftCW();
}void MagicSquareSolver::L()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'L';m_history[m_historyNum] = '\0';}rotateXLeftACW();
}void MagicSquareSolver::Rr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'R';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateXRightACW();
}void MagicSquareSolver::R()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'R';m_history[m_historyNum] = '\0';}rotateXRightCW();
}void MagicSquareSolver::Br()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'B';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateZBackCW();
}void MagicSquareSolver::B()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'B';m_history[m_historyNum] = '\0';}rotateZBackACW();
}void MagicSquareSolver::Fr()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'F';m_history[m_historyNum++] = '\'';m_history[m_historyNum] = '\0';}rotateZFrontACW();
}void MagicSquareSolver::F()
{if (m_historyNum<1024-8){m_history[m_historyNum++] = 'F';m_history[m_historyNum] = '\0';}rotateZFrontCW();
}//==================^_^==================^_^==================^_^==================^_^
MagicSquarePlayer::RotateFun MagicSquarePlayer::RotateFunTable[3][3][2] =
{//x from negative to positive,i.e. from left to right{   {&MagicSquarePlayer::rotateXLeftCW  , &MagicSquarePlayer::rotateXLeftACW},{&MagicSquarePlayer::rotateXMiddleCW, &MagicSquarePlayer::rotateXMiddleACW},{&MagicSquarePlayer::rotateXRightCW , &MagicSquarePlayer::rotateXRightACW}},//y{   {&MagicSquarePlayer::rotateYDownCW  , &MagicSquarePlayer::rotateYDownACW},{&MagicSquarePlayer::rotateYMiddleCW, &MagicSquarePlayer::rotateYMiddleACW},{&MagicSquarePlayer::rotateYUpCW    , &MagicSquarePlayer::rotateYUpACW}},//z{   {&MagicSquarePlayer::rotateZBackCW  , &MagicSquarePlayer::rotateZBackACW},{&MagicSquarePlayer::rotateZMiddleCW, &MagicSquarePlayer::rotateZMiddleACW},{&MagicSquarePlayer::rotateZFrontCW , &MagicSquarePlayer::rotateZFrontACW}},
};
MagicSquarePlayer::MagicSquarePlayer()
:m_movieCube3(NULL)
,m_movieOrnament(NULL)
,m_rotAnimAng(0)
,RotSpeed(HALFPI)
{memset(m_executeStr,0,sizeof(m_executeStr));m_blockFrames = new Frame[BlockNum];m_ornamentFrames = new Frame[OrnamentNum];float len = BlockSize * 0.707106f;//vertexes for every aspect//frontblockVertexes[FRONT][0][0] = vec2I();blockVertexes[FRONT][0][1].x = 0;blockVertexes[FRONT][0][1].y = - BlockSize;blockVertexes[FRONT][0][2].x = BlockSize;blockVertexes[FRONT][0][2].y = - BlockSize;blockVertexes[FRONT][0][3].x = BlockSize;blockVertexes[FRONT][0][3].y = 0;for(int i = 1; i <= 2; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[FRONT][i][ind].x = blockVertexes[FRONT][i - 1][ind].x + BlockSize;blockVertexes[FRONT][i][ind].y = blockVertexes[FRONT][0][ind].y;}}for(int i = 3; i <= 8; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[FRONT][i][ind].x = blockVertexes[FRONT][i - 3][ind].x;blockVertexes[FRONT][i][ind].y = blockVertexes[FRONT][i - 3][ind].y - BlockSize;}}//backvec2I v(int(BlockSize * 3 + int(len * 3)), int(- int(len * 3)));blockVertexes[BACK][2][0] = v;blockVertexes[BACK][2][1].x = v.x;blockVertexes[BACK][2][1].y = v.y - BlockSize;blockVertexes[BACK][2][2].x = v.x + BlockSize;blockVertexes[BACK][2][2].y = v.y - BlockSize;blockVertexes[BACK][2][3].x = v.x + BlockSize;blockVertexes[BACK][2][3].y = v.y;for(int i = 1; i >= 0; i--){for(int ind = 0; ind < 4; ind++){blockVertexes[BACK][i][ind].x = blockVertexes[BACK][i + 1][ind].x + BlockSize;blockVertexes[BACK][i][ind].y = blockVertexes[BACK][2][ind].y;}}for(int i = 3; i <= 8; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[BACK][i][ind].x = blockVertexes[BACK][i - 3][ind].x;blockVertexes[BACK][i][ind].y = blockVertexes[BACK][i - 3][ind].y - BlockSize;}}//leftfor(int ind = 0; ind < 4; ind++){blockVertexes[LEFT][0][ind].x = blockVertexes[FRONT][0][ind].x - BlockSize * 3;blockVertexes[LEFT][0][ind].y = blockVertexes[FRONT][0][ind].y;}for(int i = 1; i <= 2; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[LEFT][i][ind].y = blockVertexes[LEFT][i - 1][ind].y - BlockSize;blockVertexes[LEFT][i][ind].x = blockVertexes[LEFT][0][ind].x;}}for(int i = 3; i <= 8; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[LEFT][i][ind].x = blockVertexes[LEFT][i - 3][ind].x + BlockSize;blockVertexes[LEFT][i][ind].y = blockVertexes[LEFT][i - 3][ind].y;}}//rightblockVertexes[RIGHT][0][3] = v;blockVertexes[RIGHT][0][0].x = v.x - int(len);blockVertexes[RIGHT][0][0].y = v.y + int(len);blockVertexes[RIGHT][0][1].x = blockVertexes[RIGHT][0][0].x;blockVertexes[RIGHT][0][1].y = blockVertexes[RIGHT][0][0].y - BlockSize;blockVertexes[RIGHT][0][2].x = blockVertexes[RIGHT][0][3].x;blockVertexes[RIGHT][0][2].y = blockVertexes[RIGHT][0][3].y - BlockSize;for(int i = 1; i <= 2; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[RIGHT][i][ind].y = blockVertexes[RIGHT][i - 1][ind].y - BlockSize;blockVertexes[RIGHT][i][ind].x = blockVertexes[RIGHT][0][ind].x;}}for(int i = 3; i <= 8; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[RIGHT][i][ind].x = blockVertexes[RIGHT][i - 3][ind].x - int(len);blockVertexes[RIGHT][i][ind].y = blockVertexes[RIGHT][i - 3][ind].y + int(len);}}//upv.x = int(len * 3);v.y = - int(len * 3) - BlockSize * 3;blockVertexes[UP][0][0].x = v.x - int(len);blockVertexes[UP][0][0].y = v.y + int(len);blockVertexes[UP][0][1] = v;blockVertexes[UP][0][2].x = v.x + BlockSize;blockVertexes[UP][0][2].y = v.y;blockVertexes[UP][0][3].x = blockVertexes[UP][0][0].x + BlockSize;blockVertexes[UP][0][3].y = blockVertexes[UP][0][0].y;for(int i = 1; i <= 2; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[UP][i][ind].x = blockVertexes[UP][i - 1][ind].x + BlockSize;blockVertexes[UP][i][ind].y = blockVertexes[UP][0][ind].y;}}for(int i = 3; i <= 8; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[UP][i][ind].x = blockVertexes[UP][i - 3][ind].x - int(len);blockVertexes[UP][i][ind].y = blockVertexes[UP][i - 3][ind].y + int(len);}}//downfor(int i = 0; i < 9; i++){for(int ind = 0; ind < 4; ind++){blockVertexes[DOWN][i][ind].x = blockVertexes[FRONT][i][ind].x;blockVertexes[DOWN][i][ind].y = blockVertexes[FRONT][i][ind].y + BlockSize * 3;}}aspectVertexes[0][0] = blockVertexes[0][0][0];aspectVertexes[0][1] = blockVertexes[0][6][1];aspectVertexes[0][2] = blockVertexes[0][8][2];aspectVertexes[0][3] = blockVertexes[0][2][3];aspectVertexes[1][0] = blockVertexes[1][2][0];aspectVertexes[1][1] = blockVertexes[1][8][1];aspectVertexes[1][2] = blockVertexes[1][6][2];aspectVertexes[1][3] = blockVertexes[1][0][3];aspectVertexes[2][0] = blockVertexes[2][0][0];aspectVertexes[2][1] = blockVertexes[2][2][1];aspectVertexes[2][2] = blockVertexes[2][8][2];aspectVertexes[2][3] = blockVertexes[2][6][3];aspectVertexes[3][0] = blockVertexes[3][6][0];aspectVertexes[3][1] = blockVertexes[3][8][1];aspectVertexes[3][2] = blockVertexes[3][2][2];aspectVertexes[3][3] = blockVertexes[3][0][3];aspectVertexes[4][0] = blockVertexes[4][6][0];aspectVertexes[4][1] = blockVertexes[4][0][1];aspectVertexes[4][2] = blockVertexes[4][2][2];aspectVertexes[4][3] = blockVertexes[4][8][3];aspectVertexes[5][0] = blockVertexes[5][0][0];aspectVertexes[5][1] = blockVertexes[5][6][1];aspectVertexes[5][2] = blockVertexes[5][8][2];aspectVertexes[5][3] = blockVertexes[5][2][3];
}MagicSquarePlayer::~MagicSquarePlayer()
{SafeDeleteArray(m_blockFrames);SafeDeleteArray(m_ornamentFrames);
}bool MagicSquarePlayer::Start()
{MiniPlayer::Start();G_TextureMgr->AddTexture(m_texture,"data/minigame/magicsquare/cube.png");m_colorTexRects[BLUE  ] = RectF(0.25f,0.0f,0.25f,0.5f);m_colorTexRects[GREEN ] = RectF(0.25f,0.5f,0.25f,0.5f);m_colorTexRects[RED   ] = RectF(0.0f,0.0f,0.25f,0.5f);m_colorTexRects[ORANGE] = RectF(0.0f,0.5f,0.25f,0.5f);m_colorTexRects[WHITE ] = RectF(0.5f,0.5f,0.25f,0.5f);m_colorTexRects[YELLOW] = RectF(0.5f,0.0f,0.25f,0.5f);m_colorTexRects[GRAY  ] = RectF(0.75f,0.5f,0.25f,0.5f);//m_tileNum = vec3I(2, 3, 4);//加载魔方Frame frame;if (m_movieCube3 == NULL){LoadConfig loader(LoadConfig::GenDonotReShrinkBound, true, true);m_movieCube3 = new RendSys::MovieClip;m_movieCube3->LoadFromFile("data/minigame/magicsquare/cube.movie", &loader);frame.SetPos(m_startPos);m_movieCube3->SetProgramFrame(&frame);m_movieCube3->Advance();}if (m_movieCube3->IsLoadComplete() == false){return false;}//查找blockchar buf[512];for (int i=0;i<9;i++){sprintf(buf,"block0%d",i+1);m_movieBlocks[i] = m_movieCube3->GetMovieClip(buf);}for (int i=0;i<8;i++){sprintf(buf,"block1%d",i+1);m_movieBlocks[9+i] = m_movieCube3->GetMovieClip(buf);}for (int i=0;i<9;i++){sprintf(buf,"block2%d",i+1);m_movieBlocks[17+i] = m_movieCube3->GetMovieClip(buf);}//清除关键帧 设置位置MC_Frame* frameMovie;frame.m_matrix.Identity();for (int i=0;i<BlockNum;i++){frameMovie = dynamic_cast<MC_Frame*>(m_movieBlocks[i]);frame.SetPos(frameMovie->GetFrameLine()->m_keyFrames[0].m_pos);frameMovie->ZeroFrames();frameMovie->SetProgramFrame(&frame);}//高亮moviem_movieSelect = m_movieCube3->GetMovieClip("select1");if (m_movieSelect){m_movieSelect->SetPickable(false);}//装饰movieif (m_movieOrnament == NULL){LoadConfig loader(LoadConfig::DonotGenAABBTree, true, true);m_movieOrnament = new RendSys::MovieClip;m_movieOrnament->LoadFromFile("data/minigame/magicsquare/ornament.movie", &loader);frame.m_matrix.Identity();frame.SetPos(m_startPos);m_movieOrnament->SetProgramFrame(&frame);m_movieOrnament->Advance();}m_ornamentBlockNum = 0;if (m_movieOrnament->IsLoadComplete()){//清除关键帧 设置位置MovieThrough thtorgh(m_movieOrnament);MovieClip* subMovie = thtorgh.GetFirst();while (subMovie && m_ornamentBlockNum<OrnamentNum){m_movieOrnamentBlocks[m_ornamentBlockNum++] = subMovie;frameMovie = dynamic_cast<MC_Frame*>(subMovie);if (frameMovie){frame.SetPos(frameMovie->GetFrameLine()->m_keyFrames[0].m_pos);frameMovie->ZeroFrames();frameMovie->SetProgramFrame(&frame);}RendSys::MC_Particle* particleMovie = dynamic_cast<MC_Particle*>(subMovie);if (particleMovie){frame.SetPos(particleMovie->GetFrameLine()->m_keyFrames[0].m_pos);particleMovie->ZeroFrames();particleMovie->SetProgramFrame(&frame);}subMovie = thtorgh.GetNext();}}//m_rotAnimAng = 0;m_state = None;Reset();return true;
}bool MagicSquarePlayer::Stop()
{SafeDelete(m_movieCube3);MiniPlayer::Stop();return true;
}void MagicSquarePlayer::AnimRotate(float ang)
{mat4 mat;mat.FromAxisAngle(m_rotAxis,ang);Frame frame;//旋转动画for (int i=0;i<BlockNum;i++){if(m_bBlockRotating[i]){frame.m_matrix = mat * m_blockFrames[i].m_matrix;m_movieBlocks[i]->SetProgramFrame(&frame);}}for (int i=0;i<m_ornamentBlockNum;i++){if(m_bOrnamentRotating[i]){frame.m_matrix = mat * m_ornamentFrames[i].m_matrix;m_movieOrnamentBlocks[i]->SetProgramFrame(&frame);}}
}
void MagicSquarePlayer::BackupFrame(const AABB& bound)
{for (int i=0;i<BlockNum;i++){Frame* frame = m_movieBlocks[i]->GetProgramFrame();if(TestPointAABB(frame->m_matrix.GetTranslate(),bound)){m_blockFrames[i] = *frame;m_bBlockRotating[i] = true;}else{m_bBlockRotating[i] = false;}}for (int i=0;i<m_ornamentBlockNum;i++){Frame* frame = m_movieOrnamentBlocks[i]->GetProgramFrame();if(TestPointAABB(frame->m_pos,bound)){m_ornamentFrames[i] = *frame;m_bOrnamentRotating[i] = true;}else{m_bOrnamentRotating[i] = false;}}
}
void MagicSquarePlayer::RestoreFrame()
{for (int i=0;i<BlockNum;i++){if(m_bBlockRotating[i] == true){m_movieBlocks[i]->SetProgramFrame(&m_blockFrames[i]);}}for (int i=0;i<m_ornamentBlockNum;i++){if(m_bOrnamentRotating[i] == true){m_movieOrnamentBlocks[i]->SetProgramFrame(&m_ornamentFrames[i]);}}
}
void MagicSquarePlayer::rotate3D(const AABB& bound,const vec3& axis)
{//若上次旋转动画未结束,结束之if(m_state == AnimRotating && m_rotAnimAng<HALFPI){AnimRotate(HALFPI);}//保存初始位置m_state = AnimRotating;m_rotAnimAng = 0;m_rotAxis = axis;BackupFrame(bound);//G_MagicSquareGame->PlaySound__("data/sound/gladiator/punchUnHit.wav");
}void MagicSquarePlayer::Update()
{MiniPlayer::Update();if (m_state == AnimRotating){//90度旋转动画if (m_rotAnimAng < 0){m_rotAnimAng = 0;}else if (m_rotAnimAng < HALFPI){m_rotAnimAng += G_Timer->GetStepTimeLimited()*RotSpeed;}if (m_rotAnimAng >= HALFPI){m_rotAnimAng = HALFPI; //模型规整到90度if (m_executeStr[0]==0){m_state = None;}else{m_state = ExecuteRotating;}}//旋转动画AnimRotate(m_rotAnimAng);}else if (m_state == DragRotating){if (m_dragRotDecided){//旋转动画AnimRotate(m_rotAnimAng);}}else if (m_state==ExecuteRotating){if (m_executeStr[0]!=0){char buf[4]={0,0,0,0};buf[0] = m_executeStr[0];buf[1] = m_executeStr[1];if (buf[1]!='\''){buf[1] = 0;}int len = strlen(m_executeStr)-strlen(buf);if(len>0)memmove(m_executeStr,m_executeStr+strlen(buf),len);m_executeStr[len] = 0;Execute(buf);}else{m_state = None;}}if (m_movieOrnament){m_movieOrnament->Advance();}if (m_movieCube3){m_movieCube3->Advance();}
}void MagicSquarePlayer::Render()
{G_RendDriver->EndUI();if (m_movieCube3){m_movieCube3->RendClip();}if (m_movieOrnament){m_movieOrnament->RendClip();}G_RendDriver->BeginUI();显示思考中//if(G_MagicSquareGame->m_gameState==MS_Gamming//    &&G_MagicSquareGame->m_curSide == m_side)//{// //m_ctrlThink->SetVisible(true);//   int index = int(G_Timer->GetAccumTime()*10)%4;//    Texture* texture = G_MagicSquareGame->m_thinkTexture[index];//  texture->Bind();//   //if(m_screenPos == SP_Down)//    if(dynamic_cast<MagicSquarePlayerRole*>(this))//  {//     G_RendDriver->DrawTextureRect(vec2(G_Window->m_iWidth-G_MagicSquareGame->Offset.x ,  G_Window->m_iHeight- G_MagicSquareGame->Offset.y-texture->GetHeight()));//   }// else//  {//     G_RendDriver->DrawTextureRect(vec2(G_Window->m_iWidth-G_MagicSquareGame->Offset.x ,  G_MagicSquareGame->Offset.y));//   }//}选中//if(m_manSelected!=ID_MAN_NULL)//{//    Texture* tex = m_side==SideRed?G_MagicSquareGame->m_textureSelectGreen:G_MagicSquareGame->m_textureSelectRed;//    tex->Bind();//   vec2I pos;//    G_MagicSquareGame->PointToScreen(G_MagicSquareGame->m_manPoint[m_manSelected],pos);// G_RendDriver->DrawTextureRect(RectF(pos.x,pos.y,BoardCellWidth,BoardCellWidth));//}m_offset = vec2I(100,230);G_RendDriver->BlendFunc(Blend_Filter);//G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST, true);G_RendDriver->SetRenderStateEnable(RS_TEXTURE_2D, true);G_RendDriver->PushMatrix();G_RendDriver->Translatef(m_offset.x,-m_offset.y,0);m_texture->Bind();for(int i = 0; i < 6; i++){for(int asp = 0; asp < 9; asp++){RectF tex = m_colorTexRects[m_blockColors[i][asp]];vec2I* v = &blockVertexes[i][asp][0];//G_RendDriver->DrawTextureRect(RectF(v->x,v->y,BlockSize,BlockSize),tex);G_RendDriver->RendBegin(RS_QUADS);G_RendDriver->TexCoord2f(tex.x,tex.y);G_RendDriver->Vertex3f(v->s,G_Window->m_iHeight- v->y,0);v++;G_RendDriver->TexCoord2f(tex.x+tex.width,tex.y);G_RendDriver->Vertex3f(v->s,G_Window->m_iHeight- v->y,0);v++;G_RendDriver->TexCoord2f(tex.x+tex.width,tex.y+tex.height);G_RendDriver->Vertex3f(v->s,G_Window->m_iHeight- v->y,0);v++;G_RendDriver->TexCoord2f(tex.x,tex.y+tex.height);G_RendDriver->Vertex3f(v->s,G_Window->m_iHeight- v->y,0);G_RendDriver->RendEnd();}}G_RendDriver->PopMatrix();G_RendDriver->EndUI();}bool MagicSquarePlayer::IsInThisRect(vec2I* pts, const vec2I& point)
{if(pts[0].x == pts[1].x){if(pts[0].y == pts[3].y) //rectangle{if(point.x > pts[0].x && point.x < pts[3].x &&point.y < pts[0].y && point.y > pts[1].y){return true;}}else  //irregular quadrangle:3{int vdist = point.x - pts[0].x;if(point.x > pts[0].x && point.x < pts[3].x &&point.y < pts[0].y - vdist && point.y > pts[1].y - vdist){return true;}}}else  //irregular quadrangle:4{int vdist = pts[0].y - point.y;if(point.y < pts[0].y && point.y > pts[1].y &&point.x > pts[0].x + vdist && point.x < pts[3].x + vdist){return true;}}return false;
}FaceDir MagicSquarePlayer::GetAspect(const vec2I& point)
{for(int i = 0; i < 6; i++){if(IsInThisRect(aspectVertexes[i], point)){return FaceDir(i);}}return NOASPECT;
}
int  MagicSquarePlayer::GetSmallAspectIndex(FaceDir asp, const vec2I& point)
{for(int i = 0; i < 9; i++){if(IsInThisRect(blockVertexes[asp][i], point)){return i;}}return -1;
}void MagicSquarePlayer::Reset()
{m_executeStr[0] = 0;MagicSquareSolver::Reset();m_rotAnimAng = 0;int snapAlign = 5;//10//mat4 mat;for (int i=0;i<BlockNum;i++){MovieClip* movie = m_movieBlocks[i];Frame* frame = movie->GetProgramFrame();mat = frame->m_matrix;mat.SetTranslate(vec3());mat.Inverse();{mat = mat * frame->m_matrix;vec3 pos = mat.GetTranslate();pos.x = floor(pos.x/snapAlign+0.5f)*snapAlign;pos.y = floor(pos.y/snapAlign+0.5f)*snapAlign;pos.z = floor(pos.z/snapAlign+0.5f)*snapAlign;frame->m_matrix.Identity();frame->SetPos(pos);movie->SetProgramFrame(frame);}m_bBlockRotating[i] = false;}for (int i=0;i<m_ornamentBlockNum;i++){MovieClip* movie = m_movieOrnamentBlocks[i];Frame* frame = movie->GetProgramFrame();mat = frame->m_matrix;mat.SetTranslate(vec3());mat.Inverse();{mat = mat * frame->m_matrix;vec3 pos = mat.GetTranslate();pos.x = floor(pos.x/snapAlign+0.5f)*snapAlign;pos.y = floor(pos.y/snapAlign+0.5f)*snapAlign;pos.z = floor(pos.z/snapAlign+0.5f)*snapAlign;frame->m_matrix.Identity();frame->SetPos(pos);movie->SetProgramFrame(frame);}m_bOrnamentRotating[i] = false;}
}void MagicSquarePlayer::OnRandom()
{Reset();char buf[128] = "";int scrambleNumber = 30;while(scrambleNumber-- > 0){strcat(buf,RotateFunNameTable[rand() % 3][rand() % 2 * 2][rand() % 2]);}OnExecute(buf);
}
void MagicSquarePlayer::OnSolution()
{MagicSquareSolver tempSolver = *this;tempSolver.MethodFewerFormula();OnExecute(tempSolver.m_history);
}
void MagicSquarePlayer::OnExecute(const char* str)
{//MagicSquareSolver::Execute(str);if (m_state==None){m_state = ExecuteRotating;}else if (m_state==DragRotating){//等待结束后自动跳转 }else if (m_state==AnimRotating){//等待结束后自动跳转 否则模型没转到90度}strcpy_s(m_executeStr,str);m_executeStr[sizeof(m_executeStr)-1] = 0;
}
void MagicSquarePlayer::OnStopExecute()
{m_executeStr[0] = 0;
}void MagicSquarePlayer::rotateFullAspectCW(FaceDir asp, int* index)
{MagicSquareSolver::rotateFullAspectCW(asp, index);
}
void MagicSquarePlayer::rotateFullAspectACW(FaceDir asp, int* index)
{MagicSquareSolver::rotateFullAspectACW(asp, index);
}
void MagicSquarePlayer::rotateXLeftCW(int flag)
{//L'//.x < -5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-1000) ,vec3(-5,1000,1000)),vec3(-1,0,0));MagicSquareSolver::rotateXLeftCW(flag);
}
void MagicSquarePlayer::rotateXLeftACW(int flag)
{//L//.x < -5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-1000) ,vec3(-5,1000,1000)),vec3(1,0,0));MagicSquareSolver::rotateXLeftACW(flag);
}
void MagicSquarePlayer::rotateXRightCW(int flag)
{//R//.x > 5if (flag&2) rotate3D(AABB(vec3(5,-1000,-1000) ,vec3(1000,1000,1000)),vec3(-1,0,0));MagicSquareSolver::rotateXRightCW(flag);
}
void MagicSquarePlayer::rotateXRightACW(int flag)
{//R'//.x > 5if (flag&2) rotate3D(AABB(vec3(5,-1000,-1000) ,vec3(1000,1000,1000)),vec3(1,0,0));MagicSquareSolver::rotateXRightACW(flag);
}
void MagicSquarePlayer::rotateXMiddleCW(int flag)
{////-5 < .x < 5if (flag&2) rotate3D(AABB(vec3(-5,-1000,-1000) ,vec3(5,1000,1000)),vec3(-1,0,0));MagicSquareSolver::rotateXMiddleCW(flag);
}
void MagicSquarePlayer::rotateXMiddleACW(int flag)
{////-5 < .x < 5if (flag&2) rotate3D(AABB(vec3(-5,-1000,-1000) ,vec3(5,1000,1000)),vec3(1,0,0));MagicSquareSolver::rotateXMiddleACW(flag);
}
void MagicSquarePlayer::rotateYDownCW(int flag)
{//Dr//.y < -5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-1000) ,vec3(1000,-5,1000)),vec3(0,-1,0));MagicSquareSolver::rotateYDownCW(flag);
}
void MagicSquarePlayer::rotateYDownACW(int flag)
{//D//.y < -5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-1000) ,vec3(1000,-5,1000)),vec3(0,1,0));MagicSquareSolver::rotateYDownACW(flag);
}
void MagicSquarePlayer::rotateYUpCW(int flag)
{//U//.y > 5if (flag&2) rotate3D(AABB(vec3(-1000,5,-1000) ,vec3(1000,1000,1000)),vec3(0,-1,0));MagicSquareSolver::rotateYUpCW(flag);
}
void MagicSquarePlayer::rotateYUpACW(int flag)
{//U'//.y > 5if (flag&2) rotate3D(AABB(vec3(-1000,5,-1000) ,vec3(1000,1000,1000)),vec3(0,1,0));MagicSquareSolver::rotateYUpACW(flag);
}
void MagicSquarePlayer::rotateYMiddleCW(int flag)
{////-5 < .y < 5if (flag&2) rotate3D(AABB(vec3(-1000,-5,-1000) ,vec3(1000,5,1000)),vec3(0,-1,0));MagicSquareSolver::rotateYMiddleCW(flag);
}
void MagicSquarePlayer::rotateYMiddleACW(int flag)
{////-5 < .y < 5if (flag&2) rotate3D(AABB(vec3(-1000,-5,-1000) ,vec3(1000,5,1000)),vec3(0,1,0));MagicSquareSolver::rotateYMiddleACW(flag);
}
void MagicSquarePlayer::rotateZFrontCW(int flag)
{//F//.z > 5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,5) ,vec3(1000,1000,1000)),vec3(0,0,-1));MagicSquareSolver::rotateZFrontCW(flag);
}
void MagicSquarePlayer::rotateZFrontACW(int flag)
{//F'//.z > 5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,5) ,vec3(1000,1000,1000)),vec3(0,0,1));MagicSquareSolver::rotateZFrontACW(flag);
}
void MagicSquarePlayer::rotateZBackCW(int flag)
{//B'//.z < -5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-1000) ,vec3(1000,1000,-5)),vec3(0,0,-1));MagicSquareSolver::rotateZBackCW(flag);
}
void MagicSquarePlayer::rotateZBackACW(int flag)
{//B//.z < -5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-1000) ,vec3(1000,1000,-5)),vec3(0,0,1));MagicSquareSolver::rotateZBackACW(flag);
}
void MagicSquarePlayer::rotateZMiddleCW(int flag)
{////-5 < .z < 5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-5) ,vec3(1000,1000,5)),vec3(0,0,-1));MagicSquareSolver::rotateZMiddleCW(flag);
}
void MagicSquarePlayer::rotateZMiddleACW(int flag)
{////-5 < .z < 5if (flag&2) rotate3D(AABB(vec3(-1000,-1000,-5) ,vec3(1000,1000,5)),vec3(0,0,1));MagicSquareSolver::rotateZMiddleACW(flag);
}

玩家自身:

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/MagicSquare/MagicSquare.cpp
//  @Brief:     MagicSquare
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================#include "General/Pch.h"
#include "General/Window.h"
#include "MagicSquare/MagicSquareRole.h"
#include "MagicSquare/MiniGameMagicSquare.h"
#include "General/Timer.h"
#include "Rpg/SyncGameInfo.h"
#include "Sound/SoundManager.h"
#include "Packet/PacketMiniGame.h"
#include "Input/InputMgr.h"
#include "Render/Camera.h"
#include "Render/RendDriver.h"
#include "Render/MC_MovieClip.h"
#include "General/Pce.h"
#include "Math/MathLibAdvance.h"MagicSquarePlayerRole::MagicSquarePlayerRole()
:m_colorSelected(BLUE)
{m_workingWithAI = false;
}
MagicSquarePlayerRole::~MagicSquarePlayerRole()
{
}
bool MagicSquarePlayerRole::Start()
{if(MagicSquarePlayerRobot::Start()==false)return false;m_colorSelected = BLUE;return true;
}void MagicSquarePlayerRole::Reset()
{MagicSquarePlayerRobot::Reset();m_colorSelected = BLUE;
}vec3 NearestAxis(const vec3& dir)
{float absX = (dir.x>0?dir.x:-dir.x);float absY = (dir.y>0?dir.y:-dir.y);float absZ = (dir.z>0?dir.z:-dir.z);vec3 axis;if (absX > absY && absX > absZ){axis.x = (dir.x>0?1:-1);}else if (absY > absX && absY > absZ){axis.y = (dir.y>0?1:-1);}else{axis.z = (dir.z>0?1:-1);}return axis;
}void MagicSquarePlayerRole::Update()
{if(m_workingWithAI){return MagicSquarePlayerRobot::Update();}MagicSquarePlayer::Update();if (G_Mouse->IsButtonDowning(MOUSE_LEFT)){vec2 pos = G_Mouse->GetMousePos();OnLButtonDown(vec2I(pos.x,pos.y));}m_movieSelect->SetVisible(m_state==None || m_state==DragRotating,Recursive);vec3 dir;vec3 start;G_Camera->GetMouseTray(start,dir);vec3 end = start+10000*dir;RayMovieCollideRes res(start,end);if (m_state==None){Frame frame;int snapAlign = 10;if(m_movieCube3->IntersectTray(res)){//posint  flag = 0;vec3 regularPos = res.resPos - m_startPos;if (abs(res.resNorml.x)<0.5f){regularPos.x = floor(regularPos.x/snapAlign+0.5f)*snapAlign;flag++;}if (abs(res.resNorml.y)<0.5f){regularPos.y = floor(regularPos.y/snapAlign+0.5f)*snapAlign;flag++;}if (abs(res.resNorml.z)<0.5f){regularPos.z = floor(regularPos.z/snapAlign+0.5f)*snapAlign;flag++;}//rotvec3 regularNormal = NearestAxis(res.resNorml);if (abs(res.resNorml.x) < abs(res.resNorml.y) && abs(res.resNorml.x)<abs(res.resNorml.z)){frame.m_matrix.FromToDir(vec3(0,1,0),vec3(0,0,1),res.resNorml,vec3(res.resNorml.x,-res.resNorml.z,res.resNorml.y));}else if (abs(res.resNorml.y) < abs(res.resNorml.x)&& abs(res.resNorml.y) < abs(res.resNorml.z)){frame.m_matrix.FromToDir(vec3(0,1,0),vec3(0,0,1),res.resNorml,vec3(-res.resNorml.z,res.resNorml.y,res.resNorml.x));}else{frame.m_matrix.FromToDir(vec3(0,1,0),vec3(0,0,1),res.resNorml,vec3(-res.resNorml.y,res.resNorml.x,res.resNorml.z));}frame.m_matrix .SetTranslate(regularPos);if (G_Mouse->IsButtonDowning(MOUSE_LEFT)&&flag==2){//已经选中初始 facelet 还未确定旋转方向m_state = MagicSquarePlayer::DragRotating;m_dragRotDecided  = false;m_dragStartMovie  = res.resClip;m_dragBeginRegularPos    = regularPos;m_dragBeginRegularNormal = regularNormal;m_dragBeginMousePos = G_Mouse->GetMousePos();m_rotAnimAng = 0;}}else{frame.m_matrix .SetTranslate(vec3()-m_startPos);}m_movieSelect->SetProgramFrame(&frame);}else if (m_state==DragRotating){if (G_Mouse->IsButtonPressed(MOUSE_LEFT)){if (m_dragRotDecided==false){if(m_movieCube3->IntersectTray(res) && res.resClip!=m_dragStartMovie){//开始确定方向vec3 pos = res.resPos - m_startPos;m_dragRotDecided = true;m_rotAxis    = m_dragBeginRegularNormal.Cross(pos-m_dragBeginRegularPos);m_rotAxis    = NearestAxis(m_rotAxis);m_dragDecideMousePos = G_Mouse->GetMousePos();m_rotAnimAng = 0;pos = m_dragBeginRegularPos;AABB bound;if (abs(m_rotAxis.x) == 1){bound.min = vec3(pos.x-2.0f,pos.y-1000,pos.z-1000);bound.max = vec3(pos.x+2.0f,pos.y+1000,pos.z+1000);}else if (abs(m_rotAxis.y) == 1){bound.min = vec3(pos.x-1000,pos.y-2.0f,pos.z-1000);bound.max = vec3(pos.x+1000,pos.y+2.0f,pos.z+1000);}else {bound.min = vec3(pos.x-1000,pos.y-1000,pos.z-2.0f);bound.max = vec3(pos.x+1000,pos.y+1000,pos.z+2.0f);}BackupFrame(bound);//rotate3D(bound,m_rotAxis);//m_state = DragRotating;}}else{//已经确定旋转方向vec2  dir = m_dragDecideMousePos - m_dragBeginMousePos;dir.Normalize();float dot = (G_Mouse->GetMousePos() - m_dragBeginMousePos).Dot(dir);m_rotAnimAng = dot/400*HALFPI;if (m_rotAnimAng>HALFPI){m_rotAnimAng = HALFPI;}else if (m_rotAnimAng<-HALFPI){m_rotAnimAng = -HALFPI;}//mat4 mat;mat.FromAxisAngle(m_rotAxis,m_rotAnimAng);Frame frame;vec3 normal = mat*m_dragBeginRegularNormal;if (abs(normal.x) < abs(normal.y) && abs(normal.x)<abs(normal.z)){frame.m_matrix.FromToDir(vec3(0,1,0),vec3(0,0,1),normal,vec3(normal.x,-normal.z,normal.y));}else if (abs(normal.y) < abs(normal.x)&& abs(normal.y) < abs(normal.z)){frame.m_matrix.FromToDir(vec3(0,1,0),vec3(0,0,1),normal,vec3(-normal.z,normal.y,normal.x));}else{frame.m_matrix.FromToDir(vec3(0,1,0),vec3(0,0,1),normal,vec3(-normal.y,normal.x,normal.z));}frame.m_matrix .SetTranslate(mat*m_dragBeginRegularPos);m_movieSelect->SetProgramFrame(&frame);}}else{//已经确定旋转方向if (m_dragRotDecided==true ){if (abs(m_rotAnimAng)>_PI*0.1f){//确定旋转m_state = MagicSquarePlayer::AnimRotating;if (m_rotAnimAng < 0){m_rotAxis *= -1;m_rotAnimAng *= -1;}G_MagicSquareGame->PlaySound__("data/sound/gladiator/punchUnHit.wav");int axis;int dir;int chunk;if (m_rotAxis.x==1){axis = X;dir  = COUNTERCLOCKWISE;}else if (m_rotAxis.x==-1){axis = X;dir  = CLOCKWISE;}else if (m_rotAxis.y==1){axis = Y;dir  = COUNTERCLOCKWISE;}else if (m_rotAxis.y==-1){axis = Y;dir  = CLOCKWISE;}else if (m_rotAxis.z==1){axis = Z;dir  = COUNTERCLOCKWISE;}else if (m_rotAxis.z==-1){axis = Z;dir  = CLOCKWISE;}if (m_dragBeginRegularPos[axis]<0){chunk = NEGATIVE;}else if (m_dragBeginRegularPos[axis]>0){chunk = POSITIVE;}else{chunk = MIDDLE;}RotateFun fun = RotateFunTable[axis][chunk][dir];(this->*fun)(1);}else{//取消m_state = MagicSquarePlayer::None;RestoreFrame();}}else{//取消m_state = MagicSquarePlayer::None;}}}
}void MagicSquarePlayerRole::Render()
{MagicSquarePlayerRobot::Render();//G_RendDriver->BlendFunc(Blend_Filter);//G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST, true);G_RendDriver->SetRenderStateEnable(RS_TEXTURE_2D, true);//show selected colorRectF rc(m_offset.x,m_offset.y+100,BlockSize,BlockSize);G_RendDriver->DrawTextureRect(rc,m_colorTexRects[m_colorSelected]);G_RendDriver->Color3f(1,1,1);char* text="Selected Color";G_FontMgr->TextAtPos(vec2(rc.x-20,rc.y+rc.height+3),text);G_RendDriver->EndUI();
}void MagicSquarePlayerRole::OnLButtonDown(vec2I point)
{point.x -= m_offset.x;point.y -= m_offset.y;FaceDir asp = GetAspect(point);if(asp != NOASPECT){int index = GetSmallAspectIndex(asp, point);if(index >= 0){if(index == 4){m_colorSelected = m_blockColors[asp][index];}else{m_blockColors[asp][index] = m_colorSelected;}}}
}

z

带自动还原魔方游戏源码相关推荐

  1. PHP大灌篮投篮游戏源码 微信+手机wap源码 带控制_大灌篮游戏源码

    内含详细安装教程,请严格按照文档来安装,顺序错了也会安装不起来. PHP大灌篮游戏源码,投篮游戏源码,手动提现 后台密码自己替换MD5 [完整源码链接] PHP大灌篮投篮游戏源码微信+手机wap源码带 ...

  2. Cocos2dx游戏开发笔记22:以仿《王者之剑》游戏源码为例,学习cocos2dx2.X到 3.0beta2 的升级(附源码)

    懒骨头(http://blog.csdn.net/iamlazybone QQ:124774397 青岛) 原贴在此:http://www.9miao.com/thread-45434-1-1.htm ...

  3. 11款手机微信小游戏源码特效

    html5微信吃苹果游戏源码下载 html5手机淘宝万能时装屋小游戏源码下载 html5 3d拳王游戏制作3D拳击游戏源码下载 html5 3d拼图游戏制作3D魔方游戏源码下载 htm5 3d游戏制作 ...

  4. 如何用php农场项目,2020全新亲测php农场游戏源码-金币菇种植理财区块链源码 带商城系统...

    2020全新亲测php农场游戏源码-金币菇种植理财区块链源码 带商城系统+抽奖系统+独家搭建教程 金币菇一款复利理财游戏,在这里大家可以更轻松.愉快的进行理财投资!本源码是一套理财游戏盘系统,蘑菇只是 ...

  5. HTML5高度还原复古24层魔塔网页版小游戏源码

    简介: HTML5高度还原复古24层魔塔网页版小游戏源码 网盘下载地址: http://kekewl.cc/OFfi6keX7OS0 图片:

  6. 最新王了个王H5游戏源码+三消游戏/带后台版本

    正文: 王了个王H5游戏源码,带后台版本,仿羊了个羊的玩法,其它的就没什么好介绍的了,有兴趣的自行去研究吧. 程序: wwfesu.lanzoux.com/ibw5V0crixpg 图片:  

  7. 苹果cms php免费资源,苹果CMS自动采集 X站源码带全部资源PHP - 下载 - 搜珍网

    压缩包 : 苹果CMS自动采集H站源码带全部资源.zip 列表 admin/ admin/admin_conn.php admin/admin_data.php admin/admin_interfa ...

  8. c#推箱子小游戏代码_C# 推箱子游戏源码(带音效/关卡)

    C# 推箱子游戏源码(带音效/关卡) c# 2021-1-29 下载地址 https://www.codedown123.com/62444.html Vs2010 FrameWork 4.0 具有音 ...

  9. java井字棋ai_JavaScript实现一个带AI的井字棋游戏源码

    JavaScript实现一个带AI的井字棋游戏源码 发布时间:2020-09-05 00:56:12 来源:脚本之家 阅读:100 作者:小楼夜听雨QAQ 最近有一门课结束了,需要做一个井字棋的游戏, ...

  10. 100行JS代码实现❤坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript )

    坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript ) HTML5坦克大战网页小游戏,完美还原小霸王学习机效果,以坦克战斗及保卫基地为主题,属于策略型类游戏. ...

最新文章

  1. 汇编:内存地址为什么从0开始?等问题
  2. 从放弃迅雷和IDM到自己开发下载工具
  3. virtualBox下安装Linux6.4
  4. [POI2006]OKR-Periods of Words
  5. python题库刷题训练软件_Python基础练习100题 ( 11~ 20)
  6. POJ 1581 优先队列 priority_queue -- 比赛胜者求解
  7. XML万能数据库设计
  8. 蔚来汽车澄清“4年亏损57亿美元”说法:只有200亿人民币
  9. 如何使用SQL Server链接服务器查询Excel数据
  10. real-time RGB-D camera relocalization
  11. Entity FrameWork利用Database.SqlQueryT执行存储过程并返回参数
  12. hsql转换oracle,Oracle To Hsql
  13. SQLite的主键外键
  14. win7计算机怎么初始化,win7怎么初始化电脑 win7初始化电脑步骤
  15. java编程符号大全_数学符号大全
  16. 字节跳动工作总结:工作一年的真心话
  17. VSCode插件,TODO标记
  18. 科学计算机百分比怎么按成小数,手机计算器百分比怎么用
  19. OS学习笔记-2(清华大学慕课)mooc实验介绍
  20. Redis之击穿、穿透、雪崩问题

热门文章

  1. android 定时器 误差,计时器秒表app下载
  2. GO语言04(简单的RESTful API服务器,API 服务器健康状态自检)
  3. 【报错】进程已结束,退出代码-1073740791 (0xC0000409)
  4. 瀚高数据库并行导入导出
  5. G. 打印 LOGO(递归)
  6. 秒杀的实现原理及实现方式
  7. 普歌-码上鸿鹄团队-复习系统模块
  8. 马哥教育 mysql_马哥教育第二十三MySQL基础应用入门
  9. linux oel7没有网络,sudo su命令不在OEL 7中工作(sudo su command not working in OEL 7)
  10. beego golang bootstrap-table做月度考勤(打卡、签到)统计表