#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 последовательных записей, в которых хотя бы один кубик показывает это значение.
Вы можете воспользоваться несколькими ярлыками:
- Если
counter[3]
илиcounter[4]
равно нулю, это невозможно ни для прямой длиной 4, ни для прямой длиной 5 - Если
counter[2]
иcounter[5]
оба равны 0 , это невозможно для прямой длиной 5 - Если есть какие-либо
counter
значения> 1, то невозможно, чтобы произошла прямая длиной 5 - И если существует более 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;
}
}