khetai 0.2.3 → 0.3.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.
@@ -3,51 +3,45 @@
3
3
 
4
4
  #include "ai_loader.h"
5
5
 
6
- #include <FL/Fl_Widget.H>
7
- #include <FL/Fl_PNG_Image.H>
8
6
  #include <FL/Fl_Input.H>
7
+ #include <FL/Fl_PNG_Image.H>
8
+ #include <FL/Fl_Widget.H>
9
9
  #include <string>
10
- #include <vector>
11
10
  #include <unordered_map>
11
+ #include <vector>
12
12
 
13
- class GameBoard : public Fl_Widget
14
- {
15
- public:
13
+ class GameBoard : public Fl_Widget {
14
+ public:
16
15
  GameBoard(int X, int Y, int W, int H, const char *L = 0);
17
16
  Fl_Input *max_time_input, *max_depth_input;
18
17
  void draw() override;
19
18
  int handle(int event) override;
20
19
  void init(const std::vector<std::vector<std::string>> &pieces);
21
20
 
22
- enum Color
23
- {
21
+ enum Color {
24
22
  SILVER = 1,
25
23
  RED = 2
26
24
  };
27
- enum LaserDirection
28
- {
25
+ enum LaserDirection {
29
26
  NORTH = 1,
30
27
  EAST = 2,
31
28
  SOUTH = 3,
32
29
  WEST = 4
33
30
  };
34
- enum PieceType
35
- {
31
+ enum PieceType {
36
32
  ANUBIS,
37
33
  PYRAMID,
38
34
  SCARAB,
39
35
  PHARAOH,
40
36
  SPHINX
41
37
  };
42
- enum PieceOrientation
43
- {
38
+ enum PieceOrientation {
44
39
  ORIENT_NORTH,
45
40
  ORIENT_EAST,
46
41
  ORIENT_SOUTH,
47
42
  ORIENT_WEST
48
43
  };
49
- enum ReflectionResult
50
- {
44
+ enum ReflectionResult {
51
45
  RESULT_DEAD,
52
46
  RESULT_ABSORBED,
53
47
  RESULT_EAST,
@@ -55,8 +49,7 @@ public:
55
49
  RESULT_SOUTH,
56
50
  RESULT_NORTH
57
51
  };
58
- enum MovePermission
59
- {
52
+ enum MovePermission {
60
53
  S = 1,
61
54
  R = 2,
62
55
  B = 3
@@ -66,7 +59,7 @@ public:
66
59
  static std::pair<PieceType, PieceOrientation> getPieceTypeAndOrientation(const std::string &piece_str);
67
60
  static void laser_timer_cb(void *data);
68
61
 
69
- private:
62
+ private:
70
63
  AILoader ai_loader;
71
64
  int rows = 8, cols = 10, clicked_row = -1, clicked_col = -1, square_selected_num = -1;
72
65
  int cell_width, cell_height;
@@ -1,28 +1,23 @@
1
1
  #include "game_board_util.h"
2
2
 
3
- #include <iostream>
4
3
  #include <cstring>
4
+ #include <iostream>
5
5
 
6
- std::vector<std::string> flatten_2d_vector_with_buffer(const std::vector<std::vector<std::string>> &vec2d)
7
- {
6
+ std::vector<std::string> flatten_2d_vector_with_buffer(const std::vector<std::vector<std::string>> &vec2d) {
8
7
  size_t new_rows = vec2d.size() + 2;
9
8
  size_t new_cols = vec2d.empty() ? 0 : vec2d[0].size() + 2;
10
9
 
11
10
  std::vector<std::vector<std::string>> buffered_vec2d(new_rows, std::vector<std::string>(new_cols, "--"));
12
11
 
13
- for (size_t i = 0; i < vec2d.size(); ++i)
14
- {
15
- for (size_t j = 0; j < vec2d[i].size(); ++j)
16
- {
12
+ for (size_t i = 0; i < vec2d.size(); ++i) {
13
+ for (size_t j = 0; j < vec2d[i].size(); ++j) {
17
14
  buffered_vec2d[i + 1][j + 1] = vec2d[i][j];
18
15
  }
19
16
  }
20
17
 
21
18
  std::vector<std::string> flattened;
22
- for (const auto &row : buffered_vec2d)
23
- {
24
- for (const auto &elem : row)
25
- {
19
+ for (const auto &row : buffered_vec2d) {
20
+ for (const auto &elem : row) {
26
21
  flattened.push_back(elem);
27
22
  }
28
23
  }
@@ -30,11 +25,9 @@ std::vector<std::string> flatten_2d_vector_with_buffer(const std::vector<std::ve
30
25
  return flattened;
31
26
  }
32
27
 
33
- char **vector_to_c_array(const std::vector<std::string> &vec)
34
- {
28
+ char **vector_to_c_array(const std::vector<std::string> &vec) {
35
29
  char **c_array = new char *[vec.size()];
36
- for (size_t i = 0; i < vec.size(); ++i)
37
- {
30
+ for (size_t i = 0; i < vec.size(); ++i) {
38
31
  c_array[i] = new char[vec[i].size() + 1];
39
32
  std::strcpy(c_array[i], vec[i].c_str());
40
33
  }
@@ -42,17 +35,14 @@ char **vector_to_c_array(const std::vector<std::string> &vec)
42
35
  return c_array;
43
36
  }
44
37
 
45
- void free_c_array(char **c_array, size_t size)
46
- {
47
- for (size_t i = 0; i < size; ++i)
48
- {
38
+ void free_c_array(char **c_array, size_t size) {
39
+ for (size_t i = 0; i < size; ++i) {
49
40
  delete[] c_array[i];
50
41
  }
51
42
  delete[] c_array;
52
43
  }
53
44
 
54
- Move call_ai_move(AILoader &ai_loader, const std::vector<std::vector<std::string>> &board_pieces, Player player, int max_depth, int max_time)
55
- {
45
+ Move call_ai_move(AILoader &ai_loader, const std::vector<std::vector<std::string>> &board_pieces, Player player, int max_depth, int max_time) {
56
46
  auto init_zobrist = ai_loader.get_init_zobrist();
57
47
  auto reset_undo = ai_loader.get_reset_undo();
58
48
  auto setup_board = ai_loader.get_setup_board();
@@ -80,8 +70,7 @@ Move call_ai_move(AILoader &ai_loader, const std::vector<std::vector<std::string
80
70
  int depth = 1;
81
71
  Move best_move = (Move)0;
82
72
  Move current_move = (Move)0;
83
- while (depth <= max_depth)
84
- {
73
+ while (depth <= max_depth) {
85
74
  printf("\nDEPTH: %-3d-> ", depth);
86
75
  current_move = alphabeta_root(depth, player);
87
76
  printf("MOVE -> START: %d, END: %d, ROTATION: %d\n", get_start(current_move), get_end(current_move), get_rotation(current_move));
@@ -106,8 +95,7 @@ Move call_ai_move(AILoader &ai_loader, const std::vector<std::vector<std::string
106
95
  return best_move;
107
96
  }
108
97
 
109
- void get_row_col(int index, int &row, int &col)
110
- {
98
+ void get_row_col(int index, int &row, int &col) {
111
99
  int border_width = 1;
112
100
  int width_with_border = 10 + 2 * border_width;
113
101
 
@@ -3,8 +3,8 @@
3
3
 
4
4
  #include "ai_loader.h"
5
5
 
6
- #include <vector>
7
6
  #include <string>
7
+ #include <vector>
8
8
 
9
9
  std::vector<std::string> flatten_2d_vector_with_buffer(const std::vector<std::vector<std::string>> &vec2d);
10
10
  char **vector_to_c_array(const std::vector<std::string> &vec);
@@ -1,24 +1,20 @@
1
+ #include "game_board.h"
1
2
  #include <FL/Fl.H>
3
+ #include <FL/Fl_Box.H>
2
4
  #include <FL/Fl_Double_Window.H>
3
5
  #include <FL/Fl_Input.H>
4
6
  #include <FL/Fl_Int_Input.H>
5
- #include <FL/Fl_Box.H>
6
- #include "game_board.h"
7
7
 
8
- class PositiveIntInput : public Fl_Int_Input
9
- {
10
- public:
8
+ class PositiveIntInput : public Fl_Int_Input {
9
+ public:
11
10
  PositiveIntInput(int X, int Y, int W, int H, const char *L = 0)
12
11
  : Fl_Int_Input(X, Y, W, H, L) {}
13
12
 
14
- int handle(int event) override
15
- {
13
+ int handle(int event) override {
16
14
  int result = Fl_Int_Input::handle(event);
17
- if (event == FL_KEYDOWN || event == FL_KEYUP || event == FL_PASTE)
18
- {
15
+ if (event == FL_KEYDOWN || event == FL_KEYUP || event == FL_PASTE) {
19
16
  const char *value = this->value();
20
- if (value[0] == '-')
21
- {
17
+ if (value[0] == '-') {
22
18
  this->value("");
23
19
  }
24
20
  }
@@ -26,8 +22,7 @@ public:
26
22
  }
27
23
  };
28
24
 
29
- int main(int argc, char **argv)
30
- {
25
+ int main(int argc, char **argv) {
31
26
  Fl_Double_Window *window = new Fl_Double_Window(800, 600, "Khet AI");
32
27
  GameBoard *board = new GameBoard(50, 50, 700, 504);
33
28
 
@@ -50,7 +45,7 @@ int main(int argc, char **argv)
50
45
 
51
46
  Fl_Box *max_depth_label = new Fl_Box(250, 10, 80, 30, "Max Depth:");
52
47
  PositiveIntInput *max_depth_input = new PositiveIntInput(325, 15, 30, 20);
53
- max_depth_input->value("10");
48
+ max_depth_input->value("25");
54
49
  board->max_depth_input = max_depth_input;
55
50
 
56
51
  window->end();
@@ -1,7 +1,7 @@
1
+ #include "../khetai_lib.h"
1
2
  #include <stdio.h>
2
3
  #include <stdlib.h>
3
4
  #include <time.h>
4
- #include "../khetai_lib.h"
5
5
 
6
6
  char *init_board[120] =
7
7
  {"--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--",
@@ -15,8 +15,7 @@ char *init_board[120] =
15
15
  "--", "--", "--", "p3", "a0", "x0", "a0", "--", "--", "--", "l0", "--",
16
16
  "--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--"};
17
17
 
18
- int main()
19
- {
18
+ int main() {
20
19
  init_zobrist();
21
20
  srand((unsigned)time(NULL));
22
21
 
@@ -31,9 +30,8 @@ int main()
31
30
  int depth = 1;
32
31
  Move best_move = (Move)0;
33
32
  Move current_move = (Move)0;
34
- while (depth <= max_depth)
35
- {
36
- current_move = alphabeta_root(depth, Red);
33
+ while (depth <= max_depth) {
34
+ current_move = alphabeta_root(depth, RED);
37
35
  if (time(NULL) - start_time < max_time)
38
36
  best_move = current_move;
39
37
  else
data/ext/khetai/khetai.c CHANGED
@@ -1,26 +1,22 @@
1
+ #include "khetai_lib.h"
1
2
  #include <ruby.h>
2
3
  #include <stdlib.h>
3
4
  #include <time.h>
4
- #include "khetai_lib.h"
5
5
 
6
- VALUE move(VALUE self, VALUE board_array, VALUE _player, VALUE _max_depth, VALUE _max_time)
7
- {
6
+ VALUE move(VALUE self, VALUE board_array, VALUE _player, VALUE _max_depth, VALUE _max_time) {
8
7
  // verify parameters
9
8
  int player = NUM2INT(_player);
10
- if (player < 0 || player > 1)
11
- {
9
+ if (player < 0 || player > 1) {
12
10
  rb_raise(rb_eArgError, "player must be 0 (silver) or 1 (red)");
13
11
  }
14
12
 
15
13
  int max_time = NUM2INT(_max_time);
16
- if (max_time < 1)
17
- {
14
+ if (max_time < 1) {
18
15
  rb_raise(rb_eArgError, "max_time (seconds) must be 1 or greater");
19
16
  }
20
17
 
21
18
  int max_depth = NUM2INT(_max_depth);
22
- if (max_depth < 2 || max_depth > 25)
23
- {
19
+ if (max_depth < 2 || max_depth > 25) {
24
20
  rb_raise(rb_eArgError, "max_depth (ply) must be between 2 and 25");
25
21
  }
26
22
 
@@ -29,33 +25,27 @@ VALUE move(VALUE self, VALUE board_array, VALUE _player, VALUE _max_depth, VALUE
29
25
  unsigned int array_size = (unsigned int)RARRAY_LEN(board_array);
30
26
 
31
27
  // verify board_array is valid
32
- if (array_size != 80)
33
- {
28
+ if (array_size != 80) {
34
29
  rb_raise(rb_eArgError, "board_array must have exactly 80 elements");
35
30
  }
36
31
  const char valid_pieces[] = {'L', 'A', 'X', 'P', 'S', 'p', 'a', 'x', 's', 'l'};
37
32
  size_t valid_pieces_count = 10;
38
- for (unsigned int i = 0; i < array_size; i++)
39
- {
33
+ for (unsigned int i = 0; i < array_size; i++) {
40
34
  VALUE element = rb_ary_entry(board_array, i);
41
- if (!RB_TYPE_P(element, T_STRING) || RSTRING_LEN(element) != 2)
42
- {
35
+ if (!RB_TYPE_P(element, T_STRING) || RSTRING_LEN(element) != 2) {
43
36
  rb_raise(rb_eArgError, "each element in board_array must be 2 characters");
44
37
  }
45
38
 
46
39
  // check if element in board_array is a valid string
47
40
  const char *element_str = RSTRING_PTR(element);
48
41
  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
- {
42
+ for (unsigned int j = 0; j < valid_pieces_count; j++) {
43
+ if ((element_str[0] == valid_pieces[j] && element_str[1] >= '0' && element_str[1] <= '3') || strcmp(element_str, "--") == 0) {
53
44
  is_valid = 1;
54
45
  break;
55
46
  }
56
47
  }
57
- if (!is_valid)
58
- {
48
+ if (!is_valid) {
59
49
  rb_raise(rb_eArgError, "each element in board_array must be a valid piece (example: 'p1') or empty ('--')");
60
50
  }
61
51
  }
@@ -64,22 +54,19 @@ VALUE move(VALUE self, VALUE board_array, VALUE _player, VALUE _max_depth, VALUE
64
54
  char *init_board[120];
65
55
 
66
56
  // top and bottom row padding
67
- for (unsigned int i = 0; i < 12; i++)
68
- {
57
+ for (unsigned int i = 0; i < 12; i++) {
69
58
  init_board[i] = "--";
70
59
  init_board[108 + i] = "--";
71
60
  }
72
61
 
73
62
  // left and right column padding
74
- for (unsigned int i = 0; i < 8; i++)
75
- {
63
+ for (unsigned int i = 0; i < 8; i++) {
76
64
  init_board[12 * (i + 1)] = "--";
77
65
  init_board[12 * (i + 2) - 1] = "--";
78
66
  }
79
67
 
80
68
  // fill in the rest of the board passed from ruby
81
- for (unsigned int i = 0; i < array_size; i++)
82
- {
69
+ for (unsigned int i = 0; i < array_size; i++) {
83
70
  VALUE square = rb_ary_entry(board_array, i);
84
71
  init_board[13 + ((i % 10) + ((i / 10) * 12))] = StringValueCStr(square);
85
72
  }
@@ -95,8 +82,7 @@ VALUE move(VALUE self, VALUE board_array, VALUE _player, VALUE _max_depth, VALUE
95
82
  int depth = 1;
96
83
  Move best_move = (Move)0;
97
84
  Move current_move = (Move)0;
98
- while ((time(NULL) - start_time < max_time) && (depth <= max_depth))
99
- {
85
+ while ((time(NULL) - start_time < max_time) && (depth <= max_depth)) {
100
86
  best_move = current_move;
101
87
  current_move = alphabeta_root(depth, player);
102
88
  depth++;
@@ -111,8 +97,7 @@ VALUE move(VALUE self, VALUE board_array, VALUE _player, VALUE _max_depth, VALUE
111
97
  return out;
112
98
  }
113
99
 
114
- void Init_khetai()
115
- {
100
+ void Init_khetai() {
116
101
  VALUE KhetAI = rb_define_module("KhetAI");
117
102
  rb_define_singleton_method(KhetAI, "move", move, 4);
118
103
  }