| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 11005 人关注过本帖, 2 人收藏
标题:[原创] 不到 800 行代码,彻底搞定魔方还原问题
只看楼主 加入收藏
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
结帖率:95.65%
收藏(2)
已结贴  问题点数:20 回复次数:46 
[原创] 不到 800 行代码,彻底搞定魔方还原问题
今天进展比较顺利,彻底解决了魔方还原问题

总共代码不到 800 行,还原速度在 10s 左右,当然还可以进一步优化。

代码我放到 github 上了:

https://

一些符号的含义:
F - 正面,程序运行后白色的这一面
B - 背面,黄色面
L - 左面,紫色面(标准魔方应该是橙色,但是 windows 控制台无法显示橙色,用紫色替代)
R - 右面,红色面
U - 上面,蓝色面
D - 下面,绿色面


命令说明:

魔方操作命令:
f  - 正面顺时针旋转
f2 - 正面 180 度旋转
f' - 正面逆时针旋转

其他面以此类推:
f2 f' b b2 b' u u2 u' d d2 d' l l2 l' r r2 r'

init  - 魔方复位
rand  - 随机打乱魔方,可以直接 rand 或者 rand n,n 为随机打乱次数
input - 输入魔方状态,按照提示输入即可
solve - 自动还原魔方
help  - 帮助信息
exit  - 退出程序

所有命令都是用小写字母。



数据结构和算法说明:

数据结构方面,每个面都用简单的二维数组来表示。要点是六个面的旋转操作的实现,以及魔方状态的显示,和状态输入。

算法方面,主要是用到了启发式的广度优先搜索。要点在于魔方状态的评估函数,剪枝方法,搜索算法等。

当然,你还得懂魔方。


程序代码量不大,也写得足够精简,可仔细品味。如有不懂可以提问。


[此贴子已经被作者于2018-12-10 11:22编辑过]

搜索更多相关主题的帖子: 代码 魔方 还原 旋转 状态 
2018-12-09 21:28
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#pragma pack(1)
typedef struct tagCUBE {
    struct tagCUBE *parent;
    char f[3][3];
    char b[3][3];
    char u[3][3];
    char d[3][3];
    char l[3][3];
    char r[3][3];
    char op;
} CUBE;
#pragma pack()

typedef struct {
    int   stride;
    char *buffer;
} LINEITEM;

static void line_rotate90(LINEITEM item[5])
{
    int i, j;
    for (i=0; i<5; i++) {
        int   dst_idx    = (i+0) % 5;
        int   src_idx    = (i+1) % 5;
        char *dst_buf    = item[dst_idx].buffer;
        char *src_buf    = item[src_idx].buffer;
        int   dst_stride = item[dst_idx].stride;
        int   src_stride = item[src_idx].stride;
        for (j=0; j<3; j++) {
            *dst_buf = *src_buf;
            dst_buf += dst_stride;
            src_buf += src_stride;
        }
    }
}

static void surface_rotate90(char buf[3][3])
{
    char tmp[3][3];
    int  i, j;
    memcpy(tmp, buf, sizeof(tmp));
    for (i=0; i<3; i++) {
        for (j=0; j<3; j++) {
            buf[i][j] = tmp[3-j-1][i];
        }
    }
}

static void cube_init(CUBE *c)
{
    memset(c->f, 'w', sizeof(c->f));
    memset(c->b, 'y', sizeof(c->b));
    memset(c->u, 'b', sizeof(c->u));
    memset(c->d, 'g', sizeof(c->d));
    memset(c->l, 'o', sizeof(c->l));
    memset(c->r, 'r', sizeof(c->r));
}

static void cube_f(CUBE *c)
{
    char temp[3];
    LINEITEM lines[5] = {
        { 1,  temp          },
        { 3,  &(c->l[0][2]) },
        { 1,  &(c->d[0][0]) },
        {-3,  &(c->r[2][0]) },
        {-1,  &(c->u[2][2]) },
    };
    line_rotate90(lines);
    surface_rotate90(c->f);
}

static void cube_b(CUBE *c)
{
    char temp[3];
    LINEITEM lines[5] = {
        { 1,  temp          },
        { 3,  &(c->r[0][2]) },
        {-1,  &(c->d[2][2]) },
        {-3,  &(c->l[2][0]) },
        { 1,  &(c->u[0][0]) },
    };
    line_rotate90(lines);
    surface_rotate90(c->b);
}

static void cube_u(CUBE *c)
{
    char temp[3];
    LINEITEM lines[5] = {
        { 1,  temp          },
        { 1,  &(c->l[0][0]) },
        { 1,  &(c->f[0][0]) },
        { 1,  &(c->r[0][0]) },
        { 1,  &(c->b[0][0]) },
    };
    line_rotate90(lines);
    surface_rotate90(c->u);
}

static void cube_d(CUBE *c)
{
    char temp[3];
    LINEITEM lines[5] = {
        { 1,  temp          },
        { 1,  &(c->b[2][0]) },
        { 1,  &(c->r[2][0]) },
        { 1,  &(c->f[2][0]) },
        { 1,  &(c->l[2][0]) },
    };
    line_rotate90(lines);
    surface_rotate90(c->d);
}

static void cube_l(CUBE *c)
{
    char temp[3];
    LINEITEM lines[5] = {
        { 1,  temp          },
        { 3,  &(c->d[0][0]) },
        { 3,  &(c->f[0][0]) },
        { 3,  &(c->u[0][0]) },
        {-3,  &(c->b[2][2]) },
    };
    line_rotate90(lines);
    surface_rotate90(c->l);
}

static void cube_r(CUBE *c)
{
    char temp[3];
    LINEITEM lines[5] = {
        { 1,  temp          },
        { 3,  &(c->u[0][2]) },
        { 3,  &(c->f[0][2]) },
        { 3,  &(c->d[0][2]) },
        {-3,  &(c->b[2][0]) },
    };
    line_rotate90(lines);
    surface_rotate90(c->r);
}

enum {
    CUBE_OP_F,
    CUBE_OP_B,
    CUBE_OP_U,
    CUBE_OP_D,
    CUBE_OP_L,
    CUBE_OP_R,
};

static void (*g_op_tab[])(CUBE *c) = { cube_f, cube_b, cube_u, cube_d, cube_l, cube_r };
static void cube_op  (CUBE *c, int op) { (g_op_tab[op])(c); }
static void cube_rand(CUBE *c, int n ) { while (n-- > 0) cube_op(c, rand() % 6); }

static void cube_render(CUBE *c)
{
    char buffer[9][12] = {0};
    int  i, j;

    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    WORD wOldColorAttrs;
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

    // save the current color
    GetConsoleScreenBufferInfo(h, &csbiInfo);
    wOldColorAttrs = csbiInfo.wAttributes;

    for (i=0; i<3; i++) for (j=0; j<3; j++) buffer[3+i][3+j] = c->f[i][j];
    for (i=0; i<3; i++) for (j=0; j<3; j++) buffer[3+i][9+j] = c->b[i][j];
    for (i=0; i<3; i++) for (j=0; j<3; j++) buffer[0+i][3+j] = c->u[i][j];
    for (i=0; i<3; i++) for (j=0; j<3; j++) buffer[6+i][3+j] = c->d[i][j];
    for (i=0; i<3; i++) for (j=0; j<3; j++) buffer[3+i][0+j] = c->l[i][j];
    for (i=0; i<3; i++) for (j=0; j<3; j++) buffer[3+i][6+j] = c->r[i][j];

    for (i=0; i<9; i++) {
        for (j=0; j<12; j++) {
            switch (buffer[i][j]) {
            case 'w': case 'W': SetConsoleTextAttribute(h, FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); break;
            case 'y': case 'Y': SetConsoleTextAttribute(h, FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN); break;
            case 'b': case 'B': SetConsoleTextAttribute(h, FOREGROUND_INTENSITY|FOREGROUND_BLUE ); break;
            case 'g': case 'G': SetConsoleTextAttribute(h, FOREGROUND_INTENSITY|FOREGROUND_GREEN); break;
            case 'o': case 'O': SetConsoleTextAttribute(h, FOREGROUND_RED|FOREGROUND_BLUE       ); break;
            case 'r': case 'R': SetConsoleTextAttribute(h, FOREGROUND_INTENSITY|FOREGROUND_RED  ); break;
            }
            printf(buffer[i][j] ? "# " : "  ");
        }
        printf("\n");
    }

    // restore the original color
    SetConsoleTextAttribute(h, wOldColorAttrs);
}

static int cube_check_fcross0(CUBE *cube)
{
    int checklist[][2] = {
        { cube->f[1][1], cube->f[0][1] },
        { cube->f[1][1], cube->f[1][0] },
        { cube->f[1][1], cube->f[1][2] },
        { cube->f[1][1], cube->f[2][1] },
    };
    int value = 0, i;
    for (i=0; i<4; i++) {
        value += (checklist[i][0] == checklist[i][1]);
    }
    return value;
}

static int cube_check_fcross1(CUBE *cube)
{
    int checklist[][2] = {
        { cube->l[1][1], cube->l[1][2] },
        { cube->u[1][1], cube->u[2][1] },
        { cube->r[1][1], cube->r[1][0] },
        { cube->d[1][1], cube->d[0][1] },
    };
    int value = 0, i;
    for (i=0; i<4; i++) {
        value += (checklist[i][0] == checklist[i][1]);
    }
    return value;
}

static int cube_check_fcorners(CUBE *cube)
{
    int checklist[][3][2] = {
        {
            { cube->f[1][1], cube->f[0][0] },
            { cube->l[1][1], cube->l[0][2] },
            { cube->u[1][1], cube->u[2][0] },
        },
        {
            { cube->f[1][1], cube->f[0][2] },
            { cube->u[1][1], cube->u[2][2] },
            { cube->r[1][1], cube->r[0][0] },
        },
        {
            { cube->f[1][1], cube->f[2][0] },
            { cube->l[1][1], cube->l[2][2] },
            { cube->d[1][1], cube->d[0][0] },
        },
        {
            { cube->f[1][1], cube->f[2][2] },
            { cube->r[1][1], cube->r[2][0] },
            { cube->d[1][1], cube->d[0][2] },
        },
    };
    int value = 0, i, j;
    for (j=0; j<4; j++) {
        value++;
        for (i=0; i<3; i++) {
            if (checklist[j][i][0] != checklist[j][i][1]) { value--; break; }
        }
    }
    return value;
}

static int cube_check_medges(CUBE *cube)
{
    int checklist[][2][2] = {
        {
            { cube->l[1][1], cube->l[0][1] },
            { cube->u[1][1], cube->u[1][0] },
        },
        {
            { cube->u[1][1], cube->u[1][2] },
            { cube->r[1][1], cube->r[0][1] },
        },
        {
            { cube->l[1][1], cube->l[2][1] },
            { cube->d[1][1], cube->d[1][0] },
        },
        {
            { cube->r[1][1], cube->r[2][1] },
            { cube->d[1][1], cube->d[1][2] },
        },
    };
    int value = 0, i, j;
    for (j=0; j<4; j++) {
        value++;
        for (i=0; i<2; i++) {
            if (checklist[j][i][0] != checklist[j][i][1]) { value--; break; }
        }
    }
    return value;
}

static int cube_check_bcross(CUBE *cube)
{
    int checklist[][2][2] = {
        {
            { cube->b[1][1], cube->b[0][1] },
            { cube->b[1][1], cube->b[2][1] },
        },
        {
            { cube->b[1][1], cube->b[1][0] },
            { cube->b[1][1], cube->b[1][2] },
        },
    };
    int value = 0, i, j;
    for (j=0; j<2; j++) {
        value += 2;
        for (i=0; i<2; i++) {
            if (checklist[j][i][0] != checklist[j][i][1]) { value -= 2; break; }
        }
    }
    return value;
}

static int cube_check_bsurface(CUBE *cube)
{
    int checklist[][2] = {
        { cube->b[1][1], cube->b[0][0] },
        { cube->b[1][1], cube->b[0][2] },
        { cube->b[1][1], cube->b[2][0] },
        { cube->b[1][1], cube->b[2][2] },
    };
    int value = 0, i;
    for (i=0; i<4; i++) {
        value += (checklist[i][0] == checklist[i][1]);
    }
    if (value == 2) value = 0;
    return value;
}

static int cube_check_bcorners(CUBE *cube)
{
    int checklist[][3][2] = {
        {
            { cube->b[1][1], cube->b[0][2] },
            { cube->l[1][1], cube->l[0][0] },
            { cube->u[1][1], cube->u[0][0] },
        },
        {
            { cube->b[1][1], cube->b[0][0] },
            { cube->u[1][1], cube->u[0][2] },
            { cube->r[1][1], cube->r[0][2] },
        },
        {
            { cube->b[1][1], cube->b[2][0] },
            { cube->r[1][1], cube->r[2][2] },
            { cube->d[1][1], cube->d[2][2] },
        },
        {
            { cube->b[1][1], cube->b[2][2] },
            { cube->l[1][1], cube->l[2][0] },
            { cube->d[1][1], cube->d[2][0] },
        },
    };
    int returned[4] = { 1, 1, 1, 1 };
    int value = 0, flag = 0, i, j;
    for (j=0; j<4; j++) {
        value++;
        for (i=0; i<3; i++) {
            if (checklist[j][i][0] != checklist[j][i][1]) { value--; returned[j] = 0; break; }
        }
    }
    for (i=0; i<4; i++) {
        if (returned[i] && returned[(i+1)%4]) flag = 1;
    }
    return flag ? value : 0;
}

static int cube_check_bedges(CUBE *cube)
{
    int checklist[][2][2] = {
        {
            { cube->u[1][1], cube->u[0][1] },
            { cube->b[1][1], cube->b[0][1] },
        },
        {
            { cube->d[1][1], cube->d[2][1] },
            { cube->b[1][1], cube->b[2][1] },
        },
        {
            { cube->l[1][1], cube->l[1][0] },
            { cube->b[1][1], cube->b[1][2] },
        },
        {
            { cube->r[1][1], cube->r[1][2] },
            { cube->b[1][1], cube->b[1][0] },
        },
    };
    int value = 0, i, j;
    for (j=0; j<4; j++) {
        value++;
        for (i=0; i<2; i++) {
            if (checklist[j][i][0] != checklist[j][i][1]) { value--; break; }
        }
    }
    return value;
}

static int cube_check_state(CUBE *cube, int flag)
{
    int (*pfn_check_tab[])(CUBE* cube) = {
        cube_check_fcross0 ,
        cube_check_fcross1 ,
        cube_check_fcorners,
        cube_check_medges  ,
        cube_check_bcross  ,
        cube_check_bsurface,
        cube_check_bcorners,
        cube_check_bedges  ,
        NULL,
    };
    int value = 0, cur, i;
    for (i=0; pfn_check_tab[i]; i++) {
        if (flag) {
            value += pfn_check_tab[i](cube);
            cur   += 4;
            if (cur >= flag) break;
        } else {
            cur    = pfn_check_tab[i](cube);
            value += cur;
            if (cur != 4) break;
        }
    }
    return value;
}

typedef struct {
    int   open ;
    int   close;
    int   size ;
    CUBE *cubes;
} TABLE;

static int search_table_create(TABLE *table, int size)
{
    table->size  = size;
    table->cubes = malloc(size * sizeof(CUBE));
    return table->cubes ? 0 : -1;
}

static void search_table_destroy(TABLE *table)
{
    if (table->cubes) {
        free(table->cubes);
        table->cubes = NULL;
    }
}

static int is_4same_ops(CUBE *cube)
{
    int curop = cube->op;
    int n     = 0;
    while (cube) {
        if (cube->op == curop) {
            if (++n == 4) {
                return 1;
            }
            cube = cube->parent;
        } else break;
    }
    return 0;
}

static int cut_branch(int newval, int cutval)
{
    return newval < cutval;
}

static CUBE* search(TABLE *table, CUBE *start, int state, char *oplist, int opnum, int cutval)
{
    CUBE *curcube ,*newcube;
    int   newstate, newvalue, i;

    start->parent = NULL;
    start->op     = -1;
    if (cube_check_state(start, 0) >= state) return start;

    // init search table
    table->open  = 0;
    table->close = 0;

    // put original cube into open table
    table->cubes[table->open] = *start;
    table->open++;

    while (table->close < table->open) {
        // check memory usage
        if (table->open + 6 >= table->size - 1) {
            printf("all table memory have been used !\n");
            break;
        }

        // dequeue a cube from open table
        curcube = &(table->cubes[table->close++]);

        // extend cubes check state and put new cubes into open table
        for (i=0; i<opnum; i++) {
            newcube = &(table->cubes[table->open]);
            memcpy (newcube, curcube, sizeof(CUBE));
            cube_op(newcube, oplist[i]);
            newcube->op     = oplist[i];
            newcube->parent = curcube;
            newstate = cube_check_state(newcube, 0    );
            newvalue = cube_check_state(newcube, state);
            if (newstate >= state) { // found
                return newcube;
            }
            if (is_4same_ops(newcube)) {
                continue;
            }
            if (cut_branch(newvalue, cutval)) {
                continue;
            }
            table->open++;
        }
    }
    return NULL;
}

static void print_solve_oplist(CUBE *cube)
{
    static char* optab[] = {
        "F" , "B" , "U" , "D" , "L" , "R" ,
        "F2", "B2", "U2", "D2", "L2", "R2",
        "F'", "B'", "U'", "D'", "L'", "R'",
    };
    char *oplist[256];
    int   last = -1, times = 0, i = 0, n = 0;
    while (cube) {
        if (cube->op >= 0) {
            if (last != cube->op) {
                if (last != -1) {
                    oplist[i++] = optab[last + times * 6];
                }
                last = cube->op;
                times= 0;
            } else {
                times++;
            }
        } else {
            if (last != -1) oplist[i++] = optab[last + times * 6];
        }
        cube = cube->parent;
    }
    printf("\noperation list:\n");
    while (--i >= 0) {
        printf("%s%s%s", oplist[i], i == 0 ? "" : " -> ", ++n % 12 == 0 ? "\n" : "");
    }
    printf("\n");
}

static void cube_solve(CUBE *c)
{
    TABLE t;

    if (search_table_create(&t, 1024*1024*16) != 0) {
        printf("failed to create cube search table !\n");
        return;
    }

    if (1) {
        static char oplisttab[][6] = {
            { CUBE_OP_F, CUBE_OP_U, CUBE_OP_D, CUBE_OP_L, CUBE_OP_R },
            { CUBE_OP_U, CUBE_OP_D, CUBE_OP_L, CUBE_OP_R, CUBE_OP_B },
            { CUBE_OP_B, CUBE_OP_R, CUBE_OP_U },
        };
        static int stepparams[][4] = {
            { 2 , 0, 5, 0 }, //+ fcross0
            { 4 , 0, 5, 2 }, //- fcross0
            { 8 , 0, 5, 2 }, //+-fcross1
            { 9 , 0, 5, 3 }, //+ fcorners
            { 10, 0, 5, 4 }, //..
            { 11, 0, 5, 5 }, //..
            { 12, 0, 5, 5 }, //- fcorners
            { 13, 1, 5, 6 }, //+ medges
            { 14, 1, 5, 6 }, //..
            { 15, 1, 5, 7 }, //..
            { 16, 1, 5, 8 }, //- medges
            { 18, 1, 5, 10}, //+ bcross
            { 20, 1, 5, 11}, //- bcross
            { 21, 1, 5, 11}, //+ bsurface
            { 24, 1, 5, 11}, //- bsurface
            { 26, 2, 3, 12}, //+ bcorners
            { 28, 2, 3, 12}, //- bcorners
            { 32, 2, 2, 12}, //+-bedges
            { 0 , 0, 0, 0 },
        };
        CUBE *start = c;
        CUBE *find  = NULL;
        int   i;
        for (i=0; stepparams[i][0]; i++) {
            find = search(&t, start, stepparams[i][0], oplisttab[stepparams[i][1]], stepparams[i][2], stepparams[i][3]);
            if (find) {
                if (find != start) {
                    start = find;
                    *c    =*find;
                    print_solve_oplist(find);
                    if (stepparams[i][0] != 32) cube_render(c);
                }
            } else {
                printf("can't solve !\n");
                goto done;
            }
        }
        printf("\ncube solved !\n");
    }

done:
    search_table_destroy(&t);
}

static void cube_input(CUBE *c)
{
    char str[256];

    printf("please input F surface of cube:\n");
    scanf("%c %c %c %c %c %c %c %c %c",
        &(c->f[0][0]), &(c->f[0][1]), &(c->f[0][2]),
        &(c->f[1][0]), &(c->f[1][1]), &(c->f[1][2]),
        &(c->f[2][0]), &(c->f[2][1]), &(c->f[2][2]));
    gets(str);

    printf("please input U surface of cube:\n");
    scanf("%c %c %c %c %c %c %c %c %c",
        &(c->u[0][0]), &(c->u[0][1]), &(c->u[0][2]),
        &(c->u[1][0]), &(c->u[1][1]), &(c->u[1][2]),
        &(c->u[2][0]), &(c->u[2][1]), &(c->u[2][2]));
    gets(str);

    printf("please input D surface of cube:\n");
    scanf("%c %c %c %c %c %c %c %c %c",
        &(c->d[0][0]), &(c->d[0][1]), &(c->d[0][2]),
        &(c->d[1][0]), &(c->d[1][1]), &(c->d[1][2]),
        &(c->d[2][0]), &(c->d[2][1]), &(c->d[2][2]));
    gets(str);

    printf("please input L surface of cube:\n");
    scanf("%c %c %c %c %c %c %c %c %c",
        &(c->l[0][0]), &(c->l[0][1]), &(c->l[0][2]),
        &(c->l[1][0]), &(c->l[1][1]), &(c->l[1][2]),
        &(c->l[2][0]), &(c->l[2][1]), &(c->l[2][2]));
    gets(str);

    printf("please input R surface of cube:\n");
    scanf("%c %c %c %c %c %c %c %c %c",
        &(c->r[0][0]), &(c->r[0][1]), &(c->r[0][2]),
        &(c->r[1][0]), &(c->r[1][1]), &(c->r[1][2]),
        &(c->r[2][0]), &(c->r[2][1]), &(c->r[2][2]));
    gets(str);

    printf("please input B surface of cube:\n");
    scanf("%c %c %c %c %c %c %c %c %c",
        &(c->b[0][0]), &(c->b[0][1]), &(c->b[0][2]),
        &(c->b[1][0]), &(c->b[1][1]), &(c->b[1][2]),
        &(c->b[2][0]), &(c->b[2][1]), &(c->b[2][2]));
    gets(str);
}

static void show_help(void)
{
    printf(
        "\n"
        "available commands:\n\n"
        "f f2 f' b b2 b' u u2 u' d d2 d' l l2 l' r r2 r'\n"
        "init rand input solve help exit\n\n"
        "note: all command is case sensitive.\n"
    );
}

int main(void)
{
    char cmd[128];
    char str[256];
    CUBE c;

    // init cube
    cube_init(&c);

    show_help();
    while (1) {
        cube_render(&c);
        printf("command: ");
        scanf("%s", cmd);
        if (strcmp(cmd, "f") == 0) {
            cube_f(&c);
        } else if (strcmp(cmd, "f2") == 0) {
            cube_f(&c); cube_f(&c);
        } else if (strcmp(cmd, "f'") == 0) {
            cube_f(&c); cube_f(&c); cube_f(&c);
        } else if (strcmp(cmd, "b" ) == 0) {
            cube_b(&c);
        } else if (strcmp(cmd, "b2") == 0) {
            cube_b(&c); cube_b(&c);
        } else if (strcmp(cmd, "b'") == 0) {
            cube_b(&c); cube_b(&c); cube_b(&c);
        } else if (strcmp(cmd, "u" ) == 0) {
            cube_u(&c);
        } else if (strcmp(cmd, "u2") == 0) {
            cube_u(&c); cube_u(&c);
        } else if (strcmp(cmd, "u'") == 0) {
            cube_u(&c); cube_u(&c); cube_u(&c);
        } else if (strcmp(cmd, "d" ) == 0) {
            cube_d(&c);
        } else if (strcmp(cmd, "d2") == 0) {
            cube_d(&c); cube_d(&c);
        } else if (strcmp(cmd, "d'") == 0) {
            cube_d(&c); cube_d(&c); cube_d(&c);
        } else if (strcmp(cmd, "l" ) == 0) {
            cube_l(&c);
        } else if (strcmp(cmd, "l2") == 0) {
            cube_l(&c); cube_l(&c);
        } else if (strcmp(cmd, "l'") == 0) {
            cube_l(&c); cube_l(&c); cube_l(&c);
        } else if (strcmp(cmd, "r" ) == 0) {
            cube_r(&c);
        } else if (strcmp(cmd, "r2") == 0) {
            cube_r(&c); cube_r(&c);
        } else if (strcmp(cmd, "r'") == 0) {
            cube_r(&c); cube_r(&c); cube_r(&c);
        } else if (strcmp(cmd, "init") == 0) {
            cube_init(&c);
        } else if (strcmp(cmd, "rand") == 0) {
            gets(str);
            cube_rand(&c, atoi(str) == 0 ? 100 : atoi(str));
        } else if (strcmp(cmd, "input") == 0) {
            cube_input(&c);
        } else if (strcmp(cmd, "solve") == 0) {
            cube_solve(&c);
        } else if (strcmp(cmd, "help") == 0) {
            show_help();
        } else if (strcmp(cmd, "exit") == 0) {
            break;
        } else {
            printf("unsupported command !\n");
        }
        printf("\n");
    }

    return 0;
}



[此贴子已经被作者于2020-3-13 09:23编辑过]

2018-12-09 21:33
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
代码直接贴出来吧

VC 可以编译运行,或者用 mingw 的 gcc 编译都可以
2018-12-09 21:34
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
cube.rar (10.5 KB)

编译好的测试程序
2018-12-09 21:46
幻紫灵心
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山咔咔里面
等 级:贵宾
威 望:53
帖 子:395
专家分:2640
注 册:2018-3-30
收藏
得分:4 
有点强啊

saber,别哭.
2018-12-09 22:02
yyglxc
Rank: 1
等 级:新手上路
帖 子:4
专家分:4
注 册:2018-12-4
收藏
得分:4 
厉害!看看学习一下!
2018-12-10 06:33
zc2546885976
Rank: 1
等 级:新手上路
帖 子:15
专家分:4
注 册:2018-11-13
收藏
得分:4 
回复 2楼 RockCarry
2018-12-10 10:56
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
一些符号的含义:
F - 正面,程序运行后白色的这一面
B - 背面,黄色面
L - 左面,紫色面(标准魔方应该是橙色,但是 windows 控制台无法显示橙色,用紫色替代)
R - 右面,红色面
U - 上面,蓝色面
D - 下面,绿色面


命令说明:

魔方操作命令:
f  - 正面顺时针旋转
f2 - 正面 180 度旋转
f' - 正面逆时针旋转

其他面以此类推:
f2 f' b b2 b' u u2 u' d d2 d' l l2 l' r r2 r'

init  - 魔方复位
rand  - 随机打乱魔方,可以直接 rand 或者 rand n,n 为随机打乱次数
input - 输入魔方状态,按照提示输入即可
solve - 自动还原魔方
help  - 帮助信息
exit  - 退出程序

所有命令都是用小写字母。


2018-12-10 11:13
caosule
Rank: 1
等 级:新手上路
帖 子:4
专家分:4
注 册:2018-11-23
收藏
得分:4 
2018-12-10 18:16
powerfrank
Rank: 2
等 级:论坛游民
帖 子:31
专家分:37
注 册:2018-4-25
收藏
得分:4 
牛BI啊
2018-12-11 08:51
快速回复:[原创] 不到 800 行代码,彻底搞定魔方还原问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020081 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved