wxPython五子棋
期末了!!!做了个五子棋,没有使用布局组件,主要内容是代码绘制的......
用到了递归判断输赢,实现了五子棋开局算法。
按钮是用矩形加文字来代替的...文字居中。这样做显得我的代码高深,老师更容易给分。好耶!!!
有许多数值和勉强能用的算法,让人难以阅读。。。
┑( ̄Д  ̄)┍
鼠标左键双击落子!!!其它的自行体验好啦。
以下是我的参考版代码...
#!/usr/bin/python # -*- coding: UTF-8 -*- import wx import random import sys # ChessBackLeft ChessPositionLeft Tools.DrawGoBang(两个位置) # ChessBackTop ChessPositionTop dc.DrawRectangle(棋谱的线、点、数字、字母) ChessSpace = 26 ChessRadius = 12 ChessBackLeft = 203 ChessBackTop = 23 ChessPositionLeft = 216 ChessPositionTop = 36 crNum = 15 ButtonLeft = 28 ButtonTop = 40 ButtonWidth = 111 class GoBang(): NONE = 0 BLACK = 1 WHITE = 2 # 自定义窗体 class GobangFrame(wx.Frame): blackPlayerNow = True chesses = [[GoBang.NONE for i in range(crNum)] for j in range(crNum)] """ We simply derive a new class of Frame. """ def __init__(self, parent, title, height, width): wx.Frame.__init__(self, parent, title=title, size=(height,width)) # 文本框 # self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE) self.CreateStatusBar() # A Statusbar in the bottom of the window # Setting up the menu. filemenu= wx.Menu() # wx.ID_ABOUT and wx.ID_EXIT are standard ids provided by wxWidgets. menuAbout = filemenu.Append(wx.ID_ABOUT, "&帮助"," Information about this program") menuExit = filemenu.Append(wx.ID_EXIT,"&退出"," Terminate the program") # Creating the menubar. menuBar = wx.MenuBar() menuBar.Append(filemenu,"&菜单") # Adding the "filemenu" to the MenuBar self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content. # 绘制UI self.InitUI() # 事件绑定 # Set events. self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout) self.Bind(wx.EVT_MENU, self.OnExit, menuExit) self.Bind(wx.EVT_LEFT_DOWN , self.on_left_down) self.Bind(wx.EVT_LEFT_UP , self.on_left_up) self.Bind(wx.EVT_LEFT_DCLICK, self.on_left_click) # 窗口居中 self.Centre() self.Show(True) def OnAbout(self,e): # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets. dlg = wx.MessageDialog( self, "1.用户双击鼠标左键来落子。\n2.本程序默认启用初始开局。\n3.点击“重新开始”则重新开始游戏并重新开局。\n4.联机对战模式还在开发中,敬请期待。", "关于本程序", wx.OK) dlg.ShowModal() # Show it dlg.Destroy() # finally destroy it when finished. def OnExit(self,e): self.Close(True) # Close the frame. # 初始化UI界面 初始化动画 def InitUI(self): # 只能用一个 self.Bind(wx.EVT_PAINT, self.OnPaint) self.Centre() self.Show(True) self.GobangGambit() def GobangGambit(self): # 五子棋开局算法 if True: # 黑白黑 secondChess = random.randint(0,1) thirdChess = random.randint(0,23) self.chesses[7][7] = GoBang.BLACK if secondChess == 0: self.chesses[7][6] = GoBang.WHITE if thirdChess > 6: thirdChess+=1 else: self.chesses[8][6] = GoBang.WHITE if thirdChess > 7: thirdChess+=1 if thirdChess > 11 and thirdChess != 24: thirdChess+=1 self.chesses[5+thirdChess%5][5+thirdChess//5] = GoBang.BLACK # 轮到白色玩家 self.blackPlayerNow = False # 向左边(left)递归 def goBangL(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if left-1 >= 0: if self.chesses[left-1][top] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangL(left-1, top, step+1, aim) # 向右(right)递归 def goBangR(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if left+1 < crNum: if self.chesses[left+1][top] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangR(left+1, top, step+1, aim) # 向上(top)递归 def goBangT(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if top-1 >=0: if self.chesses[left][top-1] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangT(left, top-1, step+1, aim) # 向下(bottom)递归 def goBangB(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if top+1 < crNum: if self.chesses[left][top+1] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangB(left, top+1, step+1, aim) # 向左上(left top)递归 def goBangLT(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if left-1 >= 0 and top-1 >= 0: if self.chesses[left-1][top-1] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangLT(left-1, top-1, step+1, aim) # 向右上(right top)递归 def goBangRT(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if left+1 < crNum and top-1 >=0: if self.chesses[left+1][top-1] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangRT(left+1, top-1, step+1, aim) # 向左下(left bottom)递归 def goBangLB(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if left-1 >= 0 and top+1 < crNum: if self.chesses[left-1][top+1] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangLB(left-1, top+1, step+1, aim) # 向右下(right bottom)递归 def goBangRB(self, left, top, step, aim): # 防止异常(几率很小) if step >= 4: return 0 num = 0 if left+1 < crNum and top+1 < crNum: if self.chesses[left+1][top+1] == aim: num += 1 else: return 0 else: return 0 return num + self.goBangRB(left+1, top+1, step+1, aim) # 每次重新绘制时都会运行 def OnPaint(self, e): self.Paint() # 绘制 def Paint(self): # dc = wx.PaintDC(self) dc = wx.ClientDC(self) brush = wx.Brush("white") dc.SetBackground(brush) dc.Clear() color = wx.Colour(255,0,0) b = wx.Brush(color) Tools.DrawGoBang(self) def on_left_click(self, event): dc = wx.ClientDC(self) if event.GetPosition().x > ChessBackLeft and event.GetPosition().y > ChessBackTop and event.GetPosition().x < ChessBackLeft+crNum*ChessSpace and event.GetPosition().y < ChessBackTop+crNum*ChessSpace: # 棋子位于棋谱的坐标 chessLeft = (event.GetPosition().x - ChessBackLeft)//ChessSpace chessTop = (event.GetPosition().y - ChessBackTop)//ChessSpace if self.chesses[chessLeft][chessTop] == 0: # 颜色 if self.blackPlayerNow: self.blackPlayerNow = False dc.SetBrush(wx.Brush(wx.Colour(0,0,0))) self.chesses[chessLeft][chessTop] = GoBang.BLACK else: self.blackPlayerNow = True dc.SetBrush(wx.Brush(wx.Colour(255,255,255))) self.chesses[chessLeft][chessTop] = GoBang.WHITE # 画棋子 CircleLeft = (chessLeft) * ChessSpace + ChessBackLeft + ChessSpace//2 CircleTop = (chessTop) * ChessSpace + ChessBackTop + ChessSpace//2 dc.DrawCircle(CircleLeft,CircleTop,ChessRadius) # 判断 左+右 上+下 左上+右下 左下+右上 aimChessColor = self.chesses[chessLeft][chessTop] if self.goBangL(chessLeft,chessTop,0,aimChessColor)+self.goBangR(chessLeft,chessTop,0,aimChessColor)>=4 or self.goBangT(chessLeft,chessTop,0,aimChessColor)+self.goBangB(chessLeft,chessTop,0,aimChessColor)>=4: if self.chesses[chessLeft][chessTop] == GoBang.BLACK: wx.MessageBox("Black player is vectory!", "Message" ,wx.OK) else: wx.MessageBox("White player is vectory!", "Message" ,wx.OK) self.chesses = [[GoBang.NONE for i in range(crNum)] for j in range(crNum)] self.blackPlayerNow = True self.GobangGambit() self.Paint() elif self.goBangLT(chessLeft,chessTop,0,aimChessColor)+self.goBangRB(chessLeft,chessTop,0,aimChessColor)>=4 or self.goBangLB(chessLeft,chessTop,0,aimChessColor)+self.goBangRT(chessLeft,chessTop,0,aimChessColor)>=4: if self.chesses[chessLeft][chessTop] == GoBang.BLACK: wx.MessageBox("Black player is vectory!", "Message" ,wx.OK) else: wx.MessageBox("White player is vectory!", "Message" ,wx.OK) self.chesses = [[GoBang.NONE for i in range(crNum)] for j in range(crNum)] self.blackPlayerNow = True self.GobangGambit() self.Paint() def on_left_down(self, event): if event.LeftIsDown(): pos = event.GetPosition() if pos[0] >= ButtonLeft and pos[0] <= ButtonLeft + ButtonWidth: tempTop = pos[1] tempTop = tempTop - ButtonTop if tempTop>=0 and tempTop <5*58: tempId = tempTop//58 tempTop = tempTop%58 if tempTop <= 40: # print(tempId) # tempId 为0指 第一个按钮的位置 if tempId == 0: self.chesses = [[GoBang.NONE for i in range(crNum)] for j in range(crNum)] self.blackPlayerNow = True self.GobangGambit() self.Paint() def on_left_up(self, event): # print('left up') pass class Tools(): def __init__(self): pass @classmethod def DrawGoBang(cls,self): dc = wx.ClientDC(self) # 棋谱 pen = wx.Pen(wx.Colour(0,0,0)) dc.SetPen(pen) # 填充色 dc.SetBrush(wx.Brush('#000000')) dc.DrawRectangle(213+ 3*26, 33+ 3*26 , 6, 6) dc.DrawRectangle(213+ 3*26, 33+11*26 , 6, 6) dc.DrawRectangle(213+11*26, 33+ 3*26 , 6, 6) dc.DrawRectangle(213+11*26, 33+11*26 , 6, 6) dc.DrawRectangle(212+ 7*26, 32+ 7*26 , 8, 8) # 棋谱边上的数字和字母 chessNumber = 1 chessCharacter = 65 # 字体设置 font = wx.Font(12, wx.ROMAN, wx.NORMAL, wx.BOLD) dc.SetFont(font) # 绘制棋谱 for i in range(0, crNum): dc.DrawRectangle(200, 35+i*26 ,103+21*14, 2) dc.DrawRectangle(215+i*26, 20 ,2, 103+21*14) dc.DrawText(chr(chessCharacter + i),183,26+i*26) dc.DrawText(str(chessNumber + i),212+i*26-(i//9)*5,0) # 绘制按键框 for i in range(0, 5): dc.SetBrush(wx.Brush('#525278')) dc.DrawRectangle(ButtonLeft, ButtonTop+i*58 , ButtonWidth, 40) dc.SetBrush(wx.Brush('#FFFFFF')) dc.DrawRectangle(ButtonLeft + 5, ButtonTop+5+i*58 , ButtonWidth-10, 30) # 绘制按键文字 font = wx.Font(16, wx.ROMAN, wx.NORMAL, wx.BOLD) dc.SetFont(font) tempContentTop = ButtonTop + 8 dc.DrawText("重新开始",ButtonLeft + 55 - len("重新开始") * 11.5,tempContentTop) tempContentTop = tempContentTop + 58 dc.DrawText("临时",ButtonLeft + 55 - len("临时") * 11.5,tempContentTop) tempContentTop = tempContentTop + 58 dc.DrawText("临 时",ButtonLeft + 55 - len("临时") * 11.5 - len(" ") * 3,tempContentTop) tempContentTop = tempContentTop + 58 dc.DrawText("临时时",ButtonLeft + 55 - len("临时时") * 11.5,tempContentTop) tempContentTop = tempContentTop + 58 dc.DrawText("临时",ButtonLeft + 55 - len("临时") * 11.5,tempContentTop) for i in range(crNum): for j in range(crNum): if self.chesses[i][j] == GoBang.NONE: continue elif self.chesses[i][j] == GoBang.BLACK: dc.SetBrush(wx.Brush(wx.Colour(0,0,0))) # 绘制棋子 CircleX = i * ChessSpace + ChessBackLeft + ChessSpace//2 CircleY = j * ChessSpace + ChessBackTop + ChessSpace//2 dc.DrawCircle(CircleX,CircleY,ChessRadius) # 打印坐标和棋子值 # print(i," ",j," ",self.chesses[i][j]) elif self.chesses[i][j] == GoBang.WHITE: dc.SetBrush(wx.Brush(wx.Colour(255,255,255))) # 绘制棋子 CircleX = i * ChessSpace + ChessBackLeft + ChessSpace//2 CircleY = j * ChessSpace + ChessBackTop + ChessSpace//2 dc.DrawCircle(CircleX,CircleY,ChessRadius) # 打印坐标和棋子值 # print(i," ",j," ",self.chesses[i][j]) def Client(): app = wx.App(False) # Create a new app, don't redirect stdout/stderr to a window. # frame = wx.Frame(None, wx.ID_ANY, "Hello World") # A Frame is a top-level window. frame = GobangFrame(None, 'Gobang', 700, 560) frame.Show(True) # Show the frame. app.MainLoop() if __name__ == "__main__": Client()