From: <umg...@us...> - 2007-03-29 19:53:45
|
Revision: 373 http://svn.sourceforge.net/pybridge/?rev=373&view=rev Author: umgangee Date: 2007-03-29 12:53:46 -0700 (Thu, 29 Mar 2007) Log Message: ----------- Rename Player to Direction, tidy up some code. Modified Paths: -------------- trunk/pybridge/pybridge/bridge/bidding.py trunk/pybridge/pybridge/bridge/deck.py trunk/pybridge/pybridge/bridge/playing.py Modified: trunk/pybridge/pybridge/bridge/bidding.py =================================================================== --- trunk/pybridge/pybridge/bridge/bidding.py 2007-03-29 19:42:57 UTC (rev 372) +++ trunk/pybridge/pybridge/bridge/bidding.py 2007-03-29 19:53:46 UTC (rev 373) @@ -17,10 +17,10 @@ from call import Call, Bid, Pass, Double, Redouble -from symbols import Level, Player, Strain +from symbols import Direction, Level, Strain -class Bidding: +class Bidding(object): """This class models the bidding (auction) phase of a game of bridge. A bidding session is a list of Call objects and the dealer. @@ -28,7 +28,8 @@ def __init__(self, dealer): - assert dealer in Player + if dealer not in Direction: + raise TypeError, "Expected Direction, got %s" % type(dealer) self.calls = [] self.dealer = dealer @@ -72,7 +73,7 @@ redouble = self.getCurrentCall(Redouble) # Determine declarer. partnership = (self.whoCalled(bid), \ - Player[(self.whoCalled(bid).index + 2) % 4]) + Direction[(self.whoCalled(bid).index + 2) % 4]) for call in self.calls: if isinstance(call, Bid) and call.strain == bid.strain \ and self.whoCalled(call) in partnership: @@ -123,7 +124,7 @@ @return: True if call is available, False if not. """ assert isinstance(call, Call) - assert player in Player or player is None + assert player in Direction or player is None # The bidding must not be complete. if self.isComplete(): @@ -150,15 +151,15 @@ # A double must be made on the current bid from opponents, # with has not been already doubled by partnership. if isinstance(call, Double): - opposition = (Player[(self.whoseTurn().index + 1) % 4], - Player[(self.whoseTurn().index + 3) % 4]) + opposition = (Direction[(self.whoseTurn().index + 1) % 4], + Direction[(self.whoseTurn().index + 3) % 4]) return bidder in opposition and not self.getCurrentCall(Double) # A redouble must be made on the current bid from partnership, # which has been doubled by an opponent. elif isinstance(call, Redouble): partnership = (self.whoseTurn(), - Player[(self.whoseTurn().index + 2) % 4]) + Direction[(self.whoseTurn().index + 2) % 4]) return bidder in partnership and self.getCurrentCall(Double) \ and not self.getCurrentCall(Redouble) @@ -173,15 +174,17 @@ """ assert isinstance(call, Call) if call in self.calls: - return Player[(self.calls.index(call) + self.dealer.index) % 4] + return Direction[(self.calls.index(call) + self.dealer.index) % 4] return False # Call not made by any player. def whoseTurn(self): - """If bidding is not complete, returns the player who is next to call. + """Returns position of player who is next to make a call. - @return: the player next to call. + @return: the current turn. + @rtype: Direction """ - player = Player[(len(self.calls) + self.dealer.index) % 4] - return not self.isComplete() and player + if self.isComplete(): + return None + return Direction[(len(self.calls) + self.dealer.index) % 4] Modified: trunk/pybridge/pybridge/bridge/deck.py =================================================================== --- trunk/pybridge/pybridge/bridge/deck.py 2007-03-29 19:42:57 UTC (rev 372) +++ trunk/pybridge/pybridge/bridge/deck.py 2007-03-29 19:53:46 UTC (rev 373) @@ -21,7 +21,7 @@ from random import shuffle from card import Card -from symbols import Player, Rank, Suit +from symbols import Direction, Rank, Suit # See http://mail.python.org/pipermail/edu-sig/2001-May/001288.html for details. @@ -30,17 +30,17 @@ # TODO: consider making Hand a subclass of List, with additional constraints. -class Deck: +class Deck(object): """A Deck object provides operations for dealing Card objects. A hand is a collection of 13 cards from the deck. A deal is a distribution of all 52 cards to four hands. - A deal is represented as a dictionary, mapping Player labels to lists (hands) - of Card objects. + A deal is represented as a dictionary, mapping Direction labels to + lists (hands) of Card objects. There are exactly 52! / (13!)**4 (comb(52,13) * comb(39,13) * comb(26,13)) - distinct deals of 13 cards to 4 players from a standard 52-card deck. + distinct deals of 13 cards to 4 positions from a standard 52-card deck. """ cards = [Card(r, s) for r in Rank for s in Suit] @@ -56,7 +56,7 @@ def isValidDeal(self, deal): """Checks that structure of deal conforms to requirements: - * 4-element dict, mapping Player objects to hand lists. + * 4-element dict, mapping Direction objects to hand lists. * Hand lists contain exactly 13 Card objects. * No card may be repeated in the same hand, or between hands. * The cards in hands may be in any order. @@ -64,7 +64,7 @@ @param deal: a deal dict. @return: True if deal is valid, False otherwise. """ - return True # TODO + return True # TODO - if invalid, perhaps give reason def randomDeal(self): @@ -74,10 +74,10 @@ """ shuffle(self.cards) hands = {} - for player in Player: - hands[player] = [] + for position in Direction: + hands[position] = [] for index, card in enumerate(self.cards): - hands[Player[index % len(Player)]].append(card) + hands[Direction[index % len(Direction)]].append(card) for hand in hands.values(): hand.sort() return hands @@ -98,19 +98,19 @@ indexes = {} # For each hand, compute indexes of cards in cardSeq. - for player in (Player.North, Player.East, Player.South): - indexes[player] = 0 - deal[player].sort(reverse=False) + for position in (Direction.North, Direction.East, Direction.South): + indexes[position] = 0 + deal[position].sort(reverse=False) # It is desirable to remove cards from cardSeq when adding their # indexes, instead of doing so in an extra step. # Removing cards backwards preserves the indexes of later cards. - for i, card in enumerate(deal[player]): - indexes[player] += comb(cardSeq.index(card), 13-i) + for i, card in enumerate(deal[position]): + indexes[position] += comb(cardSeq.index(card), 13-i) cardSeq.remove(card) # Deal index = (Nindex * Emax * Smax) + (Eindex * Smax) + Sindex - indexes[Player.North] *= self.Emax * self.Smax - indexes[Player.East] *= self.Smax + indexes[Direction.North] *= self.Emax * self.Smax + indexes[Direction.East] *= self.Smax return long(sum(indexes.values())) @@ -130,28 +130,28 @@ deal = {} # Split index into hand indexes. - indexes = {Player.North : (num / self.Smax) / self.Emax, - Player.East : (num / self.Smax) % self.Emax, - Player.South : (num % self.Smax) } + indexes = {Direction.North : (num / self.Smax) / self.Emax, + Direction.East : (num / self.Smax) % self.Emax, + Direction.South : (num % self.Smax) } - for player in (Player.North, Player.East, Player.South): - deal[player] = [] + for position in (Direction.North, Direction.East, Direction.South): + deal[position] = [] for k in range(13, 0, -1): - # Find the largest n such that comb(n, k) <= indexes[player]. + # Find the largest n such that comb(n, k) <= indexes[position]. n = k-1 # n < k implies comb(n, k) = 0 # comb(n+1, k) = # n-k = -1 => comb(n, k) * (n+1) # otherwise => (comb(n, k) * (n+1)) / (n+1 - k) - while comb(n+1, k) <= indexes[player]: + while comb(n+1, k) <= indexes[position]: n += 1 # Remove card index from indices, add card to hand. - indexes[player] -= comb(n, k) + indexes[position] -= comb(n, k) card = cardSeq[n] - deal[player].append(card) + deal[position].append(card) cardSeq.remove(card) - deal[Player.West] = cardSeq # West has the remaining cards. + deal[Direction.West] = cardSeq # West has the remaining cards. return deal Modified: trunk/pybridge/pybridge/bridge/playing.py =================================================================== --- trunk/pybridge/pybridge/bridge/playing.py 2007-03-29 19:42:57 UTC (rev 372) +++ trunk/pybridge/pybridge/bridge/playing.py 2007-03-29 19:53:46 UTC (rev 373) @@ -157,7 +157,7 @@ return False elif hand and card not in hand: return False # Playing a card not in hand. - elif player and player is not self.whoseTurn(): + elif player and player != self.whoseTurn(): return False # Playing out of turn. elif self.whoPlayed(card): return False # Card played previously. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <umg...@us...> - 2007-03-29 20:11:11
|
Revision: 375 http://svn.sourceforge.net/pybridge/?rev=375&view=rev Author: umgangee Date: 2007-03-29 13:11:12 -0700 (Thu, 29 Mar 2007) Log Message: ----------- Remove string conversions on serialize/unserialize, since enum values are now copyable over the network. Modified Paths: -------------- trunk/pybridge/pybridge/bridge/call.py trunk/pybridge/pybridge/bridge/card.py Modified: trunk/pybridge/pybridge/bridge/call.py =================================================================== --- trunk/pybridge/pybridge/bridge/call.py 2007-03-29 19:57:32 UTC (rev 374) +++ trunk/pybridge/pybridge/bridge/call.py 2007-03-29 20:11:12 UTC (rev 375) @@ -26,20 +26,32 @@ class Bid(Call): - """A Bid represents a statement of a level and a strain.""" + """A Bid represents a statement of a level and a strain. + + @param level: the level of the bid. + @type level: L{Level} + @param strain: the strain (denomination) of the bid. + @type strain: L{Strain} + """ + level = property(lambda self: self.__level) + strain = property(lambda self: self.__strain) + + def __init__(self, level, strain): - assert level in Level - assert strain in Strain - - self.level = level - self.strain = strain + if level not in Level: + raise TypeError, "Expected Level, got %s" % type(level) + if strain not in Strain: + raise TypeError, "Expected Strain, got %s" % type(strain) + self.__level = level + self.__strain = strain + def __cmp__(self, other): if not issubclass(other.__class__, Call): raise TypeError, "Expected Call, got %s" % type(other) - + if isinstance(other, Bid): # Compare two bids. selfIndex = self.level.index*len(Strain) + self.strain.index otherIndex = other.level.index*len(Strain) + other.strain.index @@ -53,17 +65,16 @@ def getStateToCopy(self): - state = {} - state['level'] = self.level.key - state['strain'] = self.strain.key - return state + return self.level, self.strain def setCopyableState(self, state): - self.level = getattr(Level, state['level']) - self.strain = getattr(Strain, state['strain']) + self.__level, self.__strain = state +pb.setUnjellyableForClass(Bid, Bid) + + class Pass(Call): """A Pass represents an abstention from the bidding.""" @@ -71,6 +82,9 @@ return "Pass" +pb.setUnjellyableForClass(Pass, Pass) + + class Double(Call): """A Double over an opponent's current bid.""" @@ -78,9 +92,15 @@ return "Double" +pb.setUnjellyableForClass(Double, Double) + + class Redouble(Call): """A Redouble over an opponent's double of partnership's current bid.""" def __str__(self): return "Redouble" + +pb.setUnjellyableForClass(Redouble, Redouble) + Modified: trunk/pybridge/pybridge/bridge/card.py =================================================================== --- trunk/pybridge/pybridge/bridge/card.py 2007-03-29 19:57:32 UTC (rev 374) +++ trunk/pybridge/pybridge/bridge/card.py 2007-03-29 20:11:12 UTC (rev 375) @@ -69,10 +69,12 @@ def getStateToCopy(self): - return {'rank' : self.rank.key, 'suit' : self.suit.key} + return self.rank, self.suit def setCopyableState(self, state): - self.__rank = getattr(Rank, state['rank']) - self.__suit = getattr(Suit, state['suit']) + self.__rank, self.__suit = state + +pb.setUnjellyableForClass(Card, Card) + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <umg...@us...> - 2007-06-20 15:14:27
|
Revision: 432 http://svn.sourceforge.net/pybridge/?rev=432&view=rev Author: umgangee Date: 2007-06-20 08:14:28 -0700 (Wed, 20 Jun 2007) Log Message: ----------- Add simple vulnerability rotation. TODO: consider vulnerability rules for duplicate, rubber bridge. Modified Paths: -------------- trunk/pybridge/pybridge/bridge/board.py trunk/pybridge/pybridge/bridge/game.py Modified: trunk/pybridge/pybridge/bridge/board.py =================================================================== --- trunk/pybridge/pybridge/bridge/board.py 2007-06-20 15:13:03 UTC (rev 431) +++ trunk/pybridge/pybridge/bridge/board.py 2007-06-20 15:14:28 UTC (rev 432) @@ -65,6 +65,11 @@ self['dealer'] = random.choice(Direction) if result: - self['vuln'] = Vulnerable.All # TODO + # TODO: proper GameResult object. + # TODO: consider vulnerability rules for duplicate, rubber bridge. + #if result.bidding.isPassedOut(): + # self['vuln'] = result.board['vuln'] + #elif result.getScore() >= 0 + self['vuln'] = Vulnerable[(result.board['vuln'].index + 1) % 4] else: self['vuln'] = Vulnerable.None # The default value. Modified: trunk/pybridge/pybridge/bridge/game.py =================================================================== --- trunk/pybridge/pybridge/bridge/game.py 2007-06-20 15:13:03 UTC (rev 431) +++ trunk/pybridge/pybridge/bridge/game.py 2007-06-20 15:14:28 UTC (rev 432) @@ -79,7 +79,7 @@ if board: # Use specified board. self.board = board elif self.board: # Advance to next deal. - self.board.nextDeal(result=999) + self.board.nextDeal(result=self) # TODO: proper GameResult object. else: # Create a board. self.board = Board() self.board.nextDeal() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <umg...@us...> - 2007-07-09 14:00:00
|
Revision: 462 http://svn.sourceforge.net/pybridge/?rev=462&view=rev Author: umgangee Date: 2007-07-09 07:00:02 -0700 (Mon, 09 Jul 2007) Log Message: ----------- Move bridge UI component to pybridge.bridge.ui. Added Paths: ----------- trunk/pybridge/pybridge/bridge/ui/ trunk/pybridge/pybridge/bridge/ui/__init__.py Added: trunk/pybridge/pybridge/bridge/ui/__init__.py =================================================================== This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |