예제 #1
0
class Player():
    def __init__(self, player_name, counter, player_id):
        self.player_name = player_name
        self.player_id = player_id
        self.counter = counter
        self.buyin_time = 1
        self.active = False
        self.ready = False
        self.pool = 0
        self.hands = Deck()

    def GetStatus(self, show_hands):
        rsp = PlayerStatus()
        rsp.player_name = self.player_name
        rsp.player_id = self.player_id
        rsp.counter = self.counter
        rsp.buyin_time = self.buyin_time
        rsp.active = self.active
        rsp.ready = self.ready
        rsp.pool = self.pool
        if show_hands:
            for suit, value in self.hands.get_pokers():
                rsp.hands.append(Poker(suit=suit, value=value))
        return rsp

    def BuyIn(self, buyin):
        self.buyin_time += 1
        self.counter += buyin

    def Speak(self, target, queue):
        while True:
            #allin
            if self.counter == 0:
                return target
            #try:
            if True:
                user_name, action = queue.get()
                if user_name != self.player_name:
                    continue
                if action['action'] == 'call':
                    money = target - self.pool
                    self.counter -= money
                    self.pool += money
                    return target
                if action['action'] == 'fold':
                    self.active = False
                    return target
                if action['action'] == 'raise':
                    money = action['raise_target'] - self.pool
                    self.counter -= money
                    self.pool += money
                    return self.pool
            #except queue.Empty:
            #    self.active = False
            #    return target

    def PutBlind(self, money):
        self.counter -= money
        self.pool += money
예제 #2
0
class Room():
    def __init__(self, room_name, blind, buyin, room_id):
        self.room_name = room_name
        if isinstance(blind, int) and blind < 100:
            self.blind = blind
        else:
            raise Exception('blind must be int and small than 100')
        if isinstance(buyin, int):
            self.buyin = buyin
        else:
            raise Exception('buyin must be int')
        self.lock = Lock()
        self.room_id = room_id
        self.stage = 1  #未开局/翻牌/转牌/河牌/开牌
        self.players = []
        self.change_banker = False
        self.banker = 1
        self.speak = 0  #all speak
        self.queue = Queue()
        self.poker_engine = PokerEngine()
        self.public = Deck()
        self.players_cache = {}

    def AddPlayer(self, player_name):
        if player_name not in self.players_cache:
            player = Player(player_name, self.buyin, len(self.players) + 1)
            self.players_cache[player_name] = player
        else:
            player = self.players_cache[player_name]
        for player_in_room in self.players:
            if player_in_room.player_name == player_name:
                return False
        player.player_id = len(self.players) + 1
        player.active = False
        player.ready = False
        self.players.append(player)
        return True

    def DelPlayer(self, player_name):
        idx = -1
        for player_idx, player in enumerate(self.players):
            if player.player_name == player_name:
                idx = player_idx
        if idx == -1:
            raise Exception('can not find player {}'.format(player_name))

        self.players_cache[player_name] = self.players[idx - 1]
        del self.players[idx - 1]
        for player_idx, player in enumerate(self.players):
            player.player_id = player_idx

    def GetRoomInfo(self):
        rsp = RoomResponse()
        rsp.code = 0
        rsp.room_name = self.room_name
        rsp.room_id = self.room_id
        rsp.blind = self.blind
        rsp.buyin = self.buyin
        return rsp

    def PushAction(self, user_name, action):
        self.queue.push((user_name, action))

    def GetStatus(self, user_name):
        rsp = RoomStatus()
        rsp.stage = self.stage
        for player in self.players:
            #print('get status find player {}, id = {}'.format(player.player_name,player.player_id))
            if player.player_name == user_name or self.stage == 1:
                rsp.players.append(player.GetStatus(show_hands=True))
            else:
                rsp.players.append(player.GetStatus(show_hands=False))
        for suit, value in self.public.get_pokers():
            rsp.public.append(Poker(suit=suit, value=value))
        rsp.banker = self.banker
        rsp.speak = self.speak
        #print('get status = {}'.format(rsp))
        return rsp

    def active_player(self):
        res = 0
        for player in self.players:
            if player.ready:
                res += 1
        return res

    def find_player(self, player_name):
        for player in self.players:
            if player.player_name == player_name:
                return player

    def run(self):
        try:
            self._run()
        except:
            print(traceback.format_exc())

    def _run(self):
        target = 0
        btn = 0
        ptr = 0
        while True:
            while len(self.players) == 0:
                time.sleep(1)
            if self.stage == 1:
                while not (len(self.players) >= 2
                           and self.active_player() == len(self.players)):
                    try:
                        user_name, action = self.queue.get()
                        print('recieve action:{} {}'.format(user_name, action))
                        if action['action'] == 'quit':
                            self.DelPlayer(user_name)
                            continue
                        elif action['action'] != 'ready':
                            continue
                        player = self.find_player(user_name)
                        player.ready = True
                        print('set player {} ready'.format(player.player_name))
                    except queue.Empty:
                        for player in self.players:
                            if not player.ready:
                                self.DelPlayer(player.player_name)
                        continue
                for player in self.players:
                    if player.counter < self.blind * 2:
                        player.BuyIn(self.buyin)
                #print('begin stage 2')
                self.stage = 2
            elif self.stage == 2:
                if self.change_banker:
                    self.banker = self.next_id(self.banker)
                self.poker_engine.wash()
                #TODO:发牌和清除状态
                for player in self.players:
                    player.hands.clear()
                    player.hands.draw(self.poker_engine)
                    player.hands.draw(self.poker_engine)
                    player.active = True
                self.public.clear()
                sb_idx = self.next_id(self.banker)
                sb = self.players[sb_idx - 1]
                sb.PutBlind(self.blind)
                bb_idx = self.next_id(sb_idx)
                bb = self.players[bb_idx - 1]
                bb.PutBlind(self.blind * 2)
                ptr = self.next_id(bb_idx)
                btn = ptr
                target = self.blind * 2
                first_ptr_flag = True
                #print('ptr = {}, btn = {}'.format(ptr, btn))
                while ptr != btn or (ptr == btn and first_ptr_flag):
                    if ptr == btn and first_ptr_flag:
                        first_ptr_flag = False
                    if self.players[ptr - 1].active:
                        self.speak = ptr
                        new_target = self.players[ptr - 1].Speak(
                            target, self.queue)
                        if new_target != target:
                            target = new_target
                            btn = ptr
                    ptr = self.next_id(ptr)
                self.stage = 3
            elif self.stage == 3:
                for i in range(3):
                    self.public.draw(self.poker_engine)
                ptr = self.next_id(self.banker)
                btn = ptr
                first_ptr_flag = True
                while ptr != btn or (ptr == btn and first_ptr_flag):
                    if ptr == btn and first_ptr_flag:
                        first_ptr_flag = False
                    if self.players[ptr - 1].active:
                        self.speak = ptr
                        new_target = self.players[ptr - 1].Speak(
                            target, self.queue)
                        if new_target != target:
                            target = new_target
                            btn = ptr
                    ptr = self.next_id(ptr)
                self.stage = 4
            elif self.stage == 4:
                self.public.draw(self.poker_engine)
                ptr = self.next_id(self.banker)
                btn = ptr
                first_ptr_flag = True
                while ptr != btn or (ptr == btn and first_ptr_flag):
                    if ptr == btn and first_ptr_flag:
                        first_ptr_flag = False
                    if self.players[ptr - 1].active:
                        self.speak = ptr
                        new_target = self.players[ptr - 1].Speak(
                            target, self.queue)
                        if new_target != target:
                            target = new_target
                            btn = ptr
                    ptr = self.next_id(ptr)
                self.stage = 5
            elif self.stage == 5:
                self.public.draw(self.poker_engine)
                ptr = self.next_id(self.banker)
                btn = ptr
                first_ptr_flag = True
                while ptr != btn or (ptr == btn and first_ptr_flag):
                    if ptr == btn and first_ptr_flag:
                        first_ptr_flag = False
                    if self.players[ptr - 1].active:
                        self.speak = ptr
                        new_target = self.players[ptr - 1].Speak(
                            target, self.queue)
                        if new_target != target:
                            target = new_target
                            btn = ptr
                    ptr = self.next_id(ptr)
                self.stage = 6
            elif self.stage == 6:
                #按牌型大小排序
                winners = CalWinners(self.players, self.public)
                for idx, win_player in enumerate(winners):
                    if win_player.active:  #如果玩家没有fold
                        for lose_player_idx in range(
                                len(winners) - 1, idx - 1, -1):
                            lose_player = winners[lose_player_idx]
                            if win_player.pool >= lose_player.pool:
                                money = lose_player.pool
                            else:
                                money = win_player.pool
                            win_player.counter += money
                            lose_player.pool -= money
                            print('player {} got {} from {}'.format(
                                win_player.player_name, money,
                                lose_player.player_name))
                self.stage = 1
                self.change_banker = True
                self.speak = 0  #all speak
                for player in self.players:
                    player.ready = False

    def next_id(self, idx, times=1):
        for i in range(times):
            idx = idx + 1
            if idx > len(self.players):
                idx = 1
        return idx

    def pre_id(self, idx, times=1):
        for i in range(times):
            idx = idx - 1
            if idx < 1:
                idx = len(self.players)
        return idx