diff --git a/answer.txt b/answer.txt index ddb2ade..5c406b3 100644 --- a/answer.txt +++ b/answer.txt @@ -1 +1 @@ -265 80 \ No newline at end of file +155 80 \ No newline at end of file diff --git a/bin/back b/bin/back index 9a71ad9..5baf2ce 100755 Binary files a/bin/back and b/bin/back differ diff --git a/leaderboard.txt b/leaderboard.txt new file mode 100644 index 0000000..5dd5ff8 --- /dev/null +++ b/leaderboard.txt @@ -0,0 +1,5 @@ +name, elo +./bots/dumb 2154 +./bots/dumb 1000 +./bots/dumb 1500 +./bots/dumb 501 diff --git a/obj/base.o b/obj/base.o index 8bae35a..a7b37aa 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/collisions.o b/obj/collisions.o index 1335957..edf7bbe 100644 Binary files a/obj/collisions.o and b/obj/collisions.o differ diff --git a/obj/main.o b/obj/main.o index aa74258..7025d55 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/obj/structure.o b/obj/structure.o index 4f5069c..8d3e3c9 100644 Binary files a/obj/structure.o and b/obj/structure.o differ diff --git a/output.txt b/output.txt index 8bbca05..bacaecb 100644 --- a/output.txt +++ b/output.txt @@ -1,28 +1,13 @@ 4 -0 (4 0) (44.83 67.29) -1 (2 0) (11.26 93.67) -2 (1 3) (95.26 50.45) -3 (1 3) (72.77 32.85) -[1] +0 (2 0) (32.28 87.09) +1 (2 0) (83.34 49.89) +2 (2 0) (81.67 74.71) +3 (1 0) (79.36 63.40) +[3] -5 5 -..S14 -....0 -...35 -.E15. -..... +1 3 +S1E -100 -200 -5 -0.90 -0.80 -0.20 +100 200 5 0.90 0.80 0.20 - -Room Size -Maximum speed -Player Radius -Friction -Restitution factor -Track Distance to Edge +Room Size, Maximum speed, Player Radius, Friction, Restitution factor, Track Distance to Edge, \ No newline at end of file diff --git a/src/base.c b/src/base.c index e11d73f..3c9e350 100644 --- a/src/base.c +++ b/src/base.c @@ -17,6 +17,7 @@ int* winners; int remainingTurns; +int nextRank; int currentTurn; int nPlayers; @@ -48,6 +49,7 @@ color assignColor() { void init_all(int nPl) { nPlayers = nPl; + nextRank = 1; RED = 255*(rand()%2); GREEN = 255*(rand()%2); BLUE = 255*(rand()%2); diff --git a/src/collisions.c b/src/collisions.c index 1a7b0c3..a7c4819 100644 --- a/src/collisions.c +++ b/src/collisions.c @@ -47,8 +47,8 @@ ptf get_absolute_coords(int nPl) { // -------------------------------------------------------------------------------- // // make the player move DT (does not take friction into consideration) -// start and finish -void move_on_ENDS(int nPl) { +// start +void move_on_START(int nPl) { car* c = players[nPl].c; c->pos.fx += c->vel.fx*DT; c->pos.fy += c->vel.fy*DT; @@ -86,6 +86,41 @@ void move_on_ENDS(int nPl) { } } +// finish +void move_on_FINISH(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 <= 0.0 && 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 >= 1.0*ROOM_SIZE && 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; + } + if( + (c->pos.fy-PLAYER_R <= 0.0 && 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 >= 1.0*ROOM_SIZE && 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; + } +} + void move_on_STR_V(int nPl) { car* c = players[nPl].c; c->pos.fx += c->vel.fx*DT; @@ -197,8 +232,14 @@ bool updateCar(level* lvl, int nPl) { return false; case START: + move_on_START(nPl); + bumpOtherCars(nPl); + apply_friction(nPl); + updateChunk(nPl); + return true; + case END: - move_on_ENDS(nPl); + move_on_FINISH(nPl); bumpOtherCars(nPl); apply_friction(nPl); updateChunk(nPl); @@ -254,10 +295,14 @@ bool updateCar(level* lvl, int nPl) { } } -void hasWon(int nPl) { +void hasWon(int nPl, int* ranks, int* incr) { 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 && ranks[nPl] == nPlayers) { + ranks[nPl] = nextRank; + *incr += 1; + } if(winners[nPl]==1 && remainingTurns == -1) { remainingTurns = 4; } @@ -265,10 +310,12 @@ void hasWon(int nPl) { } -void updateWins() { +void updateWins(int* ranks) { + int incr = 0; for(int p = 0; p < nPlayers; p++) { - hasWon(p); + hasWon(p, ranks, &incr); } + nextRank += incr; } // return true if at least one car moved diff --git a/src/collisions.h b/src/collisions.h index 1c4badf..27d4baa 100644 --- a/src/collisions.h +++ b/src/collisions.h @@ -2,6 +2,6 @@ #define COLLISIONS_H bool updateCars(level* lvl); -void updateWins(); +void updateWins(int* ranks); #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index c7cddd5..18ae0c9 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,7 @@ #include "cars.h" bool WAIT = true; +bool matchDone = false; void cameraActions(level* lvl, bool* halt, int* cx, int* cy, int* dezoom, int* sizeR) { SDL_Event event; @@ -100,7 +101,9 @@ int main(int argc, char** argv) { int N_PLAYERS = argc-2; char** execs = malloc(sizeof(char*)*N_PLAYERS); + int* ranks = malloc(sizeof(int)*N_PLAYERS); for(int k = 0; k < N_PLAYERS; k++) { + ranks[k] = N_PLAYERS; execs[k] = malloc(sizeof(char)*64); execs[k][0] = '.'; execs[k][1] = '/'; @@ -160,6 +163,8 @@ int main(int argc, char** argv) { int cy = START_CHY; int dezoom = 2; int sizeR = 200; + + int count = 0; while(!halt) { resetRenderer(rend); renderMap(rend, stage, pth, cx, cy, dezoom, sizeR); @@ -187,11 +192,12 @@ int main(int argc, char** argv) { } else { // no movement placeRectToRenderer(rend, 0, HEIGHT-50, 50, 50, 255, 32, 32, 192); - updateWins(); + updateWins(ranks); if(remainingTurns != 0)parse_all_players(stage, execs); if(remainingTurns > 0) { remainingTurns -= 1; if(remainingTurns == 0) { + matchDone = true; //halt = true; } } @@ -204,10 +210,12 @@ int main(int argc, char** argv) { } updateRenderer(rend); elapsed += DT; - if(WAIT)usleep((int)(1000000*(DT/4))); + if(WAIT && count%3==0)usleep((int)(1000000*DT)); cameraActions(stage, &halt, &cx, &cy, &dezoom, &sizeR); + count += 1; } + if(matchDone)updateLeaderBoard(execs, ranks); // ---------------------------- // free_digits(digits); free_digits(letters); @@ -218,6 +226,8 @@ int main(int argc, char** argv) { } free(execs); + free(ranks); + SDL_DestroyRenderer(rend); SDL_DestroyWindow(win); SDL_Quit(); diff --git a/src/structure.c b/src/structure.c index a763d62..02b83f1 100644 --- a/src/structure.c +++ b/src/structure.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include "structure.h" @@ -61,12 +63,80 @@ void write_output(char* stream, level* lvl, int nPl) { fprintf(ptr, "\n"); } fprintf(ptr, "\n"); - fprintf(ptr, "%d\n", ROOM_SIZE); - fprintf(ptr, "%d\n", MAX_SPEED); - fprintf(ptr, "%d\n", PLAYER_R); - fprintf(ptr, "%.2lf\n", FRICTION); - fprintf(ptr, "%.2lf\n", RESTITUTION_WALL); - fprintf(ptr, "%.2lf\n", DIST_EDGE); - fprintf(ptr, "\n\nRoom Size\nMaximum speed\nPlayer Radius\nFriction\nRestitution factor\nTrack Distance to Edge\n"); + fprintf(ptr, "%d %d %d %.2lf %.2lf %.2lf\n", ROOM_SIZE, MAX_SPEED, PLAYER_R, FRICTION, RESTITUTION_WALL, DIST_EDGE); + fprintf(ptr, "\nRoom Size, Maximum speed, Player Radius, Friction, Restitution factor, Track Distance to Edge, "); fclose(ptr); +} + +// ------------------------- // + +bool str_equal(char* s1, char* s2) { + if(s1[0] == '\0' || s2[0] == '\0') { + return (s1[0] == '\0' && s2[0] == '\0'); + } else if(s1[0] != s2[0]) { + return false; + } + return str_equal(&s1[1], &s2[1]); +} + +int gains(int elo, int rank) { + return (int)( + 60*exp(-elo*((rank-1.0)/(nPlayers-1.0))/1200.0)-34 + ); +} + +void updateLeaderBoard(char** execs, int* ranks) { + FILE* ptr = fopen("leaderboard.txt", "r"); + FILE* ptrOut = fopen("tempLeader.txt", "w"); + + // ignore first line + char c = fgetc(ptr); + while(c != EOF && c != '\n') { + fprintf(ptrOut, "%c", c); + c = fgetc(ptr); + } + fprintf(ptrOut, "\n"); + + bool* found = malloc(sizeof(bool)*nPlayers); + char* entry = malloc(sizeof(char)*64); + int elo; + int res = fscanf(ptr, "%s %d", entry, &elo); + while(res > 0) { + for(int p = 0; p < nPlayers; p++) { + if(!found[p] && str_equal(execs[p], entry)) { + found[p] = true; + printf("[%s - rank %d/%d] : %d -", execs[p], ranks[p], nPlayers, elo); + int de = gains(elo, ranks[p]); + printf("(%d)-> ", de); + elo += de; + printf("%d\n", elo); + } + } + + fprintf(ptrOut, "%s %d\n", entry, elo); + res = fscanf(ptr, "%s %d\n", entry, &elo); + } + fclose(ptr); + fclose(ptrOut); + + // copy data to main file + FILE* tempRead = fopen("tempLeader.txt", "r"); + FILE* mainWrite = fopen("leaderboard.txt", "w"); + + c = fgetc(tempRead); + while(c != EOF) { + fprintf(mainWrite, "%c", c); + c = fgetc(tempRead); + } + for(int k = 0; k < nPlayers; k++) { + if(!found[k]) { + fprintf(mainWrite, "%s %d\n", execs[k], 500+gains(500, ranks[k])); + } + } + + fclose(tempRead); + fclose(mainWrite); + + free(entry); + free(found); } \ No newline at end of file diff --git a/src/structure.h b/src/structure.h index 6ad0bf3..e99e9de 100644 --- a/src/structure.h +++ b/src/structure.h @@ -112,10 +112,12 @@ extern const double DELTA_V; extern const double DELTA_THETA; extern int* winners; +extern int nextRank; extern int remainingTurns; // -------------------------------------------------------------------------------- // void write_output(char* stream, level* lvl, int nPl); +void updateLeaderBoard(char** execs, int* ranks); #endif \ No newline at end of file diff --git a/tempLeader.txt b/tempLeader.txt new file mode 100644 index 0000000..5dd5ff8 --- /dev/null +++ b/tempLeader.txt @@ -0,0 +1,5 @@ +name, elo +./bots/dumb 2154 +./bots/dumb 1000 +./bots/dumb 1500 +./bots/dumb 501