Skip to content

Commit

Permalink
Implement scramble and reset menu item modals
Browse files Browse the repository at this point in the history
  • Loading branch information
rayzchen committed Jun 8, 2024
1 parent f8eb08a commit 22cf2ff
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 52 deletions.
86 changes: 41 additions & 45 deletions control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,8 @@ void PuzzleController::startCellMove(CellLocation cell, RotateDirection directio
void PuzzleController::keyCallback(GLFWwindow* window, int key, int action, int mods, bool flip) {
if (renderer->animating) return;
if (action == GLFW_PRESS) {
status.clear();
if (mods == 0) {
if (!(key == GLFW_KEY_Z || key == GLFW_KEY_Y)) {
status.clear();
}
if (checkMiddleGyro(key, flip)) return;
if (checkDirectionalMove(window, key, flip)) return;

Expand All @@ -352,13 +350,6 @@ void PuzzleController::keyCallback(GLFWwindow* window, int key, int action, int
} else if (key == GLFW_KEY_Y) {
redoMove();
}
} else if (mods & GLFW_MOD_CONTROL) {
if (key == GLFW_KEY_F) {
resetPuzzle();
scramblePuzzle();
} else if (key == GLFW_KEY_R) {
resetPuzzle();
}
}
}
}
Expand All @@ -376,7 +367,7 @@ void PuzzleController::undoMove() {
renderer->scheduleMove(entry);
status = "Undid 1 move!";
} else {
status = "No moves left!";
status = "Error: nothing to undo!";
}
}

Expand All @@ -386,7 +377,7 @@ void PuzzleController::redoMove() {
renderer->scheduleMove(entry);
status = "Redid 1 move!";
} else {
status = "No moves left!";
status = "Error: nothing to redo!";
}
}

Expand Down Expand Up @@ -414,15 +405,17 @@ void rotate8bycell(std::array<int, 8>& cells, CellLocation cell) {
}
}

void PuzzleController::scramblePuzzle() {
void PuzzleController::scramblePuzzle(int scrambleLength) {
static std::discrete_distribution<int> typeDist({2, 3});
static std::uniform_int_distribution<int> directionDist(0, 5);
static std::discrete_distribution<int> cellDist({2, 2, 6, 6, 1, 1, 1, 1});
// only for visual effect, functionally unneeded
// FBUD only for visual effect, functionally unneeded
static std::uniform_int_distribution<int> boolDist(0, 1);
MoveEntry entry;
entry.type = TURN;
int scrambleLength = 45;
if (scrambleLength == 0) {
scrambleLength = 45;
}
CellLocation lastCell = (CellLocation)-1;
for (int i = 0; i < scrambleLength; i++) {
if (typeDist(rng) == 0 && entry.type != GYRO) {
Expand Down Expand Up @@ -464,37 +457,40 @@ void PuzzleController::scramblePuzzle() {
scramble.push_back(entry);
}

// R, L, U, D, F, B, O, I
// Reorient to HSC default orientation
std::array<int, 8> cells = {0, 1, 4, 5, 3, 2, 6, 7};
for (size_t i = 0; i < scramble.size(); i++) {
if (scramble[i].type == GYRO) {
rotate8bycell(cells, scramble[i].cell);
}
}
entry.type = GYRO;
std::array<int, 3> colorsToFix = {4, 2, 7};
for (int i = 0; i < 3; i++) {
int index = std::distance(cells.begin(), std::find(cells.begin(), cells.end(), colorsToFix[i]));
if (index != colorsToFix[i]) {
// Move to I
if (index == 6) {
entry.cell = LEFT;
scramble.push_back(entry);
scramble.push_back(entry);
rotate8bycell(cells, entry.cell);
rotate8bycell(cells, entry.cell);
} else if (index < 6) {
entry.cell = (CellLocation)(2 + index);
scramble.push_back(entry);
rotate8bycell(cells, entry.cell);
bool reorient = false;
if (reorient) {
// R, L, U, D, F, B, O, I
// Reorient to HSC default orientation
std::array<int, 8> cells = {0, 1, 4, 5, 3, 2, 6, 7};
for (size_t i = 0; i < scramble.size(); i++) {
if (scramble[i].type == GYRO) {
rotate8bycell(cells, scramble[i].cell);
}
// Move to desired location (gyro opposite)
if (colorsToFix[i] != 7) {
// Don't gyro if inner
entry.cell = (CellLocation)(2 + colorsToFix[i] + 1);
scramble.push_back(entry);
rotate8bycell(cells, entry.cell);
}
entry.type = GYRO;
std::array<int, 3> colorsToFix = {4, 2, 7};
for (int i = 0; i < 3; i++) {
int index = std::distance(cells.begin(), std::find(cells.begin(), cells.end(), colorsToFix[i]));
if (index != colorsToFix[i]) {
// Move to I
if (index == 6) {
entry.cell = LEFT;
scramble.push_back(entry);
scramble.push_back(entry);
rotate8bycell(cells, entry.cell);
rotate8bycell(cells, entry.cell);
} else if (index < 6) {
entry.cell = (CellLocation)(2 + index);
scramble.push_back(entry);
rotate8bycell(cells, entry.cell);
}
// Move to desired location (gyro opposite)
if (colorsToFix[i] != 7) {
// Don't gyro if inner
entry.cell = (CellLocation)(2 + colorsToFix[i] + 1);
scramble.push_back(entry);
rotate8bycell(cells, entry.cell);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion control.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class PuzzleController {
void getScrambleTwists();

void resetPuzzle();
void scramblePuzzle();
void scramblePuzzle(int scrambleLength);
void undoMove();
void redoMove();

Expand Down
80 changes: 78 additions & 2 deletions gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ GuiRenderer::GuiRenderer(GLFWwindow *window, PuzzleController *controller, int w
this->width = width;
this->height = height;
showHelp = false;
modalToggle = false;

ImGui::CreateContext();
ImGui_ImplGlfw_InitForOpenGL(window, true);
Expand Down Expand Up @@ -146,6 +147,7 @@ void GuiRenderer::renderGui() {
ImGui::PushFont(uiFont);
displayMenuBar();
displayStatusBar();
displayModal();
#ifndef NO_DEMO_WINDOW
if (showDemoWindow) {
ImGui::ShowDemoWindow();
Expand All @@ -164,15 +166,23 @@ void GuiRenderer::renderGui() {
void GuiRenderer::displayMenuBar() {
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Open", "Ctrl+O", false, false)) {}
if (ImGui::MenuItem("Open", "Ctrl+O", false, false)) checkUnsaved("open another file");
if (ImGui::MenuItem("Save", "Ctrl+S", false, false)) {}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Edit")) {
if (ImGui::MenuItem("Undo", "Z", false, history->canUndo())) controller->undoMove();
if (ImGui::MenuItem("Redo", "Y", false, history->canRedo())) controller->redoMove();
ImGui::Separator();
if (ImGui::MenuItem("Reset", "Ctrl+R")) controller->resetPuzzle();
if (ImGui::MenuItem("Reset", "Ctrl+R")) checkUnsaved("reset puzzle");
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Scramble")) {
for (int i = 1; i < 9; i++) {
if (ImGui::MenuItem(std::to_string(i).c_str(), NULL)) checkUnsaved("scramble", i);
}
ImGui::Separator();
if (ImGui::MenuItem("Full", "Ctrl+F")) checkUnsaved("scramble", 0);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Tools")) {
Expand All @@ -181,10 +191,37 @@ void GuiRenderer::displayMenuBar() {
#endif
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help")) {
if (ImGui::MenuItem("Show help", "H")) toggleHelp();
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
}

void GuiRenderer::displayModal() {
if (modalToggle) {
ImGui::SetNextWindowSize({100, 0});
ImGui::OpenPopup("Unsaved changes");
modalToggle = false;
}
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("Unsaved changes", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextWrapped("Discard puzzle state and %s?", modalText.c_str());
if (ImGui::Button("Yes", ImVec2(80, 0))) {
ImGui::CloseCurrentPopup();
resolveModal();
}
ImGui::SetItemDefaultFocus();
ImGui::SameLine();
if (ImGui::Button("No", ImVec2(80, 0))) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}

void GuiRenderer::displayHUD() {
#ifdef __EMSCRIPTEN__
EM_ASM(document.documentElement.style.removeProperty(UTF8ToString($0)), "cursor");
Expand Down Expand Up @@ -249,3 +286,42 @@ void GuiRenderer::displayStatusBar() {
void GuiRenderer::toggleHelp() {
showHelp = !showHelp;
}

void GuiRenderer::keyCallback(GLFWwindow* window, int key, int action, int mods) {
if (action == GLFW_PRESS) {
if (mods == 0) {
if (key == GLFW_KEY_H) {
toggleHelp();
}
} else if (mods & GLFW_MOD_CONTROL) {
if (key == GLFW_KEY_F) {
checkUnsaved("scramble", 0);
} else if (key == GLFW_KEY_R) {
checkUnsaved("reset puzzle");
}
}
}
}

void GuiRenderer::checkUnsaved(std::string action, int argument) {
modalArg = argument;
checkUnsaved(action);
}

void GuiRenderer::checkUnsaved(std::string action) {
modalText = action;
modalToggle = true;
}

void GuiRenderer::resolveModal() {
if (modalText == "reset puzzle") {
controller->resetPuzzle();
} else if (modalText == "scramble") {
controller->resetPuzzle();
controller->scramblePuzzle(modalArg);
} else if (modalText == "open another file") {
//
} else if (modalText == "exit") {
//
}
}
11 changes: 9 additions & 2 deletions gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,24 @@ class GuiRenderer {
void renderGui();
void displayMenuBar();
void displayHUD();
void displayModal();
void displayStatusBar();
void toggleHelp();
bool captureMouse();

void resetPuzzle();
void keyCallback(GLFWwindow* window, int key, int action, int mods);
void resolveModal();
void toggleHelp();
void checkUnsaved(std::string action);
void checkUnsaved(std::string action, int argument);

private:
PuzzleController *controller;
MoveHistory *history;
int width, height;
bool showHelp;
bool modalToggle;
std::string modalText;
int modalArg;
ImFont *hudFont, *uiFont;

#ifndef NO_DEMO_WINDOW
Expand Down
3 changes: 1 addition & 2 deletions window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ void Window::setCallbacks() {
});
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
Window::current->keyCallback(window, key, scancode, action, mods);
Window::current->gui->keyCallback(window, key, action, mods);
Window::current->controller->keyCallback(window, key, action, mods, Window::current->camera->inputFlipped());
});
glfwSetWindowPosCallback(window, [](GLFWwindow* window, int xpos, int ypos) {
Expand Down Expand Up @@ -243,8 +244,6 @@ void Window::keyCallback(GLFWwindow* window, int key, int scancode, int action,
glfwSwapInterval(vsync);
}
fullscreen = !fullscreen;
} else if (key == GLFW_KEY_H) {
gui->toggleHelp();
}
}
}
Expand Down

0 comments on commit 22cf2ff

Please sign in to comment.