Game Ant Run - requires 8x8 LED RG shield - project MPOA (VUT v Brne)

Dependencies:   MMA8451Q RGB mbed

main.cpp

Committer:
tomas_dca
Date:
2015-01-08
Revision:
0:56ca0aab95fc
Child:
1:806df0da28dc

File content as of revision 0:56ca0aab95fc:

#include "mbed.h"
#include "MMA8451Q.h"
#include "MyColor.h"




// LED matrix states (pixel)

#define led_used    3 // color orange
#define led_lab     2 // color green
#define led_ant     1 // color red
#define led_free    0 // off

// brightness of LED matrix 
#define brightness 0.0003f // 0.001f optimal, 0.0003f for night

// RGB states

#define color_red       1.0
#define color_orange    0.1
#define color_green     0.3
#define color_blue      0.5



// labyrint virtual LED matrix
uint8_t matrix[8][8];

// templates for labyrint
#define template_fill (~0)    // fill all pixels

#define template_arrow 0x12244848241200
                              /*
                               *  . . . . . . . .
                               *  . . . x . . x . 
                               *  . . x . . x . .
                               *  . x . . x . . .
                               *  . . x . . x . .
                               *  . . . x . . x .
                               *  . . . . . . . .
                               *  . . . . . . . .
                               */

#define lab_turn_big    0x0D  /* 
                               *  x x
                               *  . x 
                               */
                               
#define lab_turn_small  0x08   /* 
                               *  x .
                               *  . . 
                               */
                               
#define lab_straight    0x0A   /* 
                                *  x .
                                *  x . 
                                */


#define one     0xF248               
//000000001111001001001000  

#define two     0x3D2B8
//000000111101001010111000

#define three   0x39678
//000000111001011001111000

#define four    0x25E48
//000000100101111001001000

#define five    0x3CE78
//000000111100111001111000

#define six     0x3CF78
//000000111100111101111000    

#define seven   0x39248
//000000111001001001001000

#define eight   0x3DF78
//000000111101111101111000

#define nine    0x3DE78
//000000111101111001111000

#define zero    0x3DB78
//000000111101101101111000


// init LED 8x8 matrix -> port
DigitalOut ROW0(PTB0);
DigitalOut ROW1(PTB1);
DigitalOut ROW2(PTB2);

DigitalOut COLG0(PTC0);
DigitalOut COLG1(PTC1);
DigitalOut COLG2(PTC2);
DigitalOut COLG3(PTC3);
DigitalOut COLG4(PTC4);
DigitalOut COLG5(PTC5);
DigitalOut COLG6(PTC6);
//      DigitalOut COLG7(PTC7); TODO
DigitalOut COLG7(PTA1);

DigitalOut COLR0(PTC8);
DigitalOut COLR1(PTC9);
DigitalOut COLR2(PTC10);
DigitalOut COLR3(PTC11);
DigitalOut COLR4(PTC12);
DigitalOut COLR5(PTC13);
DigitalOut COLR6(PTC16);
DigitalOut COLR7(PTC17);

// init LED 8x8 matrix -> port    
   
// state table                 TEST     |   GAME      |  PAUSE
//                        ----------------------------------------
DigitalIn BTN_L(PTD7);  // ->new game   |  ->pause    | ->game
DigitalIn BTN_R(PTD6);  // new 0 state  |   rotate    | ->new game


 
// define accelerometer stuffs  
#define MMA8451_I2C_ADDRESS (0x1d<<1)
#define MOVE_ANGLE 25   // > degrees for move  
#define IDLE_ANGLE 10   // < degrees for idle state
    
MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
    



// index for actual block of control
uint8_t row = 2;
uint8_t column = 2;

// index for ant position
uint8_t ant_row      = 5;
uint8_t ant_column   = 3;

// score counter
uint32_t score_cnt = 0;

// Timer ticker
Ticker display;     // display matrix of pixels
Ticker acc_scan;    // scan accelerometer move
Ticker ant_run;     // ant move

// periodic func. prototypes (Tickers)
void show_matrix(void);     //  Ticker display
void accelerometer(void);   //  Ticker acc_scan
void ant_move(void);        //  Ticker ant_run

// func. prototypes
void fill_matrix(uint64_t temp,uint8_t color);   
void rotate_matrix(void);
void rotate_lab(uint8_t lab_row, uint8_t lab_col);

void prepare_matrix(void);  // prepare matrix for new labyrint and set initial conditions
void reload_matrix(void);   // generate new labyrint blocks (only instead of used)       

uint32_t translate(uint8_t);    // number to symbol

// func. under accelerometer()
void confirm_dir(void);
void move_cursor(void);

// states of game
typedef enum  {ready, pause, game, test, save, learn, score} state_t;
state_t game_state = ready;

/*
 * ready - ready for game (idle)
 * test  - test controls 
 * save  - save accelerator offset
 * 
 * game  - ant run game
 * learn - special type of the game (without score and game over)
 * pause - pause game
 *
 * score - game over - show score
 */

// directions
typedef enum  {idle, left, up, right, down} direction_t;
direction_t acc_dir = idle; // enum for move direction -> control
direction_t ant_dir = down; // enum for move direction -> ant


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main(void)
{
     // init RGB backlight

    DigitalOut rled(LED_RED, 1); 
    DigitalOut gled(LED_GREEN, 1); 
    DigitalOut bled(LED_BLUE, 1); 
    
    PwmOut r (LED_RED);
    PwmOut g (LED_GREEN);
    PwmOut b (LED_BLUE);  
    
    MyColor color(LED_RED, LED_GREEN, LED_BLUE);
    
     uint8_t learning = 0;
     
     Timer timer;
     timer.start();
     
     // display turn on 
     display.attach(&show_matrix, 0.01);    // the address of the function to be attached (show_matrix) and the interval (0.01 seconds)
     acc_scan.attach(&accelerometer, 0.1);  // accelerometer 0.1 s
     ant_run.attach(&ant_move, 1.2);        // ant_move      1.2 s
    
     // learn mode
     if(!BTN_L && !BTN_R)
     {

        color = color_blue;
        learning = 1;                         
        while(!BTN_L || !BTN_R);             //debounce
     } 
    
     //control test
     game_state = test;
     color = color_orange;
     
    // init rand() seed
    srand(timer.read_ms());
                
    // init time for debounce
    int time = timer.read_ms();
   
    while (true) 
    { 
        switch(game_state)
        {
            case score:
            {
                // SHOW SCORE
                static uint8_t go = 0;          // go and show score
                static uint8_t sym_col = 100;   // state of showing score
                
                
                if((timer.read_ms() % 600 ) > 300)
                {
                    color = color_red;
                    
                    if(go == 5)
                        go = 1;
                    else
                        go = 6;
                              
                }
                else
                {        
                    if(go == 6)
                        go = 1;
                    else
                        go = 5;
                                                       
                    color = color_blue;
                }
                
                if( go == 1 )
                {
                    static uint32_t sym_act = 0;
                    static uint32_t sym_clr = led_ant;
                    static uint32_t score_cnt_temp = 0;
                    
                   
                    
                    switch(sym_col)
                    {
                        case 0:
                        case 1:
                            sym_col++;
                            break;
                        case 2:   
                            score_cnt_temp -= score_cnt_temp % 10;
                            score_cnt_temp /=10; 
                            
                            if(score_cnt_temp == 0)
                            {
                               // empty block
                                sym_act = 0;
                               // close ceremony
                               sym_col++;   
                            }
                            else
                            {
                                // next number
                                sym_act = translate(score_cnt_temp % 10);
                                sym_col = 0;
                            }
                            
                            if(sym_clr == led_ant)
                                sym_clr = led_lab; 
                            else
                                sym_clr = led_ant; 
                                
                            break; 
                        case 3:
                        case 4:
                        case 5:
                        case 6:
                        case 7:
                        case 8:
                        case 9:
                        case 10:
                            // close loop
                           sym_col++; 
                           break; 
                        case 11:
                            sym_col = 100;
                            // show score again 
                            break;                   
                        default:
                            // erase old symbol
                            fill_matrix(template_fill, led_free);
                            // load score
                            score_cnt_temp = score_cnt;
                            // init new char;
                            sym_act = translate(score_cnt_temp % 10);
                            sym_col = 0;
                    }
                    
                    // shift matrix
                    if((sym_col < 12))
                    {
                        for(uint8_t j = 5; j > 0;j--)       // rows
                        {
                            for(uint8_t i = 0; i < 7;i++)   // columns
                            {
                                matrix[j][7-i] = matrix[j][6-i]; 
                            }
                            // add new column to matrix
                            // find actual bit sym_col, assign color
                            matrix[j][0] = sym_clr * ((((0x1 << sym_col) << (3*j)) & sym_act) > 0);
                        }
                    } 
                }
                
                // buttons
                if( BTN_R && !BTN_L  && (time < timer.read_ms()))
                {
                    game_state = pause;
                    color = color_orange;
                    
                    // reset score show
                    sym_col = 100;
                    
                    // RESET LABYRINT
                    game_state = ready;
                    
                    time = timer.read_ms() + 200;    //debounce
                }
                
                break;
            }
            case pause:
            {
               // PAUSE
            
               if( BTN_L && !BTN_R && (time < timer.read_ms()))
               {
                    // RESET LABYRINT
                    
                    color = color_orange;
                    // prepare matrix for labyrint 
                    prepare_matrix();
                    wait(0.4f);
                  
                    // generate new playground
                    reload_matrix();
                    wait(0.2f); 
                    
                    color = color_red;
                      
               }
               else
               // RETURN
               if( BTN_R && !BTN_L && (time < timer.read_ms()))
               {
                   color = color_green;
                   if(!learning)
                   {
                        game_state = game;
                        
                        // haaahaaaa :D
                        score_cnt = 0;
                   }
                   else
                   {
                        game_state = learn;
                   }
                   
                   time = timer.read_ms() + 200;    //debounce 
                }
                
                break;
            }
            case game:
            case learn:
            {
                // GAME
                
                if( BTN_L && !BTN_R && (time < timer.read_ms()))
                {
                   // rotate block
                   time = timer.read_ms() + 200;    // debounce
                   rotate_lab(row, column);  
                }  
                else
                if( BTN_R && !BTN_L && (time < timer.read_ms()))
                {
                   // pause
                   color = color_red;
                   game_state = pause;
                                  
                   time = timer.read_ms() + 200;    // debounce
                   // wait for action
                   // RETURN or RESET  
                }
                
                break;
            }   
            case ready:
            {
                // RESET LAB
                
                color = color_orange;
                
                // prepare matrix for labyrint
                prepare_matrix();
                wait(0.4f);
                  
                // generate new playground
                reload_matrix();
                wait(0.2f);  
                  
                game_state = pause;
                
                color = color_red;
                break;    
            }
            default:
            {
                // TEST  
                
                 
                // arrows   
                    
                // set new 0 point (offset)  
                if( BTN_R && !BTN_L && (time < timer.read_ms()))
                {
                    color = color_green;
                    game_state = save;
                    wait(0.4f);
                    game_state = test;
                    color = color_orange;
                    
                    time = timer.read_ms() + 200;    // debounce
                }
                
                if( BTN_L && !BTN_R && (time < timer.read_ms()))
                {
                    // generate new playground
                    game_state = ready; 
                    
                    time = timer.read_ms() + 200;    // debounce
                }  
            }
        }
    }
}


