-1

This is my code, for a machine project, I'm only in my first year in programming course (basic stuff). This is a pokemon battle simulator, and i' am merely setting the moves, and stats, of the pokemon, as to what the user decides what his pokemon is. However, when I start to print the moveset for Player 1, the strcpy() messes up and somehow it includes bits of the strcpy() after it.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

/*
    Name: POKEMON 1v1 BATTLE SIMULATOR
    Author: ADRIAN PAULE D. TY
    Date Created: 10/18/2017
    Last Modified: 10/18/2017
    Description: This machine project is a program that puts two pokemon selected by the users against each other, taking the user's input to interact and determine the moves used.

*/

//--------------------------------------------------------------------------------------------------
//GLOBAL VARIABLES
///---Player 1
char cP1_Pokemon_Name[] = "POKEMON";
char cP1_Move1_Name[] = "TACKLE";
char cP1_Move2_Name[] = "POUND";
int nP1_HP_Base, nP1_HP_Current;
int nP1_Move1_PP, nP1_Move1_BP, nP1_Move2_PP, nP1_Move2_BP;
int nP1_Protect_PP= 5;
int nP1_Protect_Status = 0;
int nP1_ChargeUp_PP= 5;
int nP1_ChargeUp_Status = 0;

///---Player 2
char cP2_Pokemon_Name[] = "POKEMON";
char cP2_Move1_Name[] = "TACKLE";
char cP2_Move2_Name[] = "POUND";
int nP2_HP_Base, nP2_HP_Current;
int nP2_Move1_PP, nP2_Move1_BP, nP2_Move2_PP, nP2_Move2_BP;
int nP2_Protect_PP = 5;
int nP2_Protect_Status = 0;
int nP2_ChargeUp_PP = 5; 
int nP2_ChargeUp_Status = 0;

//--------------------------------------------------------------------------------------------------
//FUNCTION PROTOTYPES
///---Player 1
void declare_pokemon_and_stats_1(int nChoice);
void display_player1_moveset_and_action();
///---Player 2
void declare_pokemon_and_stats_2(int nChoice);
void display_player2_moveset_and_action();
//--------------------------------------------------------------------------------------------------
//MAIN EXECUTION FUNCTION

int main(int argc, char *argv[]) {
    int nP1_choice, nP2_choice;

    printf("**************** POKEMON 1v1 BATTLE SIMULATOR **************** \n\n");
    printf("Here are the POKEMON choices:\n");
    printf("1 -- Entei\n");
    printf("2 -- Milotic\n");
    printf("3 -- Torterra\n");
    printf("4 -- Pikachu\n");
    printf("5 -- Groudon\n");
    printf("6 -- Lapras\n");
    printf("7 -- Stunfisk\n\n");
    
    printf("PLAYER 1, please select your POKEMON: ");
    scanf("%d", &nP1_choice);
    declare_pokemon_and_stats_1(nP1_choice);

    
    printf("PLAYER 2, please select your POKEMON: ");
    scanf("%d", &nP2_choice);
    declare_pokemon_and_stats_2(nP2_choice);

    display_player1_moveset_and_action();
    return 0;
}

//--------------------------------------------------------------------------------------------------
//FUNCTION DEFINITIONS

///---Declare Pokemon and Stats (PLAYER1)
/* This function sets the printed choice of PLAYER 1's Pokemon as well as the values for the stats, moves, PP of moves......  */
void declare_pokemon_and_stats_1(int nChoice){
    int nP1_choice;
         
    if (nChoice == 1){
            
            nP1_HP_Base = 150;
            nP1_HP_Current = 150;
            
            strcpy(cP1_Move1_Name,"FIRE BLAST"); 
            nP1_Move1_PP = 5;
            nP1_Move1_BP = 30;
            
            strcpy(cP1_Move2_Name,"EARTHQUAKE");
            nP1_Move2_PP = 5;
            nP1_Move2_BP = 30;  
            
            strcpy(cP1_Pokemon_Name, "ENTEI");
            printf("PLAYER 1 has selected %s! \n\n", cP1_Pokemon_Name);
            
    } else if (nChoice == 2){
            
            nP1_HP_Base = 200;
            nP1_HP_Current = 200;
            
            strcpy(cP1_Move1_Name,"SCALD");
            nP1_Move1_PP = 7;
            nP1_Move1_BP = 20;
            
            strcpy(cP1_Move2_Name,"ICE BEAM");
            nP1_Move2_PP = 7;
            nP1_Move2_BP = 20;  
            
            strcpy(cP1_Pokemon_Name,"MILOTIC");
            printf("PLAYER 1 has selected %s! \n\n", cP1_Pokemon_Name);
            
    } else if (nChoice == 3){
            
            nP1_HP_Base = 220;
            nP1_HP_Current = 220;
            
            strcpy(cP1_Move1_Name,"DIG");
            nP1_Move1_PP = 7;
            nP1_Move1_BP = 20;
            
            strcpy(cP1_Move2_Name,"LEAF STORM");
            nP1_Move2_PP = 5;
            nP1_Move2_BP = 40;  
            
            strcpy(cP1_Pokemon_Name,"TORTERRA");
            printf("PLAYER 1 has selected %s! \n\n", cP1_Pokemon_Name);
            
    } else if (nChoice == 4){
            
            nP1_HP_Base = 120;
            nP1_HP_Current = 120;
            
            strcpy(cP1_Move1_Name,"THUNDERBOLT");
            nP1_Move1_PP = 10;
            nP1_Move1_BP = 10;
            
            strcpy(cP1_Move2_Name,"DIG");
            nP1_Move2_PP = 7;
            nP1_Move2_BP = 20;  
            
            strcpy(cP1_Pokemon_Name,"PIKACHU");
            printf("PLAYER 1 has selected %s! \n\n", cP1_Pokemon_Name);
            
    } else if (nChoice == 5){   
            
            nP1_HP_Base = 150;
            nP1_HP_Current = 150;
            
            strcpy(cP1_Move1_Name,"FISSURE");
            nP1_Move1_PP = 5;
            nP1_Move1_BP = 40;
            
            strcpy(cP1_Move2_Name,"FIRE BLAST");
            nP1_Move2_PP = 5;
            nP1_Move2_BP = 30;  
            
            strcpy(cP1_Pokemon_Name,"GROUDON");
            printf("PLAYER 1 has selected %s! \n\n", cP1_Pokemon_Name);
    } else if (nChoice == 6){
            
            nP1_HP_Base = 190;
            nP1_HP_Current = 190;
            
            strcpy(cP1_Move1_Name,"ICE BEAM");
            nP1_Move1_PP = 7;
            nP1_Move1_BP = 20;
            
            strcpy(cP1_Move2_Name,"SCALD");
            nP1_Move2_PP = 7;
            nP1_Move2_BP = 20;  
            
            strcpy(cP1_Pokemon_Name,"LAPRAS");
            printf("PLAYER 1 has selected %s! \n\n", cP1_Pokemon_Name);
    } else if (nChoice == 7){

            nP1_HP_Base = 130;
            nP1_HP_Current = 130;
            
            strcpy(cP1_Move1_Name,"WATER GUN");
            nP1_Move1_PP = 10;
            nP1_Move1_BP = 10;
            
            strcpy(cP1_Move2_Name,"EARTHQUAKE");
            nP1_Move2_PP = 5;
            nP1_Move2_BP = 30;
            
            strcpy(cP1_Pokemon_Name,"STUNFISK");
            printf("PLAYER 1 has selected %s! \n\n", cP1_Pokemon_Name);
    } else { 
            printf("PLAYER 1, please select your POKEMON (from the list, Please): ");
            scanf("%d", &nP1_choice);
            declare_pokemon_and_stats_1(nP1_choice);
    }

}

///---Declare Pokemon and Stats (PLAYER2)
/* This function sets the printed choice of PLAYER 2's POkemon as well as the values for the stats, moves, PP of moves......  */
void declare_pokemon_and_stats_2(int nChoice){
    int nP2_choice;
         
    if (nChoice == 1){
            
            nP2_HP_Base = 150;
            nP2_HP_Current = 150;
            
            strcpy(cP2_Move1_Name,"FIREBLAST");
            nP2_Move1_PP = 5;
            nP2_Move1_BP = 30;
            
            strcpy(cP2_Move2_Name,"EARTHQUAKE");
            nP2_Move2_PP = 5;
            nP2_Move2_BP = 30;  
            
            strcpy(cP2_Pokemon_Name,"ENTEI");
            printf("PLAYER 2 has selected %s! \n\n", cP2_Pokemon_Name);
            
    } else if (nChoice == 2){
            
            nP2_HP_Base = 200;
            nP2_HP_Current = 200;
            
            strcpy(cP2_Move1_Name,"SCALD");
            nP2_Move1_PP = 7;
            nP2_Move1_BP = 20;
            
            strcpy(cP2_Move2_Name,"ICE BEAM");
            nP2_Move2_PP = 7;
            nP2_Move2_BP = 20;  
            
            strcpy(cP2_Pokemon_Name,"MILOTIC");
            printf("PLAYER 2 has selected %s! \n\n", cP2_Pokemon_Name);
    } else if (nChoice == 3){

            nP2_HP_Base = 220;
            nP2_HP_Current = 220;
            
            strcpy(cP2_Move1_Name,"DIG");
            nP2_Move1_PP = 7;
            nP2_Move1_BP = 20;
            
            strcpy(cP2_Move2_Name,"LEAF STORM");
            nP2_Move2_PP = 5;
            nP2_Move2_BP = 40;  
            
            strcpy(cP2_Pokemon_Name,"TORTERRA");
            printf("PLAYER 2 has selected %s! \n\n", cP2_Pokemon_Name);
    } else if (nChoice == 4){
            
            nP2_HP_Base = 120;
            nP2_HP_Current = 120;
            
            strcpy(cP2_Move1_Name,"THUNDERBOLT");
            nP2_Move1_PP = 10;
            nP2_Move1_BP = 10;
            
            strcpy(cP2_Move2_Name,"DIG");
            nP2_Move2_PP = 7;
            nP2_Move2_BP = 20;  
            
            strcpy(cP2_Pokemon_Name,"PIKACHU");
            printf("PLAYER 2 has selected %s! \n\n", cP2_Pokemon_Name);
    } else if (nChoice == 5){   
            
            nP2_HP_Base = 150;
            nP2_HP_Current = 150;
            
            strcpy(cP2_Move1_Name,"FISSURE");
            nP2_Move1_PP = 5;
            nP2_Move1_BP = 40;
            
            strcpy(cP2_Move2_Name,"FIRE BLAST");
            nP2_Move2_PP = 5;
            nP2_Move2_BP = 30;  
            
            strcpy(cP2_Pokemon_Name,"GROUDON");
            printf("PLAYER 2 has selected %s! \n\n", cP2_Pokemon_Name);
    } else if (nChoice == 6){
            
            nP2_HP_Base = 190;
            nP2_HP_Current = 190;
            
            strcpy(cP2_Move1_Name,"ICE BEAM");
            nP2_Move1_PP = 7;
            nP2_Move1_BP = 20;
            
            strcpy(cP2_Move2_Name,"SCALD");
            nP2_Move2_PP = 7;
            nP2_Move2_BP = 20;  
            
            strcpy(cP2_Pokemon_Name,"LAPRAS");
            printf("PLAYER 2 has selected %s! \n\n", cP2_Pokemon_Name);
    } else if (nChoice == 7){

            nP2_HP_Base = 130;
            nP2_HP_Current = 130;
            
            strcpy(cP2_Move1_Name,"WATER GUN");
            nP2_Move1_PP = 10;
            nP2_Move1_BP = 10;
            
            strcpy(cP2_Move2_Name,"EARTHQUAKE");
            nP2_Move2_PP = 5;
            nP2_Move2_BP = 30;
            
            strcpy(cP2_Pokemon_Name,"STUNFISK");
            printf("PLAYER 2 has selected %s! \n\n", cP2_Pokemon_Name);
    } else { 
            printf("PLAYER 2, please select your POKEMON (from the list, Please): ");
            scanf("%d", &nP2_choice);
            declare_pokemon_and_stats_2(nP2_choice);
    }

}

void display_player1_moveset_and_action(){
    
    printf("***********************************************************************\n \n");
    
    printf("%s: %d/%d HP\n", cP1_Pokemon_Name, nP1_HP_Base, nP1_HP_Current);
    printf("%s: %d/%d HP\n\n", cP2_Pokemon_Name, nP2_HP_Base, nP2_HP_Current);
    
    printf("%s's moves are: \n", cP1_Pokemon_Name);
    printf("1 -- %s (%d BP, %d PP) \n", cP1_Move1_Name, nP1_Move1_BP, nP1_Move1_PP);
    printf("2 -- %s (%d BP, %d PP) \n", cP1_Move2_Name, nP1_Move2_BP, nP1_Move2_PP);
    printf("3 -- PROTECT (%d PP) \n", nP1_Protect_PP);
    printf("4 -- CHARGE UP (%d PP) \n", nP1_ChargeUp_PP);
    
    getch();
    display_player2_moveset_and_action();
}

void display_player2_moveset_and_action(){
    
    printf("***********************************************************************\n \n");
    
    printf("%s: %d/%d HP\n", cP1_Pokemon_Name, nP1_HP_Base, nP1_HP_Current);
    printf("%s: %d/%d HP\n\n", cP2_Pokemon_Name, nP2_HP_Base, nP2_HP_Current);
    
    printf("%s's moves are: \n", cP2_Pokemon_Name);
    printf("1 -- %s (%d BP, %d PP) \n", cP2_Move1_Name, nP2_Move1_BP, nP2_Move1_PP);
    printf("2 -- %s (%d BP, %d PP) \n", cP2_Move2_Name, nP2_Move2_BP, nP2_Move2_PP);
    printf("3 -- PROTECT (%d PP) \n", nP2_Protect_PP);
    printf("4 -- CHARGE UP (%d PP) \n", nP2_ChargeUp_PP);
    
    getch();
    display_player1_moveset_and_action();
}

This is the output I get:

**************** POKEMON 1v1 BATTLE SIMULATOR ****************

Here are the POKEMON choices:
1 -- Entei
2 -- Milotic
3 -- Torterra
4 -- Pikachu
5 -- Groudon
6 -- Lapras
7 -- Stunfisk

PLAYER 1, please select your POKEMON:
1
PLAYER 1 has selected ENTEI!

PLAYER 2, please select your POKEMON: 4
PLAYER 2 has selected PIKACHU!

***********************************************************************

ENTEI: 150/150 HP
PIKACHU: 120/120 HP

ENTEI's moves are:
1 -- FIRE BLEARTHQUAKE (30 BP, 5 PP)
2 -- EARTHQUAKE (30 BP, 5 PP)
3 -- PROTECT (69 PP)
4 -- CHARGE UP (5 PP)
***********************************************************************

ENTEI: 150/150 HP
PIKACHU: 120/120 HP

PIKACHU's moves are:
1 -- THUNDERDIG (10 BP, 10 PP)
2 -- DIG (20 BP, 7 PP)
3 -- PROTECT (5 PP)
4 -- CHARGE UP (5 PP)

For some reason what should be Fire Blast, contains bits of Earthquake (FIRE BLEARTHQUAKE), same goes for the other moveset of player 2.

Also, For some reason, Even tho i set nP1_Protect_PP = 5, it prints as 69

Thanks For the Help

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Adrian Ty
  • 3
  • 2
  • 2
    Please provide a [mcve]. Not many people will want to look through all of your code to find your mistake. – Kevin Oct 18 '17 at 15:47
  • 2
    tl;dr Are you sure you have enough space allocated for all the strings? – 001 Oct 18 '17 at 15:48
  • 1
    Not related to your problem, but using structs and arrays you can probably reduce the size of your program at least by a factor 4. – Jabberwocky Oct 18 '17 at 16:01
  • @Kevin Noted, sorry for the trouble, it's my first time here, and my upperclassmen suggested this site to me. Thanks! – Adrian Ty Oct 18 '17 at 22:06
  • @Michael Walz He's not covering structs in this term, so he probably knows we could make the machine project work without them :( – Adrian Ty Oct 18 '17 at 22:09

1 Answers1

2

These 2 lines show what's going wrong:

Following line declares an array of char cP1_Move2_Name initialized with "POUND". The size of this array is exactly 6 bytes, that is the 5 characters from "POUND" plus one for the NUL terminator (strings are terminated by a NUL character, read the chapter dealing with string in your C textbook for more details):

char cP1_Move2_Name[] = "POUND";

Now in following line you copy "EARTHQUAKE" into the array cP1_Move2_Name. For "EARTHQUAKE" you need 11 bytes, but as mentioned before, the size of the cP1_Move2_Name array is only 6.

strcpy(cP1_Move2_Name,"EARTHQUAKE");

So what happens is that more bytes are copied than there is space, so some other memory will be overwritten and you may experience all sorts of problems.

In order to correct the program you can declare your array with a predetermined maximum size in order to make sure that there will be always enough space.

#define MAXSTRINGLENGTH 100
...
char cP1_Pokemon_Name[MAXSTRINGLENGTH] = "POKEMON";
char cP1_Move1_Name[MAXSTRINGLENGTH] = "TACKLE";
char cP1_Move2_Name[MAXSTRINGLENGTH] = "POUND";
...
etc.
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Oh, that makes more sense. I've ran past by that define string length but I didn't understand and realize and it's implications. Programming sure is a lot of work hahaha. Now I just need to figure out why 5 is printing out as 69. – Adrian Ty Oct 18 '17 at 22:00