大专考试,C语言贪吃蛇程序编写,

大专考试,C语言贪吃蛇程序编写,,第1张

//DEV C++ 通过

/

program by wlfryq  71693456@qqcom

/

#include <stdioh>

#include <stdlibh>

#include <conioh>

#include <windowsh>

#include <timeh>

#include <directh>

#include <stdboolh>

#define W 80    //屏幕宽度 

#define H 37    //屏幕高度 

#define SNAKE_ALL_LENGTH 200   //蛇身最长为 

void CALLBACK TimerProc(

HWND hwnd,       

        UINT message,     

        UINT idTimer,     

        DWORD dwTime);

void start();

struct MYPOINT

{

int x;

int y;

} s[SNAKE_ALL_LENGTH] , head, end, food;

int max_count=0; //历史最高分,如果count>max_count, 则max_count=count

int old_max_count=0;  //历史最高分,不会变动, 用于死亡时判断max_count是否大于old_max_count,如果大于,则写入文件 

int count=0;  //得分 

int len=20;   //当前蛇身长度 

int direct=0; //方向: 0-向右, 1-向下, 2-向左, 3-向上

int speed=200;  //速度:毫秒 

bool isfood=false; //食物是否存在

int timerID;

bool stop=false;   //暂停 

char ini_path;    //数据文件绝对路径 

void setxy(int x, int y)  //设置CMD窗口光标位置

{

   COORD coord = {x, y};

   SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

}

void hide_cursor() //隐藏CMD窗口光标

{

CONSOLE_CURSOR_INFO cci;

ccibVisible = FALSE;

ccidwSize = sizeof(cci);

HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

SetConsoleCursorInfo(handle, &cci);

}

void set_food()      //设置食物坐标 

{

if(isfood==true)

{

return;

}

int x,y,i;

bool flag=false;

while(1)

{

flag=false;

x=rand()%(W-14)+6;

y=rand()%(H-12)+6;

for(i=0;i<len;i++)      //判断食物是否落在蛇身上 

{

if(s[i]x==x && s[i]y==y)

{

flag=true;

break;

}

}

if(flag==true)

{

continue;

}

else

{

foodx=x;

foody=y;

break;

}

}

setxy(foodx,foody);

printf("");

isfood=true;

}

void check_board()    //检测蛇身是否越界和相交 

{

int i;

if(s[0]x>=W-3 || s[0]x<=2 || s[0]y>=H-1 || s[0]y<=2)

{

setxy(W/2-5,0);

printf("game over\n");

stop=true;

if(old_max_count<max_count)

{

char t[5]={'\0'};

sprintf(t,"%d",max_count);

WritePrivateProfileString("MAX_COUNT","max_count",t,ini_path);

}

}

for(i=1;i<len;i++)

{

if(s[i]x==s[0]x && s[i]y==s[0]y)

{

setxy(W/2-5,0);

printf("game over\n");

stop=true;

if(old_max_count<max_count)

{

char t[5]={'\0'};

sprintf(t,"%d",max_count);

WritePrivateProfileString("MAX_COUNT","max_count",t,ini_path);

}

break;

}

}

if(stop==true)

{

KillTimer(NULL,timerID);

int c;

while(1)

{

fflush(stdin);

c=_getch();

if(c=='n' || c=='N')

{

start();

}

else if(c=='q' || c=='Q')

{

exit(0);

}

else continue;

}

}

}

void printf_body(bool is_first)  //打印蛇身 

{

if(is_first==true)     //如果是第一次打印蛇身 

{

int i;

for(i=0;i<len;i++)

{

setxy(s[i]x,s[i]y);

printf("O");

}

}

else                  //如果不是第一次打印蛇身 

{

setxy(endx,endy);

printf(" ");

setxy(s[0]x,s[0]y);

printf("O");

}

if(foodx==s[0]x && foody==s[0]y)  //如果吃到食物 

{

count++;

isfood=false;                     //重置食物 

set_food();

len++;

KillTimer(NULL,timerID);

if(speed>100) speed-=10;

else if(speed>50) speed-=5;

else if(speed>30) speed-=2;

else if(speed>16) speed-=1;

else ;

setxy(0,0);

if(max_count<count) max_count=count;

printf("  speed : %d ms     score : %d                                   best score:%d  ",speed,count,max_count);

timerID=SetTimer(NULL,001,speed,TimerProc);

}

}

