public double Calculate(Move move) { if (move.IsEmpty) { return(Move.RejectScore); } ScoreInfo score = new ScoreInfo(Coefficients, Group0); int from = move.From; int fromRow = move.FromRow; int to = move.To; int toRow = move.ToRow; if (move.Type == MoveType.CompositeSinglePile) { return(CalculateCompositeSinglePileScore(move)); } Pile fromPile = FindTableau[from]; Pile toPile = FindTableau[to]; if (toPile.Count == 0) { return(CalculateLastResortScore(move)); } bool isSwap = move.Type == MoveType.Swap; Card fromParent = fromRow != 0 ? fromPile[fromRow - 1] : Card.Empty; Card fromChild = fromPile[fromRow]; Card toParent = toRow != 0 ? toPile[toRow - 1] : Card.Empty; Card toChild = toRow != toPile.Count ? toPile[toRow] : Card.Empty; int oldOrderFrom = GetOrder(fromParent, fromChild); int newOrderFrom = GetOrder(toParent, fromChild); int oldOrderTo = isSwap ? GetOrder(toParent, toChild) : 0; int newOrderTo = isSwap ? GetOrder(fromParent, toChild) : 0; score.Order = newOrderFrom - oldOrderFrom + newOrderTo - oldOrderTo; if (score.Order < 0) { return(Move.RejectScore); } score.Reversible = oldOrderFrom != 0 && (!isSwap || oldOrderTo != 0); score.Uses = CountUses(move); score.OneRunDelta = !isSwap?RunFinder.GetOneRunDelta(oldOrderFrom, newOrderFrom, move) : 0; int faceFrom = (int)fromChild.Face; int faceTo = isSwap ? (int)toChild.Face : 0; score.FaceValue = Math.Max(faceFrom, faceTo); bool wholePile = fromRow == 0 && toRow == toPile.Count; int netRunLengthFrom = RunFinder.GetNetRunLength(newOrderFrom, from, fromRow, to, toRow); int netRunLengthTo = isSwap ? RunFinder.GetNetRunLength(newOrderTo, to, toRow, from, fromRow) : 0; score.NetRunLength = netRunLengthFrom + netRunLengthTo; #if true int newRunLengthFrom = RunFinder.GetNewRunLength(newOrderFrom, from, fromRow, to, toRow); int newRunLengthTo = isSwap ? RunFinder.GetNewRunLength(newOrderTo, to, toRow, from, fromRow) : 0; score.Discards = newRunLengthFrom == 13 || newRunLengthTo == 13; #endif score.DownCount = FindTableau.GetDownCount(from); score.TurnsOverCard = wholePile && score.DownCount != 0; score.CreatesSpace = wholePile && score.DownCount == 0; score.NoSpaces = FindTableau.NumberOfSpaces == 0; if (score.Order == 0 && score.NetRunLength < 0) { return(Move.RejectScore); } int delta = 0; if (score.Order == 0 && score.NetRunLength == 0) { if (!isSwap && oldOrderFrom == 1 && newOrderFrom == 1) { delta = RunFinder.GetRunDelta(from, fromRow, to, toRow); } if (delta <= 0) { return(Move.RejectScore); } } score.IsCompositeSinglePile = false; return(score.Score); }
public bool IsViable(Move move) { int from = move.From; int fromRow = move.FromRow; int to = move.To; int toRow = move.ToRow; Pile fromPile = FindTableau[from]; Pile toPile = FindTableau[to]; if (toPile.Count == 0) { if (fromPile.Count == 0 && FindTableau.GetDownCount(from) == 0) { return(false); } else if (fromRow != 0 && fromPile[fromRow - 1].IsTargetFor(fromPile[fromRow])) { return(false); } return(true); } bool isSwap = move.Type == MoveType.Swap; Card fromParent = fromRow != 0 ? fromPile[fromRow - 1] : Card.Empty; Card fromChild = fromPile[fromRow]; Card toParent = toRow != 0 ? toPile[toRow - 1] : Card.Empty; Card toChild = toRow != toPile.Count ? toPile[toRow] : Card.Empty; int oldOrderFrom = GetOrder(fromParent, fromChild); int newOrderFrom = GetOrder(toParent, fromChild); int oldOrderTo = isSwap ? GetOrder(toParent, toChild) : 0; int newOrderTo = isSwap ? GetOrder(fromParent, toChild) : 0; int order = newOrderFrom - oldOrderFrom + newOrderTo - oldOrderTo; if (order < 0) { return(false); } int netRunLengthFrom = RunFinder.GetNetRunLength(newOrderFrom, from, fromRow, to, toRow); int netRunLengthTo = isSwap ? RunFinder.GetNetRunLength(newOrderTo, to, toRow, from, fromRow) : 0; int netRunLength = netRunLengthFrom + netRunLengthTo; if (order == 0 && netRunLength < 0) { return(false); } int delta = 0; if (order == 0 && netRunLength == 0) { if (!isSwap && oldOrderFrom == 1 && newOrderFrom == 1) { delta = RunFinder.GetRunDelta(from, fromRow, to, toRow); } if (delta <= 0) { return(false); } } return(true); }