Paul Kloos

Welcome

This website is a look at programming projects that I've worked on and would like to show to potential employers.

Contact Information

linkedin: http://www.linkedin.com/pub/paul-kloos/8/341/170
GitHub: https://github.com/paulkloos/

Tic-Tac-Toe Blackboard AI

While exploring software architecture for class, I made a Blackboard AI Tic-Tac-Toe program. It has a client and server architecure, with the AI on one of the client-side's. You run the server, and then you can play against another client, or against the AI client. The AI client will read the rule file, and apply the rules during its turn.

How Blackboard works
Wikipedia Blackboard AI defenition
To get a better idea of how the AI works, the Blackboard design pattern uses rules. The Rules are compared to the current state of the game, and the results of the rules' analysis gives suggestions on what to do next, and the most recomended solution is applied. To make the process more effiecient, each rule has it's own thread which does not cause a race condition issue, as rules are independent of each other and their results are agrigated through the function that decides what rule should be applied.

Source Files

Intelligent Database Management System

This is a project that was worked on by a team of three people, including myself, for two semesters. We had a customer, the computer science department, and competition, other teams in the class.
We had the challenge of making a system that managed the department information, such as equpiment database, student information, staff information, ABET informtion, data security, and making all of this while not having matching schedules. We conqured our scheduling challenge by designing the system so that we could work on pieces without interfering with other people's work.

The system
Since we were all students and knew we couldn't all work on code in the same room often, and the customer might change their mind on a whim, we decided to go with a modular approach.

The backend layer that all modules connected to was the database access layer, this layer listened to requests, checked if the requestor had appropriate permissions, and returned data based on those permissions.

The next layer is where the different sections of the system were broken up into their own modules. These modules conisted of:
  • Backend - this is where the bussiness logic for the module is
  • Interface intermideate - this is where the interface and backend interact, along with generation of any dynamic content
  • Interface Layout - this handles all of the static content of the interface and determines where the dynamic content is placed
The final layer is the generic interface shell, this is where all the modules are tied in. Any module that is added, calls from this shell in order to get a consistent system layout.

Security
Since the system was designed to handle sensitive information, we wanted to be sure that all data management was handled properly. When a module want information from the database, it sends a query to the security module. The security module will check the query against the requestor's permissions and it will:
  • Run the query and return the results
  • Run the query and return sanitized results
  • Deny the request
When a query requires the results to be sanitized, the module will strip out rows and columns that the requestor does not have permission to see.
This system protects against SQL injection 2 ways:
      It anaylyizes the queries sent.
      when making a call to the database, it will run the query from a database account that only has privaleges for SELECT, INSERT/UPDATE or DELETE, depending on the query.

Page Count Tracker

