回答編集履歴

1

コード修正

2023/03/19 09:43

投稿

jimbe
jimbe

スコア12492

test CHANGED
@@ -6,62 +6,89 @@
6
6
  #include <stdlib.h>
7
7
  #include <string.h>
8
8
 
9
- int board[8][8]; //1=黒,2=白,0以下=フラグ群(あるターンにおいて8方向それぞれにひっくり返せる石があるか)
10
- #define inboard(y,x) (0<=y && y<8 && 0<=x && x<8)
9
+ #define SIZE 8
11
- char *images[] = { "-","●","○","*"};
12
10
 
11
+ #define BLACK 1
12
+ #define WHITE 2
13
+ #define nextTurn(turn) ((turn) ^ 3)
14
+ #define toString(turn) ((turn)==BLACK ? "黒" : "白")
15
+
16
+ int board[SIZE][SIZE]; //1以上=BLACK/WHITE, 0以下=フラグ群(ビットフィールド:あるターンにおいて8方向それぞれにひっくり返せる石があるか)
17
+ #define inboard(y,x) (0<=(y) && (y)<SIZE && 0<=(x) && (x)<SIZE)
18
+ #define isPlaced(square) ((square) > 0)
19
+ #define canPlace(square) ((square) < 0)
20
+
21
+ char *images[] = { "-","●","○","*" };
22
+ #define toImage(square) (images[(square)<0 ? 3 : (square)])
23
+
24
+ //8方向変化値
13
25
  typedef struct {
14
26
  int y, x;
15
27
  } Delta;
16
- //8方向変化値
17
28
  Delta d[] = {
18
- {-1,-1},{-1,0},{-1,1},
29
+ {-1,-1},{-1,0},{-1,1},
19
- { 0,-1}, { 0,1},
30
+ { 0,-1}, { 0,1},
20
- { 1,-1},{ 1,0},{ 1,1}
31
+ { 1,-1},{ 1,0},{ 1,1}
21
32
  };
22
33
  int dlen = sizeof(d)/sizeof(d[0]);
23
34
 
24
- void init(){
35
+ void init() {
25
36
  memset(board, 0, sizeof(board));
26
- board[3][4] = 1;
37
+ board[SIZE/2-1][SIZE/2] = BLACK;
27
- board[4][3] = 1;
38
+ board[SIZE/2] [SIZE/2-1] = BLACK;
28
- board[3][3] = 2;
39
+ board[SIZE/2-1][SIZE/2-1] = WHITE;
29
- board[4][4] = 2;
40
+ board[SIZE/2] [SIZE/2] = WHITE;
30
41
  }
42
+
43
+ int checkLines(int y, int x, int turn) {
44
+ int flags = 0; //下位8ビットが8方向に対応
45
+ for(int i=0; i<dlen; i++) {
46
+ for(int sx=x+d[i].x, sy=y+d[i].y, c=0; inboard(sy,sx) && isPlaced(board[sy][sx]); sx+=d[i].x, sy+=d[i].y, c++) {
47
+ if(board[sy][sx] == turn) {
48
+ if(c > 0) flags |= 1<<i; //置けるならフラグセット
49
+ break;
50
+ }
51
+ }
52
+ }
53
+ board[y][x] = flags * -1; //0以下の数にして保存
54
+ return flags;
55
+ }
56
+
57
+ void changeLines(int y, int x, int turn) {
58
+ int flags = board[y][x] * -1; //0以上に戻す
59
+ board[y][x] = turn;
60
+ for(int i=0; i<dlen; i++) {
61
+ if(!(flags & (1<<i))) continue; //フラグが立っていない
62
+ for(int sx=x+d[i].x, sy=y+d[i].y; board[sy][sx]!=turn; sx+=d[i].x, sy+=d[i].y) {
63
+ board[sy][sx] = turn;
64
+ }
65
+ }
66
+ }
67
+
68
+ #define GAMEEND -1
31
69
 
32
70
  int check(int turn) {
33
71
  int count = 0; //置ける個所数
34
72
  int space = 0; //空き数
35
- for(int y=0; y<8; y++) {
73
+ for(int y=0; y<SIZE; y++) {
36
- for(int x=0; x<8; x++) {
74
+ for(int x=0; x<SIZE; x++) {
37
- if(board[y][x] > 0) continue; //石がある所はスキップ
75
+ if(isPlaced(board[y][x])) continue; //石がある所はスキップ
38
76
  space ++;
39
- //8方向を検索
40
- int flags = 0; //下位8ビットが8方向に対応
41
- for(int i=0; i<dlen; i++) {
42
- for(int sx=x+d[i].x, sy=y+d[i].y, c=0; inboard(sy,sx) && board[sy][sx]>0; sx+=d[i].x, sy+=d[i].y, c++) {
43
- if(board[sy][sx] == turn) {
44
- if(c > 0) flags |= 1<<i; //置けるならフラグセット
45
- break;
46
- }
47
- }
48
- }
49
- board[y][x] = flags * -1; //0以下の数にして保存
50
- if(flags != 0) count++;
77
+ if(checkLines(y, x, turn) != 0) count++;
51
78
  }
52
79
  }
53
- return space == 0 ? -1 : count;
80
+ return space == 0 ? GAMEEND : count;
54
81
  }
55
82
 
56
83
  void print() {
57
84
  printf(" ");
58
- for(int x=0; x<8; x++) printf(" %d ", x);
85
+ for(int x=0; x<SIZE; x++) printf(" %d ", x);
59
86
  printf("\n");
60
87
 
61
- for(int y=0; y<8; y++) {
88
+ for(int y=0; y<SIZE; y++) {
62
89
  printf("%d ", y);
63
- for(int x=0; x<8; x++) {
90
+ for(int x=0; x<SIZE; x++) {
64
- printf(" %s ", images[board[y][x] < 0 ? 3 : board[y][x]]);
91
+ printf(" %s ", toImage(board[y][x]));
65
92
  //if(board[y][x] > 0) printf(" %s ", images[board[y][x]]);
66
93
  //else printf(" %02x ", board[y][x]*-1);
67
94
  }
@@ -72,38 +99,31 @@
72
99
  void input(int turn) {
73
100
  int x, y;
74
101
  do{
75
- printf("%sの番 \"横 縦\"の形で入力:", turn==1?"黒":"白"); fflush(stdout);
102
+ printf("%sの番 \"横 縦\"の形で入力:", toString(turn)); fflush(stdout);
76
103
  scanf("%d %d", &x, &y);
77
- } while(board[y][x] >= 0);
104
+ } while(!canPlace(board[y][x]));
78
105
 
79
- int flags = board[y][x] * -1;
80
- board[y][x] = turn;
81
- for(int i=0; i<dlen; i++) {
82
- if(!(flags & (1<<i))) continue; //フラグが立っていない
83
- for(int sx=x+d[i].x, sy=y+d[i].y; board[sy][sx]!=turn; sx+=d[i].x, sy+=d[i].y) {
84
- board[sy][sx] = turn;
106
+ changeLines(y, x, turn);
85
- }
86
- }
87
107
  }
88
108
 
89
- void judge(){
109
+ void judge() {
90
110
  int bc=0, wc=0;
91
- for(int y=0; y<8; y++) {
111
+ for(int y=0; y<SIZE; y++) {
92
- for(int x=0; x<8; x++) {
112
+ for(int x=0; x<SIZE; x++) {
93
- if(board[y][x] == 1) bc++;
113
+ if(board[y][x] == BLACK) bc++;
94
- else if(board[y][x] == 2) wc++;
114
+ else if(board[y][x] == WHITE) wc++;
95
115
  }
96
116
  }
97
117
  printf("*** %s ***\n", bc>wc?"黒の勝ち":bc<wc?"白の勝ち":"引き分け");
98
118
  }
99
119
 
100
- int main(void){
120
+ int main(void) {
101
121
  while(1) {
102
122
  printf("-------------------------\n");
103
123
  init();
104
- for(int turn=1, skip=0, state; (state=check(turn))>=0; turn^=3) {
124
+ for(int turn=BLACK, skip=0, count; (count=check(turn))!=GAMEEND; turn=nextTurn(turn)) {
105
- if(state == 0) {
125
+ if(count == 0) {
106
- printf("%s パス\n", turn==1?"黒":"白"); fflush(stdout);
126
+ printf("%s パス\n", toString(turn)); fflush(stdout);
107
127
  if(++skip >= 2) break; //空きは有ってもどちらも置けない
108
128
  continue;
109
129
  }