pywargame 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. pywargame/__init__.py +2 -0
  2. pywargame/common/__init__.py +3 -0
  3. pywargame/common/collector.py +87 -0
  4. pywargame/common/dicedraw.py +363 -0
  5. pywargame/common/drawdice.py +40 -0
  6. pywargame/common/singleton.py +22 -0
  7. pywargame/common/test.py +25 -0
  8. pywargame/common/verbose.py +59 -0
  9. pywargame/common/verboseguard.py +53 -0
  10. pywargame/cyberboard/__init__.py +18 -0
  11. pywargame/cyberboard/archive.py +283 -0
  12. pywargame/cyberboard/base.py +63 -0
  13. pywargame/cyberboard/board.py +462 -0
  14. pywargame/cyberboard/cell.py +200 -0
  15. pywargame/cyberboard/collect.py +49 -0
  16. pywargame/cyberboard/collectgbx0pwd.py +30 -0
  17. pywargame/cyberboard/collectgbxext.py +30 -0
  18. pywargame/cyberboard/collectgsnexp.py +32 -0
  19. pywargame/cyberboard/collectgsnext.py +30 -0
  20. pywargame/cyberboard/draw.py +396 -0
  21. pywargame/cyberboard/exporter.py +1132 -0
  22. pywargame/cyberboard/extractor.py +240 -0
  23. pywargame/cyberboard/features.py +17 -0
  24. pywargame/cyberboard/gamebox.py +81 -0
  25. pywargame/cyberboard/gbxexp.py +76 -0
  26. pywargame/cyberboard/gbxext.py +64 -0
  27. pywargame/cyberboard/gsnexp.py +147 -0
  28. pywargame/cyberboard/gsnext.py +59 -0
  29. pywargame/cyberboard/head.py +111 -0
  30. pywargame/cyberboard/image.py +76 -0
  31. pywargame/cyberboard/main.py +47 -0
  32. pywargame/cyberboard/mark.py +102 -0
  33. pywargame/cyberboard/palette.py +36 -0
  34. pywargame/cyberboard/piece.py +169 -0
  35. pywargame/cyberboard/player.py +36 -0
  36. pywargame/cyberboard/scenario.py +115 -0
  37. pywargame/cyberboard/testgrid.py +156 -0
  38. pywargame/cyberboard/tile.py +121 -0
  39. pywargame/cyberboard/tray.py +68 -0
  40. pywargame/cyberboard/windows.py +41 -0
  41. pywargame/cyberboard/zeropwd.py +45 -0
  42. pywargame/cyberboard.py +2728 -0
  43. pywargame/gbx0pwd.py +2776 -0
  44. pywargame/gbxextract.py +2795 -0
  45. pywargame/gsnexport.py +16499 -0
  46. pywargame/gsnextract.py +2790 -0
  47. pywargame/latex/__init__.py +2 -0
  48. pywargame/latex/collect.py +34 -0
  49. pywargame/latex/latexexporter.py +4010 -0
  50. pywargame/latex/main.py +184 -0
  51. pywargame/vassal/__init__.py +66 -0
  52. pywargame/vassal/base.py +139 -0
  53. pywargame/vassal/board.py +243 -0
  54. pywargame/vassal/buildfile.py +60 -0
  55. pywargame/vassal/chart.py +79 -0
  56. pywargame/vassal/chessclock.py +197 -0
  57. pywargame/vassal/collect.py +98 -0
  58. pywargame/vassal/collectpatch.py +28 -0
  59. pywargame/vassal/command.py +21 -0
  60. pywargame/vassal/documentation.py +322 -0
  61. pywargame/vassal/dumpcollect.py +28 -0
  62. pywargame/vassal/dumpvsav.py +28 -0
  63. pywargame/vassal/element.py +439 -0
  64. pywargame/vassal/exporter.py +89 -0
  65. pywargame/vassal/extension.py +101 -0
  66. pywargame/vassal/folder.py +103 -0
  67. pywargame/vassal/game.py +940 -0
  68. pywargame/vassal/gameelements.py +1091 -0
  69. pywargame/vassal/globalkey.py +127 -0
  70. pywargame/vassal/globalproperty.py +433 -0
  71. pywargame/vassal/grid.py +573 -0
  72. pywargame/vassal/map.py +1061 -0
  73. pywargame/vassal/mapelements.py +1020 -0
  74. pywargame/vassal/merge.py +57 -0
  75. pywargame/vassal/merger.py +460 -0
  76. pywargame/vassal/moduledata.py +275 -0
  77. pywargame/vassal/mrgcollect.py +31 -0
  78. pywargame/vassal/patch.py +44 -0
  79. pywargame/vassal/patchcollect.py +28 -0
  80. pywargame/vassal/player.py +83 -0
  81. pywargame/vassal/save.py +495 -0
  82. pywargame/vassal/skel.py +380 -0
  83. pywargame/vassal/trait.py +224 -0
  84. pywargame/vassal/traits/__init__.py +36 -0
  85. pywargame/vassal/traits/area.py +50 -0
  86. pywargame/vassal/traits/basic.py +35 -0
  87. pywargame/vassal/traits/calculatedproperty.py +22 -0
  88. pywargame/vassal/traits/cargo.py +29 -0
  89. pywargame/vassal/traits/click.py +41 -0
  90. pywargame/vassal/traits/clone.py +28 -0
  91. pywargame/vassal/traits/delete.py +24 -0
  92. pywargame/vassal/traits/deselect.py +32 -0
  93. pywargame/vassal/traits/dynamicproperty.py +112 -0
  94. pywargame/vassal/traits/globalcommand.py +55 -0
  95. pywargame/vassal/traits/globalhotkey.py +26 -0
  96. pywargame/vassal/traits/globalproperty.py +54 -0
  97. pywargame/vassal/traits/hide.py +67 -0
  98. pywargame/vassal/traits/label.py +76 -0
  99. pywargame/vassal/traits/layer.py +105 -0
  100. pywargame/vassal/traits/mark.py +20 -0
  101. pywargame/vassal/traits/mask.py +85 -0
  102. pywargame/vassal/traits/mat.py +26 -0
  103. pywargame/vassal/traits/moved.py +35 -0
  104. pywargame/vassal/traits/movefixed.py +51 -0
  105. pywargame/vassal/traits/nonrect.py +95 -0
  106. pywargame/vassal/traits/nostack.py +55 -0
  107. pywargame/vassal/traits/place.py +104 -0
  108. pywargame/vassal/traits/prototype.py +20 -0
  109. pywargame/vassal/traits/report.py +34 -0
  110. pywargame/vassal/traits/restrictaccess.py +28 -0
  111. pywargame/vassal/traits/restrictcommand.py +32 -0
  112. pywargame/vassal/traits/return.py +40 -0
  113. pywargame/vassal/traits/rotate.py +62 -0
  114. pywargame/vassal/traits/sendto.py +59 -0
  115. pywargame/vassal/traits/sheet.py +129 -0
  116. pywargame/vassal/traits/skel.py +9 -0
  117. pywargame/vassal/traits/stack.py +28 -0
  118. pywargame/vassal/traits/submenu.py +27 -0
  119. pywargame/vassal/traits/trail.py +61 -0
  120. pywargame/vassal/traits/trigger.py +72 -0
  121. pywargame/vassal/turn.py +272 -0
  122. pywargame/vassal/upgrade.py +191 -0
  123. pywargame/vassal/vmod.py +323 -0
  124. pywargame/vassal/vsav.py +100 -0
  125. pywargame/vassal/widget.py +358 -0
  126. pywargame/vassal/withtraits.py +634 -0
  127. pywargame/vassal/xml.py +4 -0
  128. pywargame/vassal/zone.py +399 -0
  129. pywargame/vassal.py +12500 -0
  130. pywargame/vmodpatch.py +12548 -0
  131. pywargame/vsavdump.py +12533 -0
  132. pywargame/vslmerge.py +13015 -0
  133. pywargame/wgexport.py +16689 -0
  134. pywargame/ztexport.py +14351 -0
  135. pywargame/zuntzu/__init__.py +5 -0
  136. pywargame/zuntzu/base.py +82 -0
  137. pywargame/zuntzu/collect.py +38 -0
  138. pywargame/zuntzu/countersheet.py +250 -0
  139. pywargame/zuntzu/dicehand.py +48 -0
  140. pywargame/zuntzu/exporter.py +936 -0
  141. pywargame/zuntzu/gamebox.py +154 -0
  142. pywargame/zuntzu/map.py +36 -0
  143. pywargame/zuntzu/piece.py +37 -0
  144. pywargame/zuntzu/scenario.py +208 -0
  145. pywargame/zuntzu/ztexp.py +115 -0
  146. pywargame-0.3.1.dist-info/METADATA +353 -0
  147. pywargame-0.3.1.dist-info/RECORD +150 -0
  148. pywargame-0.3.1.dist-info/WHEEL +5 -0
  149. pywargame-0.3.1.dist-info/licenses/LICENSE +5 -0
  150. pywargame-0.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,272 @@
1
+ ## BEGIN_IMPORT
2
+ from common import VerboseGuard
3
+ from . base import *
4
+ from . element import Element
5
+ ## END_IMPORT
6
+
7
+ # --------------------------------------------------------------------
8
+ class TurnLevel(Element):
9
+ UNIQUE = ['property']
10
+ def __init__(self,elem,tag,node=None,**kwargs):
11
+ super(TurnLevel,self).__init__(elem,tag,node=node,**kwargs)
12
+
13
+ def addLevel(self,counter=None,phases=None):
14
+ '''Add a `Level` element to this
15
+
16
+ Parameters
17
+ ----------
18
+ kwargs : dict
19
+ Dictionary of attribute key-value pairs
20
+
21
+ Returns
22
+ -------
23
+ element : Level
24
+ The added element
25
+ '''
26
+ if counter is None and phases is None:
27
+ return self
28
+
29
+ t = TurnCounter if counter is not None else TurnList
30
+ o = counter if counter is not None else phases
31
+
32
+ subcounter = o.pop('counter',None)
33
+ subphases = o.pop('phases',None)
34
+
35
+ s = t(self,node=None,**o)
36
+
37
+ return s.addLevel(subcounter, subphases)
38
+
39
+ def getUp(self):
40
+ return self.getParent(TurnLevel)
41
+ def addCounter(self,**kwargs):
42
+ '''Add a `Counter` element to this
43
+
44
+ Parameters
45
+ ----------
46
+ kwargs : dict
47
+ Dictionary of attribute key-value pairs
48
+
49
+ Returns
50
+ -------
51
+ element : Counter
52
+ The added element
53
+ '''
54
+ return self.add(self,TurnCounter,**kwargs)
55
+ def addList(self,**kwargs):
56
+ '''Add a `List` element to this
57
+
58
+ Parameters
59
+ ----------
60
+ kwargs : dict
61
+ Dictionary of attribute key-value pairs
62
+
63
+ Returns
64
+ -------
65
+ element : List
66
+ The added element
67
+ '''
68
+ return self.add(self,TurnList,**kwargs)
69
+ def getCounter(self):
70
+ return self.getAllElements(TurnCounter)
71
+ def getList(self):
72
+ return self.getAllElements(TurnList)
73
+
74
+ # --------------------------------------------------------------------
75
+ class TurnTrack(TurnLevel):
76
+ TAG = Element.MODULE+'turn.TurnTracker'
77
+ UNIQUE = ['name']
78
+ MAXIMUM = 'Maximum'
79
+ FIXED = 'Fixed'
80
+ VARIABLE = 'Variable'
81
+ def __init__(self,elem,node=None,
82
+ name = '',
83
+ buttonText = 'Turn',
84
+ hotkey = '',
85
+ icon = '',
86
+ length = -1,
87
+ lengthStyle = MAXIMUM,
88
+ nexthotkey = key('T',ALT),
89
+ plusButtonSize = 22,
90
+ prevhotkey = key('T',ALT_SHIFT),
91
+ reportFormat = 'Turn updated from $oldTurn$ to $newTurn$',
92
+ turnButtonHeight = 22,
93
+ fwdOnly = True,
94
+ turnFormat = None,
95
+ counter = None,
96
+ phases = None):
97
+ levels = (counter if counter is not None else
98
+ phases if phases is not None else None)
99
+ if levels is not None:
100
+ lvl = 1
101
+ lvls = [f'$level{lvl}$']
102
+ sub = levels
103
+ while True:
104
+ sub = sub.get('counter',sub.get('phases',None))
105
+ if sub is None:
106
+ break
107
+ lvl += 1
108
+ lvls.append(f'$level{lvl}$')
109
+
110
+ turnFormat = ' '.join(lvls)
111
+
112
+ if turnFormat is None:
113
+ turnFormat = '$level1$ $level2$ $level3$ $level4$'
114
+
115
+ super(TurnTrack,self).__init__(elem, self.TAG,
116
+ node = node,
117
+ name = name,
118
+ buttonText = buttonText,
119
+ hotkey = hotkey,
120
+ icon = icon,
121
+ length = length,
122
+ lengthStyle = lengthStyle,
123
+ nexthotkey = nexthotkey,
124
+ plusButtonSize = plusButtonSize,
125
+ prevhotkey = prevhotkey,
126
+ reportFormat = reportFormat,
127
+ turnButtonHeight = turnButtonHeight,
128
+ turnFormat = turnFormat)
129
+
130
+ self.addLevel(counter=counter, phases=phases)
131
+
132
+ def getGame(self):
133
+ return self.getParent(Game)
134
+ def getLists(self,asdict=True):
135
+ '''Get all List element(s) from this
136
+
137
+ Parameters
138
+ ----------
139
+ asdict : bool
140
+ If `True`, return a dictonary that maps key to `List`
141
+ elements. If `False`, return a list of all List`
142
+ children.
143
+
144
+ Returns
145
+ -------
146
+ children : dict or list
147
+ Dictionary or list of `List` children
148
+
149
+ '''
150
+ return self.getElementsByKey(TurnList,'property',asdict=asdict)
151
+ def getCounters(self,asdict=True):
152
+ '''Get all Counter element(s) from this
153
+
154
+ Parameters
155
+ ----------
156
+ asdict : bool
157
+ If `True`, return a dictonary that maps key to `Counter`
158
+ elements. If `False`, return a list of all Counter`
159
+ children.
160
+
161
+ Returns
162
+ -------
163
+ children : dict or list
164
+ Dictionary or list of `Counter` children
165
+
166
+ '''
167
+ return self.getElementsByKey(TurnCounter,'property',asdict=asdict)
168
+ def addHotkey(self,**kwargs):
169
+ '''Add a `Hotkey` element to this
170
+
171
+ Parameters
172
+ ----------
173
+ kwargs : dict
174
+ Dictionary of attribute key-value pairs
175
+
176
+ Returns
177
+ -------
178
+ element : Hotkey
179
+ The added element
180
+ '''
181
+ return self.add(TurnGlobalHotkey,**kwargs)
182
+ def getHotkeys(self,asdict=True):
183
+ return self.getElementsByKey(TurnGlobalHotkey,'name',asdict=asdict)
184
+ def encode(self):
185
+ ret = f'TURN{self["name"]}\t'
186
+
187
+ return []
188
+
189
+ registerElement(TurnTrack)
190
+
191
+ # --------------------------------------------------------------------
192
+ class TurnCounter(TurnLevel):
193
+ TAG = Element.MODULE+"turn.CounterTurnLevel"
194
+ def __init__(self,elem,node=None,
195
+ property = '',
196
+ start = 1,
197
+ incr = 1,
198
+ loop = False,
199
+ loopLimit = -1,
200
+ turnFormat = "$value$"):
201
+ super(TurnCounter,self).__init__(elem,self.TAG,node=node,
202
+ property = property,
203
+ start = start,
204
+ incr = incr,
205
+ loop = loop,
206
+ loopLimit = loopLimit,
207
+ turnFormat = turnFormat)
208
+
209
+ registerElement(TurnCounter)
210
+
211
+ # --------------------------------------------------------------------
212
+ class TurnList(TurnLevel):
213
+ TAG = Element.MODULE+"turn.ListTurnLevel"
214
+ def __init__(self,elem,node=None,
215
+ property = '',
216
+ names = [],
217
+ configFirst = False,
218
+ configList = False,
219
+ turnFormat = '$value$'):
220
+ super(TurnList,self).\
221
+ __init__(elem,self.TAG,node=node,
222
+ property = property,
223
+ list = ','.join([str(p) for p in names]),
224
+ configFirst = configFirst,
225
+ configList = configList,
226
+ turnFormat = turnFormat)
227
+
228
+ registerElement(TurnList)
229
+
230
+ # --------------------------------------------------------------------
231
+ class TurnGlobalHotkey(Element):
232
+ TAG = Element.MODULE+'turn.TurnGlobalHotkey'
233
+ UNIQUE = ['name']
234
+ def __init__(self,elem,
235
+ node = None,
236
+ hotkey = '',
237
+ match = '{true}',
238
+ reportFormat = '',
239
+ name = ''):
240
+ '''Global key activated by turn change
241
+
242
+ Parameters
243
+ ----------
244
+ doc : Element
245
+ Parent
246
+ node : xml.dom.Element
247
+ Node to read state from
248
+ hotkey : str
249
+ What to send (global command)
250
+ match : str
251
+ When to send
252
+ reportFormat : str
253
+ What to what
254
+ name : str
255
+ A free form name
256
+ '''
257
+ super(TurnGlobalHotkey,self).__init__(elem,self.TAG,
258
+ node = node,
259
+ hotkey = hotkey,
260
+ match = match,
261
+ reportFormat = reportFormat,
262
+ name = name)
263
+
264
+ def getTurnTrack(self):
265
+ '''Get the turn track'''
266
+ return self.getParent(TurnTrack)
267
+
268
+ registerElement(TurnGlobalHotkey)
269
+
270
+ #
271
+ # EOF
272
+ #
@@ -0,0 +1,191 @@
1
+ ## BEGIN_IMPORT
2
+ from common import VerboseGuard
3
+ from . base import *
4
+ from . element import Element
5
+ from . command import *
6
+ from . trait import Trait
7
+ from . save import SaveIO
8
+ from . vmod import VMod
9
+ from . buildfile import BuildFile
10
+ from . game import Game
11
+ from . withtraits import PieceSlot
12
+ ## END_IMPORT
13
+
14
+
15
+ class VLogUpgrader:
16
+ def __init__(self,
17
+ vmodFileName,
18
+ vlogFileName,
19
+ verbose=False):
20
+ self._readVModFile(vmodFileName,verbose)
21
+ self._readVLogFile(vlogFileName,verbose)
22
+
23
+ def _readVModFile(self,vmodFileName,verbose=False):
24
+ with VMod(vmodFileName, 'r') as vmod:
25
+ self._build = BuildFile(vmod.getBuildFile())
26
+ self._game = self._build.getGame()
27
+
28
+ self._vmod_pieces = {}
29
+ for piece in self._game.getPieces():
30
+ name, piece = self._expandPiece(piece,verbose)
31
+ self._vmod_pieces[name] = piece
32
+
33
+ def _expandPiece(self,piece,verbose=False):
34
+ traits = piece.getTraits();
35
+ newTraits = Trait.flatten(traits, game=self._game,verbose=verbose)
36
+
37
+ piece.setTraits(*newTraits)
38
+
39
+ name = newTraits[-1]['name']
40
+
41
+ return name, piece
42
+
43
+ def _readVLogFile(self,vlogFileName,verbose=False):
44
+ key, lines, sdata, mdata = SaveIO.readSave(vlogFileName,
45
+ alsometa=True)
46
+
47
+ self._key = key
48
+ self._lines = lines
49
+ self._save_data = sdata
50
+ self._meta_data = mdata
51
+ self._vlog_pieces = {}
52
+
53
+ for line in self._lines:
54
+ iden, name, piece = self._vlogPiece(line,verbose)
55
+ if piece is None:
56
+ continue
57
+
58
+ vmod_piece = self._vmod_pieces.get(name,None)
59
+ if vmod_piece is None:
60
+ print(f'Did not find piece "{name}" in vmod')
61
+ vmod_piece = piece
62
+
63
+ vmod_piece.copyStates(piece)
64
+ self._vlog_pieces[iden] = {'name': name,
65
+ 'vlog': piece,
66
+ 'vmod': vmod_piece}
67
+
68
+
69
+ def _vlogPiece(self,line,verbose=False):
70
+ from re import match
71
+
72
+ m = match(r'^\+/([0-9]+)/.*;([a-z0-9_]+)\.png.*',line)
73
+ if m is None:
74
+ return None,None,None
75
+
76
+ iden = int(m.group(1))
77
+ piece = PieceSlot(None)
78
+ piece.setTraits(*piece.decodeAdd(line,verbose),iden=iden)
79
+ basic = piece.getTraits()[-1]
80
+
81
+ return iden,basic['name'],piece
82
+
83
+
84
+ def _newLine(self,line,verbose):
85
+ self._new_lines.append(line)
86
+ if verbose:
87
+ print(line)
88
+
89
+ def upgrade(self,shownew=False,verbose=False):
90
+ self._new_lines = []
91
+ for line in self._lines:
92
+ add_line = self.newDefine(line,verbose)
93
+ if add_line:
94
+ self._newLine(add_line,shownew)
95
+ continue
96
+
97
+ cmd_line = self.newCommand(line,verbose)
98
+ if cmd_line:
99
+ self._newLine(cmd_line,shownew)
100
+ continue
101
+
102
+ oth_line = self.other(line,verbose)
103
+ if oth_line:
104
+ self._newLine(oth_line,shownew)
105
+ continue
106
+
107
+ self._newLine(line,shownew)
108
+
109
+ def newCommand(self,line,verbose=False):
110
+ from re import match
111
+
112
+ m = match(r'LOG\s+([+MD])/([0-9]+)/([^/]+)(.*)',line)
113
+ if not m:
114
+ return None
115
+
116
+ cmd = m.group(1)
117
+ iden = int(m.group(2))
118
+ more = m.group(3)
119
+
120
+ if more == 'stack':
121
+ return None
122
+
123
+ vp = self._vlog_pieces.get(iden,None)
124
+ if vp is None:
125
+ print(f'Piece {iden} not found: "{line}"')
126
+ return None
127
+
128
+ if cmd == '+' or cmd == 'M':
129
+ return None
130
+
131
+ # Get the code
132
+ code = more + m.group(4)
133
+
134
+ # Decode the states from the code into the old piece
135
+ vp['vlog'].decodeStates(code,verbose)
136
+
137
+ # Get the previsous state from the new piece
138
+ old = vp['vmod'].encodedStates()
139
+
140
+ # Copy states from the old piece to the new piece
141
+ vp['vmod'].copyStates(vp['vlog'],verbose)
142
+
143
+ # Get the new state code from the new piece
144
+ new = vp['vmod'].encodedStates()
145
+
146
+ newline = 'LOG\t'+cmd+'/'+str(iden)+'/'+new+'/'+old+'\\\\'
147
+ # print('WAS',line)
148
+ # print('NOW',newline)
149
+ return newline
150
+
151
+ def newDefine(self,line,verbose):
152
+ from re import match
153
+
154
+ m = match(r'\+/([0-9]+)/([^/]+).*',line)
155
+
156
+ if not m:
157
+ return False
158
+
159
+ iden = int(m.group(1))
160
+ more = m.group(2)
161
+ if more == 'stack':
162
+ return False
163
+
164
+ vp = self._vlog_pieces.get(iden,None)
165
+ if vp is None:
166
+ print(f'Piece {iden} not known')
167
+
168
+ old = vp['vlog']
169
+ new = vp['vmod']
170
+
171
+ old_add = old._node.childNodes[0].nodeValue;
172
+ new_add = new.encodeAdd(*new.getTraits(),iden=iden,verbose=verbose);
173
+
174
+ return new_add
175
+
176
+ def other(self,line,verbose=False):
177
+ return None
178
+
179
+
180
+ def write(self,outFileName,verbose=False):
181
+ SaveIO.writeSave(outFileName,
182
+ key = 0xAA,
183
+ lines = self._new_lines,
184
+ savedata = self._save_data,
185
+ moduledata = self._meta_data)
186
+
187
+
188
+
189
+ #
190
+ # EOF
191
+ #