Micro: битовые классы вместо глобальных переменных - ошибка выделения памяти в микропифоне - PullRequest
0 голосов
/ 01 мая 2018

Я только что создал свою первую маленькую правду или решился / раскрутить бутылку для старшего / старшего школьного клуба по программированию на Micro: bit. Я хотел бы представить использование oop / classes / objects вместо (страшных) глобальных переменных. Игра отлично работает на эмуляторах, таких как https://create.withcode.uk/,, но на самом Micro: bit я сталкиваюсь с ошибками выделения памяти, как только я пытаюсь поместить что-нибудь в классы. Разве 16 КБ ОЗУ в микробите недостаточно Или я объявляю классы неправильно?

Исходя из внешнего интерфейса и немного PHP / SQL, я новичок в области знаний Python и памяти, поэтому любая помощь приветствуется.

Если я использую глобальные переменные в каждой из функций, это работает без проблем.

Вот код:

from microbit import *
import random

#timer current function

#Global variables
class game:
    gsTime = 3000
    timerPrev = 0
    numOfPlayers = 0
    maxPlayers = 8
    stage = 'start'
    minSpinTime = 3000

class player:
    #Which player is currently selected
    selected = 0

    #Player position display
    def pos1(): display.set_pixel(2, 4, 9)
    def pos2(): display.set_pixel(2, 0, 9)
    def pos3(): display.set_pixel(0, 2, 9)
    def pos4(): display.set_pixel(4, 2, 9)
    def pos5(): display.set_pixel(0, 4, 9)
    def pos6(): display.set_pixel(4, 0, 9)
    def pos7(): display.set_pixel(0, 0, 9)
    def pos8(): display.set_pixel(4, 4, 9)

    #Array of all player positions
    positions = [
        [pos1, 1, Image.ARROW_S],
        [pos2, 5, Image.ARROW_N],
        [pos3, 3, Image.ARROW_W],
        [pos4, 7, Image.ARROW_E],
        [pos5, 2, Image.ARROW_SW],
        [pos6, 6, Image.ARROW_NE],
        [pos7, 4, Image.ARROW_NW],
        [pos8, 8, Image.ARROW_SE]
    ]
    positionsOrdered = []

class buttons:
    pressed = False

class spinner:
    completeSpins = 0
    isCompleteSpin = False
    rdTime = 0
    stage = 'start'
    stageStarted = False

gameCall = game()
playerCall = player()
buttonsCall = buttons()
spinnerCall = spinner()

#Return a random range of numbers
def rdRange(minMult,maxMult,base):
    return random.randint(base*minMult, base*maxMult)

#return sort key of list
def getKey(item):
    return item[1]

#Timer function
def timer(timeElapsed, onCompleteFunc):
    if running_time() - gameCall.timerPrev >= timeElapsed:
        onCompleteFunc()

#Position Players Start is true
def positionPlayersStartTrue():
    game.stage = 'positionPlayers'

def selectNumOfPlayers(gteOrLte):
    game.timerPrev = running_time()
    if gteOrLte == 'gte':
        if gameCall.numOfPlayers >= gameCall.maxPlayers:
            game.numOfPlayers = 1
        else:
            game.numOfPlayers += 1
    else:
        if gameCall.numOfPlayers <= 1:
            game.numOfPlayers = maxPlayers
        else:
            game.numOfPlayers -= 1
    display.show(str(gameCall.numOfPlayers)) #Have to convert int to string before passing to display.show func
    buttons.pressed = True

#Ask for number of players up to maxPlayers.
def setPlayerNum():
    #If B is pressed increment by 1 up the max players and cycle back to 1
    if button_b.was_pressed():
        selectNumOfPlayers('gte')
    #If A is pressed decrement by 1 down to 1 and then cycle back to maxPlayers var
    elif button_a.was_pressed():
        selectNumOfPlayers('lte')
    elif buttonsCall.pressed == False:
        #Ask how many players
        display.show('#?')
    else:
        timer(gameCall.gsTime, positionPlayersStartTrue)

#display the position of players
def positionPlayers():
    buttons.pressed = False

    display.clear()
    for i in range(gameCall.numOfPlayers):
        el = player.positions[i]
        player.positionsOrdered.append(el)
        el[0]()
    player.positionsOrdered.sort(key=getKey)
    while buttonsCall.pressed == False:
        startSpin()

#start the spin - useful for starting the spin after one spin was complete too
def startSpin():
    if button_a.was_pressed() or button_b.was_pressed():
        buttons.pressed = True
        game.stage = 'spin'

#Spin start
def spin():
    if spinnerCall.stage == 'start' and spinnerCall.stageStarted == False:
        game.timerPrev = running_time()
        spinner.rdTime = rdRange(200, 700, gameCall.numOfPlayers)
        spinner.stageStarted = True
        print(spinner.rdTime)
    for i in range(gameCall.numOfPlayers):
        display.clear()
        el = player.positionsOrdered[i]
        el[0]()
        if i + 1 == gameCall.numOfPlayers:
            spinner.completeSpins += 1
            spinner.isCompleteSpin = True
        else:
            spinner.isCompleteSpin = False
        if spinnerCall.stage == 'start':
            if (running_time() - gameCall.timerPrev >= (gameCall.minSpinTime + spinnerCall.rdTime)) and (spinnerCall.isCompleteSpin == True):
                spinner.stage = 'slow'
                spinner.stageStarted = False
            sleep(200)
        #Slower spin to emulate spinner slowing down as it comes near to stopping. Should probably use some clever-er maths here instead.
        elif spinner.stage == 'slow':
            if spinnerCall.stageStarted == False:
                game.timerPrev = running_time()
                spinner.rdTime = rdRange(500, 900, gameCall.numOfPlayers)
                spinner.stageStarted = True
                print(spinnerCall.rdTime)
            if running_time() - gameCall.timerPrev >= spinnerCall.rdTime:
                spinner.stage = 'stop'
                spinner.stageStarted = False
            sleep(400)
        elif spinner.stage == 'stop':
            player.selected = i
            game.stage = 'selectedPlayer'
            # reset spinner stage for next spin
            spinner.stage = 'start'
            break

#Player has been selected
def selectedPlayer():
    el = playerCall.positionsOrdered[playerCall.selected]
    sleep(200)
    display.show(el[2])
    sleep(200)
    display.clear()


while True:
    #CALL FUNCTIONS
    if gameCall.stage == 'start':
        setPlayerNum()
    elif gameCall.stage == 'positionPlayers' and buttonsCall.pressed == True:
        positionPlayers()
    elif gameCall.stage == 'spin':
        spin()
    elif gameCall.stage == 'selectedPlayer':
        #print('this one is selected ', playerCall.selected)
        selectedPlayer()
        #start spin again if button is pressed
        startSpin()

1 Ответ

0 голосов
/ 21 января 2019

Ваш код слишком велик для микробита. Микробит ограничен 16 КБ ОЗУ . Чтобы уменьшить размер вашего кода вы можете:

  1. минимизируйте напрямую из редактора Mu или используйте любой другой минификатор lib
  2. Сокращение имен переменных
  3. Удалить комментарии
...