0 / 0 / 1
Регистрация: 19.12.2012
Сообщений: 108
1

Вектора, заполнение двумерного массива

05.06.2017, 12:51. Показов 1956. Ответов 13
Метки нет (Все метки)

Здравствуйте дамы и господа. Вопрос конечно простой, но в тупик меня поставил и не могу понять как быть в данной ситуации.
Но все по порядку. У меня есть класс, клетки myCell.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class myCell                                    // класс являющийся ячейкой
{
public:
    int MyX;                              // начало отрисовки. координаты по X
    int MyY;                              // начало отрисовки. координаты по Y
    int MyWidth;                       // ширина клетки
    int MyHeight;                      // высота клетки
    bool MyClick;                       // факт создания клетки
    bool MyFriend;                    // является ли клетка вражеской или нет
 
    myCell()
    {
        MyX = 0; MyY = 0; MyWidth = 0; MyHeight = 0; MyClick = false; MyFriend = false;
    }
    void show()   
    {
    cout<< "x = " <<  MyX << ", y = " <<  MyY << " это клетка " << "MyFriend ";
    }
};
Есть вектор
C++
1
vector<vector<Cell>> myVek;
. Но добавлять в него элементы таким образом
C++
1
    vek.push_back<i,j><new Cell(i, j, 20, 20, false, false)>;
