某大神网站发现2048一枚

在论坛发现2048的C语言的源代码。

真心佩服大神的创作。

复制一起学习。

//=============================================================================

//Console2048:

//C语言写的一个手机游戏2048的控制台版。

//作者:0xAA55

//QQ:838816058

//论坛:www.技术宅的结界.com

//2048原版作者:

//Gabriele Cirulli

//2048原版网址:

//http://gabrielecirulli.GitHub.io/2048/

//=============================================================================

#include<time.h>//time

#include<stdio.h>//printf,fputc,fputs

#include<conio.h>//getch

#include<stdlib.h>//rand,srand

#include<signal.h>//sigint



typedef unsigned int    UINT;//存储矩阵的数字的变量类型



#define MATRIX_LINES    4   /*矩阵的行数*/

#define MATRIX_ROWS     4   /*矩阵的列数*/



#define NEW_BASE        2   /*添加的新数字的最小值*/

#define NEW_RANGE       2   /*添加的新数字的范围*/



int     g_Quit=0;           //是否退出

size_t  g_Score=0;          //分数

size_t  g_HighestScore=0;   //最高分数



UINT    g_uGameMatrix[MATRIX_LINES][MATRIX_ROWS]={0};//“矩阵”

size_t  g_NewX,g_NewY;//最新添加的数字的位置



//=============================================================================

//ShowMatrix:

//将“矩阵”显示出来。

//-----------------------------------------------------------------------------

void ShowMatrix()

{

    size_t x,y;

    fputs("-------------------------------------------------------------------------------
",stdout);

    for(y=0;y<MATRIX_LINES;y++)

    {

        for(x=0;x<MATRIX_ROWS;x++)

        {

            if(g_uGameMatrix[y][x])

            {

                if(x==g_NewX&&y==g_NewY)//如果这个数是新添加的

                    printf("[%d]	",g_uGameMatrix[y][x]);//加个方括号

                else

                    printf("%d	",g_uGameMatrix[y][x]);

            }

            else

                fputc('	',stdout);

        }

        fputc('
',stdout);

    }

}

//=============================================================================

//ShowHowToPlay:

//将“玩法”显示出来。

//-----------------------------------------------------------------------------

void ShowHowToPlay()

{

    fputs(

        "-------------------------------------------------------------------------------
"

        "[W]:move up
"

        "[S]:move down
"

        "[A]:move left
"

        "[D]:move right
"

        "[X]:Exit
"

        "HOW TO PLAY: Move the tiles. When two tiles with the same number touch, they
"

        "merge into one!
",stdout);

}

//=============================================================================

//ShowStatus:

//显示状态

//-----------------------------------------------------------------------------

void ShowStatus()

{

    printf(

        "-------------------------------------------------------------------------------
"

        "Your score:%d	Highest score:%d
",g_Score,g_HighestScore);

}



//=============================================================================

//MoveUp:

//全部数字往上移,但是不合并

//-----------------------------------------------------------------------------

int MoveUp()

{

    size_t x,y;

    unsigned Moves;

    int Moved=0;

    do

    {

        Moves=0;

        for(y=1;y<MATRIX_LINES;y++)

        {

            for(x=0;x<MATRIX_ROWS;x++)

            {

                UINT*pUpper=&g_uGameMatrix[y-1][x];

                if(g_uGameMatrix[y][x]&&!*pUpper)

                {

                    *pUpper=g_uGameMatrix[y][x];

                    g_uGameMatrix[y][x]=0;

                    Moves++;

                    Moved=1;

                    continue;

                }

            }

        }

    }while(Moves);

    return Moved;

}



//=============================================================================

//CombineUp:

//全部数字往上合并

//-----------------------------------------------------------------------------

int CombineUp()

{

    int Moved=0;

    size_t x,y;

    for(y=1;y<MATRIX_LINES;y++)

    {

        for(x=0;x<MATRIX_ROWS;x++)

        {

            UINT*pUpper=&g_uGameMatrix[y-1][x];

            if(g_uGameMatrix[y][x]&&g_uGameMatrix[y][x]==*pUpper)

            {

                g_Score+=*pUpper<<=1;//累加到总分

                g_uGameMatrix[y][x]=0;

                Moved=1;

                continue;

            }

        }

    }

    return Moved;

}



//=============================================================================

//MoveDown:

//全部数字往下移

//-----------------------------------------------------------------------------

int MoveDown()

{

    size_t x,y;

    unsigned Moves;

    int Moved=0;

    do

    {

        Moves=0;

        for(y=MATRIX_LINES-1;y--;)

        {

            for(x=0;x<MATRIX_ROWS;x++)

            {

                UINT*pLower=&g_uGameMatrix[y+1][x];

                if(g_uGameMatrix[y][x]&&!*pLower)

                {

                    *pLower=g_uGameMatrix[y][x];

                    g_uGameMatrix[y][x]=0;

                    Moves++;

                    Moved=1;

                    continue;

                }

            }

        }

    }while(Moves);

    return Moved;

}



//=============================================================================

//CombineDown:

//全部数字往下合并

//-----------------------------------------------------------------------------

int CombineDown()

{

    int Moved=0;

    size_t x,y;

    for(y=MATRIX_LINES-1;y--;)

    {

        for(x=0;x<MATRIX_ROWS;x++)

        {

            UINT*pLower=&g_uGameMatrix[y+1][x];

            if(g_uGameMatrix[y][x]&&g_uGameMatrix[y][x]==*pLower)

            {

                g_Score+=*pLower<<=1;//累加到总分

                g_uGameMatrix[y][x]=0;

                Moved=1;

                continue;

            }

        }

    }

    return Moved;

}



//=============================================================================

//MoveLeft:

//全部数字往左移

//-----------------------------------------------------------------------------

int MoveLeft()

{

    size_t x,y;

    unsigned Moves;

    int Moved=0;

    do

    {

        Moves=0;

        for(x=1;x<MATRIX_ROWS;x++)

        {

            for(y=0;y<MATRIX_LINES;y++)

            {

                UINT*pLeft=&g_uGameMatrix[y][x-1];

                if(g_uGameMatrix[y][x]&&!*pLeft)

                {

                    *pLeft=g_uGameMatrix[y][x];

                    g_uGameMatrix[y][x]=0;

                    Moves++;

                    Moved=1;

                    continue;

                }

            }

        }

    }while(Moves);

    return Moved;

}



//=============================================================================

//CombineLeft:

//全部数字往左合并

//-----------------------------------------------------------------------------

int CombineLeft()

{

    int Moved=0;

    size_t x,y;

    for(x=1;x<MATRIX_ROWS;x++)

    {

        for(y=0;y<MATRIX_LINES;y++)

        {

            UINT*pLeft=&g_uGameMatrix[y][x-1];

            if(g_uGameMatrix[y][x]&&g_uGameMatrix[y][x]==*pLeft)

            {

                g_Score+=*pLeft<<=1;//累加到总分

                g_uGameMatrix[y][x]=0;

                Moved=1;

                continue;

            }

        }

    }

    return Moved;

}



//=============================================================================

//MoveRight:

//全部数字往右移

//-----------------------------------------------------------------------------

int MoveRight()

{

    size_t x,y;

    unsigned Moves;

    int Moved=0;

    do

    {

        Moves=0;

        for(x=MATRIX_ROWS-1;x--;)

        {

            for(y=0;y<MATRIX_LINES;y++)

            {

                UINT*pRight=&g_uGameMatrix[y][x+1];

                if(g_uGameMatrix[y][x]&&!*pRight)

                {

                    *pRight=g_uGameMatrix[y][x];

                    g_uGameMatrix[y][x]=0;

                    Moves++;

                    Moved=1;

                    continue;

                }

            }

        }

    }while(Moves);

    return Moved;

}



//=============================================================================

//CombineRight:

//全部数字往右合并

//-----------------------------------------------------------------------------

int CombineRight()

{

    int Moved=0;

    size_t x,y;

    for(x=MATRIX_ROWS-1;x--;)

    {

        for(y=0;y<MATRIX_LINES;y++)

        {

            UINT*pRight=&g_uGameMatrix[y][x+1];

            if(g_uGameMatrix[y][x]&&g_uGameMatrix[y][x]==*pRight)

            {

                g_Score+=*pRight<<=1;//累加到总分

                g_uGameMatrix[y][x]=0;

                Moved=1;

                continue;

            }

        }

    }

    return Moved;

}



//=============================================================================

//GetZeroCount:

//取得零的数量

//-----------------------------------------------------------------------------

size_t GetZeroCount()

{

    size_t x,y,count=0;

    for(y=0;y<MATRIX_LINES;y++)

    {

        for(x=0;x<MATRIX_ROWS;x++)

        {

            if(!g_uGameMatrix[y][x])

                count++;

        }

    }

    return count;

}



//=============================================================================

//AddNum:

//随机找到零然后改成随机的数字,返回非零成功。

//-----------------------------------------------------------------------------

int AddNum(UINT iNum)

{

    size_t ZeroCount=GetZeroCount();//取得零的数量

    if(ZeroCount)

    {

        size_t PosAdd=rand()%ZeroCount;//添加的位置(在第X个零处添加)

        size_t x,y;

        for(y=0;y<MATRIX_LINES;y++)

        {

            for(x=0;x<MATRIX_ROWS;x++)

            {

                if(!g_uGameMatrix[y][x])//找到零

                {

                    if(!PosAdd)//计数已到

                    {

                        g_uGameMatrix[y][x]=iNum?iNum:NEW_BASE<<(rand()%NEW_RANGE);//添加新数字

                        g_NewX=x;

                        g_NewY=y;

                        return ZeroCount;

                    }

                    PosAdd--;//否则计数还没到。

                }

            }

        }

    }

    return 0;

}



//=============================================================================

//GetBiggest:

//取得最大的数字

//-----------------------------------------------------------------------------

UINT GetBiggest()

{

    size_t x,y;

    UINT uBiggest=0;

    for(y=0;y<MATRIX_LINES;y++)

    {

        for(x=0;x<MATRIX_ROWS;x++)

        {

            if(g_uGameMatrix[y][x]>uBiggest)

                uBiggest=g_uGameMatrix[y][x];

        }

    }

    return uBiggest;

}



//=============================================================================

//NewGame:

//重置为一场新的游戏

//-----------------------------------------------------------------------------

void NewGame()

{

    size_t x,y,count=0;

    for(y=0;y<MATRIX_LINES;y++)

    {

        for(x=0;x<MATRIX_ROWS;x++)

            g_uGameMatrix[y][x]=0;

    }

    AddNum(0);

    AddNum(0);

    g_Score=0;

}



//=============================================================================

//GameOver:

//判断游戏是否结束,返回1表示游戏结束

//-----------------------------------------------------------------------------

int GameOver()

{

    size_t x,y;

    if(GetZeroCount())//还有空位,没有结束

        return 0;

    for(y=0;y<MATRIX_LINES;y++)

    {

        for(x=1;x<MATRIX_ROWS;x++)

        {

            if(g_uGameMatrix[y][x]==g_uGameMatrix[y][x-1])

                return 0;//横向有相等的

        }

    }

    for(y=1;y<MATRIX_LINES;y++)

    {

        for(x=0;x<MATRIX_ROWS;x++)

        {

            if(g_uGameMatrix[y][x]==g_uGameMatrix[y-1][x])

                return 0;//纵向有相等的

        }

    }

    return 1;

}



//=============================================================================

//SigProc:

//信号处理程序

//-----------------------------------------------------------------------------

void SigProc(int iSig)

{

    switch(iSig)

    {

    case SIGINT:

        fputs("Ctrl+C catched.
",stdout);

        g_Quit=1;

        break;

    }

}



int main(int argc,char**argv)

{

    signal(SIGINT,SigProc);

    srand((unsigned)time(NULL));//先初始化随机数种子,以免每次玩游戏效果都一样。

    NewGame();

    do

    {

        int Moved=0;

        if(g_Score>g_HighestScore)

            g_HighestScore=g_Score;

        ShowStatus();

        ShowMatrix();

        ShowHowToPlay();

        switch(getch())

        {

        case 'w':

        case 'W':

            Moved =MoveUp();

            Moved|=CombineUp();

            Moved|=MoveUp();

            break;

        case 's':

        case 'S':

            Moved =MoveDown();

            Moved|=CombineDown();

            Moved|=MoveDown();

            break;

        case 'a':

        case 'A':

            Moved =MoveLeft();

            Moved|=CombineLeft();

            Moved|=MoveLeft();

            break;

        case 'd':

        case 'D':

            Moved =MoveRight();

            Moved|=CombineRight();

            Moved|=MoveRight();

            break;

        case 'x':

        case 'X':

        case 3://getch的时候按下Ctrl+C

            raise(SIGINT);

            break;

        }

        if(Moved)AddNum(0);//至少要动了才能添加新的数字

        if(GameOver())

        {

            if(g_Score>g_HighestScore)

                g_HighestScore=g_Score;

            ShowStatus();

            ShowMatrix();

            printf(

                "Game over.
"

                "Your score is %d.
",g_Score);

            fputs("Try again?[Y/N]
",stdout);

AskRetry:   switch(getch())

            {

            case 'y':

            case 'Y':

                NewGame();

                break;

            case 'n':

            case 'N':

            case 3://getch的时候按下Ctrl+C

                raise(SIGINT);

                g_Quit=1;

                break;

            default:

                goto AskRetry;

            }

        }

    }while(!g_Quit);

    return 0;

}



转自:http://www.0xaa55.com/thread-599-1-1.html

@ Mayuko 

原文地址:https://www.cnblogs.com/mayuko/p/4567671.html