PDA

View Full Version : C++ student question


Deathdust
04-24-2005, 07:49 AM
I'm currently adding save/load functionality to a battleship game for a course I'm doing. To give you an idea where I'm at, I just learnt how to read and write files. My question is, is there a type of variable I can cin into that accepts both characters and numbers?
I want the user to people able to save at any point during the game. As it is now the players set up their boards and then take turns entering coordinates into ints which are checked against a (2d?) array. I want to be able to choose to save at the prompt for entering these but I'm open to alternate suggestions.

Feel free to check out the sourcecode http://forums.3drealms.com/ubbthreads/images/graemlins/smile.gif

rg3
04-24-2005, 10:19 AM
Without looking at the source code, you should write a couple of functions that save and restore the game variable values from a file. At a given moment, the situation can be described with the contents of the board, who's playing and some other conditions.

You should pass all the necessary data to a function and that function writes that data to a file, in an order and way that you establish it. Probably, the easiest way to start is to use a text file (as opposed to a binary file). In that file you write the contents of the game in any order you decide, through

file << variable << endl;

And you restore the values using

file >> variable;

That way, numbers, chars, whatever are stored in their text representation and read when you load a game. You must read the values in the same order you save them.

EDIT:

If you think you need a variable that stores different types of data, you're not approaching the problem with the right angle http://forums.3drealms.com/ubbthreads/images/graemlins/smile.gif.

Among the data you may save to the file you can use, for example, an integer number that represents the game stage (setup, playing, finished...), which ships are placed in the board (if there's a predefined number and type of the ships you can use a flag to mark which ones are placed and which ones are not, in other case you can save the number of ships each player has placed and then the descriptions for each ship, etc), etc. Try to think a way to store the data so that you can read it knowing what to read next at any moment in the process.

IceColdDuke
04-24-2005, 04:26 PM
Here is a example on how you would do it with the standard IO library in C++.

// Headers are good so you know your reading the correct file.

struct saveGameHeader_t
{
long majicNumber; // whatever byte should be the first byte.
long version; // version number. Useful to see if the save game structure is out of date.
};

struct gameShips_t
{
int type; // battleship, carrier, etc
int state; // how many pegs it has.
long posX; // XY position
long posY;
};

struct saveGameContents_t
{
char playerName0[20];
char playerName1[20];
gameShips_t player1Ships[6];
gameShips_t player2Ships[6];
};

I know your not using the C file IO library. But this is how you might do it.

void LoadGame(char *saveName)
{
FILE *mySaveGame = fopen(saveName,"rb");
saveGameHeader_t *mySaveHeader = new saveGameHeader_t;
saveGameContents_t *mySaveData = new saveGameContents_t;

fread(mySaveHeader,sizeof(saveGameHeader_t),1,mySa veGame);
if(majicNumber, or ID number wrong)
throw YourErrorHere;


fread(mySaveData, sizeof(saveGameContents_t),1,mySaveGame);
fread
}

void WriteData(char *saveName, saveGameContents_t *gameData)
{
FILE *mySaveGame = fopen(saveName,"wb");
saveGameHeader_t *mySaveHeader = new saveGameHeader_t;

set magicnumber and ID here

fwrite(mySaveHeader,sizeof(saveGameHeader_t),1,myS aveGame);
fwrite(gameData,sizeof(saveGameContents_t ),1,mySaveGame);
}

Destroyer
04-24-2005, 11:01 PM
I dont think I understand what you guys are doing, but perhaps look into templates.

Deathdust
04-25-2005, 05:59 AM
I probably didn't word my post well enough - thanks for your help but it wasn't the help I needed. I have the saving and loading working fine but I want the player to be able to interrupt the game at their screen for entering coordinates (currently cins into ints which are checked against the board arrays) and save the current game. Is there a way I can do this?

Vexed
04-25-2005, 12:49 PM
perhaps always make the cin write to a string, then check to see if it's a number or text. If it's a number you convert it to an int.

Deathdust
04-26-2005, 05:02 AM
Awesome, thanks. I hadn't considered that.

rg3
04-26-2005, 01:02 PM
I don't know much about the C++ standard library, but I'd swear that if you do:

cin >> integer_variable;

And it can't read an integer, some flags are raised in the cin object that let you know an error happened.

Edit: try this code to see how the flags are set depending on if you provide EOF, an integer, something different from an integer, a too big integer, an integer followed by dirt data, etc:


#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int main()
{
int foo;
cin >> foo;
cout << cin.eof() << endl
<< cin.fail() << endl
<< cin.bad() << endl
<< foo << endl;
return 0;
}

Vexed
04-26-2005, 05:40 PM
Deathdust said:
Awesome, thanks. I hadn't considered that.


you need to deduct 48 from a char to get the int number, if you didnt know and if I'm not mistaken.

Deathdust
04-27-2005, 05:40 AM
I didn't get to see your posts before I got it working based on vexed's string to int idea. It took a bit of googling but I've got it running well like this:

cout << "Remaining Enemy Ships: " << p2alivecount << "/6 No. of your ships remaining: " << p1alivecount << "/6\n\n";
cout << "Player 1, enter your target. Enter 's' to save.\n";
cout << "Row value: ";
cin >> checkx;
if (checkx == "s")
{
save();
}
else
{
x = atoi(checkx.c_str());
}
Thanks everyone for your help http://forums.3drealms.com/ubbthreads/images/graemlins/smile.gif

Deathdust
04-30-2005, 03:47 AM
Would anyone mind pointing out my mistake(s)?

What's required:
For the final exercise you are required to write a program for a farmer who has built himself a tanker trailer for his tractor so that he can spray paddocks with a fertiliser mixture. The ratio is 3 litres of water to every litre of fertiliser concentrate. The fertiliser is sprayed on paddocks at a rate of 2000 litres per hectare.

The tank is a cylinder and lays on its side like a milk tanker. It is 2.5 metres in diameter and 4 metres long. The farmer has built a dip stick and measures the level of liquid in the tank in millimeters. The problem that he has is working out how many litres of liquid is in the tank and how litres of fertilizer to add to give enough to cover a paddock.

The farmer therefore wishes to enter the size of his paddocks and the current level of fertiliser in the tank into the program. And the program then calculates for the farmer how many litres water and concentrate to be put in the tank to give the correct amount of fertiliser to cover the paddock.

My current code:
#include <iostream>
#include <cmath>
using namespace std;

class Tanker
{
public:
Tanker();
void needed(float hec1);
void currentamount(int dipstick1);
int howmuchmore();
double water;
double fertiliser;
float currentlitres;

private:
float d;
int radius;
float arc;
double angle;
float sectorarea;
float trianglearea;
int length;
double tan;
float liquid;
};

int main()
{
Tanker();
Tanker thisTanker;
float hec;
int dipstick;
system("CLS");
cout << "\n\tthe Fertiliser program\n\n";
cout << "Size of the paddock: ";
cin >> hec;
thisTanker.needed(hec);
cout << "\nDipstick mm: ";
cin >> dipstick;
thisTanker.currentamount(dipstick);
thisTanker.howmuchmore();
cout << "\nTanker currently holding " << thisTanker.currentlitres;
cout << "\nTanker needs " << thisTanker.water << "L water and " << thisTanker.fertiliser << "L more fertiliser.";
return 0;
}

Tanker::Tanker()
{
length = 4000;
radius = 12500;
}

void Tanker::needed(float hec1)
{
tan = hec1 * 2000;
}

void Tanker::currentamount(int dipstick1)
{
if (dipstick1 < 12500)
{
d = 12500 - dipstick1;
angle = 2 * (acos (d / radius));
arc = radius * angle;
sectorarea = (radius / 2) * arc;
trianglearea = (radius * radius / 2) * sin (angle);
currentlitres = (sectorarea - trianglearea) * length / 1000;
}
}

int Tanker::howmuchmore()
{
liquid = tan - currentlitres;
water = (liquid / 4) * 3;
fertiliser = liquid / 4;
}


I realise I haven't added the code for the case where the tank is more than half full but the first half isn't working yet..

DudeMiester
04-30-2005, 11:43 AM
First of all, calling Tanker(); is pointless. Second if you are using temporaries decalare them in the function, NOT the class. Third, comment your code. Forth, use captital to denote the seperate words in your various names. Five, HowMuchMore() shouldn't return a value, or better yet you could return a class that contains the three result variables.

Deathdust
05-01-2005, 06:41 AM
Thanks for your input, although I should have made my question clearer. I need someone to check the accuracy of the math for what I'm trying to do.. its been 4-5 years since I've done anything like this.

EDIT:
This is an example of the current output.. It definitely doesn't sound right.

http://img.photobucket.com/albums/v126/Deathdust/currentoutput.jpg

This was my reference for the math: http://mathworld.wolfram.com/CircularSegment.html

DudeMiester
05-01-2005, 11:42 AM
deleted