#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#ifndef TRUE
const bool TRUE = 1;
#endif
const char BLOCK = '@';
const char BALL = 'O';
const char BAT = 'T';
const char BOUND = '#';
const int ROW = 12;
const int COL = 9;
const int BLOCK_ROW = 4;
const int UP_BOUND = 0;
const int LEFT_BOUND = 0;
const int RIGHT_BOUND = COL + 1;
const int DOWN_BOUND = ROW;
const int TO_LD = 0, TO_RD = 1, TO_RU = 2, TO_LU = 3,
TO_STRAIGHT = 4;
const int COL_X[] = {-1, 1, 1, -1, 0};
const int ROW_Y[] = {1, 1, -1, -1, -1};
const int ALARM_SLEEP = 1;
//const char NO_ACTION = 'x';
char map[ROW + 5][COL + 5];
bool LOSE, WIN;
int cnt, TOTAL;
int batPos;
int ballRowPos, ballColPos;
int ballDir;
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
int kbhit();
int readch();
void setBall(char ch);
void setBat(char ch);
void printScreen();
static void catch_sigalrm(int sig);
static void (*Signal(int sig, void (*handler)(int )))(int);
void setSignalFunc();
void init();
void moveBat(char key);
void run();
int main(){
//set rand seed for the time when the BALL beating the BLOCK
srand(time(NULL));
init();
printScreen();
struct itimerval it;
(void)Signal(SIGALRM, &catch_sigalrm);
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 500000;
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 500000;
(void)setitimer(ITIMER_REAL, &it, NULL);
run();
return 0;
}
void init_keyboard(){
tcgetattr(0, &initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard(){
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit(){
char ch;
int nread;
if(peek_character != -1)
return 1;
new_settings.c_cc[VMIN] = 0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0, &ch, 1);
new_settings.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1){
peek_character = ch;
return 1;
}
return 0;
}
int readch(){
char ch;
if(peek_character != -1){
ch = peek_character;
peek_character = -1;
return ch;
}
read(0, &ch, 1);
return ch;
}
void setBall(char ch){
map[ballRowPos][ballColPos] = ch;
return ;
}
void setBat(char ch){
map[ROW][batPos - 1] = map[ROW][batPos] = map[ROW][batPos + 1] = ch;
return ;
}
void printScreen(){
system("clear");
if(LOSE){
printf("\t\t\t\t\t\t\tYOU LOSE, TRY IT AGAIN!\n\n\n");
return ;
}
if(WIN || cnt == TOTAL){
printf("\t\t\t\t\t\t\tCONGRATULATIONS, YOU WIN!\n\n\n");
return ;
}
//set 'BALL' and 'BAT'
for(int i= 0; i <= ROW + 1; i++){
if(i == ROW / 2)
printf("\t\tAuthor: %s, Class: %s.\t\t", "XuKe", "CS-095");
else if(i == (ROW / 2 + 1))
printf("\t\tStudent ID: %s.\t\t", "200901050633");
else
printf("\t\t\t\t\t\t\t");
for(int j = 0; j <= COL + 1; j++){
printf("%c", map[i][j]);
}
printf("\n");
}
printf("\t\t\t\t\t\t\t\tTotal: %d, Score: %d, Rest: %d.\n", TOTAL, cnt, TOTAL - cnt);
char * str;
switch(ballDir){
case 0: str = "To_LeftDown\n"; break;
case 1: str = "To_RightDown\n"; break;
case 2: str = "To_RightUp\n"; break;
case 3: str = "To_LeftUp\n"; break;
case 4: str = "Fire!!!\n"; break;
default:str = "Error!...\n"; break;
}
printf("\t\t\t\t\t\t\t\tStatus : %s.\n", str);
return ;
}
static void catch_sigalrm(int sig){
//identfy and draw the ball
setBall(' ');
int row, col;
do{
row = ballRowPos + ROW_Y[ballDir];
col = ballColPos + COL_X[ballDir];
if(map[row][col] == ' ' && row != DOWN_BOUND){
ballRowPos = row;
ballColPos = col;
}
else if(map[row][col] == BLOCK){
++cnt;
if(cnt == TOTAL)
WIN = TRUE;
ballRowPos = row;
ballColPos = col;
while(TRUE){
int tempDir = rand() % 4;
if(tempDir != ballDir){
ballDir = tempDir;
break ;
}
}
}
else if(map[row][col] == BAT){
if(ballDir == TO_LD)
ballDir = TO_LU;
else
ballDir = TO_RU;
if(map[ballRowPos + ROW_Y[ballDir]][ballColPos + COL_X[ballDir]] != BOUND &&
map[ballRowPos + ROW_Y[ballDir]][ballColPos + COL_X[ballDir]] != BAT){
ballRowPos += ROW_Y[ballDir];
ballColPos += COL_X[ballDir];
}
}
else if(map[row][col] == BOUND){
if(ballDir == TO_LD){
if(col == LEFT_BOUND)
ballDir = TO_RD;
else
ballDir = TO_LU;
}
else if(ballDir == TO_RD){
if(col == RIGHT_BOUND)
ballDir = TO_LD;
else
ballDir = TO_RU;
}
else if(ballDir == TO_RU){
if(col == RIGHT_BOUND)
ballDir = TO_LU;
else
ballDir = TO_RD;
}
else{
if(col == LEFT_BOUND)
ballDir = TO_RU;
else
ballDir = TO_LD;
}
if(map[ballRowPos + ROW_Y[ballDir]][ballColPos + COL_X[ballDir]] == BLOCK){
++cnt;
ballRowPos += ROW_Y[ballDir];
ballColPos += COL_X[ballDir];
}
else if(map[ballRowPos + ROW_Y[ballDir]][ballColPos + COL_X[ballDir]] != BOUND &&
map[ballRowPos + ROW_Y[ballDir]][ballColPos + COL_X[ballDir]] != BAT){
ballRowPos += ROW_Y[ballDir];
ballColPos += COL_X[ballDir];
}
}
else{
LOSE = TRUE;
ballRowPos += ROW_Y[ballDir];
ballColPos += COL_X[ballDir];
}
}while(map[ballRowPos][ballColPos] == BOUND || map[ballRowPos][ballColPos] == BAT);
setBall(BALL);
printScreen();
return ;
}
static void (*Signal(int sig, void (*handler)(int )))(int){
struct sigaction act, oact;
act.sa_handler = handler;
act.sa_flags = 0;
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
if(sigaction(sig, &act, &oact))
return SIG_ERR;
return oact.sa_handler;
}
void setSignalFunc(){
struct itimerval it;
(void)Signal(SIGALRM, &catch_sigalrm);
it.it_interval.tv_sec = 1;
it.it_interval.tv_usec = 0;
it.it_value.tv_sec = 1;
it.it_value.tv_usec = 0;
(void)setitimer(ITIMER_REAL, &it, NULL);
return ;
}
void init(){
//set LOSE flag and WIN flag
LOSE = !TRUE;
WIN = !TRUE;
//set cnt(record the counts beat) and TOTAL;
cnt = TOTAL = 0;
memset(map, ' ', sizeof(map));
//set '^'
for(int i = 0; i <= COL + 1; i++) map[DOWN_BOUND + 1][i] = '^';
//set '#'
for(int i = 0; i <= COL + 1; i++) map[UP_BOUND][i] = BOUND;
for(int i = 0; i <= ROW + 1; i++) map[i][LEFT_BOUND] = map[i][RIGHT_BOUND] = BOUND;
//set 'BLOCk'
for(int i = 1; i <= BLOCK_ROW;i++)
for(int j = 1; j <= COL ; j++){
map[i][j] = BLOCK;
++TOTAL;
}
//set 'BALL'
ballRowPos = ROW - 1;
ballColPos = COL / 2 + 1;
setBall(BALL);
//set 'BAT'
batPos = COL / 2 + 1;
setBat(BAT);
//set 'ballDir'
ballDir = TO_STRAIGHT;
return ;
}
void moveBat(char key){
if(key == 'a'){//move to left
if((batPos - 1) - 1 != LEFT_BOUND){
if(map[DOWN_BOUND - 1][batPos - 1] == BALL || map[DOWN_BOUND - 1][batPos] == BALL ||
map[DOWN_BOUND - 1][batPos + 1] == BALL){
setBall(' ');
--ballColPos;
ballDir = TO_LU;
setBall(BALL);
}
setBat(' ');
--batPos;
setBat(BAT);
}
}
else if(key == 'd'){//move to right
if((batPos + 1) + 1 != RIGHT_BOUND){
if(map[DOWN_BOUND - 1][batPos - 1] == BALL || map[DOWN_BOUND - 1][batPos] == BALL ||
map[DOWN_BOUND - 1][batPos + 1] == BALL){
setBall(' ');
++ballColPos;
ballDir = TO_RU;
setBall(BALL);
}
setBat(' ');
++batPos;
setBat(BAT);
}
}
else if(key == 'w'){
if(map[DOWN_BOUND - 1][batPos - 1] == BALL || map[DOWN_BOUND - 1][batPos] == BALL ||
map[DOWN_BOUND - 1][batPos + 1] == BALL){
system("clear");
ballDir = TO_STRAIGHT;
}
}
printScreen();
return ;
}
void run(){
int key;
init_keyboard();
while(!LOSE && !WIN){
if(kbhit()){
key = readch();
if(key == 'q')
break ;
moveBat((char)key);
}
}
// scanf("%c", &key);
// if(key != NO_ACTION){
// if(key == 'q')
// return ;
//
// moveBat(key);
// key = NO_ACTION;
// }
// }
close_keyboard();
return ;
}
蛋疼游戏
最新推荐文章于 2024-04-07 15:27:50 发布