确保我的代码逻辑合理。该代码最终将导致yahtzee的Java表示形式

时间:2019-04-14 22:23:09

标签: java

我正在为Yahtzee的Straight类别上一堂课。 Yahtzee有2种选择,直,小或大。小笔直将是4个连续模具面的序列,例如1、2、3、4。较大的笔直将是5个连续模具面的序列。如果一个玩家获得小直牌,他们将获得30分,如果获得更大的直子,则将获得40分。

我的Straight类继承自名为Scores的类,并且仅使用一种名为getDiceScore的方法。 getDiceScore将接受DieInterface类型的参数。我将在下面附加DieInterface接口代码。

我只想确保我正在研究的项目的代码逻辑合理。

public interface DieInterface
{
    public static String[] dieFaces =
        {"+---+\n|   |\n| o |\n|   |\n+---+",
         "+---+\n|o  |\n|   |\n|  o|\n+---+",
         "+---+\n|o  |\n| o |\n|  o|\n+---+",
         "+---+\n|o o|\n|   |\n|o o|\n+---+",
         "+---+\n|o o|\n| o |\n|o o|\n+---+",
         "+---+\n|o o|\n|o o|\n|o o|\n+---+"};

    public static String toDieString(DieInterface aDie)
    {
        return dieFaces[aDie.getFaceValue()-1];
    }

    // Do not modify above this line

    public static String toDiceString(DieInterface[] dice)
    {
        StringBuilder result = new StringBuilder();
        String sideBySide = "";
        String die1 = dieFaces[dice[0].getFaceValue()-1];
        String die2 = dieFaces[dice[1].getFaceValue()-1];
        String die3 = dieFaces[dice[2].getFaceValue()-1];
        String die4 = dieFaces[dice[3].getFaceValue()-1];
        String die5 = dieFaces[dice[4].getFaceValue()-1];
        //String die6 = dieFaces[dice[5].getFaceValue()-1];
        String splitter = die1 + "\n" + die2 + "\n" + die3 + "\n"+ die4 + "\n"+ die4+ "\n"+ die5;
        String [] temp = splitter.split("\n");
        for(int i = 0; i < (temp.length/6); i++)
        {
            result.append(temp[0*(5)+i] + "  " + temp[1*(5)+i] + "  " + temp[2*(5)+i] +"  " +  temp[3*(5)+i] +"  "+ temp[4*(5)+i] +"\n");
        }

        return result.toString();

    }

    // Do not modify below this line
    public int roll();
    public int getFaceValue();
}

public class Straight extends Scores
{
    protected String name;
    protected int numConsecutiveFaces; // indicates how many consecutive faces that a player should have to satisfy this scoring category 
    public Straight(String aName, int numConsecutiveFaces)
    {
        super(aName);
        this.numConsecutiveFaces = numConsecutiveFaces;
    }
    public int getDiceScore(DieInterface[] dice)
    {
        boolean ones = false;//determines that only one side of a die appeared once
        int[] straight = new int[numConsecutiveFaces]; // array used to store numbers in the correct straight format
        int [] counter = {0, 0, 0, 0, 0 ,0}; //using to track how many times a die appeared 
        //looping through dice array to determine how many times a die appeared 
        for(int i = 0; i < dice.length; i++)
        {
            counter[dice[i].getFaceValue()-1]++;
        }
        //sorting the die in sequential order
        sort(counter);

        //determining that a die only appeared once and they are no larger than by one value. ex 1, 2, 3, 4, 5 not 2, 3, 5, 6
        for(int i = 0; i < counter.length; i++)
        {
            if(counter[i] == 1 && byAFactorOfOne(counter, counter) == true)
            {
                ones = true;
                byAFactorOfOne(counter, counter);
                counter[i] = straight[i];
            }
         }
        //if 4 die in a row are in correct sequential order return 30 points back
        if(straight[numConsecutiveFaces] == 4)
            return 30;
        //if 5 die in a row are in correct sequential order return 40 points back
        else if(straight[numConsecutiveFaces] == 5)
            return 40;
        else 
            return 0;
    }

    private void sort(int[] counter)
    {
        for (int i = 0; i <counter.length; i++) 
        {
            for (int j = 0; j < counter.length - i - 1; j++) 
            {
                if (counter[j] > counter[j + 1]) 
                {
                    int temp = counter[j];
                    counter[j] = counter[j + 1];
                    counter[j + 1] = temp;
                }
            }
        }

    }

    private boolean byAFactorOfOne(int[] counter, int[] counter2)
    {
        int value;
        int counting = 0;
        boolean repeat = true;
        int i = 0;

        while(repeat && counting < counter.length)
        {
            value = counter[i] - counter[i + 1];
            i++;
            if(value != 1)
            {
                repeat = false;
                return false;
            }
            counting ++;
        }
        return true;
    }
}

2 个答案:

答案 0 :(得分:0)

首先,以下代码不起作用:

if(straight[numConsecutiveFaces] == 4)

...,因为您没有在straight数组中设置任何值。


您正在计算每个模具值的显示次数:

//looping through dice array to determine how many times a die appeared 
for(int i = 0; i < dice.length; i++)
{
    counter[dice[i].getFaceValue()-1]++;
}

...,数组的索引是管芯上的值。这是有道理的。

但是,一旦对这些值进行排序,就会丢失每个计数代表的模具值。 不要这样做

//sorting the die in sequential order
sort(counter);

如果这样做,您将不再知道n次显示哪个模具值。

您不需要查找counter,而是查找4或5个不为0的连续条目。换言之,查找至少有一个骰子的4或5个连续条目显示该值。 / p>

您可以采取一些捷径:

  1. 如果counter[3]counter[4]为零,则不能使用4长度或5长度的直线
  2. 如果counter[2]counter[5]都为0,则不可能是5字长的直棋
  3. 如果counter的任何值> 1,则不可能出现5字长的直线
  4. 如果counter的值大于1个,则大于1,则不可能出现4长度的直线。

答案 1 :(得分:0)

解决此问题的更简单方法,不涉及对值进行计数或排序(使用二进制值表示模具值的存在):

public class Straight extends Scores
{

    static final int valueForOneToFour = Math.pow(2, 0) + Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3);
    static final int valueForTwoToFive = Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4);
    static final int valueForThreeToSix = Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4) + Math.pow(2, 5);

    static final int valueForOneToFive = Math.pow(2, 0) + Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4);
    static final int valueForTwoToSix = Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4) + Math.pow(2, 5);

    ...

    public int getDiceScore(DieInterface[] dice)
    {
        // calculate a binary representation of the values available
        int occurrenceValue = 0;
        for (int i = 0; i < 6; i++) {
            occurrenceValue |= Math.pow(2, dice[i] - 1));
        }

        if (occurrenceValue & valueForOneToFive == valueForOneToFive
                || occurrenceValue & valueForTwoToSix == valueForTwoToSix) {
            return 40;
        }

        if (occurrenceValue & valueForOneToFour == valueForOneToFour
                || occurrenceValue & valueForTwoToFive == valueForTwoToFive
                || occurrenceValue & valueForThreeToSix == valueForThreeToSix) {
            return 30;
        }

        return 0;
    }
}