Warning : long post incoming
Code: Select all
define e = Character('Eileen', color="#c8ffc8")
# The game starts here.
label start:
$ drink_points = 0
$ hunger_points = 0
$ social_points = 0
e "You've created a new Ren'Py game."
e "Once you add a story, pictures, and music, you can release it to the world!"
"There was a brief moment of silence as she considered what she should do next."
menu:
"Get a drink.":
$ drink_points += 1
"Eat nachos.":
$ hunger_points += 1
"Call Susie.":
$ social_points += 1
"Do nothing.":
jump next
label next:
e "Now what should I do?"
"She thought about her options again."
menu:
"Get a soda.":
$ drink_points += 1
"Eat fruit.":
$ hunger_points += 1
"Call Jake.":
$ social_points += 1
"Do nothing.":
jump end
So far so good. (The script check did told you so, but it is also almost completely correct on a code design standpoint).
I'll just comment on the fourth menu choice (for both of your menus) : you put a
jump statement when you "Do nothing". Now, I understand why you did it : it is mandatory to put at least one renpy statement after a '
:'-ended statement (here a menu choice).
But it is also bad practice, structurally speaking, to put a jump in one of your choices when not any of the other does, and it is bad practice of semantic design to put a action after the choice "doing nothing".
Yet, fear not! Here is your savior, the
pass statement, which allow you to tell renpy to... well, not do anything. Seems useless, huh ? But pretty useful here. Just tell him to do nothing when the user chose to do just that.
--------------
Code: Select all
python:
points = {
'drink': drink_points,
'hunger': hunger_points,
'social': social_points,
}
Okay, the initialisation of the dictionary is cool.
--------------
Code: Select all
highest_points = max(points.values())
people_with_highest_points = []
for person, person_points in points.iteritems():
if person_points == highest_points:
people_with_highest_points.append(person)
You cut-and-paste.
You cut-and-paste.
You cut-and-paste.
YOU CUT-AND-PASTE. DON'T DO IT.
FOREVER.
Cut-and-paste is the bane of good coding. Cut-and-paste is the enemy of all mankind. Cut-and-paste will come at night and eat your babies!
Seriously, cut-and-paste is evil. As a proof, look at Discord : he's a cut-and-paste monster, and he's evil.
Jokes aside, always try to re-code yourself everything you code, even if you end up re-coding it letter for letter - it has several advantages:
- You're in control of everything in your code - and, reciprocally, you're responsible for everything in your code. You feel a greater responsability to have your code proper and clean, while one is unconciously much more cavalier towards the lines you pilfered from someone else.
- Re-writing a block allows you - in fact, forces you - to think about the sense and meaning of what you're coding.
It is just as if you were spelling out a word, or translating a foreign language sentence.
- It allows you to combine what you have with what you need to produce what you want.
If you go the cut and paste route, you just modify what you have.
- In fact, when you cut paste, you tend to overlook mistakes - or, if you modify part of it, you miss other references to the cut&pasted passage's elements.
Cut-and-paste might seem like it makes you gain time at first, but in the long run it is a net loss of time to fix the eventual mistakes.
Valmoer goes down from his soapbox.
Now, I don't say that you shouldn't have used this block of code - actually, it is a good thing you used it - but remember what I said about the fact that the name of variables was of no importance to the computer, but of vital importance to the coder, so he could understand what he codes, what the variables he uses are used for ? Look, here, you have
- highest_points : it is the maximum value of a collection of points value : it is well-named
- people_with_highest_points : it is a list that is about to store the names (keys, actually) of the points dictionary items that has the highest total points. But what are these dictonary items ? What is their semantical sense ? Their lexical field ? "drink", "hunger", "social" - those aren't people, and thus people_with_highest_points is ill-named. (I'd suggest categories_with_highest_points (or highest_points_categories - it's the same thing, really.)) You can name your variables as you wish, so name them with something meaningful.
- The same reason makes person and person_points ill-named
--------------
Code: Select all
if len(people_with_highest_points) > 1:
$ menuitems = [ ("I'll take a sandwich", "eat"), ("I'll rather have a glass of water", "drink") ]
$ result = renpy.display_menu(menuitems)
if eat: $ hunger_points += 1
elif drink: $ drink_points += 1
jump goodbye
Okay, this is where it's begining to go down the drain.
First things first - why is renpy shouting at you ?
Code: Select all
if eat: $ hunger_points += 1
elif drink: $ drink_points += 1
It is because, in renpy (and in python) one line = one statement. But here, you have two statements for each line:
- the if / elif condition :
- and a python statement, which here of the form $ variable operator value
So, the correct way to format your code - with the right indentation
Code: Select all
if eat:
$ hunger_points += 1
elif drink:
$ drink_points += 1
which doesn't matter, because the code is wrong anyway.
So let's start again your code, just modified to be syntaxically correct:
Code: Select all
if len(people_with_highest_points) > 1:
$ menuitems = [ ("I'll take a sandwich", "eat"), ("I'll rather have a glass of water", "drink") ]
$ result = renpy.display_menu(menuitems)
if eat:
$ hunger_points += 1
elif drink:
$ drink_points += 1
jump goodbye
First, cut-and-paste strike again : for the first three lines, you took the code we three made together, and just let it as is. Now let me ask you : would that code play its intended role if
'social' was one of the tied values ? No, of course not.
See the end of my post for a relevant homework assignation.
Next, we have this:
Code: Select all
if eat:
$ hunger_points += 1
elif drink:
$ drink_points += 1
which is thrice wrong
- You're confusing eat, the variable, and "eat", which is a text string, i.e. a litteral value. While eat might be affected any value (42, 0, "zoo", 3299902.28, "J3rezjkl _9oi", ["blargh", 76, 8.3]... and so on), the litteral will never have any other value than itself : here, the value "eat".
What you were doing here is asking renpy if eat was True. A variable that is True is a variable that isn't False, 0, or an empty list []. That means that any variable that has been initialized to a value different from those would be True. Here, however, as you never initialized eat, it would have crashed as soon as you'd arrived there.
- So what you do want to do here is rather compare the returned value of the renpy.display_menu(...) function to the value you know it might have. It would look like that
Code: Select all
if result == "eat":
$ hunger_points += 1
elif result == "drink":
$ drink_points += 1
- But what you MUST realize is that these preceding four lines are utterly useless. You try to add one point to your category_points, but you don't have to! The tie has already been broken! It has been the moment the user chose a element in the menu. And this choice has been materialised by the result variable. So if you want to know which was the winning category, just "ask" the result variable (we could have called it decision...). This fact, by the way, makes obsolete half of your following code. I will, however, continue to demolish it for educational reasons.
Code: Select all
else:
python:
points = {
'drink': drink_points
'hunger': hunger_points
'social': social_points
}
highest_points = max(points.values())
people_with_highest_points = []
for person, person_points in points.iteritems():
if person_points == highest_points:
people_with_highest_points.append(person)
jump goodbye
Starting from here, things stop making sense.
I kind of guess what you were trying to do - that is, you put modified drink/hunger in the above if and wanted to have anew a list with the item with the maximum values, but
- why the Hell would you put it in the else statement of the if len(people_with_highest_points)>1 statement: remember, that if len(...) > 1, it means there is more than one 'maximum'. Conversely, if you go to the else statement, it meant that len(people_with_highest_points)>1 was false, that is that there was one or less element in people_with_highest_points i.e, that there is no tie. So no putting tiebreaking code in this else statement.
- what you should have put in else : as I said , if you been up to else, it means there is no tie, and that there is only one element in people_with_highest_points. What do we do ? We access it with people_with_highest_points[0] (in a general manner, you access the nth element of a list with listname[n-1]) And, now, look carefully, cause it's a simple yet wicked trick. We'll stock this value in a variable named... result.
Code: Select all
else:
$ result = people_with_highest_points[0]
That means that result will contain the name of the highest value. And this, whatever path was taken (either the if or the else). Wicked, isn't it ? (Do make sure however, that the menu-returned results are the same that the dictionary's keys names, for this to work)
- Regardless of the code's inherent worth, you should never have twice the same code in your program. If you do, you need to define a function. But we'll see that later.
- Again, as with your menu choice, the jump statement was unecessary.
Code: Select all
label goodbye:
if hunger_points > max(drink_points, social_points):
e "Man, I am never eating another bite!"
if drink_points > max(hunger_points, social_points):
e "I sure was thirsty."
if social_points > max(hunger_points, social_points):
e "I love talkting with friends."
What are you doing here ? You're checking which is the maximum? YOU ALREADY HAVE! And, you see, Cut-and-paste is bad (I know it is c&p, I've seen that code wheeze around in a few topics of the forum). You already have your result, so no need to make a calculation
anew.
--------------
Wew. So let's see what your code gives, Valmoer-styled:
Code: Select all
define e = Character('Eileen', color="#c8ffc8")
# The game starts here.
label start:
$ drink_points = 0
$ hunger_points = 0
$ social_points = 0
e "You've created a new Ren'Py game."
e "Once you add a story, pictures, and music, you can release it to the world!"
"There was a brief moment of silence as she considered what she should do next."
menu:
"Get a drink.":
$ drink_points += 1
"Eat nachos.":
$ hunger_points += 1
"Call Susie.":
$ social_points += 1
"Do nothing.":
pass
label next:
e "Now what should I do?"
"She thought about her options again."
menu:
"Get a soda.":
$ drink_points += 1
"Eat fruit.":
$ hunger_points += 1
"Call Jake.":
$ social_points += 1
"Do nothing.":
pass
label end:
python:
points = {
'drink': drink_points,
'hunger': hunger_points,
'social': social_points,
}
highest_points = max(points.values())
highest_points_categories = []
for category, category_points in points.iteritems():
if category_points == highest_points:
highest_points_categories.append(category)
if len(highest_points_categories) > 1:
$ menuitems = # This is your homework
$ result = renpy.display_menu(menuitems)
else:
$ result = people_with_highest_points[0]
label goodbye:
if result == "eat":
e "Man, I am never eating another bite!"
if result == "drink":
e "I sure was thirsty."
if result == "social":
e "I love talkting with friends."
e "I guess that's all, then!"
return
See the
Code: Select all
if len(highest_points_categories) > 1:
$ menuitems = # This is your homework
$ result = renpy.display_menu(menuitems)
Here is your third homework assignation (this one is a bit tricky) : you have a
list,
highest_points_categories, that contains the names of the categories with the highest point total. You don't
know which are the names inside.
Find a way to define correctly the
menuitems variable, so that the when you pass menuitems as parameter to
renpy.display_menu(...) function, a menu with the tied values, and only those - will appear.
Do read carfully the
renpy.display_menu() function definition, so that you know what is the "shape" of the parameters that the function expects.
This function might help you.
Now, don't be disheartened - mistakes are normal, and I can honestly tell you that you are doing well (for an English major
). Again, don't hesitate if you have any question