Еще ВНЕЗАПНЕЕ... И, насколько понимаю, собственно, ВОТ. Что сказать? Что начинать надо не с перечисления тех трех гаек, что завалялись в кармане, а с объяснения, почему автор не может игры не делать... Я, конечно, излишне ностальгирую по тем временам, когда игры не выходили за пределы двора (разве что, в мемуарах), но даже учитывая это. как-то неуютно жить в мире, где каждый чувствует себя вправе клянчить на улице копеечку за то, что он, в принципе, наверное, может сделать не хуже других, если, конечно вы ему сначала эту копеечку дадите... Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Сообщение отредактировал Gudleifr - Воскресенье, 27 Декабря 2015, 14:43
RigVix, дело в том, что большинство присутствующих идет по пути "такой же, но с перламутровыми пуговицами". Т.е. берется какой-то красивый проект и к нему прицепляется некая фича (обычно из другого проекта, но, иногда, и придуманная самостоятельно). Т.е. задача сводится к поиску "наибольшего общего делителя" - точки "неполной разборки" обоих проектов, на которой можно остановить копание в программировании и спокойно прицепить одно к другому. Желание же "чего-то большого" требует гораздо более глубокого погружения. Настолько глубокого, что не захочется выныривать. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
В таких случаях всегда хочется посоветовать одно. Создайте простенький сайт (не группу, не блог, не репозиторий и не тему на чужом форуме). Выложите там демо - cgi, gif, flash... Разбавьте текстами по и около темы... Глядишь, люди и потянутся. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Сообщение отредактировал Gudleifr - Суббота, 26 Декабря 2015, 13:58
Daeloce, оказывается, я был практически первопроходцем, т.к. использовал этот метод для построения платоновых тел в те самые 80-е... Однако, думаю, к теме эти вкусности отношения не имеют. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Для тех, кто на бронепоезе, поясню: 1. Решение задачи. Нужно выяснить в каком порядке (прямом, обратном, внутреннем) нужно перебирать дерево. 2. Программирование. Как для перебора применить рекурсивные ф-ии? В начале или конце рекурсивного шага осуществлять вывод? Каковы параметры могут потребоваться рекурсифной ф-ии? 3. Требования ОС. Если хочется по-виндосовски (Пуск-Проводник-Папки), нужно найти, какой класс вашего обезьянника инкапсулирует функционал класса WinAPI TreeVieW. Иначе (обычно) табуляция и псевдографика. Можно также с минимальными j-скриптами сделать красивое выпадающее дерево в HTML (вместо вывода на консоль). Так понятнее? Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Storm54, цитируйте аккуратнее, а то я чуть не просмотрел Ваше замечание.
Есть три Unix- и один Forth-способ написать свой язык. Насколько они трудны? Судите сами:
1. Если язык служит чисто служебной цели, как в примере выше, то его очень просто реализовать на любом языке. Развитием этого метода служат языки C++ и Python, но они ущербны. На C++ невозможно написать ничего кроме C++, а на Python написать что-то сложное просто проблемно.
2. Если язык достаточно прост, но требует развитых интерфейсов, то его можно реализовать просто средствами Unix-скриптования. shell, sed, awk... Например, можно написать Perl-обработчик команд и засунуть его в Tcl/Tk-оболочку. Так можно лепить достаточно сложные продукты:
Подробнее см. там. Я там предлагаю даже более простой набор (Perl+HTML).
3. Если язык сложен, но Unix предлагает спарку lex + yacc и их последлвателей. Компиляторы компиляторов. На входе - грамматика, на выходе - готовый компилятор. Минус, как в C++ - требование полноценной НИОКР по проходу "сверху вниз", как однажды написанную сложную иерархию классов фиг подправишь, так и грамматику "чуть-чуть" не улучшишь.
4. Наконец, FORTH. Ядро языка пригодное для развертывания вашего языка пишется на коленке за две недели. Затем вы строите свои лексиконы строго по вашему решению задачи, перекладывая свои мысли в программу один-в-один. Минусы? FORTH-программы пишутся очень быстро и очень компактны, но это касается только исходных текстов. Готовые программы не такие уж и быстрые и маленькие.
Есть ли альтернативы написанию своего языка? Я, разумеется, имею в виду случай большой программы (для маленькой ничего изобретать особо и не надо).
Большой кусок, возможно войдет в "заметки", неоконченный
Возможно, настоящие писатели могут писать свои романы в свободной форме - все более углубляя и расширяя произведение - и не имеют проблем с добавлением новых поворотов сюжета или свежих идей туда, куда надо. Возможно даже, есть программисты, способные так же писать программы - постепенно добавляя все новые и новые возможности, и без труда преодолевают тот рубеж, на котором мои программы если и не перестают работать, то начинают терять в фунциональности после каждого исправления ошибок, вызванных очередным "улучшением". Однако, я не видел ни таких программистов, ни таких программ. Если угодно, эту проблему описал Дейкстра еще в 70-е годы XX века. А Брукс сделал популярной ее формулировку: "Серебряной пули не существует".
Какие же способы, кроме очевидного "взять и написать то, что надо", существуют?
Видимо, есть два "философских" способа. Первый - рассматривать большую программу как машину, собранную из других машин, связанных простыми интерфейсаи (см. "Заметки о структурном программировании" Дейкстры). Вопрос модификации программы т.о. решается как замена одной из машин на другую с тем же интерфейсом Второй - изобретение языка, на котором решение задачи можно описать достаточно просто. Пограмма в этом случае тредставляется как набор переводчиков с языка на язык.
Т.к. между понятиями "машина" и "язык" в программировании существует взаимооднозначное соответствие, то выбор "философии" определяется, скорее тем, с чем мы имем дело - с компилятором или с интерпретатором.
Каковы практические решения, порожденные нашей философией? И, самое главное, какие подводные камни нас ожидают?
1. "Плюем и копипастим". Очевидно, что чем "последовательнее" куски кода, тем длиннее они могут быть. Но где найти столь выразительный язык, чтобы на нем можно было бы писать без "петель"? На помощь приходят Операционные Системы. Они разрешают пользователю писать только отдельные главы "Что произойдет, когда пользователь нажмет на кнопку?", "Что надо не забыть при размещении окна на экране?",.. А связь между главами берут полностью на себя. В такой умной среде даже достаточно сложно привязанную к сюжету "главу" можно просто приписать в конец программы. Минус подхода, разумеется, в том, что здесь не писатель управляет сюжетом, а сюжет - писателем. Мы постоянно видим вокруг программы, напрягающими пользователя заполнением ненужных ему форм, требуя от него ненужных подтверждений очевидного, навязывая ненужные ритуалы.
2. "Структутное программирование". В своей книге "Дисциплина программирования" Дейкстра ввел аксиоматику соединения программных глав в единое произведение. Два важнейших способа - операторы выбора и цикла. Со временем аксиоматика забылась и программисты уверовали, что цикл может гарантировать им чуть ли не кибернетическую ультраустойчивость, а выбор обеспечит возможность учеть "все". Эти два оператора ответственны за увеличение мусора в программах на один, а то и два, порядка. Чтобы это оценить нуджно вспомнить аксиоматику. Она проста (если не вникать в математику): основное качество цикла не способность вовремя остановиться, а способность сохранять т.н. "инвариант цикла", что позволяет ему не пойти вразнос; с выбором все очевиднее - этот оператор должен учитывать все варианты не в смысле "все что придет в голову", а в смысле "честной мат.логики" - всех возможных наборов значений переменых, входящих в условие выбора. Как это работает?
Обычная ошибка применения циклов - "матрешка". Циклы вкладываются один в другой не "по логике", а "по сюжету". Кроме потерь на лишние переборы, порожденые именением одной-двух переменных состояния, приходится слишком долго проверять, не был ли поврежден "инвариант". А, если программист сам плохо понимает, какой инвариант к какому циклу относится, число проверок/восстановлений растет в геометрической прогрессии.
Аналогичная ошибка в использовании оператора выбора является "елочка". Вместо последовательной обработки отдельных переменных состояния, при неудачном распределении последних, получается громоздкое дерево. Для всех вариантов значения первой переменной, проверяются все значения второй, для каждого значения второй - все значения третьей... В сложных елочках часто происходит более одной проверки одного одного условия, т.к. понять была ли ранее сделана та или другая проверка достаточно сложно, особенно после внесения пары-другой исправлений.
Как избежать матрешки и елочки? Нужно стараться отделить логику управления от других вычислений программы. А затем - попытаться ее упростить по правилам обычной математики.
Несмотря на трудность правильного применения структурного програмирования, оно позволяет писать очень красивые (и доказуемо правильные) программы.
3. "Масштабирование". С ростом популярности языка C термин "структурное программирование" стал использоваться в другом значении - как программирование путем бесконечной группировки структур (кода и данных) в более крупные структуры. Появилось так же и его доведение до абсурда - "объектно-ориентированное програмирование" - создание неких универсальных структур (объединяющих - "инкапсулирующих" - в себе и код, и данные вместе).
Для увеличения сложности таким путем, очевидно, характерен "синдром чайника" - когда "вылить уже налитую воду" проще, чем переписать процедуру "кипячения".
Другой источник мусора при таком подходе - избыточность предохранительных процедур, которые "для универсальности и безопасности" вставляют во все процедуры, где неправильные данные могут вызвать ошибки. Такой подход не только приводит к жуткой избыточности ненужных проверок, но и служит источником ошибок - необнаружению критических сбоев.
ЦитатаStorm54 ()
У Вас есть опыт коммерческой разработки или хотя бы опыт работы в команде?
Уже отечал: да и да. Но, кстати, раз уж вспомнил Дейкстру:
Цитата
Наконец, эта задача позволяет нам рассеять некоторые сомнения, вызванные тем, что коммерческие программы являются чем-то особенным. (Если уж говорить о чем-то особом, то, скорее, о характере коммерческих программистов...)
Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Сообщение отредактировал Gudleifr - Среда, 23 Декабря 2015, 19:08
Я обычно использую не ООП, а метод проблемно-ориентированного языка. Т.е. не строю иерархию объектов, а изобретаю язык, на котором задача описывается естественно, а затем его реализую. Например, простенькая библиотека переупаковки байтовых полей выглядит у меня так:
Код
#include "all.h"
/* Описание формата: <формат> ::= <массив> | <формат> [ "." ] <массив> ; -- следующие в памяти друг за другом фрагменты -- точка только для читабельности <массив> ::= <блок> | "(" <формат> ")" <блок> ] ; -- повторяющиеся фрагменты <блок> ::= [ <счетчик> ] [ <направление> ] ; -- простые блоки <счетчик> ::= NUM | "N" ; -- NUM байт (или повторов предыдущего блока), -- N - "до конца строки" (по умолчанию) <направление> ::= "D" | "B" -- в прямом (D, по умолчанию) или обратном (B) порядке Порядок: "естественным" порядком считается порядок, при котором самый правый бит - самый значащий (внутри байтов он поддерживается автоматически, при хранении байтов в памяти в виде строки или слова - обратный, т.е. естественным считается "B" (он же "NB")); Ограничения: В случае если лень ставить D, нужно поставить точку между <массивами>; NUM - неотрицательное десятичное число. Расширения: В любом месте можно поставить имя в кавычках (апострофах). */
static BYTE get_lex(i) /* лексический анализатор */ STRING *i; { num = 0; if (lexlit[**i] == 8) { /* имя в кавычках */ str = ++(*i); while (lexlit[*(*i)++] != 8); num = *i - str - 1; return 8; } if (lexlit[**i] != 9) return lexlit[*(*i)++]; while (lexlit[**i] == 9) /* число */ num = num * 10 + *(*i)++ - '0'; return 9; }
STRUCT(block) { /* узел дерева */ TREE(block) STRING name; /* указатель на имя, хранящееся в формате */ int ns; /* длина имени */ int thr; /* # текущего прохода */ int n, d; /* число подблоков, направление */ int s; /* сумма длин подблоков */ int is; /* сам или входит в блок с выбранным именем */ int s_nm; /* сумма длин подблоков нужного имени */ };
DEL0(block) /* деструктор узла */ TFREE(block) /* деструктор дерева */
static add_block(cur) /* добавить младшего сына */ pblock *cur; { pblock t; t = (*cur)->child; if (!t) { MALLOC(t, block) (*cur)->child = t; } else { while (!t->next) t = t->next; MALLOC(t->next, block) t = t->next; } t->dad = *cur; *cur = t; }
static get_sum(cur, nm, ns, is) /* расчет длины подблоков */ STRING nm; /* с учетом имени */ pblock cur; { pblock t; if (!is && nm && cur->name && cur->ns == ns && !strncmp(nm, cur->name, cur->ns)) is =1; cur->is = is; if (t = cur->child) while (t) { cur->s += get_sum(t, nm, ns, is) * t->n; cur->s_nm += t->s_nm * t->n; t = t->next; } else { cur->s = 1; if (is) cur->s_nm = 1; } return cur->s; }
static test_tree(cur, t) /* тестовая выдача дерева блоков */ pblock cur; { pblock c; int i; for (i = 0; i < t; i++) printf("\t"); printf("n=%d d=%d s=%d is=%d s_nm=%d", cur->n, cur->d, cur->s, cur->is, cur->s_nm); if (cur->name) { char *s; NALLOC(s, cur->name, cur->ns) printf("\t\"%s\"", s); } printf("\n"); if (c = cur->child) test_tree(c, t + 1); if (c = cur->next) test_tree(c, t); }
static build(o, cur, n, p, l) /* генерация таблиы перестановок */ pblock cur; /* n - куда, p - откуда */ int *o; { pblock t; int i; if (!cur->n) /* блок до конца строки */ cur->n = (l - p) / cur->s; for (i = 0; i < cur->n; i++) /* повтор подблоков */ if (t = cur->child) /* подблоки */ build(o, t, n + i * cur->s, cur->d ? p + (cur->n - i - 1) * cur->s : p + i * cur->s, /* учет порядка */ p + (i + 1) * cur->s); else /* байты */ o[n + i] = cur->d ? p + cur->n - i - 1 : p + i; n += cur->s * cur->n; if (t = cur->next) n = build(o, t, n, p + cur->s * cur->n, l); return n; }
static build_nm(o, cur, n, p, l) /* генерация таблиы перестановок */ pblock cur; /* с учетом имени */ int *o; /* n - куда, p - откуда */ { pblock t; int i; if (!cur->n) /* блок до конца строки */ cur->n = (l - p) / cur->s; for (i = 0; i < cur->n; i++) /* повтор подблоков */ if (t = cur->child) /* подблоки */ build_nm(o, t, n + i * cur->s_nm, cur->d ? p + (cur->n - i - 1) * cur->s : p + i * cur->s, /* учет порядка */ p + (i + 1) * cur->s); else /* байты */ if (cur->is) o[n + i] = cur->d ? p + cur->n - i - 1 : p + i; n += cur->s_nm * cur->n; if (t = cur->next) n = build_nm(o, t, n, p + cur->s * cur->n, l); return n; }
static build_n(cur, p, l) /* пересчет полей с учетом имени и, */ pblock cur; /* возможно (l != 0), длины входа */ { pblock t; int i, n; n = 0; if (!cur->is) { if (t = cur->child) n = build_n(t, p, p + cur->s) * cur->n; } else n = 1; if (l && !cur->n) /* блок до конца строки */ n *= (l - p) / cur->s; else if (t = cur->next) n += build_n(t, p + cur->s_nm * cur->n, l); return n; }
static parser(root, f, l, nm, ns) /* генерация дерева блоков */ pblock root; BYTE *f; STRING nm; /* с учетом имени */ { int c; pblock cur; cur = root; while (c = get_lex(&f)) { /* взять лексему */ if (c == '.') /* принудительно следующий блок */ add_next(&cur); if (c == '(') { /* повторяющийся блок */ if (cur->n) /* следующий блок */ add_next(&cur); add_block(&cur); } else if (c == 9) { /* длина блока в подблоках */ if (cur->n) /* следующий блок */ add_next(&cur); cur->n = num; } else if (c == 8) { /* имя блока */ cur->name = str; cur->ns = num; } else if (c == 'N') { /* длина остается 0 */ if (cur->n) /* следующий блок */ add_next(&cur); } else if (c == 'B') /* обратный порядок в блоке */ cur->d = 1; /* 'D' - ничего не делает */ else if (c == ')') /* конец блока */ cur = cur->dad; } cur = root; while (cur) { /* рассчитать длину подблоков */ get_sum(cur, nm, ns, 0); cur = cur->next; } /* test_tree(root, 0); */ }
static int *make_o(f, l) /* создать табоицу перестановки f->"" */ STRING f; { int *o; pblock root; /* охватывающий блок */ ALLOC(o, int, l) /* выделить место под таблицу */ MALLOC(root, block); parser(root, f, l, NULL, 0); /* построение дерева блоков */ build(o, root, 0, 0, l); /* генерация таблицы */ freeblock(root, 1); /* удаление дерева */ return o; }
static int *make_o_nm(f, l, nm, lo) /* создать табоицу перестановки f->"" */ STRING f, nm; /* с учетом имени */ int *lo; { int *o; pblock root; /* охватывающий блок */ ALLOC(o, int, l) /* выделить место под таблицу */ MALLOC(root, block); parser(root, f, l, nm, strlen(nm)); /* построение дерева блоков */ *lo = build_nm(o, root, 0, 0, l); /* генерация таблицы */ freeblock(root, 1); /* удаление дерева */ return o; }
gswap(fi, fo, ti, to, l) /* копировать l байтов из ti в to, */ STRING fi, fo, ti, to; /* согласно форматов fi и fo */ { int i, *oi, *oo; oi = make_o(fi, l); /* перестановочная таблица fi->"" */ oo = make_o(fo, l); /* перестановочная таблица fo->"" */ for (i = 0; i < l; i++) /* копирование ti->to с перестановкой */ to[oo[i]] = ti[oi[i]]; }
gget(fi, fo, ti, to, l, nm) /* вывести в to (согласно fo) все */ STRING fi, fo, ti, to, nm; /* значения полей с именем nm из ti */ { /* (формата fi и длиной l) */ int i, *oi, *oo, lo; oi = make_o_nm(fi, l, nm, &lo); /* перестановочная таблица fi->"" */ if (lo) { /* имя найдено */ oo = make_o(fo, lo); /* перестановочная таблица fo->"" */ for (i = 0; i < lo; i++) /* копирование ti->to с перестановкой */ to[oo[i]] = ti[oi[i]]; } return lo; }
ggetnum(f, l, nm) /* выдать количество полей */ STRING f, nm; /* с именем nm из формата f */ { /* при длине входного текста l */ int n; pblock root; /* охватывающий блок */ MALLOC(root, block); parser(root, f, l, nm, strlen(nm)); /* построение дерева блоков */ n = build_n(root, 0, l); /* пересчет полей */ freeblock(root, 1); /* удаление дерева */ return n; }
gset(fi, fo, ti, to, l, nm) /* заместить в ti (формата fi и */ STRING fi, fo, ti, to, nm; /* длины l) все поля с именем nm */ { /* на to (формата fo) */ int i, *oi, *oo, lo; oi = make_o_nm(fi, l, nm, &lo); /* перестановочная таблица fi->"" */ if (lo) { /* имя найдено */ oo = make_o(fo, lo); /* перестановочная таблица fo->"" */ for (i = 0; i < lo; i++) /* копирование to->ti с перестановкой */ ti[oi[i]] = to[oo[i]]; } return lo; }
pname_list gfields(f) /* выдергивание имен из формата; */ STRING f; /* имена остаются в формате, */ { /* хранятся только указатели */ pname_list x; int c; x = NULL; while (c = get_lex(&f)) {/* взять лексему */ if (c == 8) { /* имя блока */ pname_list t; MALLOC(t, name_list) t->s = str; t->ns = num; t->next = x; x = t; } } return x; }
BYTE I[900], O[900];
main() { int i, l; STRING fi; pname_list p; /* scanf("%d", &l); read_hex(I, l); write_hex(I + 72 + 36, 32); printf("\n"); */ fi = "'C_UZ'64.4'C_UZ_IMIT'4'IM_UZ'(32'C_LMK'.4'C_LMK_IMIT')20.4'C_FSG'.4'C_FSG_IMIT'"; /* l = gget(fi, "", I, O, l, "C_LMK_IMIT"); write_hex(O, l); printf("\n"); p = gfields(fi); */ printf("%d\n", ggetnum(fi, 828, "C_LMK_IMIT")); }
Можно видеть, что я нигде не ставлю проверок допустимости параметров. Это основное правило обеспечения работоспособности кода. Умные данные - это самый верный способ оставить в коде дыру. Пусть код валится как можно чаще и пусть все ошибки будут видны на верхнем уровне - тогда будет шанс их обнаружить. *** Наиболее удобный этап выйти на удобный проблемно ориентированный язык - перед началом планирования в обычном блокноте попытаться нарисовать программу как некую Incredible Machine (в крайнем случае - панель прибора/план завода, который вы будете эмулировать/асучивать). Например (художник я еще тот, проект):
Или текстом см. там. *** Если модель не удается проработать на бумаге, то получается срашненько. Например, как в Лунолете. *** Но, конечно, этот метод лучше всего работает в языке FORTH. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Сообщение отредактировал Gudleifr - Четверг, 24 Декабря 2015, 15:10
Ну, как бы, первый Ваш пост при не мог иметь никакого отношения ко мне физически, я появился в теме позже. Так что думаю хватит обращать в этой теме внимание на Вашу брехню. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Можно было бы несколько улучшить ситуацию, дав игроку возможность совершать какие-то действия для снижения\устранения шансов внезапной гибели.
Это, безусловно, правильно. Только, желательно, повесить на это какую-то "мораль". Например, игрок научается выбирать наиболее безопасный выход, получая смутные намеки. Я это называю головоломками "третьего рода" (по Стругацким): 1. если способв распознавания головоломок ясен еще до игры, это «спинномозговик» (1 уровень); 2. если правильную стратегию игрок вырабатывает в процессе игры, это уровень 2; 3. если стратегию надо изменять в течение игры, это уровень 3. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
где здесь вариация при убийстве барлога не получить правильную концовку?
А почему кубик обязательно бросать в самом конце? Барлог может вас замочить даже если вы действовали правильно. Можно даже до него не дойти... Кстати, в одном из первых расширений настольного TALISMAN практически в самом конце - получение Короны Власти - добавили случайный выбор вариантов, один из которых - сдохнуть.
Похоже, Вы уже давно слили.
Добавлено (22 декабря 2015, 17:33) ---------------------------------------------
ЦитатаHitguy ()
А вот это действительно чистый флуд, никакого отношение к играм с предусмотренным сюжетом решениями и поведением
Вы думаете военные игры ограничиваются FPS и RTS? Классическая военная игра в буквальном значении этого слова подразумевает продуманный сюжет. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Hitguy, а чем Вас не устроило предложенное выше? Вы видели мало РПГ с развитой боевкой? Начнем с азов. Раз Rogue поминали, берем следующую - AKALABETH. Из приведенного кода видно, сдохнуть можно при любом поведении.
Добавлено (22 декабря 2015, 17:14) --------------------------------------------- С точки зрения реализма... Например, рассмотрим, какова специфика военных решений (по книге А.В.Маркина "Основы тактической подготовки современного солдата"): 1. Неопределенность обстановки. 2. Слабая корреляция правильности действий с положительностью результата. 3. Страх ответственности. 4. Отсутствие времени на обдумывание. 5. Неясность цели действий. Т.е. для военных игр прямо-таки рекомендуется.
Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
наличие одной (да даже миллиона) удовлетворяющей Вашим запросам игры, не доказывает отсутствия игр, где описанный прием с успехом используется. Так что, правильно, кончайте флуд о непонятой мечты безрукого ботана всегда "победять"... Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Он, по сути, вообще не генерирует код, т.к. является, по сути, просто макроассемблером. Что пишу - то и получаю.
ЦитатаOpenGOO ()
C ... не поддерживает ООП
Не поддерживает ООП в стиле C++. Никто не мешает использовать методы ООП в C, или иметь доступ к ОО-библиотекам.
ЦитатаOpenGOO ()
С++ генерирует высокопроизводительный машинный код
Только, если не пользоваться дурацкими библиотеками (типа STL, табличку я приводил), не провоцировать компилятор на создание избыточных конструкторов и отказаться от умных указателей и прочего мусора.
ЦитатаOpenGOO ()
С++ ... поддерживает ООП.
В стиле C++? к нормальному ООП отношения не имеющему. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Hitguy, так бы сразы и сказали... Берите любую РПГ-игру с развитой боевкой. Ситуация безвозвратной потери армии при "неудачных кубах" вполне вероятна. Или возьмите, например, KING'S BOUNTY. Упоминавшиеся выше рогалики. Любую игру, где возможен проигрыш "по очкам". Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Hitguy, извините, но все мои примеры приведены вместе с утверждениями об их применимости. В отличие от Ваших. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Соответственно прошу примеры проектов/книги авторов, которые бы доказывали ваше утверждение.
ЦитатаDaeloce ()
На работе, где в основном пишу HPC вещи, плюсы в использую в режиме "Си с классами", ибо там голые массивы, да еще и руками выровненные под кэш и т.п. суровая необходимость, так что в ООП не развернешься.
Как бы, вот.
ЦитатаDaeloce ()
Ну например бинарные деревья, это map.
Таблица расстановки, если только в STL не налажали. Но не суть,
ЦитатаDaeloce ()
ибо область применения подобных алгоритмов крайне специфична
Отложим разговор лет на 10-20.
ЦитатаDaeloce ()
И снова я возвращаюсь к вопросу, вы вообще в курсе что такое ООП?
Надоели. Простите за хамство, но, в отличие от Вас, понимаю. Разница между нашими пониманиями:
Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Daeloce, речь не о том, как писать на C++ "правильно", а о том, что писать на нем иначе невозможно ("классический" способ не работает, способ "чтобы было" слишком затратен). Конечно грубо утверждать, что Вы "смотрели в книгу, а видели фигу", но, думаю, этого, к счастью, и не требуется. Еще надцать лет попишете (как сейчас) код, к которому нельзя по очевидным причинам прицепить ООП, и сами по другому посмотрите на "красивый код общепринятых классиков".
P.S. Почему я обзываю STL "быдлокодом"? По причине его убожества. Например, каждый человек, сталкивавшийся с большими объемами данных, помнит табличку:
И какой процент этого покрывает STL? А, ведь, "чистые" типы данных встречаются крайне редко. Так что, STL просто "защищает" пользователя от данных вместо того, чтобы получить к ним доступ в нужной для него форме. Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
Сообщение отредактировал Gudleifr - Вторник, 22 Декабря 2015, 14:42