main logo
Subject: [dabo-dev] dabodemo Commit 278
Author: Ed Leafe
Posted: 2005/08/31 16:08:57
 
View Entire Thread
New Search


dabodemo Commit
Revision 278
Date: 2005-08-31 14:18:03 -0700 (Wed, 31 Aug 2005)
Author: ed

Changed:
D trunk/montana/
A trunk/montana.py

Log:
Moved the code out of its own directory, and into a simple script.
Added a help dialog to display the rules.


Diff:
Copied: trunk/montana.py (from rev 275, trunk/montana/main.py)
===================================================================
--- trunk/montana/main.py 2005-08-31 20:02:54 UTC (rev 275)
+++ trunk/montana.py 2005-08-31 21:18:03 UTC (rev 278)
@@ -0,0 +1,628 @@
+#!/usr/bin/env python
+"""This is a favorite card game of mine called 'Montana'. """
+
+helpText = """Object:
+To arrange all of the cards into 4 rows in increasing order from
+2 to King, with one suit per row.
+
+Starting a game
+The cards are dealt out into 4 rows of 13 cards each. The aces
+are then removed, leaving 4 gaps.
+
+Playing the game:
+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.
+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.
+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).
+
+Scoring:
+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.
+
+Re-deals:
+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.
+"""
+
+import random
+import dabo
+from dabo.dLocalize import _
+dabo.ui.loadUI("wx")
+
+
+class Card(dabo.ui.dBitmapButton):
+ def afterInit(self):
+ self._suit = None
+ self._rank = None
+ self.scored = False
+ self.bindEvent(dabo.dEvents.Hit, self.onClick)
+ self.bindEvent(dabo.dEvents.MouseLeftDown, self.onMDown)
+ self.bindEvent(dabo.dEvents.MouseLeftUp, self.onMUp)
+ # Turn auto-resize on
+ self.AutoSize = True
+ # These help when re-scaling
+ baseBmp = dabo.ui.dBitmap(self.Parent, Picture="cards/blank")
+ self._baseWd = baseBmp.Width
+ self._baseHt = baseBmp.Height
+ baseBmp.release()
+
+ # Base the size on the ImageScale
+ self.ImageScale = 1.0
+
+
+ def onClick(self, evt):
+ self.Parent.cardClick(self)
+
+
+ def onMDown(self, evt):
+ self.Parent.cardMDown(self)
+
+
+ def onMUp(self, evt):
+ self.Parent.cardMUp(self)
+
+
+ def updPic(self):
+ """Sets the Picture property for this card to match
+ its Suit and Rank.
+ """
+ if not self.Rank or not self.Suit:
+ # Card isn't set yet
+ pic = "cards/blank"
+ else:
+ rank = self.Rank
+ suit = self.Suit.lower()
+ if rank == 1:
+ # Ace, hide it
+ pic = "cards/blank"
+ else:
+ pic = "cards/%s%s" % (suit, str(rank))
+ self.Picture = pic
+
+
+ def setDeadPic(self):
+ """Mark the card as dead"""
+ self.Picture = "cards/x"
+
+
+ def setLivePic(self):
+ """Mark the card as active"""
+ self.Picture = "cards/blank"
+
+
+ def _getBaseHt(self):
+ return self._baseHt
+
+ def _getBaseWd(self):
+ return self._baseWd
+
+ def _getDesc(self):
+ rank = self._rank
+ suit = self._suit
+ if rank == 1:
+ ret = "Empty Space"
+ else:
+ if 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 _getRank(self):
+ return self._rank
+ def _setRank(self, val):
+ if self._rank != val:
+ self._rank = val
+ self.updPic()
+
+ def _getSuit(self):
+ return self._suit
+ def _setSuit(self, val):
+ suit = val[0].upper()
+ if self._suit != suit:
+ if suit in ("H", "D", "S", "C"):
+ self._suit = suit
+ self.updPic()
+
+ BaseHeight = property(_getBaseHt, None, None,
+ _("Normal (100%) height of the card (int)") )
+
+ BaseWidth = property(_getBaseWd, None, None,
+ _("Normal (100%) width of the card (int)") )
+
+ Description = property(_getDesc, None, None,
+ _("Descriptive name for this card, such as 'King of Clubs' (str)") )
+
+ Rank = property(_getRank, _setRank, None,
+ _("Rank for this card (int)") )
+
+ Suit = property(_getSuit, _setSuit, None,
+ _("Suit for this card (Spades, Hearts, Diamonds, Clubs)") )
+
+
+class Board(dabo.ui.dPanel):
+ def afterInit(self):
+ self.Sizer = dabo.ui.dSizer("v")
+ self.gridSizer = None
+ self._redeals = 2
+ self._score = 0
+ self.isStuck = True
+ # Controls card flashing
+ self.cardTimer = dabo.ui.dTimer(self, Interval=100)
+ self.cardTimer.bindEvent(dabo.dEvents.Hit, self.onCardTimer)
+ self.flashCard = None
+ # Holds a reference to all the aces in the deck.
+ self.aces = []
+ # Flag that indicates we need to resize the cards
+ self.needResize = False
+ # Base (100%) size of the board
+ self._baseWd = self._baseHt = None
+ # Create the deck
+ self.deck = self.createDeck()
+
+
+ def initEvents(self):
+ self.bindEvent(dabo.dEvents.Resize, self.onResize)
+ self.bindEvent(dabo.dEvents.Idle, self.onIdle)
+
+
+ def onResize(self, evt):
+ """Resize the cards to fit the board."""
+ self.needResize = True
+
+
+ def onIdle(self, evt):
+ if not self.needResize:
+ return
+ if self._baseWd is None:
+ # No deck info yet
+ return
+ self.needResize = False
+ # Determine the ratios needed to fill this panel
+ wdRatio = self.Width / float(self._baseWd)
+ htRatio = self.Height / float(self._baseHt)
+ # Use the smaller of the two, in order to guarantee that
+ # the full layout will fit.
+ newRatio = min(wdRatio, htRatio)
+ self.setAll("ImageScale", newRatio)
+ self.layout()
+
+
+ def sizeToNormal(self):
+ """Reset the cards to 100% size"""
+ self.setAll("ImageScale", 1.0)
+ self.layout()
+
+
+ def createSizer(self):
+ 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):
+ # Change this to use preference setting!
+ self._redeals = 2
+ 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 = []
+ random.shuffle(self.deck)
+ self.createSizer()
+ self.gridSizer.appendItems(self.deck)
+ self.updateCardLayout()
+ self.updateStatus()
+
+ if self._baseWd is None:
+ # First time through. Set the base measurments
+ cd = self.deck[0]
+ cdW, cdH = cd.BaseWidth, cd.BaseHeight
+ hgap = self.gridSizer.hgap
+ vgap = self.gridSizer.vgap
+ # Total width is the 13 card widths + 12 hgaps
+ self._baseWd = (13 * cdW) + (12 * hgap)
+ # Same goes for heights
+ self._baseHt = (4 * cdH) + (3 * vgap)
+ self.needResize = True
+
+
+ def createDeck(self):
+ """Creates a dict representing a 52-card deck."""
+ ret = []
+ for suit in "SHDC":
+ for rank in range(1, 14):
+ card = Card(self, Suit=suit, Rank=rank)
+ ret.append(card)
+ if rank == 1:
+ self.aces.append(card)
+ return ret
+
+
+ def redeal(self):
+ """ Gather all the non-scored cards, shuff
[excessive length snipped]
 
©2005 Ed Leafe
<-- Prior Message New Search Next Message -->