在函数中生成坐标的二元元组

2024-06-12 16:12:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一个函数来传递元组形式的坐标,例如(x,y)。你知道吗

这是我的第一个项目。你知道吗

我想用pygame创建一个棋盘,只需简单地在屏幕上点上黑白方块。你知道吗

现在,我已经设法在正确的目的地把所有的白色方块都用闪电击中了。你知道吗

我在这里尝试的是自动创建白色方块(稍后黑色方块也会发生同样的情况),更准确地说,我尝试传递以下元组:

    # first column
    window.blit(square, (0, 0))
    window.blit(square, (0, 200))
    window.blit(square, (0, 400))
    window.blit(square, (0, 600))
    window.blit(square, (0, 800))
    # second column
    window.blit(square, (100, 100))
    window.blit(square, (100, 300))
    window.blit(square, (100, 500))
    window.blit(square, (100, 700))
    # third column
    window.blit(square, (200, 0))
    window.blit(square, (200, 200))
    window.blit(square, (200, 400))
    window.blit(square, (200, 600))
    window.blit(square, (200, 800))
    # fourth column
    window.blit(square, (300, 100))
    window.blit(square, (300, 300))
    window.blit(square, (300, 500))
    window.blit(square, (300, 700))
    # fifth column
    window.blit(square, (400, 0))
    window.blit(square, (400, 200))
    window.blit(square, (400, 400))
    window.blit(square, (400, 600))
    window.blit(square, (400, 800))
    # seventh column
    window.blit(square, (500, 100))
    window.blit(square, (500, 300))
    window.blit(square, (500, 500))
    window.blit(square, (500, 700))
    # seventh column
    window.blit(square, (600, 0))
    window.blit(square, (600, 200))
    window.blit(square, (600, 400))
    window.blit(square, (600, 600))
    window.blit(square, (600, 800))
    # eighth column
    window.blit(square, (700, 100))
    window.blit(square, (700, 300))
    window.blit(square, (700, 500))
    window.blit(square, (700, 700))

在我的协调函数中,我成功地编写了以下代码,但从现在起我真的不知道该怎么做:

def coordinator():
    x = 0
    y = 0
    for column in range(0, 5):
        print((x, y))
        y += 200

    x = 200
    y = 0
    for column in range(0, 5):
        print((x, y))
        y += 200


coordinator()

其输出为:

(0, 0)
(0, 200)
(0, 400)
(0, 600)
(0, 800)
(200, 0)
(200, 200)
(200, 400)
(200, 600)
(200, 800)

提前谢谢你的帮助。你知道吗

好的,伙计们好消息,我已经设法写了一些代码,打印出所有我需要的坐标。这是我的“主要”课程,也就是显示.py地址:

import pygame
import sys
from coordinator import coordinator

pygame.init()
window_size = (800, 800)
game_window = pygame.display.set_mode(size=window_size)
pygame.display.set_caption('My Game')


while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()


    class WhiteSquare:
        height = int(window_size[0] / 8)
        width = int(window_size[1] / 8)
        a = height
        b = width
        white_square = pygame.Surface((a, b))
        white_square.fill((255, 255, 255), )

    ws = WhiteSquare()


    class BlueSquare:
        height = int(window_size[0] / 8)
        width = int(window_size[1] / 8)
        a = height
        b = width
        blue_square = pygame.Surface((a, b))
        blue_square.fill((0, 0, 255), )

    bs = BlueSquare()


    class ChessBoard:
        game_window.blit(ws.white_square, (0, 0))
        game_window.blit(bs.blue_square, (0, 100))





    cb = ChessBoard()

    coordinator()

    pygame.display.update()

对于那些有一个黑方格或以任何方式引用黑方格的解,我显然把我的“蓝色”改成了“黑色”。我只使用蓝色,因为我想确保黑色方块也在黑色背景上正常工作(如果这是有意义的话)。你知道吗

这是你的名字协调员.py它本身就足够好用了。当我试着把它叫进来时,问题就出现了显示.py文件。你知道吗

看一看:

def coordinator():
    o = white_odd_columns()
    e = white_even_columns()
    print('o: ' + str(o))
    print('e: ' + str(e))


def white_odd_columns():
    for x in range(0, 800, 200):
        print('odd column: ')
        y = 0
        for first_column in range(0, 5):
            odd_coordinate = (x, y)
            print('This is odd_coordinate ' + str(odd_coordinate))
            y += 200
            #return odd_coordinate

def white_even_columns():
    for x in range(100, 800, 200):
        print('even column: ')
        y = 100
        for first_column in range(0, 4):
            even_coordinate = (x, y)
            print('This is even_coordinate ' + str(even_coordinate))
            y += 200
            #return even_coordinate

white_even_columns()
white_odd_columns()
coordinator()

现在,当我运行coordinator时,我得到以下输出:

even column: 
This is even_coordinate (100, 100)
This is even_coordinate (100, 300)
This is even_coordinate (100, 500)
This is even_coordinate (100, 700)
even column: 
This is even_coordinate (300, 100)
This is even_coordinate (300, 300)
This is even_coordinate (300, 500)
This is even_coordinate (300, 700)
even column: 
This is even_coordinate (500, 100)
This is even_coordinate (500, 300)
This is even_coordinate (500, 500)
This is even_coordinate (500, 700)
even column: 
This is even_coordinate (700, 100)
This is even_coordinate (700, 300)
This is even_coordinate (700, 500)
This is even_coordinate (700, 700)
odd column: 
This is odd_coordinate (0, 0)
This is odd_coordinate (0, 200)
This is odd_coordinate (0, 400)
This is odd_coordinate (0, 600)
This is odd_coordinate (0, 800)
odd column: 
This is odd_coordinate (200, 0)
This is odd_coordinate (200, 200)
This is odd_coordinate (200, 400)
This is odd_coordinate (200, 600)
This is odd_coordinate (200, 800)
odd column: 
This is odd_coordinate (400, 0)
This is odd_coordinate (400, 200)
This is odd_coordinate (400, 400)
This is odd_coordinate (400, 600)
This is odd_coordinate (400, 800)
odd column: 
This is odd_coordinate (600, 0)
This is odd_coordinate (600, 200)
This is odd_coordinate (600, 400)
This is odd_coordinate (600, 600)
This is odd_coordinate (600, 800)
odd column: 
This is odd_coordinate (0, 0)
This is odd_coordinate (0, 200)
This is odd_coordinate (0, 400)
This is odd_coordinate (0, 600)
This is odd_coordinate (0, 800)
odd column: 
This is odd_coordinate (200, 0)
This is odd_coordinate (200, 200)
This is odd_coordinate (200, 400)
This is odd_coordinate (200, 600)
This is odd_coordinate (200, 800)
odd column: 
This is odd_coordinate (400, 0)
This is odd_coordinate (400, 200)
This is odd_coordinate (400, 400)
This is odd_coordinate (400, 600)
This is odd_coordinate (400, 800)
odd column: 
This is odd_coordinate (600, 0)
This is odd_coordinate (600, 200)
This is odd_coordinate (600, 400)
This is odd_coordinate (600, 600)
This is odd_coordinate (600, 800)
even column: 
This is even_coordinate (100, 100)
This is even_coordinate (100, 300)
This is even_coordinate (100, 500)
This is even_coordinate (100, 700)
even column: 
This is even_coordinate (300, 100)
This is even_coordinate (300, 300)
This is even_coordinate (300, 500)
This is even_coordinate (300, 700)
even column: 
This is even_coordinate (500, 100)
This is even_coordinate (500, 300)
This is even_coordinate (500, 500)
This is even_coordinate (500, 700)
even column: 
This is even_coordinate (700, 100)
This is even_coordinate (700, 300)
This is even_coordinate (700, 500)
This is even_coordinate (700, 700)
o: None
e: None

我的问题是协调员.py,当我运行coordinator()函数时,我希望看到一个包含所有坐标的元组列表,这样我就可以通过列表索引轻松地访问它们。你知道吗

如果可以的话,希望我能把坐标传递给ChessBoard类。你知道吗

我将继续尝试您的解决方案,尽管它们对我来说太难理解了,因为我刚刚开始使用python和pygame。你知道吗

这句话说,谢谢你们的时间,伙计们,我会继续关注你们的答案。:)


Tags: incoordinateforiscolumnwindowthispygame
3条回答

我想我做到了!我得到了我想要的确切结果(现在有一个全新的问题,但会发布一个新问题)。你知道吗

这是协调员:

# Returns two list of tuples, one for even columns (white squares), and
# one for odd columns (white squares).

# Needs to be implemented to achieve the same for black squares.

def coordinator():
    odd_columns = white_odd_columns()
    even_columns = white_even_columns()
    columns = [odd_columns, even_columns]
    # print(columns)
    return columns
    # print('odd_columns: ' + str(odd_columns))
    # print('even_columns: ' + str(even_columns))

# Returns a list with coordinates
# for white squares in odd columns
def white_odd_columns():
    odd_coordinates = []
    for x in range(0, 800, 200):
        y = 0
        for first_column in range(0, 5):
            odd_coordinates.append((x, y))
            y += 200
    # print('This should be the complete list of odd coordinates' + str(odd_coordinates))
    return odd_coordinates

# Returns a list with coordinates
# for white squares in even columns
def white_even_columns():
    even_coordinates = []
    for x in range(100, 800, 200):
        y = 100
        for first_column in range(0, 4):
            even_coordinates.append((x, y))
            y += 200
    # print('This should be the complete list of even coordinates' + str(even_coordinates))
    return even_coordinates

# white_even_columns()
# white_odd_columns()
coordinator()

这里是输出(两个元组列表的列表-奇数列和偶数列,基本上是所有坐标):

[[(0, 0), (0, 200), (0, 400), (0, 600), (0, 800), (200, 0), (200, 200), (200, 400), (200, 600), (200, 800), (400, 0), (400, 200), (400, 400), (400, 600), (400, 800), (600, 0), (600, 200), (600, 400), (600, 600), (600, 800)], [(100, 100), (100, 300), (100, 500), (100, 700), (300, 100), (300, 300), (300, 500), (300, 700), (500, 100), (500, 300), (500, 500), (500, 700), (700, 100), (700, 300), (700, 500), (700, 700)]]

Process finished with exit code 0

我认为我的问题得到了回答,但当我更新最终解决方案时,我会记住你的问题。谢谢你们,伙计们。你知道吗

在这个答案的最后,我给你一个函数,它将产生棋盘的所有坐标,以及右边的方块:

for square, coord in coordinator((ws.white_square, bs.blue_square)):
    window.blit(square, coord)

但我将首先介绍如何使用几种不同的循环方法来解决这个问题。你知道吗

最简单的方法是创建一个列表,并附加坐标:

def coordinator():
    coordinates = []
    x = 0
    y = 0
    for column in range(0, 5):
        coordinates.append((x, y))
        y += 200

    x = 200
    y = 0
    for column in range(0, 5):
        coordinates.append((x, y))
        y += 200
    return coordinates

然后调用者可以循环每个元组的列表:

for coord in coordinator():
    window.blit(square, coord)

请注意,您可以大大简化循环;y可以通过乘法计算,您可以在同一次迭代中同时附加(0, ...)(200, ...)元组:

def coordinator():
    coordinates = []
    for column in range(5):
        coordinates.append((0, column * 200))
        coordinates.append((200, column * 200))
    return coordinates

或者,您可以告诉range()使步数为200,而不是列计数器:

def coordinator():
    coordinates = []
    for y in range(0, 900, 200):
        coordinates.append((0, y))
        coordinates.append((200, y))
    return coordinates

您还可以使x成为一个循环,循环使用两个值:

def coordinator():
    coordinates = []
    for x in (0, 200):
        for y in range(0, 900, 200):
            coordinates.append((x, y))
    return coordinates

然后可以将其转换为单个列表:

def coordinator():
    return [(x, y) for x in (0, 200) for y in range(0, 900, 200)]

您实际上不需要整个列表,也可以将其设置为生成器表达式;这将按需生成值,一旦使用了每个坐标,内存将再次被清除:

def coordinator():
    return ((x, y) for x in (0, 200) for y in range(0, 900, 200))

我只是用(... for target in iterable)替换了[... for target in iterable],告诉Python不要将所有内容都保存在内存中。你知道吗

