by Jim Krumm
Click here to go to the Computer Science Department Home Page for Casper College at www.caspercomsci.com.
Here are some projects that we have made in our C++ classes Computer Science I (COSC1030) and Computer Science II (COSC2030):
Source Code Examples of Console Applications Written in C++:
2. How to Setup and Create a Simple Triangle Header Class File Using C++
3. How to Setup a Fraction Class Using Operator Overloading
4. The Console Tic Tac Toe Program
5. Selection Sort, File Write, File Open, and Binary Search Program
6. Circularly Linked List Using Pointers And Dynamic Allocation of Memory
7. How to take Command Line Parameters
8. How to Compile and Link C++ Class Files in the Linux Environment and How to Use Makefiles
9. π ( Pi) to 14 Places Behind the Decimal Using the cmath Arc Cosine Function
11. A Function that Rounds to However Many Places You Specify
12. A Console Based Pong Game with Sound
Prime Number program: This program determines if a number is prime. Click here for the program's source file.
#include <iostream> using namespace std;int main(){int num=0;int count=0;int prime=1;char ans=' ';do{cout <<"Enter a number: ";cin >> num;for (int i=(num)/2; i>1; i--){if (num%i==0){count=count+1;if (count==1)cout <<"Internal Factor(s): ";prime=0;cout <<i<<" ";}}if (prime==0){cout<<"\nNumber is not prime."<<endl;}if (prime==1){cout <<"Number is prime."<<endl;}cout<<"Do you wish to find another prime: ";cin>>ans;cin.ignore(200,'\n');count=0;prime=1;system("cls");}while(ans =='y' || ans=='Y');system("pause");return 0;} |
How to Setup and Create a Simple Triangle Class file using C++.
1. Click here for the source file. First, set up the Driver, here a file called triangle_driver.cpp as follows:
|
//driver file ...it calls the class #include <iostream> //usually std lib headers in other directories #include "triangle.h" //local header using namespace std; int main() { triangle t1,t2, t3[10]; //just like declaring //a variable //t1,t2, t3[10] are objects and not used triangle t4(5, 6); //the numbers stand for base and //height //t3 sets up an array of 10 objects cout <<"Area of triangle t4 equals "<< t4.area()<<endl; t1.setBase(3); //can set values of variables using methods t1.setHeight(4); cout<<"Area of triangle t1 equals " << t1.area()<<endl; t3[0].setBase(5); t3[0].setHeight(6); cout<<"Area of triangle t3[0] equals " << t3[0].area()<<endl; system("pause"); return 0; } |
2. Next set up the header file, here named triangle.h
|
//write the prototypes/declare data for the class //header file class triangle { //if you don't say public or private, by //default it is all private, can mix public/private //no order public: //user accessed data, functions //data has state, functions have behavior //functions in classes are called methods //just like prototypes triangle(); //creates triangle objects //constructor...never have return types //if no parameters...it is called //the default constructor triangle(double, double); //not a default constructor //constructor allows you to set base and height void setBase(double); void setHeight(double); double area(); private: //declaring variables...never make //variables something the user can declare //it gives him too much power...this is dangerous double base, height; //sort of global variable //in the implementation //protected: //usually use in cases of inheritance }; |
3. Finally setup the implementation file, here named triangle.cpp
|
//implementation...write the functions #include <iostream> #include "triangle.h" using namespace std; //syntax: return type if there is one, write the class you are in :: //scope resolution operator, then the name of the function triangle::triangle() //creates triangle objects {//default constructor base=0; //typically in default constructor height=0; //initialize your variables } triangle::triangle(double b, double h) //not a default constructor {//never in your parameter use the variable names given in the header //or they will become local to the function base=b; height=h; } void triangle::setBase(double b) { base=b; } void triangle::setHeight(double h) { height=h; } double triangle::area() {// the 1./ required to create a decimal answer or truncation occurs return (1./2)*base*height; } |
This is how to setup and create a class which demonstrates how to overload operators including the insertion, extraction, >, and + operators.
1. Click here to download
the fraction class source files. To begin, first set up the Driver, here
a file called fraction_driver.cpp. :
|
//driver #include <iostream> #include "fraction.h" using namespace std; int main() { fraction f1, f2; //f1 and f2 are objects: instance of the fraction //class fraction f3; //f3 stores the
answer of f1*f2 cout <<"Enter the first fraction:
"<<endl; f1.readFrac(); cout <<"Enter the second fraction:
"<<endl; f2.readFrac(); f1.displayFrac(); cout<<"*"; f2.displayFrac(); cout<<"="; f3=f1.multiply(f2); f3.displayFrac(); cout <<endl; f1.displayFrac(); cout<<"+"; f2.displayFrac(); cout<<"="; f3=f1.add(f2); f3.displayFrac(); cout<<endl; //****************** //overloads the +
operator f1.displayFrac(); cout<<"+"; f2.displayFrac(); cout<<"="; //over loads the +
operator f3=f1+f2; //overload the + operator to allow us to add f3.displayFrac(); cout <<endl; //*********************** //overload the
<< (insertion operator) //display f3: cout<<f3<<endl; //**************************** //overloads the
>> extraction operator cout<<"Enter a fraction: "; cin>>f1; cout<<f1<<endl; //************************ //over loads the >
operator cout<<"Enter a fraction: "; cin>>f2; cout<<f2<<endl; if(f1 >
f2) cout<<f1 <<" is greater than " << f2<<endl; else cout <<f1 <<" is not greater than "<<f2 <<endl; //************************ system("PAUSE"); } |
2. Next set up the header file, here named fraction.h
|
//header file #include
<iostream>
//needs to be here if
you are overloading << or >> using namespace std; #ifndef FRACTION_H //stops multiple
declarations in memory of the //fraction class #define FRACTION_H //compiler directives class fraction{ public:
fraction(); //default constructor...no incoming parameter
fraction(int
n, int d); void readFrac(); void
displayFrac(); fraction
multiply(fraction); //come in with a
fraction, and //in multiply the fraction out front f1.multiply(f2) is a fraction
add(fraction); fraction operator+(fraction &); //prototype allow
f1+f2 friend ostream& operator<<(ostream &, fraction
&); //ostream is not a part of the fraction class, it is in the
//iostream class //so we say since we will use this class it is a friend //out file stream & reference object (fraction output) //function parameters: (ostream object (allows output), //fraction is your fraction friend istream& operator>>(istream &, fraction
&); //main changes istream means infile stream, //>> (extraction) operator (istream & and ,
fraction &)) int operator >(fraction &); //int is return type no need mentioning a class, >
operator //you are coming in with a fraction (objects usually always
//passed by reference private: int num; int denom; }; #endif //compiler directive |
3. Finally setup the implementation file, here named faction.cpp
|
//implementation #include <iostream> #include "fraction.h" using namespace std; fraction::fraction() //default constructor...no incoming parameter {//set variables equal to 0 num=0; denom=0; } fraction::fraction(int n, int d) //constructor {//set variables equal to 0 num=n; denom=d; } void fraction::readFrac() { char slash; cout<<"Enter a fraction (i.e. 3/4): "; cin>>num>>slash>>denom; } void fraction::displayFrac() { cout<<num<<"/"<<denom; } fraction fraction::multiply(fraction f) { fraction temp(num*f.num, denom*f.denom); return temp; } fraction fraction::add(fraction f) { fraction temp(num*f.denom+denom*f.num, denom*f.denom); return temp; } //shows how to overload an operator fraction fraction::operator+(fraction &f) { fraction temp(num*f.denom+denom*f.num, denom*f.denom); return temp; } ostream & operator<<(ostream &o, fraction &f) //can think of o as //cout<< { //ostream is the return type by reference //o is exactly like cout <<f.num<<"/"<<f.denom; o<<f.num<<"/"<<f.denom; return o; } istream & operator>>(istream &i, fraction &f) { char slash; //i is exactly like cin>>f.num>>slash>>f.denom; i>>f.num>>slash>>f.denom; return i; } int fraction::operator >(fraction &f) { int result; double firstF, secondF; firstF=((double)(num))/((double)(denom)); secondF=((double)(f.num))/((double)(f.denom)); if(firstF>secondF) //return 1; result=1; else //return 0; result= 0; return result; //return num*f.denom>denom*f.num; //another way to do all the //lines of code above }
|
Click here for the source for the entire console project and source code on tic tac toe made in Visual Studio.NET 2007.
This program randomly selects numbers saves them to file in C++, opens the file, sorts the numbers using a selection sort and then finds a value in the array using a binary search: Click here for the program's source file.
|
//Prints 100 numbers 1 to 1000 #include<iostream> #include<fstream> #include<time.h> #include <stdlib.h> using namespace std; void selectionSorter(int [], int ); void binarySearcher(int []); void main() { //random number generation and file writing int x[100]; int j=0; srand(time(NULL)); ofstream outfile; outfile.open("myData.dat", ios::out); for (int i = 0; i< 100; i++) { x[i]= 1+rand()%(200); outfile << x[i] << endl; } outfile.close(); //***************** //opens file j=0; int y[100]; ifstream infile; infile.open("myData.dat", ios::in); do { infile >> y[j]; j++; }while (!infile.eof()); infile.close(); //**************** //displays the contents of the array for (i=0; i<100; i++ ) { if (i%20==0) //forces 20 numbers to a line cout<<endl; cout<< y[i]<< " "; } cout << endl; selectionSorter(y, i); binarySearcher(y); //******************* } void selectionSorter(int input_array[], int input_size) { int i, j; int large, temp; for (i = input_size - 1; i > 0; i--) { large = 0; // Initialize small to first element.
// Find the smallest element between the positions 1 and i. for (j = 1; j <= i; j++) { if (input_array[j] > input_array[large]) { large = j; } } // Swap the smallest element found with element in position i. temp = input_array[large]; input_array[large] = input_array[i]; input_array[i] = temp; } for (i=0; i<100; i++) { if (i%8==0) //forces 15 numbers to a line cout<<endl; cout<<i<<") " <<input_array[i]<< " "; } } //************************ //binary searcher void binarySearcher(int xArray[]) { int target=0; int max = 99; //max index int min = 0; //min index int count=0; int index; cout << "\nWhich number do you wish to look for: "; cin >> target; index=(max+min)/2; while ((xArray[index] != target) && (min<=max)) { count = count +1; if (xArray[index]>target) max=index-1; else min=index+1; index=(max+min)/2; } if (xArray[index] == target) { cout << "Target found at " << index<< endl; cout << "It took " << count << " tries to find the number "; } else cout << "Target not found. "; cout << endl; char mine[30]; cin.getline(mine,100,'\n'); cin.ignore(100, '\n'); } |
Making a circularly linked list: Click here for the program's source file. This program shows how to dynamically allocate memory and how to use pointers to make a linked list data structure.
|
#include <iostream> //Change here is to output several letters chained #include <stdlib.h> using namespace std; //together using traditional structure notation struct node //notice how each new letter is linked to the previous { //letter so the first letter in becomes the last in the char letter; //actual list, so the letters get reversed in the list node *link; }; void main() { //head only needed if a loop is used to output the data in the linked list node *head =NULL; //each node is attached to another node called its head node *p, *q, *r; //except the very (or the head of the heads) which is attached //to nothing p=new node; //here the head attached to null (the front of the chain is p p->letter='m'; p->link=NULL; //head not linked to anything head =p; cout << p->letter <<endl; //output is m //************ now add a new node, p is still where it was the new node becomes //the new head q = new node; q->letter='i'; q->link=p; //the letter i is linked to the letter m head=q; //this letter becomes the new head cout << p->letter << " " << q->letter<<endl; //************ r=new node; r->letter='j'; r->link=q; head=r; cout << p->letter<< " " <<q->letter<<" "<<r->letter<<endl; //This is the circular part: //link the nose to the tail: p->link=r; //************* //mechanism to report the contents of the linked list //processing the nodes of a list in order is called transversing; //here done with a loop char ans=' '; head=r; while (head != NULL) //starts at the end { cout<< "\nDo you wish to see an item in the linked list (y/n): "; cin >>ans; system("cls"); if (ans=='n') break; cout << head->letter; //outputs a letter head=head->link; //shifts the head to the next letter } //so it can be examined in the chain cout << endl; //*************** } |
How to take command line parameters: Click here to download the source and makefiles in this project. The intent of this program is to show how the various parameters after the command line can be read and interpreted effecting the flow of the program itself. Here argc stores the number of parameters after typing the name of the executable file (minus one) and argv is an array of char arrays which store all the parameters. This program detects if a parameter is a number, provided the first character of a char array suggests the rest of the elements in the array make up a number. This method will work with positive integers. First, encode the following source file and compile it. Run the executable at the command line as shown in the console screen below.
|
#include <iostream> using namespace
std; int
main( int argc, char **argv ) { //for taking command line arguments bool numFound=false; char myCharArray[10];
int x=argc;
int
y;
cout <<"You
entered "<<x-1
<<" parameters after the command
\"commandLine.\""<<endl; cout <<"They
were: "; for (int
i=1; i<x; i++) {
strcpy(myCharArray, argv[i]);
cout <<myCharArray<<" ";
} cout<<endl; for (int
i=1; i<x; i++) {
strcpy(myCharArray, argv[i]);
if(isdigit(myCharArray[0]))
{
if(numFound==false)
cout<<"The
number(s) you entered were: ";
numFound=true;
y=atoi(argv[i]);
cout <<y<<"
";
} } cout <<endl; } |
Sample output:
|
C:\>commandline My monkey has fleas 3 7 |
Making and Compiling a Class File in the Linux Environment. Click here to download the source and makefiles in this project.
This program was made in Knoppix, a bootable form of Linux which can be booted from a CDROM on a IBM Compatible PC. Bootable Knoppix interact with the hard drive at all. It runs completely from ram and allows you to send files to yourself via email through built in browsers like Firefox which are automatically configured to detect the internet if on a network. It also allows you to save to a USB flash drive.
To make a class in Linux, first create the files made below, respectively named copyMachineDriver.cpp, copyMachine.h, and copyMachine.cpp. These files are respectively the driver, the header and the implementation file. They are easily made in Kate, an editor with a console window built in, available in Knoppix. The class files are intentionally made to be very simple. A word to the wise. At the end of each of the files, hit your line return and give an extra line feed. Linux may give a warning if you don't give this extra line feed.
Within the console window type the following:
g++ copyMachineDriver.cpp copyMachine.h copyMachine.cpp -o copyMachineDriver.o
If you type the Linux command, ls, in the console you should now see a copyMachineDriver.o executable file present in the folder. To run this copyMachineDriver.o type:
./copyMachineDriver.o
|
// copyMachine.cpp Driver File #include <iostream> #include "copyMachine.h" using namespace std; int main() { //cout <<"hello"<<endl; copyMachine cM; cM.makeCopy(); return 0; } // Output looks like // One copy made! // That will be $.25 |
|
//copyMachine.h header file #include "copyMachine.h" #include <iostream> using namespace std; copyMachine::copyMachine() { //default constructor...nothing in the parameter } void copyMachine::makeCopy() { cout<< "One copy made!"<<endl; cout<< "That will be $.25"<<endl; } |
|
//copyMachine.cpp implementation file #include "copyMachine.h" #include <iostream> using namespace std; copyMachine::copyMachine() { //default constructor...nothing in the parameter } void copyMachine::makeCopy() { cout<< "One copy made!"<<endl; cout<< "That will be $.25"<<endl; } |
A second way of compiling the file is to make a Makefile. Make the following Makefile using Kate and save the file as “Makefile”. In Linux, naming files is very case sensitive so you must name things just as they are written here.
|
copyMachine: copyMachine.o g++ copyMachineDriver.cpp copyMachine.h copyMachine.cpp -Wall -o copyMachine.o |
To use the Makefile to create the executable file, all you need to do is go to the Linux console and type:
make copyMachine |
π ( PI) to 14 places behind the decimal. This program outputs an estimate of π to 14 places behind the decimal using the cmath function and setprecision to show 15 significant figures. Click here for the program's source file. To see the first 10,000 significant digits of PI visit http://www.joyofpi.com/pi.html.
#include <iostream> #include <iomanip> #include <cmath> using namespace std; double pi(); int main() { cout <<setprecision(15)<<pi()<<endl; } double pi() { return acos(-1); } |
Color in Console programs. Click here for the program's source file. Adapted from Michael Watson’s Work (a computer science student at Casper College). This program will only work in the windows environment. Below back colors are multiples of 16 and fore colors are 1 through 16, such that if the Constant Red=12 and the Constant Blue equaled 9 putting a Red Forecolor on a Blue Back color would be equal to (12+9*16). Because we are using constants in the following program we can refer to the value of 12 as RED and 9 as BLUE, so we can code a RED fore color on a BLUE back color as (RED+BLUE*16).
The program looks as follows when it runs:
The Source Code:
#include <iostream> #include <windows.h> // Used to provide support for //changing screen colors. using namespace std; //constants below make it easier to identify colors const int BLACK = 0; const int DARK_BLUE = 1; const int DARK_GREEN = 2; const int DARK_CYAN = 3; const int DARK_RED = 4; const int DARK_MAGENTA = 5; const int DARK_YELLOW = 6; const int DARK_WHITE = 7; const int GRAY = 8; const int BLUE = 9; const int GREEN = 10; const int CYAN = 11; const int RED = 12; const int MAGENTA = 13; const int YELLOW = 14; const int WHITE = 15; int main() { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole,YELLOW); //can use the numbers 1 through 15 cout <<" "<<"\1"<<endl; SetConsoleTextAttribute(hConsole,GREEN); cout <<" "<<"/"; SetConsoleTextAttribute(hConsole,RED); cout <<"|"; SetConsoleTextAttribute(hConsole,BLUE); cout <<"\\"<<endl; SetConsoleTextAttribute(hConsole,MAGENTA); cout <<" "<<"/"; SetConsoleTextAttribute(hConsole,CYAN); cout <<" \\"; //SetConsoleTextAttribute(hConsole,WHITE); cout <<endl; //Formula for Fore Color and Back Color: (F + B*16) Where F and B are Colors 1-15 //where F stands for forecolor and B stands for Backcolor //Example SetConsoleTextAttribute(hConsole,4+15*16); //DARK red on White... cout <<"hi"; //red on blue since 12 is red (forecolor) and 9 is blue in colors SetConsoleTextAttribute(hConsole,MAGENTA+YELLOW*16); //Magenta FC Yellow BC cout <<"how"; SetConsoleTextAttribute(hConsole,RED+GREEN*16); //Red FC Green BC cout<< " are"; SetConsoleTextAttribute(hConsole,DARK_RED+BLUE*16); //DARK Red FC Blue BC cout<<" you"; SetConsoleTextAttribute(hConsole,GREEN+RED*16); //GRAY FC DARK_GREEN BC cout<<"?"<<endl; SetConsoleTextAttribute(hConsole,WHITE+BLACK*16); //White FC Black BC cout <<endl; //SetConsoleTextAttribute(hConsole,WHITE); cout <<endl; //Formula for FC and BC: (F + B*16) Where F and B are Colors 1-15 //where F stands for forecolor and B stands for Backcolor } |
A Function that Rounds to However Many Places You Specify. This program rounds to however many places you specify (provided it is 15 of less significant digits). Click here for the program's source file.
#include <iostream> #include <iomanip> //used to see precision #include <sstream> //used for the stringstream object using namespace std; double round(double d, int n); int main() { double mydecimal; int numPlaces; cout <<"Enter a decimal: "; cin>>mydecimal; cout<<"Number of places significant figures rounded to (15 or less): "; cin>>numPlaces; cout<<setprecision(16)<<round(mydecimal, numPlaces)<<endl; return 0; } double round(double d, int n) //d is number to round, // n is number of places { double number=0.; stringstream s; //object requires #include <sstream> s << setprecision(n) <<d; //rounds to 12 places, setpre- //sion requires #include <iomanip> s >>number; return number; }
|
A Console Based Pong Game With Sound This is a rough DOS based pong game which also has sound effects to run in the WindowsXP environment. It is sort of exciting in that it is a giant step...backwards in time. Click here for the program's project, source and sound files in MSVC 2008 and here for the project, source and sound files for either the Borland or Dev++ compilers. This source will compile with no linker changes in the Borland 5.5 compiler. The program uses asynchronous keys. The A and Z keys control up and down for the left paddle, the up and down arrow control the right paddle. Yes, 2 players on one machine. The space bar releases a new ball and the escape key quits out of the program. It uses primitive colors, sound effects, and sizes the window. Thanks to Michael Watson for his assistance in putting this one together. Read below on how to configure your compiler to link with the necessary sound files for Borland, Dev C++, and MSVC++.

The tricky part is configuring your IDE to run sound. The Borland 5.5 free compiler will run the following program without any configuration of the linker, simply follow the instructions under the methods CheerSound(), Bong() and PaddleHit(). Microsoft Visual C++ requires gdi32.lib and winmm.lib to be linked into the project for sound. Typically gdi32.lib is already included by default. To add winmm.lib in Microsoft Visual C++2008 environment first go to Project and selecting Properties as shown below:

Then select Configuration Properties>Linker>Command line> and under Additional Options type winmm.lib as shown below and the code should compile. Make sure that gdi32.lib is included in the parameter under "All Options" or you will have to add it too.

If using the free Bloodshed or Dev C++ compiler select Project>Project Options as shown below.

Then select Parameters and under parameters add -lwinmm and -lgdi32 under linker as shown below.

The Source is as follows. To run in either Borland or Dev C++ modify the CheerSound(), Bong() and PaddleHit() methods as outlined in the methods themselves and rem out the MSVC methods. To run in MSVC include the "stdafx.h" header and rem out the Borland/Dev C++ lines in CheerSound(), Bong() and PaddleHit(). Below the program is presented to run in Borland/Dev C++. If you like it let me know what you think:
//Place the sound files in the same directory as the executable: //bounce.wav pop.way, cheer.wav //The A and Z are the controls for the left paddle, the up and down arrow //are for the right paddle. The space bar releases a new ball and the escape //key quits out of the program. It uses colors and sizes the window //by Jim Krumm and assistance from Michael Watson //#include "stdafx.h" //Unremark For Studio 2008 #include <stdlib.h> #include <iostream> #include <time.h> //for random stuff #include <windows.h> #include <MMSystem.h>
//libraries //dev c++ needs //-lwinmm //-lgdi32
//(vc++ needs): //Winmm.lib //gdi32.lib ...usually built in
#include <stdio.h> #include <string.h> using namespace std;
//next is for asynchronous keys detection #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0 )
const int BLACK = 0; const int DIM_BLUE = 1; const int DIM_GREEN = 2; const int DIM_CYAN = 3; const int DIM_RED = 4; const int DIM_MAGENTA = 5; const int DIM_YELLOW = 6; const int DIM_WHITE = 7; const int GRAY = 8; const int BLUE = 9; const int GREEN = 10; //A const int CYAN = 11; //B const int RED = 12; //c const int MAGENTA = 13; //D const int YELLOW = 14; //E const int WHITE = 15; //F
void gotoxy(int, int); //(79, 24) void drawPaddle(int x, int y); void drawBall(int x, int y); int newDirection(); void NewGame(int &x, int &y,int &direction); void setScreenSize(); void determineXYChange(int direction,int &xChange,int &yChange); void boing( ); void PaddHitSound(); void CheerSound();
int main() {
int player2Score=0; int player1Score=0; double ballSpeed=1; int x=0; int y=0; int yChange=0; int xChange=0; int direction; bool gameover=true; int paddleLeftx=3; int paddleLefty=18; int paddleRightx=75; int paddleRighty=18; HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); setScreenSize(); x=42; //balls location y=18; direction=newDirection(); //***************** SetConsoleTextAttribute(hConsole,WHITE); gotoxy(10,40); cout <<"Player 1: "; gotoxy(60,40); cout <<"Player 2: "; gotoxy(20,40); cout <<player1Score; gotoxy(70,40); cout <<player2Score; //**************** while(1<2) { /* if (KEY_DOWN(VK_LEFT)) //works just don't need it { /detect left arrow key gotoxy(0,0); cout <<"left"; } if (KEY_DOWN(VK_RIGHT)) { //detect right arrow key gotoxy(0,0); cout <<"right"; } */ if (KEY_DOWN(65) ) //A key (65 ascii for A) { //left paddle goes up...detect A if(paddleLefty>0) paddleLefty=paddleLefty-1; } if (KEY_DOWN(90) ) //A key (65 ascii for Z) { //left paddle goes down...detect Z
if(paddleLefty<36) paddleLefty=paddleLefty+1; } if (KEY_DOWN(VK_UP)) { //right paddle goes up detect up arrow if(paddleRighty>0) paddleRighty=paddleRighty-1; } if (KEY_DOWN(VK_DOWN)) { //right paddle goes down, detect down arrow if(paddleRighty<36) paddleRighty=paddleRighty+1; } if(KEY_DOWN(VK_ESCAPE)) { //quit if escape key hit return 0; } if (KEY_DOWN(VK_SPACE)) { //send new ball out after last game SetConsoleTextAttribute(hConsole,BLACK); NewGame(x, y, direction); gameover=false; } //****************************************** //determine change in x and y of a ball for a specific direction determineXYChange(direction, xChange,yChange);
//****************************** //if ball hits the top of the screen have it bounce off in the right direction if(y<2) { if (direction==158) direction=203; if (direction==135) direction=225; if (direction==113) direction=248; if (direction==68) direction=293; if (direction==45) direction=315; if (direction==23) direction=338; //if (gameover==false) //uncomment for sound if ball is in play boing(); y=4; //bring back far enough don't get a double bouce from sound } //********************* //if ball hits the bottom of the screen have it bounce off in the right direction if(y>36) { if (direction==203) direction=158; if (direction==225) direction=135; if (direction==248) direction=113; if (direction==293) direction=68; if (direction==315) direction=45; if (direction==338) direction=23; y=34; //bring back far enough don't get a double bouce from sound //if (gameover==false) //uncomment for sound if ball is in play boing(); } //*************************** y=y+(int)(ballSpeed*yChange); x=x+(int)(ballSpeed*xChange); //cout <<"x="<<x<<" y="<<y<<" "<<"xChange="<<xChange<<"yChange="<<yChange<<endl; //system("pause"); SetConsoleTextAttribute(hConsole,GREEN); drawPaddle(paddleLeftx,paddleLefty); drawPaddle(paddleRightx,paddleRighty); //*************************** //detect left paddle if(paddleLeftx >x && paddleLeftx<=x+4) { if(paddleLefty-1 == y) { direction =68; x=paddleLeftx+2; PaddHitSound(); //uncomment for sound } if(paddleLefty == y) { direction =45; x=paddleLeftx+2; PaddHitSound(); } if(paddleLefty+1 == y) { direction =23; x=paddleLeftx+2; PaddHitSound(); } if(paddleLefty+2 == y) { direction =0; x=paddleLeftx+2; PaddHitSound(); } if(paddleLefty+3 == y) { direction =338; x=paddleLeftx+2; PaddHitSound(); } if(paddleLefty+4 == y) { direction =315; x=paddleLeftx+2; PaddHitSound(); } if(paddleLefty+5 == y) { direction =293; x=paddleLeftx+2; PaddHitSound(); } } //******************** //detect right paddle if(paddleRightx <x && paddleRightx>=x-4) { //the following code divides up the paddle into regions and //causes the ball to bounce in different directions dependent //where it hits the paddle if(paddleRighty-1 == y) { direction =113; //113 is in degrees ; x=paddleRightx-2; PaddHitSound(); } if(paddleRighty == y) { direction =135; x=paddleRightx-2; PaddHitSound(); } if(paddleRighty+1 == y) { direction =158; x=paddleRightx-2; PaddHitSound(); } if(paddleRighty+2 == y) { direction =180; x=paddleRightx-2; PaddHitSound(); } if(paddleRighty+3 == y) { direction =203; x=paddleRightx-2; PaddHitSound(); } if(paddleRighty+4 == y) { direction =225; x=paddleRightx-2; PaddHitSound(); } if(paddleRighty+5 == y) { direction =248; x=paddleRightx-2; PaddHitSound(); } } //******************** //determine balls next move if (x<0 && gameover==false) //||x>79) { //do not drawball if it goes off screen gameover=true; player2Score++; CheerSound(); //Uncomment for sound
} if (x>79 && gameover==false) //||x>79) { //do not drawball if it goes off screen gameover=true; player1Score++; CheerSound(); } if(x >0 && x<79 && gameover !=true) { SetConsoleTextAttribute(hConsole,WHITE); drawBall(x, y); //draw only if ball is somewhere between left edge and right edge } SetConsoleTextAttribute(hConsole,WHITE); gotoxy(70,40); cout <<player2Score; gotoxy(20,40); cout <<player1Score; //************************************ Sleep(70); //keep ball on screen 50 milliseconds so you can see it //system("cls"); //then clear SetConsoleTextAttribute(hConsole,BLACK); //draw black over old ball (old one disappears) drawBall(x, y); //find new coordinate for ball drawPaddle(paddleLeftx,paddleLefty); drawPaddle(paddleRightx,paddleRighty); SetConsoleTextAttribute(hConsole,WHITE); //draw a white ball gotoxy(10,40); cout <<"Player 1: "; gotoxy(60,40); cout <<"Player 2: "; } //closes while loop return 0;
} int newDirection() { //choose a new direction int r; int direction; r=(int)(rand()%14)+1; //pick a number 1-14 if(r==1) direction=0; if(r==2) direction=23; if(r==3) direction=45; if(r==4) direction=68; if(r==5) direction=113; if(r==6) direction=135; if(r==7) direction=158; if(r==8) direction=180; if(r==9) direction=203; if(r==10) direction=225; if(r==11) direction=248; if(r==12) direction=293; if(r==13) direction=315; if(r==14) direction=338; return direction; } void determineXYChange(int direction,int &xChange,int &yChange) { if(direction==338) { xChange=2; yChange =1; } if(direction==315) { xChange=2; yChange =2; } if(direction==293) { xChange=1; yChange =2; } if(direction==270) { xChange=0; yChange =3; } if(direction==248) { xChange=-1; yChange =2; } if(direction==225) { xChange=-2; yChange =2; } if(direction==203) { xChange=-2; yChange =1; } if(direction==180) { xChange=-3; yChange =0; } if(direction==158) { xChange=-2; yChange =-1; } if(direction==135) { xChange=-2; yChange =-2; } if(direction==113) { xChange=-1; yChange =-2; } if(direction==90) { xChange=0; yChange =-3; } if(direction==68) { xChange=1; yChange =-2; } if(direction==45) { xChange=2; yChange =-2; } if(direction==23) { xChange=2; yChange =-1; } if(direction==0) { xChange=3; yChange =0; } }
void drawBall(int x, int y) { gotoxy(x,y); cout <<(char)219;//<<'o'; } void setScreenSize() { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO screenBufferInformation; GetConsoleScreenBufferInfo(hConsole,&screenBufferInformation); SMALL_RECT myWindow = {0, 0, 0, 0}; myWindow.Right = 79; myWindow.Bottom = 40; SetConsoleWindowInfo(hConsole,TRUE,&myWindow);
} void drawPaddle(int x, int y) { gotoxy(x,y); cout <<(char)219; gotoxy(x,y+1); cout <<(char)219; gotoxy(x,y+2); cout <<(char)219; gotoxy(x,y+3); cout <<(char)219; gotoxy(x,y+4); cout <<(char)219; } void NewGame(int &x, int &y,int &direction) { x=42; y=18; drawBall(x,y); direction=newDirection(); } void gotoxy(int x, int y) { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); COORD position = {x,y}; SetConsoleCursorPosition(hConsole,position); }
void boing() //put bounce.wav, pop.wav and cheer.wav in the source code { // or executable directory char* mySound = "bounce.wav"; //needed for borland or Dev C++ sndPlaySound(mySound, SND_ASYNC); //needed for borland or Dev C++ //sndPlaySound(mySound, SND_ASYNC); //playSound causes a slight delay in screen //so don't use the next line //PlaySound(L"bounce.wav", NULL, SND_FILENAME | SND_SYNC); //works good with msvc++ //but causes a time delay //better method: //sndPlaySound(L"bounce.wav", SND_ASYNC); //needed for msvc++ }
void PaddHitSound() { char* mySound = "pop.wav"; //needed for borland or Dev C++ sndPlaySound(mySound, SND_ASYNC); //needed for borland or Dev C++ //sndPlaySound(L"pop.wav", SND_ASYNC); //needed for msvc++ } void CheerSound() { char* mySound = "cheer.wav"; //needed for borland or Dev C++ sndPlaySound(mySound, SND_ASYNC); //needed for borland or Dev C++ //sndPlaySound(L"cheer.wav", SND_ASYNC); //needed for msvc++ }
|
©All rights reserved by James Krumm. Originally made available at www.caspercomsci.com. Materials here can be used, and redistributed, provided proper reference is made to the origin and author(s) of these materials. Please send any corrections or suggestions to jkrumm@caspercollege.edu. Last modified Oct. 11, 2009.
To find out more about the
James Krumm |