private void SetHandOutcome(IPlayerHand playerHand, int dealerHandValue) { int playerHandValue = playerHand.GetBestCardValue(); if (playerHandValue > Constants.BestHandValue) { playerHand.Outcome = HandOutcome.Lost; } else if (dealerHandValue > Constants.BestHandValue) { playerHand.Outcome = HandOutcome.Won; } else if (playerHandValue == dealerHandValue) { playerHand.Outcome = HandOutcome.Pushed; } else if (playerHandValue > dealerHandValue) { playerHand.Outcome = HandOutcome.Won; } else if (playerHandValue < dealerHandValue) { playerHand.Outcome = HandOutcome.Lost; } else { throw new Exception("Could not determine outcome of player's hand"); } }
public ViewModelFactory() { playerHand = new PlayerHand(); IPlayerService player = new PlayerService(playerHand); _controller = new SimulationController(player); }
/// <summary>Rollback the previous cancellation of this command.</summary> public override void Redo() { preventConflict(stackBefore, stackAfter); // does the hand already contain an identical clone? IPlayerHand playerHand = model.CurrentGameBox.CurrentGame.GetPlayerHand(playerGuid); for (int i = 0; i < playerHand.Count; ++i) { ITerrainClone handPiece = stackAfter.Pieces[i] as ITerrainClone; if (handPiece != null && handPiece.Prototype == piece.Prototype) { // yes -> don't redo ordering of the hand, it's not transactional model.AnimationManager.LaunchAnimationSequence( new MoveToFrontOfBoardAnimation(stackBefore, boardBefore), new MoveStackToHandAnimation(stackBefore), new RemoveTerrainAnimation(stackBefore)); return; } } // add the piece model.AnimationManager.LaunchAnimationSequence( new MoveToFrontOfBoardAnimation(stackBefore, boardBefore), new MoveStackToHandAnimation(stackBefore), (stackBefore == stackAfter ? (IAnimation) new FillPlayerHandAnimation(playerGuid, stackBefore) : (IAnimation) new MergeStacksAnimation(stackAfter, stackBefore, insertionIndex))); }
private decimal GetOrDistributeMoneyTo(IPlayer player, IPlayerHand playerHand) { switch (playerHand.Outcome) { case HandOutcome.InProgress: throw new InvalidOperationException("Cannot get or distribute money to hand already in play"); case HandOutcome.Won: if (playerHand.IsBlackjack) { player.CurrentTotalCash += Math.Round(playerHand.Bet * Constants.BlackjackBetWinMultiplier, Constants.DecimalDigitsForCash); } else { player.CurrentTotalCash += Math.Round(playerHand.Bet * Constants.NonBlackjackBetWinMultiplier, Constants.DecimalDigitsForCash); } return(0); case HandOutcome.Lost: return(playerHand.Bet); case HandOutcome.Pushed: player.CurrentTotalCash += playerHand.Bet; return(0); default: throw new ArgumentOutOfRangeException(); } }
public sealed override void Handle(Controller controller) { IPlayer sender = controller.Model.GetPlayer(senderId); if (sender != null) { IGame game = controller.Model.CurrentGameBox.CurrentGame; // is the terrain in the player's hand? if (boardId != -1) { // no IBoard board = game.GetBoardById(boardId); if (board != null) { IStack stack = board.GetStackFromZOrder(zOrder); sender.StackBeingDragged = stack.Pieces[0]; sender.DragAndDropAnchor = anchor; } } else { // yes, in the hand if (sender.Guid != Guid.Empty) { IPlayerHand playerHand = game.GetPlayerHand(sender.Guid); if (playerHand != null && playerHand.Count > zOrder) { IPiece piece = playerHand.Pieces[zOrder]; sender.PieceBeingDragged = piece; sender.DragAndDropAnchor = anchor; } } } } }
public void SplitInto(IPlayerHand hand) { var card2 = _cards[1]; _cards.RemoveAt(1); hand.AddCard(card2); CreatedFromSplit = true; hand.CreatedFromSplit = true; }
public decimal GetInitialBetAmount(IPlayerHand lastHand, decimal playerTotalCash, TableSettings tableSettings) { if (playerTotalCash < tableSettings.MinimumBet) { throw new InvalidOperationException("Not enough money to play the game"); } return(tableSettings.MinimumBet); }
public MainViewModel(ISimulationController controller, IPlayerHand playerHand) { _controller = controller; _playerHand = playerHand; _roundCounts = controller.InitializeRoundCounts(); _simulatedDoubleQuote = "0% (0/0)"; _result = new Result(); My = 22; Sigma = 12; }
/// <summary>Execute this command.</summary> public override void Do() { preventConflict(stackBefore, stackAfter); boardBefore = stackBefore.Board; positionBefore = stackBefore.Position; piece = (ITerrainClone)stackBefore.Pieces[0]; zOrderBefore = ((Board)boardBefore).GetZOrder(stackBefore); rotationAngleBefore = piece.RotationAngle; sideBefore = piece.Side; // does the hand already contain an identical clone? IPlayerHand playerHand = model.CurrentGameBox.CurrentGame.GetPlayerHand(playerGuid); for (int i = 0; i < playerHand.Count; ++i) { ITerrainClone handPiece = stackAfter.Pieces[i] as ITerrainClone; if (handPiece != null && handPiece.Prototype == piece.Prototype) { // yes -> simply move the piece to the new insertion index if (playerGuid == model.ThisPlayer.Guid) { model.AnimationManager.LaunchAnimationSequence( new RemoveTerrainAnimation(stackBefore), new RearrangePlayerHandAnimation(playerHand, i, insertionIndex)); } else { model.AnimationManager.LaunchAnimationSequence( new MoveToFrontOfBoardAnimation(stackBefore, boardBefore), new MoveStackToHandAnimation(stackBefore), new RemoveTerrainAnimation(stackBefore), new RearrangePlayerHandAnimation(playerHand, i, insertionIndex)); } return; } } // add the piece if (playerGuid == model.ThisPlayer.Guid) { model.AnimationManager.LaunchAnimationSequence( (stackBefore == stackAfter ? (IAnimation) new FillPlayerHandAnimation(playerGuid, stackBefore) : (IAnimation) new MergeStacksAnimation(stackAfter, stackBefore, insertionIndex))); } else { model.AnimationManager.LaunchAnimationSequence( new MoveToFrontOfBoardAnimation(stackBefore, boardBefore), new MoveStackToHandAnimation(stackBefore), (stackBefore == stackAfter ? (IAnimation) new FillPlayerHandAnimation(playerGuid, stackBefore) : (IAnimation) new MergeStacksAnimation(stackAfter, stackBefore, insertionIndex))); } }
public sealed override void HandleAccept(Controller controller) { IModel model = controller.Model; IGame game = model.CurrentGameBox.CurrentGame; // is the terrain in the player's hand? if (boardId != -1) { // no IBoard board = game.GetBoardById(boardId); if (board != null) { IStack stackBeingDropped = board.GetStackFromZOrder(zOrder); IPiece piece = stackBeingDropped.Pieces[0]; if (senderId == model.ThisPlayer.Id) { controller.IdleState.AcceptRotation(); model.CommandManager.ExecuteCommandSequence(new ConfirmedRotatePieceCommand(model, piece, rotationIncrements)); } else { model.CommandManager.ExecuteCommandSequence(new RotatePieceCommand(model, piece, rotationIncrements)); } } } else { // yes, in the hand if (senderId == model.ThisPlayer.Id) { controller.IdleState.AcceptRotation(); } else { IPlayer sender = model.GetPlayer(senderId); if (sender != null && sender.Guid != Guid.Empty) { IPlayerHand playerHand = game.GetPlayerHand(sender.Guid); if (playerHand != null && playerHand.Count > zOrder) { IPiece piece = playerHand.Pieces[zOrder]; if (model.AnimationManager.IsBeingAnimated(piece.Stack)) { model.AnimationManager.EndAllAnimations(); } model.AnimationManager.LaunchAnimationSequence(new InstantRotatePiecesAnimation(new IPiece[1] { piece }, rotationIncrements)); } } } } }
/// <summary>Returns the index from left to right in the hand at the given position.</summary> /// <param name="mouseScreenPosition">Position in screen coordinates.</param> /// <returns>An value indicating the position in the stack from 0 (leftmost) to the number of pieces in the stack (rightmost).</returns> private int getIndexAtPosition(PointF mouseScreenPosition) { IGame game = model.CurrentGameBox.CurrentGame; IPlayerHand playerHand = game.GetPlayerHand(model.ThisPlayer.Guid); if (playerHand.Count > 0) { RectangleF area = view.HandArea; IPiece[] pieces = playerHand.Pieces; int handCount = 0; float totalWidth = 0; for (int i = 0; i < pieces.Length; ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { totalWidth += piece.Size.Width; ++handCount; } } float offset = (handCount < 2 ? 0.0f : Math.Min(0.0f, (area.Width - 4.0f * (handCount + 1) - totalWidth * pieceScaling) / (handCount - 1))); float xPos = area.X + 4.0f; for (int i = 0; i < pieces.Length; ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { float pieceWidth = piece.Size.Width * pieceScaling; if (piece == focusPiece) { if (mouseScreenPosition.X < xPos + pieceWidth) { return(mouseScreenPosition.X < xPos + pieceWidth * 0.5f ? i : i + 1); } xPos += pieceWidth + 4.0f; } else { if (mouseScreenPosition.X < xPos + pieceWidth + offset) { return(mouseScreenPosition.X < xPos + pieceWidth * 0.5f ? i : i + 1); } xPos += pieceWidth + 4.0f + offset; } } } return(pieces.Length); } return(0); }
public void When_Getting_Deep_Copy_Of_Player_Hand_Should_Have_Same_Card_Values_In_The_Copy() { _sut.Cards.Add(new Card(CardType.Eight, CardSuit.Clubs, _blackjackCardValueAssigner)); _sut.Cards.Add(new Card(CardType.Jack, CardSuit.Clubs, _blackjackCardValueAssigner)); _sut.Bet = 10M; IPlayerHand deepCopyOfPlayerHand = _sut.GetDeepCopy(); for (int cardIndex = 0; cardIndex < _sut.Cards.Count; cardIndex++) { Assert.AreEqual(_sut.Cards.ElementAt(cardIndex), deepCopyOfPlayerHand.Cards.ElementAt(cardIndex)); } }
public sealed override void HandleAccept(Controller controller) { IModel model = controller.Model; IGame game = model.CurrentGameBox.CurrentGame; IPlayer sender = model.GetPlayer(senderId); // is the terrain in the player's hand? if (boardId != -1) { // no IBoard board = game.GetBoardById(boardId); if (board != null) { IStack stackBeingDropped = board.GetStackFromZOrder(zOrder); IBoard visibleBoard = model.CurrentGameBox.CurrentGame.VisibleBoard; if (board == visibleBoard) { model.CommandManager.ExecuteCommandSequence( new CommandContext(visibleBoard, stackBeingDropped.BoundingBox), new CommandContext(visibleBoard), new DragDropStackCommand(model, stackBeingDropped, newPosition)); } else { model.CommandManager.ExecuteCommandSequence( new CommandContext(stackBeingDropped.Board, stackBeingDropped.BoundingBox), new CommandContext(visibleBoard), new DragDropStackFromOtherBoardCommand(model, stackBeingDropped, visibleBoard, newPosition)); } } if (sender != null) { sender.StackBeingDragged = null; } } else { // yes, in the hand if (sender != null && sender.Guid != Guid.Empty) { IPlayerHand playerHand = game.GetPlayerHand(sender.Guid); if (playerHand != null && playerHand.Count > zOrder) { ITerrainClone piece = (ITerrainClone)playerHand.Pieces[zOrder]; model.CommandManager.ExecuteCommandSequence( new CloneTerrainFromHandCommand(model, sender.Guid, piece, newPosition)); } sender.PieceBeingDragged = null; } } }
public sealed override void HandleAccept(Controller controller) { IModel model = controller.Model; IGame game = model.CurrentGameBox.CurrentGame; // is the terrain in the player's hand? if (boardId != -1) { // no IBoard board = game.GetBoardById(boardId); if (board != null) { IStack stack = board.GetStackFromZOrder(zOrder); IPiece piece = stack.Pieces[0]; if (piece.CounterSection.Type == CounterSectionType.TwoSided) { ISelection selection = piece.Select(); model.CommandManager.ExecuteCommandSequence(new FlipSelectionCommand(model, selection)); } } } else { // yes, in the hand IPlayer sender = model.GetPlayer(senderId); if (sender != null && sender.Guid != Guid.Empty) { IPlayerHand playerHand = game.GetPlayerHand(sender.Guid); if (playerHand != null && playerHand.Count > zOrder) { IPiece piece = playerHand.Pieces[zOrder]; // piece is in a player's hand -> it can't be undone if (model.AnimationManager.IsBeingAnimated(piece.Stack)) { model.AnimationManager.EndAllAnimations(); } if (senderId == model.ThisPlayer.Id) { model.AnimationManager.LaunchAnimationSequence(new FlipPiecesAnimation(new IPiece[] { piece })); } else { model.AnimationManager.LaunchAnimationSequence(new InstantFlipPiecesAnimation(new IPiece[] { piece })); } } } } }
public bool OfferDoubleDown(IPlayerHand playerHand, IBlackjackCard dealerFaceUpCard) { // Simple Strategy - always accept if eligible if (!playerHand.EligibleForDoubleDown) { return false; } var originalAmount = playerHand.Bet.Amount; Balance -= originalAmount; playerHand.Bet = new DoubleDownBet(originalAmount * 2); return true; }
public sealed override void HandleAccept(Controller controller) { IModel model = controller.Model; IGame game = model.CurrentGameBox.CurrentGame; IPlayer sender = model.GetPlayer(senderId); // is the terrain in the player's hand? if (boardId != -1) { // no IBoard board = game.GetBoardById(boardId); if (board != null) { IStack stack = board.GetStackFromZOrder(zOrder); CommandContext context = new CommandContext(board, stack.BoundingBox); model.CommandManager.ExecuteCommandSequence( context, context, new RemoveTerrainCommand(model, stack)); } if (sender != null) { sender.StackBeingDragged = null; } } else { // yes, in the hand if (sender != null && sender.Guid != Guid.Empty) { IPlayerHand playerHand = game.GetPlayerHand(sender.Guid); if (playerHand != null && playerHand.Count > zOrder) { ITerrainClone piece = (ITerrainClone)playerHand.Pieces[zOrder]; model.CommandManager.ExecuteCommandSequence( new RemoveTerrainFromHandCommand(model, sender.Guid, piece)); } } if (sender != null) { sender.PieceBeingDragged = null; } } }
public sealed override void HandleAccept(Controller controller) { // this is a private action -> it can't be undone IModel model = controller.Model; IPlayer sender = model.GetPlayer(senderId); if (sender != null) { if (sender.Guid != Guid.Empty) { IPlayerHand playerHand = model.CurrentGameBox.CurrentGame.GetPlayerHand(sender.Guid); if (playerHand != null && playerHand.Count > 0) { if (model.AnimationManager.IsBeingAnimated(playerHand.Pieces[0].Stack)) { model.AnimationManager.EndAllAnimations(); } model.AnimationManager.LaunchAnimationSequence( new RearrangePlayerHandAnimation(playerHand, currentIndex, insertionIndex)); } } sender.PieceBeingDragged = null; } }
public bool RuleSatisfied(IPlayerHand hand) { return(hand.HandSize <= 5); }
public override void HandleLeftMouseButtonDown() { // over the board if (model.ThisPlayer.CursorLocation is IBoardCursorLocation) { IBoardCursorLocation location = (IBoardCursorLocation)model.ThisPlayer.CursorLocation; // over a piece if (location.Piece != null) { PointF piecePosition = location.Piece.Position; model.ThisPlayer.DragAndDropAnchor = new PointF( location.ModelPosition.X - piecePosition.X, location.ModelPosition.Y - piecePosition.Y); controller.SelectingStackState.StackBottomBeingSelected = location.Piece; controller.State = controller.SelectingStackState; // over an empty space with the stack inspector visible } else if (model.CurrentSelection != null && !model.CurrentSelection.Empty) { controller.State = controller.MovingState; // over an empty space (no stack inspector) } else { controller.State = controller.ScrollingState; } // over the tabs } else if (model.ThisPlayer.CursorLocation is ITabsCursorLocation) { ITabsCursorLocation location = (ITabsCursorLocation)model.ThisPlayer.CursorLocation; // over an icon if (location.Icon != TabsIcon.None) { // Undo if (location.Icon == TabsIcon.Undo) { if (model.CommandManager.CanUndo) { networkClient.Send(new UndoMessage(model.StateChangeSequenceNumber)); } // Redo } else if (location.Icon == TabsIcon.Redo) { if (model.CommandManager.CanRedo) { networkClient.Send(new RedoMessage(model.StateChangeSequenceNumber)); } // Show/Hide hand } else if (location.Icon == TabsIcon.Hand) { if (model.ThisPlayer.Guid != Guid.Empty) { IPlayerHand playerHand = model.CurrentGameBox.CurrentGame.GetPlayerHand(model.ThisPlayer.Guid); if (controller.View.Hand.IsVisible) { controller.View.Hand.IsVisible = false; if (playerHand != null && playerHand.Count == 0) { networkClient.Send(new RemovePlayerHandMessage(model.StateChangeSequenceNumber)); } } else { controller.View.Hand.IsVisible = true; if (playerHand == null) { networkClient.Send(new AddPlayerHandMessage(model.StateChangeSequenceNumber)); } } } // Terrain mode } else if (location.Icon == TabsIcon.TerrainMode) { networkClient.Send(new ChangeModeMessage(model.StateChangeSequenceNumber, (model.CurrentGameBox.CurrentGame.Mode == Mode.Terrain ? Mode.Default : Mode.Terrain))); // Stacking } else if (location.Icon == TabsIcon.Stacking) { networkClient.Send(new ChangeStackingMessage(model.StateChangeSequenceNumber)); // Hide/reveal board } else if (location.Icon == TabsIcon.HideReveal) { Guid visibleBoardOwner = model.CurrentGameBox.CurrentGame.VisibleBoard.Owner; if (model.CurrentGameBox.Reference != model.GameLibrary.DefaultGameBox && model.ThisPlayer.Guid != Guid.Empty) { if (visibleBoardOwner == Guid.Empty || visibleBoardOwner == model.ThisPlayer.Guid) { networkClient.Send(new HideRevealBoardMessage(model.StateChangeSequenceNumber)); } } // Tab scrollers } else if (location.Icon == TabsIcon.FirstTab) { view.Tabs.ShowFirstTab(); } else if (location.Icon == TabsIcon.PreviousTab) { view.Tabs.ShowPreviousTab(); } else if (location.Icon == TabsIcon.NextTab) { view.Tabs.ShowNextTab(); } else if (location.Icon == TabsIcon.LastTab) { view.Tabs.ShowLastTab(); } // over a tab } else if (location.Tab != null) { networkClient.Send(new VisibleBoardChangedMessage(model.StateChangeSequenceNumber, location.Tab.Id)); } // over the stack inspector } else if (model.ThisPlayer.CursorLocation is IStackInspectorCursorLocation) { IStackInspectorCursorLocation location = (IStackInspectorCursorLocation)model.ThisPlayer.CursorLocation; // over an icon if (location.Icon != StackInspectorIcon.None) { // Close if (location.Icon == StackInspectorIcon.Close) { if (model.CurrentSelection != null) { SelectionChangedMessage.SelectionInfo selectionInfo = new SelectionChangedMessage.SelectionInfo(); selectionInfo.StackId = -1; networkClient.Send(new SelectionChangedMessage(model.StateChangeSequenceNumber, selectionInfo)); } // Recycle } else if (location.Icon == StackInspectorIcon.Recycle) { if (model.CurrentSelection != null && !model.CurrentSelection.Empty && !model.CurrentSelection.Stack.AttachedToCounterSection) { // assumption: the stack will remain unchanged in the meantime if (!model.AnimationManager.IsBeingAnimated(model.CurrentSelection.Stack)) { networkClient.Send(new UnpunchSelectionMessage(model.StateChangeSequenceNumber)); } } // Shuffle } else if (location.Icon == StackInspectorIcon.Shuffle) { if (model.CurrentSelection != null && model.CurrentSelection.Stack.Pieces.Length > 1) { // assumption: the stack will remain unchanged in the meantime if (!model.AnimationManager.IsBeingAnimated(model.CurrentSelection.Stack)) { networkClient.Send(new ShuffleMessage(model.StateChangeSequenceNumber)); } } // Invert } else if (location.Icon == StackInspectorIcon.Invert) { if (model.CurrentSelection != null && model.CurrentSelection.Stack.Pieces.Length > 1) { // assumption: the stack will remain unchanged in the meantime if (!model.AnimationManager.IsBeingAnimated(model.CurrentSelection.Stack)) { networkClient.Send(new InvertMessage(model.StateChangeSequenceNumber)); } } } // over a piece } else if (location.Piece != null) { model.ThisPlayer.DragAndDropAnchor = location.AnchorPosition; controller.SelectingPieceState.PieceBeingSelected = location.Piece; controller.State = controller.SelectingPieceState; } // over the hand } else if (model.ThisPlayer.CursorLocation is IHandCursorLocation) { IHandCursorLocation location = (IHandCursorLocation)model.ThisPlayer.CursorLocation; // over an icon if (location.Icon != HandIcon.None) { // Resize handle if (location.Icon == HandIcon.Resize) { controller.State = controller.ResizingHandState; // Pin/Unpin } else if (location.Icon == HandIcon.Pin) { view.Hand.IsPinned = !view.Hand.IsPinned; } // over a piece } else if (location.Piece != null) { model.ThisPlayer.DragAndDropAnchor = location.AnchorPosition; controller.SelectingPieceState.PieceBeingSelected = location.Piece; controller.State = controller.SelectingPieceState; } // over a menu item } else if (model.ThisPlayer.CursorLocation is IMenuCursorLocation) { IMenuCursorLocation location = (IMenuCursorLocation)model.ThisPlayer.CursorLocation; if (!location.Item.IsDisabled && location.Item.UserData != null) { ((ZunTzu.Control.Menu.IMenuItem)location.Item.UserData).Select(controller); } } }
public PlayerService(IPlayerHand playerHand) { this.playerHand = playerHand; }
public bool ShouldSplit(IPlayerHand currentHand, ICard visibleCard) { return(currentHand.Cards.Count == 2 && currentHand.Cards[0].Type == CardType.Ace && currentHand.Cards[1].Type == CardType.Ace); }
/// <summary>Execute this command.</summary> public override void Do() { if (piece is ITerrainPrototype) { if (stackAfter != null) { preventConflict(stackAfter); // does the hand already contain an identical clone? for (int i = 0; i < stackAfter.Pieces.Length; ++i) { ITerrainClone handPiece = stackAfter.Pieces[i] as ITerrainClone; if (handPiece != null && handPiece.Prototype == piece) { // yes -> simply move the piece to the new insertion index IPlayerHand playerHand = model.CurrentGameBox.CurrentGame.GetPlayerHand(playerGuid); model.AnimationManager.LaunchAnimationSequence( new RearrangePlayerHandAnimation(playerHand, i, insertionIndex)); return; } } } // add the piece clone = new TerrainClone((TerrainPrototype)piece); stackBefore = clone.Stack; sideBefore = piece.Side; if (playerGuid == model.ThisPlayer.Guid) { model.AnimationManager.LaunchAnimationSequence( new MoveToFrontOfBoardAnimation(stackBefore, piece.CounterSection.CounterSheet), (stackAfter == null ? (IAnimation) new FillPlayerHandAnimation(playerGuid, stackBefore) : (IAnimation) new MergeStacksAnimation(stackAfter, stackBefore, insertionIndex))); } else { model.AnimationManager.LaunchAnimationSequence( new MoveToFrontOfBoardAnimation(stackBefore, piece.CounterSection.CounterSheet), new MoveStackToHandAnimation(stackBefore), (stackAfter == null ? (IAnimation) new FillPlayerHandAnimation(playerGuid, stackBefore) : (IAnimation) new MergeStacksAnimation(stackAfter, stackBefore, insertionIndex))); } } else { preventConflict(stackBefore, stackAfter); sideBefore = piece.Side; if (playerGuid == model.ThisPlayer.Guid) { model.AnimationManager.LaunchAnimationSequence( new DetachStacksAnimation(new IStack[] { stackBefore }, new Side[] { sideBefore }), new MoveToFrontOfBoardAnimation(stackBefore, piece.CounterSection.CounterSheet), (stackBefore == stackAfter ? (IAnimation) new FillPlayerHandAnimation(playerGuid, stackBefore) : (IAnimation) new MergeStacksAnimation(stackAfter, stackBefore, insertionIndex))); } else { model.AnimationManager.LaunchAnimationSequence( new DetachStacksAnimation(new IStack[] { stackBefore }, new Side[] { sideBefore }), new MoveToFrontOfBoardAnimation(stackBefore, piece.CounterSection.CounterSheet), new MoveStackToHandAnimation(stackBefore), (stackBefore == stackAfter ? (IAnimation) new FillPlayerHandAnimation(playerGuid, stackBefore) : (IAnimation) new MergeStacksAnimation(stackAfter, stackBefore, insertionIndex))); } } }
public RearrangePlayerHandAnimation(IPlayerHand playerHand, int currentIndex, int insertionIndex) { this.playerHand = (PlayerHand)playerHand; indexInStackBefore = currentIndex; indexInStackAfter = (insertionIndex < currentIndex ? insertionIndex : insertionIndex - 1); }
public bool ShouldDoubleDown(IPlayerHand currentHand, ICard visibleCard) { return(currentHand.GetCardValues().Contains(DOUBLE_DOWN_VALUE) && !currentHand.GetCardValues().Contains(Constants.BestHandValue)); }
public bool Hit(IPlayerHand playerHand, IBlackjackCard dealerFaceUpCard) { // Simplistic strategy return playerHand.Value() < 17 && playerHand.Bet is AnteBet; }
public override void HandleLeftMouseButtonUp() { IPlayer thisPlayer = model.ThisPlayer; IPiece pieceBeingDragged = thisPlayer.PieceBeingDragged; IPlayerHand playerHand = model.CurrentGameBox.CurrentGame.GetPlayerHand(thisPlayer.Guid); if (pieceBeingDragged != null && playerHand.Count > 0 && playerHand.Pieces[0].Stack == pieceBeingDragged.Stack) { ICursorLocation cursorLocation = thisPlayer.CursorLocation; // over the hand if (cursorLocation is IHandCursorLocation) { IHandCursorLocation location = (IHandCursorLocation)cursorLocation; int insertionIndex = location.Index; int currentIndex = pieceBeingDragged.IndexInStackFromBottomToTop; // assumption: the stack will remain unchanged in the meantime if (insertionIndex != currentIndex && insertionIndex != currentIndex + 1 && !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack)) { networkClient.Send(new RearrangePlayerHandMessage(model.StateChangeSequenceNumber, currentIndex, insertionIndex)); } else { networkClient.Send(new DragDropAbortedMessage()); } // over the board } else if (cursorLocation is IBoardCursorLocation) { IBoardCursorLocation location = (IBoardCursorLocation)cursorLocation; IPiece pieceAtMousePosition = location.Piece; // over an unattached stack if (model.CurrentGameBox.CurrentGame.StackingEnabled && pieceAtMousePosition != null && !pieceAtMousePosition.Stack.AttachedToCounterSection && pieceAtMousePosition.GetType() == pieceBeingDragged.GetType() && !(pieceBeingDragged is ITerrainClone)) { // assumption: both stacks will remain unchanged in the meantime if (pieceAtMousePosition.Stack != pieceBeingDragged.Stack && !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack) && !model.AnimationManager.IsBeingAnimated(pieceAtMousePosition.Stack)) { networkClient.Send(new DragDropPieceOnTopOfOtherStackMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id, pieceAtMousePosition.Stack.Id)); } else { networkClient.Send(new DragDropAbortedMessage()); } // over an empty space } else { // assumption: the stack will remain unchanged in the meantime if (!model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack)) { PointF newPiecePosition = new PointF( location.ModelPosition.X - thisPlayer.DragAndDropAnchor.X, location.ModelPosition.Y - thisPlayer.DragAndDropAnchor.Y); if (pieceBeingDragged is ITerrainClone) { networkClient.Send(new DragDropTerrainMessage(model.StateChangeSequenceNumber, -1, pieceBeingDragged.IndexInStackFromBottomToTop, newPiecePosition)); } else { networkClient.Send(new DragDropPieceMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id, newPiecePosition)); } } else { networkClient.Send(new DragDropAbortedMessage()); } } // over the stack inspector } else if (cursorLocation is IStackInspectorCursorLocation) { IStackInspectorCursorLocation location = (IStackInspectorCursorLocation)cursorLocation; // assumption: boths stacks will remain unchanged in the meantime if (model.CurrentSelection != null && model.CurrentSelection.Stack != pieceBeingDragged.Stack && model.CurrentSelection.Stack.Pieces[0].GetType() == pieceBeingDragged.GetType() && !model.AnimationManager.IsBeingAnimated(model.CurrentSelection.Stack) && !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack)) { networkClient.Send(new DragDropPieceIntoOtherStackMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id, location.Index)); } else { networkClient.Send(new DragDropAbortedMessage()); } // over a counter sheet tab // assumption: the stack will remain unchanged in the meantime } else if (cursorLocation is ITabsCursorLocation && ((ITabsCursorLocation)cursorLocation).Tab is ICounterSheet && !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack)) { if (pieceBeingDragged is ITerrainClone) { networkClient.Send(new RemoveTerrainMessage(model.StateChangeSequenceNumber, -1, pieceBeingDragged.IndexInStackFromBottomToTop)); } else { networkClient.Send(new UnpunchPieceMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id)); } } else { networkClient.Send(new DragDropAbortedMessage()); } } thisPlayer.PieceBeingDragged = null; controller.State = controller.IdleState; }
/// <summary>Displays the next frame.</summary> public override void Render(IGraphics graphics, long currentTimeInMicroseconds) { if (model.PlayerCount > 0) { RectangleF area = view.PlayerViewArea; float margin = marginCoeff * view.GameDisplayAreaInPixels.Height; float singleLineHeight = singleLineHeightCoeff * view.GameDisplayAreaInPixels.Height; IImage background = graphics.MonochromaticImage; float scale = view.GameDisplayAreaInPixels.Height / 1200.0f; // render player list area.Y += margin; foreach (IPlayer player in model.Players) { // render colored background RectangleF backgroundArea = new RectangleF(area.X + scale * 68.0f, area.Y + scale * 15.0f, scale * 120.0f, scale * 46.0f); background.Render(backgroundArea, player.Color); // render player picture RectangleF playerIconArea = new RectangleF(area.X + scale * 6.0f, area.Y + scale * 6.0f, scale * 64.0f, scale * 64.0f); if (player.VideoAssetIndex == -1) { playerIcon.Render(playerIconArea); } else { playerVideoFrames[player.VideoAssetIndex].Render(playerIconArea); } // render frame RectangleF frameArea = new RectangleF(area.X, area.Y, scale * 195.0f, scale * 76.0f); frameIcon.Render(frameArea); // render name RectangleF firstNameArea = new RectangleF(area.X + scale * 76.0f, area.Y + scale * 17.0f, scale * 110.0f, scale * 25.0f); graphics.DrawTextToFit(font, 0xFFFFFFFF, firstNameArea, StringAlignment.Center, player.FirstName); RectangleF lastNameArea = new RectangleF(area.X + scale * 76.0f, area.Y + scale * 39.0f, scale * 110.0f, scale * 20.0f); graphics.DrawTextToFit(font, 0xFFFFFFFF, lastNameArea, StringAlignment.Center, player.LastName); if (player == model.ThisPlayer) { background.Render(new RectangleF(area.X + scale * 193.0f, area.Y + scale * 14.0f, scale * 7.0f, scale * 46.0f), 0xFF000000); background.Render(new RectangleF(area.X + scale * 193.0f, area.Y + scale * (60.0f - model.NetworkClient.VoiceInputLevel * (46.0f / 99.0f)), scale * 7.0f, scale * model.NetworkClient.VoiceInputLevel * (46.0f / 99.0f)), (model.NetworkClient.IsRecording ? 0xFF00FF00 : 0xFFFFFFFF)); microphoneLevelIcon.Render(new RectangleF(area.X + scale * 187.0f, area.Y + scale * 8.0f, scale * 19.0f, scale * 59.0f)); microphoneThresholdIcon.Render(new RectangleF(area.X + scale * 198.0f, area.Y + scale * (54.5f - model.NetworkClient.VoiceActivationThresholdLevel * (46.0f / 99.0f)), scale * 9.0f, scale * 11.0f)); } else if (player.VoicePlaybackInProgress) { loudspeakerIcon.Render(new RectangleF(area.X + scale * 60.0f, area.Y + scale * 37.0f - 7.5f, 10.0f, 15.0f), player.Color); float animationProgress = (currentTimeInMicroseconds % (long)300000) * 0.00000333333f; float wavesPositionX = 6.0f + animationProgress * 6.0f; float wavesHalfHeight = 1.0f + wavesPositionX * 0.8f; soundWavesIcon.Render(new RectangleF(area.X + scale * 60.0f + wavesPositionX, area.Y + scale * 37.0f - wavesHalfHeight, wavesHalfHeight * (10.0f / 7.5f), wavesHalfHeight * 2.0f), player.Color); } // render hand count IPlayerHand playerHand = model.CurrentGameBox.CurrentGame.GetPlayerHand(player.Guid); if (playerHand != null) { RectangleF handArea = new RectangleF(area.X - 7.0f, area.Y + scale * (76.0f * 0.5f) - 9.0f, 17.0f, 18.0f); handIcon.Render(handArea, player.Color); if (playerHand.Count > 0) { handArea.Offset(2.0f, 3.0f); graphics.DrawText(handCountFont, 0xFFFFFFFF, handArea, StringAlignment.Center, playerHand.Count.ToString()); } } area.Y += singleLineHeight; } } }
/// <summary>Displays the next frame.</summary> public override void Render(IGraphics graphics, long currentTimeInMicroseconds) { IGame game = model.CurrentGameBox.CurrentGame; IPlayerHand playerHand = game.GetPlayerHand(model.ThisPlayer.Guid); if (isVisible && playerHand != null) { // animate hand folding/unfolding if (state == HandState.Unfolding) { float unfoldingSpeed = unfoldedHeight / 300000.0f; currentHeight += (int)(unfoldingSpeed * (currentTimeInMicroseconds - previousRenderTime)); if (currentHeight >= unfoldedHeight) { currentHeight = unfoldedHeight; state = HandState.Unfolded; } } else if (state == HandState.Folding && timeBeforeFolding < currentTimeInMicroseconds) { if (timeBeforeFolding == 0) { timeBeforeFolding = currentTimeInMicroseconds + 1000000; } else { float foldingSpeed = unfoldedHeight / 300000.0f; currentHeight -= (int)(foldingSpeed * (currentTimeInMicroseconds - previousRenderTime)); if (currentHeight <= 0) { currentHeight = 0; state = HandState.Folded; } } } if (state != HandState.Folded && currentHeight > 0) { RectangleF area = view.HandArea; HandCursorLocation cursorLocation = model.ThisPlayer.CursorLocation as HandCursorLocation; // render background frameImageElements[0].Render(new RectangleF(area.X, area.Y, area.Width, 6.0f)); if (area.Height > 6.0f) { frameImageElements[1].Render(new RectangleF(area.X, area.Y + 6.0f, area.Width, area.Height - 6.0f)); } // render pieces if (playerHand.Count > 0) { IPiece[] pieces = playerHand.Pieces; focusPiece = (cursorLocation != null ? cursorLocation.FocusPiece : null); int handCount = 0; float totalWidth = 0; float minWidth = float.MaxValue; for (int i = 0; i < pieces.Length; ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { ++handCount; float width = piece.Size.Width; totalWidth += width; if (width < minWidth) { minWidth = width; } } } // maxScaling is such that offset == 2.0f - minWidth * pieceScaling // => 2.0f - minWidth * pieceScaling == (area.Width - 4.0f * (pieces.Length + 1) - totalWidth * pieceScaling) / (pieces.Length - 1) // => 2.0f * (pieces.Length - 1) - minWidth * pieceScaling * (pieces.Length - 1) == area.Width - 4.0f * (pieces.Length + 1) - totalWidth * pieceScaling // => (totalWidth - minWidth * (pieces.Length - 1)) * pieceScaling == area.Width - 4.0f * (pieces.Length + 1) - 2.0f * (pieces.Length - 1) // => pieceScaling == (area.Width - 4.0f * (pieces.Length + 1) - 2.0f * (pieces.Length - 1)) / (totalWidth - minWidth * (pieces.Length - 1)) float maxScaling = Math.Min(1.0f, (handCount < 2 ? (area.Width - 4.0f * (handCount + 1)) / totalWidth : (area.Width - 6.0f * handCount - 2.0f) / (totalWidth - minWidth * (handCount - 1)))); pieceScaling = Math.Max(0.0625f, Math.Min(maxScaling, pieceScaling)); float offset = (handCount < 2 ? 0.0f : Math.Min(0.0f, (area.Width - 4.0f * (handCount + 1) - totalWidth * pieceScaling) / (handCount - 1))); // render each piece in order (from back to front) { float xPos = area.X + 4.0f; float yPos = area.Y + 10.0f; for (int i = 0; i < pieces.Length; ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { SizeF size = piece.Size; SizeF scaledSize = new SizeF(size.Width * pieceScaling, size.Height * pieceScaling); PointF position = new PointF(xPos + scaledSize.Width * 0.5f, yPos + scaledSize.Height * 0.5f); float flipAngleCosinus = piece.FlipAngleCosinus; RectangleF localisation = new RectangleF( position.X - scaledSize.Width * 0.5f * flipAngleCosinus, position.Y - scaledSize.Height * 0.5f, scaledSize.Width * flipAngleCosinus, scaledSize.Height); // render a roll-over hint if (cursorLocation != null && piece == cursorLocation.Piece) { // cards pop up when rolled over if (piece is ICard) { float overflow = localisation.Bottom - area.Bottom; if (overflow > 0.0f) { localisation.Y -= overflow; } } // computes modulation color for blinking uint blinkFactor = (uint)(128 * Math.Sin((double)(currentTimeInMicroseconds % (long)400000) * (Math.PI / 200000.0)) + 128); uint blinkModulationColor = 0xFF000000 | blinkFactor << 16 | blinkFactor << 8 | blinkFactor; RectangleF hintLocalisation = new RectangleF( localisation.X - 2.0f, localisation.Y - 2.0f, localisation.Width + 4.0f, localisation.Height + 4.0f); piece.Graphics.RenderSilhouette(hintLocalisation, piece.RotationAngle, blinkModulationColor); } piece.Graphics.Render(localisation, piece.RotationAngle); xPos += scaledSize.Width + 4.0f + (piece != focusPiece ? offset : 0.0f); } } } // render focus piece visible through the other pieces if (focusPiece != null) { float xPos = area.X + 4.0f; float yPos = area.Y + 10.0f; for (int i = 0; i < pieces.Length; ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { SizeF size = piece.Size; SizeF scaledSize = new SizeF(size.Width * pieceScaling, size.Height * pieceScaling); if (piece == focusPiece) { PointF position = new PointF(xPos + scaledSize.Width * 0.5f, yPos + scaledSize.Height * 0.5f); float flipAngleCosinus = piece.FlipAngleCosinus; RectangleF localisation = new RectangleF( position.X - scaledSize.Width * 0.5f * flipAngleCosinus, position.Y - scaledSize.Height * 0.5f, scaledSize.Width * flipAngleCosinus, scaledSize.Height); // cards pop up when rolled over if (cursorLocation != null && piece == cursorLocation.Piece && piece is ICard) { float overflow = localisation.Bottom - area.Bottom; if (overflow > 0.0f) { localisation.Y -= overflow; } } piece.Graphics.Render(localisation, piece.RotationAngle, 0x3fffffff); // 25% transparent break; } xPos += scaledSize.Width + 4.0f + offset; } } } // render insertion mark, if needed if (cursorLocation != null && (model.ThisPlayer.PieceBeingDragged != null || model.ThisPlayer.StackBeingDragged != null)) { int insertionIndex = cursorLocation.Index; float xPos = area.X + 4.0f; for (int i = 0; i < Math.Min(insertionIndex, pieces.Length); ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { xPos += piece.Size.Width * pieceScaling + 4.0f + (piece != focusPiece ? offset : 0.0f); } } IImage image = graphics.MonochromaticImage; image.Render(new RectangleF(xPos - 4.0f, area.Y + 8.0f, 3.0f, area.Height - 10.0f)); } } // icons if (state == HandState.Unfolded) { if (isPinned) { unpinIcon.Render(new RectangleF(area.Right - 12.0f, area.Y + 6.0f, 10.0f, 10.0f), (cursorLocation != null && cursorLocation.Icon == HandIcon.Pin && model.ThisPlayer.StackBeingDragged == null && model.ThisPlayer.PieceBeingDragged == null ? 0xff7fff7f : 0xffffffff)); } else { pinIcon.Render(new RectangleF(area.Right - 24.0f, area.Y + 6.0f, 22.0f, 10.0f), (cursorLocation != null && cursorLocation.Icon == HandIcon.Pin && model.ThisPlayer.StackBeingDragged == null && model.ThisPlayer.PieceBeingDragged == null ? 0xff7fff7f : 0xffffffff)); } // tool tips if (cursorLocation != null && model.ThisPlayer.StackBeingDragged == null && model.ThisPlayer.PieceBeingDragged == null) { if (cursorLocation.Icon == HandIcon.Pin) { graphics.DrawText(font, 0xff7fff7f, new RectangleF(area.Right - 33.0f, area.Y + 5.0f - 17.0f, 31.0f, 17.0f), StringAlignment.Far, (isPinned ? Resources.ToolTipUnpin : Resources.ToolTipPin)); } } } } } previousRenderTime = currentTimeInMicroseconds; }
/// <summary>Returns the piece displayed at a given position.</summary> /// <param name="mouseScreenPosition">Position in screen coordinates.</param> /// <param name="anchorPosition">Point of the piece attached to the cursor hotspot.</param> /// <returns>Piece found at the given position, or null if none was found.</returns> private IPiece getPieceAtPosition(PointF mouseScreenPosition, out PointF anchorPosition) { IGame game = model.CurrentGameBox.CurrentGame; IPlayerHand playerHand = game.GetPlayerHand(model.ThisPlayer.Guid); anchorPosition = PointF.Empty; if (playerHand.Count == 0) { return(null); } else { RectangleF area = view.HandArea; IPiece[] pieces = playerHand.Pieces; // trigger bounding box calculation RectangleF box = pieces[0].Stack.BoundingBox; int handCount = 0; float totalWidth = 0; for (int i = 0; i < pieces.Length; ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { totalWidth += piece.Size.Width; ++handCount; } } float offset = (handCount < 2 ? 0.0f : Math.Min(0.0f, (area.Width - 4.0f * (handCount + 1) - totalWidth * pieceScaling) / (handCount - 1))); float inversePieceScaling = 1.0f / pieceScaling; // each piece is tested in reverse order (from front to back) float xPos = area.X + 4.0f; float yPos = area.Y + 10.0f; IPiece pieceAtPosition = null; for (int i = 0; i < pieces.Length; ++i) { IPiece piece = pieces[i]; if ((game.Mode == Mode.Terrain) == (piece is ITerrain)) { SizeF size = piece.Size; RectangleF boundingBox = piece.BoundingBox; float shadowLength = piece.CounterSection.ShadowLength; RectangleF actualBoundingBox = new RectangleF(xPos, yPos, (boundingBox.Width - shadowLength) * pieceScaling, (boundingBox.Height - shadowLength) * pieceScaling); if (actualBoundingBox.Contains(mouseScreenPosition)) { SizeF scaledSize = new SizeF(size.Width * pieceScaling, size.Height * pieceScaling); PointF position = new PointF(xPos + scaledSize.Width * 0.5f, yPos + scaledSize.Height * 0.5f); // we have to handle rotations of the piece // apply the inverse rotation to the mouse model position PointF pieceAnchorPosition = new PointF( (mouseScreenPosition.X - position.X) * inversePieceScaling, (mouseScreenPosition.Y - position.Y) * inversePieceScaling); PointF transformedPosition; if (piece.RotationAngle == 0.0f) { transformedPosition = pieceAnchorPosition; } else { // rotation: // x <- x * cos - y * sin // y <- x * sin + y * cos float sin = (float)Math.Sin(piece.RotationAngle); float cos = (float)Math.Cos(piece.RotationAngle); transformedPosition = new PointF( pieceAnchorPosition.X * cos - pieceAnchorPosition.Y * sin, pieceAnchorPosition.X * sin + pieceAnchorPosition.Y * cos); } if (new RectangleF( -size.Width * 0.5f, -size.Height * 0.5f, size.Width, size.Height).Contains(transformedPosition)) { // is the piece completely transparent at that location? uint color = piece.Graphics.GetColorAtPosition(transformedPosition); if ((color & 0xFF000000) != 0x00000000) { // no it is not pieceAtPosition = piece; // cards pop up when rolled over if (piece is ICard) { float bottom = position.Y + scaledSize.Height * 0.5f; float overflow = bottom - area.Bottom; if (overflow > 0.0f) { pieceAnchorPosition.Y += overflow * inversePieceScaling; } } anchorPosition = pieceAnchorPosition; } } } xPos += size.Width * pieceScaling + 4.0f + (piece != focusPiece ? offset : 0.0f); } } return(pieceAtPosition); } }
public double SettleBet(IPlayerHand hand, IDealerHand dealerHand) { if (hand.Busted) return hand.Bet.LoseAmount(); if (dealerHand.Busted) { Balance += hand.Bet.Amount + hand.Bet.WinAmount(); return hand.Bet.WinAmount()*-1; } // Neither hand busted if (hand.Value() == dealerHand.Value()) { Balance += hand.Bet.Amount; hand.Bet = hand.Bet.ConvertToPushBet(); return 0; } if (hand.Value() < dealerHand.Value()) { return hand.Bet.LoseAmount(); } Balance += hand.Bet.Amount + hand.Bet.WinAmount(); return hand.Bet.WinAmount()*-1; }
public bool ShouldHit(IPlayerHand currentHand, ICard visibleCard) { var currentHandCardValues = currentHand.GetCardValues(); return(!MeetsStayCriteria(currentHandCardValues) && MeetsHitCriteria(currentHandCardValues)); }
private bool ConsiderSplitOffer(IPlayerHand playerHand, IBlackjackCard dealerFaceUpCard) { if (!playerHand.EligibleForSplit) { return false; } // Using simple logic for now var hand = new PlayerHand(); Balance -= Ante; hand.Bet = new AnteBet(Ante); _hands.Add(hand); playerHand.SplitInto(hand); return true; }