# Lesson 10: Math Functions

Before you can get into the math functions built into QB64 you must first understand how a computer counts. In order to understand how a computer counts though you must first understand how a human counts. Why do we have 10 numbers in our counting system ranging from 0 to 9? Why do numbers get longer at 10, 100, 100, and so on? Who invented the human counting system?

**It was cave men ... yep ... cave men.** One day Ugh was standing at his cave entrance and saw seven woolly mammoths pass by. Hearing his stomach growl he got the hankerin' for a woolly burger. He quickly ran into the cave to tell his friends Unk and Nog what he had seen. Stomping around acting like a woolly mammoth and pointing to the cave entrance his buddies got the general idea that a woolly mammoth was passing by. They were tired though and figured Ugh could handle a single mammoth by himself. **It was then that Ugh had a brilliant idea.** He envisioned his fingers as individual mammoths! Ugh quickly threw seven fingers into the air, pointed at the cave entrance, and starting stammering about like a mammoth again. Unk thought Ugh might have fleas again and simply ignored him. However Nog saw what Ugh was trying to say, quickly jumped up, motioned Unk to follow and they headed out the cave. The counting system, based on human fingers, 10 of them, emerged! **True story.**

# The Decimal (BASE10 ) Numbering System

The decimal numbering system is based on 10 digits from 0 to 9. This is also known as the **BASE****10**** numbering system** because it's based on 10 individual symbols that represent numbers. In Ugh's time those symbols were fingers however today we use symbols based on Arabic numerals.

BASE10 simply means that any digit to the left of any other digit is worth ten times as much in value. In school you learned these as place holder values with names such as the 1's place, the 10's place, the 100's place, and so on.

**Figure 1: The BASE****10**** numbering system**

Using **Figure 1** as an illustration the decimal number **387,237** can be broken down like this:

**(3 x 10**^{5}**) + (8 x 10**^{4}**) + (7 x 10**^{3}**) + (2 x 10**^{2}**) + (3 x 10**^{1}**) + (7 x 10**^{0}**)****( 300000) + (80000 ) + ( 7000 ) + ( 200 ) + ( 30 ) + ( 7 ) = 387,237**

In other words each place holder is worth 10 times as much as the place holder to the right of it. Numbering systems are based on something that is familiar or readily available. In the case of humans it's our ten fingers and toes that decided it for us. The Roswell aliens use a BASE6 numbering system because of only having three fingers on each hand (The Grays, not the shape-shifting Reptilians). Computers use a BASE2 numbering system called * binary*.

# The Binary (BASE2) Numbering System

Computers at their core are based on the actions of transistors which are simple electronic switches that can be turned on and off. Because of this computers only know two things, **ON** or **OFF**, so a numbering system based on this must be used by them. That numbering system is known as * binary*, or BASE2, which only contains the two digits

**0**and

**1**. The digit

**0**is often referred to as

*and the digit*

**false****1**referred to as

*.*

**true**The * binary* numbering system can be described in exactly the same way as the decimal numbering system with each place holder being based on the number 2 instead of 10. Therefore each place holder is worth 2 times as much as the place holder to the right of it.

**Figure 2: The BASE****2**** numbering system**

The number **183** to a computer in * binary* is represented as

**10110111**and using

**Figure 2**above as an illustration can be broken down like this:

**(****1**** x 2**^{7}**)+(****0**** x 2**^{6}**)+(****1**** x 2**^{5}**)+(****1**** x 2**^{4}**)+(****0**** x 2**^{3}**)+(****1**** x 2**^{2}**)+(****1**** x 2**^{1}**)+(****1**** x 2**^{0}**)****( 128 ) +( 0 )+( 32 )+( 16 )+( 0 )+( 4 )+( 2 )+( 1 ) = 183**

Computers use * binary* numbers to represent the state in which transistors should be placed in. Placing a 1 in video memory for instance tells a transistor to turn on, which in turn lights up a pixel on the monitor. When you create a program it ultimately gets turned into a series of ones and zeros that instruct the millions of transistors to switch on and off. This

*dance is what makes the magic happen on the monitor in front of you.*

**binary**In computing bit lengths are given names to identify how many bits are contained within a binary number.

**Bit - a single 1 or 0Nibble - 4 bitsByte - 8 bits or 2 nibblesWord - 16 bits, 2 bytes, or 4 nibblesDouble Word - 32 bits, 4 bytes, or 8 nibblesQuad Word - 64 bits, 8 bytes, or 16 nibbles**

# Bitwise Math and Boolean Logic

George Boole was a 19th century mathematician that devised a new form of mathematics based on logic and is often considered the founder of the field of computer science. Today we use his insights into logic, called Boolean logic, to describe the interactions between * binary* numbers and electronic states.

*is a perfect fit in computing because it can have only two states,*

**Boolean logic***and*

**true***, and therefore only two outcomes,*

**false***or*

**true***. By equating the two digits of*

**false***to the these states,*

**binary****0**(zero) for

*and*

**false****1**(one) for

*, we can use George Boole's logic to perform what is known as bitwise math.*

**true*** Bitwise math* consists of operations that act on numbers at the bit level. Bitwise operations are often used for storing useful information and manipulating numbers at the bit level through the use of logic gates.

*are used to sample bits, or inputs, and derive a single output in bit form. There are a number of*

**Logic gates***available in QB64 that allow the programmer to manipulate numbers at the bit, or*

**logic gate operators***, level.*

**binary**# The AND Statement

The **AND** statement is a logical numerical operator that compares two values at the bit level. If two corresponding bits are set to **1**, or * true*, the result of the operation becomes

*, anything else will result in*

**true***.*

**false***can be described using*

**Logical operators***. The*

**truth tables***for the*

**truth table****AND**

*is shown in*

**logical operator****Figure 3**below.

**Figure 3: AND truth table**

The only time the **AND** * logical operator* will return a value of

**1**, or

*, is if both inputs being tested are*

**true****1**or

*. The truth table equates to:*

**true****0 AND 0 = 00 AND 1 = 01 AND 0 = 01 AND 1 = 1**

* Logical operators* also work with zero (

*) and non-zero (*

**false***) values. A*

**true***can be used in the following manner:*

**logical operator****IF Number% = 10 AND User$ = "Admin" THEN**

The tests on either side of **AND** will result in either * true* or

*. If both tests result in*

**false***then the*

**true****IF...THEN**statement will proceed.

*also work at the bit level on numeric values. Type the following three lines of code in then execute it.*

**Logical operators****b1% = 255b2% = 64PRINT b1% AND b2%**

The value of **64** should have been printed, but why? Logical operators look at numeric values in * binary*. The decimal number

**255**when converted to binary is

**11111111**. The decimal number

**64**in binary is

**01000000**. The bits in each one of these binary numbers is what

**AND**is actually looking at.

**Figure 4**below shows what this looks like.

**Figure 4: ANDing 255 and 64**

The only column with a 1 in both cells is in the 64's place making the answer to **AND**ing **255** and **64** the binary number of **01000000** or **64** in decimal. Let's **AND** **237** and **212** together to see the result as seen in **Figure 5** below.

**Figure 5: ANDing 237 and 212**

In this example the 128's, 64's, and 4's place columns all contain the value of **1** resulting in the binary number **11000100** or **196** in decimal. Many times in source code you'll come across something like this:

**Variable% = 255IF Variable% AND 64 THEN ' do some code hereEND IF**

We already know that the result of **AND**ing **255** and **64** results in **64**. So basically the **IF...THEN** statement equates to this:

**IF 64 THEN**

and since **64** is non-zero it will be seen as * true* and the block of code will be entered.

**How can code like this be useful?**Well get to that in a bit but first there are a few more logical operators to cover.

# The OR Statement

The **OR** * logical operator* requires two input bits to test as well resulting in the following truth table.

**Figure 6: OR truth table**

The only time the **OR** * logical operator* will return a value

**0**, or

*, is if both inputs being tested are*

**false****0**or

*. The truth table equates to:*

**false****0 OR 0 = 00 OR 1 = 11 OR 0 = 11 OR 1 = 1**

Just like with **AND** the **OR** logical operator can be used for **IF...THEN** testing:

**IF Number% = 10 OR User$ = "Admin" THEN**

If either side of **OR** results in * true* then the entire statement becomes

*.*

**true**Let's **OR** the numbers **237** and **212** together to see the result.

**Figure 7: ORing 237 and 212**

# The XOR Statement

The **XOR**, or e**X**clusive **OR**, * logical operator* requires two input bits to test as well resulting in the following truth table.

**Figure 8: XOR truth table**

The only time the * XOR* logical operator will return a value of

**1**, or

*, is when only one input is*

**true***, not both. The truth table equates to:*

**true****0 XOR 0 = 00 XOR 1 = 11 XOR 0 = 11 XOR 1 = 0**

Just like with **AND** and **OR**, the **XOR** logical operator can be used for **IF...THEN** testing:

**IF Number% = 10 XOR User$ = "Admin" THEN**

If only one side of **XOR** results in * true* the entire statement becomes

*.*

**true**Let's **XOR** the numbers **237** and **212** together to see the result.

**Figure 9: XORing 237 and 212**

# The NOT Statement

The **NOT** * logical operator* takes one input and

*it.*

**inverts****Figure 10: NOT truth table**

Many times **NOT** is used to make a line of code easier to read like so:

**CONST FALSE = 0, TRUE = NOT FALSE**

**PlayerDead% = FALSE ' player is aliveIF NOT PlayerDead% THEN ' is player dead? ' do this code because player is still aliveEND IF**

The **NOT** logical operator in the line above inverts the value of the variable turning what was a * FALSE* into a

*and therefore making the*

**TRUE****IF...THEN**statement

*.*

**true**# BitWise Example: A BitMapped Maze

There are many, many variables and conditions to track when writing computer games; is the player alive or dead, did the player grab the key needed to open this door, can the player move in a certain direction, etc. Many of these conditions can be set as * true* or

**false***. Instead of creating a separate variable for each condition the information can be stored in the individual bits of a single variable. This was a highly preferred method of storing information back in the early days when home computers had 4KB to 64KB of RAM. There simply was not enough room to store hundreds of individual variables and their values.*

**flags**A map can easily be created using * bitwise operations* to indicate which walls are closed and which are open to move through. Each cell of the map is given the following attributes:

**Figure 11: Setting up a map using 4-bit binary numbers**

By adding each binary placeholder with a corresponding wall a number can be created that indicates which walls are turned on. For example, the top left square contains the value of **11** because the North wall has a value of **1** (2^0), the East wall has a value of **2** (2^1) and the West wall has a value of **8** (2^3) that when added together equals **11**. * Bitwise operations* can now be used to test for the existence of a wall in any given cell.

**CONST NORTH = 1 ' (2^0)CONST EAST = 2 ' (2^1)CONST SOUTH = 4 ' (2^2)CONST WEST = 8 ' (2^3)**

**CellWalls% = 11 ' the walls in the current room**

**IF CellWalls% AND NORTH THEN PRINT "North wall is present" ' test the first bitIF CellWalls% AND EAST THEN PRINT "East wall is present" ' test the second bitIF CellWalls% AND SOUTH THEN PRINT "South wall is present" ' test the third bitIF CellWalls% AND WEST THEN PRINT "West wall is present" ' test the fourth bit**

The first four bits in **CellWalls%** are being used as * flags* to determine if a wall is present or not. The number

**11**equates to

**1011**in binary. The right-most bit is

**1**so there is a wall to the North. The second bit from the right is

**1**so there is a wall to the East. The third bit from the right is a

**0**so there in no wall to the South. Finally, the fourth bit from the right is

**1**so there is a wall to the West.

**This one variable effectively holds 4 pieces of information for us encoded in its bits.**

Here is a demonstration program showing this concept in action. The player can use the **arrow keys** to move the red circle within the map. The player will not be able to go through walls if they are present. The **ESC** key allows the player to leave the demonstration. Save the program as **BitMaze.BAS** when finished typing it in.

**Figure 12: A Bitwise maze**

A few things are going on in this example that need explained. First, in lines 73, 77, 81, and 85 the **LINE** statement is abruptly ended with an underscore ( **_** ) character and then the statement resumes on the next line. When a line of code ends in an underscore ( **_** ) character that means the rest of the command is continued on the next line. This is used to keep lines of code from scrolling off the right side of the screen. The use of this IDE feature is completely * optional* but it has been used here so the entire lines of code can be seen in the example screen shot above. You'll see more of this use in later lessons as code starts getting more complex.

