Nasal-Interpreter/test/snake.nas

171 lines
4.6 KiB
Plaintext

use module.libkey;
use std.list;
use std.runtime;
use std.coroutine;
use std.unix;
var game = func(x,y) {
rand(time(0));
var texture=[" ","██","\e[91m██\e[0m"];
var edge0="╔";
var edge1="╚";
for(var i=0;i<x;i+=1) {
edge0~="══";
edge1~="══";
}
edge0~="╗\n";
edge1~="╝\n";
var vec=[];
setsize(vec,x);
for(var i=0;i<x;i+=1) {
vec[i]=[];
setsize(vec[i],y);
for(var j=0;j<y;j+=1)
vec[i][j]=0;
}
var snake = list.new();
snake.push_back([int(x/2),int(y/3)]);
snake.push_back([int(x/2),int(y/3)+1]);
vec[int(x/2)][int(y/3)]=1;
vec[int(x/2)][int(y/3)+1]=1;
var move='w';
var gameover=0;
var setapple = func() {
var (cord_x,cord_y)=(int(rand()*x),int(rand()*y));
while(vec[cord_x][cord_y]!=0)
(cord_x,cord_y)=(int(rand()*x),int(rand()*y));
vec[cord_x][cord_y]=2;
}
setapple();
return {
print:func() {
var s="";
var (fx,fy)=snake.front();
for(var i=0;i<y;i+=1) {
s~="║";
for(var j=0;j<x;j+=1) {
if (fx==j and fy==i)
s~="\e[93m"~texture[vec[j][i]]~"\e[0m";
else
s~=texture[vec[j][i]];
}
s~='║\n';
}
print('\e[1;1H'~edge0~s~edge1);
},
next:func() {
var (fx,fy)=snake.front();
var eat=0;
if (move=="w" and fy-1>=0) {
snake.push_front([fx,fy-1]);
if (vec[fx][fy-1]==1)
gameover=1;
elsif (vec[fx][fy-1]==2)
eat=1;
vec[fx][fy-1]=1;
} elsif (move=='a' and fx-1>=0) {
snake.push_front([fx-1,fy]);
if (vec[fx-1][fy]==1)
gameover=1;
elsif (vec[fx-1][fy]==2)
eat=1;
vec[fx-1][fy]=1;
} elsif (move=='s' and fy+1<y) {
snake.push_front([fx,fy+1]);
if (vec[fx][fy+1]==1)
gameover=1;
elsif (vec[fx][fy+1]==2)
eat=1;
vec[fx][fy+1]=1;
} elsif (move=='d' and fx+1<x) {
snake.push_front([fx+1,fy]);
if (vec[fx+1][fy]==1)
gameover=1;
elsif (vec[fx+1][fy]==2)
eat=1;
vec[fx+1][fy]=1;
} else {
gameover=1;
}
if (!gameover and !eat) {
var (bx,by)=snake.back();
vec[bx][by]=0;
snake.pop_back();
}
if (eat and snake.length()!=x*y)
setapple();
elsif (snake.length()==x*y)
gameover=2;
},
move:func(c) {
move=c;
},
gameover:func() {
return gameover;
}
}
}
var co=coroutine.create(func() {
while(1) {
var moved=-1;
for(var i=0;i<30;i+=1) {
var ch=libkey.nonblock();
if (moved==-1 and ch!=nil) {
moved=ch;
}
coroutine.yield(nil);
unix.sleep(0.01);
}
coroutine.yield(moved);
}
});
var main = func(argv) {
var should_skip=(size(argv)!=0 and argv[0]=="--skip");
# enable unicode
runtime.windows.set_utf8_output();
print("\ec");
var g=game(15,10);
g.print();
print("\rpress any key to start...");
if (!should_skip) {
libkey.getch();
}
print("\r \r");
var counter=20;
while(1) {
while((var ch=coroutine.resume(co)[0])==nil);
if (ch!=nil and ch!=-1) {
if (ch=='q'[0]) {
break;
} elsif (ch=='p'[0]) {
print("\rpress any key to continue...");
libkey.getch();
print("\r \r");
} elsif (ch=='w'[0] or ch=='s'[0] or ch=='a'[0] or ch=='d'[0]) {
g.move(chr(ch));
}
}
g.next();
if (g.gameover())
break;
g.print();
}
println(g.gameover()<=1?"game over.":"you win!");
println("press 'q' to quit.");
if (should_skip) {
return;
}
while(libkey.getch()!='q'[0]);
}
main(runtime.argv());