格式化java骰子滚动程序?

时间:2018-03-02 19:05:44

标签: java

我正在制作一个java程序,其中选择并显示随机骰子面。最终,我想在控制台中并排显示五个骰子。我制作了一些字符串,这些字符串是6个骰子面的ascii表示。

以下是一个例子:

+-------+
| o   o |
|   o   |
| o   o |
+-------+

我的问题是:如何在控制台中并排显示其中五个ascii骰子?我希望控制台输出看起来像这样:

+-------+   +-------+   +-------+   +-------+   +-------+
| o   o |   | o   o |   | o   o |   | o   o |   | o   o |
|   o   |   |   o   |   |   o   |   |   o   |   |   o   |
| o   o |   | o   o |   | o   o |   | o   o |   | o   o |
+-------+   +-------+   +-------+   +-------+   +-------+

这是我的代码:

public class Die
{
    private final static int LOWEST_DIE_VALUE = 0;
    private final static int HIGHEST_DIE_VALUE = 6;

    private String die;

    public Die()
    {
        String[] dieFaces = {"+-------+\r\n|       |\r\n|   o   |\r\n|       |\r\n+-------+", 
                             "+-------+\r\n| o     |\r\n|       |\r\n|     o |\r\n+-------+",
                             "+-------+\r\n| o     |\r\n|   o   |\r\n|     o |\r\n+-------+",
                             "+-------+\r\n| o   o |\r\n|       |\r\n| o   o |\r\n+-------+",
                             "+-------+\r\n| o   o |\r\n|   o   |\r\n| o   o |\r\n+-------+",
                             "+-------+\r\n| o   o |\r\n| o   o |\r\n| o   o |\r\n+-------+"};

        die = dieFaces[((int)(Math.random() * 100) % HIGHEST_DIE_VALUE + LOWEST_DIE_VALUE)];        
    }

    public String getDie()
    {
        return die;
    }
}

public class FiveDice
{
    public static void main(String[] args)
    {
        Die die1 = new Die();
        System.out.println(die1.getDie());
    }
}

3 个答案:

答案 0 :(得分:14)

这听起来有点像家庭作业(如果我错了就道歉),所以我会让你从正确的方向开始,而不是提供完整的解决方案。

考虑六种可能的骰子:

+-------+   +-------+   +-------+   +-------+   +-------+   +-------+
|       |   | o     |   | o     |   | o   o |   | o   o |   | o   o |
|   o   |   |       |   |   o   |   |       |   |   o   |   | o   o |
|       |   |     o |   |     o |   | o   o |   | o   o |   | o   o |
+-------+   +-------+   +-------+   +-------+   +-------+   +-------+

这些是多么独特,真的吗?你可以把它分成6个字符串:

private static final String xxxxxxxxx = "+-------+";
private static final String x_______x = "|       |";
private static final String x_o_____x = "| o     |";
private static final String x___o___x = "|   o   |";
private static final String x_____o_x = "|     o |";
private static final String x_o___o_x = "| o   o |";

每个骰子面都可以通过将这些字符串与换行符组合在一起来表示,例如:

public String[] getLines(int face) {
    switch (face) {
        case 1:
            return new String[] {
                    xxxxxxxxx,
                    x_______x,
                    x___o___x,
                    x_______x,
                    xxxxxxxxx
            };
        case 2:
            ...
        case 3:
            ...
        // etc.
}

如果你想并排渲染它们,可以考虑如何安排几个阵列,这样你就可以在每个模具上迭代一次打印一行。

答案 1 :(得分:1)

对于这样的情况,我倾向于创建一些通用的解决方案。这可能是“过度工程”。对于问题的特定案例。但我认为结果可能是应用案例的有用构建块。

  • 有一组字符串应该被格式化#34;很好地"
  • 字符串数量未知。
  • 字符串可以包含多行(即它们可能包含换行符\n\r\n)。
  • 不知道换行符的数量。
  • 线路长度未知。

这里的一种方法是将字符串分成多行,并将它们视为" blocks"应该水平连接。

以下示例中的format方法正是如此:

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class MultiLineFormatting
{
    public static void main(String[] args)
    {
        showDice();
        showOtherStrings();
    }

    private static void showDice()
    {
        String s1 = 
            "+-------+" + "\n" +
            "|       |" + "\n" +
            "|   o   |" + "\n" +
            "|       |" + "\n" +
            "+-------+";
        String s4 = 
            "+-------+" + "\n" +
            "| o   o |" + "\n" +
            "|       |" + "\n" +
            "| o   o |" + "\n" +
            "+-------+";
        String s5 = 
            "+-------+" + "\n" +
            "| o   o |" + "\n" +
            "|   o   |" + "\n" +
            "| o   o |" + "\n" +
            "+-------+";

        System.out.println(format(Arrays.asList(s1, s4, s5, s4), "  "));
    }

    private static void showOtherStrings()
    {
        String sA = 
            "AAA" + "\n" +
            "AAAAAAAA" + "\n" +
            "AAAAA";
        String sB = 
            "BBBBBBBBBBBBBB" + "\n" +
            "BBBBB" + "\n" +
            "BBBBBBBBBB" + "\n" +
            "BBBBBBBBBBBBBBBBB" + "\n" +
            "BBBBB";
        String sC = 
            "CCC" + "\n" +
            "" + "\n" +
            "CCCCCCC" + "\n" +
            "CCCC";

        System.out.println(format(Arrays.asList(sA, sB, sC, sA), "  "));
    }

    private static String format(Collection<String> strings, String padding)
    {
        StringBuilder sb = new StringBuilder();

        // Convert the strings to lists of strings, breaking them at newlines
        List<List<String>> lineLists = strings.stream()
            .map(s -> s.split("\\R"))
            .map(Arrays::asList)
            .collect(Collectors.toList());

        // Compute the maximum number of lines of any block
        int maxNumLines = lineLists.stream()
            .mapToInt(Collection::size)
            .max().getAsInt();

        // Compute a map from each block index to the maximum length of a line
        Map<Integer, Integer> maxLineLengths = 
            new LinkedHashMap<Integer, Integer>();
        for (int i = 0; i < lineLists.size(); i++)
        {
            List<String> lineList = lineLists.get(i);
            int maxLineLength = lineList.stream()
                .mapToInt(String::length)
                .max().getAsInt();
            maxLineLengths.put(i, maxLineLength);
        }

        // Assemble the resulting lines
        for (int i = 0; i < maxNumLines; i++)
        {
            // Concatenate the i'th line of each block
            for (int j = 0; j < lineLists.size(); j++)
            {
                List<String> lineList = lineLists.get(j);
                int maxLineLength = maxLineLengths.get(j);
                String format = "%-" + maxLineLength + "s";
                if (i < lineList.size())
                {
                    String line = lineList.get(i);
                    sb.append(String.format(format, line));
                }
                else
                {
                    sb.append(String.format(format, ""));
                }
                sb.append(padding);
            }
            sb.append("\n");
        }
        return sb.toString();
    }
}

对于骰子的例子,输出是所希望的:

+-------+  +-------+  +-------+  +-------+  
|       |  | o   o |  | o   o |  | o   o |  
|   o   |  |       |  |   o   |  |       |  
|       |  | o   o |  | o   o |  | o   o |  
+-------+  +-------+  +-------+  +-------+  

作为一个额外的测试,有一个例子,其他字符串被格式化,具有不同的行数和行长度:

AAA       BBBBBBBBBBBBBB     CCC      AAA       
AAAAAAAA  BBBBB                       AAAAAAAA  
AAAAA     BBBBBBBBBB         CCCCCCC  AAAAA     
          BBBBBBBBBBBBBBBBB  CCCC               
          BBBBB                                 

答案 2 :(得分:0)

我没有添加评论来减少长度。如果您有任何疑问,请询问: - )

我们的想法是为&#34;眼睛场提供一个布尔矩阵(3x3)。&#34; DiceSide负责根据要显示的数字设置字段。不考虑两个字段(顶部中间,底部中间),因为它们总是空的。

createString方法将骰子打印为行(每个diceside有5行(标题,三个眼睛行和底部))。

import java.util.Arrays;
import java.util.List;

public class AsciiDice {
    private static class DiceSide {

        public DiceSide(final int nr) {
            setNr(nr);
        }

        public void setNr(final int nr) {
            if (nr <= 0 || nr > 6) return;

            fields[0][0] = nr == 2 || nr == 3 || nr == 4 || nr == 5 || nr == 6;
            fields[0][2] = nr == 4 || nr == 5 || nr == 6;
            fields[1][0] = nr == 6;
            fields[1][1] = nr == 1 || nr == 3 || nr == 5;
            fields[1][2] = nr == 6;
            fields[2][0] = nr == 4 || nr == 5 || nr == 6;
            fields[2][2] = nr == 2 || nr == 3 || nr == 4 || nr == 5 || nr == 6;
        }

        final boolean[][] fields = new boolean[3][3];
    }

    public static void main(final String[] args) {
        new AsciiDice();
    }

    public AsciiDice() {
        final List<DiceSide> diceSides = Arrays.asList(new DiceSide(5), new DiceSide(4), new DiceSide(3));
        final String str = createString(diceSides);
        System.out.println(str);
    }

    private String createString(final List<DiceSide> diceSides) {
        final StringBuilder sb = new StringBuilder();

        for (int i = 0; i < 5; i++) {
            for (final DiceSide side : diceSides) {
                if (i == 0 || i == 4) {
                    sb.append("+-------+");
                } else {
                    sb.append("| ");
                    for (int c = 0; c < 3; c++) {
                        final boolean set = side.fields[i - 1][c];
                        if (set) {
                            sb.append("o ");
                        } else {
                            sb.append("  ");
                        }
                    }
                    sb.append("|");
                }

                sb.append("\t");
            }
            sb.append("\n");
        }
        return sb.toString();
    }

}