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