Python算法之旅字符串游戏之九路棋盘

阿福:小美,听说你学过海龟绘图,能帮我用turtle 来画一张棋谱吗?

小美:什么棋谱?

阿福:就是一张9路围棋盘的棋谱,它的样子如图1所示:

Python算法之旅字符串游戏之九路棋盘_第1张图片
图1

知识小贴士:

turtle (海龟绘图)很适合用来引导孩子学习编程。最初来自于Wally Feurzig 和 Seymour Papert 于1966 年所创造的 Logo 编程语言。它在绘图区设置了一只想象中的小海龟(画面显示一个箭头代表小海龟的头),起始位置在 x-y 平面的 (0, 0) 点,面向x轴正方向。小海龟根据一组函数指令的控制,在这个平面坐标系中移动,从而在它爬行的路径上绘制了图形。


小美:这种棋谱啊,小菜一碟!只要先画横竖各9条线,再画上9个星位圆点,棋盘就画好了。接下来把黑白棋子画上去就行了。

阿福:说得简单,有这么容易吗?我也不让你画棋子,你先把棋盘画出来给我看看?

小美:这有什么难的。我不仅可以画出9路棋盘,还能把棋盘上的横纵坐标标记也画出来,甚至推广到13路、19路棋盘上去,你只需修改棋盘路数和星位坐标就行了。

import turtle astt

'''

函数功能:根据输入的棋盘的路数,格子宽度和左上角坐标,画一个围棋盘

函数名:draw_go_board(n,s, x0, y0, point)

参数表:n -- 棋盘的路数;s -- 棋盘格子宽度;

       x0, y0 --棋盘左上角坐标;point -- 存储了星位坐标的元组。

返回值:没有返回值。

'''

defdraw_go_board(n, s, x0, y0, point):

    for command in ('写字母', '写数字'):

        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  #启动绘图,在IDE中运行加这句可避免报错

tt.speed(0)

tt.ht()#隐藏笔头

#n, s, (x, y), s分别存储了棋盘的路数,格子宽度和左上角坐标

n, s, x, y = 9,60, -240, 240

#星位坐标

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()

Python算法之旅字符串游戏之九路棋盘_第2张图片
图2

 阿福:你怎么那么厉害!看来我小瞧你了。那好,你现在把棋子画上去吧。

小美:棋盘画好以后,我们只要另外再写一个画棋子的draw_go_table()函数就行了。但是在调用draw_go_table()之前我们需要先把棋盘上各个交叉点的信息存储起来,我们可以用列表go_table存储这些信息,例如go_table[0] = '空空空空空空空空空'表示第1行上全是空子,go_table[3] = '空白空白白黑黑黑白'表示了第4行上黑白子的分布情况。

阿福:有道理!那具体的程序应该怎样写呢?

小美:我都说这么明白了,你还没反应过来啊?看来“大熊猫”这个标签你还得挂一段时间。看清楚了!

'''

函数功能:在已经画好的棋盘上,按棋盘位置顺序添加棋子信息(隐藏手数编号)

函数名:draw_go_table(n,s, x0, y0, go_table)

参数表:n -- 棋盘的路数;s -- 棋盘格子宽度;

       x0, y0 --棋盘左上角坐标;go_table-- 存储了各交叉点信息的列表。

返回值:没有返回值。

'''

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 #启动绘图,在IDE中运行加这句可避免报错

tt.speed(0)

tt.ht()#隐藏笔头

#n, s, (x, y), s分别存储了棋盘的路数,格子宽度和左上角坐标

n, s, x, y = 9, 60, -240, 240

#星位坐标

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) #画棋谱(隐藏手数编号)

tt.done()

Python算法之旅字符串游戏之九路棋盘_第3张图片
图3

古老师:小美,又在欺负阿福了啊!你可别小看他,别看他嘴上不说,心里可清楚得很哪。不过小美这段时间进步确实挺大的,不仅能熟练使用各种turtle 方法,连自定义函数也写得很漂亮了呢!但我不得不说的是,你画的图并不是真正的围棋谱,真正的围棋谱上面是要显示手数编号的,就像图4这种样子:

Python算法之旅字符串游戏之九路棋盘_第4张图片
图4

阿福:没错,其实这张图才是我想让你画的。

小美:那你不早说!不过要加上手数编号的话还真有点难度呢。不能简单地用”黑白空”字符来表示了。不仅要包含棋子颜色信息,还要包含手数编号信息,那岂不是要用2个变量来表示同一个交叉点的信息?

阿福:其实一个变量就够了,但是不能用字符,而要用整数,0表示空子,正数表示黑子,负数表示白子,它们的绝对值表示手数编号。

古老师:有道理!阿福,不愧是初中生啊,数学没有白学!小美,你知道负数吗?

小美:知道的,兴趣小组里老师讲过。

古老师:那就好。这样吧,小美,你先用阿福说的方法存储棋盘上各个交叉点的信息,再用你刚才画图3的思路,按照从上到下、从左到右的顺序把棋谱画出来。阿福呢,给你一个更艰巨的任务:按照落子顺序把棋谱画出来。

阿福:古老师你偏心,净挑难题考我。如果按照落子顺序画棋谱的话,那就需要存储棋子的手数编号、颜色和坐标等信息了,原来的经验都没用了,难度不止增大一点点啊。

古老师:谁叫你是高手呢,能者多劳嘛。不过你的思路是正确的,照着这个思路去做肯定能成功。这样吧,今天我有事先走了。棋谱画好了记得告诉我一声哦。拜拜。


有事没事最好拉到文末看看,说不定作者今天提供了彩蛋哦!

需要本文word版的,可以加入“Python算法之旅”知识星球参与讨论和下载文件,“Python算法之旅”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。

我们专注Python算法,感兴趣就一起来!

Python算法之旅字符串游戏之九路棋盘_第5张图片

 彩蛋

小美:阿福,古老师很器重你啊!对了,画那个带手数编号的棋子,是不是要先把棋子画好,再写编号啊?

阿福:古老师就是嘴巴甜!你不也经常被夸吗?没错,如果先写编号的话,填充棋子颜色的时候就会把编号覆盖掉。好了,我们都抓紧时间行动吧,早点给古老师看结果。

小美:嗯。。。。。。我好了。

'''

函数功能:在已经画好的棋盘上,按棋盘位置顺序添加棋子信息(显示手数编号)

函数名:draw_go_table2(n,s, x0, y0, go_table)

参数表:n -- 棋盘的路数;s -- 棋盘格子宽度;x0, y0

-- 棋盘左上角坐标;

go_table -- 存储各交叉点信息的列表,0、正数和负数分别代表空、黑子和白子,其绝对值为手数编号。

返回值:没有返回值。

'''     

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()

            #显示手数编号

            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  #启动绘图,在IDE中运行加这句可避免报错

tt.speed(0)

tt.ht()#隐藏笔头

#n, s, (x, y), s分别存储了棋盘的路数,格子宽度和左上角坐标

n, s, x, y = 9,60, -240, 240

#星位坐标

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) #画棋谱(显示手数编号)

tt.done()


阿福:动作挺快啊!我也好了。


'''

函数功能:在已经画好的棋盘上,添加棋子信息(按落子顺序显示手数编号)

函数名:draw_go_table3(n,s, x0, y0, go_table)

参数表:n -- 棋盘的路数;s -- 棋盘格子宽度;x0, y0

-- 棋盘左上角坐标;

       go_table --存储了各交叉点信息的列表,其元素值为(手数编号,棋子颜色,横坐标,纵坐标)。

返回值:没有返回值。

'''     

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()

        #显示手数编号

        tt.penup()

        tt.goto(x, y - s * 3 / 5)

        tt.pendown()

        tt.write(num, align="center",font=("Arial", 16, "normal"))


tt.TurtleScreen._RUNNING= True  #启动绘图,在IDE中运行加这句可避免报错

tt.speed(0)

tt.ht()#隐藏笔头

#n, s, (x, y), s分别存储了棋盘的路数,格子宽度和左上角坐标

n, s, x, y = 9,60, -240, 240

#星位坐标

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 = [(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) #画棋谱(显示手数编号) 

tt.done()

Python算法之旅字符串游戏之九路棋盘_第6张图片
图5

你可能感兴趣的:(Python算法之旅字符串游戏之九路棋盘)