Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 24, средняя оценка - 4.71
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
#1

Создание игр в текстовом режиме - C++

17.02.2014, 00:43. Просмотров 3304. Ответов 67
Метки нет (Все метки)

Привет всем! Тут занялся написанием игрушек в текстовом режиме, типа змейки, тетриса и т.п. Суть в том, что я хочу как можно более правильно написать код, со стороны рефакторинга, со стороны выделения и освобождения памяти, и многих других аспектов. Думаю эта тема поможет многим новичкам, в написание чего-либо подобного, поэтому буду потихоньку выкладывать свои исходники и ждать ваших комментариев.Долго думал куда все-таки отнести эту тему, но решил остановиться здесь.
Итак, сейчас я хочу выложить класс интерфейса(менюшка), и данный класс будет использоваться в любой мной написанной игре.

Файл _interface.h

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
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include "msoftcon.h"
using namespace std;
 
 
/* ## Cтруктура списка интерфейса ## */
struct ListMenu 
{
    vector<wstring> item;
};
 
 
/* ## Абстрактный класс интерфейса ## */
class _interface
{
protected:
    int CurrentMenu();                              // Получение текущего списка меню
    int CurrentCursor();                            // Получение каретки текущего пункта меню
    static void NextMenu();                         // Следующий список меню
    static void BackMenu();                         // Предыдущий список меню
    void AddListMenu(wstring);                      // Добавить пункт в список меню
    void ClearListMenu();                           // Очистить список меню
    int SizeListMenu();                             // Размер списка меню
    void DrawMenu();                                // Прорисовка списка меню
 
private:
    static int current_menu;                        // Текущий список меню
    int current_cursor;                             // Каретка текущего пункта меню
    int x,y;                                        // Координаты прорисовки списка на экране
    ListMenu *menu;                                 // Структура списка меню
 
public:
    _interface(int,int);                            // Конструктор
    ~_interface();                                  // Деструктор
 
    virtual void Run() = 0;                         // Запуск статической системы меню
    virtual void Run(ListMenu*) = 0;                // Запуск динамической системы меню
};
Ну что могу сказать по поводу этого класса. Ну первое, это абстрактный класс, то есть создание экземпляров от этого класса будет невозможно.

У меня есть 8 методов в области видимости protected, которые будут доступны соответственно классу - потомку. Сейчас распишу примерно, что каждый метод делает:
Кликните здесь для просмотра всего текста
int CurrentMenu() - Соответственно получает номер текущего меню. При создании первого экземпляра класса - потомка номер текущего меню равен 0.
static void NextMenu() - Изменяет номер текущего меню на следущее +1.
static void BackMenu(); - Изменяет номер текущего меню на предыдущее -1.
int CurrentCursor() - Получаем номер текущего пункта меню, где в данное время находится каретка указателя.
void AddListMenu(wstring) - Так мы можем добавить пункт меню в список меню.
void ClearListMenu() - Соответсвенно, что видно из название - очищаем список меню.
int SizeListMenu() - Размер текущего списка меню(Количество пунктов меню данного списка).
void DrawMenu() - Метод прорисовки списка меню и выбора определенного пункта меню.


Теперь расскажу про область видимости private. Там находятся поля класса. Про них особо нечего рассказывать, практически все методы, которые были описаны выше, просто манипулируют этими полями и все:
Кликните здесь для просмотра всего текста
static int current_menu - Номер текущего меню. Причем сколько бы экземпляров класса - потомка не было, это значение для всех общее.
int current_cursor - Номер текущего пункта меню, где в данное время находится каретка указателя.
int x,y - Координаты вывода списка меню на экране.
ListMenu *menu - Ну и конечно структура самого списка меню, состоящая из одного всего поля - вектора библиотеки STL, где хранятся все пункты меню.


Ну и public:
Кликните здесь для просмотра всего текста
_interface(int,int) - Конструктор как вы поняли.
~_interface() - Деструктор соответственно.
virtual void Run() = 0 - Вот это самое интересное.Это чисто виртуальная функция, которая будет заводить всю систему меню. Она должна обязательно быть перегружена в классе - потомке, и все меню и события по нажатию на определенные пункты меню должны создаваться в ней. То есть все что связано с меню, должно выполняться именно в этой функции.
virtual void Run(ListMenu*) = 0 - Метод Run(), это статическое управление списками меню, то есть я не могу создавать, изменять, удалять меню программно. Для этого я создал функцию Run(ListMenu*), которая делает все тоже самое что и Run(), только принимает в качестве формального параметра список меню, что следовательно,что я могу создать меню программно, что иногда очень бывает нужно.


