Dwagon Skrevet 25. februar 2015 Del Skrevet 25. februar 2015 Heisann, Sitter å fomler i mørket, uten noen åpenbart lys i sikt.Intensjonen er å lage et verktøy som lar meg legge fram X tilfeldige runer på skjermen.Det er totalt 24 forskjellige å velge mellom. Jeg tillater IKKE duplikater, altså jeg skal ikke ha samme runa 2 ganger.Dette får jeg ikke til, har sett meg blind på koden og trenger nå friske øyne.Har følgende metode public void drawImage(int numRunes, int numBags) { List<int> usedInts = new List<int>(); PictureBox[] boxes = { runeBox1, runeBox2, runeBox3, runeBox4, runeBox5, runeBox6, runeBox7, runeBox8, runeBox9, runeBox10, runeBox11, runeBox12, runeBox13, runeBox14, runeBox15, runeBox16, runeBox17, runeBox18, runeBox19, runeBox20, runeBox21, runeBox22, runeBox23, runeBox24, runeBox25, runeBox26, runeBox27, runeBox28, runeBox29, runeBox30, runeBox31, runeBox32, runeBox33, runeBox34, runeBox35, runeBox36, runeBox37, runeBox38, runeBox39, runeBox40, runeBox41, runeBox42, runeBox43, runeBox44, runeBox45, runeBox46, runeBox47, runeBox48 }; int[] possibleRunes = Enumerable.Range(0, 23).ToArray(); int sharedCounter = 0; Random rnd = new Random(); if ( numBags == 1 ) // less than 2 bags? That means you cant have dupes! { while ( sharedCounter < numRunes ) { int selected = rnd.Next(0, 23); if ( !checkDupe(selected, numRunes, usedInts) ) { boxes[sharedCounter].ImageLocation = files[selected]; sharedCounter++; } else { sharedCounter--; //decrement the counter i, so that it tries again. } } } else //he has more than one bag, dupes are ok. { while ( sharedCounter < numRunes ) { int selected = rnd.Next(0, 23); boxes[sharedCounter].ImageLocation = files[selected]; sharedCounter++; } } } Inne i en IF statement kaller jeg på metoded som skal sjekke duplikater, og deretter returnere en bool som sier om jeg skal prøve igjen eller tegne runen. private bool checkDupe(int numToCheck, int tests, List<int> used) { for ( int i = 0; i < tests; i++ ) { if ( !used.Contains(numToCheck) ) { System.Console.WriteLine("Not a duplicate, returned false"); used.Add(numToCheck); return false; } else { System.Console.WriteLine("Duplicate, returned true"); return true; } } //defaults to false, as a fallback return false; } Dette er nå siste versjon av duplikatsjekkern.. hvor er det jeg er dum (i henhold til duplikatsjekken) Er relativt sikker på at koden er horibelt uoptimalisert, og har en bug inni dær som gjør at den kræsjer i blant under tegning av runen. Lenke til kommentar
Emancipate Skrevet 25. februar 2015 Del Skrevet 25. februar 2015 (endret) Den enkleste måte å gjøre det på er å ta ut elementene som du allerede har valgt fra lista. En dum konsekvens blir at selve lista ødelegges hvis du ikke tar en kopi først. Edit: Jeg misforsto kanskje litt, men du skjønner tenkemåten. Her er en algoritme som er ganske fiffig, og der man bevarer inneholdet (men ikke rekkefølgen) på lista over ting. JavaScript: var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];//, 18, 19, 20, 21, 22, 23, 24]; var selectUnique = function(list, num) { var result = []; var select; var tmp; for (var i=0; i<num; ++i) { // Select an element, but not the i elements near the end of the array, because // this is where we put already selected numbers. select = floor(random(0, list.length-i)); result.push(list[select]); // Remove element from selectable part of list and place it near the end // println(select + " : " + list[select]); tmp = list[select]; list[select] = list[list.length-i-1]; list[list.length-i-1] = tmp; //println(result); //println(list); //println("--"); } //println("result: " + result); return result; }; //println( selectUnique(list, 6); Endret 25. februar 2015 av Emancipate Lenke til kommentar
Enthroner Skrevet 25. februar 2015 Del Skrevet 25. februar 2015 Ennå lettere: * lag liste av PictureBox * .OrderBy(i=>rnd.Next()) * .Take(X) Skriver på telefon. Retter om 3min Lenke til kommentar
Dwagon Skrevet 26. februar 2015 Forfatter Del Skrevet 26. februar 2015 Hmm, må lese litt på det der orderby opplegget, er enda mye jeg ikke har kontroll på innenfor c# Faktisk er det lite jeg faktisk har kontroll på. Men sånn er det når man er fersk. Kjapt oppsummert så er teorien bak hele systemet dette: 24 runer, listet opp fra 0 til 23. Jeg vil ha 8 runer! random tall mellom 0 og 23.tegn runen på skjermen putt tallet i en beholder Velg nytt tall mellom 0 og 23dersom tallet som ble valgt er allerede i beholderen, prøv på nytt! gjennta til man når 8 unike resultater. Men dette får jeg ikke til i koden. Beklager om dette ikke kom helt klart frem i førsteposten. Lenke til kommentar
Emancipate Skrevet 26. februar 2015 Del Skrevet 26. februar 2015 Velg ut alle de random tallene først, deretter tegner du runene ut i fra det. Én ting om gangen. 1 Lenke til kommentar
Dwagon Skrevet 26. februar 2015 Forfatter Del Skrevet 26. februar 2015 (endret) Velg ut alle de random tallene først, deretter tegner du runene ut i fra det. Én ting om gangen. Random X ganger -> array -> sorter array -> se etter tall som gjentar seg -> om duplikater slett og start på nytt? sånn for eksempel? for ( int i = 0; i < numRunes; i++ ) { numGen[i] = rnd.Next(0, 23); // x runes } Array.Sort(numGen); Endret 26. februar 2015 av Dwagon Lenke til kommentar
Emancipate Skrevet 26. februar 2015 Del Skrevet 26. februar 2015 (endret) Jeg tror du misforsto. Idéen om at du skal velge ut runer og tegne dem samtidig er bare feil. Det jeg mente var at du bør dele opp koden i to deler. En del som lager en liste over hvilke runer som skal tegnes, og en del som tegner dem. Dette fordi du da deler oppgaven i to mindre deler, der hver del er enklere å løse. For å lage en liste over hvilke runer som skal tegnes kan du bruke algoritmen min eller lage din egen. IMO er det bare tull å se etter duplikater. Vil du ikke ha duplikater så skal du ikke legge til duplikater i utgangspunktet. Har du kommet dit at du ser etter duplikater har du gjort noe feil. Koden din er dessuten helt uleselig fordi den } som lukker et statement ikke kommer på linja der statementet begynner. if (sånn) { ja(); } else { ok(); } if(sånn) { ja(); } if (sånn) { Nei!!! Ikke sånn. } Og definitivt ikke sånn: if ( numBags == 1 ) // less than 2 bags? That means you cant have dupes! { } else //he has more than one bag, dupes are ok. { } Endret 26. februar 2015 av Emancipate 1 Lenke til kommentar
Emancipate Skrevet 26. februar 2015 Del Skrevet 26. februar 2015 pseudokode: int n = 8; int index; int[] chosenRunes = new Array<int>; int[] possibleRunes = Enumerable.Range(0, 23).ToArray(); for (i=0; i<n; ++i) { index = rnd.Next(0, 23-i); chosenRunes.push(i); possibleRunes.delete_element(i); } Da har du tall i chosenRunes som du bruker når du skal tegne runene. 1 Lenke til kommentar
Dwagon Skrevet 26. februar 2015 Forfatter Del Skrevet 26. februar 2015 (endret) Akkurat, ja kan ikke skryte på meg at dette er noe jeg kan. Det er åpenbart.Copy pasten inn fra visual studio er skitten. Jeg kan rett og slett ikke nok om syntaxen til å løse det på en ren måte (enda!) Så mens du skrev posten din fiklet jeg med kode og kom fram til dette. private int[] GenerateRunes(int numRunes) { int[] numGen = new int[numRunes]; for ( int i = 0; i < numRunes; i++ ) { numGen[i] = rnd.Next(0, 23); // x runes } // time to sort. Array.Sort(numGen); // now throw into dupe checker if ( checkDupe(numGen) ) { return GenerateRunes(numRunes); //woot internal method call! } else return numGen; } public void drawImage(int numRunes, int numBags) { List<int> usedInts = new List<int>(); PictureBox[] boxes = {MASSE RUNEBOKSER!}; int[] runes = new int[numRunes]; runes = GenerateRunes(numRunes); //make the runelist for ( int i = 0; i < runes.Length; i++ ) { boxes[i].ImageLocation = files[runes[i]]; } } private bool checkDupe(int[] array) { if ( array.Length < 2 ) { return false; } for ( int i = 0; i < array.Length; i++ ) { for ( int j = i+1; j < array.Length; j++ ) { if ( array[i] == array[j] ) { return true; //we found a dupe } } } return false; // all good, no dupes. } Nå må jeg bare finne ut hvorfor jeg får stackoverflow når jeg ber om mer enn 18 runer. Endret 26. februar 2015 av Dwagon Lenke til kommentar
Emancipate Skrevet 26. februar 2015 Del Skrevet 26. februar 2015 (endret) Funksjonen din GenerateRunes er bare feil. Lag den sånn som jeg viste i innlegget over: en liste med alle tallene du kan velge fra, og en tom liste. Så velger du ut et tilfeldig tall fra liste 1, legger det til i liste 2 og sletter det fra liste 1. Dette gjør du 8 ganger (hvis du skal ha 8 tall). Edit: Jeg hadde sikkert vært mer hjelpsom om jeg hadde kunnet C#. Endret 26. februar 2015 av Emancipate Lenke til kommentar
Dwagon Skrevet 26. februar 2015 Forfatter Del Skrevet 26. februar 2015 I for loopen din skriver du for (i=0; i<n; ++i) { index = rnd.Next(0, 23-i); chosenRunes.push(i); possibleRunes.delete_element(i); } Kan det være at du mente at index skal være det tallet jeg henter og sletter på? I så fall må jeg endre fra array til list, ellers blir det uhm.... merkelig. Jeg prøver litt kode og ser hvordan det går. Setter pris på all hjelp, selv om du kanskje ikke kan C# Lenke til kommentar
Dwagon Skrevet 26. februar 2015 Forfatter Del Skrevet 26. februar 2015 (endret) private int[] GenerateRunes(int numRunes) { ArrayList possibleRunes = new ArrayList(); Queue q = new Queue(Enumerable.Range(0, 23).ToArray()); possibleRunes.AddRange(q); ArrayList numGen = new ArrayList(); int index = 0; for ( int i = 0; i < numRunes; i++ ) { index = rnd.Next(0, 23 - i); numGen.Add(i); possibleRunes.RemoveAt(i); } int[] runelist = numGen.ToArray(typeof(int)) as int[]; return runelist; Sånn ser den ut nå. fungerer fint, men får feil når jeg passerer 12 runer. I motsetning til 18 fra den gamle metoden. Skjønner ikke helt hensikten med indexen. Endret 26. februar 2015 av Dwagon Lenke til kommentar
Emancipate Skrevet 26. februar 2015 Del Skrevet 26. februar 2015 Sorry, koden min var helt feil, haha. Den blinde skal lede den døve. Den legger bare til en rekke tilfeldige tall. Sånn: numGen.Add(possibleRunes[index]); 1 Lenke til kommentar
Dwagon Skrevet 26. februar 2015 Forfatter Del Skrevet 26. februar 2015 Akkurat ja Men da er den i boks. Nå må jeg bare finne ut hvorfor den dør om jeg ber om 12 runer. Lenke til kommentar
Emancipate Skrevet 26. februar 2015 Del Skrevet 26. februar 2015 Hva slags feilmelding er det du får? 1 Lenke til kommentar
Enthroner Skrevet 26. februar 2015 Del Skrevet 26. februar 2015 (endret) Her har du en enkel løsning: List<PictureBox> randomRunes = yourRunes.OrderBy(i=>rnd.Next()).Take(8).ToList(); class SimpleRandomSelection { static void Main() { List<int> yourRunes = new List<int>(); //your list of runes for (int i=0; i<24; i++) { yourRunes.Add(i); } //fill the list with something Random rnd = new Random(); //instantiate your random source /// This is where the magic happens, a onliner that solves your problem: List<int> randomRunes = yourRunes.OrderBy(i=>rnd.Next()).Take(8).ToList(); //print to console to show selection randomRunes.ForEach(i=>Console.WriteLine(i)); } } Endret 26. februar 2015 av Enthroner 1 Lenke til kommentar
Dwagon Skrevet 28. februar 2015 Forfatter Del Skrevet 28. februar 2015 (endret) Her har du en enkel løsning: List<PictureBox> randomRunes = yourRunes.OrderBy(i=>rnd.Next()).Take(8).ToList(); class SimpleRandomSelection { static void Main() { List<int> yourRunes = new List<int>(); //your list of runes for (int i=0; i<24; i++) { yourRunes.Add(i); } //fill the list with something Random rnd = new Random(); //instantiate your random source /// This is where the magic happens, a onliner that solves your problem: List<int> randomRunes = yourRunes.OrderBy(i=>rnd.Next()).Take(8).ToList(); //print to console to show selection randomRunes.ForEach(i=>Console.WriteLine(i)); } } Epic, man lærer alltid noe nyttig. takket være deg er nå verktøyet straks klart! Var litt fomling da jeg møtte på en uvented kræsj.Men det viste seg å være feil i runelesningen fra fil samt en +1 error i en loop. Men nå fungerer det som bare faen! Alt som gjennstår nå er å legge til inputlogikk og begrensninger ihht bruk. Tusen takk for all hjelpen. Ja, kanskje greit å se på resultatet. http://www.kraksletta.com/fotn/Runegenerator.html Endret 1. mars 2015 av Dwagon 1 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å