예제 #1
0
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')
예제 #2
0
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
예제 #3
0
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}
예제 #4
0
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}))   
예제 #5
0
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)
    }
예제 #6
0
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}
예제 #7
0
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