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
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})
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})
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})
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()
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})
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})