def rr(self):
     if self.rr_move == 0:
         for (r, c, p) in [(0, 6, 9), (5, 2, 5), (6, 0, 9)]:
             self.set1(r, c, p)
         self.rcell1 = self.get_cell(0, 6)
         self.rcell2 = self.get_cell(6, 0)
         self.rr_move += 1
     elif self.rr_move == 1:
         ncell = self.get_cell(6, 7)
         chessh.move(self.rcell2, ncell)
         self.rcell2 = ncell
         self.rr_move += 1
         g.state = 1
     else:
         g.state = 1
         for cell in self.cells:  # find WK
             if cell.piece == 5:
                 wk = cell
                 break
         if abs(self.rcell1.r - wk.r) < 2:
             r = 7
             if self.rcell1.r == 7: r = 0
             ncell = self.get_cell(r, self.rcell1.c)
             chessh.move(self.rcell1, ncell)
             self.rcell1 = ncell
         elif abs(self.rcell2.r - wk.r) < 2:
             r = 6
             if self.rcell2.r == 6: r = 1
             ncell = self.get_cell(r, self.rcell2.c)
             chessh.move(self.rcell2, ncell)
             self.rcell2 = ncell
         else:
             if self.rcell1.c < self.rcell2.c:
                 ncell = self.get_cell(self.rcell2.r, self.rcell2.c - 2)
                 chessh.move(self.rcell2, ncell)
                 self.rcell2 = ncell
             else:
                 ncell = self.get_cell(self.rcell1.r, self.rcell1.c - 2)
                 chessh.move(self.rcell1, ncell)
                 self.rcell1 = ncell
             if self.rcell1.c + self.rcell2.c == 1:
                 g.state = 4  # checkmate
 def left_click(self):
     if g.state != 1 and self.layout != 6: return
     cell = self.which()
     if cell != None:  # have clicked cell
         if self.layout < 7:  # number chase
             if self.aim == 10: return
             if self.layout == 1 and self.aim == 6: return
             if self.layout == 6:
                 if cell.piece == 2:
                     self.selected = cell
                     return
             if chessh.legal(self.selected, cell):
                 if chessh.move(self.selected, cell):
                     self.check_number(self.selected, cell)
                     if self.wrong != []: self.aim = 1
                     self.selected = cell
             return
         if cell == self.selected:
             self.selected = None
             return True
         if self.selected != None:
             if cell.piece == None or self.layout in (7, 8, 9, 10, 11, 13,
                                                      15, 17):
                 if self.layout == 10:
                     if cell.piece != None:
                         if chessh.colour(cell.piece) == 'w':
                             self.selected = cell
                             return True
                 # make move if possible
                 if chessh.legal(self.selected, cell):
                     pce = self.selected.piece
                     # move successful only if no check remains
                     if chessh.move(self.selected, cell):
                         self.selected = None
                         if self.layout == 9:
                             if cell.piece != pce: self.promoted = True
                         if self.layout > 6: g.state = 2
                 return True
         if cell.piece > 5: return True  # can't select black piece
         if cell.piece != None: self.selected = cell
         return True
     return False  # didn't click on square
 def one2one(self):
     cellw = None
     cellb = None
     for cell in self.cells:  # find pieces
         if cell.piece != None:
             if chessh.colour(cell.piece) == 'w': cellw = cell
             if chessh.colour(cell.piece) == 'b': cellb = cell
     if cellb == None:
         g.state = 6
         return
     attacked = chessh.attack('b')
     # find all the cells I'm (black) is attacking
     if cellw in attacked:
         chessh.move(cellb, cellw)
         g.state = 7
         return
     # no capture just make random move
     rnd = random.randint(0, len(attacked) - 1)
     chessh.move(cellb, attacked[rnd])
     g.state = 1
 def pppp(self):
     cellw = []
     cellb = []
     for cell in self.cells:  # find pieces
         if cell.piece != None:
             if chessh.colour(cell.piece) == 'w': cellw.append(cell)
             if chessh.colour(cell.piece) == 'b': cellb.append(cell)
     if cellb == []:
         g.state = 6
         return
     if cellw == []:
         g.state = 7
         return
     ind = random.randint(0, len(cellb) - 1)
     for i in range(len(cellb)):
         cell = cellb[ind]
         r = cell.r
         c = cell.c
         if cell.piece == 6:  # BP
             for dc in (-1, 1):
                 ncell = self.get_cell(r + 1, c + dc)
                 if ncell != None:
                     if ncell.piece != None:
                         if chessh.colour(ncell.piece) == 'w':
                             chessh.move(cell, ncell)
                             if len(cellw) == 1: g.state = 7
                             return
             if r == 1:
                 if self.get_cell(r + 1, c).piece == None:
                     ncell = self.get_cell(r + 2, c)
                     if ncell.piece == None:
                         chessh.move(cell, ncell)
                         return
             ncell = self.get_cell(r + 1, c)
             if ncell.piece == None:
                 chessh.move(cell, ncell)
                 return
         else:  # BQ
             ncellk = None
             for (dr, dc) in [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1),
                              (1, -1), (1, 0), (1, 1)]:
                 r1 = r
                 c1 = c
                 for i in range(7):
                     r1 += dr
                     c1 += dc
                     ncell = self.get_cell(r1, c1)
                     if ncell == None: break
                     if ncell.piece != None:
                         if chessh.colour(ncell.piece) == 'w':
                             chessh.move(cell, ncell)
                             if len(cellw) == 1: g.state = 7
                             return
                         break  # must be a Black piece
                     else:
                         ncellk = ncell
             # no captures found
             if ncellk != None:
                 chessh.move(cell, ncellk)
                 return
         ind += 1
         if ind == len(cellb): ind = 0
     # no possible move - stalemate
     g.state = 5
 def kq(self):
     if self.kq_move == 0:
         for (r, c, p) in [(1, 5, 11), (3, 3, 10), (6, 7, 5)]:
             self.set1(r, c, p)
         self.bk = self.get_cell(1, 5)
         self.bq = self.get_cell(3, 3)
         self.kq_move += 1
     elif self.kq_move == 1:
         ncell = self.get_cell(3, 5)
         chessh.move(self.bq, ncell)
         self.bq = ncell
         self.kq_move += 1
         g.state = 1
     elif self.kq_move == 2:
         ncell = self.get_cell(2, 6)
         chessh.move(self.bk, ncell)
         self.bk = ncell
         self.kq_move += 1
         g.state = 1
     else:
         g.state = 1
         # find WK
         for cell in self.cells:
             if cell.piece == 5: break
         wk = cell
         # ready to mate?
         if wk.r == 7 and self.bq.r == 6 and self.bk.r == 5:  #yes!
             if abs(wk.c - self.bk.c) < 2:
                 ncell = self.get_cell(6, wk.c)
                 chessh.move(self.bq, ncell)
                 self.bq = ncell
             else:
                 dc = utils.sign(wk.c - self.bk.c)
                 ncell = self.get_cell(self.bk.r, self.bk.c + dc)
                 chessh.move(self.bk, ncell)
                 self.bk = ncell
         # if WK on row 7 move BQ to row 6
         elif wk.r == 7 and self.bq.r != 6:
             r = self.bq.r
             c = self.bq.c
             for i in range(7):
                 r += 1
                 c -= 1
                 if r == 6: break
             ncell = self.get_cell(r, c)
             chessh.move(self.bq, ncell)
             self.bq = ncell
         else:
             # move BK down if poss, else move BQ down
             attacked = chessh.attack('w')  # fetch no go squares
             ncell = self.get_cell(self.bk.r + 1, self.bk.c)
             if ncell in attacked:
                 dc = 0
                 if self.bq.r == 5: dc = -1
                 ncell = self.get_cell(self.bq.r + 1, self.bq.c + dc)
                 chessh.move(self.bq, ncell)
                 self.bq = ncell
             else:
                 chessh.move(self.bk, ncell)
                 self.bk = ncell
         self.kq_move += 1
         self.check_wk(wk)
 def kr(self):
     if self.kr_move == 0:
         for (r, c, p) in [(1, 5, 11), (3, 6, 9), (6, 7, 5)]:
             self.set1(r, c, p)
         self.bk = self.get_cell(1, 5)
         self.br = self.get_cell(3, 6)
         self.kr_move += 1
     elif self.kr_move == 1:
         ncell = self.get_cell(self.bk.r + 1, self.bk.c)
         chessh.move(self.bk, ncell)
         self.bk = ncell
         g.state = 1
         self.kr_move += 1
     else:
         g.state = 1
         # find WK
         for cell in self.cells:
             if cell.piece == 5: break
         wk = cell
         done = False
         if not done:  # 2nd last posn?
             if self.br.r == 5 and self.bk.r == 6 and wk.r == 6:
                 ncell = self.get_cell(self.br.r, self.br.c - 1)
                 chessh.move(self.br, ncell)
                 self.br = ncell
                 done = True
         if not done:  # final posn?
             if self.br.r == 5 and self.bk.r == 6 and wk.r == 7:
                 ncell = self.get_cell(self.br.r, 7)
                 chessh.move(self.br, ncell)
                 self.br = ncell
                 done = True
         if not done:
             if self.bk.r < self.br.r:  # BK trailing
                 ncell = self.get_cell(self.bk.r + 1, self.bk.c)
                 chessh.move(self.bk, ncell)
                 self.bk = ncell
                 done = True
         if not done:
             if self.br.r < self.bk.r:  # BR trailing
                 if self.br.r < 5:
                     ncell = self.get_cell(self.br.r + 1, self.br.c)
                     chessh.move(self.br, ncell)
                     self.br = ncell
                     done = True
         if not done:  # must be level or on row 5
             if (self.bk.r + 1) == wk.r or self.br.r == 5:  # move BK
                 ncell = self.get_cell(self.bk.r + 1, self.bk.c)
                 chessh.move(self.bk, ncell)
                 self.bk = ncell
                 done = True
             else:  # move BR
                 ncell = self.get_cell(self.br.r + 1, self.br.c)
                 chessh.move(self.br, ncell)
                 self.br = ncell
                 done = True
         self.kr_move += 1
         self.check_wk(wk)  # will set g.state if necessary
 def kp(self):
     if self.kp_move == 0:
         for (r, c, p) in [(7, 6, 11), (1, 3, 6), (7, 0, 5)]:
             self.set1(r, c, p)
         self.bk = self.get_cell(7, 6)
         self.bp = self.get_cell(1, 3)
         self.kp_move += 1
     elif self.kp_move == 1:
         ncell = self.get_cell(6, 5)
         chessh.move(self.bk, ncell)
         self.bk = ncell
         self.kp_move += 1
         g.state = 1
     elif self.kp_move == 2:
         ncell = self.get_cell(5, 4)
         chessh.move(self.bk, ncell)
         self.bk = ncell
         self.kp_move += 1
         g.state = 1
     elif self.kp_move == 3:
         ncell = self.get_cell(4, 4)
         chessh.move(self.bk, ncell)
         self.bk = ncell
         self.kp_move += 1
         g.state = 1
     elif self.kp_move == 4:
         ncell = self.get_cell(3, 3)
         chessh.move(self.bp, ncell)
         self.bp = ncell
         self.kp_move += 1
         g.state = 1
     else:
         g.state = 1
         # find WK
         for cell in self.cells:
             if cell.piece == 5: break
         wk = cell
         done = False
         if self.dist(self.bp, self.bk) > 2:  # move bk towards bp
             dr = self.bp.r - self.bk.r  # v28
             ncell = self.get_cell(self.bk.r + dr,
                                   self.bk.c)  # v28 - was r-1
             if ncell != None:  # v 28 extra cautious :o)
                 chessh.move(self.bk, ncell)
                 self.bk = ncell
                 done = True
         if not done:
             ncell = self.get_cell(self.bp.r + 1,
                                   self.bp.c)  # advance pawn?
             if ncell.piece == None:  # cell is empty but ...
                 # don't move if new square under attack and not protected
                 attacked = chessh.attack('w')
                 if ncell in attacked:  # under attack - protected?
                     mates = self.get_mates(self.bk)
                     if ncell in mates:  # protected so move
                         chessh.move(self.bp, ncell)
                         self.bp = ncell
                         done = True
                 else:  # not under attack so move
                     chessh.move(self.bp, ncell)
                     self.bp = ncell
                     done = True
         if not done:  # unable to safely move pawn
             ncell = self.get_cell(self.bk.r + 1,
                                   self.bk.c)  # advance King?
             if self.bk_ok(self.bk, ncell):  # ok so move
                 chessh.move(self.bk, ncell)
                 self.bk = ncell
                 done = True
         if not done:  # move King sideways towards WK
             dc = utils.sign(wk.c - self.bk.c)
             ncell = self.get_cell(self.bk.r, self.bk.c + dc)
             if self.bk_ok(self.bk, ncell):  # ok so move
                 chessh.move(self.bk, ncell)
                 self.bk = ncell
                 done = True
             else:  # move in opposite direction
                 ncell = self.get_cell(self.bk.r, self.bk.c - dc)
                 if self.bk_ok(self.bk, ncell):  # ok so move
                     chessh.move(self.bk, ncell)
                     self.bk = ncell
                     done = True
         if not done: print 'ouch!'
         if self.bp.r == 7:
             self.bp.piece = 10
             g.state = 7
         # check for stalemate
         self.check_wk(wk)  # will set g.state if necessary
 def black(self):
     if self.layout in (7, 8, 9):
         self.one2one()
         return
     if self.layout == 10:
         self.pppp()
         return  # PPPP
     if self.layout == 11:
         self.rr()
         return  # RR
     if self.layout == 13:
         self.kq()
         return  # KQ
     if self.layout == 15:
         self.kp()
         return  # KP
     if self.layout == 17:
         self.kr()
         return  # KR
     # will only be moving a Black King in 12,14,16,18
     # find bk
     for cell in self.cells:
         if cell.piece == 11: break
     bk = cell
     mates = self.get_mates(bk)
     pce = bk.piece
     bk.piece = None
     attacked = chessh.attack('w')
     bk.piece = pce
     # check for unprotected piece to take
     for cell in mates:
         if cell.piece != None:
             if cell not in attacked:
                 cell.piece = bk.piece
                 bk.piece = None
                 return
     # move towards centre if possible
     dmin = 100
     cell1 = None
     for cell in mates:
         if cell not in attacked:
             d = self.dist(cell)
             if d < dmin:
                 dmin = d
                 cell1 = cell
     if cell1 == None:  # nowhere to move
         if bk in attacked:
             g.state = 4
             return  # mate
         else:
             g.state = 5
             return  # stale
     if self.layout in (12, 18):
         # chase closest rook
         rooks = []  # find rook(s)
         for cell in self.cells:
             if cell.piece == 3: rooks.append(cell)
         dmin = 100
         cell1 = None
         for cell in mates:
             if cell not in attacked:
                 for cell2 in rooks:
                     d = self.dist(cell, cell2)
                     if d < dmin:
                         dmin = d
                         cell1 = cell
     if self.layout == 16:
         if False:  # chase pawn - not implemented
             pawn = None
             for cell in self.cells:
                 if cell.piece == 0:
                     pawn = cell
                     break
             if pawn != None:
                 dmin = 100
                 cell1 = None
                 for cell in mates:
                     if cell not in attacked:
                         d = self.dist(cell, pawn)
                         if d < dmin:
                             dmin = d
                             cell1 = cell
         else:  # head for blocking square
             dmin = 100
             cell1 = None
             for cell in mates:
                 if cell not in attacked:
                     d = self.dist(cell, self.pawn_cell)
                     if d < dmin:
                         dmin = d
                         cell1 = cell
     chessh.move(bk, cell1)