Ok, if you don't care about the graphics, that's simpler. From a high-level pseudocode, what I suggest is like how any other game loop works:
while game has not ended yet:
keep going
// we're out of the while loop; game has ended
show results, etc.
go back to main menu
Thing is, yours is turn-based, so we can do away with the loop part, or keep it and use coroutines. Let's keep it simple for now though. (Not sure if standard Python has coroutines built-in)
So instead of a loop, we'll basically use callback functions.
The entry point for starting our game would be like this (this is still pseudocode):
// call this at the start of the game
function OnStartTurn()
{
currentPlayer.OnBeginTurn();
}
// call this function when the human player clicks on "End Turn" button, or if the AI decides it's finished.
function OnCurrentPlayerEndTurn()
{
change currentPlayer variable to the next player in line
OnStartTurn(); // will cause the next player to begin his turn
}
So from here, you can gather that we at least need a currentPlayer variable, which means we need some sort of Player class.
Also since we need to let the game pass control to the next player in line, we need to store all Player objects in a list (ordered in the way we want to). And on the OnCurrentPlayerEndTurn function, we simply cycle through that list so that the next player now begins his turn.
In OnStartTurn() we have a currentPlayer.OnBeginTurn(). You will want that for human players, this function will activate the GUI so the user can now act. For AI players you will want this function to start the AI's thinking process instead.
If you don't know how to do that, you have to learn polymorphism and object-oriented programming concepts.
Now for the human player, you'd provide some "End turn" button, which when clicked will call that OnCurrentPlayerEndTurn() function. For the AI, you'll want that immediately after the AI is done thinking and acting, it will likewise call OnCurrentPlayerEndTurn().
The idea is, either way, OnCurrentPlayerEndTurn() needs to get called in the end, so that the next player who needs to move gets his turn.
Unless a player won, in which case you don't need to bother calling that. Just go ahead and call your function to show results, etc.