Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Bots/src/CardTierList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,20 @@ public class CardTierList
new CardTier("Ragpicker", PatronId.TREASURY, TierEnum.C),
new CardTier("Tithe", PatronId.TREASURY, TierEnum.C),
new CardTier("Writ of Coin", PatronId.TREASURY, TierEnum.D),
new CardTier("Unknown", PatronId.TREASURY, TierEnum.UNKNOWN)
new CardTier("Unknown", PatronId.TREASURY, TierEnum.UNKNOWN),
// Added Saint Alessia
new CardTier("Alessian Rebel", PatronId.SAINT_ALESSIA, TierEnum.C),
new CardTier("Ayleid Defector", PatronId.SAINT_ALESSIA, TierEnum.B),
new CardTier("Ayleid Quartermaster", PatronId.SAINT_ALESSIA, TierEnum.B),
new CardTier("Chainbreaker Captain", PatronId.SAINT_ALESSIA, TierEnum.A),
new CardTier("Chainbreaker Sergeant", PatronId.SAINT_ALESSIA, TierEnum.B),
new CardTier("Morihuas Sacred Bull", PatronId.SAINT_ALESSIA, TierEnum.S),
new CardTier("Morihuas the Archer", PatronId.SAINT_ALESSIA, TierEnum.A),
new CardTier("Pelinal Whitestrake", PatronId.SAINT_ALESSIA, TierEnum.S),
new CardTier("Priestess of the Eight", PatronId.SAINT_ALESSIA, TierEnum.B),
new CardTier("Saints Wrath", PatronId.SAINT_ALESSIA, TierEnum.B),
new CardTier("Soldier of the Empire", PatronId.SAINT_ALESSIA, TierEnum.C),
new CardTier("Whitestrake Ascendant", PatronId.SAINT_ALESSIA, TierEnum.S),
};

public static TierEnum GetCardTier(string cardName)
Expand Down
7 changes: 4 additions & 3 deletions Engine/TalesOfTribute.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@

<ItemGroup>
<None Remove="Tests\**" />
<None Update="cards.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Remove="cards.json" />
<EmbeddedResource Include="cards.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Engine/src/Board/BoardManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public BoardManager(PatronId[] patrons, ulong seed)
_rng = new SeededRandom(seed);
Patrons = GetPatrons(patrons);
var patronStarterCardsIds = Patrons.SelectMany(patron => patron.GetStarterCards()).ToArray();
Tavern = new Tavern(GlobalCardDatabase.Instance.GetCardsByPatron(patrons, patronStarterCardsIds), _rng);
Tavern = new Tavern(GlobalCardDatabase.Instance.GetCardsByPatron(patrons, patronStarterCardsIds, CardId.WRIT_OF_COIN), _rng);
_playerContext = new PlayerContext(new Player(PlayerEnum.PLAYER1, _rng), new Player(PlayerEnum.PLAYER2, _rng));
CardActionManager = new CardActionManager(_playerContext, Tavern);
}
Expand Down
26 changes: 16 additions & 10 deletions Engine/src/Board/CardAction/ComplexEffectExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

