00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 #include <time.h>
00024 #include <string.h>
00025 #include <ctype.h>
00026 #include <fstream>
00027 #include <readline/readline.h>
00028 #include <readline/history.h>
00029
00030 #include "dic.h"
00031 #include "dic_search.h"
00032 #include "game_io.h"
00033 #include "game_factory.h"
00034 #include "training.h"
00035 #include "duplicate.h"
00036 #include "freegame.h"
00037
00038
00039
00040 static char *line_read = NULL;
00041
00042
00043
00044
00045
00046 char *rl_gets()
00047 {
00048
00049
00050 if (line_read)
00051 {
00052 free(line_read);
00053 line_read = NULL;
00054 }
00055
00056
00057 line_read = readline("commande> ");
00058
00059
00060 if (line_read && *line_read)
00061 add_history(line_read);
00062
00063 return line_read;
00064 }
00065
00066
00067 char *
00068 next_token_alpha(char *cmd, const char *delim)
00069 {
00070 int i;
00071 char *token = strtok(cmd, delim);
00072 if (token == NULL)
00073 return NULL;
00074 for (i = 0; token[i] && isalpha(token[i]); i++)
00075 ;
00076 token[i] = '\0';
00077 return token;
00078 }
00079
00080
00081 char *
00082 next_token_alphanum(char *cmd, const char *delim)
00083 {
00084 int i;
00085 char *token = strtok(cmd, delim);
00086 if (token == NULL)
00087 return NULL;
00088 for (i = 0; token[i] && isalnum(token[i]); i++)
00089 ;
00090 token[i] = '\0';
00091 return token;
00092 }
00093
00094
00095 char *
00096 next_token_alphaplusjoker(char *cmd, const char *delim)
00097 {
00098 int i;
00099 char *token = strtok(cmd, delim);
00100 if (token == NULL)
00101 return NULL;
00102 for (i = 0; token[i] && (isalpha(token[i]) ||
00103 token[i] == '?' ||
00104 token[i] == '+');
00105 i++)
00106 ;
00107 token[i] = '\0';
00108 return token;
00109 }
00110
00111
00112 char *
00113 next_token_digit(char *cmd, const char *delim)
00114 {
00115 int i;
00116 char *token = strtok(cmd, delim);
00117 if (token == NULL)
00118 return NULL;
00119 for (i = 0; token[i] && (isdigit(token[i]) || token[i] == '-'); i++)
00120 ;
00121 token[i] = '\0';
00122 return token;
00123 }
00124
00125
00126 char *
00127 next_token_cross(char *cmd, const char *delim)
00128 {
00129 int i;
00130 char *token = strtok(cmd, delim);
00131 if (token == NULL)
00132 return NULL;
00133 for (i = 0; token[i] &&
00134 (isalpha(token[i]) || token[i] == '.');
00135 i++)
00136 ;
00137 token[i] = '\0';
00138 return token;
00139 }
00140
00141
00142 char *
00143 next_token_filename(char *cmd, const char *delim)
00144 {
00145 int i;
00146 char *token = strtok(cmd, delim);
00147 if (token == NULL)
00148 return NULL;
00149 for (i = 0; token[i] && (isalnum(token[i]) ||
00150 token[i] == '.' ||
00151 token[i] == '_'); i++)
00152 ;
00153 token[i] = '\0';
00154 return token;
00155 }
00156
00157
00158 void
00159 eliottxt_get_cross(const Dictionary &iDic, char* cros)
00160 {
00161 int i;
00162
00163 char wordlist[RES_CROS_MAX][DIC_WORD_MAX];
00164 Dic_search_Cros(iDic, cros, wordlist);
00165 for (i = 0; i<RES_CROS_MAX && wordlist[i][0]; i++)
00166 {
00167 printf(" %s\n", wordlist[i]);
00168 }
00169 }
00170
00171
00172 void
00173 help_training()
00174 {
00175 printf(" ? : aide -- cette page\n");
00176 printf(" a [g|l|p|r|t] : afficher :\n");
00177 printf(" g -- grille\n");
00178 printf(" gj -- grille + jokers\n");
00179 printf(" gm -- grille + valeur des cases\n");
00180 printf(" gn -- grille + valeur des cases (variante)\n");
00181 printf(" l -- lettres non jouées\n");
00182 printf(" p -- partie\n");
00183 printf(" r -- recherche\n");
00184 printf(" s -- score\n");
00185 printf(" S -- score de tous les joueurs\n");
00186 printf(" t -- tirage\n");
00187 printf(" d [] : vérifier le mot []\n");
00188 printf(" * : tirage aléatoire\n");
00189 printf(" + : tirage aléatoire ajouts\n");
00190 printf(" t [] : changer le tirage\n");
00191 printf(" j [] {} : jouer le mot [] aux coordonnées {}\n");
00192 printf(" n [] : jouer le résultat numéro []\n");
00193 printf(" r : rechercher les meilleurs résultats\n");
00194 printf(" s [] : sauver la partie en cours dans le fichier []\n");
00195 printf(" q : quitter le mode entraînement\n");
00196 }
00197
00198
00199 void
00200 help_freegame()
00201 {
00202 printf(" ? : aide -- cette page\n");
00203 printf(" a [g|l|p|s|t] : afficher :\n");
00204 printf(" g -- grille\n");
00205 printf(" gj -- grille + jokers\n");
00206 printf(" gm -- grille + valeur des cases\n");
00207 printf(" gn -- grille + valeur des cases (variante)\n");
00208 printf(" j -- joueur courant\n");
00209 printf(" l -- lettres non jouées\n");
00210 printf(" p -- partie\n");
00211 printf(" s -- score\n");
00212 printf(" S -- score de tous les joueurs\n");
00213 printf(" t -- tirage\n");
00214 printf(" T -- tirage de tous les joueurs\n");
00215 printf(" d [] : vérifier le mot []\n");
00216 printf(" j [] {} : jouer le mot [] aux coordonnées {}\n");
00217 printf(" p [] : passer son tour en changeant les lettres []\n");
00218 printf(" s [] : sauver la partie en cours dans le fichier []\n");
00219 printf(" c [] : charger la partie du fichier []\n");
00220 printf(" q : quitter le mode partie libre\n");
00221 }
00222
00223
00224 void
00225 help_duplicate()
00226 {
00227 printf(" ? : aide -- cette page\n");
00228 printf(" a [g|l|p|s|t] : afficher :\n");
00229 printf(" g -- grille\n");
00230 printf(" gj -- grille + jokers\n");
00231 printf(" gm -- grille + valeur des cases\n");
00232 printf(" gn -- grille + valeur des cases (variante)\n");
00233 printf(" j -- joueur courant\n");
00234 printf(" l -- lettres non jouées\n");
00235 printf(" p -- partie\n");
00236 printf(" s -- score\n");
00237 printf(" S -- score de tous les joueurs\n");
00238 printf(" t -- tirage\n");
00239 printf(" d [] : vérifier le mot []\n");
00240 printf(" j [] {} : jouer le mot [] aux coordonnées {}\n");
00241 printf(" n [] : passer au joueur n°[]\n");
00242 printf(" s [] : sauver la partie en cours dans le fichier []\n");
00243 printf(" c [] : charger la partie du fichier []\n");
00244 printf(" q : quitter le mode duplicate\n");
00245 }
00246
00247
00248 void
00249 help()
00250 {
00251 printf(" ? : aide -- cette page\n");
00252 printf(" e : démarrer le mode entraînement\n");
00253 printf(" d [] {} : démarrer une partie duplicate avec\n");
00254 printf(" [] joueurs humains et {} joueurs IA\n");
00255 printf(" l [] {} : démarrer une partie libre avec\n");
00256 printf(" [] joueurs humains et {} joueurs IA\n");
00257 printf(" D : raccourci pour d 1 1\n");
00258 printf(" L : raccourci pour l 1 1\n");
00259 printf(" q : quitter\n");
00260 }
00261
00262
00263 void
00264 display_data(const Game &iGame, const char *delim)
00265 {
00266 char *token;
00267
00268 token = next_token_alpha(NULL, delim);
00269 if (token == NULL)
00270 {
00271 cout << "commande incomplète\n";
00272 return;
00273 }
00274 switch (token[0])
00275 {
00276 case 'g':
00277 switch (token[1])
00278 {
00279 case '\0':
00280 GameIO::printBoard(cout, iGame);
00281 break;
00282 case 'j':
00283 GameIO::printBoardJoker(cout, iGame);
00284 break;
00285 case 'm':
00286 GameIO::printBoardMultipliers(cout, iGame);
00287 break;
00288 case 'n':
00289 GameIO::printBoardMultipliers2(cout, iGame);
00290 break;
00291 default:
00292 printf("commande inconnue\n");
00293 break;
00294 }
00295 break;
00296 case 'j':
00297 cout << "Joueur " << iGame.currPlayer() << endl;
00298 break;
00299 case 'l':
00300 GameIO::printNonPlayed(cout, iGame);
00301 break;
00302 case 'p':
00303 iGame.save(cout);
00304 break;
00305 case 'r':
00306 token = next_token_digit(NULL, delim);
00307 if (token == NULL)
00308 GameIO::printSearchResults(cout,
00309 static_cast<const Training&>(iGame),
00310 10);
00311 else
00312 GameIO::printSearchResults(cout,
00313 static_cast<const Training&>(iGame),
00314 atoi(token));
00315 break;
00316 case 's':
00317 GameIO::printPoints(cout, iGame);
00318 break;
00319 case 'S':
00320 GameIO::printAllPoints(cout, iGame);
00321 break;
00322 case 't':
00323 GameIO::printPlayedRack(cout, iGame, iGame.getHistory().getSize());
00324 break;
00325 case 'T':
00326 GameIO::printAllRacks(cout, iGame);
00327 break;
00328 default:
00329 cout << "commande inconnue\n";
00330 break;
00331 }
00332 }
00333
00334
00335 void
00336 loop_training(Training &iGame)
00337 {
00338 char *token;
00339 char *commande = NULL;
00340 char delim[] = " \t";
00341 int quit = 0;
00342
00343 cout << "mode entraînement\n";
00344 cout << "[?] pour l'aide\n";
00345 while (quit == 0)
00346 {
00347 commande = rl_gets();
00348 token = strtok(commande, delim);
00349 if (token)
00350 {
00351 switch (token[0])
00352 {
00353 case '?':
00354 help_training();
00355 break;
00356 case 'a':
00357 display_data(iGame, delim);
00358 break;
00359 case 'd':
00360 token = next_token_alpha(NULL, delim);
00361 if (token == NULL)
00362 help_training();
00363 else
00364 {
00365 if (Dic_search_word(iGame.getDic(), token))
00366 printf("le mot -%s- existe\n", token);
00367 else
00368 printf("le mot -%s- n'existe pas\n", token);
00369 }
00370 break;
00371 case 'j':
00372 token = next_token_alpha(NULL, delim);
00373 if (token == NULL)
00374 help_training();
00375 else
00376 {
00377 int res;
00378 char *coord = next_token_alphanum(NULL, delim);
00379 if (coord == NULL)
00380 {
00381 help_training();
00382 break;
00383 }
00384 if ((res = iGame.play(coord, token)) != 0)
00385 {
00386 fprintf(stderr, "Mot incorrect ou mal placé (%i)\n",
00387 res);
00388 break;
00389 }
00390 }
00391 break;
00392 case 'n':
00393 token = next_token_digit(NULL, delim);
00394 if (token == NULL)
00395 help_training();
00396 else
00397 {
00398 int n = atoi(token);
00399 if (n <= 0)
00400 iGame.back(n == 0 ? 1 : -n);
00401 else
00402 {
00403 if (iGame.playResult(--n))
00404 printf("mauvais argument\n");
00405 }
00406 }
00407 break;
00408 case 'r':
00409 iGame.search();
00410 break;
00411 case 't':
00412 token = next_token_alphaplusjoker(NULL, delim);
00413 if (token == NULL)
00414 help_training();
00415 else
00416 if (iGame.setRackManual(0, token))
00417 printf("le sac ne contient pas assez de lettres\n");
00418 break;
00419 case 'x':
00420 token = next_token_cross(NULL, delim);
00421 if (token == NULL)
00422 help_training();
00423 else
00424 eliottxt_get_cross(iGame.getDic(), token);
00425 break;
00426 case '*':
00427 iGame.setRackRandom(0, false, Game::RACK_ALL);
00428 break;
00429 case '+':
00430 iGame.setRackRandom(0, false, Game::RACK_NEW);
00431 break;
00432 case 's':
00433 token = next_token_filename(NULL, delim);
00434 if (token != NULL)
00435 {
00436 ofstream fout(token);
00437 if (fout.rdstate() == ios::failbit)
00438 {
00439 printf("impossible d'ouvrir %s\n", token);
00440 break;
00441 }
00442 iGame.save(fout);
00443 fout.close();
00444 }
00445 break;
00446 case 'q':
00447 quit = 1;
00448 break;
00449 default:
00450 printf("commande inconnue\n");
00451 break;
00452 }
00453 }
00454 }
00455 printf("fin du mode entraînement\n");
00456 }
00457
00458
00459 void
00460 loop_freegame(FreeGame &iGame)
00461 {
00462 char *token;
00463 char *commande = NULL;
00464 char delim[] = " \t";
00465 int quit = 0;
00466
00467 printf("mode partie libre\n");
00468 printf("[?] pour l'aide\n");
00469 while (quit == 0)
00470 {
00471 commande = rl_gets();
00472 token = strtok(commande, delim);
00473 if (token)
00474 {
00475 switch (token[0])
00476 {
00477 case '?':
00478 help_freegame();
00479 break;
00480 case 'a':
00481 display_data(iGame, delim);
00482 break;
00483 case 'd':
00484 token = next_token_alpha(NULL, delim);
00485 if (token == NULL)
00486 help_freegame();
00487 else
00488 {
00489 if (Dic_search_word(iGame.getDic(), token))
00490 printf("le mot -%s- existe\n", token);
00491 else
00492 printf("le mot -%s- n'existe pas\n", token);
00493 }
00494 break;
00495 case 'j':
00496 token = next_token_alpha(NULL, delim);
00497 if (token == NULL)
00498 help_freegame();
00499 else
00500 {
00501 int res;
00502 char *coord = next_token_alphanum(NULL, delim);
00503 if (coord == NULL)
00504 {
00505 help_freegame();
00506 break;
00507 }
00508 if ((res = iGame.play(coord, token)) != 0)
00509 {
00510 fprintf(stderr, "Mot incorrect ou mal placé (%i)\n",
00511 res);
00512 break;
00513 }
00514 }
00515 break;
00516 case 'p':
00517 token = next_token_alpha(NULL, delim);
00518
00519 if (token == NULL)
00520 token = "";
00521
00522 if (iGame.pass(token, iGame.currPlayer()) != 0)
00523 break;
00524 break;
00525 case 's':
00526 token = next_token_filename(NULL, delim);
00527 if (token != NULL)
00528 {
00529 ofstream fout(token);
00530 if (fout.rdstate() == ios::failbit)
00531 {
00532 printf("impossible d'ouvrir %s\n", token);
00533 break;
00534 }
00535 iGame.save(fout);
00536 fout.close();
00537 }
00538 break;
00539 case 'q':
00540 quit = 1;
00541 break;
00542 default:
00543 printf("commande inconnue\n");
00544 break;
00545 }
00546 }
00547 }
00548 printf("fin du mode partie libre\n");
00549 }
00550
00551
00552 void
00553 loop_duplicate(Duplicate &iGame)
00554 {
00555 char *token;
00556 char *commande = NULL;
00557 char delim[] = " \t";
00558 int quit = 0;
00559
00560 printf("mode duplicate\n");
00561 printf("[?] pour l'aide\n");
00562 while (quit == 0)
00563 {
00564 commande = rl_gets();
00565 token = strtok(commande, delim);
00566 if (token)
00567 {
00568 switch (token[0])
00569 {
00570 case '?':
00571 help_duplicate();
00572 break;
00573 case 'a':
00574 display_data(iGame, delim);
00575 break;
00576 case 'd':
00577 token = next_token_alpha(NULL, delim);
00578 if (token == NULL)
00579 help_duplicate();
00580 else
00581 {
00582 if (Dic_search_word(iGame.getDic(), token))
00583 printf("le mot -%s- existe\n", token);
00584 else
00585 printf("le mot -%s- n'existe pas\n", token);
00586 }
00587 break;
00588 case 'j':
00589 token = next_token_alpha(NULL, delim);
00590 if (token == NULL)
00591 help_duplicate();
00592 else
00593 {
00594 int res;
00595 char *coord = next_token_alphanum(NULL, delim);
00596 if (coord == NULL)
00597 {
00598 help_duplicate();
00599 break;
00600 }
00601 if ((res = iGame.play(coord, token)) != 0)
00602 {
00603 fprintf(stderr, "Mot incorrect ou mal placé (%i)\n",
00604 res);
00605 break;
00606 }
00607 }
00608 break;
00609 case 'n':
00610 token = next_token_digit(NULL, delim);
00611 if (token == NULL)
00612 help_duplicate();
00613 else
00614 {
00615 int res = iGame.setPlayer(atoi(token));
00616 if (res == 1)
00617 fprintf(stderr, "Numéro de joueur invalide\n");
00618 else if (res == 2)
00619 fprintf(stderr, "Impossible de choisir un joueur non humain\n");
00620 }
00621 break;
00622 case 's':
00623 token = next_token_filename(NULL, delim);
00624 if (token != NULL)
00625 {
00626 ofstream fout(token);
00627 if (fout.rdstate() == ios::failbit)
00628 {
00629 printf("impossible d'ouvrir %s\n", token);
00630 break;
00631 }
00632 iGame.save(fout);
00633 fout.close();
00634 }
00635 break;
00636 case 'q':
00637 quit = 1;
00638 break;
00639 default:
00640 printf("commande inconnue\n");
00641 break;
00642 }
00643 }
00644 }
00645 printf("fin du mode duplicate\n");
00646 }
00647
00648
00649 void
00650 main_loop(const Dictionary &iDic)
00651 {
00652 char *token;
00653 char *commande = NULL;
00654 char delim[] = " \t";
00655 int quit = 0;
00656
00657 printf("[?] pour l'aide\n");
00658 while (quit == 0)
00659 {
00660 commande = rl_gets();
00661 token = strtok(commande, delim);
00662 if (token)
00663 {
00664 switch (token[0])
00665 {
00666 case '?':
00667 help();
00668 break;
00669 case 'c':
00670 token = next_token_filename(NULL, delim);
00671 if (token == NULL)
00672 {}
00673 else
00674 {
00675 FILE* fin;
00676 fprintf(stderr, "chargement de -%s-\n", token);
00677 if ((fin = fopen(token, "r")) == NULL)
00678 {
00679 printf("impossible d'ouvrir %s\n", token);
00680 break;
00681 }
00682 Game *game = Game::load(fin, iDic);
00683 fclose(fin);
00684 if (game == NULL)
00685 {
00686 fprintf(stderr, "erreur pendant le chargement\n");
00687 }
00688 else
00689 {
00690 if (game->getMode() == Game::kTRAINING)
00691 loop_training((Training&)*game);
00692 else if (game->getMode() == Game::kFREEGAME)
00693 loop_freegame((FreeGame&)*game);
00694 else
00695 loop_duplicate((Duplicate&)*game);
00696 }
00697 }
00698 break;
00699 case 'e':
00700 {
00701
00702 Training *game = GameFactory::Instance()->createTraining(iDic);
00703 game->start();
00704 loop_training(*game);
00705 GameFactory::Instance()->releaseGame(*game);
00706 break;
00707 }
00708 case 'd':
00709 {
00710 int i;
00711
00712 token = next_token_digit(NULL, delim);
00713 if (token == NULL)
00714 {
00715 help();
00716 break;
00717 }
00718 Duplicate *game = GameFactory::Instance()->createDuplicate(iDic);
00719 for (i = 0; i < atoi(token); i++)
00720 game->addHumanPlayer();
00721 token = next_token_digit(NULL, delim);
00722 if (token == NULL)
00723 {
00724 help();
00725 break;
00726 }
00727 for (i = 0; i < atoi(token); i++)
00728 game->addAIPlayer();
00729 game->start();
00730 loop_duplicate(*game);
00731 GameFactory::Instance()->releaseGame(*game);
00732 break;
00733 }
00734 case 'l':
00735 {
00736 int i;
00737
00738 token = next_token_digit(NULL, delim);
00739 if (token == NULL)
00740 {
00741 help();
00742 break;
00743 }
00744 FreeGame *game = GameFactory::Instance()->createFreeGame(iDic);
00745 for (i = 0; i < atoi(token); i++)
00746 game->addHumanPlayer();
00747 token = next_token_digit(NULL, delim);
00748 if (token == NULL)
00749 {
00750 help();
00751 break;
00752 }
00753 for (i = 0; i < atoi(token); i++)
00754 game->addAIPlayer();
00755 game->start();
00756 loop_freegame(*game);
00757 GameFactory::Instance()->releaseGame(*game);
00758 break;
00759 }
00760 case 'D':
00761 {
00762
00763 Duplicate *game = GameFactory::Instance()->createDuplicate(iDic);
00764 game->addHumanPlayer();
00765 game->addAIPlayer();
00766 game->start();
00767 loop_duplicate(*game);
00768 GameFactory::Instance()->releaseGame(*game);
00769 break;
00770 }
00771 case 'L':
00772 {
00773
00774 FreeGame *game = GameFactory::Instance()->createFreeGame(iDic);
00775 game->addHumanPlayer();
00776 game->addAIPlayer();
00777 game->start();
00778 loop_freegame(*game);
00779 GameFactory::Instance()->releaseGame(*game);
00780 break;
00781 }
00782 case 'q':
00783 quit = 1;
00784 break;
00785 default:
00786 printf("commande inconnue\n");
00787 break;
00788 }
00789 }
00790 }
00791 }
00792
00793
00794 int
00795 main(int argc, char *argv[])
00796 {
00797 char dic_path[100];
00798
00799 Dictionary dic = NULL;
00800
00801 if (argc != 2 && argc != 3)
00802 {
00803 fprintf(stdout, "Usage: eliot /chemin/vers/ods4.dawg [random_seed]\n");
00804 exit(1);
00805 }
00806 else
00807 strcpy(dic_path, argv[1]);
00808
00809 switch (Dic_load(&dic, dic_path))
00810 {
00811 case 0:
00812
00813 break;
00814 case 1:
00815 printf("chargement: problème d'ouverture de %s\n", argv[1]);
00816 exit(1);
00817 break;
00818 case 2:
00819 printf("chargement: mauvais en-tete de dictionnaire\n");
00820 exit(2);
00821 break;
00822 case 3:
00823 printf("chargement: problème 3 d'allocation mémoire\n");
00824 exit(3);
00825 break;
00826 case 4:
00827 printf("chargement: problème 4 d'alocation mémoire\n");
00828 exit(4);
00829 break;
00830 case 5:
00831 printf("chargement: problème de lecture des arcs du dictionnaire\n");
00832 exit(5);
00833 break;
00834 default:
00835 printf("chargement: problème non-repertorié\n");
00836 exit(6);
00837 break;
00838 }
00839
00840 if (argc == 3)
00841 srand(atoi(argv[2]));
00842 else
00843 srand(time(NULL));
00844
00845 main_loop(dic);
00846 GameFactory::Destroy();
00847
00848 Dic_destroy(dic);
00849
00850
00851 if (line_read)
00852 free(line_read);
00853
00854 return 0;
00855 }