tribhuvan university institute of ... -...

52
TRIBHUVAN UNIVERSITY INSTITUTE OF ENGINEERING PULCHOWK CAMPUS A REPORT ON NINJA GAME 1st YEAR MINI PROJECT SUBMISSION DATE: 2070-12-3 (March 17 th , 2014) Submitted By Submitted To Department of Electronics & Computer Engineering Sandesh Pandey 070 BCT 538 Saujanya Acharya 070 BCT 541 Saroj Niraula 070 BCT 540

Upload: vanhanh

Post on 04-Apr-2018

236 views

Category:

Documents


5 download

TRANSCRIPT

TRIBHUVAN UNIVERSITY INSTITUTE OF ENGINEERING

PULCHOWK CAMPUS

A REPORT ON NINJA GAME

1st YEAR MINI PROJECT

SUBMISSION DATE: 2070-12-3 (March 17th, 2014)

Submitted By

Submitted To

Department of Electronics & Computer

Engineering

Sandesh Pandey 070 BCT 538 Saujanya Acharya 070 BCT 541

Saroj Niraula 070 BCT 540

2

Acknowledgement

We would like to take our opportunity to express our profound gratitude and deep regards to our mentor Mr. Baburam Dawadi, our C-Programming teacher, for his exemplary guidance, monitoring and constant encouragement throughout the course of preparation of this project.

We also take this opportunity to express deep sense of gratitude to the active members of online Q&A site ‘stackoverflow’ and users from ‘reddit’ for helping us during our project development through valuable information and guidance. Also, we are highly indebted to our colleagues and seniors who helped us with various parts of the project.

Lastly, our appreciation also goes to our family, friends, brothers and sisters for their constant encouragements without which the completion of the project would have been impossible.

3

Contents

Abstract of the Project ........................................................................... 4

Background ............................................................................................. 5

Problem Analysis .................................................................................... 6

Algorithm & Flowchart ........................................................................... 7

Output Snapshot .................................................................................. 30

Testing and Debugging ......................................................................... 33

Discussion and Conclusion ................................................................... 34

Annex.................................................................................................... 35

4

Abstract of the Project “Ninja Game” is a project basically written to be submitted to the Department of Electronics and Computer Engineering, Pulchowk Campus under the course of C Programming for the 1st semester of Bachelors of Computer Engineering. The target of the project is to implement the basic techniques and implementation of C Programming concepts taught throughout the semester.

The Project’s (“Ninja Game”) source code was written, compiled, tested and debugged using a popular IDE “Codeblocks v13.11”. Our knowledge in the programming concepts such as functions, strings, arrays, loops, pointers and file handling were implemented throughout the project.

“Ninja Game” as the name suggests, is a multiplayer, turn-based artillery game. It consists of two ninjas throwing ‘Shuriken’ (or ninja stars) at each other. The player can adjust the velocity and projection angle of the star as per the conditions that the game generates. Hence, the objective for a player of this game is to strike their opponent with a ‘Shuriken’ and decrease their lives and ultimately win the game.

The game was made completely devoid of graphics library and solely made out of symbols using Codeblocks IDE. So, it was always a challenge to apply the graphical aspects of the game i.e. displaying the characters (ninjas) and the movement of the ‘Shuriken’ (ninja star). The game’s Display consists of basically three major parts, i.e. ninjas, buildings and animated movement of ninja star. As the game is opened, it asks the users to input their names and number of lives they want to play for. Once the game proceed it displays buildings of random height and ninjas above random buildings then user has to input the velocity and angle of projection for their ‘Shuriken’. If the ‘Shuriken’ hits the opponent their life decreases and ultimately the one who is able to reduce the opponent’s life to zero, wins.

Coding Hundreds of lines, testing and debugging was never an easy job, however, we got the chance to learn about different aspects of programming and various techniques we could apply to make programming more efficient.

Finally, this report gives a detailed description of our project, about how we divided our work load and how we worked upon the game. The Core idea of the project was to learn the concepts of programming and problem solving using C-Programming Language which, in my opinion, was covered pretty well by us.

5

Background

Our Project “Ninja Game” started as a 1st Semester Mini-Project on C-Programming. The main objective of the project was to understand and implement various programming tools available in C Programming language. We completed our project using the CodeBlocks IDE v13.11. That means our project was coded, tested and debugged using CodeBlocks. Throughout the development phase of the project we were mainly focusing upon using most of the programming tools in order to make the code efficient and more understandable.

The game is basically a turn-based artillery game especially designed for multiplayer mode. The user, who appears as a ninja in the game, must destroy the lives of opposing ninja using a ‘Shuriken’ or a ninja star by predicting its angle of projection and launching velocity. Once a ninja star hits its opponent his/her life decreases and the game regenerates random conditions. Finally after destroying all the lives of the opponent the user wins the game.

A lot of hard work has gone into the making of this game. Although the game looks pretty mediocre with no use of graphics, the concept and the logic applied during the coding is pretty complex. As it was our primary objective to understand the tools of C-Programming, we think that we have completed our task.

However, this being our first project has numerous of points for improvement. Issues such as the pixilated game graphics, flickering of the screen during gameplay, and animation of the ‘Shuriken’ etc could have been improved through use of various graphics libraries available, but due to number of limitations we had to complete and submit the project with such issues.

6

Problem Analysis

For properly writing and completing a useful program, we had to observe various possibilities and obstacles we could come over during the program development. Also we had to properly plan the structure of the program.

The game is programmed such that it prompts the user to input their names and number of lives they want to play for. The input is taken simply in integers to maintain the simplicity of the program. The program must not take redundant inputs such as alphabets and symbols; hence the program was designed that way. Once the game proceeds, the characters and buildings must be randomly generated and it must ask the player, in turn-basis, to input the velocity and angle of projection for the ninja star. The velocity is taken as input in real number system and is set as the velocity for projection of the ninja star. The program angle of projection in input in real number system in radian measures which is converted into degrees by the program for the calculation of the path of ninja star. After the players inputs the required parameters, the game must calculate the path of the ninja star and display the animated movement of the ninja star along with the path it follows until it completes its projectile path. If the ninja star hits another player it must display that it hit another player otherwise it must display that it was a mishit.

The program must generate buildings and ninja characters in random spaces after each exact hit. The buildings are created with properly managed and displayed symbols and special characters. Similarly, the ninja characters are also created by proper display of properly organized symbols and special characters and the game must continue as before. After a player has lost all of his/her lives the game must display that the other player has won and must exit the game.

7

Algorithm & Flowchart Main Program The game is divided into different modules according to its functionality. But the main concept of the game is straight forward, as:

Step 1. Start Step 2. Display Menu Step 3. Ask for Player Name Step 4. Ask for number of lives Step 5. Begin the game Step 6. Generate buildings with random height Step 7. Generate character in random position Step 8. Read angle of projection Step 9. Read velocity Step 10. Show the path of star Step 11. a) If star hit opponent

Reduce opponent's life If opponent's life is 0, show congratulation message to current player Else, change turn and go to step 5 b) Else, change turn and go to step 8

Step 12. Stop

Flowchart

8

main.c

The file main.c contains codes to display title, menus, and perform task according to the menu chosen by the user. The title is the sequence of ASCII characters stored in the form of text file. It is displayed in the screen with the help of file handling functions. The user defined header file "game.h" is included in this file. Here coordinate system is used according to the size of screen. As the screen consists of 73 characters in one line and 20 lines in total, the total size of screen is 73 by 20. One unit in x direction is equivalent to one character whereas one unit is y direction is equivalent to one line. Following functions are defined in this file: int main(void) Algorithm

Step 1. Start Step 2. Call printScreen() Step 3. Call displayTxt ("title.txt", 17, TOP+4) Step 4. Pause for 3 secs Step 5. Call getMenu() Step 6. Stop

Flowchart

Start

Call printScreen()

Call displayTxt ("title.txt", 17, TOP+4)

Pause for 3 secs

Call getMenu()

Stop

9

void displayTxt(char title[],int x, int y ) This function displays the contents of provided text file in the given position x, y of the screen. Algorithm

Step 1. Entry Step 2. Define character file_name Step 3. Assign file_name=title Step 4. Open file file_name Step 5. Call gotoxy(x,y) Step 6. Display content of file Step 7. Close file Step 8. Exit

Flowchart

Define character file_name

Assign file_name=title

Open file file_name

Call gotoxy(x,y)

Display content of file

Close file

void getMenu(void)

It displays the menu items and perform task according to the menu chosen by the user. Algorithm

Step 1. Entry Step 2. Call function displayTxt("Heading.txt", 23, TOP+2)

10

Step 3. Display 1: Single Player 2: Multi Player 3: Exit

Step 4. Declare integer a Step 5. Assign user inputted number to a Step 6. Call function chooseMenu(a) Step 7. Exit

Flowchart

displayTxt("Heading.txt", 23, TOP+2)

Declare integer a

Assign user inputted number

to a

chooseMenu(a)

Display1: Single Player2: Multi Player

3: Exit

void chooseMenu(int a) Perform task according to the menu chosen by the user. Algorithm

Step 1. Entry Step 2. If a==1 Step 3. Call function start(1) Step 4. Else if a==2 Step 5. Call function start(2) Step 6. Else if a==3 Step 7. Exit program Step 8. Exit

11

Flowchart

If a==1

If a==1

F

If a==1

F

start(1)T

start(2)T

Exit programT

getInput.h This header file consists of three functions for taking the input of integer, float and string from user. float floatNum (int length, int minimum) This function allow user to input only the float number from the keyboard. Any other input will be discarded.

Step 1. Entry Step 2. Declare float num=0 Step 3. Declare Character a Step 4. Assign user input to a Step 5. If a is number, add it to num Step 6. Else if a is '.' and '.' is not displayed before, display a Step 7. If '.' is displayed and a is number, add a as fractional part to num Step 8. If a==8 (backspace)

