首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言貪食蛇小遊戲:雙向鏈表、多執行緒、無 graphics.h 實作

     編輯:關於C語言

C 語言貪食蛇小遊戲:雙向鏈表、多執行緒、無 graphics.h 實作

環境與特色

  • 編譯環境:Windows 7 64 位元,Code::Blocks 13.12
  • 未使用 graphics.h,採清屏重繪,約 1 秒刷新一次
  • 資料結構:雙向鏈表,蛇身各節點狀態(方向)複製前驅節點
  • 蛇身符號可自訂(預設笑臉 char symbol = 2)

遊戲截圖

完整原始碼

/*********************************
 * time: 2016.09.17 22:50
 * version: 1.0
 *********************************/
#include 
#include 
#include 
#include 

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
#define HIGH 35
#define WIDTH 80 // 必須為偶數

int temp[HIGH][WIDTH]; // 像素陣列
int STATE = LEFT;      // 初始向左
#define FOODPOS 700    // 食物初始位置
#define INIT_LEN 1     // 初始長度
int init_pos[INIT_LEN] = { HIGH/2*WIDTH + WIDTH/2 };
int SCORE = 0;

struct Item {
    int pos;
    int state;
    struct Item *per, *next;
};

struct Item *head, *tail, *iTemp;
char symbol = 2;

// 依狀態計算新位置
int getPos(int pos, int state) {
    if (state == UP) pos -= WIDTH;
    else if (state == DOWN) pos += WIDTH;
    else if (state == LEFT) pos -= 2;
    else if (state == RIGHT) pos += 2;
    else { printf("\n狀態錯誤!"); exit(-1); }
    return pos;
}

// 更新蛇位置與狀態(執行緒 1)
void change() {
    while (1) {
        print();
        iTemp = tail;
        while (iTemp != head) {
            iTemp->state = iTemp->per->state;
            iTemp->pos = getPos(iTemp->pos, iTemp->state);
            iTemp = iTemp->per;
        }
        head->state = STATE;
        head->pos = getPos(head->pos, head->state);
    }
}

// 繪製畫面
void print() {
    int h, w;
    // 清空像素陣列
    for (h = 1; h < HIGH-1; h++)
        for (w = 1; w < WIDTH-1; w++) temp[h][w] = 0;
    // 邊框
    for (w = 0; w < WIDTH; w += 2) {
        temp[0][w] = 2; temp[HIGH-1][w] = 2;
    }
    for (h = 0; h < HIGH; h++) {
        temp[h][0] = 2; temp[h][WIDTH-1] = 2;
    }
    // 蛇身
    iTemp = head->next;
    while (iTemp) {
        h = iTemp->pos / WIDTH; w = iTemp->pos % WIDTH;
        temp[h][w] = 1; iTemp = iTemp->next;
    }
    // 蛇頭
    h = head->pos / WIDTH; w = head->pos % WIDTH;
    if (temp[h][w] == 2 || temp[h][w] == 1) { // 撞牆或撞自己
        for (int i = 0; i < (WIDTH-12)/2; i++) printf(" ");
        printf("遊戲結束:%d分", SCORE);
        getchar(); exit(0);
    }
    temp[h][w] = 1;
    // 食物
    temp[FOODPOS/WIDTH][FOODPOS%WIDTH] = 1;
    // 吃到食物
    if (head->pos == FOODPOS) {
        struct Item *new = (struct Item*)malloc(sizeof(struct Item));
        new->next = head; head->per = new; new->per = NULL;
        new->pos = getPos(head->pos, head->state);
        new->state = head->state; head = new;
        SCORE += 10;
        // 產生新食物
        while (temp[FOODPOS/WIDTH][FOODPOS%WIDTH] == 1 ||
               temp[FOODPOS/WIDTH][FOODPOS%WIDTH] == 2 ||
               FOODPOS % 2 == 1) {
            FOODPOS = rand() % (HIGH * WIDTH);
        }
        temp[FOODPOS/WIDTH][FOODPOS%WIDTH] = 1;
    }
    // 清屏並列印
    system("cls");
    for (h = 0; h < HIGH; h++)
        for (w = 0; w < WIDTH; w++) {
            if (temp[h][w] == 0) printf(" ");
            else if (temp[h][w] == 1) printf("%c", symbol);
            else if (temp[h][w] == 2) printf("*");
            else { printf("\t\t\t\t\t error!"); exit(-2); }
        }
}

// 初始化雙向鏈表
void init() {
    int i;
    head = (struct Item*)malloc(sizeof(struct Item));
    head->per = NULL; iTemp = head;
    iTemp->pos = init_pos[0]; iTemp->state = LEFT;
    for (i = 1; i < INIT_LEN; i++) {
        iTemp->next = (struct Item*)malloc(sizeof(struct Item));
        iTemp->next->per = iTemp;
        iTemp = iTemp->next;
        iTemp->pos = init_pos[i]; iTemp->state = LEFT;
    }
    iTemp->next = NULL; tail = iTemp;
}

// 執行緒 1:遊戲邏輯
DWORD WINAPI Thread1(LPVOID pM) { while (1) change(); return 0; }
// 執行緒 2:鍵盤控制
DWORD WINAPI Thread2(LPVOID pM) {
    char c;
    while (1) {
        c = _getch();
        if (c == 'a' && STATE != RIGHT) STATE = LEFT;
        else if (c == 'd' && STATE != LEFT) STATE = RIGHT;
        else if (c == 'w' && STATE != DOWN) STATE = UP;
        else if (c == 's' && STATE != UP) STATE = DOWN;
        else continue;
    }
    return 0;
}

int main(void) {
    system("mode con cols=80 lines=40");
    system("color 8f");
    init();
    HANDLE h1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);
    HANDLE h2 = CreateThread(NULL, 0, Thread2, NULL, 0, NULL);
    WaitForSingleObject(h1, INFINITE);
    WaitForSingleObject(h2, INFINITE);
    return 0;
}

原創作品,未經授權禁止轉載。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved