m0_63312581 2022-04-24 14:15 采纳率: 100%
浏览 68
已结题

How can I simplify my game to avoid it from taking larger memory as the running time increases?

问题遇到的现象和发生背景

This is a color-flipping game based on the python turtle module. The game is composed of a rectangular board divided into a number of flat colored tiles of various colors. The goal of the game is to turn all tiles to the same color by choosing one tile on the board and then changing its color to another color. The newly selected color will spread to all its neighboring tiles which match the original color of the chosen tile. The player continues selecting another tile and changing its color to another until all the tiles within the board flipped to the same color. In addition to the rectangular board, an array of colors is shown below the board. These are the colors to which the player can choose to flip the color of the selected tile.

As I started to run my game, the memory it took up was getting larger and larger as the running time increased. And it's getting slower and slower. I think it might be due to the while loop at the end of my code. But I'm not sure. How can I modify it to make it faster?

问题相关代码,请勿粘贴截图
### The game is based on the flipping number game
### 

from turtle import *
from random import choice
from functools import partial

# set game dimension to be 5 x 5
g_dim = 5
# use random.choice() to create the color for the game
g_game = [choice(['#0000FF', '#FF0000', '#FFFF00', '#008000', '#00FFFF']) for i in range(25)]
# provide the option to flip during the game
optionColor = ['#0000FF', '#FF0000', '#FFFF00', '#008000', '#00FFFF']

# show a set of colors as option for user to flip
def promptColorToFlip(optionColor,  # a list that contains a set of the color for user to choose from
                    height=100,     # the height of the option tiles
                    width=100       # the width of the option tiles
                    ):
    # the coordinates of the first tile
    x = -200
    y = -200

    for i in range(len(optionColor)):
        tile = prototype.clone()
        tile.goto(i * width + x, -(height+50) + y)
        tile.color('white', optionColor[i])
        tile.onclick(partial(returnChosenColor, i))

# return the index of the select-to-flip-to color in the optionColor list
def returnChosenColor(userChosenColor,  # the index of the select-to-flip-to color in the optionColor list
                        x, y            # take the positional arguments from the onclick() function to avoid errors, no significant meaning
                        ):
    global userOption
    userOption = userChosenColor

def refreshScreen(game, rows=5, columns=5, height=100, width=100):
    x = -200  
    y = -200

    for column in range(columns):
        for row in range(rows):
            square = prototype.clone()
            square.goto(column * (5+width) + x , row * (5+height) + y)
            square.onclick(partial(userChosenTile, row, column))
            if state['framed'] == row*5+column:
                square.color('black', game[row*5+column])
            else:
                square.color('white', game[row*5+column])
    update()

def userChosenTile(ROW, COL, x, y):
    global state, R, C
    state['framed'] = ROW*5+COL
    R = ROW
    C = COL

def flipColor(row, col, game, orig, to):
    print('excuted')
    global userOption, state, R, C
    if orig == to:
        return game
    if row < 0 or row >= g_dim:
        return
    if col < 0 or col >= g_dim:
        return

    idx = row*g_dim+col   

    if game[idx] != orig:
        return
    print(idx, 'excuted')
    game[idx] = to
    flipColor(row-1, col, game, orig, to)
    flipColor(row+1, col, game, orig, to)
    flipColor(row, col-1, game, orig, to)
    flipColor(row, col+1, game, orig, to)
    
    state = {'framed':None}
    R = None
    C = None
    userOption = None

    return game

# initialize the game status
state = {'framed':None}     # stores the number of the last selected tile, which will be framed with a black border
R = None                    # the row of the last selected tile
C = None                    # the column of the last selected tile
userOption = None           # the index of the select-to-flip-to color in the optionColor list

# create a prototype of the tiles
prototype = Turtle()
prototype.shape('square')
prototype.shapesize(5, 5, 5)
prototype.penup()

if __name__ == '__main__':
    # disable auto screen refresh
    tracer(False)
    # run the game
    while True:
        # the try and except block here is to prevent error from raising when user terminate the progarm
        try:
            promptColorToFlip(optionColor)
            refreshScreen(g_game)
            if state['framed'] is not None and R is not None and C is not None and userOption is not None:
                g_game = flipColor(R, C, g_game, g_game[state['framed']], optionColor[userOption])
        except:
            pass

运行结果及报错内容
我的解答思路和尝试过的方法
我想要达到的结果
  • 写回答

1条回答 默认 最新

  • 溪风沐雪 2022-04-24 15:44
    关注

    The problem is adding too many click events

    img

    img

    img

    from turtle import *
    from random import choice
    from functools import partial
     
    # set game dimension to be 5 x 5
    g_dim = 5
    # use random.choice() to create the color for the game
    g_game = [choice(['#0000FF', '#FF0000', '#FFFF00', '#008000', '#00FFFF']) for i in range(25)]
    # provide the option to flip during the game
    optionColor = ['#0000FF', '#FF0000', '#FFFF00', '#008000', '#00FFFF']
     
    # show a set of colors as option for user to flip
    def promptColorToFlip(optionColor,  # a list that contains a set of the color for user to choose from
                        height=100,     # the height of the option tiles
                        width=100       # the width of the option tiles
                        ):
        # the coordinates of the first tile
        x = -200
        y = -200
     
        for i in range(len(optionColor)):
            tile = prototypeForOptions[i]
            tile.goto(i * width + x, -(height+50) + y)
            tile.color('white', optionColor[i])
     
    # return the index of the select-to-flip-to color in the optionColor list
    def returnChosenColor(userChosenColor,  # the index of the select-to-flip-to color in the optionColor list
                            x, y            # take the positional arguments from the onclick() function to avoid errors, no significant meaning
                            ):
        global userOption
        userOption = userChosenColor
     
    def refreshScreen(game, rows=5, columns=5, height=100, width=100):
        x = -200  
        y = -200
     
        for column in range(columns):
            for row in range(rows):
                square = prototypeForScreens[row][column]
                square.goto(column * (5+width) + x , row * (5+height) + y)
                if state['framed'] == row*5+column:
                    square.color('black', game[row*5+column])
                else:
                    square.color('white', game[row*5+column])
        update()
     
    def userChosenTile(ROW, COL, x, y):
        global state, R, C
        state['framed'] = ROW*5+COL
        R = ROW
        C = COL
     
    def flipColor(row, col, game, orig, to):
        print('excuted')
        global userOption, state, R, C
        if orig == to:
            return game
        if row < 0 or row >= g_dim:
            return
        if col < 0 or col >= g_dim:
            return
     
        idx = row*g_dim+col   
     
        if game[idx] != orig:
            return
        print(idx, 'excuted')
        game[idx] = to
        flipColor(row-1, col, game, orig, to)
        flipColor(row+1, col, game, orig, to)
        flipColor(row, col-1, game, orig, to)
        flipColor(row, col+1, game, orig, to)
        
        state = {'framed':None}
        R = None
        C = None
        userOption = None
     
        return game
     
    # initialize the game status
    state = {'framed':None}     # stores the number of the last selected tile, which will be framed with a black border
    R = None                    # the row of the last selected tile
    C = None                    # the column of the last selected tile
    userOption = None           # the index of the select-to-flip-to color in the optionColor list
     
    # create a prototype of the tiles
    prototype = Turtle()
    prototype.shape('square')
    prototype.shapesize(5, 5, 5)
    prototype.penup()
    
    prototypeForOptions = []
    prototypeForScreens = []
    for i in range(len(optionColor)):
        tile = prototype.clone()
        tile.onclick(partial(returnChosenColor, i),add=False)
        prototypeForOptions.append(tile)
    for column in range(5):
        prototypeForScreen = []
        for row in range(5):
            square = prototype.clone()
            square.onclick(partial(userChosenTile, column, row),add=False)
            prototypeForScreen.append(square)
        prototypeForScreens.append(prototypeForScreen)
     
    if __name__ == '__main__':
        # disable auto screen refresh
        tracer(False)
        # run the game
        while True:
            # the try and except block here is to prevent error from raising when user terminate the progarm
            try:
                promptColorToFlip(optionColor)
                refreshScreen(g_game)
                if state['framed'] is not None and R is not None and C is not None and userOption is not None:
                    g_game = flipColor(R, C, g_game, g_game[state['framed']], optionColor[userOption])
            except:
                pass
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月26日
  • 已采纳回答 4月24日
  • 创建了问题 4月24日

悬赏问题

  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制