def stop_game(gameName): if not current_user.is_authenticated: return redirect(url_for('login')) game = Game.query.filter_by(gamename=gameName).first() user = User.query.filter_by(username=current_user.username).first_or_404() light_pieces = request.form['light_pieces'] dark_pieces = request.form['dark_pieces'] if(light_pieces > dark_pieces): game.completed = 1 game.player2_score = light_pieces game.player1_score = dark_pieces game.winner = game.player2_name gmove = GameMove(game_id=game.id, turn_player_id=game.player2_id, turn_player_name=game.player2_name, player_action="Gameover") user_player = User.query.filter_by(id=game.player2_id).first_or_404() user_player.win = 1 else: game.completed=1 game.player1_score=dark_pieces game.player2_score = light_pieces game.winner=game.player1_name gmove = GameMove(game_id=game.id, turn_player_id=game.player1_id, turn_player_name=game.player1_name, player_action="Gameover") user_player = User.query.filter_by(id=game.player1_id).first_or_404() user_player.win = 1 flash("Game is stopped!", "success") db.session.add(gmove) db.session.commit() return redirect(url_for('index'))
async def move(self, game: Game, prev_move: GameMove) -> GameMove: """ Return a move made by the AI. The move can be calculated based on different strategies. By default it will trigger a RandomStrategy which means, picking a random cell from the empty bucket of cells. :param Game game: game over which the move will bem ade :param GameMove prev_move: user move :return GameMove: bot move """ user = await User.find_one({'username': self.botname}) symbol = list(filter( lambda x: x != prev_move.symbol, GameMove.SYMBOLS, ))[0] cell = await self.strategy( symbol, game.size, game.board, ).move() data = { 'symbol': symbol, 'player': user.pk.__str__(), 'cell': { 'row': cell[0], 'column': cell[1], } } return GameMove(**data)
async def validate_board(self, game: Game, move: GameMove, user: User) -> Game: """ Validate if the board to check if there are winners or if there is a tie. :param Game game: :param GameMove move: :param User user: :return Game: """ win_validations = await asyncio.gather( self.__validate_right_diagonal(game), self.__validate_left_diagonal(game), self.__validate_columns(game), self.__validate_rows(game), ) tasks = [asyncio.create_task(move.commit())] if True in win_validations: game.status = Game.STATUS_FINISHED game.winner = move.player user.victories += 1 tasks.append(asyncio.create_task( user.commit() )) elif await self.__validate_tie(game): game.status = Game.STATUS_TIE tasks.append(asyncio.create_task(game.commit())) await asyncio.gather(*tasks) return game
async def get(self, pk: str): """ Retrieve a list of moves from the database :param str pk: :return: """ cursor = GameMove.find({"game": fields.ObjectId(pk)}) data = [] async for obj in cursor: data.append(obj.dump()) self.set_header("Content-Type", 'application/json') self.write({"data": data})
def first_move(gameName): if not current_user.is_authenticated: return redirect(url_for('login')) if request.method == 'POST': user = User.query.filter_by(username=current_user.username).first_or_404() game = Game.query.filter_by(gamename=gameName).first() gameboard = Gameboard(__prepare_board(request), request.form['last_move']) board = gameboard.board x = int(request.form['x']) y = int(request.form['y']) if(user.username == game.player1_name): board[y][x] = DarkPiece() last_move = 'dark' gm = GameMove(game_id=game.id, turn_player_id=game.player1_id, turn_player_name=game.player1_name, player_action="Moves",x_coor = x, y_coor = y, color = "dark") else: board[y][x] = LightPiece() last_move = 'light' gm = GameMove(game_id=game.id, turn_player_id=game.player2_id, turn_player_name=game.player2_name, player_action="Moves",x_coor = x, y_coor = y, color = "light") db.session.add(gm) db.session.commit() return render_template('play.html', board=board, user=user, last_move=last_move, gamename=game.gamename)
def create_game(): gameName = request.form.get('gamename') gameName_re_match = re.match("^[A-Za-z0-9]{5,10}$",gameName) if not bool(gameName_re_match): flash("GameName must contain a length of at least 5 characters and a maximum of 10 characters.", 'error') return redirect(url_for('index')) user = User.query.filter_by(username=current_user.username).first_or_404() game = Game(gamename=gameName, player1_id=user.id, player1_name=user.username, winner="") db.session.add(game) db.session.commit() flash("Game is successfully created!", "success") gm = GameMove(game_id=game.id, turn_player_id=game.player1_id, turn_player_name=game.player1_name, player_action="Created") db.session.add(gm) db.session.commit() return redirect(url_for('index'))
def join_game(gameName): if not current_user.is_authenticated: return redirect(url_for('login')) game = Game.query.filter_by(gamename=gameName).first() user = User.query.filter_by(username=current_user.username).first_or_404() if game.player1_id == user.id: pass else: game.player2_id = user.id game.player2_name = user.username gm = GameMove(game_id=game.id, turn_player_id=game.player1_id, turn_player_name=game.player1_name, player_action="StartGame") db.session.add(gm) db.session.commit() gameboard = Gameboard.build(9) board = gameboard.board return render_template('play.html', board=board, user=user, gamename=game.gamename)
async def execute_move(self, game: Game, move: GameMove) -> Game: """ Execute a move specified by the user considering the restrictions and the game winning calculation. :param Game game: :param GameMove move: :return Game: """ user = await User.find_by_id(move.player.pk.__str__()) move.game = game.pk if not await self.__validate_player_move(game, move): raise HTTPError( 412, 'Invalid move' ) game.board[move.cell.get('row')][move.cell.get('column')] = move.symbol game.status = Game.STATUS_IN_PROGRESS return await self.validate_board(game, move, user)
async def post(self, pk: str): """ Trigger a game move by the user. If the game is multiplayer will execute a bot move immediatly after. This can be vastly improved by the use of the strategy pattern to distinguish single player and multiplayer games. Right now in order to not increase complexity, and as the game rules are no different on both modes we are going by a simple decision. :param str pk: :return: """ game: Game = await Game.find_by_id(pk) if game.status in [Game.STATUS_TIE, Game.STATUS_FINISHED]: raise HTTPError(400, 'Game was already finished') data = json_decode(self.request.body) move = GameMove(**data) await engine.execute_move(game, move) if not game.multiplayer and game.status == Game.STATUS_IN_PROGRESS: aimove = await GameBot().move(game, move) await engine.execute_move(game, aimove) self.set_header("Content-Type", 'application/json') self.write(game.dump())