Skip to content

Commit f1fbe70

Browse files
committed
Update readMe and JSON task
1 parent 1ab5fd6 commit f1fbe70

File tree

7 files changed

+89
-28
lines changed

7 files changed

+89
-28
lines changed

.vscode/tasks.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
"GraphBuilding/node.cpp",
4040
"-Iheaders",
4141
"-I\"${workspaceFolder}/SFML-3.0.0/include\"",
42-
"-DSFML_STATIC",
4342
"-Wall",
4443
"-o",
4544
"${fileDirname}\\main.exe",

Images/Algorithm_Visualiser.gif

-2.28 MB
Loading

Images/InsertionSort.gif

-821 KB
Binary file not shown.

Images/MergeSort.gif

-553 KB
Binary file not shown.

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
11
# Algorithm visualiser
22

3+
A simple C++ algorithm visualizer using SFML, visualising different common algorithms.
4+
35
![Algorithm Visualiser](Images/Algorithm_Visualiser.gif)
6+
7+
# Features
8+
9+
I have implemented the visualisation of two sorts and two graph traversals.
10+
11+
## Sorting algorithms
12+
13+
I have implemented the visualisation of the insertion sort and merge sort algorithms. I have stored snapshots of every step of the sort so users can go through all the steps fast with the arrow keys or step by step with the mouse 1 and 2 buttons.
14+
15+
## Graph builder
16+
17+
I implemented a graph builder where the user can place nodes and edges and thereafter run a DFS or BFS on that graph.
18+
19+
# Installation
20+
21+
22+
23+
# Code structure
24+
25+
The main menu runs in main.cpp.
26+
27+
## Sorting algorithms
28+
The sorting window is run by a function in the sortingAlgorithms/sortingVisualiser.cpp, the sorting algorithms which create the snapshots are in the same folder. When the user presses one of the sorting buttons in the main menu the sorting algorithm is run, and the list of snapshots sent back to be displayed.
29+
30+
## Graph builder
31+
The graph builder window is run by a function in the GraphBuilding/runGraphBuilder.cpp, the DFS and BFS algorithms are in traversal.cpp in the same folder. When the user creates a graph the first node created is the startpoint, this can only be changed by clearing the graph and making a new one. The nodes save their neighbours in an adjacency list which is used in the searching algorithms.
32+
33+
# More information
34+
35+
More of the development process can be found on my [portfolio](https://arthurjerlstrom.wixsite.com/arthurjerlstrom/cpp).
36+
37+

draw.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,43 @@ void drawRectangles(stepStruct currentStepStruct, sf::RenderWindow& window){
1313
std::vector<int> currentStep = currentStepStruct.step;
1414
int arrSize = currentStep.size();
1515
int maxValue = arrSize;
16-
17-
for (int i = 0; i < arrSize; i++){
18-
float windowSizeY = window.getSize().y;
19-
float windowSizeX = window.getSize().x;
20-
float height = -(windowSizeY/maxValue) * currentStep.at(i);
16+
sf::RectangleShape drawWindow({600.f, 500.f});
17+
drawWindow.setFillColor({30, 30, 46});
18+
drawWindow.setPosition({15.f, 15.f});
19+
drawWindow.setOutlineThickness(5.f);
20+
drawWindow.setOutlineColor({100, 100, 100});
2121

22-
sf::RectangleShape rectangle;
23-
rectangle.setSize({10.f, height});
22+
window.draw(drawWindow);
23+
24+
float graphPosX = drawWindow.getPosition().x;
25+
float graphPosY = drawWindow.getPosition().y;
26+
float graphWidth = drawWindow.getSize().x;
27+
float graphHeight = drawWindow.getSize().y;
2428

29+
float barWidth = graphWidth / static_cast<float>(arrSize);
2530

26-
if(i == currentStepStruct.keyIndex && i == currentStepStruct.comparatorIndex){
31+
for (int i = 0; i < arrSize; i++) {
32+
float value = currentStep.at(i);
33+
float height = -(graphHeight / maxValue) * value; // negative to grow upward
34+
35+
sf::RectangleShape rectangle;
36+
rectangle.setSize({barWidth - 2.f, height}); // slight spacing between bars
37+
38+
// Color logic
39+
if (i == currentStepStruct.keyIndex && i == currentStepStruct.comparatorIndex) {
2740
rectangle.setFillColor(sf::Color::Yellow);
28-
}
29-
else if(i == currentStepStruct.keyIndex){
41+
} else if (i == currentStepStruct.keyIndex) {
3042
rectangle.setFillColor(sf::Color::Red);
31-
} else if(i == currentStepStruct.comparatorIndex){
43+
} else if (i == currentStepStruct.comparatorIndex) {
3244
rectangle.setFillColor(sf::Color::Green);
33-
}
34-
else{
45+
} else {
3546
rectangle.setFillColor(sf::Color::White);
3647
}
3748

38-
39-
//this is useless after first call, but I don't feel like doing 2 functions
40-
float currentXPosition = (windowSizeX/arrSize) * i + 5.f;
41-
float yPosition = static_cast<float>(window.getSize().y);
42-
rectangle.setPosition({currentXPosition, yPosition});
43-
49+
// Compute X and Y positions relative to graphWindow
50+
float x = graphPosX + barWidth * i + 1.f; // +1.f for left padding
51+
float y = graphPosY + graphHeight; // start at bottom of graphWindow
52+
rectangle.setPosition({x, y});
4453

4554
window.draw(rectangle);
4655
}

sortingAlgorithms/sortingVisualiser.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#include <thread>
44

55
#include "../headers/sortingVisualiser.hpp"
6+
#include "../headers/button.hpp"
7+
8+
extern const sf::Font font;
69

710
void runSortAlgo(sf::RenderWindow& window, const SortingAlgorithm algoToRun){
811

@@ -18,6 +21,14 @@ void runSortAlgo(sf::RenderWindow& window, const SortingAlgorithm algoToRun){
1821
long long unsigned stepIndex = 0;
1922
steps.emplace_back(arr, 0, 0);
2023

24+
Button returnButton({100.f, 40.f}, {650.f, 535.f}, "Return");
25+
26+
sf::Text text(font); // a font is required to make a text object
27+
text.setString("Use arrow keys and m1/m2");
28+
text.setCharacterSize(24); // in pixels, not points!
29+
text.setFillColor({240, 240, 240});
30+
text.setPosition({40.f, 550.f});
31+
2132

2233
if (algoToRun == SortingAlgorithm::insertionSort) {
2334
insertionSort(arr, arrSize, steps);
@@ -35,20 +46,27 @@ void runSortAlgo(sf::RenderWindow& window, const SortingAlgorithm algoToRun){
3546
window.close();
3647
}
3748
else if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
38-
{
39-
if (keyPressed->scancode == sf::Keyboard::Scancode::Escape){
40-
return;
41-
}
42-
}
49+
{
50+
if (keyPressed->scancode == sf::Keyboard::Scancode::Escape){
51+
return;
52+
}
53+
}
4354
}
4455
//fill display with black
4556
window.clear(sf::Color(0,0,0));
57+
58+
//button to return to menu
59+
sf::Vector2f mouse_position = sf::Vector2f(sf::Mouse::getPosition(window));
60+
if(returnButton.clicked(mouse_position)){
61+
algorithmIsDone = true;
62+
}
4663

64+
//draw everything
65+
window.draw(returnButton);
66+
window.draw(text);
4767
drawRectangles(currentStepStruct, window);
4868

49-
//display what is set up
50-
window.display();
51-
69+
//controls: arrow left, right, m1, m2
5270
bool isLeftPressed = sf::Mouse::isButtonPressed(sf::Mouse::Button::Left);
5371
if(isLeftPressed && !wasLeftPressed){
5472
if(stepIndex < steps.size() - 1){
@@ -81,6 +99,7 @@ void runSortAlgo(sf::RenderWindow& window, const SortingAlgorithm algoToRun){
8199
}
82100
}
83101

102+
window.display();
84103

85104
currentStepStruct = steps.at(stepIndex);
86105
std::this_thread::sleep_for(std::chrono::milliseconds(10));

0 commit comments

Comments
 (0)