From 660def3751f4a2e7987f327b786ceea17e7c70a6 Mon Sep 17 00:00:00 2001
From: skomoroh <skomoroh@39dd0a4e-7c14-0410-91b3-c4f2d318f732>
Date: Sat, 5 Aug 2006 21:29:10 +0000
Subject: [PATCH] + 5 new games * improved tkhtml

git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@39 39dd0a4e-7c14-0410-91b3-c4f2d318f732
---
 pysollib/games/bakersgame.py        | 49 +++++++++++++------------
 pysollib/games/beleagueredcastle.py | 53 +++++++++++++++++++++++++++
 pysollib/games/fan.py               | 11 +++---
 pysollib/games/fortythieves.py      | 20 +++++++++--
 pysollib/games/klondike.py          | 55 +++++++++++++++++++++++++++++
 pysollib/tk/tkhtml.py               | 13 ++++---
 scripts/all_games.py                |  7 ++--
 7 files changed, 170 insertions(+), 38 deletions(-)

diff --git a/pysollib/games/bakersgame.py b/pysollib/games/bakersgame.py
index 119d6690..feea47ed 100644
--- a/pysollib/games/bakersgame.py
+++ b/pysollib/games/bakersgame.py
@@ -241,18 +241,14 @@ class RelaxedSeahavenTowers(SeahavenTowers):
 # /***********************************************************************
 # // Penguin
 # // Opus
+# // Tuxedo
 # ************************************************************************/
 
-class Penguin(Game):
-    GAME_VERSION = 2
+class Tuxedo(Game):
 
     RowStack_Class = SS_RowStack
     Hint_Class = FreeCellType_Hint
 
-    #
-    # game layout
-    #
-
     def createGame(self, rows=7, reserves=7):
         # create layout
         l, s = Layout(self), self.s
@@ -286,13 +282,29 @@ class Penguin(Game):
         # define stack-groups
         l.defaultStackGroups()
 
-    #
-    # game overrides
-    #
+    def startGame(self):
+        for i in range(6):
+            self.s.talon.dealRow(frames=0)
+        self.startDealSample()
+        self.s.talon.dealRow()
+        self.s.talon.dealRow(rows=self.s.rows[::3])
+
+    shallHighlightMatch = Game._shallHighlightMatch_SSW
+
+
+class Penguin(Tuxedo):
+    GAME_VERSION = 2
 
     def _shuffleHook(self, cards):
         # move base cards to top of the Talon (i.e. first cards to be dealt)
-        return self._shuffleHookMoveToTop(cards, lambda c, rank=cards[-1].rank: (c.rank == rank, 0))
+        return self._shuffleHookMoveToTop(cards,
+                   lambda c, rank=cards[-1].rank: (c.rank == rank, 0))
+
+    def _updateStacks(self):
+        for s in self.s.foundations:
+            s.cap.base_rank = self.base_card.rank
+        for s in self.s.rows:
+            s.cap.base_rank = (self.base_card.rank - 1) % 13
 
     def startGame(self):
         self.base_card = self.s.talon.cards[-4]
@@ -310,8 +322,6 @@ class Penguin(Game):
         self.startDealSample()
         self.s.talon.dealRow()
 
-    shallHighlightMatch = Game._shallHighlightMatch_SSW
-
     def _restoreGameHook(self, game):
         self.base_card = self.cards[game.loadinfo.base_card_id]
         self._updateStacks()
@@ -323,20 +333,11 @@ class Penguin(Game):
     def _saveGameHook(self, p):
         p.dump(self.base_card.id)
 
-    #
-    # game extras
-    #
-
-    def _updateStacks(self):
-        for s in self.s.foundations:
-            s.cap.base_rank = self.base_card.rank
-        for s in self.s.rows:
-            s.cap.base_rank = (self.base_card.rank - 1) % 13
-
 
 class Opus(Penguin):
     def createGame(self):
-        Penguin.createGame(self, reserves=5)
+        Tuxedo.createGame(self, reserves=5)
+
 
 
 # register the game
@@ -356,3 +357,5 @@ registerGame(GameInfo(64, Penguin, "Penguin",
                       altnames=("Beak and Flipper",) ))
 registerGame(GameInfo(427, Opus, "Opus",
                       GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
+registerGame(GameInfo(629, Tuxedo, "Tuxedo",
+                      GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
diff --git a/pysollib/games/beleagueredcastle.py b/pysollib/games/beleagueredcastle.py
index e846d580..5e95333b 100644
--- a/pysollib/games/beleagueredcastle.py
+++ b/pysollib/games/beleagueredcastle.py
@@ -715,6 +715,57 @@ class SelectiveCastle(StreetsAndAlleys, Chessboard):
     shallHighlightMatch = Game._shallHighlightMatch_RKW
 
 
+# /***********************************************************************
+# // Soother
+# ************************************************************************/
+
+class Soother(Game):
+
+    def createGame(self, rows=9):
+        l, s = Layout(self), self.s
+        self.setSize(l.XM+11*l.XS, l.YM+4*l.YS+12*l.YOFFSET)
+
+        x, y = l.XM, l.YM
+        s.talon = WasteTalonStack(x, y, self, max_rounds=1)
+        l.createText(s.talon, 's')
+        x += l.XS
+        s.waste = WasteStack(x, y, self)
+        l.createText(s.waste, 's')
+
+        y = l.YM
+        for i in range(2):
+            x = l.XM+2.5*l.XS
+            for j in range(8):
+                s.foundations.append(SS_FoundationStack(x, y, self, suit=j%4, max_move=1))
+                x += l.XS
+            y += l.YS
+        x, y = l.XM, l.YM+2*l.YS
+        stack = ReserveStack(x, y, self, max_cards=8)
+        s.reserves.append(stack)
+        stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, l.YOFFSET
+        l.createText(stack, 'n')
+
+        x, y = l.XM+2*l.XS, l.YM+2*l.YS
+        for i in range(rows):
+            s.rows.append(RK_RowStack(x, y, self, max_move=1, base_rank=KING))
+            x += l.XS
+
+        l.defaultStackGroups()
+
+
+    def startGame(self):
+        for i in range(4):
+            self.s.talon.dealRow(frames=0)
+        self.startDealSample()
+        self.s.talon.dealRow()
+        self.s.talon.dealCards()
+
+    shallHighlightMatch = Game._shallHighlightMatch_RK
+
+    def getQuickPlayScore(self, ncards, from_stack, to_stack):
+        return int(to_stack in self.s.rows)
+
+
 # register the game
 registerGame(GameInfo(146, StreetsAndAlleys, "Streets and Alleys",
                       GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
@@ -752,3 +803,5 @@ registerGame(GameInfo(524, SelectiveCastle, "Selective Castle",
                       GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
 registerGame(GameInfo(535, ExiledKings, "Exiled Kings",
                       GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
+registerGame(GameInfo(626, Soother, "Soother",
+                      GI.GT_4DECK_TYPE | GI.GT_ORIGINAL, 4, 0, GI.SL_MOSTLY_SKILL))
diff --git a/pysollib/games/fan.py b/pysollib/games/fan.py
index 169f8c3c..b3a2ebf3 100644
--- a/pysollib/games/fan.py
+++ b/pysollib/games/fan.py
@@ -630,13 +630,12 @@ class FascinationFan(Fan):
         self.s.talon.dealRow()
 
     def redealCards(self):
-        nrows = len(self.s.talon.cards)/3
-        if len(self.s.talon.cards)%3: nrows += 1
-        self.s.talon.dealRowAvail(rows=self.s.rows[:nrows], flip=0, frames=4)
-        self.s.talon.dealRowAvail(rows=self.s.rows[:nrows], flip=0, frames=4)
+        r0 = r1 = len(self.s.talon.cards)/3
+        m = len(self.s.talon.cards)%3
+        if m >= 1: r2 += 1
+        self.s.talon.dealRow(rows=self.s.rows[:r0], flip=0, frames=4)
+        self.s.talon.dealRow(rows=self.s.rows[:r1], flip=0, frames=4)
         self.s.talon.dealRowAvail(frames=4)
-        for r in self.s.rows[nrows-2:nrows]:
-            if r.canFlipCard(): r.flipMove()
 
     shallHighlightMatch = Game._shallHighlightMatch_AC
 
diff --git a/pysollib/games/fortythieves.py b/pysollib/games/fortythieves.py
index b329ecc2..8a8d5ba7 100644
--- a/pysollib/games/fortythieves.py
+++ b/pysollib/games/fortythieves.py
@@ -804,9 +804,11 @@ class Waterloo(FortyThieves):
 
 # /***********************************************************************
 # // Junction
+# // Crossroads
 # ************************************************************************/
 
 class Junction(Game):
+    Foundation_Class = StackWrapper(DieRussische_Foundation, max_cards=8)
 
     def createGame(self, rows=7):
         
@@ -818,8 +820,8 @@ class Junction(Game):
         for i in range(2):
             x = l.XM+2*l.XS
             for j in range(8):
-                s.foundations.append(DieRussische_Foundation(x, y, self,
-                                     suit=j%4, max_cards=8))
+                s.foundations.append(self.Foundation_Class(x, y, self,
+                                                           suit=j%4))
                 x += l.XS
             y += l.YS
 
@@ -847,6 +849,18 @@ class Junction(Game):
     shallHighlightMatch = Game._shallHighlightMatch_AC
 
 
+class Crossroads(Junction):
+    Foundation_Class = StackWrapper(SS_FoundationStack, max_cards=13)
+
+    def startGame(self):
+        for i in range(3):
+            self.s.talon.dealRow(frames=0)
+            self.s.talon.dealRow(flip=0, frames=0)
+        self.startDealSample()
+        self.s.talon.dealRow()
+        self.s.talon.dealCards()
+
+
 # /***********************************************************************
 # // The Spark
 # ************************************************************************/
@@ -1146,4 +1160,6 @@ registerGame(GameInfo(578, IndianPatience, "Indian Patience",
                       GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
 registerGame(GameInfo(588, Roosevelt, "Roosevelt",
                       GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
+registerGame(GameInfo(628, Crossroads, "Crossroads",
+                      GI.GT_FORTY_THIEVES, 4, 0, GI.SL_BALANCED))
 
diff --git a/pysollib/games/klondike.py b/pysollib/games/klondike.py
index 6018d548..191236fc 100644
--- a/pysollib/games/klondike.py
+++ b/pysollib/games/klondike.py
@@ -493,6 +493,7 @@ class FlowerGarden(Stonewall):
 # // King Albert
 # // Raglan
 # // Brigade
+# // Queen Victoria
 # ************************************************************************/
 
 class KingAlbert(Klondike):
@@ -553,6 +554,10 @@ class Brigade(Raglan):
     shallHighlightMatch = Game._shallHighlightMatch_RK
 
 
+class QueenVictoria(KingAlbert):
+    RowStack_Class = AC_RowStack
+
+
 # /***********************************************************************
 # // Jane
 # // Agnes Bernauer
@@ -1222,6 +1227,51 @@ class Legion(Klondike):
         self.s.talon.dealCards()
 
 
+# /***********************************************************************
+# // Big Bertha
+# ************************************************************************/
+
+class BigBertha(Game):
+
+    def createGame(self):
+        l, s = Layout(self), self.s
+        self.setSize(l.XM+15*l.XS, l.YM+3*l.YS+15*l.YOFFSET)
+
+        x, y = l.XM, l.YM
+        s.talon = InitialDealTalonStack(x, y, self)
+
+        x, y = l.XM+3.5*l.XS, l.YM
+        for i in range(8):
+            s.foundations.append(SS_FoundationStack(x, y, self,
+                                 suit=i%4, max_cards=12))
+            x += l.XS
+
+        x, y = l.XM, l.YM+l.YS
+        for i in range(15):
+            s.rows.append(AC_RowStack(x, y, self))
+            x += l.XS
+
+        x, y = l.XM, self.height-l.YS
+        for i in range(14):
+            s.reserves.append(OpenStack(x, y, self, max_accept=0))
+            x += l.XS
+
+        s.foundations.append(RK_FoundationStack(x, y, self, suit=ANY_SUIT,
+                             base_rank=KING, dir=0, max_cards=8))
+
+        l.defaultStackGroups()
+
+
+    def startGame(self):
+        for i in range(5):
+            self.s.talon.dealRow(frames=0)
+        self.startDealSample()
+        self.s.talon.dealRow()
+        self.s.talon.dealRow(rows=self.s.reserves)
+
+    shallHighlightMatch = Game._shallHighlightMatch_AC
+
+
 
 # register the game
 registerGame(GameInfo(2, Klondike, "Klondike",
@@ -1350,4 +1400,9 @@ registerGame(GameInfo(602, BritishCanister, "British Canister",
                       GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
 registerGame(GameInfo(607, Legion, "Legion",
                       GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED))
+registerGame(GameInfo(627, QueenVictoria, "Queen Victoria",
+                      GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
+registerGame(GameInfo(630, BigBertha, "Big Bertha",
+                      GI.GT_RAGLAN | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL))
+
 
diff --git a/pysollib/tk/tkhtml.py b/pysollib/tk/tkhtml.py
index b7466b2e..2ce7d6e0 100644
--- a/pysollib/tk/tkhtml.py
+++ b/pysollib/tk/tkhtml.py
@@ -205,6 +205,10 @@ class tkHTMLParser(htmllib.HTMLParser):
     def handle_image(self, src, alt, ismap, align, width, height):
         self.formatter.writer.viewer.showImage(src, alt, ismap, align, width, height)
 
+    def do_br(self, attrs):
+        #self.formatter.add_line_break()
+        self.formatter.add_literal_data('\n')
+
 
 # /***********************************************************************
 # //
@@ -486,10 +490,11 @@ to open the following URL:
             self.images[url] = img
         ##print url, img
         if img:
-            padx, pady = 10, 10
-            padx, pady = 0, 20
-            if align.lower() == "left":
-                padx = 0
+            ##padx, pady = 10, 10
+            ##padx, pady = 0, 20
+            ##if align.lower() == "left":
+            ##    padx = 0
+            padx, pady = 0, 0
             self.text.image_create(index="insert", image=img, padx=padx, pady=pady)
 
 
diff --git a/scripts/all_games.py b/scripts/all_games.py
index 59f7e447..7112f18e 100755
--- a/scripts/all_games.py
+++ b/scripts/all_games.py
@@ -219,9 +219,10 @@ def plain_text():
     for id in get_games_func():
         gi = GAME_DB.get(id)
         if gi.category == GI.GC_FRENCH:
-            name = gi.name.lower()
-            name = re.sub('\W', '', name)
-            print id, name #, gi.si.game_type, gi.si.game_type == GI.GC_FRENCH
+            print gi.name.encode('utf-8')
+            ##name = gi.name.lower()
+            ##name = re.sub('\W', '', name)
+            ##print id, name #, gi.si.game_type, gi.si.game_type == GI.GC_FRENCH
 
 
 ##