活在控制檯的貪喫蛇遊戲

活在控制檯的貪喫蛇遊戲

忽然想寫個貪喫蛇小遊戲。
實現起來很簡單,用隊列保存小蛇的身體座標。在位置座標中小蛇頭部的下一步位置激活,尾部位置取消激活實現小蛇移動,實現捕食效果則尾部不取消激活小蛇長度增加。

import java.util.Scanner;

public class SnakeTest {

    private Scanner sc;

    private int r;// 隨機數值
    private int d;// 輸入的數字
    private int[][] dir = { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 } };// 方向數組,下,左,上,右

    private final int width = 5;// 寬
    private final int height = 5;// 高
    private int[][] pos;// 位置數組

    private int head_x, head_y;// 頭部座標
    private int snake_length = 2;// 初始場長度
    private int cur_dir;// 當前方向

    private int food_x, food_y;// 食物座標

    MyLink link;// 隊列對象

    public static void main(String[] args) {
        System.out.println("【貪喫蛇】");
        SnakeTest st = new SnakeTest();
        st.initGame();
        st.runGame();
    }

    private void initGame() {

        sc = new Scanner(System.in);// 實例化輸入類

        // 隨機初始化起源點及方向
        r = (int) (Math.random() * (width * height));
        head_x = r % width;
        head_y = r / width;
        cur_dir = (int) (Math.random() * 4);

        // 初始化座標數組以及實例化自定義的隊列類
        pos = new int[width][height];
        link = new MyLink(width, height);

        // 將第一個座標放進隊列並激活位置座標
        link.in(head_y, head_x);
        pos[head_y][head_x] = 1;

        // 根據起源座標直線延伸至設定長度,因此最大長度爲width或height
        for (int i = 1; i < snake_length; i++) {
            head_x += dir[cur_dir][1];
            head_y += dir[cur_dir][0];
            // 檢查並處理數組以及遊戲邊界
            check();
            link.in(head_y, head_x);
            pos[head_y][head_x] = 1;// 激活
        }

        // 初始化食物座標
        randomFood();
    }

    private void runGame() {
        while (true) {

            draw();// 打印在控制檯

            d = sc.nextInt();

            // 0 1 2 3 下 上 右 左
            control(d);

            head_x += dir[cur_dir][1];
            head_y += dir[cur_dir][0];

            // 檢查並處理數組以及遊戲邊界
            check();

            // 如果咬到自己遊戲失敗
            if (pos[head_y][head_x] == 8) {// 喫到東西 長度+1
                snake_length++;
                link.in(head_y, head_x);// 把頭部座標塞進隊列
                pos[head_y][head_x] = 1;// 將頭部座標激活

                // 是否大滿貫
                if (snake_length == width * height) {
                    draw();
                    System.out.println("勝利!");
                    return;
                }
                randomFood();// 隨機生成食物座標
            } else {// 否則隊列操作,實現小蛇移動
                int[] tail = link.out();// 隊列將尾部座標移除;
                pos[tail[0]][tail[1]] = 0;// 取消激活尾部座標
                if (pos[head_y][head_x] == 1) {
                    System.out.println("咬到自己啦!\n小蛇長度:"+snake_length);
                    return;
                }
                link.in(head_y, head_x);// 把頭部座標塞進隊列
                pos[head_y][head_x] = 1;// 將頭部座標激活
            }
        }
    }

    private void control(int d) {
        if (cur_dir != 2 && d == 0)// 當前方向不允許爲向上情況允許向下轉彎,下同
            cur_dir = 0;
        else if (cur_dir != 3 && d == 1)
            cur_dir = 1;
        else if (cur_dir != 0 && d == 2)
            cur_dir = 2;
        else if (cur_dir != 1 && d == 3)
            cur_dir = 3;
    }

    private void check() {
        if (head_x < 0)
            head_x = width - 1;
        else if (head_x == width)
            head_x = 0;
        if (head_y < 0)
            head_y = height - 1;
        else if (head_y == height)
            head_y = 0;
    }

    private void draw() {
        System.out.println("數字: [0]下,[1]左,[2]上,[3]右");
        System.out.printf("頭部座標:第%d行,第%d列\n", head_y + 1, head_x + 1);
        System.out.print("當前方向爲:");
        switch (cur_dir) {
        case 0:
            System.out.println("下");
            break;
        case 1:
            System.out.println("左");
            break;
        case 2:
            System.out.println("上");
            break;
        case 3:
            System.out.println("右");
        }

        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                System.out.printf("%-2s", pos[i][j]);
            }
            System.out.println();
        }
    }

    private void randomFood() {
        while (pos[food_y][food_x] != 0) {
            r = (int) (Math.random() * (width * height));
            food_y = r / width;
            food_x = r % width;
        }
        pos[food_y][food_x] = 8;
    }

}

class MyLink {
    private int[][] link;
    private int head_index;
    private int tail_index;

    public MyLink(int x, int y) {
        link = new int[x * y][2];
    }

    public void in(int x, int y) {
        link[head_index][0] = x;
        link[head_index][1] = y;
        head_index++;
        head_index %= link.length;
    }

    public int[] out() {
        int[] index = { link[tail_index][0], link[tail_index][1] };
        tail_index++;
        tail_index %= link.length;
        return index;
    }
    
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章