/** Esta função tem como objetivo imprimir as cartas no tabuleiro. Se a carta a apresentar se encontre na mão do jogador (mao toma o valor de 0 e o actual_jogador no estado for igual a 0), e caso a carta seja selecionada é então adicionada ao highlight. Se já se encontrar no highlight, então é removida de lá. Caso contrário, se a carta se encontrar na mão de um bot, é imprimido o verso de uma carta, caso contrário a carta já foi jogada por um bot logo é mostrada a carta correspondente. @param path O path. @param x Coordenada HTML. @param y Coordenada HTML. @param e O estado atual. @param mao Número de um jogador. @param naipe O naipe da carta (inteiro entre 0 e 3). @param valor O valor da carta (inteiro entre 0 e 12). */ void imprime_carta(char *path, int x, int y, ESTADO e, int mao, int naipe, int valor) { char *suit = NAIPES; char *rank = VALORES; char script[10240]; ESTADO novo = e; novo.card = 1; if (mao == 0 && e.actual_jogador == 0) { if (carta_existe (novo.highlight, naipe, valor)) { novo.highlight = rem_carta(novo.highlight, naipe, valor); } else { novo.highlight = add_carta(novo.highlight, naipe, valor); } sprintf(script, "%s?%s", SCRIPT, estado2str(novo)); printf("<a xlink:href = \"%s\"><image x = \"%d\" y = \"%d\" height = \"110\" width = \"80\" xlink:href = \"%s/%c%c.svg\" /></a>\n", script, x, y, path, rank[valor], suit[naipe]); } else { if (carta_existe(e.mao[1],naipe,valor) || carta_existe(e.mao[2],naipe,valor) || carta_existe(e.mao[3],naipe,valor)) printf("<image x = \"%d\" y = \"%d\" height = \"110\" width = \"80\" xlink:href = \"%s/11C.png\" />\n", x, y, path); else printf("<image x = \"%d\" y = \"%d\" height = \"110\" width = \"80\" xlink:href = \"%s/%c%c.svg\" />\n", x, y, path, rank[valor], suit[naipe]); } }
/* Função auxiliar que recebe parametros da função imprime. Aqui é vista a forma de como as cartas são apresentadas, neste caso por naipe. */ void imprime_aux_naipe (ESTADO e, int m, int bx1, int by1, int bx2, int by2, int bx3, int by3, int x, int y, char *path) { int n,v; for (n = 0; n < 4; n++){ for (v = 0; v < 13; v++) { if (m == 1 && carta_existe(e.cartas_bots[1],n,v)) { imprime_carta(path, bx1, by1, e, m, n, v); by1+=20; } if (m == 2 && carta_existe(e.cartas_bots[2],n,v)) { imprime_carta(path, bx2, by2, e, m, n, v); bx2+=20; } if (m == 3 && carta_existe(e.cartas_bots[3],n,v)) { imprime_carta(path,bx3, by3, e, m, n, v); by3 += 20; } if (carta_existe(e.mao[m], n, v)) { if (m % 2 == 0) { x += 30; } else { y += 30; } if (m == 0 && carta_existe(e.highlight, n, v)) { imprime_carta(path, x, (y - 20), e, m, n, v); } else { imprime_carta(path, x, y, e, m, n, v); } } } } }
/* * Numa jogada de 1,2 e 3 cartas esta função é utilizada para comparar o valor entre a ultima_jogada e a efetuda pelo atual_jogador. @param m A mão de um jogador. @returns O valor de uma carta. */ int da_valor (MAO m){ int n, v, primeiraCarta, flag = 0; primeiraCarta = 0; for (n = 0; n < 4 && flag != 1; n++) { for (v = 0; v < 13 && flag != 1; v++) if (carta_existe(m, n, v)){ primeiraCarta = v ; flag = 1; } } for (n = 0; n < 4 ; n++) { for (v = 0; v < 13 ; v++) if (carta_existe(m, n, v)){ if (v != primeiraCarta){ return -1 ; } } } return primeiraCarta; }
/** Ao receber o highlight do utilizador (neste caso um straight), confirma se este é válido para ser efetuada uma jogada. @param m A mão de um jogador. @returns Um inteiro 1, se for válido o straight, e -1 caso contrário. */ int valida_straight (MAO m) { int v,i,n,j; int contaValores[14]; for (i = 0; i < 14; i++) { contaValores[i] = 0; } i = 2; for (v = 0; v <= 13; v++) { for(n = 0; n < 4; n++) { switch (v) { case 11: if (carta_existe(m,n,v)) { contaValores[0]++; contaValores[13]++; } break; case 12: if (carta_existe(m,n,v)) { contaValores[1]++; } break; default: if (carta_existe(m,n,v)) { contaValores[i]++; } break; } } i++; } j = 0; while ((j + 4) < 14) { if ((contaValores[j] != 0) && (contaValores[j+1] != 0) && (contaValores[j+2] != 0) && (contaValores[j+3] != 0) && (contaValores[j+4] != 0)) { return 1; } j++; } return -1; }
/** Nas cartas selecionadas pelo utilizador (neste caso um straight flush), determina o valor da maior carta desse, para mais tarde comparar, se necessário, com as ultimas jogadas, de forma a avaliar a jogada. Esta função foi usada para avaliar a mão do utilizador, pois seguia o mesmo precedimento. A função retorna então o valor da maior carta de um straight se existir um straight, e -1 se não existir. @param m A mão de um jogador. @returns O valor de uma carta. */ int maior_carta_straight_bots(MAO m){ /* USAMOS MAIOR_CARTA_STRAIGHT_BOTS PARA AVALIAR A MAIOR CARTA DE UM STRAIGHT FLUSH, POIS ERA O MESMO PROCEDIMENTO */ int v,i,n,j; int contaValores[14]; for (i = 0; i < 14; i++) { contaValores[i] = 0; } i = 2; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { switch (v) { case 11: if (carta_existe(m,n,v)) { contaValores[0]++; contaValores[13]++; } break; case 12: if (carta_existe(m,n,v)) { contaValores[1]++; } break; default: if (carta_existe(m,n,v)) { contaValores[i]++; } break; } } i++; } if (contaValores[1] != 0) { j = 12; while ((j-4) >= 0) { if ((contaValores[j] != 0) && (contaValores[j-1] != 0) && (contaValores[j-3] != 0) && (contaValores[j-4] != 0)) { switch (j) { case 0: { j = 11; } break; case 1: { j = 12; } break; default: { j -= 2; } break; } return j; } j--; } } else { j = 13; while ((j-4) >= 1) { if ((contaValores[j] != 0) && (contaValores[j-1] != 0) && (contaValores[j-3] != 0) && (contaValores[j-4] != 0)) { switch (j) { case 0: { j = 11; } break; case 1: { j = 12; } break; default: { j -= 2; } break; } return j; } j--; } } return -1; }
/** Nas cartas selecionadas pelo utilizador (neste caso um four of a kind), determina o valor da maior carta de entre as quatro cartas com o mesmo valor, para mais tarde comparar, se necessário, com as ultimas jogadas, de forma a avaliar a jogada. @param m A mão de um jogador. @returns O valor das quatro cartas iguais. */ int maior_carta_fourkind (MAO m) { int v,i,x,n,j,var,flag; int contaValores[13]; var = -1; for (i = 0; i < 13; i++) { contaValores[i] = 0; } x = 0; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { if (carta_existe(m,n,v)) { contaValores[x]++; } } x++; } flag = 0; for (j = 12; j >= 0 && flag != 1; --j) { if ((contaValores[j]) == 4) { var = j; flag = 1; } } return var; }
/** Ao receber o highlight do utilizador (neste caso um four of a kind), confirma se este é válido para ser efetuada uma jogada. @param m A mão de um jogador. @returns Um inteiro 1, se for válido o four of a kind, e -1 caso contrário. */ int valida_fourkind (MAO m) { int v,i,n,j; int contaValores[13]; for (i = 0; i < 13; i++) { contaValores[i] = 0; } i = 0; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { if ((carta_existe(m,n,v))) { contaValores[i]++; } } i++; } for (j = 0; j < 13; j++) { if (contaValores[j] == 4) { return 1; } } return 0; }
/** Nas cartas selecionadas pelo utilizador (neste caso um fullhouse), determina o valor da maior carta do trio desse, para mais tarde comparar, se necessário, com as ultimas jogadas, de forma a avaliar a jogada. @param m A mão de um jogador. @returns O valor da maior carta do full house. */ int maior_carta_trio_fullhouse (MAO m) { int v,i,n,j,var; int contaValores[14]; var = 0; for (i = 0; i < 14; i++) { contaValores[i] = 0; } i = 0; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { if (carta_existe(m,n,v)) { contaValores[i]++; } } i++; } for (j = 0; j < 13; j++) { if (contaValores[j] == 3) { var = j; } } return var; }
/** Ao receber o highlight do utilizador (neste caso um fullhouse), confirma se este é válido para ser efetuada uma jogada. @param m A mão de um jogador. @returns O valor. */ int valida_fullhouse (MAO m) { int v,i,n,j,p,flag; int contaValores[13]; p=-1; flag=0; for (i = 0; i < 13; i++) { contaValores[i] = 0; } i = 0; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { if (carta_existe(m,n,v)) { contaValores[i]++; } } i++; } for (i = 0; i < 13 && flag != 1; i++) {; if (contaValores[i] >= 3 && flag != 1) { for (j = 0; j < 13 && flag != 1; j++) { if ((contaValores[j] >= 2) && j != i && flag != 1) { p = i; flag = 1; return p; } } } } return p; }
int fourofakindpos (DATABASE * simulacao, int jog, int sametype,MAO jogadas[40], int count) { /*sametype: 1-> a última jogada foi um four of a kind 0: foi uma jogada de rank inferior */ MAO temp = 0; int n,v, ind; int i = 0; int rank[13] = {0}; separa_val(simulacao->mao[jog], rank); if(sametype != 0){ i = (maior_carta_mao(simulacao->jogada) % 13) + 1; } for(; i < 13; i++) if(rank[i] == 4){ jogadas[count] = 0; temp = add_carta(temp,0,i); temp = add_carta(temp,1,i); temp = add_carta(temp,2,i); temp = add_carta(temp,3,i); for(ind = 0; ind < 52;ind++){ n = ind / 13; v = ind % 13; if(carta_existe(simulacao->mao[jog],n,v) && v != i){ jogadas[count] = add_carta(temp,n,v); count++; } } } return count; }
/** Esta função procura na mão um par válido para ser usado num full house. Se existir um par, é retornado o valor desse. @param m A mão de um jogador. @returns Valor de um par para full house. */ int maior_carta_par_fullhouse (MAO m) { int v,i,n,j,var,flag; int contaValores[13]; var = 0; for (i = 0; i < 13; i++) { contaValores[i] = 0; } i = 0; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { if (carta_existe(m,n,v)) { contaValores[i]++; } } i++; } flag = 0; for (j = 0; (j < 13) && (flag != 1); j++) { if (contaValores[j] >= 2) { var = j; flag = 1; } } return var; }
/** Para a formação de um four of a kind, é necessário quatro cartas com o mesmo valor mais uma carta qualquer existente na mão. Esta função escolhe essa carta, verificando primeiro se existe na mão. A primeira que for encontrada, é adicionada ao four of a kind. A função retorna o valor da primeira carta que encontra para juntar ao four of a kind. @param m A mão de um jogador. @returns O valor de uma carta. */ int da_carta_fourkind (MAO m) { int v,i,n,j,var=0,flag; int contaValores[13]; for (i = 0; i < 13; i++) { contaValores[i] = 0; } i = 0; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { if ((carta_existe(m,n,v))) { contaValores[i]++; } } i++; } flag = 0; for (j = 0; (j < 13) && (flag != 1); j++) { if (contaValores[j] == 1) { var = j; flag = 1; } } return var; }
/** Depois de ser validada um straight na mão de um dos bots, esta função determina o naipe da maior carta nesse straight, para se for necessário comparar com valores iguais. A função retorna o valor correspondente ao naipe da maior carta do straight existente. @param m A mão de um jogador. @param maiorCarta A maior carta de um straight. @returns O naipe da maior carta de um straight. */ int maior_naipe_straight_bots (MAO m, int maiorCarta) { int i,n; i = 0; for (n = 3; n >= 0; --n) { if (carta_existe(m,n,maiorCarta)) i = n; } return i; }
int fullhousepos (DATABASE * simulacao, int jog, int sametype, MAO jogadas[40], int count) { int rank[13] = {0}; int rank2[13] = {0}; int i = 0, v, n; int c = 0; MAO mao = simulacao->mao[jog], temp = 0; separa_val(mao, rank); if(sametype != 0){ separa_val(simulacao->jogada, rank2); for(i = 0; i < 13; i++) if(rank2[i] == 3){ ++i; break; } } for(; i < 13; i++){ temp = 0; if(rank[i] > 2){ for(n = 0; n < 4; n++) if(carta_existe(mao, n, i)){ temp = add_carta(temp,n,i); c++; if(c == 3){ c = 0; n = 4; } } for(v = 0; v < 13; v++) if(rank[v] > 1 && v != i){ jogadas[count] = temp; for(n = 0; n<4; n++) if(carta_existe(mao,n,v)){ jogadas[count] = add_carta(jogadas[count],n,v); c++; if(c == 2){ c = 0; count++; n = 4; } } } } } return count; }
/** Função que valida o highlight do jogador, para 1, 2 ou 3 cartas. Aqui, é permitido ao utilizador jogar uma das 3 combinações. @param e O estado actual. @returns Um inteiro 1 se for possível jogar, caso contrário retorna 0. */ int utilizador_joga_singles_pares_triplos (ESTADO e) { if (e.ultima_jogada == -1) { if (!combinacao_valida (e.highlight) ) { return 0; } else { if (e.actual_jogador != 0) { return 0; } else { if ((da_valor (e.highlight) != -1) && (carta_existe(e.highlight, 0, 0))) { return 1; } else return 0; } } } if (e.ultimo_jogador == 0) { if (!combinacao_valida (e.highlight) ) { return 0; } else { if (e.actual_jogador != 0) { return 0; } else { if ((da_valor (e.highlight) != -1) ) { return 1; } else return 0; } } } else { if (!combinacao_valida (e.highlight)) { return 0; } else { if (e.actual_jogador != 0) { return 0; } else { if (!compara_tamanho (e.ultima_jogada, e.highlight)) { return 0; } else { if (!combinacao_maior (e.ultima_jogada, e.highlight)) { return 0; } } } } return 1; } }
void separa_nap (MAO mao, int y[4]){ int i,n,v; for(i=0;i<52;i++){ n = i/13; v = i%13; if(carta_existe(mao,n,v)){ y[n]++; } } }
void atualizastraight(int v[13], MAO mao, int y[2]) { int ind = 0, i; if (v[11] != 0 && v[12] != 0){ /*temos um ás e é o primeiro da sequência, pq existe um 2 */ y[0] = 3; /*5 de alguma coisa é obrigatoriamente a carta mais alta*/ for(i = 0; i < 4; i++) if(carta_existe(mao, i, 2)){ y[1] = i; break; } } else { for(i = 0; i < 4; i++) if(carta_existe(mao,i, 12)) mao = rem_carta(mao, i, 12); /*remove os 2's*/ ind = maior_carta_mao(mao); y[0] = (ind % 13) + 1; y[1] = ind / 13; } }
void separa_val (MAO mao, int y[13]){ int i,n,v; for(i=0;i<52;i++){ n = i/13; v = i%13; if(carta_existe(mao,n,v)){ y[v]++; } } }
/** A função jogar vai ser invocada pela função parse, e vai retirar as cartas da mão do jogador caso esta exista no highlight, colocando-a na posição do tabuleiro correspondete a jogada do utilizador, ou seja, vai ser a função executada quando carregamos no botao jogar para um dado highlight. Esta função também convoca as funções dos bots que executam as suas jogadas enquanto não for a vez do utilizador jogar. @param e O estado actual. @returns O novo estado. */ ESTADO jogar (ESTADO e) { int n, v, x, y; x = 551; y = 450; e.play = 0; if(e.layout == 1){ for (v = 0; v < 13; v++) { for (n = 0; n < 4; n++) { if (carta_existe((e.highlight), n, v)) { e.mao[0] = rem_carta(e.mao[0], n, v); x += 20; imprime_carta(BARALHO, x, y, e, 4, n , v); } } } } else{ for (n = 0; n < 4; n++) { for (v = 0; v < 13; v++) { if (carta_existe((e.highlight), n, v)) { e.mao[0] = rem_carta(e.mao[0], n, v); x += 20; imprime_carta(BARALHO, x, y, e, 4, n , v); } } } } e = bots2(e); while(e.actual_jogador != 0 && e.cartas[0] != 0 && e.cartas[1] != 0 && e.cartas[2] != 0 && e.cartas[3] != 0){ e = bots2(e); } e.actual_jogador = 0; e.highlight = 0; return e; }
void checkFirst(MCtree tree, DATABASE * data){ int counter_tree, nc; for(nc = 0; nc < 4; nc+= 1){ for(counter_tree = 0; (tree->nextN[nc][counter_tree] != NULL) && (counter_tree < 40); counter_tree++) if((tree->nextN[nc][counter_tree]->estado == 0) || (carta_existe(tree->nextN[nc][counter_tree]->estado,0,0) == 0)){ tree->nextN[nc][counter_tree]->t = 0; tree->nextN[nc][counter_tree]->r = 0; } } data->firstplay = 2; }
/** Conta o número de cartas que se encontra numa mao numa dada altura. @param m A mão de um jogador. @returns O número de cartas. */ int numero_de_cartas(MAO m) { int n, v, contaCartas=0; for (n = 0; n < 4; n++) { for (v = 0; v < 13; v++) if (carta_existe(m, n, v)) contaCartas++; } return contaCartas; }
int da_maior_naipe (MAO m){ int n, v, maior=0; for (n = 0; n < 4; n++) { for (v = 0; v < 13; v++) if (carta_existe(m, n, v)) { if (n > maior) maior = n;} } return maior; }
/** Nas cartas selecionadas pelo utilizador (neste caso um flush), determina o valor da maior carta desse, para mais tarde comparar, se necessário, com as ultimas jogadas, de forma a avaliar a jogada. @param m A mão de um jogador. @returns O valor da maior carta do flush. */ int maior_carta_flush (MAO m) { int i, n, v; i = 0; for (v = 0; v < 13; v++) { for (n = 0; n < 4; n++) { if (carta_existe(m,n,v)) i = v; } } return i; }
/** Depois de ser validada um flush na mão de um dos bots, esta função determina o valor da maior carta nesse flush, para se for necessário comparar com valores iguais. A função retorna o valor da maior carta do flush. @param m A mão de um jogador. @param n1 Naipe correspondente ao flush. @returns O valor da maior carta do flush. */ int maior_carta_flush_bots (MAO m, int n1) { int i,v,flag; i = 0; flag = 0; for (v = 12; (v >= 0) && (flag != 1); --v) { if (carta_existe(m,n1,v)) { flag = 1; i = v; } } return i; }
/** Nas cartas selecionadas pelo utilizador (neste caso um straight), determina o valor da maior carta desse, para mais tarde comparar, se necessário, com as ultimas jogadas, de forma a avaliar a jogada. @param m A mão de um jogador. @returns O valor da maior carta de um straight. */ int maior_carta_straight (MAO m) { int v,i,n,j; int contaValores[14]; for (i = 0; i < 14; i++) { contaValores[i] = 0; } i = 2; for (v = 0; v < 13; v++) { for(n = 0; n < 4; n++) { switch (v) { case 11: if (carta_existe(m,n,v)) { contaValores[0]++; contaValores[13]++; } break; case 12: if (carta_existe(m,n,v)) { contaValores[1]++; } break; default: if (carta_existe(m,n,v)) { contaValores[i]++; } break; } } i++; } if ((contaValores[1] != 0)) { for (j = 12; j >= 0; j--) { if (contaValores[j] != 0) { return (contaValores[j]); } } } else { for (j = 13; j > 0; j--) { if (contaValores[j] != 0) { return contaValores[j]; } } } return 0; /* TER CUIDADO COM ISTO, FOI ADICIONADO PARA RESOLVER PROBLEMAS DE COMPILAÇÃO */ }
/** O estado clear permite-nos após termos diferentes cartas no highlight, removê-las do mesmo, e colocando-as de novo na nossa mão, melhorando assim a jogabilidade. @param e O estado actual. @returns O novo estado. */ ESTADO clear(ESTADO e){ int n,v; n=0; v=0; for (n = 0; n <= 3; n++) for (v = 0; v <= 12; v++) { if(carta_existe(e.highlight,n,v)){ e.highlight = rem_carta(e.highlight,n,v); } } return e; }
void simula_maos(DATABASE * data){ int ind, jog; int i,n,v; int num[4] = {13,13,13,13}; int flag = 0; MAO atribuir=0x000fffffffffffff; for(jog = 1; jog<4; jog++) data->mao[jog] = 0; for(ind = 0;ind < 52; ind ++){ n = ind / 13; v = ind % 13; for(i = 0; i < 3; i++){ if(carta_existe(data->usadas[i+1],n,v)){ atribuir = rem_carta(atribuir, n, v); num[i]--; } else if(carta_existe(data->mao[0],n,v) ||carta_existe(data->usadas[0],n,v) ) atribuir = rem_carta(atribuir, n, v); } } for (ind = 0; ind < 52 ; ind ++){ n = ind / 13; v = ind % 13; if(carta_existe(atribuir,n,v)){ do{ flag = 0; jog = rand()%3; if(num[jog] > 0){ data->mao[jog+1] = add_carta(data->mao[jog+1],n,v); num[jog]--; flag = 1; } }while(flag == 0); } } }
int maior_carta_mao(MAO mao){ int ind; int max=-1; int n,v; for(ind=0;ind<52;ind++){ n=ind/13; v=ind%13; if(carta_existe(mao,n,v)){ if((v>max%13||(v==max%13&&n>max/13)) || max == -1) max = ind; } } return max; }
int jogadas1(DATABASE * simulacao, int jog, MAO jogadas[40]){ int count = 0, n = 0, v,max; max = maior_carta_mao(simulacao->jogada); if(max == -1) v = 0; else{ v = max % 13; n = max / 13; } for(; n<4; n++) if(carta_existe(simulacao->mao[jog],n,v)){ jogadas[count] = add_carta(0,n,v); count++; } v++; for(; v < 13; v++) for(n= 0; n < 4; n++) if(carta_existe(simulacao->mao[jog],n,v)){ jogadas[count] = add_carta(0,n,v); count++; } count++; return count; }
/** Ao receber o highlight do utilizador (neste caso um flush), confirma se este é válido para ser efetuada uma jogada. Nesta função, é retornado 0,1,2 ou 3 conforme o naipe do flush. Exemplo: 0 -> Ouros; 1 -> Copas; etc... Com isto, conseguimos mais tarde avaliar dois flushes. @param m A mão de um jogador. @returns Um inteiro (0,1,2,3), que corresponde a diferentes naipes. */ int valida_flush (MAO m) { int v, n, i; int contaNaipes[4]; for (i = 0; i < 4; i++) { contaNaipes[i] = 0; } for (v = 0; v < 13; v++) for(n = 0; n < 4; n++) { switch(n) { case 0: if (carta_existe(m,n,v)) { contaNaipes[0]++; } break; case 1: if (carta_existe(m,n,v)) { contaNaipes[1]++; } break; case 2: if (carta_existe(m,n,v)) { contaNaipes[2]++; } break; case 3: if (carta_existe(m,n,v)) { contaNaipes[3]++; } break; } } if (contaNaipes[0] >= 5) return 0; else { if (contaNaipes[1] >= 5) return 1; else { if (contaNaipes[2] >= 5) return 2; else { if (contaNaipes[3] >= 5) return 3; else return -1; } } } }