Skip to content

Commit

Permalink
Added ExtendToString extension method to IMapView. Ported 2D array-ba…
Browse files Browse the repository at this point in the history
…sed grid printing code to use it. Added appropriate ToString functions to all IMapView implementations. This fixes issue #60.
  • Loading branch information
Chris3606 committed Oct 20, 2018
1 parent 84664c6 commit 458f2a5
Show file tree
Hide file tree
Showing 8 changed files with 301 additions and 68 deletions.
13 changes: 10 additions & 3 deletions GoRogue/MapViews/ArrayMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ public ArrayMap(int width, int height)
array = new T[width, height];
}

// Sets the internal array to the existing one. Should not (and cannot) be used outside of GoRogue. Be careful,
// as it is a straight reference assignment!
internal ArrayMap(T[,] existingArray)
{
array = existingArray;
}

/// <summary>
/// The height of the array.
/// </summary>
Expand Down Expand Up @@ -73,7 +80,7 @@ public object Clone()
/// Returns a string representation of the 2D array.
/// </summary>
/// <returns>A string representation of the 2D array.</returns>
public override string ToString() => array.ExtendToStringGrid();
public override string ToString() => this.ExtendToString();

/// <summary>
/// Returns a string representation of the 2D array, using the elementStringifier function
Expand All @@ -87,7 +94,7 @@ public object Clone()
/// Function determining the string representation of each element.
/// </param>
/// <returns>A string representation of the 2D array.</returns>
public string ToString(Func<T, string> elementStringifier) => array.ExtendToStringGrid(elementStringifier: elementStringifier);
public string ToString(Func<T, string> elementStringifier) => this.ExtendToString(elementStringifier: elementStringifier);

/// <summary>
/// Prints the values in the ArrayMap, using the function specified to turn elements into
Expand All @@ -102,6 +109,6 @@ public object Clone()
/// function of type T.
/// </param>
/// <returns>A string representation of the ArrayMap.</returns>
public string ToString(int fieldSize, Func<T, string> elementStringifier = null) => array.ExtendToStringGrid(fieldSize, elementStringifier: elementStringifier);
public string ToString(int fieldSize, Func<T, string> elementStringifier = null) => this.ExtendToString(fieldSize, elementStringifier: elementStringifier);
}
}
109 changes: 102 additions & 7 deletions GoRogue/MapViews/IMapViewExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Troschuetz.Random;

namespace GoRogue.MapViews
Expand Down Expand Up @@ -120,14 +121,108 @@ public static Coord RandomPosition<T>(this IMapView<T> mapView, IGenerator rng =
}

/// <summary>
/// Returns a Coord (Width, Height) representing the size of the MapView.
/// Extension method for IMapViews allowing printing the contents. Takes characters
/// to surround the map printout, and each row, the method used to get the string representation of
/// each element (defaulting to the ToString function of type T), and separation characters
/// for each element and row.
/// </summary>
/// <typeparam name="T">Type of items being exposed by the MapView.</typeparam>
/// &gt;
/// <param name="mapView">
/// Map view to get bounds for -- never specified manually as this is an extension method.
/// <typeparam name="T">Type of elements in the IMapView.</typeparam>
/// <param name="map">
/// The IMapView to stringify -- never specified manually as this is an extension method.
/// </param>
/// <returns>A Coord (Width, Height) representing the size of the MapView.</returns>
public static Coord Size<T>(this IMapView<T> mapView) => Coord.Get(mapView.Width, mapView.Height);
/// <param name="begin">Character(s) that should precede the IMapView printout.</param>
/// <param name="beginRow">Character(s) that should precede each row.</param>
/// <param name="elementStringifier">
/// Function to use to get the string representation of each value. Null uses the ToString
/// function of type T.
/// </param>
/// <param name="rowSeparator">Character(s) to separate each row from the next.</param>
/// <param name="elementSeparator">Character(s) to separate each element from the next.</param>
/// <param name="endRow">Character(s) that should follow each row.</param>
/// <param name="end">Character(s) that should follow the IMapView printout.</param>
/// <returns>
/// A string representation of the map, as viewd by the given map view.
/// </returns>
public static string ExtendToString<T>(this IMapView<T> map, string begin = "", string beginRow = "", Func<T, string> elementStringifier = null,
string rowSeparator = "\n", string elementSeparator = " ", string endRow = "", string end = "")
{
if (elementStringifier == null)
elementStringifier = (T obj) => obj.ToString();

var result = new StringBuilder(begin);
for (int y = 0; y < map.Height; y++)
{
result.Append(beginRow);
for (int x = 0; x < map.Width; x++)
{
result.Append(elementStringifier(map[x, y]));
if (x != map.Width - 1) result.Append(elementSeparator);
}

result.Append(endRow);
if (y != map.Height - 1) result.Append(rowSeparator);
}

result.Append(end);

return result.ToString();
}

/// <summary>
/// Extension method for IMapViews allowing printing the contents. Takes characters
/// to surround the map, and each row, the method used to get the string representation of
/// each element (defaulting to the ToString function of type T), and separation characters
/// for each element and row. Takes the size
/// of the field to give each element, characters to surround the MapView printout, and each row, the
/// method used to get the string representation of each element (defaulting to the ToString
/// function of type T), and separation characters for each element and row.
/// </summary>
/// <typeparam name="T">Type of elements in the 2D array.</typeparam>
/// <param name="map">
/// The IMapView to stringify -- never specified manually as this is an extension method.
/// </param>
/// <param name="fieldSize">
/// The amount of space each element should take up in characters. A positive number aligns
/// the text to the right of the space, while a negative number aligns the text to the left.
/// </param>
/// <param name="begin">Character(s) that should precede the IMapView printout.</param>
/// <param name="beginRow">Character(s) that should precede each row.</param>
/// <param name="elementStringifier">
/// Function to use to get the string representation of each value. Null uses the ToString
/// function of type T.
/// </param>
/// <param name="rowSeparator">Character(s) to separate each row from the next.</param>
/// <param name="elementSeparator">Character(s) to separate each element from the next.</param>
/// <param name="endRow">Character(s) that should follow each row.</param>
/// <param name="end">Character(s) that should follow the IMapView printout.</param>
/// <returns>
/// A string representation of the map, as viewd by the given map view.
/// </returns>
public static string ExtendToString<T>(this IMapView<T> map, int fieldSize, string begin = "", string beginRow = "", Func<T, string> elementStringifier = null,
string rowSeparator = "\n", string elementSeparator = " ", string endRow = "", string end = "")
{
if (elementStringifier == null)
elementStringifier = (T obj) => obj.ToString();

var result = new StringBuilder(begin);
for (int y = 0; y < map.Height; y++)
{
result.Append(beginRow);
for (int x = 0; x < map.Width; x++)
{
result.Append(string.Format($"{{0, {fieldSize}}} ", elementStringifier(map[x, y])));
if (x != map.Width - 1) result.Append(elementSeparator);
}

result.Append(endRow);
if (y != map.Height - 1) result.Append(rowSeparator);
}

result.Append(end);

return result.ToString();
}


}
}
35 changes: 35 additions & 0 deletions GoRogue/MapViews/LambdaMapView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,40 @@ public LambdaMapView(Func<int> widthGetter, Func<int> heightGetter, Func<Coord,
/// provided at construction.
/// </returns>
public T this[Coord pos] { get => valueGetter(pos); }

/// <summary>
/// Returns a string representation of the LambdaMapView.
/// </summary>
/// <returns>A string representation of the LambdaMapView.</returns>
public override string ToString() => this.ExtendToString();

/// <summary>
/// Returns a string representation of the LambdaMapView, using the elementStringifier function
/// given to determine what string represents which value.
/// </summary>
/// <remarks>
/// This could be used, for example, on an LambdaMapView of boolean values, to output '#' for
/// false values, and '.' for true values.
/// </remarks>
/// <param name="elementStringifier">
/// Function determining the string representation of each element.
/// </param>
/// <returns>A string representation of the LambdaMapView.</returns>
public string ToString(Func<T, string> elementStringifier) => this.ExtendToString(elementStringifier: elementStringifier);

/// <summary>
/// Prints the values in the LambdaMapView, using the function specified to turn elements into
/// strings, and using the "field length" specified. Each element of type T will have spaces
/// added to cause it to take up exactly fieldSize characters, provided fieldSize is less
/// than the length of the element's string represention. A positive-number right-aligns the
/// text within the field, while a negative number left-aligns the text.
/// </summary>
/// <param name="fieldSize">The size of the field to give each value.</param>
/// <param name="elementStringifier">
/// Function to use to convert each element to a string. Null defaults to the ToString
/// function of type T.
/// </param>
/// <returns>A string representation of the LambdaMapView.</returns>
public string ToString(int fieldSize, Func<T, string> elementStringifier = null) => this.ExtendToString(fieldSize, elementStringifier: elementStringifier);
}
}
35 changes: 35 additions & 0 deletions GoRogue/MapViews/LambdaSettableMapView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,40 @@ public T this[Coord pos]
get => valueGetter(pos);
set => valueSetter(pos, value);
}

/// <summary>
/// Returns a string representation of the LambdaSettableMapView.
/// </summary>
/// <returns>A string representation of the LambdaSettableMapView.</returns>
public override string ToString() => this.ExtendToString();

/// <summary>
/// Returns a string representation of the LambdaSettableMapView, using the elementStringifier function
/// given to determine what string represents which value.
/// </summary>
/// <remarks>
/// This could be used, for example, on an LambdaSettableMapView of boolean values, to output '#' for
/// false values, and '.' for true values.
/// </remarks>
/// <param name="elementStringifier">
/// Function determining the string representation of each element.
/// </param>
/// <returns>A string representation of the LambdaSettableMapView.</returns>
public string ToString(Func<T, string> elementStringifier) => this.ExtendToString(elementStringifier: elementStringifier);

/// <summary>
/// Prints the values in the LambdaSettableMapView, using the function specified to turn elements into
/// strings, and using the "field length" specified. Each element of type T will have spaces
/// added to cause it to take up exactly fieldSize characters, provided fieldSize is less
/// than the length of the element's string represention. A positive-number right-aligns the
/// text within the field, while a negative number left-aligns the text.
/// </summary>
/// <param name="fieldSize">The size of the field to give each value.</param>
/// <param name="elementStringifier">
/// Function to use to convert each element to a string. Null defaults to the ToString
/// function of type T.
/// </param>
/// <returns>A string representation of the LambdaSettableMapView.</returns>
public string ToString(int fieldSize, Func<T, string> elementStringifier = null) => this.ExtendToString(fieldSize, elementStringifier: elementStringifier);
}
}
41 changes: 36 additions & 5 deletions GoRogue/MapViews/SettableTranslationMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,6 @@ public void ApplyOverlay(ISettableMapView<T2> overlay)
this[x, y] = overlay[x, y];
}

/// <summary>
/// Returns a string representation of the underlying map.
/// </summary>
public override string ToString() => BaseMap.ToString();

/// <summary>
/// Translates your map data into the view type.
/// </summary>
Expand All @@ -122,5 +117,41 @@ public void ApplyOverlay(ISettableMapView<T2> overlay)
/// <param name="value">A value of the mapped data type</param>
/// <returns>The data value for your map.</returns>
protected abstract T1 TranslateSet(T2 value);

/// <summary>
/// Returns a string representation of the SettableTranslationMap.
/// </summary>
/// <returns>A string representation of the SettableTranslationMap.</returns>
public override string ToString() => this.ExtendToString();

/// <summary>
/// Returns a string representation of the SettableTranslationMap, using the elementStringifier function
/// given to determine what string represents which value.
/// </summary>
/// <remarks>
/// This could be used, for example, on an SettableTranslationMap of boolean values, to output '#' for
/// false values, and '.' for true values.
/// </remarks>
/// <param name="elementStringifier">
/// Function determining the string representation of each element.
/// </param>
/// <returns>A string representation of the SettableTranslationMap.</returns>
public string ToString(Func<T2, string> elementStringifier) => this.ExtendToString(elementStringifier: elementStringifier);

/// <summary>
/// Prints the values in the SettableTranslationMap, using the function specified to turn elements into
/// strings, and using the "field length" specified. Each element of type T will have spaces
/// added to cause it to take up exactly fieldSize characters, provided fieldSize is less
/// than the length of the element's string represention. A positive-number right-aligns the
/// text within the field, while a negative number left-aligns the text.
/// </summary>
/// <param name="fieldSize">The size of the field to give each value.</param>
/// <param name="elementStringifier">
/// Function to use to convert each element to a string. Null defaults to the ToString
/// function of type T.
/// </param>
/// <returns>A string representation of the SettableTranslationMap.</returns>
public string ToString(int fieldSize, Func<T2, string> elementStringifier = null) => this.ExtendToString(fieldSize, elementStringifier: elementStringifier);

}
}
43 changes: 38 additions & 5 deletions GoRogue/MapViews/TranslationMap.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace GoRogue.MapViews
using System;

namespace GoRogue.MapViews
{
/// <summary>
/// Map view class capable of taking complex data and providing a simpler view of it. For a
Expand All @@ -8,8 +10,8 @@
/// Many GoRogue algorithms work on a IMapView of a simple data type, which is likely to be a
/// poor match for your game's actual map data. For example, map generation works with bools, and
/// FOV calculation with doubles, while your map data may model each map cell as a class or
/// struct containing many different member values. /// This class allows you to build descendant
/// classes that override the TranslateGet method for simple mapping, or the this properties if
/// struct containing many different member values. This class allows you to build descendant
/// classes that override the TranslateGet method for simple mapping, or the "this" indexers if
/// you need full access to the underlying data for context, in order to present a simplified
/// view of your data to an algorithm without having to create the large amount of duplicate code
/// associated with multiple ISettableMapView instances that all extract data from a Cell or Tile class.
Expand Down Expand Up @@ -67,9 +69,40 @@ virtual public T2 this[Coord pos]
}

/// <summary>
/// Returns a string representation of the underlying map.
/// Returns a string representation of the TranslationMap.
/// </summary>
/// <returns>A string representation of the TranslationMap.</returns>
public override string ToString() => this.ExtendToString();

/// <summary>
/// Returns a string representation of the TranslationMap, using the elementStringifier function
/// given to determine what string represents which value.
/// </summary>
public override string ToString() => BaseMap.ToString();
/// <remarks>
/// This could be used, for example, on an TranslationMap of boolean values, to output '#' for
/// false values, and '.' for true values.
/// </remarks>
/// <param name="elementStringifier">
/// Function determining the string representation of each element.
/// </param>
/// <returns>A string representation of the TranslationMap.</returns>
public string ToString(Func<T2, string> elementStringifier) => this.ExtendToString(elementStringifier: elementStringifier);

/// <summary>
/// Prints the values in the TranslationMap, using the function specified to turn elements into
/// strings, and using the "field length" specified. Each element of type T will have spaces
/// added to cause it to take up exactly fieldSize characters, provided fieldSize is less
/// than the length of the element's string represention. A positive-number right-aligns the
/// text within the field, while a negative number left-aligns the text.
/// </summary>
/// <param name="fieldSize">The size of the field to give each value.</param>
/// <param name="elementStringifier">
/// Function to use to convert each element to a string. Null defaults to the ToString
/// function of type T.
/// </param>
/// <returns>A string representation of the TranslationMap.</returns>
public string ToString(int fieldSize, Func<T2, string> elementStringifier = null) => this.ExtendToString(fieldSize, elementStringifier: elementStringifier);


/// <summary>
/// Translates your map data into the view type.
Expand Down
Loading

0 comments on commit 458f2a5

Please sign in to comment.