void accelerometer()
{
    // offset
    static float xAngle_offset = 0;
    static float yAngle_offset = 0;

    if((game_state == test) || (game_state == game) || (game_state == save) || (game_state == learn))
    {
        float ax, ay, az;
        float xAngle, yAngle;
    
        ax = acc.getAccX();
        ay = acc.getAccY();
        az = acc.getAccZ();
        
        
        xAngle = atan( ax / (sqrt((ay)*(ay) + (az)*(az)))) * 60;
        yAngle = atan( ay / (sqrt((ax)*(ax) + (az)*(az)))) * 60;
       
        if(game_state == save)
        {
            xAngle_offset = xAngle;
            yAngle_offset = yAngle;    
        }
        else
        {       
            xAngle -= xAngle_offset;
            yAngle -= yAngle_offset;
        }
        
        // find maximum
        if(abs(xAngle) >= abs(yAngle))
        {
            if(xAngle >= MOVE_ANGLE)
            {                 
                 // +X 
                 acc_dir = up;   
            }
            else
            if(xAngle <= -MOVE_ANGLE)
            {
                 // -X   
                 acc_dir = down;   
            }  
            else
            if(abs(xAngle) <= IDLE_ANGLE)
            {
                if(game_state == test)
                    confirm_dir();  
                else
                    move_cursor();       
            }
        }
        else
        {      
            if(yAngle >= MOVE_ANGLE)
            {
                 // +Y 
                 acc_dir = left;  
            }
            else
            if(yAngle <= -MOVE_ANGLE)
            {
                 // -Y   
                 acc_dir = right;  
            }
            else
            if(abs(yAngle) <= IDLE_ANGLE)
            {
                if(game_state == test)
                    confirm_dir(); 
                else
                    move_cursor();
            }
            
        }  
        
        if(acc_dir != idle)
        {
            if(game_state == test)
            {
                fill_matrix(template_arrow, led_ant); 
            
                 
                switch(acc_dir)
                {
                   case down:
                       rotate_matrix();
                   case right:
                       rotate_matrix();
                   case up:
                       rotate_matrix();
                   case left:
                       break;    
                   default:
                       fill_matrix(template_fill, led_free); 
                 } 
            }
         } 
    }
}
 
void move_cursor(void)
{   
    switch(acc_dir)
    {
       case up:
            if(row == 6)
                row = 0;
            else
                row +=2;
           break;
       case right:
            if(column == 6)
                column = 0;
            else
                column +=2;
            break;
       case down:
           if(row == 0)
                row = 6;
            else
                row -=2;
           break;
       case left:
           if(column == 0)
                column = 6;
            else
                column -=2;
           break;    
       default:
           break; 
     }
     acc_dir = idle; 
}

void confirm_dir(void)
{
    fill_matrix(template_arrow, led_lab); 
                 
     switch(acc_dir)
     {
        case down:
            rotate_matrix();
        case right:
            rotate_matrix();
        case up:
            rotate_matrix();
        case left:
            break;    
        default:
             fill_matrix(template_fill, led_free); 
     }
     acc_dir = idle;  
}

void show_matrix(void)
{
    // labyrint block selection
    static uint8_t mask = 0;    // on/off -> blink

    mask++;
    
    for(uint8_t j = 0; j < 8;j++)
    {
        ROW0 = 0x0001 & j;
        ROW1 = 0x0002 & j;
        ROW2 = 0x0004 & j;
       
        COLG0 = ~matrix[j][0] & led_lab;
        COLG1 = ~matrix[j][1] & led_lab;
        COLG2 = ~matrix[j][2] & led_lab;
        COLG3 = ~matrix[j][3] & led_lab;
        COLG4 = ~matrix[j][4] & led_lab;
        COLG5 = ~matrix[j][5] & led_lab;
        COLG6 = ~matrix[j][6] & led_lab;
        COLG7 = ~matrix[j][7] & led_lab;
        
        COLR0 = ~matrix[j][0] & led_ant;
        COLR1 = ~matrix[j][1] & led_ant;
        COLR2 = ~matrix[j][2] & led_ant;
        COLR3 = ~matrix[j][3] & led_ant;
        COLR4 = ~matrix[j][4] & led_ant;
        COLR5 = ~matrix[j][5] & led_ant;
        COLR6 = ~matrix[j][6] & led_ant;
        COLR7 = ~matrix[j][7] & led_ant;
        
        
        // blik cursor (block)
        if(((row == j) || ((row+1) == j)) && ((mask % 0x17) < 0xD) && ((game_state == game || (game_state == learn))))
        {
            switch(column)
            {
                case 0:
                    COLG0 = ~led_free; 
                    COLR0 = ~led_free;
                    COLG1 = ~led_free; 
                    COLR1 = ~led_free;
                    break;
                case 2:
                    COLG2 = ~led_free; 
                    COLR2 = ~led_free;
                    COLG3 = ~led_free; 
                    COLR3 = ~led_free;
                    break;
                case 4:
                    COLG4 = ~led_free; 
                    COLR4 = ~led_free;
                    COLG5 = ~led_free; 
                    COLR5 = ~led_free;
                    break;
                case 6:
                    COLG6 = ~led_free; 
                    COLR6 = ~led_free;
                    COLG7 = ~led_free; 
                    COLR7 = ~led_free;
                    break;
                default:
                    break;
            }
        }
         
        wait(brightness);
    
    COLG0 = ~led_free;
    COLG1 = ~led_free;
    COLG2 = ~led_free;
    COLG3 = ~led_free;
    COLG4 = ~led_free;
    COLG5 = ~led_free;
    COLG6 = ~led_free;
    COLG7 = ~led_free;
    
    COLR0 = ~led_free;
    COLR1 = ~led_free;
    COLR2 = ~led_free;
    COLR3 = ~led_free;
    COLR4 = ~led_free;
    COLR5 = ~led_free;
    COLR6 = ~led_free;
    COLR7 = ~led_free;
    }
}

void fill_matrix(uint64_t temp, uint8_t color)
{
    for(uint8_t j = 0; j < 8;j++)
    {
        for(uint8_t i = 0; i < 8;i++)
        {
            matrix[j][i] = color * ( 0 < (temp & (0x8000000000000000>>((8*j)+i))));  // print template to the matrix 
        }
    }
}

void rotate_matrix(void)
{
    uint8_t temp[8][8];
    
    for(uint8_t j = 0; j < 8;j++)
    {
        for(uint8_t i = 0; i < 8;i++)
        {
            temp[7-i][j] = matrix[j][i];
        }
    }
    
    for(uint8_t j = 0; j < 8;j++)
    {
        for(uint8_t i = 0; i < 8;i++)
        {
            matrix[j][i] = temp[j][i];
        }
    }       
}

void rotate_lab(uint8_t lab_row, uint8_t lab_col)
{
    // if block is labyrint only
    if(((matrix[lab_row][lab_col]%2) == 0) && ((matrix[lab_row+1][lab_col]%2) == 0)  && ((matrix[lab_row][lab_col+1]%2) == 0)  && ((matrix[lab_row+1][lab_col+1]%2) == 0))
    {
        uint8_t temp;
        
        temp = matrix[lab_row][lab_col];
        matrix[lab_row][lab_col]     = matrix[lab_row][lab_col+1];
        matrix[lab_row][lab_col+1]   = matrix[lab_row+1][lab_col+1];
        matrix[lab_row+1][lab_col+1] = matrix[lab_row+1][lab_col];
        matrix[lab_row+1][lab_col]   = temp; 
        
        // change block type (because of turn clockwise and Anticlockwise too)
        if(matrix[lab_row][lab_col+1] == led_lab)
        {
            if((matrix[lab_row][lab_col] == led_lab) && (matrix[lab_row+1][lab_col] == led_lab))
            {
                matrix[lab_row][lab_col]     = led_free; 
                matrix[lab_row][lab_col+1]   = led_lab;
                matrix[lab_row+1][lab_col+1] = led_free;
                matrix[lab_row+1][lab_col]   = led_free; 
            } 
            else
            if((matrix[lab_row][lab_col] == led_free) && (matrix[lab_row+1][lab_col] == led_free) && (matrix[lab_row+1][lab_col+1] == led_free))
            {
                matrix[lab_row][lab_col]   = led_lab;
                matrix[lab_row+1][lab_col]   = led_lab;
                matrix[lab_row+1][lab_col+1] = led_free; 
            } 
        }
        
    }
}

void prepare_matrix(void)
{
    // only used blocks are re-generate
    fill_matrix(template_fill, led_used); 
    
    // reset counter
    if(game_state != game)
        score_cnt = 0;
    
    // start marker position
    row      = 2;
    column   = 2;
    
    // start symbol (home)
    matrix[4][2] = led_free; 
    matrix[5][2] = led_free;
    matrix[4][3] = led_lab;
    matrix[5][3] = led_ant;
    
    // start ant position
    ant_row      = 5;
    ant_column   = 3;
    
    // new direction
    ant_dir = down;
}

void reload_matrix(void)
{
    for(uint8_t j = 0; j < 4;j++)
    {
        for(uint8_t i = 0; i < 4;i++)
        {
            int8_t block;
            int8_t shift;
            
            // if labyrint part == used => generate new part 
            if((matrix[j*2][i*2] == led_used) && (matrix[(j*2) + 1][i*2] == led_used) && (matrix[(j*2) + 1][(i*2) + 1] == led_used) && (matrix[j*2][(i*2) + 1] == led_used))    
            {
                 switch( rand() % 3 )
                 {
                    case 0:
                        block = lab_turn_big;
                        break; 
                    case 1:
                        block = lab_turn_small;
                        break;
                    case 2:
                        block = lab_straight;
                        break; 
                    default:
                        block = 0x0f;
                 }
                
                 shift = rand() % 4;
                 matrix[2*j][2*i]         = led_lab * ( 1 & block >>  (shift % 4));       //  0 
                 matrix[2*j][(2*i)+1]     = led_lab * ( 1 & (block >> (++shift % 4)));    //  1
                 matrix[(2*j)+1][2*i]     = led_lab * ( 1 & (block >> (++shift % 4)));    //  2
                 matrix[(2*j)+1][(2*i)+1] = led_lab * ( 1 & (block >> (++shift % 4)));    //  3
    
                // one block == one point
                if(game_state == game)
                    score_cnt++;
            }
        }
    }
}

