Advertisement
Guest User

Joc Domino

a guest
Mar 6th, 2014
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*##############################################################################
  2. # Alumne: Octavi Allué Fonoll (1224997)                                        #
  3. # Data: 09/05/09 14:02                                                         #
  4. # Descripció: El joc del dominó, projecte final de MTP1                        #
  5. ##############################################################################*/
  6.  
  7. /* Llibrerires utilitzades                                                    */
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12.  
  13. /* Constants definides                                                        */
  14.  
  15. #define MAX_JUGADORS 4
  16.  
  17. /* Estructures de dades                                                       */
  18.  
  19. typedef enum {
  20.     FITXA_VERTICAL = 0,
  21.     FITXA_DRETA = 1,
  22.     FITXA_ESQUERRA = 2
  23. } ePosicio;
  24.  
  25. typedef enum {
  26.     ESQUERRA = 0,
  27.     DRETA = 1
  28. } eCostat;
  29.  
  30. typedef struct {
  31.     int superior, inferior;
  32.     ePosicio pos;
  33. } tFitxa;
  34.  
  35. typedef struct stNode {
  36.     tFitxa info;
  37.     struct stNode *seg;
  38. } tNode;
  39.  
  40. typedef struct {
  41.     tNode *cap;
  42. } tPila;
  43.  
  44. typedef struct {
  45.     tNode *esquerra, *dreta;
  46. } tPartida;
  47.  
  48. typedef struct {
  49.     tNode *primer;
  50. } tLlista;
  51.  
  52. typedef struct {
  53.     char nom[50];
  54.     int actiu;
  55.     tNode *fitxes;
  56. } tJugador;
  57.  
  58. /* Altres funcions                                                            */
  59.  
  60. void intercanvia (char *a, char *b, int length) {
  61.     char *aux;
  62.     int i;
  63.     aux = (char*) malloc (length);
  64.     for (i = 0; i < length; ++i) {
  65.         aux[i] = a[i];
  66.         a[i] = b[i];
  67.         b[i] = aux[i];
  68.     }
  69.     free(aux);
  70. }
  71.  
  72. /* Procediments i funcions per el tractament d'estructures de dades           */
  73.  
  74. void iniciarPila (tPila *p) {
  75.     /* Inicia la pila */
  76.     p->cap = NULL;
  77. }
  78.  
  79. int esBuidaPila (tPila *p) {
  80.     return(p->cap == NULL);
  81. }
  82.  
  83. int push (tPila *p, tNode x) {
  84.     /* Insereix un node a la pila */
  85.     tNode *q;
  86.     q = (tNode*) malloc (sizeof(tNode));
  87.     if (q != NULL) {
  88.         q->info.superior = x.info.superior;
  89.         q->info.inferior = x.info.inferior;
  90.         q->info.pos = x.info.pos;
  91.         q->seg = p->cap;
  92.         p->cap = q;
  93.     }
  94.     return(q != NULL);
  95. }
  96.  
  97. tNode pop (tPila *p) {
  98.     /* Retorna el node superior de la pila i lliberar memòria */
  99.     tNode *q;
  100.     tNode x;
  101.     q = p->cap;
  102.     x.info.superior = q->info.superior;
  103.     x.info.inferior = q->info.inferior;
  104.     x.info.pos = q->info.pos;
  105.     p->cap = p->cap->seg;
  106.     free(q);
  107.     return(x);
  108. }
  109.  
  110. void iniciarLlista (tNode **llista) {
  111.     /* Inicia la llista */
  112.     (*llista) = NULL;
  113. }
  114.  
  115. void primerLlista (tNode **iterador, tNode *llista) {
  116.     /* Col·loca l'iterador de la llista en primera posició de la llista */
  117.     (*iterador) = llista;
  118. }
  119.  
  120. void seguentLlista (tNode *llista, tNode **iterador) {
  121.     /* Avança l'iterador de la llista una posició */
  122.     if ((*iterador) != NULL) {
  123.         (*iterador) = (*iterador)->seg;
  124.     }
  125. }
  126.  
  127. int inserirLlista (tNode **llista, tNode *iterador, tNode x) {
  128.     /* Insereix a la llista el node x */
  129.     tNode *q;
  130.     q = (tNode*) malloc (sizeof(tNode));
  131.     if (q != NULL) {
  132.         q->info.superior = x.info.superior;
  133.         q->info.inferior = x.info.inferior;
  134.         q->info.pos = x.info.pos;
  135.         if (iterador == NULL) { /* Insereix en primera posició */
  136.             q->seg = (*llista);
  137.             (*llista) = q;      
  138.         }
  139.         else { /* Insereix en la posició següent a l'iterador */
  140.             q->seg = iterador->seg;
  141.             iterador->seg = q;
  142.         }
  143.     }
  144.     return(q != NULL);
  145. }
  146.  
  147. void eliminarLlista (tNode **llista, tNode *iterador, tNode *x) {
  148.     /* Treu de la llista el node següent a l'apuntat per l'iterador */
  149.     tNode *q;
  150.     if (iterador == NULL) { /* Elimina el primer node de la llista */
  151.         q = (*llista);
  152.         (*llista) = (*llista)->seg;
  153.     }
  154.     else {
  155.         q = iterador->seg;
  156.         iterador->seg = q->seg;
  157.     }
  158.     *x = *q;
  159.     free(q);
  160. }
  161.  
  162. tNode elementLlista (tNode *iterador) {
  163.     /* Selecciona un element de la llista */
  164.     tNode x;
  165.     x.info.superior = iterador->info.superior;
  166.     x.info.inferior = iterador->info.inferior;
  167.     x.info.pos = iterador->info.pos;
  168.     return(x);
  169. }
  170.  
  171. int esBuidaLlista (tNode *llista) {
  172.     return(llista == NULL);
  173. }
  174.  
  175. /* Funcions pròpies del joc                                                   */
  176.  
  177. void introduir_jugadors (tJugador *jugador) {
  178.     int nJugadors;
  179.     int i;
  180.     char n[50];
  181.     printf("Introdueix el nombre de jugadors que juga la partida: ");
  182.     scanf("%d", &nJugadors); printf("\n");
  183.     while (nJugadors > MAX_JUGADORS || nJugadors <= 1) {
  184.         printf("El nombre de jugadors permesos es d'entre 2 i 4.\n");
  185.         printf("Introdueix el nombre de jugadors que juga la partida: ");
  186.         scanf("%d", &nJugadors); printf("\n");
  187.     }
  188.     i = 0;
  189.     while (i < nJugadors) {
  190.         printf("Escriu el nom del jugador %d: ", i+1);
  191.         scanf("%s", n);
  192.         strcpy(jugador[i].nom, n);
  193.         jugador[i].actiu = 1;
  194.         iniciarLlista(&jugador[i].fitxes);
  195.         i++;
  196.     }
  197.     printf("\n");
  198.     while (i < MAX_JUGADORS-1) {
  199.         strcpy(jugador[i].nom, "");
  200.         jugador[i].actiu = 0;
  201.         iniciarLlista(&jugador[i].fitxes);
  202.         i++;
  203.     }
  204. }
  205.  
  206. tPila obtenir_fitxes_barrejades () {
  207.     tPila fitxesDisponibles;
  208.     FILE *z;
  209.     char fitxer[50], c;
  210.     tNode x;
  211.     int sup, inf;
  212.     printf("Introdueix el nom del fitxer que conte les fitxes: ");
  213.     scanf("%s", fitxer); printf("\n");
  214.     while ((z = fopen(fitxer, "r")) == NULL) {
  215.         printf("El fitxer no existeix, introdueix el nom d'un fitxer valid: ");
  216.         scanf("%s", fitxer); printf("\n");
  217.     }
  218.     iniciarPila(&fitxesDisponibles);
  219.     while (!feof(z)) {
  220.         fscanf(z, "%d", &sup);
  221.         fscanf(z, "%c", &c);
  222.         fscanf(z, "%d", &inf);
  223.         fscanf(z, "%c", &c);
  224.         x.info.superior = sup;
  225.         x.info.inferior = inf;
  226.         push(&fitxesDisponibles, x);
  227.     }
  228.     fclose(z);
  229.     x = pop(&fitxesDisponibles);
  230.     return(fitxesDisponibles);
  231. }    
  232.  
  233. void obtenir_index_seguent_jugador (tJugador jugador[], int *i) {
  234.     if (jugador[*i+1].actiu == 1 && *i < 3) {
  235.         *i = *i+1;
  236.     }
  237.     else {
  238.         *i = 0;
  239.     }
  240. }
  241.  
  242. void agafar_fitxa_pila (tPila *fitxesDisponibles, tJugador *jugador, int i) {
  243.     tNode fitxa;
  244.     fitxa = pop(fitxesDisponibles);
  245.     inserirLlista(&jugador[i].fitxes, NULL, fitxa);
  246. }  
  247.      
  248. void repartir (tPila *fitxesDisponibles, tJugador *jugador) {
  249.     int i = 0;
  250.     int j = 7;
  251.     tNode fitxa;
  252.     while (j > 0) {
  253.         fitxa = pop(fitxesDisponibles);
  254.         fitxa.info.pos = FITXA_ESQUERRA;
  255.         inserirLlista(&jugador[i].fitxes, NULL, fitxa);
  256.         obtenir_index_seguent_jugador(jugador, &i);
  257.         if (i == 0) {
  258.             j = j-1;
  259.         }
  260.     }
  261. }
  262.  
  263. int pot_tirar (tPartida partida, tJugador jugador[], int i) {
  264.     int trobat;
  265.     int esq, dre;
  266.     tNode *iteradorLlista;
  267.     if (partida.esquerra->info.pos == FITXA_ESQUERRA) {
  268.         esq = partida.esquerra->info.superior;
  269.     }
  270.     else {
  271.         esq = partida.esquerra->info.inferior;
  272.     }
  273.     if (partida.dreta->info.pos == FITXA_ESQUERRA) {
  274.         dre = partida.dreta->info.inferior;
  275.     }
  276.     else {
  277.         dre = partida.dreta->info.superior;
  278.     }
  279.     primerLlista(&iteradorLlista, jugador[i].fitxes);
  280.     trobat = 0;
  281.     while (iteradorLlista != NULL && !trobat) {
  282.         if (iteradorLlista->info.superior == esq || iteradorLlista->info.inferior == esq ||
  283.             iteradorLlista->info.superior == dre || iteradorLlista->info.inferior == dre) {
  284.                 trobat = 1;
  285.         }
  286.         seguentLlista(jugador[i].fitxes, &iteradorLlista);
  287.     }
  288.     return(trobat);
  289. }
  290.  
  291. int demanar_tirar_fitxa (tPartida *partida, tJugador *jugador, int i) {
  292.     int resultat;
  293.     tNode *iteradorLlista, *fitxaSeleccionada; /* Cal un doble iterador per fer les eliminacions */
  294.     tNode fitxa;
  295.     int nFitxa, nDisponibles, j, n;
  296.     char opc; /* Indicarà el costat de la partida on inserir la fitxa */
  297.     primerLlista(&iteradorLlista, partida->esquerra);
  298.     printf("Es torn de %s, l'estat actual de la partida es:\n", jugador[i].nom);
  299.     while (iteradorLlista != NULL) { /* Recorrem la llista de la partida per imprimir-la */
  300.         if (iteradorLlista->info.pos == FITXA_VERTICAL) {
  301.             printf("[[%d]]", iteradorLlista->info.superior);
  302.         }
  303.         else if (iteradorLlista->info.pos == FITXA_DRETA) {
  304.             printf("[%d|%d]", iteradorLlista->info.inferior, iteradorLlista->info.superior);
  305.         }
  306.         else {
  307.             printf("[%d|%d]", iteradorLlista->info.superior, iteradorLlista->info.inferior);
  308.         }
  309.         seguentLlista(partida->esquerra, &iteradorLlista);
  310.     }
  311.     primerLlista(&iteradorLlista, jugador[i].fitxes);
  312.     nDisponibles = 0;
  313.     printf("\nLes fitxes disponibles son:\n");
  314.     while (iteradorLlista != NULL) { /* Recorrem la llista de fitxes del jugador per imprimir-la */
  315.         printf(" [%d|%d] ", iteradorLlista->info.superior, iteradorLlista->info.inferior);
  316.         seguentLlista(jugador[i].fitxes, &iteradorLlista);
  317.         nDisponibles = nDisponibles+1;
  318.     }
  319.     printf("\nTens un total de %d fitxes disponibles.", nDisponibles);
  320.     printf("\nIntrodueix el nombre de fitxa que desitges inserir al domino: ");
  321.     scanf("%d", &nFitxa); printf("\n");
  322.     while (nFitxa > nDisponibles || nFitxa <= 0) {
  323.         printf("Nomes queden %d fitxes disponibles, introdueix un nou nombre de fitxa valid: ", nDisponibles);
  324.         scanf("%d", &nFitxa); printf("\n");
  325.     }
  326.     primerLlista(&fitxaSeleccionada, jugador[i].fitxes);
  327.     if (nFitxa == 1) { /* Al seleccionar la primera fitxa col·loquem iteradorLlista a NULL per esborrar correctament */
  328.         iteradorLlista = NULL;
  329.     }
  330.     for (j = 0; j < nFitxa-1; ++j) { /* Només entra si nFitxa > 1 */
  331.         iteradorLlista = fitxaSeleccionada;
  332.         seguentLlista(jugador[i].fitxes, &fitxaSeleccionada); /* Avança l'iterador fitxaSeleccionada */
  333.     }
  334.     if (partida->esquerra == NULL) { /* Primer moviment de la partida */
  335.         eliminarLlista(&jugador[i].fitxes, iteradorLlista, &fitxa);
  336.         if (fitxa.info.superior == fitxa.info.inferior) { /* Posem la fitxa en posició vertical  si és un doble */
  337.             fitxa.info.pos = FITXA_VERTICAL;
  338.         }
  339.         inserirLlista(&partida->esquerra, partida->esquerra, fitxa);
  340.         partida->dreta = partida->esquerra; /* Al inserir la primera fitxa fem que partida->esquerra i partida->dreta siguin iguals */
  341.         resultat = 1;
  342.     }
  343.     else { /* Altres moviments de la partida */
  344.         opc = 'x';
  345.         while (opc != 'd' && opc != 'e') {
  346.             printf("Introdueix el costat on s'introdueix la fitxa: (d)reta o (e)squerra: ");
  347.             scanf("%c", &opc); printf("\n");
  348.         }
  349.         if (opc == 'e') { /* Inserció a l'esquerra */
  350.             if (partida->esquerra->info.pos == FITXA_DRETA) {
  351.                 n = partida->esquerra->info.inferior;
  352.             }
  353.             else {
  354.                 n = partida->esquerra->info.superior;
  355.             }
  356.         }
  357.         else { /* Inserció a la dreta */
  358.             if (partida->dreta->info.pos == FITXA_ESQUERRA) {
  359.                 n = partida->dreta->info.inferior;
  360.             }
  361.             else {
  362.                 n = partida->dreta->info.superior;
  363.             }
  364.         }
  365.         fitxa = elementLlista(fitxaSeleccionada);
  366.         if (fitxa.info.superior == n || fitxa.info.inferior == n) { /* La fitxa serà inserida a la partida */
  367.             eliminarLlista(&jugador[i].fitxes, iteradorLlista, &fitxa);
  368.             if (opc == 'e') {
  369.                 if (fitxa.info.superior == fitxa.info.inferior) {
  370.                         fitxa.info.pos = FITXA_VERTICAL;
  371.                 }
  372.                 else {
  373.                     if (fitxa.info.superior == n) {
  374.                         fitxa.info.pos = FITXA_DRETA;
  375.                     }
  376.                 }
  377.                 inserirLlista(&partida->esquerra, NULL, fitxa);
  378.             }
  379.             else {
  380.                 if (fitxa.info.superior == fitxa.info.inferior) {
  381.                         fitxa.info.pos = FITXA_VERTICAL;
  382.                 }
  383.                 else {
  384.                     if (fitxa.info.inferior == n) {
  385.                         fitxa.info.pos = FITXA_DRETA;
  386.                     }
  387.                 }
  388.                 inserirLlista(&partida->esquerra, partida->dreta, fitxa);
  389.                 seguentLlista(partida->esquerra, &partida->dreta);
  390.             }
  391.             if (esBuidaLlista(jugador[i].fitxes)) {
  392.                 resultat = 2;
  393.             }
  394.             else {
  395.                 resultat = 1;
  396.             }
  397.         }
  398.         else { /* No s'ha inserit cap fitxa */
  399.             resultat = 0;
  400.         }
  401.     }
  402.     return(resultat);
  403. }
  404.  
  405. void mostrar_resultats (tJugador jugador[]) {
  406.     int i, j, minim, jActius;
  407.     int puntuacio[MAX_JUGADORS];
  408.     tNode *iteradorLlista;
  409.     jActius = 0;
  410.     for (i = 0; i <= MAX_JUGADORS-1; ++i) {
  411.         puntuacio[i] = 0;
  412.         if (jugador[i].nom != "") {
  413.             primerLlista(&iteradorLlista, jugador[i].fitxes);
  414.             printf("Ordenant");
  415.             while (iteradorLlista != NULL) {
  416.                 puntuacio[i] = puntuacio[i] + iteradorLlista->info.superior + iteradorLlista->info.inferior;
  417.                 seguentLlista(jugador[i].fitxes, &iteradorLlista);
  418.             }
  419.             jActius = jActius + 1;
  420.             printf("puntuacio[%d] = %d", i, puntuacio[i]);
  421.         }
  422.     }
  423.     for (i = 1; i <= jActius-1; ++i) {
  424.         minim = i;
  425.         for (j = i+1; i <= jActius; ++j) {
  426.             if (puntuacio[j] < puntuacio[minim]) {
  427.                 minim = j;
  428.             }
  429.         }
  430.         intercanvia((char*)&jugador[i], (char*)&jugador[minim], sizeof(tJugador));
  431.         intercanvia((char*)&puntuacio[i], (char*)&puntuacio[minim], sizeof(int));
  432.     }
  433.     printf("Llista ordenada");
  434.     for (i = 0; i <= MAX_JUGADORS-1; i++) {
  435.         if (jugador[i].nom != "") {
  436.             if (jugador[i].fitxes == NULL) {
  437.                 printf("El jugador %s ha guanyat la partida amb 0 punts i sense fitxes", jugador[i].nom);
  438.             }
  439.             else {
  440.                 printf("%d. %s amb %d punts", i+1, jugador[i].nom, puntuacio[i]);
  441.             }
  442.         }
  443.         else {
  444.             printf("%d.", i+1);
  445.         }
  446.     }
  447. }
  448.  
  449. void partida (tPartida *partida, tJugador *jugador) {
  450.     int final, continuar;
  451.     int indexJugador;
  452.     partida->esquerra = NULL;
  453.     partida->dreta = NULL;
  454.     tPila fitxesDisponibles;
  455.     tNode fitxa;
  456.     fitxesDisponibles = obtenir_fitxes_barrejades();
  457.     repartir(&fitxesDisponibles, jugador);
  458.     final = 0;
  459.     indexJugador = 0;
  460.     demanar_tirar_fitxa(partida, jugador, indexJugador); /* Primer moviment */
  461.     while (!final) {
  462.         obtenir_index_seguent_jugador(jugador, &indexJugador);
  463.         while (!pot_tirar(*partida, jugador, indexJugador) && !esBuidaPila(&fitxesDisponibles)) {
  464.             agafar_fitxa_pila(&fitxesDisponibles, jugador, indexJugador);
  465.         }
  466.         final = !pot_tirar(*partida, jugador, indexJugador) && esBuidaPila(&fitxesDisponibles); /*Cambio AND i esBuidaPila*/
  467.         if (!final) {
  468.             continuar = 0;
  469.             while (continuar == 0) {
  470.                 continuar = demanar_tirar_fitxa(partida, jugador, indexJugador);
  471.                 if (continuar == 2) { /* El jugador ha inserit la darrera fitxa */
  472.                     final = 1;
  473.                 }
  474.             }
  475.         }
  476.     }
  477.     mostrar_resultats(jugador);
  478.     for (indexJugador = 0; indexJugador < MAX_JUGADORS; ++indexJugador) { /* Lliberem memòria de les llistes de tots els jugadors */
  479.         while (!esBuidaLlista(jugador[indexJugador].fitxes)) {
  480.             eliminarLlista(&jugador[indexJugador].fitxes, NULL, &fitxa);
  481.         }
  482.     }
  483.     while (!esBuidaLlista(partida->esquerra)) { /* Lliberem memòria de les fitxes de la partida */
  484.         eliminarLlista(&partida->esquerra, NULL, &fitxa);
  485.     }
  486.     while (!esBuidaPila(&fitxesDisponibles)) { /* Lliberem la memòria utilitzada per la pila de fitxes fitxesDisponibles */
  487.         fitxa = pop(&fitxesDisponibles);
  488.     }
  489. }
  490.  
  491. /* Programa principal                                                         */
  492.  
  493. int main () {
  494.     tJugador jugador[MAX_JUGADORS];
  495.     tPartida game;
  496.     introduir_jugadors(jugador);
  497.     partida(&game, jugador);
  498.  
  499.     system("PAUSE");
  500.     return(0);
  501. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement