1. C++ / Говнокод #26962

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    97. 97
    98. 98
    #include <iostream>
    #include <ctime>
    #include <cstdlib>
    #include <conio.h>
    const int x_size(20), y_size(10); int x_pos(x_size/2+1); int y_pos(y_size/2+1);
    enum border_types{lineNL, single, singleNL};
    enum directions{UpLeft=1, UpRight, DownLeft, DownRight}dir;
    void draw_border(enum border_types borders) {
    	do{
    		if(borders == single || borders == singleNL) break;
    		for(int i=0; i<x_size+1; i++)
    	  	  putchar('#');
    	}while(false);
    	putchar('#');
    	if(borders == singleNL || borders == lineNL) std::cout << '\n';}
    void display_update() {
    	system("cls");
    	draw_border(lineNL);
    	for(int i=1; i<=y_size; i++)
    	{
    		draw_border(single);
    		for(int j=1; j<=x_size; j++)
    		{
    			if(j == x_pos && i == y_pos)
    			{
    				putchar('x');
    				continue;
    			}
    			putchar(32);
    		}
    		draw_border(singleNL);;
    	}
    	draw_border(lineNL);
    	std::cout << "X: " << x_pos << "\tY: " << y_pos;}
    void logic() {
    	switch(x_pos)
    	{
    		case 1:
    			if(dir == UpLeft) dir = UpRight;
    			if(dir == DownLeft) dir = DownRight;
    			break;
    		case x_size:
    			if(dir == UpRight) dir = UpLeft;
    			if(dir == DownRight) dir = DownLeft;
    	}
    	switch(y_pos)
    	{
    		case 1:
    			if(dir == UpLeft) dir = DownLeft;
    			if(dir == UpRight) dir = DownRight;
    			break;
    		case y_size:
    			if(dir == DownLeft) dir = UpLeft;
    			if(dir == DownRight) dir = UpRight;
    	}}
    void move() {
    	switch(dir)
    	{
    		case UpLeft:
    			x_pos--;
    			y_pos--;
    			break;
    		case UpRight:
    			x_pos++;
    			y_pos--;
    			break;
    		case DownLeft:
    			x_pos--;
    			y_pos++;
    			break;
    		case DownRight:
    			x_pos++;
    			y_pos++;
    	}}
    int main() {
    	srand(time(0));
    	rand();
    	switch(rand()%4+1)
    	{
    		case UpLeft:
    			dir = UpLeft;
    			break;
    		case UpRight:
    			dir = UpRight;
    			break;
    		case DownLeft:
    			dir = DownLeft;
    			break;
    		case DownRight:
    			dir = DownRight;
    	}
    	while(!kbhit())
    	{
    		display_update();
    		logic();
    		move();
    	}
    	return 0;}

    Сорян, пришлось уплотнить фигурные скобки, чтобы код уместился в 100 строк.

    Запостил: BelCodeMonkey, 18 Сентября 2020

    Комментарии (66) RSS

    • > }}
      > return 0;}

      Какая экономия )))
      Ответить
    • > system("cls");

      Ну раз уж на венду завязался, поюзай виндовые апишки. Там и очистка экрана и перемещение курсора есть и цвета. Всё лучше, чем процесс поднимать на каждый фрейм.
      Ответить
      • Но для линуха можно будет заменить всего одну строчку с «cls» и будут кросплатформенные исходники! Так что это кроссплатформенный код )))
        Ответить
        • clear, да)

          но лучше конечно сделать это через ConsoleApi на винде и через ncruses напрямую на Linux: последнее будет совместимо с любым униксом

          Правда я вот не уверен про переносимость
          <conio.h> азаза
          Ответить
          • На борланд си точно переносим.
            Ответить
            • тоже про это подумал) conio же)
              а в досе был cls?
              Ответить
              • Да вроде оттуда этот cls и пошел.

                З.Ы. Но в старом конио и clrscr() был. Просрали все полимеры.
                Ответить
                • а, ну тогда ок. В винде так-то все или из доса или из VMS
                  а туда он из CP/M небось?

                  Кстати, почему в паскале conio назывался crt?
                  Ответить
              • Да. И в досе, в qбейсике.
                Ответить
                • Ну кстати на бейсике я такую прогу строчек в 10 писал. Вот языки раньше были!
                  Ответить
          • Вот кстати, почему ncurses винду не умеет? Куча проблем бы ушла с кроссплатформенной соснолью.
            Ответить
            • а почему винда не умеет esc последовательности и termcap/terminfo? (причем дос умел, ansi.sys же)
              а почему она не умеет сигналы? а почему winsock отличается в некоторых местах от berkely sockets?

              на то и щука, чтоб карась не скучал
              Ответить
              • > почему

                Потому что винду создали анскильные менеджеры для ещё более анскильных юзверей, а линукс — программисты для чуть более продвинутых юзеров и других программистов
                Ответить
                • Вообще Мелкомягкие хотели сделать то ли DOS, то ли Винду на основе UNIX. Но им помешал тогда еще большой брат IBM, для компьютеров которых и делали ось. Помешал потому, что UNIX была осью конкурентов.
                  Ответить
                  • хым

                    DOS был уже куплен -- его никто не делал изначально, а сделан он был на основе cp/m (ну в стилистике её во всяк случае).

                    Windows NT делалось под сильным влияниекм VMS (Дейв Калтер бывший VMSовец).

                    С IBM они делали OS/2, но та была просрана (потому что IBM всё просирает).
                    А Unix, кмк, в ту пору на фоне unix wars не выглядел привлекательно, и не пах деньгами (В отличие от VMS) отсюда и вот.
                    Ответить
                    • У NT и OS/2 было сильное влияние друг на друга. Вроде альфа-версия NT изначально даже называлась типа «OS/2 NT», т. е. новая технология для OS/2.

                      Про «Unix»: мелкомягкие делали платный юниксоподобный «Xenix» (ты даже где-то писал, что в нём не было виртуальной памяти, что с позиции нашего времени звучит как очередная порнуха на порнхабе).
                      Ответить
            • Наверное потому, что нужна TTY, которой в винде нету.
              Ответить
              • Деталь реализации. У курсесов один хрен есть внутренний буфер, через который они оптимизацию вывода в терминал делают. Высрать этот же буфер в виндовую консоль через виндовое апи никаких проблем не будет.
                Ответить
                • Думаешь управляющие коды консолей совместимы?
                  Ответить
                  • А зачем тебе управляющие коды? В этом буфере по сути буковки да цвета, а коды уже юзаются чтобы все это в терминал вкачать.

                    В винде ты просто отдашь этот буфер в винапишную функцию и она его нарисует.
                    Ответить
                    • > В винде ты просто отдашь этот буфер в винапишную функцию и она его нарисует.
                      Кстати, с десятки винда поддерживает стандартные ANSI коды, так что теперь можно даже винапишными функциями не заморачиваться.
                      Ответить
                      • > десятки

                        А как же Сёма?
                        Ответить
                        • А Сёме придётся обходиться консолью из линолеума.
                          Ответить
                          • Ну причем там десятка еще не какая попало, на старых LTS'ках поди еще и не взлетит.
                            Ответить
                            • Да, там какие-то затруднения есть, кажется. То ли только в новых версиях работает, то ли компонент какой-то включать надо, не помню. Но лично у меня всё работает искаропки.
                              Ответить
                              • > искаропки

                                Обновись, перестанет.

                                Они вроде в какой-то версии изкоробки включили. А потом задумались над совместимостью и теперь надо явно звать апишку для включения.

                                Не то чтобы ее сложно было позвать. Один фиг надо тест на терминал делать, даже в прыщах.
                                Ответить
                                • > Обновись, перестанет.
                                  И тут мы возвращаемся к тому, о чём я уже говорил…

                                  > над совместимостью
                                  А что там с совместимостью? Кто-то случайно введёт «\x1b[30;1m» и получит багор?
                                  Ответить
                        • показать все, что скрытоvanished
                          Ответить
                      • >Кстати, с десятки винда поддерживает стандартные ANSI коды,
                        в какой из восьми используемых версий?:)
                        Ответить
                    • > А зачем тебе управляющие коды?
                      Ну ncurses, как и любая Linux программа с цветным выводом и передает эти цвета уже буфер вместе с управляющими кодами в TTY.

                      В винде же, как я нагуглил, сначала переключают консоль в нужный цветовой режим, а потом выводят через printf\cout.
                      https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute
                      https://coderoad.ru/9262270/Цветной-консольный-вывод-с-C-в-Windows

                      То есть подходы совершенно разные. И в винде совершенно другие абстракции.

                      Можно, конечно, сделать функцию которая на основе этих управляющих кодов TTY будет переключать виндовую консоль в разные режимы и выводить, и будет совместимость ncurses с виндой.
                      Ответить
                      • > This function affects text written after the function call.
                        То есть тоже подставляет туда коды.
                        Странно, противоречит примерам со второй ссылки.
                        Хотя никакого буфера туда не надо передавать.
                        Значит меняется текст непосредственно абстракцией консоли.
                        Ответить
                      • В винде есть ВритеКонсолеАутпут() где ты просто передаешь массив символов и атрибутов.

                        Сука, зачем они названия функций то переводят...
                        Ответить
                        • WriteConsoleOutput treats the source buffer and the destination screen buffer as two-dimensional arrays (columns and rows of character cells).

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

                          Тогда в ncurses и отпадает нужда. Разве что только если нужна кроссплатформенность.
                          Ответить
                        • https://docs.microsoft.com/ru-ru/windows/console/coord-str

                          Структура курд


                          да
                          Вертикальная координата или значение строки. Единицы зависят от вызова функции.

                          филлконсолеаутпутаттрибуте
                          филлконсолеаутпутчарактер
                          жетконсолефонтсизе
                          жетларжестконсолевиндовсизе
                          Ответить
                          • Мне больше понравилась "структура маленького рект", у которой в участниках слева, топ, правильные и последние.

                            Только полный и качественный перевод.

                            З.Ы. Хотя вместо "слева" должны быть "оставленные" для полной аутентичности.
                            Ответить
                          • > филлконсолеаутпутаттрибуте
                            > филлконсолеаутпутчарактер
                            > жетконсолефонтсизе
                            > жетларжестконсолевиндовсизе

                            Если бы WinAPI писали на 1С.
                            Ответить
              • В винде действительно нет TTY, но она тут не причем. Обрабатывать ESC последовательности можно и без TTY. Никто же не ждет от винды понятия foreground/background, session leader, istty, итд..
                Ответить
                • > istty

                  Ну вот эту проверку таки стоит сэмулировать. А то получится как с некоторыми тулами от майкрософта, у которых stdout не редиректится (всё рисуется напрямую в сосноль).
                  Ответить
                  • почти уверен, что можно взять GetStdHandle для аутпута и проверить, что он не консоль
                    алсо, можно прверить, что к тебе приаттачена консоль вообще.
                    Ответить
                    • Вроде надо позвать GetConsoleMode(GetStdHandle(...)). И если оно вернёт ошибку для любого из них - значит все цвета и перемещения курсора идут лесом.

                      А на аттач плохо проверять, вдруг ты приаттачен, но один из потоков редиректнули?
                      Ответить
                      • я имею ввиду, что если у тебя не приаттачена консоль, то туда вообще не нужно писать

                        а сам факт приаттачености конечно ни о чем не говорит. Да, у тебя есть консоль, но ты в нее не пишешь.

                        Точно так же как в прыще у тебя есть tty, но твой аутпут редиректунт

                        вроде бы так
                        Ответить
                        • Ну так то ты можешь и создать себе консоль...
                          Ответить
                          • можешь. А в прыщах tty -- нет. Ахахаха
                            Ответить
                            • Ну да. Я конечно могу какой-нибудь xterm запустить, но это уже чит.
                              Ответить
                              • а как ты с ним свяжешься, кстати? нужно запустить в нем новый процесс, или можно тупо открыть псевдотерминал? кажется, что нет красивого способа.


                                Да и xtermа нет без иксов, где нить на севере. Из демона ты ничего не запустишь бо нет $DISPLAY
                                А на винде можешь создать консоль из сервиса, но так как сервис живет в своей сессии, то твою консоль никто не увидит кмк. но писать в нее ты можешь наверное
                                Ответить
                                • Ну самый простой способ - перезапустить себя через xterm, наверное.

                                  Или пойти и нагло открыть нужную сосноль в /dev. Это даже для сервиса прокатит. Но х.з. как выбрать нужную. Да и висящий в ней процесс как-то надо заткнуть.
                                  Ответить
                                  • Я не уверен, что можно открыть чужой tty и стать его владельцем, но писнуть туда ты точно можешь. А вот читнуть -- хз.

                                    И уж точно ты не станешь там сешн лидером или как там его, чтоб тебя уведомили о закрытии tty
                                    Ответить
                                    • Ну я проверил сейчас, открыл pts'ку - и пишется и читается. Причём новый процесс даже приоритетнее для чтения оказался, старый убивать не пришлось (но возможно это UB и рандом).

                                      > уведомили

                                      read и write ошибку возвращают, когда pts'ка удалена. Так что всё норм.
                                      Ответить
                                      • ккококококй багор)

                                        >read ошибку возвращает,
                                        а сигнал ты получаешь, когда tty закрывают?

                                        Кстати, я погуглив
                                        https://www.win.tue.nl/~aeb/linux/lk/lk-10.html

                                        Getting a controlling tty
                                        How does one get a controlling terminal? Nobody knows, this is a great mystery.

                                        The System V approach is that the first tty opened by the process becomes its controlling tty.

                                        The BSD approach is that one has to explicitly call
                                        ioctl(fd, TIOCSCTTY, ...);

                                        Linux tries to be compatible with both, as always, and this results in a very obscure complex of conditions.

                                        ну и дальше расписывается как

                                        прыщебляди соснули малость
                                        Ответить
                                        • Не, сигнала не заметил. Только обрыв пайпа.
                                          Ответить
                                          • ну то есть сешн лидером ты не стал, верно?
                                            тогда это всё таки не совсем твоя tty.

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

                                FAR например умеет ресайзить окошко например. А в никсах терминал может быть какой угодно (да хоть железный!) и как бы ты хотел его ресайзить?
                                Ответить
                                • Ну х.з., кинуть ему эскейп на ресайз. Что мешает некоторым терминалам иметь такую команду? Другие команды же тоже не везде реализованы.

                                  Ну с другой стороны для юзера такой ресайз почти бесполезен. Наоборот даже мешаться будет.
                                  Ответить
                                  • да, опсать такое капабилити в termcap/terminfo было бы круто.
                                    В конце концов статус лайн тоже не все умеют: виртуальный терминал на консоли же не умеет

                                    И так-то да, если мне путти начнет само ресайзица -- я охуею
                                    Ответить
          • показать все, что скрытоvanished
            Ответить
        • Оно не мерцает, кстати?

          А то может проще высрать пачку \n вместо очистки и не париться.
          Ответить

    Добавить комментарий