pythonでオセロ(8×8)を作る方法のコード
このページでは「pythonでオセロ(8×8)を作る方法」のコードを載せています。
アルゴリズムや解説を読みたい方はこちらから
pythonのコード
import numpy as np
import random
import copy
def stone_location(stone):
stone_list =[]
tuple_list = np.where(field == stone)
for i in range(len(tuple_list[0])):
stone_list.append((tuple_list[0][i], tuple_list[1][i]))
return stone_list
def empty_location(stone_list):
emp = {}
for x, y in stone_list:
for i, j in offset:
p = (x+i, y+j)
if((p[0] <= 7) and (p[0] >= 0) and (p[1] <= 7) and (p[1] >= 0) ):
if((field[p] == EMPTY) and not(p in emp)):
emp[p] = []
emp[p].append((i, j))
elif((field[p] == EMPTY) and (p in emp)):
emp[p].append((i, j))
else:
pass
else:
pass
return emp
def bw_turn(TURN):
stone_list = stone_location(3 - TURN)
emp = empty_location(stone_list)
stone_possible = []
stone_dic = {}
for kx, ky in emp.keys():
for vx, vy in emp[kx, ky]:
addx = vx*(-1)
addy = vy*(-1)
px = kx+(vx*(-1))
py = ky+(vy*(-1))
p = (px, py)
while((px >=0 and px <= 7) and (py >= 0 and py <= 7)):
if(field[p] == (3 - TURN)):
pass
elif(field[p] == TURN):
if(not((kx, ky) in stone_dic) and not((kx, ky) in stone_possible)):
stone_possible.append((kx, ky))
stone_dic[(kx, ky)] = [(addx, addy)]
elif(((kx, ky) in stone_dic) and ((kx, ky) in stone_possible)):
stone_dic[(kx, ky)].append((addx, addy))
break
else:
break
px = px + addx
py = py + addy
p = (px, py)
# black_possibleから1つ選出する
if(len(stone_possible) == 0):
return (-1, -1), [(0, 0)]
r = random.randrange(len(stone_possible))
return stone_possible[r], stone_dic[stone_possible[r]]
def update_field(TURN, point, offset_list):
px = point[0]
py = point[1]
update_possible = []
update_possible.append(point)
for addx, addy in offset_list:
vx = px
vy = py
value = point
while((vx >=0 and vx <= 8) and (vy >= 0 and vy <= 8)):
p = field[value]
if((p == TURN) or (p == EMPTY) and not(value in update_possible)):
break
elif((p != TURN) and (p != EMPTY) and not(value in update_possible)):
update_possible.append(value)
else:
pass
vx = vx + addx
vy = vy + addy
value = (vx, vy)
for i in update_possible:
field[i] = TURN
return field
def address2point(address):
for i in range(8):
for j in range(8):
if(field_address[(i, j)] == address and field[(i, j)] == 0):
return (i, j)
return (-1, -1)
def point2offset(point, TURN):
px = point[0]
py = point[1]
p2o_list = []
for i, j in offset:
vx = px + i
vy = py + j
p = (vx, vy)
if((p[0] <= 7) and (p[0] >= 0) and (p[1] <= 7) and (p[1] >= 0) and (field[p] != TURN) and (field[p] != EMPTY)):
vx = vx + i
vy = vy + j
p = (vx, vy)
while((p[0] <= 7) and (p[0] >= 0) and (p[1] <= 7) and (p[1] >= 0)):
if(field[p] != TURN and field[p] != EMPTY):
pass
elif(field[p] == TURN and field[p] != EMPTY):
p2o_list.append((i, j))
break
elif(field[p] != TURN and field[p] == EMPTY):
break
vx = vx + i
vy = vy + j
p = (vx, vy)
return p2o_list
def address_check(point, TURN):
bw_stone = stone_location(3-TURN)
emp = empty_location(bw_stone)
stone_possible = []
stone_dic = {}
for kx, ky in emp.keys():
for vx, vy in emp[kx, ky]:
addx = vx*(-1)
addy = vy*(-1)
px = kx+(vx*(-1))
py = ky+(vy*(-1))
p = (px, py)
while((px >=0 and px <= 7) and (py >= 0 and py <= 7)):
if(field[p] != TURN):
pass
elif(field[p] == TURN):
if(not((kx, ky) in stone_dic) and not((kx, ky) in stone_possible)):
stone_possible.append((kx, ky))
stone_dic[(kx, ky)] = [(addx, addy)]
elif(((kx, ky) in stone_dic) and ((kx, ky) in stone_possible)):
stone_dic[(kx, ky)].append((addx, addy))
break
else:
break
px = px + addx
py = py + addy
p = (px, py)
if(point in stone_possible):
return True
return False
def point2address(point):
if(field_address[point] and field[point] == 0):
return field_address[point]
return z0
def show_result():
black_stone = 0
white_stone = 0
for i in range(8):
for j in range(8):
stone = field[(i, j)]
if(stone == 1):
black_stone += 1
elif(stone == 2):
white_stone += 1
else:
pass
s = ""
winner = ""
if(black_stone < white_stone):
winner = "後手(白石)"
s = "勝者は{0}".format(winner)
elif(black_stone > white_stone):
winner = "先手(黒石)"
s = "勝者は{0}".format(winner)
elif(black_stone == white_stone):
s = "引き分け"
else:
winner = ""
print("")
print("===================")
print("結果発表")
print("黒石:{0}石".format(black_stone))
print("白石:{0}石".format(white_stone))
print("")
print("よって、{0}です。".format(s))
def main():
# define
global EMPTY
EMPTY = 0
global BLACK
BLACK = 1
global WHITE
WHITE = 2
global Player
global Computer
global TURN
global field
field = np.array([[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,2,1,0,0,0],
[0,0,0,1,2,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0]])
global field_address
field_address = np.array([["a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1"],
["a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2"],
["a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3"],
["a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4"],
["a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5"],
["a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6"],
["a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7"],
["a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8"]]) # 4
global offset_x
offset_x = [-1, 0, 1]
global offset_y
offset_y = [-1, 0, 1]
global offset
offset = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 0), (0, 1), (1, -1), (1, 0), (1, 1)]
""" program """
print("先手:BLACK (1)")
print("後手:WHITE (2)")
print("空欄:EMPTY (0)")
Player = input("先手か後手を選んでください:")
if(Player == "BLACK"):
Player = BLACK
Computer = WHITE
TURN = Player
elif(Player == "WHITE"):
Player = WHITE
Computer = BLACK
TURN = Computer
else:
print("error : Please write your turn.(BLACK or WHITE)")
return field
print("")
print(field)
print("")
print(field_address)
num = 0
before_field = copy.copy(field)
after_field = copy.copy(field)
while(TURN != 0):
if(TURN == BLACK):
point, offset_list = bw_turn(BLACK)
if(TURN == Player):
print("TURN : You")
if(point == (-1, -1)): # pass判定
print("pass")
print(field)
TURN = WHITE
if((before_field == after_field).all()): # 両者pass判定
print("両者passのため対局を終了")
TURN = 0
break
before_field = copy.copy(after_field)
continue
address = input("石を置く場所を指定してください : ")
point = address2point(address)
offset_list = point2offset(point, Player)
if(not(address_check(point, TURN))): # 有効手判定
print("「{0}」は無効な手です。".format(address))
print("よって、対局を終了します。")
print(field)
TURN = 0
break
elif(TURN == Computer):
print("TURN : Computer")
if(point == (-1, -1)): # pass判定
print("pass")
print(field)
TURN = WHITE
if((before_field == after_field).all()): # 両者pass判定
print("両者passのため対局を終了")
TURN = 0
break
before_field = copy.copy(after_field)
continue
print("石を置く場所 : {0} ".format(point2address(point)))
else:
print("error")
TURN = 0
break
field = update_field(TURN, point, offset_list)
print(field)
print("")
before_field = copy.copy(after_field)
after_field = copy.copy(field)
TURN = WHITE
elif(TURN == WHITE):
point, offset_list = bw_turn(WHITE)
if(TURN == Player):
print("TURN : You")
if(point == (-1, -1)): # pass判定
print("pass")
print(field)
TURN = BLACK
if((before_field == after_field).all()): # 両者pass判定
print("両者passのため対局を終了")
TURN = 0
break
before_field = copy.copy(after_field)
continue
address = input("石を置く場所を指定してください : ")
point = address2point(address)
offset_list = point2offset(point, Player)
if(not(address_check(point, TURN))): # 有効手判定
print("「{0}」は無効な手です。".format(address))
print(field)
TURN = 0
break
elif(TURN == Computer):
print("TURN : Computer")
if(point == (-1, -1)): # pass判定
print("pass")
print(field)
TURN = BLACK
if((before_field == after_field).all()): # 両者pass判定
print("両者passのため対局を終了")
TURN = 0
break
before_field = copy.copy(after_field)
continue
print("石を置く場所 : {0} ".format(point2address(point)))
else:
print("error")
TURN = 0
break
field = update_field(TURN, point, offset_list)
print(field)
print("")
before_field = copy.copy(after_field)
after_field = copy.copy(field)
TURN = BLACK
else:
print("error")
TURN = 0
break
if(len(np.where(field == 0)[0]) == 0):
print("")
print(field)
print("")
print("対局を終了します。")
print("")
show_result()
TURN = 0
break
return field
if __name__ == '__main__':
main()
スポンサードサーチ