Python Pygame制作简单五子棋游戏

代码参考自:https://blog.csdn.net/weixin_43918046/article/details/119521845
新增功能:1任意棋盘大小;2.任意棋子连线

# 棋盘大小 [670, 670] 
# 棋盘行列 15*15
import pygame
from pygame.locals import QUIT, KEYDOWN
import numpy as np
import time

line_space=44
screen_margin=27
row=col=17
# screen_size=(670, 670) # 27*2+44*14
screen_row=(row-1)*line_space+screen_margin*2
screen_col=(col-1)*line_space+screen_margin*2
screen_size=(screen_row,screen_col )
screen_color = [238, 154, 73]
line_color=[0,0,0]
prompt_box_color=[0, 229, 238]
stage = np.zeros((row, col))
white_color = [255, 255, 255]  # 白棋颜色
black_color = [0, 0, 0]  # 黑棋颜色
victory_color=[238,48,167]
line=5 # 五颗棋子
# 设置鼠标时延
flag = False
tim = 0

def find_pos(x, y):
    x=int((x-screen_margin)/line_space+0.5)
    y=int((y-screen_margin)/line_space+0.5)
    x=x if x<=(row-1) else row-1
    y=y if y<=(col-1) else col-1
    return x,y
def find_line_consecutive_ones_v2(matrix, line):
    victory_list_v2=[]
    a=find_line_consecutive_ones(matrix, line)
    b=find_line_consecutive_ones(matrix*(-1), line)
    victory_list_v2.extend(a)
    victory_list_v2.extend(b)
    return victory_list_v2
def my_range(start,end):
    if start<end:
        return range(start,end+1)
    else:
        return range(start,end-1,-1)
def find_line_consecutive_ones(matrix, line):
    victory_list=[]
    w, h = matrix.shape
    # 水平方向
    for row_index, row in enumerate(matrix):
        for col_index in range(len(row) - (line - 1)):
            if np.all(row[col_index:col_index + line] == 1):
                r,c=row_index,col_index
                victory_list.append([[r,c+i] for i in range(line) ])

    # 垂直方向
    for col_index in range(matrix.shape[1]):
        for row_index in range(matrix.shape[0] - (line - 1)):
            if np.all(matrix[row_index:row_index + line, col_index] == 1):
                r, c = row_index, col_index
                victory_list.append([[r+i, c] for i in range(line )])

    # 正对角线方向
    for diag in range(-(w - line), (h - line) + 1):
        diagonal = np.diag(matrix, k=diag)
        # print(diagonal)
        if len(diagonal) >= line:
            for start in range(len(diagonal) - (line - 1)):
                if np.all(diagonal[start:start + line] == 1):
                    start_row = max(0, -diag) + start
                    start_col = max(0, diag) + start
                    end_row = start_row + line-1
                    end_col = start_col + line-1
                    r=[i for i in my_range(start_row,end_row)]
                    c=[i for i  in my_range(start_col,end_col)]
                    rc=[i for i in zip(r,c)]
                    victory_list.append(rc)

    # 反对角线方向
    for diag in range(-(w - line), (h - line) + 1):
        diagonal = np.diag(np.fliplr(matrix), k=diag)
        # print(diagonal)
        if len(diagonal) >= line:
            for start in range(len(diagonal) - (line - 1)):
                if np.all(diagonal[start:start + line] == 1):
                    start_row = max(0, -diag) + start
                    start_col = min(h - 1, h - 1 - diag) - start
                    end_row = start_row + line-1
                    end_col = start_col - line+1
                    r=[i for i in my_range(start_row,end_row)]
                    c=[i for i  in my_range(start_col,end_col)]
                    rc=[i for i in zip(r,c)]
                    victory_list.append(rc)
    return victory_list
    
# 初始化pygame
pygame.init()
# 获取对显示系统的访问,并创建一个窗口screen
# 窗口大小为670x670
screen = pygame.display.set_mode(screen_size)
while True:  # 不断训练刷新画布
    for event in pygame.event.get():  # 获取事件,如果鼠标点击右上角关闭按钮,关闭
        if event.type in (QUIT, KEYDOWN):
            sys.exit()
    screen.fill(screen_color)  # 清屏

    col_lines = [[[screen_margin+i*line_space, screen_margin], [screen_margin +
                                                                i*line_space, screen_margin+(col-1)*line_space]] for i in range(col)]
    for i, xy_xy in enumerate(col_lines):
        line_thickness = 2
        if i == 0 or i == len(col_lines)-1:
            line_thickness = 4
        pygame.draw.line(screen, line_color,
                         xy_xy[0], xy_xy[1], line_thickness)

    row_lines = [[[screen_margin, screen_margin+i*line_space], [screen_margin +
                                                                (row-1)*line_space, screen_margin+i*line_space]] for i in range(row)]
    for i, xy_xy in enumerate(row_lines):
        line_thickness = 2
        if i == 0 or i == len(row_lines)-1:
            line_thickness = 4
        pygame.draw.line(screen, line_color,
                         xy_xy[0], xy_xy[1], line_thickness)

    pygame.draw.circle(screen, line_color, [screen_row/2, screen_col/2], 8, 0)
    for x in range(stage.shape[0]):  # 外层循环遍历行
        for y in range(stage.shape[1]):  # 内层循环遍历列
            if stage[x][y] == 0:
                continue
            play_color = black_color if stage[x][y] == -1 else white_color
            pygame.draw.circle(screen, play_color, [
                               screen_margin+x*line_space, screen_margin+y*line_space], 20, 0)
    res = find_line_consecutive_ones_v2(stage, line)
    time.sleep(0.1)
    if len(res) > 0:
        for ret in res:
            for x, y in ret:
                pygame.draw.rect(screen, victory_color, [screen_margin + int(
                    (x-0.5)*line_space), screen_margin+int((y-0.5)*line_space), line_space, line_space], 2, 1)
        pygame.display.update()  # 刷新显示
        continue  # 游戏结束,停止下面的操作

        # 获取鼠标坐标信息
    x, y = pygame.mouse.get_pos()

    x, y = find_pos(x, y)
    if stage[x][y] == 0:
        pygame.draw.rect(screen, prompt_box_color, [screen_margin + int(
            (x-0.5)*line_space), screen_margin+int((y-0.5)*line_space), line_space, line_space], 2, 1)

    if pygame.mouse.get_pressed()[0] and tim == 0:
        flag = True
        if stage[x][y] == 0:  # 判断是否可以落子,再落子
            if np.sum(stage == 0) % 2 == 0:  # 黑子
                stage[x][y] = -1
            else:
                stage[x][y] = 1
        # 鼠标左键延时作用
    if flag:
        tim += 1
    if tim % 10 == 0:  # 延时200ms
        flag = False
        tim = 0

    pygame.display.update()  # 刷新显示

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值