у меня не получается . Что то делаю не так.
Вообще мною преследовалась идея создания некого кортежа, из двух координат, которые я в процессе работы программы указываю, а все флаги держать в myCell, т.к. они меняются. Но (хотя и повторяюсь) зашел в тупик ((. Потому прошу вашей помощи.
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.06.2017, 12:51
Ответы с готовыми решениями:

Массив: Заполнение двумерного вектора с клавиатуры
Доброго времени суток. Хотелось бы узнать, возможно ли заполнение двумерного вектора с...

Заполнение двумерного массива
Ребят, такой вопрос: надо создать двумерный массив, но размерность должен указать юзер. Пробовал...

Заполнение двумерного массива
НАШЕЛ САМ

заполнение двумерного массива
Заполнить двумерный массив таким образом: 1 1 1 1 1 1 0 0 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 1 1

13
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
05.06.2017, 13:37 2
Где ты такой синтаксис взял? push_back() добавляет в конец. И откуда там new?
Размер известен заранее?
0
295 / 124 / 106
Регистрация: 30.10.2015
Сообщений: 690
05.06.2017, 13:40 3
C++
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
#include <iostream>
#include <vector>
 
class MyCell       // класс являющийся ячейкой
{
private:
  int  myX;        // начало отрисовки. координаты по X
  int  myY;        // начало отрисовки. координаты по Y
  int  myWidth;    // ширина клетки
  int  myHeight;   // высота клетки
  bool myClick;    // факт создания клетки
  bool myFriend;   // является ли клетка вражеской или нет
 
public:
  MyCell() 
    : myX(0), myY(0), myWidth(0), myHeight(0), myClick(false), myFriend(false) { }
 
  MyCell(int x, int y, int w, int h, bool c, bool f)
    : myX(x), myY(y), myWidth(w), myHeight(h), myClick(c), myFriend(f) { }
 
  void Show()   
  {
    std::cout<< "x = " <<  myX << ", y = " <<  myY << " это клетка " << "MyFriend ";
  }
};
 
int main()
{ 
  std::vector<std::vector<MyCell>> matrix;
  std::vector<MyCell> m;
 
  m.push_back(MyCell(1, 2, 3, 4, true, true));
  matrix.push_back(m);
}
0
0 / 0 / 1
Регистрация: 19.12.2012
Сообщений: 108
05.06.2017, 13:41  [ТС] 4
нет, размер неизвестен. Безразмерное поле из клеток
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
05.06.2017, 14:26 5
Цитата Сообщение от Frodo4500 Посмотреть сообщение
Безразмерное поле из клеток
Как это? Ну какие-то границы же есть?
0
0 / 0 / 1
Регистрация: 19.12.2012
Сообщений: 108
05.06.2017, 14:44  [ТС] 6
В общем, мне было дано задание написать игру ГО. Только вот условие - поле должно быть безразмерным (в целях данного задания ) и по нему можно перемещаться и зумировать поле. То что мы рисуем (фишки) - должны рисоваться при клике.
В итоге я с помощью SDL - сделал зум поля и отрисовку клеток при клике (перемещение по полю не дописал, т.к. не слишком важная задача). Однако, то что я слепил - не корректно.
C++
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <string>
#include <iostream>
#include <array>
#include <map>
#include <vector>
#include <utility>
 
SDL_Window* window = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Surface *imageSurface = NULL;
SDL_Renderer* renderer = NULL;
 
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
 
using namespace std;
 
void chip(string wayimage, SDL_Rect MySrcR, SDL_Rect MySrcR2);
void close();
 
class Cell                                    // класс являющийся ячейкой
{
public:
    int MyX;                              // начало отрисовки. координаты по X
    int MyY;                              // начало отрисовки. координаты по Y
    int MyWidth;                       // ширина клетки
    int MyHeight;                      // высота клетки
    bool MyClick;                       // факт создания клетки
    bool MyFriend;                    // является ли клетка вражеской или нет
 
    Cell()
    {
        MyX = 0; MyY = 0; MyWidth = 0; MyHeight = 0; MyClick = false; MyFriend = false;
    }
    Cell(int x, int y, int nWidth, int nHeight, bool nClick, bool nFriend) : MyX(x), MyY(y), MyWidth(nWidth), MyHeight(nHeight), MyClick(nClick), MyFriend(nFriend)
    {
    };
    void show()                                                                                         // рисую клетку
    {
        SDL_Rect outlineRect = { MyX, MyY, 20 , 20 };                                  // по полученным координатам X и Y создается прямоугольник
        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);           // заливка прямоугольника цветом
        SDL_RenderDrawRect(renderer, &outlineRect);                                   // сама отрисовка на рендере
    }
};
 
void chip(string wayimage, SDL_Rect MySrcR, SDL_Rect MySrcR2)         //для рисования точки
{
    SDL_Surface *myimage = SDL_LoadBMP(wayimage.c_str());               // загружаем картинку по полученному пути
    if (myimage == NULL)
    {
        cout << "Error of loading of the image" << endl;                               // выдаем ошибку если картинка не загрузилась
    }
    SDL_Texture *mytexture = SDL_CreateTextureFromSurface(renderer, myimage);  // создаем текстуру
    SDL_FreeSurface(myimage);
    SDL_RenderCopy(renderer, mytexture, NULL, &MySrcR);
    SDL_RenderPresent(renderer);                                                           // рисуем нашу точку
    SDL_BlitSurface(imageSurface, &MySrcR2, windowSurface, &MySrcR);
}
 
void close()                                                                                          // очищаем память от всего с чем работали
{
    SDL_FreeSurface(imageSurface);
    imageSurface = NULL;
    window = NULL;
    windowSurface = NULL;
    renderer = NULL;
    SDL_DestroyWindow(window);
    SDL_Quit();
}
 
int main(int argc, char* args[])
{
    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow("sdl game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);           // создаем окно
    if (window == NULL)
    {
        cout << "Error of creation of a window" << endl;                     // в случае ошибки, выдаем сообщение и выходим из программы
        return 0;
    }
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);        // создаем рендер
 
    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);                                    // заливаем рендер цветом
    SDL_RenderClear(renderer);
 
    int step = 20;
 
    map<tuple<int, int, bool, bool>, Cell *> nMap;                                                      // создаем массив экземпляров класса Cell
 
    int MouseX;
    int MouseY;
 
    bool isRunning = true;
    SDL_Event e;
 
    while (isRunning)
    {
        while (SDL_PollEvent(&e) != 0)
        {
            if (e.type == SDL_QUIT)
                isRunning = false;
 
            switch (e.type)
            {
            case SDL_MOUSEMOTION:             // считываем и записываем координаты мыши
                MouseX = e.motion.x;
                MouseY = e.motion.y;
 
                if (e.button.button == 1 || e.button.button == 4)            // если  нажата левая или правая клавиша мыши, то
                {
                    int i = 20;
                    int j = 20;
                    for (i; i < (MouseX - 20);)                                              // в этом цикле, и том что ниже приводим координаты к нормальному виду, чтобы клетка рисовалась по 
                                                                                             //              x и y от начала координат с кратностью 20 (ширина и высота клетки) - в результате клетки не будут пересекаться друг с другом при отрисовке
                    {
                        i += 20;
                        //  cout << i << " " << endl;
                    }
                    for (j; j < (MouseY - 20);)
                    {
                        j += 20;
                        //  cout << j << " " << endl;
                    }
 
                    auto it = make_tuple(i, j, false, false);                      // кортеж или динамический массив - кому как удобней
                    nMap[it] = new Cell(i, j, 20, 20, false, false);            // создаю экземпляр класса по данным из кортежа
                                                                                //      cout << i << "  " << j << endl;                           // отладочная инфа, дабы быть уверенным, что овсе просчитано норм
                    cout << "" << endl;
 
                    for (auto it : nMap)
                    {
                        Cell * nCell = it.second;
                        SDL_Rect SrcR;                                  // создаю прямоугольник в котором будет рисоваться текстура
                        SrcR.x = nCell->MyX;
                        SrcR.y = nCell->MyY;
                        SrcR.w = 20;
                        SrcR.h = 20;
 
                        SDL_Rect SrcR2;                              // указания, тому прямоугольнику, что выше, откуда он будет рисоваться
                        SrcR2.x = MouseX;
                        SrcR2.y = MouseY;
 
                        if (nCell->MyClick == false)           // проверка, если клетка уже существует, то в этом месте мы рисовать не можем
                        {
                                windowSurface = SDL_GetWindowSurface(window);
                                if (e.button.button == 1)             // если нажата ЛКМ, то рисуем синию фишку
                                {
                                    nCell->MyClick = true;
                                    chip("data/image/btn_blue.bmp", SrcR, SrcR2);
                                }
                                else
                                {                                                  // иначе рисуем красную
                                    nCell->MyClick = true;
                                    nCell->MyFriend = true;
                                    chip("data/image/btn_red.bmp", SrcR, SrcR2);
                                }
 
                                if (nCell->MyClick == true)
                                {
                                    int MyX1 = SrcR.x;
                                    int MyY1 = SrcR.y;
 
                                    for (int k = (MyX1 - 20); k <= (MyX1 + 20); k += 20)
                                    {
                                        for (int j = (MyY1 - 20); j <= (MyY1 + 20); j += 20)
                                        {
                                            // здесь я могу получать координаты вокруг только что поставленной мной точки, для
                                            //       дальнейшей проверки , но не могу понять как получить экземпляр класса, зная лишь x и y, для того чтобы проверить, вражеская это клетка или нет.
                                            cout << k << "  " << j << endl;
 
                                        }
                                    }
                                }
 
                            nCell->show();
                        }
                    }
                }
            }
        }
        SDL_RenderPresent(renderer);
    }
    close();
 
    return 0;
}
В результате мне дали подсказку, что можно реализовывать в виде некого списка "создание некого кортежа, из двух координат (x и y), которые я в процессе работы программы указываю, а все флаги держать в myCell, т.к. они меняются."
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
06.06.2017, 18:15 7
Лучший ответ Сообщение было отмечено Frodo4500 как решение

Решение

Может, тебе ассоциативный массив нужен?
C++
1
2
3
std::map<std::pair<int, int>, Cell> myVek;
 
myVek[std::make_pair(i, j)] = Cell(20, 20, false, false);
Добавлено через 22 часа 47 минут
Так и обращаться.
C++
1
myVek[std::make_pair(i, j)].MyWidth
Только проверять надо.
1
0 / 0 / 1
Регистрация: 19.12.2012
Сообщений: 108
06.06.2017, 22:55  [ТС] 8
Попробовал
Выдает - выражение должно иметь тип класса
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
06.06.2017, 23:15 9
Программу показывай.
0
0 / 0 / 1
Регистрация: 19.12.2012
Сообщений: 108
07.06.2017, 08:12  [ТС] 10
C++
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <string>
#include <iostream>
#include <array>
#include <map>
#include <utility>
 
SDL_Window* window = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Surface *imageSurface = NULL;
SDL_Renderer* renderer = NULL;
 
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
 
using namespace std;
 
void chip(string wayimage, SDL_Rect MySrcR, SDL_Rect MySrcR2);
void close();
 
class Cell                                    // класс являющийся ячейкой
{
public:
    int MyX;                              // начало отрисовки. координаты по X
    int MyY;                              // начало отрисовки. координаты по Y
    int MyWidth;                       // ширина клетки
    int MyHeight;                      // высота клетки
    bool MyClick;                       // факт создания клетки
    bool MyFriend;                    // является ли клетка вражеской или нет
 
    Cell()
    {
        MyX = 0; MyY = 0; MyWidth = 0; MyHeight = 0; MyClick = false; MyFriend = false;
    }
    Cell(int x, int y, int nWidth, int nHeight, bool nClick, bool nFriend) : MyX(x), MyY(y), MyWidth(nWidth), MyHeight(nHeight), MyClick(nClick), MyFriend(nFriend)
    {
    };
    void show()                                                                                         // рисую клетку
    {
        SDL_Rect outlineRect = { MyX, MyY, 20 , 20 };                                  // по полученным координатам X и Y создается прямоугольник
        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);           // заливка прямоугольника цветом
        SDL_RenderDrawRect(renderer, &outlineRect);                                   // сама отрисовка на рендере
    }
};
 
void chip(string wayimage, SDL_Rect MySrcR, SDL_Rect MySrcR2)         //для рисования точки
{
    SDL_Surface *myimage = SDL_LoadBMP(wayimage.c_str());               // загружаем картинку по полученному пути
    if (myimage == NULL)
    {
        cout << "Error of loading of the image" << endl;                               // выдаем ошибку если картинка не загрузилась
    }
    SDL_Texture *mytexture = SDL_CreateTextureFromSurface(renderer, myimage);  // создаем текстуру
    SDL_FreeSurface(myimage);
    SDL_RenderCopy(renderer, mytexture, NULL, &MySrcR);
    SDL_RenderPresent(renderer);                                                           // рисуем нашу точку
    SDL_BlitSurface(imageSurface, &MySrcR2, windowSurface, &MySrcR);
}
 
void close()                                                                                          // очищаем память от всего с чем работали
{
    SDL_FreeSurface(imageSurface);
    imageSurface = NULL;
    window = NULL;
    windowSurface = NULL;
    renderer = NULL;
    SDL_DestroyWindow(window);
    SDL_Quit();
}
 
