あなたのコードを見ている間、正確な5つまたは6つの簡単なクラスを作成することで、これをもっと簡単にすることができると感じています。
まず、いくつかの部分をクラスに分割します。私が考えている2つの主なクラスは単純なDie
クラスです。このクラスは作成されたときにダイ値を1から6までの乱数に設定する不変のDie
です。Die
オブジェクトを作成すると変更できません。あなたのThreeDice
クラスは狭く、実際には3つのダイスが実際にオブジェクト(次のクラス)の一部である必要があり、Die
オブジェクトの単純な配列であり、Die
オブジェクトの配列として、ローからハイにサイコロを並べ替えることができます。
「ダイ」クラスのサンプルは以下の通りです:
Public final class Die implements Comparable<Die>
{
private int dieNumber;
// default constructor
public Die()
{
RollDie();
}
public int GetDieNumber()
{
return dieNumber;
}
public int compareTo(Die otherDie)
{
return this.dieNumber - otherDie.dieNumber;
}
private void RollDie()
{
dieNumber = 1 + (int)(6 * Math.random());
}
}
支援するための次のクラスはプレーヤーのクラスになります。このクラスの重要な部分は、プレイヤーの名前、次にランダムなサイコロを保持するDie
オブジェクト配列(あなたの場合はサイズ3)です。このクラスでは、3つのダイスの合計値を取得する方法と、3つのダイスが同じ数である場合、ペアなどがある場合にユーザーが取得する余分なポイントを取得するためのメソッド/変数を使用することもできます。ダイス配列を作成するときに、ローからハイへのダイス配列のソートを利用できます。これにより、ストレートのチェックが容易になります。
Playerクラスの例は以下のとおりです。
public class Player implements Comparable<Player>
{
private String playerName;
private Die[] diceArray;
private int diceTotal = 0;
private int extraPoints = 0;
private int overallTotal = 0;
private String extraPointsString = "";
public Player(String inName, Die[] inDiceArray)
{
playerName = inName;
diceArray = inDiceArray;
SetDiceTotals();
}
public String GetPlayerName()
{
return playerName;
}
public int GetExtraPoints()
{
return extraPoints;
}
public int GetDiceTotal()
{
return diceTotal;
}
public int GetOverallTotal()
{
return overallTotal;
}
public String GetExtraPointsString()
{
return extraPointsString;
}
public Die[] GetDiceArray()
{
return diceArray;
}
public String toString()
{
String playerString = playerName + " Dice values: ";
for (int i = 0; i < diceArray.length; i++)
{
if (i < (diceArray.length - 1))
playerString = playerString + diceArray[i].GetDieNumber() + ", ";
else
playerString = playerString + diceArray[i].GetDieNumber();
}
playerString = playerString + " Total: " + GetDiceTotal();
playerString = playerString + " - Special Points added: " + GetExtraPoints() + " for having " + GetExtraPointsString();
return playerString + " Total Points: " + GetOverallTotal();
}
public int compareTo(Player otherPlayer)
{
int thisTotal = this.GetDiceTotal() + this.GetExtraPoints();
int otherTotal = otherPlayer.GetDiceTotal() + otherPlayer.GetExtraPoints();
return otherTotal - thisTotal;
}
// private internal method to set dice totals, extra points and extra points string
private void SetDiceTotals()
{
int total = 0;
for (int i = 0; i < diceArray.length; i++)
{
total = total + diceArray[i].GetDieNumber();
}
diceTotal = total;
if (is3OfAKind())
{
extraPoints = 60;
extraPointsString = "Three of a Kind";
}
else
{
if (isPair())
{
extraPoints = 40;
extraPointsString = "Pair";
}
else
{
if (isStraight())
{
extraPoints = 20;
extraPointsString = "Straight";
}
else
{
extraPoints = 0;
extraPointsString = "All die are different";
}
}
}
overallTotal = extraPoints + diceTotal;
}
private boolean is3OfAKind()
{
if (diceArray[0].GetDieNumber() == diceArray[1].GetDieNumber() &&
diceArray[0].GetDieNumber() == diceArray[2].GetDieNumber())
return true;
return false;
}
private boolean isPair()
{
if (diceArray[0].GetDieNumber() == diceArray[1].GetDieNumber() ||
diceArray[0].GetDieNumber() == diceArray[2].GetDieNumber() ||
diceArray[1].GetDieNumber() == diceArray[2].GetDieNumber())
return true;
return false;
}
// this method needs to have the diceArray sorted from low to high
private boolean isStraight()
{
if (diceArray[1].GetDieNumber() == (diceArray[0].GetDieNumber() + 1) &&
diceArray[2].GetDieNumber() == (diceArray[1].GetDieNumber() + 1))
return true;
return false;
}
}
あなたはすべてのラウンドの合計を維持したいので、その後、私はあなたがRound
クラスが必要な場合があります把握。このクラスは、ラウンドのためのPlayer
オブジェクトの配列で構成されます。また、ラウンドナンバー、すべてのプレーヤーからのラウンドの合計ポイント、ラウンドのポイントの平均値、およびラウンドを獲得したプレーヤーを示す文字列。
ラウンドクラスの例を以下に示します。あなたはすべてのプレーヤーの合計を維持したいので、
public class Round
{
private Player[] playerArray;
private int roundNumber = 0;
private int totalPointsForRound = 0;
private double roundAveragePoints = 0;
private String roundWinnerName = "";
public Round(int inRoundNumber, Player[] inPlayerArray)
{
playerArray = inPlayerArray;
roundNumber = inRoundNumber;
totalPointsForRound = SetAllPointsForRound();
roundAveragePoints = SetAveragePoints();
roundWinnerName = SetRoundWinnerName();
}
public int GetTotalPointsForRound()
{
return totalPointsForRound;
}
public double GetAveragePointsForRound()
{
return roundAveragePoints;
}
public String GetRoundWinnerName()
{
return roundWinnerName;
}
public Player[] GetPlayerArray()
{
return playerArray;
}
public int GetRoundNumber()
{
return roundNumber;
}
private String SetRoundWinnerName()
{
// sort the array from high to low - if the first two total are equal then its a tie
Player[] tempArray = playerArray;
Arrays.sort(tempArray);
if (tempArray[0].GetOverallTotal() == tempArray[1].GetOverallTotal())
return "Tie";
if (tempArray[0].GetOverallTotal() > tempArray[1].GetOverallTotal())
return tempArray[0].GetPlayerName();
return "Unknown Winner???";
}
private double SetAveragePoints()
{
double totalPoints = GetTotalPointsForRound();
double average = totalPoints/playerArray.length;
return Math.round(average*100.0)/100.0;
}
private int SetAllPointsForRound()
{
int allPoints = 0;
for (int i = 0; i < playerArray.length; i++)
{
allPoints = allPoints + playerArray[i].GetOverallTotal();
}
return allPoints;
}
}
その後、あなたは小さなPlayerTotals
クラスを作成することもできます。このクラスは、プレイヤー名、すべてのラウンドの合計得点、すべてのラウンドの合計得点で構成されます。個々のラウンドではなく、Player
オブジェクトがRound's
playerArray
の各ラウンドの合計を含むため、これらはすべてのラウンドの合計です。
A PlayerTotalsクラスの例では、実際には1つのクラスに組み合わせることができ
public class PlayerTotals implements Comparable<PlayerTotals>
{
String playerName;
int totalWins = 0;
int totalPoints = 0;
public PlayerTotals(String inPlayerName)
{
playerName = inPlayerName;
}
public int GetTotalPoints()
{
return totalPoints;
}
public void SetTotalPoints(int inPoints)
{
totalPoints = inPoints;
}
public int GetTotalWins()
{
return totalWins;
}
public void SetTotalWins(int inWins)
{
totalWins = inWins;
}
public int compareTo(PlayerTotals otherPlayerTotals)
{
int thisTotalPoints = this.GetTotalPoints();
int otherTotalPoints = otherPlayerTotals.GetTotalPoints();
return otherTotalPoints - thisTotalPoints;
}
}
次に、2つの以上のクラスを下回っています。静的なGameUtils
クラスは、GetPlayerArray
のようないくつかのグローバルな処理を行うのに役立ち、このメソッドはPlayer
オブジェクトの配列を取得します。各Player
オブジェクトには、各プレイヤーがロールした3つのサイコロの配列が含まれます。このダイスの配列は、低から高にソートされます。これは、各ラウンドの各プレイヤーの最初のランダムロールを取得する方法です。また、ここで我々はすべてのラウンドをループすることができ、各プレイヤーが獲得した勝利数を合計することができるGetPlayerOverallWins
を行うことができます。すべてのラウンドからの総同数を得るには、GetTotalTies
というメソッド。そして、方法GetPlayerOverallPoints
すべてのラウンドからすべての選手ポイントの合計を取得する。また、ここでは、ユーザーの入力が有効であることを確認するために、プレーヤーの数とラウンド数を入力するためのプロンプトを表示しました。
A GameUtils例は以下の通りです:
public final class GameUtils
{
public static Player[] GetPlayerArray(int numOfPlayers, int numOfDice)
{
Player[] playerArray = new Player[numOfPlayers];
for (int i = 0; i < numOfPlayers; i++)
{
Die[] diceArray = new Die[numOfDice];
for (int j = 0; j < numOfDice; j++)
{
diceArray[j] = new Die();
}
Arrays.sort(diceArray);
playerArray[i] = new Player("Player " + (i + 1), diceArray);
}
return playerArray;
}
public static int GetNumberOfPlayers(Scanner input)
{
return GetValidInteger("Please input number of players (greater than 0) --> ", input);
}
public static int GetNumberOfRounds(Scanner input)
{
return GetValidInteger("Please input number of rounds (greater than 0) --> ", input);
}
private static int GetValidInteger(String prompt, Scanner input)
{
boolean done = false;
int validInt = -1;
String userInput = "";
while (!done)
{
System.out.print(prompt);
userInput = input.nextLine();
try
{
validInt = Integer.parseInt(userInput);
done = true;
}
catch (NumberFormatException e)
{
System.out.println("Invalid Input: " + userInput + " Try again!");
}
}
return validInt;
}
public static int GetPlayerOverallWins(String playerName, Round[] allRounds)
{
int totalWins = 0;
for (int i = 0; i < allRounds.length; i++)
{
Round curRound = allRounds[i];
String roundWinner = curRound.GetRoundWinnerName();
if (playerName.equals(roundWinner))
{
totalWins++;
}
}
return totalWins;
}
public static int GetTotalTies(Round[] allRounds)
{
int totalTies = 0;
for (int i = 0; i < allRounds.length; i++)
{
Round curRound = allRounds[i];
String roundWinner = curRound.GetRoundWinnerName();
if (roundWinner.equals("Tie"))
{
totalTies++;
}
}
return totalTies;
}
public static int GetPlayerOverallPoints(String player, Round[] allRounds)
{
int totalPoints = 0;
for (int i = 0; i < allRounds.length; i++)
{
Round curRound = allRounds[i];
for (int j = 0; j < curRound.GetPlayerArray().length; j++)
{
Player curPlayer = curRound.GetPlayerArray()[j];
if (player.equals(curPlayer.GetPlayerName()))
{
totalPoints = totalPoints + curPlayer.GetOverallTotal();
break;
}
}
}
return totalPoints;
}
}
が最後にメインエントリと
DiceGame
クラスはすべて一緒にそれを置くために。ダイスゲームクラスはグローバル変数
numberOfPlayers
で構成されます。
numberOfRounds
,および
playerArray
を各ラウンドに使用し、次に
Rounds
の配列を使用して、すべてのラウンドを実行した後に合計ラウンドを保持します。以下の例は、ラウンド数のループを設定することから始まります。このループでは、すべてのプレイヤーとダイスの値を作成し、ラウンド情報を新しい
Round
オブジェクトに保存してから、新しい各
Round
オブジェクトを配列に配置します。次に、現在のラウンドの結果がユーザーに出力されます。ラウンド数のループが終了すると、
Round
個のオブジェクトが配列されます。すべてのラウンドで
PlayerTotals
オブジェクトの別の配列を作成できるので、ここでは
PlayerTotals
クラスが役立ちます。これは
GameUtils
のいくつかのメソッドを使用しており、これらのメソッドはこのメインクラスに置くことができます。すべてのラウンドのプレーヤー合計が合計された後、結果がユーザーに出力されます。
メインDiceGameクラス例:
public class DiceGame
{
public static Scanner input = new Scanner(System.in);
static int numberOfPlayers;
static int numberOfRounds;
static int numberOfDice = 3;
static Player[] playerArray;
static Round[] allRounds;
public static void main(String[] args)
{
numberOfPlayers = GameUtils.GetNumberOfPlayers(input);
numberOfRounds = GameUtils.GetNumberOfRounds(input);
System.out.println("");
allRounds = new Round[numberOfRounds];
// for each round - we want to create players with the proper number of random dice
for (int i = 0; i < numberOfRounds; i++)
{
// get an array of players with random dice
playerArray = GameUtils.GetPlayerArray(numberOfPlayers, numberOfDice);
Round currentRound = new Round(i, playerArray);
allRounds[i] = currentRound;
// print the results of this round
System.out.println("Round " + (i + 1) + " Results - Winner is: " + currentRound.GetRoundWinnerName()
+ " -- Average score for this round: " + currentRound.GetAveragePointsForRound());
for (int j = 0; j < playerArray.length; j++)
{
System.out.println(playerArray[j].toString());
}
System.out.println("---------------------------------------");
}
// now get totals for all rounds
// first create an array of PlayerTotals
PlayerTotals[] allPlayersTotals = new PlayerTotals[numberOfPlayers];
for (int i = 0; i < numberOfPlayers; i++)
{
PlayerTotals curPlayer = new PlayerTotals(playerArray[i].GetPlayerName());
curPlayer.SetTotalPoints(GameUtils.GetPlayerOverallPoints(curPlayer.playerName, allRounds));
curPlayer.SetTotalWins(GameUtils.GetPlayerOverallWins(curPlayer.playerName, allRounds));
allPlayersTotals[i] = curPlayer;
}
// print the overall results
System.out.println("");
System.out.println(" -- Overall Results --");
System.out.println("Ties: " + GameUtils.GetTotalTies(allRounds));
Arrays.sort(allPlayersTotals);
PlayerTotals curPlayer;
for (int i = 0; i < allPlayersTotals.length; i++)
{
curPlayer = allPlayersTotals[i];
System.out.println(curPlayer.playerName + " Won " + curPlayer.totalWins + " times - Total Points: " + curPlayer.totalPoints);
}
}
}
これらは物事が容易になります願っています。がんばろう!
質問から大きな(そして重要な)チャンクを削除しないでください。 – Tom