Выкладываю определение всех методов данного класса. Файл _interface.cpp

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
#include "_interface.h"
 
 
int _interface :: current_menu = 0;
 
 
/* ## Конструктор ## */
_interface :: _interface(int x1,int y1) : x(x1),y(y1)
{ 
    init_graphics();
    menu = new ListMenu;
}
 
 
/* ## Деструктор ## */
_interface :: ~_interface()
{ }
 
 
/* ## Следующий список меню ## */
void _interface :: NextMenu()
{
    current_menu++;
}
 
 
/* ## Предыдущий список меню ## */
void _interface :: BackMenu()
{
    current_menu--;
}
 
 
/* ## Получение текущего списка меню ## */
int _interface :: CurrentMenu()
{
    return current_menu;
}
 
 
/* ## Получение каретки текущего пункта меню ## */
int _interface :: CurrentCursor()
{
    return current_cursor;
}
 
 
/* ## Добавить пункт в список меню ## */
void _interface :: AddListMenu(wstring item)
{
    menu -> item.push_back(item);
}
 
 
/* ## Очистить список меню ## */
void _interface :: ClearListMenu()
{
    menu -> item.clear();
}
 
 
/* ## Размер списка меню ## */
int _interface :: SizeListMenu()
{
    return menu -> item.size();
}
 
 
/* ## Прорисовка списка меню ## */
void _interface :: DrawMenu()
{
    set_color(cWHITE,cBLACK);
    clear_screen();
 
    for(int i = 0; i < menu -> item.size(); i++)
    {
        set_cursor_pos(x + 4,y + i);
        wcout << menu -> item[i] << endl;
    }
 
    set_cursor_pos(x,y);
    current_cursor = 1;
    char c;
 
    do
    {
        for(int i = 0; i < SizeListMenu(); i++)
        {
            if(i == current_cursor - 1)
            { set_color(cBLACK,cYELLOW); }
            else
            { set_color(cBLACK,cBLUE); }
 
            set_cursor_pos(x,y + i);
            cout << "->";
        }
 
        c = _getch();
 
        switch(c)
        {
        case 72: if(current_cursor != 1) { current_cursor = current_cursor - 1; } break;
        case 80: if(current_cursor != SizeListMenu()) { current_cursor = current_cursor + 1; } break;
        }
    }
    while(c != 13);
}
Ну если все понятно, можно теперь создать собственно меню.) Создаем вначале класс - потомок. Файл ___interface.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
#include "_interface.h"
using namespace std;
 
 
/* ## Производный класс от класса интерфейса ## */
class ___interface : public _interface
{
public:
    ___interface(int,int);      // Конструктор
    ~___interface();            // Деструктор
 
    void Run();                 // Запуск статической системы меню
    void Run(ListMenu*);        // Запуск динамической системы меню
};
Здесь вроде все понятно, теперь соответственно определяем функции Run() и Run(ListMenu*). Но прежде чем их определить, нужно придумать меню).
Давайте создадим меню из списка: START, OPTION, EXIT.
По нажатию на START - Выводится сообщение "hello world"
По нажатию на OPTION - Создается второе меню - DINAMIC CREATE MENU, MESSAGE, BACK
По нажатию на EXIT - Выходим из программы

Теперь распишем что будет делать второе меню,созданное по нажатию на OPTION.
По нажатию на DINAMIC CREATE MENU - Создается динамическое меню, из 6 пунктов, если нажмем на один из первых трех - вернемся назад на второе меню, если нажмем на один из трех следующих - вернемся на START, ...
По нажатию на MESSAGE - Выводится сообщение "I Love CyberForum" и возвращаемся на меню START, ...
По нажатию на BACK - Возвращаемся назад на первое меню

