I'm making a little console game. It's a little, turn-based fighting game about the political compass. Everything was fine and dandy but then it wasn't. I am not sure what isn't linking as everything should be included and defined. I've made sure the declarations and the definitions use the same arguments and there should be no spelling mistakes (Hopefully). I will post my code here and I'm very sorry for how messy it is. Here is the main.cpp:
#include "Header.h" //I wanted to have two seperate header files but couldn't figure out how to
#include <iostream>
#include <vector> //I like vectors
bool turn;//Ignore the global variable, for some reason, the main "do while" loop, which I had in main(), didn't recognise it unless it was global
int main()
{
Attacks at;
Left_Attacks at1;
Right_Attacks at2;
Lib_Attacks at3;
LibLeft_Attacks at4;
Auth_Attacks at5;
LibRight_Attacks at6;
AuthLeft_Attacks at7;
AuthRight_Attacks at8;
Authleft Bob;
Character Joe;
Character Joe2;
Authleft Bob2;
//I made 2 copies of the same character so you could use the same two characters againt each other, or at least to make sure that I could
Joe.hp = 100;
Joe.strength = 10;
Joe.ap = 10;
Bob.hp = 110;
Bob.strength = 45;
Bob.ap = 10;
//hentai
Joe2.hp = 100;
Joe2.strength = 10;
Joe2.ap = 10;
Bob2.hp = 110;
Bob2.strength = 45;
Bob2.ap = 10;
int y2;
std::vector<int> Choices; //I didn't know how else to have 2 values stored in one thing
std::cout << "Player 1, Choose your fighter: ";
std::cin >> y2;
Choices.push_back(y2);
int y; //I supposed I didn't have to make a vector but it's too late
std::cout << "Player 2, Choose your fighter: ";
std::cin >> y;
Choices.push_back(y);
if (Choices[0] == 1 && Choices[1] == 2) {
game_cycle(Joe, Bob, at, at1, at2, at3, at4, at5, at6, at7, at8, turn);
}
if (Choices[0] == 2 && Choices[1] == 2) {
game_cycle(Bob, Bob2, at, at1, at2, at3, at4, at5, at6, at7, at8, turn);
}
if (Choices[0] == 1 && Choices[1] == 1) {
game_cycle(Joe, Joe2, at, at1, at2, at3, at4, at5, at6, at7, at8, turn);
}
if (Choices[0] == 2 && Choices[1] == 1) {
game_cycle(Bob, Joe, at, at1, at2, at3, at4, at5, at6, at7, at8, turn);
}
else {
std::cout << "Invalid Input!\n";
return 0;
}
}
Here is the header file:
#pragma once
class Character
{
public: //I originally wasn't going to make the stats public but then realised it would've been harder to manage
double hp;
int strength;
int ap;
void set_hp(int x);
void set_strength(int x);
void lower_ap(int x);
int get_hp();
};
class Attacks /*this could be the parent class of other types of attacks, such as elemental attacks (elements could be stuff like if the character is
cappie or not*/
{
int burning_damage = 10; //We could have different status effects
int poison_damage = 7; //Plus they're unused because I forgot to use them in the Skeleton
public:
int attack(int x, int y);
int status_effect_damage(int x, int y);
};
class Leftist_Char : public Character {
public:
bool rightist = false;
bool leftist = true;
int left_axis;
};
class LibLeft : public Leftist_Char {
public:
bool Lib = true;
bool rightist = false;
bool Auth = false;
bool leftist = true;
int libertarian_axis;
};
class Authleft : public Leftist_Char {
public:
int auth_axis;
bool Libertarian = false;
bool rightist = false;
bool Auth = true;
bool leftist = true;
};
class Rightist_Char : public Character {
public:
int right_axis;
bool rightist = true;
bool leftist = false;
};
class Libright : public Rightist_Char {
public:
int lib_axis;
bool Libertarian = true;
bool rightist = true;
bool Auth = false;
bool leftist = false;
};
class Authright : public Rightist_Char {
public:
int auth_axis;
bool Libertarian = false;
bool rightist = true;
bool Auth = true;
bool leftist = false;
};
class Left_Attacks : public Attacks {
public: //first int is the base damage of the attack, the second is the variable that'll be modified, third is their left axis level so I can do-
//-damage multipliers correctly, third is the required level so it can be subtracted from the Leftist axis while calculating the damage boost
double leftist_attack(int damage, double health, int leftist_axis, int requirement);
};
class Right_Attacks : public Attacks {
public:
double rightist_attack(int damage, double health, int rightist_axis, int requirement);
};
class Auth_Attacks : public Attacks {
public:
double auth_attack(int damage, double health, int auth_axis, int requirement);
};
class Lib_Attacks : public Attacks {
public:
double lib_attack(int damage, double health, int lib_axis, int requirement);
};
class LibLeft_Attacks : public Attacks {
public:
double libleftist_attack(int damage, double health, int leftist_axis, int requirement, int lib_axis, int requirement2);
};
class AuthLeft_Attacks : public Attacks {
public:
double authleftist_attack(int damage, double health, int leftist_axis, int requirement, int auth_axis, int requirement2);
};
class AuthRight_Attacks : public Attacks {
public:
double authrightist_attack(int damage, double health, int rightist_axis, int requirement, int auth_axis, int requirement2);
};
class LibRight_Attacks : public Attacks {
public:
double librightist_attack(int damage, double health, int right_axis, int requirement, int lib_axis, int requirement2);
};
template <class T, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11>
int game_cycle(T charachter, T2 charachter2, T3 attacky, T4 attacky1, T5 attacky2, T6 attacky3, T7 attacky4, T8 attacky5, T9 attacky6, T10 attacky7, T11 attacky8, bool turn);
Here is the cpp file with the method definitions:
#include "Header.h"
void Character::set_hp(int x) {
hp = x;
}
void Character::set_strength(int x) {
strength = x;
}
void Character::lower_ap(int x) {
ap = ap - x;
}
int Character::get_hp() {
return hp;
}
int Attacks::attack(int x, int y) {
int y2 = 20 + y;
x = x - y2;
return x;
}
double Left_Attacks::leftist_attack(int damage, double health, int leftist_axis, int requirement) {
int x = leftist_axis - requirement;
int x2 = damage / 100;
int x3 = x2 * leftist_axis;
int x4 = damage + x3;
int x5 = health - x4;
return x5;
}
double Right_Attacks::rightist_attack(int damage, double health, int rightist_axis, int requirement) {
int x = rightist_axis - requirement;
int x2 = damage / 100;
int x3 = x2 * rightist_axis;
int x4 = damage + x3;
int x5 = health - x4;
return x5;
}
double Auth_Attacks::auth_attack(int damage, double health, int auth_axis, int requirement) {
int x = auth_axis - requirement;
int x2 = damage / 100;
int x3 = x2 * auth_axis;
int x4 = damage + x3;
int x5 = health - x4;
return x5;
}
double Lib_Attacks::lib_attack(int damage, double health, int lib_axis, int requirement) {
int x = lib_axis - requirement;
int x2 = damage / 100;
int x3 = x2 * x;
int x4 = damage + x3;
int x5 = health - x4;
return x5;
}
double LibLeft_Attacks::libleftist_attack(int damage, double health, int lib_axis, int requirement, int left_axis, int requirement2) {
int x = lib_axis + left_axis;
int x2 = requirement + requirement2;
int x3 = x - x2;
int x4 = damage / 100;
int x5 = x4 * x3;
int x6 = damage + x5;
int x7 = health - x6;
return x7;
}
double AuthLeft_Attacks::authleftist_attack(int damage, double health, int left_axis, int requirement, int auth_axis, int requirement2) {
int x = auth_axis + left_axis;
int x2 = requirement + requirement2;
int x3 = x - x2;
int x4 = damage / 100;
int x5 = x4 * x3;
int x6 = damage + x5;
int x7 = health - x6;
return x7;
}
double AuthRight_Attacks::authrightist_attack(int damage, double health, int left_axis, int requirement, int auth_axis, int requirement2) {
int x = auth_axis + left_axis;
int x2 = requirement + requirement2;
int x3 = x - x2;
int x4 = damage / 100;
int x5 = x4 * x3;
int x6 = damage + x5;
int x7 = health - x6;
return x7;
}
double LibRight_Attacks::librightist_attack(int damage, double health, int right_axis, int requirement, int lib_axis, int requirement2) {
int x = lib_axis + right_axis;
int x2 = requirement + requirement2;
int x3 = x - x2;
int x4 = damage / 100;
int x5 = x4 * x3;
int x6 = damage + x5;
int x7 = health - x6;
return x7;
}
And here is my last cpp file with my game loop function:
#include <iostream>
#include "Header.h"
//T, T, T, T, T, T, T, T, bool
//charachter charachter2 attacky
/* This is where the turn cycle happens and where we can act. It takes two characters because there are two characters fighting, an attack object
because those are the actions, and a bool turn because I couldn't be bothered to declare a bool inside the function*/
//I also know that I misspelt character but by the time I noticed it, it was too late
template <class T, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11>
int game_cycle(T charachter, T2 charachter2, T3 attacky, T4 attacky1, T5 attacky2, T6 attacky3, T7 attacky4, T8 attacky5, T9 attacky6, T10 attacky7, T11 attacky8, bool turn) {
do { /*This "do while" loop is the main game loop. I chose a "do while" loop because with that, it's guaranteed to play out once so it's easier to
start the loop */
if (turn == true && charachter.hp > 0 && charachter2.hp > 0) {
std::cout << "Player 1's Turn\n";
std::cout << "Do you want to attack? [y/n]: ";
char x;
std::cin >> x;
if (x == 'y') {
std::cout << "How do you want to attack? \n 1: Strenght attack \n 2: Magic Attack \n 3: Heal Yourself [1, 2, 3]: ";
int r;
std::cin >> r;
if (r == 1 && charachter.ap >= 2) {
charachter2.set_hp(attacky.attack(charachter2.hp, charachter.strength));
charachter.lower_ap(1);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
turn = true;
}
if (r == 2 && charachter.ap >= 3) {
if (charachter.leftist == true && charachter.rightist == false && charachter.Auth == false && charachter.Lib == true) {
int r;
std::cout << "Do you want to do a: 1) Leftist attack\n 2) Libertarian attack\n 3) Libleft attack[1, 2, 3]: ";
std::cin >> r;
if (r == 1) {
charachter2.set_hp(attacky1.leftist_attack(15, charachter2.hp, charachter.left_axis, 1));
charachter.lower_ap(3);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
}
if (r == 2) {
charachter2.set_hp(attacky3.lib_attack(15, charachter2.hp, charachter.lib_axis, 1));
charachter.lower_ap(3);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
}
if (r == 3) {
charachter2.set_hp(attacky4.libleftist_attack(15, charachter2.hp, charachter.lib_axis, 1, charachter.left_axis, 1));
charachter.lower_ap(3);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
}
}
}
else if (charachter2.ap <= 0) {
std::cout << "You don't have enough AP to do anything, so you rest \n\n";
charachter2.ap++;
}
else {
std::cout << "Invalid input! \n\n";
turn = false;
}
}
else if (x == 'n') {
std::cout << "You rest and gain +1 AP" << std::endl << std::endl;
charachter2.ap++;
turn = false;
}
if (turn == false && charachter2.hp > 0 && charachter.hp > 0) {
std::cout << "Player 2's Turn\n";
std::cout << "Do you want to attack? [y/n]: ";
char x;
std::cin >> x;
if (x == 'y') {
std::cout << "How do you want to attack? \n 1: Strenght attack \n 2: Political Attack \n[1, 2]: ";/* Idk if I should
have the "[1,2,3]"
seperate or connected*/
int r;
std::cin >> r;
if (r == 1 && charachter.ap >= 2) {
charachter2.set_hp(attacky.attack(charachter2.hp, charachter.strength));
charachter.lower_ap(1);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
turn = true;
}
if (r == 2 && charachter.ap >= 3) {
if (charachter.leftist == true && charachter.rightist == false && charachter.Auth == false && charachter.Lib == true) {
int r;
std::cout << "Do you want to do a: 1) Leftist attack\n 2) Libertarian attack\n 3) Libleft attack[1, 2, 3]: ";
std::cin >> r;
if (r == 1) {
charachter2.set_hp(attacky1.leftist_attack(15, charachter2.hp, charachter.left_axis, 1));
charachter.lower_ap(3);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
}
if (r == 2) {
charachter2.set_hp(attacky3.lib_attack(15, charachter2.hp, charachter.lib_axis, 1));
charachter.lower_ap(3);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
}
if (r == 3) {
charachter2.set_hp(attacky4.libleftist_attack(15, charachter2.hp, charachter.lib_axis, 1, charachter.left_axis, 1));
charachter.lower_ap(3);
std::cout << "Player 1's health was lowered to " << charachter2.hp << std::endl << std::endl;
}
}
}
else if (charachter.ap <= 0) {
std::cout << "You don't have enough AP to do anything, so you rest \n";
charachter.ap++;
}
else {
std::cout << "Invalid input! \n";
turn = true;
}
}
else if (x == 'n') {
std::cout << "You rest and gain +1 AP \n \n";
charachter.ap++;
turn = true;
}
}
if (charachter.hp <= 0) {
std::cout << "Player 2 has Lost \n"; //I should think of a better way of announcing the loss of a player
return 0;
}
if (charachter2.hp <= 0) {
std::cout << "Player 1 has lost \n";
return 0;
}
}
} while (charachter2.hp > 0 || charachter.hp > 0);
return 0;
}
Here is the error message:
1>------ Build started: Project: Jreg Fighter, Configuration: Debug x64 ------
1>Functions.cpp
1>Jreg_Fighter.cpp
1>Generating Code...
1>Jreg_Fighter.obj : error LNK2019: unresolved external symbol "int __cdecl game_cycle<class Character,class Character,class Attacks,class Left_Attacks,class Right_Attacks,class Lib_Attacks,class LibLeft_Attacks,class Auth_Attacks,class LibRight_Attacks,class AuthLeft_Attacks,class AuthRight_Attacks>(class Character,class Character,class Attacks,class Left_Attacks,class Right_Attacks,class Lib_Attacks,class LibLeft_Attacks,class Auth_Attacks,class LibRight_Attacks,class AuthLeft_Attacks,class AuthRight_Attacks,bool)" (??$game_cycle@VCharacter@@V1@VAttacks@@VLeft_Attacks@@VRight_Attacks@@VLib_Attacks@@VLibLeft_Attacks@@VAuth_Attacks@@VLibRight_Attacks@@VAuthLeft_Attacks@@VAuthRight_Attacks@@@@YAHVCharacter@@0VAttacks@@VLeft_Attacks@@VRight_Attacks@@VLib_Attacks@@VLibLeft_Attacks@@VAuth_Attacks@@VLibRight_Attacks@@VAuthLeft_Attacks@@VAuthRight_Attacks@@_N@Z) referenced in function main
1>C:\Users\basyu\source\repos\Jreg Fighter\x64\Debug\Jreg Fighter.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "Jreg Fighter.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I'll happily answer your questions if you don't understand something about the code. Please help, I'm bad at C++