import 'package:flutter/material.dart'; import 'package:aesthetica_wallpaper/models/puzzle_game_interface.dart'; /// 拖拽式拼图块数据模型 class DragPuzzlePiece { final int id; // 唯一标识 final int correctRow; // 正确的行位置 final int correctCol; // 正确的列位置 final ImageProvider image; // 图片块 bool isPlaced; // 是否已放置到正确位置 int? currentRow; // 当前行位置(如果已放置) int? currentCol; // 当前列位置(如果已放置) DragPuzzlePiece({ required this.id, required this.correctRow, required this.correctCol, required this.image, this.isPlaced = false, this.currentRow, this.currentCol, }); bool get isCorrectlyPlaced => isPlaced && currentRow == correctRow && currentCol == correctCol; DragPuzzlePiece copyWith({ int? id, int? correctRow, int? correctCol, ImageProvider? image, bool? isPlaced, int? currentRow, int? currentCol, }) { return DragPuzzlePiece( id: id ?? this.id, correctRow: correctRow ?? this.correctRow, correctCol: correctCol ?? this.correctCol, image: image ?? this.image, isPlaced: isPlaced ?? this.isPlaced, currentRow: currentRow ?? this.currentRow, currentCol: currentCol ?? this.currentCol, ); } } /// 拖拽式拼图游戏状态 class DragPuzzleGame implements IPuzzleGame { final List pieces; // 所有拼图块 final int gridRows; // 网格行数 final int gridCols; // 网格列数 final Duration elapsedTime; // 已用时间 final int moves; // 移动次数 final bool isComplete; // 是否完成 final String imagePath; // 原图路径 DragPuzzleGame({ required this.pieces, required this.gridRows, required this.gridCols, this.elapsedTime = Duration.zero, this.moves = 0, this.isComplete = false, required this.imagePath, }); /// 获取未放置的拼图块 List get unplacedPieces => pieces.where((piece) => !piece.isPlaced).toList(); /// 获取已放置的拼图块 List get placedPieces => pieces.where((piece) => piece.isPlaced).toList(); /// 检查游戏是否完成 bool checkComplete() { return pieces.every((piece) => piece.isCorrectlyPlaced); } /// 获取指定位置的拼图块 DragPuzzlePiece? getPieceAt(int row, int col) { try { return pieces.firstWhere( (piece) => piece.isPlaced && piece.currentRow == row && piece.currentCol == col, ); } catch (e) { return null; } } @override String get difficultyLabel { return '${gridRows}x$gridCols'; } /// 获取星级评分 @override int getStarRating() { if (!isComplete) return 0; final totalPieces = gridRows * gridCols; final optimalMoves = totalPieces; // 理想情况下每个块只移动一次 final optimalTime = Duration(minutes: totalPieces ~/ 4); // 理想时间 int stars = 1; if (moves <= optimalMoves && elapsedTime <= optimalTime) { stars = 3; } else if (moves <= optimalMoves * 1.5 || elapsedTime <= optimalTime * 1.5) { stars = 2; } return stars; } DragPuzzleGame copyWith({ List? pieces, int? gridRows, int? gridCols, Duration? elapsedTime, int? moves, bool? isComplete, String? imagePath, }) { return DragPuzzleGame( pieces: pieces ?? this.pieces, gridRows: gridRows ?? this.gridRows, gridCols: gridCols ?? this.gridCols, elapsedTime: elapsedTime ?? this.elapsedTime, moves: moves ?? this.moves, isComplete: isComplete ?? this.isComplete, imagePath: imagePath ?? this.imagePath, ); } } /// 拖拽式拼图难度 enum DragPuzzleDifficulty { beginner(2, 2, 'Beginner', '2x2'), easy(3, 2, 'Easy', '3x2'), medium(4, 3, 'Medium', '4x3'), hard(5, 4, 'Hard', '5x4'), expert(6, 5, 'Expert', '6x5'); final int rows; final int cols; final String label; final String description; const DragPuzzleDifficulty( this.rows, this.cols, this.label, this.description, ); int get totalPieces => rows * cols; }