用C语言编写 贪吃蛇的思路啥怎么样的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C语言编写 贪吃蛇的思路啥怎么样的相关的知识,希望对你有一定的参考价值。

那些怎么样形成蛇的图形 和食物 还有游戏中的规则 用什么样的函数

表示??

请指点一下

用的编译器是 vc++6.0 那位老师告诉我 谢谢

把你的邮箱给我,我把源程序发给你,或者你自己从网上下载,这个snake程序是NetBSD操作系统源代码的一部分,要是你能发现Bug,我先恭喜你。

/* $NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $ */

/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)snake.c 8.2 (Berkeley) 1/7/94";
#else
__RCSID("$NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $");
#endif
#endif /* not lint */

/*
* snake - crt hack game.
*
* You move around the screen with arrow keys trying to pick up money
* without getting eaten by the snake. hjkl work as in vi in place of
* arrow keys. You can leave at the exit any time.
*
* compile as follows:
* cc -O snake.c move.c -o snake -lm -ltermlib
*/

#include <sys/param.h>

#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include "snake.h"
#include "pathnames.h"

#define PENALTY 10 /* % penalty for invoking spacewarp */

#define EOT '\004'
#define LF '\n'
#define DEL '\177'

#define ME 'I'
#define SNAKEHEAD 'S'
#define SNAKETAIL 's'
#define TREASURE '$'
#define GOAL '#'

#define BSIZE 80

struct point you;
struct point money;
struct point finish;
struct point snake[6];

int loot, penalty;
int long tl, tm = 0L;
int moves;
char stri[BSIZE];
char *p;
char ch, savec;
char *kl, *kr, *ku, *kd;
int fast = 1;
int repeat = 1;
time_t tv;
char *tn;

int main __P((int, char **));

int
main(argc, argv)
int argc;
char **argv;

extern char *optarg;
extern int optind;
int ch, i;

(void) time(&tv);
srandom((int) tv);

while ((ch = getopt(argc, argv, "l:w:")) != -1)
switch ((char) ch)
#ifdef notdef
case 'd':
tv = atol(optarg);
break;
#endif
case 'w': /* width */
ccnt = atoi(optarg);
break;
case 'l': /* length */
lcnt = atoi(optarg);
break;
case '?':
default:
fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr);
exit(1);


penalty = loot = 0;
getcap();

i = MIN(lcnt, ccnt);
if (i < 4)
cook();
pr("snake: screen too small for a fair game.\n");
exit(1);

/*
* chunk is the amount of money the user gets for each $.
* The formula below tries to be fair for various screen sizes.
* We only pay attention to the smaller of the 2 edges, since
* that seems to be the bottleneck.
* This formula is a hyperbola which includes the following points:
* (24, $25) (original scoring algorithm)
* (12, $40) (experimentally derived by the "feel")
* (48, $15) (a guess)
* This will give a 4x4 screen $99/shot. We don't allow anything
* smaller than 4x4 because there is a 3x3 game where you can win
* an infinite amount of money.
*/
if (i < 12)
i = 12; /* otherwise it isn't fair */
/*
* Compensate for border. This really changes the game since
* the screen is two squares smaller but we want the default
* to be $25, and the high scores on small screens were a bit
* much anyway.
*/
i += 2;
chunk = (675.0 / (i + 6)) + 2.5; /* min screen edge */

signal(SIGINT, stop);
putpad(TI); /* String to begin programs that use cm */
putpad(KS); /* Put terminal in keypad transmit mode */

snrand(&finish);
snrand(&you);
snrand(&money);
snrand(&snake[0]);

if (ospeed < 9600 || ((!CM) && (!TA)))
fast = 0;
for (i = 1; i < 6; i++)
chase(&snake[i], &snake[i - 1]);
setup();
mainloop();
/* NOTREACHED */
return (0);


/* Main command loop */
void
mainloop()

int j, k;

for (;;)
int c, lastc, match;

lastc = 0;
move(&you);
fflush(stdout);
if (((c = getchar() & 0177) <= '9') && (c >= '0'))
ungetc(c, stdin);
j = scanf("%d", &repeat);
c = getchar() & 0177;
else
if (c != '.')
repeat = 1;

if (c == '.')
c = lastc;

if ((Klength > 0) &&
(c == *KL || c == *KR || c == *KU || c == *KD))
savec = c;
match = 0;
kl = KL;
kr = KR;
ku = KU;
kd = KD;
for (j = Klength; j > 0; j--)
if (match != 1)
match = 0;
if (*kl++ == c)
ch = 'h';
match++;

if (*kr++ == c)
ch = 'l';
match++;

if (*ku++ == c)
ch = 'k';
match++;

if (*kd++ == c)
ch = 'j';
match++;

if (match == 0)
ungetc(c, stdin);
ch = savec;
/* Oops! This works if we
* figure it out on second
* character. */
break;


savec = c;
if (j != 1)
c = getchar() & 0177;

c = ch;

if (!fast)
flushi();
lastc = c;
switch (c)
case CTRL('z'):
suspend();
continue;
case EOT:
case 'x':
case 0177: /* del or end of file */
ll();
length(moves);
logit("quit");
done();
case CTRL('l'):
setup();
winnings(cashvalue);
continue;
case 'p':
case 'd':
snap();
continue;
case 'w':
spacewarp(0);
continue;
case 'A':
repeat = you.col;
c = 'h';
break;
case 'H':
case 'S':
repeat = you.col - money.col;
c = 'h';
break;
case 'T':
repeat = you.line;
c = 'k';
break;
case 'K':
case 'E':
repeat = you.line - money.line;
c = 'k';
break;
case 'P':
repeat = ccnt - 1 - you.col;
c = 'l';
break;
case 'L':
case 'F':
repeat = money.col - you.col;
c = 'l';
break;
case 'B':
repeat = lcnt - 1 - you.line;
c = 'j';
break;
case 'J':
case 'C':
repeat = money.line - you.line;
c = 'j';
break;

for (k = 1; k <= repeat; k++)
moves++;
switch (c)
case 's':
case 'h':
case '\b':
if (you.col > 0)
if ((fast) || (k == 1))
pchar(&you, ' ');
you.col--;
if ((fast) || (k == repeat) ||
(you.col == 0))
pchar(&you, ME);

break;
case 'f':
case 'l':
case ' ':
if (you.col < ccnt - 1)
if ((fast) || (k == 1))
pchar(&you, ' ');
you.col++;
if ((fast) || (k == repeat) ||
(you.col == ccnt - 1))
pchar(&you, ME);

break;
case CTRL('p'):
case 'e':
case 'k':
case 'i':
if (you.line > 0)
if ((fast) || (k == 1))
pchar(&you, ' ');
you.line--;
if ((fast) || (k == repeat) ||
(you.line == 0))
pchar(&you, ME);

break;
case CTRL('n'):
case 'c':
case 'j':
case LF:
case 'm':
if (you.line + 1 < lcnt)
if ((fast) || (k == 1))
pchar(&you, ' ');
you.line++;
if ((fast) || (k == repeat) ||
(you.line == lcnt - 1))
pchar(&you, ME);

break;


if (same(&you, &money))
loot += 25;
if (k < repeat)
pchar(&you, ' ');
do
snrand(&money);
while ((money.col == finish.col &&
money.line == finish.line) ||
(money.col < 5 && money.line == 0) ||
(money.col == you.col &&
money.line == you.line));
pchar(&money, TREASURE);
winnings(cashvalue);
continue;

if (same(&you, &finish))
win(&finish);
ll();
cook();
pr("You have won with $%d.\n", cashvalue);
fflush(stdout);
logit("won");
post(cashvalue, 1);
length(moves);
done();

if (pushsnake())
break;

fflush(stdout);



/*
* setup the board
*/
void
setup()

int i;

clear();
pchar(&you, ME);
pchar(&finish, GOAL);
pchar(&money, TREASURE);
for (i = 1; i < 6; i++)
pchar(&snake[i], SNAKETAIL);

pchar(&snake[0], SNAKEHEAD);
drawbox();
fflush(stdout);


void
drawbox()

int i;
struct point p;

p.line = -1;
for (i = 0; i < ccnt; i++)
p.col = i;
pchar(&p, '-');

p.col = ccnt;
for (i = -1; i <= lcnt; i++)
p.line = i;
pchar(&p, '|');

p.col = -1;
for (i = -1; i <= lcnt; i++)
p.line = i;
pchar(&p, '|');

p.line = lcnt;
for (i = 0; i < ccnt; i++)
p.col = i;
pchar(&p, '-');



void
snrand(sp)
struct point *sp;

struct point p;
int i;

for (;;)
p.col = random() % ccnt;
p.line = random() % lcnt;

/* make sure it's not on top of something else */
if (p.line == 0 && p.col < 5)
continue;
if (same(&p, &you))
continue;
if (same(&p, &money))
continue;
if (same(&p, &finish))
continue;
for (i = 0; i < 5; i++)
if (same(&p, &snake[i]))
break;
if (i < 5)
continue;
break;

*sp = p;


int
post(iscore, flag)
int iscore, flag;

short score = iscore;
int rawscores;
short uid;
short oldbest = 0;
short allbwho = 0, allbscore = 0;
struct passwd *p;

/*
* Neg uid, 0, and 1 cannot have scores recorded.
*/
if ((uid = getuid()) <= 1)
pr("No saved scores for uid %d.\n", uid);
return (1);

if ((rawscores = open(_PATH_RAWSCORES, O_RDWR | O_CREAT, 0644)) < 0)
pr("No score file %s: %s.\n", _PATH_RAWSCORES,
strerror(errno));
return (1);

/* Figure out what happened in the past */
read(rawscores, &allbscore, sizeof(short));
read(rawscores, &allbwho, sizeof(short));
lseek(rawscores, uid * sizeof(short), 0);
read(rawscores, &oldbest, sizeof(short));
if (!flag)
return (score > oldbest ? 1 : 0);

/* Update this jokers best */
if (score > oldbest)
lseek(rawscores, uid * sizeof(short), 0);
write(rawscores, &score, sizeof(short));
pr("You bettered your previous best of $%d\n", oldbest);
else
pr("Your best to date is $%d\n", oldbest);

/* See if we have a new champ */
p = getpwuid(allbwho);
if (p == NULL || score > allbscore)
lseek(rawscores, 0, 0);
write(rawscores, &score, sizeof(short));
write(rawscores, &uid, sizeof(short));
if (allbwho)
pr("You beat %s's old record of $%d!\n",
p->pw_name, allbscore);
else
pr("You set a new record!\n");
else
pr("The highest is %s with $%d\n", p->pw_name, allbscore);
close(rawscores);
return (1);


/*
* Flush typeahead to keep from buffering a bunch of chars and then
* overshooting. This loses horribly at 9600 baud, but works nicely
* if the terminal gets behind.
*/
void
flushi()

tcflush(0, TCIFLUSH);


int mx[8] =
0, 1, 1, 1, 0, -1, -1, -1
;
int my[8] =
-1, -1, 0, 1, 1, 1, 0, -1
;
float absv[8] =
1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
;
int oldw = 0;

void
chase(np, sp)
struct point *sp, *np;

/* this algorithm has bugs; otherwise the snake would get too good */
struct point d;
int w, i, wt[8];
double v1, v2, vp, max;
point(&d, you.col - sp->col, you.line - sp->line);
v1 = sqrt((double) (d.col * d.col + d.line * d.line));
w = 0;
max = 0;
for (i = 0; i < 8; i++)
vp = d.col * mx[i] + d.line * my[i];
v2 = absv[i];
if (v1 > 0)
vp = ((double) vp) / (v1 * v2);
else
vp = 1.0;
if (vp > max)
max = vp;
w = i;


for (i = 0; i < 8; i++)
point(&d, sp->col + mx[i], sp->line + my[i]);
wt[i] = 0;
if (d.col < 0 || d.col >= ccnt || d.line < 0 || d.line >= lcnt)
continue;
/*
* Change to allow snake to eat you if you're on the money,
* otherwise, you can just crouch there until the snake goes
* away. Not positive it's right.
*
* if (d.line == 0 && d.col < 5) continue;
*/
if (same(&d, &money))
continue;
if (same(&d, &finish))
continue;
wt[i] = i == w ? loot / 10 : 1;
if (i == oldw)
wt[i] += loot / 20;

for (w = i = 0; i < 8; i++)
w += wt[i];
vp = ((rand() >> 6) & 01777) % w;
for (i = 0; i < 8; i++)
if (vp < wt[i])
break;
else
vp -= wt[i];
if (i == 8)
pr("failure\n");
i = 0;
while (wt[i] == 0)
i++;

oldw = w = i;
point(np, sp->col + mx[w], sp->line + my[w]);


void
spacewarp(w)
int w;

struct point p;
int j;
char *str;

snrand(&you);
point(&p, COLUMNS / 2 - 8, LINES / 2 - 1);
if (p.col < 0)
p.col = 0;
if (p.line < 0)
p.line = 0;
if (w)
str = "BONUS!!!";
loot = loot - penalty;
penalty = 0;
else
str = "SPACE WARP!!!";
penalty += loot / PENALTY;

for (j = 0; j < 3; j++)
clear();
delay(5);
apr(&p, str);
delay(10);

setup();
winnings(cashvalue);


void
snap()

struct point p;

if (you.line < 3)
pchar(point(&p, you.col, 0), '-');

if (you.line > lcnt - 4)
pchar(point(&p, you.col, lcnt - 1), '_');

if (you.col < 10)
pchar(point(&p, 0, you.line), '(');

if (you.col > ccnt - 10)
pchar(point(&p, ccnt - 1, you.line), ')');

if (!stretch(&money))
if (!stretch(&finish))
delay(10);
if (you.line < 3)
point(&p, you.col, 0);
chk(&p);

if (you.line > lcnt - 4)
point(&p, you.col, lcnt - 1);
chk(&p);

if (you.col < 10)
point(&p, 0, you.line);
chk(&p);

if (you.col > ccnt - 10)
point(&p, ccnt - 1, you.line);
chk(&p);

fflush(stdout);


int
stretch(ps)
struct point *ps;

struct point p;

point(&p, you.col, you.line);
if (abs(ps->col - you.col) < 6)
if (you.line < ps->line)
for (p.line = you.line + 1; p.line <= ps->line;
p.line++)
pchar(&p, 'v');
delay(10);
for (; p.line > you.line; p.line--)
chk(&p);
else
for (p.line = you.line - 1; p.line >= ps->line;
p.line--)
pchar(&p, '^');
delay(10);
for (; p.line < you.line; p.line++)
chk(&p);

return (1);
else
if (abs(ps->line - you.line) < 3)
p.line = you.line;
if (you.col < ps->col)
for (p.col = you.col + 1; p.col <= ps->col;
p.col++)
pchar(&p, '>');
delay(10);
for (; p.col > you.col; p.col--)
chk(&p);
else
for (p.col = you.col - 1; p.col >= ps->col;
p.col--)
pchar(&p, '<');
delay(10);
for (; p.col < you.col; p.col++)
chk(&p);

return (1);

return (0);


void
surround(ps)
struct point *ps;

struct point x;
int j;

if (ps->col == 0)
ps->col++;
if (ps->line == 0)
ps->line++;
if (ps->line == LINES - 1)
ps->line--;
if (ps->col == COLUMNS - 1)
ps->col--;
apr(point(&x, ps->col - 1, ps->line - 1), "/*\\\r* *\r\\*/");
for (j = 0; j < 20; j++)
pchar(ps, '@');
delay(1);
pchar(ps, ' ');
delay(1);

if (post(cashvalue, 0))
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/");
delay(6);
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.-\r\\_/");
delay(6);

apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/");


void
win(ps)
struct point *ps;

struct point x;
int j, k;
int boxsize; /* actually diameter of box, not radius */

boxsize = fast ? 10 : 4;
point(&x, ps->col, ps->line);
for (j = 1; j < boxsize; j++)
for (k = 0; k < j; k++)
pchar(&x, '#');
x.line--;

for (k = 0; k < j; k++)
pchar(&x, '#');
x.col++;

j++;
for (k = 0; k < j; k++)
pchar(&x, '#');
x.line++;

for (k = 0; k < j; k++)
pchar(&x, '#');
x.col--;


fflush(stdout);


int
pushsnake()

int i, bonus;
int issame = 0;

/*
* My manual says times doesn't return a value. Furthermore, the
* snake should get his turn every time no matter if the user is
* on a fast terminal with typematic keys or not.
* So I have taken the call to times out.
*/
for (i = 4; i >= 0; i--)
if (same(&snake[i], &snake[5]))
issame++;
if (!issame)
pchar(&snake[5], ' ');
for (i = 4; i >= 0; i--)
snake[i + 1] = snake[i];
chase(&snake[0], &snake[1]);
pchar(&snake[1], SNAKETAIL);
pchar(&snake[0], SNAKEHEAD);
for (i = 0; i < 6; i++)
if (same(&snake[i], &you))
surround(&you);
i = (cashvalue) % 10;
bonus = ((rand() >> 8) & 0377) % 10;
ll();
pr("%d\n", bonus);
delay(30);
if (bonus == i)
spacewarp(1);
logit("bonus");
flushi();
return (1);

if (loot >= penalty)
pr("You and your $%d have been eaten\n",
cashvalue);
else
pr("The snake ate you. You owe $%d.\n",
-cashvalue);

logit("eaten");
length(moves);
done();


return (0);


int
chk(sp)
struct point *sp;

int j;

if (same(sp, &money))
pchar(sp, TREASURE);
return (2);

if (same(sp, &finish))
pchar(sp, GOAL);
return (3);

if (same(sp, &snake[0]))
pchar(sp, SNAKEHEAD);
return (4);

for (j = 1; j < 6; j++)
if (same(sp, &snake[j]))
pchar(sp, SNAKETAIL);
return (4);


if ((sp->col < 4) && (sp->line == 0))
winnings(cashvalue);
if ((you.line == 0) && (you.col < 4))
pchar(&you, ME);
return (5);

if (same(sp, &you))
pchar(sp, ME);
return (1);

pchar(sp, ' ');
return (0);


void
winnings(won)
int won;

struct point p;

p.line = p.col = 1;
if (won > 0)
move(&p);
pr("$%d", won);



void
stop(dummy)
int dummy;

signal(SIGINT, SIG_IGN);
ll();
length(moves);
done();


void
suspend()

ll();
cook();
kill(getpid(), SIGTSTP);
raw();
setup();
winnings(cashvalue);


void
length(num)
int num;

pr("You made %d moves.\n", num);


void
logit(msg)
const char *msg;

FILE *logfile;
time_t t;

if ((logfile = fopen(_PATH_LOGFILE, "a")) != NULL)
time(&t);
fprintf(logfile, "%s $%d %dx%d %s %s",
getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
fclose(logfile);

参考资料:netbsd/src/bin/echo

参考技术A #define N 200
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score=0;/*得分*/
int gamespeed=50000;/*游戏速度自己调整*/
struct Food

int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
food;/*食物的结构体*/
struct Snake

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);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
/*主函数*/
void main(void)

Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/

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

int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\\tc");
cleardevice();

/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void DrawK(void)

/*setbkcolor(LIGHTGREEN);*/
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(void)

randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇头*/
snake.x[1]=110;snake.y[1]=100;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/

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

if(food.yes==1)/*需要出现新食物*/

food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*画面上有食物了*/

if(food.yes==0)/*画面上有食物了就要显示*/

setcolor(GREEN);
rectangle(food.x,food.y,food.x+10,food.y-10);

for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/

snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];

/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction)

case 1:snake.x[0]+=10;break;
case 2: snake.x[0]-=10;break;
case 3: snake.y[0]-=10;break;
case 4: snake.y[0]+=10;break;

for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/

if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])

GameOver();/*显示失败*/
snake.life=1;
break;


if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到墙壁*/

GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/

if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/

setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node]=-20;snake.y[snake.node]=-20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
PrScore();/*输出新得分*/

setcolor(4);/*画出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);
/*endwhile(!kbhit)*/
if(snake.life==1)/*如果蛇死就跳出循环*/
break;
key=bioskey(0);/*接收按键*/
if(key==ESC)/*按ESC键退出*/
break;
else
if(key==UP&&snake.direction!=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
/*endwhile(1)*/

/*游戏结束*/
void GameOver(void)

cleardevice();
PrScore();
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,"score:%d",score);
outtextxy(55,20,str);

/*图形结束*/
void Close(void)

getch();
closegraph();

Linux下贪吃蛇的c语言实现

#include<curses.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
#define UP 1
#define DOWN -1
#define LEFT  2
#define RIGHT -2

struct Snake
	int hang;
	int lie;
	struct Snake*next;
;//声明贪吃蛇结点的结构体

struct Snake*head=NULL;
struct Snake*tail=NULL;

int key;
int dir;
struct Snake Food;

void initFood()

	int x=rand()%20;
	int y=rand()%20;

	Food.hang=x;
	Food.lie=y;
//初始化食物(在20x20的范围内随机生成食物)
void initNcurse()

	initscr();
	keypad(stdscr,1);//开启小键盘方向键输入捕捉支持
//初始化Ncurses(选择要使用的功能函数)

void addNode()

	struct Snake*new=(struct Snake*)malloc(sizeof(struct Snake));
	new->next=NULL;
	switch(dir)

		case UP:
			new->hang=tail->hang-1;
			new->lie=tail->lie;
			break;
		case DOWN:
			new->hang=tail->hang+1;
			new->lie=tail->lie;
			break;
		case LEFT:
			new->hang=tail->hang;
			new->lie=tail->lie-1;
			break;
		case RIGHT:
			new->hang=tail->hang;
			new->lie=tail->lie+1;
			break;
	
	tail->next=new;
	tail=new;
//增加贪吃蛇身体结点

void deleNode()

	head=head->next;
//删除贪吃蛇身体的头结点

void initSnake()
   struct Snake* p;
	dir=RIGHT;  //默认行走方向
	
	if(head!=NULL)
		p=head;
		head=head->next;
		free(p);
	
	initFood();
	head=(struct Snake*)malloc(sizeof(struct Snake));
	head->hang=2;
	head->lie=2;
	head->next=NULL;
	tail=head;
	addNode();
	addNode();
	addNode();


int hasSnakeNode(int hang,int lie)
       struct Snake*p;
	p=head;
	while(p!=NULL)       
		if(p->hang==hang && p->lie==lie)
			return 1;
		
		p=p->next;
	

	return 0;        
   //判断地图上当前坐标位置是否存在贪吃蛇身体结点

int hasFood(int hang,int lie)
 
	if(Food.hang==hang && Food.lie==lie)

		return 1;
	

	return 0;
 //判断地图上当前坐标位置是否存在食物
void initMap()
	int hang;
	int lie;
	move(0,0);


	for(hang=0;hang<20;hang++)

		if(hang==0)

			for(lie=-1;lie<20;lie++)

				printw("--");   
			
			printw("\\n");
		
		if(hang>=0 || hang<=19)

			for(lie=-1;lie<=20;lie++)

				if(lie==-1||lie==20)

					printw("|");
				

				else if( hasSnakeNode(hang,lie))

					printw("[]");
				
				else if( hasFood(hang,lie))
					printw("##");
				
				else

					printw("  ");
				

			 
			printw("\\n");            
		

		if(hang==19)
			for(lie=-1;lie<20;lie++)

				printw("--");

			 
			printw("\\n");
			printw("by chenhongming\\n");
			printw("food(%d,%d),",Food.hang,Food.lie);
			printw("snake head(%d,%d)\\n",tail->hang,tail->lie);
		  

	 
//绘制地图


int issnakedie()

	struct Snake* p;
	p=head;

	if(tail->hang<0 || tail->lie==-1 || tail->hang==20 || tail->lie==20)

		return 1;
	
	while(p->next!=NULL)
		if(p->hang==tail->hang && p->lie==tail->lie)

			return 1;
		
		p=p->next;
	
	return 0;
//判断??是否死亡 


void moveSnake()

	addNode();
	if(hasFood(tail->hang,tail->lie))
		initFood();
	

	else
		deleNode();
	  

	if(issnakedie())

		initSnake();
		

	       
//移动??身(在尾部添加结点 删除头结点 有食物则不删)
void*  refreshjiemian()
      
	while(1) 
		moveSnake();
		initMap();
		refresh();

		usleep(100000);


	 
//刷新界面(不断的移动??和刷新地图 )
void turn(int direction)

	if(abs(dir) !=abs(direction))
		dir=direction;
	
//转向


void* changeDir()


	int key;
	while(1)
		key=getch();
		switch(key)
			case KEY_DOWN:
				turn(DOWN);
				break;   
			case KEY_UP:
				turn(UP);
				break;
			case KEY_RIGHT:
				turn(RIGHT);
				break;
			case KEY_LEFT:
				turn(LEFT);        
				break; 
		
	
//不断从键盘获取方向键的命令
int main()




	//char 1byte 8bit 128
        initNcurse();
        initSnake();
        initMap();

        pthread_t t1;
        pthread_t t2;
        pthread_create(&t1,NULL,refreshjiemian,NULL);
        pthread_create(&t2,NULL,changeDir,NULL);
		//利用线程同时执行 刷新界面和获得方向的函数
        while(1);

	//    getch();
	endwin();
	return 0;

运行gcc snake.c -lpthread -lcurses
然后上下左右方向键

以上是关于用C语言编写 贪吃蛇的思路啥怎么样的的主要内容,如果未能解决你的问题,请参考以下文章

C语言课程设计,贪吃蛇应该怎么做?

用C语言编写贪吃蛇小游戏

C语言实现《贪吃蛇》小游戏,代码分享+思路注释

C语言零基础项目:贪吃蛇!详细思路+源码分享

C语言项目:贪吃蛇游戏(双人模式),详细思路+源码分享

C - 简易贪吃蛇的编写