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使用PyFetion来发送短信的例子
Apr 22 Python
Python中的startswith和endswith函数使用实例
Aug 25 Python
Python中使用装饰器时需要注意的一些问题
May 11 Python
json跨域调用python的方法详解
Jan 11 Python
Python原始字符串与Unicode字符串操作符用法实例分析
Jul 22 Python
python使用threading获取线程函数返回值的实现方法
Nov 15 Python
numpy数组之存取文件的实现示例
May 24 Python
PyQt5 对图片进行缩放的实例
Jun 18 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
Jul 02 Python
Python爬虫回测股票的实例讲解
Jan 22 Python
解决Pycharm 运行后没有输出的问题
Feb 05 Python
python opencv将多个图放在一个窗口的实例详解
Feb 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
PHP number_format() 函数定义和用法
2012/06/01 PHP
PHP中error_log()函数的使用方法
2015/01/20 PHP
php生成固定长度纯数字编码的方法
2015/07/09 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
php生成word并下载代码实例
2019/03/15 PHP
JS 字符串连接[性能比较]
2009/05/10 Javascript
js中iframe调用父页面的方法
2014/10/30 Javascript
初识Node.js
2015/03/20 Javascript
javascript判断并获取注册表中可信任站点的方法
2015/06/01 Javascript
有关json_decode乱码及NULL的问题
2015/10/13 Javascript
纯JS代码实现气泡效果
2016/05/04 Javascript
Node.js的项目构建工具Grunt的安装与配置教程
2016/05/12 Javascript
js 中获取制定的cook信息实现方法
2016/11/19 Javascript
angular4模块中给标签添加背景图的实现方法
2017/09/15 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
2017/10/30 Javascript
element ui 表格动态列显示空白bug 修复方法
2018/09/04 Javascript
Vue 实现列表动态添加和删除的两种方法小结
2018/09/07 Javascript
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
简单了解vue中的v-if和v-show的区别
2019/10/08 Javascript
微信小程序返回箭头跳转到指定页面实例解析
2019/10/08 Javascript
vue element table中自定义一些input的验证操作
2020/07/18 Javascript
vue 使用localstorage实现面包屑的操作
2020/11/16 Javascript
200行python代码实现2048游戏
2019/07/17 Python
Python属性和内建属性实例解析
2020/01/14 Python
如何打包Python Web项目实现免安装一键启动的方法
2020/05/21 Python
python 安装移动复制第三方库操作
2020/07/13 Python
Python爬虫入门教程02之笔趣阁小说爬取
2021/01/24 Python
深圳-东方伟业笔试部分
2015/02/11 面试题
毕业生大学生活自我总结
2014/01/31 职场文书
爱国口号
2014/06/19 职场文书
大四毕业生自荐书
2014/07/05 职场文书
2014年学生党支部工作总结
2014/12/20 职场文书
安全守法证明
2015/06/23 职场文书
Django如何与Ajax交互
2021/04/29 Python
德生2P3收音机开箱评测
2022/04/30 无线电
Python实现聚类K-means算法详解
2022/07/15 Python