贪吃蛇的编程
㈠ 如何用慧编程做贪吃蛇代码
用慧编程做贪吃蛇代码过程如下:
1、我们需要建立四个头文件,然后分别设置蛇的状态,上下左右,这是蛇能够有方向可走的前提,然后我们再设置蛇身的节点,定义一个简单的函数,这样蛇的全身以及他的行走方向就弄完了。
2、贪吃蛇不能穿墙代码。
3、第二步,一个函数这个函数的目的是贪吃蛇不能穿墙,很简单的代码分别设置长宽的最大位移,在内部范围内设置为一即可通过,否则不能穿墙。贪吃蛇随机生成一个食物。
4、设置一个随机函数。这样贪吃蛇代码就做好了。
慧编程是一款面向STEAM教育领域的积木式和代码编程软件,基于图形化编程开发。
㈡ c语言 贪吃蛇 程序
基本思路:
蛇每吃一个食物蛇身子就增加一格,用UP, DOWN, LEFT, RIGHT控制蛇头的运动,而蛇身子跟着蛇头走,每后一格蛇身子下一步走到上一格蛇身子的位置,以此类推。
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define BEG_X 2
#define BEG_Y 1
#define WID 20
#define HEI 20
HANDLE hout;
typedef enum {UP, DOWN, LEFT, RIGHT} DIR;
typedef struct Snake_body
{
COORD pos;//蛇身的位置
struct Snake_body *next;//下一个蛇身
struct Snake_body *prev;//前一个蛇身
}SNAKE, *PSNAKE;
PSNAKE head = NULL;//蛇头
PSNAKE tail = NULL;//蛇尾
//画游戏边框的函数
void DrawBorder()
{
int i, j;
COORD pos = {BEG_X, BEG_Y};
for(i = 0; i < HEI; ++i)
{
SetConsoleCursorPosition(hout, pos);
for(j = 0; j < WID; ++j)
{
if(i == 0)//第一行
{
if(j == 0)
printf("┏");
else if(j == WID - 1)
printf("┓");
else
printf("━");
}
else if(i == HEI - 1)//最后一行
{
if(j == 0)
printf("┗");
else if(j == WID - 1)
printf("┛");
else
printf("━");
}
else if(j == 0 || j == WID - 1)//第一列或最后一列
printf("┃");
else
printf(" ");
}
++pos.Y;
}
}
//添加蛇身的函数
void AddBody(COORD pos)
{
PSNAKE pnew = (PSNAKE)calloc(1, sizeof(SNAKE));
pnew->pos = pos;
if(!head)
{
head = tail = pnew;
}
else
{
pnew->next = head;//新创建蛇身的next指向原先的蛇头
head->prev = pnew;//原先的蛇头的prev指向新创建的蛇身
head = pnew;//把新创建的蛇身作为新的蛇头
}
SetConsoleCursorPosition(hout, head->pos);
printf("◎");
}
//蛇身移动的函数
void MoveBody(DIR dir)
{
PSNAKE ptmp;
COORD pos = head->pos;
switch(dir)
{
case UP:
if(head->pos.Y > BEG_Y + 1)
--pos.Y;
else
return;
break;
case DOWN:
if(head->pos.Y < BEG_Y + HEI - 2)
++pos.Y;
else
return;
break;
case LEFT:
if(head->pos.X > BEG_X + 2)
pos.X -= 2;
else
return;
break;
case RIGHT:
if(head->pos.X < BEG_X + (WID - 2) * 2)
pos.X += 2;
else
return;
break;
}
AddBody(pos);//添加了一个新的蛇头
ptmp = tail;//保存当前的蛇尾
tail = tail->prev;
if(tail)
tail->next = NULL;
SetConsoleCursorPosition(hout, ptmp->pos);
printf(" ");
free(ptmp);
}
int main()
{
int ctrl;
DIR dir = RIGHT;//初始蛇的方向是向右的
COORD pos = {BEG_X + 2, BEG_Y + HEI / 2};
system("color 0E");
system("mode con cols=90 lines=30");
hout = GetStdHandle(STD_OUTPUT_HANDLE);
printf(" ------------贪吃蛇的移动------------");
DrawBorder();
//自定义几个蛇的身体
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
//控制蛇的移动
while(ctrl = getch())
{
switch(ctrl)
{
case 'w':
if(dir == DOWN)
continue;
dir = UP;
break;
case 's':
if(dir == UP)
continue;
dir = DOWN;
break;
case 'a':
if(dir == RIGHT)
continue;
dir = LEFT;
break;
case 'd':
if(dir == LEFT)
continue;
dir = RIGHT;
break;
case 'q':
return 0;
}
MoveBody(dir);
}
return 0;
}
(2)贪吃蛇的编程扩展阅读:
实现逻辑
1,可以设置光标,就能实现制定位置打印制定符号。
2,涉及一个结构体,包含两个元素坐标元素和一个结构体指针。
3,结构体串联形成链表,遍历获取成员坐标,打印符号得到蛇身。
4,不断的加头,去尾,重新遍历坐标,再打印形成蛇的移动。
5,食物产生的位置判定,不能越界,也不能与蛇身体重合。
6,蛇的转向判定,一条规则,不允许倒退。
7,转向的实现,跟行进方向决定新的关节坐标(当前头的上下左右)
8,死亡检测,是否头节点坐标是否与墙壁重合,是否与身体其他关节重合。
9,加速减速,设置刷新休眠时间实现。
㈢ 贪吃蛇游戏的C语言编程
#include <windows.h>
#include <ctime>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#ifndef SNAKE_H
#define SNAKE_H
class Cmp
{
friend class Csnake;
int rSign; //横坐标
int lSign; //竖坐标
public:
// friend bool isDead(const Cmp& cmp);
Cmp(int r,int l){setPoint(r,l);}
Cmp(){}
void setPoint(int r,int l){rSign=r;lSign=l;}
Cmp operator-(const Cmp &m)const
{
return Cmp(rSign-m.rSign,lSign-m.lSign);
}
Cmp operator+(const Cmp &m)const
{
return Cmp(rSign+m.rSign,lSign+m.lSign);
}
};
const int maxSize = 5; //初始蛇身长度
class Csnake
{
Cmp firstSign; //蛇头坐标
Cmp secondSign;//蛇颈坐标
Cmp lastSign; //蛇尾坐标
Cmp nextSign; //预备蛇头
int row; //列数
int line; //行数
int count; //蛇身长度
vector<vector<char> > snakeMap;//整个游戏界面
queue<Cmp> snakeBody; //蛇身
public:
int GetDirections()const;
char getSymbol(const Cmp& c)const
//获取指定坐标点上的字符
{
return snakeMap[c.lSign][c.rSign];
}
Csnake(int n)
//初始化游戏界面大小
{
if(n<20)line=20+2;
else if(n>30)line=30+2;
else line=n+2;
row=line*3+2;
}
bool isDead(const Cmp& cmp)
{
return ( getSymbol(cmp)=='@' || cmp.rSign == row-1
|| cmp.rSign== 0 || cmp.lSign == line-1 ||
cmp.lSign == 0 );
}
void InitInstance(); //初始化游戏界面
bool UpdataGame(); //更新游戏界面
void ShowGame(); //显示游戏界面
};
#endif // SNAKE_H
using namespace std;
//测试成功
void Csnake::InitInstance()
{
snakeMap.resize(line); // snakeMap[竖坐标][横坐标]
for(int i=0;i<line;i++)
{
snakeMap[i].resize(row);
for(int j=0;j<row;j++)
{
snakeMap[i][j]=' ';
}
}
for(int m=1;m<maxSize+1;m++)
{
//初始蛇身
snakeMap[line/2][m]='@';
//将蛇身坐标压入队列
snakeBody.push(Cmp(m,(line/2)));
//snakeBody[横坐标][竖坐标]
}
//链表头尾
firstSign=snakeBody.back();
secondSign.setPoint(maxSize-1,line/2);
}
//测试成功
int Csnake::GetDirections()const
{
if(GetKeyState(VK_UP)<0) return 1; //1表示按下上键
if(GetKeyState(VK_DOWN)<0) return 2; //2表示按下下键
if(GetKeyState(VK_LEFT)<0) return 3; //3表示按下左键
if(GetKeyState(VK_RIGHT)<0)return 4; //4表示按下右键
return 0;
}
bool Csnake::UpdataGame()
{
//-----------------------------------------------
//初始化得分0
static int score=0;
//获取用户按键信息
int choice;
choice=GetDirections();
cout<<"Total score: "<<score<<endl;
//随机产生食物所在坐标
int r,l;
//开始初始已经吃食,产生一个食物
static bool eatFood=true;
//如果吃了一个,才再出现第2个食物
if(eatFood)
{
do
{
//坐标范围限制在(1,1)到(line-2,row-2)对点矩型之间
srand(time(0));
r=(rand()%(row-2))+1; //横坐标
l=(rand()%(line-2))+1;//竖坐标
//如果随机产生的坐标不是蛇身,则可行
//否则重新产生坐标
if(snakeMap[l][r]!='@')
{snakeMap[l][r]='*';}
}while (snakeMap[l][r]=='@');
}
switch (choice)
{
case 1://向上
//如果蛇头和社颈的横坐标不相同,执行下面操作
if(firstSign.rSign!=secondSign.rSign)nextSign.setPoint(firstSign.rSign,firstSign.lSign-1);
//否则,如下在原本方向上继续移动
else nextSign=firstSign+(firstSign-secondSign);
break;
case 2://向下
if(firstSign.rSign!=secondSign.rSign)nextSign.setPoint(firstSign.rSign,firstSign.lSign+1);
else nextSign=firstSign+(firstSign-secondSign);
break;
case 3://向左
if(firstSign.lSign!=secondSign.lSign)nextSign.setPoint(firstSign.rSign-1,firstSign.lSign);
else nextSign=firstSign+(firstSign-secondSign);
break;
case 4://向右
if(firstSign.lSign!=secondSign.lSign)nextSign.setPoint(firstSign.rSign+1,firstSign.lSign);
else nextSign=firstSign+(firstSign-secondSign);
break;
default:
nextSign=firstSign+(firstSign-secondSign);
}
//----------------------------------------------------------
if(getSymbol(nextSign)!='*' && !isDead(nextSign))
//如果没有碰到食物(且没有死亡的情况下),删除蛇尾,压入新的蛇头
{
//删除蛇尾
lastSign=snakeBody.front();
snakeMap[lastSign.lSign][lastSign.rSign]=' ';
snakeBody.pop();
//更新蛇头
secondSign=firstSign;
//压入蛇头
snakeBody.push(nextSign);
firstSign=snakeBody.back();
snakeMap[firstSign.lSign][firstSign.rSign]='@';
//没有吃食
eatFood=false;
return true;
}
//-----吃食-----
else if(getSymbol(nextSign)=='*' && !isDead(nextSign))
{
secondSign=firstSign;
snakeMap[nextSign.lSign][nextSign.rSign]='@';
//只压入蛇头
snakeBody.push(nextSign);
firstSign=snakeBody.back();
eatFood=true;
//加分
score+=20;
return true;
}
//-----死亡-----
else {cout<<"Dead"<<endl;cout<<"Your last total score is "<<score<<endl; return false;}
}
void Csnake::ShowGame()
{
for(int i=0;i<line;i++)
{
for(int j=0;j<row;j++)
cout<<snakeMap[i][j];
cout<<endl;
}
Sleep(1);
system("cls");
}
int main()
{
Csnake s(20);
s.InitInstance();
//s.ShowGame();
int noDead;
do
{
s.ShowGame();
noDead=s.UpdataGame();
}while (noDead);
system("pause");
return 0;
}
这个代码可以运行的,记得给分啦
㈣ 贪吃蛇编程
这里有我以前敲过的贪吃蛇,不介意可以参考一下,(ps:需要建一了application而不是console application)
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <time.h>
#define speed 200
#define left 100
#define top 50
#define right 500
#define bottom 350
struct snake
{
POINT pos;
snake *front,*next;
};
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
bool InitWindow(HINSTANCE,int);
void items(HDC,int,int);
void MoveSnake(int);
void remove();
void destroy();
void inf(int,int,int,int);
void inf(const char*,int,int,int,int);
void inf(const char*,int,int,int);
bool is_fail();
void eat();
void wall();
void show_fruit();
UINT ShowMode;
PAINTSTRUCT ps;
bool onoff;
HFONT hf;
char judge[20];
int dir;
HDC hdc;
HWND hwnd;
HBRUSH BlackBrush,MainBrush,NULLBrush;
HPEN MainPen,BlackPen;
snake *head,*tail,*temp;
POINT fruit;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
onoff=1;
int i;
dir=-2;
tail=NULL;
InitWindow(hInstance,nCmdShow);
for(i=0;i<5;i++)
{
if(!tail)
{
head=new snake;
tail=head;
head->pos.x=300+i*10;
head->pos.y=200;
items(hdc,head->pos.x,head->pos.y);
}
else
{
tail->next=new snake;
tail->next->front=tail;
tail=tail->next;
tail->pos.x=300+i*10;
tail->pos.y=200;
tail->next=NULL;
items(hdc,tail->pos.x,tail->pos.y);
}
}
hf=CreateFont(20,0,0,0,400,0,0,0,GB2312_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"华文行楷");
SelectObject(hdc,hf);
SetBkColor(hdc,RGB(124,146,131));
SelectObject(hdc,MainBrush);
wall();
show_fruit();
inf("得分:",260,0,0);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
destroy();
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
static int seed=15;
switch(msg)
{
case WM_TIMER:
MoveSnake(dir);
if(!is_fail())
{
KillTimer(hwnd,1);
MessageBox(hwnd,"you are lost","caption",0);
}
eat();
break;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
wall();
EndPaint(hwnd,&ps);
hdc=GetDC(hwnd);
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:dir=(dir!=1?-1:dir);break;
case VK_DOWN:dir=(dir!=-1?1:dir);break;
case VK_RIGHT:dir=(dir!=-2?2:dir);break;
case VK_LEFT:dir=(dir!=2?-2:dir);break;
}
break;
case WM_CLOSE:
if(MessageBox(hwnd,"确定退出?","caption",MB_YESNO)==IDYES)
DestroyWindow(hwnd);
break;
case WM_DESTROY:
ReleaseDC(hwnd,hdc);
KillTimer(hwnd,1);
PostQuitMessage(0);
break;
default:return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 1;
}
bool InitWindow(HINSTANCE hInstance,int nCmdShow)
{
WNDCLASS wc;
wc.style=CS_HREDRAW | CS_VREDRAW;
wc.lpszClassName="test";
wc.lpszMenuName=NULL;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hbrBackground=CreateSolidBrush(RGB(124,146,131));
wc.hIcon=NULL;
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hInstance=hInstance;
wc.lpfnWndProc=WndProc;
MainBrush=CreateSolidBrush(RGB(124,146,131));
BlackBrush=(HBRUSH)GetStockObject(BLACK_BRUSH);
NULLBrush=(HBRUSH)GetStockObject(NULL_BRUSH);
MainPen=CreatePen(PS_SOLID,1,RGB(124,146,131));
BlackPen=CreatePen(PS_SOLID,1,RGB(0,0,0));
if(!RegisterClass(&wc)) return false;
hwnd=CreateWindow("test","贪吃蛇",WS_SYSMENU,400,150,616,400,NULL,NULL,hInstance,NULL);
hdc=BeginPaint(hwnd,&ps);
if(!hwnd) return false;
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
SetTimer(hwnd,1,speed,NULL);
return true;
}
void items(HDC hdc,int x,int y)
{
SelectObject(hdc,BlackPen);
SelectObject(hdc,NULLBrush);
Rectangle(hdc,x,y,x+10,y+10);
SelectObject(hdc,BlackBrush);
Rectangle(hdc,x+2,y+2,x+8,y+8);
// DeleteObject(BlackPen);
// DeleteObject(BlackBrush);
}
void MoveSnake(int dir)
{
static int i=0;
remove();
tail=tail->front;
delete tail->next;
tail->next=NULL;
temp=new snake;
temp->next=head;
head->front=temp;
temp->pos.x=head->pos.x+(dir/2)*10;
temp->pos.y=head->pos.y+(dir%2)*10;
head=temp;
i++;
items(hdc,head->pos.x,head->pos.y);
}
void remove()
{
SelectObject(hdc,MainBrush);
SelectObject(hdc,MainPen);
Rectangle(hdc,tail->pos.x,tail->pos.y,tail->pos.x+10,tail->pos.y+10);
// DeleteObject(MainBrush);
// DeleteObject(MainPen);
}
void destroy()
{
while(head->next)
{
head=head->next;
delete head->front;
}
delete tail;
}
void inf(int x,int y,int px,int py)
{
inf("",x,y,px,py);
}
void inf(const char*str,int x,int y,int scores)
{
sprintf(judge,"%s%d",str,scores);
TextOut(hdc,x,y,judge,strlen(judge));
}
void inf(const char*str,int x,int y,int px,int py)
{
sprintf(judge,"%s(%d,%d) ",str,px,py);
TextOut(hdc,x,y,judge,strlen(judge));
}
bool is_fail()
{
temp=head;
int px=head->pos.x,py=head->pos.y;
if(px<left||px>=right||py<top||py>=bottom)
return 0;
while(temp->next)
{
temp=temp->next;
if(px==temp->pos.x&&py==temp->pos.y)
return 0;
}
return 1;
}
void show_fruit()
{
srand((UINT)time(NULL));
fruit.x=10*((rand()%(right-left-10))/10)+left;
fruit.y=10*((rand()%(bottom-top-10))/10)+top;
items(hdc,fruit.x,fruit.y);
}
void eat()
{
inf("食物:",0,25,fruit.x,fruit.y);
inf("蛇头:",0,0,head->pos.x,head->pos.y);
static int scores=0;
if(head->pos.x==fruit.x&&head->pos.y==fruit.y)
{
scores++;
inf("得分:",260,0,scores);
KillTimer(hwnd,1);
temp=new snake;
temp->next=head;
head->front=temp;
temp->pos.x=head->pos.x+(dir/2)*10;
temp->pos.y=head->pos.y+(dir%2)*10;
head=temp;
items(hdc,head->pos.x,head->pos.y);
SetTimer(hwnd,1,speed,NULL);
show_fruit();
}
}
void wall()
{
SelectObject(hdc,MainBrush);
Rectangle(hdc,left-1,top-1,right+1,bottom+1);
// DeleteObject(MainBrush);
}