import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:solitaire_game/entities/tile.dart'; import 'package:solitaire_game/utils/game_utils.dart'; class Data extends ChangeNotifier { // Configuration available values List _availableParameters = ['skin']; List _availableSkinValues = ['default']; List get availableParameters => _availableParameters; List get availableSkinValues => _availableSkinValues; // Application default configuration String _parameterSkin = ''; String _parameterSkinDefault = 'default'; // Application current configuration String get parameterSkin => _parameterSkin; // Game data bool _assetsPreloaded = false; bool _gameIsRunning = false; List<List<Tile?>> _board = []; int _boardSize = 0; double _tileSize = 0; int _movesCount = 0; int _remainingPegsCount = 0; String _currentState = ''; void updateParameterSkin(String parameterSkin) { _parameterSkin = parameterSkin; notifyListeners(); } String getParameterValue(String parameterCode) { switch (parameterCode) { case 'skin': return _parameterSkin; } return ''; } List getParameterAvailableValues(String parameterCode) { switch (parameterCode) { case 'skin': return _availableSkinValues; } return []; } void setParameterValue(String parameterCode, String parameterValue) async { switch (parameterCode) { case 'skin': updateParameterSkin(parameterValue); break; } final prefs = await SharedPreferences.getInstance(); prefs.setString(parameterCode, parameterValue); } void initParametersValues() async { final prefs = await SharedPreferences.getInstance(); setParameterValue('skin', prefs.getString('skin') ?? _parameterSkinDefault); } String get currentState => _currentState; String computeCurrentGameState() { String boardValues = ''; String textBoard = ' '; String textHole = 'ยท'; String textPeg = 'o'; for (var rowIndex = 0; rowIndex < _board.length; rowIndex++) { for (var colIndex = 0; colIndex < _board[rowIndex].length; colIndex++) { String cellValue = textBoard; if (_board[rowIndex][colIndex] != null) { cellValue = (_board[rowIndex][colIndex]?.hasPeg ?? false) ? textPeg : textHole; } boardValues += cellValue; } } var currentState = { 'skin': _parameterSkin, 'movesCount': _movesCount.toString(), 'boardValues': boardValues, }; return json.encode(currentState); } void saveCurrentGameState() async { if (_gameIsRunning) { _currentState = computeCurrentGameState(); final prefs = await SharedPreferences.getInstance(); prefs.setString('savedState', _currentState); } else { resetCurrentSavedState(); } } void resetCurrentSavedState() async { _currentState = ''; final prefs = await SharedPreferences.getInstance(); prefs.setString('savedState', _currentState); notifyListeners(); } void loadCurrentSavedState() async { final prefs = await SharedPreferences.getInstance(); _currentState = prefs.getString('savedState') ?? ''; } bool hasCurrentSavedState() { return (_currentState != ''); } Map<String, dynamic> getCurrentSavedState() { if (_currentState != '') { Map<String, dynamic> savedState = json.decode(_currentState); if (savedState.isNotEmpty) { return savedState; } } return {}; } bool get assetsPreloaded => _assetsPreloaded; void updateAssetsPreloaded(bool assetsPreloaded) { _assetsPreloaded = assetsPreloaded; } double get tileSize => _tileSize; void updateTileSize(double tileSize) { _tileSize = tileSize; } int get boardSize => _boardSize; void updateBoardSize(int boardSize) { _boardSize = boardSize; } List<List<Tile?>> get board => _board; void updateBoard(List<List<Tile?>> board) { _board = board; updateBoardSize(board.length); updateRemainingPegsCount(GameUtils.countRemainingPegs(this)); notifyListeners(); } updatePegValue(int row, int col, bool hasPeg) { if (_board[row][col] != null) { _board[row][col]?.hasPeg = hasPeg; saveCurrentGameState(); notifyListeners(); } } int get movesCount => _movesCount; void updateMovesCount(int movesCount) { _movesCount = movesCount; notifyListeners(); } void incrementMovesCount() { updateMovesCount(movesCount + 1); } int get remainingPegsCount => _remainingPegsCount; void updateRemainingPegsCount(int remainingPegsCount) { _remainingPegsCount = remainingPegsCount; notifyListeners(); } bool get gameIsRunning => _gameIsRunning; bool get isGameFinished => !_gameIsRunning; void updateGameIsRunning(bool gameIsRunning) { _gameIsRunning = gameIsRunning; notifyListeners(); } bool gameWon() { return isGameFinished; } void resetGame() { _gameIsRunning = false; _movesCount = 0; _remainingPegsCount = 0; notifyListeners(); } }