⛳
Pythonで、五目並べを作る
動作環境
Python:3.12.1 64bit
GoogleChrome:127.0.6533.120(Official Build)(64 ビット)
OS:Windows10
CPU:Core i5-1135G7
メモリ:16GB
すること
# 相手の盤面チェック
'''
相手が必ず勝つ場合、Trueを返す
相手が勝つケースがある場合、座標を返す
勝つケースがない場合、Falseを返す
'''
def check_enemy(board, N, player):
enemy = "0"
if player == "0":
enemy = "1"
# 相手の碁石が4つある場合をカウント
horizontal_count = 0
vertical_count = 0
diagonal_count = 0
win_case = []
# 水平方向の碁石の数をチェック
'''
碁盤の水平方向で碁石が5個置ける範囲は、j(碁盤の横)がN - 5 + 1となる
'''
for i in range(N):
for j in range(N - 4):
row = board[i][j:j + 5]
# 取得した5マスに相手の碁石が4つある、かつ空きマスがある場合
if row.count(enemy) == 4 and "-1" in row:
horizontal_count += 1
# 座標をリストに保存しておく
win_case.append(str(row.index("-1") + j + 1) + " " + str(i + 1))
# 相手が必ず勝つケースのチェック
# 4つ並んだ碁石の前後が空きマスの場合
if (j > 0 and board[i][j - 1] == "-1" and row[-1] == "-1") or (j + 5 < N and board[i][j + 5] == "-1" and row[0] == "-1"):
return True
# 垂直方向の碁石の数をチェック
'''
碁盤の垂直方向で碁石が5個置ける範囲は、i(碁盤の縦)がN - 5 + 1となる
'''
for i in range(N - 4):
for j in range(N):
column = [board[i + k][j] for k in range(5)]
# 取得した5マスに相手の碁石が4つある、かつ空きマスがある場合
if column.count(enemy) == 4 and "-1" in column:
vertical_count += 1
# 座標をリストに保存しておく
win_case.append(str(j + 1) + " " + str(column.index("-1") + i + 1))
# 相手が必ず勝つケースのチェック
# 4つ並んだ碁石の前後が空きマスの場合
if (i > 0 and board[i - 1][j] == "-1" and column[-1] == "-1") or (i + 5 < N and board[i + 5][j] == "-1" and column[0] == "-1"):
return True
# 碁盤の左上から右下・右上から左下の斜め方向の碁石の数をチェックする
'''
碁盤の斜め方向で碁石が5個置けるスタート位置は、i(碁盤の縦)・j(碁盤の横)どちらもN - 4となる
例えば、N = 8の場合、碁盤の左上・右上から4 × 4の範囲がチェックスタート範囲となる
'''
for i in range(N - 4):
for j in range(N - 4):
# 左上から右下方向に5マス取得する
diagonal1 = [board[i + k][j + k] for k in range(5)]
# 右上から左下方向に5マス取得する
# Nがいかなる場合でも、横軸のスタートは左から5マス目となるため、j + 4となる
diagonal2 = [board[i + k][j + 4 - k] for k in range(5)]
# 取得した5マスに相手の碁石が4つある、かつ空きマスがある場合
if diagonal1.count(enemy) == 4 and "-1" in diagonal1:
diagonal_count += 1
# 座標をリストに保存しておく
win_case.append(str(diagonal1.index("-1") + j + 1) + " " + str(diagonal1.index("-1") + i + 1))
# 相手が必ず勝つケースのチェック
# 4つ並んだ碁石の前後が空きマスの場合
if (i > 0 and j > 0 and board[i - 1][j - 1] == "-1" and diagonal1[-1] == "-1") or (i + 5 < N and j + 5 < N and board[i + 5][j + 5] == "-1" and diagonal1[0] == "-1"):
return True
# 取得した5マスに相手の碁石が4つある、かつ空きマスがある場合
if diagonal2.count(enemy) == 4 and "-1" in diagonal2:
diagonal_count += 1
# 座標をリストに保存しておく
win_case.append(str(j + 1 + 4 - diagonal2.index("-1")) + " " + str(diagonal2.index("-1") + i + 1))
# 相手が必ず勝つケースのチェック
# 4つ並んだ碁石の前後が空きマスの場合
if (i > 0 and j + 4 < N and board[i - 1][j + 4] == "-1" and diagonal2[-1] == "-1") or (i + 5 < N and j < N and board[i + 5][j] == "-1" and diagonal2[0] == "-1"):
return True
# 相手が勝つケースが2つ以上ある場合
if horizontal_count + vertical_count + diagonal_count > 1:
win_case_tmp = set(win_case)
# 相手が勝つケースが2種類以上の場合
if len(win_case_tmp) > 1:
return True
# 相手が勝つケースが1種類の場合
elif len(win_case_tmp) == 1:
# 座標を返す
return list(win_case_tmp)[0]
# 相手が勝つケースが1つの場合
elif horizontal_count + vertical_count + diagonal_count == 1:
# 座標を返す
return win_case[0]
# 相手に勝つケースが無い場合
return False
# プレイヤーの盤面チェック
'''
プレイヤーが勝つケースがある場合、座標を返す
勝つケースが無い場合、Falseを返す
'''
def check_player(board, N, player):
# 水平方向の碁石の数をチェック(i=行数)
for i in range(N):
for j in range(N - 4):
row = board[i][j:j + 5]
# プレイヤーの碁石が4つある場合
if row.count(player) == 4 and "-1" in row:
# 座標を出力
return str(row.index("-1") + j + 1) + " " + str(i + 1)
# 垂直方向の碁石の数をチェック
for i in range(N - 4):
for j in range(N):
column = [board[i + k][j] for k in range(5)]
# プレイヤーの碁石が4つある場合
if column.count(player) == 4 and "-1" in column:
# 座標を出力
return str(j + 1) + " " + str(column.index("-1") + i + 1)
# 斜め方向の碁石の数をチェック
for i in range(N - 4):
for j in range(N - 4):
diagonal1 = [board[i + k][j + k] for k in range(5)]
diagonal2 = [board[i + k][j + 4 - k] for k in range(5)]
if diagonal1.count(player) == 4 and "-1" in diagonal1:
# 座標を出力
return str(diagonal1.index("-1") + j + 1) + " " + str(diagonal1.index("-1") + i + 1)
if diagonal2.count(player) == 4 and "-1" in diagonal2:
# 座標を出力
return str(j + 1 + 4 - diagonal2.index("-1")) + " " + str(diagonal2.index("-1") + i + 1)
return False
# 盤面チェック
'''
盤面から空きマスを取得し、座標を返す
'''
def check_grid(board, N):
for i in range(N):
for j in range(N):
grid = board[i][j]
if grid == "-1":
return str(j + 1) + " " + str(i + 1)
def main():
input_list = input().split()
N = int(input_list[0])
player = input_list[1]
board = []
for _ in range(N):
board.append(input().rstrip().split(' '))
# 相手の状況をチェック
enemy_win = check_enemy(board, N, str(player))
# プレイヤーの状況をチェック
player_win = check_player(board, N, str(player))
# プレイヤーが勝つ場合
if isinstance(player_win, str) == True and enemy_win == False:
print(player_win)
# プレイヤーも相手も勝つ場合
elif isinstance(player_win, str) == True and isinstance(enemy_win, str) == True:
print(player_win)
# 相手が勝つ場合
elif player_win == False and isinstance(enemy_win, str) == True:
print(enemy_win)
# プレイヤーが勝つかつ、相手が必ず勝つ場合
elif isinstance(player_win, str) == True and enemy_win == True:
print(player_win)
# 相手が必ず勝つ場合
elif player_win == False and enemy_win == True:
print("LOSE")
# ゲーム途中の場合
elif player_win == False and enemy_win == False:
grid = check_grid(board, N)
print(grid)
else:
print("LOSE")
if __name__ == "__main__":
main()
Discussion