If '.' is entered Delete fractional part of num Else Delete digit from once position of num

Step 9. If a!= return or num<minimum, go to step 4. Else to step 10 Step 10. return num Step 11. Exit

12

Flowchart

Declare float num=0

Declare Character a

Assign user input to a

If a is number

If a is '.'

F

If '.' is displayed

T

add a as integer to

numF

add a as fractional

part to numT

T

If a==8

F

If '.' is entered

T

Delete fractional

part of numT

Delete digit from once position of

num

F

If a!= return or num<minimum

F

If '.' is not displayed Display aT

Return num

F

T

int intNum (int length, int minimum) It is similar to the function floatNum(), but is take only integer value.

Step 1. Entry Step 2. Declare integer num=0 Step 3. Declare Character a Step 4. Assign user input to a Step 5. If a is number, add it to num Step 6. If a==8 (backspace), delete digit from once position of num. Step 7. If a!= return or num<minimum, go to step 4. Else to step 8

13

Step 8. return num Step 9. Exit

Flowchart

Declare integer num=0

Declare Character a

Assign user input to a

If a is number

If a==8

F

If a!= return or num<minimum

F

return num

F

T

Add a to numT

delete digit from once position of num

T

14

char charWord (char letters[]) It takes the string containing only characters as the input from user and store in array letters. Any other key pressed will be discarded.

Step 1. Entry Step 2. Declare Character a Step 3. Assign user input to a Step 4. If a is alphabet, add it to letters Step 5. If a==8 (backspace), delete last character from letters[] Step 6. If a!= return or length of letter is>0, go to step 3. Else to step 7 Step 7. Exit

Flowchart

Declare Character a

Assign user input to a

If a is alphabet

If a==8

F

If a!= return or length of letter is>0

F

add a to lettersT

delete last character from letters[]

T

T

F

15

game.h All the functions directly related to game is kept in module "game.h". It also include user defined header file "getInput.h" The function contains following definitions: PI=3.1415 defines the value of pi. SCREENX=73 defines the total width of screen SCREENY=20 defines the height of screen TOP=4 denotes the top spacing LEFT=3 denotes the left spacing There are few global variables: charHeight=6 (Height of the character) charWidth=5 (Width of the character) g=9.8 (value of acceleration due to gravity) totalLife=3 len (Total length of screen in meters) unit (Length equivalent to one character position) bHeight[6] (Array containing height of each building) bWidth=12 (Width of each building) tmpAng, tmpVel (Help to determine angle and velocity during single player mode) The functions defined in the header file are: void gotoxy(int x, int y) This sets cursor in given x and y position of screen. void printScreen(void) This function creates the boarder around the screen and defines the area of the screen.

Step 1. Entry Step 2. Loop from top-left corner to top-right corner

Display character '-' Step 3. Loop from top-left corner to bottom-left corner

Display character '|' Step 4. Loop from top-right corner to bottom-right corner

Display character '|' Step 5. Loop from bottom-left corner to bottom-right corner

Display character '-' Step 6. Exit

16

void details(char *p1, char *p2) This function ask user to input details like player name and total number of life. Here the arguments p1, p2 and total life are passed by reference so that it can be modified by the function.

Step 1. Entry Step 2. Read first player's name Step 3. *p1=First player's name Step 4. Read second player's name Step 5. *p2=Second player's name Step 6. Read total life Step 7. Exit

Flowchart int building(int x, int index) This function generates building of random height. It also limits the height of first and last building to 8 lines and second and second last building to 10 lines. Other buildings can have maximum height of 13 lines. The value of index ranges from 0 to 5 that represent the building number.

Step 1. Entry Step 2. Declare integer height=RANDOM()%10+3 Step 3. If (index==0 OR index==5)

If height>8 height -= (height%8)

Step 4. If (index==1 OR index==4) If height>10 height -= (height%10)

Step 5. Declare integer y=TOP+SCREENY-height Step 6. gotoxy(x,y) Step 7. Display building

17

Step 8. Return height Step 9. Exit

Here, x and y represent the top left position of the building. Other positions are obtained accordingly. Flowchart

18

void town(void) This function generates the town i.e. six buildings in the scene. Also, height of each building is stored in the array bHeight.

Step 1. Entry Step 2. Declare integers x and i Step 3. Assign x=LEFT+1 and i=0 Step 4. bHeight[i]= building(x,i) Step 5. x += bWidth Step 6. i++ Step 7. If x<(LEFT+SCREENX)

goto step 4 Else goto step 8

Step 8. Exit Flowchart void charPosition(int *x, int *y, int player) This function randomly generates the position of character within the screen and saves it in variable x and y. As, the function have to return two values for x position and y position, it makes use of call by reference feature of C. Here we have to make sure that the characters are not on middle of two buildings and are on the top of building.

19

Step 1. Entry Step 2. If player=1

*x = LEFT + 1 + (RANDOM () %2)*bWidth + RANDOM () %6 Else *x=LEFT+SCREENX-(RANDOM () %2)*bWidth- RANDOM ( ) %6-6

Step 3. Declare integer j Step 4. If *x/bWidth is NOT integer

j = (*x/bWidth) Else j = (*x/bWidth)-1

Step 5. *y=TOP+SCREENY-charHeight-bHeight[j]; Step 6. Exit

Flowchart void printChar1(int x, int y) and void printChar2(int x, int y) These functions display character in the given position. Two integers x and y denotes the top left position of these characters. Here the cursor is set into the given coordinate by the user defined function 'gotoxy()' and print the portion of the character there and again goes to next positon and so on.

20

void printLife(int hit, int player, char name[]) It displays the total remaining life of each player.

Step 1. Entry Step 2. Declare integer x Step 3. If player=1, x= (LEFT+1, 1)

Else, x=(LEFT+SCREENX-15) Step 4. gotoxy(x,1) Step 5. Display name[] Step 6. life = totalLife-hit Step 7. gotoxy(x,2) Step 8. Display life Step 9. Exit

void request(float *ang, float *vel, int player) It request player to enter angle and velocity for the projection of star. Here parameters are passed by reference as we need to replace its current value by the one inputted by the user. Here argument for player defines where to show the request box and also help in angle conversion.

Step 1. Entry Step 2. Declare float deg Step 3. Read deg Step 4. If player=1, ang=toRad(deg)

Else, ang=PI-toRad(deg) Step 5. Read vel Step 6. Exit

Flowchart Y N

21

void message(char text[], int x, int y) This is a simple function to display the message in the given position. It takes three arguments. text[] is the array of characters or basically string to be displayed. Integers x and y specifies where to display the message in screen. After displaying the message it pauses for 3 seconds and clears the message.

Step 1. Entry Step 2. gotoxy(x,y) Step 3. Display text[] Step 4. Pause for 3 secs Step 5. gotoxy(x,y) Step 6. Integer i=0 Step 7. Print blank space i.e. ' ' Step 8. i++ Step 9. If i<srting length, goto step 7

Else goto step 10 Step 10. Exit

float toRad(float deg) This function takes the angle in degree as argument, convert it into radian and return the converted number. It is useful for the proper operation of function sin() defined in math.h which takes radian angle as its argument.

Step 1. Entry Step 2. Declare float rad Step 3. rad = (deg*PI)/180 Step 4. return rad Step 5. Exit

Flowchart

22

float height(float vel, float ang, float dist) This function calculates the height of projectile for given value of velocity, angle and distance from the point of projection.

Step 1. Entry Step 2. Declare float h Step 3. h= (distance * tan(angle)- (g* distance^2))/(2*velocity^2*(cos(angle))^2) Step 4. Return h Step 5. Exit

Flowchart int star(int charX, int charY, float ang, float vel, int player, int char2X, int char2Y) This function displays star in the given coordinates. Here arguments charX and charY acts as starting position of the projectile from where it is projected with the velocity vel and at angle ang. The projectile follows its trajectory until it hits the edge of the screen or any of the buildings. The motion will also break if the projectile hits another player which is determined by the parameters char2X and char2Y, which is basically the position of another player within the screen. The argument for parameter player is either 1 or 2 which denote the respective player i.e. player 1 or player 2. It helps to determine which direction the projectile will go and whose life is to be deduced on hit. If the projectile hit opponent, this function returns value 1 and 0 if not.

Step 1. Entry Step 2. Declare starBegin and starEnd Step 3. If player=1:

starBegin = charX + charWidth starEnd = LEFT + SCREENX - 1 Else: starBegin = charX - 1 starEnd = LEFT + 1

Step 4. unit = Actual length of screen in m / SCREENX Step 5. Declare integers x, y and y1 Step 6. Declare floats h and h1

23

Step 7. Assign x=starBegin Step 8. Calculate distance in m represented by x:

distance = (x-charX)*unit Step 9. Calculate height of projectile for that distance

h = height (vel, ang, distance) Step 10. Convert height in terms of coordinate and store in y

y = (charY+3) - round (h/unit) Step 11. If y<TOP OR y>TOP+SCREENY-1

Display "Target Missed" return 0 goto Else if y>= TOP+SCREENY-bHeight[x/bWidth] Display "Target Missed" return 0 goto

Step 12. gotoxy (x,y) and Display '*' Step 13. Pause for 150 ms Step 14. gotoxy (x,y) and Display '.' Step 15. If x<= char2X+charWidth AND x>=char2X

If y<=(char2Y+charHeight) AND y>=char2Y return 1 goto

Step 16. If player=1, x++ Else, x--

Step 17. If player=1 If x<starEnd, goto step 8 Else, goto step 18 If player=2 If x>starEnd, goto step 8 Else, goto step 18

Step 18. Exit

24

Flowchart

25

void clearStar(int charX, int charY, float ang, float vel, int player) This function acts in the same way as star(), but it is used to clear the path of the star. It simply recalculate the entire path of the projectile and prints blank space ' ' to clear it. void start(void) This is the main function that compiles all the other function and run the game.

Step 1. Entry Step 2. Declare float angle and velocity Step 3. Call printScreen() Step 4. Declare p1 and p2 Step 5. Declare integer n Step 6. Call details(&p1, &p2) Step 7. Declare hit1=0, hit2=0 Step 8. Declare turn=0 Step 9. If hit1<totalLife AND hit2<totalLife, goto step 10

Else goto step 26 Step 10. len = 250+rand()%300 Step 11. Clear screen Step 12. Call printScreen()

26

Step 13. Call town() Step 14. Declare integers x1, y1 Step 15. Call charPosition(&x1, &y1, 1) Step 16. Call printChar1(x1, y1) Step 17. Declare integers x2, y2 Step 18. Call charPosition(&x2, &y2, 2) Step 19. Call printChar1(x2, y2) Step 20. Call printLife(hit1, 1, p1) and printLife(hit2, 2, p2) Step 21. Declare integer index=0 Step 22. Assign integer tmp=turn Step 23. If index=0 goto step 24, else goto step 9 Step 24. If turn%2=0

Call request (&ang, &vel, 1) Assign integer result=star(x1, y1, ang, vel, 1, x2, y2) Call clearStar(x1, y1, ang, vel,1) turn++ If result=1 Call message ("Exact Hit", SCREENX/2, 2) hit2++ and index++ goto step 23 Else Call request(&ang, &vel, 2) Assign integer result=star(x2,y2,ang, vel,2, x1, y1) Call clearStar(x2,y2,ang, vel,2) turn++ If result=1 Call message ("Exact Hit", SCREENX/2, 2) hit1++ and index++ goto step 23

Step 25. If turn>=(tmp+10) Call message("Draw", SCREENX/2, 2) goto step 9

Step 26. If hit2>hit1, Display congratulation message to p1 Else Display congratulation message to p1

Step 27. Exit

27

Flowchart

28

N

Y N Y

29

N N Y Y

N

Y

Y N

30

Output Snapshot 1) Title Screen

2) Main Menu

31

3) Player's Details

4) In-Game Snapshots

32

33

Testing and Debugging

During the creation of "Ninja Game", a lot of problems were seen. As it was our first project, the main problem was our lack of experience. Because of it a lot of syntax errors were seen while coding. Initially, we even had problem finding a way to solve the problems encountered. A lot of time was spent for executing the motion of ninja star. Various semantic errors were also seen during the process, which was usually hard to spot and fix. Due to the help of our classmates and seniors and after spending a long time searching for the problem in internet, we were able to fix a lot of those bugs.

Still, the game might not be bug free. Some errors might be seen during its execution. We expect the help from our users by letting us know about those errors so that we can know our mistakes and learn from it.

34

Discussion and Conclusion

“Ninja Game”, being out first project, has various issues that could have been worked upon but due to various limiting factors we couldn’t improve numerous aspects of the game. The program development despite being a difficult and time consuming work, enabled us to learn many functions and programming tools available in C-Programming language, and gave us the idea about writing an efficient and properly managed program using C-Programming Language. We also learned about work division and working as a team. As a result of which we were able to create, in our opinion, a complete mini project.

35

Annex Codes main.c #include <stdio.h> #include <conio.h> #include <stdlib.h> #include "game.h" void displayTxt(char title[],int x, int y ); void getMenu(void); void chooseMenu(int a); int main(void) { printScreen(); displayTxt("title.txt", 17, TOP+4); Sleep(3000); FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); getMenu(); return 0; } void displayTxt(char title[],int x, int y ) //display text from file title[] { char ch, file_name[25]; FILE *fptr; if((fptr = fopen(title,"r")) == NULL ) { perror("Error while opening the file.\n"); exit(1); } int j=x; while( ( ch = fgetc(fptr) ) != EOF ) { gotoxy(j,y); if (ch=='\n')

36

{ y++; j=x; } else { printf("%c",ch); j++; } } fclose(fptr); } void getMenu(void) //Display menu item { system("cls"); printScreen(); displayTxt("Heading.txt", 23, TOP+2); int x=31, y=TOP+11; gotoxy(x,y); printf("1: Single Player"); gotoxy(x,y+=2); printf("2: Multi Player"); gotoxy(x,y+=2); printf("3: Exit"); int a; do { a=getch()-'0'; }while(a<1 || a>3); chooseMenu(a); } void chooseMenu(int a) //choose menu items { switch(a) { case 1: start(1);

37

break; case 2: start(2); break; case 3: break; } } getInput.h #ifndef GETINPUT_H_INCLUDED #define GETINPUT_H_INCLUDED #endif // GETINPUT_H_INCLUDED #include <stdio.h> #include <conio.h> #include <math.h> //function prototypes float floatNum (int length, int minimum); int intNum (int length, int minimum); char charWord (char letters[]); //function declarations float floatNum (int length, int minimum) //take input of float numbers { float num=0; char a; int index=0, currentLen=0,x; do { a=getch(); if (a>=48 && a<=57){ a-='0'; if (index==0 && currentLen<length){ printf("%d", a); num*=10; num+=a; currentLen++; }else if((index>0) && (index<3)){

38

printf("%d", a); num+=pow(10, -index)*a; index++; } }else if(a=='.' && index==0) { printf("%c", a); index++; } else if (a==8) { if (index>1){ printf("\b \b"); x=pow(10,index-2); num=floor(num*x)/x; index--; } else if (index==1) { printf("\b \b"); index--; } else if (currentLen>0){ printf("\b \b"); int tmp=num; tmp/=10; num = tmp; currentLen--; } } }while(a!='\r' || num<minimum); return num; } int intNum (int length, int minimum) //take input of integer number { int num=0, currentLen=0; char a; do { a=getch(); if (a>=48 && a<=57 && currentLen<length){ printf("%c", a); a-='0'; num*=10; num+=a; currentLen++;

39

} else if (a==8 && currentLen>0) { printf("\b \b"); num/=10; currentLen--; } }while(a!='\r' || num<minimum); return num; } char charWord (char letters[]) //take string as input { char a; int i=0; do { a=getch(); if ((a>=65 && a<=90) || (a>=97 && a<=122)){ printf("%c", a); letters[i++]=a; letters[i]=NULL; } else if (a==8 && i>0) { printf("\b \b"); letters[--i]=NULL; } }while(a!='\r' || i==0); } game.h #ifndef GAME_H_INCLUDED #define GAME_H_INCLUDED #endif // GAME_H_INCLUDED #include <stdio.h> #include <conio.h> #include <windows.h> #include <time.h> #include <math.h> #include <string.h> #include "getInput.h"

40

#define PI 3.14159265359 #define SCREENX 73 //width of screen #define SCREENY 20 //height of screen #define TOP 4 //top spacing #define LEFT 3 //left spacing /*-------function prototypes------*/ void start(int player); void town(void); int building(int x, int index); void charPosition(int *x, int *y, int player); void printLife(int hit, int player, char name[]); void details(char p1[], char p2[]); void gotoxy(int x, int y); void request(float *ang, float *vel, int player); void calcAngVel(float *ang, float *vel); void calcAngVel(float *ang, float *vel); void message(char text[], int x, int y); float toRad(float deg); float height(float vel, float ang, float dist); void printScreen(void); void printChar1(int x, int y); void printChar2(int x, int y); int star(int charX, int charY, float ang, float vel, int player, int char2X, int char2Y); void clearStar(int charX, int charY, float ang, float vel, int player); /*--------------------------------*/ //Global variables int charHeight=6; int charWidth=5; float g=9.8; //value of acceleration due to gravity int totalLife=3; float len; //total length in meter equivalent of SCREENX float unit; //length equivalent to one character int bHeight[6]; //array of height of buildings int bWidth=12; //width of buildings int tmpAng=0, tmpVel=0; void start(int player)

41

//start of game //If single player, player=1. Else 2. { system("cls"); float ang, vel; //angle and velocity for projectile float ang2=0, vel2=0; printScreen(); char p1[10], p2[10]; //names of players int n; details(p1, p2); int hit1=0,hit2=0; int turn=0; while(hit1<totalLife && hit2<totalLife) { srand(time(0)); len = 250+rand()%300; system("cls"); printScreen(); town(); int x1,y1; charPosition(&x1,&y1,1); printChar1(x1,y1); int x2,y2; charPosition(&x2,&y2,2); printChar2(x2,y2); printLife(hit1, 1, p1); printLife(hit2, 2, p2); vel2=0, ang2=0; int index=0; int tmp=turn; while (index==0){ if (turn%2==0){ request(&ang, &vel, 1); int result=star(x1,y1,ang, vel,1, x2, y2); clearStar(x1,y1,ang, vel,1); turn++; if (result==1){

42

message("Exact Hit", SCREENX/2, 2); ++hit2; ++index; continue; } } else { if (player==2) request(&ang, &vel, 2); else calcAngVel(&ang2, &vel2); ang=ang2; vel=vel2; int result=star(x2,y2,ang, vel,2, x1, y1); clearStar(x2,y2,ang, vel,2); turn++; if (result==1){ message("Exact Hit", SCREENX/2, 2); ++hit1; ++index; } } if (turn>=(tmp+10)){ message("Draw", SCREENX/2, 2); break; } } } printLife(hit1, 1, p1); printLife(hit2, 2, p2); if (hit2>hit1){ gotoxy(SCREENX/2, SCREENY/2); printf("Congratultion"); gotoxy(SCREENX/2, SCREENY/2+1); printf("Ninja %s wins", p1); write(p1, p2, 1, hit1, hit2, totalLife); } else { gotoxy(SCREENX/2, SCREENY/2); printf("Congratultion"); gotoxy(SCREENX/2, SCREENY/2+1); printf("Ninja %s wins", p2); write(p1, p2, 2, hit1, hit2, totalLife); }

43

gotoxy(SCREENX/2,2); printf("Replay? (y/n)"); char a; do { a=getch(); } while (a!='y' && a!='n'); if (a=='y') getMenu(); else ; } void town(void) { int x,i; srand(time(0)); for (x=(LEFT+1), i=0; x<(LEFT+SCREENX); x+=bWidth, i++) bHeight[i]=building(x,i); //print building and save its height in array h } int building(int x, int index) //Print building with random height { int height=rand()%10+3;//randomly generated height //limiting height of first and last building to less than 8 if (index==0 || index==5) height>8?(height-=(height%8)):height; //limiting height of second and second last building to less than 10 if (index==1 || index==4) height>10?(height-=(height%10)):height; int i,j; int y=TOP+SCREENY-height; gotoxy(x,y); printf("%c", 201); for (i=1;i<bWidth-1;i++){ gotoxy(x+i,y); printf("="); } gotoxy(x+bWidth-1,y);

44

printf("%c\n",187); for (i=x+1;i<x+bWidth-1;i++){ if (i%2==0){ gotoxy(i, y+1); printf("%c", 222); gotoxy(i, y+2); printf("%c", 222); } gotoxy(i,y+3); printf("%c", 196); } for (j=1;j<height;j++){ gotoxy(x,y+j); printf("%c",186); gotoxy(x+bWidth-1,y+j); printf("%c",186); } return height; } void charPosition(int *x, int *y, int player) { srand(time(0)); if (player==1) *x=LEFT+1+(rand()%2)*bWidth+rand()%6; else *x=LEFT+SCREENX-(rand()%2)*bWidth-rand()%6-6; int j; if ((float)*x/bWidth!=(int)*x/bWidth) j=(*x/bWidth); else j=(*x/bWidth)-1; *y=TOP+SCREENY-charHeight-bHeight[j]; } void printLife(int hit, int player, char name[]) { int x; (player==1)?(x=LEFT+1):(x=LEFT+SCREENX-15);

45

gotoxy(x,1); printf("Ninja %s", name); gotoxy(x,2); printf("Life : %3d", totalLife-hit); } void details(char p1[], char p2[]) { int x= SCREENX/2-8, j=2; gotoxy(x, TOP+j); printf("Enter player's name"); gotoxy(x, TOP+(++j)); printf("-------------------"); gotoxy(x, TOP+(j+=2)); printf("Player 1 : "); charWord(p1); gotoxy(x, TOP+(++j)); printf("Player 2 : "); charWord(p2); gotoxy(x-=4, TOP+(j+=3)); printf("How much do you want to play?!"); gotoxy(x, TOP+(++j)); printf("------------------------------"); gotoxy(x+5, TOP+(++j)); printf("Number of lives : "); totalLife = intNum(1,1); gotoxy(x-=1, TOP+(j+=3)); printf("Get Ready to play the NINJA GAME"); gotoxy(x, TOP+(++j)); printf("--------------------------------"); j++; int i; for (i=3; i>0; i--){ gotoxy(x+15, TOP+j); printf("\a%d", i); Sleep(1000); FlushConsoleInputBuffer( GetStdHandle( STD_INPUT_HANDLE ) ); gotoxy(x+15, TOP+j);

46

printf(" "); } } void gotoxy(int x, int y) //Set cursor position to x,y { COORD coord={0,0}; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void request(float *ang, float *vel, int player) /*player= 1 or 2*/ { int x; if (player==1){ x=LEFT+2; }else{ x=LEFT+SCREENX-16; } float deg; gotoxy(x, TOP+1); printf("Angle: "); deg=floatNum(2,10); (player==1)?(*ang= toRad(deg)):(*ang=PI-toRad(deg)); gotoxy(x, TOP+2); printf("Velocity: "); *vel=floatNum(3,10); gotoxy(x+strlen("Angle: "), TOP+1); printf(" "); gotoxy(x+strlen("Velocity: "), TOP+2); printf(" "); } void calcAngVel(float *ang, float *vel) { int x=LEFT+SCREENX-16;

47

static float deg; gotoxy(x, TOP+1); printf("Angle: "); Sleep(rand()%3*1000+rand()%10*100); srand(time(0)); if (*ang==0) deg=rand()%10+30; else if (tmpAng>0) deg+=(5+rand()%3); else if (tmpAng<0) deg-=(5+rand()%3); else; printf("%3.2f", deg); *ang=PI-toRad(deg); gotoxy(x, TOP+2); printf("Velocity: "); Sleep(rand()%3*1000+rand()%10*100); if (*vel==0) *vel=rand()%10+35; else if (tmpVel>0) *vel+=((5+rand()%3))*tmpVel; else if (tmpVel<0) *vel-=((5+rand()%3)*tmpVel); else; printf("%3.2f", *vel); Sleep(1000); FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); gotoxy(x+strlen("Angle: "), TOP+1); printf(" "); gotoxy(x+strlen("Velocity: "), TOP+2); printf(" "); } void message(char text[], int x, int y)//text and display position { gotoxy(x,y); printf("%s", text);

48

Sleep(3000); FlushConsoleInputBuffer( GetStdHandle( STD_INPUT_HANDLE ) ); gotoxy(x,y); int i; for (i=0;i<strlen(text);i++) printf(" "); } float toRad(float deg) //convert deg into radian { float rad = (deg*PI)/180; return rad; } float height(float vel, float ang, float dist) //claculate height of projectile { float h=(float) dist*tan(ang)-(g*pow(dist, 2))/(2*pow(vel, 2)*pow(cos(ang),2)); return h; } void printScreen(void) { int i,j; char chSide=179, chTop=196; for (i=LEFT+1; i<LEFT+SCREENX;i++){ gotoxy(i,TOP-1); printf("%c", chTop); } for (i=LEFT+1; i<LEFT+SCREENX;i++){ gotoxy(i,TOP+SCREENY); printf("%c", chTop); } for (j=TOP; j<TOP+SCREENY; j++){ gotoxy(LEFT, j); printf("%c", chSide); } for (j=TOP; j<TOP+SCREENY; j++){ gotoxy(LEFT+SCREENX, j); printf("%c", chSide); } }

49

void printChar1(int x, int y) { gotoxy(x+1,y++); printf("__"); gotoxy(x,y++); printf("|@@"); gotoxy(x,y++); printf("|_-)"); gotoxy(x,y++); printf("|\\\\|\\"); gotoxy(x,y++); printf("| \\|"); gotoxy(x,y); printf("|m|m"); } void printChar2(int x, int y) { gotoxy(x+2,y++); printf("__"); gotoxy(x+2,y++); printf("@@|"); gotoxy(x+1,y++); printf("<-_)"); gotoxy(x,y++); printf("/| |"); gotoxy(x+1,y++); printf("| |"); gotoxy(x+1,y); printf("m|m|"); } int star(int charX, int charY, float ang, float vel, int player, int char2X, int char2Y) { int starBegin, starEnd; if (player==1){ starBegin=charX+charWidth;//5=>char width +1 starEnd=LEFT+SCREENX-1; } else { starBegin=charX-1; starEnd=LEFT+1; }

50

unit=len/SCREENX; int x,y,y1; float h, h1; for (x=starBegin; (player==1)?(x<starEnd):(x>starEnd);) { tmpAng=0; h = height(vel, ang, (float) (x-charX)*unit); y = (charY+3)-roundf(h/unit); if (y<=TOP||y>=TOP+SCREENY){ message("Target Missed", (SCREENX/2),2); if (player==2 && y<=TOP) tmpAng=-1; return 0; break; } else if (y>=(TOP+SCREENY-bHeight[x/bWidth])){ message("Target Missed", (SCREENX/2),2); return 0; break; } int index=0,j=1; float dist; do{ (player==1)?(dist=x-charX+j):(dist=x-charX-j); h1 = height(vel, ang, (float) dist*unit); y1 = (charY+3)-roundf(h1/unit); index+=1; j++; }while(y==y1 && j<60); dist=x-charX-j; h1 = height(vel, ang, (float) dist*unit); y1 = (charY+3)-roundf(h1/unit); if (tmpAng>=0) { if (x<char2X) tmpVel=-1; else if (x>(char2X+(char2Y-char2X)/2)) tmpVel=3; else if (x>(char2X+(char2Y-char2X)/3))

51

tmpVel=2; else if (x>(char2X)) tmpVel=1; } else { tmpVel=0; } if (player==2 && y>=(TOP+SCREENY-bHeight[x/bWidth])) { if (y1>y) tmpAng=1; else tmpAng=0; } if (player==1) x+=index/2; else x-=index/2; gotoxy(x,y); printf("*"); Sleep(150); gotoxy(x,y); printf("."); if (x<=(char2X+charWidth) && x>=char2X){ if (y<=(char2Y+charHeight) && y>=char2Y){ return 1; break; } } if (index==1){ if (player==1) x++; else x--; } else { if (player==1) x+=index/2; else

52

x-=index/2; } } } void clearStar(int charX, int charY, float ang, float vel, int player) { int starBegin, starEnd; if (player==1){ starBegin=charX+charWidth;//4=>char width +1 starEnd=LEFT+SCREENX-1; } else { starBegin=charX-1; starEnd=LEFT+1; } unit=len/SCREENX; int x,y; float h; for (x=starBegin; (player==1)?(x<starEnd):(x>starEnd);) { h = height(vel, ang, (float) (x-charX)*unit); y = (charY+3)-roundf(h/unit); if (y<=TOP||y>=TOP+SCREENY){ break; } else if (y>=(TOP+SCREENY-bHeight[x/bWidth])){ break; } gotoxy(x,y); printf(" "); (player==1)?x++:x--; } }