俄罗斯方块

Centos6.5
C语言
需要用到VT100控制码编程
实现基本的功能,旋转,移动,满行消除等功能。

/*************************************************************************
    > File Name: 9.c
    > Author: Yangkun   
    > Mail: yangkungetit@163.com
    > Created Time: Mon 02 Oct 2017 08:32:10 AM PDT
 ************************************************************************/
#include<string.h>
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>
#include"/home/yangkun/keyboard/keyboard/keyboard.h"

#define H 20
#define W 10
#define BC 0
#define FC 5

int background_arr[H][W] = {};

int cur;
int next;
typedef struct mode
{
    int s[5][5];
}mode;

struct pos
{
    int x;
    int y;
};
struct pos t = {.x=5,.y=0};


void element(int x,int y,char c)
{
    x++;
    y++;
    x*=2;
    printf("\033[%d;%dH\033[3%dm\033[4%dm[]",y,x,c,c);
    printf("\033[?25l\033[0m");
    fflush(stdout);
}

void background()
{
    int i,j;
    for(i=0;i<H;i++)
    {
        for(j=0;j<W;j++)
        {
            if(background_arr[i][j] == 0)
                element(j,i,BC);
            else
                element(j,i,FC);
        }
    }
}

mode mode_arr[7]=
{
    {
        0,0,0,0,0,
        0,0,1,0,0,
        0,0,1,0,0,
        0,0,1,0,0,
        0,0,1,0,0
    },
    {
        0,0,0,0,0,
        0,1,1,0,0,
        0,1,1,0,0,
        0,0,0,0,0,
        0,0,0,0,0
    },
    {
        0,0,0,0,0,
        0,0,1,1,0,
        0,1,1,0,0,
        0,0,0,0,0,
        0,0,0,0,0
    },
    {
        0,0,0,0,0,
        0,0,1,0,0,
        0,0,1,0,0,
        0,1,1,0,0,
        0,0,0,0,0
    },
    {
        0,0,0,0,0,
        0,0,1,0,0,
        0,0,1,0,0,
        0,0,1,1,0,
        0,0,0,0,0
    },
    {
        0,0,0,0,0,
        0,0,1,0,0,
        0,1,1,1,0,
        0,0,0,0,0,
        0,0,0,0,0
    },
    {
        0,0,0,0,0,
        0,0,1,0,0,
        0,0,1,0,0,
        0,0,1,1,0,
        0,0,0,0,0
    },
};

void draw(int x,int y,mode m,char c)
{
    int i,j;
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            if(m.s[i][j]==1)
            {
                element(x+j,y+i,c);
            }
        }
    }
}

int move(int x,int y,mode p)
{
    int i,j;
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            if(p.s[i][j]==0)
                continue;
            if(x+j>=W)
                return 0;
            if(y+i>=H)
                return 0;
            if(x+j<0)
                return 0;
            if(background_arr[y+i][x+j]!=0)
                return 0;
        }
    }
    return 1;
}

void setbackground(struct pos* t)
{
    int i,j;
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            if(mode_arr[cur].s[i][j] != 0)
            {
                background_arr[t->y+i][t->x+j] = 1;
            }
        }
    }
}

void nextpitc()
{
    int i,j;
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            if(mode_arr[next].s[i][j]==0)
            {
                element(W+j+2,2+i,BC);
            }
            else
            {
                element(W+j+2,2+i,FC);
            }
        }
    }
}

void fullline()
{
    int i;
    for(i=0;i<W;i++)
    {
        if(background_arr[1][i]!=0)
        {
            printf("Game Over!!!\n");
            recover_keyboard();
            exit(0);
        }
    }
}

void clean_line()
{
    int i,j;
    int k;
    for(i=0;i<H;i++)
    {
        k=0;
        for(j=0;j<W;j++)
        {
            if(background_arr[i][j] != 0)
                k++;
        }
        if(k==W)
        {
            int t;
            for(t=i;t>0;t--)
            {
                memcpy(background_arr[t],background_arr[t-1],sizeof(background_arr[t]));
            }
            memset(background_arr[0],0x00,sizeof(background_arr[0]));
        }
    }
    fullline();
}

void count_time( struct pos* t )
{
    draw(t->x,t->y,mode_arr[cur],BC);
    if(move(t->x,t->y+1,mode_arr[cur]))
    {
        t->y++;
        draw(t->x,t->y,mode_arr[cur],FC);
    }
    else
    {
        setbackground(t);
        clean_line();
        background();
        cur=next;
        next=rand()%7;
        nextpitc();
        t->y=0;
        t->x=0;
    }
}

void handler(int x)
{
    count_time(&t);
}

mode turn_90(mode m)
{
    int i,j;
    mode tmp;
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            tmp.s[i][j]=m.s[4-j][i];
        }
    }
    return tmp;
}


void tetirs(struct pos* t)
{
    int c;
    c=get_key();
    if(is_up(c))
    {
        draw(t->x,t->y,mode_arr[cur],BC);
        mode_arr[cur] = turn_90(mode_arr[cur]);
        if(move(t->x,t->y,mode_arr[cur])==0)
        {
            mode_arr[cur] = turn_90(mode_arr[cur]);
            mode_arr[cur] = turn_90(mode_arr[cur]);
            mode_arr[cur] = turn_90(mode_arr[cur]);
        }
    }
    else if(is_down(c))
    {
        draw(t->x,t->y,mode_arr[cur],BC);
        if(move(t->x,t->y+1,mode_arr[cur]))
        {
            t->y++;
            draw(t->x,t->y,mode_arr[cur],FC);
        }
    }
    else if(is_left(c))
    {
        draw(t->x,t->y,mode_arr[cur],BC);
        if(move(t->x-1,t->y,mode_arr[cur]))
        {
            t->x--;
            draw(t->x,t->y,mode_arr[cur],FC);
        }
    }
    else if(is_right(c))
    {
        draw(t->x,t->y,mode_arr[cur],BC);
        if(move(t->x+1,t->y,mode_arr[cur]))
        {
            t->x++;
            draw(t->x,t->y,mode_arr[cur],FC);
        }  
    }
}

int main(void)
{
    background();
    struct itimerval it;
    it.it_value.tv_sec = 0;
    it.it_value.tv_usec = 1;
    it.it_interval.tv_sec = 0;
    it.it_interval.tv_usec =300000;


    srand(time(NULL));
    next=rand()%7;
    cur=rand()%7;

    signal(SIGALRM, handler);
    setitimer(ITIMER_REAL,&it,NULL);

    init_keyboard();
    while( 1 )
    {
        tetirs(&t);
        clean_line();
    }
    recover_keyboard();

}

keyboard.c

#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>

struct termios tcsave;
int flsave;

#define UP    0x415b1b
#define DOWN  0x425b1b
#define LEFT  0x445b1b
#define RIGHT 0x435b1b
#define ENTER 0xa
#define ESC   0x1b
#define SPACE 0x20

int init_keyboard(void)
{
    int ret;
    struct termios tc;
    ret = tcgetattr(0, &tcsave);
    if(ret < 0)
        return -1;
    tc = tcsave;
    tc.c_lflag &= ~(ECHO|ICANON);
    ret = tcsetattr(0, TCSANOW, &tc);
    if(ret < 0)
        return -1;
    flsave = fcntl(0, F_GETFL);
    fcntl(0, F_SETFL, flsave|O_NONBLOCK);
    return 0;
}
void recover_keyboard(void)
{
    tcsetattr(0, TCSANOW, &tcsave);
    fcntl(0, F_SETFL, flsave);
}
int get_key(void)
{   
    unsigned char buf[3];
    int ret, i, key, r;
    ret = read(0, buf, sizeof(buf));
    if(ret < 0)
        return -1;
    //*
    if(ret == 1 || ret == 2){
        r = read(0, &buf[ret], sizeof(buf)-ret);
        if(r > 0)
            return -1;
        r = read(0, &buf[ret], sizeof(buf)-ret);
        if(r > 0)
            return -1;
        r = read(0, &buf[ret], sizeof(buf)-ret);
        if(r > 0)
            return -1;
        r = read(0, &buf[ret], sizeof(buf)-ret);
        if(r > 0)
            return -1;
    }
    //*/
    //printf("ret = %d r = %d key=[%d]\n", ret, buf[0]);
    key = 0;
    for(i=0; i<ret; i++){
        key += (buf[i]<<(i*8));
    }
    return key;
}
int is_up(int key)
{   
    return key == UP;
}
int is_down(int key)
{   
    return key == DOWN;
}
int is_left(int key)
{   
    return key == LEFT;
}
int is_right(int key)
{   
    return key == RIGHT;
}
int is_enter(int key)   
{
    return key == ENTER;
}
int is_esc(int key)
{   
    return key == ESC;
}
int is_space(int key)
{
    return key == SPACE;
}
#if 0
int main(void)
{
    int key, ret;
    ret = init_keyboard();
    if(ret < 0)
        return -1;
    while(1){
        key = get_key();
        if(key < 0)
            continue;   
        //printf("key = %x\n", key);
        if(is_left(key))
            printf("left\n");
        if(is_right(key))
            printf("right\n");
        if(is_up(key))
            printf("up\n");
        if(is_down(key))
            printf("down\n");
        if(is_enter(key))
            printf("enter\n");
        if(is_space(key))
            printf("space\n");
        if(is_esc(key)){
            printf("esc\n");
            break;
        }

        //if(key == 'q')
        //  break;
    }   
    recover_keyboard();
    return 0;
}
#endif

keyboard.h

#ifndef KEYBOARD_H
#define KEYBOARD_H
int init_keyboard(void);
void recover_keyboard(void);
int get_key(void);
int is_up(int key);
int is_down(int key);
int is_left(int key);
int is_right(int key);
int is_enter(int key);  
int is_esc(int key);
int is_space(int key);
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值