tortoise & hare

S

Shock

Hi everybody,

I have been getting so much good advice here that I figured I would
post another question. I am still learning c++ from a text that I
inherited from my brother. I am now working on a problem that seems
lame, but I really want it to work. It is a tortoise & hare sim. I
am pretty sure I have everything right except printing the array. I
cannot figure out how to print the array correctly. It should print
the T & H one after another depending on the calculated location. I
am having trouble understanding how to input data to the array and
then print it without printing the entire array. Here is my source so
far.

#include <iostream>
#include <ctime>

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

void moveTortoise( int *);
void moveHare( int * );
void printCurrentPositions( int *, int * );
void delay ( double );

char arrayRace[71] = {' '};

int main()
{

int hPos = 1; // hare's position
int tPos = 1; // tortoise's position

cout << "BANG !!!!!" << endl << "AND THEY\'RE OFF !!!!!" << endl;

srand(time(0));

while ( hPos < 70 && tPos < 70 ) {

moveTortoise( &tPos ); //works fine
delay (.2);
moveHare ( &hPos );
printCurrentPositions( &tPos, &hPos ); // problem here!

} // end while

if ( hPos > tPos )
cout << "\nHare wins. Yuch.";
else if ( hPos < tPos )
cout << "\nTORTOISE WINS!!! YAY!!!";
else if ( hPos == tPos )
cout << "\nIts a tie. Good job Tortoise!";

return 0;

} // end main

void moveTortoise( int *tPosptr )
{
int i = ( 1 + rand() % 10 );

if ( ( i >= 1 ) && ( i <= 5 ) )
*tPosptr += 3;
else if ( ( i >= 6 ) && ( i <= 7 ) )
*tPosptr -= 6;
else if ( ( i >= 8 ) && ( i <= 10 ) )
*tPosptr += 1;

if ( *tPosptr < 1 )
*tPosptr = 1;

} // end moveTortoise

void moveHare( int *hPosptr )
{
int j = ( 1 + rand() % 10 );

if ( ( j >= 1 ) && ( j <= 2 ) )
*hPosptr = *hPosptr;
else if ( ( j >= 3 ) && ( j <= 4 ) )
*hPosptr += 9;
else if ( j == 5 )
*hPosptr -= 12;
else if ( ( j >= 6 ) && ( j <= 8 ) )
*hPosptr += 1;
else if ( ( j >= 9 ) && ( j <= 10) )
*hPosptr -= 2;

if ( *hPosptr < 1 )
*hPosptr = 1;

} // end moveHare


void printCurrentPositions( int *tPosptr, int *hPosptr )
{
for ( int track = 1; track <= 70; track++ ) {

if ( track == *tPosptr ) {
arrayRace[track] = 'T';
}

if ( track == *hPosptr ) {
arrayRace[track] = 'H';
}

if ( track == *hPosptr == *tPosptr ) {
arrayRace[track] = 'O';
}

}

cout << arrayRace;

} // end printCurrentPositions

void delay( double how_long )
{
clock_t target = static_cast< clock_t >( how_long * CLOCKS_PER_SEC )
+ clock();
while ( clock() <= target )
{ } // Do Nothing
}

thanks in advance,

shock
 
R

Ron Natalie

Shock said:
char arrayRace[71] = {' '};

