#!/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 . # # --------------------------------------------------------------------------- from pysollib.game import Game from pysollib.gamedb import GI, GameInfo, registerGame from pysollib.layout import Layout from pysollib.stack import \ AbstractFoundationStack, \ BasicRowStack, \ DealRowTalonStack from pysollib.util import ANY_RANK, CLUB, HEART # ************************************************************************ # * Knockout # * Knockout + # ************************************************************************ class Knockout_Talon(DealRowTalonStack): def dealCards(self, sound=False): game = self.game if game.cards_dealt == game.DEALS_BEFORE_SHUFFLE: if self.canDealCards(): old_state = game.enterState(game.S_FILL) game.saveStateMove(2 | 16) # for undo self.game.cards_dealt = 0 game.saveStateMove(1 | 16) # for redo game.leaveState(old_state) self.redealCards() else: return False old_state = game.enterState(game.S_FILL) game.saveStateMove(2 | 16) # for undo self.game.cards_dealt += 1 game.saveStateMove(1 | 16) # for redo game.leaveState(old_state) return DealRowTalonStack.dealCards(self, sound) def canDealCards(self): game = self.game return (game.cards_dealt < game.DEALS_BEFORE_SHUFFLE or self.round < self.max_rounds) def canFlipCard(self): return False def redealCards(self): self.game.startDealSample() for r in self.game.s.rows: if r.cards: while r.cards: self.game.moveMove(1, r, self, frames=4) if self.cards[-1].face_up: self.game.flipMove(self) assert self.round != self.max_rounds self.game.shuffleStackMove(self) self.game.nextRoundMove(self) class Knockout_Foundation(AbstractFoundationStack): def acceptsCards(self, from_stack, cards): return cards[0].suit == self.cap.suit class Knockout(Game): FOUNDATION_SUIT = CLUB DEALS_BEFORE_SHUFFLE = 5 cards_dealt = 0 def createGame(self, rows=3): # create layout l, s = Layout(self), self.s # set window # (piles up to 4 cards are playable in default window size) h = max((2 * l.YS) + l.TEXT_HEIGHT, (4 * l.YOFFSET)) self.setSize(l.XM + (1.5 + rows) * l.XS + l.XM, l.YM + h) # create stacks x0 = l.XM + (l.XS * 1.5) x = x0 y = l.YM for i in range(rows): stack = BasicRowStack(x, y, self, max_cards=5, max_accept=0, max_move=1) s.rows.append(stack) x = x + l.XS self.setRegion(s.rows, (x0-l.XS//2, y-l.CH//2, 999999, 999999)) x, y = l.XM, l.YM s.talon = Knockout_Talon(x, y, self, max_rounds=3) l.createText(s.talon, 'ne') l.createRoundText(s.talon, 's') y = y + l.YS + l.TEXT_HEIGHT s.foundations.append(Knockout_Foundation(x, y, self, max_move=0, base_rank=ANY_RANK, suit=self.FOUNDATION_SUIT)) l.createText(s.foundations[0], 'se') # define stack-groups l.defaultStackGroups() return l def isGameWon(self): return len(self.s.foundations[0].cards) == self.gameinfo.ncards / 4 # # game overrides # def startGame(self): self.cards_dealt = 0 self.startDealSample() self.s.talon.dealCards() shallHighlightMatch = Game._shallHighlightMatch_SS def fillStack(self, stack): if stack in self.s.rows: old_state = self.enterState(self.S_FILL) if not self.s.talon.cards[-1].face_up: self.s.talon.flipMove() self.s.talon.moveMove(1, stack, 4) self.leaveState(old_state) def _restoreGameHook(self, game): self.cards_dealt = game.loadinfo.cards_dealt def _loadGameHook(self, p): self.loadinfo.addattr(cards_dealt=p.load()) def _saveGameHook(self, p): p.dump(self.cards_dealt) def getHighlightPilesStacks(self): return () def setState(self, state): # restore saved vars (from undo/redo) self.cards_dealt = state[0] def getState(self): # save vars (for undo/redo) return [self.cards_dealt] class KnockoutPlus(Knockout): DEALS_BEFORE_SHUFFLE = 8 # ************************************************************************ # * Herz zu Herz # ************************************************************************ class HerzZuHerz(Knockout): FOUNDATION_SUIT = HEART def fillStack(self, stack): pass # register the game registerGame(GameInfo(850, Knockout, "Knockout", GI.GT_1DECK_TYPE | GI.GT_STRIPPED, 1, 2, GI.SL_LUCK, altnames=("Hope Deferred", "Hope"), ranks=(0, 6, 7, 8, 9, 10, 11, 12))) registerGame(GameInfo(851, HerzZuHerz, "Herz zu Herz", GI.GT_1DECK_TYPE | GI.GT_STRIPPED, 1, 2, GI.SL_LUCK, ranks=(0, 6, 7, 8, 9, 10, 11, 12))) registerGame(GameInfo(872, KnockoutPlus, "Knockout +", GI.GT_1DECK_TYPE, 1, 2, GI.SL_LUCK, altnames=("Abandon Hope",)))