khetai 0.2.0 → 0.2.1
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/Gemfile.lock +1 -1
- data/ext/khetai/dev/fltk-ui/README.md +2 -2
- data/ext/khetai/dev/main.rb +1 -1
- data/ext/khetai/khetai.c +57 -6
- data/lib/khetai/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1883bbf3758483b6771f1fce6c7ff1c9bc6625a88035ca57f71efb7e03b25e9d
|
4
|
+
data.tar.gz: 62a0eb4c822754885c6e92d4ad07a78301e6d566b2f804e4fb03db31f4192a6a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcd3d8db78079c7373a228f53408444341d43f5abbc96402d5775cd3f379554b3790152bd7dc1d17604d956dcf2d07329149098a89f6d54df94222f4a6b6c637
|
7
|
+
data.tar.gz: c1e1ca8ce28b5e690720de15a32af6938970ad6b86fa759bd8cee1f101f8d607642f0d05b6861f8507794e3950e69a03cd76797121d3038ec19193fda36ba6cf
|
data/Gemfile.lock
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## Overview
|
4
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).
|
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](https://www.fltk.org/)).
|
6
6
|
|
7
7
|
### Hot Reload KhetAI Lib
|
8
8
|
|
@@ -31,4 +31,4 @@ The KhetAI Test Harness provides a GUI for interacting with the KhetAI library.
|
|
31
31
|
|
32
32
|
- Reset all pieces back to their original places by pressing: `r`
|
33
33
|
|
34
|
-

|
34
|
+

|
data/ext/khetai/dev/main.rb
CHANGED
data/ext/khetai/khetai.c
CHANGED
@@ -3,13 +3,65 @@
|
|
3
3
|
#include <time.h>
|
4
4
|
#include "khetai_lib.h"
|
5
5
|
|
6
|
-
VALUE move(VALUE self, VALUE board_array, VALUE
|
6
|
+
VALUE move(VALUE self, VALUE board_array, VALUE _player, VALUE _max_depth, VALUE _max_time)
|
7
7
|
{
|
8
|
+
// verify parameters
|
9
|
+
int player = NUM2INT(_player);
|
10
|
+
if (player < 0 || player > 1)
|
11
|
+
{
|
12
|
+
rb_raise(rb_eArgError, "player must be 0 (silver) or 1 (red)");
|
13
|
+
}
|
14
|
+
|
15
|
+
int max_time = NUM2INT(_max_time);
|
16
|
+
if (max_time < 1)
|
17
|
+
{
|
18
|
+
rb_raise(rb_eArgError, "max_time (seconds) must be 1 or greater");
|
19
|
+
}
|
20
|
+
|
21
|
+
int max_depth = NUM2INT(_max_depth);
|
22
|
+
if (max_depth < 2 || max_depth > 25)
|
23
|
+
{
|
24
|
+
rb_raise(rb_eArgError, "max_depth (ply) must be between 2 and 25");
|
25
|
+
}
|
26
|
+
|
8
27
|
srand((unsigned)time(NULL));
|
9
28
|
|
29
|
+
unsigned int array_size = (unsigned int)RARRAY_LEN(board_array);
|
30
|
+
|
31
|
+
// verify board_array is valid
|
32
|
+
if (array_size != 80)
|
33
|
+
{
|
34
|
+
rb_raise(rb_eArgError, "board_array must have exactly 80 elements");
|
35
|
+
}
|
36
|
+
const char valid_pieces[] = {'L', 'A', 'X', 'P', 'S', 'p', 'a', 'x', 's', 'l'};
|
37
|
+
size_t valid_pieces_count = 10;
|
38
|
+
for (unsigned int i = 0; i < array_size; i++)
|
39
|
+
{
|
40
|
+
VALUE element = rb_ary_entry(board_array, i);
|
41
|
+
if (!RB_TYPE_P(element, T_STRING) || RSTRING_LEN(element) != 2)
|
42
|
+
{
|
43
|
+
rb_raise(rb_eArgError, "each element in the board_array must be 2 characters");
|
44
|
+
}
|
45
|
+
|
46
|
+
// check if element in board_array is a valid string
|
47
|
+
const char *element_str = RSTRING_PTR(element);
|
48
|
+
int is_valid = 0;
|
49
|
+
for (unsigned int j = 0; j < valid_pieces_count; j++)
|
50
|
+
{
|
51
|
+
if ((element_str[0] == valid_pieces[j] && element_str[1] >= '0' && element_str[1] <= '3') || strcmp(element_str, "--") == 0)
|
52
|
+
{
|
53
|
+
is_valid = 1;
|
54
|
+
break;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
if (!is_valid)
|
58
|
+
{
|
59
|
+
rb_raise(rb_eArgError, "each element in the board_array must be a valid piece (example: 'p1') or empty ('--')");
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
10
63
|
// khetai_lib assumes an extra level of padding around the board
|
11
64
|
char *init_board[120];
|
12
|
-
unsigned int array_size = (unsigned int)RARRAY_LEN(board_array);
|
13
65
|
|
14
66
|
// top and bottom row padding
|
15
67
|
for (unsigned int i = 0; i < 12; i++)
|
@@ -25,7 +77,7 @@ VALUE move(VALUE self, VALUE board_array, VALUE player, VALUE max_depth, VALUE _
|
|
25
77
|
init_board[12 * (i + 2) - 1] = "--";
|
26
78
|
}
|
27
79
|
|
28
|
-
// fill in the rest of the
|
80
|
+
// fill in the rest of the board passed from ruby
|
29
81
|
for (unsigned int i = 0; i < array_size; i++)
|
30
82
|
{
|
31
83
|
VALUE square = rb_ary_entry(board_array, i);
|
@@ -37,17 +89,16 @@ VALUE move(VALUE self, VALUE board_array, VALUE player, VALUE max_depth, VALUE _
|
|
37
89
|
setup_board(init_board);
|
38
90
|
|
39
91
|
time_t start_time = time(NULL);
|
40
|
-
int max_time = NUM2INT(_max_time);
|
41
92
|
set_time_parameters(max_time, start_time);
|
42
93
|
|
43
94
|
// iterative deepening
|
44
95
|
int depth = 1;
|
45
96
|
Move best_move = (Move)0;
|
46
97
|
Move current_move = (Move)0;
|
47
|
-
while ((time(NULL) - start_time < max_time) && (depth <=
|
98
|
+
while ((time(NULL) - start_time < max_time) && (depth <= max_depth))
|
48
99
|
{
|
49
100
|
best_move = current_move;
|
50
|
-
current_move = alphabeta_root(depth,
|
101
|
+
current_move = alphabeta_root(depth, player);
|
51
102
|
depth++;
|
52
103
|
}
|
53
104
|
make_move(best_move);
|
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.2.1
|
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-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|