khetai 0.1.7 → 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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/Gemfile.lock +2 -2
  4. data/README.md +36 -22
  5. data/ext/khetai/dev/README.md +15 -0
  6. data/ext/khetai/dev/fltk-ui/Makefile +65 -0
  7. data/ext/khetai/dev/fltk-ui/Makefile.khetai +46 -0
  8. data/ext/khetai/dev/fltk-ui/README.md +34 -0
  9. data/ext/khetai/dev/fltk-ui/ai_loader.cpp +93 -0
  10. data/ext/khetai/dev/fltk-ui/ai_loader.h +33 -0
  11. data/ext/khetai/dev/fltk-ui/assets/anubis_red_e.png +0 -0
  12. data/ext/khetai/dev/fltk-ui/assets/anubis_red_n.png +0 -0
  13. data/ext/khetai/dev/fltk-ui/assets/anubis_red_s.png +0 -0
  14. data/ext/khetai/dev/fltk-ui/assets/anubis_red_w.png +0 -0
  15. data/ext/khetai/dev/fltk-ui/assets/anubis_silver_e.png +0 -0
  16. data/ext/khetai/dev/fltk-ui/assets/anubis_silver_n.png +0 -0
  17. data/ext/khetai/dev/fltk-ui/assets/anubis_silver_s.png +0 -0
  18. data/ext/khetai/dev/fltk-ui/assets/anubis_silver_w.png +0 -0
  19. data/ext/khetai/dev/fltk-ui/assets/example_board.png +0 -0
  20. data/ext/khetai/dev/fltk-ui/assets/laser_red_e.png +0 -0
  21. data/ext/khetai/dev/fltk-ui/assets/laser_red_n.png +0 -0
  22. data/ext/khetai/dev/fltk-ui/assets/laser_red_s.png +0 -0
  23. data/ext/khetai/dev/fltk-ui/assets/laser_red_w.png +0 -0
  24. data/ext/khetai/dev/fltk-ui/assets/laser_silver_e.png +0 -0
  25. data/ext/khetai/dev/fltk-ui/assets/laser_silver_n.png +0 -0
  26. data/ext/khetai/dev/fltk-ui/assets/laser_silver_s.png +0 -0
  27. data/ext/khetai/dev/fltk-ui/assets/laser_silver_w.png +0 -0
  28. data/ext/khetai/dev/fltk-ui/assets/pharaoh_red.png +0 -0
  29. data/ext/khetai/dev/fltk-ui/assets/pharaoh_silver.png +0 -0
  30. data/ext/khetai/dev/fltk-ui/assets/pyramid_red_e.png +0 -0
  31. data/ext/khetai/dev/fltk-ui/assets/pyramid_red_n.png +0 -0
  32. data/ext/khetai/dev/fltk-ui/assets/pyramid_red_s.png +0 -0
  33. data/ext/khetai/dev/fltk-ui/assets/pyramid_red_w.png +0 -0
  34. data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_e.png +0 -0
  35. data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_n.png +0 -0
  36. data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_s.png +0 -0
  37. data/ext/khetai/dev/fltk-ui/assets/pyramid_silver_w.png +0 -0
  38. data/ext/khetai/dev/fltk-ui/assets/scarab_red_e.png +0 -0
  39. data/ext/khetai/dev/fltk-ui/assets/scarab_red_n.png +0 -0
  40. data/ext/khetai/dev/fltk-ui/assets/scarab_red_s.png +0 -0
  41. data/ext/khetai/dev/fltk-ui/assets/scarab_red_w.png +0 -0
  42. data/ext/khetai/dev/fltk-ui/assets/scarab_silver_e.png +0 -0
  43. data/ext/khetai/dev/fltk-ui/assets/scarab_silver_n.png +0 -0
  44. data/ext/khetai/dev/fltk-ui/assets/scarab_silver_s.png +0 -0
  45. data/ext/khetai/dev/fltk-ui/assets/scarab_silver_w.png +0 -0
  46. data/ext/khetai/dev/fltk-ui/build_khetai.sh +9 -0
  47. data/ext/khetai/dev/fltk-ui/game_board.cpp +896 -0
  48. data/ext/khetai/dev/fltk-ui/game_board.h +105 -0
  49. data/ext/khetai/dev/fltk-ui/game_board_util.cpp +119 -0
  50. data/ext/khetai/dev/fltk-ui/game_board_util.h +15 -0
  51. data/ext/khetai/dev/fltk-ui/khet.cpp +59 -0
  52. data/ext/khetai/dev/main.c +8 -7
  53. data/ext/khetai/dev/main.rb +9 -10
  54. data/ext/khetai/khetai.c +22 -6
  55. data/ext/khetai/khetai_lib.c +24 -13
  56. data/ext/khetai/khetai_lib.h +51 -24
  57. data/lib/khetai/version.rb +1 -1
  58. metadata +50 -4
  59. data/README_ORIGINAL.md +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57b893b2ca7a9ab8690ce116801bbd6286bc5856c7f87d01b7d51a7bbd6cc8f9
4
- data.tar.gz: 433c4c67445b585526e598f6c04c53ca9e3ce67dab012a65aafa9922d18d8a80
3
+ metadata.gz: a32fa87a05f48b757c7e3c601e26313ad9d58d7c2ff773603d89ec8313c7d07b
4
+ data.tar.gz: 47f0883f7445baaf8541b340caff8e929d01ef1fa8c175b859936ecad30c355e
5
5
  SHA512:
6
- metadata.gz: 5e85bedabf5229ac1abad59889e2d2980e0fe194ad42d3acff67fb72817ed6755b59798af3a7312836cc225bb044f1bc12641edb30f4693e37e91144581ac142
7
- data.tar.gz: f7cb8d7735f580752ed50ca8f4cf084a5398bbac70d26b32da6c9a61049de9a79b68aceac685afe5a907ec8bea83ba24e72fcf3c991a88145996c5a8563b85e3
6
+ metadata.gz: 9df12c681f8bfc73d712c5682d483038abc81793d48235af7038dcf75cefa12d84de2c8760f88c036365115a4074d40f877c2707aa8faa38e5b126bf43b10b22
7
+ data.tar.gz: d5663b3a6b7110b86c309530f4dc7cdb019afbaf1c8148a670366088a486bd2406fdc5c49f3c83bd586f2fba8a74cd6e4f5c08f1fb9329697b9b6c8e0bad29f1
data/.gitignore CHANGED
@@ -7,5 +7,10 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /build/
10
+ /ext/khetai/dev/build/
11
+ /ext/khetai/dev/fltk-ui/build/
12
+ /ext/khetai/dev/fltk-ui/build_khetai/
10
13
  .vscode
11
14
  *.so
15
+ *.o
16
+ khet
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- khetai (0.1.7)
4
+ khetai (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -19,4 +19,4 @@ DEPENDENCIES
19
19
  rake-compiler
20
20
 
21
21
  BUNDLED WITH
22
- 2.1.2
22
+ 2.4.21
data/README.md CHANGED
@@ -1,34 +1,31 @@
1
1
  # KhetAI
2
2
 
3
- ## Install
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
- "--", "L2", "--", "--", "--", "A2", "X2", "A2", "P1", "--", "--", "--",
24
- "--", "--", "--", "P2", "--", "--", "--", "--", "--", "--", "--", "--",
25
- "--", "--", "--", "--", "p3", "--", "--", "--", "--", "--", "--", "--",
26
- "--", "P0", "--", "p2", "--", "S2", "S3", "--", "P1", "--", "p3", "--",
27
- "--", "P1", "--", "p3", "--", "s1", "s0", "--", "P0", "--", "p2", "--",
28
- "--", "--", "--", "--", "--", "--", "--", "P1", "--", "--", "--", "--",
29
- "--", "--", "--", "--", "--", "--", "--", "--", "p0", "--", "--", "--",
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
- gem push pkg/<gem>
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
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ cd "$(dirname "$0")"
5
+
6
+ make -f Makefile.khetai clean
7
+ make -f Makefile.khetai
8
+
9
+ echo "KhetAI lib rebuilt successfully"