采用 pygame 写的象棋程序,目前只完成绘制棋盘与走动棋子,还没考虑规则等问题。

1. 代码:

  1. """ x01.xiangqi (c) 2019 by x01"""
  2.  
  3. import os, sys, pygame
  4. from pygame.locals import *
  5.  
  6. BaseDir = os.path.dirname(os.path.abspath(__file__))
  7. ImagePath = BaseDir + '/res/'
  8.  
  9. BoardWidth = 520
  10. BoardHeight = 576
  11. BoardEdge = 8
  12. PieceSize = 56
  13.  
  14. # piece type
  15. King = 0
  16. Advisor = 1
  17. Bishop = 2
  18. Knight = 3
  19. Rook = 4
  20. Cannon = 5
  21. Pawn = 6
  22. Selected = 7
  23.  
  24. # piece types
  25. types = [
  26. 20, 19, 18, 17, 16, 17, 18, 19, 20,
  27. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  28. 0, 21, 0, 0, 0, 0, 0, 21, 0,
  29. 22, 0, 22, 0, 22, 0, 22, 0, 22,
  30. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  31. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  32. 14, 0, 14, 0, 14, 0, 14, 0, 14,
  33. 0, 13, 0, 0, 0, 0, 0, 13, 0,
  34. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  35. 12, 11, 10, 9, 8, 9, 10, 11, 12
  36. ]
  37.  
  38. class Piece(object):
  39. def __init__(self, player, ptype, name, pos):
  40. self.player = player
  41. self.ptype = ptype
  42. self.name = name
  43. self.pos = pos
  44.  
  45. pieces = [
  46. # black
  47. Piece(0, King, "bk.bmp", (4,0)),
  48. Piece(0, Advisor, "ba.bmp", (3,0)),Piece(0, Advisor, "ba.bmp", (5,0)),
  49. Piece(0, Bishop, "bb.bmp", (2,0)), Piece(0, Bishop, "bb.bmp", (6,0)),
  50. Piece(0, Knight, "bn.bmp", (1,0)), Piece(0, Knight, "bn.bmp", (7,0)),
  51. Piece(0, Rook, "br.bmp", (0,0)), Piece(0, Rook, "br.bmp", (8,0)),
  52. Piece(0, Cannon, "bc.bmp", (1,2)), Piece(0, Cannon, "bc.bmp", (7,2)),
  53. Piece(0, Pawn, "bp.bmp", (0,3)), Piece(0, Pawn, "bp.bmp", (2,3)),
  54. Piece(0, Pawn, "bp.bmp", (4,3)),Piece(0, Pawn, "bp.bmp", (6,3)),Piece(0, Pawn, "bp.bmp", (8,3)),
  55.  
  56. # red
  57. Piece(1, King, "rk.bmp", (4,9)),
  58. Piece(1, Advisor, "ra.bmp", (3,9)),Piece(1, Advisor, "ra.bmp", (5,9)),
  59. Piece(1, Bishop, "rb.bmp", (2,9)), Piece(1, Bishop, "rb.bmp", (6,9)),
  60. Piece(1, Knight, "rn.bmp", (1,9)), Piece(1, Knight, "rn.bmp", (7,9)),
  61. Piece(1, Rook, "rr.bmp", (0,9)), Piece(1, Rook, "rr.bmp", (8,9)),
  62. Piece(1, Cannon, "rc.bmp", (1,7)), Piece(1, Cannon, "rc.bmp", (7,7)),
  63. Piece(1, Pawn, "rp.bmp", (0,6)), Piece(1, Pawn, "rp.bmp", (2,6)),
  64. Piece(1, Pawn, "rp.bmp", (4,6)),Piece(1, Pawn, "rp.bmp", (6,6)),Piece(1, Pawn, "rp.bmp", (8,6)),
  65.  
  66. # selected
  67. Piece(2, Selected, 'selected.bmp', (0,0))
  68. ]
  69.  
  70. # type index
  71. def index(pos):
  72. col,row = pos[0], pos[1]
  73. return row * 9 + col
  74.  
  75. def draw(surface, name, xy, ispiece=True):
  76. img = pygame.image.load(ImagePath + name).convert()
  77. if ispiece:
  78. img.set_colorkey((0,255,0))
  79. surface.blit(img, xy)
  80.  
  81. def draw_pieces(surface):
  82. for p in pieces[:-1]:
  83. x = p.pos[0] * PieceSize + BoardEdge
  84. y = p.pos[1] * PieceSize + BoardEdge
  85. draw(surface, p.name, (x,y))
  86.  
  87. def run():
  88. pygame.init()
  89. screen = pygame.display.set_mode((BoardWidth, BoardHeight),0,32)
  90. pygame.display.set_caption('x01.xiangqi')
  91. draw(screen, 'board.bmp', (0,0), False)
  92. draw_pieces(screen)
  93.  
  94. prevPiece = None
  95. player = 1
  96. clock = pygame.time.Clock()
  97. while True:
  98. for event in pygame.event.get():
  99. if event.type == QUIT:
  100. sys.exit()
  101. if event.type == KEYDOWN:
  102. if event.key == K_ESCAPE:
  103. sys.exit()
  104. if event.type == MOUSEBUTTONDOWN:
  105. x,y = pygame.mouse.get_pos()
  106. x,y = ((x // PieceSize) * PieceSize + BoardEdge, (y//PieceSize)*PieceSize + BoardEdge)
  107. pos = (x//PieceSize, y//PieceSize)
  108.  
  109. draw(screen,'board.bmp',(0,0),False)
  110. draw_pieces(screen)
  111. pieces[-1].pos = pos
  112. draw(screen, pieces[-1].name, (x,y))
  113.  
  114. for p in pieces[:-1]:
  115. if p.pos == pos:
  116. prevPiece = p
  117. break
  118.  
  119. if types[index(pos)] == 0 and prevPiece != None:
  120. if player != prevPiece.player:
  121. continue
  122. player = 1 - player
  123. if prevPiece.player == 0:
  124. types[index(pos)] = prevPiece.ptype + 16
  125. elif prevPiece.player == 1:
  126. types[index(pos)] = prevPiece.ptype + 8
  127. types[index(prevPiece.pos)] = 0
  128. for p in pieces[:-1]:
  129. if p.pos == prevPiece.pos:
  130. p.pos = pos
  131. break
  132. prevPiece = None
  133.  
  134. draw(screen,'board.bmp',(0,0),False)
  135. draw_pieces(screen)
  136. draw(screen, pieces[-1].name, (x,y))
  137.  
  138. clock.tick(40)
  139. pygame.display.update()
  140.  
  141. if __name__ == '__main__':
  142. run()

main.py

2. 效果图:

3. 下载链接:(x01.lab => py => xiangqi)

x01.xiangqi

附: md 批量转换到 pdf 文件

a) 需安装 pandoc, 拷贝 template.tex 到 /usr/share/pandoc/data/templates/ 目录中。

b) 需安装中文字体。

c) 需安装 xelatex.

d) 代码 md2pdfs.py 及模板 template.tex 如下:

  1. from pathlib import Path
  2. import os
  3.  
  4. def md2pdfs(currdir='.'):
  5. dir = os.path.abspath(currdir)
  6. files = os.listdir(dir)
  7. for f in files:
  8. path = os.path.join(dir, f)
  9. if os.path.isdir(path):
  10. md2pdfs(path)
  11. dir = os.path.dirname(path)
  12. continue
  13. name = os.path.splitext(f)[0]
  14. ext = os.path.splitext(f)[1]
  15. if ext == '.md':
  16. mdfile = f
  17. pdffile = name + '.pdf'
  18. os.chdir(dir)
  19. print(os.getcwd() + '/' + f)
  20. cmd = "pandoc '{0}' -o '{1}' --latex-engine=xelatex -V mainfont='PingFang SC' --template=template.tex".format(mdfile, pdffile)
  21. os.system(cmd)
  22.  
  23. if __name__ == '__main__':
  24. md2pdfs()

md2pdfs.py

  1. \documentclass[12pt]{article}
  2. \usepackage{xeCJK}
  3. \setCJKmainfont{SimSun}
  4. $if(fontfamily)$
  5. \usepackage{$fontfamily$}
  6. $else$
  7. \usepackage{lmodern}
  8. $endif$
  9. $if(linestretch)$
  10. \usepackage{setspace}
  11. \setstretch{$linestretch$}
  12. $endif$
  13.  
  14. % 图片设置
  15. \usepackage{graphicx}
  16. % 可以指定根目录下的image文件夹为图片文件夹
  17. \graphicspath{{image/}}
  18.  
  19. % 页面设置
  20. \usepackage[a4paper]{geometry}
  21. \geometry{
  22. left=2.54cm,
  23. right=2.54cm,
  24. top=3.18cm,
  25. bottom=3.18cm,
  26. footskip=1.48cm,
  27. headsep=.5cm,
  28. headheight=1.5cm
  29. }
  30.  
  31. \usepackage{amssymb,amsmath}
  32. \usepackage{ifxetex,ifluatex}
  33. \usepackage{fixltx2e} % provides \textsubscript
  34. \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  35. \usepackage[T1]{fontenc}
  36. \usepackage[utf8]{inputenc}
  37. $if(euro)$
  38. \usepackage{eurosym}
  39. $endif$
  40. \else % if luatex or xelatex
  41. \ifxetex
  42. \usepackage{xltxtra,xunicode}
  43. \else
  44. \usepackage{fontspec}
  45. \fi
  46. \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
  47. \newcommand{\euro}{€}
  48.  
  49. % $if(mainfont)$
  50. % \setmainfont{$mainfont$}
  51. % $endif$
  52. % $if(sansfont)$
  53. % \setsansfont{$sansfont$}
  54. % $endif$
  55. % $if(monofont)$
  56. % \setmonofont[Mapping=tex-ansi]{$monofont$}
  57. % $endif$
  58. % $if(CJKmainfont)$
  59. % \usepackage{xeCJK}
  60. % \setCJKmainfont[$CJKoptions$]{$CJKmainfont$}
  61. % $endif$
  62.  
  63. % 字体的设置,可以自行修改
  64. % \usepackage{xeCJK}
  65. % 【推荐】第一种设置
  66. % XeLaTeX在编译时会自动选择思源宋体的bold部分
  67. % 不设置monofont,因为有些字符在其他指定字符的出现变形,不如默认字体美观
  68. % \setCJKmainfont{思源宋体 CN}
  69. % \setCJKsansfont{思源黑体 CN}
  70. % \setmainfont{思源宋体 CN}
  71. % \setsansfont{思源黑体 CN}
  72. % 【列示】第二种设置
  73. % \setCJKmainfont{思源宋体}[BoldFont = 思源黑体 Regular]
  74. %\setCJKmonofont{思源黑体 Light}
  75. % \setCJKsansfont{思源黑体 Regular}
  76. % \setmainfont{IBM Plex Serif}
  77. % \setmonofont{IBM Plex Mono}
  78. % \setsansfont{IBM Plex Sans}
  79.  
  80. \fi
  81. % use upquote if available, for straight quotes in verbatim environments
  82. \IfFileExists{upquote.sty}{\usepackage{upquote}}{}
  83. % use microtype if available
  84. \IfFileExists{microtype.sty}{%
  85. \usepackage{microtype}
  86. \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
  87. }{}
  88.  
  89. \ifxetex
  90. \usepackage[setpagesize=false, % page size defined by xetex
  91. unicode=false, % unicode breaks when used with xetex
  92. xetex]{hyperref}
  93. \else
  94. \usepackage[unicode=true]{hyperref}
  95. \fi
  96. \usepackage[usenames,dvipsnames]{color}
  97. \hypersetup{breaklinks=true,
  98. bookmarks=true,
  99. pdfauthor={$author-meta$},
  100. pdftitle={$title-meta$},
  101. colorlinks=true,
  102. citecolor=$if(citecolor)$$citecolor$$else$blue$endif$,
  103. urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,
  104. linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,
  105. pdfborder={0 0 0}}
  106. \urlstyle{same} % don't use monospace font for urls
  107. $if(lang)$
  108. \ifxetex
  109. \usepackage{polyglossia}
  110. \setmainlanguage{$mainlang$}
  111. \setotherlanguages{$for(otherlang)$$otherlang$$sep$,$endfor$}
  112. \else
  113. \usepackage[shorthands=off,$lang$]{babel}
  114. \fi
  115. $endif$
  116. $if(natbib)$
  117. \usepackage{natbib}
  118. \bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
  119. $endif$
  120. $if(biblatex)$
  121. \usepackage{biblatex}
  122. $for(bibliography)$
  123. \addbibresource{$bibliography$}
  124. $endfor$
  125. $endif$
  126. $if(listings)$
  127. \usepackage{listings}
  128. $endif$
  129. $if(lhs)$
  130. \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
  131. $endif$
  132. $if(highlighting-macros)$
  133. $highlighting-macros$
  134. $endif$
  135. $if(verbatim-in-note)$
  136. \usepackage{fancyvrb}
  137. \VerbatimFootnotes
  138. $endif$
  139. $if(tables)$
  140. \usepackage{longtable,booktabs}
  141. $endif$
  142. $if(graphics)$
  143. \usepackage{graphicx,grffile}
  144. \makeatletter
  145. \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
  146. \def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
  147. \makeatother
  148. % Scale images if necessary, so that they will not overflow the page
  149. % margins by default, and it is still possible to overwrite the defaults
  150. % using explicit options in \includegraphics[width, height, ...]{}
  151. \setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
  152. $endif$
  153. $if(links-as-notes)$
  154. % Make links footnotes instead of hotlinks:
  155. \renewcommand{\href}[2]{#2\footnote{\url{#1}}}
  156. $endif$
  157. $if(strikeout)$
  158. \usepackage[normalem]{ulem}
  159. % avoid problems with \sout in headers with hyperref:
  160. \pdfstringdefDisableCommands{\renewcommand{\sout}{}}
  161. $endif$
  162. \setlength{\emergencystretch}{3em} % prevent overfull lines
  163. \providecommand{\tightlist}{%
  164. \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
  165. $if(numbersections)$
  166. \setcounter{secnumdepth}{5}
  167. $else$
  168. \setcounter{secnumdepth}{0}
  169. $endif$
  170. $if(verbatim-in-note)$
  171. \VerbatimFootnotes % allows verbatim text in footnotes
  172. $endif$
  173.  
  174. $if(title)$
  175. \title{\bfseries \huge $title$$if(subtitle)$\\\vspace{0.5cm}{\Large $subtitle$}$endif$}
  176. $endif$
  177. $if(author)$
  178. \author{\LARGE $for(author)$$author$$sep$ \and $endfor$}
  179. $endif$
  180. \date{{\large \today}}
  181. $for(header-includes)$
  182. $header-includes$
  183. $endfor$
  184.  
  185. % Redefines (sub)paragraphs to behave more like sections
  186. \ifx\paragraph\undefined\else
  187. \let\oldparagraph\paragraph
  188. \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
  189. \fi
  190. \ifx\subparagraph\undefined\else
  191. \let\oldsubparagraph\subparagraph
  192. \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
  193. \fi
  194.  
  195. \begin{document}
  196. $if(title)$
  197. \maketitle
  198. $endif$
  199. $if(abstract)$
  200. \begin{abstract}
  201. $abstract$
  202. \end{abstract}
  203. $endif$
  204.  
  205. $for(include-before)$
  206. $include-before$
  207.  
  208. $endfor$
  209. $if(toc)$
  210. {
  211. \setcounter{tocdepth}{$toc-depth$}
  212. \tableofcontents
  213. }
  214. $endif$
  215. $if(lot)$
  216. \listoftables
  217. $endif$
  218. $if(lof)$
  219. \listoffigures
  220. $endif$
  221. $body$
  222.  
  223. $if(natbib)$
  224. $if(bibliography)$
  225. $if(biblio-title)$
  226. $if(book-class)$
  227. \renewcommand\bibname{$biblio-title$}
  228. $else$
  229. \renewcommand\refname{$biblio-title$}
  230. $endif$
  231. $endif$
  232. \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}
  233.  
  234. $endif$
  235. $endif$
  236. $if(biblatex)$
  237. \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
  238.  
  239. $endif$
  240. $for(include-after)$
  241. $include-after$
  242.  
  243. $endfor$
  244. \end{document}

template.tex

e) 合并 pdf 代码 merge_pdf.py 如下:

  1. # merge_pdf.py
  2. # usage:
  3. # 复制到目标目录,由终端进入,运行 "python3 merge_pdf.py" 命令即可。
  4.  
  5. import os
  6. from PyPDF2 import PdfFileReader, PdfFileWriter
  7.  
  8. filenames = []
  9. outfile = '../temp.pdf'
  10.  
  11. def getfiles(curr_dir='.', ext='.pdf'):
  12. global filenames
  13. dir = os.path.abspath(curr_dir)
  14. files = os.listdir(dir)
  15. for f in files:
  16. path = os.path.join(dir,f)
  17. if os.path.isdir(path):
  18. getfiles(path, ext)
  19. continue
  20. extname = os.path.splitext(f)[1]
  21. if ext == extname:
  22. filenames.append(os.path.join(dir,f))
  23.  
  24. def merge():
  25. getfiles()
  26. filenames.sort()
  27. writer = PdfFileWriter()
  28. pages = 0
  29. for f in filenames:
  30. print(f)
  31. reader = PdfFileReader(open(f, 'rb'))
  32. count = reader.getNumPages()
  33. pages += count
  34. for i in range(count):
  35. writer.addPage(reader.getPage(i))
  36. writer.addBookmark(os.path.basename(f)[:-3],pages - count)
  37. stream = open(outfile, 'wb')
  38. writer.write(stream)
  39. stream.close()
  40. print("OK!")
  41.  
  42. def test(dir='.'):
  43. dirs = os.listdir(dir)
  44. for f in dirs:
  45. if os.path.isdir(f):
  46. test(f)
  47. continue
  48. print(f)
  49.  
  50. if __name__ == '__main__':
  51. filenames.clear()
  52. merge()

merge_pdf.py

又:github 上的 python-100 项目转换后的下载链接:  py100days.pdf

x01.xiangqi: 走动棋子的更多相关文章

  1. x01.Weiqi.12: 定式布局

    定式 下一步当将定式保存到数据库中,如布局中的代码所示,但其初始的代码更有利于理解.以小飞挂为例: // 0 // + 0 0 // + // // + List<Pos> P_LuSta ...

  2. x01.Weiqi.7: 调整重绘

    GitHub 谁方便谁拍,谁重要拍谁.在这个砖头满天飞的时代,一个好的生态显得尤为重要.  红颜小头发,要的很简单. 也许成绝唱,只因鱼断肠. 姚贝福娃的离去,除感叹人生无常外,活着做点有意义的事情, ...

  3. HDU 4121 Xiangqi 我老了?

    Xiangqi Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  4. HDU 4121 Xiangqi 模拟题

    Xiangqi Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4121 ...

  5. JavaScript中国象棋程序(2) - 校验棋子走法

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第2节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  6. Uva - 1589 - Xiangqi

    Xiangqi is one of the most popular two-player board games in China. The game represents a battle bet ...

  7. Xiangqi(简单模拟)

    4746: Xiangqi 时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte 总提交: 15            测试通过:2 描述 Xiangqi i ...

  8. x01.Tetris: 俄罗斯方块

    最强大脑有个小孩玩俄罗斯方块游戏神乎其技,那么,就写一个吧,玩玩而已. 由于逻辑简单,又作了一些简化,所以代码并不多. using System; using System.Collections.G ...

  9. x01.MagicCube: 简单操作

    看最强大脑,发现魔方还是比较好玩的,便买了一个,对照七步还原法,居然也能成功还原. 为什么不写一个魔方程序呢?在网上找了找,略作修改,进行简单操作,还是不错的,其操作代码如下: protected o ...

随机推荐

  1. <linux下extmail服务的搭建>

    下载2个软件包: extmail-1.1.0.tar.gz     extman-1.1.tar.gz 下载地址:http://www.cpan.org/ 创建extsuite目录 mkdir /va ...

  2. css最佳实践(reset.css)

    html, body, div, span, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,abbr, address, cite ...

  3. Css文件目录结构

    一般一个网站会有这么三个样式: global.css | reset.css(格式化样式) common.css(公共组件样式) layout.css(当前页面样式) global.css | res ...

  4. 报错:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    参考原文:http://bbs.csdn.net/topics/390121452 项目>属性>配置属性>清单工具>输入和输出>嵌入清单:原来是“是”,改成“否” 如果上 ...

  5. redis在Windows下以后台服务一键搭建集群(多机器)

    redis在Windows下以后台服务一键搭建集群(多机器) 一.概述 此教程介绍如何在windows系统中多台机器之间布置redis集群,同时要以后台服务的模式运行.布置以脚本的形式,一键完成.多台 ...

  6. ssh登录卡住问题

    使用ssh登录远程centos服务器,卡住不动 系统centos 7 加-v查看登录过程,一直卡在这里 解决:我的是mtu问题 将eth0 mtu 默认1500修改为1200就可以了 ifconfig ...

  7. LeetCode Valid Anagram (简单题)

    题意: 给出两个字符串s和t,判断串t是否为s打乱后的串. 思路: 如果返回的是true,则两个串的长度必定相等,所有字符出现的次数一样.那么可以统计26个字母的次数来解决,复杂度O(n).也可以排序 ...

  8. c++ STL list容器成员函数

    list是一个双链表. 函数 描述 void l.assign (int n, const val) void l.assign (it first, it last) 将链表l初始化为n个相同的va ...

  9. jquery datatable 获取当前分页的数据

    使用jquery datatable 遇到分页分别求和时,找了半天才找到获取当前分页数据的方法,以此总结 var table=$('#example').DataTable( { "pagi ...

  10. java Vamei快速教程03 构造器和方法重载

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initial ...