1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

Added Moojub game.

This commit is contained in:
Joe R 2021-12-15 18:51:19 -05:00
parent 659760b43a
commit a258946d30
4 changed files with 153 additions and 2 deletions

View file

@ -0,0 +1,37 @@
<h1>Moojub</h1>
<p>
One-Deck game type. 1 deck. No redeals.
<h3>Object</h3>
<p>
Move all cards to foundations.
<h3>Rules</h3>
<p>
Four cards are dealt to reserves from the talon at the start of the
game. Cards from the reserves may be moved to foundations.
<p>
The foundations in Moojub are unique in that there are four rows of
foundations, containing a number of different columns. If a foundation
has been started (at least one card in it), it is built up by suit,
turning the corner from king to ace as necessary. An empty foundation
can be started by playing a card to it, following these rules:
<ul>
<li>Foundations must be started in sequence, starting with the leftmost
column and moving right. Within each column, the topmost row must be
started first, and moving down.</li>
<li>Each foundation must be started with a card with the same suit as
the card in the foundation directly to the left (except in the leftmost
column, of course).</li>
<li>In the first column, each row must be started with a card of a
different suit.</li>
<li>If the reserve contains multiple visible cards of the same suit,
only the one with the lowest rank can be used to start a foundation.</li>
<li>If a card can legally be played on an existing foundation, it
cannot be used to start a new one.</li>
</ul>
<p>
When there are no moves left, you can deal one card from the talon
to each of the four reserve piles. The game is won if all cards have
been moved to foundations (it doesn't matter which foundations are
empty, and how many cards are in each).

View file

@ -397,7 +397,8 @@ class GI:
("Michael Keller", (592,)),
("Fred Lunde", (459,)),
("Albert Morehead and Geoffrey Mott-Smith", (25, 42, 48, 173, 282,
303, 362, 547, 738)),
303, 362, 547, 738,
845)),
("Toby Ord", (788,)),
("David Parlett", (64, 98, 294, 338, 654, 796, 812)),
("Randy Rasa", (187, 190, 191, 192,)),
@ -485,7 +486,7 @@ class GI:
('fc-2.12', tuple(range(774, 811)) + (16681,) +
tuple(range(22217, 22219))),
('fc-2.14', tuple(range(811, 827))),
('fc-2.16', tuple(range(827, 845)))
('fc-2.16', tuple(range(827, 846)))
)
# deprecated - the correct way is to or a GI.GT_XXX flag

View file

@ -61,6 +61,7 @@ from . import larasgame # noqa: F401
from . import matriarchy # noqa: F401
from . import montana # noqa: F401
from . import montecarlo # noqa: F401
from . import moojub # noqa: F401
from . import napoleon # noqa: F401
from . import needle # noqa: F401
from . import numerica # noqa: F401

112
pysollib/games/moojub.py Normal file
View file

@ -0,0 +1,112 @@
#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
# Copyright (C) 2005-2009 Skomoroh
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------
from pysollib.game import Game
from pysollib.gamedb import GI, GameInfo, registerGame
from pysollib.layout import Layout
from pysollib.stack import \
DealRowTalonStack, \
OpenStack, \
RK_FoundationStack
from pysollib.util import ACE, ANY_SUIT, KING
# ************************************************************************
# * Moojub
# ************************************************************************
class Moojub_Foundation(RK_FoundationStack):
def acceptsCards(self, from_stack, cards):
if len(self.cards) > 0:
return (self.cards[-1].suit == cards[0].suit and
RK_FoundationStack.acceptsCards(self, from_stack, cards))
foundations = self.game.s.foundations
# Checking each rule for starting a new foundation:
# Only the next foundation can be built to.
if self.id > 0 and len(foundations[self.id - 1].cards) == 0:
return False
# The suit must match the foundation directly to the left.
if (self.id > 3 and
foundations[self.id - 4].cards[0].suit != cards[0].suit):
return False
# Two foundations in the same column can't have the same suit.
if self.id <= 3:
for i in range(4):
if (foundations[i].cards and
foundations[i].cards[0].suit == cards[0].suit):
return False
# Only the lowest available card of a suit can start a foundation.
for row in self.game.s.rows:
if (row.cards and row.cards[-1].suit == cards[0].suit
and row.cards[-1].rank < cards[0].rank):
return False
# Can't start a foundation with a card that can be played on an
# existing foundation.
for foundation in foundations:
if (foundation.cards and
foundation.cards[-1].suit == cards[0].suit and
(foundation.cards[-1].rank == cards[0].rank - 1 or
(foundation.cards[-1].rank == KING and
cards[0].rank == ACE))):
return False
return True
class Moojub(Game):
Foundations = 8
def createGame(self):
# create layout
l, s = Layout(self), self.s
# set window
self.setSize(l.XM + (l.XS * 1.5) + self.Foundations * l.XS,
l.YM + 5 * l.YS)
# create stacks
for j in range(self.Foundations):
for i in range(4):
x, y, = l.XM + (l.XS * (j + 1.5)), (l.YM + i * l.YS) + l.YS
s.foundations.append(Moojub_Foundation(x, y, self, ANY_SUIT,
mod=13, max_move=0))
for i in range(4):
x, y, = l.XM, (l.YM + i * l.YS) + l.YS
s.rows.append(OpenStack(x, y, self))
x, y, = l.XM, l.YM
s.talon = DealRowTalonStack(x, y, self, max_rounds=1)
l.createText(s.talon, 'se')
# define stack-groups
l.defaultStackGroups()
def startGame(self):
self._startAndDealRow()
# register the game
registerGame(GameInfo(845, Moojub, "Moojub",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))