omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Optimising the UI for a 2048 Widget Game

    Pythonista
    user-interface optimisation widget
    4
    15
    7566
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Buzzerb
      Buzzerb last edited by Buzzerb

      @JonB I managed to get it working simply by adding del ui after loading my view. All the necessary objects were contained in screen as far as I can tell, so this removed a significant quantity of unnecessary data.

      Edit: Somewhat working- occasional crashes occur

      cvp 1 Reply Last reply Reply Quote 0
      • cvp
        cvp @Buzzerb last edited by cvp

        @Buzzerb It is always possible to make the code shorter, but I don't know of that helps
        Assume your buttons are named up,right,down and left, all with the same action:

        def MoveButton(sender):
        	n = ['up','right','down','left']
        	moveTilesDirection(n.index(sender.name))
        	if failed == False:
        		generateNewNumbers()
        		printGrid()
        
        1 Reply Last reply Reply Quote 0
        • JonB
          JonB last edited by

          oh wait, this is a scene game? Im surprised that works at all in the the widget. I though you were just using views?

          All of those dels should be unnecessary, since unreferenced items should automatically be deleted at the end of the scope where it is declared. but gc.collect() might help?

          Buzzerb 1 Reply Last reply Reply Quote 0
          • ccc
            ccc last edited by ccc

            Optimizing in a different place... A dict will speed up printGrid().

            bg_colors = {2: "#fbffaa",
                         4: "#fff1aa",
                         8: "#ffb86a",
                         16: "#ff703e",
                         32: "#ff4f4f",
                         64: "#f20000",
                         128: "#edf800",
                         256: "#7cff61",
                         512: "#00f315",
                         1024: "#23ffe2",
                         2048: "#47b7ff",
                         4096: "#0b20ff",
                         8192: "#9400db"}
            
            
            def printGrid():
                """Outputs the current grid onto the UI, along with score, and number of moves"""
                for y in range(4):
                    for x in range(4):
                        value = playGrid[y][x]
                        tile = screen["tile{}{}".format(y, x)]
                        tile.text = "" if value == 0 else str(value)
                        tile.font = ("<system-bold>", 42 if value == 0 else 50)
                        tile.background_color = bg_colors.get(value, "#000000")
                        tile.text_color = "#000000" if 0 < value < 4096 else "#ffffff"
                        del tile         
                screen["scoreLabel"].text = "Score: " + str(score)
                screen["movesLabel"].text = "Moves: " + str(moves)
            
            Buzzerb 1 Reply Last reply Reply Quote 0
            • ccc
              ccc last edited by ccc

              You could also make all four buttons share a single action...

              def button_pressed(sender)
                  moveTilesDirection('up right down left'.split().index(sender.text))
                  if not failed:
                      generateNewNumbers()
                      printGrid()
              
              1 Reply Last reply Reply Quote 0
              • Buzzerb
                Buzzerb @ccc last edited by

                @ccc Speed isn’t really the problem as far as I know, but it’s possible that your method helps, I’ll test it. And thank you for the all buttons sharing a single action script.

                1 Reply Last reply Reply Quote 0
                • Buzzerb
                  Buzzerb @JonB last edited by Buzzerb

                  @JonB I’m not sure what would classify this as a scene game, could you explain?

                  Edit: @ccc In that case I'm not using a scene game

                  1 Reply Last reply Reply Quote 0
                  • ccc
                    ccc last edited by ccc

                    Also tryout f”strings” like:

                        screen[f"tile{y}{x}"]         
                        screen["scoreLabel"].text = f"Score: {score}"
                        screen["movesLabel"].text = f"Moves: {moves}"
                    
                    Buzzerb 1 Reply Last reply Reply Quote 0
                    • ccc
                      ccc last edited by

                      Scene games are built using http://omz-software.com/pythonista/docs/ios/scene.html

                      1 Reply Last reply Reply Quote 0
                      • Buzzerb
                        Buzzerb @ccc last edited by

                        @ccc Not sure how legitimate it is but I read that '+' string concatenation is faster when only combining two strings, and f string is faster with more. Also, is using dict.get with a default significantly slower or faster than just fetching a value because my game is unlikely to get above 8192, and I could always add more pairs to the dictionary.

                        1 Reply Last reply Reply Quote 0
                        • ccc
                          ccc last edited by ccc

                          https://docs.python.org/3/library/timeit.html#timeit.timeit will give you a good sense of performance differences. My bet is that timeit.timeit() will reveal that the dict will be faster then the repeated if/else. However the reason that I suggested the dict approach for a widget is code size.

                          Also try timeit() on the string question but remember that the current code is not concatenating two strings. That innocent little call to str() effects performance as well. Let timeit() guide choices that really matter to you.

                          https://goo.gl/images/BNdGdm

                          Buzzerb 1 Reply Last reply Reply Quote 0
                          • Buzzerb
                            Buzzerb @ccc last edited by

                            @ccc I looked into using timeit to determine performance of all these changes but ultimately decided that performance was almost definitely not the problem my widget was encountering.

                            Thank you for the dictionary approach anyway, it’s much more concise than I would’ve managed

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post
                            Powered by NodeBB Forums | Contributors