import pygame
import random
import sys

pygame.init()
WIDTH, HEIGHT = 900, 650
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("蜘蛛纸牌（简易版·不限花色）")

# ========== 颜色定义 ==========
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (20, 100, 30)
RED = (200, 0, 0)
BLUE = (30, 60, 160)
GRAY = (150, 150, 150)

# 字体（海龟编辑器兼容，无字体报错）
font = pygame.font.Font(None, 26)
tip_font = pygame.font.Font(None, 36)

# ========== 卡牌基础设置 ==========
CARD_W = 72
CARD_H = 104
CARD_OFFSET_Y = 26  # 堆叠纵向偏移
SUITS = ["♠", "♥"]
SUIT_COLOR = [BLACK, RED]
VALUES = ["K","Q","J","10","9","8","7","6","5","4","3","2","A"]
VALUE_ORDER = {"K":12,"Q":11,"J":10,"10":9,"9":8,"8":7,"7":6,"6":5,"5":4,"4":3,"3":2,"2":1,"A":0}

# 生成牌组（两套黑桃+两套红桃，双花色）
def create_deck():
    deck = []
    for _ in range(2):
        for suit_idx in range(2):
            for val in VALUES:
                deck.append({"suit": suit_idx, "value": val})
    random.shuffle(deck)
    return deck

# ========== 全局变量 ==========
deck = create_deck()
piles = []          # 7列牌堆
stock_pile = []     # 发牌堆
selected_cards = [] # 当前拖动选中卡牌
drag_origin = None
drag_pos = (0,0)
game_win = False

# 初始化布局
def init_game():
    global deck, piles, stock_pile, selected_cards, game_win
    deck = create_deck()
    piles = [[] for _ in range(7)]
    # 7列发牌
    for i in range(7):
        count = i + 1
        for _ in range(count):
            card = deck.pop()
            piles[i].append({"card":card, "face": False})
        # 最上面一张翻开
        piles[i][-1]["face"] = True
    stock_pile = deck
    selected_cards = []
    game_win = False

# 绘制单张卡牌
def draw_card(x, y, card_info, face=True):
    rect = pygame.Rect(x, y, CARD_W, CARD_H)
    if not face:
        pygame.draw.rect(screen, BLUE, rect)
        pygame.draw.rect(screen, BLACK, rect, 2)
        return
    pygame.draw.rect(screen, WHITE, rect)
    pygame.draw.rect(screen, BLACK, rect, 2)
    suit_idx = card_info["suit"]
    val = card_info["value"]
    text = font.render(val + SUITS[suit_idx], True, SUIT_COLOR[suit_idx])
    screen.blit(text, (x+6, y+6))

# 【修改核心】放置规则：只判断点数，不限制花色
def can_place(target_pile, moving_cards):
    if len(moving_cards) == 0:
        return False
    top_card = moving_cards[0]
    target_top = target_pile[-1]["card"] if len(target_pile) > 0 else None
    if target_top is None:
        return True
    # 只要求：目标点数 = 当前点数 +1，花色不限
    if VALUE_ORDER[target_top["value"]] == VALUE_ORDER[top_card["value"]] + 1:
        return True
    return False

# 【修改核心】成套判定：只需要连续K-A，不再要求同花色
def check_complete(pile):
    if len(pile) < 13:
        return False
    seq = [c["card"] for c in pile[-13:]]
    order_list = [VALUE_ORDER[c["value"]] for c in seq]
    if order_list == list(range(12, -1, -1)):
        return True
    return False

# 检查游戏胜利
def check_win():
    total = 0
    for p in piles:
        total += len(p)
    return total == 0

init_game()
clock = pygame.time.Clock()
running = True

while running:
    screen.fill(GREEN)
    mx, my = pygame.mouse.get_pos()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.MOUSEBUTTONDOWN and not game_win:
            # 点击发牌堆
            if event.button == 1:
                stock_x, stock_y = 780, 30
                if stock_pile and pygame.Rect(stock_x, stock_y, CARD_W, CARD_H).collidepoint(mx, my):
                    for pile in piles:
                        if stock_pile:
                            c = stock_pile.pop()
                            pile.append({"card":c, "face":True})
                    continue

                # 点击列，尝试选中卡牌
                selected_cards.clear()
                drag_origin = None
                for pile_idx in range(7):
                    px = 30 + pile_idx * (CARD_W + 12)
                    pile = piles[pile_idx]
                    for card_idx in range(len(pile)-1, -1, -1):
                        cy = 30 + card_idx * CARD_OFFSET_Y
                        rect = pygame.Rect(px, cy, CARD_W, CARD_H)
                        if rect.collidepoint(mx, my) and pile[card_idx]["face"]:
                            drag_origin = (pile_idx, card_idx)
                            # 选中从此往下所有牌
                            selected_cards = pile[card_idx:]
                            drag_pos = (mx, my)
                            break
                    if drag_origin is not None:
                        break

        if event.type == pygame.MOUSEMOTION:
            if drag_origin is not None:
                drag_pos = (mx, my)

        if event.type == pygame.MOUSEBUTTONUP and drag_origin is not None and not game_win:
            pile_idx, card_idx = drag_origin
            target_pile_idx = -1
            # 判断拖到哪一列
            for i in range(7):
                px = 30 + i * (CARD_W + 12)
                last_y = 30 + len(piles[i]) * CARD_OFFSET_Y
                rect = pygame.Rect(px, last_y - CARD_OFFSET_Y, CARD_W, CARD_H + 40)
                if rect.collidepoint(mx, my):
                    target_pile_idx = i
                    break
            # 执行移动
            if target_pile_idx != -1 and target_pile_idx != pile_idx:
                if can_place(piles[target_pile_idx], [x["card"] for x in selected_cards]):
                    # 移动卡牌
                    piles[target_pile_idx].extend(selected_cards)
                    del piles[pile_idx][card_idx:]
                    # 如果原列还有牌，翻开最上面一张
                    if len(piles[pile_idx]) > 0:
                        piles[pile_idx][-1]["face"] = True
                    # 检查是否完成一套
                    while True:
                        cleared = False
                        for pi in range(7):
                            if check_complete(piles[pi]):
                                del piles[pi][-13:]
                                cleared = True
                                break
                        if not cleared:
                            break
                    # 判断胜利
                    if check_win():
                        game_win = True
            selected_cards.clear()
            drag_origin = None

    # ========== 绘制所有牌列 ==========
    for pile_idx in range(7):
        px = 30 + pile_idx * (CARD_W + 12)
        pile = piles[pile_idx]
        for card_idx, item in enumerate(pile):
            py = 30 + card_idx * CARD_OFFSET_Y
            # 不绘制正在拖动的牌
            if drag_origin and pile_idx == drag_origin[0] and card_idx >= drag_origin[1]:
                continue
            draw_card(px, py, item["card"], item["face"])

    # 绘制拖动中的卡牌
    if drag_origin is not None and len(selected_cards) > 0:
        for i, item in enumerate(selected_cards):
            draw_card(drag_pos[0], drag_pos[1] + i * CARD_OFFSET_Y, item["card"], True)

    # 绘制发牌堆
    stock_x, stock_y = 780, 30
    if stock_pile:
        draw_card(stock_x, stock_y, {}, face=False)
    else:
        pygame.draw.rect(screen, GRAY, (stock_x, stock_y, CARD_W, CARD_H))
        pygame.draw.rect(screen, BLACK, (stock_x, stock_y, CARD_W, CARD_H), 2)

    # 文字提示
    tip1 = tip_font.render("拖动卡牌，K→A降序堆叠（不限花色），点击右侧牌堆发牌", True, WHITE)
    screen.blit(tip1, (20, HEIGHT - 45))

    if game_win:
        overlay = pygame.Surface((WIDTH, HEIGHT))
        overlay.set_alpha(160)
        overlay.fill(BLACK)
        screen.blit(overlay, (0,0))
        win_text = tip_font.render("恭喜通关蜘蛛纸牌！", True, WHITE)
        screen.blit(win_text, win_text.get_rect(center=(WIDTH//2, HEIGHT//2)))

    pygame.display.update()
    clock.tick(60)

pygame.quit()
sys.exit()