;ò ÏnZGc@stdZdZdkZdkZeodklZdkZndZdZ ee Z dZ dZ e edƒZe edeƒZeefZd d d d d ddfZdddddddfZdddddfZdZdefd„ƒYZdefd „ƒYZd!efd"„ƒYZd#efd$„ƒYZd%efd&„ƒYZd'„Zed(jo eƒndS()snA simple Awalé game. Copyright (C) 2007 MiKael NAVARRO The count-and-capture official board game of Africa. s$MiKael Navarro N(spprinti iiiisAsBsCsDsEsFsGsasbscsdsesfsgsbfssminimaxsmaxisnegamaxs alphabetais AwaleErrorcBstZdZRS(s Base class for Awale exceptions.(s__name__s __module__s__doc__(((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys AwaleError=s s InvalidSowncBstZdZRS(sInvalid input.(s__name__s __module__s__doc__(((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys InvalidSownBs s NoMoreMovecBstZdZRS(sNo move available.(s__name__s __module__s__doc__(((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys NoMoreMoveGs s EndOfGamecBstZdZRS(s End of game?(s__name__s __module__s__doc__(((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys EndOfGameLs sAwalecBs¹tZdZegeddgeded„Zd„Zd„Z d„Z d„Z d„Z d „Z d „Zd „Zd „Zd „Ze ed„Zd„Zd„Zd„ZRS(sAwale board class. Usage: >>> awale = Awale() >>> awale {'board': [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], 'score': [0, 0]} >>> awale.sow_and_capture(3) >>> awale.sow_and_capture(6) >>> awale.sow_and_capture(2) >>> awale.sow_and_capture(6) >>> print awale f e d c b a North ( 0) [ 5] [ 5] [ 5] [ 5] [ 7] [ 0] [ 4] [ 4] [ 0] [ 1] [ 6] [ 6] ( 0) South A B C D E F >>> awale.sow_and_capture(1) >>> awale.best_sown(1) 10 >>> awale.sow_and_capture(10) >>> print awale f e d c b a North ( 5) [ 6] [ 0] [ 5] [ 5] [ 7] [ 0] [ 5] [ 1] [ 0] [ 0] [ 7] [ 7] ( 0) South A B C D E F iicCs1||_||_d|_||_||_dS(sÌInitialize the board game and player scores. By default BOARD_SIZE cups with INITIAL_SEEDS inside each houses; South (human) and north (computer) players begin with a score of 0. iN(sboardsselfsscoresturnsalgos algo_typesdepths algo_depth(sselfsboardsscoresalgosdepth((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys__init__ps     cCs$dt|iƒt|iƒfSdS(s5Friendly representation of Awale data: board + score.s{'board': %s, 'score': %s}N(sstrsselfsboardsscore(sself((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys__repr__€scCsd}|d7}|digi}tttd ƒD]}||ƒq5~ƒ7}|d7}|d|i t 7}|digi}t|i t dƒD]}|d|ƒqš~ƒ7}|d7}|d 7}|digi}|i td D]}|d|ƒqñ~ƒ7}|d |i t 7}|d7}|d7}|digi}ttd D]}||ƒqZ~ƒ7}|Sd S( sDisplay Awale board.ss s is s North (%2d) s s[%2d]s s (%2d) SouthN(sssjoinsappends_[1]sreverseds COMPUTER_CUPSs BOARD_SIZEscsselfsscores NORTH_PLAYERsboardsis SOUTH_PLAYERs HUMAN_CUPS(sselfscsis_[1]ss((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys__str__†s B J  C  <cCs_|tt|iƒƒjpt‚t}|tjo t }n|t jo t }n|SdS(sDetermine who play given index.N( sidxsrangeslensselfsboardsAssertionErrorsNonesplayers SOUTH_CUPSs SOUTH_PLAYERs NORTH_CUPSs NORTH_PLAYER(sselfsidxsplayer((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys _who_play£s#    cCsD|tt|iƒƒjpt‚|i|ƒ}|i|djotSnt gi }t d|D]}||i|ƒqg~ƒdjo«t}|i|}d}x{|os||dt|iƒ|jon@||dt|iƒt d|jo t}Pn|d8}|d7}q­W| otSq<ntSdS(s5Check if sowing seeds from given index is authorized?iiN(sidxsrangeslensselfsboardsAssertionErrors _who_playsplayersFalsesmaxsappends_[1]s PLAYER_CUPSsisstatussnb_seedssTrue(sselfsidxsstatussis_[1]splayersnb_seeds((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys_valid±s*#C "*  cCsë|tt|iƒƒjpt‚|i|ƒ o td‚n|i|}d|i| "%s" [ label="idx=%d" ];N()slvlslensnodesboards INITIAL_SEEDSsmax_notesNonesbest_idxsnodessdepthschildssidx_paths __debug__smd5snewsreprs hexdigestsnode_ids north_boardsreverses south_boardsscores node_labelsrangesisplayersidxs_validsAwales algo_types algo_depthschildssow_and_captures AwaleErrorsmsgschild_ids child_labels new_idx_pathsappendsnotesn(snodesplayersdepthschildssbest_idxschild_idsnotesmsgsnodess node_labelsidx_pathsmax_notes child_labels new_idx_paths north_boardsnode_idschildsidxsisns south_boardslvl((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pysbfssp    + /    c Cs+toŸtit|ƒƒiƒ} |it|iƒ d} | i ƒ|it|iƒd }d|i |t| ƒt|ƒt|iƒf}d| |fGHn|it|ittjp:|djp-|ittdjp|ittdjoH|ittdjo d}n|it|it}d|fSnt}|tjot|iƒt }n&|tjot|iƒt }nt}xztt|iƒdƒD]_} | |t|iƒd} |i| ƒo.td|id|id |id |i ƒ} y| i| ƒWnt j o }nXtoLtit|ƒƒiƒ} tit| ƒƒiƒ}d | || fGHnti#| d ||d ƒ\}}|tjo!||jo|}| }qq|tjo!||jo|}| }qqqºqºW||fSd S(s;Minimax algorithm. Return the tuple (best_idx, note).is{ depth%d | %s | %s | %s }s$"%s" [ label="%s", shape="record" ];iiiÿÿÿÿsboardsscoresalgosdepths "%s" -> "%s" [ label="idx=%d" ];iN(&s __debug__smd5snewsreprsnodes hexdigestsnode_idsboardslens north_boardsreverses south_boards algo_depthsdepthsscores node_labels SOUTH_PLAYERs NORTH_PLAYERs ALL_SEEDSsnotesNonesplayers INITIAL_SEEDSsbest_idxsrangesisidxs_validsAwales algo_typeschildssow_and_captures AwaleErrorsmsgschild_idsminimaxscurr_idxs curr_note(snodesplayersdepthsbest_idxscurr_idxschild_idsnotesmsgs node_labels north_boardsnode_idschildsidxsis curr_notes south_board((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pysminimaxrsV 2\   #    c Cs°toŸtit|ƒƒiƒ} |it|iƒ d} | i ƒ|it|iƒd }d|i |t| ƒt|ƒt|iƒf}d| |fGHn|it|ittjp:|djp-|ittdjp|ittdjoH|ittdjo d}n|it|it}d|fSnt|iƒt } t}x;tt|iƒdƒD] }||t|iƒd} |i| ƒoïtd|id|id |id |i ƒ} y| i | ƒWnt!j o }nXtoLtit|ƒƒiƒ} tit| ƒƒiƒ}d | || fGHnti$| d ||d ƒ\}}|| jo|} | }qžq~q~W|| fSd S(sPMinimax algorithm with ponderation. Return the tuple (best_idx, max_note).is{ depth%d | %s | %s | %s }s$"%s" [ label="%s", shape="record" ];iiiÿÿÿÿsboardsscoresalgosdepths "%s" -> "%s" [ label="idx=%d" ];iN(&s __debug__smd5snewsreprsnodes hexdigestsnode_idsboardslens north_boardsreverses south_boards algo_depthsdepthsscores node_labels SOUTH_PLAYERs NORTH_PLAYERs ALL_SEEDSsnotes INITIAL_SEEDSsmax_notesNonesbest_idxsrangesisplayersidxs_validsAwales algo_typeschildssow_and_captures AwaleErrorsmsgschild_idsmaxiscurr_idx(snodesplayersdepthsbest_idxscurr_idxschild_idsnotesmsgs node_labelsmax_notes north_boardsnode_idschildsidxsis south_board((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pysmaxiºsD 2\ # c CsÁtoŸtit|ƒƒiƒ} |it|iƒ d} | i ƒ|it|iƒd }d|i |t| ƒt|ƒt|iƒf} d| | fGHn|it|ittjp:|djp-|ittdjp|ittdjoH|ittdjo d}n|it|it}d|fSnt}x`tt|iƒdƒD]E}||t|iƒd}|i|ƒotd|id|id |id |i ƒ} y| i|ƒWntj o } nXtoLtit|ƒƒiƒ} tit| ƒƒiƒ}d | ||fGHnti"| d ||d | | ƒ\}}| |jo| }|}n||jo||fSq¯qjqjW||fSd S(s9Variant formulation of minimax search: Negamax algorithm.is{ depth%d | %s | %s | %s }s$"%s" [ label="%s", shape="record" ];iiiÿÿÿÿsboardsscoresalgosdepths "%s" -> "%s" [ label="idx=%d" ];iN('s __debug__smd5snewsreprsnodes hexdigestsnode_idsboardslens north_boardsreverses south_boards algo_depthsdepthsscores node_labels SOUTH_PLAYERs NORTH_PLAYERs ALL_SEEDSsnotesNonesbest_idxsrangesisplayersidxs_validsAwales algo_typeschildssow_and_captures AwaleErrorsmsgschild_idsnegamaxsbetasalphascurr_idxs curr_note(snodesplayersdepthsalphasbetasbest_idxscurr_idxschild_idsnotesmsgs node_labels north_boardsnode_idschildsidxsis curr_notes south_board((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pysnegamax÷sF 2\ +  cCs$td|_ti|||ƒSdS(sAlpha-beta pruning.iN(s ALGO_TYPESsnodes algo_typesAwalesnegamaxsplayersdepth(snodesplayersdepth((s@/mnt/gmirror/ports/games/pyawale/work/pyawale-0.3.6/src/awale.pys alphabeta6s cCs“|tt|iƒƒjpt‚|i|ƒ}|i|ƒ}|t d|jo |i |c|i |ƒ7