Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

C# Programming: Creating Random Numbers and Animation, Exams of Computer Science

An excerpt from 'introduction to computer programming using c#'. It explains how to create random numbers in c# using the random data type and initialize it with a seed value. The text also covers the use of random numbers in simple animation techniques, such as drawing balls on the screen and creating games like pong. Code examples and project assignments for practicing these concepts.

Typology: Exams

Pre 2010

Uploaded on 08/07/2009

koofers-user-o81
koofers-user-o81 🇺🇸

3

(2)

10 documents

1 / 32

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
9 Introduction to Computer Programming Using C#
9-2
Creating Random Numbers in C#
As was noted earlier, one of the most important capabilities of a computer is its ability to carry
out tasks repeatedly. But if the “input” doesn’t change, your program will just produce a series of
copies of identical “output.”
We’ve seen two different ways to provide different input for each repetition. We’ve seen how
keyboard users can be prompted to modify the input, and we’ve seen how special looping
instructions can be used to vary, in a predictable manner, the input that a program uses.
When a certain level of unpredictability is preferred, computer programs instead use some kind
of “randomness” facility, usually in the form of a random number generator. This is simply a
function that produces a randomly chosen numeric value each time it is referenced. It’s ironic
that the most reliable way that’s been found to model random behavior is to use a precise
mathematical function.
In C#, random numbers are normally produced using a variable of the data type Random. While
it’s legal to have as many variables of type Random as you want in a program, the usual practice
is to create just one such variable, and use it for every situation where a randomly chosen value is
needed.
The first step, then, would be to declare a variable of type Random, perhaps at the very start of
your form definition:
public partial class Form1 : Form
{
Random choose;
Subsequently, the “random selection” variable can be initialized in the form’s constructor:
public Form1()
{
InitializeComponent();
Choose = new Random();
This initialization step will ensure that the random-number function is initialized to some
randomly chosen starting point, usually using some combination of the date and time. If you’d
prefer to have more control over the function, you can specify a starting point. This would be
most useful during program development, when you may want to ensure, for testing purposes,
that the same “random” set of numbers is used every time. To specify a starting point, which is
conventionally known as a seed value, simply add it as a parameter:
Choose = new Random(seed);
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20

Partial preview of the text

Download C# Programming: Creating Random Numbers and Animation and more Exams Computer Science in PDF only on Docsity!

(^9) 9-2 Introduction to Computer Programming Using C#

Creating Random Numbers in C#

As was noted earlier, one of the most important capabilities of a computer is its ability to carry out tasks repeatedly. But if the “input” doesn’t change, your program will just produce a series of copies of identical “output.”

We’ve seen two different ways to provide different input for each repetition. We’ve seen how keyboard users can be prompted to modify the input, and we’ve seen how special looping instructions can be used to vary, in a predictable manner, the input that a program uses.

When a certain level of unpredictability is preferred, computer programs instead use some kind of “randomness” facility, usually in the form of a random number generator. This is simply a function that produces a randomly chosen numeric value each time it is referenced. It’s ironic that the most reliable way that’s been found to model random behavior is to use a precise mathematical function.

In C#, random numbers are normally produced using a variable of the data type Random. While it’s legal to have as many variables of type Random as you want in a program, the usual practice is to create just one such variable, and use it for every situation where a randomly chosen value is needed.

The first step, then, would be to declare a variable of type Random , perhaps at the very start of your form definition:

public partial class Form1 : Form { Random choose;

Subsequently, the “random selection” variable can be initialized in the form’s constructor:

public Form1() { InitializeComponent(); Choose = new Random();

This initialization step will ensure that the random-number function is initialized to some randomly chosen starting point, usually using some combination of the date and time. If you’d prefer to have more control over the function, you can specify a starting point. This would be most useful during program development, when you may want to ensure, for testing purposes, that the same “random” set of numbers is used every time. To specify a starting point, which is conventionally known as a seed value, simply add it as a parameter:

Choose = new Random(seed);

Chapter 9: Random Numbers, Timers, and Simple Animation (^) 9-

In this example, seed might be some variable, some arithmetic expression, or, when you’re testing an application, probably just a simple fixed constant.

Once a variable of type Random has been initialized, you can use it to produce new random numbers in a number of different ways. Assuming that the random number variable is named choose , you can produce a randomly chosen non-negative integer using the Next function, like this:

choice = choose.Next();

With this form, the variable choice will be assigned a randomly chosen value between 0 and the maximum possible integer value, completely at random. In many cases, though, you may want the value to be restricted. For those circumstances, you can use either of two alternate forms:

choice = choose.Next(maximum); choice = choose.Next(minimum, maximum);

The first form will select a random value between 0 and maximum-1 , inclusively while the second selects a random value between minimum and maximum-.

Random number generators are a critical component of most gaming applications. To simulate rolling a pair of dice, you’d want to produce two random integers, with the smallest possible value of 1, and the largest possible value of 6. Randomly drawing a playing card from a standard deck of 52 cards might require a random value from 0 to 51, or maybe two random values – one for the card’s suit, and another for its rank. Animations typically use random number generation to control variables such as speed and direction of movement for various parts of the display.

Timers

Every computer uses a special clock chip to generate the pulses needed to drive its circuitry. In fact, the frequency with which the clock chip generates these pulses is often quoted when comparing two computer systems. The original IBM PC had an internal clock rate of 4. megahertz, or 4700 clock pulses per second, although the chip used in that early machine was actually rated for a maximum clock speed of 8 megahertz. Today’s processors have clock pulse frequencies several hundreds of times faster. Of course, trying to base a comparison solely on clock speed isn't completely accurate, since not all computers use the same number of clock pulses to complete a particular operation. Still, the pulse rate of the internal clock is an important measure in determining the relative speed of a particular computer.

For so-called real-time applications, the underlying clock speed is an important consideration. If a programmer carefully tailors a flight simulation game, for example, to a particular processor's true clock speed, the application would behave in a completely unsatisfactory way if run on a computer that was significantly faster or slower. Consequently, programmers must tie the program's behavior to a reliable clock that accurately measures time in the same way, regardless

Chapter 9: Random Numbers, Timers, and Simple Animation (^) 9-

point of the modern video game era. By today's standards, Pong is an extremely primitive game. Basically, a ball bounces back and forth across the screen, and the player tries to maneuver a paddle to hit the ball before it goes off the screen.

To illustrate some of the foundational details, we’ll look at implementing a simple “Pong”-ish style game in C#. In the original version of Pong, a ball bounces back and forth across the screen, being hit (or missed) by a paddle that moves in response to inputs from a controller. For our example program, we’ll instead have a ball bounce back and forth across the screen while the keyboard user tries to hit it with the mouse. A simple scoreboard at the top of the screen will keep track of the number of shots – mouse clicks – and the number of hits – the number of times the mouse is actually on the bouncing ball. A number of obvious extensions will be possible – changing the direction of motion when the ball is hit, or changing the size or speed of the ball in response to hits or misses. It would also be possible to add a Pong-style paddle to the screen by drawing a narrow rectangle on one (or both) ends of the screen, with the paddle moving in response to mouse movements. Rather than responding to mouse clicks, the program could instead test to see if the ball hits the paddles, rather than the edges of the screen, to score points.

The Bouncing Ball Game: Overview

As described above, this ball-bouncing game needs to move a circle back and forth across the screen, in response to timer ticks. Whenever the mouse is clicked, a shot counter needs to be updated. If the mouse is positioned over the circle when it is clicked, a hit counter will also be updated.

The basic form layout will be quite simple. The caption at the top of the form is set to read “Let’s Bounce!,” a panel is placed on the form, with its Dock attribute set to Top , and four Label fields are placed on the panel (which is then narrowed down so the panel is just wide enough to hold the labels. The labels are set to read “Shots:,” “0”, “Hits:,” and “0.”

The panel’s BorderStyle attribute is set to FixedSingle , and the panel’s color is set to contrast with the color of the form.

Additionally, a Timer component is placed on the form, with its Interval attribute set to 25.

The ball will be modeled by a class that tracks the balls location, size, and color, along with the direction in which it’s currently moving. Class methods will include a constructor, for creating and initially positioning the ball, along with a method for moving and drawing the ball, and another method for testing if a mouse click has hit the ball.

Each time a TimerClick event occurs, the TimerClick method will be responsible for updating the ball’s position on the screen, and drawing the ball in its new location, by invoking a screen refresh request.

The MouseClick event handler is responsible for updating the shots count on the screen, and also

(^9) 9-6 Introduction to Computer Programming Using C#

for testing if the mouse has actually “hit” the ball, in which case the hit count must also be updated. This method will need to use the “did I hit it” method of the ball class to do its work.

Finally, the Paint event handler will be responsible for moving and drawing the ball in its new position.

When the program first starts up, the screen will look something like this:

The Ball Class

As noted above, the Ball class will be responsible for tracking the ball’s position, size, and direction of movement, as well as its color. Toward that end, the first few lines of this class are:

public class Ball { int x, y; int radius; int xStep, yStep; int screenTop; Color ballCenter, ballBorder; Random random;

The variables x and y are used to track the center of the ball, while the variable radius is used to keep track of its size. The variables xStep and yStep are used to tell how far the center of the ball should move each time the timer clicks, while the variable screenTop is used to keep track of the size of the panel on the top of the screen – you don’t want the ball to bounce “under” the panel.

(^9) 9-8 Introduction to Computer Programming Using C#

public void Draw(Graphics g) { Brush B; Pen P;

// update the x coordinate, reversing direction // whenever the boundary is hit

x += xStep; if (x < radius || x > g.VisibleClipBounds.Width - radius) { xStep = -xStep; x += 2 * xStep; }

// now update the y-coordinate, reversing direction if // the bottom of the screen or the bottom of the panel is hit

y += yStep; if (y < radius + screenTop || y > g.VisibleClipBounds.Height - radius) { yStep = -yStep; y += 2 * yStep; }

// finally, draw the ball in its new location

using (B = new SolidBrush(ballCenter)) g.FillEllipse(B, x - radius, y - radius, 2 * radius, 2 * radius); using (P = new Pen(ballBorder)) g.DrawEllipse(P, x - radius, y - radius, 2 * radius, 2 * radius); }

The final method in the ball class is used to test to see if a particular point is inside or outside of the ball. This class is used in conjunction with the MouseClick event handler to decide if the mouse was “clicked” while it was positioned on top of the ball. To do this, the distance from the center of the ball to the point that is provided as a parameter is computed, using the algebraic distance formula:

Dist =^ ()Τϕ mouseX^ /Φ4− x^ 15.8711^2 +()Τϕ mouseY^ /Φ4Τφ− y^ 0.744815.8711^2 0 Τφ^0 1 0.7448^ 300.6^ 0 0 1 380.28170.6098 Τμ

In this formula, (mouseX, mouseY) is the position of the mouse, while (x,y) is the center of the ball on the screen.

Chapter 9: Random Numbers, Timers, and Simple Animation (^) 9-

public bool Hit (int mouseX, int mouseY) { if (Math.Sqrt(Math.Pow(mouseX - x, 2) + Math.Pow(mouseY - y, 2)) <= radius) return true; return false; }

Filling in the Remaining Pieces

There really isn’t that much left to the program; most of the dirty work has already been handled within the Ball class. The first thing the program needs to do is declare a variable of type Ball to represent the ball bouncing across the screen, create the actual ball, and then turn on the timer:

namespace Ball_Bouncing { public partial class Form1 : Form { Ball ball;

public Form1() { InitializeComponent(); timer1.Enabled = true; }

Once the ball has been created and set in motion, the next thing that’s needed is the handler for the TimerTick event. This one’s almost trivial – whenever the timer ticks, a screen refresh is requested:

private void timer1_Tick(object sender, EventArgs e) { Refresh(); }

Refreshing the screen will invoke the Paint method, which is also trivial:

private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g;

using (g = this.CreateGraphics()) ball.Draw(g); }

Chapter 9: Random Numbers, Timers, and Simple Animation (^) 9-

Project Assignments

Project 9.1: The Magic 8-Ball

The Magic 8-Ball, which was invented in 1946, is a fortune-telling toy that became very popular in the 1960’s, and is still available, both in its original form, and also in a variety of customized versions. The original 8-ball is black, and somewhat larger than a standard pool ball, with a black 8 on a circular background on the top. On the reverse side, there is a smaller window through which one face of an icosahedron (a 20-sided figure with triangular faces) is visible. Each of the 20 sides of the icosahedron has a different response to a yes-or-no question. The players would take turns asking questions to the “top” of the 8-ball, and then turn the ball over to see the answer to their question. Here are the original responses:

  • As I see it, yes
  • Ask again later
  • Better not tell you now
  • Cannot predict now
  • Concentrate and ask again
  • Don't count on it
  • It is certain
  • It is decidedly so
  • Most likely
  • My reply is no
    • My sources say no
    • Outlook good
    • Outlook not so good
    • Reply hazy, try again
    • Signs point to yes
    • Very doubtful
    • Without a doubt
    • Yes
    • Yes - definitely
    • You may rely on it

For this project, I’d like you to develop a C# program that simulates the behavior of the Magic 8- Ball. While the basic project will be fairly simple, there are lots of opportunities for you to customize the project so it behaves a more personalized way.

Step 1: Set Up the Basic Form

Your basic form will be quite simple. It’ll include a text box in which you can type a question, and three buttons – one to ask for an answer to your question, a second to ask the same question, in case you got a non-committal response the first time, and a third to indicate that you’re ready to ask a new question. Initially, only the first button should be enabled.

You also need to “draw” the 8-ball on the screen. This, however, will be done “at run time,” rather than during the program design stage. In anticipation of drawing the 8-ball on the screen, you’ll place a panel on the screen. A black circle, representing the 8-ball, will be drawn on the ellipse by the panel’s paint event handler. When a response is solicited, the answer will be drawn in the middle of the circle.

Here’s what your form should look like; be sure to make the form large enough so your 8-ball circle isn’t too small!

(^9) 9-12 Introduction to Computer Programming Using C#

Step 2: Create the Panel’s Paint Event Handler

To create this handler, click on the panel, and then click on the “lightning bolt” button on the Properties tab to bring up the event handler lists. Click in the area next to “Paint” to create the handler function. Add instructions to this handler to draw a solid (filled) black ellipse, with its upper left corner at position (10,10) of the panel. Set the width of the ellipse equal to the width of the panel minus 20, and the height of the ellipse equal to the height of the panel minus 20.

Be careful, though, and make sure your references are all relative to the panel, rather than to the form. When you create the Graphics handle, use panel1.CreateGraphics() , rather than this.CreateGraphics() , and reference panel1.Height and panel1.Width to set the dimensions of the ellipse.

Step 3: Create the Click Handler for the First Button

Presumably, the keyboard user will click on the “Tell Me, Oh 8-Ball” button after typing a question into the text box. When this happens, the program needs to select a response and display it in the middle of the 8-ball’s ellipse.

(^9) 9-14 Introduction to Computer Programming Using C#

multiple times!

Step 4: Implement the Other Two Buttons

When the “Are You Sure?” button is clicked, your program needs to essentially repeat a “click” on the first button. First, though, you need to erase your previous response by redrawing the 8- Ball. Only two instructions are required to accomplish this task:

panel1_Paint(sender, null); button1_Click(sender, e);

The “Thank You” button isn’t a whole lot more difficult. It should send focus back to the (cleared) text box, re-enable the first button, disable the 2nd^ and 3rd^ buttons, and then repaint the 8-ball.

Step 5: Amaze Your Friends

Now you’ve got the perfect way to amaze your friends with your uncanny ability to predict the future.

Chapter 9: Random Numbers, Timers, and Simple Animation (^) 9-

Project 9.2: Beat the Goalie

For this project, we’ll develop a game program that is similar in style to the classic Pong game. In this case, the “player” will be controlling the goaltender’s stick in a hockey game, responsible for stopping the puck, which will be shot from random locations on the ice.

Step 1: Set Up the Basic Form

The form used in this application is quite simple, as shown below. It contains three timer components, which aren’t visible on the screen, a pair of labels with the captions Save !!! and Goal!!! , and a small panel, representing the score board, with some additional label components. When the game is actually running, there will be a lot more detail. However, the instructions for creating that detail will be addressed later. Only the first timer should be enabled. The Interval attribute of this timer should be set to 25, while the second timer’s Interval should be 250, and the third timer’s Interval should be 100. Also, the Save!!! and Goal!!! labels should be invisible.

In addition to the obvious setup details, you should set the form’s WindowState attribute to Maximized , and set its FormBorderStyle attribute to FixedSingle. This will prevent the individual playing the game from re-sizing the game’s screen while it is running.

Step 2: Create the “Rink” Class

The heart of this project is a set of three separate classes – one for the underlying rink, one for the goal stick, and a third for the puck. The rink will be drawn when the program first starts, and then redrawn every time there is any movement from either the goalie’s stick or the puck. The only methods for this class are the class constructor, which lays out the positions of the various items on the rink, and a draw method, which, as the name implies, is used to draw the rink on the screen.

Chapter 9: Random Numbers, Timers, and Simple Animation (^) 9-

// Now create the goalie stick

gs = new GoalStick(g, netFront, netTop, netBottom); }

public void Draw(Graphics g) { Pen p; Brush b;

// Draw the net and the large outer faceoff circles

using (p = new Pen(Color.Red, 3)) { g.DrawLine(p, netFront, netTop, netBack, netTop); g.DrawLine(p, netBack, netTop, netBack, netBottom); g.DrawLine(p, netBack, netBottom, netFront, netBottom); g.DrawEllipse(p, circleX - OuterCircleSize, circleY1 - OuterCircleSize, 2 * OuterCircleSize, 2 * OuterCircleSize); g.DrawEllipse(p, circleX - OuterCircleSize, circleY2 - OuterCircleSize, 2 * OuterCircleSize, 2 * OuterCircleSize); }

// Finally, draw the blue line and the inner circles

using (b = new SolidBrush(Color.Blue)) { g.FillRectangle(b, BlueLineStart, 0, BlueLineWidth, rinkHeight); } using (b = new SolidBrush(Color.Red)) { g.FillEllipse(b, circleX - InnerCircleSize, circleY1 - InnerCircleSize, 2 * InnerCircleSize, 2 * InnerCircleSize); g.FillEllipse(b, circleX - InnerCircleSize, circleY2 - InnerCircleSize, 2 * InnerCircleSize, 2 * InnerCircleSize); }

(^9) 9-18 Introduction to Computer Programming Using C#

Step 3: Create the Goalie Stick Class

The GoalStick class provides the necessary support for the goalie stick, which is moved back and forth in front of the net by the mouse in an effort to stop the puck. This class has four methods – the constructor, which creates the goal stick, a draw class, for drawing the mouse on the screen, a method for moving the stick, in response to mouse movements, and a method for testing if the puck hit or missed the stick on its travels toward the net. The definition of the GoalStick class follows:

public class GoalStick { int stickX, stickY, netTop, netBottom, stickLength; const int stickWidth = 4;

public GoalStick(Graphics g, int netX, int top, int bottom) { // Save the top and bottom coordinates of the net

netTop = top; netBottom = bottom;

// Position the stick in front of the net

stickX = netX - 5 - stickWidth; stickLength = (netBottom - netTop) / 4; stickY = (netTop + (netBottom - netTop) / 2 – (stickLength / 2));

// Draw the goal stick

Draw(g); }

public void Draw(Graphics g) { Brush b;

using (b = new SolidBrush(Color.Black)) g.FillRectangle(b, stickX, stickY, stickWidth, stickLength); }

(^9) 9-20 Introduction to Computer Programming Using C#

this.rink = rink; parent = form;

// Pick a starting location for the puck

puckX = Rink.BlueLineStart + Rink.BlueLineWidth + PuckSize + rand.Next(3 * width / 4); puckY = 20 + rand.Next(height - 40);

// Pick the spot in the net where the puck is aimed

target = rand.Next(Rink.NetWidth - 2 * PuckSize) + rink.netTop + PuckSize;

// Compute the offsets and steps to the destination

deltaX = rink.netFront - puckX; deltaY = target - puckY; xStep = 20 + rand.Next(20); yStep = deltaY / (deltaX / xStep); }

public void Move() { // Move the puck, and check to see if it’s hit the net

puckX += xStep; puckY += yStep; if (puckX >= rink.netFront) { parent.updateScoreboard((int)puckY, PuckSize); } }

public void Draw(Graphics g) { Brush b; using (b = new SolidBrush(Color.Black)) { g.FillEllipse(b, (int)(puckX) - PuckSize, (int)(puckY) - PuckSize, 2 * PuckSize, 2 * PuckSize); } } }

Chapter 9: Random Numbers, Timers, and Simple Animation (^) 9-

Step 5: Define the Main Program’s Variables

The main program will need a total of 7 variables, as follows:

  • rink , a variable of type Rink , that will hold the definition of the ice rink
  • gs , a variable of type GoalStick , that will hold the definition of the goalie’s stick
  • p , a variable of type Puck , that holds the definition of the current puck
  • started , a variable of type bool , that should initially be set to false. This variable will have its value change to true once the initial screen has been drawn, and is used to ensure that the program doesn’t attempt to “repaint” the rink and goalie stick until after they’ve actually been created
  • goalCount and shotCount , a pair of variables of type int that will be used to keep track of the scoreboard data
  • random , a variable of type Random , that will be used to generate the random numbers needed to initially position the puck and set its speed as it travels toward the net

These 7 variables should be declared at the very start of your form definition, just ahead of the constructor for Form1. In addition, you need to add an instruction to the constructor for Form to initialize the random number generator:

random = new Random();

Step 6: Implement the First “Timer Tick” Event Handler

The first timer is only used once – to trigger the creation of the variable rink , and draw the initial rink layout on the screen. This is done under timer control to ensure that the form has opened and maximized, because the “Save” and “Goal” labels, along with the “scoreboard” panel, are move to the extreme right-hand side of the form.

Your timer event handler should do the following:

  • Declare a variable g of type Graphics
  • disable timer1 (set its Enabled attribute to false )
  • Move the “Save” and “Goal” labels to the right-hand side of the screen by setting the Left attribute of these label fields to this.Width (the width of the form), minus the Width of that label field, minus 10
  • Move the scoreboard panel to the lower right corner of the screen by setting the Left attribute of the panel to this.Width , minus the Width of the panel, minus 10, while also setting the Top attribute of the panel to this.Height (the height of the form), minus the Height of the panel, minus 40
  • Create the Rink variable, which will also create the goalie stick, like this:

using (g = this.CreateGraphics()) {