Lab Activity 8

Lab Description:

This week's lab consists of three parts. In the first part you review how loops work in C and consider how to generate random numbers in C.  In the second part we will write a number-guessing game in C. To do so you will use C program constructs such as the if-else statement and the while statement.

In the third part of this lab you will learn to use external libraries to draw some 3D graphics. To do so, you will use for loops and the OpenGL graphics library.


Instructions:

This lab is performed in groups. Passing of the Lab will require that you communicate, help one another, and be responsible for each other's learning to some extent. Make sure every member of your team knows the material and has coded the program on their own machines before moving on to each new section.  You will need to get the TA's signature throughout the Lab at which time the TA may request at random that one of your team members show their implementation before signing to ensure you all know the material.
 

Part I: Doing Loops and Random Numbers

Three types of loops

We often want to write programs that do something over and over again, and for that we use loops. There are three types of loops available. The first type is the while loop, which looks like this:
  while( condition ) 
{

Do something...

}
Of course, condition has to be replaced by a real C condition. As long as the condition is true, the statements in between the braces get repeated. For example, try typing the following program in Eclipse. Create a new project called 'lab8a'. Then, create a new C source file named loop.c and save the following code in it. The following program generates 10 random integer values from 0 to N.
  #include <stdio.h>
#include <time.h> /* library containing the "time" function */
#include <stdlib.h> /* library containing the "rand" function */

int main(void)
{
int N;
int Total = 10;
int counter = 1;



printf("Enter a number: ");
scanf("%i", &N);

while(counter <= Total)
{
printf(" %i ", rand()% (N+1) ); /* generate a random number between 0 and N inclusive */
counter = counter + 1;
}

printf("\n");
return 0;
}




The function  rand() returns an integer value from 0 to RAND_MAX ( a constant equal to 2,147,483,647 on our lab machine).

Compile and run this program. It will ask for a number so enter any positive integer (20 for example). Run the program again and type the same number as in the previous run. Notice that the 10 random numbers are the same.

A variation of the while loop is the do-while loop. This type of loop avoids the problem of having to worry about whether n is initialized correctly. do-while loops look like this:

  do 
{

Do something here...

} while( condition );
Notice the semicolon at the end. First the code "Do something here..." is executed then the condition is checked. If the condition is TRUE then the code is executed again else if the condition is FALSE then the loop is finished.


 Re-write the above program using a do-while loop and then answer Question #1 on the Answer Sheet.







Often when we write a loop, there's one particular variable whose value determines when the loop stops. For example, in the loops above, the variable counter serves that purpose. So the third type of loop, the for loop, makes it a little easier to control the value of that variable. for loops look like this:

  for( initialize; condition; update ) 
{

Do something here...

}
initialize, condition, and update have to be replaced by real C statements. Notice that there are always two semicolons between the parentheses of a for loop. A for with the above structure is essentially identical to a while loop like this:
  initialize;
while( condition )
{

Do something here...

update;
}

Again, re-write the above program using a for loop and then answer Question #2 on the Answer Sheet.


 

Part II   Guessing Game

1. Requirements Specification (Problem Definition)

You will write a program where the computer generates a random number and the user tries to guess that number. The user will be given an unlimited number of guesses, until the correct number is guessed.

2. Analysis---Refine, Generalize, Decompose the problem definition
Request from the user 'e'asy , 'm'oderate or 'd'ifficult level for the game.
     'e' means that the user guesses a number in the range 1 and N=16.
     'm' means that the user guesses a number in the range 1 and N=128.
     'd' means that the user guesses a number range 1 and N=1024.

Generate an integer value in the approriate range and assign to the variable named target.
Allow the user to guess any number of times until the user guesses the value assigned to the variable target .
If the guess is less than or greater than the target tell the user whether the guess was larger or smaller than the target, and allow the user to guess again.
If the user makes a correct guess tell them and terminate the program.
3. Design---Develop Algorithm
choices    loop

elseif

4. Implementation --- Write the "Program" (Code)

Create an Eclipse project named 'lab8b'. Then, create a new C source file in that project called 'guess.c'. And, copy the following piece of code into the c file.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

void main(void)
{
/* declare all variables here */



/* your code goes here */






}



Hints:
To check for choice you can either use a nested if-else statement or a switch statement, which is more compact.
To generate a random integer between a and b you can use the expression:  rand()%(b+1 - a) + a
To generate an infinite while or do-while loop try while(1). To generate an infinite for loop try  for ( ... ;  ; ...) where you omit any value between the pair of semicolons.
When you want to execute two or more statements in an if statement you will need to use a pair of curly braces { }. For example to write code that executes if guess = target you write,

if (guess == target)
{
 print something
 return;
}


5. Run the code
Save to compile your program. Note that whenever you save your source file, the compiler is run. Any compile errors are shown under the "problems" tab at the bottom of the screen and highlighted in red. If there are no errors, your source code is automatically compiled into an executable file. To run a program in Eclipse you must create another 'launch configuration' as you did in previous labs. That is, click on the black down arrow of the run button and select the binary you want to run, or click run..., double click on C/C++ application, and click Search Project. Once you've created the launch configuration, you can just select that launch configuration from the run button pull-down menu. To see a demo of how your program should work download guess  (right-click and choose "Save Link Target As" and name it guess without any extension.). Run this program by typing

   guess

at the Unix prompt (Go to Applications, Utilities, Terminal to open a Unix prompt).

Make sure your program works properly before you proceed to the next step. If in doubt, ask your TA for help.



Now, we'd like to modify the program to generate a different random number every time we run the program. To do this you will need to add the statement,

  srand(time(NULL));

immediately after the declarations but before any executable code. The statement srand(time(NULL)); sets the seed (or first value) of the rand() function so that the first random number occurs at "random". Every time you re-run your program rand will not always return the same first random number. The statement above says, seed the random number generator with the current time on the computer clock. The time() function returns the time on the clock when the program is running and is to some degree random, assuming the time is kept down to milliseconds. To read more about srand() and rand() see the course book "Applied C An Introduction and More" pp. 260-261. Save, compile and run your program.


Obtain your TA's signature on the answer sheet for Question #3.

On the answer sheet answer the following question.
4. What is the best strategy to win the guessing game? That is, for a random number N of the form N = 2i, write down a strategy in which you need at most i+1 times to guess the target .
(For example, when n = 16 = 24 you would need at most 5 guesses to guess any target between 1 and 16.)
 

Part III Using external libraries / OpenGL

Description of problem:

In this section, we will learn to use external libraries as part of a C program. One of the most common libraries used in C is the OpenGL graphics library. This is the graphics technology behind many popular video games, such as Quake 3 and Half-Life. OpenGL has also been used to create feature-length films.

You will use some simple OpenGL code to plot and visualize a mathematical function.

Step 0.Download the Eclipse project lab8-opengl.zip  You have to import this project into your Eclipse and begin adding your code into it. To do so, go to File, Import..., and then select 'Existing Projects into Workspace' from 'General'. Next, make sure the 'Select archive file' radio button is selected. And, Browse for 'lab8-opengl.zip'. Click on 'Finish' button, expand the newly exported project, and locate the file 'lab8.c'.

Step 1. In the file lab8.c, Locate the comment:

/* Draw coordinate axes */
The OpenGL function glBegin(GL_LINES) sets up an environment in which every pair of new vertices you draw creates a line. For example, the code:
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(10.0f, 0.0f, 0.0f);
will create a line from the point (1,0,0) to the point (10,0,0). glVertex3f takes three floating point numbers as arguments. Remember that if you type a decimal number in C, the default will make that number a double. However, the OpenGL functions you will use in this lab require floats as arguments. This is why you must put an 'f' at the end of each number. The first is the x coordinate, the second is the y coordinate, and the third is the z coordinate. When you want to stop drawing lines, use the glEnd() function.

Write OpenGL code to draw the three coordinate axes, each starting at the origin and extending out with length 10. In OpenGL, the x axis goes from left to right on your monitor, the y axis goes from bottom to top, and the z axis goes into the monitor.

When you are ready, compile your program by saving it. Test your program by running your program using the run button and lauch configuration as usual. If you don't see the usual run button, try this: On the left, locate the lab8-opengl project. Right click "lab8-opengl" and choose "Run As...", then "Run..." then double click C/C++ as usual.

You should see a window that looks like this:


Step 2. Locate the comment:

/* Plot your function with points */
The OpenGL function glBegin(GL_POINTS) sets up an environment in which every vertex you draw creates an individual point. For example, the code:
glVertex3f(1.0f, 1.0f, 1.0f); 
will draw a point located at (1,1,1). When you want to stop drawing points, use the glEnd() function. Write OpenGL code to plot the y = sin(x) + cos(z) function on a 100 by 100 grid of evenly spaced points, in the cube x in [0,10] and z in [0,10]. You will need to use a pair of nested for loops each from 0 to 99. Divide the indices by 10.0 to scale the values to fit on the axes we have already drawn. Then, use a call to glVertex3f to plot each point. Compile and test your program. It should look like this:

You can rotate the 3D image using the arrow keys.

Step 3. Well, we have a 3D plot, but it looks a little dull. Let's add some color. The OpenGL function glColor3f takes 3 float arguments between 0.0 and 1.0. The first argument is the amount of red, the second is the amount of green, and the third is the amount of blue. For example,

glColor3f(0.0f, 0.0f, 1.0f)
would be the color dark blue, since it has no red or green, but is as much blue as possible. When you call the glColor3f function, everything OpenGL draws afterwards will be the specified color. Let's make the color blue everywhere and add more red as the height (y value) of the function increases, thus making purple tips. Add a glColor3f function before each call to glVertex3f when you plot your points. Compile and run your program. It should look something like this:


Show your TA your 3D graphics and get your TAs signature for Question #5 on the Answer Sheet.


Appendix A: OpenGL functions used in this lab.

glBegin(GL_LINES): Sets up the line drawing environment of OpenGL. Until you call glEnd(), all vertices drawn will be interpreted as endpoints of a line.

glBegin(GL_POINTS): Sets up the point drawing environment of OpenGL. Until you call glEnd(), all vertices drawn will be interpreted as individual points.

glEnd(): Closes any vertex interpreting environment. If you draw vertices after calling glEnd(), they will be ignored.

glVertex3f(float x, float y, float z): Draws a vertex on the point specified by the input arguments.

glColor3f(float red, float green, float blue): Changes the color used to draw OpenGL objects. Each value is a float between 0.0f and 1.0f.