private int AggregateScoreFromVectorGrades(int column) { bool player = CurrentPlayer; Location rootLocation = new Location(NumberTokensInColumn[column], column); Location aboveLocation = new Location(rootLocation.row + 1, column); Location aboveTwiceLocation = new Location(aboveLocation.row + 1, column); VectorGrade grade = BestVectorGradeForColumn(rootLocation, player, true); //do not check below because board state is not updated VectorGrade gradeAbove = BestVectorGradeForColumn(aboveLocation, player, false); //one more time. VectorGrade gradeAboveTwice = BestVectorGradeForColumn(aboveTwiceLocation, player, false); player = !player; VectorGrade opponentGrade = BestVectorGradeForColumn(rootLocation, player, true); //do not check below because board state is not updated VectorGrade opponentGradeAbove = BestVectorGradeForColumn(aboveLocation, player, false); //if (opponentGradeAbove.lengthOfChain >= 4) { //Console.WriteLine(opponentGradeAbove.lengthOfChain + " length of chain"); } //this is a must make play do not bother with math! if (grade.lengthOfChain >= 4) { return(VectorGrade.WinningScore); } if (opponentGrade.lengthOfChain >= 4) { return(199); } if (opponentGradeAbove.lengthOfChain >= 4) { return(-200); } //this is another win move, remember we already checked and guarded against oppenent wins above if (gradeAbove.lengthOfChain >= 4 && gradeAboveTwice.lengthOfChain >= 4) { return(198); } //else take the sum, of your score with the difference of the opponents play //Console.WriteLine("myscore"); int sumOfScores = grade.score + (opponentGrade.score - opponentGradeAbove.score); //deweight score if the over spot is a win for you if (gradeAbove.lengthOfChain >= 4) { sumOfScores -= 40;//this is a number that is probably too large } return(sumOfScores); }
private VectorGrade BestVectorGradeForColumn(Location location, bool hypotheticalCurrentPlayer, bool checkBelow) { VectorGrade[] gradeDetails = new VectorGrade[4]; int insertionIndex = 0; //score for foreach (KeyValuePair <string, Location> direction in travelTokenVectors) { Location vectorToGrade = direction.Value; //do not check below if the direction is vertical and checkbelow is false //check below is false when you are evaluating future moves above current row VectorGrade vectorGrade = GradeVector( rootLocation: location, direction: vectorToGrade, player: hypotheticalCurrentPlayer, checkBelow: !(direction.Key == "Vertical" && checkBelow == false) ); gradeDetails[insertionIndex] = vectorGrade; insertionIndex++; } VectorGrade best = gradeDetails[0]; for (int i = 1; i < gradeDetails.Length; i++) { if (best.score < gradeDetails[i].score) { best = gradeDetails[i]; } } return(best); }
//vector grade below private VectorGrade GradeVector(Location rootLocation, Location direction, bool player, bool checkBelow) { bool hypotheticalCurrentPlayer = player; bool continousChain = true; int maxLengthInChain = 1; int lengthOfChain = 1; bool openEndedOtherWay = false; bool openEndedOneWay = false; Location currentLocation = rootLocation; //this little bit could be recursive, but it doesn't play super nice with readonly VectorGrades for (int i = 0; i < 3; i++) { currentLocation.row += direction.row; currentLocation.column += direction.column; if (ValidateSpace(currentLocation)) { //if space is unoccupied if (SpaceEmpty(currentLocation)) { continousChain = false; openEndedOneWay = true; maxLengthInChain++; } //if space is yours else if (GameState[currentLocation.row, currentLocation.column] == hypotheticalCurrentPlayer) { maxLengthInChain++; if (continousChain) { lengthOfChain++; } } //if space is opponents else { //this will break out of loop i = 3; } } else { i = 3; } } //and the other way if (checkBelow == true) { continousChain = true;//canidate for deleteion Location reversedDirection = direction.VectorReversed(); currentLocation = rootLocation; for (int i = 0; i < 3; i++) { currentLocation.row += reversedDirection.row; currentLocation.column += reversedDirection.column; if (ValidateSpace(currentLocation)) { //if space is unoccupied if (SpaceEmpty(currentLocation)) { continousChain = false; openEndedOtherWay = true; maxLengthInChain++; } //if space is yours else if (GameState[currentLocation.row, currentLocation.column] == hypotheticalCurrentPlayer) { maxLengthInChain++; if (continousChain) { lengthOfChain++; } } //if space is opponents else { //this will break out of loop i = 3; } } else { i = 3; } } } bool openEndedBothWays = false; if (openEndedOneWay && openEndedOtherWay) { openEndedBothWays = true; } VectorGrade returnGrade = new VectorGrade(lengthOfChain, maxLengthInChain, openEndedBothWays); return(returnGrade); }