diff --git a/Game of Life/Game of Life/Game of Life.vcxproj b/Game of Life/Game of Life/Game of Life.vcxproj index 911436e..324db44 100644 --- a/Game of Life/Game of Life/Game of Life.vcxproj +++ b/Game of Life/Game of Life/Game of Life.vcxproj @@ -105,6 +105,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(SolutionDir)\include + stdc17 Console @@ -122,7 +123,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(SolutionDir)\include; - Default + stdc17 Windows @@ -139,13 +140,16 @@ + - + + + - + diff --git a/Game of Life/Game of Life/Game of Life.vcxproj.filters b/Game of Life/Game of Life/Game of Life.vcxproj.filters index 3cfe70d..4603913 100644 --- a/Game of Life/Game of Life/Game of Life.vcxproj.filters +++ b/Game of Life/Game of Life/Game of Life.vcxproj.filters @@ -33,7 +33,10 @@ Файлы заголовков - + + Файлы заголовков + + Файлы заголовков @@ -47,7 +50,13 @@ Исходные файлы - + + Исходные файлы + + + Исходные файлы + + Исходные файлы diff --git a/Game of Life/src/dynamic_memory.c b/Game of Life/src/dynamic_memory.c new file mode 100644 index 0000000..b97588d --- /dev/null +++ b/Game of Life/src/dynamic_memory.c @@ -0,0 +1,31 @@ +#include +#include + +void* SafeMalloc(size_t size) +{ + void* buffer = malloc(size); + if (buffer == NULL) { + fprintf(stderr, "Error in SafeMalloc: failed to allocate %zu bytes.\n", size); + abort(); + } + return buffer; +} + +void* SafeCalloc(size_t count, size_t size) +{ + void* buffer = calloc(count, size); + if (buffer == NULL) { + fprintf(stderr, "Error in SafeCalloc: failed to allocate %zu bytes.\n", count * size); + abort(); + } + return buffer; +} + +void* SafeRealloc(void* block, size_t size) { + void* buffer = realloc(block, size); + if (buffer == NULL) { + fprintf(stderr, "Error in SafeRealloc: failed to reallocate block %p of %zu bytes.\n", block, size); + abort(); + } + return buffer; +} diff --git a/Game of Life/src/dynamic_memory.h b/Game of Life/src/dynamic_memory.h new file mode 100644 index 0000000..4678f09 --- /dev/null +++ b/Game of Life/src/dynamic_memory.h @@ -0,0 +1,5 @@ +#pragma once + +void* SafeMalloc(size_t size); +void* SafeCalloc(size_t count, size_t size); +void* SafeRealloc(void* block, size_t size); diff --git a/Game of Life/src/gol_threading.c b/Game of Life/src/gol_threading.c new file mode 100644 index 0000000..1046d9c --- /dev/null +++ b/Game of Life/src/gol_threading.c @@ -0,0 +1,53 @@ +//#include +//#include +//#include +// +//typedef struct { +// bool** map; +// bool** tempMap; +// int startX; +// int endX; +// int startY; +// int endY; +//} golArgs; + +//static inline int checkCell(int x, int y) { +// if (x < 0 or y < 0 or x > MAP_X - 1 or y > MAP_Y - 1) { +// return 0; +// } +// else { +// return map[x][y]; +// } +//} + +//void celluralAutomata() +//{ +// for (int x = 0; x < MAP_X; x++) { +// for (int y = 0; y < MAP_Y; y++) { +// int neighbours = 0; +// +// neighbours += checkCell(x - 1, y); +// neighbours += checkCell(x - 1, y + 1); +// neighbours += checkCell(x - 1, y - 1); +// neighbours += checkCell(x + 1, y); +// neighbours += checkCell(x + 1, y + 1); +// neighbours += checkCell(x + 1, y - 1); +// neighbours += checkCell(x, y + 1); +// neighbours += checkCell(x, y - 1); +// +// if (neighbours == 3) { +// tempMap[x][y] = true; +// } +// else if (neighbours == 2) { +// tempMap[x][y] = map[x][y]; +// } +// else { +// tempMap[x][y] = false; +// } +// +// } +// } +// for (int x = 0; x < MAP_X; x++) { +// memcpy(map[x], tempMap[x], MAP_Y * sizeof(bool)); +// } +//} \ No newline at end of file diff --git a/Game of Life/src/main.c b/Game of Life/src/main.c index be57189..deb1b9a 100644 --- a/Game of Life/src/main.c +++ b/Game of Life/src/main.c @@ -3,21 +3,20 @@ #include "raylib.h" #include "raymath.h" #include "resource_dir.h" + #include #include #include #include +#include -#include "parallel_for.h" +#include "dynamic_memory.h" +#include "memory_arena.h" -#define RAYGUI_IMPLEMENTATION -#include "raygui.h" - -#define MAP_X 400 -#define MAP_Y 200 -#define CELL_SIZE 6 +#define MAP_X 1200 +#define MAP_Y 600 +#define CELL_SIZE 2 #define FCELL_SIZE (float)CELL_SIZE - #define BOTTOM_BAR_HEIGHT 60 #define PUREBLUE CLITERAL(Color){ 0, 0, 255, 255 } @@ -25,275 +24,379 @@ #define VSGREEN CLITERAL(Color){78, 201, 176, 255} #define WATERBLUE CLITERAL(Color){200, 240, 255, 255} -//static bool map[MAP_X][MAP_Y] = { 0 }; -//static bool tempMap[MAP_X][MAP_Y] = { 0 }; - bool** map; bool** tempMap; -void* SafeMalloc(size_t size) +typedef struct { + bool** map; + bool** tempMap; + int startX; + int endX; + int startY; + int endY; +} golArgs; + +thrd_t threads[32]; +golArgs thread_args[32]; +int numThreads = 5; + +static inline int checkCell(int x, int y) { - void* buffer = malloc(size); - if (buffer == NULL) { - fprintf(stderr, "Error in SafeMalloc: failed to allocate %zu bytes.\n", size); - abort(); - } - return buffer; + if (x < 0 or y < 0 or x > MAP_X - 1 or y > MAP_Y - 1) { + return 0; + } + else { + return map[x][y]; + } } -void* SafeCalloc(size_t count, size_t size) +static inline single_gol(int x, int y) { - void* buffer = calloc(count, size); - if (buffer == NULL) { - fprintf(stderr, "Error in SafeCalloc: failed to allocate %zu bytes.\n", count * size); - abort(); - } - return buffer; + int neighbours = 0; + + neighbours += checkCell(x - 1, y); + neighbours += checkCell(x - 1, y + 1); + neighbours += checkCell(x - 1, y - 1); + neighbours += checkCell(x + 1, y); + neighbours += checkCell(x + 1, y + 1); + neighbours += checkCell(x + 1, y - 1); + neighbours += checkCell(x, y + 1); + neighbours += checkCell(x, y - 1); + + if (neighbours == 2) { + tempMap[x][y] = map[x][y]; + } + else if (neighbours == 3) { + tempMap[x][y] = true; + } + else { + tempMap[x][y] = false; + } } -static inline int checkCell(int x, int y) { - if (x < 0 or y < 0 or x > MAP_X - 1 or y > MAP_Y - 1) { - return 0; - } - else { - return map[x][y]; - } +int gol_thread(void* arg_ptr) +{ + golArgs args = *(golArgs*)(arg_ptr); + + for (int x = args.startX; x < args.endX; x++) { + for (int y = args.startY; y < args.endY; y++) { + int neighbours = 0; + + neighbours += checkCell(x - 1, y); + neighbours += checkCell(x - 1, y + 1); + neighbours += checkCell(x - 1, y - 1); + neighbours += checkCell(x + 1, y); + neighbours += checkCell(x + 1, y + 1); + neighbours += checkCell(x + 1, y - 1); + neighbours += checkCell(x, y + 1); + neighbours += checkCell(x, y - 1); + + if (neighbours == 2) { + tempMap[x][y] = map[x][y]; + } + else if (neighbours == 3) { + tempMap[x][y] = true; + } + else { + tempMap[x][y] = false; + } + + } + } + + single_gol(args.startX, args.startY); + single_gol(args.startX, args.endY); + single_gol(args.endX, args.startY); + single_gol(args.endX, args.endY); + + return 0; +} + +void gol_thread_init() { + int deltaX = MAP_X / numThreads; + int remainder = MAP_X % numThreads; + + for (int i = 0; i < numThreads - 1; i++) { + thread_args[i] = (golArgs){ + .startX = deltaX * i, + .endX = deltaX * (i + 1), + .startY = 0, + .endY = MAP_Y + }; + } + thread_args[numThreads - 1] = (golArgs){ + .startX = deltaX * (numThreads - 1), + .endX = MAP_X, + .startY = 0, + .endY = MAP_Y + }; +} + +void gol_thread_start() +{ + for (int i = 0; i < numThreads; i++) { + thrd_create(&threads[i], gol_thread, &thread_args[i]); + } + for (int i = 0; i < numThreads; i++) { + thrd_join(threads[i], NULL); + } + for (int x = 0; x < MAP_X; x++) { + memcpy(map[x], tempMap[x], MAP_Y * sizeof(bool)); + } } void celluralAutomata() { - for (int x = 0; x < MAP_X; x++) { - for (int y = 0; y < MAP_Y; y++) { - int neighbours = 0; + for (int x = 0; x < MAP_X; x++) { + for (int y = 0; y < MAP_Y; y++) { + int neighbours = 0; - neighbours += checkCell(x - 1, y); - neighbours += checkCell(x - 1, y + 1); - neighbours += checkCell(x - 1, y - 1); - neighbours += checkCell(x + 1, y); - neighbours += checkCell(x + 1, y + 1); - neighbours += checkCell(x + 1, y - 1); - neighbours += checkCell(x, y + 1); - neighbours += checkCell(x, y - 1); + neighbours += checkCell(x - 1, y); + neighbours += checkCell(x - 1, y + 1); + neighbours += checkCell(x - 1, y - 1); + neighbours += checkCell(x + 1, y); + neighbours += checkCell(x + 1, y + 1); + neighbours += checkCell(x + 1, y - 1); + neighbours += checkCell(x, y + 1); + neighbours += checkCell(x, y - 1); - if (neighbours == 3) { - tempMap[x][y] = true; - } - else if (neighbours == 2) { - tempMap[x][y] = map[x][y]; - } - else { - tempMap[x][y] = false; - } + if (neighbours == 3) { + tempMap[x][y] = true; + } + else if (neighbours == 2) { + tempMap[x][y] = map[x][y]; + } + else { + tempMap[x][y] = false; + } - } - } - for (int x = 0; x < MAP_X; x++) { - memcpy(map[x], tempMap[x], MAP_Y * sizeof(bool)); - } + } + } + for (int x = 0; x < MAP_X; x++) { + memcpy(map[x], tempMap[x], MAP_Y * sizeof(bool)); + } } -//int compute_cell(int x) { -// int neighbours = 0; -// -// neighbours += checkCell(x - 1, y); -// neighbours += checkCell(x - 1, y + 1); -// neighbours += checkCell(x - 1, y - 1); -// neighbours += checkCell(x + 1, y); -// neighbours += checkCell(x + 1, y + 1); -// neighbours += checkCell(x + 1, y - 1); -// neighbours += checkCell(x, y + 1); -// neighbours += checkCell(x, y - 1); -// -// if (neighbours == 3) { -// tempMap[x][y] = true; -// } -// else if (neighbours == 2) { -// tempMap[x][y] = map[x][y]; -// } -// else { -// tempMap[x][y] = false; -// } -//} -// -//void* compute_cell_forp(void* arg) -//{ -// int* pa = (int*)arg; -// int* result = malloc(sizeof(*result)); -// *result = mult2(*pa); -// return result; -//} - void ClearMap() { - for (int x = 0; x < MAP_X; x++) { - memset(map[x], 0, MAP_Y * sizeof(bool)); - } + for (int x = 0; x < MAP_X; x++) { + memset(map[x], 0, MAP_Y * sizeof(bool)); + } } void drawMap() { - for (int x = 0; x < MAP_X; x++) { - for (int y = 0; y < MAP_Y; y++) { - if (map[x][y]) { - int posX = x * CELL_SIZE; - int posY = y * CELL_SIZE; - DrawRectangle(posX, posY, CELL_SIZE, CELL_SIZE, BLACK); - } - } - } + for (int x = 0; x < MAP_X; x++) { + for (int y = 0; y < MAP_Y; y++) { + if (map[x][y]) { + int posX = x * CELL_SIZE; + int posY = y * CELL_SIZE; + DrawRectangle(posX, posY, CELL_SIZE, CELL_SIZE, BLACK); + } + } + } } void drawNet() { - for (int i = 0; i <= MAP_X * CELL_SIZE; i += CELL_SIZE) { - DrawLine(i, 0, i, MAP_Y * CELL_SIZE, GRAY); - DrawLine(i+1, 0, i+1, MAP_Y * CELL_SIZE, GRAY); - } + for (int i = 0; i <= MAP_X * CELL_SIZE; i += CELL_SIZE) { + DrawLine(i, 0, i, MAP_Y * CELL_SIZE, GRAY); + DrawLine(i+1, 0, i+1, MAP_Y * CELL_SIZE, GRAY); + } - for (int i = 0; i <= MAP_Y * CELL_SIZE; i += CELL_SIZE) { - DrawLine(0, i, MAP_X * CELL_SIZE, i, GRAY); - DrawLine(0, i-1, MAP_X * CELL_SIZE, i-1, GRAY); - } + for (int i = 0; i <= MAP_Y * CELL_SIZE; i += CELL_SIZE) { + DrawLine(0, i, MAP_X * CELL_SIZE, i, GRAY); + DrawLine(0, i-1, MAP_X * CELL_SIZE, i-1, GRAY); + } } void drawBottomBar() { - DrawRectangle(0, MAP_Y * CELL_SIZE, MAP_X * CELL_SIZE, BOTTOM_BAR_HEIGHT, BLACKGRAY); + DrawRectangle(0, MAP_Y * CELL_SIZE, MAP_X * CELL_SIZE, BOTTOM_BAR_HEIGHT, BLACKGRAY); } #define CPSIZE 213 int main() { - map = (bool**)SafeMalloc(MAP_X * sizeof(bool*)); - tempMap = (bool**)SafeMalloc(MAP_X * sizeof(bool*)); - for (int x = 0; x < MAP_X; x++) { - map[x] = (bool*)SafeCalloc(MAP_Y, sizeof(bool)); - tempMap[x] = (bool*)SafeCalloc(MAP_Y, sizeof(bool)); - } + map = (bool**)SafeMalloc(MAP_X * sizeof(bool*)); + tempMap = (bool**)SafeMalloc(MAP_X * sizeof(bool*)); + for (int x = 0; x < MAP_X; x++) { + map[x] = (bool*)SafeCalloc(MAP_Y, sizeof(bool)); + tempMap[x] = (bool*)SafeCalloc(MAP_Y, sizeof(bool)); + } - const int screenWidth = MAP_X * CELL_SIZE; - const int screenHeight = MAP_Y * CELL_SIZE + BOTTOM_BAR_HEIGHT; + gol_thread_init(); - InitWindow(screenWidth, screenHeight, "Game of Life"); + /*Arena arena = ArenaCreate(SafeCalloc(1024 * 1024, 1), 1024 * 1024); + map = (bool**)ArenaAlloc(&arena, MAP_X * sizeof(bool*)); + tempMap = (bool**)ArenaAlloc(&arena, MAP_X * sizeof(bool*)); + for (int x = 0; x < MAP_X; x++) { + map[x] = (bool*)ArenaAlloc(&arena, MAP_Y * sizeof(bool)); + tempMap[x] = (bool*)ArenaAlloc(&arena, MAP_Y * sizeof(bool)); + }*/ - SearchAndSetResourceDir("resources"); + const int screenWidth = MAP_X * CELL_SIZE; + const int screenHeight = MAP_Y * CELL_SIZE + BOTTOM_BAR_HEIGHT; - int codepoints[CPSIZE] = { 0 }; - for (int i = 0; i < 127 - 32; i++) codepoints[i] = 32 + i; // Basic ASCII characters - for (int i = 0; i < 118; i++) codepoints[95 + i] = 1024 + i; // Cyrillic characters + SetConfigFlags(FLAG_VSYNC_HINT); - Font InconsolataBold = LoadFontEx("Inconsolata-LGC-Bold.ttf", 36, codepoints, CPSIZE); - SetTextureFilter(InconsolataBold.texture, TEXTURE_FILTER_BILINEAR); + InitWindow(screenWidth, screenHeight, "Game of Life"); - GuiSetFont(InconsolataBold); - GuiSetStyle(DEFAULT, TEXT_SIZE, (int)(24)); - GuiSetStyle(DEFAULT, TEXT_SPACING, 0); - GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, (int)(24)); - GuiSetStyle(STATUSBAR, BORDER_WIDTH, 2); + int monitor = GetCurrentMonitor(); + int monitorFPS = GetMonitorRefreshRate(monitor); - int monitor = GetCurrentMonitor(); - int monitorFPS = GetMonitorRefreshRate(monitor); + SetTargetFPS(monitorFPS); - SetTargetFPS(monitorFPS); + SearchAndSetResourceDir("resources"); - Vector2 mousePos = { 0 }; - int mouseCellX = 0; - int mouseCellY = 0; + int codepoints[CPSIZE] = { 0 }; + for (int i = 0; i < 127 - 32; i++) codepoints[i] = 32 + i; // Basic ASCII characters + for (int i = 0; i < 118; i++) codepoints[95 + i] = 1024 + i; // Cyrillic characters - bool editMap = true; - bool netToggle = false; + Font InconsolataBold = LoadFontEx("Inconsolata-LGC-Bold.ttf", 36, codepoints, CPSIZE); + SetTextureFilter(InconsolataBold.texture, TEXTURE_FILTER_BILINEAR); - float simSpeed = 1.0f; - int frameCounter = 0; + Vector2 mousePos = { 0 }; + Vector2 mouseWorldPos = { 0 }; + int mouseWorldCellX = 0; + int mouseWorldCellY = 0; - int guyScreenWidth = 720; + bool editMap = true; + bool netToggle = false; - while (!WindowShouldClose()) - { - frameCounter++; + float simSpeed = 1.0f; + int frameCounter = 0; - if (IsKeyPressed(KEY_SPACE)) { - editMap = !editMap; - } - if (IsKeyPressed(KEY_N)) { - netToggle = !netToggle; - } - if (IsKeyPressed(KEY_EQUAL)) { - simSpeed *= 2.0f; - } - if (IsKeyPressed(KEY_MINUS)) { - simSpeed *= 0.5f; - } - if (IsKeyPressed(KEY_C)) { - ClearMap(); - } + int guiScreenWidth = 720; - if (editMap) - { - mousePos = GetMousePosition(); - mouseCellX = (int)(Clamp(mousePos.x, 0, (float)(MAP_X * CELL_SIZE - 1)) / CELL_SIZE); - mouseCellY = (int)(Clamp(mousePos.y, 0, (float)(MAP_Y * CELL_SIZE - 1)) / CELL_SIZE); + Camera2D camera = { + .target = (Vector2){ screenWidth / 2.0f, screenHeight / 2.0f }, + .offset = (Vector2){ screenWidth / 2.0f, screenHeight / 2.0f }, + .rotation = 0.0f, + .zoom = 1.0f + }; + int cameraSpeed; + float frametime; + //float mouseWheel; - if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - map[mouseCellX][mouseCellY] = true; - } - else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) { - map[mouseCellX][mouseCellY] = false; - } - } - else if (FloatEquals(simSpeed, 1.0f)) { - celluralAutomata(); - } - else if (simSpeed < 1.0f and frameCounter >= 1 / simSpeed) { - celluralAutomata(); - //printf("%d %d\n", frameCounter, (int)(1 / simSpeed)); - frameCounter = 0; - } - else if (simSpeed > 1.0f) { - for (int i = 0; i < (int)simSpeed; i++) { - celluralAutomata(); - } - //printf("%f speed\n", simSpeed); - } + while (!WindowShouldClose()) + { + frameCounter++; + frametime = GetFrameTime(); - BeginDrawing(); - ClearBackground(WHITE); + if (IsKeyPressed(KEY_SPACE)) { + editMap = !editMap; + } + if (IsKeyPressed(KEY_N)) { + netToggle = !netToggle; + } + if (IsKeyPressed(KEY_EQUAL)) { + simSpeed *= 2.0f; + } + if (IsKeyPressed(KEY_MINUS)) { + simSpeed *= 0.5f; + } + if (IsKeyPressed(KEY_C)) { + ClearMap(); + } - drawMap(); - drawBottomBar(); + if (editMap) + { + mousePos = GetMousePosition(); + mouseWorldPos = GetScreenToWorld2D(mousePos, camera); + mouseWorldCellX = (int)(Clamp(mouseWorldPos.x, 0, (float)(MAP_X * CELL_SIZE - 1)) / CELL_SIZE); + mouseWorldCellY = (int)(Clamp(mouseWorldPos.y, 0, (float)(MAP_Y * CELL_SIZE - 1)) / CELL_SIZE); - if (netToggle) drawNet(); + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + map[mouseWorldCellX][mouseWorldCellY] = true; + } + else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) { + map[mouseWorldCellX][mouseWorldCellY] = false; + } + } + else if (FloatEquals(simSpeed, 1.0f)) { + //celluralAutomata(); + gol_thread_start(); + } + else if (simSpeed < 1.0f and frameCounter >= 1 / simSpeed) { + //celluralAutomata(); + gol_thread_start(); + frameCounter = 0; + } + else if (simSpeed > 1.0f) { + for (int i = 0; i < (int)simSpeed; i++) { + //celluralAutomata(); + gol_thread_start(); + } + //printf("%f speed\n", simSpeed); + } - if (editMap) - { - Rectangle rec = { mouseCellX * FCELL_SIZE, mouseCellY * FCELL_SIZE, FCELL_SIZE, FCELL_SIZE }; - DrawRectangleLinesEx(rec, 2, GREEN); - } - //Rectangle settingsBox = { 400, 400, 400, 200 }; - //GuiGroupBox(settingsBox, u8"Init game"); - //Rectangle valueBox1 = { 620, 420, 100, 40 }; - //GuiValueBox(valueBox1, u8"screen Width ", &guyScreenWidth, 120, 2560, true); - DrawFPS(0, MAP_Y * CELL_SIZE); - DrawText(TextFormat("%.4fx", simSpeed), 0, MAP_Y * CELL_SIZE + 20, 20, ORANGE); - DrawText(TextFormat("%.1f TPS", GetFPS() * simSpeed), 0, MAP_Y * CELL_SIZE + 40, 20, BLUE); + if (IsKeyDown(KEY_LEFT_SHIFT)) { + cameraSpeed = 1000; + } + else { + cameraSpeed = 200; + } - EndDrawing(); - } + if (IsKeyDown(KEY_W)) { + camera.target.y -= cameraSpeed * frametime; + } + if (IsKeyDown(KEY_S)) { + camera.target.y += cameraSpeed * frametime; + } + if (IsKeyDown(KEY_A)) { + camera.target.x -= cameraSpeed * frametime; + } + if (IsKeyDown(KEY_D)) { + camera.target.x += cameraSpeed * frametime; + } - for (int x = 0; x < MAP_X; x++) { - free(map[x]); - free(tempMap[x]); - } - free(map); - free(tempMap); + BeginDrawing(); - UnloadFont(InconsolataBold); + ClearBackground(WHITE); - CloseWindow(); + BeginMode2D(camera); - return 0; + drawMap(); + Rectangle rec = { -2, -2, MAP_X * CELL_SIZE + 4, MAP_Y * CELL_SIZE + 4 }; + + DrawRectangleLinesEx(rec, 2.0f, RED); + + if (netToggle) drawNet(); + + if (editMap) + { + Rectangle rec = { mouseWorldCellX * FCELL_SIZE, mouseWorldCellY * FCELL_SIZE, FCELL_SIZE, FCELL_SIZE }; + DrawRectangleLinesEx(rec, 2, GREEN); + } + + EndMode2D(); + + drawBottomBar(); + + DrawFPS(0, MAP_Y * CELL_SIZE); + DrawText(TextFormat("%.4fx", simSpeed), 0, MAP_Y * CELL_SIZE + 20, 20, ORANGE); + DrawText(TextFormat("%.1f TPS", GetFPS() * simSpeed), 0, MAP_Y * CELL_SIZE + 40, 20, BLUE); + + EndDrawing(); + } + + for (int x = 0; x < MAP_X; x++) { + free(map[x]); + free(tempMap[x]); + } + free(map); + free(tempMap); + + //ArenaDestroy(&arena); + + UnloadFont(InconsolataBold); + + CloseWindow(); + + return 0; } int WinMain() { - return main(); + return main(); } \ No newline at end of file diff --git a/Game of Life/src/memory_arena.c b/Game of Life/src/memory_arena.c new file mode 100644 index 0000000..ee74114 --- /dev/null +++ b/Game of Life/src/memory_arena.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "memory_arena.h" + +static bool is_power_of_two(uintptr_t x) { + return (x & (x - 1)) == 0; +} + +static uintptr_t AlignForward(uintptr_t ptr, size_t alignment) { + uintptr_t p, a, modulo; + + assert(is_power_of_two(alignment)); + + p = ptr; + a = (uintptr_t)alignment; + // Same as (p % a) but faster as 'a' is a power of two + modulo = p & (a - 1); + + if (modulo != 0) { + // If 'p' address is not aligned, push the address to the + // next value which is aligned + p += a - modulo; + } + return p; +} + +void* ArenaAllocAligned(Arena* arena, size_t size, size_t alignment) +{ + uintptr_t aligned_offset_ptr = AlignForward(arena->offset_ptr, alignment); + uintptr_t next_offset_ptr = aligned_offset_ptr + size; + + if (next_offset_ptr - (uintptr_t)arena->buffer <= arena->size) + { + arena->offset_ptr = next_offset_ptr; + return (void*)aligned_offset_ptr; + } + + fprintf(stderr, "\nError in ArenaAllocAligned: reached arena end.\n"); + abort(); +} + +void* ArenaAlloc(Arena* arena, size_t size) +{ + return ArenaAllocAligned(arena, size, DEFAULT_ALIGNMENT); +} + +Arena ArenaCreate(void* buffer, size_t buffer_size) +{ + return (Arena) { + .buffer = buffer, + .size = buffer_size, + .offset_ptr = (uintptr_t)buffer + }; +} + +void ArenaDestroy(Arena* arena) +{ + free(arena->buffer); + arena->offset_ptr = 0; + arena->size = 0; +} \ No newline at end of file diff --git a/Game of Life/src/memory_arena.h b/Game of Life/src/memory_arena.h new file mode 100644 index 0000000..5642de2 --- /dev/null +++ b/Game of Life/src/memory_arena.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +#define ARENA_ALIGNMENT(type) offsetof(struct { char c; type x; }, x) // generates C4116 warning + +#ifndef DEFAULT_ALIGNMENT +#define DEFAULT_ALIGNMENT (2 * sizeof(void*)) +#endif + +typedef struct { + void* buffer; + size_t size; + uintptr_t offset_ptr; +} Arena; + +Arena ArenaCreate(void* buffer, size_t buffer_size); +void* ArenaAlloc(Arena* arena, size_t size); +void* ArenaAllocAligned(Arena* arena, size_t size, size_t alignment); +void ArenaDestroy(Arena* arena); \ No newline at end of file diff --git a/Game of Life/src/parallel_for.c b/Game of Life/src/parallel_for.c deleted file mode 100644 index 8dea67f..0000000 --- a/Game of Life/src/parallel_for.c +++ /dev/null @@ -1,463 +0,0 @@ -#include "parallel_for.h" - -#if defined(__APPLE__) || defined(__linux__) -#define POSIX -#elif defined(_WIN32) - -#else -#error "Platform not supported." -#endif - -#include -#include - -#ifdef POSIX -#include -#include -#else -#include -#endif - -/****************************************************************************** -* A task descriptor specifying the input element and the address at which the * -* output element should be stored. * -******************************************************************************/ -typedef struct task_descriptor { - void* input_element; - void** output_element_address; -} task_descriptor; - -/************************************************************ -* This structure implements a concurrent array-based queue. * -************************************************************/ -typedef struct concurrent_queue { - -#ifdef POSIX - pthread_mutex_t mutex; -#elif defined(_WIN32) - CRITICAL_SECTION criticalSection; -#endif - - task_descriptor** array; - size_t begin_index; - size_t end_index; - size_t size; - size_t len; -} concurrent_queue; - -/************************************************************ -* Initializes the input concurrent queue to an empty state. * -************************************************************/ -static int concurrent_queue_init(concurrent_queue* queue, size_t len) -{ - int ret; - queue->array = malloc(len * sizeof(*queue->array)); - - if (queue->array == NULL) - { - return ERROR_FORP_MALLOC_FAIL; - } - - queue->begin_index = 0; - queue->end_index = 0; - queue->size = 0; - queue->len = len; - -#ifdef POSIX - - ret = pthread_mutex_init(&queue->mutex, NULL); - - if (ret != 0) - { - return ERROR_FORP_NO_MUTEX_INIT; - } - -#else - - InitializeCriticalSection(&queue->criticalSection); - -#endif - - return ERROR_FORP_SUCCESS; -} - -/****************************************************** -* Appends a task descriptor to the tail of the queue. * -******************************************************/ -static void concurrent_queue_enqueue(concurrent_queue* queue, - task_descriptor* descriptor) -{ - queue->array[queue->end_index] = descriptor; - queue->end_index++; - queue->size++; -} - -/****************************************************************************** -* Removes the head element from the queue. Unlike all other functions related * -* to the queue, this is one is thread-safe. * -******************************************************************************/ -static task_descriptor* concurrent_queue_dequeue(concurrent_queue* queue) -{ - task_descriptor* descriptor; - -#ifdef POSIX - pthread_mutex_lock(&queue->mutex); -#else - EnterCriticalSection(&queue->criticalSection); -#endif - - if (queue->size > 0) - { - descriptor = queue->array[queue->begin_index]; - queue->begin_index++; - queue->size--; - } - else - { - descriptor = NULL; - } - -#ifdef POSIX - pthread_mutex_unlock(&queue->mutex); -#else - LeaveCriticalSection(&queue->criticalSection); -#endif - - return descriptor; -} - -/***************************************************************************** -* Releases all the resources occupied by the queue, or namely, the mutex and * -* the array. * -*****************************************************************************/ -static int concurrent_queue_destroy(concurrent_queue* queue) -{ - int ret; - size_t i; - - for (i = 0; i < queue->len; i++) - { - free(queue->array[i]); - } - - free(queue->array); - -#ifdef POSIX - ret = pthread_mutex_destroy(&queue->mutex); - return ret == 0 ? ERROR_FORP_SUCCESS : ERROR_FORP_NO_MUTEX_DESTROY; -#else - DeleteCriticalSection(&queue->criticalSection); - return ERROR_FORP_SUCCESS; -#endif - -} - -/******************************************************* -* Returns the number of processors on Mac OS or Linux. * -*******************************************************/ -static int get_number_of_processors_apple_linux(size_t* p_number_of_processors) -{ -#ifdef POSIX - * p_number_of_processors = (size_t)sysconf(_SC_NPROCESSORS_ONLN); -#endif - - return ERROR_FORP_SUCCESS; -} - -/*********************************************** -* Returns the number of processors on Windows. * -***********************************************/ -static int get_number_of_processors_windows(size_t* p_number_of_processors) -{ -#ifdef _WIN32 - SYSTEM_INFO si; - GetSystemInfo(&si); - *p_number_of_processors = (size_t)2 * si.dwNumberOfProcessors; -#endif - - return ERROR_FORP_SUCCESS; -} - -/************************************************************** -* A portable function for returning the number of processors. * -**************************************************************/ -static int get_number_of_processors(size_t* p_number_of_processors) -{ -#ifdef POSIX - return get_number_of_processors_apple_linux(p_number_of_processors); -#else - return get_number_of_processors_windows(p_number_of_processors); -#endif -} - -/***************************************************************************** -* Specifies the worker thread arguments. Holds the queue and the function to * -* be applied to each queue element. * -*****************************************************************************/ -typedef struct worker_thread_proc_args { - concurrent_queue* queue; - void* (*func)(void*); - int return_status; -} worker_thread_proc_args; - -/********************************* -* Implements the worker threads. * -*********************************/ -static void* worker_thread_proc(void* args) -{ - worker_thread_proc_args* worker_thread_proc_arguments = - (worker_thread_proc_args*)args; - - concurrent_queue* queue = worker_thread_proc_arguments->queue; - void* (*func)(void*) = worker_thread_proc_arguments->func; - task_descriptor* task_desc; - int ret = 0; - -#ifdef POSIX - ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); -#endif - - if (ret != 0) - { - worker_thread_proc_arguments->return_status = ret; - return NULL; - } - else - { - worker_thread_proc_arguments->return_status = 0; - } - - while ((task_desc = concurrent_queue_dequeue(queue)) != NULL) - { - *task_desc->output_element_address = func(task_desc->input_element); - } - - return NULL; -} - -/*************************************** -* Cancels all the first 'len' threads. * -***************************************/ -#ifdef POSIX -static void cancel_threads(pthread_t* pthreads, size_t len) -#else -static void cancel_threads(HANDLE* threads, size_t len) -#endif -{ - size_t i; - - for (i = 0; i < len; ++i) - { - -#ifdef POSIX - pthread_cancel(pthreads[i]); -#else - TerminateThread(threads[i], 0); -#endif - - } -} - -/*********************************************************** -* The actual implementation of the parallel for construct. * -***********************************************************/ -int forp(void** input, void** output, size_t len, void* (*func)(void*)) -{ - size_t number_of_cores; - size_t szi; - int ret; - int join_ret = ERROR_FORP_SUCCESS; - concurrent_queue queue; - task_descriptor* task_desc; - worker_thread_proc_args* wtpa; - -#ifdef POSIX - - pthread_t* threads; - -#else - - HANDLE* threads; - -#endif - - if (input == NULL || output == NULL || func == NULL) - { - return ERROR_FORP_NO_ARGS; - } - - if (len == 0) - { - /***************** - * Nothing to do. * - *****************/ - return ERROR_FORP_SUCCESS; - } - - ret = get_number_of_processors(&number_of_cores); - - if (ret != ERROR_FORP_SUCCESS) - { - return ret; - } - - if (number_of_cores == 0) - { - return ERROR_FORP_UNKNOWN_CORES; - } - - if ((ret = concurrent_queue_init(&queue, len)) != ERROR_FORP_SUCCESS) - { - return ret; - } - - /************************************** - * Create a concurrent queue of tasks. * - **************************************/ - for (szi = 0; szi < len; szi++) - { - task_desc = malloc(sizeof * task_desc); - - if (task_desc == NULL) - { - concurrent_queue_destroy(&queue); - return ERROR_FORP_MALLOC_FAIL; - } - - task_desc->input_element = input[szi]; - task_desc->output_element_address = &output[szi]; - concurrent_queue_enqueue(&queue, task_desc); - - if (ret != ERROR_FORP_SUCCESS) - { - concurrent_queue_destroy(&queue); - return ret; - } - } - - /***************************** - * Create the worker threads. * - *****************************/ - threads = malloc(number_of_cores * sizeof(*threads)); - - if (threads == NULL) - { - concurrent_queue_destroy(&queue); - return ERROR_FORP_MALLOC_FAIL; - } - - wtpa = malloc(number_of_cores * sizeof(*wtpa)); - - if (wtpa == NULL) - { - free(threads); - concurrent_queue_destroy(&queue); - return ERROR_FORP_MALLOC_FAIL; - } - - for (szi = 0; szi < number_of_cores; szi++) - { - wtpa[szi].queue = &queue; - wtpa[szi].func = func; - wtpa[szi].return_status = 0; - -#ifdef POSIX - ret = pthread_create(&threads[szi], - NULL, - worker_thread_proc, - &wtpa[szi]); -#else - threads[szi] = CreateThread(NULL, - 100000, - (LPTHREAD_START_ROUTINE)worker_thread_proc, - (LPVOID)&wtpa[szi], - 0, - NULL); -#endif - - if (ret != 0) - { - cancel_threads(threads, szi); - concurrent_queue_destroy(&queue); - return ERROR_FORP_NO_THREAD; - } - - if (wtpa[szi].return_status != 0) - { - cancel_threads(threads, szi + 1); - concurrent_queue_destroy(&queue); - return ERROR_FORP_NO_SETCANCELTYPE; - } - } - - /*********************************************** - * Wait for all the worker threads to complete. * - ***********************************************/ - for (szi = 0; szi < number_of_cores; szi++) - { -#ifdef _WIN32 - - if (WaitForSingleObject(threads[szi], INFINITE) != 0 && join_ret == 0) - { - join_ret = ERROR_FORP_NO_JOIN; - } -#else - join_ret = pthread_join(threads[szi], NULL); - - if (ret != 0 && join_ret == ERROR_FORP_SUCCESS) - { - join_ret = ERROR_FORP_NO_JOIN; - } -#endif - } - - return join_ret; -} - -const char* forp_error(int error_code) -{ - switch (error_code) - { - case ERROR_FORP_SUCCESS: - return "forp succeeded."; - - case ERROR_FORP_NO_ARGS: - return "Some arguments missing."; - - case ERROR_FORP_NO_JOIN: - return "Could not join a thread."; - - case ERROR_FORP_CPU_FEOF: - return "Reached EOF while reading the number of processors."; - - case ERROR_FORP_NO_THREAD: - return "Could create a thread."; - - case ERROR_FORP_CPU_FERROR: - return "An error occured while reading the number of processors."; - - case ERROR_FORP_POPEN_FAIL: - return "Could not execute a program in popen."; - - case ERROR_FORP_MALLOC_FAIL: - return "A call to malloc returned NULL."; - - case ERROR_FORP_SSCANF_FAIL: - return "sscanf failed."; - - case ERROR_FORP_NO_MUTEX_INIT: - return "Could not initialize a mutex."; - - case ERROR_FORP_NO_MUTEX_DESTROY: - return "Could not destroy a mutex."; - - case ERROR_FORP_UNKNOWN_CORES: - return "Could not determine the number of processors."; - - case ERROR_FORP_NO_SETCANCELTYPE: - return "setcanceltype failed."; - - default: - return "Unknown error code."; - } -} \ No newline at end of file diff --git a/Game of Life/src/parallel_for.h b/Game of Life/src/parallel_for.h deleted file mode 100644 index 060b294..0000000 --- a/Game of Life/src/parallel_for.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef PARALLEL_FOR_H -#define PARALLEL_FOR_H - -#include - -#define ERROR_FORP_SUCCESS 0 -#define ERROR_FORP_NO_ARGS 1 -#define ERROR_FORP_UNKNOWN_CORES 2 -#define ERROR_FORP_NO_MUTEX_INIT 3 -#define ERROR_FORP_NO_MUTEX_DESTROY 4 -#define ERROR_FORP_MALLOC_FAIL 5 -#define ERROR_FORP_SSCANF_FAIL 6 -#define ERROR_FORP_POPEN_FAIL 7 -#define ERROR_FORP_CPU_FEOF 8 -#define ERROR_FORP_CPU_FERROR 9 -#define ERROR_FORP_NO_THREAD 10 -#define ERROR_FORP_NO_SETCANCELTYPE 11 -#define ERROR_FORP_NO_JOIN 12 - -/******************************************************************************* -* Runs a multithreaded for loop over the input array producing the results and * -* storing them in the output array. * -*******************************************************************************/ -int forp(void** input, - void** output, - size_t len, - void* (*func)(void*)); - -/************************************************************************* -* Returns a human-readable description of an error code related to forp. * -*************************************************************************/ -const char* forp_error(int error_code); - -#endif /* PARALLEL_FOR_H */ \ No newline at end of file diff --git a/Iso_C_1999_definition.pdf b/Iso_C_1999_definition.pdf new file mode 100644 index 0000000..ed517dc Binary files /dev/null and b/Iso_C_1999_definition.pdf differ diff --git a/exam test variant/exam test variant.sln b/exam test variant/exam test variant.sln new file mode 100644 index 0000000..8345a2a --- /dev/null +++ b/exam test variant/exam test variant.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35527.113 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exam test variant", "exam test variant\exam test variant.vcxproj", "{4BD82D12-E491-4ACC-9A31-E269F2A6F346}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Debug|x64.ActiveCfg = Debug|x64 + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Debug|x64.Build.0 = Debug|x64 + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Debug|x86.ActiveCfg = Debug|Win32 + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Debug|x86.Build.0 = Debug|Win32 + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Release|x64.ActiveCfg = Release|x64 + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Release|x64.Build.0 = Release|x64 + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Release|x86.ActiveCfg = Release|Win32 + {4BD82D12-E491-4ACC-9A31-E269F2A6F346}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/exam test variant/exam test variant/exam test variant.vcxproj b/exam test variant/exam test variant/exam test variant.vcxproj new file mode 100644 index 0000000..4d3aa87 --- /dev/null +++ b/exam test variant/exam test variant/exam test variant.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {4bd82d12-e491-4acc-9a31-e269f2a6f346} + examtestvariant + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/exam test variant/exam test variant/exam test variant.vcxproj.filters b/exam test variant/exam test variant/exam test variant.vcxproj.filters new file mode 100644 index 0000000..48814f7 --- /dev/null +++ b/exam test variant/exam test variant/exam test variant.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Исходные файлы + + + \ No newline at end of file diff --git a/exam test variant/exam test variant/main.c b/exam test variant/exam test variant/main.c new file mode 100644 index 0000000..8c346fa --- /dev/null +++ b/exam test variant/exam test variant/main.c @@ -0,0 +1,199 @@ +#define _CRT_SECURE_NO_WARNINGS +#include +#include +#include + +int N1; +int N2; +int M2; + +#define MAX_N2 20 +#define MAX_M2 20 + +int A1[20]; +int A2[MAX_N2][MAX_M2]; + +void loadLists(char filepath[]) +{ + FILE* fin = fopen(filepath, "r"); + + if (fin == NULL) { + printf("File didn't open!\n"); + return; + } + + fscanf(fin, "%d", &N1); + + for (int i = 0; i < N1; i++) { + fscanf(fin, "%d", &A1[i]); + } + + fscanf(fin, "%d", &N2); + fscanf(fin, "%d", &M2); + + for (int n = 0; n < N2; n++) { + for (int m = 0; m < M2; m++) { + fscanf(fin, "%d", &A2[n][m]); + } + } + + fclose(fin); +} + +void saveLists(char filepath[]) +{ + FILE* fout = fopen(filepath, "w"); + if (fopen == NULL) { + printf("File didn't create!\n"); + return; + } + + fprintf(fout, "%d\n", N1); + for (int i = 0; i < N1; i++) { + fprintf(fout, "%d ", A1[i]); + } + fprintf(fout, "\n"); + + fprintf(fout, "%d %d\n", N2, M2); + + for (int n = 0; n < N2; n++) { + for (int m = 0; m < M2; m++) { + fprintf(fout, "%d ", A2[n][m]); + } + fprintf(fout, "\n"); + } + + fclose(fout); +} + +void printLists() +{ + printf("===== =====\n"); + printf("A1[%d]: ", N1); + for (int i = 0; i < N1; i++) { + printf("%d ", A1[i]); + } + printf("\n\n"); + + printf("A2[%d][%d]:\n", N2, M2); + for (int n = 0; n < N2; n++) { + for (int m = 0; m < M2; m++) { + printf("%2d ", A2[n][m]); + } + printf("\n"); + } + printf("=====================================\n"); +} + +void task2() +{ + int firstEvenId = 0; + int lastEvenId = 0; + + for (int i = 0; i < N1; i++) { + if (A1[i] % 2 == 0) { + firstEvenId = i; + break; + } + } + + for (int i = 0; i < N1; i++) { + if (A1[i] % 2 == 0) { + lastEvenId = i; + } + } + + for (int i = firstEvenId + 1; i < lastEvenId; i++) { + if (A1[i] % 2 == 0) { + A1[i] += 100; + } + } + + printf("> 2\n"); +} + +void deleteRow(int row) +{ + for (int n = row; n < N2 - 1; n++) { + for (int m = 0; m < M2; m++) { + A2[n][m] = A2[n + 1][m]; + } + } + N2 -= 1; +} + +void addColumn() { + if (M2 + 1 <= MAX_M2) { + for (int n = 0; n < N2; n++) { + A2[n][M2] = 0; + } + M2++; + } + else { + printf(" !\n"); + } +} + +void insertColumn(int column) { + if (M2 + 1 <= MAX_M2) { + for (int n = 0; n < N2; n++) { + for (int m = M2; m > column; m--) { + A2[n][m] = A2[n][m - 1]; + } + } + for (int n = 0; n < N2; n++) { + A2[n][column] = 0; + } + M2++; + } + else { + printf(" !\n"); + } +} + +void insertRow(int row) { + if (N2 + 1 <= MAX_N2) { + for (int n = N2; n > row; n--) { + for (int m = 0; m < M2; m++) { + A2[n][m] = A2[n - 1][m]; + } + } + for (int m = 0; m < M2; m++) { + A2[row][m] = 0; + } + N2++; + } + else { + printf(" !\n"); + } +} + +void task3() { + for (int n = 0; n < N2; n++) { + for (int m = 0; m < M2; m++) { + if (A2[n][m] < 0) { + deleteRow(n); + break; + } + } + } + printf("> 3\n"); +} + +int main() +{ + SetConsoleCP(1251); + SetConsoleOutputCP(1251); + + loadLists("test.txt"); + printLists(); + + task2(); + task3(); + + printLists(); + + saveLists("out.txt"); + + return 0; +} \ No newline at end of file diff --git a/exam test variant/exam test variant/out.txt b/exam test variant/exam test variant/out.txt new file mode 100644 index 0000000..95f0dcc --- /dev/null +++ b/exam test variant/exam test variant/out.txt @@ -0,0 +1,5 @@ +6 +1 2 104 106 7 8 +2 4 +-2 -1 0 1 +2 3 4 3 diff --git a/exam test variant/exam test variant/test.txt b/exam test variant/exam test variant/test.txt new file mode 100644 index 0000000..88cb37e --- /dev/null +++ b/exam test variant/exam test variant/test.txt @@ -0,0 +1,6 @@ +6 +1 2 4 6 7 8 +3 4 +-2 -1 0 1 +2 3 4 3 +2 1 0 -1 \ No newline at end of file diff --git a/lab15/lab15/main.c b/lab15/lab15/main.c index a107c01..12dd495 100644 --- a/lab15/lab15/main.c +++ b/lab15/lab15/main.c @@ -1,324 +1,324 @@ -#include -#include -#include - -#define MAX_M 10 -#define MAX_N 10 - -int m = 3; -int n = 3; - -int arr[MAX_M][MAX_N] = { - {1, 2, 3}, - {4, 5, 6}, - {7, 8, 9} -}; - -void printarr() { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - printf("%2d ", arr[i][j]); - } - printf("\n"); - } -} - -void fill_with_indexes() { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - arr[i][j] = (i * 10) + j; - } - } -} - -void fillZero() { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - arr[i][j] = 0; - } - } -} - -void fillRand() { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - arr[i][j] = rand() % 10; - } - } -} - -void findMin() { - int min = arr[0][0]; - int iMin = 0; - int jMin = 0; - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - if (arr[i][j] < min) { - printf("min = %d\n", arr[i][j]); - printf("imin = %d\n", i); - printf("jmin = %d\n", j); - } - } - } - -} - -void deleteRow(int row) { - for (int i = row; i < m - 1; i++) { - for (int j = 0; j < n; j++) { - arr[i][j] = arr[i + 1][j]; - } - } - m--; -} - -void addColumn() { - if (n + 1 <= MAX_N) { - for (int i = 0; i < m; i++) { - arr[i][n] = 0; - } - n++; - } - else { - printf("Достигнут максимум колонок!\n"); - } -} - -void insertColumn(int column) { - if (n + 1 <= MAX_N) { - for (int i = 0; i < m; i++) { - for (int j = n; j > column; j--) { - arr[i][j] = arr[i][j - 1]; - } - } - for (int i = 0; i < m; i++) { - arr[i][column] = 0; - } - n++; - } - else { - printf("Достигнут максимум колонок!\n"); - } -} - -void insertRow(int row) { - if (m + 1 <= MAX_M) { - for (int i = m; i > row; i--) { - for (int j = 0; j < n; j++) { - arr[i][j] = arr[i - 1][j]; - } - } - for (int i = 0; i < n; i++) { - arr[row][i] = 0; - } - m++; - } - else { - printf("Достигнут максимум строк!\n"); - } -} - -void odd10x() { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (arr[i][j] % 2 != 0) arr[i][j] *= 10; - } - } -} - -void crat10() { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (arr[i][j] % 10 == 0) arr[i][j] /= 10; - } - } -} - -void inputArr() { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - printf("a%d%d = ", i, j); - scanf_s("%d", &arr[i][j]); - } - } -} - -void save() { - FILE* fout = fopen("savefile.txt", "w"); - if (fout == NULL) { - puts("Невозможно открыть файл"); - return; - } - - fprintf(fout, "%d %d\n", m, n); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - fprintf(fout, "%2d ", arr[i][j]); - } - fprintf(fout, "\n"); - } - - fclose(fout); -} - -void load() { - FILE* fin = fopen("savefile.txt", "r"); - if (fin == NULL) { - puts("Невозможно открыть файл"); - return; - } - - fscanf_s(fin, "%d%d", &m, &n); - if (m > MAX_M || n > MAX_N) { - printf("Слишком большой массив в файле!"); - return; - } - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - fscanf_s(fin, "%d", &arr[i][j]); - } - } - - fclose(fin); -} - -void duplicateColumn(int column) { - insertColumn(column); - for (int i = 0; i < m; i++) { - arr[i][column] = arr[i][column + 1]; - } -} - -int count(int num, int arr[], int len) { - int count = 0; - for (int i = 0; i < len; i++) { - if (arr[i] == num) count += 1; - } - return count; -} - -void row0() { - for (int i = 0; i < m; i++) { - if (count(0, arr[i], n) > 2) { - for (int j = 0; j < n; j++) { - arr[i][j] = 0; - } - } - } -} - -void duplicateRow(int row) { - insertRow(row); - for (int j = 0; j < n; j++) { - arr[row][j] = arr[row + 1][j]; - } -} - -void dupRow0() { - for (int i = 0; i < m; i++) { - if (count(0, arr[i], n) > 0) { - duplicateRow(i); - i++; - } - } -} - -int main() { - SetConsoleCP(1251); - SetConsoleOutputCP(1251); - - int tmp; - - int n = 0; - do { - puts("\n"); - printf("Содержимое массива:\n"); - printarr(arr); - puts("Выберите программу"); - puts("1) Заполнение значениями i * 10 + j"); - puts("2) Заполнение нулями"); - puts("3) Заполнение случайными числами от 0 до 9"); - puts("4) Найти минимальный элемент"); - puts("5) Удалить строку"); - puts("6) Добавить пустую колонку"); - puts("7) Все нечетные увеличить в 10 раз"); - puts("8) Все кратные 10 уменьшить в 10 раз"); - puts("9) Ввести массив с клавиатуры"); - puts("10) Сохранить в файл"); - puts("11) Загрузить из файла"); - puts("12) Вставить пустую колонку"); - puts("13) Продублировать заданный столбец массива"); - puts("14) Обнулить элементы тех строк, в которых встречается более двух нулевых элементов"); - puts("15) Продублировать те строки, в которых встречаются нулевые элементы"); - puts(""); - puts("0) Выйти из программы"); - - while (scanf_s(" %d", &n) != 1) { - scanf_s("%*[^\n]"); - scanf_s("%*c"); - } - puts(""); - - switch (n) - { - case 1: - fill_with_indexes(); - break; - case 2: - fillZero(); - break; - case 3: - fillRand(); - break; - case 4: - findMin(); - break; - case 5: - printf("Какую строку удалить: "); - scanf_s("%d", &tmp); - deleteRow(tmp); - break; - case 6: - addColumn(); - break; - case 7: - odd10x(); - break; - case 8: - crat10(); - break; - case 9: - inputArr(); - break; - case 10: - save(); - break; - case 11: - load(); - break; - case 12: - printf("На каком индексе вставить колонку: "); - scanf_s("%d", &tmp); - insertColumn(tmp); - break; - case 13: - printf("На каком индексе одублировать столбец: "); - scanf_s("%d", &tmp); - duplicateColumn(tmp); - break; - case 14: - row0(); - break; - case 15: - dupRow0(); - break; - case 0: - puts("Досвидания :3"); - break; - default: - puts("Ошибка: неправильное N"); - break; - } - } while (n != 0); - return 0; -} +#include +#include +#include + +#define MAX_M 10 +#define MAX_N 10 + +int m = 3; +int n = 3; + +int arr[MAX_M][MAX_N] = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; + +void printarr() { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + printf("%2d ", arr[i][j]); + } + printf("\n"); + } +} + +void fill_with_indexes() { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + arr[i][j] = (i * 10) + j; + } + } +} + +void fillZero() { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + arr[i][j] = 0; + } + } +} + +void fillRand() { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + arr[i][j] = rand() % 10; + } + } +} + +void findMin() { + int min = arr[0][0]; + int iMin = 0; + int jMin = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (arr[i][j] < min) { + printf("min = %d\n", arr[i][j]); + printf("imin = %d\n", i); + printf("jmin = %d\n", j); + } + } + } + +} + +void deleteRow(int row) { + for (int i = row; i < m - 1; i++) { + for (int j = 0; j < n; j++) { + arr[i][j] = arr[i + 1][j]; + } + } + m--; +} + +void addColumn() { + if (n + 1 <= MAX_N) { + for (int i = 0; i < m; i++) { + arr[i][n] = 0; + } + n++; + } + else { + printf("Достигнут максимум колонок!\n"); + } +} + +void insertColumn(int column) { + if (n + 1 <= MAX_N) { + for (int i = 0; i < m; i++) { + for (int j = n; j > column; j--) { + arr[i][j] = arr[i][j - 1]; + } + } + for (int i = 0; i < m; i++) { + arr[i][column] = 0; + } + n++; + } + else { + printf("Достигнут максимум колонок!\n"); + } +} + +void insertRow(int row) { + if (m + 1 <= MAX_M) { + for (int i = m; i > row; i--) { + for (int j = 0; j < n; j++) { + arr[i][j] = arr[i - 1][j]; + } + } + for (int i = 0; i < n; i++) { + arr[row][i] = 0; + } + m++; + } + else { + printf("Достигнут максимум строк!\n"); + } +} + +void odd10x() { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (arr[i][j] % 2 != 0) arr[i][j] *= 10; + } + } +} + +void crat10() { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (arr[i][j] % 10 == 0) arr[i][j] /= 10; + } + } +} + +void inputArr() { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + printf("a%d%d = ", i, j); + scanf_s("%d", &arr[i][j]); + } + } +} + +void save() { + FILE* fout = fopen("savefile.txt", "w"); + if (fout == NULL) { + puts("Невозможно открыть файл"); + return; + } + + fprintf(fout, "%d %d\n", m, n); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + fprintf(fout, "%2d ", arr[i][j]); + } + fprintf(fout, "\n"); + } + + fclose(fout); +} + +void load() { + FILE* fin = fopen("savefile.txt", "r"); + if (fin == NULL) { + puts("Невозможно открыть файл"); + return; + } + + fscanf_s(fin, "%d%d", &m, &n); + if (m > MAX_M || n > MAX_N) { + printf("Слишком большой массив в файле!"); + return; + } + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + fscanf_s(fin, "%d", &arr[i][j]); + } + } + + fclose(fin); +} + +void duplicateColumn(int column) { + insertColumn(column); + for (int i = 0; i < m; i++) { + arr[i][column] = arr[i][column + 1]; + } +} + +int count(int num, int arr[], int len) { + int count = 0; + for (int i = 0; i < len; i++) { + if (arr[i] == num) count += 1; + } + return count; +} + +void row0() { + for (int i = 0; i < m; i++) { + if (count(0, arr[i], n) > 2) { + for (int j = 0; j < n; j++) { + arr[i][j] = 0; + } + } + } +} + +void duplicateRow(int row) { + insertRow(row); + for (int j = 0; j < n; j++) { + arr[row][j] = arr[row + 1][j]; + } +} + +void dupRow0() { + for (int i = 0; i < m; i++) { + if (count(0, arr[i], n) > 0) { + duplicateRow(i); + i++; + } + } +} + +int main() { + SetConsoleCP(1251); + SetConsoleOutputCP(1251); + + int tmp; + + int n = 0; + do { + puts("\n"); + printf("Содержимое массива:\n"); + printarr(arr); + puts("Выберите программу"); + puts("1) Заполнение значениями i * 10 + j"); + puts("2) Заполнение нулями"); + puts("3) Заполнение случайными числами от 0 до 9"); + puts("4) Найти минимальный элемент"); + puts("5) Удалить строку"); + puts("6) Добавить пустую колонку"); + puts("7) Все нечетные увеличить в 10 раз"); + puts("8) Все кратные 10 уменьшить в 10 раз"); + puts("9) Ввести массив с клавиатуры"); + puts("10) Сохранить в файл"); + puts("11) Загрузить из файла"); + puts("12) Вставить пустую колонку"); + puts("13) Продублировать заданный столбец массива"); + puts("14) Обнулить элементы тех строк, в которых встречается более двух нулевых элементов"); + puts("15) Продублировать те строки, в которых встречаются нулевые элементы"); + puts(""); + puts("0) Выйти из программы"); + + while (scanf_s(" %d", &n) != 1) { + scanf_s("%*[^\n]"); + scanf_s("%*c"); + } + puts(""); + + switch (n) + { + case 1: + fill_with_indexes(); + break; + case 2: + fillZero(); + break; + case 3: + fillRand(); + break; + case 4: + findMin(); + break; + case 5: + printf("Какую строку удалить: "); + scanf_s("%d", &tmp); + deleteRow(tmp); + break; + case 6: + addColumn(); + break; + case 7: + odd10x(); + break; + case 8: + crat10(); + break; + case 9: + inputArr(); + break; + case 10: + save(); + break; + case 11: + load(); + break; + case 12: + printf("На каком индексе вставить колонку: "); + scanf_s("%d", &tmp); + insertColumn(tmp); + break; + case 13: + printf("На каком индексе одублировать столбец: "); + scanf_s("%d", &tmp); + duplicateColumn(tmp); + break; + case 14: + row0(); + break; + case 15: + dupRow0(); + break; + case 0: + puts("Досвидания :3"); + break; + default: + puts("Ошибка: неправильное N"); + break; + } + } while (n != 0); + return 0; +} diff --git a/lab16 with raylib/lab16 with raylib/lab16 with raylib.vcxproj b/lab16 with raylib/lab16 with raylib/lab16 with raylib.vcxproj index c4f2734..d5c66c0 100644 --- a/lab16 with raylib/lab16 with raylib/lab16 with raylib.vcxproj +++ b/lab16 with raylib/lab16 with raylib/lab16 with raylib.vcxproj @@ -110,7 +110,7 @@ Console true $(SolutionDir)\lib - raylib.lib;opengl32.lib;winmm.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + raylib33test.lib;opengl32.lib;winmm.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) @@ -129,7 +129,7 @@ true true $(SolutionDir)\lib - raylib.lib;opengl32.lib;winmm.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + raylib33test.lib;opengl32.lib;winmm.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) mainCRTStartup diff --git a/lab16 with raylib/lib/raylib33test.lib b/lab16 with raylib/lib/raylib33test.lib new file mode 100644 index 0000000..249ba23 Binary files /dev/null and b/lab16 with raylib/lib/raylib33test.lib differ diff --git a/lab16 with raylib/lib/raylib.lib b/lab16 with raylib/lib/raylib43.lib similarity index 100% rename from lab16 with raylib/lib/raylib.lib rename to lab16 with raylib/lib/raylib43.lib diff --git a/memory_arena/src/memory_arena.c b/memory_arena/src/memory_arena.c index ff1a68a..c492265 100644 --- a/memory_arena/src/memory_arena.c +++ b/memory_arena/src/memory_arena.c @@ -57,7 +57,7 @@ void* ArenaAlloc(Arena* arena, size_t size) return ArenaAllocAligned(arena, size, DEFAULT_ALIGNMENT); } -Arena ArenaInit(size_t buffer_size) +Arena ArenaCreate(size_t buffer_size) { void* buffer = SafeMalloc(buffer_size); return (Arena) { diff --git a/memory_arena/src/memory_arena.h b/memory_arena/src/memory_arena.h index 4b6ba34..732f2d7 100644 --- a/memory_arena/src/memory_arena.h +++ b/memory_arena/src/memory_arena.h @@ -15,7 +15,7 @@ typedef struct { uintptr_t offset_ptr; } Arena; -Arena ArenaInit(size_t buffer_size); +Arena ArenaCreate(size_t buffer_size); void* ArenaAlloc(Arena* arena, size_t size); void* ArenaAllocAligned(Arena* arena, size_t size, size_t alignment); void ArenaDestroy(Arena* arena); \ No newline at end of file diff --git a/threads/main.c b/threads/main.c index d83858b..4cb7b38 100644 --- a/threads/main.c +++ b/threads/main.c @@ -1,15 +1,37 @@ -#include -#include -#include - -void thrd_func(int* i) { - printf_s("%d\n", *i); -} - -int main() { - thrd_t* threads[10]; - for (int i = 0; i < 10; i++) { - thrd_create(threads[i], thrd_func, &i); - } - return 0; +#include +#include +#include +#include +#include +#include + +#include + +int thrd_func(void* i) { + int* arg_ptr = (int*)i; + + unsigned long long y = 1; + for (unsigned long long x = 0; x < 1000ULL * 1000 * 1000 * 10; x++) { + y += x; + } + + printf("lol %d) y=%llu\n", *arg_ptr, y); + return *arg_ptr; +} + +int main() { + thrd_t threads[10]; + int args[10]; + int results[10]; + for (int i = 0; i < 10; i++) { + args[i] = i; + thrd_create(&threads[i], thrd_func, &args[i]); + printf("%d) thread created\n", i); + } + printf("-----------\n"); + for (int i = 0; i < 10; i++) { + thrd_join(threads[i], &results[i]); + } + + return 0; } \ No newline at end of file diff --git a/threads/threads.vcxproj b/threads/threads.vcxproj index 79454ee..c5628a0 100644 --- a/threads/threads.vcxproj +++ b/threads/threads.vcxproj @@ -1,135 +1,137 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 17.0 - Win32Proj - {0d89d366-f1ee-4ff3-af21-0e209449319e} - threads - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {0d89d366-f1ee-4ff3-af21-0e209449319e} + threads + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdc17 + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdc17 + + + Console + true + true + true + + + + + + + + \ No newline at end of file