import 'package:flutter/material.dart'; import 'package:minehunter/provider/data.dart'; import 'package:minehunter/utils/board_animate.dart'; import 'package:minehunter/utils/board_utils.dart'; class Cell { bool isMined = false; bool isExplored = false; bool isMarked = false; bool isExploded = false; int minesCountAround = 0; bool isAnimated = false; Cell( this.isMined, ); /* * Build widget for board cell, with interactions */ Container widget(Data myProvider, int row, int col) { String imageAsset = getImageAssetName(myProvider); return Container( decoration: BoxDecoration( color: getBackgroundColor(myProvider), border: getCellBorders(myProvider, row, col), ), child: GestureDetector( child: AnimatedSwitcher( duration: const Duration(milliseconds: 100), transitionBuilder: (Widget child, Animation<double> animation) { return ScaleTransition(scale: animation, child: child); }, child: Image( image: AssetImage(imageAsset), fit: BoxFit.fill, key: ValueKey<int>(imageAsset.hashCode), ), ), onTap: () { // Set mines on board after first player try if (!myProvider.isBoardMined) { myProvider.updateCells(BoardUtils.createBoard(myProvider, row, col)); myProvider.updateIsBoardMined(true); } if (!(myProvider.gameWin || myProvider.gameFail)) { if (myProvider.reportMode) { BoardUtils.reportCell(myProvider, row, col); } else { BoardUtils.walkOnCell(myProvider, row, col); } if (BoardUtils.checkGameIsFinished(myProvider)) { myProvider.updateReportMode(false); BoardAnimate.startAnimation(myProvider, myProvider.gameWin ? 'win' : 'fail'); } } }, ), ); } /* * Compute image asset name, from skin and cell value/state */ String getImageAssetName(Data myProvider) { String imageAsset = 'assets/skins/${myProvider.parameterSkin}_tile_unknown.png'; bool showSolution = myProvider.gameWin || myProvider.gameFail; if (!showSolution) { // Running game if (isExplored) { if (isMined) { // Boom imageAsset = 'assets/skins/${myProvider.parameterSkin}_tile_mine.png'; } else { // Show mines count around imageAsset = 'assets/skins/${myProvider.parameterSkin}_tile_$minesCountAround.png'; } } else { if (isMarked) { // Danger! imageAsset = 'assets/skins/${myProvider.parameterSkin}_tile_flag.png'; } } } else { // Finished game if (isMined) { if (isExploded) { // Mine exploded imageAsset = 'assets/skins/${myProvider.parameterSkin}_tile_mine.png'; } else { // Mine not found imageAsset = 'assets/skins/${myProvider.parameterSkin}_tile_mine_not_found.png'; } } else { // Show all mines counts imageAsset = 'assets/skins/${myProvider.parameterSkin}_tile_$minesCountAround.png'; } } return imageAsset; } // Compute cell background color, from cell state Color getBackgroundColor(Data myProvider) { if (myProvider.gameWin) { return isAnimated ? Colors.green.shade400 : Colors.green.shade500; } if (myProvider.gameFail) { return isAnimated ? Colors.pink.shade200 : Colors.pink.shade400; } return isAnimated ? Colors.white : Colors.grey.shade200; } // Compute cell borders, from board size and cell state Border getCellBorders(Data myProvider, int row, int col) { Color cellBorderColor = Colors.grey.shade500; double cellBorderWidth = 4; // Reduce cell border width on big boards int boardSize = myProvider.sizeHorizontal; if (boardSize > 8) { cellBorderWidth = 2; if (boardSize > 10) { cellBorderWidth = 1; } } if (myProvider.gameWin) { cellBorderColor = Colors.green.shade700; } else if (myProvider.gameFail) { cellBorderColor = Colors.pink.shade300; } Border borders = Border.all( color: cellBorderColor, width: cellBorderWidth, ); return borders; } }