Java code- TicTac toe

Wirtschaftsinformatiker

Bekanntes Mitglied
Kann jemand den Code erklären?
Warum machen wir -1? Wofür steht 0b11? Warum machen wir *2 und ?
warum schieben wir nach rechts? Ich verstehe den Code garnicht
Java:
public int gibBesitzer(int zeile, int spalte) {
        int index = zeile*3+spalte;
        return (spielInt>>>2*index & 0b11) - 1;
    }
public void besetzePosition(int zeile, int spalte, int spieler) {
        int index = zeile*3+spalte;
        spielInt &= ~(0b11 << 2*index); // clear
        spielInt |= (spieler+1) << 2*index;
    }
 

KonradN

Super-Moderator
Mitarbeiter
Also so einen Ausschnitt zu zeigen bringt nur Vermutungen. Im Code wird man z.B. sehen, wie man Werte speichert. Wie die Besitzer gespeichert werden und so.

Und was hast Du denn verstanden? Woran scheitert es? Hast Du die einzelnen Operatoren verstanden?
Kannst Du das, was da gemacht wird, denn erläutern? Hast Du das mal einfach mit Stift und Papier durchgespielt?

int index = zeile*3+spalte;
Was wird hier berechnet? Was kommt da raus? Hast Du mal ein Spielfeld aufgemalt und dann die index Werte eines jeden Feldes rein geschrieben?

(spielInt>>>2*index & 0b11) - 1;
Was passiert da bei den Operatoren? Was macht spielInt>>>2*index?
Wenn Du das verstanden hast: Was macht ein & 0b11 - was ist dieses 0b11 überhaupt?

Das -1 wirst Du verstehen, wenn Du anschaust, wie Werte geschrieben werden. Welche Werte werden denn als Besitzer genommen?
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Also so einen Ausschnitt zu zeigen bringt nur Vermutungen. Im Code wird man z.B. sehen, wie man Werte speichert. Wie die Besitzer gespeichert werden und so.

Und was hast Du denn verstanden? Woran scheitert es? Hast Du die einzelnen Operatoren verstanden?
Kannst Du das, was da gemacht wird, denn erläutern? Hast Du das mal einfach mit Stift und Papier durchgespielt?

int index = zeile*3+spalte;
Was wird hier berechnet? Was kommt da raus? Hast Du mal ein Spielfeld aufgemalt und dann die index Werte eines jeden Feldes rein geschrieben?

(spielInt>>>2*index & 0b11) - 1;
Was passiert da bei den Operatoren? Was macht spielInt>>>2*index?
Wenn Du das verstanden hast: Was macht ein & 0b11 - was ist dieses 0b11 überhaupt?

Das -1 wirst Du verstehen, wenn Du anschaust, wie Werte geschrieben werden. Welche Werte werden denn als Besitzer genommen?
int index = zeile*3+spalte;
int index = zeile*3+spalte;
setzt die beiden Indices für ein 3x3-Feld in einen Index für ein eindimensionales Array um:

0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
wird übersetzt in

0 1 2
3 4 5
6 7 8

Ich kenne schon die Bedeutung von einzelnen Opertionen, aber seine Bedeutung mit dem Code verstehe ich nicht.
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Der Code kommt aus diesem Code, die ich aber nicht verstanden habe.
Java:
public class SpielfeldInteger implements Spielfeld
{
    private int spielInt;
    
    /**
     * Initialisiert ein neues, leeres Spielfeld.
     */
    public SpielfeldInteger() {
        spielInt = 0x00000;//2AAAA
        // 0000 0000 0000 0000 0000;
    }

    /**
     * Gibt den Besitzer der angegebenen Position auf dem Spielfeld.
     *
     * @param zeile  vertikale Position (0-2)
     * @param spalte horizontale Position (0-2)
     * @return 0 (unbesetzt), 1 (Spieler 1), 2 (Spieler 2)
     */
    public int gibBesitzer(int zeile, int spalte) {
        int schiebung = (zeile*3*2)+(spalte*2);
        int geschobenerInt = spielInt>>>schiebung;
        //System.out.println(Integer.toBinaryString(geschobenerInt));
        
        //System.out.println((geschobenerInt&3));
        if((geschobenerInt&3) == 2) {
            return 1;
        } else if((geschobenerInt&3) == 3) {
            return 2;
        } else {
            return 0;
        }
    }

    /**
     * Besetzt die angegebene Position auf dem Spielfeld fuer einen Spieler.
     *
     * @param zeile   vertikale Position (0-2)
     * @param spalte  horizontale Position (0-2)
     * @param spieler 0 (leer), 1 (Spieler 1), 2 (Spieler 2)
     */
    public void besetzePosition(int zeile, int spalte, int spieler) {
        int setzung;
        if(spieler == 1 || spieler == 2) {
            setzung = (spieler+1)<<(zeile*3*2)+(spalte*2);
            spielInt = spielInt|setzung;
        }
        else if(spieler == 0) {
            setzung = ~(3<<(zeile*3*2)+(spalte*2));
            spielInt = spielInt&setzung;
        }
        
        
    }

    /**
     * Gibt an, ob das Spielfeld an allen Positionen belegt ist.
     */
    public boolean istVoll() {
        return ((spielInt&0x2AAAA) == 0x2AAAA);
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Damit hast Du das mit dem index verstanden. Was ist mit den übrigen Dingen?

So Code kann man sich nur erarbeiten, in dem man sich genau überlegt, was jeder einzelne Schritt macht. Das dann verständlich formuliert und schon hat man eine Beschreibung an Hand derer man einen Überblick bekommen kann.

Daher wirklich alle Punkte der Reihe nach ganz genau beschreiben!
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Damit hast Du das mit dem index verstanden. Was ist mit den übrigen Dingen?

So Code kann man sich nur erarbeiten, in dem man sich genau überlegt, was jeder einzelne Schritt macht. Das dann verständlich formuliert und schon hat man eine Beschreibung an Hand derer man einen Überblick bekommen kann.

Daher wirklich alle Punkte der Reihe nach ganz genau beschreiben!
Ich verstehe nicht, wie die Opertaionen mit dem Code verstehe, also welche Bedeutung sie im Code haben? Also was ist 0b11?
 

KonradN

Super-Moderator
Mitarbeiter
Also was ist 0b11?
Das ist ein Literal - um genau zu sein: ein Integer Literal:

Und da halt speziell ein binary numeral:
A binary numeral consists of the leading ASCII characters 0b or 0B followed by one or more of the ASCII digits 0 or 1 interspersed with underscores, and can represent a positive, zero, or negative integer.

0b11 ist also einfach eine 3 - ein 2 Bit lange "binary numeral" bestehend aus zwei 1er und damit ist der Wert 1 + 2 = 3

Damit haben wir einen weiteren Punkt meiner Fragen geklärt. Wie wäre es, wenn man die weiteren Punkt auch noch klärt?
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Das ist ein Literal - um genau zu sein: ein Integer Literal:

Und da halt speziell ein binary numeral:


0b11 ist also einfach eine 3 - ein 2 Bit lange "binary numeral" bestehend aus zwei 1er und damit ist der Wert 1 + 2 = 3

Damit haben wir einen weiteren Punkt meiner Fragen geklärt. Wie wäre es, wenn man die weiteren Punkt auch noch klärt?
2* ( zeile*3+ spalte), also *2 weil jedes Feld 2 Bits hat, richtig? Wir habe neun Zellen, dann 18 Bits
 

temi

Top Contributor
Wie wird denn das Spielfeld gespeichert?
int index = zeile*3+spalte;
int index = zeile*3+spalte;
setzt die beiden Indices für ein 3x3-Feld in einen Index für ein eindimensionales Array um:

0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
wird übersetzt in

0 1 2
3 4 5
6 7 8
Du hast ja bereits erläutert, wie man einen Index für ein mehrdimensionales (Spiel-) Feld in ein eindimensionales Feld umrechnet. Du hast geschrieben Array. Es gibt aber kein Array. Wie wird also das Spielfeld gespeichert. Hilfe: Die Lösung steht bereits im Namen der Klasse.

Lösung: Das Feld wird in einem Integer gespeichert. Du hast also 32 Bit zur Verfügung, um ein Spielfeld mit 9 Feldern unterzubringen. Nebenbei hast du zwei Spieler, ein Feld muss also drei Zustände annehmen können: leer - Spieler 1 - Spieler 2. Wie du bereits erkannt hast, benötigt man dazu 2 Bits. Jeweils zwei Bits der 32 Bit des Integers entsprechen also einem Feld. Und die kann man auch indexieren, ungefähr so:
Code:
Bits im Integer: .. 00 00 00 00 00 00 00 00 00
Index          :     8  7  6  5  4  3  2  1  0

Jetzt kannst du dir mal überlegen, wie man mit dem gezeigten Code an die entsprechenden Stellen heran kommt.
 
Zuletzt bearbeitet:

MarvinsDepression

Bekanntes Mitglied
in der Variablen spielInt (Typ int -> 32bit groß) ist das ganze Spielfeld abgebildet, einschließlich der Besitzer der einzelnen Felder. Für jedes der neun Felder werden zwei benachbarte bits reserviert. Je nachdem, welches der bits gesetzt, also (1) ist, bedeuted es, dass Spieler_0, oder Spieler_1 im Besitz eines Feldes ist.
Java:
Zeile           |    2   |    1   |    0   |
Spalte          | 2| 1| 0| 2| 1| 0| 2| 1| 0|
       |00| ... |10|01|01|10|00|00|10|00|01| <- spielInt
        ^        ^                        ^
bit-nr. 31(MSB) 17           ...          0(LSB)

leer      : 0 => 0b00
Spieler_0 : 1 => 0b01
Spieler_1 : 2 => 0b10
Kannst Du der zeile 3 aus dem Beispiel entnehmen, wer gerade gewonnen hat?
 

temi

Top Contributor
Das ist nicht ganz korrekt, gemäß dem oben gezeigten Code, werden die Spieler anders kodiert:
Java:
// @param spieler 0 (leer), 1 (Spieler 1), 2 (Spieler 2)
leer      : 0 => 0b00
Spieler 1 : 2 => 0b10
Spieler 2 : 3 => 0b11
 

KonradN

Super-Moderator
Mitarbeiter
Also Nur um es noch einmal ganz deutlich zu machen:

Du hast eine binäre Darstellung - es werden immer 2 Bit pro Feld gespeichert.

Ein Bit besagt, ob ein Feld belegt ist oder nicht und das andere bit besagt, welcher Spieler (falls das Feld belegt ist).

Bei den 9 Feldern sind das also 18 Bit, die genutzt werden. Diese 18 Bit betrachten wir jetzt einfach. Am Anfang ist alles 0:

00 00 00 00 00 00 00 00 00

Wenn wir jetzt ein bestimmtes Feld haben wollen, dann müssen wir
a) Die bits so verschieben, dass die gewünschten Bits ganz rechts sind.
b) alle anderen bits wegmachen.

Also wir interessieren uns z.B. für index 2 - das wären dann diese Bits:
?? ?? ?? ?? ?? ?? xx ?? ?? (da wir die anderen Werte nicht kennen, habe ich da mal ?? gesetzt!)

Um diese xx ganz rechts zu haben, müssen wir alles nach rechts schieben. Dazu dient der Operator >>>
Und um wie viele Bits müssen wir schieben? Um 4 Bits - halt 2 * den index.

Somit erhalten wir bei >>> 4 dann folgendes:
?? ?? ?? ?? ?? ?? xx

Nun stören aber noch die ganzen ?? - um die los zu werden können wir nun eine bitweise operation machen.

0 und 0 -> 0
0 und 1 -> 0
1 und 0 -> 0
1 und 1 -> 0

Also 0 und ? ist immer 0.

Also machen wir:
?? ?? ?? ?? ?? ?? xx und
00 00 00 00 00 00 11

und erhalten: 00 00 00 00 00 00 xx

Bei den gannzen 0er und dann 11 kann man die führenden 0er weglassen ... das ist also einfach 11 (also 0b11 in Java)

Somit weisst Du nun, wie die Methode nun den Wert eines Feldes bekommt.
 

Wirtschaftsinformatiker

Bekanntes Mitglied
in der Variablen spielInt (Typ int -> 32bit groß) ist das ganze Spielfeld abgebildet, einschließlich der Besitzer der einzelnen Felder. Für jedes der neun Felder werden zwei benachbarte bits reserviert. Je nachdem, welches der bits gesetzt, also (1) ist, bedeuted es, dass Spieler_0, oder Spieler_1 im Besitz eines Feldes ist.
Java:
Zeile           |    2   |    1   |    0   |
Spalte          | 2| 1| 0| 2| 1| 0| 2| 1| 0|
       |00| ... |10|01|01|10|00|00|10|00|01| <- spielInt
        ^        ^                        ^
bit-nr. 31(MSB) 17           ...          0(LSB)

leer      : 0 => 0b00
Spieler_0 : 1 => 0b01
Spieler_1 : 2 => 0b10
Kannst Du der zeile 3 aus dem Beispiel entnehmen, wer gerade gewonnen hat?
Kannst du bitte auch die Methode besetztePosition erklären?
 

KonradN

Super-Moderator
Mitarbeiter
Warum dann -1?
return (spielInt>>>2*index & 0b11) - 1;
Weil der Wert 1 bzw 2 mit +1 gespeichert wird:
setzung = (spieler+1)<<(zeile*3*2)+(spalte*2);

Die Idee ist halt, dass Du hast:
00 -> nicht belegt
1x -> belegt mit x = 0 bzw. 1 für Spieler 1 bzw 2.

Wenn Du so Code hast, den Du nicht verstehst, dann spiel etwas damit:
=> Schreib Dir eine Methode, die diese 18 Bit ausgibt
=> Nutze diverse Methoden um Werte zu setzen / zu lesen um zu sehen, was gespeichert wird.

Darüber kannst Du dann prüfen, ob alle Felder belegt sind: (spielInt&0x2AAAA) == 0x2AAAA
Das wirst Du verstehenm wenn Du 0x2AAAA einmal binär darstellst.
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Weil der Wert 1 bzw 2 mit +1 gespeichert wird:
setzung = (spieler+1)<<(zeile*3*2)+(spalte*2);

Die Idee ist halt, dass Du hast:
00 -> nicht belegt
1x -> belegt mit x = 0 bzw. 1 für Spieler 1 bzw 2.

Wenn Du so Code hast, den Du nicht verstehst, dann spiel etwas damit:
=> Schreib Dir eine Methode, die diese 18 Bit ausgibt
=> Nutze diverse Methoden um Werte zu setzen / zu lesen um zu sehen, was gespeichert wird.

Darüber kannst Du dann prüfen, ob alle Felder belegt sind: (spielInt&0x2AAAA) == 0x2AAAA
Das wirst Du verstehenm wenn Du 0x2AAAA einmal binär darstellst.
Warum aber &3? Es bedeutet drei Werte 0, 1, 2?
 

Wirtschaftsinformatiker

Bekanntes Mitglied
in der Variablen spielInt (Typ int -> 32bit groß) ist das ganze Spielfeld abgebildet, einschließlich der Besitzer der einzelnen Felder. Für jedes der neun Felder werden zwei benachbarte bits reserviert. Je nachdem, welches der bits gesetzt, also (1) ist, bedeuted es, dass Spieler_0, oder Spieler_1 im Besitz eines Feldes ist.
Java:
Zeile           |    2   |    1   |    0   |
Spalte          | 2| 1| 0| 2| 1| 0| 2| 1| 0|
       |00| ... |10|01|01|10|00|00|10|00|01| <- spielInt
        ^        ^                        ^
bit-nr. 31(MSB) 17           ...          0(LSB)

leer      : 0 => 0b00
Spieler_0 : 1 => 0b01
Spieler_1 : 2 => 0b10
Kannst Du der zeile 3 aus dem Beispiel entnehmen, wer gerade gewonnen hat?
Wie können wir verstehen, wer gewonnen ist?
 

Wirtschaftsinformatiker

Bekanntes Mitglied
in der Variablen spielInt (Typ int -> 32bit groß) ist das ganze Spielfeld abgebildet, einschließlich der Besitzer der einzelnen Felder. Für jedes der neun Felder werden zwei benachbarte bits reserviert. Je nachdem, welches der bits gesetzt, also (1) ist, bedeuted es, dass Spieler_0, oder Spieler_1 im Besitz eines Feldes ist.
Java:
Zeile           |    2   |    1   |    0   |
Spalte          | 2| 1| 0| 2| 1| 0| 2| 1| 0|
       |00| ... |10|01|01|10|00|00|10|00|01| <- spielInt
        ^        ^                        ^
bit-nr. 31(MSB) 17           ...          0(LSB)

leer      : 0 => 0b00
Spieler_0 : 1 => 0b01
Spieler_1 : 2 => 0b10
Kannst Du der zeile 3 aus dem Beispiel entnehmen, wer gerade gewonnen hat?
"also (1) ist, bedeuted es, dass Spieler_0, oder Spieler_1 im Besitz eines Feldes ist." Welche 1 meinen Sie?
 

KonradN

Super-Moderator
Mitarbeiter
Können wir hier einfach >>> statt >> benutzen?
Also bei dem verschieben nach rechts war ja der >>> im Code. Generell kann aber auch das >> genommen werden.

Der Unterschied findet sich hier: https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.19
> (signed right shift), and >>> (unsigned right shift)

Also der Unterschied ist, wie mit dem Vorzeichen umgegangen wird. Einmal wird einfach das Vorzeichen beachtet und das andere Mal kommt einfach eine 0 rein. Da das Vorzeichenbit aber immer 0 ist (wir haben ja nur positive Werte da drin) ist der Verhalten hier also gleich.
 

MarvinsDepression

Bekanntes Mitglied
Nochmals in korrigierter Fassung, da ich mich in #14 nicht ganz an die Vorgaben gehalten habe.
Code:
Zeile                |    2   |    1   |    0   |
Spalte               | 2| 1| 0| 2| 1| 0| 2| 1| 0|
spielInt    |00| ... |10|11|11|10|00|00|10|00|11| (für das Programm sind nur die rechten 18 bit wichtig)
             ^        ^                        ^
bit-Position 31(MSB)  17          ...          0(LSB)

leer      : 0 => binär 00    (linkes bit (=0) -> Feld frei)
Spieler_1 : 2 => binär 10   (linkes bit (=1) -> Feld besetzt, rechtes bit (=0) -> Spieler_1)
Spieler_2 : 3 => binär 11    (linkes bit (=1) -> Feld besetzt, rechtes bit (=1) -> Spieler_2)

gewonnen hat Spieler_1, weil drei mal in Spalte 2 das Bitmuster 10 steht.
Jetzt überlege Dir: Um wieviele bit-Positionen muss das bit-Paar einer bestimmten Zeilen/Spalten-Kombination nach rechts verschoben werden, damit es an Position 0 zu liegen kommt?
Warum will man nun ein bestimmtes bit-Paar ganau an Position 0 haben. Weil nur dann sich Werte vergleichen lassen, wie z.B. das Bitmuster eines Feldes mit dem Bitmuster eines bestimmten Spielers.
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Nochmals in korrigierter Fassung, da ich mich in #14 nicht ganz an die Vorgaben gehalten habe.
Code:
Zeile                |    2   |    1   |    0   |
Spalte               | 2| 1| 0| 2| 1| 0| 2| 1| 0|
spielInt    |00| ... |10|11|11|10|00|00|10|00|11| (für das Programm sind nur die rechten 18 bit wichtig)
             ^        ^                        ^
bit-Position 31(MSB)  17          ...          0(LSB)

leer      : 0 => binär 00    (linkes bit (=0) -> Feld frei)
Spieler_1 : 2 => binär 10   (linkes bit (=1) -> Feld besetzt, rechtes bit (=0) -> Spieler_1)
Spieler_2 : 3 => binär 11    (linkes bit (=1) -> Feld besetzt, rechtes bit (=1) -> Spieler_2)

gewonnen hat Spieler_1, weil drei mal in Spalte 2 das Bitmuster 10 steht.
Jetzt überlege Dir: Um wieviele bit-Positionen muss das bit-Paar einer bestimmten Zeilen/Spalten-Kombinatiowarum setzen wir hiern nach rechts verschoben werden, damit es an Position 0 zu liegen kommt?
Warum will man nun ein bestimmtes bit-Paar ganau an Position 0 haben. Weil nur dann sich Werte vergleichen lassen, wie z.B. das Bitmuster eines Feldes mit dem Bitmuster eines bestimmten Spielers.
Warum setzen wie hier ==2 oder ==3 , woher kommen diese Zahlen? Warum &3 jmx nicht &2? Kannst du die Zeile 1 bis 8 bei folgenden Code erklären?
Java:
if((geschobenerInt&3) == 2) {
            return 1;
        } else if((geschobenerInt&3) == 3) {
            return 2;
        } else {
            return 0;
        }
    }
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Hast Du dir das bitweise und einmal im Detail angesehen? Die ganzen Erklärungen sind doch schon gekommen.

3 ist binäre 11 - wir wollen nur die letzten 2 Bits betrachten:
Also machen wir:
?? ?? ?? ?? ?? ?? xx und
00 00 00 00 00 00 11 ergibt
00 00 00 00 00 00 xx ==> die letzten zwei Bit bleiben und alles übrige bleibt.

