:: Enseignements :: ESIPE :: E4INFO :: 2015-2016 :: Interface Graphique avec Android ::
[LOGO]

SortGame


Au cours de ce TP noté, il sera question d'implanter un jeu permettant de trier une liste d'items (présentés initialement dans le désordre).
Par exemple, seriez-vous capable de trier ces capitales de la moins peuplée à la plus peuplée ?
  • Sofia (Bulgarie)
  • Kinshasa (République démocratique du Congo)
  • Moscou (Russie)
  • Jakarta (Indonésie)
  • Brasilia (Brésil)

Exercice 1 - Layout de jeu

L'activité principale du jeu (nommée GameActivity et présente dans le paquetage fr.upem.sortgame) affiche la question, une liste d'items, le score maximal atteignable en répondant correctement à la question, deux boutons permettant de déplacer un item de la liste vers le haut ou vers le bas ainsi qu'un bouton permettant de valider le résultat.

Par défaut la langue de l'application est l'anglais. Il faudra faire en sorte que le tous les textes soient également traduits en français. On ne se préoccupera pas en revanche de l'internationalisation des énoncés des problèmes (on les utilise tels quels).

Voici le résultat que l'on souhaiterait obtenir pour l'activité :

Écrivez un layout XML permettant d'obtenir une activité présentant un affichage similaire.

Exercice 2 - Mode paysage

Si l'application est en mode paysage, on souhaite avoir un layout un peu modifié avec le score maximal, les deux boutons de déplacement ainsi que le bouton de validation à gauche.

Ecrivez le layout correspondant et faites en sorte que le layout adapté soit choisi pour le contexte courant (1er layout si l'appareil est en mode portrait, 2ème layout si l'appareil est en mode paysage).

Voici le résultat que l'on souhaiterait obtenir en mode paysage :

Exercice 3 - Problème

Créez une classe SortPuzzle disposant d'un constructeur adéquat et de deux getters : l'un pour obtenir l'intitulé de la question et l'autre pour récupérer la liste des réponses (dans le bon ordre).

Créez une interface SortPuzzleProvider retournant un problème à résoudre lorsqu'on l'interroge :
public interface SortPuzzleProvider {
	public SortPuzzle fetchPuzzle();
}
		

On implante maintenant le SortPuzzleProvider le plus simple qui soit qui ne fait que retourner un unique problème :
public class SimpleSortPuzzleProvider implements SortPuzzleProvider {
	public static final SortPuzzle DEFAULT_PUZZLE =
		new SortPuzzle("Trier ces capitales par population croissance",
			new String[] {"Moscou", "Jakarta", "Kinshasa", "Brasilia", "Sofia"});
			
	private SortPuzzle puzzle;
	
	public static final SimpleSortPuzzleProvider DEFAULT_INSTANCE = new SimpleSortPuzzleProvider(DEFAULT_PUZZLE);
	
	public SimpleSortPuzzleProvider(SortPuzzle puzzle) {
		this.puzzle = puzzle;
	}
			
	public SortPuzzle fetchPuzzle() {
		return puzzle;
	}
}
		

Exercice 4 - Affichage de la question et des items de réponse

GameActivity doit afficher la question et les items de réponse pour un problème donné. Le problème est communiqué par l'activité appelante dans l'Intent de lancement. Ce problème est un objet SortPuzzle présent dans l'entrée nommée puzzle du Bundle extras.

Quel est le pré-requis sur la classe SortPuzzle pour insérer une instance de SortPuzzle dans le Bundle d'un Intent ? On mettra en oeuvre ce pré-requis.

Si aucun SortPuzzle n'a été communiqué avec l'Intent de lancement (c'est le cas par exemple si l'activité a été lancée depuis l'écran d'accueil de l'appareil), on récupère un problème avec SimpleSortPuzzleProvider.DEFAULT_INSTANCE.fetchPuzzle() (on obtiendra donc toujours la même question à résoudre).

Affichez ensuite l'intitulé de la question et les différents items de réponse correspondant au SortPuzzle. On prendra le soin de préalablement mélanger les items de réponse.

Remarque : pour l'instant, on ne se préoccupe pas du contenu du TextView affichant le score maximal.

Exercice 5 - Déplacement des items

Pour déplacer un item de réponse, le joueur clique d'abord sur l'item de la liste à déplacer. Il clique ensuite sur un des boutons de déplacement (monter ou descendre) pour échanger l'item avec son prédécesseur ou son successeur. Il devra être possible bien sûr de réaliser successivement plusieurs actions de déplacement sur le même item sans avoir à le réselectionner sur la liste.

Implantez le déplacement des items.

On souhaite maintenant qu'un item sélectionné pour le déplacement présente un fond coloré spécifique sans compromettre toutefois la lisibilité du texte (par exemple avec un fond jaune et des caractères noirs).

Faites en sorte que l'item sélectionné de la liste ait ainsi une apparence différente des autres items.

Exercice 6 - Rotation de l'activité

L'utilisateur doit avoir la possibilité de tourner l'appareil Android sans que la partie de jeu courante soit perdue.

Implantez le code nécessaire afin que le classement des items soit conservé lors de la rotation.

Exercice 7 - Validation de la réponse

Lorsque le joueur estime avoir bien classé les différents items, il peut valider sa réponse. Il clique pour cela sur le bouton de validation. On vérifie alors si le classement proposé correspond avec la solution présente dans SortPuzzle. Pour déterminer le score attribué au joueur, on calcule la distance de Kendall-Tau de la permutation des items qu'il a proposé. Si l'on considère tous les couples d'items, la valeur de la distance est le nombre de couples mal-ordonnés (ce qui correspond au nombre d'échanges à réaliser lors d'un tri à bulles pour réordonner correctement la liste). Comme l'on souhaite attribuer un score croissant en fonction des performances du joueur, le score adopté est la différence entre la distance maximale de Kendall-Tau si tous les couples étaient désordonnés (obtenue en cas de tri inverse) et la distance de Kendall-Tau pour la proposition du joueur.

Ainsi par exemple pour une liste de 5 items, le score maximal obtenable par le joueur est 10 si tous les items sont bien classés. Le joueur obtiendra au minimum un score de 0 si les items sont classés dans l'ordre inverse.

La classe qui est fournie ici dispose de méthodes statiques pour réaliser le calcul de score.

Faites en sorte que le score maximal théorique atteignable par le joueur soit affiché en permanence sur la TextView correspondante.

Faites également en sorte que le clic sur le bouton de validation provoque l'affichage d'un Toast avec le score obtenu pour la proposition du joueur.

Exercice 8 - Récupération des problèmes sur le web

Proposer toujours le même problème à résoudre au joueur n'est pas très intéressant. Ainsi nous lui proposons la possibilité de récupérer de nouveaux problèmes fournis depuis un service web.

Le service web accessible à l'adresse http://igm.univ-mlv.fr/~chilowi/data/sortgame/ retourne à chaque appel une nouvelle énigme. Vous pouvez tester des appels à cette URL depuis n'importe quel navigateur pour constater que le problème est retourné sous la forme d'un document texte UTF-8 dont la première ligne est l'intitulé de la question et les lignes suivantes les items de réponses exprimés dans le bon ordre.

Écrivez une classe WebSortPuzzleProvider dont la méthode fetchPuzzle() retourne un problème récupéré depuis le service web indiqué précédemment.

Rajoutez un bouton sur l'activité afin de commencer une nouvelle partie avec une énigme fournie par SortPuzzleWebProvider. Attention, fetchPuzzle() peut potentiellement présenter un temps d'exécution important et il n'est pas question de bloquer l'interface graphique de l'activité !

Exercice 9 - Écran de fin

Créez une nouvelle activité (dont l'agencement est libre) qui sera affichée lors de la validation de la réponse à la place du toast. Cette activité indiquera le score obtenu ainsi que la liste des items classée correctement.