Permalänk

Hjälp i c# gissa nummer

Tjena alla!
Har nyligen börjat studera programmering i c# och nu har jag fastnat lite.
Min uppgift är att göra ett "spel" där man ska gissa på ett nummer mellan 1-100.
Jag har fått det att funka hyfsat men problemet jag har är att jag måste använda en do och while loop, och det har låst sig lite i mitt huvud.
Jag vill nämligen att man får lite hjälp genom att du får information om att talet är större och mindre, men iom min do-while loop så körs inte större eller mindre första gången och jag har stopp i huvudet. Säkert lätt att fixa, men jag har låst mig, här kommer koden.

Console.WriteLine("Välkommen till ett spel där du gissar nummer?");
Random randomerare = new Random();
int slump_tal = randomerare.Next(1, 100);
Console.WriteLine("Gissa på ett tal mellan 1 och 100");
string str = Console.ReadLine();
int tal = Convert.ToInt32(str);

do
{
Console.WriteLine("Fel gissa igen!");
str = Console.ReadLine();
tal = Convert.ToInt32(str);
if (tal > slump_tal)
{
Console.WriteLine("Talet är mindre");
}
else if (tal < slump_tal)
{
Console.WriteLine("Talet är större");
}

}
while (tal != slump_tal);
Console.WriteLine("Grattis du gissade rätt");
Console.ReadLine();

Permalänk
Medlem

Du kollar ju aldrig värdet på första gissningen. Man skulle kunna lösa det genom att ta bort ReadLine från innan do-while samt ha en bool som anger ifall det är första gissningen eller inte, och i så fall inte skriva ut "Fel gissa igen!". Typ såhär:

Console.WriteLine("Välkommen till ett spel där du gissar nummer?"); Random randomerare = new Random(); int slump_tal = randomerare.Next(1, 100); Console.WriteLine("Gissa på ett tal mellan 1 och 100"); string str; int tal; bool isFirstTime = true; do { if (!isFirstTime) { Console.WriteLine("Fel gissa igen!"); } str = Console.ReadLine(); tal = Convert.ToInt32(str); if (tal > slump_tal) { Console.WriteLine("Talet är mindre"); } else if (tal < slump_tal) { Console.WriteLine("Talet är större"); } isFirstTime = false; } while (tal != slump_tal); Console.WriteLine("Grattis du gissade rätt"); Console.ReadLine(); }

Permalänk
Hedersmedlem

Hej!

Du är rätt nära den korrekta lösningen. Gå igenom steg för steg vad programmet gör så tror jag att du fattar vad som händer.

Se nedan för en av mig kommenterad version av din kod, så tror jag att du snabbt ser vad som är fel.

/* Först så gör vi lite setup, säger hej och skapar en slumpgenerator */ Console.WriteLine("Välkommen till ett spel där du gissar nummer?"); Random randomerare = new Random(); /* Vi slumpar fram ett tal. slump_tal ändras aldrig under körningen */ int slump_tal = randomerare.Next(1, 100); /* Vi erbjuder spelaren att gissa tal första gången */ Console.WriteLine("Gissa på ett tal mellan 1 och 100"); string str = Console.ReadLine(); /* läser text från konsollen */ int tal = Convert.ToInt32(str); /* behandlar det som en siffra och lagrar i tal, variabeln "tal" håller alltså gissningen */ do { /* Här skriver vi ut att spelaren har fel. Men, stämmer det här? Om det här är första körningen så har vi inte kollat om spelaren har rätt innan vi bombsäkert säger att spelaren har fel. */ Console.WriteLine("Fel gissa igen!"); /* vi läser in en ny gissning på samma sätt som koden ovan */ str = Console.ReadLine(); tal = Convert.ToInt32(str); /* först här kollar vi om gissningen är rätt eller inte! */ /* gissningen som kollas är alltså den som precis matades in... */ if (tal > slump_tal) { Console.WriteLine("Talet är mindre"); } else if (tal < slump_tal) { Console.WriteLine("Talet är större"); } } while (tal != slump_tal); /* den här "while"-satsen hör till do-blocket ovan, d.v.s. först vid loopens slut kollar vi om spelaren gissat fel */ /* vi är nu ute ur loopen vilket betyder att spelaren gissat rätt */ Console.WriteLine("Grattis du gissade rätt"); Console.ReadLine();

Fundamentalt tror jag att du behöver ha koll på skillnaden mellan en do-while-loop och en while-loop.

En do-while-loop kör alltid igenom "do"-blocket minst en gång, och kollar först i slutet av blocket om det ska köras igen.

En while-loop kollar INNAN blocket körs om blocket behöver köras, det är alltså möjligt att ett while-block inte körs alls. Tänk på en while-loop ungefär som en if-sats, med skillnaden att blocket körs tills att if-satsen är falsk.

