Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make code more modular #5

Merged
merged 9 commits into from
Feb 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
snake
*.swp
*.o
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ LIBS += $(if $(shell pkg-config --exists ncursesw && echo y),\
$(shell pkg-config --libs ncurses),-lcurses))
CFLAGS = -Wall -std=c99

SRCS = snake.c pipe.c util.c render.c
OBJS = $(SRCS:.c=.o)

all: $(TARGET)

$(TARGET): snake.c
$(CC) -o$@ $(CFLAGS) $< $(LIBS)
$(TARGET): $(OBJS)
$(CC) -o$@ $(CFLAGS) $^ $(LIBS)

.c.o:
$(CC) $(CFLAGS) -o$@ -c $<

clean:
-rm -f $(TARGET)
-rm -f $(TARGET) $(OBJS)

.PHONY: all clean
92 changes: 92 additions & 0 deletions pipe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <stdlib.h>
#include <stdbool.h>
#include "pipe.h"
#include "util.h"

//The states describe the current "velocity" of a pipe. Notice that the allowed
//transitions are given by a change of +/- 1. So, for example, a pipe heading
//left may go up or down but not right.
// Right Down Left Up
const char states[][2] = {{1,0}, {0,1}, {-1,0}, {0,-1}};

//The transition matrices here describe the character that should be output upon
//a transition from] one state (direction) to another. If you wanted, you could
//modify these to include the probability of a transition.
//┓ : U+2513
//┛ : U+251B
//┗ : U+2517
//┏ : U+250F
const char* trans_unicode[] = {
// R D L U
"", "\u2513", "", "\u251B", //R
"\u2517", "", "\u251B", 0 , //D
"", "\u250F", "", "\u2517", //L
"\u250F", "", "\u2513", 0 //D
};
const char* trans_ascii[] = {
// R D L U
"", "+", "", "+", //R
"+", "", "+", 0 , //D
"", "+", "", "+", //L
"+", "", "+", 0 //U
};

const char * transition_char(const char **list, int row, int col){
return list[row * 4 + col];
}

//The characters to represent a travelling (or extending, I suppose) pipe.
const char* unicode_pipe_chars[] = {"\u2501", "\u2503"};
const char* ascii_pipe_chars[] = {"-", "|"};

void init_pipe(struct pipe *pipe, int ncolours, int initial_state,
int width, int height){

if(initial_state < 0)
pipe->state = randrange(0, 4);
else
pipe->state = initial_state;
pipe->colour = randrange(0, ncolours);
pipe->length = 0;
pipe->x = randrange(0, width);
pipe->y = randrange(0, height);
}

void move_pipe(struct pipe *pipe){
pipe->x += states[pipe->state][0];
pipe->y += states[pipe->state][1];
pipe->length++;
}

bool wrap_pipe(struct pipe *pipe, int width, int height){
if(pipe->x < 0 || pipe->x == width
|| pipe->y < 0 || pipe->y == height){
if(pipe->x < 0){ pipe->x += width; }
if(pipe->y < 0){ pipe->y += height; }
if(pipe->x >= width) {pipe->x -= width; }
if(pipe->y >= height) {pipe->y -= height; }
return true;
}
return false;
}

void random_pipe_colour(struct pipe *pipe, int ncolours){
pipe->colour = randrange(0, ncolours);
}

char flip_pipe_state(struct pipe *pipe){
char old_state = pipe->state;
char new_state = pipe->state;
char flip = randbool(0.5) ? -1 : 1;
new_state += flip;
if(new_state < 0) { new_state = 3; }
else if(new_state > 3){ new_state = 0; }
pipe->state = new_state;
pipe->length = 0;
return old_state;
}

bool should_flip_state(struct pipe *p, int min_len, float prob){
return p->length > min_len && randbool(prob);
}

32 changes: 32 additions & 0 deletions pipe.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef PIPE_H_
#define PIPE_H_

//States and transition characters
extern const char states[][2];

//The characters to represent a travelling (or extending, I suppose) pipe.
extern const char* unicode_pipe_chars[];
extern const char* ascii_pipe_chars[];

//Represents a pipe
struct pipe {
unsigned char state;
unsigned short colour;
unsigned short length;
int x, y;
};

void init_pipe(struct pipe *pipe, int ncolours, int initial_state,
int width, int height);
void move_pipe(struct pipe *pipe);
bool wrap_pipe(struct pipe *pipe, int width, int height);
char flip_pipe_state(struct pipe *pipe);
void random_pipe_colour(struct pipe *pipe, int ncolours);
bool should_flip_state(struct pipe *p, int min_len, float prob);
char pipe_char(struct pipe *p, char old_state);

extern const char *trans_ascii[];
extern const char *trans_unicode[];
const char * transition_char(const char **list, int row, int col);

#endif //PIPE_H_
59 changes: 59 additions & 0 deletions render.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#define _POSIX_C_SOURCE 199309L
#include <time.h>
#include <signal.h>
#include <curses.h>
#include "render.h"
#include "pipe.h"

#define NS 1000000000L //1ns

void init_colours(){
//Initialise colour pairs if we can.
if(has_colors()){
start_color();
for(short i=1; i < COLORS; i++){
init_pair(i, i, COLOR_BLACK);
}
}
}

void animate(int fps, anim_function renderer,
volatile sig_atomic_t *interrupted, void *data){
//Store start time
struct timespec start_time;
long delay_ns = NS / fps;


while(!(*interrupted)){
clock_gettime(CLOCK_REALTIME, &start_time);

//Render
(*renderer)(data);

//Get end time
struct timespec end_time;
clock_gettime(CLOCK_REALTIME, &end_time);
//Work out how long that took
long took_ns =
NS * (end_time.tv_sec - start_time.tv_sec)
+ (end_time.tv_nsec - start_time.tv_nsec);
//Sleep for delay_ns - render time
struct timespec sleep_time = {
.tv_sec = (delay_ns - took_ns) / NS,
.tv_nsec = (delay_ns - took_ns) % NS
};
nanosleep(&sleep_time, NULL);
}
}

void render_pipe(struct pipe *p, const char **trans, const char **pipe_chars,
int old_state, int new_state){

move(p->y, p->x);
attron(COLOR_PAIR(p->colour));
if(old_state != new_state)
addstr(transition_char(trans, old_state, new_state));
else
addstr(pipe_chars[old_state % 2]);
attroff(COLOR_PAIR(p->colour));
}
13 changes: 13 additions & 0 deletions render.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef RENDER_H_
#define RENDER_H_
#include "pipe.h"

typedef void (*anim_function)(void *data);

void init_colours();
void animate(int fps, anim_function renderer,
volatile sig_atomic_t *interrupted, void *data);
void render_pipe(struct pipe *p, const char **trans, const char **pipe_chars,
int old_state, int new_state);

#endif //RENDER_H_
Loading