【C语言】贪吃蛇【附源码】

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
 
#define ROW 22 //游戏区行数
#define COL 42 //游戏区列数
 
#define KONG 0 //标记空(什么也没有)
#define WALL 1 //标记墙
#define FOOD 2 //标记食物
#define HEAD 3 //标记蛇头
#define BODY 4 //标记蛇身
 
#define UP 72 //方向键:上
#define DOWN 80 //方向键:下
#define LEFT 75 //方向键:左
#define RIGHT 77 //方向键:右
#define SPACE 32 //暂停
#define ESC 27 //退出

//初始化蛇
void InitSnake()
{
  snake.len = 2; //蛇的身体长度初始化为2
  snake.x = COL / 2; //蛇头位置的横坐标
  snake.y = ROW / 2; //蛇头位置的纵坐标
  //蛇身坐标的初始化
  body[0].x = COL / 2 - 1;
  body[0].y = ROW / 2;
  body[1].x = COL / 2 - 2;
  body[1].y = ROW / 2;
  //将蛇头和蛇身位置进行标记
  face[snake.y][snake.x] = HEAD;
  face[body[0].y][body[0].x] = BODY;
  face[body[1].y][body[1].x] = BODY;
}
//随机生成食物
void RandFood()
{
  int i, j;
  do
  {
    //随机生成食物的横纵坐标
    i = rand() % ROW;
    j = rand() % COL;
  } while (face[i][j] != KONG); //确保生成食物的位置为空,若不为空则重新生成
  face[i][j] = FOOD; //将食物位置进行标记
  color(12); //颜色设置为红色
  CursorJump(2 * j, i); //光标跳转到生成的随机位置处
  printf("●"); //打印食物
}

打印蛇部分:
如果 flag 的值为1,表示需要打印蛇。
将终端颜色设置为绿色,使用 color(10) 函数。
将光标跳转到蛇头的位置,使用 CursorJump(2 * snake.x, snake.y) 函数。
在蛇头的位置打印蛇头图标,这里使用了 "■" 表示蛇头。
使用 for 循环遍历蛇的身体,将光标跳转到每个蛇身体部分的位置,并打印蛇身体的图标,这里使用了 "□" 表示蛇身体。
 

覆盖蛇部分:
如果 flag 的值不为1,表示需要覆盖蛇。
首先检查蛇尾的位置是否为 (0, 0),这是为了避免在蛇的长度增加时将墙壁位置覆盖。
如果蛇尾的位置不是 (0, 0),则将光标跳转到蛇尾的位置,并将该位置打印为空格,即将蛇尾覆盖掉。

void DrawSnake(int flag)
{
  if (flag == 1) //打印蛇
  {
    color(10); //颜色设置为绿色
    CursorJump(2 * snake.x, snake.y);
    printf("■"); //打印蛇头
    for (int i = 0; i < snake.len; i++)
    {
      CursorJump(2 * body[i].x, body[i].y);
      printf("□"); //打印蛇身
    }
  }
  else //覆盖蛇
  {
    if (body[snake.len - 1].x != 0) //防止len++后将(0, 0)位置的墙覆盖
    {
      //将蛇尾覆盖为空格即可
      CursorJump(2 * body[snake.len - 1].x, body[snake.len - 1].y);
      printf("  ");
    }
  }
}
void MoveSnake(int x, int y)
{
  DrawSnake(0); //先覆盖当前所显示的蛇
  face[body[snake.len - 1].y][body[snake.len - 1].x] = KONG; //蛇移动后蛇尾重新标记为空
  face[snake.y][snake.x] = BODY; //蛇移动后蛇头的位置变为蛇身
  //蛇移动后各个蛇身位置坐标需要更新
  for (int i = snake.len - 1; i > 0; i--)
  {
    body[i].x = body[i - 1].x;
    body[i].y = body[i - 1].y;
  }
  //蛇移动后蛇头位置信息变为第0个蛇身的位置信息
  body[0].x = snake.x;
  body[0].y = snake.y;
  //蛇头的位置更改
  snake.x = snake.x + x;
  snake.y = snake.y + y;
  DrawSnake(1); //打印移动后的蛇
}

初始化设置:
int n = RIGHT;:开始游戏时,默认向右移动。
int tmp = 0;:记录蛇的移动方向。
游戏循环:
使用 while(1) 构建游戏主循环,表示游戏一直进行。
n = getch();:获取键盘输入的方向控制。
方向控制调整:
通过 switch 语句,根据用户输入的方向键来调整蛇的移动方向。
如果用户按下的方向键与当前蛇的移动方向相反,则忽略该输入,保持蛇的当前移动方向不变。
蛇的移动:
使用 switch 语句,根据当前的移动方向来调用 run 函数,实现蛇的移动,并更新 tmp 记录的当前移动方向。
游戏控制:
如果用户按下空格键,则游戏暂停。
如果用户按下 ESC 键,则清空屏幕并退出游戏。
如果用户按下 'r' 或 'R' 键,则重新开始游戏,清空屏幕并调用 main 函数重新执行游戏。

void Game()
{
  int n = RIGHT; 
  int tmp = 0; 
  goto first; 
  while (1)
  {
    n = getch(); 
    switch (n)
    {
    case UP:
    case DOWN: 
      if (tmp != LEFT&&tmp != RIGHT) 
      {
        n = tmp; 
      }
      break;
    case LEFT:
    case RIGHT: 
      if (tmp != UP&&tmp != DOWN) 
      {
        n = tmp; 
      }
    case SPACE:
    case ESC:
    case 'r':
    case 'R':
      break; //这四个无需调整
    default:
      n = tmp;
      break;
    }
  first:
    switch (n)
    {
    case UP: 
      run(0, -1); 
      tmp = UP;
      break;
    case DOWN: 
      run(0, 1); 
      tmp = DOWN; 
      break;
    case LEFT: 
      run(-1, 0); 
      tmp = LEFT; 
      break;
    case RIGHT:
      run(1, 0); 
      tmp = RIGHT;
      break;
    case SPACE: 
      system("pause>nul"); 
      break;
    case ESC:
      system("cls"); 
      color(7);
      CursorJump(COL - 8, ROW / 2);
      printf("  游戏结束  ");
      CursorJump(COL - 8, ROW / 2 + 2);
      exit(0);
    case 'r':
    case 'R': 
      system("cls"); 
      main();
    }
  }
}
void run(int x, int y)
{
  int t = 0;
  while (1)
  {
    if (t == 0)
      t = 3000; 
    while (--t)
    {
      if (kbhit() != 0) 
        break;
    }
    if (t == 0) 
    {
      JudgeFunc(x, y); 
      MoveSnake(x, y); 
    }
    else 
    {
      break;
    }
  }
}
void JudgeFunc(int x, int y)
{
  //若蛇头即将到达的位置是食物,则得分
  if (face[snake.y + y][snake.x + x] == FOOD)
  {
    snake.len++; //蛇身加长
    grade += 10; //更新当前得分
    color(7); //颜色设置为白色
    CursorJump(0, ROW);
    printf("当前得分:%d", grade); //重新打印当前得分
    RandFood(); //重新随机生成食物
  }
  //若蛇头即将到达的位置是墙或者蛇身,则游戏结束
  else if (face[snake.y + y][snake.x + x] == WALL || face[snake.y + y][snake.x + x] == BODY)
  {
    Sleep(1000); //留给玩家反应时间
    system("cls"); //清空屏幕
    color(7); //颜色设置为白色
    CursorJump(2 * (COL / 3), ROW / 2 - 3);
    if (grade > max)
    {
      printf("恭喜你打破最高记录,最高记录更新为%d", grade);
      WriteGrade();
    }
    else if (grade == max)
    {
      printf("与最高记录持平,加油再创佳绩", grade);
    }
    else
    {
      printf("请继续加油,当前与最高记录相差%d", max - grade);
    }
    CursorJump(2 * (COL / 3), ROW / 2);
    printf("GAME OVER");
    while (1) //询问玩家是否再来一局
    {
      char ch;
      CursorJump(2 * (COL / 3), ROW / 2 + 3);
      printf("再来一局?(y/n):");
      scanf("%c", &ch);
      if (ch == 'y' || ch == 'Y')
      {
        system("cls");
        main();
      }
      else if (ch == 'n' || ch == 'N')
      {
        CursorJump(2 * (COL / 3), ROW / 2 + 5);
        exit(0);
      }
      else
      {
        CursorJump(2 * (COL / 3), ROW / 2 + 5);
        printf("选择错误,请再次选择");
      }
    }
  }
}
void ReadGrade()
{
  FILE* pf = fopen("贪吃蛇最高得分记录.txt", "r"); //以只读的方式打开文件
  if (pf == NULL) //打开文件失败
  {
    pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
    fwrite(&max, sizeof(int), 1, pf); //将max写入文件(此时max为0),即将最高得分初始化为0
  }
  fseek(pf, 0, SEEK_SET); //使文件指针pf指向文件开头
  fread(&max, sizeof(int), 1, pf); //读取文件当中的最高得分到max当中
  fclose(pf); //关闭文件
  pf = NULL; //文件指针及时置空
}
void WriteGrade()
{
  FILE* pf = fopen("贪吃蛇最高得分记录.txt", "w");
  if (pf == NULL)
  {
    printf("保存最高得分记录失败\n");
    exit(0);
  }
  fwrite(&grade, sizeof(int), 1, pf);
  fclose(pf);
  pf = NULL; 
}

主函数 main():
首先,它声明了两个全局变量 max 和 grade,分别用来存储最高得分和本局游戏得分。
然后,在 main() 函数内部,通过 #pragma warning (disable:4996) 关闭了编译器的警告提示,可能是因为某些函数被认为是不安全的。
接着,初始化了两个全局变量 max 和 grade,将它们都设置为0。
使用 system() 函数设置了命令提示符窗口的标题为 "贪吃蛇",并设置了窗口大小为84列 * 23行。
调用 HideCursor() 函数隐藏了命令提示符窗口中的光标。
调用 ReadGrade() 函数从文件中读取最高分到全局变量 max 中。
调用 InitInterface() 函数初始化游戏界面。
调用 InitSnake() 函数初始化贪吃蛇。
使用 srand((unsigned int)time(NULL)) 函数根据当前时间设置随机数种子。
调用 RandFood() 函数随机生成食物。
调用 DrawSnake(1) 函数在界面上绘制贪吃蛇。
最后,调用 Game() 函数开始游戏。

完整代码:

   

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
 
#define ROW 22 //游戏区行数
#define COL 42 //游戏区列数
 
#define KONG 0 //标记空(什么也没有)
#define WALL 1 //标记墙
#define FOOD 2 //标记食物
#define HEAD 3 //标记蛇头
#define BODY 4 //标记蛇身
 
#define UP 72 //方向键:上
#define DOWN 80 //方向键:下
#define LEFT 75 //方向键:左
#define RIGHT 77 //方向键:右
#define SPACE 32 //暂停
#define ESC 27 //退出
 
//蛇头
struct Snake
{
    int len; //记录蛇身长度
    int x; //蛇头横坐标
    int y; //蛇头纵坐标
}snake;
 
//蛇身
struct Body
{
    int x; //蛇身横坐标
    int y; //蛇身纵坐标
}body[ROW * COL]; //开辟足以存储蛇身的结构体数组
 
int face[ROW][COL]; //标记游戏区各个位置的状态
 
//隐藏光标
void HideCursor();
//光标跳转
void CursorJump(int x, int y);
//初始化界面
void InitInterface();
//颜色设置
void color(int c);
//从文件读取最高分
void ReadGrade();
//更新最高分到文件
void WriteGrade();
//初始化蛇
void InitSnake();
//随机生成食物
void RandFood();
//判断得分与结束
void JudgeFunc(int x, int y);
//打印蛇与覆盖蛇
void DrawSnake(int flag);
//移动蛇
void MoveSnake(int x, int y);
//执行按键
void run(int x, int y);
//游戏主体逻辑函数
void Game();
 
int max, grade; //全局变量
int main()
{
#pragma warning (disable:4996) 
    max = 0, grade = 0; 
    system("title 贪吃蛇");
    system("mode con cols=84 lines=23");
    HideCursor(); //隐藏光标
    ReadGrade(); //从文件读取最高分到max变量
    InitInterface(); //初始化界面
    InitSnake(); //初始化蛇
    srand((unsigned int)time(NULL));
    RandFood(); 
    DrawSnake(1); //打印蛇
    Game(); //开始游戏
    return 0;
}
 
//隐藏光标
void HideCursor()
{
    CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
    curInfo.dwSize = 1; //如果没赋值的话,光标隐藏无效
    curInfo.bVisible = FALSE; //将光标设置为不可见
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
}
//光标跳转
void CursorJump(int x, int y)
{
    COORD pos; //定义光标位置的结构体变量
    pos.X = x; //横坐标
    pos.Y = y; //纵坐标
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    SetConsoleCursorPosition(handle, pos); //设置光标位置
}
void InitInterface()
{
    color(6); 
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COL; j++)
        {
            if (j == 0 || j == COL - 1)
            {
                face[i][j] = WALL; //标记该位置为墙
                CursorJump(2 * j, i);
                printf("■");
            }
            else if (i == 0 || i == ROW - 1)
            {
                face[i][j] = WALL; //标记该位置为墙
                printf("■");
            }
            else
            {
                face[i][j] = KONG; 
            }
        }
    }
    color(7);
    CursorJump(0, ROW);
    printf("当前得分:%d", grade);
    CursorJump(COL, ROW);
    printf("历史最高得分:%d", max);
}
void color(int c)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); 
 
}
void ReadGrade()
{
    FILE* pf = fopen("贪吃蛇最高得分记录.txt", "r"); 
    if (pf == NULL) //打开文件失败
    {
        pf = fopen("贪吃蛇最高得分记录.txt", "w"); 
        fwrite(&max, sizeof(int), 1, pf);
    }
    fseek(pf, 0, SEEK_SET);
    fread(&max, sizeof(int), 1, pf);
    fclose(pf); //关闭文件
    pf = NULL; //文件指针及时置空
}
//更新最高分到文件
void WriteGrade()
{
    FILE* pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
    if (pf == NULL) //打开文件失败
    {
        printf("保存最高得分记录失败\n");
        exit(0);
    }
    fwrite(&grade, sizeof(int), 1, pf); //将本局游戏得分写入文件当中
    fclose(pf); //关闭文件
    pf = NULL; //文件指针及时置空
}
void InitSnake()
{
    snake.len = 2; 
    snake.x = COL / 2; 
    snake.y = ROW / 2; 
    body[0].x = COL / 2 - 1;
    body[0].y = ROW / 2;
    body[1].x = COL / 2 - 2;
    body[1].y = ROW / 2;
 
    face[snake.y][snake.x] = HEAD;
    face[body[0].y][body[0].x] = BODY;
    face[body[1].y][body[1].x] = BODY;
}
void RandFood()
{
    int i, j;
    do
    {
        i = rand() % ROW;
        j = rand() % COL;
    } while (face[i][j] != KONG);
    face[i][j] = FOOD; 
    color(12); 
    CursorJump(2 * j, i); 
    printf("●"); 
}
void JudgeFunc(int x, int y)
{
    if (face[snake.y + y][snake.x + x] == FOOD)
    {
        snake.len++; 
        grade += 10; 
        color(7); 
        CursorJump(0, ROW);
        printf("当前得分:%d", grade);
        RandFood(); 
    }
    else if (face[snake.y + y][snake.x + x] == WALL || face[snake.y + y][snake.x + x] == BODY)
    {
        Sleep(1000);
        system("cls"); 
        color(7);
        CursorJump(2 * (COL / 3), ROW / 2 - 3);
        if (grade > max)
        {
            printf("恭喜你打破最高记录,最高记录更新为%d", grade);
            WriteGrade();
        }
        else if (grade == max)
        {
            printf("与最高记录持平,加油再创佳绩", grade);
        }
        else
        {
            printf("请继续加油,当前与最高记录相差%d", max - grade);
        }
        CursorJump(2 * (COL / 3), ROW / 2);
        printf("GAME OVER");
        while (1) 
        {
            char ch;
            CursorJump(2 * (COL / 3), ROW / 2 + 3);
            printf("再来一局?(y/n):");
            scanf("%c", &ch);
            if (ch == 'y' || ch == 'Y')
            {
                system("cls");
                main();
            }
            else if (ch == 'n' || ch == 'N')
            {
                CursorJump(2 * (COL / 3), ROW / 2 + 5);
                exit(0);
            }
            else
            {
                CursorJump(2 * (COL / 3), ROW / 2 + 5);
                printf("选择错误,请再次选择");
            }
        }
    }
}
 
void DrawSnake(int flag)
{
    if (flag == 1) 
    {
        color(10); 
        CursorJump(2 * snake.x, snake.y);
        printf("■"); 
        for (int i = 0; i < snake.len; i++)
        {
            CursorJump(2 * body[i].x, body[i].y);
            printf("□"); 
        }
    }
    else
    {
        if (body[snake.len - 1].x != 0) 
        {
            CursorJump(2 * body[snake.len - 1].x, body[snake.len - 1].y);
            printf("  ");
        }
    }
}
void MoveSnake(int x, int y)
{
    DrawSnake(0); 
    face[body[snake.len - 1].y][body[snake.len - 1].x] = KONG; 
    face[snake.y][snake.x] = BODY;
 
    for (int i = snake.len - 1; i > 0; i--)
    {
        body[i].x = body[i - 1].x;
        body[i].y = body[i - 1].y;
    }
    body[0].x = snake.x;
    body[0].y = snake.y;
    snake.x = snake.x + x;
    snake.y = snake.y + y;
    DrawSnake(1); 
}
void run(int x, int y)
{
    int t = 0;
    while (1)
    {
        if (t == 0)
            t = 3000;
        while (--t)
        {
            if (kbhit() != 0)
                break;
        }
        if (t == 0) //键盘未被敲击
        {
            JudgeFunc(x, y); //判断到达该位置后,是否得分与游戏结束
            MoveSnake(x, y); //移动蛇
        }
        else //键盘被敲击
        {
            break; 
        }
    }
}
void Game()
{
    int n = RIGHT; 
    int tmp = 0; 
    goto first; 
    while (1)
    {
        n = getch(); //读取键值
        switch (n)
        {
        case UP:
        case DOWN: 
            if (tmp != LEFT && tmp != RIGHT) 
            {
                n = tmp; //那么下一次蛇的移动方向设置为上一次蛇的移动方向
            }
            break;
        case LEFT:
        case RIGHT: 
            if (tmp != UP && tmp != DOWN) 
            {
                n = tmp; 
            }
        case SPACE:
        case ESC:
        case 'r':
        case 'R':
            break; //这四个无需调整
        default:
            n = tmp; 
            break;
        }
    first:
        switch (n)
        {
        case UP: 
            run(0, -1); 
            tmp = UP;
            break;
        case DOWN: //方向键:下
            run(0, 1); 
            tmp = DOWN; //记录当前蛇的移动方向
            break;
        case LEFT: //方向键:左
            run(-1, 0); 
            tmp = LEFT; //记录当前蛇的移动方向
            break;
        case RIGHT: 
            run(1, 0); 
            tmp = RIGHT; 
            break;
        case SPACE: //暂停
            system("pause>nul"); 
            break;
        case ESC: 
            system("cls");
            color(7); 
            CursorJump(COL - 8, ROW / 2);
            printf("  游戏结束  ");
            CursorJump(COL - 8, ROW / 2 + 2);
            exit(0);
        case 'r':
        case 'R': 
            system("cls"); 
            main();
        }
    }
}

                       

用windows api 做的贪吃蛇 #include #include"resource.h" #include"Node.h" #include #include TCHAR szAppname[] = TEXT("Snack_eat"); #define SIDE (x_Client/80) #define x_Client 800 #define y_Client 800 #define X_MAX 800-20-SIDE //点x的范围 #define Y_MAX 800-60-SIDE //点y的范围 #define TIME_ID 1 #define SECOND 100 #define NUM_POINT 10 //点的总个数 #define ADD_SCORE 10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; //窗口句柄 MSG msg; //消息 WNDCLASS wndclass; //窗口类 HACCEL hAccel;//加速键句柄 wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口的水平和垂直尺寸被改变时,窗口被重绘 wndclass.lpfnWndProc = WndProc; //窗口过程为WndProc函数 wndclass.cbClsExtra = 0; //预留额外空间 wndclass.cbWndExtra = 0; //预留额外空间 wndclass.hInstance = hInstance; //应用程序的实例句柄,WinMain的第一个参数 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //设置图标 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //载入预定义的鼠标指针 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置画刷 wndclass.lpszMenuName = szAppname; //设置菜单 wndclass.lpszClassName = szAppname; //设置窗口类的名字 if (!RegisterClass(&wndclass))//注册窗口类 { MessageBox(NULL, TEXT("这个程序需要windows NT!"), szAppname, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppname, TEXT("Snack_eat"),//CreateWindow函数调用时,WndProc将受到WM_CREATE WS_OVERLAPPEDWINDOW&~WS_THICKFRAME& ~WS_MAXIMIZEBOX,//普通的层叠窗口&禁止改变大小&禁止最大化 CW_USEDEFAULT, //初始x坐标(默认) CW_USEDEFAULT, //初始y坐标 x_Client, //初始x方向尺寸 770 y_Client, //初始y方向尺寸 750 NULL, //父窗口句柄 NULL, //窗口菜单句柄 hInstance, //程序实例句柄 WinMain函数中第二个参数 NULL); //创建参数 ShowWindow(hwnd, iCmdShow);//显示窗口,iCmdShow是WinMain的第四个参数,决定窗口在屏幕中的初始化显示形式,例:SW_SHOWNORMAL表示正常显示 UpdateWindow(hwnd);//使窗口客户区重绘,通过向WndProc发送一条WM_PAINT消息而完成的 hAccel = LoadAccelerators(hInstance, szAppname);//加载加速键 while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(hwnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }/* while (GetMessage(&msg, NULL, 0, 0))//GetMessage函数从消息队列中得到消息,填充msg。如果msg.message等于WM_QUIT,返回0,否则返回非0 { TranslateMessage(&msg);//将msg返回给windows已进行某些键盘消息的转换 DispatchMessage(&msg);//将msg再次返回给windows }*/ return msg.wParam;//msg.wParam是PostQuitMessage函数的参数值,通常是0 } ...
### 回答1: 以下是一个简单的贪吃蛇游戏的 C 语言程序代码: ```c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> #define MAX_LENGTH 100 int width = 20; // 游戏窗口宽度 int height = 20; // 游戏窗口高度 int x, y; // 蛇头坐标 int food_x, food_y; // 食物坐标 int score; // 得分 int tail_x[MAX_LENGTH], tail_y[MAX_LENGTH]; // 蛇身坐标 int tail_length; // 蛇身长度 enum direction {STOP = 0, LEFT, RIGHT, UP, DOWN}; // 方向控制 enum direction dir; void init() { x = width / 2; y = height / 2; food_x = rand() % width; food_y = rand() % height; score = 0; dir = STOP; } void draw() { system("cls"); for (int i = 0; i < width+2; i++) printf("#"); printf("\n"); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (j == 0) printf("#"); if (i == y && j == x) printf("O"); else if (i == food_y && j == food_x) printf("F"); else { int flag = 0; for (int k = 0; k < tail_length; k++) { if (tail_x[k] == j && tail_y[k] == i) { printf("o"); flag = 1; } } if (!flag) printf(" "); } if (j == width - 1) printf("#"); } printf("\n"); } for (int i = 0; i < width+2; i++) printf("#"); printf("\n"); printf("Score: %d\n", score); } void input() { if (kbhit()) { switch (getch()) { case 'a': dir = LEFT; break; case 'd': dir = RIGHT; break; case 'w': dir = UP; break; case 's': dir = DOWN; break; case 'x': dir = STOP; break; case 'q': exit(0); break; } } } void logic() { int prev_x = tail_x[0], prev_y = tail_y[0]; int prev2_x, prev2_y; tail_x[0] = x; tail_y[0] = y; for (int i = 1; i < tail_length; i++) { prev2_x = tail_x[i]; prev2_y = tail_y[i]; tail_x[i] = prev_x; tail_y[i] = prev_y; prev_x = prev2_x; prev_y = prev2_y; } switch (dir) { case LEFT: x--; break; case RIGHT: x++; break; case UP: y--; break; case DOWN: y++; break; } if (x >= width) x = 0; else if (x < 0) x = width - 1; if (y >= height) y = 0; else if (y < 0) y = height - 1; for (int i = 0; i < tail_length; i++) { if (tail_x[i] == x && tail_y[i] == y) { score = 0; tail_length = 0; } } if (x == food_x && y == food_y) { score += 10; food_x = rand() % width; food_y = rand() % height; tail_length++; } } int main() { init(); while (1) { draw(); input(); logic(); Sleep(100); } return 0; } ``` 这个程序使用了 Windows.h 头文件,所以只能在 Windows 系统上运行。如果需要在其他系统上运行,需要将 `system("cls")` 改为相应的清屏命令。 ### 回答2: 贪吃蛇是一款经典的游戏,一般由一个蛇和苹果组成。游戏目标是控制蛇吃苹果,每吃到一个苹果蛇身长度增加一节。如果蛇头撞到蛇身或者撞墙,则游戏结束。 以下是一个简单的贪吃蛇C语言程序代码: ```c #include <stdio.h> #include <conio.h> #include <windows.h> #define WIDTH 20 #define HEIGHT 15 int score; int gameOver; int x, y; // 蛇头的坐标 int fruitX, fruitY; // 苹果的坐标 int tailX[100], tailY[100]; // 蛇身的坐标 int tailLength; enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN }; enum eDirection dir; void Setup() { gameOver = 0; dir = STOP; x = WIDTH / 2; y = HEIGHT / 2; fruitX = rand() % WIDTH; fruitY = rand() % HEIGHT; score = 0; } void Draw() { system("cls"); for (int i = 0; i < WIDTH + 2; i++) printf("#"); printf("\n"); for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { if (j == 0) printf("#"); if (i == y && j == x) printf("O"); else if (i == fruitY && j == fruitX) printf("F"); else { int printTail = 0; for (int k = 0; k < tailLength; k++) { if (tailX[k] == j && tailY[k] == i) { printf("o"); printTail = 1; } } if (!printTail) printf(" "); } if (j == WIDTH - 1) printf("#"); } printf("\n"); } for (int i = 0; i < WIDTH + 2; i++) printf("#"); printf("\n"); printf("Score: %d\n", score); } void Input() { if (_kbhit()) { switch (_getch()) { case 'a': dir = LEFT; break; case 'd': dir = RIGHT; break; case 'w': dir = UP; break; case 's': dir = DOWN; break; case 'x': gameOver = 1; break; } } void Logic() { int prevX = tailX[0]; int prevY = tailY[0]; int prev2X, prev2Y; tailX[0] = x; tailY[0] = y; for (int i = 1; i < tailLength; i++) { prev2X = tailX[i]; prev2Y = tailY[i]; tailX[i] = prevX; tailY[i] = prevY; prevX = prev2X; prevY = prev2Y; } switch (dir) { case LEFT: x--; break; case RIGHT: x++; break; case UP: y--; break; case DOWN: y++; break; } if (x >= WIDTH) x = 0; else if (x < 0) x = WIDTH - 1; if (y >= HEIGHT) y = 0; else if (y < 0) y = HEIGHT - 1; for (int i = 0; i < tailLength; i++) { if (tailX[i] == x && tailY[i] == y) { gameOver = 1; break; } } if (x == fruitX && y == fruitY) { score += 10; fruitX = rand() % WIDTH; fruitY = rand() % HEIGHT; tailLength++; } } int main() { Setup(); while (!gameOver) { Draw(); Input(); Logic(); Sleep(10); // 控制帧率 } return 0; } ``` 这个C语言程序通过控制台绘制了一个贪吃蛇游戏界面。可以使用键盘的ADWS键来控制蛇的移动方向,X键用来退出游戏。贪吃蛇移动时,每吃到一个苹果分数增加10分,同时长度也会增加一节。如果蛇头撞到蛇身或者撞墙,则游戏结束。 ### 回答3: 贪吃蛇是一款经典的游戏,在C语言中编写贪吃蛇的程序代码相当有趣。 首先,我们需要定义一些常量,如窗口宽度、高度、蛇身长度等。然后,我们需要定义蛇的结构体,包括蛇头位置、蛇身数组、蛇的长度等成员变量。 接下来,我们需要实现一些基本的功能函数,如初始化蛇头位置、绘制蛇身、处理键盘输入等。在每次游戏循环中,我们需要不断更新蛇的位置,并处理碰撞事件,如蛇头与边界、自身以及食物的碰撞。 当蛇头与食物碰撞时,蛇的长度增加,然后随机生成一个新的食物位置。同时,我们还需要实现一个函数来判断游戏是否结束,即蛇头与边界或自身碰撞。 在游戏主循环中,我们通过不断更新蛇的位置,并根据用户的输入来改变蛇的方向。通过不断刷新屏幕来实现动画效果,让蛇在窗口中移动。 最后,在主函数中调用以上函数,并通过一个循环来控制游戏的进行。当游戏结束时,展示最终得分,并询问玩家是否重新开始游戏。 总之,贪吃蛇C语言程序代码实现起来并不复杂,主要涉及蛇的移动、碰撞检测以及界面的绘制等基本操作。有了上述的框架和思路,我们就可以编写出一个简单而有趣的贪吃蛇游戏了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值