2017-07-02 15 views
2

私はTic Tac Toeの位置を評価するために、できるだけ単純なネガマックスアルゴリズムを使用しています。ゲームの状態はnumpyで配列として格納され、Xの部分は1で表され、Oの部分は4で表されます。Python Negamaxアルゴリズム

私はちょうど今、これをテストしていた、とが見つかりました:

a = np.zeros(9).reshape(3,3) 
negaMax(a, 6, 1) # Returned zero as it should 
negaMax(a, 7, 1) # Returns 100 

は私のアルゴリズムは、それがXは明らかに不可能であるチックタックトーのゲーム、で7枚のプライで勝つための方法を発見したと考えていることを意味しますまともなプレーに対して。私はそれが見つけた最高の動きを印刷する方法を試すことができないので、これをデバッグするのに本当の問題があります。私は間違って何をしていますか?

def winCheck(state): 
     """Takes a position, and returns the outcome of that game""" 
     # Sums which correspond to a line across a column 
     winNums = list(state.sum(axis=0)) 
     # Sums which correspond to a line across a row 
     winNums.extend(list(state.sum(axis=1))) 
     # Sums which correspond to a line across the main diagonal 
     winNums.append(state.trace()) 
     # Sums which correspond to a line across the off diagonal 
     winNums.append(np.flipud(state).trace()) 

     if Square.m in winNums: 
       return 'X' 
     elif (Square.m**2 + Square.m) in winNums: 
       return 'O' 
     elif np.count_nonzero(state) == Square.m**2: 
       return 'D' 
     else: 
       return None 

def moveFind(state): 
     """Takes a position as an nparray and determines the legal moves""" 
     moveChoices = [] 

     # Iterate over state, to determine which squares are empty 
     it = np.nditer(state, flags=['multi_index']) 
     while not it.finished: 
      if it[0] == 0: 
        moveChoices.append(it.multi_index) 
      it.iternext() 
     return moveChoices 

def moveSim(state, move, player): 
     """Create the state of the player having moved without interfering with the board""" 
     simState = state.copy() 
     if player == 1: 
       simState[move] = 1 
     else: 
       simState[move] = gamecfg.n + 1 
     return simState 

def positionScore(state): 
     """The game is either won or lost""" 
     if winCheck(state) == 'X': 
       return 100 
     elif winCheck(state) == 'O': 
       return -100 
     else: 
       return 0 

def negaMax(state, depth, colour): 
     """Recursively find the best move via a negamax search""" 
     if depth == 0: 
       return positionScore(state) * colour 

     highScore = -100 

     moveList = moveFind(state) 
     for move in moveList: 
       score = -negaMax(moveSim(state, move, colour), depth -1, colour * -1) 
       highScore = max(score, highScore) 

     return highScore 
+1

@JacobIRR申し訳ありませんが、私は何とかいくつかの行を逃しましたコピー中に途中で、私は質問を編集しました。 – Qiri

+0

誰かが勝ったときにゲームを止めないことが重要かどうか疑問に思いますか?おそらく、あなたが3人のOの最初の行を取得することを気にしない場合は、常に3つのXの行を取得することは可能ですか? –

+0

@PeterdeRivazそれは私が思っていたものではありませんが、センターで始めれば7つのプライで連続して3つを強制することが非常に可能で、最初に失うことを心配していません。 – Qiri

答えて

1

あなたのコードでは、3つのシンボルの行が作成されたときにゲームが停止するとはみなされません。

これは、それがXは、彼がOこのバリアント3.

の行をした後も3行を行う場合、プログラムが正しく持って勝ち三目並べの変形を果たしていることを意味しXがいつも勝つことが可能であることを発見しました!

(私はコンピュータが、それは少し後でチェックメイト達するならば、その王を犠牲にすることを幸せだったところ私が作ったチェスプログラムと同じ状況に出くわした...)

関連する問題