diff --git a/lib/main.dart b/lib/main.dart index 90d182f..a17fe95 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,7 +14,7 @@ class MastermindApp extends StatelessWidget { return MaterialApp( theme: ThemeData.dark(), debugShowCheckedModeBanner: false, - home: StartScreen(), + home: const StartScreen(), ); } } diff --git a/lib/screens/game_screen.dart b/lib/screens/game_screen.dart index 9d7919f..11a74d5 100644 --- a/lib/screens/game_screen.dart +++ b/lib/screens/game_screen.dart @@ -153,11 +153,11 @@ class MastermindGameState extends State { mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Text( + const Text( "Correct Solution:", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600), ), - SizedBox( + const SizedBox( height: 10, ), Row( @@ -170,7 +170,7 @@ class MastermindGameState extends State { size: 40, color: color, ), - SizedBox( + const SizedBox( width: 5, ) ], @@ -231,15 +231,18 @@ class MastermindGameState extends State { number = type ? guessed[row][0] : guessed[row][1]; } - return Text( - "$number", - style: TextStyle( - fontSize: 22, - color: currentGuess - 1 >= row - ? type - ? Colors.red - : Colors.white - : Colors.transparent), + return Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + "$number", + style: TextStyle( + fontSize: 22, + color: currentGuess - 1 >= row + ? type + ? Colors.red + : Colors.white + : Colors.transparent), + ), ); } @@ -248,78 +251,103 @@ class MastermindGameState extends State { if (guesses[row][column] != Colors.grey && row == currentGuess) { draggable = true; } - return DragTarget( - builder: (context, candidateData, rejectedData) { - return GestureDetector( - child: Draggable( - maxSimultaneousDrags: draggable ? null : 0, - data: guesses[row][column], - feedback: ColorOption( - selected: false, - color: guesses[row][column], - onTap: () {}, - ), - childWhenDragging: Container( - width: 40, - height: 40, - margin: const EdgeInsets.all(4), - decoration: BoxDecoration( - color: Colors.grey, - shape: BoxShape.circle, - ), - ), - child: Container( - width: 40, - height: 40, - margin: const EdgeInsets.all(4), - decoration: BoxDecoration( + return Padding( + padding: const EdgeInsets.only(left: 6.0, right: 6.0), + child: DragTarget( + builder: (context, candidateData, rejectedData) { + return GestureDetector( + child: Draggable( + maxSimultaneousDrags: draggable ? null : 0, + data: { + "color": guesses[row][column], + "row": row, + "column": column + }, + feedback: ColorOption( + selected: false, color: guesses[row][column], - shape: BoxShape.circle, + onTap: () {}, + ), + childWhenDragging: Container( + width: 40, + height: 40, + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: + widget.uniqueColors ? Colors.grey : guesses[row][column], + shape: BoxShape.circle, + ), + ), + ignoringFeedbackSemantics: true, + ignoringFeedbackPointer: true, + child: Container( + width: 40, + height: 40, + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: guesses[row][column], + shape: BoxShape.circle, + ), ), ), - ignoringFeedbackSemantics: true, - ignoringFeedbackPointer: true, - ), - onTap: () async { - setState(() { - if (_selectedColor != null) { - if (row == currentGuess) { - if (widget.uniqueColors && - guesses[row].contains(_selectedColor)) { - int idx = guesses[row].indexOf(_selectedColor!); - guesses[row][idx] = Colors.grey; - } + onTap: () async { + setState(() { + if (_selectedColor != null) { + if (row == currentGuess) { + if (widget.uniqueColors && + guesses[row].contains(_selectedColor)) { + int idx = guesses[row].indexOf(_selectedColor!); + guesses[row][idx] = Colors.grey; + } - guesses[row][column] = _selectedColor!; + guesses[row][column] = _selectedColor!; + } + if (widget.uniqueColors) { + _selectedColor = null; + } + } else { + if (row == currentGuess) { + guesses[row][column] = Colors.grey; + } } - _selectedColor = null; - } else { - if (row == currentGuess) { - guesses[row][column] = Colors.grey; + }); + }, + onLongPress: () { + if (row == currentGuess) { + setState(() { + _selectedColor = guesses[row][column]; + }); + } + }, + ); + }, + onAcceptWithDetails: (details) { + setState(() { + if (row == currentGuess) { + if (details.data["row"] != null) { + Color oldColor = guesses[row][column]; + if (oldColor != Colors.grey) { + guesses[details.data["row"]][details.data["column"]] = + oldColor; } } - }); - }, - ); - }, - onAcceptWithDetails: (details) { - setState(() { - if (row == currentGuess) { - if (widget.uniqueColors && guesses[row].contains(details.data)) { - int idx = guesses[row].indexOf(details.data); - guesses[row][idx] = Colors.grey; - } + if (widget.uniqueColors && + guesses[row].contains(details.data["color"])) { + int idx = guesses[row].indexOf(details.data["color"]); + guesses[row][idx] = Colors.grey; + } - guesses[row][column] = details.data; - } - }); - }, + guesses[row][column] = details.data["color"]; + } + }); + }, + ), ); } Widget buildRow(int row) { return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.center, children: [ buildTexts(row, false), for (int i = 0; i < rowSize; i++) buildColorButton(row, i), @@ -345,8 +373,8 @@ class MastermindGameState extends State { } Widget _buildDraggableColorOption(Color color) { - return Draggable( - data: color, + return Draggable( + data: {"color": color}, feedback: ColorOption( selected: false, color: color, @@ -380,22 +408,6 @@ class MastermindGameState extends State { centerTitle: true, title: const Text('Mastermind'), actions: [ - IconButton( - tooltip: "Clear Row", - onPressed: () { - setState(() { - for (int i = 0; i <= 4; i++) { - guesses[currentGuess][i] = Colors.grey; - } - }); - }, - icon: const Icon( - Icons.clear, - size: 30, - )), - const SizedBox( - width: 5, - ), IconButton( tooltip: "Restart Game", onPressed: () async { @@ -448,8 +460,10 @@ class MastermindGameState extends State { height: 10, ), if (!finished && multiplayerSelectionDone) - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + Wrap( + spacing: 15, + runSpacing: 15, + alignment: WrapAlignment.spaceAround, children: [ ElevatedButton.icon( onPressed: () { @@ -473,6 +487,39 @@ class MastermindGameState extends State { label: const Text("Random Colors"), icon: const Icon(Icons.shuffle), ), + ElevatedButton.icon( + onPressed: () { + if (currentGuess >= 1) { + setState(() { + guesses[currentGuess] = + List.from(guesses[currentGuess - 1]); + }); + } + }, + label: const Text( + "Copy Last Row", + ), + icon: const Icon( + Icons.copy, + ), + ), + ElevatedButton.icon( + onPressed: () { + setState(() { + for (int i = 0; i < rowSize; i++) { + guesses[currentGuess][i] = Colors.grey; + } + }); + }, + label: const Text( + "Clear Row", + style: TextStyle(color: Colors.red), + ), + icon: const Icon( + Icons.clear, + color: Colors.red, + ), + ), ElevatedButton.icon( onPressed: () { if (guesses[currentGuess].contains(Colors.grey)) { diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 0d5cde7..30bf888 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -72,6 +72,26 @@ class SettingsScreenState extends State { title: const Text('Game Settings'), centerTitle: true, ), + floatingActionButton: FloatingActionButton.extended( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MastermindGame( + trys: trys.toInt(), + rowSize: rowSize.toInt(), + colorCount: colors.toInt(), + countTogether: countTogether, + uniqueColors: uniqueColors, + isSinglePlayer: widget.isSinglePlayer)), + ); + }, + label: const Text( + "Start", + ), + icon: const Icon( + Icons.check, + )), body: Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( @@ -158,24 +178,6 @@ class SettingsScreenState extends State { }, ), ), - Center( - child: ElevatedButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => MastermindGame( - trys: trys.toInt(), - rowSize: rowSize.toInt(), - colorCount: colors.toInt(), - countTogether: countTogether, - uniqueColors: uniqueColors, - isSinglePlayer: widget.isSinglePlayer)), - ); - }, - child: const Text('Start Game'), - ), - ), ], ), ), diff --git a/lib/screens/start_screen.dart b/lib/screens/start_screen.dart index 1357ead..80e5965 100644 --- a/lib/screens/start_screen.dart +++ b/lib/screens/start_screen.dart @@ -3,9 +3,11 @@ import 'package:flutter/material.dart'; import '../components/game_mode_button.dart'; class StartScreen extends StatelessWidget { + const StartScreen({super.key}); + @override Widget build(BuildContext context) { - return Scaffold( + return const Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center,