BomberMan/graphing.c

329 lines
8.3 KiB
C

#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
int width = 800 ;
int height = 500 ;
int offset = 25 ;
int wside = 15 ;
int map_size = 64 ;
int min(int x, int y) {
if(x < y) {
return x;
}
return y ;
}
int max(int x, int y) {
if(x > y) {
return x;
}
return y ;
}
int int_of_string(char* s) {
int i = 0;
int res = 0 ;
while(s[i] != '\0' && (int)(s[i]) >= 48 && (int)(s[i]) <= 57) {
res = res*10 + (int)(s[i]) - 48 ;
i += 1;
}
return res ;
}
int truncated_float_of_string(char* s) {
int i = 0;
int res = 0 ;
while(s[i] != '\0' && s[i] != '.') {
res = res*10 + (int)(s[i]) - 48 ;
i += 1;
}
return res ;
}
char* input_line(FILE* ptr) {
char* res = malloc(sizeof(char)*256) ;
int i = 0 ;
char c = fgetc(ptr) ;
while(c != EOF && c != '\n') {
res[i] = c;
i += 1;
c = fgetc(ptr) ;
}
res[i] = '\0' ;
return res;
}
void flush_line(FILE* ptr) {
char c = fgetc(ptr) ;
while(c != EOF && c != '\n') {
c = fgetc(ptr);
}
}
int input_int(FILE* ptr) {
int res = 0 ;
char c = '0' ;
while(c != EOF && (int)c >= 48 && (int)c <= 57) {
res = 10*res + (int)c - 48 ;
c = fgetc(ptr);
}
return res ;
}
void updateRenderer(SDL_Renderer* renderer) {
SDL_RenderPresent(renderer);
}
void setRendererColor(SDL_Renderer* renderer, int r, int g, int b, int a) {
SDL_SetRenderDrawColor(renderer, r, g, b, a);
}
void resetRenderer(SDL_Renderer* renderer) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
}
void refreshRenderer(SDL_Renderer* renderer) {
resetRenderer(renderer);
updateRenderer(renderer);
}
void drawRectToRenderer(SDL_Renderer* renderer, SDL_Rect* rect, int R, int G, int B, int A) {
SDL_SetRenderDrawColor(renderer, R, G, B, A);
SDL_RenderFillRect(renderer, rect);
}
void placeRectToRenderer(SDL_Renderer* renderer, int X, int Y, int W, int H, int R, int G, int B, int A) {
SDL_Rect rect;
rect.x = X;
rect.y = Y;
rect.w = W;
rect.h = H;
SDL_SetRenderDrawColor(renderer, R, G, B, A);
SDL_RenderFillRect(renderer, &rect);
}
void placeRectToRendererNoColor(SDL_Renderer* renderer, int X, int Y, int W, int H) {
SDL_Rect rect;
rect.x = X;
rect.y = Y;
rect.w = W;
rect.h = H;
SDL_RenderFillRect(renderer, &rect);
}
void drawCircleToRenderer(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius) {
const int32_t diameter = (radius * 2);
int32_t x = (radius - 1);
int32_t y = 0;
int32_t tx = 1;
int32_t ty = 1;
int32_t error = (tx - diameter);
while (x >= y)
{
// each of the following renders an octant of the circle
SDL_RenderDrawPoint(renderer, centreX + x, centreY - y);
SDL_RenderDrawPoint(renderer, centreX + x, centreY + y);
SDL_RenderDrawPoint(renderer, centreX - x, centreY - y);
SDL_RenderDrawPoint(renderer, centreX - x, centreY + y);
SDL_RenderDrawPoint(renderer, centreX + y, centreY - x);
SDL_RenderDrawPoint(renderer, centreX + y, centreY + x);
SDL_RenderDrawPoint(renderer, centreX - y, centreY - x);
SDL_RenderDrawPoint(renderer, centreX - y, centreY + x);
if (error <= 0)
{
++y;
error += ty;
ty += 2;
}
if (error > 0)
{
--x;
tx += 2;
error += (tx - diameter);
}
}
}
int get_data(char* filename, int** board, bool* ended) {
// if board has been modified //
FILE* ptr = fopen(filename, "r") ;
int cur_t = input_int(ptr) ;
char ignored = '0' ;
flush_line(ptr);
flush_line(ptr);
int maze_w = input_int(ptr) ;
int maze_h = input_int(ptr) ;
board[cur_t%map_size][0] = 0 ;
board[cur_t%map_size][1] = 0 ;
board[cur_t%map_size][2] = 0 ;
board[cur_t%map_size][3] = 0 ;
for(int w = 0; w < maze_w; w++) {
for(int h = 0; h < maze_h; h++) {
int tile = input_int(ptr) ;
//fprintf(stderr, "%d ", tile) ;
if(tile >= 3) {
board[cur_t%map_size][tile-3] += 1;
}
}
ignored = fgetc(ptr); // \n
//fprintf(stderr, "\n") ;
}
int nbombs = input_int(ptr) ;
for(int k = 0; k < nbombs; k++) {
flush_line(ptr);
}
int nplayers = input_int(ptr) ;
if(nplayers == 1) {
*ended = true ;
}
fprintf(stderr, "(%d, %d, %d, %d, %d)\n", cur_t, maze_w, maze_h, nbombs, nplayers);
fclose(ptr) ;
return cur_t ;
}
int convex_pt(int a, int b, float theta) {
return (a + (int)((b - a) * theta)) ;
}
void playerActions() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_t:
exit(1);
break;
}
}
}
}
void update_graph(SDL_Renderer* renderer, int** board, int current_time) {
resetRenderer(renderer) ;
placeRectToRenderer(renderer, offset, offset, width - 2*offset, height - 2*offset, 128, 128, 128, 255) ;
placeRectToRenderer(renderer, offset + wside, offset + wside, width - 2*(offset + wside), height - 2*(offset + wside), 255, 255, 255, 255) ;
playerActions();
int max_val = 0 ;
for(int k = 0; k < map_size; k++) {
for(int l = 0; l < 4; l++) {
max_val = max(max_val, board[k][l]) ;
}
}
int left_x = offset + wside ;
int bot_y = offset + wside ;
int right_x = width - 2*(offset + wside) ;
int top_y = height - 2*(offset + wside) ;
int borned = min(map_size, current_time) ;
int x_size = 1+(right_x - left_x)/borned ;
int y_size = 1+(top_y - bot_y)/(1+max_val) ;
for(int t0 = 0; t0 < borned; t0++) {
for(int pl = 0; pl < 4; pl++) {
int t = (t0 + max(0, current_time - map_size +1))%map_size ;
//int t = t0 ;
int xc = convex_pt(left_x, right_x, ((float)(t0))/((float)(borned))) ;
int yc = convex_pt(bot_y, top_y, 1.0f - ((float)(max(0, board[t][pl])))/((float)(max_val+1))) ;
//drawCircleToRenderer(renderer, xc, yc, 10) ;
placeRectToRenderer(renderer, xc, yc-y_size+offset+wside, x_size, y_size, 255*(pl==0||pl==3), 255*(pl>=2), 255*(pl==1), 96) ;
}
}
updateRenderer(renderer) ;
}
bool can_pass() {
FILE* ptr = fopen("signal.txt", "r") ;
bool cp = false ;
if(fgetc(ptr) == '1') {
FILE* pptr = fopen("signal.txt", "w") ;
fprintf(pptr, "0") ;
fclose(pptr);
cp = true ;
}
fclose(ptr) ;
return cp ;
}
int main(int argc, char** argv) {
fprintf(stderr, "|||||||||||||||| ENTER ||||||||||||||||\n") ;
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
fprintf(stderr, "error initializing SDL: %s\n", SDL_GetError());
}
SDL_Window* win = SDL_CreateWindow("statistics because why not :)", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0);
Uint32 render_flags = SDL_RENDERER_ACCELERATED;
SDL_Renderer* rend = SDL_CreateRenderer(win, -1, render_flags);
SDL_SetRenderDrawBlendMode(rend, SDL_BLENDMODE_BLEND);
int** board = malloc(sizeof(int*)*map_size) ;
for(int k = 0; k < 128; k++) {
board[k] = malloc(sizeof(int)*4);
for(int l = 0; l < 4; l++) {
board[k][l] = (-1) ;
}
}
bool game_ended = false ;
int last_time = (-1) ;
usleep(250000);
//int cur_time = get_data("entrees.txt", board, &game_ended) ;
//assert(false);
while(!game_ended) {
while(!can_pass()) {
}
int cur_time = get_data("entrees.txt", board, &game_ended) ;
//fprintf(stderr, "%d %d %d\n", last_time, cur_time, game_ended) ;
if(cur_time != last_time) {
update_graph(rend, board, cur_time) ;
last_time = cur_time ;
}
}
fprintf(stderr, "|||||||||||||||| QUIT ||||||||||||||||\n") ;
for(int k = 0; k < 128; k++) {
free(board[k]);
}
free(board);
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}