/// <summary> /// update score table /// </summary> /// <param name="scoreTable"></param> /// <param name="col">columnIndex of new joined chess</param> /// <param name="row">rowIndex of new joined chess</param> private void UpdateScoreTable(ref IChessBoard chessBoard, Position pos,PieceTypeEnum pieceType) { //could not happen /* if (chessBoard.GetPointState(pos.Col,pos.Row)!=PointStateEnum.Blank) { return; } */ #region ---partial board //get all the 32 piece states surrounding this position ExtendedPointStateEnum[,] pointState=new ExtendedPointStateEnum[4,9]; int row,col; //horizontal for (col = pos.Col - 4; col < pos.Col + 5;col++) { if (col<0||col>14) { pointState[0,col-pos.Col+4]=ExtendedPointStateEnum.Virtual; } else { pointState[0, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(pos.Row,col); } } //vertical for (row = pos.Row - 4; row < pos.Row + 5;row++ ) { if (row<0||row>14) { pointState[1, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual; } else { pointState[1, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row,pos.Col); } } //backslash for (row = pos.Row - 4, col = pos.Col - 4; row < pos.Row + 5;row++,col++ ) { if (row < 0 || row > 14 || col < 0 || col > 14) { pointState[2, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual; } else { pointState[2, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row, col); } } //slash for (row = pos.Row + 4, col = pos.Col - 4; row > pos.Row - 5; row--, col++) { if (row < 0 || row > 14 || col < 0 || col > 14) { pointState[3, col - pos.Col + 4] = ExtendedPointStateEnum.Virtual; } else { pointState[3, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(col, col); } } //assume the center of partial board is empty for (int m = 0; m < 4;m++ ) { pointState[m, 4] = ExtendedPointStateEnum.Blank; } #endregion #region ---recognize formerTuples //recognize types of all the 20 Tuples . TupleType[,] formerTuples = new TupleType[4, 5]; TupleType[,] changedTuples = new TupleType[4, 5]; int white, black, blank; for (int i = 0; i < 4;i++ ) { int start=0; int finish = 0; //deal with virtual tuples from front for (int j = 0; j < 4;j++ ) { if (pointState[i,j]==ExtendedPointStateEnum.Virtual) { changedTuples[i,j] = formerTuples[i, j] = TupleType.Virtual; } else { start = j; break;//jump inner layer loop } } //deal with virtual tuples from back for (int j = 8; j >= 5;j-- ) { if (pointState[i, j] == ExtendedPointStateEnum.Virtual) { changedTuples[i, j-4] = formerTuples[i, j - 4] = TupleType.Virtual; } else { finish = j; break;//jump inner layer loop } } white = black = blank = 0; //start recognize general tuples,deal with first four points for (int j = start; j <start+4;j++ ) { if (pointState[i, j] == ExtendedPointStateEnum.Blank) { blank++; } else if (pointState[i, j] == ExtendedPointStateEnum.Black) { black++; } else if (pointState[i, j] == ExtendedPointStateEnum.White) { white++; } } //tuples recognition sliding for (int j = start + 4; j <= finish;j++ ) { if (pointState[i, j] == ExtendedPointStateEnum.Blank) { blank++; } else if (pointState[i, j] == ExtendedPointStateEnum.Black) { black++; } else if (pointState[i, j] == ExtendedPointStateEnum.White) { white++; } //deal with formerTuples if (black > 0 && white > 0) { formerTuples[i, j - 4] = TupleType.Polluted; } else if (black == 0 && white == 0) { formerTuples[i, j - 4] = TupleType.Blank; } else if (black == 0) { formerTuples[i, j - 4] = (TupleType)(white + 4); } else { formerTuples[i, j - 4] = (TupleType)black; } //deal with changedTuples,increase for change if (pieceType==PieceTypeEnum.Black) { black++; } else { white++; } //recognize if (black > 0 && white > 0) { changedTuples[i, j - 4] = TupleType.Polluted; } else if (black == 0 && white == 0) { changedTuples[i, j - 4] = TupleType.Blank; } else if (black == 0) { changedTuples[i, j - 4] = (TupleType)(white + 4); } else { changedTuples[i, j - 4] = (TupleType)black; } //deal with changedTuples,decrease if (pieceType == PieceTypeEnum.Black) { black--; } else { white--; } //slide to next tuple ,so the first of current tuple should be dropped if (pointState[i, j-4] == ExtendedPointStateEnum.Blank) { blank--; } else if (pointState[i, j-4] == ExtendedPointStateEnum.Black) { black--; } else if (pointState[i, j-4] == ExtendedPointStateEnum.White) { white--; } } } #endregion #region ---update scores of correlative points //score changed caused by this chess int[,] changedScore = new int[4, 5]; for (int i = 0; i < 4;i++ ) { for (int j = 0; j < 5;j++ ) { int score=tupleScoreTable[(int)changedTuples[i,j]]-tupleScoreTable[(int)formerTuples[i,j]]; changedScore[i, j] = score; } } //internal calculation int[,] changedScoreSum = new int[4, 9]; for (int i = 0; i < 4;i++ ) { for (int j = 0; j < 4;j++ ) { int sum=0; for (int m=0;m<=j;m++) { sum+=changedScore[i,m]; } changedScoreSum[i,j]=sum; } for (int j = 8; j > 4;j-- ) { int sum = 0; for (int m=8;m>=j;m--) { sum += changedScore[i, m-4]; } changedScoreSum[i, j] = sum; } } //update center point,occupied point's score is 0 scoreTable[pos.Col, pos.Row] = 0; //update general points //horizontal for (col = (pos.Col >= 4?pos.Col-4:0); col <= (pos.Col <=10?pos.Col+4:14); col++) { if (scoreTable[col,pos.Row]!=0)//not occupied { scoreTable[col, pos.Row] += changedScoreSum[0, col - pos.Col + 4]; if (scoreTable[col, pos.Row] < 0) { scoreTable[col, pos.Row] = 0; } } } //vertical for (row = (pos.Row >= 4 ? pos.Row - 4 : 0); row <= (pos.Row <= 10 ? pos.Row + 4 : 14); row++) { if (scoreTable[pos.Col, row] != 0)//not occupied { scoreTable[pos.Col, row] += changedScoreSum[1, row - pos.Row + 4]; if (scoreTable[pos.Col, row] < 0) { scoreTable[pos.Col, row] = 0; } } } //backslash for (col = (pos.Col >= 4 ? pos.Col - 4 : 0), row = (pos.Row >= 4 ? pos.Row - 4 : 0); col <= (pos.Col <= 10 ? pos.Col + 4 : 14) && row <= (pos.Row <= 10 ? pos.Row + 4 : 14); col++,row++) { if (scoreTable[col, row] != 0)//not occupied { scoreTable[col, row] += changedScoreSum[2, row - pos.Row + 4]; if (scoreTable[col, row]<0) { scoreTable[col, row] = 0; } } } //slash for (col = (pos.Col >= 4 ? pos.Col - 4 : 0), row = (pos.Row <= 10 ? pos.Row + 4 : 14); col <= (pos.Col <= 10 ? pos.Col + 4 : 14) && row >= (pos.Row >= 4 ? pos.Row - 4 : 0); col++, row--) { if (scoreTable[col, row] != 0)//not occupied { scoreTable[col, row] += changedScoreSum[3, col - pos.Col + 4]; if (scoreTable[col, row] < 0) { scoreTable[col, row] = 0; } } } #endregion }
/// <summary> /// update score table /// </summary> /// <param name="scoreTable"></param> /// <param name="col">columnIndex of new joined chess</param> /// <param name="row">rowIndex of new joined chess</param> private void UpdateScoreTable(ref IChessBoard chessBoard, Position pos, PieceTypeEnum pieceType) { //could not happen /* if (chessBoard.GetPointState(pos.Col,pos.Row)!=PointStateEnum.Blank) * { * return; * } */ #region ---partial board //get all the 32 piece states surrounding this position ExtendedPointStateEnum[,] pointState = new ExtendedPointStateEnum[4, 9]; int row, col; //horizontal for (col = pos.Col - 4; col < pos.Col + 5; col++) { if (col < 0 || col > 14) { pointState[0, col - pos.Col + 4] = ExtendedPointStateEnum.Virtual; } else { pointState[0, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(pos.Row, col); } } //vertical for (row = pos.Row - 4; row < pos.Row + 5; row++) { if (row < 0 || row > 14) { pointState[1, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual; } else { pointState[1, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row, pos.Col); } } //backslash for (row = pos.Row - 4, col = pos.Col - 4; row < pos.Row + 5; row++, col++) { if (row < 0 || row > 14 || col < 0 || col > 14) { pointState[2, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual; } else { pointState[2, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row, col); } } //slash for (row = pos.Row + 4, col = pos.Col - 4; row > pos.Row - 5; row--, col++) { if (row < 0 || row > 14 || col < 0 || col > 14) { pointState[3, col - pos.Col + 4] = ExtendedPointStateEnum.Virtual; } else { pointState[3, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(col, col); } } //assume the center of partial board is empty for (int m = 0; m < 4; m++) { pointState[m, 4] = ExtendedPointStateEnum.Blank; } #endregion #region ---recognize formerTuples //recognize types of all the 20 Tuples . TupleType[,] formerTuples = new TupleType[4, 5]; TupleType[,] changedTuples = new TupleType[4, 5]; int white, black, blank; for (int i = 0; i < 4; i++) { int start = 0; int finish = 0; //deal with virtual tuples from front for (int j = 0; j < 4; j++) { if (pointState[i, j] == ExtendedPointStateEnum.Virtual) { changedTuples[i, j] = formerTuples[i, j] = TupleType.Virtual; } else { start = j; break;//jump inner layer loop } } //deal with virtual tuples from back for (int j = 8; j >= 5; j--) { if (pointState[i, j] == ExtendedPointStateEnum.Virtual) { changedTuples[i, j - 4] = formerTuples[i, j - 4] = TupleType.Virtual; } else { finish = j; break;//jump inner layer loop } } white = black = blank = 0; //start recognize general tuples,deal with first four points for (int j = start; j < start + 4; j++) { if (pointState[i, j] == ExtendedPointStateEnum.Blank) { blank++; } else if (pointState[i, j] == ExtendedPointStateEnum.Black) { black++; } else if (pointState[i, j] == ExtendedPointStateEnum.White) { white++; } } //tuples recognition sliding for (int j = start + 4; j <= finish; j++) { if (pointState[i, j] == ExtendedPointStateEnum.Blank) { blank++; } else if (pointState[i, j] == ExtendedPointStateEnum.Black) { black++; } else if (pointState[i, j] == ExtendedPointStateEnum.White) { white++; } //deal with formerTuples if (black > 0 && white > 0) { formerTuples[i, j - 4] = TupleType.Polluted; } else if (black == 0 && white == 0) { formerTuples[i, j - 4] = TupleType.Blank; } else if (black == 0) { formerTuples[i, j - 4] = (TupleType)(white + 4); } else { formerTuples[i, j - 4] = (TupleType)black; } //deal with changedTuples,increase for change if (pieceType == PieceTypeEnum.Black) { black++; } else { white++; } //recognize if (black > 0 && white > 0) { changedTuples[i, j - 4] = TupleType.Polluted; } else if (black == 0 && white == 0) { changedTuples[i, j - 4] = TupleType.Blank; } else if (black == 0) { changedTuples[i, j - 4] = (TupleType)(white + 4); } else { changedTuples[i, j - 4] = (TupleType)black; } //deal with changedTuples,decrease if (pieceType == PieceTypeEnum.Black) { black--; } else { white--; } //slide to next tuple ,so the first of current tuple should be dropped if (pointState[i, j - 4] == ExtendedPointStateEnum.Blank) { blank--; } else if (pointState[i, j - 4] == ExtendedPointStateEnum.Black) { black--; } else if (pointState[i, j - 4] == ExtendedPointStateEnum.White) { white--; } } } #endregion #region ---update scores of correlative points //score changed caused by this chess int[,] changedScore = new int[4, 5]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 5; j++) { int score = tupleScoreTable[(int)changedTuples[i, j]] - tupleScoreTable[(int)formerTuples[i, j]]; changedScore[i, j] = score; } } //internal calculation int[,] changedScoreSum = new int[4, 9]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { int sum = 0; for (int m = 0; m <= j; m++) { sum += changedScore[i, m]; } changedScoreSum[i, j] = sum; } for (int j = 8; j > 4; j--) { int sum = 0; for (int m = 8; m >= j; m--) { sum += changedScore[i, m - 4]; } changedScoreSum[i, j] = sum; } } //update center point,occupied point's score is 0 scoreTable[pos.Col, pos.Row] = 0; //update general points //horizontal for (col = (pos.Col >= 4?pos.Col - 4:0); col <= (pos.Col <= 10?pos.Col + 4:14); col++) { if (scoreTable[col, pos.Row] != 0)//not occupied { scoreTable[col, pos.Row] += changedScoreSum[0, col - pos.Col + 4]; if (scoreTable[col, pos.Row] < 0) { scoreTable[col, pos.Row] = 0; } } } //vertical for (row = (pos.Row >= 4 ? pos.Row - 4 : 0); row <= (pos.Row <= 10 ? pos.Row + 4 : 14); row++) { if (scoreTable[pos.Col, row] != 0)//not occupied { scoreTable[pos.Col, row] += changedScoreSum[1, row - pos.Row + 4]; if (scoreTable[pos.Col, row] < 0) { scoreTable[pos.Col, row] = 0; } } } //backslash for (col = (pos.Col >= 4 ? pos.Col - 4 : 0), row = (pos.Row >= 4 ? pos.Row - 4 : 0); col <= (pos.Col <= 10 ? pos.Col + 4 : 14) && row <= (pos.Row <= 10 ? pos.Row + 4 : 14); col++, row++) { if (scoreTable[col, row] != 0)//not occupied { scoreTable[col, row] += changedScoreSum[2, row - pos.Row + 4]; if (scoreTable[col, row] < 0) { scoreTable[col, row] = 0; } } } //slash for (col = (pos.Col >= 4 ? pos.Col - 4 : 0), row = (pos.Row <= 10 ? pos.Row + 4 : 14); col <= (pos.Col <= 10 ? pos.Col + 4 : 14) && row >= (pos.Row >= 4 ? pos.Row - 4 : 0); col++, row--) { if (scoreTable[col, row] != 0)//not occupied { scoreTable[col, row] += changedScoreSum[3, col - pos.Col + 4]; if (scoreTable[col, row] < 0) { scoreTable[col, row] = 0; } } } #endregion }
public ChessBoardPoint GetNextStep(IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep? prevStep) { int[] tupleScoreTable = new int[11] { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //initialize tuple score table if (stepIndex % 2 == 0)//even step is first hand,i.e. the black side { if (stepIndex == 0) { return ChessBoardPoint.TENGEN; } else if(stepIndex==2) { Position[][] classicalOpen = new Position[8][]; //0:white is on left side of Tengen classicalOpen[0]=new Position[21]{ new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; //1:white is on up side of Tengen classicalOpen[1]=new Position[21]{ new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; //2:white is on right side of Tengen classicalOpen[2]=new Position[21]{ new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; //3:white is on bottom side of Tengen classicalOpen[3]=new Position[21]{ new Position(8,8),new Position(9,7),new Position(7,8),new Position(7,9), new Position(8,9),new Position(6,9),new Position(5,8),new Position(6,8), new Position(6,7),new Position(5,7),new Position(9,9),new Position(5,5), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; //4:white is on topleft corner of Tengen classicalOpen[4]=new Position[25]{ new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; //5:white is on topright corner of Tengen classicalOpen[5]=new Position[25]{ new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; //6:white is on bottomright corner of Tengen classicalOpen[6]=new Position[25]{ new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; //7:white is on bottomleft corner of Tengen classicalOpen[7] = new Position[25]{ new Position(6,6),new Position(7,5),new Position(7,6),new Position(6,5), new Position(8,5),new Position(6,8),new Position(9,5),new Position(7,9), new Position(5,5),new Position(5,6),new Position(7,8),new Position(5,8), new Position(5,9),new Position(8,5),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position(),new Position(),new Position(),new Position(), new Position()}; Position whiteFirst = new Position(14-prevStep.Value.Location.RowIndex, prevStep.Value.Location.ColumnIndex); switch () { case : break; } } tupleScoreTable[1] = 35; tupleScoreTable[2] = 800; tupleScoreTable[3] = 15000; tupleScoreTable[4] = 800000; tupleScoreTable[5] = 15; tupleScoreTable[6] = 400; tupleScoreTable[7] = 1800; tupleScoreTable[8] = 100000; } else//odd step is back hand,i.e. the white side { tupleScoreTable[1] = 15; tupleScoreTable[2] = 400; tupleScoreTable[3] = 1800; tupleScoreTable[4] = 100000; tupleScoreTable[5] = 35; tupleScoreTable[6] = 800; tupleScoreTable[7] = 15000; tupleScoreTable[8] = 800000; } //extended board,with virtual points ExtendedPointStateEnum[,] exPointStates = new ExtendedPointStateEnum[23, 23]; for (int row = 0; row < 23; row++) { for (int col = 0; col < 23; col++) { if (row < 4 || row > 18 || col < 4 || col > 18) { exPointStates[row, col] = ExtendedPointStateEnum.Virtual; } else { exPointStates[row, col] = (ExtendedPointStateEnum)chessBoard.GetPointState(14 - (row - 4), col - 4); } } } int[,] scoreTable = new int[15, 15]; /// <summary>calculate type of every tuple</summary> /// <description>In order to give a clear train of thought, /// I used an intuitionistic method to do this work. /// But this results in not efficient. /// Every tuple is calculated for twice. /// But it's easy to modify it:two ends of a tuple own the same tuple /// I'll modify it in next version ,where efficiency becomes bottleneck. /// </description> //every point indexs 8 tuples around it TupleType[, ,] tupleTable = new TupleType[15, 15, 8]; for (int row = 4; row < 19; row++) { for (int col = 4; col < 19; col++) { int[] white = new int[8];//white points in a tuple int[] black = new int[8];//black points in a tuple #region ---check tuples of every direction //left ,index 0 for (int i = 0; i < 5; i++) { if (exPointStates[row, col - i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 0] = TupleType.Virtual; break; } else if (exPointStates[row, col - i] == ExtendedPointStateEnum.Black) { black[0]++; } else if (exPointStates[row, col - i] == ExtendedPointStateEnum.White) { white[0]++; } } //top left,index 1 for (int i = 0; i < 5; i++) { if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 1] = TupleType.Virtual; break; } else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Black) { black[1]++; } else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.White) { white[1]++; } } //up ,index 2 for (int i = 0; i < 5; i++) { if (exPointStates[row - i, col] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 2] = TupleType.Virtual; break; } else if (exPointStates[row - i, col] == ExtendedPointStateEnum.Black) { black[2]++; } else if (exPointStates[row - i, col] == ExtendedPointStateEnum.White) { white[2]++; } } //top right,index 3 for (int i = 0; i < 5; i++) { if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 3] = TupleType.Virtual; break; } else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Black) { black[3]++; } else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.White) { white[3]++; } } //right,index 4 for (int i = 0; i < 5; i++) { if (exPointStates[row, col + i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 4] = TupleType.Virtual; break; } else if (exPointStates[row, col + i] == ExtendedPointStateEnum.Black) { black[4]++; } else if (exPointStates[row, col + i] == ExtendedPointStateEnum.White) { white[4]++; } } //bottom right,index 5 for (int i = 0; i < 5; i++) { if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 5] = TupleType.Virtual; break; } else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Black) { black[5]++; } else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.White) { white[5]++; } } //bottom,index 6 for (int i = 0; i < 5; i++) { if (exPointStates[row + i, col] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 6] = TupleType.Virtual; break; } else if (exPointStates[row + i, col] == ExtendedPointStateEnum.Black) { black[6]++; } else if (exPointStates[row + i, col] == ExtendedPointStateEnum.White) { white[6]++; } } //bottom left,index 7 for (int i = 0; i < 5; i++) { if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 7] = TupleType.Virtual; break; } else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Black) { black[7]++; } else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.White) { white[7]++; } } #endregion //check tuples of every direction //decide tuple type for (int i = 0; i < 8; i++) { //already assigned if (tupleTable[row - 4, col - 4, i] == TupleType.Virtual) { continue; } if (white[i] > 0 && black[i] > 0) { tupleTable[row - 4, col - 4, i] = TupleType.Polluted; } else if (white[i] == 0 && black[i] == 0) { tupleTable[row - 4, col - 4, i] = TupleType.Blank; } else if (white[i] == 0) { tupleTable[row - 4, col - 4, i] = (TupleType)black[i]; } else { tupleTable[row - 4, col - 4, i] = (TupleType)(white[i] + 4); } } } } #region ---scoreTable calculate //calculate score table . using symmetry //top left corner for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row >= m)//top right { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]];//bottom scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]];//bottom right scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]];//right } } } //top right corner for (int row = 0; row < 8; row++) { for (int col = 8; col < 15; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row >= m)//top left { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]];//bottom scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]];//bottom left scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]];//left } } } //bottom left corner for (int row = 8; row < 15; row++) { for (int col = 0; col < 8; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row + m < 15)//bottom right { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]];//top scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]];//top right scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]];//right } } } //bottom right corner for (int row = 8; row < 15; row++) { for (int col = 8; col < 15; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row + m < 15)//bottom left { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]];//top scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]];//top left scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]];//left } } } #endregion //scoreTable //select best position List<Position> bestList = new List<Position>(); //select first valid point Position first = new Position(0, 0); //all the point is forbidden.connot happen //while (IsFobidden(first)) //{ // while (IsFobidden(first)) // { // if (first.Col<14) // { // first.Col++; // } // else // { // break; // } // } // if (first.Row<14) // { // first.Row++; // } // else // { // break; // } //} while (IsFobidden(ref chessBoard, first, pieceType)) { if (first.Col < 14) { first.Col++; } else if (first.Row < 14) { first.Row++; first.Col = 0; } else { return new ChessBoardPoint(-1, -1); } } bestList.Add(first); Referee checkWin = new Referee(); //select best points for (int row = 0; row < 15; row++) { for (int col = 0; col < 15; col++) { if (scoreTable[row, col] > scoreTable[bestList[0].Row, bestList[0].Col]) { Position best = new Position(row, col); if (!IsFobidden(ref chessBoard, best, pieceType)) { bestList.Clear(); bestList.Add(best); } } else if (scoreTable[row, col] == scoreTable[bestList[0].Row, bestList[0].Col]) { Position best = new Position(row, col); if (!IsFobidden(ref chessBoard, best, pieceType)) { bestList.Add(best); } } } } //there is no best .connot happen if (bestList.Count == 0) { return new ChessBoardPoint(-1, -1); } Position ret = bestList[(new Random()).Next(bestList.Count)]; return new ChessBoardPoint(14 - ret.Row, ret.Col); }
public ChessBoardPoint GetNextStep(IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep?prevStep) { int[] tupleScoreTable = new int[11] { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //initialize tuple score table if (stepIndex % 2 == 0)//even step is first hand,i.e. the black side { if (stepIndex == 0) { return(ChessBoardPoint.TENGEN); } else if (stepIndex == 2) { Position[][] classicalOpen = new Position[8][]; //0:white is on left side of Tengen classicalOpen[0] = new Position[21] { new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; //1:white is on up side of Tengen classicalOpen[1] = new Position[21] { new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; //2:white is on right side of Tengen classicalOpen[2] = new Position[21] { new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; //3:white is on bottom side of Tengen classicalOpen[3] = new Position[21] { new Position(8, 8), new Position(9, 7), new Position(7, 8), new Position(7, 9), new Position(8, 9), new Position(6, 9), new Position(5, 8), new Position(6, 8), new Position(6, 7), new Position(5, 7), new Position(9, 9), new Position(5, 5), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; //4:white is on topleft corner of Tengen classicalOpen[4] = new Position[25] { new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; //5:white is on topright corner of Tengen classicalOpen[5] = new Position[25] { new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; //6:white is on bottomright corner of Tengen classicalOpen[6] = new Position[25] { new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; //7:white is on bottomleft corner of Tengen classicalOpen[7] = new Position[25] { new Position(6, 6), new Position(7, 5), new Position(7, 6), new Position(6, 5), new Position(8, 5), new Position(6, 8), new Position(9, 5), new Position(7, 9), new Position(5, 5), new Position(5, 6), new Position(7, 8), new Position(5, 8), new Position(5, 9), new Position(8, 5), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position(), new Position() }; Position whiteFirst = new Position(14 - prevStep.Value.Location.RowIndex, prevStep.Value.Location.ColumnIndex); switch () { case: break; } } tupleScoreTable[1] = 35; tupleScoreTable[2] = 800; tupleScoreTable[3] = 15000; tupleScoreTable[4] = 800000; tupleScoreTable[5] = 15; tupleScoreTable[6] = 400; tupleScoreTable[7] = 1800; tupleScoreTable[8] = 100000; } else//odd step is back hand,i.e. the white side { tupleScoreTable[1] = 15; tupleScoreTable[2] = 400; tupleScoreTable[3] = 1800; tupleScoreTable[4] = 100000; tupleScoreTable[5] = 35; tupleScoreTable[6] = 800; tupleScoreTable[7] = 15000; tupleScoreTable[8] = 800000; } //extended board,with virtual points ExtendedPointStateEnum[,] exPointStates = new ExtendedPointStateEnum[23, 23]; for (int row = 0; row < 23; row++) { for (int col = 0; col < 23; col++) { if (row < 4 || row > 18 || col < 4 || col > 18) { exPointStates[row, col] = ExtendedPointStateEnum.Virtual; } else { exPointStates[row, col] = (ExtendedPointStateEnum)chessBoard.GetPointState(14 - (row - 4), col - 4); } } } int[,] scoreTable = new int[15, 15]; /// <summary>calculate type of every tuple</summary> /// <description>In order to give a clear train of thought, /// I used an intuitionistic method to do this work. /// But this results in not efficient. /// Every tuple is calculated for twice. /// But it's easy to modify it:two ends of a tuple own the same tuple /// I'll modify it in next version ,where efficiency becomes bottleneck. /// </description> //every point indexs 8 tuples around it TupleType[, ,] tupleTable = new TupleType[15, 15, 8]; for (int row = 4; row < 19; row++) { for (int col = 4; col < 19; col++) { int[] white = new int[8]; //white points in a tuple int[] black = new int[8]; //black points in a tuple #region ---check tuples of every direction //left ,index 0 for (int i = 0; i < 5; i++) { if (exPointStates[row, col - i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 0] = TupleType.Virtual; break; } else if (exPointStates[row, col - i] == ExtendedPointStateEnum.Black) { black[0]++; } else if (exPointStates[row, col - i] == ExtendedPointStateEnum.White) { white[0]++; } } //top left,index 1 for (int i = 0; i < 5; i++) { if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 1] = TupleType.Virtual; break; } else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Black) { black[1]++; } else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.White) { white[1]++; } } //up ,index 2 for (int i = 0; i < 5; i++) { if (exPointStates[row - i, col] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 2] = TupleType.Virtual; break; } else if (exPointStates[row - i, col] == ExtendedPointStateEnum.Black) { black[2]++; } else if (exPointStates[row - i, col] == ExtendedPointStateEnum.White) { white[2]++; } } //top right,index 3 for (int i = 0; i < 5; i++) { if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 3] = TupleType.Virtual; break; } else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Black) { black[3]++; } else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.White) { white[3]++; } } //right,index 4 for (int i = 0; i < 5; i++) { if (exPointStates[row, col + i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 4] = TupleType.Virtual; break; } else if (exPointStates[row, col + i] == ExtendedPointStateEnum.Black) { black[4]++; } else if (exPointStates[row, col + i] == ExtendedPointStateEnum.White) { white[4]++; } } //bottom right,index 5 for (int i = 0; i < 5; i++) { if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 5] = TupleType.Virtual; break; } else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Black) { black[5]++; } else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.White) { white[5]++; } } //bottom,index 6 for (int i = 0; i < 5; i++) { if (exPointStates[row + i, col] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 6] = TupleType.Virtual; break; } else if (exPointStates[row + i, col] == ExtendedPointStateEnum.Black) { black[6]++; } else if (exPointStates[row + i, col] == ExtendedPointStateEnum.White) { white[6]++; } } //bottom left,index 7 for (int i = 0; i < 5; i++) { if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Virtual) { tupleTable[row - 4, col - 4, 7] = TupleType.Virtual; break; } else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Black) { black[7]++; } else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.White) { white[7]++; } } #endregion //check tuples of every direction //decide tuple type for (int i = 0; i < 8; i++) { //already assigned if (tupleTable[row - 4, col - 4, i] == TupleType.Virtual) { continue; } if (white[i] > 0 && black[i] > 0) { tupleTable[row - 4, col - 4, i] = TupleType.Polluted; } else if (white[i] == 0 && black[i] == 0) { tupleTable[row - 4, col - 4, i] = TupleType.Blank; } else if (white[i] == 0) { tupleTable[row - 4, col - 4, i] = (TupleType)black[i]; } else { tupleTable[row - 4, col - 4, i] = (TupleType)(white[i] + 4); } } } } #region ---scoreTable calculate //calculate score table . using symmetry //top left corner for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row >= m)//top right { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]]; //bottom scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]]; //bottom right scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]]; //right } } } //top right corner for (int row = 0; row < 8; row++) { for (int col = 8; col < 15; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row >= m)//top left { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]]; //bottom scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]]; //bottom left scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]]; //left } } } //bottom left corner for (int row = 8; row < 15; row++) { for (int col = 0; col < 8; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row + m < 15)//bottom right { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]]; //top scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]]; //top right scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]]; //right } } } //bottom right corner for (int row = 8; row < 15; row++) { for (int col = 8; col < 15; col++) { if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank) { //this situation has been considered //scoreTable[row,col]=0; continue; } for (int m = 0; m < 5; m++) { if (row + m < 15)//bottom left { scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]]; } scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]]; //top scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]]; //top left scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]]; //left } } } #endregion //scoreTable //select best position List <Position> bestList = new List <Position>(); //select first valid point Position first = new Position(0, 0); //all the point is forbidden.connot happen //while (IsFobidden(first)) //{ // while (IsFobidden(first)) // { // if (first.Col<14) // { // first.Col++; // } // else // { // break; // } // } // if (first.Row<14) // { // first.Row++; // } // else // { // break; // } //} while (IsFobidden(ref chessBoard, first, pieceType)) { if (first.Col < 14) { first.Col++; } else if (first.Row < 14) { first.Row++; first.Col = 0; } else { return(new ChessBoardPoint(-1, -1)); } } bestList.Add(first); Referee checkWin = new Referee(); //select best points for (int row = 0; row < 15; row++) { for (int col = 0; col < 15; col++) { if (scoreTable[row, col] > scoreTable[bestList[0].Row, bestList[0].Col]) { Position best = new Position(row, col); if (!IsFobidden(ref chessBoard, best, pieceType)) { bestList.Clear(); bestList.Add(best); } } else if (scoreTable[row, col] == scoreTable[bestList[0].Row, bestList[0].Col]) { Position best = new Position(row, col); if (!IsFobidden(ref chessBoard, best, pieceType)) { bestList.Add(best); } } } } //there is no best .connot happen if (bestList.Count == 0) { return(new ChessBoardPoint(-1, -1)); } Position ret = bestList[(new Random()).Next(bestList.Count)]; return(new ChessBoardPoint(14 - ret.Row, ret.Col)); }