2
1

オセロ、ランダム実行

Last updated at Posted at 2023-09-29

前回の記事で本職の方にクラスの使い方をご指導いただけたので、その反省とアウトプットとしてオセロをランダムな置き方で終了まで実行するコードを作りました。
これを基盤として、盤面の状態価値を推定していきたいです。

オセロ、ランダム実行
import copy
import random


class Board:
    
    dir=[-11,-10,-9,-1,1,9,10,11]
    
    def __init__(self):
        self.turn=0
        self.reward=[0,0,0,0,0,0,0,0,0,0]#場所ごとの報酬を管理
        """ボードの作成(空き→0,黒→1、白→2、置ける場所→3,壁→5)"""
        self.places=[5,5,5,5,5,5,5,5,5,5,
                     5,0,0,0,0,0,0,0,0,5,
                     5,0,0,0,0,0,0,0,0,5,
                     5,0,0,0,3,0,0,0,0,5,
                     5,0,0,3,2,1,0,0,0,5,
                     5,0,0,0,1,2,3,0,0,5,
                     5,0,0,0,0,3,0,0,0,5,
                     5,0,0,0,0,0,0,0,0,5,
                     5,0,0,0,0,0,0,0,0,5,
                     5,5,5,5,5,5,5,5,5,5]
         
    def put(self,player,place):
        """placeに置いて裏返す、placeには置ける場所のみ"""
        sum_rev=0#裏返せる枚数の総数
        for i in self.dir:#すべての方向を探索
            cnt_rev=0
            tmp_place=place
            while True:#裏返す
                if self.places[tmp_place+i]==player.opp_disc:
                    tmp_place+=i
                    cnt_rev+=1
                elif self.places[tmp_place+i]==player.disc:
                    break
                else:
                    cnt_rev=0
                    break
            if cnt_rev!=0:#裏返せた
                for j in range(cnt_rev+1):#裏返す
                    self.places[tmp_place-i*j]=player.disc
            sum_rev+=cnt_rev
        return sum_rev

    def cnt_disc(self):
        """枚数を返す"""
        cnt1=0
        cnt2=0
        for i in range(100):
                if self.places[i]==1:
                    cnt1+=1
                elif self.places[i]==2:
                    cnt2+=1
        return cnt1,cnt2

    def show(self):
        for i in range(100):
            if self.places[i]!=5:
                print(self.places[i],end=' ')
                if i%10==8:
                    print("\n")
        print("\n")
    

class Player:
    
    def __init__(self,disc,opp_disc):
        self.disc=disc
        self.opp_disc=opp_disc#相手の石
        self.can_place=[34,43,56,65]
        
    def put(self,board):
        """ランダムに置く"""
        place=random.choice(self.can_place)
        board.put(self,place)
    
    def check(self,board):
        """can_placeに置ける場所の座標を入れる"""
        self.can_place.clear()
        for i in range(100):
            if board.places[i]==3:
                board.places[i]=0
            if board.places[i]==0:
                tmp_board=copy.deepcopy(board)#ボードをコピー
                sum_rev=tmp_board.put(self,i)
                if sum_rev!=0:#裏返せたら
                    self.can_place.append(i)#置ける場所に追加
                    board.places[i]=3
    

def main():
    player1=Player(1,2)
    player2=Player(2,1)
    player=player1
    turn={player1:player2,player2:player1}
    board=Board()
    while True:
        player.put(board)
        player=turn[player]
        player.check(board)
        if len(player.can_place)==0:
            player=turn[player]
            player.check(board)
            if len(player.can_place)==0:
                break
    cnt1,cnt2=board.cnt_disc()
    if cnt1>cnt2:
        print("1の勝ちです")
    elif cnt1==cnt2:
        print("引き分けです")
    elif cnt1<cnt2:
        print("2の勝ちです")
        

if __name__ == "__main__":
    main()
2
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1