Und das ==2 bzw ==3 ist doch logisch. Es wurde ja die Spielernummer + 1 eingetragen. Also bei Spieler 1 steht da 2 und bei Spieler 2 eine 3.

Mal Dir das mit den Bits richtig auf und spiel es durch. Ich habe das sichere Gefühl, dass Du massive Probleme hast mit den bitweisem Verknüpfungen aber auch mir den ganzen anderen Operatoren, die verwendet wurden. Aber mehr, als die einmal zu erläutern können wir nicht. Die wichtigen Punkte sind jetzt mehrfach beschrieben worden - geh diese durch und versuch die Erläuterungen zu verstehen.
 

temi

Top Contributor
Das Eintragen des Spielers geschieht hier:
Java:
int setzung;
if(spieler == 1 || spieler == 2) {
    setzung = (spieler+1) << (zeile*3*2)+(spalte*2);
    spielInt = spielInt | setzung;
}

Zunächst enthält setzung den Wert 0.

Jetzt möchten wir Spieler 2 auf das Feld 2 eintragen. Hier der erste Teil (spieler + 1) in binärer Darstellung:
Java:
Spieler 2  => 0b10 (2)
+ 1        => 0b11 (3)

Das muss jetzt an die Stelle von Feld 2. Wie der Index berechnet wird, weißt du ja aus Beitrag #3.

Wir verschieben also den berechneten Wert um die entsprechende Anzahl an Bits nach links, das Ergebnis ist (nur 8 von 32 Bits dargestellt)
Java:
0b00110000

Jetzt muss dieser Wert nur noch in das eigentliche Spielfeld übertragen werden. Dazu verwenden wir diesmal die logische ODER Verknüpfung:
Java:
0 oder 0 -> 0
0 oder 1 -> 1
1 oder 0 -> 1
1 oder 1 -> 1

Java:
Spielfeld: 0b???????? ODER
Setzung  : 0b00110000
ergibt   : 0b??11????

Alle Bits, die in Setzung "1" enthalten, enthalten auch im Spielfeld den Wert "1". Die anderen Bits aus Spielfeld bleiben unverändert erhalten. Genau was erreicht werden sollte.

Diese Technik mit Bitmasken sowie UND/ODER Verknüpfungen gezielt Bits zu manipulieren ist schon sehr alt, Stichworte dafür sind "Bitmaske" oder "Bitmanipulation".
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Hast Du dir das bitweise und einmal im Detail angesehen? Die ganzen Erklärungen sind doch schon gekommen.

3 ist binäre 11 - wir wollen nur die letzten 2 Bits betrachten:
Also machen wir:
?? ?? ?? ?? ?? ?? xx und
00 00 00 00 00 00 11 ergibt
00 00 00 00 00 00 xx ==> die letzten zwei Bit bleiben und alles übrige bleibt.

Und das ==2 bzw ==3 ist doch logisch. Es wurde ja die Spielernummer + 1 eingetragen. Also bei Spieler 1 steht da 2 und bei Spieler 2 eine 3.

Mal Dir das mit den Bits richtig auf und spiel es durch. Ich habe das sichere Gefühl, dass Du massive Probleme hast mit den bitweisem Verknüpfungen aber auch mir den ganzen anderen Operatoren, die verwendet wurden. Aber mehr, als die einmal zu erläutern können wir nicht. Die wichtigen Punkte sind jetzt mehrfach beschrieben worden - geh diese durch und versuch die Erläuterungen zu verstehen.
Kannst du bitte auch die Methode besetzePosition erklären?
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Das hat temi doch in #34 gemacht.
ich hab den Code bisschen geändert, ist jetzt auch richtig?
Java:
public class SpielfeldInteger implements Spielfeld
{
    private int spielInt;

    /**
     * Initialisiert ein neues, leeres Spielfeld.
     */
    public SpielfeldInteger() {
        spielInt = 0; //00 00 00 00 00 00 00 00 00
    }

    /**
     * Gibt den Besitzer der angegebenen Position auf dem Spielfeld.
     *
     * @param zeile  vertikale Position (0-2)
     * @param spalte horizontale Position (0-2)
     * @return 0 (unbesetzt), 1 (Spieler 1), 2 (Spieler 2)
     */
    public int gibBesitzer(int zeile, int spalte) {
        int index= zeile*3+spalte;

        int schiebung = 2*(zeile*3+spalte);
        int geschobenerInt = spielInt>>schiebung;

        if((geschobenerInt&3) == 0b01) {            //0b01= 1 Dezimal
            return 1;
        } else if((geschobenerInt&3) == 0b10) {     //0b10 = 2 Dezimal
            return 2;
        } else {
            return 0;
        }
    }

    /**
     * Besetzt die angegebene Position auf dem Spielfeld fuer einen Spieler.
     *
     * @param zeile   vertikale Position (0-2)
     * @param spalte  horizontale Position (0-2)
     * @param spieler 0 (leer), 1 (Spieler 1), 2 (Spieler 2)
     */

    public void besetzePosition(int zeile, int spalte, int spieler) {
        int setzung;
        if(spieler == 1 || spieler == 2) {
            setzung = spieler <<2*(zeile*3+spalte);
            spielInt = spielInt|setzung;
        }
        else if(spieler == 0) {
            setzung = ~(3<<2*(zeile*3+spalte));
            spielInt = spielInt&setzung;
        }
    }

    /**
     * Überprüft ob das Spielfeld komplett voll ist
     * return   boolean true falls Spielfeld voll ist
     */

    public boolean istVoll() {
        for(int zeile = 0; zeile<3; zeile++) {
            for(int spalte = 0; spalte<3; spalte++) {
                if(gibBesitzer(zeile, spalte) == 0) {
                    return false;
                }
            }
        }
        return true;
    }
}
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Das Eintragen des Spielers geschieht hier:
Java:
int setzung;
if(spieler == 1 || spieler == 2) {
    setzung = (spieler+1) << (zeile*3*2)+(spalte*2);
    spielInt = spielInt | setzung;
}

Zunächst enthält setzung den Wert 0.

Jetzt möchten wir Spieler 2 auf das Feld 2 eintragen. Hier der erste Teil (spieler + 1) in binärer Darstellung:
Java:
Spieler 2  => 0b10 (2)
+ 1        => 0b11 (3)

Das muss jetzt an die Stelle von Feld 2. Wie der Index berechnet wird, weißt du ja aus Beitrag #3.

Wir verschieben also den berechneten Wert um die entsprechende Anzahl an Bits nach links, das Ergebnis ist (nur 8 von 32 Bits dargestellt)
Java:
0b00110000

Jetzt muss dieser Wert nur noch in das eigentliche Spielfeld übertragen werden. Dazu verwenden wir diesmal die logische ODER Verknüpfung:
Java:
0 oder 0 -> 0
0 oder 1 -> 1
1 oder 0 -> 1
1 oder 1 -> 1

Java:
Spielfeld: 0b???????? ODER
Setzung  : 0b00110000
ergibt   : 0b??11????

Alle Bits, die in Setzung "1" enthalten, enthalten auch im Spielfeld den Wert "1". Die anderen Bits aus Spielfeld bleiben unverändert erhalten. Genau was erreicht werden sollte.

Diese Technik mit Bitmasken sowie UND/ODER Verknüpfungen gezielt Bits zu manipulieren ist schon sehr alt, Stichworte dafür sind "Bitmaske" oder "Bitmanipulation".
Aber warum spieler 2 und spieler +1 UND nicht spieler 1 und spieler 2? Wir haben doch zwei spieler?
 

KonradN

Super-Moderator
Mitarbeiter
Das wurde bereits behandelt:

Es sollen binär die Werte 10 und 11 gespeichert werden, denn so lässt sich das höherwertige bit als Flag: belegt / nicht belegt benutzen. (Was dann zu der Möglichkeit führt, dass man dies über das 2AAAA prüfen kann.)
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Das wurde bereits behandelt:

Es sollen binär die Werte 10 und 11 gespeichert werden, denn so lässt sich das höherwertige bit als Flag: belegt / nicht belegt benutzen. (Was dann zu der Möglichkeit führt, dass man dies über das 2AAAA prüfen kann.)
Ich habe meine istVoll Methode geändert, weil ich nicht mit 2AAAAA zurecht komme. Mit dieser Änderung ist mein Code #37 richtig? oder muss trotzdem 10, 11 und dann spieler+1 schreiben?
 

Wirtschaftsinformatiker

Bekanntes Mitglied
Hier würde ich empfehlen, einfach einmal den Code selbst zu testen. Du kannst das ja einfach einmal nutzen - halt diverse Felder setzen und immer prüfen, dass genau dieses Feld gesetzt wurde und kein anderes. Da kannst Du dann den ganzen Code intensiv ausprobieren um dann so selbst die Frage zu beantworten.
hab probiert, es funktioniert, aber ist der Code vom syntax richtig?
 

Wirtschaftsinformatiker

Bekanntes Mitglied
aber wie wird diesen Code ändern?
leer : 0 => binär 00 (linkes bit (=0) -> Feld frei)
Spieler_1 : 1 => binär 01 (linkes bit (=0) ->?????
Spieler_2 : 2 => binär 10 (linkes bit (=1) -> Feld besetzt, rechtes bit (=0) -> ??????
Java:
leer      : 0 => binär 00    (linkes bit (=0) -> Feld frei)
Spieler_1 : 2 => binär 10   (linkes bit (=1) -> Feld besetzt, rechtes bit (=0) -> Spieler_1)
Spieler_2 : 3 => binär 11    (linkes bit (=1) -> Feld besetzt, rechtes bit (=1) -> Spieler_2)
 

temi

Top Contributor
weil ich nicht mit 2AAAAA zurecht komme
Such unbedingt nach "Bitmaske" oder "Bitmanipulation". Das sind Techniken, die man nicht oft benötigt, aber dennoch kennen sollte. Die ganze Übung, die du gerade machst, geht nur ganz genau um dieses Thema.

Du weißt, dass ein Spieler zwei Bit belegt. Sobald das Feld besetzt ist, dann ist das höherwertige Bit gesetzt. Welcher Spieler darauf steht ist egal (=> ?).
Java:
2b0? => Feld frei
2b1? => Feld belegt

Wir beschränken uns wieder auf 8 Bit, damit es nicht so lang wird. Das Feld 2 ist durch einen Spieler belegt, sieht also so aus:
Java:
2b001?0000

Möchte ich wissen, ob diese Feld belegt ist, dann kann ich das mit einer Bitmaske herausfinden:
Java:
2b001?0000 (Feld)
2b00100000 (Maske)
------------------ AND  
2b00100000 (Ergebnis)
Das Ergebnis entspricht der Maske, wenn das Feld gesetzt war, ansonsten wäre es 0 (in diesem Fall).

Jetzt besetzen wir alle Felder.
Java:
2b1?1?1?1? (Feld)
2b10101010 (Maske)
------------------ AND
2b10101010 (Ergebnis)

Gleicher Ergebnis: Wenn das Ergebnis der Maske entspricht, dann waren alle Felder gesetzt.
Die binäre Darstellung 2b10101010 entspricht einer hexadezimalen Darstellung von 0xAA

Die Verknüpfung mit 0x2AAAA ist das selbe Prinzip nur mit ein paar Bits mehr, um alle 9 Felder abzudecken.
Java:
2AAAA (hexadezimal)
101010101010101010 (binär)
 

temi

Top Contributor
Die hexadezimale Darstellung geht ja von 0 bis F, was dezimal 0 bis 15 und binär 0000 bis 1111 entspricht. Man kann eine binäre Darstellung also ganz gut in Viererblöcke aufteilen und sehr leicht zur hexadezimalen Darstellung gelangen.
Java:
0000 => 0x0
0001 => 0x1
1010 => 0xA
1111 => 0xF


00101010101010101010 (binär)

0010 1010 1010 1010 1010 (binär in Viererblöcken)
0x2  0xA  0xA  0xA  0xA  (hexadezimal in Viererblöcken)
   
0x2AAAA (hexadezimal)

Siehst du also 0xFF, dann kannst du mit einem Blick sagen => zwei Viererblöcke => 8 Bit => jeweils alle Bit gesetzt => 2b1111 1111.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I QR code in Java selber generieren Java Basics - Anfänger-Themen 5
W Java-Code mit Array Java Basics - Anfänger-Themen 14
W Java-Code Java Basics - Anfänger-Themen 2
W Java-code Java Basics - Anfänger-Themen 8
W Java-code Java Basics - Anfänger-Themen 9
W Java-Code erklären Java Basics - Anfänger-Themen 6
C Java boolean Code läuft nicht Java Basics - Anfänger-Themen 5
B Den Dateipfad einer Java Datei durch Code in Selbiger finden? Java Basics - Anfänger-Themen 10
S Hilfe bei Umänderung von Java Code Java Basics - Anfänger-Themen 16
N Java-Code abwärtskompatibel machen Java Basics - Anfänger-Themen 4
Aemulit Java Schaltjahr berechnen Code Java Basics - Anfänger-Themen 7
F Frage betreff Programm mit dem man C++-Code in JAVA-Code übersetzen lassen kann Java Basics - Anfänger-Themen 2
I Erklärung zum Java Code Java Basics - Anfänger-Themen 2
AlexVo String zu Java Anweisung getString("*** java code ***") Java Basics - Anfänger-Themen 19
Gaudimagspam Caesars Code entziffern in Java Java Basics - Anfänger-Themen 8
X Reverse algorithm engineering (Java code) Java Basics - Anfänger-Themen 6
M Java Code Verständnis Java Basics - Anfänger-Themen 4
M Java Code Verständnis Java Basics - Anfänger-Themen 2
J Fragen zum Code aus dem Buch "Schrödinger programmiert Java 2.te Ausgabe" Java Basics - Anfänger-Themen 6
S Brauche hilfe in Java [Fehler in mein Code]? Java Basics - Anfänger-Themen 2
B UML Klassen Diagramm zu Java Code Programmieren und ausführen Java Basics - Anfänger-Themen 21
C Klassendiagramm aus Java-Code entwickeln Java Basics - Anfänger-Themen 3
B HTML Code / Seite auslesen und JAVA Objekte erstellen Java Basics - Anfänger-Themen 12
T Java Code erklären Java Basics - Anfänger-Themen 7
B Java Vererbung Fragen (zu Code Beispiel) Java Basics - Anfänger-Themen 3
E ASCII-Code in Java ausgeben Java Basics - Anfänger-Themen 6
L Wie kann man fehlerfrei im Java Code auf die fxml Datei zugreifen? Java Basics - Anfänger-Themen 26
D Text als Code in java-forum.com formatieren. Wie ? Java Basics - Anfänger-Themen 3
P Java-Code funktioniert nicht Java Basics - Anfänger-Themen 13
snipesss Java-Code gedownloaded, funktioniert aber nicht? Java Basics - Anfänger-Themen 9
T Java Code erklären Java Basics - Anfänger-Themen 5
S Hinweis zu Fehler im Kalender-Code - Aufgabe 5.3 aus Grundkurs Programmieren in Java 7. Auflage Java Basics - Anfänger-Themen 4
A Zeichentool mit automatischer Java Code Erstellung Java Basics - Anfänger-Themen 1
Nicole1989 Was Bewirkt dieser Java Code? Java Basics - Anfänger-Themen 4
S Input/Output JS Source code in Java nutzen Java Basics - Anfänger-Themen 1
J Java was Started but Returned Exit Code=13 in Eclipse Java Basics - Anfänger-Themen 13
A Code läuft nicht, Fehlermeldung Exception in thread "main" java.lang.Error: Unresolved compilation " Java Basics - Anfänger-Themen 11
I Java Code so gut es geht Kommentieren Java Basics - Anfänger-Themen 4
K Suche Hilfe bei einfachem Java Code ( Debuggen ) Java Basics - Anfänger-Themen 1
T Java Code Hilfe - public void xxx() Java Basics - Anfänger-Themen 2
C CMD Befehl + Variable im Java-Code ausführen Java Basics - Anfänger-Themen 8
B Variablen im Java-Code selber "ausrechnen" Java Basics - Anfänger-Themen 8
O Rätsel Java Code Java Basics - Anfänger-Themen 8
O Forum: Per Java-Code anmelden? Java Basics - Anfänger-Themen 2
E Mein erstes Java Projekt - Sauberer code? Java Basics - Anfänger-Themen 28
M Code recompilen mit älterem Java Java Basics - Anfänger-Themen 3
C Fehler in Java-Code finden Java Basics - Anfänger-Themen 17
K Java source code generieren Java Basics - Anfänger-Themen 5
H Java- Source Code Java Basics - Anfänger-Themen 8
F uralter Java Code Java Basics - Anfänger-Themen 3
L Library nötig, obwohl nicht in Java-Code verwendet Java Basics - Anfänger-Themen 4
N Mac - Java Code aus dem Forum kopieren Java Basics - Anfänger-Themen 12
J VB Code mit Java ausführen lassen? Java Basics - Anfänger-Themen 2
W Java-Code auf Konsole ausgeben - Wie? Java Basics - Anfänger-Themen 10
K Java Code rechnen Java Basics - Anfänger-Themen 7
S Hilfe - java.lang.RuntimeException: Uncompilable source code - incompatible types Java Basics - Anfänger-Themen 10
A Stück Java code im laufenden Betrieb einlesen und ausführen Java Basics - Anfänger-Themen 9
V Vom Aktivitätsdiagramm zum Java-Code Java Basics - Anfänger-Themen 12
saxman Java Source Code Download Java Basics - Anfänger-Themen 2
H Hilfe bei Java Code Java Basics - Anfänger-Themen 3
X Objektorientierte Java Programmierung - 3 Fragen zum Code Java Basics - Anfänger-Themen 5
astralarse JNI: Echt(!) nativen Code in Java ausführen? Java Basics - Anfänger-Themen 6
C Bäume in Java. Code funktioniert nicht Java Basics - Anfänger-Themen 12
zilti Externen Java-Code laden Java Basics - Anfänger-Themen 3
G Java Code -> RTF Java Basics - Anfänger-Themen 6
G source code von Java classes Java Basics - Anfänger-Themen 12
G Jar-File erzuegen, das Code a verschiedenen Java Versionen? Java Basics - Anfänger-Themen 4
D Probleme bei Code Portierung von C# nach Java [Gelöst] Java Basics - Anfänger-Themen 4
L UML in Java-Code Java Basics - Anfänger-Themen 5
J Java-Code in UML 2.0 Java Basics - Anfänger-Themen 38
D Java Code verbessern? Java Basics - Anfänger-Themen 8
B Java 1.0 Code in NetBeans IDE 5.0 ??? Java Basics - Anfänger-Themen 4
M Benutzung von fremden Java-Code mit Eclipse Java Basics - Anfänger-Themen 3
M Source Code von java.util.SubList Java Basics - Anfänger-Themen 2
G PHP Code -> Java Code Java Basics - Anfänger-Themen 6
M Aus WSDL Java-Code generieren. Java Basics - Anfänger-Themen 1
C Problem mit Code aus "Sprechen Sie Java" Java Basics - Anfänger-Themen 13
D HTML code in java generieren. Java Basics - Anfänger-Themen 6
S Java Compiler? oder doch der Code? Java Basics - Anfänger-Themen 6
F Fehler im Java Code, hilfe? Java Basics - Anfänger-Themen 9
A aus Java-Code eine jar-Datei ausführen Java Basics - Anfänger-Themen 8
B Code von Java-Funktionen einsehen Java Basics - Anfänger-Themen 2
M String als Java-Code ausführen Java Basics - Anfänger-Themen 4
B Wie funktioniert die implementierung von c code in Java? Java Basics - Anfänger-Themen 7
H .java Dateien in Eclipse einbinden und ausführen Java Basics - Anfänger-Themen 1
onlyxlia Schlüsselworte Was meint man mit "einen Typ" in Java erstellen? Java Basics - Anfänger-Themen 2
O Java Kara geschweifte Klammern Java Basics - Anfänger-Themen 2
richis-fragen Mausrad logitech kann links und rechts klick wie in java abragen. Java Basics - Anfänger-Themen 15
XWing Java Klssenproblem Java Basics - Anfänger-Themen 4
R Umgebungsvariable java -cp gibt immer Java-Hilfe... Java Basics - Anfänger-Themen 3
farbenlos Csv Datei in Java einlesen Java Basics - Anfänger-Themen 18
F TableModelListener: java.lang.ArrayIndexOutOfBoundsException: 132 Java Basics - Anfänger-Themen 3
G Java 8 - Support-Ende Java Basics - Anfänger-Themen 7
T Java Weihnachtsbaum + Rahmen Java Basics - Anfänger-Themen 1
N Will mit Java anfangen Java Basics - Anfänger-Themen 13
Ü Java Array - Buchstaben als Zahlen ausgeben Java Basics - Anfänger-Themen 22
M Java Iterator Verständnisfrage Java Basics - Anfänger-Themen 6
M Java Mail Programm Java Basics - Anfänger-Themen 4
Sniper1000 Java 391 für Windows Java Basics - Anfänger-Themen 37
J Java long- in int-Variable umwandeln Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben