Skip to content

Instantly share code, notes, and snippets.

@soon
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soon/51708a206704b2c717e4 to your computer and use it in GitHub Desktop.
Save soon/51708a206704b2c717e4 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace SampleAi
{
[DebuggerDisplay("Pont({X}, {Y})")]
public class Point
{
#region Constructors
public Point(int x, int y)
{
X = x;
Y = y;
}
#endregion // Constructors
#region Properties
public int X
{
get;
private set;
}
public int Y
{
get;
private set;
}
#endregion // Properties
#region Methods
public Point Add(Point point)
{
return new Point(X + point.X, Y + point.Y);
}
#endregion // Methods
#region Overrides of Object
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>
/// A string that represents the current object.
/// </returns>
public override string ToString()
{
return string.Format("Point({0}, {1})", X, Y);
}
#endregion
}
public static class Map
{
#region Properties
private static bool[,] CellsWithShips
{
get;
set;
}
#endregion // Properties
#region Methods
public static IEnumerable<Point> GetAllShipPoints()
{
return Enumerable.Range(0, CellsWithShips.GetLength(0))
.SelectMany(x => Enumerable.Range(0, CellsWithShips.GetLength(1)).Select(y => new Point(x, y)))
.Where(p => CellsWithShips[p.X, p.Y]);
}
public static void Init(int width, int height)
{
CellsWithShips = new bool[width, height];
}
public static void Wound(Point location)
{
CellsWithShips[location.X, location.Y] = true;
}
public static void Kill(Point location)
{
Wound(location);
foreach(var point in GetShipPointsAndTheirNeighbors(location).ToList())
{
CellsWithShips[point.X, point.Y] = false;
}
}
/// <summary>
/// This version does not work for strange reasons, it just skips a half of points. See TestKill_DoesNotWork_1 test case
/// </summary>
/// <param name="location"></param>
public static void Kill_DoesNotWork(Point location)
{
Wound(location);
foreach(var point in GetShipPointsAndTheirNeighbors(location))
{
CellsWithShips[point.X, point.Y] = false;
}
}
private static IEnumerable<Point> GetShipPointsAndTheirNeighbors(Point location)
{
return GetShipPoints(location).SelectMany(Near);
}
private static IEnumerable<Point> Near(Point location)
{
return new[]
{
location.Add(new Point(0, -1)),
location.Add(new Point(0, 0))
};
}
private static IEnumerable<Point> GetShipPoints(Point location)
{
var beforePoint = new[]
{
location,
location.Add(new Point(0, -1)),
location.Add(new Point(0, -2)),
location.Add(new Point(0, -3))
};
return beforePoint.TakeWhile(p => CellsWithShips[p.X, p.Y]);
}
#endregion // Methods
}
public static class Program
{
private static void LoadMap()
{
Map.Init(20, 20);
Map.Wound(new Point(1, 4));
Map.Wound(new Point(1, 5));
Map.Wound(new Point(1, 6));
}
private static int TestKill()
{
LoadMap();
Map.Kill(new Point(1, 7));
return Map.GetAllShipPoints().Count();
}
private static int TestKillDoesNotWork()
{
LoadMap();
Map.Kill_DoesNotWork(new Point(1, 7));
return Map.GetAllShipPoints().Count();
}
private static void Main()
{
Console.WriteLine("Test kill: {0}", TestKill());
Console.WriteLine("Test kill (does not work): {0}", TestKillDoesNotWork());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment