yet another n00b and his c++ crap ^^ (but it compiles at least)

Started by
4 comments, last by nobodynews 14 years, 10 months ago
Sorry first of all i have not found a code block funktion so i post the code normal here im one of those ppl that think they can do better blabla but dont seem to be true :P anyhow im getting my programm to run but it wont do everything as i would wish it to since i startet like a week ago and i work and take care of reallife so kinda limitied about codingtime. btw dont take my english to serios im a kraut :P here my code now tho my biggest problems i have addressed with // ;) it would be very kind if anyone had some time to give me a clue what im doing wrong, and i would be glad if anyone would tell me if the code is readebl seems there are alot of ppl that format it badly so its a pain to see throu it.
   
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <limits>
#include <cctype>

#include <String>

using std::cout;
using std::cin;
//using namespace std;

bool ambush();

/*public class Tank{				// dont seem to work yet that i extend tiger and sherman from the basic tank...
public:
int front, right, left, back, antitank;

	  int shootmaingun(){
      int firepower;
      firepower = antitank + rand() % 6+1;
      return firepower;
      }

	  int getfront(){
      return front;
      }
	  int getright(){
      return right;
      }
	  int getleft(){
      return left;
      }
	  int getback(){
      return back;
      }
	  int getantitank(){
      return antitank;
      }

	  int move(){
	  int random;
	  random = rand() % 10+1;
	  
	  switch(random){
		case 1:
			cout<<"Sie fahren weiter aber entdecken nichts ungewoenliches!\n";
			break;
        case 2:
			cout<<"Sie fahren weiter aber entdecken nichts ungewoenliches!\n";
			break;
        case 3:
			cout<<"Feindlicher Panzer vorraus!\n";
			ambush();
			break;
        case 4:
			cout<<"Sie fahren weiter aber entdecken nichts\n";
			break;
        case 5:
			cout<<"Sie fahren weiter aber entdecken nichts ungewoenliches!";
			break;
        case 6:
			cout<<"Feindlicher Panzer vorraus!\n";
			ambush();
			break;
        case 7:
			cout<<"Feindlicher Panzer vorraus!\n";
			ambush();
			break;
        case 8:
			cout<<"Feindlicher Panzer vorraus!\n";
			ambush();
			break;
		case 9:
			cout<<"Sie fahren weiter aber entdecken nichts\n";
			break;
		case 10:
			cout<<"Sie fahren weiter aber entdecken nichts\n";
			break;
	  }
	  }

};*/

public class M4Sherman{
private:
int front, right, left, back, antitank;

public:
M4Sherman(){
front = 10;
antitank = 12;
}

	  int shootmaingun(){
      int firepower;
      firepower = antitank + rand() % 6+1;
      return firepower;
      }

	  int getfront(){
      return front;
      }
	  int getright(){
      return right;
      }
	  int getleft(){
      return left;
      }
	  int getback(){
      return back;
      }
	  int getantitank(){
      return antitank;
      }

};

public class Tiger{
private:
int front, right, left, back, antitank;

public:
Tiger(){
front = 18;
antitank = 18;
}

	  int shootmaingun(){
      int firepower;
      firepower = antitank + rand() % 6 + 1;
      return firepower;
      }

	  int getfront(){
      return front;
      }
	  int getright(){
      return right;
      }
	  int getleft(){
      return left;
      }
	  int getback(){
      return back;
      }
	  int getantitank(){
      return antitank;
      }

	  int move(){
	  int random;
	  random = rand() % 10+1;
	  
	  switch(random){
		case 1:
			cout<<"Sie fahren weiter aber entdecken nichts ungewoenliches!\n";
			return 0;
			break;
        case 2:
			cout<<"Sie fahren weiter aber entdecken nichts ungewoenliches!\n";
			return 0;
			break;
        case 3:
			//here it should kinda return false so i can break and lead 
			ambush();
			return 1;							  //over into the fight
			break;
        case 4:
			cout<<"Sie fahren weiter aber entdecken nichts\n";
			return 0;
			break;
        case 5:
			cout<<"Sie fahren weiter aber entdecken nichts ungewoenliches!\n";
			return 0;
			break;
        case 6:
			//here it should kinda return false so i can break and lead
			ambush();
			return 1;								//over into the fight
			break;
        case 7:
			//here it should kinda return false so i can break and lead
			ambush();
			return 1;								//over into the fight
			break;
        case 8:
			//here it should kinda return false so i can break and lead
			ambush();
			return 1;								//over into the fight
			break;
		case 9:
			cout<<"Sie fahren weiter aber entdecken nichts\n";
			return 0;
			break;
		case 10:
			cout<<"Sie fahren weiter aber entdecken nichts\n";
			return 0;
			break;
	  }
	  }

};

bool ambush(){

	cout<<"Drei feindliche Panzer vorraus!\n";
	cout<<"Sie werden beschossen!\n";
	M4Sherman a,b,c; //how do i create a random number of foes anyway?
	Tiger z;
	
	bool alive;
	alive = 1;
	int schusseins;
	int schusszwei;
	int schussdrei;
	z.getfront();
	a.shootmaingun();

	schusseins  = a.shootmaingun();
	{
		if (alive == 0)
		return 0;
	if (z.getfront() > schusseins)
		cout<<"Ihr Panzer wurde getroffen, hat aber nur einen Kratzer abbekommen!\n";
	else
		cout<<"Ihr Panzer wurde getroffen und zerstoert!\n";
		alive = 0;//this ist somewhat bugging me it seems to chance alive even if the tank did not get hit
	}
	b.shootmaingun();

	schusszwei = b.shootmaingun();
	{
		if (alive == 0)
		return 0;
	if (z.getfront() > schusszwei)
		cout<<"Ihr Panzer wurde getroffen, hat aber nur einen Kratzer abbekommen!\n";

	else
		cout<<"Ihr Panzer wurde getroffen und zerstoert!\n";
		alive = 0;				//this ist somewhat bugging me it seems to chance alive even if the tank did not get hit
	}
	c.shootmaingun();

	schussdrei = c.shootmaingun();
	{
		if (alive == 0)
		return 0;
	if (z.getfront() > schussdrei)
		cout<<"Ihr Panzer wurde getroffen, hat aber nur einen Kratzer abbekommen!\n";
	else
		cout<<"Ihr Panzer wurde getroffen und zerstoert!\n";
		alive = 0;//this ist somewhat bugging me it seems to chance alive even if the tank did not get hit

		return alive;
	}

}

void main(){
	Tiger a;
	srand((unsigned)time(0));

	cout<<"Willkommen Kommandant ihre Besatzung erwartet ihre Anweisungen! \n";
	cout<<"Sie klettern auf ihren Panzer und nehmen ihren Platz ein. \n"<<"\n";

	cout<<"Ihnen wurde aufgetragen: \nMit ihrem Tiger vorzuruecken \n";
	cout<<"und auf kleinere feindliche Verbaende zu achten und sie im Notfall auch zu vernichten!\n";

	cout<<"\nWie lauten ihre Befehle?\n";
	cout<<"Ran an den Feind!\n";


		cout<<"Der Motor brummt sie beginnen ihre Mission.\n"<<"\n";
		
			if (a.move() == 0)
			a.move();
			else
				ambush();

			if (ambush() == false)				//same here even if the tank did not get hit alive was chanced to false somehow..
				cout<<"Die Mission ist gescheitert";
		
		
char f;
cin>>f;
}
 
so long and thanks for all the fish ;) [Edited by - derhenker on June 10, 2009 11:27:00 AM]
Advertisement
Quote:Original post by derhenker
Sorry first of all i have not found a code block funktion so i post the code normal here

Read here on how to use source tags.

Quote:it would be very kind if anyone had some time to give me a clue what im doing wrong, and i would be glad if anyone would tell me if the code is readebl seems there are alot of ppl that format it badly so its a pain to see throu it.

You haven't really given a very specific description of the problem. However, two things stand out immediately:

If you don't use brackets, only the execution of first instruction will depend on the if-else conditions.
if (z.getfront() > schusseins)  cout<<"Ihr Panzer wurde getroffen, hat aber nur einen Kratzer abbekommen!\n";else{  cout<<"Ihr Panzer wurde getroffen und zerstoert!\n";  alive = 0;//this ist somewhat bugging me it seems to chance alive even if the tank did not get hit}

Secondly, make sure you initialize you variables to some default value before using them (as in the case of front, right, left etc. in your tank class), preferably using an initialization list.
Quote:Original post by derhenker


/*public class Tank{ // dont seem to work yet that i extend tiger and sherman from the basic tank...


public class M4Sherman{

public class Tiger{


so you want to inherit tank's stuff for tiger and m4sherman?

class tank{

}

class M4Sherman : public tank{
}
You could you inheritance here, but I wouldn't. What you should do is make your code data driven. This means that you have a single tank class, but you make it configurable by giving it a constructor to set various parameters.

You can even retain your "take type" system by using an enumeration, and setting the tanks parameters based on which enumerated value is passed to the constructor.

I'm going to make some points about your code. First of all, "public" classes are a C++.net thing, not standard C++. You can simply omit them (C++ classes are all effectively public, unless you nest them inside one another or hide them in a source file rather than a header file).

In standard C++, main returns "int", not "void".

You should increase your warning level to as high as it can go. When I compile your code I get warned:
Quote:
warning C4715: 'Tiger::move' : not all control paths return a value

In this case, the warning is spurious. However, it does suggest that the code is brittle and further changes could easily cause this function to end without returning a value. This is a very bad idea. It is usually a good idea to put in some code that can handle cases that can "never" happen, because a few weeks later some innocent looking change can make them happen.

Here is a reworking of your code. It adds in the "random number of foes" you wanted, as well as making a player variable that is passed to the "ambush" function.

There are a few things I want to draw your attention to in particular. Note that I made all the tank variables private, and I didn't use "get" methods. Instead, the tank has operations that encapsulate the actions that it can do. This makes the code using these operations clearer.
//#include "stdafx.h"#include <iostream>#include <ctime>#include <limits>#include <cctype>// Use <string>, not <String>.// Some file systems are case sensitive, and will cause compile errors#include <string>#include <vector>#include <stdexcept>using namespace std;enum TankType{	M4SHERMAN, TIGER};class Tank{public:	Tank(TankType type)	{		if(type == M4SHERMAN)		{			front = 10;			antitank = 12;			health = 3; // Change this value to whatever you want.		}		else if(type == TIGER)		{			front = 18;			antitank = 18;			health = 10; // Change this value to whatever you want. I'm giving the player lots of health.		}		else		{			// This is another example of how to handle "impossible" conditions.			throw std::invalid_argument("Tank with invalid type being created");		}	}	int shootmaingun() const	{		// You don't have to name a temporary value		return antitank + rand() % 6+1;	}	bool shootAt(Tank &other) const	{		int attack = shootmaingun();		int damage = attack - other.front;		if(damage > 0)		{			other.health -= damage;			return true;		}		return false;	}	bool alive() const	{		return health > 0;	}	bool dead() const	{		return !alive();	}	private:	// I am making these private, and temporarily removing the unused values.	int front, /* right, left, back,*/ antitank, health;};// Declare the new ambush function.void ambush(Tank &player);void move(Tank &player){	// Initialise during declaration where possible.	int random = rand() % 10 + 1;	if(random < 4)	{		cout << "Sie fahren weiter aber entdecken nichts ungewoenliches!";	}	else if(random == 4)	{		cout << "Sie fahren weiter aber entdecken nichts\n";	}	else if(random < 9)	{		cout << "Feindlicher Panzer vorraus!\n";		ambush(player);	}	else	{		cout << "Sie fahren weiter aber entdecken nichts\n";	}}void ambush(Tank &player){	cout << "Drei feindliche Panzer vorraus!\n";	cout << "Sie werden beschossen!\n";		// You can create a random number of enemies using a container, like std::vector.	// I will demonstrate:	int enemyCount = rand() % 3 + 1;	// This line declares a variable sized array of Tank instances.	// The size is "enemyCount", and all the tanks are M4Shermans.	vector<Tank> enemies(enemyCount, Tank(M4SHERMAN));	// If you wanted, you could even add a tiger, or some other TankType	// like so:	// enemies.push_back(Tank(TIGER));	cout << "You have encountered " << enemyCount << " tanks\n";	// Keep going until the player is dead or all the enemies are.	while(player.alive() && !enemies.empty())	{		for(unsigned i = 0 ; i < enemies.size() ; ++i)		{			if(enemies.shootAt(player))			{				// I don't know German, but I'm sure you can provide a translation.				cout << "The enemy tank shot you and hit!\n";			}			else			{				cout << "The enemy tank missed.\n";			}		}		// Take a shot at the enemy. Choose a random one and try to hit it.		int enemy = rand() % enemies.size();		if( player.shootAt(enemies[enemy]) )		{			cout << "You shoot and hit!\n";		}		else		{			cout << "You miss.\n";		}		if(enemies[enemy].dead())		{			cout << "You destroyed the tank you hit.\n";			// Remove the element from the vector			enemies.erase(enemies.begin() + enemy);		}	}}int main(){	// It is preferred to use C++ casts, rather than C style.	// It does the same thing, but is far more explicit about what the purpose of the case s.	srand(static_cast<unsigned>(time(0)));	// Use whitespace liberally, particularly in expressions	cout << "Willkommen Kommandant ihre Besatzung erwartet ihre Anweisungen! \n";	cout << "Sie klettern auf ihren Panzer und nehmen ihren Platz ein. \n\n";	cout << "Ihnen wurde aufgetragen: \nMit ihrem Tiger vorzuruecken \n";	cout << "und auf kleinere feindliche Verbaende zu achten und sie im Notfall auch zu vernichten!\n";	cout << "\nWie lauten ihre Befehle?\n";	cout << "Ran an den Feind!\n";	cout << "Der Motor brummt sie beginnen ihre Mission.\n\n";		/*	// This is your original code	// The problem is that you are calling each function twice here, once in the condition.	// And again in the conditions body.	if (a.move() == 0)		a.move();	else		ambush();	if (ambush() == false)				cout<<"Die Mission ist gescheitert";	*/	// Note how I declare the variable "player" close to where it is used.	Tank player(TIGER);	move(player);		if(player.alive())	{		cout << "You survived the mission.\n";	}	else	{		cout << "You have died.\n";	}	// for an artificial pause, use this	cout << "Press enter key to continue...\n";		cin.get();}
Thanks so far for all these answers!

It is a pure beauty to see how in c++ the same things could be done so many ways.

looking at other peoples code is a fine thing to learn from as far as you understand what the code is suppost to do!

ill habe to look over it and try around with it.

so far thanks a lot ;)
I believe you meant this:
Quote:Original post by derhenker
It is a pure beauty to see how in programming the same things could be done so many ways.


C++ isn't unique in having multiple solutions to given problem. It may be unique in how easy it is to do something incorrectly even if you aren't aware of it at the time.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

This topic is closed to new replies.

Advertisement