当前位置:嗨网首页>书籍在线阅读

06-用井字棋测试极小化极大算法

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

8.2.3 用井字棋测试极小化极大算法

井字棋游戏十分简单,因此人类能够轻松找出对于给定棋局的绝对正确的走法。这样单元测试就很容易开发了。在代码清单8-10所示的代码段中,本章的极小化极大算法将迎接挑战,为3种不同的井字棋局查找下一步的正确走法。第一个棋局很容易,只需要考虑下一步如何赢棋。第二个棋局需要挡一手(block),而且AI必须阻止对手获胜。最后一个棋局的挑战性稍强一点,需要AI思考后面的两步棋。

代码清单8-10 tictactoe_tests.py

import unittest
from typing import List
from minimax import find_best_move
from tictactoe import TTTPiece, TTTBoard
from board import Move
class TTTMinimaxTestCase(unittest.TestCase):
    def test_easy_position(self):
        # win in 1 move
        to_win_easy_position: List[TTTPiece] = [TTTPiece.X, TTTPiece.O, TTTPiece.
          X, TTTPiece.X, TTTPiece.E, TTTPiece.O, TTTPiece.E, TTTPiece.E, TTTPiece.O]
        test_board1: TTTBoard = TTTBoard(to_win_easy_position, TTTPiece.X)
        answer1: Move = find_best_move(test_board1)
        self.assertEqual(answer1, 6)
    def test_block_position(self):
        # must block O's win
        to_block_position: List[TTTPiece] = [TTTPiece.X, TTTPiece.E, TTTPiece.E, 
          TTTPiece.E, TTTPiece.E, TTTPiece.O, TTTPiece.E, TTTPiece.X, TTTPiece.O]
        test_board2: TTTBoard = TTTBoard(to_block_position, TTTPiece.X)
        answer2: Move = find_best_move(test_board2)
        self.assertEqual(answer2, 2)
    def test_hard_position(self):
        # find the best move to win 2 moves
        to_win_hard_position: List[TTTPiece] = [TTTPiece.X, TTTPiece.E, TTTPiece.E, 
          TTTPiece.E, TTTPiece.E, TTTPiece.O, TTTPiece.O, TTTPiece.X, TTTPiece.E]
        test_board3: TTTBoard = TTTBoard(to_win_hard_position, TTTPiece.X)
        answer3: Move = find_best_move(test_board3)
        self.assertEqual(answer3, 1)
if __name__ == '__main__':
    unittest.main()

运行tictactoe_tests.py的时候,3个测试过程都应该都能顺利通过。

提示  实现极小化极大算法并没有用太多的代码,而且该算法不但可以用于井字游戏,而且可以用于很多其他游戏。如果你想要为其他游戏实现极小化极大算法,那么走向成功的重要一点就是,创建与极小化极大算法设计方案相适应的数据结构,类似于 Board 类。学习极小化极大算法存在一个常见错误,即采用可修改的数据结构,这种数据结构在极小化极大算法的递归调用过程中会被改动,因此无法回到原始状态进行再次调用。