0
1

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 3 years have passed since last update.

コンピュータとオセロ対戦10 ~Pythonでオセロ~

Last updated at Posted at 2021-10-01

前回

今回の目標

今後機械学習などでPythonを使うので、まずは普通にオセロを目指します。
といってもC言語で作ったプログラムの丸写しです。

ここから本編

グローバル変数

timeは試合時間表示のためにインポートしました。必須ではないです。
「PLAYER = BLACK」は後ほど使うためです。これも今回は必須ではないです。

osero.py
from time import time

#define
NONE = 0
WHITE = 1
BLACK = 2
SIZE = 8
PLAYER = BLACK
# PLAYER = WHITE
NUM = 1000

board = [[NONE for i in range(SIZE)] for i in range(SIZE)]
turn = BLACK

printb

osero.py
def printb():
    print(end="\n ")
    for i in range(SIZE):
        print(" ", i + 1, end="")
    print("\n -------------------------")
    for i in range(SIZE):
        print(end=str(i + 1))
        for j in range(SIZE):
            if board[i][j] == NONE:
                print(end="|  ");
            elif board[i][j] == WHITE:
                print(end="|●")
            elif board[i][j] == BLACK:
                print(end="|○")
        print("|\n -------------------------")

setup

osero.py
def setup():
    board[(SIZE >> 1) - 1][(SIZE >> 1) - 1] = WHITE
    board[SIZE >> 1][SIZE >> 1] = WHITE
    board[(SIZE >> 1) - 1][SIZE >> 1] = BLACK
    board[SIZE >> 1][(SIZE >> 1) - 1] = BLACK

check_all

osero.py
def check_all() -> bool:
    for i in range(SIZE):
        for j in range(SIZE):
            if check(i, j):
                return True
    
    return False

que

何も入力しなかった場合、C言語だとなぜかエラーにならないですがPythonはエラーになるのでエラー処理を行いました。
lineとcolにSIZEを入れることで、check関数で自動的に省くようになっています。

osero.py
def que():
    line = input("行: ")
    col = input("列: ")
    try:
        line = int(line)
        col = int(col)
    except:
        line = SIZE
        col = SIZE
    return line, col

check

osero.py
def check(line: int, col: int) -> bool:
    if (board[line][col] != NONE):
        return False
    
    my, opp = turn, 3 - turn
    
    for x in range(-1, 2):
        for y in range(-1, 2):
            if x != 0 or y != 0:
                line_x = x
                col_y = y
                while (0 <= line + x + line_x < SIZE\
                       and 0 <= col + y + col_y < SIZE\
                       and board[line + line_x][col + col_y] == opp):
                    if board[line + x + line_x][col + y + col_y] == my:
                        return True
                    line_x += x
                    col_y += y
    
    return False

put

最後の繰り返し関数、C言語では「num + 2まで」としていましたが、「num + 1まで」でよかったようです。
プログラムミスで無駄なことしてました。

osero.py
def put(line: int, col: int):
    my, opp = turn, 3 - turn
    
    board[line][col] = my
    
    for x in range(-1, 2):
        for y in range(-1, 2):
            if x != 0 or y != 0:
                num = 0
                check_bool = False
                line_x = x
                col_y = y
                while (0 <= line + x + line_x < SIZE\
                       and 0 <= col + y + col_y < SIZE\
                       and board[line + line_x][col + col_y] == opp):
                    if board[line + x + line_x][col + y + col_y] == my:
                        check_bool = True
                    line_x += x
                    col_y += y
                    num += 1
            if check_bool:
                for i in range(1, num + 1):
                    board[line + i * x][col + i * y] = my

count

osero.py
def count():
    black, white = 0, 0
    
    for i in range(SIZE):
        for j in range(SIZE):
            if board[i][j] == BLACK:
                black += 1
            elif board[i][j] == WHITE:
                white += 1
    
    if black > white:
        print("黒の勝ちです")
    elif black > white:
        print("白の勝ちです")
    else:
        print("引き分けです")

main

osero.py
def main():
    global turn
    start = time()
    
    can, old_can = True, True
    
    print("黒: ○")
    print("白: ●")
    
    setup()
    printb()
    
    while can or old_can:
        if turn == BLACK:
            print("黒のターンです")
        else:
            print("白のターンです")
        if can:
            line, col = que()
            while not check(line - 1, col - 1):
                print("その位置には置けません")
                line, col = que()
            put(line - 1, col - 1)
            printb()
        else:
            print("置ける場所がありません")
        old_can = can
        turn = 3 - turn
        can = check_all()
    
    print("\n試合時間: %d秒" % (time() - start))
    count()

if __name__ == "__main__":
    main()

フルバージョン

実際にやってみた

プロンプト上でのオセロはなんだか懐かしいですね。
C言語でやっていた頃を思い出しました。

次回は

機械学習を使って対戦できるようにしたいです。

次回

0
1
0

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?