オセロをつくった
pythonでオセロのプログラムを書いた。
functions_othello.pyに使う関数をまとめた。
from functions_othello import * turn = 'black' #黒 B = board() #盤面生成 BP, able = check(B,turn) show_double(B,BP,turn) while able != 0: B, turn = place(B,BP,turn) BP, able = check(B,turn) show_double(B,BP,turn) if able == 0: if turn == 'black': BP, able = check(B,'white') if able == 0: break else: turn = 'white' print('黒を置ける場所はありません') show_double(B,BP,turn) else:#white BP, able = check(B,'black') if able == 0: break else: turn = 'black' print('白を置ける場所はありません') show_double(B,BP,turn) cnt_black_stone = 0 cnt_white_stone = 0 for i in range(8): for j in range(8): if B[i][j] == 'black': cnt_black_stone += 1 elif B[i][j] == 'white': cnt_white_stone += 1 show(B) if cnt_black_stone > cnt_white_stone: print('黒○ の勝ち') elif cnt_black_stone < cnt_white_stone: print('白● の勝ち') else: print('引き分け')
Bは現在の盤面を表し、'black'、'white'、'null'が入った8×8のリストです。
BPは石を置くことのできる位置を表し、'able'、'null'が入った8×8のリストです。
turnは黒と白のどちらの番であるかを表し、'black'または'white'です。
board()はオセロの初めの盤面を構成する関数です。
def board(): B = [['null' for i in range(8) ] for i in range(8)] B[3][3] = 'white' B[3][4] = 'black' B[4][3] = 'black' B[4][4] = 'white' return B
show(B)は現在の盤面をオセロ風に表示する関数です。
def show(B): BQ = ['null']*10 for i in range(1,9): s = chr(97 + i - 1) + '|' for j in range(8): if B[i-1][j] == 'white': s += '● ' elif B[i-1][j] == 'black': s += '○ ' else: s += ' ' s += '|' s += chr(97 + i - 1) BQ[i] = s K = ' |' for i in range(1,9): K += ' ' + str(i) K += '|' BQ[0] = K BQ[9] = K for i in range(10): print(BQ[i])
check(B,turn)は現在の盤面と番を入力することで、置ける位置と置ける枚数を返す関数です。
def check(B,turn):#BPとして置ける部分をマークしたものを出力したい #turn = 'black'の場合で解説を書く able = 0 BP = [['null' for i in range(8) ] for i in range(8)] #縦横斜めで順番にcheckしていく for i in range(8):#横 a = -1 k = 0 t = 2 for j in range(8): stone = B[i][j] if stone == 'null': if t == 1: if a >= 1: BP[i][j] = 'able' able += 1 k = j a = 0 t = 0 else: t = 0 k = j else: a = 0 k = j t = 0 elif stone != turn:#white if t == 1 or t == -1: a += 1 elif t == 0: a = 1 t = -1 else:#black if t == -1 and a >= 1: BP[i][k] = 'able' able += 1 k = j a = 0 t = 1 else: a = 0 t = 1 for j in range(8):#縦 a = -1 k = 0 t = 2 for i in range(8): stone = B[i][j] if stone == 'null': if t == 1: if a >= 1: BP[i][j] = 'able' able += 1 k = i a = 0 t = 0 else: t = 0 k = i else: a = 0 k = i t = 0 elif stone != turn:#white if t == 1 or t == -1: a += 1 elif t == 0: a = 1 t = -1 else:#black if t == -1 and a >= 1: BP[k][j] = 'able' able += 1 k = i a = 0 t = 1 else: a = 0 t = 1 for i in range(8):#斜め右上 a = -1 k = 0 t = 2 for j in range(8-i): stone = B[i+j][j] if stone == 'null': if t == 1: if a >= 1: BP[i+j][j] = 'able' able += 1 k = j a = 0 t = 0 else: t = 0 k = j else: k = j a = 0 t = 0 elif stone != turn:#white if t == 1 or t == -1: a += 1 elif t == 0: a = 1 t = -1 else:#black if t == -1 and a >= 1: BP[i+k][k] = 'able' able += 1 k = j a = 0 t = 1 else: a = 0 t = 1 for j in range(1,8):#斜め左下 a = -1 k = 0 t = 2 for i in range(8-j): stone = B[i][i+j] if stone == 'null': if t == 1: if a >= 1: BP[i][i+j] = 'able' able += 1 k = i a = 0 t = 0 else: t = 0 k = i else: a = 0 k = i t = 0 elif stone != turn:#white if t == 1 or t == -1: a += 1 elif t == 0: a = 1 t = -1 else:#black if t == -1 and a >= 1: BP[k][k+j] = 'able' able += 1 k = i a = 0 t = 1 else: a = 0 t = 1 for i in range(8):#斜め左上 a = -1 k = 0 t = 2 for j in range(8-i): stone = B[7-i-j][j] if stone == 'null': if t == 1: if a >= 1: BP[7-i-j][j] = 'able' able += 1 k = j a = 0 t = 0 else: t = 0 k = j else: k = j a = 0 t = 0 elif stone != turn:#white if t == 1 or t == -1: a += 1 elif t == 0: a = 1 t = -1 else:#black if t == -1 and a >= 1: BP[7-i-k][k] = 'able' able += 1 k = j a = 0 t = 1 else: a = 0 t = 1 for j in range(1,8):#斜め右下 a = -1 k = 0 t = 2 for i in range(8-j): stone = B[7-i][i+j] if stone == 'null': if t == 1: if a >= 1: BP[7-i][i+j] = 'able' able += 1 k = i a = 0 t = 0 else: t = 0 k = i else: a = 0 k = i t = 0 elif stone != turn:#white if t == 1 or t == -1: a += 1 elif t == 0: a = 1 t = -1 else:#black if t == -1 and a >= 1: BP[7-k][k+j] = 'able' able += 1 k = i a = 0 t = 1 else: a = 0 t = 1 return BP, able
show_able(BP)は置ける場所を三角で表示する関数です。必要はない。
def show_able(BP): BPQ = ['null']*10 for i in range(1,9): s = chr(97 + i - 1) + '|' for j in range(8): if BP[i-1][j] == 'able': s += '△ ' else: s += ' ' s += '|' s += chr(97 + i - 1) BPQ[i] = s K = ' |' for i in range(1,9): K += ' ' + str(i) K += '|' BPQ[0] = K BPQ[9] = K for i in range(10): print(BPQ[i])
place(B,BP,turn)は石をどこに置くかの入力を求めて、それが置けるかどうか判断して、実際に現状の盤面Bを更新する関数です。
更新はupdate(B,turn,x,y)に任せた。
def place(B,BP,turn):#turnの人が入力してそれを盤面に反映する while True: if turn == 'black': S = list(input('黒○ の番です。置きたい位置を入力してください。(例:5d)')) else: S = list(input('白● の番です。置きたい位置を入力してください。(例:5d)')) x, y = ord(S[1])-97, int(S[0]) -1 if BP[x][y] == 'able': if turn == 'black': B = update(B,turn,x,y) turn = 'white' else:#white B = update(B,turn,x,y) turn = 'black' return B, turn else: print('そこは置けません') show_double(B,BP,turn) pass
update(B,turn,x,y)はx,y成分に石が置かれた場合の盤面の更新をする関数です。
def update(B,turn,x,y): S = [] for i in range(x-1,-1,-1):#北 if B[i][y] == 'null': break elif B[i][y] == turn:#black for j in S: B[j][y] = turn break else:#white S.append(i) S = [] for i in range(x+1,8):#南 if B[i][y] == 'null': break elif B[i][y] == turn:#black for l in S: B[l][y] = turn break else:#white S.append(i) S = [] for j in range(y-1,-1,-1):#西 if B[x][j] == 'null': break elif B[x][j] == turn:#black for l in S: B[x][l] = turn break else:#white S.append(j) S = [] for j in range(y+1,8):#東 if B[x][j] == 'null': break elif B[x][j] == turn:#black for l in S: B[x][l] = turn break else:#white S.append(j) if x <= y:#右上 S = [] for i in range(x-1,-1,-1): if B[i][y-x+i] == 'null': break elif B[i][y-x+i] == turn: for l in S: B[l][y-x+l] = turn break else: S.append(i) S = [] for j in range(y+1,8): if B[x+j-y][j] == 'null': break elif B[x+j-y][j] == turn: for l in S: B[x+l-y][l] = turn break else: S.append(j) else:#左下 S = [] for j in range(y-1,-1,-1): if B[x-y+j][j] == 'null': break elif B[x-y+j][j] == turn: for l in S: B[x-y+l][l] = turn break else: S.append(j) S = [] for i in range(x+1,8): if B[i][y+i-x] == 'null': break elif B[i][y+i-x] == turn: for l in S: B[l][y+l-x] = turn break else: S.append(i) if x + y <= 7:#左上 S = [] for i in range(x-1,-1,-1): if B[i][y+x-i] == 'null': break elif B[i][y+x-i] == turn: for l in S: B[l][y+x-l] = turn break else: S.append(i) S = [] for j in range(y-1,-1,-1): if B[x+y-j][j] == 'null': break elif B[x+y-j][j] == turn: for l in S: B[x+y-l][l] = turn break else: S.append(j) else:#右下 S = [] for i in range(x+1,8): if B[i][y+x-i] == 'null': break elif B[i][y+x-i] == turn: for l in S: B[l][y+x-l] = turn break else: S.append(i) S = [] for j in range(y+1,8): if B[x+y-j][j] == 'null': break elif B[x+y-j][j] == turn: for l in S: B[x+y-l][l] = turn break else: S.append(j) B[x][y] = turn return B
show_double(B,BP,turn)は前述のshow(B)とshow_able(B,BP)を合わせたものです。
def show_double(B,BP,turn): if turn == 'black': T = '△ ' else: T = '▲ ' BandBP= ['null']*10 for i in range(1,9): s = chr(97 + i - 1) + '|' for j in range(8): if B[i-1][j] == 'white': s += '● ' elif B[i-1][j] == 'black': s += '○ ' elif BP[i-1][j] == 'able': s += T else: s += ' ' s += '|' s += chr(97 + i - 1) BandBP[i] = s K = ' |' for i in range(1,9): K += ' ' + str(i) K += '|' BandBP[0] = K BandBP[9] = K for i in range(10): print(BandBP[i])