200 lines
5.5 KiB
C
200 lines
5.5 KiB
C
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <math.h>
|
|
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_image.h>
|
|
#include "structure.h"
|
|
|
|
const int WIDTH = 1000;
|
|
const int HEIGHT = 1000;
|
|
|
|
const int ROOM_SIZE = 100;
|
|
const int MAX_SPEED = 200; // m/s
|
|
|
|
const double DIST_EDGE = 0.2;
|
|
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 = 5;
|
|
const int MAX_THETA_SPAWN = 80; // degrees
|
|
|
|
const int BARRIERS = 1;
|
|
const double BARRIER_WIDTH = 0.05;
|
|
|
|
const double FRICTION = 0.90;
|
|
const double DV = 2.2; // m/s
|
|
const double DT = 1.0/100.0;
|
|
const double EPSILON = 1.0/4096.0;
|
|
|
|
const double DELTA_V = 7.0; // %
|
|
const double DELTA_THETA = 7.0; // degrees
|
|
|
|
// ------------------------------------------------------------------------------------------ //
|
|
|
|
void write_output(char* stream, level* lvl, int nPl) {
|
|
FILE* ptr = fopen(stream, "w");
|
|
fprintf(ptr, "%d\n",nPlayers);
|
|
for(int p = 0; p < nPlayers; p++) {
|
|
fprintf(ptr, "%d (%d %d) (%.2lf %.2lf)\n", p, players[p].c->chx, players[p].c->chy, players[p].c->pos.fx, players[p].c->pos.fy);
|
|
}
|
|
fprintf(ptr, "[%d]\n\n", nPl);
|
|
fprintf(ptr, "%d %d\n", lvl->lines, lvl->cols);
|
|
for(int l = 0; l < lvl->lines; l++) {
|
|
for(int c = 0; c < lvl->cols; c++) {
|
|
switch (lvl->map[l][c]){
|
|
case NONE:
|
|
fprintf(ptr, ".");
|
|
break;
|
|
|
|
case START:
|
|
fprintf(ptr, "S");
|
|
break;
|
|
|
|
case END:
|
|
fprintf(ptr, "E");
|
|
break;
|
|
|
|
default:
|
|
fprintf(ptr, "%d", (int)lvl->map[l][c]-3);
|
|
break;
|
|
}
|
|
}
|
|
fprintf(ptr, "\n");
|
|
}
|
|
fprintf(ptr, "\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* get_elo_diffs(char** execs) {
|
|
FILE* ptr = fopen("leaderboard.txt", "r");
|
|
int* elos = malloc(sizeof(int)*nPlayers);
|
|
for(int p = 0; p < nPlayers; p++) {
|
|
elos[p] = 500;
|
|
}
|
|
|
|
// ignore first line
|
|
char c = fgetc(ptr);
|
|
while(c != EOF && c != '\n') {
|
|
c = fgetc(ptr);
|
|
}
|
|
|
|
char* name = malloc(sizeof(char)*64);
|
|
int elo;
|
|
int scanres = fscanf(ptr, "%s %d", name, &elo);
|
|
while(scanres > 0) {
|
|
for(int p = 0; p < nPlayers; p++) {
|
|
if(str_equal(name, execs[p])) {
|
|
elos[p] = elo;
|
|
}
|
|
}
|
|
|
|
scanres = fscanf(ptr, "%s %d", name, &elo);
|
|
}
|
|
|
|
fclose(ptr);
|
|
free(name);
|
|
|
|
int* diffs = malloc(sizeof(int)*nPlayers);
|
|
for(int p = 0; p < nPlayers; p++) {
|
|
diffs[p] = 0;
|
|
for(int q = 0; q < nPlayers; q++) {
|
|
if(p != q) {
|
|
diffs[p] += elos[q] - elos[p];
|
|
}
|
|
}
|
|
diffs[p] = diffs[p]/(nPlayers-1+((nPlayers==1)?(1):(0)));
|
|
}
|
|
|
|
free(elos);
|
|
return diffs;
|
|
}
|
|
|
|
int smax(int a, int b) {return (a>b)?(a):(b);}
|
|
int smin(int a, int b) {return (a<b)?(a):(b);}
|
|
double fsmax(double a, double b) {return (a>b)?(a):(b);}
|
|
double fsmin(double a, double b) {return (a<b)?(a):(b);}
|
|
|
|
// +20 for #1 no matter what
|
|
// up to -70 (past 2500) for last
|
|
// if diff < -250, no bonus
|
|
// if diff > 250, 2x bonus
|
|
int gains(int elo, int rank, int diff) {
|
|
return (int)(
|
|
(fsmax(0.1, fsmin(2.0, (diff+250.0)/250.0)))*20-
|
|
(smax(40,smin(90, (90*elo)/3250)))*
|
|
(((rank-1)*1.0)/((nPlayers-1+((nPlayers==1)?(1):(0)))*1.0))
|
|
);
|
|
}
|
|
|
|
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");
|
|
|
|
int* diffs = get_elo_diffs(execs);
|
|
|
|
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], diffs[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], diffs[k]));
|
|
}
|
|
}
|
|
|
|
fclose(tempRead);
|
|
fclose(mainWrite);
|
|
|
|
free(entry);
|
|
free(found);
|
|
free(diffs);
|
|
} |