void ant_move(void)
{
    // ant_dir
    // enum left(1), up(2), right(3), down(4)
    
    
    if((game_state == game) || (game_state == learn))
    {
               
        // old pixel
        matrix[ant_row][ant_column] = led_used;

        // find new pixel 
        if((ant_dir % 2) == 0)
        {
            // up, down
            if(((ant_row + (ant_dir == down)) % 2) == 0) 
            {
                // 1. type move
/* | str in */  if(matrix[ant_row + 1 - (2 * (ant_dir == down))][ant_column] == led_lab)
                {
                    // go straight (in block)
                    // ant_dir = ant_dir;
                    ant_row += 1 - (2 * (ant_dir == down));                       
                }
                else
                {   
/* | turn out */    if((matrix[ant_row][ant_column - 1 + (2 * (ant_dir == down))] == led_lab ) && (matrix[ant_row + 1 - (2 * (ant_row % 2))][ant_column - 1 + (2 * (ant_dir == down))] == led_free ))
                    {
                        // mark used block
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                        matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        
                        if((ant_column % 2) == 0)
                        {
                            ant_dir = left;    
                        }
                        else
                        {
                            ant_dir = right;   
                        }
                        
                        // turn (out block)
                        ant_column += -1 + (2 * (ant_column % 2));
                    }
                    else
                    // reload matrix
                    if((ant_column == 7) || (ant_column == 0))
                    {                        
                        if((matrix[ant_row][7 * (ant_column != 7)] == led_lab) && (matrix[ant_row + 1 - (2 * (ant_row % 2))][7 * (ant_column != 7)] == led_free))
                        {
                            // mark used block
                            matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                            matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                            matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                            
                            reload_matrix();
                            
                            if(ant_column == 0)
                            {
                                ant_column = 7;
                                ant_dir = left;
                            }
                            else
                            {
                                ant_column = 0;
                                ant_dir = right;
                            }
                        }
                        else
                        {
                            // GAME OVER
                            if(game_state == game)
                                game_state = score;    
                        }
                    }
                    else
                    {
                        // GAME OVER
                        if(game_state == game)
                            game_state = score;    
                    }
                }
            }
            else
            if(((ant_row + (ant_dir == down)) % 2) == 1) 
            {
                // 2. type move
/* | turn in */ if(matrix[ant_row][ant_column + 1 - (2 * (ant_column % 2))] == led_lab)
                {
                    if((ant_column % 2) == 0)
                    {
                        ant_dir = right;    
                    }
                    else
                    {
                        ant_dir = left;   
                    }
                    
                    // turn (in block)
                    ant_column += 1 - (2 * (ant_column % 2));
                    
                }
                else
                {
                    // go straight (out block)
/* | str out */     
                    if((matrix[ant_row + 1 - (2 * (ant_dir == down))][ant_column] == led_lab) && (matrix[ant_row + 1 - (2 * (ant_dir == down))][ant_column + 1 - (2 * (ant_column % 2))] == led_free))
                    {
                        // mark used block
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                        matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        
                        // ant_dir = ant_dir;  
                        ant_row += 1 - (2 * (ant_dir == down));  
                    }
                    else
                    // reload matrix
                    if((ant_row == 7) || (ant_row == 0))
                    {
                        if((matrix[7 * (ant_row != 7)][ant_column] == led_lab) && (matrix[7 * (ant_row != 7)][ant_column + 1 - (2 * (ant_column % 2))] == led_free))
                        {
                            // mark used block
                            matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                            matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                            matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                            
                            reload_matrix();
                    
                            if(ant_dir == down)
                                ant_row = 7;
                            else
                                ant_row = 0;
                        }
                        else
                        {
                            // GAME OVER
                            if(game_state == game)
                                game_state = score;    
                        }
                    }
                    else
                    {
                        // GAME OVER
                        if(game_state == game)
                            game_state = score;    
                    }
                }
            }
               
        }
        // right, left
        else
        {
            if(((ant_column + (ant_dir == right)) % 2) == 1)
            {
                // 1. type move  
/* - str in */  
                if(matrix[ant_row][ant_column - 1 + (2 * ( ant_dir == right))] == led_lab ) 
                {
                    // go straight (in block)
                    // ant_dir = ant_dir;
                    ant_column += - 1 + (2 * ( ant_dir == right));
                    
                }
                else
/* - turn out */
                if((matrix[ant_row - 1 + (2 * (ant_row % 2 ))][ant_column] == led_lab ) && (matrix[ant_row - 1 + (2 * (ant_row % 2 ))][ant_column - 1 + (2 * (ant_dir == right))] == led_free )) 
                {
                    // mark used block
                    matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                    matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                    matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                   
                    if((ant_row % 2) == 0)
                    {
                        ant_dir = down;
                    }
                    else
                    {
                        ant_dir = up;    
                    }
                   
                    // turn (out block)
                    ant_row += -1 + (2 * (ant_row % 2));

                }
                else
                // reload matrix
                if((ant_row == 7) || (ant_row == 0))
                {
                    if((matrix[7 * (ant_row != 7)][ant_column] == led_lab) && (matrix[7 * (ant_row != 7)][ant_column + 1 - (2 * (ant_column % 2))] == led_free))
                    {
                        // mark used block
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                        matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        
                        reload_matrix();
                    
                        if(ant_row == 0)
                        {
                            ant_row = 7;
                            ant_dir = down;
                        }
                        else
                        {
                            ant_row = 0;
                            ant_dir = up;
                        }
                    }
                    else
                    {
                        // GAME OVER
                        if(game_state == game)
                            game_state = score;    
                    }
                }
                else
                {
                    // GAME OVER
                    if(game_state == game)
                        game_state = score;    
                }   
            }  
            else 
            {
                // 2. type move
/* - turn in */ if(matrix[ant_row + 1 - (2 * (ant_dir == right))][ant_column] == led_lab) 
                {
                    if((ant_row % 2) == 0)
                    {
                        ant_dir = up;
                    }
                    else
                    {
                        ant_dir = down;            
                    }
                    
                    // turn (in block) 
                    ant_row += 1 - (2 * (ant_row % 2));                 
                }
/* - str out */ 
                else
                if((matrix[ant_row][ant_column - 1 + (2 * ( ant_dir == right))] == led_lab) && (matrix[ant_row + 1 - (2 * (ant_row % 2))][ant_column - 1 + (2 * ( ant_dir == right))] == led_free))
                {
                    // mark used block
                    matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                    matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                    matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                    
                    // go straight (out block)  
                    ant_column += -1 + (2 * ( ant_dir == right));
                    
                    // ant_dir = ant_dir;                                       
                } 
                else
                // reload matrix
                if((ant_column == 7) || (ant_column == 0))
                {
                    if((matrix[ant_row][7 * (ant_column != 7)] == led_lab) && (matrix[ant_row + 1 - (2 * (ant_row % 2))][7 * (ant_column != 7)] == led_free))
                    {
                        // mark used block
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column] = led_used; 
                        matrix[ant_row][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        matrix[ant_row + 1 - (2* (ant_row % 2))][ant_column + 1 - (2* (ant_column % 2))] = led_used; 
                        
                        reload_matrix();
                    
                        if(ant_dir == left)
                            ant_column = 7;
                        else
                            ant_column = 0;
                    }
                    else
                    {
                        // GAME OVER
                        if(game_state == game)
                            game_state = score;    
                    }
                }
                else
                {
                    // GAME OVER
                    if(game_state == game)
                        game_state = score;    
                }       
            }   
        }    
        matrix[ant_row][ant_column] = led_ant;
    }
}

uint32_t translate(uint8_t number)
{    
    uint32_t ret;
    
    
    // translate numbers to symbols
    for(uint8_t j = 0; j < 5;j++)
    {
        switch(number)
        {
            case 0:
                ret = zero;
                break;  
            case 1:
                ret = one;
                break; 
            case 2:
                ret = two;
                break; 
            case 3:
                ret = three;
                break;  
            case 4:
                ret = four;
                break; 
            case 5:
                ret = five;
                break; 
            case 6:
                ret = six;
                break;  
            case 7:
                ret = seven;
                break; 
            case 8:
                ret = eight;
                break; 
            default:
                ret = nine;
                break;   
        } 
    }
    
    return(ret);
}