reversi 2.0.3 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/reversi/bit_board_functions.c +126 -75
- data/ext/reversi/board.c +4 -4
- data/ext/reversi/board.h +4 -4
- data/ext/reversi/reversi.c +4 -4
- data/ext/reversi/reversi.h +1 -0
- data/lib/reversi/board.rb +5 -5
- data/lib/reversi/configuration.rb +4 -0
- data/lib/reversi/version.rb +1 -1
- data/spec/game_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b04e18b34cf5a1d99f66c71cb9d2049931aa93b7
|
|
4
|
+
data.tar.gz: c0d30414f6fcbcc2bd787da52f127667382038bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63173220183fcd71d3eb17b36534b613df94161453fd2f94d6fbf9a14c506b6fd3e17876bd28b71b4b25751a7129cf6b0a86d0878b7ae79069f5d5112f7ab896
|
|
7
|
+
data.tar.gz: 2bf6f253e1f54af117bfea8a9a7ca89513949af1f73aab6f03c863c1acea7cf1da392f76ef5f123119429f2af1b3f849ba2aad8ab779025a8f81dcbc2cf08741
|
|
@@ -12,85 +12,25 @@ uint64_t XY2BB(int x, int y) {
|
|
|
12
12
|
*/
|
|
13
13
|
VALUE BB2XY(uint64_t bb) {
|
|
14
14
|
VALUE xy = rb_ary_new();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
case 0x2000000000000000: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(1)); break;
|
|
20
|
-
case 0x1000000000000000: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(1)); break;
|
|
21
|
-
case 0x0800000000000000: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(1)); break;
|
|
22
|
-
case 0x0400000000000000: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(1)); break;
|
|
23
|
-
case 0x0200000000000000: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(1)); break;
|
|
24
|
-
case 0x0100000000000000: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(1)); break;
|
|
25
|
-
|
|
26
|
-
case 0x0080000000000000: rb_ary_push(xy, INT2FIX(1)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
27
|
-
case 0x0040000000000000: rb_ary_push(xy, INT2FIX(2)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
28
|
-
case 0x0020000000000000: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
29
|
-
case 0x0010000000000000: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
30
|
-
case 0x0008000000000000: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
31
|
-
case 0x0004000000000000: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
32
|
-
case 0x0002000000000000: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
33
|
-
case 0x0001000000000000: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(2)); break;
|
|
34
|
-
|
|
35
|
-
case 0x0000800000000000: rb_ary_push(xy, INT2FIX(1)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
36
|
-
case 0x0000400000000000: rb_ary_push(xy, INT2FIX(2)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
37
|
-
case 0x0000200000000000: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
38
|
-
case 0x0000100000000000: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
39
|
-
case 0x0000080000000000: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
40
|
-
case 0x0000040000000000: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
41
|
-
case 0x0000020000000000: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
42
|
-
case 0x0000010000000000: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(3)); break;
|
|
43
|
-
|
|
44
|
-
case 0x0000008000000000: rb_ary_push(xy, INT2FIX(1)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
45
|
-
case 0x0000004000000000: rb_ary_push(xy, INT2FIX(2)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
46
|
-
case 0x0000002000000000: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
47
|
-
case 0x0000001000000000: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
48
|
-
case 0x0000000800000000: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
49
|
-
case 0x0000000400000000: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
50
|
-
case 0x0000000200000000: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
51
|
-
case 0x0000000100000000: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(4)); break;
|
|
52
|
-
|
|
53
|
-
case 0x0000000080000000: rb_ary_push(xy, INT2FIX(1)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
54
|
-
case 0x0000000040000000: rb_ary_push(xy, INT2FIX(2)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
55
|
-
case 0x0000000020000000: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
56
|
-
case 0x0000000010000000: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
57
|
-
case 0x0000000008000000: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
58
|
-
case 0x0000000004000000: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
59
|
-
case 0x0000000002000000: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
60
|
-
case 0x0000000001000000: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(5)); break;
|
|
61
|
-
|
|
62
|
-
case 0x0000000000800000: rb_ary_push(xy, INT2FIX(1)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
63
|
-
case 0x0000000000400000: rb_ary_push(xy, INT2FIX(2)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
64
|
-
case 0x0000000000200000: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
65
|
-
case 0x0000000000100000: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
66
|
-
case 0x0000000000080000: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
67
|
-
case 0x0000000000040000: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
68
|
-
case 0x0000000000020000: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
69
|
-
case 0x0000000000010000: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(6)); break;
|
|
70
|
-
|
|
71
|
-
case 0x0000000000008000: rb_ary_push(xy, INT2FIX(1)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
72
|
-
case 0x0000000000004000: rb_ary_push(xy, INT2FIX(2)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
73
|
-
case 0x0000000000002000: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
74
|
-
case 0x0000000000001000: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
75
|
-
case 0x0000000000000800: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
76
|
-
case 0x0000000000000400: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
77
|
-
case 0x0000000000000200: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
78
|
-
case 0x0000000000000100: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(7)); break;
|
|
79
|
-
|
|
80
|
-
case 0x0000000000000080: rb_ary_push(xy, INT2FIX(1)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
81
|
-
case 0x0000000000000040: rb_ary_push(xy, INT2FIX(2)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
82
|
-
case 0x0000000000000020: rb_ary_push(xy, INT2FIX(3)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
83
|
-
case 0x0000000000000010: rb_ary_push(xy, INT2FIX(4)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
84
|
-
case 0x0000000000000008: rb_ary_push(xy, INT2FIX(5)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
85
|
-
case 0x0000000000000004: rb_ary_push(xy, INT2FIX(6)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
86
|
-
case 0x0000000000000002: rb_ary_push(xy, INT2FIX(7)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
87
|
-
case 0x0000000000000001: rb_ary_push(xy, INT2FIX(8)), rb_ary_push(xy, INT2FIX(8)); break;
|
|
88
|
-
}
|
|
15
|
+
int x = 8 - ( (int)log2((double)bb) % 8 );
|
|
16
|
+
int y = 8 - ( (int)log2((double)bb) / 8 );
|
|
17
|
+
rb_ary_push(xy, INT2FIX(x));
|
|
18
|
+
rb_ary_push(xy, INT2FIX(y));
|
|
89
19
|
return xy;
|
|
90
20
|
}
|
|
91
21
|
|
|
92
22
|
/*
|
|
93
23
|
* Rotate a bitboard by 90 degrees to the right.
|
|
24
|
+
*
|
|
25
|
+
* For example,
|
|
26
|
+
* 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1
|
|
27
|
+
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
|
|
28
|
+
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
|
|
29
|
+
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
|
|
30
|
+
* 0 0 0 0 0 0 0 0 -> 0 0 0 0 0 0 0 1
|
|
31
|
+
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
|
|
32
|
+
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
|
|
33
|
+
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
|
|
94
34
|
*/
|
|
95
35
|
uint64_t rotate_r90(uint64_t bb) {
|
|
96
36
|
bb = ((bb << 8) & 0xAA00AA00AA00AA00) |
|
|
@@ -110,6 +50,16 @@ uint64_t rotate_r90(uint64_t bb) {
|
|
|
110
50
|
|
|
111
51
|
/*
|
|
112
52
|
* Rotate a bitboard by 90 degrees to the left.
|
|
53
|
+
*
|
|
54
|
+
* For example,
|
|
55
|
+
* 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
|
|
56
|
+
* 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
|
|
57
|
+
* 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
|
|
58
|
+
* 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
|
|
59
|
+
* 0 0 0 0 0 0 0 0 -> 1 0 0 0 0 0 0 0
|
|
60
|
+
* 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
|
|
61
|
+
* 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
|
|
62
|
+
* 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
|
|
113
63
|
*/
|
|
114
64
|
uint64_t rotate_l90(uint64_t bb) {
|
|
115
65
|
bb = ((bb << 1) & 0xAA00AA00AA00AA00) |
|
|
@@ -129,6 +79,16 @@ uint64_t rotate_l90(uint64_t bb) {
|
|
|
129
79
|
|
|
130
80
|
/*
|
|
131
81
|
* Rotate a bitboard by 45 degrees to the right.
|
|
82
|
+
*
|
|
83
|
+
* For example,
|
|
84
|
+
* 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
|
|
85
|
+
* 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
|
|
86
|
+
* 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
|
|
87
|
+
* 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
|
|
88
|
+
* 0 0 0 1 0 0 0 0 -> 0 0 0 0 0 0 0 0
|
|
89
|
+
* 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
90
|
+
* 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
91
|
+
* 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
132
92
|
*/
|
|
133
93
|
uint64_t rotate_r45(uint64_t bb) {
|
|
134
94
|
bb = (bb & 0x0101010101010101) |
|
|
@@ -144,6 +104,16 @@ uint64_t rotate_r45(uint64_t bb) {
|
|
|
144
104
|
|
|
145
105
|
/*
|
|
146
106
|
* Rotate a bitboard by 45 degrees to the left.
|
|
107
|
+
*
|
|
108
|
+
* For example,
|
|
109
|
+
* 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
110
|
+
* 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
111
|
+
* 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
112
|
+
* 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
|
|
113
|
+
* 0 0 0 0 1 0 0 0 -> 0 0 0 0 0 0 0 0
|
|
114
|
+
* 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
|
|
115
|
+
* 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
|
|
116
|
+
* 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
|
|
147
117
|
*/
|
|
148
118
|
uint64_t rotate_l45(uint64_t bb) {
|
|
149
119
|
bb = (bb & 0x0101010101010101) |
|
|
@@ -157,11 +127,45 @@ uint64_t rotate_l45(uint64_t bb) {
|
|
|
157
127
|
return bb;
|
|
158
128
|
}
|
|
159
129
|
|
|
130
|
+
/*
|
|
131
|
+
* 'p' is a position of player's move, 'XY2BB(FIX2INT(rb_x), FIX2INT(rb_y))'.
|
|
132
|
+
* 'my' is a bitboard of my disks, and 'op' is a bitboard of opponent's disks.
|
|
133
|
+
* horizontal_pat, vertical_pat and diagonal_pat method
|
|
134
|
+
* are used in Reversi::Board#flip_disks method to get the positions
|
|
135
|
+
* of the opponent's disks between a new disk and another disk of my color.
|
|
136
|
+
*
|
|
137
|
+
* This method returns a bitboard of flippable oppenent's disks
|
|
138
|
+
* in the horizontal direction.
|
|
139
|
+
*
|
|
140
|
+
* A mask for the horizontal direction is '0x7E7E7E7E7E7E7E7E'.
|
|
141
|
+
* 0 1 1 1 1 1 1 0
|
|
142
|
+
* 0 1 1 1 1 1 1 0
|
|
143
|
+
* 0 1 1 1 1 1 1 0
|
|
144
|
+
* 0 1 1 1 1 1 1 0
|
|
145
|
+
* 0 1 1 1 1 1 1 0
|
|
146
|
+
* 0 1 1 1 1 1 1 0
|
|
147
|
+
* 0 1 1 1 1 1 1 0
|
|
148
|
+
* 0 1 1 1 1 1 1 0
|
|
149
|
+
*/
|
|
160
150
|
uint64_t horizontal_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
161
151
|
op &= 0x7E7E7E7E7E7E7E7E;
|
|
162
152
|
return right_pat(my, op, p) | left_pat(my, op, p);
|
|
163
153
|
}
|
|
164
154
|
|
|
155
|
+
/*
|
|
156
|
+
* This method returns a bitboard of flippable oppenent's disks
|
|
157
|
+
* in the vertical direction.
|
|
158
|
+
*
|
|
159
|
+
* A mask for the vertical direction is '0x00FFFFFFFFFFFF00'.
|
|
160
|
+
* 0 0 0 0 0 0 0 0
|
|
161
|
+
* 1 1 1 1 1 1 1 1
|
|
162
|
+
* 1 1 1 1 1 1 1 1
|
|
163
|
+
* 1 1 1 1 1 1 1 1
|
|
164
|
+
* 1 1 1 1 1 1 1 1
|
|
165
|
+
* 1 1 1 1 1 1 1 1
|
|
166
|
+
* 1 1 1 1 1 1 1 1
|
|
167
|
+
* 0 0 0 0 0 0 0 0
|
|
168
|
+
*/
|
|
165
169
|
uint64_t vertical_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
166
170
|
my = rotate_r90(my);
|
|
167
171
|
op = rotate_r90(op & 0x00FFFFFFFFFFFF00);
|
|
@@ -169,17 +173,35 @@ uint64_t vertical_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
|
169
173
|
return rotate_l90(right_pat(my, op, p) | left_pat(my, op, p));
|
|
170
174
|
}
|
|
171
175
|
|
|
176
|
+
/*
|
|
177
|
+
* This method returns a bitboard of flippable oppenent's disks
|
|
178
|
+
* in the diagonal direction.
|
|
179
|
+
*
|
|
180
|
+
* a masks for the diagonal direction is '0x007E7E7E7E7E7E00'.
|
|
181
|
+
* 0 0 0 0 0 0 0 0
|
|
182
|
+
* 0 1 1 1 1 1 1 0
|
|
183
|
+
* 0 1 1 1 1 1 1 0
|
|
184
|
+
* 0 1 1 1 1 1 1 0
|
|
185
|
+
* 0 1 1 1 1 1 1 0
|
|
186
|
+
* 0 1 1 1 1 1 1 0
|
|
187
|
+
* 0 1 1 1 1 1 1 0
|
|
188
|
+
* 0 0 0 0 0 0 0 0
|
|
189
|
+
*/
|
|
172
190
|
uint64_t diagonal_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
173
191
|
uint64_t my_r45 = rotate_r45(my);
|
|
174
192
|
uint64_t op_r45 = rotate_r45(op & 0x007E7E7E7E7E7E00);
|
|
175
193
|
uint64_t p_r45 = rotate_r45(p);
|
|
176
194
|
uint64_t my_l45 = rotate_l45(my);
|
|
177
|
-
uint64_t op_l45 = rotate_l45(op &
|
|
195
|
+
uint64_t op_l45 = rotate_l45(op & 0x007E7E7E7E7E7E00);
|
|
178
196
|
uint64_t p_l45 = rotate_l45(p);
|
|
179
197
|
return rotate_l45(right_pat(my_r45, op_r45, p_r45) | left_pat(my_r45, op_r45, p_r45)) |
|
|
180
198
|
rotate_r45(right_pat(my_l45, op_l45, p_l45) | left_pat(my_l45, op_l45, p_l45));
|
|
181
199
|
}
|
|
182
200
|
|
|
201
|
+
/*
|
|
202
|
+
* This method returns a bitboard of flippable oppenent's disks
|
|
203
|
+
* in the right direction.
|
|
204
|
+
*/
|
|
183
205
|
uint64_t right_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
184
206
|
uint64_t rev = (p >> 1) & op;
|
|
185
207
|
rev |= (rev >> 1) & op;
|
|
@@ -190,6 +212,10 @@ uint64_t right_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
|
190
212
|
return ((rev >> 1) & my) == 0 ? 0 : rev;
|
|
191
213
|
}
|
|
192
214
|
|
|
215
|
+
/*
|
|
216
|
+
* This method returns a bitboard of flippable oppenent's disks
|
|
217
|
+
* in the left direction.
|
|
218
|
+
*/
|
|
193
219
|
uint64_t left_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
194
220
|
uint64_t rev = (p << 1) & op;
|
|
195
221
|
rev |= (rev << 1) & op;
|
|
@@ -200,11 +226,24 @@ uint64_t left_pat(uint64_t my, uint64_t op, uint64_t p) {
|
|
|
200
226
|
return ((rev << 1) & my) == 0 ? 0 : rev;
|
|
201
227
|
}
|
|
202
228
|
|
|
229
|
+
/*
|
|
230
|
+
* 'p' is a position of player's move, 'XY2BB(FIX2INT(rb_x), FIX2INT(rb_y))'.
|
|
231
|
+
* 'my' is a bitboard of my disks, and 'op' is a bitboard of opponent's disks.
|
|
232
|
+
* horizontal_pos, vertical_pos and diagonal_pos method
|
|
233
|
+
* are used in Reversi::Board#next_moves method to get positions of the next move.
|
|
234
|
+
*
|
|
235
|
+
* This method returns a bitboard of nextmove's positions
|
|
236
|
+
* in the horizontal direction.
|
|
237
|
+
*/
|
|
203
238
|
uint64_t horizontal_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
204
239
|
op &= 0x7E7E7E7E7E7E7E7E;
|
|
205
240
|
return right_pos(my, op, blank) | left_pos(my, op, blank);
|
|
206
241
|
}
|
|
207
242
|
|
|
243
|
+
/*
|
|
244
|
+
* This method returns a bitboard of nextmove's positions
|
|
245
|
+
* in the vertical direction.
|
|
246
|
+
*/
|
|
208
247
|
uint64_t vertical_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
209
248
|
my = rotate_r90(my);
|
|
210
249
|
op = rotate_r90(op & 0x00FFFFFFFFFFFF00);
|
|
@@ -212,6 +251,10 @@ uint64_t vertical_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
|
212
251
|
return rotate_l90(right_pos(my, op, blank) | left_pos(my, op, blank));
|
|
213
252
|
}
|
|
214
253
|
|
|
254
|
+
/*
|
|
255
|
+
* This method returns a bitboard of nextmove's positions
|
|
256
|
+
* in the diagonal direction.
|
|
257
|
+
*/
|
|
215
258
|
uint64_t diagonal_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
216
259
|
uint64_t my_r45 = rotate_r45(my);
|
|
217
260
|
uint64_t op_r45 = rotate_r45(op & 0x007E7E7E7E7E7E00);
|
|
@@ -223,6 +266,10 @@ uint64_t diagonal_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
|
223
266
|
rotate_r45(right_pos(my_l45, op_l45, blank_l45) | left_pos(my_l45, op_l45, blank_l45));
|
|
224
267
|
}
|
|
225
268
|
|
|
269
|
+
/*
|
|
270
|
+
* This method returns a bitboard of nextmove's positions
|
|
271
|
+
* in the right direction.
|
|
272
|
+
*/
|
|
226
273
|
uint64_t right_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
227
274
|
uint64_t rev = (my << 1) & op;
|
|
228
275
|
rev |= (rev << 1) & op;
|
|
@@ -233,6 +280,10 @@ uint64_t right_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
|
233
280
|
return (rev << 1) & blank;
|
|
234
281
|
}
|
|
235
282
|
|
|
283
|
+
/*
|
|
284
|
+
* This method returns a bitboard of nextmove's positions
|
|
285
|
+
* in the left direction.
|
|
286
|
+
*/
|
|
236
287
|
uint64_t left_pos(uint64_t my, uint64_t op, uint64_t blank) {
|
|
237
288
|
uint64_t rev = (my >> 1) & op;
|
|
238
289
|
rev |= (rev >> 1) & op;
|
data/ext/reversi/board.c
CHANGED
|
@@ -21,7 +21,7 @@ VALUE board_initialize(VALUE self) {
|
|
|
21
21
|
*
|
|
22
22
|
* @param black [Fixnum, Bignum] a bitboard for black
|
|
23
23
|
*/
|
|
24
|
-
VALUE
|
|
24
|
+
VALUE set_black(VALUE self, VALUE black) {
|
|
25
25
|
struct bit_board *ptr;
|
|
26
26
|
Data_Get_Struct(self, struct bit_board, ptr);
|
|
27
27
|
ptr->black = NUM2ULL(black);
|
|
@@ -33,7 +33,7 @@ VALUE black_setter(VALUE self, VALUE black) {
|
|
|
33
33
|
*
|
|
34
34
|
* @param black [Fixnum, Bignum] a bitboard for white
|
|
35
35
|
*/
|
|
36
|
-
VALUE
|
|
36
|
+
VALUE set_white(VALUE self, VALUE white) {
|
|
37
37
|
struct bit_board *ptr;
|
|
38
38
|
Data_Get_Struct(self, struct bit_board, ptr);
|
|
39
39
|
ptr->white = NUM2ULL(white);
|
|
@@ -45,7 +45,7 @@ VALUE white_setter(VALUE self, VALUE white) {
|
|
|
45
45
|
*
|
|
46
46
|
* @return [Fixnum, Bignum]
|
|
47
47
|
*/
|
|
48
|
-
VALUE
|
|
48
|
+
VALUE get_black(VALUE self) {
|
|
49
49
|
struct bit_board *ptr;
|
|
50
50
|
Data_Get_Struct(self, struct bit_board, ptr);
|
|
51
51
|
return ULL2NUM(ptr->black);
|
|
@@ -56,7 +56,7 @@ VALUE black_getter(VALUE self) {
|
|
|
56
56
|
*
|
|
57
57
|
* @return [Fixnum, Bignum]
|
|
58
58
|
*/
|
|
59
|
-
VALUE
|
|
59
|
+
VALUE get_white(VALUE self) {
|
|
60
60
|
struct bit_board *ptr;
|
|
61
61
|
Data_Get_Struct(self, struct bit_board, ptr);
|
|
62
62
|
return ULL2NUM(ptr->white);
|
data/ext/reversi/board.h
CHANGED
|
@@ -11,10 +11,10 @@ struct bit_board {
|
|
|
11
11
|
VALUE bit_board_alloc(VALUE class);
|
|
12
12
|
VALUE board_initialize(VALUE self);
|
|
13
13
|
|
|
14
|
-
VALUE
|
|
15
|
-
VALUE
|
|
16
|
-
VALUE
|
|
17
|
-
VALUE
|
|
14
|
+
VALUE set_black(VALUE self, VALUE black);
|
|
15
|
+
VALUE set_white(VALUE self, VALUE white);
|
|
16
|
+
VALUE get_black(VALUE self);
|
|
17
|
+
VALUE get_white(VALUE self);
|
|
18
18
|
|
|
19
19
|
VALUE status(VALUE self);
|
|
20
20
|
VALUE openness(VALUE self, VALUE rb_x, VALUE rb_y);
|
data/ext/reversi/reversi.c
CHANGED
|
@@ -7,10 +7,10 @@ void Init_reversi(void) {
|
|
|
7
7
|
rb_define_alloc_func(reversi_board, bit_board_alloc);
|
|
8
8
|
|
|
9
9
|
/* These private methods are used in the board.rb file. */
|
|
10
|
-
rb_define_private_method(reversi_board, "
|
|
11
|
-
rb_define_private_method(reversi_board, "
|
|
12
|
-
rb_define_private_method(reversi_board, "
|
|
13
|
-
rb_define_private_method(reversi_board, "
|
|
10
|
+
rb_define_private_method(reversi_board, "set_black", set_black, 1);
|
|
11
|
+
rb_define_private_method(reversi_board, "set_white", set_white, 1);
|
|
12
|
+
rb_define_private_method(reversi_board, "get_black", get_black, 0);
|
|
13
|
+
rb_define_private_method(reversi_board, "get_white", get_white, 0);
|
|
14
14
|
|
|
15
15
|
/* This method is used in the `Reversi::Board.new` method. */
|
|
16
16
|
rb_define_private_method(reversi_board, "board_initialize", board_initialize, 0);
|
data/ext/reversi/reversi.h
CHANGED
data/lib/reversi/board.rb
CHANGED
|
@@ -54,8 +54,8 @@ module Reversi
|
|
|
54
54
|
" #{"+---"*8}+\n" <<
|
|
55
55
|
(0..63).map do |i|
|
|
56
56
|
case 1
|
|
57
|
-
when
|
|
58
|
-
when
|
|
57
|
+
when get_black[63 - i] then "\e[#{@options[:disk_color_b]}m#{@options[:disk_b]}\e[0m"
|
|
58
|
+
when get_white[63 - i] then "\e[#{@options[:disk_color_w]}m#{@options[:disk_w]}\e[0m"
|
|
59
59
|
else " "
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -69,7 +69,7 @@ module Reversi
|
|
|
69
69
|
# Pushes an array of the game board onto a stack.
|
|
70
70
|
# The stack size limit is 3(default).
|
|
71
71
|
def push_stack
|
|
72
|
-
bb = {:black =>
|
|
72
|
+
bb = {:black => get_black,:white => get_white}
|
|
73
73
|
@stack.push(Marshal.load(Marshal.dump(bb)))
|
|
74
74
|
@stack.shift if @stack.size > @options[:stack_limit]
|
|
75
75
|
end
|
|
@@ -78,8 +78,8 @@ module Reversi
|
|
|
78
78
|
# and that is stored in the instance variable.(`@bit_board`)
|
|
79
79
|
def undo!
|
|
80
80
|
bb = @stack.pop
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
set_black(bb[:black])
|
|
82
|
+
set_white(bb[:white])
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
end
|
|
@@ -27,20 +27,24 @@ module Reversi
|
|
|
27
27
|
|
|
28
28
|
attr_accessor *OPTIONS_KEYS
|
|
29
29
|
|
|
30
|
+
# This method is used for setting configuration options.
|
|
30
31
|
def configure
|
|
31
32
|
yield self
|
|
32
33
|
end
|
|
33
34
|
|
|
35
|
+
# Create a hash of options.
|
|
34
36
|
def options
|
|
35
37
|
Hash[*OPTIONS_KEYS.map{|key| [key, send(key)]}.flatten]
|
|
36
38
|
end
|
|
37
39
|
|
|
40
|
+
# Reset all options to their default values.
|
|
38
41
|
def reset
|
|
39
42
|
DEFAULTS.each do |option, default|
|
|
40
43
|
self.send("#{option}=".to_sym, default)
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
|
|
47
|
+
# Set default value for the option that is still not set.
|
|
44
48
|
def set_defaults
|
|
45
49
|
DEFAULTS.each do |option, default|
|
|
46
50
|
default.class == String ?
|
data/lib/reversi/version.rb
CHANGED
data/spec/game_spec.rb
CHANGED
|
@@ -101,8 +101,8 @@ describe Reversi::Game do
|
|
|
101
101
|
:white =>0x7F60_513B_274B_0400
|
|
102
102
|
}
|
|
103
103
|
it do
|
|
104
|
-
expect(game.board.send(:
|
|
105
|
-
expect(game.board.send(:
|
|
104
|
+
expect(game.board.send(:get_black)).to eq ans[:black]
|
|
105
|
+
expect(game.board.send(:get_white)).to eq ans[:white]
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: reversi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- seinosuke
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-08-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|