0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Tkinterを用いたオセロ

Posted at

tkinterを用いたオセロゲーム

開発環境:VScode python 3.10.2

実行結果
仕様:下記のpythonプログラムを実行すると2つのウィンドウが表示される(図1)。図1の右のウィンドウにおきたいマス(行>row(1-8行)、列>col(1-8列))を入力し「ok」をクリック。その後、vscodeのコンソール上で任意の文字を入力すると、図3のように駒が置かれる。

図1:実行結果(1)
スクリーンショット_20230126_173448.png

図2:実行結果(2)
スクリーンショット_20230126_173508.png

図3:実行結果(3)
スクリーンショット_20230126_173530.png

#othelloプログラム
#作成日:2022/12/07
#モジュールインストール
import tkinter as tk

#駒が置けるか判定する関数
def judge(bw,rowcol,board):
    #変数定義
    i=1 #ループカウンタ、走査する際に使用する
    j=1 #ループカウンタ、走査する際に使用する
    cnt=0 #カウンタ変数、何枚ひっくり返すか記憶する変数
    ok=0 #一枚でもひっくり返せたら1にする
    way=0 #どこの向きを走査するか 1:上 2:下 3:右 4:左 5:右上 6:左上 7:左下 8:右下

    if(1>rowcol[0] or 8<rowcol[0] or 1>rowcol[1] or 8<rowcol[1]):
        print('存在しないマスです。')
        return 1


    #置けるかどうかチェック
    #way 1:上 2:下 3:右 4:左 5:右上 6:右下 7:左上 8:左下
    for way in range(1,9):
        cnt=0 #変数の初期化
        if(way==1 or way==2):
            i=0
        if(way==3 or way==5 or way==6):
            i=1
        if(way==4 or way==7 or way==8):
            i=-1
        if(way==3 or way==4):
            j=0
        if(way==2 or way==6 or way==8):
            j=1
        if(way==1 or way==5 or way==7):
            j=-1

        if(bw==1): #黒色(bw==1)の場合
            if(board[rowcol[1]+i][rowcol[0]+j]==2): #特定の方向が白色
                cnt+=1
                if(way==1 or way==5 or way==7):
                    j-=1
                if(way==2 or way==6 or way==8):
                    j+=1
                if(way==3 or way==5 or way==6):
                    i+=1
                if(way==4 or way==7 or way==8):
                    i-=1
                while(board[rowcol[1]+i][rowcol[0]+j]==2): #その方向に白色がいくつあるのか
                    cnt+=1
                    if(way==1 or way==5 or way==7):
                        j-=1
                    if(way==2 or way==6 or way==8):
                        j+=1
                    if(way==3 or way==5 or way==6):
                        i+=1
                    if(way==4 or way==7 or way==8):
                        i-=1
                if(board[rowcol[1]+i][rowcol[0]+j]==bw): #黒までをひっくり返す
                    ok=1
                    while(cnt>0):
                        if(way==1):#上方向ひっくり返す
                            board[rowcol[1]][rowcol[0]-cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1)*50,5+(rowcol[0]-1-cnt)*50,45+(rowcol[1]-1)*50,45+(rowcol[0]-1-cnt)*50,fill='black')
                        if(way==2):#下方向ひっくり返す
                            board[rowcol[1]][rowcol[0]+cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1)*50,5+(rowcol[0]-1+cnt)*50,45+(rowcol[1]-1)*50,45+(rowcol[0]-1+cnt)*50,fill='black')
                        if(way==3):#右方向ひっくり返す
                            board[rowcol[1]+cnt][rowcol[0]]=bw
                            canvas.create_oval(5+(rowcol[1]-1+cnt)*50,5+(rowcol[0]-1)*50,45+(rowcol[1]-1+cnt)*50,45+(rowcol[0]-1)*50,fill='black')
                        if(way==4):#左方向ひっくり返す
                            board[rowcol[1]-cnt][rowcol[0]]=bw
                            canvas.create_oval(5+(rowcol[1]-1-cnt)*50,5+(rowcol[0]-1)*50,45+(rowcol[1]-1-cnt)*50,45+(rowcol[0]-1)*50,fill='black')
                        if(way==5):#右上方向ひっくり返す
                            board[rowcol[1]+cnt][rowcol[0]-cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1+cnt)*50,5+(rowcol[0]-1-cnt)*50,45+(rowcol[1]-1+cnt)*50,45+(rowcol[0]-1-cnt)*50,fill='black')
                        if(way==6):#右下方向ひっくり返す
                            board[rowcol[1]+cnt][rowcol[0]+cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1+cnt)*50,5+(rowcol[0]-1+cnt)*50,45+(rowcol[1]-1+cnt)*50,45+(rowcol[0]-1+cnt)*50,fill='black')
                        if(way==7):#左上方向ひっくり返す
                            board[rowcol[1]-cnt][rowcol[0]-cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1-cnt)*50,5+(rowcol[0]-1-cnt)*50,45+(rowcol[1]-1-cnt)*50,45+(rowcol[0]-1-cnt)*50,fill='black')
                        if(way==8):#左下方向ひっくり返す
                            board[rowcol[1]-cnt][rowcol[0]+cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1-cnt)*50,5+(rowcol[0]-1+cnt)*50,45+(rowcol[1]-1-cnt)*50,45+(rowcol[0]-1+cnt)*50,fill='black')
                        cnt-=1
            #一枚でもひっくり返したら指定された場所に黒色を置く
            if(ok==1):
                board[rowcol[1]][rowcol[0]]=bw
                canvas.create_oval(5+(rowcol[1]-1)*50,5+(rowcol[0]-1)*50,45+(rowcol[1]-1)*50,45+(rowcol[0]-1)*50,fill='black')

        if(bw==2): #白色(bw==2)の場合
            if(board[rowcol[1]+i][rowcol[0]+j]==1): #特定の方向が黒色
                cnt+=1
                if(way==1 or way==5 or way==7):
                    j-=1
                if(way==2 or way==6 or way==8):
                    j+=1
                if(way==3 or way==5 or way==6):
                    i+=1
                if(way==4 or way==7 or way==8):
                    i-=1
                while(board[rowcol[1]+i][rowcol[0]+j]==1): #その方向に黒色がいくつあるのか
                    cnt+=1
                    if(way==1 or way==5 or way==7):
                        j-=1
                    if(way==2 or way==6 or way==8):
                        j+=1
                    if(way==3 or way==5 or way==6):
                        i+=1
                    if(way==4 or way==7 or way==8):
                        i-=1
                if(board[rowcol[1]+i][rowcol[0]+j]==bw): #黒までをひっくり返す
                    ok=1
                    while(cnt>0):
                        if(way==1):#上方向ひっくり返す
                            board[rowcol[1]][rowcol[0]-cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1)*50,5+(rowcol[0]-1-cnt)*50,45+(rowcol[1]-1)*50,45+(rowcol[0]-1-cnt)*50,fill='white')
                        if(way==2):#下方向ひっくり返す
                            board[rowcol[1]][rowcol[0]+cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1)*50,5+(rowcol[0]-1+cnt)*50,45+(rowcol[1]-1)*50,45+(rowcol[0]-1+cnt)*50,fill='white')
                        if(way==3):#右方向ひっくり返す
                            board[rowcol[1]+cnt][rowcol[0]]=bw
                            canvas.create_oval(5+(rowcol[1]-1+cnt)*50,5+(rowcol[0]-1)*50,45+(rowcol[1]-1+cnt)*50,45+(rowcol[0]-1)*50,fill='white')
                        if(way==4):#左方向ひっくり返す
                            board[rowcol[1]-cnt][rowcol[0]]=bw
                            canvas.create_oval(5+(rowcol[1]-1-cnt)*50,5+(rowcol[0]-1)*50,45+(rowcol[1]-1-cnt)*50,45+(rowcol[0]-1)*50,fill='white')
                        if(way==5):#右上方向ひっくり返す
                            board[rowcol[1]+cnt][rowcol[0]-cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1+cnt)*50,5+(rowcol[0]-1-cnt)*50,45+(rowcol[1]-1+cnt)*50,45+(rowcol[0]-1-cnt)*50,fill='white')
                        if(way==6):#右下方向ひっくり返す
                            board[rowcol[1]+cnt][rowcol[0]+cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1+cnt)*50,5+(rowcol[0]-1+cnt)*50,45+(rowcol[1]-1+cnt)*50,45+(rowcol[0]-1+cnt)*50,fill='white')
                        if(way==7):#左上方向ひっくり返す
                            board[rowcol[1]-cnt][rowcol[0]-cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1-cnt)*50,5+(rowcol[0]-1-cnt)*50,45+(rowcol[1]-1-cnt)*50,45+(rowcol[0]-1-cnt)*50,fill='white')
                        if(way==8):#左下方向ひっくり返す
                            board[rowcol[1]-cnt][rowcol[0]+cnt]=bw
                            canvas.create_oval(5+(rowcol[1]-1-cnt)*50,5+(rowcol[0]-1+cnt)*50,45+(rowcol[1]-1-cnt)*50,45+(rowcol[0]-1+cnt)*50,fill='white')
                        cnt-=1
            #一枚でもひっくり返したら指定された場所に白色を置く
            if(ok==1):
                board[rowcol[1]][rowcol[0]]=bw
                canvas.create_oval(5+(rowcol[1]-1)*50,5+(rowcol[0]-1)*50,45+(rowcol[1]-1)*50,45+(rowcol[0]-1)*50,fill='white')
    #何もひっくり返せなかったとき            
    if(ok==0):
        return 1            

#ボード表示関数
def display(board):
    cnt=1 #何行目かを記憶する変数
    for i in range(10):
        if(i==0):#列番号表示
            for k in range(9):
                if(k==0):
                    print(' ',end=' ')
                else:
                    print(k,end=' ')
            print()
        for j in range(10):
            if(i!=0 and i!=9):#行番号表示
                if(j==0 and j!=9):
                    print(cnt,end=' ')
                    cnt+=1
            if(board[j][i]==0):#何も置かれていないマスの表示
                print('',end=' ')
            if(board[j][i]==1):#黒色表示
                print('',end=' ')
            if(board[j][i]==2):#白色表示
                print('',end=' ') 
        if(i!=0):
            print()

#ボードの黒色と白色の枚数を数える関数
def check(board,bw):
    cnt_black=0 #黒色の枚数
    cnt_white=0 #白色の枚数
    
    for i in range(1,9):
        for j in range(1,9):
            if(board[j][i]==1): #黒色の枚数チェック
                cnt_black+=1
            if(board[j][i]==2): #白色の枚数チェック
                cnt_white+=1
    if(bw==1): #黒色のターンのとき
        return cnt_black
    if(bw==2): #白色のターンのとき
        return cnt_white

#OKボタンがクリックされた時windows_sb2のウィンドウのentryから文字列を取得する関数
def button_ok(rowcol):
    global count
    #入力されている行列を取得する
    rowcol[0]=int(entry1.get())
    rowcol[1]=int(entry2.get())

    count+=1

    #entryの文字列をクリア
    entry1.delete(0,tk.END)
    entry2.delete(0,tk.END)

#変数、リストの定義
board=[[0 for i in range(10)]for i in range(10)] #オセロボードのリスト[列][行]
rowcol=[0,0] #行列のリスト [行,列]
flag=0 #状態記憶変数 0:正常 1:異常
masu=60 #残りのマスの変数
bw=1 #黒色か白色か記憶する変数 1:黒色 2:白色
result_black=0 #黒色の最終枚数
result_white=0 #白色の最終枚数
tm=0 #時間の変数
count=0 #グローバル変数の定義 button_okで使用する
buf=0 #便宜的な変数
start=0 #初める変数

#ウィンドウ(アプリ)の作成(メインウィンドウ)
windows = tk.Tk()
windows.geometry("500x600+100+100") #ウィンドウサイズ、位置指定
windows.title('othello') #ウィンドウ名
windows.configure(bg='beige') #背景色設定

#ウィンドウ(アプリ)の作成(サブ2ウィンドウ)
windows_sb2 = tk.Tk()
windows_sb2.geometry("200x120+650+100") #ウィンドウサイズ、位置指定
windows_sb2.title('The rule of othello') #ウィンドウ名
windows_sb2.configure(bg='beige') #背景色設定

#フレーム、エントリーの作成
frame = tk.Frame(windows_sb2,width=200,height=120,bg='beige')
entry1=tk.Entry(frame)
entry2=tk.Entry(frame)

#ラベルの作成
label_row = tk.Label(frame,font = ("Helvetica", 10), text = "row",bg='beige')
label_col = tk.Label(frame,font = ("Helvetica", 10), text = "col",bg='beige')

#ボタンの作成
button = tk.Button(frame,text='OK',command=lambda:button_ok(rowcol))
button.place(x=40,y=85)

#フレーム、エントリー、ラベルの配置
frame.place(x=0,y=0)
label_row.place(x=10,y=18)
label_col.place(x=10,y=53)
entry1.place(x=40,y=20)
entry2.place(x=40,y=55)

#canvasの設定
canvas = tk.Canvas(windows,width=400,height=400,background="white")

#canvasの配置
canvas.place(x=50,y=50)

#ボード生成
for i in range(1,9):
    for j in range(1,9):
        canvas.create_rectangle((j-1)*50, (i-1)*50, j*50, i*50, fill = 'green3',outline='black')

#ボード初期化
canvas.create_oval(155,155,195,195,fill='white')
canvas.create_oval(205,205,245,245,fill='white')
canvas.create_oval(205,155,245,195,fill='black')
canvas.create_oval(155,205,195,245,fill='black')

#ラベルの配置
label = tk.Label(windows, font = ("Helvetica", 20), text = "othello")

#ラベルの配置、背景色の設定
label.place(x=50,y=10)
label.configure(bg='beige')

#オセロボードの初期化
board[4][4]=2 #初期白色配置
board[5][5]=2 #初期白色配置
board[5][4]=1 #初期黒色配置
board[4][5]=1 #初期黒色配置

# オセロボード仕様 
# 0(☐):何も置かれていないマス
# 1():黒色が置かれているマス
# 2():白色が置かれているマス
# 9(✕):置いてはいけないマス
#
# 0123456789 列(col)
#0✕✕✕✕✕✕✕✕✕✕
#1✕☐☐☐☐☐☐☐☐✕
#2✕☐☐☐☐☐☐☐☐✕
#3✕☐☐☐☐☐☐☐☐✕
#4✕☐☐☐21☐☐☐✕
#5✕☐☐☐12☐☐☐✕
#6✕☐☐☐☐☐☐☐☐✕
#7✕☐☐☐☐☐☐☐☐✕
#8✕☐☐☐☐☐☐☐☐✕
#9✕✕✕✕✕✕✕✕✕✕
#行(row)

#置いてはいけないマスの設定
for i in range(10):
    board[i][0]=9
    board[i][9]=9
    board[0][i]=9
    board[9][i]=9

#ゲームスタート
print('ゲームスタート!!!')
bw=1 #黒色から始めるようにする
while masu>0:
    #display(board)
    flag=0

    #黒色のターン
    if(bw==1):
        print('---黒色のターン---\n')

        #ラベルの作成(どちらのターン)
        label_bw = tk.Label(windows,font = ("Helvetica", 20), text = "黒色のターン")

        #ラベルの配置、背景色の設定
        label_bw.place(x=50,y=460)
        label_bw.configure(bg='beige')

        #ラベルの作成(黒色白色何枚)
        label_howmany = tk.Label(windows,font = ("Helvetica", 20),text = f'黒:{check(board,1)}  白:{check(board,2)}')

        #ラベルの配置、背景色の設定
        label_howmany.place(x=150,y=10)
        label_howmany.configure(bg='beige')
       
        #どこに置くか入力待ち
        ok=input('右下のウィンドウにどこに置くか入力してください。\n入力し終わったら任意のキーを押し、エンターキーを押してください。')
        
        #置けるのか判定する
        flag=judge(bw,rowcol,board)
        if(flag==1):
            print('もう一度入力してください。')
            continue
        else:
            masu-=1 #一枚置いたことを記憶する
            bw=2
            #display(board)
    
    flag=0
    #白色のターン
    if(bw==2):
        print('---白色のターン---\n')

        #ラベルの作成
        label_bw = tk.Label(windows, font = ("Helvetica", 20),text = "白色のターン")

        #ラベルの配置、背景色の設定
        label_bw.place(x=50,y=460)
        label_bw.configure(bg='beige')

        #ラベルの作成(黒色白色何枚)
        label_howmany = tk.Label(windows,font = ("Helvetica", 20), text = f'黒:{check(board,1)}  白:{check(board,2)}')

        #ラベルの配置、背景色の設定
        label_howmany.place(x=150,y=10)
        label_howmany.configure(bg='beige')

        #どこに置くか
        ok=input('右下のウィンドウにどこに置くか入力してください。\n入力し終わったら任意のキーを押し、エンターキーを押してください。')
        #置けるのか判定する
        flag=judge(bw,rowcol,board)
        if(flag==1):
            print('もう一度入力してください。')
            continue
        else:
            masu-=1
            bw=1
            #display(board)
 
#スコア表示
#ウィンドウ(アプリ)の作成(サブ2ウィンドウ)
windows_sb1 = tk.Tk()
windows_sb1.geometry("400x300+650+300") #ウィンドウサイズ、位置指定
windows_sb1.title('The result of othello') #ウィンドウ名
windows_sb1.configure(bg='beige') #背景色設定

#ラベルの作成
label_result = tk.Label(windows_sb2, font = ("Helvetica", 20),text = f"result\n\n黒:{check(board,1)}  白:{check(board,2)}")
label_result.place(x=50,y=50)
label_result.configure(bg='beige')

windows.mainloop()
windows_sb1.mainloop()
windows_sb2.mainloop()
0
0
1

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?