AI做五印一当猜牌游戏Python代码与成品分享

查看 105|回复 9
作者:volo   
本人纯小白,看恶魔游戏里面的五印一当感觉挺有意思挑战做一个。
代码全用ai做的。大约问了30余次完成,基本无bug。电脑猜牌逻辑为随机,正常逻辑太复杂做不出来,希望有大佬解惑。默认玩家先手,更改player_first = True可设置。牌面资源复刻原版。
成品与源码:https://pan.baidu.com/s/1jBeupZ51GyVKNR1SCVAG_A?pwd=rsj2


界面.jpg (187.23 KB, 下载次数: 0)
下载附件
2025-4-25 17:00 上传

资源路径说明:
/img(5正面 1背面 1背景 2按钮 共9png)
/music(2音效mp3)
/font(SmileySans-Oblique.ttf)
[Python] 纯文本查看 复制代码import pygame
import random
pygame.init()
window_width = 1600
window_height = 950
screen = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption('五印一当')
font_path = resource_path(r'font\SmileySans-Oblique.ttf')
font = pygame.font.Font(font_path, 36)
small_font = pygame.font.Font(font_path, 12)
card_original_width = 300
card_original_height = 460
player_card_scale = 0.3
deck_card_scale = 0.2
player_card_width = int(card_original_width * player_card_scale)
player_card_height = int(card_original_height * player_card_scale)
deck_card_width = int(card_original_width * deck_card_scale)
deck_card_height = int(card_original_height * deck_card_scale)
target_card_width = int(card_original_width * player_card_scale)
target_card_height = int(card_original_height * player_card_scale)
open_card_area_width = player_card_width * 3 + 40
open_card_area_height = player_card_height + 10
top_open_card_area_x = (window_width - open_card_area_width) / 2 - 100 - 90
top_open_card_area_y = 50
bottom_open_card_area_x = (window_width - open_card_area_width) / 2 - 100 - 90
bottom_open_card_area_y = window_height - open_card_area_height - 50 - 100
player_hand_card_x = bottom_open_card_area_x + open_card_area_width + 40
player_hand_card_y = bottom_open_card_area_y
player_hand_card_positions = [
    (player_hand_card_x, player_hand_card_y),
    (player_hand_card_x + player_card_width + 20, player_hand_card_y),
    (player_hand_card_x + (player_card_width + 20) * 2, player_hand_card_y)
]
computer_hand_card_x = top_open_card_area_x + open_card_area_width + 40
computer_hand_card_y = top_open_card_area_y
computer_hand_card_positions = [
    (computer_hand_card_x, computer_hand_card_y),
    (computer_hand_card_x + player_card_width + 20, computer_hand_card_y),
    (computer_hand_card_x + (player_card_width + 20) * 2, computer_hand_card_y)
]
deck_x = (window_width - 4 * deck_card_width) / 3
deck_y = window_height / 3
deck_positions = []
for i in range(2):
    for j in range(4):
        x = deck_x + j * (deck_card_width + 20)
        y = deck_y + i * (deck_card_height + 20)
        deck_positions.append((x, y))
target_card_x = (window_width - target_card_width) * 2 / 3
target_card_y = window_height / 3
target_card_position = (target_card_x, target_card_y)
button_width = 150
button_height = 70
button_x1 = (window_width - 2 * button_width - 40) / 2
button_y1 = window_height - button_height - 40
button_x2 = button_x1 + button_width + 40
button_y2 = button_y1
button_positions = [
    (button_x1, button_y1),
    (button_x2, button_y2)
]
def draw_dashed_rect(surface, color, rect, width=1, dash_length=10, border_radius=20):
    x, y, w, h = rect
    r = border_radius
    for i in range(r, w - r, dash_length * 2):
        pygame.draw.line(surface, color, (x + i, y), (x + i + dash_length, y), width)
    for i in range(r, w - r, dash_length * 2):
        pygame.draw.line(surface, color, (x + i, y + h), (x + i + dash_length, y + h), width)
    for i in range(r, h - r, dash_length * 2):
        pygame.draw.line(surface, color, (x, y + i), (x, y + i + dash_length), width)
    for i in range(r, h - r, dash_length * 2):
        pygame.draw.line(surface, color, (x + w, y + i), (x + w, y + i + dash_length), width)
    for angle in range(180, 270, 10):
        rad = pygame.math.Vector2(r, 0).rotate(angle)
        pygame.draw.circle(surface, color, (int(x + r + rad.x), int(y + r + rad.y)), 1)
    for angle in range(270, 360, 10):
        rad = pygame.math.Vector2(r, 0).rotate(angle)
        pygame.draw.circle(surface, color, (int(x + w - r + rad.x), int(y + r + rad.y)), 1)
    for angle in range(90, 180, 10):
        rad = pygame.math.Vector2(r, 0).rotate(angle)
        pygame.draw.circle(surface, color, (int(x + r + rad.x), int(y + h - r + rad.y)), 1)
    for angle in range(0, 90, 10):
        rad = pygame.math.Vector2(r, 0).rotate(angle)
        pygame.draw.circle(surface, color, (int(x + w - r + rad.x), int(y + h - r + rad.y)), 1)
bg_image = pygame.image.load(resource_path(r'img\bg.png'))
bg_image = pygame.transform.scale(bg_image, (window_width, window_height))
card_images = {}
for card in ["bm", "em", "fk", "ht", "hx", "mh"]:
    original = pygame.image.load(resource_path(f'img\{card}.png'))
    player_scaled = pygame.transform.smoothscale(
        original,
        (player_card_width, player_card_height)
    )
    deck_scaled = pygame.transform.smoothscale(
        original,
        (deck_card_width, deck_card_height)
    )
    card_images[card] = {
        "original": original,
        "player": player_scaled,
        "deck": deck_scaled
    }
button_images = {
    "normal": pygame.image.load(resource_path(r'img/an1.png')),
    "clicked": pygame.image.load(resource_path(r'img/an2.png'))
}
button_images["normal"] = pygame.transform.smoothscale(button_images["normal"], (button_width, button_height))
button_images["clicked"] = pygame.transform.smoothscale(button_images["clicked"], (button_width, button_height))
card_list = ["em", "fk", "ht", "hx", "mh"] * 3
random.shuffle(card_list)
all_positions = computer_hand_card_positions + player_hand_card_positions + [target_card_position] + deck_positions
card_assignments = dict(zip(all_positions, card_list))
player_first = True  # 可修改为False让电脑先手/True为玩家先手
current_turn = "player" if player_first else "computer"
player_round = 1  # 玩家当前回合
computer_round = 1  # 电脑当前回合
mingpai_used = {"player": False, "computer": False}
has_guessed = False
guess_box_width = player_card_width * 5 + 40 + 80
guess_box_height = player_card_height + 40
guess_box_x = (window_width - guess_box_width) / 2
guess_box_y = (window_height - guess_box_height) / 2
guess_box_visible = False
player_is_guessing = False
top_open_card_available_positions = [(top_open_card_area_x + i * (player_card_width + 20), top_open_card_area_y) for i
                                     in range(3)]
bottom_open_card_available_positions = [
    (bottom_open_card_area_x + i * (player_card_width + 20), bottom_open_card_area_y) for i in range(3)]
selected_player_cards = []
button1_clicked = False
button2_clicked = False
result_box_visible = False
result_text = ""
result_box_width = 660
result_box_height = 150
result_box_x = (window_width - result_box_width) // 2
result_box_y = (window_height - result_box_height) // 2
restart_button_visible = False
restart_button_width = button_width
restart_button_height = button_height
restart_button_x = result_box_x + (result_box_width - restart_button_width) // 2
restart_button_y = result_box_y + result_box_height - restart_button_height - 20 + 50  #
restart_button_clicked = False
card_name_mapping = {
    "em": "恶魔",
    "fk": "方块",
    "ht": "黑桃",
    "hx": "红心",
    "mh": "梅花"
}
pygame.mixer.music.load(resource_path(r'music\bgm.mp3')) # 加载背景音乐文件
pygame.mixer.music.set_volume(0.5)  # 设置背景音乐音量(可根据需要调整)
pygame.mixer.music.play(-1)  # 循环播放背景音乐
click_sound = pygame.mixer.Sound(resource_path(r'music\yx.mp3'))  # 加载点击音效文件
def handle_mingpai(turn):
    global mingpai_used, selected_player_cards
    if (turn == "player" and player_round > 1) or \
            (turn == "computer" and computer_round > 1) or \
            mingpai_used[turn] or has_guessed:
        return
    if turn == "player":
        if not selected_player_cards:
            return
        for card_pos in selected_player_cards:
            card_name = card_assignments[card_pos]
            new_pos = bottom_open_card_available_positions.pop(0)
            card_assignments[new_pos] = card_name
            del card_assignments[card_pos]
            if deck_positions:
                new_deck_pos = random.choice(deck_positions)
                new_card_name = card_assignments[new_deck_pos]
                card_assignments[card_pos] = new_card_name
                del card_assignments[new_deck_pos]
                deck_positions.remove(new_deck_pos)
        selected_player_cards = []
        mingpai_used[turn] = True
    elif turn == "computer":
        num_to_mingpai = random.choice([1, 2, 3])
        selected_cards = random.sample(computer_hand_card_positions, num_to_mingpai)
        for card_pos in selected_cards:
            card_name = card_assignments[card_pos]
            new_pos = top_open_card_available_positions.pop(0)
            card_assignments[new_pos] = card_name
            del card_assignments[card_pos]
            if deck_positions:
                new_deck_pos = random.choice(deck_positions)
                new_card_name = card_assignments[new_deck_pos]
                card_assignments[card_pos] = new_card_name
                del card_assignments[new_deck_pos]
                deck_positions.remove(new_deck_pos)
        mingpai_used[turn] = True
def handle_guess(turn):
    global has_guessed, current_turn, result_box_visible, result_text, player_round, computer_round, guess_box_visible, player_is_guessing
    if has_guessed:
        return
    if turn == "player":
        guess_box_visible = True
        player_is_guessing = True
    elif turn == "computer":
        guess_card = random.choice(["em", "fk", "ht", "hx", "mh"])
        target_card = card_assignments[target_card_position]
        if guess_card == target_card:
            result_text = f"对手猜中目标牌为:{card_name_mapping[target_card]},游戏结束"
        else:
            result_text = f"对手猜测目标牌为:{card_name_mapping[guess_card]},猜测错误,游戏继续"
        result_box_visible = True
        has_guessed = guess_card == target_card
        if not has_guessed:
            current_turn = "player"
            computer_round = 2  # 新增行
def reset_game():
    global card_list, card_assignments, all_positions, current_turn, player_round, computer_round, mingpai_used, has_guessed, \
        guess_box_visible, result_box_visible, result_text, selected_player_cards, top_open_card_available_positions, bottom_open_card_available_positions, deck_positions, restart_button_visible, player_is_guessing
    card_list = ["em", "fk", "ht", "hx", "mh"] * 3
    random.shuffle(card_list)
    deck_positions.clear()
    for i in range(2):
        for j in range(4):
            x = deck_x + j * (deck_card_width + 20)
            y = deck_y + i * (deck_card_height + 20)
            deck_positions.append((x, y))
    all_positions = computer_hand_card_positions + player_hand_card_positions + [target_card_position] + deck_positions
    card_assignments = dict(zip(all_positions, card_list))
    current_turn = "player" if player_first else "computer"
    player_round = 1
    computer_round = 1
    mingpai_used = {"player": False, "computer": False}
    has_guessed = False
    guess_box_visible = False
    result_box_visible = False
    result_text = ""
    selected_player_cards = []
    restart_button_visible = False
    player_is_guessing = False
    top_open_card_available_positions = [(top_open_card_area_x + i * (player_card_width + 20), top_open_card_area_y) for
                                         i in range(3)]
    bottom_open_card_available_positions = [
        (bottom_open_card_area_x + i * (player_card_width + 20), bottom_open_card_area_y) for i in range(3)]
def computer_action():
    global current_turn, computer_round, mingpai_used
    if computer_round == 1:
        if random.random()  0:
                    prefix = result_text[0:start_idx]
                    text_surface = font.render(prefix, True, (255, 255, 255))
                    screen.blit(text_surface, (text_x, text_y))
                    text_x += text_surface.get_width()
                text_surface = font.render(card_chinese, True, (255, 100, 100))
                screen.blit(text_surface, (text_x, text_y))
                text_x += text_surface.get_width()
                suffix = result_text[end_idx:]
                text_surface = font.render(suffix, True, (255, 255, 255))
                screen.blit(text_surface, (text_x, text_y))
                break
        else:
            text_surface = font.render(result_text, True, (255, 255, 255))
            screen.blit(text_surface, (text_x, text_y))
        if has_guessed:
            if restart_button_visible:
                screen.blit(button_images["clicked" if restart_button_clicked else "normal"],
                            (restart_button_x, restart_button_y))
            text_surface = font.render("再来一局", True, (255, 255, 255))
            text_rect = text_surface.get_rect(
                center=(restart_button_x + restart_button_width / 2, restart_button_y + restart_button_height / 2))
            screen.blit(text_surface, text_rect)
            restart_button_visible = True
    # 电脑先手处理
    if current_turn == "computer" and not has_guessed and computer_round == 1 and not mingpai_used[
        "computer"] and not result_box_visible and not guess_box_visible:
        computer_action()
        current_turn = "player"
    pygame.display.flip()
pygame.quit()

先手, 明牌

volo
OP
  


ydafu168 发表于 2025-4-26 11:41
怎么分开问?用的是什么Ai?

deepseek 一步步分开问,先让他做布局图,然后一个功能一个功能的加,写逻辑修bug,最后美化一下就好了。一次性把规则给他说,他可以理解但是做不出来,做出来的不能用
mscm123   

进来看看
qwaa   

直接看成“五一”猜牌游戏了
QT2008   

AI写代码的逻辑看着可以啊
iefydi   

看看怎么样
ashirogimuto   

AI已经这么强了啊
volo
OP
  


ashirogimuto 发表于 2025-4-26 09:23
AI已经这么强了啊

确实有点强,但是要分开问,一下做不出来。ai写的也会出bug,可能是沟通问题
ydafu168   


volo 发表于 2025-4-26 09:27
确实有点强,但是要分开问,一下做不出来。ai写的也会出bug,可能是沟通问题

怎么分开问?用的是什么Ai?
追风营销   


volo 发表于 2025-4-26 12:03
deepseek 一步步分开问,先让他做布局图,然后一个功能一个功能的加,写逻辑修bug,最后美化一下就好了。 ...

别开启思考功能联网他就会按照设计完成
您需要登录后才可以回帖 登录 | 立即注册

返回顶部