There is no practical rason why this is global. It ought to be local
to the print function.
while ( hPos < 70 && tPos < 70 ) {

You use the constant 70 all over the place (and in the case above
70+1). Would be nice if this was all done in one place:

const int GamePositions = 70;

That way if you decide to change the value from 70 to 75 you
don't have to hunt down and change all the 70 and 71's to 75's and
76's. Also, it doesn't leave people wondering what this number means.
void printCurrentPositions( int *tPosptr, int *hPosptr )

Why do you pass in pointers here? You don't change the values, at the very
list they should be const pointers, but passing just the int's value would make more sense.
{
for ( int track = 1; track <= 70; track++ ) {

if ( track == *tPosptr ) {
arrayRace[track] = 'T';
}

if ( track == *hPosptr ) {
arrayRace[track] = 'H';
}

if ( track == *hPosptr == *tPosptr ) {
arrayRace[track] = 'O';
}

cout << arrayRace;

cout here gets a const char* which refers to the first element of arrayRace. This is expected
to be the first element of a null-terminated array. In your case you have not terminated the array.
You could bump up the size to 72, and then set arrayRace[71] to his value before you
call cout. However, there's no need to maintain an array here at all.

void printCurrentPositions(int tPos, in hPos) {
for(int pos = 1; pos <= 70; ++pos) {
if(track == tPos) cout << 'T';
else if(track = hPos) cout << 'H'; // what if tPos == hPos?
else cout << ' ';
}
cout << '\n';
}
 
A

Agent Mulder

//Hi everybody,
//
//I have been getting so much good advice here that I figured I would
//post another question. I am still learning c++ from a text that I
//inherited from my brother. I am now working on a problem that seems
//lame, but I really want it to work. It is a tortoise & hare sim. I
//am pretty sure I have everything right except printing the array. I
//cannot figure out how to print the array correctly. It should print
//the T & H one after another depending on the calculated location. I
//am having trouble understanding how to input data to the array and
//then print it without printing the entire array. Here is my source so
//far.

Hi Shock,

I messed up the code a bit, but there still is a problem. When Hare
wins, the message for Tortoise is displayed, and vice versa. You'll
hate the 'tightcode' that I use, but I am afraid the language will
overload tab and space in the near future, so I leave them out. I
wished that your brother could hack this, too.

-X

#include <iostream.h>
#include <string>
#include <stdlib.h>
#include <ctime>
struct Runner
{
enum{PARCOURS=70};
int pos;
Runner():pos(1){}
bool finished(){return pos==PARCOURS;}
virtual int jump(int)=0;
operator int(){return pos;}
void move()
{
pos+=jump(rand()%10+1);
pos=pos<1?1:pos>PARCOURS?PARCOURS:pos;
}};
struct Hare:Runner
{
int jump(int a)
{
bool b=a>=1&&a<=2;
bool c=a>=3&&a<=4;
bool d=a==5;
bool e=a>=6&&a<=8;
bool f=a>=9&&a<=10;
return b?0:c?9:d?-12:e?1:f?-2:0;
}};
struct Tortoise:Runner
{
int jump(int a)
{
bool b=a>=1&&a<=5;
bool c=a>=6&&a<=7;
bool d=a>=8&&a<=10;
return b?3:c?-6:d?1:0;
}};
bool operator==(const Runner&a,const Runner&b){return a.pos==b.pos;}
bool operator<(const Runner&a,const Runner&b){return a.pos<b.pos;}
void print(const Runner&a,Runner&b)
{
string c(71,' ');
c[70]='|';
c[a]='T';
c='H';
if(a==b)c[a]='O';
cout<<c<<endl;
}
void delay(double a)
{
clock_t b=static_cast<clock_t>(clock()+a*CLOCKS_PER_SEC);
while(b>clock()){} // Do Nothing
}
int main()
{
Hare hare;
Tortoise tortoise;
string harewins="\nHare wins. Yuch.";
string tortoisewins="\nTORTOISE WINS!!! YAY!!!";
string tie="\nIts a tie. Good job Tortoise!";
srand(time(0));
cout<<"BANG !!!!!\nAND THEY\'RE OFF !!!!!i\n";
print(hare,tortoise);
while(!hare.finished()&&!tortoise.finished())
{
tortoise.move();
delay(.02);
hare.move();
print(hare,tortoise);
}
cout<<(hare==tortoise?tie:hare<tortoise?tortoisewins:harewins); //??
return 0;
}
 
S

Shock

Agent Mulder said:
//Hi everybody,
//
//I have been getting so much good advice here that I figured I would
//post another question. I am still learning c++ from a text that I
//inherited from my brother. I am now working on a problem that seems
//lame, but I really want it to work. It is a tortoise & hare sim. I
//am pretty sure I have everything right except printing the array. I
//cannot figure out how to print the array correctly. It should print
//the T & H one after another depending on the calculated location. I
//am having trouble understanding how to input data to the array and
//then print it without printing the entire array. Here is my source so
//far.

Hi Shock,

I messed up the code a bit, but there still is a problem. When Hare
wins, the message for Tortoise is displayed, and vice versa. You'll
hate the 'tightcode' that I use, but I am afraid the language will
overload tab and space in the near future, so I leave them out. I
wished that your brother could hack this, too.

-X

#include <iostream.h>
#include <string>
#include <stdlib.h>
#include <ctime>
struct Runner
{
enum{PARCOURS=70};
int pos;
Runner():pos(1){}
bool finished(){return pos==PARCOURS;}
virtual int jump(int)=0;
operator int(){return pos;}
void move()
{
pos+=jump(rand()%10+1);
pos=pos<1?1:pos>PARCOURS?PARCOURS:pos;
}};
struct Hare:Runner
{
int jump(int a)
{
bool b=a>=1&&a<=2;
bool c=a>=3&&a<=4;
bool d=a==5;
bool e=a>=6&&a<=8;
bool f=a>=9&&a<=10;
return b?0:c?9:d?-12:e?1:f?-2:0;
}};
struct Tortoise:Runner
{
int jump(int a)
{
bool b=a>=1&&a<=5;
bool c=a>=6&&a<=7;
bool d=a>=8&&a<=10;
return b?3:c?-6:d?1:0;
}};
bool operator==(const Runner&a,const Runner&b){return a.pos==b.pos;}
bool operator<(const Runner&a,const Runner&b){return a.pos<b.pos;}
void print(const Runner&a,Runner&b)
{
string c(71,' ');
c[70]='|';
c[a]='T';
c='H';
if(a==b)c[a]='O';
cout<<c<<endl;
}
void delay(double a)
{
clock_t b=static_cast<clock_t>(clock()+a*CLOCKS_PER_SEC);
while(b>clock()){} // Do Nothing
}
int main()
{
Hare hare;
Tortoise tortoise;
string harewins="\nHare wins. Yuch.";
string tortoisewins="\nTORTOISE WINS!!! YAY!!!";
string tie="\nIts a tie. Good job Tortoise!";
srand(time(0));
cout<<"BANG !!!!!\nAND THEY\'RE OFF !!!!!i\n";
print(hare,tortoise);
while(!hare.finished()&&!tortoise.finished())
{
tortoise.move();
delay(.02);
hare.move();
print(hare,tortoise);
}
cout<<(hare==tortoise?tie:hare<tortoise?tortoisewins:harewins); //??
return 0;
}


I am a rookie, and you code is complex. Here is what I came up with
for my print positions module.

char array[GamePos];

for ( int i = 0; i < GamePos; i++ ) {
array = ' ';
array[GamePos] = '\0';

if ( hPos == tPos ) {
array[tPos] = 'O';
array[tPos] = 'U';
array[tPos] = 'C';
array[tPos] = 'H';
array[tPos] = '!';
array[tPos] = '!';
array[tPos] = '!';
}
else {
array[tPos] = 'T';
array[hPos] = 'H';
}

cout << array << endl;

It works. Thanks for the tips everybody!

shock56
 
T

Thomas Matthews

Shock said:
I am a rookie, and you code is complex. Here is what I came up with
for my print positions module.

char array[GamePos];

You may want:
char array[GamePos + 1];
to allow for the terminating null character ('\0').

for ( int i = 0; i < GamePos; i++ ) {
array = ' ';
array[GamePos] = '\0';


Note that array[GamePos] is one past the end of the array.
The assignment will cause Undefined Behavior. Search
news.comp.lang.c for "Nasal Demons".

Change your array to be larger by one.

if ( hPos == tPos ) {
array[tPos] = 'O';
array[tPos] = 'U';
array[tPos] = 'C';
array[tPos] = 'H';
array[tPos] = '!';
array[tPos] = '!';
array[tPos] = '!';

This is really interesting. The index to the array doesn't
change, so the same character in the array gets changed many
times.

Try these:
if (hPos == tPos)
{
strcpy(array + tPos, "OUCH!!!");
// OR
array[tPos++] = 'O';
array[tPos++] = 'U';
// etc.
// OR
array[++tPos] = 'O';
array[++tPos] = 'U';
// etc.
}
}
else {
array[tPos] = 'T';
array[hPos] = 'H';
}

cout << array << endl;

It works. Thanks for the tips everybody!

Not all the time. There are cases where data is written past
the end of the array. For example, when tPos == hPos == GamePos,
in the above "if" statment, the phrase "OUCH!!!" will be written
past the end of the array, promoting undefined behavior.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top