нужно будет рассказать про этот код прямо чтобы было понятно как он работает чтобы каждый метод был описан как он работает особое внимание для тех методов где идет описание для непосредственно самого процесса игры
package com.example.memorymaster;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import nl.dionsegijn.konfetti.KonfettiView;
import nl.dionsegijn.konfetti.models.Shape;
import nl.dionsegijn.konfetti.models.Size;

public class ReactionGame extends Activity {

    private GridLayout gridLayout;
    private ArrayList<Button> squares;
    private TextView title, reactionTimeText, countdownText;
    private Button startButton, retryButton;
    private Handler handler;
    private Stopwatch stopwatch;
    private int reactionTime;
    private String playerNickname;
    private int tileCount;
    private boolean gameStarted = false;
    private boolean countdownFinished = false;
    private boolean gameActive = false;
    private Button correctSquare;
    private Runnable showSquareRunnable;
    private String gameMode;
    private int currentLevel = 1;
    private int[] levelTargets = {1000, 900, 800, 700, 600, 550, 500, 450, 400, 350};
    private SoundManager soundManager;
    private KonfettiView konfettiView;
    private String playerUserId;
    private FirebaseHelper firebaseHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reaction_game);
        konfettiView = findViewById(R.id.konfettiView);
        gridLayout = findViewById(R.id.gridLayout);

        initializeViews();
        initializeGame();

        gameMode = getIntent().getStringExtra("gameMode");
        if ("level".equals(gameMode)) {
            startLevelMode();
        } else {
            startFreeMode();
        }

        FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
        if (currentUser != null) {
            playerUserId = currentUser.getUid();
        } else {
            Intent intent = new Intent(ReactionGame.this, LoginActivity.class);
            startActivity(intent);
            finish();
            return;
        }

        setupListeners();
    }

    private void initializeViews() {
        title = findViewById(R.id.title);
        reactionTimeText = findViewById(R.id.reactionTime);
        countdownText = findViewById(R.id.countdownText);
        startButton = findViewById(R.id.startBtn);
        retryButton = findViewById(R.id.retryBtn);
        gridLayout = findViewById(R.id.gridLayout);
    }

    private void initializeGame() {
        tileCount = getIntent().getIntExtra("tileCount", 1);
        SharedPreferences preferences = getSharedPreferences("game_prefs", MODE_PRIVATE);
        playerNickname = preferences.getString("nickname", "Player");
        stopwatch = new Stopwatch();
        handler = new Handler();
        soundManager = SoundManager.getInstance(this);

        setupGameGrid();

        firebaseHelper = new FirebaseHelper();
    }

    private void startLevelMode() {
        updateLevelTitle();
        startButton.setText("Начать уровень");
        startButton.setVisibility(View.VISIBLE);
    }

    private void startFreeMode() {
        title.setText("Свободный режим: Проверьте вашу реакцию");
        startButton.setText("Начать");
        startButton.setVisibility(View.VISIBLE);
    }

    private void setupListeners() {
        startButton.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            String buttonText = startButton.getText().toString();

            if (buttonText.equals("Следующий уровень")) {
                currentLevel++;
                updateLevelTitle();
                startButton.setText("Начать уровень");
            } else if (buttonText.equals("Начать уровень") || buttonText.equals("Начать")) {
                gameActive = true;
                startCountdown();
                startButton.setVisibility(View.GONE);
            } else if (buttonText.equals("Завершить игру")) {
                gameCompleted();
                return;
            }
        });

        retryButton.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            gameActive = true;
            retryButton.setVisibility(View.GONE);
            startCountdown();
        });

        setAllSquaresClickable(true);
    }

    private void setAllSquaresClickable(boolean clickable) {
        for (Button square : squares) {
            square.setClickable(clickable);
        }
    }

    private void setupGameGrid() {
        squares = new ArrayList<>();
        gridLayout.removeAllViews();

        int columnCount = tileCount == 2 ? 2 : (int) Math.sqrt(tileCount);
        gridLayout.setColumnCount(columnCount);

        int screenWidth = getResources().getDisplayMetrics().widthPixels;
        int tileSize = (screenWidth - 60) / columnCount;

        for (int i = 0; i < tileCount; i++) {
            Button button = new Button(this);
            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.width = tileSize;
            params.height = tileSize;
            params.setMargins(5, 5, 5, 5);
            button.setLayoutParams(params);
            button.setBackgroundColor(Color.WHITE);
            button.setOnClickListener(this::checkReaction);
            squares.add(button);
            gridLayout.addView(button);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();

        if (currentUser == null) {
            Intent intent = new Intent(ReactionGame.this, LoginActivity.class);
            startActivity(intent);
            finish();
        }
    }

    private void startCountdown() {
        countdownText.setVisibility(View.VISIBLE);
        gameStarted = false;
        countdownFinished = false;

        handler.postDelayed(() -> countdownText.setText("3"), 0);
        handler.postDelayed(() -> countdownText.setText("2"), 1000);
        handler.postDelayed(() -> countdownText.setText("1"), 2000);

        handler.postDelayed(() -> {
            countdownText.setText("");
            countdownText.setVisibility(View.GONE);
            countdownFinished = true;
            startReactionGame();
        }, 3000);
    }

    private void startReactionGame() {
        title.setText("Ждите...");
        int randomDelay = new Random().nextInt(5000 - 1000) + 1000;

        showSquareRunnable = () -> {
            showRandomSquare();
            stopwatch.start();
            gameStarted = true;
        };

        handler.postDelayed(showSquareRunnable, randomDelay);
    }

    private void showRandomSquare() {
        Random random = new Random();
        int randomIndex = random.nextInt(squares.size());
        correctSquare = squares.get(randomIndex);

        handler.post(() -> {
            correctSquare.setBackgroundColor(Color.GREEN);
            title.setText("Нажмите на зеленую плитку!");
        });
    }

    private void checkReaction(View view) {
        if (!gameActive) {
            return;
        }

        Button clickedButton = (Button) view;

        if (!countdownFinished) {
            Toast.makeText(this, "Подождите окончания отсчета!", Toast.LENGTH_SHORT).show();
            return;
        }

        if (!gameStarted) {
            title.setText("Слишком рано! Подождите зеленую плитку.");
            soundManager.playWrongSound();
            resetGame();
            return;
        }

        if (clickedButton != correctSquare) {
            title.setText("Ошибка! Нажата неверная плитка.");
            soundManager.playWrongSound();
            resetGame();
            return;
        }

        stopwatch.stop();
        reactionTime = (int) stopwatch.getElapsedTimeMillis();
        reactionTimeText.setText("Время реакции: " + reactionTime + " мс");

        clickedButton.setBackgroundColor(Color.BLUE);
        new Handler().postDelayed(() -> {
            clickedButton.setBackgroundColor(Color.WHITE);
        }, 200);

        if ("level".equals(gameMode)) {
            checkLevelCompletion(reactionTime);
        } else {
            evaluateReactionTime(reactionTime);
            retryButton.setVisibility(View.VISIBLE);
        }

        saveBestTime();
        gameActive = false;
    }

    private void evaluateReactionTime(int reactionTime) {
        if (reactionTime <= 200) {
            title.setText("Отличная реакция!");
        } else if (reactionTime <= 300) {
            title.setText("Хорошая реакция!");
        } else if (reactionTime <= 500) {
            title.setText("Средняя реакция.");
        } else {
            title.setText("Можно быстрее!");
        }
    }

    private void checkLevelCompletion(int reactionTime) {
        if (reactionTime <= levelTargets[currentLevel - 1]) {
            if (currentLevel >= levelTargets.length) {
                gameCompleted();
            } else {
                levelCompleted();
            }
        } else {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Уровень не пройден")
                    .setMessage("Вы не уложились в " + levelTargets[currentLevel - 1] + " мс")
                    .setCancelable(false)
                    .setPositiveButton("Начать с начала", (dialog, which) -> {
                        soundManager.playButtonClickSound();
                        currentLevel = 1;
                        updateLevelTitle();
                        startButton.setText("Начать уровень");
                        startButton.setVisibility(View.VISIBLE);
                        resetGame();
                    })
                    .setNegativeButton("Главное меню", (dialog, which) -> {
                        soundManager.playButtonClickSound();
                        finish();
                    });
            AlertDialog alert = builder.create();
            alert.show();
        }
    }

    private void levelCompleted() {
        soundManager.playLevelUpSound();

        if (currentLevel == levelTargets.length) {
            title.setText("Уровень " + currentLevel + " пройден!");
            startButton.setText("Завершить игру");
        } else {
            title.setText("Уровень " + currentLevel + " пройден!");
            startButton.setText("Следующий уровень");
        }

        startButton.setVisibility(View.VISIBLE);
        retryButton.setVisibility(View.GONE);
        gameActive = false;
    }

    private void gameCompleted() {
        firebaseHelper.updateReactionGameStats(playerUserId, reactionTime, new FirebaseHelper.UpdateStatsCallback() {
            @Override
            public void onUpdateCompleted(boolean newRecord) {
                if (newRecord) {
                    soundManager.playNewRecordSound();
                    showConfetti();
                } else {
                    soundManager.playVictorySound();
                }

                if ("level".equals(gameMode)) {
                    unlockNextTile();
                }

                AlertDialog.Builder builder = new AlertDialog.Builder(ReactionGame.this);
                builder.setTitle("Поздравляем!")
                        .setMessage("Вы прошли все уровни!\nВремя реакции: " + reactionTime + " мс")
                        .setPositiveButton("Играть снова", (dialog, which) -> {
                            soundManager.playButtonClickSound();
                            resetGame();
                        })
                        .setNegativeButton("Выйти", (dialog, which) -> {
                            soundManager.playButtonClickSound();
                            finish();
                        })
                        .show();
            }

            @Override
            public void onUpdateFailed(Exception e) {
                Toast.makeText(ReactionGame.this, "Ошибка обновления статистики: " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }

    private void unlockNextTile() {
        SharedPreferences preferences = getSharedPreferences("game_prefs", MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();

        Set<String> unlockedTiles = preferences.getStringSet("unlocked_tiles", new HashSet<>(Collections.singleton("1")));
        unlockedTiles = new HashSet<>(unlockedTiles);

        unlockedTiles.add(String.valueOf(tileCount));

        int nextTileCount = getNextTileCount(tileCount);
        if (nextTileCount != -1) {
            unlockedTiles.add(String.valueOf(nextTileCount));
            Toast.makeText(this, "Разблокировано количество плиток: " + nextTileCount, Toast.LENGTH_LONG).show();
        } else {
            editor.putBoolean("free_mode_unlocked", true);
            Toast.makeText(this, "Свободный режим разблокирован!", Toast.LENGTH_LONG).show();
        }

        editor.putStringSet("unlocked_tiles", unlockedTiles);
        editor.apply();
    }

    private int getNextTileCount(int currentTileCount) {
        int[] tileCounts = {1, 2, 4};
        for (int i = 0; i < tileCounts.length - 1; i++) {
            if (tileCounts[i] == currentTileCount) {
                return tileCounts[i+1];
            }
        }
        return -1;
    }

    private void saveBestTime() {
        firebaseHelper.updateReactionGameStats(playerUserId, reactionTime, new FirebaseHelper.UpdateStatsCallback() {
            @Override
            public void onUpdateCompleted(boolean newRecord) {
                if (newRecord) {
                    soundManager.playNewRecordSound();
                    showConfetti();
                    title.setText(title.getText() + " Новый рекорд!");
                }
            }

            @Override
            public void onUpdateFailed(Exception e) {
                Toast.makeText(ReactionGame.this, "Ошибка сохранения рекорда: " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }

    private void resetGame() {
        handler.removeCallbacks(showSquareRunnable);

        for (Button square : squares) {
            square.setBackgroundColor(Color.WHITE);
        }
        gameStarted = false;
        countdownFinished = false;
        gameActive = false;

        if ("level".equals(gameMode)) {
            startButton.setText("Начать уровень");
            startButton.setVisibility(View.VISIBLE);
        } else {
            retryButton.setVisibility(View.VISIBLE);
        }

        if (stopwatch.isRunning()) {
            stopwatch.stop();
        }

        setAllSquaresClickable(true);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        soundManager.release();
    }

    private void showConfetti() {
        konfettiView.build()
                .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
                .setDirection(0.0, 359.0)
                .setSpeed(1f, 5f)
                .setFadeOutEnabled(true)
                .setTimeToLive(2000L)
                .addShapes(Shape.Square.INSTANCE, Shape.Circle.INSTANCE)
                .addSizes(new Size(12, 5f))
                .setPosition(-50f, konfettiView.getWidth() + 50f, -50f, -50f)
                .streamFor(300, 5000L);
    }

    private void updateLevelTitle() {
        title.setText("Уровень " + currentLevel + ": Реагируйте быстрее чем " + levelTargets[currentLevel - 1] + " мс");
    }


}