2016-08-19 5 views
-3

問題は、ドローを検出しておらず、誰も勝利しなければハングするということです。私はここにスクリプト全体を貼り付けて助けを求めるのは良い習慣ではないが、私はすべてアイデアがないことを理解している。私はこのTicTacToeスクリプトをgithubから取り除き、2人のAIプレイヤーの間でランダムな動きを実装しようとしています(どちらもランダムな動きだけです)。ループが正しく破られていないときに、スクリプトがハングする

import random 
    import time 


class Tic(object): 
winning_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]) 

    winners = ('X-win', 'Draw', 'O-win') 

    def __init__(self, squares=[]): 
     if len(squares) == 0: 
      self.squares = [" " for i in range(9)] 
     else: 
      self.squares = squares 

def show(self): 
    for element in [self.squares[i:i + 3] for i in range(0, len(self.squares), 3)]: 
     print(element) 

def available_moves(self): 
    """what spots are left empty?""" 
    return [k for k, v in enumerate(self.squares) if v is " "] 

def available_combos(self, player): 
    """what combos are available?""" 
    return self.available_moves() + self.get_squares(player) 

def complete(self): 
    """is the game over?""" 
    if " " not in [v for v in self.squares]: 
     return True 
    if self.winner() != " ": 
     return True 
    return False 

def X_won(self): 
    return self.winner() == 'X' 

def O_won(self): 
    return self.winner() == 'O' 

def tied(self): 
    return self.complete() is True and self.winner() is " " 

def winner(self): 
    for player in ('X', 'O'): 
     positions = self.get_squares(player) 
     for combo in self.winning_combos: 
      win = True 
      for pos in combo: 
       if pos not in positions: 
        win = False 
      if win: 
       return player 

    return " " 

def get_squares(self, player): 
    """squares that belong to a player""" 
    return [k for k, v in enumerate(self.squares) if v == player] 

def make_move(self, position, player): 
    """place on square on the board""" 
    self.squares[position] = player 


def determine(board, player): 
    a = -2 
    choices = [] 
    if len(board.available_moves()) == 9: 
     return 4 
    for move in board.available_moves(): 
     board.make_move(move, player) 
     board.make_move(move, " ") 
     if val > a: 
      a = val 
      choices = [move] 
     elif val == a: 
      choices.append(move) 
    return random.choice(choices) 


def get_enemy(player): 
    if player == 'O': 
     return 'X' 
    return 'O' 


board = Tic() 

count = 0 
player = 'X' 

while not board.complete(): 
     if board.complete(): 
      break 
     while count == 0: 
      player_move = int(random.randint(1, 9)) 
      if player_move not in board.available_moves(): 
       continue 
      board.make_move(player_move, player) 

      player = get_enemy(player) 
      count += 1 

     while count == 1: 
      computer_move = int(random.randint(1, 9)) 
      if computer_move not in board.available_moves(): 
       continue 
      board.make_move(computer_move, player) 

      count -= 1 

     if board.complete(): 
      break 


if board.complete(): 
     print("winner is", board.winner()) 
     final_win = "winner is " + board.winner() 
     log = open("log_for_orig.txt", "a") 
     log.write(final_win + "\n" + "\n") 
+1

は[MCVE]を思い付くためにあなたのコードを減らしてみ参照してください。それはあなたが問題を絞り込んで助けになるのを助けます。 – Praveen

答えて

0

プレーヤーブロック

while count == 0: 
     player_move = int(random.randint(1, 9)) 
     if player_move not in board.available_moves(): 
      continue 

コンピュータブロック

while count == 1: 
     computer_move = int(random.randint(1, 9)) 
     if computer_move not in board.available_moves(): 
      continue 

問題は、2つのコードブロックの上にあります。

最初のブロックで、countが0で、player_moveに利用可能な移動がない場合、continueを実行するとスキップします。カウントは0のままで、同じ最初のブロックに入ります。プレーヤーが彼の動きを変えない限り。基本的には、継続するのではなく、移動を変更するようユーザーに促す必要があります。

同じことが第2ブロックのコードにも当てはまります。コンピュータが動いているので、あなたはもっと良い方法でそれを扱うべきです。

+0

プレイヤーの移動はユーザーからのものではなく、 'random.randint(1、9) 'に由来します。利用可能なものが見つかるまで動くようにしなければならないという考えがあるようです。それから、これを過ぎて 'count'を変更するコードを実行します。 – Barmar

+0

@Barmar次に、プレイヤーの移動部分を別の機能に移動させてから、ループ中に全体を通過させるのではなく、それを呼び出すようにしておくといいと思います。もっと良い方法は 'int(random.randint(1、9)) 'ではなくboard.available_moves()からランダムに選択することです。 –

+0

何もする必要はありません。それは自分のコードではありません。 – Barmar

1

これは、利用可能な移動を選択するための非常に悪い方法です:

while count == 0: 
    player_move = int(random.randint(1, 9)) 
    if player_move not in board.available_moves(): 
     continue 

可能な移動がたくさんあるとき、それはOKに動作します。しかし、利用可能な移動がほとんどない場合、random.randint()がそれらの1つを選択するのに時間がかかることがあるので、プログラムがハングアップしているように見えることがあります。

randomモジュールは、リストから要素を直接選択する機能を提供します。

if count == 0: 
    player_move = random.choice(board.available_moves()) 

How to randomly select an item from a list?

関連する問題