Goziqi AI 알고리즘은 또한 일반적인 게임 AI 알고리즘입니다. 일부 체스 AI 알고리즘을 참조로 사용할 수 있습니다. 다음은 Java 구현 코드입니다.
체스 판 추상 인터페이스
Java.util.list 가져 오기; 공개 인터페이스 ichessboard {// 보드의 최대 수평 좌표를 가져옵니다. 공개 getmaxx (); // 최대 수직 좌표 public int getMaxy (); // 현재의 모든 빈 점을 가져 오면이 포인트는 체스 공개 목록 <point> getFreePoints () 만 재생할 수 있습니다. }체스 클래스 구현
// 체스 클래스 포인트 {// 이것은 공개 int x로 설정된 성능입니다. 공개 in y; public int getx () {return x; } public point setx (int x) {this.x = x; 이것을 반환하십시오; } public int gety () {return y; } public point sety (int y) {this.y = y; 이것을 반환하십시오; } 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) return true; 포인트 기타 = (포인트) obj; if (x! = Other.x) false를 반환합니다. if (y! = Other.y) false를 반환합니다. 진실을 반환하십시오. }} 플레이어 초록 인터페이스
Java.util.list 가져 오기; Public Interface iPlayer {// 다음 단계는 상대방이 이미 공개적으로 공개 실행을 설정 한 체스 보드 세트를 전달하는 것입니다 (List <point> Empoints, Point Point); 공개 부울 haswin (); 공개 void setchessboard (Ichessboard Chessboard); 공개 목록 <point> getMypoints (); } 플레이어 기본 초록 수업
java.util.arraylist 가져 오기; Java.util.list 가져 오기; 공개 초록 클래스베이스 플레이어는 iPlayer {// 체스 조각을 보호 목록 <point> myPoints = new ArrayList <point> (200); // 체스 판 보호 ICHESSBORD 체스 보드; // 보드의 최대 수평 및 수직 좌표는 int maxx를 보호합니다. 보호 된 INT Maxy; // 모든 빈 체스 조각 보호 목록 <point> allfreepoints; @override public final list <point> getmypoints () {return mypoints; } @override public void setchessboard (Ichessboard Chessboard) {this.chessboard = Chessboard; allfreepoints = chessboard.getfreepoints (); maxx = chessboard.getmaxx (); maxy = chessboard.getMaxy (); mypoints.clear (); } private final point temp = new Point (0, 0); // 공개 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 (); // 수평- 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; } // 수직 | 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; } // 앞으로의 경사/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; } false를 반환합니다. }} 컴퓨터 AI 구현
java.util.arraylist 가져 오기; java.util.collections import; java.util.hashmap import; Java.util.list 가져 오기; java.util.map import; // 알고리즘의 핵심 클래스, 알고리즘의 주요 아이디어는 세 단계로 나뉩니다. // 첫 번째 단계 : 두 당사자의 현재 상황에 따라 자신과 상대방의 점수를 주기적으로 가정하고,이 작품이 가져올 수있는 상황의 변화를 러쉬를 뿌릴 수 있는지, 우리 또는 적의 더블 3 등을 형성 할 수 있는지 여부와 같은 상황의 변화를 판단합니다. 적과 우리 쪽을 포함하여 반은 4) 등입니다. // 3 단계 : 사용자가 제공 한 규칙에 따라 이전 결과를 정렬하고 하위 주제 및 방어 형태 (공격 및 방어 형태에 대한 규칙이 있습니다) 공개 클래스 BaseComputerai는베이스 플레이어를 확장합니다 {// 4 방향, 수평 -, 수직 | , 전방 슬래랑드 /, 백사 / 개인 정적 최종 최종 int heng = 0; 개인 정적 최종 최종 int Zhong = 1; 개인 정적 최종 최종 INT Zheng_Xie = 2; 비공개 정적 최종 int fan_xie = 3; // 전면 대 뒤로 비공개 정적 최종 부울 앞으로 = true; 개인 정적 최종 부울 뒷면 = 거짓; // 분석 결과를 표시합니다. 현재 포인트가 2- 엔드 패스 (Alive)이든 1- 엔드 패스 (Half_Alive)이든, 차단 된 체스 피스 분석 프로세스는 자동으로 차단됩니다. 개인 정적 최종 int half_alive = 0; // 비공개 정적 최종 int dead = -1; // 범위를 계산하고 너무 넓은 범위가 성능 문제가 있습니다. 개인 클래스 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; }} // 컴퓨터 계산 범위를 제한합니다. 전체 체스 보드 계산 성능이 너무 열악한 경우 현재 사용 된 모든 체스 조각의 경계 값에 따라 형성됩니다. 현재 1 개인 정적 최종 최종 int range_step = 1입니다. Calcuterange CurrentRange = New Calcuterange (0, 0, 0, 0); 개인 void initRange (List <point> couters, list <point> humans) {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; for (point point : humans) {if (point.getx () -range_step <currange.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; }} for (point point : coounters) {if (point.getx () -range_step <currentrange.xstart) {currentRange.xstart = point.getx ()-범위_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; }} // 범위가 확장되어 체스 판을 초과하면 Chessboard currentRange.xstart = currentRange.xstart <0? 0 : currentRange.xstart; currentRange.ystart = currange.ystart <0? 0 : currentRange.ystart; currentRange.ystart = currange.ystart <0? 0 : currentRange.ystart; currentRange.xstop = currentRange.xStop> = maxx? maxx-1 : currentRange.xstop; currentRange.ystop = currenge.ystop> = maxy? maxy-1 : currentRange.ystop; } // 현재 입력 방법을 분석합니다. 분석은 총 3 단계로 나뉩니다. 세 번째 단계는 난이도를 위해 서브 클래스로 제어 할 수 있습니다. Private Point doanalysis (list <point> couters, list <point> humans) {if (humans.size () == 1) {// 첫 번째 단계는 getFirstPoint (Humans)를 반환합니다. } // 계산 범위 초기화 initRange (Comuters, Humans); // 이전 결과를 지우십시오. initAnalysisResults (); // 분석 시작, 모든 빈 점을 스캔하고 첫 번째 분석 결과 포인트 BestPoint = Dofirstanalysis (Comuters, Humans)를 형성합니다. if (bestpoint! = null) {//system.out.println("이 조각은 가장 중요합니다.이 작품 만 재생할 수 있습니다. "); BestPoint 리턴; } // 첫 번째 결과를 분석하고 최상의 포인트를 찾으십시오. BestPoint = DocomPupersenCondAnalysis (ComputerFirStresults, ComputerSencoDresults); if (bestpoint! = null) {//system.out.println("i'm이 승리하려고합니다. BestPoint 리턴; } computerfirstresults.clear (); System.gc (); // 첫 번째 결과를 분석하고 적의 가장 좋은 점을 찾으십시오. if (bestpoint! = null) {//system.out.println("if이 작품을 재생하지 않으면 잃을 것입니다. BestPoint 리턴; } humanFirStresults.Clear (); System.gc (); // 최종 킬 포인트가 발견되지 않았으며, 세 번째 결과 분석은 dothirdanalysis ()를 반환했습니다. } // 체스 조각의 첫 번째 단계는 복잡한 계산이 필요하지 않으며 체스 조각의 인간 첫 단계의 x 값을 기반으로 완료됩니다. Private Point getFirstPoint (List <point> Humans) {Point Point = Humans.get (0); if (point.getx () == 0 || point.gety () == 0 || point.getx () == maxx && point.gety () == maxy) 새로운 포인트 (maxx/2, maxy/2); else {return new point (point.getx () -1, point.gety ()); }} // private int debugx, debugy; // debug // debug a Start Analysis, 모든 빈 점을 스캔하고 첫 번째 분석 결과 개인 포인트 dofirstanalysis (list <point> couters, list <point> humans) {int size = allfreepoints.size (); Point ComputerPoint = NULL; Point HumanPoint = NULL; int x, y; FirstAnalysisResult FirstAnalysisResult; for (int i = 0; i <size; i ++) {computerpoint = allfreepoints.get (i); // 분석 프로세스 중에 원래 객체가 변경되므로 x 및 y 좌표를 먼저 클릭하십시오. x = computerpoint.getx (); y = computerpoint.gety (); if (x <currenge.xstart || x> currentRange.xstop || y <currentRange.ystart || y> currentRange.ystop) {계속; } // if (x == debugx && y == debugy) {// system.out.println ( "sssssssssssssssssssssssssssssssssssssssssssssssssssssss) {계속;} // if (x == debugx && y == debugy) {// 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 (Comuters, Humans, Computerpoint, Heng); computerpoint.setx (x) .sety (y); // 다음 분석에 대한 포인트의 원래 값에 응답합니다. if (firstAnalysisResult.count == 5) // 5와 동일하다면이 시점에서 체스 조각을 재생할 수 있고 5에 연결할 수 있음을 의미합니다. 이길 경우 분석하지 않습니다. 컴퓨터 포인트 리턴; // 첫 번째 분석 결과 addTofirstanalysisResult (FirstAnalysisResult, ComputerFirstresults); } // 위의 단계를 "수직 방향"으로 반복합니다. FirstAnalysisResult = TryandCountresult (Comuters, Human, Computerpoint, Zhong); computerpoint.setx (x) .sety (y); if (firstAnalysisResult! = null) {// 체스를 죽으십시오. AddTofirstanalysisResult (FirstAnalysisResult, ComputerFirstresults); } // 전방 OBLIQUE FIRDNALYSISRESULT = TRYANDCOUNTRESULT (COMUTERS, HUMANS, COMPUTERPOINT, ZHENG_XIE); computerpoint.setx (x) .sety (y); if (firstAnalysisResult! = null) {// Dead Chess, (FirstAnalysisResult.count = 5) ComputerPoint를 반환하는 경우 재생하지 마십시오. AddTofirstanalysisResult (FirstAnalysisResult, ComputerFirstresults); } // Backside FirstAnalysisResult = tryandCountresult (Comuters, Humans, Computerpoint, Fan_xie); computerpoint.setx (x) .sety (y); if (firstAnalysisResult! = null) {// Dead Chess, (FirstAnalysisResult.count = 5) ComputerPoint를 반환하는 경우 재생하지 마십시오. AddTofirstanalysisResult (FirstAnalysisResult, ComputerFirstresults); } // 적의 라이브 라이브 3, 반 생물 4 등과 같은 "수평"방향으로 적의이 조각의 상태를 분석하십시오. FirstAnalysionResult = tryandcountresult (인간, 코미터, 컴퓨터 포인트, heng); computerpoint.setx (x) .sety (y); if (firstAnalysisResult! = null) {// Die Chess, (FirstAnalysisResult.count == 5) humanpoint = computerpoint; AddTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); } // "long-perendicular"firstAnalysisResult = tryandCountresult (인간, comuters, computerpoint, Zhong); computerpoint.setx (x) .sety (y); if (firstAnalysisResult! = null) {// Die Chess, (FirstAnalysisResult.count = 5) humanpoint = computerpoint; AddTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); } // "전진"FirstanalysisResult = tryandCountresult (인간, Comuters, Computerpoint, Zheng_Xie); computerpoint.setx (x) .sety (y); if (firstAnalysisResult! = null) {// Die Chess, (FirstAnalysisResult.count = 5) humanpoint = computerpoint; AddTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); } // "backslash"firstAnalysisResult = tryandCountresult (인간, comuters, computerpoint, fan_xie); computerpoint.setx (x) .sety (y); if (firstAnalysisResult! = null) {// Die Chess, (FirstAnalysisResult.count = 5) humanpoint = computerpoint; AddTofirstanalysisResult (FirstAnalysisResult, HumanFirstresults); }} // 승리가없는 경우 첫 번째 분석은 첫 번째 분석 결과를 반환 할 필요가 없습니다. } // 두 번째 분석, 첫 번째 형성의 결과를 분석하면 첫 번째 분석 결과는 최대 4 개의 FirstAnalysionResult 객체 (4 개의 적 및 서로)를 생성합니다. // 네 객체는 Sencondanalysisresult 객체, 개인 지점 docompupersencondanalysis (map <point, list <firstAnalysisResult >> firstresults, list <sencondanalysisresult> sencodResults)로 결합해야합니다. sencondanalysisresult sr = null; for (point p : firstresults.keyset ()) {sr = new sencondanalysisresult (p); list = firstresults.get (p); for (fordAnalysisResult result : list) {if (result.count == 4) {if (result.alivestate == alive) {// 이전 필터링 후 양측은 궁극적 인 킬을 배제했습니다. 4가 있다면이 단계를 수행하고 다음 단계에서 승리하십시오. result.point; // 최종 킬이 있으면 첫 번째 라운드가 돌아 왔습니다. 이 라운드에서 4 라운드에서는 이미 좋은 조각이며 직접 돌아와 더 이상 분석하지 않습니다} else {sr.halfalive4 ++; computer4halfalives.add (sr); }} else if (result.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는 첫 번째 단계에서 제외되었으며 더 이상 처리되지 않은 sr.alive2 ++; if (sr.alive2 == 1) {computer2alives.add (sr); } else {computerdouble2alives.add (sr); }}}} sencodresults.add (sr); } // 라이브 4는 발견되지 않았습니다. 널 리턴; } //이 방법은 기본적으로 위와 동일하지만 성능의 경우 판단력이 적고 인간과 컴퓨터를 분리합니다. 개인 지점 DohumanSenconDanalysis (Map <Point, List <FirstAnalysisResult >> firstresults, list <sencondanalysisresult> sencodresults) {list <firstanalysult> list = null; sencondanalysisresult sr = null; for (point p : firstresults.keyset ()) {sr = new sencondanalysisresult (p); list = firstresults.get (p); for (firstAnalysisResult result : list) {if (result.count == 4) {if (result.alivestate == alive) {human4alives.add (sr); } else {sr.halfalive4 ++; human4halfalives.add (sr); }} else if (result.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); } // 라이브 4가 발견되지 않았습니다. } private void sleep (int minisecond) {try {thread.sleep (minisecond); } catch (InterpruptedException e) {}} // 세 번째 분석, 어느 쪽도 살아있는 4를 만들 수없고, 이중 라이브 3 조각을 찾을 수없고, 그렇지 않은 경우 4 번을 찾으십시오. } system.gc (); 수면 (300); collections.sort (computersencodresults); System.gc (); // 나는 4 살이 되려고합니다. 반 생명 4 명 이상이 없으므로 대부분을 차단할 수 있습니다. if (mostbest! = null)가 가장 많은 것을 반환합니다. Collections.SORT (HumanSencoDresults); System.gc (); mostbest = getbestpoint (); if (mostbest! = null)가 가장 많은 것을 반환합니다. // 첫 번째 것을 꺼내면 더 나은 사람은 computersencodresults.get (0) .point; } // 서브 클래스는이 방법을 구현하고 방어 지향 또는 공격 지점을 달성하기위한 순서를 변경합니다. if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getbestpoint (Computer3alives, HumansenCodresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getBestPoint (HumanDouble3alives, ComputerSencoDresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getBestPoint (Human3alives, ComputerSencoDresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getBestPoint (ComputerDouble2alives, HumansenCodresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getBestPoint (Computer2alives, HumansenCodresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getbestpoint (Computer3halfalives, Humansencodresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getbestpoint (Human4halfalives, computernsencodresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getBestPoint (HumanDouble2alives, computernsencodresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getBestPoint (Human2alives, ComputerSencoDresults); if (mostbest! = null)가 가장 많은 것을 반환합니다. mostbest = getbestpoint (Human3halfalives, computernsencodresults); Mostbest를 반환합니다. } // 세 번째 분석의 마지막 단계, 두 번째 결과는 정렬되었습니다. 여기서는 전면 보호 지점에서 최고의 체스 조각을 선택할 수 있습니다. 귀하의 : YoursEncodResults) {if (myBest.contains (Your)) {return Your.point; }} return mybest.get (0) .Point; } else {return mybest.get (0) .Point; }} return null; } // 첫 번째 분석 결과 개인 최종 맵 <point, list <firstAnalysisResult >> computerFirstresults = new Hashmap <point, list <firstAnalysisResult >> (); 개인 최종지도 <포인트, 목록 <firstAnalysisResult >> humanfirstresults = new Hashmap <point, list <firstAnalysisResult >> (); // 두 번째 전체 결과 보호 된 최종 목록 <SencondAnalysisResult> ComputerSenCodResults = New ArrayList <SencondAnalysisResult> (); 보호 된 최종 목록 <SencondAnalysisResult> HumanSencoDresults = New ArrayList <SencondAnalysisResult> (); 보호 된 최종 목록 <SencondAnalysisResult> (); // 두 번째 결과는 컴퓨터 보호 최종 목록 <SencondAnalysisResult> Computer4halfalives = New ArrayList <SencondAnalysisResult> (2)입니다. 보호 된 최종 목록 <SencondAnalysisResult> ComputerDouble3alives = New ArrayList <SencondAnalysisResult> (4); 보호 된 최종 목록 <SencondAnalysisResult> Computer3alives = New Arraylist <SencondanalysisResult> (5); 보호 된 최종 목록 <SencondAnalysisResult> Computer3alives = New Arraylist <SencondanalysisResult> (5); 보호 된 최종 목록 <SencondAnalysisResult> ComputerDouble2alives = New ArrayList <SencondAnalysisResult> (); 보호 된 최종 목록 <SencondAnalysisResult> Computer2alives = New ArrayList <SencondAnalysisResult> (); 보호 된 최종 목록 <SencondAnalysisResult> Computer3halfalives = New ArrayList <SencondAnalysisResult> (); // 두 번째 결과는 인간 보호 최종 목록 <SencondAnalysisResult> Human4alives = New ArrayList <SencondAnalysisResult> (2)입니다. 보호 된 최종 목록 <SencondanalysisResult> Human4halfalives = New Arraylist <SencondanalysisResult> (5); 보호 된 최종 목록 <SencondAnalysisResult> HumanDouble3alives = New ArrayList <SencondAnalysisResult> (2); 보호 된 최종 목록 <SencondanalysisResult> Human3alives = New Arraylist <SencondanalysisResult> (10); 보호 된 최종 목록 <SencondAnalysisResult> HumanDouble2alives = New ArrayList <SencondAnalysisResult> (3); 보호 된 최종 목록 <SencondAnalysisResult> Human2alives = New ArrayList <SencondAnalysisResult> (); 보호 된 최종 목록 <SencondAnalysisResult> Human3halfalives = New ArrayList <SencondAnalysisResult> (); // 첫 번째 분석 이전에 이전 부분을 지우는 분석 결과 개인 무효 InitAnalysisResults () {computerfirstresults.clear (); HumanFirstresults.clear (); // 두 번째 총 결과 ComputerSenCodResults.clear (); humansencodresults.clear (); // 두 번째 결과 computer4halfalives.clear (); computerdouble3alives.clear (); computer3alives.clear (); computerdouble2alives.clear (); computer2alives.clear (); computer3halfalives.clear (); computer3alives.clear (); computerdouble2alives.clear (); computer2alives.clear (); computer3halfalives.clear (); // 두 번째 결과는 human4alives.clear ()입니다. Human4halfalives.clear (); humandouble3alives.clear (); Human3alives.clear (); humandouble2alives.clear (); human2alives.clear (); Human3halfalives.clear (); System.gc (); } // 첫 번째 분석 결과 개인 void addtofirstanalysisresult (FirstAnalysisResult result, map <point, list <firstAnalysisResult >> dest) {if (dest.containskey (result.point)) {dest.get (result.get) .add (result); } else {list <firstAnalysisResult> list = new ArrayList <DestanalysisResult> (1); list.add (결과); dest.put (result.point, list); }} // 첫 번째 분석 결과 클래스 개인 클래스 퍼스트 앤 알라 슈즈 룰 {// 연속 카운트; // 포인트 포인트 포인트; // 방향 int 방향; // State int alivestate; private firstanalysisresult (int count, point point, int direction) {this (count, point, direction, alive); } private firstAnalysisResult (int count, point point, int direction, int alivestate) {this.count = count; this.point = point; 이것은 방향 = 방향; this.alivestate = alivestate; } private firstanalysisResult init (포인트 포인트, int 방향, int alivestate) {this.count = 1; this.point = point; 이것은 방향 = 방향; this.alivestate = alivestate; 이것을 반환하십시오; } private firstAnalysisResult cloneme () {return new firstAnalysisResult (수, 포인트, 방향, invivestate); }} // SecondAnalysisResult는 비슷한 <sencondanalysisresult> {int alive4 = 0; // 살아있는 3 int alive3 = 0; // Secondliving 4, 씰의 한쪽 끝 int halfalive4 = 0; // Secondliving 3, 씰의 한쪽 끝 int halfalive3 = 0; // 살아있는 2 수량 int alive2 = 0; // 포인트 포인트; @override public int hashcode () {Final int Prime = 31; int result = 1; result = prime * result + ((point == null)? 0 : point.hashcode ()); 반환 결과; } @override public boolean equals (Object obj) {sencondanalysisresult 기타 = (SencondanalysisResult) obj; if (point == null) {if (기타 .point! = null) false를 반환합니다. } else if (! point.equals (기타 .point)) false를 반환합니다. 진실을 반환하십시오. } private sencondanalysisresult (포인트 포인트) {this.point = point; } // 세 번째 분석 중에 두 번째 분석 결과가 정렬됩니다. 이것은 정렬 콜백 함수 @override public int compareto (sencondanalysisresult other) {return comparetowresult (this, 다른); }} // return -1이 첫 번째 매개 변수 인 경우 1은 두 번째 매개 변수이고 0은 첫 번째 매개 변수이고 0은 원래 순서 비교에서 개인 int int (sencondanalysisresult oneresult, sencondanalysisresult other) {if (oneresult.alive4> eleas.alive4) {return -1; } if (oneresult.alive4 <exer.alive4) {return 1; } if (oneresult.alive4> exer.alive4) {return -1; } if (oneresult.alive3> exer.alive3) {return -1; } if (oneresult.alive3 <exer.alive3) {return 1; } if (oneresult.alive2> exer.alive2) {return -1; } if (oneresult.alive2 <exer.alive2) {return 1; } if (oneresult.alive3> exer.alive3) {return -1; } if (oneresult.alive3> exer.alive3) {return 1; } 반환 0; } // 임시 객체는 첫 번째 분석 중에 분석 결과를 일시적으로 저장하는 데 사용됩니다. 1 (제외) 결과가있는 경우 결과를 얻기 위해 Cloneme 방법이 호출됩니다. 그렇지 않으면,이 결과는 개인 최종 FirstAnalysisresult Far = New FirstAnalysisResult (1, NULL, HENG)로 폐기됩니다. // 분석 서브가 현재 위치 옆에있는 경우 특정 방향으로 얼마나 많은 서브가 형성 될 것인지. 매개 변수 : 현재 측면에 배치 된 모든 점, 가정 해야하는 포인트, Private FirstAnalysisResult TryandCountresult (List <point> myPoints, List <point> Empoints, Point Point, int Direction) {int x = point.getx (); int y = point.gety (); FirstAnalysisResult fr = null; int maxCountOnThisDirection = maxCountOnThisDiperection (포인트, 적군, 방향, 1); if (maxCountonThisDirection <5) {// 무의미한 체스 조각은 널 리턴 리턴 널 리턴; //이 방향에는 5 개의 빈 공간이 있으며 이미 설정 한 체스 조각은 제외됩니다} else (maxCountOnThisDipection == 5) {// 하프 데드 상태 (1 렌트 FR = FAR.init). } else {// 양쪽 끝은 fr = far.init (포인트, 방향, 살아있는)입니다. } // COUNTPOINT 계산 (MyPoints, Enemypoints, Point.setx (x) .sety (y), Fr, Direction, Forward); Countpoint (MyPoints, Empoints, Point.setx (x) .sety (y), Fr, Direction, Backward); if (fr.count <= 1 || (fr.count == 2 && fr.alivestate == Half_Alive)) {// realive1, semi-active2 및 다음 결과, 버려진 반환 null; } // 복사 결과를 반환합니다. return fr.cloneme (); } // 체스 조각은 벽에서 나옵니다. 개인 부울 isoutsideofwall (포인트 포인트, int 방향) {if (direction == heng) {return point.getx () <0 || point.getx ()> = maxx; // 최대 x와 y 값은 벽 밖에 있으므로 동일한 부호를 사용하십시오} else if (direction == Zhong) {return point.gety () <0 || point.gety ()> = maxy; } else {// 여기에 문제가있을 수 있습니다. return.getx () <0 || point.gety () <0 || point.gety () <0 || point.gety () <0 || point.gety () <0 || point.getx ()> = maxx || point.gety ()> = maxy; }} private point pointtonext (포인트 포인트, int 방향, 부울 앞) {switch (direction) {case heng : if (porowd) x ++; else point.x-; 부서지다; Case Zhong : if (앞으로) point.y ++; else point.y-; 부서지다; CASE ZHENG_XIE : if (Forward) {point.x ++; Point.y-; } else {point.x-; point.y ++; } 부서지다; CASE FAN_XIE : if (Forward) {Point.x ++; point.y ++; } else {point.x-; Point.y-; } 부서지다; } 반환 지점; } // 특정 방향으로 얼마나 많은 조각을 재생할 수 있는지 (8 개 중 하나). 이 메소드는 첫 번째 분석 개인 무효 카운트 포인트 (list <point> mypoints, list <point> Empoints, Point Point, intanalysisresult fr, int direction, boolean forward) {if (myPoints.contains (pointTonext (point, direction, forward)) {fr.count ++; if (myPoints.contains (pointTonext (point, direction, forward))) {fr.count ++; if (myPoints.contains (pointTonext (point, direction, forward))) {fr.count ++; if (myPoints.contains (pointTonext (point, direction, forward))) {fr.count ++; } else if (empoints.contains (point) || isoutsideofwall (point, direction)) {fr.alivestate = half_alive; }} else if (empoints.contains (point) || isoutsideofwall (point, direction)) {fr.alivestate = half_alive; }} else if (empoints.contains (point, direction)) {fr.alivestate = half_alive; }} else if (empoints.contains (point) || isoutsideofwall (point, direction)) {fr.alivestate = half_alive; }} else if (empoints.contains (point) || isoutsideofwall (point, direction)) {fr.alivestate = half_alive; }} // 여전히 특정 방향으로 5 개의 조각을 얻을 수 있습니까? private int maxCountOnThisDirection (point point, list <point> inverypoints, int direction, int count) {int x = point.getx (), y = point.gety (); switch (Direction) {// 수평 케이스 heng : while (! empoints.contains (point.setx (point.getx () -1)) && point.getx ()> = 0 && count <6) {count ++; } point.setx (x); while (! empoints.contains (point.setx (point.getx ()+1)) && point.getx () <maxx && count <6) {count ++; } 부서지다; // 수 말입물 케이스 Zhong : while (! empoints.contains (point.sety (point.gety () -1)) && point.gety ()> = 0) {count ++; } point.sety (y); while (! empoints.contains (point.sety (point.gety ()+1)) && point.gety () <maxy && count <6) {count ++; } 부서지다; // 전방 경사/case zheng_xie : while (! empoints.contains (point.setx (point.getx () -1) .sety (point.gety ()+1)) && point.getx ()> = 0 && point.gety () {maxy) {count ++; } point.setx (x) .sety (y); while (! empoints.contains (point.setx (point.getx ()+1) .sety (point.gety () -1)) && point.getx () <maxx && point.gety ()> = 0 && count <6) {count ++; } 부서지다; // backSlash/case fan_xie : while (! empoints.contains (point.setx (point.getx () -1) .sety (point.gety () -1)) && point.getx ()> = 0 && point.gety () {count ++; } point.setx (x) .sety (y); while (! empoints.contains (point.setx (point.getx ()+1) .sety (point.gety ()+1)) && point.getx () <maxx && point.gety () <maxy && count <6) {count ++; } 부서지다; } 반환 수; } // 체스 조각, 외부 인터페이스 @override public void run (list <point> 인간, point p) {// 인간의 마지막 단계를 allfreepoints.remove (humans.get (humans.size ()-1)); // 컴퓨터의 한 단계는 포인트 결과 = doanalysis (myPoints, Humans)를 만들 수 있습니다. // 컴퓨터에서 체스 조각을 제거합니다. // 컴퓨터 체스 조각에 추가하고 myPoints.add (result)를 재생합니다. }} 인간 플레이어를 구현하는 것은 매우 쉽습니다
Java.util.list 가져 오기; Public Class HumanPlayer는 BasePlayer를 확장합니다. allfreepoints.remove (p); }}
요약 : Java로 작성되었지만 알고리즘은 추상화되었으며 다양한 플랫폼의 구현으로 쉽게 수정할 수 있습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.