Просмотр исходного кода

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

git-subtree-dir: 4inrow
git-subtree-mainline: 101ba1c5d85caf0cab2d864b216f26046865806a
git-subtree-split: 695acb26f00ed7affd26ce44bd71f9043cc8ec65
Willy-JL 2 лет назад
Родитель
Сommit
d8d2691abe
8 измененных файлов с 344 добавлено и 0 удалено
  1. 1 0
      4inrow/.gitsubtree
  2. 325 0
      4inrow/4inrow.c
  3. BIN
      4inrow/4inrow_10px.png
  4. 1 0
      4inrow/ReadMe.md
  5. 17 0
      4inrow/application.fam
  6. BIN
      4inrow/img/1.png
  7. BIN
      4inrow/img/2.png
  8. BIN
      4inrow/img/3.png

+ 1 - 0
4inrow/.gitsubtree

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

+ 325 - 0
4inrow/4inrow.c

@@ -0,0 +1,325 @@
+#include <stdio.h>
+#include <furi.h>
+#include <gui/gui.h>
+#include <input/input.h>
+#include <notification/notification.h>
+#include <notification/notification_messages.h>
+#include <dolphin/dolphin.h>
+
+static int matrix[6][7] = {0};
+static int cursorx = 3;
+static int cursory = 5;
+static int player = 1;
+static int scoreX = 0;
+static int scoreO = 0;
+
+typedef struct {
+    FuriMutex* mutex;
+} FourInRowState;
+
+void init() {
+    for(size_t i = 0; i < 6; i++) {
+        for(size_t j = 0; j < 7; j++) {
+            matrix[i][j] = 0;
+        }
+    }
+    cursorx = 3;
+    cursory = 5;
+    player = 1;
+}
+
+const NotificationSequence end = {
+    &message_vibro_on,
+
+    &message_note_ds4,
+    &message_delay_10,
+    &message_sound_off,
+    &message_delay_10,
+
+    &message_note_ds4,
+    &message_delay_10,
+    &message_sound_off,
+    &message_delay_10,
+
+    &message_note_ds4,
+    &message_delay_10,
+    &message_sound_off,
+    &message_delay_10,
+
+    &message_vibro_off,
+    NULL,
+};
+
+void intToStr(int num, char* str) {
+    int i = 0, sign = 0;
+
+    if(num < 0) {
+        num = -num;
+        sign = 1;
+    }
+
+    do {
+        str[i++] = num % 10 + '0';
+        num /= 10;
+    } while(num > 0);
+
+    if(sign) {
+        str[i++] = '-';
+    }
+
+    str[i] = '\0';
+
+    // Reverse the string
+    int j, len = i;
+    char temp;
+    for(j = 0; j < len / 2; j++) {
+        temp = str[j];
+        str[j] = str[len - j - 1];
+        str[len - j - 1] = temp;
+    }
+}
+
+int next_height(int x) {
+    if(matrix[0][x] != 0) {
+        return -1;
+    }
+    for(size_t y = 1; y < 6; y++) {
+        if(matrix[y][x] != 0) {
+            return y - 1;
+        }
+    }
+    return 5;
+}
+
+int wincheck() {
+    for(size_t y = 0; y <= 2; y++) {
+        for(size_t x = 0; x <= 6; x++) {
+            if(matrix[y][x] != 0 && matrix[y][x] == matrix[y + 1][x] &&
+               matrix[y][x] == matrix[y + 2][x] && matrix[y][x] == matrix[y + 3][x]) {
+                return matrix[y][x];
+            }
+        }
+    }
+
+    for(size_t y = 0; y <= 5; y++) {
+        for(size_t x = 0; x <= 3; x++) {
+            if(matrix[y][x] != 0 && matrix[y][x] == matrix[y][x + 1] &&
+               matrix[y][x] == matrix[y][x + 2] && matrix[y][x] == matrix[y][x + 3]) {
+                return matrix[y][x];
+            }
+        }
+    }
+
+    for(size_t y = 0; y <= 2; y++) {
+        for(size_t x = 0; x <= 3; x++) {
+            if(matrix[y][x] != 0 && matrix[y][x] == matrix[y + 1][x + 1] &&
+               matrix[y][x] == matrix[y + 2][x + 2] && matrix[y][x] == matrix[y + 3][x + 3]) {
+                return matrix[y][x];
+            }
+        }
+    }
+
+    for(size_t y = 3; y <= 5; y++) {
+        for(size_t x = 0; x <= 3; x++) {
+            if(matrix[y][x] != 0 && matrix[y][x] == matrix[y - 1][x + 1] &&
+               matrix[y][x] == matrix[y - 2][x + 2] && matrix[y][x] == matrix[y - 3][x + 3]) {
+                return matrix[y][x];
+            }
+        }
+    }
+
+    bool tf = true;
+    for(size_t y = 0; y < 6; y++) {
+        for(size_t x = 0; x < 7; x++) {
+            if(matrix[y][x] == 0) {
+                tf = false;
+            }
+        }
+    }
+    if(tf) {
+        return 0;
+    }
+
+    return -1;
+}
+
+static void draw_callback(Canvas* canvas, void* ctx) {
+    furi_assert(ctx);
+    const FourInRowState* fourinrow_state = ctx;
+
+    furi_mutex_acquire(fourinrow_state->mutex, FuriWaitForever);
+    canvas_clear(canvas);
+
+    if(wincheck() != -1) {
+        canvas_set_font(canvas, FontPrimary);
+
+        if(wincheck() == 0) {
+            canvas_draw_str(canvas, 30, 35, "Draw! O_o");
+        }
+        if(wincheck() == 1) {
+            canvas_draw_str(canvas, 30, 35, "Player X win!");
+        }
+        if(wincheck() == 2) {
+            canvas_draw_str(canvas, 30, 35, "Player O win!");
+        }
+
+        furi_mutex_release(fourinrow_state->mutex);
+
+        return;
+    }
+
+    for(size_t i = 0; i < 6; i++) {
+        for(size_t j = 0; j < 7; j++) {
+            char el[2];
+            switch(matrix[i][j]) {
+            case 0:
+                strcpy(el, "_\0");
+                break;
+
+            case 1:
+                strcpy(el, "X\0");
+                break;
+
+            case 2:
+                strcpy(el, "O\0");
+                break;
+            }
+            canvas_draw_str(canvas, j * 10 + 10, i * 10 + 10, el);
+        }
+    }
+    canvas_draw_str(canvas, cursorx * 10 + 8, cursory * 10 + 10, "[ ]");
+
+    if(player == 1) {
+        canvas_draw_str(canvas, 80, 10, "Turn: X");
+    }
+    if(player == 2) {
+        canvas_draw_str(canvas, 80, 10, "Turn: O");
+    }
+    char scX[1];
+    intToStr(scoreX, scX);
+    char scO[1];
+    intToStr(scoreO, scO);
+
+    canvas_draw_str(canvas, 80, 20, "X:");
+    canvas_draw_str(canvas, 90, 20, scX);
+
+    canvas_draw_str(canvas, 80, 30, "O:");
+    canvas_draw_str(canvas, 90, 30, scO);
+
+    furi_mutex_release(fourinrow_state->mutex);
+}
+
+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 four_in_row_app(void* p) {
+    UNUSED(p);
+
+    // Текущее событие типа InputEvent
+    InputEvent event;
+    // Очередь событий на 8 элементов размера InputEvent
+    FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
+
+    FourInRowState* fourinrow_state = malloc(sizeof(FourInRowState));
+
+    fourinrow_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); // Alloc Mutex
+    if(!fourinrow_state->mutex) {
+        FURI_LOG_E("4inRow", "cannot create mutex\r\n");
+        furi_message_queue_free(event_queue);
+        free(fourinrow_state);
+        return 255;
+    }
+
+    dolphin_deed(DolphinDeedPluginGameStart);
+
+    // Создаем новый view port
+    ViewPort* view_port = view_port_alloc();
+    // Создаем callback отрисовки, без контекста
+    view_port_draw_callback_set(view_port, draw_callback, fourinrow_state);
+    // Создаем callback нажатий на клавиши, в качестве контекста передаем
+    // нашу очередь сообщений, чтоб запихивать в неё эти события
+    view_port_input_callback_set(view_port, input_callback, event_queue);
+
+    // Создаем GUI приложения
+    Gui* gui = furi_record_open(RECORD_GUI);
+    // Подключаем view port к GUI в полноэкранном режиме
+    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+    NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
+    notification_message_block(notification, &sequence_display_backlight_enforce_on);
+
+    // Бесконечный цикл обработки очереди событий
+    while(1) {
+        // Выбираем событие из очереди в переменную event (ждем бесконечно долго, если очередь пуста)
+        // и проверяем, что у нас получилось это сделать
+        if(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
+            if((event.type == InputTypePress) && (event.key == InputKeyBack)) {
+                break;
+            }
+
+            furi_mutex_acquire(fourinrow_state->mutex, FuriWaitForever);
+            if(wincheck() != -1) {
+                notification_message(notification, &end);
+                furi_delay_ms(1000);
+                if(wincheck() == 1) {
+                    scoreX++;
+                }
+                if(wincheck() == 2) {
+                    scoreO++;
+                }
+                init();
+                furi_mutex_release(fourinrow_state->mutex);
+                continue;
+            }
+
+            if(event.type == InputTypePress) {
+                if(event.key == InputKeyOk) {
+                    int nh = next_height(cursorx);
+                    if(nh != -1) {
+                        matrix[nh][cursorx] = player;
+                        player = 3 - player;
+                    }
+                }
+                if(event.key == InputKeyUp) {
+                    //cursory--;
+                }
+                if(event.key == InputKeyDown) {
+                    //cursory++;
+                }
+                if(event.key == InputKeyLeft) {
+                    if(cursorx > 0) {
+                        cursorx--;
+                    }
+                }
+                if(event.key == InputKeyRight) {
+                    if(cursorx < 6) {
+                        cursorx++;
+                    }
+                }
+            }
+
+            furi_mutex_release(fourinrow_state->mutex);
+        }
+        view_port_update(view_port);
+    }
+
+    // Чистим созданные объекты, связанные с интерфейсом
+    view_port_enabled_set(view_port, false);
+    gui_remove_view_port(gui, view_port);
+    view_port_free(view_port);
+    furi_message_queue_free(event_queue);
+    furi_record_close(RECORD_GUI);
+    // Clear notification
+    notification_message_block(notification, &sequence_display_backlight_enforce_auto);
+    furi_record_close(RECORD_NOTIFICATION);
+
+    furi_mutex_free(fourinrow_state->mutex);
+
+    free(fourinrow_state);
+
+    return 0;
+}

BIN
4inrow/4inrow_10px.png


+ 1 - 0
4inrow/ReadMe.md

@@ -0,0 +1 @@
+Four in row for flipper zero!!

+ 17 - 0
4inrow/application.fam

@@ -0,0 +1,17 @@
+App(
+    appid="4inrow",
+    name="4 in row",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="four_in_row_app",
+    requires=[
+        "gui",
+    ],
+    stack_size=1 * 1024,
+    order=90,
+    fap_icon="4inrow_10px.png",
+    fap_category="Games",
+    fap_author="leo-need-more-coffee",
+    fap_weburl="https://github.com/leo-need-more-coffee/flipperzero-4inrow",
+    fap_version="1.1",
+    fap_description="4 in row Game",
+)

BIN
4inrow/img/1.png


BIN
4inrow/img/2.png


BIN
4inrow/img/3.png