Advertisement
Normantas

Coding Game: Ocean of Code

Jan 16th, 2021
1,042
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 62.25 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.IO;
  4. using System.Text;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Diagnostics;
  9. /**
  10.  * Auto-generated code below aims at helping you parse
  11.  * the standard input according to the problem statement.
  12.  **/
  13. class Player
  14. {  
  15.     static void Main(string[] args)
  16.     {
  17.         //Initializes the BOT--------------------------------------------------------------------------------------------------------------------------------------------------
  18.         Dictionary<string, Movement> movementDictionary = InitializeMovementDictionary();
  19.         List<Movement> movementList = InitializeMovementList();
  20.         int prevOppLife = 6;
  21.         int prevMyLife = 6;
  22.         //Inputs
  23.         string map = "";
  24.         string[] inputs;
  25.         inputs = Console.ReadLine().Split(' ');
  26.         int width = int.Parse(inputs[0]);
  27.         int height = int.Parse(inputs[1]);
  28.         int myId = int.Parse(inputs[2]);
  29.         for (int i = 0; i < height; i++)
  30.         {
  31.             string line = Console.ReadLine();
  32.             map += line;
  33.         }
  34.        
  35.         Grid[,] grid = CreateGrid(map, height, width,0,0);
  36.         //Random spawn postion that is not island----------------------------------------
  37.         SpawnSubmarine(grid,movementList);
  38.        
  39.        
  40.         Location lastShotTorpedo = new Location(-1, -1);
  41.         bool lastTurnUsedTorpedo = false;
  42.         int prevSonarSector = -1;
  43.         string move = "";
  44.         string myPrevOppMove = "";
  45.         List<OppGrid> oppGrid = InitializeOppGrid(grid);
  46.         List<OppGrid> myOppGrid = InitializeOppGrid(grid);
  47.         bool hasTouchedCorners = false;
  48.         string prevOppMove = "";
  49.         int silenceUses = 0;
  50.         Location lastMineTrigger = new Location(-1,-1);
  51.         List<Location> mines = new List<Location>();
  52.         int silenceCountDown = 0;
  53.         bool hadNotToBrakeOut = true;
  54.        
  55.         // -------------------game loop---------------------------------------------------------------------------------------------------------
  56.         while (true)
  57.         {      
  58.             string currTurn = "";
  59.  
  60.             if(oppGrid.Any() == false) //resets grid
  61.                 oppGrid = InitializeOppGrid(grid);
  62.                
  63.             if(myOppGrid.Any() == false) //resets grid
  64.                 myOppGrid = InitializeOppGrid(grid);
  65.            
  66.             //Inputs
  67.             inputs = Console.ReadLine().Split(' ');
  68.             int x = int.Parse(inputs[0]);
  69.             int y = int.Parse(inputs[1]);
  70.             int myLife = int.Parse(inputs[2]);
  71.             int oppLife = int.Parse(inputs[3]);
  72.             int torpedoCooldown = int.Parse(inputs[4]);
  73.             int sonarCooldown = int.Parse(inputs[5]);
  74.             int silenceCooldown = int.Parse(inputs[6]);
  75.             int mineCooldown = int.Parse(inputs[7]);
  76.             string sonarResult = Console.ReadLine();
  77.             string opponentOrders = Console.ReadLine();
  78.            
  79.             bool oppHasUsedSilence = false;
  80.             Location oppShotTorpedo = new Location(-1,-1);
  81.             grid[y,x].CanBeSwimmed = false;
  82.             bool hasNotExplodedAMine = true;
  83.             bool hasPlacedMine = false;
  84.             silenceCountDown++;
  85.             int moveValue = 0;
  86.             Location oppTriggeredMine = new Location(-1,-1);
  87.             bool hasUsedSilence = false;
  88.            
  89.             //Updates info after the previous turn
  90.             if(sonarResult != "NA")
  91.                 oppGrid = UpdateOppGridOnSonar(oppGrid, prevSonarSector, sonarResult, grid);
  92.                
  93.             if(lastShotTorpedo.x != -1 || lastMineTrigger.x != -1)
  94.             {
  95.                 oppGrid = UpdateGridAfterFiring(oppGrid, lastShotTorpedo, lastMineTrigger, oppLife, prevOppLife, opponentOrders);
  96.             }
  97.              
  98.              Console.Error.WriteLine($"OPP orders are {opponentOrders}");
  99.             //Reads enemies inputs that I might use
  100.             foreach(var command in opponentOrders.Split('|'))
  101.             {
  102.                 var time = new Stopwatch();
  103.                 time.Start();
  104.                 string[] orders = command.Split(' ');
  105.                
  106.                
  107.                 if (orders[0] == "TORPEDO")
  108.                 {
  109.                     oppGrid = UpdateOppGridOnTorpedoFire(oppGrid, grid ,new Location(int.Parse(orders[1]),int.Parse(orders[2])));
  110.                     oppShotTorpedo = new Location(int.Parse(orders[1]),int.Parse(orders[2]));
  111.                    
  112.                     Console.Error.Write("Has tested for OPP postions post OPP-TORPEDO-FIRE");
  113.                 }
  114.                    
  115.                 else if(orders[0] == "MOVE")
  116.                 {
  117.                     oppGrid = UpdateOppGridOnMove(oppGrid, grid, orders[1], movementDictionary, hadNotToBrakeOut);
  118.                     Console.Error.Write("Has tested for OPP postions post MOVE");
  119.                     prevOppMove = orders[1];
  120.                 }
  121.                    
  122.                  else if (orders[0] == "SURFACE")
  123.                  {
  124.                     oppGrid = UpdateOppGridOnSurface(oppGrid, grid, int.Parse(orders[1]));
  125.                     Console.Error.Write("Has tested for OPP postions post SURFACE");
  126.                     prevOppMove = "";
  127.                  }
  128.                 else if(orders[0] == "TRIGGER")
  129.                 {
  130.                     oppTriggeredMine = new Location(int.Parse(orders[1]),int.Parse(orders[2]));
  131.                    
  132.                     if(hadNotToBrakeOut)
  133.                         oppGrid = UpdateOppGridAfterMineFieldCheck(oppGrid, oppTriggeredMine);
  134.                        
  135.                     oppGrid = UpdateOppGridAfterMineTrigger(oppGrid, grid, oppTriggeredMine, oppLife, prevOppLife);
  136.                     Console.Error.Write("Has tested for OPP postions post ENEMY-TRIGGER");
  137.                 }
  138.                 else if (orders[0] == "SILENCE")
  139.                 {
  140.                     oppGrid = UpdateOppGridOnOppSilence(oppGrid, prevOppMove, grid, ref hadNotToBrakeOut);
  141.                     Console.Error.Write("Has tested for OPP postions post SILENCE");
  142.                     hasUsedSilence = true;
  143.                 }
  144.                 else if (orders[0] == "MINE")
  145.                 {
  146.                     if(hadNotToBrakeOut)
  147.                         oppGrid = UpdateOppGridOnMinePlaced(oppGrid);
  148.                        
  149.                     Console.Error.Write("Has updated Minefield for OPPs");
  150.                 }
  151.                     time.Stop();
  152.                     Console.Error.WriteLine($" Time:{time.ElapsedMilliseconds}");
  153.             }    
  154.              
  155.             //Decides what to do
  156.             int[,] valueGrid = CreateValueGrid(oppGrid); //Creates a value-grid from the current information
  157.             //int[,] valueGrid = CreateValueGrid(ResetOppGridOnLocations(oppGrid)); //Creates a value-grid from the current information
  158.             int[,] mineLocChecker = MineFill(mines);
  159.             ValueGridTyped(valueGrid);
  160.             if(oppGrid.Any() && hadNotToBrakeOut)
  161.                 WriteMinefield(oppGrid[0].minefield);
  162.            
  163.             lastMineTrigger = new Location(-1,-1); //resets last Triggered Mine
  164.             lastShotTorpedo = new Location(-1,-1); //Resets Torpedo
  165.            
  166.             //At Start
  167.             RepeatableActionCheck(ref lastShotTorpedo, ref hasPlacedMine, ref lastMineTrigger, oppGrid, grid, ref currTurn, x, y, ref torpedoCooldown, ref mineCooldown, ref mines);
  168.            
  169.             move = GetMove(grid, oppGrid, mines, x, y, movementList, movementDictionary, ref moveValue, torpedoCooldown); //Decides in what direction to move;
  170.            
  171.                
  172.             if(move != "" && (currTurn == "" || lastShotTorpedo.x != -1))
  173.             {
  174.                 string item = GetItem(ref torpedoCooldown, ref silenceCooldown, ref sonarCooldown, ref mineCooldown);
  175.                 currTurn += String.Format($"MOVE {move} {item} |");
  176.                 myPrevOppMove = move;
  177.                 x+=movementDictionary[move].x; //Updates my currPostion
  178.                 y+=movementDictionary[move].y;
  179.                 Console.Error.WriteLine($"My current position after move is x:{x} y:{y}");
  180.                 grid[y,x].CanBeSwimmed = false;
  181.                 //Post Move
  182.                 RepeatableActionCheck(ref lastShotTorpedo, ref hasPlacedMine, ref lastMineTrigger, oppGrid, grid, ref currTurn, x, y, ref torpedoCooldown, ref mineCooldown, ref mines);
  183.             }
  184.            
  185.             // ------------------------------------------------------------------------------------------------------
  186.             if(silenceCooldown == 0 && silenceCountDown >= 20) //SILENCE --------------------------------------------------------
  187.                 DeploySilence(oppGrid, ref myOppGrid, ref grid, ref currTurn, ref x, ref y, map,
  188.                 mines, oppShotTorpedo, oppTriggeredMine, myLife, sonarCooldown, mineCooldown, torpedoCooldown, ref lastShotTorpedo, ref silenceCooldown);
  189.                
  190.            
  191.             prevSonarSector = -1;
  192.             if(sonarCooldown == 0)
  193.                 DeploySonar(oppGrid, ref currTurn, ref prevSonarSector, hasUsedSilence);
  194.            
  195.             //Post Silence
  196.             if(silenceCooldown == -1)
  197.                 RepeatableActionCheck(ref lastShotTorpedo, ref hasPlacedMine, ref lastMineTrigger, oppGrid, grid, ref currTurn, x, y, ref torpedoCooldown, ref mineCooldown, ref mines);
  198.            
  199.             if(currTurn == "")
  200.             {
  201.                 Console.Write("SURFACE |");
  202.                 hasTouchedCorners = false;
  203.                 grid = CreateGrid(map, height, width,x,y); //resets my path
  204.             }
  205.  
  206.             //Saves info for next round depending how I left
  207.             Console.WriteLine(currTurn); //Ends Turn
  208.             if(x == 0 || y == 0 || x == 14 || y == 14)
  209.                 hasTouchedCorners = !hasTouchedCorners;      
  210.             Console.Error.WriteLine($"My Current sector is: {CalculateSectorFromCordinates(x, y)}");
  211.            movementList = UpdateMovementList(move, hasTouchedCorners); //sets priority of movement
  212.            Console.Error.WriteLine($"My Move direcition: {move}");
  213.            prevOppLife = oppLife;
  214.            prevMyLife = myLife;
  215.         }
  216.     }
  217.    
  218.  
  219.         //--------------------------------------------------------------------------------------------------------------------------------------
  220.     /*------------------------Classes and structs*/
  221.  
  222.     public struct Movement
  223.     {
  224.         public string direction {get; set;}
  225.         public int x {get; set;}
  226.         public int y {get; set;}
  227.        
  228.         public Movement(int _x, int _y,string _direction)
  229.         {
  230.             x = _x;
  231.             y = _y;
  232.             direction = _direction;
  233.         }
  234.        
  235.     }
  236.    
  237.     public struct Location
  238.     {
  239.         public int x { get; set; }
  240.         public int y { get; set; }
  241.         public Location(int _x, int _y)
  242.         {
  243.             x = _x;
  244.             y = _y;
  245.         }
  246.     }
  247.    
  248.    
  249.     public struct OppGrid
  250.     {    
  251.         public int x { get; set; }
  252.         public int y { get; set; }
  253.         public bool[,] hasVisited { get; set; }
  254.         public bool[,] minefield { get; set; }
  255.         public OppGrid(int _x, int _y)
  256.         {
  257.             x = _x;
  258.             y = _y;
  259.             hasVisited = new bool[15,15];
  260.             minefield = new bool[15,15];
  261.         }
  262.     }
  263.    
  264.     public struct Grid
  265.     {
  266.         public bool IsNotIsland {get; set;}
  267.         public bool CanBeSwimmed { get; set; }
  268.         public int x { get; set; }
  269.         public int y { get; set; }
  270.     }
  271.         //--------------------------------------------------------------------------------------------------------------------------------------
  272.         /*------------------------Methods */
  273.         //--------------------------------------------------------------------------------------------------------------------------------------
  274.        
  275.         public static void RepeatableActionCheck(ref Location lastShotTorpedo, ref bool hasPlacedMine, ref Location lastMineTrigger, List<OppGrid> oppGrid, Grid[,] grid, ref string currTurn, int x, int y,
  276.         ref int torpedoCooldown, ref int mineCooldown, ref List<Location> mines)
  277.         {
  278.             if(torpedoCooldown == 0 && lastShotTorpedo.x == -1)
  279.                 lastShotTorpedo = FireTorpedo(oppGrid, grid, oppGrid.Count(), x, y, ref currTurn);
  280.                
  281.             if(lastShotTorpedo.x != -1)
  282.                 torpedoCooldown = 3;
  283.                
  284.             if(mineCooldown == 0)
  285.             {
  286.                 hasPlacedMine = DeployMine(ref mines, grid, ref currTurn, x, y);
  287.                 if(hasPlacedMine)
  288.                         mineCooldown = 3;
  289.             }
  290.            
  291.             if(lastMineTrigger.x == -1)
  292.             {
  293.                 lastMineTrigger = TriggerMine(oppGrid, ref mines, ref currTurn, x, y);
  294.             }
  295.         }
  296.     //--------------------------------------------------------------------------------------------------------------------------------------        
  297.     //--------------------------------------------------------------------------------------------------------------------------------------        
  298.     //MINES
  299.     public static Location TriggerMine(List<OppGrid> oppGrid, ref List<Location> mines, ref string currTurn, int x, int y) //KILLER QUEEN FIRST BOMB!
  300.     {
  301.         var timeCheckAfterFiring = new Stopwatch();
  302.         timeCheckAfterFiring.Start();
  303.         oppGrid = ResetOppGridOnLocations(oppGrid);
  304.         int[,] valueGrid = CreateValueGrid(oppGrid);
  305.        
  306.         Location target = new Location(-1,-1);
  307.        
  308.         int currValue = 0;
  309.         foreach(Location loc in mines)
  310.         {  
  311.             int movedX = Math.Abs(loc.x-x);
  312.             int movedY = Math.Abs(loc.y-y);
  313.            
  314.             if(movedY > 1 || movedX > 1) // Does not hit me
  315.             {
  316.                     int corX = loc.x-1;
  317.                     int corY = loc.y-1;
  318.                     int tempValue = 0;
  319.                     for(int i = 0; i < 3; i++) //Calculates the value of this trigger
  320.                         for(int l = 0; l < 3; l++)
  321.                             {
  322.                                 if(InGrid(corX+i,corY+l))
  323.                                     tempValue+=valueGrid[corY+l,corX+i];
  324.                             }
  325.                            
  326.                     if(tempValue > currValue)
  327.                     {
  328.                         currValue = tempValue;
  329.                         target = new Location(loc.x,loc.y);
  330.                     }
  331.             }
  332.         }
  333.        
  334.         timeCheckAfterFiring.Stop();
  335.         Console.Error.WriteLine($"Time for TRIGGERING A MINE:{timeCheckAfterFiring.ElapsedMilliseconds}");
  336.        
  337.         int dev;
  338.         if(mines.Count >= 10)
  339.             dev = 4;
  340.         else if(mines.Count >= 7)
  341.             dev = 3;
  342.         else
  343.             dev = 2;
  344.        
  345.            
  346.         if(currValue >= oppGrid.Count() / dev && target.x != -1) //checks if it's worth it to detonate
  347.         {
  348.             currTurn += String.Format($"TRIGGER {target.x} {target.y} | MSG KILLER'S QUEEN THIRD BOMB! | ");
  349.             List<Location> minesOutput = new List<Location>();
  350.             foreach(var i in mines)
  351.             {
  352.                 if(i.x != target.x && i.y != target.y)
  353.                     minesOutput.Add(i);
  354.             }
  355.             mines = minesOutput;
  356.             return target;
  357.         }
  358.            
  359.         return new Location(-1,-1); //No good target
  360.     }
  361.    
  362.     public static bool DeployMine(ref List<Location> mines, Grid[,] grid, ref string currTurn, int x, int y)
  363.     {
  364.         Dictionary<string, Movement> moveDict = InitializeMovementDictionary();
  365.         int[,] mineLocChecker = MineFill(mines);
  366.        
  367.         foreach(var i in moveDict.Values)
  368.         {
  369.             int tempX = i.x + x;
  370.             int tempY = i.y + y;
  371.             int mineValueToPlace = mines.Count() / 10;
  372.             if(InGrid(tempX,tempY) && mineLocChecker[tempY, tempX] <= mineValueToPlace && grid[tempY,tempX].IsNotIsland && tempX != 14 && tempX != 0 && tempY != 0 && tempY != 14)
  373.             {
  374.                 mines.Add(new Location(tempX,tempY));
  375.                 currTurn += String.Format($"MINE {i.direction} |");
  376.                 return true;
  377.                 break;
  378.             }
  379.         }
  380.         return false;
  381.     }
  382.    
  383.     public static int[,] MineFill(List<Location> mines)
  384.     {
  385.         int [,] output = new int[15,15];
  386.         foreach(Location mine in mines)
  387.         {
  388.             int corX = mine.x-2;
  389.             int corY = mine.y-2;
  390.             for(int y = 0; y < 5; y++)
  391.             {
  392.                 for(int x = 0; x < 5; x++)
  393.                     if(InGrid(corY+y,corX+x))
  394.                         output[corY+y,corX+x]++;
  395.             }
  396.            
  397.             //Removes corners
  398.             if(InGrid(corY,corX))
  399.                 output[corY,corX]--;
  400.                
  401.             if(InGrid(corY+4,corX))
  402.                 output[corY+4,corX]--;
  403.                
  404.             if(InGrid(corY,corX+4))
  405.                 output[corY,corX+4]--;
  406.                
  407.             if(InGrid(corY+4,corX+4))
  408.                 output[corY+4,corX+4]--;
  409.                
  410.             output[mine.y,mine.x] += 100;
  411.         }
  412.         return output;
  413.     }
  414.     //-------------------------------------------------
  415.     //GRID functions
  416.     //creates a grid with the island locations, used for initialization and surface-----------------------------------------------------------------------------
  417.     public static List<OppGrid> UpdateOppGridOnMinePlaced(List<OppGrid> oppGrid)
  418.     {
  419.         Dictionary<string,Movement> moveDict = InitializeMovementDictionary();
  420.         Console.Error.WriteLine("Updated OPPs on their possible mine placements");
  421.        
  422.         foreach(OppGrid obj in oppGrid)
  423.             foreach(var movement in moveDict.Values)
  424.             {
  425.                 int x =  obj.x+ movement.x;
  426.                 int y = obj.y + movement.y;
  427.                 if(InGrid(x,y))
  428.                     obj.minefield[y,x] = true; //Updates possible mine locations.
  429.             }
  430.            
  431.         return oppGrid;
  432.     }
  433.     public static int[,] DistanceFill(Grid[,] grid, int x, int y, int maxVal)
  434.     {
  435.         Dictionary<string, Movement> moveDict = InitializeMovementDictionary();
  436.         LinkedList<Location> myList = new LinkedList<Location>();
  437.         myList.AddLast(new Location(x,y));
  438.        
  439.         int[,] output = new int[15,15];
  440.         output[y,x] = maxVal;
  441.        
  442.         while(myList.Any())
  443.         {
  444.             Location i = myList.First.Value;
  445.             myList.RemoveFirst();
  446.             if(output[i.y,i.x] > 1)
  447.             {
  448.                 foreach(var mov in moveDict.Values)
  449.                 {
  450.                        int tempX = i.x+mov.x;
  451.                        int tempY = i.y+mov.y;
  452.                        if(InGrid(tempX, tempY) && grid[tempY,tempX].IsNotIsland)
  453.                        {
  454.                            if(output[i.y,i.x]-1 > output[tempY,tempX])
  455.                            {
  456.                                 output[tempY,tempX] = output[i.y,i.x] - 1;
  457.                                 myList.AddLast(new Location(tempX, tempY));
  458.                            }
  459.                        }
  460.                 }
  461.             }
  462.         }
  463.         return output;
  464.     }
  465.    
  466.     public static Grid[,] CreateGrid(string str, int height, int width,int x, int y)
  467.     {
  468.         Grid[,] output = new Grid[height,width];
  469.         for(int i = 0; i < str.Length; i++)
  470.         {
  471.             bool temp = true;
  472.             if(str[i] == 'x')
  473.                 temp = false;
  474.                
  475.             output[i/width,i%width].CanBeSwimmed = temp; //Islands and swimmed terrain is marked with false, so info can be pasted in a boolean expression
  476.             output[i/width,i%width].IsNotIsland = temp;
  477.             output[i/width,i%width].y = i/width;
  478.             output[i/width,i%width].x = i%width;
  479.         }
  480.         output[y,x].CanBeSwimmed = false;
  481.         return output;
  482.     }
  483.     public static List<OppGrid> InitializeOppGrid(Grid[,] grid)
  484.     {
  485.         List<OppGrid> output = new List<OppGrid>();
  486.        for(int y = 0; y < 15; y++)
  487.        {
  488.             for(int x = 0; x < 15; x++)
  489.             {
  490.                     if(grid[y,x].IsNotIsland)
  491.                     {
  492.                         OppGrid temp = new OppGrid(x,y);
  493.                         output.Add(temp);
  494.                     }  
  495.             }
  496.        }
  497.        Console.Error.WriteLine($"Initialized OppGrid At start, size {output.Count()}");
  498.        return output;
  499.     }
  500.        
  501.     public static Grid[,] MakeADeepGridCopy(Grid[,] grid)
  502.     {
  503.         Grid[,] output = new Grid[15,15];
  504.         for(int y = 0; y < 15; y++)
  505.             for(int x = 0; x < 15; x++)
  506.             {
  507.                 output[y,x].x = grid[y,x].x;
  508.                 output[y,x].y = grid[y,x].y;
  509.                 output[y,x].CanBeSwimmed = grid[y,x].CanBeSwimmed;
  510.             }
  511.         return output;
  512.     }
  513.        
  514.     public static bool InGrid(int x, int y) //checks if the object cordinates are in grid.
  515.     {
  516.         return x <= 14  && y <= 14 && x >= 0 && y >= 0;
  517.     }
  518.  
  519.     public static int[,] CreateValueGrid(List<OppGrid> oppGrid)
  520.     {
  521.         int[,] output = new int[15,15];
  522.        
  523.         foreach(var i in oppGrid)
  524.         {
  525.             output[i.y,i.x]++;
  526.         }
  527.         return output;
  528.     }
  529.    
  530.     public static void ValueGridTyped(int[,] grid)
  531.     {
  532.         Console.Error.Write($"  ");
  533.         for(int i = 0; i < 15; i++)
  534.             Console.Error.Write($" {i%10}");
  535.         Console.Error.WriteLine("\n--------------------------------");
  536.        
  537.         for(int y = 0; y < 15; y++)
  538.         {
  539.             Console.Error.Write($"{y%10}|");
  540.             for(int x = 0; x < 15; x++)
  541.             {
  542.                 Console.Error.Write($" {grid[y,x]}");
  543.             }
  544.             Console.Error.WriteLine();
  545.         }
  546.     }
  547.     public static int CalculateSectorFromCordinates(int x, int y)
  548.     {
  549.         return 1 + (y / 5) * 3 + x / 5;
  550.     }
  551.    
  552.    
  553.     public static List<OppGrid> ResetOppGridOnLocations(List<OppGrid> oppGrid)
  554.     {
  555.         bool[,] locations = new bool[15,15];
  556.         foreach(OppGrid obj in oppGrid)
  557.             locations[obj.y,obj.x] = true;
  558.          
  559.         List<OppGrid> output = new List<OppGrid>();  
  560.         for(int y = 0; y < 15; y++)
  561.             for(int x = 0; x < 15; x++)
  562.                 if(locations[y,x])
  563.                     output.Add(new OppGrid(x,y));
  564.                    
  565.         return output;
  566.     }
  567.     public static void WriteMinefield(bool[,] minefield)
  568.     {
  569.         for(int i = 0; i < 15; i++)
  570.         {
  571.             for(int l = 0; l < 15; l++)
  572.             {
  573.                 if(minefield[i,l])
  574.                     Console.Error.Write(" +");
  575.                 else
  576.                     Console.Error.Write(" -");
  577.             }
  578.             Console.Error.WriteLine();
  579.         }
  580.     }
  581.    
  582.     //--------------------------------------------------------------------------------------------------------------------------------------
  583.     //Grid Update functions to predict enemies----------------------------------------------------------------------------------------------
  584.     public static List<OppGrid> UpdateOppGridAfterMineFieldCheck(List<OppGrid> oppGrid, Location mine)
  585.     {
  586.         Console.Error.WriteLine("\n\nUPDATED oppGRID after mineFieldCheck\n\n");
  587.         List<OppGrid> output = new List<OppGrid>();
  588.         foreach(OppGrid obj in oppGrid)
  589.         {
  590.             if(obj.minefield[mine.y,mine.x])
  591.                 {
  592.                     obj.minefield[mine.y,mine.x] = false;
  593.                     output.Add(obj);
  594.                 }
  595.         }
  596.         return output;
  597.     }
  598.    
  599.     public static int[,] DrawDamageGrid(Location torpedo, Location mine)
  600.     {  
  601.         int[,] output = new int[15,15];
  602.         if(torpedo.x != -1) //Draws torpedo
  603.         {
  604.             int x = torpedo.x - 1;
  605.             int y = torpedo.y - 1;
  606.             for(int i = 0; i < 3; i++) //X
  607.                 for(int l = 0; l < 3; l++) //Y
  608.                     if(InGrid(x+i,y+l))
  609.                         output[y+l,x+i]++;
  610.                        
  611.             output[torpedo.y,torpedo.x]++;
  612.                        
  613.         }
  614.        
  615.         if(mine.x != -1) //Draws Mine
  616.         {
  617.             int x = mine.x - 1;
  618.             int y = mine.y - 1;
  619.             for(int i = 0; i < 3; i++) //X
  620.                 for(int l = 0; l < 3; l++) //Y
  621.                     if(InGrid(x+i,y+l))
  622.                         output[y+l,x+i]++;
  623.                        
  624.             output[mine.y,mine.x]++;
  625.                        
  626.         }
  627.         return output;
  628.     }
  629.    
  630.     public static bool[,] copyHasVisited(OppGrid obj)
  631.     {
  632.         bool[,] output = new bool[15,15];
  633.         for(int y = 0; y < 15; y++)
  634.             for(int x = 0; x < 15; x++)
  635.                 output[y,x] = obj.hasVisited[y,x];
  636.         return output;
  637.     }
  638.     public static bool[,] copyMinefield(OppGrid obj)
  639.     {
  640.         bool[,] output = new bool[15,15];
  641.         for(int y = 0; y < 15; y++)
  642.             for(int x = 0; x < 15; x++)
  643.                 output[y,x] = obj.minefield[y,x];
  644.                
  645.         return output;
  646.     }
  647.    
  648.     public static List<OppGrid> UpdateOppGridAfterMineTrigger(List<OppGrid> oppGrid, Grid[,] grid, Location triggerLoc, int hpp, int prevHpp)
  649.     {
  650.         if(prevHpp == hpp) //HasNotHitHimself
  651.         {
  652.             int[,] distanceGrid = DistanceFill(grid,triggerLoc.x,triggerLoc.y,2);
  653.            
  654.             List<OppGrid> output = new List<OppGrid>();
  655.             foreach(OppGrid i in oppGrid)
  656.             {
  657.                 if(distanceGrid[i.y,i.x] == 0)
  658.                     output.Add(i);
  659.             }
  660.             return output;
  661.         }
  662.         else
  663.             return oppGrid;
  664.     }
  665.    
  666.     public static List<OppGrid> UpdateGridAfterFiring(List<OppGrid> oppGrid, Location lastShotTorpedo, Location lastMineTrigger, int oppLife, int prevOppLife, string opponentOrders)
  667.     {  
  668.         var timeCheckPostMyTorpedoFire = new Stopwatch();
  669.         timeCheckPostMyTorpedoFire.Start();
  670.        
  671.         List<OppGrid> output = new List<OppGrid>();        
  672.         int hpDiff = 0;
  673.        
  674.         int[,] damageGrid = DrawDamageGrid(lastShotTorpedo,lastMineTrigger);
  675.        
  676.         if(opponentOrders.Contains("SURFACE")) //Checks if the enemy has not surfaced for safe check;
  677.             hpDiff++;
  678.        
  679.         Console.Error.WriteLine($"POF:{prevOppLife} OF:{oppLife} HDF:{hpDiff}");
  680.         if(prevOppLife - oppLife > hpDiff)
  681.         {
  682.             hpDiff = prevOppLife - oppLife + hpDiff;
  683.             Console.Error.WriteLine($"hpDiff is:{hpDiff}");
  684.             foreach(var obj in oppGrid)
  685.                 if(damageGrid[obj.y,obj.x] == hpDiff)
  686.                     output.Add(obj);
  687.         }
  688.         else //Has missed
  689.         {
  690.            output = UpdateGridOnTorpedoMissed(oppGrid,lastShotTorpedo, lastMineTrigger);
  691.         }
  692.  
  693.         timeCheckPostMyTorpedoFire.Stop();
  694.         Console.Error.WriteLine($"Time After my torpedo fire AFTERCHECK:{timeCheckPostMyTorpedoFire.ElapsedMilliseconds}");
  695.         return output;
  696.     }
  697.    
  698.     public static List<OppGrid> UpdateOppGridOnOppSilence(List<OppGrid> oppGrid, string prevMove, Grid[,] grid, ref bool HadNotBrokenOut)
  699.     {
  700.         var time = new Stopwatch();
  701.         Dictionary<string, Movement> moveDict = InitializeMovementDictionary();
  702.         moveDict.Remove(prevMove);
  703.        
  704.         int count = oppGrid.Count();
  705.         bool brakeOut = false;
  706.        
  707.         List<OppGrid> output = new List<OppGrid>();
  708.         int[,] valueGrid = CreateValueGrid(oppGrid);
  709.  
  710.        
  711.         foreach(OppGrid obj in oppGrid) //Main way of checking previous paths.
  712.         {
  713.             foreach(Movement dir in moveDict.Values)
  714.             {
  715.                 int moveX = dir.x;
  716.                 int moveY = dir.y;
  717.                
  718.                 OppGrid parent = new OppGrid(obj.x, obj.y);
  719.                 parent.hasVisited = copyHasVisited(obj);
  720.                     if(HadNotBrokenOut)
  721.                         parent.minefield = copyMinefield(obj);
  722.                 parent.hasVisited[parent.y,parent.y] = true;
  723.                 for(int i = 0; i < 4; i++)
  724.                 {
  725.                     if(count > 9000)
  726.                     {
  727.                         brakeOut = true;
  728.                         HadNotBrokenOut = false;
  729.                         Console.Error.WriteLine("\n\n\n\n\nHAD TO BRAKE OUT\n\n\n\n");
  730.                         break; //brakes out incase of timeout
  731.                     }  
  732.                    
  733.                     int x = parent.x+moveX;
  734.                     int y = parent.y+moveY;
  735.                    
  736.                     OppGrid child = new OppGrid(x, y);
  737.                    
  738.                     child.hasVisited = copyHasVisited(parent);
  739.                     child.hasVisited[parent.y,parent.x] = true;
  740.                     if(HadNotBrokenOut)
  741.                         child.minefield = copyMinefield(parent);    
  742.                    
  743.                     if(InGrid(x, y) && grid[y,x].IsNotIsland &&  child.hasVisited[y,x] == false)
  744.                     {
  745.                         count++;
  746.                         child.hasVisited[y,x] = true;
  747.                         valueGrid[y,x]++;
  748.                         output.Add(child);
  749.                         parent = child;
  750.                     }
  751.                     else
  752.                         break;
  753.                 }
  754.                 if(brakeOut)
  755.                     break;
  756.             }
  757.             if(brakeOut)
  758.                 break;
  759.         }
  760.        
  761.         if(brakeOut) //SafetyCheck bigger grid
  762.         {
  763.             output.Clear();
  764.             oppGrid = ResetOppGridOnLocations(oppGrid); //resets paths and multiple locations
  765.             valueGrid = CreateValueGrid(oppGrid);
  766.            
  767.             foreach(OppGrid obj in oppGrid)
  768.             {
  769.                 foreach(Movement dir in moveDict.Values)
  770.                 {
  771.                     int moveX = dir.x;
  772.                     int moveY = dir.y;
  773.                    
  774.                     OppGrid parent = new OppGrid(obj.x, obj.y);
  775.                     parent.hasVisited = copyHasVisited(obj);
  776.                     parent.hasVisited[parent.y,parent.y] = true;
  777.                     for(int i = 0; i < 4; i++)
  778.                     {
  779.                         int x = parent.x+moveX;
  780.                         int y = parent.y+moveY;
  781.                        
  782.                         OppGrid child = new OppGrid(x, y);
  783.                        
  784.                         parent.hasVisited = copyHasVisited(parent);
  785.                         parent.hasVisited[parent.y,parent.x] = true;
  786.                        
  787.                         if(InGrid(x, y) && grid[y,x].IsNotIsland && valueGrid[x,y] == 0)
  788.                         {
  789.                             child.hasVisited[y,x] = true;
  790.                             valueGrid[y,x]++;
  791.                             output.Add(child);
  792.                             parent = child;
  793.                         }
  794.                         else
  795.                             break;
  796.                     }
  797.  
  798.                 }
  799.  
  800.             }
  801.         }
  802.  
  803.         output.AddRange(oppGrid);
  804.         Console.Error.WriteLine($"Locations post Silence: {output.Count()}");
  805.  
  806.         time.Stop();
  807.         Console.Error.WriteLine($"Time for UPDATING SILENCE:{time.ElapsedMilliseconds}");
  808.         return output;
  809.     }
  810.    
  811.     //NOTE Update Torpedo plausible for to be sure that torpedo has been shot
  812.     public static List<OppGrid> UpdateOppGridOnSonar(List<OppGrid> oppGrid, int sector, string sonarResult, Grid[,] grid)
  813.     {
  814.         List<OppGrid> output = new List<OppGrid>();
  815.         sector--;
  816.         int sectorY = ((sector / 3) * 5) + 2;
  817.         int sectorX = ((sector % 3) * 5) + 2;
  818.        
  819.         Console.Error.WriteLine($"Sonar results are:{sonarResult}");
  820.             Console.Error.WriteLine($"SecX: {sectorX} SecY: {sectorY} on sector {sector}");
  821.         if(sonarResult == "N")
  822.         {
  823.             Console.Error.WriteLine($"OPP IS NOT IN SEARCHED SECTOR");
  824.             foreach(var i in oppGrid)  
  825.             {
  826.                 int movedX = Math.Abs(i.x - sectorX);
  827.                 int movedY = Math.Abs(i.y - sectorY);
  828.                 if(movedX > 2 || movedY > 2)
  829.                     output.Add(i);
  830.             }  
  831.         }
  832.        
  833.         else if (sonarResult == "Y")
  834.         {
  835.             Console.Error.WriteLine($"OPP IS IN THE SEARCHED SECTOR");
  836.             foreach(var i in oppGrid)
  837.             {
  838.                 int movedX = Math.Abs(i.x - sectorX);
  839.                 int movedY = Math.Abs(i.y - sectorY);
  840.                 if(movedX <= 2 && movedY <= 2)
  841.                     output.Add(i);
  842.             }  
  843.         }
  844.         else
  845.             output = oppGrid;
  846.        
  847.         Console.Error.WriteLine($"SONAR: oppGrid:{oppGrid.Count()} output:{output.Count()}");
  848.        
  849.         return output;
  850.     }
  851.     public static List<OppGrid> UpdateOppGridOnHit(List<OppGrid> oppGrid, Location torpedo, Location mine)
  852.     {
  853.         List<OppGrid> output = new List<OppGrid>();
  854.         foreach(var i in oppGrid)
  855.         {
  856.  
  857.                 int movedX = Math.Abs(torpedo.x - i.x);
  858.                 int movedY = Math.Abs(torpedo.y - i.y);
  859.                 int movedMineX = Math.Abs(mine.x - i.x);
  860.                 int movedMineY = Math.Abs(mine.y - i.y);
  861.                 if((torpedo.x != -1 && movedX <= 1 && movedY <=1 && movedX+movedY > 0) || (mine.x != -1 && movedMineX <= 1 && movedMineY <=1 && movedMineX+movedMineY > 0))
  862.                     output.Add(i);
  863.  
  864.         }
  865.         return output;
  866.     }
  867.    
  868.     public static List<OppGrid> UpdateOppGridOnBullseye(List<OppGrid> oppGrid,Location target, Location lastMineTrigger)
  869.     {
  870.        List<OppGrid> output = new List<OppGrid>();
  871.        
  872.        foreach(OppGrid i in oppGrid)
  873.        {
  874.             if((target.x != -1 && i.x == target.x && i.y == target.y) || (lastMineTrigger.x != -1 && i.x == lastMineTrigger.x && i.y == lastMineTrigger.y))
  875.                 output.Add(i);
  876.        }
  877.        
  878.        return output;
  879.  
  880.     }
  881.    
  882.     public static List<OppGrid> UpdateGridOnTorpedoMissed(List<OppGrid> oppGrid, Location torpedoTarget, Location mine)
  883.     {
  884.         List<OppGrid> output = new List<OppGrid>();
  885.         foreach(OppGrid i in oppGrid)
  886.         {
  887.             int distanceX = Math.Abs(i.x - torpedoTarget.x);
  888.             int distanceY = Math.Abs(i.y - torpedoTarget.y);
  889.            
  890.             int distanceMineX = Math.Abs(i.x - mine.x);
  891.             int distanceMineY = Math.Abs(i.y - mine.y);
  892.  
  893.             if(( torpedoTarget.x != -1 && (distanceY <= 1 && distanceX <= 1) == false) || ( mine.x != -1 && (distanceMineY <= 1 && distanceMineX <= 1) == false)) //Torpedo AOE not in range;
  894.                 output.Add(i);
  895.         }
  896.         return output;
  897.     }
  898.    
  899.     public static List<OppGrid> UpdateOppGridOnMove(List<OppGrid> oppGrid, Grid[,] grid, string move, Dictionary<string, Movement> moveDict, bool hadNotToBrakeOut)
  900.     {
  901.         List<OppGrid> output = new List<OppGrid>();
  902.         int x = moveDict[move].x;
  903.         int y = moveDict[move].y;
  904.         foreach(var i in oppGrid)
  905.         {
  906.             if(InGrid(x+i.x,y+i.y) && grid[i.y+y,i.x+x].IsNotIsland && i.hasVisited[i.y+y,i.x+x] == false)
  907.             {
  908.                 OppGrid iClone = i;
  909.                 iClone.y +=y;
  910.                 iClone.x +=x;
  911.                 iClone.hasVisited = copyHasVisited(i);
  912.                 iClone.hasVisited[iClone.y,iClone.x] = true;
  913.                 if(hadNotToBrakeOut)
  914.                     iClone.minefield = copyMinefield(i);
  915.                
  916.                 output.Add(iClone);
  917.             }
  918.         }
  919.        
  920.         return output;
  921.     }
  922.    
  923.     public static List<OppGrid> UpdateOppGridOnTorpedoFire(List<OppGrid> oppGrid, Grid[,] grid, Location torpedo) //Update
  924.     {
  925.         List<OppGrid> output = new List<OppGrid>();
  926.         int[,] distanceGrid = DistanceFill(grid,torpedo.x,torpedo.y,5);
  927.         foreach(var i in oppGrid)
  928.         {
  929.             if(distanceGrid[i.y,i.x] > 0)
  930.                 output.Add(i);
  931.         }
  932.         return output;
  933.     }
  934.    
  935.     public static List<OppGrid> UpdateOppGridOnSurface(List<OppGrid> oppGrid, Grid[,] grid, int sector)
  936.     {
  937.         var time = new Stopwatch();
  938.         time.Start();
  939.        
  940.         oppGrid = ResetOppGridOnLocations(oppGrid);
  941.        
  942.         List<OppGrid> output = new List<OppGrid>();
  943.         sector -= 1;
  944.         int sectorY = ((sector / 3) * 5)+2; //Corner cordinates of Sector
  945.         int sectorX = ((sector % 3) * 5)+2;
  946.         int sizeOfOutput = 0;
  947.        
  948.         foreach(OppGrid i in oppGrid)
  949.         {
  950.             int movedX = sectorX - i.x;
  951.             int movedY = sectorY - i.y;
  952.             if(movedX <= 2 && movedY <= 2)
  953.             {
  954.                 OppGrid clone = new OppGrid(i.x,i.y);
  955.                 clone.minefield = copyMinefield(i);
  956.                 output.Add(clone); //REsets has visited
  957.                
  958.             }
  959.         }
  960.        
  961.         time.Stop();
  962.         Console.Error.WriteLine($"Time for UPDATING OPPGRID AFTER SURFACE {time.ElapsedMilliseconds}");
  963.         return output;
  964.        
  965.     }
  966.    
  967.     //--------------------------------------------------------------------------------------------------------------------------------------
  968.     //TORPEDO FIRE
  969.     public static Location FireTorpedo(List<OppGrid> oppGrid,Grid[,] grid, int totalValue,int x, int y, ref string currTurn) //X, Y - my location on grid
  970.     {
  971.         var timeCheckAfterFiring = new Stopwatch();
  972.         timeCheckAfterFiring.Start();
  973.         oppGrid = ResetOppGridOnLocations(oppGrid);
  974.         totalValue = oppGrid.Count();
  975.         int [,] valueGrid = CreateValueGrid(oppGrid);
  976.        
  977.         int[,] distanceGrid = DistanceFill(grid, x, y, 5);
  978.        
  979.         Location target = new Location(-1,-1);
  980.        
  981.         int value = 0;
  982.         foreach(OppGrid obj in oppGrid)
  983.         {  
  984.             int movedX = Math.Abs(obj.x-x);
  985.             int movedY = Math.Abs(obj.y-y);
  986.             if( distanceGrid[obj.y,obj.x] > 0 && (movedX >= 2 || movedY >= 2))
  987.             {
  988.                     int corX = obj.x-1;
  989.                     int corY = obj.y-1;
  990.                     int tempValue = 0;
  991.                     for(int i = 0; i < 3; i++)
  992.                         for(int l = 0; l < 3; l++)
  993.                             {
  994.                                 if(InGrid(corX+i,corY+l))
  995.                                     tempValue+=valueGrid[corY+l,corX+i];
  996.                             }
  997.                     if(tempValue >= totalValue / 2)
  998.                     {
  999.                         target = new Location(obj.x,obj.y);
  1000.                         currTurn += String.Format($"TORPEDO {obj.x} {obj.y} |");
  1001.                         return target;
  1002.                     }
  1003.             }
  1004.  
  1005.         }
  1006.        
  1007.         if(target.x == -1)//For when the enemy prediction is a square/Oval
  1008.         {
  1009.             Console.Error.WriteLine("Searching for oval Oval Torpedo Range");
  1010.             for(int Y = 0; Y < 15; Y++)
  1011.                 for(int X = 0; X < 15; X++)
  1012.                 {  
  1013.                     if(InGrid(Y,X))
  1014.                     {
  1015.                         Location obj = new Location(X,Y);
  1016.                         int movedX = Math.Abs(obj.x-x);
  1017.                         int movedY = Math.Abs(obj.y-y);
  1018.                         if( distanceGrid[obj.y,obj.x] > 0 && (movedX >= 2 || movedY >= 2))
  1019.                         {
  1020.                                 int corX = obj.x-1;
  1021.                                 int corY = obj.y-1;
  1022.                                 int tempValue = 0;
  1023.                                 for(int i = 0; i < 3; i++)
  1024.                                     for(int l = 0; l < 3; l++)
  1025.                                         {
  1026.                                             if(InGrid(corX+i,corY+l))
  1027.                                                 tempValue+=valueGrid[corY+l,corX+i];
  1028.                                         }
  1029.                                 if(tempValue >= totalValue)
  1030.                                 {
  1031.                                     target = new Location(obj.x,obj.y);
  1032.                                     currTurn += String.Format($"TORPEDO {obj.x} {obj.y} |");
  1033.                                     return target;
  1034.                                 }
  1035.                         }
  1036.                     }
  1037.        
  1038.                 }
  1039.         }
  1040.        
  1041.         timeCheckAfterFiring.Stop();
  1042.         Console.Error.WriteLine($"Time for TAKING TORPEDO FIRE:{timeCheckAfterFiring.ElapsedMilliseconds}");
  1043.         return target;
  1044.     }
  1045.     //--------------------------------------------------------------------------------------------------------------------------------------
  1046.     //Submarine movement
  1047.    
  1048.    
  1049.     public static int closestEnemyDistance(int x, int y, List<OppGrid> oppGrid)
  1050.     {
  1051.         int output = int.MaxValue;
  1052.         foreach(OppGrid i in oppGrid)
  1053.         {
  1054.             int distance = Math.Abs(i.x - x) + Math.Abs(i.y-y);
  1055.                 if (distance < output)
  1056.                     output = distance;
  1057.         }
  1058.         return output;
  1059.     }
  1060.     public static int closestLocationDistance(int x, int y, List<Location> locations)
  1061.     {
  1062.         int output = int.MaxValue;
  1063.         foreach(Location i in locations)
  1064.         {
  1065.             int distance = Math.Abs(i.x - x) + Math.Abs(i.y-y);
  1066.                 if (distance < output)
  1067.                     output = distance;
  1068.         }
  1069.         return output;
  1070.     }
  1071.    
  1072.     public static string GetMove(Grid[,] grid, List<OppGrid> oppGrid, List<Location> mines,  int x, int y, List<Movement> moveList, Dictionary<string, Movement> moveDict, ref int value, int torpedoCooldown)
  1073.     {
  1074.         var time = new Stopwatch();
  1075.         time.Start();
  1076.        
  1077.         string output;
  1078.         value = 0;
  1079.         output = "";
  1080.  
  1081.         List<string> directions = new List<string>();
  1082.        
  1083.        
  1084.         if( torpedoCooldown == 0 && ResetOppGridOnLocations(oppGrid).Count() <= 2  && ResetOppGridOnLocations(oppGrid).Count() > 0)
  1085.         {
  1086.             foreach(var direction in moveList)
  1087.             {
  1088.                 int tempX = x + direction.x;
  1089.                 int tempY = y + direction.y;
  1090.                 var gridClone = MakeADeepGridCopy(grid);
  1091.                
  1092.                 int tempValue = FloodFill(gridClone,tempX,tempY,moveList);
  1093.                
  1094.                 int valueZone = 15;
  1095.                
  1096.                 if(tempValue == value && tempValue > 0)
  1097.                     directions.Add(direction.direction);
  1098.                 else if(tempValue >=  valueZone && value >= valueZone)
  1099.                 {
  1100.                     directions.Clear();
  1101.                     directions.Add(direction.direction);
  1102.                     value = tempValue;
  1103.                 }
  1104.                 else if(value < valueZone && tempValue > value)
  1105.                 {
  1106.                     value = tempValue;
  1107.                     directions.Clear();
  1108.                     directions.Add(direction.direction);
  1109.                 }
  1110.             }
  1111.            
  1112.             List<string> runToKill = new List<string>(); //RunAway
  1113.             if(directions.Any())
  1114.             {
  1115.                 int distanceValue = int.MaxValue;
  1116.                 foreach(string i in directions)
  1117.                 {
  1118.                     Movement dir = moveDict[i];
  1119.                     int tempDistance = closestEnemyDistance(x+dir.x, y+dir.y, oppGrid);
  1120.                     if(tempDistance < distanceValue)
  1121.                     {
  1122.                         distanceValue = tempDistance;
  1123.                         runToKill.Clear();
  1124.                         runToKill.Add(i);
  1125.                     }
  1126.                     else if(tempDistance == distanceValue)
  1127.                         runToKill.Add(i);
  1128.                    
  1129.                 }
  1130.                
  1131.                 if(runToKill.Any())
  1132.                     output = runToKill[0];
  1133.                 else
  1134.                     output = "";
  1135.             }
  1136.             else
  1137.                 output = "";
  1138.         }
  1139.        
  1140.         else
  1141.         {
  1142.  
  1143.             foreach(var direction in moveList)
  1144.             {
  1145.                 int tempX = x + direction.x;
  1146.                 int tempY = y + direction.y;
  1147.                 var gridClone = MakeADeepGridCopy(grid);
  1148.                
  1149.                 int tempValue = FloodFill(gridClone,tempX,tempY,moveList);
  1150.                
  1151.                 if(tempValue == value && tempValue > 0)
  1152.                     directions.Add(direction.direction);
  1153.                 else if(tempValue > value)
  1154.                 {
  1155.                     directions.Clear();
  1156.                     directions.Add(direction.direction);
  1157.                     value = tempValue;
  1158.                 }
  1159.             }
  1160.            
  1161.             List<string> runAwayDir = new List<string>(); //RunAway
  1162.             if(directions.Any())
  1163.             {
  1164.                 int distanceValue = int.MinValue;
  1165.                 foreach(string i in directions)
  1166.                 {
  1167.                     Movement dir = moveDict[i];
  1168.                     int tempDistance = closestEnemyDistance(x+dir.x, y+dir.y, oppGrid);
  1169.                     if(tempDistance > distanceValue)
  1170.                     {
  1171.                         distanceValue = tempDistance;
  1172.                         runAwayDir.Clear();
  1173.                         runAwayDir.Add(i);
  1174.                     }
  1175.                     else if(tempDistance == distanceValue)
  1176.                         runAwayDir.Add(i);
  1177.                    
  1178.                 }
  1179.                 output = runAwayDir[0];
  1180.             }
  1181.             else
  1182.                 output = "";
  1183.                
  1184.             if(runAwayDir.Any()) //RunToMines
  1185.             {
  1186.                 int distanceValue = int.MaxValue;
  1187.                 foreach(string i in runAwayDir)
  1188.                 {
  1189.                     Movement dir = moveDict[i];
  1190.                     int tempDistance = closestLocationDistance(x+dir.x, y+dir.y, mines);
  1191.                     if(tempDistance < distanceValue)
  1192.                     {
  1193.                         distanceValue = tempDistance;
  1194.                         output = i;
  1195.                     }
  1196.                    
  1197.                 }
  1198.             }
  1199.             else
  1200.                 output = "";
  1201.         }
  1202.        
  1203.            
  1204.            
  1205.         Console.Error.WriteLine($"In positiox x:{x} y:{y} there are {directions.Count()} paths with the same value");
  1206.        
  1207.         time.Stop();
  1208.         Console.Error.WriteLine($"Time for FINDING MOVE:{time.ElapsedMilliseconds}");
  1209.        
  1210.         return output;
  1211.     }
  1212.    
  1213.     //FloodFill algorithm
  1214.     public static int FloodFill(Grid[,] grid, int x, int y, List<Movement> moveList)
  1215.     {
  1216.         int value = 0;
  1217.         if(InGrid(x,y) == false || grid[y,x].CanBeSwimmed == false)
  1218.             return 0;
  1219.            
  1220.         OppGrid location = new OppGrid();
  1221.         location.x = x;
  1222.         location.y = y;
  1223.        
  1224.         LinkedList<OppGrid> myList = new LinkedList<OppGrid>();
  1225.         myList.AddLast(location);
  1226.         grid[location.y,location.x].CanBeSwimmed = false;
  1227.        
  1228.         while(myList.Any())
  1229.         {
  1230.             OppGrid bigTemp = (OppGrid)myList.First.Value;
  1231.             myList.RemoveFirst();
  1232.  
  1233.             foreach(var direction in moveList)
  1234.             {
  1235.                 OppGrid temp = new OppGrid();
  1236.                 temp.x = bigTemp.x;
  1237.                 temp.y = bigTemp.y;
  1238.                
  1239.                 temp.x += direction.x;
  1240.                 temp.y += direction.y;
  1241.                 if(InGrid(temp.x,temp.y) && grid[temp.y,temp.x].CanBeSwimmed)
  1242.                 {
  1243.                     myList.AddLast(temp);
  1244.                     value++;
  1245.                     grid[temp.y,temp.x].CanBeSwimmed = false;
  1246.                 }
  1247.             }
  1248.         }
  1249.        
  1250.         return value;
  1251.     }
  1252.         //--------------------------------------------------------------------------------------------------------------------------------------
  1253.     public static int CalculateOppGridCount(List<OppGrid> oppGrid)
  1254.     {
  1255.         int output = 0;
  1256.         foreach(var i in oppGrid)
  1257.                 output++;
  1258.                
  1259.         return output;
  1260.     }
  1261.     //--------------------------------------------------------------------------------------------------------------------------------------
  1262.     public static OppGrid FindTorpedoTarget(int x,int y, List<OppGrid> oppGrid, Grid[,] grid)
  1263.     {
  1264.             foreach(OppGrid i in oppGrid)
  1265.             {
  1266.                 int movedY = Math.Abs(y-i.y);
  1267.                 int movedX = Math.Abs(x-i.x);
  1268.                 int distance = movedX + movedY;
  1269.                 if(distance == 4 || distance == 3)
  1270.                 {  
  1271.                     Console.Error.WriteLine($"\nTorpedo Target range x:{movedX} y:{movedY}");
  1272.                     Console.Error.WriteLine($"Torpedo target x:{i.x} y:{i.y}\n");
  1273.                     return i;
  1274.                 }
  1275.                    
  1276.             }
  1277.             OppGrid noFoundOutput = new OppGrid();
  1278.             noFoundOutput.x = -1;
  1279.             return noFoundOutput;
  1280.     }
  1281.     //--------------------------------------------------------------------------------------------------------------------------------------
  1282.    
  1283.     public static void OppGridVisitedLocationsTyped(OppGrid i)
  1284.     {
  1285.         for (int y = 0; y < 15; y++)
  1286.         {
  1287.             for(int x = 0; x < 15; x++)
  1288.             {
  1289.                 if(i.hasVisited[y,x])
  1290.                     Console.Error.Write(" -");
  1291.                 else
  1292.                     Console.Error.Write(" +");
  1293.             }
  1294.             Console.Error.WriteLine();
  1295.         }
  1296.     }
  1297.    
  1298.     //decides what item to reload--------------------------------------------------------------------------------------------------------------
  1299.     public static string GetItem(ref int torpedoCooldown, ref int silenceCooldown, ref int sonarCooldown, ref int mineCooldown)
  1300.     {
  1301.         string item = "SILENCE";
  1302.         if(torpedoCooldown > 0)
  1303.         {
  1304.             item = "TORPEDO";
  1305.             torpedoCooldown--;
  1306.         }
  1307.         else if (silenceCooldown > 0)
  1308.         {
  1309.             item = "SILENCE";
  1310.             silenceCooldown--;
  1311.         }
  1312.         else if(mineCooldown > 0)
  1313.         {
  1314.             item = "MINE";
  1315.             mineCooldown--;
  1316.         }
  1317.         else if(sonarCooldown > 0)
  1318.         {
  1319.             item = "SONAR";
  1320.             sonarCooldown--;
  1321.         }
  1322.         return item;
  1323.     }
  1324.     //--------------------------------------------------------------------------------------------------------------------------------
  1325.     //Spawns a submarine
  1326.     public static void SpawnSubmarine(Grid[,] grid, List<Movement> movementList)
  1327.     {
  1328.         List<Location> spawns = new List<Location>();
  1329.         int value = 0;
  1330.         for(int x = 0; x < 15; x++)
  1331.             for(int y = 14; y >= 0;y--)
  1332.             {
  1333.                 if(InGrid(x,y) && grid[y,x].CanBeSwimmed)
  1334.                 {
  1335.                     var gridClone = MakeADeepGridCopy(grid);
  1336.                     gridClone[y,x].CanBeSwimmed = false;
  1337.                    
  1338.                     foreach(Movement mov in movementList)
  1339.                     {
  1340.                         int tempX = x + mov.x;
  1341.                         int tempY = y + mov.y;
  1342.                         if(InGrid(tempX,tempY) && grid[tempY,tempX].CanBeSwimmed)
  1343.                         {
  1344.                             int tempValue = FloodFill(gridClone, tempX, tempY, movementList);
  1345.                             if(tempValue == value)
  1346.                                 spawns.Add(new Location(x,y));
  1347.                             else if (tempValue > value)
  1348.                             {
  1349.                                 value = tempValue;
  1350.                                 spawns.Clear();
  1351.                                 spawns.Add(new Location(x,y));
  1352.                             }
  1353.                         }
  1354.                     }
  1355.                 }
  1356.             }
  1357.         spawns.Count();
  1358.         int[] sectors = new int[9];
  1359.         List<List<Location>> optimalSpawns  = new List<List<Location>>();
  1360.         for(int i = 0; i < 9; i++)
  1361.             optimalSpawns.Add(new List<Location>());
  1362.        
  1363.         foreach(var i in spawns)
  1364.         {
  1365.             int sectr = CalculateSectorFromCordinates(i.x,i.y)-1;
  1366.             sectors[sectr]++; //Calculates value
  1367.             optimalSpawns[sectr].Add(i);
  1368.         }
  1369.         int spawnSector = 5;
  1370.         int spawnValue = 0;
  1371.         for(int i = 0; i < 9; i++) //Most valuable sector
  1372.             if(sectors[i] > spawnValue)
  1373.             {
  1374.                 spawnSector = i;
  1375.                 spawnValue = sectors[i];
  1376.             }
  1377.         List<Location> spawnList =  optimalSpawns[spawnSector];
  1378.         int mySpawnIndex = spawnList.Count()  / 2;
  1379.         Location mySpawn = spawnList[mySpawnIndex];
  1380.        
  1381.         Console.Error.WriteLine($"There are {spawns.Count()} With the same value of {value}");
  1382.         Console.WriteLine($"{mySpawn.x} {mySpawn.y}");
  1383.     }
  1384.     //--------------------------------------------------------------------------------------------------------------
  1385.     //Finds where to deploy sonar
  1386.     public static void DeploySonar(List<OppGrid> oppGrid, ref string currTurn, ref int sonarLoc, bool hasUsedSilence)
  1387.     {
  1388.        
  1389.         //Initiate sector values for calculation
  1390.         int[] sectors = new int[9];
  1391.         for(int i = 0; i < sectors.Length; i++)
  1392.             sectors[i] = 0;
  1393.            
  1394.         foreach(var i in oppGrid) //Calculates the value where to deploy the sonar
  1395.                 sectors[CalculateSectorFromCordinates(i.x,i.y)-1]++;
  1396.        
  1397.         int value = 0;
  1398.         int output = 0;
  1399.        
  1400.         for(int i = 0; i < sectors.Length; i++)
  1401.             if(sectors[i] > value) //Finds the best LOCATION
  1402.             {
  1403.                  value = sectors[i];
  1404.                  output = i;
  1405.             }
  1406.            
  1407.         output++;
  1408.        
  1409.         if(oppGrid.Count() > value && (hasUsedSilence || oppGrid.Count() > 1000 || value > 500)) //Checks if I even get anything from sonar
  1410.         {
  1411.             currTurn += String.Format($"SONAR {output} |");
  1412.             sonarLoc = output;
  1413.         }
  1414.        
  1415.     }
  1416.    
  1417.     public static bool IfHeFoundMe(int x, int y, Location enemyTorpedo)
  1418.     {
  1419.         if(enemyTorpedo.x != -1)
  1420.             if(Math.Abs(x-enemyTorpedo.x) <= 1 && Math.Abs(y-enemyTorpedo.y) <= 1)
  1421.                 return true;
  1422.             return false;
  1423.     }
  1424.    
  1425.     //--------------------------------------------------------------------------------------------------------------
  1426.     public static void DeploySilence(List<OppGrid> oppGrid, ref List<OppGrid> myOppGrid, ref Grid[,] grid, ref string currTurn, ref int x, ref int y, string map,
  1427.     List<Location> mines, Location enemyTorpedo, Location enemyMine, int myLife, int sonarCoolDown, int mineCooldown, int torpedoCooldown, ref Location lastTorpedo, ref int silenceCooldown)
  1428.     {
  1429.         Dictionary<string,Movement> moveDict = InitializeMovementDictionary();
  1430.         int value = 0;
  1431.         string move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
  1432.        
  1433.        
  1434.         Random rng = new Random();
  1435.         List<OppGrid> attackGrid = ResetOppGridOnLocations(oppGrid);
  1436.         Location toFireTorepdoLocation = new Location(-1,-1);
  1437.         if(attackGrid.Count() > 0 && attackGrid.Count() < 3 && lastTorpedo.x != -1) //Dash to kill
  1438.         {
  1439.             bool brakeOut = false;
  1440.             List<Grid> possibleDashLocations = new List<Grid>();
  1441.             string tempTurn = "";
  1442.             foreach(var dir in moveDict.Values)
  1443.             {
  1444.                 Grid[,] parent = MakeADeepGridCopy(grid);
  1445.                 for(int i = 1; i <= 4; i++)
  1446.                 {
  1447.                     tempTurn = "";
  1448.                     int tempX = x+dir.x;
  1449.                     int tempY = y+dir.y;
  1450.                     if(InGrid(tempX,tempY) && parent[tempY,tempX].CanBeSwimmed)
  1451.                     {
  1452.                         Grid[,] child = parent; //passes on the grid
  1453.                         child[tempY,tempX].CanBeSwimmed = false;
  1454.                        
  1455.                         toFireTorepdoLocation = FireTorpedo(attackGrid, child, oppGrid.Count(), x, y, ref tempTurn);
  1456.                         if(toFireTorepdoLocation.x != -1)
  1457.                         {
  1458.                             lastTorpedo = toFireTorepdoLocation;
  1459.                             brakeOut = true;
  1460.                             currTurn += String.Format("SILENCE {dir.direction} {i}| {tempTurn}"); //Outputs a move
  1461.                             grid = child;
  1462.                             x = tempX;
  1463.                             y = tempY;
  1464.                            
  1465.                             break;
  1466.                         }
  1467.                     }
  1468.                 }
  1469.                 if(brakeOut)
  1470.                     break;
  1471.             }
  1472.         }
  1473.        
  1474.         else if((IfHeFoundMe(x,y,enemyTorpedo) || IfHeFoundMe(x,y,enemyMine) || lastTorpedo.x != -1) && myLife > 1) //RunAway
  1475.         {
  1476.             Console.Error.WriteLine($"My move is {move}");
  1477.             move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
  1478.             if(myLife > 1 && value < 25)
  1479.             {
  1480.                 currTurn+= String.Format($"SURFACE |");
  1481.                 grid = CreateGrid(map, 15,15, x, y);
  1482.                 move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
  1483.             }
  1484.            
  1485.             Console.Error.WriteLine($"My move is {move}");
  1486.             int i = 0;
  1487.             for(i = 0; i < 4; i++)
  1488.             {
  1489.                 int tempX = x + moveDict[move].x;
  1490.                 int tempY = y + moveDict[move].y;
  1491.                 if(InGrid(tempY,tempX) && grid[tempY,tempX].CanBeSwimmed)
  1492.                 {
  1493.                     grid[y,x].CanBeSwimmed = false;
  1494.                     x = tempX;
  1495.                     y = tempY;
  1496.                 }
  1497.                 else
  1498.                     break;
  1499.             }
  1500.            
  1501.             currTurn+= String.Format($"SILENCE {move} {i} |");
  1502.             silenceCooldown = -1;
  1503.         }
  1504.         else if(sonarCoolDown == 0 && mineCooldown == 0 && torpedoCooldown == 0) //Spam
  1505.         {
  1506.             if(value < 4 || move == "")
  1507.             {
  1508.                
  1509.                 if(myLife > 1)
  1510.                 {
  1511.                     currTurn+= String.Format($"SURFACE |");
  1512.                     grid = CreateGrid(map, 15,15, x, y);
  1513.                 }
  1514.                
  1515.                 Console.Error.WriteLine($"My move is {move}");
  1516.                 grid = CreateGrid(map, 15, 15,x,y); //resets my path
  1517.                 move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
  1518.                 Console.Error.WriteLine($"My move is {move}");
  1519.                 currTurn+= String.Format($"SILENCE {move} {rng.Next(0,1)} |");
  1520.                 silenceCooldown = -1;
  1521.             }
  1522.             else
  1523.             {
  1524.                 Console.Error.WriteLine($"My move is {move}");
  1525.                 currTurn+= String.Format($"SILENCE {move} 1 |");
  1526.                 silenceCooldown = -1;
  1527.             }
  1528.             x += moveDict[move].x;
  1529.             y += moveDict[move].y;
  1530.         }
  1531.     }
  1532.    
  1533.     //--------------------------------------------------------------------------------------------------------------
  1534.     //Movement List Functions
  1535.     public static Dictionary<string, Movement> InitializeMovementDictionary()
  1536.     {
  1537.         Dictionary<string, Movement> output = new Dictionary<string, Movement>();  
  1538.         output.Add("N", new Movement(0,-1,"N"));
  1539.         output.Add("E", new Movement(1,0,"E"));
  1540.         output.Add("W", new Movement(-1,0,"W"));
  1541.         output.Add("S", new Movement(0,1,"S"));
  1542.         return output;
  1543.     }
  1544.    
  1545.     public static List<Movement> InitializeMovementList()
  1546.     {
  1547.         List<Movement> output = new List<Movement>();
  1548.         output.Add(new Movement(0,-1,"N"));
  1549.         output.Add(new Movement(1,0,"E"));
  1550.         output.Add(new Movement(0,1,"S"));
  1551.         output.Add(new Movement(-1,0,"W"));
  1552.         return output;
  1553.        
  1554.     }
  1555.    
  1556.     public static List<Movement> UpdateMovementList(string move, bool hasTouchedCorners)
  1557.     {
  1558.         List<Movement> output = new List<Movement>();
  1559.         if(move == "N")
  1560.         {
  1561.             output.Add(new Movement(1,0,"E"));
  1562.             output.Add(new Movement(0,-1,"N"));
  1563.             output.Add(new Movement(0,1,"S"));
  1564.             output.Add(new Movement(-1,0,"W"));
  1565.         }
  1566.         else if(move == "E")
  1567.         {
  1568.             output.Add(new Movement(0,1,"S"));
  1569.             output.Add(new Movement(1,0,"E"));
  1570.             output.Add(new Movement(-1,0,"W"));
  1571.             output.Add(new Movement(0,-1,"N"));
  1572.         }
  1573.         else if(move == "S")
  1574.         {
  1575.             output.Add(new Movement(-1,0,"W"));
  1576.             output.Add(new Movement(0,1,"S"));
  1577.             output.Add(new Movement(0,-1,"N"));
  1578.             output.Add(new Movement(1,0,"E"));
  1579.         }
  1580.         else if (move == "W")
  1581.         {
  1582.             output.Add(new Movement(0,-1,"N"));
  1583.             output.Add(new Movement(-1,0,"W"));
  1584.             output.Add(new Movement(1,0,"E"));
  1585.             output.Add(new Movement(0,1,"S"));
  1586.            
  1587.         }
  1588.         else
  1589.             output = InitializeMovementList();
  1590.         if(hasTouchedCorners)
  1591.             output.Reverse();//Remove this in case
  1592.         return output;
  1593.     }
  1594. }
  1595. /*
  1596.         List<Location> possibleLocationsToGet = new List<Location>();
  1597.         possibleLocationsToGet.Add(new Location(x, y));
  1598.        
  1599.         foreach(Movement mov in moveDict.Values)
  1600.         {
  1601.             Location parent = new Location(x,y); // gets possible positions to dash to.
  1602.             for(int i = 0; i < 4; i++)
  1603.             {
  1604.                 int tempX = parent.x + mov.x;
  1605.                 int tempY = parent.y + mov.y;
  1606.                 if(InGrid(tempX,tempY) && grid[tempY,tempX].CanBeSwimmed)
  1607.                 {
  1608.                     Location child = new Location(tempX,tempY);
  1609.                     parent = child;
  1610.                     possibleLocationsToGet.Add(child);
  1611.                 }
  1612.                 else
  1613.                     break;
  1614.             }
  1615.            
  1616.         }
  1617.        
  1618.         Console.Error.WriteLine($"In position x:{x} y:{y} I can dash to {possibleLocationsToGet.Count()}");
  1619.        
  1620.         */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement