3 Replies - 789 Views - Last Post: 09 December 2013 - 04:40 PM Rate Topic: -----

#1 HorizonBrave   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 08-December 13

Incorporating "struct" for Robot Game Stats

Posted 08 December 2013 - 11:11 PM

I just need a little push(shove) in the right direction. For my final assignment in my intro to programming class, I need to create a robot combat game. I have a large majority of it done, I just need to incorporate a struct that allows the two players to give their robots custom stats before they fight. The players are given 6 points to allocate towards Dexterity, Strength, Armor and Construct. The robots must also have base stats to start. This is what I have so far. The comments are for my professor:

#include <conio.h>	// Needed for _getch().
#include <ctype.h>	// Needed for toupper() in the upperCase() function.
#include <stdio.h>	// Standard input/output.
#include <stdlib.h>	// For system("pause").
#include <string.h>	// For our string handling functions.
#include <time.h>	// For time(NULL) in srand().

#define DICE 6	// Macro for the number of dice in the attack and defense rolls.
#define HP 50	// Macro for the number of hitpoints for each robot.
#define SIZE 25	// Macro for the size of the robot name arrays. 24 chars + '\0'
	

/* The following function loops through a name passed in via the character pointer *nameIn and
   converts the case of each character to uppercase. It then returns the character pointer back to 
   the calling function, in thie case doAttack(). */
char* upperCase( char *nameIn ) // Has to go first because it is called in the doAttack() function.
{
    int charIndex = 0;
    while ( nameIn[charIndex] != '\0' ) // Loop through each character until you hit the null terminator.
    {
        nameIn[charIndex] = toupper( nameIn[charIndex] ); // Convert the character to uppercase.
        charIndex++;
    }
    return nameIn; // Return the name back to the caller of this function.
}

/* THe following function either performs one of the two attacks for a robot or it does the defense
   action which just sets the defense bonus of the robot defending next round to 6. There is a lot
   to go through so it's best to refer back to the How-To document for a complete walkthough. */
int doAttack( int atkIn, char *atkName, char *defName, int *defHP, int *atkBonus, int *defBonus ) 
{
    int atkOpt; // The player's attack or defend options retrieved via a _getch().
    int atkRoll = 0, defRoll = 0, fCtr;
    int retVal = 1; // The exit condition in the while loop of main. If it is set to 0, the game ends.

    printf("\n\n  Player %d, choose action for %s:\n  [1]-Power Attack [2]-Normal Attack [3]-Defend > ", atkIn, atkName);
    atkOpt = _getch();
    if ( atkOpt == 51 ) // '3' was pressed.
    {
        *atkBonus = 6;
        printf("\n\n  %s defends itself for attack and gains +6 defense!", atkName);
    }
    else // If it is one of the two attacks.
    {
        // The following six lines do the die rolls and adds/subtracts the respective bonuses or penalties.
		for ( fCtr = 0; fCtr < DICE ; fCtr++) 
            atkRoll += 1 + (rand() % 6);
        atkRoll += atkOpt == 49 ? 6 : 0; // If power attack, add 6 to the attack roll.
        for ( fCtr = 0; fCtr < DICE ; fCtr++)
            defRoll += 1 + (rand() % 6);
        defRoll += *defBonus;

        printf("\n\n  %s performs a %s attack on %s and %s!", atkName, atkOpt == 49 ? "power" : "normal", defName, atkRoll > defRoll ? "hits" : "misses");
        if ( atkOpt == 49 ) // '1' was pressed.
        {
            *atkBonus = -6; // If power attack, set the bonus for next round to -6 for a defense penalty.
            printf("\n  Its power attack leaves %s weakened to an attack!", atkName);
        }
        if ( atkRoll > defRoll ) // Check to see if the attacker hit.
        {
            *defHP -= atkRoll - defRoll;
            printf("\n  %s takes %d damage and has %d hit points left!", defName, atkRoll - defRoll, *defHP > 0 ? *defHP : 0 );
            if ( *defHP <= 0 ) 
            {
                printf("\n\n  %s HAS DEFEATED %s!!!", upperCase(atkName), upperCase(defName) );
                retVal = 0;
            }
        }
    }
    if ( *defBonus != 0 ) // If the defender had a bonus or penalty this round, reset their bonus to 0.
		*defBonus = 0;
    return retVal;
}

void getRobotName( char *nameIn ) 
{
	fgets(nameIn, SIZE+1, stdin); // Get the robot's name. SIZE+1 to account for the '\n'.
	fflush(stdin); /* If we input more than 24 chars, it will flush them out of the buffer.
					  Note this MAY NOT work in all compilers. But Visual Studio is safe. */
	nameIn[ strlen(nameIn)-1 ] = '\0'; // Replace the '\n' with another '\0'.
}

void printTitle( void )
{
    printf("\n  *************************");
    printf("\n  * WELCOME TO ROBOCOMBAT *");
    printf("\n  *************************\n");
}

