Permalänk
Medlem

Hjälp med Lottoprogram i C

Hej!
Jag har precis börjat plugga på yrkeshögskolan till Mjukvaruutvecklare inom industriell IoT. Jag håller på med en uppgift i C där jag ska göra ett Lottoprogram. Jag är nästan färdig med alla delar( spelaren ska kunna välja mellan att få 7 nummer automatiskt slumpade eller att knappa in dem själv, därefter ska den rätta lottoraden slumpas fram) men jag får inte till det med dubbletter. När en dubblett slumpas fram ska det slumpas igen för att få ett nytt nummer. Jag vet inte längre vad jag ska göra för att få det att funka och hoppas att någon här har lust att kolla igenom/köra koden och berätta för mig hur jag ska göra för att lösa det för jag börjar bli desperat här..Tack på förhand.

#include <stdio.h> #include <stdlib.h>//för rand-funktionen #include <time.h>//för att rand ska generera #include <conio.h>//för att kunna använda getch() #include <windows.h>//för Sleep() #include <stdbool.h> void meny(void); int automatisk(); int manuell(); int Lotto(); int resultat(); int val, nr; int nummer[7]; int rättRad[7]; bool minBool; int main(void) { srand(time(0)); printf("\nHej och välkommen till EC Lotto!\n"); printf("Det här spelet har dessvärre inga vinster.\n\n"); printf("Tryck ENTER för att fortsätta...\n\n"); getch(); meny(); return 0; } void meny() { printf("Gör ditt val: \n"); Sleep(600); printf("1. Ge mig slumpmässiga val, tack! \n"); printf("2. Jag vill välja själv.\n"); scanf("%d", &val); if(val==1) { automatisk(); Lotto(); resultat(); } else if(val==2) { manuell(); Lotto(); resultat(); } else { printf("Felaktigt val! Var god försök igen!"); meny(); } } int automatisk(void) { int i; for ( i = 0; i < 7; i++) { do { nr=(rand()%35)+1; minBool=true; for (int j = 0; j < i; j++) { if(nummer[i]==nummer[j]) { minBool=false; } } }while(!minBool); nummer[i]=nr; Sleep(600); printf("Nummer %d: %d\n", i+1, nr); } printf("\nTryck ENTER för att fortsätta...\n\n"); getch(); } int manuell(void) { printf("Ange 7 stycken olika nummer: \n"); for (int i = 0; i < 7; i++) { do { printf("Ange nummer %d: ", i+1); scanf("%d", &nummer[i]); if(nummer[i]>35) { printf("Du kan inte ange ett tal större en 35!\n"); } if(nummer[i]<1) { printf("Du kan inte ange ett tal mindre än 1!\n"); } } while (nummer[i]<1 || nummer[i]>35); } } int Lotto() { printf("Nu börjar dragningen!\n\n"); Sleep(700); int i; for (i = 0; i < 7; i++) { do { nr=(rand()%35)+1; minBool=true; for (int j = 0; j < i; j++) { if(rättRad[i]==rättRad[j]) { minBool=false; } } }while (!minBool); rättRad[i]=nr; Sleep(2000); Beep(600, 600); printf("Boll nummer %d blir... %d\n", i+1, nr); } } //Funktion för att skriva ut int resultat(void) { Sleep(2000); printf("\nDina nummer:\n"); for (int i = 0; i < 7; i++) { printf("%d ", nummer[i]); } Sleep(2000); printf("\n\nRätt lottorad: \n"); for (int i = 0; i < 7; i++) { printf("%d ", rättRad[i]); } Sleep(2000); printf("\n\nTack för att du har spelat EC Lotto! Ha en bra dag!\n\n"); }

Permalänk
Medlem

Det är bara att gå igenom arrayen innan du stoppar in talet. Kolla om talet redan finns eller inte.

Ser ut som att du bara behöver byta if(nummer[i]==mummer[j]) till if(nummer[j] != nr)

Dålig läsbarhet på koden dock. Lite för tillkrånglat med dubbelnegationer och så, men det är vanligt när man är ny på det. Jag hade skrivit det såhär:

for ( i = 0; i < 7; i++) { int new_number; do { new_number = (rand()%35)+1; bool found_duplicate = false; for (int j = 0; j < i; j++) { if (number[j] == new_number) { found_duplicate = true; break; } } } while(found_duplicate); number[i] = new_number; printf("Nummer %d: %d\n", i+1, nr); }

Och skriv på engelska, dina framtida kollegor kommer att hata dig annars.

Jag är lite rostig på C, så syntaxfel kan förekomma.

Permalänk
Medlem
Skrivet av dlq84:

Det är bara att gå igenom arrayen innan du stoppar in talet. Kolla om talet redan finns eller inte.

Ser ut som att du bara behöver byta if(nummer[i]==mummer[j]) till if(nummer[j] != nr)

testade men får då alla samma nummer vid dragningen..

Permalänk
Medlem
Skrivet av ivana89:

testade men får då alla samma nummer vid dragningen..

Kolla igen, uppdaterat

Permalänk
Medlem
Skrivet av dlq84:

Kolla igen, uppdaterat

testade precis nu och det verkar som att det fryser sig när en dubblett hittas.. dragningen bara stoppas vid något nummer..

Permalänk
Medlem
Skrivet av dlq84:

Och skriv på engelska, dina framtida kollegor kommer att hata dig annars.

Jag är lite rostig på C, så syntaxfel kan förekomma.

Och ja jag ska försöka skriva på engelska from nu, lika bra att börja träna redan nu
Innan läste jag C# för att komma in på utbildningen och nu läser vi C :'D, from nästa vecka går vi över till C++, sedan Phyton.. det blir mycket att ta in på så kort tid..
Jag är tacksam för all hjälp jag kan få här <3 <3 <3

Permalänk
Medlem

@ivana89: Koden är lite onödigt krånglig just nu, du behöver egentligen inte do-loopen utan du kan låta den yttre loopen köra tills arrayen är full istället. D.v.s.:

for (i = 0; i < 7;) { nr=(rand()%35)+1; if (nr inte finns i arrayen) { number[i] = nr; i++; } }

För att kolla om ett nummer redan finns i arrayen så är det förstås bara att loopa igenom den, men du kan med fördel lägga den biten i en separat funktion för att göra koden mer överskådlig.

Permalänk
Medlem
Skrivet av perost:

@ivana89: Koden är lite onödigt krånglig just nu, du behöver egentligen inte do-loopen utan du kan låta den yttre loopen köra tills arrayen är full istället. D.v.s.:

for (i = 0; i < 7;) { nr=(rand()%35)+1; if (nr inte finns i arrayen) { number[i] = nr; i++; } }

För att kolla om ett nummer redan finns i arrayen så är det förstås bara att loopa igenom den, men du kan med fördel lägga den biten i en separat funktion för att göra koden mer överskådlig.

Tack för ditt svar:) Ja, jag har krånglat till det ordentligt efter 3 dagar med att lösa dubbletter..
Har testat som du skrev men nu får jag bara plats 2,4,6,8 i arrayen utskrivna.. varför blir det så nu?

skrev så här:

int automatisk(void) { int i; for ( i = 0; i < 7; i++) { int nr; nr=(rand()%35)+1; if(nummer[i]!=nr) { nummer[i]=nr; i++; } Sleep(600); printf("Nummer %d: %d\n", i+1, nr); } printf("\nTryck ENTER för att fortsätta...\n\n"); getch(); }

Permalänk
Medlem

@ivana89: För det första så har du fortfarande i++ i for-satsen, så du ökar alltid i i varje iteration istället för varje gång du lägger till ett nytt värde.

Och för det andra så kollar du bara om den nuvarande platsen i arrayen har samma värde som nr. nummer[i] kommer alltid vara 0 eftersom du inte tilldelat något värde till den platsen än¹ och nr kommer alltid vara minst 1, så nummer[i] != nr kommer alltid vara sant. Du ökar därför i två gånger i varje iteration av loopen.

¹ Variabler i C initieras normalt inte, om du inte tilldelar dem något värde så kommer de bara innehålla värdet som redan råkar ligga i minnet de tilldelats. Globala variabler är ett undantag och initialiseras till 0 (men bör undvikas eftersom de gör koden väldigt svår att följa så fort man har lite större program).

Permalänk
Medlem
Skrivet av perost:

@ivana89: För det första så har du fortfarande i++ i for-satsen, så du ökar alltid i i varje iteration istället för varje gång du lägger till ett nytt värde.

Och för det andra så kollar du bara om den nuvarande platsen i arrayen har samma värde som nr. nummer[i] kommer alltid vara 0 eftersom du inte tilldelat något värde till den platsen än¹ och nr kommer alltid vara minst 1, så nummer[i] != nr kommer alltid vara sant. Du ökar därför i två gånger i varje iteration av loopen.

¹ Variabler i C initieras normalt inte, om du inte tilldelar dem något värde så kommer de bara innehålla värdet som redan råkar ligga i minnet de tilldelats. Globala variabler är ett undantag och initialiseras till 0 (men bör undvikas eftersom de gör koden väldigt svår att följa så fort man har lite större program).

Tack så mycket, fick till det till slut med en while-loop som ska köras så länge som i är mindre än 7, och så inuti den först rand() och sedan en for-loop för jämföresle och inuti for-loppen en if-block som hittar dubbletter, därefter en till if utanför for-loopen som kollar om det inte var dubblett. Tack för att ni tog er tid att hjälpa till. Trevlig helg!!

Permalänk
Medlem
Skrivet av ivana89:

När en dubblett slumpas fram ska det slumpas igen för att få ett nytt nummer.

Om man bygger sitt program på principen att slumpa fram ett nummer, och om det inte är unikt slumpa fram ett nytt, så kan man ibland få slumpa om väldigt många gånger, särskilt om antalet nummer som skall väljas är nära antalet valbara nummer.

Ponera att man skall slumpa fram 999999 st unika nummer mellan 1 och 1000000, och man gör detta genom att anropa rand(1,1000000) 999999 ggr, och när man stöter på ett redan valt nummer så slumpar man om. Ponera vidare att man nått fram till det 999999:e numret som skall slumpas fram. Då finns endast 2 nummer som inte redan valts. Då slumpar man alltså om och om igen tills rand(1,1000000) träffar ett av dessa två nummer.

Det finns betydligt smartare sätt att få fram unika nummer. Att exkludera redan valda nummer från nästkommande slumpning gör att inga omslumpningar behövs. En enkel metod är:

Skapa en array innehållande alla nummer (som exempel här använder jag "välj 3 nr mellan 1 och 10").
[1,2,3,4,5,6,7,8,9,10]
Slumpa fram ett index mellan 0 och 9 (ponera 5).
Byt plats på talen på det framslumpade indexet och det sista möjliga indexet (9).
[1,2,3,4,5,10,7,8,9,6] // 6:an är här vald och skall inte ingå i nästa slumpning
Slumpa fram ett index mellan 0 och 8 (ponera 2).
Byt plats på talen på det framslumpade indexet och det sista möjliga indexet (8).
[1,2,9,4,5,10,7,8,3,6] // 3:an och 6:an är här valda och skall inte ingå i nästa slumpning
Slumpa fram ett index mellan 0 och 7 (ponera 2 igen).
Byt plats på talen på det framslumpade indexet och det sista möjliga indexet (7).
[1,2,8,4,5,10,7,9,3,6] // 3:an, 6:an och 9:an är här valda...och vi har nu tre nr.