Linux贪吃蛇小游戏 curses库1.0

此版本为测试版,还有些细节问题需要改善,不过已经可以正常游戏,没有明显的bug
/****************************************************************************
 * snake.c
 *
 * Author:SamBrown
 * 
 *
 * Implements the game of Snake.
 ***************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<curses.h>
#include<sys/time.h>
#include<signal.h>
#include <unistd.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define Start_Error "Error starting up ncurses!\n"
#define ICON_FOOD '*'
#define ICON_BUG '#'
#define ICON_SNAKE '@'
#define CRASH_WALL 1
#define CRASH_ITSELF 2
#define WIN 3
#define BLANK ' '
#define ARGC_ERR "your input is wrong, eg: ./snake 2"
typedef struct Snake
{
        int x, y;
        struct Snake * next;
        struct Snake * pre;
}Snake;
typedef struct Food_Pos
{
        int x, y;
}Food;
int a = 1, b= 1;
Food food;
int dirx, diry;
int speed = 2, control = 2;
int length;
Snake *head;
Snake *tail;
bool Start();						//ok
void Init();						//ok
void F_Dis();						//ok
void S_Init();						//ok
void S_Move();						//ok     
void S_Insert( int y, int x );					//ok
void S_Delete();					//ok
int Set_ticker( int n_msecs );		//ok
void Key_Control();					//ok
void S_Free();						//ok
void End();                //ok
void gameover( int n );    //ok
int main( int argc, char * argv[] ) 
{
	if( argc != 2 )
	{
		fprintf( stderr, ARGC_ERR );
		exit( 0 );
	}
	if( strcmp( argv[1], "1" ) != 0  )
	{
		fprintf( stderr, "sorry, we just support one player now" );
		exit( 0 );
	}
    if( !Start() )         
    {
        fprintf(stderr, Start_Error );
        return 0;
    }
    Init();             
    F_Dis();                
    S_Init();                 
    signal( SIGALRM, S_Move );
    Set_ticker( 50 );
    Key_Control();
    End();    
    return 0;
}
void S_Move( )
{
	 char c;
     int move = 0;
     signal(SIGALRM, SIG_IGN);
     
     /* Crash Wall   */
     if( (head->y+diry <= 1 && diry == -1) ||
         (head->y+diry >= LINES && diry == 1 ) ||
         (head->x+dirx <= 1 && dirx == -1 ) ||
         (head->x+dirx >=COLS && dirx == 1 ) 
       )
       gameover( CRASH_ITSELF );
       
     /* Crash itself */
	 c = mvinch( head->y+diry, head->x+dirx );
	 mvprintw( 0, 0, "%c", c );
     if( c == '@' )
       gameover( CRASH_ITSELF );
	 if( speed > 0 && control-- == 1 )
	 {
		S_Insert( head->y+diry, head->x+dirx );
		/* reset the speed of the snake */
		control = speed;	
		move = 1;
	 }
     if( move )
     {
         /* Eat the Food */    
         if( head->y == food.y &&  head->x == food.x )
         {
             length++;
             if( length > 20 )
                 gameover( WIN );
			 F_Dis();
         }
         else
         {
             mvaddch( tail->y, tail->x, ' ' );
             S_Delete( );        
         }    
		/* refresh */
		 mvaddch( head->y, head->x, ICON_SNAKE );
		 refresh();
	 }
	 signal( SIGALRM, S_Move );
}
void gameover(int n)
{
	switch( n )
	{
		case WIN: 
			mvaddstr(LINES / 2, COLS / 3 - 4, "Mission Completes,press any key to exit.\n");
			break;
		case CRASH_WALL:
			mvaddstr(LINES/2, COLS/3 - 4, "Game Over, crash the wall,press any key to exit.\n");
			break;
		case CRASH_ITSELF:
			mvaddstr(LINES/2, COLS/3 - 4, "Game Over, crash yourself,press any key to exit.\n");
			break;
		default:
			break;
	}
	refresh();
	/* delete the whole double linked list */
	End();
}
void S_Free()
{
     Snake *temp;
     Snake *ne;
     temp = head;
     while( temp != tail )
     {
            ne = temp->pre;
            free( temp );
            temp = ne;
     }
     free( tail );
}
void S_Insert( int y, int x )
{
     Snake * temp = (Snake *)malloc( sizeof(Snake) );
     if( temp == NULL )
         perror( "malloc error" );
     temp->x = x;
     temp->y = y;
     head->next = temp;
     temp->pre = head;
     temp->next = NULL;
     head = temp;
	 
}
void S_Delete()
{
     Snake *temp;
     temp = tail->next;
     tail->next = NULL;
	 free( tail );
     tail = temp;
}
void End()
{
    /* turn off the timer */
	S_Free();
    Set_ticker(0);	
	getchar();
	endwin();
	exit(0);
}
void Key_Control()
{
     int key;
     keypad( stdscr, true );
     while( key = getch() , key != 'q' )
     {
            switch( key )
            {
                    case KEY_LEFT:
                         if( length > 1 && dirx == 1 && diry == 0 )
                             continue;
                         dirx = -1;
                         diry = 0;
						 break;
                    case KEY_RIGHT:
                         if( length > 1 && dirx == -1 && diry == 0 )
                             continue;
                         dirx = 1;
                         diry = 0;
                         break;
                    case KEY_UP:
                         if( length > 1 && dirx == 0 && diry == 1 )
                             continue;
                         dirx = 0;
                         diry = -1;
                         break;
                    case KEY_DOWN:
                         if( length > 1 && dirx == 0 && diry == -1 )
                             continue;
                         dirx = 0;
                         diry = 1;
                         break;
            } 
     }
}
int Set_ticker(int n_msecs)
{
	struct itimerval new_timeset;
	long n_sec, n_usecs;

	n_sec = n_msecs / 1000;					/* int second part */
	n_usecs = (n_msecs % 1000) * 1000L;		/* microsecond part */

	new_timeset.it_interval.tv_sec = n_sec;	/* set reload */
	new_timeset.it_interval.tv_usec = n_usecs;

	new_timeset.it_value.tv_sec = n_sec;	/* set new ticker value */
	new_timeset.it_value.tv_usec = n_usecs;

	return setitimer(ITIMER_REAL, &new_timeset, NULL);
}

void S_Init()
{
     dirx = 1;
     diry = 0;
     /* At the beginning the length of snake is 1 */
     length = 1;
     Snake *temp = ( Snake* )malloc( sizeof(Snake) );
     if( temp == NULL )
         perror("malloc");
     temp->x = 5;
     temp->y = 10;
     head = temp;
	 tail = temp;
     temp->next = NULL;
     temp->pre = NULL;
     mvaddch(temp->y, temp->x, ICON_SNAKE );
     refresh();
}
void Init()
{
	   	/* the init interface */
     mvprintw( LINES/2, COLS/2, "The Snake...\n" );
	 mvprintw( LINES/2+1, COLS/2, "Author:SamBrown\n" );
	 mvprintw( LINES/2+2, COLS/2, "<-^->  Control\n " );
	 mvprintw( LINES/2+3, COLS/2, "press any key to continue...\n");
	 getch();
	 clear();
}
void F_Dis()
{   
    srand(time(0));
	food.x = rand() % (COLS-5);
	food.y = rand() % (LINES-5);
//	food.x = 20;
//	food.y = 10;
	mvaddch(food.y, food.x, ICON_FOOD);/* display the food */
	refresh();
}
bool Start( )
{
    // initialize ncurses
    if (initscr() == NULL)
        return false;

    // prepare for color if possible
    if (has_colors())
    {
        // enable color
        if (start_color() == ERR || attron(A_PROTECT) == ERR)
        {
            endwin();
            return false;
        }    
    }

    // don't echo keyboard input
    if ( noecho() == ERR )
    {
        endwin();
        return false;
    }

    // disable line buffering and certain signals
    if ( raw() == ERR )
    {
        endwin();
        return false;
    }

    // enable arrow keys
    if (keypad(stdscr, true) == ERR)
    {
        endwin();
        return false;
    }
    
   	/* set cursor invisible */
    curs_set(0);
	crmode(); 		
    // wait 1000 ms at a time for input
    timeout(1000);

    // w00t
    return true;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值