0

I'm having some trouble trying to move a ball around obstacles towards a goal on a 2x2 array. I have a function that takes two integers as parameters. The function then creates a 2x2 array of size 10, fills it with free space, creates a set obstacle (obstacle stays the same everytime). Then it creates the goal point (assigns it to the same spot everytime) and the ball point (which is in the array location [x][y]).

The goal is to have the ball move towards the goal until it hits an obstacle, then circumvent the obstacle while keeping track of how far away it is from the goal for each space around the obstacle, then return to the closest point and continue towards the goal.

I'm trying to develop a moveToGoal function that moves the ball towards the goal given that there is no obstacle in the way, but I'm having a lot of trouble accessing the grid outside of the printGrid function. If I create the grid outside of the print grid function, I can't access it because it is out of scope. I know it might seem confusing, but I'll try and answer any questions about it. Here's what I have so far:

#include <stdio.h>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>

using namespace std;

void printGrid(int x, int y)        //Used to clear old grids, and print a
{                                   //new grid with input location for ball
    system("CLS");
    string grid [10][10];           //Initialize grid array
    for (int i=0; i<10; i++)
    {
        for (int j=0; j<10; j++)
        {
            grid[i][j] = ' ';       //Constructs grid with freespace
        }
    }
    for (int i=2; i<8; i++)         //Constructs obstacle(s)
    {
        grid[5][i]='O';
    }
    grid[2][5] = 'G';               //Sets Goal location
    grid[x][y] = 'B';               //Sets current ball location(starts 8,5)
    for (int i=0; i<10; i++)        //Prints finished grid
    {
        for (int j=0; j<10; j++)
        {
            cout<<grid[i][j];
        }
        cout<<endl;
    }   
}

void moveToGoal(int x, int y)
{
    printGrid(x-1, y);
}

int main()
{
    moveToGoal(8,5);
    sleep(1);
    moveToGoal(7,5);
    sleep(1);
    moveToGoal(6,5);
    sleep(1);
    moveToGoal(5,5);
    sleep(1);
    moveToGoal(4,5);
    sleep(1);
    moveToGoal(3,5); 
}

Any help would be appreciated!

N. Sunilkumar
  • 65
  • 1
  • 7
  • Why do you need the `sleep` calls? – Thomas Matthews Sep 14 '16 at 05:03
  • A "2x2" array is an array of length 2 and width 2. Do you mean "2 dimensional array"? – kfsone Sep 14 '16 at 05:58
  • Your grid is local to the printGrid function. If you need to adjust it outside this function you either need to pass it back and forth as a function parameter or work with it as a global variable. – Adrian Colomitchi Sep 14 '16 at 05:58
  • `string` is a non-trivial object, your grid is of single characters, not strings. Use `char` instead of `string`. – kfsone Sep 14 '16 at 05:59
  • take a look at [A star](http://stackoverflow.com/a/28317199/2521214) algorithm for pathfinding (the raster/map/grid version not the graph one). You can compute the path once (or once i a while if conditions changes in the map with time) and then just iterate through it ... – Spektre Sep 14 '16 at 07:22

2 Answers2

0

Try this:

string grid [10][10];           // the grid array is now global

void printGrid(int x, int y)        //Used to clear old grids, and print a
{                                   //new grid with input location for ball
    system("CLS");
    for (int i=0; i<10; i++)  // clean the old grid
    {
        for (int j=0; j<10; j++)
        {
            grid[i][j] = ' ';       //Constructs grid with freespace
        }
    }
    for (int i=2; i<8; i++)         //Constructs obstacle(s)
    {
        grid[5][i]='O';
    }
    grid[2][5] = 'G';               //Sets Goal location
    grid[x][y] = 'B';               //Sets current ball location(starts 8,5)
    for (int i=0; i<10; i++)        //Prints finished grid
    {
        for (int j=0; j<10; j++)
        {
            cout<<grid[i][j];
        }
        cout<<endl;
    }   
}
Adrian Colomitchi
  • 3,974
  • 1
  • 14
  • 23
0

In the following code

int f() {
    int i = 1;
    i++;
    std::cout << i << "\n";
}

int main() {
    f();
    f();
}

The variable i in function f is a local variable. This means that there is a new instance of it created for every call to f(). So the output of the above code is 2, twice, not 2 and then 3.

In your code, the grid is local to printGrid so every time you call printGrid the grid is created over.

The solution is to make the grid either a parameter you pass to it or a global variable. Passing the grid as a parameter is preferred, and you might consider placing it inside a struct or a class to make it easier to do.

#include <array>
#include <utility>
#include <iostream>

class Grid
{
    // type alias for a grid of 10x10 chars
    using grid_t = std::array<std::array<char, 10>, 10>;

    grid_t grid_;  // our actual grid data: note grid_[y][x].
    int ballX_ = -1, ballY_ = -1;

public:
    // Constructor
    Grid(int goalX, int goalY)
    {
        // populate the grid with free space
        for (auto&& row: grid_) {
            std::fill(row.begin(), row.end(), ' ');
        }
        // add obstacles
        for (size_t i = 2; i < 8; ++i)
            grid_[i][5] = 'O';
        // place the goal
        grid_[goalY][goalX] = 'G';
    }

    // place, move or remove the ball on the grid
    void placeBall(int x, int y)
    {
        // Remove the ball from any previous location
        if (ballX_ != -1 && ballY != -1)
            grid_[ballY_][ballX_] = ' ';

        // update location
        ballX_ = x, ballY = y;

        // Place ball on board if location is not -1,-1
        if (ballX_ != -1 && ballY != -1)
            grid_[ballY_][ballX_] = 'B';
    }

    // Return the character at a given location
    char at(int x, int y) const
    {
        return grid_[y][x];
    }

    // Query ball position
    int ballX() const { return ballX_; }
    int ballY() const { return ballY_; }

    // print the grid
    friend ostream& operator << (ostream&, const Grid&);
};

ostream& operator<<(ostream& stream, const Grid& grid)
{
    for (auto&& row: grid.grid_) {
        for (auto&& col: row) {
            stream << col << ' ';
        }
        stream << '\n';
    }
    return stream;
}

// helper for your cls/sleep thing around printing the grid.
void printGrid(const Grid& grid)
{
    system("CLS");
    std::cout << grid;
    sleep(1);
}

void manipulateGrid(Grid& grid)  // reference to the caller's grid
{
    printGrid(grid);
    grid.placeBall(8, 5);
    printGrid(grid);
    grid.placeBall(7, 5);
    // ...
}

int main()
{
    Grid g(2, 5);  // create grid with [2,5] as the goal
    manipulateGrid(g);  // to demonstrate passing as parameter
}
kfsone
  • 23,617
  • 2
  • 42
  • 74