match_magic/lib/models/game_state.dart
2024-08-02 13:53:40 +03:00

164 lines
4.1 KiB
Dart

import 'dart:math';
import 'package:flutter/material.dart';
class GameState extends ChangeNotifier {
final int rows = 8;
final int cols = 8;
late List<List<int>> grid;
int? selectedRow;
int? selectedCol;
GameState() {
_initializeGrid();
}
void _initializeGrid() {
grid = List.generate(
rows, (i) => List.generate(cols, (j) => _randomElement()));
_removeInitialMatches();
}
int _randomElement() {
return Random().nextInt(6) + 1;
}
void _removeInitialMatches() {
bool hasMatches;
do {
hasMatches = false;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (_hasMatch(i, j)) {
grid[i][j] = _randomElement();
hasMatches = true;
}
}
}
} while (hasMatches);
}
void selectElement(int row, int col) {
if (selectedRow == null || selectedCol == null) {
selectedRow = row;
selectedCol = col;
} else {
if (_isAdjacent(selectedRow!, selectedCol!, row, col)) {
swapElements(selectedRow!, selectedCol!, row, col);
Future.delayed(const Duration(milliseconds: 300), () {
if (!_checkMatches()) {
swapElements(row, col, selectedRow!, selectedCol!);
}
selectedRow = null;
selectedCol = null;
notifyListeners();
});
} else {
selectedRow = row;
selectedCol = col;
}
}
notifyListeners();
}
bool _isAdjacent(int row1, int col1, int row2, int col2) {
return (row1 == row2 && (col1 - col2).abs() == 1) ||
(col1 == col2 && (row1 - row2).abs() == 1);
}
void swapElements(int row1, int col1, int row2, int col2) {
final temp = grid[row1][col1];
grid[row1][col1] = grid[row2][col2];
grid[row2][col2] = temp;
notifyListeners();
}
bool _checkMatches() {
final matches = <List<int>>[];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (_hasMatch(i, j)) {
matches.add([i, j]);
}
}
}
if (matches.isNotEmpty) {
for (final match in matches) {
_removeMatchedElements(match[0], match[1]);
}
_applyGravity();
Future.delayed(const Duration(milliseconds: 300), () {
_fillEmptySpaces();
_checkMatches();
});
return true;
}
return false;
}
bool _hasMatch(int row, int col) {
final value = grid[row][col];
if (value == 0) return false;
int count = 1;
for (int i = col + 1; i < cols && grid[row][i] == value; i++) count++;
for (int i = col - 1; i >= 0 && grid[row][i] == value; i--) count++;
if (count >= 3) return true;
count = 1;
for (int i = row + 1; i < rows && grid[i][col] == value; i++) count++;
for (int i = row - 1; i >= 0 && grid[i][col] == value; i--) count++;
return count >= 3;
}
void _removeMatchedElements(int row, int col) {
final value = grid[row][col];
int left = col;
while (left > 0 && grid[row][left - 1] == value) left--;
int right = col;
while (right < cols - 1 && grid[row][right + 1] == value) right++;
if (right - left + 1 >= 3) {
for (int i = left; i <= right; i++) {
grid[row][i] = 0;
}
}
int top = row;
while (top > 0 && grid[top - 1][col] == value) top--;
int bottom = row;
while (bottom < rows - 1 && grid[bottom + 1][col] == value) bottom++;
if (bottom - top + 1 >= 3) {
for (int i = top; i <= bottom; i++) {
grid[i][col] = 0;
}
}
}
void _applyGravity() {
for (int col = 0; col < cols; col++) {
int emptyRow = rows - 1;
for (int row = rows - 1; row >= 0; row--) {
if (grid[row][col] != 0) {
if (row != emptyRow) {
grid[emptyRow][col] = grid[row][col];
grid[row][col] = 0;
}
emptyRow--;
}
}
}
}
void _fillEmptySpaces() {
for (int col = 0; col < cols; col++) {
for (int row = rows - 1; row >= 0; row--) {
if (grid[row][col] == 0) {
grid[row][col] = _randomElement();
}
}
}
notifyListeners();
}
}