How to properly plan a program?

Pages: 12
closed account (L6b7X9L8)
So I have a project that I am determined to finish, however I am struggling to understand exactly how each part of my program works with each other.

So far most of my programs how been introductions to C++ keywords and how they work, such as void, if, switch etc etc. I have the jist of it and I am able to create programs which utilize them, but only in a procedural fashion.

I am trying to learn OOP by using classes and defining what my objects are, but I am struggling with understand how my objects work with each other.


As of right now I have a finished object, BattleBot. The BattleBot class uses other objects ( Motherboard, Armor, Motor, Weapon, Sensor ) in which the BattleBot is constructed.

Here is my code, I'm sorry that it is long, I couldn't see a 'Spoiler' tag.

Module.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef MODULE_H
#define MODULE_H

#include <string>

using std::string;

/***************************************************************

Each BattleBot consists of several modules; A Motherboard, Armor, Motor and a Weapon.

A Motherboard consists of a CPU module and a RAM module, with it's own MaxWeight attribute.

***************************************************************/

class Module // This is the base class of all the Modules, the rest of the classes inherit these 2 attributes and functions.
{
public:
	Module::Module();
	Module::Module(string name, int cost);
	Module::~Module();
	string getName() { return ModuleName; }	// Function that returns the name of a Module
	int getCost() { return ModuleCost; }		// Function that returns the cost of a Module

protected:

	const string ModuleName;				// Allocated memory to store the name of a Module
	const int ModuleCost;					// Allocated memory to store the cost of a Module
};

/////////////////////////////////////////////////////////////////////////////////////

class CPU: public Module // CPU class: The CPU of the BattleBot determines how many actions a BattleBot can do in one turn.
{						 // This is determined by how many Threads the CPU has and it's Speed.
public:

	CPU::CPU();
	CPU::CPU(string name, int cost, int threads, int speed);
	CPU::~CPU();
	int getThreads() { return Threads; }
	int getSpeed() { return Speed; }

private:

	const int Threads;
	const int Speed;

};

class RAM: public Module
{
public:

	RAM::RAM();
	RAM::RAM(string name, int cost, int space);
	RAM::~RAM();
	int getSpace() { return Space; }

private:

	const int Space;
};

//////////////////////////////////////////////////////////////////////////////////////

class Motherboard: public Module
{
public:

	Motherboard::Motherboard();
	Motherboard::Motherboard(string name, int cost, CPU *cpu, RAM *ram, int maxweight);
	Motherboard::~Motherboard();
	CPU mCPU;
	RAM mRAM;
	int getMaxWeight() { return MaxWeight; }
	
private:

	const int MaxWeight;
	
};

class Armor: public Module
{
public:

	Armor::Armor();
	Armor::Armor(string name, int cost, int defense, int weight);
	Armor::~Armor();
	int getDefense() { return Defense; }
	int getCurrentDefense() { return CurrentDefense; }
	int getWeight() { return Weight; }
	void takeDamage(int dam) 
	{ 
		CurrentDefense -= dam;
		if(CurrentDefense < 0)
		{
			CurrentDefense = 0;
		}
	}

private:

	const int Defense;
	int CurrentDefense;
	const int Weight;

};

class Motor: public Module
{
public:

	Motor::Motor();
	Motor::Motor(string name, int cost, int speed, int weight);
	Motor::~Motor();
	int getSpeed() { return Speed; }
	int getWeight() { return Weight; }

private:

	const int Speed;
	const int Weight;

};

class Weapon: public Module
{
public:

	Weapon::Weapon();
	Weapon::Weapon(string name, int cost, int damage, int weight);
	Weapon::~Weapon();
	int getDamage() { return Damage; }
	int getWeight() { return Weight; }

private:

	const int Damage;
	const int Weight;

};

class Sensor: public Module
{
public:

	Sensor::Sensor();
	Sensor::Sensor(string name, int cost, int range, int weight);
	Sensor::~Sensor();
	int getRange() { return Range; }
	int getWeight() { return Weight; }

private:

	const int Range;
	const int Weight;

};

#endif 




BattleBot.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef BATTLE_BOT_H
#define BATTLE_BOT_H

#include "Module.h"

class BattleBot
{

public:

	BattleBot::BattleBot();
	BattleBot::BattleBot(Motherboard *mobo, Armor *armor, Motor *motor, Weapon *weapon, Sensor *sensor);
	BattleBot::~BattleBot();

	Motherboard bMotherboard;
	Armor bArmor;
	Motor bMotor;
	Weapon bWeapon;
	Sensor bSensor;

};

#endif 



So now I can create a BattleBot object and construct it using different 'Parts'. Now I am wondering, how do I use this BattleBot object to put it on a "Map" so it can fight a computer BattleBot?

Also how do I get my 'Sensor' module to sense where another BattleBot is so I can add some more logic to my BattleBot so I can program it what to do if another BattleBot is near.

I've been able to plan what my BattleBot is and what it can do, but not how it does it, I feel kind of stupid as I feel I might have to do this all over again.

I appreciate any help and code people can give me so I don't have to re-write this entire project from scratch.
closed account (j3Rz8vqX)
Since this is in the lounge now, more folks can contribute to non-objective theory-crafting; possible production of useful tangents.

First off:
I am wondering, how do I use this BattleBot object to put it on a "Map" so it can fight a computer BattleBot?
What graphics library are you using? What input library?

If you're on console and possibly windows, a relative input solution would be either conio.h or windows:
http://www.cplusplus.com/forum/beginner/131826/

Graphics is another story...

Possibly learn sfml or sdl:

sfml: Object Orientated library with access to graphics, sound, input, network, and a bunch of other goodies.

sdl: C like library that has similar access to sfml; possibly a tiny bit more portability with ports to mod communities to hand held devices (PSP, NDS, ect...)

Both has its pros and cons; simply stating two available libraries.

Have fun.
closed account (L6b7X9L8)
I'm not using any library, I was planning on just doing some cout's on every action, not really much graphics or moving about, just wanting to simulate what's happening in the logic if you get what I mean?

 
cout << "You got hit! Your armor's durability is now: " << Player->bArmor.getCurrentDefense << "\n";


My current objective is making a Map class, passing 2 BattleBots to it and letting them fight it out till one of them is destroyed.

EDIT:

I was thinking of creating an array 25x25 and putting 2 BattleBots in it, however BattleBot's aren't an integer or char or anything, so I'm unsure how to make a plane of space for them to sit in, move around it and fire at each other.


/EDIT

A secondary objective is creating an Engine class in which I can tie all this together, which it can call functions such as gotoShop, createBotFromBoughtParts etc etc.
Last edited on
closed account (j3Rz8vqX)
Also how do I get my 'Sensor' module to sense where another BattleBot is so I can add some more logic to my BattleBot
This is an issue of detection(collision) and physics.

I'm no specialist in physics (yet) but a simple solution would be to compare your location (x,y) against every other mobile objects location (x,y) to predetermine AI behavior.

You can also use a detection algorithm to determine visibility of objects.
Example: Simple cubic vision of 5 units plus and minus your x and y coordinates.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <conio.h>
using namespace std;
struct Object
{
public:
    int x,y;
    char sprite;
    Object()
    {
        x=y=2;          //default location (2,2);
        sprite='@';     //default sprite (@);
    }
    char draw();
};
namespace global
{
    const static char esc = 27;//Escape;
    const static char cr = 13;//Carriage return;
    const static char etx = 3;//Ctrl-C; end of text;

    const static int SIZEX = 38;//Map size(X);
    const static int SIZEY = 20;//Map size(Y);
    char map[SIZEY][SIZEX] =
                                         {"#####################################",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#####################################",
					 "#####################################",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#####################################",
					 "#####################################",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#####################################",
					 "#####################################",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#   #   #   #   #   #   #   #   #   #",
					 "#####################################"};
    Object player;
    char input;
    int adjustScreen=0;
}
void adjust(int y)
{
    if(y>0)
    {
        for(int i=0;i<y;i++)
            cout<<endl;
    }
}
bool heroVision(int i,int x,int y){
    if(x<global::player.x-i || x>global::player.x+i)
        return false;
    if(y<global::player.y-i || y>global::player.y+i)
        return false;
    return true;
}
void draw()
{
    adjust(100);
    for(int y=0;y<global::SIZEY;++y)
    {
        for(int x=0;x<global::SIZEX;++x)
        {
            if(x == global::player.x && y == global::player.y)
            {
                cout<<global::player.sprite;
            }
            else
            {
                if(heroVision(5,x,y))
                    cout<<global::map[y][x];
                else
                    cout<<'%';
            }
        }
        cout<<endl;
    }
    cout<<"w=Up; s=Down; a=Left; d=Right; #=adjustScreen; esc/ctrl-c = QUIT"<<endl;
    adjust(global::adjustScreen);
}
bool event(char input)
{
    if(input=='w')
    {
        --global::player.y;
        return true;
    }
    if(input=='s')
    {
        ++global::player.y;
        return true;
    }
    if(input=='a')
    {
        --global::player.x;
        return true;
    }
    if(input=='d')
    {
        ++global::player.x;
        return true;
    }
    //Adjust command prompt:
    if(input>='0'&&input<='9')
    {
        global::adjustScreen=input-'0';
        return true;
    }

    //Unimplemented key entered:
    return false;

}
void debug()
{
    cout<<"x: "<<global::player.x<<" y: "<<global::player.y<<" Adjust: "<<global::adjustScreen<<endl;//Also. display space adjustment
}
int main()
{
    draw();
    debug();
    do
    {
        if(event(global::input = getch()))
        {
            draw();
            debug();
        }
    }while(global::input!=global::esc && global::input!=global::etx);
    return 0;
}


This example is demonstrating restriction of vision and simple input features. Simply drawing sprites, fog, and maze.
Last edited on
closed account (L6b7X9L8)
How would I make that more object orientated?

In this example your Map is an array of characters and the object occupies a space within that array.

My sensor module is encapsulated within the BattleBot class and cannot interact with the Array outside of it's scope, is there any other way?

In my head I was thinking along the lines of:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
    User creates it's bot and chooses the fight option
*/

Map level1 = new Map(BattleBot *Player, BattleBot *Level1Enemy);

While(Player->bArmor.getCurrentDefense() > 0 && Level1Enemy->getCurrentDefense() > 0) // Edit: Did || instead of &&
{
    Map->runCommand(*Player);  // The user does not control the bot directly, they program it before the fight
    Map->UpdateStatistics();
    Map->runCommand(*Level1Enemy); // The AI bots have a pre built program  it utilizes
    Map->UpdateStatistics();
}

if(Player->isDead())
{
    Loose();
}
else
{
    Win();
}

delete level1;
delete Player;
delete Level1Enemy;

// Refreshes everything for the next bout


I'm sorry if I'm getting the wrong end of the stick here.
Last edited on
closed account (j3Rz8vqX)
How would I make that more object orientated?

Not sure what you're asking.
My sensor module is encapsulated within the BattleBot class and cannot interact with the Array outside of it's scope, is there any other way?
I do not know the intentions of sensor and will assume that it is combat detection related.

You can always implement get methods.

What is your approach?

What is runCommand doing?
closed account (L6b7X9L8)
Okay I'll try and explain this best I can, however I struggle getting my thoughts out into writing for some bizarre reason.

For object orientation I would like every aspect of this program put into it's own class, just like the modules and BattleBot. Maybe this is the wrong way to go about it ( Hence the title: How to properly plan a program ) so I'm actually unsure of my next steps. All I know is that so far I can create a BattleBot object, which is no use on it's own.

I was hoping I could have a Map class, Shop class and the like so I could have the program sectioned off into pieces so it's not all the main and get extremely messy ( Like many of my existing programs ). I wanted to encapsulate functions relative to it's variables to make maintenance easier and leave room for expansion without having to change things through hundreds of lines of code.

I hope you are with me so far...

The 'Sensor' is a module that can be added to the BattleBot. In my head I saw this as an invisible circle surrounding the BattleBot with the Sensor::Range being the diameter radius. It's similar to the functionality of your HeroVision functions, however it detects if another BattleBot is nearby, or perhaps approaching a wall.

The get method for the range of this is basically:

 
BattleBot->bSensor.getRange(); // Returns the range of the Sensor equipped to the BattleBot 


Module.h

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
class Sensor: public Module
{
public:

	Sensor::Sensor();
	Sensor::Sensor(string name, int cost, int range, int weight);
	Sensor::~Sensor();
	int getRange() { return Range; }
	int getWeight() { return Weight; }

        // Functions need to be added here for Detection

private:

	const int Range;
	const int Weight;

};



So far I do not have an approach nor idea for getting the Sensor module to interact with the game world. I'm hoping someone can give me some ideas.

runCommand was pseudocode. My idea for this game was instead of people taking control of their player directly like most games, I wanted to try something different where the player has to program their Robot before the fight. It would run through that code until the enemy were destroyed or itself was destroyed. The player would have to upgrade it's RAM module as it wins fights to upgrade how much space it has to add more advanced logic.

^ This is possible way out of my scope, but you can't blame a man for trying. I had a simple syntax in mind.

Sense - Get's information about it's surrounding environment
if(Sense.Enemy): Aim, FireWeapon - Faces enemy, fires at it
if(Sense.HitWall): TurnLeft - Turns 90 degrees to it's left
Repeat
Last edited on
closed account (j3Rz8vqX)
BattleBot would seem to need to return its sensor; will you not enable a get function for sensor range?
closed account (L6b7X9L8)
Return it's sensor? meaning the object Sensor?

I have a get Sensor range function

int Sensor::getRange() { return Range; }

As the Sensor is part of the BattleBot ( And the BattleBot is created after every fight due to adding new parts and what not )

BattleBot->bSensor.getRange();

EDIT:

I'm sorry if I am dense, it's 3am and it's really annoying me because I want to get this part finished.
Last edited on
closed account (j3Rz8vqX)
I do not have an approach nor idea for getting the Sensor module to interact with the game world

Sensor is public, it can react if needed, I think you mean you've yet to design a way for map to interact with sensor, not the other way around; my misinterpretation.

I was thinking of creating an array 25x25 and putting 2 BattleBots in it, however BattleBot's aren't an integer or char or anything, so I'm unsure how to make a plane of space for them to sit in, move around it and fire at each other.


The first sentence says you want a 25 by 25 grid. The second says you are unsure of how to create the plane.

First:
vector of 25x25? (creating the plane - done)

Second://Think here first!
Unit size? (unknown - possibly 1 character unit? or 4 char units?)
**
**

"sit in, move around it and fire at each other" can be dealt with later.
closed account (L6b7X9L8)
Huh... So the Map interacts with the Sensor? I thought the Sensor was the 'Eyes' of the Robot, I figured the sensor would have to interact with the map as our eyes interact with our environment.

It's 4am and I will take your word for it. :)


I have never used a vector before when I first saw it's implementation it scared me off a bit and I never got round to using it.


I was thinking that 1 BattleBot takes up 1 unit of space and 8 orientations.

N, NE, E, SE, S, SW, W, NW
closed account (j3Rz8vqX)
1
2
3
4
5
6
7
While(Player->bArmor.getCurrentDefense() > 0 && Level1Enemy->getCurrentDefense() > 0) // Edit: Did || instead of &&
{
    Map->runCommand(*Player);  // The user does not control the bot directly, they program it before the fight
    Map->UpdateStatistics();
    Map->runCommand(*Level1Enemy); // The AI bots have a pre built program  it utilizes
    Map->UpdateStatistics();
}
Based on the above, it would seem that your Map class is also your event processing class; unless I'm misinterpreting something.

Map->runCommand(*Player);
Map will need to interact with player to determine players behavior; example: is the opponent within range.

Unless Map->UpdateStatistics(); will because there are no other processes.

Normally a map object would do what its name implies: contains a map.

In this situation, it would seem it is a zone(game object) that should supply processes for player and enemy.
closed account (j3Rz8vqX)
As for vectors, they are simply containers:
http://www.cplusplus.com/reference/stl/

Vector would have constructors, destructor, and accessors:
http://www.cplusplus.com/reference/vector/vector/

After construction, it will act similar to an array:
1
2
3
4
5
int main()
{
    vector<int> myVector(10,0);//Array size = 10, with values assigned 0;
    return 0;
}
http://www.cplusplus.com/reference/vector/vector/vector/

You would access it the same as arrays and it can be dynamically increased with the push_back(0) method, adding to the end:
http://www.cplusplus.com/reference/vector/vector/push_back/
pop_back() would dynamically decrease it by 1 unit, removing the last unit:
http://www.cplusplus.com/reference/vector/vector/pop_back/

Unless you're comfortable with primitive arrays, especially with dynamic allocations, you should invest some time into learning vector; it will handle dynamic sizing for the programmer.
closed account (L6b7X9L8)
I appreciate all your help Dput.

I'm struggling to understand what I am supposed to be doing. I had a great idea in my head but I feel like I just can't get it into code. I might just have to give up with it for a few years until I fully understand what C++ is about.

I think I should first refine what an object is, how this object is controlled and how that object interacts with other objects.

Thanks for everything, friend.
I had a great idea in my head but I feel like I just can't get it into code

There's a reason software engineers are paid the big bucks :)

It's not something that will just go straight from idea to implementation. It takes time to figure out how all the moving parts will work together. Lots of prototyping ideas.

So, don't get discouraged. Keep at it.
closed account (L6b7X9L8)
You are right, I've been trying to plan stuff out but it seems even my plans are messed up from that start, maybe coding just isn't for me which sucks. I were really excited about this.
Its a skill. It takes lots of time to get decent at. Reading books and articles by experts will greatly help. Picking up a book on design patterns is recommended. Design Patterns: Elements of Reusable Object-Oriented Software is something everybody in software needs to read. You can find free PDFs of it online.

And just write code. Don't get discouraged. You're going to write bad code. You will have a bad designs. You will scrap more code than you write :) But you will learn from all of it. Nobody starts off an expert.
closed account (L6b7X9L8)
Thanks for your encouragement :)

I have just downloaded that book, I will give it a read while my girlfriend studies. Hopefully it's noob friendly?

I have been doing C++ for a couple of years now on and off. I can build simple programs but that's it. If I ever try to expand my boundaries I just fall flat on my face. I can make toast without thinking, but I can't make creme brulee no matter how hard I try.

It's a real downer because when you actually find something you enjoy, and you can't hack it.. it really does make you feel like crap. I'm not good at much stuff and I really want to be good at this.
It's fairly noob friendly. It's not based on any language, it's just about some of the most common design patterns that pop up in software.

You might be trying too much too quickly. If you want a really fun (in my opinion) project to get you exposed to several different skills, go make an IRC bot. Know nothing about IRC? That's fine, it's a super simple protocol. And network programming can be super fun. You see real world results almost immediately. If this interests you, join us at irc.quakenet.org #cplusplus and we'll help you.
Last edited on
closed account (L6b7X9L8)
Yes I see that, I am flicking through it now before I have something to eat. It's rather in depth and dense I hope I can force myself to read through it. Through school I always struggled with books without examples but I will do my best.

Isn't an IRC like a chat room? That's what I always thought it were haha. Not sure what an IRC Bot is but I have a free couple of days to try and get one up and running. I copied and pasted your link but it seems like it doesn't want to connect? Sorry if I'm being retarded.
Pages: 12