Reversi Algorithmus Probleme

Wunderschönen Guten Tag,

ich bin dabei eine App in Swift zu programmieren und stehe absolut auf dem Schlauch. Ich möchte das Spiel Reversi/Othello generieren und scheitere gerade am Algorithmus zum Umdrehen der Steine.

Ich versuche es mal in Javaquellcode (Java und Swift sind von der Syntax nicht so übel anders, aber ist vielleicht besser so) darzulegen.
Also das Startfeld sieht so aus:

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 1 2 0 0 0
0 0 0 2 1 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

Nun lege ich einen Stein dazu:

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 1 2 1 0 0
0 0 0 2 1 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

Auf Punkt 5/3 habe ich gesetzt und damit muss Sein 4/3 umgeklappt werden, weil er sich zwischen 3/3 und 5/3 befindet. 1 und 2 sind hier die Spielernummern und 0 sind leere Felder.

Nun habe ich einen Algorithmus gebastelt, welcher in alle acht Richtungen schießt und überprüft, wie viele Steine er umlegen muss.
Dazu habe ich diese beiden Arrays:

        int[] yDirArr = {-1, 0, 1}```

Die ich also in einer doppelten for-each Schleife durchlaufen lasse.

Ich weiß nicht, ob mein Konzept einfach nur ungünstig ist, oder ob ich auf dem Schlauch stehe, aber er gibt mir nun folgende sechs Dinge aus:
[ul]
[li]int x: Die x-Position des Steins, der hinzugesetzt wurde.
[/li][li]int y: Die y-Position des Steins, der hinzugesetzt wurde.
[/li][li]int currX: Die x-Position des letzten umlegbaren Steins. 
[/li][li]int currY: Die y-Position des letzten umlegbaren Steins. 
[/li][li]int dirX: Die x-Richtung in die er gerade prüft.
[/li][li]int dirY: Die yx-Richtung in die er gerade prüft.
[/li][/ul]

Das heißt also, es wird alles von Position (x,y) in Richtung (dirX,dirY) bis hin zu (currX,currY) umgelegt.
Das Umlegen mache ich durch diese einfache Zeile (ruft eine passende Methode auf):

setStone(currPlayer, x:a, y:b)



Nun mein Problem: Ich bin schlicht weg gerade nicht fähig es zu schaffen der Programmiersprache zu sagen, dass er genau diese Steine drehen soll. Es scheitert an der for-Schleife an folgender Sache:

for var b=currY+1;b<=x;b++ {
for var a=currX+1;a<=y;a++ {
setStone(currPlayer, x:a, y:b)
}
}



Bedingt durch die Tatsache, dass die Steine ja in alle acht Richtungen geprüft werden, ist die Abschlussbedingung `b<=x` und `a<=y` hinfällig, weil es ja, je nach Richtung sowohl größergleich, als auch kleinergleich sein kann.

Kann mir jemand sagen, wie ich dieses Problem lösen kann?

Die Lösung ist wahrscheinlich näher als ich denken kann ...

Ohne das jetzt alles im Detail gelesen zu haben:
-vom gesetztes Stein aus musst du in jeder Richtung ohne etwas zu tun einmal hin laufen (bis Du auf ein Feld ohne fremden Stein oder den Rand triffst.)
-Wenn Du auf einen eigenen Stein gestoßen bist kannst Du “zurück” laufen und dabei alle Steine unterwegs umdrehen.

bye
TT

Ich habe es mal schnell in Java runtergetippt, wie ich mir das vorstelle.```import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class ReversyTest {
enum Spieler {
LEER(" ") {
@Override
public Spieler gibAnderen() {
return LEER;
}
},
EINS(“1”) {
@Override
public Spieler gibAnderen() {
return Spieler.ZWEI;
}
},
ZWEI(“2”) {
@Override
public Spieler gibAnderen() {
return Spieler.EINS;
}
};
private String display;

    Spieler(String display) {
        this.display = display;
    }

    public abstract Spieler gibAnderen();

    public static Spieler fürDisplay(String display) {
        System.out.println(display);
        Spieler[] values = values();
        for (Spieler spieler : values) {
            System.out.println(spieler.display);
            if (spieler.display.equals(display.trim()))
                return spieler;
        }
        return LEER;
    }
}

static enum Richtung {
    HOCH {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return i < 8 ? Feld.RAND : felder.get(i - 8);
        }
    },
    LINKS {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return 0 == i % 8 ? Feld.RAND : felder.get(i - 1);
        }
    },
    RUNTER {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return felder.size() - 8 > i ? felder.get(i + 8) : Feld.RAND;
        }

    },
    RECHTS {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return 7 == i % 8 ? Feld.RAND : felder.get(i + 1);
        }
    },
    HOCH_LINKS {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return (i > 9 && 0 != i % 8) ? felder.get(i - 9) : Feld.RAND;
        }

    },
    RUNTER_LINKS {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return (felder.size() - 9 > i && 0 != i % 8) ? felder.get(i + 7) : Feld.RAND;
        }
    },
    RUNTER_RECHTS {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return (felder.size() - 8 > i && 7 != i % 8) ? felder.get(i + 9) : Feld.RAND;
        }
    },
    HOCH_RECHTS {
        public Feld findeNachbar(List<Feld> felder, int i) {
            return (i > 7 && 7 != i % 8) ? felder.get(i - 7) : Feld.RAND;
        }
    };
    public abstract Feld findeNachbar(List<Feld> felder, int i);
}

static class Feld {
    static int idCounter = 0;
    static final Feld RAND = new Feld();

    private final int id = idCounter++;
    private final Map<Richtung, Feld> nachbarn = new HashMap<>();

    private Spieler owner = Spieler.LEER;

    public void neuerNachbar(Richtung richtung, Feld nachbar) {
        nachbarn.put(richtung, nachbar);
    }

    public Feld gibNachbar(Richtung richtung) {
        Feld nachbar = nachbarn.get(richtung);
        System.out.print(": " + id + "->" + nachbar.id);
        return nachbar;
    }

    public boolean neuerBesitzer(Spieler spieler) {
        boolean istWechsel = spieler.equals(owner.gibAnderen());
        System.out.print(" " + owner.gibAnderen() + "->" + spieler + "=" + istWechsel);

        owner = istWechsel ? spieler : owner;
        return istWechsel;
    }
}

public static void main(String[] args) {
    List<Feld> felder = new ArrayList<>();
    for (int i = 0; i < 64; i++) {
        felder.add(new Feld());
    }
    for (int i = 0; i < 64; i++) {
        Richtung[] richtungen = Richtung.values();
        for (Richtung richtung : richtungen) {
            felder.get(i).neuerNachbar(richtung, richtung.findeNachbar(felder, i));
        }
    }
    felder.get(3 * 8 + 3).owner = (Spieler.EINS);
    felder.get(4 * 8 + 4).owner = (Spieler.EINS);
    felder.get(4 * 8 + 3).owner = (Spieler.ZWEI);
    felder.get(3 * 8 + 4).owner = (Spieler.ZWEI);

    TableModel viewModel = new DefaultTableModel(8, 8) {
        @Override
        public Object getValueAt(int row, int column) {
            return felder.get(row * 8 + column).owner.display;
        }

        @Override
        public void setValueAt(Object aValue, int row, int column) {
            Feld feld = felder.get(row * 8 + column);
            Spieler spieler = Spieler.fürDisplay((String) aValue);
            übernimmNachbarn(feld, spieler);
        }

        private void übernimmNachbarn(Feld feld, Spieler spieler) {
            boolean zugGültig = false;
            if (feld.owner.equals(Spieler.LEER)) {
                Richtung[] richtungen = Richtung.values();
                for (Richtung richtung : richtungen) {
                    boolean reiheÜbernommen = fülleBisNächstesEigenesFeld(feld, spieler, richtung);
                    zugGültig = zugGültig || reiheÜbernommen;
                }
                if (zugGültig)
                    feld.owner = (spieler);
                fireTableDataChanged();
            }
        }

        private boolean fülleBisNächstesEigenesFeld(Feld feld, Spieler spieler, Richtung richtung) {
            System.out.print(richtung);
            Feld nachbar = feld.gibNachbar(richtung);
            List<Feld> übernameKandidaten = new ArrayList<>();
            while (nachbar.owner.equals(spieler.gibAnderen())) {
                System.out.print(" check " + nachbar.id);
                übernameKandidaten.add(nachbar);
                nachbar = nachbar.gibNachbar(richtung);
            }
            boolean zugGültig = false;
            if (!übernameKandidaten.isEmpty() && nachbar.owner.equals(spieler)) {
                zugGültig = true;
                for (Feld übernahmeFeld : übernameKandidaten) {
                    übernahmeFeld.neuerBesitzer(spieler);
                }
                System.out.print(" reihe übernommen");
            }
            System.out.println();
            return zugGültig;
        }
    };
    JTable jTable = new JTable(viewModel);
    jTable.setColumnSelectionAllowed(false);
    jTable.setRowSelectionAllowed(false);
    JOptionPane.showMessageDialog(null, jTable);
}

}```Steine setzten geht durch Zahl eintippen.
Falsche Züge werden abgelehnt, aber es wird nicht gecheckt welcher Spieler dran ist.
Manchmal macht zeigt die Tabelle Spielernummern in leeren Feldern, wer weis warum darf mich gerne berichtigen…

bye
TT

Hallo,

danke für Deine Hilfe. Habe es aufgrund einiger Recherchen und Deinem Quellcode schaffen können! Ist auch schon reichlich spät. :stuck_out_tongue:
Ich musste nur noch mit ein paar outOfRangeFehlern kämpfen, die hier auftraten.

Gruß
Lukas