private double EvaluteMove(IBoard board, IPiece piece, out int bestRotationDelta, out int bestTranslationDelta) { int currentBestTranslationDelta = 0; int currentBestRotationDelta = 0; double currentBestRating = -1.0e+20; // Really bad! int currentBestPriority = 0; //current.Translate(0, -1); IBoard tempBoard = board.Clone(); IPiece tempPiece = piece.Clone(); // Consider all possible rotations for (int trialRotationDelta = 0; trialRotationDelta < piece.MaxOrientations; trialRotationDelta++) { // Copy piece tempPiece.CopyFrom(piece); // Rotate tempPiece.Rotate(trialRotationDelta); // Get translation range bool isMovePossible; int minDeltaX; int maxDeltaX; BoardHelper.GetAccessibleTranslationsForOrientation(board, tempPiece, out isMovePossible, out minDeltaX, out maxDeltaX); //StringBuilder sb = new StringBuilder(); //for (int i = 1; i <= tempPiece.TotalCells; i++) //{ // int x, y; // tempPiece.GetCellAbsolutePosition(i, out x, out y); // sb.Append(String.Format("[{0}->{1},{2}]", i, x - tempPiece.PosX, y - tempPiece.PosY)); //} //Log.Log.Default.WriteLine("{0} {1} -> {2} {3}", trialRotationDelta, minDeltaX, maxDeltaX, sb.ToString()); if (isMovePossible) { // Consider all allowed translations for (int trialTranslationDelta = minDeltaX; trialTranslationDelta <= maxDeltaX; trialTranslationDelta++) { // Evaluate this move // Copy piece tempPiece.CopyFrom(piece); // Rotate tempPiece.Rotate(trialRotationDelta); // Translate tempPiece.Translate(trialTranslationDelta, 0); // Check if move is acceptable if (board.CheckNoConflict(tempPiece)) { // Copy board tempBoard.CopyFrom(board); // Drop piece tempBoard.DropAndCommit(tempPiece); tempBoard.CollapseCompletedRows(); double trialRating = 0; trialRating += -0.65 * BoardHelper.GetTotalShadowedHoles(board); trialRating += -0.10 * BoardHelper.GetPileHeightWeightedCells(board); trialRating += -0.20 * BoardHelper.GetSumOfWellHeights(board); // Check if better than previous best if (trialRating > currentBestRating) { currentBestRating = trialRating; currentBestTranslationDelta = trialTranslationDelta; currentBestRotationDelta = trialRotationDelta; } } } } } // Commit to this move bestTranslationDelta = currentBestTranslationDelta; bestRotationDelta = currentBestRotationDelta; return(currentBestRating); }
public bool GetBestMove(IBoard board, IPiece current, IPiece next, out int bestRotationDelta, out int bestTranslationDelta, out bool rotationBeforeTranslation) { int currentBestTranslationDelta = 0; int currentBestRotationDelta = 0; double currentBestRating = -1.0e+20; // Really bad! //if (current.PosY == board.Height) // TODO: put current totally in board before trying to get best move // current.Translate(0, -1); IBoard tempBoard = board.Clone(); IPiece tempPiece = current.Clone(); //Log.Default.WriteLine(LogLevels.Debug, "Get Best Move for Piece {0} {1}", tempPiece.Value, tempPiece.Index); // Consider all possible rotations for (int trialRotationDelta = 0; trialRotationDelta < current.MaxOrientations; trialRotationDelta++) { // Copy piece tempPiece.CopyFrom(current); // Rotate tempPiece.Rotate(trialRotationDelta); // Get translation range bool isMovePossible; int minDeltaX; int maxDeltaX; BoardHelper.GetAccessibleTranslationsForOrientation(board, tempPiece, out isMovePossible, out minDeltaX, out maxDeltaX); //Log.Default.WriteLine(LogLevels.Debug, "Accessible translation {0} {1} {2} {3} {4} {5} {6}", minDeltaX, maxDeltaX, trialRotationDelta, current.PosX, current.PosY, tempPiece.Value, tempPiece.Index); //StringBuilder sb = new StringBuilder(); //for (int i = 1; i <= tempPiece.TotalCells; i++) //{ // int x, y; // tempPiece.GetCellAbsolutePosition(i, out x, out y); // sb.Append(String.Format("[{0}->{1},{2}]", i, x - tempPiece.PosX, y - tempPiece.PosY)); //} //Log.Log.Default.WriteLine("{0} {1} -> {2} {3}", trialRotationDelta, minDeltaX, maxDeltaX, sb.ToString()); if (isMovePossible) { // Consider all allowed translations for (int trialTranslationDelta = minDeltaX; trialTranslationDelta <= maxDeltaX; trialTranslationDelta++) { // Evaluate this move // Copy piece tempPiece.CopyFrom(current); // Rotate tempPiece.Rotate(trialRotationDelta); // Translate tempPiece.Translate(trialTranslationDelta, 0); // Check if move is acceptable if (board.CheckNoConflict(tempPiece)) { // Copy board tempBoard.CopyFrom(board); // Drop piece tempBoard.DropAndCommit(tempPiece); // Evaluate double trialRating = EvaluteMove(tempBoard, tempPiece); //Log.Log.Default.WriteLine("R:{0:0.0000} P:{1} R:{2} T:{3}", trialRating, trialRotationDelta, trialTranslationDelta); // Check if better than previous best if (trialRating > currentBestRating) { currentBestRating = trialRating; currentBestTranslationDelta = trialTranslationDelta; currentBestRotationDelta = trialRotationDelta; } } } } } // Commit to this move rotationBeforeTranslation = true; bestTranslationDelta = currentBestTranslationDelta; bestRotationDelta = currentBestRotationDelta; // Log.Default.WriteLine(LogLevels.Debug, "{0} {1} {2:0.000}", bestRotationDelta, bestTranslationDelta, currentBestRating); return(true); }
public bool GetBestMove(IBoard board, IPiece current, IPiece next, out int bestRotationDelta, out int bestTranslationDelta, out bool rotationBeforeTranslation) { int currentBestTranslationDelta = 0; int currentBestRotationDelta = 0; double currentBestRating = -1.0e+20; // Really bad! int currentBestPriority = 0; //current.Translate(0, -1); IBoard tempBoard = board.Clone(); IPiece tempPiece = current.Clone(); // Consider all possible rotations for (int trialRotationDelta = 0; trialRotationDelta < current.MaxOrientations; trialRotationDelta++) { // Copy piece tempPiece.CopyFrom(current); // Rotate tempPiece.Rotate(trialRotationDelta); // Get translation range bool isMovePossible; int minDeltaX; int maxDeltaX; BoardHelper.GetAccessibleTranslationsForOrientation(board, tempPiece, out isMovePossible, out minDeltaX, out maxDeltaX); StringBuilder sb = new StringBuilder(); for (int i = 1; i <= tempPiece.TotalCells; i++) { int x, y; tempPiece.GetCellAbsolutePosition(i, out x, out y); sb.Append(String.Format("[{0}->{1},{2}]", i, x - tempPiece.PosX, y - tempPiece.PosY)); } //Log.Log.Default.WriteLine("{0} {1} -> {2} {3}", trialRotationDelta, minDeltaX, maxDeltaX, sb.ToString()); if (isMovePossible) { // Consider all allowed translations for (int trialTranslationDelta = minDeltaX; trialTranslationDelta <= maxDeltaX; trialTranslationDelta++) { // Evaluate this move // Copy piece tempPiece.CopyFrom(current); // Rotate tempPiece.Rotate(trialRotationDelta); // Translate tempPiece.Translate(trialTranslationDelta, 0); // Check if move is acceptable if (board.CheckNoConflict(tempPiece)) { // Copy board tempBoard.CopyFrom(board); // Drop piece tempBoard.DropAndCommit(tempPiece); // Evaluate double trialRating; int trialPriority; EvaluteMove(tempBoard, tempPiece, out trialRating, out trialPriority); //Log.Log.Default.WriteLine("R:{0:0.0000} P:{1} R:{2} T:{3}", trialRating, trialPriority, trialRotationDelta, trialTranslationDelta); // Check if better than previous best if (trialRating > currentBestRating || (Math.Abs(trialRating - currentBestRating) < 0.0001 && trialPriority > currentBestPriority)) { currentBestRating = trialRating; currentBestPriority = trialPriority; currentBestTranslationDelta = trialTranslationDelta; currentBestRotationDelta = trialRotationDelta; } } } } } // commit to this move rotationBeforeTranslation = true; bestTranslationDelta = currentBestTranslationDelta; bestRotationDelta = currentBestRotationDelta; //Console.SetCursorPosition(0, _client.Board.Height+1); // Console.WriteLine("{0} {1} {2:0.000} {3}", bestRotationDelta, bestTranslationDelta, currentBestRating, currentBestPriority); return(true); }