262

私は現在、タイル マップを使用して、pygame のゲームのマップ エディターに取り組んでいます。レベルは、次の構造のブロックから構築されます (ただし、はるかに大きくなります)。

level1 = (
         (1,1,1,1,1,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,1,1,1,1,1))

ここで、「1」は壁のブロック、「0」は空の空気のブロックです。

次のコードは、基本的にブロック タイプの変更を処理するコードです。

clicked = pygame.mouse.get_pressed()
if clicked[0] == 1:
    currLevel[((mousey+cameraY)/60)][((mousex+cameraX)/60)] = 1

しかし、レベルはタプルに格納されているため、異なるブロックの値を変更することはできません。レベル内のさまざまな値を簡単に変更するにはどうすればよいですか?

4

10 に答える 10

348

タプルをリストに変換:

>>> t = ('my', 'name', 'is', 'mr', 'tuple')
>>> t
('my', 'name', 'is', 'mr', 'tuple')
>>> list(t)
['my', 'name', 'is', 'mr', 'tuple']

リストをタプルに変換:

>>> l = ['my', 'name', 'is', 'mr', 'list']
>>> l
['my', 'name', 'is', 'mr', 'list']
>>> tuple(l)
('my', 'name', 'is', 'mr', 'list')
于 2014-05-06T14:27:56.903 に答える
87

タプルのタプルがあります。
すべてのタプルをリストに変換するには:

[list(i) for i in level] # list of lists

- - また - -

map(list, level)

編集が完了したら、元に戻すだけです。

tuple(tuple(i) for i in edited) # tuple of tuples

--- または --- (@jamylak に感謝)

tuple(itertools.imap(tuple, edited))

numpy 配列を使用することもできます。

>>> a = numpy.array(level1)
>>> a
array([[1, 1, 1, 1, 1, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 1, 1, 1, 1, 1]])

操作用:

if clicked[0] == 1:
    x = (mousey + cameraY) // 60 # For readability
    y = (mousex + cameraX) // 60 # For readability
    a[x][y] = 1
于 2013-04-30T09:38:41.467 に答える
27

リストのリストを持つことができます。以下を使用して、タプルのタプルをリストのリストに変換します。

level1 = [list(row) for row in level1]

また

level1 = map(list, level1)

それに応じてそれらを変更します。

しかし、派手な配列はよりクールです。

于 2013-04-30T09:37:02.773 に答える
20

タプルをリストに変換するには

(指定された質問のタプル間にカンマがありませんでした。エラー メッセージを防ぐために追加されました)

方法 1:

level1 = (
     (1,1,1,1,1,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,1,1,1,1,1))

level1 = [list(row) for row in level1]

print(level1)

方法 2:

level1 = map(list,level1)

print(list(level1))

方法 1 の所要時間 --- 0.0019991397857666016 秒 ---

方法 2 にかかった --- 0.0010001659393310547 秒 ---

于 2015-06-20T02:20:29.910 に答える
16

その型をタプルからリストに、またはその逆に変換してみませんか。

level1 = (
     (1,1,1,1,1,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,1,1,1,1,1))

print(level1)

level1 = list(level1)

print(level1)

level1 = tuple(level1)

print(level1)
于 2015-05-30T17:22:54.423 に答える
5

どちらの答えも良いですが、ちょっとしたアドバイス:

タプルは不変であり、変更できないことを意味します。したがって、データを操作する必要がある場合は、データをリストに格納することをお勧めします。これにより、不要なオーバーヘッドが削減されます。

あなたの場合、eumiroで示されているようにデータをリストに抽出し、変更後、Schoolboyからの回答と同様の構造の同様のタプルを作成します。

また、numpy 配列を使用することをお勧めします。

于 2013-04-30T09:51:50.327 に答える
2

リストのリストの代わりにリストを 1 つだけ使用すると、処理速度が劇的に向上する可能性があります。もちろん、これはすべての内部リストが同じサイズである場合にのみ可能です(これはあなたの例に当てはまるので、これを想定しています)。

WIDTH = 6
level1 = [ 1,1,1,1,1,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,1,1,1,1,1 ]
print level1[x + y*WIDTH]  # print value at (x,y)

リストの代わりにビットフィールドを使用すると、さらに高速になる可能性があります。

WIDTH = 8  # better align your width to bytes, eases things later
level1 = 0xFC84848484FC  # bit field representation of the level
print "1" if level1 & mask(x, y) else "0"  # print bit at (x, y)
level1 |= mask(x, y)  # set bit at (x, y)
level1 &= ~mask(x, y)  # clear bit at (x, y)

def mask(x, y):
  return 1 << (WIDTH-x + y*WIDTH)

ただし、それはもちろん、フィールドに 0 または 1 が含まれている場合にのみ機能します。より多くの値が必要な場合は、問題をより複雑にするいくつかのビットを組み合わせる必要があります。

于 2013-04-30T10:02:36.257 に答える