8 svar
68 visningar
Plugghingsten är nöjd med hjälpen!
Plugghingsten 66
Postad: 5 dec 2018

Kortleksspel

Hej! Jag försöker läsa en kod där en kortlek blandas och delas ut som sker i följande metod:

 

public void shuffle() {

          for (int i = 51; i >= 1; i--) {

          int nbr = rand.nextInt(i+1) 

          Card temp = cards[nbr];

          cards[nbr] = cards[i];

          cards[i] = temp;

          }

}

Jag tänker som så:

1. "int nbr = rand.nextInt(i+1)" där ett slumpmässigt kort tas från högen vi har. En fundering om det nu skulle vara så, hade det inte tagit väldigt lång tid då slumpmässigt tal ej är begränsat? Eller när den väl är i loopen så kan den inte välja tal mindre än eller större än omfånget som anges? 

2.  Osäker men antar att det nyligen slumpmässigt plockade kortet (Card temp) sätts som ett temporärt kort.

3. En ny likadan lista som cards[nbr] skapas (cards[i]). Antar för att kunna överföra från gamla listan till den nya. Dock tror jag detta blir fel. Vad skulle hända om det slumpmässiga kortet redan är borta (t.ex. plats 30 redan borta), skulle det bli tomt då i den nya?

4. Det slumpmässigt plockade kortet sätts in i en antagligen ny position i den nya listan. 

 

Helheten:

Jag ser det som om man slumpmässigt plockar ut ett kort och sedan lägger från position 0 till 51. Jag må ha skrivit helt tokigt men fråga då!

Laguna Online 1801
Postad: 5 dec 2018

Jag antar att rand.nextInt(k) ger heltal från 0 till och med k-1. Så det blir aldrig större än 52.

Det görs ingen ny lista, det finns bara listan 'cards'. Man använder en variabel temp för att hålla i ett Card, för att i de tre sista raderna låta cards[nbr] och cards[i] byta plats.

Skriv ut hela 'cards' varje varv i loopen så ser du vad som händer.

Jag tror inte lista är rätt ord, egentligen, utan snarare vektor eller array, men det kan vara lista, och det framgår inte av den här koden och spelar ingen roll för algoritmen.

adamcl 14
Postad: 6 dec 2018

1. Här väljs bara en slumpmässig int mellan 0 och 52 minus forloopens iteration. Metoden rand.nextInt går från och med 0 till det som anges som argument (endast till, inte till och med).

2. Exakt, om t ex 32 väljs av rand.nextInt så får objektet på som cards[32] pekar på en tillfällig pekare, temp. Detta för att inte glömmas bort när cards[32] ska få ett nytt kort tilldelat.

3. Ingen ny vektor skapas, allt sker i cards[]. Det slumpmässigt valda kortet (32) tilldelas kortet på forloopens iteration (pos 51 i första iterationen). Det som sker är att pekaren ändras i cards[32] till att peka till objektet på cards[51]. På detta sätt skapas inga nya objekt eller vektorer, och ingenting tas heller bort.

4. I cards[i] = temp så tilldelas cards[51] (som nu är en dublett av cards[32]) det ursprungliga objektet på cards[nbr].

Kort sagt, cards[i] och cards[nbr] byter plats.

Plugghingsten 66
Postad: 6 dec 2018

@adamcl

1. Då har jag skrivit den rätt, "int nbr = rand.nextInt(i+1);" och inte bara "i", eller? Följdfråga1: Om det gäller en kortlek, ska det inte stå int i = 52 istället? Följdfråga2: Kommer loopen att ta EN gång varje värde eller kan det hända att den plockar (i.o.m. "rand.") redan tagna platser som då är tomma?

adamcl 14
Postad: 7 dec 2018

Vektorer är 0-indexerade i Java, så på position 51 i Cards[] har du kort nummer 52.

i+1 är för att rand.nextInt som sagt går från och med 0 till argumentet (i första loopen 52). 52 är alltså inte med, däremot 51. Nästa loop är det 51 kort kvar och då går rand.nextInt från och med 0 till 51, dvs 0 till 50 = 51 positioner.

Varje kort kommer att hämtas en gång och flyttas till iterationens värde. Om du är i tionde iterationen (i = 41), så kommer rand.nextInt att ta ett slumpmässigt kort på position 0-41 och flytta det till position 41. Nästa iteration lämnas detta kort utanför, då i minskar i varje iteration och det tas ett slumpmässigt kort på position 0-40 (och flyttas till pos 40). På detta sätt flyttas alla kort förutom det sista.

Notera att inga platser är tomma. Cards[x] är en pekare till ett objekt, när Cards[x] och Cards[y] byter plats byter de egentligen bara adress till objekt med varandra (via tempobjektet).

Plugghingsten 66
Postad: 7 timmar sedan Redigerad: 7 timmar sedan

Jag återkommer nu till denna tråd, sorry about that! Jag tolkar det som om det ska stå "for (int i = 51; i >= 0; i--) {

...

}

Laguna Online 1801
Postad: 7 timmar sedan
Plugghingsten skrev:

Jag återkommer nu till denna tråd, sorry about that! Jag tolkar det som om det ska stå "for (int i = 51; i >= 0; i--) {

...

}

Det kan du göra, men när i = 0 så finns bara ett kort att välja, så man byter ut det mot sig självt, dvs. inget händer.

Plugghingsten 66
Postad: 6 timmar sedan

Men om det står "for (int i = 51; i >= 1; i--) {" så kommer aldrig kort nummer 1 väljas då nästa rag säger "i+1" vilket kommer som lägst bli 2. 

Laguna Online 1801
Postad: 6 timmar sedan
Plugghingsten skrev:

Men om det står "for (int i = 51; i >= 1; i--) {" så kommer aldrig kort nummer 1 väljas då nästa rag säger "i+1" vilket kommer som lägst bli 2. 

Då tar man de två första (sista, lägsta, nånting) korten och bestämmer slumpmässigt om man ska låta dem byta plats eller inte.

Svara Avbryt
Close