Skip to content
This repository has been archived by the owner on Jan 18, 2025. It is now read-only.

Commit

Permalink
faster serial game
Browse files Browse the repository at this point in the history
  • Loading branch information
Palani Johnson committed Dec 8, 2021
1 parent c34a5c1 commit 542c8a0
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 151 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
initial

game
game.ppm
game.ppm
omp_game
87 changes: 87 additions & 0 deletions game.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* File: game.c
*
* This file contains some of my utility functions
* that I use in some of my other files
*
*/
#include "game_of_life.h"


// UTILITY

// Gets the file extension
char *get_filename_ext(char *filename) {
char *dot = strrchr(filename, '.');
if(!dot || dot == filename) {
fprintf(stderr, "Invalid file type. File must be .rle or .cells\n");
exit(EXIT_FAILURE);
};
return dot + 1;
}

// Writes the current buffer of a life struct to ppm format
void ppm_write(struct GameOfLife *life, FILE *f, char *vid_buff) {
fprintf(f, "P6\n%d %d 255\n", life->width, life->height);
fwrite(vid_buff, sizeof(char), life->width * life->height * 3, f);
fflush(f);
}

char * alloc_video_buff(struct GameOfLife *life) {
return malloc(life->width * life->height * sizeof(char) * 3);
}

//

// LIFE FUNCTIONS

// Fills a life struct with useful data
void init_life(struct GameOfLife *life, char *init_type, int width, int height, int op1, int op2) {
life->width = width;
life->height = height;
life->buff_size = (life->width + 2) * (life->height + 2);

life->next_buff = malloc(life->buff_size * sizeof(bool));
life->buff = strcmp(init_type, "random") || strcmp(init_type, "rand")
? alloc_random_buff(life, op1, op2)
: alloc_buff_from_file(life, init_type, op1, op2);
}

// Allocates random data to a life struct buffer
bool *alloc_random_buff(struct GameOfLife *life, int seed, int fill) {
use_game_pos(life);
bool *buff;

if (seed == -1) {
buff = calloc(life->buff_size, sizeof(bool));
for (int i = 0; i < 3; i++)
buff[game_pos(i, 1)] = 1;
} else {
srand(seed);
buff = malloc(life->buff_size * sizeof(bool));
for (int j = 0; j < life->height; j++)
for (int i = 0; i < life->width; i++)
buff[game_pos(i, j)] = (rand() / (double)RAND_MAX)
< (double)fill / 100;
}

return buff;
}

// TODO: Make this function
bool *alloc_buff_from_file(struct GameOfLife *life, char *file, int seed, int fill) {
bool *buff = calloc(life->buff_size, sizeof(bool));
return buff;
}

// Make the next buffer the current buffer in a life struct
void iterate_buff(struct GameOfLife *life) {
bool *temp_buff = life->buff;
life->buff = life->next_buff;
life->next_buff = temp_buff;
}

// Free the buffers in a life struct
void free_buffs(struct GameOfLife *life) {
free(life->buff);
free(life->next_buff);
}
28 changes: 28 additions & 0 deletions game_of_life.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef GAME_OF_LIFE
#define GAME_OF_LIFE

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

struct GameOfLife {
int width;
int height;
int buff_size;
bool *buff;
bool *next_buff;
};

#define use_game_pos(l) int _w2 = l->width+2; int _w3 = l->width+3
#define game_pos(i, j) ((j)*_w2 + _w3 + (i))

void init_life(struct GameOfLife *life, char *init_type, int width, int height, int op1, int op2);
bool *alloc_random_buff(struct GameOfLife *life, int seed, int fill);
bool *alloc_buff_from_file(struct GameOfLife *life, char *file, int seed, int fill);
void ppm_write(struct GameOfLife *life, FILE *f, char *vid_buff);
void iterate_buff(struct GameOfLife *life);
void free_buffs(struct GameOfLife *life);
char * alloc_video_buff(struct GameOfLife *life);
#endif
167 changes: 50 additions & 117 deletions serial_game.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* File: serial_game.c
*
* Compile: gcc -g -Wall -o game serial-game.c
* Compile: gcc -g -Wall -o game game.c serial_game.c
* Run: ./game [random|rand] [board_width] [board_height] [seed] [fill] [iterations]
*
* Examples:
Expand All @@ -13,72 +13,7 @@
* Stream game with pipe into mpv:
* ./game rand 500 500 10 50 600 | mpv --no-correct-pts --fps=10 -
*/
#include "serial_game.h"


int main(int argc, char** argv) {
if (argc != 7) {
// fprintf(
// stderr,
// "usage: %s [input_file] [board_width] [board_height] [start_x] [start_y] [iterations]\n",
// argv[0]
// );
fprintf(
stderr,
"usage: %s [random|rand] [board_width] [board_height] [seed] [fill] [iterations]\n",
argv[0]
);
exit(EXIT_FAILURE);
};

struct GameOfLife life, *life_pointer;

init_life(
&life,
argv[1],
strtol(argv[2], NULL, 10),
strtol(argv[3], NULL, 10),
strtol(argv[4], NULL, 10),
strtol(argv[5], NULL, 10)
);

ppm_write(&life, stdout);
for (int i = 0; i < strtol(argv[6], NULL, 10); i++) {
gen_next_buff(&life);
iterate_buff(&life);
ppm_write(&life, stdout);
}

free_buffs(&life);

return EXIT_SUCCESS;
}

// UTILITY

char *get_filename_ext(char *filename) {
char *dot = strrchr(filename, '.');
if(!dot || dot == filename) {
fprintf(stderr, "Invalid file type. File must be .rle or .cells\n");
exit(EXIT_FAILURE);
};
return dot + 1;
}

// LIFE FUNCTIONS

// Fills a life struct with useful data
void init_life(struct GameOfLife *life, char *init_type, int width, int height, int op1, int op2) {
life->width = width;
life->height = height;
life->buff_size = (life->width + 2) * (life->height + 2);

life->next_buff = malloc(life->buff_size * sizeof(bool));
life->buff = strcmp(init_type, "random") || strcmp(init_type, "rand")
? alloc_random_buff(life, op1, op2)
: alloc_buff_from_file(life, init_type, op1, op2);
make_torus(life);
}
#include "game_of_life.h"

// Copies data into the extra space of a life buffer so that
// it has the topology of a torus
Expand All @@ -105,33 +40,6 @@ void make_torus(struct GameOfLife *life) {
life->buff[bm1 - (life->width + 1)] = life->buff[game_pos(wm1, 0)];
}

// Allocates random data to a life struct buffer
bool *alloc_random_buff(struct GameOfLife *life, int seed, int fill) {
use_game_pos(life);
bool *buff;

if (seed == -1) {
buff = calloc(life->buff_size, sizeof(bool));
for (int i = 0; i < 3; i++)
buff[game_pos(i, 1)] = 1;
} else {
srand(seed);
buff = malloc(life->buff_size * sizeof(bool));
for (int j = 0; j < life->height; j++)
for (int i = 0; i < life->width; i++)
buff[game_pos(i, j)] = (rand() / (double)RAND_MAX)
< (double)fill / 100;
}

return buff;
}

// TODO: Make this function
bool *alloc_buff_from_file(struct GameOfLife *life, char *file, int seed, int fill) {
bool *buff = calloc(life->buff_size, sizeof(bool));
return buff;
}

// Creates the next buffer in a life struct
void gen_next_buff(struct GameOfLife *life) {
use_game_pos(life);
Expand All @@ -150,32 +58,57 @@ void gen_next_buff(struct GameOfLife *life) {
}
}

// Make the next buffer the current buffer in a life struct
void iterate_buff(struct GameOfLife *life) {
bool *temp_buff = life->buff;
life->buff = life->next_buff;
life->next_buff = temp_buff;
void write_video_buffer(struct GameOfLife *life, char *vid_buff) {
use_game_pos(life);

make_torus(life);
}
int i, j, b, c, jh, i3;

// Free the buffers in a life struct
void free_buffs(struct GameOfLife *life) {
free(life->buff);
free(life->next_buff);
for (j = 0; j < life->height; j++) {
jh = j*life->height*3;
for (i = 0; i < life->width; i++) {
i3 = i*3;
b = life->buff[game_pos(i, j)] ? 0 : 255;
for(c = 0; c < 3; c++) vid_buff[i3 + jh + c] = b;
}
}
}

// Writes the current buffer of a life struct to ppm format
void ppm_write(struct GameOfLife *life, FILE *f) {
use_game_pos(life);
int main(int argc, char** argv) {
if (argc != 7) {
fprintf(
stderr,
"usage: %s [random|rand] [board_width] [board_height] [seed] [fill] [iterations]\n",
argv[0]
);
exit(EXIT_FAILURE);
};

fprintf(f, "P6\n%d %d 255\n", life->width, life->height);
for (int j = 0; j < life->height; j++) {
for (int i = 0; i < life->width; i++) {
char b = life->buff[game_pos(i, j)] ? 0 : 255;
fprintf(f, "%c%c%c", b, b, b);
}
struct GameOfLife life_struct, *life;
life = &life_struct;

init_life(
life,
argv[1],
strtol(argv[2], NULL, 10),
strtol(argv[3], NULL, 10),
strtol(argv[4], NULL, 10),
strtol(argv[5], NULL, 10)
);

char *vid_buff = alloc_video_buff(life);

write_video_buffer(life, vid_buff);
ppm_write(life, stdout, vid_buff);

for (int i = 0; i < strtol(argv[6], NULL, 10); i++) {
make_torus(life);
gen_next_buff(life);
iterate_buff(life);
write_video_buffer(life, vid_buff);
ppm_write(life, stdout, vid_buff);
}

fflush(f);
}

free_buffs(life);

return EXIT_SUCCESS;
}
33 changes: 0 additions & 33 deletions serial_game.h

This file was deleted.

0 comments on commit 542c8a0

Please sign in to comment.