dabo Commit
Revision 3562
Date: 2007-10-24 09:13:30 -0700 (Wed, 24 Oct 2007)
Author: Ed
Trac: http://svn.dabodev.com/trac/dabo/changeset/3562
Changed:
_U trunk/demo/samples/__init__.py
UU trunk/demo/samples/bubblet.py
A trunk/demo/samples/games/Montana.py
UU trunk/demo/samples/games/__init__.py
_U trunk/demo/samples/games/bubblet/BubbleBizobj.py
_U trunk/demo/samples/games/bubblet/BubblePanel.py
_U trunk/demo/samples/games/bubblet/BubbletForm.py
_U trunk/demo/samples/games/bubblet/StatsForm.py
_U trunk/demo/samples/games/bubblet/__init__.py
A trunk/demo/samples/games/cardlib.py
A trunk/demo/samples/montana.py
Log:
Added Montana to the demo games. Set the svn:eol-style for these newly-added
files.
Diff:
Property changes on: trunk/demo/samples/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: trunk/demo/samples/bubblet.py
===================================================================
--- trunk/demo/samples/bubblet.py 2007-10-24 15:43:01 UTC (rev 3561)
+++ trunk/demo/samples/bubblet.py 2007-10-24 16:13:30 UTC (rev 3562)
@@ -12,9 +12,9 @@
sz = self.Sizer = dabo.ui.dSizer("v")
sz.appendSpacer(40)
- lbl = dabo.ui.dLabel(self, Caption="Bubblet is a fun and
somewhat addictive game.\nFor instructions, please see the Overview tab.")
+ lbl = dabo.ui.dLabel(self, Caption="Bubblet is a fun and
somewhat addictive game.\n\nFor instructions, please see the Overview tab.")
sz.append(lbl, halign="center")
- sz.appendSpacer(20)
+ sz.appendSpacer(30)
btn = dabo.ui.dButton(self, Caption="Run the Bubblet Game",
OnHit=self.runGame)
sz.append(btn, halign="center")
Property changes on: trunk/demo/samples/bubblet.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/demo/samples/games/Montana.py
===================================================================
--- trunk/demo/samples/games/Montana.py (rev 0)
+++ trunk/demo/samples/games/Montana.py 2007-10-24 16:13:30 UTC (rev 3562)
@@ -0,0 +1,595 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import random
+import dabo
+from dabo.dLocalize import _
+dabo.ui.loadUI("wx")
+import cardlib
+
+
+class MontanaDeck(cardlib.PokerDeck):
+# def passHoverEvent(self, evt):
+# self.board.onHover(evt)
+#
+# def passEndHoverEvent(self, evt):
+# self.board.endHover(evt)
+
+
+ def appendCard(self, suit, rank):
+ newCard = super(MontanaDeck, self).appendCard(suit, rank)
+# newCard._hover = True
+# newCard.onHover = self.passHoverEvent
+# newCard.endHover = self.passEndHoverEvent
+ newCard.bindEvent(dabo.dEvents.MouseLeftDown,
self.board.onCardMDown)
+ newCard.bindEvent(dabo.dEvents.MouseLeftUp,
self.board.onCardMUp)
+
+ def createDeck(self):
+ super(MontanaDeck, self).createDeck()
+ self.faceUpAll()
+ self.aces = []
+ for card in self:
+ if card.Rank == 1:
+ self.aces.append(card)
+
+
+class CardTimer(dabo.ui.dTimer):
+ def start(self, *args, **kwargs):
+ self.target._cardTimerFirstHit = False
+ super(CardTimer, self).start(*args, **kwargs)
+
+ def onHit(self, evt):
+ flashCards = self.target.flashCards
+ if not flashCards:
+ self.stop()
+ else:
+ for card in flashCards:
+ card.Visible = not card.Visible
+ card.refresh()
+ self.start(100)
+ self.target._cardTimerFirstHit = True
+
+
+class Board(dabo.ui.dPanel):
+ def afterInit(self):
+ self.DeckDirectory = self.Form.getDeckDir()
+ self.BackColor = "olivedrab"
+ self._priorHandScore = 0
+ self._score = 0
+ self.isStuck = True
+ # Controls card flashing
+ self.cardTimer = CardTimer()
+ self.cardTimer.target = self
+ self._cardTimerFirstHit = False
+ self.flashCards = []
+ # Flag that indicates we need to resize the cards
+ self.needResize = False
+ self.gridSizer = None
+ # Border around the cards
+ self._border = 15
+ # Create the deck
+ self.deck = MontanaDeck(self)
+ self.createSizer()
+
+
+ def createSizer(self):
+ if not self.Sizer:
+ self.Sizer = dabo.ui.dSizer("v")
+ self.Sizer.DefaultBorder = self._border
+ self.Sizer.DefaultBorderAll = True
+ if self.gridSizer:
+ self.Sizer.remove(self.gridSizer)
+ for card in self.deck:
+ self.gridSizer.remove(card)
+ self.gridSizer.release()
+ self.gridSizer = dabo.ui.dGridSizer(MaxCols=13, HGap=2, VGap=2)
+ self.Sizer.append1x(self.gridSizer)
+
+
+ def newGame(self):
+ self.Redeals = self.Form.PreferenceManager.redeals
+ self._priorHandScore = 0
+ self._score = 0
+
+ # Contains the current layout of the cards.
+ self.cardLayout = ()
+ # This holds the history, enabling undo. Most recent positions
+ # are at the end.
+ self.historyStack = []
+ # This holds the redo stack
+ self.redoStack = []
+ # Clear the 'scored' attribute for the cards
+ for card in self.deck:
+ card.scored = False
+ random.shuffle(self.deck)
+ self.createSizer()
+ self.gridSizer.appendItems(self.deck)
+ self.updateCardLayout()
+ self.updateStatus()
+
+
+ def redeal(self):
+ """ Gather all the non-scored cards, shuffle 'em,
+ and place them back into the layout.
+ """
+ sz = self.gridSizer
+ redo = []
+ for card in self.deck:
+ if not card.scored:
+ sz.remove(card)
+ redo.append(card)
+ random.shuffle(redo)
+ sz.appendItems(redo)
+ self.Redeals -= 1
+ self.historyStack = []
+ self.redoStack = []
+# self.cardLayout = ()
+ self.updateCardLayout(False)
+ self.updateStatus()
+
+
+ def cardClick(self, card):
+ """Called from a card when it is clicked."""
+ rank, suit = card.Rank, card.Suit
+
+ if rank == 1:
+ # Ace; nothing to do
+ return
+ if rank == 2:
+ # See if there are any aces in the first column.
+ for row in range(4):
+ firstColCard =
self.gridSizer.getItemByRowCol(row, 0)
+ if firstColCard is not None:
+ if firstColCard.Rank == 1:
+ self.switchCards(card,
firstColCard)
+ self.updateStatus()
+ break
+ else:
+ # See if the card below it in sequence has an ace to
its right
+ prevCard = self.getCard(rank-1, suit)
+ rCard = self.gridSizer.getNeighbor(prevCard, "right")
+ if rCard is not None:
+ if rCard.Rank == 1:
+ # We can move it
+ self.switchCards(card, rCard)
+ self.updateStatus()
+
+
+# def onHover(self, evt):
+# if evt is None:
+# return
+# self.onCardMDown(evt)
+# def endHover(self, evt):
+# if evt is None:
+# return
+# self.onCardMUp(evt)
+
+ def onCardMDown(self, evt):
+ card = evt.EventObject
+ rank, suit = card.Rank, card.Suit
+ aceClicked = (rank == 1)
+ if aceClicked:
+ # Ace; flash the card that goes in this slot
+ leftCard = self.gridSizer.getNeighbor(card, "left")
+ if leftCard is None:
+ # We're at the left column: flash all the 2's:
+ targets = []
+ for suit in "SCDH":
+ targets.append(self.getCard(2, suit))
+ self.flashCards = targets
+ self.cardTimer.start(1)
+ return
+ else:
+ rank, suit = leftCard.Rank, leftCard.Suit
+ if rank == 1:
+ # Another ace; do nothing
+ return
+
+
+ if rank and suit:
+ flashAll = aceClicked or not
self.Form.getOnlyFlashAces()
+ # Flash the card next in sequence
+ target = self.getCard(rank+1, suit)
+ if target and flashAll:
+ self.flashCards = [target,]
+ if aceClicked:
+ self.cardTimer.start(1)
+ else:
+ # Add the card before in sequence also
+ target = self.getCard(rank-1, suit)
+ if (target.Rank > 1) and flashAll:
+ self.flashCards.append(target)
+ # Need to delay the start of the blinking, so
that the user has enough
+ # time to finish the click to move the card
+ self.cardTimer.start(500)
+
+
+ def onCardMUp(self, evt):
+ card = evt.EventObject
+ if card is None:
+ return
+ # Stop any flashing:
+ self.cardTimer.stop()
+ for fc in self.flashCards:
+ fc.Visible = True
+ self.flashCards = []
+
+ if not self._cardTimerFirstHit:
+ # user wasn't holding down the mouse button, so process
the click
+ self.cardClick(card)
+
+
+ def updateStatus(self):
+ """Several things need to be determined:
+ - update the score and the scored property of the cards
+ - xmark and count any dead aces
+ - if all aces are dead, enable re-deal button
+ """
+ # Calculate the score
+ self._score = 0
+ for row in range(4):
+ start = row*13
+ cards = self.cardLayout[start:start+12]
+ if cards[0].Rank == 2:
+ # There is scoring in this row
+ suit = cards[0].Suit
+ seq = 1
+ for card in cards:
+ if card.Suit == suit:
+ if card.Rank == seq+1:
+ card.scored = True
+ self._score += 1
+ seq += 1
+ else:
+ break
+ else:
+ break
+
+ # update the form
+ self.Form.updateScore()
+ deckdir = self.DeckDirectory
+ # Mark the dead aces. These are all the aces to the right
+ # of Kings.
+ sz = self.gridSizer
+ for ace in self.deck.aces:
+ ace.AlternatePicture = "%s/blank" % deckdir
+ dead = 0
+ self.isStuck = False
+ for suit in "SHDC":
+ king = self.getCard(13, suit)
+ rtCard = sz.getNeighbor(king, "right")
+ while (rtCard is not None) and (rtCard.Rank == 1):
+ rtCard.AlternatePicture = "%s/x" % deckdir
+ dead += 1
+ rtCard = sz.getNeighbor(rtCard, "right")
+ if dead == 4:
+ # No more moves possible!
+ self.stuck()
+
+ # Update the redeal button:
+ self.Form.updateRedealCaption()
+
+ if self.Application.Platform == "Win":
+ # Windows needs to be refreshed, or card pix are wrong,
but don't do this on
+ # Mac or Linux because it isn't necessary and it adds a
noticeable lag.
+ self.refresh()
+
+
+ def stuck(self, _forceWin=False, _forceLose=False):
+ """Called when no more moves are possible. If there
+ are re-deals left, enable the re-deal button. Otherwise,
+ flash 'em the Game Over message.
+ """
+ self.isStuck = True
+ # see if we've completed the deck
+ outOfPlace = [cd for cd in self.deck
+ if cd.Rank != 1 and not cd.scored]
+ if not outOfPlace or _forceWin:
+ self._priorHandScore += self._score
+ msg = "Congratulations! You completed the board!\n\n" +
\
+ "You have earned an extra re-deal, and
the game continues!"
+ dabo.ui.exclaim(msg)
+ # We have to add 2 here, since the redeal count will be
decreased
+ # by one when we call redeal().
+ self.Redeals += 2
+ # Mark all the cards as not 'scored' so that they are
all shuffled.
+ self.setAll("scored", False)
+ self.redeal()
+ return
+ if self.Redeals < 1 or _forceLose:
+ msg = "Game over! Your final score was %s" %
self.TotalScore
+ dabo.ui.callAfter(dabo.ui.info, msg)
+ else:
+ self.Form.showRedeal()
+
+
+ def switchCards(self, c1, c2):
+ """Change the position of the two cards."""
+ sz = self.gridSizer
+ c1.lockDisplay()
+ c2.lockDisplay()
+ row1, col1 = sz.getGridPos(c1)
+ row2, col2 = sz.getGridPos(c2)
+ # Move the first out of the way
+ tempRow, tempCol = sz.findFirstEmptyCell()
+ sz.moveObject(c1, tempRow, tempCol, delay=True)
+ # Now move the second to the first position
+ sz.moveObject(c2, row1, col1, delay=True)
+ # Now move the first to the second position
+ sz.moveObject(c1, row2, col2)
+ # Since this is a move forward, clear the redo stack
+ self.redoStack = []
+ # Update the card layout and history
+ self.updateCardLayout()
+ dabo.ui.callAfter(c1.unlockDisplay)
+ dabo.ui.callAfter(c2.unlockDisplay)
+
+
+ def updateCardLayout(self, addToHistory=True):
+ if addToHistory:
+ if self.cardLayout:
+ # Push the old layout onto the history stack
+ self.historyStack.append(self.cardLayout)
+ # Set the new card layout
+ layout = []
+ sz = self.gridSizer
+ for row in range(4):
+ for col in range(13):
+ layout.append(sz.getItemByRowCol(row, col))
+ self.cardLayout = tuple(layout)
+
+
+ def undo(self):
+ self.undoRedo(self.historyStack, self.redoStack)
+
+
+ def redo(self):
+ self.undoRedo(self.redoStack, self.historyStack)
+
+
+ def undoRedo(self, fromStack, toStack):
+ if fromStack:
+ turn = fromStack.pop()
+ toStack.append(self.cardLayout)
+ self.createSizer()
+ self.gridSizer.appendItems(turn)
+ self.layout()
+ self.updateCardLayout(False)
+ self.updateStatus()
+
+
+ def getCard(self, rank, suit):
+ """Returns a reference to the card that has the specified
+ rank and suit.
+ """
+ # Updated to use RegIDs.
+ id = "%s%s" % (suit, rank)
+ ret = self.Form.getObjectByRegID(id)
+ if ret is None:
+ try:
+ ret = [cd for cd in self.deck
+ if (cd.Rank == rank) and
(cd.Suit == suit)][0]
+ except:
+ ret = None
+ return ret
+
+
+ def _getRedeals(self):
+ if hasattr(self, "_redeals"):
+ v = self._redeals
+ else:
+ v = self._redeals = self.Form.PreferenceManager.redeals
+ return v
+
+ def _setRedeals(self, val):
+ self._redeals = val
+
+
+ def _getScore(self):
+ return self._score
+
+ def _setScore(self, val):
+ self._score = val
+
+
+ def _getTotScore(self):
+ return self._priorHandScore + self._score
+
+
+ Redeals = property(_getRedeals, _setRedeals, None,
+ _("Number of remaining redeals (int)") )
+
+ Score = property(_getScore, _setScore, None,
+ _("Score of the game for the current hand (int)") )
+
+ TotalScore = property(_getTotScore, None, None,
+ _("Total score of the game, including prior hands
(int)") )
+
+
+
+class MontanaForm(dabo.ui.dForm):
+ def afterInit(self):
+ self.Centered = True
+ self.Caption = "Montana"
+ pfm = self.PreferenceManager
+ if not isinstance(pfm.redeals, (int, long)):
+ pfm.redeals = 2
+ if not isinstance(pfm.flashOnlyAces, bool):
+ pfm.flashOnlyAces = False
+ if not isinstance(pfm.smallDeck, bool):
+ pfm.smallDeck = False
+
+ # Add the board, score display and re-deal button
+ self.gameBoard = Board(self)
+ self.Sizer.append1x(self.gameBoard)
+ self.layout()
+ self.fitToSizer(80, 30)
+ self.fillMenu()
+ dabo.ui.callAfter(self.startGame)
+
+
+ def fillMenu(self):
+ iconPath = "themes/tango/16x16"
+
+ mb = self.MenuBar
+ fileMenu = mb.getMenu(_("File"))
+ fileMenu.prependSeparator()
+ fileMenu.prepend(_("&New Game"), HotKey="Ctrl+N", help=_("Start
a new game"),
+ OnHit=self.onNewGame,
bmp="%s/actions/document-new.png" % iconPath)
+ helpMenu = mb.getMenu(_("Help"))
+ helpMenu.append(_("&How to Play"), HotKey="Ctrl+I",
help=_("Rules of the game"),
+ OnHit=self.onRules, bmp="%s/apps/help-browser.png" %
iconPath)
+
+ tb = self.ToolBar = dabo.ui.dToolBar(self, ShowCaptions=True)
## Mac has a resize problem otherwise.
+
+ if self.Application.Platform == "Mac":
+ # Toolbar looks better with larger icons on Mac. In
fact, I believe HIG
+ # recommends 32x32 for Mac Toolbars.
+ iconSize = (32, 32)
+ else:
+ iconSize = (22, 22)
+ tb.SetToolBitmapSize(iconSize) ## need to abstract in dToolBar!
+ iconPath = "themes/tango/%sx%s" % iconSize
+
+ tb.appendButton("New", pic="%s/actions/document-new.png" %
iconPath,
+ toggle=False, OnHit=self.onNewGame, tip="New
Game",
+ help="Start a new game")
+ tb.appendButton("Preferences",
pic="%s/categories/preferences-system.png" % iconPath,
+ toggle=False, OnHit=self.onEditPreferences,
+ tip="Preferences", help="Edit preferences")
+ tb.appendSeparator()
+
+ btn = self.btnRedeal = tb.appendControl(dabo.ui.dButton(tb,
Enabled=False))
+ btn.Height += 6
+ self.updateRedealCaption()
+ self.btnRedeal.bindEvent(dabo.dEvents.Hit, self.onRedeal)
+ tb.appendSeparator()
+
+ tb.appendControl(dabo.ui.dLabel(tb, Caption="Hand Score:",
Width=50, Height=20))
+ self.txtHandScore = tb.appendControl(dabo.ui.dTextBox(tb,
Value=0,
+ FontBold=True, Width=40, ReadOnly=True,
Alignment="Right"))
+ tb.appendSeparator()
+ tb.appendControl(dabo.ui.dLabel(tb, Caption="Game Score:",
Width=50, Height=20))
+ self.txtGameScore = tb.appendControl(dabo.ui.dTextBox(tb,
Value=0,
+ FontBold=True, Width=40, ReadOnly=True,
Alignment="Right"))
+
+
+ def updateRedealCaption(self):
+ btn = self.btnRedeal
+ btn.Caption = "Redeals left: %s" % self.gameBoard.Redeals
+ btn.Width = dabo.ui.fontMetric(btn.Caption, wind=btn)[0] + 24
+ btn.Enabled = (self.gameBoard.isStuck and
self.gameBoard.Redeals > 0)
+
+
+ def getOnlyFlashAces(self):
+ return self.PreferenceManager.flashOnlyAces
+
+
+ def getDeckDir(self):
+ ret = "cards/large"
+ if self.PreferenceManager.smallDeck:
+ ret = "cards/small"
+ return ret
+
+
+ def onEditUndo(self, evt):
+ self.gameBoard.undo()
+
+
+ def onEditRedo(self, evt):
+ self.gameBoard.redo()
+
+
+ def onEditPreferences(self, evt):
+ """Create a dialog to edit preferences."""
+ xml = self.getPrefControlXML()
+ class MontanaPrefDialog(dabo.ui.dOkCancelDialog):
+ def addControls(self):
+ self.prf = self.Parent.PreferenceManager
+ ctls = self.addObject(xml)
+ self.Sizer.append1x(ctls, border=10)
+ self.Sizer.appendSpacer(20)
+ self.update()
+
+ prf = self.PreferenceManager
+ # Save the card size. If it changes, we need to create a new
board
+ small = prf.smallDeck
+ prf.AutoPersist = False
+ dlg = MontanaPrefDialog(self, Caption="Montana Prefs")
+ dlg.show()
+ if dlg.Accepted:
+ prf.persist()
+ if prf.smallDeck != small:
+ msg = """You must quit and restart the game for
the
+ card size changes to take
effect""".replace("\t", "")
+ dabo.ui.info(msg, title="Card Size Changed")
+ else:
+ prf.flushCache()
+ prf.AutoPersist = True
+
+
+ def onRules(self, evt):
+ win = dabo.ui.dForm(self, Caption="Montana Rules",
Centered=True)
+ pnl = dabo.ui.dScrollPanel(win)
+ win.Sizer.append1x(pnl)
+ txt = dabo.ui.dLabel(pnl, Caption=helpText)
+ sz = dabo.ui.dSizer("v")
+ sz.append1x(txt, border=10)
+ pnl.Sizer = sz
+ btn = dabo.ui.dButton(win, Caption="OK")
+ btn.bindEvent(dabo.dEvents.Hit, win.close)
+ win.Sizer.append(btn, border=10, halign="right")
+ win.layout()
+ pnl.fitToSizer()
+ win.Visible = True
+
+
+ def onNewGame(self, evt):
+ # Check for a game in progress.
+ if self.gameBoard.historyStack and (not self.gameBoard.isStuck
or self.gameBoard.Redeals):
+ if not dabo.ui.areYouSure(message="Your game is not
over. Are " +
+ "you sure you want to end it and start
a new game?"):
+ return
+ self.startGame()
+
+
+ def startGame(self):
+ self.gameBoard.newGame()
+ self.updateRedealCaption()
+
+
+ def showRedeal(self):
+ self.btnRedeal.Enabled = True
+
+
+ def onRedeal(self, evt):
+ self.gameBoard.redeal()
+ self.btnRedeal.Enabled = False
+ self.updateRedealCaption()
+
+
+ def updateScore(self):
+ self.txtHandScore.Value = self.gameBoard.Score
+ self.txtGameScore.Value = self.gameBoard.TotalScore
+ self.layout()
+
+
+ def getPrefControlXML(self):
+ return """<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<dPanel classID="408701584" BorderColor="(0, 0, 0)" sizerInfo="{}"
Name="dPanel" Buffered="False" code-ID="dPanel-top" ForeColor="(0, 0, 0)"
designerClass="path://montanaPrefs.cdxml" BorderWidth="0" BackColor="(221, 221,
221)" BorderStyle="Default" ToolTipText="None" BorderLineStyle="Solid"
savedClass="True">
+ <dGridSizer classID="408701584-408700624" HGap="3" Rows="3"
designerClass="LayoutGridSizer" VGap="3" MaxDimension="r" Columns="2">
+ <dLabel classID="408701584-408656304" BorderColor="(0, 0, 0)"
FontBold="False" Name="dLabel" FontFace="Lucida Grande" sizerInfo="{'RowSpan':
1, 'RowExpand': False, 'ColSpan': 1, 'Proportion': 0, 'HAlign': 'Right',
'ColExpand': False, 'VAlign': 'Middle', 'Expand': False}" rowColPos="(0, 0)"
Caption="Number of Redeals:" ForeColor="(0, 0, 0)" designerClass="controlMix"
BorderWidth="0" BackColor="(221, 221, 221)" FontSize="13" BorderStyle="Default"
ToolTipText="None" BorderLineStyle="Solid" FontItalic="False"
FontUnderline="False"></dLabel>
+ <dSpinner classID="408701584-408656560" BorderColor="(0, 0, 0)"
FontBold="False" Name="dSpinner" FontFace="Lucida Grande"
sizerInfo="{'RowSpan': 1, 'RowExpand': False, 'ColSpan': 1, 'Proportion': 0,
'HAlign': 'Left', 'ColExpand': True, 'VAlign': 'Top', 'Expand': False}"
rowColPos="(0, 1)" FontUnderline="False" ForeColor="(0, 0, 0)"
DataSource="self.Form.prf" designerClass="controlMix" BorderWidth="0"
BackColor="(221, 221, 221)" FontSize="13" BorderStyle="Default"
ToolTipText="None" BorderLineStyle="Solid" FontItalic="False"
DataField="redeals"></dSpinner>
+ <dLabel classID="408701584-408773008" BorderColor="(0, 0, 0)"
FontBold="False" Name="dLabel1" FontFace="Lucida Grande" sizerInfo="{'RowSpan':
1, 'RowExpand': False, 'ColSpan': 1, 'Proportion': 0, 'HAlign': 'Right',
'ColExpand': False, 'VAlign': 'Middle', 'Expand': False}" rowColPos="(1, 0)"
Caption="Only flash empty spaces?" ForeColor="(0, 0, 0)"
designerClass="controlMix" BorderWidth="0" BackColor="(221, 221, 221)"
FontSize="13" BorderStyle="Default" ToolTipText="None" BorderLineStyle="Solid"
FontItalic="False" FontUnderline="False"></dLabel>
+ <dCheckBox classID="408701584-408811504" BorderColor="(0, 0,
0)" FontBold="False" DataField="flashOnlyAces" Name="dCheckBox"
FontFace="Lucida Grande" sizerInfo="{'RowSpan': 1, 'RowExpand': False,
'ColSpan': 1, 'Proportion': 0, 'HAlign': 'Left', 'ColExpand': True, 'VAlign':
'Top', 'Expand': True}" rowColPos="(1, 1)" Caption="" ForeColor="(0, 0, 0)"
DataSource="self.Form.prf" designerClass="controlMix" BorderWidth="0"
BackColor="(221, 221, 221)" FontSize="13" BorderStyle="Default"
ToolTipText="None" BorderLineStyle="Solid" FontItalic="False"
FontUnderline="False"></dCheckBox>
+ <dCheckBox classID="408701584-430021296" BorderColor="(0, 0,
0)" FontBold="False" DataField="smallDeck" Name="dCheckBox1" FontFace="Lucida
Grande" sizerInfo="{'RowSpan': 1, 'RowExpand': False, 'ColSpan': 1,
'Proportion': 0, 'HAlign': 'Left', 'ColExpand': True, 'VAlign': 'Top',
'Expand': True}" rowColPos="(2, 1)" Caption="" ForeColor="(0, 0, 0)"
DataSource="self.Form.prf" designerClass="controlMix" BorderWidth="0"
BackColor="(221, 221, 221)" FontSize="13" BorderStyle="Default"
ToolTipText="None" BorderLineStyle="Solid" FontItalic="False"
FontUnderline="False"></dCheckBox>
+ <dLabel classID="408701584-430460656" BorderColor="(0, 0, 0)"
FontBold="False" Name="dLabel2" FontFace="Lucida Grande" sizerInfo="{'RowSpan':
1, 'RowExpand': False, 'ColSpan': 1, 'Proportion': 0, 'HAlign': 'Right',
'ColExpand': False, 'VAlign': 'Middle', 'Expand': False}" rowColPos="(2, 0)"
Caption="Use small cards" ForeColor="(0, 0, 0)" designerClass="controlMix"
BorderWidth="0" BackColor="(221, 221, 221)" FontSize="13" BorderStyle="Default"
ToolTipText="None" BorderLineStyle="Solid" FontItalic="False"
FontUnderline="False"></dLabel>
+ </dGridSizer>
+</dPanel>"""
+
+
+if __name__ == "__main__":
+ app = dabo.dApp(MainFormClass=MontanaForm)
+ app.BasePrefKey = "demo.games.montana"
+ app.setAppInfo("appName", "Montana")
+ app.start()
+
Property changes on: trunk/demo/samples/games/Montana.py
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:eol-style
+ native
Modified: trunk/demo/samples/games/__init__.py
===================================================================
--- trunk/demo/samples/games/__init__.py 2007-10-24 15:43:01 UTC (rev
3561)
+++ trunk/demo/samples/games/__init__.py 2007-10-24 16:13:30 UTC (rev
3562)
@@ -1 +1,2 @@
import bubblet
+from Montana import MontanaForm
Property changes on: trunk/demo/samples/games/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Property changes on: trunk/demo/samples/games/bubblet/BubbleBizobj.py
___________________________________________________________________
Name: svn:eol-style
+ native
Property changes on: trunk/demo/samples/games/bubblet/BubblePanel.py
___________________________________________________________________
Name: svn:eol-style
+ native
Property changes on: trunk/demo/samples/games/bubblet/BubbletForm.py
___________________________________________________________________
Name: svn:eol-style
+ native
Property changes on: trunk/demo/samples/games/bubblet/StatsForm.py
___________________________________________________________________
Name: svn:eol-style
+ native
Property changes on: trunk/demo/samples/games/bubblet/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/demo/samples/games/cardlib.py
===================================================================
--- trunk/demo/samples/games/cardlib.py (rev 0)
+++ trunk/demo/samples/games/cardlib.py 2007-10-24 16:13:30 UTC (rev 3562)
@@ -0,0 +1,159 @@
+# -*- coding: utf-8 -*-
+import dabo
+dabo.ui.loadUI("wx")
+from dabo.dLocalize import _
+
+
+class Card(dabo.ui.dBitmap):
+ """Class representing an individual playing card."""
+
+ def updPic(self):
+ """Sets the Picture property for this card to match
+ its Suit and Rank.
+ """
+ if not self.FaceUp or not self.Rank or not self.Suit:
+ # Card isn't set yet, or card is face-down:
+ pic = "%s/back" % self.Parent.DeckDirectory
+ else:
+ if self.AlternatePicture:
+ # The game has set an alternate pic for the card
+ pic = self.AlternatePicture
+ else:
+ rank = self.Rank
+ suit = self.Suit.lower()
+ pic = "%s/%s%s" % (self.Parent.DeckDirectory,
suit, str(rank))
+ self.Picture = pic
+
+
+ def _getDesc(self):
+ rank = self.Rank
+ suit = self.Suit
+ if suit[0] == "J":
+ ret = "Joker"
+ else:
+ if rank == 1:
+ ret = "Ace"
+ elif rank == 11:
+ ret = "Jack"
+ elif rank == 12:
+ ret = "Queen"
+ elif rank == 13:
+ ret = "King"
+ else:
+ ret = str(rank)
+ suitNames = {"S" : "Spades", "D" : "Diamonds", "H" :
"Hearts", "C" : "Clubs"}
+ ret += " of %s" % suitNames[suit]
+ return ret
+
+
+ def _getAlternatePicture(self):
+ if hasattr(self, "_alternatePicture"):
+ v = self._alternatePicture
+ else:
+ v = self._alternatePicture = None
+ return v
+
+ def _setAlternatePicture(self, val):
+ self._alternatePicture = val
+ self.updPic()
+
+
+ def _getFaceUp(self):
+ if hasattr(self, "_faceUp"):
+ v = self._faceUp
+ else:
+ v = self._faceUp = False
+ return v
+
+ def _setFaceUp(self, val):
+ if self.FaceUp != val:
+ self._faceUp = bool(val)
+ self.updPic()
+
+
+ def _getRank(self):
+ if hasattr(self, "_rank"):
+ v = self._rank
+ else:
+ v = self._rank = None
+ return v
+
+ def _setRank(self, val):
+ if self.Rank != val:
+ self._rank = val
+ self.updPic()
+
+
+ def _getSuit(self):
+ if hasattr(self, "_suit"):
+ v = self._suit
+ else:
+ v = self._suit = None
+ return v
+
+ def _setSuit(self, val):
+ suit = val[0].upper()
+ if self.Suit != suit:
+ if suit in ("H", "D", "S", "C"):
+ self._suit = suit
+ self.updPic()
+
+
+ AlternatePicture = property(_getAlternatePicture, _setAlternatePicture,
None,
+ _("Alternate picture to show on face of card,
overriding default behavior."))
+
+ Description = property(_getDesc, None, None,
+ _("Descriptive name for this card, such as 'King of
Clubs' (str)") )
+
+ FaceUp = property(_getFaceUp, _setFaceUp, None,
+ _("Specifies whether the card value is revealed.
(bool)"))
+
+ Rank = property(_getRank, _setRank, None,
+ _("Rank for this card (int)") )
+
+ Suit = property(_getSuit, _setSuit, None,
+ _("Suit for this card (Spades, Hearts, Diamonds,
Clubs)") )
+
+
+class Deck(list):
+ """Class representing a deck of any number of cards.
+
+ This is an abstract class, and should be overridden to define a
particular
+ playing card deck.
+ """
+ def __init__(self, board):
+ self.board = board
+ self.createDeck()
+
+ def createDeck(self):
+ """Create the Deck, which is a list of Card objects.
+
+ Subclasses must override.
+ """
+ pass
+
+ def appendCard(self, suit, rank):
+ """Append a Card object with the passed suit and rank."""
+ newCard = Card(self.board, Suit=suit, Rank=rank, RegID="%s%s" %
(suit, rank))
+ self.append(newCard)
+ return newCard
+
+ def faceUpAll(self):
+ """Turn all cards face up."""
+ for card in self:
+ card.FaceUp = True
+
+ def faceDownAll(self):
+ """Turn all cards face down."""
+ for card in self:
+ card.FaceUp = False
+
+
+class PokerDeck(Deck):
+ def createDeck(self):
+ """Create a standard 52-card Poker deck, no jokers."""
+ for suit in "SHDC":
+ for rank in range(1, 14):
+ self.appendCard(suit, rank)
+
+
Property changes on: trunk/demo/samples/games/cardlib.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/demo/samples/montana.py
===================================================================
--- trunk/demo/samples/montana.py (rev 0)
+++ trunk/demo/samples/montana.py 2007-10-24 16:13:30 UTC (rev 3562)
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+import datetime
+import dabo
+dabo.ui.loadUI("wx")
+import dabo.dEvents as dEvents
+from dabo.dLocalize import _
+from samples.games import MontanaForm
+
+
+class TestPanel(dabo.ui.dPanel):
+ def afterInit(self):
+ sz = self.Sizer = dabo.ui.dSizer("v")
+ sz.appendSpacer(40)
+
+ lbl = dabo.ui.dLabel(self, Caption="Montana is a solitaire game
that is easy to learn,\nbut difficult to master.\n\nFor instructions, please
see the Overview tab.")
+ sz.append(lbl, halign="center")
+ sz.appendSpacer(30)
+ btn = dabo.ui.dButton(self, Caption="Play Montana",
+ OnHit=self.runGame)
+ sz.append(btn, halign="center")
+
+
+ def runGame(self, evt):
+ frm = MontanaForm(self.Form, Size=(980,514), Centered=True)
+ frm.show()
+
+
+
+category = "Games.Montana"
+
+overview = """
+<h3>About Montana</h3>
+<p> <b>Montana</b> is a solitaire card game that is easy to learn, but
+difficult to master. </p>
+
+<h3>Object of the Game</h3>
+<p> Arrange all of the cards into 4 rows in increasing order from 2 to
+King, with one suit per row. </p>
+
+<h3>Starting a Game</h3>
+<p> The cards are dealt out into 4 rows of 13 cards each. The aces are
+then removed, leaving 4 gaps. </p>
+
+<h3>Playing the Game</h3>
+<p> Move cards into the gaps, which will create new gaps in their old
+location. The only card that can be moved into any gap is determined by
+the card to the immediate left of the gap. The moved card must be the
+same suit, and one rank higher. Example: if there is a gap, and the card
+to left of it is 4C, only 5C can be moved to the gap. </p>
+
+<p> If the gap is located in the leftmost column, any 2 card can be
+moved there. If the card to the left of the gap is a King, no card can
+be moved there. </p>
+
+<p> When all 4 gaps are located to the right of Kings, no further moves
+are possible, and the hand ends. If there are any re-deals remaining,
+the cards are re-dealt, and another hand is played. When all re-deals
+are used, the game ends. The number of re-deals can be set in the game
+preferences (default=2 re-deals). </p>
+
+<h3>Scoring</h3>
+<p> When a card is placed "in order", it scores a point. "In order" is
+defined as any cards arranged with a 2 of that suit in the leftmost
+column of a row, followed by other cards of that suit in sequence. Since
+Aces are not played, you can score a maximum of 48 points per level.
+Completing a level starts you over again, adding an additional re-deal
+to your remaining re-deal status. </p>
+
+<h3>Re-deals</h3>
+<p> All ordered cards (i.e., those that in sequence and have scored a
+point) remain where they are. All unordered cards (i.e., those not in
+sequence) are picked up, shuffled with the Aces, and dealt into the open
+spaces. The Aces are then removed, and play resumes. </p>
+"""
Property changes on: trunk/demo/samples/montana.py
___________________________________________________________________
Name: svn:eol-style
+ native
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev
Searchable Archives: http://leafe.com/archives/search/dabo-dev
This message: http://leafe.com/archives/byMID/dabo-dev/[EMAIL PROTECTED]