My simple maze program with UniGraphic library version.

Dependencies:   MMA8451Q UniGraphic mbed

This is basically a same program with my maze_vt100_MMA8451Q
but this time I used UniGraphic library and Adafruit 2.8" TFT (with touch).

http://developer.mbed.org/users/Rhyme/code/maze_vt100_MMA8451Q/

You can tailor the maze by editing "maze.h."

先にパブリッシュした簡単な迷路プログラムで UniGraphic ライブラリを使用してみました。

“maze.h” を編集することで独自の迷路を作成していただけます。

/media/uploads/Rhyme/maze_tft_1.jpg

After download and reset, a green circle is located at the start point.
Goal is the red circle.

ダウンロードしてリセットすると、画面のスタート位置に緑の●が置かれます。
ゴールは赤色の●です。

Move the FRDM-KL25Z board to let the green circle go.

FRDM-KL25Z を動かして、緑●を移動させます。

/media/uploads/Rhyme/maze_tft_2.jpg

When the green circle arrives at the goal with the "goal" banner, game ends.

緑●がゴールにたどり着くと“goal”というバナーが出てゲーム終了です。

/media/uploads/Rhyme/maze_tft_3.jpg

Since I did not use TSC (Touch Sensor) in this proram,
it should be easy to use other TFT panel(s), thanks for the "UniGraphic" library.
(let me know when you succeed with other TFT panel ;-)

このプログラムではタッチセンサーは使用していませんので、
“UniGraphic” ライブラリの恩恵として、他のTFTパネルへの移植も
容易だと思います。 (上手く行った人いたら知らせてくださいね・・・)

Revision:
0:572a79c1c040
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Mar 07 00:11:50 2015 +0000
@@ -0,0 +1,254 @@
+/** maze_vt100 a simple maze using UniGraphic and MMA8451Q libraries
+ */
+#include "mbed.h"
+#include "MMA8451Q.h"
+#include <ILI9341.h>
+#include "Arial12x12.h"
+#include "Arial24x23.h"
+#include "Arial28x28.h"
+#include "Arial43x48_numb.h"
+#include "maze.h"
+
+#if   defined (TARGET_KL25Z) 
+#define PIN_MOSI        PTD2
+#define PIN_MISO        PTD3 
+#define PIN_SCLK        PTD1 
+#define PIN_CS_TFT      PTD0 
+#define PIN_DC_TFT      PTD5 
+#define PIN_BL_TFT      PTC9 
+#define PIN_CS_SD       PTA4 
+#define PIN_CS_TSC      PTA13
+#define PIN_TSC_INTR    PTC9
+#define PIN_RESET_TFT   PTB10
+#else
+  #error TARGET NOT DEFINED
+#endif
+
+#define DIR_STAY  0
+#define DIR_UP    1
+#define DIR_DOWN  2
+#define DIR_RIGHT 3 
+#define DIR_LEFT  4
+
+#define MMA8451_I2C_ADDRESS (0x1D<<1)
+
+typedef struct _pos {
+    int x ;
+    int y ;
+} pos_type ;
+
+MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS) ;
+float threshold = 0.2 ;
+
+DigitalOut backlight(PTA12) ;
+ILI9341 TFT(SPI_8, 10000000, 
+    PIN_MOSI, PIN_MISO,  PIN_SCLK, 
+    PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "Adafruit2.8") ;
+
+/** Check if two pos_type values are same
+ * @param pos_type a
+ * @param pos_type b
+ * @returns if a and b are same position
+ */
+bool isSame(pos_type a, pos_type b)
+{
+    return((a.x == b.x)&&(a.y == b.y)) ;
+}
+
+/** Draw the maze defined in the "maze.h"
+ * @param pos_type *current actually the start point
+ * @param pos_type *goal the position of the goal
+ * @note those params are actually returned by this function
+ */
+void drawTFTMaze(pos_type *current, pos_type *goal)
+{
+    int x, y, i, j ;
+    TFT.BusEnable(true) ;
+    
+    backlight = 0 ;
+    for (j = 0 ; j < MAZE_H ; j++ ) {
+        for (i = 0 ; i < MAZE_W ; i++ ) {
+            x = i * 10 ;
+            y = j * 10 ;
+            switch(maze[j][i]) {
+            case 0: // path
+                TFT.fillrect(x, y, x+9, y+9, Black) ;
+                break ;
+            case 1: // wall
+                TFT.fillrect(x, y, x+9, y+9, DarkGrey) ;
+                break ;
+            case 2: // Start point
+                TFT.fillcircle(x+5, y+4, 4, Green) ;
+                current->x = i ;
+                current->y = j ;
+                break ;
+            case 3: // Goal
+                TFT.fillcircle(x+5, y+4, 4, Red) ;
+                goal->x = i ;
+                goal->y = j ;
+                break ;
+            default: // should not be here
+                break ;
+            }
+        }
+    }
+    backlight = 1 ;
+    TFT.BusEnable(false) ;
+}
+
+/** Filter out too little move 
+ * @param float in returned value from the acc
+ * @returns float result filtered value of in
+ */
+float filterVal(float in)
+{
+    float result = 0.0 ;
+    if ((-threshold > in)||(in > threshold)) {
+        result = in ;
+    }
+    return( result ) ;
+}
+
+/** Decide which direction to go
+ * @param float res[] acc value of x, y 
+ * @returns int direction to move 
+ */
+int getDirection(float res[])
+{
+    float dx, dy ;
+    int direction = DIR_STAY ;
+    dx = filterVal(res[0]) ;
+    dy = filterVal(res[1]) ;
+
+    if ((dx*dx) > (dy*dy)) { // holizontal move
+        if (dx > 0.0) {
+            direction = DIR_DOWN ;
+        } else if (dx < 0.0) {
+            direction = DIR_UP ;
+        }
+    } else { // vertical move
+        if (dy > 0.0) {
+            direction = DIR_RIGHT ;
+        } else if (dy < 0.0) {
+            direction = DIR_LEFT ;
+        }
+    }
+    return(direction) ;
+}
+
+/** Get next positon to move to
+ * @param pos_type current where we are now
+ * @param int direction which way we'd like to move
+ * @returns the candidate positon for the next move
+ */
+pos_type getNext(pos_type current, int direction) 
+{
+    pos_type next = current ;
+    switch(direction) {
+    case DIR_STAY: 
+        break ;
+    case DIR_UP: 
+        if (next.y > 0) { 
+            next.y-- ; 
+        }  
+        break ;
+    case DIR_DOWN: 
+        if (next.y < (MAZE_H - 1)) { 
+            next.y++ ; 
+        } 
+        break ;
+    case DIR_RIGHT: 
+        if (next.x < (MAZE_W - 1)) { 
+            next.x++ ; 
+        } 
+        break ;
+    case DIR_LEFT: 
+        if (next.x > 0) { 
+            next.x-- ; 
+        } 
+        break ;
+    default: 
+        break ;
+    }
+    return( next ) ;
+}
+
+/** Notice of the goal
+ */
+void showGoal(void)
+{
+    int x0, y0, x1, y1 ;
+    x0 = ((MAZE_W/2)-4) * 10 ;
+    y0 = ((MAZE_H/2)-1) * 10 ;
+    x1 = ((MAZE_W/2)+4) * 10 ;
+    y1 = ((MAZE_H/2)+1) * 10 ;
+
+    TFT.BusEnable(true) ;
+    TFT.fillrect(x0, y0, x1, y1, Blue) ;
+    TFT.rect(x0,y0,x1,y1, Yellow) ;
+    TFT.foreground(Red) ;
+    TFT.background(Blue) ;
+    x0 = ((MAZE_W/2) - 2) * 10 ;
+    y0 = (MAZE_H/2) * 10 - 3 ;
+    TFT.locate(x0, y0) ;
+    TFT.printf("G O A L") ;
+    TFT.BusEnable(false) ;
+}
+
+/** Check if we can move to the next position
+ * @param pos_type next the position we'd like to move next
+ * @returns if the position is empty (movable)
+ */
+bool checkMove(pos_type next) 
+{
+    bool result = false ;
+    
+    switch(maze[next.y][next.x]) {
+    case POS_PATH:
+    case POS_GOAL:
+        result = true ;
+        break ;
+    case POS_START:
+    case POS_WALL:
+    default:
+        result = false ;
+        break ;
+    } 
+    return( result ) ;
+}
+
+/** main a simple maze program
+ */
+int main() {
+    float res[3] ;
+    pos_type current, next, goal ;
+    int direction = DIR_STAY ;
+    int x, y ;
+    
+    drawTFTMaze(&current, &goal) ;
+    
+    for (;;) {
+        acc.getAccAllAxis(res) ;
+        direction = getDirection(res) ;
+        next = getNext(current, direction) ;
+        if ((!isSame(current, next)) && checkMove(next)) {
+           TFT.BusEnable(true) ;
+           x = current.x * 10 ;
+           y = current.y * 10 ;
+           TFT.fillrect(x, y, x+9, y+9, Black) ;
+           x = next.x * 10 ;
+           y = next.y * 10 ;
+           TFT.fillcircle(x+5, y+5, 4, Green) ; 
+           TFT.BusEnable(false) ;
+           current = next ;
+           if (isSame(next, goal)) {
+             break ; // goal in!
+           }
+        }
+        wait(0.1) ;
+    }
+    showGoal() ;
+    for (;;) {
+        // wait for ever for reset
+    }
+}