164 lines
4.1 KiB
Dart
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();
|
|
}
|
|
}
|