Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Lesson 12 Updated: Added challenge
#1
A challenge has been added to Lesson 12: Add sound effects to the slot machine created in Lesson 10.

The tutorial asset file has been updated to include the Lesson 12 challenge solution and sound files.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#2
(06-11-2024, 06:44 PM)TerryRitchie Wrote: A challenge has been added to Lesson 12: Add sound effects to the slot machine created in Lesson 10.

The tutorial asset file has been updated to include the Lesson 12 challenge solution and sound files.
Thanks a lot Terry! I'm taking some time to reread and get a better understanding of what I've done so far (first 10 Lessons), before moving on with the new material. I've played a lot with your PONG game lately ... I'm doing some progress and I hope sooner or later to win a match Big Grin

Doing some of the exercises last week and rereading Lesson 6 on FUNCTIONs and SUBs I found some difficulty in understanding how differently functions and subroutines are called (syntactically) in QB64: the difference depends on the fact that functions return a value and subroutines don't, they do some stuff but they have no value to return, but that means also that they are invoked differently in the source code: 
provided one has defined a subroutine DrawCircle (center, radius) that sub is invoked by writing

DrawCircle center, radius

but if one has defined a function AreaCircle (radius) that function is invoked typically by writing

Area! = AreaCircle (radius)

that is a function call usually appears on the right hand side of an assignment operation in which the value returned is assigned to a variable, where subs don't do this. Is it correct? I'll let you know about my progress (or regress) Smile

PS: of course only the radius is needed to calculate the area. The center only to draw a circle on screen
Reply
#3
(06-13-2024, 08:55 AM)marbac74 Wrote:
(06-11-2024, 06:44 PM)TerryRitchie Wrote: A challenge has been added to Lesson 12: Add sound effects to the slot machine created in Lesson 10.

The tutorial asset file has been updated to include the Lesson 12 challenge solution and sound files.
Thanks a lot Terry! I'm taking some time to reread and get a better understanding of what I've done so far (first 10 Lessons), before moving on with the new material. I've played a lot with your PONG game lately ... I'm doing some progress and I hope sooner or later to win a match Big Grin

Doing some of the exercises last week and rereading Lesson 6 on FUNCTIONs and SUBs I found some difficulty in understanding how differently functions and subroutines are called (syntactically) in QB64: the difference depends on the fact that functions return a value and subroutines don't, they do some stuff but they have no value to return, but that means also that they are invoked differently in the source code: 
provided one has defined a subroutine DrawCircle (center, radius) that sub is invoked by writing

DrawCircle center, radius

but if one has defined a function AreaCircle (center, radius) that function is invoked typically by writing

Area! = AreaCircle (center, radius)

that is a function call usually appears on the right hand side of an assignment operation in which the value returned is assigned to a variable, where subs don't do this. Is it correct? I'll let you know about my progress (or regress) Smile
That's correct. A function allows a return value through the function's name:

FUNCTION AddTwoIntegers&(Value1%, Value2%)

    AddTwoIntegers& = Value1% + Value2%

END FUNCTION


The above function accepts two parameters, Value1% and Value2%, adds them together, and then passes the sum back through the function's name:

Sum& = AddTwoIntegers(10, 20)
PRINT Sum& '                                the value of 30 is printed to the screen


A subroutine can also accept parameters but can't pass any values back through the subroutine's name:

DIM SHARED Sum& ' make this variable global so it can be seen everywhere

SUB AddTwoIntegers(Value1%, Value2%)

    Sum& = Value1% + Value2%

END SUB


This subroutine performs the same task, adding Value1% and Value2%, and then saving the sum in the shared variable Sum&:

AddTwoIntegers 10, 20
PRINT Sum& '                  the value of 30 is printed to the screen


It's also possible to pass values back through the parameter list of both subroutines and functions:

DIM Sum& ' variable is local to the main program only

SUB AddTwoIntegers(Value1%, Value2%, Sum&)

    Sum& = Value1% + Value2%

END SUB

In this subroutine a third parameter is passed, Sum&, that gets modified by the subroutine by placing the sum of Value1% + Value2% into it:

AddTwoIntegers 10, 20, Sum&
PRINT Sum& '                            the value of 30 is printed to the screen


It's important to remember that the parameters in both subroutines and functions can be modified in this fashion. It's very easy to inadvertently change a parameter's value by mistake causing bugs in your code. For example:

DIM Integer1% ' local variable
DIM Integer2% ' local variable

DIM Sum& ' local variable

Integer1% = 10
Integer2% = 20

AddTwoIntegers Integer1%, Integer2%, Sum&

PRINT Integer1% ' 10 is printed to the screen
PRINT Integer2% ' 10 is printed to the screen (it changed!)
PRINT Sum& ' 20 is printed to the screen


SUB AddTwoIntegers(Value1%, Value2%, Sum&)

    IF Value1% > 10 THEN Value1% = 10
    IF Value2% > 10 THEN Value2% = 10
    Sum& = Value1% + Value2%

END SUB


This subroutine will change the the values passed in if they are greater than 10. Value2%, as seen by the subroutine, contains the value of 20, so it will be changed to the value of 10. That change is passed back to the parameter Value2%, which in turn is passed back to Integer2% that was used in the calling parameter list. This change to Integer2% may have unforeseen consequences to your program. If parameters passed in need to be modified you should always do this:

DIM Integer1% ' local variable
DIM Integer2% ' local variable

DIM Sum& ' local variable

Integer1% = 10
Integer2% = 20

AddTwoIntegers Integer1%, Integer2%, Sum&

PRINT Integer1% ' 10 is printed to the screen
PRINT Integer2% ' 20 is printed to the screen
PRINT Sum& ' 20 is printed to the screen


SUB AddTwoIntegers(Value1%, Value2%, Sum&)

    DIM v1% ' the value of Value1% passed in, local to this subroutine only
    DIM v2% ' the value of Value2% passed in, local to this subroutine only


    v1% = Value1%
    v2% = Value2%

    IF v1% > 10 THEN v1% = 10
    IF v2% > 10 THEN v2% = 10   
    Sum& = v1% + v2%

END SUB


Here we created two local variables inside the subroutine, v1% and v2%, that will have the values in Value1% and Value2% transferred to them. Now there is no chance of accidentally changing the values contained in Value1% or Value2% and passing those changes back to the main program code.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#4
(06-13-2024, 04:22 PM)TerryRitchie Wrote:
(06-13-2024, 08:55 AM)marbac74 Wrote:
(06-11-2024, 06:44 PM)TerryRitchie Wrote: A challenge has been added to Lesson 12: Add sound effects to the slot machine created in Lesson 10.

The tutorial asset file has been updated to include the Lesson 12 challenge solution and sound files.
Thanks a lot Terry! I'm taking some time to reread and get a better understanding of what I've done so far (first 10 Lessons), before moving on with the new material. I've played a lot with your PONG game lately ... I'm doing some progress and I hope sooner or later to win a match Big Grin

Doing some of the exercises last week and rereading Lesson 6 on FUNCTIONs and SUBs I found some difficulty in understanding how differently functions and subroutines are called (syntactically) in QB64: the difference depends on the fact that functions return a value and subroutines don't, they do some stuff but they have no value to return, but that means also that they are invoked differently in the source code: 
provided one has defined a subroutine DrawCircle (center, radius) that sub is invoked by writing

DrawCircle center, radius

but if one has defined a function AreaCircle (center, radius) that function is invoked typically by writing

Area! = AreaCircle (center, radius)

that is a function call usually appears on the right hand side of an assignment operation in which the value returned is assigned to a variable, where subs don't do this. Is it correct? I'll let you know about my progress (or regress) Smile
That's correct. A function allows a return value through the function's name:

FUNCTION AddTwoIntegers&(Value1%, Value2%)

    AddTwoIntegers& = Value1% + Value2%

END FUNCTION


The above function accepts two parameters, Value1% and Value2%, adds them together, and then passes the sum back through the function's name:

Sum& = AddTwoIntegers(10, 20)
PRINT Sum& '                                the value of 30 is printed to the screen


A subroutine can also accept parameters but can't pass any values back through the subroutine's name:

DIM SHARED Sum& ' make this variable global so it can be seen everywhere

SUB AddTwoIntegers(Value1%, Value2%)

    Sum& = Value1% + Value2%

END SUB


This subroutine performs the same task, adding Value1% and Value2%, and then saving the sum in the shared variable Sum&:

AddTwoIntegers 10, 20
PRINT Sum& '                  the value of 30 is printed to the screen


It's also possible to pass values back through the parameter list of both subroutines and functions:

DIM Sum& ' variable is local to the main program only

SUB AddTwoIntegers(Value1%, Value2%, Sum&)

    Sum& = Value1% + Value2%

END SUB

In this subroutine a third parameter is passed, Sum&, that gets modified by the subroutine by placing the sum of Value1% + Value2% into it:

AddTwoIntegers 10, 20, Sum&
PRINT Sum& '                            the value of 30 is printed to the screen


It's important to remember that the parameters in both subroutines and functions can be modified in this fashion. It's very easy to inadvertently change a parameter's value by mistake causing bugs in your code. For example:

