diff --git a/README.md b/README.md
index 7076032..f11dcc5 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,59 @@
-# Sorting-Algorithms-Visualizer
+# Sorting Algorithms Visualizer
-## Run
+An educational application developed in Python using the game development library Pygame, which helps illustrate how a variety of sorting algorithms function in real-time by making visual adjustments to the bars as the algorithms perform the calculations.
+
+## Features
+
+- **9 Sorting Algorithms**: Bubble Sort, Bucket Sort, Cocktail Sort, Counting Sort, Heap Sort, Insertion Sort, Merge Sort, Quick Sort, and Selection Sort
+- **Real-time Visualization**: See each algorithm's step-by-step execution
+- **Educational**: Perfect for students learning algorithms and data structures
+- **Interactive**: Built with Pygame for smooth animations
+
+## Getting Started
+
+### Prerequisites
+
+- Python 3.x
+- pip (Python package installer)
+
+### Installation
+
+1. Clone the repository:
-- Clone GitHub repository
-```
git clone https://github.com/LucasPilla/Sorting-Algorithms-Visualizer.git
-```
-- Install requirements:
-```
+cd Sorting-Algorithms-Visualizer
+
+2. Install dependencies:
+
pip install -r requirements.txt
-```
-- Run:
-```
+
+3. Run the visualizer:
+
python3 src/main.py
-```
## Preview
+
+Watch the algorithms in action:
+
| | | |
|:-------------------------:|:-------------------------:|:-------------------------:|
-| Bubble sort |  Bucket sort | Cocktail sort |
-| Counting sort |  Heap sort | Insertion sort |
-| Merge sort |  Quick sort | Selection sort |
+|
**Bubble Sort** | 
**Bucket Sort** |
**Cocktail Sort** |
+|
**Counting Sort** | 
**Heap Sort** |
**Insertion Sort** |
+|
**Merge Sort** | 
**Quick Sort** |
**Selection Sort** |
+
+## Contributing
+
+Contributions are welcome! Please check out our [Contributing Guidelines](CONTRIBUTING.md) to get started.
+
+## License
+
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
+
+## Acknowledgments
+
+- Built with [Pygame](https://www.pygame.org/)
+- Inspired by the need to make algorithm learning more visual and intuitive
+## Support
+If you find this project helpful, please consider giving it a ⭐️ on GitHub!
diff --git a/src/main.py b/src/main.py
index 3a362de..fb6c93d 100644
--- a/src/main.py
+++ b/src/main.py
@@ -8,104 +8,182 @@
# Initialize pygame modules
pygame.init()
+# Constants
+SCREEN_WIDTH = 900
+SCREEN_HEIGHT = 500
+BAR_AREA_HEIGHT = 400
+WIDGET_Y = 440
+
# Font
baseFont = pygame.font.SysFont('Arial', 24)
# Colors
-grey = (100, 100, 100)
-green = (125, 240, 125)
-white = (250, 250, 250)
-red = (255, 50, 50)
-black = (0, 0, 0)
-blue = (50, 50, 255)
-
-pygame.display.set_caption('Sorting Algorithms Visualizer')
-screen = pygame.display.set_mode((900, 500))
-window = Window(screen)
-
-window.add_widget(
- widget_id = 'size_input',
- widget = TextBox((30, 440, 100, 50), 'Size', grey, baseFont, '100')
-)
-window.add_widget(
- widget_id='delay_slider',
- widget=SlideBox((140, 440, 150, 50), 'Delay', grey, baseFont)
-)
-window.add_widget(
- widget_id = 'algorithm_input',
- widget = DropdownBox((300, 440, 200, 50), 'Algorithm', grey, baseFont, list(algorithmsDict.keys()), white)
-)
-window.add_widget(
- widget_id = 'play_button',
- widget = ButtonBox((510, 445, 40, 40), 'res/playButton.png', 'res/stopButton.png')
-)
-
-def drawBars(screen, array, redBar1, redBar2, blueBar1, blueBar2, greenRows = {}):
- '''Draw the bars and control their colors'''
- numBars = len(array)
- if numBars != 0:
- bar_width = 900 / numBars
+GREY = (100, 100, 100)
+GREEN = (125, 240, 125)
+WHITE = (250, 250, 250)
+RED = (255, 50, 50)
+BLACK = (0, 0, 0)
+BLUE = (50, 50, 255)
+
+# Default values
+DEFAULT_ARRAY_SIZE = 100
+MIN_BAR_HEIGHT = 10
+MAX_BAR_HEIGHT = 400
+
+class SortingVisualizer:
+ """Main class to handle the sorting visualization"""
+
+ def __init__(self):
+ pygame.display.set_caption('Sorting Algorithms Visualizer')
+ self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
+ self.window = Window(self.screen)
+ self.clock = pygame.time.Clock()
+
+ self._setup_widgets()
+ self._reset_state()
+
+ def _setup_widgets(self):
+ """Initialize all UI widgets"""
+ self.window.add_widget(
+ widget_id='size_input',
+ widget=TextBox((30, WIDGET_Y, 100, 50), 'Size', GREY, baseFont, str(DEFAULT_ARRAY_SIZE))
+ )
+ self.window.add_widget(
+ widget_id='delay_slider',
+ widget=SlideBox((140, WIDGET_Y, 150, 50), 'Delay', GREY, baseFont)
+ )
+ self.window.add_widget(
+ widget_id='algorithm_input',
+ widget=DropdownBox((300, WIDGET_Y, 200, 50), 'Algorithm', GREY, baseFont,
+ list(algorithmsDict.keys()), WHITE)
+ )
+ self.window.add_widget(
+ widget_id='play_button',
+ widget=ButtonBox((510, WIDGET_Y + 5, 40, 40), 'res/playButton.png', 'res/stopButton.png')
+ )
+
+ def _reset_state(self):
+ """Reset the visualizer state"""
+ self.numbers = []
+ self.is_sorting = False
+ self.sorting_iterator = None
+ self.last_iteration = 0
+
+ def _generate_random_array(self, size):
+ """Generate a random array for sorting"""
+ try:
+ num_bars = max(1, min(int(size), SCREEN_WIDTH)) # Validate input
+ except (ValueError, TypeError):
+ num_bars = DEFAULT_ARRAY_SIZE
+
+ return [randint(MIN_BAR_HEIGHT, MAX_BAR_HEIGHT) for _ in range(num_bars)]
+
+ def _draw_bars(self, red_indices=(-1, -1), blue_indices=(-1, -1), green_indices=None):
+ """
+ Draw the bars with appropriate colors
+
+ Args:
+ red_indices: Tuple of indices to color red (comparison)
+ blue_indices: Tuple of indices to color blue (swap)
+ green_indices: Set of indices to color green (sorted)
+ """
+ if not self.numbers:
+ return
+
+ num_bars = len(self.numbers)
+ bar_width = SCREEN_WIDTH / num_bars
ceil_width = math.ceil(bar_width)
+ green_indices = green_indices or set()
+
+ for idx, height in enumerate(self.numbers):
+ # Determine bar color based on state
+ if idx in red_indices:
+ color = RED
+ elif idx in blue_indices:
+ color = BLUE
+ elif idx in green_indices:
+ color = GREEN
+ else:
+ color = GREY
+
+ # Draw the bar
+ x_pos = idx * bar_width
+ y_pos = BAR_AREA_HEIGHT - height
+ pygame.draw.rect(self.screen, color, (x_pos, y_pos, ceil_width, height))
+
+ def _start_sorting(self):
+ """Initialize and start the sorting process"""
+ size_input = self.window.get_widget_value('size_input')
+ self.numbers = self._generate_random_array(size_input)
+
+ algorithm_name = self.window.get_widget_value('algorithm_input')
+ self.sorting_iterator = algorithmsDict[algorithm_name](
+ self.numbers, 0, len(self.numbers) - 1
+ )
+ self.is_sorting = True
+ self.last_iteration = time.time()
+
+ def _update_sorting(self, delay):
+ """Update the sorting visualization"""
+ current_time = time.time()
+
+ if current_time - self.last_iteration >= delay:
+ try:
+ self.numbers, red1, red2, blue1, blue2 = next(self.sorting_iterator) # type: ignore
+ self.last_iteration = current_time
+ self._draw_bars(red_indices=(red1, red2), blue_indices=(blue1, blue2))
+ except StopIteration:
+ # Sorting completed
+ self.is_sorting = False
+ self.window.set_widget_value('play_button', False)
+ self._draw_bars(green_indices=set(range(len(self.numbers))))
+ else:
+ # Redraw with current state
+ self._draw_bars()
- for num in range(numBars):
- if num in (redBar1, redBar2) : color = red
- elif num in (blueBar1, blueBar2): color = blue
- elif num in greenRows : color = green
- else : color = grey
- pygame.draw.rect(screen, color, (num * bar_width, 400 - array[num], ceil_width, array[num]))
+ def run(self):
+ """Main application loop"""
+ running = True
-def main():
- numbers = []
- running = True
- isPlaying = False
- isSorting = False
- sortingIterator = None
- last_iteration = 0
-
- while running:
- screen.fill(white)
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
-
- window.update(event)
-
- # Get delay in seconds
- delay = window.get_widget_value('delay_slider') / 10
-
- isPlaying = window.get_widget_value('play_button')
- if isPlaying and not isSorting:
- # Random list to be sorted
- numBars = int(window.get_widget_value('size_input'))
- numbers = [randint(10, 400) for i in range(numBars)]
-
- # Initialize sorting iterator
- sortingAlgorithm = window.get_widget_value('algorithm_input')
- sortingIterator = algorithmsDict[sortingAlgorithm](numbers, 0, numBars - 1)
- isSorting = True
-
- if not isPlaying:
- isSorting = False
-
- if isSorting:
- try:
- # Get the next state from the sorting iterator
- if time.time() - last_iteration >= delay:
- numbers, redBar1, redBar2, blueBar1, blueBar2 = next(sortingIterator)
- last_iteration = time.time()
-
- drawBars(screen, numbers, redBar1, redBar2, blueBar1, blueBar2)
- window.render()
- pygame.display.update()
-
- except StopIteration:
- isSorting = False
- window.set_widget_value('play_button', False)
- else:
- drawBars(screen, numbers, -1, -1, -1, -1, greenRows=set(range(len(numbers))))
+ while running:
+ self.screen.fill(WHITE)
+
+ # Handle events
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ running = False
+ self.window.update(event)
+
+ # Get current state
+ is_playing = self.window.get_widget_value('play_button')
+ delay = self.window.get_widget_value('delay_slider') / 10
- window.render()
- pygame.display.update()
+ # Handle play/pause
+ if is_playing and not self.is_sorting:
+ self._start_sorting()
+ elif not is_playing and self.is_sorting:
+ self.is_sorting = False
+
+ # Update visualization
+ if self.is_sorting:
+ self._update_sorting(delay)
+ else:
+ # Show array in final state
+ green_indices = set(range(len(self.numbers))) if self.numbers else set()
+ self._draw_bars(green_indices=green_indices)
+
+ # Render UI and update display
+ self.window.render()
+ pygame.display.update()
+ self.clock.tick(60) # Limit to 60 FPS
+
+ pygame.quit()
+
+
+def main():
+ """Entry point for the application"""
+ visualizer = SortingVisualizer()
+ visualizer.run()
if __name__ == '__main__':