public GameManager(Player[] players, int roundsToPlay, AIBidType[] bidAITypes, AIGameType[] gameAITypes) { Players = players; aiPlayers = new Dictionary<Player, AI>(); for (int i = 0; i < 4; i++) { aiPlayers.Add(players[i], AIFactory.CreateAI(players[i], this, bidAITypes[i], gameAITypes[i])); } RoundsToPlay = roundsToPlay; RoundNumber = 1; IsGameInProgress = true; Round = new Round(players); }
public GameManager() { Players = new Player[] { new Player("Player",0),//Index 0-3 is very important. new Player("Comp 1",1), new Player("Comp 2",2), new Player("Comp 3",3) }; HumanPlayer = Players[0]; RoundsToPlay = 13; RoundNumber = 1; IsGameInProgress = true; Round = new Round(Players); aiPlayers = new Dictionary<Player, AI>(); foreach (Player player in Players.Except(new Player[] { HumanPlayer })) aiPlayers.Add(player, AIFactory.CreateAI(player, this, AIBidType.OMNISCIENT, AIGameType.PERFECTMEMORY)); /* aiPlayers.Add(Players[1], AIFactory.CreateAI(Players[1], this, AIBidType.BASIC, AIGameType.BRUTEFORCE)); aiPlayers.Add(Players[2], AIFactory.CreateAI(Players[2], this, AIBidType.BASIC, AIGameType.MEMORY)); aiPlayers.Add(Players[3], AIFactory.CreateAI(Players[3], this, AIBidType.BASIC, AIGameType.MEMORY));*/ }
/// <summary> /// To be called after ending a round, to start the next one. /// When initialized the GameManager starts a first round automatically and this function shouldn't be called. /// </summary> public void StartNewRound() { if (!IsRoundInProgress && IsGameInProgress) { if (RoundNumber < RoundsToPlay) { CyclePlayers(); RoundNumber++; foreach (AI ai in aiPlayers.Values) ai.ResetMemory(); Round = new Round(Players); } else { IsGameInProgress = false; } } }
private static bool IsTeamCurrentLeader(Round round) { return CurrentTeam(round).Players.Any(p => p == round.PileOwner); }
public static Card GetMove(Round round) { var cards = round.CurrentPlayer.hand.Cards; var pile = round.Pile; var trump = round.Trump; var teams = round.Teams; if (pile.Count > 0) { var pileSuit = pile[0].Suit; var leadCard = LeadingCard(round); if (OpposingPlayersLeftInTrick(round)) //There will still be opposing players after current player's turn. { if (cards.Any(c => c.Suit == pileSuit))//Hand contains card of same suit as pile. { if (leadCard.Suit != pileSuit)// Leadingcard is trump while pilesuit isn't trump. { return GetLowestCardStrategic(cards, pileSuit, trump); } else //leadingCard is pilesuit (which may or may not be trump) { var cardsOfSuit = cards.Where(c => c.Suit == pileSuit); if (IsTeamCurrentLeader(round))//If the team is winning, see if an opponent could possible outplay team. { bool possibleHigherCard = false; for (int i = (int)leadCard.Number; i <= (int)Numbers.ACE; i++) { if (cardsOfSuit.All(c => c.Number != (Numbers)i))//If all cards have a different number, the higher card is in another player's hand. { possibleHigherCard = true; } } if (possibleHigherCard) { return HighOrLowCardSelection(cardsOfSuit, leadCard);//If an opponent can play a higher card, try winning. } else { return GetLowestCard(cardsOfSuit);//If an opponent won't be able to play a higher card, play a low card. } } else//If the team is losing, try to win. { return HighOrLowCardSelection(cardsOfSuit, leadCard); } } } else//Hand contains no card of the same suit as pile. { if (cards.Any(c => c.Suit == trump))//Hand has trump card. { var cardsOfTrump = cards.Where(c => c.Suit == trump); if (IsTeamCurrentLeader(round)) {//Team is winning if (leadCard.Suit == trump) { return GetLowestCardStrategic(cards, pileSuit, trump); } else { if (leadCard.Number == Numbers.ACE) return GetLowestCardStrategic(cards, pileSuit, trump); else return GetLowestCard(cardsOfTrump); } } else//Team is not winning. { if (leadCard.Suit == trump)//Leadcard is trump. { if (GetHighestCard(cardsOfTrump).Number > leadCard.Number)//If AI can beat leadcard { return GetHighestCard(cardsOfTrump);//Give highest trump card } else//if AI can't beat leadcard { return GetLowestCardStrategic(cards, pileSuit, trump); } } else//Leadcard is not trump { return GetLowestCard(cardsOfTrump);//give lowest trump. } } } else //Hand contains neither pileSuit card of trump card. { return GetLowestCard(cards); } } } else //There won't be opponents after current player's turn. { if (IsTeamCurrentLeader(round))//AI's team is already winning. { return GetLowestCardStrategic(cards, pileSuit, trump); } else //AI's team is not already winning. { //Give lowest winning card. if (cards.Any(c => c.Suit == pileSuit))//Hand contains card of same suit as pile. { if (leadCard.Suit != pileSuit)// Leadingcard is trump while pilesuit isn't trump. { return GetLowestCardStrategic(cards, pileSuit, trump); } else //leadingCard is pilesuit (which may or may not be trump) { var higherCardsOfPilesuit = cards.Where(c => c.Suit == pileSuit && c.Number > leadCard.Number); if (higherCardsOfPilesuit.Count() > 0) return GetLowestCard(higherCardsOfPilesuit);//player has higher cards than leading card and gives the lowest of them. else return GetLowestCardStrategic(cards, pileSuit, trump);//player hasn't got higher cards than leading card so returns lowest card. } } else//Hand doesn't contain card of the same suit as pile. { if (cards.Any(c => c.Suit == trump))//Hand contains trump cards. { if (leadCard.Suit == trump)//Leading card is trump. { var higherCardsOfTrump = cards.Where(c => c.Suit == trump && c.Number > leadCard.Number); if (higherCardsOfTrump.Count() > 0) return GetLowestCard(higherCardsOfTrump);//player has higher cards than leading card and gives the lowest of them. else return GetLowestCardStrategic(cards, pileSuit, trump);//player hasn't got higher cards than leading card so returns lowest card. } else //leading card is not trump { return GetLowestCard(cards.Where(c => c.Suit == trump));//return lowest trump card. } } else //Hand contains neither pilesuit nor trump cards. { return GetLowestCard(cards); } } } } } else//AI Starts Pile. { return GetHighestCard(cards); } }
private static int GetCurrentPlayerIndex(Round round) { for (int i = 0; i < round.Players.Count(); i++) if (round.Players[i] == round.CurrentPlayer) return i; return -1; }
//Leading card's suit is always either trump or pileSuit. private static Card LeadingCard(Round round) { if (round.Pile.Any(c => c.Suit == round.Trump)) { return GetHighestCard(round.Pile.Where(c => c.Suit == round.Trump));//If pile has trump cards, return highest card of trumpsuit. } else { return GetHighestCard(round.Pile.Where(c => c.Suit == round.Pile[0].Suit));//If pile doesn't have trump cards, return highest card of pilesuit. } }
private static Team CurrentTeam(Round round) { return round.Teams.Where(t => t.Players.Any(p => p == round.CurrentPlayer)).Single(); }
private static bool OpposingPlayersLeftInTrick(Round round) { int remainingPlayersAfterCurrent = 3 - round.Pile.Count(); int index = GetCurrentPlayerIndex(round); for (int i = 0; i < remainingPlayersAfterCurrent; i++) { index++; if (index == round.Players.Count()) index = 0; if (!CurrentTeam(round).Players.Contains(round.Players[index])) return true; } return false;//No opponents will be able to play a card for the remainder of this trick. }
protected override int GetHandStrength(Suits trump) { Player[] CopyPlayers = new Player[] { new Player("copy0", 0), new Player("copy1", 1), new Player("copy2", 2), new Player("copy3", 3) }; Round simRound; do { simRound = new Round(CopyPlayers); } while (simRound.GameCase != Case.UNDECIDED); for (int i = 0; i < 4; i++) { CopyPlayers[i].hand.Cards.Clear(); foreach (var card in game.Players[i].hand.Cards) CopyPlayers[i].hand.AddCard(card); } while (simRound.InBiddingPhase) { if (simRound.CurrentPlayer == CopyPlayers.Where(cp => cp.Number == player.Number).Single()) { if (simRound.BiddingGetPossibleActions().Contains(Action.ABONDANCE)) simRound.BiddingDoAction(Action.ABONDANCE); else { switch (trump) { case Suits.HEARTS: { simRound.BiddingDoAction(Action.HEARTS); break; } case Suits.DIAMONDS: { simRound.BiddingDoAction(Action.DIAMONDS); break; } case Suits.SPADES: { simRound.BiddingDoAction(Action.SPADES); break; } case Suits.CLUBS: { simRound.BiddingDoAction(Action.CLUBS); break; } default: break; } } simRound.BiddingDoAction(Action.ASK); } else simRound.BiddingDoAction(Action.PASS); } simRound.EndBiddingRound(); while (simRound.InTrickPhase) { while (simRound.TrickInProgress) simRound.PlayCard(SimpleGameAI.GetMove(simRound)); simRound.EndTrick(); } return CopyPlayers.Where(cp => cp.Number == player.Number).Single().Tricks; }
public TrickSimulator(Round round) { pile = new Card[4]; players = new int[4]; trump = round.Trump; for (int i = 0; i < round.Pile.Count; i++) { pile[i] = round.Pile[i]; players[i] = round.PlayerWhoPlayedCard(pile[i]).Number; } }
public void ProcessRound(Round round) { foreach (Player p in round.Players) { tricksWon[p.Number] += p.Tricks; } foreach (Team t in round.Teams) { if (t.Tricks >= t.objective) { foreach (Player p in t.Players) { roundsWon[p.Number]++; } } } if (!gamecaseoccurences.ContainsKey(round.GameCase)) gamecaseoccurences.Add(round.GameCase, 0); gamecaseoccurences[round.GameCase]++; if (!gamecaseplaysperplayer.ContainsKey(round.GameCase)) { gamecaseplaysperplayer.Add(round.GameCase, new int[] { 0, 0, 0, 0 }); gamecasewinsperplayer.Add(round.GameCase, new int[] { 0, 0, 0, 0 }); } var team = round.Teams.Where(t => t.objective == round.Teams.Max(tm => tm.objective)).Single(); foreach (var pl in team.Players) { gamecaseplaysperplayer[round.GameCase][pl.Number]++; if (team.Tricks >= team.objective) gamecasewinsperplayer[round.GameCase][pl.Number]++; } }