khetai 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,18 +35,16 @@ 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();
47
+ auto reset_undo = ai_loader.get_reset_undo();
57
48
  auto setup_board = ai_loader.get_setup_board();
58
49
  auto print_board = ai_loader.get_print_board();
59
50
  auto set_time_parameters = ai_loader.get_set_time_parameters();
@@ -65,6 +56,7 @@ Move call_ai_move(AILoader &ai_loader, const std::vector<std::vector<std::string
65
56
 
66
57
  char **c_board = vector_to_c_array(flatten_2d_vector_with_buffer(board_pieces));
67
58
 
59
+ reset_undo();
68
60
  init_zobrist();
69
61
  srand((unsigned)time(NULL));
70
62
 
@@ -78,8 +70,7 @@ Move call_ai_move(AILoader &ai_loader, const std::vector<std::vector<std::string
78
70
  int depth = 1;
79
71
  Move best_move = (Move)0;
80
72
  Move current_move = (Move)0;
81
- while (depth <= max_depth)
82
- {
73
+ while (depth <= max_depth) {
83
74
  printf("\nDEPTH: %-3d-> ", depth);
84
75
  current_move = alphabeta_root(depth, player);
85
76
  printf("MOVE -> START: %d, END: %d, ROTATION: %d\n", get_start(current_move), get_end(current_move), get_rotation(current_move));
@@ -104,8 +95,7 @@ Move call_ai_move(AILoader &ai_loader, const std::vector<std::vector<std::string
104
95
  return best_move;
105
96
  }
106
97
 
107
- void get_row_col(int index, int &row, int &col)
108
- {
98
+ void get_row_col(int index, int &row, int &col) {
109
99
  int border_width = 1;
110
100
  int width_with_border = 10 + 2 * border_width;
111
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
  }