private void OnCompletedDealAnimation(Animation animation) { _board.Deal(); for (int i = 0; i < Board.StackCount; i++) { CardStack stack = _board.GetStack(i); FixupStackCardViewRects(stack); } for (int i = 0; i < Board.StackCount; i++) { if (_board.GetStack(i).ContainsCompleteRun()) { ClearRun(_board.GetStack(i)); } } }
public void MoveCards(CardStack stackSrc, int posSrc, CardStack stackDest) { if (posSrc < 0) { return; } if (!stackSrc.CanPickupRun(posSrc)) { Console.WriteLine("Asked to move cards that are not in a sequential run - bug?"); } Card sourceCard = stackSrc.GetCard(posSrc); if (!CanMoveCardToStack(sourceCard, stackDest)) { Console.WriteLine(@"Asked to move cards to an invalid location - bug?"); } for (int i = posSrc; i < stackSrc.Count; i++) { Card card = stackSrc.GetCard(i); stackDest.Add(card); } int cardCount = stackSrc.Count - posSrc; stackSrc.RemoveRange(posSrc, cardCount); bool revealedCard = false; if (stackSrc.Count > 0) { Card revealed = stackSrc.GetCard(posSrc - 1); if (!revealed.Visible) { revealedCard = true; revealed.Reveal(); } } MoveCount++; Score -= ScorePerMove; _undoStack.AddMoveOfCards(cardCount, stackSrc, stackDest, revealedCard); }
public void FixupCardHighlights() { if (_cardsInAction != null && _currentAction != CardAction.None) { for (int i = 0; i < Board.StackCount; i++) { CardStack stack = _board.GetStack(i); foreach (Card card in stack.GetCards()) { card.View.Highlighted = false; } foreach (Card cardInAction in _cardsInAction) { if (_board.CanMoveCardToStack(cardInAction, stack)) { if (stack.Count > 0) { stack.GetLastCard().View.Highlighted = true; } break; } } } } else { for (int i = 0; i < Board.StackCount; i++) { CardStack stack = _board.GetStack(i); foreach (Card card in stack.GetCards()) { card.View.Highlighted = true; } } } // For now, ensure that all completed cards are highlighted for (int i = 0; i < _board.CompletedCount(); i++) { Card completedCard = _board.GetCompletedStack(i); completedCard.View.Highlighted = true; } }
public void PickFromStack(CardStack stack, Point ptExpand) { if (stack.Count > 0) { int top = stack.GetTopOfSequentialRun(); if (top < stack.Count - 1) { Animation expandAnimation = new StackExpandAnimation(_board, stack, ptExpand) { OnAnimationCompleted = OnCompletedExpandAnimation }; _currentAnimations.Add(expandAnimation); } else { SelectStack(stack); } _currentStack = stack.Index; } }
public void StartDrag(Point pt) { CardStack cardStack = GetStackAtPoint(pt); if (cardStack != null && cardStack.Count > 0 && (_currentAction == CardAction.None || _currentAction == CardAction.Moving)) { _dragInfo = new DragInfo(); int top = cardStack.GetTopOfSequentialRun(); _dragInfo.CardsToDrag = cardStack.GetCards(); _dragInfo.CardsToDrag.RemoveRange(0, top); _dragInfo.Stack = cardStack.Index; Point cardOrigin = GetLocationOfCardInStack(cardStack, cardStack.Count - _dragInfo.CardsToDrag.Count); _dragInfo.StartPos = pt; _dragInfo.Offset = new Point(_dragInfo.StartPos.X - cardOrigin.X, _dragInfo.StartPos.Y - cardOrigin.Y); } }
public void RemoveCompleteRun(CardStack stack, bool revealCard, bool addToComplete) { List <Card> runCards = stack.RemoveCompleteRun(revealCard); if (addToComplete) { Card king = runCards[0]; _completed.Add(king); Score += ScorePerRun; // Check for cleared board if (!_cleared && _completed.Count == CardCount / 13) { SetBoardClear(); } #if DEBUG bool check = true; for (int i = 0; i < StackCount && check; i++) { if (GetStack(i).Count > 0) { check = false; } } if (CountOfExtraDealingsLeft() > 0) { check = false; } if (check != _cleared) { Debug.WriteLine("BUG warning!!! Completed stack count does not match full board check!!!"); throw new Exception(); } #endif } }
public void ClearRun(CardStack stack) { // Need to account for any other run clearing in progress int clearAnimations = 0; foreach (Animation animation in _currentAnimations) { if (animation is ClearRunAnimation) { clearAnimations++; } } _board.ClearUndoStack(); Point destPoint = new Point((_board.CompletedCount() + clearAnimations) * 25 + _undoButtonRect.Width + 20, _viewRect.Height - _cardSize.Y); Animation clearAnimation = new ClearRunAnimation(_board, stack.Index, destPoint) { OnAnimationCompleted = OnCompletedClearRunAnimation }; _currentAnimations.Add(clearAnimation); }
public Rectangle GetAreaOfStack(CardStack stack) { return(GetRectOfCardRunInStack(stack, 0, stack.Count)); }
public void MoveCards(CardStack stackSrc, int posSrc, CardStack stackDest) { _board.MoveCards(stackSrc, posSrc, stackDest); FixupStackCardViewRects(stackSrc); FixupStackCardViewRects(stackDest); }
public void Touch(Point pt) { if (_completed) { StartNewGame(); Deal(); } else if (_currentAction == CardAction.Selecting) { _currentAction = CardAction.None; for (int i = 0; i < _cardsSelectionAnimation.Count; i++) { if (_cardsSelectionAnimation[i].CurrentRect.Contains(pt)) { _currentAction = CardAction.Moving; _cardsInAction = new List <Card>(); for (; i < _cardsSelectionAnimation.Count; i++) { _cardsInAction.Add(_cardsSelectionAnimation[i].Card); } } } CloseStack(_board.GetStack(_currentStack), _cardsSelectionAnimation); _cardsSelectionAnimation = null; } else if (_currentAction == CardAction.Dragging) { _currentAction = CardAction.None; CardStack destStack; Rectangle card0Rect = _cardsInAction[0].View.Rect; CardStack destStack1 = GetStackAtPoint(card0Rect.Location); CardStack destStack2 = GetStackAtPoint(new Point(card0Rect.Right, card0Rect.Top)); CardStack destStack3 = GetStackAtPoint(pt); if (destStack1 != null && destStack2 != null) // Check based on card position first { Rectangle destRect1 = GetAreaOfStack(destStack1); Rectangle destRect2 = GetAreaOfStack(destStack2); if (destRect1.Width - (card0Rect.Left - destRect1.Left) > card0Rect.Right - destRect2.Left) { destStack = destStack1; } else { destStack = destStack2; } } else if (destStack1 != null) // Prefer card location instead of top right { destStack = destStack1; } else if (destStack2 != null) // Prefer top right instead of touch pos { destStack = destStack2; } else // Accept touch pos if we don't have a better option { destStack = destStack3; } CardStack srcStack = _board.GetStack(_currentStack); bool movedRun = false; for (int t = 0; t < 2 && !movedRun; t++) { if (destStack != null && destStack.Index != _currentStack) { for (int i = 0; i < _cardsInAction.Count; i++) { if (_board.CanMoveCardToStack(_cardsInAction[i], destStack)) { MoveCards(srcStack, srcStack.Count - _cardsInAction.Count + i, destStack); if (destStack.ContainsCompleteRun()) { ClearRun(destStack); } movedRun = true; break; } } } destStack = (destStack == destStack1 ? destStack2 : destStack1); } if (!movedRun) { FixupStackCardViewRects(srcStack); } _cardsInAction = null; } else if (_currentAction == CardAction.Moving) { _currentAction = CardAction.None; CardStack stack = GetStackAtPoint(pt); if (stack != null) { if (stack.Index == _currentStack) { PickFromStack(stack, pt); } else { for (int i = 0; i < _cardsInAction.Count; i++) { if (_board.CanMoveCardToStack(_cardsInAction[i], stack)) { MoveCards(_board.GetStack(_currentStack), _board.GetStack(_currentStack).Count - _cardsInAction.Count + i, stack); if (stack.ContainsCompleteRun()) { ClearRun(stack); } _cardsInAction = null; break; } } if (_cardsInAction != null) { _cardsInAction = null; if (stack.Count > 0) { SelectStack(stack); } } } } } else if (GetExtraStackArea().Contains(pt)) { if (_board.CountOfExtraDealingsLeft() > 0) { Deal(); } } else if (GetCardArea().Contains(pt)) { CardStack stack = GetStackAtPoint(pt); if (stack != null) { if (stack.Count > 0) { SelectStack(stack); } } } else if (_undoButtonRect.Contains(pt) && _board.CanUndo()) { UndoAction nextAction = _board.NextUndoAction(); _board.Undo(); FixupStackCardViewRects(nextAction.SourceStack); FixupStackCardViewRects(nextAction.DestStack); } _dragInfo = null; FixupCardHighlights(); }
public void Render(Rectangle rc, SpriteBatch batch) { // TODO:V2: Render move count and score? batch.Begin(); batch.Draw(CardResources.GradientTex, rc, Color.Green); batch.End(); int cardWidth = rc.Width / 10 - 4; int cardHeight = (int)(cardWidth * (3.5 / 2.5)); int spacing = (rc.Width - cardWidth * Board.StackCount) / (Board.StackCount - 1); // Draw the game board for (int i = 0; i < Board.StackCount; i++) { int stackSize = _board.GetStack(i).Count; if (stackSize == 0) { var cardRect = new Rectangle(i * (cardWidth + spacing), 0, cardWidth, cardHeight); batch.Begin(); batch.Draw(CardResources.PlaceholderTex, cardRect, Color.White); batch.End(); } else { int stackCount = _board.GetStack(i).Count - (_currentAction == CardAction.Dragging && i == _currentStack ? _cardsInAction.Count : 0); for (int c = 0; c < stackSize; c++) { Card card = _board.GetStack(i).GetCard(c); if (!card.View.Animating && c < stackCount) { card.View.Render(batch); } } } } // Draw the current mover overlay if (_currentAction == CardAction.Moving) { CardStack stack = _board.GetStack(_currentStack); int stackSize = stack.Count; Point pt = _board.View.GetLocationOfCardInStack(_board.GetStack(_currentStack), stackSize - _cardsInAction.Count); Point pt2 = _board.View.GetLocationOfCardInStack(_board.GetStack(_currentStack), stackSize - 1); Point size = _board.View.GetCardSize(); var overlayRect = new Rectangle(pt.X, pt.Y, size.X, pt2.Y - pt.Y + size.Y); overlayRect.Inflate(size.X / 20, size.Y / 20); var topRect = new Rectangle(overlayRect.Left, overlayRect.Top, overlayRect.Width, size.Y / 4); var bottomRect = new Rectangle(overlayRect.Left, overlayRect.Bottom - topRect.Height, overlayRect.Width, topRect.Height); var centerRect = new Rectangle(overlayRect.Left, overlayRect.Top + topRect.Height, overlayRect.Width, overlayRect.Height - topRect.Height * 2); batch.Begin(); batch.Draw(CardResources.HighlightEndTex, topRect, Color.White); batch.Draw(CardResources.HighlightEndTex, bottomRect, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.FlipVertically, 0.0f); batch.Draw(CardResources.HightlightCenterTex, centerRect, Color.White); batch.End(); } // Draw the extra stacks for (int i = 0; i < _board.CountOfExtraDealingsLeft(); i++) { var cardRect = new Rectangle(rc.Width - cardWidth - i * 25, rc.Height - cardHeight, cardWidth, cardHeight); batch.Begin(); batch.Draw(CardResources.CardBackTex, cardRect, Options.CardBackColor); batch.End(); } // Draw the undo button Color undoColor = (_board.CanUndo() ? Color.White : Color.Multiply(Color.White, 0.4f)); batch.Begin(); batch.Draw(CardResources.UndoTex, _undoButtonRect, undoColor); batch.End(); // Draw the completed stacks for (int i = 0; i < _board.CompletedCount(); i++) { Card completedCard = _board.GetCompletedStack(i); completedCard.View.Render(batch); } // Draw the cards being dragged if (_currentAction == CardAction.Dragging) { foreach (Card card in _cardsInAction) { card.View.Render(batch); } } if (_board.IsBoardClear()) { var winTextSize = CardResources.WinFont.MeasureString(Strings.Game_WinMessage); var winPos = new Vector2(_viewRect.Width / 2.0f - winTextSize.X / 2, _viewRect.Height / 2.0f - winTextSize.Y / 2); batch.Begin(); batch.DrawString(CardResources.WinFont, Strings.Game_WinMessage, winPos, Color.Black); batch.End(); if (_completed) { var newGameSize = CardResources.AgainFont.MeasureString(Strings.Game_Again); var pos = new Vector2(_viewRect.Width / 2.0f - newGameSize.X / 2, _viewRect.Height / 2.0f - newGameSize.Y / 2 + winTextSize.Y); batch.Begin(); batch.DrawString(CardResources.AgainFont, Strings.Game_Again, pos, Color.Black); batch.End(); } } else if (Errors.Count > 0) { } foreach (Animation animation in _currentAnimations) { animation.Render(batch); } if (_currentAction == CardAction.Selecting) { batch.Begin(); batch.Draw(CardResources.BlankTex, _board.View.GetViewArea(), new Color(0, 0, 0, 128)); batch.End(); foreach (CardAnimationView animation in _cardsSelectionAnimation) { animation.Render(batch); } } }
public Point GetLocationOfStack(CardStack stack) { int spacing = (_viewRect.Width - _cardSize.X * Board.StackCount) / (Board.StackCount - 1); return(new Point(stack.Index * (_cardSize.X + spacing), 0)); }
public bool Load() { if (ResumeGameExists()) { Reset(); GameSerialization gameSerialization; try { var storage = IsolatedStorageFile.GetUserStoreForApplication(); var stream = storage.OpenFile(ResumeGameFilename, FileMode.Open, FileAccess.Read); TextReader reader = new StreamReader(stream); var serializer = new XmlSerializer(typeof(GameSerialization)); gameSerialization = serializer.Deserialize(reader) as GameSerialization; reader.Close(); } catch (FileNotFoundException) { // We thought we had a file...? return(false); } catch (Exception exc) { // Something else bad happened. Crap. Debug.WriteLine(exc); return(false); } if (gameSerialization == null) { return(false); } SuitCount = gameSerialization.Suits; MoveCount = gameSerialization.MoveCount; Score = gameSerialization.Score; for (int i = 0; i < StackCount; i++) { CardStackSerialization stackSerialization = gameSerialization.Board.Stacks[i]; CardStack stack = GetStack(i); foreach (CardSerialization cardSerialization in stackSerialization.Cards) { var card = new Card((Suit)cardSerialization.Suit, (Value)cardSerialization.Value, new Random()) { Visible = cardSerialization.Visible }; card.View = new CardView(card); stack.Add(card); } } for (int i = 0; i < gameSerialization.Board.Extras.Count; i++) { CardStackSerialization extraSerialization = gameSerialization.Board.Extras[i]; _extras[i] = new List <Card>(); foreach (CardSerialization cardSerialization in extraSerialization.Cards) { var card = new Card((Suit)cardSerialization.Suit, (Value)cardSerialization.Value, new Random()) { Visible = cardSerialization.Visible }; card.View = new CardView(card); _extras[i].Add(card); } } for (int i = 0; i < gameSerialization.Board.Completed.Count; i++) { CardStackSerialization completedSerialization = gameSerialization.Board.Completed[i]; CardSerialization cardSerialization = completedSerialization.Cards[0]; var card = new Card((Suit)cardSerialization.Suit, (Value)cardSerialization.Value, new Random()) { Visible = cardSerialization.Visible }; card.View = new CardView(card); _completed.Add(card); } for (int i = 0; i < gameSerialization.UndoStack.Actions.Count; i++) { UndoActionSerialization actionSerialization = gameSerialization.UndoStack.Actions[i]; var action = new UndoAction(actionSerialization.CardCount, GetStack(actionSerialization.SourceStack), GetStack(actionSerialization.DestStack), actionSerialization.RevealedCard); _undoStack.Stack.Add(action); } for (int i = 0; i < StackCount; i++) { View.FixupStackCardViewRects(GetStack(i)); } // Stats were reset with a suspended game - bump the count since we have a game in progress if (Statistics.TotalGames == 0) { Statistics.TotalGames++; switch (SuitCount) { case 1: Statistics.EasyGames++; break; case 2: Statistics.MediumGames++; break; case 4: Statistics.HardGames++; break; } } return(true); } return(false); }
public void AddMoveOfCards(int cardCount, CardStack stackSrc, CardStack stackDest, bool revealedCard) { Stack.Add(new UndoAction(cardCount, stackSrc, stackDest, revealedCard)); }