在论坛发现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("-------------------------------------------------------------------------------\n",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]\t",g_uGameMatrix[y][x]);//加个方括号
                else
                    printf("%d\t",g_uGameMatrix[y][x]);
            }
            else
                fputc('\t',stdout);
        }
        fputc('\n',stdout);
    }
}
//=============================================================================
//ShowHowToPlay:
//将“玩法”显示出来。
//-----------------------------------------------------------------------------
void ShowHowToPlay()
{
    fputs(
        "-------------------------------------------------------------------------------\n"
        "[W]:move up\n"
        "[S]:move down\n"
        "[A]:move left\n"
        "[D]:move right\n"
        "[X]:Exit\n"
        "HOW TO PLAY: Move the tiles. When two tiles with the same number touch, they\n"
        "merge into one!\n",stdout);
}
//=============================================================================
//ShowStatus:
//显示状态
//-----------------------------------------------------------------------------
void ShowStatus()
{
    printf(
        "-------------------------------------------------------------------------------\n"
        "Your score:%d\tHighest score:%d\n",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.\n",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.\n"
                "Your score is %d.\n",g_Score);
            fputs("Try again?[Y/N]\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;
}
