I'm writing a C++ project and have a generic evaluate method in a class template.
My only question is how would I define the generateAllMoves and isPosFinal so that it is defined inside the classes that use this class template?
I've read that using pure virtual functions is a no no. I also do not want to make it static.
I foresee myself rewriting this as an abstract class, but then I would end up with a problem that requires generic types.
#ifndef ENGINE_H
#define ENGINE_H
#include <map>
using namespace std;
template< class M, class P >
class Engine {
public:
  Engine() { };  
  struct Move {
    P move;
    P pos;
    int score;
  };
  Move evaluate( P position ) {
    Move best;      
    if ( posIsFinal( position ) ) {
      Move newMove;
      newMove.pos = position;
      newMove.score = 1;
      return newMove;
    }
    else {
      map< M , P > allMoves = generateAllMoves( position );
      typename map< M , P > :: iterator it;
      for (it = allMoves.begin(); it != allMoves.end(); it++ ) {
        Move next = evaluate(it->second);
        if (next.score > best.score ) {
          best.pos = next.pos;
          best.move = next.move;
          best.score = next.score;
        }
      }
      return best;
    }
  }
};
#endif
Edit: To be more clear for everyone!
I have two different games right that defines its own generateAllMoves and isPosFinal methods. They use different algorithms and return different types.... For example, I will be soon implementing a chess game, but right now I'm implementing nim. Both interpret move and is this position final, differently.
2nd Edit:
Final code compiles!
#ifndef ENGINE_H
#define ENGINE_H
#include <map>
using namespace std;
template< typename Derived, class M, class P >
class Engine {
public:
  struct Move {
    P move;
    P pos;
    int score;
  };
  Move evaluate( P position ) {
    Move best;      
    if ( static_cast<Derived*>(this)->posIsFinal( position ) ) {
      Move newMove;
      newMove.pos = position;
      newMove.score = 1;
      return newMove;
    }
    else {
      map< M , P > allMoves = static_cast<Derived*>(this)->generateAllMoves( position );
      typename map< M , P > :: iterator it;
      for (it = allMoves.begin(); it != allMoves.end(); it++ ) {
        Move next = evaluate(it->second);
        if (next.score > best.score ) {
          best.pos = next.pos;
          best.move = next.move;
          best.score = next.score;
        }
      }
      return best;
    }
  }
  bool posIsFinal( P position ) {
    cerr << "Generic posIsFinal\n";
    exit(1);
  }
  map< M , P > generateAllMoves( P position ) {
    cerr << "Generic generateAllMoves\n";
    exit(1);
  }
private:
};
#endif
 
     
     
    