zoukankan      html  css  js  c++  java
  • C语言贪吃蛇

    /*亲测DEVC++编译器完美执行*/

    #define _CRT_SECURE_NO_WARNINGS

    #include<windows.h>
    #include<time.h>
    #include<conio.h>
    #include<stdio.h>


    void readini(FILE **fphead, int *score, char *argv[]) //创建或打开一个和运行文件对应的ini文件,读取最高纪录
    {
    char filename[200], *pfilename;
    int flag = -1, i;


    strcpy(filename, argv[0]);
    for (i = 0; filename[i] != ''; i++)
    {
    if ('.' == filename[i])flag = 1;
    }


    if (1 == flag)
    {
    filename[i - 1] = 'i';
    filename[i - 2] = 'n';
    filename[i - 3] = 'i';
    }
    else
    {
    filename[i] = '.';
    filename[i + 1] = 'i';
    filename[i + 2] = 'n';
    filename[i + 3] = 'i';
    filename[i + 4] = '';
    }
    for (; filename[i] != '\'&&i >= 0; i--)pfilename = &filename[i];
    if ((*fphead = fopen(pfilename, "rb+")) == NULL)
    {
    if ((*fphead = fopen(pfilename, "wb+")) == NULL)
    {
    printf("无法创建或打开"%s"文件 ", pfilename);
    system("pause");
    exit(0);
    }
    }
    else
    {
    fread(score, sizeof(int), 1, *fphead);
    }
    }
    void writeini(FILE **fphead, int *score, char *argv[])  //打开一个和运行文件对应的ini文件,写入最高纪录
    {
    char filename[200], *pfilename;
    int flag = -1, i;


    strcpy(filename, argv[0]);
    for (i = 0; filename[i] != ''; i++)
    {
    if ('.' == filename[i])flag = 1;
    }


    if (1 == flag)
    {
    filename[i - 1] = 'i';
    filename[i - 2] = 'n';
    filename[i - 3] = 'i';
    }
    else
    {
    filename[i] = '.';
    filename[i + 1] = 'i';
    filename[i + 2] = 'n';
    filename[i + 3] = 'i';
    filename[i + 4] = '';
    }
    for (; filename[i] != '\'&&i >= 0; i--)pfilename = &filename[i];
    if ((*fphead = fopen(pfilename, "wb+")) == NULL)
    {
    printf("无法写入"%s"文件,磁盘写保护! ", pfilename);
    system("pause");
    exit(0);
    }
    else
    {
    rewind(*fphead);
    fwrite(score, sizeof(int), 1, *fphead);
    fclose(*fphead);
    }
    }
    void gotoxy(int x, int y)//光标定位,光标定位函数SetConsoleCursorPosition是左上角位置是0,0然后向左向下延伸
    {
    COORD pos;
    pos.X = 2 * y;
    pos.Y = x;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
    }
    void color(int a)//颜色函数
    {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
    }


    void Refresh(int q[][22], int grade, int gamespeed, int length, int score) //  输出贪吃蛇棋盘
    {
    int i, j;
    for (i = 0; i<22; i++)
    {
    for (j = 0; j<22; j++)
    {
    if (q[i][j] == 0)//输出棋盘空白
    {
    gotoxy(i, j);
    color(11);
    printf("■");
    }
    if (q[i][j] == 1 || q[i][j] == 2)//输出棋盘墙壁
    {
    gotoxy(i, j);
    color(11);
    printf("□");
    }
    if (q[i][j] == 3)//输出蛇头
    {
    gotoxy(i, j);
    color(14);
    printf("★");
    }
    if (q[i][j] == 4)//输出蛇身
    {
    gotoxy(i, j);
    color(12);
    printf("◆");
    }
    if (q[i][j] == 5)//输出果子
    {
    gotoxy(i, j);
    color(12);
    printf("●");
    }
    }
    if (i == 0) printf(" ***********************");
    if (i == 1) printf(" 等级为:%d", grade);//显示等级
    if (i == 3) printf(" 自动前进时间");
    if (i == 4) printf(" 间隔为:%dms", gamespeed);//显示时间
    if (i == 6) printf(" 历史最高分为:%d分", score);
    if (i == 7) printf(" 你现在得分为:%d分", (length + (grade - 1) * 8) * 10);
    if (i == 8) printf(" **********************");
    if (i == 9) printf(" 游戏说明:");
    if (i == 10) printf(" (1)用小键盘方向键控制");
    if (i == 11) printf(" 蛇头运动方向;");
    if (i == 12) printf(" (2)蛇每吃一个果子蛇身");
    if (i == 13) printf(" 增加一节;");
    if (i == 14) printf(" (3)蛇咬到自己或碰到墙");
    if (i == 15) printf(" 壁游戏结束。");
    if (i == 18) printf(" **********************");


    }
    }


    int main(int argc, char *argv[])
    {


    int  score;
    FILE  *fpini;//*fpini 信息文件
    int grade = 1, length = 4;  //设置初始等级和蛇的初始长度
    int first = 0;
    readini(&fpini, &score, argv);//读取ini文件的最高纪录




    while (1)
    {
    int tcsZuobiao[2][500];     //蛇的坐标数组
    int tcsQipan[22][22];     //  贪吃蛇棋盘是一个二维数组(如22*22,包括墙壁)
    int i, j, directiontemp;
    int x1, y1;           // 随机出果子
    int head = 3, tail = 0;//标示蛇头和蛇尾的数组偏移量  
    int timeover = 1, otherkey = 1;//初始化超时时间和按键判断参数
    char direction = 77;  // 设置初始情况下,向右运动
    int x, y;//保存蛇头坐标到x,y变量
    long start, starttemp;
    int grade = 1, length = 4;  //设置初始等级和蛇的初始长度
    int first = 0;
    int gamespeed = 500;  //设置初始前进时间间隔
    if (score<0)//最高成绩小于零设置为零,初建文件会是负数
    score = 0;



    for (i = 1; i <= 20; i++)
    for (j = 1; j <= 20; j++)
    tcsQipan[i][j] = 0;    //贪吃蛇棋盘相应坐标标上中间空白部分的标志0
    for (i = 0; i <= 21; i++)
    tcsQipan[0][i] = tcsQipan[21][i] = 1;      //贪吃蛇棋盘相应坐标标上上下墙壁的标志1
    for (i = 1; i <= 20; i++)
    tcsQipan[i][0] = tcsQipan[i][21] = 2;      //贪吃蛇棋盘相应坐标标上左右墙壁的标志2


    if (first == 0)
    {
    for (i = 0; i<4; i++)
    {
    tcsZuobiao[0][i] = 1;//蛇身和蛇头的x坐标
    tcsZuobiao[1][i] = i + 1;//蛇身和蛇头的y坐标
    }
    first = 1;


    for (i = 1; i <= 3; i++)
    tcsQipan[1][i] = 4;    //蛇身
    tcsQipan[1][4] = 3;       //蛇头
    }








    srand(time(0));//设置随机种子
    do
    {
    x1 = rand() % 20 + 1;
    y1 = rand() % 20 + 1;
    } while (tcsQipan[x1][y1] != 0);//如果不是在空白处重新出果子
    tcsQipan[x1][y1] = 5;//贪吃蛇棋盘相应坐标标上果子的标志5
    color(12);
    printf(" 贪吃蛇游戏即将开始 ! ");//准备开始


    for (i = 3; i >= 0; i--)
    {
    start = clock();
    while (clock() - start <= 1000);
    system("cls");
    if (i>0)
    printf(" 进入倒计时:%d ", i);  //倒计时显示
    else
    Refresh(tcsQipan, grade, gamespeed, length, score);  //初始棋盘显示
    }


    x = tcsZuobiao[0][head];
    y = tcsZuobiao[1][head];//保存蛇头坐标到x,y变量
    while (1)//运行一局游戏
    {
    start = clock();
    while ((timeover = ((starttemp = clock()) - start <= gamespeed)) && !kbhit());//如果有键按下或时间超过自动前进时间间隔则终止循环
    if (direction == 72 || direction == 80 || direction == 75 || direction == 77)
    directiontemp = direction;//保留上一次方向按键
    //starttemp=gamespeed+start-starttemp;//保留停留时间
    if (timeover)
    {


    if ((direction = getch()) == -32)
    direction = getch();


    }


    if (!(direction == 72 || direction == 80 || direction == 75 || direction == 77))
    {
    otherkey = 0;//  按键非方向键,otherkey设置为0
    }
    else
    {
    otherkey = 1;//  按键为方向键,otherkey设置为1
    }
    if (direction == 72 && directiontemp == 80)//忽略反方向按键
    {
    direction = 32;
    otherkey = 0;
    //start = clock();
    //while(clock()-start<=starttemp);
    }
    else if (direction == 80 && directiontemp == 72)
    {
    direction = 32;//设置按键为非方向键
    otherkey = 0;//  按键为非方向键,otherkey设置为0
    // start = clock();
    //while(clock()-start<=starttemp);//补偿等待时间
    }
    else if (direction == 75 && directiontemp == 77)
    {
    direction = 32;
    otherkey = 0;
    //start = clock();
    //while(clock()-start<=starttemp);
    }
    else if (direction == 77 && directiontemp == 75)
    {
    direction = 32;
    otherkey = 0;
    //start = clock();
    //while(clock()-start<=starttemp);
    }




    switch (direction)//判断方向键
    {
    case 72: x = tcsZuobiao[0][head] - 1; y = tcsZuobiao[1][head]; break;      // 向上
    case 80: x = tcsZuobiao[0][head] + 1; y = tcsZuobiao[1][head]; break;      // 向下
    case 75: x = tcsZuobiao[0][head]; y = tcsZuobiao[1][head] - 1; break;      // 向左
    case 77: x = tcsZuobiao[0][head]; y = tcsZuobiao[1][head] + 1; break;      // 向右
    default: break;
    }




    if (x == 0 || x == 21 || y == 0 || y == 21)      // 蛇头碰到墙壁,结束本局游戏
    {
    gotoxy(22, 12);
    printf(" 游戏已结束! ");
    if (score >= (length + (grade - 1) * 8) * 10)//判断是否破记录
    {
    gotoxy(10, 7);
    color(12);
    printf("闯关失败 加油耶! ");
    fclose(fpini);//关闭ini文件
    }
    else
    {
    gotoxy(10, 7);
    color(12);
    printf("恭喜您打破记录 ");
    score = (length + (grade - 1) * 8) * 10;
    writeini(&fpini, &score, argv);//写入ini文件的最高纪录
    }
    gotoxy(23, 12);
    printf("按回车键重新开始,按ESC退出游戏 ");//显示的提示
    break;//退出该局游戏
    }
    if (tcsQipan[x][y] != 0 && !(x == x1&&y == y1) && tcsQipan[x][y] != 3) //   蛇头碰到蛇身,结束本局游戏
    {
    gotoxy(22, 12);
    printf(" 游戏已结束! ");
    if (score >= (length + (grade - 1) * 8) * 10)//判断是否破记录
    {
    gotoxy(10, 7);
    color(12);
    printf("闯关失败 加油耶! ");
    fclose(fpini);//关闭ini文件
    }
    else
    {
    gotoxy(10, 7);
    color(12);
    printf("恭喜您打破记录 ");
    score = (length + (grade - 1) * 8) * 10;
    writeini(&fpini, &score, argv);//写入ini文件的最高纪录
    }
    gotoxy(23, 12);
    printf("按回车键重新开始,按ESC退出游戏 ");//显示的提示
    break;//退出该局游戏
    }
    /*
    游戏运行时的核心算法开始
    */
    if (x == x1 && y == y1) //  吃果子,长度加1
    {
    length++;
    if (length >= 8)//长度大于等于8重新计算长度,等级加1
    {
    length -= 8;//重新计算长度
    grade++;//等级加1
    if (gamespeed>50)//控制最快速度为50
    gamespeed = 550 - grade * 50; // 改变自动前进时间间隔
    }
    tcsQipan[x][y] = 3;//贪吃蛇棋盘相应坐标现在蛇头标志改为蛇头标志3
    tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]] = 4;//贪吃蛇棋盘相应坐标原来蛇头标志改为蛇身标志4
    head = (head + 1) % 400;//防止数组越界
    tcsZuobiao[0][head] = x;//蛇头的x坐标
    tcsZuobiao[1][head] = y;//蛇头的y坐标
    do//随机出果子
    {
    x1 = rand() % 20 + 1;
    y1 = rand() % 20 + 1;
    } while (tcsQipan[x1][y1] != 0);//如果不是在空白处重新出果子
    tcsQipan[x1][y1] = 5;//贪吃蛇棋盘相应坐标标上果子的标志5
    gotoxy(22, 12);
    printf(" 游戏进行中! ");
    Refresh(tcsQipan, grade, gamespeed, length, score);
    }
    else  //  不吃果子
    {
    if (otherkey)
    {
    tcsQipan[tcsZuobiao[0][tail]][tcsZuobiao[1][tail]] = 0;
    tail = (tail + 1) % 400;//防止数组越界
    tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]] = 4;
    head = (head + 1) % 400;//防止数组越界
    tcsZuobiao[0][head] = x;//蛇头的x坐标
    tcsZuobiao[1][head] = y;//蛇头的y坐标
    tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]] = 3;
    gotoxy(22, 12);
    printf(" 游戏进行中! ");
    Refresh(tcsQipan, grade, gamespeed, length, score);
    }
    else
    {
    gotoxy(22, 12);
    printf(" 游戏暂停中! ");
    }
    }
    /*
    游戏运行时的核心算法结束
    */
    }
    while (1)
    {
    while (!kbhit());
    if ((direction = getch()) == 13)//按回车键开始下一局
    break;
    if (direction == 27)//按ESC退出游戏
    exit(0);
    }
    system("cls");//清除屏幕重新开始
    }
    return 0;
    }
  • 相关阅读:
    [转] Web前端优化之 Flash篇
    [转] Web 前端优化最佳实践之 Mobile(iPhone) 篇
    [转] Web前端优化之 图片篇
    [转] Web前端优化之 Javascript篇
    [转] Web前端优化之 CSS篇
    react事件获取元素
    Nodejs学习笔记02【module】
    Nodejs学习笔记01【EventEmitter】
    javascript运算符优先级
    jQuery-placeholder
  • 原文地址:https://www.cnblogs.com/viplanyue/p/12700745.html
Copyright © 2011-2022 走看看