How can I change variables inside classes? in python

I started coding a simple game, but I'll add several input types later.

My problem is my stocks class

don't add int

from def

chop / mine to my variable

"SP_wood / SP_stone", it just replaces variable

with the number it got from def

chop / mine. I tried giving int straight to def

addwood / addstone, but that didn't work for me. +=

should work and add two together. Should I do it variable

out class

and do it global

?

import random
import time
idle = True


class Taskassigner:
    def __init__(self, tasknum):
        self.tasknum = tasknum
    def choosejob(self):
        if self.tasknum == 1:
            self.chop()
        if self.tasknum == 2:
            self.mine()
    def chop(self):
        wood = random.randint(1, 10)
        print('chopping wood')
        time.sleep(1.5)
        print('you got', wood)
        Stockpile(wood, 0)
        time.sleep(0.75)
    def mine(self):
        stone = random.randint(1, 10)
        print('mining for stone')
        time.sleep(1.5)
        print('you got', stone)
        Stockpile(0, stone)
        time.sleep(0.75)

class Stockpile:
    def __init__(self, wood, stone):
        self.wood = wood
        self.stone = stone
        self.SP_wood = 0
        self.SP_stone = 0
        self.Addwood(self.wood)
        self.Addstone(self.stone)
        self.check_wood()
        self.check_stone()
    def Addwood(self, addwood):
        self.addwood = addwood
        self.SP_wood += self.addwood
    def Addstone(self, addstone):
        self.addstone = addstone
        self.SP_stone += self.addstone
    def check_wood(self):
        print(self.SP_wood)
    def check_stone(self):
        print(self.SP_stone)


while idle:
    taskchance = random.randint(0, 100)
    if taskchance < 50:
        tasknum = random.randint(0, 2)
        job = Taskassigner(tasknum)
        job.choosejob()

    else:
        print('idle')
        time.sleep(0.5)

      

+3


source to share


2 answers


I would change a few things, mainly because you are making it harder than necessary. It doesn't seem like yours TaskAssigner

really needs to contain state, so let's refactor it a bit, basically like a factory function. Then change these functions to work on our newly refactored class Stockpile

. Great job in encapsulation though !!!

def taskassigner(tasknum):
    """Function factory for tasks

    taskassigner(1) --> mine
    taskassigner(2) --> chop
    """

    def mine(stockpile):
        stockpile.stone += random.randint(1,10)
    def chop(stockpile):
        stockpile.wood += random.randint(1,10)

    tasks = [None, chop, mine]
    return tasks[tasknum]

class Stockpile(object):
    def __init__(self, wood, stone):
        self.wood = wood
        self.stone = stone
        # it not really clear what SP_wood and SP_stone do
        # so I'm not sure if you actually need them!

      

Since it is TaskAssigner

now a factory function instead of a class, our call signature looks a little different.

STARTING_WOOD, STARTING_STONE = 10, 10  # or whatever...
idle = True

player_stockpile = Stockpile(STARTING_WOOD, STARTING_STONE)
while idle:
    if random.randint(0, 1):  # since it a coinflip, this is easier
        task_num = random.randint(1, 2)
        task = taskassigner(task_num)  # task is now one of your functions
        task(player_stockpile)
    else:
        time.sleep(0.5)

      



All this suggests that you need to use separate modules for this!

# /main.py
import tasks
import time

STARTING_STONE, STARTING_WOOD = 10, 10
idle = True


class Stockpile(object):
    # defined as above


player_stockpile = Stockpile(STARTING_WOOD, STARTING_STONE)
while idle:
    if random.choice((True, False)):
        task = random.choice(tasks.tasklist)
        task(player_stockpile)
    else:
        time.sleep(0.5)

      

 

# /tasks.py
def mine(stockpile):
    stockpile.stone += random.randint(1,10)

def chop(stockpile):
    stockpile.wood += random.randint(1,10)

tasklist = [mine, chop]

      

+3


source


you need to keep your stock separate (but you should probably be transferring it, not globally)



import random
import time
idle = True


class Taskassigner:
    def __init__(self, tasknum,stockpile):
        self.tasknum = tasknum
        self.stockpile = stockpile
    def choosejob(self):
        if self.tasknum == 1:
            self.chop()
        if self.tasknum == 2:
            self.mine()
    def chop(self):
        wood = random.randint(1, 10)
        print('chopping wood')
        time.sleep(1.5)
        print('you got', wood)
        self.stockpile.AddWood(wood)
        time.sleep(0.75)
    def mine(self):
        stone = random.randint(1, 10)
        print('mining for stone')
        time.sleep(1.5)
        print('you got', stone)
        self.stockpile.AddStone(stone)
        time.sleep(0.75)

class Stockpile:
    def __init__(self, wood, stone):
        self.wood = wood
        self.stone = stone
        self.SP_wood = 0
        self.SP_stone = 0
        self.Addwood(self.wood)
        self.Addstone(self.stone)
        self.check_wood()
        self.check_stone()
    def Addwood(self, addwood):
        self.addwood = addwood
        self.SP_wood += self.addwood
    def Addstone(self, addstone):
        self.addstone = addstone
        self.SP_stone += self.addstone
    def check_wood(self):
        print(self.SP_wood)
    def check_stone(self):
        print(self.SP_stone)

player_stockpile = Stockpile(0,0)
while idle:
    taskchance = random.randint(0, 100)
    if taskchance < 50:
        tasknum = random.randint(0, 2)
        #be sure to pass in the player stockpile
        job = Taskassigner(tasknum,player_stockpile)
        job.choosejob()

    else:
        print('idle')
        time.sleep(0.5)

      

0


source







All Articles