+
+
+
+
+
+
@@ -298,7 +368,42 @@
<<<<<<< HEAD
+<<<<<<< HEAD
+=======
=======
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>>>>>>> release/workingfinal
@@ -315,26 +420,33 @@
+<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> release/working-2
+=======
+
+>>>>>>> release/workingfinal
+<<<<<<< HEAD
<<<<<<< HEAD
=======
+=======
+>>>>>>> release/workingfinal
>>>>>>> release/working-2
-
+
<<<<<<< HEAD
@@ -343,7 +455,11 @@
=======
+<<<<<<< HEAD
>>>>>>> release/working-2
+=======
+
+>>>>>>> release/workingfinal
@@ -351,8 +467,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<<<<<<< HEAD
<<<<<<< HEAD
@@ -367,11 +509,19 @@
>>>>>>> release/working-2
+=======
+
+
+
+
+
+>>>>>>> release/workingfinal
-
+
+<<<<<<< HEAD
<<<<<<< HEAD
=======
@@ -385,38 +535,61 @@
=======
+=======
+
+
+
+
-
+
-
-
+
+
-
+
+>>>>>>> release/workingfinal
-
+
-
-
+
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
diff --git a/eight_queens/android/.gradle/5.6.2/executionHistory/executionHistory.bin b/eight_queens/android/.gradle/5.6.2/executionHistory/executionHistory.bin
new file mode 100644
index 0000000..f242c9a
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/executionHistory/executionHistory.bin differ
diff --git a/eight_queens/android/.gradle/5.6.2/executionHistory/executionHistory.lock b/eight_queens/android/.gradle/5.6.2/executionHistory/executionHistory.lock
new file mode 100644
index 0000000..1239417
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/executionHistory/executionHistory.lock differ
diff --git a/eight_queens/android/.gradle/5.6.2/fileChanges/last-build.bin b/eight_queens/android/.gradle/5.6.2/fileChanges/last-build.bin
new file mode 100644
index 0000000..f76dd23
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/fileChanges/last-build.bin differ
diff --git a/eight_queens/android/.gradle/5.6.2/fileContent/fileContent.lock b/eight_queens/android/.gradle/5.6.2/fileContent/fileContent.lock
new file mode 100644
index 0000000..9027b10
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/fileContent/fileContent.lock differ
diff --git a/eight_queens/android/.gradle/5.6.2/fileHashes/fileHashes.bin b/eight_queens/android/.gradle/5.6.2/fileHashes/fileHashes.bin
new file mode 100644
index 0000000..88e885e
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/fileHashes/fileHashes.bin differ
diff --git a/eight_queens/android/.gradle/5.6.2/fileHashes/fileHashes.lock b/eight_queens/android/.gradle/5.6.2/fileHashes/fileHashes.lock
new file mode 100644
index 0000000..d1d42f1
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/fileHashes/fileHashes.lock differ
diff --git a/eight_queens/android/.gradle/5.6.2/fileHashes/resourceHashesCache.bin b/eight_queens/android/.gradle/5.6.2/fileHashes/resourceHashesCache.bin
new file mode 100644
index 0000000..920f983
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/fileHashes/resourceHashesCache.bin differ
diff --git a/eight_queens/android/.gradle/5.6.2/gc.properties b/eight_queens/android/.gradle/5.6.2/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/eight_queens/android/.gradle/5.6.2/javaCompile/classAnalysis.bin b/eight_queens/android/.gradle/5.6.2/javaCompile/classAnalysis.bin
new file mode 100644
index 0000000..5e3f79b
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/javaCompile/classAnalysis.bin differ
diff --git a/eight_queens/android/.gradle/5.6.2/javaCompile/jarAnalysis.bin b/eight_queens/android/.gradle/5.6.2/javaCompile/jarAnalysis.bin
new file mode 100644
index 0000000..5e038a5
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/javaCompile/jarAnalysis.bin differ
diff --git a/eight_queens/android/.gradle/5.6.2/javaCompile/javaCompile.lock b/eight_queens/android/.gradle/5.6.2/javaCompile/javaCompile.lock
new file mode 100644
index 0000000..71229f7
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/javaCompile/javaCompile.lock differ
diff --git a/eight_queens/android/.gradle/5.6.2/javaCompile/taskHistory.bin b/eight_queens/android/.gradle/5.6.2/javaCompile/taskHistory.bin
new file mode 100644
index 0000000..71b0e21
Binary files /dev/null and b/eight_queens/android/.gradle/5.6.2/javaCompile/taskHistory.bin differ
diff --git a/eight_queens/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/eight_queens/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644
index 0000000..5b37d31
Binary files /dev/null and b/eight_queens/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/eight_queens/android/.gradle/buildOutputCleanup/cache.properties b/eight_queens/android/.gradle/buildOutputCleanup/cache.properties
new file mode 100644
index 0000000..0bd5037
--- /dev/null
+++ b/eight_queens/android/.gradle/buildOutputCleanup/cache.properties
@@ -0,0 +1,2 @@
+#Mon Feb 17 15:14:25 CST 2020
+gradle.version=5.6.2
diff --git a/eight_queens/android/.gradle/buildOutputCleanup/outputFiles.bin b/eight_queens/android/.gradle/buildOutputCleanup/outputFiles.bin
new file mode 100644
index 0000000..95fee05
Binary files /dev/null and b/eight_queens/android/.gradle/buildOutputCleanup/outputFiles.bin differ
diff --git a/eight_queens/android/.gradle/vcs-1/gc.properties b/eight_queens/android/.gradle/vcs-1/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/eight_queens/android/gradle/wrapper/gradle-wrapper.jar b/eight_queens/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/eight_queens/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/eight_queens/android/gradlew b/eight_queens/android/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/eight_queens/android/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/eight_queens/android/gradlew.bat b/eight_queens/android/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/eight_queens/android/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/lib/main.dart b/lib/main.dart
index d23f862..0573db0 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -2,7 +2,7 @@ import 'package:eight_queens/queens.dart';
import 'package:eight_queens/results.dart';
import 'package:flutter/material.dart';
import 'package:progress_dialog/progress_dialog.dart';
-
+import 'package:validators/validators.dart';
void main() => runApp(MyApp());
@@ -40,6 +40,7 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State {
int _boardSize = 0;
ProgressDialog pr;
+ bool shouldCheck;
// Create a controller to retrieve data from the TextField
final boardController = TextEditingController();
@@ -51,11 +52,54 @@ class _MyHomePageState extends State {
super.dispose();
}
- /**
- * Retrieve the board number and pass it to the eight queens controller
- * TODO: Create the Responsible class in Dart
- */
+ ///
+ /// Creates a simple Dialog to show a message
+ /// Receives a [String] title and a [String] message to display a [AlertDialog]
+ ///
+ void _showDialogBuilder(String title, String message) {
+ showDialog(context: context,builder: (BuildContext context){
+ return AlertDialog(
+ title: new Text(title),
+ content: new Text(message),
+ actions: [
+ new FlatButton(
+ child: new Text("close"), onPressed: () {
+ setState(() {
+ _boardSize = 0;
+ });
+ Navigator.of(context).pop();
+ })
+ ],
+ );
+ });
+ }
+
+ @override
+ void initState() {
+ // TODO: implement initState
+ setState(() {
+ shouldCheck = true;
+ });
+ super.initState();
+ }
+
+ ///
+ /// This method retrieves the [boardController.text] and checks if [isNumeric] and [boardController.text.isEmpty].
+ /// Then, it shows a [ProgressDialog] element while [QueenResolver] is executed.
+ /// Once a [count] is retrieved, we [Navigator.push] to [ResultsPage]
+ ///
void _startProcessing() async {
+
+ if(boardController.text.isEmpty){
+ _showDialogBuilder("Empty Textfield", "Please enter a value into the text field");
+ return;
+ }
+
+ if(boardController.text.isNotEmpty && !isNumeric(boardController.text)) {
+ _showDialogBuilder("Non numeric", "Please enter a numeric value into the text field");
+ return;
+ }
+
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
diff --git a/lib/queens.dart b/lib/queens.dart
index c4ecb15..682f8e8 100644
--- a/lib/queens.dart
+++ b/lib/queens.dart
@@ -1,7 +1,8 @@
-/**
- * Queen Resolver class
- * Solved using algorithm found in: https://www.geeksforgeeks.org/n-queen-problem-using-branch-and-bound/
- */
+///
+///Queen Resolver class
+///Solved using algorithm found in: https://www.geeksforgeeks.org/n-queen-problem-backtracking-3/
+///Adapted for use with Dart and Flutter
+///
import 'package:shared_preferences/shared_preferences.dart';
@@ -9,7 +10,11 @@ class QueenResolver {
int count = 0;
- Future _isSafe(board, int row, int col, int n) async {
+ ///
+ /// Checks if a queen can be placed on a [board] in a [row] and [col]
+ /// Returns a [bool] if it's safe to place it [true] or not [false]
+ ///
+ Future isSafe(board, int row, int col, int n) async {
// Check row on the left side
for (var i = 0; i < col; i++) {
if(board[row][i] == 1 && board[row][i] != null) {
@@ -40,27 +45,38 @@ class QueenResolver {
return true;
}
- Future _solveQueens(board, int col, int n) async {
+ ///
+ /// Main eight queens algorithm
+ /// Receives a single [board] and [col] positions, as well as [n] queens.
+ /// Will return [true] when solved.
+ ///
+ Future solveQueens(board, int col, int n) async {
+ /* Solve for the base case : All queens are placed
+ * Then, store it into local storage */
if (col >= n) {
count++;
- _storeSolution(board).then((value) {
+ storeSolution(board).then((value) {
return true;
});
}
var res = false;
+ /** Consider the [col] and try placing it on the [board] **/
for(int i = 0; i < n; i++) {
- if(await _isSafe(board, i, col, n)){
+ if(await isSafe(board, i, col, n)){
board[i][col] = 1;
- res = await _solveQueens(board, col + 1, n);
+ res = await solveQueens(board, col + 1, n);
board[i][col] = 0;
}
}
return res;
}
-
- Future _storeSolution(List> board) async {
+
+ /// Stores a complete [board] into [SharedPreferences]
+ /// Because the [board] is not completely initialized, it requires to convert all [null] values to [0].
+ /// Stores also the current [count] into [SharedPreferences]
+ Future storeSolution(List> board) async {
for(int i = 0; i < board.length; i++) {
for(int x = 0; x < board[i].length ; x++) {
if(board[i][x] == null) {
@@ -73,11 +89,15 @@ class QueenResolver {
await prefs.setInt('count', count);
}
+ ///
+ /// Function entryway to solve for [n] queens.
+ /// Will return [count] for the app's purposes
+ ///
Future solve(int n) async {
// Create the initial queens board
List> board = new List.generate(n, (_) => new List(n));
- if(await _solveQueens(board,0,n) == false) {
+ if(await solveQueens(board,0,n) == false) {
return count;
}
return count;
diff --git a/lib/results.dart b/lib/results.dart
index 2b606f0..23e0843 100644
--- a/lib/results.dart
+++ b/lib/results.dart
@@ -1,4 +1,5 @@
+import 'package:eight_queens/queens.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
@@ -15,6 +16,11 @@ class ResultsPage extends StatefulWidget {
class _ResultsPageState extends State {
var boards = new List();
+ ///
+ /// Retrieves the [QueenResolver] [boards] that were calculated.
+ /// Will call [SharedPreferences] and get [String] for every posible solution.
+ /// Will then append it to [boards] and [setState()]
+ ///
Future retrieveEightQueensResults() async {
final prefs = await SharedPreferences.getInstance();
var _boards = new List();
@@ -36,7 +42,11 @@ class _ResultsPageState extends State {
super.initState();
});
}
-
+
+ ///
+ /// Simple Item builder to display a [board]
+ /// Uses [String] concatenation to make it work
+ ///
Widget ResultItem(BuildContext context, int index) {
String todisplay = "";
for(int x = 0; x < boards[index].length; x++ ){
diff --git a/pubspec.yaml b/pubspec.yaml
index 216c2f7..0366a86 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -20,6 +20,7 @@ dependencies:
flutter:
sdk: flutter
shared_preferences : ^0.5.6
+ validators: ^2.0.0
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
diff --git a/test/eight_test.dart b/test/eight_test.dart
new file mode 100644
index 0000000..c95f830
--- /dev/null
+++ b/test/eight_test.dart
@@ -0,0 +1,66 @@
+import 'package:eight_queens/queens.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+
+void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+
+ group('Eight Queens algorithm', () {
+
+ test('count should be 2 on a 4 piece chessboard', () {
+ Future future = QueenResolver().solve(4);
+ expect(future,completion(equals(2)));
+ });
+
+ test('count should be 92 on a 8 piece chessboard', () {
+ Future future = QueenResolver().solve(8);
+ expect(future,completion(equals(92)));
+ });
+
+ test('placing a queen on the same place as another is not a safe move', () {
+ List> board = [[1,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0]];
+ Future future = QueenResolver().isSafe(board, 0, 0, 4);
+ expect(future,completion(equals(false)));
+ });
+
+ test('placing a queen on an empty place is a safe move', () {
+ List> board = [[0,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0]];
+ Future future = QueenResolver().isSafe(board, 0, 0, 4);
+ expect(future,completion(equals(true)));
+ });
+
+ test('placing a queen right next to another is not a safe move', () {
+ List> board = [[1,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0]];
+ Future future = QueenResolver().isSafe(board, 0, 1, 4);
+ expect(future,completion(equals(false)));
+ });
+
+ test('placing a queen in direct diagonal to another is not a safe move', () {
+ List> board = [[1,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0],
+ [0,0,0,0]];
+ Future future = QueenResolver().isSafe(board, 1, 1, 4);
+ expect(future,completion(equals(false)));
+ });
+
+ test('passing a complete board to the solver method returns false', () {
+ List> board = [[0,0,1,0],
+ [1,0,0,0],
+ [0,0,0,1],
+ [0,1,0,0]];
+ Future future = QueenResolver().solveQueens(board, 4, 4);
+ expect(future,completion(equals(false)));
+ });
+
+ });
+}
\ No newline at end of file
diff --git a/test/widget_test.dart b/test/widget_test.dart
index b58f346..ff352f5 100644
--- a/test/widget_test.dart
+++ b/test/widget_test.dart
@@ -5,26 +5,75 @@
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
+import 'package:eight_queens/results.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:eight_queens/main.dart';
void main() {
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
- // Build our app and trigger a frame.
- await tester.pumpWidget(MyApp());
+ group('Main Application tests', () {
+ testWidgets('My App has a title', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(MyApp());
- // Verify that our counter starts at 0.
- expect(find.text('0'), findsOneWidget);
- expect(find.text('1'), findsNothing);
+ // Find the title
+ expect(find.text('Eight Queens App'), findsOneWidget);
+ });
+
+ testWidgets('My App has the desired message', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(MyApp());
+
+ // Find the title
+ expect(find.text('Select a board size'), findsOneWidget);
+ });
+
+ testWidgets('My App has an usable textfield', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(MyApp());
+
+ // Enter a number into the textfield
+ await tester.enterText(find.byType(TextField), '8');
+
+ //Expect it was stored correctly
+ expect(find.text('8'),findsWidgets);
+ });
+
+ testWidgets('App pushes a new view with results', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(MyApp());
+
+ // Enter a number into the textfield
+ await tester.enterText(find.byType(TextField), '8');
+
+ //Tap the button to go to the next screen
+ await tester.tap(find.byIcon(Icons.done));
+
+ // Wait for it to be shown
+ await tester.pumpAndSettle();
+
+ //Expect the new page to be shown
+ expect(find.byType(ResultsPage),findsOneWidget);
+ });
+
+ testWidgets('App with invalid input wont show results widget', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(MyApp());
+
+ // Enter a number into the textfield
+ await tester.enterText(find.byType(TextField), '0');
+
+ //Tap the button to go to the next screen
+ await tester.tap(find.byIcon(Icons.done));
+
+ // Wait for it to be shown
+ await tester.pumpAndSettle();
+
+ //Expect the new page to be shown
+ expect(find.byType(ResultsPage),findsNothing);
+ });
- // Tap the '+' icon and trigger a frame.
- await tester.tap(find.byIcon(Icons.add));
- await tester.pump();
- // Verify that our counter has incremented.
- expect(find.text('0'), findsNothing);
- expect(find.text('1'), findsOneWidget);
});
}