我最近一直在从事一个项目,该项目包括一个Rubik的Cube加密生成器。基本上,程序应生成并显示随机的多维数据集符号,以便用户可以跟随每个动作并获得一个相当混乱的多维数据集。标记包括:“ R”用于右移图层,“ L”用于左移图层,“ F”用于旋转顶层,“ D”用于向下,“ U”用于向上,“ B”用于后向。因此,您总共有6个面“ R,L,U,D,F,B”。这些符号中的任何一个之后的提案表示逆时针移动该层,“ 2”表示将该层移动两次。问题是您不能像“ R2”一样将相同的符号彼此相邻地重复,例如“ R,R”,也不能使“ R,R'”彼此相邻会互相抵消。我的解决方案是制作一个二维数组,用于存储每种类型的3组符号。
string notation_group[row][column] = { { "R ", "L ", "F ", "B ", "U ", "D " },
{"R' ", "L' ", "F' ", "B' ", "U' ", "D' "}, { "R2", "L2", "F2", "B2", "U2", "D2"} };
这意味着,只要程序从这些组中的任何一个中选择一个随机列,该程序就必须防止下一个生成的符号选择任何其他组中的相同列。因此,假设程序选择了第一组“ R”的第一个元素,那么对于下一次迭代,它可以选择“ R”,“ R”和“ R2”以外的任何符号,它们都属于第一列他们各自的群体。因此,程序要做的就是不要在下次迭代中选择该列。
我使用了一个“ temp”变量来记住当前随机生成的表示法,并将其与下一个表示法进行比较,并在它们相等时生成一个新的表示法。
int temp;
scrambled_notation[i] = notation_group[pickGroup][pickColumn];
temp = pickColumn;
pickColumn = 0 + rand() % 6;
while (temp == pickColumn) {
pickColumn = 0 + rand() % 6;
}
它确实有效,但是仍然存在另一个问题,每当您将诸如“ R,L”或“ R,L',R”之类的内容彼此相邻重复多次时,它们将再次相互抵消,不会造成任何影响在多维数据集上。有什么想法可以防止两个相对的边彼此重复多次?我将非常感谢您的帮助。
void initScramble(const int, string[][6], string[]);
int main() {
srand(time(0));
const int row = 3, column = 6;
string notation_group[row][column] = { { "R", "L", "F", "B", "U", "D" },
{"R'", "L'", "F'", "B'", "U'", "D'"}, { "R2", "L2", "F2", "B2", "U2", "D2"} };
const int scrambleSize = 22;
string scrambled_notation[scrambleSize];
cout << "SCRAMBLE: " << endl;
initScramble(scrambleSize, notation_group, scrambled_notation);
system("pause");
return 0;
}
void initScramble(const int scrambleSize, string notation_group[][6], string scrambled_notation[]) {
int pickColumn = 0 + rand() % 6;
while (true) {
cin.get();
for (int i = 0; i < scrambleSize; i++) {
int pickGroup = 0 + rand() % 3;
int temp;
scrambled_notation[i] = notation_group[pickGroup][pickColumn];
temp = pickColumn;
pickColumn = 0 + rand() % 6;
while (temp == pickColumn) {
pickColumn = 0 + rand() % 6;
}
}
for (int i = 0; i < scrambleSize; i++) {
cout << scrambled_notation[i] << " ";
}
cin.get();
system("CLS");
}
}
答案 0 :(得分:1)
您必须寻找最后两个动作,只要它们是可交换的。如果不是,则只检查最后一步。每对列都是可交换的,从而简化了这一过程:
void initScramble(const int scrambleSize, string notation_group[][6], string scrambled_notation[]) {
while (true) {
int lastColumn = 7; // Invalid columns
int beforeLastColumn = 7;
cin.get();
for (int i = 0; i < scrambleSize; i++) {
int pickGroup = 0 + rand() % 3;
int pickColumn = 0 + rand() % 6;
bool isCommutative = (lastColumn / 2) == (beforeLastColumn / 2);
while (pickColumn == lastColumn || isCommutative && pickColumn == beforeLastColumn) {
pickColumn = 0 + rand() % 6;
}
scrambled_notation[i] = notation_group[pickGroup][pickColumn];
beforeLastColumn = lastColumn;
lastColumn = pickColumn;
}
for (int i = 0; i < scrambleSize; i++) {
cout << scrambled_notation[i] << " ";
}
cin.get();
system("CLS");
}
}
您不必进一步看,因为按照加扰规则,您只能进行2个可交换的连续移动。例如,“ L,R,L”和“ L,R,R”将被丢弃,因此将永远不会产生3个换向运动。