khetai 0.1.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/Gemfile.lock +2 -2
- data/README.md +36 -22
- 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 +24 -13
- data/ext/khetai/khetai_lib.h +51 -24
- data/lib/khetai/version.rb +1 -1
- metadata +50 -4
- data/README_ORIGINAL.md +0 -40
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
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,34 +1,31 @@
|
|
1
1
|
# KhetAI
|
2
2
|
|
3
|
-
##
|
4
|
-
|
5
|
-
gem install khetai
|
6
|
-
```
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
$ gem install khetai
|
7
6
|
|
8
7
|
## Usage
|
9
|
-
```
|
8
|
+
```ruby
|
10
9
|
require 'khetai'
|
11
10
|
move = KhetAI.move(board, whose_turn, max_search_depth, max_search_time)
|
12
11
|
```
|
13
12
|
|
14
13
|
## Example
|
15
|
-
```
|
14
|
+
```ruby
|
16
15
|
require 'khetai'
|
17
16
|
|
18
17
|
# initial board setup:
|
19
18
|
# A = anubis, P = pyramid, S = scarab, X = pharaoh, L = sphinx
|
20
19
|
# capital letters = red, lowercase letters = silver
|
21
20
|
# 0 = north, 1 = east, 2 = south, 3 = west
|
22
|
-
board = ["
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
"--", "--", "--", "p3", "a0", "x0", "a0", "--", "--", "--", "l0", "--",
|
31
|
-
"--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--"]
|
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"]
|
32
29
|
|
33
30
|
whose_turn = 1 # silver = 0, red = 1
|
34
31
|
max_search_depth = 25 # must be between 2 and 25
|
@@ -42,11 +39,28 @@ move = KhetAI.move(board, whose_turn, max_search_depth, max_search_time)
|
|
42
39
|
# move[2] = rotation (1, -1, 0) (clockwise, anticlockwise, none)
|
43
40
|
```
|
44
41
|
|
42
|
+
The representation of the board gets converted an array of 8-bit integers once it is passed to the gem.
|
43
|
+
|
44
|
+
## Development
|
45
|
+
|
46
|
+
The internals of the gem are written in C, located in `ext/khetai`.
|
47
|
+
|
45
48
|
## Build and Deploy Commands
|
46
|
-
```
|
47
|
-
bundle exec rake compile
|
48
|
-
bundle exec rake build
|
49
|
-
bundle exec rake release
|
50
49
|
|
51
|
-
|
52
|
-
|
50
|
+
$ bundle exec rake compile
|
51
|
+
$ bundle exec rake build
|
52
|
+
$ gem install pkg/khetai-<version>.gem
|
53
|
+
|
54
|
+
|
55
|
+
To release and push to rubygems.org:
|
56
|
+
|
57
|
+
$ bundle exec rake release
|
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
|
+
![board](assets/example_board.png)
|
@@ -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
|