Статьи

Создайте Yahtzee Dice Roller и Scorer в скомпилированном скрипте JavaFX

Я все еще на Симпозиуме по серверной стороне в Лас-Вегасе , и я думаю, что прогулка по всем этим игровым автоматам вдохновила этот пост в блоге. Сегодняшний пример основан на программе из сообщения «Бросьте кости» , чтобы создать каток и бомбардировщика Яхце.
Каждый раз, когда вы нажимаете кнопку « Бросить» , пять кубиков принимают случайные значения, а комбинация значений оценивается в соответствии с возможными категориями в нижней части листа оценки Яхтце. Вот скриншот:

Yahtzee_2

В дополнение к файлам Dice.fx и PipPlacement.fx из публикации « Бросьте кости» эта программа состоит из следующих файлов исходного кода.

YahtzeeMain.fx

 

/*
* YahtzeeMain.fx -
* A compiled JavaFX program that demonstrates creating custom
* components with CompositeNode and evaluates Yahtzee dice rolls.
*
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
* to serve as a JavaFX Script example.
*/

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

/*
* YahtzeeModel.fx -
* The model behind the Yahtzee dice roll and combination evaluation
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
* to serve as a JavaFX Script example.
*/
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);
}
}

 

Концепцией JavaFX Script, которую мы еще не рассмотрели, является набор статических функций, доступных в новом классе javafx.lang.Sequence . Эти функции позволяют выполнять операции (например, сортировку) над последовательностью. В этой программе я использую функции max и min этого класса, чтобы найти наибольшее и наименьшее значение в броске костей.

С уважением,
Джим Уивер
JavaFX Script: динамические сценарии Java для многофункциональных интернет-приложений и приложений на стороне клиента.

Немедленная загрузка электронных книг (PDF) доступна на сайте книги Apress.