Ну вот более менее подходящее меню, чтобы задействовать всю мощь моего написанного класса)
Реализовываем. Файл ___interface.cpp

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
#include "___interface.h"
 
 
/* ## Конструктор ## */
___interface :: ___interface(int x,int y) : _interface(x,y)
{ }
 
 
/* ## Деструктор ## */
___interface :: ~___interface()
{ }
 
 
/* ## Запуск системы ## */
void ___interface :: Run()
{
    set_color(cWHITE,cBLACK);
 
    ClearListMenu();
 
    switch(CurrentMenu())
    {
    case 0: // Первое меню - START  OPTION  EXIT
        {
            AddListMenu(L"START");
            AddListMenu(L"OPTION");
            AddListMenu(L"EXIT");
 
            DrawMenu();
 
            switch(CurrentCursor())
            {
            case 1:
                {
                    clear_screen();
                    cout << "hello world";
                    getch();
                }
            break;
 
            case 2:
                {
                    NextMenu();
                }
            break;
 
            case 3:
                {
                    exit(0);
                }
            break;
            }
        }
    break;
 
    case 1: // Второе меню - DINAMIC CREATE MENU   MESSAGE   BACK
        {
            AddListMenu(L"DINAMIC CREATE MENU");
            AddListMenu(L"MESSAGE");
            AddListMenu(L"BACK");
 
            DrawMenu();
 
            switch(CurrentCursor())
            {
            case 1:
                {
                    clear_screen();
                    ListMenu* DinamicMenu = new ListMenu;
                    wstring item;
 
                    for(int i = 0; i < 6; i++)
                    {
                        cout << "Input item of menu";
                        wcin >> item;
                        DinamicMenu -> item.push_back(item);
                    }
 
                    Run(DinamicMenu); // Создаем новое меню динамически
                }
            break;
 
            case 2:
                {
                    clear_screen();
                    cout << "I Love CyberForum";
                    getch();
                    BackMenu();
                }
            break;
 
            case 3:
                {
                    BackMenu();
                }
            break;
            }
        }
    break;
 
    }
 
    Run(); // Рекурсивно вызываем эту же функцию
}
 
 
void ___interface::Run(ListMenu *list)
{
    set_color(cWHITE,cBLACK);
    NextMenu();
    ClearListMenu();                                // Очищаем список
 
    for(int i = 0; i < list -> item.size(); i++)
    {
        AddListMenu(list -> item[i]);               // Инициализируем список с формальным параметром
    }
 
    DrawMenu();                                     // Прорисовка списка меню
 
    switch(CurrentCursor())
    {
    case 1: BackMenu(); break;
    case 2: BackMenu(); break;
    case 3: BackMenu(); break;
    case 4: { BackMenu(); BackMenu(); } break;
    case 5: { BackMenu(); BackMenu(); } break;
    case 6: { BackMenu(); BackMenu(); } break;
    }
}
В main.cpp можно вызвать меню таким способом:

C++
1
2
3
4
5
6
7
8
9
#include "___interface.h"
 
 
void main()
{
    ___interface *inter = new ___interface(38,10);
 
    inter -> Run();
}
Постепенно я буду выкладывать и остальные части игр, и буду слушать ваше мнение по написанному. Почему я начал с меню? Потому что это главный класс, который заводит всю игру, и его нужно написать на сколько можно правильно. Поэтому жду ваших комментариев,критик по поводу написанного, может что то нужно изменить, добавить, убрать. Я прислушаюсь к любому мнению)
1
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.02.2014, 00:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Создание игр в текстовом режиме (C++):

Создание интерфейса пользователя в текстовом режиме - C++
Создание интерфейса пользователя в текстовом режиме. Библиотека PDCurses. (С++) Задание: В текстовом режиме экрана реализуйте...

Работа с экраном в текстовом режиме - C++
Ниже дана программа которая до нажатия Esc повторяет действия: случайным образом выбирает размеры (соотношение 25х80) и положение окна ...

Работа с экраном в текстовом режиме - C++
В меню с выбором пунктов Функциональными Клавишами по программе с клавиатуры в 1-е окно вводится текст с цифрами. Во 2-м окне...

Нарисовать мышью прямоугольник в текстовом режиме экрана - C++
Помогите разобраться.. Нужно нарисовать прямоугольник (любыми символами) в текстовом режиме экрана с помощью мышки. Ну я пытался...

ООП иерархия классов с выводом в текстовом режиме - C++
Помогите с решением &quot;Дана иерархия классов числа-числа кратные 5-числа кратные 25. Написать программу с выводом объектов указанных классов...

Как сделать прокрутку (в текстовом режиме) и менюшку в turbo c - C++
(Turbo c)Если прогамма выводит на экран большое кол-во информации, то некоторая её часть становится недоступной, как же сделать прокрутку...

