简体   繁体   English

尝试在 Python 中使用 Turtle 绘制棋盘格 - 如何填充每隔一个方块?

[英]Trying to draw a checkerboard using Turtle in Python - how do I fill in every other square?

I'm trying to draw a checkerboard.我正在尝试画一个棋盘。

I drew the board, but now I have to define a function (a loop) that fills in every other square with black.我画了黑板,但现在我必须定义一个函数(一个循环),用黑色填充每隔一个方块。 I've been trying to write a loop to do this for a while, can someone help?我一直在尝试编写一个循环来执行此操作,有人可以帮忙吗?

Here's my code:这是我的代码:

import turtle


def drawGrid():
turtle.penup()
turtle.goto(-300, 250)
turtle.pendown()
turtle.forward(300)
turtle.right(90)
turtle.forward(300)
turtle.right(90)
turtle.forward(300)
turtle.right(90)
turtle.forward(300)

def drawColumns():
for i in range(4):
    turtle.right(90)
    turtle.forward(37.5)
    turtle.right(90)
    turtle.forward(300)
    turtle.left(90)
    turtle.forward(37.5)
    turtle.left(90)
    turtle.forward(300)

def drawRows():
turtle.left(180)
rows = 0 
while rows <= 3:
    rows += 1
    turtle.forward(37.5)
    turtle.right(90)
    turtle.forward(300)
    turtle.left(90)
    turtle.forward(37.5)
    turtle.left(90)
    turtle.forward(300)
    turtle.right(90)

def main():
drawGrid()
drawColumns()
drawRows()
if __name__ == "__main__":
main()

Turtles fill method works on shapes, ie a completely bounded area.海龟填充方法适用于形状,即完全有界的区域。 So rather than drawing a grid you need to think in terms of drawing a series of squares.因此,与其绘制网格,不如考虑绘制一系列正方形。

So lets start by defining a simple function to draw a filled in square.因此,让我们首先定义一个简单的函数来绘制一个实心正方形。 It takes a turtle object and a size which is the length of the side.它需要一个海龟对象和一个边长的大小。

import turtle

def draw_filled_square(this_turtle, size):    
    """Draw a square by drawing a line and turning through 90 degrees 4 times"""
    this_turtle.pendown()
    this_turtle.fill(True)
    for _ in range(4):
        this_turtle.forward(size)
        this_turtle.right(90)
    this_turtle.fill(False)
    this_turtle.penup()

we can call it like this:我们可以这样称呼它:

window = turtle.Screen()
myturtle = turtle.Turtle()
square_size = 90
myturtle.goto(-300, 200)

draw__filled_square(myturtle, square_size)

Which draws a single square.绘制一个正方形。 Note that it puts it back at the starting place, so we need to move it before drawing the next square.请注意,它会将其放回起始位置,因此我们需要在绘制下一个方块之前移动它。

Now, in practice, as long as we draw the outline of the box we only need to draw filled squares, unfilled squares can be represented negative space.现在,在实践中,只要我们画出盒子的轮廓,我们只需要绘制实心方块,未实心方块可以表示负空间。 But for the purposes of explanation I'm going to also draw them.但出于解释的目的,我还将绘制它们。

Defining a function for an unfilled square is easy -- just duplicate the existing function but set this_turtle.fill(False) at the beginning instead.为一个未填充的正方形定义一个函数很容易——只需复制现有函数,但在开头设置this_turtle.fill(False)

Anytime something needs to count in a repeating sequence (1, 2, 3, 4, 1, 2, 3, 4, ...) it calls for use of modulo (remainder).任何需要在重复序列(1、2、3、4、1、2、3、4、...)中计数的东西都需要使用模数(余数)。 Modulo means remainder so if x modulo y is 0 it means x is exactly divisible by y . Modulo 表示余数,因此如果x modulo y0则表示x可以被y整除。 This translates into code as if x % y == 0 :这转化为代码就像x % y == 0

Here's a simple drum machine to demonstrate:这是一个简单的鼓机来演示:

def drum_loop(x):
     # go bang on the fourth beat
     if x % 4 == 0:
         print("bang!")
     else:
         print("tish")

# prints tish, tish, tish, bang! tish, tish, tish, bang!
for i in range(1,9):
   drum_loop(i)

Alternating is just like counting 0, 1 , 0, 1 repeatedly.交替就像重复数 0, 1 , 0, 1 一样。

So we can draw a row like this:所以我们可以这样画一行:

