目录

利用-搜索的博弈树算法编写一字棋游戏-python

目录

利用α-β搜索的博弈树算法编写一字棋游戏 python

游戏规则

“一字棋"游戏(又叫"三子棋"或"井字棋”),是一款十分经典的益智小游戏。“井字棋"的棋盘很简单,是一个 3×3 的格子,很像中国文字中的"井"字,所以得名"井字棋”。“井字棋"游戏的规则与"五子棋"十分类似,“五子棋"的规则是一方首先五子连成一线就胜利;“井字棋"是一方首先三子连成一线就胜利。

极小极大分析法

设有九个空格,由 MAX,MIN 二人对弈,轮到谁走棋谁就往空格上放一只自己的棋子,谁先使自己的棋子构成"三子成一线”(同一行或列或对角线全是某人的棋子),谁就取得了胜利。

估价函数定义如下:设棋局为 P,估价函数为 e§。

(1) 若 P 对任何一方来说都不是获胜的位置,则 e§=e(那些仍为 MAX 空着的完全的行、列或对角线的总数)-e(那些仍为 MIN 空着的完全的行、列或对角线的总数)

(2) 若 P 是 MAX 必胜的棋局,则 e§=+∞ (实际上赋了 60)。

(3) 若 P 是 B 必胜的棋局,则 e§=-∞ (实际上赋了-20)。

https://i-blog.csdnimg.cn/blog_migrate/61e27b353edfa611430ab1d6b4ba5361.png

# -*- coding: utf-8 -*-

import random
import copy
import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import cholesky

class maps:

    def __init__(self,inf):#初始化

        self.matrix = [[" "]*3,[" "]*3,[" "]*3]
        for i in range(0,3):
            for j in range(0,3):
                self.matrix[i][j] = inf[i][j]
        self.cnt = 0

    def __str__(self):
        return str( self.matrix[0] ) + "\n" +str( self.matrix[1] ) + "\n" +str( self.matrix[2] ) + "\n"

    def getvalue(self):

        for i in range(0,3):

            if self.matrix[0][i] == 'X' and self.matrix[1][i] == 'X' and self.matrix[2][i] == 'X' :
                return 100
            if self.matrix[0][i] == 'O' and self.matrix[1][i] == 'O' and self.matrix[2][i] == 'O' :
                return -100

            if self.matrix[i] == ['X', 'X', 'X']:
                return 100
            if self.matrix[i] == ['O', 'O', 'O']:
                return -100

        if self.matrix[0][0] == 'X' and self.matrix[1][1] == 'X' and self.matrix[2][2] == 'X' :
            return 100
        if self.matrix[0][0] == 'O' and self.matrix[1][1] == 'O' and self.matrix[2][2] == 'O' :
            return -100
        if self.matrix[0][2] == 'X' and self.matrix[1][1] == 'X' and self.matrix[2][0] == 'X' :
            return 100
        if self.matrix[0][2] == 'O' and self.matrix[1][1] == 'O' and self.matrix[2][0] == 'O' :
            return -100

        value = 0

        for i in range(0,3):

            if self.matrix[0][i] != 'O' and self.matrix[1][i] != 'O' and self.matrix[2][i] != 'O' :
                value += 1
            if self.matrix[0][i] != 'X' and self.matrix[1][i] != 'X' and self.matrix[2][i] != 'X' :
                value -= 1

            if self.matrix[0][i] != 'O' and self.matrix[1][i] != 'O' and self.matrix[2][i] != 'O' :
                value += 1
            if self.matrix[0][i] != 'X' and self.matrix[1][i] != 'X' and self.matrix[2][i] != 'X' :
                value -= 1

        if self.matrix[0][0] != 'O' and self.matrix[1][1] != 'O' and self.matrix[2][2] != 'O' :
            value += 1
        if self.matrix[0][0] != 'X' and self.matrix[1][1] != 'X' and self.matrix[2][2] != 'X' :
            value -= 1
        if self.matrix[0][2] != 'O' and self.matrix[1][1] != 'O' and self.matrix[2][0] != 'O' :
            value += 1
        if self.matrix[0][2] != 'X' and self.matrix[1][1] != 'X' and self.matrix[2][0] != 'X' :
            value -= 1

        return value




def dfs(nowmaps , pre ,step):#博弈树核心算法

    #print(nowmaps,nowmaps.getvalue())

    if nowmaps.cnt == 9 or nowmaps.getvalue() == 100 or nowmaps.getvalue() == -100:
        return nowmaps.getvalue();

    if step % 2 ==0:
        value = 200

        for i in range(0,3):
            for j in range(0,3):
                if nowmaps.matrix[i][j] == ' ' :
                    nowmaps.matrix[i][j] = 'O'
                    nowmaps.cnt += 1
                    tmp = dfs(nowmaps,value,step+1)
                    nowmaps.cnt -= 1
                    nowmaps.matrix[i][j] = ' '
                    if tmp < value:
                        value = tmp
                    if value <= pre :
                        return value

    else:
        value = -200

        for i in range(0,3):
            for j in range(0,3):
                if nowmaps.matrix[i][j] == ' ' :
                    nowmaps.matrix[i][j] = 'X'
                    nowmaps.cnt += 1
                    tmp = dfs(nowmaps,value,step+1)
                    nowmaps.cnt -= 1
                    nowmaps.matrix[i][j] = ' '
                    if tmp > value:
                        value = tmp
                    if value >= pre :
                        return value
    return value

if **name** == '**main**':

    start = maps([[" "]*3,[" "]*3,[" "]*3])

    print(start)

    time = 0

    while True :

        if start.getvalue() == 100 or start.getvalue() == -100:
            break

        print("轮到你下棋")

        x , y = input("输入下棋的点:").split()
        x = int(x)-1
        y = int(y)-1

        start.matrix[x][y]='O'
        start.cnt += 1
        print("你下棋后")
        print(start)

        time += 1
        if time == 9:#下满了棋盘
            break

        maxvalue = -200

        for i in range(0,3):#遍历、寻找一个合适的点
            for j in range(0,3):
                if start.matrix[i][j] == ' ' :

                    start.cnt += 1
                    start.matrix[i][j] = 'X'
                    tmp = dfs(start,maxvalue,0)
                    start.matrix[i][j] = ' '
                    start.cnt -= 1
                    if tmp > maxvalue:
                        maxvalue = tmp
                        x,y=i,j

        start.matrix[x][y]='X'
        start.cnt += 1
        print("电脑下棋后")
        print(start)
        time += 1
        #break


    if start.getvalue() == -100 :
        print("胜利")
    elif start.getvalue() == 100 :
        print("失败")
    else:
        print("平局")