Убедившись, что логика моего кода верна. Этот код в конечном итоге приведет к java-представлению yahtzee

#java

#java

Вопрос:

Я создаю класс для прямой категории Yahtzee. У Yahtzee есть 2 варианта для прямого, малого или большего. Маленькая прямая будет представлять собой последовательность из 4 последовательных граней матрицы, таких как 1, 2, 3, 4. Большая прямая будет представлять собой последовательность из 5 последовательных граней матрицы. Если игрок получает небольшой стрит, он получает 30 очков, а если он получает больший, то это 40 очков.

Мой прямой класс наследует от класса с именем 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 amp;amp; 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 amp;amp; counting < counter.length)
        {
            value = counter[i] - counter[i   1];
            i  ;
            if(value != 1)
            {
                repeat = false;
                return false;
            }
            counting   ;
        }
        return true;
    }
}
 

Ответ №1:

Прежде всего, следующий код не будет работать:

 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 последовательных записей, в которых хотя бы один кубик показывает это значение.

Вы можете воспользоваться несколькими ярлыками:

  1. Если counter[3] или counter[4] равно нулю, это невозможно ни для прямой длиной 4, ни для прямой длиной 5
  2. Если counter[2] и counter[5] оба равны 0 , это невозможно для прямой длиной 5
  3. Если есть какие-либо counter значения> 1, то невозможно, чтобы произошла прямая длиной 5
  4. И если существует более 1 counter значений> 1, то невозможно, чтобы произошла прямая длиной 4.

Ответ №2:

Более простой способ решения этой проблемы, который не требует подсчета значений или сортировки (использует двоичные значения для представления наличия значения матрицы):

 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 amp; valueForOneToFive == valueForOneToFive
                || occurrenceValue amp; valueForTwoToSix == valueForTwoToSix) {
            return 40;
        }

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

        return 0;
    }
}