#include <stdio.h>
#include <curses.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define UP 1
#define DOWN -1
#define LEFT 2
#define RIGHT -2
#define BOUND 20
typedef struct snakebody
{
int x;
int y;
struct snakebody * next;
}node;
int pass_1=1,pass_2=0,pass_3=0;
time_t t_start,t_end;
int dir,score=0;
node *head,*tail;
node *food;
char *name;
void initial()
{
initscr();
noecho();
keypad(stdscr,TRUE);
timeout(1);
}
int hasSnakeBody(int x,int y)
{
node* tmp=head;
while(tmp!=NULL)
{
if(tmp->x==x&&tmp->y==y)
return 1;
tmp=tmp->next;
}
return 2;
}
void refreshBG()
{
int x,y;
mvprintw(0,0,"");
for(y=0;y<BOUND;y++){
if(y==0){
for(x=0;x<=BOUND;x++){
printw("--");
}
printw("\n");
}
for(x=0;x<BOUND;x++){
if(x==0){
printw("|");
}
if(hasSnakeBody(x,y)==1){
if(tail->x==x&&tail->y==y)
printw("OO");
else
printw("[]");
}else if(food->x==x&&food->y==y){
printw("##");
}else {
if(x==15&&y==15&&pass_1==1)
printw("**");
else if(x==10&&y==10&&pass_2==1)
printw("**");
else if(x==7&&y==9&&pass_3==1)
printw("**");
else
printw(" ");
}
if(x==BOUND-1)
{
printw("|");
}
}
if(y==8&&pass_3==1) printw("\tPASS 3");
if(y==8&&pass_3==0&&pass_2==1) printw("\tPASS 2");
if(y==8&&pass_2==0) printw("\tPASS 1");
if(y==10)printw("\tscore:%d",score);
if(y==12&&pass_1==1&&pass_2==0)printw("require:5 scores");
if(y==12&&pass_1==1&&pass_2==1&&pass_3==0)printw("require:10 scores");
if(y==12&&pass_3==1)printw("require:15 scores");
printw("\n");
if(y==BOUND-1)
{
for(x=0;x<=BOUND;x++)
{
printw("--");
}
printw("\n");
}
}
t_end =time(NULL);
printw(" time: %.0fs",difftime(t_end,t_start));
// refresh();
}
void initDir()
{
dir= RIGHT;
}
void wingame()
{
printw("\t you win");
}
void addNode()
{
node *newnode;
node *bak;
newnode=(node *)malloc(sizeof(node));
newnode->next=NULL;
tail->next = newnode;
bak = tail;
tail = newnode;
switch(dir)
{
case UP:
newnode->x=bak->x;
newnode->y=bak->y-1;
break;
case DOWN:
newnode->x=bak->x;
newnode->y=bak->y+1;
break;
case LEFT:
newnode->x=bak->x-1;
newnode->y=bak->y;
break;
case RIGHT:
newnode->x=bak->x+1;
newnode->y=bak->y;
break;
}
}
void dirch(int direction)
{
if(abs(direction)!=abs(dir))
dir=direction;
}
void initSnake()
{
head = tail = (node*)malloc(sizeof(node));
head->x=0;
head->y=0;
addNode();
addNode();
addNode();
}
void createFood()
{
node*tmp=head;
srand(time(NULL));
food = (node*)malloc(sizeof(node));
food->x=rand()%BOUND;
food->y=rand()%BOUND;
while(tmp!=NULL){
if(tmp->x==food->x&&tmp->y==food->y||food->x==15&&food->y==15||food->x==10&&food->y==10||food->x==7&&food->y==9)
{food->x=rand()%BOUND; food->y=rand()%BOUND; tmp=head; }
tmp=tmp->next;
}
}
void deleteHead()// yi dong
{
node *tmp = head;
head = head->next;
free(tmp);
tmp=NULL;
}
void moveSnake()
{
addNode();
if(pdfood())
{ score++;
createFood();
}else
deleteHead();
refreshBG();
}
int pdfood()
{
node *tmp = head;
while(tmp!=NULL){
if(tmp->x==food->x&&tmp->y==food->y)
return 1;
tmp = tmp->next;
}
return 0;
}
int killed_obstacle()
{
node *tmp=head;
while(tmp!=NULL){
if(pass_1==1&&tmp->x==15&&tmp->y==15)return 1;
if(pass_2==1&&tmp->x==10&&tmp->y==10)return 1;
if(pass_3==1&&tmp->x==7&&tmp->y==9)return 1;
tmp = tmp->next;
}
return 0;
}
int killed_wall()
{
node* tmp=head;
while(tmp!=NULL){
if(tmp->x<0||tmp->x>BOUND-1||tmp->y<0||tmp->y>BOUND-1)
return 1;
tmp=tmp->next;
}
return 0;
}
int killed_snake()
{
node *tmpi,*tmpj;
for(tmpi=head;tmpi!=NULL;tmpi=tmpi->next)
for(tmpj=head;tmpj!=NULL;tmpj=tmpj->next)
{ if(tmpi!=tmpj)
{
if(tmpi->x==tmpj->x&&tmpi->y==tmpj->y)
return 1;
}
}
return 0;
}
void newgame()
{
node*tmp=head;
node*tmp2;
while(tmp!=NULL)
{
tmp2=tmp->next;
free(tmp);
tmp=tmp2;
}
score=0;
t_start=time(NULL);
dir=RIGHT;
initSnake();
}
void refresh_thread()
{
int i;
while(1){
for(i=0;i<50000000;i++);
{
if(killed_wall()==0&&killed_snake()==0&&killed_obstacle()==0)
{ if(pass_2==0&&score==5){newgame(); pass_2=1;}
else if(pass_3==0&&pass_2==1&&score==10){newgame();pass_3=1;}else if(pass_3==1&&pass_2==1&&score==15){wingame();}
else
moveSnake();
}
else {
newgame();
}
}
}
}
void operate_thread()
{ int action;
while(1){
action=getch();
switch(action){
case KEY_UP:
dirch(UP);
break;
case KEY_LEFT:
dirch(LEFT);
break;
case KEY_RIGHT:
dirch(RIGHT);
break;
case KEY_DOWN:
dirch(DOWN);
break;
}
// usleep(200);
}
}
int main()
{
int action,i;
long int speeds[]={30000000,100000000};
t_start=time(NULL);
initial();//chu shi hua han shu
initDir();//chu shi hua fang xiang
// mean();
createFood();//sui ji sheng cheng shi wu
initSnake();//chu shi hua she sheng
refreshBG();//da ying tu xing jiemian
pthread_t pt_operate;
pthread_t pt_refresh;
pthread_create(&pt_operate,NULL,(void*)operate_thread,NULL);
pthread_create(&pt_refresh,NULL,(void*)refresh_thread,NULL);
pthread_join(pt_operate,NULL);
pthread_join(pt_refresh,NULL);
endwin();
return 0;
}