int main(int argc, char* args[])
{
    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow("sdl game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);           // создаем окно
    if (window == NULL)
    {
        cout << "Error of creation of a window" << endl;                     // в случае ошибки, выдаем сообщение и выходим из программы
        return 0;
    }
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);        // создаем рендер
 
    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);                                    // заливаем рендер цветом
    SDL_RenderClear(renderer);
 
    map<pair<int, int>, Cell*> myVek;
 
    int step = 20;
    int MouseX;
    int MouseY;
 
    bool isRunning = true;
    SDL_Event e;
 
    while (isRunning)
    {
        while (SDL_PollEvent(&e) != 0)
        {
            if (e.type == SDL_QUIT)
                isRunning = false;
 
            switch (e.type)
            {
            case SDL_MOUSEMOTION:             // считываем и записываем координаты мыши
                MouseX = e.motion.x;
                MouseY = e.motion.y;
 
                if (e.button.button == 1 || e.button.button == 4)            // если  нажата левая или правая клавиша мыши, то
                {
                    int i = 20;
                    int j = 20;
                    for (i; i < (MouseX - 20);)                                              // в этом цикле, и том что ниже приводим координаты к нормальному виду, чтобы клетка рисовалась по 
                                                                                             //x и y от начала координат с кратностью 20 (ширина и высота клетки) - в результате клетки не будут пересекаться друг с другом при отрисовке
                    {
                        i += 20;
                        //  cout << i << " " << endl;
                    }
                    for (j; j < (MouseY - 20);)
                    {
                        j += 20;
                        //  cout << j << " " << endl;
                    }
 
                    myVek[make_pair(i, j)] = new Cell(i,j,20,20,true,true);
 
                    cout << i << "  " << j << endl;                           // отладочная инфа, дабы быть уверенным, что овсе просчитано норм
                    cout << "" << endl;
 
                    SDL_Rect SrcR;                                  // создаю прямоугольник в котором будет рисоваться текстура
                    SrcR.x = i;
                    SrcR.y = j;
                    SrcR.w = 20;
                    SrcR.h = 20;
 
                    SDL_Rect SrcR2;                              // указания, тому прямоугольнику, что выше, откуда он будет рисоваться
                    SrcR2.x = MouseX;
                    SrcR2.y = MouseY;
                    
                    if (myVek[make_pair(i, j)].MyClick == false)       // проверка, если клетка уже существует, то в этом месте мы рисовать не можем
                    {
                        windowSurface = SDL_GetWindowSurface(window);
                        if (e.button.button == 1)             // если нажата ЛКМ, то рисуем синию фишку
                        {
                            chip("data/image/btn_blue.bmp", SrcR, SrcR2);
                        }
                        else
                        {                                                  // иначе рисуем красную
                            chip("data/image/btn_red.bmp", SrcR, SrcR2);
                        }
                    }
                }
            }
        }
        SDL_RenderPresent(renderer);
    }
    close();
 
    return 0;
}
Вложения
Тип файла: 7z D.7z (7.71 Мб, 2 просмотров)
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
07.06.2017, 10:57 11
Почему у тебя упорно появляется указатель на Cell? Зачем эти сложности с выделением памяти, которую ещё и освободить нужно после?
Я же показал как должно быть.
1
0 / 0 / 1
Регистрация: 19.12.2012
Сообщений: 108
07.06.2017, 12:05  [ТС] 12
Блин, вот я болбес. Спасибо за ваши ответы - они очень ценны для меня.
Если вас не затруднит, на основании того, что вы видели из моего кода и моих вопросов дать мне совет - что почитать для сведения таких ошибок к минимуму ?
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
07.06.2017, 12:09 13
Лучший ответ Сообщение было отмечено Frodo4500 как решение

Решение

Ну про STL, наверное, надо читать. Использовать указатели тоже можно, но в данном случае незачем.
1
0 / 0 / 1
Регистрация: 19.12.2012
Сообщений: 108
07.06.2017, 12:15  [ТС] 14
Еще раз спасибо - очень помогли )
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.06.2017, 12:15
Помогаю со студенческими работами здесь

Заполнение двумерного массива
Такая задача: Вам вводится число N — размер двумерного массива. Необходимо вывести массив, где i-я...

Заполнение двумерного массива
Есть простой код, но он не работает. Выскакивает сообщение о необработанном исключении. Типо...

Заполнение двумерного массива
как написать функцию ввода двумерного массива вещественными и не обязательно положительными...

Заполнение двумерного массива
есть 4 массива одномерных, как сделать чтобы создавался массив А двумерный размером 4х4, который...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru