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;
            }

        }
    }

}


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