int main( void )
{
    char robot1[SIZE], robot2[SIZE];
    char *r1Ptr = robot1;
    char *r2Ptr = robot2;
    int inGame = 1;
    int nameLen;
    int robot1Bonus = 0, robot2Bonus = 0;
    int robot1HP = HP, robot2HP = HP;
    int robotTurn;

    srand( (unsigned)time(NULL) ); // Seed the random number generator.

    printTitle();
    printf("\n  Player 1, enter a name for your robot > ");
	getRobotName( r1Ptr ); // Call our user-defined function that contains fgets().
    printf("  Player 2, enter a name for your robot > ");
    getRobotName( r2Ptr );
    nameLen = strlen(r1Ptr) + strlen(r2Ptr) + 4;
    printf("\n  *** Tonight's metal-mashing RoboCombat match is: ***");
    printf("\n  %*s%s vs %s", (52-nameLen)/2, "", r1Ptr, r2Ptr);
    robotTurn = 1 + (rand() % 2); // Randomize the robot who goes first.
    while ( inGame ) // Means that if inGame is not 0.
    {
        if ( robotTurn == 1 ) 
            inGame = doAttack( robotTurn, r1Ptr, r2Ptr, &robot2HP, &robot1Bonus, &robot2Bonus );
        else
            inGame = doAttack( robotTurn, r2Ptr, r1Ptr, &robot1HP, &robot2Bonus, &robot1Bonus );
        robotTurn = robotTurn == 1 ? 2 : 1; // Switch turns with a ternary operator.
    }
    printf("\n  Thanks for playing RoboCombat. ");
	system("pause");
    return 0;
}




Again, I'm not looking for you to do it for me, just a little push so I can get back on the right track.

Is This A Good Question/Topic? 0
  • +

Replies To: Incorporating "struct" for Robot Game Stats

#2 Adak   User is offline

  • D.I.C Lover
  • member icon

Reputation: 332
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Incorporating "struct" for Robot Game Stats

Posted 08 December 2013 - 11:43 PM

Line #24 of your code, you are returning namein - but there's no need to return anything. namein is a char pointer parameter, so namein is already changed - it's not a copy of the namein array.

The prototype of the struct, should go just below your #defines. Then, in main() you make your array of type struct. It might look like this:

struct robot {
   int number;
   int strength;
   int speed;
   //etc.
};


int main() {
   struct robot robots[2]={
     {1, 10, 8, etc},
     {2, 12, 5, etc}
   };
Inital assignments like this can be made only when the struct is created, and each value must be in the same exact order as the prototype, with the correct data type. Elsewhere, they must use the assignment method:
   robots[0].number = 1;
   robots[0].strength = 10;
   //etc.
   robots[1].number = 2;
   //etc.
No special order needs to be used, in this case, you can interleave the robots struct member assignments, any way you please, since you are using their full record field names, with the dot access operator.



This post has been edited by Adak: 08 December 2013 - 11:44 PM

Was This Post Helpful? 1
  • +
  • -

#3 HorizonBrave   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 08-December 13

Re: Incorporating "struct" for Robot Game Stats

Posted 09 December 2013 - 02:41 PM

Thanks. I passed out before I could read your response last night. Using that as an example, would it allow the players to give the robots extra stats before the combat portion starts. For example, what I'm trying to accomplish is:

Enter name for robot 1: Blah*

Base Stats : 1 Dexterity 1 Strength 1 Armour 1 Construction

Enter D, S, A, C for modified stats:

[D]exterity [S]trength [A]rmour [C]onstruction (6 Points remaining)

D

(5 Points remaining)

2 Dexterity 1 Strength 1 Armour 1 Construction

A

(4 Points remaining)

2 Dexterity 1 Strength 2 Armour 1 Construction

* This continues until all points are used then the next player modifies their robot.
Was This Post Helpful? 0
  • +
  • -

#4 Adak   User is offline

  • D.I.C Lover
  • member icon

Reputation: 332
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Incorporating "struct" for Robot Game Stats

Posted 09 December 2013 - 04:40 PM

Yes, the values could be changed or given initial values, through regular keyboard entry by a user, but not as you've shown it, above.

printf("Do you want to change the robot's parameters [Y/N]? ");
fflush(stdout);
if(answer=='y' || answer=='Y') {
   printf("For which robot [1-3]? ");
   fflush(stdout);
   scanf("%d",&n);
   printf("Enter new robot %d strength\n",n);
   scanf("%d",&robot[n-1].strength); //n-1 because C arrays are 0 based

// you may continue like this, changing any and all struct members for any robot you please,
// and do so in any order you like. For string changes, use %s and leave out the & in the scanf().
// if you want the robots to have names, remember to change the struct prototype, so it has a
// char name[26] struct member, as a part of it. Also, remember that the last char in any C string
// MUST be a 0 or '\0', which C uses to mark the end of any string with. Longest name here for example,
// would be 25 chars, not 26.



}   


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1