📄 4049dcf993fb001c1573b62be8af1246
字号:
package com.sans.ninemen.core;
import java.util.ArrayList;
/**
* The class MM contains the logic for MiniMax Algorithm. To get a minimax move for a given board
* position call getMaxMove()function.
* @author sanshack
*
*/
public class MM {
public static String maxChild;
public static long numEstimation=0;
public static long maxEstimate =0;
public static boolean gameStatus=true;
/**
* This function would return a Mini Max move.
* @param initialPosition
* @param totaldepth
* @param mode
* @return move
*/
public String getMaxMove(String initialPosition,int totaldepth,int mode) {
MaxMin(initialPosition,0,totaldepth,mode);
if(maxChild==null)maxChild=initialPosition;
System.out.println("Board Position: "+maxChild);
System.out.println("Positions Evaluated by static estimation:"+numEstimation);
System.out.println("MINIMAX estimate="+maxEstimate);
ArrayList<String> childList1 = new ArrayList<String>();
childList1 = GenerateMoves(maxChild,totaldepth,'B',1);
int numBlackMoves =childList1.size();
int value = StaticEstimator.midEndGameEstimator(maxChild, numBlackMoves);
if(value <= -10000 && mode==1){
System.out.println("You won");
} else if(value >= 10000 && mode==1) {
System.out.println("I won");
}
return maxChild;
}
/**
*
* Recursive Max Min function
* @param x
* @param depth
* @param totaldepth
* @param mode
* @return Max value
*/
public int MaxMin(String x,int depth,int totaldepth,int mode) {
int numWhite = Utility.countChar(x, 'W');
int numBlack = Utility.countChar(x, 'B');
ArrayList<String> childList1 = new ArrayList<String>();
childList1 = GenerateMoves(x,depth,'B',mode);
int numBlackMoves =childList1.size();
ArrayList<String> childList2 = new ArrayList<String>();
childList2 = GenerateMoves(x,depth,'B',mode);
int numWhiteMoves =childList2.size();
if(depth==totaldepth || ((mode==1)&&((numWhite<=2) || (numBlack<=2) ||(numWhiteMoves==0)))) {
numEstimation++;
if(mode==1) {
int value=StaticEstimator.midEndGameEstimator(x,numBlackMoves);
return value;
} else {
return StaticEstimator.defaultEstimator(x);
}
}
else {
int v =-100000;
ArrayList<String> childList = GenerateMoves(x,depth,'W',mode);
java.util.Iterator iter = childList.iterator();
while(iter.hasNext()) {
String childString = (String)iter.next();
int var = MinMax(childString,depth+1,totaldepth,mode);
if(var > v) {
if(depth==0) {
maxChild = childString;
//System.out.println(maxChild+" "+depth);
maxEstimate = var;
}
v = var;
}
}
return v;
}
}
public int max(int x ,int y) {
if(x > y) return x;
return y;
}
/**
* Recursive MinMax function
* @param x
* @param depth
* @param totaldepth
* @param mode
* @return Min value
*/
public int MinMax(String x,int depth,int totaldepth,int mode) {
if(depth==totaldepth) {
numEstimation++;
//System.out.println("numblackmoves start");
ArrayList<String> childList1 = GenerateMoves(x,depth,'B',mode);
//System.out.println("numblackmoves end");
int numBlackMoves =childList1.size();
if(mode==1) {
int value=StaticEstimator.midEndGameEstimator(x,numBlackMoves);
return value;
} else {
return StaticEstimator.defaultEstimator(x);
}
}
else {
int v =1000000;
ArrayList<String> childList = GenerateMoves(x,depth,'B',mode);
java.util.Iterator iter = childList.iterator();
while(iter.hasNext()) {
String childString = (String)iter.next();
int var = MaxMin(childString,depth+1,totaldepth,mode);
if(var < v) {
v = var;
}
}
return v;
}
}
/**
* Generate a moves in a list.
* @param x
* @param depth - depth to traverse the tree
* @param color - generate moves of which color
* @param mode - 0 for opening 1 for midend game
* @return List of moves
*/
public ArrayList<String> GenerateMoves(String x,int depth,char color,int mode) {
ArrayList<String> list;
if(mode==0) {
list = GenerateMovesOpening(x,depth,color);
}else {
list = GenerateMovesMidEndGame(x,depth,color);
}
return list;
}
/**
* Generate a moves in a list for mid end game.
* @param x
* @param depth - depth to traverse the tree
* @param color - generate moves of which color
* @param mode - 0 for opening 1 for midend game
* @return List of moves
*/
public ArrayList<String> GenerateMovesMidEndGame (String x,int depth,char color) {
//System.out.println("i am here");
int numWhite=Utility.countChar(x, 'W');
int numBlack=Utility.countChar(x, 'B');
ArrayList<String> list=null;
if((numWhite == 3 && color =='W')||(numBlack==3 && color=='B')) {
list= GenerateHopping(x,depth,color);
} else {
list= GenerateMove(x,depth,color);
}
if(list == null) {System.out.println("null for list");}
return list;
}
public ArrayList<String> GenerateMovesOpening(String x,int depth,char color) {
ArrayList<String> list = GenerateAdd(x,depth,color);
return list;
}
/**
* Generate a moves in a list for opening.
* @param x
* @param depth - depth to traverse the tree
* @param color - generate moves of which color
* @param mode - 0 for opening 1 for midend game
* @return List of moves
*/
public ArrayList<String> GenerateMove(String x,int depth,char color) {
ArrayList<String> list= new ArrayList<String>();
for(int i=0;i<Constants.BOARD_LENGTH;i++) {
char temp = x.charAt(i);
if(temp == color) {
int[] n = getNeighbors(i);
for(int k=0;k<4;k++) {
int j=n[k];
if(j!=-1) {
if(x.charAt(j)=='x') {
char[] charArray = new char[23];
charArray = x.toCharArray();
charArray[i]='x';
charArray[j]=color;
String tempString = String.valueOf(charArray);
if(closeMill(j,tempString,color)) {
generateRemove(tempString,list,color);
} else {
//System.out.println("Generate mov:adding "+tempString);
list.add(tempString);
}
}
}
}
}
}
return list;
}
/**
* Generate a moves in a list for end game.
* @param x
* @param depth - depth to traverse the tree
* @param color - generate moves of which color
* @param mode - 0 for opening 1 for midend game
* @return List of moves
*/
public ArrayList<String> GenerateHopping(String x,int depth,char color) {
ArrayList<String> list= new ArrayList<String>();
for(int j=0;j<Constants.BOARD_LENGTH;j++) {
if(x.charAt(j)==color) {
for(int i=0;i<Constants.BOARD_LENGTH;i++) {
char temp = x.charAt(i);
if(temp == 'x') {
char[] charArray = new char[23];
charArray = x.toCharArray();
charArray[j]='x';
charArray[i]=color;
String tempString = String.valueOf(charArray);
if(closeMill(i,tempString,color)) {
generateRemove(tempString,list,color);
} else {
//System.out.println("Generate hop:adding "+tempString);
list.add(tempString);
}
}
}
}
}
return list;
}
/**
* Generate a moves in a list by adding pieces of specified color at vacant spaces .
* @param x
* @param depth - depth to traverse the tree
* @param color - generate moves of which color
* @return List of moves
*/
public ArrayList<String> GenerateAdd(String x,int depth,char color) {
//System.out.println("i am here in add");
ArrayList<String> list= new ArrayList<String>();
for(int i=0;i<Constants.BOARD_LENGTH;i++) {
char temp = x.charAt(i);
if(temp == 'x') {
char[] charArray = new char[23];
charArray = x.toCharArray();
charArray[i]=color;
String tempString = String.valueOf(charArray);
if(closeMill(i,tempString,color)) {
generateRemove(tempString,list,color);
} else {
//System.out.println("Generate add:adding: "+tempString);
list.add(tempString);
}
}
}
return list;
}
/**
* Generate list of moves possible by removing the desired piece
* @param b
* @param list
* @param color
*/
public void generateRemove(String b,ArrayList<String> list,char color) {
int count=0;
if(color=='B') {
color='W';
}else {
color='B';
}
for(int i=0;i<b.length();i++) {
if(b.charAt(i)==color) {
if(!closeMill(i,b,color)) {
char[] charArray = new char[23];
charArray = b.toCharArray();
charArray[i]='x';
String tempString = String.valueOf(charArray);
//System.out.println("Generate rem:adding "+tempString);
list.add(tempString);
count++;
}
}
}
if(count==0) {
list.add(b);
}
}
/**
* Checks to see if the addition of current piece closes a mill
* @param index
* @param b
* @param compChar
* @return
*/
public boolean closeMill(int index,String b,char compChar) {
boolean flag=false;
switch(index) {
case 0:
if((b.charAt(8)==compChar && b.charAt(20)==compChar)
||(b.charAt(1)==compChar&&b.charAt(2)==compChar)
||(b.charAt(3)==compChar&&b.charAt(6)==compChar)) {
flag=true;
}
break;
case 1:
if(b.charAt(0)==compChar&&b.charAt(2)==compChar)
{
flag=true;
break;
}
break;
case 2:
if((b.charAt(13)==compChar&&b.charAt(22)==compChar)
||(b.charAt(1)==compChar&&b.charAt(0)==compChar)
||(b.charAt(7)==compChar&&b.charAt(5)==compChar)) {
flag=true;
break;
}
break;
case 3:
if((b.charAt(0)==compChar&&b.charAt(6)==compChar)
||(b.charAt(9)==compChar&&b.charAt(17)==compChar)
||(b.charAt(4)==compChar&&b.charAt(5)==compChar)) {
flag=true;
break;
}
break;
case 4:
if((b.charAt(3)==compChar&&b.charAt(5)==compChar))
{
flag=true;
break;
}
break;
case 5:
if((b.charAt(3)==compChar&&b.charAt(4)==compChar)
||(b.charAt(19)==compChar&&b.charAt(12)==compChar)
||(b.charAt(7)==compChar&&b.charAt(2)==compChar)) {
flag=true;
break;
}
break;
case 6:
if((b.charAt(10)==compChar&&b.charAt(14)==compChar)
||(b.charAt(0)==compChar&&b.charAt(3)==compChar))
{
flag=true;
break;
}
break;
case 7:
if((b.charAt(5)==compChar&&b.charAt(2)==compChar)
||(b.charAt(11)==compChar&&b.charAt(16)==compChar))
{
flag=true;
break;
}
break;
case 8:
if((b.charAt(10)==compChar&&b.charAt(9)==compChar)
||(b.charAt(0)==compChar&&b.charAt(20)==compChar))
{
flag=true;
break;
}
break;
case 9:
if((b.charAt(8)==compChar&&b.charAt(10)==compChar)
||(b.charAt(3)==compChar&&b.charAt(17)==compChar))
{
flag=true;
break;
}
break;
case 10:
if((b.charAt(8)==compChar&&b.charAt(9)==compChar)
||(b.charAt(6)==compChar&&b.charAt(14)==compChar))
{
flag=true;
break;
}
break;
case 11:
if((b.charAt(12)==compChar&&b.charAt(13)==compChar)
||(b.charAt(16)==compChar&&b.charAt(7)==compChar))
{
flag=true;
break;
}
break;
case 12:
if((b.charAt(19)==compChar&&b.charAt(5)==compChar)
||(b.charAt(13)==compChar&&b.charAt(11)==compChar))
{
flag=true;
break;
}
break;
case 13:
if((b.charAt(22)==compChar&&b.charAt(2)==compChar)
||(b.charAt(12)==compChar&&b.charAt(11)==compChar))
{
flag=true;
break;
}
break;
case 14:
if((b.charAt(20)==compChar&&b.charAt(17)==compChar)
||(b.charAt(15)==compChar&&b.charAt(16)==compChar)
||(b.charAt(10)==compChar&&b.charAt(6)==compChar)) {
flag=true;
break;
}
break;
case 15:
if((b.charAt(18)==compChar&&b.charAt(21)==compChar)
||(b.charAt(14)==compChar&&b.charAt(16)==compChar))
{
flag=true;
break;
}
break;
case 16:
if((b.charAt(14)==compChar&&b.charAt(15)==compChar)
||(b.charAt(19)==compChar&&b.charAt(22)==compChar)
||(b.charAt(7)==compChar&&b.charAt(11)==compChar)) {
flag=true;
break;
}
break;
case 17:
if((b.charAt(20)==compChar&&b.charAt(14)==compChar)
||(b.charAt(18)==compChar&&b.charAt(19)==compChar)
||(b.charAt(3)==compChar&&b.charAt(9)==compChar)) {
flag=true;
break;
}
break;
case 18:
if((b.charAt(21)==compChar&&b.charAt(15)==compChar)
||(b.charAt(19)==compChar&&b.charAt(17)==compChar))
{
flag=true;
break;
}
break;
case 19:
if((b.charAt(12)==compChar&&b.charAt(5)==compChar)
||(b.charAt(16)==compChar&&b.charAt(22)==compChar)
||(b.charAt(17)==compChar&&b.charAt(18)==compChar)) {
flag=true;
break;
}
break;
case 20:
if((b.charAt(0)==compChar&&b.charAt(8)==compChar)
||(b.charAt(21)==compChar&&b.charAt(22)==compChar)
||(b.charAt(17)==compChar&&b.charAt(14)==compChar)) {
flag=true;
break;
}
break;
case 21:
if((b.charAt(18)==compChar&&b.charAt(15)==compChar)
||(b.charAt(20)==compChar&&b.charAt(22)==compChar))
{
flag=true;
break;
}
break;
case 22:
if((b.charAt(20)==compChar&&b.charAt(21)==compChar)
||(b.charAt(13)==compChar&&b.charAt(2)==compChar)
||(b.charAt(16)==compChar&&b.charAt(19)==compChar)) {
flag=true;
break;
}
break;
}
return flag;
}
/**
* Returns the list of neighbors of a node
* @param i
* @return list of neighbors
*/
public int[] getNeighbors(int i) {
switch(i) {
case 0:
int n0[]= {1,3,8,-1};
return (n0);
case 1:
int n1[]= {0,4,2,-1};
return (n1);
case 2:
int n2[]= {1,5,13,-1};
return (n2);
case 3:
int n3[]= {0,4,9,6};
return (n3);
case 4:
int n4[]= {3,5,1,-1};
return (n4);
case 5:
int n5[]= {7,4,2,12};
return (n5);
case 6:
int n6[]= {10,7,3,-1};
return (n6);
case 7:
int n7[]= {6,11,5,-1};
return (n7);
case 8:
int n8[]= {0,9,20,-1};
return (n8);
case 9:
int n9[]= {8,10,3,17};
return (n9);
case 10:
int n10[]= {9,6,14,-1};
return (n10);
case 11:
int n11[]= {16,7,12,-1};
return (n11);
case 12:
int n12[]= {11,13,5,19};
return (n12);
case 13:
int n13[]= {12,2,22,-1};
return (n13);
case 14:
int n14[]= {17,10,15,-1};
return (n14);
case 15:
int n15[]= {14,16,18,-1};
return (n15);
case 16:
int n16[]= {15,11,19,-1};
return (n16);
case 17:
int n17[]= {14,20,9,18};
return (n17);
case 18:
int n18[]= {17,19,15,21};
return (n18);
case 19:
int n19[]= {18,22,12,16};
return (n19);
case 20:
int n20[]= {8,21,17,-1};
return (n20);
case 21:
int n21[]= {20,18,22,-1};
return (n21);
case 22:
int n22[]= {19,13,21,-1};
return (n22);
}
int defaulta[]= {-1,-1,-1,-1};
return(defaulta);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -