Sugeruję odłożyć w kąt enum i ify/switch. Przy zmianie liczby stanów musiałbyś ingerować w samego enuma i wszystkie funkcje, w których na instancji tego enuma bazujesz. Mało elegankie.
Proponuję zrobić klasę abstrakcyjną stanu (załóżmy - IState), która będzie posiadać wirtualne metody potrzebne Ci dla każdego ze stanów - jak update czy draw.
Każdy stan (dodawanie fiszek, przepytywanie, itd.) to będzie klasa dziedzicząca po klasie abstrakcyjnej, w której zaimplementujesz dla każdego stanu odpowiednie metody oraz dodasz niezbędne zmienne instancyjne. Zauważ, że masz tutaj też do dyspozycji konstruktor i destruktor, które pozwolą Ci na jednorazowe akcje przy tworzeniu i niszczeniu danego stanu - to bardzo przydatne.
W pętli głównej aplikacji piszesz po prostu:
#include <memory> // dla inteligentnego wskaźnika
// ...
int main()
{
// ...
unique_ptr <IState> state( new StateStart( /* parameters */ ) );
while(true) // main loop
{
state -> update();
state -> draw();
// ...
}
// ...
}
i teraz zależnie od tego, jaką klasę przypiszesz do zmiennej state, odpowiednie metody dla każdego stanu będą się wykonywały.
Możesz też sobie napisać prosty manager stanów, który będzie odpowiednio zarządzał aktualnym stanem. To rozwiązanie ma też wcale niezły potencjał na budowanie stosu stanów - to znaczy że w trakcie trwania, np. stanu gry, user wciśnie przycisk odpowiedzialny za pauzę. Wtedy manager stanów odkłada na stos stan gry i wrzuca na wierzchołek stosu stan pauzy. Po zakończeniu stanu pauzy, stan ten idzie do kosza i można zdjąć z wierzchołka stosu stan gry i go pięknie przywrócić.
Jest tutaj odrobina zabawy, ale jak trochę się nad tym posiedzi, to myślę że efekt będzie warty poświęconego czasu. :)
// edytowałem lekko kod, dla użycia smart pointera w miejsce raw pointera