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

Dependencies:   MMA8451Q RGB mbed

Revision:
0:56ca0aab95fc
Child:
1:806df0da28dc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jan 08 11:55:23 2015 +0000
@@ -0,0 +1,1203 @@
+#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);
+}
\ No newline at end of file