贪吃蛇(十二)贪吃蛇咬到自己

2023-12-24 15:30:58

最后我们做小的机制优化,蛇咬到自己后会导致游戏结束,重置。

实现思路

我们通过循环整个蛇身,判断蛇头(链表尾指针)是否和蛇身中的某一处坐标相同,如果相同,那么游戏结束。注意,需要蛇头和除了蛇身的位置去作比较,否则会导致每次都判断通过。

#include"curses.h"
#include "stdlib.h"
#include "pthread.h"
#include "time.h"
#define UP     1
#define DOWN  -1
#define LEFT   2
#define RIGHT -2

struct Snake
{
  int row;
  int col;
  struct Snake* next; 
};

struct Snake food;


int key;  // user input
int dir;
struct Snake* head = NULL;
struct Snake* tail = NULL;

void addNode();
void mapinit();


void cursesinit()
{
   
  initscr();
  keypad(stdscr,1);
  // noecho();
}


void snakeinit()
{
  // init food
  foodinit();
  // dir init
  dir = RIGHT;

  // free 
  struct Snake* p;
  while(head != NULL)
  {
    p = head;
    head = head->next;
    free(p);
  }
  // create node
  head = (struct Snake*)malloc(sizeof(struct Snake));
  head->row = 2;
  head->col = 2;
  head->next = NULL;
  tail = head;

  addNode();
  addNode();
}


void foodinit()
{
  // 使用当前时间作为种子
  srand(time(NULL));  
  // 生成[1, 19)区间的随机数
  int x = rand() % 18 + 1;
  int y = rand() % 18 + 1;
  food.row = x;
  food.col = y;
  x += 2;
  y += 2;
}

void addNode()
{  
  struct Snake* node = (struct Snake*)malloc(sizeof(struct Snake));
  node->next = NULL;
  
  switch(dir)
  {
	case RIGHT:
	  node->row = tail->row;
          node->col = tail->col + 1;
	  break;
	case LEFT:
	  node->row = tail->row;
          node->col = tail->col - 1;
	  break;
	case DOWN:
	  node->row = tail->row + 1;
          node->col = tail->col;
	  break;
	case UP:
	  node->row = tail->row - 1;
          node->col = tail->col;
	  break;
  }
  
  tail->next = node;
  tail = node;
}

void deleteNode()
{
  struct Snake* p;
  p = head;
  head = head->next;
  free(p);
}

int isSnakeDie()
{
  
  if(tail->row == 0 || tail->col == 0 || tail->row >= 20 || tail->col >= 19)
	return 1;
  
  struct Snake* p;
  p = head;
  while(p->next != NULL)
  {
	if(p->row == tail->row && p->col == tail->col)
		return 1;
	p = p->next;
  }
  return 0;
}

void moveSnake()
{
  addNode();

  // if there have food
  if(hasFood(tail->row,tail->col))
	foodinit();
  else
	deleteNode();

  // if snake is die
  if(isSnakeDie())
	snakeinit(); 
}


int hasSnake(int row,int col)
{
  struct Snake* p = head;
  while(p!=NULL)
  {
    if(row == p->row && col == p->col)
	return 1;
    p = p->next;
  }
  return 0; 
}

int hasFood(int row,int col)
{
  if(row==food.row && col==food.col)
	return 1;
  return 0;
}

void mapinit()
{
  int row;
  int col;
  move(0,0);
  for(row = 0;row < 20;row++)
  {
   // one
   if(row == 0 || row == 19)
   {
     for(col = 0;col < 19;col++)
        printw("--");
   }
   // two
   else
   {
     for(col = 0;col < 20;col++)
     {
        if(col == 0 || col == 19 ) printw("|");
	else if(hasSnake(row,col))
	{
	  printw("[]");
	}
	else if(hasFood(row,col))
	{
	  printw("##");
	}
	else
	{
	  printw("  "); 
	}
     }
   }

    printw("\n");
  }

  printw("By hongzhe food:(%d,%d)\n",food.row,food.col);
}


void refreshScreen()
{
  while(1)
  {
	moveSnake(); // snake forward 
	mapinit();   // fresh map
	refresh();   // fresh screen
	usleep(100000);	// sleep(0.5)
  }
  return;
}

void turnDir(int direction)
{
  if(abs(dir) != abs(direction))
	dir = direction;
}


void changeDir()
{
  
  while(1)
  {
    key = getch();
    switch(key)
    {
      case KEY_DOWN:
	printw("\rDOWN\t");
	turnDir(DOWN);
	break;
      case KEY_RIGHT:
	printw("\rRIGHT\t");
	turnDir(RIGHT);
	break;
      case KEY_LEFT:
	printw("\rLEFT\t");
	turnDir(LEFT);
	break;
      case KEY_UP:
	printw("\rUP\t");
	turnDir(UP);
	break;

    }
  }
  return;
}




int main()
{
  pthread_t t1;
  pthread_t t2;
 
  cursesinit();  
  snakeinit();
  mapinit();
  

  pthread_create(&t1,NULL,refreshScreen,NULL);
  pthread_create(&t2,NULL,changeDir,NULL);

  while(1);  // zu se main thread

  getch();  
  endwin();
  return 0;
}


学习打卡

在这里插入图片描述

文章来源:https://blog.csdn.net/qq_17802895/article/details/135181756
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。