Advertisement
Guest User

Untitled

a guest
Nov 15th, 2020
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 30.14 KB | None | 0 0
  1. #define TESTING
  2. #define DEBUG
  3. #define SAVE_DEBUG_TREE
  4.  
  5. using System;
  6. using System.Linq;
  7. using System.IO;
  8. using System.Text;
  9. using System.Collections;
  10. using System.Diagnostics;
  11. using System.Collections.Generic;
  12.  
  13.  
  14.  
  15. public class Game
  16. {
  17.     public enum ActionTypes { BREW, CAST, OPCAST, LEARN, NONE };
  18.     public static void DebugPrint(string txt)
  19.     {
  20. #if DEBUG && TESTING
  21.         Console.Error.WriteLine(txt);
  22. #endif
  23.     }
  24.  
  25.     public class DebugTree
  26.     {
  27.         public static string StrTree
  28.         {
  29.             get
  30.             {
  31. #if DEBUG && TESTING
  32.                 return mTree.ToString();
  33. #endif
  34.                 return "";
  35.             }
  36.         }
  37.  
  38.  
  39.         //echo "graph TST{a0 -- {a1 a2} ; a1 -- {a3 a4} ; a2 -- {a5 a6} ;}" | dot -Tpng > out.png
  40.         //graph TST{a0 -- { a1 b1};  a1 [label="a1=-2147483648 Beta",color=blue]; b1 [label="b1=-2147483648 Beta",color=blue]; a0 [label="a0=2147483647"];a1 -- { a2 b2};  a2 [label="a2=2147483647 Alpha",color=red]; b2 [label="b2=2147483647 Alpha",color=red];}
  41.  
  42.         public static void Init()
  43.         {
  44. #if DEBUG && TESTING
  45.             mTree = new StringBuilder();
  46.             mChildsList = new SortedList<int, List<(State, State)>>();
  47.             //     mTree.Append("graph TST{");
  48.             mChildNum = 0;
  49. #endif
  50.         }
  51.  
  52.         public static void BeginChilds()
  53.         {
  54. #if DEBUG && TESTING
  55.  
  56. #endif
  57.         }
  58.         public static void EndChilds()
  59.         {
  60. #if DEBUG && TESTING
  61.          
  62. #endif
  63.         }
  64.  
  65.         public static void SetChilds(int depth, State par, State ch)
  66.         {
  67. #if DEBUG && TESTING
  68.             if (!mChildsList.ContainsKey(depth))
  69.             {
  70.                 mChildsList.Add(depth, new List<(State, State)>());
  71.             }
  72.             mChildsList[depth].Add((par, ch));
  73.             mChildNum++;
  74. #endif
  75.         }
  76.  
  77.         public static void SetEnd()
  78.         {
  79. #if DEBUG && TESTING
  80.             // mTree.Append(" }");
  81.             var i = -1;
  82.             foreach (var item in mChildsList)
  83.             {
  84.                 mTree.Append($"\r\n- \t{item.Key}\t -\r\n");
  85.                 foreach (var item1 in item.Value)
  86.                 {
  87.                     mTree.Append($"depth: {item.Key}  parent: {item1.Item1.PlayerData} - evalby: {item1.Item1.EvalActID}  , child: {item1.Item2.PlayerData} - evalby: {item1.Item2.EvalActID} - evaval: {item1.Item2.EvalVal}; ");
  88.                 }
  89.             }
  90. #if SAVE_DEBUG_TREE
  91.             File.WriteAllText("tmptree01.txt", mTree.ToString());
  92. #endif
  93. #endif
  94.         }
  95.  
  96.         private static (string, string) mParent;
  97.         private static SortedList<int, List<(State, State)>> mChildsList;
  98.         private static StringBuilder mTree;
  99.         private static int mChildNum;
  100.     }
  101.  
  102.     public struct Action
  103.     {
  104.         public Action(string ln)
  105.         {
  106.             var inputs = ln.Split(' ');
  107.             // $"{ActionId} {ActionId} {Deltas[0]} {Deltas[1]} {Deltas[2]} {Deltas[3]} {Price} {TomeIndex} {TaxCount} {Castable} {Repeatable} "
  108.             ActionId = int.Parse(inputs[0]); // the unique ID of this spell or recipe
  109.             StrActionType = inputs[1].Trim(); // in the first league: BREW; later: CAST, OPPONENT_CAST, LEARN, BREW
  110.  
  111.             Deltas = new int[4];
  112.             Deltas[0] = int.Parse(inputs[2]); // tier-0 ingredient change
  113.             Deltas[1] = int.Parse(inputs[3]); // tier-1 ingredient change
  114.             Deltas[2] = int.Parse(inputs[4]); // tier-2 ingredient change
  115.             Deltas[3] = int.Parse(inputs[5]); // tier-3 ingredient change
  116.  
  117.             Price = int.Parse(inputs[6]); // the price in rupees if this is a potion
  118.             TomeIndex = int.Parse(inputs[7]); // in the first two leagues: always 0; later: the index in the tome if this is a tome spell, equal to the read-ahead tax
  119.             TaxCount = int.Parse(inputs[8]); // in the first two leagues: always 0; later: the amount of taxed tier-0 ingredients you gain from learning this spell
  120.             Castable = inputs[9] != "0"; // in the first league: always 0; later: 1 if this is a castable player spell
  121.             Repeatable = inputs[10] != "0"; // for the first two leagues: always 0; later: 1 if this is a repeatable player spell
  122.  
  123.             Type = ActionTypes.NONE;
  124.  
  125.             if (StrActionType.Equals("BREW"))
  126.             {
  127.                 Type = ActionTypes.BREW;
  128.             }
  129.             else if (StrActionType.Equals("CAST"))
  130.             {
  131.                 Type = ActionTypes.CAST;
  132.             }
  133.             else if (StrActionType.Equals("LEARN"))
  134.             {
  135.                 Type = ActionTypes.LEARN;
  136.             }
  137.             else if (StrActionType.Equals("OPPONENT_CAST"))
  138.             {
  139.                 Type = ActionTypes.OPCAST;
  140.             }
  141.         }
  142.         public override string ToString()
  143.         {
  144.             return $"{ActionId} {ActionId} {Deltas[0]} {Deltas[1]} {Deltas[2]} {Deltas[3]} {Price} {TomeIndex} {TaxCount} {Castable} {Repeatable} ";
  145.         }
  146.         public ActionTypes Type; //
  147.         public int ActionId; // the unique ID of this spell or recipe
  148.         public string StrActionType; // in the first league: BREW; later: CAST, OPPONENT_CAST, LEARN, BREW
  149.         public int[] Deltas; //indigriedns deltas
  150.         public int Price; // the price in rupees if this is a potion
  151.         public int TomeIndex; // in the first two leagues: always 0; later: the index in the tome if this is a tome spell, equal to the read-ahead tax
  152.         public int TaxCount; // in the first two leagues: always 0; later: the amount of taxed tier-0 ingredients you gain from learning this spell
  153.         public bool Castable; // in the first league: always 0; later: 1 if this is a castable player spell
  154.         public bool Repeatable; // for the first two leagues: always 0; later: 1 if this is a repeatable player spell
  155.  
  156.     }
  157.  
  158.     public struct PData
  159.     {
  160.         public PData(string ln)
  161.         {
  162.             var inputs = ln.Split(' ');
  163.             //
  164.             Inventories = new int[4];
  165.             Inventories[0] = int.Parse(inputs[0]); // tier-0 ingredients in inventory
  166.             Inventories[1] = int.Parse(inputs[1]);
  167.             Inventories[2] = int.Parse(inputs[2]);
  168.             Inventories[3] = int.Parse(inputs[3]);
  169.             Scores = int.Parse(inputs[4]); // amount of rupees
  170.         }
  171.         public PData(PData pdata)
  172.         {
  173.             Inventories = new int[4];
  174.             pdata.Inventories.CopyTo(Inventories, 0);
  175.             Scores = pdata.Scores;
  176.         }
  177.  
  178.         public override string ToString()
  179.         {
  180.             return $"{Inventories[0]} {Inventories[1]} {Inventories[2]} {Inventories[3]} {Scores} ";
  181.         }
  182.  
  183.         public int[] Inventories; //inventories
  184.         public int Scores;// amount of rupees
  185.  
  186.     }
  187.  
  188.     public class State
  189.     {
  190.         public int EvalActID => mEvalActID;
  191.         public int OptimalFirstMove => mOptimalFirstMove;
  192.         public State Parent => mParent;
  193.         public List<State> Childrens => mChildrens;
  194.         public double EvalVal => mEvalVal;
  195.         public List<Action> Actions => mActions;
  196.         public PData PlayerData => mPlayerData;
  197.         public PData OppData => mOpponentData;
  198.         public List<Action> BrewActs => mBrewActs;
  199.         public List<Action> CastsActs => mCastsActs;
  200.         public List<Action> UnCastsActs => mUnCastsActs;
  201.         public List<Action> OpCastsActs => mOpCastsActs;
  202.         public List<Action> CanLearn => mCanLearn;
  203.         //brew diffs          
  204.         public Dictionary<int, int[]> BDiffs => mBDiffs;
  205.         //casts diffs
  206.         public Dictionary<int, int[]> CDiffs => mCDiffs;
  207.         //uncastable diffs
  208.         public Dictionary<int, int[]> UnCDiffs => mUnCDiffs;
  209.         //brew if can with max
  210.         public Dictionary<int, int[]> BrewCansDiffd => mBrewCansDiffd;
  211.         //cast
  212.         public Dictionary<int, int[]> CastCansDiffd => mCastCansDiffd;
  213.         //uncastable can do
  214.         public Dictionary<int, int[]> UnCastCansDiffd => mUnCastCansDiffd;
  215.         public List<Action> CastsCans => mCastsCans;
  216.         public List<Action> UnCastsCans => mUnCastsCans;
  217.         //same as new inventory after spell cast
  218.         public Dictionary<int, int[]> CastsCansDiffDiff => mCastsCansDiffDiff;
  219.         //same as new inventory after spell uncast
  220.         public Dictionary<int, int[]> UnCastsCansDiffDiff => mUnCastsCansDiffDiff;
  221.         //rest if brew next move
  222.         //Can do brew next move check
  223.         public List<int> UnCastDiff3 => mUnCastDiff3;
  224.         //Can do brew next move check
  225.         public List<int> CastDiff3 => mCastDiff3;
  226.         //FirstBrewMoves was called
  227.         public bool FirstBrIsEval => mFirstBrIsEval;
  228.  
  229.         public State(List<Action> actions, PData playerData, PData opponentData, int actionCount, State parent = null, int evActID = -1)
  230.         {
  231.             mActionCount = actionCount;
  232.             mActions = actions;
  233.             mPlayerData = playerData;
  234.             mOpponentData = opponentData;
  235.  
  236.             mEvalVal = 0;
  237.             mParent = parent;
  238.             mChildrens = new List<State>();
  239.             mEvalActID = evActID;
  240.             mFirstBrIsEval = false;
  241.  
  242.             UpdateActsVals();
  243.         }
  244.  
  245.         public void AddChilderen(State children)
  246.         {
  247.             mChildrens.Add(children);
  248.         }
  249.         public void UpdateActsVals()
  250.         {
  251.             mBrewActs = Actions.Where(act => act.Type == ActionTypes.BREW)?.ToList();
  252.             mCastsActs = Actions.Where(act => act.Type == ActionTypes.CAST && act.Castable)?.ToList();
  253.             mUnCastsActs = Actions.Where(act => act.Type == ActionTypes.CAST && !act.Castable)?.ToList();
  254.             mOpCastsActs = Actions.Where(act => act.Type == ActionTypes.OPCAST)?.ToList();
  255.             mLearnActs = mActions.Where(act => act.Type == ActionTypes.LEARN)?.ToList();
  256.  
  257.             ///
  258.             //brew diffs          
  259.             mBDiffs = GetInvDiffs(mBrewActs);
  260.             //casts diffs
  261.             mCDiffs = GetInvDiffs(mCastsActs);
  262.             //uncastable diffs
  263.             mUnCDiffs = GetInvDiffs(mUnCastsActs);
  264.             //brew if can with max
  265.             mBrewCansDiffd = CanDo(mBDiffs);
  266.             ///
  267.             //cast
  268.             mCastCansDiffd = CanDo(mCDiffs);
  269.             //uncastable can do
  270.             mUnCastCansDiffd = CanDo(mUnCDiffs);
  271.             ///
  272.             //
  273.             mCastsCans = mCastsActs.Where(v => (v.Deltas.Sum() + mPlayerData.Inventories.Sum()) < 11
  274.                                         && mCastCansDiffd.Any(ba => ba.Key == v.ActionId))?.ToList();
  275.             //
  276.             mUnCastsCans = mUnCastsActs.Where(v => (v.Deltas.Sum() + mPlayerData.Inventories.Sum()) < 11
  277.                                                   && mUnCastCansDiffd.Any(ba => ba.Key == v.ActionId))?.ToList();
  278.             ///
  279.             //TODO: optim . remove need only one check in CanDo
  280.             //same as new inventory after spell cast
  281.             mCastsCansDiffDiff = GetInvDiffs(CastsCans);
  282.             //same as new inventory after spell uncast
  283.             mUnCastsCansDiffDiff = GetInvDiffs(mUnCastsCans);
  284.             //rest if brew next move
  285.             //Can do brew next move check
  286.             mUnCastDiff3 = GetCastDiffsBrewNext(mBrewActs, mUnCastsCansDiffDiff);
  287.             //Can do brew next move check
  288.             mCastDiff3 = GetCastDiffsBrewNext(mBrewActs, CastsCansDiffDiff);
  289.             //total inv
  290.             mCurrentTotalInv = mPlayerData.Inventories.Sum();
  291.             //
  292.             mCanLearn = mLearnActs.Where(ll => ll.TomeIndex <= mPlayerData.Inventories[0]).ToList();
  293.         }
  294.         public State EvaluateByActId(int actId)
  295.         {
  296.             List<Action> actions = new List<Action>();
  297.             actions.AddRange(mActions);
  298.             PData playerData = new PData(mPlayerData);
  299.             PData opponentData = new PData(mOpponentData);
  300.             int actionCount = mActionCount;
  301.  
  302.             //Evaluate actions
  303.             if (actId == -1)
  304.             {
  305.                 var castbls = Actions.Where(act => act.Type == ActionTypes.CAST && !act.Castable)?.ToList();
  306.                 foreach (var castbl in castbls)
  307.                 {
  308.                     int actind = actions.FindIndex(aa => aa.ActionId == castbl.ActionId);
  309.                     var act = actions[actind];
  310.                     act.Castable = true;
  311.                     actions[actind] = act;
  312.                 }
  313.             }
  314.             else
  315.             {
  316.                 int actind = actions.FindIndex(aa => aa.ActionId == actId);
  317.                 var act = actions[actind];
  318.                 switch (act.Type)
  319.                 {
  320.                     case ActionTypes.CAST:
  321.                         act.Castable = false;
  322.                         for (int i = 0; i < 4; i++)
  323.                         {
  324.                             playerData.Inventories[i] = mCastsCansDiffDiff[actId][i];
  325.                         }
  326.                         actions[actind] = act;
  327.                         break;
  328.                     case ActionTypes.LEARN:
  329.                         playerData.Inventories[0] += act.TaxCount - act.TomeIndex;
  330.                         act.Castable = true;
  331.                         act.StrActionType = "CAST";
  332.                         act.Type = ActionTypes.CAST;
  333.                         actions.Add(act);
  334.                         actions.RemoveAt(actind);
  335.                         break;
  336.                     case ActionTypes.BREW:
  337.                         actions.RemoveAt(actind);
  338.                         break;
  339.                 }
  340.             }
  341.  
  342.             State nstate = new State(actions, playerData, opponentData, actionCount, this, actId);
  343.             mChildrens.Add(nstate);
  344.             return nstate;
  345.         }
  346.         //first best moves eval
  347.         //-1 -- not found  
  348.         public int FirstBrewMoves()
  349.         {
  350.             mFirstBrIsEval = true;
  351.             //TODO: never happens
  352.             if (mBrewCansDiffd.Count > 0)
  353.             {
  354.                 var brewmax = GetMaxPriceArr(mBrewCansDiffd, mBrewActs);
  355.                 var brrand = brewmax[(new Random(DateTime.Now.Millisecond)).Next(0, brewmax.Length)];
  356.                 mEvalVal = brrand.Price * 5;
  357.                 mOptimalFirstMove = brrand.ActionId;
  358.                 return mOptimalFirstMove;
  359.             }
  360.  
  361.             //[a,b] , b - negative from bdiffs a
  362.             int[,] Wishes = GetWishesFromBDiffs(mBDiffs);
  363.  
  364.             if (mCastCansDiffd.Count > 0)
  365.             {
  366.                 //rest if UnCastsCans can brew next move
  367.                 if (mUnCastsCans != null && mUnCastsCans.Count > 0)
  368.                 {
  369.                     if (mUnCastDiff3 != null && mUnCastDiff3.Count > 0)
  370.                     {
  371.                         // DebugPrint("!!!!!!!!!!!!!!REST for brew next move !!!!!!!!!!");
  372.                         mEvalVal = 5;
  373.                         return -1;
  374.                     }
  375.                 }
  376.                 //casts
  377.                 if (mCastsCans != null)
  378.                 {
  379.  
  380.                     double TotalPositiveInv = (mPlayerData.Inventories.Where(v => v > 0)?.Sum(vv => 10 / (double)vv)) ?? 0;
  381.                     double SoLargeInv = (mPlayerData.Inventories.Where(v => v > 1)?.Sum()) ?? 0;
  382.  
  383.                     var TotalPositiveCastsDiff = (mCastsCansDiffDiff.Select((vv, TPosVal) => new
  384.                     {
  385.                         Key = vv.Key,
  386.                         Val = vv,
  387.                         Sum = vv.Value.Sum(),
  388.                         SoLarge = vv.Value.Where(vv0 => vv0 > 1)?.Sum() ?? 0,
  389.                         TotalPos = (double)(vv.Value.Where(vv0 => 10 / (double)vv0 > 0)?.Sum() ?? 0)
  390.                     }));
  391.                     //Can do brew next move check
  392.                     if (mCastDiff3 != null && mCastDiff3.Count > 0)
  393.                     {
  394.                         mEvalVal = 5;
  395.                         mOptimalFirstMove = mCastDiff3.First();
  396.                         return mOptimalFirstMove;
  397.                     }
  398.                     //rest if couldn't get 1/3
  399.                     //    //uncommon remove?
  400.                     double rest_ratio = (double)mCastsActs.Count() / (double)mUnCastsActs.Count();
  401.                     if (mCastsActs.Count > 9 && rest_ratio < 0.2)
  402.                     {
  403.                         mEvalVal = 0;
  404.                         //DebugPrint("!!!!!!!!!! rest 0.3 !!!!!!!!!!!!!!!!!");
  405.                         return -1;
  406.                     }
  407.                     //Can
  408.                     //learn if not enought spells
  409.                     //learn test //2
  410.                     if (mCastsCans.Count < 2)
  411.                     {
  412.                         mOptimalFirstMove = Learn(Wishes);
  413.                         if (mOptimalFirstMove > -1)
  414.                         {
  415.                             mEvalVal = 0;//1
  416.                             return mOptimalFirstMove;
  417.                         }
  418.                     }
  419.                     //eval cast
  420.                     double evaval = Double.MinValue;
  421.                     int retcast_actid = -1;
  422.                     //int uplim=casts.Count==4?11:10 ;
  423.                     int uplim = 9;
  424.  
  425.                     foreach (var castactt in TotalPositiveCastsDiff)
  426.                     {
  427.                         double cevaval = (castactt.TotalPos - TotalPositiveInv) + (SoLargeInv - castactt.SoLarge) * 3;
  428.                         if (cevaval > evaval && castactt.Sum < uplim && !LastSpellWasRemoved(castactt.Val.Value))
  429.                         {
  430.                             evaval = cevaval;
  431.                             retcast_actid = castactt.Key;
  432.                         }
  433.                     }
  434.  
  435.                     if (retcast_actid > -1)
  436.                     {
  437.                         mEvalVal = 0;
  438.                         mOptimalFirstMove = retcast_actid;
  439.                         return mOptimalFirstMove;
  440.                     }
  441.                     else if ((mCastsCans.Count < 3 && rest_ratio < 1.5) || (rest_ratio > 3 && mCurrentTotalInv >= 10))
  442.                     {
  443.                         mOptimalFirstMove = Learn(Wishes);
  444.                         if (mOptimalFirstMove > -1)
  445.                         {
  446.                             mEvalVal = 0;
  447.                             return mOptimalFirstMove;
  448.                         }
  449.                     }
  450.                 }
  451.                 // return (castCansDiffd.ElementAt((new Random(DateTime.Now.Millisecond)).Next(0, castCansDiffd.Count - 1)).Key);
  452.             }
  453.             //rest
  454.             mOptimalFirstMove = -1;
  455.             mEvalVal = 0;
  456.             return -1;
  457.         }
  458.  
  459.         // diffs beetween inventory and action list  
  460.         private Dictionary<int, int[]> GetInvDiffs(List<Action> acts)
  461.         {
  462.             return GetDiffs(acts, mPlayerData.Inventories);
  463.         }
  464.  
  465.         // cast_id - new inv[]
  466.         // dicVals -- new invetories dic
  467.         //used for check if can brew next move
  468.         private List<int> GetCastDiffsBrewNext(List<Action> acts, Dictionary<int, int[]> dicVals)
  469.         {
  470.             List<int> diffs = new List<int>();
  471.             foreach (var pair in dicVals)
  472.             {
  473.                 var tmp = GetDiffs(acts, pair.Value);
  474.                 var tmp_can = CanDo(tmp);
  475.                 if (tmp_can != null && tmp_can.Count > 0) diffs.Add(pair.Key);
  476.             }
  477.             return diffs;
  478.         }
  479.  
  480.         //diff between actions and arr
  481.         private Dictionary<int, int[]> GetDiffs(List<Action> acts, int[] vals)
  482.         {
  483.             Dictionary<int, int[]> diffs = new Dictionary<int, int[]>(); // mPlayerData.Inv +
  484.             foreach (var act in acts)
  485.             {
  486.                 var diff = new int[4];
  487.                 for (int i = 0; i < act.Deltas.Length; i++)
  488.                 {
  489.                     int ad = act.Deltas[i];
  490.                     diff[i] = vals[i] + ad;
  491.                 }
  492.                 diffs.Add(act.ActionId, diff);
  493.             }
  494.             return diffs;
  495.         }
  496.  
  497.         //vals wish casts
  498.         public int Learn(int[,] vals)
  499.         {
  500.             int ret = -1;
  501.             //            List<Action> learn_acts = mActions.Where(act => act.StrActionType.Equals("LEARN"))?.ToList();
  502.  
  503.             if (mLearnActs != null && mLearnActs.Count > 0)
  504.             {
  505.  
  506.                 if (mCanLearn != null && mCanLearn.Count() > 0 && vals != null)
  507.                 {
  508.                     var can_learn_diffs = GetInvDiffs(mCanLearn);
  509.                     var can_learn_can_do = CanDo(can_learn_diffs);
  510.  
  511.                     int max = Int32.MinValue;
  512.                     int act_id = -1;
  513.                     foreach (var can_lact in can_learn_can_do)
  514.                     {
  515.                         for (int i = 0; i < vals.GetLength(0); i++)
  516.                         {
  517.                             int sum = 0;
  518.                             for (int j = 0; j < vals.GetLength(1); j++)
  519.                             {///???????
  520.  
  521.                                 var wval = vals[i, j]; //if 0 didn't calc, we didn't need it//give worth results
  522.                                                        // if (wval < 0)
  523.                                 {
  524.                                     var lactv = can_lact.Value[j];
  525.                                     sum += (wval + lactv); // 0<  lim -> 0
  526.                                 }
  527.  
  528.                             }
  529.                             if (sum > max)
  530.                             {
  531.                                 max = sum;
  532.                                 act_id = can_lact.Key;
  533.                             }
  534.                         }
  535.                     }
  536.                     if (act_id > -1) return act_id;
  537.                 }
  538.  
  539.                 if (mCanLearn != null && mCanLearn.Count() > 0)
  540.                     return (mCanLearn[(new Random(DateTime.Now.Millisecond)).Next(0, mCanLearn.Count())].ActionId);
  541.             }
  542.  
  543.             return ret;
  544.         }
  545.         // wishes negative values what we need
  546.         public int[,] GetWishesFromBDiffs(Dictionary<int, int[]> bdiffs)
  547.         {
  548.             int[,] wishes = new int[bdiffs.Count, 4];
  549.  
  550.             for (int i = 0; i < bdiffs.Count; i++)
  551.             {
  552.                 if (bdiffs.ElementAt(i).Value.Any(v => v < 0))
  553.                 {
  554.                     for (int j = 0; j < 4; j++)
  555.                     {
  556.                         int val = bdiffs.ElementAt(i).Value[j];
  557.                         if (val < 0)
  558.                             wishes[i, j] = val;
  559.                         else
  560.                             wishes[i, j] = 0;
  561.                     }
  562.                 }
  563.             }
  564.             return wishes;
  565.         }
  566.         public bool LastSpellWasRemoved(int[] checvals)
  567.         {
  568.             for (int i = 0; i < checvals.Length; i++)
  569.             {
  570.                 if (checvals[i] == 0 && mPlayerData.Inventories[i] != 0)
  571.                 {
  572.                     return true;
  573.                 }
  574.             }
  575.             return false;
  576.         }
  577.  
  578.         public Action[] GetMaxPriceArr(Dictionary<int, int[]> candiffs, List<Action> acts)
  579.         {
  580.             var ActsCans = acts.Where(v => candiffs.Any(ba => ba.Key == v.ActionId)).ToList(); // brewCansDiffd.Where( v => bacts.Any(ad => ad.ActionId==v.Key)) ;
  581.             int maxprice = ActsCans.Max(m => m.Price);
  582.             var brewmax = ActsCans.Where(v => v.Price == maxprice).ToArray();
  583.             return brewmax;
  584.         }
  585.  
  586.  
  587.         //brew dic - breew diff inv+brew
  588.         private Dictionary<int, int[]> CanDo(Dictionary<int, int[]> dic)
  589.         {
  590.             Dictionary<int, int[]> cans = new Dictionary<int, int[]>();
  591.  
  592.             foreach (var d in dic)
  593.             {
  594.                 if (d.Value.Any(v => v < 0)) continue;
  595.                 cans.Add(d.Key, d.Value);
  596.             }
  597.             return cans;
  598.         }
  599.  
  600.         private int mOptimalFirstMove = -1;
  601.         private bool mFirstBrIsEval;
  602.  
  603.         private int mCurrentTotalInv;
  604.         private double mEvalVal;
  605.         private List<Action> mActions;
  606.         private int mActionCount;
  607.         private PData mPlayerData;
  608.         private PData mOpponentData;
  609.         private int mEvalActID; // was evaluated by this action        
  610.         private State mParent;
  611.         private List<State> mChildrens;
  612.         private List<Action> mBrewActs;
  613.         private List<Action> mCastsActs;
  614.         private List<Action> mUnCastsActs;
  615.         private List<Action> mOpCastsActs;
  616.         private List<Action> mLearnActs;
  617.         //
  618.         private List<Action> mCanLearn;
  619.         //brew diffs          
  620.         private Dictionary<int, int[]> mBDiffs;
  621.         //casts diffs
  622.         private Dictionary<int, int[]> mCDiffs;
  623.         //uncastable diffs
  624.         private Dictionary<int, int[]> mUnCDiffs;
  625.         //brew if can with max
  626.         private Dictionary<int, int[]> mBrewCansDiffd;
  627.         //
  628.         //cast
  629.         private Dictionary<int, int[]> mCastCansDiffd;
  630.         //uncastable can do
  631.         private Dictionary<int, int[]> mUnCastCansDiffd;
  632.         //
  633.         private List<Action> mCastsCans;
  634.         private List<Action> mUnCastsCans;
  635.         //
  636.         //same as new inventory after spell cast
  637.         private Dictionary<int, int[]> mCastsCansDiffDiff;
  638.         //same as new inventory after spell uncast
  639.         private Dictionary<int, int[]> mUnCastsCansDiffDiff;
  640.         //rest if brew next move
  641.         //Can do brew next move check
  642.         private List<int> mUnCastDiff3;
  643.         //Can do brew next move check
  644.         private List<int> mCastDiff3;
  645.         //
  646.  
  647.     }
  648.  
  649.     public class Evalator
  650.     {
  651.         public Evalator(int actCount, List<Action> actions, PData playerDat, PData oppDat)
  652.         {
  653.             mStates = new Stack<State>();
  654.             mStates.Push(new State(actions, playerDat, oppDat, actCount));
  655.         }
  656.  
  657.         public string Evaluate()
  658.         {
  659.             //1. get all possible acts exclude Brew
  660.             //2. walk over
  661.             //3. evaluate them
  662.             //4. FirstBrewMoves (add calc return to) for every
  663.             //5. generate tree walk over
  664.             // in the first league: BREW <id> | WAIT; later: BREW <id> | CAST <id> [<times>] | LEARN <id> | REST | WAIT
  665.  
  666.             try
  667.             {
  668.                 var curst = mStates.Peek();
  669.                 DebugTree.Init();
  670.                 //DebugTree.SetParent($"{curst.PlayerData}");              
  671.                 Process(curst, 0);
  672.                 DebugTree.SetEnd();
  673.                 var stree = DebugTree.StrTree;
  674.                 var retv = RecalAct(curst, 0);
  675.                 int actid = -1;
  676.                 //DebugPrint($"!!!! {retv.Item2} !!!!! {retv.Item1} !!!!");  
  677.  
  678.  
  679.                 if (retv.Item1 > 60 && retv.Item2 > -1)
  680.                 {
  681.                     DebugPrint($"!!!! {retv.Item2} !!!!! {retv.Item1} !!!!");
  682.                     actid = retv.Item2;
  683.                 }
  684.                 else
  685.                 {
  686.                     actid = curst.OptimalFirstMove;
  687.                 }
  688.  
  689.  
  690.                 if (actid > -1)
  691.                 {
  692.                     var act = mStates.Peek().Actions.First(av => av.ActionId == actid);
  693.  
  694.                     return $"{act.StrActionType} {act.ActionId}";
  695.                 }
  696.             }
  697.             catch (Exception e)
  698.             {
  699.                 DebugPrint($"Exception!!!!!!!!!! msg: {e.Message}\r\n stack trace: {e.StackTrace} \r\n ");
  700.             }
  701.  
  702.             return "REST";
  703.         }
  704.         //ret max, EvalActId
  705.         private (double, int) RecalAct(State st, int depth)
  706.         {
  707.             if (depth > mMaxDepth)
  708.             {
  709.                 return (0, -1);
  710.             }
  711.  
  712.             double max = double.MinValue;
  713.             int eactid = -1;
  714.             foreach (var cst in st.Childrens)
  715.             {
  716.                 double c = cst.EvalVal;
  717.                 var tmp = RecalAct(cst, ++depth);
  718.                 c += tmp.Item1;
  719.                 if (c > max)
  720.                 {
  721.                     max = c;
  722.                     eactid = cst.EvalActID;
  723.                 }
  724.             }
  725.  
  726.             return (max, eactid);
  727.         }
  728.         private void Process(State st, int depth)
  729.         {
  730.             if (depth > mMaxDepth)
  731.             {
  732.                 return;
  733.             }
  734.  
  735.             var fmactId = st.FirstBrewMoves();
  736.  
  737.          
  738.          
  739.             foreach (var canacts in st.CastsCans)
  740.             {
  741.                 var nst = st.EvaluateByActId(canacts.ActionId);
  742.                 Process(nst, 1 + depth);
  743.             }
  744. #if DEBUG && TESTING
  745.             foreach (var nst in st.Childrens)
  746.             {
  747.                 DebugTree.SetChilds(depth, st, nst);
  748.             }
  749. #endif
  750.  
  751.         }
  752.  
  753.         private int mMaxDepth = 10;
  754.         private Stack<State> mStates;
  755.  
  756.     }
  757.     public static string ExecuteCommand(string command, string args)
  758.     {
  759.         Process proc = new System.Diagnostics.Process();
  760.         string out_txt = "";
  761.         proc.StartInfo.FileName = $"{command}";
  762.         proc.StartInfo.Arguments = $" {args}";
  763.         proc.StartInfo.UseShellExecute = false;
  764.         proc.StartInfo.RedirectStandardOutput = true;
  765.         proc.Start();
  766.         StreamReader reader = proc.StandardOutput;
  767.         out_txt = reader.ReadToEnd();
  768.         return out_txt;
  769.     }
  770.     public static void Start()
  771.     {
  772.  
  773.         // game loop
  774.         while (true)
  775.         {
  776.             int actionCount = int.Parse(Console.ReadLine()); // the number of spells and recipes in play
  777.             DebugPrint($"actionCount: {actionCount}");
  778.             List<Action> Actions = new List<Action>();
  779.             for (int i = 0; i < actionCount; i++)
  780.             {
  781.                 var ln0 = Console.ReadLine();
  782.                 DebugPrint($"actions 0: {ln0}");
  783.                 Actions.Add(new Action(ln0));
  784.             }
  785.             //
  786.             var ln1 = Console.ReadLine();
  787.             DebugPrint($"player data : {ln1}");
  788.             PData pdat = new PData(ln1);
  789.  
  790.             ln1 = Console.ReadLine();
  791.             DebugPrint($"op data : {ln1}");
  792.             PData opdat = new PData(ln1);
  793.  
  794.             Evalator evl = new Evalator(actionCount, Actions, pdat, opdat);
  795.  
  796.             // in the first league: BREW <id> | WAIT; later: BREW <id> | CAST <id> [<times>] | LEARN <id> | REST | WAIT
  797.            
  798.             Console.WriteLine(evl.Evaluate());
  799.  
  800.         }
  801.     }
  802.  
  803.   //  public static void Main(string[] args) => Start();
  804. }
  805.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement