class Player: color = None enemy = None board = None # datastructure (length, [list of free extensions]) # rows of player off_rows = [] # rows of enemy def_rows = [] def __init__(self): self.init_boards() def init_boards(self): self.board = GameBoard() def get_next_move(self,message): if len(message) == 1: self.color = 'B' self.enemy = 'W' coord = Coord(9,9) self.board.put_token(coord,self.color) return "0909" elif len(message) == 5: self.color = 'W' self.enemy = 'B' coord = Coord(int(message[1:3]),int(message[3:5])) self.put_enemy_stones(coord) start = self.get_start_moves() start.discard(coord) m1 = random.choice(list(start)) start.discard(m1) m2 = random.choice(list(start)) self.board.put_token(m1,self.color) self.board.put_token(m2,self.color) return self.get_message((m1,m2)) elif len(message) == 8: coord1 = Coord(int(message[0:2]),int(message[2:4])) coord2 = Coord(int(message[4:6]),int(message[6:8])) self.put_enemy_stones(coord1,coord2) best_move = self.do_best_move() self.board.put_token(best_move[0],self.color) self.board.put_token(best_move[1],self.color) return self.get_message(best_move) def get_message(self,move): msg = "" msg1 = move[0].get_msg_repr() msg2 = move[1].get_msg_repr() if msg2 == None: msg2 = self.get_legal_move(1).get_msg_repr() print "emergency random move(None)" elif len(msg2) != 4: msg2 = self.get_legal_move(1).get_msg_repr() print "emergency random move(Len)" if msg1 == msg2: msg2 = self.get_legal_move(1).get_msg_repr() print "emergency random move(Equal)" msg = msg1+msg2 return msg # live 5: just need to put one stone to form a Conn-6, # but the opponent need to put two stones to prevent it # forming a Conn-6. # live 4: need to put two stones to form a Conn-6, also, # two stones is needed to defend. # ... # returns list of my alive def get_alive_off(self, length): return filter(lambda live: live[0]==length and self.is_alive(live), self.off_rows) #returns a list of opponents alive def get_alive_def(self, length): return filter(lambda live: live[0]==length and self.is_alive(live), self.def_rows) # similar to Live-5, but only one stone can prevent from Conn-6 # Sleep-4, similar to Live-4, but only one stone is enough to prevent it. # ... # returns list of my sleeping def get_sleeping_off(self, length): return filter(lambda live: live[0]==length and self.is_sleeping(live), self.off_rows) # returns list of opponents sleeping def get_sleeping_def(self, length): return filter(lambda live: live[0]==length and self.is_sleeping(live), self.def_rows) #returns 2 Coords def do_best_move(self): print "Best Move!" self.get_rows() # if any of our sleep/alive 4/5 exists, make a conn6 alive5 = self.get_alive_off(5) if alive5: return self.getCoord(alive5[0][1][0]), self.getCoord(alive5[0][1][1]) sleep5 = self.get_sleeping_off(5) if sleep5: return self.getCoord(sleep5[0][1][0]), self.get_legal_move(1) alive4 = self.get_alive_off(4) if alive4: return self.getCoord(alive4[0][1][0]), self.getCoord(alive4[0][1][1]) sleep4 = self.get_sleeping_off(4) if sleep4: for row in sleep4: coord1 = self.getCoord(row[1][0]) direction = row[2] ##check if win is possible otherwise check next row if (direction == VER): if self.board.get_board()[coord1.row-1][coord1.col]=='': return coord1, Coord(coord1.row-1)(coord1.col) elif self.board.get_board()[coord1.row+1][coord1.col]=='': return coord1, Coord(coord1.row+1)(coord1.col) elif (direction == HOR): if self.board.get_board()[coord1.row][coord1.col-1]=='': return coord1, Coord(coord1.row)(coord1.col-1) elif self.board.get_board()[coord1.row][coord1.col+1]=='': return coord1, Coord(coord1.row)(coord1.col+1) elif (direction == DRI): if self.board.get_board()[coord1.row-1][coord1.col-1]=='': return coord1, Coord(coord1.row-1)(coord1.col-1) elif self.board.get_board()[coord1.row+1][coord1.col+1]=='': return coord1, Coord(coord1.row+1)(coord1.col+1) else: if self.board.get_board()[coord1.row-1][coord1.col+1]=='': return coord1, Coord(coord1.row-1)(coord1.col+1) elif self.board.get_board()[coord1.row+1][coord1.col-1]=='': return coord1, Coord(coord1.row+1)(coord1.col-1) # if enemy has sleep/alive 4/5 exists, make it dead alive5 = self.get_alive_def(5) if alive5: return self.getCoord(alive5[0][1][0]), self.getCoord(alive5[0][1][1]) alive4 = self.get_alive_def(4) if alive4: return self.getCoord(sleep4[0][1][0]), self.getCoord(alive4[0][1][1]) sleep5 = self.get_sleeping_def(5) if sleep5: # If only one sleep 5? improve own standing, else: destroy other sleep5 if len(sleep5) == 1: return self.getCoord(sleep5[0][1][0]), self.get_improvement_move(1) else: return self.getCoord(sleep5[0][1][0]), self.getCoord(sleep5[1][1][0]) ## toDo only put to sleep if conn-6 is possible sleep4 = self.get_sleeping_def(4) if sleep4: if len(sleep4) == 1: return self.getCoord(sleep4[0][1][0]), self.get_improvement_move(1) else: return self.getCoord(sleep4[0][1][0]), self.getCoord(sleep4[1][1][0]) return self.get_improvement_move(2) ## Avoided opponent win .. do best move ## Put enemy live2/3 to sleep ## ... def get_improvement_move(self,count): print "Defense!!!" # alive3 = self.get_alive_def(3) if alive3: if len(alive3) == 1: if count == 2: return self.getCoord(alive3[0][1][0]), self.do_offensive_move(1) else: return self.getCoord(alive3[0][1][0]) else: if count == 2: return self.getCoord(alive3[0][1][0]), self.getCoord(alive3[1][1][0]) else: return self.getCoord(alive3[0][1][0]) alive2 = self.get_alive_def(2) if alive2: if len(alive2) == 1: if count == 2: return self.getCoord(alive2[0][1][0]), self.do_offensive_move(1) else: return self.getCoord(alive2[0][1][0]) else: if count == 2: return self.getCoord(alive2[0][1][0]), self.getCoord(alive2[1][1][0]) else: return self.getCoord(alive2[0][1][0]) return self.do_offensive_move(2) ## enemy live2/3 were put to sleep ## remaining moves for offense def do_offensive_move(self,count): print "Offense!!!" returnCount = count moves = [] while (count > 0): alive3 = self.get_alive_off(3) for row in alive3: coord1 = self.getCoord(row[1][0]) direction = row[2] ##check if win is possible otherwise check next row if (direction == VER): if self.board.get_board()[coord1.row-1][coord1.col]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col]=='': moves.append(coord1) count -= 1 elif (direction == HOR): if self.board.get_board()[coord1.row][coord1.col-1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row][coord1.col+1]=='': moves.append(coord1) count -= 1 elif (direction == DRI): if self.board.get_board()[coord1.row-1][coord1.col-1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col+1]=='': moves.append(coord1) count -= 1 else: if self.board.get_board()[coord1.row-1][coord1.col+1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col-1]=='': moves.append(coord1) count -= 1 if (count > 0): alive2 = self.get_alive_off(2) for row in alive2: coord1 = self.getCoord(row[1][0]) direction = row[2] ##check if win is possible otherwise check next row if (direction == VER): if self.board.get_board()[coord1.row-1][coord1.col]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col]=='': moves.append(coord1) count -= 1 elif (direction == HOR): if self.board.get_board()[coord1.row][coord1.col-1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row][coord1.col+1]=='': moves.append(coord1) count -= 1 elif (direction == DRI): if self.board.get_board()[coord1.row-1][coord1.col-1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col+1]=='': moves.append(coord1) count -= 1 else: if self.board.get_board()[coord1.row-1][coord1.col+1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col-1]=='': moves.append(coord1) count -= 1 if (count > 0): alive1 = self.get_alive_off(1) for row in alive1: coord1 = self.getCoord(row[1][0]) moves.append(coord1) count -= 1 if (count > 0): sleep1 = self.get_sleeping_off(2) for row in sleep1: coord1 = self.getCoord(row[1][0]) direction = row[2] ##check if win is possible otherwise check next row if (direction == VER): if self.board.get_board()[coord1.row-1][coord1.col]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col]=='': moves.append(coord1) count -= 1 elif (direction == HOR): if self.board.get_board()[coord1.row][coord1.col-1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row][coord1.col+1]=='': moves.append(coord1) count -= 1 elif (direction == DRI): if self.board.get_board()[coord1.row-1][coord1.col-1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col+1]=='': moves.append(coord1) count -= 1 else: if self.board.get_board()[coord1.row-1][coord1.col+1]=='': moves.append(coord1) count -= 1 elif self.board.get_board()[coord1.row+1][coord1.col-1]=='': moves.append(coord1) count -= 1 if (count == 2): m = self.get_legal_move(count) moves.append(m[0]) moves.append(m[1]) count = 0 elif (count ==1): m = self.get_legal_move(count) moves.append(m) if returnCount == 1: return moves[0] elif returnCount == 2: return moves[0],moves[1] def get_legal_move(self,count): print "Random Move" freecoord = [] for r in range(19): for c in range(19): if self.board.get_board()[r][c]=='': freecoord.append(Coord(r,c)) if count==1: c = random.choice(freecoord) return c elif count==2: f1 = random.choice(freecoord) freecoord.remove(f1) f2 = random.choice(freecoord) return f1,f2 def get_start_moves(self): start_moves = Set() start_moves.add(Coord(10,10)) start_moves.add(Coord(9,9)) start_moves.add(Coord(10,9)) start_moves.add(Coord(9,10)) return start_moves def getCoord(self,tuple): return Coord(tuple[0],tuple[1]) def put_enemy_stones(self,coord1,coord2=None): self.board.put_token(coord1,self.enemy) if coord2 != None: self.board.put_token(coord2,self.enemy) def get_rows(self): self.def_rows = [] self.off_rows = [] #self.board.print_board() self.get_vertical_rows() self.get_horizontal_rows() ### BUG IN HORIZONTAL OR VERTICAL def get_horizontal_rows(self): previous_color = '' off_row = None def_row = None for r in range(19): for c in range(19): #print "hor@",r,c token = self.board.get_board()[r][c] ## player field if token == self.color: #print "me@",r,c ## Extend self.player row if previous_color == self.color: off_row = (off_row[0]+1,off_row[1],VER) ## New self.player row else: ## self.enemy_row disturbed? if def_row != None: self.def_rows.append(def_row) def_row = None off_row = (1,[],VER) ## Check if previous field is free if c > 0: #print "free@prev",r,(c-1) if self.board.get_board()[r][c-1] == '': off_row = (off_row[0],[(r,c-1)],VER) ## enemy field elif token == self.enemy: ## Extend self.enemy row if previous_color == self.enemy: def_row = (def_row[0]+1,def_row[1],VER) ## New self.enemy row else: ## self.player row disturbed? if off_row != None: self.off_rows.append(off_row) off_row = None def_row = (1,[],VER) ## Check if previous field is free if c > 0: if self.board.get_board()[r][c-1] == '': def_row = (def_row[0],[(r,c-1)],VER) ## Free field else: ## Any rows disturbed? if off_row != None: #print "free@next",r,c off_row[1].append((r,c)) self.off_rows.append(off_row) off_row = None if def_row != None: def_row[1].append((r,c)) self.def_rows.append(def_row) def_row = None previous_color = token def get_vertical_rows(self): previous_color = '' off_row = None def_row = None for c in range(19): for r in range(19): token = self.board.get_board()[c][r] ## player field if token == self.color: ## Extend self.player row if previous_color == self.color: off_row = (off_row[0]+1,off_row[1],VER) ## New self.player row else: ## self.enemy_row disturbed? if def_row != None: self.def_rows.append(def_row) def_row = None off_row = (1,[],VER) ## Check if previous field is free if c > 0: if self.board.get_board()[r-1][c] == '': off_row = (off_row[0],[(r-1,c)],VER) ## enemy field elif token == self.enemy: ## Extend self.enemy row if previous_color == self.enemy: def_row = (def_row[0]+1,def_row[1],VER) ## New self.enemy row else: ## self.player row disturbed? if off_row != None: self.off_rows.append(off_row) off_row = None def_row = (1,[],VER) ## Check if previous field is free if c > 0: if self.board.get_board()[r-1][c] == '': def_row = (def_row[0],[(r-1,c)],VER) ## Free field else: ## Any rows disturbed? if off_row != None: off_row[1].append((r,c)) self.off_rows.append(off_row) off_row = None if def_row != None: def_row[1].append((r,c)) self.def_rows.append(def_row) def_row = None previous_color = token def is_alive(self,row): return True if len(row[1]) > 1 else False def is_dead(self,row): return True if len(row[1]) == 0 else False def is_sleeping(self,row): return True if len(row[1]) == 1 else False def get_enemy_rows(self): return sorted(self.def_rows, key=lambda number:(number[0], len(number[1])),reverse=True) def get_player_rows(self): return sorted(self.off_rows, key=lambda number:(number[0], len(number[1])),reverse=True) def remove_free_coord(self,coord): containing_coord = filter(self.off_rows, key=lambda c:c[1].contains(coord)) for co in containing_coord: containing_coord.remove(coord)