from ctypes import c_long, c_uint, c_ulong import dds SUIT_ORDER = {"S": 0, "H": 1, "D": 2, "C": 3} RANK_ORDER = { "A": 14, "K": 13, "Q": 12, "J": 11, "T": 10, "9": 9, "8": 8, "7": 7, "6": 6, "5": 5, "4": 4, "3": 3, "2": 2, } RANK_STRENGTH = { "A": 1, "K": 2, "Q": 3, "J": 4, "T": 5, "9": 6, "8": 7, "7": 8, "6": 9, "5": 10, "4": 11, "3": 12, "2": 13, } SUIT_STRENGTH = { "S": 0, "H": 1, "D": 2, "C": 3, } RANK_TO_BIT = {rank: 2**power for rank, power in RANK_ORDER.items()} def is_text_valid(text): text = ( text.replace("1O", "T") .replace("10", "T") .replace("0", "T") .replace("O", "T") .replace("U", "J") .replace("1", "7") ) for rank in RANK_ORDER.keys(): if rank in text: return rank return None def arrange_hand(hand): unique_hand = list(set(hand)) sorted_hand = sorted( unique_hand, key=lambda card: ( SUIT_ORDER.get(card[0], 99), -RANK_ORDER.get(card[1:], 0), ), ) return sorted_hand def convert2xhd(all_result, title): xhd = f""" {title} """ for i, result in enumerate(all_result): if "error" in result.keys(): continue xhd += f'\r\n' xhd += convert2xhd_board(result["hands"]) xhd += "\r\n\r\n" xhd += "" return xhd def convert2xhd_board(board): north_hand = convert2xhd_hand(board["north"]) south_hand = convert2xhd_hand(board["south"]) west_hand = convert2xhd_hand(board["west"]) east_hand = convert2xhd_hand(board["east"]) return f"{north_hand} {east_hand} {south_hand} {west_hand}" def convert2xhd_hand(hand): arranged_cards = arrange_hand(hand) S, H, D, C = "", "", "", "" for card in arranged_cards: if card[0] == "S": S += card[1:] if card[0] == "H": H += card[1:] if card[0] == "D": D += card[1:] if card[0] == "C": C += card[1:] return f"{S}.{H}.{D}.{C}" def convert2dup(all_result, _): num = len(all_result) dup = "" for result in all_result: if "error" in result.keys(): continue dup += convert2dup_board(result["hands"], num) return dup def convert2dup_board(board, num): north_hand_num = convert2dup_hand_num(board["north"]) east_hand_num = convert2dup_hand_num(board["east"]) south_hand_num = convert2dup_hand_num(board["south"]) north_hand = convert2dup_hand_str(board["north"]) south_hand = convert2dup_hand_str(board["south"]) west_hand = convert2dup_hand_str(board["west"]) east_hand = convert2dup_hand_str(board["east"]) return f"{north_hand_num}{east_hand_num}{south_hand_num}{north_hand}{east_hand}{south_hand}{west_hand}YN1 1 {str(num).ljust(2)} " def convert2dup_hand_num(hand): arranged_hand = arrange_hand(hand) cards_num = [convert_card2num(card) for card in arranged_hand] sorted(cards_num) return "".join(str(c).zfill(2) for c in cards_num) def convert2dup_hand_str(hand): arranged_hand = arrange_hand(hand) S, H, D, C = "", "", "", "" for card in arranged_hand: if card[0] == "S": S += card[1] if card[0] == "H": H += card[1] if card[0] == "D": D += card[1] if card[0] == "C": C += card[1] return f"{S}{H}{D}{C}" def convert_card2num(card): suit = SUIT_STRENGTH.get(card[0]) rank = RANK_STRENGTH.get(card[1]) if suit is None or rank is None: return -1 return suit * 13 + rank def convert2pbn(all_result): res = "% Dealer4 ver 4.82\r\n" for i, result in enumerate(all_result): if "error" in result.keys(): continue res += '[Event "#"]\r\n' if i != 0 else '[Event ""]\r\n' res += '[Site "#"]\r\n' if i != 0 else '[Site ""]\r\n' res += '[Date "#"]\r\n' if i != 0 else '[Date ""]\r\n' res += f'[Board "{i}"]\r\n' res += f'[Dealer "{get_dealer(i)}"]\r\n' res += f'[Vulnerable "{get_vul(i)}"]\r\n' res += f'{convert2pbn_board(result["hands"], get_dealer(i))}\r\n\r\n' return res def convert2pbn_board(board, dealer): return f'[Deal "{convert2pbn_txt(board, dealer)}"]' def convert2pbn_txt(board, dealer): player_order = ["north", "south", "west", "east"] dealer_dict = {"N": 0, "E": 1, "S": 2, "W": 3} north_hand = convert2pbn_hand(board[player_order[dealer_dict[dealer]]]) south_hand = convert2pbn_hand( board[player_order[(dealer_dict[dealer] + 1) % 4]] ) west_hand = convert2pbn_hand( board[player_order[(dealer_dict[dealer] + 2) % 4]] ) east_hand = convert2pbn_hand( board[player_order[(dealer_dict[dealer] + 3) % 4]] ) return f"{dealer}:{north_hand} {east_hand} {south_hand} {west_hand}" def convert2pbn_hand(hand): arranged_cards = arrange_hand(hand) S, H, D, C = "", "", "", "" for card in arranged_cards: if card[0] == "S": S += card[1:] if card[0] == "H": H += card[1:] if card[0] == "D": D += card[1:] if card[0] == "C": C += card[1:] return f"{S}.{H}.{D}.{C}" def get_vul(num): r = num % 4 q = (num - 1) // 4 if (r + q) % 4 == 1: return "None" elif (r + q) % 4 == 2: return "NS" elif (r + q) % 4 == 3: return "EW" else: return "All" def get_dealer(num): if num % 4 == 1: return "N" elif num % 4 == 2: return "E" elif num % 4 == 3: return "S" else: return "W" def convert2ddTableDeal(hands_dict): table_deal = dds.ddTableDeal() # C言語の配列のように振る舞うため、このように初期化 cards = ((c_uint * 4) * 4)() # ddTableDealはc_uintでOK hand_map = {"north": 0, "east": 1, "south": 2, "west": 3} suit_map = {"S": 0, "H": 1, "D": 2, "C": 3} for player_name, hand in hands_dict.items(): for card in hand: suit_char = card[0] rank_char = card[1:] player_idx = hand_map.get(player_name) suit_idx = suit_map.get(suit_char) if player_idx is not None and suit_idx is not None: cards[player_idx][suit_idx] |= RANK_TO_BIT.get(rank_char, 0) table_deal.cards = cards return table_deal # DDSのdealオブジェクトを作成する最終確定版の関数 def convert_hands_to_binary_deal(hands_dict): from ctypes import c_uint deal = dds.deal() deal.trump = 0 deal.first = 0 deal.currentTrickSuit = (0, 0, 0) deal.currentTrickRank = (0, 0, 0) cards = ((c_long * 4) * 4)() hand_map = {"north": 0, "east": 1, "south": 2, "west": 3} suit_map = {"S": 0, "H": 1, "D": 2, "C": 3} for player_name, hand in hands_dict.items(): for card in hand: suit_char = card[0] rank_char = card[1:] player_idx = hand_map.get(player_name) suit_idx = suit_map.get(suit_char) if player_idx is not None and suit_idx is not None: cards[player_idx][suit_idx] |= RANK_TO_BIT.get(rank_char, 0) deal.remainCards = cards return deal def PrintTable(table): dcardSuit = ["S", "H", "D", "C", "N"] print( "{:5} {:<5} {:<5} {:<5} {:<5}".format( "", "North", "South", "East", "West" ) ) print( "{:>5} {:5} {:5} {:5} {:5}".format( "NT", table.resTable[0][4], table.resTable[2][4], table.resTable[1][4], table.resTable[3][4], ) ) for suit in range(0, dds.DDS_SUITS): print( "{:>5} {:5} {:5} {:5} {:5}".format( dcardSuit[suit], table.resTable[0][suit], table.resTable[2][suit], table.resTable[1][suit], table.resTable[3][suit], ) ) print("") def reshape_table(table): players_map = {0: "North", 1: "East", 2: "South", 3: "West"} suits_map = {4: "nt", 0: "s", 1: "h", 2: "d", 3: "c"} res = {p_name: {} for p_name in players_map.values()} for i, suit in suits_map.items(): for j, player in players_map.items(): # new_suit = suits_map[(i + 5 * j) // 4] # new_player = players_map[(i + 5 * j) % 4] # print( # suit, player, i, j, new_suit, new_player, table.resTable[j][i] # ) res[player][suit] = table.resTable[i][j] return res