Skip to content

Commit

Permalink
Merge pull request #37 from JohnMurwin/release/v0.2.0
Browse files Browse the repository at this point in the history
Release v0.2.0
  • Loading branch information
JohnMurwin authored Nov 21, 2021
2 parents cc25bc1 + cb17e9a commit 5a6ac1c
Show file tree
Hide file tree
Showing 17 changed files with 386 additions and 59 deletions.
8 changes: 8 additions & 0 deletions NQueensSimulation/Assets/NQueensSimulation/Prefabs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

108 changes: 108 additions & 0 deletions NQueensSimulation/Assets/NQueensSimulation/Scripts/Board.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System.Text;

namespace NQueensSimulation
{
public class Board
{
#region Fields
//* Public Variables

//* Protected Variables

//* Private Variables
private int [,] board;

#endregion

//? ALL Public methods go here
#region PublicMethods

/// <summary>
/// Constructs an empty, square 2D integer array based off size input
/// </summary>
/// <param name="squareSize">the number of columns and rows this 'board' should have</param>
public void ConstructBoard (int squareSize)
{
board = new int[squareSize, squareSize];

for (int i = 0; i < squareSize; i++)
{
for (int j = 0; j < squareSize ; j++)
{
board[i,j] = 0;
}
}
}

/// <summary>
/// Returns the integer value of any particular position in the 2D array
/// </summary>
/// <param name="row">Row # of the desired position</param>
/// <param name="col">Column # of the desired position</param>
/// <returns></returns>
public int ReturnPositionValue(int row, int col)
{
return board[row,col];
}

/// <summary>
/// Sets an integer value at any particular position in the 2D array
/// </summary>
/// <param name="desiredValue">The value to set in the position the board</param>
/// <param name="row">Row # of the desired position</param>
/// <param name="col">Column # of the desired position</param>
public void SetPositionValue (int desiredValue, int row, int col)
{
board[row, col] = desiredValue;
}

/// <summary>
/// Uses the number of rows to find length
/// </summary>
/// <returns>int value of row length</returns>
public int ReturnRowLength ()
{
return board.GetLength(0);
}

/// <summary>
/// Uses the number of columns to find length
/// </summary>
/// <returns>int value of column length</returns>
public int ReturnColumnLength ()
{
return board.GetLength(1);
}

/// <summary>
/// Prints the board state as a single string using StringBuilder
/// </summary>
/// <returns>string value of board</returns>
//ToDo: might want to remove this and make it either an extension method, or a static external method
public string PrintBoard()
{
StringBuilder boardOutput = new StringBuilder(); //make string builder

for (int i = 0; i < board.GetLength(1); i++)
{
for (int j = 0; j < board.GetLength(0) ; j++)
{
boardOutput.Append(board[i, j]); //store value at point [i,j]
boardOutput.Append(" "); //give space for formatting
}

boardOutput.AppendLine(); //new line for new row
}

return boardOutput.ToString(); //output
}

#endregion

//! All Private methods go here
#region PrivateMethods


#endregion
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

109 changes: 109 additions & 0 deletions NQueensSimulation/Assets/NQueensSimulation/Scripts/NQueensSolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using UnityEngine;

namespace NQueensSimulation
{
/// <summary>
/// The NQueens Algorithm Solver Component
/// </summary>
// ToDo: extract out this class to remove MonoBehaviour dependency
public class NQueensSolver : MonoBehaviour
{
#region Fields
//* Public Variables


//* Protected Variables
protected Board queensBoard = new Board();

//* Private Variables
[SerializeField]
[Tooltip("Determines the starting number of Queens (and by extension the size of the board)")]
private int numberOfQueens = 4;


#endregion


//* Any UNITY methods go here
#region LifeCycle
private void Start() {

Debug.Log("Starting number of queens: " + numberOfQueens);

queensBoard.ConstructBoard(numberOfQueens);

Debug.Log("Starting Board: " + '\n' + queensBoard.PrintBoard());


Solve();
}

#endregion

//? ALL Public methods go here
#region PublicMethods

/// <summary>
/// Solves the NQueens Algorithm based off the input value: numberOfQueens
/// </summary>
/// <returns>void</returns>
public void Solve()
{
if (FindSolution(queensBoard, 0))
Debug.Log("Could not find a solution... Either it doesnt exit, or something went wrong.");

Debug.Log("Solved NQueens board for size: " + numberOfQueens + '\n' + queensBoard.PrintBoard());
}

#endregion

//! All Private methods go here
#region PrivateMethods
private bool FindSolution (Board board, int col)
{
if (col >= numberOfQueens) // our base case for when/if all Queens are placed on board
return true;

for (int i = 0; i < numberOfQueens; i++) // start with current column and place Queen in row after row
{
if (CheckSafePlace(board, i, col)) // CheckSafePlace to see if we can place Queen here
{
board.SetPositionValue(1, i, col); // set space to 1 for successful Queen location

if (FindSolution(board, col + 1)) // recursive call to place the rest of the Queens
return true;
}

board.SetPositionValue(0, i, col); // else we backtrack and set that spot to 0 and move onto next row [BACKTRACING]
}

return false; //Queen cannot be placed, so we return false
}

//* Note: since we are only placing from the left, we only need to check left spots, we assume right spots will always be open
private bool CheckSafePlace (Board board, int rowLoc, int colLoc)
{
int i, j; // temp row/column values

// check direct-left of current spot
for (i = 0; i < colLoc; i++)
if (board.ReturnPositionValue(rowLoc, i) == 1)
return false;

// check upper-left of current spot
for (i = rowLoc, j = colLoc; i >=0 && j >= 0; i--,j--)
if (board.ReturnPositionValue(i,j) == 1)
return false;

// check lower-left of current spot
for (i = rowLoc, j = colLoc; j >=0 && i < numberOfQueens; i++, j--)
if (board.ReturnPositionValue(i,j) == 1)
return false;

return true; //if none of the above checks fired, then its a safe spot to place Queen
}


#endregion
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 64 additions & 0 deletions NQueensSimulation/Assets/Tests/EditMode/ET_Board.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

using NUnit.Framework;
using NQueensSimulation;

namespace Tests
{
public class ET_Board
{
int defaultSize = 4;
Board testBoard = new Board();

[Test]
public void NewBoardIsSquareArray()
{
testBoard.ConstructBoard(defaultSize);

Assert.AreEqual(defaultSize, testBoard.ReturnRowLength());
Assert.AreEqual(defaultSize, testBoard.ReturnColumnLength());
Assert.AreEqual(testBoard.ReturnRowLength(), testBoard.ReturnColumnLength());
}

[Test]
public void ReturnPositionValueIsNotNull()
{
int sixQueens = 4;

testBoard.ConstructBoard(sixQueens);

Assert.IsNotNull(testBoard.ReturnPositionValue(0,0));
Assert.IsNotNull(testBoard.ReturnPositionValue(0,sixQueens-1));
Assert.IsNotNull(testBoard.ReturnPositionValue(1,0));
Assert.IsNotNull(testBoard.ReturnPositionValue(1,sixQueens-1));
Assert.IsNotNull(testBoard.ReturnPositionValue(sixQueens-1,0));
Assert.IsNotNull(testBoard.ReturnPositionValue(sixQueens-1,sixQueens-1));
}

[Test]
public void SetPositionValueUpdatesPosition()
{
int newPosValue = 9;
int oldPosValue;

testBoard.ConstructBoard(defaultSize);

oldPosValue = testBoard.ReturnPositionValue(1,1);

testBoard.SetPositionValue(newPosValue, 1, 1);

Assert.AreEqual(newPosValue, testBoard.ReturnPositionValue(1,1));
Assert.AreNotEqual(oldPosValue, newPosValue);
}

[Test]
public void PrintBoardYieldsNonEmptyString()
{
string emptyString= "";

testBoard.ConstructBoard(defaultSize);

Assert.IsNotNull(testBoard.PrintBoard());
Assert.AreNotEqual(emptyString, testBoard.PrintBoard());
}
}
}
Loading

0 comments on commit 5a6ac1c

Please sign in to comment.