Create a Yahtzee game using JavaFX with following requirements The program will
ID: 3915846 • Letter: C
Question
Create a Yahtzee game using JavaFX with following requirements
The program will still need JavaFx GUI
- 5 dice will be rolled only when a user clicks on a specific location such as a button or image.
- all dice that are not held to be rolled out of the 5 dice on the screen
- only 3 rolls per round and you choose which dice to hold. 10 rounds or when user wants to stop
- Now when dice are clicked on they will either gain a border around them to show they are held OR if they are already held, the border will be dropped
Explanation / Answer
YahtzeeMain.fx
import javafx.ui.*;
import javafx.ui.canvas.*;
import java.lang.System;
Frame {
var model = YahtzeeModel {}
width: 510
height: 400
title: "Roll Dice and Evaluate Yahtzee Combinations"
background: Color.WHITE
content:
BorderPanel {
center:
Box {
var evalFont =
Font {
size: 20
}
orientation: Orientation.VERTICAL
content: [
Canvas {
content:
for (diceNum in [0 .. model.numDice - 1]) {
model.newDice =
Dice {
x: diceNum * 100 + 10
y: 10
width: 80
height: 80
faceColor: Color.RED
pipColor: Color.WHITE
}
}
},
GroupPanel {
var fiveOfKindRow = Row { alignment: Alignment.BASELINE }
var largeStraightRow = Row { alignment: Alignment.BASELINE }
var smallStraightRow = Row { alignment: Alignment.BASELINE }
var fullHouseRow = Row { alignment: Alignment.BASELINE }
var fourOfKindRow = Row { alignment: Alignment.BASELINE }
var threeOfKindRow = Row { alignment: Alignment.BASELINE }
var chanceRow = Row { alignment: Alignment.BASELINE }
var labelsColumn = Column {
alignment: Alignment.TRAILING
}
var fieldsColumn = Column {
alignment: Alignment.LEADING
}
rows: [
fiveOfKindRow,
largeStraightRow,
smallStraightRow,
fullHouseRow,
fourOfKindRow,
threeOfKindRow,
chanceRow
]
columns: [
labelsColumn,
fieldsColumn
]
content: [
SimpleLabel {
font: evalFont
row: fiveOfKindRow
column: labelsColumn
text: "Five of a Kind (Yahtzee):"
},
SimpleLabel {
font: evalFont
row: fiveOfKindRow
column: fieldsColumn
text: bind
if (model.fiveOfKind)
"{model.fiveOfKindScore}"
else "N/A"
},
SimpleLabel {
font: evalFont
row: largeStraightRow
column: labelsColumn
text: "Large Straight:"
},
SimpleLabel {
font: evalFont
row: largeStraightRow
column: fieldsColumn
text: bind
if (model.largeStraight)
"{model.largeStraightScore}"
else "N/A"
},
SimpleLabel {
font: evalFont
row: smallStraightRow
column: labelsColumn
text: "Small Straight:"
},
SimpleLabel {
font: evalFont
row: smallStraightRow
column: fieldsColumn
text: bind
if (model.smallStraight)
"{model.smallStraightScore}"
else "N/A"
},
SimpleLabel {
font: evalFont
row: fullHouseRow
column: labelsColumn
text: "Full House:"
},
SimpleLabel {
font: evalFont
row: fullHouseRow
column: fieldsColumn
text: bind
if (model.fullHouse)
"{model.fullHouseScore}"
else "N/A"
},
SimpleLabel {
font: evalFont
row: fourOfKindRow
column: labelsColumn
text: "Four of a Kind:"
},
SimpleLabel {
font: evalFont
row: fourOfKindRow
column: fieldsColumn
text: bind
if (model.fourOfKind)
"{model.sumOfDiceValues}"
else "N/A"
},
SimpleLabel {
font: evalFont
row: threeOfKindRow
column: labelsColumn
text: "Three of a Kind:"
},
SimpleLabel {
font: evalFont
row: threeOfKindRow
column: fieldsColumn
text: bind
if (model.threeOfKind)
"{model.sumOfDiceValues}"
else "N/A"
},
SimpleLabel {
font: evalFont
row: chanceRow
column: labelsColumn
text: "Chance:"
},
SimpleLabel {
font: evalFont
row: chanceRow
column: fieldsColumn
text: bind "{model.sumOfDiceValues}"
},
]
},
]
}
bottom:
FlowPanel {
content:
Button {
text: "Roll"
defaultButton: true
action:
function():Void {
model.roll();
}
}
}
}
visible: true
onClose:
function():Void {
System.exit(0);
}
}
YahtzeeModel.fx
import javafx.lang.Sequences;
import java.lang.System;
class YahtzeeModel {
attribute numDice:Integer = 5;
attribute diceDistribution:Integer[];
attribute newDice:Dice on replace {
insert newDice into dice;
}
attribute dice:Dice[];
attribute fiveOfKind:Boolean;
attribute largeStraight:Boolean;
attribute smallStraight:Boolean;
attribute fullHouse:Boolean;
attribute fourOfKind:Boolean;
attribute threeOfKind:Boolean;
attribute fiveOfKindScore:Integer = 50;
attribute largeStraightScore:Integer = 40;
attribute smallStraightScore:Integer = 30;
attribute fullHouseScore:Integer = 25;
attribute sumOfDiceValues:Integer = 0;
function roll():Void {
for (die in dice) {
die.roll();
}
evalYahtzeeCombos();
}
function evalYahtzeeCombos() {
var values =
for (val in dice) {
val.value;
}
var maxVal:Integer = Sequences.max(values, null) as Integer;
var minVal:Integer = Sequences.min(values, null) as Integer;
// Create a sequence that contains the distribution of values
// and Calclulate the sum of the dice values
diceDistribution =
for (i in [1 .. 6]) 0;
sumOfDiceValues = 0;
for (val in values) {
diceDistribution[val - 1]++;
sumOfDiceValues += val;
}
// Determine if five-of-a-kind
fiveOfKind =
((for (occurance in diceDistribution
where occurance >= 5) occurance) <> []);
// Determine if four-of-a-kind
fourOfKind =
((for (occurance in diceDistribution
where occurance >= 4) occurance) <> []);
// Determine if three-of-a-kind
threeOfKind =
sizeof (for (occurance in diceDistribution
where occurance >= 3) occurance) > 0;
// Determine if full house
fullHouse =
sizeof (for (occurance in diceDistribution
where occurance == 3) occurance) > 0 and
sizeof (for (occurance in diceDistribution
where occurance == 2) occurance) > 0;
// Determine if large straight
largeStraight =
sizeof (for (occurance in diceDistribution
where occurance > 1) occurance) == 0 and
(maxVal - minVal == 4);
// Determine if small straight
smallStraight =
sizeof (for (occurance in diceDistribution
where occurance == 2) occurance) == 1 and
(maxVal - minVal == 3);
}
}