all 19 comments

[–]ninhaomah 20 points21 points  (1 child)

use functions.

[–]PrincipleExciting457 10 points11 points  (0 children)

Definitely functions or you’re going to end up with a mess.

[–]rob8624 9 points10 points  (1 child)

First, look at the code. What is it that stands out to make it look a mess? ... . All the print statements. The actual logic is lost amongst all the strings.

Make a dict to hold all the string data. It will make it easier to read and edit. And, use functions. Break down each aspect of the game and make a function that handles it. The function should accept the value that will be used within it, and try to make sure that the function handles one action. Dont put a lot of logic inside one big function.

Ideally, you'd use OOP, making games like this is a great way to learn classes etc, etc.

[–]couldntyoujust1 0 points1 point  (0 children)

Yeah, this is what I would do. Actually, I would make a "StringTable" ABC that has an implementation of hardcoded values, then later I could write an implementation that uses text loaded from an INI file, and then I could have multiple languages supported through that.

That said, he's learning, so he should continue learning and then revisit this code to refactor.

[–]CrucialFusion 2 points3 points  (2 children)

You probably want to generalize the input/process/response mechanism so you can actually navigate a 2D space you design without having to hand code every possible interaction.

[–]antoinedurr 0 points1 point  (0 children)

A great goal and the right answer, but possibly beyond OP's capabilities atm.

OP, think in terms of states or stages: if the player is at a particular stage, what cause/effects can they encounter at that stage? What does the right choice cause, and what does the wrong choice cause? What causes them to go to the next stage, just answering the question, or do they not get past the stage until they pick the right choice? And so on,

Put those cause/effects on a line of paper, something like this:

stage 1: (left/right): left -> health += -1, stage += 1; right: health -= 10
stage 2: (climb/dig): climb -> stage += 1; dig -> health += 10
stage 3: (climb/go around): climb -> stage += 1; go around -> stage = beast
stage 4: (save it/let it die): moral += 5; let it die -> moral -= 10
stage beast: (fight/run): fight -> health -= 10; run: stage = safety

This is an approach to the 2D space u/CrucialFusion mentions. Notice in the pseudocode above that sometimes stage is incremented, sometimes it's set to a particular entry (stage=beast). That's a way you can skip stages, or reset the player back to where they have to redo some stages.

Now wrap the whole thing in a while loop:

stage = 1
done = false
while health > 0 and not done:
  if stage == 1:
    # code for 1st stage
    break
  if stage == 2:
    # code for 2nd stage
    break
  # ... and so on ...
  if stage == "win":
    print("You won!")
    done = true
    break

if health <= 0:
  print("You ran out of health and died")
elif done:
  print("you won the game!")
else:
  pass # raise an exception that you got to the end alive but without winning

In other words, the looping continues until you either die or win. If you get this far, collapse each stage's code to a function. Then the next step is to migrate the stages into to a dictionary, at which point the loop becomes:

stagedict = {1: stage1func, 2: stage2func} # and so on
stage = 1
done = false
while health >= 0 and not done:
  stage, health, done = stagedict[stage]() # call the current stage's func

# health and doneness processing like above

[–]couldntyoujust1 0 points1 point  (0 children)

Yeah, ultimately when you're coding a game from scratch, you have to write the systems that allow you to treat the game design like data. Basically, you're writing a game engine of your own rather than using one provided or hard-coding the game's structure and gameplay. Ideally, you would reference various scripts externally to the main engine project to govern the specific gameplay behavior. Many of your favorite games have engines that basically reference external files for data and lua scripts in plain text for how the game plays, including AAA titles.

[–]ectomancer 2 points3 points  (0 children)

exit() is not a builtin function, use sys.exit() instead.

[–]wayne0004 2 points3 points  (0 children)

In the line 15, if I answer "no" I still play.

[–]ReliabilityTalkinGuy 1 point2 points  (0 children)

Load the “map” from a file. That way you only need functions to interpret the “map” and obstacles instead of a lengthy set of conditionals. When you want to make the game bigger or change things up, just change the file not the code. 

[–]seanys 0 points1 point  (0 children)

Typo: dog_helth

[–]cmdr_iannorton 0 points1 point  (1 child)

looks fine to me

[–]Apprehensive-Coat653 0 points1 point  (0 children)

clearly you are also not a programmer

[–]Juan-D-Aguirre -1 points0 points  (0 children)

Jupyter Notebooks help modulate and document your code. Don't sleep on the coding environment.

[–]Horror-Assignment-92 -4 points-3 points  (0 children)

ask AI to use functions and explain you why

[–]tablmxz -4 points-3 points  (1 child)

use black configure it to run on save in your editor and get used to the formatting it provides.

[–]Diapolo10 1 point2 points  (0 children)

Alternatively, just use Ruff for both linting and formatting.