python

超轻量级php框架startmvc

python使用minimax算法实现五子棋

更新时间:2020-07-18 23:24:01 作者:startmvc
这是一个命令行环境的五子棋程序。使用了minimax算法。除了百度各个棋型的打分方式,所

这是一个命令行环境的五子棋程序。使用了minimax算法。

除了百度各个棋型的打分方式,所有代码皆为本人所撸。本程序结构与之前的井字棋、黑白棋一模一样。

有一点小问题,没时间弄了,就这样吧。

一、效果图

(略)

二、完整代码


from functools import wraps
import time
import csv

''' 
五子棋 Gobang 
作者:hhh5460
时间:20181213
'''


#1.初始化棋盘
#------------
def init_board():
 '''
 初始化棋盘
 
 棋盘规格 15*15
 
 如下所示:
 board = [[. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .],
 [. . . . . . . . . . . . . . .]]

 其中: 
 . – 未被占用 
 X – 被黑棋占用 
 O – 被白棋占用
 '''
 print('Init board...')
 time.sleep(0.5)
 n = 15
 board = [['.' for _ in range(n)] for _ in range(n)]
 
 return board

#2.确定玩家,执黑先走
#--------------------
def get_player():
 '''
 人类玩家选择棋子颜色(黑'X'先走)
 '''
 humancolor = input("Enter your color. (ex. 'X' or 'O'):").upper()
 computercolor = ['X', 'O'][humancolor == 'X']
 
 return computercolor, humancolor

#3.进入循环
#----------

#4.打印棋盘、提示走子
#------------------------------
def print_board(board): #ok
 '''
 打印棋盘、比分
 
 开局:
 1 2 3 4 5 6 7 8 9 a b c d e f
 1 . . . . . . . . . . . . . . .
 2 . . . . . . . . . . . . . . .
 3 . . . . . . . . . . . . . . .
 4 . . . . . . . . . . . . . . .
 5 . . . . . . . . . . . . . . .
 6 . . . . . . . . . . . . . . .
 7 . . . . . . . . . . . . . . .
 8 . . . . . . . . . . . . . . .
 9 . . . . . . . . . . . . . . .
 a . . . . . . . . . . . . . . .
 b . . . . . . . . . . . . . . .
 c . . . . . . . . . . . . . . .
 d . . . . . . . . . . . . . . .
 e . . . . . . . . . . . . . . .
 f . . . . . . . . . . . . . . .
 '''
 axises = list('123456789abcdef')
 print(' ', ' '.join(axises))
 for i, v in enumerate(axises): 
 print(v, ' '.join(board[i]))

#5.思考走法、放弃终止
#--------------------
def get_human_move(board, color): #ok
 '''
 取人类玩家走法
 '''
 giveup = True # 放弃标志
 
 legal_moves = _get_legal_moves(board, color)
 
 #print(','.join([translate_move(move) for move in legal_moves]), len(legal_moves))
 
 while True:
 _move = input("Enter your move.(ex.'cd' means row=c col=d): ").lower()
 
 move = translate_move(_move)
 
 if move in legal_moves:
 giveup = False # 不放弃
 break
 
 return move, giveup

def _get_all_lianxin(board, move, color): #ok
 '''
 取当前点位落子后连星
 
 1.按照棋盘两连、三连、四连的个数 double triple quadra penta
 '''
 n = len(board)
 uncolor = ['X', 'O'][color == 'X'] # 反色
 
 lianxin = [] # 连星数,len(lianxin) == 4
 
 directions = ((0,1),(1,0),(1,1),(1,-1)) # 东, 南, 东南, 西南
 for direction in directions:
 dr, dc = direction # 步幅
 #r, c = move # 起点
 
 count = 1 # 连星数,算上起点(落子位置)
 jump_count = [0, 0] # 顺、反方向跳开一个空格之后的连星数
 jump_flag = [False, False] # 顺、反方向跳开一个空格的标志
 block = [False, False] # 顺、反方向是否堵死
 #name = ['','']
 
 for i,v in enumerate([1, -1]): # 顺、反方向分别用1、-1表示
 dr, dc = v*dr, v*dc # 步幅
 r, c = move[0]+dr, move[1]+dc # 先走一步
 while True:
 if not _is_on_board(board, [r, c]) or board[r][c] == uncolor: # 不在棋盘内,或对方棋子
 block[i] = True # 被堵死
 break
 if board[r][c] == '.': # 为空
 if not _is_on_board(board, [r+dr, c+dc]) or board[r+dr][c+dc] != color: # 且下一格,不在棋盘内、或者非己方棋子
 break
 if jump_flag[i] == True: # 前面已经跳了一格了,则终止
 break # 能力所限,不考虑又跳一格的情况!!!
 else:
 jump_flag[i] = True
 elif board[r][c] == color:
 if jump_flag[i] == True:
 jump_count[i] += 1
 else:
 count += 1
 
 r, c = r + dr, c + dc # 步进
 
 
 
 lianxin.append([count, jump_count, block])
 
 return lianxin
 
def _move_score(board, move): #ok
 '''
 对该落子位置“打分”
 
 这个逻辑太复杂了,代码又长又臭!!暂时不考虑简化
 
 棋型分值:
 0.活五 +100000
 1.死五 +100000
 2.活四 +10000
 3.死四 +1000
 4.活三 +1000
 5.死三 +100
 6.活二 +100
 7.死二 +10
 8.活一 +10
 9.死一 +2
 
 特别说明:
 10.跳N 两边棋型分相加 * 上一级分值的20% ?商榷
 
 
 lianxin == [[2,[0,0],[True,False]],
 [1,[0,0],[True,False]],
 [3,[1,0],[False,False]],
 [3,[2,1],[True,False]]]
 '''
 # 死一, 活一, 死二, 活二, 死三, 活三, 死四, 活四, 死五, 活五
 scores = [ 2, 10, 10, 100, 100, 1000, 1000, 10000,100000,100000]
 sum_score = 0
 for color in ['X','O']:
 for lianxin in _get_all_lianxin(board, move, color):
 count, jump_count, block = lianxin
 if jump_count[0] > 0 and jump_count[1] > 0: # 情况一:两边跳
 if block[0] == True and block[1] == True:
 if count + jump_count[0] + jump_count[1] + 2 < 5: continue
 else:
 # 这边跳了
 if block[0] == True: # 有跳的,先把分数加了再说(查表加分)
 sum_score += scores[jump_count[0]*2-2] # 加死的分
 sum_score += min(scores[(jump_count[0]+count)*2-2] * 0.2, 200) # 上一级的20%
 else:
 sum_score += scores[jump_count[0]*2-1] # 加活的分
 sum_score += min(scores[(jump_count[0]+count)*2-1] * 0.2, 200) # 上一级的20%
 
 # 这边也跳了
 if block[1] == True: # 有跳的,先把分数加了再说(查表加分)
 sum_score += scores[jump_count[1]*2-2] # 加死的分
 sum_score += min(scores[(jump_count[1]+count)*2-2] * 0.2, 200) # 上一级的20%
 else:
 sum_score += scores[jump_count[1]*2-1] # 加活的分
 sum_score += min(scores[(jump_count[1]+count)*2-1] * 0.2, 200) # 上一级的20%
 
 # 中间
 sum_score += scores[count*2-1] # 中间加活的分
 
 elif jump_count[0] > 0 and jump_count[1] == 0: # 情况二:有一边跳
 if block[0] == True and block[1] == True:
 if count + jump_count[0] + jump_count[1] + 1 < 5: continue
 else:
 # 跳的这边
 if block[0] == True: # 先把跳那边的分数加了再说(查表加分)
 sum_score += scores[jump_count[0]*2-2] # 加死的分
 sum_score += min(scores[(jump_count[0]+count)*2-2] * 0.2, 200) # 上一级的20%
 else:
 sum_score += scores[jump_count[0]*2-1] # 加活的分
 sum_score += min(scores[(jump_count[0]+count)*2-1] * 0.2, 200) # 上一级的20%
 
 # 没跳的那边
 if block[1] == True:
 sum_score += scores[count*2-2] # 加死的分
 else:
 sum_score += scores[count*2-1] # 加活的分
 
 elif jump_count[1] > 0 and jump_count[0] == 0: # 情况三:另一边跳
 if block[0] == True and block[1] == True:
 if count + jump_count[0] + jump_count[1] + 1 < 5: continue
 else:
 # 跳的这边
 if block[1] == True: # 先把跳那边的分数加了再说(查表加分)
 sum_score += scores[jump_count[1]*2-2] # 加死的分
 sum_score += min(scores[(jump_count[1]+count)*2-2] * 0.2, 200) # 上一级的20%
 else:
 sum_score += scores[jump_count[1]*2-1] # 加活的分
 sum_score += min(scores[(jump_count[1]+count)*2-1] * 0.2, 200) # 上一级的20%
 
 # 没跳的那边
 if block[0] == True:
 sum_score += scores[count*2-2] # 加死的分
 else:
 sum_score += scores[count*2-1] # 加活的分
 
 elif jump_count[0] == 0 and jump_count[1] == 0: # 情况四:两边都没跳
 if block[0] and block[1]: # 两边都堵死了
 if count == 5: # 等于5才加,否则不加
 sum_score += scores[count*2-2] # -1,-2一样
 elif block[0] or block[1]: # 只堵死一边
 sum_score += scores[count*2-2] # 加死的分
 else:
 sum_score += scores[count*2-1] # 加活的分

 return sum_score
 
def _get_center_enmpty_points(board): #ok
 '''
 取中心点附近的空位
 
 从中心点逐圈顺时针扫描,若连续两圈未有棋子,则停止
 '''
 n = len(board)
 
 center_point = [n//2, n//2] # 中心点[7,7],即'88'
 
 c1 = 0 # 空圈计数
 legal_moves = [] # 保存空位
 for i in range(8): #从内到外扫描8圈
 c2 = True # 空圈标志
 
 if i == 0:
 points = [[n//2, n//2]]
 else:
 # points = [第7-i行] + [第7+i列] + [第7+i行] + [第7-i列] # 从左上开始,顺时针一圈
 points = [[7-i,c] for c in range(7-i,7+i)] + \
 [[r,7+i] for r in range(7-i,7+i)] + \
 [[7+i,c] for c in range(7+i,7-i,-1)] + \
 [[r,7-i] for r in range(7+i,7-i,-1)]
 
 for point in points:
 if board[point[0]][point[1]] == '.': # 遇到空位,则
 legal_moves.append(point) # 保存点位
 else:
 c2 = False # 此圈非空
 
 if c2 == True: # 若此圈为空,空圈计数器加1
 c1 += 1
 if c1 == 2: break
 else: # 否则,清零
 c1 = 0
 
 return legal_moves # 越前,棋盘点位分值越高!

def minimax(board, color, maximizingPlayer, depth):
 '''
 极大极小算法
 
 其中:
 maximizingPlayer = True #己方
 
 用例:
 _, move = minimax(board, 'X', True, 4) # 假设计算机执黑'X'
 
 #参见: https://en.wikipedia.org/wiki/Minimax
 function minimax(node, depth, maximizingPlayer) is
 if depth = 0 or node is a terminal node then
 return the heuristic value of node
 if maximizingPlayer then
 value := −∞
 for each child of node do
 value := max(value, minimax(child, depth − 1, FALSE))
 return value
 else (* minimizing player *)
 value := +∞
 for each child of node do
 value := min(value, minimax(child, depth − 1, TRUE))
 return value

 (* Initial call *)
 minimax(origin, depth, TRUE)
 '''
 pass
 
def get_computer_move(board, color):
 '''
 取计算机玩家走法
 
 计算机走子策略:
 1.对所有合法的落子位置逐个“打分”(如何“打分”,决定了计算机下棋的水平)
 2.取所有分值最高的落子位置
 '''
 print('Computer is thinking...', end='')
 legal_moves = _get_legal_moves(board, color)
 
 scores = [_move_score(board, move) for move in legal_moves]
 
 max_score = max(scores) # 最高分值
 best_move = legal_moves[scores.index(max_score)]
 
 print("'{}'".format(translate_move(best_move)))
 return best_move
 
def _is_legal_move(board, move): #ok
 '''
 判断落子位置是否合法
 
 说明:只要在棋盘内,且为空,即合法
 
 '''
 if _is_on_board(board, move) and board[move[0]][move[1]] == '.': 
 return True
 
 return False
 
def _get_legal_moves(board, color): #ok
 '''
 取当前颜色棋子所有的合法走法
 
 返回格式:[[x1,y1], [x2,y2], ...]
 '''
 legal_moves = _get_center_enmpty_points(board)
 
 return legal_moves
 
def _is_on_board(board, move): #ok
 '''
 判断点位是否在棋盘范围内
 '''
 n = len(board)
 
 return move[0] in range(n) and move[1] in range(n)
 
def translate_move(move): #ok
 '''
 转换坐标
 
 如'1a'可转换为[0,9];又如[9,10]转换为'ab'
 
 此函数,只是为了方便,不是必要的
 '''
 axises = list('123456789abcdef')

 if type(move) is str: # 如'cd'
 row = axises.index(move[0]) 
 col = axises.index(move[1])
 _move = [row, col] # 得[2,3]
 elif type(move) is list: # 如[2,3]
 row = axises[move[0]]
 col = axises[move[1]]
 _move = '{}{}'.format(row, col) # 得'cd'

 return _move
 
#6.落子
#----------
def do_move(board, move, color): #ok
 '''
 在当前位置落子
 '''
 assert board[move[0]][move[1]] == '.'
 
 board[move[0]][move[1]] = color
 
#7.判断局面、是否终止
#------------------------------
def check_board(board, color): #ok
 '''
 检查棋盘
 
 返回:是否胜利
 '''
 n = len(board)
 
 directions = ((0,1),(1,0),(1,1),(1,-1)) # 东, 南, 东南, 西南
 # 四个搜索方向的起点(坐标),分四组。
 # 形如:[[第1列的点], [第1行的点], [第1列+第1行的点], [第1行+第n列的点]]
 all_start_points = [[[i, 0] for i in range(n)],
 [[0, j] for j in range(n)],
 [[i, 0] for i in range(n-4)] + [[0, j] for j in range(1,n-4)], # 排除了长度小于5,及重复的情况
 [[0, j] for j in range(4,n)] + [[i, n-1] for i in range(1,n-4)]]
 
 for direction, start_points in zip(directions, all_start_points):
 dr, dc = direction # 步幅
 for start_point in start_points:
 r, c = start_point # 起点
 count = 0
 while _is_on_board(board, [r, c]):
 if board[r][c] == color:
 count += 1
 if count == 5:
 return True
 else:
 count = 0
 
 r, c = r + dr, c + dc # 步进
 
 return False

def check_board__(board, color): # 废弃!
 '''
 检查棋盘 (不如上面的方式简洁)
 
 返回 是否胜利
 '''
 n = len(board)
 uncolor = ['X', 'O'][color == 'X'] # 反色
 
 # 1.行搜索
 for i in range(n):
 count = 0
 for j in range(n):
 if board[i][j] == color:
 count += 1
 if count == 5:
 return True # 'Winner is ' + color
 elif board[i][j] == uncolor:
 count = 0
 
 # 2.列搜索
 for j in range(n):
 count = 0
 for i in range(n):
 if board[i][j] == color:
 count += 1
 if count == 5:
 return True # 'Winner is ' + color
 elif board[i][j] == uncolor:
 count = 0
 
 # 3.斜搜索k=1左上右下
 #3.a.k=1对角线上方
 for j in range(n-4): # 终止列n-4
 count = 0
 for i in range(n-j): # 终止行n-j
 if board[i][j+i] == color:
 count += 1
 if count == 5:
 return True
 elif board[i][j+i] == uncolor:
 count = 0
 
 #3.b.k=1对角线下方
 for i in range(1, n-4): # 终止行n-4
 count = 0
 for j in range(n-i): # 终止列n-i
 if board[i+j][j] == color:
 count += 1
 if count == 5:
 return True
 elif board[i+j][j] == uncolor:
 count = 0
 
 # 4.斜搜索k=-1左下右上
 #4.a.k=-1对角线下方
 for j in range(n-4): # 终止列n-4
 count = 0
 for i in range(n-j): # 终止行n-j
 if board[n-i-1][j+i] == color:
 count += 1
 if count == 5:
 return True
 elif board[n-i-1][j+i] == uncolor:
 count = 0
 
 #4.b.k=-1对角线上方
 for j in range(4, n):
 count = 0
 for i in range(n-1):
 if board[i][j-i] == color:
 count += 1
 if count == 5:
 return True
 elif board[i][j-i] == uncolor:
 count = 0
 return False
 



#8.游戏结束,返回信息
#--------------------

 
def logging(func): #ok
 '''
 记录游戏相关信息 (装饰器)
 
 包括:
 开始时间、比赛耗时、棋盘大小、黑棋玩家、白棋玩家、游戏比分、本局棋谱
 
 保存到reversi.csv文件
 '''
 @wraps(func)
 def wrap(*args, **kwargs):
 try:
 start = time.strftime("%Y%m%d %H:%M:%S", time.localtime()) # 开始时间
 
 t1 = time.time()
 info = func(*args,**kwargs) # 棋盘大小、黑棋玩家、白棋玩家、游戏比分、本局棋谱(主程序)
 t2 = time.time()
 t = int(t2 - t1) # 比赛耗时
 
 line = [start, t, *info]
 
 with open('gobang.csv', 'a') as f:
 writer = csv.writer(f, lineterminator='\n')
 writer.writerow(line) # 写入
 except Exception as e:
 pass
 
 return wrap

#==========================================
# 主函数
#==========================================
#@logging
def main(): #ok
 '''
 主程序

 人机对战

 流程:
 1.初始化棋盘
 2.确定棋手,黑先
 3.进入循环
 4.打印棋盘,提示走子
 5.思考走法,放弃终止
 6.落子
 7.检查棋盘,是否终止
 8.切换棋手
 9.游戏结束,返回信息
 '''
 # 1.初始化棋盘
 board = init_board()
 
 # 2.确定玩家,执黑先走
 computer_color, human_color = get_player()
 current_color = 'X'
 
 record = '' # 棋谱,如'X:ab O:aa X:ba ...'
 # 3.进入循环
 while True:
 # 4.打印棋盘、提示走子
 print_board(board)
 print("Now turn to '{}'...".format(current_color))
 
 # 5.思考走法,记录棋谱
 if current_color == computer_color:
 move = get_computer_move(board, current_color)
 elif current_color == human_color:
 move, giveup = get_human_move(board, current_color)
 if giveup == True: break # 放弃则终止
 
 record = record + ' {}:{}'.format(current_color, translate_move(move)) # 录入棋谱
 
 # 6.落子
 do_move(board, move, current_color)
 
 # 7.判断局面
 done = check_board(board, current_color) # 返回终止标志
 
 # 7_1.终止
 if done == True:
 print_board(board)
 print("Game over! Winner is '{}'".format(current_color))
 break
 
 # 8.切换棋手
 current_color = ['X', 'O'][current_color == 'X']


#测试
def test_get_center_enmpty_points():
 '''
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [[. . . . . . . . . . . . . . .],#1
 [. . . . . . . . . . . . . . .],#2
 [. . . . . . . . . . . . . . .],#3
 [. . . . . . . . . . . . . . .],#4
 [. . . . . . . . . . . . . . .],#5
 [. . . . . . . . . . . . . . .],#6
 [. . . . . . . . . . . . . . .],#7
 [. . . . . . . . . . . . . . .],#8
 [. . . . . . . . . . . . . . .],#9
 [. . . . . . . . . . . . . . .],#a
 [. . . . . . . . . . . . . . .],#b
 [. . . . . . . . . . . . . . .],#c
 [. . . . . . . . . . . . . . .],#d
 [. . . . . . . . . . . . . . .],#e
 [. . . . . . . . . . . . . . .]]#f
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [[. . . . . . . . . . . . . . .],#1
 [. . . . . . . . . . . . . . .],#2
 [. . . . . . . . . . . . . . .],#3
 [. . . . . . . . . . . . . . .],#4
 [. . . . . . . . . X . . . . .],#5
 [. . . . . . X . . . . . . . .],#6
 [. . . . . O . . X O . . . . .],#7
 [. . . . . X X O X . . . . . .],#8
 [. . . . . X O X . . . . . . .],#9
 [. . . . . . . . . . X . . . .],#a
 [. . . X . . . . . . . . . . .],#b
 [. . X . . . . . . . . . . . .],#c
 [. O . . . . . . . . . . . . .],#d
 [. . . . . . . . . . . . . . .],#e
 [. . . . . . . . . . . . . . .]]#f
 '''
 print('Testing _get_center_enmpty_points()...')
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#1
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#2
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#3
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#4
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#5
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#6
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#7
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#8
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#9
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#a
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#b
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#c
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#d
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#e
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]#f
 empty_points = _get_center_enmpty_points(board)
 
 translate_points = [translate_move(move) for move in empty_points]
 #print(translate_points)
 assert translate_points == ['77','78','79','89','99','98','97','87', '66','67','68','69','6a','7a','8a','9a','aa','a9','a8','a7','a6','96','86','76']
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#1
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#2
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#3
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#4
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#5
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#6
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#7
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#8
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#9
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#a
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#b
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#c
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#d
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#e
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]#f
 empty_points = _get_center_enmpty_points(board)
 
 translate_points = [translate_move(move) for move in empty_points]
 print(translate_points)
 assert '11' in translate_points
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#1
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#2
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#3
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#4
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#5
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#6
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#7
 ['.','.','.','.','.','.','.','X','.','.','.','.','.','.','.'],#8
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#9
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#a
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#b
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#c
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#d
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#e
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]#f
 empty_points = _get_center_enmpty_points(board)
 
 translate_points = [translate_move(move) for move in empty_points]
 print(translate_points)
 assert '11' in translate_points
 
 print('ok')
 
def test_move_score():
 '''
 _move_score(board, move, color)
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [[. . . . . . . . . . . . . . .],#1
 [. . . . . . . . . . . . . . .],#2
 [. . . . . . . . . . . . . . .],#3
 [. . . . . . . . . . . . . . .],#4
 [. . . . . . . . . . . . . . .],#5
 [. . . . . . . . . . . . . . .],#6
 [. . . . . . . . . . . . . . .],#7
 [. . . . . . . . . . . . . . .],#8
 [. . . . . . . . . . . . . . .],#9
 [. . . . . . . . . . . . . . .],#a
 [. . . . . . . . . . . . . . .],#b
 [. . . . . . . . . . . . . . .],#c
 [. . . . . . . . . . . . . . .],#d
 [. . . . . . . . . . . . . . .],#e
 [. . . . . . . . . . . . . . .]]#f
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [[. . . . . . . . . . . . . . .],#1
 [. . . . . . . . . . . . . . .],#2
 [. . . . . . . . . . . . . . .],#3
 [. . . . . . . . . . . . . . .],#4
 [. . . . . . . . . X . . . . .],#5
 [. . . . . . X . . . . . . . .],#6
 [. . . . . O . . X O . . . . .],#7
 [. . . . . X X O X . . . . . .],#8
 [. . . . . X O X . . . . . . .],#9
 [. . . . . . . . . . X . . . .],#a
 [. . . X . . . . . . . . . . .],#b
 [. . X . . . . . . . . . . . .],#c
 [. O . . . . . . . . . . . . .],#d
 [. . . . . . . . . . . . . . .],#e
 [. . . . . . . . . . . . . . .]]#f
 '''
 print('Testing _move_score()...')
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#1
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#2
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#3
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#4
 ['.','.','.','.','.','.','.','.','.','X','.','.','.','.','.'],#5
 ['.','.','.','.','.','.','X','.','.','.','.','.','.','.','.'],#6
 ['.','.','.','.','.','O','.','.','X','O','.','.','.','.','.'],#7
 ['.','.','.','.','.','X','X','O','X','.','.','.','.','.','.'],#8
 ['.','.','.','.','.','X','O','X','.','.','.','.','.','.','.'],#9
 ['.','.','.','.','.','.','.','.','.','.','X','.','.','.','.'],#a
 ['.','.','.','X','.','.','.','.','.','.','.','.','.','.','.'],#b
 ['.','.','X','.','.','.','.','.','.','.','.','.','.','.','.'],#c
 ['.','O','.','.','.','.','.','.','.','.','.','.','.','.','.'],#d
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#e
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]#f
 #[count, jump_count, block] # 东, 南, 东南, 西南
 lianxin = _get_all_lianxin(board, [6,7], 'X')
 #print(lianxin)
 assert lianxin == [[2,[0,0],[True,False]],
 [1,[0,0],[True,False]],
 [3,[1,0],[False,False]],
 [3,[2,1],[True,False]]]
 # 死一, 活一, 死二, 活二, 死三, 活三, 死四, 活四, 死五, 活五
 scores = [ 2, 10, 10, 100, 100, 1000, 1000, 10000,100000,100000]
 assert _move_score(board, [6,7], 'X') == 10 + 2 + (1000 + 10 + 200) + (1000 + 10 + 10 + 200 + 200)
 
 print('ok')
 
def test_get_all_lianxin():
 '''
 get_all_lianxin(board, move, color)
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [[. . . . . . . . . . . . . . .],#1
 [. . . . . . . . . . . . . . .],#2
 [. . . . . . . . . . . . . . .],#3
 [. . . . . . . . . . . . . . .],#4
 [. . . . . . . . . . . . . . .],#5
 [. . . . . . . . . . . . . . .],#6
 [. . . . . . . . . . . . . . .],#7
 [. . . . . . . . . . . . . . .],#8
 [. . . . . . . . . . . . . . .],#9
 [. . . . . . . . . . . . . . .],#a
 [. . . . . . . . . . . . . . .],#b
 [. . . . . . . . . . . . . . .],#c
 [. . . . . . . . . . . . . . .],#d
 [. . . . . . . . . . . . . . .],#e
 [. . . . . . . . . . . . . . .]]#f
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [[. . . . . . . . . . . . . . .],#1
 [. . . . . . . . . . . . . . .],#2
 [. . . . . . . . . . . . . . .],#3
 [. . . . . . . . . . . . . . .],#4
 [. . . . . . . . . X . . . . .],#5
 [. . . . . . X . . . . . . . .],#6
 [. . . . . O . . X O . . . . .],#7
 [. . . . . X X O X . . . . . .],#8
 [. . . . . X O X . . . . . . .],#9
 [. . . . . . . . . . X . . . .],#a
 [. . . X . . . . . . . . . . .],#b
 [. . X . . . . . . . . . . . .],#c
 [. O . . . . . . . . . . . . .],#d
 [. . . . . . . . . . . . . . .],#e
 [. . . . . . . . . . . . . . .]]#f
 '''
 print('Testing _get_all_lianxin()...')
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#1
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#2
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#3
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#4
 ['.','.','.','.','.','.','.','.','.','X','.','.','.','.','.'],#5
 ['.','.','.','.','.','.','X','.','.','.','.','.','.','.','.'],#6
 ['.','.','.','.','.','O','.','.','X','O','.','.','.','.','.'],#7
 ['.','.','.','.','.','X','X','O','X','.','.','.','.','.','.'],#8
 ['.','.','.','.','.','X','O','X','.','.','.','.','.','.','.'],#9
 ['.','.','.','.','.','.','.','.','.','.','X','.','.','.','.'],#a
 ['.','.','.','X','.','.','.','.','.','.','.','.','.','.','.'],#b
 ['.','.','X','.','.','.','.','.','.','.','.','.','.','.','.'],#c
 ['.','O','.','.','.','.','.','.','.','.','.','.','.','.','.'],#d
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],#e
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]#f
 #[count, jump_count, block] # 东, 南, 东南, 西南
 lianxin = _get_all_lianxin(board, [6,7], 'X')
 #print(lianxin)
 assert lianxin == [[2,[0,0],[True,False]],
 [1,[0,0],[True,False]],
 [3,[1,0],[False,False]],
 [3,[2,1],[True,False]]]
 
 # 1 2 3 4 5 6 7 8 9 a b c d e f
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'], #1
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'], #2
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'], #3
 ['.','.','.','.','.','.','.','.','.','X','.','.','.','.','.'], #4
 ['.','.','.','.','.','.','X','.','.','.','.','.','.','.','.'], #5
 ['.','.','.','.','.','O','.','.','X','O','.','.','.','.','.'], #6
 ['.','.','.','.','.','X','X','O','X','.','.','.','.','.','.'], #7
 ['.','.','.','.','.','X','O','X','.','.','.','.','.','.','.'], #8
 ['.','.','.','.','.','.','.','.','.','.','X','.','.','.','.'], #9
 ['.','.','.','X','.','.','.','.','.','.','.','.','.','.','.'], #a
 ['.','.','X','.','.','.','.','.','.','.','.','.','.','.','.'], #b
 ['.','O','.','.','.','.','.','.','.','.','.','.','.','.','.'], #c
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'], #d
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'], #e
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']] #f
 #[count, jump_count, block] # 东, 南, 东南, 西南
 lianxin = _get_all_lianxin(board, [5,7], 'X')
 #print(lianxin)
 assert lianxin == [[2,[0,0],[True,False]],
 [1,[0,0],[True,False]],
 [3,[1,0],[False,False]],
 [3,[2,1],[True,False]]]
 
 
 print('ok')
 
def test_check_board():
 '''
 
 '''
 print('Testing check_board()...')
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]
 assert check_board(board, 'X') == False
 
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['X','X','X','X','X','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]
 assert check_board(board, 'X') == True
 
 board = [['X','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['X','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['X','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['X','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['X','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]
 assert check_board(board, 'X') == True

 board = [['.','.','.','.','.','.','.','.','.','.','X','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','X','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','X','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','X','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','X'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]
 assert check_board(board, 'X') == True
 
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['X','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','X','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','X','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','X','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','X','.','.','.','.','.','.','.','.','.','.']]
 assert check_board(board, 'X') == True
 
 board = [['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','X'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','X','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','X','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','X','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','X','.','.','.','.']]
 assert check_board(board, 'X') == True
 
 board = [['.','.','.','.','X','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','X','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','X','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','X','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['X','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'],
 ['.','.','.','.','.','.','.','.','.','.','.','.','.','.','.']]
 assert check_board(board, 'X') == True
 
 print('ok')
 
if __name__ == '__main__':
 main()
 #test_check_board()
 #test_get_all_lianxin()
 #test_move_score()
 #test_get_center_enmpty_points()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

python minimax 五子棋