用Java实现的2048(没UI)

本文介绍如何使用Java实现2048游戏的核心算法。通过设计思路和具体步骤,包括用0-3表示方向,判断游戏结束条件,以及二维数组存储游戏状态。在每次事件触发前,元素向指定方向移动并消除空白,接着反向合并相同元素。代码已开源在GitHub,欢迎探讨交流。

设计思路:
用0,1,2,3表示事件向左,右,上,下;然后是判断游戏结束标志:

  1. 游戏出现2048时,赢得游戏而退出;
  2. 游戏画板满了,并且左右上下移动都不能再合并任何元素时,那么游戏已经进入了死胡同不可能再有解,所以判断输了而结束游戏;

游戏实现:
用二维数组来储存游戏画板;
1.每次捕捉事件前,先将每个元素向指定的方向移动,
将他们之间空白的元素去掉,
2.然后按照他们时间的方向的的反方向去没两个相邻的元素比较,如果相同就相加复制给前一个元素,后一个元素置零(表示空白);
3.重复1;

下面是代码,有注释,大家可以看看,欢迎拍砖;
代码工程已发布在https://github.com/BrightenYim/2048inJava
欢迎大家拍砖:

package brighten.demo;
/*
 * @author  BrightenYim 2015.4.12
 * @mailto  brightenyim@qq.com
 */
import java.util.Random;
import java.util.Scanner;

public class Game2048 {

    public final static int  n=4;

    int[][]  array = new int[n][n];

    void  initial(){//初始化这个数组  开始时初始化
    for(int p = 0;p < 4;p++)//默认 0?是否需要初始化
        for(int q =0;q < 4;q++){
            array[p][q]  = 0;
        }
    Random random = new Random();
    int  j  =random.nextInt(4);
    int k  = random.nextInt(4);
    array[j][k] = 2;
    }

    void again(){//合并事件后 随机生成2
        Random random = new Random();
       while(true){
        int   j  = random.nextInt(4);
        int k  = random.nextInt(4);
        if(array[j][k] == 0){
            array[j][k] = 2;break;
        }
        else {
            continue;
        }
       }
    }

    void display(){//显示数组
        for(int i = 0;i < 4;i++)
            for(int j = 0;j < 4 ;j++){
                if(j==3){
                    System.out.println(array[i][j]);
                    }
                else {
                    System.out.printf("%d ",array[i][j]);
                }

                }
            }
    /*void swap(int  i, int  j){//交换           //caution 形参
            int  temp;
            temp  = i;
                    i   = j;
                    j  = temp;
    }*/

    //remov 下面的函数时消去数值间的0数值
    void up_remove_blank(){  //上面的那个为空   交换 靠上集合
        int i,j,k;  
        for(j=0;j<4;j++){  
            for(i=1;i<4;i++){  
                k=i;  
                while(k-1>=0&&array[k-1][j]==0){ 
                  //  swap(array[k][j],array[k-1][j]);  
                    int temp;
                    temp = array[k][j];array[k][j] =array[k-1][j];array[k-1][j] =temp;
                    k--;  

                }  
            }  
        }  
    }  
    void down_remove_blank(){  //下面的那个为空   交换 靠下集合
        int i,j,k;  
        for(j=0;j<4;j++){  
            for(i=2;i>=0;i--){  
                k=i;  
                while(k+1<=3&&array[k+1][j]==0){ 
                    //swap(array[k][j],array[k+1][j]);  
                    int temp;
                    temp=array[k][j];
                    array[k][j] = array[k+1][j];
                    array[k+1][j] = temp;
                    k++;      
                }  
            }  
        }  
    }  
    void left_remove_blank(){  //左面的那个为空   交换 靠左集合
        int i,j,k;  
        for(i=0;i<4;i++){  
            for(j=1;j<4;j++){  
                k=j;  
                while(k-1>=0&&array[i][k-1]==0){
                    //swap(array[i][k],array[i][k-1]);  
                    int temp = array[i][k];
                    array[i][k] =array[i][k-1];
                    array[i][k-1] = temp;
                    k--;  
                }     
            }  
        } 
    }   
    void right_remove_blank(){  //右面的那个为空   交换 靠右集合
        int i,j,k;  
        for(i=0;i<4;i++){  
            for(j=2;j>=0;j--){  
                k=j;  
                while(k+1<=3&&array[i][k+1]==0){  
                  //  swap(array[i][k],array[i][k+1]);  
                    int temp =array[i][k];
                    array[i][k] =array[i][k+1];
                    array[i][k+1] =temp;
                    k++;      
                }     
            }  
        }     
    }  
    //事件 

      void toLeft(){ 
        left_remove_blank();
        int i,j;  
        for(i=0;i<4;i++){  //每一行
            for(j=0;j<3;j++){  
                if(array[i][j]==array[i][j+1]){  
                    array[i][j]+=array[i][j+1];  
                    array[i][j+1]=0; 
                    left_remove_blank();
                }  
            }  
        } 
       // left_remove_blank();  
    }  
      void toRight(){
            right_remove_blank();
            int i,j;  
            for(i=0;i<4;i++){  
                for(j=3;j>=1;j--){  
                    if(array[i][j]==array[i][j-1]){  
                        array[i][j]+=array[i][j-1];  
                        array[i][j-1]=0; 
                        right_remove_blank(); 
                    }  
                }  
            } 
         //   right_remove_blank(); 
        } 
      void  toUp(){
          up_remove_blank();
          int i,j;  
            for(j=0;j<4;j++){//每一列
                for(i=0;i<3;i++){  
                    if(array[i][j]==array[i+1][j]){  
                        array[i][j]=array[i][j]+array[i+1][j];  
                        array[i+1][j]=0;  
                        up_remove_blank();   
                    }  
                }   
            }  
      }
      void toDown(){
          down_remove_blank();
          int i,j;
          for(j=0;j<4;j++){
                for(i=3;i>=1;i--){  
                    if(array[i][j]==array[i-1][j]){  
                        array[i][j]=array[i][j]+array[i-1][j];  
                        array[i-1][j]=0;  
                        down_remove_blank();
                    }
                }
          }
      }


//下面是游戏结束判断 
//Dead如过数组满了 并且 左右都不能合并 那么游戏结束  
//win 如过出先2048 那么赢了游戏
   boolean isFull(){//数组满了
       boolean T =true;
       for(int i =0;i<4;i++)
           for(int j=0;j<4;j++){
               if(array[i][j] == 0){
                   T =false;break;
               }
           }
       return T;
   }

   boolean nearEquals(){//相邻没有相等的
        int i , j;
        boolean T=false;
        for(i =0;i<=2;i++)//上下比 
            for(j=0;j<4;j++){
                if(array[i][j] == array[i+1][j]){
                T=true;break;
                }
            }
        for(i =0;i<4;i++)//左右比  
            for(j=0;j<=2;j++){
                if(array[i][j] == array[i][j+1]){
                T =true;break;
                }
            }
         return T;
     }

 boolean dead(){//如果数组满了&& 相邻没有相等的 那么这个数组已经无法操作 
     boolean T =false;
     if(isFull()==true&&nearEquals()==false){
         T =true;
     }
     return T;
 }

 boolean getWin(){//Judge 是否 赢了

        boolean T =false;
        for(int j =0;j<4;j++)
        for(int k=0;k<4;k++){
            if(array[j][k] == 2048){
                T = true;
            return T;
            }
        }
        return  T;  
    }

    public static void main(String arg[]){

        Game2048 game = new Game2048();
        Scanner  input = new Scanner(System.in);
        game.initial();
        game.display();
        System.out.println("输入数字来表示你想进行的操作:\n"
                + "0表示向左滑动\n"
                + "1表示向右滑动\n"
                + "2表示向上滑动\n"
                + "3表示向下滑动");
        while(true){
            if(game.getWin() == true){//注意和dead的判断顺序
                System.out.println("2048!You Win!");
                input.close();
                break;
                }
            if(game.dead() ==true){
                System.out.println("Game Over!");
                input.close();
                break;
            }
        int  i  =input.nextInt();
        if(i == 0){
        //game.left_remove_blank();
        game.toLeft();
        if(game.isFull() ==false){//fun时不能再加入2  否者会死循环
        game.again();}
        game.display();
        }
        else if(i == 1){
            game.toRight();
            if(game.isFull() ==false){
            game.again();}
            game.display();
            }
        else if(i == 2){
            game.toUp();
            if(game.isFull() ==false){
            game.again();}
            game.display();
            }
        else if(i ==3){
                game.toDown();
                if(game.isFull() ==false){
                game.again();}
                game.display();
                }
        else{
            System.out.println("请输入0-3的数字来表示方向,重新输入吧-_-");
            continue ;
            }
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值