Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

29.04.2009, 20:53

Frage zu DWORD und &= |=

Abend zusammen!

Ich habe in meinem Spiel (mal wieder :lol: ) ein Problem (ich glaub, es vergeht kaum ein Tag ohne...).
Und zwar möchte ich den Spielstatus (ob jetzt der PC spielt, der Spieler spielt und was der Spieler so macht) in einem DWORD Wert speichern wie man es z.B. von den DX-Flags kennt.
Jetzt hab ich mir einen kleinen Code zusammengebaut, aber er läuft nicht.
Durchs Debuggen konnte ich das Problem lokalisieren:
Wenn eine Aktion getan ist, soll er das entsprechende Flag entfernen und neue setzen. Nur das entfernen klappt nicht.
Hier der Code (*.h und *.cpp zusammen ^^)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define COMPUTER_PLAYS         0
#define PLAYER_PLAYS           1
#define COMPUTER_WON           2
#define PLAYER_WON             3
#define PLAYER_WAITS           4
#define PLAYER_SELECTED_FIGUR 5

DWORD State;

// Anfang cpp Datei

// Startwerte setzen (in der Initialisierungsfunktion)

State |= PLAYER_PLAYS;
State |= PLAYER_WAITS;
// [...]

// Klickbehandlungsfunktion, Werte ändern

State &= PLAYER_WAITS; // <--- Hier ist der Fehler

State |= PLAYER_SELECTED_FIGUR;
//Überprüfen ob richtig gesetzt wurde (mit dem Debugger)

bool ask1 = false, ask2 = false, ask3 = false;
if(m_pState & PLAYER_WAITS)ask1 = true;
if(m_pState & PLAYER_SELECTED_FIGUR)ask2 = true;
if(m_pState & COMPUTER_PLAYS)ask3 = true;


Nachdem ich herausgefunden habe, dass das Entfernen scheinbar nicht richtig funktioniert, hab ich die Überprüfung (mit ask :lol: ) hinzugefügt und im Debugger festgestellt, dass:
- PLAYER_WAITS gesetzt ist (falsch)
- PLAYER_SELECTED_FIGUR gesetzt ist (richtig)
- COMPUTER_PLAYS nicht gesetzt ist (richtig)

Hab ich einen Pragrammierfehler gemacht (ist &= falsch?) oder ist das einfach nur ein Denkfehler? Hoffe (und glaube) dass mir jmd. helfen kann.

mfg mm

PS: Ich weiß, dass es (wahrschienlich) einfachere und vll. auch bessere Methoden gibt, aber ich finde DWORD halt interessant :D

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

2

29.04.2009, 21:10

das ist durchaus eine gute idee! nun musst du das aber als setzen von bits sehen:

Quellcode

1
2
3
4
5
6
7
0000 0001 -> deizmal 1 -> z. b. PLAYER_PLAYS
0000 0010 -> dezimal 2 -> z. b. COMPUTER_PLAYS
0000 0100 -> dezimal 4 -> z. b. COMPUTER_WON

das kann man einzeln setzen:

PLAYER_PLAYS | COMPUTER_WON -> 0000 0101


wenn du 1,2,3 nimmst geht das nicht denn da sind bits doppelt!

Quellcode

1
2
3
4
5
0000 0001 -> dezimal 1 -> z. b. PLAYER_PLAYS
0000 0010 -> dezimal 2 -> z. b. COMPUTER_PLAYS
0000 0011 -> dezimal 3 -> z. b. COMPUTER_WON

PLAYER_PLAYS | COMPUTER_WON -> 0000 0011


aber aus dem code kann man nicht eineindeutig lesen, das heisst wenn man die flags nachschaut COMPUTER_WON.

daher: immer nur zahlen mit einem einzelnen vergeben mit nehmen, und das sind alle zahlen zur basis 2! 1,2,4,8,16,32,64,128,...

EDIT: ein paar fehler korrigiert sry ;)

3

30.04.2009, 15:42

Danke für deine Antwort, das hat das ganze etwas klarer gemacht (funktioniert leider noch nicht...). Aber ich hab trotzdem noch eine Frage zu | und &. Erstmal ein Codeschnipsel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
dmResult CGame::Init()
{
    m_State = PLAYER_PLAYS | PLAYER_WAITS;
    if(m_State & PLAYER_WAITS)INFO("Spieler wartet...");
    if(m_State & PLAYER_PLAYS)INFO("Spieler ist am Zug...");
    if(m_State & PLAYER_SELECTED_FIGUR)INFO("Spieler hat Figur ausgesucht...");
    if(m_State & COMPUTER_PLAYS)INFO("PC spielt...");

    INFO("Und jetzt die Ver&auml;nderungen!");
    m_State &= PLAYER_PLAYS;  // Das sollte doch PLAYER_PLAYS loeschen, oder?

    if(m_State & PLAYER_WAITS)INFO("Spieler wartet...");
    if(m_State & PLAYER_PLAYS)INFO("Spieler ist am Zug...");
    if(m_State & PLAYER_SELECTED_FIGUR)INFO("Spieler hat Figur ausgesucht...");
    if(m_State & COMPUTER_PLAYS)INFO("PC spielt...");
    
    
        // Der Rest gehört nur zum Spiel, nicht zur Frage :D

    current.x = 0;
    current.y = 0;
    InitLevel();
    PostQuitMessage(0); // <- Zu Testzwecken

    return R_OK;
}


INFO() ist eine Logbuchfunktion, wie man sich ja schon denken kann :D
Jetzt noch der geänderte Code der Definierungen:

C-/C++-Quelltext

1
2
3
4
5
6
#define COMPUTER_PLAYS         2
#define PLAYER_PLAYS           4
#define COMPUTER_WON           8
#define PLAYER_WON             16
#define PLAYER_WAITS           32
#define PLAYER_SELECTED_FIGUR  64

Im Logbuch steht dann:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
INFO:Logbuch wird initialisiert...
INFO:Fenster wird erstellt...
INFO:Intro wird gestartet...
INFO:Betrete die Nachrichtenschleife...
INFO:Menue wird initialisiert...
INFO:Spiel wird initialisiert...
INFO:Spieler wartet...
INFO:Spieler ist am Zug...
INFO:Und jetzt die Veränderungen!
INFO:Spieler ist am Zug...
INFO:Fenster wird zerstört...

Das heißt: Der Flag, den ich eigentlich löschen wollte ist jetzt der einzige, und das verstehe ich irgendwie nicht so ganz...
Also: Was hat es jetzt mit &=, |= &, | so auf sich?

mfg mm

DasBlub

Alter Hase

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

4

30.04.2009, 15:47

löschen macht man so:

C-/C++-Quelltext

1
m_State |= ~PLAYER_PLAYS;

5

30.04.2009, 15:53

Zitat von »"DasBlub"«

löschen macht man so:

C-/C++-Quelltext

1
m_State |= ~PLAYER_PLAYS;

Funktioniert nicht, wenn ich das so mache, sagt das Logbuch bei der zweiten Abfrage: Alle Flags aktiv
Ich hab mal ne andere Kombination ausprobiert:

C-/C++-Quelltext

1
m_State &= ~PLAYER_PLAYS;


So funktioniert es.
Also ist das jetzt so korrekt?

mfg mm

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

6

30.04.2009, 16:23

Überleg dir, was die Ausdrücke bedeuten und du kannst es dir ganz leicht selbst überlegen ;). Aber ja, so müsste es stimmen und dasBlub hat sich wahrscheinlich nur vertippt.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

DasBlub

Alter Hase

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

7

30.04.2009, 16:26

Zitat von »"Nox"«

Aber ja, so müsste es stimmen und dasBlub hat sich wahrscheinlich nur vertippt.


ja, tut mir leid :oops:

8

30.04.2009, 16:52

Juhuu, jetzt funktioniert es!
Danke Leute!

Werbeanzeige