使用python實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
用python實(shí)現(xiàn)五子棋簡(jiǎn)單人機(jī)模式的練習(xí)過(guò)程,供大家參考,具體內(nèi)容如下
第一次寫(xiě)博客,我盡力把它寫(xiě)好。
最近在初學(xué)python,今天就用自己的一些粗淺理解,來(lái)記錄一下這幾天的python簡(jiǎn)單人機(jī)五子棋游戲的練習(xí),下面是實(shí)現(xiàn)過(guò)程的理解(是在cmd中運(yùn)行的):
主要流程: *重點(diǎn)內(nèi)容*
- 首先是模塊及類的劃分
- 棋子類和棋盤(pán)類的方法
- 對(duì)策略類里的功能進(jìn)行細(xì)分,調(diào)用棋子類和棋盤(pán)類
- 寫(xiě)出判斷輸贏的方法
- 用main函數(shù)進(jìn)行整個(gè)游戲進(jìn)度的控制
模塊及類的劃分
類的劃分涉及到了面向?qū)ο蟮膬?nèi)容,根據(jù)五子棋游戲的設(shè)定,人和機(jī)器依次在一個(gè)棋盤(pán)里下棋,一方五子連線為贏,初步分為棋子類、棋盤(pán)類和策略類,每個(gè)類單獨(dú)放一個(gè)模塊,加上main模塊一共四個(gè)模塊。
- 棋子類包含棋子的坐標(biāo)和棋子顏色(陣營(yíng)),及相關(guān)get、set方法
- 棋盤(pán)類包含了棋盤(pán)的大小和棋盤(pán)的狀態(tài) ,及相關(guān)get、set方法
- 棋盤(pán)類的功能:接收要放入的棋子,清空棋盤(pán),打印(顯示)棋盤(pán),給出對(duì)應(yīng)位置的狀態(tài)
- 策略類:一個(gè)策略類對(duì)應(yīng)一個(gè)棋盤(pán)類,在構(gòu)造器里導(dǎo)入一個(gè)棋盤(pán)類
- 策略類的功能:人把棋子放入棋盤(pán)、機(jī)器把棋子放入棋盤(pán)、判斷棋局的輸贏
棋子類和棋盤(pán)類
棋子類比較簡(jiǎn)單,在棋子的角度,只要接收位置和顏色(陣營(yíng)),傳出位置和顏色(陣營(yíng))即可,其中位置用元組打包傳遞
class Chessman(object): #初始化 def __init__(self): pass def set_pos(self,pos): self.pos = pos def get_pos(self): return self.pos def set_color(self,color): self.color = color def get_color(self): return self.color
棋盤(pán)類需要用到棋子類,在這之前,先要進(jìn)行棋盤(pán)的設(shè)定
在這里棋盤(pán)是用列表來(lái)構(gòu)建,分為兩層,實(shí)現(xiàn)x,y的位置,棋盤(pán)大小設(shè)為類屬性
#類屬性 board_size =15 #初始化棋盤(pán) def __init__(self): self.__board = [[0 for i in range(0,Chessboard.board_size+1)] for j in range(0,Chessboard.board_size+1)]
清空棋盤(pán)類似
#清空棋盤(pán),‘+'為棋盤(pán)的樣子 def init_board(self): #忽略第0行 for i in range(1,Chessboard.board_size+1): for j in range(1,Chessboard.board_size+1): self.__board[i][j] = '+'
打印也差不多,注意在坐標(biāo)軸旁放上序列號(hào),這里縱坐標(biāo)為1-15,橫坐標(biāo)為a-o
# 打印棋盤(pán) def print_board(self): #打印列號(hào) print(' ', end='') for i in range(1,Chessboard.board_size+1): c = chr(ord('a') + i-1) # ord 字母轉(zhuǎn)ASCLL碼 print(c,end='') print() #棋盤(pán) for i in range(1,Chessboard.board_size+1): if 1<= i <=9: print(' ', end='') print(i, end='') for j in range(1,Chessboard.board_size+1): print(self.__board[i][j], end='') print()
效果為如下
接下來(lái)是棋子的放入:
這個(gè)可分為兩個(gè)方法,一個(gè)根據(jù)傳入的位置放置傳入的顏色;另一個(gè)接收一個(gè)棋子類的實(shí)例對(duì)象,獲取該實(shí)例的位置和顏色,調(diào)用第一個(gè)方法并傳入數(shù)值,一定要注意在傳參的時(shí)候驗(yàn)證
#寫(xiě)入對(duì)應(yīng)位置的顏色 def set_chess(self,pos, color): if not isinstance(pos,tuple): raise RuntimeError('第一個(gè)參數(shù)必須為元組') if pos[0] <= 0 or pos[0] > Chessboard.board_size: raise RuntimeError('行下標(biāo)越界') if pos[1] <=0 or pos[1] > Chessboard.board_size: raise RuntimeError('縱下標(biāo)越界') self.__board[pos[0]][pos[1]] = color #把棋子對(duì)象擺放到棋盤(pán)上 def set_chessman(self,chessman): if not isinstance(chessman, Chessman): raise RuntimeError('類型不對(duì),第一個(gè)參數(shù)應(yīng)為ChessMan對(duì)象') pos = chessman.get_pos() color = chessman.get_color() self.set_chess(pos,color)
接下來(lái)的根據(jù)棋盤(pán)位置獲取棋子顏色的方法主要是為了策略類的判定輸贏準(zhǔn)備的
#根據(jù)棋盤(pán)位置獲取棋子的顏色 def get_chess(self,pos): if pos[0] <= 0 or pos[0] > Chessboard.board_size: raise RuntimeError('行下標(biāo)越界') if pos[1] <=0 or pos[1] > Chessboard.board_size: raise RuntimeError('縱下標(biāo)越界') return self.__board[pos[0]][pos[1]]
策略類
策略類要用到前面兩類,有更多名稱的方法或?qū)傩缘囊?,所以要更仔?xì)一點(diǎn)搞清楚哪個(gè)是哪個(gè)
首先傳入一個(gè)棋盤(pán)實(shí)例對(duì)象
#初始化要把棋盤(pán)對(duì)象傳入 def __init__(self,chessboard): self.__chessboard = chessboard
人下棋:策略類負(fù)責(zé)把人輸入的東西字符串變成x,y坐標(biāo),寫(xiě)入棋子對(duì)象
def parse_user_input(self,input,chessman): if not isinstance(chessman,Chessman): raise RuntimeError('類型不對(duì),第一個(gè)參數(shù)必須為Chessman對(duì)象') ret = input.split(',') value1 = ret[0] value2 = ret[1] #轉(zhuǎn)換成坐標(biāo) pos_x = int(value1) pos_y = ord(value2) - ord('a') +1 chessman.set_pos((pos_x, pos_y)) #print(ret)
機(jī)器下棋:這里具體策略暫用隨機(jī)數(shù)代替了(有空在想,略過(guò)略過(guò)~)
#電腦下棋的策略 def computer_go(self, chessman): if not isinstance(chessman,Chessman): raise RuntimeError('類型不對(duì),第一個(gè)參數(shù)必須為Chessman對(duì)象') while True: # pos_x和pos_y在1~15之間隨機(jī)生成一個(gè)數(shù) pos_x = math.ceil(random.random()*Chessboard.board_size) pos_y = random.randint(1,15) #判斷是否為空,否則重新生成坐標(biāo) if self.__chessboard.get_chess((pos_x,pos_y)) == '+': print('電腦下棋的位置:%d,%d'%(pos_x,pos_y)) chessman.set_pos((pos_x,pos_y)) break
判斷當(dāng)前棋局的勝負(fù):每一方下棋都要判斷一次,因此可根據(jù)當(dāng)前下的一子的范圍來(lái)判斷是否在上下左右和兩斜排有連續(xù)五子,如果有則勝利。
斜排主要是x,y的判斷范圍比較難定,其他的差不多。以下是本寶寶絞盡腦汁想到的判斷方法(特別是斜排的),檢查到目前是沒(méi)有問(wèn)題的,或許還有更好的方法:
#判斷勝負(fù) #當(dāng)擺放一個(gè)棋子,判斷是否贏 def is_won(self,pos,color): #垂直方向的范圍 start_x = 1 end_x = 15 if pos[0] -4 >=1: start_x =pos[0] - 4 if pos[0] +4 <=15: end_x = pos[0]+4 #垂直方向的判斷 count = 0 for pos_x in range(start_x, end_x+1): if self.__chessboard.get_chess((pos_x, pos[1])) == color: count +=1 if count >=5: return True else: # 一旦斷開(kāi) 統(tǒng)計(jì)數(shù)清0 count = 0 #水平方向的范圍 start_y = 1 end_y = 15 if pos[1] -4 >=1: start_y =pos[1] - 4 if pos[1] +4 <=15: end_y = pos[1]+4 #水平方向的判斷 count = 0 for pos_y in range(start_y, end_y+1): if self.__chessboard.get_chess((pos[0], pos_y)) == color: count +=1 if count >=5: return True else: # 一旦斷開(kāi) 統(tǒng)計(jì)數(shù)清0 count = 0 #左上右下方向判斷 count = 0 s=pos[0] - pos[1] start=start_x end=end_y+s if pos[0]>pos[1]: start=start_y+s end=end_x for index in range(start, end+1): if self.__chessboard.get_chess((index, index-s)) == color: count +=1 if count >=5: return True else: # 一旦斷開(kāi) 統(tǒng)計(jì)數(shù)清0 count = 0 #左下右上方向判斷 count = 0 s=pos[0] + pos[1] if pos[0]+pos[1]<=16: start=start_x end=s-start_y if pos[0]+pos[1]>16: start=s-start_y end=start_x if s>=6 and s<=12: for index in range(start, end+1): if self.__chessboard.get_chess((index, s-index)) == color: count +=1 if count >=5: return True else: # 一旦斷開(kāi) 統(tǒng)計(jì)數(shù)清0 count = 0 return False
接下來(lái)再用一個(gè)判斷勝利方的方法調(diào)用上面的策略
#判斷對(duì)象放置后,勝負(fù)是否已分 def is_wonman(self,chessman): if not isinstance(chessman,Chessman): raise RuntimeError('類型不對(duì),第一個(gè)參數(shù)必須為Chessman對(duì)象') pos = chessman.get_pos() color = chessman.get_color() #調(diào)用is_won()獲取它的返回值 return self.is_won(pos,color)
main模塊
main模塊用來(lái)對(duì)整個(gè)游戲的玩法格局進(jìn)行控制。
main函數(shù)實(shí)現(xiàn)一局的流程,這里用循環(huán)來(lái)實(shí)現(xiàn)簡(jiǎn)單的人機(jī)輪流下棋。因?yàn)樘砑恿擞脩暨x擇先后的功能,所以代碼暫時(shí)被我弄得繁瑣了(捂臉)還可以精簡(jiǎn)的,這里就先放這個(gè):
def main(): chessboard =Chessboard() chessboard.init_board() chessboard.print_board() engine = Engine(chessboard) count=0 select = int(input('用戶選擇先后:(先:1,后:2)')) #先 while True: chessman = Chessman() chessman.set_color('x') if select==1: i = input('人下棋,請(qǐng)輸入下棋坐標(biāo)(格式:x,y):') engine.parse_user_input(i, chessman)#轉(zhuǎn)換成坐標(biāo) else: #電腦下棋 print('電腦下棋:') engine.computer_go(chessman) # 把該棋子對(duì)象放到棋盤(pán)上 chessboard.set_chessman(chessman) count +=1 #打印棋盤(pán) chessboard.print_board() if engine.is_wonman(chessman): if select==1: print('人贏了!') else: print('電腦贏了!') break if count == 225: print('平局!') break #后 chessman = Chessman() chessman.set_color('o') if k==1: #電腦下棋 print('電腦下棋:') #電腦給棋子生成策略(位置) engine.computer_go(chessman) else: i = input('人下棋,請(qǐng)輸入下棋坐標(biāo)(格式:x,y):') engine.parse_user_input(i, chessman)#轉(zhuǎn)換成坐標(biāo) #下棋 chessboard.set_chessman(chessman) count +=1 chessboard.print_board() if engine.is_wonman(chessman): if k==1: print('電腦贏了!') else: print('人贏了!') break if count == 225: print('平局!') break
主線程作為程序入口操控每個(gè)棋局:
if __name__ == '__main__': while True: print('開(kāi)始一局!') #調(diào)用main方法 main() s=int(input('是否再來(lái)一局:(是:1,否:0)')) if s!=1: break print('游戲結(jié)束!')
五子棋的簡(jiǎn)單人機(jī)模式就是綜上所述的了,不過(guò)這個(gè)代碼中輸入的地方?jīng)]加檢查,所以坐標(biāo)輸入一定要是數(shù)字加逗號(hào)加字母的格式才行,可以加正則表達(dá)式進(jìn)行判斷。放上效果圖:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- python實(shí)現(xiàn)五子棋小游戲
- python pygame實(shí)現(xiàn)五子棋小游戲
- python實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
- python實(shí)現(xiàn)五子棋游戲(pygame版)
- python五子棋游戲的設(shè)計(jì)與實(shí)現(xiàn)
- python實(shí)現(xiàn)五子棋游戲
- python制作簡(jiǎn)單五子棋游戲
- python實(shí)現(xiàn)五子棋人機(jī)對(duì)戰(zhàn)游戲
- python代碼實(shí)現(xiàn)五子棋游戲
- 使用Python寫(xiě)一個(gè)創(chuàng)意五子棋游戲源代碼
相關(guān)文章
Python函數(shù)中不定長(zhǎng)參數(shù)的寫(xiě)法
今天小編就為大家分享一篇關(guān)于Python函數(shù)中不定長(zhǎng)參數(shù)的寫(xiě)法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02關(guān)于python的第三方庫(kù)下載與更改方式
這篇文章主要介紹了關(guān)于python的第三方庫(kù)下載與更改方式,使用python的朋友都知道python有很多非常方便的第三方庫(kù)可以使用,那么如果下載這些第三方庫(kù)呢,今天小編就帶你們來(lái)看看2023-04-04Python的dict字典結(jié)構(gòu)操作方法學(xué)習(xí)筆記
這篇文章主要介紹了Python的dict字典結(jié)構(gòu)操作方法學(xué)習(xí)筆記本,字典的操作是Python入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-05-05在Python中使用PIL模塊對(duì)圖片進(jìn)行高斯模糊處理的教程
這篇文章主要介紹了在Python中使用PIL模塊對(duì)圖片進(jìn)行高斯模糊處理的教程,這個(gè)無(wú)圖形界面的腳本代碼非常簡(jiǎn)單,需要的朋友可以參考下2015-05-05

python中重啟for循環(huán),使其重新開(kāi)始遍歷