Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Leak
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7
1

Оптимизация и усовершенствование

01.01.2017, 01:35. Просмотров 492. Ответов 21
Метки нет (Все метки)

Здравствуйте, совсем недавно начал изучать язык программирования "С++". Решил попрактиковаться, сделал маленькую консольную игру. Назвал "Лабиринт", помогите как можно упростить код и уменьшить время прорисовки "лабиринта" после каждого хода. В будущем добавлю "монстров" (если так можно назвать символы, разумеется ), и выход, который открываеться ключиком, который будет "спавниться" в одном из нескольких мест, случайно.
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
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <fstream>
#include <stdlib.h>
#include <iomanip>
#include <string.h>
#include <conio.h>
 
using namespace std;
 
int mapa[20][25] =        {{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
                           {3, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 3,},
                           {3, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 3,},
                           {3, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 3,},
                           {3, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3,},
                           {3, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 3,},
                           {3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 3,},
                           {3, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 3,},
                           {3, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 3,},
                           {3, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 3,},
                           {3, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 3,},
                           {3, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 3,},
                           {3, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 3,},
                           {3, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 3,},
                           {3, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 3,},
                           {3, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 3,},
                           {3, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 3,},
                           {3, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 3,},
                           {3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,},
                           {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,}}; //Сам лабиринт.
int n = 1, m = 1, o, b;
char wasd;
 
void maps(){  // Прорисовка лабиринта и игрока в нём.
for (int i = 0; i < 20; i++)
    {
        for (int j = 0; j < 25; j++)
            if (mapa[i][j] == 0)
            {
 
                cout << static_cast<char>(176);
                cout << static_cast<char>(176);
            }
             else if (mapa[i][j] == 3)
            {
                cout << static_cast<char>(35);
                cout << static_cast<char>(35);
            }
             else if (mapa[i][j] == 2)
            {
                cout << static_cast<char>(64);
                cout << static_cast<char>(64);
 
            }
             else if (mapa[i][j] == 4)
            {
                cout << static_cast<char>(36);
                cout << static_cast<char>(36);
            } else
                 cout << "  ";
        cout << endl;
    }
}
 
void player() //Передвижение игрока.
{
wasd = getch();
switch (wasd)
     {
         case 'w': if(mapa[n-1][m]!=3&&mapa[n-1][m]!=0) { mapa[n][m] = 1; n--; } break;
         case 'a': if(mapa[n][m-1]!=3&&mapa[n][m-1]!=0) { mapa[n][m] = 1; m--; } break;
         case 's': if(mapa[n+1][m]!=3&&mapa[n+1][m]!=0) { mapa[n][m] = 1; n++; } break;
         case 'd': if(mapa[n][m+1]!=3&&mapa[n][m+1]!=0) { mapa[n][m] = 1; m++; } break;
 
         case 't': if(mapa[n-1][m]==1) { o = n - 1; b = m; mapa[o][b] = 4; } break; // Возможность застраивать ходы.
         case 'f': if(mapa[n][m-1]==1) { o = n; b = m - 1; mapa[o][b] = 4; } break;
         case 'g': if(mapa[n+1][m]==1) { o = n + 1; b = m; mapa[o][b] = 4; } break;
         case 'h': if(mapa[n][m+1]==1) { o = n; b = m + 1; mapa[o][b] = 4; } break;
}
mapa[n][m] = 2;
}
int main() 
{
 setlocale( LC_ALL,"Russian" );
 cout <<  "        ЛАБИРИНТ" << endl;
 while(1){
    player();
    system("cls");
    maps();
 }
 maps();
 system("PAUSE");
 return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.01.2017, 01:35
Ответы с готовыми решениями:

усовершенствование кода
как сделать чтобы он сначало показевал что написано в файле а уже потом просил...

Усовершенствование кода
Добрый вечер форумчане. Только вхожу в C++ и объектно-ориентированное...

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

Усовершенствование программы, деление нацело и остаток от деления
Добрый вечер, учусь программировать на С++. Придумал одну задачку и решил...

Оптимизация
Условие задачи: Как известно, красить забор Тому Сойеру помогали...

21
GbaLog-
Любитель чаепитий
3165 / 1471 / 465
Регистрация: 24.08.2014
Сообщений: 5,204
Записей в блоге: 1
Завершенные тесты: 2
01.01.2017, 06:38 2
Чтобы "ускорить" прорисовку надо либо делать её с помощью сишных потоков(этого вряд ли будет достаточно), либо использовать сторонние либы, которые могут работать с буфером консоли(правда в таком случае обновления прорисовки вообще не понадобится), либо использовать для подобного API системы.
0
rao
894 / 415 / 158
Регистрация: 02.04.2014
Сообщений: 1,201
01.01.2017, 11:22 3
В целом согласен с GbaLog-, но не совсем.
1) Не очень понятно каким образом "сишные потоки" ускорят прорисовку? Что имелось в виду? cout разве не идентификатор потока? Или подразумевалась многопоточность самого приложения, _beginthread(...) и т.п.) ?
2) Сомневаюсь, что есть какие то "сторонние либы" работающие с буфером консоли, потому что вся эта функциональность исчерпывающе реализована набором соответствующего API: Console Functions. Там есть и чтение символов (ReadConsoleOutputCharacter), и запись (WriteConsole) и позиционирование курсора (SetConsoleCursorPosition) и изменение цвета и пр.
3) По коду: возможно не стоит хранить массив констант и при выводе делать каждому символу if(..). Лучше хранить сразу строки символов (типа "###$####....") Так их проще выводить просто printf'ом

Но еще лучше конечно же работать с буфером консоли. Тогда будет достаточно перерисовывать только изменившиеся символы, а не весь экран (что бы не было мерцания).
0
GbaLog-
Любитель чаепитий
3165 / 1471 / 465
Регистрация: 24.08.2014
Сообщений: 5,204
Записей в блоге: 1
Завершенные тесты: 2
01.01.2017, 15:15 4
Цитата Сообщение от rao Посмотреть сообщение
каким образом "сишные потоки" ускорят прорисовку?
Ну всем давно известно, что сишные потоки быстрее цппшных, поэтому при отрисовке мерцания будут казаться чуть меньше, но это в целом можно даже не заметить, ибо это мерцание будет всё равно достаточно сильным, потому что вечный цикл с обновлением экрана это плохой подход.
Цитата Сообщение от rao Посмотреть сообщение
cout разве не идентификатор потока?
Что имеется ввиду под словом идентификатор?
Цитата Сообщение от rao Посмотреть сообщение
Сомневаюсь, что есть какие то "сторонние либы" работающие с буфером консоли
pdcurses(Win)/ncurses(*nix). Причём большинство никсовых псевдогуишных программ как раз на ncurses написаны, если вообще не все.
Цитата Сообщение от rao Посмотреть сообщение
потому что вся эта функциональность исчерпывающе реализована набором соответствующего API
Представляете, в мире существует такая ОС, как Linux, вернее это не совсем ОС, а дистрибутив, но не об этом речь, API у неё тоже есть, только вот самому разруливать отдельную компиляцию под виндовс и линукс вряд ли кто-то будет, если существует такая вещь, как (pd/n)curses, которая написана специально для этих нужд.
0
Leak
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7
01.01.2017, 18:22  [ТС] 5
Вот новая версия добавил "передвигаемые блоки", которые можно ставить на "t", "f", "g", "h". Простите за не читаемую функцию "player".
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
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <fstream>
#include <stdlib.h>
#include <iomanip>
#include <string.h>
#include <conio.h>
 
using namespace std;
 
char mapa[20][25] ={{176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,},
                   {176,'#',176,176,' ',' ',' ',' ',' ',' ',' ',176,176,176,176,' ',' ',176,176,176,' ',' ',' ',' ',176,},
                   {176,' ',176,176,' ',176,' ',176,176,176,' ',' ',' ',' ',176,176,' ',176,176,176,' ',176,176,' ',176,},
                   {176,' ',176,' ',' ',176,' ',176,' ',' ',' ',176,176,' ',' ',' ',' ',176,' ',' ',' ',176,' ',' ',176,},
                   {176,' ',176,' ',176,176,' ',176,176,176,176,176,176,176,176,176,' ',176,' ',176,' ',176,' ',176,176,},
                   {176,' ',176,' ',176,176,' ',' ',' ',' ',' ',' ',' ',' ',' ',176,' ',176,' ',176,176,176,' ',176,176,},
                   {176,' ',' ',' ',176,176,176,176,176,176,176,176,' ',176,' ',176,' ',176,' ',' ',' ',176,' ',176,176,},
                   {176,176,176,' ',176,' ',176,176,' ',176,176,' ',' ',176,' ',176,' ',176,176,176,' ',176,' ',' ',176,},
                   {176,176,' ',' ',176,' ',' ',' ',' ',176,176,' ',176,176,' ',176,' ',' ',176,176,' ',176,176,' ',176,},
                   {176,176,' ',176,176,176,176,' ',176,176,176,' ',176,176,' ',176,176,' ',176,176,' ',176,176,' ',176,},
                   {176,' ',' ',176,' ',176,176,' ',176,' ',' ',' ',176,176,' ',176,176,' ',' ',176,' ',176,176,' ',176,},
                   {176,' ',176,176,' ',176,176,' ',176,176,176,176,176,176,' ',176,176,176,' ',176,' ',' ',176,' ',176,},
                   {176,' ',' ',' ',' ',176,176,' ',' ',' ',' ',' ',176,' ',' ',176,176,176,' ',176,176,' ',176,' ',176,},
                   {176,176,176,' ',176,176,176,' ',176,176,176,' ',176,' ',176,176,' ',' ',' ',' ',' ',' ',176,' ',176,},
                   {176,' ',176,' ',176,176,176,' ',176,' ',176,' ',176,' ',176,176,' ',176,176,176,176,176,176,' ',176,},
                   {176,' ',176,' ',176,' ',' ',' ',176,' ',176,' ',176,' ',176,176,' ',176,176,' ',' ',' ',176,' ',176,},
                   {176,' ',176,' ',176,' ',176,176,176,' ',176,' ',176,' ',176,176,' ',176,' ',' ',176,' ',176,' ',176,},
                   {176,' ',' ',' ',' ',' ',176,' ',176,' ',176,' ',176,' ',176,176,176,176,176,176,176,' ',176,' ',176,},
                   {176,176,176,176,176,176,176,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',176,' ',' ',},
                   {176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,}};
int n = 1, m = 1, o, b, j = 5, d = 1, g;
char wasd;
 
void maps(){
for (int i = 0; i < 20; i++)
    {
           for (int j = 0; j < 25; j++)
           cout << mapa[i][j] << mapa[i][j];
        cout << endl;
    }
 
}
 
 
void player()
{
wasd = getch();
switch (wasd)
     {
         case 'w': if(mapa[n-1][m]==' ') { mapa[n][m] = ' '; n--; } else if(mapa[n-1][m]=='%'&&mapa[n-2][m]==' '){mapa[n][m] = ' '; n--; mapa[n-1][m]='%';  } break;
         case 'a': if(mapa[n][m-1]==' ') { mapa[n][m] = ' '; m--; } else if(mapa[n][m-1]=='%'&&mapa[n][m-2]==' '){mapa[n][m] = ' '; m--; mapa[n][m-1]='%'; } break;
         case 's': if(mapa[n+1][m]==' ') { mapa[n][m] = ' '; n++; } else if(mapa[n+1][m]=='%'&&mapa[n+2][m]==' '){mapa[n][m] = ' '; n++; mapa[n+1][m]='%'; } break;
         case 'd': if(mapa[n][m+1]==' ') { mapa[n][m] = ' '; m++; } else if(mapa[n][m+1]=='%'&&mapa[n][m+2]==' '){mapa[n][m] = ' '; m++; mapa[n][m+1]='%'; } break;
         case 't': if(mapa[n-1][m]==' ') { o = n - 1; b = m; mapa[o][b] = '%'; } break;
         case 'f': if(mapa[n][m-1]==' ') { o = n; b = m - 1; mapa[o][b] = '%'; } break;
         case 'g': if(mapa[n+1][m]==' ') { o = n + 1; b = m; mapa[o][b] = '%'; } break;
         case 'h': if(mapa[n][m+1]==' ') { o = n; b = m + 1; mapa[o][b] = '%'; } break;
}
mapa[n][m] = '#';
}
int main()
{
 while(1)
 {
 maps();
 player();
 system("cls");
 }
 system("PAUSE");
 return 0;
}
0
hoggy
Нарушитель
Эксперт С++
7084 / 3128 / 647
Регистрация: 15.11.2014
Сообщений: 7,193
Завершенные тесты: 1
02.01.2017, 00:39 6
Цитата Сообщение от GbaLog- Посмотреть сообщение
Ну всем давно известно, что сишные потоки быстрее цппшных, поэтому при отрисовке мерцания будут казаться чуть меньше
шняга. во-первых не быстрее.
а во-вторых, что б не мерцало,
нужно пользовать двойную буферизацию.
это единственный способ достичь плавности.

ну и в третьих, как я понял,
тс не жаловалосо на мерцание.
0
GbaLog-
Любитель чаепитий
3165 / 1471 / 465
Регистрация: 24.08.2014
Сообщений: 5,204
Записей в блоге: 1
Завершенные тесты: 2
02.01.2017, 10:34 7
Цитата Сообщение от hoggy Посмотреть сообщение
во-первых не быстрее
А как же это? https://habrahabr.ru/post/246257/
Ложь?
Цитата Сообщение от hoggy Посмотреть сообщение
во-вторых, что б не мерцало,
нужно пользовать двойную буферизацию.
это единственный способ достичь плавности.
Не понял, как это можно использовать в консоли.
Что это такое я знаю, а как в консоли юзать - нет.
Скорее всего, только через АПИ системы?
Цитата Сообщение от hoggy Посмотреть сообщение
ну и в третьих, как я понял,
тс не жаловалосо на мерцание.
Цитата Сообщение от Leak Посмотреть сообщение
уменьшить время прорисовки "лабиринта" после каждого хода.
Мне кажется, что это как раз для того, чтобы не мерцало.
0
hoggy
Нарушитель
Эксперт С++
7084 / 3128 / 647
Регистрация: 15.11.2014
Сообщений: 7,193
Завершенные тесты: 1
02.01.2017, 14:37 8
Цитата Сообщение от GbaLog- Посмотреть сообщение
Ложь?
собственно, в этой статье и приводится мысль,
что медленность с++ потоков - миф.
всё зависит от того, как их правильно готовить.

так например, в режиме оптимизаций,
отключая все возможные проверки,
синхронизацию с сишными потоками,
получаем:

В C++11 самый быстрый стандартный способ чтения чисел из потока — std::getline + std::stol (в сочетании с sync_with_stdio(false), если используются стандартный поток std::cin). Этот способ заметно быстрее чем scanf и уступает только способам с getchar.
и хотя в статье не приводится конкретных причин почему,
но зато очень наглядно иллюстрируется:
Большой блок + Boost::Spirit ---> абсолютный чемпион.
такой перфоманс в первую очередь достигается
за счет грамотного алгоритма загрузки в целом.
примерно тоже самое можно было бы провернуть и на сишных функциях,
и на приплюснутых.

в целом я конечно согласен, что с ослабленной защитой,
и многочисленными нарушениями инвариантов,
приплюснутые потоки начинают работать,
как обычные сишные функции (собственно, они то там и используется у них под капотом).
и в этом случае проще не заморачиваться,
а сразу писать на сишных функциях ради перфоманса.
но фишка в том, что это все - экономия на спичках.
операции ввода/вывода - традиционно самые медленные.
и настоящая оптимизация здесь - правильно подобрать параметры.
где то отключить буферизацию. где то наоборот включить.
подобрать оптимальный размер блока, и тд.

причем практика показывает,
что в случае просадки производительности,
проще поставить быстрый скази-диск, и ничего не менять в коде.
и скорость ввода/вывода увеличится в сотни раз!
и это будет намного дешевле,
чем платить программисту столько денег,
за непонятные мозговыверты.


Цитата Сообщение от GbaLog- Посмотреть сообщение
Не понял, как это можно использовать в консоли.
это древний как мир паттерн.
для современной графики он конечно несколько морально устарел
и не используется.
(все расчеты нынче происходят прям на видеокарточках).
но для текстовой консольки - то, что доктор прописал.

суть такая:
создаем обычную матрицу цветных буковок.
и запрашиваем у системы два буфера.
один основной (видимый), другой задний (не видимый).

в процессе работы бизнес-логики,
производим модификацию в нашей матрица.
собственно матрица - это что то вроде нашей игровой сцены.
после того, как очередной цикл работы бизнес-логики завершился,
мы определяем: были ли в матрицу внесены изменения.
и если были, тогда копируем содержимое матрицы в задний (не видимый буфер) консоли.
после чего делаем flip - делаем задний буфер передним.
а передний соответственно, становится задним.
содержимое заднего буфера моментально отображается в консоли.

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

Добавлено через 25 секунд
Цитата Сообщение от GbaLog- Посмотреть сообщение
Скорее всего, только через АПИ системы?
я делал когда то через апи
2
GbaLog-
Любитель чаепитий
3165 / 1471 / 465
Регистрация: 24.08.2014
Сообщений: 5,204
Записей в блоге: 1
Завершенные тесты: 2
02.01.2017, 14:53 9
Цитата Сообщение от hoggy Посмотреть сообщение
это древний как мир паттерн.
Ну я же сказал, что знаю что это, зачем было объяснять?
Цитата Сообщение от hoggy Посмотреть сообщение
но фишка в том, что это все - экономия на спичках.
операции ввода/вывода - традиционно самые медленные.
В этом-то и проблема.
Тут вряд ли даже двойная буферизация спасёт.
Вообще, мерцание возникает из-за низкой скорости вывода, т.к. просто не успевает с такой скоростью отрисовываться и стираться. Работа напрямую с буфером от этого спасает, т.к. отрисовываются и стираются только нужные части.
0
hoggy
Нарушитель
Эксперт С++
7084 / 3128 / 647
Регистрация: 15.11.2014
Сообщений: 7,193
Завершенные тесты: 1
02.01.2017, 15:11 10
Цитата Сообщение от GbaLog- Посмотреть сообщение
Тут вряд ли даже двойная буферизация спасёт.
нет, не вряд ли.
я ж сказал, что делал уже в консольке.
можно делать очень плавную анимацию,
при возможности колоссальной скорости отрисовки.

Цитата Сообщение от GbaLog- Посмотреть сообщение
Работа напрямую с буфером от этого спасает, т.к. отрисовываются и стираются только нужные части.
нет, не спасет.
даже если вы будите напрямки писать в активный буфер, средствами апи
мерцания вы не избежите.
это может быть не заметно при перемещении одной буковки.
но если там ещё расчеты делать, и допустим проанимировать человечка в акси-арт,
будет мерцать.
только двойная буферизация.
двойная буферизация позволяет мгновенно перерисовать весь буфер.
1
GbaLog-
Любитель чаепитий
3165 / 1471 / 465
Регистрация: 24.08.2014
Сообщений: 5,204
Записей в блоге: 1
Завершенные тесты: 2
02.01.2017, 15:17 11
Цитата Сообщение от hoggy Посмотреть сообщение
только двойная буферизация.
В этом случае ещё может помочь паттерн "game loop", т.к. перерисовки будут зависеть не от скорости процессора.
Перерисовок будет меньше, и, соответственно, мерцание будет меньше, если вообще будет.
0
hoggy
Нарушитель
Эксперт С++
7084 / 3128 / 647
Регистрация: 15.11.2014
Сообщений: 7,193
Завершенные тесты: 1
02.01.2017, 15:25 12
Цитата Сообщение от GbaLog- Посмотреть сообщение
Перерисовок будет меньше
щас уже не помню, нужно как минимум 33 кадра в секунду что ли перерисовывать.
иначе глаз заметит лаги))
0
GbaLog-
Любитель чаепитий
3165 / 1471 / 465
Регистрация: 24.08.2014
Сообщений: 5,204
Записей в блоге: 1
Завершенные тесты: 2
02.01.2017, 15:43 13
Цитата Сообщение от hoggy Посмотреть сообщение
щас уже не помню, нужно как минимум 33 кадра в секунду что ли перерисовывать.
иначе глаз заметит лаги))
Вообще 24 кадра в фильмах используют. Вроде не видно лагов.
А вот в играх хуже. К примеру, мой глаз видит лаги уже при 40 кадрах, ибо глаз привык к 60+ фпс, но нормальных драйверов на мою видеокарту не нашлось для 7-ки(слишком старая уже), поэтому приходится играть <60 фпс, либо вообще не играть.
0
hoggy
Нарушитель
Эксперт С++
7084 / 3128 / 647
Регистрация: 15.11.2014
Сообщений: 7,193
Завершенные тесты: 1
02.01.2017, 15:52 14
Цитата Сообщение от GbaLog- Посмотреть сообщение
ибо глаз привык к 60+ фпс
ну значит 60+.
0
Leak
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7
03.01.2017, 01:37  [ТС] 15
Собственно, как можно реализовать двойную буферизацию в консольном приложении?

Добавлено через 7 часов 28 минут
Добавил выход(Он то был, но не функционировал.), добавил двери и ключи ($ - дверь, * - ключ).Что бы открыть дверь нужно подобрать ключ, после открытия двери он исчезает. Мерцание так и не устранил. Осознал что надо было писать тему в "cpp-beginners".
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
#include <iostream>
#include <windows.h>
#include <iomanip>
#include <conio.h>
 
using namespace std;
 
char mapa[20][25] ={{176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,},
                   {176,'#',176,176,' ',' ',' ',' ',' ',' ',' ',176,176,' ','$',' ',' ',' ',' ',' ',' ',' ',' ',' ',176,},
                   {176,' ',176,176,' ',176,176,176,176,176,' ',' ',' ',' ',176,176,176,176,176,176,176,176,176,' ',176,},
                   {176,' ',176,' ',' ',176,' ',176,' ',' ',' ',176,176,' ',' ',' ',' ',176,' ',' ',' ',176,' ',' ',176,},
                   {176,' ',176,' ',176,176,' ',176,176,176,176,176,176,176,176,176,' ',176,' ',176,'*',176,' ',176,176,},
                   {176,' ',176,'$',176,176,' ',' ',' ',' ',' ',' ',' ',' ',' ',176,' ',176,' ',176,176,176,' ',176,176,},
                   {176,' ',' ',' ',176,176,176,176,176,176,176,176,' ',176,' ',176,' ',176,' ',' ',' ',176,' ',176,176,},
                   {176,176,176,' ',' ',' ',176,176,' ',176,176,' ',' ',176,' ',176,' ',176,176,176,' ',176,' ',' ',176,},
                   {176,176,' ',' ',176,' ',' ',' ',' ',176,176,' ',176,176,' ',176,' ',' ',176,176,' ',176,176,' ',176,},
                   {176,176,' ',176,176,176,176,' ',176,176,176,' ',176,176,' ',176,176,' ',176,176,' ',176,176,' ',176,},
                   {176,' ',' ',176,' ',176,176,' ',176,' ',' ',' ',176,176,' ',176,' ',' ',' ',176,' ',176,176,' ',176,},
                   {176,' ',176,176,' ',176,176,' ',176,176,176,176,176,176,' ',176,' ',176,' ',176,' ',' ',176,' ',176,},
                   {176,' ',' ',' ',' ',176,176,' ',' ',' ',' ',' ',176,' ',' ',176,' ',176,' ',176,176,' ',176,' ',176,},
                   {176,176,176,' ',176,176,176,' ',176,176,176,' ',176,' ',176,176,176,176,' ',' ',' ',' ',176,' ',176,},
                   {176,' ',176,' ',176,176,176,' ',176,' ',176,' ',176,' ',176,' ',' ',176,176,176,176,176,176,' ',176,},
                   {176,' ',176,' ',176,' ',' ',' ',176,' ',176,' ',176,' ',176,176,' ',176,176,' ',' ',' ',176,' ',176,},
                   {176,' ',176,' ',176,' ',176,176,176,' ',176,' ',176,' ',176,176,' ',176,'*',' ',176,' ',176,' ',176,},
                   {176,' ',' ',' ',' ',' ',176,' ',176,' ',176,' ',176,' ',176,176,' ',176,176,176,176,' ',176,' ',176,},
                   {176,176,176,176,176,176,176,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',176,' ',' ',},
                   {176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,}};
int n = 1, m = 1, o, b, j = 5, d = 1;
bool g = 0;
char wasd;
 
void maps(){
for (int i = 0; i < 20; i++)
    {
           for (int j = 0; j < 25; j++)
           cout << mapa[i][j];
        cout << endl;
    }
 
}
bool win(){
if(n==18&&m==24){
return 1;
}
else {return 0;}
}
 
 
 
void player()
{
wasd = getch();
switch (wasd)
     {
         case 'w': if(mapa[n-1][m]==' ') { mapa[n][m] = ' '; n--; }
              else if(mapa[n-1][m]=='%'&&mapa[n-2][m]==' '){mapa[n][m] = ' '; n--; mapa[n-1][m]='%'; }
              else if(mapa[n-1][m]=='$'&&g==true){mapa[n][m] = ' '; n--; g=0; }
              else if(mapa[n-1][m]=='*'){mapa[n][m] = ' '; n--; g = true; }  break;
         case 'a': if(mapa[n][m-1]==' ') { mapa[n][m] = ' '; m--; }
              else if(mapa[n][m-1]=='%'&&mapa[n][m-2]==' '){mapa[n][m] = ' '; m--; mapa[n][m-1]='%'; }
              else if(mapa[n][m-1]=='$'&&g==true){mapa[n][m] = ' '; m--; g=0; }
              else if(mapa[n][m-1]=='*'){mapa[n][m] = ' '; m--; g = true; } break;
         case 's': if(mapa[n+1][m]==' ') { mapa[n][m] = ' '; n++; }
              else if(mapa[n+1][m]=='%'&&mapa[n+2][m]==' '){mapa[n][m] = ' '; n++; mapa[n+1][m]='%'; }
              else if(mapa[n+1][m]=='$'&&g==true){mapa[n][m] = ' '; n++; g=0;}
              else if(mapa[n+1][m]=='*'){mapa[n][m] = ' '; n++; g = true; } break;
         case 'd': if(mapa[n][m+1]==' ') { mapa[n][m] = ' '; m++; }
              else if(mapa[n][m+1]=='%'&&mapa[n][m+2]==' '){mapa[n][m] = ' '; m++; mapa[n][m+1]='%'; }
              else if(mapa[n][m+1]=='$'&&g==true){mapa[n][m] = ' '; m++; g=0; }
              else if(mapa[n][m+1]=='*'){mapa[n][m] = ' '; m++; g = true; } break;
         case 't': if(mapa[n-1][m]==' ') { o = n - 1; b = m; mapa[o][b] = '%'; } break;
         case 'f': if(mapa[n][m-1]==' ') { o = n; b = m - 1; mapa[o][b] = '%'; } break;
         case 'g': if(mapa[n+1][m]==' ') { o = n + 1; b = m; mapa[o][b] = '%'; } break;
         case 'h': if(mapa[n][m+1]==' ') { o = n; b = m + 1; mapa[o][b] = '%'; } break;
}
mapa[n][m] = '#';
}
int main()
{
 while(win()==0)
 {
 maps();
 player();
 win();
 system("cls");
 
 }
 system("PAUSE");
 return 0;
}
Кстати, отключил лишние библиотеки.
0
rao
894 / 415 / 158
Регистрация: 02.04.2014
Сообщений: 1,201
03.01.2017, 12:18 16
Ребята, всё это конечно хорошо, дискуссия получилась интересной и познавательной, но вам не кажется, что двойная буферизация для консольной игрушки, которую пишет начинающий это немножко перебор? Анимация псевдографики "дискретна" по своей природе, и "плавности" всё равно не будет (т.е. полюбому символы будут двигаться скачками). Для устранения мерцания просто не надо перерисовывать весь экран. Нужно избавиться от цикличного вызова ф-ции maps() заменив его чем нибудь вроде этого:
C++
1
2
3
4
5
6
7
8
void RefresScreenMap(int iPosY, int iPosX, char cSymbol)
{
    HANDLE hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD ptPos = {iPosX, iPosY};
    SetConsoleCursorPosition(hConOut, ptPos );
    DWORD dwWritten = 0;
    WriteConsole(hConOut, &cSymbol, 1, &dwWritten, NULL);
}
(т.е. перерисовкой одного символа, который изменился)

Функцию player() тоже можно упростить сведя все повторяющиеся однотипные проверки в одно место. Если Написать универсальную процедуру:
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
void TryToMove(int iOffsetX, int iOffsetY)
{
    if (mapa[n + iOffsetY][m + iOffsetX] == ' ') 
    { 
        RefresScreenMap(n, m, ' ');
        m += iOffsetX; 
        n += iOffsetY; 
    }
    else if ( mapa[n + iOffsetY][m + iOffsetX] == '%' && mapa[n + 2*(iOffsetY)][m + 2*(iOffsetX)] == ' ') 
    {
        RefresScreenMap(n, m, ' ');
        n += iOffsetY;
        m += iOffsetX;
        mapa[n+ iOffsetY][m + iOffsetX] = '%'; 
    }
    else if ( mapa[n+ iOffsetY][m + iOffsetX] =='$' && g == true)
    {
        RefresScreenMap(n, m, ' ');
        n += iOffsetY;
        m += iOffsetX;
        g = 0; 
    } else if (mapa[n+ iOffsetY][m + iOffsetX] == '*')
    {
        mapa[n][m] = ' '; 
        RefresScreenMap(n, m, ' ');
        n += iOffsetY; 
        m += iOffsetX;
        g = true; 
    }  
}
то получим легко читаемый код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void player()
{
    wasd = getch();
    switch (wasd)
    {
        case 'w': TryToMove(0, -1); break;
        case 'a': TryToMove(-1, 0); break;
        case 's': TryToMove(0, +1 ); break;
        case 'd': TryToMove(+1, 0 ); break;
...
    }
    // mapa[n][m] = '#';
    RefresScreenMap(n, m, '#');
}
ну и главный цикл тоже чуть-чуть изменится:
C++
1
2
3
4
5
6
7
8
    maps();
    while(win()==0)
    {
        // maps();
        player();
        win();
        // system("cls");
    }
Пробовал. Не мерцает.
0
GbaLog-
03.01.2017, 12:52
  #17

Не по теме:

Цитата Сообщение от rao Посмотреть сообщение
вам не кажется, что двойная буферизация для консольной игрушки, которую пишет начинающий это немножко перебор?
Нет. Это не так сложно, на самом деле.

0
hoggy
Нарушитель
Эксперт С++
7084 / 3128 / 647
Регистрация: 15.11.2014
Сообщений: 7,193
Завершенные тесты: 1
04.01.2017, 09:51 18
Цитата Сообщение от rao Посмотреть сообщение
вам не кажется, что двойная буферизация для консольной игрушки, которую пишет начинающий это немножко перебор?
нет, не кажется.

Цитата Сообщение от rao Посмотреть сообщение
Анимация псевдографики "дискретна" по своей природе, и "плавности" всё равно не будет
ничего подобного.
зависит от самой псевдографики.
в интернетах можно нарыть качественную анимацию
человечков например.

https://youtu.be/3wYz3zVnkIA

Цитата Сообщение от rao Посмотреть сообщение
Для устранения мерцания просто не надо перерисовывать весь экран
ещё один.
шняга это все.
1
rao
894 / 415 / 158
Регистрация: 02.04.2014
Сообщений: 1,201
04.01.2017, 11:25 19
hoggy, клёвая видяшка экран наверное символов в триста шириной.. при таком разрешении конечно есть где разгуляться.

Цитата Сообщение от hoggy Посмотреть сообщение
зависит от самой псевдографики
Вот про что я и пишу! Оптимизация - это не всегда стремление к максимальной производительности. Должна быть "золотая середина" затрат и эффективности. В данном конкретном случае, двойная буферизация просто не требуется (что было подтверждено моим кодом), поэтому все усилия не приносящие ощутимого результата будут не рациональны и не целесообразны (т.е. не оптимальны). Не нужно стрелять из пушки по воробьям. В текстовом режиме хоть десятирную буферизацию заведи, а символ "#" в соседнюю клеточку все-равно будет перескакивать, а не плавно перетекать.

Впрочем, я не спорю. ..всё это дело вкуса и личных убеждений. Все правы
0
Leak
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7
07.01.2017, 16:04  [ТС] 20
Цитата Сообщение от rao Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
void RefresScreenMap(int iPosY, int iPosX, char cSymbol)
{
   HANDLE hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
   COORD ptPos = {iPosX, iPosY};
   SetConsoleCursorPosition(hConOut, ptPos );
   DWORD dwWritten = 0;
   WriteConsole(hConOut, &cSymbol, 1, &dwWritten, NULL);
}
Понял всё кроме этой функции Пожалуйста, можете объяснить?
0
07.01.2017, 16:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.01.2017, 16:04

Оптимизация
Здравствуйте! Решаю задачи на e-olymp. Подскажите, пожалуйста, как ускорить...

оптимизация
какие 5 способов оптимизации?

Оптимизация
Как-нибудь можно уменьшить размер кода, т.е. сократить количество строк данного...


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

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

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