khetai 0.2.3 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.clang-format +14 -0
- data/Gemfile.lock +1 -1
- data/ext/khetai/dev/fltk-ui/ai_loader.cpp +20 -40
- data/ext/khetai/dev/fltk-ui/ai_loader.h +4 -5
- data/ext/khetai/dev/fltk-ui/game_board.cpp +98 -204
- data/ext/khetai/dev/fltk-ui/game_board.h +12 -19
- data/ext/khetai/dev/fltk-ui/game_board_util.cpp +16 -36
- data/ext/khetai/dev/fltk-ui/game_board_util.h +1 -1
- data/ext/khetai/dev/fltk-ui/khet.cpp +9 -14
- data/ext/khetai/dev/main.c +4 -6
- data/ext/khetai/khetai.c +25 -33
- data/ext/khetai/khetai_lib.c +252 -272
- data/ext/khetai/khetai_lib.h +88 -104
- data/lib/khetai/version.rb +1 -1
- metadata +3 -2
data/ext/khetai/khetai_lib.h
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#ifndef KHET_LIB_H_INCLUDED
|
2
2
|
#define KHET_LIB_H_INCLUDED
|
3
3
|
|
4
|
-
#include <stdint.h>
|
5
4
|
#include <stdbool.h>
|
5
|
+
#include <stdint.h>
|
6
|
+
#include <time.h>
|
6
7
|
|
7
8
|
#ifdef __cplusplus
|
8
9
|
#include <ctime>
|
@@ -15,44 +16,29 @@ typedef uint32_t Move;
|
|
15
16
|
#define MAX_SCORE 9999999
|
16
17
|
#define MAX_DEPTH 25
|
17
18
|
|
18
|
-
enum Player
|
19
|
-
|
20
|
-
|
21
|
-
Red
|
19
|
+
enum Player {
|
20
|
+
SILVER,
|
21
|
+
RED
|
22
22
|
};
|
23
|
-
enum Piece
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Sphinx = 5
|
23
|
+
enum Piece {
|
24
|
+
ANUBIS = 1,
|
25
|
+
PYRAMID = 2,
|
26
|
+
SCARAB = 3,
|
27
|
+
PHARAOH = 4,
|
28
|
+
SPHINX = 5
|
30
29
|
};
|
31
|
-
enum Orientation
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
West
|
30
|
+
enum Orientation {
|
31
|
+
NORTH,
|
32
|
+
EAST,
|
33
|
+
SOUTH,
|
34
|
+
WEST
|
37
35
|
};
|
38
36
|
|
39
|
-
extern enum Player whose_turn;
|
40
|
-
extern enum Player starter;
|
41
|
-
extern int initial_depth;
|
42
|
-
|
43
37
|
// north, east, south, west, diagonals
|
44
38
|
static const int directions[8] = {-12, 1, 12, -1, (12 + 1), (12 - 1), (-12 + 1), (-12 - 1)};
|
45
39
|
static const int rotations[2] = {1, -1};
|
46
40
|
static const int sphinx_loc[2] = {106, 13};
|
47
41
|
|
48
|
-
extern int pharaoh_loc[2];
|
49
|
-
|
50
|
-
extern Square board[120];
|
51
|
-
extern Move undo_moves[MAX_DEPTH];
|
52
|
-
extern int undo_capture_indices[MAX_DEPTH];
|
53
|
-
extern Square undo_capture_squares[MAX_DEPTH];
|
54
|
-
extern int undo_index;
|
55
|
-
|
56
42
|
static const int can_move[2][120] = {
|
57
43
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
58
44
|
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
|
@@ -92,39 +78,21 @@ extern time_t start_time;
|
|
92
78
|
extern int max_time;
|
93
79
|
|
94
80
|
#ifdef __cplusplus
|
95
|
-
extern "C"
|
96
|
-
{
|
81
|
+
extern "C" {
|
97
82
|
#endif
|
98
83
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
84
|
+
void set_time_parameters(int _max_time, time_t _start_time);
|
85
|
+
void reset_undo();
|
86
|
+
void init_zobrist();
|
87
|
+
void setup_board(char *board[]);
|
88
|
+
Move alphabeta_root(int depth, enum Player player);
|
89
|
+
void make_move(Move move);
|
90
|
+
void print_board();
|
106
91
|
|
107
92
|
#ifdef __cplusplus
|
108
93
|
}
|
109
94
|
#endif
|
110
95
|
|
111
|
-
Square str_to_square(char *str);
|
112
|
-
void print_piece(Square s);
|
113
|
-
|
114
|
-
void find_valid_moves(Move *valid_moves, int *vi);
|
115
|
-
void find_valid_anubis_pyramid_moves(int i, Move *valid_moves, int *vi);
|
116
|
-
void find_valid_scarab_moves(int i, Move *valid_moves, int *vi);
|
117
|
-
void find_valid_pharaoh_moves(int i, Move *valid_moves, int *vi);
|
118
|
-
void find_valid_sphinx_moves(int i, Move *valid_moves, int *vi);
|
119
|
-
|
120
|
-
int alphabeta(int depth, enum Player player, int alpha, int beta);
|
121
|
-
int calculate_score();
|
122
|
-
int distance_from_pharaoh(int i, int p);
|
123
|
-
|
124
|
-
void undo_move();
|
125
|
-
void fire_laser(uint64_t *hash);
|
126
|
-
bool is_move_legal(Move move);
|
127
|
-
|
128
96
|
static inline bool is_piece(Square s) { return s > 0; }
|
129
97
|
|
130
98
|
static inline enum Player get_owner(Square s) { return (enum Player)(s >> 1 & 0x1); }
|
@@ -137,18 +105,16 @@ static inline int get_end(Move m) { return m >> 8 & 0x7F; }
|
|
137
105
|
static inline int get_rotation(Move m) { return (m >> 15 & 0x3) - 2; }
|
138
106
|
|
139
107
|
#ifdef __cplusplus
|
140
|
-
extern "C"
|
141
|
-
{
|
108
|
+
extern "C" {
|
142
109
|
#endif
|
143
|
-
|
144
|
-
|
145
|
-
|
110
|
+
int get_start_wrapper(Move move);
|
111
|
+
int get_end_wrapper(Move move);
|
112
|
+
int get_rotation_wrapper(Move move);
|
146
113
|
#ifdef __cplusplus
|
147
114
|
}
|
148
115
|
#endif
|
149
116
|
|
150
|
-
static inline Square rotate(Square s, int rotation)
|
151
|
-
{
|
117
|
+
static inline Square rotate(Square s, int rotation) {
|
152
118
|
int orientation = get_orientation(s);
|
153
119
|
orientation = (orientation + rotation) % 4;
|
154
120
|
if (orientation < 0)
|
@@ -156,52 +122,43 @@ static inline Square rotate(Square s, int rotation)
|
|
156
122
|
return (s & 0x1F) + (orientation << 5);
|
157
123
|
}
|
158
124
|
|
159
|
-
static inline enum Player opposite_player(enum Player player)
|
160
|
-
|
161
|
-
return player == Red ? Silver : Red;
|
125
|
+
static inline enum Player opposite_player(enum Player player) {
|
126
|
+
return player == RED ? SILVER : RED;
|
162
127
|
}
|
163
128
|
|
164
|
-
#define
|
165
|
-
#define
|
129
|
+
#define DEAD -1
|
130
|
+
#define ABSORBED -2
|
166
131
|
|
167
132
|
// [laser direciton][piece type][piece orientation] = reflection result
|
168
133
|
// anubis, pyramid, scarab, pharaoh, sphinx
|
169
134
|
static const int reflections[4][5][4] = {
|
170
135
|
{// North
|
171
|
-
{
|
172
|
-
{
|
173
|
-
{
|
174
|
-
{
|
175
|
-
{
|
136
|
+
{DEAD, DEAD, ABSORBED, DEAD},
|
137
|
+
{DEAD, EAST, WEST, DEAD},
|
138
|
+
{WEST, EAST, WEST, EAST},
|
139
|
+
{DEAD, DEAD, DEAD, DEAD},
|
140
|
+
{ABSORBED, ABSORBED, ABSORBED, ABSORBED}},
|
176
141
|
{// East
|
177
|
-
{
|
178
|
-
{
|
179
|
-
{
|
180
|
-
{
|
181
|
-
{
|
142
|
+
{DEAD, DEAD, DEAD, ABSORBED},
|
143
|
+
{DEAD, DEAD, SOUTH, NORTH},
|
144
|
+
{SOUTH, NORTH, SOUTH, NORTH},
|
145
|
+
{DEAD, DEAD, DEAD, DEAD},
|
146
|
+
{ABSORBED, ABSORBED, ABSORBED, ABSORBED}},
|
182
147
|
{// South
|
183
|
-
{
|
184
|
-
{
|
185
|
-
{
|
186
|
-
{
|
187
|
-
{
|
148
|
+
{ABSORBED, DEAD, DEAD, DEAD},
|
149
|
+
{EAST, DEAD, DEAD, WEST},
|
150
|
+
{EAST, WEST, EAST, WEST},
|
151
|
+
{DEAD, DEAD, DEAD, DEAD},
|
152
|
+
{ABSORBED, ABSORBED, ABSORBED, ABSORBED}},
|
188
153
|
{// West
|
189
|
-
{
|
190
|
-
{
|
191
|
-
{
|
192
|
-
{
|
193
|
-
{
|
194
|
-
|
195
|
-
extern uint64_t keys[0xFF][120];
|
196
|
-
extern uint64_t hashes[MAX_DEPTH];
|
197
|
-
extern uint64_t turn_key;
|
198
|
-
extern int move_num;
|
199
|
-
extern bool checkmate;
|
200
|
-
|
201
|
-
uint64_t get_board_hash();
|
154
|
+
{DEAD, ABSORBED, DEAD, DEAD},
|
155
|
+
{NORTH, SOUTH, DEAD, DEAD},
|
156
|
+
{NORTH, SOUTH, NORTH, SOUTH},
|
157
|
+
{DEAD, DEAD, DEAD, DEAD},
|
158
|
+
{ABSORBED, ABSORBED, ABSORBED, ABSORBED}}};
|
159
|
+
|
202
160
|
static uint64_t seed = 1070372;
|
203
|
-
static inline uint64_t random_number()
|
204
|
-
{
|
161
|
+
static inline uint64_t random_number() {
|
205
162
|
seed ^= seed >> 12;
|
206
163
|
seed ^= seed << 25;
|
207
164
|
seed ^= seed >> 27;
|
@@ -209,12 +166,12 @@ static inline uint64_t random_number()
|
|
209
166
|
}
|
210
167
|
|
211
168
|
#define TABLE_SIZE 0x400000
|
169
|
+
#define TABLE_MASK 0x3FFFFF
|
212
170
|
|
213
171
|
#define EXACT 0
|
214
|
-
#define
|
215
|
-
#define
|
216
|
-
typedef struct HashEntry
|
217
|
-
{
|
172
|
+
#define LOWERBOUND 1
|
173
|
+
#define UPPERBOUND 2
|
174
|
+
typedef struct HashEntry {
|
218
175
|
uint64_t key;
|
219
176
|
int depth;
|
220
177
|
int flag;
|
@@ -223,7 +180,34 @@ typedef struct HashEntry
|
|
223
180
|
} HashEntry;
|
224
181
|
|
225
182
|
extern HashEntry table[TABLE_SIZE];
|
226
|
-
static inline HashEntry *search_table(uint64_t key) { return &table[key
|
227
|
-
|
183
|
+
static inline HashEntry *search_table(uint64_t key) { return &table[key & TABLE_MASK]; };
|
184
|
+
|
185
|
+
#define EPT 0xFF
|
186
|
+
typedef struct PieceTracker {
|
187
|
+
uint8_t positions[13];
|
188
|
+
uint8_t board_idx_position[120];
|
189
|
+
} PieceTracker;
|
190
|
+
extern PieceTracker piece_trackers[2];
|
191
|
+
|
192
|
+
static inline uint8_t get_board_index(enum Player player, uint8_t pos_idx) { return piece_trackers[player].positions[pos_idx]; }
|
193
|
+
static inline uint8_t get_position_index(enum Player player, uint8_t board_idx) { return piece_trackers[player].board_idx_position[board_idx]; }
|
194
|
+
static inline void update_piece_tracker(enum Player player, uint8_t old_board_idx, uint8_t new_board_idx) {
|
195
|
+
uint8_t pos_idx = get_position_index(player, old_board_idx);
|
196
|
+
piece_trackers[player].positions[pos_idx] = new_board_idx;
|
197
|
+
piece_trackers[player].board_idx_position[old_board_idx] = EPT;
|
198
|
+
piece_trackers[player].board_idx_position[new_board_idx] = pos_idx;
|
199
|
+
}
|
200
|
+
static inline void remove_from_piece_tracker(enum Player player, uint8_t board_idx) {
|
201
|
+
uint8_t pos_idx = get_position_index(player, board_idx);
|
202
|
+
piece_trackers[player].positions[pos_idx] = EPT;
|
203
|
+
piece_trackers[player].board_idx_position[board_idx] = EPT;
|
204
|
+
}
|
205
|
+
static inline void add_to_piece_tracker(enum Player player, uint8_t board_idx) {
|
206
|
+
uint8_t pos_idx = 0;
|
207
|
+
while (piece_trackers[player].positions[pos_idx] != EPT)
|
208
|
+
pos_idx++;
|
209
|
+
piece_trackers[player].positions[pos_idx] = board_idx;
|
210
|
+
piece_trackers[player].board_idx_position[board_idx] = pos_idx;
|
211
|
+
}
|
228
212
|
|
229
213
|
#endif // KHET_LIB_H_INCLUDED
|
data/lib/khetai/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: khetai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jkugs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -18,6 +18,7 @@ extensions:
|
|
18
18
|
- ext/khetai/extconf.rb
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- ".clang-format"
|
21
22
|
- ".gitignore"
|
22
23
|
- Gemfile
|
23
24
|
- Gemfile.lock
|