summaryrefslogtreecommitdiffstats
path: root/examples/qml/blackjack
diff options
context:
space:
mode:
Diffstat (limited to 'examples/qml/blackjack')
-rw-r--r--examples/qml/blackjack/blackjack.qml213
-rw-r--r--examples/qml/blackjack/blackjack.scxml372
-rw-r--r--examples/qml/blackjack/main.cpp1
3 files changed, 335 insertions, 251 deletions
diff --git a/examples/qml/blackjack/blackjack.qml b/examples/qml/blackjack/blackjack.qml
index 976661a..6e68022 100644
--- a/examples/qml/blackjack/blackjack.qml
+++ b/examples/qml/blackjack/blackjack.qml
@@ -9,85 +9,196 @@ Rectangle {
id: controller
source: "blackjack.scxml"
}
+ states: [
+ State {
+ name: "placeBets"
+ when: controller.current.waitForBet
+ PropertyChanges {
+ target: betContainer
+ opacity: 1
+ }
+ PropertyChanges {
+ target: welcomeText
+ text: "Please place your bet"
+ }
+ },
+ State {
+ name: "waitForAction"
+ when: controller.current.waitForAction
+ PropertyChanges {
+ target: welcomeText
+ text: "Hit or stand?"
+ }
+ PropertyChanges {
+ target: actionContainer
+ opacity: 1
+ }
+ },
+ State {
+ name: "win"
+ when: controller.current.win
+ PropertyChanges {
+ target: welcomeText
+ text: "You win!"
+ }
+ },
+ State {
+ name: "lose"
+ when: controller.current.loss
+ PropertyChanges {
+ target: welcomeText
+ text: "You lose..."
+ }
+ },
+ State {
+ name: "draw"
+ when: controller.current.draw
+ PropertyChanges {
+ target: welcomeText
+ text: "It's a draw."
+ }
+ },
+ State {
+ name: "game"
+ when: controller.current.game
+ PropertyChanges {
+ target: welcomeText
+ text: "Welcome"
+ }
+ },
+ State {
+ name: "default"
+ when: !controller.current.waitForBet
+ PropertyChanges {
+ target: betContainer
+ opacity: 0
+ }
+ }
+ ]
Text {
id: welcomeText
text: "Blackjack"
font.pixelSize: 24
- states: [
- State {
- name: "placeBets"
- when: controller.current.waitForBet
- PropertyChanges {
- target: welcomeText
- text: "Please place your bet"
- }
- },
- State {
- name: "game"
- when: controller.current.game
- PropertyChanges {
- target: welcomeText
- text: "Welcome"
- }
- }
- ]
+ height: 40
}
Rectangle {
color: "white"
- x: 100
- y: 100
+ height: 40
+ id: pointsContainer
+ anchors.top: welcomeText.bottom
Text {
color: "blue"
text: "You have " + controller.data.points + " points"
+ font.pixelSize: 24
}
}
+ Text {
+ id: handContainer
+ height: 30
+ font.pixelSize: 24
+ anchors.top: pointsContainer.bottom
+ color: "red"
+ text: "You: "+controller.data.myHand
+ }
+ Text {
+ id: dealerContainer
+ height: 30
+ font.pixelSize: 24
+ anchors.left: handContainer.right
+ anchors.top: handContainer.top
+ anchors.leftMargin: 10
+ text: "Dealer: "+controller.data.dealerHand
+ }
Rectangle {
color: "white"
- id: betEditBg
- x: 80
- y: 400
+ id: betContainer
+ anchors.top: handContainer.bottom
+ radius: 5
width: 100
- height: 20
+ height: 40
+ color: "#ffcc33"
+ opacity: Behavior { NumberAnimation { duration: 300; easing: "InOutQuad" } }
TextInput {
id: betEdit
color: "black"
- anchors.fill: parent
text: controller.data.pointsToBet
+ font.pixelSize: 24
+ anchors.fill: parent
+ horizontalAlignment: "AlignHCenter"
}
- states: [
- State {
- name: "placeBets"
- when: controller.current.waitForBet
- PropertyChanges {
- target: betEditBg
- color: "#ffcc33"
- opacity: 1
- }
- },
- State {
- name: "default"
- when: !controller.current.waitForBet
- PropertyChanges {
- target: betEditBg
- opacity: 0
+ Rectangle {
+ width: 100
+ height: betEdit.height
+ radius: 5
+ color: "blue"
+ anchors.left: betEdit.right
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: {
+ controller.data.pointsToBet = betEdit.text;
+ controller.events.bet.raise();
}
}
- ]
+ Text {
+ color: "#ffffcc"
+ text: "Bet"
+ font.weight: "Bold"
+ font.pixelSize: 18
+ anchors.fill: parent
+ horizontalAlignment: "AlignHCenter"
+ verticalAlignment: "AlignVCenter"
+ }
+ }
}
Rectangle {
- anchors.left: betEditBg.right
- anchors.top: betEditBg.top
- anchors.bottom: betEditBg.bottom
+ color: "white"
+ id: actionContainer
+ anchors.top: handContainer.bottom
+ radius: 5
width: 100
- color: "blue"
- MouseRegion {
+ height: 40
+ color: "#ffcc33"
+ opacity: 0
+ Rectangle {
+ id: hitButton
+ color: "green"
anchors.fill: parent
- onClicked: { controller.events.bet.raise(); }
+ opacity: Behavior { NumberAnimation { duration: 300; easing: "InOutQuad" } }
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: {
+ controller.events.hit.raise();
+ }
+ }
+ Text {
+ color: "#ffffcc"
+ text: "Hit"
+ anchors.fill: parent
+ horizontalAlignment: "AlignHCenter"
+ verticalAlignment: "AlignVCenter"
+ }
}
- Text {
- color: "yellow"
- text: "Bet"
+ Rectangle {
+ id: standButton
+ width: 100
+ height: hitButton.height
+ radius: 5
+ color: "#9966cc"
+ anchors.left: hitButton.right
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: {
+ controller.events.stand.raise();
+ }
+ }
+ Text {
+ color: "#ffffcc"
+ text: "Stand"
+ anchors.fill: parent
+ horizontalAlignment: "AlignHCenter"
+ verticalAlignment: "AlignVCenter"
+ }
}
}
diff --git a/examples/qml/blackjack/blackjack.scxml b/examples/qml/blackjack/blackjack.scxml
index ab1b9cd..0c32a3e 100644
--- a/examples/qml/blackjack/blackjack.scxml
+++ b/examples/qml/blackjack/blackjack.scxml
@@ -1,224 +1,196 @@
-<scxml
- xmlns="http://www.w3.org/2005/07/scxml"
- initial="root" profile="ecmascript">
- <datamodel>
+<scxml xmlns="http://www.w3.org/2005/07/scxml" initial="root" profile="ecmascript">
+ <datamodel>
<data id="points" expr="1000" />
<data id="pot" expr="0" />
<data id="pointsToBet" expr="0" />
- </datamodel>
+ <data id="myHand" expr="new Deck()" />
+ <data id="dealerHand" expr="new Deck()" />
+ <data id="availDeck" expr="new Deck()" />
+ </datamodel>
<script><![CDATA[
- var Suits = "CDHS";
- var Ranks = "-A23456789TJQK";
-
- function Card (r,s)
- {
- this.rank = r;
- this.suit = s;
- this.minValue = Math.min(r,10);
- this.toString = function() {
- return "" + Ranks[this.rank] + Suits[this.suit];
- };
-;
+ var Suits = "CDHS";
+ var Ranks = "-A23456789TJQK";
+
+ function Card (r,s)
+ {
+ this.rank = r;
+ this.suit = s;
+ this.minValue = Math.min(r,10);
+ }
+
+ Card.prototype.toString = function() {
+ return "" + Ranks[this.rank] + Suits[this.suit];
+ };
+
+ function Deck() {}
+ Deck.prototype =
+ {
+ draw: function() { return this.cards.pop(); scxml.notifyChange(this);},
+ cards: [],
+ reshuffle: function() {
+ this.clear ();
+ function randomSort(a,b) {
+ return Math.random() - 0.5;
}
- function Deck()
- {
- this.draw = function()
- {
- return this.cards.pop();
- };
- this.cards = new Array();
- this.reset = function()
- {
- this.clear ();
- for (var i=1; i <= 13; ++i)
- for (var j = 0; j < 4; ++j)
- this.cards.push(new Card(i,j));
- this.cards.sort(function (a,b)
- {
- return Math.random() * 3 - 1;
- });
- };
-
- this.clear = function()
- {
- this.cards = new Array;
- };
- this.evalMin = function ()
- {
- var minVal = 0;
- var cardCount = this.cards.length;
- for (c in this.cards) {
- minVal += this.cards[c].minValue;
- }
- if (cardCount > 4 && minVal < 22)
- minVal = 21;
- return minVal;
- };
-
- this.evalBest = function()
- {
- var bestVal = this.evalMin();
- if (bestVal > 21)
- return 0;
- else if (bestVal == 21)
- return bestVal;
-
- for (i in this.cards) {
- if (this.cards[i].rank == 1)
- {
- var v = bestVal + 10;
- if (v <= 21)
- bestVal = v;
- }
- }
- return bestVal;
-
- };
- this.toString = function()
- {
- var s = "";
- for (i in this.cards)
- s += this.cards[i].toString() + ":";
-
- return s;
- };
-
- this.drawFrom = function(d)
- {
- var c = d.draw ();
- this.cards.push(c);
-// updateDisplay ();
- };
+ for (var i=1; i <= 13; ++i)
+ for (var j = 0; j < 4; ++j)
+ this.cards.push(new Card(i,j));
+ this.cards.sort(randomSort);
+ },
+
+ clear: function() {
+ this.cards = [];
+ scxml.notifyChange(this);
+ },
+ evalMin: function () {
+ var minVal = 0;
+ var cardCount = this.cards.length;
+ for (c in this.cards) {
+ minVal += this.cards[c].minValue;
}
-
-
- function hitMe ()
- {
- myDeck.drawFrom (availDeck);
+ if (cardCount > 4 && minVal < 22)
+ minVal = 21;
+ return minVal;
+ },
+ evalBest: function() {
+ var bestVal = this.evalMin();
+ if (bestVal > 21)
+ return 0;
+ else if (bestVal == 21)
+ return bestVal;
+
+ for (i in this.cards) {
+ if (this.cards[i].rank == 1)
+ {
+ var v = bestVal + 10;
+ if (v <= 21)
+ bestVal = v;
+ }
}
+ return bestVal;
+
+ },
+ toString: function() {
+ return this.cards.join(' ');
+ },
+ drawFrom: function(d) {
+ this.cards.push(d.draw ());
+ scxml.notifyChange(this);
+ }
+ };
+
+ function hitMe ()
+ {
+ _data.myHand.drawFrom (_data.availDeck);
+ }
]]></script>
- <final id="exit" />
<state id="root" initial="newgame">
- <onentry>
- <script>
- var myDeck = new Deck;
- var dealerCards = new Deck;
- var availDeck = new Deck;
- </script>
-
- </onentry>
- <transition event="NEWGAME" target="newgame" />
- <state id="newgame">
- <transition target="newround" />
- </state>
- <state id="quitdlg">
- <transition event="YES" target="exit" />
- <transition event="NO" target="gamestate" />
- </state>
- <state id="game">
- <history type="deep" id="gamestate" />
- <transition event="EXIT" target="quitdlg" />
- <state id="newround">
<onentry>
- <assign dataid="pot" expr="0" />
- <script>
- availDeck.reset ();
- myDeck.clear ();
- dealerCards.clear();
- dealerCards.drawFrom(availDeck);
- hitMe ();
- hitMe ();
- </script>
+ <assign dataid="myHand" expr="new Deck()" />
+ <assign dataid="dealerHand" expr="new Deck()" />
+ <assign dataid="availDeck" expr="new Deck()" />
</onentry>
- <transition target="waitForBet" />
- </state>
- <state id="waitForBet">
- <transition event="BET" target="testCards" cond="parseInt(_data.pointsToBet) &lt;= _data.points">
- <assign dataid="pot" expr="_data.pointsToBet" />
- <assign dataid="points" expr="_data.points-_data.pot" />
- </transition>
- <transition event="BET" target="betTooHigh" cond="parseInt(_data.pointsToBet) &gt; _data.points">
- </transition>
- <transition event="SURRENDER" target="newround" />
- </state>
- <state id="betTooHigh">
- <transition event="OK" target="waitForBet" />
- <transition event="TIMEOUT" target="waitForBet" />
- <onentry>
- <send event="TIMEOUT" delay="1500ms" />
- </onentry>
- </state>
- <state id="testCards">
- <transition target="loss" cond="myDeck.evalBest() == 0" />
- <transition target="getDealerCards" cond="myDeck.evalBest() == 21" />
- <transition target="waitForAction" cond="myDeck.evalBest() %21 != 0" />
- </state>
-
- <state id="waitForAction">
- <transition event="HIT" target="testCards">
- <script>hitMe (); </script>
- </transition>
- <transition event="STAND" target="getDealerCards" />
- </state>
-
- <state id="getDealerCards">
- <onentry>
- <script><![CDATA[
- while (dealerCards.evalBest() > 0 && dealerCards.evalBest() < 17)
- dealerCards.drawFrom(availDeck);
- ]]></script>
- <raise event="DONE" />
- </onentry>
- <transition target="checkWinner" />
- </state>
-
- <state id="checkWinner">
+ <transition event="NEWGAME" target="newgame" />
+ <state id="newgame">
+ <transition target="newRound" />
+ </state>
+ <state id="quitdlg">
+ <transition event="YES" target="exit" />
+ <transition event="NO" target="gamestate" />
+ </state>
+ <state id="game">
+ <history type="deep" id="gamestate" />
+ <transition event="EXIT" target="quitdlg" />
+ <state id="newRound">
+ <onentry>
+ <assign dataid="pot" expr="0" />
+ <script>
+ _data.availDeck.reshuffle ();
+ _data.myHand.clear ();
+ _data.dealerHand.clear();
+ _data.dealerHand.drawFrom(_data.availDeck);
+ hitMe ();
+ hitMe ();
+ </script>
+ </onentry>
+ <transition target="waitForBet" />
+ </state>
+ <state id="waitForBet">
+ <transition event="BET" target="testCards" cond="parseInt(_data.pointsToBet) &lt;= _data.points">
+ <assign dataid="pot" expr="_data.pointsToBet" />
+ <assign dataid="points" expr="_data.points-_data.pot" />
+ </transition>
+ <transition event="BET" target="betTooHigh" cond="parseInt(_data.pointsToBet) &gt; _data.points" />
+ <transition event="SURRENDER" target="newRound" />
+ </state>
+ <state id="betTooHigh">
+ <transition event="OK" target="waitForBet" />
+ <transition event="TIMEOUT" target="waitForBet" />
+ <onentry>
+ <send event="TIMEOUT" delay="1500ms" />
+ </onentry>
+ </state>
+ <state id="testCards">
+ <transition target="loss" cond="_data.myHand.evalBest() == 0" />
+ <transition target="getdealerHand" cond="_data.myHand.evalBest() == 21" />
+ <transition target="waitForAction" cond="_data.myHand.evalBest() %21 != 0" />
+ </state>
- <onentry>
- <assign location="_data.diff" expr="myDeck.evalBest() - dealerCards.evalBest()" />
- </onentry>
+ <state id="waitForAction">
+ <transition event="HIT" target="testCards">
+ <script>hitMe (); </script>
+ </transition>
+ <transition event="STAND" target="getdealerHand" />
+ </state>
- <transition cond="diff&gt;0" target="win" />
- <transition cond="diff&lt;0" target="loss" />
- <transition cond="diff==0" target="draw" />
- </state>
- <state id="endGame">
- <invoke type="q-bindings"><content>[[welcomeLabel,"text","Game Over"]]</content></invoke>
- <transition event="TIMEOUT" target="newgame" />
- <onentry>
- <send event="TIMEOUT" delay="3s" />
- </onentry>
- </state>
- <state id="endRound">
- <invoke type="q-bindings"><content>[[newRoundButton,"enabled",true]]</content></invoke>
- <transition event="NEWROUND" target="newround" />
- <transition event="TIMEOUT" target="newround" />
- <onentry>
- <send event="TIMEOUT" delay="3s" />
- </onentry>
+ <state id="getdealerHand">
+ <onentry>
+ <script><![CDATA[
+ while (_data.dealerHand.evalBest() > 0 && _data.dealerHand.evalBest() < 17)
+ _data.dealerHand.drawFrom(_data.availDeck);
+ ]]></script>
+ <raise event="DONE" />
+ </onentry>
+ <transition target="checkWinner" />
+ </state>
- <state id="win">
+ <state id="checkWinner">
+ <onentry>
+ <assign location="_data.diff" expr="_data.myHand.evalBest() - _data.dealerHand.evalBest()" />
+ </onentry>
+ <transition cond="_data.diff &gt; 0" target="win" />
+ <transition cond="_data.diff &lt; 0" target="loss" />
+ <transition cond="_data.diff==0" target="draw" />
+ </state>
+ <state id="endGame">
+ <transition event="TIMEOUT" target="newgame" />
<onentry>
- <assign dataid="points" expr="Math.floor(_data.points) + Math.floor(_data.pot) * 2" />
+ <send event="TIMEOUT" delay="3s" />
</onentry>
- </state>
- <state id="loss">
- <invoke type="q-bindings"><content>[[welcomeLabel,"text","You Lost..."]]</content></invoke>
- <transition cond="points == 0" target="endGame" />
+ </state>
+ <state id="endRound">
+ <transition event="newRound" target="newRound" />
+ <transition event="TIMEOUT" target="newRound" />
+ <onentry>
+ <send event="TIMEOUT" delay="3s" />
+ </onentry>
+
+ <state id="win">
+ <onentry>
+ <assign dataid="points" expr="Math.floor(_data.points) + Math.floor(_data.pot) * 2" />
+ </onentry>
+ </state>
+ <state id="loss">
+ <transition cond="_data.points == 0" target="endGame" />
</state>
<state id="draw">
- <invoke type="q-bindings"><content>[[welcomeLabel,"text","You It's a draw."]]</content></invoke>
- <onentry>
- <assign dataid="points" expr="Math.floor(_data.points) + Math.floor(pot)" />
- </onentry>
+ <onentry>
+ <assign dataid="points" expr="Math.floor(_data.points) + Math.floor(_data.pot)" />
+ </onentry>
</state>
</state>
</state>
-
</state>
-
+ <final id="exit" />
</scxml>
-
-
-
diff --git a/examples/qml/blackjack/main.cpp b/examples/qml/blackjack/main.cpp
index dd7777a..87639d6 100644
--- a/examples/qml/blackjack/main.cpp
+++ b/examples/qml/blackjack/main.cpp
@@ -48,6 +48,7 @@
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
+ qsrand(QDateTime::currentDateTime().toTime_t());
QmlView view(NULL);
QmlComponent component(view.engine(), "blackjack.qml");