#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <ncurses.h>
#define X_MAX 53 地图大小
#define Y_MAX 100
#define BLACKDROP ' ' 背景
#define BOUNDARY '0' 边界
#define ENEMY 'v' 敌机
#define PLANE '^' 自己
#define ATTACK '|' 己方子弹
#define ATTACK1 '*' 地方子弹
typedef struct Enemy 敌机结构体
{
int x;
int y;
_Bool tof;
struct Enemy *next;
}
Enemy;
typedef struct Enemy_attack 敌机子弹结构体
{
int x;
int y;
struct Enemy_attack *next;
}
Enemy_attack;
typedef struct Attack 己方子弹结构体
{
int x;
int y;
struct Attack *next;
}
Attack;
Enemy *EHEAD, *ETAIL;
Enemy_attack *EAHEAD, *EATAIL;
Attack *HEAD, *TAIL;
int X = 52, Y = 50; 自己坐标
void my_refresh(); 刷新
void printmain(void); 打印菜单
void make_HEAD(void); 创建链表头指针
void set_itimerval(struct itimerval *t); 设定定时时间
void printmap(void); 打印地图
void set_plane(void); 放置飞机
int get_move(char move); 获取移动
void clear_plane(void); 清楚飞机
void plane_attack(void); 攻击指令
void set_attack(int x, int y); 放置子弹
void attack_refresh(void); 刷新子弹
void clear_attack(int x, int y); 清楚子弹
void free_attack(Attack *last, Attack *next); 释放子弹链表
void add_enemy(void); 添加敌机
void move_enemy(void); 敌机移动
void clear_enemy(int x, int y); 清除敌机
void free_enemy(Enemy *last, Enemy *next); 释放敌机链表
void set_enemy(int x, int y); 放置敌机
void enemy_attack(Enemy *next); 敌机攻击
void set_enemy_attack(int x, int y); 放置敌机子弹
void enemy_attack_refresh(void); 刷新敌机子弹
void clear_enemy_attack(int x, int y); 清楚敌机子弹
void free_enemy_attack(Enemy_attack *last, Enemy_attack *next); 释放敌机子弹链表
void exit_game(void); 退出游戏
void exit_game(void)
{
endwin();
exit(0);
}
void free_enemy_attack(Enemy_attack *last, Enemy_attack *next)
{
last->next = next->next;
free(next);
refresh();
}
void clear_enemy_attack(int x, int y)
{
move(x, y);
addch(BLACKDROP);
refresh();
}
void enemy_attack_refresh(void)
{
Enemy_attack *last, *next;
last = EAHEAD;
next = EAHEAD->next;
while(next != NULL)
{
clear_enemy_attack(next->x, next->y);
next->x++;
move(next->x, next->y);
if(inch() == BOUNDARY)
{
free_enemy_attack(last, next);
next = last->next;
}
else
{
set_enemy_attack(next->x, next->y);
last->next;
next = next->next;
}
}
refresh();
}
void set_enemy_attack(int x, int y)
{
move(x, y);
addch(ATTACK1);
refresh();
}
void enemy_attack(Enemy *next)
{
Enemy_attack *new;
new = (Enemy_attack *)malloc(sizeof(Enemy_attack));
new->x = next->x;
new->y = next->y;
if(EAHEAD->next == NULL)
{
EAHEAD->next = new;
}
else
{
EATAIL->next = new;
}
new->next = NULL;
EATAIL = new;
set_enemy_attack(new->x, new->y);
refresh();
}
void set_enemy(int x, int y)
{
move(x, y);
addch(ENEMY);
refresh();
}
void free_enemy(Enemy *last, Enemy *next)
{
last->next = next->next;
free(next);
refresh();
}
void clear_enemy(int x, int y)
{
move(x, y);
addch(BLACKDROP);
refresh();
}
void move_enemy(void)
{
Enemy *last, *next;
int i;
char a;
last = EHEAD;
next = EHEAD->next;
while(next != NULL)
{
i = rand()%5;
clear_enemy(next->x, next->y);
switch(i)
{
case 0:
next->x++;
break;
case 1:
next->x--;
break;
case 2:
next->y++;
break;
case 3:
next->y--;
break;
case 4:
if(next->tof == 0)
{
next->tof = 1;
enemy_attack(next);
}
break;
}
move(next->x, next->y);
a = inch();
if(a == BOUNDARY || a == ATTACK)
{
free_enemy(last, next);
next = last->next;
}
else
{
set_enemy(next->x, next->y);
last = next;
next = next->next;
}
}
refresh();
}
void add_enemy(void)
{
Enemy *enemy;
int x, y;
_Bool tof;
enemy = (Enemy *)malloc(sizeof(Enemy));
do
{
tof = 1;
enemy->x = rand()%(X_MAX - 1) + 1;
enemy->y = rand()%(X_MAX - 1) + 1;
move(enemy->x, enemy->y);
if(inch() != BLACKDROP)
{
tof = 0;
}
}
while(!tof);
if(EHEAD->next == NULL)
{
EHEAD->next = enemy;
}
else
{
ETAIL->next = enemy;
}
enemy->next = NULL;
ETAIL = enemy;
refresh();
}
void free_attack(Attack *last, Attack *next)
{
last->next = next->next;
free(next);
refresh();
}
void clear_attack(int x, int y)
{
move(x, y);
addch(BLACKDROP);
refresh();
}
void attack_refresh(void)
{
Attack *last, *next, *temp;
last = HEAD;
next = HEAD->next;
while(next != NULL)
{
clear_attack(next->x, next->y);
next->x--;
move(next->x, next->y);
if(inch() == BOUNDARY)
{
free_attack(last, next);
next = last->next;
}
else
{
set_attack(next->x, next->y);
last = next;
next = next->next;
}
}
refresh();
}
void set_attack(int x, int y)
{
move(x, y);
addch(ATTACK);
refresh();
}
void plane_attack(void)
{
Attack *new;
new = (Attack *)malloc(sizeof(Attack));
new->x = X - 1;
new->y = Y;
if(HEAD->next == NULL)
{
HEAD->next = new;
}
else
{
TAIL->next = new;
}
new->next = NULL;
TAIL = new;
set_attack(new->x, new->y);
refresh();
}
void clear_plane(void)
{
move(X, Y);
addch(BLACKDROP);
refresh();
}
int get_move(char move)
{
int x, y;
char a;
x = X;
y = Y;
clear_plane();
switch(move)
{
case 'w':
X--;
break;
case 'a':
Y--;
break;
case 's':
X++;
break;
case 'd':
Y++;
break;
case 'j':
plane_attack();
break;
case 'q':
return 0;
}
move(X, Y);
a = inch();
if(a == ATTACK1 || a == ENEMY)
{
exit_game();
}
if(a == BOUNDARY)
{
X = x;
Y = y;
}
refresh();
return 1;
}
void set_plane(void)
{
move(X, Y);
addch(PLANE);
refresh();
}
void printmap(void)
{
int x, y;
move(0, 0);
addstr(" \n \n ");
for(x = 0; x <= X_MAX; x++)
{
for(y = 0; y <= Y_MAX; y++)
{
if(x == 0 || y == 0 || x == X_MAX || y == Y_MAX)
{
move(x, y);
addch(BOUNDARY);
}
}
}
move(X_MAX + 1, 0);
addstr("(w/a/s/d/j/q):");
refresh();
}
void set_itimerval(struct itimerval *t)
{
t->it_interval.tv_usec = 200000;
t->it_interval.tv_sec = 0;
t->it_value.tv_usec = 10;
t->it_value.tv_sec = 0;
}
void make_HEAD(void)
{
HEAD = (Attack *)malloc(sizeof(Attack));
HEAD->x = 0;
HEAD->y = 0;
HEAD->next = NULL;
EHEAD = (Enemy *)malloc(sizeof(Enemy));
EHEAD->x = 0;
EHEAD->y = 0;
EHEAD->tof = 0;
EHEAD->next = NULL;
EAHEAD = (Enemy_attack *)malloc(sizeof(Enemy_attack));
EAHEAD->x = 0;
EAHEAD->y = 0;
EAHEAD->next = NULL;
}
void printmain()
{
move(0, 0);
addstr("1.begin\n");
addstr("2.quit\n");
addch(':');
refresh();
}
void my_refresh()
{
int i = rand()%100;
attack_refresh();
if(i >= 0 && i <= 20)
{
add_enemy();
}
move_enemy();
enemy_attack_refresh();
refresh();
}
int main(void)
{
struct itimerval t;
char move;
initscr();
cbreak();
noecho();
curs_set(0);
printmain();
move = getch();
if(move == '1')
{
make_HEAD();
set_itimerval(&t);
setitimer(ITIMER_REAL, &t, NULL);
signal(SIGALRM, my_refresh);
printmap();
do
{
srand(time(NULL));
do
{
set_plane();
move = getch();
}
while(move != 'q' && move != 'w' && move != 'a' && move != 's' && move != 'd' && move != 'j');
}
while(get_move(move));
}
endwin();
return 0;
}