qt 五子棋python python五子棋原理_qt 五子棋python


继续介绍python游戏编程,仍然是基于pgzero。关于该软件包的基础使用技巧可参考本人专栏文章:

老娄:python游戏编程之pgzero使用介绍zhuanlan.zhihu.com

qt 五子棋python python五子棋原理_游戏编程_02


思考

  • 绘制棋盘。五子棋的棋盘是15*15的表格,所以就是画交叉的直线即可。可以使用screen.draw.line来实现,它接受3个参数:起点坐标、终点坐标、线的颜色。
def


显示的效果如下图所示:


qt 五子棋python python五子棋原理_游戏编程_03


  • 关于走棋。鼠标可以在任何位置单击,所以不是一个精准的事件,我们已经知道def


qt 五子棋python python五子棋原理_游戏编程_04


同时,在落棋时,还要判断是否本点上已经有其它棋子。这里想到可以用一个0,1的二维矩阵来刻画每个位置上是否有棋子。这里使用的逻辑是:


chess_black = []
chess_white = []
def on_mouse_down(pos):
    # print("Mouse button clicked at", pos)
    click_x, click_y = pos
    #计算落在第几行、第几列的交叉点上
    xs,zs = math.modf((click_x - 20) / SIZE)  #获取小数、整数部分
    if xs > 0.5:
        x = int(zs + 1)
    else:
        x = int(zs)

    xs_y,zs_y = math.modf((click_y - 20) / SIZE)
    if xs_y > 0.5:
        y = int(zs_y + 1)
    else:
        y = int(zs_y)

    if matrix[y][x] != 1:
        chess = Actor("gobang_black")
        chess.x = x * SIZE + 20
        chess.y = y * SIZE + 20
        matrix[y][x] = 1
        chess_black.append(chess)


事实上,我们需要轮流走黑、白两种颜色的棋子,可以通过一个全局变量来实现,当黑棋走过后,手工将该全局变量置为另一种颜色即可。

  • 是否结束。当落一子的时候,就要判断一下是否游戏可以结束了:横、竖、斜有5个同色棋子。

完整代码


import pgzrun
import pgzero
import math
import numpy

SIZE = 40
WIDTH = 15 * SIZE
HEIGHT = 15 * SIZE

#初始化每个坐标位,0表示没有棋子
matrix = [[0]*15 for i in range(15)]

chess_black = []
chess_white = []
global turn
turn = "black"

global FINISH
FINISH = False

def draw():
    screen.fill((210,180,140))
    for i in range(15):
        screen.draw.line((20,20+SIZE*i),(20+SIZE*14,20+SIZE*i),(0,0,0))   #周边稍有留白
    for i in range(15):
        screen.draw.line((20+SIZE*i, 20), (20+SIZE*i,20 + SIZE * 14), (0, 0, 0))

    for b in chess_black:
        b.draw()
    for b in chess_white:
        b.draw()

    if FINISH:
        screen.draw.text("GAME OVER", topleft=(20, 100), color="green", fontsize=80)
        return

def on_mouse_down(pos):
    global turn
    # print("Mouse button clicked at", pos)
    click_x, click_y = pos
    #计算落在第几行、第几列的交叉点上
    xs,zs = math.modf((click_x - 20) / SIZE)  #获取小数、整数部分
    if xs > 0.5:
        x = int(zs + 1)
    else:
        x = int(zs)

    xs_y,zs_y = math.modf((click_y - 20) / SIZE)
    if xs_y > 0.5:
        y = int(zs_y + 1)
    else:
        y = int(zs_y)

    if matrix[y][x] == 0:
        if turn == "black":
            chess = Actor("gobang_black")
            chess.x = x * SIZE + 20
            chess.y = y * SIZE + 20
            matrix[y][x] = 1
            chess_black.append(chess)
            turn = "white"
            check_finish(y, x)
            print(FINISH)
        elif turn == "white":
            chess = Actor("gobang_white")
            chess.x = x * SIZE + 20
            chess.y = y * SIZE + 20
            matrix[y][x] = -1
            chess_black.append(chess)
            turn = "black"
            check_finish(y, x)
            # print(FINISH)
        else:
            pass

def check_finish(i,j):
# i,j 表示 matrix的第i行,第j列
    global FINISH
    #判断横向
    if [1,1,1,1,1] in [matrix[i][j:j+5], matrix[i][j-1:j+4],matrix[i][j-2:j+3],matrix[i][j-3:j+2],matrix[i][j-4:j+1],matrix[i][j-5:j]] or [-1,-1,-1,-1,-1] in [matrix[i][j:j+5], matrix[i][j-1:j+4],matrix[i][j-2:j+3],matrix[i][j-3:j+2],matrix[i][j-4:j+1]]:
        FINISH = True
        return
    #判断纵向
    mat = numpy.mat(matrix)
    for x in range(-5,1):
        y = 5 - abs(x)
        col = mat[i+x:i+y,j]
        col_list = [i[0] for i in col.tolist()]
        if col_list == [1,1,1,1,1] or col_list == [-1,-1,-1,-1,-1]:
            FINISH = True
            return
    #判断斜向
    col_list = []
    for x in range(-4,5):
        if i + x >= 0 and i + x < 15 and j + x >= 0 and j + x < 15:
            col_list.append(mat[i+x,j+x])
            if col_list == [1,1,1,1,1] or col_list == [-1,-1,-1,-1,-1]:
                FINISH = True
                return

    col_list = []
    for x in range(-4,5):
        if i + x >= 0 and i+x < 15 and j - x >= 0 and j-x < 15:
            col_list.append(mat[i+x,j-x])
            if col_list == [1,1,1,1,1] or col_list == [-1,-1,-1,-1,-1]:
                FINISH = True
                return

pgzrun.go()


参考资料

《趣学python游戏编程》何青 著