void despertarTrack( tlcde* framesBuf, tlcde* lsTracks, tlcde* lsIds ){ STFrame* frameData1; STTrack* NewTrack; STTrack* SleepingTrack; float distancia; // almacena la distancia entre el track nuevo y los que duermen. float menorDistancia = 100000; // almacena el valor de la menor distancia int masCercano; // almacena la posición de la lista del track nuevo más cercano al track durmiendo float direccion; int a; // para hayar la distancia int b; // idem int tiempoVivo; if( framesBuf->numeroDeElementos < 3 ) return; frameData1 = (STFrame*)obtener(framesBuf->numeroDeElementos-1, framesBuf); // frameData0 = (STFrame*)obtener(0, framesBuf); if( lsTracks->numeroDeElementos <= trackParams->MaxBlobs ) return; for(int i = 0;i < lsTracks->numeroDeElementos ; i++){ // obtener Track NewTrack = (STTrack*)obtener(i, lsTracks); // comprobar si se han iniciado nuevos tracks. Los tracks que lleguen aqui // son posibles tracks válidos( no han sido eliminados en validar tracks), es decir, // llevan vivos 1 frames y tienen asignación válida tiempoVivo = frameData1->num_frame - NewTrack->Stats->InitTime ; if( tiempoVivo == 1 ){ //deteccion de nuevos tracks posiblemente válidos for(int j = 0;j < lsTracks->numeroDeElementos ; j++){ // si hay tracks durmiendo escogemos el nuevo track más cercano con un umbral SleepingTrack = (STTrack*)obtener(j, lsTracks); if( SleepingTrack->Stats->Estado == SLEEPING ){ // && SleepingTrack->id <= trackParams->MaxBlobs) ??si hay tracks durmiento // una vez se haya confirmado la validez de los tracks restringimos mas. // nos quedamos con el más cercano al punto donde se inicio el nuevo track a = NewTrack->Stats->InitPos.x - SleepingTrack->x_k_Pos->data.fl[0]; b = NewTrack->Stats->InitPos.y - SleepingTrack->x_k_Pos->data.fl[1]; EUDistance( a,b,&direccion, &distancia); if( (distancia < menorDistancia) && (distancia < (int)obtenerFilterParam( MAX_JUMP ) ) ){ masCercano = j; menorDistancia = distancia; } } } //Si se cumple la condición reasignamos if ( menorDistancia <= (int)obtenerFilterParam( MAX_JUMP )){ dejarId( NewTrack, lsIds ); reasignarTracks( lsTracks, framesBuf,lsIds,i,masCercano, UPDATE_STATS ); deadTrack( lsTracks, masCercano ); } } } }
void ordenarTracks( tlcde* lsTracks ){ STTrack* Track1; STTrack* Track2; int permutacion = 1; while( permutacion){ permutacion = 0; for( int i = 1; i < lsTracks->numeroDeElementos; i++){ Track1 = (STTrack*)obtener(i-1, lsTracks); Track2 = (STTrack*)obtener(i, lsTracks); if( Track1->id > Track2->id ){ permutacion = 1; Track1 = (STTrack*)borrarEl(i-1, lsTracks); // borra el elemento i-1. Actual apunta al sig (i) insertar( (STTrack*)Track1,lsTracks); // se inserta el track 1 a continuación del actual(i) } } } }
unsigned int sumFrame( tlcde* Flies ){ STFly* flyOut = NULL; float sumatorio = 0; unsigned int sumUint; for(int i = 0; i< Flies->numeroDeElementos ; i++){ flyOut = (STFly*)obtener(i,Flies); sumatorio = flyOut->VInst + sumatorio; } sumUint = ( unsigned int)cvRound(sumatorio); return sumUint; }
void Restaurar(tlcde* lista, IplImage* Fg, IplImage* Origin, CvRect Roi, int elemento) { STFly* FlyData; FlyData = (STFly *) obtener(elemento, lista); FlyData->failSeg = true; // restaurar cvSetImageROI(Origin, Roi); cvSetImageROI(Fg, Roi); cvCopy(Origin, Fg); cvResetImageROI(Origin); cvResetImageROI(Fg); }
main() { int i = 0; Elemento *llse = NULL; double *n = NULL, d = 0; printf("Introducir datos. Finalizar con eof.\n"); printf("Valor double: "); while(scanf("%lf", &d)!= EOF) { n = (double *)malloc(sizeof(double)); if(!n) error(); *n=d; anyadirAlPrincipio(n, &llse); printf("Valor double: "); } printf("\n"); i = 0; n = (double *)obtener(i, llse); while(n != NULL){ printf("%g \n", *n); // printf("%g \n", *n); por un formato variable de impresion de los numeros %lf por el double i++; n = (double *)obtener(i, llse); } printf("\n%d valores.\n", i); i=0; n=(double *)obtener(i, llse); while(n != NULL){ free(n); i++; n = (double *)obtener(i, llse); } borrarTodos(&llse); }
double CalcProbTotal(tlcde* Lista, SHModel* SH, ValParams* Params, STFly* FlyData) { double PX = 1; double Pxi = 0; for (int i = 0; i < Lista->numeroDeElementos; i++) { FlyData = (STFly *) obtener(i, Lista); CalcProbFly(SH, FlyData, Params); PX = PX * Pxi; } return PX; }
/*!\brief Calcula la Pxi de cada una de las flies resultado de la segmentación. En función de ésta * decide sobre si se a finalizado, se segmentará de nuevo alguno de los blobs resultantes por ser * aun muy grandeo bien se descarta la segmentación por dar algún blob un área demasiado pequeña, * restaurando así el original. * * Si el blob es válido ( sin exceso ni defecto) se establece flag_seg true ( segmentado correctamente ). Si no * es válido por exceso se establece flag_seg a false y se devuelve 1 (exito): el blob con exceso será * segmentado de nuevo. * si no es válida por defecto, se establece flag_seg a false pero en este caso se devuelve un 0 (fallo). Se * restaura el blob original. * * si Exeso = 0 => segmentación correcta. * si Exceso = 1 => segmentación correcta pero aun hay exceso * si Exceso = -1 => fallo en segmentación. Uno de los blobs es demasiado pequeño. * @param TempSeg * @param SH * @param Params * @return 1 si éxito, 0 si fallo. */ int comprobarPxi(tlcde* TempSeg, SHModel* SH, ValParams* Params) { STFly* FlyData; int Exceso; for (int j = 0; j < TempSeg->numeroDeElementos; j++) { // Calcular Pxi del/los blob/s resultante/s FlyData = (STFly *) obtener(j, TempSeg); Exceso = CalcProbFly(SH, FlyData, Params); if (Exceso == 0) FlyData->flag_seg = true; else if (Exceso == 1) FlyData->flag_seg = false; else if (Exceso == -1) return 0; // algún elemento no es correca } return 1; // correcta. aquellos con flyseg = false serán segmentados de nuevo }
void statsBloB(STFrame* frameDataOut ){ STFly* fly = NULL; frameDataOut->Stats->TotalBlobs = frameDataOut->Flies->numeroDeElementos; for(int i = 0; i< frameDataOut->Stats->TotalBlobs ; i++){ fly = (STFly*)obtener(i,frameDataOut->Flies); if( fly->Estado == 1 ) frameDataOut->Stats->dinamicBlobs +=1; else frameDataOut->Stats->staticBlobs +=1; // velocidad instantánea // EUDistance( fly->Vx, fly->Vy, NULL, &fly->Stats->VInst); } frameDataOut->Stats->dinamicBlobs = (frameDataOut->Stats->dinamicBlobs/frameDataOut->Stats->TotalBlobs)*100; frameDataOut->Stats->staticBlobs = (frameDataOut->Stats->staticBlobs/ frameDataOut->Stats->TotalBlobs)*100; }
void cleanGhosts( IplImage* FG, tlcde* flies ){ STFly* flyData = NULL; cvCreateTrackbar( "Umbral borde plato","Foreground", &valParams->umbralCleanGhosts, 100, onTrackBarClean); int Ghost; if( !flies||flies->numeroDeElementos == 0) return; for (int i = 0; i < flies->numeroDeElementos; i++) { // Almacenar la Roi del blob visitado antes de ser validado flyData = (STFly *) obtener(i, flies); Ghost = verificarBlob(FG, flyData ); // si es un reflejo, eliminar if( Ghost ){ if (flyData->Tracks ) free(flyData->Tracks); if (flyData->Stats) free(flyData->Stats); free(flyData); // borrar el área de datos del elemento eliminado flyData = NULL; flyData = (STFly *)borrarEl(i,flies); i--; } } }
void mediaMovil( STStatsCoef* Coef, tlcde* vector, STStatFrame* Stats ){ valorSum* valor; valorSum* valorT; // Se suma el nuevo valor valorT = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 , vectorSumFr ); Coef->F1SSum = Coef->F1SSum + valorT->sum; Coef->F1SSum2 = Coef->F1SSum2 + valorT->sum*valorT->sum; Coef->F30SSum = Coef->F30SSum + valorT->sum; Coef->F30SSum2 = Coef->F30SSum2 + valorT->sum*valorT->sum; Coef->F1Sum = Coef->F1Sum + valorT->sum; Coef->F1Sum2 = Coef->F1Sum + valorT->sum*valorT->sum; Coef->F5Sum = Coef->F5Sum + valorT->sum; Coef->F5Sum2 = Coef->F5Sum2 + valorT->sum*valorT->sum; Coef->F10Sum = Coef->F10Sum + valorT->sum; Coef->F10Sum2 = Coef->F10Sum2 +valorT->sum*valorT->sum; Coef->F30Sum = Coef->F30Sum + valorT->sum; Coef->F30Sum2 = Coef->F30Sum2 + valorT->sum*valorT->sum; Coef->F1HSum = Coef->F1HSum + valorT->sum; Coef->F1HSum2 = Coef->F1HSum2 + valorT->sum*valorT->sum; Coef->F2HSum = Coef->F2HSum + valorT->sum; Coef->F2HSum2 = Coef->F2HSum2 + valorT->sum*valorT->sum; Coef->F4HSum = Coef->F4HSum + valorT->sum; Coef->F4HSum2 = Coef->F4HSum2 + valorT->sum*valorT->sum; Coef->F8HSum = Coef->F48HSum + valorT->sum; Coef->F8HSum2 = Coef->F48HSum2 + valorT->sum*valorT->sum; if((unsigned)vector->numeroDeElementos > Coef->F1S){ // los que hayan alcanzado el valor máximo restamos al sumatorio el primer valor valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F1S, vectorSumFr ); Coef->F1SSum = Coef->F1SSum - valor->sum; // sumatorio para la media Coef->F1SSum2 = Coef->F1SSum2 - (valor->sum*valor->sum); // sumatorio para la varianza Stats->CMov1SMed = Coef->F1SSum / Coef->F1S; // cálculo de la media Stats->CMov1SDes = sqrt( abs(Coef->F1SSum2 / Coef->F1S - Stats->CMov1SMed*Stats->CMov1SMed ) ); // cálculo de la desviación } if(vector->numeroDeElementos > Coef->F30S){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F30S, vectorSumFr ); Coef->F30SSum = Coef->F30SSum - valor->sum; // sumatorio para la media Coef->F30SSum2 = Coef->F30SSum2 - (valor->sum*valor->sum); // sumatorio para la varianza Stats->CMov30SMed = Coef->F30SSum / Coef->F30S; Stats->CMov30SDes = sqrt( abs(Coef->F30SSum2 / Coef->F30S - Stats->CMov30SMed*Stats->CMov30SMed )); } if(vector->numeroDeElementos > Coef->F1){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F1, vectorSumFr ); Coef->F1Sum = Coef->F1Sum - valor->sum; Coef->F1Sum2 = Coef->F1Sum2 - (valor->sum*valor->sum); Stats->CMov1Med = Coef->F1Sum / Coef->F1; Stats->CMov1Des = sqrt( abs(Coef->F1Sum2 / Coef->F1 - Stats->CMov1Med *Stats->CMov1Med )) ; } if(vector->numeroDeElementos > Coef->F5){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F5, vectorSumFr ); Coef->F5Sum = Coef->F5Sum - valor->sum; Coef->F5Sum2 = Coef->F5Sum2 - (valor->sum*valor->sum); Stats->CMov5Med = Coef->F5Sum / Coef->F5; Stats->CMov5Des = sqrt( abs(Coef->F5Sum2 / Coef->F5 - Stats->CMov5Med *Stats->CMov5Med )); } if(vector->numeroDeElementos > Coef->F10){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F10, vectorSumFr ); Coef->F10Sum = Coef->F10Sum - valor->sum; Coef->F10Sum2 = Coef->F10Sum2 - (valor->sum*valor->sum); Stats->CMov10Med = Coef->F10Sum / Coef->F10; Stats->CMov10Des = sqrt( abs(Coef->F10Sum2 / Coef->F10 - Stats->CMov10Med*Stats->CMov10Med)); } if(vector->numeroDeElementos > Coef->F15){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F15, vectorSumFr ); Coef->F15Sum = Coef->F15Sum - valor->sum; Coef->F15Sum2 = Coef->F15Sum2 - (valor->sum*valor->sum); Stats->CMov15Med = Coef->F15Sum / Coef->F15; Stats->CMov15Des = sqrt( abs(Coef->F15Sum2 / Coef->F15 - Stats->CMov15Med*Stats->CMov15Med)); } if(vector->numeroDeElementos > Coef->F30){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F30, vectorSumFr ); Coef->F30Sum = Coef->F30Sum - valor->sum; Coef->F30Sum2 = Coef->F30Sum2- (valor->sum*valor->sum); Stats->CMov30Med = Coef->F30Sum / Coef->F30; Stats->CMov30Des = sqrt( abs(Coef->F30Sum2 / Coef->F30 - Stats->CMov30Med*Stats->CMov30Med)); } if(vector->numeroDeElementos > Coef->F1H){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F1H, vectorSumFr ); Coef->F1HSum = Coef->F1HSum - valor->sum; Coef->F1HSum2 = Coef->F1HSum2 - (valor->sum*valor->sum); Stats->CMov1HMed = Coef->F1HSum / Coef->F1H; Stats->CMov1HDes = sqrt( abs(Coef->F1HSum2 / Coef->F1H - Stats->CMov1HMed*Stats->CMov1HMed)); } if(vector->numeroDeElementos > Coef->F2H){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F2H, vectorSumFr ); Coef->F2HSum = Coef->F2HSum - valor->sum; Coef->F2HSum2 = Coef->F2HSum2 - (valor->sum*valor->sum); Stats->CMov2HMed = Coef->F2HSum / Coef->F2H; Stats->CMov2HDes = sqrt( abs(Coef->F2HSum2 / Coef->F2H - Stats->CMov2HMed*Stats->CMov2HMed)); } if(vector->numeroDeElementos > Coef->F4H){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F4H, vectorSumFr ); Coef->F4HSum = Coef->F4HSum - valor->sum; Coef->F4HSum2 = Coef->F4HSum2- (valor->sum*valor->sum); Stats->CMov4HMed = Coef->F4HSum / Coef->F4H; Stats->CMov4HDes = sqrt( abs(Coef->F4HSum2 / Coef->F4H - Stats->CMov4HMed*Stats->CMov4HMed)); } if(vector->numeroDeElementos > Coef->F8H){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F8H, vectorSumFr ); Coef->F8HSum = Coef->F48HSum - valor->sum; Coef->F8HSum2 = Coef->F8HSum2 - (valor->sum*valor->sum); Stats->CMov8HMed = Coef->F8HSum / Coef->F8H; Stats->CMov8HDes = sqrt( abs(Coef->F8HSum2 / Coef->F8H - Stats->CMov8HMed*Stats->CMov8HMed)); } if(vector->numeroDeElementos > Coef->F16H){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F16H, vectorSumFr ); Coef->F16HSum = Coef->F16HSum - valor->sum; Coef->F16HSum2 = Coef->F16HSum2 - (valor->sum*valor->sum); Stats->CMov16HMed = Coef->F16HSum / Coef->F16H; Stats->CMov16HDes = sqrt( abs(Coef->F16HSum2 / Coef->F16H - Stats->CMov16HMed*Stats->CMov16HMed)); } if(vector->numeroDeElementos > Coef->F24H){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F24H, vectorSumFr ); Coef->F24HSum = Coef->F24HSum - valor->sum; Coef->F24HSum2 = Coef->F24HSum2 - (valor->sum*valor->sum); Stats->CMov24HMed = Coef->F24HSum / Coef->F24H; Stats->CMov24HDes = sqrt( abs(Coef->F24HSum2 / Coef->F24H - Stats->CMov24HMed*Stats->CMov24HMed)); } if(vector->numeroDeElementos > Coef->F48H){ valor = ( valorSum*)obtener( vectorSumFr->numeroDeElementos-1 - Coef->F48H, vectorSumFr ); Coef->F48HSum = Coef->F48HSum - valor->sum; Coef->F48HSum2 = Coef->F48HSum2 - (valor->sum*valor->sum); Stats->CMov48HMed = Coef->F48HSum / Coef->F48H; Stats->CMov48HDes = sqrt( abs(Coef->F48HSum2 / Coef->F48H - Stats->CMov48HMed*Stats->CMov48HMed)); } }
void Validacion2(IplImage *Imagen, STFrame* FrameData, SHModel* SH,StaticBGModel* BGModel, IplImage* Mask) { //Inicializar estructura para almacenar los datos cada mosca STFly *FlyData = NULL; int Exceso;//Flag que indica si la Pxi minima no se alcanza por exceso o por defecto. double Circul; // Para almacenar la circularidad del blob actual double Besthres = 0;// el mejor de los umbrales perteneciente a la mejor probabilidad double BestPxi = 0; // la mejor probabilidad obtenida para cada mosca // Establecemos los parámetros de validación por defecto // establecer los umbrales de resta iniciales if (valParams->privateParams == NULL) { PrivateValParams(SH,BGModel, &valParams->privateParams); } // Establecemos parámetros para los umbrales en la resta de fondo por defecto ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; if( SH->FlyAreaDes == 0){ printf("hola"); } // almacenar una copia del FG para restaurar el blob en caso de que falle la validación cvCopy(FrameData->FG, Mask); // Recorremos los blobs uno por uno y los validamos. // Bucle for desde el primero hasta el ultimo individuo de la Lista FrameData->Flie del frame actual. // Los blobs resultantes de la fisión se añaden al final para ser validados de nuevo if (SHOW_VALIDATION_DATA) mostrarFliesFrame(FrameData); for (int i = 0; i < FrameData->Flies->numeroDeElementos; i++) { // Almacenar la Roi del blob visitado antes de ser validado FlyData = (STFly *) obtener(i, FrameData->Flies); if (FlyData->flag_seg == true) continue; // si el blob ha sido validado y es correcto pasar al siguiente CvRect FlyDataRoi = FlyData->Roi; // Inicializar LOW_THRESHOLD y demas valores ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; FlyData->bestTresh = ValBGParams->LOW_THRESHOLD; // calcular su circularidad Circul = CalcCircul(FlyData); // Comprobar si existe Exceso o Defecto de area, en caso de Exceso la probabilidad del blob es muy pequeña // y el blob puede corresponder a varios blobs que forman parte de una misma moscas o puede corresponder a // un espurio. Exceso = CalcProbFly(SH, FlyData, valParams); // Calcular la px de la mosca. BestPxi = FlyData->Px; STFly* MejorFly = FlyData;// = NULL; // comprobar si está dentro de los límites: // Params->MaxLowTH = *ObtenerMaximo(Imagen, FrameData ,FlyData->Roi); // En caso de EXCESO de Area /* Incrementar paulatinamente el umbral de resta de fondo hasta * que haya fisión o bien desaparzca el blob sin fisionarse o bien * no se supere la pximin. * - Si hay fisión: * -si los blobs tienen una probabilidad mayor que la pximin fin segmentacion * -si alguno de ellos tiene una probabilidad menor a la pximin, restaurar original y aplicar EM * - Si no hay fisión: Si el blob desaparece antes de alcanzar la pximin o * bien alcanza la pximin, restablecer el tamaño original del blob para aplicar EM * */ if (Exceso > 0) { //Inicializar estructura para almacenar la lista de los blobs divididos. tlcde* TempSeg = NULL; ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; // sustituir por un for con el número máximo de iteraciones. int j = 0; while (1) { // primero probar con el umbral anterior. si el blob desaparece o no da un resutado satisfactorio // proceder desde el umbral predetermindado // Incrementar umbral ValBGParams->LOW_THRESHOLD += 1; j++; // Restar fondo BackgroundDifference(Imagen, FrameData->BGModel, NULL, FrameData->FG, ValBGParams, FlyDataRoi); //verMatrizIm(FrameData->FG, FlyDataRoi); // Segmentar TempSeg = segmentacion2(Imagen, FrameData->BGModel, FrameData->FG, FlyDataRoi, NULL); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); // Comprobar si se ha conseguido dividir el blob y verificar si el resultado es optimo // 1) El blob desaparece antes de alcanzar la pximin sin dividirse. Restauramos el blob y pasamos al siguiente elemento. if (TempSeg->numeroDeElementos < 1 || TempSeg == NULL) { RestaurarElMejor(FrameData->Flies, FrameData->FG, MejorFly, FlyDataRoi, i); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); // liberar lista liberarListaFlies(TempSeg); break; } // 2) mientras no haya fisión else if (TempSeg->numeroDeElementos == 1) { FlyData = (STFly *) obtener(0, TempSeg); Exceso = CalcProbFly(SH, FlyData, valParams); // no se rebasa la pximin.Almacenar la probabilidad mas alta y continuar if (Exceso > -1 && j < valParams->MaxIncLTHIters && ValBGParams->LOW_THRESHOLD < valParams->MaxLowTH) { if (FlyData->Px >= BestPxi) { MejorFly = FlyData; BestPxi = FlyData->Px; Besthres = ValBGParams->LOW_THRESHOLD; } liberarListaFlies(TempSeg); free(TempSeg); TempSeg = NULL; continue; } // se ha rebasado la pxmin o bien se ha alcanzado el máximo de iteraciones o bien se ha llegado // al máximo valor permitido. Restaurar y pasar al siguiente else { RestaurarElMejor(FrameData->Flies, FrameData->FG, MejorFly, FlyDataRoi, i); //Restaurar(FrameData->Flies, FrameData->FG, Mask, FlyDataRoi, i); liberarListaFlies(TempSeg); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); break; } } // 3) Hay fisión else if (TempSeg->numeroDeElementos > 1) { // comprobar si las pxi son válidas. En caso de que todas lo sean eliminar de la lista el blob segmentado // y añadirlas a la lista al final. int exito = comprobarPxi(TempSeg, SH, valParams); if (exito) { borrarEl(i, FrameData->Flies); // se borra el elemento dividido for (int j = 0; j < TempSeg->numeroDeElementos; j++) { // se añaden los nuevos al final FlyData = (STFly *) obtener(j, TempSeg); anyadirAlFinal(FlyData, FrameData->Flies); } if (SHOW_VALIDATION_DATA){ printf("\n Lista Flies tras FISION\n"); mostrarFliesFrame(FrameData); } i--; // decrementar i para no saltarnos un elemento de la lista break; // salir del while } // Se ha rebasado la pximin en alguno de los blobs resultantes. Restauramos y pasamos al sig. blob else { liberarListaFlies(TempSeg); Restaurar(FrameData->Flies, FrameData->FG, Mask, FlyDataRoi, i); break; // salir del while } } }// Fin del While //liberarListaFlies( TempSeg ); if (TempSeg) free(TempSeg); TempSeg = NULL; } //Fin Exceso /* En el caso de DEFECTO disminuir el umbral, para maximizar la probabilidad del blob * Si no es posible se elimina (spurio) */ else if (Exceso < 0) { STFly* MejorFly = NULL; CvRect newRoi; tlcde* TempSeg = NULL; ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; newRoi = FlyDataRoi; BestPxi = 0; int j = 0; while (j < valParams->MaxDecLTHIters) { newRoi.height += 1; newRoi.width += 1; newRoi.x -= 1; newRoi.y -= 1; ValBGParams->LOW_THRESHOLD -= 1; if (ValBGParams->LOW_THRESHOLD == valParams->MinLowTH) { Restaurar(FrameData->Flies, FrameData->FG, Mask, FlyDataRoi, i); break; } //while(Exceso < 0 && ValBGParams->LOW_THRESHOLD > Params->MinLowTH && Params->MaxDecLTHIters){ // Restar fondo BackgroundDifference(Imagen, FrameData->BGModel, FrameData->IDesvf, FrameData->FG, ValBGParams, newRoi); // Segmentar TempSeg = segmentacion2(Imagen, FrameData->BGModel, FrameData->FG, newRoi, NULL); //TempSeg = segmentacion(Imagen, FrameData, newRoi,NULL); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); if (TempSeg == NULL || TempSeg->numeroDeElementos < 1) continue; // Calcular la pxi FlyData = (STFly *) obtener(0, TempSeg); Exceso = CalcProbFly(SH, FlyData, valParams); // Calcular la px de la mosca. // mientras la probabilidad se incremente continuamos decrementando el umbral j++; if (FlyData->Px >= BestPxi) { MejorFly = (STFly *) obtener(0, TempSeg); BestPxi = FlyData->Px; Besthres = ValBGParams->LOW_THRESHOLD; } else if (FlyData->Px < BestPxi || j == valParams->MaxDecLTHIters) { // cuando deje de mejorar o bien se llegue al máximo de iteraciones //nos quedamos con aquel que dio la mejor probabilidad. Lo insertamos en la lista en la misma posición. DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); sustituirEl(MejorFly, FrameData->Flies, i); break; } liberarListaFlies(TempSeg); if (TempSeg) { free(TempSeg); TempSeg = NULL; } }// FIN WHILE liberarListaFlies(TempSeg); if (TempSeg) free(TempSeg); }// FIN DEFECTO }//FOR dibujarBGFG( FrameData->Flies,FrameData->FG,1); if (valParams->CleanGhosts){ cleanGhosts(FrameData->FG, FrameData->Flies); dibujarBGFG( FrameData->Flies,FrameData->FG,1); cvAdd( FrameData->FG, maskCleanGhost, FrameData->FG); } }//Fin de Validación
void menu(matriz A, matriz B) {int op; limpiar();double x; gotoxy(10,5); cout<<"[1] OBTENER UN ELEMENTO DE A.."; gotoxy(10,6); cout<<"[2] OBTENER UN ELEMENTO DE B.."; gotoxy(10,7); cout<<"[3] ASIGNAR UN ELEMENTO DE A.."; gotoxy(10,8); cout<<"[4] ASIGNAR UN ELEMENTO DE B.."; gotoxy(10,9); cout<<"[5] IGUALAR A<-B.............."; gotoxy(10,10); cout<<"[6] IGUALAR B<-A.............."; gotoxy(10,11); cout<<"[7] SUMAR A + B..............."; gotoxy(10,12); cout<<"[8] NEGATIVA DE A............."; gotoxy(10,13); cout<<"[9] NEGATIVA DE B............."; gotoxy(10,14); cout<<"[10] RESTAR A - B............."; gotoxy(10,15); cout<<"[11] RESTAR B - A............."; gotoxy(10,16); cout<<"[12] ESCALAR PARA A..........."; gotoxy(10,17); cout<<"[13] ESCALAR PARA B..........."; gotoxy(10,18); cout<<"[14] PRODUCTO A * B..........."; gotoxy(10,19); cout<<"[15] PRODUCTO B * A..........."; gotoxy(10,20); cout<<"[16] TRANSPUESTA DE A........."; gotoxy(10,21); cout<<"[17] TRANSPUESTA DE B........."; gotoxy(10,22); cout<<"[18] DETERMINANTE DE A........"; gotoxy(10,23); cout<<"[19] DETERMINANTE DE B........"; gotoxy(10,24); cout<<"[20] INVERSA DE A............."; gotoxy(10,25); cout<<"[21] INVERSA DE B............."; gotoxy(10,26); cout<<"[22] SALIR...................."; do{gotoxy(22,28); cout<<"Seleccione una opcion (1-22): ";cin>>op; if(op<1 || op>22) {gotoxy(20,28);cout<<"Opci¢n incorrecta vuelva a intentar";} }while(op<1 || op>22); switch(op) {case 1: {limpiar();gotoxy(28,4); cout<<"[1] OBTENER UN ELEMENTO DE A.."; obtener(A);menu(A,B);break;} case 2: {limpiar(); gotoxy(28,4); cout<<"[2] OBTENER UN ELEMENTO DE B.."; obtener(B);menu(A,B);break;} case 3: {limpiar(); gotoxy(28,4); cout<<"[3] ASIGNAR UN ELEMENTO DE A.."; imprimir(asignar(A));getchar();menu(A,B);break;} case 4: {limpiar(); gotoxy(28,4); cout<<"[4] ASIGNAR UN ELEMENTO DE B.."; imprimir(asignar(B));getchar();menu(A,B);break;} case 5: {limpiar(); gotoxy(28,4); cout<<"[5] IGUALAR A<-B.............."; imprimir(igual(A,B));menu(A,B);break;} case 6: {limpiar(); gotoxy(28,4); cout<<"[6] IGUALAR B<-A.............."; imprimir(igual(B,A));menu(A,B);break;} case 7: {limpiar(); gotoxy(28,4); cout<<"[7] SUMAR A + B..............."; imprimir(sumar(A,B));menu(A,B);break;} case 8: {limpiar(); gotoxy(28,4); cout<<"[8] NEGATIVA DE A............."; imprimir(negativa(A));menu(A,B);break;} case 9: {limpiar(); gotoxy(28,4); cout<<"[9] NEGATIVA DE B............."; imprimir(negativa(B));menu(A,B);break;} case 10: {limpiar(); gotoxy(28,4); cout<<"[10] RESTAR A - B............."; imprimir(restar(A,B));menu(A,B);break;} case 11: {limpiar(); gotoxy(28,4); cout<<"[11] RESTAR B - A............."; imprimir(restar(B,A));menu(A,B);break;} case 12: {limpiar(); gotoxy(28,4); cout<<"[12] ESCALAR PARA A..........."; imprimir(escalar(A));menu(A,B);break;} case 13: {limpiar(); gotoxy(28,4); cout<<"[13] ESCALAR PARA B..........."; imprimir(escalar(B));menu(A,B);break;} case 14: {limpiar(); gotoxy(28,4); cout<<"[14] PRODUCTO A * B..........."; imprimir(producto(A,B));menu(A,B);break;} case 15: {limpiar(); gotoxy(28,4); cout<<"[15] PRODUCTO B * A..........."; imprimir(producto(B,A));menu(A,B);break;} case 16: {limpiar(); gotoxy(28,4); cout<<"[16] TRANSPUESTA DE A........."; imprimir(transpuesta(A));menu(A,B);break;} case 17: {limpiar(); gotoxy(28,4); cout<<"[17] TRANSPUESTA DE B........."; imprimir(transpuesta(B));menu(A,B);break;} case 18: {limpiar(); gotoxy(28,4); cout<<"[18] DETERMINANTE DE A........"; x=det(A);gotoxy(5,5);cout<<"Determinante = "<<x;getchar();menu(A,B);break;} case 19: {limpiar(); gotoxy(28,4); cout<<"[19] DETERMINANTE DE B........"; x=det(B);gotoxy(5,5);cout<<"Determinante = "<<x;getchar();menu(A,B);break;} case 20: {limpiar(); gotoxy(28,4); cout<<"[20] INVERSA DE A............."; inversa(A);menu(A,B);break;} case 21: {limpiar(); gotoxy(28,4); cout<<"[21] INVERSA DE B............."; inversa(B);menu(A,B);break;} case 22: {limpiar(); gotoxy(28,4); cout<<"[22] SALIR...................."; gotoxy(10,10); cout<<"Saliendo..."; gotoxy(25,23); cout<<"Presione Enter Para Salir...";break; } } }
/*!\brief Si recibe track nuevo: * Sustituye el track antiguo por el nuevo, actualiza los datos del nuevo en base a los del antiguo. * si no hay trak nuevo: * Elimina todo rastro del track antiguo incluyendo el blob que rastreaba. Este caso es de tracks que seguian a blobs con una * alta probabilidad de ser falsos. * * * * @param lsTracks * @param nuevo * @param viejo * @param framesBuf */ void reasignarTracks( tlcde* lsTracks,tlcde* framesBuf, tlcde* lsIds , int nuevo, int viejo, int Accion ){ // obtener posicion del buffer desde la que hay que corregir. STFrame* frameData1 = NULL; STTrack* NewTrack = NULL; STTrack* SleepingTrack = NULL; STFly* Fly = NULL; int posInit; // posición del buffer desde la que se inicia la correción // obtener Track// SleepingTrack = (STTrack*)obtener(viejo, lsTracks); if(Accion != BORRAR ) NewTrack= (STTrack*)obtener(nuevo, lsTracks); if(Accion == BORRAR || Accion == RE_ETIQUETAR){ // en caso de que no haya nuevo track, posInit = (framesBuf->numeroDeElementos-1) - SleepingTrack->Stats->FrameCount ; if(posInit < 0) posInit = 0; // eliminamos del buffer los datos de su fly. if(Accion == RE_ETIQUETAR){ SleepingTrack->id = NewTrack->id; SleepingTrack->Color = NewTrack->Color; } irAl( posInit,framesBuf); for( int i = posInit; i < framesBuf->numeroDeElementos; i++ ){ // obtener frame frameData1 = (STFrame*)obtenerActual( framesBuf); //frameData1 = (STFrame*)obtener(i, framesBuf); irAlPrincipio( frameData1->Flies); for( int j = 0;j < frameData1->Flies->numeroDeElementos ; j++){ Fly = (STFly*)obtenerActual( frameData1->Flies); if( Accion == BORRAR){ // Limpiar datos del track indicado por la variable viejo y su blob if( Fly->etiqueta == SleepingTrack->id ){ borrar(frameData1->Flies); if (Fly->Tracks ) free(Fly->Tracks); if (Fly->Stats) free(Fly->Stats); free(Fly); // borrar el área de datos del elemento eliminado } }// se etiquetan las flies con id del viejo con la id del nuevo. Se continuará con el viejo // re_etiquetado como el nuevo. else if( Accion == RE_ETIQUETAR){ Fly = (STFly*)obtenerActual( frameData1->Flies); if( Fly->etiqueta == SleepingTrack->id ){ Fly->etiqueta = NewTrack->id; Fly->Color = NewTrack->Color; } } irAlSiguiente(frameData1->Flies ); } irAlSiguiente( framesBuf); } } else{ // se actualiza el nuevo con los datos del antiguo y se continua con el nuevo // obtener posición desde la que se corrige la id. posInit = framesBuf->numeroDeElementos - NewTrack->Stats->FrameCount ; // corregir buffer. No se eliminan los datos de la fly, sino que se actualizan if(posInit < 0) posInit = 0; // Usar la etiqueta, no fly sig, ya que sino se pisaría la etiqueta 0 ( KAM_CONTROL ) for( int i = posInit; i < framesBuf->numeroDeElementos; i++ ){ // obtener frame frameData1 = (STFrame*)obtener(i, framesBuf); for( int j = 0;j < frameData1->Flies->numeroDeElementos ; j++){ Fly = (STFly*)obtener(j, frameData1->Flies); if( Fly->etiqueta == NewTrack->id ){ if( Accion == ONLY_UPDATE_IDS){ Fly->etiqueta = SleepingTrack->id; Fly->Color = SleepingTrack->Color; } else{ Fly->etiqueta = SleepingTrack->id; Fly->Color = SleepingTrack->Color; Fly->dstTotal = SleepingTrack->Stats->dstTotal + Fly->dstTotal; } } } } // ACTUALIZAR TRACK if( Accion == ONLY_UPDATE_IDS){ NewTrack->id = SleepingTrack->id; NewTrack->Color = SleepingTrack->Color; }else{ NewTrack->id = SleepingTrack->id; NewTrack->Color = SleepingTrack->Color; NewTrack->Stats->dstTotal = SleepingTrack->Stats->dstTotal + NewTrack->Stats->dstTotal; NewTrack->Stats->FrameCount = SleepingTrack->Stats->FrameCount; NewTrack->Stats->InitTime = SleepingTrack->Stats->InitTime; NewTrack->Stats->InitPos = SleepingTrack->Stats->InitPos; NewTrack->Stats->TimeBlobOff = SleepingTrack->Stats->TimeBlobOff + NewTrack->Stats->TimeBlobOff; NewTrack->Stats->TimeBlobOn = SleepingTrack->Stats->TimeBlobOn + NewTrack->Stats->TimeBlobOn; } } }
void corregirTracks( tlcde* framesBuf, tlcde* lsTracks, tlcde* lsIds){ STFrame* frameData1; STTrack* NewTrack; STTrack* SleepingTrack; int masAntiguo ; int tiempoVivo; // posición (tiempo) desde el que se van a examinar nuevos tracks // si fuese 0 se pisaría a despertarTrack frameData1 = (STFrame*)obtener(framesBuf->numeroDeElementos-1, framesBuf); // irAlPrincipio( lsTracks); for(int i = 0;i < lsTracks->numeroDeElementos ; i++){ // obtener Track// de los durmiendo, buscamos asignar en primer lugar el de etiqueta más baja. // damos prioridad a los menores o iguales a maxTrack, como están en orden, recorremos la lista // en orden SleepingTrack = (STTrack*)obtener(i, lsTracks); // if( SleepingTrack->Stats->Estado == SLEEPING && // SleepingTrack->id <= trackParams->MaxBlobs && // SleepingTrack->EstadoCount == MAX_BUFFER ) if( SleepingTrack->Stats->Estado == SLEEPING && SleepingTrack->Stats->EstadoCount >= (unsigned)trackParams->MaxBuffer-1 ){ //todo antes era == // intentamos asignarle un nuevo track // damos prioridad a los que tengan la menor etiqueta frente a los más altos, // que es lo mismo que escojer el nuevo track más antiguo int ultimo = 0; for( int j = 0;j < lsTracks->numeroDeElementos ; j++){ // de los nuevos asignaremos el que lleve más tiempo vivo. NewTrack = (STTrack*)obtener(j, lsTracks); tiempoVivo = frameData1->num_frame - NewTrack->Stats->InitTime; if( tiempoVivo < trackParams->MaxBuffer && tiempoVivo > ultimo ){ masAntiguo = j; ultimo = tiempoVivo; } } if( ultimo != 0){ dejarId( NewTrack, lsIds ); reasignarTracks( lsTracks, framesBuf,lsIds, masAntiguo , i, UPDATE_STATS ); deadTrack( lsTracks, i ); continue; // si se ha conseguido asignar continuar al siguiente } //. Si no es que no hay nuevos tracks. En este caso // si su etiqueta es menor que maxTracks, no hacer nada. Esperar a que aparezca el nuevo track. // Nunca será eliminado un track de este tipo. Se intentará reasignar al más adecuado en cuanto // sea posible if( SleepingTrack->id <= trackParams->MaxBlobs ) continue; // en cambio si su etiqueta es mayor, si durante un tiempo no aparecen nuevos tracks, eliminarlo // , dejar su id y eliminar los datos de la fly que creó. else { dejarId( SleepingTrack, lsIds ); reasignarTracks(lsTracks, framesBuf, lsIds, -1, i, BORRAR); deadTrack( lsTracks, i ); } } } }
int validarTracks(tlcde* framesBuf, tlcde* lsTracks, tlcde* identities, int MaxTracks, int numFrame ){ STTrack* Track = NULL; STTrack* Track2 = NULL; int valCount = 0; // VALIDAR NUEVOS TRACKS // únicamente serán validos aquellos tracks que los primeros instantes tengan asignaciones válidas // y unicas. Si no es así será un trackDead originado por ruido: // Un track será válido cuando se verifique que es estable. Un track se considerará estable cuando // transcurran T frames sin pasar a estado KalmanControl desde su nacimiento. Si no es estable será // eliminado. Si se ha eliminado un track prioritario y existe un track de id mayor a max track // a dicho track se le asignará la id del track eliminado. if( lsTracks->numeroDeElementos < 1) return 0; irAlPrincipio( lsTracks); for(int i = 0;i < lsTracks->numeroDeElementos ; i++){ // obtener Track Track = (STTrack*)obtenerActual( lsTracks); // eliminar los tracks creados en t y sin asignación en t+1 if( falsoTrack( Track, numFrame ) ){ dejarId( Track, identities ); reasignarTracks(lsTracks, framesBuf, identities, -1, i, BORRAR ); deadTrack( lsTracks, i ); } // ELIMINAR TRACKS NO VERIFICADOS // Eliminar tracks con alta id que hayan nacido hace menos de max buffer frames y pasen a estado kalmanControl unsigned int tiempoVivo = numFrame - Track->Stats->InitTime ; // Eliminar tracks con alta id que hayan nacido hace menos de T frames y pasen a estado kalmanControl if( (tiempoVivo <= 200) &&(Track->Stats->Estado != CAM_CONTROL)){ Track->validez = false; } else { Track->validez = true; } if( !Track->validez ) { // En los primeros MaxBuffer frames, si nos hemos cargado un track de los prioritarios // comprobar si hay tracks con id mayor a MaxTracks y reasignar el de mayor id y CamControl en caso afimativo if (framesBuf->numeroDeElementos< trackParams->MaxBuffer){ irAlFinal(lsTracks); for(int j = lsTracks->numeroDeElementos - 1; j = 0 ; j--){ unsigned int tiempoVivo = numFrame - Track->Stats->InitTime ; // si se encuentra un track en estado camControl de id mayor, se reasigna. El de mayor id // pasa a tomar la etiqueta del menor y se corrige el buffer, Track2 = (STTrack*)obtener( j,lsTracks); if( ( Track2->id > Track->id )&&(Track2->Stats->Estado == CAM_CONTROL)&&(Track2->Stats->EstadoCount == tiempoVivo )){ dejarId( Track2, identities ); reasignarTracks( lsTracks, framesBuf, identities, i , j, RE_ETIQUETAR ); deadTrack(lsTracks, i ); break; } else if(Track2->id == Track->id ){ // si no encuentra uno directamente se elimina dejarId( Track, identities ); reasignarTracks(lsTracks, framesBuf, identities,-1, i, BORRAR ); deadTrack(lsTracks, i ); } } } // Si ya ha transcurrido el periodo inicial, Se elimina (si su id es mayor que maxBlobs ?? ) else{ if( Track->id > trackParams->MaxBlobs){ dejarId( Track, identities ); reasignarTracks(lsTracks, framesBuf, identities, -1, i, BORRAR); deadTrack( lsTracks, i ); } } irAl( i-1, lsTracks); } irAlSiguiente( lsTracks); }//FIN FOR return valCount; }
void main(){ //mostramos una imagen super fancy imprimeImagenPrincipal(" "); printf("\n\n\tPulsa [ENTER] para comenzar!\n"); pausa(); //srand(time(NULL)); char opcion[STRING_MAX]; char opcionJuego[STRING_MAX]; boolean menu = TRUE; //variable del bucle del menu de opciones inicial boolean juego = FALSE; //variable del bucle del juego boolean buclePreJuego = FALSE; //variable del bucle de las opciones del juego boolean bucleTurnosJuego = FALSE; //variable del bucle de las jugadas //============================================ // BUCLE MENU PRINCIPAL //-------------------------------------------- while(menu){ //limpia la consola limpiar(); imprimeMenuPrincipal(); fflush(stdin); //limpia buffer entrada fgets(opcion, STRING_MAX, stdin); //Opciones de entrada //opcion 1: entrar a un juego nuevo. if(atoi(opcion) == 1){ buclePreJuego = TRUE; } //opcion 2: salir if(atoi(opcion) == 2){ menu = FALSE; } //==================================================== // BUCLE PRE-JUEGO //---------------------------------------------------- char cantidadJugadores[STRING_MAX]; nodo* jugadores = NULL; //jugadores nodo* mazo = NULL; //mazo del juego nodo* pozo = NULL; //donde se tiran las cartas nodo** manos = NULL; // cartas de los jugadores (puntero doble porque es un malloc de nodo*) while(buclePreJuego){ //==================================================== // CONDICIONES PRE-JUEGO //---------------------------------------------------- limpiar(); printf("Condiciones pre-juego.\n"); //cuantos jugadores (incluyendo el humano) printf("ingrese la cantidad de jugadores [2-10]: "); fflush(stdin); fgets(cantidadJugadores,STRING_MAX, stdin); printf("jugadores: %d\n", atoi(cantidadJugadores)); if(atoi(cantidadJugadores) < 2){ buclePreJuego = FALSE; } else{ //hacemos un arreglo de listas enlazadas que seran las manos. manos = (nodo**)malloc(sizeof(nodo*)*atoi(cantidadJugadores)); //generamos el mazo del juego con orden aleatorio mazo = crearMazo(); //colocamos una carta del mazo en el pozo. nodo* cartaInicial = obtener(mazo,0); //sacamos la primera carta pozo = push(pozo, cartaInicial->dato, cartaInicial->dato2); mazo = borrarTipo(mazo, cartaInicial->dato,cartaInicial->dato2); //agrega los jugadores a una lista... //...los CPU... int t; for(t=0;t<atoi(cantidadJugadores)-1;t++) { jugadores = push(jugadores, JUGADOR_CPU,-1); } //...y al humano. jugadores = push(jugadores, JUGADOR_HUMANO,-1); //agregamos las manos int j,m; for(j=0;j<atoi(cantidadJugadores);j++){ manos[j] = NULL; for(m=0; m<MANO_INICIAL;m++){ //numero random //vemos una carta cartaInicial = obtener(mazo,0); //sacamos la primera carta //se coloca en la mano manos[j]= push(manos[j],cartaInicial->dato,cartaInicial->dato2); //se borra del mazo mazo = borrarTipo(mazo, cartaInicial->dato,cartaInicial->dato2); } } //muestra los turnos del juego antes de comenzar. muestraTurnos(jugadores); //borrar //printf("largo del mazo: %d\n", largo(mazo)); //listarCartas(mazo); //fin borrar printf("\nPresione ENTER para comenzar la partida..."); pausa(); //terminamos condiciones pre-juego buclePreJuego = FALSE; //y vamos al bucle de turnos... bucleTurnosJuego = TRUE; } } //---------------------------------------------------------- // FIN bucle pre-juego //========================================================== //========================================================== // BUCLE TURNOS DEL JUEGO //---------------------------------------------------------- limpiar(); int turno=-1; //turno actual char opcionJuego[STRING_MAX]; //entrada por teclado char sentido = 1; //sentido de los turnos (para cartas invertir) nodo* jugadorActual; //jugador que le toca turno while(bucleTurnosJuego){ //verifica si quedan cartas en el mazo if(largo(mazo)<1){ //si no hay cartas voltea el pozo mazo = volteaPozo(&mazo,&pozo); } turno = estableceTurno(atoi(cantidadJugadores),turno, sentido); //imprime estado del juego imprimeEstadoJuego(mazo,pozo); //obtiene el jugador que le corresponde el turno. jugadorActual = obtener(jugadores,turno); if( jugadorActual->dato == JUGADOR_HUMANO){ printf("Tu turno!\n"); //muestra la mano del jugador mostrarMano(manos[turno]," "); //imprimirCartitas(largo(manos[turno])); //interaccion en turno printf(" Botar carta: "); fflush(stdin); fgets(opcionJuego,STRING_MAX,stdin); //reaccion a la opcion //================================================== // JUGADA DEL JUGADOR HUMANO //-------------------------------------------------- //si el turno no es exitoso, no se avanza al siguiente jugador... if(!logicaTurno(&manos[turno], &mazo, &pozo, &turno, opcionJuego)){ if(sentido){ turno--; } else turno++; } else{ if(largo(manos[turno])==0){ limpiar(); printf("\n\t\aFELICIDADES, HAS GANADO!!!\n\n"); imprimeEstadoJugadores(jugadores,manos); printf("\n\t\aFELICIDADES, HAS GANADO!!!\n\n"); bucleTurnosJuego = FALSE; printf("Presione [ENTER] para ontinuar..."); pausa(); } } //para salir if(atoi(opcionJuego) == -1){ bucleTurnosJuego = FALSE; } //-------------------------------------------------- // FIN jugada del jugador humano //================================================== //este "limpiar" permite que se vean solo las jugadas //de las CPU que se hacen hasta que le toca al usuario. limpiar(); } else{ //========================================================== //JUGADA AUTOMATICA DE COMPUTADORAS //---------------------------------------------------------- printf("Turno Computadora %d, mano:", turno+1); imprimirCartitas(largo(manos[turno])); //si el turno no es exitoso, no se avanza al siguiente jugador... if(!jugadaAutomatica(&manos[turno], &mazo, &pozo, &turno)){ if(sentido){ turno--; } else turno++; } else{ if(largo(manos[turno])==0){ limpiar(); imprimeEstadoJuego(mazo,pozo); printf("\n\t\aLA COMPUTADORA %d, HA GANADO!\n",turno+1); imprimeEstadoJugadores(jugadores,manos); printf("\n\t\aLA COMPUTADORA %d, HA GANADO!\n",turno+1); bucleTurnosJuego = FALSE; printf("Presione [ENTER] para continuar..."); pausa(); } } //----------------------------------------------------------- // FIN jugada automatica de computadoras //=========================================================== } } //-------------------------------------------------------------- // FIN bucle turnos juego //============================================================== //====================================== // LIBERACION DE MEMORIA //-------------------------------------- //liberamos lista de jugadores jugadores = anular(jugadores); //libera el mazo mazo = anular(mazo); //libarar el pozo pozo = anular(pozo); //libramos manos if(manos != NULL){ int d; for(d=0; d < atoi(cantidadJugadores);d++){ manos[d] = anular(manos[d]); } free(manos); } //------------------------------------- // FIN liberacion memoria //===================================== } //-------------------------------- // FIN bucle menu principal //================================ }