void change_body_pos(int x, int y)   //改变蛇身的坐标数据 

{

endx=s[len-1]x;

endy=s[len-1]y;

int i;

for(i=len-1;i>0;i--)

{

s[i]x=s[i-1]x;

s[i]y=s[i-1]y;

}

s[0]x=x;

s[0]y=y;

}

void CALLBACK TimerProc(

HWND hwnd,       

        UINT message,     

        UINT idTimer,     

        DWORD dwTime)

{

switch(direct)

{

case 0:

headx++;

change_body_pos(headx,heady);

printf_body(false);

check_board();

break;

case 1:

heady++;

change_body_pos(headx,heady);

printf_body(false);

check_board();

break;

case 2:

headx--;

change_body_pos(headx,heady);

printf_body(false);

check_board();

break;

case 3:

heady--;

change_body_pos(headx,heady);

printf_body(false);

check_board();

break;

}

}

void start()

{

int i;

KillTimer(NULL,timerID);

count=0;  //得分 

len=20;   //当前蛇身长度 

direct=0; //方向: 0-向右, 1-向下, 2-向左, 3-向上

speed=200;  //速度:毫秒 

isfood=false; //食物是否存在

stop=false;   //停止 

system("cls");

setxy(1,4);

printf("┌─────────────────────────────────────┐\n");

for(i=0;i<33;i++)

{

printf(" │                                                                          │\n");

}

printf(" └─────────────────────────────────────┘");

headx=len-1+5;

heady=H/2;

for(i=0;i<len;i++)

{

s[i]x=headx-i;

s[i]y=heady;

}

setxy(0,0);

printf("  speed : %d:ms     score : %d                                   best score:%d  ",speed,count,max_count);

printf_body(true);

set_food();

timerID=SetTimer(NULL,001,speed,TimerProc);

int c;

MSG msg;

while(GetMessage(&msg,NULL,0,0))

{

if(stop==true) break;

if(_kbhit())   //如果按下的是方向键或功能键, _getch()要调用两次,第一次返回0XE0或0 

{

fflush(stdin);

c=_getch();   //上: 72 下:80  左:75  右:77 

if(c==0XE0 || c==0)

{

c=_getch();

if(c==72 && direct!=1 && direct!=3)

{

direct=3;

}

else if(c==80 && direct!=1 && direct!=3)

{

direct=1;

}

else if(c==75 && direct!=0 && direct!=2)

{

direct=2;

}

else if(c==77 && direct!=0 && direct!=2)

{

direct=0;

}

}

else if(c==' ')

{

setxy(W/2-10,0);

system("pause");

setxy(W/2-10,0);

printf("                    ");

}

}

if(msgmessage==WM_TIMER)

{

DispatchMessage(&msg);

}

}

}

int main()

{

ini_path=(char)malloc(sizeof(char)50);

srand((unsigned)time(0));

getcwd(ini_path,50);//取得当前程序绝对路径

ini_path=strcat(ini_path,"snakedat");

max_count=GetPrivateProfileInt("MAX_COUNT","max_count",0,ini_path);

old_max_count=max_count;

char cmd[50];

sprintf(cmd,"mode con cols=%d lines=%d\0",W,H);

system(cmd);//改变CMD窗口大小

hide_cursor();

start();

return 0;

}

#include<graphicsh>

#include<stdlibh>

#include<dosh>

#define LEFT 0x4b00

#define RIGHT 0x4d00

#define DOWN 0x5000

#define UP 0x4800

#define ESC 0x011b

int i,key;

int score=0;

int gamespeed=32000;

struct Food /食物的结构体/

{

int x; /食物的横坐标/

int y; /食物的纵坐标/

int yes; /食物是否出现的变量/

}food;

struct Snack /蛇的结构体/

{

int x[N];

int y[N];

int node; /蛇的节数/

int direction; /蛇的方向/

int life; /蛇的生命,0活着,1死亡/

}snake;

void Init(void); /图形驱动/

void Close(void); /关闭游戏函数/

void DrawK(void); /画图函数/

void GameOver(void);/输出失败函数/

void GamePlay(); /游戏控制函数 主要程序/

void PrScore(void); /分数输出函数/

DELAY(char ch)/调节游戏速度/

{

if(ch=='3')

{

delay(gamespeed); /delay是延迟函数/

delay(gamespeed);

}

else if(ch=='2')

{

delay(gamespeed);

}

}

Menu()/游戏开始菜单/

{

char ch;

printf("Please choose the gamespeed:\n");

printf("1-Fast 2-Normal 3-Slow\n");

printf("\nPlease Press The numbers\n");

do

{ch=getch();}

while(ch!='1'&&ch!='2'&&ch!='3');

clrscr();

return(ch);

}

/主函数/

void main(void)

{

int ch;

ch=Menu();

Init();

DrawK();

GamePlay(ch);

Close();

}

void Init(void)

{

int gd=DETECT,gm;

initgraph(&gd,&gm,"c:\\tc");

cleardevice();

}

void DrawK(void)

{

setcolor(11);

setlinestyle(SOLID_LINE,0,THICK_WIDTH);

for(i=50;i<=600;i+=10)

{

rectangle(i,40,i+10,49); /画出上边框/

rectangle(i,451,i+10,460); /画出下边框/

}

for(i=40;i<=450;i+=10)

{

rectangle(50,i,59,i+10); /画出左边框/

rectangle(601,i,610,i+10); /画出右边框/

}

}

void GamePlay(char ch)

{

randomize(); /随机数发生器/

foodyes=1; /1代表要出现食物,0表示以存在食物/

snakelife=0;

snakedirection=1;

snakex[0]=100;snakey[0]=100;

snakex[1]=110;snakey[1]=100;

snakenode=2;

PrScore();

while(1) /可以重复游戏/

{

while(!kbhit()) /在没有按键的情况下蛇自己移动/

{

if(foodyes==1) /需要食物/

{

foodx=rand()%400+60;

foody=rand()%350+60; /使用rand函数随机产生食物坐标/

while(foodx%10!=0)

foodx++;

while(foody%10!=0)

foody++; /判断食物是否出现在整格里/

foodyes=0; /现在有食物了/

}

if(foodyes==0) /有食物了就要显示出来/

{

setcolor(GREEN);

rectangle(foodx,foody,foodx+10,foody-10);

}

for(i=snakenode-1;i>0;i--) /贪吃蛇的移动算法/

{

snakex[i]=snakex[i-1];

snakey[i]=snakey[i-1]; /贪吃蛇的身体移动算法/

}

switch(snakedirection) /贪吃蛇的头部移动算法,以此来控制移动/

{

case 1:snakex[0]+=10;break;

case 2:snakex[0]-=10;break;

case 3:snakey[0]-=10;break;

case 4:snakey[0]+=10;break;

}

for(i=3;i<snakenode;i++) /判断是否头部与身体相撞/

{

if(snakex[i]==snakex[0]&&snakey[i]==snakey[0])

{

GameOver();

snakelife=1;

break;

}

}

/下面是判断是否撞到墙壁/

if(snakex[0]<55||snakex[0]>595||snakey[0]<55||snakey[0]>455)

{

GameOver();

snakelife=1;

}

if(snakelife==1) /如果死亡就退出循环/

break;

if(snakex[0]==foodx&&snakey[0]==foody) /判断蛇是否吃到食物/

{

setcolor(0);

rectangle(foodx,foody,foodx+10,foody-10); /吃的食物后用黑色将食物擦去/

snakex[snakenode]=-20;snakey[snakenode]=-20; /现把增加的一节放到看不到的地方去/

snakenode++;

foodyes=1;

score+=10;

PrScore();

}

setcolor(4); /每次移动后将后面的身体擦去/

for(i=0;i<snakenode;i++)

rectangle(snakex[i],snakey[i],snakex[i]+10,snakey[i]-10);

delay(gamespeed);

DELAY(ch);

setcolor(0);

rectangle(snakex[snakenode-1],snakey[snakenode-1],snakex[snakenode-1]+10,snakey[snakenode-1]-10);

}

if(snakelife==1)

break;

key=bioskey(0); /接受按键/

if(key==ESC)

break;

else

if(key==UP&&snakedirection!=4)/判断是否改变方向/

snakedirection=3;

else

if(key==RIGHT&&snakedirection!=2)

snakedirection=1;

else

if(key==LEFT&&snakedirection!=1)

snakedirection=2;

else

if(key==DOWN&&snakedirection!=3)

snakedirection=4;

}

}

void GameOver(void)

{

cleardevice();

setcolor(RED);

settextstyle(0,0,4);

outtextxy(200,200,"GAME OVER");

getch();

}

void PrScore(void)

{

char str[10];

setfillstyle(SOLID_FILL,YELLOW);

bar(50,15,220,35);

setcolor(6);

settextstyle(0,0,2);

sprintf(str,"scord:%d",score);

outtextxy(55,20,str);

}

void Close(void)

{

getch();

closegraph();

}

用MVC方式实现的贪吃蛇游戏,共有4个类。运行GreedSnake运行即可。主要是观察者模式的使用,我已经添加了很多注释了。

1、

/

程序名称:贪食蛇

原作者:BigF

修改者:algo

说明:我以前也用C写过这个程序,现在看到BigF用Java写的这个,发现虽然作者自称是Java的初学者,

但是明显编写程序的素养不错,程序结构写得很清晰,有些细微得地方也写得很简洁,一时兴起之

下,我认真解读了这个程序,发现数据和表现分开得很好,而我近日正在学习MVC设计模式,

因此尝试把程序得结构改了一下,用MVC模式来实现,对源程序得改动不多。

我同时也为程序增加了一些自己理解得注释,希望对大家阅读有帮助。

/

package mvcTest;

/

@author WangYu

@version 10

Description:

</pre>

Create on :Date :2005-6-13 Time:15:57:16

LastModified:

History:

/

public class GreedSnake {

public static void main(String[] args) {

SnakeModel model = new SnakeModel(20,30);

SnakeControl control = new SnakeControl(model);

SnakeView view = new SnakeView(model,control);

//添加一个观察者,让view成为model的观察者

modeladdObserver(view);

(new Thread(model))start();

}

}

-------------------------------------------------------------

2、

package mvcTest;

//SnakeControljava

import javaawteventKeyEvent;

import javaawteventKeyListener;

/

MVC中的Controler,负责接收用户的 *** 作,并把用户 *** 作通知Model

/

public class SnakeControl implements KeyListener{

SnakeModel model;

public SnakeControl(SnakeModel model){

thismodel = model;

}

public void keyPressed(KeyEvent e) {

int keyCode = egetKeyCode();

if (modelrunning){ // 运行状态下,处理的按键

switch (keyCode) {

case KeyEventVK_UP:

modelchangeDirection(SnakeModelUP);

break;

case KeyEventVK_DOWN:

modelchangeDirection(SnakeModelDOWN);

break;

case KeyEventVK_LEFT:

modelchangeDirection(SnakeModelLEFT);

break;

case KeyEventVK_RIGHT:

modelchangeDirection(SnakeModelRIGHT);

break;

case KeyEventVK_ADD:

case KeyEventVK_PAGE_UP:

modelspeedUp();

break;

case KeyEventVK_SUBTRACT:

case KeyEventVK_PAGE_DOWN:

modelspeedDown();

break;

case KeyEventVK_SPACE:

case KeyEventVK_P:

modelchangePauseState();

break;

default:

}

}

// 任何情况下处理的按键,按键导致重新启动游戏

if (keyCode == KeyEventVK_R ||

keyCode == KeyEventVK_S ||

keyCode == KeyEventVK_ENTER) {

modelreset();

}

}

public void keyReleased(KeyEvent e) {

}

public void keyTyped(KeyEvent e) {

}

}

-------------------------------------------------------------

3、

/

/

package mvcTest;

