-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
211 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<h1>Clear the Dungeon</h1> | ||
<p> | ||
One-Deck game type. 1 joker deck. No redeal. | ||
|
||
<h3>Object</h3> | ||
<p> | ||
Clear the dungeon by removing all the "monster cards" (face cards) | ||
from the tableau. | ||
|
||
<h3>Rules</h3> | ||
<p> | ||
The face cards are dealt in four rows of three cards each, with only the top | ||
card of each pile face-up. These represent the dungeon monsters. The remaining | ||
cards are set aside in the talon, called the "power deck". | ||
<p> | ||
Cards are dealt from the talon three at a time. These cards can be moved to | ||
the monsters on the tableau, or moved to a single reserve pile. The top card | ||
of this reserve pile can also be moved to the tableau. Once all three cards | ||
have been moved to either the tableau or the reserve, three additional cards | ||
are dealt. | ||
<p> | ||
To slay a monster and remove it from the tableau, three additional cards must | ||
be placed on it. | ||
<ul> | ||
<li>The first two cards must have a total rank that's greater than or equal | ||
to the rank of the face card (Jacks are 11, Queens are 12, Kings are 13). This | ||
represents the monster's power. | ||
<li>Finally, a card of the same suit as the face card must be played to it to | ||
finish the attack. | ||
</ul> | ||
<p> | ||
Jokers are wild. They are treated as having a value of 10, and can be of any | ||
suit. | ||
<p> | ||
Once all three cards have been played correctly, the monster is slain, and all | ||
four cards are immediately removed (to the foundation). Cards in the tableau | ||
cannot be moved or removed otherwise. | ||
<p> | ||
The game is won if you're able to discard all the monster cards in the tableau. | ||
|
||
<h3>Notes</h3> | ||
<p> | ||
Clear the Dungeon was invented by Mark S. Ball. More details can be found | ||
on <a href="https://www.riffleshuffleandroll.com/clear-the-dungeon">his website</a>. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
#!/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 \ | ||
AbstractFoundationStack, \ | ||
BasicRowStack, \ | ||
OpenStack, \ | ||
ReserveStack, \ | ||
TalonStack | ||
from pysollib.util import ANY_SUIT, JACK, KING, NO_RANK, QUEEN | ||
|
||
# ************************************************************************ | ||
# * Clear the Dungeon | ||
# ************************************************************************ | ||
|
||
|
||
class ClearTheDungeon_RowStack(BasicRowStack): | ||
def acceptsCards(self, from_stack, cards): | ||
cardnum = 0 | ||
goal_rank = 0 | ||
goal_suit = 0 | ||
total = 0 | ||
for card in self.cards: | ||
if card.face_up: | ||
if cardnum == 0: | ||
goal_rank = card.rank + 1 | ||
goal_suit = card.suit | ||
elif cardnum == 1: | ||
if card.suit == 4: | ||
total += 10 | ||
else: | ||
total += (card.rank + 1) | ||
cardnum += 1 | ||
if cards[0].suit == 4: | ||
new_val = 10 | ||
else: | ||
new_val = cards[0].rank + 1 | ||
if cardnum == 1: | ||
if new_val + 10 < goal_rank: | ||
return False | ||
if cardnum == 2: | ||
if total + new_val < goal_rank: | ||
return False | ||
elif cardnum == 3: | ||
if cards[0].suit not in (goal_suit, 4): | ||
return False | ||
|
||
return BasicRowStack.acceptsCards(self, from_stack, cards) | ||
|
||
|
||
class ClearTheDungeon(Game): | ||
# | ||
# game layout | ||
# | ||
|
||
def createGame(self): | ||
# create layout | ||
l, s = Layout(self), self.s | ||
|
||
# set window | ||
self.setSize(l.XM + 5 * l.XS, | ||
l.YM + 2 * l.YS + 12 * l.YOFFSET) | ||
|
||
# create stacks | ||
x, y = l.XM, l.YM | ||
for i in range(4): | ||
s.rows.append(ClearTheDungeon_RowStack(x, y, self, | ||
max_move=0, max_accept=1, | ||
dir=0, base_rank=NO_RANK)) | ||
x += l.XS | ||
s.foundations.append(AbstractFoundationStack(x, y, self, suit=ANY_SUIT, | ||
max_move=0, max_accept=0, | ||
max_cards=52)) | ||
x, y = l.XM, self.height - l.YS | ||
for i in range(3): | ||
s.reserves.append(OpenStack(x, y, self, max_cards=1, max_accept=0)) | ||
x += l.XS | ||
|
||
x += l.XS | ||
s.talon = TalonStack(x, y, self) | ||
l.createText(s.talon, "sw") | ||
|
||
y -= l.YS | ||
s.reserves.append(ReserveStack(x, y, self, max_accept=1, max_move=1, | ||
max_cards=52)) | ||
|
||
# define stack-groups | ||
l.defaultStackGroups() | ||
|
||
def _shuffleHook(self, cards): | ||
topcards = [] | ||
for c in cards[:]: | ||
if c.rank in (JACK, QUEEN, KING): | ||
topcards.append(c) | ||
cards.remove(c) | ||
topcards.reverse() | ||
return cards + topcards | ||
|
||
def startGame(self): | ||
for r in self.s.rows: | ||
for j in range(2): | ||
self.s.talon.dealRow(rows=[r], flip=0, frames=0) | ||
self.startDealSample() | ||
self.s.talon.dealRow(rows=self.s.rows) | ||
self.s.talon.dealRow(rows=self.s.reserves[:3]) | ||
|
||
def fillStack(self, stack): | ||
old_state = self.enterState(self.S_FILL) | ||
|
||
for s in self.s.rows: | ||
num_cards = 0 | ||
for c in s.cards: | ||
if c.face_up: | ||
num_cards += 1 | ||
if num_cards == 4: | ||
s.moveMove(4, self.s.foundations[0]) | ||
if len(s.cards) > 0: | ||
s.flipMove() | ||
|
||
if stack in self.s.reserves[:3]: | ||
for stack in self.s.reserves[:3]: | ||
if stack.cards: | ||
self.leaveState(old_state) | ||
return | ||
self.s.talon.dealRow(rows=self.s.reserves[:3], sound=1) | ||
self.leaveState(old_state) | ||
|
||
def isGameWon(self): | ||
for s in self.s.rows: | ||
if len(s.cards) > 0: | ||
return False | ||
return True | ||
|
||
def getAutoStacks(self, event=None): | ||
return ((), (), self.sg.dropstacks) | ||
|
||
|
||
# register the game | ||
registerGame(GameInfo(909, ClearTheDungeon, "Clear the Dungeon", | ||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL, | ||
subcategory=GI.GS_JOKER_DECK, trumps=list(range(2)))) |