touch

Friday, April 17, 2026

セキュリティ

騙されないようにね

Wednesday, April 8, 2026

Sunday, March 29, 2026

the GIMP

3.2.2

Wednesday, March 18, 2026

Thursday, March 12, 2026

Sunday, March 1, 2026

AIサンプル

import pygame
import random

pygame.init()

# ========= サイズ =========
WIDTH, HEIGHT = 20, 40
CELL = 24
HALF = CELL // 2
screen = pygame.display.set_mode((WIDTH * CELL, HEIGHT * CELL))
clock = pygame.time.Clock()

# ========= SRS キック =========
JLSTZ_KICKS = {
    (0,1): [(0,0),(-1,0),(-1,1),(0,-2),(-1,-2)],
    (1,0): [(0,0),(1,0),(1,-1),(0,2),(1,2)],
    (1,2): [(0,0),(1,0),(1,-1),(0,2),(1,2)],
    (2,1): [(0,0),(-1,0),(-1,1),(0,-2),(-1,-2)],
    (2,3): [(0,0),(1,0),(1,1),(0,-2),(1,-2)],
    (3,2): [(0,0),(-1,0),(-1,-1),(0,2),(-1,2)],
    (3,0): [(0,0),(-1,0),(-1,-1),(0,2),(-1,2)],
    (0,3): [(0,0),(1,0),(1,1),(0,-2),(1,-2)],
}

I_KICKS = {
    (0,1): [(0,0),(-2,0),(1,0),(-2,-1),(1,2)],
    (1,0): [(0,0),(2,0),(-1,0),(2,1),(-1,-2)],
    (1,2): [(0,0),(-1,0),(2,0),(-1,2),(2,-1)],
    (2,1): [(0,0),(1,0),(-2,0),(1,-2),(-2,1)],
    (2,3): [(0,0),(2,0),(-1,0),(2,1),(-1,-2)],
    (3,2): [(0,0),(-2,0),(1,0),(-2,-1),(1,2)],
    (3,0): [(0,0),(1,0),(-2,0),(1,-2),(-2,1)],
    (0,3): [(0,0),(-1,0),(2,0),(-1,2),(2,-1)],
}

# ========= テトリミノ =========
PIECES = {
    "I": {
        0: [(0,1),(1,1),(2,1),(3,1)],
        1: [(2,0),(2,1),(2,2),(2,3)],
        2: [(0,2),(1,2),(2,2),(3,2)],
        3: [(1,0),(1,1),(1,2),(1,3)],
    },
    "O": {
        0: [(1,0),(2,0),(1,1),(2,1)],
        1: [(1,0),(2,0),(1,1),(2,1)],
        2: [(1,0),(2,0),(1,1),(2,1)],
        3: [(1,0),(2,0),(1,1),(2,1)],
    },
    "T": {
        0: [(1,0),(0,1),(1,1),(2,1)],
        1: [(1,0),(1,1),(2,1),(1,2)],
        2: [(0,1),(1,1),(2,1),(1,2)],
        3: [(1,0),(0,1),(1,1),(1,2)],
    },
    "S": {
        0: [(1,0),(2,0),(0,1),(1,1)],
        1: [(1,0),(1,1),(2,1),(2,2)],
        2: [(1,1),(2,1),(0,2),(1,2)],
        3: [(0,0),(0,1),(1,1),(1,2)],
    },
    "Z": {
        0: [(0,0),(1,0),(1,1),(2,1)],
        1: [(2,0),(1,1),(2,1),(1,2)],
        2: [(0,1),(1,1),(1,2),(2,2)],
        3: [(1,0),(0,1),(1,1),(0,2)],
    },
    "J": {
        0: [(0,0),(0,1),(1,1),(2,1)],
        1: [(1,0),(2,0),(1,1),(1,2)],
        2: [(0,1),(1,1),(2,1),(2,2)],
        3: [(1,0),(1,1),(0,2),(1,2)],
    },
    "L": {
        0: [(2,0),(0,1),(1,1),(2,1)],
        1: [(1,0),(1,1),(1,2),(2,2)],
        2: [(0,1),(1,1),(2,1),(0,2)],
        3: [(0,0),(1,0),(1,1),(1,2)],
    },
}

# ========= ペンタミノ 0° 定義(ここから自動で 4 回転生成) =========
PENTA_BASE = {
    "P5":  [(0,0),(1,0),(0,1),(1,1),(0,2)],
    "P5U": [(0,0),(1,0),(0,1),(1,1),(1,2)],
    "X5":  [(1,0),(0,1),(1,1),(2,1),(1,2)],
    "T5":  [(1,0),(0,1),(1,1),(2,1),(1,2)],
    "U5":  [(0,0),(2,0),(0,1),(1,1),(2,1)],
}

def gen_rotations(shape):
    rots = {}
    cur = shape
    for r in range(4):
        min_x = min(x for x, y in cur)
        min_y = min(y for x, y in cur)
        norm = [(x - min_x, y - min_y) for x, y in cur]
        rots[r] = norm
        nxt = []
        for x, y in cur:
            nx = -y
            ny = x
            nxt.append((nx, ny))
        cur = nxt
    return rots

for name, base in PENTA_BASE.items():
    PIECES[name] = gen_rotations(base)

# ========= 盤面 =========
board = [[0]*WIDTH for _ in range(HEIGHT)]

# ========= 基本関数 =========
def can_place_blocks(blocks, x, y):
    for dx, dy in blocks:
        nx, ny = x + dx, y + dy
        if nx < 0 or nx >= WIDTH or ny < 0 or ny >= HEIGHT:
            return False
        if board[ny][nx] == 1:
            return False
    return True

def place_blocks(blocks, x, y):
    for dx, dy in blocks:
        nx, ny = x + dx, y + dy
        board[ny][nx] = 1

def draw(active_blocks, ax, ay, hide=None, falling=None):
    screen.fill((0,0,0))
    for yy in range(HEIGHT):
        for xx in range(WIDTH):
            if board[yy][xx] == 1:
                if hide and (xx,yy) in hide:
                    continue
                pygame.draw.rect(screen, (0,200,200),
                    (xx*CELL, yy*CELL, CELL-1, CELL-1))
    if falling:
        for fx, fy in falling:
            pygame.draw.rect(screen, (255,80,80),
                (fx*CELL, fy, CELL-1, CELL-1))
    if active_blocks:
        for dx, dy in active_blocks:
            pygame.draw.rect(screen, (200,200,0),
                ((ax+dx)*CELL, (ay+dy)*CELL, CELL-1, CELL-1))
    pygame.display.flip()

# ========= 回転 =========
def rotate_srs(piece_type, rot, x, y):
    new_rot = (rot + 1) % 4
    blocks_new = PIECES[piece_type][new_rot]

    if piece_type == "O":
        if can_place_blocks(blocks_new, x, y):
            return new_rot, x, y
        return rot, x, y

    if piece_type in ("I","J","L","S","T","Z"):
        kicks = I_KICKS if piece_type == "I" else JLSTZ_KICKS
        for ox, oy in kicks.get((rot, new_rot), [(0,0)]):
            nx, ny = x + ox, y + oy
            if can_place_blocks(blocks_new, nx, ny):
                return new_rot, nx, ny
        return rot, x, y

    if piece_type in ("P5","P5U","X5","T5","U5"):
        SIMPLE_KICKS = [
            (0,0),(1,0),(-1,0),(0,-1),(0,1),
            (1,-1),(-1,-1),(1,1),(-1,1)
        ]
        for ox, oy in SIMPLE_KICKS:
            nx, ny = x + ox, y + oy
            if can_place_blocks(blocks_new, nx, ny):
                return new_rot, nx, ny

    return rot, x, y

# ========= 行消し =========
def clear_lines_once():
    new_board = []
    cleared = []
    for y in range(HEIGHT):
        if all(board[y]):
            cleared.append(y)
        else:
            new_board.append(board[y])
    if not cleared:
        return []
    while len(new_board) < HEIGHT:
        new_board.insert(0, [0]*WIDTH)
    for y in range(HEIGHT):
        board[y] = new_board[y]
    return cleared

# ========= 縦穴落下アニメーション =========
def cascade_animation(cleared, active_blocks, ax, ay):
    if not cleared:
        return
    bottom = max(cleared)
    target = bottom + 1
    if target >= HEIGHT:
        return

    fall_cols = []
    segments = {}

    for x in range(WIDTH):
        if board[target][x] != 0:
            continue
        ys = []
        for y in range(target-1, -1, -1):
            if board[y][x] == 1:
                ys.append(y)
            else:
                break
        if 1 <= len(ys) <= 4:
            ys.sort()
            fall_cols.append(x)
            segments[x] = ys

    if not fall_cols:
        return

    fall_info = {}
    hide = set()

    for x in fall_cols:
        ys = segments[x]
        for y in ys:
            hide.add((x,y))

        y_bottom = ys[-1]
        stop_row = HEIGHT - 1
        for yy in range(y_bottom+1, HEIGHT):
            if board[yy][x] == 1:
                stop_row = yy - 1
                break

        h = len(ys)
        final_rows = list(range(stop_row - h + 1, stop_row + 1))

        fall_info[x] = []
        for y, fr in zip(ys, final_rows):
            fall_info[x].append({
                "x": x,
                "start": y*CELL,
                "cur": y*CELL,
                "end": fr*CELL
            })

    anim = True
    while anim:
        anim = False
        falling_blocks = []
        pygame.event.pump()

        for x in fall_cols:
            for b in fall_info[x]:
                if b["cur"] < b["end"]:
                    b["cur"] = min(b["cur"] + HALF, b["end"])
                    anim = True
                falling_blocks.append((b["x"], b["cur"]))

        draw(None, 0, 0, hide=hide, falling=falling_blocks)
        pygame.time.delay(50)

    for x in fall_cols:
        ys = segments[x]
        for y in ys:
            board[y][x] = 0
        for b in fall_info[x]:
            final_row = b["end"] // CELL
            board[final_row][x] = 1

    draw(None, 0, 0)
    pygame.time.delay(80)

# ========= せり上がり =========
def rise_shift_animation():
    global rise_hole_x, rise_dir, rise_same_count

    new_row = [1] * WIDTH
    new_row[rise_hole_x] = 0

    for y in range(HEIGHT - 1):
        board[y] = board[y + 1][:]

    board[HEIGHT - 1] = new_row

    rise_same_count += 1
    if rise_same_count >= 5:
        rise_same_count = 0
        rise_hole_x += rise_dir
        if rise_hole_x <= 0:
            rise_hole_x = 0
            rise_dir = 1
        elif rise_hole_x >= WIDTH - 1:
            rise_hole_x = WIDTH - 1
            rise_dir = -1

    draw(None, 0, 0)
    pygame.time.delay(120)

# ========= 行消し後の処理 =========
def resolve_all(active_blocks, ax, ay):
    while True:
        cleared = clear_lines_once()
        if not cleared:
            break
        draw(None, 0, 0)
        pygame.time.delay(150)
        cascade_animation(cleared, active_blocks, ax, ay)

    rise_shift_animation()

# ========= 初期 5 行の地面 =========
def init_ground_rows():
    global rise_hole_x, rise_dir, rise_same_count
    rise_hole_x = WIDTH // 2
    rise_dir = 1
    rise_same_count = 5

    for i in range(5):
        new_row = [1] * WIDTH
        new_row[rise_hole_x] = 0
        board[HEIGHT - 1 - i] = new_row[:]

# ========= 新しいミノ =========
def new_piece():
    ptype = random.choice(list(PIECES.keys()))
    rot = 0
    x = WIDTH // 2 - 2
    y = 0
    return ptype, rot, x, y

# ========= 初期化 =========
init_ground_rows()
piece_type, rot, x_pos, y_pos = new_piece()
fall_timer = 0
move_cd = 0
rot_cd = 0

# ========= メインループ =========
running = True
while running:
    clock.tick(60)
    fall_timer += 1
    move_cd = max(0, move_cd - 1)
    rot_cd = max(0, rot_cd - 1)

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

    active_blocks = PIECES[piece_type][rot]
    keys = pygame.key.get_pressed()

    # --- 左右移動 ---
    if move_cd == 0:
        if keys[pygame.K_LEFT] and can_place_blocks(active_blocks, x_pos - 1, y_pos):
            x_pos -= 1
            move_cd = 8
        if keys[pygame.K_RIGHT] and can_place_blocks(active_blocks, x_pos + 1, y_pos):
            x_pos += 1
            move_cd = 8

    # --- 回転 ---
    if rot_cd == 0 and (keys[pygame.K_UP] or keys[pygame.K_SPACE]):
        new_rot, nx, ny = rotate_srs(piece_type, rot, x_pos, y_pos)
        rot, x_pos, y_pos = new_rot, nx, ny
        rot_cd = 12

    # --- 下移動(ソフトドロップ) ---
    if keys[pygame.K_DOWN] and can_place_blocks(active_blocks, x_pos, y_pos + 1):
        y_pos += 1

    # --- 自動落下 ---
    if fall_timer >= 30:
        fall_timer = 0
        if can_place_blocks(active_blocks, x_pos, y_pos + 1):
            y_pos += 1
        else:
            place_blocks(active_blocks, x_pos, y_pos)
            resolve_all(active_blocks, x_pos, y_pos)
            piece_type, rot, x_pos, y_pos = new_piece()
            if not can_place_blocks(PIECES[piece_type][rot], x_pos, y_pos):
                print("GAME OVER")
                running = False

    draw(PIECES[piece_type][rot], x_pos, y_pos)

pygame.quit()