khetai 0.2.3 → 0.3.2
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/.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
|