James Bryant

【转】c语言版贪吃蛇小游戏

0
阅读(1301)

编译环境:windows 7 64位

编译工具:codeblocks 13.12

备注:未使用graphics.h

声明:个人原创,未经允许,禁止转载!!!

数据结构:双向链表

1.程序未使用graphis.h中的 函数,所以采用先清屏,再打印的方式显示图形,大约每秒刷新一次;

2.除蛇头元素外,其它元素的状态(行进方向)均重复前一元素;

3.蛇的图形元素为笑脸,可在源码中更改symbol参数选用不同元素。

游戏截图1                                                                                                                         游戏截图2

复制代码

/*********************************
*time:    2016.09.17 22:50
*version:1.0
*********************************/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>

#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;//初始状态为向左走

int FOODPOS = 700; //WIDTH*HIGH/2+WIDTH/2-WIDTH*HIGH/4;//食物的初始位置

#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状态state出错!");
        exit(-1);
    }
    return pos;
}

//更新蛇的位置与状态
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){//置第0行和最后一行为2
        temp[0][w] = 2;
        temp[HIGH-1][w] = 2;
    }
    for(h = 0; h < HIGH; h++){//置第0列和最后一列为2
        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;
    int i;
    if(temp[h][w] == 2 || temp[h][w] == 1){//撞到墙或自己,游戏结束head->pos < 0 || head->pos > HIGH*WIDTH
        for(i = 0; i < (WIDTH-12)/2; i++)
            printf(" ");
        printf("游戏结束:%d分", SCORE);
        getchar();
        exit(0);
    }
    else
        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;
        //head = 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;
}

DWORD WINAPI Thread1(LPVOID pM){
    while(1){
        change();
    }
    return 0;
}

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 handle1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);//线程1
    HANDLE handle2 = CreateThread(NULL, 0, Thread2, NULL, 0, NULL);//线程2

    WaitForSingleObject(handle1, INFINITE);
    WaitForSingleObject(handle2, INFINITE);
    return 0;
}