Ejemplo n.º 1
0
    def join_game(cls, uid, game_id):
        result = ApiResult.get_inst()
        actor = Actor.objects(id=uid).first()

        if not actor:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        game_info = LudoHelper.get_game(game_id)
        if actor.gold < game_info['gold']:
            return result.error(errorCode.GOLD_NOT_ENOUGH)

        if game_info['status'] > config.LUDO_READY:
            return result.error(errorCode.GAME_IS_RUNNING)

        if len(game_info['uids']) >= game_info['max_numbers']:
            return result.error(errorCode.REACH_MAX_PLAYER)

        update_dict = dict()
        # 要进行加锁
        with DistributedLock("ludo_game_{}".format(game_id), timeout=1, ex=30, slp=0.1) as lock:
            Player.init(uid, game_id)

            update_dict['uids'] = game_info['uids'].append(uid)
            update_dict['status'] = config.LUDO_READY
            game = LudoHelper.update_game(game_id, **update_dict)

        player_dict = dict()
        for p in game['uids']:
            player_info = Player.get_player_info(p, game_id)
            player_dict[p] = player_info

        log.debug("uid: %s, game_id: %s, game_info: %s, player_dict: %s", uid, game_id, game, player_dict)
        uid_list = game['uids']
        cls.broadcast_to_uids(uid_list.pop(uid), data={"game_info":game, "players_info": player_dict})
        return result.success(data={"game_info":game, "players_info": player_dict})
Ejemplo n.º 2
0
    def strike_handle(cls, location, uid, game_id):
        """
        判断是否撞机
        :return:
        """
        game_info = LudoHelper.get_game(game_id)
        if not game_info:
            log.error("judge_strike, game not exist !!!!!, game_id: %s", game_id)
            return False

        if location in config.SAFE_PLACE:
            return False

        for p in game_info['uids']:
            if p == uid:
                continue

            player_info = Player.get_player_info(p, game_id)
            location_list = cls.get_user_locations(player_info)
            if location in location_list:
                index = location.index(location)
                update = dict()
                update[config.PLANE_NAME[index+1]] = 0
                Player.update_info(p, game_id, **update)
                return True

        return False
Ejemplo n.º 3
0
 def reset_game(cls, uid, game_id, win_gold):
     """
     重新设置游戏信息
     :param uid:
     :param game_id:
     :return:
     """
     game_info = LudoHelper.update_game(game_id, winner=uid, win_gold=win_gold, status=config.LUDO_END)
     return game_info
Ejemplo n.º 4
0
    def start_game(cls, uid, game_id):
        """
        开始游戏
        :param uid:
        :param game_id:
        :return:
        """
        result = ApiResult.get_inst()

        game_info = LudoHelper.get_game(game_id)
        if not game_info:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        if uid not in game_info['uids']:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        if game_info['creator'] != uid:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        numbers = game_info['max_numbers']
        if len(game_info['uids']) < numbers:
            return result.error(errorCode.PLAYER_NOT_ENOUGH)

        if game_info['status'] != config.LUDO_READY:
            return result.error(errorCode.PLAYER_NOT_READY)

        with DistributedLock("ludo_game_{}".format(game_id), timeout=1, ex=30, slp=0.1) as lock:
            update_dict = dict()
            update_dict['status'] = config.LUDO_RUN
            update_dict['current_player'] = uid
            game = LudoHelper.update_game(game_id, **update_dict)

        player_dict = dict()
        for p in game['uids']:
            # todo 看情况是否要进行异步
            tools.change_gold(p, -game_info['gold'])
            player_info = Player.get_player_info(p, game_id)
            player_dict[p] = player_info

        log.debug("uid: %s, game_id: %s, game: %s", uid, game_id, game)
        uid_list = game['uids']
        cls.broadcast_to_uids(uid_list.pop(uid), data={"game_info":game, "players_info": player_dict})
        log.debug("uid: %s, game_id: %s, game_info: %s, player_dict: %s", uid, game_id, game_info, player_dict)
        return result.success(data={"game_info":game, "players_info": player_dict})
