def index(request): """ TODO VALIDAR QUE SOLO SE PUEDA ACCEDER AL GAME DESDE CIERTA URL, BLOQUEAR LAS DEMAS CONEXIONES CORRER ALV A ALGUIEN SI LA SALA YA TIENE 2 VATOS HACER LOGIN Y REGISTER EN LA MISMA PAGINA """ if request.method == 'POST': # Usar id del juego en vez de nombre # Checar si existe alguien mas que haya echo este post if (len(Games.objects.all()) > 0): # si hay game_name = Games.objects.get() # borramos la partida de la db true_game_name = game_name.game_name game_name.delete() return render(request, 'index.html', {'game_name': true_game_name}) else: # No hay juegos entonces lo creamos letters = string.ascii_letters game_name = ''.join(random.choice(letters) for i in range(8)) game = Games(game_name=game_name) game.save() # Mandamos al usuario a su partida return render(request, 'index.html', {'game_name': game_name}) else: return render(request, 'index.html')
async def game_replay_ws(request): ''' Replay of ended game ''' game_id = request.match_info['id'] ws = web.WebSocketResponse(autoclose=False) await ws.prepare(request) games = Games(request.db) game_info = await games.one(game_id) try: if not game_info.finished or not game_info.winner_id: raise Exception('Game is not finished.') game_moves = await games.get_moves(game_id) for move in game_moves: ws.send_str(json.dumps({ 'status': STATUS['OK'], 'x': move.x, 'y': move.y, 'value': move.users_id, 'message': '#{} made move on {},{}'.format(move.users_id, move.x, move.y) })) await asyncio.sleep(1) except: print(str(e)) ws.send_str(json.dumps({ 'status': STATUS['ERROR'], 'message': str(e) })) await ws.close() return ws
async def games_create(request): ''' Create new game ''' session = await get_session(request) form = GameCreateForm() if request.method == 'POST': form.process(await request.post()) if form.validate(): games = Games(request.db) result = await games.create(form.data) if result and result.lastrowid: await games_join_helper(request, result.lastrowid) return {'title': 'List of games', 'form': form}
async def games_join_helper(request, game_id=None): ''' Join game helper function ''' games = Games(request.db) count_players = await games.count_users_in_game(game_id) if count_players >= PLAYERS_IN_GAME: print('Game has already {} players.'.format(PLAYERS_IN_GAME)) raise web.HTTPFound(request.app.router['main'].url()) session = await get_session(request) user_id = int(session['user']) is_user_in_game = await games.is_user_in_game(user_id, game_id) if is_user_in_game: print('User #{} is already in game #{}'.format(user_id, game_id)) raise web.HTTPFound(request.app.router['main'].url()) await games.add_user(user_id, game_id) raise web.HTTPFound(request.app.router['game_detail'].url(parts={'id': game_id}))
async def games_detail(request): ''' Play or watch game ''' session = await get_session(request) user_id = int(session['user']) game_id = request.match_info['id'] games = Games(request.db) game_info = await games.one(game_id) game_users = await games.get_users(game_id) game_moves = await games.get_moves(game_id) size = game_info.config_size data_moves = [[0]*size for i in range(size)] for moves in game_moves: data_moves[moves.x][moves.y] = str(moves.users_id) current_user_in_game = any(user.id == user_id for user in game_users) next_user_id = 0 if len(game_users) == PLAYERS_IN_GAME: next_user_id = game_users[int((size**2 - len(game_moves)) % 2 == 0)].id elif not len(game_moves): next_user_id = game_users[0].id return { 'game_id': game_id, 'game_info': game_info, 'data_moves': data_moves, 'game_users': game_users, 'game_size': range(size), 'title': 'Game room #{}'.format(game_id), 'url': request.app.router['game_ws'].url(parts={'id': game_id}), 'replay_url': request.app.router['game_replay'].url(parts={'id': game_id}), 'user_id': user_id, 'current_user_in_game': int(current_user_in_game), 'next_user_id': next_user_id, 'response_status': json.dumps(STATUS) }
async def games_list(request): ''' List of games ''' session = await get_session(request) user_id = int(session['user']) games = Games(request.db) result = await games.all() data = [] for one in result: data_one = dict(one) if not one.finished and one.users_count < PLAYERS_IN_GAME and \ user_id not in list(map(int, one.users_ids.split(','))): data_one['url'] = request.app.router['game_join'].url(parts={'id': one.id}) data_one['url_label'] = 'Join' else: data_one['url'] = request.app.router['game_detail'].url(parts={'id': one.id}) data_one['url_label'] = 'View' if one.finished and one.winner_id == DRAW: data_one['winner_login'] = '******' data.append(data_one) return {'title': 'List of games', 'data': data}
async def game_detail_ws(request): ''' Game websocket handler ''' session = await get_session(request) user_id = int(session.get('user')) game_id = request.match_info['id'] ws = web.WebSocketResponse(autoclose=False) await ws.prepare(request) opened_ws = request.app['websockets'][game_id] games = Games(request.db) game_users = await games.get_users(game_id) data_users = [] for user in game_users: data_users.append({ 'id': user.id, 'login': user.login }) for _ws in opened_ws: _ws.send_str(json.dumps({'message': '{} joined'.format(user_id), 'status': STATUS['INFO']})) _ws.send_str(json.dumps({'message': 'update user list', 'status': STATUS['UPDATE_USERS'], 'users': data_users})) opened_ws.append(ws) async for msg in ws: if msg.tp == MsgType.text: if msg.data == 'close': await ws.close() else: data = json.loads(msg.data) try: # Check need attributes if 'i' not in data or 'j' not in data: raise Exception('Positions of move are required.') # Check if user in game if not any(user.id == user_id for user in game_users): raise Exception('You cannot play this game. Create your own to game.') game_info = await games.one(game_id) # Check if game was not ended if game_info.winner_id: raise Exception('Game is over.') game_moves = await games.get_moves(game_id) check_pairs_moves = ((game_info.config_size**2 - len(game_moves)) % 2 == 0) check_pairs_user = ((next(index for index, user in enumerate(game_users) if user.id == user_id) + 1) % 2 == 0) # Check if current user must move if check_pairs_user != check_pairs_moves: raise Exception('It is not your turn.') data_moves = [[0]*game_info.config_size for i in range(game_info.config_size)] for moves in game_moves: data_moves[moves.x][moves.y] = str(moves.users_id) # Check if the field is available if data_moves[data['i']][data['j']]: raise Exception('This field is not available.') data_moves[data['i']][data['j']] = str(user_id) # Save move await games.save_move(user_id, game_id, data['i'], data['j']) # Check game for winner winner_id = await check_for_winner(data_moves) # Draw if game_info.config_size**2 == (len(game_moves) + 1) and not winner_id: winner_id = DRAW # if we find winner or draw -> game is end. if winner_id: await games.finish_game(game_id, winner_id) # if user alone in game and make move next_user_id = -1 if len(game_users) == PLAYERS_IN_GAME: next_user_id = next(user.id for user in game_users if user.id != user_id) context = { 'status': STATUS['OK'], 'winner_id': winner_id, 'next_user_id': next_user_id, 'current_user_id': user_id, 'i': data['i'], 'j': data['j'], 'message': '{} made choice'.format(user_id) } except Exception as e: print(str(e)) context = { 'status': STATUS['ERROR'], 'message': str(e) } for _ws in opened_ws: _ws.send_str(json.dumps(context)) elif msg.tp == MsgType.error: log.debug('ws connection closed with exception {}'.format(ws.exception())) opened_ws.remove(ws) for _ws in opened_ws: _ws.send_str(json.dumps({'message': '{} disconected'.format(user_id), 'status': STATUS['INFO']})) log.debug('websocket connection closed') return ws