PyQt写的五子棋

技术路线

GUI的实现

  1. 使用PyQt技术作为基础。PyQt是一个支持多平台的客户端开发SDK,使用它实现的客户端可以运行在目前几乎所有主流平台之上。
  2. 使用PyQt,Qt设计器实现UI,通过pyuic4 -x -o main_page.py untitled.ui命令将设计好的xml文件转换为python程序。
  3. 继承纯UI的mainWindow类,重写setupUI方法,在UI建立完成之后进行控件的信号-槽的绑定。
  4. 在子类中完成各类事件的响应。

棋盘的绘制

  1. PyQt提供了丰富的控件,如TableView,虽然和棋盘有相似之处,但提供的API过于死板。所以我决定用Widget绘制一个棋盘。
  2. 建立一个QiPan类,继承于QtGui.QWidget 实现它的paintEvent接口,在此接口中可进行Widget的绘制。
  3. 将QiPan的长宽和棋盘格子数进行计算,绘制横纵的直线,完成棋盘的绘制。
  4. 将QiPan类实例化,得到的对象在主窗口setupUI的时候添加到上一层的容器内。

落子位置的判定

  1. 因为用户不可能每次恰好点中横纵线的交点处,所以要对用户点击的位置的坐标进行判定,判断用户想要落子到哪个点
  2. 如图,我将每个点的有效范围扩充至它到邻点的1/2组成的矩形。如图阴影区域: 
  3. 如此,棋盘中每个点都能映射到对应的交点上。

胜利条件判定算法

  1. 因为每次落棋都需要判定当前状态是否有一方胜利,所以胜利条件的判定应当在每次落棋之后进行。
  2. 又因为每次落棋时,落子的一方只有(赢/还没赢)两种状态,所以只需判断落子的一方是否赢得比赛,另一方的棋子无需判断。所以只需从当前落子的棋的4条线上进行判定是否连珠即可。
  3. 4条线分为8个方向,两两对称。因为情况很多,所以我构造了两个数组,dx和dy,如图:

  4. 将数组从[0,3][4,7]分为两部分,分别对应四条线每条线的两个方向。
  5. 如此只需循环遍历8个方向,每个方向出发的4个棋子子,统计这些棋子有多少和中心棋子颜色相同,每个方向的除以4取余数的存储计算结果。
  6. 如果某个方向上第x个棋子已经与中心棋子不同,立即跳出循环,不再继续遍历该方向。
  7. 核心判断代码:
def check_line(self, x, y, map, width, height):
        tag = map[x][y]
        dx = [+1, -1, 0, -1, -1, + 1, 0, +1]
        dy = [-1, 0, -1, -1, +1, 0, +1, +1]
        count = [0] * 4
        for k in xrange(0, 8):
            for i in xrange(1, 5):
                if 0 < x + dx[k] * i < width and 0 < y + dy[k] * i < height and map[x + dx[k] * i][y + dy[k] * i] == tag:
                    count[k % 4] += 1
                else:
                    break
        for k in count:
            if k == 4:
                return True
        return False

悔棋功能的实现

  1. 建立两个栈,分别用作黑棋和白棋的棋子状态,在每次落子时push进该棋子的状态。
  2. 当用户点击悔棋按钮时,从相应的栈中pop出来,恢复上一状态。

工程结构

采用MVC的模式

  • build: 生成可执行文件目录
  • controller:UI的相关控制,相当于C的作用
    1. MyMainWindow.py:继承Ui_MainWindow类,主要控制主窗口
    2. QiPan.py:棋盘类,继承于QWidget,用于棋盘的相关控制
  • libs: 各项判定条件的算法,充当了一部分Model的作用
    1. AI.py:AI类,用来判定输赢条件
    2. BitmapTools.py:封装了对落子在棋盘map中的位置的判定方法
  • resource:图片资源文件夹
  • ui:UI相关代码,View的作用
    1. main_page.py:UI界面的python代码
    2. untitled.ui:UI界面的xml代码

阿萨德 - app.py:主函数入口,用于启动MainWindow

设计模式

单例模式

AI类和BitMapTools都采用单例模式: 好处在于可以只用实例化一次,占用资源少。在棋盘初始化的时候就加载这两个工具类,将它们的实例保存为成员,以后可以频繁地使用这个实例。

class BitMapTools:
    tools = None
    @staticmethod
    def getinstance():
        if BitMapTools.tools is None:
            BitMapTools.tools = BitMapTools()
        return BitMapTools.tools

观察者模式

继承UI相关的类,并重写setupUI,在其中订阅各类点击事件,在相关的函数中处理这些事件发生之后的工作。

self.father.restart_btn.clicked.connect(self.restart)

这样每一个事件对应一个函数,使得结构更加清晰。

from: PyQt写的五子棋

blog: http://cyhhao.zhusun.in/

时间: 10-05

PyQt写的五子棋的相关文章

PyQt写的图片播放器简约版.

用PyQt写的图片播放器. 用线程控制. 线程之间的信号传递. 1 # -*- coding:utf-8 -*- 2 3 from PyQt4 import QtGui, QtCore 4 import sys, os, time 5 6 # from datetime import date, time, datetime, timedelta 7 QtCore.QTextCodec.setCodecForTr(QtCore.QTextCodec.codecForName("utf8"

写给2014的我,技术在哪?

马上就要元旦,想想今年有没有赚到钱? 有没有完成年初时想的目标? 有没有在忙碌中度过没有任何进步的一年? 想想时间匆匆,到了年底总是感叹今年又这么过去了,创业未成(也不是说未成吧,其实算是打工吧). 本来不想说太多,但我觉得写出来听听大家的意见好一点,群众的眼睛是雪亮的. 说起来是这样的,从2012年毕业,当时对游戏比较感兴趣,自己C++也熟悉一点.找到了一家XX游戏公司,这家是做棋牌类的.我刚进去经理让我熟悉公司框架,让我花点时间利用这个框架写个小游戏(当然要是棋牌的最好).然后我就写个五子棋

纯CSS3之五子棋(黑白棋)画法

无聊想用JS写个五子棋玩玩,这边先用CSS3画出了五子棋,感觉挺惊艳的.发上来看看 PS:第一次发博文T-T  此为个人原创. 不多说上图: 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box{ width:500px; heigh

自制html五子棋

花了一个早上写的五子棋,好久不写前端都有些生疏了,有啥好的建议可以反馈给我,谢谢哈. 话不多说,开始介绍. 一,主要三部分 样式代码 <style> *{ margin:0px; padding: 0px; } #box{ width:600px; height:600px; border:1px solid; margin:0px; } .line{ border:1px solid; border-top:0px; border-left:0px; border-right:0px; wi

【源码分享】iOS-OC版五子棋

五子棋是程序猿比较熟悉的一款小游戏,相信很多人大学时期就用多种语言写过五子棋小游戏,笔者工作闲暇之余,试着用OC实现了一下,在这里给大家分享一下.有不足之处,欢迎大家提供建议和指点! GitHub源码链接:https://github.com/HelloYeah/Gomoku-Game 先上效果图 - 功能展示 - 初高级棋盘切换效果 实现思路及主要代码详解 1.绘制棋盘 利用Quartz2D绘制棋盘.代码如下 - (void)drawBackground:(CGSize)size{     

PyQT之多窗口切换

最近做个软件,用PyQT写的,在实现菜单栏点击弹出新窗口的时候严重被卡壳,发现用WxPython的思想和方式来做完全无法实现.PyQT的中文资料实在是太少了.看了点英文资料和QT的资料,逆推PyQT的实现方法,总算搞定.下面是一个小demo. 主界面的代码如下所示: # -*- coding: utf-8 -*- from PyQt4 import QtCore, QtGui from dialog1 import Dialog1 from dialog2 import Dialog2 impo

AI实现五子棋机器人(一)

前言: 前几天在 csdn 下载资源的时候才发现自己 csdn 有近 200 的下载积分,看了看共享的资源,哈哈 ... 7年前写的五子棋游戏很受欢迎. 下载地址:新手入门五子棋游戏     刚入行的时候写的,采用的 "权值" 计算法. 在这个 AI 的浪尖风口上,借助我对游戏领域的热爱,在工作余外的时间唤起了我的想法,学习 AI 实现一个五子棋机器人. 一.五子棋介绍 种类及区别 先说说五子棋吧,通常大家玩的五子棋分为带禁手和不带禁手两个版本, (前者称之为连珠Renju,后者一般称

PyQt:左侧选项卡

写在前面 正在用pyqt写我们比赛项目的客户端,针对左侧选项卡,写了一个简单的demo.记录一下. 环境 Python3.5.2 PyQt5 陈述 用的结构是左边一个QListWidget + 右边QStackedWidget,将QWebView加在QStackedWidget上(因为打算用来展示一些charts,用的pyecharts做的数据可视化,生成的html文件,直接嵌入在客户端内,因此用QWebView来显示,关于pyecharts可以看我另外一篇文章https://www.cnblo

python将下载地址转换成迅雷和qq旋风的下载地址

迅雷和qq旋风下载,有加速和离线功能,很方面,我是在网上看到的原始地址和迅雷地址,qq旋风地址的转化原理,然后用python+pyqt写了一个客户端 原理: 迅雷: 迅雷下载地址="thunder://"+Base64编码("AA"+"真实地址"+"ZZ") QQ旋风: qqdl="qqdl://"+Base64编码("真实地址") import re import base64 fro