pygame围棋

import pygame
import random

font = "./font/方正像素12.TTF"
gamename = '围棋'

WIN_WIDTH = 1000  # 窗口宽度
WIN_HEIGHT = 694  # 窗口高度

# 初始化游戏
pygame.init()
pygame.mixer.init()

window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 创建窗口
pygame.display.set_caption(gamename)  # 设置title
pygame.display.flip()  # 初始化后第一次更新窗口

board_image = pygame.image.load("./imgs/board.png").convert_alpha()
board_image = pygame.transform.scale(board_image, (700, 694))

clock = pygame.time.Clock()
game_exit = False


def check_capture(chess_dic, x, y):
    capture_points = []
    color = chess_dic[(x, y)].color

    # 检查上下左右四个方向的棋子
    for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
        nx, ny = x + dx, y + dy
        enemy_count = 0
        enemy_list = []

        while True:
            # 到达棋盘边缘或者遇到空位,则不再继续
            if not (nx, ny) in chess_dic or chess_dic[(nx, ny)] == -1:
                break
            # 如果遇到了敌方棋子
            if chess_dic[(nx, ny)].color != color:
                enemy_count += 1
                enemy_list.append((nx, ny))
            else:
                break
            nx += dx
            ny += dy

        # 如果遇到了敌方棋子,且这些棋子被包围,则需要提子
        if enemy_count == 1 and (not (nx, ny) in chess_dic or chess_dic[(nx, ny)] == -1):
            capture_points += enemy_list

    # 提子
    for point in capture_points:
        chess_dic[point] = -1

    return capture_points


def draw_board(screen, distance):

    # 设置线条颜色
    line_color = (0, 0, 0)

    # 绘制线条
    for i in range(0, 19):
        pygame.draw.line(screen, line_color, (distance,
                         distance * (i+1)), (distance * 19, distance * (i+1)))
        pygame.draw.line(screen, line_color, (distance * (i+1),
                         distance), (distance * (i+1), distance * 19))

    # 设置星位颜色
    star_color = (0, 0, 0)

    # 绘制星位
    star_points = [(4, 4), (4, 10), (4, 16), (10, 4), (10, 10),
                   (10, 16), (16, 4), (16, 10), (16, 16)]
    for point in star_points:
        pygame.draw.circle(screen, star_color, (distance *
                           point[0], distance * point[1]), int(distance / 4))


def fillText(text, x, y, fontsize, font_color=(0, 0, 0), font_=font):
    f = pygame.font.Font(font_, fontsize)
    te = f.render(text, True, font_color)
    window.blit(te, (x, y))


def log(text):
    print(f"{gamename}: {text}")


class Chess:
    def __init__(self, screen, x, y, color):
        self.x = x + random.randint(-2, 1)
        self.y = y + random.randint(0, 2)
        self.color = color
        self.screen = screen
        self.qi = 4

    def show(self):
        pygame.draw.circle(self.screen, self.color, (self.x, self.y), 15)


def draw_cross(screen, x, y, color, size=15):
    pygame.draw.line(screen, color, (x-size, y), (x+size, y), 5)
    pygame.draw.line(screen, color, (x, y+size), (x, y-size), 5)


chess_dic = {}
# 记录棋盘交叉点
po_x11 = 35
po_y11 = 35
for i in range(19):
    for j in range(19):
        chess_dic[(round(po_x11), round(po_y11))] = -1
        po_x11 += 35
    po_x11 = 35
    po_y11 += 35

is_black_turn = True

chess_list = []
while not game_exit:

    e_x, e_y = pygame.mouse.get_pos()
    window.blit(board_image, (0, 0))
    draw_board(window, 35)
    for i in chess_dic:
        # 落点预判
        if i[0]+17 > e_x > i[0]-17 and i[1]+17 > e_y > i[1]-17 and chess_dic[i] == -1:
            if is_black_turn:
                chess_dic[i] = ("black_show", i[0], i[1])
            else:
                chess_dic[i] = ("white_show", i[0], i[1])
        elif type(chess_dic[i]) != Chess:
            if i[0]+17 > e_x > i[0]-17 and i[1]+17 > e_y > i[1]-17:
                pass
            else:
                chess_dic[i] = -1

        # 画出盘面信息
        if chess_dic[i] == -1:
            continue

        elif type(chess_dic[i]) == Chess:
            Chess.show(chess_dic[i])
            if (int((i[0]-35)/35), int((i[1]-35)/35), "black") in chess_list or (int((i[0]-35)/35), int((i[1]-35)/35), "white") in chess_list:
                pass
            else:
                if chess_dic[i].color == "black":
                    chess_list.append(
                        (int((i[0]-35)/35), int((i[1]-35)/35), "black"))
                else:
                    chess_list.append(
                        (int((i[0]-35)/35), int((i[1]-35)/35), "white"))
        elif chess_dic[i][0] == "black_show":
            draw_cross(window, chess_dic[i][1],
                       chess_dic[i][2], "black")
        elif chess_dic[i][0] == "white_show":
            draw_cross(window, chess_dic[i][1],
                       chess_dic[i][2], (232, 232, 232))

    # 游戏事件检测
    for event in pygame.event.get():
        # 鼠标点击事件
        if event.type == pygame.MOUSEBUTTONDOWN:
            for i in chess_dic:
                if i[0]+17 > e_x > i[0]-17 and i[1]+17 > e_y > i[1]-17 and type(chess_dic[i]) != Chess:
                    if is_black_turn:
                        chess_dic[i] = Chess(window, i[0], i[1], "black")
                        log(f"黑方落子:{(int((i[0]-35)/35),int((i[1]-35)/35))}")
                    else:
                        chess_dic[i] = Chess(
                            window, i[0], i[1], (232, 232, 232))
                        log(f"白方落子:{(int((i[0]-35)/35),int((i[1]-35)/35))}")
                    # 检查是否需要提子
                    capture_points = check_capture(chess_dic, i[0], i[1])
                    if capture_points:
                        log(f"有{len(capture_points)}个子被提子:{capture_points}")
                    is_black_turn = not is_black_turn
        # 点X关闭窗口
        if event.type == pygame.QUIT:
            window.fill((0, 18, 78))
            fillText("正在关闭...", (WIN_WIDTH - 100*5)/2,
                     (WIN_HEIGHT-100)/2-50, 100, "pink")
            game_exit = True

    # 画面更新
    pygame.display.update()
    clock.tick(120)
pygame.quit()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值