8 willekeurige nummers: eerste nummer altijd dubbel

Arduino specifieke Software
Berichten: 2
Geregistreerd: 22 Jun 2018, 13:03

8 willekeurige nummers: eerste nummer altijd dubbel

Berichtdoor Duggel » 22 Jun 2018, 13:21

Graag jullie hulp/advies bij het volgende:

Ik ben een stok-vang spel aan het maken. De bedoeling is dat na het drukken op en knop de stokken 1 voor 1 vallen in een willekeurige volgorde. De tijd tussen het vallen is dynamisch en afhankelijk van een draaiknop.
Dit werkt zo goed als perfect, op 1 ding na: Het eerste willekeurige getal komt altijd 2x voor in de reeks van 8, waardoor 1 stok blijft hangen.

Hierbij valt het op dat altijd een van deze patroon terug keert:
XX000000
X0X00000
X000X000
Oftewel het eerste getal is telkens ook het tweede, derde of vijfde getal.

Hieronder mijn code... ik kan niet ontdekken waar het fout gaat. Als een 'stoknummer' al is toegevoegd aan de array droppedPins zou dat nummer niet nog eens gekozen kunnen worden.
Wellicht zit er een fout in deze vergelijking, maar ik kan 'm niet ontdekken.

Alvast bedankt voor de feedback.

Code: Alles selecteren
bool play = false; //Wordt op true gezet als de 'play' knop wordt ingedrukt
int numberOfDroppedPins = 1; //aantal gevallen stokken. Als ik deze bij 0 liet beginnen werkte de array 'droppedPins' vreemd genoeg niet
int droppedPins[] = {}; //de lijst met stokken die al gevallen zijn

//reeks met relays voor het  aansturen van de elektromagneten
int Relay1 = 2;
int Relay2 = 3;
int Relay3 = 4;
int Relay4 = 5;
int Relay5 = 6;
int Relay6 = 7;
int Relay7 = 8;
int Relay8 = 9;

const int buttonPin = 10; // de start knop
int buttonState = 0;  //standaard waarde startknop

int levelPin = 2; // de draaiknop om de moeilijkheidsgraad te bepalen
int level = 0; // standaard level 0
int levelTime = 8000; // standaard 8 sec tussen het vallen van stokken

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);

//3 leds als stoplicht bij het beginnen van het spel
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);

//alle magneten aan zetten
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);

  pinMode(buttonPin, INPUT);

//ervoor zorgen dat niet dezelfde stok als eerste gekozen wordt
  randomSeed(analogRead(0));
}

void loop() {   // Loops forever

  level = analogRead(levelPin);
  if (level < 400) {
    //easy
    levelTime = random((8000-level), (12000-level));
  } else if (level < 800) {
    //medium
    levelTime = random((8000-(3*level)), (12000-(3*level)));
  } else {
    //hard
    levelTime = random((8000-(6*level)), (12000-(random(4,7)*level)));
  }
 
  buttonState = digitalRead(buttonPin);
  if (buttonState) {
    digitalWrite(13, HIGH);
    delay(1000);
    digitalWrite(12, HIGH);
    delay(1000);
    digitalWrite(11, HIGH);
    delay(1000);
   
    numberOfDroppedPins = 1;
    droppedPins[0] = 0;
    droppedPins[1] = 0;
    play = true;
   
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);
    digitalWrite(13, LOW);
    delay(levelTime);
  }
 
  if (numberOfDroppedPins < 9 && play) {

    int randomPin = random(1,9);

    bool pickedPinDropped = false;
    for (int checkPin=1; checkPin<=numberOfDroppedPins; checkPin++){
      if (droppedPins[checkPin] == randomPin){
        pickedPinDropped = true;
      }
    }

    if (!pickedPinDropped) {
      digitalWrite((randomPin+1), LOW);

      droppedPins[numberOfDroppedPins] = randomPin;
      numberOfDroppedPins++;
     
      delay(levelTime);
    } else {
      //deze is al gevallen, geen getreuzel, direct een nieuwe kiezen.
    }
  } else {
    if (play) {
      delay(2000);
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(8, HIGH);
      digitalWrite(9, HIGH);
    }
    play = false;
  }
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: 8 willekeurige nummers: eerste nummer altijd dubbel

