def broadcast_all(self, message): """ 系统广播 """ proto = game_pb2.CommonNotify() proto.messageId = 4 proto.sdata = message for player in self.player_dict.values(): send(NOTIFY_MSG, proto, player.session)
def execute(self, owner, event, proto=None): super(DiscardState, self).execute(owner, event, proto) if event == "discard": discard(owner, proto) else: owner.table.logger.warn("player {0} event {1} not register".format( owner.seat, event)) proto_re = game_pb2.CommonNotify() proto_re.messageId = PLAYER_MSG_RECONNECT send(NOTIFY_MSG, proto_re, owner.session)
def execute(self, owner, event, proto=None): super(PromptDrawState, self).execute(owner, event, proto) from logic.player_action import action, discard if event == "action": action(owner, proto) elif event == "discard" and owner.table.state != 'HaiDiState': discard(owner, proto) else: owner.table.logger.warn("player {0} event {1} not register".format(owner.seat, event)) proto_re = game_pb2.CommonNotify() proto_re.messageId = PLAYER_MSG_RECONNECT send(NOTIFY_MSG, proto_re, owner.session)
def send_last_card(self): # 将最后一张牌发送给客户端,按照宝牌发送 # proto_slc = game_pb2.ShowLastCardResponse() # proto_slc.last_card.card = self.last_card # for player in self.player_dict.values(): # send(SHOW_LAST_CARD,proto_slc,player.session) if 0 == self.last_card: return proto = game_pb2.CommonNotify() proto.messageId = PLAYER_MSG_KANBAO proto.idata = self.last_card proto.sdata = '' proto.seat = 0 for player in self.player_dict.values(): proto.seat = player.seat send(NOTIFY_MSG, proto, player.session)
def broadcast_change_bao(self): if not self.conf.allow_view_bao(): return False # 第一次动画不让发 if self.disable_show: self.disable_show = False return False proto = game_pb2.CommonNotify() proto.messageId = PLAYER_MSG_KANBAO if self.bao_card == 0: return proto.idata = (self.bao_card | (self.bao_card_idx << 8)) proto.sdata = '' proto.seat = 0 for player in self.player_dict.values(): if player.isTing and player.can_look_bao: proto.seat = player.seat send(NOTIFY_MSG, proto, player.session) self.replay["procedure"].append({"bao": self.bao_card})
def action(player, proto): player.table.logger.debug( ("when player do action", "prompts", player.table.player_prompts, "proto.action_id", proto.action_id)) state = player.state if proto.action_id: # 判断是否在提示列表中 if proto.action_id in player.action_dict.keys(): # 判断是否在提示列表中 player.table.logger.info( "player {0} do {1} action {2} {3} {4} {5}".format( player.seat, proto.action_id, player.action_dict[proto.action_id], PLAYER_ACTION_TYPE_WIN_DISCARD, PLAYER_ACTION_TYPE_WIN_DRAW, player.action_dict[proto.action_id]["prompt"], player.table.win_seat_prompt)) if player.seat in player.table.win_seat_prompt and player.action_dict[proto.action_id]["prompt"]\ in [PLAYER_ACTION_TYPE_WIN_DISCARD, PLAYER_ACTION_TYPE_WIN_DRAW]: player.table.win_seat_action.append(player.seat) player.action(proto.action_id) else: proto_re = game_pb2.CommonNotify() proto_re.messageId = PLAYER_MSG_RECONNECT send(NOTIFY_MSG, proto_re, player.session) player.table.logger.warn("player {0} do {1} not illegal".format( player.seat, proto.action_id)) return else: player.table.logger.info("player {0} pass".format(player.seat)) # 只要点过则未更换手牌之前不能胡任何牌, 如果提示操作里面没有胡则不清除胡牌提示 #if PLAYER_ACTION_TYPE_WIN_DRAW <= max([i["prompt"] for i in player.action_dict.values()]): #player.cards_ready_hand = [] player.del_prompt() if player.seat in player.table.win_seat_prompt: player.table.win_seat_prompt.remove(player.seat) # from state.player_state.wait import WaitState # 海底捞月特殊 if player.table.state != "HaiDiState": # 杠之后有上听提示但是选择过,这里不要走next_state会在is_all_players_do_action走, # 也不能像自摸点过直接清除提示,因为之后的抓牌可能有新的提示,如果清理则又出现问题 if state != "PromptTingKongState": player.machine.next_state() if state == 'PromptDrawState' and not proto.action_id and player.table.state != "HaiDiState": # if player.state == "DiscardState": # 玩家处于自摸点过出牌状态 player.table.clear_prompt() else: # 玩家处于其他玩家出牌提示状态 player.table.player_actions.append(player.uuid) # 将低优先级的玩家直接过掉 for player_id in player.table.player_prompts: if player_id == player.uuid: continue p = player.table.player_dict[player_id] # 只有在其他玩家没做出选择才可以直接pass, 但是不能重复pass if p.highest_prompt_weight() < player.action_weight and p.action_id == 0 and \ p.uuid not in player.table.player_actions: player.table.logger.info("player {0} auto pass".format(p.seat)) p.del_prompt() if p.table.state != "HaiDiState": p.machine.next_state() player.table.player_actions.append(p.uuid) next_seat = player.next_seat if player.action_weight == PLAYER_ACTION_TYPE_WIN_DISCARD and p.uuid not in player.table.player_actions: # print player.table.discard_seat count = 0 while next_seat != player.table.discard_seat: next_p = player.table.seat_dict[next_seat] if next_p.highest_prompt_weight( ) == PLAYER_ACTION_TYPE_WIN_DISCARD: next_p.del_prompt() if next_p.uuid not in player.table.player_actions: player.table.player_actions.append(next_p.uuid) next_seat = next_p.next_seat count += 1 if count >= 10: break # 单独为海底捞月添加 if player.action_weight == PLAYER_ACTION_TYPE_WIN_DRAW and len( player.table.player_prompts) > 1: def seat_order(seat): return (seat - player.table.seat_dict[ player.table.haidi_pre_seat].next_seat + player.table.conf.chairs) % player.table.conf.chairs for p in player.table.seat_dict.values(): if p.uuid not in player.table.player_prompts: continue if p.uuid in player.table.player_actions: continue if seat_order(p.seat) > seat_order(player.seat): p.del_prompt() # p.machine.next_state() player.table.player_actions.append(p.uuid) if len(player.table.player_actions) != len( player.table.player_prompts): return player.table.is_all_players_do_action()
def discard(player, proto): card = proto.card.card if player.has_win_cards: # 胡牌不能再更换手牌 if card != player.draw_card: proto = game_pb2.SynchroniseCardsResponse() for i in player.cards_in_hand: c = proto.card.add() c.card = i send(SYNCHRONISE_CARDS, proto, player.session) player.table.logger.warn( "player {0} has already played,can not discard {1} in hand". format(player.seat, card)) return if card not in player.cards_in_hand: # 出不存在的牌的时候同步手牌 proto = game_pb2.SynchroniseCardsResponse() for i in player.cards_in_hand: c = proto.card.add() c.card = i send(SYNCHRONISE_CARDS, proto, player.session) player.table.logger.warn( "player {0} discard {1} not exist in hand".format( player.seat, card)) return player.table.replay["procedure"].append({"discard": [player.seat, card]}) # 当玩家处于自摸提示状态下直接出牌 # if player.state == "PromptState" and player.machine.last_state.name == "DrawState": if player.state == "PromptDrawState": player.del_prompt() player.table.clear_prompt() player.machine.next_state() proto_re = game_pb2.CommonNotify() proto_re.messageId = PLAYER_MSG_RECONNECT send(NOTIFY_MSG, proto_re, player.session) player.table.logger.fatal( "{0} client send discard event without pass".format(player.uuid)) # 将出牌玩家至于当前玩家 player.table.discard_seat = player.seat player.table.last_oper_seat = player.seat # 最后操作玩家 if player.last_gang_card != 0: player.gang_pao_card = player.last_gang_card else: player.gang_pao_card = 0 player.last_gang_card = 0 player.cards_in_hand.remove(card) player.cards_discard.append(card) player.table.logger.info("player {0} discard {1}".format( player.seat, card)) player.table.active_card = card player.miss_win_cards = [] player.draw_card = 0 proto = game_pb2.DiscardResponse() proto.card.card = card proto.player = player.uuid player.table.reset_proto(DISCARD) for i in player.table.player_dict.values(): if i.uuid == player.uuid: continue i.proto.p = copy(proto) i.machine.cur_state.execute(i, "other_discard") i.proto.send() #player.ready_hand() player.table.step += 1 # player.table.check_bao_change() if player.table.player_prompts: player.machine.trigger(PauseState()) else: player.machine.next_state()