今天分享给大家的是采用Python3+tkinter制作而成的小项目——黑白棋

tkinter是Python内置的图形化模块,简单易用,一般的小型UI程序可以快速用它实现,具体的tkinter相关知识王老师会在以后开辟专栏单独讲解

我们先来看看这个黑白棋项目吧

一、项目演示

二、代码

完整代码如下,用到的素材(图片等)下载地址为:https://www.itprojects.cn/detail.html?example_id=f00fd7f9722b363f9dc15cf08d80e212

  1 from tkinter import *
2 from tkinter.messagebox import *
3 import random
4
5 root = Tk('黑白棋')
6 root.title("黑白棋(更多项目实例请访问www.itprojects.cn)")
7 # 加载图片
8 imgs = [PhotoImage(file='black.png'), PhotoImage(file='white.png'), PhotoImage(file='board.png'), PhotoImage(file='info2.png')]
9
10
11 def resetBoard(board):
12 """重置棋盘"""
13 for x in range(8):
14 for y in range(8):
15 board[x][y] = 'none'
16 # Starting pieces:
17 board[3][3] = 'black'
18 board[3][4] = 'white'
19 board[4][3] = 'white'
20 board[4][4] = 'black'
21
22
23 def getNewBoard():
24 """开局时建立新棋盘"""
25 board = []
26 for i in range(8):
27 board.append(['none'] * 8)
28 return board
29
30
31 def isValidMove(board, tile, xstart, ystart):
32 """是否是合法走法,如果合法返回需要翻转的棋子列表"""
33 # 如果该位置已经有棋子或者出界了,返回False
34 if not isOnBoard(xstart, ystart) or board[xstart][ystart] != 'none':
35 return False
36 # 临时将tile 放到指定的位置
37 board[xstart][ystart] = tile
38 if tile == 'black':
39 otherTile = 'white'
40 else:
41 otherTile = 'black'
42 # 要被翻转的棋子
43 tilesToFlip = []
44 for xdirection, ydirection in [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]:
45 x, y = xstart, ystart
46 x += xdirection
47 y += ydirection
48 if isOnBoard(x, y) and board[x][y] == otherTile:
49 x += xdirection
50 y += ydirection
51 if not isOnBoard(x, y):
52 continue
53 # 一直走到出界或不是对方棋子的位置
54 while board[x][y] == otherTile:
55 x += xdirection
56 y += ydirection
57 if not isOnBoard(x, y):
58 break
59 # 出界了,则没有棋子要翻转OXXXXX
60 if not isOnBoard(x, y):
61 continue
62 # 是自己的棋子OXXXXXXO
63 if board[x][y] == tile:
64 while True:
65 x -= xdirection
66 y -= ydirection
67 # 回到了起点则结束
68 if x == xstart and y == ystart:
69 break
70 # 需要翻转的棋子
71 tilesToFlip.append([x, y])
72 # 将前面临时放上的棋子去掉,即还原棋盘
73 board[xstart][ystart] = 'none' # restore the empty space
74 # 没有要被翻转的棋子,则走法非法。翻转棋的规则。
75 if len(tilesToFlip) == 0: # If no tiles were flipped, this is not a valid move.
76 return False
77 return tilesToFlip
78
79
80 def isOnBoard(x, y):
81 """是否出界"""
82 return x >= 0 and x <= 7 and y >= 0 and y <= 7
83
84
85 def getValidMoves(board, tile):
86 """获取可落子的位置"""
87 validMoves = []
88 for x in range(8):
89 for y in range(8):
90 if isValidMove(board, tile, x, y) != False:
91 validMoves.append([x, y])
92 return validMoves
93
94
95 def getScoreOfBoard(board):
96 """获取棋盘上黑白双方的棋子数"""
97 xscore = 0
98 oscore = 0
99 for x in range(8):
100 for y in range(8):
101 if board[x][y] == 'black':
102 xscore += 1
103 if board[x][y] == 'white':
104 oscore += 1
105 return {'black': xscore, 'white': oscore}
106
107
108 def whoGoesFirst():
109 """决定谁先走"""
110 if random.randint(0, 1) == 0:
111 return 'computer'
112 else:
113 return 'player'
114
115
116 def makeMove(board, tile, xstart, ystart):
117 """将一个tile棋子放到(xstart, ystart)"""
118 tilesToFlip = isValidMove(board, tile, xstart, ystart)
119 if tilesToFlip == False:
120 return False
121 board[xstart][ystart] = tile
122 for x, y in tilesToFlip: # tilesToFlip是需要翻转的棋子列表
123 board[x][y] = tile # 翻转棋子
124 return True
125
126
127 def getBoardCopy(board):
128 """复制棋盘"""
129 dupeBoard = getNewBoard()
130 for x in range(8):
131 for y in range(8):
132 dupeBoard[x][y] = board[x][y]
133 return dupeBoard
134
135
136 def isOnCorner(x, y):
137 """是否在角上"""
138 return (x == 0 and y == 0) or (x == 7 and y == 0) or (x == 0 and y == 7) or (x == 7 and y == 7)
139
140
141 def getComputerMove(board, computerTile):
142 """电脑走法,AI"""
143 # 获取所以合法走法
144 possibleMoves = getValidMoves(board, computerTile)
145 if not possibleMoves: # 如果没有合法走法
146 print("电脑没有合法走法")
147 return None
148
149 # 打乱所有合法走法
150 random.shuffle(possibleMoves)
151 # [x, y]在角上,则优先走,因为角上的不会被再次翻转
152 for x, y in possibleMoves:
153 if isOnCorner(x, y):
154 return [x, y]
155 bestScore = -1
156 for x, y in possibleMoves:
157 dupeBoard = getBoardCopy(board)
158 makeMove(dupeBoard, computerTile, x, y)
159 # 按照分数选择走法,优先选择翻转后分数最多的走法
160 score = getScoreOfBoard(dupeBoard)[computerTile]
161 if score > bestScore:
162 bestMove = [x, y]
163 bestScore = score
164 return bestMove
165
166
167 def isGameOver(board):
168 """是否游戏结束"""
169 for x in range(8):
170 for y in range(8):
171 if board[x][y] == 'none':
172 return False
173 return True
174
175
176 def drawQiPan():
177 """画棋盘"""
178 img1 = imgs[2]
179 cv.create_image((360, 360), image=img1)
180 cv.pack()
181
182
183 def callback(event):
184 """走棋"""
185 global turn
186 # print ("clicked at", event.x, event.y,turn)
187 # x=(event.x)//40 #换算棋盘坐标
188 # y=(event.y)//40
189 if (gameOver == False and turn == 'computer'): # 没轮到玩家走棋
190 return
191 col = int((event.x - 40) / 80) # 换算棋盘坐标
192 row = int((event.y - 40) / 80)
193 if mainBoard[col][row] != "none":
194 showinfo(title="提示", message="已有棋子")
195 if makeMove(mainBoard, playerTile, col, row) == True: # 将一个玩家棋子放到(col, row)
196 if getValidMoves(mainBoard, computerTile) != []:
197 turn = 'computer'
198 # 电脑走棋
199 if getComputerMove(mainBoard, computerTile) == None:
200 turn = 'player'
201 showinfo(title="玩家继续", message="玩家继续")
202 else:
203 computerGo()
204 # 重画所有的棋子和棋盘
205 drawAll()
206 drawCanGo()
207 if isGameOver(mainBoard): # 游戏结束,显示双方棋子数量
208 scorePlayer = getScoreOfBoard(mainBoard)[playerTile]
209 scoreComputer = getScoreOfBoard(mainBoard)[computerTile]
210 outputStr = gameoverStr + "玩家:" + str(scorePlayer) + ":" + "电脑:" + str(scoreComputer)
211 showinfo(title="游戏结束提示", message=outputStr)
212
213
214 def computerGo():
215 """电脑走棋"""
216 global turn
217 if (gameOver == False and turn == 'computer'):
218 x, y = getComputerMove(mainBoard, computerTile) # 电脑AI走法
219 makeMove(mainBoard, computerTile, x, y)
220 savex, savey = x, y
221 # 玩家没有可行的走法了,则电脑继续,否则切换到玩家走
222 if getValidMoves(mainBoard, playerTile) != []:
223 turn = 'player'
224 else:
225 if getValidMoves(mainBoard, computerTile) != []:
226 showinfo(title="电脑继续", message="电脑继续")
227 computerGo()
228
229
230 def drawAll():
231 """重画所有的棋子和棋盘"""
232 drawQiPan()
233 for x in range(8):
234 for y in range(8):
235 if mainBoard[x][y] == 'black':
236 cv.create_image((x * 80 + 80, y * 80 + 80), image=imgs[0])
237 cv.pack()
238 elif mainBoard[x][y] == 'white':
239 cv.create_image((x * 80 + 80, y * 80 + 80), image=imgs[1])
240 cv.pack()
241
242
243 def drawCanGo():
244 """画提示位置"""
245 list1 = getValidMoves(mainBoard, playerTile)
246 for m in list1:
247 x = m[0]
248 y = m[1]
249 cv.create_image((x * 80 + 80, y * 80 + 80), image=imgs[3])
250 cv.pack()
251
252
253 if __name__ == '__main__':
254 # 初始化
255 gameOver = False
256 gameoverStr = 'Game Over Score '
257 mainBoard = getNewBoard()
258 resetBoard(mainBoard)
259 turn = whoGoesFirst()
260 showinfo(title="游戏开始提示", message=turn + "先走!")
261 print(turn, "先走!")
262 if turn == 'player':
263 playerTile = 'black'
264 computerTile = 'white'
265 else:
266 playerTile = 'white'
267 computerTile = 'black'
268 computerGo()
269
270 # 设置窗口
271 cv = Canvas(root, bg='green', width=720, height=780)
272 # 重画所有的棋子和棋盘
273 drawAll()
274 drawCanGo()
275 cv.bind("<Button-1>", callback)
276 cv.pack()
277 root.mainloop()

python3+tkinter实现的黑白棋,代码完整 100%能运行的更多相关文章

  1. 用Dart写的黑白棋游戏

    2013年11月,Dart语言1.0稳定版SDK发布,普天同庆.从此,网页编程不再纠结了. 在我看来,Dart语法简直就是C#的升级版,太像了.之所以喜欢Ruby的一个重要理由是支持mixin功能,而 ...

  2. [CareerCup] 8.8 Othello Game 黑白棋游戏

    8.8 Othello is played as follows: Each Othello piece is white on one side and black on the other. Wh ...

  3. 黑白棋游戏 (codevs 2743)题解

    [问题描述] 黑白棋游戏的棋盘由4×4方格阵列构成.棋盘的每一方格中放有1枚棋子,共有8枚白棋子和8枚黑棋子.这16枚棋子的每一种放置方案都构成一个游戏状态.在棋盘上拥有1条公共边的2个方格称为相邻方 ...

  4. bzoj 2281 [Sdoi2011]黑白棋(博弈+组合计数)

    黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色 ...

  5. 【BZOJ2281】【博弈论+DP】 [Sdoi2011]黑白棋

    Description 黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是 ...

  6. 从0开始 Java实习 黑白棋

    黑白棋的设计 代码如下: import java.util.*; public class Chess{ char[][] chess = new char[16][16]; public stati ...

  7. 51nod 1368:黑白棋 二分图最大匹配

    1368 黑白棋 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  取消关注 有一个N*M的棋盘(1<=N,M< ...

  8. P2490 [SDOI2011]黑白棋

    P2490 [SDOI2011]黑白棋 题意 一个 \(1*n\) 的棋盘上,A 可以移动白色棋子,B 可以移动黑色的棋子,其中白色不能往左,黑色不能往右.他们每次操作可以移动 1 到 \(d\) 个 ...

  9. Python3中的新特性(3)——代码迁移与2to3

    1.将代码移植到Python2.6 建议任何要将代码移植到Python3的用户首先将代码移植到Python2.6.Python2.6不仅与Python2.5向后兼容,而且支持Python3中的部分新特 ...

随机推荐

  1. 病毒侵袭 HDU - 2896 板子题

    当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~ 但网路上总有那么些网站,开 ...

  2. centos 7下安装配置Supervisor

    1.安装Supervisor centos下安装yum install supervisor 2. systemctl enable supervisord 开机自启 systemctl start ...

  3. HttpClient&&RestTemplate学习

    1. 什么是HttpClient HttpClient是Apache下面的子项目,可以提供高效的,最新的,功能丰富的支持HTTP协议的客户端编程工具包. 2. 为什么要学习HttpClient Htt ...

  4. 01.原生态jdbc程序中问题总结

    1.数据库启动包配置到工程目录中(mysql5.1) mysql-connector-java-5.1.7-bin.jar 2.jdbc原生态操作数据库(程序) 操作mysql数据库 1 packag ...

  5. Django用户注册、登录

    一.用户注册 1 ''' 2 注册的表单模型 3 forms.py 的例子 4 ''' 5 6 from django import forms #表单功能 7 from django.contrib ...

  6. Cobbler服务引导第三方PE系统

    通过Cobbler服务引导第三方PE系统 1.上传第三方ios到/root/Ushendu_win10.iso并增加菜单项 cobbler distro add --name=Ushendu_win1 ...

  7. Leetcode(144)-二叉树的前序遍历

    给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 二叉树的前序遍历有递归 ...

  8. Go string 一清二楚

    前言 字符串(string) 作为 go 语言的基本数据类型,在开发中必不可少,我们务必深入学习一下,做到一清二楚. 本文假设读者已经知道切片(slice)的使用,如不了解,可阅读 Go 切片 基本知 ...

  9. Python Web Framework All In One

    Python Web Framework All In One Django and Flask are the top Python web frameworks so far. Django ht ...

  10. ReactDOM API All In One

    ReactDOM API All In One React DOM API render() hydrate() unmountComponentAtNode() findDOMNode() crea ...