/

游戏的Model类,负责所有游戏相关数据及运行

@author WangYu

@version 10

Description:

</pre>

Create on :Date :2005-6-13 Time:15:58:33

LastModified:

History:

/

//SnakeModeljava

import javaxswing;

import javautilArrays;

import javautilLinkedList;

import javautilObservable;

import javautilRandom;

/

游戏的Model类,负责所有游戏相关数据及运行

/

class SnakeModel extends Observable implements Runnable {

boolean[][] matrix; // 指示位置上有没蛇体或食物

LinkedList nodeArray = new LinkedList(); // 蛇体

Node food;

int maxX;

int maxY;

int direction = 2; // 蛇运行的方向

boolean running = false; // 运行状态

int timeInterval = 200; // 时间间隔,毫秒

double speedChangeRate = 075; // 每次得速度变化率

boolean paused = false; // 暂停标志

int score = 0; // 得分

int countMove = 0; // 吃到食物前移动的次数

// UP and DOWN should be even

// RIGHT and LEFT should be odd

public static final int UP = 2;

public static final int DOWN = 4;

public static final int LEFT = 1;

public static final int RIGHT = 3;

public SnakeModel( int maxX, int maxY) {

thismaxX = maxX;

thismaxY = maxY;

reset();

}

public void reset(){

direction = SnakeModelUP; // 蛇运行的方向

timeInterval = 200; // 时间间隔,毫秒

paused = false; // 暂停标志

score = 0; // 得分

countMove = 0; // 吃到食物前移动的次数

// initial matirx, 全部清0

matrix = new boolean[maxX][];

for (int i = 0; i < maxX; ++i) {

matrix[i] = new boolean[maxY];

Arraysfill(matrix[i], false);

}

// initial the snake

// 初始化蛇体,如果横向位置超过20个,长度为10,否则为横向位置的一半

int initArrayLength = maxX > 20 10 : maxX / 2;

nodeArrayclear();

for (int i = 0; i < initArrayLength; ++i) {

int x = maxX / 2 + i;//maxX被初始化为20

int y = maxY / 2; //maxY被初始化为30

//nodeArray[x,y]: [10,15]-[11,15]-[12,15]~~[20,15]

//默认的运行方向向上,所以游戏一开始nodeArray就变为:

// [10,14]-[10,15]-[11,15]-[12,15]~~[19,15]

nodeArrayaddLast(new Node(x, y));

matrix[x][y] = true;

}

// 创建食物

food = createFood();

matrix[foodx][foody] = true;

}

public void changeDirection(int newDirection) {

// 改变的方向不能与原来方向同向或反向

if (direction % 2 != newDirection % 2) {

direction = newDirection;

}

}

/

运行一次

@return

/

public boolean moveOn() {

Node n = (Node) nodeArraygetFirst();

int x = nx;

int y = ny;

// 根据方向增减坐标值

switch (direction) {

case UP:

y--;

break;

case DOWN:

y++;

break;

case LEFT:

x--;

break;

case RIGHT:

x++;

break;

}

// 如果新坐标落在有效范围内,则进行处理

if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {

if (matrix[x][y]) { // 如果新坐标的点上有东西(蛇体或者食物)

if (x == foodx && y == foody) { // 吃到食物,成功

nodeArrayaddFirst(food); // 从蛇头赠长

// 分数规则,与移动改变方向的次数和速度两个元素有关

int scoreGet = (10000 - 200 countMove) / timeInterval;

score += scoreGet > 0 scoreGet : 10;

countMove = 0;

food = createFood(); // 创建新的食物

matrix[foodx][foody] = true; // 设置食物所在位置

return true;

} else // 吃到蛇体自身,失败

return false;

} else { // 如果新坐标的点上没有东西(蛇体),移动蛇体

nodeArrayaddFirst(new Node(x, y));

matrix[x][y] = true;

n = (Node) nodeArrayremoveLast();

matrix[nx][ny] = false;

countMove++;

return true;

}

}

return false; // 触到边线,失败

}

public void run() {

running = true;

while (running) {

try {

Threadsleep(timeInterval);

} catch (Exception e) {

break;

}

if (!paused) {

if (moveOn()) {

setChanged(); // Model通知View数据已经更新

notifyObservers();

} else {

JOptionPaneshowMessageDialog(null,

"you failed",

"Game Over",

JOptionPaneINFORMATION_MESSAGE);

break;

}

}

}

running = false;

}

private Node createFood() {

int x = 0;

int y = 0;

// 随机获取一个有效区域内的与蛇体和食物不重叠的位置

do {

Random r = new Random();

x = rnextInt(maxX);

y = rnextInt(maxY);

} while (matrix[x][y]);

return new Node(x, y);

}

public void speedUp() {

timeInterval = speedChangeRate;

}

public void speedDown() {

timeInterval /= speedChangeRate;

}

public void changePauseState() {

paused = !paused;

}

public String toString() {

String result = "";

for (int i = 0; i < nodeArraysize(); ++i) {

Node n = (Node) nodeArrayget(i);

result += "[" + nx + "," + ny + "]";

}

return result;

}

}

