C# - Uppdaterad med ny fråga! Array i en annan klass till använding i main()?

Permalänk
Medlem

C# - Uppdaterad med ny fråga! Array i en annan klass till använding i main()?

Är riktigt färsk på OOP så kan ha fårr hela det här om bakfoten. Det är en uppgift i skolan men läraren svarar inte och tiden rinner ut så om man kunde få lite förklaring så hade det vart guld med.

Har en switch sats i main som fungerar som en meny, vid en case så ska jag kunna fylla på en array med input som ska lagras i en annan klass.

class spara { public static void words() { String[] Ord = new String[5]; Ord[0] = Console.ReadLine(); //spelaren till delar varje index i arrayen ett ord Ord[1] = Console.ReadLine(); Ord[2] = Console.ReadLine(); Ord[3] = Console.ReadLine(); Ord[4] = Console.ReadLine(); HängaGubbe.Main(); } }

Lyckas få in ord i en array, men hur tusan ska jag få så att de går att använda utanför klassen? Känns som jag testat allt.

Permalänk
Medlem

Du kan ju skicka med arrayen som en parameter till HängaGubbe.Main, så du ropar på HängaGubbe.Main(Ord);

Blanda inte engelska och svenska (words, Ord, HängaGubbe, Main etc)...

Visa signatur

Jag är en optimist; det är aldrig så dåligt så att det inte kan bli sämre.

Permalänk

Du måste skicka med Arrayen i anropet till HängaGubbe.Main(). Sen måste din Main i HängaGubbe kunna hantera argumentet.
HängaGubbe.Main(Ord);

Permalänk
Medlem
Skrivet av Misspenguin:

Sen måste din Main i HängaGubbe kunna hantera argumentet.

Tack för svar.

Hur går det till?

Edit: asså!, ni mena i main huvudet Main(String[] Ord)

för nu fungerar det, men har för mig man inte får lägga saker där? Eller kanske bara inbillat mig det för det låter knäppt.

Permalänk
Medlem
Skrivet av swennor:

Tack för svar.

Hur går det till?

Edit: asså!, ni mena i main huvudet Main(String[] Ord)

för nu fungerar det, men har för mig man inte får lägga saker där? Eller kanske bara inbillat mig det för det låter knäppt.

Förmodligen ska du inte anropa Main i HängaGubbe alls från din nya klass. Om vi bortser från att den på namnet låter som att det är den metoden som drar igång hela programmet och absolut inte bör anropas där, så vore det rimligare att bara returnera och låta programmet fortsätta där det var innan anropet.

Jag tror det bästa är att du läser uppgiften du fått igen i lugn och ro och tittar på vad den faktiskt be dig göra. Oftast är uppgifterna formulerade så att det i kombination med kurslitteraturen med lite tankemöda är uppenbart vad som skall göras. Men om du nu ska lagra något i en klass kanske det kan vara en idé att kolla upp instansvariabler till att börja med, och fundera på vad static innebär, och hur objekt förhåller sig till klasser.

Permalänk
Avstängd

Nej, nej, nej. Man ska inte hålla på och skicka runt beroenden på detta vis.. Abstrahera beroendet till ett interface, använd sedan en DI för att injicera beroendet när de krävs. Inversion of control

Visa signatur
Permalänk
Medlem
Skrivet av CyberVillain:

Nej, nej, nej. Man ska inte hålla på och skicka runt beroenden på detta vis.. Abstrahera beroendet till ett interface, använd sedan en DI för att injicera beroendet när de krävs. Inversion of control

Jösses, har du läst en bok om patterns nyligen eller? Nej, man behöver inte använda dependency injection för att göra ett hänga-gubbe spel för en skoluppgift.

Main-metoden är ditt programs startpunkt, den som först anropas när du kör programmet, därför bör du som sagt inte anropa den själv. Snarare är det förmodligen så att du från den anropar din metod "words" och därifrån går vidare till en ny metod som tar emot din array som argument (ex "Hängagubbe.GörNågotMedOrd(string[] ord) {.... })

Här är en fördjupande förklaring om tanken bakom Main-metoden:
https://en.wikipedia.org/wiki/Main_function

Permalänk
Avstängd

I från Main ska du enbart invoka din Bootstrapper och dra igång din mainclass

Här är ett exempel på en bra Main (Jag som skrivit den)
https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE...

Tänker inte ens bemöda mig med din kommentar "Arkitekten". jag har använt IoC som pattern långt innan termen var myntad

Visa signatur
Permalänk
Medlem

CyberVillain har ju rätt i sak, MEN eftersom det tydligt framgår av frågeställningen att det är en skoluppgift, så är ju svaret helt uppåt väggarna "fel". Det är väldigt osannolikt att trådskaparen gynnas av denna information, hur rätt den än är.

En tidigare rage-post från mig pekar på just detta problem med att svara på allt för hög nivå. Det finns ju faktiskt en anledning till att man i skolan börjar lära sig bokstäver, sedan läser man ord, för att långt senare komma in på grammatikens regler. På samma sätt börjar man ju inom programmeringen med Hello World, för att sedan ge sig på if/else, funktioner, klasser osv. Lika lite som man direkt ger sig på att läsa grammatik i första klass, ger man sig på design patterns när man lär sig programmera. Dessutom kan allt för avancerade svar (hur rätt de än är!) få till följd att man faktiskt inte fortsätter med programmeringen alls.

Den som med gott samvete kan säga att hen ALLTID (från sina första stapplande steg inom programmering) har gjort enligt best practices kan räcka upp en hand. Jag gör det då iaf inte...

(Som en liten personlig parentes undrar jag hur gammal CyberVillain är, då IoC som term dök upp 1988 [källa]. På den tiden knackade jag nog Basic på C-64 (möjligen Vic-20) och då var det inte tal om IoC för mig iaf... )

Visa signatur

as far as we can tell, the massacre went well...

Permalänk
Avstängd

1988 var det mest HP Basic för mig Okej jag överdrev väl lite då

Jag förväntar mig inte att han ska kunna det, MEN, och ett stort men. Folk här föreslår att skicka runt beroenden utan att även förklara att det inte är ett bra sett.

Visa signatur
Permalänk
Avstängd

Ett problem med IoC och DI är ju att man ibland har ett beroende av föräldern som inte går att abstrahera bort via IoC. Vad jag då brukar göra är att injecera typen via DIn men sedan ha en Init metod som tar beroendet, på så sätt kan man iallafall skicka in beroenden via konstruktorn. Exemple

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE...

edit: Dock lever man inte alltid som man lär https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE...

Visa signatur
Permalänk
Medlem

Newb strikes again!

Tack för svaren men hittade ett sätt som fungerade. Nu till ett annat krångel.

for (int i = 0; i < rOrd.Length; i++) //loop igenom rOrds längd { if (sGiss == rOrd[i]) //om bokstaven som spelaren gissade med är lika med nånstans i rOrds bokstäver { chrray[i] = sGiss; //så lägg spelarens bokstav i chhray arrayens samma index som räknaren var i rOrd. if (check == rOrd) { Console.WriteLine("grattis"); } } }

rOrd är en random string.
chrray är en char array av samma storlek som rOrd där varje bokstav i rOrd är bytt mot - i chhray
sGiss är spelarens gissning.
check är en string av chhray (String check = new String(chhray)????)

Mitt problem är att mitt "grattis" vill inte skrivas ut när hela ordet är avlöjat, tycker ändå det borde fungera då check == rOrd borde bli sant om sista bokstaven blir prickad och därmed skrivas ut, men nada händer.

Permalänk
Medlem

Det verkar inte som om du instansierar check efter du lagt in bokstaven i chrray, lägg in koden

String check = new String(chrray);

direkt innan

if (check == rOrd)

så ska du ser den funkar bättre.

Permalänk
Medlem
Skrivet av The-Architect:

Det verkar inte som om du instansierar check efter du lagt in bokstaven i chrray, lägg in koden

String check = new String(chrray);

direkt innan

if (check == rOrd)

så ska du ser den funkar bättre.

Tack, trodde jag testade det men nix!

Men while sats vill dock inte brytas :S

while (klar == false || fel != 0) { Console.WriteLine("\n\tGissa en bokstav! " + missar + "/" + fel + " fel.\n"); Console.Write("\n\t"); Console.Write(chrray); Console.Write("\n\t"); char sGiss = char.Parse(Console.ReadLine()); //spelarens gissning for (int i = 0; i < rOrd.Length; i++) //loop igenom rOrds längd { if (sGiss == rOrd[i]) //om bokstaven som spelaren gissade med är lika med nånstans i rOrds bokstäver { chrray[i] = sGiss; //så lägg spelarens bokstav i chhray arrayens samma index som räknaren var i rOrd. String check = new String(chrray); if (check == rOrd) { MessageBox.Show(rOrd + " var rätt! Du slapp bli hängd!"); klar = true; } } }

Permalänk
Medlem
Skrivet av swennor:

Vad är värdet av fel? Är det möjligtvis något annat än 0?

Permalänk
Medlem
Skrivet av The-Architect:

Vad är värdet av fel? Är det möjligtvis något annat än 0?

Borde det spela roll då jag har "or" och inte &&? Men nej det är 0

Permalänk
Medlem
Skrivet av swennor:

Borde det spela roll då jag har "or" och inte &&? Men nej det är 0

Ja det gör det. Så länge klar är false ELLER fel != 0 så kommer din while-loop vara aktiv. men om både klar är true samt fel är 0 så ska din while-loop avslutas, förutsatt det inte händer något mer off-screen, jag ser inte hela while-loopen i din kodsnutt där ovan.

Sedan brukar man även använda !-operatorn för att testa booleans. ! betyder "NOT" Inte för att det är något syntaxfel i din kod, men bara som ett tips:

while(!klar || fel != 0) { ...

Permalänk
Medlem
Skrivet av The-Architect:

Ja det gör det. Så länge klar är false ELLER fel != 0 så kommer din while-loop vara aktiv. men om både klar är true samt fel är 0 så ska din while-loop avslutas, förutsatt det inte händer något mer off-screen, jag ser inte hela while-loopen i din kodsnutt där ovan.

Sedan brukar man även använda !-operatorn för att testa booleans. ! betyder "NOT" Inte för att det är något syntaxfel i din kod, men bara som ett tips:

while(!klar || fel != 0) { ...

Tog bort så bara klar == false finns kvar och satte dit klar = true; vid varje avslut, även fast felen maxas, tänkte lite fel där, men nu funkar det nästan! while loopen avslutas och jag kommer tillbaka till min meny, så det är ju guld.

Stöte på ett annat problem nu dock...

char sGiss = char.Parse(Console.ReadLine()); //spelarens gissning for (int i = 0; i < rOrd.Length; i++) //loop igenom rOrds längd { if (sGiss == rOrd[i]) //om bokstaven som spelaren gissade med är lika med nånstans i rOrds bokstäver { chrray[i] = sGiss; //så lägg spelarens bokstav i chhray arrayens samma index som räknaren var i rOrd. String check = new String(chrray); if (check == rOrd) { MessageBox.Show(rOrd + " var rätt! Du slapp bli hängd!"); klar = true; } } else { missar++; if (missar == fel) { MessageBox.Show("Du blev hängd! Ordet var: " + rOrd + "!"); klar = true; } } }

Hur tusan ska man lösa det så att den inte räknar alla bokstäver som inte stämde som fel utan bara 1 fel? Ganska logiskt att det skulle göra så för det är ju många bokstäver som den räknar igenom som inte stämmer. Men bara så du får se min kod.

fel är någon int och missar startar på 0.

edit: string.Contain() kanske funkar iof

Permalänk
Medlem

du kan ex, runt din forloop lägga ex:

if(rOrd.IndexOf(sGiss) > -1) { //forloop här } else { // spelaren gissade fel, hantera det }

Och sen ta bort else-satsen inne i loopen, för du vet att rOrd innehåller sGiss vid det laget.

IndexOf returnerar vilken position i en viss sträng en annan sträng, eller char ligger på, position 0 är första tecknet. -1 betyder att den inte fanns i strängen alls.

Edit: eller såklart bara använda .Contains()... Jag använder oftast IndexOf så det sitter lite i muskelminnet att jag föreslog det
(skulle kanske finnas argument för att indexof är snabbare då det är en metod på strängobjektet och inte en extension som kan medföra lite overhead, men det är överkurs)

Permalänk
Medlem

Ahh tack, nu löser jag resten!