(3) メソッドについて

 

ここではupdateメソッド、drawメソッド、gameinitメソッド以外のメソッドについて解説します。

 

ここのソースは解説範囲のみ抜粋して載せています。

全体ソースはこちらのリンクを参照してください。

七並べソース(Googleドキュメント)

 

-ソース(一部抜粋)------------------------------------------------------

    def bachk(self,mov):    #置ける手札を取得

        #場札のカードが置かれている場所と置かれていない場所の境目を取得

        l=[]

        for j in range(4):

            for i in range(5,-1,-1):

            #7→A向きにサーチ

                if self.ba[j][i]<0:     #カードが置かれていない場所の場合

                    self.ba[j][i]=-2    #枠表示はカード無しをセット

                    l.append(j*100+i)

                    break

            for i in range(7,13,1):

            #7→K向きにサーチ

                if self.ba[j][i]<0:     #カードが置かれていない場所の場合

                    self.ba[j][i]=-2    #枠表示はカード無しをセット

                    l.append(j*100+i)

                    break

 

        #手札の置ける場所を取得

        lchk=[]

        if len(l)>0:

            for j in self.ply[mov]:

                for i in l:

                    if j==i:    #手札に境目のカードがある場合

                        lchk.append(i)

                        if self.openflg[mov]==1:

                            #手札表表示の場合、置ける場所に枠を表示

                            self.ba[i//100][i%100]=-1

        return lchk

 

    def dobon(self,mov):    #ドボン処理

        for i in self.ply[mov]:

            if i!=1000:     #残っている手札は場に置く

                self.ba[i//100][i%100]=1

        self.ply[mov]=[1000 for i in self.ply[mov]] #全手札を使用済みにする

        self.rank[mov]=4-self.endflg.count(1)   #順位を下から付ける

 

    def passed(self,mov):   #パス処理

        if self.endflg[mov]==0:     #プレイ中のプレイヤー

            self.passchuflg[mov]=1  #パス中にする

            self.passcnt[mov]-=1    #パス回数減算

            if self.passcnt[mov]<0: #パス回数がマイナス

                self.endflg[mov]=1  #ドボン

                self.dobon(self.mov)    #ドボン処理

        self.mov=(self.mov+1)%4     #プレイヤー交代

 

    def automov(self,mov,chk,l):    #次手思考

        if len(chk)==1:

            #置けるカードが1つの場合、そのカードのindexを返す

            return l.index(chk[0])

 

        cnot=[9,0]

        for i in chk:   #置けるカードループ

            if i%100==0 or i%100==12:

                #カードがAorKの場合、検証対象カードのindexを返す

                return l.index(i)

           

            #検証対象カードのマークと数を取得

            m=i//100

            s=i%100

            if s<=5:    #7より下位の場を検索

                cc=self.ba[m][:s].count(-2)

                if cc==0:

                    #空き無しの場合、検証対象カードのindexを返す

                    return l.index(i)

                else:

                    #空きありの場合、空きの少ないカードを保存

                    if cnot[0]>cc:

                        cnot=[cc,i]

            else:       #7より上位の場を検索

                cc=self.ba[m][s+1:].count(-2)

                if cc==0:

                    #空き無しの場合、検証対象カードのindexを返す

                    return l.index(i)

                else:

                    #空きありの場合、空きの少ないカードを保存

                    if cnot[0]>cc:

                        cnot=[cc,i]

 

        if cnot[0]!=9:

            #優先条件のカードの先の空きが少ないカードのindexを返す

            return l.index(cnot[1])

        #優先条件のカードが存在しない場合、先頭のカードのindexを返す

        return l.index(chk[0])

-------------------------------------------------------

 

・bachk処理について

場札の7を中心に大方向および小方向に「カードが置かれていない場所」を検索して、現在手番のプレイヤーの手札の中にそのカードがある場合は戻り値用リストにまとめて返します

また、手札が表表示指定の場合は場札の対象位置に枠を表示します。

 

                     ↓↓↓↓

                     ↓↓↓↓

 

・pass処理およびdobon処理について

bachk処理の戻り値のリストが空だった場合は場に出すカードが手札に無いことになり、自動でpass処理が呼び出されます。

更にpassの残数が0の状態でpass処理が行われるとdobon処理が呼び出されて、そのプレイヤーは手札を全て場札に出して退場となります。

 

また、オートフラグが「手動」に設定されているプレイヤーは任意にpassを行うことが出来ます。その場合もpass処理が呼び出されます。但し、任意のpassは残数0では行えないのでdobon処理に流れることはありません。

 

パス処理後は次の順のプレイヤーに交代します。

 

 

・automov処理について

オートフラグが「オート」に設定されているプレイヤーはautomov処理で場に出すカードが決定されます。そしてそのカードの位置(手札の中のindex)が返されます。

呼び出し元では戻り値のindexに応じた位置をクリックした様に変数値が設定され、その後は手札選択のクリックと同様に処理されます。

 

場に出すカードの判定は以下の順で行われます。

1.置けるカードが1つの場合、そのカードに決定される。

2.置けるカードが複数の場合、for文で置けるカードを順に検証し、条件に該当した時点でその検証対象カードに決定される。

 2-1.検証対象カード「A」または「K」の場合、そのカードに決定される。

 2-2.検証対象カード6以下の場合、検証対象カードより下位カードが置かれていない箇所があるかチェックする。置かれていない箇所が無い場合、そのカードに決定される。

   ※置かれていない箇所がある場合は置かれていない箇所がより少ないカードを保存しておく

 2-3.検証対象カード8以上の場合、検証対象カードより上位カードが置かれていない箇所があるかチェックする。置かれていない箇所が無い場合、そのカードに決定される。

   ※置かれていない箇所がある場合は置かれていない箇所がより少ないカードを保存しておく

 2-4.検証対象カード6以下の場合、手札の中に検証対象カードより小さいカードがあるかチェックする。存在した場合、そのカードに決定される。

 2-5.検証対象カード8以上の場合、手札の中に検証対象カードより大きいカードがあるかチェックする。存在した場合、そのカードに決定される。

 2-6.2-22-3で保存した置かれていない箇所がより少ない(端に近い)カードに決定される。

 2-7.検証対象カード2-1~2-6のいずれにも該当しない場合、置けるカードの中の先頭のindexのカードに決定される。

   ※但し、2-6までに決定しているはずなので2-7は保険的な条件になる

 

場に出すカードの選択の根拠として、以下の条件の順にカードを決定することにします。

①他のプレイヤーの手札を極力減らさない

②自分の手札を極力減らす

 

七並べは配られたカードで勝敗がほぼ決まるゲームですが、少しでも有利に進めるため①、②の条件を満たす様にカードを選択することにします。また、オートの場合は意図的なパスはしない仕様なのでパスは考慮しません。

 

以下に判定の詳細を処理順に解説します。

1:置けるカードが1つなので、無条件です。

 

2-1「A」と「K」は両端のカードなので他のプレイヤーの置ける場所を増やすことなく自分の手札を減らせます①と②の条件を満たすので優先的に選択されます。

 

2-2および2-3:基本的には2-1と同様の条件です。ドボンで抜けたプレイヤーの手札で両端が埋められた場合は「A」や「K」でなくても、その時点での両端になり得るので、これも①と②の条件を満たします

 

2-4および2-5手前のカードを置かないとその先のカードも置けない(「6」を置かないとその先の「A」も置けない等)仕様なので、自分の手札の中にその先のカードがある場合は、手前のカードを置くことで②の条件に繋がります。なお隣のカード離れたカードのどちらを優先するかは、どちらにもプラス面とマイナス面があるのでカードの値の距離は考慮しないことにしました。

 

2-6検証対象カードの先置かれていない箇所が少ないというのは、言い換えると他のプレイヤーが持っているカード置く箇所が少ないということになります。この図ではハートの方が置ける箇所が少ないのでハートの4に決定されます。

検証対象カードの先自分の手札のカードが含まれている場合(上図の場合、スペードのAor2が手札にある場合)は2-4または2-5の条件に該当するので、2-6まで処理が流れてきているということは検証対象カードの先自分の手札のカードは含まれていないことになります。

 

2-7:1~2-6までの判定に引っかからない場合は、どのカードも優先する理由がないことになるので先頭のカードを返しています。

 

(3)は以上です。(4)に続きます。