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?

オセロ作ってみた #100日チャレンジに感化されて

Last updated at Posted at 2025-05-03

今日はオセロ作ってみた

GW後半戦突入〜!制作頑張ろう

othell.gif

import pygame
import sys
import random

pygame.init()

#初期画面設定
size = 8
cell_size = 60
board_size = size * cell_size
window = pygame.display.set_mode((board_size, board_size))
#ゲームウィンドウを作成するための関数
#pygame.display.set_mode((幅, 高さ))

pygame.display.set_caption("オセロ")

#色の設定
green = (0,255,0)
black = (0,0,0)
white = (255,255,255)

#ゲーム盤の状態
#初期は「0」 黒の碁を置いたら,「1」 白の碁を置いたら「2」
board = [[0 for _ in range(size)] for _ in range(size)]

#boardの中央に,碁石を置く
board[3][4] = board[4][3] = 1
board[3][3] = board[4][4] = 2

player = 1

# 8方向
directions = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)]

def is_valid_move(x, y, player):
    if board[y][x] != 0:
        return False
    opponent = 3 - player
    for dx, dy in directions:
        nx, ny = x + dx, y + dy
        has_opponent_between = False
        while 0 <= nx < size and 0 <= ny < size:
            if board[ny][nx] == opponent:
                has_opponent_between = True
            elif board[ny][nx] == player:
                if has_opponent_between:
                    return True
                else:
                    break
            else:
                break
            nx += dx
            ny += dy
    return False

def get_valid_moves(player):
    return [(x, y) for y in range(size) for x in range(size) if is_valid_move(x, y, player)]

def place_disc(x, y, player):
    board[y][x] = player
    opponent = 3 - player
    for dx, dy in directions:
        nx, ny = x + dx, y + dy
        discs_to_flip = []
        while 0 <= nx < size and 0 <= ny < size:
            if board[ny][nx] == opponent:
                discs_to_flip.append((nx, ny))
            elif board[ny][nx] == player:
                for fx, fy in discs_to_flip:
                    board[fy][fx] = player
                break
            else:
                break
            nx += dx
            ny += dy

def draw_board():
    window.fill(green)
    for x in range(size):
        for y in range(size):
            rect = pygame.Rect(x * cell_size, y * cell_size, cell_size, cell_size)
            pygame.draw.rect(window, black, rect, 1)
            if board[y][x] == 1:
                pygame.draw.circle(window, black, rect.center, cell_size // 2 - 5)
            elif board[y][x] == 2:
                pygame.draw.circle(window, white, rect.center, cell_size // 2 - 5)
    pygame.display.update()

def cpu_move():
    moves = get_valid_moves(2) #CPUはplayer=2と仮定
    if moves:
        x, y = random.choice(moves)
        place_disc(x, y, 2)

def count_discs():
    black_count = sum(row.count(1) for row in board)
    white_count = sum(row.count(2) for row in board)
    return black_count, white_count

def show_result_and_restart():
    black_count, white_count = count_discs()
    if black_count > white_count:
        result_text = f"winner! {black_count} vs {white_count}"
    elif white_count > black_count:
        result_text = f"loss... {white_count} vs {black_count}"
    else:
        result_text = f"draw... {black_count} vs {white_count}"

    font = pygame.font.SysFont("arial", 36)
    button_font = pygame.font.SysFont("arial", 28)
    window.fill(green)

    text_surface = font.render(result_text, True, black, white)
    text_rect = text_surface.get_rect(center=(board_size // 2, board_size // 2 - 60))
    window.blit(text_surface, text_rect)

    button_rect = pygame.Rect(board_size // 2 - 80, board_size // 2 + 20, 160, 50)
    pygame.draw.rect(window, white, button_rect)
    pygame.draw.rect(window, black, button_rect, 2)
    button_text = button_font.render("restart", True, black)
    button_text_rect = button_text.get_rect(center=button_rect.center)
    window.blit(button_text, button_text_rect)

    pygame.display.update()
    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                if button_rect.collidepoint(event.pos):
                    restart_game()
                    waiting = False
                    
def restart_game():
    global board, player, cpu_pending, cpu_timer
    board = [[0 for _ in range(size)] for _ in range(size)]
    board[3][4] = board[4][3] = 1
    board[3][3] = board[4][4] = 2
    player = 1

cpu_pending = False
cpu_timer = 0

# --- メインループ ---
running = True
while running:
    draw_board()

    now = pygame.time.get_ticks()
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            if not cpu_pending:
                
                mx, my = pygame.mouse.get_pos()
                x, y = mx // cell_size, my // cell_size
                if is_valid_move(x, y, 1):
                    place_disc(x, y, 1)
                    
                    if get_valid_moves(2): #CPUに手があるなら
                        cpu_pending = True
                        cpu_timer = now + 500 #1秒後
                    elif not get_valid_moves(1) and not get_valid_moves(2):
                        running = False

        if cpu_pending and now>= cpu_timer:
            cpu_move()
            cpu_pending = False
            
            while not get_valid_moves(1) and get_valid_moves(2):
                pygame.time.delay(500)
                cpu_move()
                
        if not get_valid_moves(1) and not get_valid_moves(2):
            draw_board()
            show_result_and_restart()

気に入ったらいいね👍してね!

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