1
votes

Comment puis-je mélanger une ArrayList, mais après la lecture aléatoire des index spécifiques restent les mêmes?

Dans ma ArrayList , chaque numéro a une couleur qui lui est attribuée en fonction de sa position dans la ArrayList . Les nombres dans les index impairs sont rouges, les nombres dans les index pairs sont bleus et les nombres dans les index de multiples de 10 sont noirs. Je dois mélanger la liste pour qu'après la lecture aléatoire, les nombres rouges soient toujours dans des index impairs, les nombres bleus soient toujours dans des index pairs et les nombres noirs soient toujours dans des multiples de dix index. Je sais comment mélanger une liste entière, mais pas des choses spécifiques comme celle-ci. Comment procéder?

Voici le code pour le contexte:

/* Slice class*/
public class Slice
{
  private String color;
  private int prizeAmount;


  // Creates a slice with color c, and cash prize p
  public Slice(String c, int p) {
   color = c;
   prizeAmount = p;
  }


  // Returns the cash prize in dollars for this slice
  public int getPrizeAmount() {
    return prizeAmount;
  }


  // Returns the color of this slice as a string
  public String getColor() {
    return color;
  }


  /* Returns a string representation of the slice in the following format: 
   * Color: red, prize amount: $50.
   */
  public String toString() {
    return "Color: " + color + ", Prize Amount: $" + prizeAmount;      
  }
}

et voici comment les tranches sont créées:

/* Term 2 Assignment 5 - Game Wheel */
/* GameWheel class*/
import java.util.*;
import java.lang.*;

public class GameWheel
{
  // List of slices making up the wheel
  private List<Slice> slices;

  // Position of currently selected slice on wheel
  private int currentPos;


  /* Creates a wheel with 40 preset slices which are then randomized (keeping 
   * the color pattern the same).
   */
  public GameWheel()
  {
    slices = new ArrayList<Slice>();
    currentPos = 0;
    initGameWheel();
    scramble();
  }


  /* Spins the wheel by so that a different slice is selected. Return that 
   * slice (Note: the 20 slices following the current slice are more likely to 
   * be returned than the other 20).
   */
  public Slice spinWheel()
  {
    //spin power between range of 1-100 (inclusive)
    int power = (int)(Math.random()*100 + 1);
    int newPos = (currentPos + power) % slices.size();
    currentPos = newPos;
    return slices.get(currentPos);
  }


  /* Helper method for the constructor. Randomizes the positions of the slices 
   * that are in the wheel, but without changing the pattern of the colors 
   * (i.e. the red slices will still be at odd indices, the black slices at 
   * multiples of 10, and the blue slices at all other even indices).
   */ 
  private void scramble()
  {

  }


  // Helper method which initializes the slices in the wheel
  private void initGameWheel()
  {
    slices.add(new Slice("black", 8000));
    for (int i=1; i < 40; i++)
    {
      if (i%2 == 1)
        slices.add(new Slice("red", i*10));
      else if (i%10 == 0)
        slices.add(new Slice("black", i*200));
      else
        slices.add(new Slice("blue", i*100));
    }
  }


  // Returns the list of slices for this GameWheel
  public List<Slice> getSlices() {
    return slices;
  }
}


1 commentaires

Parcourez la liste et, pour chaque index, déterminez s'il est impair, pair ou multiple de 10. Ensuite, générez un nombre aléatoire


3 Réponses :


-1
votes

Je pense que vous pourriez créer 3 listes différentes et les mélanger séparément. Après cela, recréez la liste originale en utilisant des listes mélangées:

public static List<Slice> shuffle(List<Slice> slices) {
    final int total = slices.size();
    List<Slice> red = new ArrayList<>();
    List<Slice> blue = new ArrayList<>();
    List<Slice> black = new ArrayList<>();

    int i = 0;

    for (Slice slice : slices) {
        if (i % 2 == 1)
            red.add(slice);
        else if (i % 10 == 0)
            black.add(slice);
        else
            blue.add(slice);
        i++;
    }

    Collections.shuffle(red);
    Collections.shuffle(blue);
    Collections.shuffle(black);

    Iterator<Slice> itRed = red.iterator();
    Iterator<Slice> itBlue = blue.iterator();
    Iterator<Slice> itBlack = black.iterator();
    slices.clear();

    for (int j = 0; j < total; j++) {
        if (j % 2 == 1)
            slices.add(itRed.next());
        else if (j % 10 == 0)
            slices.add(itBlack.next());
        else
            slices.add(itBlue.next());
    }

    return slices;
}


0 commentaires

0
votes

Il n'y a pas de méthode «facile» (comme dans, via une méthode existante comme Collections.shuffle ); vous devez programmer cette fonctionnalité vous-même, mais vous pouvez bien sûr utiliser des éléments existants pour vous aider.

Une manière quelque peu détournée est de `` déconstruire et reconstruire '': écrivez une méthode qui décompose une seule liste en 3 listes distinctes (1 pour chaque couleur), puis mélangez-les, puis `` reconstruisez '' vos trois listes séparées en une seule grande liste, en utilisant l'algorithme évident (si l'index est divisible par 10, prenez le suivant dans la liste noire, sinon s'il est divisible par 2, récupérez-le dans la liste bleue, sinon, récupérez-le dans la liste rouge).

Une autre façon consiste simplement à implémenter vous-même l'algorithme de lecture aléatoire. Pour le contexte, vous recherchez l ' algorithme de lecture aléatoire de Fisher-Yates , que l'implémentation de Collections.shuffle utilise également. Les choses cruciales à savoir:

  • Pour obtenir un nombre aléatoire entre 0 et N, appelez .nextInt (n) sur une instance de Random (créez une seule instance, une fois, et continuez à le réutiliser). N'utilisez pas le courant (int) (Math.random () * n) , qui est subtilement faux (principe de casier), et Java non idiomatique.

  • fisher yates consiste principalement à parcourir la liste du début (index 0) à l ' avant-dernier élément (celui avec l'index list.size () -2 < / code>). Pour chaque élément, échangez-le avec un élément choisi au hasard uniforme qui est lui-même ou tout élément au-dessus.

En d'autres termes, pour mélanger 1,2,3,4,5 , nous commençons au 0e élément (le 1), et choisissons n'importe quel élément, uniformément aléatoire, de lui-même et jusqu'à swap avec. C'est un choix de 5 éléments, nous appelons donc rnd.nextInt (5) pour le comprendre. Ce nombre aléatoire pourrait être 0, auquel cas `` vous échangez 1 avec lui-même '', ce qui signifie qu'il reste où il est (hé, mélanger signifie aléatoire; parfois une carte se retrouve au même endroit dans la pile après avoir mélangé un jeu de cartes. !). Ensuite, pour l'élément suivant (le 2; à l'index 1), vous choisissez n'importe quel index de lui-même (donc index 1) jusqu'à la fin, nous appelons donc rnd.nextInt (4) , et ainsi de suite .

Pour cet exercice, le plus délicat est de déterminer combien d'endroits valides 'au-dessus de vous' avec lesquels vous pouvez échanger existent (ce serait l'argument que vous passez à rnd.nextInt (X) ), et comment traduire le nombre que votre appel nextInt vous donne avec l'index avec lequel vous devez maintenant échanger.

Notez que cet algorithme fonctionne entièrement en place; il n'y a pas besoin de listes ou de tableaux supplémentaires. Une seule variable temporaire pour activer l'échange est tout ce dont vous avez besoin.

Cela ressemble à des devoirs, je ne vais donc pas pré-mâcher la réponse pour vous. J'espère que cela vous suffit pour l'écrire vous-même. Bonne chance!


0 commentaires

0
votes

Essayez cette solution:

[Color: black, Prize Amount: $2000, Color: red, Prize Amount: $90, Color: blue, Prize Amount: $800, Color: red, Prize Amount: $70, Color: blue, Prize Amount: $200, Color: red, Prize Amount: $10, Color: blue, Prize Amount: $400, Color: red, Prize Amount: $50, Color: blue, Prize Amount: $600, Color: red, Prize Amount: $30, Color: black, Prize Amount: $8000]

Sortie avant:

[Color: black, Prize Amount: $8000, Color: red, Prize Amount: $10, Color: blue, Prize Amount: $200, Color: red, Prize Amount: $30, Color: blue, Prize Amount: $400, Color: red, Prize Amount: $50, Color: blue, Prize Amount: $600, Color: red, Prize Amount: $70, Color: blue, Prize Amount: $800, Color: red, Prize Amount: $90, Color: black, Prize Amount: $2000]

Sortie après:

public void shuffle(List<Slice> slices) {
    Map<String, Iterator<Slice>> slicesByColor = slices.stream()
            .collect(groupingBy(Slice::getColor)).entrySet().stream()
            .peek(e -> Collections.shuffle(e.getValue()))
            .collect(toMap(Map.Entry::getKey, e -> e.getValue().iterator()));

    for (int i = 0; i < slices.size(); i++) {
        Iterator<Slice> sliceIterator = slicesByColor.get(colorByIndex(i));
        slices.set(i, sliceIterator.next());
    }
}

private String colorByIndex(int index) {
    if (index % 2 == 1)
        return "red";
    else if (index % 10 == 0)
        return "black";
    else
        return "blue";
}


0 commentaires