38

ifこれらの4つをPythonで書く必要があります。それが何をするかに注意してください、ループ内の4つの可能な状態の間で変化しています:1,0 -> 0,1 -> -1,0 -> 0,-1そして最初に戻ります。

if [dx, dy] == [1,0]:
    dx, dy = 0, 1
if [dx, dy] == 0, 1:
    dx, dy = -1, 0
if [dx, dy] == [-1, 0]
    dx, dy = 0, -1
if [dx, dy] == [0, -1]:
    dx, dy = 1, 0

誰かが私にこれを書くためのより良い/より良い方法を提案できますか?

4

5 に答える 5

158
dx, dy = -dy, dx

疑わしい場合は、数学を適用してください。;)

于 2012-02-01T23:12:25.583 に答える
56

マグナスの提案は、提起された質問に対する間違いなく正しい答えですが、一般的に言えば、次のような問題には辞書を使用する必要があります。

statemap = {(1, 0): (0, 1), (0, 1): (-1, 0), (-1, 0): (0, -1), (0, -1): (1, 0)}

dx, dy = statemap[dx, dy]

この場合でも、正確に4つの状態があり、それらが繰り返されることは明らかであるため、辞書を使用する方が良いと主張できますが、すべての数学の純粋な美しさに抵抗することはできません。

ちなみに、質問のコードにはバグがあり、テストする値が唯一の可能な値であると仮定すると、次のようになります。

dx, dy = 1, 0

バグは、2番目以降の条件が必要なことです。それ以外の場合は、テストをelif続行し、条件を変更した後です。それらがとである場合、すべての条件が真になり、最終的には同じになります。それらがとして開始された場合、2番目以降のすべての条件が真になり、再び。になります。等々...dxdy10011, 0

于 2012-02-01T23:11:09.797 に答える
31

マグナスの答えを拡張するだけです。[dx, dy] をベクトルとして想像すると、実際に行っているのは90 度 (または PI/2)の回転です。

これを計算するには、次の変換を使用できます。

二次元回転

あなたの場合、これは次のように翻訳されます:

x = x * cos(90) - y * sin(90)
y = x * sin(90) + y * cos(90)

それ以来sin(90) = 1、次のcos(90) = 0ように単純化します。

x, y = -y, x

そして、あなたはそれを持っています!

于 2012-02-08T16:22:22.497 に答える
18

操作している値は、連続的に回転する単位ベクトル、つまりフェーザーのように見えます。複素数は座標なので、次のようになります。

# at initialization
phase = 1
# at the point of modification
phase *= 1j
dx, dy = phase.real, phase.imag

dx,dy 値の意味に関する私の解釈が正しいと仮定すると、後で各ステップで別の量だけ回転させたいことが判明した場合に備えて、これにより柔軟性が高まります。

于 2012-02-02T00:42:19.497 に答える
6

私は Magnus の答えに賛成しますが、一連の値をローテーションするためのさらに別のアプローチを次に示します。

def rotate(*states):
    while 1:
        for state in states:
            yield state

for dx, dy in rotate((1, 0), (0, 1), (-1, 0), (0, -1)):
    pass

ループのbreakどこかにが必要であることに注意してください。そうしないと、決して終了しません。for dx, dy

于 2012-02-01T23:55:16.843 に答える