From dcb00be88047faa9edb80fdce3ed5299a008239f Mon Sep 17 00:00:00 2001 From: cancel Date: Sun, 25 Nov 2018 11:56:57 +0900 Subject: [PATCH] Add test basic 'a' function --- base.h | 2 ++ field.c | 21 +++++++++++++++++++++ field.h | 2 ++ sim.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/base.h b/base.h index c8d1a82..7289043 100644 --- a/base.h +++ b/base.h @@ -11,6 +11,8 @@ typedef char Term; typedef uint32_t U32; typedef int32_t I32; +typedef uint64_t U64; +typedef int64_t I64; typedef struct { Term* buffer; diff --git a/field.c b/field.c index cc3bd07..9c497e9 100644 --- a/field.c +++ b/field.c @@ -111,6 +111,16 @@ Term field_peek(Field* f, U32 y, U32 x) { return f->buffer[y * f_width + x]; } +Term field_peek_relative(Field* f, U32 y, U32 x, I32 offs_y, I32 offs_x) { + I64 f_height = f->height; + I64 f_width = f->width; + I64 y0 = (I64)y + (I64)offs_y; + I64 x0 = (I64)x + (I64)offs_x; + if (y0 >= f_height || x0 >= f_width || y0 < 0 || x0 < 0) + return '.'; + return f->buffer[y0 * f_width + x0]; +} + void field_poke(Field* f, U32 y, U32 x, Term term) { size_t f_height = f->height; size_t f_width = f->width; @@ -120,6 +130,17 @@ void field_poke(Field* f, U32 y, U32 x, Term term) { f->buffer[y * f_width + x] = term; } +void field_poke_relative(Field* f, U32 y, U32 x, I32 offs_y, I32 offs_x, + Term term) { + I64 f_height = f->height; + I64 f_width = f->width; + I64 y0 = (I64)y + (I64)offs_y; + I64 x0 = (I64)x + (I64)offs_x; + if (y0 >= f_height || x0 >= f_width || y0 < 0 || x0 < 0) + return; + f->buffer[y0 * f_width + x0] = term; +} + inline bool term_char_is_valid(char c) { return c >= '#' && c <= '~'; } diff --git a/field.h b/field.h index 7648816..3c8900a 100644 --- a/field.h +++ b/field.h @@ -10,7 +10,9 @@ void field_copy_subrect(Field* src, Field* dest, U32 src_y, U32 src_x, void field_fill_subrect(Field* f, U32 y, U32 x, U32 height, U32 width, Term fill_char); Term field_peek(Field* f, U32 y, U32 x); +Term field_peek_relative(Field* f, U32 y, U32 x, I32 offs_y, I32 offs_x); void field_poke(Field* f, U32 y, U32 x, Term term); +void field_poke_relative(Field* f, U32 y, U32 x, I32 offs_y, I32 offs_x, Term term); void field_fput(Field* f, FILE* stream); diff --git a/sim.c b/sim.c index 23f676b..52a4638 100644 --- a/sim.c +++ b/sim.c @@ -1,6 +1,56 @@ #include "field.h" #include "sim.h" +static Term const indexed_terms[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '.', '*', ':', ';', '#', +}; + +enum { Terms_array_num = sizeof indexed_terms }; + +static inline size_t index_of_term(Term c) { + for (size_t i = 0; i < Terms_array_num; ++i) { + if (indexed_terms[i] == c) + return i; + } + return SIZE_MAX; +} + +static inline Term term_lowered(Term c) { + return (c >= 'A' && c <= 'Z') ? c - ('a' - 'A') : c; +} + +static inline Term terms_sum(Term a, Term b) { + size_t ia = index_of_term(term_lowered(a)); + size_t ib = index_of_term(term_lowered(b)); + if (ia == SIZE_MAX) ia = 0; + if (ib == SIZE_MAX) ib = 0; + return indexed_terms[(ia + ib) % Terms_array_num]; +} + +static inline void act_a(Field* f, U32 y, U32 x) { + Term inp0 = field_peek_relative(f, y, x, 0, 1); + Term inp1 = field_peek_relative(f, y, x, 0, 2); + if (inp0 != '.' && inp1 != '.') { + Term t = terms_sum(inp0, inp1); + field_poke_relative(f, y, x, 1, 0, t); + } +} + void orca_run(Field* f) { - (void)f; + size_t ny = f->height; + size_t nx = f->width; + Term* f_buffer = f->buffer; + for (size_t iy = 0; iy < ny; ++iy) { + Term* row = f_buffer + iy * nx; + for (size_t ix = 0; ix < nx; ++ix) { + Term c = row[ix]; + switch (c) { + case 'a': + act_a(f, iy, ix); + break; + } + } + } }