简单的Python五子棋

一个简单的 Python 五子棋


初学Python,设计了一款简单的五子棋游戏。水平有限,欢迎批评指正

代码详见: https://gitee.com/liio/gobang

目录结构如下

卷 DATA 的文件夹 PATH 列表
卷序列号为 207A-076D
/.
│  gobang.py        // 五子棋类文件
│  thread_stop.py   // 线程停止文件(由于我的 tk_game.py 写的不是很好所以需要辅助关闭进程)
│  tk_game.py       // UI 界面
│  
└─source     
    └─img
            background.png
            background_c.png
            chessboard.png
            icon.ico
            icon.png 

gobang.py 文件的分析:

主界面

输赢判断

在这里插入图片描述

def isWin(self, line_list=None):
        if line_list is None:
            line_list = self.arround()
        for line in line_list:
            if line[0].count(self.__playerid) >= 5:
                for i in range(0, len(line[0]) - 4):
                    if line[0][i] == line[0][i + 1] == line[0][i + 2] == line[
                            0][i + 3] == line[0][i + 4] == self.__playerid:
                        return True
        else:
            return False

    def arround(self=None, row=0, column=0):
        if self is not None:
            if len(self.getStep()) != 0:
                row = ord(list(self.getStep().items())[-1][1][0]) - 97
                column = ord(list(self.getStep().items())[-1][1][1]) - 97
            else:
                row = 7
                column = 7
        line_list, line_list1, line_list2, line_list3, line_list4 = [], [], [], [], []
        line_list1_, line_list2_, line_list3_, line_list4_ = [], [], [], []
        # 获取一整行
        line_list1 = [list(Chess.__checkerboard[row])]
        for i in range(len(Chess.__checkerboard[row])):
            line_list1_.append([row, i])
        line_list1.append(line_list1_)
        # 获取一整列
        line_list2 = [list(Chess.__checkerboard.T[column])]
        for i in range(len(Chess.__checkerboard.T[column])):
            line_list2_.append([i, column])
        line_list2.append(line_list2_)
        # 获取正斜线
        if row >= column:
            for i in range(14 - abs(row - column) + 1):
                line_list3.append(Chess.__checkerboard[i +
                                                       abs(row - column)][i])
            line_list3 = [line_list3]
            for i in range(14 - abs(row - column) + 1):
                line_list3_.append([i + abs(row - column), i])
            line_list3.append(line_list3_)
        if row < column:
            for i in range(14 - abs(row - column) + 1):
                line_list3.append(Chess.__checkerboard[i][i +
                                                          abs(row - column)])
            line_list3 = [line_list3]
            for i in range(14 - abs(row - column) + 1):
                line_list3_.append([i, i + abs(row - column)])
            line_list3.append(line_list3_)
        # 获取反斜线
        if row + column <= 14:
            for i in range(row + column + 1):
                line_list4.append(Chess.__checkerboard[i][row + column - i])
            line_list4 = [line_list4]
            for i in range(row + column + 1):
                line_list4_.append([i, row + column - i])
            line_list4.append(line_list4_)
        if row + column > 14:
            for i in range(28 - (row + column) + 1):
                line_list4.append(
                    Chess.__checkerboard[14 - i][14 - (28 -
                                                       (row + column) - i)])
            line_list4 = [line_list4]
            for i in range(28 - (row + column) + 1):
                line_list4_.append([14 - i, 14 - (28 - (row + column) - i)])
            line_list4.append(line_list4_)
        line_list.append(list(line_list1))
        line_list.append(list(line_list2))
        line_list.append(line_list3)
        line_list.append(line_list4)
        return line_list
计算机执子

在这里插入图片描述

def aiChess():
    def get_score(id):
        score = [[1, [0, 0, 0, 0, id], [1, 2, 4, 6, 0]],
                 [1, [id, 0, 0, 0, 0], [0, 6, 4, 2, 1]],
                 [1, [0, 0, 0, id, 0], [2, 4, 6, 0, 1]],
                 [1, [0, id, 0, 0, 0], [1, 0, 6, 4, 2]],
                 [10, [0, 0, id, 0, 0], [1, 10, 0, 10, 1]],
                 [50, [0, id, id, 0, 0], [50, 0, 0, 50, 10]],
                 [50, [0, 0, id, id, 0], [10, 50, 0, 0, 50]],
                 [50, [0, id, 0, id, 0], [10, 0, 50, 0, 10]],
                 [200, [id, id, 0, id, 0], [0, 0, 200, 0, 50]],
                 [500, [0, 0, id, id, id], [50, 200, 0, 0, 0]],
                 [500, [id, id, id, 0, 0], [0, 0, 0, 200, 50]],
                 [5000, [0, id, id, id, 0], [200, 0, 0, 0, 200]],
                 [5000, [0, id, 0, id, id, 0], [200, 0, 500, 0, 0, 200]],
                 [5000, [0, id, id, 0, id, 0], [200, 0, 0, 500, 0, 200]],
                 [5000, [id, id, id, 0, id], [0, 0, 0, 500, 0]],
                 [5000, [id, id, 0, id, id], [0, 0, 500, 0, 0]],
                 [5000, [id, 0, id, id, id], [0, 50000, 0, 0, 0]],
                 [5000, [id, id, id, id, 0], [0, 0, 0, 0, 50000]],
                 [5000, [0, id, id, id, id], [50000, 0, 0, 0, 0]],
                 [99999999, [id, id, id, id, id], [0, 0, 0, 0, 0]]]
        return score

    def dict_span(dict1: dict, dict2: dict):
        weight = 100
        dict1_keys = list(dict1.keys())
        dict2_keys = list(dict2.keys())
        re_dict = {}
        for key in dict1_keys:
            if key in dict2_keys:
                re_dict[key] = (dict1[key] *
                                dict2[key]) / weight + dict2[key] + dict1[key]
            else:
                re_dict[key] = dict1[key]
        for key in dict2_keys:
            if key not in dict1_keys:
                re_dict[key] = dict2[key]

        return re_dict

    def get_p_score(id):
        p_score = {}
        for s_line in get_score(id):
            for _ in traversal_checkerboard():
                for i in _:
                    for j in range((len(i[0]) - len(s_line[1])) + 1):
                        if i[0][j:len(s_line[1]) + j] == s_line[1]:
                            for p in range(
                                    len(i[0][j + 1:len(s_line[1]) + j + 1])):
                                if str(i[0][j + 1:len(s_line[1]) + j +
                                            1][p]) in p_score:
                                    p_score[str(
                                        i[1][j:len(s_line[1]) + j]
                                        [p])] += s_line[0] * s_line[2][p]
                                else:
                                    p_score[str(
                                        i[1][j:len(s_line[1]) +
                                             j][p])] = s_line[0] * s_line[2][p]
        return p_score

    score = get_p_score(2)
    score_my = get_p_score(1)
    score = dict_span(score, score_my)
    if len(score) == 0:
        score = dict_span(score, score_my)

    return (eval(max(score, key=score.get))[0], eval(max(score,
                                                         key=score.get))[1])


def dicttoChees(step_dict):
    Chess.step = step_dict.copy()
    for r in range(len(Chess._Chess__checkerboard)):
        for c in range(len(Chess._Chess__checkerboard[r])):
            Chess._Chess__checkerboard[r][c] = 0
    if len(step_dict) != 0:
        for step in step_dict.items():
            row = ord(step[1][0]) - 97
            column = ord(step[1][1]) - 97
            if step[0] % 2 == 0:
                Chess._Chess__checkerboard[row][column] = 2
            elif step[0] % 2 == 1:
                Chess._Chess__checkerboard[row][column] = 1

tk_game.py 分析


在这里插入图片描述

点击落子
def click(event):
    if not w.isWin() and not b.isWin():
        ismove_x = False
        ismove_y = False
        if 10 < event.x < 650 and 10 < event.y < 650:
            if (event.x - START) % LENGTH < 20:
                x = (event.x - START) // LENGTH
                ismove_x = True
            elif (event.x - START) % LENGTH > 24:
                x = ((event.x - START) // LENGTH) + 1
                ismove_x = True
            if (event.y - START) % LENGTH < 20:
                y = (event.y - START) // LENGTH
                ismove_y = True
            elif (event.y - START) % LENGTH > 24:
                y = ((event.y - START) // LENGTH) + 1
                ismove_y = True
            if ismove_x and ismove_y:
                move(y, x)
移动提示
def sign(event):
    # 获取鼠标实时位置,做出提示
    # time.sleep(0.08)
    canvas.delete("Sign")
    ismove_x = False
    ismove_y = False
    if 10 < event.x < 650 and 10 < event.y < 650 and not w.isWin(
    ) and not b.isWin():
        if (event.x - START) % LENGTH < 20:
            x = (event.x - START) // LENGTH
            ismove_x = True
        elif (event.x - START) % LENGTH > 24:
            x = ((event.x - START) // LENGTH) + 1
            ismove_x = True
        if (event.y - START) % LENGTH < 20:
            y = (event.y - START) // LENGTH
            ismove_y = True
        elif (event.y - START) % LENGTH > 24:
            y = ((event.y - START) // LENGTH) + 1
            ismove_y = True
        if ismove_x and ismove_y:
            y1 = START + (LENGTH * y) - 20
            x1 = START + (LENGTH * x) - 20
            y2 = START + (LENGTH * y) + 20
            x2 = START + (LENGTH * x) + 20
            canvas.create_oval(x1 + 15,
                               y1 + 15,
                               x2 - 15,
                               y2 - 15,
                               fill='red',
                               tags='Sign')

#####落子与绘制棋盘

def move(y, x):
    # 落子
    global times
    if not w.isWin() and not b.isWin():
        if w.isPlayer():
            if w.moveChessmen(y, x):
                draw()
        elif b.isPlayer():
            if b.moveChessmen(y, x):
                draw()
    if w.isWin():
        tkinter.messagebox.showinfo('提示', '白方获胜!')
    if b.isWin():
        tkinter.messagebox.showinfo('提示', '黑方获胜!')



def draw(step_dict=None):
    # 绘制棋盘
    canvas.delete('Piece')
    color = {1: 'black', 0: 'white'}
    if step_dict is None:
        step_dict = Chess.getStep().copy()
    for step in step_dict.items():
        row = ord(step[1][0]) - 97
        column = ord(step[1][1]) - 97
        y1 = START + (LENGTH * row) - 20
        x1 = START + (LENGTH * column) - 20
        y2 = START + (LENGTH * row) + 20
        x2 = START + (LENGTH * column) + 20
        canvas.create_oval(x1,
                           y1,
                           x2,
                           y2,
                           fill=color[(step[0] % 2)],
                           tags='Piece')
        if step[0] == len(step_dict.items()):
            canvas.create_oval(x1 + 15,
                               y1 + 15,
                               x2 - 15,
                               y2 - 15,
                               fill='pink',
                               tags='Piece')
        if order:
            canvas.create_text(x1 + 20,
                               y1 + 20,
                               text=str(step[0]),
                               fill=color[int(not bool((step[0] % 2)))],
                               tags='Piece')
    # print(draw_list) # 测试输出
打开与保存棋谱

在这里插入图片描述

def open_gs():
    # 打开棋谱文件 TODO
    gs_file = tkinter.filedialog.askopenfilename(title="选择棋谱",
                                                 initialdir=ex_folder,
                                                 filetypes=[("棋谱文件", ".sgf"),
                                                            ("棋谱文件", ".gbs"),
                                                            ("Gobang棋谱文件",
                                                             ".gbs")])
    if gs_file != '':
        try:
            with open(gs_file, encoding='utf-8') as f:
                gs_text = f.read()
        except UnicodeDecodeError:
            with open(gs_file) as f:
                gs_text = f.read()
        finally:
            step_dict = {}
            step_list = re.findall(r"[\[']([a-z][a-z])['\]]", gs_text)
            for i in range(len(step_list)):
                step_dict[i + 1] = step_list[i]
            score_mode(step_dict)


def save_gbs():
    # 保存棋谱文件 `gbs` 格式
    gbs_data = tkinter.filedialog.asksaveasfile(mode='w',
                                                title="选择棋谱",
                                                initialdir=ex_folder,
                                                defaultextension=".espace",
                                                filetypes=[("Gobang棋谱文件",
                                                            ".gbs")])
    if gbs_data is not None:
        gbs_data.write(str(Chess.getStep()))

猜你喜欢

转载自blog.csdn.net/weixin_43540317/article/details/106834520