------------
|..........|
|..........|
|.....?....|
|.....?....|
|.....??...|
|..........|
|..........|
|..........| Press 'q' to quit!
|..........|
|..........|
|..........| 得分: 0
|..........|
|..........|
|..........|
|..........|
|..........|
|..........|
|........?.|
|....???.?.|
|.....?..??|
------------game over!
彩色没有打印出来
// block.h
// Created by on 16-3-22.
//
#ifndef ELS1_BLOCK_H
#define ELS1_BLOCK_H
#if 0
#define PRINTF_TEST cout << __FILE__<< ":" << __FUNCTION__ << "------" << __LINE__ << endl;
#else
#define PRINTF_TEST
#endif
typedef struct point_t {
int x;
int y;
}point_t;
class block_c {
public:
int move_left();
int move_right();
int move_down();
int set_point(point_t t_point);
int get_point(point_t *t_point);
int set_flg(int flg);
int get_flg(int *flg);
int set_clolr(int clolr);
int get_clolr(int *clolr);
block_c();
block_c(point_t t_point1);
virtual ~block_c();
private:
int clolr;
int flg;
point_t t_point;
};
#endif //ELS1_BLOCK_H
//block.cpp
// Created by on 16-3-22.
//
#include <iostream>
#include "block.h"
using namespace std;
block_c::block_c():flg(0)
{
PRINTF_TEST
point_t t_tmp = {-1, -1};
t_point = t_tmp;
}
block_c::block_c(point_t t_point1):t_point(t_point1),flg(0)
{
PRINTF_TEST
}
block_c::~block_c()
{
PRINTF_TEST
}
int block_c::move_left()
{
PRINTF_TEST
t_point.x--;
return 0;
}
int block_c::move_right()
{
PRINTF_TEST
t_point.x++;
return 0;
}
int block_c::move_down()
{
PRINTF_TEST
t_point.y++;
return 0;
}
int block_c::set_point(point_t t_point)
{
PRINTF_TEST
this->t_point = t_point;
return 0;
}
int block_c::get_point(point_t *t_point)
{
PRINTF_TEST
*t_point = this->t_point;
return 0;
}
int block_c::set_flg(int flg)
{
PRINTF_TEST
this->flg = flg;
return 0;
}
int block_c::get_flg(int *flg)
{
PRINTF_TEST
*flg = this->flg;
return 0;
}
int block_c::set_clolr(int clolr)
{
PRINTF_TEST
this->clolr = clolr;
return 0;
}
int block_c::get_clolr(int *clolr)
{
PRINTF_TEST
*clolr = this->clolr;
return 0;
}
//shape.h
// Created by on 16-3-22.
//
#ifndef ELS1_SHAPE_H
#define ELS1_SHAPE_H
#include "block.h"
#define NUM_BLOCK 4
class shape_c : public block_c{
private:
block_c c_buf[NUM_BLOCK];
public:
int create();
int move_left();
int move_right();
int move_down();
int overturn();
int set_point(const point_t *t_p);
int get_point(point_t *t_p);
int set_clolr(const int *clolr);
int get_clolr(int *clolr);
shape_c();
shape_c(point_t t_p);
virtual ~shape_c();
private:
};
#endif //ELS1_SHAPE_H
// shape.cpp
// Created by on 16-3-22.
//
#include <iostream>
#include "shape.h"
using namespace std;
shape_c::shape_c()
{
point_t t_p = {-1, -1};
PRINTF_TEST
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].set_point(t_p);
}
}
shape_c::shape_c(point_t t_p):block_c(t_p)
{
PRINTF_TEST
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].set_point(t_p);
}
}
shape_c::~shape_c()
{
PRINTF_TEST
}
int shape_c::move_left()
{
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].move_left();
}
return 0;
}
int shape_c::move_right()
{
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].move_right();
}
return 0;
}
int shape_c::move_down()
{
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].move_down();
}
return 0;
}
int shape_c::overturn()
{
int x, y;
point_t t_center, t_tmp;
c_buf[0].get_point(&t_center);
for (int i = 0; i < NUM_BLOCK; i++) {
c_buf[i].get_point(&t_tmp);
x = t_tmp.x - t_center.x;
y = t_tmp.y - t_center.y;
t_tmp.x = t_center.x + y;
t_tmp.y = t_center.y - x;
c_buf[i].set_point(t_tmp);
}
return 0;
}
int shape_c::set_point(const point_t *t_p)
{
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].set_point(*t_p++);
}
return 0;
}
int shape_c::get_point(point_t *t_p)
{
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].get_point(t_p++);
}
return 0;
}
int shape_c::set_clolr(const int *clolr)
{
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].set_clolr(*clolr++);
}
return 0;
}
int shape_c::get_clolr(int *clolr)
{
for (int i = 0; i < NUM_BLOCK; ++i) {
c_buf[i].get_clolr(clolr++);
}
return 0;
}
//backplane.h
// Created by on 16-3-22.
//
#ifndef ELS1_BACKPLANE_H
#define ELS1_BACKPLANE_H
#include "shape.h"
#define NONE "\33[m"
#define RED "\33[0;32;31m"
#define LIGHT_RED "\33[1;31m"
#define GREEN "\33[0;32;32m"
#define LIGHT_GREEN "\33[1;32m"
#define BLUE "\33[0;32;34m"
#define LIGHT_BLUE "\33[1;34m"
#define DARY_GRAY "\33[1;30m"
#define CYAN "\33[0;36m"
#define LIGHT_CYAN "\33[1;36m"
#define PURPLE "\33[0;35m"
#define LIGHT_PURPLE "\33[1;35m"
#define BROWN "\33[0;33m"
#define YELLOW "\33[1;33m"
#define LIGHT_GRAY "\33[0;37m"
#define WHITE "\33[1;37m"
#define ENTER "\n"
// 清除屏幕
#define CLEAR() printf("\33[2J")
//清除从光标位置到行末的内容
#define CLEAR_TAIL() printf("\33[K");
// 上移光标
#define MOVE_UP(x) printf("\33[%dA", (x))
// 下移光标
#define MOVE_DOWN(x) printf("\33[%dB", (x))
// 左移光标
#define MOVE_LEFT(y) printf("\33[%dD", (y))
// 右移光标
#define MOVE_RIGHT(y) printf("\33[%dC",(y))
// 定位光标
#define MOVETO(x,y) printf("\33[%d;%dH", (x), (y))
// 光标复位
#define RESET_CURSOR() printf("\33[H")
// 隐藏光标
#define HIDE_CURSOR() printf("\33[?25l")
// 显示光标
#define SHOW_CURSOR() printf("\33[?25h")
//反显
#define HIGHT_LIGHT() printf("\33[7m")
#define UN_HIGHT_LIGHT() printf("\33[27m")
#define STDIN 0
#define NUM_MAX_KEY 25
#define TIME_SLEEP (500 * 1000) //ms
#define CHAR_A 'a'
#define CHAR_D 'd'
#define CHAR_S 's'
#define CHAR_Q 'q'
#define CHAR_SPACE ' '
#define CHAR_LEFT 0x44
#define CHAR_RIGHT 0x43
#define CHAR_DOWN 0x42
#define STR_BOX "?"
#define STR_FRAME_X "-"
#define STR_FRAME_Y "|"
#define STR_POINT "."
#define HIGH_BACK 20
#define WID_BACK 10
#define NUM_SHAPE 7
#define NUM_CLOLR 8
class backplane_c {
private:
unsigned int score;
block_c c_buf[HIGH_BACK][WID_BACK];
shape_c s,s_save;
public:
int init();
int deal_key(char *buf, int num);
int judge_move();
int judge_down();
int deal_score();
int cp_box();
int paint_box(int y, int x);
int paint();
int printf_clolr(int clolr);
backplane_c();
~backplane_c();
};
#endif //ELS1_BACKPLANE_H
//backplane.cpp
// Created by on 16-3-22.
//
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include "backplane.h"
using namespace std;
backplane_c::backplane_c():score(0)
{
}
backplane_c::~backplane_c()
{
}
int backplane_c::init()
{
int i;
int buf_clolr[NUM_CLOLR] = {0};
point_t t_buf[NUM_BLOCK];
PRINTF_TEST
srand((unsigned)time(NULL));
i = 1+ rand() % NUM_SHAPE;
switch(i) {
case 1: //L
t_buf[0].x = WID_BACK / 2;
t_buf[0].y = 0;
t_buf[1].x = WID_BACK / 2;
t_buf[1].y = 1;
t_buf[2].x = WID_BACK / 2;
t_buf[2].y = 2;
t_buf[3].x = WID_BACK / 2 + 1;
t_buf[3].y = 2;
break;
case 2: //反L
t_buf[0].x = WID_BACK / 2;
t_buf[0].y = 0;
t_buf[1].x = WID_BACK / 2 + 1;
t_buf[1].y = 0;
t_buf[2].x = WID_BACK / 2;
t_buf[2].y = 1;
t_buf[3].x = WID_BACK / 2;
t_buf[3].y = 2;
break;
case 3: //Z
t_buf[0].x = WID_BACK / 2 - 1;
t_buf[0].y = 0;
t_buf[1].x = WID_BACK / 2;
t_buf[1].y = 0;
t_buf[2].x = WID_BACK / 2;
t_buf[2].y = 1;
t_buf[3].x = WID_BACK / 2 + 1;
t_buf[3].y = 1;
break;
case 4: //反Z
t_buf[0].x = WID_BACK / 2;
t_buf[0].y = 0;
t_buf[1].x = WID_BACK / 2 + 1;
t_buf[1].y = 0;
t_buf[2].x = WID_BACK / 2;
t_buf[2].y = 1;
t_buf[3].x = WID_BACK / 2 - 1;
t_buf[3].y = 1;
break;
case 5: //田
t_buf[0].x = WID_BACK / 2;
t_buf[0].y = 0;
t_buf[1].x = WID_BACK / 2 + 1;
t_buf[1].y = 0;
t_buf[2].x = WID_BACK / 2;
t_buf[2].y = 1;
t_buf[3].x = WID_BACK / 2 + 1;
t_buf[3].y = 1;
break;
case 6: //1
t_buf[0].x = WID_BACK / 2;
t_buf[0].y = 0;
t_buf[1].x = WID_BACK / 2;
t_buf[1].y = 1;
t_buf[2].x = WID_BACK / 2;
t_buf[2].y = 2;
t_buf[3].x = WID_BACK / 2;
t_buf[3].y = 3;
break;
case 7: //山
t_buf[0].x = WID_BACK / 2 - 1;
t_buf[0].y = 0;
t_buf[1].x = WID_BACK / 2;
t_buf[1].y = 0;
t_buf[2].x = WID_BACK / 2 + 1;
t_buf[2].y = 0;
t_buf[3].x = WID_BACK / 2;
t_buf[3].y = 1;
break;
default:
return -1;
}
//for (int i = 0; i < NUM_BLOCK; ++i) {
s.set_point(t_buf);
// }
for (int j = 0; j < NUM_CLOLR; ++j) {
buf_clolr[j] = (i + j) % NUM_CLOLR;
}
//printf("%d %d %d %d\n", buf_clolr[0], buf_clolr[1], buf_clolr[2], buf_clolr[3]);
s.set_clolr(buf_clolr);
return 0;
}
int backplane_c::deal_key(char *buf, int num)
{
int i, ret;
s_save = s;
for (i = 0; i < num; i++) {
//printf("%d\n", buf[i]);
switch(buf[i]) {
case CHAR_A:
case CHAR_LEFT:
s.move_left();
ret = judge_move();
//printf("%s %d %d\n",__FUNCTION__, __LINE__, ret);
if (-1 == ret)
s = s_save;
break;
case CHAR_D:
case CHAR_RIGHT:
s.move_right();
ret = judge_move();
// printf("%s %d %d\n",__FUNCTION__, __LINE__, ret);
if (-1 == ret)
s = s_save;
break;
case CHAR_SPACE:
s.overturn();
ret = judge_move();
//printf("%s %d %d\n",__FUNCTION__, __LINE__, ret);
if (-1 == ret)
s = s_save;
break;
case CHAR_S:
case CHAR_DOWN:
s.move_down();
ret = judge_down();
//printf("%s %d %d\n",__FUNCTION__, __LINE__, ret);
if (0 > ret)
return ret;
else if (1 == ret) {
s = s_save;
cp_box();
deal_score();
init();
}
break;
case CHAR_Q:
return -1;
default:
break;
}
}
if (0 >= num){
s.move_down();
ret = judge_down();
//printf("%s %d %d\n",__FUNCTION__, __LINE__, ret);
//point_t tmp[NUM_BLOCK];
//s.get_point(tmp);
//printf("0 x%d-y%d \n1 x%d-y%d \n2 x%d-y%d \n3 x%d-y%d \n", tmp[0].x, tmp[0].y, tmp[1].x, tmp[1].y, tmp[2].x, tmp[2].y, tmp[3].x, tmp[3].y);
if (0 > ret)
return ret;
else if (1 == ret) {
s = s_save;
cp_box();
deal_score();
init();
}
}
return 0;
}
int backplane_c::paint_box(int y, int x)
{
int i;
int buf_clolr[NUM_CLOLR];
point_t t_buf[NUM_BLOCK];
s.get_point(t_buf);
if (t_buf[0].x == t_buf[1].x && t_buf[0].y == t_buf[1].y)
return -1;
s.get_clolr(buf_clolr);
for(i = 0; i < NUM_BLOCK; i++) {
if (x == t_buf[i].x && y == t_buf[i].y) {
printf_clolr(buf_clolr[i]);
return 0;
}
}
return -1;
}
int backplane_c::paint()
{
int i, j, ret, flg, clolr;
//printf("\033[0;0H\033[K");
MOVETO(0,0);
for(i = 0; i < WID_BACK + 2; i++)
printf(RED STR_FRAME_X NONE);
//printf("\33[0;%dH\33[K-",i);
CLEAR_TAIL();
printf(ENTER);
for(i = 0; i < HIGH_BACK; i++) {
printf(RED STR_FRAME_Y NONE);
for(j=0; j < WID_BACK; j++) {
c_buf[i][j].get_flg(&flg);
c_buf[i][j].get_clolr(&clolr);
if(0 == flg) {
ret = paint_box(i, j);
if (ret)
printf(STR_POINT);
} else
printf_clolr(clolr);
}
if(10 == i)
printf(RED STR_FRAME_Y " 得分: %d" NONE, score);
else if(7 == i)
printf(RED STR_FRAME_Y NONE LIGHT_BLUE" Press 'q' to quit!" NONE);
else
printf(RED STR_FRAME_Y NONE);
CLEAR_TAIL();
printf(ENTER);
}
for(i = 0; i < WID_BACK + 2; i++)
printf(RED STR_FRAME_X NONE);
CLEAR_TAIL();
fflush(stdout);
return 0;
}
int backplane_c::judge_down()
{
int flg;
point_t t_buf[NUM_BLOCK];
s.get_point(t_buf);
for (int i = 0; i < NUM_BLOCK; i++) {
if (HIGH_BACK <= t_buf[i].y) {
return 1;
}
c_buf[t_buf[i].y][t_buf[i].x].get_flg(&flg);
if (1 == flg) {
if (1 == t_buf[i].y)
return -1;
return 1;
}
}
return 0;
}
int backplane_c::judge_move()
{
int flg;
point_t t_buf[NUM_BLOCK];
s.get_point(t_buf);
for (int i = 0; i < NUM_BLOCK; i++) {
if (WID_BACK <= t_buf[i].x || 0 > t_buf[i].x)
return -1;
c_buf[t_buf[i].y][t_buf[i].x].get_flg(&flg);
if (1 == flg)
return -1;
}
return 0;
}
int backplane_c::deal_score()
{
int j, flg, flg_disp, clolr;
for (int i = 0; i < HIGH_BACK; i++) {
flg = 1;
for (j = 0; j < WID_BACK; j++) {
c_buf[i][j].get_flg(&flg_disp);
if (0 == flg_disp) {
flg = 0;
break;
}
}
if (flg) {
score++;
for (j = i; j > 0; j--) {
for (int k = 0; k < WID_BACK; k++) {
c_buf[j - 1][k].get_flg(&flg_disp);
c_buf[j][k].set_flg(flg_disp);
c_buf[j - 1][k].get_clolr(&clolr);
c_buf[j][k].set_clolr(clolr);
}
}
for (int k = 0; k < WID_BACK; k++) {
c_buf[0][k].set_flg(0);
}
}
}
return 0;
}
int backplane_c::cp_box()
{
int buf_clolr[NUM_BLOCK];
point_t t_buf[NUM_BLOCK];
s.get_point(t_buf);
s.get_clolr(buf_clolr);
for (int i = 0; i < NUM_BLOCK; i++) {
c_buf[t_buf[i].y][t_buf[i].x].set_flg(1);
c_buf[t_buf[i].y][t_buf[i].x].set_clolr(buf_clolr[i]);
}
return 0;
}
int backplane_c::printf_clolr(int clolr)
{
switch (clolr) {
case 0:
printf(LIGHT_RED STR_BOX NONE);
break;
case 1:
printf(LIGHT_GREEN STR_BOX NONE);
break;
case 2:
printf(LIGHT_CYAN STR_BOX NONE);
break;
case 3:
printf(LIGHT_PURPLE STR_BOX NONE);
break;
case 4:
printf(YELLOW STR_BOX NONE);
break;
case 5:
printf(BROWN STR_BOX NONE);
break;
case 6:
printf(LIGHT_GRAY STR_BOX NONE);
break;
default:
printf(BLUE STR_BOX NONE);
break;
}
}
//main.cpp
#include <iostream>
#include "backplane.h"
using namespace std;
//#include <string.h>
//#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
//#include <unistd.h>
//#include <sys/types.h>
//#include <stropts.h>
//#include <sys/select.h>
/*"?" "?" "▊" "■" */
static struct termios st_tr_save;
static void termios_init()
{
struct termios tmp;
tcgetattr(STDIN, &st_tr_save);
tmp=st_tr_save;
tmp.c_lflag &= ~ECHO;
tmp.c_lflag &= ~ICANON;
tcsetattr(STDIN, TCSANOW, &tmp);
}
static void termios_recover()
{
tcsetattr(STDIN, TCSANOW, &st_tr_save);
}
static int get_key(char *key, int *num_key)
{
int ret, num, i, cnt = 0;
fd_set fds;
struct timeval tv;
char buf[NUM_MAX_KEY] = {0};
*num_key = 0;
FD_ZERO(&fds);
FD_SET(STDIN, &fds); //文件描述符0表示STDIN键盘输入
tv.tv_sec = 0;
tv.tv_usec = TIME_SLEEP;
ret = select(STDIN + 1, &fds, NULL, NULL, &tv); //第一个参数是监控句柄号+1
if(0 >= ret)
return ret;
if(!FD_ISSET(STDIN, &fds)) //监控输入的确是已经发生了改变
return ret;
num = read(STDIN, buf, NUM_MAX_KEY); //从键盘读取输入
for (i = 0; i < num; i++) { /* a s d 空格 */
if ((CHAR_A == buf[i]) || (CHAR_S == buf[i]) || (CHAR_D == buf[i]) || (CHAR_SPACE == buf[i]) || (CHAR_Q == buf[i]))
key[cnt++] = buf[i];
/*0x1b5b 方向键控制符,thinkpad是 0x5b 0x1b5b41 up(完整键值) 42 down 43 right 44 left*/
else if (0x5b == buf[i]) {
if ((CHAR_DOWN <= buf[i + 1]) && (CHAR_LEFT >= buf[i + 1]))
key[cnt++] = buf[++i];
}
}
*num_key = cnt;
return ret;
}
int main()
{
int ret, num;
char key[NUM_MAX_KEY];
backplane_c back;
fflush(stdout);
//system("clear");
CLEAR();
HIDE_CURSOR();
fflush(stdout);
termios_init();
back.init();
while(1)
{
ret = get_key(key, &num);
if (0 > ret) {
printf("err\n");
break;
}
ret = back.deal_key(key, num);
if (0 > ret) {
printf("game over!\n");
break;
}
// 保存光标貌似无效 printf光标移位好像0和1是一样的
ret = back.paint();
}
termios_recover();
return 0;
}