3

I've started coding an idle game but I will put some type of input in later.

My problem is that my class stockpiles doesn't add int's from def chop/mine to my variable "SP_wood/SP_stone", it's just replacing the variable with the number it got from def chop/mine. I've tried to give the int straight to def addwood/addstone but that didn't work for me. The += should work and add the two together. Should i make the variable outside the class and make 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)
5
  • this is very nice code for a 14 y/o keep it up :) Commented May 14, 2015 at 18:58
  • 1
    Welcome to SO and Coding! I did a bit of cleanup on the question, make sure I didn't edit out anything important. Commented May 14, 2015 at 19:00
  • 1
    thank you. Im sorry if i went against the rules a bit, i should of read them first. (if there is any) Commented May 14, 2015 at 19:04
  • 1
    Also, the question can be more description maybe something like "How to access and increment variables inside a python class". Commented May 14, 2015 at 19:05
  • note that random.randint includes both endpoints, so what you presumably think is a coinflip is actually weighted towards "No". len(range(0, 50)) < len(range(50, 101)) Commented May 14, 2015 at 19:29

2 Answers 2

3

I'd change a few things, mostly because you're making this harder than it needs to be. It doesn't look like your TaskAssigner really needs to hold state, so let's refactor it a bit to basically be a function factory. Then let's change those functions so they'll work on our newly refactored Stockpile class. Great job encapsulating, 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's not really clear what SP_wood and SP_stone do
        # so I'm not sure if you actually need them!

Since taskassigner is now a function factory instead of a class, our calling signature looks a little different, too.

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's 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)

This all being said, it seems like you should be using 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]
Sign up to request clarification or add additional context in comments.

5 Comments

lol apparently i really need to go eat something ... my brain is shutting down :P
it says no module named tasks. what axactl do i do im confused could you plz help?
the comment lines at the top of each of those bottom snippets are filenames. If you have some root directory .../ you should have .../main.py importing tasks, which is .../tasks.py
could you please put it all into one big paragraph for me plz? i dont undertand it
thank you very much. i like what you did with my idea.
0

you need to keep your stockpile separate (but you should probably pass it around rather than make it global)

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)

3 Comments

Could you plz tell me what you did there? i knida don't understand. sorry
the player stockpile is initialized before the loop ... then passed into the taskassigner... and instead of creating a new stockpile each time you simply AddWood or Stone to the existing stockpile
do i still need the stockpile class then? if so what for?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.