Chapitre 10 - Département d`informatique et de génie logiciel
Transcription
Chapitre 10 - Département d`informatique et de génie logiciel
Solutions du chapitre 10 Caractères et chaînes de caractères Note: les exercices 10.3 à 10.6 lancent des défis raisonnables et accessibles. Lorsque vous aurez résolu ces problèmes, vous devriez être capable de mettre en oeuvre la plupart des jeux de cartes populaires sans difficulté. 10.3 Modifiez le programme de la figure 10.21 pour que la méthode de brassage des cartes distribue une main de cinq cartes du poker. Puis écrivez les méthodes supplémentaires suivantes: a) Déterminer si la main contient une paire. b) Déterminer si la main contient deux paires. c) Déterminer si la main contient trois cartes identiques (par exemple trois valets). d) Déterminer si la main contient quatre cartes identiques (par exemple quatre as). e) Déterminer si la main contient un flush, c’est-à-dire toutes les cinq cartes d’une même couleur. f) Déterminer si la main contient une suite, c’est-à-dire cinq cartes qui se suivent. g) Déterminer si la main contient un full, c’est-à-dire deux cartes d’une même valeur et trois cartes d’une autre valeur. RÉP.: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 // Solution de l’exercice 10.3. // Poker.java // Programme de brassage et de distribution de cartes. import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Poker extends JFrame { private Carte jeu[]; private Carte main[]; private int carteCourante; private JButton boutonDistribution, boutonBrassage; private JTextField affichageCarte; private JLabel etat; private int nombres[]; private String faces[], couleurs[], sortie; public Poker() { super( "Programme de distribution de cartes" ); String f[] = { "As", "Deux", "Trois", "Quatre", "Cinq", "Six", "Sept", "Huit", "Neuf", "Dix", "Valet", "Dame", "Roi" }; String c[] = { "Coeur", "Carreau", "Trèfle", "Pique" }; faces = f; couleurs = c; nombres = new int[ 13 ]; jeu = new Carte[ 52 ]; main = new Carte[ 5 ]; COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 carteCourante = -1; for ( int i = 0; i < jeu.length; i++ ) jeu[ i ] = new Carte( faces[ i % 13 ], couleurs[ i / 13 ] ); Container p = getContentPane(); p.setLayout( new FlowLayout() ); boutonDistribution = new JButton( "Distribuer main" ); boutonDistribution.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { affichageCarte.setText( "" ); // Effacer zone de texte. sortie = ""; for ( int n = 0; n < main.length; n++ ) { Carte distributionFaite = distribuerCartes(); if ( distributionFaite != null ) { main[ n ] = distributionFaite; affichageCarte.setText( affichageCarte.getText() + main[ n ].toString() + "\n" ); } else { affichageCarte.setText( "PLUS DE CARTE À DISTRIBUER" ); etat.setText( "Brasser cartes pour continuer" ); } } totalMain(); paire(); brelan(); carre(); suite(); flush(); // Calcule le contenu de la main. } } ); p.add( boutonDistribution ); boutonBrassage = new JButton( "Brasser cartes" ); boutonBrassage.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { affichageCarte.setText( "BRASSAGE ..." ); brasser(); affichageCarte.setText( "JEU BRASSÉ" ); } } ); p.add( boutonBrassage ); affichageCarte = new JTextField( 20 ); affichageCarte.setEditable( false ); p.add( affichageCarte ); etat = new JLabel(); p.add( etat ); setSize( 275, 250 ); show(); // Définit la taille de la fenêtre. // Montre la fenêtre. COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 } public void brasser() { carteCourante = -1; for ( int i = int j = ( Carte temp jeu[ i ] = jeu[ j ] = } 0; i < jeu.length; i++ ) { int ) ( Math.random() * 52 ); = jeu[ i ]; // Permuter jeu[ j ]; // les temp; // cartes. boutonDistribution.setEnabled( true ); } public Carte distribuerCartes() { if ( ++carteCourante < jeu.length ) return jeu[ carteCourante ]; else { boutonDistribution.setEnabled( false ); return null; } } private void totalMain() { for ( int x = 0; x < faces.length; x++ ) nombres[ x ] = 0; for ( int h = 0; h < main.length; h++ ) for ( int f = 0; f < faces.length; f++ ) if ( main[ h ].getFace().equals( faces[ f ] ) ) ++nombres[ f ]; } public void paire() { for ( int k = 0; k < faces.length; k++ ) if ( nombres[ k ] == 2 ) sortie += ( "Paire de " + faces[ k ] + " etat.setText( sortie ); } public void brelan() { for ( int k = 0; k < faces.length; k++ ) if ( nombres[ k ] == 3 ) { sortie += ( "Brelan de " + faces[ k ] ); break; } etat.setText( sortie ); } public void carre() { for ( int k = 0; k < faces.length; k++ ) if ( nombres[ k ] == 4 ) sortie += ( "Carré de " + faces[ k ] ); etat.setText( sortie ); } public void flush() " ); COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 { String laCouleur = main[ 0 ].getCouleur(); for ( int s = 1; s < main.length; s++ ) if ( main[ s ].getCouleur().compareTo( laCouleur ) != 0 ) return; // Pas un flush. sortie += ( "Flush en " + laCouleur ); etat.setText( sortie ); } public void suite() { int emplacements[] = new int[ 5 ], z = 0; for ( int y = 0; y < nombres.length; y++ ) if ( nombres[ y ] == 1 ) emplacements[ z++ ] = y; triParBulles( emplacements ); int valeurFace = emplacements[ 0 ]; for ( int m = 1; m < emplacements.length; m++ ) { if ( valeurFace != emplacements[ m ] - 1 ) return; // Pas de suite. else valeurFace = emplacements[ m ]; } sortie += "Suite "; etat.setText( sortie ); } private void triParBulles( int valeurs[] ) { for ( int pass = 1; pass < valeurs.length; pass++ ) for ( int comp = 0; comp < valeurs.length - 1; comp++ ) if ( valeurs[ comp ] > valeurs[ comp + 1 ] ) { int temp = valeurs[ comp ]; valeurs[ comp ] = valeurs[ comp + 1 ]; valeurs[ comp + 1 ] = valeurs[ comp ]; } } public static void main( String args[] ) { Poker app = new Poker(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } class Carte { private String face; private String couleur; public Carte( String f, String c ) { COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 235 236 237 238 239 240 241 242 face = f; couleur = c; } protected String getCouleur() { return couleur; } protected String getFace() { return face; } public String toString() { return face + " de " + couleur; } } 10.4 Utilisez les méthodes développées à l’exercice 10.3 pour écrire un programme qui distribue deux mains de cinq cartes du poker, évalue chaque main, et détermine laquelle des deux est la meilleure. RÉP.: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 // Solution de l’exercice 10.4. // Poker2.java // Ce programme distribue deux mains du Poker. import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Poker2 extends JFrame { private Carte jeu[], main[], main2[]; private int carteCourante; private JButton boutonDistribution, boutonBrassage; private JTextArea affichageCarte, affichageCarte2; private JLabel etat; private String faces[], couleurs[], sortie; private int nombres[], nombres2[]; private int valeurHaute, valeurHaute2, groupe, groupe2; private boolean suiteDansMain, suiteDansMain2; private final int UNEPAIRE = 2; private final int DEUXPAIRES = 4; private final int BRELAN = 6; private final int SUITE = 8; private final int QUINTE = 10; private final int CARRE = 12; private final int QUINTEROYALE = 14; public Poker2() { super("Programme de distribution de cartes"); String f[] = { "As", "Deux", "Trois", "Quatre", "Cinq", "Six", "Sept", "Huit", "Neuf", "Dix", "Valet", "Dame", "Roi" }; String s[] = { "Coeur", "Carreau", "Trèfle", "Pique" }; faces = f; couleurs = s; nombres = new int[ 13 ]; nombres2 = new int[ 13 ]; main = new Carte[ 5 ]; COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 main2 = new Carte[ 5 ]; jeu = new Carte[ 52 ]; carteCourante = -1; for ( int i = 0; i < jeu.length; i++ ) jeu[ i ] = new Carte( faces[ i % 13 ], couleurs[ i / 13 ] ); Container p = getContentPane(); p.setLayout( new FlowLayout() ); boutonDistribution = new JButton( "Distribuer main" ); boutonDistribution.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { affichageCarte.setText( "" ); // Effacer zone de texte. affichageCarte2.setText( "" ); // Effacer zone de texte. sortie = ""; for ( int n = 0; n < main.length; n++ ) { Carte distributionFaite = distribuerCartes(); if ( distributionFaite != null ) { main[ n ] = distributionFaite; affichageCarte.setText( affichageCarte.getText() + main[ n ].toString() + "\n" ); } else { affichageCarte.setText("PLUS DE CARTE À DISTRIBUER" ); etat.setText("Brasser cartes pour continuer" ); } } for ( int n = 0; n < main2.length; n++ ) { Carte distributionFaite = distribuerCartes(); if ( distributionFaite != null ) { main2[ n ] = distributionFaite; affichageCarte2.setText( affichageCarte2.getText() + main2[ n ].toString() + "\n" ); } else { affichageCarte2.setText("PLUS DE CARTE À DISTRIBUER" ); etat.setText("Brasser cartes pour continuer" ); } } totalMain(); paire(); brelan(); carre(); suite(); flush(); // Calcule le contenu de la main. if ( groupe > groupe2 ) etat.setText( "La main du haut est meilleure" ); else if ( groupe < groupe2 ) etat.setText( "La main du bas est meilleure" ); else { // Tester la carte supérieure. // Cette solution ne vérifie pas la carte supérieure suivante. // Vous pourriez ajouter cette faculté. if ( valeurHaute > valeurHaute2 ) etat.setText( "La main du haut est meilleure." ); else if ( valeurHaute < valeurHaute2 ) COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 etat.setText( "La main du bas est meilleure." ); else etat.setText( "Jeux égaux." ); } } } ); p.add( boutonDistribution ); boutonBrassage = new JButton( "Brasser cartes" ); boutonBrassage.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { affichageCarte.setText( "BRASSAGE ..." ); affichageCarte2.setText( "" ); brasser(); affichageCarte.setText( "JEU BRASSÉ" ); } } ); p.add( boutonBrassage ); affichageCarte = new JTextArea( 8, 20 ); affichageCarte.setEditable( false ); affichageCarte2 = new JTextArea( 8, 20 ); affichageCarte2.setEditable( false ); p.add( affichageCarte ); p.add( affichageCarte2 ); etat = new JLabel(); p.add( etat ); setSize( 275, 400 ); show(); // Définir la taille de la fenêtre. // Montrer la fenêtre. } public void brasser() { carteCourante = -1; for ( int i = 0; i < jeu.length; i++ ) { int j = ( int ) ( Math.random() * 52 ); Carte temp = jeu[ i ]; jeu[ i ] = jeu[ j ]; jeu[ j ] = temp; } boutonDistribution.setEnabled( true ); } public Carte distribuerCartes() { if ( carteCourante > 50 ) { boutonDistribution.setEnabled( false ); return null; } else if ( ++carteCourante < jeu.length ) return jeu[ carteCourante ]; return null; // Inutilisée sur le plan logique, nécessaire au seul compilateur. } private void totalMain() { for ( int x = 0; x < faces.length; x++ ) nombres[ x ] = nombres2[ x ] = 0; COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 for ( int h = 0; h < main.length; h++ ) for ( int f = 0; f < faces.length; f++ ) { if ( main[ h ].getFace().equals( faces[ f ] ) ) { ++nombres[ f ]; if ( f == 0 ) valeurHaute = 15; // Valeur spéciale de l’as. if ( f > valeurHaute ) valeurHaute = f; } if ( main2[ h ].getFace().equals( faces[ f ] ) ) { ++nombres2[ f ]; if ( f == 0 ) valeurHaute2 = 15; // Valeur spéciale de l’as. if ( f > valeurHaute2 ) valeurHaute2 = f; } } } public void paire() { int c = 0, c2 = 0, haut = 0, haut2 = 0; for ( int k = 0; k < faces.length; k++ ) { if ( nombres[ k ] == 2 ) { if ( k == 0 ) haut = 15; // Valeur spéciale de l’as. if ( haut < k ) haut = k; c++; } if ( nombres2[ k ] == 2 ) { if ( k == 0 ) haut2 = 15; // Valeur spéciale de l’as. if ( haut2 < k ) haut2 = k; c2++; } } if ( c != 0 && c2 != 0 && c == c2 ) { if ( c == 1 && c2 == 1 ) { groupe = UNEPAIRE; groupe2 = UNEPAIRE; } else { // deux pairs groupe = DEUXPAIRES; groupe2 = DEUXPAIRES; } if ( haut > haut2 ) groupe++; else if ( haut < haut2 ) groupe2++; } else if ( c > c2 && c == 1 ) COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 groupe = UNEPAIRE; else if ( c > c2 && c == 2 ) { groupe = DEUXPAIRES; if ( c2 == 1 ) groupe2 = UNEPAIRE; } else if ( c < c2 && c2 == 1 ) groupe2 = UNEPAIRE; else if ( c < c2 && c2 == 2 ) { groupe2 = DEUXPAIRES; if ( c == 1 ) groupe = UNEPAIRE; } } public void brelan() { int haut = 0, haut2 = 0; boolean drapeau = false, drapeau2 = false; for ( int k = 0; k < faces.length; k++ ) { if ( nombres[ k ] == 3 ) { groupe = BRELAN; drapeau = true; if ( k == 0 ) haut = 15; // Valeur spéciale de l’as. if ( k > haut ) haut = k; } if ( nombres2[ k ] == 3 ) { groupe2 = BRELAN; drapeau2 = true; if ( k == 0 ) haut2 = 15; // Valeur spéciale de l’as. if ( k > haut2 ) haut2 = k; } } if ( drapeau == true && drapeau2 == true ) if ( haut > haut2 ) groupe++; else if ( haut < haut2 ) groupe2++; } public void carre() { int haut = 0, haut2 = 0; boolean drapeau = false, drapeau2 = false; for ( int k = 0; k < faces.length; k++ ) { if ( nombres[ k ] == 4 ) { groupe = CARRE; drapeau = true; if ( k == 0 ) haut = 15; if ( k > haut ) // Valeur spéciale de l’as. COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 haut = k; } if ( nombres2[ k ] == 4 ) { groupe2 = CARRE; drapeau2 = true; if ( k == 0 ) haut2 = 15; // Valeur spéciale de l’as. if ( k > haut2 ) haut2 = k; } } if ( drapeau == true && drapeau2 == true ) if ( haut > haut2 ) groupe++; else if ( haut < haut2 ) groupe2++; } public void flush() { String laCouleur = main[ 0 ].getCouleur(); boolean drapeau1 = true, drapeau2 = true; int haut = 0, haut2 = 0; for ( int s = 1; s < main.length && drapeau1 == true; s++ ) if ( main[ s ].getCouleur().compareTo( laCouleur ) != 0 ) drapeau1 = false; // Pas de flush. for ( int s = 1; s < main.length && drapeau2 == true; s++ ) if ( main2[ s ].getCouleur().compareTo( laCouleur ) != 0 ) drapeau2 = false; // Pas de flush. if ( drapeau1 == true ) { groupe = QUINTE; if ( suiteDansMain == true ) groupe = QUINTEROYALE; } if ( drapeau2 == true ) { groupe2 = QUINTE; if ( suiteDansMain2 == true ) groupe2 = QUINTEROYALE; } } public void suite() { int emplacements[] = new int[ 5 ], emplacements2[] = new int[ 5 ], z = 0, z2 = 0; for ( int y = 0; y < nombres.length; y++ ) { if ( nombres[ y ] == 1 ) emplacements[ z++ ] = y; if ( nombres[ y ] == 1 ) emplacements2[ z2++ ] = y; } triParBulles( emplacements ); triParBulles( emplacements2 ); COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 int valeurFace = emplacements[ 0 ]; boolean drapeau1 = true, drapeau2 = true; for ( int m = 1; m < emplacements.length && drapeau1 == true; m++ ) { if ( valeurFace != emplacements[ m ] - 1 ) drapeau1 = false; // Pas une suite. else valeurFace = emplacements[ m ]; } valeurFace = emplacements2[ 0 ]; for ( int m = 1; m < emplacements.length && drapeau2 == true; m++ ) { if ( valeurFace != emplacements2[ m ] - 1 ) drapeau2 = false; // Pas une suite. else valeurFace = emplacements2[ m ]; } if ( drapeau1 == true ) { suiteDansMain = true; groupe = SUITE; } if ( drapeau2 == true ) { suiteDansMain2 = true; groupe2 = SUITE; } } private void triParBulles( int valeurs[] ) { for ( int passe = 1; passe < valeurs.length; for ( int comp = 0; comp < valeurs.length if ( valeurs[ comp ] > valeurs[ comp + int temp = valeurs[ comp ]; valeurs[ comp ] = valeurs[ comp + 1 valeurs[ comp + 1 ] = valeurs[ comp } } passe++ ) - 1; comp++ ) 1 ] ) { ]; ]; public static void main( String args[] ) { Poker2 app = new Poker2(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } class Carte { private String face; private String couleur; public Carte( String f, String s ) { face = f; couleur = s; } COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 443 444 445 446 447 public String getFace() { return face; } public String getCouleur() { return couleur; } public String toString() { return face + " de " + couleur; } } 10.5 Modifiez le programme développé à l’exercice 10.4 pour qu’il simule le distributeur. La main de cinq cartes que donne le distributeur est face au sol, de sorte que le joueur ne peut en voir le contenu. Le programme doit ensuite évaluer la main du distributeur et, selon la qualité de la main, le distributeur doit jeter une, deux ou trois cartes pour les remplacer par le nombre correspondant de nouvelles cartes. Le programme doit ensuite réévaluer la main du distributeur. Attention: ceci est un problème vraiment difficile! 10.6 Modifiez le programme développé à l’exercice 10.5 pour qu’il puisse traiter automatiquement la main du distributeur, mais le joueur est autorisé à décider quelles cartes il veut remplacer dans sa main. Le programme doit alors évaluer les deux mains et déterminer laquelle des deux gagne. Utilisez ensuite ce programme pour jouer vingt fois contre l’ordinateur. Qui, de vous ou de l’ordinateur, gagne le plus de parties? Faites jouer un de vos amis vingt fois contre l’ordinateur. Qui de lui ou de l’ordinateur gagne le plus de parties? Sur base des résultats de ces parties, effectuez quelques modifications appropriées pour affiner le programme de jeu de poker, ce qui constitue un problème difficile aussi. Jouez de nouveau vingt parties. Le programme joue-t-il mieux cette fois? 10.7 10.8 10.9 10.10 (Limericks) Le limerick est un épigramme burlesque en cinq vers, dans lequel les première et deuxième lignes riment avec la cinquième, et où la troisième ligne rime avec la quatrième. Reprenez les techniques développées à l’exercice 10.9, pour écrire un programme Java capable de produire des limericks aléatoires. Le peaufinage de ce programme pour qu’il génère de bons limericks constitue un défi mais le résultat en vaut la peine! 10.11 (Latin enroulé) Écrivez une application qui encode des phrases de la langue française en latin enroulé. Le latin enroulé est une sorte de langage codé dont le but est souvent ludique. De nombreuses variantes existent pour la formation de phrases en latin enroulé. Pour simplifier, utilisez l’algorithme suivant: Pour former une phrase en latin enroulé à partir d’une phrase en français, découpez la phrase en mots à l’aide d’un objet de la classe StringTokenizer, placez la première lettre du mot français à la fin du mot et ajoutez les lettres «fe.» Ainsi, le mot «saut» devient «autsfe,» le mot «le» devient «elfe,» et le mot «ordinateur» devient «rdinateurofe.» Les espaces entre les mots demeurent tels quels. Fondez votre approche sur les hypothèses que la phrase française est constituée de mots séparés par des espaces, qu’aucun signe de ponctuation n’y existe et que tous les mots ont au moins deux lettres. La méthode afficheMotLatin doit afficher chaque mot. Chaque jeton renvoyé par nextToken est transmis à la méthode afficheMotLatin pour qu’elle affiche le mot en latin enroulé. Permettez à l’utilisateur d’introduire sa propre phrase. Conservez un affichage progressif de toutes les phrases converties dans une zone de texte. RÉP.: 1 2 3 // Solution de l’exercice 10.11. // LatinEnroule.java // Ce programme traduit du français en latin enroulé. COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import import import import javax.swing.*; java.util.*; java.awt.*; java.awt.event.*; public class LatinEnroule extends JFrame { private JLabel invite; private JTextField entree; private JTextArea sortie; private int compteur; public LatinEnroule() { super( "Générateur de latin enroulé" ); invite = new JLabel( "Entrer une phrase en français:" ); entree = new JTextField( 30 ); entree.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { String s = e.getActionCommand().toString(); StringTokenizer jetons = new StringTokenizer( s ); compteur = jetons.countTokens(); while ( jetons.hasMoreTokens() ) { compteur--; afficherMotLatin( jetons.nextToken() ); } } } ); sortie = new JTextArea( 10, 30 ); sortie.setEditable( false ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); c.add( invite ); c.add( entree ); c.add( sortie ); setSize( 375, 300 ); show(); } private void afficherMotLatin( String token ) { char lettres[] = token.toCharArray(); StringBuffer latinEnroule = new StringBuffer(); latinEnroule.append( lettres, 1, lettres.length - 1 ) ; latinEnroule.append( Character.toLowerCase( lettres[ 0 ] ) ); latinEnroule.append( "fe" ); sortie.append( latinEnroule.toString() + " " ); if ( compteur == 0 ) sortie.append( "\n" ); } public static void main( String args[] ) { LatinEnroule app = new LatinEnroule(); app.addWindowListener( new WindowAdapter() { COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 71 72 73 74 75 76 77 78 public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } 10.12 10.13 Écrivez une application qui entre une ligne de texte, la découpe par un objet de la classe StringTokenizer et affiche les jetons dans l’ordre inverse. RÉP.: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 // Solution de l’exercice 10.13. // TestJetons.java // Ce programme affiche les jetons dans l’ordre inverse. import javax.swing.*; import java.awt.*; import java.util.*; import java.awt.event.*; public class TestJetons extends JFrame{ private JLabel invite; private JTextField entree; private JTextArea sortie; public TestJetons() { invite = new JLabel( "Entrer une phrase et appuyer sur Entrée" ); entree = new JTextField( 50 ); entree.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e) { String s[]; String chaineADecouper = e.getActionCommand().toString(); StringTokenizer jetons = new StringTokenizer( chaineADecouper ); sortie.setText( "" ); int compteur = jetons.countTokens(); s = new String[ compteur ]; int i = compteur - 1; sortie.append( "Nombre d’éléments: " + compteur + "\nLes jetons sont:\n" ); while ( jetons.hasMoreTokens() ) s[ i-- ] = jetons.nextToken(); COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 for ( int k = 0; k < compteur; k++ ) sortie.append( s[ k ] + "\n" ); } } ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); sortie = new JTextArea( 10, 30 ); sortie.setEditable( false ); c.add( invite ); c.add( entree ); c.add( sortie ); setSize( 570, 360 ); show(); } public static void main( String args[] ) { TestJetons app = new TestJetons(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } 10.14 10.15 10.16 Écrivez une application qui entre plusieurs lignes de texte et un caractère de recherche, puis utilise la méthode indexOf de String pour déterminer le nombre d’occurrences du caractère dans le texte. RÉP.: 1 2 3 4 5 // Solution de l’exercice 10.16. // Index.java // Ce programme sort le nombre d’occurrences trouvées d’un caractère de recherche. import javax.swing.*; import java.awt.*; COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import java.awt.event.*; public class Index extends JFrame { private JTextField entreeCle; private JLabel inviteCle; private JTextArea entree; private int compteur; public Index() { super( "Recherche de caractère" ); entreeCle = new JTextField( 4 ); entreeCle.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { compteur = 0; String cle = e.getActionCommand().toString(); String s = entree.getText(); int dernier = -2, courant = 0; for ( int j = -1; j < s.length(); ) { courant = s.indexOf( cle.charAt( 0 ), ++j ); if ( courant != -1 && courant != dernier ) { dernier = courant; compteur++; } } JOptionPane.showMessageDialog( null, "Le nombre de " + cle.charAt( 0 ) + " est de : " + compteur, "Résultats", JOptionPane.INFORMATION_MESSAGE ); } } ); inviteCle = new JLabel( "Entrer un caractère:" ); entree = new JTextArea( 4, 20 ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); c.add( inviteCle ); c.add( entreeCle ); c.add( entree ); setSize( 375, 150 ); show(); } public static void main( String args[] ) { Index app = new Index(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 10.17 Écrivez une application basée sur le programme de l’exercice 10.16 qui entre plusieurs lignes de texte et utilise la méthode indexOf de String pour déterminer le nombre total d’occurrences de chaque lettre de l’alphabet dans le texte. Comptez ensemble les bas de casse et les capitales. Calculez et mémorisez les totaux de chaque lettre dans un tableau, puis affichez les valeurs sous forme tabulaire à la fin de la détermination. RÉP.: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 // Solution de l’exercice 10.17. // Index2.java // Ce programme le nombre d’occurrence de chaque caractère de l’alphabet // dans une phrase. import javax.swing.*; import java.util.*; import java.awt.*; import java.awt.event.*; public class Index2 extends JFrame { private JLabel invite; private JTextArea entree, sortie; private JButton b; private int compteur; public Index2() { b = new JButton( "Cliquer ici pour entrer le texte" ); b.addActionListener( new ActionListener () { public void actionPerformed( ActionEvent e ) { compteur = 0; sortie.setText( "" ); String alphabet = "abcdefghijklmnopqrstuvwxyz"; String s = entree.getText().toLowerCase(); int dernier = -2, courant = 0; int compteur[] = new int[ 26 ]; for ( int j = 0; j < alphabet.length(); j++ ) { for ( int k = 0; k < s.length() - 1; k++ ) { courant = s.indexOf( alphabet.charAt( j ), k ); if ( courant != -1 && courant != dernier ) { dernier = courant; compteur[ j ]++; k = courant; // optimisation. } } dernier = -2; } for ( int y = 0; y < compteur.length; y++ ) sortie.append( alphabet.charAt( y ) + ": compteur[ y ] + "\n" ); } } ); invite = new JLabel( "Entrer un texte quelconque:" ); " + COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 entree = new JTextArea( 4, 20 ); sortie = new JTextArea( 5, 10 ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); c.add( invite c.add( entree c.add( b ); c.add( sortie setSize( 200, show(); ); ); ); 150 ); } public static void main( String args[] ) { Index2 app = new Index2(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } 10.18 Écrivez une application qui lise une suite de chaînes et ne sorte que celles qui commencent par la lettre «b». Affichez les résultats dans une zone de texte à l’écran. RÉP.: 1 2 3 4 5 // Solution de l’exercice 10.18. // PremierB.java // Ce programme sort les chaînes qui commencent par "b". import javax.swing.*; import java.awt.*; COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 import java.awt.event.*; public class PremierB extends JFrame { private JTextField entree; private JLabel invite; private JTextArea affichage; public PremierB() { super( "PremierB" ); entree = new JTextField( 20 ); entree.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { String s = e.getActionCommand().toString(); if ( s.startsWith( "b" ) ) affichage.append( s + "\n" ); entree.setText( "" ); } } ); invite = new JLabel( "Entrer une chaîne:" ); affichage = new JTextArea( 4, 20 ); affichage.setEditable( false ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); c.add( invite ); c.add( entree ); c.add( affichage ); setSize( 375, 150 ); show(); } public static void main( String args[] ) { PremierB app = new PremierB(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } 10.19 Écrivez une application qui lise une suite de chaînes et n’affiche que celles qui se terminent par les lettres «NÉ». Les résultats apparaîtront dans une zone de texte à l’écran. RÉP.: COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 // Solution de l’exercice 10.19. // DernierNe.java // Ce programme sort les chaînes qui se terminent par "NÉ". import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DernierNe extends JFrame { private JTextField entree; private JLabel invite; private JTextArea affichage; public DernierNe() { super("LastEd"); entree = new JTextField( 20 ); entree.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { String s = e.getActionCommand().toString(); if ( s.endsWith( "NÉ" ) ) affichage.append( s + "\n" ); entree.setText( "" ); } } ); invite = new JLabel( "Entrer une chaîne:" ); affichage = new JTextArea( 4, 20 ); affichage.setEditable( false ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); c.add( invite ); c.add( entree ); c.add( affichage ); setSize( 375, 150 ); show(); } public static void main( String args[] ) { DernierNe app = new DernierNe(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); } } COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. 10.20 Écrivez une application qui entre le code entier d’un caractère et en affiche le caractère correspondant. Modifiez ce programme pour qu’il génère tous les codes en trois chiffres compris entre 000 et 255, et tente ensuite d’afficher les caractères correspondants. Affichez les résultats dans une zone de texte. 10.21 10.22 Écrivez un programme qui demande à l’utilisateur un mot de cinq lettres et génère tous les mots de trois lettres possibles dérivés de celui de cinq lettres. Par exemple, les mots de trois lettres d’usage fréquent obtenus à partir du mot «banni» sont «ban» et «bai». Section spéciale: exercices avancés de manipulation de chaînes de caractères Les exercices qui précèdent sont dévoués au texte et conçus pour tester la compréhension du lecteur des concepts fondamentaux de la manipulation de chaînes de caractères. Cette section comprend une collection d’exercices de manipulation de chaînes, de niveau moyen à avancé. Les aspects de défi mais aussi de détente qu’apportent ces exercices n’échapperont pas au lecteur attentif. Les problèmes varient en difficulté: certains ne demandent qu’une ou deux heures de programmation pour leur achèvement, tandis que d’autres constituent de vrais travaux pratiques de laboratoire d’informatique, qui peuvent demander de deux à trois semaines d’étude et de réalisation. Certains encore constituent des projets de fin de session. 10.23 (Analyseur de texte) L’accès à des ordinateurs dotés de possibilités de manipulation de chaînes de caractères ont entraîné la naissance d’approches intéressantes dans l’analyse des textes des grands auteurs. Une grande attention a été ainsi portée sur la question de savoir si William Shakespeare a effectivement vécu. Quelques bacheliers croient en une certaine évidence que Christopher Marlowe ou d’autres auteurs ont en fait écrit des pièces principales attribuées à Shakespeare. Des chercheurs ont employé des ordinateurs pour tenter de trouver des similitudes entre les textes de ces deux auteurs. Cet exercice examine trois méthodes d’analyse de texte par informatique. a) Écrivez une application qui lise plusieurs lignes de texte au clavier et affiche une table qui contient le nombre d’occurrences de chacune des lettres de l’alphabet dans ce texte. Par exemple, la phrase To be, or not vers be: that is the question: contient un «a», deux «b», aucun «c», et ainsi de suite. b) Écrivez une application qui lise plusieurs lignes de texte et affiche un tableau contenant le nombre de mots d’une seule lettre, de deux lettres, de trois lettres, et ainsi de suite, qui apparaissent dans le texte. Par exemple, la phrase Whether 'tis nobler in the mind vers suffer contient Longueur de mot Occurrences 1 0 2 2 3 1 4 2 (y compris 'tis) 5 0 6 2 7 1 c) Écrivez une application qui demande plusieurs lignes de texte et affiche un tableau de regroupement des nombres d’occurrences de chaque mot différent dans le texte. Une première version de ce programme inclut dans le tableau les mots dans l’ordre où ils apparaissent dans le texte. Par exemple, les lignes COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. To be, or not vers be: that is the question: Whether 'tis nobler in the mind vers suffer contiennent trois fois le mot «vers», deux fois le mot «be», une fois le mot «or», etc. Un listing plus intéressant, et utile d’ailleurs, doit reprendre les mots dans l’ordre alphabétique. 10.24 10.25 (Protection de chèque) L’informatique vient au secours des systèmes de vérification de chèques intégrés aux applications de paie et de gestion de comptes bancaires. Les histoires étranges ne manquent pas, qui mentionnent des virements de fin de mois payés par erreur pour des montants supérieurs à 1 million de dollars. De telles erreurs de montants imprimés dans les systèmes d’édition de chèques ou de virements sont bien souvent le fait d’erreurs humaines et (ou) imputables à des machines. Les concepteurs de logiciels ont donc produit des contrôles dans leurs systèmes pour éviter l’émission de tels montants erronés. Une autre problème plus grave suppose une altération volontaire et malintentionnée du montant du chèque par quelqu’un qui tente de toucher un chèque dans le cadre d’une fraude. Pour éviter l’altération frauduleuse du montant d’un chèque, la plupart des systèmes informatisés de génération de chèques ou de virements utilisent une technique dite de protection de chèque. Les chèques et virements destinés à la génération informatique comportent un nombre fixe d’espaces dans lesquels l’ordinateur imprime un montant. Supposons qu’un chèque de paie contienne huit espaces vierges dans lesquels l’ordinateur est susceptible d’inscrire le montant du salaire d’un employé. Si le montant est important, alors les huit cases seront remplies, comme par exemple, dans: 1.230,60 (montant chèque) -------12345678 (numéros de position) Par contre, si le montant est inférieur à 1000 $, alors plusieurs espaces seront inoccupés. Par exemple, le montant 99,87 -------12345678 contient trois espaces vierges. Si un chèque est imprimé avec des espaces libres, il est facile, pour une personne malintentionnée, d’altérer le montant supposé du chèque. Pour éviter ce risque, nombre de logiciels de génération de chèques occupent les espaces vierges par des astérisques d’en-tête qui n’interviennent pas dans le montant du chèque lorsqu’il est touché mais qui occupent les cases vierges, comme suit: ***99,87 -------12345678 Écrivez une application qui entre un montant en dollars à imprimer sur un chèque et affiche le montant au format de protection de chèque avec le nombre d’astérisques d’en-tête nécessaires. Supposez que neuf espaces sont disponibles pour l’impression du montant. Vous devez aussi écrire une virgule et non un point décimal. 10.26 (Écriture en lettres de l’équivalent du montant d’un chèque) SI nous poursuivons la discussion entamée à l’exercice précédent, nous pouvons insister sur l’importance de bien concevoir les logiciels d’écriture de chèques et de virements, pour éviter toute malversation dans l’utilisation de ces documents. Une autre méthode de sécurité fréquente impose que le montant du chèque soit écrit non seulement en chiffres mais également en lettres, où le montant est épelé correctement en français. Dans ce cas, même si quelqu’un parvenait à trafiquer le montant en chiffres, il aurait beaucoup de difficultés à altérer celui indiqué en lettres. La majorité des programmes de génération de chèques n’impriment pas les montants des chèques en lettres; ceci sans doute parce que peu de langages de programmation de haut niveau utilisés pour bâtir les applications commerciales disposent des fonctionnalités nécessaires à la manipulation évoluée de chaînes de caractères. Une autre raison en est que la logique de l’écriture de l’équivalent en mots d’un montant est extrêmement complexe. Écrivez une application qui entre le montant numérique d’un chèque pour écrire en mots l’équivalent du montant. Par exemple, le montant 112.43 sera écrit ainsi: CENT DOUZE DOLLARS ET QUARANTE-TROIS CENTS 10.27 (Code Morse) Le code Morse est sans doute le plus fameux de tous les schémas de codage jamais développés. Il est dû à Samuel Morse qui l’a conçu en 1832 pour la télégraphie. Le code Morse associe une suite de points et de tirets («barres») à chaque lettre de l’alphabet, à chaque chiffre et à un nombre réduit de caractères de ponctuation tels que le point, la virgule, le double-point et le point-virgule. Dans les systèmes ultérieurs de transmission sonore, le point est représenté par un son court (lu par les opérateurs Morse comme «ti») tandis que la barre est représentée par un son long («tâ»). D’autres supports ont employé le code Morse, notamment par voie optique et par le biais de mouvements de drapeaux. COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. La séparation entre les mots est assurée par un espace ou, plus simplement par l’absence de point et de barre. Dans les systèmes de transmission sonore, un espace se marque par une courte interruption pendant laquelle aucun son n’est émis. La figure 10.22 reprend la version internationale du code Morse. Caractère Code Caractère Code A .- T - B -... U ..- C -.-. V ...- D -.. W .-- E . X -..- F ..-. Y -.-- G --. Z --.. H .... I .. Chiffres J .--- 1 .---- K -.- 2 ..--- L .-.. 3 ...-- M -- 4 ....- N -. 5 ..... O --- 6 -.... P .--. 7 --... Q --.- 8 ---.. R .-. 9 ----. S ... 0 ----- Figure 10.22 Les lettres de l’alphabet exprimées en code Morse international. Écrivez une application qui lise une phrase en langue française et l’encode en Morse. Écrivez aussi un programme qui lise une phrase en Morse et la convertisse en son équivalent en langue française. Utilisez un blanc entre chaque lettre codée en Morse et trois blancs entre chaque mot codé en Morse. 10.28 Section spéciale: des projets stimulants de manipulation de chaînes de caractères 10.29 (Projet: correcteur orthographique) La plupart des progiciels populaires de traitement de texte disposent de correcteurs orthographiques intégrés. Dans ce projet, vous devez développer votre propre utilitaire de vérification orthographique. Quelques suggestions vont vous permettre de démarrer ce travail. Vous devriez ajouter quelques possibilités supplémentaires. Vous vous faciliterez la tâche si vous utilisez un dictionnaire électronique existant comme source de mots. Pourquoi faisons-nous tant de fautes d’orthographe lorsque nous tapons? Parfois, nous ne connaissons tout simplement pas l’épellation exacte du mot : nous choisissons ce qui nous semble le plus probable. D’autres fois, c’est parce que nous inversons deux lettres (par ex., «fonciton» au lieu de «fonction»). Parfois encore, nous répétons accidentellement un caractère (par ex., «mannuel» au lieu de «manuel»). Parfois enfin, nous tapons une touche au clavier proche de celle voulue (par ex., «alyas» au lieu de «alias»), et ainsi de suite. Concevez et réalisez un programme de vérification orthographique en Java. Ce programme conservera en mémoire un tableau listeDeMots de chaînes de caractères. Faites en sorte que l’utilisateur saisisse ces chaînes au clavier. Note: le chapitre 17 introduit la gestion des fichiers. Si vous en avez la possibilité, récupérez les mots d’un vérificateur orthographique existant enregistrés dans un fichier. Le programme doit demander à l’utilisateur d’entrer un mot, puis il doit rechercher ce mot dans la listeDeMots. Si le mot s’y trouve, le programme affiche le message «Le mot est épelé correctement». Si le mot est absent du tableau, le programme affiche «Le mot n’est pas épelé correctement.» Puis il doit tenter de trouver d’autres mots de listeDeMots que l’utilisateur aurait pu vouloir écrire. Par exemple, essayez toutes les transpositions simples possibles de lettres adjacentes pour découvrir que le mot «fonction» est une correspondance directe d’un mot COPYRIGHT 2001 LES ÉDITIONS REYNALD GOULET INC. TOUTE REPRODUCTION INTERDITE. de listeDeMots. Bien entendu, ceci suppose que le programme vérifiera toutes les transpositions possibles, telles que «ofnction», «focntion», «fontcion», «fonctoin» et «fonctino». Lorsque vous trouvez un mot correspondant à un de ceux de listeDeMots, affichez ce mot dans un message du genre: «Vouliez-vous dire "fonction"?». Implantez d’autres tests, tels que le remplacement des lettres doubles par une lettre simple, ainsi que tout autre test que vous puissiez développer pour améliorer la qualité de votre vérificateur orthographique. 10.30 (Projet: générateur de mots-croisés aléatoires) La plupart des gens ont au moins une fois dans leur vie tenté de remplir une grille de mots croisés, mais peu d’entre eux ont essayé d’en créer. La création de mots croisés s’inscrit ici dans le cadre d’un projet de manipulation de chaînes de caractères qui requiert une sophistication et des efforts substantiels. De nombreux obstacles freinent le programmeur dans la mise en place d’un générateur de mots-croisés, même très simple. La représentation de la grille représente déjà une difficulté. Faut-il utiliser une suite de chaînes de caractères ou un tableau à deux indices? Le programmeur a besoin également d’une source de mots, et de définitions, c’est-à-dire d’un dictionnaire de mots, dont il puisse directement utiliser les références dans son programme. Quelle forme faut-il donner à ces mots pour faciliter les manipulations complexes qu’exige le programme? Le lecteur vraiment ambitieux appréciera de résoudre la partie «devinettes» du mot-croisé, où la brève description des mots horizontaux et verticaux sera affichée à l’intention de l’utilisateur. Même l’affichage d’une authentique grille de mots-croisés vierge n’est pas un problème simple!