【问题标题】:Python - Tic Tac Toe - Computer Always WinsPython - 井字游戏 - 计算机总是赢
【发布时间】:2021-11-11 11:20:54
【问题描述】:

目前使用非常简单的代码,将游戏板定义为名为 game 的类中的多级数组

class game:
    board = [['#','#','#'],['#','#','#'],['#','#','#']]

win check设置如下:

def 检查(棋盘,玩家):

if (board[0][0] == player and board[0][1] == player and board[0][2] == player) or \
    (board[1][0] == player and board[1][1] == player and board[1][2] == player) or \
    (board[2][0] == player and board[2][1] == player and board[2][2] == player) or \
    (board[0][0] == player and board[1][0] == player and board[2][0] == player) or \
    (board[0][1] == player and board[1][1] == player and board[2][1] == player) or \
    (board[0][2] == player and board[1][2] == player and board[2][2] == player) or \
    (board[0][0] == player and board[1][1] == player and board[2][2] == player) or \
    (board[0][2] == player and board[1][1] == player and board[2][0] == player):
        
    win.player_won(player)
else:
    pass

我的问题是关于游戏的“逻辑”,我目前正在使用 if/elif 语句写出所有可能的游戏组合。我确信必须有更有效的方法来完成此操作,但想不出该使用什么。

'''
        Below code is to prevent user from winning
This isn't the code in its entirety, just an example for the question 
        '''
        
        if board[0][0] == "O" and board[0][1] == "O":
            game.board[0][2] = "X" # Location 1 and 2 already have O's, block with X in Loc 3
            
        elif board [0][0] == "O" and board [1][0] == "O":
            game.board[2][0] = "X" # Loc 1 and 4 Already have O's, block with X in loc 7
            
        elif board [0][0] == "O" and board [1][1] == "O":
            game.board[2][2] = "X" # Loc 1 and 5 have O's, Block in Loc 9
            
        elif board [0][1] == "O" and board [1][1] == "O":
            game.board[2][1] = "X" # Loc 2 and Loc 4 have O's, block in Loc 8
            
        elif board [1][0] == "O" and board [1][1] == "O":
            game.board[1][2] = "X" # Loc 4 and Loc 5 have O's, block in Loc 6
            
        elif board [1][2] == "O" and board [1][1] == "O":
            game.board[1][0] = "X" # Loc 6 and Loc 5 have O's, Block in loc 4
            
        elif board [0][2] == "O" and board [0][1]== "O":
            game.board[2][0] = "X" # Loc 3 and Loc 5 have O's, block in loc 7
            
        elif board [2][0] == "O" and board [2][1] =="O":
            game.board[2][2] = "X" # Loc 7 and Loc 8 have O's, block in loc 9
            
        elif board [2][2] == "O" and board [2][1]== "O":
            game.board[2][0] = "X" # Loc 9 and loc 8 have O's, block in loc 7
            
        elif board [0][2] == "O" and board [1][2]== "O":
            game.board[2][2] = "X" # Loc 3 and loc 6 have O's, block in loc 9 
            
        elif board [0][2] == "O" and board [1][1] =="O":
            game.board[2][0] = "X" # Loc 3 and Loc 5 have O's, block in loc 7

        elif board [0][2] == "O" and board [0][1] == "O":
            game.board[0][0] = "X"

所以我基本上要问的是任何人对我可以为此做些什么的想法,这比一堆 if 语句更有效。谢谢

【问题讨论】:

  • 看看递归和 MinMax 算法
  • 您希望有一个 for 循环遍历数组中的每个正方形,以计算紧邻它的 O 的数量。然后,您会希望计算机在旁边有最多 O 的正方形上放置一个 X。这并不涵盖所有情况,我相信玩家仍然能够获胜,但这应该是一个好的开始!

标签: python tic-tac-toe


【解决方案1】:

可以进行大量优化的基本方法,但是,这是此用例的一个很好的起点:

# CHECK WIN CONDITION 是该逻辑的占位符。那就是调用break 来停止游戏。

import itertools
import random

def printBoard(board):
    print ( "   |   |   ")
    print (" "+board[0]+" | "+board[1]+" | "+board[2]+"  ")
    print ("   |   |")
    print ("---|---|---")
    print ("   |   |")
    print (" "+board[3]+" | "+board[4]+" | "+board[5]+"  ")
    print ("   |   |")
    print ("---|---|---")
    print ("   |   |")
    print (" "+board[6]+" | "+board[7]+" | "+board[8]+"  ")
    print ("   |   |   ")

win_combos = [[0, 1, 2],
              [3, 4, 5],
              [6, 7, 8],
              [0, 3, 6],
              [1, 4, 7],
              [2, 5, 8],
              [0, 4, 8],
              [2, 4, 6]]

cpu_moves = []

player_moves = []

board = ['.', '.', '.', '.', '.', '.', '.', '.', '.']

def make_move(board, win_combos, moves):
  for two in itertools.combinations(moves, 2):
    for run in win_combos:
      if all(item in run for item in two):
        move = set(run).difference(set(two)).pop()
        if board[move] == '.':
          return move
  return None

while True:
  # ACCEPT PLAYER TURN
  p1 = int(input('Select a tile (0-8): '))
  board[p1] = 'p'
  player_moves.append(p1)
  
  # CHECK WIN CONDITION

  # MAKE CPU MOVE
  # check if cpu can win...
  move = make_move(board, win_combos, cpu_moves)

  # check if can block player win...
  if not move:
    move = make_move(board, win_combos, player_moves)
          
  # random placement
  if not move:
    move = random.choice([i[0] for i in enumerate(board) if i[1] == '.'])

  # MAKE MOVE
  board[move] = 'c'
  cpu_moves.append(move)

  # CHECK WIN CONDITION

  printBoard(board)

这种方法定义了所有获胜条件,并为 cpu 的移动和玩家的移动提取了两个组合,然后将这些组合与定义的获胜组合进行比较,看看是否可以再放置一个瓷砖来获胜 (cpu_moves)或阻止 (player_moves),如果没有,则选择一个随机槽。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多