简体   繁体   English

用随机列表中的 2 个值填充 2D 数组(2048 游戏)

[英]Filling 2D Array with 2 values from a random list (2048 Game)

I am trying to recreate the 2048 game and I have hit a brick wall and am stumped.我正在尝试重新创建 2048 游戏,但我撞到了一堵砖墙并被难住了。 I have made my grid with a 2d array and it seems to be working okay.我用二维数组制作了我的网格,它似乎工作正常。 I have then made a method to store an list of empty/free space in this grid/array so that the two starting numbers can be assigned to two random free spaces.然后我做了一个方法来在这个网格/数组中存储一个空/可用空间列表,以便可以将两个起始数字分配给两个随机的可用空间。 My problem is that I cannot get the numbers to show inside the actual grid.我的问题是我无法在实际网格中显示数字。 I have my code below and would appreciate if anybody could show me where i am going wrong.我在下面有我的代码,如果有人能告诉我我哪里出错了,我将不胜感激。 Apologies if I explained this horribly, I am still quite new to Java.抱歉,如果我对此进行了可怕的解释,我对 Java 还是很陌生。

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class Main {
    //Game Board Size Method - Getting User Number to use for dimension of game board
    public static int gameBoardSize() {
        int number = 0;
        int row = 0;
        Scanner in = new Scanner(System.in);
        System.out.println("Welcome to 1024");
        System.out.print("Please select a number between 4 & 8 to determine the size of your game board: "); //Prompt user to select number
        number = in.nextInt(); //Storing number in variable
        if (number >= 4 && number <= 8) { //If number is >= 4 and <= 8
            row = number; //Assign number to row variable
        } else {
            System.out.print("Error, please select a number between 4 & 8"); //Error print message
        }
        return row; //Return
    }

    //Display Game board method - Array for game board grid and to display the grid.
    public static void displayGameBoard(int[][] gameBoard, int gameBoardSize) {
        String divider;
        switch (gameBoardSize) {
            case 5:
                divider = "\n+-----+-----+-----+-----+-----+"; //User Number 5
                break;
            case 6:
                divider = "\n+-----+-----+-----+-----+-----+-----+"; //User Number 6
                break;
            case 7:
                divider = "\n+-----+-----+-----+-----+-----+-----+-----+"; //User Number 7
                break;
            case 8:
                divider = "\n+-----+-----+-----+-----+-----+-----+-----+-----+"; //User Number 8
                break;
            default:
                divider = "\n+----+-----+-----+----+"; //User Number 4
        }
        System.out.println(divider); //Printing Divider at top
        for (int i = 0; i < gameBoard.length; i++) {
            for (int j = 0; j < gameBoard[i].length; j++) {
                if (gameBoard[i][j] == 0) { //If both i & j is == 0
                    System.out.print("|     "); //Print this left border
                }
                if (j == gameBoard[j].length - 1) { //If 2nd array length -1 (end)
                    System.out.print("|"); //Print end border
                }
            }

            System.out.println(divider); //Printing Divider at bottom
        }
    }



    public static int[][] createGameBoard(int userRows) {
        return new int[userRows][userRows]; //Returning rows
    }


    //Method to loop through array to find empty space
    public static int[][] findEmptyCells(int[][] gameBoard)  {
        int freeCellCount = 0;
        int[][] emptyList = new int[gameBoard.length * gameBoard.length][2];
        for (int i = 0; i < gameBoard.length; i++) {
            for (int j = 0; j < gameBoard[i].length; j++) {
                if (gameBoard[i][j] == 0) {
                    emptyList[freeCellCount][0] = i;
                    emptyList[freeCellCount][1] = j;
                    freeCellCount++;
                }
                Random rnd = new Random();
                int rndPair = rnd.nextInt(freeCellCount);
                emptyList[rndPair][0] = i;
                emptyList[rndPair][1] = j;
            }
        }
        return emptyList;
    }

    //Use WASD: W for up, S for Down, A for Left and D for Right
    public static void instructions() {
        System.out.println("How to Play");
        System.out.println("Press W to move up");
        System.out.println("Press S to move down");
        System.out.println("Press A to move left");
        System.out.println("Press D to move right");
    }



    public static void main(String[] args) {
        int rows = gameBoardSize();
        int[][] gameBoard = createGameBoard(rows);
        displayGameBoard(gameBoard, rows);
        instructions();
        int[][] findEmptyCells = findEmptyCells(gameBoard);
    }
}

Unless you are required to create this game using printing to the console - I would abandon this method ASAP.除非你需要使用打印到控制台来创建这个游戏 - 我会尽快放弃这种方法。 Creating a game like 2048 in a space that is not designed to act like an animation pane is going to be very difficult and frustrating.在一个不是为动画面板设计的空间中创建像 2048 这样的游戏将是非常困难和令人沮丧的。

Instead, I would have each tile be an object and do some research on swing and Graphics in Java.相反,我会让每个 tile 都是一个对象,并在 Java 中对摆动和图形进行一些研究。

If you must do it this way, (by the way, check the way you set up the grid - it's not consistent spacing) you'll have to print the values between the "|"如果你必须这样做,(顺便说一下,检查你设置网格的方式 - 它的间距不一致)你必须打印“|”之间的值characters.人物。

What's a smart way to do that?有什么聪明的方法可以做到这一点? Well, you could create a 2D int array, int[][] , and store all the values on the game board.好吧,您可以创建一个 2D int 数组int[][] ,并将所有值存储在游戏板上。 Then, you can loop over every element in the 2D array, and print it between your "|"然后,您可以循环遍历 2D 数组中的每个元素,并将其打印在“|”之间characters.人物。 This example below will work for any size 2D array.下面的这个例子适用于任何大小的二维数组。 Try changing the number of values you pass in and notice how it behaves .尝试更改您传入的值的数量并注意它的行为

public class Test {
    private static int[][] temp = new int[][] {{0,2, 4},{4, 4,16}, {3, 0, 128}};

    public static void main(String[] args) {
        int rows = temp.length;
        int cols = temp[0].length;

        for (int i = 0; i < rows; i++) {
            // This will resize our row separator for each row
            for (int j = 0; j < cols; j++) {
                System.out.print("+-----");
            }

            System.out.print("+\n");

            for (int j = 0; j < cols; j++) {
                System.out.print("|");

                // Here you have to deal with the spacing. You can see that this is ugly.
                // There's definitely better ways to do this, such as using mod
                if (temp[i][j] == 0) {System.out.print("     ");}
                else if (temp[i][j] < 10) {System.out.print("  " + temp[i][j] + "  ");}
                else if (temp[i][j] < 100) {System.out.print("  " + temp[i][j] + " ");}
                else if (temp[i][j] < 1000) {System.out.print(" " + temp[i][j] + " ");}
            }

            System.out.print("|\n");
        }

        for (int j = 0; j < cols; j++) {
            System.out.print("+-----");
        }

        System.out.print("+\n");
    }
}

Output from the program above:上面程序的输出:

+-----+-----+-----+
|     |  2  |  4  |
+-----+-----+-----+
|  4  |  4  |  16 |
+-----+-----+-----+
|  3  |     | 128 |
+-----+-----+-----+

But then there is the problem of keeping your spacing correct.但是接下来是保持间距正确的问题。 You need to account for the length of the number, because your have to have the right number of spaces printed if the number is blank.您需要考虑数字的长度,因为如果数字为空,您必须打印正确数量的空格。 Or you'll have to use replace()... it sounds confusing.或者你必须使用replace()...听起来很混乱。

To piggy back off @sleepToken's answer you can use String.format to pad your output:要背负@sleepToken 的答案,您可以使用String.format来填充您的输出:

public class Test {
  private static int[][] temp = new int[][] {{0,2, 4},{4, 4,16}, {3, 0, 128}};

  public static void main(String[] args) {
      int rows = temp.length;
      int cols = temp[0].length;

      String separator = "+---------------";

      for (int i = 0; i < rows; i++) {
          // This will resize our row separator for each row
          for (int j = 0; j < cols; j++) {
              System.out.print(separator);
          }

          System.out.print("+\n");

          for (int j = 0; j < cols; j++) {
            System.out.print(String.format("|%5s%5s%5s", "", temp[i][j], ""));
          }

          System.out.print("|\n");
      }

      for (int j = 0; j < cols; j++) {
        System.out.print(separator);
      }

      System.out.print("+\n");
  }
}

Which will pad like thus:它将像这样填充:

+---------------+---------------+---------------+
|         0     |         2     |         4     |
+---------------+---------------+---------------+
|         4     |         4     |        16     |
+---------------+---------------+---------------+
|         3     |         0     |       128     |
+---------------+---------------+---------------+

Might have to play around with the padding values but the format that i have will play nicely up to a 5 digit number.可能必须使用填充值,但我拥有的格式可以很好地播放多达 5 位数字。

Below is another example of how you can do dynamic padding based of how long you want your max cell width (length) to be:下面是另一个示例,说明如何根据您希望最大单元格宽度(长度)的长度进行动态填充:

public class Test {
  private static int[][] temp = new int[][] {{0,2, 4},{4, 4,16}, {3, 0, 8}};

  public static void main(String[] args) {

    int rows = temp.length;
    int cols = temp[0].length;

    int maxCellLength = 15; //define our cell width

    int longestDigit = longestDigit(temp); //get the length of our longest diget

    if (longestDigit > maxCellLength) maxCellLength = longestDigit + 10; //add extra padding if the longest digit is longer than our cell length

    int leftPad = (maxCellLength - longestDigit) / 2;

    int rightPad = maxCellLength - longestDigit - leftPad;

    String fmt = "|%" + leftPad +"s%" + longestDigit + "s%" + rightPad + "s"; //construct our string format

    String separator = "+" + repeat("-", maxCellLength); //construct the separator

    for (int i = 0; i < rows; i++) {
      // This will resize our row separator for each row
      for (int j = 0; j < cols; j++) {
        System.out.print(separator);
      }

      System.out.print("+\n");

      for (int j = 0; j < cols; j++) {
        System.out.print(String.format(fmt, "", temp[i][j], ""));
      }

      System.out.print("|\n");
    }

    for (int j = 0; j < cols; j++) {
      System.out.print(separator);
    }

    System.out.print("+\n");
  }


  public static int longestDigit(int[][] arr) {
    int longest = 0;
    for(int i = 0; i < arr.length; i++) {
      for (int j = 0; j < arr[i].length; j++) {
        String intStr = String.valueOf(arr[i][j]);
        if (intStr.length() > longest) longest = intStr.length();
      }
    }

    return longest;
  }

  private static String repeat(String n, int length) {
    StringBuilder sb = new StringBuilder();
    for(int i = 0; i < length; i++) {
      sb.append(n);
    }
    return sb.toString();
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM