//http://tetris.wikia.com/wiki/Wall_kick public override bool RotateCounterClockwise(IPiece piece) { // Special case: cannot place piece at starting location. if (!CheckNoConflict(piece)) return false; // Try to rotate IPiece tempPiece = piece.Clone(); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) { // Try to move right then rotate tempPiece.CopyFrom(piece); tempPiece.Translate(1, 0); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) { // Try to move left then rotate tempPiece.CopyFrom(piece); tempPiece.Translate(-1, 0); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) return false; else piece.Translate(-1, 0); } else piece.Translate(1, 0); } // Perform rotation (wall kick translation has been done before if needed) piece.RotateCounterClockwise(); return true; }
public void Drop(IPiece piece) { // Special case: cannot place piece at starting location. bool goalAcceptable = CheckNoConflict(piece); if (!goalAcceptable) // cannot drop piece at all { return; } // Try successively larger drop distances, up to the point of failure. // The last successful drop distance becomes our drop distance. int lastSuccessfulDropDistance = 0; IPiece tempPiece = piece.Clone(); for (int trial = 0; trial <= Height; trial++) { tempPiece.CopyFrom(piece); // Set temporary piece to new trial Y tempPiece.Translate(0, -trial); goalAcceptable = CheckNoConflict(tempPiece); if (!goalAcceptable) { // We failed to drop this far. Stop drop search. break; } else { lastSuccessfulDropDistance = trial; } } // Simply update the piece Y value. piece.Translate(0, -lastSuccessfulDropDistance); }
public void DrawPiece(IPiece piece, int boardHeight) { // Clear foreach (Rectangle rect in _grid) { rect.Fill = TransparentColor; } if (piece == null) { return; } // Draw IPiece temp = piece.Clone(); int minX, minY, maxX, maxY; temp.GetAbsoluteBoundingRectangle(out minX, out minY, out maxX, out maxY); // Move to top, left temp.Translate(-minX, 0); temp.Translate(0, boardHeight - maxY); Pieces cellPiece = temp.Value; for (int i = 1; i <= temp.TotalCells; i++) { int x, y; temp.GetCellAbsolutePosition(i, out x, out y); // 1->Width x 1->Height int cellY = boardHeight - y; int cellX = x; Rectangle uiPart = GetControl(cellX, cellY); uiPart.Fill = TextureManager.TextureManager.Instance.GetBigPiece(cellPiece); } }
private void DrawPiece(IPiece piece, int size, int topX, int topY) { IPiece temp = piece.Clone(); Pieces cellPiece = temp.Value; for (int i = 1; i <= temp.TotalCells; i++) { int x, y; temp.GetCellAbsolutePosition(i, out x, out y); // 1->Width x 1->Height Rectangle rectangle = new Rectangle { Width = size, Height = size, Fill = TextureManager.TextureManager.Instance.GetBigPiece(cellPiece) }; Canvas.Children.Add(rectangle); Canvas.SetLeft(rectangle, topX + x * size); Canvas.SetTop(rectangle, topY + y * size); } Rectangle anchor = new Rectangle { Width = size, Height = size, Fill = PieceAnchorColor }; Canvas.Children.Add(anchor); Canvas.SetLeft(anchor, topX); Canvas.SetTop(anchor, topY); }
public static void GetAccessibleTranslationsForOrientation(IBoard board, IPiece piece, out bool isMovePossible, out int minDeltaX, out int maxDeltaX) { isMovePossible = false; minDeltaX = 0; maxDeltaX = 0; IPiece tempPiece = piece.Clone(); // Check if we can move bool moveAcceptable = board.CheckNoConflict(tempPiece); if (!moveAcceptable) { return; } isMovePossible = true; // Scan from center to left to find left limit. for (int trial = 0; trial >= -board.Width; trial--) { // Copy piece tempPiece.CopyFrom(piece); // Translate tempPiece.Translate(trial, 0); // Check if move is valid moveAcceptable = board.CheckNoConflict(tempPiece); if (moveAcceptable) { minDeltaX = trial; } else { break; } } // Scan from center to right to find right limit. for (int trial = 0; trial <= board.Width; trial++) { // Copy piece tempPiece.CopyFrom(piece); // Translate tempPiece.Translate(trial, 0); // Check if move is valid moveAcceptable = board.CheckNoConflict(tempPiece); if (moveAcceptable) { maxDeltaX = trial; } else { break; } } }
// The following counts the number of cells (0..4) of a piece that would // be eliminated by dropping the piece. public static int CountPieceCellsEliminated(IBoard board, IPiece piece, bool alreadyDropped) { // Copy piece and board so that this measurement is not destructive. IBoard copyOfBoard = alreadyDropped ? board : board.Clone(); IPiece copyOfPiece = alreadyDropped ? piece : piece.Clone(); if (!alreadyDropped) { // Drop copy of piece on to the copy of the board copyOfBoard.DropAndCommit(copyOfPiece); } // Scan rows. For each full row, check all board Y values for the // piece. If any board Y of the piece matches the full row Y, // increment the total eliminated cells. int countPieceCellsEliminated = 0; for (int y = 1; y <= copyOfBoard.Height; y++) { bool fullRow = true; // hypothesis for (int x = 1; x <= copyOfBoard.Width; x++) { byte cellValue = copyOfBoard[x, y]; if (cellValue == 0) { fullRow = false; break; } } if (fullRow) { // Find any matching board-relative Y values in dropped copy of piece. for (int cellIndex = 1; cellIndex <= piece.TotalCells; cellIndex++) { int boardX; int boardY; copyOfPiece.GetCellAbsolutePosition(cellIndex, out boardX, out boardY); if (boardY == y) { countPieceCellsEliminated++; // Moohahahaaa! } } } } return(countPieceCellsEliminated); }
public virtual bool RotateCounterClockwise(IPiece piece) { // Special case: cannot place piece at starting location. if (!CheckNoConflict(piece)) { return(false); } // Try to rotate IPiece tempPiece = piece.Clone(); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) { return(false); } // Simply update the piece rotation piece.RotateCounterClockwise(); return(true); }
public bool MoveDown(IPiece piece) { // Special case: cannot place piece at starting location. if (!CheckNoConflict(piece)) { return(false); } // Try to move down IPiece tempPiece = piece.Clone(); tempPiece.Translate(0, -1); if (!CheckNoConflict(tempPiece)) { return(false); } // Simply update the piece Y value piece.Translate(0, -1); return(true); }
//http://tetris.wikia.com/wiki/Wall_kick public override bool RotateCounterClockwise(IPiece piece) { // Special case: cannot place piece at starting location. if (!CheckNoConflict(piece)) { return(false); } // Try to rotate IPiece tempPiece = piece.Clone(); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) { // Try to move right then rotate tempPiece.CopyFrom(piece); tempPiece.Translate(1, 0); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) { // Try to move left then rotate tempPiece.CopyFrom(piece); tempPiece.Translate(-1, 0); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) { return(false); } else { piece.Translate(-1, 0); } } else { piece.Translate(1, 0); } } // Perform rotation (wall kick translation has been done before if needed) piece.RotateCounterClockwise(); 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! //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 virtual bool RotateCounterClockwise(IPiece piece) { // Special case: cannot place piece at starting location. if (!CheckNoConflict(piece)) return false; // Try to rotate IPiece tempPiece = piece.Clone(); tempPiece.RotateCounterClockwise(); if (!CheckNoConflict(tempPiece)) return false; // Simply update the piece rotation piece.RotateCounterClockwise(); return true; }
public bool MoveDown(IPiece piece) { // Special case: cannot place piece at starting location. if (!CheckNoConflict(piece)) return false; // Try to move down IPiece tempPiece = piece.Clone(); tempPiece.Translate(0, -1); if (!CheckNoConflict(tempPiece)) return false; // Simply update the piece Y value piece.Translate(0, -1); return true; }
public void Drop(IPiece piece) { // Special case: cannot place piece at starting location. bool goalAcceptable = CheckNoConflict(piece); if (!goalAcceptable) // cannot drop piece at all return; // Try successively larger drop distances, up to the point of failure. // The last successful drop distance becomes our drop distance. int lastSuccessfulDropDistance = 0; IPiece tempPiece = piece.Clone(); for (int trial = 0; trial <= Height; trial++) { tempPiece.CopyFrom(piece); // Set temporary piece to new trial Y tempPiece.Translate(0, -trial); goalAcceptable = CheckNoConflict(tempPiece); if (!goalAcceptable) // We failed to drop this far. Stop drop search. break; else lastSuccessfulDropDistance = trial; } // Simply update the piece Y value. piece.Translate(0, -lastSuccessfulDropDistance); }
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! 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); }