[C/C++] Bejeweled Bot - Farberkennung

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von bonsai, 25. Juli 2011 .

  1. 25. Juli 2011
    Zuletzt von einem Moderator bearbeitet: 14. April 2017
    Bejeweled Bot - Farberkennung

    Hey.

    Ich habe die letzten Tage mal aus Langeweile versucht einen Bot für das Spiel 'bejeweled' zu proggen.
    Der Bot läuft auch relativ gut, aber ich habe immernoch ein großes Problem mit der Farberkennung.
    Der Rest vom Bot läuft perfekt, aber er erkennt nicht immer alle Steine 100%.

    Hier mal ein Beispiel, wie die Steine aussehen könnten:
    Bild

    So ermittle ich mir momentan die Farbe:
    Code:
     // RGB Kodierung des Pixels holen
     COLORREF c = GetPixel(dc, x, y);
    
     cR = GetRValue(c);
     cG = GetGValue(c);
     cB = GetBValue(c);
    Anhand des RGB Farbcodes ordne ich dann die Farben zu.
    Allerdings gibt es halt große Überschneidungen und daher auch Fehl-Erkennungen.

    Das große Problem:
    => Die Position der Steine kann innerhalb der 8x8 Matrix um wenige Pixel variiren.
    - Der Stein in der linken Ecke kann so zum Beispiel 1 Pixel höher liegen als der Stein in der rechten Ecke.
    - Das macht es für mich unglaublich schwer die Farben richtig zu ermitteln.
    => Es gibt Bonussteine, die zwar auch die normale Farbe haben, aber zusätzlich noch glänzen.
    - Diese Steine haben an einer zufälligen Position ein helles 'Leuchten'
    - Dieses 'Leuchten' müsste ich natürlich auch i-wie erkennen und trotzdem die richtige Farbe ermitteln.

    Daher nun meine Frage:
    Wie könnte ich die Farberkennung so umschreiben, dass er die Steine 100% richtig erkennt?
     
  2. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Wenn du nicht nur ein Pixel nimmst sonst 5 ?
    Code:
    COLORREF c = GetPixel(dc, x+1, y+1);
    
     cR = GetRValue(c);
     cG = GetGValue(c);
     cB = GetBValue(c);
    COLORREF c1 = GetPixel(dc, x-1, y-1);
    
     cR = GetRValue(c);
     cG = GetGValue(c);
     cB = GetBValue(c);
    COLORREF c2 = GetPixel(dc, x+1, y-1);
    
     cR = GetRValue(c);
     cG = GetGValue(c);
     cB = GetBValue(c);
    COLORREF c3 = GetPixel(dc, x-1, y+1);
    
     cR = GetRValue(c);
     cG = GetGValue(c);
     cB = GetBValue(c);
    COLORREF c4 = GetPixel(dc, x, y);
    
     cR = GetRValue(c);
     cG = GetGValue(c);
     cB = GetBValue(c);
    
    Musst spontan auch noch an OpenCV denken vllt bieten die dir deine gewünschte Funktion
     
  3. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Habe ich bereits probiert.

    Wüsste aber nicht was mir das bringen soll.
    Braucht 4x mehr Zeit pro Stein (Auslesen und Vergleichen der Farbe) und liefert mir 5 RGB-codes.
    Aber was soll ich dann mit diesen 5 RGB codes anfangen?

    Wenn ich aus diesen 5 jeweils den Durchschnitt berechnen würde, dann hätte ich am Ende
    noch ungenauere Werte, weil ja durch diese Methode auch zufällig 4x das "falsche" Pixel kommen kann.
     
  4. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Das einzige was mir noch einfallen würde:

    Bestimmte Farb Spektren den Grundfarben zuzuordnen.

    zum Beispiel: FF4500 bis FF0000 = red

    Ich hoffe du verstehst wie ich das meine? Dann nimmst du halt immer ziemlich Mittig die Pixel.
    Matcht den RGB Code mit ner Tabelle wo er halt die RGB Codes den Grundfarben zuordnet und "fertig".
     
  5. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Das ist im Prinzip genau das was ich gerade mache.

    Aber bei dieser Methode überschneiden sich einige Farben:
    - hellblau, dunkelblau
    - weiß und gelb
    - orange und rot

    Die Farben überschneiden sich halt leider auf einigen Pixeln.
    Das liegt halt daran, dass die Steine auf Ihrer Position einige Pixel variiren können.
     
  6. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Dann musst du halt die Grenzen der Codes ausloten und diese selber matchen. Mehr als eingrenzen in der Farbtabelle kannst du da nicht. Also mir würd da zumindest grad nichts einfallen.

    Oder wie oben schon gesagt wurde, aus 4 Punkten die Farben nehmen und wenn er aus allen 4 Codes die gleiche Grundfarbe heraus bekommt ist es bestimmt. Wenn 3 von 4 dann ist es auch eindeutig, wenn 2 von 4 wird verworfen ( und vielleicht nochmal an 4 anderen Punkten gemessen ).
     
  7. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Hm.. das ist vielleicht noch eine Idee.

    Ich bin grad dabei mir zu testzwecken eine Art 'overlay' zu basteln.
    Das leg ich dann über die 8x8 Matrix vom Spielfeld und lasse mir vom bot anzeigen
    welches Pixel er gerade scannt. Vielleicht finde ich dadurch dann die optimale Position
    für den Scan.

    Aber auf jeden Fall einen Versuch wert, mit den 5 Pixeln und dann jedes einzeln vergleichen.
    Mal sehen was dann am Ende so dabei rauskommt...

    Muss jetzt auf jeden Fall erstmal mit dem Overlay fertig werden und vielleicht bringt mich
    das schon ein Stück weiter.
     
  8. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Ist es nicht einfacher den Wert aus dem Speicher zu holen? So weißt du doch dann 100%ig wo sich welcher Stein in der 8x8 matrix befindet.

    Oder WILLST du es über die Farben herausfinden wo welcher Stein liegt?
     
  9. 25. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Wie die Erkennung am Ende funktioniert ist mir egal.
    Wenn ich den Wert im Speicher finden kann, würd ich das natürlich auch so machen.

    Ich hab es ganz am Anfang mal auf diesem Weg probiert und konnte leider keine
    Werte für die Position der Steine finden.

    Kannst mir ja mal ne PN schicken, falls du dich damit auskennst, um es mir kurz zu erklären.
     
  10. 26. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Nachdem ich jetzt die gesamte Erkennung der Farben umgeschrieben habe, schafft es der Bot
    nun endlich alle Steine richtig zu erkennen. Einzige Ausnahme ist momentan ein Bonusstein,
    welcher die gleiche Farbe hat, wie einer der normalen Steine, aber eine andere Form.

    Für diesen einen Stein muss ich noch eine Abfrage anhand der Anzahl der übrigen Steine einbauen,
    aber dann sollte ich es geschafft haben.

    Zur Farberkennung:
    - Ich habe mir ein Overlay erstellt, welches ich über die 8x8 Matrix lege (transparent)
    - Innerhalb der 8x8 Matrix scanne ich pro Feld/Stein je 5 Pixel
    - den RGB Code dieser 5 Pixel vergleiche ich mit meiner Datenbank
    - die Werte in der Datenbank hab ich per Script und pro Farbe eingescannt
    - wenn mind. 2 der 5 pixel, die gleiche Farbe ergeben, zähle ich es als positive Erkennung

    Falls noch jemand einen Tipp hat, wie ich die Position der Steine im Speicher finden kann,
    würde ich mir das gern auch noch ansehen. Dürfte auf jeden Fall um einiges schneller
    gehen als der Farbscan.
     
  11. 26. Juli 2011
    AW: Bejeweled Bot - Farberkennung

    Dürfte mit CheatEngine am schnellsten gehen, einfach das Game nach jeder Position- bzw. Steinänderung, im Speicher, nach änderungen scannen um die Spiefeldmatrix einzugrenzen bzw. komplett zu bestimmen. (Tipp: Sie könnte sich wohl in der nähe des Speicherbereichs der Spielpunkte befinden.)
    Eventuell sind die Spielfelddaten auch dynamisch Verwaltet, dann müsste man die Pointeraddresse bzw. die relative Addresse zum Modul bestimmen.

    Mfg Rushh0ur
     
  12. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.