#!/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 . # # --------------------------------------------------------------------------- import os from pysollib.gamedb import GI, hideGame, loadGame from pysollib.layout import Layout from pysollib.mygettext import _, n_ from pysollib.stack import AC_FoundationStack, \ AC_RowStack, \ BO_FoundationStack, \ BO_RowStack, \ BasicRowStack, \ DealFirstRowRedealTalonStack, \ DealReserveRedealTalonStack, \ DealRowRedealTalonStack, \ GroundsForADivorceTalonStack, \ InitialDealTalonStack, \ RK_FoundationStack, \ RK_RowStack, \ SC_FoundationStack, \ SC_RowStack, \ SS_FoundationStack, \ SS_RowStack, \ SpiderTalonStack, \ Spider_AC_Foundation, \ Spider_AC_RowStack, \ Spider_BO_Foundation, \ Spider_BO_RowStack, \ Spider_RK_Foundation, \ Spider_SC_Foundation, \ Spider_SC_RowStack, \ Spider_SS_Foundation, \ Spider_SS_RowStack, \ UD_AC_RowStack, \ UD_BO_RowStack, \ UD_RK_RowStack, \ UD_SC_RowStack, \ UD_SS_RowStack, \ WasteTalonStack, \ Yukon_AC_RowStack, \ Yukon_BO_RowStack, \ Yukon_RK_RowStack, \ Yukon_SC_RowStack, \ Yukon_SS_RowStack from pysollib.util import ACE, ANY_RANK, KING, NO_RANK, UNLIMITED_MOVES from pysollib.wizardpresets import presets # ************************************************************************ # * # ************************************************************************ class WizSetting: def __init__(self, values_map, default, var_name, label, widget='menu'): self.values_map = values_map self.default = default # self.values_dict = dict(self.values_map) self.translation_map = {} # for backward translation if widget == 'menu': self.values = [] for k, v in self.values_map: self.values.append(k) self.translation_map[_(k)] = k assert self.default in self.values elif widget == 'preset': self.values = [] for v in self.values_map: self.values.append(v) self.translation_map[_(v)] = v assert self.default in self.values else: self.values = self.values_map self.var_name = var_name self.label = label self.widget = widget self.variable = None # Tk variable self.current_value = None WizardPresets = WizSetting( values_map=list(presets.keys()), default='None', widget='preset', label=_('Initial setting:'), var_name='preset', ) GameName = WizSetting( values_map=(), default=_('My Game'), widget='entry', label=_('Name:'), var_name='name', ) SkillLevel = WizSetting( values_map=((n_('Luck only'), GI.SL_LUCK), (n_('Mostly luck'), GI.SL_MOSTLY_LUCK), (n_('Balanced'), GI.SL_BALANCED), (n_('Mostly skill'), GI.SL_MOSTLY_SKILL), (n_('Skill only'), GI.SL_SKILL), ), default=n_('Balanced'), label=_('Skill level:'), var_name='skill_level', ) NumDecks = WizSetting( values_map=((n_('One'), 1), (n_('Two'), 2), (n_('Three'), 3), (n_('Four'), 4)), default=n_('One'), label=_('Number of decks:'), var_name='decks', ) LayoutType = WizSetting( values_map=((n_('FreeCell'), Layout.freeCellLayout), (n_('Klondike'), Layout.klondikeLayout), (n_('Gypsy'), Layout.gypsyLayout), (n_('Harp'), Layout.harpLayout), ), default=n_('FreeCell'), label=_('Layout:'), var_name='layout', ) TalonType = WizSetting( values_map=((n_('Deal all cards at the beginning'), InitialDealTalonStack), (n_('Deal to waste'), WasteTalonStack), (n_('Deal to tableau'), DealRowRedealTalonStack), (n_('Deal to first tableau'), DealFirstRowRedealTalonStack), (n_('Deal to reserves'), DealReserveRedealTalonStack), (n_('Spider'), SpiderTalonStack), (n_('Grounds for a Divorce'), GroundsForADivorceTalonStack), ), default=n_('Deal all cards at the beginning'), label=_('Type:'), var_name='talon', ) Redeals = WizSetting( values_map=((n_('No redeals'), 0), (n_('One redeal'), 1), (n_('Two redeals'), 2), (n_('Three redeals'), 3), (n_('Unlimited redeals'), -1), ), default=n_('No redeals'), label=_('Number of redeals:'), var_name='redeals', ) DealToWaste = WizSetting( values_map=(1, 5), default=1, widget='spin', label=_('# of cards dealt to the waste:'), var_name='deal_to_waste', ) TalonShuffle = WizSetting( values_map=(0, 1), default=0, label=_('Shuffle during redeal:'), var_name='talon_shuffle', widget='check', ) FoundType = WizSetting( values_map=((n_('Same suit'), SS_FoundationStack), (n_('Alternate color'), AC_FoundationStack), (n_('Same color'), SC_FoundationStack), (n_('Rank'), RK_FoundationStack), (n_('Any suit but the same'), BO_FoundationStack), (n_('Spider same suit'), Spider_SS_Foundation), (n_('Spider alternate color'), Spider_AC_Foundation), (n_('Spider same color'), Spider_SC_Foundation), (n_('Spider rank'), Spider_RK_Foundation), (n_('Spider any suit but the same'), Spider_BO_Foundation), ), default=n_('Same suit'), label=_('Type:'), var_name='found_type', ) FoundBaseCard = WizSetting( values_map=((n_('Ace'), ACE), (n_('King'), KING), (n_('Any'), ANY_RANK), ), default=n_('Ace'), label=_('Base card:'), var_name='found_base_card', ) FoundDir = WizSetting( values_map=((n_('Up'), 1), (n_('Down'), -1)), default=n_('Up'), label=_('Direction:'), var_name='found_dir', ) FoundMaxMove = WizSetting( values_map=((n_('None'), 0,), (n_('Top card'), 1)), default=n_('Top card'), label=_('Move:'), var_name='found_max_move', ) FoundEqual = WizSetting( values_map=(0, 1), default=1, label=_('First card sets base cards:'), var_name='found_equal', widget='check', ) RowsNum = WizSetting( values_map=(1, 20), default=8, widget='spin', label=_('Number of tableau piles:'), var_name='rows_num', ) RowsType = WizSetting( values_map=((n_('No building'), BasicRowStack), (n_('Same suit'), SS_RowStack), (n_('Alternate color'), AC_RowStack), (n_('Same color'), SC_RowStack), (n_('Rank'), RK_RowStack), (n_('Any suit but the same'), BO_RowStack), (n_('Up or down by same suit'), UD_SS_RowStack), (n_('Up or down by alternate color'), UD_AC_RowStack), (n_('Up or down by same color'), UD_SC_RowStack), (n_('Up or down by rank'), UD_RK_RowStack), (n_('Up or down by any suit but the same'), UD_BO_RowStack), (n_('Spider same suit'), Spider_SS_RowStack), (n_('Spider alternate color'), Spider_AC_RowStack), (n_('Spider same color'), Spider_SC_RowStack), (n_('Spider any suit but the same'), Spider_BO_RowStack), (n_('Yukon same suit'), Yukon_SS_RowStack), (n_('Yukon alternate color'), Yukon_AC_RowStack), (n_('Yukon same color'), Yukon_SC_RowStack), (n_('Yukon rank'), Yukon_RK_RowStack), (n_('Yukon any suit but the same'), Yukon_BO_RowStack), ), default=n_('Alternate color'), label=_('Type:'), var_name='rows_type', ) RowsBaseCard = WizSetting( values_map=((n_('Ace'), ACE), (n_('King'), KING), (n_('Any'), ANY_RANK), (n_('None'), NO_RANK), ), default=n_('Any'), label=_('Base card:'), var_name='rows_base_card', ) RowsDir = WizSetting( values_map=((n_('Up'), 1), (n_('Down'), -1), (n_('Same rank'), 0)), default=n_('Down'), label=_('Direction:'), var_name='rows_dir', ) RowsMaxMove = WizSetting( values_map=((n_('Top card'), 1), (n_('Sequence'), UNLIMITED_MOVES)), default=n_('Sequence'), label=_('Move:'), var_name='rows_max_move', ) RowsWrap = WizSetting( values_map=(0, 1), default=0, label=_('Wrapping:'), var_name='rows_wrap', widget='check', ) RowsSuperMove = WizSetting( values_map=(0, 1), default=0, label=_('Use "Super Move" feature:'), var_name='rows_super_move', widget='check', ) ReservesNum = WizSetting( values_map=(0, 20), default=4, widget='spin', label=_('Number of reserves:'), var_name='reserves_num', ) ReservesMaxAccept = WizSetting( values_map=(0, 20), default=1, widget='spin', label=_('Max # of accepted cards:'), var_name='reserves_max_accept', ) DealType = WizSetting( values_map=((n_('Triangle'), 'triangle'), (n_('Rectangle'), 'rectangle'), (n_('Pyramid'), 'pyramid') ), default=n_('Rectangle'), label=_('Type:'), var_name='deal_type', ) DealFaceDown = WizSetting( values_map=(0, 20), default=0, widget='spin', label=_('# of face-down cards dealt to the tableau pile:'), var_name='deal_face_down', ) DealFaceUp = WizSetting( values_map=(0, 20), default=8, widget='spin', label=_('# of face-up cards dealt to the tableau pile:'), var_name='deal_face_up', ) DealToReseves = WizSetting( values_map=(0, 208), default=0, widget='spin', label=_('# of cards dealt to the reserve:'), var_name='deal_to_reserves', ) DealMaxCards = WizSetting( values_map=(0, 208), default=52, widget='spin', label=_('Max # of dealt cards:'), var_name='deal_max_cards', ) DealToFound = WizSetting( values_map=(0, 1), default=0, label=_('Deal first cards to the foundations:'), var_name='deal_found', widget='check', ) WizardWidgets = ( _('General'), WizardPresets, GameName, SkillLevel, NumDecks, LayoutType, _('Talon'), TalonType, Redeals, DealToWaste, TalonShuffle, _('Foundations'), FoundType, FoundBaseCard, FoundDir, FoundMaxMove, FoundEqual, _('Tableau'), RowsNum, RowsType, RowsBaseCard, RowsDir, RowsMaxMove, RowsWrap, RowsSuperMove, _('Reserves'), ReservesNum, ReservesMaxAccept, _('Opening deal'), DealType, DealFaceDown, DealFaceUp, DealToReseves, DealMaxCards, DealToFound, ) def write_game(app, game=None): import pysollib.customgame # for py2exe pysollib.customgame.no_use() if game is None: # new game d = app.dn.plugins n = 1 while True: fn = os.path.join(d, 'customgame%d.py' % n) # file name mn = 'customgame%d' % n # module name gameid = 200000+n if not os.path.exists(fn): break n += 1 check_game = True else: # edit current game fn = game.MODULE_FILENAME mn = game.__module__ gameid = game.SETTINGS['gameid'] check_game = False # print '===>', fn with open(fn, 'w') as fd: fd.write('''\ ## -*- coding: utf-8 -*- ## THIS FILE WAS GENERATED AUTOMATICALLY BY THE SOLITAIRE WIZARD ## DO NOT EDIT from pysollib.customgame import CustomGame, registerCustomGame class MyCustomGame(CustomGame): WIZARD_VERSION = 1 SETTINGS = { ''') for w in WizardWidgets: if isinstance(w, str): continue v = w.variable.get() if w.widget in ('menu', 'preset'): v = w.translation_map[v] if v == w.default: # save only unique values continue if isinstance(v, int): fd.write(" '%s': %i,\n" % (w.var_name, v)) else: if w.var_name == 'name': # escape v = v.replace('\\', '\\\\') v = v.replace("'", "\\'") v = v.replace("\n", "\\n") v = v.replace("\r", "\\r") v = v.replace("\t", "\\t") # See: https://github.com/shlomif/PySolFC/issues/177 # if isinstance(v, str): # v = v.encode('utf-8') if not v: v = 'Invalid Game Name' fd.write(" '{}': '{}',\n".format(w.var_name, v)) fd.write(" 'gameid': %i,\n" % gameid) fd.write('''\ } registerCustomGame(MyCustomGame) ''') loadGame(mn, fn, check_game=check_game) return gameid def delete_game(app, game): hideGame(game) app.stats.deleteGameStats(game.id) fn = game.MODULE_FILENAME os.remove(fn) def reset_wizard(game): for w in WizardWidgets: if isinstance(w, str): continue if game is None: # set to default v = w.default else: # set from current game if w.var_name in game.SETTINGS: v = game.SETTINGS[w.var_name] else: v = w.default w.current_value = v