周末作业
// 贪吃蛇.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <time.h>
using namespace std;
#define KEY_DOWN(vk_code) GetAsyncKeyState(vk_code)&0x8000?1:0
int _tmain(int argc, _TCHAR* argv[])
{
int arrMap[15][15] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
//蛇的结构体
struct Snake{
int nSnakeRow;
int nSnakeCol;
int nSnakeRowBk;
int nSnakeColBk;
};
//用数组存放蛇头到蛇尾的坐标
Snake arrSnake[20];
//初始化蛇头的方向
arrSnake[0].nSnakeRow = 5;
arrSnake[0].nSnakeCol = 5;
arrSnake[0].nSnakeRowBk = 0;
arrSnake[0].nSnakeColBk = 0;
//定义蛇的长度变量
int nLen = 1;
//食物的结构体
struct SFood{
int nFoodRow;
int nFoodCol;
};
//定义食物的随机出现,随机种子初始化
srand(time(nullptr));
//初始化食物
SFood sFood;
//随机生成食物
sFood.nFoodRow = rand() % 13 + 1;
sFood.nFoodCol = rand() % 13 + 1;
//控制方向的枚举值
enum
{
E_DIR_NONE
};
int nDir = E_DIR_NONE;
//数据更新,要在渲染的前面
//刷新
while (true)
{
//身体跟随蛇头
for (int i = 0; i < nLen; i++)
{
//备份当前这一节的坐标
arrSnake[i].nSnakeRowBk = arrSnake[i].nSnakeRow;
arrSnake[i].nSnakeColBk = arrSnake[i].nSnakeCol;
}
for (int i = 0; i < nLen; i++)
{
//把当前节的坐标给下一节
arrSnake[i + 1].nSnakeRow = arrSnake[i].nSnakeRowBk;
arrSnake[i + 1].nSnakeCol = arrSnake[i].nSnakeColBk;
}
//数据更新,要在渲染的前面
//让小人根据按键的方向一直动
if (nDir <= 3)
{
if (0 == nDir)
{
arrSnake[0].nSnakeRow--;
}
else if (1 == nDir)
{
arrSnake[0].nSnakeRow++;
}
else if (2 == nDir)
{
arrSnake[0].nSnakeCol--;
}
else if (3 == nDir)
{
arrSnake[0].nSnakeCol++;
}
}
//设置按键让贪吃蛇改变方向
if (KEY_DOWN(VK_UP))
{
nDir = 0;
}
else if (KEY_DOWN(VK_DOWN))
{
nDir = 1;
}
else if (KEY_DOWN(VK_LEFT))
{
nDir = 2;
}
else if (KEY_DOWN(VK_RIGHT))
{
nDir = 3;
}
//蛇吃食物
if (arrSnake[0].nSnakeRow == sFood.nFoodRow && arrSnake[0].nSnakeCol == sFood.nFoodCol)
{
//再次随机生成食物,让食物的位置变化
sFood.nFoodRow = rand() % 13 + 1;
sFood.nFoodCol = rand() % 13 + 1;
nLen++;
}
//渲染
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
bool DrawSnake = false;
for (int k = 0; k < nLen;k++)
{
if (i == arrSnake[k].nSnakeRow && j == arrSnake[k].nSnakeCol)
{
DrawSnake = true;
break;
}
}
if (1 == arrMap[i][j])
{
cout << "■";
}
else if (DrawSnake)
{
cout << "蛇";
}
else if (i == sFood.nFoodRow && j == sFood.nFoodCol)
{
cout << "肉";
}
else
{
cout << " ";
}
}
cout << endl;//数组换行输出
}
system("cls");
}
system("pause");
return 0;
}
教师案例(代码顺序更规范一点)
// Snake.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <time.h>
using namespace std;
#define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code)&0x8000?1:0)
//global
int g_arrMap[15][20] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
struct SNode
{
int nRow;
int nCol;
int nRowBk;
int nColBk;
};
struct SFood
{
int nRow;
int nCol;
};
SNode g_arrSnake[20] = {};
SFood g_Food;
int g_nLen = 1;
int g_nDir = 0;
int _tmain(int argc, _TCHAR* argv[])
{
srand(time(nullptr));
//给蛇头赋值
g_arrSnake[0].nRow = 5;
g_arrSnake[0].nCol = 10;
g_Food.nRow = 6;
g_Food.nCol = 5;
while (true)
{
//数据更新
if (KEY_DOWN(VK_UP))
{
g_nDir = 1;
}
else if (KEY_DOWN(VK_DOWN))
{
g_nDir = 2;
}
else if (KEY_DOWN(VK_LEFT))
{
g_nDir = 3;
}
else if (KEY_DOWN(VK_RIGHT))
{
g_nDir = 4;
}
//蛇头移动之前要进行坐标备份
g_arrSnake[0].nRowBk = g_arrSnake[0].nRow;
g_arrSnake[0].nColBk = g_arrSnake[0].nCol;
if (1 == g_nDir)
{
g_arrSnake[0].nRow--;
}
else if (2 == g_nDir)
{
g_arrSnake[0].nRow++;
}
else if (3 == g_nDir)
{
g_arrSnake[0].nCol--;
}
else if (4 == g_nDir)
{
g_arrSnake[0].nCol++;
}
//判断是否吃到食物
if (g_arrSnake[0].nRow == g_Food.nRow && g_Food.nCol == g_arrSnake[0].nCol)
{
//食物位置重新随机
//1-13
g_Food.nRow = rand() % 13 + 1;
g_Food.nCol = rand() % 18 + 1;
//蛇的长度要+1
g_nLen++;
}
//跟随
//从第一节开始跟随
for (int i = 1; i < 20; i++)
{
//第i节跟随过去之前要先进行坐标备份
g_arrSnake[i].nRowBk = g_arrSnake[i].nRow;
g_arrSnake[i].nColBk = g_arrSnake[i].nCol;
//后一节的坐标 = 前一节的备份坐标
g_arrSnake[i].nRow = g_arrSnake[i - 1].nRowBk;
g_arrSnake[i].nCol = g_arrSnake[i - 1].nColBk;
}
//渲染
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 20; j++)
{
//渲染蛇
bool bDrawSnake = false;
for (int m = 0; m < g_nLen; m++)
{
if (g_arrSnake[m].nRow == i && g_arrSnake[m].nCol == j)
{
bDrawSnake = true;
break;
}
}
if (1 == g_arrMap[i][j])
{
cout << "■";
}
else if (bDrawSnake)
{
cout << "蛇";
}
else if (g_Food.nRow == i && g_Food.nCol == j)
{
cout << "食";
}
else{
cout << " ";
}
}
cout << endl;
}
system("cls");
}
return 0;
}
剩余功能实现
1、蛇头撞墙后,显示游戏结束;
2、蛇头与蛇身相撞,显示游戏结束。
//检测蛇头是否幢墙
if (1 == arrMap[arrSnake[0].nSnakeRow][arrSnake[0].nSnakeCol])
{
cout << "Game over!"<<endl;
break;
}
//蛇头与蛇身的碰撞
for (int i= 1; i < 20; i++)
{
if ((arrSnake[0].nSnakeRow == arrSnake[i].nSnakeRow) && (arrSnake[0].nSnakeCol == arrSnake[i].nSnakeCol))
{
cout << "Game over!"<<endl;
break;
}
}