2048游戏

#include "stdio.h"
#include "windows.h"
#include "conio.h"
#include "stdlib.h"

#define MAX 10
int box[MAX][MAX];

/*     http://black4yl.blog.51cto.com
      Black4yL: 2015年1月4日
         /---2 0 4 8 游戏---\  (纯属练 数组 , 方向感, 测试是否瞌睡,以及 高数,大物,相对运动...)
        以 left为例说明原理:
        
          0x01: 进入left函数
          0x02:  
                left(),(1)首先是moveleft操作,也即将所有数字左移
                       (2)然后是megerleft操作,也即左移后的同数字合并
                           合并完了,还必须执行一次移动,因为可能会有中间空隙. 
                           比如 2 4  4 8 移动后是 2 8 空 8,需要再次移动变为 2 8 8 空
                       (3)最后就是返回一个 bool 型 ret值,表示当前数字是否发生变化,变化了需要
                          检查是否满了? 变化了还需要 随机生成一个数字,继续游戏~
          0x03:    详解
                    mov 操作
                     for( )
                       for( )
                        {
                            (1)找空闲列
                            (2)前移
                            (3)修改移动的位置为 空 (-1)
                        }
                     meger操作
                        遍历数组,left情况 则 以行优先,列值由0 -> n-1
                                  up情况  则 以列优先,行值由0 -> n-1
                                  其他 同理。
                             寻找前后是否有相同值,有则 消除后面的,前面的数字X2 
*/


bool megerleft(int n)                        //left 合并
{
    bool ret = false;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(box[i][j] == -1) continue;
            
            if(box[i][j] == box[i][j+1])
            {
                box[i][j] *= 2;
                box[i][j+1] = -1;
                ret = true;
                j++;
            }
        }
    }
    return ret;
}

bool movleft(int n)
{
    bool ret = false;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            int k;
            for(k=j-1;k>=0;k--)                    //找到第i行 j列前面第一个不是空的位置
            {
                if( box[i][k] != -1) break;
            }
            box[i][k+1] = box[i][j];            //插到它的前一个(这个不为空,前一个肯定是空)

            if( k+1 != j)                                //如果发生移动,也就是 k != j-1 ,也就是 k+1 ! = j
            {
                box[i][j] = -1;                    //移动了 ,填充为空
                ret = true;                        //发生变化
            }
        }
    }
    return ret;
}


bool left(int n)
{
    bool ret = false;
    ret = movleft(n);
    ret = megerleft(n);
    ret = movleft(n);
    return ret;
}

bool megerright(int n)
{
    bool ret = false;
    for(int i=0;i<n;i++)
        for(int j=n-1;j>=0;j--)
        {
            if( box[i][j] == -1) continue;
            if( box[i][j] == box[i][j-1])
            {
                    box[i][j] *= 2;
                    box[i][j-1] = -1;
                    ret = true;
                    j-- ;
            }

        }
    return ret;
}

bool movright(int n)
{
        bool ret = false;
    for(int i=0;i<n;i++)
        for(int j=n-1;j>=0;j--)
        {
            int k;
            for(k=j+1;k<n;k++)
            {
                if(box[i][k]!=-1)
                    break;
            }
            box[i][k-1] = box[i][j];
            if( k-1 != j)
            {
                box[i][j] = -1;
                ret = true;
            }

        }
return ret;
}

bool right(int n)
{
    bool ret = false;
    ret = movright(n);
    ret = megerright(n);
    ret = movright(n);
    return ret;
}

bool megerup(int n)
{
        bool ret = false;
        for( int i=0 ;i <n;i++)        //    此时为列
            for(int j=0 ; j<n;j++)        //    此时为行
            {
                if( box[j][i] == -1) continue;
                
                if( box[j][i] == box[j+1][i] )
                {
                    box[j][i] *= 2;
                    box[j+1][i] = -1;
                    ret = true;
                    j++;
                }
                
            }

    return ret;
}
bool movup(int n)
{    
    bool ret = false;
    for( int i=0 ;i <n;i++)        //    此时为列
        
        for(int j=0 ; j<n;j++)        //    此时为行
        {
            int k ;
            for( k =j -1 ; k>=0 ; k--)    //行变化
            {
                if( box[k][i] != -1) break;
            }
            box[k+1][i] = box[j][i];

            if(k+1 != j)
            {
                box[j][i] = -1;
                ret = true;
            }
            
        }

    return ret;
}
bool up(int n)
{
        bool ret = false;
        ret = movup(n);
        ret = megerup(n);
        ret = movup(n);
        return ret;
}

bool megerdown(int n)
{
    bool ret = false;
    for( int i = 0; i<n;i++)        //列
        for( int j = n-1; j >=0; j--)    //行
        {
            if( box[j][i] == -1) continue;
            if( box[j][i] == box[j-1][i])
            {
                box[j][i] *= 2;
                box[j-1][i] = -1;
                j--;
                ret = true;

            }
        }
    return ret;
}

bool movdown(int n)
{
    bool ret = false;
    for( int i = 0; i<n;i++)        //列
        for( int j = n-1;j>=0;j--)    //行
        {
            int k;
            for(k = j+1;k<n;k++)
            {
                if( box[k][i] != -1)
                    break;
            }

            box[k-1][i] = box[j][i];

            if( k-1 != j)
            {
                box[j][i] = -1;
                ret = true;
            }
        }
    return ret;
}

bool down(int n)
{
    bool ret = false;
    ret = movdown(n);
    ret = megerdown(n);
    ret = movdown(n);
    return ret;
}

void line(int n)
{
    for (int i = 0; i < n; ++i)
    {
        printf("--------");
    }
    printf("-");
    printf("\n");
}

void print(int n)
{
    
    for(int i=0;i<n;i++)
    {
        line(n);
        for(int j=0 ; j<n ; j++)
        {
            printf("|");
            if( box[i][j] == -1)
            {
                printf("\t");
                
            }
            else
                printf("%2d\t", box[i][j]);
        }
        printf("|");
        printf("\n");
    }
    line(n);
}

bool isfull(int n)        //是否    满
{
    bool ret = true;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            if( box[i][j] == -1)
            {    
                ret = false;
                return ret;
            }
            
        }
        return ret;        //满
}

bool isOver(int n)            //是否 结束游戏
{
    if( !isfull(n))    
        return false;
    for(int i=0;i<n;i++)
        for( int j=0;j<n;j++)
        {
            if( box[i][j] == box[i][j+1] || box[i][j] == box[i+1][j])    //有相同的
                return false;
        }
        return true;
}

void fillbox(int n)        //随机填充
{
    int i,j,num;
    if( isfull(n))    //格子满
        return ;
    while(1)
    {
        i = rand() % n;
        j = rand() % n;
        num = rand() % 2 ? 2 : 4;
        if(box[i][j] == -1)
        {
            box[i][j] = num;
            break;
        }
    }
}

void main()
{
    char ch;
    int n = 9;
    memset(box,-1,sizeof(box));
    bool mak = false ;
    fillbox(n);
    while(1)
    {    
        system("CLS");
        print(n);
        ch = getch();
        switch(ch)
        {
        case 'a': 
            mak = left(n);
            break;
        case 'd':
            mak = right(n);
            break;
        case 'w':
             mak = up(n);
             break;
        case 's':
             mak = down(n);
             break;
        default:
                continue;
        }
        if(mak)        //有变化
        {
            fillbox(n);
            if(isOver(n))
            {
                system("CLS");
                printf("Game oVer!\n");
                break;
            }

        }
    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章