Nicht ganz zufällige Zufallszahl

Hallo liebe Javafreunde,

meine Frage: Wie erhält man eine Zufallszahl, die eigentlich gar keine Zufallszahl mehr ist? In meinem konkreten Fall habe ich vorher schon zwei Zufallszahlen erzeugt, die einen Wert zwischen 1 und 3 haben, nennen wir sie mal Gewinn und Wahl_des_Kandidaten.

Zum einem möchte ich nun, dass die dritte “Zufallszahl”, die “Niete”, erzeugt wird, die weder mit dem Wert der Variablen Gewinn noch Wahl_des_Kandidaten übereinstimmt. Bspw. 2 wenn Gewinn 1 und Wahl_des_Kandidaten 3 ist. Das könnte ich ja eigentlich noch mit einer if then else-Schleife machen, um die verschiedenen Möglichkeiten abzudecken, wie z.B.

    Niete = 3;
} else {
if (Gewinn + Wahl_des_Kandidaten == 2) {
    Niete = 3;

Natürlich wären damit auch nicht alle Möglichkeiten abgedeckt. Niete könnte in beiden Fällen auch den Wert 2 haben. Meine erste Frage wäre also, wie kann ich in diesem Fall eine Zufallszahl erzeugen, die entweder 2 oder 3 ist?

Zur zweiten Frage. Angenommen Gewinn wäre 1, die Wahl_des_Kandidaten ebenfalls 1. Nun erfährt der Kandidat, dass 3 eine Niete ist, und kann sich nun nochmal zwischen 1-2 entscheiden. Wie baue ich so etwas in mein Programm ein?

zu 1: in welchem bereich können diese zahlen denn sein? Wenn nur zwischen 1 und 5 zB könnte man alle in eine liste speichern, {1, 2, 3, 4, 5} und beim generieren einer solchen diese daraus holen. Ich generiere 4, also: {1, 2, 3, 5} und dann einfach ne zufallszahl von 0 bis zu länge der liste - 1, und vom dem platz die zahl nehmen…

zu 2: was hast du denn für eine art von programm? Besitzt du schon eine gui? oder läuft alles in der console? Was meinst du mit entscheiden? einen entsprechenden button anklicken?..

1: Meinst du mittels Array? Im Bereich von 1-3 können die Zahlen sein. Nur wie hole ich diese bestimmte Zahl daraus?

Random zufallszahl = new Random ();
int zufallsZahl = zufallszahl.nextInt(3);

So bestimmte ich ja den Raum 0-3. Die Zahl wäre als zufallsZahl + 1, da 0 ja nicht in Frage kommt. Nun habe ich eben auch diese Liste von {1, 2, 3}. Was meinst du mit “ich generiere 4”? Ich muss ja eine Zahl generieren, die zwei bestimmte Werte nicht annehmen kann. Oder meinst du die Liste wird am Anfang generiert, alle Variablen greifen quasi auf sie zu. Und wenn z.B. Gewinn den Wert 2 hat ist dieser aus der Liste gelöscht? Die Variablen Gewinn und Wahl_des_Kandidaten können allerdings den gleichen Wert haben. Es ist quasi so wie in einer Spielshow, man weiß nicht, dass Gewinn Zahl x ist, bis die Niete bekannt ist und der Kandidat umentschieden hat.

2: Nennt sich “das Ziegenproblem”. Eine GUI habe ich nicht, läuft alles in der Konsole, eine Eingabe des Nutzers ist auch nicht vorgesehen, lediglich die Ausgabe von Werten, aber das kriege ich schon hin. Mit entscheiden meine ich eine neue Wahl treffen. Also der Kandidat soll in jedem Falle umentscheiden. Wenn Gewinn und Wahl 1 sind und Niete 3, soll in einer anderen Variable “neueWahl” 2 gespeichert werden.

Nein mymakismus meinte schon Listen:

List<Integer> werte = new ArrayList(maxWert);
for(int i = 1; i<=maxWert; i++) {
  werte.add(i);
}
Collections.shuffle(werte);

Damit hast Du eine Liste mit den möglichen Werten. Der “Zufall” wird hier durch das Collections.shuffle (englisch: Mischen) erzeugt.
Dadurch kannst Du mit Hilfe immer desselben Indexes Zahlen ziehen:
int gezogenerWert = werte.remove(0);
Durch das remove kann jede Zahl nur einmal gezogen werden.

Das Problem ist ja, das eine Zahl durchaus zweimal vorkommen kann.
Geplanter Programmablauf:
[ul]
[li]Variablen: Wahl, Gewinn, Niete und neue_Wahl
[/li][li]zufälliger Wert zwischen 1-3 für Wahl und Gewinn.
[/li][li]zufälliger Wert für Niete, jedoch ungleich Gewinn. (Niete != Gewinn)
[/li][li]zufälliger Wert für neue_Wahl, jedoch ungleich Niete und ungleich (alte) Wahl (neue_Wahl != Niete && Wahl) <-- Hier also quasi nur 2 mögliche Werte anstatt 3.
[/li][/ul]

Naja nun, Du weißt schon, wie man eine Liste erzeugt und mit Werten befüllt. Du weißt auch, wie man sie mischt. Reicht das nicht, um es auf Deinen (für mich recht unverständlichen Anwendungsfall) zu übertragen? Du musst die Liste halt anders und mit anderen Werten (ggf. sogar Werte doppelt, das geht bei einer Liste) befüllen.

Edit: Geht es nicht auch mit sowas wie
int zufallsZahl4 = zufallszahl.nextint(3 !=zufallsZahl3);
allerdings vertragen sich Zahlen und boolean nicht, kann ich das ändern, aber bei dieser Idee bleiben? Dann wäre das Problem eigentlich auch schon gelöst!

Liste mit Zahlen 1,2 & 3.

Zufälligen Index für Gewinn bestimmen. gewinn = nextInt(liste.size());
Gewinn aus der Liste rausziehen.
Jetzt 2x ziehen, 1x für Wahl, einmal für Niete.

Müsste doch klappen

Danke, versuche es später nochmal und gebe dann Rückmeldung.

[QUOTE=temao]Edit: Geht es nicht auch mit sowas wie
int zufallsZahl4 = zufallszahl.nextint(3 !=zufallsZahl3);
allerdings vertragen sich Zahlen und boolean nicht, kann ich das ändern, aber bei dieser Idee bleiben? Dann wäre das Problem eigentlich auch schon gelöst![/QUOTE]

Das sähe so aus, wäre aber extremst uneffizient:

int x = 0;
do{
    x = random.nextInt(3); //oder math.random oder wat auch immer
}
while(x == zahlDieNichtSeinDarf);

@temao : was möchtest du mit dem Programm bezwecken? Ich habe vor Jahren mal das ein Progrämmchen geschrieben, das die Gewinnwahrscheinlichkeit ermittelt.

procedure TForm1.Button1Click(Sender: TObject);
var
  a,b: Byte;
  i, gewonnen, verloren: Cardinal;
begin
  randomize;
  gewonnen:=0;
  verloren:=0;
  for i:=1 to StrToInt(EdtDurchlaeufe.Text) do begin
    a:=Random(3);
    b:=Random(3);
    if (a=b) then begin
      inc(verloren);
    end else begin
      inc(gewonnen);
    end;
  end;
  Label1.Caption:=FloatToStr(gewonnen/(verloren+gewonnen));
end;