camera in display() function

I have a vector that is 30x17. I want to create a camera where it prints a 9x9 vector of the character '@' where '@' is at the center of the map. If '@' is near the edge of the map, it prints a 9x9 with the character NOT in the center of the map.

Here's what I have so far:

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
//displays 9x9 map based on hero's position
void Game::show() const
{
  system("clear");
//below is 2d vector map
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// X   XXX      XXXXXXXXX       X
// XX$      XXXXXXXXXXX         X
// XXX   XXXXXXXXX       XXXX   X
// XXX   XXXXXXXXX    XXXXXX    X
// XX   XXXXXXXX    XXXXXXX    XX
// X   XXXXXXXXXX  XXXXX      XXX
// X     XXXXXXXXXXXXXXXX     XXX
// X XXX    XXXXXXXXXXX     XXXXX
// X XXX    XXXXXXXXXXXXXX    XXX
// X  XXX    XXXXXXXXXXX      XXX
// XXXXXXX       XXXX       XXXXX
// XXXXX   XXXX            XXXXXX
// XXXX  XXXXX       XXXXXXXXXXXX
// XXX  XXXXXX       XXXX   X   X
// X   XXXXXX                   X
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  short r = get_hero_position_row();
  short c = get_hero_position_col();

  if (r < 5 && c < 5) //this part works
  {
    for (short i = 0; i < 9; i++)
    {
      for (short j = 0; j < 9; j++)
      {
       std::cout << map2d[i][j];
      }
      std::cout << std::endl;
    }
  } 
  else if (r < 5) //this doesn't work
  {
    short d = 0; //d means difference
    for (short i = 0; i < col; i++)
    {
      if (col - i == c)
      {
        d = i;
      }
    }

    for (short i = 0; i < 9; i++)
    {
      for (short j = 0; j < d; j++)
      {
       std::cout << map2d[i][j];
      }
      std::cout << std::endl;
    }
  }
  else if (c < 5)//this doesn't work
  {
    for (short i = 0; i < r + 5; i++)
    {
      for (short j = 0; j < c + 5; j++)
      {
       std::cout << map2d[i][j];
      }
      std::cout << std::endl;
    }
  }
  else
  {
    for (short i = r - 4; i < r + 4; i++)//this works
    {
      for (short j = c - 5; j < c + 5; j++)
      {
        std::cout << map2d[i][j];
      }
    std::cout << std::endl;
    }
  }

  std::cout << "Bounty Count: "; bountys_left(); 
  std::cout << "    Moves made: " << moves_made << "\n"; 

}


full code is too long to post here, but can be found here: (you can run it to see how the map changes size and is no longer 9x9 when the character reaches 3,6)
https://repl.it/@clonxy/CS135-HP9
Last edited on
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
#include <iostream>
#include <cstdlib>

int main(int argc, char **argv)
{
  if (argc != 3) {
    std::cerr << "Usage: mappywap ROW COL\n";
    return 0;
  }

  const int NROWS = 17, NCOLS = 30, WINDOW_SIZE = 9;

  char map[NROWS][NCOLS+1] = {
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "X   XXX      XXXXXXXXX       X",
    "XX$      XXXXXXXXXXX         X",
    "XXX   XXXXXXXXX       XXXX   X",
    "XXX   XXXXXXXXX    XXXXXX    X",
    "XX   XXXXXXXX    XXXXXXX    XX",
    "X   XXXXXXXXXX  XXXXX      XXX",
    "X     XXXXXXXXXXXXXXXX     XXX",
    "X XXX    XXXXXXXXXXX     XXXXX",
    "X XXX    XXXXXXXXXXXXXX    XXX",
    "X  XXX    XXXXXXXXXXX      XXX",
    "XXXXXXX       XXXX       XXXXX",
    "XXXXX   XXXX            XXXXXX",
    "XXXX  XXXXX       XXXXXXXXXXXX",
    "XXX  XXXXXX       XXXX   X   X",
    "X   XXXXXX                   X",
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  };

  int r = std::atoi(argv[1]);
  int c = std::atoi(argv[2]);

  int top = r - WINDOW_SIZE / 2;
  int left = c - WINDOW_SIZE / 2;

  if (top < 0)
    top = 0;
  else if (top + WINDOW_SIZE > NROWS)
    top = NROWS - WINDOW_SIZE;

  if (left < 0)
    left = 0;
  else if (left + WINDOW_SIZE > NCOLS)
    left = NCOLS - WINDOW_SIZE;

  for (int row = top; row < top + WINDOW_SIZE; row++) {
    for (int col = left; col < left + WINDOW_SIZE; col++)
      std::cout << map[row][col];
    std::cout << '\n';
  }  
}

BTW, there's no advantage to using short instead of int. It's not generally considered a good idea to use short just because your values are small. The usual use of short is to save space in an array or something like that.
Last edited on
I'm not advanced enough to understand your code yet, is it possible to do it using for-loops? I think I just got the math wrong for the for-loop-ranges.
Last edited on
It's not advanced at all, and it does use for loops. It's on the same level as your code. Look through it carefully and I'm sure you will have no problem understanding it.

The only thing that might look "advanced" to you is that I used argv to input values for r and c from the command line for testing. Just get rid of that part for your own code.

I also just used a 2D char array where you may have used vectors. You didn't give that part of your code so I just whipped up something that worked for testing.
I tried reading it, but it was just too difficult. I added a link to my code/compiler: https://repl.it/@clonxy/CS135-HP9

It's too long to be posted here since there's a character limit of 9000
Last edited on
Is anyone else able to help?
Are you joking? You're not even saying what part you don't understand.

Anyway, try replacing your function with this:

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
void Game::show() const
{
  system("clear");

  const int NROWS = 17, NCOLS = 30, WINDOW_SIZE = 9;

  int r = get_hero_position_row();
  int c = get_hero_position_col();

  int top = r - WINDOW_SIZE / 2;
  int left = c - WINDOW_SIZE / 2;

  if (top < 0)
    top = 0;
  else if (top + WINDOW_SIZE > NROWS)
    top = NROWS - WINDOW_SIZE;

  if (left < 0)
    left = 0;
  else if (left + WINDOW_SIZE > NCOLS)
    left = NCOLS - WINDOW_SIZE;

  for (int row = top; row < top + WINDOW_SIZE; row++) {
    for (int col = left; col < left + WINDOW_SIZE; col++)
      std::cout << map2d[row][col];
    std::cout << '\n';
  }  

  std::cout << "Bounty Count: "; bountys_left(); 
  std::cout << "    Moves made: " << moves_made << "\n"; 
}

You probably have the NROWS and NCOLS sizes stored somewhere else. For instance, if you are using a vector<vector<char>> for the 2d array then you could do something like:

1
2
int NROWS = map2d.size();
int NCOLS = map2d[0].size();

It took awhile for me to read it. I've added the translation below if anyone else needs it... this is pure genius, how were you able to find the algorithm for this?

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
void Game::show() const
{
  system("clear");

  const int window_size = 9; //for 9x9

  int r = get_hero_position_row();
  int c = get_hero_position_col();

  int top = r - window_size / 2; //means position (row) of character minus 5 
  int left = c - window_size / 2; //means position (col) of character minus 5

  if (top < 0) //means if position of character is less than 5, map will start at 0
  {
    top = 0;
  }
  else if (top + window_size > row) //otherwise, if position of character is greater than the 2d vector of row, it is now row - 5. which means the other end of the map.
  {
    top = row - window_size;
  }

  if (left < 0) //if position of char - 5 is less than 0
  {
    left = 0;
  }
  else if (left + window_size > col) //if position (col) of char > the col size of vector
  {
    left = col - window_size; //left now prints the other side of the map
  }

  //prints out vector
  for (int row = top; row < top + window_size; row++) 
  {
    for (int col = left; col < left + window_size; col++)
    {
      std::cout << map2d[row][col];
    }
    std::cout << '\n';
  }  

  std::cout << "Bounty Count: "; bountys_left(); 
  std::cout << "    Moves made: " << moves_made << "\n"; 
}
Last edited on
Yes, that's pretty much it. But WINDOW_SIZE/2 is 9/2 which is 4, not 5 (integer division "truncates" any fractional part instead of "rounding up").

The code just determines a top and left position that fits and then prints out a 9x9 grid from there.
Topic archived. No new replies allowed.