67
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
21.02.2014, 02:51  [ТС] #16
Jupiter,вы сказали,что мой класс делает все,и вы скорее всего имели ввиду,что его нужно разложить на более маленькие классы,чтобы лучше применить рефакторинг...скорее всего много чего лишнего уберется и изменится в лучшую сторону...но я не вижу где его изменить!может мне не хватает опыта?(можете приблизительно рассказать,как бы вы реализовали этот класс в лучшую сторону?
буду очень благодарен
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
21.02.2014, 09:38 #17
Цитата Сообщение от Bretbas Посмотреть сообщение
Jupiter,вы сказали,что мой класс делает все,и вы скорее всего имели ввиду,что его нужно разложить на более маленькие классы,
я раньше писал статью на этот счёт, когда отвечал на вопросы на этом форуме.
Но так как я теперь использую https, в ссылках нужно заменять http на https.
Возможно сегодня вечером поправлю ссылки.
Используя преобразование диаграммы бизнес объектов в диаграмму классов, размер класса обычно не превышает 1000 строк.
0
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
21.02.2014, 23:42  [ТС] #18
я не понимаю в чем мне нужно изменить свой класс,но я однозначно знаю что это нужно сделать.
Подкиньте идейки то?
1
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
22.02.2014, 00:11 #19
Цитата Сообщение от Bretbas Посмотреть сообщение
я не понимаю в чем мне нужно изменить свой класс,но я однозначно знаю что это нужно сделать.
Подкиньте идейки то?
Нормальный у вас класс. Все связано с меню, я на вашем месте ничего не разбивала бы на мелкие классы.
1
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
22.02.2014, 00:18  [ТС] #20
еще будут мнения или на этом остановимся?
0
programina
22.02.2014, 00:49
  #21

Не по теме:

Цитата Сообщение от Bretbas Посмотреть сообщение
еще будут мнения или на этом остановимся?
Говорят, что утро вечера мудренее. Половина России, Украина, Белорусия, Казахстан и др. уже спят.

0
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
23.02.2014, 00:42  [ТС] #22
Так, наконец нашел время все поправить в лучшую сторону. По вашим комментарием собрал вот это:

Файл Interface.h
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
#ifndef INTERFACE_H_
#define INTERFACE_H_
 
#include <iostream>
#include <vector>
#include <string>
 
#include "msoftcon.h"
 
 
/* ## Cтруктура списка интерфейса ## */
struct ListMenu 
{
    vector<wstring> item;
};
 
 
/* ## Абстрактный класс интерфейса ## */
class Interface
{
protected:
    int current_menu() const;                       // Получение текущего списка меню
    int current_cursor() const;                     // Получение каретки текущего пункта меню
    static void next_menu();                        // Следующий список меню
    static void back_menu();                        // Предыдущий список меню
    void add_list_menu(wstring);                    // Добавить пункт в список меню
    void clear_list_menu();                         // Очистить список меню
    int size_list_menu() const;                         // Размер списка меню
    void draw_menu();                               // Прорисовка списка меню
 
private:
    static int number_current_menu_;                // Текущий список меню
    int current_cursor_;                            // Каретка текущего пункта меню
    int x_, y_;                                     // Координаты прорисовки списка на экране
    static ListMenu *menu_;                         // Структура списка меню
 
public:
    Interface(int,int);                             // Конструктор
    virtual ~Interface() = 0;                       // Деструктор
 
    virtual void run() = 0;                         // Запуск статической системы меню
    virtual void run(ListMenu*) = 0;                // Запуск динамической системы меню
};
 
#endif  INTERFACE_H_

Файл Inteface.cpp
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
#include "Interface.h"
 
 
int Interface :: number_current_menu_ = 1;
ListMenu* Interface :: menu_ = NULL;
 
 
/* ## Конструктор ## */
Interface :: Interface(int x,int y) : x_(x),y_(y)
{ 
    init_graphics();
    menu_ = new ListMenu;
}
 
 
/* ## Деструктор ## */
Interface :: ~Interface()
{ 
    delete menu_;
}
 
 
/* ## Следующий список меню ## */
void Interface :: next_menu()
{
    number_current_menu_++;
}
 
 
/* ## Предыдущий список меню ## */
void Interface :: back_menu()
{
    number_current_menu_--;
}
 
 
/* ## Получение текущего списка меню ## */
int Interface :: current_menu() const
{
    return number_current_menu_;
}
 
 
/* ## Получение каретки текущего пункта меню ## */
int Interface :: current_cursor() const
{
    return current_cursor_;
}
 
 
/* ## Добавить пункт в список меню ## */
void Interface :: add_list_menu(wstring item)
{
    menu_ -> item.push_back(item);
}
 
 
/* ## Очистить список меню ## */
void Interface :: clear_list_menu()
{
    menu_ -> item.clear();
}
 
 
/* ## Размер списка меню ## */
int Interface :: size_list_menu() const
{
    return menu_ -> item.size();
}
 
 
/* ## Прорисовка списка меню ## */
void Interface :: draw_menu()
{
    if ( (menu_ == nullptr) || (menu_ -> item.empty()) )
    {
        clear_screen();
        cout << "Check your list menu!It is empty!";
        _getch();
        exit(0);
    }
 
    set_color(cWHITE,cBLACK);
    clear_screen();
 
    for(unsigned int i = 0; i < menu_ -> item.size(); i++) 
    {
        set_cursor_pos(x_ + 4,y_ + i);
        wcout << menu_ -> item[i] << endl;
    }
 
    set_cursor_pos(x_,y_);
    current_cursor_ = 1;
    char c;
 
    do
    {
        for(int i = 0; i < size_list_menu(); i++)
        {
            if(i == current_cursor_ - 1)
            { set_color(cBLACK,cYELLOW); }
            else
            { set_color(cBLACK,cBLUE); }
 
            set_cursor_pos(x_,y_ + i);
            cout << "->";
        }
 
        c = _getch();
 
        switch(c)
        {
        case 72: if(current_cursor_ != 1) { current_cursor_--; } break;
        case 80: if(current_cursor_ != size_list_menu()) { current_cursor_++; } break;
        }
    }
    while(c != 13);
 
    clear_list_menu();
}
 
 
/* ## Запуск динамической системы меню ## */
void Interface :: run(ListMenu *list)
{
    if ( (list == nullptr) || (list -> item.empty()) )
    {
        clear_screen();
        cout << "Check your list menu!It is empty!";
        _getch();
        exit(0);
    }
}

Файл InterfaceChild.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef INTERFACECHILD_H_
#define INTERFACECHILD_H_
 
#include "Interface.h"
 
 
/* ## Производный класс от класса интерфейса ## */
class InterfaceChild : public Interface
{
public:
    InterfaceChild(int,int);        // Конструктор
    ~InterfaceChild();              // Деструктор
 
    void run();                     // Запуск статической системы меню
    void run(ListMenu*);            // Запуск динамической системы меню
};
 
#endif INTERFACECHILD_H_

Файл InterfaceChild.cpp
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
#include "InterfaceChild.h"
 
 
/* ## Конструктор ## */
InterfaceChild :: InterfaceChild(int x,int y) : Interface(x,y)
{ }
 
 
/* ## Деструктор ## */
InterfaceChild :: ~InterfaceChild()
{ }
 
 
/* ## Запуск системы ## */
void InterfaceChild :: run()
{
    set_color(cWHITE,cBLACK);
 
    switch(current_menu())
    {
    case 1: // Первое меню - START  OPTION  EXIT
        {
            add_list_menu(L"START");
            add_list_menu(L"OPTION");
            add_list_menu(L"EXIT");
 
            draw_menu();
 
            switch(current_cursor())
            {
            case 1:
                {
                    clear_screen();
                    cout << "hello world";
                    _getch();
                }
            break;
 
            case 2:
                {
                    next_menu();
                }
            break;
 
            case 3:
                {
                    exit(0);
                }
            break;
            }
        }
    break;
 
    case 2: // Второе меню - DINAMIC CREATE MENU   MESSAGE   BACK
        {
            add_list_menu(L"DINAMIC CREATE MENU");
            add_list_menu(L"MESSAGE");
            add_list_menu(L"BACK");
 
            draw_menu();
 
            switch(current_cursor())
            {
            case 1:
                {
                    clear_screen();
                    ListMenu* DinamicMenu = new ListMenu;
                    wstring item;
 
                    for(int i = 0; i < 6; i++)
                    {
                        cout << "Input item of menu";
                        wcin >> item;
                        DinamicMenu -> item.push_back(item);
                    }
 
                    run(DinamicMenu);
                }
            break;
 
            case 2:
                {
                    clear_screen();
                    cout << "I Love CyberForum";
                    _getch();
                    back_menu();
                }
            break;
 
            case 3:
                {
                    back_menu();
                }
            break;
            }
        }
    break;
 
    }
 
    run(); // Рекурсивно вызываем эту же функцию
}
 
 
void InterfaceChild :: run(ListMenu *list)
{
    Interface :: run(list);
    set_color(cWHITE,cBLACK);
 
    for(unsigned int i = 0; i < list -> item.size(); i++)
    {
        add_list_menu(list -> item[i]);                 // Инициализируем список с формальным параметром
    }
 
    draw_menu();                                        // Прорисовка списка меню
 
    switch(current_cursor())
    {
    case 1: back_menu(); break;
    case 2: back_menu(); break;
    case 3: back_menu(); break;
    }
}

Ну и конечно же сам main.cpp
C++
1
2
3
4
5
6
7
8
9
10
#include "InterfaceChild.h"
 
 
int main()
{
    InterfaceChild *inter = new InterfaceChild(38,10);
    inter -> run();
 
    return 0;
}

Вроде все, ничего не забыл) Ну теперь жду ваших новых комментариев по новому "улучшенному коду". Что скажете? Так оставлять или можно что-то еще изменить?)
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
23.02.2014, 01:11 #23
Название класса Interface не несёт в себе никакой сущности, вы также не определяете пространств имен для класса.
В больших проектах это грозит тем, что на использование класса Interface будут претендовать совершенно разные по назначению классы, и в конечном счете заставит разделить вас класс Interface на несколько. Этой ситуации можно избежать, определив на ранних этапах сущности предметной области, что я и пытался объяснить в статье на которую давал ссылку. Думаю Страуструп также относит ваш подход к "overabstract"

Поэтому дальше названия класса проверять не интересно.
0
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
23.02.2014, 01:29  [ТС] #24
XRuZzz, я не понял, какой сущности нет в названии моего класса?Если я переименую его в AbstractInterface то будет у него сущность?или я вас не правильно понял?объясните пожалуйста.
а про какие пространства имен идет речь?у меня в классе используется только одно пространство имен std и больше ничего.
0
0x10
2474 / 1647 / 247
Регистрация: 24.11.2012
Сообщений: 4,068
23.02.2014, 08:24 #25
Для такой простой задачи написать такой сложный класс - это, конечно, надо было постараться.
Не будем зарываться в реализацию, а посмотрим на класс с точки зрения пользователя.

По идее, должно быть достаточно посмотреть на интерфейс класса, чтобы стало ясно как его использовать. А что у нас в интерфейсе?
C++
1
2
    virtual void run() = 0;                         // Запуск статической системы меню
    virtual void run(ListMenu*) = 0;                // Запуск динамической системы меню
Два метода для какой-то статической системы и какой-то динамической. О чем это вообще?
Ок, второй метод я еще могу понять - передаем список пунктов, которые следует отобразить. А первый? Откуда он возьмет этот список? Интерфейс не дает ответов на эти вопросы.

А теперь главный фейл - метод run чисто виртуальный. Т.е. я, как пользователь, обязан каждый раз для каждого меню писать свой дочерний класс и каждый раз реализовывать логику выбора пункта и отрисовки меню? Вот уж чего мне точно хочется меньше всего. Скорее всего в большинстве случаев логика будет одна: выбрали пункт - вызвали его обработчик - отрисовали меню.
В данном случае эта логика уже реализована в дочернем классе, и тут возникает вопрос - это пример использования или этот класс является частью библиотеки?

