خوارزمية Goziqi AI هي أيضًا خوارزمية نموذجية منظمة العفو الدولية. يمكن استخدام بعض خوارزميات الشطرنج AI كمرجع. فيما يلي رمز تنفيذ Java.
واجهة تجريدية الشطرنج
استيراد java.util.list ؛ الواجهة العامة ichessboard {// احصل على الحد الأقصى من الإحداثي الأفقي للمجلس العام int getMaxx () ؛ // الحد الأقصى للإحداثي العمودي العام int getMaxy () ؛ // احصل على جميع النقاط الفارغة الحالية ، ولا }تنفيذ فئة الشطرنج
// نقطة فئة الشطرنج {// هذا هو الأداء ، الذي تم تعيينه على int x ؛ الجمهور int y ؛ public int getx () {return x ؛ } النقطة العامة setx (int x) {this.x = x ؛ إرجاع هذا ؛ } public int gety () {return y ؛ } النقطة العامة sety (int y) {this.y = y ؛ إرجاع هذا ؛ } النقطة العامة (int x ، int y) {this.x = x ؛ this.y = y ؛ } Override public int hashcode () {return x + y ؛ } Override Public Boolean يساوي (كائن OBJ) {if (this == obj) إرجاع true ؛ نقطة أخرى = (نقطة) OBJ ؛ إذا (x! = other.x) إرجاع خطأ ؛ إذا (y! = others.y) العودة خطأ ؛ العودة صحيح. }} واجهة تجريد لاعب
استيراد java.util.list ؛ الواجهة العامة iplayer {// الخطوة التالية هي تمرير مجموعة الألواح الشطرنج التي قام بها الخصم بالفعل بتعيين تشغيل الفراغ العام (قائمة <Point> EnemyPoints ، Point Point) ؛ منطقية عامة هاسوين () ؛ public void setChessboard (Ichessboard Chessboard) ؛ القائمة العامة <point> getMypoints () ؛ } فئة التجريد الأساسية اللاعب
استيراد java.util.arraylist ؛ استيراد java.util.list ؛ Public Class Class BasePlayer تنفذ iPlayer {// قطعة الشطرنج التي وضعتها في قائمة محمية <Point> myPoints = new ArrayList <Point> (200) ؛ // شطرنج الشطرنج المحمي الشطرنج. // أقصى إحداثيات أفقية ورأسية للوحة محمية 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 () ؛ } temp final point temp = new point (0 ، 0) ؛ // هل فزت بنهائي عام Boolean Haswin () {if (mypoints.size () <5) {return false ؛ } point = mypoints.get (mypoints.size ()-1) ؛ عدد int = 1 ؛ int x = point.getx () ، y = point.gety () ؛ // الأفقي- temp.setx (x) .sety (y) ؛ بينما (mypoints.contains (temp.setx (temp.getx ()-1)) && temp.getx ()> = 0 && count <5) {count ++ ؛ } if (count> = 5) {return true ؛ } temp.setx (x) .sety (y) ؛ بينما (mypoints.contains (temp.setx (temp.getx ()-1)) && temp.getx ()> = 0 && count <5) {count ++ ؛ } if (count> = 5) {return true ؛ } temp.setx (x) .sety (y) ؛ بينما (mypoints.contains (temp.setx (temp.getx ()+1)) && temp.getx () <maxx && count <5) {count ++ ؛ } if (count> = 5) {return true ؛ } // عمودي | العد = 1 ؛ temp.setx (x) .sety (y) ؛ بينما (mypoints.contains (temp.sety (temp.gety ()-1)) && temp.gety ()> = 0) {count ++ ؛ } if (count> = 5) {return true ؛ } temp.setx (x) .sety (y) ؛ بينما (mypoints.contains (temp.sety (temp.gety ()-1)) && temp.gety ()> = 0) {count ++ ؛ } if (count> = 5) {return true ؛ } temp.setx (x) .sety (y) ؛ بينما (mypoints.contains (temp.sety (temp.gety ()+1)) && temp.gety () <maxy && count <5) {count ++ ؛ } if (count> = 5) {return true ؛ } // forward spulque/count = 1 ؛ temp.setx (x) .sety (y) ؛ بينما (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) ؛ بينما (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) ؛ بينما (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) ؛ بينما (mypoints.contains (temp.setx (temp.getx ()+1) .sety (temp.gety ()+1)) } if (count> = 5) {return true ؛ } إرجاع خطأ ؛ }} تطبيق AI Computer
استيراد java.util.arraylist ؛ استيراد java.util.collections ؛ استيراد java.util.hashmap ؛ استيراد java.util.list ؛ استيراد java.util.map ؛ // الفئة الأساسية من الخوارزمية ، تنقسم الفكرة الرئيسية للخوارزمية إلى ثلاث خطوات. // الخطوة الأولى: تفترض دوريًا النتيجة لنفسه والطرف الآخر (لتحقيق درجة ضمن نطاق معين) وفقًا للوضع الحالي لكلا الطرفين ، والحكم على التغييرات في الموقف الذي يمكن أن تحضره هذه القطعة ، مثل ما إذا كان يمكن أن تستعجل 4 ، أو ما إذا كان يمكن أن تشكل عدونا أو عدونا 3 ، وما إلى ذلك. نسميها نصف مباشر 4) ، وما إلى ذلك) ، بما في ذلك العدو وجانبنا. // الخطوة 3: فرز النتيجة السابقة وفقًا للقواعد التي قدمها المستخدم وتحديد الأشكال الفرعية والدفاعية (هناك قواعد للأشكال الهجومية والدفاعية) يمتد الطبقة العامة من الطبقة العامة {// أربعة اتجاهات ، أفقي - ، عمودي | ، الأم إلى الأمام / ، الخلفي الهروب / الأساسي الأساسي النهائي int heng = 0 ؛ استاتيكي خاص int Zhong = 1 ؛ int static int zheng_xie = 2 ؛ خاص ثابت نهائي int fan_xie = 3 ؛ // من الأمام إلى الظهر الأساسي الثابت النهائي إلى الأمام = صحيح ؛ خاص ثابت نهائي نهائي للخلف = خطأ ؛ // عرض نتيجة التحليل. سواء كانت النقطة الحالية عبارة عن تمريرة من نهايتها (على قيد الحياة) أو تمريرة واحدة فقط (Half_alive) ، يتم حظر عملية تحليل قطعة الشطرنج المحظورة تلقائيًا ، وليس كقطعة شطرنج لاختيارها نهائية ثابتة خاصة بـ int على قيد الحياة = 1 ؛ خاص ثابت نهائي int half_alive = 0 ؛ // private static final 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 ؛ }} // الحد من نطاق حساب الكمبيوتر. إذا كان أداء حساب لوحة الشطرنج بأكمله ضعيفًا للغاية ، فسيتم تشكيله حاليًا بناءً على القيمة الحدودية لجميع قطع الشطرنج التي تم استخدامها. وهو حاليًا واحد ثابت واحد ثابت int int_step = 1 ؛ calcuterange currentRange = new calcuterange (0 ، 0 ، 0 ، 0) ؛ private void interrange (قائمة <point> cooters ، قائمة <point> البشر) {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 ؛ لـ (Point Point: Humans) {if (point.getx ()-range_step <currentRange.xstart) {currentRange.xstart = point.getx ()-range_step ؛ } آخر 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 ؛ } آخر if (point.gety ()+range_step> currentRange.ystop) {currentRange.ystop = point.gety ()+range_step ؛ }} لـ (نقطة النقطة: cooters) {if (point.getx ()-range_step <currentRange.xstart) {currentRange.xStart = point.getx ()-range_step ؛ } آخر 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 ؛ } آخر if (point.gety ()+range_step> currentRange.ystop) {currentRange.ystop = point.gety ()+range_step ؛ }} // إذا تم توسيع النطاق وتجاوز لوح الشطرنج ، فهو يساوي لوحة الشطرنج 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 ؛ } // تحليل الشكل الحالي لطريقة الدخول. ينقسم التحليل إلى ثلاث خطوات في المجموع. يمكن التحكم في الخطوة الثالثة بواسطة فئات فرعية لصعوبة. Private Point doanalysis (قائمة <POINT> COOTERS ، قائمة <POINT> البشر) {if (Humans.size () == 1) {// تعيد الخطوة الأولى getFirstPoint (البشر) ؛ } // تهيئة نطاق الحساب interrange (comuters ، البشر) ؛ // مسح النتائج السابقة initAnalysInsults () ؛ . if (BestPoint! = null) {//system.out.println("this قطعة الأهم ، يمكنك فقط تشغيل هذه القطعة ") ؛ العودة BestPoint ؛ } // تحليل النتيجة الأولى وابحث عن أفضل نقطة لديك = doComputersenCondanalysis (ComputerFirstresults ، computersencodresults) ؛ if (BestPoint! = null) {//system.out.println("i'm على وشك الفوز ، سألعب هذه القطعة ") ؛ العودة BestPoint ؛ } computerfirstresults.clear () ؛ System.gc () ؛ // تحليل النتيجة الأولى وابحث عن أفضل نقطة في BestPoint العدو = dohumansencondanalysis (HumanFirstresults ، Humansencodresults) ؛ if (BestPoint! = null) {//system.out.println("f عدم تشغيل هذه القطعة ، ستفقد ") ؛ العودة BestPoint ؛ } humanfirstresults.clear () ؛ System.gc () ؛ // لم يتم العثور على نقطة قتل نهائية ، أعاد تحليل النتيجة الثالثة dothirdanalysis () ؛ } // لا تتطلب الخطوة الأولى من قطعة الشطرنج حسابات معقدة ، ويتم إكمالها بناءً على قيمة X للخطوة الأولى البشرية من قطعة الشطرنج. نقطة خاصة getFirstPoint (قائمة <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 // START التحليل ، ومسح جميع النقاط الفارغة ، وتشكيل أول نتيجة التحليل النقطة الخاصة dofirstanalysis (قائمة <POINT> COOLES ، قائمة <POINT> البشر) {int size = allfreepoints.size () ؛ Point ComputerPoint = null ؛ نقطة humanpoint = null ؛ int x ، y ؛ FERENALYSERSERTULT FERSANALYSERSULT ؛ لـ (int i = 0 ؛ i <size ؛ i ++) {computerPoint = allfreepoints.get (i) ؛ // انقر فوق الإحداثيات X و Y أولاً ، لأنه سيتم تغيير الكائن الأصلي أثناء عملية التحليل x = computerpoint.getx () ؛ y = computerpoint.gety () ؛ if (x <currentrange.xstart || x> currentRange.xstop || y <currentRange.ystart || y> currentRange.ystop) {conter ؛ } // if (x == debugx && y == debugy) {// system.out.println ("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS) {متابعة ؛ System.out.println ("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS) {//} // حاول أن تضع قطعة شطرنج في هذا الموقف وتحليل الولايات المتحدة فقط في" Horizontal ". = TryAndCountresult (Comuters ، Humans ، ComputerPoint ، Heng) ؛ computerpoint.setx (x) .sety (y) ؛ // الرد على القيمة الأصلية للنقطة للتحليل التالي إذا (festanalysisressult! = null) {// no return ، فمن المستحيل الوصول إلى خمس قطع شطرنج في هذا الاتجاه. إذا كان (FirstAnalysicResult.count == 5) // يساوي 5 يعني أنه يمكنك لعب قطع الشطرنج في هذه المرحلة ويمكنك الاتصال بـ 5. إذا فزت ، فلن تقوم بتحليلها. إرجاع ComputerPoint ؛ // سجل أول نتيجة تحليل AddTofiRstanalyStuls (Firstanalysisressult ، computerfirstresults) ؛ } // كرر الخطوات المذكورة أعلاه في "الاتجاه الرأسي" festanalysisrult = tryAndCountresult (comuters ، البشر ، كمبيوتر ، Zhong) ؛ ComputerPoint.setx (x) .sety (y) ؛ if (firstanalySresult! = NULL) {// Die the Chess ، لا تلعب إذا (festAnalySresult.count == 5) إرجاع ComputerPoint ؛ AddtofiRstanalysisResult (FirstanalysicResult ، computerfirstresults) ؛ } // forward firstanalysisresult = tryAndCountResult (comuters ، البشر ، proberpoint ، zheng_xie) ؛ ComputerPoint.setx (x) .sety (y) ؛ if (firstanalysingResult! = null) {// dead chess ، لا تلعب إذا (festanalysicResult.count == 5) إرجاع ComputerPoint ؛ AddtofiRstanalysisResult (FirstanalysicResult ، computerfirstresults) ؛ } // Backside Firstanalysisressult = tryAndCountresult (comuters ، humans ، computerpoint ، fan_xie) ؛ ComputerPoint.setx (x) .sety (y) ؛ if (firstanalysingResult! = null) {// dead chess ، لا تلعب إذا (festanalysicResult.count == 5) إرجاع ComputerPoint ؛ AddtofiRstanalysisResult (FirstanalysicResult ، computerfirstresults) ؛ } // تحليل حالة هذه القطعة في العدو في الاتجاه "الأفقي" ، مثل العدو Live 3 ، و Semi-Living 4 ، إلخ. ComputerPoint.setx (x) .sety (y) ؛ if (firstanalysicResult! = null) {// die chess ، لا تلعب إذا (festanalysresult.count == 5) HumanPoint = ComputerPoint ؛ addtofirstanalysisresult (Firstanalysisult ، HumanFirstresults) ؛ } // "long-pendiculy" festanalysisrult = tryAndCountresult (البشر ، comuters ، computerpoint ، Zhong) ؛ ComputerPoint.setx (x) .sety (y) ؛ if (firstanalysicResult! = null) {// die chess ، لا تلعب إذا (festAnalySresult.count == 5) HumanPoint = ComputerPoint ؛ addtofirstanalysisresult (Firstanalysisult ، HumanFirstresults) ؛ } // "forward-slant" firstanalysisult = tryAndCountresult (البشر ، comuters ، computerpoint ، zheng_xie) ؛ ComputerPoint.setx (x) .sety (y) ؛ if (firstanalysicResult! = null) {// die chess ، لا تلعب إذا (festAnalySresult.count == 5) HumanPoint = ComputerPoint ؛ addtofirstanalysisresult (Firstanalysisult ، HumanFirstresults) ؛ } // "backslash" festanalysisrult = tryAndCountresult (البشر ، comuters ، computerpoint ، fan_xie) ؛ ComputerPoint.setx (x) .sety (y) ؛ if (firstanalysicResult! = null) {// die chess ، لا تلعب إذا (festAnalySresult.count == 5) HumanPoint = ComputerPoint ؛ addtofirstanalysisresult (Firstanalysisult ، HumanFirstresults) ؛ }} // إذا لم يكن هناك قطعة رابحة ، فإن التحليل الأول لا يحتاج إلى إعادة نتيجة التحليل الأول ؛ } // التحليل الثاني ، تحليل نتيجة التكوين الأول ، ستولد نتيجة التحليل الأولى ما يصل إلى أربعة كائنات فيرستانيسريولت (أربعة أعداء وبعضهم البعض). // يجب دمج الكائنات الأربعة في كائن sencondanalysicResult ، النقطة الخاصة doComputersenCondanalysis (MAP <Point ، List <FirstAnalyStResult >> firstresults ، list <sencondanalyStResult> sencodresults) {list <siranalysisresult> list = null ؛ sencondanalysisresult sr = null ؛ لـ (Point P: firstresults.keyset ()) {sr = new sencondanalysisressult (p) ؛ قائمة = firstresults.get (p) ؛ لـ (FirstAnalysicResult Result: List) {if (result.count == 4) {if (result.alivestate == Alive) {// بعد التصفية السابقة ، استبعد كلا الجانبين القتل النهائي. إذا كان هناك 4 ، خذ هذه الخطوة ، واربح الخطوة التالية. النتيجة. // إذا كان هناك قتل نهائي ، فقد عادت الجولة الأولى. في هذه الجولة من 4 عبارة عن قطعة جيدة بالفعل ، ارجع مباشرة ولم تعد تحليلها} {sr.halfalive4 ++ ؛ computer4halfalives.add (sr) ؛ }} آخر if (result.count == 3) {if (result.alivestate == Alive) {sr.alive3 ++ ؛ if (sr.alive3 == 1) {computer3alives.add (sr) ؛ } آخر {computerDouble3Alives.add (sr) ؛ }} آخر {sr.halfalive3 ++ ؛ computer3halfalives.add (sr) ؛ }} تم استبعاد {// semi-live 2 في المرحلة الأولى ولم يعد معالجته sr.alive2 ++ ؛ if (sr.alive2 == 1) {computer2alives.add (sr) ؛ } آخر {computerDouble2Alives.add (sr) ؛ }}}} sencodresults.add (sr) ؛ } // لم يتم العثور على Live 4 ؛ العودة لاغية. } // هذه الطريقة هي نفسها على النحو الوارد أعلاه ، ولكن بالنسبة للأداء ، فهي أقل حكمًا ، ويفصل البشر وأجهزة الكمبيوتر الخاصة بنقطة خاصة dohumansencondanalysis (الخريطة <point ، قائمة <presanalysultruult >> firstresults ، قائمة <sencondanalysisresultsultsults) sencondanalysisresult sr = null ؛ لـ (Point P: firstresults.keyset ()) {sr = new sencondanalysisressult (p) ؛ قائمة = firstresults.get (p) ؛ لـ (FirstAnalyStResult Result: List) {if (result.count == 4) {if (result.alivestate == Alive) {human4alives.add (sr) ؛ } آخر {sr.halfalive4 ++ ؛ Human4Halfalives.Add (SR) ؛ }} آخر if (result.count == 3) {if (result.alivestate == Alive) {sr.alive3 ++ ؛ if (sr.alive3 == 1) {human3alives.add (sr) ؛ } آخر {humandouble3alives.add (sr) ؛ }} آخر {sr.halfalive3 ++ ؛ Human3Halfalives.Add (SR) ؛ }} آخر {sr.alive2 ++ ؛ if (sr.alive2 == 1) {human2alives.add (sr) ؛ } آخر {humandouble2alives.add (sr) ؛ }}} sencodresults.add (sr) ؛ } // no live 4 تم العثور على عودة فارغة ؛ } private void sleep (int minisecond) {try {thread.sleep (minisecond) ؛ } catch (interruptedException e) {}} // التحليل الثالث ، لا يمكن لأي من الجانبين إنشاء Live 4 ، والعثور على 3 قطع Live 3 ، إذا لم يكن الأمر كذلك ، ابحث عن Half Live 4 ، إذا لم يكن ، ابحث عن Live 3 ، Double Live 2 point dothirdanalysis () {if (! } system.gc () ؛ النوم (300) ؛ collections.sort (ComputerSencodResults) ؛ System.gc () ؛ // أنا على وشك أن أعيش 4 ، وليس لدي نصف معيشة 4 أو أكثر ، لذلك لا يمكنني فقط منع MostBest = getBestPoint (Human4alives ، ComputerSencodResults) ؛ إذا (mostbest! = null) العودة mostbest ؛ collections.sort (Humansencodresults) ؛ System.gc () ؛ MostBest = getBestPoint () ؛ إذا (mostbest! = null) العودة mostbest ؛ // أخرج الأول ، وأي شخص أفضل سيعيد ComputerSencodResults.get (0). } // تنفذ الفئة الفرعية هذه الطريقة ويغير أمرها لتحقيق النقطة المحمية الموجه نحو الدفاع أو المهاجمة GetBestPoint () {// أنا على وشك أن أعيش 4 ، وليس لديّ نصف معيشة 4 أو أكثر ، لذلك لا يمكنني فقط منع MostBest = getBestPoint (ComputerDouble3Alives ، HumansencodresultStults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Computer3alives ، HumansenCodresults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Humandouble3Alives ، ComputerSenCodresults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Human3Alives ، ComputerSencodResults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (ComputerDouble2Alives ، HumansenCodresults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Computer2alives ، HumansenCodresults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Computer3halfalives ، HumansenCodresults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Human4halfalives ، computersencodresults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Humandouble2alives ، ComputerSencodResults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Human2alives ، ComputerSenCodresults) ؛ إذا (mostbest! = null) العودة mostbest ؛ MostBest = getBestPoint (Human3Halfalives ، ComputerSenCodresults) ؛ العودة أكثر } // الخطوة الأخيرة من التحليل الثالث ، تم فرز النتيجة الثانية ، هنا يمكنك تحديد أفضل قطعة شطرنج من نقطة GetBestPoint الأمامية (قائمة <sencondanalysisResult> mybest ، قائمة <sencondanalyStResult> yoursencondresult) {if (! mybest.isempty () yoursencodresults) {if (mybest.contains (your)) {return your.point ؛ }} إرجاع mybest.get (0) .point ؛ } آخر {return myBest.get (0) .point ؛ }} الإرجاع null ؛ } // النتيجة الأولى لتحليل الخريطة النهائية الخاصة <point ، قائمة <VeranalysicResult >> computerfirstresults = new hashmap <point ، list <foranalysicResult >> () ؛ الخريطة النهائية الخاصة <point ، قائمة <presanalysisressult >> humanfirstresults = new hashmap <point ، قائمة <presanalysisrult >> () ؛ . القائمة النهائية المحمية <SenconDanalysicResult> HumansencodResults = ArrayList جديد <sencondanalysisressult> () ؛ القائمة النهائية المحمية <sencondanalysicResult> () ؛ // النتيجة الثانية هي أن القائمة النهائية المحمية للكمبيوتر <sencondanalysicResult> computer4halfalives = new ArrayList <SenconDanalysicResult> (2) ؛ القائمة النهائية المحمية <SenconDanalysicResult> ComputerDouble3Alives = new ArrayList <sencondanalysisressult> (4) ؛ القائمة النهائية المحمية <SenconDanalysicResult> computer3alives = new ArrayList <SenconDanalysicResult> (5) ؛ القائمة النهائية المحمية <SenconDanalysicResult> computer3alives = new ArrayList <SenconDanalysicResult> (5) ؛ القائمة النهائية المحمية <SenconDanalysicResult> ComputerDouble2Alives = new ArrayList <sencondanalysicResult> () ؛ القائمة النهائية المحمية <SenconDanalysicResult> Computer2Alives = new ArrayList <SenconDanalysicResult> () ؛ القائمة النهائية المحمية <SenconDanalysicResult> computer3halfalives = new ArrayList <sencondanalysicResult> () ؛ // النتيجة الثانية هي ، القائمة النهائية المحمية البشرية <sencondanalysicResult> human4alives = new ArrayList <SenconDanalysicResult> (2) ؛ القائمة النهائية المحمية <SenconDanalysicResult> human4halfalives = new ArrayList <sencondanalysicResult> (5) ؛ القائمة النهائية المحمية <SenconDanalysicResult> Humandouble3Alives = ArrayList جديد <sencondanalysisressult> (2) ؛ القائمة النهائية المحمية <SenconDanalysicResult> Human3Alives = new ArrayList <SenconDanalysisressult> (10) ؛ القائمة النهائية المحمية <SenconDanalysicResult> Humandouble2Alives = ArrayList جديد <sencondanalysisressult> (3) ؛ القائمة النهائية المحمية <SenconDanalysicResult> human2alives = new ArrayList <SenconDanalysicResult> () ؛ القائمة النهائية المحمية <SenconDanalysicResult> Human3Halfalives = ArrayList جديد <sencondanalysisressult> () ؛ . 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 () ؛ } // أضف إلى أول نتيجة للتحليل الناتجة عن private void addtofirstanalysisrult (نتيجة FestAnalySresult ، الخريطة <point ، قائمة <presanalysicResult >> dest) {if (dest.containskey (result.point)) {dest.get (result.point) .add (result) ؛ } آخر {list <SteranalyStResult> list = new ArrayList <SteranalysicResult> (1) ؛ list.add (النتيجة) ؛ dest.put (result.point ، list) ؛ }} // التحليل الأول فئة الفئة الخاصة بالفئة الخاصة festanalysisrult {// counture count ؛ // نقطة نقطة ؛ // اتجاه الاتجاه ؛ // الدولة int alivestate ؛ PrivateAnalysisResult (عدد int ، نقطة ، الاتجاه int) {هذا (العد ، النقطة ، الاتجاه ، على قيد الحياة) ؛ } privateanalysisResult (عدد int ، نقطة نقطة ، الاتجاه int ، int alivestate) {this.count = count ؛ this.point = point ؛ this.direction = الاتجاه ؛ this.alivestate = alivestate ؛ } private fersanalysisresult init (point point ، int direction ، int alivestate) {this.count = 1 ؛ this.point = point ؛ this.direction = الاتجاه ؛ this.alivestate = alivestate ؛ إرجاع هذا ؛ } private fersanalysisultult cloneme () {return NewAnalysisResult (count ، point ، direction ، alivestate) ؛ }} // secondanalysisresult تنفذ قابلة للمقارنة <sencondanalysisResult> {int alive4 = 0 ؛ // living 3 int alive3 = 0 ؛ // secondliving 4 ، نهاية واحدة من الختم int halfalive4 = 0 ؛ // secondliving 3 ، نهاية واحدة من الختم int halfalive3 = 0 ؛ // Living 2 Quantity Int Alive2 = 0 ؛ // نقطة نقطة ؛ Override public int hashcode () {Final int prime = 31 ؛ int النتيجة = 1 ؛ النتيجة = prime * result + ((point == null)؟ 0: point.hashCode ()) ؛ نتيجة العودة } Override public boolean يساوي (كائن obj) {sencondanalysisResult Other = (sencondanalysisresult) obj ؛ if (point == null) {if (other.point! = null) return false ؛ } آخر إذا (! point.equals (other.point)) إرجاع خطأ ؛ العودة صحيح. } sencondanalysisresult (point point) {this.point = point ؛ } // خلال التحليل الثالث ، يتم فرز نتائج التحليل الثاني. هذه هي وظيفة Callback Protect Override Public int (sencondanalysisresult أخرى) }} // إذا كانت العائد -1 هي المعلمة الأولى ، فإن 1 هي المعلمة الثانية هي الأولى ، و 0 هي int int الخاصة في المقارنة الأصلية للترتيب (sencondanalysisresult oneresult ، sencondanalysisrult other) {if (oneresult.alive4> alay.alive4) {return -1 ؛ } if (oneresult.alive4 <anhare.alive4) {return 1 ؛ } if (oneresult.alive4> anher.alive4) {return -1 ؛ } if (oneresult.alive3> other.alive3) {return -1 ؛ } if (oneresult.alive3 <anhare.alive3) {return 1 ؛ } if (oneresult.alive2> analy.alive2) {return -1 ؛ } if (oneresult.alive2 <anhare.alive2) {return 1 ؛ } if (oneresult.alive3> other.alive3) {return -1 ؛ } if (oneresult.alive3> anher.alive3) {return 1 ؛ } العودة 0 ؛ } // يتم استخدام كائن مؤقت لتخزين نتائج التحليل مؤقتًا أثناء التحليل الأول. إذا كان هناك أكثر من نتائج واحدة (باستثناء) ، يتم استدعاء طريقة Cloneme للحصول على النتيجة. خلاف ذلك ، سيتم التخلص من هذه النتيجة النهائية الخاصة في FirstAnalysisult Far = NewAnalysisResult (1 ، Null ، Heng) ؛ // التحليل إذا كان Sub بجوار الموضع الحالي ، فكم عدد الغواصات التي سيتم تشكيلها في اتجاه معين. المعلمات: جميع النقاط التي تم وضعها على الجانب الحالي ، والنقطة التي يجب افتراضها ، والاتجاه الذي يجب الحكم عليه في FERSANALYSERSERSULT TRAINANDCOUNTRESULT (قائمة <POINT> MEPOINTS ، قائمة <POINT> ENEMYPOINTS ، POINT POINT ، Int Direction) {int x = point.getx () ؛ int y = point.gety () ؛ FersanalysisResult FR = NULL ؛ int maxcountonthisdirection = maxcountonthisdirection (point ، enemypoints ، Direction ، 1) ؛ إذا كان (maxcountonthisdirection <5) {// عودة قطعة شطرنج عديمة المعنى فارغة ؛ } آخر {// كلا الطرفين هما fr = far.init (نقطة ، الاتجاه ، على قيد الحياة) ؛ } // حساب countpoint (mypoints ، enemypoints ، point.setx (x) .sety (y) ، fr ، الاتجاه ، إلى الأمام) ؛ CountPoint (MyPoints ، enemypoints ، point.setx (x) .sety (y) ، fr ، الاتجاه ، للخلف) ؛ if (fr.count <= 1 || (fr.count == 2 && fr.alivestate == half_alive)) {// realive1 ، semi-active2 والنتائج التالية ، التخلي عن الإرجاع null ؛ } // إرجاع نتيجة نسخ الإرجاع fr.cloneme () ؛ }. point.getx ()> = maxx ؛ // أقصى قيم x و y تكون خارج الجدار ، لذا استخدم العلامة المتساوية} if (Direction == Zhong) {return point.gety () <0 || point.gety ()> = maxy ؛ } آخر {// قد تكون هناك مشكلة هنا return Point.getx () <0 || point.gety () <0 || point.gety () <0 || point.gety () <0 || point.gety () <0 || point.getx ()> = maxx || point.gety ()> = maxy ؛ }} prope pointtonext (point point ، int direction ، boolean forward) {switch (direction) {case heng: if (forward) point.x ++ ؛ آخر point.x-- ؛ استراحة؛ قضية Zhong: if (إلى الأمام) point.y ++ ؛ point.y-- ؛ استراحة؛ Case Zheng_xie: if (إلى الأمام) {point.x ++ ؛ point.y-- ؛ } آخر {point.x-- ؛ point.y ++ ؛ } استراحة؛ case fan_xie: if (إلى الأمام) {point.x ++ ؛ point.y ++ ؛ } آخر {point.x-- ؛ point.y-- ؛ } استراحة؛ } نقطة العودة ؛ } // كم عدد القطع التي يمكن لعبها في اتجاه معين (واحد من ثمانية). هذه الطريقة هي الطريقة الأساسية في التحليل الأول CountPoint private void (قائمة <Point> MePoints ، قائمة <Point> enemypoints ، Point Point ، FestanalySresult 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 ++ ؛ } if if (inemypoints.contains (point) || isoutsideofwall (point ، direction)) {fr.alivestate = half_alive ؛ }} آخر إذا (enemypoints.contains (point) || isoutsideofwall (point ، direction)) {fr.alivestate = half_alive ؛ }} آخر إذا (inemypoints.contains (نقطة ، اتجاه)) {fr.alivestate = half_alive ؛ }} آخر إذا (enemypoints.contains (point) || isoutsideofwall (point ، direction)) {fr.alivestate = half_alive ؛ }} آخر إذا (enemypoints.contains (point) || isoutsideofwall (point ، direction)) {fr.alivestate = half_alive ؛ }} // هل لا يزال بإمكانك الحصول على خمس قطع في اتجاه معين int int maxcountonthisdirection (point point ، قائمة <Point> enemypoints ، الاتجاه int ، عدد int) {int x = point.getx () ، y = point.gety () ؛ Switch (Direction) {// Aptonizontal Case Heng: بينما (! enemypoints.contains (point.setx (point.getx ()-1)) && point.getx ()> = 0 && count <6) {count ++ ؛ } point.setx (x) ؛ بينما (! enemypoints.contains (point.setx (point.getx ()+1)) && point.getx () <maxx && count <6) {count ++ ؛ } استراحة؛ // case Zhong Zhong: بينما (! inemypoints.contains (point.sety (point.gety ()-1)) && point.gety ()> = 0) {count ++ ؛ } point.sety (y) ؛ بينما (! enemypoints.contains (point.sety (point.gety ()+1)) && point.gety () <maxy && count <6) {count ++ ؛ } استراحة؛ // إلى الأمام المائل/CASE ZHENG_XIE: بينما (! inemypoints.contains (point.setx (point.getx ()-1) .Sety (point.gety ()+1)) && point.getx ()> = 0 && point.gety () <maxy) {count ++ ؛ } point.setx (x) .sety (y) ؛ بينما (! enemypoints.contains (point.setx (point.getx ()+1) .sety (point.gety ()-1)) } استراحة؛ // backslash/case fan_xie: بينما (! inemypoints.contains (point.setx (point.getx ()-1) .Sety (point.gety ()-1)) && point.getx ()> = 0 && point.gety ()> = 0) {count ++ ؛ } point.setx (x) .sety (y) ؛ بينما (! enemypoints.contains (point.setx (point.getx ()+1) .sety (point.gety ()+1)) } استراحة؛ } عدد العائد ؛ } // play play chess pacts ، extrental interface Override public void run (list <point> humans ، point p) {// قم بإزالة الخطوة الأخيرة من الإنسان allfreepoints.remove (humans.get (humans.size ()-1)) ؛ // يمكن لخطوة واحدة من الكمبيوتر أن تجعل النقطة نتيجة = doanalysis (Mypoints ، البشر) ؛ // قم بإزالة قطع الشطرنج على الكمبيوتر allfreepoints.remove (النتيجة) ؛ // أضف إلى قطع شطرنج الكمبيوتر ولعب mypoints.add (النتيجة) ؛ }} من السهل جدًا تنفيذ اللاعبين البشر
استيراد java.util.list ؛ الطبقة العامة HumanPlayer يمتد BasePlayer {Override public void Run (قائمة <Point> enemypoints ، النقطة P) {getMypoints (). add (p) ؛ allfreepoints.remove (p) ؛ }}ملخص: على الرغم من أنه مكتوب في Java ، فقد تم استخلاص الخوارزمية ويمكن تعديلها بسهولة إلى تطبيقات مختلفة من المنصات.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.