Advertisement
Guest User

Untitled

a guest
May 3rd, 2016
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.73 KB | None | 0 0
  1. /* Projeto Intermédio de Programação: JOGO DE BLACKJACK
  2. * Autor: Rúben Dos Santos Gomes
  3. * Nº de aluno: 84180 / ist425480
  4. * Data de realização: 18 de Março de 2016
  5. * Descrição do jogo: 4 jogadores que jogam contra a casa, que vão ganhando ou perdendo dinheiro consoante as jogadas que efetuarem
  6. */
  7.  
  8. #include <SDL2/SDL.h>
  9. #include <SDL2/SDL_ttf.h>
  10. #include <SDL2/SDL_image.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <time.h>
  14. #include <stdbool.h>
  15.  
  16. #define STRING_SIZE 100 // max size for some strings
  17. #define WIDTH_WINDOW 900 // window width
  18. #define HEIGHT_WINDOW 525 // window height
  19. #define MAX_DECK_SIZE 52 // number of max cards in the deck
  20. #define MAX_CARD_HAND 11 // 11 cards max. that each player can hold
  21. #define CARD_WIDTH 67 // card width
  22. #define CARD_HEIGHT 97 // card height
  23. #define WINDOW_POSX 500 // initial position of the window: x
  24. #define WINDOW_POSY 250 // initial position of the window: y
  25. #define EXTRASPACE 150
  26. #define MARGIN 5
  27. #define MAX_PLAYERS 4 // number of maximum players
  28. #define MAX_POINTS 21 // máximo de pontos que um jogador pode ter, para ganhar
  29. #define MIN_HOUSE_POINTS 17 // mínimo de pontos que a casa deve ter
  30.  
  31. // declaration of the functions related to graphical issues
  32. void InitEverything(int , int , TTF_Font **, SDL_Surface **, SDL_Window ** , SDL_Renderer ** );
  33. void InitSDL();
  34. void InitFont();
  35. SDL_Window* CreateWindow(int , int );
  36. SDL_Renderer* CreateRenderer(int , int , SDL_Window *);
  37. int RenderText(int , int , const char* , TTF_Font *, SDL_Color *, SDL_Renderer * );
  38. int RenderLogo(int , int , SDL_Surface *, SDL_Renderer * );
  39. void RenderTable(int newgame, int pontoscasa, int [], int pontos [], int player, TTF_Font *, SDL_Surface **, SDL_Renderer * );
  40. void RenderCard(int , int , int , SDL_Surface **, SDL_Renderer * );
  41. void RenderHouseCards(int [], int , SDL_Surface **, SDL_Renderer * );
  42. void RenderPlayerCards(int [][MAX_CARD_HAND], int [], SDL_Surface **, SDL_Renderer * );
  43. void LoadCards(SDL_Surface **);
  44. void UnLoadCards(SDL_Surface **);
  45.  
  46. // definition of some strings: they cannot be changed when the program is executed !
  47. const char myName[] = "Ruben Gomes";
  48. const char myNumber[] = "IST425480";
  49. const char * playerNames[] = {"Player 1", "Player 2", "Player 3", "Player 4"};
  50.  
  51. //PROTÓTIPO DAS FUNÇÕES CRIADAS POR MIM
  52. void LerParametrosJogo ( int *num_baralhos, int *valor_inicial, int *dinheiro_apostado );
  53. void InicializarBaralho (int num_baralhos, int VetorCartas []);
  54. void BaralharCartas(int vetorcartas[], int num_baralhos);
  55. int CalcPontos (int playercards[][MAX_CARD_HAND], int player, int posicao_player_hand []);
  56. int CalcPontosCasa (int pos_house_hand, int house_cards[]);
  57. void NewGame(int money [], int i, int vetorcartas[], int pos_player_hand[], int *pos_house_hand, int player_cards[][MAX_CARD_HAND], int house_cards [], int valorinicial, int valoraposta);
  58. void VerificarPontos (int pontos [], int money [], int valoraposta, int pontoscasa, int pos_player_hand [], int pos_house_hand);
  59. void CalculaGanhosEmpatesPerdidos(int pos_house_hand, int money [], int valoraposta, int pontoscasa, int pontos [], int ganhos [], int perdidos [], int empates [], int pos_player_hand []);
  60. void RetirarDinheiroAposta(int money [], int valoraposta);
  61. int CalcSaldoCasa (int valorinicial, int money []);
  62.  
  63. /**
  64. * main function: entry point of the program
  65. * only to invoke other functions !
  66. */
  67. int main( int argc, char* args[] )
  68. {
  69. SDL_Window *window = NULL;
  70. SDL_Renderer *renderer = NULL;
  71. TTF_Font *serif = NULL;
  72. SDL_Surface *cards[MAX_DECK_SIZE+1], *imgs[2];
  73. SDL_Event event;
  74. int delay = 300;
  75. int quit = 0;
  76. int money[MAX_PLAYERS] = {110, 110, 110, 110};
  77. int player_cards[MAX_PLAYERS][MAX_CARD_HAND] = {{0}};
  78. int house_cards[MAX_CARD_HAND] = {0};
  79. int pos_house_hand = 0;
  80. int pos_player_hand[MAX_PLAYERS] = {0};
  81.  
  82. //VARIÁVEIS CRIADAS POR MIM RELATIVAS AO FUNCIONAMENTO DO JOGO
  83. int VetorCartas[6*MAX_DECK_SIZE]; //O máximo de baralhos de cada jogo é 6, logo o VetorCartas que representa o conjunto de baralhos tem dimensão 6 * (número de cartas em cada baralho)
  84. int num_baralhos = 0, valorinicial = 0, valoraposta = 0; //Pârametros do jogo
  85. int i = 0, h= 0; //Variáveis usadas em ciclo
  86. int pos = 0, player = 0; //Variáveis usadas como índice do array player_cards[player][pos]: player representa o jogador, e pos a posição da carta.
  87. int pontos [MAX_PLAYERS + 1] = {0}, pontoscasa = 0; //pontos [] é um vetor de 5 posições, em que cada posição é referente aos pontos de cada jogador. pontoscasa representa os pontos da casa
  88. int newgame = 1; //newgame está 1 enquanto a jogada decorre, usada para impossibilitar fazer um novo jogo no decorrer de uma jogada.
  89. int ganhos [MAX_PLAYERS] = {0}, empates [MAX_PLAYERS] = {0}, perdidos [MAX_PLAYERS] = {0}; //Armazenam o número de jogos ganhos, empatados e perdidos de cada jogador ao longo do jogo.
  90. int attmoney = 0;//Enquanto attmoney = 0 não atualiza o dinheiro
  91. int saldo_casa = 0;//No final de cada jogada esta vaŕiável é atualizada, e representa o dinheiro que a casa perdeu ou ganhou
  92. int count_ases = 0;//É usado para o caso específico de ocorrer soft hand (count_ases == 1 e pontos_casa == 17)
  93. int softhand_ciclo = 0;//variável usada em ciclo para percorrer todas as cartas da casa e averiguar o numero de ases
  94. int jogada = 1;//Variável que não interfere com o funcionamento do jogo, apenas server para imprimir no terminal em que jogada estamos
  95. FILE *filestats;//ponteiro usado para a escrita de ficheiros
  96.  
  97. //LÊ OS PARÂMETROS DO JOGO (Nº DE BARALHOS, DINHEIRO INICIAL, VALOR FIXO DE CADA APOSTA)
  98. LerParametrosJogo (&num_baralhos,&valorinicial,&valoraposta);
  99.  
  100. //ATUALIZA O DINHEIRO DE CADA JOGADOR NA INTERFACE GRÁFICA CONSOANTE O VALOR INICIAL E O VALOR DA APOSTA
  101. //É logo retirado ao jogador o valor da aposta para a 1º jogada
  102. for (player = 0; player < MAX_PLAYERS; player++)
  103. {
  104. money[player] = valorinicial - valoraposta;
  105. }
  106.  
  107. //INICIALIZA O VETOR DAS CARTAS
  108. //Preenche as posições do vetor não utilizados com o valor -1 para detetar se restam muitas cartas no baralho
  109. //Se o valor -1 estiver próximo inicializa-se o vetor e baralha-se como no início
  110. InicializarBaralho(num_baralhos, VetorCartas);
  111.  
  112. //BARALHA O VETOR DAS CARTAS
  113. BaralharCartas (VetorCartas, num_baralhos);
  114.  
  115. // initialize graphics
  116. InitEverything(WIDTH_WINDOW, HEIGHT_WINDOW, &serif, imgs, &window, &renderer);
  117. // loads the cards images
  118. LoadCards(cards);
  119.  
  120. // put down some cards just for testing purposes: for you to remove !
  121.  
  122. // DISTRIBUIÇÃO DA 1ª MÃO
  123. i = 0, h = 0;
  124. for(pos = 0; pos <= 1; pos++)
  125. {
  126. for(player = 0; player < MAX_PLAYERS; player++)
  127. {
  128. player_cards [player][pos] = VetorCartas [i];
  129. i++;
  130. }
  131. house_cards[h] = VetorCartas [i];
  132. if (h == 0) //Após ser distribuida a 1ª carta à casa incrementa-se a posição o VetorCartas para que seja a próxima carta do Baralho a ser distribuida ao jogador.
  133. i++; //No entanto, após ser distribuida a 2ª carta à casa não incrementamos a posição porque no "case SDLk_h:" (hit) uma das primeiras instruções é i++, ou seja incrementar a posição do vetor das cartas.
  134. h++;
  135. }
  136. pos_player_hand[0] = 2; //Cada jogador começa com 2 cartas.
  137. pos_player_hand[1] = 2;
  138. pos_player_hand[2] = 2;
  139. pos_player_hand[3] = 2;
  140. pos_house_hand = 1; //A casa começa com uma carta virada para cima e outra para baixo.
  141.  
  142.  
  143. //CÁLCULA OS PONTOS QUE CADA JOGADOR TEM APÓS A DISTRIBUIÇÃO DAS CARTAS
  144. pontos[0] = CalcPontos(player_cards,0,pos_player_hand);
  145. pontos[1] = CalcPontos(player_cards,1,pos_player_hand);
  146. pontos[2] = CalcPontos(player_cards,2,pos_player_hand);
  147. pontos[3] = CalcPontos(player_cards,3,pos_player_hand);
  148.  
  149. pos = 1;
  150. player = 0; //PASSA A DECISÃO AO PRIMEIRO JOGADOR
  151.  
  152. while( quit == 0 )
  153. {
  154. //Enquanto o jogador não tiver cartas por ter perdido o jogo, incrementa-se o jogador.
  155. while ((money [player] < valoraposta) && (pos_player_hand [player] == 0) && (player < 4))
  156. {
  157. player++;
  158. }
  159.  
  160. //Se o Baralho estiver quase a chegar ao fim inicializa-se o vetor e baralha-se e informa-se o utilizador.
  161. //É utilizado o número 9, porque o maior número de cartas a ser distribuido consecutivamente sem passar por esta condição é 8, quando é distribuida a 1ª mão
  162. if (VetorCartas [i + 9] == -1)
  163. {
  164. InicializarBaralho(num_baralhos, VetorCartas);
  165. BaralharCartas(VetorCartas, num_baralhos);
  166. i=0;
  167. printf("\nDevido à possibilidade das cartas se esgotarem durante a jogada foram adicionadas cartas baralhadas!!!\n");
  168. }
  169.  
  170. //No entanto, como forma de previnir, caso o baralho esgote, o jogo fecha e informa-se o utilizador da causa.
  171. else if (VetorCartas [i] == -1)
  172. {
  173. printf("\nEsgotaram-se as cartas! Por favor, inicie um novo jogo...\n");
  174. exit(EXIT_FAILURE);
  175. }
  176. // while there's events to handle
  177. while( SDL_PollEvent( &event ) )
  178. {
  179. //Caso o jogador saia do jogo, clicando no X, a janela fecha e é guardado um ficheiro com as estatísticas desse jogo.
  180. if( event.type == SDL_QUIT )
  181. {
  182. quit = 1;
  183. filestats = fopen("Estatísticas.txt","wt");
  184. fprintf(filestats,"Jogador\t\tGanhos \t\tEmpates \t\tPerdidos\t\t Dinheiro final\n");
  185. fprintf(filestats,"Player1\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[0], empates[0], perdidos[0],money[0]);
  186. fprintf(filestats,"Player2\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[1], empates[1], perdidos[1],money[1]);
  187. fprintf(filestats,"Player3\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[2], empates[2], perdidos[2],money[2]);
  188. fprintf(filestats,"Player4\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[3], empates[3], perdidos[3],money[3]);
  189. fprintf(filestats,"Variação do saldo da casa = %d", saldo_casa);
  190. fclose(filestats);
  191. }
  192. else if ( event.type == SDL_KEYDOWN )
  193. {
  194. switch ( event.key.keysym.sym )
  195. {
  196. //Caso o jogador prima a tecla q, a janela fecha, e é guardado um ficheiro com as estatísticas do jogo.
  197. case SDLK_q:
  198. quit = 1;
  199. filestats = fopen("Estatísticas.txt","wt");
  200. fprintf(filestats,"Jogador\t\tGanhos \t\tEmpates \t\tPerdidos\t\t Dinheiro final\n");
  201. fprintf(filestats,"Player1\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[0], empates[0], perdidos[0],money[0]);
  202. fprintf(filestats,"Player2\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[1], empates[1], perdidos[1],money[1]);
  203. fprintf(filestats,"Player3\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[2], empates[2], perdidos[2],money[2]);
  204. fprintf(filestats,"Player4\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\t\t\t\t\t%d\n", ganhos[3], empates[3], perdidos[3],money[3]);
  205. fprintf(filestats,"Variação do saldo da casa = %d", saldo_casa);
  206. fclose(filestats);
  207.  
  208. break;
  209.  
  210. //Se o jogador fizer stand (tecla s)
  211. case SDLK_s:
  212.  
  213. pontos [player] = CalcPontos(player_cards, player, pos_player_hand);
  214. pos = 1;
  215. player++;
  216.  
  217. break;
  218.  
  219. //Se o jogador fizer hit (tecla h)
  220. case SDLK_h:
  221.  
  222. pos_player_hand [player] ++;
  223. pos++;
  224. i++;
  225.  
  226. //É distribuída a próxima carta do baralho
  227. player_cards [player][pos] = VetorCartas [i];
  228.  
  229. //Calcula os pontos do jogador que fez hit
  230. pontos [player] = CalcPontos(player_cards, player, pos_player_hand);
  231.  
  232. //Se o jogador tiver mais do que 21 pontos
  233. if (pontos [player] > MAX_POINTS)
  234. {
  235. //O controlo passa para o próximo jogador.
  236. player++;
  237.  
  238. //Se o jogador seguinte ainda estiver a jogar fica com 2 cartas, e a posição da carta é 1
  239. if (money [player] >= valoraposta)
  240. {
  241. pos = 1;
  242. pos_player_hand [player] = 2;
  243. }
  244. }
  245. break;
  246.  
  247. //Se o jogador fizer "New Game" (tecla n)
  248. case SDLK_n:
  249. if (newgame == 0)
  250. {
  251. //attmoney = 0 permite a atualização do dinheiro na janela
  252. attmoney = 0;
  253.  
  254. //Com newgame a 1, se carregarem na tecla n não acontece nada
  255. newgame = 1;
  256.  
  257. i++;
  258. NewGame(money, i,VetorCartas,pos_player_hand,&pos_house_hand,player_cards,house_cards,valorinicial,valoraposta); // São distribuidas as cartas aos jogadores
  259.  
  260. //É retirado a cada jogador o valor da aposta.
  261. RetirarDinheiroAposta(money, valoraposta);
  262.  
  263. //Avança no baralho, visto que a função NewGame não altera o valor de i (visto ser usada passagem por valor)
  264. i = i + 9;
  265.  
  266. //Quando inicia um novo jogo, o controlo passa para o primeiro jogador e visto que tem duas cartas, a posição da carta (pos) = 1
  267. pos = 1;
  268. player = 0;
  269. jogada++;
  270. }
  271. default:
  272. break;
  273. }
  274.  
  275. //(Quando)/(Se) os pontos da casa forem maiores ou iguais a 17, são calculados os pontos de cada jogador e armazenados, para depois serem comparados com os pontos da casa.
  276. if (pontoscasa >= MIN_HOUSE_POINTS)
  277. {
  278. pontos[0] = CalcPontos(player_cards,0,pos_player_hand);
  279. pontos[1] = CalcPontos(player_cards,1,pos_player_hand);
  280. pontos[2] = CalcPontos(player_cards,2,pos_player_hand);
  281. pontos[3] = CalcPontos(player_cards,3,pos_player_hand);
  282. }
  283. }
  284.  
  285. //Quando acabar a jogada (newgame == 0) e puder-se atualizar o dinheiro (attmoney == 0)
  286. if (newgame == 0 && attmoney == 0)
  287. {
  288. VerificarPontos(pontos, money, valoraposta, pontoscasa, pos_player_hand, pos_house_hand);//É devolvido o dinheiro a quem tenha ganho
  289. CalculaGanhosEmpatesPerdidos(pos_house_hand, money, valoraposta, pontoscasa, pontos, ganhos, perdidos, empates, pos_player_hand);//Verifica-se e armazena-se quem ganhou perdeu e empatou
  290. attmoney = 1;
  291. }
  292.  
  293. //Se fôr a vez da casa e o jogo ainda nao tiver terminado:_
  294. if (player == 4 && newgame == 1)
  295. {
  296.  
  297. //newgame = 0 (pode-se fazer newgame)
  298. newgame = 0;
  299.  
  300. //Mostra-se a 2ª carta da casa
  301. pos_house_hand = 2;
  302. h = 1;
  303.  
  304. //Calcula-se os pontos das duas cartas da casa para averiguar se é > 17
  305. pontoscasa = CalcPontosCasa(pos_house_hand, house_cards);
  306.  
  307. //Enquanto os pontos da casa forem menor que 17, a casa retira uma carta do baralho e vai calculando os pontos
  308. while (pontoscasa < MIN_HOUSE_POINTS)
  309. {
  310. i++;
  311. pos_house_hand++;
  312. h++;
  313. house_cards[h] = VetorCartas [i];
  314. pontoscasa = CalcPontosCasa(pos_house_hand, house_cards);
  315. }
  316.  
  317. //Este "for" percorre as cartas da casa e por cada Às encontrado incrementa o count_ases, que nos dá o número de Ases que a casa tem
  318. for (softhand_ciclo = 0; softhand_ciclo <= h - 1; softhand_ciclo++)
  319. {
  320. switch (house_cards [softhand_ciclo])
  321. {
  322. case 12: case 25: case 38: case 52: count_ases++;
  323. }
  324. }
  325.  
  326. //[SOFTHAND] Se a casa tiver apenas um às e tiver 17 pontos, pede mais uma carta
  327. if ((count_ases == 1) && (pontoscasa == MIN_HOUSE_POINTS))
  328. {
  329. i++;
  330. pos_house_hand++;
  331. h++;
  332. house_cards[h] = VetorCartas [i];
  333. pontoscasa = CalcPontosCasa(pos_house_hand, house_cards);
  334. }
  335.  
  336. //Quando os pontos da casa forem maiores ou iguais a 17 imprime no terminal os pontos de cada jogador e da casa.
  337. if (pontoscasa >= MIN_HOUSE_POINTS)
  338. {
  339. printf("\n ---------- Final da jogada %d ----------\n", jogada);
  340.  
  341. pontos[0] = CalcPontos(player_cards,0,pos_player_hand);
  342. printf("\nO jogador 1 têm %d pontos \n\n", pontos[0]);
  343. pontos[1] = CalcPontos(player_cards,1,pos_player_hand);
  344. printf("O jogador 2 têm %d pontos \n\n", pontos[1]);
  345. pontos[2] = CalcPontos(player_cards,2,pos_player_hand);
  346. printf("O jogador 3 têm %d pontos \n\n", pontos[2]);
  347. pontos[3] = CalcPontos(player_cards,3,pos_player_hand);
  348. printf("O jogador 4 têm %d pontos \n\n", pontos[3]);
  349. printf("A casa tem %d pontos\n\n", pontoscasa);
  350.  
  351. }
  352.  
  353.  
  354. }
  355.  
  356. //Função que calcula quanto dinheiro é que a casa ganhou ou perdeu até ao momento
  357. saldo_casa = CalcSaldoCasa(valorinicial, money);
  358.  
  359. }
  360.  
  361.  
  362.  
  363.  
  364. // render game table
  365. RenderTable(newgame, pontoscasa, money, pontos, player, serif, imgs, renderer);
  366. // render house cards
  367. RenderHouseCards(house_cards, pos_house_hand, cards, renderer);
  368. // render player cards
  369. RenderPlayerCards(player_cards, pos_player_hand, cards, renderer);
  370. // render in the screen all changes above
  371. SDL_RenderPresent(renderer);
  372. // add a delay
  373. SDL_Delay( delay );
  374. }
  375.  
  376. // free memory allocated for images and textures and close everything including fonts
  377. UnLoadCards(cards);
  378. TTF_CloseFont(serif);
  379. SDL_FreeSurface(imgs[0]);
  380. SDL_FreeSurface(imgs[1]);
  381. SDL_DestroyRenderer(renderer);
  382. SDL_DestroyWindow(window);
  383. SDL_Quit();
  384. return EXIT_SUCCESS;
  385. }
  386.  
  387. //FUNÇÕES CRIADAS POR MIM QUE FORAM UTILIZADAS AO LONGO DO MAIN
  388.  
  389. //Obtém e armazena em variáveis o número de baralhos, o dinheiro inicial, e o valor fixo de cada aposta
  390. void LerParametrosJogo ( int *num_baralhos, int *valor_inicial, int *dinheiro_apostado )
  391. {
  392. printf("\t\t****************************************\n");
  393. printf("\t\t* BEM VINDOS AO BLACKJACK! *\n");
  394. printf("\t\t****************************************\n");
  395. puts("\n");
  396.  
  397. printf("Digite o número de baralhos com que pretende jogar: ");
  398. scanf("%d", num_baralhos);
  399.  
  400. //O nº de baralhos tem que estar contido entre 1 e 6. Caso contrário informa o utilizador
  401. if(*num_baralhos < 1 || *num_baralhos > 6)
  402. {
  403. printf("\nO número de baralhos tem de estar entre 1 e 6!\n");
  404. exit(EXIT_FAILURE);
  405. }
  406.  
  407. printf("\nDigite o dinheiro inicial de cada jogador: ");
  408. scanf("%d", valor_inicial);
  409.  
  410. // O dinheiro inicial tem de ser superior a 10 euros. Caso contrário informa o utilizador e termina o processo
  411. if(*valor_inicial < 10)
  412. {
  413. printf("\nO dinheiro inicial tem de ser superior a 10 euros!\n");
  414. exit(EXIT_FAILURE);
  415. }
  416.  
  417. printf("\nDigite o valor fixo de cada aposta: ");
  418. scanf("%d",dinheiro_apostado);
  419.  
  420. /* O valor da aposta tem de ser, no mínimo, 5 vezes menor do que o dinheiro inicial
  421. Caso contrário informa o utilizador e termina o processo*/
  422. if(*dinheiro_apostado > (*valor_inicial/5))
  423. {
  424. printf("\nO dinheiro inicial tem de ser 5 vezes maior que o valor de cada aposta!\n");
  425. exit(EXIT_FAILURE);
  426. }
  427.  
  428. /* O valor da aposta tem de ser igual ou superior a 1 euro
  429. Caso contrário informa o utilizador e termina o processo */
  430. if(*dinheiro_apostado < 1)
  431. {
  432. printf("\nO valor de cada aposta tem de ser no mínimo 1 euro!\n");
  433. exit(EXIT_FAILURE);
  434. }
  435. }
  436.  
  437. /* Função utilizada para inicializar o vetor baralho
  438. Dependendo do número de baralhos introduzido pelo utilizador, preenche certas posições do baralho, e as não utilizadas preenche com o valor -1 */
  439. void InicializarBaralho(int num_baralhos, int VetorCartas [])
  440. {
  441. int soma = 0, k = 0, i = 0, j = 0;
  442. do {
  443. for (i = 0 + soma, j = 0; j < 52; i++, j++)
  444. {
  445. VetorCartas [i] = j;
  446. }
  447. soma = soma + 52;
  448. k++;
  449. } while (k < num_baralhos);
  450.  
  451. for (i = soma; i < 311; i++)
  452. {
  453. VetorCartas [i] = -1;
  454. }
  455. }
  456.  
  457. // Baralha o vetor representante das cartas do jogo, no entanto, não mistura as posições que contêm cartas com as que não têm (-1)
  458. void BaralharCartas ( int vetorcartas [], int num_baralhos )
  459. {
  460. int j = 0, a = 0, i = 0, aux = 0;
  461. srand (time(NULL));
  462. a = MAX_DECK_SIZE * num_baralhos;
  463. for (i = a - 1; i > 0; i--) //Algoritmo de Fisher-Yales:
  464. { //Troca a última posição do vetor por uma posição aleatória
  465. j = (rand () % i); //Troca a penúltima posição do vetor por uma posição aleatória
  466. aux = vetorcartas[i]; //Troca a ante-penúltima posição do vetor por uma posição aleatória
  467. vetorcartas[i] = vetorcartas[j]; //E assim sucessivamente... Resultado: Vetor Baralhado
  468. vetorcartas[j] = aux;
  469. }
  470. }
  471.  
  472. //Calcula os pontos de todos os jogadores e armazena esses pontos num vetor cuja 1ª posição (posição 0) refere-se ao 1º jogador e assim sucessivamente
  473. int CalcPontos (int playercards[][MAX_CARD_HAND], int player, int posicao_player_hand [])
  474. {
  475. int cardpoints = 0, pos = 0, valortotal = 0, az=0;
  476.  
  477. for (pos = 0; pos <= posicao_player_hand[player]-1; pos++)
  478. {
  479. cardpoints = 0;
  480.  
  481. //A cada card ID, faz corresponder um número de pontos
  482. switch (playercards[player][pos])
  483. {
  484. case 0: case 13: case 26: case 39: cardpoints = 2; break;
  485. case 1: case 14: case 27: case 40: cardpoints = 3; break;
  486. case 2: case 15: case 28: case 41: cardpoints = 4; break;
  487. case 3: case 16: case 29: case 42: cardpoints = 5; break;
  488. case 4: case 17: case 30: case 43: cardpoints = 6; break;
  489. case 5: case 18: case 31: case 44: cardpoints = 7; break;
  490. case 6: case 19: case 32: case 45: cardpoints = 8; break;
  491. case 7: case 20: case 33: case 46: cardpoints = 9; break;
  492. case 8: case 21: case 34: case 47: cardpoints =10; break;
  493. case 9: case 22: case 35: case 48: cardpoints = 10; break;
  494. case 10: case 23: case 36: case 49: cardpoints = 10; break;
  495. case 11: case 24: case 37: case 50: cardpoints = 10; break;
  496. case 12: case 25: case 38: case 51: cardpoints = 11; break;
  497. }
  498. valortotal = valortotal + cardpoints;
  499.  
  500. //Se o jogador tiver um ÀS e exceder os 21 pontos, ÀS passa a valer 1 ponto
  501. if(cardpoints == 11)
  502. {
  503. az = 1;
  504. }
  505.  
  506. //Retira os 11 pontos que o ás representava e soma um. (-11 + 1 = -10)
  507. if((valortotal > 21) && az ==1)
  508. {
  509. az = 0;
  510. valortotal = valortotal - 10;
  511. }
  512. }
  513. return valortotal;
  514. }
  515.  
  516. /* Criação de uma nova função para calcular os PONTOS DA CASA tendo em conta que a outra função tem como parâmetro de entrada
  517. uma matriz (Array de 2 dimensões), enquanto a variável house_cards é um Vetor (1 dimensão), o que impossibilita o
  518. seu uso como parâmetro de entrada na função atrás criada, no entanto o processo é muito semelhante */
  519.  
  520. int CalcPontosCasa(int pos_house_hand, int house_cards[])
  521. {
  522. int pos = 0, valor = 0, cardpoints = 0, az = 0;
  523. for(pos = 0; pos <= pos_house_hand - 1; pos++)
  524. {
  525. //A cada card ID faz corresponder um número de pontos
  526. switch (house_cards[pos])
  527. {
  528. case 0: case 13: case 26: case 39: valor = 2; break;
  529. case 1: case 14: case 27: case 40: valor = 3; break;
  530. case 2: case 15: case 28: case 41: valor = 4; break;
  531. case 3: case 16: case 29: case 42: valor = 5; break;
  532. case 4: case 17: case 30: case 43: valor = 6; break;
  533. case 5: case 18: case 31: case 44: valor = 7; break;
  534. case 6: case 19: case 32: case 45: valor = 8; break;
  535. case 7: case 20: case 33: case 46: valor = 9; break;
  536. case 8: case 21: case 34: case 47: valor = 10; break;
  537. case 9: case 22: case 35: case 48: valor = 10; break;
  538. case 10: case 23: case 36: case 49: valor = 10; break;
  539. case 11: case 24: case 37: case 50: valor = 10; break;
  540. case 12: case 25: case 38: case 51: valor = 11; break;
  541. }
  542. cardpoints = cardpoints + valor;
  543.  
  544. //Se a casa tiver um ÀS e exceder os 21 pontos, ÀS passa a valer 1 ponto
  545. if(valor ==11)
  546. {
  547. az = 1;
  548. }
  549.  
  550. //Retira os 11 pontos que o ÀS representava e soma um. (-11 + 1 = -10)
  551. if((cardpoints > 21) && az ==1)
  552. {
  553. az = 0;
  554. cardpoints = cardpoints - 10;
  555. }
  556.  
  557. }
  558. return cardpoints;
  559. }
  560.  
  561. //Compara os pontos dos jogadores e da casa e devolve dinheiro aos jogadores que ganharam.
  562. void VerificarPontos (int pontos [], int money [], int valoraposta, int pontoscasa, int pos_player_hand [], int pos_house_hand)
  563. {
  564. int player = 0;
  565. for (player = 0; player < MAX_PLAYERS; player++)
  566. {
  567. //Se o jogador já não estiver a jogar
  568. if (money [player] < valoraposta && pos_player_hand [player] == 0)
  569. {
  570. // Não devolve nem retira dinheiro
  571. }
  572.  
  573. // Jogador faz BLACKJACK (2 cartas) e a casa não tem 21 pontos
  574. // É devolvido o dinheiro apostado mais 1.5 * dinheiro apostado
  575. else if (((pontos [player] == MAX_POINTS) && (pos_player_hand[player] == 2)) && (pontoscasa != MAX_POINTS))
  576. {
  577. money [player] = money [player] + (2*valoraposta) + (valoraposta/2);
  578. }
  579.  
  580. // Jogador faz BLACKJACK (2 cartas) e a casa também faz BLACKJACK -> EMPATE
  581. // É devolvido o dinheiro apostado
  582. else if (((pontos [player] == MAX_POINTS) && (pos_player_hand[player] == 2)) && (pontoscasa == MAX_POINTS) && (pos_house_hand == 2))
  583. {
  584. money [player] = money [player] + valoraposta;
  585. }
  586.  
  587. // Jogador faz BLACKJACK (2 cartas) e a casa tem 21 pontos, sem BLACKJACK
  588. // É devolvido o dinheiro apostado mais 1.5 * (valor da aposta)
  589. else if (((pontos [player] == MAX_POINTS) && (pos_player_hand[player] == 2)) && (pontoscasa == MAX_POINTS) && (pos_house_hand != 2))
  590. {
  591. money [player] = money [player] + (1.5 *valoraposta);
  592. }
  593.  
  594. // JOGADOR PERDE: A casa, sem exceder os 21 pontos, tem mais pontos que o jogador
  595. // Não é devolvido dinheiro ao jogador
  596. else if ((pontoscasa > pontos[player]) && (pontoscasa <= MAX_POINTS))
  597. {
  598. money [player] = money [player]; //
  599. }
  600.  
  601. // JOGADOR GANHA: O jogador, sem exceder os 21 pontos, tem mais pontos que a casa
  602. // Devolve-se o dobro do dinheiro que o jogador apostou
  603. else if ((pontoscasa < pontos[player]) && (pontos [player] <= MAX_POINTS))
  604. {
  605. money [player] = money [player] + (2 * valoraposta);
  606. }
  607.  
  608. // JOGADOR GANHA: O jogador não excede os 21 pontos, mas a casa excede
  609. // Devolve-se o dobro do dinheiro que o jogador apostou
  610. else if ((pontos[player] <= MAX_POINTS) && (pontoscasa > MAX_POINTS))
  611. {
  612. money [player] = money [player] + (2 * valoraposta);
  613. }
  614.  
  615. // JOGADOR PERDE: Sempre que o jogador excede os 21 pontos
  616. // Não é devolvido o dinheiro da aposta ao jogador
  617. else if (((pontos [player]) > MAX_POINTS))
  618. {
  619. money [player] = money [player];
  620. }
  621.  
  622. // JOGADOR EMPATA: Os pontos do jogador são iguais aos pontos da casa
  623. // É devolvido o dinheiro da aposta ao jogador
  624. else if ((pontos [player] <= MAX_POINTS) && (pontos [player] == pontoscasa))
  625. {
  626. money [player] = money [player] + valoraposta;
  627. }
  628. }
  629. }
  630.  
  631. // Inicia uma nova jogada, redistribui a 1st hand
  632. void NewGame(int money [], int i, int vetorcartas[], int pos_player_hand[], int *pos_house_hand, int player_cards[][MAX_CARD_HAND], int house_cards [], int valorinicial, int valoraposta)
  633. {
  634. int h = 0, pos = 0, player = 0;
  635. for(pos=0; pos<=1; pos++)
  636. {
  637. for(player=0; player<MAX_PLAYERS; player++)
  638. {
  639. while (money [player] < valoraposta)
  640. {
  641. player++;
  642. }
  643. player_cards [player][pos] = vetorcartas [i];
  644. i++;
  645. }
  646. house_cards[h] = vetorcartas [i];
  647. if (h == 0)
  648. i++;
  649. h++;
  650. }
  651. pos_player_hand[0] = 2;
  652. pos_player_hand[1] = 2;
  653. pos_player_hand[2] = 2;
  654. pos_player_hand[3] = 2;
  655. *pos_house_hand = 1;
  656. for (player = 0; player < MAX_PLAYERS; player ++)
  657. {
  658. if (money [player] < valoraposta)
  659. {
  660. pos_player_hand [player] = 0;
  661. }
  662. }
  663. }
  664.  
  665. // Função responsável por calcular e armazenar o número de jogadas ganhas, perdidas, empatadas por cada jogador ao longo do jogo
  666. void CalculaGanhosEmpatesPerdidos(int pos_house_hand, int money [], int valoraposta, int pontoscasa, int pontos [], int ganhos [], int perdidos [], int empates [], int pos_player_hand [])
  667. {
  668. int i = 0;
  669. for(i=0; i < MAX_PLAYERS; i++)
  670. {
  671. // Se o jogador não estiver a jogar por ter perdido, não é alterado o número de jogos ganhos, perdidos e empatados por esse jogador
  672. if((money [i] < valoraposta) && (pos_player_hand [i] == 0))
  673. {
  674. ganhos [i] = ganhos [i];
  675. perdidos [i] = perdidos [i];
  676. empates [i] = empates [i];
  677. }
  678.  
  679. // Se o jogador tiver BLACKJACK e a casa tiver 21 pontos sem BLACKJACK incrementa o número de jogos ganhos
  680. else if ((pontos [i] == MAX_POINTS ) && (pos_player_hand [i] == 2) && (pontoscasa == MAX_POINTS) && (pos_house_hand != 2))
  681. {
  682. ganhos [i] ++;
  683. continue;
  684. }
  685.  
  686. // Se o jogador exceder os 21 pontos incrementa o número de jogos perdidos
  687. else if (pontos [i] > MAX_POINTS)
  688. {
  689. perdidos [i] ++;
  690. continue;
  691. }
  692.  
  693. // Se o jogador tiver menos pontos que a casa, sem que a casa exceda os 21 pontos, incrementa o número de jogos perdidos
  694. else if ((pontos [i] < pontoscasa) && (pontoscasa <= MAX_POINTS))
  695. {
  696. perdidos [i] ++;
  697. continue;
  698. }
  699.  
  700. // Se a casa tiver menos pontos que o jogador, sem que o jogador tenha excedido os 21 pontos, incrementa o número de jogos ganhos
  701. else if ((pontoscasa < pontos [i]) && (pontos [i] <= MAX_POINTS))
  702. {
  703. ganhos [i]++;
  704. continue;
  705. }
  706.  
  707. // Se o jogador não exceder 21 pontos e a casa exceder incrementa o número de jogos ganhos.
  708. else if ((pontos [i] <= MAX_POINTS) && (pontoscasa > MAX_POINTS))
  709. {
  710. ganhos [i]++;
  711. continue;
  712. }
  713.  
  714. // Se o jogador não exceder os 21 pontos e tiver os mesmos pontos do que a casa incrementa o número de empates
  715. else if ((pontos[i] <= MAX_POINTS && (pontos [i] == pontoscasa)))
  716. {
  717. empates [i]++;
  718. continue;
  719. }
  720. }
  721. }
  722.  
  723. /* Função que retira o dinheiro da aposta no início de cada jogada.
  724. Nota: -> A função VerificarPontos, atualiza o dinheiro dos jogadores no final de uma jogada consoante os jogadores tenham ganho ou perdido
  725. -> Na função não é logo retirado o valor da aposta, pois isto só acontece se o jogador carregar na tecla n, para jogar um novo jogo */
  726. void RetirarDinheiroAposta(int money [], int valoraposta)
  727. {
  728. int i=0;
  729. for (i=0; i < MAX_PLAYERS; i++)
  730. {
  731. if (money [i] >= valoraposta)
  732. {
  733. money [i] = money [i] - valoraposta;
  734. }
  735. else
  736. {
  737. money [i] = money [i];
  738. }
  739. }
  740. }
  741.  
  742. //Função que calcula a variação do saldo da casa
  743. int CalcSaldoCasa (int valorinicial, int money [])
  744. {
  745. int player = 0, dinheiro = 0, saldo = 0;
  746. for (player = 0; player < MAX_PLAYERS; player++)
  747. {
  748. dinheiro = valorinicial - money [player];
  749. saldo = saldo + dinheiro;
  750. }
  751. return saldo;
  752. }
  753. /**
  754. * RenderTable: Draws the table where the game will be played, namely:
  755. * - some texture for the background
  756. * - the right part with the IST logo and the student name and number
  757. * - squares to define the playing positions of each player
  758. * - names and the available money for each player
  759. * \param _money amount of money of each player
  760. * \param _img surfaces where the table background and IST logo were loaded
  761. * \param _renderer renderer to handle all rendering in a window
  762. */
  763. void RenderTable(int newgame, int pontoscasa, int _money[], int pontos [], int player, TTF_Font *_font, SDL_Surface *_img[], SDL_Renderer* _renderer)
  764. {
  765. SDL_Color black = { 0, 0, 0 }; // black
  766. SDL_Color white = { 255, 255, 255 }; // white
  767. char name_bust_str[STRING_SIZE];
  768. SDL_Texture *table_texture;
  769. SDL_Rect tableSrc, tableDest, playerRect;
  770. int separatorPos = (int)(0.95f*WIDTH_WINDOW); // seperates the left from the right part of the window
  771. int height;
  772.  
  773. char house_points_str[STRING_SIZE], points_money_str[STRING_SIZE];
  774. // set color of renderer to some color
  775. SDL_SetRenderDrawColor( _renderer, 255, 255, 255, 255 );
  776.  
  777. // clear the window
  778. SDL_RenderClear( _renderer );
  779.  
  780. tableDest.x = tableSrc.x = 0;
  781. tableDest.y = tableSrc.y = 0;
  782. tableSrc.w = _img[0]->w;
  783. tableSrc.h = _img[0]->h;
  784.  
  785. tableDest.w = separatorPos;
  786. tableDest.h = HEIGHT_WINDOW;
  787.  
  788. table_texture = SDL_CreateTextureFromSurface(_renderer, _img[0]);
  789. SDL_RenderCopy(_renderer, table_texture, &tableSrc, &tableDest);
  790.  
  791. // render the IST Logo
  792. height = RenderLogo(separatorPos, 0, _img[1], _renderer);
  793.  
  794. // render the student name
  795. height += RenderText(separatorPos+3*MARGIN, height, myName, _font, &black, _renderer);
  796.  
  797. // this renders the student number
  798. RenderText(separatorPos+3*MARGIN, height, myNumber, _font, &black, _renderer);
  799.  
  800. // renders the areas for each player: names and money too !
  801. for ( int i = 0; i < MAX_PLAYERS; i++)
  802. {
  803. // renders the squares + name for each player
  804. SDL_SetRenderDrawColor(_renderer, 255, 255, 255, 255 );
  805.  
  806. if (player == i)
  807. {
  808. SDL_SetRenderDrawColor(_renderer, 0, 0, 200, 0 );
  809. }
  810.  
  811. playerRect.x = i*(separatorPos/4-5)+10;
  812. playerRect.y = (int) (0.55f*HEIGHT_WINDOW);
  813. playerRect.w = separatorPos/4-5;
  814. playerRect.h = (int) (0.42f*HEIGHT_WINDOW);
  815.  
  816. // Enquanto os pontos do jogador forem menores do que 21, aparece o nome deles , quando fazem bust, aparece BUST à frente
  817. if (pontos [i] <= 21)
  818. {
  819. sprintf(name_bust_str,"%s", playerNames[i]);
  820. }
  821. else
  822. {
  823. sprintf(name_bust_str,"%s BUST!", playerNames[i]);
  824. }
  825.  
  826. RenderText(playerRect.x+10, playerRect.y-50, name_bust_str, _font, &white, _renderer);
  827. SDL_RenderDrawRect(_renderer, &playerRect);
  828.  
  829. sprintf(points_money_str, "%d pontos -- %d euros", pontos [i], _money [i]);
  830. RenderText(playerRect.x + 10, playerRect.y-30, points_money_str, _font, &white, _renderer);
  831.  
  832. // Quando a jogada acabar aparecem os pontos da casa
  833. if (newgame == 0)
  834. {
  835. sprintf(house_points_str, "Pontos da casa: %d", pontoscasa);
  836. RenderText(100, playerRect.y-150, house_points_str, _font, &white, _renderer);
  837. }
  838.  
  839. }
  840.  
  841. // destroy everything
  842. SDL_DestroyTexture(table_texture);
  843. }
  844.  
  845. /**
  846. * RenderHouseCards: Renders cards of the house
  847. * \param _house vector with the house cards
  848. * \param _pos_house_hand position of the vector _house with valid card IDs
  849. * \param _cards vector with all loaded card images
  850. * \param _renderer renderer to handle all rendering in a window
  851. */
  852. void RenderHouseCards(int _house[], int _pos_house_hand, SDL_Surface **_cards, SDL_Renderer* _renderer)
  853. {
  854. int card, x, y;
  855. int div = WIDTH_WINDOW/CARD_WIDTH;
  856.  
  857. // drawing all house cards
  858. for ( card = 0; card < _pos_house_hand; card++)
  859. {
  860. // calculate its position
  861. x = (div/2-_pos_house_hand/2+card)*CARD_WIDTH + 15;
  862. y = (int) (0.26f*HEIGHT_WINDOW);
  863. // render it !
  864. RenderCard(x, y, _house[card], _cards, _renderer);
  865. }
  866. // just one card ?: draw a card face down
  867. if (_pos_house_hand == 1)
  868. {
  869. x = (div/2-_pos_house_hand/2+1)*CARD_WIDTH + 15;
  870. y = (int) (0.26f*HEIGHT_WINDOW);
  871. RenderCard(x, y, MAX_DECK_SIZE, _cards, _renderer);
  872. }
  873. }
  874.  
  875. /**
  876. * RenderPlayerCards: Renders the hand, i.e. the cards, for each player
  877. * \param _player_cards 2D array with the player cards, 1st dimension is the player ID
  878. * \param _pos_player_hand array with the positions of the valid card IDs for each player
  879. * \param _cards vector with all loaded card images
  880. * \param _renderer renderer to handle all rendering in a window
  881. */
  882. void RenderPlayerCards(int _player_cards[][MAX_CARD_HAND], int _pos_player_hand[], SDL_Surface **_cards, SDL_Renderer* _renderer)
  883. {
  884. int pos, x, y, num_player, card;
  885.  
  886. // for every card of every player
  887. for ( num_player = 0; num_player < MAX_PLAYERS; num_player++)
  888. {
  889. for ( card = 0; card < _pos_player_hand[num_player]; card++)
  890. {
  891. // draw all cards of the player: calculate its position: only 4 positions are available !
  892. pos = card % 4;
  893. x = (int) num_player*((0.95f*WIDTH_WINDOW)/4-5)+(card/4)*12+15;
  894. y = (int) (0.55f*HEIGHT_WINDOW)+10;
  895. if ( pos == 1 || pos == 3) x += CARD_WIDTH + 30;
  896. if ( pos == 2 || pos == 3) y += CARD_HEIGHT+ 10;
  897. // render it !
  898. RenderCard(x, y, _player_cards[num_player][card], _cards, _renderer);
  899. }
  900. }
  901. }
  902.  
  903. /**
  904. * RenderCard: Draws one card at a certain position of the window, based on the card code
  905. * \param _x X coordinate of the card position in the window
  906. * \param _y Y coordinate of the card position in the window
  907. * \param _num_card card code that identifies each card
  908. * \param _cards vector with all loaded card images
  909. * \param _renderer renderer to handle all rendering in a window
  910. */
  911. void RenderCard(int _x, int _y, int _num_card, SDL_Surface **_cards, SDL_Renderer* _renderer)
  912. {
  913. SDL_Texture *card_text;
  914. SDL_Rect boardPos;
  915.  
  916. // area that will be occupied by each card
  917. boardPos.x = _x;
  918. boardPos.y = _y;
  919. boardPos.w = CARD_WIDTH;
  920. boardPos.h = CARD_HEIGHT;
  921.  
  922. // render it !
  923. card_text = SDL_CreateTextureFromSurface(_renderer, _cards[_num_card]);
  924. SDL_RenderCopy(_renderer, card_text, NULL, &boardPos);
  925.  
  926. // destroy everything
  927. SDL_DestroyTexture(card_text);
  928. }
  929.  
  930. /**
  931. * LoadCards: Loads all images of the cards
  932. * \param _cards vector with all loaded card images
  933. */
  934. void LoadCards(SDL_Surface **_cards)
  935. {
  936. int i;
  937. char filename[STRING_SIZE];
  938.  
  939. // loads all cards to an array
  940. for (i = 0 ; i < MAX_DECK_SIZE; i++ )
  941. {
  942. // create the filename !
  943. sprintf(filename, ".//cartas//carta_%02d.png", i+1);
  944. // loads the image !
  945. _cards[i] = IMG_Load(filename);
  946. // check for errors: deleted files ?
  947. if (_cards[i] == NULL)
  948. {
  949. printf("Unable to load image: %s\n", SDL_GetError());
  950. exit(EXIT_FAILURE);
  951. }
  952. }
  953. // loads the card back
  954. _cards[i] = IMG_Load(".//cartas//carta_back.jpg");
  955. if (_cards[i] == NULL)
  956. {
  957. printf("Unable to load image: %s\n", SDL_GetError());
  958. exit(EXIT_FAILURE);
  959. }
  960. }
  961.  
  962.  
  963. /**
  964. * UnLoadCards: unloads all card images of the memory
  965. * \param _cards vector with all loaded card images
  966. */
  967. void UnLoadCards(SDL_Surface **_array_of_cards)
  968. {
  969. // unload all cards of the memory: +1 for the card back
  970. for (int i = 0 ; i < MAX_DECK_SIZE + 1; i++ )
  971. {
  972. SDL_FreeSurface(_array_of_cards[i]);
  973. }
  974. }
  975.  
  976. /**
  977. * RenderLogo function: Renders the IST Logo on the window screen
  978. * \param x X coordinate of the Logo
  979. * \param y Y coordinate of the Logo
  980. * \param _logoIST surface with the IST logo image to render
  981. * \param _renderer renderer to handle all rendering in a window
  982. */
  983. int RenderLogo(int x, int y, SDL_Surface *_logoIST, SDL_Renderer* _renderer)
  984. {
  985. SDL_Texture *text_IST;
  986. SDL_Rect boardPos;
  987.  
  988. // space occupied by the logo
  989. boardPos.x = x;
  990. boardPos.y = y;
  991. boardPos.w = _logoIST->w;
  992. boardPos.h = _logoIST->h;
  993.  
  994. // render it
  995. text_IST = SDL_CreateTextureFromSurface(_renderer, _logoIST);
  996. SDL_RenderCopy(_renderer, text_IST, NULL, &boardPos);
  997.  
  998. // destroy associated texture !
  999. SDL_DestroyTexture(text_IST);
  1000. return _logoIST->h;
  1001. }
  1002.  
  1003. /**
  1004. * RenderText function: Renders the IST Logo on the window screen
  1005. * \param x X coordinate of the text
  1006. * \param y Y coordinate of the text
  1007. * \param text string where the text is written
  1008. * \param font TTF font used to render the text
  1009. * \param _renderer renderer to handle all rendering in a window
  1010. */
  1011. int RenderText(int x, int y, const char *text, TTF_Font *_font, SDL_Color *_color, SDL_Renderer* _renderer)
  1012. {
  1013. SDL_Surface *text_surface;
  1014. SDL_Texture *text_texture;
  1015. SDL_Rect solidRect;
  1016.  
  1017. solidRect.x = x;
  1018. solidRect.y = y;
  1019. // create a surface from the string text with a predefined font
  1020. text_surface = TTF_RenderText_Blended(_font,text,*_color);
  1021. if(!text_surface)
  1022. {
  1023. printf("TTF_RenderText_Blended: %s\n", TTF_GetError());
  1024. exit(EXIT_FAILURE);
  1025. }
  1026. // create texture
  1027. text_texture = SDL_CreateTextureFromSurface(_renderer, text_surface);
  1028. // obtain size
  1029. SDL_QueryTexture( text_texture, NULL, NULL, &solidRect.w, &solidRect.h );
  1030. // render it !
  1031. SDL_RenderCopy(_renderer, text_texture, NULL, &solidRect);
  1032.  
  1033. SDL_DestroyTexture(text_texture);
  1034. SDL_FreeSurface(text_surface);
  1035. return solidRect.h;
  1036. }
  1037.  
  1038. /**
  1039. * InitEverything: Initializes the SDL2 library and all graphical components: font, window, renderer
  1040. * \param width width in px of the window
  1041. * \param height height in px of the window
  1042. * \param _img surface to be created with the table background and IST logo
  1043. * \param _window represents the window of the application
  1044. * \param _renderer renderer to handle all rendering in a window
  1045. */
  1046. void InitEverything(int width, int height, TTF_Font **_font, SDL_Surface *_img[], SDL_Window** _window, SDL_Renderer** _renderer)
  1047. {
  1048. InitSDL();
  1049. InitFont();
  1050. *_window = CreateWindow(width, height);
  1051. *_renderer = CreateRenderer(width, height, *_window);
  1052.  
  1053. // load the table texture
  1054. _img[0] = IMG_Load("table_texture.png");
  1055. if (_img[0] == NULL)
  1056. {
  1057. printf("Unable to load image: %s\n", SDL_GetError());
  1058. exit(EXIT_FAILURE);
  1059. }
  1060.  
  1061. // load IST logo
  1062. _img[1] = SDL_LoadBMP("ist_logo.bmp");
  1063. if (_img[1] == NULL)
  1064. {
  1065. printf("Unable to load bitmap: %s\n", SDL_GetError());
  1066. exit(EXIT_FAILURE);
  1067. }
  1068. // this opens (loads) a font file and sets a size
  1069. *_font = TTF_OpenFont("FreeSerif.ttf", 16);
  1070. if(!*_font)
  1071. {
  1072. printf("TTF_OpenFont: %s\n", TTF_GetError());
  1073. exit(EXIT_FAILURE);
  1074. }
  1075. }
  1076.  
  1077. /**
  1078. * InitSDL: Initializes the SDL2 graphic library
  1079. */
  1080. void InitSDL()
  1081. {
  1082. // init SDL library
  1083. if ( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
  1084. {
  1085. printf(" Failed to initialize SDL : %s\n", SDL_GetError());
  1086. exit(EXIT_FAILURE);
  1087. }
  1088. }
  1089.  
  1090. /**
  1091. * InitFont: Initializes the SDL2_ttf font library
  1092. */
  1093. void InitFont()
  1094. {
  1095. // Init font library
  1096. if(TTF_Init()==-1)
  1097. {
  1098. printf("TTF_Init: %s\n", TTF_GetError());
  1099. exit(EXIT_FAILURE);
  1100. }
  1101. }
  1102.  
  1103. /**
  1104. * CreateWindow: Creates a window for the application
  1105. * \param width width in px of the window
  1106. * \param height height in px of the window
  1107. * \return pointer to the window created
  1108. */
  1109. SDL_Window* CreateWindow(int width, int height)
  1110. {
  1111. SDL_Window *window;
  1112. // init window
  1113. window = SDL_CreateWindow( "BlackJack", WINDOW_POSX, WINDOW_POSY, width+EXTRASPACE, height, 0 );
  1114. // check for error !
  1115. if ( window == NULL )
  1116. {
  1117. printf("Failed to create window : %s\n", SDL_GetError());
  1118. exit(EXIT_FAILURE);
  1119. }
  1120. return window;
  1121. }
  1122.  
  1123. /**
  1124. * CreateRenderer: Creates a renderer for the application
  1125. * \param width width in px of the window
  1126. * \param height height in px of the window
  1127. * \param _window represents the window for which the renderer is associated
  1128. * \return pointer to the renderer created
  1129. */
  1130. SDL_Renderer* CreateRenderer(int width, int height, SDL_Window *_window)
  1131. {
  1132. SDL_Renderer *renderer;
  1133. // init renderer
  1134. renderer = SDL_CreateRenderer( _window, -1, 0 );
  1135.  
  1136. if ( renderer == NULL )
  1137. {
  1138. printf("Failed to create renderer : %s", SDL_GetError());
  1139. exit(EXIT_FAILURE);
  1140. }
  1141.  
  1142. // set size of renderer to the same as window
  1143. SDL_RenderSetLogicalSize( renderer, width+EXTRASPACE, height );
  1144.  
  1145. return renderer;
  1146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement