Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
1

Несколько вопросов

25.04.2011, 11:58. Показов 1272. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Делаю небольшую консольную игру для тренировки и есть несколько вопросов.
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
char *lev[50];
//char lev[50][320];   //как передать правильно этот массив в конструктор ниже?
 
class Level
{
    char** pl;
    COORD yx;
    int draw_x;
    int draw_y;
    int dx;
    int dy; 
    int x;
    int y;
public:
    Level(char *lev[50])   //Level(char lev[50][320]) так не работает
    {
        pl=lev;
        for(x=0;x<320;x++)
        {
            for(y=0;y<25;y++)
                pl[y][x]=' ';
        }
        for(y=5;y<15;y++) lev[y][10]=char(177);
        for(y=5;y<15;y++) lev[y][220]=char(177);
        for(x=11;x<220;x++) lev[14][x]=char(177);
 
        for(y=30;y<40;y++) lev[y][8]=char(177);
        for(y=30;y<40;y++) lev[y][210]=char(177);
        for(x=9;x<210;x++) lev[39][x]=char(177);
        draw_x=0, draw_y=0;
        dx=0,dy=0; 
        yx.X=0; yx.Y=0;
    }
    void Draw()  // вывод на экран
    {
        x=draw_x, y=draw_y;
/**/
        yx.X=10; yx.Y=0; x=draw_x, y=draw_y;
        SetConsoleCursorPosition(hConsole, yx);
        cout<<"draw_x="<<draw_x<<' '<<"draw_y="<<draw_y<< \
            ' '<<cout<<pl[my][mx];
        while(true) //vivod level
        {
            yx.X=dx; yx.Y=dy;
            if(dx==80) {dy++; dx=0; y++; x=draw_x;}
            if(dy==24 && dx==79) break;
            SetConsoleCursorPosition(hConsole, yx);
            cout<<pl[y][x]; x++; dx++;
        }
        dy=0; y=draw_y;
    }
};
просто редко сейчас пишу на С++, и некоторое подзабылось .
Поправьте пожалуйста, может какие-то строчки надо переделать?
Тоесть в том массиве будет уровень (лабиринт)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.04.2011, 11:58
Ответы с готовыми решениями:

Несколько вопросов
Здравствуйте. Возникло несколько вопросов: 1. Когда нажимаешь на определённую клавишу происходит...

Несколько вопросов
Добрый день. Начал писать одну программу в VS 2008 C++ (консоль) и столкнулся в несколькими...

Несколько вопросов по указателям.
Добрый день. Не получается до конца разобраться с указателями, потому есть несколько вопросов. Кому...

Несколько вопросов к программистам.
Доброго времени суток! я начинающий, последние пару месяцев делал упор на изучение Си, WinAPI и...

19
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
25.04.2011, 12:09 2
Выделяешь память, лучше динамически, под lev.
C++
1
char **lev;
C++
1
2
lev= new char*[50];
for(int i=0;i<50;i++) lev[i]=new char[320];
В новый класс передаешь lev и внутри класса обращаешься к нему lev[i][j]
1
2022 / 1621 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
25.04.2011, 12:21 3
Цитата Сообщение от dimon1984 Посмотреть сообщение
Level(char *lev[50]) //Level(char lev[50][320]) так не работает
C++
1
Level(char (*lev)[320])
1
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
25.04.2011, 12:27  [ТС] 4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char lv[50][320];   //как передать правильно этот массив в конструктор ниже?
 
class Level
{
        char** lev;
        COORD yx;
        int draw_x;
        int draw_y;
        int dx;
        int dy; 
        int x;
        int y;
public:
        Level(char (*lv)[320])
        {
                lev=lv; //как тут правильно назначить? выдаёт ошибку
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
25.04.2011, 12:39 5
Описывай так не зависимо от того статически или динамически массив был выделен:
C++
1
Level(char **lv)
А передавай так:
C++
1
Level(lv);
или
C++
1
Level((char**)lv);
Сообщать компилятору размерность передаваемого массива не нужно, видимо именно поэтому он и не понимает что ты от него хочешь то.
1
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
25.04.2011, 12:48  [ТС] 6
что-то не получается. Напишите плиз код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char lv[50][320];   //как передать правильно этот массив в конструктор ниже?
 
class Level
{
        char** lev;
        COORD yx;
        int draw_x;
        int draw_y;
        int dx;
        int dy; 
        int x;
        int y;
public:
        Level(char **lv)
        {
                lev=lv; //как тут правильно назначить? выдаёт ошибку
0
2022 / 1621 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
25.04.2011, 12:56 7
Цитата Сообщение от dimon1984 Посмотреть сообщение
lev=lv; //как тут правильно назначить? выдаёт ошибку
C++
1
2
3
4
5
6
char (*lev)[320];
...
Level(char (*lv)[320])
{
    lev = lv; 
    ...
1
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
25.04.2011, 12:58 8
dimon1984, Что конекретно не работает? Ошибку компилятор выдает или при выполнении выскакивает? На какой строке ошибка?
0
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
25.04.2011, 13:31  [ТС] 9
если написать, как в 6-м посте, то компилируется, но при запуске выдаёт ошибку.

Добавлено через 3 минуты
C++
1
2
3
4
5
6
char (*lev)[320];
...
Level(char (*lv)[320])
{
    lev = lv; 
    ...
ошибка
error C2440: '=' : cannot convert from 'char (*)[320]' to 'char ** '
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Добавлено через 2 минуты
или может не char lev[50][320]; использовать а что-то проще? динамически выделять?
просто хотелось разобраться, как всё-таки с char lev[50][320]; надо.

Добавлено через 5 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
    Level l(lv);
 
    while(true)
    {
        l.Draw();
    }
 
    system("pause");
    return 0;
}
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
25.04.2011, 13:37 10
dimon1984, Вообще правильнее выделять динамически, а потом передавать в класс (как это делать я еще в первом посте написал).
Когда ты выделяешь статически, у тебя массив уничтожается после окончания процедуры, в которой был создан.
1
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
25.04.2011, 20:32  [ТС] 11
есть класс Level и другой класс, допустим men, и из этого men надо менять переменную из класса Level. Как это организовать? чтобы не создавать в классе men обьект Level. Надо наверно static ?
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
class Level
{
protected:
    char **lev;
    COORD yx;
    static int draw_x;   //правильно? надо сделать static, чтобы менять из другого класса
    static int draw_y;
    int dx, dy; 
    int x, y;
public:
    Level()
    {
        lev= new char*[50];
        for(y=0;y<50;y++) lev[y]=new char[320];
        for(x=0;x<320;x++)
        {
            for(y=0;y<50;y++)
                lev[y][x]=' ';
        }
...
    static int Get_dx() {return draw_x;}
    static int Get_dy() {return draw_y;}
    static void add_dx() {draw_x++;}
    static void sub_dx() {draw_x--;}
    static void add_dy() {draw_y++;}
    static void sub_dy() {draw_y--;}
};
компилируется, но не линкуется:
error LNK2001: unresolved external symbol "protected: static int Level::draw_y" (?draw_y@Level@@1HA)
переменную draw_x из класса Level менял так: Level::add_dx(); из класса men

Добавлено через 33 минуты
не могу найти в книге про это, которую давненько читал, подзабыл

Добавлено через 25 минут
мне подскажут?
или может идею подкинете? Тоесть я пытаюсь из класса men при перемещении менять значение класса Level чтобы перемещался экран в соответствии движению.
Что посоветуете? Как всё-таки изменить переменную класса Level

Добавлено через 12 минут
принцип? неужели трудно подсказать?

Добавлено через 35 минут
так как там?

Добавлено через 3 часа 16 минут
поделитесь идеей пожалуйста. Допустим проверка на соприкосновение со стенками лучше в другом потоке делать?
есть управляемый символ по консоли. Что лучше запускать в отдельном потоке? Какую функцию?
Или можно не запускать отдельный поток CreateThread?
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
25.04.2011, 21:14 12
static тебе тут нафиг не нужен....
Ты слишком много накручиваешь, все намного проще.
Из того что ты написал нифига не понятно, что такое level и какое отношение он имеет к экрану. Ты сначала составь структуру классов. определи какой класс за что будет отвечать, а потом уже кидайся программу писать.
Ты хочешь работать с массивом lev класса level из класса men?
Если обьекты классов level и men независимы, тогда создаешь эти два класса, lev заносишь в public, в men сохраняешь адрес вызываемого обьекта, и обращаешься так:
родитель->обьект level->lev

Добавлено через 1 минуту
Насчет потоков сам смотри что у тебя должно параллельно выполняться. а что можно и последовательно, нафига проверку соприкосновения со стенками выделять в поток я вообще не понимаю....может это конечно еще один метод мазохизма...
1
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
25.04.2011, 22:48  [ТС] 13
lev заносишь в public, в men сохраняешь адрес вызываемого обьекта, и обращаешься так:
родитель->обьект level->lev
а немного конкретней можно?
к примеру есть два обьекта
C++
1
2
Level l;
men M;
и кто здесь родитель?
Насчет потоков сам смотри
согласитесь, если бы у меня был опыт, зачем тогда я бы спрашивал у вас?
это одно из первых прог, которые я делаю. Опыта ещё маловато.
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
26.04.2011, 05:13 14
dimon1984, Я имею ввиду тот обьект, внутри которого созданы обьекты L и M. У тебя возможно это будет класс окна.
Ты толком общей структуры своей программы не понимаешь, а приводишь только куски своего кода и хочешь что бы тебе объяснили что то....

Даже если нет опыта, сам рассуди, зачем проверку выделять в поток, ты там цикл сделаешь, который будет периодически проверять значения? Не проще ли при движении обьекта проверять соприкосновение. Ты пока без потоков научись ООП применять.
0
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
26.04.2011, 19:29  [ТС] 15
Ты пока без потоков научись ООП применять
согласен. Уже несколько раз переделывал организацию программы, т.е. классы, сначало вообще пытался без классов.
Есть метод класса проверки соприкосновения:
C++
1
2
3
4
5
6
7
    bool Get_simb(short _x, short _y, char s)
    {
        pos.Y = _y; pos.X = _x;
        ReadConsoleOutputCharacter(hConsole, &str, 1, pos, &len);
        if(str==s) return true;
        return false;
    }
и метод обработки клавиш:
C++
1
2
3
4
5
6
7
8
9
10
11
    void moves()
    {
        kl=getch();
        if(kl=='d')
        {
            if(xy.X<60 || xy.X>=60 && draw_x==240)
                {if(xy.X<79) xy.X++;}
            else if(draw_x<240)  draw_x++;
            if(mx<319) mx++;
        }
...
kl=getch(); я делаю правильно? используя kl=getch();
или что лучше использовать?
в main я пока делаю так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
//  Level L;
    men Man(20,5,'X');
 
    while(!KEYDOWN(VK_ESCAPE))
    {
        Man.Draw();
 
//      Man.grav();
        Man.moves();
    }
тоесть пока не нажата Escape, выполняется игра.
так дело в том, я использую проверку на соприкосновение в методе void moves() обработки клавиш:
C++
1
2
3
if(!Get_simb(xy.X, xy.Y+1, char(177)) 
...
дальше обработка клавиш, как выше
при такой организации если подойти к стенке ,то человечек как бы зависает на месте, и мигает, как будто удерживается клавиша. Как надо лучше?

Добавлено через 11 часов 54 минуты
так что там на счёт kl=getch();
getch() можно использовать или что-то другое?
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
26.04.2011, 19:33 16
Не понятно почему подвисает, выложи весь код, тогда может что будет ясно....
Но я консольными играми не занимался, хрен его знает какие там приколы могут всплыть...
1
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
26.04.2011, 20:03  [ТС] 17
как я уже упоминал, опыта ещё маловато, так что очень буду рад любым полезным и просто для размышления подсказкам
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
 
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
 
class Level
{
protected:
    char **lev;
    COORD yx;
    int draw_x;
    int draw_y;
    int dx, dy; 
    int x, y;
public:
 
    Level()
    {
        lev= new char*[50];
        for(y=0;y<50;y++) lev[y]=new char[320];
        for(x=0;x<320;x++)
        {
            for(y=0;y<50;y++)
                lev[y][x]=' ';
        }
        for(y=5;y<15;y++) lev[y][10]=char(177);
        for(y=5;y<15;y++) lev[y][220]=char(177);
        for(x=11;x<220;x++) lev[14][x]=char(177);
 
        for(y=30;y<40;y++) lev[y][8]=char(177);
        for(y=30;y<40;y++) lev[y][210]=char(177);
        for(x=9;x<210;x++) lev[39][x]=char(177);
        draw_x=0, draw_y=0;
        dx=0,dy=0; 
        yx.X=0; yx.Y=0;
        ShowConsoleCursor(FALSE);
    }
    ~Level()
    {
        for(x=0;x<50;x++) delete[]lev[x];
        delete[]lev;
    }
    void Draw()
    {
//      ShowConsoleCursor(FALSE);
        x=draw_x, y=draw_y;
/*
        yx.X=10; yx.Y=0; //x=draw_x, y=draw_y;
        SetConsoleCursorPosition(hConsole, yx);
        cout<<"draw_x="<<draw_x<<' '<<"draw_y="<<draw_y<< \
            ' '<<"mx="<<mx<<' '<<"my="<<my<<' '<<cout<<lev[my][mx];*/
        while(true) //vivod level
        {
            yx.X=dx; yx.Y=dy;
            if(dx==80) {dy++; dx=0; y++; x=draw_x;}
            if(dy==24 && dx==79) break;
            SetConsoleCursorPosition(hConsole, yx);
            cout<<lev[y][x]; x++; dx++;
        }
        dy=0; y=draw_y;
    }
/*  int Get_dx() {return draw_x;}
    int Get_dy() {return draw_y;}
    void add_dx() {draw_x++;}
    void sub_dx() {draw_x--;}
    void add_dy() {draw_y++;}
    void sub_dy() {draw_y--;}*/
};
 
class Moves: public Level
{
protected:
    COORD xy;
    int mx, my;
//  char X;
    char kl;
public:
//  Moves():{}
    Moves(short _x, short _y): Level()
    {xy.X=_x; xy.Y=_y; mx=_x; my=_y;}
 
    void moves()
    {
//      SetConsoleCursorPosition(hConsole, xy);
//      cout<<X;
        kl=getch();
        if(kl=='d')
        {
            if(xy.X<60 || xy.X>=60 && draw_x==240)
                {if(xy.X<79) xy.X++;}
            else if(draw_x<240)  draw_x++;
            if(mx<319) mx++;
        }
        else if(kl=='a')
        {
            if(xy.X>=20  \
                || xy.X<20 && draw_x==0) 
                {if(xy.X>0) xy.X--;}
            else if(draw_x>0) draw_x--;
            if(mx>0) mx--;
        }
        else if(kl=='w')
        {
/**/
            if(xy.Y>=10  \
                || xy.Y<10 && draw_y==0) 
                {if(xy.Y>0) xy.Y--;}
            else if(draw_y>0) draw_y--;
            if(my>0) my--;
        }
        else if(kl=='s')
        {
/**/
            if(xy.Y<15  \
                || xy.Y>=15 && draw_y==25)
                {if(xy.Y<24) xy.Y++;}
            else if(draw_y<25) draw_y++;
            if(my<49){my++;}
        }
        kl=0;
    }
};
/**/
class men: public Moves
{
protected:
    char X;
    bool fl;
    int t;
    char str;
    unsigned long len;
public:
    men(short _x, short _y, char _X):Moves(_x,_y) {X=_X; fl=true;}
 
    bool Get_simb(short _x, short _y, char s)
    {
        pos.Y = _y; pos.X = _x;
        ReadConsoleOutputCharacter(hConsole, &str, 1, pos, &len);
        if(str==s) return true;
        return false;
    }
    void Draw()
    {
/**/
        Moves::Draw();
        yx.X=10; yx.Y=0; //x=draw_x, y=draw_y;
        SetConsoleCursorPosition(hConsole, yx);
        cout<<"draw_x="<<draw_x<<' '<<"draw_y="<<draw_y<< \
            ' '<<"mx="<<mx<<' '<<"my="<<my<<' '<<lev[my][mx];
    }
    void moves()
    {
        SetConsoleCursorPosition(hConsole, xy);   cout<<X;
        if(Get_simb(xy.X-1, xy.Y, ' '))   //здесь проверка на соприкосновение
        { if(fl) Moves::moves(); }   // при подходе к стене зависает чувак
//      else if(Get_simb(xy.X+1, xy.Y, ' ')) Moves::moves();
//          Moves::moves();
//      else cout<<'W';
    }
/**/
    void grav()   // гравитация
    {
        if(Get_simb(xy.X, my+1, ' '))
        {
            fl=false;
            while(true)
            {
                t=GetTickCount();
                while(true)
                {
                    if(GetTickCount()-t==250)
                    {
                        SetConsoleCursorPosition(hConsole, xy); cout<<' ';
                        if(xy.Y<15  || xy.Y>=15 && draw_y==25)
                            {if(xy.Y<24) xy.Y++;}
                        else if(draw_y<25) draw_y++;
                        if(my<49){my++;}
                        SetConsoleCursorPosition(hConsole, xy);
                        cout<<X; break;
                    }
                }
                if(Get_simb(xy.X, my+1, char(177))) break;
            }
            fl=true;
        }//if
    }// grav()
};
 
 
int main()
{
//  Level L;
    men Man(20,5,'X');
 
    while(!KEYDOWN(VK_ESCAPE))
    {
        Man.Draw();
 
        Man.grav();
        Man.moves();
    }
 
    system("pause");
    return 0;
}
 
BOOL ShowConsoleCursor(BOOL bShow)
{
    CONSOLE_CURSOR_INFO cci;
    HANDLE hStdOut;
 
    hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
 
    if(hStdOut == INVALID_HANDLE_VALUE)
        return FALSE;
 
    if(!GetConsoleCursorInfo(hStdOut, &cci))
        return FALSE;
 
    cci.bVisible = bShow;
 
    if(!SetConsoleCursorInfo(hStdOut,&cci))
        return FALSE;
 
    return TRUE;
}
Я для простоты в коде наследовал класс Level классом men.
Потом может что-то придумаю может что-то подскажете полезное.
Man.moves(); в цикле идёт обработка клавиш.
Вложения
Тип файла: rar game.rar (95.5 Кб, 7 просмотров)
0
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
26.04.2011, 20:45  [ТС] 18
в 158-й строке
if(Get_simb(xy.X-1, xy.Y, ' ')) //здесь проверка на соприкосновение
{ if(fl) Moves::moves(); }
я проверял только одну сторону для простоты. Получается если слева стена, (xy.X-1) то человечек начинает мигать, какбудто зажата какая-то клавиша как при вводе.
А должен просто по идее не вызывать moves()
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
26.04.2011, 21:13 19
dimon1984,Ээээ.....а наследование то тут причем, как оно вписывается в модель приложения....мне кажется что никаким боком....
0
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
27.04.2011, 08:20  [ТС] 20
Я для простоты в коде наследовал класс Level классом men.
Потом может что-то придумаю может что-то подскажете полезное.
на первое время для простоты
не в этом дело.
Меня интересует getch()
у меня уже было несколько версий игры много дополнял удалял

Добавлено через 23 минуты
можно конечно делать проверку на соприкосновение не вызывая метод Get_simb
а проверять значения массива lev, но это не меняет дела, тоже самое.
Как надо правильно организовать проверку соприкосновения?
может отдельную функцию сделать? И как правильно организовать обработку клавиш? Может не надо использовать getch() ?
чтото другое

Добавлено через 1 час 59 минут
друзья, посоветуйте пожалуста на счёт кода.

Добавлено через 8 часов 39 минут
если в методе moves() поменять обработку клавиш: if(KEYDOWN ...
тоже самое, при подходе к стене человечек зависает на месте и мигает, как будто удерживается клавиша
0
27.04.2011, 08:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.04.2011, 08:20
Помогаю со студенческими работами здесь

Несколько вопросов по извучению C++
Добрый день, товарищи!! Я немного новичек в вопросах программирования на C++, поэтому прошу...

Несколько вопросов по строкам в С
Привет всем участникам форума. Изучаю С++, по пути прошел строки из С ( массивы символов ) И...

Несколько простых вопросов от начинающего
Здравствуйте! Мне интересны следующие вопросы: 1. Где лучше объявить переменные нужные на...

Несколько вопросов про массив
Добрый день, было задание написать программку, которая бы подсчитывала количество элементов в...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru