Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added detailed comments - clearthedungeon.py #405

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 49 additions & 22 deletions pysollib/games/clearthedungeon.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,58 @@
#
# ---------------------------------------------------------------------------##

# Importing necessary classes from the `pysollib` package to define the game
# and its components
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.stack import (
AbstractFoundationStack,
BasicRowStack,
OpenStack,
ReserveStack,
TalonStack
)
from pysollib.util import ANY_SUIT, JACK, KING, NO_RANK, QUEEN

# ************************************************************************
# * Clear the Dungeon
# * Clear the Dungeon (Game Definition)
# ************************************************************************


# Define a custom RowStack class for the "Clear the Dungeon" game
class ClearTheDungeon_RowStack(BasicRowStack):
# Function that checks whether a move (card placement) is valid
def acceptsCards(self, from_stack, cards):
cardnum = 0
goal_rank = 0
goal_suit = 0
total = 0

# Loop through the cards in the row to establish game rules for
# accepting new cards
for card in self.cards:
if card.face_up:
if card.face_up: # Only consider face-up cards
if cardnum == 0:
# Set the goal rank and suit based on the first face-up
# card
goal_rank = card.rank + 1
goal_suit = card.suit
elif cardnum == 1:
# Add a value of 10 if the card is a joker, otherwise
# add its rank
if card.suit == 4:
total += 10
else:
total += (card.rank + 1)
cardnum += 1
if cards[0].suit == 4:

# Determine the value of the new card being played
if cards[0].suit == 4: # Joker
new_val = 10
else:
new_val = cards[0].rank + 1

# Ensure the new card follows the rules for valid placement
if cardnum == 1:
if new_val + 10 < goal_rank:
return False
Expand All @@ -68,23 +83,25 @@ def acceptsCards(self, from_stack, cards):
if cards[0].suit not in (goal_suit, 4):
return False

# If all conditions are satisfied, call the base class function
return BasicRowStack.acceptsCards(self, from_stack, cards)


# Define the main game class for "Clear the Dungeon"
class ClearTheDungeon(Game):
#
# game layout
# Define the layout of the game
#

def createGame(self):
# create layout
# Create the game layout
l, s = Layout(self), self.s

# set window
self.setSize(l.XM + 5 * l.XS,
l.YM + 2 * l.YS + 12 * l.YOFFSET)
# Set the window size for the game layout
self.setSize(l.XM + 5 * l.XS, l.YM + 2 * l.YS + 12 * l.YOFFSET)

# create stacks
# Create different stacks in the game (rows, foundations, reserves,
# talon)
x, y = l.XM, l.YM
for i in range(4):
s.rows.append(ClearTheDungeon_RowStack(x, y, self,
Expand All @@ -94,42 +111,49 @@ def createGame(self):
s.foundations.append(AbstractFoundationStack(x, y, self, suit=ANY_SUIT,
max_move=0, max_accept=0,
max_cards=52))
# Position reserve stacks
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)
s.talon = TalonStack(x, y, self) # Create the Talon stack
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
# Define default stack groups for easier management
l.defaultStackGroups()

# Custom shuffle behavior to ensure that Jacks, Queens, and Kings are
# dealt last
def _shuffleHook(self, cards):
topcards = []
for c in cards[:]:
if c.rank in (JACK, QUEEN, KING):
topcards.append(c)
cards.remove(c)
topcards.reverse()
topcards.reverse() # Reverses the topcards to keep Jacks on top
return cards + topcards

# Initialize the game and deal the first cards
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.startDealSample() # Deals sample cards for the game
self.s.talon.dealRow(rows=self.s.rows)
self.s.talon.dealRow(rows=self.s.reserves[:3])

# Function to manage the auto-filling of stacks
def fillStack(self, stack):
old_state = self.enterState(self.S_FILL)

# Move cards from the row stack to the foundation if certain
# conditions are met
for s in self.s.rows:
num_cards = 0
for c in s.cards:
Expand All @@ -140,6 +164,7 @@ def fillStack(self, stack):
if len(s.cards) > 0:
s.flipMove()

# If the stack is in the reserves, deal a row from the talon
if stack in self.s.reserves[:3]:
for stack in self.s.reserves[:3]:
if stack.cards:
Expand All @@ -148,17 +173,19 @@ def fillStack(self, stack):
self.s.talon.dealRow(rows=self.s.reserves[:3], sound=1)
self.leaveState(old_state)

# Check if the game is won
def isGameWon(self):
for s in self.s.rows:
if len(s.cards) > 0:
return False
return True

# Return the auto-stacks for automatic card moves
def getAutoStacks(self, event=None):
return ((), (), self.sg.dropstacks)


# register the game
# Register the game in the game's database
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))))