for i in range(8): 
    if i % 2 == 0:
        draw_filled_square(myturtle, square_size)
    else:
        draw_unfilled_square(myturtle, square_size)
    # move to start of next square
    myturtle.forward(square_size)

Now just repeating this isn't going to do the trick, but it should be clear you can use modulo 2 again to make the rows alternate properly.现在只是重复这一点并不能解决问题,但应该很清楚,您可以再次使用模 2 使行正确交替。

Do this by defining a row function that will alternate between starting with a black and starting with a white square, then calling this from within another loop.为此,请定义一个行函数,该函数将在以黑色开始和以白色方块开始之间交替,然后从另一个循环中调用它。 (Don't forget to go back to the beginning and move down every time you start a row). (不要忘记每次开始一行时都回到开头并向下移动)。

Here's another example where drawing creates more work for the poor turtle than simply stamping .这是另一个例子,绘图为可怜的乌龟创造了比简单的冲压更多的工作。 Rather than thinking about drawing and filling boxes, think about the board itself as a filled square onto which other filled squares are stamped:与其考虑绘制和填充框,不如将电路板本身视为一个填充方块,上面印有其他填充方块:

from turtle import Turtle, Screen

NUMBER_SQUARES = 8
SQUARE_SIZE = 40
BOARD_SIZE = SQUARE_SIZE * NUMBER_SQUARES
BORDER_FRACTION = 1.025  # add a slight edge to board

STAMP_SIZE = 20  # size of turtle square image

turtle = Turtle(shape='square', visible=False)
turtle.shapesize(BOARD_SIZE / STAMP_SIZE * BORDER_FRACTION)
turtle.color('black')
turtle.stamp()

turtle.shapesize(SQUARE_SIZE / STAMP_SIZE)
turtle.color('white')
turtle.penup()

for y in range(-NUMBER_SQUARES//2, NUMBER_SQUARES//2):
    parity = y % 2 == 0

    for x in range(-NUMBER_SQUARES//2, NUMBER_SQUARES//2):
        if parity:
            turtle.goto(x * SQUARE_SIZE + SQUARE_SIZE//2, y * SQUARE_SIZE + SQUARE_SIZE//2)
            turtle.stamp()

        parity = not parity

Screen().exitonclick()

This solution can print a board in any two colors (eg black and red), it doesn't assume a white background.此解决方案可以打印任何两种颜色(例如黑色和红色)的板,它不假定为白色背景。 Just another example of better living through stamping.这只是通过冲压改善生活的另一个例子。

import turtle

turtle.pensize(2)
turtle.penup()
turtle.goto(-160,-160)
turtle.pendown()
turtle.color("black")

for i in range(4):
    turtle.forward(320)
    turtle.left(90)

for y in range(-160,160,80):
    for x in range(-160,160,80):
        turtle.begin_fill()
        turtle.penup()
        turtle.goto(x,y)
        turtle.pendown()

        for k in range(4):
            turtle.forward(40)
            turtle.left(90)

        turtle.end_fill()       

for y in range(-120,160,80):
    for x in range(-120,160,80):
        turtle.begin_fill()
        turtle.penup()
        turtle.goto(x,y)
        turtle.pendown()
        for k in range(4):
            turtle.forward(40)
            turtle.left(90)
        turtle.end_fill()   

turtle.done()

Let's have a look at the zig-zag approach (the explanation of the code is commented inside) :我们来看看锯齿形方法(代码的解释在里面有注释)

import turtle

def drawGrid(rows, cols, size):
    turtle.sety(turtle.ycor() + size * rows) # Draw the initial line
    f = size * 2
    turtle.begin_fill()
    for j in range(cols): # Make the columns
        if j % 2:
            turtle.backward(f) # Make room for the zig-zag up and zig-zag down
        for i in range(rows * 2): # rows * 2 because there will be both zig-zag down and a zig-zag up for each row
            turtle.forward(size)
            turtle.right(90)
            if i % 2:
                turtle.left, turtle.right = turtle.right, turtle.left # Switch the zig-zag direction
        turtle.left(180)
    turtle.end_fill()
    turtle.sety(turtle.ycor() - size * rows) # Draw the final line
    
turtle.penup()
turtle.goto(-300, -50) # Set the bottom-left position of the grid
turtle.pendown()
turtle.speed("fastest") # Because I have no patience
drawGrid(8, 8, 40)

Output:输出:

在此处输入图片说明

Note that the number of rows and columns must be even for this to work.请注意,行数和列数必须是偶数才能起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM