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()

 

posted @ 2020-12-23 19:15  Drake19  阅读(252)  评论(0编辑  收藏  举报