当然,这一切只会产生已经用print()语句创建的输出。你知道吗

要生成所有可能的白色方块(9行100x100个方块,偶数行5个奇数方块,奇数行4个偶数方块),只需为x使用完整的range(),并为奇数列添加另一个这样的循环:

for x in range(0, 900, 200):
    for y in range(0, 900, 200):
        coordinates.append((x, y))
for x in range(100, 900, 200):
    for y in range(100, 900, 200):
        coordinates.append((x, y))

请注意,对于第二组循环,唯一更改的是y的起始值。实际上,你可以从x算出起始值,如果x,除以平方大小(100)是偶数,你希望y0开始,否则你希望y100开始。以100为增量进行x步进:

for x in range(0, 900, 100):
    even = (x // 100) % 2 == 0  # true for even, false for odd
    for y in range(0 if even else 100, 900, 200):
        coordinates.append((x, y))

这将生成所有期望的坐标,从第一行的(0, 0), (0, 200), (0, 400), (0, 600), (0, 800)到第二行的(100, 100), (100, 300), (100, 500), (100, 700),一直到最后一行的(800, 0), (800, 200), (800, 400), (800, 600), (800, 800)。你知道吗

请注意,最好不要硬编码上面的数字,它将更好地为宽度,高度和正方形大小是可配置的。作为一个函数,它变成:

def coordinator(boardsize=900, squaresize=100):
    coordinates = []
    for x in range(0, boardsize, squaresize):
        even = x // squaresize % 2 == 0  # true for even, false for odd
        for y in range(0 if even else squaresize, boardsize, squaresize * 2):
            coordinates.append((x, y))
    return coordinates

产生精确的输出:

>>> from pprint import pprint
>>> pprint(coordinator())
[(0, 0),
 (0, 200),
 (0, 400),
 (0, 600),
 (0, 800),
 (100, 100),
 (100, 300),
 (100, 500),
 (100, 700),
 (200, 0),
 (200, 200),
 (200, 400),
 (200, 600),
 (200, 800),
 (300, 100),
 (300, 300),
 (300, 500),
 (300, 700),
 (400, 0),
 (400, 200),
 (400, 400),
 (400, 600),
 (400, 800),
 (500, 100),
 (500, 300),
 (500, 500),
 (500, 700),
 (600, 0),
 (600, 200),
 (600, 400),
 (600, 600),
 (600, 800),
 (700, 100),
 (700, 300),
 (700, 500),
 (700, 700),
 (800, 0),
 (800, 200),
 (800, 400),
 (800, 600),
 (800, 800)]

但是这还不够,因为这只是白色的正方形。你必须改变逻辑来产生蓝色的方块。你知道吗

然而,实际上,只生成所有的正方形会更容易,让函数告诉你放在那里的正方形是什么。您将生成所有坐标,将xy增加100((0, 0), (0, 100), (0, 200), ..., (100, 0), (100, 100), (100, 200), ...,等等),然后用交替的白色和蓝色正方形组合这些坐标。你知道吗

最简单的方法是使用^{} module;它有一个函数来生成(x, y)坐标(^{})所需的笛卡尔积,它有一个函数来在正方形(^{})之间反复交替:

from itertools import cycle, product

def coordinator(squares, boardsize=900, squaresize=100):
    # (x, y), from (0, 0) through to (800, 800)
    coordinates = product(range(0, boardsize, squaresize), repeat=2)
    # endless series of white, blue, white, blue, white, blue, ...
    squares_cycle = cycle(squares)
    return zip(squares_cycle, coordinates)

这将为您生成(square, (x, y))值;我使用字符串'white''blue'来演示结果:

>>> pprint(list(coordinator(("white", "blue"))))
[('white', (0, 0)),
 ('blue', (0, 100)),
 ('white', (0, 200)),
 ('blue', (0, 300)),
 ('white', (0, 400)),
 ('blue', (0, 500)),
 ('white', (0, 600)),
 ('blue', (0, 700)),
 ('white', (0, 800)),
 ('blue', (100, 0)),
 ('white', (100, 100)),
 ('blue', (100, 200)),
 ('white', (100, 300)),
 ('blue', (100, 400)),
 ('white', (100, 500)),
 ('blue', (100, 600)),
 ('white', (100, 700)),
 ('blue', (100, 800)),
 ('white', (200, 0)),
 ('blue', (200, 100)),
 ('white', (200, 200)),
 ('blue', (200, 300)),
 ('white', (200, 400)),
 ('blue', (200, 500)),
 ('white', (200, 600)),
 ('blue', (200, 700)),
 ('white', (200, 800)),
 ('blue', (300, 0)),
 ('white', (300, 100)),
 ('blue', (300, 200)),
 ('white', (300, 300)),
 ('blue', (300, 400)),
 ('white', (300, 500)),
 ('blue', (300, 600)),
 ('white', (300, 700)),
 ('blue', (300, 800)),
 ('white', (400, 0)),
 ('blue', (400, 100)),
 ('white', (400, 200)),
 ('blue', (400, 300)),
 ('white', (400, 400)),
 ('blue', (400, 500)),
 ('white', (400, 600)),
 ('blue', (400, 700)),
 ('white', (400, 800)),
 ('blue', (500, 0)),
 ('white', (500, 100)),
 ('blue', (500, 200)),
 ('white', (500, 300)),
 ('blue', (500, 400)),
 ('white', (500, 500)),
 ('blue', (500, 600)),
 ('white', (500, 700)),
 ('blue', (500, 800)),
 ('white', (600, 0)),
 ('blue', (600, 100)),
 ('white', (600, 200)),
 ('blue', (600, 300)),
 ('white', (600, 400)),
 ('blue', (600, 500)),
 ('white', (600, 600)),
 ('blue', (600, 700)),
 ('white', (600, 800)),
 ('blue', (700, 0)),
 ('white', (700, 100)),
 ('blue', (700, 200)),
 ('white', (700, 300)),
 ('blue', (700, 400)),
 ('white', (700, 500)),
 ('blue', (700, 600)),
 ('white', (700, 700)),
 ('blue', (700, 800)),
 ('white', (800, 0)),
 ('blue', (800, 100)),
 ('white', (800, 200)),
 ('blue', (800, 300)),
 ('white', (800, 400)),
 ('blue', (800, 500)),
 ('white', (800, 600)),
 ('blue', (800, 700)),
 ('white', (800, 800))]

你的代码要做的就是给这个函数你的ws.white_squarebs.blue_square平方值,然后使用每个迭代步骤的输出来blit:

for square, coord in coordinator((ws.white_square, bs.blue_square)):
    window.blit(square, coord)

这种方法的优点是,您现在可以改变电路板的大小,也可以改变正方形的大小。您的电路板有9 x 9个正方形,因此必须产生交替行:

1  2  3  4  5  6  7  8  9
┌───────────────────────────┐
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 1
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 2
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 3
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 4
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 5
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 6
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 7
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 8
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 9
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
└───────────────────────────┘

但是actual chess boards有八行和八列:

1  2  3  4  5  6  7  8
┌────────────────────────┐
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 1
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 2
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 3
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 4
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 5
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 6
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│ 7
│░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓│
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│ 8
│▓▓▓░░░▓▓▓░░░▓▓▓░░░▓▓▓░░░│
└────────────────────────┘

请注意,在这种情况下,每行上有相同数量的白色和蓝色方块。你知道吗

要生成这种电路板,您所要做的就是调整电路板的大小,并可以选择调整正方形的大小。一块800x800像素的电路板会立即产生正确的输出:

for square, coords in coordinator((ws.white_square, bs.blue_square), 800):
    # ...

因为range()的值很容易调整,所以不管怎样,正方形总是交替的。你知道吗

您需要使用模运算符来生成“隔一个”样式的坐标。你知道吗

for row in range(8):
    for col in range(8):
        if col % 2 == row % 2:
            x = col * 100
            y = row * 100
            window.blit(square, (x, y))

与原始代码具有相同的效果。你知道吗

一次画黑白方块

for row in range(8):
    for col in range(8):
        is_black = (col % 2 == row % 2)
        x = col * 100
        y = row * 100
        window.blit((black_square if is_black else white_square), (x, y))

(假设您有black_squarewhite_square精灵)

相关问题 更多 >