Last active
August 29, 2015 14:14
-
-
Save soon/51708a206704b2c717e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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