#ifndef EUCLIDEAN_STRATEGY_H #define EUCLIDEAN_STRATEGY_H #include "MelodyStrategy.h" #include class EuclideanStrategy : public MelodyStrategy { public: void generate(Step* sequence, int numSteps, int* scaleNotes, int numScaleNotes, int seed) override { randomSeed(seed); if (numScaleNotes == 0) return; int pulses = random(1, numSteps + 1); int offset = random(numSteps); // Euclidean distribution (Bresenham) int bucket = 0; // Generate pattern bool pattern[numSteps]; for(int i=0; i= numSteps) { bucket -= numSteps; pattern[i] = true; } else { pattern[i] = false; } } for (int i = 0; i < numSteps; i++) { // Apply offset int stepIndex = (i + offset) % numSteps; if (pattern[i]) { int octave = random(3) + 3; // 3, 4, 5 sequence[stepIndex].note = 12 * octave + scaleNotes[random(numScaleNotes)]; sequence[stepIndex].accent = (random(100) < 30); sequence[stepIndex].tie = (random(100) < 10); } else { sequence[stepIndex].note = -1; sequence[stepIndex].accent = false; sequence[stepIndex].tie = false; } } randomSeed(micros()); } void generateScale(int* scaleNotes, int& numScaleNotes) override { numScaleNotes = random(3, 13); // 3 to 12 notes for (int i = 0; i < 12; i++) { scaleNotes[i] = i; // Fill with all notes } // Shuffle for (int i = 0; i < 12; i++) { int j = random(12); int temp = scaleNotes[i]; scaleNotes[i] = scaleNotes[j]; scaleNotes[j] = temp; } sortArray(scaleNotes, numScaleNotes); } void mutate(Step* sequence, int numSteps, int* scaleNotes, int numScaleNotes) override { // Rotate sequence if (random(2) == 0) { Step last = sequence[numSteps - 1]; for (int i = numSteps - 1; i > 0; i--) { sequence[i] = sequence[i - 1]; } sequence[0] = last; } else { // Randomize a note int s = random(numSteps); if (sequence[s].note != -1) { int octave = random(3) + 3; sequence[s].note = 12 * octave + scaleNotes[random(numScaleNotes)]; } } } const char* getName() override { return "Euclid"; } }; #endif