O algoritmo Goziqi AI também é um algoritmo AI típico de jogo. Alguns algoritmos AI de xadrez podem ser usados como referência. A seguir, o código de implementação Java.
Interface abstrata de tabuleiro de xadrez
importar java.util.list; interface pública Ichessboard {// Obtenha a coordenada horizontal máxima do conselho public int getMaxx (); // coordenada vertical máxima public int getMaxy (); // Obtenha todos os pontos em branco atuais, e esses pontos só podem reproduzir o xadrez Lista pública <point> getFreePoints (); }Implementação da classe de xadrez
// O ponto de classe de xadrez {// Este é o desempenho, definido como public int x; public int y; public int getx () {return x; } public Point Setx (int x) {this.x = x; devolver isso; } public int gety () {return y; } public Point Sety (int y) {this.y = y; devolver isso; } public Point (int x, int y) {this.x = x; this.y = y; } @Override public int hashCode () {return x + y; } @Override public boolean equals (object obj) {if (this == obj) retorna true; Ponto outro = (ponto) obj; if (x! = other.x) retorna false; if (y! = outros.y) retornar false; retornar true; }} Interface abstrata do jogador
importar java.util.list; Interface pública IPLAYER {// A próxima etapa é passar no conjunto de chess do quadro de xadrez que o oponente já definiu o public void Run (List <Point> inimigo pontos, pontos Point); public boolean haswin (); public void SetChessboard (tabuleiro de xadrez Ichessboard); Lista pública <Point> getMyPoints (); } Classe abstrata básica do jogador
importar java.util.arraylist; importar java.util.list; classe abstrata public abstrair o BasePlayer implementa o iPlayer {// a peça de xadrez que coloquei na lista protegida <point> myPoints = new ArrayList <Point> (200); // O tabuleiro de xíchas protegido pelo tabuleiro de xadrez; // As coordenadas horizontais e verticais máximas da placa são protegidas int maxx; Int Maxy protegido; // todas as peças de xadrez em branco Lista protegida <Point> AllFreePoints; @Override Public Final List <Point> getMyPoints () {return myPoints; } @Override public void SetChessboard (Ichessboard de xadrez) {this.chessboard = xadrez; allfreePoints = chessboard.getfreePoints (); maxx = chessboard.getMaxx (); maxy = chessboard.getMaxy (); myPoints.clear (); } ponto final privado temp = novo ponto (0, 0); // eu ganho public final boolean haswin () {if (myPoints.size () <5) {return false; } Ponto de ponto = 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; } // perpendicular | contagem = 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; } // encaminhar oblíquo/contagem = 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; } retornar false; }} Implementação da IA do computador
importar java.util.arraylist; importar java.util.Collections; importar java.util.hashmap; importar java.util.list; importar java.util.map; // A classe principal do algoritmo, a principal idéia do algoritmo é dividida em três etapas. //The first step: cyclically assume the score for oneself and the other party (to make a score within a certain range) according to the current situation of both parties, and judge the changes in the situation that this piece can bring, such as whether it can rush 4, whether it can form our or enemy double 3, etc. //The second step: According to the results of the previous step, combine all the results brought by each piece (such as a piece of chess piece may form our side 1 live 3, 1 run 4 (Eu chamo isso de meio vivo 4), etc.), incluindo o inimigo e o nosso lado. // Etapa 3: Classifique o resultado anterior de acordo com as regras fornecidas pelo usuário e selecione Formas sub -subjetivas e defensivas (existem regras para formas ofensivas e defensivas) classe pública Basecomputerai estende o jogador de base {// quatro direções, horizontal -, vertical | . private estático final int zhong = 1; private estático final int zheng_xie = 2; private estático final int fan_xie = 3; // Frente para trás estático privado final Boolean Forward = true; Private estático final booleano para trás = false; // exibe o resultado da análise. Se o ponto atual é o passe de duas pontas (vivo) ou apenas um passe de ponta (Half_alive), o processo de análise de peças de xadrez bloqueado é bloqueado automaticamente, não como uma peça de xadrez a ser selecionada private estática final int viva = 1; private estático final int Half_alive = 0; // private estático final int morto = -1; // calcular o intervalo, o alcance muito grande terá problemas de desempenho Classe Private 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; }} // Limite o intervalo de cálculo do computador. Se todo o desempenho do cálculo da placa de xadrez for muito ruim, atualmente será formado com base no valor limite de todas as peças de xadrez que foram colocadas em uso. Atualmente, é 1 estático privado int range_Step = 1; CalcuteRange CurrentRange = new CalcUteRange (0, 0, 0, 0); private void initRange (list <point> couters, list <point> humanos) {currentRange.xstart = Humans.get (0) .getx ()-range_step; currentRange.ystart = Humans.get (0) .gety ()-range_step; currentRange.xstop = Humans.get (0) .getx ()+range_step; CurrentRange.yStop = Humans.get (0) .gety ()+range_step; para (ponto de ponto: humanos) {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 ()-range_step <currentRange.ystart) {currentRange.ystart = Point.gety ()-range_step; } else if (Point.gety ()+range_step> currentRange.yStop) {currentRange.ystop = Point.gety ()+range_step; }} para (ponto ponto: couters) {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 ()-range_step <currentRange.ystart) {currentRange.ystart = Point.gety ()-range_step; } else if (Point.gety ()+range_step> currentRange.yStop) {currentRange.ystop = Point.gety ()+range_step; }} // Se o intervalo for expandido e exceder o quadro de xadrez, é igual ao quadro de xadrez CurrentRange.xstart = currentRange.xstart <0? 0: currentRange.xstart; currentRange.ystart = currentRange.ystart <0? 0: currentRange.ystart; currentRange.ystart = currentRange.ystart <0? 0: currentRange.ystart; currentRange.xstop = currentRange.xstop> = maxx? maxx-1: currentRange.xstop; currentRange.ystop = currentRange.yStop> = maxy? maxy-1: currentRange.ystop; } // Analise a forma atual do método de entrada. A análise é dividida em três etapas no total. O terceiro passo pode ser controlado por subclasses para dificuldade. Ponto privado Doanalysis (List <Point> Couters, List <Point> Humans) {if (Humans.size () == 1) {// A primeira etapa retorna getFirstpoint (Humans); } // inicialize o intervalo de cálculo InitRange (Comutores, Humanos); // limpe os resultados anteriores InitanalysisResults (); // Iniciar análise, digitalizar todos os pontos em branco e formar o primeiro ponto de análise Point Bestpoint = Dofirstanalysis (Comutores, Humanos); if (bestpoint! = null) {//system.out.println(" Esta peça é a mais importante, você só pode reproduzir esta peça "); retornar o melhor ponto; } // Analise o primeiro resultado e encontre o seu melhor ponto Bestpoint = DocomputerSencanalysis (ComputerFirstresults, ComputerSEncodResults); if (bestpoint! = null) {//system.out.println("i'm prestes a vencer, eu tocarei esta peça "); retornar o melhor ponto; } Computerfirstresults.clear (); System.gc (); // Analise o primeiro resultado e encontre o melhor ponto do inimigo Bestpoint = Dohumansencondanalysis (HumanFirstresults, HumansEncodResults); if (melhor! retornar o melhor ponto; } humanfirstresults.clear (); System.gc (); // Nenhum ponto de morte final foi encontrado, a terceira análise de resultado retornou a DothirdAnálise (); } // A primeira etapa da peça de xadrez não requer cálculos complicados e é concluída com base no valor x da primeira etapa humana da peça de xadrez. Ponto privado getfirstpoint (list <point> humanos) {Point Point = Humans.get (0); if (Point.getx () == 0 || Point.gety () == 0 || Point.getx () == maxx && Point.gety () == maxy) retorna novo ponto (maxx/2, maxy/2); else {return New Point (Point.getx ()-1, Point.gety ()); }} // private int debugx, debugy; // use para depuração // Iniciar a análise, digitalizar todos os pontos em branco e formar o primeiro resultado da análise do ponto privado dofirstanalysis (list <point> couters, list <point> humanos) {int size = allfreePoints.size (); Point ComputerPoint = NULL; Point HumanPoint = NULL; int x, y; FirstAnalysisResultsult FirstanalysisResult; for (int i = 0; i <tamanho; i ++) {ComputerPoint = allfreepoints.get (i); // Clique nas coordenadas X e Y primeiro, porque o objeto original será alterado durante o processo de análise x = computerpoint.getx (); y = computadorPoint.gety (); if (x <currentRange.xstart || x> currentRange.xstop || y <currentRange.ystart || y> currentRange.yStop) {continuação; } // if (x == DebugX && y == Debugy) {// System.out.println ("Ssssssssssssssssssssssssssssssssssssssssss) {continuação; System.out.println("ssssssssssssssssssssssssssssssssssssssssssss){ // } //Try to set a chess piece at this position and analyze the states that we can only form in the "horizontal" direction, such as live 4, live 3, semi-living 4, live 2, etc. FirstAnalysisResult = TryandCountResult (Comutores, Humanos, ComputerPoint, Heng); ComputerPoint.Setx (X) .Sety (y); // Responda o valor original do ponto para a próxima análise se (FirstAnalysisResult! = NULL) {// Sem resultado de retorno, é impossível chegar a cinco peças de xadrez nessa direção. Se (FirstAnalysisResult.Count == 5) // igual a 5 significa que você pode jogar peças de xadrez neste momento e poderá se conectar a 5. Se você vencer, não o analisará. Retornar computerpoint; // registra o primeiro resultado da análise AddTofirStanalysisResult (FirstanalysisResult, ComputerFirstresults); } // Repita as etapas acima na "direção vertical" FirstanalysisResult = TryandCountResult (Cituters, Humanos, ComputerPoint, Zhong); ComputerPoint.Setx (X) .Sety (Y); if (FirstAnalysisResult! = null) {// morre o xadrez, não jogue se (FirstAnalysisResult.Count == 5) retorne o computador do computador; addTofirStanalysisResult (FirstAnalysisResult, ComputerFirstresults); } // encaminhamento oblíquo FirstanalysisResult = TryandCountResult (Comutores, Humanos, ComputerPoint, Zheng_Xie); ComputerPoint.Setx (X) .Sety (Y); if (FirstAnalysisResult! = NULL) {// xadrez morto, não jogue se (FirstAnalysisResult.Count == 5) retorne o computador do computador; addTofirStanalysisResult (FirstAnalysisResult, ComputerFirstresults); } // Backside FirstanalysisResult = TryandCountResult (Comutores, Humanos, ComputerPoint, FAN_XIE); ComputerPoint.Setx (X) .Sety (Y); if (FirstAnalysisResult! = NULL) {// xadrez morto, não jogue se (FirstAnalysisResult.Count == 5) retorne o computador do computador; addTofirStanalysisResult (FirstAnalysisResult, ComputerFirstresults); } // Analise o estado desta peça no inimigo na direção "horizontal", como o Live 3 do inimigo, semi-vivos 4, etc. FirstanalysisResult = TryandCountResult (humanos, adultos, computadores, heng); ComputerPoint.Setx (X) .Sety (Y); if (FirstAnalysisResult! = NULL) {// Die xadrez, não jogue se (FirstAnalysisResult.Count == 5) HumanPoint = ComputerPoint; addTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); } // "long-perpendicular" FirstanalysisResult = TryandCountResult (Humanos, Cituters, ComputerPoint, Zhong); ComputerPoint.Setx (X) .Sety (Y); if (FirstAnalysisResult! = NULL) {// Die xadrez, não jogue se (FirstAnalysisResult.Count == 5) HumanPoint = ComputerPoint; addTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); } // "Forward-Slant" FirstanalysisResult = TryandCountResult (Humanos, Comuters, ComputerPoint, Zheng_Xie); ComputerPoint.Setx (X) .Sety (Y); if (FirstAnalysisResult! = NULL) {// Die xadrez, não jogue se (FirstAnalysisResult.Count == 5) HumanPoint = ComputerPoint; addTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); } // "backslash" FirstanalysisResult = TryandCountResult (Humanos, Comuters, ComputerPoint, FAN_XIE); ComputerPoint.Setx (X) .Sety (Y); if (FirstAnalysisResult! = NULL) {// Die xadrez, não jogue se (FirstAnalysisResult.Count == 5) HumanPoint = ComputerPoint; addTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); }} // Se não houver peça vencedora, a primeira análise não precisará retornar o resultado da primeira análise; } // A segunda análise, analise o resultado da primeira formação, o primeiro resultado da análise gerará até quatro objetos de FirstAnalysisResult (quatro inimigos e um ao outro). // Os quatro objetos devem ser combinados em um objeto sencondanalysisResult, Ponto privado docomputerSencanálise (mapa <ponto, list <strimanalysissultsult>> firstresults, list <sencondanalysislResult> sencodResults) {list <firstanalysisult> list = null; SencondanalysisResult sr = nulo; for (ponto P: firstresults.KeySet ()) {sr = novo sencondanalysisResult (p); list = firstSults.get (p); para (FirstAnalysisResult Result: List) {if (resultado.Count == 4) {if (result.aliveState == Alive) {// Após a filtragem anterior, ambos os lados descartaram a matança final. Se houver 4, dê este passo e ganhe o próximo passo. resultado.point; // Se houver uma morte final, a primeira rodada retornou. Nesta rodada de 4, já é uma boa peça, retorne diretamente e não a analise mais} else {Sr.Halfalive4 ++; computer4halfalives.add (SR); }} else if (resultado.count == 3) {if (result.aliveState == Alive) {sr.alive3 ++; if (sr.Alive3 == 1) {computer3alives.add (sr); } else {ComputerDouble3alives.add (sr); }} else {sr.halfalive3 ++; Computer3halfalives.add (SR); }} else {// semi-live 2 foi excluído no primeiro estágio e não é mais processado sr.Alive2 ++; if (sr.Alive2 == 1) {Computer2alives.add (sr); } else {ComputerDouble2alives.add (SR); }}}} sencodResults.add (sr); } // sem vida 4 foi encontrado; retornar nulo; } // Este método é basicamente o mesmo que acima, mas para o desempenho, é menos julgamento, separa os seres humanos e computadores de ponto privado dohumansencondanálise (mapa <ponto, list <strimanalysissult >> firstresults, list <sencondanalysislResult> senCodResults) {list) SencondanalysisResult sr = nulo; for (ponto P: firstresults.KeySet ()) {sr = novo sencondanalysisResult (p); list = firstSults.get (p); para (FirstAnalysisChyResult Result: List) {if (result.Count == 4) {if (result.aliveState == Alive) {Human4alives.add (sr); } else {sr.halfalive4 ++; Human4halfalives.add (SR); }} else if (resultado.count == 3) {if (result.aliveState == Alive) {sr.alive3 ++; if (sr.Alive3 == 1) {Human3alives.add (sr); } else {Humandouble3alives.add (sr); }} else {sr.halfalive3 ++; Human3Halfalives.add (SR); }} else {sr.alive2 ++; if (sr.Alive2 == 1) {Human2alives.add (sr); } else {Humandouble2alives.add (sr); }}} sencodResults.add (sr); } // No Live 4 foi encontrado retorno nulo; } Sono privativo void (int minisEcond) {tente {thread.sleep (minissegund); } Catch (interruptedException e) {}} // A terceira análise, nenhum dos lados pode criar um Live 4, encontre 3 peças ao vivo, se não, encontre metade Live 4, se não, encontre um único Live 3, Double Live 2 Point Private Dothirdanalysis () {if (! } System.gc (); sono (300); Coleções.sort (ComputerEncodResults); System.gc (); // Estou prestes a viver 4, e não tenho 4 ou mais, então só posso bloquear o ponto mais Best = getBestpoint (Human4Alives, ComputerSEncodResults); if (MostBest! = NULL) retornar mais BELES; Coleções.sort (HumansEncodResults); System.gc (); MostBest = getBestPoint (); if (MostBest! = NULL) retornar mais BELES; // Retire os primeiros, e quem estiver melhor retornará os computherEncodResults.get (0) .point; } // A subclasse implementa esse método e altera sua ordem para alcançar o ponto de proteção protegido de defesa ou atacando o ponto getBestPoint () {// estou prestes a viver 4, e não tenho 4 ou mais de vida, então só posso bloquear o ponto mais Best = getBestPoint (ComputerDouble3Alives, HumansEncodResults); if (MostBest! = NULL) retornar mais BELES; MostBest = getBestPoint (Computer3alives, HumansEncodResults); if (MostBest! = NULL) retornar mais BELES; MOSTBEST = getBestPoint (Humandouble3alives, ComputerSEncodResults); if (MostBest! = NULL) retornar mais BELES; MOSTBEST = getBestPoint (Human3alives, ComputerCodResults); if (MostBest! = NULL) retornar mais BELES; MostBest = getBestPoint (ComputerDouble2alives, HumansEncodResults); if (MostBest! = NULL) retornar mais BELES; MostBest = getBestPoint (Computer2alives, HumansEncodResults); if (MostBest! = NULL) retornar mais BELES; MOSTBEST = getBestPoint (Computer3Halfalives, HumansEncodResults); if (MostBest! = NULL) retornar mais BELES; MostBest = getBestPoint (Human4Halfalives, ComputerSEncodResults); if (MostBest! = NULL) retornar mais BELES; MOSTBEST = getBestPoint (Humandouble2alives, ComputerCodResults); if (MostBest! = NULL) retornar mais BELES; MOSTBEST = getBestPoint (Human2alives, ComputerCodResults); if (MostBest! = NULL) retornar mais BELES; MostBest = getBestPoint (Human3Halfalives, ComputerSEncodResults); retornar o MostBest; } // A última etapa da terceira análise, o segundo resultado foi classificado, aqui você pode selecionar a melhor peça de xadrez do ponto frontal protegido getBestPoint (List <SencondanalysisResult> mybest, list <sencondanalysissult> itensencodresults) {se (! (SencondanalysisResult Your: itensencodResults) {if (mybest.contains (your)) {return your.point; }} retorna mybest.get (0) .point; } else {return mybest.get (0) .point; }} retornar nulo; } // O primeiro mapa final privado do resultado da análise <Point, List <PrimeiraNalysisResult>> Computerfirstresults = new Hashmap <Point, List <FirstAnalysisResult >> (); mapa final privado <ponto, list <strimanalysisResult>> HumanFirstresults = new Hashmap <Point, List <FirstAnalysisResult >> (); // O segundo resultado total protegido Lista final <SencondanalysisResult> ComputerSEncodResults = new ArrayList <SencondanalysisResult> (); Lista final protegida <SencondanalysisResult> HUMANSENCODRESULTS = NOVA ARRAYLIST <SENCONDANALYSISTRESULT> (); Lista final protegida <SencondanalysisResult> (); // O segundo resultado é que a lista final protegida por computador <sencondanalysisResult> computer4halfalives = new ArrayList <SencondanalysisResult> (2); Lista final protegida <SencondanalysisResult> ComputerDouble3alives = new ArrayList <SencondanalysisResult> (4); Lista final protegida <SencondanalysisResult> Computer3alives = novo ArrayList <SencondanalysisResult> (5); Lista final protegida <SencondanalysisResult> Computer3alives = novo ArrayList <SencondanalysisResult> (5); Lista final protegida <SencondanalysisResult> ComputerDouble2alives = new ArrayList <SencondanalysisResult> (); Lista final protegida <SencondanalysisResult> Computer2alives = new ArrayList <SencondanalysisResult> (); Lista final protegida <SencondanalysisResult> Computer3halfalives = new ArrayList <SencondanalysisResult> (); // O segundo resultado é: Lista final protegida humana <SencondanalysisResult> Human4Alives = New ArrayList <SencondanalysisResult> (2); Lista final protegida <SencondanalysisResult> Human4Halfalives = New ArrayList <SencondanalysisResult> (5); Lista final protegida <SencondanalysisResult> Humandouble3alives = novo ArrayList <SencondanalysisResult> (2); Lista final protegida <SencondanalysisResult> Human3alives = novo ArrayList <SencondanalysisResult> (10); Lista final protegida <SencondanalysisResult> Humandouble2alives = novo ArrayList <SencondanalysisResult> (3); Lista final protegida <SencondanalysisResult> humana2alives = new ArrayList <SencondanalysisResult> (); Lista final protegida <SencondanalysisResult> Human3Halfalives = New ArrayList <SencondanalysisResult> (); // Os resultados da análise da limpeza da peça anterior antes da primeira análise private vazio initanalysisResults () {Computerfirstresults.clear (); HumanFirstresults.clear (); // o segundo resultado total ComputerSecodResults.clear (); HumansEncodResults.clear (); // o segundo resultado computer4halfalives.clear (); ComputerDouble3alives.clear (); computer3alives.clear (); ComputerDouble2alives.clear (); comput2alives.clear (); computer3halfalives.clear (); computer3alives.clear (); ComputerDouble2alives.clear (); comput2alives.clear (); computer3halfalives.clear (); // O segundo resultado é Human4alives.clear (); Human4Halfalives.clear (); Humandouble3alives.clear (); Human3alives.clear (); Humandouble2alives.clear (); Human2alives.clear (); Human3Halfalives.clear (); System.gc (); } // Adicione ao primeiro resultado da análise private void addTofirStanalysisResult (resultado do FirstAnalysisResult, map <Point, List <FirstAnalysisisResult >> dest) {if (dest.containsKey (resultado.point)) {dest.get (resultado.point) .dd (resultado); } else {list <firstanalysisResult> list = new ArrayList <FirstAnalysisResult> (1); list.add (resultado); dest.put (resultado.point, list); }} // Primeira análise Classe de classe Private FirstanalysisResult {// contínua contagem; // ponto de ponto de ponto; // direção int direção; // state int alivestate; private FirstanalysisResult (int conting, ponto de ponto, direção int) {this (contagem, ponto, direção, vivo); } private FirstanalysisResult (int contagem, ponto de ponto, direção int, int alivestate) {this.count = count; this.Point = Point; this.direction = direção; this.alivestate = alivestate; } private FirstanalysisResult init (ponto Point, Int Direction, int Alivestate) {this.count = 1; this.Point = Point; this.direction = direção; this.alivestate = alivestate; devolver isso; } private FirstAnalysisResult cloneme () {retorna new FirstanalysisResult (contagem, ponto, direção, alivestado); }} // SecondAnalysisResult implementos comparáveis <SencondanalysisResult> {int vivo4 = 0; // Living 3 int vivo3 = 0; // SecondLiving 4, uma extremidade do selo int halfalive4 = 0; // SecondLiving 3, uma extremidade do selo int halfalive3 = 0; // Living 2 Quantity int Alive2 = 0; // ponto de ponto; @Override public int hashCode () {final int prime = 31; int resultado = 1; Result = Prime * resultado + ((Point == NULL)? 0: Point.HashCode ()); resultado de retorno; } @Override public boolean equals (object obj) {sencondanalysisResult outros = (sencondanalysisResult) obj; if (ponto == null) {if (other.point! = null) retorna false; } else if (! Point.equals (outro.point)) retornar false; retornar true; } private sencondanalysisResult (ponto ponto) {this.point = Point; } // Durante a terceira análise, os resultados da segunda análise são classificados. Esta é a função de retorno de chamada de classificação @Override public int compareto (sencondanalysisResult outro) {return comparetowResult (isto, outro); }} // Se o retorno -1 for o primeiro parâmetro, 1 é o segundo parâmetro é o primeiro e 0 é o privado int int na ordem original CompareTowResult (SencondanalysisResult OneResult, sencondanalysissult outro) {if (oneResult.alive4> outro.alive4) {Return -1; } if (oneResult.alive4 <outro.alive4) {return 1; } if (oneResult.alive4> outro.Alive4) {return -1; } if (oneResult.alive3> outro.Alive3) {return -1; } if (oneResult.alive3 <outro.alive3) {return 1; } if (oneResult.alive2> outro.alive2) {return -1; } if (oneResult.alive2 <outro.alive2) {return 1; } if (oneResult.alive3> outro.Alive3) {return -1; } if (oneResult.alive3> outro.Alive3) {return 1; } retornar 0; } // Um objeto temporário é usado para armazenar temporariamente os resultados da análise durante a primeira análise. Se houver mais de 1 (excluindo) os resultados, o método Cloneme será chamado para obter o resultado. Caso contrário, esse resultado será descartado, privado FirstAnalysisResult Far = New FirstAnalysisResult (1, NULL, HENG); // Análise Se o sub estiver próximo à posição atual, quantos subs serão formados em uma certa direção. Parâmetros: todos os pontos que foram colocados no lado atual, o ponto que precisa ser assumido, a direção que precisa ser julgada privada Firstanalysisissult TryandCountResult (List <Point> myPoints, list <point> inimigo, ponto pontual, int direction) {int x = Point.getx (); int y = Point.gety (); FirstanalysisResult FR = nulo; int maxCountOnthisDirection = maxCountOnthisDirection (Point, inimigo pontos, direção, 1); if (maxcountOnthisdirection <5) {// peça de xadrez sem sentido retornar nulo; // Existem menos de cinco espaços vazios nessa direção, e a peça de xadrez que você já definiu é excluída} mais se (maxCountOnthisDirection == 5) {// o estado de half-mor, se é um end de um-end =. } else {// Ambas as extremidades são fr = Far.init (ponto, direção, vivo); } // Calcule o CountPoint (MyPoints, Enempoints, Point.Setx (x) .Sety (y), FR, Direção, para a frente); CountPoint (MyPoints, inimigo, Point.Setx (x) .Sety (y), Fr, Direção, para trás); if (fr.count <= 1 || (fr.count == 2 && fr.aliveState == half_alive)) {// realive1, semi-ateio2 e os seguintes resultados, abandone o retorno nulo; } // retorna o resultado da cópia de retorno f.CloneMe (); } // A peça do xadrez sai da parede private boolean isoutsideofwall (ponto de ponto, int direção) {if (direção == heng) {return Point.getx () <0 || Point.getx ()> = maxx; // Os valores máximos x e y estão fora da parede; portanto, use o sinal igual} else if (direção == zhong) {retorno ponto.gety () <0 || Point.gety ()> = maxy; } else {// pode haver um problema aqui Retorno Point.getx () <0 || Point.gety () <0 || Point.gety () <0 || Point.gety () <0 || Point.gety () <0 || Point.getx ()> = maxx || Point.gety ()> = maxy; }} private ponto de pontoTONEXT (ponto de ponto, int orientação, boolean para frente) {switch (direção) {case heng: if (forward) Point.x ++; else Point.x--; quebrar; caso zhong: if (forward) ponto.y ++; else Point.Y--; quebrar; case zheng_xie: if (forward) {Point.x ++; Point.Y--; } else {Point.x--; Point.y ++; } quebrar; Caso fan_xie: if (forward) {Point.x ++; Point.y ++; } else {Point.x--; Point.Y--; } quebrar; } ponto de retorno; } // Quantas peças podem ser tocadas em uma certa direção (uma das oito). Este método é o método central na primeira análise, private vazio CountPoint (List <Point> MyPoints, List <Point> Enempoints, Point Point, FirstAnalysisChySultsult FR, int Direction, Boolean Forward) {if (myPoints.contains (PointTonext (Point, Direção, Forward)) {fr.count ++; if (myPoints.contains (PointTonext (ponto, direção, avanço))) {fr.count ++; if (myPoints.contains (PointTonext (ponto, direção, avanço))) {fr.count ++; if (myPoints.contains (PointTonext (ponto, direção, avanço))) {fr.count ++; } else if (inenepoints.contains (ponto) || isoutsideofwall (ponto, direção)) {fr.aliveState = half_alive; }} else if (inimigo pontos.contains (ponto) || isoutsideOfwall (ponto, direção)) {fr.aliveState = half_alive; }} else if (inimigo pontos.Contains (Point, Direction)) {fr.aliveState = Half_alive; }} else if (inimigo pontos.contains (ponto) || isoutsideOfwall (ponto, direção)) {fr.aliveState = half_alive; }} else if (inimigo pontos.contains (ponto) || isoutsideOfwall (ponto, direção)) {fr.aliveState = half_alive; }} // Você ainda pode obter cinco peças em uma certa direção privado int maxCountOnthisDirection (ponto de ponto, list <point> inimigo, Int Direction, int count) {int x = Point.getx (), y = Point.gety (); switch (direção) {// case horizontal heng: while (! inimigoints.contains (Point.Setx (Point.getx ()-1)) && Point.getx ()> = 0 && count <6) {count ++; } Point.setx (x); while (! inimigoints.contains (Point.Setx (Point.getx ()+1)) && Point.getx () <maxx && count <6) {count ++; } quebrar; // Caso perpendicular zhong: while (! Inimigo pontos.contains (Point.Sety (Point.gety ()-1)) && Point.gety ()> = 0) {count ++; } Point.sety (y); while (! inimigoints.contains (Point.Sety (Point.gety ()+1)) && Point.gety () <maxy && count <6) {count ++; } quebrar; // encaminhar oblíquo/case zheng_xie: while (! Inimigoints.contains (Point.Setx (Point.getX ()-1) .Sety (Point.gety ()+1)) && Point.getx ()> = 0 && Point.gety () <Maxy) {count ++; } Point.Setx (x) .Sety (y); while (! inimigoints.contains (Point.Setx (Point.getx ()+1) .Sety (Point.gety ()-1)) && Point.getx () <maxx && Point.gety ()> = 0 && count <6) {count ++; } quebrar; // backslash/case fan_xie: while (! Inimigoints.contains (Point.Setx (Point.getx ()-1) .Sety (Point.gety ()-1)) && Point.getx ()> = 0 && Point.gety ()> = 0) {count ++; } Point.Setx (x) .Sety (y); while (! inimigoints.contains (Point.Setx (Point.getx ()+1) .Sety (Point.gety ()+1)) && Point.getx () <maxx && Point.gety () <maxy && count <6) {count ++; } quebrar; } contagem de retorno; } // Jogue peças de xadrez, interface externa @Override public void Run (List <Point> Humanos, Ponto P) {// Remova a última etapa do ser humano AllfreePoints.Remove (Humans.get (Humans.size ()-1)); // Uma etapa do computador pode fazer resultado de ponto = doanálise (MyPoints, humanos); // remova as peças de xadrez no computador allfreePoints.remove (resultado); // adiciona às peças de xadrez do computador e reproduz myPoints.add (resultado); }} É muito fácil implementar jogadores humanos
importar java.util.list; classe pública HumanPlayer estende o BasePlayer {@Override public void run (list <point> inimigo, ponto p) {getMypoints (). add (p); allfreepoints.remove (p); }}Resumo: Embora esteja escrito em Java, o algoritmo foi abstraído e pode ser facilmente modificado nas implementações de várias plataformas.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.