国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼)

這篇具有很好參考價(jià)值的文章主要介紹了python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


0 項(xiàng)目簡(jiǎn)介

?? Hi,各位同學(xué)好呀,這里是L學(xué)長(zhǎng)!

??今天向大家分享一個(gè)今年(2022)最新完成的畢業(yè)設(shè)計(jì)項(xiàng)目作品

python小游戲畢設(shè) 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼)

?? 學(xué)長(zhǎng)根據(jù)實(shí)現(xiàn)的難度和等級(jí)對(duì)項(xiàng)目進(jìn)行評(píng)分(最低0分,滿分5分)

  • 難度系數(shù):3分

  • 工作量:3分

  • 創(chuàng)新點(diǎn):4分

  • 項(xiàng)目獲?。?/strong>https://gitee.com/sinonfin/system-sharing文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-780294.html


1 游戲介紹

基于python實(shí)現(xiàn)的支持局域網(wǎng)聯(lián)機(jī)對(duì)戰(zhàn)的五子棋小游戲。

游戲規(guī)則:

五子棋起源于中國(guó),是全國(guó)智力運(yùn)動(dòng)會(huì)競(jìng)技項(xiàng)目之一,是一種兩人對(duì)弈的純策略型棋類游戲。雙方分別使用黑白兩色的棋子,下在棋盤直線與橫線的交叉點(diǎn)上,先形成五子連珠者獲勝。

2 實(shí)現(xiàn)效果

python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼),python
python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼),python

3 開發(fā)工具

3.1 環(huán)境配置

  • Python版本:3.6.4

  • 相關(guān)模塊:

  • pygame模塊;

  • 以及一些Python自帶的模塊。

3.2 Pygame介紹

簡(jiǎn)介

Pygame是一系列專門為編寫電子游戲而設(shè)計(jì)的Python模塊(modules)。Pygame在已經(jīng)非常優(yōu)秀的SDL庫(kù)的基礎(chǔ)上增加了許多功能。這讓你能夠用Python語(yǔ)言編寫出豐富多彩的游戲程序。

Pygame可移植性高,幾乎能在任何平臺(tái)和操作系統(tǒng)上運(yùn)行。

Pygame已經(jīng)被下載過(guò)數(shù)百萬(wàn)次。

Pygame免費(fèi)開源。它在LGPL許可證(Lesser General Public License,GNU寬通用公共許可證)下發(fā)行。使用Pygame,你可以創(chuàng)造出免費(fèi)開源,可共享,或者商業(yè)化的游戲。詳情請(qǐng)見LGPL許可證。

優(yōu)點(diǎn)

  • 能夠輕松使用多核CPU(multi core CPUs) :如今雙核CPU很常用,8核CPU在桌面系統(tǒng)中也很便宜,而利用好多核系統(tǒng),能讓你在你的游戲中實(shí)現(xiàn)更多東西。特定的pygame函數(shù)能夠釋放令人生畏的python GIL(全局解釋器鎖),這幾乎是你用C語(yǔ)言才能做的事。

  • 核心函數(shù)用最優(yōu)化的C語(yǔ)言或匯編語(yǔ)言編寫:C語(yǔ)言代碼通常比Python代碼運(yùn)行速度快10-20倍。而匯編語(yǔ)言編寫的代碼(assembly code)比Python甚至快到100多倍。

  • 安裝便捷:一般僅需包管理程序或二進(jìn)制系統(tǒng)程序便能安裝。

  • 真正地可移植:支持Linux (主要發(fā)行版), Windows (95, 98, ME, 2000, XP, Vista, 64-bit Windows,), Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX等操作系統(tǒng).也能支持AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS and OS/2,但是還沒有受到官方認(rèn)可。你也可以在手持設(shè)備,游戲控制臺(tái), One Laptop Per Child (OLPC) computer項(xiàng)目的電腦等設(shè)備中使用pygame.

  • 用法簡(jiǎn)單:無(wú)論是小孩子還是大人都能學(xué)會(huì)用pygame來(lái)制作射擊類游戲。

  • 很多Pygame游戲已發(fā)行:其中包括很多游戲大賽入圍作品、非常受歡迎的開源可分享的游戲。

  • 由你來(lái)控制主循環(huán):由你來(lái)調(diào)用pygame的函數(shù),pygame的函數(shù)并不需要調(diào)用你的函數(shù)。當(dāng)你同時(shí)還在使用其他庫(kù)來(lái)編寫各種各種的程序時(shí),這能夠?yàn)槟闾峁O大的掌控權(quán)。

  • 不需要GUI就能使用所有函數(shù):僅在命令行中,你就可以使用pygame的某些函數(shù)來(lái)處理圖片,獲取游戲桿輸入,播放音樂(lè)……

  • 對(duì)bug反應(yīng)迅速:很多bug在被上報(bào)的1小時(shí)內(nèi)就能被我們修復(fù)。雖然有時(shí)候我們確實(shí)會(huì)卡在某一個(gè)bug上很久,但大多數(shù)時(shí)候我們都是很不錯(cuò)的bug修復(fù)者。如今bug的上報(bào)已經(jīng)很少了,因?yàn)樵S多bug早已被我們修復(fù)。

  • 代碼量少:pygame并沒有數(shù)以萬(wàn)計(jì)的也許你永遠(yuǎn)用不到的冗雜代碼。pygame的核心代碼一直保持著簡(jiǎn)潔特點(diǎn),其他附加物諸如GUI庫(kù)等,都是在核心代碼之外單獨(dú)設(shè)計(jì)研發(fā)的。

  • 模塊化:你可以單獨(dú)使用pygame的某個(gè)模塊。想要換著使用一個(gè)別的聲音處理庫(kù)?沒問(wèn)題。pygame的很多核心模塊支持獨(dú)立初始化與使用。

最小開發(fā)框架

import pygame,sys #sys是python的標(biāo)準(zhǔn)庫(kù),提供Python運(yùn)行時(shí)環(huán)境變量的操控

pygame.init()  #內(nèi)部各功能模塊進(jìn)行初始化創(chuàng)建及變量設(shè)置,默認(rèn)調(diào)用
size = width,height = 800,600  #設(shè)置游戲窗口大小,分別是寬度和高度
screen = pygame.display.set_mode(size)  #初始化顯示窗口
pygame.display.set_caption("小游戲程序")  #設(shè)置顯示窗口的標(biāo)題內(nèi)容,是一個(gè)字符串類型
while True:  #無(wú)限循環(huán),直到Python運(yùn)行時(shí)退出結(jié)束
    for event in pygame.event.get():  #從Pygame的事件隊(duì)列中取出事件,并從隊(duì)列中刪除該事件
        if event.type == pygame.QUIT:  #獲得事件類型,并逐類響應(yīng)
            sys.exit()   #用于退出結(jié)束游戲并退出          
    pygame.display.update()  #對(duì)顯示窗口進(jìn)行更新,默認(rèn)窗口全部重繪

代碼執(zhí)行流程

python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼),python

4 具體實(shí)現(xiàn)

這里簡(jiǎn)單介紹下原理吧,代碼主要用PyQt5寫的,pygame只用來(lái)播放一些音效。首先,設(shè)計(jì)并實(shí)現(xiàn)個(gè)游戲主界面:

python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼),python
代碼實(shí)現(xiàn)如下:


'''游戲開始界面'''
class gameStartUI(QWidget):
  def __init__(self, parent=None, **kwargs):
    super(gameStartUI, self).__init__(parent)
    self.setFixedSize(760, 650)
    self.setWindowTitle('五子棋-微信公眾號(hào): Charles的皮卡丘')
    self.setWindowIcon(QIcon(cfg.ICON_FILEPATH))
    # 背景圖片
    palette = QPalette()
    palette.setBrush(self.backgroundRole(), QBrush(QPixmap(cfg.BACKGROUND_IMAGEPATHS.get('bg_start'))))
    self.setPalette(palette)
    # 按鈕
    # --人機(jī)對(duì)戰(zhàn)
    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)
    # --聯(lián)機(jī)對(duì)戰(zhàn)
    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)
  '''人機(jī)對(duì)戰(zhàn)'''
  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()
  '''聯(lián)機(jī)對(duì)戰(zhàn)'''
  def playOnline(self):
    self.close()
    self.gaming_ui = playOnlineUI(cfg, self)
    self.gaming_ui.show()

會(huì)pyqt5的應(yīng)該都可以寫出這樣的界面,沒啥特別的,記得把人機(jī)對(duì)戰(zhàn)和聯(lián)機(jī)對(duì)戰(zhàn)兩個(gè)按鈕觸發(fā)后的信號(hào)分別綁定到人機(jī)對(duì)戰(zhàn)和聯(lián)機(jī)對(duì)戰(zhàn)的函數(shù)上就行。

然后分別來(lái)實(shí)現(xiàn)人機(jī)對(duì)戰(zhàn)和聯(lián)機(jī)對(duì)戰(zhàn)就行了。這里人機(jī)對(duì)戰(zhàn)的算法抄的公眾號(hào)之前發(fā)的那篇AI五子棋的文章里用的算法,所以只要花點(diǎn)心思用PyQt5重新寫個(gè)游戲界面就行了,效果大概是這樣的:

python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼),python
主要的代碼實(shí)現(xiàn)如下:


'''人機(jī)對(duì)戰(zhàn)'''
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('五子棋-微信公眾號(hào): Charles的皮卡丘')
        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)
        # 落子標(biāo)志
        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目前輪到誰(shuí)落子
        self.player_color = 'white'
        self.ai_color = 'black'
        self.whoseround = self.player_color
        # 實(shí)例化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'))
    '''鼠標(biāo)左鍵點(diǎn)擊事件-玩家回合'''
    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
        # 保證只在棋盤范圍內(nèi)響應(yīng)
        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)
            # 保證落子的地方本來(lái)沒有人落子
            if self.chessboard[pos[0]][pos[1]]:
                return
            # 實(shí)例化一個(gè)棋子并顯示
            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()
            # 最后落子位置標(biāo)志對(duì)落子位置進(jìn)行跟隨
            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
            # 切換回合方(其實(shí)就是改顏色)
            self.nextRound()
    '''鼠標(biāo)左鍵釋放操作-調(diào)用電腦回合'''
    def mouseReleaseEvent(self, event):
        if (self.winner is not None) or (self.whoseround != self.ai_color) or (not self.is_gaming):
            return
        self.aiAct()
    '''電腦自動(dòng)下-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)
        # 實(shí)例化一個(gè)棋子并顯示
        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()
        # 最后落子位置標(biāo)志對(duì)落子位置進(jìn)行跟隨
        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
        # 切換回合方(其實(shí)就是改顏色)
        self.nextRound()
    '''改變落子方'''
    def nextRound(self):
        self.whoseround = self.player_color if self.whoseround == self.ai_color else self.ai_color
    '''顯示游戲結(jié)束結(jié)果'''
    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()
    '''認(rèn)輸'''
    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()
    '''悔棋-只有我方回合的時(shí)候可以悔棋'''
    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()
    '''開始游戲-之前的對(duì)弈必須已經(jīng)結(jié)束才行'''
    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()
    '''關(guān)閉窗口事件'''
    def closeEvent(self, event):
        if not self.send_back_signal:
            self.exit_signal.emit()
    '''返回游戲主頁(yè)面'''
    def goHome(self):
        self.send_back_signal = True
        self.close()
        self.back_signal.emit()

整個(gè)邏輯是這樣的:

設(shè)計(jì)并實(shí)現(xiàn)游戲的基本界面之后,先默認(rèn)永遠(yuǎn)是玩家先手(白子),電腦后手(黑子)。然后,當(dāng)監(jiān)聽到玩家鼠標(biāo)左鍵點(diǎn)擊到棋盤網(wǎng)格所在的范圍內(nèi)的時(shí)候,捕獲該位置,若該位置之前沒有人落子過(guò),則玩家成功落子,否則重新等待玩家鼠標(biāo)左鍵點(diǎn)擊事件。玩家成功落子后,判斷是否因?yàn)橥婕衣渥佣鴮?dǎo)致游戲結(jié)束(即棋盤上有5顆同色子相連了),若游戲結(jié)束,則顯示游戲結(jié)束界面,否則輪到AI落子。AI落子和玩家落子的邏輯類似,然后又輪到玩家落子,以此類推。

需要注意的是:為保證響應(yīng)的實(shí)時(shí)性,AI落子算法應(yīng)當(dāng)寫到鼠標(biāo)左鍵點(diǎn)擊后釋放事件的響應(yīng)中(感興趣的小伙伴可以試試寫到鼠標(biāo)點(diǎn)擊事件的響應(yīng)中,這樣會(huì)導(dǎo)致必須在AI計(jì)算結(jié)束并落子后,才能顯示玩家上一次的落子和AI此次的落子結(jié)果)。

開始按鈕就是重置游戲,沒啥可說(shuō)的,這里為了避免有些人喜歡耍賴,我實(shí)現(xiàn)的時(shí)候代碼寫的是必須完成當(dāng)前對(duì)弈才能重置游戲(畢竟小伙子小姑娘們要學(xué)會(huì)有耐心地下完一盤棋呀)。

因?yàn)槭呛虯I下,所以悔棋按鈕直接悔兩步,從歷史記錄列表里pop最后兩次落子然后從棋盤對(duì)應(yīng)位置取下這兩次落子就OK了,并且保證只有我方回合可以悔棋以避免出現(xiàn)意料之外的邏輯出錯(cuò)。

認(rèn)輸按鈕也沒啥可說(shuō)的,就是認(rèn)輸然后提前結(jié)束游戲。

接下來(lái)我們來(lái)實(shí)現(xiàn)一下聯(lián)機(jī)對(duì)戰(zhàn),這里我們選擇使用TCP/IP協(xié)議進(jìn)行聯(lián)機(jī)通信從而實(shí)現(xiàn)聯(lián)機(jī)對(duì)戰(zhàn)。先啟動(dòng)游戲的一方作為服務(wù)器端:

python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼),python
通過(guò)新開一個(gè)線程來(lái)實(shí)現(xiàn)監(jiān)聽:


threading.Thread(target=self.startListen).start()
'''開始監(jiān)聽客戶端的連接'''
def startListen(self):
    while True:
       self.setWindowTitle('五子棋-微信公眾號(hào): Charles的皮卡丘 ——> 服務(wù)器端啟動(dòng)成功, 等待客戶端連接中')
       self.tcp_socket, self.client_ipport = self.tcp_server.accept()
       self.setWindowTitle('五子棋-微信公眾號(hào): Charles的皮卡丘 ——> 客戶端已連接, 點(diǎn)擊開始按鈕進(jìn)行游戲')

后啟動(dòng)方作為客戶端連接服務(wù)器端并發(fā)送客戶端玩家的基本信息:


self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_socket.connect(self.server_ipport)
data = {'type': 'nickname', 'data': self.nickname}
self.tcp_socket.sendall(packSocketData(data))

當(dāng)客戶端連接到服務(wù)器端時(shí),服務(wù)器端也發(fā)送服務(wù)器端的玩家基本信息給客戶端:


data = {'type': 'nickname', 'data': self.nickname}
self.tcp_socket.sendall(packSocketData(data))

然后客戶端和服務(wù)器端都利用新開的線程來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)監(jiān)聽接收:

'''接收客戶端數(shù)據(jù)'''
def receiveClientData(self):
    while True:
        data = receiveAndReadSocketData(self.tcp_socket)
        self.receive_signal.emit(data)
'''接收服務(wù)器端數(shù)據(jù)'''
def receiveServerData(self):
    while True:
        data = receiveAndReadSocketData(self.tcp_socket)
        self.receive_signal.emit(data)

并根據(jù)接收到的不同數(shù)據(jù)在主進(jìn)程中做成對(duì)應(yīng)的響應(yīng):


'''響應(yīng)接收到的數(shù)據(jù)'''
def responseForReceiveData(self, data):
    if data['type'] == 'action' and data['detail'] == 'exit':
        QMessageBox.information(self, '提示', '您的對(duì)手已退出游戲, 游戲?qū)⒆詣?dòng)返回主界面')
        self.goHome()
    elif data['type'] == 'action' and data['detail'] == 'startgame':
        self.opponent_player_color, self.player_color = data['data']
        self.whoseround = 'white'
        self.whoseround2nickname_dict = {self.player_color: self.nickname, self.opponent_player_color: self.opponent_nickname}
        res = QMessageBox.information(self, '提示', '對(duì)方請(qǐng)求(重新)開始游戲, 您為%s, 您是否同意?' % {'white': '白子', 'black': '黑子'}.get(self.player_color), QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            data = {'type': 'reply', 'detail': 'startgame', 'data': True}
            self.tcp_socket.sendall(packSocketData(data))
            self.is_gaming = True
            self.setWindowTitle('五子棋-微信公眾號(hào): Charles的皮卡丘 ——> %s走棋' % self.whoseround2nickname_dict.get(self.whoseround))
            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.history_record.clear()
            self.winner = None
            if self.winner_info_label:
                self.winner_info_label.close()
            self.winner_info_label = None
            self.chessman_sign.hide()
        else:
            data = {'type': 'reply', 'detail': 'startgame', 'data': False}
            self.tcp_socket.sendall(packSocketData(data))
    elif data['type'] == 'action' and data['detail'] == 'drop':
        pos = data['data']
        # 實(shí)例化一個(gè)棋子并顯示
        c = Chessman(self.cfg.CHESSMAN_IMAGEPATHS.get(self.whoseround), self)
        c.move(QPoint(*Chesspos2Pixel(pos)))
        c.show()
        self.chessboard[pos[0]][pos[1]] = c
        # 落子聲音響起
        self.drop_sound.play()
        # 最后落子位置標(biāo)志對(duì)落子位置進(jìn)行跟隨
        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
        # 切換回合方(其實(shí)就是改顏色)
        self.nextRound()
    elif data['type'] == 'action' and data['detail'] == 'givein':
        self.winner = self.player_color
        self.showGameEndInfo()
    elif data['type'] == 'action' and data['detail'] == 'urge':
        self.urge_sound.play()
    elif data['type'] == 'action' and data['detail'] == 'regret':
        res = QMessageBox.information(self, '提示', '對(duì)方請(qǐng)求悔棋, 您是否同意?', QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            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()
            self.nextRound()
            data = {'type': 'reply', 'detail': 'regret', 'data': True}
            self.tcp_socket.sendall(packSocketData(data))
        else:
            data = {'type': 'reply', 'detail': 'regret', 'data': False}
            self.tcp_socket.sendall(packSocketData(data))
    elif data['type'] == 'reply' and data['detail'] == 'startgame':
        if data['data']:
            self.is_gaming = True
            self.setWindowTitle('五子棋-微信公眾號(hào): Charles的皮卡丘 ——> %s走棋' % self.whoseround2nickname_dict.get(self.whoseround))
            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.history_record.clear()
            self.winner = None
            if self.winner_info_label:
                self.winner_info_label.close()
            self.winner_info_label = None
            self.chessman_sign.hide()
            QMessageBox.information(self, '提示', '對(duì)方同意開始游戲請(qǐng)求, 您為%s, 執(zhí)白者先行.' % {'white': '白子', 'black': '黑子'}.get(self.player_color))
        else:
            QMessageBox.information(self, '提示', '對(duì)方拒絕了您開始游戲的請(qǐng)求.')
    elif data['type'] == 'reply' and data['detail'] == 'regret':
        if data['data']:
            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.nextRound()
            QMessageBox.information(self, '提示', '對(duì)方同意了您的悔棋請(qǐng)求.')
        else:
            QMessageBox.information(self, '提示', '對(duì)方拒絕了您的悔棋請(qǐng)求.')
    elif data['type'] == 'nickname':
        self.opponent_nickname = data['data']

對(duì)戰(zhàn)過(guò)程實(shí)現(xiàn)的基本邏輯和人機(jī)對(duì)戰(zhàn)是一致的,只不過(guò)要考慮數(shù)據(jù)同步問(wèn)題,所以看起來(lái)代碼略多了一些。當(dāng)然對(duì)于聯(lián)機(jī)對(duì)戰(zhàn),我也做了一些小修改,比如必須點(diǎn)擊開始按鈕,并經(jīng)過(guò)對(duì)方同意之后,才能正式開始對(duì)弈,悔棋按鈕只有在對(duì)方回合才能按,對(duì)方同意悔棋后需要記得把落子方切換回自己。然后加了一個(gè)催促按鈕,同樣必須在對(duì)方回合才能按。其他好像也沒什么特別的改動(dòng)了。

5 最后

項(xiàng)目獲?。?/strong>https://gitee.com/sinonfin/system-sharing

到了這里,關(guān)于python項(xiàng)目分享 - 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 用c++實(shí)現(xiàn)五子棋小游戲

    用c++實(shí)現(xiàn)五子棋小游戲

    五子棋是一款經(jīng)典小游戲,今天我們就用c++實(shí)現(xiàn)簡(jiǎn)單的五子棋小游戲 目錄 用到的算法: 思路分析 定義變量? 開始寫代碼 ? 完整代碼? 結(jié)果圖: 合法移動(dòng)的判斷: isValidMove 函數(shù)通過(guò)檢查指定位置是否在棋盤范圍內(nèi),并且該位置是否為空位來(lái)確定是否為合法的移動(dòng)。 獲勝條

    2024年02月07日
    瀏覽(23)
  • 小游戲?qū)崙?zhàn)丨基于Tkinter的五子棋小游戲

    小游戲?qū)崙?zhàn)丨基于Tkinter的五子棋小游戲

    本期內(nèi)容:基于tkinter的五子棋小游戲 下載地址:https://download.csdn.net/download/m0_68111267/88700190 實(shí)驗(yàn)環(huán)境 python3.11及以上 pycharm tkinter Tkinter是Python的一個(gè)標(biāo)準(zhǔn)的圖形用戶界面(GUI)庫(kù),它是基于Tk工具包的。Tkinter庫(kù)提供了GUI應(yīng)用程序開發(fā)所需的各種組件和方法,方便開發(fā)者快速創(chuàng)建

    2024年01月22日
    瀏覽(23)
  • Android Studio實(shí)現(xiàn)五子棋小游戲

    Android Studio實(shí)現(xiàn)五子棋小游戲

    五子棋是一種兩人對(duì)弈的策略型棋類游戲,本次五子棋小游戲具有人機(jī)對(duì)戰(zhàn)和人人對(duì)戰(zhàn)兩種玩法。人機(jī)對(duì)戰(zhàn)可以單人挑戰(zhàn)AI,實(shí)時(shí)記錄比賽得分,AI是根據(jù)棋盤上每個(gè)點(diǎn)的得分進(jìn)行決策,人人對(duì)戰(zhàn)采用輪流下棋方式進(jìn)行對(duì)決,下棋過(guò)程中會(huì)記錄當(dāng)前棋子的顏色??梢栽谙缕暹^(guò)程

    2024年02月08日
    瀏覽(26)
  • Java實(shí)現(xiàn)五子棋小游戲(附源碼)

    Java實(shí)現(xiàn)五子棋小游戲(附源碼)

    ??銅9鐵10已經(jīng)結(jié)束了,但還是有很多Java程序員沒有找到工作或者成功跳槽,跳槽成功的也只是從一個(gè)坑中,跳入另一個(gè)坑中…… ? 在LZ看來(lái),真正有意義的就業(yè)與跳槽,是要進(jìn)入到一個(gè)有絕對(duì)潛力的行業(yè)或者薪資能實(shí)現(xiàn)爆炸式增長(zhǎng)的。這件事不容易,但也沒有想象的遙不可

    2024年02月08日
    瀏覽(24)
  • 五子棋小游戲 java版(代碼+詳細(xì)注釋)

    五子棋小游戲 java版(代碼+詳細(xì)注釋)

    游戲展示 ? ? ? ? 這周閑來(lái)無(wú)事,再來(lái)寫個(gè)五子棋小游戲?;竟δ芏紝?shí)現(xiàn)了,包括人人對(duì)戰(zhàn)、人機(jī)對(duì)戰(zhàn)。界面布局和功能都寫的還行,沒做到很優(yōu)秀,但也不算差。如有需要,做個(gè)java初學(xué)者的課程設(shè)計(jì)或者自己寫著玩玩也都是不錯(cuò)的(非常簡(jiǎn)單,小白照著就能寫出來(lái))。

    2024年02月07日
    瀏覽(26)
  • C語(yǔ)言實(shí)現(xiàn)五子棋小游戲(內(nèi)附源碼)

    C語(yǔ)言實(shí)現(xiàn)五子棋小游戲(內(nèi)附源碼)

    游戲中有人機(jī),雙人兩種模式。五子棋作為一個(gè)平面游戲,很明顯用二維數(shù)組來(lái)寫最合適不過(guò)。為了讓代碼看起來(lái)更有條理,我們用三個(gè).c文件,分別是:text.c 用來(lái)測(cè)試我們的游戲;game.c 游戲功能的實(shí)現(xiàn);is_win.c 判斷輸贏的版塊。另外,還有一個(gè)game.h 文件來(lái)放我們的函數(shù)聲

    2024年02月09日
    瀏覽(28)
  • Java實(shí)現(xiàn)五子棋小游戲(附思路講解,全部代碼,游戲截圖)

    Java實(shí)現(xiàn)五子棋小游戲(附思路講解,全部代碼,游戲截圖)

    本文章是如何實(shí)現(xiàn)一個(gè)單機(jī)版雙人五子棋小游戲,通過(guò)Swing技術(shù)進(jìn)行可視操作. 個(gè)人簡(jiǎn)介: ???♂?個(gè)人主頁(yè):碼云不禿頭. ??本人是一名大三學(xué)生,馬上就要變成考研狗啦,通過(guò)一學(xué)期對(duì)Java學(xué)習(xí),經(jīng)過(guò)老師的教學(xué),實(shí)現(xiàn)單機(jī)版的雙人五子棋小游戲,大家互相學(xué)習(xí),也同時(shí)為了完成我的實(shí)

    2024年02月07日
    瀏覽(23)
  • 趣味益智小游戲 三子棋+五子棋 優(yōu)化版(可任意選擇棋盤大?。? decoding=

    趣味益智小游戲 三子棋+五子棋 優(yōu)化版(可任意選擇棋盤大小)

    今天牛牛給大家分享的是c語(yǔ)言實(shí)現(xiàn)三子棋和五子棋游戲,初學(xué)者可能有些不理解的地方,記得私信提問(wèn)哦,牛牛會(huì)一 一回答的。 《三子棋》是一款益智小游戲,通常是在九宮格里面玩,所以也被稱為”九宮棋“或”井字棋“。 游戲規(guī)則也極其簡(jiǎn)單,只要三子相連即可獲勝。

    2024年01月19日
    瀏覽(23)
  • python實(shí)現(xiàn)五子棋-人機(jī)對(duì)戰(zhàn)/人人對(duì)戰(zhàn)(動(dòng)圖演示+源碼分享)

    python實(shí)現(xiàn)五子棋-人機(jī)對(duì)戰(zhàn)/人人對(duì)戰(zhàn)(動(dòng)圖演示+源碼分享)

    大家好,我是夢(mèng)執(zhí),對(duì)夢(mèng)執(zhí)著。希望能和大家共同進(jìn)步! ? 五子棋對(duì)戰(zhàn)-所有文件文末自取 前言 人人對(duì)戰(zhàn) 動(dòng)態(tài)演示 源碼分享 cheackboard.py 人人對(duì)戰(zhàn).py 導(dǎo)入模塊 設(shè)置棋盤和棋子參數(shù) 局內(nèi)字體設(shè)置 落子循壞體 畫棋盤 畫棋子 運(yùn)行框返回落子坐標(biāo) 執(zhí)行文件 人機(jī)對(duì)戰(zhàn) 動(dòng)態(tài)演示

    2023年04月08日
    瀏覽(22)
  • python五子棋代碼最簡(jiǎn)單的,python五子棋代碼能復(fù)制

    python五子棋代碼最簡(jiǎn)單的,python五子棋代碼能復(fù)制

    本篇文章給大家談?wù)刾ython五子棋代碼紅方藍(lán)方,以及python五子棋代碼最簡(jiǎn)單的,希望對(duì)各位有所幫助,不要忘了收藏本站喔。 開端 畫棋盤 首先肯定是要畫出棋盤來(lái),用? pygame ?畫出一個(gè) 19 × 19 或 15 × 15 的棋盤并不是什么難事,這在之前的文章中已經(jīng)多次用到,就不贅述了

    2024年03月13日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包