/* ----------------------------------------------------------------------- * * Life: A game program that emulates the growth of cells in a petri dish * * Author: Suzi Anvin * * Rules: Cells die if lonely or overcrowded. They only live if the 8 * surrounding squares have 2 or 3 other cells. Cells can be created * in any empty square that is adjacent to 3 other cells. * * Operation: (Versions 0.X) Non-operational development stages. * Version 0.2: Inputs up to 20 lines of the array with all features * of version 0.1, and reprints array in binary and in the display * version. If an error message is recieved during input, the error * is printed below the last entered string, and the cursor moves up * to type over this string. If a user enters nothing on any line, * that line and all subsequent lines are set to empty squares. * An error message is returned if this occurs on the first line. * * Goal: (Versions 1.X) User enters a string of text on several lines, * representing cells as 'x' and empty spaces as '.' This is * converted into an array of bits. "Life" then runs step by step * through the lifecycle of the cells, re-drawing the display each * time the user presses enter. The display quits when the user * types 'Q' and then asks the user if they want to play again. * If the user's answer begins with 'Y' the program restarts. * Otherwise, it quits. * ----------------------------------------------------------------------- */ #include #include inline void set_bit (uint8_t array[], unsigned int bit) { array[bit/8] |= 1<<(bit%8); } inline void clr_bit (uint8_t array[], unsigned int bit) { array[bit/8] &= ~(1<<(bit%8)); } /* test_bit returns 1 if the bit is 1 and 0 if the bit is 0. */ inline int test_bit (const uint8_t array[], unsigned int bit) { return (array[bit/8]>>(bit%8)) & 1; } /* set_bmp_line takes a text line of x's and .'s. It assigns them to * one line of a bitmap array with x = 1 and . = 0 * * When passing the array to set_bmp_line, be sure to specify the line * number [in brackets]. * * set_bmp_line returns 0 if all bits are correctly assigned and 1 if * it does not recognize a character from the text line. */ int set_bmp_line (uint8_t array[], char line[]) { int i; /* counter */ clr_bit (array, 0); for (i=1; i <= 62; i++) { switch (line[i-1]) { case 'x': set_bit (array, i); break; case '.': clr_bit (array, i); break; default: return (1); } } clr_bit (array, 63); return (0); } /* draw_bmp_line is a preliminary function to draw one line of the bitmap * seperately. Each line of the array is passed individually, and bits 1-38 * are drawn on the screen, with 1 = 'x' and 0 = '.'. the comand call needs to * specify the current line # [in brackets] to use the function. * * I'm told I'm "already using pointers" to pass in the 1 * dimensional array. That's fine, I'll wait til I have a better clue before * passing in both dimensions. In version 1.1 or so this function should * be updated to draw the whole bitmap. */ void draw_bmp_line (uint8_t array[]) { int i; /* counter(s) */ putchar(' '); for (i=1; i<= 62; i++) { if (test_bit(array, i)) putchar('x'); else putchar('.'); } putchar('\n'); } /* debug_bits prints out the bits as the appear in the array. This tests that * they have been encoded correctly. */ void debug_bits (uint8_t array[]) { int i; for (i=0; i < 64; i++) { printf("%d", test_bit(array, i)); } putchar('\n'); } /* set up bitmap array as [line #] [byte # in that line] */ /* temporary main function to test the set_bmp_line and draw_bmp_line * functions with the full 64x22 array */ int main() { char line[100]; uint8_t bitmap[22][8]; /* one dimensional bitmap array */ int i, j; /* counter(s) */ while (1) { /* loop for debugging */ printf("\n\nWelcome to the game of Life, development version 0.2.\n" "Please enter your cells one line at a time, with 62\n" "characters per line as indicated by the line of ---'s.\n" "You may enter as many as 20 lines, or as few as 1 line.\n" "After first line, enter only [return] to stop entering lines.\n" "Use x to indicate a cell and a period to " "indicate an empty space.\n" " --------------------------------------------------------------\n"); /* Initializing the bits in the bitmap. Lines [0] and [21] are set to * all 0's. Lines [1-20] take user input and are initialized with * set_bmp_line, or, if left blank, are set to all 0's. */ for (j=0; j < 8; j++) { /* initializing 0th line to 0 */ bitmap [0][j] = 0; } while (1){ /* first line special - cannot be blank */ printf("First line: "); fgets(line, sizeof(line), stdin); if (set_bmp_line(bitmap[1], line) == 1) { printf("Error: re-enter last line using only x and . Please fill row." "\x1b[1A\x1b[1G"); continue; } else break; } for (i=2; i<=20; i++) { /* initializing lines 2-20 with user input */ printf(" Next line: "); fgets(line, sizeof(line), stdin); if (line[0] == '\n') break; if (set_bmp_line(bitmap[i], line) == 1) { printf("Error: re-enter last line using only x and . Please fill row." "\x1b[1A\x1b[1G"); --i; continue; } } for (; i < 22; i++) { for (j=0; j < 8; j++) { /* initializing remaining lines to 0 */ bitmap [i][j] = 0; } } for (i = 0; i < 22; i++) { /* print out the actual bits encoded */ debug_bits(bitmap[i]); } for (i=1; i<=20; i++) { /* print out array as user sees it */ draw_bmp_line(bitmap[i]); } printf("try again? (y/n)"); fgets(line, sizeof(line), stdin); if (line[0] == 'n') break; } return (0); }