<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MemoryMaster"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>





package com.example.memorymaster;

import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

public class DifficultySelectionActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_difficulty_selection);

        Button btnEasy = findViewById(R.id.btn_easy);
        Button btnMedium = findViewById(R.id.btn_medium);
        Button btnHard = findViewById(R.id.btn_hard);

        btnEasy.setOnClickListener(v -> startGameWithDifficulty(4)); // Легкая сложность - 4 плитки
        btnMedium.setOnClickListener(v -> startGameWithDifficulty(9)); // Средняя сложность - 9 плиток
        btnHard.setOnClickListener(v -> startGameWithDifficulty(12)); // Сложная - 12 плиток
    }

    private void startGameWithDifficulty(int tileCount) {
        Intent intent = new Intent(DifficultySelectionActivity.this, MemoryGame.class);
        intent.putExtra("tileCount", tileCount); // Передаем выбранную сложность
        startActivity(intent);
    }
}





package com.example.memorymaster;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Button;
import com.google.firebase.FirebaseApp;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private SoundManager soundManager;
    private FirebaseAuth auth;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        auth = FirebaseAuth.getInstance();

        // Проверяем, вошел ли пользователь
        if (auth.getCurrentUser() == null) {
            startActivity(new Intent(MainActivity.this, LoginActivity.class));
            finish();
        }
        FirebaseApp.initializeApp(this);
        soundManager = SoundManager.getInstance(this);

        SharedPreferences preferences = getSharedPreferences("game_prefs", MODE_PRIVATE);
        boolean isFirstRun = preferences.getBoolean("isFirstRun", true);

        if (isFirstRun) {
            // Go to LoginActivity on the first run
            startActivity(new Intent(MainActivity.this, LoginActivity.class));
            finish();
            preferences.edit().putBoolean("isFirstRun", false).apply();
            return;
        }


        Button btnStartMemoryGame = findViewById(R.id.btn_memory);
        Button btnStartReactionGame = findViewById(R.id.btn_reaction);
        Button btnProfile = findViewById(R.id.btn_profile);
        Button btnStartPairMatchingGame = findViewById(R.id.btn_pair_matching);

        btnStartMemoryGame.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            Intent intent = new Intent(MainActivity.this, DifficultySelectionActivity.class);
            startActivity(intent);
        });

        btnStartReactionGame.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            Intent intent = new Intent(MainActivity.this, ReactionGameModeSelection.class);
            startActivity(intent);
        });

        btnProfile.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
            startActivity(intent);
        });

        btnStartPairMatchingGame.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            Intent intent = new Intent(MainActivity.this, PairMatchingGame.class);
            startActivity(intent);
        });
    }

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

        // If user is not logged in, navigate to LoginActivity
        if (currentUser == null) {
            Intent intent = new Intent(MainActivity.this, LoginActivity.class);
            startActivity(intent);
            finish();  // Close MainActivity to prevent going back to it
        }
    }



    @Override
    protected void onPause() {
        super.onPause();
        if (soundManager != null) {
            soundManager.pauseBackgroundMusic();
        }
    }

}




package com.example.memorymaster;


public class MemoryCard {
    private final int value;

    public MemoryCard(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}





package com.example.memorymaster;


import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaPlayer;
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 java.util.ArrayList;
import java.util.Random;
import android.content.SharedPreferences;
import android.app.AlertDialog;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import androidx.constraintlayout.widget.ConstraintLayout;
import nl.dionsegijn.konfetti.KonfettiView;
import nl.dionsegijn.konfetti.models.Shape;
import nl.dionsegijn.konfetti.models.Size;
public class MemoryGame extends Activity {

    private GridLayout gridLayout;
    private ArrayList<Button> squares;
    private TextView title;
    private TextView level;
    private TextView scoreText;
    private Button startButton;
    private Button nextLevelButton;
    private ArrayList<Button> correctSeq;
    private int currentLevel;
    private int currentScore;
    private int userIndex;
    private int tileCount;
    private String difficulty;
    private Handler handler;
    private SharedPreferences preferences;
    private String playerNickname;
    private int attemptsLeft = 3;
    private int currentTilePoints = 50;
    private SoundManager soundManager;

    private TextView timerTextView;
    private Handler timerHandler = new Handler();
    private Runnable timerRunnable;
    private long startTime;
    private long endTime;

    private final int COLOR_BACKGROUND = Color.parseColor("#E6E6FA");
    private final int COLOR_BUTTON_NORMAL = Color.parseColor("#800080");
    private final int COLOR_BUTTON_FLASH = Color.parseColor("#008000");
    private final int COLOR_BUTTON_CORRECT = Color.parseColor("#0000FF");
    private final int COLOR_BUTTON_WRONG = Color.parseColor("#F44336");
    private final int COLOR_TEXT = Color.parseColor("#FFA500");
    private final int COLOR_TILE_NORMAL = Color.parseColor("#FFFFFF");
    private boolean gameStarted = false;
    private KonfettiView konfettiView;


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

        soundManager = SoundManager.getInstance(this);
        gridLayout = findViewById(R.id.gridLayout);

        tileCount = getIntent().getIntExtra("tileCount", 9);
        difficulty = getDifficultyLabel(tileCount);

        preferences = getSharedPreferences("game_prefs", MODE_PRIVATE);
        playerNickname = preferences.getString("nickname", "Player");

        ConstraintLayout mainLayout = findViewById(R.id.mainLayout);
        mainLayout.setBackgroundColor(COLOR_BACKGROUND);

        title = findViewById(R.id.title);
        level = findViewById(R.id.level);
        scoreText = findViewById(R.id.score);
        startButton = findViewById(R.id.startBtn);
        nextLevelButton = findViewById(R.id.nextLevelBtn);
        timerTextView = findViewById(R.id.timerTextView);

        startButton.setOnClickListener(v -> startGame());
        nextLevelButton.setOnClickListener(v -> startGame());
        nextLevelButton.setVisibility(View.GONE);

        correctSeq = new ArrayList<>();
        currentLevel = 1;
        currentScore = 0;
        handler = new Handler();

        setupUI();
        setupGameGrid();
        updateUI();

        timerRunnable = new Runnable() {
            @Override
            public void run() {
                long millis = System.currentTimeMillis() - startTime;
                int seconds = (int) (millis / 1000);
                int minutes = seconds / 60;
                seconds = seconds % 60;

                timerTextView.setText(String.format("%d:%02d", minutes, seconds));
                timerHandler.postDelayed(this, 500);
            }
        };
        startButton.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            startGame();
        });
        nextLevelButton.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            startGame();
        });
    }

    private void setupUI() {
        title.setTextColor(COLOR_TEXT);
        level.setTextColor(COLOR_TEXT);
        scoreText.setTextColor(COLOR_TEXT);

        startButton.setBackgroundColor(COLOR_BUTTON_NORMAL);
        startButton.setTextColor(COLOR_TEXT);

        nextLevelButton.setBackgroundColor(COLOR_BUTTON_NORMAL);
        nextLevelButton.setTextColor(COLOR_TEXT);
    }

    private String getDifficultyLabel(int tileCount) {
        switch (tileCount) {
            case 4:
                return "easy";
            case 9:
                return "medium";
            case 12:
                return "hard";
            default:
                return "medium";
        }
    }

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

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

        int screenWidth = getResources().getDisplayMetrics().widthPixels;
        int screenHeight = getResources().getDisplayMetrics().heightPixels;

        int availableWidth = screenWidth - 40;
        int availableHeight = screenHeight - 300;

        int tileSize = Math.min(availableWidth / columnCount, availableHeight / columnCount) - 10;

        for (int i = 0; i < tileCount; i++) {
            Button button = new Button(this);
            button.setId(View.generateViewId());

            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.width = tileSize;
            params.height = tileSize;
            params.setMargins(5, 5, 5, 5);
            button.setLayoutParams(params);

            button.setBackgroundColor(COLOR_TILE_NORMAL);
            button.setTextColor(COLOR_TEXT);
            button.setTextSize(20);

            button.setOnClickListener(this::checkSequence);
            squares.add(button);
            gridLayout.addView(button);
        }
    }

    private void resetTileColors() {
        for (Button button : squares) {
            button.setBackgroundColor(COLOR_TILE_NORMAL);
            button.setText("");
        }
    }

    private void startGame() {
        gameStarted = true;
        isCheckingSequence = false;
        if (currentLevel == 1) {
            startTime = System.currentTimeMillis();
        }
        timerHandler.postDelayed(timerRunnable, 0);
        nextLevelButton.setVisibility(View.GONE);
        if (currentLevel > 2) {
            showVictoryMessage();
            return;
        }

        correctSeq.clear();
        userIndex = 0;
        currentTilePoints = 50;
        title.setText("Запоминай последовательность!");
        level.setText("Уровень " + currentLevel + " | Попыток: " + attemptsLeft);
        disableSquares();
        startButton.setVisibility(View.INVISIBLE);

        resetTileColors();
        showPattern();
    }



    private void showPattern() {
        disableSquares();
        int delay = preferences.getInt("sequence_speed", 700);
        for (int i = 0; i < currentLevel; i++) {
            int finalI = i;
            handler.postDelayed(() -> {
                Random random = new Random();
                int randomIndex = random.nextInt(squares.size());
                Button randomSq = squares.get(randomIndex);
                flashButton(randomSq, false);
                correctSeq.add(randomSq);

                if (finalI == currentLevel - 1) {
                    handler.postDelayed(this::playerTurn, 700);
                }
            }, delay);
            delay += preferences.getInt("sequence_speed", 700);
        }
    }

    private void flashButton(Button button, boolean isPlayerTurn) {
        int color = isPlayerTurn ? COLOR_BUTTON_CORRECT : COLOR_BUTTON_FLASH;
        animateButton(button, color, "");
        soundManager.playButtonClickSound();
    }

    private void playerTurn() {
        enableSquares();
        title.setText("Повтори последовательность");
    }

    private boolean isCheckingSequence = false;
    private void checkSequence(View view) {
        if (!gameStarted || isCheckingSequence) {
            return;
        }

        soundManager.playButtonClickSound();
        isCheckingSequence = true;
        Button clickedButton = (Button) view;

        if (clickedButton == correctSeq.get(userIndex)) {
            soundManager.playCorrectSound();
            animateButton(clickedButton, COLOR_BUTTON_CORRECT, "✔");

            userIndex++;
            level.setText(userIndex + "/" + currentLevel);

            currentScore += currentTilePoints;
            currentTilePoints += 25;

            updateUI();

            if (userIndex == currentLevel) {
                currentLevel++;
                soundManager.playLevelUpSound();
                handler.postDelayed(this::startNextLevel, 1000);
            } else {
                handler.postDelayed(() -> {
                    isCheckingSequence = false;
                    enableSquares();
                }, 500);
            }
        } else {
            soundManager.playWrongSound();
            animateButton(clickedButton, COLOR_BUTTON_WRONG, "✖");

            currentScore = 0;
            updateUI();

            attemptsLeft--;
            if (attemptsLeft > 0) {
                handler.postDelayed(this::resetLevel, 1000);
            } else {
                handler.postDelayed(this::gameOver, 1000);
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (gameStarted) {
            timerHandler.postDelayed(timerRunnable, 0);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        timerHandler.removeCallbacks(timerRunnable);
    }


    private void startNextLevel() {
        title.setText("Уровень пройден! Готовы к следующему?");
        nextLevelButton.setVisibility(View.VISIBLE);
        disableSquares();
        isCheckingSequence = false;
    }

    private void resetLevel() {
        title.setText("Новая последовательность! Попыток: " + attemptsLeft);
        disableSquares();
        isCheckingSequence = false;
        handler.postDelayed(this::startGame, 1000);
    }

    private void gameOver() {
        gameStarted = false;
        isCheckingSequence = false;
        timerHandler.removeCallbacks(timerRunnable);
        title.setText("Игра окончена!");

        endTime = System.currentTimeMillis();
        long totalTime = (endTime - startTime) / 1000;

        disableSquares();
        startButton.setVisibility(View.VISIBLE);

        boolean isNewRecord = dbHelper.updateMemoryGameStats(playerNickname, difficulty, currentScore, totalTime);

        if (isNewRecord) {
            soundManager.playNewRecordSound();
            showConfetti();
        } else {
            soundManager.playDefeatSound();
        }

        showGameOverDialog(isNewRecord);
    }

    private void showGameOverDialog(boolean isNewRecord) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AlertDialogCustom);
        String message = isNewRecord ?
                "Поздравляем! Вы установили новый рекорд!\n" :
                "Вы исчерпали все попытки. ";
        message += "Хотите попробовать снова или вернуться в главное меню?";

        builder.setTitle("Игра окончена!")
                .setMessage(message)
                .setPositiveButton("Попробовать снова", (dialog, which) -> {
                    currentLevel = 1;
                    currentScore = 0;
                    currentTilePoints = 50;
                    attemptsLeft = 3;
                    startGame();
                })
                .setNegativeButton("Главное меню", (dialog, which) -> {
                    Intent intent = new Intent(MemoryGame.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                })
                .setCancelable(false)
                .show();
    }


    private void showVictoryMessage() {
        endTime = System.currentTimeMillis();
        long totalTime = (endTime - startTime) / 1000;

        boolean isNewRecord = dbHelper.updateMemoryGameStats(playerNickname, difficulty, currentScore, totalTime);

        if (isNewRecord) {
            soundManager.playNewRecordSound();
            showConfetti();
        } else {
            soundManager.playVictorySound();
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AlertDialogCustom);
        String message = isNewRecord ?
                "Поздравляем! Вы установили новый рекорд!\n" :
                "Вы успешно прошли игру!\n";

        builder.setTitle("Поздравляем!")
                .setMessage(message)
                .setPositiveButton("Назад в главное меню", (dialog, which) -> {
                    Intent intent = new Intent(MemoryGame.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                })
                .setCancelable(false)
                .show();
    }


    private void updateUI() {
        scoreText.setText("Очки: " + currentScore);
        level.setText("Уровень: " + currentLevel + " | Попыток: " + attemptsLeft);
    }

    private void enableSquares() {
        for (Button square : squares) {
            square.setClickable(true);
        }
    }

    private void disableSquares() {
        for (Button square : squares) {
            square.setClickable(false);
        }
    }

    private void animateButton(final Button button, int color, String text) {
        button.setBackgroundColor(color);
        button.setText(text);

        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1f, 1.2f, 1f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1f, 1.2f, 1f);
        ObjectAnimator scaleAnimator = ObjectAnimator.ofPropertyValuesHolder(button, scaleX, scaleY);
        scaleAnimator.setDuration(300);
        scaleAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

        scaleAnimator.start();

        handler.postDelayed(() -> {
            button.setBackgroundColor(COLOR_TILE_NORMAL);
            button.setText("");
        }, 500);
    }



    @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);
    }
}






package com.example.memorymaster;


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 androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Collections;

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

public class PairMatchingGame extends AppCompatActivity {

    private GridLayout gridLayout;
    private ArrayList<Button> cardButtons;
    private MemoryCard[] cardValues;
    private Button firstSelectedCard = null;
    private boolean isFlipping = false;
    private int matchedPairs = 0;
    private int currentLevel = 1;
    private int totalMoves = 0;
    private int moves = 0;
    private long totalTime = 0;
    private TextView movesTextView;
    private long startTime;
    private Handler timerHandler = new Handler();
    private TextView timerTextView;
    private DB dbHelper;
    private String nickname;
    private long pauseTime = 0;
    private SoundManager soundManager;
    private KonfettiView konfettiView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pair_matching_game);
        konfettiView = findViewById(R.id.konfettiView);
        soundManager = SoundManager.getInstance(this);


        gridLayout = findViewById(R.id.gridLayout);
        cardButtons = new ArrayList<>();
        movesTextView = findViewById(R.id.movesTextView);
        timerTextView = findViewById(R.id.timerTextView);

        dbHelper = new DB(this);
        SharedPreferences preferences = getSharedPreferences("game_prefs", MODE_PRIVATE);
        nickname = preferences.getString("nickname", "");

        setupGameForLevel(currentLevel);
        startTimer();
    }

    private void setupGameForLevel(int level) {
        int numberOfCards;
        switch (level) {
            case 1:
                numberOfCards = 6;  // Easy level (6 cards)
                break;
            case 2:
                numberOfCards = 12; // Medium level (12 cards)
                break;
            default:
                numberOfCards = 16; // Hard level (16 cards)
        }

        cardValues = new MemoryCard[numberOfCards];
        for (int i = 0; i < numberOfCards / 2; i++) {
            cardValues[i] = new MemoryCard(i + 1);
            cardValues[i + numberOfCards / 2] = new MemoryCard(i + 1);
        }

        setupGameGrid(numberOfCards);
        updateMovesDisplay();

        // Reset matchedPairs and moves for the new level
        matchedPairs = 0;
        moves = 0;
    }

    private void setupGameGrid(int numberOfCards) {
        gridLayout.removeAllViews();
        cardButtons.clear();

        int columnCount = (int) Math.sqrt(numberOfCards);
        gridLayout.setColumnCount(columnCount);

        ArrayList<MemoryCard> cardList = new ArrayList<>();
        Collections.addAll(cardList, cardValues);
        Collections.shuffle(cardList);

        for (MemoryCard card : cardList) {
            Button button = new Button(this);
            button.setTag(card);
            button.setText("");
            button.setBackgroundResource(R.drawable.card_back);

            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.width = 0;
            params.height = GridLayout.LayoutParams.WRAP_CONTENT;
            params.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f);
            params.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f);
            button.setLayoutParams(params);

            button.setOnClickListener(this::onCardClick);
            cardButtons.add(button);
            gridLayout.addView(button);
        }
    }

    private void onCardClick(View view) {
        if (isFlipping) return;

        Button selectedButton = (Button) view;
        MemoryCard selectedCard = (MemoryCard) selectedButton.getTag();

        soundManager.playButtonClickSound();

        if (selectedButton.getText().toString().isEmpty()) {
            selectedButton.setText(String.valueOf(selectedCard.getValue()));
            selectedButton.setBackgroundResource(R.drawable.card_front);

            if (firstSelectedCard == null) {
                firstSelectedCard = selectedButton;
            } else {
                moves++;
                totalMoves++;
                updateMovesDisplay();

                MemoryCard firstCard = (MemoryCard) firstSelectedCard.getTag();
                if (firstCard.getValue() == selectedCard.getValue()) {
                    soundManager.playCorrectSound();
                    firstSelectedCard.setEnabled(false);
                    selectedButton.setEnabled(false);
                    matchedPairs++;

                    if (matchedPairs == cardValues.length / 2) {
                        onGameWon();
                    }
                    firstSelectedCard = null;
                } else {
                    soundManager.playWrongSound();
                    isFlipping = true;
                    new Handler().postDelayed(() -> {
                        firstSelectedCard.setText("");
                        selectedButton.setText("");
                        firstSelectedCard.setBackgroundResource(R.drawable.card_back);
                        selectedButton.setBackgroundResource(R.drawable.card_back);
                        firstSelectedCard = null;
                        isFlipping = false;
                    }, 1000);
                }
            }
        }
    }
    private void updateMovesDisplay() {
        movesTextView.setText("Moves: " + moves + " (Total: " + totalMoves + ")");
    }

    private void startTimer() {
        startTime = System.currentTimeMillis() - pauseTime;
        timerHandler.postDelayed(timerRunnable, 0);
    }

    private void pauseTimer() {
        timerHandler.removeCallbacks(timerRunnable);
        pauseTime = System.currentTimeMillis() - startTime;
    }

    private Runnable timerRunnable = new Runnable() {
        @Override
        public void run() {
            long millis = System.currentTimeMillis() - startTime;
            int seconds = (int) (millis / 1000);
            int minutes = seconds / 60;
            seconds = seconds % 60;

            timerTextView.setText(String.format("%d:%02d", minutes, seconds));
            timerHandler.postDelayed(this, 500);
        }
    };

    private void onGameWon() {
        pauseTimer();
        totalTime += pauseTime / 1000;

        if (currentLevel < 3) {
            currentLevel++;
            soundManager.playLevelUpSound();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Level " + (currentLevel - 1) + " Completed!")
                    .setMessage("Get ready for Level " + currentLevel + "\nMoves: " + moves + "\nTime: " + formatTime(pauseTime / 1000))
                    .setPositiveButton("Continue", (dialog, which) -> {
                        soundManager.playButtonClickSound();
                        setupGameForLevel(currentLevel);
                        pauseTime = 0;
                        startTimer();
                    })
                    .setCancelable(false)
                    .show();
        } else {
            // Game completed
            boolean isNewRecord = dbHelper.updatePairMatchingStats(nickname, totalMoves, totalTime);

            if (isNewRecord) {
                soundManager.playNewRecordSound();
                showConfetti();
            } else {
                soundManager.playVictorySound();
            }

            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Congratulations!")
                    .setMessage("You've completed all levels!\nTotal Moves: " + totalMoves + "\nTotal Time: " + formatTime(totalTime))
                    .setPositiveButton("Play Again", (dialog, which) -> {
                        soundManager.playButtonClickSound();
                        resetGame();
                    })
                    .setNegativeButton("Exit", (dialog, which) -> {
                        soundManager.playButtonClickSound();
                        finish();
                    })
                    .show();
        }
    }

    private String formatTime(long totalSeconds) {
        long minutes = totalSeconds / 60;
        long seconds = totalSeconds % 60;
        return String.format("%d:%02d", minutes, seconds);
    }

    private void resetGame() {
        currentLevel = 1;
        totalMoves = 0;
        totalTime = 0;
        pauseTime = 0;
        setupGameForLevel(currentLevel);
        startTimer();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        timerHandler.removeCallbacks(timerRunnable);
    }


    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);
    }
}







package com.example.memorymaster;

import android.app.Activity;
import android.content.SharedPreferences;
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.graphics.Color;
import android.app.AlertDialog;

import java.util.ArrayList;
import java.util.Random;

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 DB dbHelper;
    private SharedPreferences preferences;
    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;

    @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();
        }

        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);
        dbHelper = new DB(this);
        preferences = getSharedPreferences("game_prefs", MODE_PRIVATE);
        playerNickname = preferences.getString("nickname", "Player");
        stopwatch = new Stopwatch();
        handler = new Handler();
        soundManager = SoundManager.getInstance(this);

        setupGameGrid();
    }

    private void startLevelMode() {
        updateLevelTitle();
    }

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

    private void setupListeners() {
        startButton.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            gameActive = true;
            startCountdown();
            startButton.setVisibility(View.GONE);
        });

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

        setAllSquaresClickable(true);
    }

    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);
        }
    }

    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) {
            // Если игрок нажал слишком рано, игра считается проигранной
            title.setText("Слишком рано! Вы проиграли.");
            soundManager.playWrongSound();
            resetGame();  // Завершаем игру
            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 levelCompleted() {
        soundManager.playLevelUpSound();
        title.setText("Уровень " + currentLevel + " пройден!");
        startButton.setText("Следующий уровень");
        startButton.setVisibility(View.VISIBLE);
        retryButton.setVisibility(View.GONE);
        gameActive = false;
        startButton.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            currentLevel++;
            updateLevelTitle();
            startButton.setVisibility(View.GONE);
            gameActive = true;
            startCountdown();
        });
    }

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

    private void gameCompleted() {
        soundManager.playVictorySound();
        showConfetti();
        title.setText("Поздравляем! Вы прошли все уровни!");
        startButton.setText("Играть снова");
        startButton.setVisibility(View.VISIBLE);
        retryButton.setVisibility(View.GONE);
        gameActive = false;
        startButton.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            currentLevel = 1;
            updateLevelTitle();
            startButton.setVisibility(View.GONE);
            gameActive = true;
            startCountdown();
        });
    }

    private void saveBestTime() {
        boolean newRecord = dbHelper.updateReactionGameStats(playerNickname, reactionTime);
        if (newRecord) {
            soundManager.playNewRecordSound();
            showConfetti();
            title.setText(title.getText() + " Новый рекорд!");
        }
    }

    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.setVisibility(View.VISIBLE);
            startButton.setText("Начать уровень");
        } else {
            retryButton.setVisibility(View.VISIBLE);
        }

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

        setAllSquaresClickable(true);
    }

    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();
                        gameActive = true;
                        startCountdown();
                    })
                    .setNegativeButton("Главное меню", (dialog, which) -> {
                        soundManager.playButtonClickSound();
                        finish(); // Возвращаемся в главное меню
                    });
            AlertDialog alert = builder.create();
            alert.show();
        }
        resetGame();
    }

    private void setAllSquaresClickable(boolean clickable) {
        for (Button square : squares) {
            square.setClickable(clickable);
            if (clickable) {
                square.setOnClickListener(this::checkReaction);
            } else {
                square.setOnClickListener(null);
            }
        }
    }

    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);
    }
}





package com.example.memorymaster;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;

public class ReactionGameModeSelection extends Activity {
    private SoundManager soundManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reaction_game_mode_selection);

        soundManager = SoundManager.getInstance(this);

        Button btnFreeMode = findViewById(R.id.btn_free_mode);
        Button btnLevelMode = findViewById(R.id.btn_level_mode);

        // Вместо непосредственного запуска игры, переходим на экран выбора плиток
        btnFreeMode.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            Intent intent = new Intent(ReactionGameModeSelection.this, TileSelectionActivity.class);
            intent.putExtra("gameMode", "free");
            startActivity(intent);
        });

        btnLevelMode.setOnClickListener(v -> {
            soundManager.playButtonClickSound();
            Intent intent = new Intent(ReactionGameModeSelection.this, TileSelectionActivity.class);
            intent.putExtra("gameMode", "level");
            startActivity(intent);
        });
    }
}







package com.example.memorymaster;

import android.content.Context;
import android.media.AudioAttributes;
import android.media.MediaPlayer;
import android.media.SoundPool;

public class SoundManager {
    private static SoundManager instance;
    private SoundPool soundPool;
    private MediaPlayer backgroundMusic;
    private Context context;

    private int buttonClickSound;
    private int correctSound;
    private int wrongSound;
    private int victorySound;
    private int defeatSound;
    private int newRecordSound;
    private int levelUpSound;

    private boolean isMusicEnabled = true;
    private boolean isSoundEnabled = true;

    private SoundManager(Context context) {
        this.context = context.getApplicationContext();
        initializeSoundPool();
    }

    public static synchronized SoundManager getInstance(Context context) {
        if (instance == null) {
            instance = new SoundManager(context);
        } else if (instance.soundPool == null) {
            instance.initializeSoundPool();
        }
        return instance;
    }

    private void initializeSoundPool() {
        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();

        soundPool = new SoundPool.Builder()
                .setMaxStreams(6)
                .setAudioAttributes(audioAttributes)
                .build();

        buttonClickSound = soundPool.load(context, R.raw.button_click, 1);
        correctSound = soundPool.load(context, R.raw.correct_sound, 1);
        wrongSound = soundPool.load(context, R.raw.wrong_sound, 1);
        victorySound = soundPool.load(context, R.raw.victory, 1);
        defeatSound = soundPool.load(context, R.raw.defeat, 1);
        newRecordSound = soundPool.load(context, R.raw.new_record, 1);
        levelUpSound = soundPool.load(context, R.raw.level_up, 1);

        initializeBackgroundMusic();
    }

    private void initializeBackgroundMusic() {
        backgroundMusic = MediaPlayer.create(context, R.raw.background_music);
        backgroundMusic.setLooping(true);
    }

    public void playButtonClickSound() {
        playSoundEffect(buttonClickSound);
    }

    public void playCorrectSound() {
        playSoundEffect(correctSound);
    }

    public void playWrongSound() {
        playSoundEffect(wrongSound);
    }

    public void playVictorySound() {
        playSoundEffect(victorySound);
    }

    public void playDefeatSound() {
        playSoundEffect(defeatSound);
    }

    public void playNewRecordSound() {
        playSoundEffect(newRecordSound);
    }

    public void playLevelUpSound() {
        playSoundEffect(levelUpSound);
    }

    private void playSoundEffect(int soundId) {
        if (isSoundEnabled && soundPool != null) {
            soundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
        }
    }

    public void playBackgroundMusic() {
        if (isMusicEnabled && backgroundMusic != null && !backgroundMusic.isPlaying()) {
            backgroundMusic.start();
        }
    }

    public void pauseBackgroundMusic() {
        if (backgroundMusic != null && backgroundMusic.isPlaying()) {
            backgroundMusic.pause();
        }
    }

    public void stopBackgroundMusic() {
        if (backgroundMusic != null) {
            backgroundMusic.stop();
            backgroundMusic.prepareAsync();
        }
    }

    public void setMusicEnabled(boolean enabled) {
        isMusicEnabled = enabled;
        if (enabled) {
            playBackgroundMusic();
        } else {
            pauseBackgroundMusic();
        }
    }

    public void setSoundEnabled(boolean enabled) {
        isSoundEnabled = enabled;
    }

    public void release() {
        if (soundPool != null) {
            soundPool.release();
            soundPool = null;
        }
        if (backgroundMusic != null) {
            backgroundMusic.release();
            backgroundMusic = null;
        }
    }
}






package com.example.memorymaster;

public class Stopwatch {
    private long startTime;
    private long stopTime;
    private boolean running;

    public void start() {
        this.startTime = System.currentTimeMillis();
        this.running = true;
    }

    public void stop() {
        this.stopTime = System.currentTimeMillis();
        this.running = false;
    }

    public long getElapsedTimeNano() {
        if (running) {
            return System.nanoTime() - startTime;
        } else {
            return stopTime - startTime;
        }
    }

    public long getElapsedTimeMillis() {
        if (running) {
            return System.currentTimeMillis() - startTime;
        } else {
            return stopTime - startTime;
        }
    }

    public boolean isRunning() {
        return running;
    }
}





package com.example.memorymaster;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;

public class TileSelectionActivity extends Activity {

    private String gameMode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tile_selection);

        // Получаем режим игры из предыдущей активности
        gameMode = getIntent().getStringExtra("gameMode");

        Button btnOneTile = findViewById(R.id.btn_one_tile);
        Button btnTwoTiles = findViewById(R.id.btn_two_tiles);
        Button btnFourTiles = findViewById(R.id.btn_four_tiles);

        // Слушатели для выбора количества плиток
        btnOneTile.setOnClickListener(v -> startGame(1));
        btnTwoTiles.setOnClickListener(v -> startGame(2));
        btnFourTiles.setOnClickListener(v -> startGame(4));
    }

    // Метод для запуска игры с выбранным количеством плиток
    private void startGame(int tileCount) {
        Intent intent = new Intent(TileSelectionActivity.this, ReactionGame.class);
        // Передаем количество плиток и режим игры в ReactionGame
        intent.putExtra("tileCount", tileCount);
        intent.putExtra("gameMode", gameMode);
        startActivity(intent);

        // Закрываем текущую активность выбора
        finish();  // Закрывает TileSelectionActivity, чтобы оно не накладывалось на интерфейс игры
    }
}








activity_difficulty_selection.xml:
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E6E6FA"
    android:padding="16dp">

    <!-- Закрепленный заголовок сверху -->
    <TextView
        android:id="@+id/select_difficulty_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Выберите сложность"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="#FFA500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <!-- Центрируем кнопки с отступами -->
    <Button
        android:id="@+id/btn_easy"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="Легкая сложность"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/select_difficulty_label"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/btn_medium"
        app:layout_constraintVertical_chainStyle="packed"
        android:layout_marginTop="16dp"/>

    <Button
        android:id="@+id/btn_medium"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="Средняя сложность"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/btn_easy"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/btn_hard"
        android:layout_marginTop="16dp"/>

    <Button
        android:id="@+id/btn_hard"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="Тяжелая сложность"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/btn_medium"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginTop="16dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>





activity_level_selection.xml:
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E6E6FA"
    android:padding="16dp">

    <TextView
        android:id="@+id/select_level_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Выберите уровень"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="#FFA500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="16dp"/>

    <!-- Сетка для отображения уровней -->
    <androidx.gridlayout.widget.GridLayout
        android:id="@+id/levelGrid"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:columnCount="3"
        app:layout_constraintTop_toBottomOf="@id/select_level_label"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp"
        app:rowCount="3" />

</androidx.constraintlayout.widget.ConstraintLayout>






activity_main.xml:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:background="#E6E6FA">

    <!-- Закрепленный заголовок сверху -->
    <TextView
        android:id="@+id/game_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Мастер памяти"
        android:textSize="30sp"
        android:textStyle="bold"
        android:textColor="#FFA500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <!-- Центрируем кнопки -->
    <Button
        android:id="@+id/btn_memory"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="Мастер памяти"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/game_title"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/btn_reaction"
        app:layout_constraintVertical_chainStyle="packed"
        android:layout_marginTop="200dp"/>

    <Button
        android:id="@+id/btn_reaction"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="Игра на реакцию"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/btn_memory"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/btn_pair_matching"
        app:layout_constraintVertical_chainStyle="packed"
        android:layout_marginTop="16dp"/>

    <Button
        android:id="@+id/btn_pair_matching"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="Найди пару плиток"
        android:background="#800080"
        android:textColor="#FFA500"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/btn_reaction"
        app:layout_constraintBottom_toTopOf="@id/btn_profile"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintVertical_chainStyle="packed"/>


    <Button
        android:id="@+id/btn_profile"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="Профиль"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/btn_pair_matching"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp"
        app:layout_constraintVertical_chainStyle="packed"/>


</androidx.constraintlayout.widget.ConstraintLayout>





activity_memory_game.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Мастер памяти"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="#FFA500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <TextView
        android:id="@+id/level"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Уровень 1"
        android:textSize="18sp"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/title"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginTop="8dp"/>

    <TextView
        android:id="@+id/score"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Счёт: 0"
        android:textSize="18sp"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/title"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="8dp"/>

    <TextView
        android:id="@+id/timerTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0:00"
        android:textSize="18sp"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/level"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginTop="8dp"/>

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.2" />

    <GridLayout
        android:id="@+id/gridLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/guideline"
        app:layout_constraintBottom_toTopOf="@id/startBtn"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp"/>

    <Button
        android:id="@+id/startBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Начать игру"
        android:textColor="#FFA500"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="16dp"/>

    <Button
        android:id="@+id/nextLevelBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Следующий уровень"
        android:textColor="#FFA500"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="16dp"
        android:visibility="gone" />


    <nl.dionsegijn.konfetti.KonfettiView
        android:id="@+id/konfettiView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>





activity_pair_matching_game.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E6E6FA"
    android:padding="16dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Найди пару плиток"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="#FFA500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="16dp"/>

    <TextView
        android:id="@+id/movesTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Ходы: 0"
        android:textSize="18sp"
        android:textColor="#4B0082"
        app:layout_constraintTop_toBottomOf="@id/title"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginTop="8dp"/>

    <TextView
        android:id="@+id/timerTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Время: 0:00"
        android:textSize="18sp"
        android:textColor="#4B0082"
        app:layout_constraintTop_toBottomOf="@id/title"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="8dp"/>

    <GridLayout
        android:id="@+id/gridLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/movesTextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="16dp"/>

    <nl.dionsegijn.konfetti.KonfettiView
        android:id="@+id/konfettiView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>





activity_reaction_game.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E6E6FA"
    android:padding="16dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Игра на реакцию"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="#FFA500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <TextView
        android:id="@+id/countdownText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="36sp"
        android:textStyle="bold"
        android:textColor="#FF0000"
        app:layout_constraintTop_toBottomOf="@id/title"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp"
        android:visibility="gone" />

    <TextView
        android:id="@+id/reactionTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Время реакции: 0 ms"
        android:textSize="18sp"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/countdownText"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp"/>

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.3" />

    <GridLayout
        android:id="@+id/gridLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/guideline"
        app:layout_constraintBottom_toTopOf="@id/startBtn"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp"/>

    <Button
        android:id="@+id/startBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Начать игру"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="16dp"
        android:visibility="visible" />

    <Button
        android:id="@+id/retryBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Ещё раз"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="16dp"
        android:visibility="gone" />

    <nl.dionsegijn.konfetti.KonfettiView
        android:id="@+id/konfettiView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>




activity_reaction_game_mode_selection.xml:
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_free_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Free Mode" />

    <Button
        android:id="@+id/btn_level_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Level Mode" />
</LinearLayout>






activity_tile_selection.xml:
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E6E6FA"
    android:padding="16dp">

    <TextView
        android:id="@+id/select_difficulty_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Выберите количество плиток"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="#FFA500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <Button
        android:id="@+id/btn_one_tile"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="1 Плитка"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/select_difficulty_label"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/btn_two_tiles"
        app:layout_constraintVertical_chainStyle="packed"
        android:layout_marginTop="16dp"/>

    <Button
        android:id="@+id/btn_two_tiles"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="2 Плитки"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/btn_one_tile"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/btn_four_tiles"
        app:layout_constraintVertical_chainStyle="packed"
        android:layout_marginTop="16dp"/>

    <Button
        android:id="@+id/btn_four_tiles"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="4 Плитки"
        android:background="#800080"
        android:textColor="#FFA500"
        app:layout_constraintTop_toBottomOf="@id/btn_two_tiles"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        android:layout_marginTop="16dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>



как сделать кастомную авторизацию чтобы пользователи просто вводили свой никнейм и пароль и у них создавался аккаунт в firebase и вся внутриигровая рекорды хранились там 

вот в старом коде я кажется использовал локальную базу данных но в новом этом проекте я хочу полностью использовать firebase

