C#でテトリス

## visual studio code
visual studio codeでC#を開きます以下のコードを打ってください

```cs
    using System;
    using System.Drawing;
    using System.Windows.Forms;

    public partial class TetrisForm : Form
    {
    private const int BoardWidth = 10;
    private const int BoardHeight = 20;
    private const int BlockSize = 30;

    private Timer gameTimer;
    private int[,] board = new int[BoardWidth, BoardHeight];
    private Point currentPosition;
    private int[,] currentPiece;

    public TetrisForm()
    {
        InitializeComponent();
        InitializeGame();
    }

    private void InitializeComponent()
    {
        this.ClientSize = new Size(BoardWidth * BlockSize, BoardHeight * BlockSize);
        this.Text = "Tetris";
        this.Paint += new PaintEventHandler(OnPaint);
        this.KeyDown += new KeyEventHandler(OnKeyDown);

        gameTimer = new Timer();
        gameTimer.Interval = 500; // 0.5秒ごとにTickイベントを発生
        gameTimer.Tick += new EventHandler(GameTick);
        gameTimer.Start();
    }

    private void InitializeGame()
    {
        // 最初のピースを生成
        currentPiece = GenerateRandomPiece();
        currentPosition = new Point(BoardWidth / 2 - 1, 0);
    }

    private void GameTick(object sender, EventArgs e)
    {
        MovePieceDown();
        Invalidate();
    }

    private void OnPaint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;

        // ボードを描画
        for (int y = 0; y < BoardHeight; y++)
        {
            for (int x = 0; x < BoardWidth; x++)
            {
                if (board[x, y] != 0)
                {
                    g.FillRectangle(Brushes.Blue, x * BlockSize, y * BlockSize, BlockSize, BlockSize);
                    g.DrawRectangle(Pens.Black, x * BlockSize, y * BlockSize, BlockSize, BlockSize);
                }
            }
        }

        // 現在のピースを描画
        for (int y = 0; y < currentPiece.GetLength(0); y++)
        {
            for (int x = 0; x < currentPiece.GetLength(1); x++)
            {
                if (currentPiece[x, y] != 0)
                {
                    int drawX = (currentPosition.X + x) * BlockSize;
                    int drawY = (currentPosition.Y + y) * BlockSize;
                    g.FillRectangle(Brushes.Red, drawX, drawY, BlockSize, BlockSize);
                    g.DrawRectangle(Pens.Black, drawX, drawY, BlockSize, BlockSize);
                }
            }
        }
    }

    private void OnKeyDown(object sender, KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.Left:
                MovePieceLeft();
                break;
            case Keys.Right:
                MovePieceRight();
                break;
            case Keys.Down:
                MovePieceDown();
                break;
            case Keys.Up:
                RotatePiece();
                break;
        }
        Invalidate();
    }

    private void MovePieceLeft()
    {
        if (IsValidPosition(currentPiece, new Point(currentPosition.X - 1, currentPosition.Y)))
        {
            currentPosition.X--;
        }
    }

    private void MovePieceRight()
    {
        if (IsValidPosition(currentPiece, new Point(currentPosition.X + 1, currentPosition.Y)))
        {
            currentPosition.X++;
        }
    }

    private void MovePieceDown()
    {
        if (IsValidPosition(currentPiece, new Point(currentPosition.X, currentPosition.Y + 1)))
        {
            currentPosition.Y++;
        }
        else
        {
            PlacePiece();
            ClearFullLines();
            currentPiece = GenerateRandomPiece();
            currentPosition = new Point(BoardWidth / 2 - 1, 0);

            if (!IsValidPosition(currentPiece, currentPosition))
            {
                gameTimer.Stop();
                MessageBox.Show("Game Over");
            }
        }
    }

    private void RotatePiece()
    {
        int[,] rotatedPiece = RotateMatrix(currentPiece);
        if (IsValidPosition(rotatedPiece, currentPosition))
        {
            currentPiece = rotatedPiece;
        }
    }

    private void PlacePiece()
    {
        for (int y = 0; y < currentPiece.GetLength(0); y++)
        {
            for (int x = 0; x < currentPiece.GetLength(1); x++)
            {
                if (currentPiece[x, y] != 0)
                {
                    board[currentPosition.X + x, currentPosition.Y + y] = currentPiece[x, y];
                }
            }
        }
    }

    private void ClearFullLines()
    {
        for (int y = 0; y < BoardHeight; y++)
        {
            bool isFullLine = true;
            for (int x = 0; x < BoardWidth; x++)
            {
                if (board[x, y] == 0)
                {
                    isFullLine = false;
                    break;
                }
            }

            if (isFullLine)
            {
                for (int yy = y; yy > 0; yy--)
                {
                    for (int xx = 0; xx < BoardWidth; xx++)
                    {
                        board[xx, yy] = board[xx, yy - 1];
                    }
                }
                for (int xx = 0; xx < BoardWidth; xx++)
                {
                    board[xx, 0] = 0;
                }
            }
        }
    }

    private bool IsValidPosition(int[,] piece, Point position)
    {
        for (int y = 0; y < piece.GetLength(0); y++)
        {
            for (int x = 0; x < piece.GetLength(1); x++)
            {
                if (piece[x, y] != 0)
                {
                    int boardX = position.X + x;
                    int boardY = position.Y + y;

                    if (boardX < 0 || boardX >= BoardWidth || boardY < 0 || boardY >= BoardHeight)
                    {
                        return false;
                    }

                    if (board[boardX, boardY] != 0)
                    {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private int[,] RotateMatrix(int[,] matrix)
    {
        int width = matrix.GetLength(0);
        int height = matrix.GetLength(1);
        int[,] rotatedMatrix = new int[height, width];

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                rotatedMatrix[y, x] = matrix[width - x - 1, y];
            }
        }

        return rotatedMatrix;
    }

    private int[,] GenerateRandomPiece()
    {
        int[,,] pieces = new int[,,]
        {
            { { 1, 1, 1, 1 } },  // I
            { { 1, 1 }, { 1, 1 } },  // O
            { { 0, 1, 0 }, { 1, 1, 1 } },  // T
            { { 1, 1, 0 }, { 0, 1, 1 } },  // S
            { { 0, 1, 1 }, { 1, 1, 0 } },  // Z
            { { 1, 0, 0 }, { 1, 1, 1 } },  // J
            { { 0, 0, 1 }, { 1, 1, 1 } }   // L
        };

        Random rand = new Random();
        int index = rand.Next(pieces.GetLength(0));
        int[,] piece = new int[pieces.GetLength(1), pieces.GetLength(2)];
        for (int y = 0; y < pieces.GetLength(1); y++)
        {
            for (int x = 0; x < pieces.GetLength(2); x++)
            {
                piece[x, y] = pieces[index, y, x];
            }
        }
        return piece;
        }
    }
```
これでok