This is a program that tracks current page counts of printers (I've only tested HP printers) by getting them at a set interval and putting that value in an access database. This program uses another program that uses the SNMP protocol that the printer understands, to get its page count, then the value is stored and then it can be queried for graphing purposes and can be exported to a csv file.
The programs features:
  • Printers can be temporarily disabled
  • If you moved a printer, but it was using the same address, you can add the printer under another name and re-assign those page counts based on the date it was moved
  • A graph that can show pages per collection increment, and can be filtered by date and time of day
  • The graph can be set to show the latest page counts when they are collected
  • csv's have daily, weekly, and monthly intervals, and can involve any set of printers
  • csv's are made with excel in mind, so they include formulas in some columns for data point comparisons
  • Accepts a command from the command line to start collecting data and if the interface should be visible, when the program is started
Controls screen


Data visualization


Export options


Now hosted on GitHub https://github.com/paulkloos/pagecount

Sudoku solver

During christmas break one year, the local computer science club decided to have a programming contest, they chose to have us make Sudoku solvers.

The code involves three different algorithms for solving the puzzle, the first two use a process of narrowing down what choices a certain cell has for numbers, and determining if the dataset equals 1 for any given cell. The third is a brute force algorithm that starts with the puzzle at the stage where it is partially solved by the previous two logics.
The program turned out to work great, it can solve most puzzles in nano seconds, for all but a very small set of puzzles.


Source Code:
  • main.cpp
  • item.h
  • item.cpp - single cell representation
  • table.h
  • table.cpp - puzzle solving algorithms
  • input.txt - Sample input
/********************************************************************
*** Author :			Paul Kloos		***
*** Program Name:	sudokuPuzzle	***
*** Date:	 1/27/08				***
*************************************************************************
*** DESCRIPTION : This program will solve any valid sudoku puzzle through	***
***				a combination of logic and brute force algorithms			***
*************************************************************************/
// preprocessor directives
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
#include <cctype>
#include "item.h"
#include "table.h"

// global declarations and definitions – constants, data types, functions
using namespace std;

const int LINE_SIZE = 40;
typedef char Line[LINE_SIZE + 1];

void getFilename(const int, const char* [], Line &);
void getFilenameInterface(int & Flength, Line);
void parseContent(const Line, int[], int&);

// main function definition
int main(const int argc, const char* argv[])
{
	ifstream inFile;
	Line content, fileName;
	table puzzle;
	int row[TABLE_SIZE], location = 0, clueCount=0;
	
	getFilename(argc, argv, fileName);
	inFile.open(fileName);
	if(!inFile)
	{
		cerr << "File not found: " << fileName << endl;
	}
	else
	{//fills in the puzzle to be solved
		while(!inFile.getline(content,LINE_SIZE,']').eof())
		{
			if(location < TABLE_SIZE)
			{
				parseContent(content,row,clueCount);
				for(int y = 0; y < TABLE_SIZE; y++)
				{
					puzzle.setCellValue(location,y,row[y]);
				}
				location++;
			}
		}
		puzzle.setClueCount(clueCount); //sets the number of clues
		puzzle.solve(); // solves the puzzle
		puzzle.printTable(); //prints the results
	}
	system("Pause");
	return 0;
}
/********************************************************************
*** FUNCTION getFilename ***
*********************************************************************
*** DESCRIPTION : This function gets the name of the data file that is to be read in. ***
*** INPUT ARGS : argc, argv ***
*** OUTPUT ARGS : filename ***
*** IN/OUT ARGS : N/A ***
*** RETURN : void ***
********************************************************************/
void getFilename(const int argc, const char* argv[], Line& filename)
{
	int Flength=0;
	if (argc == 1)
	{
			getFilenameInterface(Flength, filename);
	}
	else
	{
		Flength= strlen(argv[1]);

		if (Flength==0 || Flength > LINE_SIZE)
		{
			getFilenameInterface(Flength, filename);
		}
		strncpy(filename,argv[1], Flength+1);
	}
return;
}
/********************************************************************
*** FUNCTION getFilenameInterface ***
*********************************************************************
*** DESCRIPTION : This function is the user inteface portion of the getFilename function. ***
*** INPUT ARGS : N/A ***
*** OUTPUT ARGS : filename ***
*** IN/OUT ARGS : Flength ***
*** RETURN : void***
********************************************************************/
void getFilenameInterface(int & Flength, Line filename)//I decided to make this its own function since I call this portion of code twice
{
	do
		{
			cout << "Enter a source file name: ";
			cin	>> filename;
			cin.ignore();
			Flength= strlen(filename);
		}while (Flength==0 || Flength > LINE_SIZE);
return;
}
/********************************************************************
*** FUNCTION parseContent ***
*********************************************************************
*** DESCRIPTION : This function parses the file and passes the parsed information by reference ***
*** INPUT ARGS : Line content ***
*** OUTPUT ARGS : int row, int clueCount ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void parseContent(const Line content, int row[], int& clueCount)
{
	int location = 0;
	while(content[location]=='[' || content[location]==' ' && content[location] != '\0')
		location++;

	for(int count = 0; count < TABLE_SIZE; count++)
	{
		while(isdigit(content[location])==0 && toupper(content[location]) !='X')
			location++;

		if(toupper(content[location])=='X')
		{
			row[count] = 0;
		}
		else
		{
		row[count] = static_cast<int>(content[location])-(int)'0';
		clueCount++;
		}
		int string = row[count];
		location++;
	}
	return;
}

			
/********************************************************************
*** Author : Paul Kloos***
*** Date:	 1/27/08				***
**************************************************************************
*** DESCRIPTION : This class is used for each square in they sudoku puzzle.	***
***		Special note on data hiding, I purposely left the variables public	***
***		because using standard data hiding techniques was slowing down data	***
***		proccessing signicantly.											***
*** item, ~item, void clearNumbers									***
**************************************************************************/
#ifndef ITEM_H
#define ITEM_H

const int TABLE_SIZE = 9;
class item;
typedef item cell;

class item
{
public:
/********************************************************************
*** FUNCTION item ***
*********************************************************************
*** DESCRIPTION : Sets the item object to a null state ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : none ***
********************************************************************/
	item();
/********************************************************************
*** FUNCTION ~item ***
*********************************************************************
*** DESCRIPTION : The destructor does nothing ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : none ***
********************************************************************/
	~item();
/********************************************************************
*** FUNCTION clearNumbers ***
*********************************************************************
*** DESCRIPTION : Set the number array to zeros ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
	void clearNumbers();
	int cellNumber;
	bool set;
	int numbers[TABLE_SIZE];	
};
#endif

			
			/********************************************************************
*** Author : Paul Kloos ***
*** Date:	 1/27/08				***
*********************************************************************
*** DESCRIPTION : This class is used for each square in they sudoku puzzle.	***
***		Special note on data hiding, I purposely left the variables public	***
***		because using standard data hiding techniques was slowing down data	***
***		proccessing signicantly.											***
*** item, ~item, void clearNumbers ***
********************************************************************/
#include "item.h"
/********************************************************************
*** FUNCTION item ***
*********************************************************************
*** DESCRIPTION : Sets the item object to a null state ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : none ***
********************************************************************/
item::item()
{
	clearNumbers();
	cellNumber = 0;
	set = false;
}

item::~item()
{
}
/********************************************************************
*** FUNCTION clearNumbers ***
*********************************************************************
*** DESCRIPTION : Set the number array to zeros ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void item::clearNumbers()
{
	for(int x = 0; x < TABLE_SIZE; x++)
	{
		numbers[x] = 0;
	}
	return;
}

			
/********************************************************************
*** Author : Paul Kloos***
*** Date:	 1/27/08				***
*************************************************************************
*** DESCRIPTION : This class is the center of this sudoku solving program.	***
***		This class handels puzzle table setup, logic solving formulas,		***
***		brute force solving formula, and outputing results.					***
*** table, ~table, void setCellValue, void setClueCount, void solve,		***
*** void printTable															***
************************************************************************/
#ifndef TABLE_H
#define TABLE_H
#include "item.h"

const int BLOCK = TABLE_SIZE/3;

class table
{
public:
/********************************************************************
*** FUNCTION table ***
*********************************************************************
*** DESCRIPTION : Sets default values ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : none ***
********************************************************************/
	table();
/********************************************************************
*** FUNCTION ~table ***
*********************************************************************
*** DESCRIPTION : The destructor does nothing ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : none ***
********************************************************************/
	~table();
	
/********************************************************************
*** FUNCTION setCellValue ***
*********************************************************************
*** DESCRIPTION : Sets the value of of a cell ***
*** INPUT ARGS : const int, const int, const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
	void setCellValue(const int, const int, const int);
/********************************************************************
*** FUNCTION setClueCount ***
*********************************************************************
*** DESCRIPTION : Sets the clue count ***
*** INPUT ARGS : const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
	void setClueCount(const int);
/********************************************************************
*** FUNCTION solve ***
*********************************************************************
*** DESCRIPTION : Calls the different solving algorithms in order of***
***		simple logic, advanced logic, and brute force				***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
	void solve();
/********************************************************************
*** FUNCTION printTable ***
*********************************************************************
*** DESCRIPTION : Prints the results of the solved puzzle ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
	void printTable();
private:
	bool numberCheck(const int, const int);
	void row(const int, const int);
	void column(const int, const int);
	void blockCheck(const int, const int);
	bool singleLogic();
	void forceSolve();
	cell puzzle[TABLE_SIZE][TABLE_SIZE];
	bool solved[BLOCK][BLOCK];
	int clueCount;
};
#endif
			
/**************************************************************************
*** Author : Paul Kloos				***
*** Date:	 1/27/08				***
****************************************************************************
*** DESCRIPTION : This class is the center of this sudoku solving program.	***
***		This class handels puzzle table setup, logic solving formulas,		***
***		brute force solving formula, and outputing results.					***
*** table, ~table, void setCellValue, void setClueCount, void solve,		***
*** bool singleLogic, void forceSolve, void row, void column,				***
*** void blockCheck, bool numberCheck, void printTable						***
**************************************************************************/
#include <iostream>
#include <fstream>
#include "item.h"
#include "table.h"
using namespace std;
/********************************************************************
*** FUNCTION table ***
*********************************************************************
*** DESCRIPTION : Sets default values ***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : none ***
********************************************************************/
table::table()
{
	clueCount = 0;
}

table::~table()
{
}
/********************************************************************
*** FUNCTION setCellValue ***
*********************************************************************
*** DESCRIPTION : Sets the value of of a cell ***
*** INPUT ARGS : const int, const int, const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void table::setCellValue(const int x, const int y , const int value)
{
	if(x < TABLE_SIZE && y < TABLE_SIZE)
	{
		puzzle[x][y].cellNumber = value;
	}
	return;
}
/********************************************************************
*** FUNCTION setClueCount ***
*********************************************************************
*** DESCRIPTION : Sets the clue count ***
*** INPUT ARGS : const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void table::setClueCount(const int count)
{
	clueCount = count;
	return;
}
/********************************************************************
*** FUNCTION solve ***
*********************************************************************
*** DESCRIPTION : Calls the different solving algorithms in order of***
***		simple logic, advanced logic, and brute force				***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void table::solve()
{
	bool vfound = false;
	int x = 0, y = 0;
	do
	{
		vfound = false;
		for(x = 0; x < TABLE_SIZE && !vfound; x++)
		{//simple logic
			for(y = 0; y < TABLE_SIZE && !vfound; y++)
			{
				if(puzzle[x][y].cellNumber == 0)
				{
					vfound = numberCheck(x,y);
				}
			}
		}
		
		if(!vfound)
		{//advanced logic
			vfound = singleLogic();
		}

		if(!vfound)
		{//brute force solver
			forceSolve();
		}
	}while(vfound);
return;
}
/********************************************************************
*** FUNCTION singleLogic ***
*********************************************************************
*** DESCRIPTION : This function is the advanced logic, where you can	***
*** solve a cell by examining all of the cells in its 3x3 block and		***
*** determining if there is only one cell in that block that can contain***
*** a certain number that no other cell in that block can contain.		***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : bool ***
********************************************************************/
bool table::singleLogic()
{
	bool found = false;
	int count = 0;
	int location[2];
	int xE, yE;
	for(int num = 0; num < TABLE_SIZE; num++)
	{
		for(int z = 1; z < BLOCK + 1; z++)
		{
			for(int w = 1; w < BLOCK + 1; w++)
			{
				xE = (z * BLOCK);
				for(int x = (z * BLOCK) - BLOCK; x < xE; x++)
				{
					yE = (w * BLOCK);
					for(int y = (w * BLOCK) - BLOCK; y < yE; y++)
					{
						row(x,y);
						column(x,y);
						blockCheck(x,y);
						if(puzzle[x][y].cellNumber == 0)
						{
							if(puzzle[x][y].numbers[num]==0)
							{
								count++;
								location[0] = x;
								location[1] = y;
							}
						}
						if(count > 1)
						{//if more than one possiblities exist, this ends the search on the current block
							y = (w * BLOCK);
							x = (z * BLOCK);
						}
					}
				}
				if(count==1)
				{
					puzzle[location[0]][location[1]].cellNumber = (num + 1);
					found = true;
				}
				count=0;
			}
		}
	}

	return found;
}
/********************************************************************
*** FUNCTION forceSolve ***
*************************************************************************
*** DESCRIPTION : This function is the brute force solving algorithm, which	***
***	checks every every possiblity until it finds one that works. Since this	***
*** type of solving can take a long time due to the high itteration count,	***
*** this specific algorithm has shortcuts implemented to reduce itterations	***
*** as much as possible.													***
*** INPUT ARGS : none										***
*** OUTPUT ARGS : none										***
*** IN/OUT ARGS : none										***
*** RETURN : void											***
**************************************************************************/
void table::forceSolve()
{
	bool reverse = false;
	int positionx = 0, positiony = 0, number = 1, value;
	for(int x = 0; x < TABLE_SIZE; x++)
	{//sets the already solved cells as not changeable
		for(int y = 0; y < TABLE_SIZE; y++)
		{
			if(puzzle[x][y].cellNumber > 0)
				puzzle[x][y].set = true;
		}
	}

	while(positionx < 9)
	{
		if(!puzzle[positionx][positiony].set && !reverse)
		{//This code helps reduce iterations by jumping to the first posibility for the cell
			if(puzzle[positionx][positiony].cellNumber == 0)
			{
				puzzle[positionx][positiony].clearNumbers();
				row(positionx,positiony);
				column(positionx,positiony);
				blockCheck(positionx,positiony);
				for(int p = number; p < TABLE_SIZE; p++)
				{
					if(puzzle[positionx][positiony].numbers[p - 1] == 0)
					{
						number = p;
						p = TABLE_SIZE;//end the for loop
					}
				}
			}
			puzzle[positionx][positiony].cellNumber = number;
			puzzle[positionx][positiony].clearNumbers();
			row(positionx,positiony);
			column(positionx,positiony);
			blockCheck(positionx,positiony);
			if(puzzle[positionx][positiony].numbers[(number-1)] != 3)
			{
				number++;

				if(number > 9)
						reverse = true;

				continue;
			}
		}
		if(!reverse)
		{//advance forward
			positiony = (positiony + 1)%(TABLE_SIZE);
			number = 1;

			if(positiony == 0)
				positionx++;
		}
		else
		{/*go back 1 cell itterate that cell by 1, check if valid. if not set cell to 0 and go back.
			repeat as neccsessary*/
			if(!puzzle[positionx][positiony].set)
			{
				puzzle[positionx][positiony].cellNumber = 0;
			}
			
			positiony = positiony - 1;

			if(positiony < 0)
			{
				positionx--;
				if(positionx < 0)
				{
					positionx = 0;
					positiony = 0;
					reverse = false;
					number = value;
					continue;
				}
				else
					positiony = 8;
			}
			
			if(!puzzle[positionx][positiony].set)
			{
				value = puzzle[positionx][positiony].cellNumber;
				if(value < TABLE_SIZE)
				{
					puzzle[positionx][positiony].cellNumber = ++value;
					puzzle[positionx][positiony].clearNumbers();
					row(positionx,positiony);
					column(positionx,positiony);
					blockCheck(positionx,positiony);
					reverse = false;

					if(puzzle[positionx][positiony].numbers[(value-1)] > 1)
						number = value;
				}
				else
					reverse = true;
			}	
		}
	}
	return;
}
/********************************************************************
*** FUNCTION row ***
*********************************************************************
*** DESCRIPTION : This function is used for checking the different	***
***		possiblities in each row.									***
*** INPUT ARGS : const int, const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void table::row(const int Xaxis, const int Yaxis)
{
	int value;
	for(int y = 0; y < TABLE_SIZE; y++)
	{
		value = puzzle[Xaxis][y].cellNumber;
		if(value > 0)
		{
			puzzle[Xaxis][Yaxis].numbers[(value - 1)]++;
		}
	}
	return;
}
/********************************************************************
*** FUNCTION column ***
*********************************************************************
*** DESCRIPTION : This function is used for checking the different	***
***		possiblities in each column									***
*** INPUT ARGS : const int, const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void table::column(const int Xaxis, const int Yaxis)
{
	int value;
	for(int x = 0; x < TABLE_SIZE; x++)
	{
		value = puzzle[x][Yaxis].cellNumber;
		if(value > 0)
		{
			puzzle[Xaxis][Yaxis].numbers[(value - 1)]++;
		}
	}
	return;
}
/********************************************************************
*** FUNCTION block ***
*********************************************************************
*** DESCRIPTION : This function is used for checking the different	***
***		possibilities in each 3x3 block								***
*** INPUT ARGS : const int, const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void table::blockCheck(const int Xaxis, const int Yaxis)
{
	int xMul, yMul, value, xB, xE, yB, yE;
//find which block to check
	if(Xaxis >= 0 && Xaxis <= 2)
	{
		if(Yaxis >= 0 && Yaxis <= 2)
		{
			xMul = 1;
			yMul = 1;
		}
		else if(Yaxis >= 3 && Yaxis <= 5)
		{
			xMul = 1;
			yMul = 2;
		}
		else
		{
			xMul = 1;
			yMul = 3;
		}
	}
	else if(Xaxis >= 3 && Xaxis <= 5)
	{
		if(Yaxis >= 0 && Yaxis <= 2)
		{
			xMul = 2;
			yMul = 1;
		}
		else if(Yaxis >= 3 && Yaxis <= 5)
		{
			xMul = 2;
			yMul = 2;
		}
		else
		{
			xMul = 2;
			yMul = 3;
		}
	}
	else
	{
		if(Yaxis >= 0 && Yaxis <= 2)
		{
			xMul = 3;
			yMul = 1;
		}
		else if(Yaxis >= 3 && Yaxis <= 5)
		{
			xMul = 3;
			yMul = 2;
		}
		else
		{
			xMul = 3;
			yMul = 3;
		}
	}

	xB = ((BLOCK * xMul) - BLOCK);
	xE = (BLOCK * xMul);
	yB = ((BLOCK * yMul) - BLOCK);
	yE = (BLOCK * yMul);

	for(int x = xB; x < xE; x++)
	{
		for(int y = yB; y < yE; y++)
		{
			value = puzzle[x][y].cellNumber;
			if(value > 0)
			{
				puzzle[Xaxis][Yaxis].numbers[(value - 1)]++;
			}
		}
	}
	return;
}
/********************************************************************
*** FUNCTION numberCheck ***
*********************************************************************
*** DESCRIPTION : This function is the simple logic algorithm. It finds	***
***		if a cell has only one unique value that it can be and returns	***
***		true and assigns the appropriate value to the cell if found		***
*** INPUT ARGS : const int, const int ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : bool ***
********************************************************************/
bool table::numberCheck(const int Xaxis, const int Yaxis)
{
	int zeroValue, count = 0;
	bool found = false;
	row(Xaxis,Yaxis);
	column(Xaxis,Yaxis);
	blockCheck(Xaxis,Yaxis);
	for(int x = 0; x < TABLE_SIZE; x++)
	{
		if(puzzle[Xaxis][Yaxis].numbers[x]==0)
		{
			zeroValue=(x + 1);
			count++;
		}
	}
	if(count == 1)
	{
		puzzle[Xaxis][Yaxis].cellNumber = zeroValue;
		found = true;
	}
	return found;
}
/********************************************************************
*** FUNCTION printTable ***
*********************************************************************
*** DESCRIPTION : Prints the results of the solved puzzle on the	***
***				screen and in the file solution.txt					***
*** INPUT ARGS : none ***
*** OUTPUT ARGS : none ***
*** IN/OUT ARGS : none ***
*** RETURN : void ***
********************************************************************/
void table::printTable()
{
	ofstream outPut;
	outPut.open("solution.txt");
	if(!outPut)
	{
		cerr << "Could not creat file: " << endl;
	}
	else
	{
		for(int x = -1; x  -1)
			{
				cout	<< " |";
				outPut	<< " |";
				for(int y = 0; y < TABLE_SIZE; y++)
				{
					cout	<< " " << puzzle[x][y].cellNumber << " |";
					outPut	<< " " << puzzle[x][y].cellNumber << " |";
					if(y == 2 || y == 5)
					{
						cout	<< "|";
						outPut	<< "|";
					}
				}
			cout	<< endl;
			outPut	<< endl;
			}
			cout	<< " ";
			outPut	<< " ";
			for(int z = 0; z < TABLE_SIZE - 1; z++)
			{
				if(x == 2 || x == 5)
				{
					cout	<< "=====";
					outPut	<< "=====";
				}
				else
				{
					cout	<< "-----";
					outPut	<< "-----";
				}
			}
			cout	<< endl;
			outPut	<< endl;
		}
		cout	<< fixed << endl << "Clue Count: " << clueCount << endl;
		outPut	<< fixed << endl << "Clue Count: " << clueCount << endl;
	}
	outPut.close();
	return;
}
			
[[4,x,3,9,x,x,6,x,x],[x,9,x,6,x,x,4,x,5],[x,7,x,5,x,4,x,3,x],[x,x,5,x,7,6,1,x,x],[8,4,x,x,x,x,x,6,3],[x,x,9,2,4,x,7,x,x],[x,8,x,7,x,1,x,2,x],[5,x,2,x,x,9,x,1,x],[x,x,4,x,x,8,5,x,6]]