affe90 Skrevet 20. september 2008 Del Skrevet 20. september 2008 God morgen, godtfolk! Jeg satt på jobben i går og tuklet med C#. Jeg skulle prøve å lage et nummergjettespill som kjørte som et console application. Jeg strevde, men fant ingen løsning på problemet mitt. Jeg brukte IF-setninger til å sjekke om mitt nummer stemte overens med det random nummeret som ble generert. Programmet stoppet etter at den fant ut av at en av de 3 IF-ene mine var true. Det ville ikke jeg ha noe av. Derfor kom jeg i kontakt med en gammel Fortran-programmerer som sa; bruk labels og goto! Jeg gjorde det og alt funket slik jeg ville. Etter en samtale med Manfred på MSN satt han å gråt siden jeg fortalte at jeg hadde funnet nytten i bruken av GoTo. Han fortalte at det hadde vært diskusjoner rundt dette og konklusjonen ble: Dårlig programmering. Så derfor trenger jeg litt inspill fra dere andre her rundt dette og gode begrunnelser på hvorfor akkurat dette er dårlig programmering. Her er et eksempelprogram som jeg har brukt GoTo i. Skriv gjerne om uten GoTo for å motbevise meg. Random rnd = new Random(); // Fyrer opp random funksjon int number = rnd.Next(1, 11); // Gir en variabel et tall som blir generert av random (fra 1 - 10) gjettigjen: // Gir prosessen der brukeren skirver inn et tall en label Console.Write("Gjett et nummer fra 1 til 10\n"); // Skriver ut noe vræl int nummer = Int32.Parse(Console.ReadLine()); // Det brukeren skrev blir lagret i en variabel // Begynner med første IF if (nummer == number) { Console.WriteLine("Bra gjettet!"); } // Andre IF-setning if (nummer < number) { Console.WriteLine("Du må gjette høyere"); goto gjettigjen; // Sender brukeren tilbake til starten, altså der jeg satt den første labelen } // Tredje IF-setning if (nummer > number) { Console.WriteLine("Du må gjette lavere"); goto gjettigjen; // Sender brukeren tilbake til starten, altså der jeg satt den første labelen } Lenke til kommentar
steingrim Skrevet 20. september 2008 Del Skrevet 20. september 2008 (endret) Etter en samtale med Manfred på MSN satt han å gråt siden jeg fortalte at jeg hadde funnet nytten i bruken av GoTo. Jeg føler med deg Manfred... Han fortalte at det hadde vært diskusjoner rundt dette og konklusjonen ble: Dårlig programmering. Så derfor trenger jeg litt inspill fra dere andre her rundt dette og gode begrunnelser på hvorfor akkurat dette er dårlig programmering. goto gjør at koden din blir ufattelig vanskelig å lese. Kode leses gjerne mange ganger etter at den er skrevet. Jeg hadde problemer med å lese den bittelille kodesnutten din rett og slett fordi jeg ikke fant gjettigjen-labelen ved første og andre gjennomlesing. Hvis du synes din løsning er lettere å lese enn min så er det noe galt med deg Denne koden kunne utvilsomt vært skrevet kortere, men dette er den mest lesbare varianten jeg kommer på nå. Edit: jeg utfordrer deg til å endre koden din til å tillate maks 3 forsøk -- selvsagt klarer du det, men hvor enkelt er det å utvide koden din ift min? using System; class Program2 { public static void Main(string[] args) { Random rnd = new Random(); int number = rnd.Next(1, 11); while (true) { Console.WriteLine("Gjett et nummer fra 1 til 10"); int guess = Int32.Parse(Console.ReadLine()); if (guess == number) { Console.WriteLine("Bra gjettet!"); break; } if (guess < number) { Console.WriteLine("Gjett høyere"); } else { Console.WriteLine("Gjett lavere"); } } } } Endret 20. september 2008 av steingrim Lenke til kommentar
affe90 Skrevet 20. september 2008 Forfatter Del Skrevet 20. september 2008 Etter en samtale med Manfred på MSN satt han å gråt siden jeg fortalte at jeg hadde funnet nytten i bruken av GoTo. Jeg føler med deg Manfred... Han fortalte at det hadde vært diskusjoner rundt dette og konklusjonen ble: Dårlig programmering. Så derfor trenger jeg litt inspill fra dere andre her rundt dette og gode begrunnelser på hvorfor akkurat dette er dårlig programmering. goto gjør at koden din blir ufattelig vanskelig å lese. Kode leses gjerne mange ganger etter at den er skrevet. Jeg hadde problemer med å lese den bittelille kodesnutten din rett og slett fordi jeg ikke fant gjettigjen-labelen ved første og andre gjennomlesing. Hvis du synes din løsning er lettere å lese enn min så er det noe galt med deg Denne koden kunne utvilsomt vært skrevet kortere, men dette er den mest lesbare varianten jeg kommer på nå. Edit: jeg utfordrer deg til å endre koden din til å tillate maks 3 forsøk -- selvsagt klarer du det, men hvor enkelt er det å utvide koden din ift min? using System; class Program2 { public static void Main(string[] args) { Random rnd = new Random(); int number = rnd.Next(1, 11); while (true) { Console.WriteLine("Gjett et nummer fra 1 til 10"); int guess = Int32.Parse(Console.ReadLine()); if (guess == number) { Console.WriteLine("Bra gjettet!"); break; } if (guess < number) { Console.WriteLine("Gjett høyere"); } else { Console.WriteLine("Gjett lavere"); } } } } Jeg takker for et utrolig fint svar! Jeg forstår deg siden du forklarte på en utrolig god måte. Jeg prøvde en slik utforming og struktur som du hadde, men bare at jeg rota det til litt så jeg prøvde meg på en annen løsning. Nok en gang for flott svar. Jeg tok utfordringen din, men kunne den blitt løst på en annen måte? Lettere å ha oversikt i din kode, helt enig. Dette ble løsningen using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Gjettespillet { class Program { static void Main(string[] args) { Random rnd = new Random(); int number = rnd.Next(1, 11); int numberOfTries = 0; gjettigjen: if (numberOfTries >= 3) { Console.WriteLine("Game Over"); Environment.Exit(1); } Console.Write("Gjett et nummer fra 1 til 10\n"); int nummer = Int32.Parse(Console.ReadLine()); if (nummer == number) { Console.WriteLine("Bra gjettet!"); } if (nummer < number) { Console.WriteLine("Du må gjette høyere"); numberOfTries++; goto gjettigjen; } if (nummer > number) { Console.WriteLine("Du må gjette lavere"); numberOfTries++; goto gjettigjen; } } } } Lenke til kommentar
steingrim Skrevet 20. september 2008 Del Skrevet 20. september 2008 Så da lover du å holde deg unna goto framover? Legg merke til at avstanden mellom nederste goto og labelen din økte da du la til tellingen... Slikt blir bare verre! Det var det jeg mente. Men altså, hold deg unna Lenke til kommentar
affe90 Skrevet 20. september 2008 Forfatter Del Skrevet 20. september 2008 Skal holde meg unna! Hehe, kanskje bruke det i forbindelse med noen eksempler i en bok jeg jobber med, men ellers så skal jeg tråkke, spytte og kaste goto til et sted i Sverige. Takk skal du ha! Lenke til kommentar
Glenn F. Henriksen Skrevet 21. september 2008 Del Skrevet 21. september 2008 (endret) Mitt forslag til løsning: Random rnd = new Random(); int target = rnd.Next(1, 11); int maxTries = 3; int guess = 0; int failedTries = 0; Console.Write("Gjett et nummer fra 1 til 10\n"); while (target != guess && failedTries < maxTries) { if (Int32.TryParse(Console.ReadLine(), out guess)) { Console.WriteLine("Du må skrive inn et heltall."); } else { if (target == guess) { Console.WriteLine("Bra gjettet!"); } else if (target > guess) { Console.WriteLine("Du må gjette høyere"); failedTries++; } else { Console.WriteLine("Du må gjette lavere"); failedTries++; } } } if (failedTries >= maxTries) { Console.WriteLine("Game Over"); } Forskjellen mellom mitt og Steingrim sitt forslag er hovedsaklig testen på suksess i while-løkken og den tilhørende mangelen på break eller andre plutselige hopp ut av et område. Det er ikke noe objektivt galt med den metoden å gjøre ting på, dette er mest for å illustrere en annen måte å gjøre det på. I dette eksempelet vil kjøringen av programmet følge koden nedover siden, uten plutselige avbrudd. Noen mener at dette gir en mer leselig og en mer forståelig kode, andre bryr seg ikke og noen synes at det andre alternativet gir en enklere struktur og at det er lettere å forstå. Det er mest et spørsmål om smak. En annen forskjell på mitt og ditt forslag er bruken av if {} else if strukturen. Hvis en av if-ene slår til vil de andre hoppes over. I ditt tilfelle vil hver test kjøres, selv om den første slo til. Jeg har også byttet ut Int32.Parse med int.TryParse. Int32 er en BCL type, med mindre du har et spesielt behov for å angi en bestemt BCL type synes jeg det er en fordel å holde seg til de typene som er i språket du bruker, i dette tilfellet "int". Selv om de i nesten alle tilfeller er det samme synes jeg at lesbarheten og forståelsen er bedre når man bruker den samme betegnelsen. TryParse er en funksjon som ikke kaster et unntak hvis du forer den med noe annet en ett heltall (siden vi bruke int.TryParse). Det gjør programmet ditt mer robust og at det tryner mindre. Endret 21. september 2008 av Glenn F. Henriksen Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå