-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbasic.h
145 lines (106 loc) · 2.58 KB
/
basic.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#pragma once
#include <iostream>
#include <algorithm>
#include <functional>
#include <limits>
#include "util.h"
#include "board.h"
bool greedy_move(BoardState *state, eval_func eval) {
auto valid_moves = state->moves();
if (valid_moves.size() == 0) {
state->apply(PASS);
return false;
}
int player = state->active_player;
Point best_move;
int best_score = std::numeric_limits<int>::min();
for (auto move : valid_moves) {
BoardState next_state(*state);
next_state.apply(move);
int score = eval(&next_state, player);
if (score > best_score) {
best_move = move;
best_score = score;
}
}
state->apply(best_move);
return true;
}
bool random_move(BoardState *state) {
auto valid_moves = state->moves();
if (valid_moves.size() == 0) {
state->apply(PASS);
return false;
}
auto move = valid_moves[rand() % valid_moves.size()];
state->apply(move);
return true;
}
bool io_move(BoardState *state) {
state->print();
auto valid_moves = state->moves();
if (valid_moves.size() == 0) {
state->apply(PASS);
return false;
}
while (true) {
using namespace std;
string cmd;
cout << "Enter move: ";
cin >> cmd;
if (cin.eof()) exit(0);
if (cmd.size() != 2) {
cout << "Bad command" << endl;
continue;
}
int row = int(cmd[1] - '1');
int col = int(cmd[0] - 'a');
if (!BOUNDS(row, col)) {
cout << "Out of bounds" << endl;
continue;
}
Point move(row, col);
if (std::find(valid_moves.begin(), valid_moves.end(), move) == valid_moves.end()) {
cout << "Invalid move" << endl;
continue;
}
state->apply(move);
return true;
}
}
template<typename T>
int rollout_game(const T move_policy_f, BoardState *start_state) {
BoardState state(*start_state);
bool passed = false;
while (true) {
bool pass = !move_policy_f(&state);
if (pass && passed) break;
passed = pass;
}
return state.winner();
}
int eval_pieces(BoardState *state, int player) {
int s = 0;
for (int i = 0; i < BOARD_H; ++i)
for (int j = 0; j < BOARD_W; ++j)
if (state->board[i][j] == player)
++s;
return s;
}
int eval_inv_pieces(BoardState *state, int player) {
int s = 0;
for (int i = 0; i < BOARD_H; ++i)
for (int j = 0; j < BOARD_W; ++j)
if (state->board[i][j] == player)
--s;
return s;
}
int eval_sampling(BoardState *state, int player, int samples) {
int s = 0;
for (int i = 0; i < samples; ++i) {
if (rollout_game(random_move, state) == player) {
s++;
}
}
return s;
}