Ratings
The formulas in this thread produce dollar-values that can be compared between divisions and between basing ships.
https://forums.trenchwars.com/forum/...ula-discussion
Drafting
This is a sample of code from an automated drafter. It picks basing teams like a real captain would, e.g. if you pick a shark and there aren't many sharks I pick a shark. Can provide the full code if needed for someone to actually implement it.
Code:
using DraftLibrary.Classes;
using System.Collections.Generic;
using System;
using System.Linq;
namespace DraftLibrary.Algorithms
{
class Snake
{
public static List<Team> DraftWithCaptain(List<Player> players, List<Team> teams)
{
//// the snake format is still fine for picking with a captain
//// it gives the captains a turn in the correct order, like TWDT
List<int> draftOrder = GetDraftOrder(players, teams);
for (int i = 0; i < draftOrder.Count; i++)
{
int teamIndex = draftOrder[i];
Team currentTeam = teams[teamIndex];
////
//// I am ALL CAPS picking against ALL THE OTHERS
////
//// work out who we should pick
//// we need 1 terr, 2 sharks, 5 spiders
//// we know which team we're up against
Team opponentTeam = (teamIndex % 2) == 0 ? teams[teamIndex + 1] : teams[teamIndex - 1];
//// we have overall, terr, shark, spid ratings.
// see who's left to pick
List<Player> remaining = GetPlayersRemaining(players, teams);
//// someone might end up in multiple lists, e.g. turban, dreamwin
// be less selective as the draft progresses.
int round = (i + teams.Count) / teams.Count;
// some constants which vary depending on the ratings used
int HighestUsefulRating = 7; /* e.g. 7* at something is worth prioritising over their Overall rating, 6* isn't. */
int EliteRating = 10; /* you want to be picking a 10* first */
int RoundRelaxation = 1; /* each round, including round 1, reduce pickyness by 1* */
// ^ the point of this is that you don't really want to be picking an 8* over a 9/10* in round 1, but in round 2 you might.
// shortlist remaining sharks
List<Player> sharkShortlist = ShortlistSharks(remaining, Math.Max(HighestUsefulRating, EliteRating - (round * RoundRelaxation)));
// shortlist remaining terrs
List<Player> terrShortlist = ShortlistTerrs(remaining, Math.Max(HighestUsefulRating, EliteRating - (round * RoundRelaxation)));
// shortlist remaining spiders
List<Player> spiderShortlist = ShortlistSpiders(remaining, Math.Max(HighestUsefulRating, EliteRating - (round * RoundRelaxation)));
// I need to know how many turns until my next pick
bool haveAnotherPick = false;
int turnsUntilNextPick = 0;
for (int j = i + 1; j < draftOrder.Count; j++)
{
if (teamIndex == draftOrder[j])
{
haveAnotherPick = true;
turnsUntilNextPick = j - i;
break;
}
}
List<Player> solidPicks = new List<Player>();
if (
/* dont pick more than 2 sharks */
currentTeam.Sharks.Count < 2
/* this logic only works if we have shortlisted sharks available */
&& sharkShortlist.Count > 0
&& (
/* don't get out sharked */
currentTeam.Sharks.Count <= opponentTeam.Sharks.Count
/* if you're concerned someone else is going to snipe your shark pick */
|| (haveAnotherPick && sharkShortlist.Count < turnsUntilNextPick)
)
)
{
Player player = GetHighestRatedShark(sharkShortlist);
if (!solidPicks.Contains(player))
{
player.Context = "Shark";
solidPicks.Add(player);
}
}
if (
/* don't pick more than 1 terr */
currentTeam.Terr.Count < 1
/* this logic only works if we have shortlisted terrs available */
&& terrShortlist.Count > 0
&& (
/* don't get out terred */
currentTeam.Terr.Count <= opponentTeam.Terr.Count
/* if you're concerned someone else is going to snipe your terr pick */
|| (haveAnotherPick && terrShortlist.Count < turnsUntilNextPick)
)
)
{
Player player = GetHighestRatedTerr(terrShortlist);
if (!solidPicks.Contains(player))
{
player.Context = "Terr";
solidPicks.Add(player);
}
}
if (
/* don't pick more than 5 spiders */
currentTeam.Spids.Count < 5
/* this logic only works if we have shortlisted spiders available */
&& spiderShortlist.Count > 0
&& (
/* don't get out spidered */
currentTeam.Spids.Count <= opponentTeam.Spids.Count
/* if you're concerned someone else is going to snipe your spider pick */
|| (haveAnotherPick && spiderShortlist.Count < turnsUntilNextPick)
)
)
{
Player player = GetHighestRatedSpider(spiderShortlist);
if (!solidPicks.Contains(player))
{
player.Context = "Spid";
solidPicks.Add(player);
}
}
Player pick = null;
if (solidPicks.Count == 1)
{
// We found 1 solid pick, just add it.
pick = solidPicks[0];
}
else if (solidPicks.Count > 1)
{
// There's more than 1 player we'd like to pick
// We have to resolve it somehow... prefer the default order, but let higher rating override it.
Player player = GetHighestRatedSolidPick(solidPicks);
pick = player;
}
else
{
// fallback, just pick the highest overall rated player
Player player = GetHighestRatedPlayer(remaining);
player.Context = string.Empty;
pick = player;
}
switch (pick.Context)
{
case "Terr":
currentTeam.AddTerr(pick);
break;
case "Shark":
currentTeam.AddShark(pick);
break;
case "Spid":
currentTeam.AddSpid(pick);
break;
default:
currentTeam.AddPlayer(pick);
break;
}
}
return teams;
}
private static Player GetHighestRatedSpider(List<Player> spiders)
{
Player player = null;
foreach (Player p in spiders)
{
if (player == null) player = p;
if (p.Spid > player.Spid) player = p;
}
return player;
}
private static Player GetHighestRatedTerr(List<Player> terrs)
{
Player player = null;
foreach (Player p in terrs)
{
if (player == null) player = p;
if (p.Terr > player.Terr) player = p;
}
return player;
}
private static Player GetHighestRatedShark(List<Player> sharks)
{
Player player = null;
foreach (Player p in sharks)
{
if (player == null) player = p;
if (p.Shark > player.Shark) player = p;
}
return player;
}
private static List<int> GetDraftOrder(List<Player> players, List<Team> teams)
{
List<int> draftOrder = new List<int>();
int teamIndex = 0;
string direction = "r";
// the number of picks matches the number of players
for (int i = 0; i < players.Count; i++)
{
draftOrder.Add(teamIndex);
// snake
switch (direction)
{
case "r":
{
if (teamIndex + 1 == teams.Count)
{
direction = "l";
}
else
{
teamIndex++;
}
break;
}
case "l":
{
if (teamIndex == 0)
{
direction = "r";
}
else
{
teamIndex--;
}
break;
}
}
}
return draftOrder;
}
private static List<Player> ShortlistSpiders(List<Player> remaining, int rating)
{
List<Player> shortlist = new List<Player>();
foreach (Player player in remaining)
{
if (player.Spid >= rating)
{
shortlist.Add(player);
}
}
return shortlist.OrderByDescending(p => p.Spid).ToList();
}
private static List<Player> ShortlistTerrs(List<Player> remaining, int rating)
{
List<Player> shortlist = new List<Player>();
foreach (Player player in remaining)
{
if (player.Terr >= rating)
{
shortlist.Add(player);
}
}
return shortlist.OrderByDescending(p => p.Terr).ToList();
}
private static List<Player> ShortlistSharks(List<Player> remaining, int rating)
{
List<Player> shortlist = new List<Player>();
foreach (Player player in remaining)
{
if (player.Shark >= rating)
{
shortlist.Add(player);
}
}
return shortlist.OrderByDescending(p => p.Shark).ToList();
}
private static List<Player> GetPlayersRemaining(List<Player> players, List<Team> teams)
{
List<Player> remaining = new List<Player>();
foreach (Player player in players)
{
bool picked = false;
foreach (Team team in teams)
{
if (team.Players.Contains(player)) picked = true;
}
if (!picked) remaining.Add(player);
}
return remaining;
}
public static List<Team> DraftWithoutCaptain(List<Player> players, List<Team> teams)
{
List<int> draftOrder = GetDraftOrder(players, teams);
foreach (int teamIndex in draftOrder)
{
Team currentTeam = teams[teamIndex];
// see who's left to pick
List<Player> remaining = GetPlayersRemaining(players, teams);
Player player = GetHighestRatedPlayer(remaining);
currentTeam.AddPlayer(player);
}
return teams;
}
private static Player GetHighestRatedPlayer(List<Player> remaining)
{
Player player = null;
foreach (Player p in remaining)
{
if (player == null) player = p;
if (p.Overall > player.Overall) player = p;
}
return player;
}
private static Player GetHighestRatedSolidPick(List<Player> remaining)
{
Player player = null;
foreach (Player p in remaining)
{
if (player == null) player = p;
if (p.RatingInContext() > player.RatingInContext()) player = p;
}
return player;
}
}
}



Leave a comment: