Permalänk
Medlem

Lingospel i c#

Hejhej har ett projektarbete i skolan där vi ska skriva ett Lingospell i C#

Lingo är en typ av hänga gubbe spel där man ska gissa ett ord på X bokstäver (i vårat fall alltid 5).
För att gissa så måste man skriva in ett helt ord på 5 bokstäver och man ska då få en output som visar om bokstäverna finns med i ordet, om dom finns med och är på rätt plats eller om dom inte finns med över huvud taget.

Vi har haft en del problem med det här och endast lyckats med det enkla som att slumpa fram ett ord ur en lista, poäng, det visuella osv. Men vi vet knappt vart vi ska börja när det gäller själva rättningen.

Vi har värderna "string slumpatOrd" - det rätta ordet - och "string inputOrd" - de 5 tecken som man har gissat -
Bör vi göra det med substrings eller arrayer? Hur gör vi om en string till en array som innehåller varje bokstav i ett eget värde?

Tacksamma för svar

Permalänk
Medlem

Det enklaste att greppa rent logiskt, tror jag är att dela upp rättningen i två steg. Det är viktigt att ni förstår precis vad ni gör och varför det fungerar.

Börja med att loopa igenom "slumpatOrd" och för varje bokstav kolla om "inputOrd" innehåller samma bokstav på samma plats. Om så är fallet, sparar man det i en sträng som vi kallar "rättPlats". Om inte, sparar man bokstaven i en sträng vi kallar "felPlatsEllerFinnsInte" och lägger in ett mellanslag i strängen "rättPlats".

På så sätt har vi nu två strängar att jobba med, varav den ena (rättPlats) berättar vilka bokstäver som användaren satte på rätt plats. Det löser hälften av rättningen.

Nästa hälft är att kolla vilka av bokstäverna som faktiskt fanns, men sitter på fel plats. Det gör ni på liknande sätt genom att loopa igenom alla bokstäver i strängen "felPlatsEllerFinnsInte" och för varje bokstav kolla om "inputOrd" innehåller denna bokstav. Om inte, lägg bokstaven till en sträng "finnsInte". Om bokstaven finns i "inputOrd", spara bokstaven till en sträng "finnsPåAnnanPlats".

Nu har ni tre strängar (rättPlats, finnsPåAnnanPlats, finnsInte) som är ganska självförklarande. De berättar allt ni behöver veta, tror jag. Det är i om inte annat en god bit på vägen.

En C# string kan användas som en array med chars (tecken). Det går t.ex. att loopa igenom den såhär:

string ord = "abcde"; foreach (char bokstav in ord) { // ... }

För att lägga till en char till en string, kan ToString behövas:

string ord = "abcde"; char bokstav = 'f'; ord += bokstav.ToString(); // ord == abcdef

...eller inte:

string ord = "abcde"; string bokstav = "f"; ord += bokstav; // ord == abcdef

Inte här heller:

string ord = "abcde"; char bokstav = 'g'; ord += "f" + bokstav; // ord == abcdefg

Permalänk
Medlem

Tack för det ! Tror vi kan fixa det här imorgon nu

Permalänk
Medlem

Nu har vi kommit en bit in Vi har skapat en metod som heter "rättning" och den tar ut bokstäver som finns på rätt plats och bokstäver som inte finns med alls helt korrekt. Men bokstäver som finns med men som inte är på rätt plats visas flera gånger.

Så om rättOrd är banan och användaren skriver in "aaaaa" så får han 5 * rättBokstavFelPlats.
Felet ligger i att vi kollar om rättOrd innehåller någon bokstav av inputOrd. Vi skulle vilja kolla om rättOrd innehåller någon del av kanskeFelBokstav istället och sedan ta bort/byta ut den bokstaven från kanskeFelBokstav om den hittar den. Men vi kanske gör det onödigt komplicerat?

private void rättning(string inputOrd) { string rättBokstavRättPlats; string kanskeFelBokstav; string rättBokstavFelPlats; string felBokstav; int heltRätt = 0; string bokstavSträngRättOrd; string bokstavSträngInputOrd; char [] rättOrd = slumpatOrd.ToCharArray(); for (int i = 0; i < slumpatOrd.Length; i++) { bokstavSträngRättOrd = ord[i].ToString(); bokstavSträngInputOrd = inputOrd[i].ToString(); if (rättOrd[i] == inputOrd[i]) // Koden kollar om samma bokstav finns på samma plats i rättOrd och inputOrd. { rättBokstavRättPlats = bokstavSträngRättOrd; poäng += 10; heltRätt ++; ritaBokstäver(i, rättBokstavRättPlats); } else // Om bokstaven inte är på rätt ställe så läggs den till i en ny sträng som heter kanskeFelBokstav. { kanskeFelBokstav += bokstavSträngInputOrd; if (rättOrd.Contains(inputOrd[i])) //Nu kollar vi om någon del av rättOrd innehåller en bokstav av inputOrd { //OBS! Hur får vi denna att inte räkna samma bokstav flera gånger? rättBokstavFelPlats = bokstavSträngInputOrd; MessageBox.Show("Rätt bokstav fel plats: " + rättBokstavFelPlats); poäng += 1; } else { felBokstav = bokstavSträngInputOrd; MessageBox.Show("Bokstaven finns inte med i ordet: " + felBokstav); poäng -= 5; } } if (heltRätt == 5) { MessageBox.Show("Du gissade hela ordet rätt!"); poäng += 50; nyRunda(); } label2.Text = ("Du har nu: " + Convert.ToString(poäng) + " poäng."); } }

Dold text
Permalänk
Medlem
Skrivet av MaraN:

Nu har vi kommit en bit in Vi har skapat en metod som heter "rättning" och den tar ut bokstäver som finns på rätt plats och bokstäver som inte finns med alls helt korrekt. Men bokstäver som finns med men som inte är på rätt plats visas flera gånger.

Så om rättOrd är banan och användaren skriver in "aaaaa" så får han 5 * rättBokstavFelPlats.
Felet ligger i att vi kollar om rättOrd innehåller någon bokstav av inputOrd. Vi skulle vilja kolla om rättOrd innehåller någon del av kanskeFelBokstav istället och sedan ta bort/byta ut den bokstaven från kanskeFelBokstav om den hittar den. Men vi kanske gör det onödigt komplicerat?

Använd gärna CODE-taggen om det är ren kod som skrivs, istället för spoiler-taggen, så behålls indenteringen.

Jag föreslår ett annat förslag.

En enkelt sätt att angripa problemet är att göra olika steg. Att isolera på detta vis gör så man inte gör misstaget med att försöka baka in så mycket logik som möjligt i varje steg. Även om man spontant kan tycka att detta sätt känns långsamt eller icke-optimerat så får man mycket trevlig struktur som gör det enkelt att se vad som sker vilket i vissa fall är mycket bättre än ett blixtsnabbt program.

Implementationsförslag:
private void checkWords()
{
findIdenticalCharactersOnSameIndex();
findIdenticalCharactersOnOtherIndex();
calculateScore();
presentScore();
}

Jag presenterar exempeldata, förväntat resultat och "pratkod" som ni får tolka och implementera som riktig kod, om ni vill.

Testdata:
correctWord = "banan";
guessWord = "aaaab";

Steg 1 - Leta efter samma bokstav på samma position
Leta endast efter bokstäver som är rätt på samma plats
Ersätt de korrekta positionerna med "#" eller annat tecken
Resultatexempel:
correctWord = "b#n#n";
guessWord = "a#a#b";

Steg 2 - Leta efter bokstav på annan position
Leta endast efter bokstäver som finns på annan plats
Ersätt bokstäverna med "?" eller annat tecken
Resultatexempel:
correctWord = "?#n#n";
guessWord = "a#a#?";

Steg 3 - Räkna poäng
10 poäng för rätt position och 5 för rätt bokstav men fel plats(?)
Summa: 25

Steg 4 - Presentation

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

Gjorde en sån här i den här killens tråd, vet inte om den kan vara till någon nytta för dig också eller inte #11622111

Visa signatur

Windows användare sedan 1991. Numera MacBook Pro M1 Pro.

Permalänk
Hedersmedlem
Skrivet av Leedow:

Använd gärna CODE-taggen om det är ren kod som skrivs, istället för spoiler-taggen, så behålls indenteringen.

Mycket riktigt, men bara för att förtydliga kan man använda spoiler-taggen samtidigt om man vill. (Jag passade för övrigt på att ändra ovan.)

Permalänk
Medlem
Skrivet av Elgot:

Mycket riktigt, men bara för att förtydliga kan man använda spoiler-taggen samtidigt om man vill.

Man lär sig något nytt varje dag.
Tack för det.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

Tillslut fick vi till rättningen även fast vi kanske bakar in lite väl mycket i metoden då vi har poäng samt att vi anropar en annan metod för att rita ut bokstäverna. Det vore väll allra bäst om om vi kunde få in denna i en egen klass men det blir en del meck för att lyckas med det..

PS: Kortar ner koden lite för att ingen ska få för sig att plagiera rakt av

private void rättning(string inputOrd) { string rättBokstavRättPlats; string rättBokstavFelPlats; string bokstavSträngRättOrd; string bokstavSträngInputOrd; int heltRätt = 0; char[] rättOrd = slumpatOrd.ToCharArray(); char[] inputOrd2 = inputOrd.ToCharArray(); char ersättningsBokstav = '@'; for (int i = 0; i < slumpatOrd.Length; i++) { //Här ritar vi ut alla bokstäver som röda. } for (int i = 0; i < slumpatOrd.Length; i++) { bokstavSträngRättOrd = rättOrd[i].ToString(); bokstavSträngInputOrd = inputOrd[i].ToString(); if (rättOrd[i] == inputOrd[i]) { rättBokstavRättPlats = bokstavSträngRättOrd; poäng += 10; heltRätt++; // Här ritar vi ut alla gröna bokstäver i pictureboxen rättOrd[i] = ersättningsBokstav; if (heltRätt == 5) { MessageBox.Show("Du gissade hela ordet rätt!"); poäng += 50; nyRunda(); } } } //Här under löste vi problemet med dom gula bokstäverna med en dubbel loop :) Tog ett par timmar av förvirring.. for (int j = 0; j < rättOrd.Length; j++) { for (int i = 0; i < rättOrd.Length; i++) { bokstavSträngRättOrd = rättOrd[i].ToString(); bokstavSträngInputOrd = inputOrd[i].ToString(); if (rättOrd.Contains(inputOrd[i])) { rättBokstavFelPlats = bokstavSträngInputOrd; //Här ritar vi ut alla gula bokstäver. } } } label_Poäng.Text = ("Du har: " + poäng + " poäng"); }

Dold text
Permalänk
Medlem
Skrivet av Tott3:

Gjorde en sån här i den här killens tråd, vet inte om den kan vara till någon nytta för dig också eller inte #11622111

Tyvärr så lingo skilljer sig Lingo lite för mycket från hangman trots att det typ är samma sak