diff --git a/Makefile b/Makefile index 7b32397..29cc26f 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,11 @@ all: bin/back test: bin/back bin/back levels/test.txt bots/dumb bots/dumb bots/dumb bots/dumb +ez: bin/back + bin/back levels/simple.txt bots/dumb bots/dumb bots/dumb bots/dumb + mem: bin/back - valgrind --leak-check=full ./bin/back + valgrind --leak-check=full ./bin/back levels/test.txt bots/dumb bots/dumb bots/dumb bots/dumb bin/back: obj/main.o obj/display.o obj/base.o obj/collisions.o obj/cars.o obj/rooms.o obj/structure.o mkdir -p bin diff --git a/bin/back b/bin/back index c32f6d8..c31e692 100755 Binary files a/bin/back and b/bin/back differ diff --git a/bots/answer.txt b/bots/answer.txt index 7de715a..930b9f7 100644 --- a/bots/answer.txt +++ b/bots/answer.txt @@ -1 +1 @@ -165 74 \ No newline at end of file +137 83 \ No newline at end of file diff --git a/levels/simple.txt b/levels/simple.txt new file mode 100644 index 0000000..f834a6b --- /dev/null +++ b/levels/simple.txt @@ -0,0 +1,13 @@ +1 3 +S1E + +$ +. = NULL +0 = Vertical +1 = Horizontal +2 = TopRight (NE) +3 = BottomRight (SE) +4 = BottomLeft (SW) +5 = TopLeft (NW) +S = Start +E = End \ No newline at end of file diff --git a/obj/base.o b/obj/base.o index 7cc3754..72f341b 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/cars.o b/obj/cars.o index ccd5c67..96596a5 100644 Binary files a/obj/cars.o and b/obj/cars.o differ diff --git a/obj/collisions.o b/obj/collisions.o index d50de6e..f2a2666 100644 Binary files a/obj/collisions.o and b/obj/collisions.o differ diff --git a/obj/display.o b/obj/display.o index 0995f13..27a9ced 100644 Binary files a/obj/display.o and b/obj/display.o differ diff --git a/obj/main.o b/obj/main.o index f2247a2..3e9032b 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/obj/rooms.o b/obj/rooms.o index d4ad35f..3c37f71 100644 Binary files a/obj/rooms.o and b/obj/rooms.o differ diff --git a/obj/structure.o b/obj/structure.o index 083284c..1f20770 100644 Binary files a/obj/structure.o and b/obj/structure.o differ diff --git a/output.txt b/output.txt index 64a88f9..1dce8f1 100644 --- a/output.txt +++ b/output.txt @@ -1,8 +1,8 @@ 4 -0 (3 0) (45.17 65.83) -1 (4 2) (65.68 34.72) -2 (3 3) (37.74 58.35) -3 (2 0) (19.47 35.72) +0 (2 0) (44.74 79.84) +1 (2 0) (22.92 63.60) +2 (2 0) (22.92 36.40) +3 (2 0) (44.74 20.16) [3] 5 5 @@ -14,7 +14,7 @@ 100 200 -10 +5 0.90 0.80 0.20 diff --git a/src/base.c b/src/base.c index 1bd7233..dd621e0 100644 --- a/src/base.c +++ b/src/base.c @@ -15,6 +15,9 @@ #include "cars.h" #include "base.h" +int* winners; +int remainingTurns; + int currentTurn; int nPlayers; carData* players; @@ -22,8 +25,11 @@ carData* players; void init_all(int nPl) { nPlayers = nPl; currentTurn = 0; + remainingTurns = -1; + winners = malloc(sizeof(int)*nPlayers); players = malloc(sizeof(carData)*nPlayers); for(int p = 0; p < nPlayers; p++) { + winners[p] = 0; players[p].rgb = (color){.red = 255, .green = 255, .blue = 255}; players[p].c = init_car(p, nPlayers); } @@ -36,6 +42,121 @@ void destroy_all() { free(players); } +// 1 = N +// 2 = E +// 4 = S +// 8 = W +int return_directions(road r) { + switch (r){ + case NONE: return 0; + case START: return 15; + case END: return 15; + case STR_V: return 5; + case STR_H: return 10; + case TURN_NE: return 3; + case TURN_SE: return 6; + case TURN_SW: return 12; + case TURN_NW: return 9; + + default: return 0; + } +} + +void visit(level* lvl, path* pth, int cx, int cy, bool* brk) { + if(!(*brk) && (cx >= 0 && cy >= 0 && cx < lvl->lines && cy < lvl->cols) && pth->nxts[cx][cy].dx == -2) { + if(cx == FINISH_CHX && cy == FINISH_CHY) { + pth->nxts[cx][cy] = (next){.dx = -1, .dy = -1}; + *brk = true; + //printf("found\n"); + } else { + int carc = return_directions(lvl->map[cx][cy]); + //printf("at (%d %d) [%d%d%d%d]\n", cx, cy, carc%2, (carc/2)%2, (carc/4)%2, (carc/8)%2); + if(!(*brk))pth->nxts[cx][cy] = (next){.dx = 2, .dy = 2}; + + if(carc%2==1 && !(*brk)) { + pth->nxts[cx][cy] = (next){.dx = -1, .dy = 0}; + visit(lvl, pth, cx-1, cy, brk); + } + + if((carc/2)%2==1 && !(*brk)) { + pth->nxts[cx][cy] = (next){.dx = 0, .dy = 1}; + visit(lvl, pth, cx, cy+1, brk); + } + + if((carc/4)%2==1 && !(*brk)) { + pth->nxts[cx][cy] = (next){.dx = 1, .dy = 0}; + visit(lvl, pth, cx+1, cy, brk); + } + + if((carc/8)%2==1 && !(*brk)) { + pth->nxts[cx][cy] = (next){.dx = 0, .dy = -1}; + visit(lvl, pth, cx, cy-1, brk); + } + + if(!(*brk))pth->nxts[cx][cy] = (next){.dx = 2, .dy = 2}; + } + } +} + +path* getPath(level* lvl) { + path* res = malloc(sizeof(path)); + res->cols = lvl->cols; + res->lines = lvl->lines; + res->start = (pt){.ix = START_CHX, .iy = START_CHY}; + res->nxts = malloc(sizeof(next*)*lvl->lines); + for(int l = 0; l < lvl->lines; l++) { + res->nxts[l] = malloc(sizeof(next)*lvl->cols); + for(int c = 0; c < lvl->cols; c++) { + res->nxts[l][c] = (next){.dx = -2, .dy = -2}; + } + } + + bool brk = false; + visit(lvl, res, START_CHX, START_CHY, &brk); + + return res; +} + +void printPath(path* pth) { + for(int l = 0; l < pth->lines; l++) { + for(int c = 0; c < pth->cols; c++) { + if(pth->nxts[l][c].dx == -1 && pth->nxts[l][c].dy == -1) { + printf("E"); + } else if(pth->nxts[l][c].dx == 1) { + printf("v"); + } else if(pth->nxts[l][c].dx == -1) { + printf("^"); + } else if(pth->nxts[l][c].dy == 1) { + printf(">"); + } else if(pth->nxts[l][c].dy == -1) { + printf("<"); + } else { + printf("."); + } + } + printf("\n"); + } + printf("\n"); +} + +void printLvl(level* lvl) { + for(int l = 0; l < lvl->lines; l++) { + for(int c = 0; c < lvl->cols; c++) { + printf("%d", (int)lvl->map[l][c]); + } + printf("\n"); + } + printf("\n"); +} + +void freePath(path* p) { + for(int l = 0; l < p->lines; l++) { + free(p->nxts[l]); + } + free(p->nxts); + free(p); +} + // ------------------------- // int ln_baseN(int n, int b) { @@ -92,4 +213,6 @@ double dot(ptf p1, ptf p2) { ptf add(ptf p1, ptf p2) { return (ptf){.fx = p1.fx + p2.fx, .fy = p1.fy + p2.fy}; -} \ No newline at end of file +} + +// ------------------------------------------------------------------------------------ // diff --git a/src/base.h b/src/base.h index 78dbd22..34592e5 100644 --- a/src/base.h +++ b/src/base.h @@ -19,4 +19,9 @@ ptf normalize(ptf p); double dot(ptf p1, ptf p2); ptf add(ptf p1, ptf p2); +path* getPath(level* lvl); +void printPath(path* pth); +void printLvl(level* lvl); +void freePath(path* p); + #endif \ No newline at end of file diff --git a/src/collisions.c b/src/collisions.c index 7fbab5d..1a7b0c3 100644 --- a/src/collisions.c +++ b/src/collisions.c @@ -53,32 +53,32 @@ void move_on_ENDS(int nPl) { c->pos.fx += c->vel.fx*DT; c->pos.fy += c->vel.fy*DT; if( - (START_DIR != 3 && c->pos.fx-PLAYER_R/2 <= 0.0 && c->vel.fx < 0.0) || - (START_DIR == 3 && c->pos.fx-PLAYER_R/2 <= 0.0 && c->vel.fx < 0.0 && (c->pos.fy-PLAYER_R/2 <= ROOM_SIZE*DIST_EDGE || c->pos.fy+PLAYER_R/2 >= ROOM_SIZE*(1.0-DIST_EDGE))) + (START_DIR != 3 && c->pos.fx-PLAYER_R <= 0.0 && c->vel.fx < 0.0) || + (START_DIR == 3 && c->pos.fx-PLAYER_R <= 0.0 && c->vel.fx < 0.0 && (c->pos.fy-PLAYER_R <= ROOM_SIZE*DIST_EDGE || c->pos.fy+PLAYER_R >= ROOM_SIZE*(1.0-DIST_EDGE))) ) { // left wall c->vel.fx *= -1.0; c->pos.fx += 2.0*c->vel.fx*DT; c->vel.fx *= RESTITUTION_WALL; } if( - (START_DIR != 1 && c->pos.fx+PLAYER_R/2 >= 1.0*ROOM_SIZE && c->vel.fx > 0.0) || - (START_DIR == 1 && c->pos.fx+PLAYER_R/2 >= 1.0*ROOM_SIZE && c->vel.fx > 0.0 && (c->pos.fy-PLAYER_R/2 <= ROOM_SIZE*DIST_EDGE || c->pos.fy+PLAYER_R/2 >= ROOM_SIZE*(1.0-DIST_EDGE))) + (START_DIR != 1 && c->pos.fx+PLAYER_R >= 1.0*ROOM_SIZE && c->vel.fx > 0.0) || + (START_DIR == 1 && c->pos.fx+PLAYER_R >= 1.0*ROOM_SIZE && c->vel.fx > 0.0 && (c->pos.fy-PLAYER_R <= ROOM_SIZE*DIST_EDGE || c->pos.fy+PLAYER_R >= ROOM_SIZE*(1.0-DIST_EDGE))) ) { // right wall c->vel.fx *= -1.0; c->pos.fx += 2.0*c->vel.fx*DT; c->vel.fx *= RESTITUTION_WALL; } if( - (START_DIR != 0 && c->pos.fy-PLAYER_R/2 <= 0.0 && c->vel.fy < 0.0) || - (START_DIR == 0 && c->pos.fy-PLAYER_R/2 <= 0.0 && c->vel.fy < 0.0 && (c->pos.fx-PLAYER_R/2 <= ROOM_SIZE*DIST_EDGE || c->pos.fx+PLAYER_R/2 >= ROOM_SIZE*(1.0-DIST_EDGE))) + (START_DIR != 0 && c->pos.fy-PLAYER_R <= 0.0 && c->vel.fy < 0.0) || + (START_DIR == 0 && c->pos.fy-PLAYER_R <= 0.0 && c->vel.fy < 0.0 && (c->pos.fx-PLAYER_R <= ROOM_SIZE*DIST_EDGE || c->pos.fx+PLAYER_R >= ROOM_SIZE*(1.0-DIST_EDGE))) ) { // top wall c->vel.fy *= -1.0; c->pos.fy += 2.0*c->vel.fy*DT; c->vel.fy *= RESTITUTION_WALL; } if( - (START_DIR != 2 && c->pos.fy+PLAYER_R/2 >= 1.0*ROOM_SIZE && c->vel.fy > 0.0) || - (START_DIR == 2 && c->pos.fy+PLAYER_R/2 >= 1.0*ROOM_SIZE && c->vel.fy > 0.0 && (c->pos.fx-PLAYER_R/2 <= ROOM_SIZE*DIST_EDGE || c->pos.fx+PLAYER_R/2 >= ROOM_SIZE*(1.0-DIST_EDGE))) + (START_DIR != 2 && c->pos.fy+PLAYER_R >= 1.0*ROOM_SIZE && c->vel.fy > 0.0) || + (START_DIR == 2 && c->pos.fy+PLAYER_R >= 1.0*ROOM_SIZE && c->vel.fy > 0.0 && (c->pos.fx-PLAYER_R <= ROOM_SIZE*DIST_EDGE || c->pos.fx+PLAYER_R >= ROOM_SIZE*(1.0-DIST_EDGE))) ) { // bottom wall c->vel.fy *= -1.0; c->pos.fy += 2.0*c->vel.fy*DT; @@ -90,12 +90,12 @@ void move_on_STR_V(int nPl) { car* c = players[nPl].c; c->pos.fx += c->vel.fx*DT; c->pos.fy += c->vel.fy*DT; - if(c->pos.fx-PLAYER_R/2 <= ROOM_SIZE*DIST_EDGE && c->vel.fx < 0.0) { // left wall + if(c->pos.fx-PLAYER_R <= ROOM_SIZE*DIST_EDGE && c->vel.fx < 0.0) { // left wall c->vel.fx *= -1.0; c->pos.fx += 2.0*c->vel.fx*DT; c->vel.fx *= RESTITUTION_WALL; } - if(c->pos.fx+PLAYER_R/2 >= ROOM_SIZE*(1.0-DIST_EDGE) && c->vel.fx > 0.0) { // right wall + if(c->pos.fx+PLAYER_R >= ROOM_SIZE*(1.0-DIST_EDGE) && c->vel.fx > 0.0) { // right wall c->vel.fx *= -1.0; c->pos.fx += 2.0*c->vel.fx*DT; c->vel.fx *= RESTITUTION_WALL; @@ -106,12 +106,12 @@ void move_on_STR_H(int nPl) { car* c = players[nPl].c; c->pos.fx += c->vel.fx*DT; c->pos.fy += c->vel.fy*DT; - if(c->pos.fy-PLAYER_R/2 <= ROOM_SIZE*DIST_EDGE && c->vel.fy < 0.0) { // top wall + if(c->pos.fy-PLAYER_R <= ROOM_SIZE*DIST_EDGE && c->vel.fy < 0.0) { // top wall c->vel.fy *= -1.0; c->pos.fy += 2.0*c->vel.fy*DT; c->vel.fy *= RESTITUTION_WALL; } - if(c->pos.fy+PLAYER_R/2 >= ROOM_SIZE*(1.0-DIST_EDGE) && c->vel.fy > 0.0) { // bottom wall + if(c->pos.fy+PLAYER_R >= ROOM_SIZE*(1.0-DIST_EDGE) && c->vel.fy > 0.0) { // bottom wall c->vel.fy *= -1.0; c->pos.fy += 2.0*c->vel.fy*DT; c->vel.fy *= RESTITUTION_WALL; @@ -129,7 +129,7 @@ void move_on_TURN(int nPl, int cenX, int cenY) { double nextDist = distance(next, (ptf){.fx = 1.0*cenX, .fy = 1.0*cenY}); // inner circle - if(prevDist-PLAYER_R/2 > ROOM_SIZE*DIST_EDGE && nextDist-PLAYER_R/2 <= ROOM_SIZE*DIST_EDGE) { + if(prevDist-PLAYER_R > ROOM_SIZE*DIST_EDGE && nextDist-PLAYER_R <= ROOM_SIZE*DIST_EDGE) { ptf to_in = normalize((ptf){ .fx = cenX-prev.fx, .fy = cenY-prev.fy @@ -142,7 +142,7 @@ void move_on_TURN(int nPl, int cenX, int cenY) { } // outer circle - if(prevDist+PLAYER_R/2 < ROOM_SIZE*(1.0-DIST_EDGE) && nextDist+PLAYER_R/2 >= ROOM_SIZE*(1.0-DIST_EDGE)) { + if(prevDist+PLAYER_R < ROOM_SIZE*(1.0-DIST_EDGE) && nextDist+PLAYER_R >= ROOM_SIZE*(1.0-DIST_EDGE)) { ptf to_out = normalize((ptf){ .fx = prev.fx-cenX, .fy = prev.fy-cenY @@ -157,12 +157,12 @@ void move_on_TURN(int nPl, int cenX, int cenY) { void bumpOtherCars(int nPl) { for(int p = 0; p < nPlayers; p++) { - if(p != nPl) { + if(p != nPl && 0==winners[p]) { double sep = distance( get_absolute_coords(p), get_absolute_coords(nPl) ); - if(sep <= PLAYER_R) { + if(sep <= 2*PLAYER_R) { // p_total is multiplied by RESTITUTION_PLAYER ptf director = normalize((ptf){ .fx = players[p].c->pos.fx - players[nPl].c->pos.fx, @@ -254,12 +254,31 @@ bool updateCar(level* lvl, int nPl) { } } +void hasWon(int nPl) { + if(0==winners[nPl]) { + car* c = players[nPl].c; + winners[nPl] = ((c->chx == FINISH_CHY && c->chy == FINISH_CHX)?(1):(0)); + if(winners[nPl]==1 && remainingTurns == -1) { + remainingTurns = 4; + } + } + +} + +void updateWins() { + for(int p = 0; p < nPlayers; p++) { + hasWon(p); + } +} + // return true if at least one car moved bool updateCars(level* lvl) { bool res = false; for(int p = 0; p < nPlayers; p++) { - bool rr = updateCar(lvl, p); - res = res || rr; + if(0==winners[p]) { + bool rr = updateCar(lvl, p); + res = res || rr; + } } return res; } \ No newline at end of file diff --git a/src/collisions.h b/src/collisions.h index 27e217d..1c4badf 100644 --- a/src/collisions.h +++ b/src/collisions.h @@ -2,5 +2,6 @@ #define COLLISIONS_H bool updateCars(level* lvl); +void updateWins(); #endif \ No newline at end of file diff --git a/src/display.c b/src/display.c index 1b7aeba..110b01b 100644 --- a/src/display.c +++ b/src/display.c @@ -517,7 +517,7 @@ void renderPlayers(SDL_Renderer* renderer, int cx, int cy, int range, int rsize) //printf("[%d]", p); int cox = (WIDTH-rsize)/2+rsize*(players[p].c->chx-cy) + (int)((players[p].c->pos.fx*1.0)/ROOM_SIZE*rsize); int coy = (HEIGHT-rsize)/2+rsize*(players[p].c->chy-cx) + (int)((players[p].c->pos.fy*1.0)/ROOM_SIZE*rsize); - SDL_RenderFillCircle(renderer, cox, coy, PLAYER_R, players[p].rgb.red, players[p].rgb.green, players[p].rgb.blue, 255); + SDL_RenderFillCircle(renderer, cox, coy, PLAYER_R*rsize/ROOM_SIZE, players[p].rgb.red, players[p].rgb.green, players[p].rgb.blue, 255); } else { // } @@ -531,7 +531,7 @@ void renderMap(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, in for(int x = -range; x <= range; x++) { for(int y = -range; y <= range; y++) { if((cx+x == START_CHX && cy+y == START_CHY) || (cx+x == FINISH_CHX && cy+y == FINISH_CHY)) { - SDL_RenderDrawCircle(renderer, (WIDTH)/2+rsize*(y), (HEIGHT)/2+rsize*(x), (int)(ROOM_SIZE/2.0 + ROOM_SIZE/3.3), 192, 192, 192, 255); + SDL_RenderDrawCircle(renderer, (WIDTH)/2+rsize*(y), (HEIGHT)/2+rsize*(x), (int)(rsize/3.5), 192, 192, 192, 255); } } } diff --git a/src/main.c b/src/main.c index c950191..37c958d 100644 --- a/src/main.c +++ b/src/main.c @@ -39,11 +39,11 @@ void cameraActions(level* lvl, bool* halt, int* cx, int* cy, int* dezoom, int* s break; case SDLK_d: - *cy = min(lvl->lines-1, *cy+1); + *cy = min(lvl->cols-1, *cy+1); break; case SDLK_s: - *cx = min(lvl->cols-1, *cx+1); + *cx = min(lvl->lines-1, *cx+1); break; case SDLK_p: @@ -75,9 +75,11 @@ void player_turn(int id, char* exec) { void parse_all_players(level* lvl, char** execs) { currentTurn += 1; for(int p = 0; p < nPlayers; p++) { - write_output("output.txt", lvl, p); - usleep(1000000/10); - player_turn(p, execs[p]); + if(0==winners[p]) { + write_output("output.txt", lvl, p); + usleep(1000000/10); + player_turn(p, execs[p]); + } } } @@ -126,6 +128,10 @@ int main(int argc, char** argv) { //stage_file("levels/stage.txt"); level* stage = parse_level(argv[1]); init_all(N_PLAYERS); + printf("\n"); + path* pth = getPath(stage); + printLvl(stage); + printPath(pth); printf("Starting direction : "); if(START_DIR == 0) { @@ -139,9 +145,10 @@ int main(int argc, char** argv) { } else { printf("???\n"); } + printf("From (%d %d) to (%d %d)\n", START_CHX, START_CHY, FINISH_CHX, FINISH_CHY); - int cx = 1; - int cy = 2; + int cx = START_CHX; + int cy = START_CHY; int dezoom = 2; int sizeR = 200; while(!halt) { @@ -155,11 +162,12 @@ int main(int argc, char** argv) { // just selected speeds for(int p = 0; p < N_PLAYERS; p++) { pt proj = project(p, cx, cy, dezoom, sizeR); + double nm = sqrt(proj.ix*1.0*proj.ix + proj.iy*1.0*proj.iy); drawLineWithThicc(rend, 2, proj.ix, - proj.ix+(int)(players[p].c->vel.fx/5.0), + proj.ix+(int)(players[p].c->vel.fx/5.0*(nm+PLAYER_R)/nm), proj.iy, - proj.iy+(int)(players[p].c->vel.fy/5.0), + proj.iy+(int)(players[p].c->vel.fy/5.0*(nm+PLAYER_R)/nm), players[p].rgb.red, players[p].rgb.green, players[p].rgb.blue, 255 ); } @@ -170,10 +178,21 @@ int main(int argc, char** argv) { } else { // no movement placeRectToRenderer(rend, 0, 0, 50, 50, 255, 32, 32, 192); + updateWins(); parse_all_players(stage, execs); + if(remainingTurns >= 0) { + remainingTurns -= 1; + if(remainingTurns == 0) { + halt = true; + } + } elapsed = 0.0; } - draw7SegNumberToRenderer(rend, currentTurn, WIDTH/2, 30, 25, 25, 3, 255, 255, 255, 255, 0, 0); + if(remainingTurns >= 0) { + draw7SegNumberToRenderer(rend, remainingTurns, WIDTH/2, 30, 25, 25, 3, 255, 32, 32, 255, 0, 0); + } else { + draw7SegNumberToRenderer(rend, currentTurn, WIDTH/2, 30, 25, 25, 3, 255, 255, 255, 255, 0, 0); + } updateRenderer(rend); elapsed += DT; usleep((int)(1000000*DT)); @@ -184,6 +203,7 @@ int main(int argc, char** argv) { free_digits(digits); free_digits(letters); free_level(stage); + freePath(pth); for(int k = 0; k < N_PLAYERS; k++) { free(execs[k]); } diff --git a/src/structure.c b/src/structure.c index 989765a..89eb959 100644 --- a/src/structure.c +++ b/src/structure.c @@ -14,7 +14,7 @@ const double START_EDGE = 0.05; const double RESTITUTION_WALL = 0.8; const double RESTITUTION_PLAYER = 0.8; // keep equal to prevouis constant -const int PLAYER_R = 10; +const int PLAYER_R = 5; const int MAX_THETA_SPAWN = 80; // degrees const int BARRIERS = 1; diff --git a/src/structure.h b/src/structure.h index 76cc489..15fb308 100644 --- a/src/structure.h +++ b/src/structure.h @@ -57,6 +57,17 @@ typedef struct carData_t { color rgb; } carData; +// meta +typedef struct next_t {int dx; int dy;} next; + +// path +typedef struct path_t { + int lines; + int cols; + pt start; + next** nxts; +} path; + // ------------------------------------------------------------------------ // extern imgs* digits; // SDL data extern imgs* letters; // SDL data @@ -97,6 +108,9 @@ extern const double EPSILON; extern const double DELTA_V; extern const double DELTA_THETA; +extern int* winners; +extern int remainingTurns; + // -------------------------------------------------------------------------------- // void write_output(char* stream, level* lvl, int nPl);