khetai 0.1.8 → 0.2.0
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/.gitignore +5 -5
- data/Gemfile.lock +1 -1
- data/README.md +19 -11
- data/ext/khetai/dev/README.md +15 -0
- data/ext/khetai/dev/fltk-ui/Makefile +65 -0
- data/ext/khetai/dev/fltk-ui/Makefile.khetai +46 -0
- data/ext/khetai/dev/fltk-ui/README.md +34 -0
- data/ext/khetai/dev/fltk-ui/ai_loader.cpp +93 -0
- data/ext/khetai/dev/fltk-ui/ai_loader.h +33 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_red_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_red_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_red_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_red_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_silver_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_silver_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_silver_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/anubis_silver_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/example_board.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_red_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_red_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_red_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_red_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_silver_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_silver_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_silver_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/laser_silver_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pharaoh_red.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pharaoh_silver.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_red_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_red_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_red_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_red_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_red_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_red_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_red_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_red_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_silver_e.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_silver_n.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_silver_s.png +0 -0
- data/ext/khetai/dev/fltk-ui/assets/scarab_silver_w.png +0 -0
- data/ext/khetai/dev/fltk-ui/build_khetai.sh +9 -0
- data/ext/khetai/dev/fltk-ui/game_board.cpp +896 -0
- data/ext/khetai/dev/fltk-ui/game_board.h +105 -0
- data/ext/khetai/dev/fltk-ui/game_board_util.cpp +119 -0
- data/ext/khetai/dev/fltk-ui/game_board_util.h +15 -0
- data/ext/khetai/dev/fltk-ui/khet.cpp +59 -0
- data/ext/khetai/dev/main.c +8 -7
- data/ext/khetai/dev/main.rb +9 -10
- data/ext/khetai/khetai.c +22 -6
- data/ext/khetai/khetai_lib.c +22 -11
- data/ext/khetai/khetai_lib.h +35 -8
- data/lib/khetai/version.rb +1 -1
- metadata +49 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a32fa87a05f48b757c7e3c601e26313ad9d58d7c2ff773603d89ec8313c7d07b
|
4
|
+
data.tar.gz: 47f0883f7445baaf8541b340caff8e929d01ef1fa8c175b859936ecad30c355e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9df12c681f8bfc73d712c5682d483038abc81793d48235af7038dcf75cefa12d84de2c8760f88c036365115a4074d40f877c2707aa8faa38e5b126bf43b10b22
|
7
|
+
data.tar.gz: d5663b3a6b7110b86c309530f4dc7cdb019afbaf1c8148a670366088a486bd2406fdc5c49f3c83bd586f2fba8a74cd6e4f5c08f1fb9329697b9b6c8e0bad29f1
|
data/.gitignore
CHANGED
@@ -7,10 +7,10 @@
|
|
7
7
|
/spec/reports/
|
8
8
|
/tmp/
|
9
9
|
/build/
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
/ext/khetai/dev/khetai
|
14
|
-
/ext/khetai/dev/Makefile
|
10
|
+
/ext/khetai/dev/build/
|
11
|
+
/ext/khetai/dev/fltk-ui/build/
|
12
|
+
/ext/khetai/dev/fltk-ui/build_khetai/
|
15
13
|
.vscode
|
16
14
|
*.so
|
15
|
+
*.o
|
16
|
+
khet
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -18,16 +18,14 @@ require 'khetai'
|
|
18
18
|
# A = anubis, P = pyramid, S = scarab, X = pharaoh, L = sphinx
|
19
19
|
# capital letters = red, lowercase letters = silver
|
20
20
|
# 0 = north, 1 = east, 2 = south, 3 = west
|
21
|
-
board = ["
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
"--", "--", "--", "p3", "a0", "x0", "a0", "--", "--", "--", "l0", "--",
|
30
|
-
"--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--"]
|
21
|
+
board = ["L2", "--", "--", "--", "A2", "X2", "A2", "P1", "--", "--",
|
22
|
+
"--", "--", "P2", "--", "--", "--", "--", "--", "--", "--",
|
23
|
+
"--", "--", "--", "p3", "--", "--", "--", "--", "--", "--",
|
24
|
+
"P0", "--", "p2", "--", "S2", "S3", "--", "P1", "--", "p3",
|
25
|
+
"P1", "--", "p3", "--", "s1", "s0", "--", "P0", "--", "p2",
|
26
|
+
"--", "--", "--", "--", "--", "--", "P1", "--", "--", "--",
|
27
|
+
"--", "--", "--", "--", "--", "--", "--", "p0", "--", "--",
|
28
|
+
"--", "--", "p3", "a0", "x0", "a0", "--", "--", "--", "l0"]
|
31
29
|
|
32
30
|
whose_turn = 1 # silver = 0, red = 1
|
33
31
|
max_search_depth = 25 # must be between 2 and 25
|
@@ -41,9 +39,11 @@ move = KhetAI.move(board, whose_turn, max_search_depth, max_search_time)
|
|
41
39
|
# move[2] = rotation (1, -1, 0) (clockwise, anticlockwise, none)
|
42
40
|
```
|
43
41
|
|
42
|
+
The representation of the board gets converted an array of 8-bit integers once it is passed to the gem.
|
43
|
+
|
44
44
|
## Development
|
45
|
-
The internals of the gem are written in C, located in `ext/khetai`.
|
46
45
|
|
46
|
+
The internals of the gem are written in C, located in `ext/khetai`.
|
47
47
|
|
48
48
|
## Build and Deploy Commands
|
49
49
|
|
@@ -56,3 +56,11 @@ To release and push to rubygems.org:
|
|
56
56
|
|
57
57
|
$ bundle exec rake release
|
58
58
|
$ gem push pkg/<gem>
|
59
|
+
|
60
|
+
## Manual Testing
|
61
|
+
|
62
|
+
There is a GUI test harness written in C++ using FLTK available in the `ext/khetai/dev/fltk-ui` directory.
|
63
|
+
|
64
|
+
### Why does this exist?
|
65
|
+
|
66
|
+
To learn, build, and have fun.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Dev Tools
|
2
|
+
|
3
|
+
A few ways to test the khetai_lib...
|
4
|
+
|
5
|
+
### main.c
|
6
|
+
|
7
|
+
A small C program to execute a single move from the starting position.
|
8
|
+
|
9
|
+
### main.rb
|
10
|
+
|
11
|
+
A small Ruby program that will execute a single move form the starting position.
|
12
|
+
|
13
|
+
### fltk-ui
|
14
|
+
|
15
|
+
A C++ FLTK GUI that allows you set up the board however you want and request a move.
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Makefile for both the C++ FLTK GUI and the KhetAI lib as a shared object
|
2
|
+
|
3
|
+
# Compiler settings
|
4
|
+
CXX = g++
|
5
|
+
CC = gcc
|
6
|
+
CXXFLAGS = -std=c++17 $(shell fltk-config --cxxflags) -fPIC -MMD -MP
|
7
|
+
CFLAGS = -std=c11 -fPIC -MMD -MP
|
8
|
+
LDFLAGS = $(shell fltk-config --ldflags) -lfltk_images -lfltk_png -lfltk_z -ldl
|
9
|
+
|
10
|
+
# Application name
|
11
|
+
APP = khet
|
12
|
+
|
13
|
+
# Source directory
|
14
|
+
SRC_DIR = .
|
15
|
+
|
16
|
+
# Build directory
|
17
|
+
BUILD_DIR = build
|
18
|
+
|
19
|
+
# Source files
|
20
|
+
SRC_CPP = $(wildcard $(SRC_DIR)/*.cpp)
|
21
|
+
SRC_C = ../../khetai_lib.c
|
22
|
+
|
23
|
+
# Object files
|
24
|
+
OBJ_CPP = $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRC_CPP))
|
25
|
+
OBJ_C = $(patsubst ../../%.c,$(BUILD_DIR)/%.o,$(SRC_C))
|
26
|
+
|
27
|
+
# All object files
|
28
|
+
OBJ = $(OBJ_CPP) $(OBJ_C)
|
29
|
+
|
30
|
+
# AI Library
|
31
|
+
AI_LIB = libkhetai.so
|
32
|
+
|
33
|
+
# Default target
|
34
|
+
all: $(BUILD_DIR) $(APP) $(AI_LIB)
|
35
|
+
|
36
|
+
# Create the build directory
|
37
|
+
$(BUILD_DIR):
|
38
|
+
mkdir -p $(BUILD_DIR)
|
39
|
+
|
40
|
+
# Link the application
|
41
|
+
$(APP): $(OBJ)
|
42
|
+
$(CXX) -o $@ $^ $(LDFLAGS)
|
43
|
+
|
44
|
+
# Compile C++ source files into object files
|
45
|
+
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
|
46
|
+
$(CXX) -c $< -o $@ $(CXXFLAGS)
|
47
|
+
|
48
|
+
# Compile C source files into object files
|
49
|
+
$(BUILD_DIR)/%.o: ../../%.c
|
50
|
+
$(CC) -c $< -o $@ $(CFLAGS)
|
51
|
+
|
52
|
+
# Compile AI library
|
53
|
+
$(AI_LIB): $(OBJ_C)
|
54
|
+
$(CC) -shared -o $@ $^ $(CFLAGS)
|
55
|
+
|
56
|
+
# Include generated dependency files
|
57
|
+
-include $(OBJ_CPP:.o=.d)
|
58
|
+
-include $(OBJ_C:.o=.d)
|
59
|
+
|
60
|
+
# Clean target
|
61
|
+
clean:
|
62
|
+
rm -f $(OBJ) $(APP) $(AI_LIB) $(BUILD_DIR)/*.d
|
63
|
+
rm -rf $(BUILD_DIR)
|
64
|
+
|
65
|
+
.PHONY: all clean
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Makefile for the KhetAI lib as a shared object
|
2
|
+
# Used for hot reloading while the GUI is running
|
3
|
+
|
4
|
+
# Compiler settings
|
5
|
+
CC = gcc
|
6
|
+
CFLAGS = -std=c11 -fPIC -O3 -MMD -MP
|
7
|
+
|
8
|
+
# Source directory
|
9
|
+
SRC_DIR = ../../
|
10
|
+
|
11
|
+
# Build directory
|
12
|
+
BUILD_DIR = build_khetai
|
13
|
+
|
14
|
+
# Source files
|
15
|
+
SRC = $(SRC_DIR)khetai_lib.c
|
16
|
+
|
17
|
+
# Object files
|
18
|
+
OBJ = $(BUILD_DIR)/khetai_lib.o
|
19
|
+
|
20
|
+
# Library name
|
21
|
+
LIB = libkhetai.so
|
22
|
+
|
23
|
+
# Default target
|
24
|
+
all: $(BUILD_DIR) $(LIB)
|
25
|
+
|
26
|
+
# Create the build directory
|
27
|
+
$(BUILD_DIR):
|
28
|
+
mkdir -p $(BUILD_DIR)
|
29
|
+
|
30
|
+
# Compile the library
|
31
|
+
$(LIB): $(OBJ)
|
32
|
+
$(CC) -shared -o $@ $^ $(CFLAGS)
|
33
|
+
|
34
|
+
# Compile C source files into object files
|
35
|
+
$(BUILD_DIR)/%.o: $(SRC_DIR)%.c
|
36
|
+
$(CC) -c $< -o $@ $(CFLAGS)
|
37
|
+
|
38
|
+
# Include generated dependency files
|
39
|
+
-include $(OBJ:.o=.d)
|
40
|
+
|
41
|
+
# Clean target
|
42
|
+
clean:
|
43
|
+
rm -f $(OBJ) $(LIB) $(BUILD_DIR)/*.d
|
44
|
+
rm -rf $(BUILD_DIR)
|
45
|
+
|
46
|
+
.PHONY: all clean
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# KhetAI Test Harness
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
The KhetAI Test Harness provides a GUI for interacting with the KhetAI library. It is built in C++ using the Fast Light Toolkit (FLTK).
|
6
|
+
|
7
|
+
### Hot Reload KhetAI Lib
|
8
|
+
|
9
|
+
- While the GUI is running, you can edit the AI code and reload it into the app by pressing: `Shift + k`
|
10
|
+
|
11
|
+
### Select and Move Piece
|
12
|
+
|
13
|
+
- **Click** a square with a piece on it.
|
14
|
+
- **Click** another square. If there is a piece on it, the two pieces will swap. Otherwise, the piece from the first square will just move to the newly selected square.
|
15
|
+
|
16
|
+
### Rotate Piece
|
17
|
+
|
18
|
+
- **Arrow Keys**: Rotate a piece after it has been clicked. Use the following keys to rotate the selected piece:
|
19
|
+
- `Left Arrow`: Rotate piece counter-clockwise
|
20
|
+
- `Right Arrow`: Rotate piece clockwise
|
21
|
+
|
22
|
+
### Fire the Laser
|
23
|
+
|
24
|
+
- `Space`: Fires the laser from whichever is selected. This is just used for visualization purposes.
|
25
|
+
|
26
|
+
### Request AI Move
|
27
|
+
|
28
|
+
- `Enter`: Uses `khetai_lib` to determine a move for Red. The pieces will move and the laser will fire automatically once it finishes.
|
29
|
+
|
30
|
+
### Reset Pieces
|
31
|
+
|
32
|
+
- Reset all pieces back to their original places by pressing: `r`
|
33
|
+
|
34
|
+

|
@@ -0,0 +1,93 @@
|
|
1
|
+
#include "ai_loader.h"
|
2
|
+
|
3
|
+
AILoader::AILoader(const std::string &lib_path) : handle(nullptr)
|
4
|
+
{
|
5
|
+
load_library(lib_path);
|
6
|
+
}
|
7
|
+
|
8
|
+
AILoader::~AILoader()
|
9
|
+
{
|
10
|
+
if (handle)
|
11
|
+
{
|
12
|
+
dlclose(handle);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
void AILoader::load_library(const std::string &lib_path)
|
17
|
+
{
|
18
|
+
handle = dlopen(lib_path.c_str(), RTLD_LAZY);
|
19
|
+
if (!handle)
|
20
|
+
{
|
21
|
+
throw std::runtime_error("Failed to load KhetAI: " + std::string(dlerror()));
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
void AILoader::reload_library(const std::string &lib_path)
|
26
|
+
{
|
27
|
+
if (handle)
|
28
|
+
{
|
29
|
+
dlclose(handle);
|
30
|
+
}
|
31
|
+
load_library(lib_path);
|
32
|
+
}
|
33
|
+
|
34
|
+
void *AILoader::get_symbol(const std::string &symbol_name)
|
35
|
+
{
|
36
|
+
void *symbol = dlsym(handle, symbol_name.c_str());
|
37
|
+
check_error();
|
38
|
+
return symbol;
|
39
|
+
}
|
40
|
+
|
41
|
+
void AILoader::check_error()
|
42
|
+
{
|
43
|
+
const char *error = dlerror();
|
44
|
+
if (error)
|
45
|
+
{
|
46
|
+
throw std::runtime_error("Error in dynamic loading: " + std::string(error));
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
void (*AILoader::get_init_zobrist())()
|
51
|
+
{
|
52
|
+
return reinterpret_cast<void (*)()>(get_symbol("init_zobrist"));
|
53
|
+
}
|
54
|
+
|
55
|
+
void (*AILoader::get_setup_board())(char **)
|
56
|
+
{
|
57
|
+
return reinterpret_cast<void (*)(char **)>(get_symbol("setup_board"));
|
58
|
+
}
|
59
|
+
|
60
|
+
void (*AILoader::get_print_board())()
|
61
|
+
{
|
62
|
+
return reinterpret_cast<void (*)()>(get_symbol("print_board"));
|
63
|
+
}
|
64
|
+
|
65
|
+
void (*AILoader::get_set_time_parameters())(int, time_t)
|
66
|
+
{
|
67
|
+
return reinterpret_cast<void (*)(int, time_t)>(get_symbol("set_time_parameters"));
|
68
|
+
}
|
69
|
+
|
70
|
+
Move (*AILoader::get_alphabeta_root())(int, enum Player)
|
71
|
+
{
|
72
|
+
return reinterpret_cast<Move (*)(int, enum Player)>(get_symbol("alphabeta_root"));
|
73
|
+
}
|
74
|
+
|
75
|
+
void (*AILoader::get_make_move())(Move)
|
76
|
+
{
|
77
|
+
return reinterpret_cast<void (*)(Move)>(get_symbol("make_move"));
|
78
|
+
}
|
79
|
+
|
80
|
+
int (*AILoader::get_get_start())(Move)
|
81
|
+
{
|
82
|
+
return reinterpret_cast<int (*)(Move)>(get_symbol("get_start_wrapper"));
|
83
|
+
}
|
84
|
+
|
85
|
+
int (*AILoader::get_get_end())(Move)
|
86
|
+
{
|
87
|
+
return reinterpret_cast<int (*)(Move)>(get_symbol("get_end_wrapper"));
|
88
|
+
}
|
89
|
+
|
90
|
+
int (*AILoader::get_get_rotation())(Move)
|
91
|
+
{
|
92
|
+
return reinterpret_cast<int (*)(Move)>(get_symbol("get_rotation_wrapper"));
|
93
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#ifndef AI_LOADER_H
|
2
|
+
#define AI_LOADER_H
|
3
|
+
|
4
|
+
#include <dlfcn.h>
|
5
|
+
#include <stdexcept>
|
6
|
+
#include <string>
|
7
|
+
#include "../../khetai_lib.h"
|
8
|
+
|
9
|
+
class AILoader
|
10
|
+
{
|
11
|
+
public:
|
12
|
+
AILoader(const std::string &lib_path);
|
13
|
+
~AILoader();
|
14
|
+
|
15
|
+
void (*get_init_zobrist())();
|
16
|
+
void (*get_setup_board())(char **);
|
17
|
+
void (*get_print_board())();
|
18
|
+
void (*get_set_time_parameters())(int, time_t);
|
19
|
+
Move (*get_alphabeta_root())(int, enum Player);
|
20
|
+
void (*get_make_move())(Move);
|
21
|
+
int (*get_get_start())(Move);
|
22
|
+
int (*get_get_end())(Move);
|
23
|
+
int (*get_get_rotation())(Move);
|
24
|
+
void reload_library(const std::string &lib_path);
|
25
|
+
|
26
|
+
private:
|
27
|
+
void *handle;
|
28
|
+
void load_library(const std::string &lib_path);
|
29
|
+
void *get_symbol(const std::string &symbol_name);
|
30
|
+
void check_error();
|
31
|
+
};
|
32
|
+
|
33
|
+
#endif // AI_LOADER_H
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|