________________________________________________________________________________________________________ Jeu de morpion : interface gtk Vous disposez : - d'un modele du jeu de morpion - d'une vue du jeu de morpion Il s'agit de connecter les 2 ! ________________________________________________________________________________________________________ Un peu d'explication de texte : ___________ Modele => voir le fichier d'entete 'morpion.h' pour la description des structures de donnees et ds methodes Deux structures de donnees : - case_jeu - partie Liste des methodes du modele associees a la partie de morpion : - accesseurs en lecture : etat_partie partie_get_etat(partie* une_partie); int partie_get_nbcoup(partie* une_partie); etat_case partie_get_tourjoueur(partie* une_partie); etat_case partie_get_case_etat(partie* une_partie, int i, int j); case_jeu* partie_get_case(partie* une_partie, int i, int j); - fonctions de jeu : void partie_nouvelle_partie(partie* une_partie); void partie_jouer_case(partie* une_partie, int i, int j); - accesseur technique aux composants de la structure : case_jeu* partie_get_case(partie* une_partie, int i, int j); ___________ Vue => voir le fichier d'entete 'morpion_ig.h' pour la description des structures de donnees et ds methodes Deux structures de donnees : - ig_case - ig_morpion Liste des methodes de la vue associees aux cases du jeu ou a la vue globale : - construction / destruction / lancement : int ig_construire(ig_morpion* ig, int nb_case); void ig_detruire(ig_morpion* ig); void ig_run(ig_morpion* ig); - manipulation : void ig_case_set_libelle(ig_morpion* ig, int indice, char* libelle); void ig_case_set_active(ig_morpion* ig, int indice, gboolean oui_ou_non); void ig_set_titre(ig_morpion* ig, char* info_fenetre); void ig_set_partie_active(ig_morpion* ig, gboolean oui_ou_non); - accesseurs techniques aux composants graphiques : void* ig_get_fenetre(ig_morpion* ig); void* ig_get_case(ig_morpion* ig, int indice); void* ig_get_nouvelle_partie(ig_morpion* ig); - fonctions de rappel (qui sont effectivement attachees par la fonction 'ig_construire') : void cb_ig_quitter(GtkWidget* widget, gpointer ig); void cb_ig_jouer_case(GtkWidget* bouton, gpointer no_param); void cb_ig_nouvelle_partie(GtkWidget* widget, gpointer ig); ________________________________________________________________________________________________________ Questions : 1) Recuperer les sources du modele. Generer le programme de test et le lancer. De meme, recuperer les sources de la vue. Generer le programme de test et le lancer. 2) Identifier les attachements que l'on souhaiterait faire entre le vue et le modele, soit : sur quelles actions de l'utilisateur, voudrait-on faire appel a quelle(s) fonction(s) du modele ? A quelle(s) fonction(s) de la vue ? 3) Seule une structure connaissant conjointement le modele et la vue permettra aux fonctions de rappel de pouvoir agir sur les deux. 3.1) Definir une structure de donnee 'ctr_morpion' qui regroupe le modele, et la vue du morpion. 3.2) Modifier le programme test de la vue (fichier 'vue_test.c') : au lieu d'utiliser une variable de type 'ig_morpion', ce programme doit utiliser une varible du 'ctr_morpion' que vous venez de definir. 3.3) Definissez les fonctions 'ctr_construire', 'ctr_detruire', et les utiliser dans le programme test. 4) 'Nouvelle partie' 4.1) Definissez la fonction 'ctr_nouvelle_partie' qui, a partir d'un argument de type 'ctr_morpion*' : - lance une nouvelle partie dans le modele ; - synchronise la vue. 4.2) Definissez la fonction 'ctr_run', qui lance l'interface apres avoir fait appel a 'ctr_nouvelle_partie'. Utilisez cette nouvelle fonction fonction dans le programme test. 4.3) Ecrire une fonction de rappel 'cb_nouvelle_partie' qui fait appel a 'ctr_nouvelle_partie'. Attacher cette fonction au signal 'clicked' du bouton 'nouvelle partie'. A quel endroit dans votre code, cet attachement pourrait-il etre fait (dans quelle fonction) ? 5) 'Jouer case' 5.1) Definir une structure de donnee 'ctr_case' qui regroupe un case du modele, une case de la vue, et une reference sur un controleur parent. Enrichir la structure 'ctr_morpion' d'un tableau de 'ctr_case'. Combient de 'ctr_case' faut-il ? 5.2) Mettre a jour la fonction de construction d'un 'ctr_morpion' : il faut construire le tableau des 'ctr_case', chaque 'ctr_case' de ce tableau permettant de mettre en correspondance le modele (donnee de type case_jeu) et la vue (donnee de type ig_case) d'une case. 5.3) Definissez la fonction 'ctr_jouer_case' qui, a partir d'un argument de type 'ctr_case*' : - joue la case correspondante dans le modele ; - attribue a la case de la vue le libelle representant le joueur qui vient de jouer la case (ex., 'X' pour le joueur 1 et 'O' pour le joueur 2) ; - si la partie est finie a l'issue de ce coup, synchronise la vue ; sinon, synchronise eventuellement la vue en indiquant, dans le titre de la fenetre, le joueur dont c'est le tour (le prendre aussi en compte alors en tout debut de partie). 5.4) Ecrire une fonction de rappel 'cb_jouer_case' qui fait appel a 'ctr_jouer_case'. Attacher cette fonction au signal 'clicked' de chaque bouton pressoir.