simple snake game

Dependencies:   C12832_lcd EthernetInterface WebSocketClient mbed-rtos mbed

Revision:
0:2e5a51003afe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Snake.cpp	Thu Dec 08 11:20:34 2016 +0000
@@ -0,0 +1,216 @@
+#include "Snake.h"
+
+// Record snake nodes' positions, max length is 100
+int snake_body[2][100];
+// Record snake length
+int snake_length;
+// Record the food place
+int food[2];
+
+C12832_LCD lcd;
+Timer t;
+
+int raw[1280];
+// Raw data of the screen
+// 0 - Nothing
+// 1 - Food
+// 2 - Snake head
+// 3 - Snake body
+// 4 - Snake tail
+// 5 - Wall
+// loc(x, y) -> raw[x + y * 40]
+
+char lcd_data[160]; // Save the all screen data
+
+Bitmap lcd_bmp = {
+    40, // XSize
+    32, // YSize
+    5, // Bytes in Line
+    lcd_data,  // Pointer to picture data 
+};
+
+void Screen::init(){
+    // Initial the screen
+    lcd.cls();
+    lcd.setmode(XOR);
+    
+    for(int i = 0; i < 1280; i++){
+        raw[i] = 0;
+    }
+    // Draw the wall
+    for(int i = 0; i < 40; i++){
+        raw[i] = 5;
+        raw[i + 31 * 40] = 5;
+    }
+    for(int i = 0; i < 32; i++){
+        raw[i * 40] = 5;
+        raw[39 + i * 40] = 5;
+    }
+    // Draw the snake
+    raw[snake_body[0][0] + snake_body[1][0] * 40] = 2;
+    raw[snake_body[0][snake_length - 1] + snake_body[1][snake_length - 1] * 40] = 4;
+    for(int i = 1; i < snake_length - 1; i++){
+        raw[snake_body[0][i] + snake_body[1][i] * 40] = 3;
+    }
+    
+    // Draw the food
+    raw[food[0] + food[1] * 40] = 1;
+    
+    srand(t.read_ms());
+    
+    return;
+}
+
+void Screen::generate_lcd(){
+    for(int i = 0; i < 32; i++){
+        for(int j = 0; j < 5; j++){
+            char temp_c = 0x00;
+            for(int k = 0; k < 8; k++){
+                int temp = raw[k + j * 8 + i * 40];
+                temp_c = (temp_c << 1);
+                if(temp > 0){
+                    temp_c = temp_c + 0x01;
+                }
+                else{
+                    temp_c = temp_c + 0x00;
+                }
+            }
+            lcd_data[i * 5 + j] = temp_c;
+        }
+    }
+    return;
+}
+
+void Screen::write_to_screen(){
+    lcd.cls();
+    lcd.print_bm(lcd_bmp,0,0);
+    lcd.copy_to_lcd();
+    return;
+}
+
+void SnakeControll::init(){
+    snake_length = 3;       // Initialize the snake with 3 nodes
+    snake_body[0][0] = 18;
+    snake_body[1][0] = 16;
+    snake_body[0][1] = 19;
+    snake_body[1][1] = 16;
+    snake_body[0][2] = 20;
+    snake_body[1][2] = 16;
+    direction = 0;
+    
+    // Initialize the food place
+    food[0] = 10;
+    food[1] = 16;
+    
+    // Initialize the points
+    point = 0;
+    
+    // Initialize the timer
+    t.start();
+    return;
+}
+
+int SnakeControll::step(){
+    int step_direction[2];
+    switch(direction){
+        case 0: step_direction[0] = -1;     // Left
+                    step_direction[1] = 0;
+                    break;
+        case 1: step_direction[0] = 1;      // Right
+                    step_direction[1] = 0;
+                    break;
+        case 2: step_direction[0] = 0;      // Up
+                    step_direction[1] = -1;
+                    break;
+        case 3: step_direction[0] = 0;      // Down
+                    step_direction[1] = 1;
+                    break;
+    }
+    // Snake moves
+    int temp_tail[2];
+    temp_tail[0] = snake_body[0][snake_length - 1];
+    temp_tail[1] = snake_body[1][snake_length - 1];
+    raw[snake_body[0][snake_length - 1] + snake_body[1][snake_length - 1] * 40] = 0;
+    for(int i = snake_length - 1; i >0; i--){
+        snake_body[0][i] = snake_body[0][i - 1];
+        snake_body[1][i] = snake_body[1][i - 1];
+    }
+    snake_body[0][0] = snake_body[0][0] + step_direction[0];
+    snake_body[1][0] = snake_body[1][0] + step_direction[1];
+    int temp = raw[snake_body[0][0] + snake_body[1][0] * 40];
+    raw[snake_body[0][snake_length - 1] + snake_body[1][snake_length - 1] * 40] = 4;
+    raw[snake_body[0][0] + snake_body[1][0] * 40] = 2;
+    raw[snake_body[0][1] + snake_body[1][1] * 40] = 3;
+        
+    if(temp > 1){ // Hit something except food
+        raw[snake_body[0][snake_length - 1] + snake_body[1][snake_length - 1] * 40] = 4;
+        return 1;
+    }
+    if(temp == 1){  // Eat a food
+        point++;
+        raw[snake_body[0][snake_length - 1] + snake_body[1][snake_length - 1] * 40] = 3;
+        if(snake_length <= 100){
+            snake_length++;
+            snake_body[0][snake_length - 1] = temp_tail[0];
+            snake_body[1][snake_length - 1] = temp_tail[1];
+            raw[snake_body[0][snake_length - 1] + snake_body[1][snake_length - 1] * 40] = 4;
+        }
+        generate_food();
+        return 0;
+    }
+    else{ // Not hit
+        return 0;
+    }
+}
+
+void SnakeControll::set_direction(int d){
+    if(d >= 0){
+        direction = d;
+    }
+    return;
+}
+
+void SnakeControll::generate_food(){
+    int x = (rand() % 40);
+    int y = (rand() % 32);
+    while(raw[x + y * 40] > 0){
+        x = (rand() % 40);
+        y = (rand() % 32);
+    }
+    food[0] = x;
+    food[1] = y;
+    raw[food[0]+food[1]*40] = 1;
+}
+
+string SnakeControll::get_gamedata(){
+    string temp_json;
+    temp_json = "{body:[";
+    
+    temp_json.append(pos2str(snake_body[0][0], snake_body[1][0]));
+
+    for(int i = 1; i < snake_length; i++){
+        temp_json.append(",");
+        temp_json.append(pos2str(snake_body[0][i], snake_body[1][i]));
+    }
+    temp_json.append("],length:");
+    temp_json.append(num2str(snake_length));
+    temp_json.append(",food:");
+    temp_json.append(pos2str(food[0], food[1]));
+    temp_json.append("}");
+    
+    return temp_json;
+}
+
+string SnakeControll::num2str(int num){
+    char temp[3];   // Max snake length is 100
+    sprintf(temp, "%d", num);
+    string temp_str = temp;
+    return temp_str;
+}
+
+string SnakeControll::pos2str(int x, int y){
+    char temp[7];   // [xx,xx] 7 chars
+    sprintf(temp, "[%d,%d]", x, y);
+    string temp_str = temp;
+    return temp_str;
+} 
\ No newline at end of file