;ò DÄFc@s˜dZdkZdkZdkZdklZdkZdkZdk Z d„Z de fd„ƒYZ de fd„ƒYZ edjo d GHndS( suThudBoard - The Discworld Boardgame without rules Version 1.8 Copyright 2003, 2004, 2005, 2006, 2007 by Marc Boeren N(sminidomcCsId}x2|D]*}|i|ijo||i}q q W|iƒSdS(Ns(stxtsnodelistsnodesnodeTypes TEXT_NODEsdatasstrip(snodelistsnodestxt((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysminidom_gettexts sThudMovecBsktZdZdddf\ZZZeedd„Zd„Z d„Z ed„Z d „Z dd „Z RS( soA single move from a piece, including thudded opponents, optional comments A piece is either a Dwarf (d) or a Troll (T). If it is neither of these, it will be represented by a question mark (?). From- and to-positions are given in Board-coordinates (A1..P15), the thud-list is a list of such coordinates. In Koom Valley Thud, there is an extra piece, the Rock (R). These pieces are used in a ThudBattle. This ThudBattle will store extra information, such as the physical possibility of the move and if the rules were applied for this move (ensuring at least physical possibility). iiisc Csv||_|iƒ|_|iƒ|_gi} |D]}| |iƒƒq5~ |_||_ ||_ ||_ dS(N( spiecesselfsfrom_possuppersto_possappends_[1]s thud_liststhuddedspossiblesrulesscomment( sselfspiecesfrom_possto_poss thud_listspossiblesrulesscommentsthuddeds_[1]((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys__init__'s 0  cCs;d}|io#|dt|iƒdd7}n|SdS(s4Return the number of lines in a text-representation.iiN(slinessselfs thud_listslen(sselfslines((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys get_height3s  #cCs|iƒSdS(N(sselfsstr_save(sself((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys__repr__:scCs5dg}}|i o dg}n|i o dg}n|o dg}nhdd<|id<|id<|id <|i }||}|d ||i i ƒ|i i ƒfg7}d }xZ|iD]O}| o|d g|d g7}n|d|i ƒg7}|dd}qÑWdi|ƒSdS(sÅReturn a multi-line string containing the move as text. Example for a Troll move and a subsequent Thudding of two Dwarfs: ~ T J10 - L12 x L13 x M13 ss ~s %s >>>iÿÿÿÿs?sdsTsRs %s %s - %sis s s x %siiN(stxtsprependsselfsrulesspossibles savedstatesdwarfstrollsrockspieces piece_txtsfrom_possuppersto_posscounters thud_liststhuddedsjoin(sselfs savedstates piece_txtsthuddedscountersprependstxt((s1/mnt/gmirror/ports/games/thudboard/work/battle.pystxt_move=s&    : , cCs#di|iƒiƒƒ}|SdS(sLReturn a single-line text representation that can be used by load()sN(sjoinsselfstxt_movessplitstxt(sselfstxt((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysstr_saveUsc Csddhdd<}ti||iƒƒ} | otSn| idddddƒ\}}}}}ht d <d d <d |i<d |i<d |i<} || j otSn| |_|o |dj |_|i o t|_n| ||_||_||_gi} |idƒD]!} | iƒo| | ƒq&q&~ |_||_tSdS(seInitialize the move from a text-representation generated by save() or loaded from a clipboards>^([~|%%])?([D|T|R|?])?(%(coord)s)-(%(coord)s)((X%(coord)s)*)?$scoords[A-HJ-P][1-9][0-5]?iiiiiiÿÿÿÿs?sDsTsRs%sXN(s movepatternsresmatchstxtsuppersFalsesgroupsstatespsfpstpstlsNonesselfsdwarfstrollsrocks piece_checksrulesspossiblespiecesfrom_possto_possappends_[1]ssplitscoordsstrips thud_listscommentsTrue( sselfstxtscommentsfpspstlstps movepatternsstates piece_checks_[1]scoordsmatch((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysload_str[s&*<     D (s__name__s __module__s__doc__sdwarfstrollsrocksFalsesTrues__init__s get_heights__repr__stxt_movesstr_savesload_str(((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysThudMoves     s ThudBattlec BsîtZdZeiZdZdddf\ZZZ ddddd d d d d ddddddddddddddddddd d!d"d#d$g d%d&d'd(d)d*d+d,gd-ggZ ggggZ gZ d.Z d.ZdZeeed.dd/„Zd0„Zd1„Zd2„Zd3„Zd4„Zd5„Zd6„Zd7„Zd8„Zdd9„Zd.dd:„Zd;„Zd<dd=„Zd>„Zd?„Z d@„Z!dA„Z"ed.dB„Z#edC„Z$dD„Z%dE„Z&dF„Z'dG„Z(dH„Z)RS(Is½From a starting position you play a number of moves. The default Thud starting position is supplied, but you can override this with any prepared board setup. The list of moves is applied sequentially to the starting position to obtain the current position. This applying will stop as soon as an impossible move presents itself. You can view the history of the battle by setting the current position to different stages in the game (read: any move is a stage). New moves will be added after the current position, discarding any future moves. A new move is not allowed before the last saved move (the saved move is highlighted somehow). To do this anyway, you must go to some point in history and save the game from there. Note that a saved game will contain any future moves, although the saved move is remembered. The current move is stored in 'index'. The saved move is stored in 'saved_index'. siiisF1sG1sJ1sK1sL2sM3sN4sO5sP6sP7sP9sP10sO11sN12sM13sL14sK15sJ15sG15sF15sE14sD13sC12sB11sA10sA9sA7sA6sB5sC4sD3sE2sG7sH7sJ7sG8sJ8sG9sH9sJ9sH8iÿÿÿÿcCsÃ|iƒ|o ||_n|oti|ƒ|_nti|iƒ|_|o)ti|ƒ|_t |ƒd|_ n|o ||_ n|i |ƒ|i |_ ||_ ||_dS(Ni(sselfsinit_positionssnames start_posscopysdeepcopysstart_positionspositionsmovesslensindexs get_positions saved_indexsfilenamescomment(sselfsnames start_possmovessindexscomment((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys__init__”s      cCs¾ttddddddddd d d d d ddgtdƒƒƒ|_tgi}|iiƒD]\}}|||fƒqe~ƒ|_ g|_ x¦tdƒD]˜}xtd|ƒD]}}|i d|i |d|fd|i d|d|fd|i |d|fd|i d|d|fg7_ q½Wq¦Wg|_xltdƒD]^}xUtdƒD]G}d|i |d|f}||i jo|i|g7_qkqkWqXWdS(s(Calculate valid and invalid coordinates.sAsBsCsDsEsFsGsHsJsKsLsMsNsOsPiis%s%diiN(sdictszipsrangesselfsmapxsappends_[1]sitemsskeysvaluesremapxsinvalid_positionsisjsvalid_positionsposition(sselfsisjsvalues_[1]skeysposition((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysinit_positions¥s$6E     cCs›ti|iƒ|_|djod|_|iSnxNt|dƒD]<}|i|}|i |ƒ o|d|_|iSqGqGW||_|iSdS(s<Return the board configuration after move 'index' is played.iiÿÿÿÿiN( scopysdeepcopysselfsstart_positionspositionsindexsrangesismovessmsupdate_position(sselfsindexsism((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys get_position¸s      cCsÿ|i|ƒ otSn|i|ii|iƒx§|iD]œ}||i|i jo|i|i i|ƒn||i|i jo|i|i i|ƒn||i|i jo|i|i i|ƒq=q=W|i|ii |iƒtSdS(s3Return the board configuration with the given move.N(sselfs check_movesthudmovesFalsespositionspiecesremovesfrom_poss thud_liststhuddedsdwarfstrollsrocksappendsto_possTrue(sselfsthudmovesthudded((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysupdate_positionÈs cCs|i|_dS(s)Set the saved_index to the current index.N(sselfsindexs saved_index(sself((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys save_indexÖscCsn||i|ijo |iSn||i|ijo |iSn||i|ijo |iSndSdS(s1Return the piece on the given coordinate, if any.iÿÿÿÿN(s coordinatesselfspositionsdwarfstrollsrock(sselfs coordinate((s1/mnt/gmirror/ports/games/thudboard/work/battle.pyspiece_onÚs   cCs&|it||||ttƒƒSdS(sAlternative for add_thudmove.N( sselfs add_thudmovesThudMovespiecesfrom_possto_poss thud_listsTruesFalse(sselfspiecesfrom_possto_poss thud_list((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysadd_moveáscCs|i|ijotSn|i|ƒ otSn|i|id |_|iiti|ƒƒt |iƒd|_|i |ƒt SdS(s5Update the internals and the position with this move.iN( sselfsindexs saved_indexsFalses check_movesthudmovesmovessappendscopyslensupdate_positionsTrue(sselfsthudmove((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys add_thudmoveås cCsé|idjo‚|i|i|ijo|i|_n|i|i|ijo|i|_n|i|i|ijo|i|_q’n|i|i|i|ifjot|_ tSn|i|i|ijp„|i |i|ijo|i |i jpW|i |i|ijo|i |i jp*|i |i|ijo|i |i jot|_ tSnxg|i D]\}||i|ijo+||i|ijo||i|ijot|_ tSqqWt SdS(s*Return if the move is physically possible.iÿÿÿÿN(sthudmovespiecesfrom_possselfspositionsdwarfstrollsrocksFalsespossiblesto_poss thud_liststhuddedsTrue(sselfsthudmovesthudded((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys check_moveïs(" ¡  E  cCs*|djodSn|i|iƒSdS(s;Return the number of lines the move will be represented by.iiN(sindexsselfsmovess get_height(sselfsindex((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys get_height s cCs´|djoddfSn|djod|i|ƒfSnd}d}xKt|ƒD]=}||i|ƒ7}||jo||i|ƒ7}qXqXW|||i|ƒfSdS(s`Return the cumulative number of lines for all previous moves and the height of the move.iiN(sindexsselfs get_heightsoffsets base_offsetsrangesis base_index(sselfsindexs base_indexs base_offsetsisoffset((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysget_offset_and_heights    cCs—|djodSnd}xq|djo|t|iƒjoM||jo2|i|ƒ}||8}|djo|Sq€n|d7}qWdSdS(s\Return the move that is on the given line in the text- representation of the battle.iiÿÿÿÿiN(slinessindexslensselfsmovess base_indexs get_heightsh(sselfsliness base_indexsindexsh((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys get_indexs #    cCs|i|iiƒSdS(s1Return a text-representation of the current move.N(sselfsmovessindexstxt_move(sself((s1/mnt/gmirror/ports/games/thudboard/work/battle.pystxt_battle_move,sicCs|d}g}xCtt|iƒƒD],}||i|i|i |jƒg7}q&W|oYxV|ddi |||i d!ƒi dƒjo |d8}|djoPq`q`Wn|djo d}n||diisinfo(sfilenamesselfs get_filenamesfilesfsNonesFalseswrites str_positionsstart_positionsrangeslensmovessisindexsstr_savesclosesosspathssplitsnamessplitexts save_infosTrue(sselfsfilenamesfsi((s1/mnt/gmirror/ports/games/thudboard/work/battle.pyssaveŠs( "  c CsF| o|iƒ}nyt|dƒ}Wn t}nX| otSn|iƒ}|i ƒt i i |ƒd}t i i|ƒd}|idi|di ƒƒƒ}| otSn||i odg||isinfo($sfilenamesselfs get_filenamesfilesfsNonesFalses readlinesslinessclosesosspathssplitsnamessplitexts position_strsjoinsstart_positionsrocksmovessindexsislinesstripslensappendsThudMovesload_strscopysdeepcopyspositions get_positions saved_indexscomments load_infosTrue( sselfsfilenamesindexsnamesfsislinessstart_positionslinesmoves((s1/mnt/gmirror/ports/games/thudboard/work/battle.pysloads\   "  (      cCsy|i}| o)|i}tii|i|dƒ}n|i p |tijotii|idƒ}n|SdS(Ns.thuds( sselfsfilenamesnamesosspathsjoins battledirstextssanonymousBattle(sselfsfilename((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys get_filenameËs   cCsD|ip6gi}|iD]}|io|tƒqq~SdS(N(sselfscommentsappends_[1]smovessmovesTrue(sselfs_[1]smove((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys has_commentsÔsc CsDyti|ƒ}Wn tSnX|iidjo|iƒtSn|idƒ}|o8|didƒ}|ot |di ƒ|_ q”n|idƒ}|oˆ|didƒ}|ojd}xa|D]U}|idƒ}|o/y!t |di ƒ|i|_ WqqXn|d7}qÑWq2n|iƒtSdS(Ns thudbattlesinfoiscommentsmovessmovei(sminidomsparsesfilenamesdomsFalsesdocumentElementstagNamesunlinksgetElementsByTagNamesinfoscommentsminidom_gettexts childNodessselfsmovescontainersmovessismovesTrue( sselfsfilenamesinfosdomsismovesmovescontainerscommentsmoves((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys load_info×s8 ! c Csµ|iƒ o#yti|ƒWnnXtSntidƒ}|i oW|i dƒ}|o=|i dƒ}|i |i|i ƒƒ|di |ƒq¡n|io•|i dƒ}|o{xx|iD]i}|i dƒ}|i o9|i dƒ}|i |i|i ƒƒ|i |ƒn|di |ƒqËWq@nyt|dƒ}Wn|iƒt}nX| otSn|i|idd d ƒƒ|iƒ|iƒtSdS( Ns(sinfoscommentismovessmoveswbs s sutf-8(sselfs has_commentssossremovesfilenamesTruesminidoms parseStringsdomscommentsgetElementsByTagNamesinfos createElements appendChildscreateTextNodesmovessmovescontainersmoves moveelementsfilesfsunlinksNonesFalseswrites toprettyxmlsclose( sselfsfilenamesinfosfsdomsmovesmovescontainerscomments moveelement((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys save_infoõsF        (*s__name__s __module__s__doc__stextssanonymousBattlesnames battledirsdwarfstrollsrocksstart_positionspositionsmovessindexs saved_indexscommentsNones__init__sinit_positionss get_positionsupdate_positions save_indexspiece_onsadd_moves add_thudmoves check_moves get_heightsget_offset_and_heights get_indexstxt_battle_movestxt_battle_movesstxt_battle_positionss txt_battles str_positions position_strs save_positionssavesloads get_filenames has_commentss load_infos save_info(((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys ThudBattlersF  Š               .  s__main__s;This file is not meant to be executed. Run thud.py instead.(s__doc__sosscopysresxml.domsminidomscodecssencodings.utf_8s encodingsstextssminidom_gettextsobjectsThudMoves ThudBattles__name__( sminidomsminidom_gettextstextsscodecssThudMovesres encodingsscopysoss ThudBattle((s1/mnt/gmirror/ports/games/thudboard/work/battle.pys?s        [ÿ­