Pull to refresh
13
0
Дмитрий Ховрин@stalker320

Разработчик игр

Send message

Возможно, вот эту функцию можно написать лучше

#include "loader.h"
#include "functions.h"
#include <stdio.h>

#ifndef WIN32
#include <dlfcn.h>
#else
#include <windows.h>
#endif

void loadRun(const char * const s) {
   void * lib;
   void (*fun)(void);
#ifndef WIN32
   lib = dlopen(s, RTLD_LAZY);
#else
   lib = LoadLibrary(s);
#endif
   if (!lib) {
     printf("cannot open library '%s'\n", s);
     return;
   }
#ifndef WIN32
   fun = (void (*)(void))dlsym(lib, "run");
#else
   fun = (void (*)(void))GetProcAddress((HINSTANCE)lib, "run");
#endif
   if (fun == NULL) {
     printf("cannot load function run\n");
   } else {
     fun();
   }
#ifndef WIN32
   dlclose(lib);
#else
   FreeLibrary((HINSTANCE)lib);
#endif
}

Например, вот так

#include "loader.h"
#include "functions.h"
#include <stdio.h>

#ifdef WIN32
#include <windows.h>
#define OPEN(PATH) LoadLibrary(PATH)
#define GETFN(LIB, FN) GetProcAddress((HINSTANCE) LIB, FN)
#define CLOSE(LIB) FreeLibrary((HINSTANCE) LIB)

#elifdef UNIX
// Не помню правильный заголовок,
// но UNIX-подобные содержит POSIX-совместимые заголовки,
// к которым относятся dlfcn.h
#include <dlfcn.h>
#define OPEN(PATH) dlopen(PATH, RTLD_LAZY)
#define GETFN(LIB, FN) dlsym(LIB, FN)
#define CLOSE(LIB) dlclose(LIB)
#endif

void loadRun(const char * const s) {
   void * lib;
   void (*fun)(void);
   lib = OPEN(s);
   if (!lib) {
     printf("cannot open library '%s'\n", s);
     return;
   }
   fun = (void (*)(void))GETFN(lib, "run");
   if (fun == NULL) {
     printf("cannot load function run\n");
   } else {
     fun();
   }
   CLOSE(lib);  
}

P. S. Я вообще разделил реализацию и просто выбираю правильную в CMake.

Добавлю, есть ещё команда

flask --app app run

Или же в крайнем случае

python -m flask --app app run

для запуска без if __name__ == "__main__", или подобного

Да, я спрашиваю нейронку, но она так коверкает мои уникальные идеи, что я просто сам допираю как что-то сделать.

У меня вот как, я включил 694 и 705 строку в код:

#if 0
#ifndef __cplusplus
#ifndef NOMINMAX
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#endif
#endif
#endif

Да, я вот думаю, что это будет полезно в том же OpenGL на стадии понимания что делает glClear тот же:

glClear(0
  | GL_COLOR_BUFFER_BIT
  | GL_DEPTH_BUFFER_BIT
);

И да, это работает и с побитовыми операциями, я думаю.

А что за «специфичная платформа»™ подобное за С17 примет и не подавится? Для друга интересуюсь.

Ладно, у меня компилятор подавился. Но gcc на linux как-то съел struct {int;}; и не подавился. Спасибо за помощь, сейчас подредачу статью.

Спасибо, ознакомлюсь. А так пока в планах с чат-гпт напополам созданный алгоритм по определению принадлежности треугольнику(Я узнал 3 способа сделать это, но всё оказалось проще, когда узнал про смысл cross-product. А там звёзды и сошлись с принципами работы OpenGL) развивать и публиковать по-тихоньку.

Я полистал первый из 4 словарей, в нём указаны окончания.

Сколько я искал инфы на C>17, так и не находил. Спасибо. Пора снова залезть в интернет

const COORD* head = &Snake[0]; // чтобы не копипастить индекс каждый раз
isGameEnd |= head->X == W || head->X == 0; // укусила боковые границы
isGameEnd |= head->Y == H || head->Y == 0; // укусила нижнюю или верхнюю границы
for (int i = 1; i < snakeSize; i++) 
{
  // укусила себя
  isGameEnd |= head->X == Snake[i].X 
            && head->Y == Snake[i].Y;
}

Но можно проще:

isGameEnd |=
  head->X == W | head->X == 0 |
  head->Y == H | head->Y == 0; // Побитовые операции наше всё
for (int i = 1; i < snakeSize; i++) 
{
  // укусила себя
  isGameEnd |= (head->X == Snake[i].X & head->Y == Snake[i].Y);
}

Почему?

При операции сравнение мы получаем bool, где false = 0b0000 (Упрощённо), а true = 0b0001. Таким образом, задействован только 1 бит. Побитовое "или" работает для любого количества входных аргументов, поэтому я просто объединил все сравнения в одну конструкцию. А ещё мне нравится убирать тело цикла и решать всё через инкремент.

for (
  int i = 1;
  i < snakeSize | !isGameEnd; // Зачем нам продолжать проверки, если врезались.
  isGameEnd |= (head->X == Snake[i].X & head->Y == Snake[i++ /* инкремент */].Y));

Всё конечно классно переведено, но я начинаю понимать, что довольно запарно всё это создавать...

Делюсь make-комбайном по компиляции GLSL в SPIR-V

Прим:

  1. Замените glslc в коде ниже на путь (Я просто воткнул /home/stalker320/VulkanSDK/1.3.290.0/x86_64/bin в переменную PATH в начало)

  2. Поместите ниже приведённый Makefile в папку shaders

  3. Поместите шейдеры в папку shaders/src и создайте папку shaders/bin. Пути зависят от SRCPREFIX и OBJPREFIX

  4. называйте файлы следующим образом: filename.stage.glsl, где stage - это vert, vertex, frag, fragment и прочие стадии пайплайна

  5. Выполните make all для исполнения

  6. Выполните make clear для очистки

COMPILER = glslc

SRCPREFIX=src
OBJPREFIX=bin
SLSUFFIX=glsl

SOURCES = $(wildcard $(SRCPREFIX)/*.$(SLSUFFIX)) $(wildcard $(SRCPREFIX)/*.$(SLSUFFIX))
OBJECTS = $(patsubst $(SRCPREFIX)/%.$(SLSUFFIX),$(OBJPREFIX)/%.spv,$(SOURCES))

$(OBJPREFIX)/%.spv: $(SRCPREFIX)/%.$(SLSUFFIX)
	${COMPILER} -fshader-stage=$(patsubst $(SRCPREFIX)/$(basename $(basename $(notdir $<))).%,%,$(patsubst %.$(SLSUFFIX),%,$<)) $< -o $@

.PHONY: all clean

all: $(OBJECTS)

clean:
	rm $(OBJPREFIX)/*.spv

UPD: исправил для поддержки hlsl (сделал суффикс изменяемым)

Ты и пользователи github. А вообще те, кто будет писать компилятор к твоему языку программирования

Ну смотри: str - это тип, а str() - это создание объекта str. При использовании подсказок типов ты пишешь

x: str = "Hello world"
num: str = str(8)

А __str__ необходим для добавления в варианты того, что можно подставить в конструктор.

А decode - это для работы с байтами.

Генитальный кусок кода

Ты прямо серьёзно, или "гениальный" кусок "кода"?

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

Ну не знаю даже... Вынести вспомогательные функции в отдельные курсы, которые идут дополнением к уроку, не, или ссылаясь на существующие "как сделать"? К примеру мне нравится Си, хотя я приведу куда более красивый пример: Rust. Вот запрос "Нейросеть на Rust-lang" даёт следующее количество результатов: 0 по теме, +- 10 результатов про "использование нейросети в rust(игре)", +- 20 результатов про реализацию с помощью библиотек на python, +- 5 результатов с чистой математикой и слоганом "простыми словами" (лишь слоганом), при поиске в "duckduckgo". А я не хочу ковыряться тысячи часов в исходниках библиотеки tensorflow на python, чтобы написать необходимую мне библиотеку. Вот мне и нужно это +- простое объяснение, чтобы сделать то, что я желаю, или хотя бы адаптировать под свои нужды. Вот про что я могу сказать, что помогло, так это ролик про перцептрон от IT_Школьника, код которого я переписал на Rust и создав 1 рабочий слой, который даже работал. Я заинтересован в создании конвейеров нейросетей, но хочу использовать хоть немного чужого опыта, чтобы не начинать полностью с нуля.

UPD: Простите, если моё сообщение не в тему, просто вечный поиск мне немного надоел. Если есть что почитать полезного про создание нейросети на Rust, то прошу посоветуйте, не откажусь от помощи.

Слушай, вот ты ближе всего к сегодня написал: как ты понял, в производную функции активации передавать надо что?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity

Specialization

Десктоп разработчик, Разработчик игр
Git
Python
Java
C++
C
SQL
Godot Engine