1 // This file is part of Golly. 2 // See docs/License.html for the copyright notice. 3 4 /** 5 * This class implements the rules supported by QuickLife and HashLife. 6 * A rule lookup table is used for computing a new 2x2 grid from 7 * a provided 4x4 grid (two tables are used to emulate B0-not-Smax rules). 8 * The input is a 16-bit integer, with the most significant bit the 9 * upper left corner, bits going horizontally and then down. The output 10 * is a 6-bit integer, with the top two bits indicating the top row of 11 * the 2x2 output grid and the least significant two bits indicating the 12 * bottom row. The middle two bits are always zero. 13 */ 14 #ifndef LIFERULES_H 15 #define LIFERULES_H 16 #include "lifealgo.h" 17 const int MAXRULESIZE = 500 ; // maximum number of characters in a rule 18 const int ALL3X3 = 512 ; // all possible 3x3 cell combinations 19 const int ALL4X4 = 65536 ; // all possible 4x4 cell combinations 20 const int MAP512LENGTH = 86 ; // number of base64 characters to encode 512bit map for Moore neighborhood 21 const int MAP128LENGTH = 22 ; // number of base64 characters to encode 128bit map for Hex neighborhood 22 const int MAP32LENGTH = 6 ; // number of base64 characters to encode 32bit map for von Neumann neighborhood 23 24 class liferules { 25 public: 26 liferules() ; 27 ~liferules() ; 28 // string returned by setrule is any error 29 const char *setrule(const char *s, lifealgo *algo) ; 30 const char *getrule() ; 31 32 // AKT: we need 2 tables to support B0-not-Smax rule emulation 33 // where max is 8, 6 or 4 depending on the neighborhood 34 char rule0[ALL4X4] ; // rule table for even gens if rule has B0 but not Smax, 35 // or for all gens if rule has no B0, or it has B0 *and* Smax 36 char rule1[ALL4X4] ; // rule table for odd gens if rule has B0 but not Smax 37 bool alternate_rules ; // set by setrule; true if rule has B0 but not Smax 38 39 // AKT: support for various neighborhoods 40 // rowett: support for non-totalistic isotropic rules 41 enum neighborhood_masks { 42 MOORE = 0x1ff, // all 8 neighbors 43 HEXAGONAL = 0x0fe, // ignore NE and SW neighbors 44 VON_NEUMANN = 0x0ba // 4 orthogonal neighbors 45 } ; 46 47 bool isRegularLife() ; // is this B3/S23? isHexagonal()48 bool isHexagonal() const { return neighbormask == HEXAGONAL ; } isVonNeumann()49 bool isVonNeumann() const { return neighbormask == VON_NEUMANN ; } isWolfram()50 bool isWolfram() const { return wolfram >= 0 ; } 51 52 private: 53 char canonrule[MAXRULESIZE] ; // canonical version of valid rule passed into setrule 54 neighborhood_masks neighbormask ; // neighborhood masks in 3x3 table 55 bool totalistic ; // is rule totalistic? 56 bool using_map ; // is rule a map? 57 int neighbors ; // number of neighbors 58 int rulebits ; // bitmask of neighbor counts used (9 birth, 9 survival) 59 int letter_bits[18] ; // bitmask for non-totalistic letters used 60 int negative_bit ; // bit in letters bits mask indicating negative 61 int wolfram ; // >= 0 if Wn rule (n is even and <= 254) 62 int survival_offset ; // bit offset in rulebits for survival 63 int max_letters[18] ; // maximum number of letters per neighbor count 64 const int *order_letters[18] ; // canonical letter order per neighbor count 65 const char *valid_rule_letters ; // all valid letters 66 const char *rule_letters[4] ; // valid rule letters per neighbor count 67 const int *rule_neighborhoods[4] ; // isotropic neighborhoods per neighbor count 68 char rule3x3[ALL3X3] ; // all 3x3 cell mappings 012345678->4' 69 const char *base64_characters ; // base 64 encoding characters 70 71 void initRule() ; 72 void setTotalistic(int value, bool survival) ; 73 int flipBits(int x) ; 74 int rotateBits90Clockwise(int x) ; 75 void setSymmetrical512(int x, int b) ; 76 void setSymmetrical(int value, bool survival, int lindex, int normal) ; 77 void setTotalisticRuleFromString(const char *rule, bool survival) ; 78 void setRuleFromString(const char *rule, bool survival) ; 79 void createWolframMap() ; 80 void createRuleMapFromMAP(const char *base64) ; 81 void createRuleMap(const char *birth, const char *survival) ; 82 void convertTo4x4Map(char *which) ; 83 void saveRule() ; 84 void createCanonicalName(lifealgo *algo, const char *base64) ; 85 void removeChar(char *string, char skip) ; 86 bool lettersValid(const char *part) ; 87 int addLetters(int count, int p) ; 88 } ; 89 #endif 90