找回密码
 中文实名注册
搜索
查看: 332|回复: 1

五子棋

[复制链接]

7

主题

72

回帖

2万

积分

超级版主

积分
21062
发表于 2025-7-4 18:41:23 | 显示全部楼层 |阅读模式
[Python] 纯文本查看 复制代码
import turtle
import random

# 设置屏幕
screen = turtle.Screen()
screen.title("五子棋小游戏 - 玩家 vs AI")
screen.setup(width=650, height=650)
screen.tracer(0)

# 常量定义
board_size = 15  # 棋盘大小 15x15
cell_size = 40  # 每个格子宽度和高度
offset_x = -cell_size * (board_size - 1) / 2
offset_y = -cell_size * (board_size - 1) / 2

# 棋盘矩阵
board = [[0 for _ in range(board_size)] for _ in range(board_size)]  # 0为空,1为玩家,2为AI

# 当前回合
player_turn = True

# 棋子画笔
pen = turtle.Turtle()
pen.hideturtle()
pen.speed(0)

# 绘制棋盘
def draw_board():
    pen.penup()
    pen.color("black")
    # 画横线
    for i in range(board_size):
        y = offset_y + i * cell_size
        pen.goto(offset_x, y)
        pen.pendown()
        pen.goto(offset_x + (board_size - 1) * cell_size, y)
        pen.penup()

    # 画竖线
    for j in range(board_size):
        x = offset_x + j * cell_size
        pen.goto(x, offset_y)
        pen.pendown()
        pen.goto(x, offset_y + (board_size - 1) * cell_size)
        pen.penup()

    # 画星位
    star_positions = [
        (3, 3), (11, 3), (3, 11), (11, 11), (7, 7)
    ]
    for x, y in star_positions:
        pen.goto(offset_x + x * cell_size, offset_y + y * cell_size)
        pen.dot(10, "black")

# 绘制棋子
def draw_piece(x, y, color):
    pen.penup()
    screen_x = offset_x + x * cell_size
    screen_y = offset_y + y * cell_size
    pen.goto(screen_x, screen_y - cell_size * 0.4)
    pen.dot(cell_size * 0.8, color)

# 检查胜负
def check_winner(x, y, player):
    """检查某个点是否形成五子连珠"""
    directions = [
        (1, 0),  # 水平
        (0, 1),  # 垂直
        (1, 1),  # 主对角线
        (1, -1)  # 副对角线
    ]
    
    for dx, dy in directions:
        count = 1  # 当前点计为1
        for step in range(1, 5):  # 向一个方向延伸
            nx, ny = x + dx * step, y + dy * step
            if 0 <= nx < board_size and 0 <= ny < board_size and board[nx][ny] == player:
                count += 1
            else:
                break
        for step in range(1, 5):  # 向反方向延伸
            nx, ny = x - dx * step, y - dy * step
            if 0 <= nx < board_size and 0 <= ny < board_size and board[nx][ny] == player:
                count += 1
            else:
                break
        if count >= 5:  # 连续5个
            return True
    return False

# 玩家回合
def on_click(x, y):
    global player_turn

    if not player_turn:  # 若不是玩家回合,忽略点击
        return

    # 将屏幕坐标转换为棋盘坐标
    board_x = round((x - offset_x) / cell_size)
    board_y = round((y - offset_y) / cell_size)

    # 检查是否在棋盘范围内
    if 0 <= board_x < board_size and 0 <= board_y < board_size:
        if board[board_x][board_y] == 0:  # 该位置为空
            board[board_x][board_y] = 1  # 玩家棋子
            draw_piece(board_x, board_y, "black")
            
            # 检查玩家是否胜利
            if check_winner(board_x, board_y, 1):
                screen.update()
                print("玩家胜利!")
                turtle.bye()
                return

            player_turn = False  # 玩家回合结束
            screen.update()
            ai_turn()  # 轮到AI

# AI回合
def ai_turn():
    global player_turn

    def evaluate_position(x, y, player):
        """对某个位置进行评分"""
        if board[x][y] != 0:
            return -1  # 已有棋子的位置不可用

        score = 0
        directions = [
            (1, 0),  # 水平
            (0, 1),  # 垂直
            (1, 1),  # 主对角线
            (1, -1)  # 副对角线
        ]

        for dx, dy in directions:
            count = 0
            for step in range(1, 5):
                nx, ny = x + dx * step, y + dy * step
                if 0 <= nx < board_size and 0 <= ny < board_size and board[nx][ny] == player:
                    count += 1
                else:
                    break
            for step in range(1, 5):
                nx, ny = x - dx * step, y - dy * step
                if 0 <= nx < board_size and 0 <= ny < board_size and board[nx][ny] == player:
                    count += 1
                else:
                    break
            score += count ** 2  # 连续棋子数量的平方作为评分

        return score

    # 找出所有空位并评分
    best_score = -1
    best_move = None
    for x in range(board_size):
        for y in range(board_size):
            if board[x][y] == 0:  # 空位
                # 优先考虑阻止玩家
                score_player = evaluate_position(x, y, 1)
                score_ai = evaluate_position(x, y, 2)
                if score_player >= 16:  # 如果玩家即将连成五子,优先阻止
                    best_move = (x, y)
                    break
                score = max(score_player, score_ai)  # 评分取攻守最大值
                if score > best_score:
                    best_score = score
                    best_move = (x, y)
        if best_move is not None and best_score >= 16:
            break

    # AI落子
    if best_move:
        x, y = best_move
        board[x][y] = 2
        draw_piece(x, y, "red")

        # 检查AI是否胜利
        if check_winner(x, y, 2):
            screen.update()
            print("AI胜利!")
            turtle.bye()
            return

    player_turn = True  # 轮到玩家
    screen.update()

# 绘制棋盘
draw_board()

# 绑定鼠标点击事件
screen.onclick(on_click)

# 保持窗口
turtle.done()

回复

使用道具 举报

8

主题

82

回帖

2446

积分

金牌会员

积分
2446
发表于 2025-7-4 18:56:45 | 显示全部楼层
  60行修改代码  pen.goto(screen_x, screen_y - cell_size * 0)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表