Secondly, in line 102 you see the **DATA** statement. The **DATA** statement is used to store values internally inside of source code. In line 102 each cell of the maze wall values are stored here. In line 69 of the code a **READ** statement is used to read the **DATA** stored in line 102. **DATA** statements are not all that common any longer because it's just as easy to store data in files and read it from there. For the interest of keeping everything within one piece of code for this example a **DATA** statement was used. DATA statements were popular when home computers used cassette tape drives or very slow floppy diskette drives. Loading values from them took time and would pause a game. Visit the QB64 Wiki for more information on the **READ** and **DATA** statements.

# Integer Division ( \ )

Integer division uses the backslash ( **\** ) character instead of the foreslash character ( **/** ) used by standard division. Integer division will only return the whole number, or integer, portion of a result. Integer division is typically used when only integer results are needed such as working with screen coordinates. The following two lines of code highlight the difference between standard division and integer division.

**PRINT 10 / 6 ' results in 1.66666 repeatingPRINT 10 \ 6 ' results in 1**

Integer division **will not round up** but instead simply cuts off the fractional portion of a number resulting in the return of the whole number. It's important to remember that integer division will always round the * divisor*, or second number, up or down accordingly. If you try this:

**V% = 10 \ .3 ' division by 0 error!**

you will get a * division by zero error* because

**.3**was rounded down to zero. The

*in integer division must always be*

**divisor****.5**or greater to avoid this error.

# The MOD Statement (Modulus Division)

In Modulus division (sometimes referred to as * remainder division*) only the remainder of a division result is returned as an

*. The*

**integer****MOD**statement is used to perform

*. The following lines of code (copied from the QB64 Wiki) highlight the differences between standard division, integer division, and modulus division.*

**modulus division****D! = 100 / 9I% = 100 \ 9R% = 100 MOD 9PRINT "Normal Division:"; D! ' results in 11.11111PRINT "Integer Division:"; I% ' results in 11PRINT "Remainder Division:"; R% ' results in 1**

The reason modulus division resulted in the value of **1** is because **100 \ 9** = 11 and since 11 * 9 = 99 that leaves a remainder of **1**. The **MOD** statement treats the * divisor* the same as integer division rounding the

*up only if it's .5 or greater.*

**divisor****Modulus division is actually used quite often in programming especially in respect to timing in games.** Say for instance you have a counter within a loop and you want some code to execute every 30 frames. The **MOD** statement can help with this.

**DOCount% = Count% + 1 ' increment counterIF Count% MOD 30 = 0 THEN ' is counter evenly divisible by 30? ' execute the code hereEND IFLOOP**

Only when **Count%** is evenly divisible by **30** will there be no remainder:

**30 \ 30 = 1 with no remainder60 \ 30 = 2 with no remainder90 \ 30 = 3 with no remainder**

..

..

etc..

# Exponents ( ^ )

Exponent ( **^** ) is used to raise a numeric value to an exponential value, "* to the power of*". For example:

**PRINT 2 ^ 3 ' results in 8 (2 * 2 * 2)**

Exponents can also be used to calculate square and cubed roots of numbers like so:

**PRINT 144 ^ (1 / 2) ' results in 12 as the square root (12 * 12)PRINT 27 ^ (1 / 3) ' results in 3 as the cubed root (3 * 3 * 3)**

# The INT Statement

The **INT** statement converts a numeric value to an integer by * rounding down* the value to the next whole number.

**INT**rounds numbers down for both positive and negative values. Therefore:

**PRINT INT(2.5) ' result is 2 rounded down**

and

**PRINT INT(-2.5) ' result is -3 rounded down**

are both rounded down. The **INT** statement comes in handy when you need to convert between data types.

**N! = 12.789 ' stored in a single variable typeC% = INT(N!) ' converted to an integer and stored in an integer variable type**

# The CINT and CLNG Statements

The **CINT** statement is specifically used to convert decimal numbers to an * integer* using

*. This means that numbers with decimal points less than .5 are rounded down, numbers with decimal points higher than .5 are rounded up, and numbers with .5 as the decimal value are rounded to the nearest even integer value which may be up or down depending on the number.*

**Banker's Rounding****CINT**converts numbers to

*meaning that you must remember to use numbers in the range of 32,767 to -32,768.*

**true integers****PRINT CINT(2.5) ' results in 2 as 2 is the closest even number (round down)PRINT CINT(3.5) ' results in 4 as 4 is the closest even number (round up)PRINT CINT(10.6) ' results in 11 (round up)PRINT CINT(10.4) ' results in 10 (round down)N! = 1034.5 ' single value in integer rangeI% = CINT(N!) ' results in 1034 as it is the closest even number (round down)**

The **CLNG** function is specifically used to convert a decimal number to a * long integer*. It uses the same

*scheme as*

**Banker's Rounding****CINT**. Since

**CLNG**converts to

*you must remember to use numbers in the range of 2,147,483,647 to -2,147,483,648.*

**long integers**# The CSNG and CDBL Statements

The **CSNG** statement is used to convert a numeric value to the closest * single precision* value. This function is useful for defining a numeric value as single precision as well.

**N# = 895.18741378374S! = CSNG(N#)PRINT S! ' results in the single precision value 895.1874**

The **CDBL** statement is used to convert a numeric value to the closest * double precision* value. This function is mainly used to define any numeric value as double precision.

# The _ROUND Statement

The **_ROUND** statement is used to round a numeric value to the closest * even integer*,

*, or*

**long integer***value. This statement can accept any numeric value to convert and performs the same functions as*

**_integer64****CINT**and

**CDBL**while offering conversion for numbers that exceed long integer in size. Since

**_ROUND**uses the same

*scheme as*

**Banker's Rounding****CINT**and

**CDBL**it makes a suitable substitute for both commands.

# The FIX Statement

The **FIX** statement rounds a numerical value to the next whole number * closest to zero*, in effect truncating, or removing, the fractional portion of a number returning just the integer. This means that the

**FIX**statement

*and*

**rounds down for positive numbers***.*

**up for negative numbers****PRINT FIX(2.5) ' result is 2 printed to the screenPRINT FIX(-2.5) ' result is -2 printed to the screen**

# The SQR Statement

The **SQR** statement returns the square root of any * positive* numeric value.

**N% = 256PRINT SQR(N%) ' returns 16**

Calculating the hypotenuse of a right triangle:

**A% = 3 ' side AB% = 4 ' side BH! = SQR((A% ^ 2) + (B% ^ 2)) ' side CPRINT "Hypotenuse:"; H! ' value of 5 is printed**

Remember that the **SQR** statement will only work with * positive numbers* and the accuracy of

**SQR**is determined by the variable type being used to store the result.

# The ABS Statement

The **ABS** statement returns the * absolute value* of any numeric value in effect turning negative numbers into positive numbers.

**N% = -100PRINT ABS(N%) ' results in 100 printed**

# The SGN Statement

The **SGN** statement returns the * sign* of a numeric value. The value of -1 is returned for values less than zero. The value of 1 is returned for values greater than zero and 0 if the numeric value is zero.

**N1% = -10N2% = 0N3% = 10PRINT SGN(N1%), SGN(N2%), SGN(N3%) ' -1 0 1 printed to screen**

# The SIN and COS Statements

The **SIN** statement returns the * sine of an angle* measured in

*. The following is an example that displays the seconds for an analog clock. (*

**radians***)*

**Adapted from code by Ted Weissgerber.**The **COS** statement returns the * cosine of an angle* measured in

*. The following code creates 12 analog hour points that can be used with the clock example above. (*

**radians***)*

**Adapted from code by Ted Weissgerber.**# The TAN and ATN Statements

The **TAN** statement returns the ratio of sine to cosine, or the * tangent value of an angle* measured in

*. Here is an example of*

**radians****SIN**and

**TAN**working together to create spiraling text. (

*)*

**Adapted from code by John Onyon.**The **ATN** statement returns the * arctangent of an angle* measured in

*. Here we use*

**radians****ATN**to find the angle from the mouse pointer to the center point of the screen. (

*)*

**Adapted from code by Rob aka Galleon.**# The RND Statement

The **RND** statement is used to return a random number, well, sort of. **This may come as a surprise but no computer in the world to this date has been able to generate truly random numbers.** It's one of those things on computer scientist's to-do lists. Computers can generate * pseudo-random* numbers that appear to be random but in reality are not (makes you think about the "randomness" of those video poker machines in Vegas or the auto lotto numbers chosen for you doesn't it?" To see this in action type in the following code:

**FOR i% = 1 TO 5 PRINT RNDNEXT i%**

Run the code a few times and you'll see the same five "random" numbers appearing over and over again. Computers can generate what appear to be random numbers but in actuality are not. There is a work around to this however. Change the code as seen below:

**RANDOMIZE TIMERFOR i% = 1 TO 5 PRINT RNDNEXT i%**

Run the code a few times again and you'll get what appears to be truly random numbers even though they are not.

The **RND** statement generates random numbers between 0 and .9999999 but in a predictable manner each time a program is executed.

The **RANDOMIZE** statement is used to * seed* the random number generator with a supplied numeric value. This basically tells the random number generator to start somewhere else in the list.

The **TIMER** statement returns the number of seconds that have elapsed since midnight which ranges from 0 (midnight) to 86399 (11:59:59PM). TIMER resets back to 0 every day at midnight. TIMER is often used to * seed* the random number generator but even this is not fool-proof. If you execute a program at exactly noon on two or more separate days you'll get the same random numbers.

Since **RND** only produces random numbers between 0 and .9999999 you'll need to multiply **RND**'s value with the largest random number you are looking for plus 1. Modify the code once again to see this.

**RANDOMIZE TIMERFOR i% = 1 TO 5 PRINT INT(RND * 10) + 1NEXT i%**

The code above produces random numbers between **1** and **10**. **RND * 10** will produce a random value between **0** and **9.999999**, the **INT** function converts that to an integer, and finally **+ 1** is added so the resulting number will between **1** and **10**. If you want to produce random numbers between 50 and 100 you would need to add a start value like so.

**RANDOMIZE TIMERFOR i% = 1 TO 5 PRINT 50 + INT(RND * 51)NEXT i%**

**RND * 51** will produce a value between **0** and **50.99999**, the **INT** function converts that to an integer, and finally **50** is added to that value with the result being between **50** and **100**.

You can get creative with * seeding* the random number generator to make the values seem even more random. If your game is mouse driven you could do this every so often in your code:

**RANDOMIZE TIMER \ (_MOUSEX + 1)**

One is added to the value of **_MOUSEX** to ensure if the mouse pointer is sitting at coordinate zero (or off the game screen) **TIMER** will always be integer divided by at least the value of one to avoid * division by zero* errors. As the player is moving the mouse around

**_MOUSEX**will be truly random since the player is giving it analog input through the mouse and the player's movements can't be predicted.

# Your Turn

This lesson has been more of a general knowledge section on some of the math functions available in QB64. Don't worry if some of the concepts here have flown over your head so to speak. Many of the functions introduced here will be used in later advanced lessons and their usage will become more clear.

It's time to write your first game. Lessons 1 through 10 have given you enough of a working background with QB64 to write a simple slot machine as seen in the figures below.

**Figure 13: Program first run**

**Figure 14: Chicken dinner!**

**Figure 15: Not even close**

**Figure 16: More chicken!**

**Figure 17: One armed bandit!**

**Figure 18: Oh so close!**

**The program consists of:**

Six symbols: SQUARE, CIRCLE, DIAMOND, TRIANGLE UP, TRIANGLE DOWN, and SPECIAL (dual circle)

Eight colors used: RED, GREEN, BLUE, PURPLE, YELLOW, CYAN, GRAY, and BLACK

The screen is 340 pixels wide by 340 pixels tall.

Each symbol window is 100 pixel wide by 100 pixels tall.

The symbols are drawn inside each symbol window using an 80 pixel by 80 pixel area within ensuring the symbols are 10 pixels away from the outer edges of the symbol window. See the blue box symbol in

**Figure 17**.The symbols are drawn with simple graphics commands:

**LINE**,**CIRCLE**, and**PAINT**The text is printed to the screen using the

**PRINT**command. Keep in mind that a semicolon (**;**) at the end of a**PRINT**statement prevents the cursor moving down to the next line causing text to scroll up. This may () come in handy for certain**hint, hint****PRINT**statements.Player input is achieved with

**INKEY$**since the features of**_KEYDOWN**and**_KEYHIT**are not needed.The example program was written with 180 lines of code. That's tiny for a game.

**Don't be discouraged if your program uses more than this.**The example program uses one subroutine and one function. This game could easily be written without the use of subroutines or functions but try to incorporate them if you can. The example program uses a subroutine to draw each symbol based on two variables passed in and a function to spin the wheels and return the payout amount.

**Program operation:**

When the player presses the

**ENTER**key the symbols flash by in rapid succession in all three symbol windows. After a random period of time the first symbol stops. After another random period of time the second symbol stops. And once again after another random period of time the third symbol stops.I chose to have the first wheel "spin" for at least one second but no longer than two.

The second wheel then spins for at least a half second longer up to one and a half seconds longer.

The third wheel then spins for at least a half second longer up to one and a half seconds longer.

This ensure the spinning wheels are never in "Sync" and always stop on different symbols.

This emulates the old-timey mechanical slot machines that were found in Vegas.

If the player wins a spin the text at the top changes from "

**SLOT MACHINE**" to "**WINNER!!**" flashing on for a second, then off for a second, and continues this until the player presses**ENTER**again.A point is deducted from the player's score each time the wheels are spun. This simulates the player inserting a coin to play the next round. Yes, the score can go into the negative amounts showing the player is losing money.

Many times while writing a program you'll need to do something you have not done before and a command you have not encountered may help. There are a few commands used in the program that have not been covered yet but will aid in the game's creation. These statements will be covered in later lessons:

**_TITLE**- to give your program's window a title.**_SCREENMOVE****_MIDDLE**- to have the game screen automatically center on the player's desktop.**COLOR**- to give your**PRINT**ed text a foreground (the text color) and a background color.**LOCATE**- to position your text cursor any where on the screen for the next**PRINT**statement.**_LIMIT**- to limit the number of times a loop can run per second. This makes it easy to count time within a loop. For instance if you set a**_LIMIT 30**and have a counter counting within the loop you'll know that when the counter reaches 30 a second has gone by, 15 and a half second has gone by, etc..**_DISPLAY**- to tell the computer to wait until symbol drawing has been finished before displaying it to the screen. Without this your player will catch glimpses of symbols actually being drawn with the basic graphics statements even though they are rapidly flashing by.**_AUTODISPLAY**- to tell the computer to display any update to the screen right away. This is used to override any previous**_DISPLAY**statement.

These lessons are going to cover **MANY** of QB64's commands but * it won't even be half of them* available to you. When you have finished these lessons make sure to check out all the commands in the QB64 Wiki.

**Program Theory:**

In this example program I chose to envision the symbols on a rotating wheel just like the real old time slot machines had. Each wheel consists of 16 places with the symbols arranged as such:

SQUARE, CIRCLE, DIAMOND, TRIANGLE UP, TRIANGLE DOWN - repeated 3 times for 15 symbols.

The 16th symbol then contains the SPECIAL big payout symbol. This will make the big payout difficult to get because there is only one SPECIAL symbol on each wheel. The chances of them lining up is greatly reduced.

As the wheel spins a counter keeps track of which symbol should be shown. When the counter reaches 17 it's reset back to 1 to simulate that the wheel has completed one revolution.

**Of course there are many different ways to achieve the same outcome.** That's the great thing about programming. Your code may be completely different from the example code and still achieve the same outcome. Make sure to share your code on the QB64 forum when you are finished.

# Commands and Concepts Learned

**New commands introduced in this lesson:**

**AND****OR****XOR****NOT****\ (Integer Division)****MOD****INT()****CINT()****CLNG()****CSNG()****CDBL()****_ROUND()****FIX()****ABS()****SGN()****SIN()****COS()****TAN()****ATN()****READ****DATA**

**New concepts introduced in this lesson:**

**numbering system****transistor****binary****binary numbering system****George Boole****Boolean Logic****logic gate****bitwise math****flags****Banker's Rounding****sine****radian****cosine****tangent****arctangent**