Berichtdoor Koepel » 22 Jun 2018, 16:18

Welkom om dit forum.

Ik krijg een beetje gemende gevoelens bij de sketch. Enerzijds ben je bekend met een zeef-filter "else if (level < 800)", anderzijds declareer je een leeg array "int droppedPins[] = {};". Er was ooit een tijd dat zo iets was toegestaan, maar in C++ is het niet toegestaan om een leeg array te declareren. Het verbaast me dat de compiler geen foutmelding geeft.

Zet dit eens bovenaan je sketch:
Code: Alles selecteren
#pragma GCC diagnostic warning "-pedantic"

Dan krijg je daar wel een foutmelding op.

In plaats van dat zeef filter, zou je ook een curve met floating point getallen kunnen maken.

random(1,9) geeft: 1,2,3,4,5,6,7 of 8.
Dat zit er dus eentje naast.
Je wilt de eerste stok nummer 1 geven. In de taal 'c' begint een array echter bij 0. Dat is een beetje verwarrend.
Het is eenvoudiger om een reeks van getallen bij 0 te laten beginnen, en de stokken een naam te geven, bijvoorbeeld "een", "twee", "drie", of "A", "B", "C".

Ik stel voor om je sketch anders te doen.
Je mag kijken of een digitale uitgang HIGH of LOW is, door een digitalRead() op de uitgang te doen.
Zo kun je dus kijken welke relais open staan.
Het is echter beter om een array bij te houden waarin de status van stokken in staat. Dus dat array ook weer resetten als de digitale uitgangen gereset worden.

Een reeks van pin-nummers zou in een array gestopt kunnen worden. Dan zou de declaratie van de pinnen zo kunnen worden:
Code: Alles selecteren
const int int RelayPins[] = { 2, 3, 4, 5, 6, 7, 8, 9 };
const int int stoplichtPins[] = { 11, 12, 13 };
const int levelPin = A2;


Het heeft de voorkeur om de analoge ingangen "A0" en "A2" te noemen, in plaats van "0" en "2".

Volgens mij zijn deze variabelen lokaal gebruikte variabelen. Die zou je ook binnen de loop() kunnen declareren:
Code: Alles selecteren
int buttonState = 0;  //standaard waarde startknop

int level = 0; // standaard level 0
int levelTime = 8000; // standaard 8 sec tussen het vallen van stokken



Voor de zekerheid gebruik ik liever meerdere analoge ingangen:
Code: Alles selecteren
int total = 0;
for( int i=A0; i<=A6; i++)
{
  total += analogRead( i);
}
randomSeed( total);


Deze sketch leent zich heel goed om alleen met de seriële monitor uit te proberen. Kun je dat toevoegen ? dat weet je wat er gebeurt.

Berichten: 2
Geregistreerd: 22 Jun 2018, 13:03

Re: 8 willekeurige nummers: eerste nummer altijd dubbel

Berichtdoor Duggel » 27 Jun 2018, 19:42

Dankjewel voor de reactie.
Normaal programmeer ik in PHP, daar is juist wel de bedoeling om eerst een lege array te declareren voordat je deze via een loop o.i.d. gaat vullen.

Ik ga je tips proberen te verwerken en hopelijk krijg ik dan snel een beter resultaat.
Helaas is de Arduino (clone) overleden, ik vermoed dat er 12v op het 5v gedeelte is gekomen. Hij lijkt nog te leven, maar kan niet meer gevonden worden via USB. Ook het programma dat erop stond werkt niet meer (alle uitgangen zijn nu continue aan).
De nieuwe is onderweg... dus ik kom er nog op terug.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: 8 willekeurige nummers: eerste nummer altijd dubbel

Berichtdoor Koepel » 27 Jun 2018, 20:40

Een losse draad met 12V die op een Arduino boardje valt, dat is een klassieke fout.

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: uvixuuev en 10 gasten