From 58302ff3a46f4396832fd99a3c4e8639de02a96c Mon Sep 17 00:00:00 2001
From: Michael Mutote <130656746+mr1Michael@users.noreply.github.com>
Date: Thu, 19 Oct 2023 22:09:18 +0200
Subject: [PATCH] 22202956 Queens problem, solved. Does not look pretty.
 Successor, is allowed and is goal completed. Breadth first function still not
 touched

---
 Breath-First Search/Sucessors.py        | 66 ++++++++++++++++++++-----
 Breath-First Search/is_goal.py          |  6 ++-
 Breath-First Search/solution testing.py | 25 +++++++++-
 3 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/Breath-First Search/Sucessors.py b/Breath-First Search/Sucessors.py
index 896543e..05a518c 100644
--- a/Breath-First Search/Sucessors.py	
+++ b/Breath-First Search/Sucessors.py	
@@ -8,28 +8,20 @@ def maze_successor(state):
 
 
 def sudoku_successor(state):
-    y, x = 10, 10
+    new_state = list(map(list, state))  # Convert state to a list of lists
+    y, x = -1, -1
     for i, s in enumerate(state):
         if 0 in s:
             (y, x) = (i, s.index(0))
             break
     next_states = []
-    for j in range(1, 10):
-        new_state = list(map(list, state))  # Convert state to a list of lists
+    for j in range(1, len(new_state) + 1):
         new_state[y][x] = j
         if sudoku_allowed((y, x, new_state)):
             next_states.append(tuple(map(tuple, new_state)))
     return next_states
 
 
-def puzzle_successor(state):
-    return []
-
-
-def queens_successor(state):
-    return []
-
-
 def maze_allowed(state):
     maze = [[' ', 'W', ' ', ' ', 'G'],
             [' ', 'W', ' ', 'W', ' '],
@@ -69,9 +61,57 @@ def sudoku_allowed(state):
     return True
 
 
-def queens_allowed(state):
-    return False
+def puzzle_successor(state):
+    return []
+
+
+def queens_successor(state):
+    new_state = list(map(list, state))  # Convert state to a list of lists
+    y = -1
+    for i in range(len(new_state)):
+        if sum(new_state[i]) == 0:
+            y = i
+            break
+    next_states = []
+    for j in range(len(new_state[0])):
+        new_state[y] = [False] * len(new_state[y])
+        new_state[y][j] = True
+        if queens_allowed((y, j, new_state)):
+            next_states.append(tuple(map(tuple, new_state)))
+    return next_states
 
 
 def puzzle_allowed(state):
     return False
+
+
+def queens_allowed(state):
+    """in this case the state is also y, x, grid"""
+    y, x, grid = state
+
+    # check if still inside the box
+    if y < 0 or y >= len(grid):
+        return False
+    if x < 0 or x >= len(grid[0]):
+        return False
+
+    # inspect columns and rows for queens
+    if (sum([row[x] for row in grid]) > 1) or (sum(grid[y]) > 1):
+        return False
+
+    # inspect diagonal
+    for i in range(1, len(grid)):
+
+        # positive diagonal
+        if x - i >= 0 and y - i >= 0 and grid[y - i][x - i]:
+            return False
+        if x + i < len(grid[0]) and y + i < len(grid) and grid[y + i][x + i]:
+            return False
+
+        # negative diagonal
+        if x - i >= 0 and y + i < len(grid) and grid[y + i][x - i]:
+            return False
+        if x + i < len(grid[0]) and y - i >= 0 and grid[y - i][x + i]:
+            return False
+
+    return True
diff --git a/Breath-First Search/is_goal.py b/Breath-First Search/is_goal.py
index 7afb23d..503cd74 100644
--- a/Breath-First Search/is_goal.py	
+++ b/Breath-First Search/is_goal.py	
@@ -11,8 +11,12 @@ def is_goal_sudoku(state):
         if 0 in s:
             (y, x) = (i, s.index(0))
             break
-    return ((y, x) == (10, 10))
+    return (y, x) == (10, 10)
 
 
+def is_goal_queens(state):
+    return sum(map(sum, state)) == len(state)
 
 
+def is_goal_puzzle(state):
+    pass
diff --git a/Breath-First Search/solution testing.py b/Breath-First Search/solution testing.py
index 27e7401..16cf8d2 100644
--- a/Breath-First Search/solution testing.py	
+++ b/Breath-First Search/solution testing.py	
@@ -2,9 +2,11 @@ import breadth_first_search
 import Sucessors
 import is_goal
 
-print(breadth_first_search.BreadthFirstSearch((4, 0), Sucessors.maze_successor, is_goal.is_goal_maze))
 
+# Maze Problem, note, the maze if fixed in the allowed state.
+print(breadth_first_search.BreadthFirstSearch((4, 0), Sucessors.maze_successor, is_goal.is_goal_maze))
 
+# Sudoku
 grid = ((5, 3, 0, 0, 7, 0, 0, 0, 0),
         (6, 0, 0, 1, 9, 5, 0, 0, 0),
         (0, 9, 8, 0, 0, 0, 0, 6, 0),
@@ -16,3 +18,24 @@ grid = ((5, 3, 0, 0, 7, 0, 0, 0, 0),
         (0, 0, 0, 0, 8, 0, 0, 0, 0))
 
 print(breadth_first_search.BreadthFirstSearch(grid, Sucessors.sudoku_successor, is_goal.is_goal_sudoku)[-1])
+
+
+# N Queens
+board = ((False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False),
+         (False, False, False, False, False, False, False, False, False))
+
+
+print(breadth_first_search.BreadthFirstSearch(board, Sucessors.queens_successor, is_goal.is_goal_queens)[-1])
+
+
+puzzle = ()
+
+
+print(breadth_first_search.BreadthFirstSearch(puzzle, Sucessors.puzzle_successor, is_goal.is_goal_puzzle)[-1])
-- 
GitLab