lvgl 2048 sample

2023-05-16


/**
 * @file simple_test.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "simple_test.h"

#if LV_100ASK_2048_SIMPLE_TEST != 0

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/


/**********************
 *  STATIC VARIABLES
 **********************/


/**********************
 *      MACROS
 **********************/


/**********************
 *   GLOBAL FUNCTIONS
 **********************/
static void game_2048_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj_2048 = lv_event_get_target(e);
    lv_obj_t * label = lv_event_get_user_data(e);
    
    if(code == LV_EVENT_VALUE_CHANGED) {
        if (lv_100ask_2048_get_best_tile(obj_2048) >= 2048)
            lv_label_set_text(label, "#00b329 YOU WIN! #");
        else if(lv_100ask_2048_get_status(obj_2048))
            lv_label_set_text(label, "#00b329 www.100ask.net: # #ff0000 GAME OVER! #");
        else
            lv_label_set_text_fmt(label, "SCORE: #ff00ff %d #", lv_100ask_2048_get_score(obj_2048));
    }
}

static void new_game_btn_event_handler(lv_event_t * e)
{
    lv_obj_t * obj_2048 = lv_event_get_user_data(e);

    lv_100ask_2048_set_new_game(obj_2048);
}


void lv_100ask_2048_simple_test(void)
{
    /*Create 2048 game*/
    lv_obj_t * obj_2048 = lv_100ask_2048_create(lv_scr_act());
#if LV_FONT_MONTSERRAT_40    
    lv_obj_set_style_text_font(obj_2048, &lv_font_montserrat_40, 0);
#endif
    lv_obj_set_size(obj_2048, 400, 400);
    lv_obj_center(obj_2048);

    /*Information*/
    lv_obj_t * label = lv_label_create(lv_scr_act());
    lv_label_set_recolor(label, true); 
    lv_label_set_text_fmt(label, "SCORE: #ff00ff %d #", lv_100ask_2048_get_score(obj_2048));
    lv_obj_align_to(label, obj_2048, LV_ALIGN_OUT_TOP_RIGHT, 0, -10);

    lv_obj_add_event_cb(obj_2048, game_2048_event_cb, LV_EVENT_ALL, label);

    /*New Game*/
    lv_obj_t * btn = lv_btn_create(lv_scr_act());
    lv_obj_align_to(btn, obj_2048, LV_ALIGN_OUT_TOP_LEFT, 0, -25);
    lv_obj_add_event_cb(btn, new_game_btn_event_handler, LV_EVENT_CLICKED, obj_2048);

    label = lv_label_create(btn);
    lv_label_set_text(label, "New Game");
    lv_obj_center(label);
}


/*=====================
 * Other functions
 *====================*/

/**********************
 *   STATIC FUNCTIONS
 **********************/


#endif  /*SIMPLE_TEST*/
 

/**
 * @file lv_100ask_2048.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_100ask_2048.h"

#if LV_USE_100ASK_2048 != 0
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

/*********************
 *      DEFINES
 *********************/
#define MY_CLASS    &lv_100ask_2048_class

#define LV_100ASK_2048_BG_COLOR             lv_color_hex(0xb3a397)
#define LV_100ASK_2048_TEXT_BLACK_COLOR     lv_color_hex(0x6c635b)
#define LV_100ASK_2048_TEXT_WHITE_COLOR     lv_color_hex(0xf8f5f0)

#define LV_100ASK_2048_NUMBER_EMPTY_COLOR   lv_color_hex(0xc7b9ac)
#define LV_100ASK_2048_NUMBER_2_COLOR         lv_color_hex(0xeee4da)
#define LV_100ASK_2048_NUMBER_4_COLOR         lv_color_hex(0xede0c8)
#define LV_100ASK_2048_NUMBER_8_COLOR         lv_color_hex(0xf2b179)
#define LV_100ASK_2048_NUMBER_16_COLOR         lv_color_hex(0xf59563)
#define LV_100ASK_2048_NUMBER_32_COLOR         lv_color_hex(0xf67c5f)
#define LV_100ASK_2048_NUMBER_64_COLOR         lv_color_hex(0xf75f3b)
#define LV_100ASK_2048_NUMBER_128_COLOR     lv_color_hex(0xedcf72)
#define LV_100ASK_2048_NUMBER_256_COLOR     lv_color_hex(0xedcc61)
#define LV_100ASK_2048_NUMBER_512_COLOR     lv_color_hex(0xedc850)
#define LV_100ASK_2048_NUMBER_1024_COLOR     lv_color_hex(0xedc53f)
#define LV_100ASK_2048_NUMBER_2048_COLOR     lv_color_hex(0xedc22e)

/**********************
 *      TYPEDEFS
 **********************/


/**********************
 *  STATIC PROTOTYPES
 **********************/
static void lv_100ask_2048_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_100ask_2048_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_100ask_2048_event(const lv_obj_class_t * class_p, lv_event_t * e);
static void btnm_event_cb(lv_event_t * e);

static void init_matrix_num(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static void addRandom(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static void update_btnm_map(char * lv_100ask_2048_btnm_map[], uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static lv_color_t get_num_color(uint16_t num);
static char * int_to_str(char * str, uint16_t num);

static uint8_t count_empty(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static uint8_t find_target(uint16_t array[MATRIX_SIZE], uint8_t x, uint8_t stop);
static void rotate_matrix(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static bool find_pair_down(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static bool slide_array(uint16_t * score, uint16_t array[MATRIX_SIZE]);
static bool move_up(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static bool move_down(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static bool move_left(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static bool move_right(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);
static bool game_over(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]);

/**********************
 *  STATIC VARIABLES
 **********************/
const lv_obj_class_t lv_100ask_2048_class = {
    .constructor_cb = lv_100ask_2048_constructor,
    .destructor_cb  = lv_100ask_2048_destructor,
    .event_cb       = lv_100ask_2048_event,
    .width_def      = LV_DPI_DEF * 2,
    .height_def     = LV_DPI_DEF * 2,
    .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE,
    .instance_size  = sizeof(lv_100ask_2048_t),
    .base_class     = &lv_obj_class
};

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

lv_obj_t * lv_100ask_2048_create(lv_obj_t * parent)
{
    LV_LOG_INFO("begin");
    lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
    lv_obj_class_init_obj(obj);
    return obj;
}


/*=====================
 * Setter functions
 *====================*/
void lv_100ask_2048_set_new_game(lv_obj_t * obj)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);

    lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)obj;

    game_2048->score = 0;
    game_2048->game_over = false;
    game_2048->map_count = MATRIX_SIZE * MATRIX_SIZE + MATRIX_SIZE;

    init_matrix_num(game_2048->matrix);
    update_btnm_map(game_2048->btnm_map, game_2048->matrix);
    lv_btnmatrix_set_map(game_2048->btnm, game_2048->btnm_map);

    lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
}


/*=====================
 * Getter functions
 *====================*/
uint16_t lv_100ask_2048_get_score(lv_obj_t * obj)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);

    lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)obj;

    return game_2048->score;
}

bool lv_100ask_2048_get_status(lv_obj_t * obj)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);

    lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)obj;

    return game_2048->game_over;
}


uint16_t lv_100ask_2048_get_best_tile(lv_obj_t * obj)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);

    lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)obj;

    uint8_t x, y;
    uint16_t best_tile = 0;

    for (x = 0; x < MATRIX_SIZE; x++) {
        for (y = 0; y < MATRIX_SIZE; y++) {
            if (best_tile < game_2048->matrix[x][y])
                best_tile = game_2048->matrix[x][y];
        }
    }

    return (uint16_t)(1 << best_tile);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

static void lv_100ask_2048_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
    LV_UNUSED(class_p);
    LV_TRACE_OBJ_CREATE("begin");

    lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)obj;

    game_2048->score = 0;
    game_2048->game_over = false;
    game_2048->map_count = MATRIX_SIZE * MATRIX_SIZE + MATRIX_SIZE;

    uint16_t index;
    for (index = 0; index < game_2048->map_count; index++) {

        if (((index + 1) % 5) == 0)
        {
            game_2048->btnm_map[index] = lv_mem_alloc(2);
            if ((index+1) == game_2048->map_count)
                strcpy(game_2048->btnm_map[index], "");
            else
                strcpy(game_2048->btnm_map[index], "\n");
        }
        else
        {
            game_2048->btnm_map[index] = lv_mem_alloc(5);
            strcpy(game_2048->btnm_map[index], " ");
        }
    }

    init_matrix_num(game_2048->matrix);
    update_btnm_map(game_2048->btnm_map, game_2048->matrix);

    /*obj style init*/
    lv_theme_t * theme = lv_theme_get_from_obj(obj);
    lv_obj_set_style_outline_color(obj, theme->color_primary, LV_STATE_FOCUS_KEY);
    lv_obj_set_style_outline_width(obj, lv_disp_dpx(theme->disp, 2), LV_STATE_FOCUS_KEY);
    lv_obj_set_style_outline_pad(obj, lv_disp_dpx(theme->disp, 2), LV_STATE_FOCUS_KEY);
    lv_obj_set_style_outline_opa(obj, LV_OPA_50, LV_STATE_FOCUS_KEY);

    /*game_2048->btnm init*/
    game_2048->btnm = lv_btnmatrix_create(obj);
    lv_obj_set_size(game_2048->btnm, LV_PCT(100), LV_PCT(100));
    lv_obj_center(game_2048->btnm);
    lv_obj_set_style_pad_all(game_2048->btnm, 10, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_width(game_2048->btnm, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_group_remove_obj(game_2048->btnm);
    lv_obj_add_flag(game_2048->btnm, LV_OBJ_FLAG_EVENT_BUBBLE);

    lv_btnmatrix_set_map(game_2048->btnm, game_2048->btnm_map);
    lv_btnmatrix_set_btn_ctrl_all(game_2048->btnm, LV_BTNMATRIX_CTRL_DISABLED);

    lv_obj_add_event_cb(game_2048->btnm, btnm_event_cb, LV_EVENT_ALL, NULL);

    LV_TRACE_OBJ_CREATE("finished");
}

static void lv_100ask_2048_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
    LV_UNUSED(class_p);

    lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)obj;

    uint16_t index, count;
    for (index = 0; index < game_2048->map_count; index++)
    {
        lv_mem_free(game_2048->btnm_map[index]);
    }
}


static void lv_100ask_2048_event(const lv_obj_class_t * class_p, lv_event_t * e)
{
    LV_UNUSED(class_p);

    lv_res_t res;

    /*Call the ancestor's event handler*/
    res = lv_obj_event_base(MY_CLASS, e);
    if(res != LV_RES_OK) return;

    bool success = false;
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btnm = lv_event_get_target(e);
    lv_obj_t * obj = lv_event_get_current_target(e);

    lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)obj;

    if (code == LV_EVENT_CLICKED)
    {
        game_2048->game_over = game_over(game_2048->matrix);
        if (!game_2048->game_over)
        {
            switch(lv_indev_get_gesture_dir(lv_indev_get_act()))
            {
                case LV_DIR_TOP:
                    success = move_left(&(game_2048->score), game_2048->matrix);
                    break;
                case LV_DIR_BOTTOM:
                    success = move_right(&(game_2048->score), game_2048->matrix);
                    break;
                case LV_DIR_LEFT:
                    success = move_up(&(game_2048->score), game_2048->matrix);
                    break;
                case LV_DIR_RIGHT:
                    success = move_down(&(game_2048->score), game_2048->matrix);
                    break;
                default: break;
            }
        }
        else
        {
            LV_LOG_USER("100ASK 2048 GAME OVER!");
            res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
            if(res != LV_RES_OK) return;
        }
    }
    else if(code == LV_EVENT_KEY)
    {
        game_2048->game_over = game_over(game_2048->matrix);
        if (!game_2048->game_over)
        {
            switch(*((uint8_t *)lv_event_get_param(e)))
            {
                case LV_KEY_UP:
                    success = move_left(&(game_2048->score), game_2048->matrix);
                    break;
                case LV_KEY_DOWN:
                    success = move_right(&(game_2048->score), game_2048->matrix);
                    break;
                case LV_KEY_LEFT:
                    success = move_up(&(game_2048->score), game_2048->matrix);
                    break;
                case LV_KEY_RIGHT:
                    success = move_down(&(game_2048->score), game_2048->matrix);
                    break;
                default: break;
            }
        }
        else
        {
            LV_LOG_USER("100ASK 2048 GAME OVER!");
            res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
            if(res != LV_RES_OK) return;
        }
    }

    if (success)
    {
        addRandom(game_2048->matrix);
        update_btnm_map(game_2048->btnm_map, game_2048->matrix);
        lv_btnmatrix_set_map(game_2048->btnm, game_2048->btnm_map);

        res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
        if(res != LV_RES_OK) return;
    }
}


static void btnm_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btnm = lv_event_get_target(e);
    lv_obj_t * parent = lv_obj_get_parent(btnm);

     lv_100ask_2048_t * game_2048 = (lv_100ask_2048_t *)parent;

    if(code == LV_EVENT_DRAW_PART_BEGIN) {
        lv_obj_draw_part_dsc_t * dsc = lv_event_get_param(e);

        /*Change the draw descriptor the button*/
        if((dsc->id >= 0) && (dsc->label_dsc))
        {
            uint16_t x, y, num;

            x = (uint16_t)((dsc->id) / 4);
            y = (dsc->id) % 4;
            num = (uint16_t)(1 << (game_2048->matrix[x][y]));


            dsc->rect_dsc->radius = 3;
            dsc->rect_dsc->bg_color = get_num_color(num);

            if (num < 8)
                dsc->label_dsc->color = LV_100ASK_2048_TEXT_BLACK_COLOR;
            else
                dsc->label_dsc->color = LV_100ASK_2048_TEXT_WHITE_COLOR;

        }
        /*Change the draw descriptor the btnm main*/
        else if((dsc->id == 0) && !(dsc->label_dsc))
        {
            dsc->rect_dsc->radius = 5;
            dsc->rect_dsc->bg_color = LV_100ASK_2048_BG_COLOR;
            dsc->rect_dsc->border_width = 0;
        }
    }
}


static void init_matrix_num(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    uint8_t x, y;

    for (x = 0; x < MATRIX_SIZE; x++) {
        for (y = 0; y < MATRIX_SIZE; y++) {
            matrix[x][y] = 0;
        }
    }

    /* 初始化两个随机位置的随机数 */
    addRandom(matrix);
    addRandom(matrix);
}


static void addRandom(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    static bool initialized = false;
    uint16_t x, y;
    uint16_t r, len = 0;
    uint16_t n, list[MATRIX_SIZE * MATRIX_SIZE][2];

    if (!initialized) {
        srand(time(NULL));
        initialized = true;
    }

    for (x = 0; x < MATRIX_SIZE; x++) {
        for (y = 0; y < MATRIX_SIZE; y++) {
            if (matrix[x][y] == 0) {
                list[len][0] = x;
                list[len][1] = y;
                len++;
            }
        }
    }

    if (len > 0) {
        r = rand() % len;
        x = list[r][0];
        y = list[r][1];
        n = ((rand() % 10) / 9) + 1;
        matrix[x][y] = n;
    }
 }


static void update_btnm_map(char * btnm_map[], uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    uint8_t x, y, index;

    index = 0;
    for (x = 0; x < MATRIX_SIZE; x++) {
        for (y = 0; y < MATRIX_SIZE; y++) {

            if (((index + 1) % 5) == 0)
                index++;

            if (matrix[x][y] != 0)
                int_to_str(btnm_map[index], (uint16_t)(1 << matrix[x][y]));
            else
                strcpy(btnm_map[index], " ");

            index++;

        }
    }
}


//10进制
static char* int_to_str(char * str, uint16_t num)
{
    uint8_t i = 0;//指示填充str
    if(num < 0)//如果num为负数,将num变正
    {
        num = -num;
        str[i++] = '-';
    }
    //转换
    do
    {
        str[i++] = num%10+48;//取num最低位 字符0~9的ASCII码是48~57;简单来说数字0+48=48,ASCII码对应字符'0'
        num /= 10;//去掉最低位
    }while(num);//num不为0继续循环

    str[i] = '\0';

    //确定开始调整的位置
    uint8_t j = 0;
    if(str[0] == '-')//如果有负号,负号不用调整
    {
        j = 1;//从第二位开始调整
        ++i;//由于有负号,所以交换的对称轴也要后移1位
    }
    //对称交换
    for(; j < (i / 2); j++)
    {
        //对称交换两端的值 其实就是省下中间变量交换a+b的值:a=a+b;b=a-b;a=a-b;
        str[j] = str[j] + str[i-1-j];
        str[i-1-j] = str[j] - str[i-1-j];
        str[j] = str[j] - str[i-1-j];
    }

    return str;//返回转换后的值
}

static uint8_t find_target(uint16_t array[MATRIX_SIZE], uint8_t x, uint8_t stop) {
    uint8_t t;
    // if the position is already on the first, don't evaluate
    if (x == 0) {
        return x;
    }
    for(t = x-1; ; t--) {
        if (array[t] != 0) {
            if (array[t] != array[x]) {
                // merge is not possible, take next position
                return t + 1;
            }
            return t;
        } else {
            // we should not slide further, return this one
            if (t == stop) {
                return t;
            }
        }
    }
    // we did not find a
    return x;
}

static bool slide_array(uint16_t * score, uint16_t array[MATRIX_SIZE]) {
    bool success = false;
    uint8_t x, t, stop = 0;

    for (x = 0; x < MATRIX_SIZE; x++) {
        if (array[x] != 0) {
            t = find_target(array,x,stop);
            // if target is not original position, then move or merge
            if (t != x) {
                // if target is zero, this is a move
                if (array[t] == 0) {
                    array[t] = array[x];
                } else if (array[t] == array[x]) {
                    // merge (increase power of two)
                    array[t]++;
                    // increase score
                    *score += (uint32_t)1<<array[t];
                    // set stop to avoid double merge
                    stop = t + 1;
                }
                array[x] = 0;
                success = true;
            }
        }
    }
    return success;
}

static void rotate_matrix(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]) {
    uint8_t i,j,n = MATRIX_SIZE;
    uint16_t tmp;

    for (i = 0; i < (n/2); i++) {
        for (j = i; j < (n-i-1); j++) {
            tmp = matrix[i][j];
            matrix[i][j] = matrix[j][n-i-1];
            matrix[j][n-i-1] = matrix[n-i-1][n-j-1];
            matrix[n-i-1][n-j-1] = matrix[n-j-1][i];
            matrix[n-j-1][i] = tmp;
        }
    }
}

static bool move_up(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    bool success = false;
    uint8_t x;

    for (x = 0; x < MATRIX_SIZE; x++) {
        success |= slide_array(score, matrix[x]);
    }
    return success;
}

static bool move_left(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    bool success;

    rotate_matrix(matrix);

    success = move_up(score, matrix);
    rotate_matrix(matrix);
    rotate_matrix(matrix);
    rotate_matrix(matrix);

    return success;
}

static bool move_down(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    bool success;

    rotate_matrix(matrix);
    rotate_matrix(matrix);

    success = move_up(score, matrix);
    rotate_matrix(matrix);
    rotate_matrix(matrix);

    return success;
}

static bool move_right(uint16_t * score, uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    bool success;

    rotate_matrix(matrix);
    rotate_matrix(matrix);
    rotate_matrix(matrix);

    success = move_up(score, matrix);
    rotate_matrix(matrix);

    return success;
}

static bool find_pair_down(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]) {
    bool success = false;
    uint8_t x, y;

    for (x = 0; x < MATRIX_SIZE; x++) {
        for (y = 0; y < (MATRIX_SIZE-1); y++) {
            if (matrix[x][y] == matrix[x][y+1])
                return true;
        }
    }
    return success;
}

static uint8_t count_empty(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE]) {
    uint8_t x, y;
    uint8_t count = 0;

    for (x = 0; x < MATRIX_SIZE; x++) {
        for (y = 0; y < MATRIX_SIZE; y++) {
            if (matrix[x][y] == 0) {
                count++;
            }
        }
    }
    return count;
}

static lv_color_t get_num_color(uint16_t num)
{
    lv_color_t color;

    switch (num)
    {
        case 0:        color = LV_100ASK_2048_NUMBER_EMPTY_COLOR;  break;
        case 1:        color = LV_100ASK_2048_NUMBER_EMPTY_COLOR;  break;
        case 2:        color = LV_100ASK_2048_NUMBER_2_COLOR;        break;
        case 4:        color = LV_100ASK_2048_NUMBER_4_COLOR;        break;
        case 8:        color = LV_100ASK_2048_NUMBER_8_COLOR;        break;
        case 16:    color = LV_100ASK_2048_NUMBER_16_COLOR;        break;
        case 32:    color = LV_100ASK_2048_NUMBER_32_COLOR;        break;
        case 64:    color = LV_100ASK_2048_NUMBER_64_COLOR;        break;
        case 128:    color = LV_100ASK_2048_NUMBER_128_COLOR;    break;
        case 256:    color = LV_100ASK_2048_NUMBER_256_COLOR;    break;
        case 512:    color = LV_100ASK_2048_NUMBER_512_COLOR;    break;
        case 1024:    color = LV_100ASK_2048_NUMBER_1024_COLOR;   break;
        case 2048:    color = LV_100ASK_2048_NUMBER_2048_COLOR;   break;
        default:    color =  LV_100ASK_2048_NUMBER_2048_COLOR;break;
    }
    return color;
}

