Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Linq;
- using System.IO;
- using System.Text;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Diagnostics;
- /**
- * Auto-generated code below aims at helping you parse
- * the standard input according to the problem statement.
- **/
- class Player
- {
- static void Main(string[] args)
- {
- //Initializes the BOT--------------------------------------------------------------------------------------------------------------------------------------------------
- Dictionary<string, Movement> movementDictionary = InitializeMovementDictionary();
- List<Movement> movementList = InitializeMovementList();
- int prevOppLife = 6;
- int prevMyLife = 6;
- //Inputs
- string map = "";
- string[] inputs;
- inputs = Console.ReadLine().Split(' ');
- int width = int.Parse(inputs[0]);
- int height = int.Parse(inputs[1]);
- int myId = int.Parse(inputs[2]);
- for (int i = 0; i < height; i++)
- {
- string line = Console.ReadLine();
- map += line;
- }
- Grid[,] grid = CreateGrid(map, height, width,0,0);
- //Random spawn postion that is not island----------------------------------------
- SpawnSubmarine(grid,movementList);
- Location lastShotTorpedo = new Location(-1, -1);
- bool lastTurnUsedTorpedo = false;
- int prevSonarSector = -1;
- string move = "";
- string myPrevOppMove = "";
- List<OppGrid> oppGrid = InitializeOppGrid(grid);
- List<OppGrid> myOppGrid = InitializeOppGrid(grid);
- bool hasTouchedCorners = false;
- string prevOppMove = "";
- int silenceUses = 0;
- Location lastMineTrigger = new Location(-1,-1);
- List<Location> mines = new List<Location>();
- int silenceCountDown = 0;
- bool hadNotToBrakeOut = true;
- // -------------------game loop---------------------------------------------------------------------------------------------------------
- while (true)
- {
- string currTurn = "";
- if(oppGrid.Any() == false) //resets grid
- oppGrid = InitializeOppGrid(grid);
- if(myOppGrid.Any() == false) //resets grid
- myOppGrid = InitializeOppGrid(grid);
- //Inputs
- inputs = Console.ReadLine().Split(' ');
- int x = int.Parse(inputs[0]);
- int y = int.Parse(inputs[1]);
- int myLife = int.Parse(inputs[2]);
- int oppLife = int.Parse(inputs[3]);
- int torpedoCooldown = int.Parse(inputs[4]);
- int sonarCooldown = int.Parse(inputs[5]);
- int silenceCooldown = int.Parse(inputs[6]);
- int mineCooldown = int.Parse(inputs[7]);
- string sonarResult = Console.ReadLine();
- string opponentOrders = Console.ReadLine();
- bool oppHasUsedSilence = false;
- Location oppShotTorpedo = new Location(-1,-1);
- grid[y,x].CanBeSwimmed = false;
- bool hasNotExplodedAMine = true;
- bool hasPlacedMine = false;
- silenceCountDown++;
- int moveValue = 0;
- Location oppTriggeredMine = new Location(-1,-1);
- bool hasUsedSilence = false;
- //Updates info after the previous turn
- if(sonarResult != "NA")
- oppGrid = UpdateOppGridOnSonar(oppGrid, prevSonarSector, sonarResult, grid);
- if(lastShotTorpedo.x != -1 || lastMineTrigger.x != -1)
- {
- oppGrid = UpdateGridAfterFiring(oppGrid, lastShotTorpedo, lastMineTrigger, oppLife, prevOppLife, opponentOrders);
- }
- Console.Error.WriteLine($"OPP orders are {opponentOrders}");
- //Reads enemies inputs that I might use
- foreach(var command in opponentOrders.Split('|'))
- {
- var time = new Stopwatch();
- time.Start();
- string[] orders = command.Split(' ');
- if (orders[0] == "TORPEDO")
- {
- oppGrid = UpdateOppGridOnTorpedoFire(oppGrid, grid ,new Location(int.Parse(orders[1]),int.Parse(orders[2])));
- oppShotTorpedo = new Location(int.Parse(orders[1]),int.Parse(orders[2]));
- Console.Error.Write("Has tested for OPP postions post OPP-TORPEDO-FIRE");
- }
- else if(orders[0] == "MOVE")
- {
- oppGrid = UpdateOppGridOnMove(oppGrid, grid, orders[1], movementDictionary, hadNotToBrakeOut);
- Console.Error.Write("Has tested for OPP postions post MOVE");
- prevOppMove = orders[1];
- }
- else if (orders[0] == "SURFACE")
- {
- oppGrid = UpdateOppGridOnSurface(oppGrid, grid, int.Parse(orders[1]));
- Console.Error.Write("Has tested for OPP postions post SURFACE");
- prevOppMove = "";
- }
- else if(orders[0] == "TRIGGER")
- {
- oppTriggeredMine = new Location(int.Parse(orders[1]),int.Parse(orders[2]));
- if(hadNotToBrakeOut)
- oppGrid = UpdateOppGridAfterMineFieldCheck(oppGrid, oppTriggeredMine);
- oppGrid = UpdateOppGridAfterMineTrigger(oppGrid, grid, oppTriggeredMine, oppLife, prevOppLife);
- Console.Error.Write("Has tested for OPP postions post ENEMY-TRIGGER");
- }
- else if (orders[0] == "SILENCE")
- {
- oppGrid = UpdateOppGridOnOppSilence(oppGrid, prevOppMove, grid, ref hadNotToBrakeOut);
- Console.Error.Write("Has tested for OPP postions post SILENCE");
- hasUsedSilence = true;
- }
- else if (orders[0] == "MINE")
- {
- if(hadNotToBrakeOut)
- oppGrid = UpdateOppGridOnMinePlaced(oppGrid);
- Console.Error.Write("Has updated Minefield for OPPs");
- }
- time.Stop();
- Console.Error.WriteLine($" Time:{time.ElapsedMilliseconds}");
- }
- //Decides what to do
- int[,] valueGrid = CreateValueGrid(oppGrid); //Creates a value-grid from the current information
- //int[,] valueGrid = CreateValueGrid(ResetOppGridOnLocations(oppGrid)); //Creates a value-grid from the current information
- int[,] mineLocChecker = MineFill(mines);
- ValueGridTyped(valueGrid);
- if(oppGrid.Any() && hadNotToBrakeOut)
- WriteMinefield(oppGrid[0].minefield);
- lastMineTrigger = new Location(-1,-1); //resets last Triggered Mine
- lastShotTorpedo = new Location(-1,-1); //Resets Torpedo
- //At Start
- RepeatableActionCheck(ref lastShotTorpedo, ref hasPlacedMine, ref lastMineTrigger, oppGrid, grid, ref currTurn, x, y, ref torpedoCooldown, ref mineCooldown, ref mines);
- move = GetMove(grid, oppGrid, mines, x, y, movementList, movementDictionary, ref moveValue, torpedoCooldown); //Decides in what direction to move;
- if(move != "" && (currTurn == "" || lastShotTorpedo.x != -1))
- {
- string item = GetItem(ref torpedoCooldown, ref silenceCooldown, ref sonarCooldown, ref mineCooldown);
- currTurn += String.Format($"MOVE {move} {item} |");
- myPrevOppMove = move;
- x+=movementDictionary[move].x; //Updates my currPostion
- y+=movementDictionary[move].y;
- Console.Error.WriteLine($"My current position after move is x:{x} y:{y}");
- grid[y,x].CanBeSwimmed = false;
- //Post Move
- RepeatableActionCheck(ref lastShotTorpedo, ref hasPlacedMine, ref lastMineTrigger, oppGrid, grid, ref currTurn, x, y, ref torpedoCooldown, ref mineCooldown, ref mines);
- }
- // ------------------------------------------------------------------------------------------------------
- if(silenceCooldown == 0 && silenceCountDown >= 20) //SILENCE --------------------------------------------------------
- DeploySilence(oppGrid, ref myOppGrid, ref grid, ref currTurn, ref x, ref y, map,
- mines, oppShotTorpedo, oppTriggeredMine, myLife, sonarCooldown, mineCooldown, torpedoCooldown, ref lastShotTorpedo, ref silenceCooldown);
- prevSonarSector = -1;
- if(sonarCooldown == 0)
- DeploySonar(oppGrid, ref currTurn, ref prevSonarSector, hasUsedSilence);
- //Post Silence
- if(silenceCooldown == -1)
- RepeatableActionCheck(ref lastShotTorpedo, ref hasPlacedMine, ref lastMineTrigger, oppGrid, grid, ref currTurn, x, y, ref torpedoCooldown, ref mineCooldown, ref mines);
- if(currTurn == "")
- {
- Console.Write("SURFACE |");
- hasTouchedCorners = false;
- grid = CreateGrid(map, height, width,x,y); //resets my path
- }
- //Saves info for next round depending how I left
- Console.WriteLine(currTurn); //Ends Turn
- if(x == 0 || y == 0 || x == 14 || y == 14)
- hasTouchedCorners = !hasTouchedCorners;
- Console.Error.WriteLine($"My Current sector is: {CalculateSectorFromCordinates(x, y)}");
- movementList = UpdateMovementList(move, hasTouchedCorners); //sets priority of movement
- Console.Error.WriteLine($"My Move direcition: {move}");
- prevOppLife = oppLife;
- prevMyLife = myLife;
- }
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- /*------------------------Classes and structs*/
- public struct Movement
- {
- public string direction {get; set;}
- public int x {get; set;}
- public int y {get; set;}
- public Movement(int _x, int _y,string _direction)
- {
- x = _x;
- y = _y;
- direction = _direction;
- }
- }
- public struct Location
- {
- public int x { get; set; }
- public int y { get; set; }
- public Location(int _x, int _y)
- {
- x = _x;
- y = _y;
- }
- }
- public struct OppGrid
- {
- public int x { get; set; }
- public int y { get; set; }
- public bool[,] hasVisited { get; set; }
- public bool[,] minefield { get; set; }
- public OppGrid(int _x, int _y)
- {
- x = _x;
- y = _y;
- hasVisited = new bool[15,15];
- minefield = new bool[15,15];
- }
- }
- public struct Grid
- {
- public bool IsNotIsland {get; set;}
- public bool CanBeSwimmed { get; set; }
- public int x { get; set; }
- public int y { get; set; }
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- /*------------------------Methods */
- //--------------------------------------------------------------------------------------------------------------------------------------
- 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,
- ref int torpedoCooldown, ref int mineCooldown, ref List<Location> mines)
- {
- if(torpedoCooldown == 0 && lastShotTorpedo.x == -1)
- lastShotTorpedo = FireTorpedo(oppGrid, grid, oppGrid.Count(), x, y, ref currTurn);
- if(lastShotTorpedo.x != -1)
- torpedoCooldown = 3;
- if(mineCooldown == 0)
- {
- hasPlacedMine = DeployMine(ref mines, grid, ref currTurn, x, y);
- if(hasPlacedMine)
- mineCooldown = 3;
- }
- if(lastMineTrigger.x == -1)
- {
- lastMineTrigger = TriggerMine(oppGrid, ref mines, ref currTurn, x, y);
- }
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- //--------------------------------------------------------------------------------------------------------------------------------------
- //MINES
- public static Location TriggerMine(List<OppGrid> oppGrid, ref List<Location> mines, ref string currTurn, int x, int y) //KILLER QUEEN FIRST BOMB!
- {
- var timeCheckAfterFiring = new Stopwatch();
- timeCheckAfterFiring.Start();
- oppGrid = ResetOppGridOnLocations(oppGrid);
- int[,] valueGrid = CreateValueGrid(oppGrid);
- Location target = new Location(-1,-1);
- int currValue = 0;
- foreach(Location loc in mines)
- {
- int movedX = Math.Abs(loc.x-x);
- int movedY = Math.Abs(loc.y-y);
- if(movedY > 1 || movedX > 1) // Does not hit me
- {
- int corX = loc.x-1;
- int corY = loc.y-1;
- int tempValue = 0;
- for(int i = 0; i < 3; i++) //Calculates the value of this trigger
- for(int l = 0; l < 3; l++)
- {
- if(InGrid(corX+i,corY+l))
- tempValue+=valueGrid[corY+l,corX+i];
- }
- if(tempValue > currValue)
- {
- currValue = tempValue;
- target = new Location(loc.x,loc.y);
- }
- }
- }
- timeCheckAfterFiring.Stop();
- Console.Error.WriteLine($"Time for TRIGGERING A MINE:{timeCheckAfterFiring.ElapsedMilliseconds}");
- int dev;
- if(mines.Count >= 10)
- dev = 4;
- else if(mines.Count >= 7)
- dev = 3;
- else
- dev = 2;
- if(currValue >= oppGrid.Count() / dev && target.x != -1) //checks if it's worth it to detonate
- {
- currTurn += String.Format($"TRIGGER {target.x} {target.y} | MSG KILLER'S QUEEN THIRD BOMB! | ");
- List<Location> minesOutput = new List<Location>();
- foreach(var i in mines)
- {
- if(i.x != target.x && i.y != target.y)
- minesOutput.Add(i);
- }
- mines = minesOutput;
- return target;
- }
- return new Location(-1,-1); //No good target
- }
- public static bool DeployMine(ref List<Location> mines, Grid[,] grid, ref string currTurn, int x, int y)
- {
- Dictionary<string, Movement> moveDict = InitializeMovementDictionary();
- int[,] mineLocChecker = MineFill(mines);
- foreach(var i in moveDict.Values)
- {
- int tempX = i.x + x;
- int tempY = i.y + y;
- int mineValueToPlace = mines.Count() / 10;
- if(InGrid(tempX,tempY) && mineLocChecker[tempY, tempX] <= mineValueToPlace && grid[tempY,tempX].IsNotIsland && tempX != 14 && tempX != 0 && tempY != 0 && tempY != 14)
- {
- mines.Add(new Location(tempX,tempY));
- currTurn += String.Format($"MINE {i.direction} |");
- return true;
- break;
- }
- }
- return false;
- }
- public static int[,] MineFill(List<Location> mines)
- {
- int [,] output = new int[15,15];
- foreach(Location mine in mines)
- {
- int corX = mine.x-2;
- int corY = mine.y-2;
- for(int y = 0; y < 5; y++)
- {
- for(int x = 0; x < 5; x++)
- if(InGrid(corY+y,corX+x))
- output[corY+y,corX+x]++;
- }
- //Removes corners
- if(InGrid(corY,corX))
- output[corY,corX]--;
- if(InGrid(corY+4,corX))
- output[corY+4,corX]--;
- if(InGrid(corY,corX+4))
- output[corY,corX+4]--;
- if(InGrid(corY+4,corX+4))
- output[corY+4,corX+4]--;
- output[mine.y,mine.x] += 100;
- }
- return output;
- }
- //-------------------------------------------------
- //GRID functions
- //creates a grid with the island locations, used for initialization and surface-----------------------------------------------------------------------------
- public static List<OppGrid> UpdateOppGridOnMinePlaced(List<OppGrid> oppGrid)
- {
- Dictionary<string,Movement> moveDict = InitializeMovementDictionary();
- Console.Error.WriteLine("Updated OPPs on their possible mine placements");
- foreach(OppGrid obj in oppGrid)
- foreach(var movement in moveDict.Values)
- {
- int x = obj.x+ movement.x;
- int y = obj.y + movement.y;
- if(InGrid(x,y))
- obj.minefield[y,x] = true; //Updates possible mine locations.
- }
- return oppGrid;
- }
- public static int[,] DistanceFill(Grid[,] grid, int x, int y, int maxVal)
- {
- Dictionary<string, Movement> moveDict = InitializeMovementDictionary();
- LinkedList<Location> myList = new LinkedList<Location>();
- myList.AddLast(new Location(x,y));
- int[,] output = new int[15,15];
- output[y,x] = maxVal;
- while(myList.Any())
- {
- Location i = myList.First.Value;
- myList.RemoveFirst();
- if(output[i.y,i.x] > 1)
- {
- foreach(var mov in moveDict.Values)
- {
- int tempX = i.x+mov.x;
- int tempY = i.y+mov.y;
- if(InGrid(tempX, tempY) && grid[tempY,tempX].IsNotIsland)
- {
- if(output[i.y,i.x]-1 > output[tempY,tempX])
- {
- output[tempY,tempX] = output[i.y,i.x] - 1;
- myList.AddLast(new Location(tempX, tempY));
- }
- }
- }
- }
- }
- return output;
- }
- public static Grid[,] CreateGrid(string str, int height, int width,int x, int y)
- {
- Grid[,] output = new Grid[height,width];
- for(int i = 0; i < str.Length; i++)
- {
- bool temp = true;
- if(str[i] == 'x')
- temp = false;
- output[i/width,i%width].CanBeSwimmed = temp; //Islands and swimmed terrain is marked with false, so info can be pasted in a boolean expression
- output[i/width,i%width].IsNotIsland = temp;
- output[i/width,i%width].y = i/width;
- output[i/width,i%width].x = i%width;
- }
- output[y,x].CanBeSwimmed = false;
- return output;
- }
- public static List<OppGrid> InitializeOppGrid(Grid[,] grid)
- {
- List<OppGrid> output = new List<OppGrid>();
- for(int y = 0; y < 15; y++)
- {
- for(int x = 0; x < 15; x++)
- {
- if(grid[y,x].IsNotIsland)
- {
- OppGrid temp = new OppGrid(x,y);
- output.Add(temp);
- }
- }
- }
- Console.Error.WriteLine($"Initialized OppGrid At start, size {output.Count()}");
- return output;
- }
- public static Grid[,] MakeADeepGridCopy(Grid[,] grid)
- {
- Grid[,] output = new Grid[15,15];
- for(int y = 0; y < 15; y++)
- for(int x = 0; x < 15; x++)
- {
- output[y,x].x = grid[y,x].x;
- output[y,x].y = grid[y,x].y;
- output[y,x].CanBeSwimmed = grid[y,x].CanBeSwimmed;
- }
- return output;
- }
- public static bool InGrid(int x, int y) //checks if the object cordinates are in grid.
- {
- return x <= 14 && y <= 14 && x >= 0 && y >= 0;
- }
- public static int[,] CreateValueGrid(List<OppGrid> oppGrid)
- {
- int[,] output = new int[15,15];
- foreach(var i in oppGrid)
- {
- output[i.y,i.x]++;
- }
- return output;
- }
- public static void ValueGridTyped(int[,] grid)
- {
- Console.Error.Write($" ");
- for(int i = 0; i < 15; i++)
- Console.Error.Write($" {i%10}");
- Console.Error.WriteLine("\n--------------------------------");
- for(int y = 0; y < 15; y++)
- {
- Console.Error.Write($"{y%10}|");
- for(int x = 0; x < 15; x++)
- {
- Console.Error.Write($" {grid[y,x]}");
- }
- Console.Error.WriteLine();
- }
- }
- public static int CalculateSectorFromCordinates(int x, int y)
- {
- return 1 + (y / 5) * 3 + x / 5;
- }
- public static List<OppGrid> ResetOppGridOnLocations(List<OppGrid> oppGrid)
- {
- bool[,] locations = new bool[15,15];
- foreach(OppGrid obj in oppGrid)
- locations[obj.y,obj.x] = true;
- List<OppGrid> output = new List<OppGrid>();
- for(int y = 0; y < 15; y++)
- for(int x = 0; x < 15; x++)
- if(locations[y,x])
- output.Add(new OppGrid(x,y));
- return output;
- }
- public static void WriteMinefield(bool[,] minefield)
- {
- for(int i = 0; i < 15; i++)
- {
- for(int l = 0; l < 15; l++)
- {
- if(minefield[i,l])
- Console.Error.Write(" +");
- else
- Console.Error.Write(" -");
- }
- Console.Error.WriteLine();
- }
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- //Grid Update functions to predict enemies----------------------------------------------------------------------------------------------
- public static List<OppGrid> UpdateOppGridAfterMineFieldCheck(List<OppGrid> oppGrid, Location mine)
- {
- Console.Error.WriteLine("\n\nUPDATED oppGRID after mineFieldCheck\n\n");
- List<OppGrid> output = new List<OppGrid>();
- foreach(OppGrid obj in oppGrid)
- {
- if(obj.minefield[mine.y,mine.x])
- {
- obj.minefield[mine.y,mine.x] = false;
- output.Add(obj);
- }
- }
- return output;
- }
- public static int[,] DrawDamageGrid(Location torpedo, Location mine)
- {
- int[,] output = new int[15,15];
- if(torpedo.x != -1) //Draws torpedo
- {
- int x = torpedo.x - 1;
- int y = torpedo.y - 1;
- for(int i = 0; i < 3; i++) //X
- for(int l = 0; l < 3; l++) //Y
- if(InGrid(x+i,y+l))
- output[y+l,x+i]++;
- output[torpedo.y,torpedo.x]++;
- }
- if(mine.x != -1) //Draws Mine
- {
- int x = mine.x - 1;
- int y = mine.y - 1;
- for(int i = 0; i < 3; i++) //X
- for(int l = 0; l < 3; l++) //Y
- if(InGrid(x+i,y+l))
- output[y+l,x+i]++;
- output[mine.y,mine.x]++;
- }
- return output;
- }
- public static bool[,] copyHasVisited(OppGrid obj)
- {
- bool[,] output = new bool[15,15];
- for(int y = 0; y < 15; y++)
- for(int x = 0; x < 15; x++)
- output[y,x] = obj.hasVisited[y,x];
- return output;
- }
- public static bool[,] copyMinefield(OppGrid obj)
- {
- bool[,] output = new bool[15,15];
- for(int y = 0; y < 15; y++)
- for(int x = 0; x < 15; x++)
- output[y,x] = obj.minefield[y,x];
- return output;
- }
- public static List<OppGrid> UpdateOppGridAfterMineTrigger(List<OppGrid> oppGrid, Grid[,] grid, Location triggerLoc, int hpp, int prevHpp)
- {
- if(prevHpp == hpp) //HasNotHitHimself
- {
- int[,] distanceGrid = DistanceFill(grid,triggerLoc.x,triggerLoc.y,2);
- List<OppGrid> output = new List<OppGrid>();
- foreach(OppGrid i in oppGrid)
- {
- if(distanceGrid[i.y,i.x] == 0)
- output.Add(i);
- }
- return output;
- }
- else
- return oppGrid;
- }
- public static List<OppGrid> UpdateGridAfterFiring(List<OppGrid> oppGrid, Location lastShotTorpedo, Location lastMineTrigger, int oppLife, int prevOppLife, string opponentOrders)
- {
- var timeCheckPostMyTorpedoFire = new Stopwatch();
- timeCheckPostMyTorpedoFire.Start();
- List<OppGrid> output = new List<OppGrid>();
- int hpDiff = 0;
- int[,] damageGrid = DrawDamageGrid(lastShotTorpedo,lastMineTrigger);
- if(opponentOrders.Contains("SURFACE")) //Checks if the enemy has not surfaced for safe check;
- hpDiff++;
- Console.Error.WriteLine($"POF:{prevOppLife} OF:{oppLife} HDF:{hpDiff}");
- if(prevOppLife - oppLife > hpDiff)
- {
- hpDiff = prevOppLife - oppLife + hpDiff;
- Console.Error.WriteLine($"hpDiff is:{hpDiff}");
- foreach(var obj in oppGrid)
- if(damageGrid[obj.y,obj.x] == hpDiff)
- output.Add(obj);
- }
- else //Has missed
- {
- output = UpdateGridOnTorpedoMissed(oppGrid,lastShotTorpedo, lastMineTrigger);
- }
- timeCheckPostMyTorpedoFire.Stop();
- Console.Error.WriteLine($"Time After my torpedo fire AFTERCHECK:{timeCheckPostMyTorpedoFire.ElapsedMilliseconds}");
- return output;
- }
- public static List<OppGrid> UpdateOppGridOnOppSilence(List<OppGrid> oppGrid, string prevMove, Grid[,] grid, ref bool HadNotBrokenOut)
- {
- var time = new Stopwatch();
- Dictionary<string, Movement> moveDict = InitializeMovementDictionary();
- moveDict.Remove(prevMove);
- int count = oppGrid.Count();
- bool brakeOut = false;
- List<OppGrid> output = new List<OppGrid>();
- int[,] valueGrid = CreateValueGrid(oppGrid);
- foreach(OppGrid obj in oppGrid) //Main way of checking previous paths.
- {
- foreach(Movement dir in moveDict.Values)
- {
- int moveX = dir.x;
- int moveY = dir.y;
- OppGrid parent = new OppGrid(obj.x, obj.y);
- parent.hasVisited = copyHasVisited(obj);
- if(HadNotBrokenOut)
- parent.minefield = copyMinefield(obj);
- parent.hasVisited[parent.y,parent.y] = true;
- for(int i = 0; i < 4; i++)
- {
- if(count > 9000)
- {
- brakeOut = true;
- HadNotBrokenOut = false;
- Console.Error.WriteLine("\n\n\n\n\nHAD TO BRAKE OUT\n\n\n\n");
- break; //brakes out incase of timeout
- }
- int x = parent.x+moveX;
- int y = parent.y+moveY;
- OppGrid child = new OppGrid(x, y);
- child.hasVisited = copyHasVisited(parent);
- child.hasVisited[parent.y,parent.x] = true;
- if(HadNotBrokenOut)
- child.minefield = copyMinefield(parent);
- if(InGrid(x, y) && grid[y,x].IsNotIsland && child.hasVisited[y,x] == false)
- {
- count++;
- child.hasVisited[y,x] = true;
- valueGrid[y,x]++;
- output.Add(child);
- parent = child;
- }
- else
- break;
- }
- if(brakeOut)
- break;
- }
- if(brakeOut)
- break;
- }
- if(brakeOut) //SafetyCheck bigger grid
- {
- output.Clear();
- oppGrid = ResetOppGridOnLocations(oppGrid); //resets paths and multiple locations
- valueGrid = CreateValueGrid(oppGrid);
- foreach(OppGrid obj in oppGrid)
- {
- foreach(Movement dir in moveDict.Values)
- {
- int moveX = dir.x;
- int moveY = dir.y;
- OppGrid parent = new OppGrid(obj.x, obj.y);
- parent.hasVisited = copyHasVisited(obj);
- parent.hasVisited[parent.y,parent.y] = true;
- for(int i = 0; i < 4; i++)
- {
- int x = parent.x+moveX;
- int y = parent.y+moveY;
- OppGrid child = new OppGrid(x, y);
- parent.hasVisited = copyHasVisited(parent);
- parent.hasVisited[parent.y,parent.x] = true;
- if(InGrid(x, y) && grid[y,x].IsNotIsland && valueGrid[x,y] == 0)
- {
- child.hasVisited[y,x] = true;
- valueGrid[y,x]++;
- output.Add(child);
- parent = child;
- }
- else
- break;
- }
- }
- }
- }
- output.AddRange(oppGrid);
- Console.Error.WriteLine($"Locations post Silence: {output.Count()}");
- time.Stop();
- Console.Error.WriteLine($"Time for UPDATING SILENCE:{time.ElapsedMilliseconds}");
- return output;
- }
- //NOTE Update Torpedo plausible for to be sure that torpedo has been shot
- public static List<OppGrid> UpdateOppGridOnSonar(List<OppGrid> oppGrid, int sector, string sonarResult, Grid[,] grid)
- {
- List<OppGrid> output = new List<OppGrid>();
- sector--;
- int sectorY = ((sector / 3) * 5) + 2;
- int sectorX = ((sector % 3) * 5) + 2;
- Console.Error.WriteLine($"Sonar results are:{sonarResult}");
- Console.Error.WriteLine($"SecX: {sectorX} SecY: {sectorY} on sector {sector}");
- if(sonarResult == "N")
- {
- Console.Error.WriteLine($"OPP IS NOT IN SEARCHED SECTOR");
- foreach(var i in oppGrid)
- {
- int movedX = Math.Abs(i.x - sectorX);
- int movedY = Math.Abs(i.y - sectorY);
- if(movedX > 2 || movedY > 2)
- output.Add(i);
- }
- }
- else if (sonarResult == "Y")
- {
- Console.Error.WriteLine($"OPP IS IN THE SEARCHED SECTOR");
- foreach(var i in oppGrid)
- {
- int movedX = Math.Abs(i.x - sectorX);
- int movedY = Math.Abs(i.y - sectorY);
- if(movedX <= 2 && movedY <= 2)
- output.Add(i);
- }
- }
- else
- output = oppGrid;
- Console.Error.WriteLine($"SONAR: oppGrid:{oppGrid.Count()} output:{output.Count()}");
- return output;
- }
- public static List<OppGrid> UpdateOppGridOnHit(List<OppGrid> oppGrid, Location torpedo, Location mine)
- {
- List<OppGrid> output = new List<OppGrid>();
- foreach(var i in oppGrid)
- {
- int movedX = Math.Abs(torpedo.x - i.x);
- int movedY = Math.Abs(torpedo.y - i.y);
- int movedMineX = Math.Abs(mine.x - i.x);
- int movedMineY = Math.Abs(mine.y - i.y);
- if((torpedo.x != -1 && movedX <= 1 && movedY <=1 && movedX+movedY > 0) || (mine.x != -1 && movedMineX <= 1 && movedMineY <=1 && movedMineX+movedMineY > 0))
- output.Add(i);
- }
- return output;
- }
- public static List<OppGrid> UpdateOppGridOnBullseye(List<OppGrid> oppGrid,Location target, Location lastMineTrigger)
- {
- List<OppGrid> output = new List<OppGrid>();
- foreach(OppGrid i in oppGrid)
- {
- if((target.x != -1 && i.x == target.x && i.y == target.y) || (lastMineTrigger.x != -1 && i.x == lastMineTrigger.x && i.y == lastMineTrigger.y))
- output.Add(i);
- }
- return output;
- }
- public static List<OppGrid> UpdateGridOnTorpedoMissed(List<OppGrid> oppGrid, Location torpedoTarget, Location mine)
- {
- List<OppGrid> output = new List<OppGrid>();
- foreach(OppGrid i in oppGrid)
- {
- int distanceX = Math.Abs(i.x - torpedoTarget.x);
- int distanceY = Math.Abs(i.y - torpedoTarget.y);
- int distanceMineX = Math.Abs(i.x - mine.x);
- int distanceMineY = Math.Abs(i.y - mine.y);
- if(( torpedoTarget.x != -1 && (distanceY <= 1 && distanceX <= 1) == false) || ( mine.x != -1 && (distanceMineY <= 1 && distanceMineX <= 1) == false)) //Torpedo AOE not in range;
- output.Add(i);
- }
- return output;
- }
- public static List<OppGrid> UpdateOppGridOnMove(List<OppGrid> oppGrid, Grid[,] grid, string move, Dictionary<string, Movement> moveDict, bool hadNotToBrakeOut)
- {
- List<OppGrid> output = new List<OppGrid>();
- int x = moveDict[move].x;
- int y = moveDict[move].y;
- foreach(var i in oppGrid)
- {
- 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)
- {
- OppGrid iClone = i;
- iClone.y +=y;
- iClone.x +=x;
- iClone.hasVisited = copyHasVisited(i);
- iClone.hasVisited[iClone.y,iClone.x] = true;
- if(hadNotToBrakeOut)
- iClone.minefield = copyMinefield(i);
- output.Add(iClone);
- }
- }
- return output;
- }
- public static List<OppGrid> UpdateOppGridOnTorpedoFire(List<OppGrid> oppGrid, Grid[,] grid, Location torpedo) //Update
- {
- List<OppGrid> output = new List<OppGrid>();
- int[,] distanceGrid = DistanceFill(grid,torpedo.x,torpedo.y,5);
- foreach(var i in oppGrid)
- {
- if(distanceGrid[i.y,i.x] > 0)
- output.Add(i);
- }
- return output;
- }
- public static List<OppGrid> UpdateOppGridOnSurface(List<OppGrid> oppGrid, Grid[,] grid, int sector)
- {
- var time = new Stopwatch();
- time.Start();
- oppGrid = ResetOppGridOnLocations(oppGrid);
- List<OppGrid> output = new List<OppGrid>();
- sector -= 1;
- int sectorY = ((sector / 3) * 5)+2; //Corner cordinates of Sector
- int sectorX = ((sector % 3) * 5)+2;
- int sizeOfOutput = 0;
- foreach(OppGrid i in oppGrid)
- {
- int movedX = sectorX - i.x;
- int movedY = sectorY - i.y;
- if(movedX <= 2 && movedY <= 2)
- {
- OppGrid clone = new OppGrid(i.x,i.y);
- clone.minefield = copyMinefield(i);
- output.Add(clone); //REsets has visited
- }
- }
- time.Stop();
- Console.Error.WriteLine($"Time for UPDATING OPPGRID AFTER SURFACE {time.ElapsedMilliseconds}");
- return output;
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- //TORPEDO FIRE
- public static Location FireTorpedo(List<OppGrid> oppGrid,Grid[,] grid, int totalValue,int x, int y, ref string currTurn) //X, Y - my location on grid
- {
- var timeCheckAfterFiring = new Stopwatch();
- timeCheckAfterFiring.Start();
- oppGrid = ResetOppGridOnLocations(oppGrid);
- totalValue = oppGrid.Count();
- int [,] valueGrid = CreateValueGrid(oppGrid);
- int[,] distanceGrid = DistanceFill(grid, x, y, 5);
- Location target = new Location(-1,-1);
- int value = 0;
- foreach(OppGrid obj in oppGrid)
- {
- int movedX = Math.Abs(obj.x-x);
- int movedY = Math.Abs(obj.y-y);
- if( distanceGrid[obj.y,obj.x] > 0 && (movedX >= 2 || movedY >= 2))
- {
- int corX = obj.x-1;
- int corY = obj.y-1;
- int tempValue = 0;
- for(int i = 0; i < 3; i++)
- for(int l = 0; l < 3; l++)
- {
- if(InGrid(corX+i,corY+l))
- tempValue+=valueGrid[corY+l,corX+i];
- }
- if(tempValue >= totalValue / 2)
- {
- target = new Location(obj.x,obj.y);
- currTurn += String.Format($"TORPEDO {obj.x} {obj.y} |");
- return target;
- }
- }
- }
- if(target.x == -1)//For when the enemy prediction is a square/Oval
- {
- Console.Error.WriteLine("Searching for oval Oval Torpedo Range");
- for(int Y = 0; Y < 15; Y++)
- for(int X = 0; X < 15; X++)
- {
- if(InGrid(Y,X))
- {
- Location obj = new Location(X,Y);
- int movedX = Math.Abs(obj.x-x);
- int movedY = Math.Abs(obj.y-y);
- if( distanceGrid[obj.y,obj.x] > 0 && (movedX >= 2 || movedY >= 2))
- {
- int corX = obj.x-1;
- int corY = obj.y-1;
- int tempValue = 0;
- for(int i = 0; i < 3; i++)
- for(int l = 0; l < 3; l++)
- {
- if(InGrid(corX+i,corY+l))
- tempValue+=valueGrid[corY+l,corX+i];
- }
- if(tempValue >= totalValue)
- {
- target = new Location(obj.x,obj.y);
- currTurn += String.Format($"TORPEDO {obj.x} {obj.y} |");
- return target;
- }
- }
- }
- }
- }
- timeCheckAfterFiring.Stop();
- Console.Error.WriteLine($"Time for TAKING TORPEDO FIRE:{timeCheckAfterFiring.ElapsedMilliseconds}");
- return target;
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- //Submarine movement
- public static int closestEnemyDistance(int x, int y, List<OppGrid> oppGrid)
- {
- int output = int.MaxValue;
- foreach(OppGrid i in oppGrid)
- {
- int distance = Math.Abs(i.x - x) + Math.Abs(i.y-y);
- if (distance < output)
- output = distance;
- }
- return output;
- }
- public static int closestLocationDistance(int x, int y, List<Location> locations)
- {
- int output = int.MaxValue;
- foreach(Location i in locations)
- {
- int distance = Math.Abs(i.x - x) + Math.Abs(i.y-y);
- if (distance < output)
- output = distance;
- }
- return output;
- }
- 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)
- {
- var time = new Stopwatch();
- time.Start();
- string output;
- value = 0;
- output = "";
- List<string> directions = new List<string>();
- if( torpedoCooldown == 0 && ResetOppGridOnLocations(oppGrid).Count() <= 2 && ResetOppGridOnLocations(oppGrid).Count() > 0)
- {
- foreach(var direction in moveList)
- {
- int tempX = x + direction.x;
- int tempY = y + direction.y;
- var gridClone = MakeADeepGridCopy(grid);
- int tempValue = FloodFill(gridClone,tempX,tempY,moveList);
- int valueZone = 15;
- if(tempValue == value && tempValue > 0)
- directions.Add(direction.direction);
- else if(tempValue >= valueZone && value >= valueZone)
- {
- directions.Clear();
- directions.Add(direction.direction);
- value = tempValue;
- }
- else if(value < valueZone && tempValue > value)
- {
- value = tempValue;
- directions.Clear();
- directions.Add(direction.direction);
- }
- }
- List<string> runToKill = new List<string>(); //RunAway
- if(directions.Any())
- {
- int distanceValue = int.MaxValue;
- foreach(string i in directions)
- {
- Movement dir = moveDict[i];
- int tempDistance = closestEnemyDistance(x+dir.x, y+dir.y, oppGrid);
- if(tempDistance < distanceValue)
- {
- distanceValue = tempDistance;
- runToKill.Clear();
- runToKill.Add(i);
- }
- else if(tempDistance == distanceValue)
- runToKill.Add(i);
- }
- if(runToKill.Any())
- output = runToKill[0];
- else
- output = "";
- }
- else
- output = "";
- }
- else
- {
- foreach(var direction in moveList)
- {
- int tempX = x + direction.x;
- int tempY = y + direction.y;
- var gridClone = MakeADeepGridCopy(grid);
- int tempValue = FloodFill(gridClone,tempX,tempY,moveList);
- if(tempValue == value && tempValue > 0)
- directions.Add(direction.direction);
- else if(tempValue > value)
- {
- directions.Clear();
- directions.Add(direction.direction);
- value = tempValue;
- }
- }
- List<string> runAwayDir = new List<string>(); //RunAway
- if(directions.Any())
- {
- int distanceValue = int.MinValue;
- foreach(string i in directions)
- {
- Movement dir = moveDict[i];
- int tempDistance = closestEnemyDistance(x+dir.x, y+dir.y, oppGrid);
- if(tempDistance > distanceValue)
- {
- distanceValue = tempDistance;
- runAwayDir.Clear();
- runAwayDir.Add(i);
- }
- else if(tempDistance == distanceValue)
- runAwayDir.Add(i);
- }
- output = runAwayDir[0];
- }
- else
- output = "";
- if(runAwayDir.Any()) //RunToMines
- {
- int distanceValue = int.MaxValue;
- foreach(string i in runAwayDir)
- {
- Movement dir = moveDict[i];
- int tempDistance = closestLocationDistance(x+dir.x, y+dir.y, mines);
- if(tempDistance < distanceValue)
- {
- distanceValue = tempDistance;
- output = i;
- }
- }
- }
- else
- output = "";
- }
- Console.Error.WriteLine($"In positiox x:{x} y:{y} there are {directions.Count()} paths with the same value");
- time.Stop();
- Console.Error.WriteLine($"Time for FINDING MOVE:{time.ElapsedMilliseconds}");
- return output;
- }
- //FloodFill algorithm
- public static int FloodFill(Grid[,] grid, int x, int y, List<Movement> moveList)
- {
- int value = 0;
- if(InGrid(x,y) == false || grid[y,x].CanBeSwimmed == false)
- return 0;
- OppGrid location = new OppGrid();
- location.x = x;
- location.y = y;
- LinkedList<OppGrid> myList = new LinkedList<OppGrid>();
- myList.AddLast(location);
- grid[location.y,location.x].CanBeSwimmed = false;
- while(myList.Any())
- {
- OppGrid bigTemp = (OppGrid)myList.First.Value;
- myList.RemoveFirst();
- foreach(var direction in moveList)
- {
- OppGrid temp = new OppGrid();
- temp.x = bigTemp.x;
- temp.y = bigTemp.y;
- temp.x += direction.x;
- temp.y += direction.y;
- if(InGrid(temp.x,temp.y) && grid[temp.y,temp.x].CanBeSwimmed)
- {
- myList.AddLast(temp);
- value++;
- grid[temp.y,temp.x].CanBeSwimmed = false;
- }
- }
- }
- return value;
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- public static int CalculateOppGridCount(List<OppGrid> oppGrid)
- {
- int output = 0;
- foreach(var i in oppGrid)
- output++;
- return output;
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- public static OppGrid FindTorpedoTarget(int x,int y, List<OppGrid> oppGrid, Grid[,] grid)
- {
- foreach(OppGrid i in oppGrid)
- {
- int movedY = Math.Abs(y-i.y);
- int movedX = Math.Abs(x-i.x);
- int distance = movedX + movedY;
- if(distance == 4 || distance == 3)
- {
- Console.Error.WriteLine($"\nTorpedo Target range x:{movedX} y:{movedY}");
- Console.Error.WriteLine($"Torpedo target x:{i.x} y:{i.y}\n");
- return i;
- }
- }
- OppGrid noFoundOutput = new OppGrid();
- noFoundOutput.x = -1;
- return noFoundOutput;
- }
- //--------------------------------------------------------------------------------------------------------------------------------------
- public static void OppGridVisitedLocationsTyped(OppGrid i)
- {
- for (int y = 0; y < 15; y++)
- {
- for(int x = 0; x < 15; x++)
- {
- if(i.hasVisited[y,x])
- Console.Error.Write(" -");
- else
- Console.Error.Write(" +");
- }
- Console.Error.WriteLine();
- }
- }
- //decides what item to reload--------------------------------------------------------------------------------------------------------------
- public static string GetItem(ref int torpedoCooldown, ref int silenceCooldown, ref int sonarCooldown, ref int mineCooldown)
- {
- string item = "SILENCE";
- if(torpedoCooldown > 0)
- {
- item = "TORPEDO";
- torpedoCooldown--;
- }
- else if (silenceCooldown > 0)
- {
- item = "SILENCE";
- silenceCooldown--;
- }
- else if(mineCooldown > 0)
- {
- item = "MINE";
- mineCooldown--;
- }
- else if(sonarCooldown > 0)
- {
- item = "SONAR";
- sonarCooldown--;
- }
- return item;
- }
- //--------------------------------------------------------------------------------------------------------------------------------
- //Spawns a submarine
- public static void SpawnSubmarine(Grid[,] grid, List<Movement> movementList)
- {
- List<Location> spawns = new List<Location>();
- int value = 0;
- for(int x = 0; x < 15; x++)
- for(int y = 14; y >= 0;y--)
- {
- if(InGrid(x,y) && grid[y,x].CanBeSwimmed)
- {
- var gridClone = MakeADeepGridCopy(grid);
- gridClone[y,x].CanBeSwimmed = false;
- foreach(Movement mov in movementList)
- {
- int tempX = x + mov.x;
- int tempY = y + mov.y;
- if(InGrid(tempX,tempY) && grid[tempY,tempX].CanBeSwimmed)
- {
- int tempValue = FloodFill(gridClone, tempX, tempY, movementList);
- if(tempValue == value)
- spawns.Add(new Location(x,y));
- else if (tempValue > value)
- {
- value = tempValue;
- spawns.Clear();
- spawns.Add(new Location(x,y));
- }
- }
- }
- }
- }
- spawns.Count();
- int[] sectors = new int[9];
- List<List<Location>> optimalSpawns = new List<List<Location>>();
- for(int i = 0; i < 9; i++)
- optimalSpawns.Add(new List<Location>());
- foreach(var i in spawns)
- {
- int sectr = CalculateSectorFromCordinates(i.x,i.y)-1;
- sectors[sectr]++; //Calculates value
- optimalSpawns[sectr].Add(i);
- }
- int spawnSector = 5;
- int spawnValue = 0;
- for(int i = 0; i < 9; i++) //Most valuable sector
- if(sectors[i] > spawnValue)
- {
- spawnSector = i;
- spawnValue = sectors[i];
- }
- List<Location> spawnList = optimalSpawns[spawnSector];
- int mySpawnIndex = spawnList.Count() / 2;
- Location mySpawn = spawnList[mySpawnIndex];
- Console.Error.WriteLine($"There are {spawns.Count()} With the same value of {value}");
- Console.WriteLine($"{mySpawn.x} {mySpawn.y}");
- }
- //--------------------------------------------------------------------------------------------------------------
- //Finds where to deploy sonar
- public static void DeploySonar(List<OppGrid> oppGrid, ref string currTurn, ref int sonarLoc, bool hasUsedSilence)
- {
- //Initiate sector values for calculation
- int[] sectors = new int[9];
- for(int i = 0; i < sectors.Length; i++)
- sectors[i] = 0;
- foreach(var i in oppGrid) //Calculates the value where to deploy the sonar
- sectors[CalculateSectorFromCordinates(i.x,i.y)-1]++;
- int value = 0;
- int output = 0;
- for(int i = 0; i < sectors.Length; i++)
- if(sectors[i] > value) //Finds the best LOCATION
- {
- value = sectors[i];
- output = i;
- }
- output++;
- if(oppGrid.Count() > value && (hasUsedSilence || oppGrid.Count() > 1000 || value > 500)) //Checks if I even get anything from sonar
- {
- currTurn += String.Format($"SONAR {output} |");
- sonarLoc = output;
- }
- }
- public static bool IfHeFoundMe(int x, int y, Location enemyTorpedo)
- {
- if(enemyTorpedo.x != -1)
- if(Math.Abs(x-enemyTorpedo.x) <= 1 && Math.Abs(y-enemyTorpedo.y) <= 1)
- return true;
- return false;
- }
- //--------------------------------------------------------------------------------------------------------------
- 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,
- List<Location> mines, Location enemyTorpedo, Location enemyMine, int myLife, int sonarCoolDown, int mineCooldown, int torpedoCooldown, ref Location lastTorpedo, ref int silenceCooldown)
- {
- Dictionary<string,Movement> moveDict = InitializeMovementDictionary();
- int value = 0;
- string move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
- Random rng = new Random();
- List<OppGrid> attackGrid = ResetOppGridOnLocations(oppGrid);
- Location toFireTorepdoLocation = new Location(-1,-1);
- if(attackGrid.Count() > 0 && attackGrid.Count() < 3 && lastTorpedo.x != -1) //Dash to kill
- {
- bool brakeOut = false;
- List<Grid> possibleDashLocations = new List<Grid>();
- string tempTurn = "";
- foreach(var dir in moveDict.Values)
- {
- Grid[,] parent = MakeADeepGridCopy(grid);
- for(int i = 1; i <= 4; i++)
- {
- tempTurn = "";
- int tempX = x+dir.x;
- int tempY = y+dir.y;
- if(InGrid(tempX,tempY) && parent[tempY,tempX].CanBeSwimmed)
- {
- Grid[,] child = parent; //passes on the grid
- child[tempY,tempX].CanBeSwimmed = false;
- toFireTorepdoLocation = FireTorpedo(attackGrid, child, oppGrid.Count(), x, y, ref tempTurn);
- if(toFireTorepdoLocation.x != -1)
- {
- lastTorpedo = toFireTorepdoLocation;
- brakeOut = true;
- currTurn += String.Format("SILENCE {dir.direction} {i}| {tempTurn}"); //Outputs a move
- grid = child;
- x = tempX;
- y = tempY;
- break;
- }
- }
- }
- if(brakeOut)
- break;
- }
- }
- else if((IfHeFoundMe(x,y,enemyTorpedo) || IfHeFoundMe(x,y,enemyMine) || lastTorpedo.x != -1) && myLife > 1) //RunAway
- {
- Console.Error.WriteLine($"My move is {move}");
- move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
- if(myLife > 1 && value < 25)
- {
- currTurn+= String.Format($"SURFACE |");
- grid = CreateGrid(map, 15,15, x, y);
- move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
- }
- Console.Error.WriteLine($"My move is {move}");
- int i = 0;
- for(i = 0; i < 4; i++)
- {
- int tempX = x + moveDict[move].x;
- int tempY = y + moveDict[move].y;
- if(InGrid(tempY,tempX) && grid[tempY,tempX].CanBeSwimmed)
- {
- grid[y,x].CanBeSwimmed = false;
- x = tempX;
- y = tempY;
- }
- else
- break;
- }
- currTurn+= String.Format($"SILENCE {move} {i} |");
- silenceCooldown = -1;
- }
- else if(sonarCoolDown == 0 && mineCooldown == 0 && torpedoCooldown == 0) //Spam
- {
- if(value < 4 || move == "")
- {
- if(myLife > 1)
- {
- currTurn+= String.Format($"SURFACE |");
- grid = CreateGrid(map, 15,15, x, y);
- }
- Console.Error.WriteLine($"My move is {move}");
- grid = CreateGrid(map, 15, 15,x,y); //resets my path
- move = GetMove(grid,oppGrid,mines, x,y, InitializeMovementList(), InitializeMovementDictionary(), ref value, torpedoCooldown);
- Console.Error.WriteLine($"My move is {move}");
- currTurn+= String.Format($"SILENCE {move} {rng.Next(0,1)} |");
- silenceCooldown = -1;
- }
- else
- {
- Console.Error.WriteLine($"My move is {move}");
- currTurn+= String.Format($"SILENCE {move} 1 |");
- silenceCooldown = -1;
- }
- x += moveDict[move].x;
- y += moveDict[move].y;
- }
- }
- //--------------------------------------------------------------------------------------------------------------
- //Movement List Functions
- public static Dictionary<string, Movement> InitializeMovementDictionary()
- {
- Dictionary<string, Movement> output = new Dictionary<string, Movement>();
- output.Add("N", new Movement(0,-1,"N"));
- output.Add("E", new Movement(1,0,"E"));
- output.Add("W", new Movement(-1,0,"W"));
- output.Add("S", new Movement(0,1,"S"));
- return output;
- }
- public static List<Movement> InitializeMovementList()
- {
- List<Movement> output = new List<Movement>();
- output.Add(new Movement(0,-1,"N"));
- output.Add(new Movement(1,0,"E"));
- output.Add(new Movement(0,1,"S"));
- output.Add(new Movement(-1,0,"W"));
- return output;
- }
- public static List<Movement> UpdateMovementList(string move, bool hasTouchedCorners)
- {
- List<Movement> output = new List<Movement>();
- if(move == "N")
- {
- output.Add(new Movement(1,0,"E"));
- output.Add(new Movement(0,-1,"N"));
- output.Add(new Movement(0,1,"S"));
- output.Add(new Movement(-1,0,"W"));
- }
- else if(move == "E")
- {
- output.Add(new Movement(0,1,"S"));
- output.Add(new Movement(1,0,"E"));
- output.Add(new Movement(-1,0,"W"));
- output.Add(new Movement(0,-1,"N"));
- }
- else if(move == "S")
- {
- output.Add(new Movement(-1,0,"W"));
- output.Add(new Movement(0,1,"S"));
- output.Add(new Movement(0,-1,"N"));
- output.Add(new Movement(1,0,"E"));
- }
- else if (move == "W")
- {
- output.Add(new Movement(0,-1,"N"));
- output.Add(new Movement(-1,0,"W"));
- output.Add(new Movement(1,0,"E"));
- output.Add(new Movement(0,1,"S"));
- }
- else
- output = InitializeMovementList();
- if(hasTouchedCorners)
- output.Reverse();//Remove this in case
- return output;
- }
- }
- /*
- List<Location> possibleLocationsToGet = new List<Location>();
- possibleLocationsToGet.Add(new Location(x, y));
- foreach(Movement mov in moveDict.Values)
- {
- Location parent = new Location(x,y); // gets possible positions to dash to.
- for(int i = 0; i < 4; i++)
- {
- int tempX = parent.x + mov.x;
- int tempY = parent.y + mov.y;
- if(InGrid(tempX,tempY) && grid[tempY,tempX].CanBeSwimmed)
- {
- Location child = new Location(tempX,tempY);
- parent = child;
- possibleLocationsToGet.Add(child);
- }
- else
- break;
- }
- }
- Console.Error.WriteLine($"In position x:{x} y:{y} I can dash to {possibleLocationsToGet.Count()}");
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement