Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #define CELL_HEALTHY 'o'
- #define CELL_VOID '.'
- #define CELL_SICK '!'
- #define CELL_ALMOST_SICK 'X'
- #define ASK_FOR_FIELD_SIZE_PROMPT "Field size: "
- #define ASK_FOR_FIELD_FILL_PROMPT "Now fill it:\n"
- #define FIELD_MAX_W 100
- #define FIELD_MAX_H 100
- #define RESULT_OK 0
- #define ERROR_FIELD_SIZE_INVALID 1
- #define ERROR_FIELD_INVALID_CELL_VALUE 2
- #define ERROR_FIELD_INVALID_CELL_COUNT 3
- #define epic_fail( r ) { printf("Error: %s\n", error_names[r]); exit(1); }
- #define invalid_cell( cell ) ((cell != CELL_HEALTHY && cell != CELL_VOID && cell != CELL_SICK) ? 1 : 0)
- #define isspace( c ) (c=='\r' || c=='\n' || c==' ')
- #define infect( x, y ) if ( field[y][x] == CELL_HEALTHY ) field[y][x] = CELL_ALMOST_SICK
- static const char * const error_names[] = {
- "RESULT_OK",
- "invalid field size",
- "invalid cell value",
- "invalid cells amount in a row",
- };
- int ask_for_field_size( int *w, int *h );
- int ask_for_field_fill( char **field, int w, int h );
- char **create_field( int w, int h );
- char **clone_field( char **field, int w, int h );
- void do_the_math( char **field, int w, int h, int *days, int *infected_n );
- void debug_field( char **field, int w, int h );
- void plz_no_errors( int r );
- char *trim( char *str );
- int main(void) {
- int field_w, field_h; // размеры поля
- char **field; // поле
- int days, infected_n; // как быстро и сколько заразит
- // вводим размеры поля:
- plz_no_errors(ask_for_field_size(&field_w, &field_h));
- // создаем 2D массив:
- field = create_field(field_w, field_h);
- // заполняем поле:
- plz_no_errors(ask_for_field_fill(field, field_w, field_h));
- debug_field(field, field_w, field_h);
- printf("Now we will count ... ");
- // посчитать сколько заразит и как быстро
- do_the_math(field, field_w, field_h, &days, &infected_n);
- printf("DONE\ninfected: %d, days: %d\n", infected_n, days);
- debug_field(field, field_w, field_h);
- //free_field(field, field_w, field_h);
- }
- char **clone_field( char **field, int w, int h ) {
- int x, y;
- char **clone = (char **)malloc(h * sizeof(char *));
- for ( y=0; y<h; y++ ) {
- clone[y] = (char *)malloc(w * sizeof(char));
- for ( x=0; x<w; ++x ) {
- clone[y][x] = field[y][x];
- }
- }
- return clone;
- }
- void do_the_math( char **field, int w, int h, int *days, int *infected_n ) {
- int x, y;
- int infected_today;
- *days = 0;
- *infected_n = 0;
- //char **clone = clone_field(field, w, h);
- while ( 1 ) {
- infected_today = 0;
- for ( y=0; y<h; y++ ) {
- for ( x=0; x<w; ++x ) {
- if ( field[y][x] == CELL_SICK ) {
- // top (y-1, x)
- if ( y-1 >= 0 ) { // exists
- infect(x, y-1);
- }
- // bottom (y+1, x)
- if ( y+1 < h ) { // exists
- infect(x, y+1);
- }
- // left (y, x-1)
- if ( x-1 >= 0 ) { // exists
- infect(x-1, y);
- }
- // right (y, x+1)
- if ( x+1 < w ) { // exists
- infect(x+1, y);
- }
- }
- }
- }
- // convert CELL_ALMOST_SICK to CELL_SICK and increment infected_n
- for ( y=0; y<h; y++ ) {
- for ( x=0; x<w; ++x ) {
- if ( field[y][x] == CELL_ALMOST_SICK ) {
- field[y][x] = CELL_SICK;
- infected_today++;
- }
- }
- }
- if ( !infected_today ) break;
- *infected_n += infected_today;
- (*days)++;
- }
- //free_field(clone, w, h);
- }
- int ask_for_field_fill( char **field, int w, int h ) {
- printf(ASK_FOR_FIELD_FILL_PROMPT);
- char str[FIELD_MAX_W + 1]; // read buffer
- char *str_trimmed;
- int str_len;
- int x, y;
- // сначала заполняем первый ряд, потом второй и т.п.
- for ( y=0; y<h; y++ ) {
- while ( 1 ) {
- memset(str, 0, FIELD_MAX_W + 1);
- fgets(str, FIELD_MAX_W, stdin);
- str_trimmed = trim(str);
- str_len = strlen(str_trimmed);
- if ( !str_len ) {
- continue; // пропускаем пустые линии
- }
- if ( str_len != w ) {
- return ERROR_FIELD_INVALID_CELL_COUNT; // у нас ячеек больше или меньше, чем ввели буковок
- }
- // наконец-то заполняем
- for ( x=0; x<w; ++x ) {
- if ( invalid_cell(str_trimmed[x]) ) {
- return ERROR_FIELD_INVALID_CELL_VALUE; // какую-то херню ввели
- }
- field[y][x] = str_trimmed[x];
- }
- break;
- }
- }
- return RESULT_OK;
- }
- char **create_field( int w, int h ) {
- int x, y;
- char **field = (char **)malloc(h * sizeof(char *));
- for ( y=0; y<h; y++ ) {
- field[y] = (char *)malloc(w * sizeof(char));
- }
- return field;
- }
- void debug_field( char **field, int w, int h ) {
- int x, y;
- for ( y=0; y<h; y++ ) {
- for ( x=0; x<w; ++x ) {
- printf("%c ", field[y][x]);
- }
- printf("\n");
- }
- }
- int ask_for_field_size( int *w, int *h ) {
- printf(ASK_FOR_FIELD_SIZE_PROMPT);
- *w = 0;
- *h = 0;
- scanf("%d %d", w, h);
- if ( *w < 1 || *w > FIELD_MAX_W || *h < 1 || *h > FIELD_MAX_H ) {
- return ERROR_FIELD_SIZE_INVALID;
- } else {
- return RESULT_OK;
- }
- }
- void plz_no_errors( int r ) {
- if ( r != RESULT_OK ) {
- epic_fail(r);
- }
- }
- char *trim( char *str ) {
- char *end;
- while ( isspace(*str) ) str++;
- if ( *str == 0 ) {
- return str;
- }
- end = str + strlen(str) - 1;
- while ( end > str && isspace(*end) ) {
- end--;
- }
- *(end+1) = 0;
- return str;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement