# Return values help needed.

#### Podge

##### Member
Hello all,

I have another stupid problem that I can't get past.
Then code below is a simplified version of what I'm tring to do.

In the first working working method I am sending the direction the robot is facing and it is getting sucessfully turned 90 degrees to the left.

I don't know how to get the 2nd bit of code working. I'm getting confused with return values I think.

In the second piece of code I simply want to send the robots x, y co-ords and direction it's facing. I then want to get the return value of x+1/x-1 or y+1/y-1 depending on the facing direction.

Code:
``````'------This works the direction is being correctly changed
Method Left:Void()
Local direction:Int = AI_left(x, y, direction)
End Method

Method AI_left:Int(x:Int, y:Int, direction:Int)
Select direction
Case UP
direction = LEFT
Case DOWN
direction = RIGHT
Case LEFT
direction = DOWN
Case RIGHT
direction = UP
End Select
Return 0
End Method

'------I can't figure this bit out
Method forward:Void()
Local a:Int = AI_forward(x, y, direction)
End Method

Method AI_forward:Int(x:Int, y:Int, direction:Int)
Select direction
Case UP
y = y - 1
Case DOWN
y = y + 1
Case LEFT
x = x - 1
Case RIGHT
x = x + 1
End Select
Return 0
End Method``````

Last edited by a moderator:

#### MikeHart

If the first version works, then only by accident. As both methods only return 0. Nothing else.
You return values via the Return statement or with objects that are give as parameters of a function/method and then changed.

#### Podge

##### Member
If the first version works, then only by accident. As both methods only return 0. Nothing else.
You return values via the Return statement or with objects that are give as parameters of a function/method and then changed.
I think the 1st example works because, 'direction' is a global var and it it changed, so there is no need to return anything.
What I am trying to figure out is how to return two values. Like the second method. I pass x, y and direction and I want an updated return value for the new x,y co-ords.

#### Podge

##### Member
How should the 1st example look if done properly? And do you see what I am trying to do with the second method?

#### MikeHart

Ok, another good example where the question leads then one who tries to answer into the wrong direction as only a portion of a code is shown. Please post a running example next time.

I think the 1st example works because, 'direction' is a global var and it it changed, so there is no need to return anything.

But then the Parameters of AI_left:Int(x:Int, y:Int, direction:Int) make no sense, as you give direction as a parameter and inside the fucntion, this LOCAL parameter called direction is used and not your global var.

I tested it with this code and it prints 1, just like I thought.

Cerberus:
``````Strict
Global direction:Int=1
Global y:Int=-1
Global x:Int=-1

Enumerate LEFT=1, RIGHT, DOWN, UP

Function Main:Int()

Left()
Print direction
Return 0
End

'------This works the direction is being correctly changed
Function Left:Void()
Local direction:Int = AI_left(x, y, direction)
End

Function AI_left:Int(x:Int, y:Int, direction:Int)
Select direction
Case UP
direction = LEFT
Case DOWN
direction = RIGHT
Case LEFT
direction = DOWN
Case RIGHT
direction = UP
End Select
Return 0
End

'------I can't figure this bit out
Function forward:Void()
Local a:Int = AI_forward(x, y, direction)
End

Function AI_forward:Int(x:Int, y:Int, direction:Int)
Select direction
Case UP
y = y - 1
Case DOWN
y = y + 1
Case LEFT
x = x - 1
Case RIGHT
x = x + 1
End Select
Return 0
End``````

I would do it this way, but that also depends on how you really store the values and so on:

Cerberus:
``````Strict
Enumerate LEFT=1, RIGHT, DOWN, UP
Global direction:Int=LEFT
Global y:Int= 1
Global x:Int=-1

Function Main:Int()

Print ("Direction= "+direction)
Left()
Print ("Direction= "+direction)
Left()
Print ("Direction= "+direction)

Print ("x="+x+"  y="+y)
forward()
Print ("x="+x+"  y="+y)
forward()
Print ("x="+x+"  y="+y)
Return 0
End