Ejemplo n.º 5
0
    def create_game(cls, uid, numbers, type, cost_gold):
        """
        创建游戏
        :return:
        """
        result = ApiResult.get_inst()
        actor = Actor.objects(id=uid).first()
        if not actor:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        left_gold = actor.gold
        if left_gold < cost_gold:
            return result.error(errorCode.GOLD_NOT_ENOUGH)

        # 生成game_id
        game_id = LudoHelper.gen_game_id()
        if not game_id:
            return result.error(errorCode.FAIL_GEN_ID)

        game_dict = dict(
            g_room='',
            game_id=game_id,
            uids=[uid],
            max_numbers=numbers,
            gold=cost_gold,
            status=config.LUDO_CREATE,
            current_player="",
            creator=uid,
            winner="",
            win_gold=0,
        )

        # 设置玩家初始信息
        Player.init(uid, game_id)
        # 设置棋桌信息
        LudoHelper.set_game(game_id, **game_dict)
        player_info = Player.get_player_info(uid, game_id)
        player_dict = dict()
        player_dict[uid] = player_info
        log.debug("uid: %s, game_id: %s, player_dict: %s", uid, game_id, player_dict)

        # 在sorted_set中记录
        GameSet.create(numbers, game_id)
        return result.success(data={"game_info":game_dict, "players_info": player_dict})
Ejemplo n.º 6
0
    def delete_game(cls, uid, game_id):
        result = ApiResult.get_inst()

        game_info = LudoHelper.get_game(game_id)
        if not game_info:
            return result.error(errorCode.GAME_NOT_EXIST)

        if uid != game_info['creator']:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        if game_info['status'] not in [config.LUDO_CREATE, config.LUDO_END]:
            return result.error(errorCode.CODE_PARAMETER_ERR, msg="can not delete game")

        for p in game_info['uids']:
            Player.del_info(p, game_id)
            if p == uid:
                continue

            cls.broadcast(p, data={'msg': 'The game has been delete'})

        LudoHelper.del_game(game_id)
        GameSet.delete(game_info['max_numbers'], game_id)

        return result.success()
Ejemplo n.º 7
0
    def get_game_info(cls, uid, game_id):
        result = ApiResult.get_inst()

        game_info = LudoHelper.get_game(game_id)
        if not game_info:
            return result.success()

        if uid not in game_info['uids']:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        player_dict = dict()
        for p in game_info.uids:
            player_info = Player.get_player_info(p, game_id)
            if not player_info:
                continue

            player_dict[p] = player_info

        log.debug("uid: %s, game_id: %s, game_info: %s, player_dict: %s", uid, game_id, game_info, player_dict)

        return result.success(data={"game_info": game_info, "players_info": player_dict})
Ejemplo n.º 8
0
    def move_plane(cls, uid, game_id, plane_num):
        """
        移动飞机
        :param uid:
        :param game_id:
        :param plane_num:移动第几架飞机
        :return:
        """
        result = ApiResult.get_inst()
        game_info = LudoHelper.get_game(game_id)

        if not game_info:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        if uid not in game_info['uids']:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        if game_info['current_player'] != uid:  # 不是当前操作者
            return result.error(errorCode.CURRENT_PLAYER_ERROR)

        if game_info['status'] != config.LUDO_RUN:
            return result.error(errorCode.CURRENT_PLAYER_ERROR)

        player_info = Player.get_player_info(uid, game_id)
        if not player_info:
            return result.error(errorCode.CURRENT_PLAYER_ERROR)

        # 计算移动的步数
        steps = cls.count_steps(plane_num, player_info)
        if not steps:  # 扔色子过程已经计算过有无飞机可以移动
            return result.error(errorCode.PLANE_MOVE_ERROR)

        else:
            dice_num = player_info['current_dice_num']

            update_dict = dict()
            name = config.PLANE_NAME.get(plane_num)
            plane_sum_steps = player_info[name] + steps
            # 判断飞机是否到达终点
            if plane_sum_steps == config.MAX_SUM_STEPS:
                update_dict['plane_on_des'] = config.PLANE_ON_DES

            update_dict[name] = plane_sum_steps
            update_dict['current_dice_num'] = 0

            if dice_num == 6:
                update_dict['history'] = player_info['history'].append({'step':steps, 'name':name})

            # 撞机处理
            location = cls.get_location(player_info['seat_id'], plane_sum_steps)
            flag = cls.strike_handle(location, uid, game_id)
            if flag:
                update_dict['is_dislodge'] = config.SUCCESS_DISLODGE

            p_info = Player.update_info(uid, game_id, **update_dict)

            win = cls.is_win(p_info)
            if win:
                # 游戏结束
                game_info = cls.game_over(uid, game_info)

            else:
                next_uid = cls.get_next_uid(uid, game_info)
                game_info = LudoHelper.update_game(game_id, current_player=next_uid)

        player_dict = dict()
        for p in game_info['uids']:
            player_dict[p] = Player.get_player_info(uid, game_id)

        log.debug("uid: %s, game_id: %s, player_dict: %s, game_info: %s", uid, game_id, player_dict, game_info)
        uid_list = game_info['uids']
        cls.broadcast_to_uids(uid_list.pop(uid), data={"game_info":game_info, "players_info": player_dict})
        return result.success(data={"game_info":game_info, "players_info": player_dict})
Ejemplo n.º 9
0
    def throw_dice(cls, uid, game_id):
        """
        扔色子
        :param uid:
        :param game_id:
        :return:
        """
        result = ApiResult.get_inst()
        game_info = LudoHelper.get_game(game_id)

        if uid not in game_info['uids']:
            return result.error(errorCode.CODE_PARAMETER_ERR)

        if uid != game_info['current_player']:
            return result.error(errorCode.CURRENT_PLAYER_ERROR)

        if game_info['status'] != config.LUDO_RUN:
            return result.error(errorCode.CURRENT_PLAYER_ERROR)

        player_info = Player.get_player_info(uid, game_id)
        if not player_info:
            return result.error(errorCode.CURRENT_PLAYER_ERROR)

        dice_num = random.randint(1, 6)
        can_flys = cls.count_flys(dice_num, player_info)

        if not can_flys:
            if dice_num != config.MAX_DICE_NUM:
                next_uid = cls.get_next_uid(uid, game_info)
                game_info = LudoHelper.update_game(game_id, current_player=next_uid)
                Player.update_info(uid, game_id, current_dice_num=dice_num, history=[], can_flys=[])

            else:
                flag = cls.judge_recall(player_info, game_info)
                if flag:
                    cls.recall_player(player_info, game_id)
                    # 变为下一个玩家操作
                    next_uid = cls.get_next_uid(uid, game_info)
                    game_info = LudoHelper.update_game(game_id, current_player=next_uid)
                    Player.update_info(uid, game_id, can_flys=[])

                else:
                    # 客户端根据当前操作者和可以移动的飞机2项判断是扔色子还是移动飞机
                    history = player_info['history'].append({'step':0, 'name':'plane_first_steps'})
                    Player.update_info(uid, game_id, current_dice_num=dice_num, history=history ,can_flys=[])

        else:
            if dice_num == config.MAX_DICE_NUM:
                flag = cls.judge_recall(player_info, game_info)
                if flag:
                    cls.recall_player(player_info, game_id)
                    # 变为下一个玩家操作
                    next_uid = cls.get_next_uid(uid, game_info)
                    game_info = LudoHelper.update_game(game_id, current_player=next_uid)
                    Player.update_info(uid, game_id, history=[], can_flys=[])

                else:
                    Player.update_info(uid, game_id, current_dice_num=dice_num, history=[], can_flys=can_flys)

            else:
                Player.update_info(uid, game_id, current_dice_num=dice_num, history=[], can_flys=can_flys)

        player_dict = dict()
        for p in game_info['uids']:
            player_dict[p] = Player.get_player_info(p, game_id)

        uid_list = game_info['uids']
        cls.broadcast_to_uids(uid_list.pop(uid), data={"game_info":game_info, "players_info": player_dict})
        log.debug("uid: %s, game_id: %s, game_info: %s, player_dict: %s", uid, game_id, game_info, player_dict)
        return result.success(data={"game_info":game_info, "players_info": player_dict})