Edit: My original answer did not really follow MVC, sorry for the confusion. If you look
at http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller then you will see that controllers don't listen to models. So for the cases where you don't have a user involved, you either don't use MVC pattern or you replace the user by some Logic Class.
My updated design (pseudocode):
GameTable
List<card> visible
List<card> deck
changeDeck(...) { notify_observers(Event.deck_changed) }
changeCardOnTable(...) { notify_observers(Event.visible_cards_changed) }
GameState
List<card> selectedCards[num_players]
boolean gameOverManGameOver;
int turn
startGame(...) { notify_observers(Event.game_started) }
checkWin(...) { notify_observers(Event.game_won_or_lost_etc) }
playerChooseCard(player, card, ...) { notify_observers(Event.player_chose_card) }
endTurn(...) { // Do some calculations and some events }
AI Manager (you probably don't want to use a controller, because you have no view or user, so essentially you are merging 3 functionalities into one class, it is no longer MVC, but something different.
AI Manager
SomeStrategyClass strategy;
init(GameTable tableModel, GameState stateModel) {
observe(tableModel)
observe(stateModel)
}
onPlayerEvent(...) {
stragegy.think(tableModel, stateModel);
stateModel.playerChooseCard(strategy.whatToDoNext());
}
onInitOrWinEvent(...) {
// Reset/start/whatever AI should simulate on this event, etc
}
You don't really need a game controller, all the logic on how to play the game, should go inside your models, most likely your state model, inside nextTurn() function. Which leaves you with the remaining View and Controller
Player Controller
GameState stateModel;
chooseCard(...) { stateModel.playerChooseCard(...); }
resetGame(...) { stateModel.startGame(); }
doAction(...) { // do something with one of your models }
Player View
init(GameTable tableModel, GameState stateModel) {
observe(tableModel)
observe(stateModel)
}
abstract onCardChangeEvent(...);
abstract onGameWinOrLoseEvent(...);
abstract etcEvent(...);
Your JFRAME will have a combination of various gui elements, so when you build it it might be something like this.
GUIFrame extends PlayerView
Button resetButton;
PlayerController controller;
// Link button to controller
init() {
resetButton.addListener( controller.resetGame() )
someOtherButton.addListener( controller.doAction() )
}
// Implement view methods
onCardChangeEvent(...) { // redraw gui to show new card layout }
onGameWinOrLoseEvent(...) { // display some text that the player won or lost }
etcEvent(...) { // change the GUI to react to change in model state
I hope I didn't make the answer more confusing. Cheers.