diff --git a/term2/seminar04_factory/CMakeLists.txt b/term2/seminar04_factory/CMakeLists.txt new file mode 100644 index 0000000..1fb9fb7 --- /dev/null +++ b/term2/seminar04_factory/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 2.8.0) +project(skilltree) + +# Найдём библиотеку SFML в системе +find_package(SFML 2.5 REQUIRED graphics window system) + +# Создадим исполняемый файл по имени player_movement из исходных файлов +add_executable(skilltree src/skilltree.cpp) + +# Укажем, что нужно использовать стандарт C++20 +target_compile_features(skilltree PRIVATE cxx_std_20) + +# Подключим библиотеку SFML к нашему проекту +target_link_libraries(skilltree PRIVATE sfml-graphics sfml-system sfml-window) + +file(COPY src/icons DESTINATION .) diff --git a/term2/seminar04_factory/src/icons/icon_bomb.png b/term2/seminar04_factory/src/icons/icon_bomb.png new file mode 100644 index 0000000..2d9c6f1 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_bomb.png differ diff --git a/term2/seminar04_factory/src/icons/icon_claws.png b/term2/seminar04_factory/src/icons/icon_claws.png new file mode 100644 index 0000000..b35629a Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_claws.png differ diff --git a/term2/seminar04_factory/src/icons/icon_earthquake.png b/term2/seminar04_factory/src/icons/icon_earthquake.png new file mode 100644 index 0000000..83faad7 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_earthquake.png differ diff --git a/term2/seminar04_factory/src/icons/icon_eye.png b/term2/seminar04_factory/src/icons/icon_eye.png new file mode 100644 index 0000000..652a387 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_eye.png differ diff --git a/term2/seminar04_factory/src/icons/icon_fireball.png b/term2/seminar04_factory/src/icons/icon_fireball.png new file mode 100644 index 0000000..483eaa4 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_fireball.png differ diff --git a/term2/seminar04_factory/src/icons/icon_hand.png b/term2/seminar04_factory/src/icons/icon_hand.png new file mode 100644 index 0000000..676d85f Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_hand.png differ diff --git a/term2/seminar04_factory/src/icons/icon_lightning.png b/term2/seminar04_factory/src/icons/icon_lightning.png new file mode 100644 index 0000000..d54c912 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_lightning.png differ diff --git a/term2/seminar04_factory/src/icons/icon_meteorite.png b/term2/seminar04_factory/src/icons/icon_meteorite.png new file mode 100644 index 0000000..a6a6eb6 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_meteorite.png differ diff --git a/term2/seminar04_factory/src/icons/icon_rect_chain.png b/term2/seminar04_factory/src/icons/icon_rect_chain.png new file mode 100644 index 0000000..e21c576 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_rect_chain.png differ diff --git a/term2/seminar04_factory/src/icons/icon_rect_freeze.png b/term2/seminar04_factory/src/icons/icon_rect_freeze.png new file mode 100644 index 0000000..a3c8ec2 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_rect_freeze.png differ diff --git a/term2/seminar04_factory/src/icons/icon_rect_sword.png b/term2/seminar04_factory/src/icons/icon_rect_sword.png new file mode 100644 index 0000000..5b24c37 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_rect_sword.png differ diff --git a/term2/seminar04_factory/src/icons/icon_shield.png b/term2/seminar04_factory/src/icons/icon_shield.png new file mode 100644 index 0000000..d3baf8d Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_shield.png differ diff --git a/term2/seminar04_factory/src/icons/icon_shuriken.png b/term2/seminar04_factory/src/icons/icon_shuriken.png new file mode 100644 index 0000000..9ed3f54 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_shuriken.png differ diff --git a/term2/seminar04_factory/src/icons/icon_spikes.png b/term2/seminar04_factory/src/icons/icon_spikes.png new file mode 100644 index 0000000..fceb4c5 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_spikes.png differ diff --git a/term2/seminar04_factory/src/icons/icon_sword.png b/term2/seminar04_factory/src/icons/icon_sword.png new file mode 100644 index 0000000..41af946 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_sword.png differ diff --git a/term2/seminar04_factory/src/icons/icon_wind.png b/term2/seminar04_factory/src/icons/icon_wind.png new file mode 100644 index 0000000..ff35c82 Binary files /dev/null and b/term2/seminar04_factory/src/icons/icon_wind.png differ diff --git a/term2/seminar04_factory/src/sfline.hpp b/term2/seminar04_factory/src/sfline.hpp new file mode 100644 index 0000000..af68663 --- /dev/null +++ b/term2/seminar04_factory/src/sfline.hpp @@ -0,0 +1,35 @@ +#pragma once +#include + +class sfLine +{ +public: + sfLine(const sf::Vector2f& point1, const sf::Vector2f& point2, sf::Color color, float thickness): + color(color), thickness(thickness) + { + sf::Vector2f direction = point2 - point1; + sf::Vector2f unitDirection = direction/std::sqrt(direction.x*direction.x+direction.y*direction.y); + sf::Vector2f unitPerpendicular(-unitDirection.y,unitDirection.x); + + sf::Vector2f offset = (thickness/2.f)*unitPerpendicular; + + vertices[0].position = point1 + offset; + vertices[1].position = point2 + offset; + vertices[2].position = point2 - offset; + vertices[3].position = point1 - offset; + + for (int i=0; i<4; ++i) + vertices[i].color = color; + } + + void draw(sf::RenderTarget &target) const + { + target.draw(vertices, 4, sf::Quads); + } + + +private: + sf::Vertex vertices[4]; + float thickness; + sf::Color color; +}; diff --git a/term2/seminar04_factory/src/skilltree.cpp b/term2/seminar04_factory/src/skilltree.cpp new file mode 100644 index 0000000..711dcdb --- /dev/null +++ b/term2/seminar04_factory/src/skilltree.cpp @@ -0,0 +1,405 @@ +#include +#include +#include +#include +#include +#include "sfline.hpp" +#include + +using std::cout, std::endl; + + + +/* + Icons from Ken111 + https://www.flaticon.com/ru/packs/game-skill?k=1650700359068 + +*/ + + +class Node +{ +public: + Node(sf::Vector2f& position) + : mPosition{position} + { + } + + enum class State + { + Blocked, + Unblocked, + Activated + }; + + + void addChild(const std::shared_ptr& child) + { + mChildren.push_back(child); + } + + sf::Vector2f getPosition() + { + return mPosition; + } + + void unblock() + { + mState = State::Unblocked; + } + + void block() + { + mState = State::Blocked; + for (const auto& child : mChildren) + child->block(); + } + + virtual bool collisionTest(sf::Vector2f mouseCoords) = 0; + + void onMousePressed(sf::Vector2f mouseCoords) + { + if (mState == State::Blocked) + return; + + if (collisionTest(mouseCoords)) + { + if (mState == State::Unblocked) + { + mState = State::Activated; + for (const auto& child : mChildren) + child->unblock(); + } + + else if (mState == State::Activated) + { + mState = State::Unblocked; + for (const auto& child : mChildren) + child->block(); + } + } + + for (const auto& child : mChildren) + { + child->onMousePressed(mouseCoords); + } + } + virtual void draw(sf::RenderWindow& window) const = 0; + +protected: + + sf::Vector2f mPosition {0, 0}; + State mState = State::Blocked; + + std::vector> mChildren {}; + + inline static sf::Color sBlockedColor {40, 40, 40}; + inline static sf::Color sUnlockedColor {80, 80, 40}; + inline static sf::Color sActivatedColor {160, 160, 40}; +}; + + +class HitNode : public Node +{ +public: + + HitNode(sf::Vector2f position) + : Node{position} + { + } + + virtual sf::String getIconPath() = 0; + + void loadTexture() + { + sf::String texturePath = getIconPath(); + if (!mTexture.loadFromFile(texturePath)) + { + cout << "Error! Can't load file " << texturePath.toAnsiString() << endl; + std::exit(1); + } + mSprite.setTexture(mTexture); + mSprite.setOrigin({mRadius, mRadius}); + mSprite.setPosition(mPosition); + } + + + sf::Color getCurrentColor() const + { + if (mState == State::Unblocked) + return sUnlockedColor; + else if (mState == State::Activated) + return sActivatedColor; + return sBlockedColor; + } + + void draw(sf::RenderWindow& window) const + { + for (const auto& el : mChildren) + { + sfLine connectionLine {mPosition, el->getPosition(), getCurrentColor(), 2}; + connectionLine.draw(window); + el->draw(window); + } + + static sf::CircleShape shape(mRadius); + shape.setOrigin({mRadius, mRadius}); + shape.setFillColor(getCurrentColor()); + shape.setPosition(mPosition); + window.draw(shape); + + window.draw(mSprite); + } + + bool collisionTest(sf::Vector2f mouseCoords) override + { + sf::Vector2f d = mPosition - mouseCoords; + return d.x * d.x + d.y * d.y < mRadius * mRadius; + } + +private: + + sf::Texture mTexture; + sf::Sprite mSprite; + + float mRadius = 24; + bool mIsActivated = false; +}; + + + +class BombSkillNode : public HitNode +{ +public: + BombSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_bomb.png"}; + } +}; + +class SpikesSkillNode : public HitNode +{ +public: + SpikesSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_spikes.png"}; + } +}; + + +class LightningSkillNode : public HitNode +{ +public: + LightningSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_lightning.png"}; + } +}; + + +class EyeSkillNode : public HitNode +{ +public: + EyeSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_eye.png"}; + } +}; + + +class ClawsSkillNode : public HitNode +{ +public: + ClawsSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_claws.png"}; + } +}; + +class ShieldSkillNode : public HitNode +{ +public: + ShieldSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_shield.png"}; + } +}; + + +class SwordSkillNode : public HitNode +{ +public: + SwordSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_sword.png"}; + } +}; + + +class ShurikenSkillNode : public HitNode +{ +public: + ShurikenSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_shuriken.png"}; + } +}; + +class WindSkillNode : public HitNode +{ +public: + WindSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_shuriken.png"}; + } +}; + + +class MeteoriteSkillNode : public HitNode +{ +public: + MeteoriteSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_meteorite.png"}; + } +}; + +class HandSkillNode : public HitNode +{ +public: + HandSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_hand.png"}; + } +}; + +class EarthquakeSkillNode : public HitNode +{ +public: + EarthquakeSkillNode(sf::Vector2f position) : HitNode{position} + { + loadTexture(); + } + + sf::String getIconPath() override + { + return sf::String{"icons/icon_earthquake.png"}; + } +}; + + +std::shared_ptr createSkillTree() +{ + std::shared_ptr root {new LightningSkillNode({400, 500})}; + std::shared_ptr a {new ShurikenSkillNode({200, 400})}; + std::shared_ptr b {new BombSkillNode({400, 400})}; + std::shared_ptr c {new EyeSkillNode({600, 400})}; + root->addChild(a); + root->addChild(b); + root->addChild(c); + + a->addChild(std::shared_ptr{new ShieldSkillNode({100, 200})}); + a->addChild(std::shared_ptr{new SwordSkillNode({200, 200})}); + a->addChild(std::shared_ptr{new EarthquakeSkillNode({300, 200})}); + + b->addChild(std::shared_ptr{new HandSkillNode({400, 200})}); + b->addChild(std::shared_ptr{new MeteoriteSkillNode({500, 200})}); + std::shared_ptr e {new BombSkillNode({600, 200})}; + b->addChild(e); + e->addChild(std::shared_ptr{new WindSkillNode({500, 100})}); + e->addChild(std::shared_ptr{new SwordSkillNode({600, 100})}); + c->addChild(std::shared_ptr{new EyeSkillNode({700, 200})}); + + return root; +} + + +int main() +{ + sf::ContextSettings settings; + settings.antialiasingLevel = 8; + sf::RenderWindow window(sf::VideoMode(1000, 800), "Skill Tree", sf::Style::Close, settings); + window.setFramerateLimit(60); + + std::shared_ptr root = createSkillTree(); + root->unblock(); + + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + if (event.type == sf::Event::Closed) + window.close(); + + + if (event.type == sf::Event::MouseButtonPressed) + { + sf::Vector2f mouseCoords = window.mapPixelToCoords({event.mouseButton.x, event.mouseButton.y}); + root->onMousePressed(mouseCoords); + } + } + + + window.clear(sf::Color::Black); + root->draw(window); + window.display(); + } + + return 0; +} \ No newline at end of file diff --git a/term2/seminar04_factory/task_skilltree.pdf b/term2/seminar04_factory/task_skilltree.pdf new file mode 100644 index 0000000..6b2d5fc Binary files /dev/null and b/term2/seminar04_factory/task_skilltree.pdf differ diff --git a/term2/seminar_thread/01problem_paralel_max_iterators.cpp b/term2/seminar_thread/01problem_paralel_max_iterators.cpp new file mode 100644 index 0000000..1bdcf1c --- /dev/null +++ b/term2/seminar_thread/01problem_paralel_max_iterators.cpp @@ -0,0 +1,75 @@ +/* + Задача: + + В данном примере написана функция шаблонная getMaxId, которая находит максимум из чисел в векторе. + При этом вычисления проходят однопоточно. + + + Вам нужно написать шаблонную функцию + + size_t getMaxIdPar(int n, RandIt start, RandIt finish) + + которая будет делать то же самое, но только использовать для этого n потоков. + Проверить, что эта функция будет работать и для других контейнеров и типов хранящихся в них данных. + Например, для: + + std::deque d {1.2, 5.1, 8.2, 1.0, 0.2, 5.0, 7.8}; +*/ + + + + + + + + +#include +#include +#include +#include +#include +#include +#include +using std::cout, std::endl, std::size_t; +using namespace std::chrono_literals; + + + +template +size_t getMaxId(RandIt start, RandIt finish) +{ + RandIt maxIt = start; + for (auto it = start; it != finish; ++it) + { + if (*it > *maxIt) + maxIt = it; + } + return maxIt - start; +} + + +int main() +{ + cout << "Generating numbers!" << endl; + std::vector numbers(5e8); + numbers[0] = 123456789; + for (size_t i = 1; i < numbers.size(); ++i) + { + numbers[i] = numbers[i - 1] * i + 1; + } + cout << "Numbers generated!" << endl; + + + + + auto start = std::chrono::high_resolution_clock::now(); + + + size_t id = getMaxId(numbers.begin(), numbers.end()); + cout << "Maximum = " << numbers[id] << endl; + + + auto end = std::chrono::high_resolution_clock::now(); + cout << "Time to calclulate max = " << std::chrono::duration_cast(end - start).count() + << " milliseconds." << endl; +} \ No newline at end of file diff --git a/term2/seminar_thread/02problem_parallel_transform.cpp b/term2/seminar_thread/02problem_parallel_transform.cpp new file mode 100644 index 0000000..8fc4268 --- /dev/null +++ b/term2/seminar_thread/02problem_parallel_transform.cpp @@ -0,0 +1,9 @@ +/* + Задача: + + + Напишите шаблонную функцию parallelTransform, аналог функции std::transform + из библиотеки algorithm. + Количество потоков в этот раз не передавайте через аргументы функции, а узнайте + внутри самой функции с помощью std::thread::hardware_concurrency(). +*/ \ No newline at end of file