class Node {

int x;

int y;

Node(int x, int y) {

thisx = x;

thisy = y;

}

}

------------------------------------------------------------

4、

package mvcTest;

//SnakeViewjava

import javaxswing;

import javaawt;

import javautilIterator;

import javautilLinkedList;

import javautilObservable;

import javautilObserver;

/

MVC模式中得Viewer,只负责对数据的显示,而不用理会游戏的控制逻辑

/

public class SnakeView implements Observer {

SnakeControl control = null;

SnakeModel model = null;

JFrame mainFrame;

Canvas paintCanvas;

JLabel labelScore;

public static final int canvasWidth = 200;

public static final int canvasHeight = 300;

public static final int nodeWidth = 10;

public static final int nodeHeight = 10;

public SnakeView(SnakeModel model, SnakeControl control) {

thismodel = model;

thiscontrol = control;

mainFrame = new JFrame("GreedSnake");

Container cp = mainFramegetContentPane();

// 创建顶部的分数显示

labelScore = new JLabel("Score:");

cpadd(labelScore, BorderLayoutNORTH);

// 创建中间的游戏显示区域

paintCanvas = new Canvas();

paintCanvassetSize(canvasWidth + 1, canvasHeight + 1);

paintCanvasaddKeyListener(control);

cpadd(paintCanvas, BorderLayoutCENTER);

// 创建底下的帮助栏

JPanel panelButtom = new JPanel();

panelButtomsetLayout(new BorderLayout());

JLabel labelHelp;

labelHelp = new JLabel("PageUp, PageDown for speed;", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutNORTH);

labelHelp = new JLabel("ENTER or R or S for start;", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutCENTER);

labelHelp = new JLabel("SPACE or P for pause", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutSOUTH);

cpadd(panelButtom, BorderLayoutSOUTH);

mainFrameaddKeyListener(control);

mainFramepack();

mainFramesetResizable(false);

mainFramesetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);

mainFramesetVisible(true);

}

void repaint() {

Graphics g = paintCanvasgetGraphics();

//draw background

gsetColor(ColorWHITE);

gfillRect(0, 0, canvasWidth, canvasHeight);

// draw the snake

gsetColor(ColorBLACK);

LinkedList na = modelnodeArray;

Iterator it = naiterator();

while (ithasNext()) {

Node n = (Node) itnext();

drawNode(g, n);

}

// draw the food

gsetColor(ColorRED);

Node n = modelfood;

drawNode(g, n);

updateScore();

}

private void drawNode(Graphics g, Node n) {

gfillRect(nx nodeWidth,

ny nodeHeight,

nodeWidth - 1,

nodeHeight - 1);

}

public void updateScore() {

String s = "Score: " + modelscore;

labelScoresetText(s);

}

public void update(Observable o, Object arg) {

repaint();

}

}

希望采纳

以上就是关于大专考试,C语言贪吃蛇程序编写,全部的内容,包括:大专考试,C语言贪吃蛇程序编写,、求贪吃蛇的C++程序代码、求一段JAVA编写的贪吃蛇小程序源代码等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9434778.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存