'------This works the direction is being correctly changed
Function Left:Void()
AI_left()
End

Function AI_left:Int()
Select direction
Case UP
direction = LEFT
Case DOWN
direction = RIGHT
Case LEFT
direction = DOWN
Case RIGHT
direction = UP
End Select
Return 0
End

'------I can't figure this bit out
Function forward:Void()
Local xy:Int[] = AI_forward(x , y)
x = xy
y = xy
End

Function AI_forward:Int[](xp:Int, yp:Int)
Local retXY:Int
Select direction
Case UP
retXY = y - 1
Case DOWN
retXY = y + 1
Case LEFT
retXY = x - 1
Case RIGHT
retXY = x + 1
End Select
Return retXY
End``````

#### dawlane

##### Well-known member
CX Code Contributor
@Podge
You've mentioned that you have a global variable defined called direction.
It's not a good idea to use the same variable name for a class field, global or local variable or a function parameter.
It's confusing and prone to causing errors.

Let's try to explain return values with what's going on with just this bit of code you have supplied.
Cerberus:
``````Method Left:Void()
Local direction:Int = AI_left(x, y, direction)
End Method``````
This bit of code is passing the variable direction to the method AI_left and expecting a value back in return. As the method being called is not returning anything other than zero. It's pretty much pointless. If the variable direction is field in the class, then using it as a parameter is pointless as you can access it anywhere from inside the class; unless you want to make a change, but not affect the original in any way. See about the next method.

NOTE: If there is a field in the class with the same name and letter case as a global, then it would be passing the value in the field instead.
The only two ways I know of to get round this, is to use unique variable names, or wrap the global variables inside a class and access them via the scope operator. e.g.
Code:
``````Class Globals
Global direction:Int=1
End Class

Function Main:Int()
Print Globals.direction
Return 0
End``````

Now for this method
Code:
``````Method AI_left:Int(x:Int, y:Int, direction:Int)
Select direction
Case UP
direction = LEFT
Case DOWN
direction = RIGHT
Case LEFT
direction = DOWN
Case RIGHT
direction = UP
End Select
Return 0
End Method``````

This is always going to return a value of 0. The parameter direction will be treated as a local variable and have absolutely no affect out side the AI_left method. This is down to only a copy being made of the value passed as the parameter and not the memory location of the variable, so it will not affect the original variable. With class objects, only the reference (aka it's address in memory) is being copied, so any change to that object affects that object directly.

To fix the method, the parameter direction needs to be returned.
Code:
``````Method AI_left:Int(x:Int, y:Int, direction:Int)
Select direction
Case UP
direction = LEFT
Case DOWN
direction = RIGHT
Case LEFT
direction = DOWN
Case RIGHT
direction = UP
End Select
Return direction
End Method``````
Now you'll get the updated value back where you can assign it back to what ever variable you want.

NOTE: If there is a class field with the same name as a method parameter or local variable, the compiler will not change that field unless you explicitly let it know that you want this by using something like
Code:
``Self.direction = LEFT``

In the second piece of code I simply want to send the robots x, y co-ords and direction it's facing. I then want to get the return value of x+1/x-1 or y+1/y-1 depending on the facing direction.
Now the problem here depends on how the robots data is defined to start with, if the AI methods are part of the robots own data structure; and how you are going to handle the results.

For a single return value you would still have the problem of figuring out whether the return value is for the X or Y. Not considered the best option with the additional code required.

The first solution, which Mike has posted is to return an array with the two updated values and reassign them back to the X and Y variables.

The second depends on if the robots data is structured in a class and if the AI methods are part of the robots class. If the robot and AI are separate, then the robot should have dedicated public methods to access the X, Y and direction and you would pass the whole object to the AI side where it can read the direction and update the robots X and Y through those dedicated robot methods.

• • Podge, MikeHart and Wingnut

#### Podge

##### Member
Thanks to both of you!
I have a lot to learn. I will spend some time messing around with this until I get it. I really appreciate the help here.