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

游戏规则
“一字棋"游戏(又叫"三子棋"或"井字棋”),是一款十分经典的益智小游戏。“井字棋"的棋盘很简单,是一个 3×3 的格子,很像中国文字中的"井"字,所以得名"井字棋”。"井字棋"游戏的规则与"五子棋"十分类似,"五子棋"的规则是一方首先五子连成一线就胜利;“井字棋"是一方首先三子连成一线就胜利。
极小极大分析法
设有九个空格,由 MAX,MIN 二人对弈,轮到谁走棋谁就往空格上放一只自己的棋子,谁先使自己的棋子构成"三子成一线”(同一行或列或对角线全是某人的棋子),谁就取得了胜利。
估价函数定义如下:设棋局为 P,估价函数为 e§。
(1) 若 P 对任何一方来说都不是获胜的位置,则 e§=e(那些仍为 MAX 空着的完全的行、列或对角线的总数)-e(那些仍为 MIN 空着的完全的行、列或对角线的总数)
(2) 若 P 是 MAX 必胜的棋局,则 e§=+∞ (实际上赋了 60)。
(3) 若 P 是 B 必胜的棋局,则 e§=-∞ (实际上赋了-20)。

运行截图

# -*- 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("平局")

     
  • 7
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值