* 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.
* cc -O snake.c move.c -o snake -lm -ltermlib
* If CHECKBUSY is defined, the file BUSY must be executable
* and must return a value which is used to determine the priority
* a which snake runs. A zero value means no nice.
* If BUSY does not exist, snake won't play.
#define BUSY "/usr/games/lib/busy"
* This is the data file for scorekeeping.
#define SNAKERAWSCORES "/usr/games/lib/snakerawscores"
* If it exists, a log is kept here. Otherwise it isn't.
#define LOGFILE "/usr/games/lib/snake.log"
#define PENALTY 10 /* % penalty for invoking spacewarp */
ccnt
-= 2; lcnt
-= 2; /* compensate for border */
sscanf(argv
[1], "-d%ld", &tv
);
printf("bad option %s\n", argv
[1]);
i
= ((lcnt
< ccnt
) ? lcnt
: ccnt
); /* min screen edge */
printf("Screen too small for a fair game\n");
* 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")
* 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
chunk
= (675.0 / (i
+6)) + 2.5; /* min screen edge */
putpad(TI
); /* String to begin programs that use cm */
putpad(KS
); /* Put terminal in keypad transmit mode */
if ((orig
.sg_ospeed
< B9600
) ||
((! CM
) && (! TA
))) fast
=0;
chase (&snake
[i
], &snake
[i
-1]);
if (((c
= getchar() & 0177) <= '9') && (c
>= '0')) {
if (c
!= '.') repeat
= 1;
(c
== *KL
|| c
== *KR
|| c
== *KU
|| c
== *KD
)) {
* This works if we figure it out on second character.
if(j
!= 1) c
= getchar() & 0177;
case 0177: /* del or end of file */
repeat
= you
.col
- money
.col
;
repeat
= you
.line
- money
.line
;
repeat
= ccnt
- 1 - you
.col
;
repeat
= money
.col
- you
.col
;
repeat
= lcnt
- 1 - you
.line
;
repeat
= money
.line
- you
.line
;
if((fast
) || (k
== repeat
) ||
if((fast
) || (k
== repeat
) ||
if((fast
) || (k
== repeat
) ||
if((fast
) || (k
== repeat
) ||
} while (money
.col
== finish
.col
&& money
.line
== finish
.line
||
money
.col
< 5 && money
.line
== 0 ||
money
.col
== you
.col
&& money
.line
== you
.line
);
printf("You have won with $%d.\n",cashvalue
);
pchar(&snake
[i
],SNAKETAIL
);
pchar(&snake
[0], SNAKEHEAD
);
for (i
= 0; i
<ccnt
; i
++) {
for (i
= -1; i
<=lcnt
; i
++) {
for (i
= -1; i
<=lcnt
; i
++) {
for (i
= 0; i
<ccnt
; i
++) {
sp
->col
= sp
->line
= -1; /* impossible */
p
.col
= ((rand()>>8) & 0377)% ccnt
;
p
.line
= ((rand()>>8) & 0377)% lcnt
;
/* make sure it's not on top of something else */
if (p
.line
== 0 && p
.col
<5) issame
++;
if(same(&p
, &you
)) issame
++;
if(same(&p
, &money
)) issame
++;
if(same(&p
, &finish
)) issame
++;
if(same(&p
, &snake
[i
])) issame
++;
if (! strcmp (argval
[0], "test")) return;
if ((access(BUSY
,1) != 0) || (pip
= popen(BUSY
,"r")) == NULL
){
printf("Sorry, no snake just now.\n");
printf("Sorry, the system is too heavily loaded right now.\n");
short allbwho
=0, allbscore
=0;
struct passwd
*p
, *getpwuid();
* Neg uid, 0, and 1 cannot have scores recorded.
if ((uid
=getuid()) > 1 && (rawscores
=open(SNAKERAWSCORES
,2))>=0) {
/* Figure out what happened in the past */
read(rawscores
, &allbscore
, sizeof(short));
read(rawscores
, &allbwho
, sizeof(short));
lseek(rawscores
, ((long)uid
)*sizeof(short), 0);
read(rawscores
, &oldbest
, sizeof(short));
if (flag
) return (score
> oldbest
? 1 : 0);
/* Update this jokers best */
lseek(rawscores
, ((long)uid
)*sizeof(short), 0);
write(rawscores
, &score
, sizeof(short));
printf("You bettered your previous best of $%d\n", oldbest
);
printf("Your best to date is $%d\n", oldbest
);
/* See if we have a new champ */
if (p
== NULL
|| score
> allbscore
) {
lseek(rawscores
, (long)0, 0);
write(rawscores
, &score
, sizeof(short));
write(rawscores
, &uid
, sizeof(short));
printf("You beat %s's old record of $%d!\n", p
->pw_name
, allbscore
);
printf("You set a new record!\n");
printf("The highest is %s with $%d\n", p
->pw_name
, allbscore
);
printf("Unable to post score.\n");
* 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.
-1,-1, 0, 1, 1, 1, 0,-1};
1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
/* this algorithm has bugs; otherwise the
snake would get too good */
double sqrt(), 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
) );
vp
= d
.col
*mx
[i
] + d
.line
*my
[i
];
vp
= ((double)vp
)/(v1
*v2
);
point(&d
,sp
->col
+mx
[i
],sp
->line
+my
[i
]);
if (d
.col
<0 || d
.col
>=ccnt
|| d
.line
<0 || d
.line
>=lcnt
)
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;
vp
= (( rand() >> 6 ) & 01777) %w
;
point(np
,sp
->col
+mx
[w
],sp
->line
+my
[w
]);
point(&p
,COLUMNS
/2 - 8,LINES
/2 - 1);
sprintf(str
,"SPACE WARP!!!");
pchar(point(&p
,you
.col
,0),'-');
pchar(point(&p
,you
.col
,lcnt
-1),'_');
pchar(point(&p
,0,you
.line
),'(');
pchar(point(&p
,ccnt
-1,you
.line
),')');
if (! stretch(&money
)) if (! stretch(&finish
)) delay(10);
point(&p
,you
.col
,lcnt
-1);
point(&p
,ccnt
-1,you
.line
);
point(&p
,you
.col
,you
.line
);
if(abs(ps
->col
-you
.col
) < 6){
for (p
.line
= you
.line
+1;p
.line
<= ps
->line
;p
.line
++)
for (;p
.line
> you
.line
;p
.line
--)
for (p
.line
= you
.line
-1;p
.line
>= ps
->line
;p
.line
--)
for (;p
.line
< you
.line
;p
.line
++)
} else if(abs(ps
->line
-you
.line
) < 3){
for (p
.col
= you
.col
+1;p
.col
<= ps
->col
;p
.col
++)
for (;p
.col
> you
.col
;p
.col
--)
for (p
.col
= you
.col
-1;p
.col
>= ps
->col
;p
.col
--)
for (;p
.col
< you
.col
;p
.col
++)
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
--;
aprintf(point(&x
,ps
->col
-1,ps
->line
-1),"/*\\\r* *\r\\*/");
aprintf(point(&x
,ps
->col
-1,ps
->line
-1)," \ro.o\r\\_/");
aprintf(point(&x
,ps
->col
-1,ps
->line
-1)," \ro.-\r\\_/");
aprintf(point(&x
,ps
->col
-1,ps
->line
-1)," \ro.o\r\\_/");
int boxsize
; /* actually diameter of box, not radius */
point(&x
,ps
->col
,ps
->line
);
* 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.
if (same(&snake
[i
], &snake
[5]))
chase(&snake
[0], &snake
[1]);
pchar(&snake
[1],SNAKETAIL
);
pchar(&snake
[0],SNAKEHEAD
);
if (same(&snake
[i
],&you
))
bonus
= ((rand()>>8) & 0377)% 10;
printf("You and your $%d have been eaten\n",cashvalue
);
printf("The snake ate you. You owe $%d.\n",-cashvalue
);
if (same(sp
,&snake
[0])) {
if ((sp
->col
< 4) && (sp
->line
== 0)){
if((you
.line
== 0) && (you
.col
< 4)) pchar(&you
,ME
);
printf("You made %d moves.\n",num
);
if ((logfile
=fopen(LOGFILE
, "a")) != NULL
) {
fprintf(logfile
, "%s $%d %dx%d %s %s", getlogin(), cashvalue
, lcnt
, ccnt
, msg
, ctime(&t
));