2048简易控制台

//2048.c    a, b, c, d --- move
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>      // for getch()

int a[4][4] = {0}, b[4][4] = {0};
int score = 0;
int steps = 0;

void num_rand();
void display();
void runGame();
void move_up(int [][4], int [][4]);
void move_left(int [][4]);
void move_right(int [][4]);
void move_down(int [][4], int [][4]);
int merge(int *b1, int *b2);
void reverse(int [][4]);
void rotation(int [][4], int [][4]);
void anti_rotation(int [][4], int (*)[4]);
int isfull(int [][4]);
void move();
int endGame();
void copy(int [][4], int [][4]);

int main(void)
{
    srand(time(0));
    num_rand();
    num_rand();
    display();
    runGame();
    return 0;
}

int isfull(int a[][4])
{
    int x, y, con = 0;
    for(y = 0; y < 4; y++)
        for(x = 0; x < 4; x++)
            if(a[y][x] != 0)
                con++;
    if(con == 16)
        return 1;
    return 0;
}

void num_rand()
{
    int x, y;
    while(1){
        x = rand() % 16 / 4;
        y = rand() % 4;
        if(a[y][x] == 0)
            break;
    }
    if(rand() % 8 >= 2)
        a[y][x] = 2;
    else
        a[y][x] = 4;
}

void display()
{
    int i, j, k;
    system("cls");
    printf("Score: %d\tSteps: %d\n", score, steps);
    for(i = 0; i < 5*4+1; i++)
        putchar('-');
    putchar('\n');
    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++){
            putchar('|');
            if(a[i][j] != 0)
                printf("%4d", a[i][j]);
            else
                printf("%4c", 0);
        }
        putchar('|');
        putchar('\n');
        if(i != 4-1){
            for(k = 0; k < 4; k++){
                printf("|----");
            }
            putchar('|');
            putchar('\n');
        }
        else{
            for(k = 0; k < 5*4+1; k++)
                putchar('-');
            putchar('\n');
        }
    }   
}

int endGame()
{
    int c[4][4];
    copy(b, c);     // c is Duplicate of b, b now used for check game over or not
    move_down(b, c);
    move_up(b, c);
    move_left(b);
    move_right(b);
    if(isfull(b) == 1)
        return 1;
    return 0; 
}

void runGame()
{
    while(1){
        move();
        if(isfull(a) != 1)
            num_rand();
        else
            copy(a, b);
        display();
        if(endGame() == 1){
            printf("\n\n Game Over !!!\nPress ESC to quit.");
            while(getch() != 27)    
                ;
            exit(0);
        }
    }
}

void move_up(int a[][4], int b[][4])        // Anticlockwise rotation 90 degrees
{
    rotation(a, b);
    move_right(a);
    anti_rotation(a, b);
}

void move_left(int a[][4])      // reverse
{
    reverse(a);
    move_right(a);
    reverse(a);
}

void move_right(int a[][4])
{
    int x, y, k;
    for(y = 3; y >= 0; y--){        /* shift right , no empty */
        for(x = 3; x >= 0; x--) {
            if(a[y][x] == 0){
                for(k = x-1; k >= 0; k--){
                    if(a[y][k] != 0){
                        a[y][x] = a[y][k];
                        a[y][k] = 0;
                        break;
                    }
                }
            }
        }
        int flag1 = merge(&a[y][2], &a[y][3]);      /* merge if == or have zero */
        if(flag1 == 0){
            if(merge(&a[y][1], &a[y][2]) == 1){
                merge(&a[y][0], &a[y][1]);
            }
            else
                merge(&a[y][0], &a[y][1]);
        }
        else{
            int flag2 = merge(&a[y][0], &a[y][1]);
            if(flag2 == 1)
                merge(&a[y][1], &a[y][2]);
            else{
                merge(&a[y][1], &a[y][2]);
                merge(&a[y][0], &a[y][1]);
            }
        }

   }
}

void move_down(int a[][4], int b[][4])  //  clockwise rotation 90
{
    anti_rotation(a, b);
    move_right(a);
    rotation(a, b);
}

int merge(int *b1, int *b2)
{
    if(*b1 == *b2 || (*b2 == 0 && *b1 != 0)){
        *b2 += *b1;
        *b1 = 0;
        score += *b2;
        return 1;
    }
    return 0;

}

void reverse(int a[][4])        // right to left reverse
{
    int x, y, temp;
    for(y = 0; y < 4; y++){     // reverse
        for(x = 0; x < 4/2; x++){
            temp = a[y][x]; 
            a[y][x] = a[y][3-x];
            a[y][3-x] = temp;
        }
    }
}

void anti_rotation(int a[][4], int b[][4])
{
    int x, y;
    for(y = 0; y < 4; y++){
        for(x = 0; x < 4; x++){
            b[3-x][y] = a[y][x];
        }
    }
    for(y = 0; y < 4; y++)
        for(x = 0; x < 4; x++)
            a[y][x] = b[y][x];
}

void rotation(int a[][4], int b[][4])
{
    int x, y;
    for(y = 0; y < 4; y++){
        for(x = 0; x < 4; x++){
            b[x][3-y] = a[y][x];
        }
    }
    for(y = 0; y < 4; y++)
        for(x = 0; x < 4; x++)
            a[y][x] = b[y][x];
}

void move()
{
    int c = getch();
        switch(c){
            case 'w':
                move_up(a, b);
                steps++;
                break;
            case 'a':
                move_left(a);
                steps++;
                break;
            case 'd':
                move_right(a);
                steps++;
                break;
            case 's':
                move_down(a, b);
                steps++;
                break;
            case 27:    // ESC
                exit(0);
            default:
                move();
        }
}

void copy(int a[][4], int b[][4])   // from a to b
{
    int x, y;
    for(y = 0; y < 4; y++)
        for(x = 0; x < 4; x++)
            b[y][x] = a[y][x];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值