一个能在Telnet或SSH终端玩的贪食蛇小游戏


//snake.h
#define SHM_KEY 1234

#define UP 119
#define DOWN 115
#define LEFT 97
#define RIGHT 100
#define QUIT 122

#define direct (*((int *)p_shm))
extern void *p_shm;
extern int v_speed;

extern void snake_init();
extern int snake_nextstep();


#include "snake.h"

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <curses.h>
#include <string.h>
#include <sys/types.h>

#define START_X 10
#define START_Y 10
#define INIT_SIZ 5
#define H_LEN 80
#define V_LEN 35


int screen_arr[H_LEN * V_LEN];
int snake_len = 0;
extern int v_speed;

/* Snake Body Node */
typedef struct node{
int pos_x;
int pos_y;
struct node *next;
struct node *pre;
}BNode;

BNode *s_head, *s_end;

/************************************************
* functions declare
***********************************************/
extern void snake_init();

static void snake_display();
static inline void snake_feed();
static inline void snake_head_grow(int px, int py);
static inline void snake_tail_cut();

extern void snake_init()
{
s_head = (BNode *)malloc(sizeof(BNode));
s_head->pos_x = START_X;
s_head->pos_y = START_Y;
s_head->next = NULL;
s_head->pre = NULL;
s_end = s_head;
screen_arr[START_X + START_Y * H_LEN] = 1;

int i;
for (i = 1; i < INIT_SIZ; i++)
snake_head_grow(START_X + i, START_Y);
snake_feed();
snake_display();
}

extern int snake_nextstep()
{
int next_px = s_head->pos_x;
int next_py = s_head->pos_y;

switch (direct) {
case UP: next_py--; break;
case RIGHT: next_px++; break;
case DOWN: next_py++; break;
case LEFT: next_px--; break;
}

int pos = next_px + next_py * H_LEN;

/* grip itself */
if (screen_arr[pos] == 1)
return ERR;

/* up against the wall */
if (next_px < 0 || next_px >= H_LEN ||
next_py < 0 || next_py >= V_LEN)
return ERR;

int grow = 0;
/* eat a food */
if (screen_arr[pos] == 2) {
grow = 1;
snake_len++;
snake_feed();
}

snake_head_grow(next_px, next_py);

if (!grow)
snake_tail_cut();

snake_display();
return OK;
}

static void snake_display()
{
printw(" Hungry Snake -- Enjoy it! :)\n");
printw(" +---------------------------------------------"
"-----------------------------------+\n");

int i, j;
for (i = 0; i < V_LEN; i++){
printw(" |");
for(j = 0; j < H_LEN; j++) {
int pos = i * H_LEN + j;
printw("%c", screen_arr[pos] == 0 ? ' ' :
(screen_arr[pos] == 1) ? '#' : '$');
}
printw("|\n");
}
printw(" +---------------------------------------------"
"-----------------------------------+\n");
printw(" Direction: %s\n", direct == UP ? "Up" :
(direct == DOWN ? "Down" : (direct == LEFT ? "Left" : "Right")));
printw(" Scores: %d", snake_len);
refresh();
}


/********************************************************
* static functions
********************************************************/

static inline void snake_feed()
{
int pos = rand() % (H_LEN * V_LEN);
while (screen_arr[pos] == 1)
pos = rand() % (H_LEN * V_LEN);
screen_arr[pos] = 2;
v_speed -= 10;
}

static inline void snake_head_grow(int px, int py)
{
BNode *p = (BNode *)malloc(sizeof(BNode));
p->pos_x = px;
p->pos_y = py;

p->pre = NULL;
p->next = s_head;
s_head->pre = p;
s_head = p;
screen_arr[px + py * H_LEN] = 1;
}

static inline void snake_tail_cut()
{
screen_arr[s_end->pos_x + s_end->pos_y * H_LEN] = 0;
s_end = s_end->pre;
free(s_end->next);
s_end->next = NULL;
}


//usr_handler.c
#include "snake.h"

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <curses.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <time.h>

static void wait_user_handle();

void *p_shm = NULL;
int shmid = 0;;
int v_speed = 200;

int main(int argc, char *argv[])
{
pid_t pid;
initscr();
if ((pid = fork()) == 0) {
sleep(2);
shmid =
shmget((key_t) SHM_KEY, sizeof(int), 0666 | IPC_CREAT);
p_shm = shmat(shmid, (void *) 0, 0);
struct timespec slp = { (time_t) 0, 1000000 * v_speed };
snake_init();
while (true) {
if (direct == QUIT)
break;
clear();
snake_nextstep(); /* sleep specified nanoseconds and continue to run. */
slp.tv_nsec = 1000000 * v_speed;
nanosleep(&slp, NULL);
}
shmdt(p_shm);
} else { /* create shared memory by parent process. */
shmid =
shmget((key_t) SHM_KEY, sizeof(int), 0666 | IPC_CREAT);
if (shmid == -1) {
printw("shmget failed!\n");
exit(EXIT_FAILURE);
}
p_shm = shmat(shmid, (void *) 0, 0);
wait_user_handle();
waitpid(pid, NULL, 0); /* destroy shared memory by parent process. */
shmdt(p_shm);
shmctl(shmid, IPC_RMID, 0);
endwin();
} exit(EXIT_SUCCESS);
}

static void wait_user_handle()
{
int i;
int run = true;

int UP_DOWN = UP + DOWN;
int LEFT_RIGHT = LEFT + RIGHT;
int sum;
while (run) {
noecho();
i = getch();
echo();
switch (i) {
case UP:
case DOWN:
case LEFT:
case RIGHT:
sum = i + direct;
if(sum != UP_DOWN && sum != LEFT_RIGHT)
direct = i;
break;
case QUIT:
run = false;
direct = i;
break;
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值