Если это пример использования, то он отлично показывает насколько плох базовый класс - 120+ строк кода, да еще и с не пойми зачем появившейся рекурсией. В моей маленькой голове не укладывается зачем методу run() может потребоваться вызывать себя.

Если же этот класс предоставляется библиотекой, то не ясно на каких правах в нем захардкожены какие-то пункты меню. Мне могут понадобиться совсем другие.

Дальше смотреть смысла нет, ибо даже если я и решусь реализовывать метод run в своем классе меню, то мне придется смотреть в секцию protected и разбираться какой порядок вызова предполагают предоставляемые методы.

Еще класс навязывает свой способ отрисовки. У меня, например, нет заголовочного файла msoftcon.h (я так понимаю, функции для работы с псевдографикой объявлены в нем).

В общем, напишите для начала простое текстовое меню... Тут еще есть какие-то списки менюшек - не надо. Пусть будет один уровень.
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
23.02.2014, 09:40 #26
Цитата Сообщение от Bretbas Посмотреть сообщение
XRuZzz, я не понял, какой сущности нет в названии моего класса?Если я переименую его в AbstractInterface то будет у него сущность?или я вас не правильно понял?объясните пожалуйста.
а про какие пространства имен идет речь?у меня в классе используется только одно пространство имен std и больше ничего.
ну скажем если поместить Interface в пространство имен gui, становится несколько понятнее. Однако вы используете текстовый режим, поэтому это скорее не gui, а view.
Класс относится к сущности представления главного окна программы. в MVC паттерне я бы назвал его как то вроде MainFormViews.
Я к тому что по названию класса Interface нельзя догадаться относится ли он к главному окну, либо у вас он нужен для какого нить протокола, либо ещё какой-нить интерфейс для работы с реализациями абстрактных классов, который никак не относится к выводу в консоль.
Впрочем еслu вам не нравumcя мой подход, вы можеmе проuгнорuроваmь моё сообщенuе.

Во многом согласен c 0x10.
0
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
23.02.2014, 22:39  [ТС] #27
XRuZzz, я не хочу игнорировать никакое сообщение, ибо дальше я буду выкладывать уже сами игрушки с использованием этого класса меню.Я хочу преслушиваться к каждому мнению, чтобы добиться как можно идеальной техники кода.
Итак,снова я вас не понимаю, мне нужно мой класс переименовать в MainFormViews для лучшего представления того,что данный класс делает?)
А с пространством имен снова не понял(
Вы можете,если вам не сложно, изменить мой код и выложить мне?
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
24.02.2014, 09:40 #28
Цитата Сообщение от Bretbas Посмотреть сообщение
Итак,снова я вас не понимаю, мне нужно мой класс переименовать в MainFormViews для лучшего представления того,что данный класс делает?)
в данном случае слово Form я использую когда есть графический интерфейс, Views если применяется паттерн MVC(о нём можно почитать где угодно)
К вашему коду естественно такое название мало подходит. Техника зависит от опыта, опыта вряд ли вам в форуме за пару дней сильно улучшить технику программирования.
Чтоб углубится в мои подходы к программированию. Нужно потратить значительное время на изучение сайта www.uml2.ru.
вот что пишет Страуструп:
The question ‘‘How does one write good programs in C++?’’ is very similar to the question ‘‘How
does one write good English prose?’’ There are two answers: ‘‘Know what you want to say’’ and
‘‘Practice. Imitate good writing.’’ Both appear to be as appropriate for C++ as they are for English
– and as hard to follow.
Но при это с "Imitate" я не очень согласен.
0
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
25.02.2014, 00:30  [ТС] #29
XRuZzz,вы можете сказать,кроме как названия класса,что нибудь нужно менять еще?может в самом классе нужно изменить что нибудь?или все как надо там?
0
Bretbas
Каждому свое
343 / 113 / 31
Регистрация: 05.08.2013
Сообщений: 1,219
Завершенные тесты: 1
26.02.2014, 02:47  [ТС] #30
ммммм?)
0
26.02.2014, 02:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.02.2014, 02:47
Привет! Вот еще темы с ответами:

Работа с экраном в текстовом режиме (вывод всех цветов фона, разделяя цвета паузой) - C++
Пожалуйста подскажите, как сделать вывод всех цветов фона, разделяя цвета паузой. Задание: Дополнить меню функциональной клавишей F6:...

Создание 2D игр. Начало - C++
Уважаемые форумчане! Помогите: покидайте ссылок на ресурсы, связанные с разработкой 2D игр - платформеров(самых примитивных) на С++ на...

Создание конструкторов игр - C++
Вопрос этот поднимал в теме про xna, но понял что ответа на него там не получу. Всем привет! Решил задать вопрос, как работает 2d игровой...

Создание 2д игр под android на C++ - C++
Доброго времени суток. Очень часто задаюсь мыслью что делаю что либо зря.. и вот такая мысля меня посетила снова, и я решился спросить у...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru