Goziqi AI -Algorithmus ist auch ein typischer AI -Algorithmus. Einige Schach -AI -Algorithmen können als Referenz verwendet werden. Das Folgende ist der Java -Implementierungscode.
Schachbrett abstrakte Schnittstelle
importieren java.util.list; public interface iChessboard {// Erhalten Sie die maximale horizontale Koordinate des Board public int getMaxx (); // Maximale vertikale Koordinate public int getmaxy (); // Erhalten Sie alle aktuellen leeren Punkte, und diese Punkte können nur Schach öffentliche Liste <Point> getFreepoint () spielen. }Schachklassen -Implementierung
// Der Schachklassenpunkt {// Dies ist die Aufführung, die auf public int x eingestellt ist; öffentlich int y; public int getX () {return x; } public point setx (int x) {this.x = x; gib dies zurück; } public int gety () {return y; } public point sety (int y) {this.y = y; gib dies zurück; } public point (int x, int y) {this.x = x; this.y = y; } @Override public int HashCode () {return x + y; } @Override public boolean Equals (Objekt obj) {if (this == obj) return true; Punkt other = (point) obj; if (x! = other.x) return false; if (y! = other.y) return false; zurückkehren; }} Spieler abstrakte Schnittstelle
importieren java.util.list; public interface iPlayer {// Der nächste Schritt besteht darin, den Schachbrett -Satz zu übergeben, den der Gegner bereits öffentliche void Run festgelegt hat (List <Point> Enemypoint, Point Point); öffentlicher boolean Haswin (); Public Void SetChessboard (Ichessboard -Schachbrett); öffentliche Liste <Point> getMypoint (); } Spieler grundlegender abstrakter Klasse
Import Java.util.ArrayList; importieren java.util.list; public abstract Class Baseplayer implementiert iPlayer {// Das Schachstück, das ich geschützte Liste <Point> mypoints = new ArrayList <Point> (200) platziert habe; // Das Schachbrett geschützte Ichessboard -Schachbrett; // Die maximalen horizontalen und vertikalen Koordinaten der Karte sind int maxx geschützt. geschützte int maxy; // Alle leeren Schachsteine geschützt List <Point> Allfreepoint; @Override Public Final List <Point> getMyPoint () {return myPoints; } @Override public void setChessboard (iChessboard Schachbrett) {this.chessboard = Schachbrett; Allfreepoint = chessboard.getFreepoint (); maxx = chessboard.getMaxx (); maxy = chessboard.getMaxy (); mypoints.clear (); } private endgültige Punkt temp = neuer Punkt (0, 0); // Gewinne ich public Final Boolean Haswin () {if (mypoints.size () <5) {return false; } Point point = mypoints.get (mypoints.size ()-1); int count = 1; int x = point.getX (), y = point.gety (); // horizontal- temp.setx (x) .sety (y); while (mypoints.contains (temp.setx (temp.getX ()-1)) && temp.getX ()> = 0 && count <5) {count ++; } if (count> = 5) {return true; } temp.setX (x) .sety (y); while (mypoints.contains (temp.setx (temp.getX ()-1)) && temp.getX ()> = 0 && count <5) {count ++; } if (count> = 5) {return true; } temp.setX (x) .sety (y); while (mypoints.contains (temp.setx (temp.getX ()+1)) && temp.getX () <maxx && count <5) {count ++; } if (count> = 5) {return true; } // senkrecht | count = 1; temp.setx (x) .sety (y); while (mypoints.contains (temp.sety (temp.gety ()-1)) && temp.gety ()> = 0) {count ++; } if (count> = 5) {return true; } temp.setX (x) .sety (y); while (mypoints.contains (temp.sety (temp.gety ()-1)) && temp.gety ()> = 0) {count ++; } if (count> = 5) {return true; } temp.setX (x) .sety (y); while (mypoints.contains (temp.sety (temp.gety ()+1)) && temp.gety () <maxy && count <5) {count ++; } if (count> = 5) {return true; } // leiten oblique/count = 1; temp.setx (x) .sety (y); while (mypoints.contains (temp.setx (temp.getX ()-1) .sety (temp.gety ()+1)) && temp.getX ()> = 0 && temp.gety () <maxy) {count ++; } if (count> = 5) {return true; } temp.setX (x) .sety (y); while (mypoints.contains (temp.setx (temp.getX ()+1) .sety (temp.gety ()-1)) && temp.getX () <maxx && temp.gety ()> = 0 && count <6) {count ++; } if (count> = 5) {return true; } // Backslash/count = 1; temp.setx (x) .sety (y); while (mypoints.contains (temp.setx (temp.getX ()-1) .sety (temp.gety ()-1)) && temp.getX ()> = 0 && temp.gety ()> = 0) {count ++; } if (count> = 5) {return true; } temp.setX (x) .sety (y); while (mypoints.contains (temp.setx (temp.getX ()+1) .sety (temp.gety ()+1)) && temp.getX () <maxx && temp.gety () <maxy && count <5) {count ++; } if (count> = 5) {return true; } return false; }} Computer KI -Implementierung
Import Java.util.ArrayList; Import Java.util.Collections; import Java.util.hashMap; importieren java.util.list; import Java.util.map; // Die Kernklasse des Algorithmus ist die Hauptidee des Algorithmus in drei Schritte unterteilt. // Der erste Schritt: Zyklisch die Punktzahl für sich selbst und die andere Partei (um innerhalb eines bestimmten Bereichs eine Punktzahl zu erzielen) nach der aktuellen Situation beider Parteien und die Änderungen in der Situation beurteilen, die dieses Stück bringen kann, wie z. Nennen Sie es halb leben 4) usw.), einschließlich des Feindes und unserer Seite. // Schritt 3: Sortieren Sie das vorherige Ergebnis nach den vom Benutzer angegebenen Regeln und wählen Sie Sub -Subjective- und Defensive Formen (es gibt Regeln für offensive und defensive Formen) öffentliche Klasse Basicomputererai erweitert Basisplayer (// vier Richtungen, horizontal -, vertikal | , vorwärts-Slant /, Rückverfolgung / Private statische endgültige int heng = 0; privates statisches Final int zhong = 1; private statische endgültige int zheng_xie = 2; private statische endgültige int fan_xie = 3; // Front -to -Back Private Static Final Boolean Forward = True; privates statisches finales boolean rückwärts = falsch; // Zeigen Sie das Analyseergebnis an. Unabhängig davon, ob der aktuelle Punkt Zwei-End-Pass (lebendig) oder nur ein Endpass (halbalive) ist, wird der blockierte Schach-Analyse-Prozess automatisch blockiert, nicht als Schachstück, das private statische endgültige int lebe = 1; private statische endgültige int half_alive = 0; // Private statische endgültige int tote = -1; // Berechnen Sie den Bereich, zu großer Bereich hat Leistungsprobleme private Klasse CalcuTerange {int xstart, ystart, xstop, ystop; private calcuTerange (int xstart, int ystart, int xstop, int ystop) {this.xstart = xstart; this.ystart = ystart; this.xstop = xstop; this.yStop = yStop; }} // Begrenzen Sie den Computerberechnungsbereich. Wenn die gesamte Berechnungsleistung der Schachbrett zu schlecht ist, basiert sie derzeit basierend auf dem Grenzwert aller in Gebrauchszeiten eingestellten Schachstücke. Es ist derzeit 1 privates statisches Final int range_step = 1; CalcuTerange currange = new calcuTerange (0, 0, 0, 0); private void initrange (list <Point> couter, list <Point> Menschen) {currentRange.xstart = humanans.get (0) .getX ()-range_step; CurrentRange.ystart = humanans.get (0) .Gety ()-range_step; currentRange.xstop = humanans.get (0) .getX ()+range_step; currentRange.ystop = humanans.get (0) .gety ()+range_step; für (Punktpunkt: Menschen) {if (point.getX ()-range_step <currentRange.xstart) {currentRange.xstart = point.getX ()-range_step; } else if (point.getX ()+range_step> currentRange.xstop) {currentRange.xstop = point.getX ()+range_step; } if (point.gety ()-Bereich_Step <currentRange.ystart) {currentRange.ystart = point.gety ()-range_step; } else if (point.gety ()+range_step> currentRange.ystop) {currentRange.ystop = point.gety ()+range_step; }} für (Punktpunkt: Couter) {if (point.getX ()-range_step <currentRange.xstart) {currentRange.xstart = point.getX ()-Bereich_Step; } else if (point.getX ()+range_step> currentRange.xstop) {currentRange.xstop = point.getX ()+range_step; } if (point.gety ()-Bereich_Step <currentRange.ystart) {currentRange.ystart = point.gety ()-range_step; } else if (point.gety ()+range_step> currentRange.ystop) {currentRange.ystop = point.gety ()+range_step; }} // Wenn der Bereich erweitert wird und das Schachbrett überschreitet, entspricht er dem Schachbrett currange.xstart = currentRange.xstart <0? 0: currangerange.xstart; CurrentRange.YSTART = CurrentRange.yStart <0? 0: CurrentRange CurrentRange.YSTART = CurrentRange.yStart <0? 0: CurrentRange CurrentRange.xstop = currentRange.xstop> = maxx? maxx-1: currentRange.xstop; CurrentRange.ystop = currentRange.ystop> = maxy? Maxy-1: currentRange.ystem; } // Analysieren Sie die aktuelle Form der Eintragsmethode. Die Analyse ist insgesamt in drei Schritte unterteilt. Der dritte Schritt kann durch Unterklassen für Schwierigkeiten gesteuert werden. private point doanalysis (list <Point> couter, list <Point> Menschen) {if (humanans.size () == 1) {// Der erste Schritt gibt GetFirstpoint (Menschen) zurück; } // Initialisieren Sie den Berechnungsbereich initrange (Comuters, Menschen); // Die vorherigen Ergebnisse initanalysisResults () löschen; // Analyse starten, alle leeren Punkte scannen und den ersten Analyseergebnisspunkt BestPoint = Dofirstanalyse (Comuters, Menschen) bilden; if (BestPoint! Bestpoint zurückgeben; } // das erste Ergebnis analysieren und Ihren besten Punkt bester Punkt = doccomputerScondanalyse (computerfirstresults, computerscodresults) finden; if (BestPoint! Bestpoint zurückgeben; } computerFirstresults.clear (); System.gc (); // Analysieren Sie das erste Ergebnis und finden Sie den besten Punkt des Feindes Bestpoint = DohumanScondanalyse (Humanfirstresults, HumanSencodresults); if (Bestpoint! Bestpoint zurückgeben; } humanfirstresults.clear (); System.gc (); // Es wurde kein endgültiger Killpunkt gefunden, die dritte Ergebnisanalyse kehrte Dothirdanalysis zurück (); } // Der erste Schritt des Schachstücks erfordert keine komplizierten Berechnungen und wird basierend auf dem x -Wert des ersten Schritts des Schachstücks abgeschlossen. private point getFirstpoint (Liste <Point> Menschen) {point point = humanans.get (0); if (point.getX () == 0 || point.gety () == 0 || point.getX () == maxx && point.gety () == maxy) return neuer Punkt (maxx/2, maxy/2); sonst {return New Point (point.getX ()-1, point.gety ()); }} // private int debugx, debugy; // Verwenden Sie für Debug // Analyse starten, alle leeren Punkte scannen und das erste Analyseergebnis privates Punkt Dofirstanalyse (List <Point> Couters, Liste <Point> Menschen) {int size = allfreepoints.size (); Point computerpoint = null; Punkt HumanPoint = null; int x, y; FirstanalysisResult FirstanalysisResult; für (int i = 0; i <size; i ++) {computerpoint = allfreepoints.get (i); // Klicken Sie zuerst auf die X- und Y -Koordinaten, da das ursprüngliche Objekt während des Analyseprozesses x = computerpoint.getX () geändert wird. y = computerpoint.gety (); if (x <currentRange.xstart || x> currentRange.xstop || y <currentRange.yStart || y> currentRange.ystop) {Fortsetzung; } // if (x == debugx && y == debugy) {// system.out.println ("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS) {Weiter; System.out.println ("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS-ANSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS- = tryandcountResult (Comuters, Menschen, Computerpoint, Heng); computerpoint.setx (x) .sety (y); // antworte den ursprünglichen Wert des Punktes für die nächste Analyse, wenn (FirstanalysisResult! Wenn (FirstanalysisResult.count == 5) // gleich 5 bedeutet, dass Sie an diesem Punkt Schachstücke spielen können und sich mit 5 verbinden können. Wenn Sie gewinnen, werden Sie es nicht analysieren. Computerpoint zurückgeben; // Erfassen Sie das erste Analyseergebnis AddtOfirstanalyseResult (FirstanalysisResult, ComputerFirstresults); } // Die obigen Schritte in der "vertikalen Richtung" in der FirstanalysisResult = tryAndcountesult (Comuter, Menschen, Computerpoint, Zhong) wiederholen; computerpoint.setx (x) .sety (y); if (FirstanalysisResult! addtofirstanalysisResult (FirstanalysisResult, ComputerFirStresults); } // Schräg erster AnalyseResult = tryAndCoungResult (Comuters, Menschen, Computerpoint, zheng_xie); computerpoint.setx (x) .sety (y); if (FirstanalysisResult! addtofirstanalysisResult (FirstanalysisResult, ComputerFirStresults); } // Backside FirstanalysisResult = tryAndCoungResult (Comuter, Menschen, Computerpoint, fan_xie); computerpoint.setx (x) .sety (y); if (FirstanalysisResult! addtofirstanalysisResult (FirstanalysisResult, ComputerFirStresults); } // Analysieren Sie den Zustand dieses Stücks im Feind in der "horizontalen" Richtung, wie z. computerpoint.setx (x) .sety (y); if (FirstanalysisResult! addtofirstanalysisResult (FirstanalysisResult, Humanfirstresults); } // "Langzeit-perpendikulär" FirstanalysisResult = tryAndCoungResult (Menschen, Comuter, Computerpoint, Zhong); computerpoint.setx (x) .sety (y); if (FirstanalysisResult! addtofirstanalysisResult (FirstanalysisResult, Humanfirstresults); } // "Forward-Slant" FirstanalysisResult = tryAndCoungResult (Menschen, Comuters, Computerpoint, Zheng_xie); computerpoint.setx (x) .sety (y); if (FirstanalysisResult! addtofirstanalysisResult (FirstanalysisResult, Humanfirstresults); } // "Backslash" FirstanalysisResult = tryAndCoungResult (Menschen, Comuters, Computerpoint, Fan_xie); computerpoint.setx (x) .sety (y); if (FirstanalysisResult! addtofirstanalysisResult (FirstanalysisResult, Humanfirstresults); }} // Wenn es kein Gewinnstück gibt, muss die erste Analyse das Ergebnis der ersten Analyse nicht zurückgeben. } // In der zweiten Analyse werden das Ergebnis der ersten Formation analysiert. Das erste Analyseergebnis erzeugt bis zu vier FirstanalysisResult -Objekte (vier Feinde und einander). // Die vier Objekte sollten zu einem sencondanalysisResult -Objekt, privatem Point DocomputerScondanalyse (MAP <Punkt, Liste <FirstanalysisResult >> firstanalys, list <sencondanalyseResult> sencodresults) kombiniert werden. SencondanalysisResult sr = null; für (Punkt P: firStresults.Keyset ()) {sr = new sencondanalysisResult (p); list = firStresults.get (p); Für (FirstanAnysisResult Ergebnis: Liste) {if (result.count == 4) {if (result.alivestate == lebend) {// Nach der vorherigen Filterung schlossen beide Seiten den ultimativen Kill aus. Wenn es 4 gibt, machen Sie diesen Schritt und gewinnen Sie den nächsten Schritt. Ergebnis.Point; // Wenn es einen letzten Kill gibt, ist die erste Runde zurückgekehrt. In dieser Runde von 4 ist bereits ein gutes Stück, kehren Sie direkt zurück und analysieren Sie es nicht mehr} else {sr.halphalive4 ++; computer4HalFalives.add (SR); }} else if (result.count == 3) {if (result.alivestate == lebend) {sr.alive3 ++; if (sr.alive3 == 1) {computer3alives.add (sr); } else {computerDouble3alives.add (SR); }} else {sr.halphalive3 ++; computer3HalFalives.Add (SR); }} else {// semi-live 2 wurde in der ersten Stufe ausgeschlossen und nicht mehr sr.alive2 ++ verarbeitet; if (sr.alive2 == 1) {computer2alives.add (sr); } else {computerDouble2Alives.add (SR); }}}} sencodresults.add (SR); } // kein Leben 4 wurde gefunden; null zurückkehren; } // Diese Methode ist im Grunde dasselbe wie oben, aber für die Leistung ist es weniger Urteilsvermögen, trennt Menschen und Computer private Punkte DohumanScondanalyse (Karte <Punkt, list <FirstanalysisResult >> Firtresults, list <sencondanalysisUlte> sencodresults) {list <FirheFanAnalysisResult> list = nullesult> liste = nullesult> SencondanalysisResult sr = null; für (Punkt P: firStresults.Keyset ()) {sr = new sencondanalysisResult (p); list = firStresults.get (p); für (FirstanalysisResult Ergebnis: Liste) {if (result.count == 4) {if (result.alivestate == lebend) {Human4alives.add (sr); } else {sr.halphalive4 ++; Human4HalFalives.Add (SR); }} else if (result.count == 3) {if (result.alivestate == lebend) {sr.alive3 ++; if (sr.alive3 == 1) {human3alives.add (sr); } else {humandoulble3alives.add (sr); }} else {sr.halphalive3 ++; Human3HalFalives.Add (SR); }} else {sr.alive2 ++; if (sr.alive2 == 1) {human2alives.add (sr); } else {humandoulble2alives.add (SR); }}} sencodresults.add (SR); } // No Live 4 wurde zurückgegeben. Null; } private void schlaf (int minisekunden) {try {thread.sleep (minisekunde); } catch (InterruptedException e) {}} // Die dritte Analyse kann keiner Live 4 erstellen, doppelte Live -3 -Teile finden, wenn nicht, halb Live 4, wenn nicht. } System.gc (); Schlaf (300); Sammelns.sort (computerscodresults); System.gc (); // Ich bin kurz davor, 4 zu leben, und ich habe keine halblebenden 4 oder mehr, sodass ich nur die meisten Besten blockieren kann. if (am besten! = null) kehren am besten zurück; Sammlung.Sort (HumanScodresults); System.gc (); mostbest = getBestPoint (); if (am besten! = null) kehren am besten zurück; // Nehmen Sie die ersten heraus, und wer besser ist, wird computerscodresults.get (0) zurückgeben. } // Unterklasse implementiert diese Methode und ändert ihre Ordnung, um verteidigungsorientierte oder angreifende geschützte Punkte getBestPoint () zu erreichen. if (am besten! = null) kehren am besten zurück; mostbest = getBestPoint (computer3Alives, humanencodresults); if (am besten! = null) kehren am besten zurück; mostbest = GetBestPoint (Humandoulble3Alives, computerscodresults); if (am besten! = null) kehren am besten zurück; mostbest = GetBestPoint (Human3Alives, computerscodresults); if (am besten! = null) kehren am besten zurück; mostbest = getBestPoint (computerDouble2Alives, humananScodresults); if (am besten! = null) kehren am besten zurück; mostbest = getBestPoint (computer2Alives, humanencodresults); if (am besten! = null) kehren am besten zurück; mostbest = GetBestPoint (computer3HalFalive, humananScodresults); if (am besten! = null) kehren am besten zurück; mostbest = getBestPoint (Human4HalFalives, computerscodresults); if (am besten! = null) kehren am besten zurück; am besten = getBestPoint (Humandoulble2Alives, computerscodresults); if (am besten! = null) kehren am besten zurück; mostbest = getBestPoint (Human2Alives, computerscodresults); if (am besten! = null) kehren am besten zurück; mostbest = GetBestPoint (Human3HalFalives, computerscodresults); am besten zurückkehren; } // Der letzte Schritt der dritten Analyse, das zweite Ergebnis wurde sortiert. Hier können Sie das beste Schachstück aus dem vorderen geschützten Punkt getestpoint auswählen (Liste <sencondanalysisResult> myBest, list <sencondanalyseResult> youScodresults) {if (! MyBest.isempy ()) {if. (SencondanalysisResult Ihre: yourScodResults) {if (myBest.Contains (Ihr)) {return Your.point; }} return myBest.get (0) .point; } else {return myBest.get (0) .point; }} return null; } // Das erste Analyseergebnis private endgültige Karte <Punkt <Punkt <FirstanalysisResult >> computerfirstresults = new HashMap <Punkt, list <FirstanalysisResult >> (); private endgültige Karte <Punkt, Liste <FirstanalysisResult >> HumanFirstresults = new HashMap <Punkt, Liste <FirstanAnyyseResult >> (); // Das zweite Gesamtergebnis schützte die endgültige Liste <sencondanalysisResult> computerscodresults = new ArrayList <SencondanalysisResult> (); geschützte endgültige Liste <sencondanalysisResult> humananScodresults = new ArrayList <sencondanalysisResult> (); geschützte endgültige Liste <sencondanalysisResult> (); // Das zweite Ergebnis ist die computergeschützte endgültige Liste <sencondanalysisResult> computer4halFalives = new ArrayList <SencondanalysisResult> (2); geschützte endgültige Liste <sencondanalysisResult> computerDouble3alives = new ArrayList <sencondanalysisResult> (4); geschützte endgültige Liste <SencondanalysisResult> computer3alives = new ArrayList <SencondanalysisResult> (5); geschützte endgültige Liste <SencondanalysisResult> computer3alives = new ArrayList <SencondanalysisResult> (5); geschützte endgültige Liste <sencondanalysisResult> computerDouble2Alives = new ArrayList <sencondanalysisResult> (); geschützte endgültige Liste <SencondanalysisResult> computer2alives = new ArrayList <SencondanalysisResult> (); geschützte endgültige Liste <sencondanalysisResult> computer3HalFalives = new ArrayList <sencondanalysisResult> (); // Das zweite Ergebnis ist, humane geschützte endgültige Liste <sencondanalysisResult> Human4alives = New ArrayList <SencondanalysisResult> (2); geschützte endgültige Liste <sencondanalysisResult> Human4HalFalives = New ArrayList <sencondanalysisResult> (5); geschützte endgültige Liste <sencondanalysisResult> humandoulble3alives = new ArrayList <sencondanalysisResult> (2); geschützte endgültige Liste <SencondanalysisResult> Human3Alives = New ArrayList <SencondanalysisResult> (10); geschützte endgültige Liste <sencondanalysisResult> humandoulble2alives = new ArrayList <sencondanalysisResult> (3); geschützte endgültige Liste <SencondanalysisResult> Human2alives = New ArrayList <SencondanalysisResult> (); geschützte endgültige Liste <sencondanalysisResult> Human3HalFalives = New ArrayList <sencondanalysisResult> (); // Die Analyseergebnisse des Löschens des vorherigen Stücks vor der ersten Analyse private void initanalysisResults () {computerfirstresults.clear (); HumanFirStresults.Clear (); // das zweite Gesamtzahl computerscodresults.clear (); HumanScodresults.clear (); // das zweite Ergebnis computer4HalFalives.clear (); computerDouble3Alives.clear (); computer3alives.clear (); computerDouble2Alives.clear (); computer2alives.clear (); computer3HalFalives.clear (); computer3alives.clear (); computerDouble2Alives.clear (); computer2alives.clear (); computer3HalFalives.clear (); // Das zweite Ergebnis ist Human4alives.clear (); Human4HalFalives.clear (); humandoulble3alives.clear (); human3alives.clear (); humandoulble2alives.clear (); Human2alives.clear (); Human3HalFalives.clear (); System.gc (); } // dem ersten Analyseergebnis hinzuzufügen private void addtofirstanalyseResult (FirstanalysisResult -Ergebnis, Karte <Punkt, Liste <FirstanalysisResult >> dest) {if (dest.containskey (result.point)) {dest.get (result.point) .add (Ergebnis); } else {list <FirstanalysisResult> list = new ArrayList <FirstAryysisResult> (1); list.add (Ergebnis); dest.put (result.point, list); }} // Erste Analyseergebnisklasse private Klasse FirstanalysisResult {// Continuous Count; // Point Point; // Richtung int Richtung; // State int alivestate; Private FirstanalysisResult (int count, Point Point, int Direction) {this (count, point, Richtung, lebendig); } private FirstanalysisResult (int count, point Point, int -Richtung, int alivestate) {this.count = count; this.point = point; Diese. Direktion = Richtung; this.alivestate = alivestate; } private FirstanalysisResult init (Point Point, int Direction, int alivestate) {this.count = 1; this.point = point; Diese. Direktion = Richtung; this.alivestate = alivestate; gib dies zurück; } private firstanalysisResult cloneme () {return New FirstanalysisResult (Graf, Punkt, Richtung, Alivestate); }} // SecondanalysisResult implementiert vergleichbar <sencondanalysisResult> {int lebe4 = 0; // leben 3 int lebend3 = 0; // SecondLiving 4, ein Ende des Siegels in int halfalive4 = 0; // SecondLiving 3, ein Ende des Siegels in int halfalive3 = 0; // Living 2 Menge int lebend2 = 0; // Point Point; @Override public int HashCode () {final int prime = 31; int result = 1; result = prime * result + ((point == null)? 0: point.hashcode ()); Rückgabeergebnis; } @Override public boolean Equals (Objekt obj) {sencondanalysisResult other = (sencondanalysisResult) obj; if (point == null) {if (other.point! = null) return false; } else if (! point.equals (other.Point)) return false; zurückkehren; } private sencondanalysisResult (Punktpunkt) {this.point = point; } // Während der dritten Analyse werden die Ergebnisse der zweiten Analyse sortiert. Dies ist die sortierende Callback -Funktion @Override public int vergleicheto (sencondanalysisResult ein anderes) {return vergleichErTowResult (this, eine andere); }} // Wenn die Rückgabe -1 der erste Parameter ist, ist 1 der zweite Parameter der erste, und 0 ist der private int in der ursprünglichen Order vergleichErTowResult (sencondanalysisResult Oneresult, sencondanalysisResult ein anderes) {if (Oneresult.alive4> Another.alive4) {zurücksend) {zurücksend; } if (Oneresult.Alive4 <Another.Alive4) {return 1; } if (Oneresult.Alive4> Another.Alive4) {return -1; } if (Oneresult.Alive3> Another.Alive3) {return -1; } if (Oneresult.Alive3 <Another.Alive3) {return 1; } if (Oneresult.Alive2> Another.Alive2) {return -1; } if (Oneresult.Alive2 <Another.Alive2) {return 1; } if (Oneresult.Alive3> Another.Alive3) {return -1; } if (Oneresult.Alive3> Another.Alive3) {return 1; } return 0; } // Ein temporäres Objekt wird verwendet, um die Analyseergebnisse während der ersten Analyse vorübergehend zu speichern. Wenn es mehr als 1 (ausgenommen) Ergebnisse gibt, wird die Clonem -Methode aufgerufen, um das Ergebnis zu erhalten. Andernfalls wird dieses Ergebnis private Final FirstanalysisResult weit weg verworfen = neue FirstanalysisResult (1, Null, Heng); // Analyse Wenn sich das Sub neben der aktuellen Position befindet, wie viele Subs werden in eine bestimmte Richtung gebildet. Parameter: Alle Punkte, die auf der aktuellen Seite platziert wurden, der Punkt, der angenommen werden muss, die Richtung, die private FirstanalysisResult TryandCountResult beurteilt werden muss (list <Point> mypoints, list <Point> Feintzüge, Punktpunkt, int -Richtung) {int x = punkt.getX (); int y = point.gety (); FirstanalysisResult fr = null; int maxCountonthisDirection = maxCountonthisDirection (Point, Feinde, Richtung, 1); if (maxCountonthisDirection <5) {// sinnloses Schachstück return null; // Es gibt weniger als fünf leere Räume in dieser Richtung, und das Schachstück, das Sie bereits eingestellt haben, ist ausgeschlossen} else wenn (maxCountonthisDirection == 5) {// halb-tode-staatlich, wenn es sich um ein-end-Mal befindet. } else {// beide Enden sind fr = far.init (Punkt, Richtung, lebendig); } // countpoint berechnen (mypoints, fegeypoints, point.setx (x) .sety (y), fr, richtung, vorwärts); countpoint (mypoints, fegeypoints, point.setx (x) .sety (y), fr, richtung, rückwärts); if (fr.count <= 1 || (fr.count == 2 && fr.alivestate == half_alive)) {// Realive1, Semi-Active2 und die folgenden Ergebnisse, geben Sie return null zurück; } // das Ergebnis des Kopierens von return fr.cloneme () zurückgeben; } // Das Schachstück kommt aus der Wand Private boolean isoutSideofwall (Punktpunkt, int Direction) {if (Direction == Heng) {return point.getX () <0 || point.getX ()> = maxx; // Die maximalen x- und y -Werte befinden sich außerhalb der Wand. Verwenden Sie also das gleiche Vorzeichen} else if (Regie == Zhong) {return point.gety () <0 || point.gety ()> = maxy; } else {// Es kann hier ein Problem geben. Return Point.getX () <0 || point.gety () <0 || point.gety () <0 || point.gety () <0 || point.gety () <0 || point.getX ()> = maxx || point.gety ()> = maxy; }} private point pointTonext (Punktpunkt, int -Richtung, boolean vorwärts) {Switch (Richtung) {case heng: if (vorwärts) point.x ++; sonst point.x--; brechen; Fall Zhong: if (vorwärts) Punkt.y ++; sonst point.y--; brechen; case zheng_xie: if (vorwärts) {point.x ++; point.y--; } else {point.x--; point.y ++; } brechen; case fan_xie: if (vorwärts) {point.x ++; point.y ++; } else {point.x--; point.y--; } brechen; } Rückgabepunkt; } // Wie viele Teile können in eine bestimmte Richtung gespielt werden (einer von acht). Diese Methode ist die Kernmethode in der ersten Analyse private void Countpoint (List <Point> mypoints, list <Point> Enemypoints, Point Point, FirstanalysisResult FR, Int Direction, boolean vorwärts) {if (mypoints.contains (pointTonext (point)) {Fr.Count ++; if (mypoints.contains (pointTonext (Punkt, Richtung, vorwärts)) {fr.count ++; if (mypoints.contains (pointTonext (Punkt, Richtung, vorwärts)) {fr.count ++; if (mypoints.contains (pointTonext (Punkt, Richtung, vorwärts)) {fr.count ++; } else if (fegeypoints.contains (point) || isoutsideofwall (Punkt, Richtung)) {fr.alivestate = half_alive; }} else if (fegeypoints.contains (point) || isoutsideofwall (Punkt, Richtung)) {fr.alivestate = half_alive; }} else if (fegeypoints.contains (Punkt, Richtung)) {fr.alivestate = half_alive; }} else if (fegeypoints.contains (point) || isoutsideofwall (Punkt, Richtung)) {fr.alivestate = half_alive; }} else if (fegeypoints.contains (point) || isoutsideofwall (Punkt, Richtung)) {fr.alivestate = half_alive; }} // Kannst du noch fünf Teile in eine bestimmte Richtung privat int maxCountonthisDirection (Punktpunkt, Liste <Punkte> Feinde, int -Richtung, int count) {int x = point.getX (), y = point.gety (); Switch (Richtung) {// Horizontaler Fall Heng: while (! Enemypoints.contains (point.setx (point.getX ()-1)) && point.getX ()> = 0 && count <6) {count ++; } point.setX (x); while (! Enemypoints.contains (point.setx (point.getX ()+1)) && point.getX () <maxx && count <6) {count ++; } brechen; // senkrechter Fall Zhong: while (! Enemypoints.contains (point.sety (point.gety ()-1)) && point.gety ()> = 0) {count ++; } point.sety (y); while (! Enemypoints.contains (point.sety (point.gety ()+1)) && point.gety () <maxy && count <6) {count ++; } brechen; // Forward oblique/case zheng_xie: while (! Enemypoints.contains (point.setx (point.getX ()-1) .sety (point.gety ()+1)) && point.getX ()> = 0 && pointy.gety () <maxy) {count ++; } point.setx (x) .sety (y); while (! Enemypoints.contains (point.setx (point.getX ()+1) .sety (point.gety ()-1)) && point.getX () <maxx && pointy.gety ()> = 0 && count <6) {count ++; } brechen; // Backslash/case fan_xie: while (! Enemypoints.contains (point.setx (point.getX ()-1) .sety (point.gety ()-1)) && point.getX ()> = 0 && pointy.gety ()> = 0) {count ++; } point.setx (x) .sety (y); while (! Enemypoints.contains (point.setx (point.getX ()+1) .sety (point.gety ()+1)) && point.getX () <maxx && pointy.gety () <maxy && count <6) {count ++; } brechen; } return count; } // Schachstücke abspielen, externe Schnittstelle @Override public void run (list <Point> Menschen, Punkt p) {// Entfernen Sie den letzten Schritt des Menschen Allfreepoints.remove (humanans.get (humanans.size ()-1)); // Ein Schritt des Computers kann Punktergebnisse erstellen = Doanalyse (MyPoints, Menschen); // die Schachstücke auf dem Computer Allfreepoints.Remove (Ergebnis) entfernen; // Zu den Computerschachstücken hinzufügen und Mypoints.Add (Ergebnis) spielen; }} Es ist sehr einfach, menschliche Spieler umzusetzen
importieren java.util.list; Die öffentliche Klasse HumanPlayer erweitert den Basisplayer {@Override public void Run (List <Point> Enemypoint, Punkt p) {getMypoint (). add (p); Allfreepoints.remove (p); }}Zusammenfassung: Obwohl es in Java geschrieben ist, wurde der Algorithmus abstrahiert und kann leicht in die Implementierung verschiedener Plattformen geändert werden.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.