阿福:小美斋配,聽說你學(xué)過海龜繪圖孔飒,能幫我用turtle?來畫一張棋譜嗎?
小美:什么棋譜艰争?
阿福:就是一張9路圍棋盤的棋譜坏瞄,它的樣子如圖1所示:
知識小貼士:
turtle?(海龜繪圖)很適合用來引導(dǎo)孩子學(xué)習(xí)編程。最初來自于Wally Feurzig 和 Seymour Papert 于1966 年所創(chuàng)造的 Logo 編程語言甩卓。它在繪圖區(qū)設(shè)置了一只想象中的小海龜(畫面顯示一個(gè)箭頭代表小海龜?shù)念^)鸠匀,起始位置在 x-y 平面的 (0, 0) 點(diǎn),面向x軸正方向逾柿。小海龜根據(jù)一組函數(shù)指令的控制缀棍,在這個(gè)平面坐標(biāo)系中移動(dòng),從而在它爬行的路徑上繪制了圖形机错。
小美:這種棋譜啊爬范,小菜一碟!只要先畫橫豎各9條線弱匪,再畫上9個(gè)星位圓點(diǎn)青瀑,棋盤就畫好了。接下來把黑白棋子畫上去就行了。
阿福:說得簡單狱窘,有這么容易嗎杜顺?我也不讓你畫棋子,你先把棋盤畫出來給我看看蘸炸?
小美:這有什么難的躬络。我不僅可以畫出9路棋盤,還能把棋盤上的橫縱坐標(biāo)標(biāo)記也畫出來搭儒,甚至推廣到13路穷当、19路棋盤上去,你只需修改棋盤路數(shù)和星位坐標(biāo)就行了淹禾。
import turtle astt
'''
函數(shù)功能:根據(jù)輸入的棋盤的路數(shù)馁菜,格子寬度和左上角坐標(biāo),畫一個(gè)圍棋盤
函數(shù)名:draw_go_board(n,s, x0, y0, point)
參數(shù)表:n -- 棋盤的路數(shù)铃岔;s -- 棋盤格子寬度汪疮;
?????? x0, y0 --棋盤左上角坐標(biāo);point -- 存儲了星位坐標(biāo)的元組毁习。
返回值:沒有返回值智嚷。
'''
defdraw_go_board(n, s, x0, y0, point):
??? for command in ('寫字母', '寫數(shù)字'):
??????? if command == '寫字母':
??????????? x, y = x0, y0 + s * 2 / 3
??????????? a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
??????? else:
??????????? x, y = x0 - s * 2 / 3, y0 - s / 5
??????????? a = list(range(1,27))
??????? for c in a[:n]:
??????????? tt.penup()
??????????? tt.goto(x, y)
??????????? tt.pendown()
??????????? tt.write(c,align="center", font=("Arial", 16, "normal"))
??????????? if command == '寫字母':
??????????????? x += s
??????????? else:
??????????????? y -= s
??? forcommand in ('畫橫線', '畫豎線'):
??????? x, y = x0, y0
??????? for i in range(n):
??????????? tt.penup()
??????????? tt.goto(x, y)
??????????? tt.pendown()
??????????? tt.forward(s*(n-1))
??????????? if command == '畫橫線':
??????????????? y -= s
??????????? else:
??????????????? x += s
??????? tt.right(90)
??? for x, y in point: #畫星位
??????? tt.penup()
??????? tt.goto(x, y)
??????? tt.pendown()
??????? tt.dot(12)
tt.TurtleScreen._RUNNING= True? #啟動(dòng)繪圖,在IDE中運(yùn)行加這句可避免報(bào)錯(cuò)
tt.speed(0)
tt.ht()#隱藏筆頭
#n, s, (x, y), s分別存儲了棋盤的路數(shù)纺且,格子寬度和左上角坐標(biāo)
n, s, x, y = 9,60, -240, 240
#星位坐標(biāo)
point =((-120,120),(0,120),(120,120),
???????? (-120,0),(0,0),(120,0),
???????? (-120,-120),(0,-120),(120,-120))
draw_go_board(n,
s, x, y, point) #畫n路棋盤
tt.done()
?阿福:你怎么那么厲害盏道!看來我小瞧你了。那好载碌,你現(xiàn)在把棋子畫上去吧猜嘱。
小美:棋盤畫好以后,我們只要另外再寫一個(gè)畫棋子的draw_go_table()函數(shù)就行了嫁艇。但是在調(diào)用draw_go_table()之前我們需要先把棋盤上各個(gè)交叉點(diǎn)的信息存儲起來朗伶,我們可以用列表go_table存儲這些信息,例如go_table[0] = '空空空空空空空空空'表示第1行上全是空子裳仆,go_table[3] = '空白空白白黑黑黑白'表示了第4行上黑白子的分布情況腕让。
阿福:有道理孤钦!那具體的程序應(yīng)該怎樣寫呢歧斟?
小美:我都說這么明白了,你還沒反應(yīng)過來捌巍静袖?看來“大熊貓”這個(gè)標(biāo)簽?zāi)氵€得掛一段時(shí)間】∨ぃ看清楚了队橙!
'''
函數(shù)功能:在已經(jīng)畫好的棋盤上,按棋盤位置順序添加棋子信息(隱藏手?jǐn)?shù)編號)
函數(shù)名:draw_go_table(n,s, x0, y0, go_table)
參數(shù)表:n -- 棋盤的路數(shù);s -- 棋盤格子寬度捐康;
?????? x0, y0 --棋盤左上角坐標(biāo)仇矾;go_table-- 存儲了各交叉點(diǎn)信息的列表。
返回值:沒有返回值解总。
'''
def draw_go_table(n, s, x0, y0, go_table):
??? for i in range(n):
??????? x, y = x0, y0 - i * s+ s / 2
??????? for j in range(n):
??????????? if go_table[i][j]== '空': #跳過空子
??????????????? x += s
??????????????? continue
??????????? if go_table[i][j]== '黑': #畫黑子
???????????????tt.color('white', 'black')
??????????? else:????????????????????? #畫白子
??????????????? tt.color('black','white')
??????????? tt.penup()
??????????? tt.goto(x, y)
??????????? tt.pendown()
??????????? tt.begin_fill()
??????????? tt.circle(s*5/12)
??????????? tt.end_fill()
??????????? x += s
tt.TurtleScreen._RUNNING = True?#啟動(dòng)繪圖贮匕,在IDE中運(yùn)行加這句可避免報(bào)錯(cuò)
tt.speed(0)
tt.ht()#隱藏筆頭
#n, s, (x, y), s分別存儲了棋盤的路數(shù),格子寬度和左上角坐標(biāo)
n, s, x, y = 9, 60, -240, 240
#星位坐標(biāo)
point = ((-120,120),(0,120),(120,120),
????????(-120,0),(0,0),(120,0),
????????(-120,-120),(0,-120),(120,-120))
draw_go_board(n, s, x, y, point) #畫n路棋盤
go_table = ['空空空空空空空空空','空空空空空空空空空','空空白空空白白白空',
??????????? '空白空白白黑黑黑白','空黑白白黑黑空黑空','空黑黑黑空空空空空',
??????????? '空空空空空空空空空','空空空空空空空空空','空空空空空空空空空']
draw_go_table(n, s, x, y, go_table) #畫棋譜(隱藏手?jǐn)?shù)編號)
tt.done()
古老師:小美花枫,又在欺負(fù)阿福了翱萄巍!你可別小看他劳翰,別看他嘴上不說敦锌,心里可清楚得很哪。不過小美這段時(shí)間進(jìn)步確實(shí)挺大的佳簸,不僅能熟練使用各種turtle?方法乙墙,連自定義函數(shù)也寫得很漂亮了呢!但我不得不說的是生均,你畫的圖并不是真正的圍棋譜伶丐,真正的圍棋譜上面是要顯示手?jǐn)?shù)編號的,就像圖4這種樣子:
阿福:沒錯(cuò)疯特,其實(shí)這張圖才是我想讓你畫的哗魂。
小美:那你不早說!不過要加上手?jǐn)?shù)編號的話還真有點(diǎn)難度呢漓雅。不能簡單地用”黑白空”字符來表示了录别。不僅要包含棋子顏色信息,還要包含手?jǐn)?shù)編號信息邻吞,那豈不是要用2個(gè)變量來表示同一個(gè)交叉點(diǎn)的信息组题?
阿福:其實(shí)一個(gè)變量就夠了,但是不能用字符抱冷,而要用整數(shù)崔列,0表示空子,正數(shù)表示黑子旺遮,負(fù)數(shù)表示白子赵讯,它們的絕對值表示手?jǐn)?shù)編號。
古老師:有道理耿眉!阿福边翼,不愧是初中生啊,數(shù)學(xué)沒有白學(xué)鸣剪!小美组底,你知道負(fù)數(shù)嗎丈积?
小美:知道的,興趣小組里老師講過债鸡。
古老師:那就好江滨。這樣吧,小美厌均,你先用阿福說的方法存儲棋盤上各個(gè)交叉點(diǎn)的信息牙寞,再用你剛才畫圖3的思路,按照從上到下莫秆、從左到右的順序把棋譜畫出來间雀。阿福呢,給你一個(gè)更艱巨的任務(wù):按照落子順序把棋譜畫出來镊屎。
阿福:古老師你偏心惹挟,凈挑難題考我。如果按照落子順序畫棋譜的話缝驳,那就需要存儲棋子的手?jǐn)?shù)編號连锯、顏色和坐標(biāo)等信息了,原來的經(jīng)驗(yàn)都沒用了用狱,難度不止增大一點(diǎn)點(diǎn)啊运怖。
古老師:誰叫你是高手呢,能者多勞嘛夏伊。不過你的思路是正確的摇展,照著這個(gè)思路去做肯定能成功。這樣吧溺忧,今天我有事先走了咏连。棋譜畫好了記得告訴我一聲哦。拜拜鲁森。
有事沒事最好拉到文末看看祟滴,說不定作者今天提供了彩蛋哦!
需要本文word版的歌溉,可以加入“Python算法之旅”知識星球參與討論和下載文件垄懂,“Python算法之旅”知識星球匯集了數(shù)量眾多的同好,更多有趣的話題在這里討論痛垛,更多有用的資料在這里分享草慧。
我們專注Python算法,感興趣就一起來榜晦!
?彩蛋
小美:阿福冠蒋,古老師很器重你啊乾胶!對了抖剿,畫那個(gè)帶手?jǐn)?shù)編號的棋子,是不是要先把棋子畫好识窿,再寫編號罢独伞?
阿福:古老師就是嘴巴甜喻频!你不也經(jīng)常被夸嗎缩宜?沒錯(cuò),如果先寫編號的話甥温,填充棋子顏色的時(shí)候就會把編號覆蓋掉锻煌。好了,我們都抓緊時(shí)間行動(dòng)吧姻蚓,早點(diǎn)給古老師看結(jié)果宋梧。
小美:嗯。狰挡。捂龄。。加叁。倦沧。我好了。
'''
函數(shù)功能:在已經(jīng)畫好的棋盤上它匕,按棋盤位置順序添加棋子信息(顯示手?jǐn)?shù)編號)
函數(shù)名:draw_go_table2(n,s, x0, y0, go_table)
參數(shù)表:n -- 棋盤的路數(shù)展融;s -- 棋盤格子寬度;x0, y0
-- 棋盤左上角坐標(biāo)豫柬;
go_table -- 存儲各交叉點(diǎn)信息的列表愈污,0、正數(shù)和負(fù)數(shù)分別代表空轮傍、黑子和白子暂雹,其絕對值為手?jǐn)?shù)編號。
返回值:沒有返回值创夜。
'''?????
defdraw_go_table2(n, s, x0, y0, go_table):
??? for i in range(n):
??????? x, y = x0, y0 - i * s + s / 2
??????? for j in range(n):
??????????? if go_table[i][j] == 0: #跳過空子
??????????????? x += s
??????????????? continue
??????????? if go_table[i][j] > 0: #畫黑子
??????????????? tt.color('white', 'black')
??????????????? num = go_table[i][j]
??????????? else:????????????????? #畫白子
??????????????? tt.color('black', 'white')
??????????????? num = -go_table[i][j]
??????????? #畫棋子
??????????? tt.penup()
??????????? tt.goto(x, y)
??????????? tt.pendown()
??????????? tt.begin_fill()
??????????? tt.circle(s*5/12)
??????????? tt.end_fill()
??????????? #顯示手?jǐn)?shù)編號
??????????? tt.penup()
??????????? tt.goto(x, y - s * 3 / 5)
??????????? tt.pendown()
??????????? tt.write(num,align="center", font=("Arial", 16, "normal"))
??????????? x += s
tt.TurtleScreen._RUNNING= True? #啟動(dòng)繪圖杭跪,在IDE中運(yùn)行加這句可避免報(bào)錯(cuò)
tt.speed(0)
tt.ht()#隱藏筆頭
#n, s, (x, y), s分別存儲了棋盤的路數(shù),格子寬度和左上角坐標(biāo)
n, s, x, y = 9,60, -240, 240
#星位坐標(biāo)
point =((-120,120),(0,120),(120,120),
???????? (-120,0),(0,0),(120,0),
???????? (-120,-120),(0,-120),(120,-120))
draw_go_board(n,
s, x, y, point) #畫n路棋盤
go_table =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,-18,0,0,-14,-8,-12,0],
??????????? [0,-10,0,-4,-6,13,11,19,-20],[0,15,-16,-2,1,7,0,9,0],[0,17,5,3,0,0,0,0,0],
???????????[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]]
draw_go_table2(n,
s, x, y, go_table) #畫棋譜(顯示手?jǐn)?shù)編號)
tt.done()
阿福:動(dòng)作挺快俺巯拧涧尿!我也好了。
'''
函數(shù)功能:在已經(jīng)畫好的棋盤上檬贰,添加棋子信息(按落子順序顯示手?jǐn)?shù)編號)
函數(shù)名:draw_go_table3(n,s, x0, y0, go_table)
參數(shù)表:n -- 棋盤的路數(shù)姑廉;s -- 棋盤格子寬度;x0, y0
-- 棋盤左上角坐標(biāo)翁涤;
?????? go_table --存儲了各交叉點(diǎn)信息的列表桥言,其元素值為(手?jǐn)?shù)編號,棋子顏色,橫坐標(biāo),縱坐標(biāo))萌踱。
返回值:沒有返回值。
'''?????
def draw_go_table3(n,s, x0, y0, go_table):
??? for go in go_table:
??????? num = go[0]
??????? x, y = x0+(ord(go[2])-ord('A'))*s,y0-(go[3]-1)*s+s/2
??????? if go[1] == '黑': #畫黑子
??????????? tt.color('white', 'black')
??????? else:???????????? #畫白子
??????????? tt.color('black', 'white')
??????? #畫棋子
??????? tt.penup()
??????? tt.goto(x, y)
??????? tt.pendown()
??????? tt.begin_fill()
??????? tt.circle(s*5/12)
??????? tt.end_fill()
??????? #顯示手?jǐn)?shù)編號
??????? tt.penup()
??????? tt.goto(x, y - s * 3 / 5)
??????? tt.pendown()
??????? tt.write(num, align="center",font=("Arial", 16, "normal"))
tt.TurtleScreen._RUNNING= True? #啟動(dòng)繪圖号阿,在IDE中運(yùn)行加這句可避免報(bào)錯(cuò)
tt.speed(0)
tt.ht()#隱藏筆頭
#n, s, (x, y), s分別存儲了棋盤的路數(shù)并鸵,格子寬度和左上角坐標(biāo)
n, s, x, y = 9,60, -240, 240
#星位坐標(biāo)
point =((-120,120),(0,120),(120,120),
???????? (-120,0),(0,0),(120,0),
???????? (-120,-120),(0,-120),(120,-120))
draw_go_board(n,
s, x, y, point) #畫n路棋盤
#棋譜(按落子順序顯示手?jǐn)?shù)編號)?
go_table = [(1,'黑','E',5),(2,'白','D',5),(3,'黑','D',6),(4,'白','D',4),(5,'黑','C',6),
??????????? (6,'白','E',4),(7,'黑','F',5),(8,'白','G',3),(9,'黑','H',5),(10,'白','B',4),
??????????? (11,'黑','G',4),(12,'白','H',3),(13,'黑','F',4),(14,'白','F',3),(15,'黑','B',5),
??????????? (16,'白','C',5),(17,'黑','B',6),(18,'白','C',3),(19,'黑','H',4),(20,'白','I',4)]
draw_go_table3(n,
s, x, y, go_table) #畫棋譜(顯示手?jǐn)?shù)編號)?
tt.done()