欢迎光临散文网 会员登陆 & 注册

Java 命令行版 2048小游戏(2020年8月14日)

2021-03-21 13:47 作者:阿-岳同学  | 我要投稿

制作背景

大二即将开学,从头开始学习了一个多月的java,对二维数组的操作稍微熟悉了一些。于是想做一个简单的2048来试一试。

众所周知,2048是一个非常经典的游戏,但是我做他的目的主要还是用来练习编程。

效果截图


源代码

import java.util.Random;
import java.util.Scanner;
/**
* 2048小游戏命令行实现
* 2020年8月14日
* by littlefean
*/
public class GameOf2048 {

   public static void main(String[] args) {
       final int TEMP_WIDTH = 5;
       final int TEMP_HEIGHT = 5;
       int[][] temp = new int[TEMP_WIDTH][TEMP_HEIGHT];

       //随机在数组里增加数字,并返回是否满了
       //判断游戏是否出局
       //等待玩家操控
       //执行对应的方法,改变数组的状态
       Scanner sc = new Scanner(System.in);
       while (true){
           String option = sc.next();
           if (option.equals("q")){
               break;
           }
           else{
               switch (option){
                   case "w":
                       moveUp(temp);break;
                   case "s":
                       moveDown(temp);break;
                   case "a":
                       moveLeft(temp);break;
                   case "d":
                       moveRight(temp);break;
               }
               addNum(temp, 1);
               System.out.println("Your Score: "+ normalScore(temp));
               System.out.println("Your level Score: "+ levelScore(temp));
               System.out.print("Danger level:");
               if (isOverAndPrint(temp)){
                   printTemp(temp);
                   System.out.println("Game Over !");
                   break;
               }
               printTemp(temp);
           }
       }
   }

   /**
    * 打印二维数组里的内容
    * @param t 二维数组
    */
   public static void printTemp(int[][] t){
       final char stick = '|';
       final char gang = '-';
       System.out.print(stick + "\t");
       for (int[] ints : t){
           System.out.print(gang);
           System.out.print("\t");
       }
       System.out.print(stick + "\t");
       System.out.println();
       for (int[] ints : t) {
           int i = 0;
           for (int anInt : ints) {
               if(i == 0){
                   System.out.print(stick + "\t");
               }
               if(anInt == 0){
                   System.out.print(" ");
               }else{
                   System.out.print(anInt);
               }
               System.out.print("\t");
               if(i == t[0].length-1){
                   System.out.print(stick + "\t");
               }
               i++;
           }
           System.out.println();
       }
       System.out.print(stick + "\t");
       for (int[] ints : t){
           System.out.print(gang);
           System.out.print("\t");
       }
       System.out.print(stick + "\t");
       System.out.println();
   }

   /**
    * 在数组里添加数字的方法,随机添加 n 个
    * @param t 二维数组
    * @param n 添加的个数
    */
   public static void addNum(int[][] t, int n){
       for(int i = 0; i< n; i++){
           //遍历整个数组,把所有空位置的地方抽取出来放到一个集合里
           for (int y = 0; y < t.length; y++) {
               for (int x = 0; x<t[y].length; x++) {
                   if(t[y][x] == 0){
                       float min = 0, max = 1;
                       float rate = (float) (min + ((max - min) * new Random().nextDouble()));
                       if (rate < 0.2){
                           t[y][x] = 1;
                       }
                   }
               }
           }
       }
   }

   public static void moveDown(int[][] t){
       for (int y = t.length-2; y >= 0; y--) {
           for (int x = 0; x < t[y].length; x++) {
               if (t[y][x] != 0){
                   int thisNum = t[y][x];
                   int thisY = y;
                   while(true){
                       //如果到达了边界
                       if(thisY == t.length-1){
                           break;
                       }
                       //如果下面那个刚好和自己一样
                       if(t[thisY+1][x] == thisNum){
                           t[thisY][x] = 0;
                           t[thisY+1][x] += thisNum;
                           break;
                       }
                       //如果下面那个是空气
                       else if(t[thisY+1][x] == 0){
                           t[thisY+1][x] = t[thisY][x];
                           t[thisY][x] = 0;
                           thisY++;
                       }
                       else{
                           break;
                       }
                   }
               }
           }
       }
   }
   public static void moveUp(int[][] t){
       for (int y = 1; y < t.length; y++) {
           for (int x = 0; x < t[y].length; x++) {
               if (t[y][x] != 0){
                   int thisNum = t[y][x];
                   int thisY = y;
                   while(true){
                       //如果到达了边界
                       if(thisY == 0){
                           break;
                       }
                       //如果上面那个刚好和自己一样
                       if(t[thisY-1][x] == thisNum){
                           // join
                           t[thisY][x] = 0;
                           t[thisY-1][x] += thisNum;
                           break;
                       }
                       //如果下面那个是空气
                       else if(t[thisY-1][x] == 0){
                           t[thisY-1][x] = t[thisY][x];
                           t[thisY][x] = 0;
                           thisY--;
                       }
                       else {
                           break;
                       }
                   }
               }
           }
       }
   }
   public static void moveLeft(int[][] t){
       for (int y = 0; y < t.length; y++) {
           for (int x = 0; x < t[y].length; x++) {
               if (t[y][x] != 0){
                   int thisNum = t[y][x];
                   int thisX = x;
                   while(true){
                       //如果到达了边界
                       if(thisX == 0){
                           break;
                       }
                       //如果左面那个刚好和自己一样
                       if(t[y][thisX-1] == thisNum){
                           // join
                           t[y][thisX] = 0;
                           t[y][thisX-1] += thisNum;
                           break;
                       }
                       //如果面那个是空气
                       else if(t[y][thisX-1] == 0){
                           t[y][thisX-1] = t[y][thisX];
                           t[y][thisX] = 0;
                           thisX--;
                       }
                       else {
                           break;
                       }
                   }
               }
           }
       }
   }
   public static void moveRight(int[][] t){
       for (int y = 0; y < t.length; y++) {
           for (int x = t[y].length-1; x >= 0; x--) {
               if (t[y][x] != 0){
                   int thisNum = t[y][x];
                   int thisX = x;
                   while(true){
                       //如果到达了边界
                       if(thisX == t[y].length-1){
                           break;
                       }
                       //如果右面那个刚好和自己一样
                       if(t[y][thisX+1] == thisNum){
                           // join
                           t[y][thisX] = 0;
                           t[y][thisX+1] += thisNum;
                           break;
                       }
                       //如果下面那个是空气
                       else if(t[y][thisX+1] == 0){
                           t[y][thisX+1] = t[y][thisX];
                           t[y][thisX] = 0;
                           thisX++;
                       }else {
                           break;
                       }
                   }
               }
           }
       }
   }

   /**
    * 计算数组里所有元素的总和作为分数
    * @param t 二维数组
    * @return 分数
    */
   public static int normalScore(int[][] t){
       int sum = 0;
       for (int[] ints : t) {
           for (int anInt : ints) {
               sum += anInt;
           }
       }
       return sum;
   }

   /**
    * 计算最终分数
    * @param t 二维数组
    * @return 最终分数
    */
   public static int levelScore(int[][] t){
       int sum = 0;
       for (int[] ints : t) {
           for (int anInt : ints) {
               if (anInt != 1 && anInt != 0){
                   sum += (anInt * Math.sqrt(anInt));
               }
           }
       }
       return sum;
   }

   /**
    * 判断是否结束并打印危险进度条
    * @param t 二维数组
    * @return 游戏是否结束
    */
   public static boolean isOverAndPrint(int[][] t){
       int zeroNum = 0;
       final int sumPlaceNum = t.length * t[0].length;
       int liveSpaceNum = 5; //允许的最小剩余空间数
       for (int[] ints : t) {
           for (int anInt : ints) {
               if (anInt == 0){
                   zeroNum ++;
               }
           }
       }
       int black = sumPlaceNum - zeroNum;
       int wight = zeroNum - liveSpaceNum;
       if (wight < 0) {
           wight = 0;
       }
       System.out.print("  [");
       for (int i = 0; i < black; i++) {
           System.out.print("!");
       }
       for (int i = 0; i < wight; i++) {
           System.out.print(" ");
       }
       System.out.println("]");
       return zeroNum <= liveSpaceNum;
   }
}

反思与总结

  1. moveUp、moveDown、moveLeft、moveRight,代码非常相似,可以继续想办法简写

  2. 还需要使用面向对象的思想方法来提高程序的可维护性和可扩展性。

  3. 文档注释还写的不够详细

  4. 界面还需要做的更好看一点

代码还需要改进


Java 命令行版 2048小游戏(2020年8月14日)的评论 (共 条)

分享到微博请遵守国家法律