С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7

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

01.01.2017, 01:35. Показов 1224. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.01.2017, 01:35
Ответы с готовыми решениями:

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

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

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

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

Но еще лучше конечно же работать с буфером консоли. Тогда будет достаточно перерисовывать только изменившиеся символы, а не весь экран (что бы не было мерцания).
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
01.01.2017, 15:15
Цитата Сообщение от rao Посмотреть сообщение
каким образом "сишные потоки" ускорят прорисовку?
Ну всем давно известно, что сишные потоки быстрее цппшных, поэтому при отрисовке мерцания будут казаться чуть меньше, но это в целом можно даже не заметить, ибо это мерцание будет всё равно достаточно сильным, потому что вечный цикл с обновлением экрана это плохой подход.
Цитата Сообщение от rao Посмотреть сообщение
cout разве не идентификатор потока?
Что имеется ввиду под словом идентификатор?
Цитата Сообщение от rao Посмотреть сообщение
Сомневаюсь, что есть какие то "сторонние либы" работающие с буфером консоли
pdcurses(Win)/ncurses(*nix). Причём большинство никсовых псевдогуишных программ как раз на ncurses написаны, если вообще не все.
Цитата Сообщение от rao Посмотреть сообщение
потому что вся эта функциональность исчерпывающе реализована набором соответствующего API
Представляете, в мире существует такая ОС, как Linux, вернее это не совсем ОС, а дистрибутив, но не об этом речь, API у неё тоже есть, только вот самому разруливать отдельную компиляцию под виндовс и линукс вряд ли кто-то будет, если существует такая вещь, как (pd/n)curses, которая написана специально для этих нужд.
0
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7
01.01.2017, 18:22  [ТС]
Вот новая версия добавил "передвигаемые блоки", которые можно ставить на "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
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2017, 00:39
Цитата Сообщение от GbaLog- Посмотреть сообщение
Ну всем давно известно, что сишные потоки быстрее цппшных, поэтому при отрисовке мерцания будут казаться чуть меньше
шняга. во-первых не быстрее.
а во-вторых, что б не мерцало,
нужно пользовать двойную буферизацию.
это единственный способ достичь плавности.

ну и в третьих, как я понял,
тс не жаловалосо на мерцание.
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
02.01.2017, 10:34
Цитата Сообщение от hoggy Посмотреть сообщение
во-первых не быстрее
А как же это? https://habrahabr.ru/post/246257/
Ложь?
Цитата Сообщение от hoggy Посмотреть сообщение
во-вторых, что б не мерцало,
нужно пользовать двойную буферизацию.
это единственный способ достичь плавности.
Не понял, как это можно использовать в консоли.
Что это такое я знаю, а как в консоли юзать - нет.
Скорее всего, только через АПИ системы?
Цитата Сообщение от hoggy Посмотреть сообщение
ну и в третьих, как я понял,
тс не жаловалосо на мерцание.
Цитата Сообщение от Leak Посмотреть сообщение
уменьшить время прорисовки "лабиринта" после каждого хода.
Мне кажется, что это как раз для того, чтобы не мерцало.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2017, 14:37
Цитата Сообщение от GbaLog- Посмотреть сообщение
Ложь?
собственно, в этой статье и приводится мысль,
что медленность с++ потоков - миф.
всё зависит от того, как их правильно готовить.

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

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

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

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


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

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

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

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

Добавлено через 25 секунд
Цитата Сообщение от GbaLog- Посмотреть сообщение
Скорее всего, только через АПИ системы?
я делал когда то через апи
2
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
02.01.2017, 14:53
Цитата Сообщение от hoggy Посмотреть сообщение
это древний как мир паттерн.
Ну я же сказал, что знаю что это, зачем было объяснять?
Цитата Сообщение от hoggy Посмотреть сообщение
но фишка в том, что это все - экономия на спичках.
операции ввода/вывода - традиционно самые медленные.
В этом-то и проблема.
Тут вряд ли даже двойная буферизация спасёт.
Вообще, мерцание возникает из-за низкой скорости вывода, т.к. просто не успевает с такой скоростью отрисовываться и стираться. Работа напрямую с буфером от этого спасает, т.к. отрисовываются и стираются только нужные части.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2017, 15:11
Цитата Сообщение от GbaLog- Посмотреть сообщение
Тут вряд ли даже двойная буферизация спасёт.
нет, не вряд ли.
я ж сказал, что делал уже в консольке.
можно делать очень плавную анимацию,
при возможности колоссальной скорости отрисовки.

Цитата Сообщение от GbaLog- Посмотреть сообщение
Работа напрямую с буфером от этого спасает, т.к. отрисовываются и стираются только нужные части.
нет, не спасет.
даже если вы будите напрямки писать в активный буфер, средствами апи
мерцания вы не избежите.
это может быть не заметно при перемещении одной буковки.
но если там ещё расчеты делать, и допустим проанимировать человечка в акси-арт,
будет мерцать.
только двойная буферизация.
двойная буферизация позволяет мгновенно перерисовать весь буфер.
1
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
02.01.2017, 15:17
Цитата Сообщение от hoggy Посмотреть сообщение
только двойная буферизация.
В этом случае ещё может помочь паттерн "game loop", т.к. перерисовки будут зависеть не от скорости процессора.
Перерисовок будет меньше, и, соответственно, мерцание будет меньше, если вообще будет.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2017, 15:25
Цитата Сообщение от GbaLog- Посмотреть сообщение
Перерисовок будет меньше
щас уже не помню, нужно как минимум 33 кадра в секунду что ли перерисовывать.
иначе глаз заметит лаги))
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
02.01.2017, 15:43
Цитата Сообщение от hoggy Посмотреть сообщение
щас уже не помню, нужно как минимум 33 кадра в секунду что ли перерисовывать.
иначе глаз заметит лаги))
Вообще 24 кадра в фильмах используют. Вроде не видно лагов.
А вот в играх хуже. К примеру, мой глаз видит лаги уже при 40 кадрах, ибо глаз привык к 60+ фпс, но нормальных драйверов на мою видеокарту не нашлось для 7-ки(слишком старая уже), поэтому приходится играть <60 фпс, либо вообще не играть.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2017, 15:52
Цитата Сообщение от GbaLog- Посмотреть сообщение
ибо глаз привык к 60+ фпс
ну значит 60+.
0
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7
03.01.2017, 01:37  [ТС]
Собственно, как можно реализовать двойную буферизацию в консольном приложении?

Добавлено через 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
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
03.01.2017, 12:18
Ребята, всё это конечно хорошо, дискуссия получилась интересной и познавательной, но вам не кажется, что двойная буферизация для консольной игрушки, которую пишет начинающий это немножко перебор? Анимация псевдографики "дискретна" по своей природе, и "плавности" всё равно не будет (т.е. полюбому символы будут двигаться скачками). Для устранения мерцания просто не надо перерисовывать весь экран. Нужно избавиться от цикличного вызова ф-ции 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
03.01.2017, 12:52

Не по теме:

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

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.01.2017, 09:51
Цитата Сообщение от rao Посмотреть сообщение
вам не кажется, что двойная буферизация для консольной игрушки, которую пишет начинающий это немножко перебор?
нет, не кажется.

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

https://youtu.be/3wYz3zVnkIA

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

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

Впрочем, я не спорю. ..всё это дело вкуса и личных убеждений. Все правы
0
0 / 0 / 0
Регистрация: 01.01.2017
Сообщений: 7
07.01.2017, 16:04  [ТС]
Цитата Сообщение от 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.01.2017, 16:04
Помогаю со студенческими работами здесь

Усовершенствование кода декодера BIN > DEC
Здравствуйте! У меня есть проект, декодер из бинарной системы в десятичную. #include &lt;iostream&gt; #include &lt;stdlib.h&gt; ...

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

Типы оптимизация: черная оптимизация, серая оптимизация и белая оптимизация
Много много лет назад, на заре становления профессии &quot;оптимизатора&quot; в какой то умной книжке был создан миф. Это миф о цветовой индефикации...

Усовершенствование кода
Добрый вечер, хочу чтобы входные данные были (Введите значение функции: ) Но никак не получается в f(x) затолкать инпут, выручайте #...

Усовершенствование программы
Подскажите пожайлуста как к готовой программе не имея исходника добавить свой код. Для примера в программе открывается окно с кнопкой...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru