Wordsearch php – The words inserted into the grid

The WordToSearchGrid class, it extends the grid class to add in the words to search for class.

The constructor from base class Grid creates the basic grid, I have added in a testing createGridRow() in this class to build just a empty grid (this is a great thing with class inheritance / extends etc, so that you can just re-write one aspect of the base class if you want it done a different way and it still works), and the output below is of the testing createGridRow() function so it makes it easier to see where the words was placed.

The direction of the words are like a compass directions, north, south, east and west and the north east, south east, north west and south west. Their are 8 directions in total that a word can take.

The getWords function gets the words to search for.

Here is a break down of the createSearchGrid function, which is the make aspect of placement of words.

    public function createSearchGrid()
    {
	// get the size of the grid
	$size = parent::returnSize();
 
	// loop thought the words to insert
	for ($i = 0; $i < count($this->_words); $i++)
	{

Loop thought the amount of words that are going to be inserted (tried to be)

	  $wordLen = strlen($this->_words[$i]);
	  // if the word is larger than the size of the grid, it cannot be inserted.
 
	  // NOTE : at present there is no intersection (crossing search words) shall do in the next version
 
	  if ($wordLen < $size) 
	  {

As NOTED in the code, there is no intersection at present, shall do this at a later stage, just the basics of insertion at present.

Also if the word to be inserted is longer in length than the actual grid then there is no point trying to insert it, because it will not fit.

	      //need to pick a direction and also a point on the grid.
	      // also need to try and place the word onto the grid x amount of times else break out.
	      $direction = rand(1,8);
	      $pointX = rand(1, $size);
	      $pointY = rand(1, $size);
 
	      // the remainder of the subtracting the points from the size of grid will basically say how much space is required
	      $space = $size - $wordLen;

Get a randomize direction, there are 8 directions and also randomized points to insert into the grid from 1 to the maximum size of the grid

	      // check against the direction and the size of the word against where it is on the poistion in the grid
	      // 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	      // from the points point of view.
 
	      $spaceY = $size - $pointY;
	      $spaceX = $size - $pointX;

Here is when the fun starts, the space X/Y left is basically how much space is left from the size of the grid to where the point X/Y are placed on the grid.

	      // if the direction is not east or west, and there is not enought space, move the insertion pointY difference
	      // north and south
	      if (!(($direction == 7) || ($direction == 3)))
	      {
		  if ($spaceY > $space) 
		      $pointY+= ($spaceY - $space);
	      }

If the direction is not going west or east then we are going north or south. The next question is, how much space is there to insert the word (we are always working in a north/west direction, but can move the word points around for south and east) and is the space left to insert the word greater than the space left required to insert the word.

E.g.. the size of the grid is 11 and the pointY = 2 and the word to insert is “merry” which has a word length of 5.
The space required ($space) = 11 – 5 which equals 6
The space left ($spaceY) = 11 – 2 which equals 9
and since we are always heading in a north/west direction as a default (if we are heading in any direction, e.g. sometimes it would be north or west or both).
then if the space left (9) is greater than the space required (6) which it is then increment the pointY (space left) the difference between the space left ($spaceY) and the space required ($space) which equals 3.

So from the equation this would be

if ( $spaceY (9) > $space (6) )
$pointY (2) increment by 3 which makes $pointY = 5 which is the length of the word (could just make it equal the length of the word, but I prefer the equation 🙂 )

The below is the same as the north/south test, apart from east and west.

	      // if the direction is not north or south and there is not enought space, move the insertion pointX difference
	      // east and west.
	      if (!(($direction == 1) || ($direction == 5)))
	      {
		  if ($spaceX > $space)
		      $pointX+= ($spaceX - $space);
	      }
 
	      $this->insertIntoGrid($pointX, $pointY, $this->_words[$i], $direction);
	  }
	  else
	  {
	      // no need to tell the user to search for something that was not inserted
	      echo "Word ". $this->_words[$i] . " was too long for the wordsearch";
	      unset($this->_words[$i]);
	  }
	}
    }

The insertIntoGrid function, inserts the word that has a pointX and pointY coordinates and the direction.

    // insert into the grid at the positions x, y, the word to insert with the direction
    public function insertIntoGrid($pX, $pY, $word, $direction)
    {
	$wordLen = strlen($word);

Since we are based in north/west direction if the direction is south/east then correct the starting point to reflect the word direction.

	// move the starting point of the word to the correct place within the grid
	// the default is north and west, so will need to correct for south and east directions.
	if ($direction >=4 && $direction <=6) $pY-= ($wordLen-1);
	if ($direction >=2 && $direction <=4) $pX-= ($wordLen-1);
 
	// 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	// process each letter of the word and move the position to insert in the correct direction
	for ($i = 0; $i < $wordLen; $i++)
	{
	    parent::insertCharIntoGrid($pX, $pY, $word[$i]);
	    // move to the next grid position to insert the character
	    switch($direction)
	    {
	      case 1 : $pY--; break;
	      case 2 : $pY--; $pX++; break;
	      case 3 : $pX++; break;
	      case 4 : $pY++; $pX++; break;
	      case 5 : $pY++; break;
	      case 6 : $pY++; $pX--; break;
	      case 7 : $pX--; break;
	      case 8 : $pY--; $pX--; break;
	      default : break;
	    }
	}
    }

Here is the full class structure, and also a small demo. You will need to have the other classes in the same php file, the classes grid and the words.

class WordToSearchGrid extends Grid {
 
    private $_words;
 
    /* create a blank grid  - testing -- just need to comment out this function to create the real grid*/
    public function createGridRow()
    {
	$retArray = array();
	for ($i = 1; $i <= parent::returnSize(); $i++)
	{
	    $retArray[$i] = " ";
	}
	return array();
    }
 
    /* Gets the words to search for */
    public function getWords($wordsArray)
    {
	if (isset($wordsArray) && is_array($wordsArray))
	{
	  $this->_words = $wordsArray;
	}
    }
 
    // createSearchGrid, will insert the words onto a blank grid (for testing).
    // in random places and directions.
    public function createSearchGrid()
    {
	// get the size of the grid
	$size = parent::returnSize();
 
	// loop thought the words to insert
	for ($i = 0; $i < count($this->_words); $i++)
	{
	  $wordLen = strlen($this->_words[$i]);
	  // if the word is larger than the size of the grid, it cannot be inserted.
 
	  // NOTE : at present there is no intersection (crossing search words) shall do in the next version
 
	  if ($wordLen < $size) 
	  {
	      //need to pick a direction and also a point on the grid.
	      // also need to try and place the word onto the grid x amount of times else break out.
	      $direction = rand(1,8);
	      $pointX = rand(1, $size);
	      $pointY = rand(1, $size);
 
	      // the remainder of the subtracting the points from the size of grid will basically say how much space is required
	      $space = $size - $wordLen;
 
	      // check against the direction and the size of the word against where it is on the poistion in the grid
	      // 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	      // from the points point of view.
 
	      $spaceY = $size - $pointY;
	      $spaceX = $size - $pointX;
 
	      // if the direction is not east or west, and there is not enought space, move the insertion pointY difference
	      // north and south
	      if (!(($direction == 7) || ($direction == 3)))
	      {
		  if ($spaceY > $space) 
		      $pointY+= ($spaceY - $space);
	      }
 
	      // if the direction is not north or south and there is not enought space, move the insertion pointX difference
	      // east and west.
	      if (!(($direction == 1) || ($direction == 5)))
	      {
		  if ($spaceX > $space)
		      $pointX+= ($spaceX - $space);
	      }
 
	      $this->insertIntoGrid($pointX, $pointY, $this->_words[$i], $direction);
	  }
	  else
	  {
	      // no need to tell the user to search for something that was not inserted
	      echo "Word ". $this->_words[$i] . " was too long for the wordsearch";
	      unset($this->_words[$i]);
	  }
	}
    }
 
    // print out the words to search for that have been inserted into the grid
    public function printTheWordsToSearch()
    {
	foreach ($this->_words as $key => $value)
	{
	    echo "<br/>$key = $value";
	}
    }
 
    // insert into the grid at the positions x, y, the word to insert with the direction
    public function insertIntoGrid($pX, $pY, $word, $direction)
    {
	$wordLen = strlen($word);
 
	// move the starting point of the word to the correct place within the grid
	// the default is north and west, so will need to correct for south and east directions.
	if ($direction >=4 && $direction <=6) $pY-= ($wordLen-1);
	if ($direction >=2 && $direction <=4) $pX-= ($wordLen-1);
 
	// 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	// process each letter of the word and move the position to insert in the correct direction
	for ($i = 0; $i < $wordLen; $i++)
	{
	    parent::insertCharIntoGrid($pX, $pY, $word[$i]);
	    // move to the next grid position to insert the character
	    switch($direction)
	    {
	      case 1 : $pY--; break;
	      case 2 : $pY--; $pX++; break;
	      case 3 : $pX++; break;
	      case 4 : $pY++; $pX++; break;
	      case 5 : $pY++; break;
	      case 6 : $pY++; $pX--; break;
	      case 7 : $pX--; break;
	      case 8 : $pY--; $pX--; break;
	      default : break;
	    }
	}
    }
}
 
 
$GridWords = new WordToSearchGrid(11);
 
$WordsToSearchFor = new Word("words.xml",3);
 
$GridWords->getWords($WordsToSearchFor->wordsArray());
 
$GridWords->createSearchGrid();
 
$GridWords->printOut();
 
$GridWords->printTheWordsToSearch();

Here is the output from the above, you may get something different since it is based on randomized numbers.

The grid
1 .. 1 = 2 = 3 = 4 = 5 = s 6 = 7 = 8 = 9 = 10 = 11 =
2 .. 1 = 2 = 3 = 4 = 5 = a 6 = 7 = 8 = 9 = 10 = 11 =
3 .. 1 = 2 = 3 = y 4 = 5 = w 6 = 7 = 8 = 9 = o 10 = 11 =
4 .. 1 = 2 = 3 = r 4 = 5 = 6 = 7 = 8 = 9 = 10 = l 11 =
5 .. 1 = 2 = 3 = r 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 = d
6 .. 1 = 2 = 3 = e 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
7 .. 1 = 2 = 3 = m 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
8 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
9 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
10 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
11 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
 
0 = merry
1 = was
2 = old

Leave a Reply

Your email address will not be published. Required fields are marked *