• 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;
    }
  • 相关阅读:
    nginx win10 配置启动bat脚本
    linux ctrl + s 导致锁死 解决
    linux 执行shell 不小心导致无限死循环解决
    linux vim 意外退出导致下次vim进入报错提示恢复
    vue 自定义组件使用vmodel属性的具体说明,重点说明参数的定义
    echarts 官网首页能进去,但是演示和文档地址进不去的 win10解决办法
    mysql 报错 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled
    elementui h5 引入elementui 报错提示没有字体
    .net 中文传参
    ASP.NET, IE6下URL中文乱码问题 ASP.NET程序,当URL后缀包含奇数个中文字符
  • 原文地址:https://www.cnblogs.com/viplanyue/p/12700745.html
Copyright © 2020-2023  润新知