def on_askselect(self, msg): if msg['cards'] and msg['heros']: self.common_msg_process(msg) #返回的msg中third中为用户选择,forth为选择的card, #return False if self.myindex not in msg['start']: print("\r%s Selecting..." % self.person_instance[msg['start'][0]].name, end='') return True self.person_instance[self.myindex].cards_to_sel = msg['forth'] self.update() res = self.input_withtimeout(msg['third'], str) if res is None: self.person_instance[self.myindex].cards_to_sel = [] msg['third'] = False return Rooms.base.base.send_map_str(self.socket, msg) #或者是出牌 cards, ends = self.str2playcard(res, msg['fifth'], msg['end']) msg_p = Message.form_playcard(self.myindex, msg['heros'], msg['cards'], [self.myindex], ends, cards, reply=False) #通知所有人谁向谁出了牌 self.person_instance[self.myindex].cards_to_sel = [] return Rooms.base.base.send_map_str(self.socket, msg_p)
def on_pickhero(self): #2 Config.HerosforSelect = min( int(len(Persons.class_list) / len(self.socket_list)), Config.HerosforSelect) Config.HerosforSelect = max(Config.HerosforSelect, 1) #这里防止可选英雄太少,导致错误,如果每人一个都还少那就没办法了 cnt_ned = len(self.socket_list) * Config.HerosforSelect hero_list = random.sample(list(range(len(Persons.class_list))), cnt_ned) #这里每个人信息不同,需要单独处理 for ind, i in enumerate(self.socket_list): msg = Message.form_pickhero( ind, hero_list[ind * Config.HerosforSelect:(ind + 1) * Config.HerosforSelect], reply=True) self.send_map_str(i, msg) ret = self.send_recv_onebyone(self.socket_list, [Message.msg_types[11]]) for ind, i in enumerate(ret): if i and i['heros'] and ( i['heros'][0] in hero_list[ind * Config.HerosforSelect:(ind + 1) * Config.HerosforSelect]): self.heros_list[ind] = i['heros'][0] else: self.heros_list[ind] = hero_list[ind * Config.HerosforSelect] self.heros_instance[ind] = Persons.class_list[ self.heros_list[ind]](self, ind) print('Player ', ind, ' select ', self.heros_instance[ind].name)
def on_roundend_dropcard(self, msg): if msg['cards'] and msg['heros']: self.common_msg_process(msg) ''' dropedcards=[self.cards[x] for x in msg['third']] self.cards=[self.cards[x] for x in range(len(self.cards)) if (x not in msg['third'])] self.room.drop_cards(dropedcards) ''' st = msg['start'][0] dcnt = msg['third'][0] if st != self.myindex: print("\r%s Droping %2d Cards..." % (self.person_instance[st].name, dcnt), end='') return True res = self.input_withtimeout('回合结束,请弃%d张牌:' % dcnt, str) if not res: msg = Message.form_askselect(self.myindex, msg['heros'], msg['cards'], [self.myindex], None, None, [], select_cnt=0, reply=False) return Rooms.base.base.send_map_str(self.socket, msg) cards, ends = self.str2playcard(res, dcnt) msg['start'] = [self.myindex] msg['end'] = None msg['third'] = cards msg['reply'] = False return Rooms.base.base.send_map_str(self.socket, msg)
def on_gameinited(self): #3 #初始时游戏信息 for i in self.heros_instance: i.addcard(self.get_cards(Config.Cardsforinit)) msg = Message.form_gameinited(0, 0, 0, 0, reply=False) self.send_msg_to_all(msg)
def send_heartbeat_to_all(self, reply=False): msg = Message.form_heartbeat(reply=reply) res = self.send_msg_to_all(msg) if reply: ret = self.send_recv_onebyone(self.socket_list, [Message.msg_types[0]]) for ind, i in enumerate(ret): if not ret: print('Player %2d droped' % ind)
def listen_distribute(self, msgwant=[]): self.function_table = Message.make_msg2fun(self) while self.msg_queue: name = self.msg_queue[0]['msg_name'] if msgwant and name not in msgwant: self.msg_queue.pop(0) else: return self.function_table[name](self.msg_queue.pop(0)) msg_list = self.room.send_recv(self.mysocket) if not msg_list: return msg_list self.msg_queue.extend(msg_list) return self.listen_distribute(msgwant)
def check_con(self, c_sock): ''' :向客户端发送心跳包,等待回复,确认连接 ''' msg = Message.form_heartbeat(reply=True) if not Rooms_base.base.send_map_str(c_sock, msg): return False try: tmsg = c_sock.recv(Config.BuffSize) if not tmsg: return False except socket.timeout: print('detected timeout') return False except: print('unexpected error') return False return True
def roundend(self): if len(self.cards) > self.health: #启动弃牌 dropcnt = len(self.cards) - self.health msg = Message.form_roundend_dropcard(0, 0, 0, [self.playerid], [dropcnt], self.cards, reply=False) self.room.send_msg_to_all(msg, replylist=[self.playerid]) if not self.listen_distribute( [Message.msg_types[13], Message.msg_types[14]]): dropedcards = self.cards[:dropcnt] self.dropcard(dropedcards) self.round_status = False return True
def on_getcard(self, cnt, end, start=None, public=False, reply=False): if not start: cards_tep = self.get_cards(cnt) else: cnt = min(cnt, len(self.heros_instance[start].cards)) sel = random.sample(range(len(self.heros_instance[start].cards)), cnt) cards_tep = [self.heros_instance[start].cards[j] for j in sel] self.heros_instance[start].cards = [ self.heros_instance[start].cards[i] for i in range(len(self.heros_instance[start].cards)) if (i not in sel) ] for ind, i in enumerate(self.socket_list): tep = [None] * cnt if public or ind == end: tep = cards_tep heros = [[ self.heros_list[x], self.heros_instance[x].health if self.heros_instance[x] else None ] for x in range(len(self.heros_list))] cards = [ x.all_the_cards_holders() if x else None for x in self.heros_instance ] for inj, j in enumerate(cards): if j and ind != inj: j[0] = [None] * len(j[0]) msg = Message.form_getcard(ind, heros, cards, [end], ([start] if start else None), tep, reply=((ind == end) and reply)) self.send_map_str(i, msg) self.heros_instance[end].addcard(cards_tep)
def playcard(self, cardtoselect, selectcnt=1, inform='出牌阶段', end=None, endnum=[1], active=True, go_on=True): #告诉所有人谁正在选牌出,其中end为None表示由玩家选择目标,目标合理性判断由牌+玩家决定;如果有list,则目标必须在end的list中 #active表示是否是先手方,或者是被动出牌 endnum仅参考,给出目标的上限数目 self.cards_may_play = cardtoselect self.cards_num_play = selectcnt self.cards_inform = inform self.cards_end_may = end self.cards_end_num = endnum #这里发动装备 if active: if not self.init_playcards(): return False #myid, myheroid, mycards, start, end, informmsg, cardstoselect, select_cnt=1, reply=True msg=Message.form_askselect(0, 0, 0, [self.playerid], self.cards_end_may, \ self.cards_inform, self.cards_may_play, select_cnt=self.cards_num_play, reply=False) self.room.send_msg_to_all(msg, replylist=[self.playerid]) #################### msg = self.listen_distribute( [Message.msg_types[1], Message.msg_types[14]]) if not msg: return False #重要处理,很多情况下这里因该收到该消息,即用户打出一张牌 cards = msg['third'] st = [self.playerid] #list(set(msg['start'])) ed = list(set(msg['end'])) if not self.judge_playcard(cards, ed): self.failer_cnt += 1 #限制出牌失败次数 if self.failer_cnt >= Config.FailerCnt: return False return self.playcard(cardtoselect, selectcnt, inform, end, endnum, active, go_on) #出牌没问题 # 既然已经出牌了,就先把牌弃掉,但是牌的信息还在,当后面添加装备时,在从弃牌堆里面删掉该牌 self.dropcard(cards) msg = Message.form_playcard(0, 0, 0, st, ed, cards, reply=False) #通知所有人谁向谁出了牌 self.room.send_msg_to_all(msg) #将控制权交给该牌 if go_on: if ed: for k in ed: for i in cards: if self.play_one_card(self.room.heros_instance[k], i, active): break else: for i in cards: if self.play_one_card(ed, i, active): break ''' if self.before_playcards(self.room.heros_instance[k], i): #只有出牌方同意 if not self.room.heros_instance[k].on_be_playcard(self, i): #被出牌方才能进行盾牌的格挡判断 continue #这后面的处理就不要考虑装备效果了, 在牌各自的处理中只处理自己的事 tesu=Cards.class_list[ i[0] ].on_be_playedto(self, self.room.heros_instance[k], i) #返回是否命中 if tesu: break #命中一次可以了 if active:#如果未命中,可以发动一些装备 if not self.after_playcards(self.room.heros_instance[k], i): break ''' #不管如何应对,这里出牌是成功的 return [cards, ed]
def roundend(self, startid): #6 msg = Message.form_roundend(None, None, None, startid, reply=False) self.send_msg_to_all(msg) self.heros_instance[startid].roundend()
def on_gameend(self): msg = Message.form_gameend(0) self.send_msg_to_all(msg)
def on_gamestart(self): #1 msg = Message.form_gamestart(0) print(msg) self.send_msg_to_all(msg)
def inform_all(self, sock_list, message): msg = Message.form_inform_beforegame(message, reply=False) for i in sock_list: Rooms_base.base.send_map_str(i, msg)