static bool game_over(uint16_t matrix[MATRIX_SIZE][MATRIX_SIZE])
{
    bool ended = true;

    if (count_empty(matrix) > 0) return false;
    if (find_pair_down(matrix)) return false;

    rotate_matrix(matrix);
    if (find_pair_down(matrix)) ended = false;

    rotate_matrix(matrix);
    rotate_matrix(matrix);
    rotate_matrix(matrix);

    return ended;
}


#endif  /*LV_USE_100ASK_2048*/
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

lvgl 2048 sample 的相关文章

  • LVGL 之 windows 上 lvgl 模拟器 基于 Visual Studio 搭建方法的简单整理

    mark GUI Guider与lvgl联合仿真 xff08 结合stm32实验进行演示 xff0c 含触摸屏实验计数器与计算器 xff09 https blog csdn net gudao07 article details 12752
  • LVGL视频课程更新啦,基于lvgl v8.2版本,课程适配多个平台、多款板子

    视频教程观看 百问网LVGL v8 系列课程 韦东山 监制 教程基于lvgl v8 2版本 课程适配多个平台 多款板子 百问网LVGL v8 视频课程 韦东山 监制 教程基于lvgl v8 2版本 课程适配多个平台 多款板子 视频学习地址
  • LVGL使用记 - 数据更新显示

    介绍一下界面数据显示方法 关键API Set a an event handler function for an object Used by the user to react on event which happens with t
  • LVGL V8下png图片缩放显示

    这几天在研究LVGL V8下显示png图片和缩放问题 1 软件硬件环境 硬件环境 宸芯科技的SS202X系列芯片 这里使用的是SS202D 软件环境 Linux 移植的嵌入式系统 LVGL V8 编译器 arm linux gnueabih
  • LVGL学习(2):图片的转换和显示

    我们在设计UI的过程中可能需要显示一些图片 本篇文章将介绍如何转换并显示一个固定的图片到lv img中 文章目录 1 图片转换 1 1 GUI Guider 1 2 在线转换 2 图片的显示 1 图片转换 和之前我写的一篇字体转换的文章一样
  • 【esp32&lvgl】-2.1 # esp32移植lvgl7驱动st7789屏幕(ESP-IDF框架)

    目录 一 前言 二 代码 三 硬件说明 四 ESP IDF设置 重要 五 屏幕偏移修改驱动文件 参考资料 一 前言 前几天在ardiuno框架下基于platformIO用TFT eSPI库实现了lvgl库的移植 这种方法虽然在lvgl的版本
  • 【LVGL 学习】COLOR 常用接口函数说明

    COLOR 接口常用函数说明 通常跟样式 style 接口函数搭配使用 文件位置 src misc lv color c lv palette t 枚举包含以下18种 LV PALETTE RED LV PALETTE PINK LV PA
  • TensorRT学习笔记3 - 运行sampleMNIST

    目录 步骤 遇到的问题 步骤 cd your tensorrt path samples sampleMNIST make cd your tensorrt path bin sudo sample mnist h datadir your
  • 【LVGL 学习】加入内部字体

    使用到的软件 LvglFontTool exe 字符转换工具 链接 http www lfly xyz forum php mod viewthread tid 24 extra page 3D1 软件界面 按照软件界面配置 1 打开lvg
  • 【LVGL 学习】LVGL 在 arduino 环境的安装

    1 前提条件 使用 arduino IDE开发 使用 ESP32 作为主控 屏幕使用 ST7789 驱动 240 240像素TFT屏幕 注意 屏幕驱动部分不再这个赘述 以后开贴另行发布 2 安装 LVGL 库 打开 arduino 菜单栏中
  • lvgl8.2 img 图片显示

    1 lvgl 图片显示源 为了提供良好的图片显示灵活性 所以显示图像的来源可以是以下三种 代码中的一个变量 一个带有像素颜色数据的 C 数组 存储在外部的文件 比如 SD 卡 带有符号的文本 2 内部图片 对于源码内部图片 将图片转换为图片
  • LVGL V8应用——通过按键切换页面

    一 按键切换对象 程序 全局变量 static lv obj t contanier1 NULL static lv obj t contanier2 NULL 按钮对应回调函数 实现容器的切换 static void win btn ev
  • 【LVGL学习笔记】image图像相关接口

    数据结构如下 Data of image typedef struct lv obj t obj const void src 图像源 指向数组 文件或符号的指针 lv point t offset lv coord t w 宽度 lv c
  • LVGL 获取光标坐标位置

    为了方便获取物理按键输入的坐标 在仿真时直接开启打印坐标显示 获取自己想要的坐标 核心代码主要接口 indev proc press 打印光标位置 注意要先使能打印开关 LV LOG WARN pressed at x d y d proc
  • ESP32C3 移植ST7735 LVGL

    关于lvgl LVGL是一个C语言编写的免费的开源图形库 其提供了用于嵌入式GUI的各种元素 用户可以利用丰富的图形库资源 在消耗极低内存的情况下构建视觉效果丰富多彩的GUI 只需 64kB 闪存和 8kB RAM 就足以满足简单的用户界面
  • 'CreateDirectoryW':无法在 OpenCV 2.4.5 和 VS 2010 中将参数 1 从 'const char *' 转换为 'LPCWSTR'

    我正在尝试从 openCV 2 4 5 到 Visual Studio 2010 基于 VC 的示例代码 bagofwords classification cpp 但我发现了错误代码 error C2664 CreateDirectory
  • 对每组的一定比例进行采样,但具有最小约束(使用 dplyr)

    我有 6 个类别 阶层 的总体 我想在每个阶层中取 10 作为样本 这样做我采取 var c rep A 10 rep B 10 rep C 3 rep D 5 E F var value rnorm 30 dat tibble var v
  • 从 r 中的二高斯混合生成样本(MATLAB 中给出的代码)

    我正在尝试 在 r 中 创建与以下 MATLAB 函数等效的函数 该函数将从 N m1 s1 2 和 N m2 s2 2 与分数的混合物生成 n 个样本 alpha 来自第一个高斯 我有一个开始 但 MATLAB 和 R 之间的结果明显不同
  • 适用于 Android 的本机 OpenCV 示例抛出 UnsatisfiedLinkError

    我尝试在模拟器上运行 opencv android 示例 带有本机代码的示例 例如示例 教程 2 高级 1 添加本机 OpenCV 失败 我有一个Win7 x86系统 我可以构建本机库 但如果运行示例 我总是会遇到以下异常 10 04 08
  • 仅包含 1 个数字的示例[重复]

    这个问题在这里已经有答案了 我正在尝试创建一些模拟数据 为了创建聚类数据 我已指定处方者是否在一个或多个本地卫生区域 LHA 工作 现在 我正在尝试根据患者的 LHA 为患者指定一名处方医生 其代码位于以下代码块中 for i in seq

随机推荐

  • 基于形状的模板匹配(Shape-Based)

    称为基于边缘方向梯度的匹配 xff0c 是一种最常用也是最前沿的模板匹配算法 xff08 一 xff09 根本思想 以物体边缘的梯度相关性作为匹配标准 xff08 二 xff09 原理 提取ROI中的边缘特征 xff0c 结合灰度信息创建模
  • Hadoop基础教程-第7章 MapReduce进阶(7.1 MapReduce过程)(草稿)

    第7章 MapReduce进阶 7 1 MapReduce过程 7 1 1 input 一般而言 xff0c 数据文件都会上传到HDFS上 xff0c 也就是说HDFS上的文件作为MapReduce的输入 已知block块大小是128M x
  • RedHat Linux 5企业版开启VNC Server远程桌面功能手记

    环境 xff1a RedHat Linux 5企业版 Xwindows xff1a gnome xff08 红帽默认安装的图形界面 xff09 尽管我们可以使用SSH连接远程通过字符界面来操作Linux xff0c 但是对于更多熟悉图形人来
  • man: can't change directory to '/root': Permission denied

    执行 man 命令报错 man can t change directory to root Permission denied man command exited with status 255 sed e 错误原因 用户权限不够 解决
  • 树莓派3B入门开发之(一)--简介

    介绍 树莓派3B 树莓派是一个小型的单板计算机 通过将键盘 xff0c 鼠标 xff0c 显示器等外围设备连接到Raspberry Pi xff0c 它将作为一台迷你个人电脑 Raspberry Pi广泛用于实时图像 视频处理 xff0c
  • 3.19、BI之SSIS之数据流转换(合并)

    BI之SSIS之数据流转换 xff08 Union xff09 1 使用 合并 前必须先对数据进行排序 xff0c 否则会报错 xff0c 而union all则不需要排序 xff0c 这是它们二者的区别 2 新建SSIS包 3 控制流 拖
  • 3.20、BI之SSIS之数据流转换(合并连接)

    BI之SSIS之数据流转换 xff08 合并连接 xff09 1 合并联接转换功能是将两个已排序的输入列的数据通过使用FULL JOIN Left JOIN或INNERR JOIN联接形成一个输出数据集 它类似于T SQL语句中的连接查询语
  • 缓存小技巧--异步更新缓存时remove cache数据

    在支撑大规模 高并发 高可用的互联网应用中 xff0c 异步更新分布式缓存的应用已经越来越多了 xff08 为什么是异步更新缓存 xff0c 因为异步不仅可以提高系统性能 xff0c 而且提高系统的伸缩性和可用性 xff09 xff0c 由
  • pixhawk 2.4.6 pix2.4.8 原理图PCB二层板

    pixhawk 2 4 6 pix2 4 8 原理图PCB二层板 www cirmall com circuit 21579
  • Dockerfile简单使用入门

    什么是 Dockerfile xff1f Dockerfile 是一个用来构建镜像的文本文件 xff0c 文本内容包含了一条条构建镜像所需的指令和说明 docker build命令用于从Dockerfile构建映像 可以在docker bu
  • 什么是私有云?您应该知道的 6 个优势

    私有云是指单个业务实体或目标用户可以单独访问特定云计算环境中指定的硬件和软件资源 私有云类似于其他形式的云环境 xff0c 因为它通过物理组件提供虚拟化资源 私有云的优势 私有云的六大主要优势包括可预测的服务器使用 提高资源利用率 降低成本
  • CORD 4.1:打造实现边缘计算的最佳平台

    开放网络基金会 xff08 ONF xff09 周一发布了CORD 4 1版本的代码 xff0c 该版本的代码新增的功能为CORD项目注入了新的活力 xff0c 该版本是CORD项目独立一年半以来发布的一个重要的版本 xff0c 本次版本的
  • linux 查看动态库和可执行程序依赖库

    Linux动态库 一 objdump二 readelf三 ldd四 进程是否依赖指定五 动态库搜索路径顺序 一 objdump span class token comment 查看依赖的库 span objdump x xxx so sp
  • putty远程连接linux显示连接超时

    这个问题可真坑爹啊 一开始我百度谷歌了老长时间 xff0c ping一下也没有问题 xff0c 原来是关电脑后虚拟机的ip会发生变化 xff0c 重新连接就好了 xff0c 希望对大家有所帮助
  • Ubuntu 14.04安装openssh7.5

    因公司系统上线 xff0c 客户方 xff08 中国电信 xff09 入网需要系统安全评估报告 xff0c 根据第三方公司测试 xff0c 测出openssh有远程漏洞 xff0c 第三方测试公司提出整改建议 xff0c 升级最新的open
  • ovs测试vlan

    ovs端口默认是trunk模式 xff0c 且所有的VLAN tag都可以通过 单个网桥实现vlan隔离的场景 实验拓扑如下 xff1a 1 首先创建一个网桥ovs switch xff0c 在命名空间里创建两个接口p0和p1 分别分配地址
  • [STM32CubeIDE]FreeRTOS创建线程的方法

    1 在Device Configuration Tool 中 xff0c 依次选择Pinout amp Configuration gt Categories gt Middleware gt FREERTOS interface 选择CM
  • [STM32CubeIDE]使用freertos时Timebase Source为什么不能设定为SysTick

    参考https www digikey com en maker projects getting started with stm32 introduction to freertos ad275395687e4d85935351e16e
  • [CMSIS-RTOS2]rtos 基本概念

    特点 xff1a 利于采用更加面向对象的设计方法 多任务处理 相较于过程化的C xff0c 需要考虑的是任务线程设计及线程间的数据流 有助于项目管理 代码重用和软件测试 rtos需要额外的内存 xff0c 中断响应变慢 基本元素 xff1a
  • lvgl 2048 sample

    64 file simple test c INCLUDES include 34 simple test h 34 if LV 100ASK 2048 SIMPLE TEST 61 0 DEFINES TYPEDEFS