Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

Python 再帰関数をもう少し詳しく学ぶ(AIプログラミング 第6回)

はじめに

実践で「再帰関数」を使ってみようと思ったのですが、少し気になったことがあったのでもう少し詳しく学んでいきます。

 

応用(動きを追いかける)

前回の最後の例を少し変えました。

def func4(n):
    if n >= 3:
        return
    for i in range(2):
        #print("n=", n,"i=", i)
        # 再帰
        func4(n+1)
        print("n=", n,"i=", i)
    return

func4(0)

値の表示を「再帰」の後にもってきてみました。

for文に書き直して考えてみます。

for i in range(2):
    for j in range(2):
        for k in range(2):
            print("n=", 2,"k=", k)
        print("n=", 1,"j=", j)
    print("n=", 0,"i=", i)

結果はこちらです。

n= 2 k= 0
n= 2 k= 1
n= 1 j= 0
n= 2 k= 0
n= 2 k= 1
n= 1 j= 1
n= 0 i= 0
n= 2 k= 0
n= 2 k= 1
n= 1 j= 0
n= 2 k= 0
n= 2 k= 1
n= 1 j= 1
n= 0 i= 1

図にするとこうなります。

f:id:Start_python:20200222150612p:plain

 

再帰関数」の前に記述すると上から処理していきますが、「再帰関数」の後に記述すると下から処理していくのがわかります。

「ゲーム木」で「再帰関数」を扱う場合は、下から処理していく必要があります。

 

三目並べのゲーム木(ミニマックス法

f:id:Start_python:20200222151353p:plain

拡大します。この部分で解説していきます。

f:id:Start_python:20200222152753p:plain

プログラムの作り方

再帰関数」を作ってその後に処理をします。上の図では①~⑫の順で処理することになります。

 

勝敗が決まった場合(引き分けも含みます)

・評価点をつけます。勝った時は「10 - [深さ] 」点、負けた時は「[深さ] - 10 」点、引き分けの時は0点にします。(早く勝てば点数が高く、早く負けると点数が低い)

・その「再帰関数」は終了して、評価点を返します。

勝敗が決まっていない場合(まだ手が打てる場合)

・自分(AI)のターンの時は、(一つ下の深さの評価点から)一番低い点数を引き継ぎます。※相手に打たれると一番都合の悪いルートを選びます。

・相手(プレイヤー)のターンの時は、(一つ下の深さの評価点から)一番高い点数を引き継ぎます。※自分が打てる一番良いルートを選びます。

  深さが一番上の場合(n = 0)

  ・すべての「再帰関数」が終了し、打つ場所の値を返します。

  深さが一番上でない場合(n > 0)

  ・その「再帰関数」は終了して、評価点を返します。

 

ちょっと細かいところまで詰められていませんが、この流れでいけそうです。

 

 

次回は、ミニマックス法を使って三目並べを作成したいと思います。