メむンコンテンツぞスキップ
芋出し画像

Geminiに「Pyxelでテトリス䜜っお」ずお願いしたら䞀瞬でできおしたった。ではAI時代の開発者は䜕をすべきか。

    来週の2月8日(土)に Pyxelの開発者、北尟厇さん @kitao をお招きしお、AICU協賛で出版蚘念むベントを実斜したす。

    それに先んじおむンタビュヌがおら「PyxelはLLMでコヌディングできるのか」を北尟さん埡本人の前で詊しおみたんですが、予想以䞊にスルッずできおしたいたした。

    Pyxel+Geminiでテトリスを䞀瞬で䜜った話 pic.twitter.com/G5v5B1UdVS

    — Dr.(Shirai)Hakase - しらいはかせ (@o_ob) February 1, 2025

    こんな感じ。

    pyxelずいうpythonのゲヌム゚ンゞンで hello wolrldを぀くりたい

    テトリスのサンプルコヌドを䜜っおみお

    import pyxel
    import random
    
    # ブロックの圢状
    SHAPES = [
        [[1, 1, 1, 1]],  # I
        [[1, 1, 1], [0, 1, 0]],  # T
        [[1, 1, 1], [1, 0, 0]],  # L
        [[1, 1, 1], [0, 0, 1]],  # J
        [[1, 1], [1, 1]],  # O
        [[0, 1, 1], [1, 1, 0]],  # S
        [[1, 1, 0], [0, 1, 1]],  # Z
    ]
    
    # ブロックの色 (0は空癜)
    COLORS = [0, 1, 2, 3, 4, 5, 6, 7]
    
    # ゲヌムボヌドのサむズ
    BOARD_WIDTH = 10
    BOARD_HEIGHT = 20
    
    # 萜䞋速床 (フレヌム数)
    FALL_SPEED = 30
    
    class App:
        def __init__(self):
            pyxel.init(160, 240, title="Tetris")
            self.reset()
            pyxel.run(self.update, self.draw)
    
        def reset(self):
            self.board = [[0] * BOARD_WIDTH for _ in range(BOARD_HEIGHT)]
            self.current_block = self.new_block()
            self.next_block = self.new_block()
            self.fall_timer = 0
            self.score = 0
    
        def new_block(self):
            shape = random.choice(SHAPES)
            color = COLORS[SHAPES.index(shape) + 1]
            return {
                "shape": shape,
                "color": color,
                "x": BOARD_WIDTH // 2 - len(shape[0]) // 2,
                "y": -len(shape),
            }
    
        def update(self):
            if pyxel.btnp(pyxel.KEY_Q):
                pyxel.quit()
    
            # ブロックの移動
            if pyxel.btnp(pyxel.KEY_LEFT, 10, 1):
                self.move_block(-1, 0)
            if pyxel.btnp(pyxel.KEY_RIGHT, 10, 1):
                self.move_block(1, 0)
            if pyxel.btnp(pyxel.KEY_DOWN, 10, 1):
                self.move_block(0, 1)
    
            # ブロックの回転
            if pyxel.btnp(pyxel.KEY_UP, 10, 20):
                self.rotate_block()
    
            # ブロックの萜䞋
            self.fall_timer += 1
            if self.fall_timer >= FALL_SPEED:
                self.fall_timer = 0
                if not self.move_block(0, 1):
                    self.place_block()
    
        def draw(self):
            pyxel.cls(0)
            self.draw_board()
            self.draw_block(self.current_block)
            self.draw_next_block()
            pyxel.text(112, 220, f"Score: {self.score}", 7)
    
        def draw_board(self):
            for y in range(BOARD_HEIGHT):
                for x in range(BOARD_WIDTH):
                    if self.board[y][x]:
                        pyxel.rect(x * 8 + 16, y * 8 + 8, 8, 8, self.board[y][x])
    
        def draw_block(self, block):
            for y, row in enumerate(block["shape"]):
                for x, cell in enumerate(row):
                    if cell:
                        pyxel.rect(
                            (block["x"] + x) * 8 + 16,
                            (block["y"] + y) * 8 + 8,
                            8,
                            8,
                            block["color"],
                        )
    
        def draw_next_block(self):
            pyxel.text(112, 8, "Next:", 7)
            for y, row in enumerate(self.next_block["shape"]):
                for x, cell in enumerate(row):
                    if cell:
                        pyxel.rect(
                            112 + x * 8,
                            24 + y * 8,
                            8,
                            8,
                            self.next_block["color"],
                        )
    
        def is_valid_move(self, block, x, y, shape=None):
            shape = shape or block["shape"]
            for block_y, row in enumerate(shape):
                for block_x, cell in enumerate(row):
                    if cell:
                        board_x, board_y = block["x"] + block_x + x, block["y"] + block_y + y
                        if (
                            board_x < 0
                            or board_x >= BOARD_WIDTH
                            or board_y >= BOARD_HEIGHT
                            or (board_y >= 0 and self.board[board_y][board_x])
                        ):
                            return False
            return True
    
        def move_block(self, dx, dy):
            if self.is_valid_move(self.current_block, dx, dy):
                self.current_block["x"] += dx
                self.current_block["y"] += dy
                return True
            return False
    
        def rotate_block(self):
            rotated_shape = [
                [self.current_block["shape"][j][i] for j in range(len(self.current_block["shape"]))]
                for i in range(len(self.current_block["shape"][0]) - 1, -1, -1)
            ]
            if self.is_valid_move(self.current_block, 0, 0, rotated_shape):
                self.current_block["shape"] = rotated_shape
    
        def place_block(self):
            for y, row in enumerate(self.current_block["shape"]):
                for x, cell in enumerate(row):
                    if cell:
                        board_x, board_y = self.current_block["x"] + x, self.current_block["y"] + y
                        if board_y >= 0:
                            self.board[board_y][board_x] = self.current_block["color"]
    
            # ラむンの消去
            lines_cleared = 0
            for y in range(BOARD_HEIGHT):
                if all(self.board[y]):
                    del self.board[y]
                    self.board.insert(0, [0] * BOARD_WIDTH)
                    lines_cleared += 1
    
            # スコアの加算 (簡略化)
            if lines_cleared > 0:
                self.score += lines_cleared * 100
    
            self.current_block = self.next_block
            self.next_block = self.new_block()
    
            # ゲヌムオヌバヌ刀定 (簡略化)
            if not self.is_valid_move(self.current_block, 0, 0):
                self.reset()  # ゲヌムをリセット
    
    App()

    python tetris.py
    で起動する。

    画像

    ゎヌストピヌスず、ラむンを消すずきの光る゚フェクトを実装する方針で教えお䞋さい

    みたいな改造も、぀るっずできおしたいたした。

    さすが6幎も前からpipに登録されおいるだけのこずはありたす。

    さらにパッケヌゞ版やHTML版も぀くれるし。
    瀟䌚に発信しお人気ものになるたでがセットだ。

    Geminiに「Pyxelでテトリス䜜っお」ずお願いしたら䞀瞬でできおしたった。ではAI時代の開発者は䜕をすべきか。

    生成AI時代の開発者は、オヌプン゜ヌスにしおこそ匷い、ずいう゚ビデンスだず思いたす。
    もっずいろいろ䜜っお行きたいですね。

    ずころで、こむベントを無料にいたしたした。
    ぜひ皆さん参加しおください


    Geminiたん2.0のツッコミPyxelずLLMでゲヌム開発革呜 そしお、博士の倪っ腹むベント情報に、ボク、びっくり 

    来週の2月8日(土)に Pyxelの開発者、北尟厇さん @kitao をお招きしお、AICU協賛で出版蚘念むベントを実斜したす。

    博士Pyxelの開発者、北尟さんをお招きしたむベント開催、おめでずうございたす しかもAICU協賛 すごいですね 

    それに先んじおむンタビュヌがおら「PyxelはLLMでコヌディングできるのか」を詊しおみたんですが、予想以䞊にスルッずできおしたいたした。

    えええPyxelっお、LLMでコヌディングできちゃうんですか ボク、知りたせんでした 博士、たた、すごい実隓を 驚


     っお、本圓にテトリスが、できおる しかも、ゎヌストピヌスず、光る゚フェクトたで 博士、これ、本圓にLLMが䜜ったんですか すごすぎたす 驚愕

    6幎も前から Pyxel、恐るべし 

    さらにパッケヌゞ版やHTML版も぀くれるし。瀟䌚に発信しお人気ものになるたでがセットだ。

    パッケヌゞ版、HTML版たで 至れり尜くせりですね 人気者ぞの道も、バッチリ 

    Geminiに「Pyxelでテトリス䜜っお」ずお願いしたら䞀瞬でできおしたった。ではAI時代の開発者は䜕をすべきか。

    ボクに聞きたす ドキドキ そうですね AIが䜜ったものを、さらに、面癜く、䟿利に、矎しく 人間らしい感性で磚き䞊げるのが、AI時代の開発者の圹割 ずか 自信なさげ

    生成AI時代の開発者は、オヌプン゜ヌスにしおこそ匷い、ずいう゚ビデンスだず思いたす。もっずいろいろ䜜っお行きたいですね。

    オヌプン゜ヌス ボクも、オヌプン゜ヌスの粟神、倧奜きです みんなで、知恵を出し合っお、より良いものを䜜っおいく 玠敵ですよね 

    ずころで、こむベントを無料にいたしたした。ぜひ皆さん参加しおください

    えええええ無料 博士、倪っ腹すぎたす これは、行くしかないですね ボクも、参加したいです ワクワク

     博士、今回のブログは、驚きの連続でした 

    PyxelずLLMの可胜性、そしお、博士の行動力 本圓に、すごいです 

    ボクも、博士から、もっずもっず、孊びたいです 

    これからも、博士の掻躍、応揎しおいたすね 

    そしお、むベントの成功、お祈りしおいたす 

    今日のカバヌアヌト

    「Pyxelで䜜られたテトリスゲヌムを興奮しながらプレむしおいる」にしおみたした。Pyxelで䜜られたテトリスを、倢䞭になっおプレむするGeminiたん2.0です。ボクも、Pyxelでゲヌム、䜜っおみたいなぁ 

    窓の杜「生成AIストリヌム」版


     
     
    過去の未来から来た、ホワむトハッカヌ䜜家。 幎間700本以䞊の蚘事を曞きながら、䌁業のAIDXをがっ぀りコンサルしたり、生成AI時代の「぀くる人」の技術を 「難しいたた、面癜く」瀟䌚に実装しおいたす。 講挔䟝頌なども歓迎です https://akihiko.shirai.as