如何使用python实现智能五子棋游戏

发布时间:2021-09-24 09:25:33 作者:柒染
来源:亿速云 阅读:191

如何使用python实现智能五子棋游戏,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

导语

如何使用python实现智能五子棋游戏

最热门最好玩的Python游戏点击即玩!

今天推荐的游戏是五子棋小游戏——人机对战、联机对战皆可!

你是否还记得?中学时代和同桌下过的五子棋?

如何使用python实现智能五子棋游戏

这样下棋只怕是会被打!!!!我怀疑他开挂了,并且找到了证据。

如何使用python实现智能五子棋游戏

正文

首先准备好需要的图片等素材部分如下:

如何使用python实现智能五子棋游戏如何使用python实现智能五子棋游戏

好了!直接上代码吧——设置游戏开始界面:

class gameStartUI(QWidget):
    def __init__(self, parent=None, **kwargs):
        super(gameStartUI, self).__init__(parent)
        self.setFixedSize(760, 650)
        self.setWindowTitle('五子棋游戏对战')
        self.setWindowIcon(QIcon(cfg.ICON_FILEPATH))
        # 背景图片
        palette = QPalette()
        palette.setBrush(self.backgroundRole(), QBrush(QPixmap(cfg.BACKGROUND_IMAGEPATHS.get('bg_start'))))
        self.setPalette(palette)
        # 按钮
        # --人机对战
        self.ai_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('ai'), self)
        self.ai_button.move(250, 200)
        self.ai_button.show()
        self.ai_button.click_signal.connect(self.playWithAI)
        # --联机对战
        self.online_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('online'), self)
        self.online_button.move(250, 350)
        self.online_button.show()
        self.online_button.click_signal.connect(self.playOnline)
    '''人机对战'''
    def playWithAI(self):
        self.close()
        self.gaming_ui = playWithAIUI(cfg)
        self.gaming_ui.exit_signal.connect(lambda: sys.exit())
        self.gaming_ui.back_signal.connect(self.show)
        self.gaming_ui.show()
    '''联机对战'''
    def playOnline(self):
        self.close()
        self.gaming_ui = playOnlineUI(cfg, self)
        self.gaming_ui.show()
 
 
'''run'''
if __name__ == '__main__':
    app = QApplication(sys.argv)
    handle = gameStartUI()
    font = QFont()
    font.setPointSize(12)
    handle.setFont(font)
    handle.show()
    sys.exit(app.exec_())

效果如下:

如何使用python实现智能五子棋游戏如何使用python实现智能五子棋游戏

一个是五子棋规则设置的人机对战:

import pygame
from ..misc import *
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from itertools import product
from .aiGobang import aiGobang
 
 
'''人机对战'''
class playWithAIUI(QWidget):
    back_signal = pyqtSignal()
    exit_signal = pyqtSignal()
    send_back_signal = False
    def __init__(self, cfg, parent=None, **kwargs):
        super(playWithAIUI, self).__init__(parent)
        self.cfg = cfg
        self.setFixedSize(760, 650)
        self.setWindowTitle('五子棋人机对战')
        self.setWindowIcon(QIcon(cfg.ICON_FILEPATH))
        # 背景图片
        palette = QPalette()
        palette.setBrush(self.backgroundRole(), QBrush(QPixmap(cfg.BACKGROUND_IMAGEPATHS.get('bg_game'))))
        self.setPalette(palette)
        # 按钮
        self.home_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('home'), self)
        self.home_button.click_signal.connect(self.goHome)
        self.home_button.move(680, 10)
        self.startgame_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('startgame'), self)
        self.startgame_button.click_signal.connect(self.startgame)
        self.startgame_button.move(640, 240)
        self.regret_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('regret'), self)
        self.regret_button.click_signal.connect(self.regret)
        self.regret_button.move(640, 310)
        self.givein_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('givein'), self)
        self.givein_button.click_signal.connect(self.givein)
        self.givein_button.move(640, 380)
        # 落子标志
        self.chessman_sign = QLabel(self)
        sign = QPixmap(cfg.CHESSMAN_IMAGEPATHS.get('sign'))
        self.chessman_sign.setPixmap(sign)
        self.chessman_sign.setFixedSize(sign.size())
        self.chessman_sign.show()
        self.chessman_sign.hide()
        # 棋盘(19*19矩阵)
        self.chessboard = [[None for i in range(19)] for _ in range(19)]
        # 历史记录(悔棋用)
        self.history_record = []
        # 是否在游戏中
        self.is_gaming = True
        # 胜利方
        self.winner = None
        self.winner_info_label = None
        # 颜色分配and目前轮到谁落子
        self.player_color = 'white'
        self.ai_color = 'black'
        self.whoseround = self.player_color
        # 实例化ai
        self.ai_player = aiGobang(self.ai_color, self.player_color)
        # 落子声音加载
        pygame.mixer.init()
        self.drop_sound = pygame.mixer.Sound(cfg.SOUNDS_PATHS.get('drop'))
    '''鼠标左键点击事件-玩家回合'''
    def mousePressEvent(self, event):
        if (event.buttons() != QtCore.Qt.LeftButton) or (self.winner is not None) or (self.whoseround != self.player_color) or (not self.is_gaming):
            return
        # 保证只在棋盘范围内响应
        if event.x() >= 50 and event.x() <= 50 + 30 * 18 + 14 and event.y() >= 50 and event.y() <= 50 + 30 * 18 + 14:
            pos = Pixel2Chesspos(event)
            # 保证落子的地方本来没有人落子
            if self.chessboard[pos[0]][pos[1]]:
                return
            # 实例化一个棋子并显示
            c = Chessman(self.cfg.CHESSMAN_IMAGEPATHS.get(self.whoseround), self)
            c.move(event.pos())
            c.show()
            self.chessboard[pos[0]][pos[1]] = c
            # 落子声音响起
            self.drop_sound.play()
            # 最后落子位置标志对落子位置进行跟随
            self.chessman_sign.show()
            self.chessman_sign.move(c.pos())
            self.chessman_sign.raise_()
            # 记录这次落子
            self.history_record.append([*pos, self.whoseround])
            # 是否胜利了
            self.winner = checkWin(self.chessboard)
            if self.winner:
                self.showGameEndInfo()
                return
            # 切换回合方(其实就是改颜色)
            self.nextRound()
    '''鼠标左键释放操作-调用电脑回合'''
    def mouseReleaseEvent(self, event):
        if (self.winner is not None) or (self.whoseround != self.ai_color) or (not self.is_gaming):
            return
        self.aiAct()
    '''电脑自动下-AI回合'''
    def aiAct(self):
        if (self.winner is not None) or (self.whoseround == self.player_color) or (not self.is_gaming):
            return
        next_pos = self.ai_player.act(self.history_record)
        # 实例化一个棋子并显示
        c = Chessman(self.cfg.CHESSMAN_IMAGEPATHS.get(self.whoseround), self)
        c.move(QPoint(*Chesspos2Pixel(next_pos)))
        c.show()
        self.chessboard[next_pos[0]][next_pos[1]] = c
        # 落子声音响起
        self.drop_sound.play()
        # 最后落子位置标志对落子位置进行跟随
        self.chessman_sign.show()
        self.chessman_sign.move(c.pos())
        self.chessman_sign.raise_()
        # 记录这次落子
        self.history_record.append([*next_pos, self.whoseround])
        # 是否胜利了
        self.winner = checkWin(self.chessboard)
        if self.winner:
            self.showGameEndInfo()
            return
        # 切换回合方(其实就是改颜色)
        self.nextRound()
    '''改变落子方'''
    def nextRound(self):
        self.whoseround = self.player_color if self.whoseround == self.ai_color else self.ai_color
    '''显示游戏结束结果'''
    def showGameEndInfo(self):
        self.is_gaming = False
        info_img = QPixmap(self.cfg.WIN_IMAGEPATHS.get(self.winner))
        self.winner_info_label = QLabel(self)
        self.winner_info_label.setPixmap(info_img)
        self.winner_info_label.resize(info_img.size())
        self.winner_info_label.move(50, 50)
        self.winner_info_label.show()
    '''认输'''
    def givein(self):
        if self.is_gaming and (self.winner is None) and (self.whoseround == self.player_color):
            self.winner = self.ai_color
            self.showGameEndInfo()
    '''悔棋-只有我方回合的时候可以悔棋'''
    def regret(self):
        if (self.winner is not None) or (len(self.history_record) == 0) or (not self.is_gaming) and (self.whoseround != self.player_color):
            return
        for _ in range(2):
            pre_round = self.history_record.pop(-1)
            self.chessboard[pre_round[0]][pre_round[1]].close()
            self.chessboard[pre_round[0]][pre_round[1]] = None
        self.chessman_sign.hide()
    '''开始游戏-之前的对弈必须已经结束才行'''
    def startgame(self):
        if self.is_gaming:
            return
        self.is_gaming = True
        self.whoseround = self.player_color
        for i, j in product(range(19), range(19)):
            if self.chessboard[i][j]:
                self.chessboard[i][j].close()
                self.chessboard[i][j] = None
        self.winner = None
        self.winner_info_label.close()
        self.winner_info_label = None
        self.history_record.clear()
        self.chessman_sign.hide()
    '''关闭窗口事件'''
    def closeEvent(self, event):
        if not self.send_back_signal:
            self.exit_signal.emit()
    '''返回游戏主页面'''
    def goHome(self):
        self.send_back_signal = True
        self.close()
        self.back_signal.emit()

如下:害!我这下了很久呢,有几次都没下赢人机!2333游戏废材

如何使用python实现智能五子棋游戏

如何使用python实现智能五子棋游戏如何使用python实现智能五子棋游戏

如何使用python实现智能五子棋游戏另一个定义联机对战:

import sys
import random
from .server import *
from .client import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
 
 
'''联机对战'''
class playOnlineUI(QWidget):
    def __init__(self, cfg, home_ui, parent=None, **kwargs):
        super(playOnlineUI, self).__init__(parent)
        self.cfg = cfg
        self.home_ui = home_ui
        self.setWindowTitle('联机对战')
        self.setWindowIcon(QIcon(cfg.ICON_FILEPATH))
        self.setFixedSize(300, 200)
        # 昵称
        self.nickname = random.choice(['杰尼龟', '皮卡丘', '小火龙', '小锯鳄', '妙蛙种子', '菊草叶'])
        self.layout0 = QHBoxLayout()
        self.nickname_label = QLabel('游戏昵称:', self)
        self.nickname_edit = QLineEdit(self)
        self.nickname_edit.setText(self.nickname)
        self.layout0.addWidget(self.nickname_label, 1)
        self.layout0.addWidget(self.nickname_edit, 3)
        # IP
        self.target_ip = '127.0.0.1'
        self.layout1 = QHBoxLayout()
        self.ip_label = QLabel('对方IP:', self)
        self.ip_edit = QLineEdit(self)
        self.ip_edit.setText(self.target_ip)
        self.layout1.addWidget(self.ip_label, 1)
        self.layout1.addWidget(self.ip_edit, 3)
        # 按钮
        self.layout2 = QHBoxLayout()
        self.connect_button = QPushButton('作为客户端', self)
        self.connect_button.clicked.connect(self.becomeClient)
        self.ashost_button = QPushButton('作为服务器', self)
        self.ashost_button.clicked.connect(self.becomeHost)
        self.layout2.addWidget(self.connect_button)
        self.layout2.addWidget(self.ashost_button)
        # 布局
        self.layout = QVBoxLayout()
        self.layout.addLayout(self.layout0)
        self.layout.addLayout(self.layout1)
        self.layout.addLayout(self.layout2)
        self.setLayout(self.layout)
    '''作为客户端'''
    def becomeClient(self):
        self.close()
        self.nickname = self.nickname_edit.text()
        self.target_ip = self.ip_edit.text()
        self.client_ui = gobangClient(cfg=self.cfg, nickname=self.nickname, server_ip=self.target_ip)
        self.client_ui.exit_signal.connect(lambda: sys.exit())
        self.client_ui.back_signal.connect(self.home_ui.show)
        self.client_ui.show()
    '''作为服务器'''
    def becomeHost(self):
        self.close()
        self.nickname = self.nickname_edit.text()
        self.server_ui = gobangSever(cfg=self.cfg, nickname=self.nickname)
        self.server_ui.exit_signal.connect(lambda: sys.exit())
        self.server_ui.back_signal.connect(self.home_ui.show)
        self.server_ui.show()

如下联机对战界面第一步:

如何使用python实现智能五子棋游戏如何使用python实现智能五子棋游戏

如何使用python实现智能五子棋游戏如何使用python实现智能五子棋游戏

定义五子棋AI算法:

import random
from itertools import product
 
 
'''五子棋AI算法'''
class aiGobang():
    def __init__(self, ai_color, player_color, search_depth=1, **kwargs):
        assert search_depth % 2, 'search_depth must be odd number'
        self.ai_color = ai_color
        self.player_color = player_color
        self.search_depth = search_depth
        self.score_model = [(50, (0, 1, 1, 0, 0)), (50, (0, 0, 1, 1, 0)), (200, (1, 1, 0, 1, 0)),
                            (500, (0, 0, 1, 1, 1)), (500, (1, 1, 1, 0, 0)), (5000, (0, 1, 1, 1, 0)),
                            (5000, (0, 1, 0, 1, 1, 0)), (5000, (0, 1, 1, 0, 1, 0)), (5000, (1, 1, 1, 0, 1)),
                            (5000, (1, 1, 0, 1, 1)), (5000, (1, 0, 1, 1, 1)), (5000, (1, 1, 1, 1, 0)),
                            (5000, (0, 1, 1, 1, 1)), (50000, (0, 1, 1, 1, 1, 0)), (99999999, (1, 1, 1, 1, 1))]
        self.alpha = -99999999
        self.beta = 99999999
        self.all_list = [(i, j) for i, j in product(range(19), range(19))]
    '''外部调用'''
    def act(self, history_record):
        self.ai_list = []
        self.player_list = []
        self.aiplayer_list = []
        for item in history_record:
            self.aiplayer_list.append((item[0], item[1]))
            if item[-1] == self.ai_color:
                self.ai_list.append((item[0], item[1]))
            elif item[-1] == self.player_color:
                self.player_list.append((item[0], item[1]))
        while True:
            self.next_point = random.choice(range(19)), random.choice(range(19))
            if self.next_point not in self.aiplayer_list:
                break
        self.__doSearch(True, self.search_depth, self.alpha, self.beta)
        return self.next_point
    '''负极大值搜索, alpha+beta剪枝'''
    def __doSearch(self, is_ai_round, depth, alpha, beta):
        if self.__isgameover(self.ai_list) or self.__isgameover(self.player_list) or depth == 0:
            return self.__evaluation(is_ai_round)
        blank_list = list(set(self.all_list).difference(set(self.aiplayer_list)))
        blank_list = self.__rearrange(blank_list)
        for next_step in blank_list:
            if not self.__hasNeighbor(next_step):
                continue
            if is_ai_round:
                self.ai_list.append(next_step)
            else:
                self.player_list.append(next_step)
            self.aiplayer_list.append(next_step)
            value = -self.__doSearch(not is_ai_round, depth-1, -beta, -alpha)
            if is_ai_round:
                self.ai_list.remove(next_step)
            else:
                self.player_list.remove(next_step)
            self.aiplayer_list.remove(next_step)
            if value > alpha:
                if depth == self.search_depth:
                    self.next_point = next_step
                if value >= beta:
                    return beta
                alpha = value
        return alpha
    '''游戏是否结束了'''
    def __isgameover(self, oneslist):
        for i, j in product(range(19), range(19)):
            if i < 15 and (i, j) in oneslist and (i+1, j) in oneslist and (i+2, j) in oneslist and (i+3, j) in oneslist and (i+4, j) in oneslist:
                return True
            elif j < 15 and (i, j) in oneslist and (i, j+1) in oneslist and (i, j+2) in oneslist and (i, j+3) in oneslist and (i, j+4) in oneslist:
                return True
            elif i < 15 and j < 15 and (i, j) in oneslist and (i+1, j+1) in oneslist and (i+2, j+2) in oneslist and (i+3, j+3) in oneslist and (i+4, j+4) in oneslist:
                return True
            elif i > 3 and j < 15 and (i, j) in oneslist and (i-1, j+1) in oneslist and (i-2, j+2) in oneslist and (i-3, j+3) in oneslist and (i-4, j+4) in oneslist:
                return True
        return False
    '''重新排列未落子位置'''
    def __rearrange(self, blank_list):
        last_step = self.aiplayer_list[-1]
        for item in blank_list:
            for i, j in product(range(-1, 2), range(-1, 2)):
                if i == 0 and j == 0:
                    continue
                next_step = (last_step[0]+i, last_step[1]+j)
                if next_step in blank_list:
                    blank_list.remove(next_step)
                    blank_list.insert(0, next_step)
        return blank_list
    '''是否存在近邻'''
    def __hasNeighbor(self, next_step):
        for i, j in product(range(-1, 2), range(-1, 2)):
            if i == 0 and j == 0:
                continue
            if (next_step[0]+i, next_step[1]+j) in self.aiplayer_list:
                return True
        return False
    '''计算得分'''
    def __calcScore(self, i, j, x_direction, y_direction, list1, list2, all_scores):
        add_score = 0
        max_score = (0, None)
        for each in all_scores:
            for item in each[1]:
                if i == item[0] and j == item[1] and x_direction == each[2][0] and y_direction == each[2][1]:
                    return 0, all_scores
        for noffset in range(-5, 1):
            position = []
            for poffset in range(6):
                x, y = i + (poffset + noffset) * x_direction, j + (poffset + noffset) * y_direction
                if (x, y) in list2:
                    position.append(2)
                elif (x, y) in list1:
                    position.append(1)
                else:
                    position.append(0)
            shape_len5 = tuple(position[0: -1])
            shape_len6 = tuple(position)
            for score, shape in self.score_model:
                if shape_len5 == shape or shape_len6 == shape:
                    if score > max_score[0]:
                        max_score = (score, ((i + (0 + noffset) * x_direction, j + (0 + noffset) * y_direction),
                                             (i + (1 + noffset) * x_direction, j + (1 + noffset) * y_direction),
                                             (i + (2 + noffset) * x_direction, j + (2 + noffset) * y_direction),
                                             (i + (3 + noffset) * x_direction, j + (3 + noffset) * y_direction),
                                             (i + (4 + noffset) * x_direction, j + (4 + noffset) * y_direction)), (x_direction, y_direction))
        if max_score[1] is not None:
            for each in all_scores:
                for p1 in each[1]:
                    for p2 in max_score[1]:
                        if p1 == p2 and max_score[0] > 10 and each[0] > 10:
                            add_score += max_score[0] + each[0]
            all_scores.append(max_score)
        return add_score+max_score[0], all_scores
    '''评估函数'''
    def __evaluation(self, is_ai_round):
        if is_ai_round:
            list1 = self.ai_list
            list2 = self.player_list
        else:
            list2 = self.ai_list
            list1 = self.player_list
        active_all_scores = []
        active_score = 0
        for item in list1:
            score, active_all_scores = self.__calcScore(item[0], item[1], 0, 1, list1, list2, active_all_scores)
            active_score += score
            score, active_all_scores = self.__calcScore(item[0], item[1], 1, 0, list1, list2, active_all_scores)
            active_score += score
            score, active_all_scores = self.__calcScore(item[0], item[1], 1, 1, list1, list2, active_all_scores)
            active_score += score
            score, active_all_scores = self.__calcScore(item[0], item[1], -1, 1, list1, list2, active_all_scores)
            active_score += score
        passive_all_scores = []
        passive_score = 0
        for item in list2:
            score, passive_all_scores = self.__calcScore(item[0], item[1], 0, 1, list2, list1, passive_all_scores)
            passive_score += score
            score, passive_all_scores = self.__calcScore(item[0], item[1], 1, 0, list2, list1, passive_all_scores)
            passive_score += score
            score, passive_all_scores = self.__calcScore(item[0], item[1], 1, 1, list2, list1, passive_all_scores)
            passive_score += score
            score, passive_all_scores = self.__calcScore(item[0], item[1], -1, 1, list2, list1, passive_all_scores)
            passive_score += score
        total_score = active_score - passive_score * 0.1
        return total_score

关于如何使用python实现智能五子棋游戏问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

推荐阅读:
  1. 怎么使用python实现滑雪游戏
  2. python实现五子棋游戏(pygame版)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:python怎么转换为私有属性

下一篇:python有什么高级内置函数

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》