Just FYI, I haven't written any code for the game. I'm in the planning phase, brainstorming how certain game features might affect the structure/architecture of the code.
I'm thinking about the design of a multiplayer turn-based card game with regards to a technical feature: the ability to request a trade with the player who has the turn.
An example of this mechanic is Settlers of Catan, or Munchkin (I'm trying to build a Munchkin clone). The structure of the game is pretty regular: on a player's turn they have a number of actions to take: "Kick Open the Door/Fight monster", "Equip/unequip items", "Initiate trade with another player", etc.
What I would also like players to do is to perform out-of-turn actions (perhaps a subset of actions they can perform on their turn), for example, the ability to trade with other players.
How does this feature imply how my game app should be structured/architected?
One thought I had: Each player will run their own game client and it seems a multithreaded game server app with some message-passing/casting will be necessary to facilitate these features. The game server will notify the appropriate client if it's that player's turn (i.e., a message broadcast to all clients of whose turn it is). In addition, the server will listen for messages from out-of-turn players wishing to perform some actions (like trading) to broker that activity between corresponding clients.
it does not change anything major from the sound of it. Maybe it does, but I think you can do this, from the sound of it, without extremely complex structures.
player 1 turn, anyone can trade turn (press a no button to pass the opportunity), player 2 turn, anyone can trade turn, .... just do this flow.
I would have like a 30 second window (make this CONFIGURABLE by the user on how long, some will want 2 seconds, some 10, some 30 etc) where the user can pass or instigate an action. If they do an action, then the game clearly says who traded what with each other (unless its hidden, then it just says X traded with Y) for all to see and game flow proceeds. If multiple people trade, you either need to do it in parallel (if multiplayer) or just queue it up (human vs AI players) as the AI can do its thing nearly instantly anyway. What will you do if 3 humans playing want to trade such that 1 and 2 both want to trade for 3's whatever-card? What does that interface look like? How is it resolved?
A good example of this flow is the talisman version of that board game. It gives the humans a window of time to choose to do (or not) actions that are outside the normal player1-player2-... flow.
The best advice I can give at this moment though is to remember to KISS it. It probably does not require a giant, complicated 5 page block of code to figure out a way to do this cleanly. If it involves multi-threading, which it may or may not, just keep it as clean, small, and simple as possible. Its a simple thing you want to do, but very easy to make it into a big effort.
As I see it, you have three choices ( order of difficulty)
1) The simplest is to have a single input stream (cin). The difficulty here is that you have to either give control to a specific player or ask if any players have a trade they would like to make.
2) If you're considering having your game run on multiple platforms, I would suggest the client/server model you mentioned in your OP.
3) If you want to run on a single platform, such as Windows, each player can have their own window, all within a single instance of the game. Each window can message another window when there is a trade to be made. The game engine can also message each window when it is that window's turn.