public override void ViewHas(Player viewer, Owner newOwner, Card card) { var originalOwner = _viewCards[viewer, card]; if (newOwner < originalOwner) { if (!(_cardOwners[card] <= newOwner)) { throw new InvalidOperationException($"View: {viewer} Card: {card} Owner:{_cardOwners[card]} Mistake:{newOwner}"); } var newOwnerCount = _viewCount[viewer, newOwner] + 1; _viewCards[viewer, card] = newOwner; _viewCount[viewer, newOwner] = newOwnerCount; if (newOwner.MaxCount() == newOwnerCount) { foreach (var c in Card.AllCards) { var co = _viewCards[viewer, c]; if (co > newOwner) { var nco = co - newOwner; if (nco != co) { ViewHas(viewer, nco, c); } } } } } }
protected virtual void TurnImpl(Card playedCard) { var playerOnTurn = PlayerOnTurn; #if DEBUG if (playerOnTurn != _cardOwners[playedCard] || _cardUsed[playedCard]) { throw new ArgumentException(playerOnTurn + " doesn't own the card " + playedCard); } #endif var step = (Turn%3) + 1; switch (step) { case 1: StepOne(playedCard); break; case 2: StepTwo(playedCard); break; case 3: StepThree(playedCard); break; default: throw new InvalidOperationException(); } ViewHas(Player.P1, playerOnTurn, playedCard); ViewHas(Player.P2, playerOnTurn, playedCard); ViewHas(Player.P3, playerOnTurn, playedCard); _sequence[Turn] = playedCard; _cardUsed[playedCard] = true; _remainingColorCount[playerOnTurn, playedCard.Color]--; Turn++; }
public Card(Color color, Value value) { unchecked { _card = new Card((byte) ((color*Value.Count) + value)); } }
protected virtual void Hlaska(Card playedCard) { var playedColor = playedCard.Color; var playedValue = playedCard.Value; if (playedValue == Value.VQ || playedValue == Value.VK) { var hlaska = playedValue == Value.VQ ? new Card(playedColor, Value.VK) : new Card(playedColor, Value.VQ); if (_cardOwners[hlaska] == PlayerOnTurn) { _score[PlayerOnTurn] += (byte) (playedColor == Color.T ? 4 : 2); ViewHas(Player.P1, PlayerOnTurn, hlaska); ViewHas(Player.P2, PlayerOnTurn, hlaska); ViewHas(Player.P3, PlayerOnTurn, hlaska); } } }
public Color(Card card) { _color = (byte) (card/8); }
public Player(Card card) { _player = (byte) (card/8); }
public override void ViewDoesntHave(Player viewer, Owner owner, Card card) { var newOwner = _viewCards[viewer, card] - owner; ViewHas(viewer, newOwner, card); }
public Owner this[Player viewer, Card card] = > _viewCards[viewer, card];
// ReSharper restore InconsistentNaming public bool Equals(Card other) { return _card == other._card; }
private Game MakeTurn(Card turn) { var after = new Game(this); after.TurnImpl(turn); return after; }
public virtual void ViewHas(Player viewer, Owner newOwner, Card card) { }
private void StepTwo(Card playedCard) { var playedColor = playedCard.Color; var playedValue = playedCard.Value; var cardOne = _sequence[Turn - 1]; var colorOne = cardOne.Color; var valueOne = cardOne.Value; #if DEBUG if (_remainingColorCount[PlayerOnTurn, colorOne] > 0) { if (playedColor != colorOne) { throw new ArgumentException(PlayerOnTurn + " has to honour color " + colorOne); } var canSlamColor = colorOne.AllCards .Any(card => _cardOwners[card] == PlayerOnTurn && !_cardUsed[card] && card.Value > valueOne); if (canSlamColor && playedColor == colorOne && playedValue < valueOne) { throw new ArgumentException(PlayerOnTurn + " has to slam color " + colorOne); } } else if (_remainingColorCount[PlayerOnTurn, Color.T] > 0) { if (playedColor != Color.T) { throw new ArgumentException(PlayerOnTurn + " has to play trumph " + Color.T); } } #endif if (playedColor != colorOne) { // nema barvu foreach (var card in colorOne.AllCards) { if (!_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } if (playedColor != Color.T) { // nema barvu ani trumfa foreach (var card in Color.T.AllCards) { if (!_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } } // else prebyl trumfem } else { // barvu ma if (playedValue < valueOne) { // ale malou, nemuze prebit foreach (var card in colorOne.AllCards) { if (card.Value > valueOne && !_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } } } PlayerOnTurn = NextPlayer(PlayerOnTurn); }
public virtual void ViewDoesntHave(Player viewer, Owner owner, Card card) { }
private void StepThree(Card playedCard) { var playedColor = playedCard.Color; var playedValue = playedCard.Value; var cardOne = _sequence[Turn - 2]; var colorOne = cardOne.Color; var valueOne = cardOne.Value; var playerTwo = PrevPlayer(PlayerOnTurn); var playerOne = PrevPlayer(playerTwo); var playerWon = playerOne; var cardTwo = _sequence[Turn - 1]; var colorTwo = cardTwo.Color; var valueTwo = cardTwo.Value; byte score = 0; var isTrumphed = colorTwo == Color.T && colorOne != Color.T; var isTwoOut = colorTwo != colorOne; if (isTrumphed || (!isTwoOut && valueOne < valueTwo)) { playerWon = playerTwo; } #if DEBUG if (_remainingColorCount[PlayerOnTurn, colorOne] > 0) { if (playedColor != colorOne) { throw new ArgumentException(PlayerOnTurn + " has to honour color " + colorOne); } if (!isTrumphed) { var canSlamColor = colorOne.AllCards .Any(card => _cardOwners[card] == PlayerOnTurn && !_cardUsed[card] && card.Value > valueOne && (isTwoOut || card.Value > valueTwo)); if (canSlamColor && playedColor == colorOne && (playedValue < valueOne || (!isTwoOut && playedValue < valueTwo))) { throw new ArgumentException(PlayerOnTurn + " has to slam color " + colorOne); } } } else if (_remainingColorCount[PlayerOnTurn, Color.T] > 0) { if (playedColor != Color.T) { throw new ArgumentException(PlayerOnTurn + " has to play trumph " + Color.T); } var canSlamTrumph = colorTwo == Color.T && Color.T.AllCards .Any(card => _cardOwners[card] == PlayerOnTurn && !_cardUsed[card] && card.Value > valueOne && card.Value > valueTwo); if (canSlamTrumph && playedColor == Color.T && playedValue < valueTwo) { throw new ArgumentException(PlayerOnTurn + " has to slam trumph " + Color.T); } } #endif if (playedColor != colorOne) { // nema barvu foreach (var card in colorOne.AllCards) { if (card.Value > valueOne && !_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } if (playedColor != Color.T) { // nema barvu ani trumfa foreach (var card in Color.T.AllCards) { if (card.Value > valueOne && !_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } } else { //hraje trumfem if (colorTwo == Color.T) { // musi prebijet if (playedValue < valueTwo) { // ale nema foreach (var card in Color.T.AllCards) { if (card.Value > valueTwo && !_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } } else { // prebyl trumfa playerWon = PlayerOnTurn; } } else { // prebyl trumfem playerWon = PlayerOnTurn; } } } else { // barvu ma if (playedValue < valueOne || (!isTwoOut && playedValue < valueTwo)) { // dal mensi if (!isTrumphed) { // neprebiji trumfa, takze ma jenom malo a nemuze prebit if (isTwoOut) { foreach (var card in colorOne.AllCards) { var value = card.Value; if (value > valueOne && !_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } } else { foreach (var card in colorOne.AllCards) { var value = card.Value; if ((value > valueOne && value > valueTwo) && !_cardUsed[card]) { ViewDoesntHave(Player.P1, PlayerOnTurn, card); ViewDoesntHave(Player.P2, PlayerOnTurn, card); ViewDoesntHave(Player.P3, PlayerOnTurn, card); } } } } // else neprebiji trumfa, jen cti barvu } else { // prebyl barvu playerWon = PlayerOnTurn; } } if (cardOne.HasPoints()) { score++; } if (cardTwo.HasPoints()) { score++; } if (playedCard.HasPoints()) { score++; } if (Turn == 29) { score++; } _score[playerWon] += score; PlayerOnTurn = playerWon; }
private void StepOne(Card playedCard) { Hlaska(playedCard); PlayerOnTurn = NextPlayer(PlayerOnTurn); }
public Game(byte betSeven, byte betGame, bool bet100, Player playerAlone, params Card[] deck) : this(betSeven, betGame, bet100, playerAlone) { if (deck.Length != 32) { throw new ArgumentException("Card count"); } var t1 = deck[15]; var t2 = deck[16]; if (t1.HasPoints() || t2.HasPoints()) { throw new ArgumentException("Points in talon"); } var seven = new Card(Color.T, Value.V7); if (betSeven > 0 && (t1 == seven || t2 == seven)) { throw new ArgumentException("Betted seven in talon"); } for (var c = 0; c < 5; c++) { var card = deck[c]; if (_cardOwners[card] != Player.None) { throw new ArgumentException("Duplicate "+ card); } _cardOwners[card] = Player.P1; _remainingColorCount[Player.P1, card.Color]++; } for (var c = 5; c < 10; c++) { var card = deck[c]; if (_cardOwners[card] != Player.None) { throw new ArgumentException("Duplicate " + card); } _cardOwners[card] = Player.P2; _remainingColorCount[Player.P2, card.Color]++; } for (var c = 10; c < 15; c++) { var card = deck[c]; if (_cardOwners[card] != Player.None) { throw new ArgumentException("Duplicate " + card); } _cardOwners[card] = Player.P3; _remainingColorCount[Player.P3, card.Color]++; } for (var c = 17; c < 22; c++) { var card = deck[c]; if (_cardOwners[card] != Player.None) { throw new ArgumentException("Duplicate " + card); } _cardOwners[card] = Player.P1; _remainingColorCount[Player.P1, card.Color]++; } for (var c = 22; c < 27; c++) { var card = deck[c]; if (_cardOwners[card] != Player.None) { throw new ArgumentException("Duplicate " + card); } _cardOwners[card] = Player.P2; _remainingColorCount[Player.P2, card.Color]++; } for (var c = 27; c < 32; c++) { var card = deck[c]; if (_cardOwners[card] != Player.None) { throw new ArgumentException("Duplicate " + card); } _cardOwners[card] = Player.P3; _remainingColorCount[Player.P3, card.Color]++; } _cardOwners[t1] = Player.T; _cardOwners[t2] = Player.T; _remainingColorCount[Player.T, t1.Color]++; _remainingColorCount[Player.T, t2.Color]++; }