P.S. När du postar kod, lägg in mellan [ code ] och [ /code ] (inga mellanslag i taggen, det är bara så att det skulle gå att skriva om taggen utan att den behandlas. Då går det att se indentering och blir lättare att läsa.

Lite bättre formatering på kommentarerna
Permalänk
Medlem

Du använder ju do/while så länge som användaren inte gissat rätt, så kan du inte strukturera om koden så att det första som händer i do/while är utskriften av hjälptexten?

Permalänk
Medlem
Skrivet av pv2b:

Fundamentalt tror jag att du behöver ha koll på skillnaden mellan en do-while-loop och en while-loop.

En do-while-loop kör alltid igenom "do"-blocket minst en gång, och kollar först i slutet av blocket om det ska köras igen.

En while-loop kollar INNAN blocket körs om blocket behöver köras, det är alltså möjligt att ett while-block inte körs alls. Tänk på en while-loop ungefär som en if-sats, med skillnaden att blocket körs tills att if-satsen är falsk.

Bra poäng, men..
Enligt TS så måste han använda do-while. Men håller med, vore bättre med en ren while-loop.

Permalänk
Medlem

@toobypls Eller bara lägga in utskriften i den existerande if-satsen, så slipper man hålla reda på det:

if (tal > slump_tal) { Console.WriteLine("Talet är mindre"); Console.WriteLine("Fel gissa igen!"); } else if (tal < slump_tal) { Console.WriteLine("Talet är större"); Console.WriteLine("Fel gissa igen!"); }

Alternativt:

if (tal != slump_tal) { String s = tal > slump_tal ? "större" : "mindre"; Console.WriteLine("Talet är " + s); Console.WriteLine("Fel gissa igen!"); }

Permalänk
Hedersmedlem
Skrivet av toobypls:

Bra poäng, men..
Enligt TS så måste han använda do-while. Men håller med, vore bättre med en ren while-loop.

OK. Släng in följande någonstans i programmet, så har han klarat uppgiften

do {} while(0);

Skämt åsido, jag har inte sagt åt honom vilken looptyp han ska köra, bara förklarat för honom exakt hur hans nuvarande program fungerar.

Permalänk
Medlem
Skrivet av perost:

@tahmady Eller bara lägga in utskriften i den existerande if-satsen, så slipper man hålla reda på det:

if (tal > slump_tal) { Console.WriteLine("Talet är mindre"); Console.WriteLine("Fel gissa igen!"); } else if (tal < slump_tal) { Console.WriteLine("Talet är större"); Console.WriteLine("Fel gissa igen!"); }

Alternativt:

if (tal != slump_tal) { String s = tal > slump_tal ? "större" : "mindre"; Console.WriteLine("Talet är " + s); Console.WriteLine("Fel gissa igen!"); }

Yep, funkar också. Min variant var den första jag kom på.

Permalänk
Medlem
Skrivet av pv2b:

OK. Släng in följande någonstans i programmet, så har han klarat uppgiften

do {} while(0);

Skämt åsido, jag har inte sagt åt honom vilken looptyp han ska köra, bara förklarat för honom exakt hur hans nuvarande program fungerar.

Hehe

Du var lite mer pedagogisk än vad jag var när jag bara postade en lösning utan att riktigt hjälpa till genom att förklara.

Permalänk

Fy fan va grymma ni är och vilken respons!!!
Tack alla!

Som sagt så är jag tvungen att köra en do-while loop och inget annat.
Borde kanske även nämnt att jag inte får använda bool eller break i denna koden alls.

Skrivet av perost:

@tahmady Eller bara lägga in utskriften i den existerande if-satsen, så slipper man hålla reda på det:

if (tal > slump_tal) { Console.WriteLine("Talet är mindre"); Console.WriteLine("Fel gissa igen!"); } else if (tal < slump_tal) { Console.WriteLine("Talet är större"); Console.WriteLine("Fel gissa igen!"); }

Alternativt:

if (tal != slump_tal) { String s = tal > slump_tal ? "större" : "mindre"; Console.WriteLine("Talet är " + s); Console.WriteLine("Fel gissa igen!"); }

Jag försökte mig på detta men fastnar fortfarande på att första gissningen hamnar liksom utanför och får inte responsen "talet är större" alternativt "talet är mindre".
Kanske är hjärndöd här men de vill sig inte riktigt.

Permalänk
Hedersmedlem
Skrivet av mjolkbollen:

Fy fan va grymma ni är och vilken respons!!!
Tack alla!

Som sagt så är jag tvungen att köra en do-while loop och inget annat.
Borde kanske även nämnt att jag inte får använda bool eller break i denna koden alls.

Jag försökte mig på detta men fastnar fortfarande på att första gissningen hamnar liksom utanför och får inte responsen "talet är större" alternativt "talet är mindre".
Kanske är hjärndöd här men de vill sig inte riktigt.

Ingen fara.

Det jag skulle göra i ditt läge vore att sätta upp lite "pseudokod" för hur programmet bör funka. Pseudokod för programmet som du har skrivit är så här:

säg hej! slumpa fram ett värde be spelaren att gissa (första gången) gör följande: säg att spelaren har fel be spelaren att gissa (igen) säg till om gissningen är för hög säg till om gissningen är för låg upprepa enligt ovan om gissningen är felaktig gratulera spelaren till en korrekt gissning! avsluta programmet

Utifrån programmet ovan tror jag att du fattar vad som är fel och vad du bör göra istället. Fixa pseudokoden, och sedan är det bara att skriva det som riktig kod istället!

Med lite övning och väl kommenterad och strukturerad kod kommer du inte behöva skriva ner pseudokoden först, men det är ett bra verktyg för att göra det enklare att tänka efter.

Permalänk
Medlem
Skrivet av mjolkbollen:

Jag försökte mig på detta men fastnar fortfarande på att första gissningen hamnar liksom utanför och får inte responsen "talet är större" alternativt "talet är mindre".
Kanske är hjärndöd här men de vill sig inte riktigt.

Om du gör som pv2b tipsar om så kan du säkert lösa det, men ett tips är att du bara behöver läsa in gissningar från användaren på ett ställe och inte på två olika som du gör nu.

Permalänk
Medlem

Nu är du ju nybörjare, men försök gärna använda naming conventions så gott du kan:

Skriv alla namn på engelska.
Skriv variabelnamn med camelcase, dvs "randomNumber" t ex

Lycka till.

Permalänk
Medlem

Det finns ingen anledning att ha ett specialfall för första gissningen.

Exempelvis kan koden skrivas som:

Console.WriteLine("Välkommen till ett spel där du skall finna ett specifikt tal mellan 1 och 100.") int random_number = new Random().Next(1, 100); int guess = 0; do { Console.WriteLine("Gissa på ett tal:"); guess = Convert.ToInt32(Console.ReadLine()); if (guess > random_number) { Console.WriteLine("Gissa på ett lägre tal nästa gång."); } if (guess < random_number) { Console.WriteLine("Gissa på ett högre tal nästa gång."); } } while (guess != random_number); Console.WriteLine("Du gissade rätt!!!");

Visa signatur

Laptop: Dell Latitude E7270 | 12,5" FHD IPS | i5-6300U | 16GB RAM | 500GB SSD
Laptop: MacBook Air 13"
NUC: Intel i5-4250U | 8GB RAM | 250GB SSD

Permalänk

Vill bara tacka alla som tog sin tid och hjälpte mig!!

Skrivet av PeCe:

Det finns ingen anledning att ha ett specialfall för första gissningen.

Exempelvis kan koden skrivas som:

Console.WriteLine("Välkommen till ett spel där du skall finna ett specifikt tal mellan 1 och 100.") int random_number = new Random().Next(1, 100); int guess = 0; do { Console.WriteLine("Gissa på ett tal:"); guess = Convert.ToInt32(Console.ReadLine()); if (guess > random_number) { Console.WriteLine("Gissa på ett lägre tal nästa gång."); } if (guess < random_number) { Console.WriteLine("Gissa på ett högre tal nästa gång."); } } while (guess != random_number); Console.WriteLine("Du gissade rätt!!!");

Det där fick ordning på allt, tusen tack!

Permalänk
Hedersmedlem

do-while är helt korrekt att använda för det här problemet eftersom man vet att det ska göras minst en koll vilket är det enda som egentligen skiljer en do-while från en while, villkoret kollas i slutet istället för början.

Börjar man klura på specialfall ska man vara säker på att det verkligen behövs. Ofta går det att undvika.

Permalänk
Medlem
Skrivet av Baxtex:

Nu är du ju nybörjare, men försök gärna använda naming conventions så gott du kan:

Skriv alla namn på engelska.
Skriv variabelnamn med camelcase, dvs "randomNumber" t ex

Lycka till.

Det är väldigt vanligt att man skriver variabelnamn med understreck i PHP, typ "$some_value".

Permalänk
Medlem
Skrivet av Tazavoo:

Det är väldigt vanligt att man skriver variabelnamn med understreck i PHP, typ "$some_value".

Fast nu var detta C#. http://www.dofactory.com/reference/csharp-coding-standards

Permalänk
Medlem

Har ingen aning om vad jag tänkte, måste ha hoppat mellan trådar och trott att jag var på en annan. Du har så rätt!