вот код старой локальной базы данных
package com.example.memorygameone;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DB extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "games.db";
    public static final int DATABASE_VERSION = 1;

    // Table for the original memory game
    public static final String MEMORY_GAME_TABLE = "memory_game_statistics";
    public static final String COL_ID = "ID";
    public static final String COL_NICKNAME = "NICKNAME";
    public static final String COL_DIFFICULTY = "DIFFICULTY";
    public static final String COL_BEST_TIME_MEMORY = "BEST_TIME_MEMORY";
    public static final String COL_BEST_TIME_SCORE_MEMORY = "BEST_TIME_SCORE_MEMORY";
    public static final String COL_BEST_SCORE_MEMORY = "BEST_SCORE_MEMORY";
    public static final String COL_BEST_SCORE_TIME_MEMORY = "BEST_SCORE_TIME_MEMORY";

    // Table for the reaction game
    public static final String REACTION_GAME_TABLE = "reaction_game_statistics";
    public static final String COL_BEST_REACTION_TIME = "BEST_REACTION_TIME";

    // Table for the pair matching game
    public static final String PAIR_MATCHING_TABLE = "pair_matching_statistics";
    public static final String COL_BEST_MOVES = "BEST_MOVES";
    public static final String COL_BEST_TIME = "BEST_TIME";
    public static final String COL_FASTEST_MOVES = "FASTEST_MOVES";
    public static final String COL_FASTEST_TIME = "FASTEST_TIME";

    public DB(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        // Create table for memory game
        db.execSQL("CREATE TABLE " + MEMORY_GAME_TABLE + " (" +
                COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COL_NICKNAME + " TEXT, " +
                COL_DIFFICULTY + " TEXT, " +
                COL_BEST_TIME_MEMORY + " INTEGER, " +
                COL_BEST_TIME_SCORE_MEMORY + " INTEGER, " +
                COL_BEST_SCORE_MEMORY + " INTEGER, " +
                COL_BEST_SCORE_TIME_MEMORY + " INTEGER)");


        // Create table for reaction game
        db.execSQL("CREATE TABLE " + REACTION_GAME_TABLE + " (" +
                COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COL_NICKNAME + " TEXT, " +
                COL_BEST_REACTION_TIME + " INTEGER)");

        // Create table for pair matching game
        db.execSQL("CREATE TABLE " + PAIR_MATCHING_TABLE + " (" +
                COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COL_NICKNAME + " TEXT, " +
                COL_BEST_MOVES + " INTEGER, " +
                COL_BEST_TIME + " INTEGER, " +
                COL_FASTEST_MOVES + " INTEGER, " +
                COL_FASTEST_TIME + " INTEGER)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older tables if existed
        db.execSQL("DROP TABLE IF EXISTS " + MEMORY_GAME_TABLE);
        db.execSQL("DROP TABLE IF EXISTS " + REACTION_GAME_TABLE);
        db.execSQL("DROP TABLE IF EXISTS " + PAIR_MATCHING_TABLE);
        // Create tables again
        onCreate(db);
    }

    // Метод обновления статистики игры Memory
    public boolean updateMemoryGameStats(String nickname, String difficulty, int newScore, long newTime) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM " + MEMORY_GAME_TABLE +
                " WHERE " + COL_NICKNAME + "=? AND " + COL_DIFFICULTY + "=?", new String[]{nickname, difficulty});

        boolean newRecord = false;
        ContentValues values = new ContentValues();

        if (cursor.moveToFirst()) {
            long bestTime = cursor.getLong(cursor.getColumnIndexOrThrow(COL_BEST_TIME_MEMORY));
            int bestScore = cursor.getInt(cursor.getColumnIndexOrThrow(COL_BEST_SCORE_MEMORY));

            if (newTime < bestTime) {
                values.put(COL_BEST_TIME_MEMORY, newTime);
                values.put(COL_BEST_TIME_SCORE_MEMORY, newScore);
                newRecord = true;
            }

            if (newScore > bestScore) {
                values.put(COL_BEST_SCORE_MEMORY, newScore);
                values.put(COL_BEST_SCORE_TIME_MEMORY, newTime);
                newRecord = true;
            }

            if (newRecord) {
                db.update(MEMORY_GAME_TABLE, values, COL_NICKNAME + "=? AND " + COL_DIFFICULTY + "=?", new String[]{nickname, difficulty});
            }
        } else {
            values.put(COL_NICKNAME, nickname);
            values.put(COL_DIFFICULTY, difficulty);
            values.put(COL_BEST_TIME_MEMORY, newTime);
            values.put(COL_BEST_TIME_SCORE_MEMORY, newScore);
            values.put(COL_BEST_SCORE_MEMORY, newScore);
            values.put(COL_BEST_SCORE_TIME_MEMORY, newTime);
            db.insert(MEMORY_GAME_TABLE, null, values);
            newRecord = true;
        }

        cursor.close();


        return newRecord;
    }


    public Cursor getMemoryGameStats(String nickname, String difficulty) {
        SQLiteDatabase db = this.getReadableDatabase();
        return db.rawQuery("SELECT * FROM " + MEMORY_GAME_TABLE +
                " WHERE " + COL_NICKNAME + "=? AND " + COL_DIFFICULTY + "=?", new String[]{nickname, difficulty});
    }

    // Methods for Reaction Game
    public boolean updateReactionGameStats(String nickname, int reactionTime) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT " + COL_BEST_REACTION_TIME + " FROM " + REACTION_GAME_TABLE +
                " WHERE " + COL_NICKNAME + "=?", new String[]{nickname});
        boolean newRecord = false;

        if (cursor.moveToFirst()) {
            int bestTime = cursor.getInt(0);
            if (reactionTime < bestTime) {
                ContentValues contentValues = new ContentValues();
                contentValues.put(COL_BEST_REACTION_TIME, reactionTime);
                db.update(REACTION_GAME_TABLE, contentValues, COL_NICKNAME + "=?", new String[]{nickname});
                newRecord = true;
            }
        } else {
            ContentValues contentValues = new ContentValues();
            contentValues.put(COL_NICKNAME, nickname);
            contentValues.put(COL_BEST_REACTION_TIME, reactionTime);
            db.insert(REACTION_GAME_TABLE, null, contentValues);
            newRecord = true;
        }
        cursor.close();
        return newRecord;
    }

    public Cursor getReactionGameStats(String nickname) {
        SQLiteDatabase db = this.getReadableDatabase();
        return db.rawQuery("SELECT " + COL_BEST_REACTION_TIME + " FROM " + REACTION_GAME_TABLE +
                " WHERE " + COL_NICKNAME + "=?", new String[]{nickname});
    }

    // Methods for Pair Matching Game
    public boolean updatePairMatchingStats(String nickname, int moves, long time) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM " + PAIR_MATCHING_TABLE + " WHERE " + COL_NICKNAME + "=?", new String[]{nickname});

        boolean newRecord = false;
        ContentValues values = new ContentValues();

        if (cursor.moveToFirst()) {
            int bestMovesIndex = cursor.getColumnIndex(COL_BEST_MOVES);
            int bestTimeIndex = cursor.getColumnIndex(COL_BEST_TIME);
            int fastestMovesIndex = cursor.getColumnIndex(COL_FASTEST_MOVES);
            int fastestTimeIndex = cursor.getColumnIndex(COL_FASTEST_TIME);

            int bestMoves = (bestMovesIndex != -1) ? cursor.getInt(bestMovesIndex) : Integer.MAX_VALUE;
            long bestTime = (bestTimeIndex != -1) ? cursor.getLong(bestTimeIndex) : Long.MAX_VALUE;
            int fastestMoves = (fastestMovesIndex != -1) ? cursor.getInt(fastestMovesIndex) : Integer.MAX_VALUE;
            long fastestTime = (fastestTimeIndex != -1) ? cursor.getLong(fastestTimeIndex) : Long.MAX_VALUE;

            if (moves < bestMoves) {
                values.put(COL_BEST_MOVES, moves);
                values.put(COL_BEST_TIME, time);
                newRecord = true;
            }

            if (time < fastestTime) {
                values.put(COL_FASTEST_MOVES, moves);
                values.put(COL_FASTEST_TIME, time);
                newRecord = true;
            }

            if (newRecord) {
                db.update(PAIR_MATCHING_TABLE, values, COL_NICKNAME + "=?", new String[]{nickname});
            }
        } else {
            values.put(COL_NICKNAME, nickname);
            values.put(COL_BEST_MOVES, moves);
            values.put(COL_BEST_TIME, time);
            values.put(COL_FASTEST_MOVES, moves);
            values.put(COL_FASTEST_TIME, time);
            db.insert(PAIR_MATCHING_TABLE, null, values);
            newRecord = true;
        }

        cursor.close();
        return newRecord;
    }

    public Cursor getPairMatchingStats(String nickname) {
        SQLiteDatabase db = this.getReadableDatabase();
        return db.rawQuery("SELECT * FROM " + PAIR_MATCHING_TABLE + " WHERE " + COL_NICKNAME + "=?", new String[]{nickname});
    }
}



напиши все что я должен сделать для этого а также полные коды для каждого класса