def run(self): pieces = {i:Piece(val=i) for i in range(16)} board = Board() placePiece = self.p1.get_piece(board, pieces.values()) del pieces[placePiece.val] nextPlayer = self.p2 other = self.p1 victory = None try: while board.placed < 16 and not victory: placePos = nextPlayer.get_placement(board, placePiece, pieces.values()) board.place(placePiece, *placePos) nextPlayer.piece_placed(placePiece, placePos) other.piece_placed(placePiece, placePos) if pieces: placePiece = nextPlayer.get_piece(board, pieces.values()) del pieces[placePiece.val] victory = board.check_victory(placePos) if nextPlayer == self.p1: nextPlayer = self.p2 other = self.p1 else: nextPlayer = self.p1 other = self.p2 self.board = board if victory: if nextPlayer == self.p1: self.winner = self.p2 else: self.winner = self.p1 except Exception, e: self.winner = None self.board = None self.ex = e
def perform_action(self, board, piece, pieces): our_pieces = map(lambda x: Piece(val=x), pieces) our_board = Board() for i, p in enumerate(board): if p: our_board.place(Piece(val=p), *self.__translate_int_pos(i)) if piece == -1: return (self.player.get_piece(our_board, our_pieces).val, -1) else: pos = self.player.get_placement(our_board, Piece(val=piece), our_pieces) next_piece = self.player.get_piece(our_board, our_pieces) return (next_piece.val, self.__translate_pos_int(pos))
class LocalNetworkPlayer(object): '''Network player used when starting a player who is going to connect to a remote server''' def __init__(self, addr, port, player, log=None): self.addr = addr self.port = port self.player = player self.socket = None self.progress = 0 if not log: self.log = logging.getLogger(self.__class__.__name__) else: self.log = log def connect(self, timeout=None): '''Method to connect to a server. This method is used when a user want to start the player from the command-line to connect to a server''' if not self.player: self.log.critical('Can not connect to server without a proper player ' + 'to play with') return self.log.debug('Connecting to server: %s:%i', self.addr, self.port) try: self.socket = socket.create_connection((self.addr, self.port), timeout if timeout else socket.getdefaulttimeout()) except: self.log.exception('Could not establish connection with %s:%i', self.addr, self.port) return for i in range(2): self.log.debug('Trying to say hello to server, round %i', i) self.socket.sendall(const.HELLO) respons = self.socket.recv(128) if respons == const.HELLO: self.log.debug('Server said hello back!') break else: raise socket.error('Could not get a proper response from the server') #If we get here we have connected to the server and said hello to it self.log.info('Connected to server ready to play') def play(self): '''Method used to start this player playing games with the server. This method is used when the user starts this class from the command-line''' if not self.player or not self.socket: self.log.critical('Can not call method play without first calling' + ' connect successfully') return self.board = None self.games = 0 self.total_games = 0 self.mod_games = 0 self.pieces = None while True: move = self.socket.recv(512).split('\n') self.log.debug('Got message: %r', move) self.log.debug('Board:\n%s', self.board) self.log.debug('Pieces: %s', self.pieces) if not self.handle_message(filter(None, move)): break self.__shutdown() def handle_message(self, message): move = message[0].split(' ') if move[0] == const.NEW_GAME: self.log.debug('Got new_game message from server reseting player') self.board = Board() self.pieces = {i:Piece(val=i) for i in range(16)} self.player.reset() games_left = int(move[1]) if self.total_games == 0: self.log.debug('Updating total_games to: %s', games_left) self.total_games = games_left self.mod_games = self.total_games / 10.0 # if self.mod_games > 0: # if self.games % self.mod_games == 0: # self.log.info('We are %i%% complete!', (self.games / float(self.total_games))*100) if self.games % (self.mod_games) == 0: self.log.info('%i%% complete.', self.progress * 10) self.progress += 1 self.games += 1 elif move[0] == const.ERROR: self.log.warning('Got error message from server quiting') return False elif move[0] == const.GET_PIECE: self.log.debug('Got get_piece message from server: %s', move) next_piece = self.player.get_piece(self.board, self.pieces.values()) self.log.debug('Sending piece: %s(%r) to server', next_piece, next_piece) self.socket.sendall(repr(next_piece.val)) elif move[0] == const.GET_PLACEMENT: self.log.debug('Got get_placement message from server: %s', move) piece = int(move[1]) if piece in self.pieces: del self.pieces[piece] pos = self.player.get_placement(self.board, Piece(val=piece), self.pieces.values()) self.log.debug('Sending pos %s to server', pos) self.socket.sendall(repr(self.translate_pos_int(pos))) elif move[0] == const.PIECE_PLACED: self.log.debug('Got placed_piece message from server: %s', move) piece = int(move[1]) if piece in self.pieces: del self.pieces[piece] self.board.place(Piece(val=int(move[1])), *self.translate_int_pos(int(move[2]))) elif move[0] == const.SHUTDOWN: self.log.info('Got shutdown message') results = map(int, move[1:]) total = sum(results) self.log.info('Board:\n%s', self.board) self.log.info('Wins: %s(%i%%)', move[1], (results[0] / float(total))*100) self.log.info('Loses: %s(%i%%)', move[2], (results[1] / float(total))*100) self.log.info('Ties: %s(%i%%)', move[3], (results[2] / float(total))*100) return False if len(message) > 1: return self.handle_message(message[1:]) return True def translate_int_pos(self, i): '''Translate from int: [0, 1, 2, 3] ... to (x, y)''' x = i % 4 y = (i-x) / 4 return (x, y) def translate_pos_int(self, pos): return pos[1]*4 + pos[0] def __shutdown(self): self.log.debug('Shuting down socket') try: self.socket.close() except: self.log.exception('Got exception trying to close socket') def __str__(self): return 'LocalNetwork Player: {}, Connection: {}:{}'.format(self.player, self.addr, self.port)