This is my first question here.

My latest assignment is to create a random walk program using a 2-d array. The program worked fine until I tried to put this code into a function:

for(int i = 0; i < 100; i++){
        //reset field of flowers for each attempt
        populateAry(ary);  

        int row = 6, col = 1;  //reset position
        int position = ary[row][col]; //start Harvey out with his first step, forward (to my right), for each attempt
      
       //this loop represents each attempt to walk across the island.
        while(position != 3 && position != -1){
            position = walk(ary, row, col, position);       
        
            //check position & update status
            update(ary, row, col, position, flower, water, safe);
        }
    }//end for loop

It works fine when I leave that code in main(). The other functions work! But when I try to do the same with this code using a function (just like the others?), I get these errors:

invalid conversion from `int (*)[14]' to `int'
initializing argument 1 of `int walk(int, int&, int&, int)'

invalid conversion from `int (*)[14]' to `int'
initializing argument 1 of `void update(int, int&, int&, int, int&, int&, int&)'


This is the function (prototype & definition):

void runSim(int, int, int, int);

void runSim(int ary[ROWS][COLS], int flower, int water, int safe){
    
    for(int i = 0; i < 100; i++){
        //reset field of flowers for each attempt

        populateAry(ary);  //I find it ODD that the compiler does not complain about this one!?!

        int row = 6, col = 1;  //reset position
        int position = ary[row][col]; //start Harvey out with his first step, forward (to my right), for each attempt
      
       //this loop represents each attempt to walk across the island.
        while(position != 3 && position != -1){
            position = walk(ary, row, col, position);       
        
            //check position & update status
            update(ary, row, col, position, flower, water, safe);
        }
    }//end for loop
}

Here is how it is called from within int main();

runSim(ary, flower, water, safe);

And THIS (ugh!) is my entire program:

//CS 318
#include<iostream>
#include<fstream>
#include<iomanip>//for setprecision

using namespace std;

//global constant variables
const int ROWS = 13;
const int COLS = 14;

//prototypes
void populateAry(int);
void printAry(int, ofstream&);
void runSim(int, int, int, int);
int walk(int, int&, int&, int);
void update(int, int&, int&, int, int&, int&, int&);
double calcCost(int);
void printResults(int, int, int, double, ofstream&);


//functions
void populateAry(int ary[ROWS][COLS]){
    for(int r = 0; r<ROWS; r++){
        for(int c = 0; c<COLS; c++){
            //add -1's to array (water)
            if((r==0 || r==12) || ((c==0 || c==13) && r !=6)){
                ary[r][c]= -1;
            }
            //add 0's (safe path)
            else if (r==6 && c!=0 && c!=13){
                ary[r][c]= 0;
            }
            //add 3's (bridge)
            else if (r==6 && (c==0 || c==13)){
                 ary[r][c] = 3;
            }
            //add 2's (flowers)
            else{
                 ary[r][c]=2;
            }
        }
    }
}
    
void printAry(int ary[ROWS][COLS], ofstream& outFile){
     
    cout<<endl<<setw(40)<<"Flowers Unlimited Park\n\n";
    outFile<<endl<<setw(40)<<"Flowers Unlimited Park\n\n";
    
    for(int r = 0; r<ROWS; r++){
        for(int c = 0; c<COLS; c++){    
            cout<<"  "<<ary[r][c];
            outFile<<"  "<<ary[r][c];
            
            if(ary[r][c] >=0){
                cout<<" "; //extra space because of -
                outFile<<" ";
            }
            if(c==13){
                cout<<endl;//new line for each row
                outFile<<endl;
            }
        }
    }
}

void runSim(int ary[ROWS][COLS], int flower, int water, int safe){
    
    for(int i = 0; i < 100; i++){
        //reset field of flowers for each attempt
        populateAry(ary); 

        int row = 6, col = 1;  //reset position
        int position = ary[row][col]; //start Harvey out with his first step, forward (to my right), for each attempt
      
       //this loop represents each attempt to walk across the island.
        while(position != 3 && position != -1){
            position = walk(ary, row, col, position);       
        
            //check position & update status
            update(ary, row, col, position, flower, water, safe);
        }
    }//end for loop
}

int walk(int ary[ROWS][COLS], int& row, int& col, int pos){
    //move it, Harvey!!
    int step = rand() % 100 +1;
        
    //decide which way he stepped
    if(step <=45){ //forward 45%...which means to MY right.
        pos = ary[row][++col];//move him one column to my right
    }
    else if (step<=70){ //left 25%...UPward
        pos = ary[--row][col]; //move him one row up
    }
    else if (step<=90){ //right 20%...DOWNward
        pos = ary[++row][col];
    }
    else if (step<=100){ //backward 10% ...to MY left
        pos = ary[row][--col]; //move him one column left
    }
        
    return pos;
}
 
void update(int ary[ROWS][COLS], int& row, int& col, int pos, int& flower, int& water, int& safe){
    //did he step on a flower?
    if(pos ==2 || pos ==1){
        //subtract one from that element in the array
        ary[row][col]-=1; 
        //add to flower counter 
        flower++;  
    }
 
    if(pos == -1){ //he's in the water
        water++;
    }
    if(pos == 3){ //he's safe
        safe++;
    }

} 

double calcCost(int flower){
    return double((flower*5.0)/100);
}

void printResults(int water, int safe, int flower, double avg, ofstream& outFile){
     
    cout<<"\n Total number of times Harvey had to be rescued from the water: "<<water
    <<".\n\n Total number of times Harvey made it to a bridge: "<<safe
    <<".\n\n Total number of flowers Harvey destroyed: "<<flower
    <<fixed<<showpoint<<setprecision(2)<<".\n\n Average cost of Harvey's walk: $"<<avg<<endl<<endl;
    
    outFile<<"\n Total number of times Harvey had to be rescued from the water: "<<water
    <<".\n\n Total number of times Harvey made it to a bridge: "<<safe
    <<".\n\n Total number of flowers Harvey destroyed: "<<flower
    <<fixed<<showpoint<<setprecision(2)<<".\n\n Average cost of Harvey's walk: $"<<avg<<endl<<endl;
} 


int main(){

    system("color e1"); //black & white all the time is kinda boring...
    ofstream outFile;
    outFile.open("Harvey.txt");
    
    //counters 
    int water = 0, safe = 0, flower = 0;
    
    int ary[ROWS][COLS];
    
    populateAry(ary);
    printAry(ary, outFile); //just to make sure the array has been populated correctly
    
    //attempt to walk across the island--100 times
    runSim(ary, flower, water, safe);

    double avg = calcCost(flower);

    printResults(water, safe, flower, avg, outFile);
    
    outFile.close();

    cin.get(); 
    return 0;
}
    
//Random Walk

//The local town drunk, Harvey, has gotten himself into a mess.  Besides 
//being in his normal state, a state that earned him his title, he has made 
//his way into the Flowers Unlimited Park, a park where many flowers are 
//grown and display in their natural beauty.  The local ordinance fines 
//individuals $5.00 for each flower they pick or destroy.  This is enforce 
//to insure the beauty and the integrity of the park.  Now old Harv is not 
//only in the wrong state, drunk, and in the wrong place, the park, he is 
//also on a small island within the park, eleven feet wide by 12 feet long.  
//The island is connected to the main land by two bridges one at each end 
//of the island.  Now Harv needs to get off the island and in the process, 
//it will cost him (ie stepping on flowers to get off the island).
//There is a clear path down the middle of the island that leads from one 
//bridge to another.  The remainder of the island has flowers.  On the island, 
//there are two flowers growing per square foot.  What we need to find out 
//is how much is it going to cost Old Harv to walk from where he is (the end 
//of the bridge on the island (ie first step forward put  Harv on the island) 
//to either bridge and get off the island?
//After studying Harv for many years, it is known that he doesn't walk a 
//straight line when he is in his preferred state.  His walking patterns are 
//as follows.  He steps forward 45% of the time, he steps left 25% of the 
//time, right 20% and back wards 10% of the time.  If Harvey steps onto 
//either bridge, we will consider that he has made it across the island.  
//If he steps into the water, he has finished walking and must be rescued.  
//If he steps off the path onto a square containing two flowers, he destroys 
//one.  If he steps into the same square later, he destroys the second flower.
//Write a program that will compute the cost of Harvey's walk in the park.
//
//Inputs:	None
//Outputs:	The cost (average) of Harvey's walk.
//	The number of times Harvey made it to a bridge.
//	The number of times Harvey had to be rescued from the water.
//Restrictions:	Use a 2-d array.  Run the simulation 100 times to generate the results.
//Output:	Format output in a readable style.  (Columns maybe)

Edited 6 Years Ago by MyrtleTurtle: n/a

Your prototype doesn't match your definition

Change this:

void runSim(int, int, int, int);

To this:

void runSim(int ary[][COLS], int, int, int);

And see what happens. This appears to be true for all instances...

Edited 6 Years Ago by Fbody: n/a

Comments
Thank you very much! Sometimes it takes me a while to understand.

Thanks for the reply. That didn't work though. In my experience, the prototype doesn't actually need to include the variable names, just the data types.

The program does work with all the other functions, just not with that one function...

That's correct, the name is irrelevant, it's just a placeholder, you could call it "junkHeap" in the prototype if you wanted. The name that is actually used is determined by the header line of the definition. I used "ary" because that seems to be the name you've established. The important part is that you are telling the compiler to expect an array by including the "[][COLS]" part.

As you have written your calls, you are trying to pass an integer pointer directly to an integer. These are not compatible types.

The previous version should work. But the way you wrote your function's header line is probably causing an issue. The version I gave you and the existing header line don't technically match because I used a 'void' first dimension and you specified the size. Try

void runSim(int [ROWS][COLS], int, int, int);

instead.

Edited 6 Years Ago by Fbody: n/a

I appreciate your trying to help, but like I said, this works:

int main(){

    system("color e1"); //black & white all the time is kinda boring...
    ofstream outFile;
    outFile.open("Harvey.txt");
    
    //counters 
    int water = 0, safe = 0, flower = 0;
    
    int ary[ROWS][COLS];
    
    populateAry(ary);
    printAry(ary, outFile); //just to make sure the array has been populated correctly
    
    //attempt to walk across the island--100 times
        for(int i = 0; i < 100; i++){
        //reset field of flowers for each attempt
        populateAry(ary); 

        int row = 6, col = 1;  //reset position
        int position = ary[row][col]; //start Harvey out with his first step, forward (to my right), for each attempt
      
       //this loop represents each attempt to walk across the island.
        while(position != 3 && position != -1){
            position = walk(ary, row, col, position);       
        
            //check position & update status
            update(ary, row, col, position, flower, water, safe);
        }
    }//end for loop

    double avg = calcCost(flower);

    printResults(water, safe, flower, avg, outFile);
    
    outFile.close();

    cin.get(); 
    return 0;
}

All of the above function prototypes and definitions are unchanged. The only thing that is different is the runSim function is omitted, and the code that was in it is in main instead. I just can't figure out why it works for every other function except for that one.

And what I meant was that the prototypes do not even need a variable name at all. They only require the data type, which is the way I have it. In fact, I usually omit prototypes altogether, but my instructor wants them there. Anyway, they do make things a little easier, so that you don't have to worry about the order in which you define your functions. (edit: or do you?)

I did try this anyway but it did not work (the first time).

void runSim(int [ROWS][COLS], int, int, int);

Edit: I got it to work, though I still do not understand WHY it works like this and not the other way.

I moved the runSim function down so that it is defined after both the walk and the update functions.

Edited 6 Years Ago by MyrtleTurtle: n/a

Your prototypes do not match your definitions. I suspect that, since both your prototypes and your definitions are above main() you are unintentionally overloading all of your functions without implementing the improperly declared versions of the functions. You're not getting errors because you aren't using the functions that you have improperly prototyped so the compiler and linker are not looking for the implementations. If your instructor is any good, they WILL mark you down because it is not correct.

Try this and see what happens:
Leave your prototypes above main() and move all your definitions below main(). I suspect you will have several more errors show up. When you do, I have already provided you the solution.

Edited 6 Years Ago by Fbody: n/a

I suspect you will have several more errors show up.

You were right. I did what you advised, and everything you said was correct. Thank you for the help.

It did not work for me the first time I tried your advice because I only changed the ONE prototype. But when I changed them all, it did.

This question has already been answered. Start a new discussion instead.