2018-11-19 21:25:25 (edited by Dakonna 2018-11-19 21:28:46)

hi, so while I was working my way through learn python the hard way, I was struck with inspiration to try and write a little script just to see what I could do. But I ended up using a huge amount of if statements, some of which check for up to four conditions before exicuting as they should. Is there any way to do this following piece of code more efficiently? I couldn't find anything, so wonder if you have any opinions.
def best_function():
    gold=0
    production=0
    spearmen=0
    print "there are enemy warriors closing in! You have %d gold, %d production and %d spearmen with you." %(gold, production, spearmen)
    print "You are given the choice of work grassland tile, build monument, found new city, or recruit spearman."
    print "Founding the city will cost you 50 gold and 6 production. Recruiting a spearman will cost you 25 and 1 production, while the monument will cost you a further 25 and 4 production. The grassland tile will give you 10 gold every time it is worked, as well as 2 production."
    print "You can also fight. But just one spearman won't cut it!"
    built_monument=False
    built_city=False
    while True:
        choice=raw_input("What will you do? ")
        if choice=="work grassland tile":
            print "You soon reap the benefits of your hard work."
            production+=2
            gold+=20
            print "You now have %d gold and %d production." %(gold, production)
        elif choice=="found new city" and gold >=50 and production >=6:
            print "Your glorious city is founded and ready to help you conquer the world!"
            built_city=True
            gold-=50
            production-=6
            print "You now have %d gold and %d production." %(gold, production)
        elif choice =="build monument" and not built_city:
            print "You can't do that yet, because you need a city to coordinate the building operations!"
        elif choice=="build monument" and built_city and gold >=25 and production >=4:
            print "Your shiny new monument stands prowd, honouring your warriors and boosting their morale. Get enough spearmen to take the fight to the enemy!"
            built_monument=True
            gold-=25
            production-=2
            print "You now have %d gold and %d production." %(gold, production)
        elif choice=="build monument" and built_city and gold <=25 or production <=2:
            print "You do not have enough resources to perform this action!"
        elif choice=="recruit spearman" and not built_city:
            print "You can't do that yet, because you need a home base for your spearmen to stay at!"
        elif choice=="recruit spearman" and built_city and not built_monument and gold >=25 and production >=1:
            print "You are able to find an able boddied man to carry the spear, but he is easily demoralized and dies within a week of service. Thus, your resources have been wasted. Find a way to boost morale!"
            gold-=25
            production-=1
            print "You now have %d gold and %d production." %(gold, production)
        elif choice=="recruit spearman" and built_city and gold <=25 or production <=1:
            print "You do not have enough resources to propperly equip your spearman!"
        elif choice=="recruit spearman" and built_city and built_monument and gold >=25 and production >=1:
            print "Your loyal spearman is trained and ready for battle!"
            spearmen+=1
            gold-=25
            production-=1
            print "You now have %d gold, %d production and %d spearmen." %(gold, production, spearmen)
        elif choice=="fight" and spearmen <5:
            dead("Your pittyful force is easily slaughtered by the greedy hordes. Your lands are pillaged, your homes destroyed, your men sold as slaves, your women raped, your... I think you get the idea.")
        elif choice=="fight" and spearmen >=5:
            print "Your mighty army of unshakeable warriors easily slaughters the enemie's pittyful force! Their lands are pillaged, their homes destroyed, their men sold as slaves, their women raped, their... I think you get the idea. Did you really think your nation would treat the other nation differently just because you're in control? Wrong! Still, congradulations."
            exit(0)
        elif choice=="found new city" and gold <50 or production <6:
            dead("Your glorious city falls short and cannot protect itself against the barbarian hordes.")
else:
            dead("You dodder around until the warriors find you and tare you to pieces.")
def dead(why):
    print why, "Good job!"
    exit(0)

I used to be a knee like you, then I took an adventurer in the arrow.

2018-11-20 00:24:28

"Is there any way to do this more efficiently?"
Not really...

But what i Think you're. actually asking "Can this code be cleaner. e.g. can I make this code easier to read and
process."
That is a yes.

first, Functions should try and only do one thing. make a separate function for getting user input. This isn't quite so much of an issue in languages like python where all you need is one line, but its nice just to call getInput() when you need it.
while i'm on getting and matching input, The only thing I could say about efficiency is comparing single byte chars will be more efficient than comparing multi-byte strings. Plus, It makes for a much better user experience to only have to type one letter as compared to a whole sentence. This really isn't that much of a performance issue though with our computers with several gb of ram.
My second point is more of an advanced topic. So i'm sorry if it goes over your head right now, but you could come back to this post later and get it at a later date when you have learned more. also, someone else may learn from it too. To simplify the conditionals, I would first abstract the player data (gold, spearmen, etc) into its own class. Then Have a class or set of functions that holds the state of the game and can verify that what the player just tried to do is a valid move.

def best_function(player, state):
    #player is the player class we are passing into the function
    #state is the gamestate object

    running = True

    displayMainScrene() #remember functions do one thing

    while (running);
        input = getinput()

        if (input == 'a' and stateActionA(player)):
            state.doActionA(player)
        elif (input == 'b' and state.actionB(player)):
            state.doActionB(player)
        # excetra
        else:
            running = False
#end best_funct

A few last things...
not sure if The else part of the function is indented wrong because of the way it got put onto the forum or if it is just a typo. but that shouldn't run.

lastly a few style and readability notes. I saw you called sys.exit(0) in two places. As a general rule, You should have one entry to a function and one exit. You can think of your program as just a giant function run by the python interpreter. this makes for easier debugging as the size of your program grows. Also, declare all of  your variables at the top of your functions.

I'm not trying to be mean. Just trying to improve your programming skills. You do have a great start hear. keep up the good work.

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2018-11-20 00:48:21

Hi,

well, those ifs can be simplified and arranged much cleaner by using a callback system.
You for example arrange a dictionary which contains the key input by the player (a, b, c, whatever) and a function handle as value (just an example). Whenever the player enters something, you can easily check if the dictionary contains a key with that exact same text. If yes, call this function (with a given set of parameters which are equal for each of those functions, see blackbox concept), and if no, print some error screen and continue running your while loop.
Best Regards.
Hijacker

2018-11-20 21:58:11

hi, thanks for your help yall! I'm just starting to try and wrap my head around objects, modules, and classes. It's some of the hardest to understand things I've seen so far but I'll be damned if I stop now lol.

I used to be a knee like you, then I took an adventurer in the arrow.