def _solve_puzzle(self): self._label["text"] = "Working" self._window.update() try: board = Board() for row in range(Board.BOARD_SIZE): for col in range(Board.BOARD_SIZE): str_val = self._inputs[row][col].get() if str_val == "": int_val = 0 else: int_val = int(str_val) board.set_cell_value(row, col, int_val) result = Solver().solve(board) if not result.success: self._label["text"] = "Failed" return self._label["text"] = "Success" self._paint_board(result.solution) except: self._label["text"] = "Error"
def draw_boards(primary_canvas, secondary_canvas, control_canvas, width, height, size, margin, primary_board=None, secondary_board=None): primary_canvas.delete("all") secondary_canvas.delete("all") control_canvas.delete("all") if primary_board is None: primary_board = Board(width, height) if secondary_board is None: secondary_board = Board(width, height) primary_graphic_board = GraphicBoard(primary_board, secondary_board, primary_canvas) secondary_graphic_board = GraphicBoard(secondary_board, primary_board, secondary_canvas) primary_graphic_board.draw_tiles(size=size, sister_g_board=secondary_graphic_board, margin=margin, goal_board=secondary_board) secondary_graphic_board.draw_tiles(size=size, sister_g_board=primary_graphic_board, margin=margin, goal_board=primary_board) draw_buttons(control_canvas, primary_canvas, secondary_canvas, primary_board, secondary_board, primary_graphic_board, secondary_graphic_board)
def parse(self, content): ''' Parse the puzzle file's content into models ''' cars = {} for each_line in content: description = each_line.split() # print(description) index = int(description[0]) y_top_left = int(description[1]) x_top_left = int(description[2]) length = int(description[3]) orientation = int(description[4]) car = Car(index, y_top_left, x_top_left, length, orientation) if orientation == Orientation.HORIZONTAL: car.set_end_location(y_top_left, x_top_left+length-1) else: car.set_end_location(y_top_left+length-1, x_top_left) cars[index] = car self.puzzle_board = Board() # It will print "Car x: top-left at (x,x) and has length x, orientation x." # print(cars[0]) for key, car in cars.items(): occupied_locations = car.get_occupied_locations() self.puzzle_board.add_car(car, occupied_locations)
def rule_quadrant_col_and_row_elim_possible(board: Board) -> List[Action]: action_arr = [] max_val = board.max_val() max_sqrt = board.max_sqrt() for quadrant_x in range(0, max_val, max_sqrt): for quadrant_y in range(0, max_val, max_sqrt): quadrant_cells = board.quadrant_cells(quadrant_x, quadrant_y, True) if len(quadrant_cells) == 0: continue for col_y in range(quadrant_y, quadrant_y + max_sqrt): col_cells = board.col_cells(col_y, True) if len(col_cells) == 0: continue action_arr.extend(_quadrant_col_cell_elim_helper(quadrant_cells, col_cells)) for row_x in range(quadrant_x, quadrant_x + max_sqrt): row_cells = board.row_cells(row_x, True) if len(row_cells) == 0: continue action_arr.extend(_quadrant_col_cell_elim_helper(quadrant_cells, row_cells)) return action_arr
def __init__(self, playerOne=None, playerTwo=None): """Inits an instance of the Game class. PlayerOne is always the human side of the game. Args: playerOne (Optional[model.player.Player]): The human player (default is None). playerTwo (Optional[model.player.Player]): The AI player (default is None). """ self.playerOne = playerOne self.playerTwo = playerTwo self.listeners = list() self.aiPlayer = self.playerOne if self.playerOne.isAi \ else self.playerTwo self._board = Board() self._uuid = None self._moves = list() self.status = Status.InProgress self.nextPlayer = self.playerOne dispatcher.connect(self._onAiMoveResponse, signal=Events.aiResponse)
def main(): print("hello world!") board = Board() board.begin(Color.RED) print(board) for x in board.get_playable_position(): print(x)
def __init__(self, win): self.win = win self.board = Board() self.selected_piece = None self.turn = BLACK self.valid_moves = {} self._init_game()
def apply_action(self, board: Board): mod_cell = board.get_cell(self.x(), self.y()) if mod_cell.is_initial(): return new_cell = mod_cell.clear_possible_value(self._value) board.set_cell(new_cell)
def new_game(self): self.dialog_new_game.exec() if not self.ui.is_player2_human: self.ai_player = AIPlayer('red', self.ui.difficulty) else: self.ai_player = None self.board = Board() self.over = False self.active_player = 1
def single_ai_mode(): # set up local player data addPlayerData(player_name) screen_size = [700, 700] pygame.init() fpsClock = pygame.time.Clock() # create pyGame screen playSurface = pygame.display.set_mode((screen_size[0], screen_size[1])) my_board = Board(50, 50) my_snake = Snake(50, 50) # set up food and snake food_loc = [my_board.food] draw_surface(playSurface, redColour, [my_board.food], 10, 100) # draw first food pygame.display.set_caption('Food Snake') total_score = 0 score = 0 level = 1 isEnd = False while True: # give AI input, and let AI control snake dir = AI1(my_board, my_snake) my_snake.turn(dir) # catch event and control snake eventHelper(my_snake, False) # increase along the moving direction draw_surface(playSurface, blackColour, my_snake.get_cells(), 10, 100) status = my_snake.tick(my_board.food, []) my_snake.teleport_wall() my_new_cells = my_snake.get_cells() if my_snake.is_dead([]) or isEnd: break # When snake eats the food if status == 1: score += my_board.foodWeight total_score += 1 my_board.new_food(my_new_cells, my_snake.obstacles, []) food_loc = [my_board.food] if score - level > level / 2: level += 1 if level % 2 == 0: my_snake.add_obstcles(level) if level % 3 == 0: my_snake.speed += 1 displayHelper(playSurface, fpsClock, level, food_loc, my_snake, total_score, player_name) game_end(total_score)
def _clear_possible_action(board: Board, mod_cell: Cell, value: int): if mod_cell.is_initial(): return if mod_cell.value() is not None: return if mod_cell.has_possible_val(value): new_cell = mod_cell.clear_possible_value(value) board.set_cell(new_cell)
def rule_row_exclusive(board: Board) -> List[Action]: action_arr = [] for x in range(board.max_val()): cur_row = board.row_cells(x, True) action_arr.extend(_rule_exclusive_set(cur_row)) return action_arr
def rule_col_exclusive(board: Board) -> List[Action]: action_arr = [] for y in range(board.max_val()): cur_col = board.col_cells(y, True) action_arr.extend(_rule_exclusive_set(cur_col)) return action_arr
def create_board(P1, P2, P3, *args): board = Board() P1 = board.get_player(P1) P2 = board.get_player(P2) P3 = board.get_player(P3) A = board.add_node('A', player=P1, power=2) L = board.add_node('L', player=P2, power=2) P = board.add_node('P', player=P3, power=2) B, C, D, E, F, G, H, I, J, K, M, N, O = board.get_empty_nodes(['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'M', 'N', 'O']) board.add_paths([(A, B), (A, C), (A, D), (B, E), (C, F), (D, G), (E, H), (F, I), (F, J), (G, K), (H, L), (I, L), (J, P), (K, P), (L, M), (M, N), (N, O), (O, P) ]) return board
def get(self): board_id = self.get_argument("board", None) board = Board.get_by_pk(board_id) board_title = board.title if board else None self.render( "forum/topic_new.html", nav="index", page_title=page_title("新建主题", board_title, "社区"), boards=Board.get_list(), board_id=board_id, )
def apply_action(self, board: Board): mod_cell = board.get_cell(self.x(), self.y()) if mod_cell.is_initial(): return if mod_cell.value() is None: return new_cell = mod_cell.clear_value(board) board.set_cell(new_cell)
def compute(self): """ Boucle principal de ce client. Cette boucle va générer des parties IA contre IA à l'infini. Entre chaque partie, il va envoyer l'exemple au serveur. C 'est le client qui décide quel doit être le coef d'apprentissage à utiliser pour chaque exemple. Un exemple représente un tour. """ if not self.is_connected: raise NotConnectedError() try: while True: # Initialisation : board = Board() history_board = list() history_choice = list() history_actions = list() current_player = list() i = 0 while board.winner() == 0: i += 1 # On joue selon l'IA self.tree = Tree(board, self.ia, { 0: 1, 1: -1 }[board.current_player]) for _ in range(100): self.tree.compute() act = self.tree.get_best() history_board.append(board.get_board_raw()) actions = board.getActions() history_choice.append(actions.index(act)) history_actions.append( board.get_actions_board_raw(actions)) current_player.append({0: 1, 1: -1}[board.current_player]) act.do(board=board) print("Finish") # Last action # On envoie les actions 1 par 1 avec un coef d'apprentissage adapté. for i in range(25): if current_player[-1 * (i + 1)] == board.winner(): self.send(PUSH_EXEMPLE_OPCODE, exp(-1 * i * 0.075), history_board[-1], history_actions[-1], history_choice[-1], board.winner()) save_file = open( "./log-client/{}-{}.data".format( datetime.now().strftime("%m-%d_%H:%M:%S"), self.id), "wb") save_file.write( dumps((history_board, history_choice, history_actions, board.winner()))) save_file.close() kernels = self.execute(GET_KERNEL_OPCODE) self.ia.load_kernel(kernels) except KeyboardInterrupt: pass
def set_board(self, board: board_func.Board) -> None: if self.__board.max_val() != board.max_val(): raise ValueError( "GUIBoard cannot adjust to different-sized boards!") self.__board = board # The GUI board owns the GUI cells for x in range(board.max_val()): for y in range(board.max_val()): board_cell = board.get_cell(x, y) self.__gui_cells[x][y].set_cell(board_cell)
def apply_action(self, board: Board): mod_cell = board.get_cell(self.x(), self.y()) if mod_cell.is_initial(): return new_cell = mod_cell.set_value(self._value, self._initial) board.set_cell(new_cell) link_cells = board.linked_cells(mod_cell.x(), mod_cell.y()) link_cells.remove(new_cell) for cell in link_cells: _clear_possible_action(board, cell, self._value)
def start_game(self): """The game is started with the selected settings. The default settings are: human vs. human.""" # Change starting screen to Chess board self.board = Board(square_width=self.view.square_width, square_height=self.view.square_height, is_flipped=self.is_flipped) # Create players self.board.player_list.append('Human') if self.settings['vs_computer']: self.board.player_list.append('AI') else: self.board.player_list.append('Human')
def combination_exclusive_quadrant_rule(board: Board) -> List[Action]: action_arr = [] max_val = board.max_val() max_sqrt = board.max_sqrt() for quadrant_x in range(0, max_val, max_sqrt): for quadrant_y in range(0, max_val, max_sqrt): quadrant_cells = board.quadrant_cells(quadrant_x, quadrant_y, True) action_arr.extend(_combination_exclusive_rule_helper(quadrant_cells)) return action_arr
def combination_exclusive_rowcol_rule(board: Board) -> List[Action]: action_arr = [] for x in range(board.max_val()): cur_row = board.row_cells(x, True) action_arr.extend(_combination_exclusive_rule_helper(cur_row)) for y in range(board.max_val()): cur_col = board.col_cells(y, True) action_arr.extend(_combination_exclusive_rule_helper(cur_col)) return action_arr
def move(): data = bottle.request.json board = Board.from_json(data) murgatroid_controller = MurgatroidController(board) directions_map = murgatroid_controller.get_possible_directions() edge_direction = murgatroid_controller.move_edge() food_directions = murgatroid_controller.get_food_directions(directions_map) if food_directions: return json.dumps({ 'move': murgatroid_controller.get_safest_direction(food_directions), 'shout': SHOUT, }) else: if edge_direction in directions_map: direction = edge_direction else: direction = murgatroid_controller.get_safest_direction( directions_map) return json.dumps({ 'move': direction, 'shout': SHOUT, })
async def _runHanabot(self): """ Initializes the hanabot AI and keeps it running. """ await asyncio.sleep(0.5) self._hanabot = Hanabot(Board(self._sensoryBuffer.cvState['hand'])) await self._hanabot.react(self._sensoryBuffer, self._outputBuffer)
def get(self): board_id = self.get_argument('board_id', None) board = MBoard.get_by_pk(board_id) if board: self.render('admin/forum/modal_board_edit.html', board=board) else: self.finish("找不到对应的板块")
class Solver: def __init__(self): self._debut_board = Board() self._result = Result() def _attempt(self): missing_numbers = self._debut_board.get_missing_numbers() empty_cells = self._debut_board.get_empty_cell_locations() number_combinations = permutations(missing_numbers, len(missing_numbers)) for combo in number_combinations: cloned_board = self._debut_board.clone() cell_index = 0 for empty_cell in empty_cells: try: cloned_board.set_cell_value(empty_cell.get_x(), empty_cell.get_y(), combo[cell_index]) cell_index = cell_index + 1 except NumberAssignmentError: break if cloned_board.has_empty_cell(): continue evaluator = Evaluator() evaluator.evaluate(cloned_board) if evaluator.is_complete() and evaluator.is_valid(): self._result.complete = True self._result.success = True self._result.solution = cloned_board return def solve(self, board: Board) -> Result: self._result = Result() self._debut_board = board self._attempt() return self._result
def _paint_board(self, board: Board): for row in range(Board.BOARD_SIZE): for col in range(Board.BOARD_SIZE): int_val = board.get_cell_value(row, col) if int_val == 0: str_val = "" else: str_val = str(int_val) self._input_texts[row][col].set(str_val)
def get(self): self.prepare() words_query = Board.get_all() # 获得所有留言 self.render( 'board.html', words_query=words_query, find_words_query='' # 此处不赋值为空,将报错未定义变量 )
def __restart_game(self): self.round_counter += 1 self.turn_counter = 0 self.board = Board() self.checker = ResultChecker(self.board) self.player_1_ctrl.set_board(self.board) self.player_2_ctrl.set_board(self.board) self.__generate_order_of_players() self.__create_game()
def post(self): board_id = self.get_argument('board_id', None) board = MBoard.get_by_pk(board_id) if board: board.state = BOARD_STATE.DEL board.save() code = 0 else: code = -1 self.finish(json.dumps({'code': code}))
def generate_puzzle(): start = time.time() initial_actions = None max_val = 16 while initial_actions is None: print('k') initial_actions = model.solver.generate(max_val) board = Board(max_val) board = board.apply_actions(initial_actions) board_str = str(board) print(board_str) print(time.time() - start) SudokuApp(board_str).run()
def create_board(P1, P2, *args): board = Board() P1 = board.get_player(P1) P2 = board.get_player(P2) A = board.add_node('A', player=P1, power=2) B, C, D = board.get_empty_nodes(['B', 'C', 'D']) E = board.add_node('E', player=P2, power=2) board.add_paths([(A, B), (B, C), (C, D), (D, E)]) return board
def rule_one_possible(board: Board) -> List[Action]: action_arr = [] for cell in board.all_cells(): if cell.possible_count() == 1: for result_val in cell.possible_vals(): action_arr.append(SetAction(cell.x(), cell.y(), result_val)) return action_arr
def get(self): words_query = Board.get_all() # 获得所有留言 page_size = 5 cur_page = self.get_argument("cur_page", int(math.ceil(words_query.count() / page_size))) words = pagination(count_all=words_query.count(), query=words_query, page_size=page_size, cur_page=cur_page) page_title = "联系站长" self.render( 'board.html', words=words, page_title=page_title, )
def post(self): name = self.request.get('name') desc = self.request.get('desc') if name == '': self.error(400) else: creator = getSecureUser(self.request) if (creator is not None): existingBoard = Board.query(Board.name == name).fetch() if len(existingBoard) is 0: admins = [creator] newBoard = Board(name=name, desc=desc, admins=admins) newBoard.put() else: self.error(409) else: self.error(401)
def post(self): title = self.get_argument('board_title', '').strip() brief = self.get_argument('board_brief', None) if not title: self.messages.error('必须填写板块名') else: if brief: brief = brief.strip() if not MBoard.new(title, self.current_user(), brief): self.messages.error('创建失败,是否有同名板块存在?') #self.set_header('Location', self.request.headers.get("Referer")) self.redirect(url_for('admin_forum_board'))
def get(self, topic_id): topic = Topic.get_by_pk(topic_id) if not self.topic_check(topic): return self.render( "forum/topic_edit.html", nav="index", page_title=page_title("编辑主题 - %s" % topic.title, topic.board.title, "社区"), topic=topic, boards=Board.get_list(), )
def post(self): words = self.get_argument('words', '') # 用户的留言 find_words = self.get_argument('find_words', '') # 模糊查询的字符串 dele_by_id = self.get_argument('dele_by_id', '') words_query = Board.get_all() # 获取所有留言 IP = self.request.remote_ip # history_time = time.strftime('%Y-%m-%d %X', time.localtime()) #获取当前时间,与用户留言一起存入数据库 # user_key = self.get_secure_cookie('u') # User.get_by_key(user_key) #凭key找到当前用户 user = self.current_user() if find_words: # 模糊查询 find_words_query = Board.get_by_words(find_words) self.messages.success("查询成功!") else: find_words_query = [] if words: username = user.username Board.new(username, words, IP) self.messages.success("留言成功!") if dele_by_id: if user.is_admin(): # 如果不是admin用户将无法删除 Board.dele_by_id(dele_by_id) self.messages.success("删除成功!") else: self.messages.error("您没有删除权限!") self.render( 'board.html', words_query=words_query, find_words_query=find_words_query, )
def __init__(self, print_graph=False): self.when_started = dt.utcnow() self.players = [] self.turns = [[]] #element = a list of moves self.turn = 0 self.print_graph = print_graph self.board = Board(self) if self.print_graph: self.board.print_graph()
def get(self, board_id): board = Board.get_by_pk(board_id) if board: page = self.get_argument("p", "1") count, query = Topic.get_list_by_board(board) pagination_ret = pagination(count, query, config.TOPIC_PAGE_SIZE, page) self.render( "forum/board.html", nav="index", page_title=page_title(board.title, "社区"), board=board, topics_count=count, pagination=pagination_ret, page_url=self.request.path, ) else: self.write_error(404)
def post(self): board_id = self.get_argument('board_id', None) title = self.get_argument('board_title', '').strip() brief = self.get_argument('board_brief', None) weight = self.get_argument('board_weight', None) state = self.get_argument('board_state', None) board = MBoard.get_by_pk(board_id) if board: board.title = title board.brief = brief board.weight = weight board.state = state board.save() code = 0 else: code = -1 self.finish(json.dumps({'code': code}))
def post(self): words = self.get_argument('words', '') # 用户的留言 dele_by_key = self.get_argument('theKey', '') IP = self.request.headers["X-Forwarded-For"] user = self.current_user() username = None word_user = None word_username = None if user is None: user = JsDict() user.username = "******" if dele_by_key != "": word_user = Board.get_one(Board.key == dele_by_key) if word_user is not None: word_username = word_user.username if user is not None: username = user.username if dele_by_key: if user.is_admin() or username == word_username: # 如果不是admin用户将无法删除 Board.dele_by_key(dele_by_key) self.write("删除成功!") else: self.write("您没有删除权限!") elif words: username = user.username user_re = re.compile(r"@(\S{3,19}) (.*)") try: foruser = user_re.search(words).group(1) if not User.exist(foruser): foruser = "" else: words = user_re.search(words).group(2) except Exception as e: foruser = "" if Board.num_lim(username): self.messages.error("留言过多,请联系管理员!") self.redirect("/board") elif user.username != "游客" and user.level == 0: self.messages.error("您暂时无法留言!") self.redirect(url_for("board")) else: Board.new(username, foruser, words, IP) self.messages.success("留言成功!") self.redirect(url_for("board")) else: self.redirect(url_for("board")) '''
def post(self): title = self.get_argument("title", "").strip() board = self.get_argument("board", None) content = self.get_argument("content", "").strip() if title and config.TITLE_LENGTH_MIN <= len(title) <= config.TITLE_LENGTH_MAX and Board.exists_by_pk(board): t = Topic.new(title, self.current_user() or 0, board, content) self.redirect(url_for("topic", t.id)) else: # 非标准提交,不用过于客气 self.redirect(url_for("topic_new"))
def first_run(): if User.count() == 0: u = User.new('root', '123') Board.new('初学者', u, '你们啊,还是需要学习一个。') Board.new('问与答', u, '但是你们问来问去的问题呀,都 too young, too simple.') Board.new('游戏开发', u, '游戏制作的种种') Board.new('WEB开发', u, '当下最热门的技术种类') Board.new('发起项目', u, '已有创意,就差一个程序员/设计师/策划/运营了!') Board.new('项目展示', u, '今天我作为一个长者,给你们分享一点人生的经验') Board.new('水区', u, '社区的哪一个牛人我没有见过?我跟他们谈笑风生!')
def get(self): self.render("forum/index.html", nav="index", boards=Board.get_list())
class Game(object): def __init__(self, print_graph=False): self.when_started = dt.utcnow() self.players = [] self.turns = [[]] #element = a list of moves self.turn = 0 self.print_graph = print_graph self.board = Board(self) if self.print_graph: self.board.print_graph() def moves_all(self): moves = [] for turn in self.turns: moves.extend(turn) return moves def append_move(self, move): if self.turn > len(self.turns): aself.turns.append([]) self.turns[self.turn].append(move) def current_turn(self): if self.turn >= len(self.turns): self.turns.append([]) return self.turns[self.turn] def add_player(self, player): player.board = self.board self.players.append(player) def computer(self): return [x for x in self.players if x.is_computer()][0] def human(self): return [x for x in self.players if x.is_human()][0] def player_turn(self, player): player_moves = player.my_turn() for move in player_moves: self.check_and_play_player_move(player, move) if self.battle_conditions_met(): self.battle() if self.print_graph: self.board.print_graph() self.turn += 1 def check_and_play_player_move(self, player, move): if self.battle_conditions_met(): self.validate_move_can_be_played_after_battle_is_played(move) move.put_yourself_to_board(player, self.board) self.append_move(move) def validate_move_can_be_played_after_battle_is_played(self, move): if not move.can_be_done_after_battle_is_played: raise Exception('Move was made which cant go to a board after battle is used before: %s', move) def rule_move_causes_battle(self, move): #TODO: another rule here: if that is move after any player's last move, then also a battle if move.__class__.__name__.lower() == 'battle': return True else: return False def battle_conditions_met(self): for move in self.current_turn(): if self.rule_move_causes_battle(move): return True if self.board.rule_is_full_for_battle(): return True return False def battle(self): raise BattleStarts()
def get(self): self.render(nav='admin', boards=MBoard.get_list(BOARD_STATE.BAN))
class Game(object): """ Attributes: playerOne The human player. playerTwo: The AI player. listeners: The game events listeners. """ log = Logger() def __init__(self, playerOne=None, playerTwo=None): """Inits an instance of the Game class. PlayerOne is always the human side of the game. Args: playerOne (Optional[model.player.Player]): The human player (default is None). playerTwo (Optional[model.player.Player]): The AI player (default is None). """ self.playerOne = playerOne self.playerTwo = playerTwo self.listeners = list() self.aiPlayer = self.playerOne if self.playerOne.isAi \ else self.playerTwo self._board = Board() self._uuid = None self._moves = list() self.status = Status.InProgress self.nextPlayer = self.playerOne dispatcher.connect(self._onAiMoveResponse, signal=Events.aiResponse) @staticmethod def create(playerOne, playerTwo): """Creates an instance of the Game class. Sets the UUID of the new game. Args: playerOne (model.player.Player) playerTwo (model.player.Player) Returns: An instance of the Game class where the attribute _uuid was assigned a value to. """ if playerOne is None: raise ValueError('playerOne') if playerTwo is None: raise ValueError('playerTwo') p = Game(playerOne, playerTwo) p.uuid = uuid.uuid4() return p def start(self): self.log.info('Starting the game {0}'.format(self.uuid)) # prepares to launch the AI script aiScriptPath = os.getcwd() + "/../ai/aiprocess.py" self.log.debug('AI script path is {0!s}'.format(aiScriptPath)) kwargs = dict() aiprotocol.makePipe(bytes(self.uuid), self.aiPlayer.symbol, self.aiPlayer.depth, sys.executable, aiScriptPath, **kwargs) def stop(self): pass def close(self): pass @property def boardData(self): return self._board.data @property def uuid(self): """Gets the UUID of the game.""" return self._uuid @uuid.setter def uuid(self, uuid): """Sets the UUID for this game.""" if uuid is None: raise ValueError("The game's uuid cannot be None or empty.") self._uuid = uuid def makeMove(self, row, col, symbol): """Handles the player's turn. Places a piece/symbol on the board at a given position. Args: row (int): The row. col (int): The column. symbol (int): The symbol. Returns: The updated status of the game (common.ipc.GameStatus). Raises: IndexError. """ self.log.debug('Invoke makeMove with %d, %d, %d' % (row, col, symbol)) if (row < 0) or (row >= Board.SIZE): raise IndexError('Wrong value for the row index: %d' % (row)) if (col < 0) or (col >= Board.SIZE): raise IndexError('Wrong value for the column index: %d' % (col)) gameStatus = GameStatus(data=self.boardData, turn=self.nextPlayer.symbol, status=self.status, error=Errors.NoError) # if self.isGameOver(): self.log.info('The game was over !') return gameStatus # if symbol != self.nextPlayer.symbol: self.log.warn("It is not the {0:d} turn's".format(symbol)) gameStatus.error = Errors.WrongTurn return gameStatus # if self.isLegalMove(row, col): self.log.debug('Place the symbol {0:d} at ({1:d}, {2:d})'. format(symbol, row, col)) self._board.set(row, col, symbol) self._moves.append((row, col, symbol)) self.status = self._computeGameStatus(row, col) if self.isGameOver(): self.log.info('The game is over : {0:d}'.format(self.status)) dispatcher.send(signal=Events.quit, uuid=self.uuid) else: self._updateNextSymbol() self.log.debug('Game.makeMove - next symbol is {0:d}'. format(self.nextPlayer.symbol)) gameStatus.turn = self.nextPlayer.symbol # if self.nextPlayer.symbol == self.aiPlayer.symbol: self._aiMove(row, col) else: self.log.error('Illegal move') gameStatus.error = Errors.IlegalMove gameStatus.data = self.boardData gameStatus.status = self.status return gameStatus def isLegalMove(self, row, col): """Checks if a piece can be placed on the board at a given position. Args: row (int): The row. col (int): The column. Returns: bool: True if the piece can be placed on the board, False otherwise. """ self.log.debug('Invoke isLegalMove with (%d, %d)' % (row, col)) symbol = self._board.get(row, col) self.log.debug('symbol = {0!s}'.format(symbol)) return (not self.isGameOver()) and (symbol == Symbol.Empty) def isGameOver(self): """Checks whether the game is over. Returns: bool: True if the game is over, False otherwise. """ self.log.debug('invoking isGameOver: status is {status:d}', status=self.status) return (self.status != Status.InProgress) def _aiMove(self, row, col): """Signals that AI player is to make the next move. Args row (int): The last row coordinate of the human move. col (int): The last column coordinate of the human move. """ dispatcher.send(signal=Events.aiMove, uuid=self.uuid, row=row, col=col) def _onAiMoveResponse(self, uuid, row, col): """Handles the Events.AiResponse signal.""" self.log.debug('_onAiMoveResponse: {uuid}, {row}, {col}', uuid=uuid, row=row, col=col) self.log.debug('_onAiMoveResponse: self.uuid = {uuid}', uuid=self.uuid) if str(uuid) != str(self.uuid): # it's not for this game: ignore the signal return self.log.debug('AI process responded with: row {row} and col {col}', row=row, col=col) # gameStatus = None if (row == -1) or (col == -1): self.log.debug('_onAiMoveResponse: no moves available') gameStatus = CopyGameStatus(GameStatus(status=Status.Tie)) else: gameStatus = CopyGameStatus(self.makeMove(row, col, self.aiPlayer.symbol)) # try to notify the client that the AI's turn has completed if self.listeners: for cbk in self.listeners: self.log.debug('calling onAiMoved on the remote object') d = cbk.callRemote('onAiMoved', row=row, col=col, results=gameStatus) d.addCallback(lambda _: self.log.debug('remote_onAiMoved succeeded')) d.addErrback(lambda reason: self.log.error('remote_onAiMoved failed: {reason}', reason=reason)) def _count(self, symbol, row, col, dirI, dirJ): """Counts the occurrences of a symbol along a given direction. While inside the bounds of the board go in forward and backward directions of the direction vector and increment the counter while still on the 'side' symbol. Args: symbol (int): The symbol. row (int): The row where the piece/symbol was placed on. col (int): The column where the piece/symbol was placed on. dirI (int): The row component of the direction vector. dirJ (int): The column component of the direction vector. Returns: int: The number of occurrences of the given symbol. """ count = 0 i = row j = col # forward direction while (i > -1) and (i < Board.SIZE) and \ (j > -1) and (j < Board.SIZE) and \ (self._board.get(i, j) == symbol): count += 1 i += dirI j += dirJ # backward direction i = row - dirI j = col - dirJ while (i > -1) and (i < Board.SIZE) and \ (j > -1) and (j < Board.SIZE) and \ (self._board.get(i, j) == symbol): count += 1 i -= dirI j -= dirJ self.log.debug('_count: count = {0:d}'.format(count)) return count def _computeGameStatus(self, row, col): """Checks if we have a winner or it's a tie. Args: row (int): The row. col (int): The column. Returns: The status of the game: Status.Tie, Status.X_Won or Status.O_Won. """ self.log.debug('_computeGameStatus: (%d, %d)' % (row, col)) if self._moves.count == (Board.SIZE ** 2): return Status.Tie symbol = self._board.get(row, col) self.log.debug('_computeGameStatus: symbol is %d' % (symbol)) if (self._count(symbol, row, col, 1, 0) == Board.SIZE): return self._winner(symbol) if (self._count(symbol, row, col, 0, 1) == Board.SIZE): return self._winner(symbol) if (self._count(symbol, row, col, 1, -1) == Board.SIZE): return self._winner(symbol) if (self._count(symbol, row, col, 1, 1) == Board.SIZE): return self._winner(symbol) return Status.InProgress def _winner(self, symbol): """ """ return Status.X_Won if symbol == Symbol.X else Status.O_Won def _updateNextSymbol(self): """Gets the player which can place a piece on the board. Args: Returns: Symbol: the player which makes the next move. """ self.nextPlayer = self.playerOne if self.nextPlayer == self.playerTwo \ else self.playerTwo