diff --git a/PLF/plf/bsp2.py b/PLF/plf/bsp2.py new file mode 100644 index 0000000..47ea17b --- /dev/null +++ b/PLF/plf/bsp2.py @@ -0,0 +1,33 @@ +print("Berge Österreich") +b = ["Großglockner","Wildspitze","Weißkugel","Großvenediger"] +h = [3798,3768,3738,3657] + +while True: + ein=str(input("Neue Eingabe (j/n)? ")) + if ein == "j": + nb = str(input("Name des Berges: ")) + nh = int(input("Höhe: ")) + + if nb in b: + print("Schon vorhanden") + else: + b.append(nb) + h.append(nh) + else: + break + +for x,y in zip(b,h): + print(x,":",y) + +ma = max(h) +i = h.index(ma) +print("Der höchste Berg der Liste ist der",b[i],"mit einer Höhe von",ma,"m") + +d = sum(h)/len(h) +print("Die durchschnittliche Höhe aller Berge beträgt",d,"m.") + +z = 0 +for x in h: + if x >= 3000: + z+=1 +print("In der Liste sind",z,"3000er gespeichert.") \ No newline at end of file diff --git a/PLF/plf/bsp2_modern.cpp b/PLF/plf/bsp2_modern.cpp new file mode 100644 index 0000000..cddab6b --- /dev/null +++ b/PLF/plf/bsp2_modern.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +void add_mountain(vector& names, vector& heights) { + cout << "Name des Berges: "; + string name; + getline(cin >> ws, name); + + // Check if already exists + if (find(names.begin(), names.end(), name) != names.end()) { + cout << "Schon vorhanden." << endl; + return; + } + + cout << "Höhe: "; + int height; + if (!(cin >> height)) { + cout << "Ungültige Eingabe! Bitte eine Zahl angeben." << endl; + cin.clear(); + cin.ignore(numeric_limits::max(), '\n'); + return; + } + + names.push_back(name); + heights.push_back(height); + cout << "'" << name << "' mit " << height << " m wurde hinzugefügt." << endl; +} + +void display_mountains(const vector& names, const vector& heights) { + cout << "\nBergliste:\n"; + for (size_t i = 0; i < names.size(); ++i) { + cout << " • " << names[i] << ": " << heights[i] << " m\n"; + } +} + +pair get_highest_mountain(const vector& names, const vector& heights) { + auto it = max_element(heights.begin(), heights.end()); + size_t index = distance(heights.begin(), it); + return { names[index], *it }; +} + +double calculate_average_height(const vector& heights) { + double sum = accumulate(heights.begin(), heights.end(), 0); + return sum / heights.size(); +} + +int count_3000ers(const vector& heights) { + return count_if(heights.begin(), heights.end(), [](int h) { return h >= 3000; }); +} + +int main() { + cout << "Berge Österreich" << endl; + + vector mountain_names = { "Großglockner", "Wildspitze", "Weißkugel", "Großvenediger" }; + vector mountain_heights = { 3798, 3768, 3738, 3657 }; + + while (true) { + cout << "Neue Eingabe (j/n)? "; + string choice; + cin >> choice; + + if (choice == "j" || choice == "J") { + add_mountain(mountain_names, mountain_heights); + } else if (choice == "n" || choice == "N") { + break; + } else { + cout << "Bitte nur 'j' oder 'n' eingeben." << endl; + } + } + + display_mountains(mountain_names, mountain_heights); + + auto [highest_name, highest_height] = get_highest_mountain(mountain_names, mountain_heights); + cout << "\nDer höchste Berg ist der " << highest_name + << " mit " << highest_height << " m.\n"; + + cout << fixed << setprecision(1); + double avg_height = calculate_average_height(mountain_heights); + cout << "Die durchschnittliche Höhe beträgt " << avg_height << " m.\n"; + + int count = count_3000ers(mountain_heights); + cout << "In der Liste sind " << count << " 3000er gespeichert.\n"; + + return 0; +} diff --git a/PLF/plf/bsp2_modern.py b/PLF/plf/bsp2_modern.py new file mode 100644 index 0000000..a552808 --- /dev/null +++ b/PLF/plf/bsp2_modern.py @@ -0,0 +1,74 @@ +from typing import List + +def add_mountain(names: List[str], heights: List[int]) -> None: + """Add a new mountain entry if it doesn't already exist.""" + name = input("Name des Berges: ").strip() + if name in names: + print("Schon vorhanden.") + return + + try: + height = int(input("Höhe: ").strip()) + except ValueError: + print("Ungültige Eingabe! Bitte eine Zahl angeben.") + return + + names.append(name) + heights.append(height) + print(f"'{name}' mit {height} m wurde hinzugefügt.") + + +def display_mountains(names: List[str], heights: List[int]) -> None: + """Print the list of all mountains and their heights.""" + print("\nBergliste:") + for name, height in zip(names, heights): + print(f" • {name}: {height} m") + + +def get_highest_mountain(names: List[str], heights: List[int]) -> tuple[str, int]: + """Return the highest mountain as (name, height).""" + max_height = max(heights) + index = heights.index(max_height) + return names[index], max_height + + +def calculate_average_height(heights: List[int]) -> float: + """Return the average height of all mountains.""" + return sum(heights) / len(heights) + + +def count_3000ers(heights: List[int]) -> int: + """Return how many mountains are 3000 meters or higher.""" + return sum(h >= 3000 for h in heights) + + +def main() -> None: + """Main program loop.""" + print("Berge Österreich") + + mountain_names = ["Großglockner", "Wildspitze", "Weißkugel", "Großvenediger"] + mountain_heights = [3798, 3768, 3738, 3657] + + while True: + choice = input("Neue Eingabe (j/n)? ").strip().lower() + if choice == "j": + add_mountain(mountain_names, mountain_heights) + elif choice == "n": + break + else: + print("Bitte nur 'j' oder 'n' eingeben.") + + display_mountains(mountain_names, mountain_heights) + + highest_name, highest_height = get_highest_mountain(mountain_names, mountain_heights) + print(f"\nDer höchste Berg ist der {highest_name} mit {highest_height} m.") + + avg_height = calculate_average_height(mountain_heights) + print(f"Die durchschnittliche Höhe beträgt {avg_height:.1f} m.") + + count = count_3000ers(mountain_heights) + print(f"In der Liste sind {count} 3000er gespeichert.") + + +if __name__ == "__main__": + main() diff --git a/simulations/CubeCollision/Program.cs b/simulations/CubeCollision/Program.cs index dd5dbdc..1c0554c 100644 --- a/simulations/CubeCollision/Program.cs +++ b/simulations/CubeCollision/Program.cs @@ -283,7 +283,7 @@ namespace CubeCollisionSimulator // Instructions Label instructionsLabel = new Label { - Text = "Instructions:\n\n Click and drag cubes\n Throw them by dragging\n Watch them collide!\n Adjust physics sliders\n Add more cubes\n Toggle sound on/off", + Text = "Instructions:\n\n� Click and drag cubes\n� Throw them by dragging\n� Watch them collide!\n� Adjust physics sliders\n� Add more cubes\n� Toggle sound on/off", Location = new Point(10, yPos + 20), Size = new Size(230, 200), ForeColor = Color.LightGray @@ -547,4 +547,5 @@ namespace CubeCollisionSimulator Application.Run(new SimulatorForm()); } } -} \ No newline at end of file +} + diff --git a/simulations/SortVisualizer/Algorithms/BogoSort.cs b/simulations/SortVisualizer/Algorithms/BogoSort.cs new file mode 100644 index 0000000..7f8bdcc --- /dev/null +++ b/simulations/SortVisualizer/Algorithms/BogoSort.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SortVisualizer; + +public class BogoSort : ISortAlgorithm +{ + public string Name => "Bogo Sort"; + + private static readonly Random rand = new(); + public static BogoSort Instance { get; } = new BogoSort(); + public BogoSort() { } + + public async Task Sort(int[] array, Action refresh, int delay, Action playSound, CancellationToken token) + { + try + { + while (!IsSorted(array)) + { + token.ThrowIfCancellationRequested(); + + // Shuffle array + for (int i = 0; i < array.Length; i++) + { + int j = rand.Next(array.Length); + (array[i], array[j]) = (array[j], array[i]); + + playSound?.Invoke(array[i]); + refresh?.Invoke(); + + // small delay for live updates + await Task.Delay(delay, token); + } + } + } + catch (TaskCanceledException) + { + // Sorting was stopped; exit gracefully + } + } + + private bool IsSorted(int[] array) + { + for (int i = 1; i < array.Length; i++) + if (array[i - 1] > array[i]) + return false; + return true; + } +} diff --git a/simulations/SortVisualizer/Algorithms/BubbleSort.cs b/simulations/SortVisualizer/Algorithms/BubbleSort.cs new file mode 100644 index 0000000..6032580 --- /dev/null +++ b/simulations/SortVisualizer/Algorithms/BubbleSort.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SortVisualizer; + +public class BubbleSort : ISortAlgorithm +{ + public string Name => "Bubble Sort"; + + public async Task Sort(int[] array, Action refresh, int delay, Action playSound, CancellationToken token) + { + for (int i = 0; i < array.Length - 1; i++) + { + for (int j = 0; j < array.Length - i - 1; j++) + { + if (token.IsCancellationRequested) return; + + playSound(array[j]); + if (array[j] > array[j + 1]) + { + (array[j], array[j + 1]) = (array[j + 1], array[j]); + refresh(); + await Task.Delay(delay); + } + } + } + } +} diff --git a/simulations/SortVisualizer/Algorithms/ISortAlgorithm.cs b/simulations/SortVisualizer/Algorithms/ISortAlgorithm.cs new file mode 100644 index 0000000..31890d2 --- /dev/null +++ b/simulations/SortVisualizer/Algorithms/ISortAlgorithm.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SortVisualizer; + +public interface ISortAlgorithm +{ + string Name { get; } + + Task Sort( + int[] array, + Action refresh, + int delay, + Action playSound, + CancellationToken token + ); +} diff --git a/simulations/SortVisualizer/Algorithms/InsertionSort.cs b/simulations/SortVisualizer/Algorithms/InsertionSort.cs new file mode 100644 index 0000000..0aa4842 --- /dev/null +++ b/simulations/SortVisualizer/Algorithms/InsertionSort.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SortVisualizer; + +public class InsertionSort : ISortAlgorithm +{ + public string Name => "Insertion Sort"; + + public async Task Sort(int[] array, Action refresh, int delay, Action playSound, CancellationToken token) + { + for (int i = 1; i < array.Length; i++) + { + if (token.IsCancellationRequested) return; + + int key = array[i]; + int j = i - 1; + + while (j >= 0 && array[j] > key) + { + if (token.IsCancellationRequested) return; + + playSound(array[j]); + array[j + 1] = array[j]; + j--; + refresh(); + await Task.Delay(delay); + } + array[j + 1] = key; + } + } +} diff --git a/simulations/SortVisualizer/Algorithms/MergeSort.cs b/simulations/SortVisualizer/Algorithms/MergeSort.cs new file mode 100644 index 0000000..379819a --- /dev/null +++ b/simulations/SortVisualizer/Algorithms/MergeSort.cs @@ -0,0 +1,83 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SortVisualizer; + +public class MergeSort : ISortAlgorithm +{ + public string Name => "Merge Sort"; + public MergeSort() { } + public async Task Sort(int[] array, Action refresh, int delay, Action playSound, CancellationToken token) + { + await MergeSortRecursive(array, 0, array.Length - 1, refresh, delay, playSound, token); + } + + private async Task MergeSortRecursive(int[] array, int left, int right, Action refresh, int delay, Action playSound, CancellationToken token) + { + token.ThrowIfCancellationRequested(); + + if (left >= right) return; + + int mid = (left + right) / 2; + await MergeSortRecursive(array, left, mid, refresh, delay, playSound, token); + await MergeSortRecursive(array, mid + 1, right, refresh, delay, playSound, token); + await Merge(array, left, mid, right, refresh, delay, playSound, token); + } + + private async Task Merge(int[] array, int left, int mid, int right, Action refresh, int delay, Action playSound, CancellationToken token) + { + int n1 = mid - left + 1; + int n2 = right - mid; + + int[] L = new int[n1]; + int[] R = new int[n2]; + + Array.Copy(array, left, L, 0, n1); + Array.Copy(array, mid + 1, R, 0, n2); + + int i = 0, j = 0, k = left; + + while (i < n1 && j < n2) + { + token.ThrowIfCancellationRequested(); + + if (L[i] <= R[j]) + { + array[k] = L[i]; + playSound?.Invoke(L[i]); + i++; + } + else + { + array[k] = R[j]; + playSound?.Invoke(R[j]); + j++; + } + + refresh?.Invoke(); + await Task.Delay(delay, token); + k++; + } + + while (i < n1) + { + token.ThrowIfCancellationRequested(); + array[k] = L[i]; + playSound?.Invoke(L[i]); + i++; k++; + refresh?.Invoke(); + await Task.Delay(delay, token); + } + + while (j < n2) + { + token.ThrowIfCancellationRequested(); + array[k] = R[j]; + playSound?.Invoke(R[j]); + j++; k++; + refresh?.Invoke(); + await Task.Delay(delay, token); + } + } +} diff --git a/simulations/SortVisualizer/Algorithms/StoogeSort.cs b/simulations/SortVisualizer/Algorithms/StoogeSort.cs new file mode 100644 index 0000000..446131c --- /dev/null +++ b/simulations/SortVisualizer/Algorithms/StoogeSort.cs @@ -0,0 +1,58 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SortVisualizer; + +public class StoogeSort : ISortAlgorithm +{ + public string Name => "Stooge Sort"; + public StoogeSort() { } + + public async Task Sort(int[] array, Action refresh, int delay, Action playSound, CancellationToken token) + { + try + { + await StoogeSortRecursive(array, 0, array.Length - 1, refresh, delay, playSound, token); + } + catch (TaskCanceledException) + { + // Sorting was cancelled handle gracefully + // Optionally, reset UI or log here + } + catch (Exception ex) + { + // Unexpected exception optional logging + Console.WriteLine($"StoogeSort error: {ex}"); + } + } + + private async Task StoogeSortRecursive(int[] array, int i, int j, Action refresh, int delay, Action playSound, CancellationToken token) + { + if (token.IsCancellationRequested) return; // graceful early exit + + // Swap if first element is greater than last + if (array[i] > array[j]) + { + int temp = array[i]; + array[i] = array[j]; + array[j] = temp; + + playSound?.Invoke(array[i]); + playSound?.Invoke(array[j]); + refresh?.Invoke(); + + try { await Task.Delay(delay, token); } + catch (TaskCanceledException) { return; } // exit silently if cancelled + } + + if (j - i + 1 > 2) + { + int t = (j - i + 1) / 3; + + await StoogeSortRecursive(array, i, j - t, refresh, delay, playSound, token); + await StoogeSortRecursive(array, i + t, j, refresh, delay, playSound, token); + await StoogeSortRecursive(array, i, j - t, refresh, delay, playSound, token); + } + } +} diff --git a/simulations/SortVisualizer/Form1.Designer.cs b/simulations/SortVisualizer/Form1.Designer.cs new file mode 100644 index 0000000..9827aaa --- /dev/null +++ b/simulations/SortVisualizer/Form1.Designer.cs @@ -0,0 +1,38 @@ +namespace SortVisualizer; + +partial class Form1 +{ + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "Form1"; + } + + #endregion +} diff --git a/simulations/SortVisualizer/Form1.cs b/simulations/SortVisualizer/Form1.cs new file mode 100644 index 0000000..165234c --- /dev/null +++ b/simulations/SortVisualizer/Form1.cs @@ -0,0 +1,9 @@ +namespace SortVisualizer; + +public partial class Form1 : Form +{ + public Form1() + { + InitializeComponent(); + } +} diff --git a/simulations/SortVisualizer/Program.cs b/simulations/SortVisualizer/Program.cs new file mode 100644 index 0000000..3486f10 --- /dev/null +++ b/simulations/SortVisualizer/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Windows.Forms; + +namespace SortVisualizer; + +internal static class Program +{ + [STAThread] + static void Main() + { + ApplicationConfiguration.Initialize(); + Application.Run(new VisualizerForm()); + } +} diff --git a/simulations/SortVisualizer/SortVisualizer.csproj b/simulations/SortVisualizer/SortVisualizer.csproj new file mode 100644 index 0000000..c27cd77 --- /dev/null +++ b/simulations/SortVisualizer/SortVisualizer.csproj @@ -0,0 +1,11 @@ + + + + WinExe + net9.0-windows + enable + true + enable + + + \ No newline at end of file diff --git a/simulations/SortVisualizer/VisualizerForm.cs b/simulations/SortVisualizer/VisualizerForm.cs new file mode 100644 index 0000000..81fa88e --- /dev/null +++ b/simulations/SortVisualizer/VisualizerForm.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Media; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SortVisualizer; + +public class VisualizerForm : Form +{ + int[] array = Array.Empty(); + Random rand = new(); + int delay = 10; + bool sorting = false; + + ComboBox algoSelector; + Button startButton, stopButton, shuffleButton; + TrackBar speedSlider; + CheckBox soundToggle; + Label speedLabel, statusLabel; + + List algorithms; + CancellationTokenSource? cts; + + Dictionary toneCache = new(); + SemaphoreSlim soundSemaphore = new(1, 1); // prevent sound overlap + + int highlightedIndex1 = -1; + int highlightedIndex2 = -1; + + public VisualizerForm() + { + Text = "C# Sorting"; + DoubleBuffered = true; + MinimumSize = new Size(800, 500); + Width = 1000; + Height = 600; + + algorithms = new() { new BubbleSort(), new InsertionSort(), new BogoSort(), + new MergeSort() , new StoogeSort() + }; + + // --- Top Control Panel --- + var topPanel = new FlowLayoutPanel + { + Dock = DockStyle.Top, + AutoSize = true, + WrapContents = true, + FlowDirection = FlowDirection.LeftToRight, + Padding = new Padding(5), + AutoScroll = true + }; + + algoSelector = new ComboBox { Width = 160, DropDownStyle = ComboBoxStyle.DropDownList }; + algoSelector.DataSource = algorithms; + algoSelector.DisplayMember = "Name"; + + int buttonHeight = algoSelector.Height; + + startButton = new Button { Width = 100, Height = buttonHeight, Text = "Start" }; + stopButton = new Button { Width = 100, Height = buttonHeight, Text = "Stop" }; + shuffleButton = new Button { Width = 100, Height = buttonHeight, Text = "Shuffle" }; + + soundToggle = new CheckBox { Width = 100, Height = buttonHeight, Text = "Sound On", Checked = true }; + + speedLabel = new Label { Width = 60, Height = buttonHeight, Text = "Speed: 10", TextAlign = ContentAlignment.MiddleCenter }; + speedSlider = new TrackBar + { + Width = 250, + Minimum = 1, + Maximum = 100, + Value = 10, + TickFrequency = 10, + SmallChange = 1, + LargeChange = 10, + Height = buttonHeight + }; + + statusLabel = new Label { Width = 150, Height = buttonHeight, Text = "Idle", TextAlign = ContentAlignment.MiddleRight }; + + topPanel.Controls.AddRange(new Control[] + { + algoSelector, startButton, stopButton, shuffleButton, + soundToggle, speedLabel, speedSlider, statusLabel + }); + + Controls.Add(topPanel); + + speedSlider.ValueChanged += (s, e) => + { + delay = 101 - speedSlider.Value; + speedLabel.Text = $"Speed: {speedSlider.Value}"; + }; + + startButton.Click += async (s, e) => await StartSort(); + stopButton.Click += (s, e) => StopSort(); + shuffleButton.Click += (s, e) => Shuffle(); + + this.Resize += (s, e) => Invalidate(); + + Shuffle(); + } + + void Shuffle() + { + if (sorting) return; + array = Enumerable.Range(1, 100).OrderBy(_ => rand.Next()).ToArray(); + highlightedIndex1 = highlightedIndex2 = -1; + Invalidate(); + statusLabel.Text = "Shuffled!"; + } + + async Task StartSort() + { + if (sorting) return; + sorting = true; + cts = new CancellationTokenSource(); + + var algo = (ISortAlgorithm)algoSelector.SelectedItem!; + statusLabel.Text = $"Sorting ( {algo.Name} )..."; + + try + { + await algo.Sort( + array, + () => Invalidate(), // keep original signature + delay, + value => { if (soundToggle.Checked) _ = PlaySoundAsync(value); }, + cts.Token + ); + + highlightedIndex1 = highlightedIndex2 = -1; + Invalidate(); + + if (!cts.Token.IsCancellationRequested) + statusLabel.Text = "Done!"; + } + finally + { + sorting = false; + } + } + + void StopSort() + { + if (!sorting) return; + cts?.Cancel(); + sorting = false; + highlightedIndex1 = highlightedIndex2 = -1; + Invalidate(); + statusLabel.Text = "Stopped."; + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + var g = e.Graphics; + + int offsetY = 50; + int marginX = 20; + + if (array.Length == 0) return; + + int barWidth = (ClientSize.Width - 2 * marginX) / array.Length; + int availableHeight = ClientSize.Height - offsetY; + + for (int i = 0; i < array.Length; i++) + { + int height = (int)(array[i] * (availableHeight / (float)array.Length)); + Brush brush = Brushes.LightGreen; + + if (sorting) + { + if (i == highlightedIndex1) brush = Brushes.Red; + else if (i == highlightedIndex2) brush = Brushes.Orange; + else brush = Brushes.DeepSkyBlue; + } + + g.FillRectangle(brush, marginX + i * barWidth, ClientSize.Height - height, barWidth - 1, height); + } + } + + async Task PlaySoundAsync(int value) + { + // Use semaphore to prevent overlapping sounds + if (!await soundSemaphore.WaitAsync(0)) + return; // skip if already playing + + try + { + int freq = 220 + (int)(value * 12.0); + int durationMs = 10; + + if (!toneCache.TryGetValue(freq, out var wav)) + { + wav = GenerateToneWav(freq, durationMs, 44100); + + // Limit cache size + if (toneCache.Count > 200) + toneCache.Clear(); + + toneCache[freq] = wav; + } + + await Task.Run(() => + { + try + { + using var ms = new MemoryStream(wav); + using var player = new SoundPlayer(ms); + player.PlaySync(); // blocks on background thread + } + catch + { + try + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + Console.Beep(freq, durationMs); + } + catch { } + } + }); + } + finally + { + soundSemaphore.Release(); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + cts?.Dispose(); + soundSemaphore?.Dispose(); + } + base.Dispose(disposing); + } + + #region Tone Generation + + public static byte[] GenerateToneWav(int frequency, int durationMs, int sampleRate = 44100, double amplitude = 0.25) + { + int samples = (int)((durationMs / 1000.0) * sampleRate); + using var ms = new MemoryStream(); + using var bw = new BinaryWriter(ms); + + short numChannels = 1; + short bitsPerSample = 16; + int byteRate = sampleRate * numChannels * bitsPerSample / 8; + short blockAlign = (short)(numChannels * bitsPerSample / 8); + int dataSize = samples * numChannels * (bitsPerSample / 8); + + bw.Write(System.Text.Encoding.ASCII.GetBytes("RIFF")); + bw.Write(36 + dataSize); + bw.Write(System.Text.Encoding.ASCII.GetBytes("WAVE")); + + bw.Write(System.Text.Encoding.ASCII.GetBytes("fmt ")); + bw.Write(16); + bw.Write((short)1); + bw.Write(numChannels); + bw.Write(sampleRate); + bw.Write(byteRate); + bw.Write(blockAlign); + bw.Write(bitsPerSample); + + bw.Write(System.Text.Encoding.ASCII.GetBytes("data")); + bw.Write(dataSize); + + double twoPiF = 2 * Math.PI * frequency; + for (int n = 0; n < samples; n++) + { + double t = n / (double)sampleRate; + double sample = amplitude * Math.Sin(twoPiF * t); + short s = (short)Math.Max(short.MinValue, Math.Min(short.MaxValue, sample * short.MaxValue)); + bw.Write(s); + } + + bw.Flush(); + return ms.ToArray(); + } + + #endregion +} \ No newline at end of file diff --git a/simulations/balls/main.py b/simulations/balls/main.py index aa71c7d..7eac89a 100644 --- a/simulations/balls/main.py +++ b/simulations/balls/main.py @@ -8,7 +8,7 @@ pygame.init() # Screen setup WIDTH, HEIGHT = 800, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) -pygame.display.set_caption("Enhanced Physics Bouncing Balls") +pygame.display.set_caption("balls") # Colors BLACK = (0, 0, 0) @@ -259,15 +259,15 @@ while running: # Physics info font = pygame.font.SysFont(None, 22) - info = [ - f"Gravity: {gravity:.2f} (↑↓) Elasticity: {elasticity:.2f} (←→)", - f"Air Resistance: {air_resistance:.3f} (WS) Balls: {len(balls)}", - f"SPACE: Add ball C: Clear Drag to throw!" - ] +# info = [ +# f"Gravity: {gravity:.2f} Elasticity: {elasticity:.2f} (←→)", +# f"Air Resistance: {air_resistance:.3f} (WS) Balls: {len(balls)}", +# f"SPACE: Add ball C: Clear Drag to throw!" +# ] - for i, text in enumerate(info): - surface = font.render(text, True, WHITE) - screen.blit(surface, (10, 10 + i * 25)) +# for i, text in enumerate(info): +# surface = font.render(text, True, WHITE) +# screen.blit(surface, (10, 10 + i * 25)) pygame.display.flip() clock.tick(FPS)