DIM Integer1% ' local variable
DIM Integer2% ' local variable

DIM Sum& ' local variable

Integer1% = 10
Integer2% = 20

AddTwoIntegers Integer1%, Integer2%, Sum&

PRINT Integer1% ' 10 is printed to the screen
PRINT Integer2% ' 10 is printed to the screen (it changed!)
PRINT Sum& ' 20 is printed to the screen


SUB AddTwoIntegers(Value1%, Value2%, Sum&)

    IF Value1% > 10 THEN Value1% = 10
    IF Value2% > 10 THEN Value2% = 10
    Sum& = Value1% + Value2%

END SUB


This subroutine will change the the values passed in if they are greater than 10. Value2%, as seen by the subroutine, contains the value of 20, so it will be changed to the value of 10. That change is passed back to the parameter Value2%, which in turn is passed back to Integer2% that was used in the calling parameter list. This change to Integer2% may have unforeseen consequences to your program. If parameters passed in need to be modified you should always do this:

DIM Integer1% ' local variable
DIM Integer2% ' local variable

DIM Sum& ' local variable

Integer1% = 10
Integer2% = 20

AddTwoIntegers Integer1%, Integer2%, Sum&

PRINT Integer1% ' 10 is printed to the screen
PRINT Integer2% ' 20 is printed to the screen
PRINT Sum& ' 20 is printed to the screen


SUB AddTwoIntegers(Value1%, Value2%, Sum&)

    DIM v1% ' the value of Value1% passed in, local to this subroutine only
    DIM v2% ' the value of Value2% passed in, local to this subroutine only


    v1% = Value1%
    v2% = Value2%

    IF v1% > 10 THEN v1% = 10
    IF v2% > 10 THEN v2% = 10   
    Sum& = v1% + v2%

END SUB


Here we created two local variables inside the subroutine, v1% and v2%, that will have the values in Value1% and Value2% transferred to them. Now there is no chance of accidentally changing the values contained in Value1% or Value2% and passing those changes back to the main program code.
Ok, thanks, so actually things are not so black or white as I thought...I think I have to read this post with a little bit more attention. But not now Smile thanks
Reply
#5
A quick way to differentiate between Functions and Subs is to remember that Functions *return something*, while Subs *do something*.

Let me give you a few quick examples of SUBS and FUNCTIONS that you use all the time:

SUBFUNCTION
CLSSIN
PRINTABS
PSETINT
ENDSQR
WIDTHWIDTH

Now, look at the table above and take a moment to think of those commands and what they do for us.

CLS -- this clears the screen for us.   (does something)
PRINT --- this prints to the screen.   (does something)
PSET -- this sets a point a particular color for us.  (does something)
END -- this ends our program.  (does something)

See how all those SUB routines *do* something?  

Now, compare to the FUNCTIONS:

SIN(x) --- this returns the sine of x to use.   (return something)
ABS(x) -- this returns the absolute value of x.   (return something)
INT(x) -- this rounds down the value of x and returns it to us.  (return something)
SQR(x) -- this returns the square root of x to us.  (return something)

The SUBS *do* something; the FUNCTIONS *return* the value of something to us.

Another simple way to tell the difference between the two is SUBS are standalone, while FUNCTIONS arent'.   Write a line of code and you'll quickly see what I mean.

Code: (Select All)
CLS
What does the above line of code do?   It clears the screen, of course!

Code: (Select All)
SIN(2*_PI)
Now, what does the above line of code do?   

It's the exact same as asking, what this line of code does...
Code: (Select All)
2

By itself, it does nothing. (Except toss an error for us, for doing nothing.)

That SUB can standalone and *do* something.  A FUNCTION only works in places where it can *return* a value to something else.

x = SIN(_PI)
y = ABS(-2)
z = INT(3.14)
PRINT SQR(9)



And with that said, you may have noticed that the last entries in my table above are the same command.  

WHAT??!!

HOW?!!

Think of what I've just told you, and see if you can see the difference in those two uses of WIDTH.

WIDTH, by itself, is a SUB which sets the width of the screen.     

Code: (Select All)
WIDTH 80

WIDTH, as a return command, is a FUNCTION which tells us the width of the screen.

Code: (Select All)
x = WIDTH

How we use the command, tells us if were using the SUB or the FUNCTION version of it.

WIDTH x     <-- this is the SUB, which sets the screen to x characters wide
x = WIDTH    <--- this is the  FUNCTION, which returns to us the width of the screen.



And that's the differences between SUB and FUNCTION, in a nutshell.  Wink
Reply




Users browsing this thread: 4 Guest(s)