Procházet zdrojové kódy

Add rubiks_cube_scrambler from https://github.com/xMasterX/all-the-plugins

git-subtree-dir: rubiks_cube_scrambler
git-subtree-mainline: 651a6dbb399e370b7aecebe54387789629c1d51b
git-subtree-split: 6dcdaf633c7fc898740b13715d1aa9a00110191a
Willy-JL před 2 roky
rodič
revize
e27ad3d1fd

+ 1 - 0
rubiks_cube_scrambler/.gitsubtree

@@ -0,0 +1 @@
+https://github.com/xMasterX/all-the-plugins dev apps_source_code/rubiks_cube_scrambler

+ 21 - 0
rubiks_cube_scrambler/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 RaZe
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 13 - 0
rubiks_cube_scrambler/README.md

@@ -0,0 +1,13 @@
+# Rubik's Cube Scrambler FAP
+
+## Where to start?
+Install the .fap file and put it in your apps folder
+
+## What does what?
+The On/Off button toggles the vibration notification on and off. The "New" button generates a new scramble. The scramble letters correspond with the following moves: R = Right, L = Left, U = Up, D = Down, F = Front, B = Back. The number after the letter indicates how many times to turn that face. For example, R2 means to turn the right face twice. The ' symbol indicates a counter-clockwise turn. For example, R' means to turn the right face counter-clockwise once.
+
+<img src="assets/1.png">
+
+# A special thanks to Tanish for their c scrambler example 🙏
+https://github.com/TanishBhongade/RubiksCubeScrambler-C/
+

+ 24 - 0
rubiks_cube_scrambler/application.fam

@@ -0,0 +1,24 @@
+# COMPILE ISTRUCTIONS:
+
+# Clean the code and remove old binaries/compilation artefact
+# ./fbt -c fap_rubiks_cube_scrambler
+
+# Compile FAP
+# ./fbt fap_rubiks_cube_scrambler
+
+# Run application directly inside the Flip.x0
+# ./fbt launch_app APPSRC=rubiks_cube_scrambler
+
+App(
+    appid="rubiks_cube_scrambler",
+    name="Rubik's Cube Scrambler",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="rubiks_cube_scrambler_main",
+    stack_size=1 * 1024,
+    fap_category="Games",
+    fap_icon="cube.png",
+    fap_author="@RaZeSloth",
+    fap_weburl="https://github.com/RaZeSloth/flipperzero-rubiks-cube-scrambler",
+    fap_version="1.1",
+    fap_description="App generates random moves to scramble a Rubik's cube.",
+)

binární
rubiks_cube_scrambler/cube.png


binární
rubiks_cube_scrambler/img/1.png


binární
rubiks_cube_scrambler/img/2.png


+ 116 - 0
rubiks_cube_scrambler/rubiks_cube_scrambler.c

@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <furi.h>
+#include <gui/gui.h>
+#include <input/input.h>
+#include <gui/elements.h>
+#include <furi_hal.h>
+
+#include "scrambler.h"
+#include "furi_hal_random.h"
+
+int scrambleStarted = 0;
+char scramble_str[100] = {0};
+char scramble_start[100] = {0};
+char scramble_end[100] = {0};
+int notifications_enabled = 0;
+
+static void success_vibration() {
+    furi_hal_vibro_on(false);
+    furi_hal_vibro_on(true);
+    furi_delay_ms(50);
+    furi_hal_vibro_on(false);
+    return;
+}
+void split_array(char original[], int size, char first[], char second[]) {
+    int mid = size / 2;
+    if(size % 2 != 0) {
+        mid++;
+    }
+    int first_index = 0, second_index = 0;
+    for(int i = 0; i < size; i++) {
+        if(i < mid) {
+            first[first_index++] = original[i];
+        } else {
+            if(i == mid && (original[i] == '2' || original[i] == '\'')) {
+                continue;
+            }
+            second[second_index++] = original[i];
+        }
+    }
+    first[first_index] = '\0';
+    second[second_index] = '\0';
+}
+
+static void draw_callback(Canvas* canvas, void* ctx) {
+    UNUSED(ctx);
+    canvas_clear(canvas);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str(canvas, 4, 13, "Rubik's Cube Scrambler");
+
+    if(scrambleStarted) {
+        genScramble();
+        scrambleReplace();
+        strcpy(scramble_str, printData());
+        if(notifications_enabled) {
+            success_vibration();
+        }
+        split_array(scramble_str, strlen(scramble_str), scramble_start, scramble_end);
+        scrambleStarted = 0;
+    }
+    canvas_set_font(canvas, FontSecondary);
+    canvas_draw_str_aligned(canvas, 64, 28, AlignCenter, AlignCenter, scramble_start);
+    canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignCenter, scramble_end);
+    elements_button_center(canvas, "New");
+
+    elements_button_left(canvas, notifications_enabled ? "On" : "Off");
+};
+
+static void input_callback(InputEvent* input_event, void* ctx) {
+    furi_assert(ctx);
+    FuriMessageQueue* event_queue = ctx;
+    furi_message_queue_put(event_queue, input_event, FuriWaitForever);
+}
+
+int32_t rubiks_cube_scrambler_main(void* p) {
+    UNUSED(p);
+    InputEvent event;
+
+    FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
+
+    ViewPort* view_port = view_port_alloc();
+
+    view_port_draw_callback_set(view_port, draw_callback, NULL);
+
+    view_port_input_callback_set(view_port, input_callback, event_queue);
+
+    Gui* gui = furi_record_open(RECORD_GUI);
+    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+
+    while(true) {
+        furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk);
+
+        if(event.key == InputKeyOk && event.type == InputTypeShort) {
+            scrambleStarted = 1;
+        }
+        if(event.key == InputKeyLeft && event.type == InputTypeShort) {
+            if(notifications_enabled) {
+                notifications_enabled = 0;
+            } else {
+                notifications_enabled = 1;
+                success_vibration();
+            }
+        }
+        if(event.key == InputKeyBack) {
+            break;
+        }
+        view_port_update(view_port);
+    }
+
+    furi_message_queue_free(event_queue);
+
+    gui_remove_view_port(gui, view_port);
+
+    view_port_free(view_port);
+    furi_record_close(RECORD_GUI);
+    return 0;
+}

+ 99 - 0
rubiks_cube_scrambler/scrambler.c

@@ -0,0 +1,99 @@
+/*
+Authors: Tanish Bhongade and RaZe
+*/
+
+#include <stdio.h>
+#include <furi.h>
+#include <gui/gui.h>
+#include "furi_hal_random.h"
+#include <input/input.h>
+#include <gui/elements.h>
+#include "scrambler.h"
+
+// 6 moves along with direction
+char moves[6] = {'R', 'U', 'F', 'B', 'L', 'D'};
+char dir[4] = {' ', '\'', '2'};
+const int SLEN = 20;
+#define RESULT_SIZE 100
+// Structure which holds main scramble
+struct GetScramble {
+    char mainScramble[25][3];
+};
+struct GetScramble a; // Its object
+
+// Function prototypes to avoid bugs
+void valid();
+int getRand(int upr, int lwr);
+void writeToFile();
+
+// Main function
+/* int main(){
+	genScramble ();//Calling genScramble
+	scrambleReplace();//Calling scrambleReplace
+	valid();//Calling valid to validate the scramble
+	printData ();//Printing the final scramble
+	//writeToFile();//If you want to write to a file, please uncomment this
+
+	return 0;
+} */
+
+void genScramble() {
+    // Stage 1
+    for(int i = 0; i < SLEN; i++) {
+        strcpy(a.mainScramble[i], "00");
+    }
+    // This makes array like this 00 00 00.......
+}
+
+void scrambleReplace() {
+    // Stage 2
+    // Actual process begins here
+
+    // Initialize the mainScramble array with all the possible moves
+    for(int i = 0; i < SLEN; i++) {
+        a.mainScramble[i][0] = moves[furi_hal_random_get() % 6];
+        a.mainScramble[i][1] = dir[furi_hal_random_get() % 3];
+    }
+
+    // Perform the Fisher-Yates shuffle
+    for(int i = 6 - 1; i > 0; i--) {
+        int j = rand() % (i + 1);
+        char temp[3];
+        strcpy(temp, a.mainScramble[i]);
+        strcpy(a.mainScramble[i], a.mainScramble[j]);
+        strcpy(a.mainScramble[j], temp);
+    }
+
+    // Select the first 10 elements as the scramble, using only the first three elements of the dir array
+    for(int i = 0; i < SLEN; i++) {
+        a.mainScramble[i][1] = dir[furi_hal_random_get() % 3];
+    }
+    for(int i = 1; i < SLEN; i++) {
+        while(a.mainScramble[i][0] == a.mainScramble[i - 2][0] ||
+              a.mainScramble[i][0] == a.mainScramble[i - 1][0]) {
+            a.mainScramble[i][0] = moves[furi_hal_random_get() % 5];
+        }
+    }
+}
+
+// Let this function be here for now till I find out what is causing the extra space bug in the scrambles
+void remove_double_spaces(char* str) {
+    int i, j;
+    int len = strlen(str);
+    for(i = 0, j = 0; i < len; i++, j++) {
+        if(str[i] == ' ' && str[i + 1] == ' ') {
+            i++;
+        }
+        str[j] = str[i];
+    }
+    str[j] = '\0';
+}
+char* printData() {
+    static char result[RESULT_SIZE];
+    int offset = 0;
+    for(int loop = 0; loop < SLEN; loop++) {
+        offset += snprintf(result + offset, RESULT_SIZE - offset, "%s ", a.mainScramble[loop]);
+    }
+    remove_double_spaces(result);
+    return result;
+}

+ 3 - 0
rubiks_cube_scrambler/scrambler.h

@@ -0,0 +1,3 @@
+void scrambleReplace();
+void genScramble();
+char* printData();