diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 0000000..9178b38 --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/poker/Bank.py b/poker/Bank.py new file mode 100644 index 0000000..6c44648 --- /dev/null +++ b/poker/Bank.py @@ -0,0 +1,23 @@ +__author__ = 'nk-karpov' + + +class Bank: + __set_of_player = set() + __many = 0 + def __init__(self): + self.__set_of_player = set() + self.__many = 0 + + def many(self): + return self.__many + + def set_of_player(self): + return self.__set_of_player + + def add_bet(self, name, value): + self.__many += value + if name not in self.__set_of_player: + self.__set_of_player = self.__set_of_player | {name} + + def del_player(self, name): + self.__set_of_player.remove(name) diff --git a/poker/Bot.py b/poker/Bot.py new file mode 100644 index 0000000..1e032dd --- /dev/null +++ b/poker/Bot.py @@ -0,0 +1,271 @@ +__author__ = 'nk-karpov' + +from Player import * +from Utils import * +from PlayerInfo import * +from PyQt4.QtCore import * +#from TableInfo import * + + +class Bot(Player): + __player_info = None + __table_info = None + big_blind = 0 + small_blind = 0 + bet = 0 + blind = 0 + def __init__(self, player_info, table_info): + self.__player_info = player_info + self.__table_info = table_info + Player.__init__(self, player_info, table_info) + init() + +# def player_info(self): +# return self.__player_info +# def count_raise(self): +# log_turn = table_info.turns() +# result = 0 +# for turn in table: +# if turn.verdict == 'raise': +# result += 1 +# return result + def btc(self, hand_mask, enemy_mask, open_mask): +# print bit_count(hand_mask) == bit_count(enemy_mask), 5 - bit_count(open_mask), + assert bit_count(hand_mask) == bit_count(enemy_mask) + num_rem_cards = 5 - bit_count(open_mask) + if num_rem_cards == 0: +# for card in get_list_cards_from_mask(open_mask): +# card.__print__() + tmp = cmp_hand(get_list_cards_from_mask(hand_mask | open_mask), + get_list_cards_from_mask(enemy_mask | open_mask)) + if tmp == -1: + return 1. + else: + return 0. + total_mask = hand_mask | enemy_mask | open_mask + result = 0. + for i in xrange(len(suits) * len(values)): + if (total_mask >> i) & 1 == 1: + continue + result += self.btc(hand_mask, enemy_mask, open_mask | (1 << i)) + result /= len(suits) * len(values) - bit_count(total_mask) + return result + + def turn_preflop(self, value): +# count_raise = self.count_raise() + count_raise = value > 100 +# position = self.table_info.get_position(self.store.name()) + position = 1 + mask = get_mask_of_cards(self.__player_info.hand_cards()) + aa = bit_count(mask & value_masks['a']) == 2 + kk = bit_count(mask & value_masks['k']) == 2 + qq = bit_count(mask & value_masks['q']) == 2 + ak = bit_count(mask & (value_masks['a'] | value_masks['k'])) == 2 + jj = bit_count(mask & value_masks['j']) == 2 + tt = bit_count(mask & value_masks['10']) == 2 +# for _value in values: +# print value_masks[_value], +# print +# for _value in values: +# print _value, value_masks[_value], mask, value_masks[_value] & mask +# print aa, kk, qq, ak, jj, tt +# print "value =", value, ", ante =", self.__player_info.ante() + if aa | kk: + if count_raise == 0: + return self.__raise__(self.blind * 4 + value) + elif count_raise == 1: + return self.__raise__(self.blind * 4 + value) + else: + return self.__allin__(self.__player_info.many()) + if qq: + + if count_raise == 0: + return self.__raise__(self.blind * 4 + value) + elif count_raise == 1: + return self.__raise__(self.blind * 4 + value) + else: + return self.__check_or_call__(value) + if ak: + if count_raise == 0: + return self.__raise__(self.blind * 4 + value) + elif count_raise == 1: + return self.__check_or_call__(value) + else: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + if jj | tt: + print "jack or ten" + if count_raise == 0: + if 2 <= position and position <= 5: + return self.__check_or_call__(value) + else: + return self.__raise__(self.blind * 4 + value) + else: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + + for _value in values: + if bit_count(mask & value_masks[_value]): + print "go" + if count_raise == 0: + self.__check_or_call__(value) + else: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + if bit_count(mask & value_masks['a']) == 1 and bit_count(mask & value_masks['q']) == 1: + if count_raise == 0: + if False: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + else: + return self.__raise__(4 * self.blind + value) + else: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + + if bit_count(mask & value_masks['a']) == 1 and bit_count(mask & value_masks['j']): + if count_raise == 0: + if False: #TODO + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + else: + return self.__raise__(4 * self.blind + value) + else: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + + if bit_count(mask & value_masks['k']) == 1 and bit_count(mask & value_masks['q']) == 1: + if count_raise == 0: + if False: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + else: + return self.__raise__(4 * self.blind + value) + else: + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + if self.__player_info.ante() < value: + return self.__fold__() + else: + return self.__check_or_call__(value) + + def turn_flop(self, value): + return self.__check_or_call__(value) + total = len(suits) * len(values) + mult = 2. / (total - 5) / (total - 6) + hand_mask = get_mask_of_cards(self.__player_info.hand_cards()) + opened_mask = get_mask_of_cards(self.__table_info.opened_cards()) + probablity = 0. + assert bit_count(hand_mask) == 2 + for i in xrange(52): + if hand_mask & (1 << i) != 0 or opened_mask & (1 << i) != 0: + continue + for j in xrange(i): + if hand_mask & (1 << j) != 0 or opened_mask & (1 << j) != 0: + continue + enemy_mask = (1 << i) | (1 << j) + probablity += self.btc(hand_mask, enemy_mask, opened_mask) + probablity *= mult + if probablity > 0.75: + return self.__raise__(self.blind * 4 + value) + elif probablity > 0.25: + return self.__check_or_call__(value) + else: + if value > self.__player_info.ante(): + return self.__fold__() + else: + return self.__check_or_call__(value) + + def turn_turn(self, value): + return self.__check_or_call__(value) + total = len(suits) * len(values) + mult = 2. / (total - 6) / (total - 7) + hand_mask = get_mask_of_cards(self.__player_info.hand_cards()) + opened_mask = get_mask_of_cards(self.__table_info.opened_cards()) + probability = 0. + for i in xrange(52): + if hand_mask & (1 << i) != 0 or opened_mask & (1 << i) != 0: + continue + for j in xrange(i): + if hand_mask & (1 << j) != 0 or opened_mask & (1 << j) != 0: + continue + enemy_mask = (1 << i) | (1 << j) + probability += self.btc(hand_mask, enemy_mask, opened_mask) + probability *= mult + if probability > 0.75: + return self.__raise__(self.blind * 4 + value) + elif probability > 0.25: + return self.__check_or_call__(value) + else: + if value > self.bet: + return self.__fold__() + else: + self.bet = value + return self.__check_or_call__(value) + + def turn_river(self, value): +# return self.__check_or_call__(value) + total = len(suits) * len(values) + mult = 2. / (total - 7) / (total - 8) + hand_mask = get_mask_of_cards(self.__player_info.hand_cards()) + opened_mask = get_mask_of_cards(self.__table_info.opened_cards()) + probability = 0. + for i in xrange(52): + if hand_mask & (1 << i) != 0 or opened_mask & (1 << i) != 0: + continue + for j in xrange(i): + if hand_mask & (1 << j) != 0 or opened_mask & (1 << j) != 0: + continue + enemy_mask = (1 << i) | (1 << j) + probability += self.btc(hand_mask, enemy_mask, opened_mask) + probability *= mult + if probability > 0.75: + return self.__raise__(self.blind * 4 + value) + elif probability > 0.25: + return self.__check_or_call__(value) + else: + if value > self.__player_info.ante(): + return self.__fold__() + else: + return self.__check_or_call__(value) + + def turn(self, value, blind, func_to_call): + self.blind = blind + number_cards_on_table = len(self.__table_info.opened_cards()) + if number_cards_on_table == 0: + print "PREFLOP" + turn_res = self.turn_preflop(value) + elif number_cards_on_table == 3: + print "FLOP" + turn_res = self.turn_flop(value) + elif number_cards_on_table == 4: + print "TURN" + turn_res = self.turn_turn(value) + print "END TURN" + elif number_cards_on_table == 5: + print "RIVER" + turn_res = self.turn_river(value) + turn_res.verdict() + QTimer.singleShot(1000, lambda : func_to_call(turn_res)) + # func_to_call(turn_res) + +# def add_message(self, message): +# self.store.add_message(message) diff --git a/poker/Card.py b/poker/Card.py new file mode 100644 index 0000000..57d04eb --- /dev/null +++ b/poker/Card.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +__author__ = 'anlun' + +class Card: + def __init__(self, suit, value): + self.__suit = suit + self.__value = value + def __print__(self): + print "(", self.__suit, ",", self.__value, ")" + def suit(self): + return self.__suit + + def value(self): + return self.__value + + def image_path(self): + return "images/cards/%s/%s.jpg" % (self.__suit, self.__value) + + def jacket_image_path(self): + return "images/cards/d.jpg" diff --git a/poker/Player.py b/poker/Player.py new file mode 100644 index 0000000..4b879d5 --- /dev/null +++ b/poker/Player.py @@ -0,0 +1,53 @@ +__author__ = 'nk-karpov' + +#from TableInfo import * +from Turn import * +from PyQt4.QtCore import * + +class Player: + def __init__(self, player_info, table_info): + self.__player_info = player_info + self.__table_info = table_info + + def player_info(self): + return self.__player_info + + def __check_or_call__(self, value): + assert value >= self.player_info().ante() + if value >= self.__player_info.many(): + return self.__allin__() + return Turn('check or call', value) + + def __fold__(self): + return Turn('fold', 0) + + def __raise__(self, value): + if value <= self.__player_info.ante(): + return self.__check_or_call__(self.__player_info.ante()) + if value >= self.__player_info.many(): + return self.__allin__() + return Turn('raise', value) + + def __allin__(self): + self.player_info().set_is_allin(True) + return Turn('allin', self.__player_info.many() + self.__player_info.ante()) + + def is_people_player(self): + return False + + def turn(self, value, blind, func_to_call): + raise NotImplementedError() + +class PeoplePlayer(Player): + def __init__(self, player_info, table_info, decision_block): + Player.__init__(self, player_info, table_info) + self.__decision_block = decision_block + + def is_people_player(self): + return True + + def turn(self, value, blind, func_to_call): + # activate buttons + print "gamer!!!" + self.__decision_block.activate(value, blind, self, func_to_call) + # self.__decision_block.activate(value, blind, None) \ No newline at end of file diff --git a/poker/PlayerInfo.py b/poker/PlayerInfo.py new file mode 100644 index 0000000..c11a79e --- /dev/null +++ b/poker/PlayerInfo.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- + +from Card import Card + +__author__ = 'anlun' + +class PlayerInfo(): + # TODO: add is_allined + # and in Table!!!! + def set_is_allin(self, value): + self.__allin = value + + def is_allin(self): + return self.__is_allin + + def set_is_make_turn(self, value): + self.__is_make_turn = value + + def is_make_turn(self): + return self.__is_make_turn + + def __init__(self, name, hand_cards = [], many = 0, blind = 0, ante = 0, is_hand_hidden = False): + self.__name = name + self.__hand_cards = hand_cards + self.__many = many + self.__blind = blind + self.__ante = ante + self.__is_hand_hidden = is_hand_hidden + + self.__is_make_turn = False + self.__is_alive = True + self.__is_folded = False + self.__is_active = False # is player making decision right now + self.__is_allin = False + + # crl - change receive list + self.__crl_cards = [] + self.__crl_many = [] + self.__crl_blind = [] + self.__crl_ante = [] + self.__crl_active_alive = [] + + def name(self): + return self.__name + def hand_cards(self): + return self.__hand_cards + def many(self): + return self.__many + def blind(self): + return self.__blind + def ante(self): + return self.__ante + def is_hand_hidden(self): + return self.__is_hand_hidden + + def is_alive(self): + return self.__is_alive + def set_is_alive(self, is_alive): + self.__is_alive = is_alive + for cr in self.__crl_active_alive: + cr.active_alive_changed() + + def is_folded(self): + return self.__is_folded + def set_is_folded(self, is_folded): + self.__is_folded = is_folded + for cr in self.__crl_ante: + cr.ante_changed() + + def is_active(self): + return self.__is_active + def set_active(self): + self.__is_active = True + for cr in self.__crl_active_alive: + cr.active_alive_changed() + def set_unactive(self): + self.__is_active = False + for cr in self.__crl_active_alive: + cr.active_alive_changed() + + # __name is unchangable + def set_hand_cards(self, hand_cards): + self.__hand_cards = hand_cards + for cr in self.__crl_cards: + cr.hand_cards_changed() + + def set_many(self, many): + self.__many = many + for cr in self.__crl_cards: + cr.many_changed() + def change_many(self, bonus): + self.__many += bonus + for cr in self.__crl_cards: + cr.many_changed() + + def set_blind(self, blind): + self.__blind = blind + for cr in self.__crl_cards: + cr.blind_changed() + cr.ante_changed() + + def set_ante(self, ante): + self.__ante = ante + for cr in self.__crl_cards: + cr.ante_changed() + + def set_is_hand_hidden(self, is_hand_hidden): + self.__is_hand_hidden = is_hand_hidden + for cr in self.__crl_cards: + cr.hand_cards_changed() + + def add_crl_cards(self, crl_member): + self.__crl_cards.append(crl_member) + def add_crl_many(self, crl_member): + self.__crl_many.append(crl_member) + def add_crl_blind(self, crl_member): + self.__crl_blind.append(crl_member) + def add_crl_ante(self, crl_member): + self.__crl_ante.append(crl_member) + def add_crl_active_alive(self, crl_member): + self.__crl_active_alive.append(crl_member) \ No newline at end of file diff --git a/poker/Table.py b/poker/Table.py new file mode 100644 index 0000000..5826711 --- /dev/null +++ b/poker/Table.py @@ -0,0 +1,314 @@ +from Utils import * +from TableInfo import * +from Player import * +from Bot import * +from time import sleep +from TableGui import * + +import random + +class Table(QObject): + def __init__(self, table_info, table_gui): + self.__table_info = table_info + self.__table_gui = table_gui + + # self.__players = [Player(player_info, self.__table_info) for player_info in self.__table_info.players()] + self.__players = [ ( + PeoplePlayer( + self.__table_info.players()[0] + , self.__table_info + , self.__table_gui.decision_block() + ) + ) ] + self.__players += [Bot(player_info, self.__table_info) for player_info in self.__table_info.players()[1:]] + self.__player_queue = self.__players + + turn_start_player_num = random.randint(0, self.__table_info.player_count() - 1) + self.__turn_start_player_name = self.__players[turn_start_player_num].player_info().name() + + # Prepare player queue + tsp_num = self.__player_num_by_name(self.__turn_start_player_name) + self.__player_queue = self.__player_queue[tsp_num : ] + self.__player_queue[ : tsp_num] + + + def __player_num_by_name(self, name): + i = 0 + for player in self.__players: + if player.player_info().name() == name: + return i + i += 1 + + return -1 + + def __round_init(self): + round_blind = self.__round_blind() + self.__table_info.set_opened_cards([]) + + if self.__turn_start_player_name == '': + raise NotImplementedError() + + # Deal cards + self.__deck = random_shuffle(generate_deck()) + for player in self.__player_queue: + if not player.is_people_player(): + player.player_info().set_is_hand_hidden(True) + player.player_info().set_hand_cards(self.__deck[0 : 2]) + self.__deck = self.__deck[2 : ] + + # Set blinds + pl_inf_1 = self.__player_queue[0].player_info() + pl_inf_1.set_blind(1) + pl_inf_1.set_ante(round_blind / 2) + pl_inf_1.set_many(pl_inf_1.many() - round_blind / 2) + + pl_inf_2 = self.__player_queue[1].player_info() + pl_inf_2.set_blind(2) + pl_inf_2.set_ante(round_blind) + pl_inf_2.set_many(pl_inf_2.many() - round_blind) + + self.__table_info.set_bank(round_blind * 1.5) + + def __clear_round(self): + # Open cards + winers = set() + for player in self.__player_queue: + if player.player_info().is_folded(): + continue + if winers.__len__() == 0: + winers = {player} + for enemy in winers: + assert len(enemy.player_info().hand_cards()) == 2 + assert len(player.player_info().hand_cards()) == 2 + t = cmp_hand(player.player_info().hand_cards() + self.__table_info.opened_cards(), + enemy.player_info().hand_cards() + self.__table_info.opened_cards()) + if t == 0: + winers |= {player} + if t == -1: + winers = {player} + break + player.player_info().set_is_hand_hidden(False) + + assert len(winers) + bonus = int(self.__table_info.bank() / len(winers)) + for player in winers: + print 'WIN ', player.player_info().name(), '+ ', bonus + msg_box = QMessageBox() + msg_box.setText(player.player_info().name()) + msg_box.exec_() + player.player_info().change_many(bonus) + + winers = None + # Bank for winner + # TODO!!!!!! + + # Clear Bank + self.__table_info.set_bank(0) + + # Clear blinds + self.__clear_ante() + for player in self.__player_queue: + player.player_info().set_blind(0) + player.player_info().set_is_allin(False) + # Delete dead players + alive_players = [] + for player in self.__player_queue: + if player.player_info().many() > 0: + alive_players.append(player) + player.player_info().set_is_folded(False) + else: + player.player_info().set_is_alive(False) + self.__player_queue = alive_players + + # End check + if len(self.__player_queue) < 2: + msg_box = QMessageBox() + msg_box.setText('Game over') + msg_box.exec_() + + QApplication.quit() + + # Determine next tsp + if self.__player_queue[0].player_info().name() == self.__turn_start_player_name: + print self.__player_queue[0].player_info().name() + self.__player_queue = self.__player_queue[1 : ] + [ self.__player_queue[0] ] + self.__turn_start_player_name = self.__player_queue[0].player_info().name() + self.round() +# QTimer.singleShot(200, self.round) + # start new round +# self.round() + + # round + # init + # flop + # turn + # river + # clear + + def round(self): + self.__round_init() + self.__flop(self.__round_blind()) + + def __flop(self, blind): + # player for whom make_turn must be done + self.__br_visit_list = self.__player_queue[2 : ] + self.__player_queue[0 : 2] + self.__bets_and_raises(blind, 'flop') + + def __unmake_turn(self): + for player in self.__player_queue: + player.player_info().set_is_make_turn(player.player_info().is_allin()) + + def __bets_and_raises(self, cur_ante, type): + print 'bets!!!', cur_ante + if self.__br_visit_list == []: + print 'CCC' + if type == 'flop': + self.__br_visit_list = self.__player_queue[2 : ] + self.__player_queue[0 : 2] + else: + self.__br_visit_list = self.__player_queue + + self.__br_visit_list = filter(lambda x: not x.player_info().is_folded() or x.player_info().is_allin(), self.__br_visit_list) + if len(self.__br_visit_list) == 1: +# QTimer.singleShot(200, self.__clear_round) + self.__clear_round() + return + # TODO: check len of __br_visit_list + next_round = False + for player in self.__br_visit_list: + next_round = next_round or player.player_info().is_make_turn() + if next_round: + print 'DDDDD', type + # go to next type + if type == 'flop': + self.__open_flop() + return + elif type == 'turn': + self.__open_turn() + return + else: + self.__open_river() + return + + player = self.__br_visit_list[0] + self.__br_visit_list = self.__br_visit_list[1 :] + + print 'AAA', player.player_info().name(), \ + player.player_info().is_folded(), \ + player.player_info().is_make_turn() + if not player.player_info().is_folded() and not player.player_info().is_make_turn(): + # make_turn + if player.player_info().many() == 0: + player.player_info().set_is_allin(True) + if player.player_info().is_allin(): + player.player_info().set_is_make_turn(True) + if not player.player_info().is_make_turn(): + print "GO", player.player_info().name(), "!!!" + self.__make_player_turn(player, cur_ante, type) + player.player_info().set_is_make_turn(True) + else: + self.__bets_and_raises(cur_ante, type) + else: + self.__bets_and_raises(cur_ante, type) + + def __clear_ante(self): + for player in self.__player_queue: + player.player_info().set_ante(0) + + def __make_player_turn(self, player, cur_ante, type): + player.player_info().set_active() + print player.player_info().name() + + player.turn(cur_ante, self.__round_blind(), lambda turn_res : self.__player_turn_res(player, turn_res, cur_ante, type)) + + def __player_turn_res(self, player, turn_res, cur_ante, type): + verdict = turn_res.verdict() + + if verdict == 'fold': + player.player_info().set_is_folded(True) + + player.player_info().set_unactive() + + self.__bets_and_raises(cur_ante, type) + return + else: + self.__unmake_turn() + player.player_info().set_is_make_turn(True) + value = turn_res.value() + many = player.player_info().many() + ante = player.player_info().ante() + print player.player_info().name(), verdict + if verdict == 'allin': + value = max(value, cur_ante) + else: + if value < cur_ante: + player.player_info().set_is_folded(True) + player.player_info().set_unactive() + self.__bets_and_raises(cur_ante, type) + return + value = min(value, many + ante) + player.player_info().set_many(many - value + ante) + player.player_info().set_ante(value) + + self.__table_info.set_bank(self.__table_info.bank() + value - ante) + player.player_info().set_unactive() + + if verdict == 'allin': + value = max(value, cur_ante) + else: + assert value >= cur_ante +# QTimer.singleShot(200, lambda : self.__bets_and_raises(value, type)) + self.__bets_and_raises(value, type) + return + + def __open_flop(self): + self.__table_info.set_opened_cards(self.__deck[0 : 3]) + self.__deck = self.__deck[3 : ] + + self.__clear_ante() + print 'GGGGG' + self.__turn() + #QTimer.singleShot(200, self.__turn) + + def __turn(self): + print 'JJJJJ' + self.__br_visit_list = self.__player_queue + self.__unmake_turn() + self.__bets_and_raises(0, 'turn') + + def __open_turn(self): + self.__table_info.add_opened_card(self.__deck[0]) + self.__deck = self.__deck[1 : ] +# self.__river() + self.__clear_ante() + print "GO RIVER" + self.__river() +# QTimer.singleShot(200, self.__river) + + def __river(self): + self.__br_visit_list = self.__player_queue + self.__unmake_turn() + self.__bets_and_raises(0, 'river') + + def __open_river(self): + self.__table_info.add_opened_card(self.__deck[0]) + self.__deck = self.__deck[1 : ] + self.__clear_ante() + self.__clear_round() +# QTimer.singleShot(200, self.__clear_round) + + def __round_blind(self): + return 10 + + def __next_alive_player(self, player_num): + result = player_num + 1 + for player in self.__table_info.players()[player_num + 1:]: + if player.is_alive(): + return result + result += 1 + + result = 0 + for player in self.__table_info.players()[0 : player_num]: + if player.is_alive(): + return result + result += 1 + + return -1 diff --git a/poker/TableGui.py b/poker/TableGui.py new file mode 100644 index 0000000..146bbbc --- /dev/null +++ b/poker/TableGui.py @@ -0,0 +1,342 @@ +# -*- coding: utf-8 -*- + +__author__ = 'anlun' + +import sys +import math +from PyQt4.QtGui import * +from PyQt4.QtCore import * +from TableInfo import * +from PlayerInfo import * +from Table import * +from Turn import * + +from time import sleep + +class TableGui: + card_height = 70 + card_width = 50 + blind_size = 45 + + info_height = 150 + info_width = 150 + name_height = 20 + + center_x = 300 + center_y = 200 + + table_card_coef = 1.5 + + class PlayerInfoView: + def __init__(self, player_info, scene, x, y): + self.__player_info = player_info + self.__scene = scene + self.__pos = (x, y) + + self.__player_info.add_crl_cards(self) + self.__player_info.add_crl_many(self) + self.__player_info.add_crl_blind(self) + self.__player_info.add_crl_ante(self) + self.__player_info.add_crl_active_alive(self) + + self.__init_player_background() + self.__init_player_name_view() + self.__init_hand_card_view() + self.__init_many_view() + self.__init_ante_view() + self.__init_blind_view() + + def __init_player_background(self): + x = self.__pos[0] + y = self.__pos[1] + # self.__player_background = QGraphicsRectItem(x - 20, y - 20, TableGui.card_width * 3 + 40, TableGui.card_height + 70) + self.__player_background = QGraphicsRectItem(x, y, TableGui.info_width, TableGui.info_height) + + self.__player_background.setBrush(Qt.yellow) + self.__scene.addItem(self.__player_background) + + def __init_player_name_view(self): + x = self.__pos[0] + y = self.__pos[1] + self.__name_view = QGraphicsTextItem(self.__player_info.name()) + self.__name_view.setPos(x, y) + self.__scene.addItem(self.__name_view) + + def __init_hand_card_view(self): + x = self.__pos[0] + TableGui.name_height + y = self.__pos[1] + TableGui.name_height + self.__hand = self.__player_info.hand_cards() + self.__hand_pixmaps = [] + + cur_card_x = x + for card in self.__hand: + if not self.__player_info.is_hand_hidden(): + picture_path = card.image_path() + else: + picture_path = card.jacket_image_path() + + pixmap_item = QGraphicsPixmapItem(QPixmap(picture_path).scaledToHeight(TableGui.card_height)) + pixmap_item.setPos(cur_card_x, y) + self.__scene.addItem(pixmap_item) + self.__hand_pixmaps.append(pixmap_item) + + cur_card_x += TableGui.card_width + + def hand_cards_changed(self): + self.__hand = self.__player_info.hand_cards() + + i = 0 + for card in self.__hand: + if not self.__player_info.is_hand_hidden(): + picture_path = card.image_path() + else: + picture_path = card.jacket_image_path() + + self.__hand_pixmaps[i].setPixmap(QPixmap(picture_path).scaledToHeight(TableGui.card_height)) + i += 1 + + + def blind_changed(self): + blind = self.__player_info.blind() + + if blind == 0: + self.__blind.setPixmap(QPixmap()) + elif blind == 1: + self.__blind.setPixmap(QPixmap('images/littleblind.jpg').scaledToWidth(TableGui.card_width)) + else: + self.__blind.setPixmap(QPixmap('images/bigblind.jpg').scaledToWidth(TableGui.card_width)) + + def ante_changed(self): + ante_text = 'FOLD' + if not self.__player_info.is_folded(): + ante = self.__player_info.ante() + ante_text = str(ante) + self.__ante_text.setPlainText('Ante: ' + ante_text) + + def many_changed(self): + many = self.__player_info.many() + self.__many_text.setPlainText('Many: ' + str(many)) + + def active_alive_changed(self): + if not self.__player_info.is_alive(): + self.__player_background.setBrush(Qt.red) + return + if self.__player_info.is_active(): + self.__player_background.setBrush(Qt.green) + return + + self.__player_background.setBrush(Qt.yellow) + return + + def __init_many_view(self): + x = self.__pos[0] + y = self.__pos[1] + TableGui.name_height + self.__many_text = QGraphicsTextItem('Many: ' + str(self.__player_info.many())) + self.__many_text.setPos(x, y + TableGui.card_height) + self.__scene.addItem(self.__many_text) + + def __init_ante_view(self): + x = self.__pos[0] + y = self.__pos[1] + TableGui.name_height + self.__ante_text = QGraphicsTextItem('Ante: ' + str(self.__player_info.ante())) + self.__ante_text.setPos(x, y + TableGui.card_height + TableGui.name_height) + self.__scene.addItem(self.__ante_text) + + def __init_blind_view(self): + x = self.__pos[0] + y = self.__pos[1] + TableGui.name_height + self.__blind = QGraphicsPixmapItem(QPixmap()) + if self.__player_info.blind() == 1: + self.__blind = QGraphicsPixmapItem(QPixmap('images/littleblind.jpg').scaledToWidth(TableGui.blind_size)) + elif self.__player_info.blind() == 2: + self.__blind = QGraphicsPixmapItem(QPixmap('images/bigblind.jpg').scaledToWidth(TableGui.blind_size)) + self.__blind.setPos(x + 1.8 * TableGui.card_width, y + TableGui.card_height * 1.1) + self.__scene.addItem(self.__blind) + + class OpenedCardView: + def __init__(self, scene, table_info): + self.__scene = scene + self.__table_info = table_info + + table_info.add_crl_opened_cards(self) + + self.__card_view = [] + self.__card_view.append(QGraphicsPixmapItem(QPixmap())) + self.__scene.addItem(self.__card_view[0]) + self.__card_view.append(QGraphicsPixmapItem(QPixmap())) + self.__scene.addItem(self.__card_view[1]) + self.__card_view.append(QGraphicsPixmapItem(QPixmap())) + self.__scene.addItem(self.__card_view[2]) + self.__card_view.append(QGraphicsPixmapItem(QPixmap())) + self.__scene.addItem(self.__card_view[3]) + self.__card_view.append(QGraphicsPixmapItem(QPixmap())) + self.__scene.addItem(self.__card_view[4]) + + self.__card_view[0].setPos(TableGui.center_x - TableGui.card_width * TableGui.table_card_coef, TableGui.center_y - TableGui.card_height / 2) + self.__card_view[1].setPos(TableGui.center_x, TableGui.center_y - TableGui.card_height / 2) + self.__card_view[2].setPos(TableGui.center_x + TableGui.card_width * TableGui.table_card_coef, TableGui.center_y - TableGui.card_height / 2) + self.__card_view[3].setPos(TableGui.center_x + TableGui.card_width * 2 * TableGui.table_card_coef, TableGui.center_y - TableGui.card_height / 2) + self.__card_view[4].setPos(TableGui.center_x + TableGui.card_width * 3 * TableGui.table_card_coef, TableGui.center_y - TableGui.card_height / 2) + + self.opened_cards_changed() + + def opened_cards_changed(self): + # clear + for card_view in self.__card_view: + card_view.setPixmap(QPixmap()) + + i = 0 + for card in self.__table_info.opened_cards(): + self.__card_view[i].setPixmap(QPixmap(card.image_path()).scaledToHeight(TableGui.card_height * TableGui.table_card_coef)) + i += 1 + + class BankView: + def __init__(self, scene, table_info): + self.__scene = scene + self.__table_info = table_info + + self.__table_info.add_crl_bank(self) + + self.__bank_text = QGraphicsTextItem('Bank: %d' % table_info.bank()) + self.__bank_text.setPos(TableGui.center_x, TableGui.center_y + TableGui.card_height) + self.__scene.addItem(self.__bank_text) + + def bank_changed(self): + self.__bank_text.setPlainText('Bank: %d' % self.__table_info.bank()) + + class DecisionBlock: + btn_width = 70 + btn_height = 25 + + def __init__(self): + pass + + def start(self, scene, type, x, y): + # type must be 'Call' or 'Check' + self.__scene = scene + self.__type = type + + self.__call_check_btn = QPushButton(type) + self.__call_check_btn.setGeometry(x, y, self.btn_width, self.btn_height) + self.__call_check_btn.setEnabled(False) + self.__scene.addWidget(self.__call_check_btn) + + self.__fold_btn = QPushButton('Fold') + self.__fold_btn.setGeometry(x, y + self.btn_height, self.btn_width, self.btn_height) + self.__fold_btn.setEnabled(False) + self.__scene.addWidget(self.__fold_btn) + + self.__raise_btn = QPushButton('Raise:') + self.__raise_btn.setGeometry(x + self.btn_width, y, self.btn_width, self.btn_height) + self.__raise_btn.setEnabled(False) + self.__scene.addWidget(self.__raise_btn) + + self.__raise_sum_input = QLineEdit() + self.__raise_sum_input.setGeometry(x + self.btn_width * 2, y, self.btn_width, self.btn_height) + self.__raise_sum_input.setEnabled(False) + self.__scene.addWidget(self.__raise_sum_input) + + self.__allin_btn = QPushButton('All-in') + self.__allin_btn.setGeometry(x + self.btn_width, y + self.btn_height, self.btn_width * 2, self.btn_height) + self.__allin_btn.setEnabled(False) + self.__scene.addWidget(self.__allin_btn) + + self.__fold_btn.clicked.connect(self.__fold_clicked) + self.__call_check_btn.clicked.connect(self.__call_check_clicked) + self.__allin_btn.clicked.connect(self.__allin_clicked) + self.__raise_btn.clicked.connect(self.__raise_clicked) + + def __fold_clicked(self): + self.deactivate(Turn('fold', 0)) + + def __call_check_clicked(self): + if (self.__player.player_info().many() + self.__player.player_info().ante() >= self.__min_value) and ( + self.__min_value >= self.__player.player_info().ante()): + self.deactivate(Turn('check or call', self.__min_value)) + + def __allin_clicked(self): + if self.__player.player_info().many() > 0: + self.deactivate(Turn('allin', self.__player.player_info().many() + self.__player.player_info().ante())) + else: + msg_box = QMessageBox() + msg_box.setText('You have no many!') + msg_box.exec_() + + def __raise_clicked(self): + try: + sum = int(self.__raise_sum_input.text()) + if sum >= self.__blind and sum <= self.__player.player_info().many(): + self.deactivate(Turn('raise', self.__player.player_info().ante() + sum)) + else: + msg_box = QMessageBox() + msg_box.setText('You have no many enough to this raise!') + msg_box.exec_() + + except ValueError: + msg_box = QMessageBox() + msg_box.setText('Not number in the input field!') + msg_box.exec_() + + def activate(self, value, blind, player, func_to_call): + self.__call_check_btn.setEnabled(True) + self.__fold_btn.setEnabled(True) + self.__raise_btn.setEnabled(True) + self.__raise_sum_input.setEnabled(True) + self.__allin_btn.setEnabled(True) + + self.__min_value = value + self.__blind = blind + self.__player = player + self.__func_to_call = func_to_call + + def deactivate(self, turn_res): + self.__call_check_btn.setEnabled(False) + self.__fold_btn.setEnabled(False) + self.__raise_btn.setEnabled(False) + self.__raise_sum_input.setEnabled(False) + self.__allin_btn.setEnabled(False) + + self.__func_to_call(turn_res) + + def __init__(self, table_info): + self.__decision_block = TableGui.DecisionBlock() + + self.__table_info = table_info + self.__table = Table(table_info, self) + + def decision_block(self): + return self.__decision_block + + def start(self): + self.__scene = QGraphicsScene() + self.__view = QGraphicsView(self.__scene) + + self.__table_image = QGraphicsPixmapItem(QPixmap('table.png')) + self.__scene.addItem(self.__table_image) + + angle = math.pi * 2 / self.__table_info.player_count() + radius_x = 400 + radius_y = 250 + cur_angle = math.pi / 2 + for player in self.__table_info.players(): + player_info_view = TableGui.PlayerInfoView( + player + , self.__scene + , TableGui.center_x + radius_x * math.cos(cur_angle) + , TableGui.center_y + radius_y * math.sin(cur_angle) + ) + cur_angle += angle + + opened_card_view = TableGui.OpenedCardView(self.__scene, self.__table_info) + bank_view = TableGui.BankView(self.__scene, self.__table_info) + self.__decision_block.start(self.__scene, 'Call', 300, 320) + + self.__view.show() + + def __call__(self): + self.__table.round() + +if __name__ == '__main__': + table_info = TableInfo() + a = TableGui(table_info) + a.start() \ No newline at end of file diff --git a/poker/TableInfo.py b/poker/TableInfo.py new file mode 100644 index 0000000..90de8d5 --- /dev/null +++ b/poker/TableInfo.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- + +__author__ = 'anlun' + +from Card import * +from PlayerInfo import * + +class TableInfo: + def __init__(self): + # TODO: init current player // PlayerInfo + # TODO: init enemy players (self.__enemy_list) // PlayerInfo + + # TODO: Добавить обработку обновления открытых карт для TableGui + self.__client_player = [] + self.__enemy_list = [] + + playerInfo = PlayerInfo('Vasya', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0) + + self.__players = [] + self.__players.append(playerInfo) + self.__players.append(PlayerInfo('1', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + self.__players.append(PlayerInfo('2', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + self.__players.append(PlayerInfo('3', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + self.__players.append(PlayerInfo('4', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + self.__players.append(PlayerInfo('5', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + self.__players.append(PlayerInfo('6', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + self.__players.append(PlayerInfo('7', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + self.__players.append(PlayerInfo('8', [Card('h', 'a'), Card('c', '9')], 1000, 0, 0, True)) + + self.__player_order_dict = {} + + # self.__opened_cards = [] + self.__opened_cards = [Card('h', 'a'), Card('c', '9'), Card('s', 'j'), Card('d', 'k'), Card('h', 'q')] + self.__bank = 0 + + # crl - change receive list + self.__crl_cards = [] + self.__crl_bank = [] + + def players(self): + return self.__players + + def player_count(self): + return len (self.__players) + + def client_player(self): + return self.__client_player + + def enemy_players(self): + return self.__enemy_list + + def enemy_player_count(self): + return len (self.__enemy_list) + + # Можно сделать частью отдельного класса + def small_blind(self): + pass + + def big_blind(self): + pass + + def opened_cards(self): + return self.__opened_cards + + def add_opened_card(self, card): + self.__opened_cards.append(card) + for cr in self.__crl_cards: + cr.opened_cards_changed() + + def set_opened_cards(self, cards): + self.__opened_cards = cards + for cr in self.__crl_cards: + cr.opened_cards_changed() + + def add_crl_opened_cards(self, crl_member): + self.__crl_cards.append(crl_member) + + def bank(self): + return self.__bank + + def set_bank(self, bank): + self.__bank = bank + for cr in self.__crl_bank: + cr.bank_changed() + + def add_crl_bank(self, crl_member): + self.__crl_bank.append(crl_member) + + def player_order(self, player_name): + if player_name in self.__player_order_dict: + return self.__player_order_dict[player_name] + return -1 + + def __exec_msg(self): + pass + +# class TableInfo: +# def __init__(self, name): +# self.__small_blind = 0 +# self.__big_blind = 0 +# self.__many = 0 +# self.__ante = 0 +# self.__name = name + +# # 0 - no blind +# # 1 - small blind +# # 2 - big blind +# self.__cur_blind = 2 + +# def new_round(self): +# self.__hand_cards = [] +# self.__opened_cards = [] + +# def set_hand_cards(self, first, second): +# self.__hand_cards = [first, second] + +# def add_opened_cards(self, cards): +# self.__opened_cards.append(cards) + +# def hand_cards(self): +# """ Returns current hand cards. """ +# return self.__hand_cards + +# def set_blinds(self, small_blind_value, big_blind_value): +# self.__small_blind = small_blind_value +# self.__big_blind = big_blind_value + +# def big_blind(self): +# return self.__big_blind + +# def small_blind(self): +# return self.__small_blind + +# def set_ante(self, ante_value): +# self.__ante = ante_value + +# def ante(self): +# return self.__ante + +# def cur_blind(self): +# return self.__cur_blind + +# def opened_cards(self): +# """ Returns the list of already opened cards. """ +# return self.__opened_cards + +# def name(self): +# return self.__name + +# def change_many(self, value): +# self.__many += value + +# def many(self): +# return self.__many + +# def add_message(self, message): +# pass #TODO protocol and logica diff --git a/poker/Turn.py b/poker/Turn.py new file mode 100644 index 0000000..9a3e04f --- /dev/null +++ b/poker/Turn.py @@ -0,0 +1,10 @@ +__author__ = 'nk-karpov' + +class Turn: + def __init__(self, verdict, value): + self._verdict = verdict + self._value = value + def verdict(self): + return self._verdict + def value(self): + return self._value \ No newline at end of file diff --git a/poker/Utils.py b/poker/Utils.py new file mode 100644 index 0000000..b6be5be --- /dev/null +++ b/poker/Utils.py @@ -0,0 +1,342 @@ +__author__ = 'nk-karpov' + +from Card import * +from random import * + +value_to_int = { + '2':0, + '3':1, + '4':2, + '5':3, + '6':4, + '7':5, + '8':6, + '9':7, + '10':8, + 'j':9, + 'q':10, + 'k':11, + 'a':12 +} + +suit_to_int = { + 'c':0, + 'd':1, + 'h':2, + 's':3 +} + +int_to_suit = { + 0:'c', + 1:'d', + 2:'h', + 3:'s' +} + +int_to_value = { + 0:'2', + 1:'3', + 2:'4', + 3:'5', + 4:'6', + 5:'7', + 6:'8', + 7:'9', + 8:'10', + 9:'j', + 10:'q', + 11:'k', + 12:'a' +} + +suits = ('c', 'd', 'h', 's') +values = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'j', 'q', 'k', 'a') + +suit_masks = {} +value_masks = {} +initializ = False +random = None + +def init(): + global random, initializ + random = Random() + random.seed(239) + if initializ: + return None + initializ = True + for suit in suits: + tmp = 0 + for value in values: + tmp |= 1 << code_of_card(Card(suit, value)) + suit_masks[suit] = tmp + for value in values: + tmp = 0 + for suit in suits: + tmp |= 1 << code_of_card(Card(suit, value)) + value_masks[value] = tmp + + +def bit_complete(mask): + return mask ^ ((1 << (len(values) * len(suits))) - 1) +# res = 0 +# for i in xrange(len(values) * len(suits)): +# res |= 1<<(((mask>>i) & 1) ^ 1) +# return res + +def is_straight_flush(list_of_cards, start): + start_int = value_to_int[start] + mask = get_mask_of_cards(list_of_cards) + for suit in suits: + target = 0 + for i in xrange(5): + target |= 1 << code_of_card(Card(suit, int_to_value[(start_int + len(values) + i) % len(values)])) + if mask & target == target: + return True + else: + continue + return False + +def is_four(list_of_cards, value): + mask = get_mask_of_cards(list_of_cards) + target = 0 + for suit in suits: + target |= 1 << code_of_card(Card(suit, value)) + return mask & target == target + +def is_full_house(list_of_cards, three, pair): + mask = get_mask_of_cards(list_of_cards) + if bit_count(value_masks[three] & mask) < 3: + return False + return bit_count(value_masks[pair] & mask) >= 2 + +def is_flush(list_of_cards, suit): + mask = get_mask_of_cards(list_of_cards) + return bit_count(mask & suit_masks[suit]) >= 5 + +def is_straight(list_of_cards, start): + start_int = value_to_int[start] + mask = get_mask_of_cards(list_of_cards) + for i in xrange(5): + target = 0 + for suit in suits: + target |= 1 << code_of_card(Card(suit, int_to_value[(start_int + len(values) + i) % len(values)])) + if target & mask == 0: + return False + return True + +def is_three(list_of_cards, value): + mask = get_mask_of_cards(list_of_cards) + return bit_count(value_masks[value] & mask) >= 3 + +def is_two_pair(list_of_cards, first_value, second_value): + mask = get_mask_of_cards(list_of_cards) + return bit_count(value_masks[first_value] & mask) >= 2 and bit_count(value_masks[second_value] & mask) >= 2 + +def is_pair(list_of_cards, value): + mask = get_mask_of_cards(list_of_cards) + return bit_count(value_masks[value] & mask) >= 2 + +def cmp_high_card(first_list, second_list, limit): +# assert len(first_list) == len(second_list) + sorted(first_list, key = lambda x: -value_to_int[x.value()]) + sorted(second_list, key= lambda x: -value_to_int[x.value()]) + for i in xrange(min(limit, len(first_list))): + if first_list[i].value() > second_list[i].value(): + return -1 + if first_list[i].value() < second_list[i].value(): + return 1 + return 0 + +def cmp_hand(first_list, second_list): + init() + mask_of_first = get_mask_of_cards(first_list) + mask_of_second = get_mask_of_cards(second_list) + # straight flush + for start in xrange(len(values) - 5, -2, -1): + start_value = int_to_value[(len(values) + start) % len(values)] + first = is_straight_flush(first_list, start_value) + second = is_straight_flush(second_list, start_value) +# if first or second: +# print 'straight flush' + if first != second: + if first: + return -1 + else: + return 1 + if first: + return 0 + # four of kind + for value in reversed(values): + first = is_four(first_list, value) + second = is_four(second_list, value) +# if first or second: +# print 'four' + if first != second: + if first: + return -1 + else: + return 1 + if first and second: + mask_of_first &= bit_complete(value_masks[value]) + mask_of_second &= bit_complete(value_masks[value]) + return cmp_high_card(get_list_cards_from_mask(mask_of_first), + get_list_cards_from_mask(mask_of_second), + 1) + # full house + for three in reversed(values): + for pair in reversed(values): + if pair == three: + continue + first = is_full_house(first_list, three, pair) + second = is_full_house(second_list, three, pair) +# if first or second: +# print 'full house' + if first != second: + if first: + return -1 + else: + return 1 + if first and second: + return 0 + # flush + first = 0 + second = 0 + for suit in suits: + if is_flush(first_list, suit): + first = 1 + mask_of_first &= suit_masks[suit] + break + for suit in suits: + if is_flush(second_list, suit): + second = 1 + mask_of_second &= suit_masks[suit] +# if first or second: +# print 'flush' + if first != second: + if first: + return -1 + else: + return 1 + if first and second: + return cmp_high_card(get_list_cards_from_mask(mask_of_first), + get_list_cards_from_mask(mask_of_second), + 5) + # straight + for start in xrange(len(values) - 5, -2, -1): + start_value = int_to_value[(len(values) + start) % len(values)] + first = is_straight(first_list, start_value) + second = is_straight(second_list, start_value) +# if first or second: +# print 'straight' + if first != second: + if first: + return -1 + else: + return 1 + if first and second : + return 0 + # three of a kind + for value in reversed(values): + first = is_three(first_list, value) + second = is_three(second_list, value) +# if first or second: +# print 'three' + if first != second: + if first: + return -1 + else: + return 1 + if first and second: + mask_of_first &= bit_complete(value_masks[value]) + mask_of_second &= bit_complete(value_masks[value]) + return cmp_high_card(get_list_cards_from_mask(mask_of_first), + get_list_cards_from_mask(mask_of_second), + 2) + # two pair + for first_pair in reversed(values): + for second_pair in reversed(values): + if value_to_int[first_pair] < value_to_int[second_pair]: + continue + first = is_two_pair(first_list, first_pair, second_pair) + second = is_two_pair(second_list, first_pair, second_pair) +# if first or second: +# print 'two pair' + if first != second: + if first: + return -1 + else: + return 1 + if first and second: + mask_of_first &= bit_complete(value_masks[first_pair]) + mask_of_first &= bit_complete(value_masks[second_pair]) + mask_of_second &= bit_complete(value_masks[first_pair]) + mask_of_second &= bit_complete(value_masks[second_pair]) + return cmp_high_card(get_list_cards_from_mask(mask_of_first), + get_list_cards_from_mask(mask_of_second), + 1) + # one pair + for value in reversed(values): + first = is_pair(first_list, value) + second = is_pair(second_list, value) +# if first or second: +# print 'pair' + if first != second: + if first: + return -1 + else: + return 1 + if first and second: + mask_of_first &= bit_complete(value_masks[value]) + mask_of_second &= bit_complete(value_masks[value]) + return cmp_high_card(get_list_cards_from_mask(mask_of_first), + get_list_cards_from_mask(mask_of_second), + 3) + # high card +# print 'high card' + return cmp_high_card(first_list, second_list, 5) + +def code_of_card(card): + return value_to_int[card.value()] * 4 + suit_to_int[card.suit()] + +def reverse_code_of_card(code): + return Card(int_to_suit[code & 3], int_to_value[code / 4]) + +def bit_count(n): + result = 0 + for i in xrange(len(values) * len(suits)): + if n & 1 == 1: + result += 1 + n >>= 1 + return result + +def get_list_cards_from_mask(mask): + result = [] + for i in xrange(len(values) * len(suits)): + if mask & (1 << i): + result.append(reverse_code_of_card(i)) + return result + +def get_mask_of_cards(cards): + result = 0 + for card in cards: + result |= 1 << code_of_card(card) + return result + +def random_shuffle(deck): + for i in xrange(len(deck)): + pos = randint(0, i) + deck[i], deck[pos] = deck[pos], deck[i] + return deck + +def generate_deck(): + result = [] + for suit in suits: + for value in values: + result.append(Card(suit, value)) + return result + +def top_of_deck(deck, limit): + result = [] + for i in xrange(limit): + result.append(deck[i]) + return result \ No newline at end of file diff --git a/poker/images/bigblind.jpg b/poker/images/bigblind.jpg new file mode 100644 index 0000000..b1c7d8f Binary files /dev/null and b/poker/images/bigblind.jpg differ diff --git a/poker/images/cards/c/10.jpg b/poker/images/cards/c/10.jpg new file mode 100644 index 0000000..2d7d95c Binary files /dev/null and b/poker/images/cards/c/10.jpg differ diff --git a/poker/images/cards/c/2.jpg b/poker/images/cards/c/2.jpg new file mode 100644 index 0000000..6c7c404 Binary files /dev/null and b/poker/images/cards/c/2.jpg differ diff --git a/poker/images/cards/c/3.jpg b/poker/images/cards/c/3.jpg new file mode 100644 index 0000000..c8efca2 Binary files /dev/null and b/poker/images/cards/c/3.jpg differ diff --git a/poker/images/cards/c/4.jpg b/poker/images/cards/c/4.jpg new file mode 100644 index 0000000..a52e4f2 Binary files /dev/null and b/poker/images/cards/c/4.jpg differ diff --git a/poker/images/cards/c/5.jpg b/poker/images/cards/c/5.jpg new file mode 100644 index 0000000..d1273a5 Binary files /dev/null and b/poker/images/cards/c/5.jpg differ diff --git a/poker/images/cards/c/6.jpg b/poker/images/cards/c/6.jpg new file mode 100644 index 0000000..2940ac1 Binary files /dev/null and b/poker/images/cards/c/6.jpg differ diff --git a/poker/images/cards/c/7.jpg b/poker/images/cards/c/7.jpg new file mode 100644 index 0000000..1446b0b Binary files /dev/null and b/poker/images/cards/c/7.jpg differ diff --git a/poker/images/cards/c/8.jpg b/poker/images/cards/c/8.jpg new file mode 100644 index 0000000..d5d9e1b Binary files /dev/null and b/poker/images/cards/c/8.jpg differ diff --git a/poker/images/cards/c/9.jpg b/poker/images/cards/c/9.jpg new file mode 100644 index 0000000..038ea99 Binary files /dev/null and b/poker/images/cards/c/9.jpg differ diff --git a/poker/images/cards/c/a.jpg b/poker/images/cards/c/a.jpg new file mode 100644 index 0000000..e36035f Binary files /dev/null and b/poker/images/cards/c/a.jpg differ diff --git a/poker/images/cards/c/j.jpg b/poker/images/cards/c/j.jpg new file mode 100644 index 0000000..aa5543d Binary files /dev/null and b/poker/images/cards/c/j.jpg differ diff --git a/poker/images/cards/c/k.jpg b/poker/images/cards/c/k.jpg new file mode 100644 index 0000000..a2ad76c Binary files /dev/null and b/poker/images/cards/c/k.jpg differ diff --git a/poker/images/cards/c/q.jpg b/poker/images/cards/c/q.jpg new file mode 100644 index 0000000..8fa80f6 Binary files /dev/null and b/poker/images/cards/c/q.jpg differ diff --git a/poker/images/cards/d.jpg b/poker/images/cards/d.jpg new file mode 100644 index 0000000..4f75155 Binary files /dev/null and b/poker/images/cards/d.jpg differ diff --git a/poker/images/cards/d/10.jpg b/poker/images/cards/d/10.jpg new file mode 100644 index 0000000..9a8d005 Binary files /dev/null and b/poker/images/cards/d/10.jpg differ diff --git a/poker/images/cards/d/2.jpg b/poker/images/cards/d/2.jpg new file mode 100644 index 0000000..a79e0d0 Binary files /dev/null and b/poker/images/cards/d/2.jpg differ diff --git a/poker/images/cards/d/3.jpg b/poker/images/cards/d/3.jpg new file mode 100644 index 0000000..4c40920 Binary files /dev/null and b/poker/images/cards/d/3.jpg differ diff --git a/poker/images/cards/d/4.jpg b/poker/images/cards/d/4.jpg new file mode 100644 index 0000000..1f48008 Binary files /dev/null and b/poker/images/cards/d/4.jpg differ diff --git a/poker/images/cards/d/5.jpg b/poker/images/cards/d/5.jpg new file mode 100644 index 0000000..d5239f2 Binary files /dev/null and b/poker/images/cards/d/5.jpg differ diff --git a/poker/images/cards/d/6.jpg b/poker/images/cards/d/6.jpg new file mode 100644 index 0000000..d0c8f5e Binary files /dev/null and b/poker/images/cards/d/6.jpg differ diff --git a/poker/images/cards/d/7.jpg b/poker/images/cards/d/7.jpg new file mode 100644 index 0000000..dc4b001 Binary files /dev/null and b/poker/images/cards/d/7.jpg differ diff --git a/poker/images/cards/d/8.jpg b/poker/images/cards/d/8.jpg new file mode 100644 index 0000000..84e24a5 Binary files /dev/null and b/poker/images/cards/d/8.jpg differ diff --git a/poker/images/cards/d/9.jpg b/poker/images/cards/d/9.jpg new file mode 100644 index 0000000..b6295e4 Binary files /dev/null and b/poker/images/cards/d/9.jpg differ diff --git a/poker/images/cards/d/a.jpg b/poker/images/cards/d/a.jpg new file mode 100644 index 0000000..b9526b6 Binary files /dev/null and b/poker/images/cards/d/a.jpg differ diff --git a/poker/images/cards/d/j.jpg b/poker/images/cards/d/j.jpg new file mode 100644 index 0000000..73fd0e3 Binary files /dev/null and b/poker/images/cards/d/j.jpg differ diff --git a/poker/images/cards/d/k.jpg b/poker/images/cards/d/k.jpg new file mode 100644 index 0000000..d745026 Binary files /dev/null and b/poker/images/cards/d/k.jpg differ diff --git a/poker/images/cards/d/q.jpg b/poker/images/cards/d/q.jpg new file mode 100644 index 0000000..c1e58c0 Binary files /dev/null and b/poker/images/cards/d/q.jpg differ diff --git a/poker/images/cards/deckdesigns_l.jpg b/poker/images/cards/deckdesigns_l.jpg new file mode 100644 index 0000000..6faeb5e Binary files /dev/null and b/poker/images/cards/deckdesigns_l.jpg differ diff --git a/poker/images/cards/h/10.jpg b/poker/images/cards/h/10.jpg new file mode 100644 index 0000000..7ae917f Binary files /dev/null and b/poker/images/cards/h/10.jpg differ diff --git a/poker/images/cards/h/2.jpg b/poker/images/cards/h/2.jpg new file mode 100644 index 0000000..4b00775 Binary files /dev/null and b/poker/images/cards/h/2.jpg differ diff --git a/poker/images/cards/h/3.jpg b/poker/images/cards/h/3.jpg new file mode 100644 index 0000000..8686c61 Binary files /dev/null and b/poker/images/cards/h/3.jpg differ diff --git a/poker/images/cards/h/4.jpg b/poker/images/cards/h/4.jpg new file mode 100644 index 0000000..68a83b6 Binary files /dev/null and b/poker/images/cards/h/4.jpg differ diff --git a/poker/images/cards/h/5.jpg b/poker/images/cards/h/5.jpg new file mode 100644 index 0000000..6be81f6 Binary files /dev/null and b/poker/images/cards/h/5.jpg differ diff --git a/poker/images/cards/h/6.jpg b/poker/images/cards/h/6.jpg new file mode 100644 index 0000000..7a3af81 Binary files /dev/null and b/poker/images/cards/h/6.jpg differ diff --git a/poker/images/cards/h/7.jpg b/poker/images/cards/h/7.jpg new file mode 100644 index 0000000..c51862f Binary files /dev/null and b/poker/images/cards/h/7.jpg differ diff --git a/poker/images/cards/h/8.jpg b/poker/images/cards/h/8.jpg new file mode 100644 index 0000000..2b17a5c Binary files /dev/null and b/poker/images/cards/h/8.jpg differ diff --git a/poker/images/cards/h/9.jpg b/poker/images/cards/h/9.jpg new file mode 100644 index 0000000..6182a59 Binary files /dev/null and b/poker/images/cards/h/9.jpg differ diff --git a/poker/images/cards/h/a.jpg b/poker/images/cards/h/a.jpg new file mode 100644 index 0000000..3103681 Binary files /dev/null and b/poker/images/cards/h/a.jpg differ diff --git a/poker/images/cards/h/j.jpg b/poker/images/cards/h/j.jpg new file mode 100644 index 0000000..b5c0324 Binary files /dev/null and b/poker/images/cards/h/j.jpg differ diff --git a/poker/images/cards/h/k.jpg b/poker/images/cards/h/k.jpg new file mode 100644 index 0000000..0a68c9a Binary files /dev/null and b/poker/images/cards/h/k.jpg differ diff --git a/poker/images/cards/h/q.jpg b/poker/images/cards/h/q.jpg new file mode 100644 index 0000000..9a78f0d Binary files /dev/null and b/poker/images/cards/h/q.jpg differ diff --git a/poker/images/cards/s/10.jpg b/poker/images/cards/s/10.jpg new file mode 100644 index 0000000..cde8882 Binary files /dev/null and b/poker/images/cards/s/10.jpg differ diff --git a/poker/images/cards/s/2.jpg b/poker/images/cards/s/2.jpg new file mode 100644 index 0000000..e262928 Binary files /dev/null and b/poker/images/cards/s/2.jpg differ diff --git a/poker/images/cards/s/3.jpg b/poker/images/cards/s/3.jpg new file mode 100644 index 0000000..36d5858 Binary files /dev/null and b/poker/images/cards/s/3.jpg differ diff --git a/poker/images/cards/s/4.jpg b/poker/images/cards/s/4.jpg new file mode 100644 index 0000000..5db87a0 Binary files /dev/null and b/poker/images/cards/s/4.jpg differ diff --git a/poker/images/cards/s/5.jpg b/poker/images/cards/s/5.jpg new file mode 100644 index 0000000..9251268 Binary files /dev/null and b/poker/images/cards/s/5.jpg differ diff --git a/poker/images/cards/s/6.jpg b/poker/images/cards/s/6.jpg new file mode 100644 index 0000000..1c75b2c Binary files /dev/null and b/poker/images/cards/s/6.jpg differ diff --git a/poker/images/cards/s/7.jpg b/poker/images/cards/s/7.jpg new file mode 100644 index 0000000..7f91662 Binary files /dev/null and b/poker/images/cards/s/7.jpg differ diff --git a/poker/images/cards/s/8.jpg b/poker/images/cards/s/8.jpg new file mode 100644 index 0000000..eb54f9b Binary files /dev/null and b/poker/images/cards/s/8.jpg differ diff --git a/poker/images/cards/s/9.jpg b/poker/images/cards/s/9.jpg new file mode 100644 index 0000000..f2076da Binary files /dev/null and b/poker/images/cards/s/9.jpg differ diff --git a/poker/images/cards/s/a.jpg b/poker/images/cards/s/a.jpg new file mode 100644 index 0000000..5073f47 Binary files /dev/null and b/poker/images/cards/s/a.jpg differ diff --git a/poker/images/cards/s/j.jpg b/poker/images/cards/s/j.jpg new file mode 100644 index 0000000..d258d55 Binary files /dev/null and b/poker/images/cards/s/j.jpg differ diff --git a/poker/images/cards/s/k.jpg b/poker/images/cards/s/k.jpg new file mode 100644 index 0000000..6891b27 Binary files /dev/null and b/poker/images/cards/s/k.jpg differ diff --git a/poker/images/cards/s/q.jpg b/poker/images/cards/s/q.jpg new file mode 100644 index 0000000..cfb5c71 Binary files /dev/null and b/poker/images/cards/s/q.jpg differ diff --git a/poker/images/littleblind.jpg b/poker/images/littleblind.jpg new file mode 100644 index 0000000..937c2f3 Binary files /dev/null and b/poker/images/littleblind.jpg differ diff --git a/poker/main.py b/poker/main.py new file mode 100644 index 0000000..3eec477 --- /dev/null +++ b/poker/main.py @@ -0,0 +1,31 @@ +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import sys + +from TableGui import * +from TableInfo import * + +app = QApplication(sys.argv) + +# # new game dialog +# msgBox = QMessageBox() +# msgBox.setText() + +# if msgBox + +table_info = TableInfo() +gui = TableGui(table_info) +gui.start() + +QTimer.singleShot(20, gui) +# btn = QPushButton("new game") + +# def start_game(bool_var): +# print 'aaa' +# gui() + +# btn.clicked.connect(start_game) + +# btn.show() + +app.exec_() \ No newline at end of file diff --git a/poker/table.png b/poker/table.png new file mode 100644 index 0000000..f06d413 Binary files /dev/null and b/poker/table.png differ