#minimax #game-ai #chess-engine #game #alpha-beta-pruning #efficient-minimax

bin+lib minimax-alpha-beta

为任意两人最小-最大游戏(如国际象棋、围棋、井字棋等)实现的Alpha-Beta剪枝+最小-最大算法

9次发布

0.2.0 2022年8月2日
0.1.7 2022年5月30日
0.1.6 2021年5月7日

#533 in 数学

每月 30 次下载

MIT 和可能 GPL-3.0+

30KB
614

最小-最大游戏引擎的实现。

背景

最小-最大游戏是指任何回合制两人游戏,其中一方的目标是最大化评估分数,而对手则试图最小化它。这类游戏的例子包括国际象棋、围棋、井字棋、四子棋等。

在这个crate中,有一个通用的小型-最大游戏引擎实现,可以用于任何此类游戏。最小-最大算法因其速度慢而闻名,我们使用一种称为Alpha-Beta剪枝的剪枝方法来加速它。

最小-最大算法在底层试图模拟双方的所有可能的“最佳”玩法,并根据结果推荐一个应该执行的移动,以最大限度地提高移动方的胜利机会。

有一个缺点,即最小-最大算法太慢(因为它几乎无策略地探索搜索空间)。一种优化是剪枝搜索空间,通过一种巧妙的方法,我们“排除对手不会让我们改进的玩法序列”。这是通过一种称为Alpha-Beta剪枝的技术实现的。

使用方法

该crate为井字棋提供了具体的实现(注意:其他游戏正在开发中)。

使用TicTacToe::get_best_move(depth, player)方法计算此位置此玩家的最佳移动。

使用预写的驱动程序


use minimax_alph_beta::drivers;

fn main() {
    let grid_size: usize = 3;
    let search_depth: i64 = 6;

    // Control the depth to trade running time and accuracy.
    // The higher the depth the slower the compute and higher the accuracy.
    // The lower the depth the faster the compute and lower the accuracy.
    drivers::play_tic_tac_toe_against_computer_with_depth(grid_size, search_depth);

    // Or simply use the default balance of `depth = 6`.
    drivers::play_tic_tac_toe_against_computer(grid_size);
}

自己编写驱动程序

use minimax_alpha_beta::tictactoe::{TicTacToe};
use minimax_alpha_beta::strategy::*;

let mut ttt = TicTacToe::create_game(3, None, None, None);
ttt.print_board();

// The first argument takes a reference to the move position.
// The structure of the board is like [[0, 1, 2], [3, 4, 5], [6, 7, 8]].
// The second argument governs who plays this move;
// true means the first player, false means the second.

ttt.play(&4, true);
ttt.play(&0, false);

ttt.print_board();

// The first argument is the depth to explore.
// The higher the depth, the more the time it takes to compute
// the best move and that the chances of it being the best move increase.
// The lower the depth, the faster it takes to compute but the less
// the likelihood of being the best move.

// The second argument governs who plays this move;
// true means the first player, false means the second.
let best = ttt.get_best_move(6 as i64, true);

ttt.play(&best, true);

ttt.print_board();

使用引擎进行全新的最小-最大游戏(例如,国际象棋)


use minimax_alpha_beta::strategy::{Strategy, AlphaBetaMiniMaxStrategy};

/// Define the Chess structure.
pub struct Chess {
    /// The board could be represented by a vector of 64 characters.
    pub board: Vec<char>,
    /// The default char could be a '.'
    pub default_char: char,
    /// The maximizer is White.
    pub maximizer: char,
    /// The minimizer is Black.
    pub minimizer: char,
}

// Implement any basic methods on Chess.
// This should ideally allow us to work with
// Chess at a very low level.

impl Chess {
    // ...
}

// You'll likely need to have a new struct
// that represents a move in Chess.
pub struct ChessMove {
    // ...
}

// Implement all the higher level
// methods on Chess. This should ideally
// be compositions of the basic methods
// in the default impl of Chess.

impl Strategy for Chess {
    // ...
    type Move = ChessMove;
    // ...
}

// Once Strategy is implemented for Chess, the Minimax engine should be ready to use!

// Make sure there is a create_game in the default impl for Chess.
// Then create a game with parameters as necessary.
let mut chessboard = Chess::create_game()

let search_depth: i64 = 6;

// Play arbitrary number of moves depending on how've you defined it in the default impl.
chessboard.play(&your_move, true);

let best_move: ChessMove = chessboard.get_best_move(search_depth, true);

chessboard.play(&best_move, true);
chessboard.print_board();

表示赞赏

我喜欢创建这个,这是我在Rust中的第一次探险。如果你发现这个库很有用或者很酷,请考虑给它加星

问题

创建一个问题

贡献

欢迎所有 pull requests

联系方式

有任何有趣的协作想法吗?我的github是 aalekhpatel07,你可以通过 这里 联系我。

依赖项

~3.5MB
~66K SLoC