#include <iostream>
#include <string>

template <typename TType, int TRows, int TCols>
class TwoDArray {
  private:
    TType theArray[TRows][TCols];
    TType defSpace;

  public:
    TwoDArray(TType def);
    ~TwoDArray();
    void insert(int r, int c, TType value);
    TType access(int r, int c);
    void remove(int r, int c);
    void print();
    int getNumRows() const { return TRows; }
    int getNumCols() const { return TCols; }
};

//initializes the 2D Array
template <typename TType, int TRows, int TCols>
TwoDArray<TType, TRows, TCols>::TwoDArray(TType def) {
  defSpace = def;
  //sets all values to the default
  for(int i=0; i<TRows; i++) {
    for(int j=0; j<TCols; j++) {
    theArray[i][j] = defSpace;
    }
  }
}

//deletes the 2D Array
template<typename TType, int TRows, int TCols>
TwoDArray<TType, TRows, TCols>::~TwoDArray() {}

//inserts value v at row r and column c
template<typename TType, int TRows, int TCols>
void TwoDArray<TType, TRows, TCols>::insert(int r, int c, TType value) {
  theArray[r][c] = value;
}

//get value at row r, column c
template<typename TType, int TRows, int TCols>
TType TwoDArray<TType, TRows, TCols>::access(int r, int c) {
  TType result = theArray[r][c];
  return result;
}

//set value at row r and column c back to default
template<typename TType, int TRows, int TCols>
void TwoDArray<TType, TRows, TCols>::remove(int r, int c) {
  theArray[r][c] = defSpace;
}

//print the 2D Array
template<typename TType, int TRows, int TCols>
void TwoDArray<TType, TRows, TCols>::print() {
  for(int i=0; i<TRows; i++) {
    for(int j=0;j<TCols; j++) {
      std::cout << theArray[i][j];
      std::cout << " ";
    }
    std::cout << std::endl;
  }
}

int main()
{
    TwoDArray<int, 5, 5> i(0);
    i.insert(1, 1, 1);
    i.insert(1, 3, 1);
    i.insert(3, 2, 8);
    i.insert(2, 0, 3);
    i.insert(2, 4, 3);
    i.insert(3, 2, 8);
    i.print();

    std::cout << "\n\n";

    TwoDArray<std::string, 5, 5> s("o");

    s.insert(0, 2, "North");
    s.insert(4, 2, "South");
    s.insert(2, 4, "East");
    s.insert(2, 0, "West");
    s.print();

    return 0;
}
