【农大】Python绘画大师
在Python中,我们可以使用像turtle这样的图形库来绘制象棋。但是,由于象棋的复杂性,这可能需要大量的代码和耐心。在此,我将提供一个简单的例子来解释如何使用turtle来绘制一个棋盘。其中,这个例子主要使用到的函数如下:
draw_chessboard(x, y):
draw_camp():
marker(x, y):
draw_marker_gun():
draw_marker_soldier():
piece_cirle(radius):
piece_font(x, fontColor):
draw_boundary(x, y):
draw_piece_soldier(x, y):
draw_piece_gun(x, y):
draw_piece_other(x, y):
一、让我们来逐个分析这些所使用到的函数
首先根据画笔初始位置坐标x,y和单元格宽度,绘制棋盘的方格
def draw_chessboard(x, y):
t.penup() # 抬起画笔
t.goto(x - width // 5, y - width // 5)
t.pendown() # 落下画笔
t.fillcolor('orange')
t.begin_fill() # 开始填充
for i in range(2):
t.forward(8 * width + 2 * width // 5)
t.left(90)
t.forward(9 * width + 2 * width // 5)
t.left(90)
t.end_fill()
t.penup()
for i in range(10):
t.goto(x, y + i * width)
t.pendown()
t.forward(8 * width)
t.penup()
t.left(90)
for i in range(9):
t.goto(x + i * width, y)
t.pendown()
t.forward(4 * width)
t.penup()
t.forward(width)
t.pendown()
t.forward(4 * width)
t.penup()
再根据画笔初始位置坐标x,y和单元格宽度,绘制棋盘帅营斜线
def draw_camp():
t.penup()
t.goto(-width, -4 * width)
t.pendown()
t.goto(width, -2 * width)
t.goto(-width, -2 * width)
t.goto(width, -4 * width)
t.penup()
t.goto(-width, 5 * width)
t.pendown()
t.goto(width, 3 * width)
t.goto(-width, 3 * width)
t.goto(width, 5 * width)
t.penup()
绘制兵炮标记
def marker(x, y):
t.penup()
t.goto(x - 3, y - 9)
for i in range(4):
t.pendown()
t.forward(6)
t.left(90)
t.forward(6)
t.right(90)
t.penup()
t.forward(6)
t.pendown()
t.right(90)
t.penup()
绘制双方炮位的标记
def draw_marker_gun():
maker_of_x = [pos_of_x + width, pos_of_x + 7 * width, pos_of_x + width, pos_of_x + 7 * width] # 炮位置x坐标
maker_of_y = [pos_of_y + 2 * width, pos_of_y + 2 * width, pos_of_y + 7 * width, pos_of_y + 7 * width]
for i in range(4):
marker(maker_of_x[i], maker_of_y[i])
绘制双方兵卒位的标记
def draw_marker_soldier():
for i in range(5):
marker(pos_of_x + 2 * i * width, pos_of_y + 3 * width)
marker(pos_of_x + 2 * i * width, pos_of_y + 6 * width)
绘制棋子的圆,填充为白色
def piece_cirle(radius):
t.pensize(3)
t.fillcolor('white') # 设置填充色为白色
t.begin_fill()
t.circle(radius) # 绘制半径为radius的圆
t.end_fill()
接收棋子上的文字和颜色,在棋子写文字
def piece_font(x, fontColor):
t.color(fontColor)
t.write(x, font=('隶书', width // 2, 'normal')) # 在棋子上写字
写楚河汉界的文字
def draw_boundary(x, y):
t.goto(x + 7 / 4 * width, y + 17 / 4 * width)
t.pendown()
t.color("green")
t.write("楚 河 汉 界", font=('隶书', width // 2, 'normal'))
t.penup()
绘制黑红双方的兵和卒棋子
def draw_piece_soldier(x, y):
for j in range(2):
for i in range(5):
t.penup()
t.goto(x + 2 * i * width + 1 / 3 * width, y + 3 * width + 3 * j * width)
t.pendown()
t.pencolor(font_color[j])
piece_cirle(1 / 3 * width)
t.penup()
t.goto(x + 2 * i * width - 1 / 3 * width, y + 3 * width - 1 / 4 * width + 3 * j * width)
t.pendown()
piece_font(chess_pieces[j][9], font_color[j])
绘制黑红双方的棋子炮
def draw_piece_gun(x, y):
for j in range(2):
for i in range(2):
t.penup()
t.goto(x + width + 6 * i * width + 1 / 3 * width, y + 2 * width + j * 5 * width)
t.pendown()
t.pencolor(font_color[j])
piece_cirle(1 / 3 * width)
t.penup()
t.goto(x + 2 / 3 * width + 6 * i * width, y + 2 * width - 1 / 4 * width + j * 5 * width)
t.pendown()
piece_font(chess_pieces[j][10], font_color[j])
为其他棋子增加文字
def draw_piece_other(x, y):
for j in range(2):
for i in range(9):
t.penup()
t.goto(x + i * width + 1 / 3 * width, y + 9 * j * width)
t.pendown()
t.pencolor(font_color[j])
piece_cirle(1 / 3 * width)
t.penup()
t.goto(x + i * width - 1 / 3 * width, y - 1 / 4 * width + 9 * j * width)
t.pendown()
piece_font(chess_pieces[j][i], font_color[j])
最后进行主程序运行
if __name__ == '__main__':
# t.tracer(10) # 取消注释可加速刷新绘制速度
t.speed(0) # 绘制速度
t.pensize(2) # 画笔粗线
width = 60 # 设置每格宽度
t.screensize(10 * width, 12 * width) # 画布大小为12倍单元格宽度
pos_of_x, pos_of_y = -4 * width, -4 * width # 画笔初始坐标
chess_pieces = [['車', '馬', '相', '仕', '帅', '仕', '相', '馬', '車', '兵', '砲'],
['車', '馬', '象', '士', '将', '士', '象', '馬', '車', '卒', '炮']]
font_color = ['red', 'green'] # 设置棋子填充色
draw_chessboard(pos_of_x, pos_of_y) # 绘制空棋盘
draw_camp() # 绘制将帅营房
draw_marker_gun() # 绘制炮位标记
draw_marker_soldier() # 绘制兵卒位标记
draw_boundary(pos_of_x, pos_of_y) # 绘制楚河汉界
draw_piece_soldier(pos_of_x, pos_of_y) # 绘制棋子兵和卒
draw_piece_gun(pos_of_x, pos_of_y) # 绘制棋子炮
draw_piece_other(pos_of_x, pos_of_y) # 绘制其他棋子
t.hideturtle() # 隐藏画笔
t.update() # 更新缓存
t.done() # 结束绘制
二、让我们来看看最后的全部代码
import turtle as t
def draw_chessboard(x, y):
"""根据画笔初始位置坐标x,y和单元格宽度,绘制棋盘的方格"""
t.penup() # 抬起画笔
t.goto(x - width // 5, y - width // 5)
t.pendown() # 落下画笔
t.fillcolor('orange')
t.begin_fill() # 开始填充
for i in range(2):
t.forward(8 * width + 2 * width // 5)
t.left(90)
t.forward(9 * width + 2 * width // 5)
t.left(90)
t.end_fill()
t.penup()
for i in range(10):
t.goto(x, y + i * width)
t.pendown()
t.forward(8 * width)
t.penup()
t.left(90)
for i in range(9):
t.goto(x + i * width, y)
t.pendown()
t.forward(4 * width)
t.penup()
t.forward(width)
t.pendown()
t.forward(4 * width)
t.penup()
def draw_camp():
"""根据画笔初始位置坐标x,y和单元格宽度,绘制棋盘帅营斜线"""
t.penup()
t.goto(-width, -4 * width)
t.pendown()
t.goto(width, -2 * width)
t.goto(-width, -2 * width)
t.goto(width, -4 * width)
t.penup()
t.goto(-width, 5 * width)
t.pendown()
t.goto(width, 3 * width)
t.goto(-width, 3 * width)
t.goto(width, 5 * width)
t.penup()
def marker(x, y):
"""绘制兵炮标记"""
t.penup()
t.goto(x - 3, y - 9)
for i in range(4):
t.pendown()
t.forward(6)
t.left(90)
t.forward(6)
t.right(90)
t.penup()
t.forward(6)
t.pendown()
t.right(90)
t.penup()
def draw_marker_gun():
"""绘制双方炮位的标记"""
maker_of_x = [pos_of_x + width, pos_of_x + 7 * width, pos_of_x + width, pos_of_x + 7 * width] # 炮位置x坐标
maker_of_y = [pos_of_y + 2 * width, pos_of_y + 2 * width, pos_of_y + 7 * width, pos_of_y + 7 * width]
for i in range(4):
marker(maker_of_x[i], maker_of_y[i])
def draw_marker_soldier():
"""绘制双方兵卒位的标记"""
for i in range(5):
marker(pos_of_x + 2 * i * width, pos_of_y + 3 * width)
marker(pos_of_x + 2 * i * width, pos_of_y + 6 * width)
def piece_cirle(radius):
"""绘制棋子的圆,填充为白色"""
t.pensize(3)
t.fillcolor('white') # 设置填充色为白色
t.begin_fill()
t.circle(radius) # 绘制半径为radius的圆
t.end_fill()
def piece_font(x, fontColor):
"""接收棋子上的文字和颜色,在棋子写文字"""
t.color(fontColor)
t.write(x, font=('隶书', width // 2, 'normal')) # 在棋子上写字
def draw_boundary(x, y):
"""写楚河汉界的文字"""
t.goto(x + 7 / 4 * width, y + 17 / 4 * width)
t.pendown()
t.color("green")
t.write("楚 河 汉 界", font=('隶书', width // 2, 'normal'))
t.penup()
def draw_piece_soldier(x, y):
"""绘制黑红双方的兵和卒棋子"""
for j in range(2):
for i in range(5):
t.penup()
t.goto(x + 2 * i * width + 1 / 3 * width, y + 3 * width + 3 * j * width)
t.pendown()
t.pencolor(font_color[j])
piece_cirle(1 / 3 * width)
t.penup()
t.goto(x + 2 * i * width - 1 / 3 * width, y + 3 * width - 1 / 4 * width + 3 * j * width)
t.pendown()
piece_font(chess_pieces[j][9], font_color[j])
def draw_piece_gun(x, y):
"""绘制黑红双方的棋子炮"""
for j in range(2):
for i in range(2):
t.penup()
t.goto(x + width + 6 * i * width + 1 / 3 * width, y + 2 * width + j * 5 * width)
t.pendown()
t.pencolor(font_color[j])
piece_cirle(1 / 3 * width)
t.penup()
t.goto(x + 2 / 3 * width + 6 * i * width, y + 2 * width - 1 / 4 * width + j * 5 * width)
t.pendown()
piece_font(chess_pieces[j][10], font_color[j])
def draw_piece_other(x, y):
"""为其他棋子增加文字"""
for j in range(2):
for i in range(9):
t.penup()
t.goto(x + i * width + 1 / 3 * width, y + 9 * j * width)
t.pendown()
t.pencolor(font_color[j])
piece_cirle(1 / 3 * width)
t.penup()
t.goto(x + i * width - 1 / 3 * width, y - 1 / 4 * width + 9 * j * width)
t.pendown()
piece_font(chess_pieces[j][i], font_color[j])
if __name__ == '__main__':
# t.tracer(10) # 取消注释可加速刷新绘制速度
t.speed(0) # 绘制速度
t.pensize(2) # 画笔粗线
width = 60 # 设置每格宽度
t.screensize(10 * width, 12 * width) # 画布大小为12倍单元格宽度
pos_of_x, pos_of_y = -4 * width, -4 * width # 画笔初始坐标
chess_pieces = [['車', '馬', '相', '仕', '帅', '仕', '相', '馬', '車', '兵', '砲'],
['車', '馬', '象', '士', '将', '士', '象', '馬', '車', '卒', '炮']]
font_color = ['red', 'green'] # 设置棋子填充色
draw_chessboard(pos_of_x, pos_of_y) # 绘制空棋盘
draw_camp() # 绘制将帅营房
draw_marker_gun() # 绘制炮位标记
draw_marker_soldier() # 绘制兵卒位标记
draw_boundary(pos_of_x, pos_of_y) # 绘制楚河汉界
draw_piece_soldier(pos_of_x, pos_of_y) # 绘制棋子兵和卒
draw_piece_gun(pos_of_x, pos_of_y) # 绘制棋子炮
draw_piece_other(pos_of_x, pos_of_y) # 绘制其他棋子
t.hideturtle() # 隐藏画笔
t.update() # 更新缓存
t.done() # 结束绘制