猫史档案馆


az,大家来看看,用chatgpt写的α-β博弈树剪枝算法的五子棋ai

用户:rattlerrattler查看:0 回复:2 评论:0 创建时间:2023-04-15T20:35:17


import numpy as np

# 棋盘大小
BOARD_SIZE = 15
# 空位置表示
EMPTY = 0
# 黑色棋子表示
BLACK = 1
# 白色棋子表示
WHITE = -1
# 评估函数中的棋型定义
FIVE = 1e6
FOUR = 1e5
BLOCKED_FOUR = 1e4
THREE = 1e3
BLOCKED_THREE = 1e2
TWO = 10
BLOCKED_TWO = 5
ONE = 1

# alpha-beta搜索深度
SEARCH_DEPTH = 4

class AlphaBetaAI:
    def __init__(self, color):
        self.color = color
        
    # 获取可放置棋子的位置列表
    def get_legal_actions(self, chessboard):
        actions = []
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if chessboard[i][j] == EMPTY:
                    actions.append((i, j))
        return actions
    
    # 判断某个位置是否越界
    def is_out_of_board(self, x, y):
        if x < 0 or y < 0 or x >= BOARD_SIZE or y >= BOARD_SIZE:
            return True
        return False
    
    # 判断当前局面下是否存在五子连珠
    def is_win(self, chessboard, color):
        dir = [[0, 1], [1, 0], [1, 1], [1, -1]]
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if chessboard[i][j] == color:
                    for k in range(4):
                        x = i + dir[k][0]
                        y = j + dir[k][1]
                        if self.is_out_of_board(x, y) or chessboard[x][y] != color:
                            continue
                        for l in range(2, 6):
                            x = i + dir[k][0] * l
                            y = j + dir[k][1] * l
                            if self.is_out_of_board(x, y) or chessboard[x][y] != color:
                                break
                        if l == 5:
                            return True
        return False
    
    # 获取棋盘上空闲位置的数量
    def get_empty_count(self, chessboard):
        count = 0
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if chessboard[i][j] == EMPTY:
                    count += 1
        return count
    
    # 评估函数
    def evaluate(self, chessboard):
        score = 0
        dir = [[0, 1], [1, 0], [1, 1], [1, -1]]
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if chessboard[i][j] != EMPTY:
                    for k in range(4):
                        color_count = 0
                        empty_count = 0
                        blocked_flag = False
                        for l in range(-5, 6):
                            x = i + dir[k][0] * l
                            y = j + dir[k][1] * l
                            if self.is_out_of_board(x, y):
                                continue
                            if chessboard[x][y] == self.color:
                                color_count += 1
                            elif chessboard[x][y] == EMPTY:
                                if empty_count == 0 and l < 0:
                                    blocked_flag = True
                                empty_count += 1
                            else:
                                if l < 0:
                                    blocked_flag = True
                                break
                        if color_count == 0:
                            continue
                        elif color_count == 1:
                            if empty_count == 2:
                                score += TWO
                            elif empty_count == 3:
                                score += BLOCKED_TWO if blocked_flag else TWO
                            elif empty_count == 4:
                                score += BLOCKED_THREE if blocked_flag else THREE
                        elif color_count == 2:
                            if empty_count == 1:
                                score += BLOCKED_TWO if blocked_flag else TWO
                            elif empty_count == 2:
                                score += BLOCKED_THREE if blocked_flag else THREE
                            elif empty_count == 3:
                                score += BLOCKED_FOUR if blocked_flag else FOUR
                        elif color_count == 3:
                            if empty_count == 1:
                                score += BLOCKED_THREE
                            elif empty_count == 2:
                                score += BLOCKED_FOUR if blocked_flag else FOUR
                        else:
                            score += FIVE
        return score
    
    # 极大值函数
    def max_value(self, chessboard, alpha, beta, depth):
        if self.is_win(chessboard, self.color):
            return float('inf')
        if depth == SEARCH_DEPTH:
            return self.evaluate(chessboard)
        v = -float('inf')
        actions = self.get_legal_actions(chessboard)
        for action in actions:
            chessboard[action[0]][action[1]] = self.color
            v = max(v, self.min_value(chessboard, alpha, beta, depth+1))
            chessboard[action[0]][action[1]] = EMPTY
            if v >= beta:
                return v
            alpha = max(alpha, v)
        return v
    
    # 极小值函数
    def min_value(self, chessboard, alpha, beta, depth):
        if self.is_win(chessboard, -self.color):
            return -float('inf')
        if depth == SEARCH_DEPTH:
            return -self.evaluate(chessboard)
        v = float('inf')
        actions = self.get_legal_actions(chessboard)
        for action in actions:
            chessboard[action[0]][action[1]] = -self.color
            v = min(v, self.max_value(chessboard, alpha, beta, depth+1))
            chessboard[action[0]][action[1]] = EMPTY
            if v <= alpha:
                return v
            beta = min(beta, v)
        return v
    
    # alpha-beta剪枝搜索
    def alpha_beta_search(self, chessboard):
        best_action = None
        best_score = -float('inf')
        alpha = -float('inf')
        beta = float('inf')
        actions = self.get_legal_actions(chessboard)
        if not actions:
            return (7, 7)
        for action in actions:
            chessboard[action[0]][action[1]] = self.color
            score = self.min_value(chessboard, alpha, beta, 1)
            chessboard[action[0]][action[1]] = EMPTY
            if score > best_score:
                best_score = score
                best_action = action
            alpha = max(alpha, best_score)
        return best_action
# 初始化棋盘
chessboard = np.zeros((BOARD_SIZE, BOARD_SIZE), dtype=np.int32)

# 初始化AI
ai = AlphaBetaAI(BLACK)

# 主循环
while True:
    # 人类玩家下棋
    print("请输入你要下棋的坐标,用逗号分隔(如:7,7):")
    x, y = map(int, input().split(','))
    if chessboard[x][y] != EMPTY:
        print("这个位置已经有棋子了!")
        continue
    chessboard[x][y] = WHITE
    
    # 判断游戏是否结束
    if ai.is_win(chessboard, WHITE):
        print("你赢了!")
        break
    elif ai.get_empty_count(chessboard) == 0:
        print("平局!")
        break
    
    # AI下棋
    print("轮到我下棋了...")
    x, y = ai.alpha_beta_search(chessboard)
    print("我在 (%d, %d) 下了一步" % (x, y))
    chessboard[x][y] = BLACK
    
    # 判断游戏是否结束
    if ai.is_win(chessboard, BLACK):
        print("我赢了!")
        break
    elif ai.get_empty_count(chessboard) == 0:
        print("平局!")
        break

 

 

注意,坐标是从0开始的


回复

上一页1 页 / 共 1下一页
yee089yee089

chatgpt经常犯错的(

c++的int mn(){}(经典永流传)

顺便一提,有一次找gpt写的一发代码和我错的如出一辙h

点赞1


评论


月光之树月光之树

又一次,gpt4写的哈

正括号“[”

反括号“)”

点赞0


评论