public (PlayResult, IEnumerable<CompletedAction>) Enact(Choice c, UniqueEffect choice)
{
return c.FollowUp switch

Check warning on line 22 in Engine/src/Board/CardAction/ComplexEffectExecutor.cs

View workflow job for this annotation

GitHub Actions / test

The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern 'ScriptsOfTribute.ChoiceFollowUp.REPLACE_CARDS_IN_TAVERN' is not covered.
{
ChoiceFollowUp.ENACT_CHOSEN_EFFECT => CompleteChoice(choice),
};
Expand Down Expand Up @@ -226,17 +226,23 @@
}
private void handleSaintAlessiaTriggers(List<UniqueCard> knockoutedCards)
{
if (!_enemyPlayer.AgentCards.Any(c => c.CommonId == CardId.MORIHAUS_SACRED_BULL || c.CommonId == CardId.MORIHAUS_THE_ARCHER))
return;

foreach (var triggerCard in _enemyPlayer.AgentCards.Where(c => c.CommonId == CardId.MORIHAUS_SACRED_BULL || c.CommonId == CardId.MORIHAUS_THE_ARCHER).ToList())
void HandleForPlayer(IPlayer player)
{
if (knockoutedCards.Any(c => c.UniqueId == triggerCard.UniqueId))
continue;
_enemyPlayer.CoinsAmount++;
_parent.AddToCompletedActionsList(new CompletedAction(_enemyPlayer.ID, CompletedActionType.GAIN_COIN, triggerCard, 1));
var morihausAgents = player.AgentCards
.Where(c => c.CommonId == CardId.MORIHAUS_SACRED_BULL || c.CommonId == CardId.MORIHAUS_THE_ARCHER)
.ToList();

foreach (var triggerCard in morihausAgents)
{
if (knockoutedCards.Any(c => c.UniqueId == triggerCard.UniqueId))
continue;

player.CoinsAmount++;
_parent.AddToCompletedActionsList(new CompletedAction(player.ID, CompletedActionType.GAIN_COIN, triggerCard, 1));
}
}

}

HandleForPlayer(_currentPlayer);
HandleForPlayer(_enemyPlayer);
}
}
2 changes: 1 addition & 1 deletion Engine/src/Board/Cards/UniqueCard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public UniqueCard(string name, PatronId deck, CardId commonId, int cost, CardTyp
public override string ToString()
{
return string.Format($"Card: {this.Name}, " +
$"Deck: {this.Deck}, Cost: {this.Cost}, Type: {this.Type}, UniqueId: {UniqueId.Value}");
$"Deck: {this.Deck}, Cost: {this.Cost}, Type: {this.Type}, UniqueId: {UniqueId.Value}");
}

public override bool Equals(object? obj)
Expand Down
5 changes: 3 additions & 2 deletions Engine/src/Board/Cards/UniqueEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public UniqueEffect(EffectType type, int amount, int combo, UniqueCard parentCar
ChoiceFollowUp.REFRESH_CARDS,
context,
amount,
amount
0
), new List<CompletedAction>());
}
case EffectType.TOSS:
Expand Down Expand Up @@ -213,7 +213,7 @@ public UniqueEffect(EffectType type, int amount, int combo, UniqueCard parentCar
ChoiceFollowUp.REFRESH_CARDS,
context,
agentsCount,
agentsCount
0
), new List<CompletedAction>());
case EffectType.DONATE:
{
Expand Down Expand Up @@ -250,6 +250,7 @@ public override string ToString()
EffectType.CREATE_SUMMERSET_SACKING => $"Create {Amount} Summerset Sacking cards and place it in CD pile",
EffectType.HEAL => $"Heal this agent by {Amount}",
EffectType.DONATE => $"Discard up to {Amount} cards from hand, draw {Amount} cards",
EffectType.KNOCKOUT_ALL => $"Knockout all agents",
_ => ""
};
}
Expand Down
4 changes: 2 additions & 2 deletions Engine/src/utils/CardDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ public UniqueCard GetCard(CardId cardId)
return card;
}

public List<UniqueCard> GetCardsByPatron(PatronId[] patrons, CardId[] starterCardsId)
public List<UniqueCard> GetCardsByPatron(PatronId[] patrons, CardId[] starterCardsId, params CardId[] excludeCards)
{
var allCardsGrouped = from card in _allCards
where patrons.Contains(card.Deck) && !starterCardsId.Contains(card.CommonId) && card.Type != CardType.CURSE
where patrons.Contains(card.Deck) && !starterCardsId.Contains(card.CommonId) && !excludeCards.Contains(card.CommonId) && card.Type != CardType.CURSE
select Enumerable.Range(0, card.Copies).Select(_ => card.CreateUniqueCopy()).ToList();

return allCardsGrouped.SelectMany(c => c).ToList();
Expand Down
16 changes: 14 additions & 2 deletions Engine/src/utils/GlobalCardDatabase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace ScriptsOfTribute;
using System.Reflection;

namespace ScriptsOfTribute;

public class GlobalCardDatabase
{
Expand All @@ -10,7 +12,17 @@ public static CardDatabase Instance
{
if (_instance != null) return _instance.Value;

var data = File.ReadAllText("cards.json");
var assembly = Assembly.GetExecutingAssembly();
const string resourceName = "TalesOfTribute.cards.json";
using Stream? stream = assembly.GetManifestResourceStream(resourceName);

if (stream == null)
{
throw new InvalidOperationException($"Cant find resource'{resourceName}' in DLL. Available resources: {string.Join(", ", assembly.GetManifestResourceNames())}");
}

using StreamReader reader = new StreamReader(stream);
string data = reader.ReadToEnd();
var parser = new Parser(data);
_instance = new ThreadLocal<CardDatabase>(() => new CardDatabase(parser.CreateAllCards()));

Expand Down
33 changes: 32 additions & 1 deletion Tests/Board/SaintAlessiaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void TestDonateEffect()
br.CurrentPlayer.Hand.Add(priestess);
br.CurrentPlayer.Hand.Add(sote);
br.CurrentPlayer.Hand.Add(armory);

var chainbreaker = GlobalCardDatabase.Instance.GetCard(CardId.CHAINBREAKER_CAPTAIN);
var morihaus = GlobalCardDatabase.Instance.GetCard(CardId.MORIHAUS_SACRED_BULL);
br.CurrentPlayer.DrawPile.Add(chainbreaker);
Expand Down Expand Up @@ -200,4 +200,35 @@ void TestRefreshTopAgents()
Assert.Equal(BoardState.NORMAL, br.CardActionManager.State);
Assert.Contains(chainbreaker_sergeant, br.CurrentPlayer.DrawPile);
}

[Fact]
void TestMorihausTriggersBothPlayers()
{
var br = new BoardManager([PatronId.TREASURY, PatronId.PELIN, PatronId.RED_EAGLE, PatronId.ANSEI, PatronId.SAINT_ALESSIA], 123);

var morihaus1 = Agent.FromCard(GlobalCardDatabase.Instance.GetCard(CardId.MORIHAUS_SACRED_BULL));
var morihaus2 = Agent.FromCard(GlobalCardDatabase.Instance.GetCard(CardId.MORIHAUS_THE_ARCHER));
var soldier1 = Agent.FromCard(GlobalCardDatabase.Instance.GetCard(CardId.SOLDIER_OF_THE_EMPIRE));
var soldier2 = Agent.FromCard(GlobalCardDatabase.Instance.GetCard(CardId.SOLDIER_OF_THE_EMPIRE));

br.CurrentPlayer.Agents.Add(morihaus1);
br.CurrentPlayer.Agents.Add(soldier1);

br.EnemyPlayer.Agents.Add(morihaus2);
br.EnemyPlayer.Agents.Add(soldier2);

var black_sacrament = GlobalCardDatabase.Instance.GetCard(CardId.BLACK_SACRAMENT);
br.CurrentPlayer.Hand.Add(black_sacrament);

br.PlayCard(black_sacrament);

var knockout = br.CardActionManager.PendingChoice!.PossibleCards
.Where(card => card.CommonId == CardId.SOLDIER_OF_THE_EMPIRE && br.EnemyPlayer.Agents.Any(a => a.RepresentingCard.UniqueId == card.UniqueId))
.ToList();

br.CardActionManager.MakeChoice(knockout);

Assert.Equal(1, br.EnemyPlayer.CoinsAmount);
Assert.Equal(1, br.CurrentPlayer.CoinsAmount);
}
}
2 changes: 1 addition & 1 deletion gRPC/Services/AIService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public PatronId SelectPatron(List<PatronId> availablePatrons, int round)
};

request.AvailablePatrons.AddRange(availablePatrons.Select(patronId => (PatronIdProto)(patronId)).ToList());

var response = _client.SelectPatron(request);
return (PatronId)(response.PatronId);
}
Expand Down
Loading