Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright (C) 2015 Guillaume Charifi
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
- #include <stdlib.h>
- #include <time.h>
- #include "libhang.h"
- #include "libhang/libsuicide.h"
- #include "libhang/obj_classes/ColoredCube.h"
- #define ENTITIES_DISTANCE (1./10.)
- #define UNDEFINED 0
- #define ZOMBIE 1
- #define HUNTER 2
- #define VILLAGER 3
- static int nb_zombies = 0;
- static int nb_hunters = 0;
- static int nb_villagers = 0;
- static int nb_rounds = 0;
- static int nb_single = 0;
- static int nb_double = 0;
- static int nb_dead_zombies = 0;
- static int nb_dead_victims = 0;
- static int nb_dead_hunters = 0;
- static int hunters_attacked = 0;
- static int zombies_attacked = 0;
- static int results_displayed = 0;
- static struct cube {
- int type;
- int dir_x;
- int dir_y;
- int used;
- int moved;
- lh_obj_t *cube;
- int is_target;
- } cubes[20][20] = {0};
- static volatile int terminate = 0;
- static inline void pre_move(void)
- {
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- cubes[i][j].dir_x = 0;
- cubes[i][j].dir_y = 0;
- cubes[i][j].moved = 0;
- if(!cubes[i][j].cube)
- continue;
- cubes[i][j].used = 1;
- int i_min = (i == 0) ? 0 : i-1;
- int j_min = (j == 0) ? 0 : j-1;
- int i_max = (i == 19) ? 19 : i+1;
- int j_max = (j == 19) ? 19 : j+1;
- if(cubes[i][j].type == VILLAGER
- && cubes[i_min][j_min].type != ZOMBIE
- && cubes[i_max][j_min].type != ZOMBIE
- && cubes[i_min][j_max].type != ZOMBIE
- && cubes[i_max][j_max].type != ZOMBIE
- && cubes[i_min][j].type != ZOMBIE
- && cubes[i][j_min].type != ZOMBIE
- && cubes[i_max][j].type != ZOMBIE
- && cubes[i][j_max].type != ZOMBIE)
- continue;
- switch((int)(((float)rand() / (float)RAND_MAX) * 8.)) {
- case 0:
- if(cubes[i][j].type != ZOMBIE) {
- if(cubes[i_min][j_min].cube)
- break;
- cubes[i][j].dir_x = -1;
- cubes[i][j].dir_y = -1;
- break;
- }
- case 1:
- if(cubes[i_min][j].cube)
- break;
- cubes[i][j].dir_x = -1;
- break;
- case 2:
- if(cubes[i][j].type != ZOMBIE) {
- if(cubes[i_max][j_max].cube)
- break;
- cubes[i][j].dir_x = 1;
- cubes[i][j].dir_y = 1;
- break;
- }
- case 3:
- if(cubes[i_max][j].cube)
- break;
- cubes[i][j].dir_x = 1;
- break;
- case 4:
- if(cubes[i][j].type != ZOMBIE) {
- if(cubes[i_max][j_min].cube)
- break;
- cubes[i][j].dir_x = 1;
- cubes[i][j].dir_y = -1;
- break;
- }
- case 5:
- if(cubes[i][j_min].cube)
- break;
- cubes[i][j].dir_y = -1;
- break;
- case 6:
- if(cubes[i][j].type != ZOMBIE) {
- if(cubes[i_min][j_max].cube)
- break;
- cubes[i][j].dir_x = -1;
- cubes[i][j].dir_y = 1;
- break;
- }
- default:
- if(cubes[i][j_max].cube)
- break;
- cubes[i][j].dir_y = 1;
- }
- if((i == 0 && cubes[i][j].dir_x < 0)
- || (i == 19 && cubes[i][j].dir_x > 0))
- cubes[i][j].dir_x = 0;
- if((j == 0 && cubes[i][j].dir_y < 0)
- || (j == 19 && cubes[i][j].dir_y > 0))
- cubes[i][j].dir_y = 0;
- if(cubes[i + cubes[i][j].dir_x][j + cubes[i][j].dir_y].used) {
- cubes[i][j].dir_x = 0;
- cubes[i][j].dir_y = 0;
- } else {
- cubes[i + cubes[i][j].dir_x][j + cubes[i][j].dir_y].used = 1;
- }
- }
- }
- }
- static inline void move(lh_window_t *window)
- {
- int rand_y = ((int)((float)rand() / (float)RAND_MAX * 2.)) ? -1 : 1;
- for(float n = 0; n < 100; n++) {
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube)
- continue;
- if(!cubes[i][j].dir_x && !cubes[i][j].dir_y) {
- cubes[i][j].cube->angle.x = 0;
- cubes[i][j].cube->angle.y = rand_y * n / 99. * LH_PI * 2.;
- cubes[i][j].cube->angle.z = 0;
- continue;
- }
- cubes[i][j].cube->pos.x += cubes[i][j].dir_x * ENTITIES_DISTANCE / 100.f;
- cubes[i][j].cube->pos.z += cubes[i][j].dir_y * ENTITIES_DISTANCE / 100.f;
- if(cubes[i][j].dir_x && cubes[i][j].dir_y) {
- cubes[i][j].cube->angle.z = -cubes[i][j].dir_x * n / 99. * LH_PI / 2.;
- cubes[i][j].cube->angle.x = cubes[i][j].dir_y * n / 99. * LH_PI / 2.;
- } else {
- cubes[i][j].cube->angle.z = -cubes[i][j].dir_x * n / 99. * LH_PI / 2.;
- cubes[i][j].cube->angle.x = cubes[i][j].dir_y * n / 99. * LH_PI / 2.;
- }
- cubes[i][j].cube->angle.y = 0;
- }
- }
- lhDirtyObjBuffer(window);
- lhDelay(5);
- }
- }
- static inline void post_move(lh_window_t *window)
- {
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- cubes[i][j].used = 0;
- if(!cubes[i][j].cube || cubes[i][j].moved)
- continue;
- int new_i = i + cubes[i][j].dir_x;
- int new_j = j + cubes[i][j].dir_y;
- if(new_i == i && new_j == j)
- continue;
- cubes[new_i][new_j].type = cubes[i][j].type;
- cubes[new_i][new_j].cube = cubes[i][j].cube;
- cubes[i][j].type = UNDEFINED;
- cubes[i][j].cube = NULL;
- cubes[new_i][new_j].cube->pos.x = new_i * ENTITIES_DISTANCE - (ENTITIES_DISTANCE * 19. / 2.);
- cubes[new_i][new_j].cube->pos.z = new_j * ENTITIES_DISTANCE - (ENTITIES_DISTANCE * 19. / 2.);
- cubes[i][j].moved = 1;
- cubes[new_i][new_j].moved = 1;
- }
- }
- lhDirtyObjBuffer(window);
- }
- static inline void pre_hunter_attack(void)
- {
- hunters_attacked = 0;
- if(!nb_hunters || !nb_zombies)
- return;
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube || cubes[i][j].type != HUNTER)
- continue;
- int nb_targets = 0;
- int i_min = (i == 0) ? 0 : i-1;
- int j_min = (j == 0) ? 0 : j-1;
- int i_max = (i == 19) ? 19 : i+1;
- int j_max = (j == 19) ? 19 : j+1;
- if(cubes[i_min][j_min].cube && cubes[i_min][j_min].type == ZOMBIE && !cubes[i_min][j_min].is_target) { cubes[i_min][j_min].is_target = 1; nb_targets++; }
- if(cubes[i_max][j_min].cube && cubes[i_max][j_min].type == ZOMBIE && !cubes[i_max][j_min].is_target) { cubes[i_max][j_min].is_target = 1; nb_targets++; }
- if(nb_targets < 2)
- if(cubes[i_min][j_max].cube && cubes[i_min][j_max].type == ZOMBIE && !cubes[i_min][j_max].is_target) { cubes[i_min][j_max].is_target = 1; nb_targets++; }
- if(nb_targets < 2)
- if(cubes[i_max][j_max].cube && cubes[i_max][j_max].type == ZOMBIE && !cubes[i_max][j_max].is_target) { cubes[i_max][j_max].is_target = 1; nb_targets++; }
- if(nb_targets < 2)
- if(cubes[i_min][j].cube && cubes[i_min][j].type == ZOMBIE && !cubes[i_min][j].is_target) { cubes[i_min][j].is_target = 1; nb_targets++; }
- if(nb_targets < 2)
- if(cubes[i][j_min].cube && cubes[i][j_min].type == ZOMBIE && !cubes[i][j_min].is_target) { cubes[i][j_min].is_target = 1; nb_targets++; }
- if(nb_targets < 2)
- if(cubes[i_max][j].cube && cubes[i_max][j].type == ZOMBIE && !cubes[i_max][j].is_target) { cubes[i_max][j].is_target = 1; nb_targets++; }
- if(nb_targets < 2)
- if(cubes[i][j_max].cube && cubes[i][j_max].type == ZOMBIE && !cubes[i][j_max].is_target) { cubes[i][j_max].is_target = 1; nb_targets++; }
- if(nb_targets) hunters_attacked = 1;
- if(nb_targets == 1) nb_single++;
- if(nb_targets == 2) nb_double++;
- nb_dead_zombies += nb_targets;;
- }
- }
- }
- static inline void hunter_attack(lh_window_t *window)
- {
- if(!hunters_attacked)
- return;
- for(float n = 0; n < 100; n++) {
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube || !cubes[i][j].is_target)
- continue;
- lhColoredCubeSetColor(window, cubes[i][j].cube, &LH_RGBA(1.f, (float)n / 99.f, (float)n / 99.f, 1.f - (float)n / 99.f));
- }
- }
- lhDirtyObjBuffer(window);
- lhDelay(5);
- }
- }
- static inline void post_hunter_attack(lh_window_t *window)
- {
- if(!hunters_attacked)
- return;
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube || !cubes[i][j].is_target)
- continue;
- lhDeleteColoredCube(window, cubes[i][j].cube);
- nb_zombies--;
- cubes[i][j].type = UNDEFINED;
- cubes[i][j].cube = NULL;
- cubes[i][j].is_target = 0;
- }
- }
- }
- static inline void pre_zombie_attack(void)
- {
- zombies_attacked = 0;
- if(!nb_zombies || (!nb_villagers && !nb_hunters))
- return;
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube || cubes[i][j].type != ZOMBIE)
- continue;
- int nb_targets = 0;
- int i_min = (i == 0) ? 0 : i-1;
- int j_min = (j == 0) ? 0 : j-1;
- int i_max = (i == 19) ? 19 : i+1;
- int j_max = (j == 19) ? 19 : j+1;
- if(cubes[i_min][j].cube && (cubes[i_min][j].type == VILLAGER || cubes[i_min][j].type == HUNTER) && !cubes[i_min][j].is_target) { cubes[i_min][j].is_target = 1; nb_targets++; if(cubes[i_min][j].type == VILLAGER) nb_dead_victims++; else nb_dead_hunters++; }
- if(cubes[i][j_min].cube && (cubes[i][j_min].type == VILLAGER || cubes[i][j_min].type == HUNTER) && !cubes[i][j_min].is_target) { cubes[i][j_min].is_target = 1; nb_targets++; if(cubes[i][j_min].type == VILLAGER) nb_dead_victims++; else nb_dead_hunters++; }
- if(cubes[i_max][j].cube && (cubes[i_max][j].type == VILLAGER || cubes[i_max][j].type == HUNTER) && !cubes[i_max][j].is_target) { cubes[i_max][j].is_target = 1; nb_targets++; if(cubes[i_max][j].type == VILLAGER) nb_dead_victims++; else nb_dead_hunters++; }
- if(cubes[i][j_max].cube && (cubes[i][j_max].type == VILLAGER || cubes[i][j_max].type == HUNTER) && !cubes[i][j_max].is_target) { cubes[i][j_max].is_target = 1; nb_targets++; if(cubes[i][j_max].type == VILLAGER) nb_dead_victims++; else nb_dead_hunters++; }
- if(nb_targets)
- zombies_attacked = 1;
- }
- }
- }
- static inline void zombie_attack(lh_window_t *window)
- {
- if(!zombies_attacked)
- return;
- for(float n = 0; n < 100; n++) {
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube || !cubes[i][j].is_target)
- continue;
- float m = (float)n / 99.f;
- lhColoredCubeSetColor(window, cubes[i][j].cube, &LH_RGBA(m, (cubes[i][j].type == VILLAGER) ? 1. : m, (cubes[i][j].type == HUNTER) ? 1. : m, 1.f - m));
- }
- }
- lhDirtyObjBuffer(window);
- lhDelay(5);
- }
- for(float n = 0; n < 100; n++) {
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube || !cubes[i][j].is_target)
- continue;
- float m = (float)n / 99.f;
- lhColoredCubeSetColor(window, cubes[i][j].cube, &LH_RGBA(1.f, 1.f - m, 1.f - m, m));
- }
- }
- lhDirtyObjBuffer(window);
- lhDelay(5);
- }
- }
- static inline void post_zombie_attack(void)
- {
- if(!zombies_attacked)
- return;
- for(int i=0; i<20; i++) {
- for(int j=0; j<20; j++) {
- if(!cubes[i][j].cube || !cubes[i][j].is_target)
- continue;
- if(cubes[i][j].type == HUNTER) nb_hunters--;
- if(cubes[i][j].type == VILLAGER) nb_villagers--;
- nb_zombies++;
- cubes[i][j].type = ZOMBIE;
- cubes[i][j].is_target = 0;
- }
- }
- }
- static inline void disp_results(void)
- {
- if(results_displayed)
- return;
- printf("Fin de la partie !\n"
- "Nombre de single-kills : %d.\n"
- "Nombre de double-kills : %d.\n"
- "Nombre de zombies exterminés : %d.\n"
- "Nombre de victimes zombifiées : %d.\n"
- "Nombre de chasseurs zombifiés : %d.\n",
- nb_single,
- nb_double,
- nb_dead_zombies,
- nb_dead_victims,
- nb_dead_hunters);
- results_displayed = 1;
- }
- static void *anim(void *window)
- {
- while(1) {
- if(terminate)
- break;
- if(!nb_rounds) {
- nb_zombies = 0;
- nb_hunters = 0;
- nb_villagers = 0;
- disp_results();
- }
- pre_move();
- move(window);
- post_move(window);
- pre_hunter_attack();
- hunter_attack(window);
- post_hunter_attack(window);
- pre_zombie_attack();
- zombie_attack(window);
- post_zombie_attack();
- lhDirtyObjBuffer(window);
- while(lhIsDirtyObjBuffer(window))
- lhDelay(0);
- if(nb_rounds > 0)
- nb_rounds--;
- }
- }
- static inline void fflushstdin(void)
- {
- int c;
- while((c = fgetc(stdin)) != EOF && c != '\n');
- }
- int main()
- {
- lh_window_t *window;
- lh_thread_t *anim_thread;
- srand(time(NULL));
- int ret = 0;
- do {
- printf("Nombre de zombies : ");
- ret = scanf("%d", &nb_zombies);
- fflushstdin();
- } while(ret != 1 || nb_zombies < 0);
- do {
- printf("Nombre de chasseurs : ");
- ret = scanf("%d", &nb_hunters);
- fflushstdin();
- } while(ret != 1 || nb_hunters < 0);
- do {
- printf("Nombre de villageois : ");
- ret = scanf("%d", &nb_villagers);
- fflushstdin();
- } while(ret != 1 || nb_villagers < 0);
- do {
- printf("Nombre de tours : ");
- ret = scanf("%d", &nb_rounds);
- fflushstdin();
- } while(ret != 1);
- if(nb_zombies + nb_hunters + nb_villagers > 20 * 20) {
- fprintf(stderr, "Dépassement du nombre maximal d'entités.\n");
- return -1;
- }
- lhInit();
- window = lhCreateWindow("Exo du Lundi 5", 0, 0, 600, 600, LH_DEFAULT_DEPTH);
- lhEnableMSAA(window, LH_MSAA_NONE);
- lhSetRenderDistances(window, &LH_DISTANCES(.1f, 500.f));
- lhSetBackColor(window, &LH_RGBA(.1f, .1f, .1f, 1.f));
- lhSetAmbientLight(window, &LH_RGB(0.f, 0.f, .1f));
- lhEnableLight(window, 0, LH_TRUE);
- lhSetLightParameters(window, 0, &LH_RGB(1.f, 1.f, 1.f), &LH_VEC3(0.f, -1.f, 0.f));
- lhSetCameraPos(window, &LH_VEC3(0.f, 2.f, 0.f));
- lhSetCameraAngle(window, &LH_VEC3(-.5 * LH_PI, 0.f, 0.f));
- lhRegColoredCube(window);
- int nb_remaining = nb_zombies + nb_hunters + nb_villagers;
- int nb_zombies_remaining = nb_zombies;
- int nb_hunters_remaining = nb_hunters;
- int nb_villagers_remaining = nb_villagers;
- while(nb_remaining) {
- for(int i=0; i<20 && nb_remaining; i++) {
- for(int j=0; j<20 && nb_remaining; j++) {
- lh_rgba_t color;
- if(cubes[i][j].cube)
- continue;
- switch((int)(((float)rand() / (float)RAND_MAX) * (3.f + 20.f * 20.f * nb_remaining / (nb_zombies + nb_hunters + nb_villagers)))) {
- case 0:
- if(!nb_zombies_remaining) continue;
- color.r = 1.f;
- color.g = 0.f;
- color.b = 0.f;
- color.a = 1.f;
- cubes[i][j].type = ZOMBIE;
- nb_zombies_remaining--;
- break;
- case 1:
- if(!nb_hunters_remaining) continue;
- color.r = 0.f;
- color.g = 0.f;
- color.b = 1.f;
- color.a = 1.f;
- cubes[i][j].type = HUNTER;
- nb_hunters_remaining--;
- break;
- case 2:
- if(!nb_villagers_remaining) continue;
- color.r = 0.f;
- color.g = 1.f;
- color.b = 0.f;
- color.a = 1.f;
- cubes[i][j].type = VILLAGER;
- nb_villagers_remaining--;
- break;
- default:
- continue;
- }
- cubes[i][j].cube = lhNewColoredCube(window, 1.f / 30.f, &LH_VEC3(i * ENTITIES_DISTANCE - (ENTITIES_DISTANCE * 19. / 2.), 0.f, j * ENTITIES_DISTANCE - (ENTITIES_DISTANCE * 19. / 2.)), &LH_VEC3(0.f, 0.f, 0.f), &color, LH_TRUE);
- nb_remaining--;
- }
- }
- }
- anim_thread = lhCreateThread(anim, window);
- lhStartDrawing(window);
- lhEnterEventLoop(window);
- terminate = 1;
- lhWaitThread(anim_thread, NULL);
- lhReleaseThread(anim_thread);
- lhDestroyWindow(window);
- disp_results();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement