diff --git a/pysollib/games/golf.py b/pysollib/games/golf.py
index 015881c7..ffd1ab16 100644
--- a/pysollib/games/golf.py
+++ b/pysollib/games/golf.py
@@ -878,9 +878,7 @@ class ThreeFirTrees_RowStack(Golf_RowStack):
         return False
 
 
-class ThreeFirTrees(Golf):
-    Hint_Class = CautiousDefaultHint
-
+class FirTree_GameMethods:
     def _createFirTree(self, l, x0, y0):
         rows = []
         # create stacks
@@ -902,10 +900,13 @@ class ThreeFirTrees(Golf):
                 n += 1
         return rows
 
+
+class ThreeFirTrees(Golf, FirTree_GameMethods):
+    Hint_Class = CautiousDefaultHint
+
     def createGame(self):
 
         l, s = Layout(self), self.s
-
         self.setSize(l.XM+max(7*l.XS, 2*l.XS+26*l.XOFFSET), l.YM+5*l.YS)
 
         x0, y0 = (self.width-7*l.XS)/2, l.YM
@@ -934,6 +935,73 @@ class ThreeFirTrees(Golf):
         self.s.talon.dealCards()
 
 
+# /***********************************************************************
+# // Napoleon Takes Moscow
+# // Napoleon Leaves Moscow
+# ************************************************************************/
+
+class NapoleonTakesMoscow(Game, FirTree_GameMethods):
+    RowStack_Class = StackWrapper(SS_RowStack, base_rank=KING, max_move=1)
+    Hint_Class = CautiousDefaultHint
+
+    def createGame(self):
+
+        l, s = Layout(self), self.s
+        self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+15*l.YOFFSET)
+
+        x, y = l.XM+l.XS, l.YM
+        for i in range(8):
+            s.foundations.append(SS_FoundationStack(x, y, self, suit=i/2))
+            x += l.XS
+
+        x, y = l.XM, l.YM+l.YS
+        for i in range(2):
+            for j in range(4):
+                s.rows.append(self.RowStack_Class(x, y, self))
+                x += l.XS
+            x += 2*l.XS
+
+        x, y = l.XM+4*l.XS, l.YM+l.YS
+        s.reserves += self._createFirTree(l, x, y)
+
+        x, y = l.XM, self.height-l.YS
+        s.talon = WasteTalonStack(x, y, self, max_rounds=3)
+        l.createText(s.talon, 'n')
+        tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn')
+        font = self.app.getFont('canvas_default')
+        s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty-l.TEXT_MARGIN,
+                                             anchor=ta, font=font)
+
+        x += l.XS
+        s.waste = WasteStack(x, y, self)
+        l.createText(s.waste, 'n')
+
+        # define stack-groups
+        l.defaultStackGroups()
+        
+    def startGame(self):
+        self.s.talon.dealRow(rows=self.s.reserves, frames=0)
+        for i in range(3):
+            self.s.talon.dealRow(frames=0)
+        self.startDealSample()
+        self.s.talon.dealRow()
+        self.s.talon.dealCards()
+
+    shallHighlightMatch = Game._shallHighlightMatch_SS
+
+
+class NapoleonLeavesMoscow(NapoleonTakesMoscow):
+    RowStack_Class = StackWrapper(SS_RowStack, base_rank=KING)
+    Hint_Class = DefaultHint
+
+    def startGame(self):
+        self.s.talon.dealRow(rows=self.s.reserves, frames=0)
+        for i in range(4):
+            self.s.talon.dealRow(frames=0)
+        self.startDealSample()
+        self.s.talon.dealRow()
+        self.s.talon.dealCards()
+
 
 # register the game
 registerGame(GameInfo(36, Golf, "Golf",
@@ -966,9 +1034,14 @@ registerGame(GameInfo(709, Waterfall, "Waterfall",
 registerGame(GameInfo(720, Vague, "Vague",
                       GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
 registerGame(GameInfo(723, DevilsSolitaire, "Devil's Solitaire",
-                      GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
+                      GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED,
+                      altnames=('Banner',) ))
 registerGame(GameInfo(728, ThirtyTwoCards, "Thirty Two Cards",
                       GI.GT_2DECK_TYPE, 2, 0, GI.SL_LUCK))
 registerGame(GameInfo(731, ThreeFirTrees, "Three Fir-trees",
                       GI.GT_GOLF, 2, 0, GI.SL_BALANCED))
+registerGame(GameInfo(733, NapoleonTakesMoscow, "Napoleon Takes Moscow",
+                      GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
+registerGame(GameInfo(734, NapoleonLeavesMoscow, "Napoleon Leaves Moscow",
+                      GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
 
diff --git a/pysollib/games/montana.py b/pysollib/games/montana.py
index f86245a7..afcf1778 100644
--- a/pysollib/games/montana.py
+++ b/pysollib/games/montana.py
@@ -464,5 +464,5 @@ registerGame(GameInfo(381, SpacesAndAces, "Spaces and Aces",
 registerGame(GameInfo(706, Paganini, "Paganini",
                       GI.GT_MONTANA | GI.GT_OPEN, 1, 1, GI.SL_MOSTLY_SKILL,
                       ranks=(0, 5, 6, 7, 8, 9, 10, 11, 12),
-                      ))
+                      altnames=('Long Trip',) ))
 
diff --git a/pysollib/games/yukon.py b/pysollib/games/yukon.py
index 45312b54..b08ce580 100644
--- a/pysollib/games/yukon.py
+++ b/pysollib/games/yukon.py
@@ -700,6 +700,45 @@ class Hawaiian(Game):
     shallHighlightMatch = Game._shallHighlightMatch_AC
 
 
+# /***********************************************************************
+# // Wave
+# ************************************************************************/
+
+class WaveTalon(DealRowTalonStack):
+    def dealCards(self, sound=0):
+        if sound and self.game.app.opt.animations:
+            self.game.startDealSample()
+        n = self.dealRowAvail(flip=0, sound=0)
+        n += self.dealRowAvail(sound=0)
+        if sound:
+            self.game.stopSamples()
+        return n
+
+
+class Wave(Game):
+    Hint_Class = Yukon_Hint
+
+    def createGame(self, rows=8):
+        l, s = Layout(self), self.s
+        l.klondikeLayout(rows=rows, waste=0, playcards=25)
+        self.setSize(l.size[0], l.size[1])
+        s.talon = WaveTalon(l.s.talon.x, l.s.talon.y, self)
+        for r in l.s.foundations:
+            s.foundations.append(SS_FoundationStack(r.x, r.y, self,
+                                                    suit=r.suit))
+        for r in l.s.rows:
+            s.rows.append(Yukon_AC_RowStack(r.x, r.y, self))
+        l.defaultAll()
+
+    def startGame(self):
+        self.s.talon.dealRow(frames=0)
+        self.s.talon.dealRow(frames=0, flip=0)
+        self.startDealSample()
+        self.s.talon.dealRow()
+
+    shallHighlightMatch = Game._shallHighlightMatch_AC
+
+
 
 # register the game
 registerGame(GameInfo(19, Yukon, "Yukon",
@@ -761,3 +800,5 @@ registerGame(GameInfo(603, Brisbane, "Brisbane",
                       GI.GT_SPIDER, 1, 0, GI.SL_BALANCED))
 registerGame(GameInfo(707, Hawaiian, "Hawaiian",
                       GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED))
+registerGame(GameInfo(732, Wave, "Wave",
+                      GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED))
diff --git a/pysollib/stack.py b/pysollib/stack.py
index c38c987d..e5b2340b 100644
--- a/pysollib/stack.py
+++ b/pysollib/stack.py
@@ -76,6 +76,7 @@ __all__ = ['cardsFaceUp',
            'Spider_SS_RowStack',
            'Yukon_AC_RowStack',
            'Yukon_SS_RowStack',
+           'Yukon_RK_RowStack',
            'KingAC_RowStack',
            'KingSS_RowStack',
            'KingRK_RowStack',
@@ -2310,6 +2311,16 @@ class Yukon_SS_RowStack(Yukon_AC_RowStack):
         elif self.cap.dir < 0: return _('Tableau. Build down by suit, can move any face-up cards regardless of sequence.')
         else:                  return _('Tableau. Build by same rank, can move any face-up cards regardless of sequence.')
 
+# A Yukon_Rank_RowStack builds down by rank
+# but can move any face-up cards regardless of sequence.
+class Yukon_RK_RowStack(Yukon_AC_RowStack):
+    def _isSequence(self, c1, c2):
+        return (c1.rank + self.cap.dir) % self.cap.mod == c2.rank
+    def getHelp(self):
+        if self.cap.dir > 0:   return _('Tableau. Build up regardless of suit, can move any face-up cards regardless of sequence.')
+        elif self.cap.dir < 0: return _('Tableau. Build up regardless of suit, can move any face-up cards regardless of sequence.')
+        else:                  return _('Tableau. Build by same rank, can move any face-up cards regardless of sequence.')
+
 #
 # King-versions of some of the above stacks: they accepts only Kings or
 # sequences starting with a King as base_rank cards (i.e. when empty).