     { 0xFE, 0xFE, 0xFE, 0xE2, 0xBE, 0xBE, 0xE2, 0xFE },
     { 0xFE, 0xC6, 0xBE, 0xBE, 0xC6, 0xFE, 0xFE, 0xFE },
     { 0xFE, 0xFE, 0xC6, 0xBE, 0xBE, 0xC6, 0xFE, 0xFE },
-    { 0xFE, 0xFE, 0xFE, 0xC6, 0xBE, 0xBE, 0xC6, 0xFE },
+    { 0xFE, 0xFE, 0xFE, 0xC6, 0xBE, 0xBE, 0xC6, 0xFE }
+};
+
+PROGMEM static const uint8_t imgCookie[4] = { // 4x4
+    0x06, 0x09, 0x09, 0x06
+};
+
+PROGMEM static const uint8_t imgFigures[10][16] = { // 8x12 x10
+    { 0x78, 0xFC, 0xFE, 0x86, 0xFE, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 },
+    { 0x8C, 0x8C, 0xFE, 0xFE, 0xFE, 0x86, 0x80, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 },
+    { 0x0C, 0x86, 0xE6, 0xFE, 0xBE, 0xDC, 0xC0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x00 },
+    { 0x04, 0x26, 0x36, 0x3E, 0xFE, 0xF4, 0xE0, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00 },
+    { 0xE0, 0xF0, 0xD8, 0xFC, 0xFE, 0xFE, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00 },
+    { 0x38, 0x3E, 0x36, 0x76, 0xF6, 0xE6, 0xE6, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00 },
+    { 0x78, 0xFE, 0xFF, 0x9F, 0xF8, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 },
+    { 0x0E, 0x0E, 0x06, 0xC6, 0xF6, 0x7E, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00 },
+    { 0xEE, 0xFF, 0x3F, 0x7D, 0xF9, 0xFF, 0xE6, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 },
+    { 0x3C, 0x7E, 0x7E, 0xE6, 0xFE, 0xFC, 0x7C, 0x00, 0x00, 0x02, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00 }
+};
+
+PROGMEM static const uint8_t imgTen[12] = { // 12x8
+    0x08, 0x08, 0x68, 0x98, 0x08, 0x00, 0xC0, 0x70, 0x28, 0xC0, 0x80, 0x00
+};
+
+PROGMEM static const byte soundStart[] = {
+    0x90, 0x44, 0x00, 0x7D, 0x90, 0x43, 0x00, 0x7D, 0x90, 0x42, 0x00, 0x7D, 0x90, 0x41, 0x00, 0x7D,
+    0x90, 0x40, 0x00, 0x7D, 0x90, 0x41, 0x00, 0x7D, 0x90, 0x42, 0x00, 0x7D, 0x90, 0x43, 0x00, 0x7D,
+    0x90, 0x60, 0x00, 0x14, 0x90, 0x41, 0x00, 0x14, 0x90, 0x5B, 0x00, 0x14, 0x90, 0x56, 0x00, 0x14,
+    0x90, 0x51, 0x00, 0x14, 0x90, 0x4C, 0x00, 0x14, 0x90, 0x47, 0x00, 0x14, 0x90, 0x3C, 0x00, 0x14,
+    0x80, 0xF0
 };
 
 PROGMEM static const byte soundStep[] = {
-    0x90, 60, 0, 10, 0x80, 0xF0
+    0x90, 0x3C, 0x00, 0x0A, 0x80, 0xF0
 };
 
 PROGMEM static const byte soundCapture[] = {
-    0x90, 80, 0, 20, 0x90, 84, 0, 40, 0x90, 88, 0, 40, 0x80, 0xF0
+    0x90, 0x50, 0x00, 0x14, 0x90, 0x54, 0x00, 0x28, 0x90, 0x58, 0x00, 0x28, 0x80, 0xF0
+};
+
+PROGMEM static const byte soundOver[] = {
+    0x90, 0x37, 0x00, 0xC8, 0x90, 0x35, 0x00, 0xC8, 0x90, 0x37, 0x00, 0xC8, 0x90, 0x35, 0x00, 0xC8,
+    0x90, 0x32, 0x01, 0xF4, 0x80, 0xF0
+};
+
+PROGMEM static const uint8_t ledValues[] = {
+    LED_VALUE(2, 2, 2), LED_VALUE(4, 0, 0), LED_VALUE(0, 0, 4), LED_VALUE(3, 3, 0), LED_VALUE(0, 4, 0),
+    LED_VALUE(3, 1, 1), LED_VALUE(2, 1, 0), LED_VALUE(2, 0, 3), LED_VALUE(1, 3, 0), LED_VALUE(0, 2, 2)
 };
 
 MyArduboy   arduboy;
-int16_t     px, py;
-int16_t     cx[COOKIES], cy[COOKIES];
-int8_t      cvx[COOKIES], cvy[COOKIES];
-uint16_t    score;
-uint8_t     pc, pa;
+bool        isPlaying;
+int16_t     playerX, playerY;
+uint8_t     playerChr, playerAnim;
+COOKIE_T    cookie[COOKIES];
+int16_t     score, gameTime;
+uint8_t     ledRed, ledGreen, ledBlue, ledLevel;
 
 /*  For Debugging  */
 

#define FPS             60
#define APP_TITLE       "RYSK"
#define APP_CODE        "OBN-Y00"
#define APP_VERSION     "0.02"
#define APP_RELEASED    "NOVEMBER 2019"

#define COOKIES     8
#define ANIM_MAX    16

#define PL_SIZE     4
#define CK_SIZE     2
#define SCALE       64
#define WIDTH_S     (WIDTH * SCALE)
#define HEIGHT_S    (HEIGHT * SCALE)
#define PL_SIZE_S   (PL_SIZE * SCALE)
#define CK_SIZE_S   (CK_SIZE * SCALE)
#define HIT_DIFF_S  PL_SIZE_S
#define NEW_DIFF_S  (PL_SIZE_S * 4)

/*  Functions  */

void initialize(void);
void update(void);
void movePlayer(void);
void newCookie(uint8_t idx);
void draw(void);

/*  Variables  */

PROGMEM static const uint8_t imgPlayer[9][8] = { // 8x8 x9
    { 0xFE, 0xF2, 0xDE, 0xDE, 0xF2, 0xFE, 0xFE, 0xFE },

    if (arduboy.buttonPressed(RIGHT_BUTTON)) vx++;
    if (arduboy.buttonPressed(UP_BUTTON))    vy--;
    if (arduboy.buttonPressed(DOWN_BUTTON))  vy++;
    int8_t vs = (vx != 0 && vy != 0) ? (SCALE * 3 / 8) : (SCALE / 2);
    int16_t dx = playerX + vx * vs;
    int16_t dy = playerY + vy * vs;
    if (dx >= PL_SIZE_S && dx < WIDTH_S - PL_SIZE_S) playerX = dx;
    if (dy >= PL_SIZE_S && dy < HEIGHT_S - PL_SIZE_S) playerY = dy;

    /*  Animation  */
    playerChr = (vy + 1) * 3 + (vx + 1);
    if (playerChr == 4) {
        playerAnim = 0;
    } else {
        if (++playerAnim >= ANIM_MAX) {
            arduboy.playScore2(soundStep, 3);
            playerAnim = 0;
        }
    }
}

static void moveCookie(COOKIE_T *pCookie)
{
    int16_t dx = pCookie->x + pCookie->vx;
    int16_t dy = pCookie->y + pCookie->vy;
    if (dx < CK_SIZE_S || dx >= WIDTH_S - CK_SIZE_S) pCookie->vx = -pCookie->vx;
    if (dy < CK_SIZE_S || dy >= HEIGHT_S - CK_SIZE_S) pCookie->vy = -pCookie->vy;
    pCookie->x += pCookie->vx;
    pCookie->y += pCookie->vy;
}

static void newCookie(COOKIE_T *pCookie)
{
    do {
        pCookie->x = random(CK_SIZE_S, WIDTH_S - CK_SIZE_S);
        pCookie->y = random(CK_SIZE_S, HEIGHT_S - CK_SIZE_S);
    } while (isInRange(pCookie, NEW_DIFF_S));
    float d = random(2048) * PI / 1024.0;
    pCookie->vx = (int8_t) (cos(d) * (float) SCALE);
    pCookie->vy = (int8_t) (sin(d) * (float) SCALE);
}

static bool isInRange(COOKIE_T *pCookie, int16_t range)
{
    return (abs(playerX - pCookie->x) < range && abs(playerY - pCookie->y) < range);
}

/*---------------------------------------------------------------------------*/
/*                              Draw Functions                               */
/*---------------------------------------------------------------------------*/

static void draw(void)
{
    if (!isPlaying) return;
    arduboy.clear();
    drawObject(playerX, playerY - (playerAnim >= ANIM_MAX / 2) * SCALE, PL_SIZE, imgPlayer[playerChr]);
    for (COOKIE_T *pCookie = cookie; pCookie < cookie + COOKIES; pCookie++) {
        drawObject(pCookie->x, pCookie->y, CK_SIZE, imgCookie);
    }
    drawStatus();
    arduboy.setRGBled(ledRed * ledLevel, ledGreen * ledLevel, ledBlue * ledLevel);
}

static void drawObject(int16_t x, int16_t y, uint8_t size, const uint8_t *bitmap)
{
    arduboy.drawBitmap(x / SCALE - size, y / SCALE - size, bitmap, size * 2, size * 2, WHITE);
}

static void drawStatus(void)
{
    if (gameTime > GAME_DURATION + FPS) {
        arduboy.drawBitmap((WIDTH - IMG_START1_W) / 2, 8, imgStart1, IMG_START1_W, IMG_START1_H, WHITE);
    } else if (gameTime > GAME_DURATION) {
        arduboy.drawBitmap((WIDTH - IMG_START2_W) / 2, 8, imgStart2, IMG_START2_W, IMG_START2_H, WHITE);
    } else {
        int dx = drawFigure(0, 0, score, ALIGN_LEFT);
        arduboy.drawBitmap(dx, 0, imgTen, IMG_TEN_W, IMG_TEN_H, WHITE);
        drawClock(CLOCK_X, CLOCK_Y, CLOCK_R, (gameTime > 0) ? (GAME_DURATION - gameTime) / FPS : 0);
        if (gameTime <= 0) {
            arduboy.drawBitmap((WIDTH - IMG_OVER_W) / 2, 48, imgOver, IMG_OVER_W, IMG_OVER_H, WHITE);
        }
    }
}

static int drawFigure(int16_t x, int16_t y, int value, uint8_t align)
{
    int k = (value > 9) ? drawFigure(x - align * 4, y, value / 10, align) : 0;
    arduboy.drawBitmap(x + k, y, imgFigures[value % 10], IMG_FIGURE_W, IMG_FIGURE_H, WHITE);
    return k + 8 - align * 4;
}

static void drawClock(int16_t x, int16_t y, uint8_t r, uint8_t sec)
{
    float d = sec * PI / 30.0;
    int16_t vx = sin(d) * r;
    int16_t vy = -cos(d) * r;
    arduboy.drawLine(x, y, x + vx, y + vy, WHITE);
    arduboy.drawCircle(x, y, r, WHITE);
}
