为五子棋游戏实现有限的极大极小搜索和有限的alpha-beta搜索方法,使用固定深度的递归DEPTH_LIMIT和非终端状态的启发式评估
时间: 2023-05-20 11:01:35 浏览: 110
基于ALPHA-BETA算法的五子棋程序
以下是一个五子棋游戏的实现,包括有限的极大极小搜索和有限的alpha-beta搜索方法,使用固定深度的递归DEPTH_LIMIT和非终端状态的启发式评估:
```
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int BOARD_SIZE = 15;
const int DEPTH_LIMIT = 3;
const int INF = 1e9;
enum class Player {
BLACK,
WHITE
};
enum class State {
EMPTY,
BLACK,
WHITE
};
struct Point {
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y) {}
};
struct Board {
State board[BOARD_SIZE][BOARD_SIZE];
Board() {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
board[i][j] = State::EMPTY;
}
}
}
bool is_valid(const Point& p) const {
return p.x >= 0 && p.x < BOARD_SIZE && p.y >= 0 && p.y < BOARD_SIZE;
}
bool is_empty(const Point& p) const {
return board[p.x][p.y] == State::EMPTY;
}
void set(const Point& p, State s) {
board[p.x][p.y] = s;
}
State get(const Point& p) const {
return board[p.x][p.y];
}
bool is_win(const Point& p, State s) const {
int dx[4] = {1, 0, 1, -1};
int dy[4] = {0, 1, 1, 1};
for (int i = 0; i < 4; i++) {
int cnt = 1;
Point q = p;
while (true) {
q.x += dx[i];
q.y += dy[i];
if (!is_valid(q) || get(q) != s) break;
cnt++;
}
q = p;
while (true) {
q.x -= dx[i];
q.y -= dy[i];
if (!is_valid(q) || get(q) != s) break;
cnt++;
}
if (cnt >= 5) return true;
}
return false;
}
};
int evaluate(const Board& board, State s) {
int score = 0;
int dx[4] = {1, 0, 1, -1};
int dy[4] = {0, 1, 1, 1};
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board.get(Point(i, j)) == s) {
for (int k = 0; k < 4; k++) {
int cnt = 1;
Point p(i, j);
while (true) {
p.x += dx[k];
p.y += dy[k];
if (!board.is_valid(p) || board.get(p) != s) break;
cnt++;
}
p = Point(i, j);
while (true) {
p.x -= dx[k];
p.y -= dy[k];
if (!board.is_valid(p) || board.get(p) != s) break;
cnt++;
}
if (cnt >= 5) score += 10000;
else score += cnt * cnt;
}
}
}
}
return score;
}
int max_value(Board& board, int depth, int alpha, int beta, State s) {
if (depth == DEPTH_LIMIT) {
return evaluate(board, s);
}
int max_score = -INF;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
Point p(i, j);
if (board.is_empty(p)) {
board.set(p, s);
int score = min_value(board, depth + 1, alpha, beta, s == State::BLACK ? State::WHITE : State::BLACK);
board.set(p, State::EMPTY);
max_score = max(max_score, score);
alpha = max(alpha, score);
if (beta <= alpha) {
return max_score;
}
}
}
}
return max_score;
}
int min_value(Board& board, int depth, int alpha, int beta, State s) {
if (depth == DEPTH_LIMIT) {
return evaluate(board, s);
}
int min_score = INF;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
Point p(i, j);
if (board.is_empty(p)) {
board.set(p, s);
int score = max_value(board, depth + 1, alpha, beta, s == State::BLACK ? State::WHITE : State::BLACK);
board.set(p, State::EMPTY);
min_score = min(min_score, score);
beta = min(beta, score);
if (beta <= alpha) {
return min_score;
}
}
}
}
return min_score;
}
Point find_best_move(const Board& board, State s) {
int max_score = -INF;
Point best_move;
Board tmp_board = board;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
Point p(i, j);
if (board.is_empty(p)) {
tmp_board.set(p, s);
int score = min_value(tmp_board, 0, -INF, INF, s == State::BLACK ? State::WHITE : State::BLACK);
tmp_board.set(p, State::EMPTY);
if (score > max_score) {
max_score = score;
best_move = p;
}
}
}
}
return best_move;
}
int main() {
Board board;
Player player = Player::BLACK;
while (true) {
if (player == Player::BLACK) {
cout << "Black's turn:" << endl;
Point p = find_best_move(board, State::BLACK);
board.set(p, State::BLACK);
cout << "Black plays at (" << p.x << ", " << p.y << ")" << endl;
if (board.is_win(p, State::BLACK)) {
cout << "Black wins!" << endl;
break;
}
player = Player::WHITE;
} else {
cout << "White's turn:" << endl;
Point p = find_best_move(board, State::WHITE);
board.set(p, State::WHITE);
cout << "White plays at (" << p.x << ", " << p.y << ")" << endl;
if (board.is_win(p, State::WHITE)) {
cout << "White wins!" << endl;
break;
}
player = Player::BLACK;
}
}
return 0;
}
```
这个实现使用了一个简单的启发式评估函数,它会计算每个棋子的得分,得分越高表示越有利。在极大极小搜索和alpha-beta搜索中,它会尽可能地选择得分高的走法。
阅读全文