/* $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 SERVICESLOSS OF USE, DATA, OR PROFITSOR 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
charstri[BSIZE]
char *p
charch, 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 = 1i <6i++)
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 = Klengthj >0j--) {
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 = 1k <= repeatk++) {
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 = 1i <6i++) {
pchar(&snake[i], SNAKETAIL)
}
pchar(&snake[0], SNAKEHEAD)
drawbox()
fflush(stdout)
}
void
drawbox()
{
int i
struct point p
p.line = -1
for (i = 0i <ccnti++) {
p.col = i
pchar(&p, '-')
}
p.col = ccnt
for (i = -1i <= lcnti++) {
p.line = i
pchar(&p, '|')
}
p.col = -1
for (i = -1i <= lcnti++) {
p.line = i
pchar(&p, '|')
}
p.line = lcnt
for (i = 0i <ccnti++) {
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 = 0i <5i++)
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 bugsotherwise 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 = 0i <8i++) {
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 = 0i <8i++) {
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 = 0i <8i++)
w += wt[i]
vp = ((rand() >>6) &01777) % w
for (i = 0i <8i++)
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 = 0j <3j++) {
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 + 1p.line <= ps->line
p.line++)
pchar(&p, 'v')
delay(10)
for (p.line >you.linep.line--)
chk(&p)
} else {
for (p.line = you.line - 1p.line >= ps->line
p.line--)
pchar(&p, '^')
delay(10)
for (p.line <you.linep.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 + 1p.col <= ps->col
p.col++)
pchar(&p, '>')
delay(10)
for (p.col >you.colp.col--)
chk(&p)
} else {
for (p.col = you.col - 1p.col >= ps->col
p.col--)
pchar(&p, '<')
delay(10)
for (p.col <you.colp.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 = 0j <20j++) {
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 = 1j <boxsizej++) {
for (k = 0k <jk++) {
pchar(&x, '#')
x.line--
}
for (k = 0k <jk++) {
pchar(&x, '#')
x.col++
}
j++
for (k = 0k <jk++) {
pchar(&x, '#')
x.line++
}
for (k = 0k <jk++) {
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 = 4i >= 0i--)
if (same(&snake[i], &snake[5]))
issame++
if (!issame)
pchar(&snake[5], ' ')
for (i = 4i >= 0i--)
snake[i + 1] = snake[i]
chase(&snake[0], &snake[1])
pchar(&snake[1], SNAKETAIL)
pchar(&snake[0], SNAKEHEAD)
for (i = 0i <6i++) {
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 = 1j <6j++) {
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)
}
}
#include <stdio.h>#include <graphics.h>
#include <stdlib.h>
#include <dos.h>/*引用的库函数*/
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b/*宏定义键名*/
#define N 200
int i,key
int level/*游戏等级*/
int score=0/*得分*/
int gamespeed/*游戏速度*/
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 Choicelevle(void)/*选择游戏等级*/
void Init(void)/*图形驱动*/
void Close(void)/*图形结束*/
void DRAW(void)/*游戏区域*/
void GameOver(void)/*结束游戏*/
void GamePlay(void)/*玩游戏具体过程*/
void PrScore(void)/*输出成绩*/
/*主函数*/
void main(void)
{
Init()/*图形驱动*/
Choicelevle()/*选择游戏等级*/
DRAW()/*游戏区域*/
GamePlay()/*玩游戏具体过程*/
Close()/*图形结束*/
}
/*图形驱动*/
void Init(void)
{
int gd=DETECT,gm
initgraph(&gd,&gm,"\\turboc2")/*初始化图形系统*/
cleardevice()/*清除图形界面*/
}
/*选择游戏等级*/
void Choicelevle(void)
{char name[20]
setcolor(YELLOW)
settextstyle(0,0,6)
outtextxy(150,150,"Snake")
setcolor(GREEN)
settextstyle(0,0,1)
outtextxy(200,250,"please put in your English name:")
outtextxy(200,270,"Choice levle from 1-9.")
outtextxy(300,320,"name:yangzilong")/*制作人姓名*/
outtextxy(300,350,"number:0902060226")/*制作人学号*/
outtextxy(300,380,"class:computer science 0602")/*制作人班级*/
getch()
printf("please putin your name:")
gets(name)
printf("please choice levle:")
scanf("%d",&level)
gamespeed=100000-400*level-300*level*level
if(level>9||level<1)
{cleardevice()/*清除图形界面*/
setcolor(YELLOW)/*设置字体颜色*/
settextstyle(0,0,2)/*设置字体类型*/
outtextxy(150,200,"level input error")/*显示文本*/
getch()
level=1
}
}
void DRAW(void)
{cleardevice()/*清屏*/
setcolor(2)
setlinestyle(SOLID_LINE,0,THICK_WIDTH)/*设置线型*/
rectangle(45,45,465,325)
}
/*玩游戏具体过程*/
void GamePlay(void)
{setcolor(5)
setlinestyle(SOLID_LINE,0,THICK_WIDTH)/*设置线型*/
randomize()/*随机数发生器*/
food.yes=1/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0/*活着*/
snake.direction=1/*方向往右*/
snake.x[0]=320snake.y[0]=240/*蛇头*/
snake.x[1]=330snake.y[1]=240/*蛇的第二节位置*/
snake.node=3/*节数*/
PrScore()/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%360+70
food.y=rand()%250+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-1i>0i--)/*蛇的每个环节往前移动*/
{
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]+=10break
case 2: snake.x[0]-=10break
case 3: snake.y[0]-=10break
case 4: snake.y[0]+=10break
}
for(i=3i<snake.nodei++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
GameOver()/*显示失败*/
snake.life=1/*蛇死*/
break
}
}
/*如果蛇头碰到墙壁,蛇头从对面墙出来*/
if(snake.x[0]<50)
{snake.x[0]=450/*如果蛇头越过左边界,则从右边界进入*/
snake.y[0]=snake.y[0]/*纵坐标不变*/
for(i=snake.node-1i>0i--)
{snake.x[i]=snake.x[i-1]
snake.y[i]=snake.y[i-1]/*蛇的其他节数向前推进*/
}
{
setfillstyle(SOLID_FILL,0)/*设置填充模式和颜色,0表示黑色*/
bar(50,55,455,315)/*bar是表示填充的范围的函数*/
}
}
else
if(snake.x[0]>450)
{snake.x[0]=50/*如果蛇头越过右边界,则蛇头从左边界进入*/
snake.y[0]=snake.y[0]/*纵坐标不变*/
for(i=snake.node-1i>0i--)
{snake.x[i]=snake.x[i-1]
snake.y[i]=snake.y[i-1]/*蛇的其他节数向前推进*/
}
{
setfillstyle(SOLID_FILL,0)/*设置填充模式和颜色,0表示黑色*/
bar(50,55,455,315)/*bar是表示填充的范围的函数*/
}
}
else
if(snake.y[0]<60)
{snake.y[0]=320/*如果蛇头越过上边界,则从下边界进入*/
snake.x[0]=snake.x[0]/*横坐标不变*/
for(i=snake.node-1i>0i--)
{snake.x[i]=snake.x[i-1]
snake.y[i]=snake.y[i-1]/*蛇的其他节数向前推进*/
}
{
setfillstyle(SOLID_FILL,0)/*设置填充模式和颜色,0表示黑色*/
bar(50,55,455,315)/*bar是表示填充的范围的函数*/
}
}
else
if(snake.y[0]>320)
{snake.y[0]=60/*如果蛇头越过下边界,则从上边界进入*/
snake.x[0]=snake.x[0]/*横坐标不变*/
for(i=snake.node-1i>0i--)
{snake.x[i]=snake.x[i-1]
snake.y[i]=snake.y[i-1]/*蛇的其他节数向前推进*/
}
{
setfillstyle(SOLID_FILL,0)/*设置填充模式和颜色,0表示黑色*/
bar(50,55,455,315)/*bar是表示填充的范围的函数*/
}
}
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]=-20snake.y[snake.node]=-20
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++/*蛇的身体长一节*/
food.yes=1/*画面上需要出现新的食物*/
score+=10/*每吃掉一食物,得分累加10分*/
if(score%100==0)
{level++gamespeed=100000-400*level-300*level*level/*每吃掉10食物提升一级,速度加快*/
PrScore()/*输出新得分*/
setcolor(YELLOW)/*设置字体颜色*/
settextstyle(0,0,4)/*设置字体类型*/
outtextxy(150,200,"LEVEL UP")/*显示文本*/
if(level==10)
{level=1,gamespeed=100000-400*level-300*level*level}
delay(6000000)
delay(6000000)
delay(6000000)
delay(6000000)
delay(6000000)
delay(6000000)
delay(6000000)
bar(50,55,455,315)/*bar是表示填充的范围的函数*/
}
PrScore()/*输出新得分*/
}
setcolor(4)/*画出蛇*/
for(i=0i<snake.nodei++)
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 str1[20]/*设置字符型数组*/
setfillstyle(SOLID_FILL,0)
bar(50,15,390,35)/*填充矩形框*/
setcolor(6)/*设置文本颜色*/
settextstyle(0,0,2)/*设置数组显示位置*/
sprintf(str1,"score %d level %d",score,level)/*显示数组内容*/
outtextxy(55,20,str1)
setcolor(YELLOW)/*设置字体颜色*/
settextstyle(0,0,2)/*设置字体类型*/
outtextxy(250,400,"EXIT=ESC ")/*显示文本*/
}
void Close(void)
{
closegraph()
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)