# The Python Game Book

code games. learn Python.

### Site Tools

en:secret:goblins:step008

This is an old revision of the document!

## 008

 ← step008 ↑ →

### more detailed stat values

#### attack, defense and damage

At the current version of `Goblin Dice Duel`, only the `random.randint()` functions explain if a goblin get hit on the head and how much it hurts. Morst Role-Playing-Games use not only the concept of hitpoints but also various combat stats, like values for attack, defense and damage.

The easy part is to introduce the new variables in python:

```hitpointsStinky = 22
attackStinky = 6
defenseStinky = 9
hitpointsGrunty = 43
attackGrunty = 5
defenseGrunty = 3
```

#### comparing stats

Before going wild with some combat mechanics, let me first introduce a function to make a pretty compare table of those combat stats. Actually, a function that calls another function. And a reminder of the `if` `elif` `else` structure as well. And something about local scope of variables. And return values. In short, let's practice a bit the things you learned so far. You best type this whole example in your python editor:

```def sign(a,b):
"""compares a with b and returns a "<","=" or ">" sign"""
if a < b:
return "<"
elif a > b:
return ">"
else:
return "="

def compareValues(hpA, attA, defA, hpB, attB, defB):
"""returns a string with a table comparing the values of A and B"""
text = "\n          Stiny | vs. | Grunty "
text+= "\n ---------------+-----+-----------"
text+= "\n hitpoints: {0:3d} |  {1}  | {2:3d}".format(hpA, sign(hpA, hpB), hpB )
text+= "\n attack:    {0:3d} |  {1}  | {2:3d}".format(attA, sign(attA, attB), attB)
text+= "\n defense:   {0:3d} |  {1}  | {2:3d}".format(defA, sign(defA,defB), defB)
text+= "\n"
return text

hitpointsStinky = 22
attackStinky = 6
defenseStinky = 9
hitpointsGrunty = 43
attackGrunty = 5
defenseGrunty = 3

# python lines can be several physical lines long if inside brackets
print(compareValues(hitpointsStinky, attackStinky, defenseStinky,
hitpointsGrunty, attackGrunty, defenseGrunty))
```

Or you can try it out online (click on the graphic below):

#### output

The output of this program is pretty….pretty:

```          Stiny | vs. | Grunty
---------------+-----+-----------
hitpoints:  22 |  <  |  43
attack:      6 |  >  |   5
defense:     9 |  >  |   3
```

### code discussion

#### sign function

Now make sure you understand all what is happening so far (use the online debugger above). Take a look at the first defined function with the name `sign()`. All what the `sign()` function needs as parameters are two things that python can compare. In our case those things will be integer stat values of Stinky and Grunty, but the `sign()` function could also compare Strings or other objects. The `sign()` function compare the two things passed as arguments and returns either a <key»</key> sign, a <key»</key> sign or an <key>=</key> sign. Note that each return value is of type string because of the quotes. Also note that a function always terminates after running into an `return` statement and python goes back to the point from where the function was called.

This leads to the question: Who calls the `sign()` function ?

Scan the whole code for `sign(` outside the function definition.

Most Editors support the Hot-Key <key>CTRL</key> + <key>f</key> to start a find function. Even your browser does.

Found it ? The `sign()` function is called three times, from inside the `.format()` command in the `compareValues()` function. The whole point of the `compareValues()` function is to make a pretty table to show the player whose stats are better. And instead coding the whole `if`-`elif`-`else` block three times into the `compareValues()` function i prefer to code (the `sign()` function) only once and call it three times.

Note that the caller of the `sign()` function makes good use of the `sign()` functions return value: it is directly used to create the compare table string. Remember: The caller of a function has to make use of return value of a function, or the return value …is of no use.

#### compareValues function

Take a look at the second function, the `compareValue()` funciton. As you can see this function need 6 (!) parameters and all it returns is a single text String. But a pretty one !

If you wonder how to create this vertival line, the “pipe” <key>|</key>: Depending on your keyboard layout, you must press another key to get it (german keyboard layouts need to press <key>ALT GR</key> and <key><</key>. You may have a tool on your Computer named Charmap that helps you identify signs of your keyboard and remap them. In the worst case, use a <key>!</key> instead of the pipe.

As you may have noticed i use no longer the `print()` function but instead i create and return a giant text string. A side effect is that i loose all those line endings that the `print()` function was taking care for me. So i have to code a new line sign, the `\n` everywhere in the code where i want a new line. (I love to do that at the start of each code line so that i can not forget it at the end of the code line). Inside a text string, something beginning with an backslash is often a Control_character or an Escape_sequence.

The reason not to use `print()` instead of the text string lays in the future: I want to make this example work on webpages or in a Graphical_user_interface where `print()` does not work. Textstrings, on the other hand, will work and will be passed as arguments to some ultra-modern “make this visible with many colors” function.

#### calling the funciton(s)

Now to the last part of the previous code example, where the stat variables are defined and where the functions are called. It is here that the code actually begins. A def block of a function will not be computed by python until it is actually called. You must, however, define a function before you can call it, so that python knows where the called function is located.

Please take a look at the parameters of the functions. The `compareValues()` function is called with the parameters `hitpointsStinky`, `attackStinky`, `defenseStinky` etc but in the definition block of the function it takes `hpA`, `attA`, `defA` etc. as parameters. What happens here ?

Remember the local scope of functions. Each function has it's own scope, meaning it can create variables locally that already exist outside the function and use it for complete other purposes and values. The variables outside the function will not be affected or polluted (unless global variables. But i don't use them anyway). The only way of the world outside of a function to “communicate” with the function is to pass parameters while calling the function and (maybe) getting return values form the function. In-between, there is no interaction of the outside world with the function.

That means that the function does not need to care how it's parameters are named outside the function… the function can name the parameters anyhow, preferable so that it is short to type but good to undertand. Therefore, `attA` instead of `attackStinky` etc.

Also take some time to make sure that you understand the Program_flow correctly:

#### program flow

1. the `print()` function calls the `compareValues()` function iwth 6 arguments
2. the function `compareValues()` calls the function `sign()` with the values for both hitpoint stats as arguments and uses the return value
3. the function `compareValues()` calls the function `sign()` with the values for both attack stats as arguments and uses the return value
4. the function `compareValues()` calls the function `sign()` with the values for both defense stats as arguments and uses the return value
5. the return value of the `compareValues()` function (a text string) is directly printed on the screen by the calling `print()` function

A last thing: the last line in the code example (the `print()` function) is so long that it makes scrolling necessary when looking at the source code. Because that is not comfortable, i split the (python) line into 2 (physical) lines. As long as such a split happens inside brackets, python is clever enough to figure out that both (physical) lines are in reality one giant (python) line.

 ← step008 ↑ →