raynstard #5446(2008/01/24 09:13 GMT) [ C ] Rating1/1=1.00
コンソール専用化と思っていたら エスケープシーケンスってVT100エミュレーション下では ちゃんと機能するんですね。 20へぇ~ Cっぽくポインタを活用してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <assert.h> typedef struct tagCell { int alive; // 今の状態 int life; // 次の状態 struct tagCell *around[9]; // 自分の周囲(自分含む) } CELL; static const char *CELL_CHAR[] = { "□", "■" }; #define HEIGHT (10) #define WIDTH (10) static CELL cells[ HEIGHT ][ WIDTH ]; /* 初期パターン (0:死 /1:生) */ // お題サンプル(池になって終わり) static const int graph_paturn1[ HEIGHT * WIDTH ] = { // 1 2 3 4 5 6 7 8 9 10 /* 1 */ 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, /* 2 */ 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, /* 3 */ 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, /* 4 */ 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, /* 5 */ 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, /* 6 */ 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, /* 7 */ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 9 */ 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, /* 10 */ 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 }; // 基本パターン固定型 static const int graph_paturn2[ HEIGHT * WIDTH ] = { // 1 2 3 4 5 6 7 8 9 10 /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, /* 3 */ 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, /* 4 */ 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, /* 5 */ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, /* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; inline void CLS(void){ printf("\x1b[2J"); } inline void LOCATE(int x, int y){ printf("\x1b[%d;%dH", y, x); } inline void STORE_LOCATE(void){ printf("\x1b[s"); } inline void RESTORE_LOCATE(void){ printf("\x1b[u"); } /* 指定した座標のセル取得 */ inline int getCell(CELL **out, int x, int y) { assert(out != NULL ); /* 座標の正規化 */ y %= HEIGHT; if( y < 0 ){ y = HEIGHT + y; } x %= WIDTH; if( x < 0 ){ x = WIDTH + x; } /* */ *out = &cells[y][x]; assert(*out != NULL ); return 0; } /* 現在の状態から次世代の状態を設定する */ int set_next_life(struct tagCell *cell) { int score; assert(cell != NULL ); score = cell->around[0]->alive + cell->around[1]->alive + cell->around[2]->alive + cell->around[3]->alive + cell->around[5]->alive + cell->around[6]->alive + cell->around[7]->alive + cell->around[8]->alive; switch( score ) { case 2: // 維持 break; case 3: // 誕生 cell->life = 1; break; default: // 死亡 cell->life = 0; break; } return 0; } /* 初期化いろいろ */ int initialize(void) { static const int *graph = graph_paturn1; // 初期配置 struct tagCell *cell; /* スクリーンの初期化 */ CLS(); LOCATE(1,3); /* セルの初期化 */ memset( &cells, 0, sizeof(cells) ); for( int h=0; h < HEIGHT; h ++ ) { for( int w=0; w < WIDTH; w ++ ) { cell = &cells[ h ][ w ]; cell->alive = *graph++; cell->life = cell->alive; /* 周囲セルの設定 */ getCell(&cell->around[0], w-1, h-1); getCell(&cell->around[1], w , h-1); getCell(&cell->around[2], w+1, h-1); getCell(&cell->around[3], w-1, h ); getCell(&cell->around[4], w , h ); //自分自身 getCell(&cell->around[5], w+1, h ); getCell(&cell->around[6], w-1, h+1); getCell(&cell->around[7], w , h+1); getCell(&cell->around[8], w+1, h+1); } } return 0; } /* 現在の状態を表示 */ int print_cells(void) { struct tagCell *cell; for( int h=0; h < HEIGHT; h ++ ) { for( int w=0; w < WIDTH; w ++ ) { cell = &cells[ h ][ w ]; // printf("[%c]", (cell->alive == 1)?'*':' '); printf("%s", CELL_CHAR[ cell->alive ] ); cell->alive = cell->life; // 表示したので次世代の状態を反映する } printf("\n"); } return 0; } /* */ void play(int frame) { struct timespec interval = { .tv_sec = 0, .tv_nsec = 125000000 }; STORE_LOCATE(); for( int t=0; t<=frame || frame==-1; t++ ) { RESTORE_LOCATE(); /* 表示前に次の状態を計算 */ for( int h=0; h < HEIGHT; h ++ ) { for( int w=0; w < WIDTH; w ++ ) { set_next_life( &cells[ h ][ w ] ); } } /* 表示 */ printf("t=%d\n", t); print_cells(); /* ディレイ */ nanosleep(&interval, NULL); } } int main(int argc, char *argv[]) { initialize(); play( (argc>1)?atoi( argv[1] ):-1 ); return 0; }
Rating1/1=1.00-0+
[ reply ]
raynstard
#5446()
[
C
]
Rating1/1=1.00
Rating1/1=1.00-0+
[ reply ]