0

ユーザーがキーボードで押したタートル キャンバスに任意の文字を描画するタートル描画プログラムを作成しました。ユーザーが呼び出した最後の描画を元に戻すための元に戻す機能を既に実装しています (以下を参照) 。おそらく私の現在の元に戻す機能に基づいて、これを行うための最もpythonicな方法に関するヒントやコツを教えてもらえますか? 私はこれについて多くのことをグーグルで検索しましたが役に立たなかったので、この問題に関する助けは大歓迎です。

私の元に戻す機能:

def Clear():
    clear()
    speed(0)
    tracer(0,0)



def undoHandler():
    if len(function) > 0:
        undoHandler.handling = True
        if not hasattr(undoHandler, "counter"):
            undoHandler.counter = 0
        undoHandler.counter += 1
        Clear()
        function.pop()
        penup()
        try:
            goto(o,p)
            print("Gone to")
        except:
            goto(-200, 100)
        pendown()

        # "function" is a deque I created with the letter functions appended to it        
        # Items created based on a Points class that also stores all the attributes including the width, height, color, etc. of each letter.     
        # Items from a queue I created for the letter functions. The following executes each item from the deque.
        try:
            for i in function:
            k = i.getXY()
            penup()
            goto(k)
            pendown()
            hk = i.getletterheight()
            global letter_height
            letter_height = hk
            rk = i.getletterwidth()
            global letter_width
            letter_width = rk
            hw = i.getwidth()
            width(hw)
            op = i.getcolor()
            try:
                color(op)
            except:
                for g in colors:
                cp = g.getcolor2()
                colormode(255)
                color(cp)
           j = i.getfunction()
           j()
        except:
            pass



   update()

編集:混乱を避けるために、「やり直し」でやりたいことは、キャンバスをクリアし、「やり直し」を呼び出すボタンが押されるたびに、元に戻したポイントを過ぎて1つの関数ですべてを再描画することです。たとえば、ユーザーがキャンバスに「HELLO」を描画し、ユーザーが文字「H」まで元に戻した場合、やり直しを 1 回押すと、タートルは「H(ユーザーが選択した新しい文字)L」を再描画する必要があります。 2 回目の呼び出しでは、タートルは「H(ユーザーが選択した新しい文字)LL」を描画する必要があります。また、元に戻した文字を、ユーザーが置き換えた文字に変更できる必要があります (したがって、「やり直し」)。たとえば、ユーザーが "HELLO" の "H" までを元に戻し、ユーザーが "E" を "A" に置き換えた場合、redo が呼び出されると、

4

1 に答える 1

2

元に戻す/やり直しを処理する簡単な方法は、2 つのスタックを使用することです。

Webブラウザに例えると、一方のスタックは移動用backwardsで、もう一方のスタックは移動用forwardsです。

上書きによる新しいアクション:新しいユーザー アクションが実行されるたびに、backwardsスタックにプッシュされます。最後に、アクションをポップしてスタックから破棄することで、次のやり直しアクションが上書きされforwardsます (スタックが空でない場合)。

元に戻す:ユーザーが前に戻りたい場合 ( undo)、アクションがbackwardsスタックからポップされ、アクションが元に戻されてから、アクションがforwardsスタックにプッシュされます。

すべてやり直し:ユーザーが前に進みたい場合 ( redo)、アクションがforwardsスタックからポップされ、アクションがやり直されてから、アクションがbackwardsスタックにプッシュされます。この場合、redoは実際にはredo allであるため、スタックが空redoになるまで繰り返す必要があります。forwards

警告:各アクションが自己完結型であるように定義されていることを確認してください。そうしないと、アクションが上書きされたときに問題が発生する可能性があります。

于 2016-01-07T02:04:28.823 に答える