python使用minimax算法实现五子棋


Posted in Python onJuly 29, 2019

这是一个命令行环境的五子棋程序。使用了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 相关文章推荐
Python抓取Discuz!用户名脚本代码
Dec 30 Python
python实现爬虫下载漫画示例
Feb 16 Python
Python continue语句用法实例
Mar 11 Python
python实现巡检系统(solaris)示例
Apr 02 Python
Python SQLite3数据库操作类分享
Jun 10 Python
python实现文本文件合并
Dec 29 Python
Python读写/追加excel文件Demo分享
May 03 Python
Django框架基础模板标签与filter使用方法详解
Jul 23 Python
将python2.7添加进64位系统的注册表方式
Nov 20 Python
python numpy 矩阵堆叠实例
Jan 17 Python
django ListView的使用 ListView中获取url中的参数值方式
Mar 27 Python
Python基于模块Paramiko实现SSHv2协议
Apr 28 Python
浅析python 中大括号中括号小括号的区分
Jul 29 #Python
Django分页功能的实现代码详解
Jul 29 #Python
微信小程序python用户认证的实现
Jul 29 #Python
Python 堆叠柱状图绘制方法
Jul 29 #Python
Django处理Ajax发送的Get请求代码详解
Jul 29 #Python
Django框架视图函数设计示例
Jul 29 #Python
python内存监控工具memory_profiler和guppy的用法详解
Jul 29 #Python
You might like
PHP4之COOKIE支持详解
2006/10/09 PHP
apache php模块整合操作指南
2012/11/16 PHP
浅谈php安全性需要注意的几点事项
2014/07/17 PHP
laravel在中间件内生成参数并且传递到控制器中的2种姿势
2019/10/15 PHP
js单向链表的具体实现实例
2013/06/21 Javascript
window.opener用法和用途实例介绍
2013/08/19 Javascript
jquery.cookie用法详细解析
2013/12/18 Javascript
javascript自动生成包含数字与字符的随机字符串
2015/02/09 Javascript
基于JS实现移动端访问PC端页面时跳转到对应的移动端网页
2020/12/24 Javascript
jquery动态创建div与input的实例代码
2016/10/12 Javascript
javascript基础知识讲解
2017/01/11 Javascript
一道面试题引发的对javascript类型转换的思考
2017/03/06 Javascript
Vue2 Vue-cli中使用Typescript的配置详解
2017/07/24 Javascript
Vue.js学习笔记之修饰符详解
2017/07/25 Javascript
Node.js中环境变量process.env的一些事详解
2017/10/26 Javascript
vue将对象新增的属性添加到检测序列的方法
2018/02/24 Javascript
Vue父子组件双向绑定传值的实现方法
2018/07/31 Javascript
vue+node实现图片上传及预览的示例方法
2018/11/22 Javascript
记录一次完整的react hooks实践
2019/03/11 Javascript
js实现数字从零慢慢增加到指定数字示例
2019/11/07 Javascript
js实现左右轮播图
2020/01/09 Javascript
JavaScript内置对象之Array的使用小结
2020/05/12 Javascript
解决vue中使用less/sass及使用中遇到无效的问题
2020/10/24 Javascript
Python使用matplotlib简单绘图示例
2018/02/01 Python
python 标准差计算的实现(std)
2019/07/29 Python
python内置函数sorted()用法深入分析
2019/10/08 Python
基于python连接oracle导并出数据文件
2020/04/28 Python
Python读取Excel一列并计算所有对象出现次数的方法
2020/09/04 Python
Python3.7安装PyQt5 运行配置Pycharm的详细教程
2020/10/15 Python
函授本科自我鉴定
2013/11/03 职场文书
自动化专业个人求职信范文
2013/12/30 职场文书
领班岗位职责范文
2014/02/06 职场文书
幼儿园大班评语大全
2014/04/17 职场文书
党员十八大心得体会
2014/09/12 职场文书
三八红旗手主要事迹材料
2015/11/04 职场文书
Grafana可视化监控系统结合SpringBoot使用
2022/04/19 Redis